@chromahq/store 1.0.48 → 1.0.49

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
@@ -430,20 +430,30 @@ class BridgeStore {
430
430
  /**
431
431
  * Re-register all event listeners on the bridge
432
432
  * Called after reconnection because React StrictMode may have created a new eventListenersRef
433
+ * IMPORTANT: Remove existing listeners first to prevent duplicate handlers
433
434
  */
434
435
  reregisterEventListeners() {
435
436
  if (!this.bridge.on) return;
436
437
  const eventKey = `store:${this.storeName}:stateChanged`;
437
438
  if (this.stateChangedHandler) {
439
+ if (this.bridge.off) {
440
+ this.bridge.off(eventKey, this.stateChangedHandler);
441
+ }
438
442
  if (STORE_ENABLE_LOGS) {
439
443
  console.log(`BridgeStore[${this.storeName}]: Re-registering listener for '${eventKey}'`);
440
444
  }
441
445
  this.bridge.on(eventKey, this.stateChangedHandler);
442
446
  }
443
447
  if (this.disconnectHandler) {
448
+ if (this.bridge.off) {
449
+ this.bridge.off("bridge:disconnected", this.disconnectHandler);
450
+ }
444
451
  this.bridge.on("bridge:disconnected", this.disconnectHandler);
445
452
  }
446
453
  if (this.reconnectHandler) {
454
+ if (this.bridge.off) {
455
+ this.bridge.off("bridge:connected", this.reconnectHandler);
456
+ }
447
457
  this.bridge.on("bridge:connected", this.reconnectHandler);
448
458
  }
449
459
  }
@@ -611,6 +621,16 @@ function createBridgeStore(bridge, initialState, storeName = "default", readyCal
611
621
  function clearStoreCache() {
612
622
  storeCache.clear();
613
623
  }
624
+ function destroyStore(storeName) {
625
+ const store = storeCache.get(storeName);
626
+ if (store) {
627
+ if (STORE_ENABLE_LOGS) {
628
+ console.log(`BridgeStore[${storeName}]: Destroying store and removing from cache`);
629
+ }
630
+ store.destroy();
631
+ storeCache.delete(storeName);
632
+ }
633
+ }
614
634
 
615
635
  function createActionHookForStore(store, actionsFactory) {
616
636
  return function useCustomActions() {
@@ -940,6 +960,7 @@ exports.createServiceWorkerStore = createServiceWorkerStore;
940
960
  exports.createStore = createStore;
941
961
  exports.createStoreHooks = createStoreHooks;
942
962
  exports.createUIStore = createUIStore;
963
+ exports.destroyStore = destroyStore;
943
964
  exports.init = init;
944
965
  exports.useCentralDispatch = useCentralDispatch;
945
966
  exports.useCentralStore = useCentralStore;
package/dist/index.d.ts CHANGED
@@ -86,6 +86,7 @@ declare class BridgeStore<T> implements CentralStore<T> {
86
86
  /**
87
87
  * Re-register all event listeners on the bridge
88
88
  * Called after reconnection because React StrictMode may have created a new eventListenersRef
89
+ * IMPORTANT: Remove existing listeners first to prevent duplicate handlers
89
90
  */
90
91
  private reregisterEventListeners;
91
92
  private setupVisibilityListener;
@@ -140,6 +141,12 @@ declare class BridgeStore<T> implements CentralStore<T> {
140
141
  }
141
142
  declare function createBridgeStore<T>(bridge: BridgeWithEvents, initialState?: T, storeName?: string, readyCallbacks?: Set<() => void>): CentralStore<T>;
142
143
  declare function clearStoreCache(): void;
144
+ /**
145
+ * Destroy a specific store and remove it from cache.
146
+ * Call this when a store is no longer needed to free memory.
147
+ * @param storeName - The name of the store to destroy
148
+ */
149
+ declare function destroyStore(storeName: string): void;
143
150
 
144
151
  /**
145
152
  * Generic action hook factory for any store instance.
@@ -232,5 +239,5 @@ declare function createUIStore<T = any>(bridge: BridgeWithEvents, initialState?:
232
239
  */
233
240
  declare function init(storeDefinition: StoreDefinition): Promise<any>;
234
241
 
235
- export { BridgeStore, StoreBuilder, chromeStoragePersist, clearStoreCache, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
242
+ export { BridgeStore, StoreBuilder, chromeStoragePersist, clearStoreCache, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, destroyStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
236
243
  export type { Bridge, BridgeWithEvents, BridgeWithHandlers, CentralStore, ExtractSliceState, MergeSlices, PersistOptions, SliceCreator, StoreConfig, StoreDefinition };
package/dist/index.es.js CHANGED
@@ -410,20 +410,30 @@ class BridgeStore {
410
410
  /**
411
411
  * Re-register all event listeners on the bridge
412
412
  * Called after reconnection because React StrictMode may have created a new eventListenersRef
413
+ * IMPORTANT: Remove existing listeners first to prevent duplicate handlers
413
414
  */
414
415
  reregisterEventListeners() {
415
416
  if (!this.bridge.on) return;
416
417
  const eventKey = `store:${this.storeName}:stateChanged`;
417
418
  if (this.stateChangedHandler) {
419
+ if (this.bridge.off) {
420
+ this.bridge.off(eventKey, this.stateChangedHandler);
421
+ }
418
422
  if (STORE_ENABLE_LOGS) {
419
423
  console.log(`BridgeStore[${this.storeName}]: Re-registering listener for '${eventKey}'`);
420
424
  }
421
425
  this.bridge.on(eventKey, this.stateChangedHandler);
422
426
  }
423
427
  if (this.disconnectHandler) {
428
+ if (this.bridge.off) {
429
+ this.bridge.off("bridge:disconnected", this.disconnectHandler);
430
+ }
424
431
  this.bridge.on("bridge:disconnected", this.disconnectHandler);
425
432
  }
426
433
  if (this.reconnectHandler) {
434
+ if (this.bridge.off) {
435
+ this.bridge.off("bridge:connected", this.reconnectHandler);
436
+ }
427
437
  this.bridge.on("bridge:connected", this.reconnectHandler);
428
438
  }
429
439
  }
@@ -591,6 +601,16 @@ function createBridgeStore(bridge, initialState, storeName = "default", readyCal
591
601
  function clearStoreCache() {
592
602
  storeCache.clear();
593
603
  }
604
+ function destroyStore(storeName) {
605
+ const store = storeCache.get(storeName);
606
+ if (store) {
607
+ if (STORE_ENABLE_LOGS) {
608
+ console.log(`BridgeStore[${storeName}]: Destroying store and removing from cache`);
609
+ }
610
+ store.destroy();
611
+ storeCache.delete(storeName);
612
+ }
613
+ }
594
614
 
595
615
  function createActionHookForStore(store, actionsFactory) {
596
616
  return function useCustomActions() {
@@ -910,4 +930,4 @@ async function init(storeDefinition) {
910
930
  }
911
931
  }
912
932
 
913
- export { BridgeStore, StoreBuilder, chromeStoragePersist, clearStoreCache, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
933
+ export { BridgeStore, StoreBuilder, chromeStoragePersist, clearStoreCache, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, destroyStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chromahq/store",
3
- "version": "1.0.48",
3
+ "version": "1.0.49",
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",