@chromahq/store 1.0.24 → 1.0.26

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.
package/dist/index.cjs.js CHANGED
@@ -110,7 +110,6 @@ function useStoreReset(store) {
110
110
 
111
111
  const STORE_ENABLE_LOGS = typeof globalThis !== "undefined" && globalThis.__CHROMA_ENABLE_LOGS__ === false ? false : true;
112
112
  class BridgeStore {
113
- // ~1 frame at 60fps
114
113
  constructor(bridge, initialState, storeName = "default", readyCallbacks = /* @__PURE__ */ new Set()) {
115
114
  this.listeners = /* @__PURE__ */ new Set();
116
115
  this.currentState = null;
@@ -124,10 +123,14 @@ class BridgeStore {
124
123
  this.isInitializing = false;
125
124
  // Store handler references for cleanup (prevents memory leaks)
126
125
  this.reconnectHandler = null;
126
+ this.disconnectHandler = null;
127
127
  this.stateChangedHandler = null;
128
128
  // Debounce timer for state sync (optimization for rapid updates)
129
129
  this.stateSyncDebounceTimer = null;
130
130
  this.stateSyncDebounceMs = 16;
131
+ // ~1 frame at 60fps
132
+ // Reconnect delay timer (to allow SW to bootstrap before re-initializing)
133
+ this.reconnectDelayTimer = null;
131
134
  this.initialize = async () => {
132
135
  if (this.isInitializing) {
133
136
  return;
@@ -239,11 +242,19 @@ class BridgeStore {
239
242
  clearTimeout(this.stateSyncDebounceTimer);
240
243
  this.stateSyncDebounceTimer = null;
241
244
  }
245
+ if (this.reconnectDelayTimer) {
246
+ clearTimeout(this.reconnectDelayTimer);
247
+ this.reconnectDelayTimer = null;
248
+ }
242
249
  if (this.bridge.off) {
243
250
  if (this.reconnectHandler) {
244
251
  this.bridge.off("bridge:connected", this.reconnectHandler);
245
252
  this.reconnectHandler = null;
246
253
  }
254
+ if (this.disconnectHandler) {
255
+ this.bridge.off("bridge:disconnected", this.disconnectHandler);
256
+ this.disconnectHandler = null;
257
+ }
247
258
  if (this.stateChangedHandler) {
248
259
  this.bridge.off(`store:${this.storeName}:stateChanged`, this.stateChangedHandler);
249
260
  this.stateChangedHandler = null;
@@ -354,13 +365,27 @@ class BridgeStore {
354
365
  }
355
366
  setupReconnectListener() {
356
367
  if (this.bridge.on) {
368
+ this.disconnectHandler = () => {
369
+ if (STORE_ENABLE_LOGS) {
370
+ console.log(
371
+ `BridgeStore[${this.storeName}]: Bridge disconnected, marking store as not ready`
372
+ );
373
+ }
374
+ this.ready = false;
375
+ };
376
+ this.bridge.on("bridge:disconnected", this.disconnectHandler);
357
377
  this.reconnectHandler = () => {
358
378
  if (STORE_ENABLE_LOGS) {
359
379
  console.log(
360
380
  `BridgeStore[${this.storeName}]: Bridge reconnected, waiting for SW to initialize...`
361
381
  );
362
382
  }
363
- setTimeout(() => {
383
+ if (this.reconnectDelayTimer) {
384
+ clearTimeout(this.reconnectDelayTimer);
385
+ this.reconnectDelayTimer = null;
386
+ }
387
+ this.reconnectDelayTimer = setTimeout(() => {
388
+ this.reconnectDelayTimer = null;
364
389
  if (STORE_ENABLE_LOGS) {
365
390
  console.log(
366
391
  `BridgeStore[${this.storeName}]: Re-initializing after SW startup delay...`
package/dist/index.d.ts CHANGED
@@ -73,9 +73,11 @@ declare class BridgeStore<T> implements CentralStore<T> {
73
73
  private initializationTimer;
74
74
  private isInitializing;
75
75
  private reconnectHandler;
76
+ private disconnectHandler;
76
77
  private stateChangedHandler;
77
78
  private stateSyncDebounceTimer;
78
79
  private readonly stateSyncDebounceMs;
80
+ private reconnectDelayTimer;
79
81
  constructor(bridge: BridgeWithEvents, initialState?: T, storeName?: string, readyCallbacks?: Set<() => void>);
80
82
  private setupReconnectListener;
81
83
  initialize: () => Promise<void>;
package/dist/index.es.js CHANGED
@@ -90,7 +90,6 @@ function useStoreReset(store) {
90
90
 
91
91
  const STORE_ENABLE_LOGS = typeof globalThis !== "undefined" && globalThis.__CHROMA_ENABLE_LOGS__ === false ? false : true;
92
92
  class BridgeStore {
93
- // ~1 frame at 60fps
94
93
  constructor(bridge, initialState, storeName = "default", readyCallbacks = /* @__PURE__ */ new Set()) {
95
94
  this.listeners = /* @__PURE__ */ new Set();
96
95
  this.currentState = null;
@@ -104,10 +103,14 @@ class BridgeStore {
104
103
  this.isInitializing = false;
105
104
  // Store handler references for cleanup (prevents memory leaks)
106
105
  this.reconnectHandler = null;
106
+ this.disconnectHandler = null;
107
107
  this.stateChangedHandler = null;
108
108
  // Debounce timer for state sync (optimization for rapid updates)
109
109
  this.stateSyncDebounceTimer = null;
110
110
  this.stateSyncDebounceMs = 16;
111
+ // ~1 frame at 60fps
112
+ // Reconnect delay timer (to allow SW to bootstrap before re-initializing)
113
+ this.reconnectDelayTimer = null;
111
114
  this.initialize = async () => {
112
115
  if (this.isInitializing) {
113
116
  return;
@@ -219,11 +222,19 @@ class BridgeStore {
219
222
  clearTimeout(this.stateSyncDebounceTimer);
220
223
  this.stateSyncDebounceTimer = null;
221
224
  }
225
+ if (this.reconnectDelayTimer) {
226
+ clearTimeout(this.reconnectDelayTimer);
227
+ this.reconnectDelayTimer = null;
228
+ }
222
229
  if (this.bridge.off) {
223
230
  if (this.reconnectHandler) {
224
231
  this.bridge.off("bridge:connected", this.reconnectHandler);
225
232
  this.reconnectHandler = null;
226
233
  }
234
+ if (this.disconnectHandler) {
235
+ this.bridge.off("bridge:disconnected", this.disconnectHandler);
236
+ this.disconnectHandler = null;
237
+ }
227
238
  if (this.stateChangedHandler) {
228
239
  this.bridge.off(`store:${this.storeName}:stateChanged`, this.stateChangedHandler);
229
240
  this.stateChangedHandler = null;
@@ -334,13 +345,27 @@ class BridgeStore {
334
345
  }
335
346
  setupReconnectListener() {
336
347
  if (this.bridge.on) {
348
+ this.disconnectHandler = () => {
349
+ if (STORE_ENABLE_LOGS) {
350
+ console.log(
351
+ `BridgeStore[${this.storeName}]: Bridge disconnected, marking store as not ready`
352
+ );
353
+ }
354
+ this.ready = false;
355
+ };
356
+ this.bridge.on("bridge:disconnected", this.disconnectHandler);
337
357
  this.reconnectHandler = () => {
338
358
  if (STORE_ENABLE_LOGS) {
339
359
  console.log(
340
360
  `BridgeStore[${this.storeName}]: Bridge reconnected, waiting for SW to initialize...`
341
361
  );
342
362
  }
343
- setTimeout(() => {
363
+ if (this.reconnectDelayTimer) {
364
+ clearTimeout(this.reconnectDelayTimer);
365
+ this.reconnectDelayTimer = null;
366
+ }
367
+ this.reconnectDelayTimer = setTimeout(() => {
368
+ this.reconnectDelayTimer = null;
344
369
  if (STORE_ENABLE_LOGS) {
345
370
  console.log(
346
371
  `BridgeStore[${this.storeName}]: Re-initializing after SW startup delay...`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chromahq/store",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "Centralized, persistent store for Chrome extensions using zustand, accessible from service workers and React, with chrome.storage.local persistence.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",