1
- import React , { PropsWithChildren , createContext , useContext , useEffect , useRef , useState , useCallback } from 'react' ;
1
+ import React , { createContext , PropsWithChildren , useCallback , useContext , useEffect , useRef , useState } from 'react' ;
2
+
2
3
import { getAppId , getSocketURL } from '@deriv/shared' ;
3
4
import { getInitialLanguage } from '@deriv-com/translations' ;
4
5
import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
6
+
5
7
import { TSocketRequestPayload , TSocketResponseData , TSocketSubscribableEndpointNames } from '../types' ;
6
- import { hashObject } from './utils' ;
8
+
7
9
import WSClient from './ws-client/ws-client' ;
10
+ import { PLATFORMS } from './constants' ;
11
+ import { hashObject } from './utils' ;
8
12
9
13
type TSubscribeFunction = < T extends TSocketSubscribableEndpointNames > (
10
14
name : T ,
@@ -27,14 +31,14 @@ type APIContextData = {
27
31
setOnConnected : ( onConnected : ( ) => void ) => void ;
28
32
connection : WebSocket ;
29
33
wsClient : WSClient ;
34
+ createNewWSConnection : ( ) => void ;
30
35
} ;
31
36
32
37
/**
33
38
* Retrieves the WebSocket URL based on the current environment.
34
39
* @returns {string } The WebSocket URL.
35
40
*/
36
- const getWebSocketURL = ( ) => {
37
- const endpoint = getSocketURL ( ) ;
41
+ const getWebSocketURL = ( endpoint : string ) => {
38
42
const app_id = getAppId ( ) ;
39
43
const language = getInitialLanguage ( ) ;
40
44
return `wss://${ endpoint } /websockets/v3?app_id=${ app_id } &l=${ language } &brand=deriv` ;
@@ -45,8 +49,8 @@ const APIContext = createContext<APIContextData | null>(null);
45
49
/**
46
50
* @returns {WebSocket } The initialized WebSocket instance.
47
51
*/
48
- const initializeConnection = ( onWSClose : ( ) => void , onOpen ?: ( ) => void ) : WebSocket => {
49
- const wss_url = getWebSocketURL ( ) ;
52
+ const initializeConnection = ( endpoint : string , onWSClose : ( ) => void , onOpen ?: ( ) => void ) : WebSocket => {
53
+ const wss_url = getWebSocketURL ( endpoint ) ;
50
54
51
55
const connection = new WebSocket ( wss_url ) ;
52
56
connection . addEventListener ( 'close' , ( ) => {
@@ -67,12 +71,13 @@ const initializeConnection = (onWSClose: () => void, onOpen?: () => void): WebSo
67
71
type TAPIProviderProps = {
68
72
/** If set to true, the APIProvider will instantiate it's own socket connection. */
69
73
standalone ?: boolean ;
74
+ platform ?: string ;
70
75
} ;
71
76
72
77
type SubscribeReturnType = ReturnType < TSubscribeFunction > ; // This captures the entire return type of TSubscribeFunction
73
78
type UnwrappedSubscription = Awaited < SubscribeReturnType > ;
74
79
75
- const APIProvider = ( { children } : PropsWithChildren < TAPIProviderProps > ) => {
80
+ const APIProvider = ( { children, platform } : PropsWithChildren < TAPIProviderProps > ) => {
76
81
const [ reconnect , setReconnect ] = useState ( false ) ;
77
82
const connectionRef = useRef < WebSocket > ( ) ;
78
83
const subscriptionsRef = useRef < Record < string , UnwrappedSubscription [ 'subscription' ] > > ( ) ;
@@ -87,6 +92,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
87
92
88
93
const language = getInitialLanguage ( ) ;
89
94
const [ prevLanguage , setPrevLanguage ] = useState < string > ( language ) ;
95
+ const endpoint = getSocketURL ( platform === PLATFORMS . WALLETS ) ;
90
96
91
97
useEffect ( ( ) => {
92
98
isMounted . current = true ;
@@ -109,6 +115,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
109
115
// have to be here and not inside useEffect as there are places in code expecting this to be available
110
116
if ( ! connectionRef . current ) {
111
117
connectionRef . current = initializeConnection (
118
+ endpoint ,
112
119
( ) => {
113
120
if ( isMounted . current ) setReconnect ( true ) ;
114
121
} ,
@@ -118,6 +125,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
118
125
}
119
126
120
127
wsClientRef . current . setWs ( connectionRef . current ) ;
128
+ wsClientRef . current . setEndpoint ( endpoint ) ;
121
129
if ( isMounted . current ) {
122
130
isOpenRef . current = true ;
123
131
if ( onConnectedRef . current ) {
@@ -197,6 +205,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
197
205
let reconnectTimerId : NodeJS . Timeout ;
198
206
if ( reconnect ) {
199
207
connectionRef . current = initializeConnection (
208
+ endpoint ,
200
209
( ) => {
201
210
reconnectTimerId = setTimeout ( ( ) => {
202
211
if ( isMounted . current ) {
@@ -209,6 +218,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
209
218
throw new Error ( 'Connection is not set' ) ;
210
219
}
211
220
wsClientRef . current . setWs ( connectionRef . current ) ;
221
+ wsClientRef . current . setEndpoint ( endpoint ) ;
212
222
if ( onReconnectedRef . current ) {
213
223
onReconnectedRef . current ( ) ;
214
224
}
@@ -218,7 +228,7 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
218
228
}
219
229
220
230
return ( ) => clearTimeout ( reconnectTimerId ) ;
221
- } , [ reconnect ] ) ;
231
+ } , [ endpoint , reconnect ] ) ;
222
232
223
233
// reconnects to latest WS url for new language only when language changes
224
234
useEffect ( ( ) => {
@@ -229,10 +239,15 @@ const APIProvider = ({ children }: PropsWithChildren<TAPIProviderProps>) => {
229
239
// eslint-disable-next-line react-hooks/exhaustive-deps
230
240
} , [ language ] ) ;
231
241
242
+ const createNewWSConnection = useCallback ( ( ) => {
243
+ setReconnect ( true ) ;
244
+ } , [ ] ) ;
245
+
232
246
return (
233
247
< APIContext . Provider
234
248
value = { {
235
249
subscribe,
250
+ createNewWSConnection,
236
251
unsubscribe,
237
252
queryClient : reactQueryRef . current ,
238
253
setOnReconnected,
0 commit comments