@chromahq/react 1.0.16 → 1.0.18

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.
Files changed (2) hide show
  1. package/dist/index.js +42 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13,7 +13,10 @@ const CONFIG = {
13
13
  MAX_ERROR_CHECKS: 10,
14
14
  CONSECUTIVE_FAILURE_THRESHOLD: 2,
15
15
  RECONNECT_DELAY: 100,
16
- PORT_NAME: "chroma-bridge"
16
+ PORT_NAME: "chroma-bridge",
17
+ // Service worker restart retry settings (indefinite retries)
18
+ SW_RESTART_RETRY_DELAY: 500,
19
+ SW_RESTART_MAX_DELAY: 5e3
17
20
  };
18
21
  const calculateBackoffDelay = (attempt, baseDelay, maxDelay) => Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
19
22
  const clearTimeoutSafe = (ref) => {
@@ -200,6 +203,8 @@ const BridgeProvider = ({
200
203
  const retryCountRef = useRef(0);
201
204
  const reconnectTimeoutRef = useRef(null);
202
205
  const maxRetryCooldownRef = useRef(null);
206
+ const triggerReconnectTimeoutRef = useRef(null);
207
+ const swRestartRetryCountRef = useRef(0);
203
208
  const pingIntervalRef = useRef(null);
204
209
  const errorCheckIntervalRef = useRef(null);
205
210
  const consecutivePingFailuresRef = useRef(0);
@@ -233,6 +238,7 @@ const BridgeProvider = ({
233
238
  );
234
239
  const cleanup = useCallback(() => {
235
240
  clearTimeoutSafe(reconnectTimeoutRef);
241
+ clearTimeoutSafe(triggerReconnectTimeoutRef);
236
242
  clearIntervalSafe(errorCheckIntervalRef);
237
243
  clearIntervalSafe(pingIntervalRef);
238
244
  if (portRef.current) {
@@ -278,6 +284,7 @@ const BridgeProvider = ({
278
284
  }, []);
279
285
  const scheduleReconnect = useCallback(
280
286
  (connectFn) => {
287
+ if (!isMountedRef.current) return;
281
288
  if (retryCountRef.current < maxRetries) {
282
289
  retryCountRef.current++;
283
290
  const delay = calculateBackoffDelay(
@@ -287,11 +294,14 @@ const BridgeProvider = ({
287
294
  );
288
295
  console.log(`[Bridge] Reconnecting in ${delay}ms (${retryCountRef.current}/${maxRetries})`);
289
296
  updateStatus("reconnecting");
290
- reconnectTimeoutRef.current = setTimeout(connectFn, delay);
297
+ reconnectTimeoutRef.current = setTimeout(() => {
298
+ if (isMountedRef.current) connectFn();
299
+ }, delay);
291
300
  } else {
292
301
  console.warn(`[Bridge] Max retries reached. Cooldown: ${maxRetryCooldown}ms`);
293
302
  clearTimeoutSafe(maxRetryCooldownRef);
294
303
  maxRetryCooldownRef.current = setTimeout(() => {
304
+ if (!isMountedRef.current) return;
295
305
  console.log("[Bridge] Cooldown complete, reconnecting...");
296
306
  retryCountRef.current = 0;
297
307
  connectFn();
@@ -300,6 +310,25 @@ const BridgeProvider = ({
300
310
  },
301
311
  [maxRetries, retryAfter, maxRetryCooldown, updateStatus]
302
312
  );
313
+ const scheduleSwRestartReconnect = useCallback(
314
+ (connectFn) => {
315
+ if (!isMountedRef.current) return;
316
+ swRestartRetryCountRef.current++;
317
+ const delay = calculateBackoffDelay(
318
+ swRestartRetryCountRef.current,
319
+ CONFIG.SW_RESTART_RETRY_DELAY,
320
+ CONFIG.SW_RESTART_MAX_DELAY
321
+ );
322
+ console.log(
323
+ `[Bridge] Service worker not ready, retrying in ${delay}ms (attempt ${swRestartRetryCountRef.current})`
324
+ );
325
+ updateStatus("reconnecting");
326
+ reconnectTimeoutRef.current = setTimeout(() => {
327
+ if (isMountedRef.current) connectFn();
328
+ }, delay);
329
+ },
330
+ [updateStatus]
331
+ );
303
332
  const connect = useCallback(() => {
304
333
  if (isConnectingRef.current) return;
305
334
  if (retryCountRef.current >= maxRetries) {
@@ -325,10 +354,10 @@ const BridgeProvider = ({
325
354
  if (err) {
326
355
  clearIntervalSafe(errorCheckIntervalRef);
327
356
  if (err.includes("Receiving end does not exist")) {
328
- console.warn("[Bridge] Background not ready, retrying...");
357
+ console.warn("[Bridge] Service worker not ready (may be restarting)...");
329
358
  cleanup();
330
359
  isConnectingRef.current = false;
331
- scheduleReconnect(connect);
360
+ scheduleSwRestartReconnect(connect);
332
361
  }
333
362
  return;
334
363
  }
@@ -347,14 +376,19 @@ const BridgeProvider = ({
347
376
  updateStatus("disconnected");
348
377
  }
349
378
  cleanup();
350
- scheduleReconnect(connect);
379
+ if (isMountedRef.current) {
380
+ scheduleReconnect(connect);
381
+ }
351
382
  });
352
383
  const triggerReconnect = () => {
384
+ if (!isMountedRef.current) return;
353
385
  setIsServiceWorkerAlive(false);
354
386
  updateStatus("reconnecting");
355
387
  retryCountRef.current = 0;
356
388
  isConnectingRef.current = false;
357
- setTimeout(() => {
389
+ clearTimeoutSafe(triggerReconnectTimeoutRef);
390
+ triggerReconnectTimeoutRef.current = setTimeout(() => {
391
+ if (!isMountedRef.current) return;
358
392
  cleanup();
359
393
  connect();
360
394
  }, CONFIG.RECONNECT_DELAY);
@@ -375,6 +409,7 @@ const BridgeProvider = ({
375
409
  setIsServiceWorkerAlive(true);
376
410
  setError(null);
377
411
  retryCountRef.current = 0;
412
+ swRestartRetryCountRef.current = 0;
378
413
  consecutiveTimeoutsRef.current = 0;
379
414
  isConnectingRef.current = false;
380
415
  startHealthMonitor({
@@ -396,6 +431,7 @@ const BridgeProvider = ({
396
431
  handleError,
397
432
  handleMessage,
398
433
  scheduleReconnect,
434
+ scheduleSwRestartReconnect,
399
435
  defaultTimeout,
400
436
  updateStatus,
401
437
  pingInterval
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chromahq/react",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "React bindings for the Chroma Chrome extension framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",