@buoy-gg/external-sync 2.1.15 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,10 @@ var _react = require("react");
8
8
  var _socket = require("socket.io-client");
9
9
  var _platformUtils = require("./utils/platformUtils");
10
10
  var _logger = require("./utils/logger");
11
+ // True only in development. Guarded so it doesn't throw in environments
12
+ // (web/electron bundles) where __DEV__ may be undefined.
13
+ const isDev = typeof __DEV__ !== "undefined" ? __DEV__ : false;
14
+
11
15
  /**
12
16
  * Singleton socket instance that persists across component renders.
13
17
  * Multiple components share the same socket connection.
@@ -15,6 +19,16 @@ var _logger = require("./utils/logger");
15
19
  let globalSocketInstance = null;
16
20
  let currentSocketURL = "";
17
21
 
22
+ /**
23
+ * Identifies a single socket INSTANCE. Sent in the handshake query and reused
24
+ * for the life of the instance, so it survives socket.io reconnects but
25
+ * changes whenever we create a brand-new socket (remount / Fast Refresh /
26
+ * URL change). The dashboard uses this to tell a flapping connection that's
27
+ * merely reconnecting (stable nonce) from an app that keeps recreating its
28
+ * socket (changing nonce).
29
+ */
30
+ const makeConnectionNonce = () => `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
31
+
18
32
  /**
19
33
  * Hook that manages a Socket.IO connection for device-to-dashboard communication.
20
34
  *
@@ -36,9 +50,13 @@ function useExternalSyncSocket({
36
50
  const [socket, setSocket] = (0, _react.useState)(null);
37
51
  const [isConnected, setIsConnected] = (0, _react.useState)(false);
38
52
  const initialized = (0, _react.useRef)(false);
53
+ // Tracks whether we've already logged a connection error for the current
54
+ // outage, so the reconnection backoff doesn't spam an error on every retry.
55
+ const hasLoggedConnectError = (0, _react.useRef)(false);
39
56
  const logPrefix = `[${deviceName}]`;
40
57
  const onConnect = () => {
41
58
  (0, _logger.log)(`${logPrefix} Socket connected successfully`, enableLogs);
59
+ hasLoggedConnectError.current = false;
42
60
  setIsConnected(true);
43
61
  };
44
62
  const onDisconnect = reason => {
@@ -46,7 +64,13 @@ function useExternalSyncSocket({
46
64
  setIsConnected(false);
47
65
  };
48
66
  const onConnectError = error => {
49
- (0, _logger.log)(`${logPrefix} Socket connection error: ${error.message}`, enableLogs, "error");
67
+ // Never surface this in production builds.
68
+ if (!isDev) return;
69
+ // Reconnection retries indefinitely; only log the first failure of an
70
+ // outage to avoid flooding the console until the server comes back up.
71
+ if (hasLoggedConnectError.current) return;
72
+ hasLoggedConnectError.current = true;
73
+ (0, _logger.log)(`${logPrefix} Socket connection error: ${error.message}. Retrying in the background until the dashboard is available.`, enableLogs, "warn");
50
74
  };
51
75
  const onConnectTimeout = () => {
52
76
  (0, _logger.log)(`${logPrefix} Socket connection timeout`, enableLogs, "error");
@@ -70,9 +94,13 @@ function useExternalSyncSocket({
70
94
  deviceId: persistentDeviceId,
71
95
  platform,
72
96
  extraDeviceInfo: JSON.stringify(extraDeviceInfo),
73
- envVariables: JSON.stringify(envVariables)
97
+ envVariables: JSON.stringify(envVariables),
98
+ connectionNonce: makeConnectionNonce()
74
99
  },
75
- reconnection: false,
100
+ reconnection: true,
101
+ reconnectionAttempts: Infinity,
102
+ reconnectionDelay: 1000,
103
+ reconnectionDelayMax: 5000,
76
104
  transports: ["websocket"]
77
105
  });
78
106
  } else {
@@ -131,9 +159,13 @@ function useExternalSyncSocket({
131
159
  deviceId: persistentDeviceId,
132
160
  platform,
133
161
  extraDeviceInfo: JSON.stringify(extraDeviceInfo),
134
- envVariables: JSON.stringify(envVariables)
162
+ envVariables: JSON.stringify(envVariables),
163
+ connectionNonce: makeConnectionNonce()
135
164
  },
136
- reconnection: false,
165
+ reconnection: true,
166
+ reconnectionAttempts: Infinity,
167
+ reconnectionDelay: 1000,
168
+ reconnectionDelayMax: 5000,
137
169
  transports: ["websocket"]
138
170
  });
139
171
  socketRef.current = globalSocketInstance;
@@ -4,6 +4,10 @@ import { useEffect, useRef, useState } from "react";
4
4
  import { io as socketIO } from "socket.io-client";
5
5
  import { getPlatformSpecificURL } from "./utils/platformUtils";
6
6
  import { log } from "./utils/logger";
7
+ // True only in development. Guarded so it doesn't throw in environments
8
+ // (web/electron bundles) where __DEV__ may be undefined.
9
+ const isDev = typeof __DEV__ !== "undefined" ? __DEV__ : false;
10
+
7
11
  /**
8
12
  * Singleton socket instance that persists across component renders.
9
13
  * Multiple components share the same socket connection.
@@ -11,6 +15,16 @@ import { log } from "./utils/logger";
11
15
  let globalSocketInstance = null;
12
16
  let currentSocketURL = "";
13
17
 
18
+ /**
19
+ * Identifies a single socket INSTANCE. Sent in the handshake query and reused
20
+ * for the life of the instance, so it survives socket.io reconnects but
21
+ * changes whenever we create a brand-new socket (remount / Fast Refresh /
22
+ * URL change). The dashboard uses this to tell a flapping connection that's
23
+ * merely reconnecting (stable nonce) from an app that keeps recreating its
24
+ * socket (changing nonce).
25
+ */
26
+ const makeConnectionNonce = () => `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
27
+
14
28
  /**
15
29
  * Hook that manages a Socket.IO connection for device-to-dashboard communication.
16
30
  *
@@ -32,9 +46,13 @@ export function useExternalSyncSocket({
32
46
  const [socket, setSocket] = useState(null);
33
47
  const [isConnected, setIsConnected] = useState(false);
34
48
  const initialized = useRef(false);
49
+ // Tracks whether we've already logged a connection error for the current
50
+ // outage, so the reconnection backoff doesn't spam an error on every retry.
51
+ const hasLoggedConnectError = useRef(false);
35
52
  const logPrefix = `[${deviceName}]`;
36
53
  const onConnect = () => {
37
54
  log(`${logPrefix} Socket connected successfully`, enableLogs);
55
+ hasLoggedConnectError.current = false;
38
56
  setIsConnected(true);
39
57
  };
40
58
  const onDisconnect = reason => {
@@ -42,7 +60,13 @@ export function useExternalSyncSocket({
42
60
  setIsConnected(false);
43
61
  };
44
62
  const onConnectError = error => {
45
- log(`${logPrefix} Socket connection error: ${error.message}`, enableLogs, "error");
63
+ // Never surface this in production builds.
64
+ if (!isDev) return;
65
+ // Reconnection retries indefinitely; only log the first failure of an
66
+ // outage to avoid flooding the console until the server comes back up.
67
+ if (hasLoggedConnectError.current) return;
68
+ hasLoggedConnectError.current = true;
69
+ log(`${logPrefix} Socket connection error: ${error.message}. Retrying in the background until the dashboard is available.`, enableLogs, "warn");
46
70
  };
47
71
  const onConnectTimeout = () => {
48
72
  log(`${logPrefix} Socket connection timeout`, enableLogs, "error");
@@ -66,9 +90,13 @@ export function useExternalSyncSocket({
66
90
  deviceId: persistentDeviceId,
67
91
  platform,
68
92
  extraDeviceInfo: JSON.stringify(extraDeviceInfo),
69
- envVariables: JSON.stringify(envVariables)
93
+ envVariables: JSON.stringify(envVariables),
94
+ connectionNonce: makeConnectionNonce()
70
95
  },
71
- reconnection: false,
96
+ reconnection: true,
97
+ reconnectionAttempts: Infinity,
98
+ reconnectionDelay: 1000,
99
+ reconnectionDelayMax: 5000,
72
100
  transports: ["websocket"]
73
101
  });
74
102
  } else {
@@ -127,9 +155,13 @@ export function useExternalSyncSocket({
127
155
  deviceId: persistentDeviceId,
128
156
  platform,
129
157
  extraDeviceInfo: JSON.stringify(extraDeviceInfo),
130
- envVariables: JSON.stringify(envVariables)
158
+ envVariables: JSON.stringify(envVariables),
159
+ connectionNonce: makeConnectionNonce()
131
160
  },
132
- reconnection: false,
161
+ reconnection: true,
162
+ reconnectionAttempts: Infinity,
163
+ reconnectionDelay: 1000,
164
+ reconnectionDelayMax: 5000,
133
165
  transports: ["websocket"]
134
166
  });
135
167
  socketRef.current = globalSocketInstance;
@@ -1 +1 @@
1
- {"version":3,"file":"useExternalSyncSocket.d.ts","sourceRoot":"","sources":["../../src/useExternalSyncSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAS1D;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAkB,GACnB,EAAE,0BAA0B;;;;;EAoM5B"}
1
+ {"version":3,"file":"useExternalSyncSocket.d.ts","sourceRoot":"","sources":["../../src/useExternalSyncSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AA0B1D;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAkB,GACnB,EAAE,0BAA0B;;;;;EAsN5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/external-sync",
3
- "version": "2.1.15",
3
+ "version": "3.0.1",
4
4
  "description": "Generic device-to-desktop sync for Buoy dev tools",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",