Skip to content

Commit 7371e06

Browse files
author
Eliel Calebi Nabas da Silveira
committed
feat(platformUtils): add a prop to expecify if it`s a real device
1 parent 350b1c6 commit 7371e06

File tree

3 files changed

+83
-28
lines changed

3 files changed

+83
-28
lines changed

src/react-query-external-sync/platformUtils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ export const isReactNative = (): boolean => {
4545
*/
4646
export const getPlatformSpecificURL = (
4747
baseUrl: string,
48-
platform: PlatformOS
48+
platform: PlatformOS,
49+
isDevice: boolean
4950
): string => {
5051
try {
5152
const url = new URL(baseUrl);
5253

5354
// For Android emulator, replace hostname with 10.0.2.2
5455
if (
56+
!isDevice &&
5557
platform === "android" &&
5658
(url.hostname === "localhost" || url.hostname === "127.0.0.1")
5759
) {

src/react-query-external-sync/useMySocket.ts

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { useEffect, useRef, useState } from 'react';
2-
import { io as socketIO, Socket } from 'socket.io-client';
1+
import { useEffect, useRef, useState } from "react";
2+
import { io as socketIO, Socket } from "socket.io-client";
33

4-
import { log } from './utils/logger';
5-
import { getPlatformSpecificURL, PlatformOS } from './platformUtils';
4+
import { log } from "./utils/logger";
5+
import { getPlatformSpecificURL, PlatformOS } from "./platformUtils";
66

77
interface Props {
88
deviceName: string; // Unique name to identify the device
@@ -16,14 +16,20 @@ interface Props {
1616
* @default false
1717
*/
1818
enableLogs?: boolean;
19+
/**
20+
* Whether the app is running on a physical device or an emulator/simulator
21+
* This can affect how the socket URL is constructed, especially on Android
22+
* @default false
23+
*/
24+
isDevice?: boolean; // Whether the app is running on a physical device
1925
}
2026

2127
/**
2228
* Create a singleton socket instance that persists across component renders
2329
* This way multiple components can share the same socket connection
2430
*/
2531
let globalSocketInstance: Socket | null = null;
26-
let currentSocketURL = '';
32+
let currentSocketURL = "";
2733

2834
/**
2935
* Hook that handles socket connection for device-dashboard communication
@@ -43,6 +49,7 @@ export function useMySocket({
4349
envVariables,
4450
platform,
4551
enableLogs = false,
52+
isDevice = false,
4653
}: Props) {
4754
const socketRef = useRef<Socket | null>(null);
4855
const [socket, setSocket] = useState<Socket | null>(null);
@@ -78,15 +85,19 @@ export function useMySocket({
7885
};
7986

8087
const onConnectError = (error: Error) => {
81-
log(`${logPrefix} Socket connection error: ${error.message}`, enableLogs, 'error');
88+
log(
89+
`${logPrefix} Socket connection error: ${error.message}`,
90+
enableLogs,
91+
"error"
92+
);
8293
};
8394

8495
const onConnectTimeout = () => {
85-
log(`${logPrefix} Socket connection timeout`, enableLogs, 'error');
96+
log(`${logPrefix} Socket connection timeout`, enableLogs, "error");
8697
};
8798

8899
// Get the platform-specific URL
89-
const platformUrl = getPlatformSpecificURL(socketURL, platform);
100+
const platformUrl = getPlatformSpecificURL(socketURL, platform, isDevice);
90101
currentSocketURL = platformUrl;
91102

92103
try {
@@ -102,18 +113,21 @@ export function useMySocket({
102113
envVariables: JSON.stringify(envVariables),
103114
},
104115
reconnection: false,
105-
transports: ['websocket'], // Prefer websocket transport for React Native
116+
transports: ["websocket"], // Prefer websocket transport for React Native
106117
});
107118
} else {
108-
log(`${logPrefix} Reusing existing socket instance to ${platformUrl}`, enableLogs);
119+
log(
120+
`${logPrefix} Reusing existing socket instance to ${platformUrl}`,
121+
enableLogs
122+
);
109123
}
110124

111125
socketRef.current = globalSocketInstance;
112126
setSocket(socketRef.current);
113127

114128
// Setup error event listener
115-
socketRef.current.on('connect_error', onConnectError);
116-
socketRef.current.on('connect_timeout', onConnectTimeout);
129+
socketRef.current.on("connect_error", onConnectError);
130+
socketRef.current.on("connect_timeout", onConnectTimeout);
117131

118132
// Check initial connection state
119133
if (socketRef.current.connected) {
@@ -122,31 +136,39 @@ export function useMySocket({
122136
}
123137

124138
// Set up event handlers
125-
socketRef.current.on('connect', onConnect);
126-
socketRef.current.on('disconnect', onDisconnect);
139+
socketRef.current.on("connect", onConnect);
140+
socketRef.current.on("disconnect", onDisconnect);
127141

128142
// Clean up event listeners on unmount but don't disconnect
129143
return () => {
130144
if (socketRef.current) {
131145
log(`${logPrefix} Cleaning up socket event listeners`, enableLogs);
132-
socketRef.current.off('connect', onConnect);
133-
socketRef.current.off('disconnect', onDisconnect);
134-
socketRef.current.off('connect_error', onConnectError);
135-
socketRef.current.off('connect_timeout', onConnectTimeout);
146+
socketRef.current.off("connect", onConnect);
147+
socketRef.current.off("disconnect", onDisconnect);
148+
socketRef.current.off("connect_error", onConnectError);
149+
socketRef.current.off("connect_timeout", onConnectTimeout);
136150
// Don't disconnect socket on component unmount
137151
// We want it to remain connected for the app's lifetime
138152
}
139153
};
140154
} catch (error) {
141-
log(`${logPrefix} Failed to initialize socket: ${error}`, enableLogs, 'error');
155+
log(
156+
`${logPrefix} Failed to initialize socket: ${error}`,
157+
enableLogs,
158+
"error"
159+
);
142160
}
143161
// ## DON'T ADD ANYTHING ELSE TO THE DEPENDENCY ARRAY ###
144162
// eslint-disable-next-line react-hooks/exhaustive-deps
145163
}, [persistentDeviceId]);
146164

147165
// Update the socket query parameters when deviceName changes
148166
useEffect(() => {
149-
if (socketRef.current && socketRef.current.io.opts.query && persistentDeviceId) {
167+
if (
168+
socketRef.current &&
169+
socketRef.current.io.opts.query &&
170+
persistentDeviceId
171+
) {
150172
socketRef.current.io.opts.query = {
151173
...socketRef.current.io.opts.query,
152174
deviceName,
@@ -159,18 +181,28 @@ export function useMySocket({
159181
// Update the socket URL when socketURL changes
160182
useEffect(() => {
161183
// Get platform-specific URL for the new socketURL
162-
const platformUrl = getPlatformSpecificURL(socketURL, platform);
184+
const platformUrl = getPlatformSpecificURL(socketURL, platform, isDevice);
163185

164186
// Compare with last known URL to avoid direct property access
165-
if (socketRef.current && currentSocketURL !== platformUrl && persistentDeviceId) {
166-
log(`${logPrefix} Socket URL changed from ${currentSocketURL} to ${platformUrl}`, enableLogs);
187+
if (
188+
socketRef.current &&
189+
currentSocketURL !== platformUrl &&
190+
persistentDeviceId
191+
) {
192+
log(
193+
`${logPrefix} Socket URL changed from ${currentSocketURL} to ${platformUrl}`,
194+
enableLogs
195+
);
167196

168197
try {
169198
// Only recreate socket if URL actually changed
170199
socketRef.current.disconnect();
171200
currentSocketURL = platformUrl;
172201

173-
log(`${logPrefix} Creating new socket connection to ${platformUrl}`, enableLogs);
202+
log(
203+
`${logPrefix} Creating new socket connection to ${platformUrl}`,
204+
enableLogs
205+
);
174206
globalSocketInstance = socketIO(platformUrl, {
175207
autoConnect: true,
176208
query: {
@@ -181,16 +213,29 @@ export function useMySocket({
181213
envVariables: JSON.stringify(envVariables),
182214
},
183215
reconnection: false,
184-
transports: ['websocket'], // Prefer websocket transport for React Native
216+
transports: ["websocket"], // Prefer websocket transport for React Native
185217
});
186218

187219
socketRef.current = globalSocketInstance;
188220
setSocket(socketRef.current);
189221
} catch (error) {
190-
log(`${logPrefix} Failed to update socket connection: ${error}`, enableLogs, 'error');
222+
log(
223+
`${logPrefix} Failed to update socket connection: ${error}`,
224+
enableLogs,
225+
"error"
226+
);
191227
}
192228
}
193-
}, [socketURL, deviceName, logPrefix, persistentDeviceId, platform, enableLogs, extraDeviceInfo, envVariables]);
229+
}, [
230+
socketURL,
231+
deviceName,
232+
logPrefix,
233+
persistentDeviceId,
234+
platform,
235+
enableLogs,
236+
extraDeviceInfo,
237+
envVariables,
238+
]);
194239

195240
/**
196241
* Manually connect to the socket server

src/react-query-external-sync/useSyncQueriesExternal.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ interface useSyncQueriesExternalProps {
146146
* @default false
147147
*/
148148
enableLogs?: boolean;
149+
/**
150+
* Whether the app is running on a physical device or an emulator/simulator
151+
* This can affect how the socket URL is constructed, especially on Android
152+
* @default false
153+
*/
154+
isDevice?: boolean; // Whether the app is running on a physical device
149155

150156
/**
151157
* Storage instances for different storage types
@@ -312,6 +318,7 @@ export function useSyncQueriesExternal({
312318
platform,
313319
deviceId,
314320
enableLogs = false,
321+
isDevice = false,
315322
storage,
316323
mmkvStorage,
317324
asyncStorage,
@@ -439,6 +446,7 @@ export function useSyncQueriesExternal({
439446
envVariables: mergedEnvVariables,
440447
platform,
441448
enableLogs,
449+
isDevice,
442450
});
443451

444452
useEffect(() => {

0 commit comments

Comments
 (0)