@chromahq/store 1.0.4 → 1.0.6
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 +47 -21
- package/dist/index.d.ts +15 -1
- package/dist/index.es.js +46 -22
- package/package.json +6 -3
package/dist/index.cjs.js
CHANGED
|
@@ -260,11 +260,15 @@ class BridgeStore {
|
|
|
260
260
|
}
|
|
261
261
|
setupStateSync() {
|
|
262
262
|
if (this.bridge.on) {
|
|
263
|
-
this.bridge.on(`store:${this.storeName}:stateChanged`, (
|
|
264
|
-
this.
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
this.bridge.on(`store:${this.storeName}:stateChanged`, () => {
|
|
264
|
+
this.bridge.send(`store:${this.storeName}:getState`).then((newState) => {
|
|
265
|
+
this.previousState = this.currentState;
|
|
266
|
+
this.currentState = newState;
|
|
267
|
+
this.notifyListeners();
|
|
268
|
+
});
|
|
267
269
|
});
|
|
270
|
+
} else {
|
|
271
|
+
console.warn(`BridgeStore[${this.storeName}]: Bridge does not support event listening`);
|
|
268
272
|
}
|
|
269
273
|
}
|
|
270
274
|
setState(partial, replace) {
|
|
@@ -310,7 +314,7 @@ function useStoreActions(store) {
|
|
|
310
314
|
store.setState((state) => ({ ...state, ...partial }));
|
|
311
315
|
},
|
|
312
316
|
updateWith: (updater) => {
|
|
313
|
-
store.setState((state) =>
|
|
317
|
+
store.setState((state) => updater(state));
|
|
314
318
|
},
|
|
315
319
|
replace: (newState) => {
|
|
316
320
|
store.setState(newState, true);
|
|
@@ -397,6 +401,13 @@ class StoreBuilder {
|
|
|
397
401
|
this.config.bridge = bridge;
|
|
398
402
|
return this;
|
|
399
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Enable persistence with Chrome storage
|
|
406
|
+
*/
|
|
407
|
+
withPersistence(options) {
|
|
408
|
+
this.config.persistence = options;
|
|
409
|
+
return this;
|
|
410
|
+
}
|
|
400
411
|
/**
|
|
401
412
|
* Create the store
|
|
402
413
|
*/
|
|
@@ -416,10 +427,13 @@ class StoreBuilder {
|
|
|
416
427
|
createServiceWorkerStore() {
|
|
417
428
|
let isReady = false;
|
|
418
429
|
let initialState = null;
|
|
430
|
+
let runtimeBridge;
|
|
419
431
|
const notifyReady = () => {
|
|
420
432
|
isReady = true;
|
|
421
433
|
readyCallbacks.forEach((callback) => callback());
|
|
434
|
+
this.onReadyCallbacks.forEach((callback) => callback());
|
|
422
435
|
readyCallbacks.clear();
|
|
436
|
+
this.onReadyCallbacks.clear();
|
|
423
437
|
};
|
|
424
438
|
const creator = (set, get, store2) => {
|
|
425
439
|
let state = {};
|
|
@@ -438,6 +452,11 @@ class StoreBuilder {
|
|
|
438
452
|
};
|
|
439
453
|
const persistedCreator = chromeStoragePersist(persistOptions)(creator);
|
|
440
454
|
const store = vanilla.createStore(persistedCreator);
|
|
455
|
+
store.subscribe(() => {
|
|
456
|
+
if (runtimeBridge) {
|
|
457
|
+
runtimeBridge.broadcast(`store:${this.config.name}:stateChanged`, store.getState());
|
|
458
|
+
}
|
|
459
|
+
});
|
|
441
460
|
const centralStore = Object.assign(store, {
|
|
442
461
|
isReady: () => isReady,
|
|
443
462
|
reset: () => {
|
|
@@ -447,6 +466,9 @@ class StoreBuilder {
|
|
|
447
466
|
console.warn("ServiceWorkerStore: Cannot reset, initial state not available");
|
|
448
467
|
}
|
|
449
468
|
},
|
|
469
|
+
setBridge: (bridge) => {
|
|
470
|
+
runtimeBridge = bridge;
|
|
471
|
+
},
|
|
450
472
|
onReady: (callback) => {
|
|
451
473
|
if (isReady) {
|
|
452
474
|
callback();
|
|
@@ -464,8 +486,19 @@ class StoreBuilder {
|
|
|
464
486
|
function createStore(name) {
|
|
465
487
|
return new StoreBuilder(name);
|
|
466
488
|
}
|
|
489
|
+
function createServiceWorkerStore(slices, name = "default", persistOptions) {
|
|
490
|
+
const sliceArray = Array.isArray(slices) ? slices : [slices];
|
|
491
|
+
let builder = createStore(name).withSlices(...sliceArray);
|
|
492
|
+
if (persistOptions) {
|
|
493
|
+
builder = builder.withPersistence(persistOptions);
|
|
494
|
+
}
|
|
495
|
+
return builder.create();
|
|
496
|
+
}
|
|
497
|
+
function createUIStore(bridge, initialState, name = "default") {
|
|
498
|
+
return createBridgeStore(bridge, initialState, name);
|
|
499
|
+
}
|
|
467
500
|
|
|
468
|
-
function autoRegisterStoreHandlers(store) {
|
|
501
|
+
function autoRegisterStoreHandlers(store, storeName = "default") {
|
|
469
502
|
if (!store) {
|
|
470
503
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
471
504
|
}
|
|
@@ -486,8 +519,8 @@ function autoRegisterStoreHandlers(store) {
|
|
|
486
519
|
let replace = false;
|
|
487
520
|
if (args.length === 1 && args[0] && typeof args[0] === "object") {
|
|
488
521
|
const payload = args[0];
|
|
489
|
-
if ("partial" in payload
|
|
490
|
-
({ partial, replace } = payload);
|
|
522
|
+
if ("partial" in payload) {
|
|
523
|
+
({ partial, replace = false } = payload);
|
|
491
524
|
} else {
|
|
492
525
|
partial = payload;
|
|
493
526
|
replace = false;
|
|
@@ -509,22 +542,13 @@ function autoRegisterStoreHandlers(store) {
|
|
|
509
542
|
} else {
|
|
510
543
|
store.setState(partial);
|
|
511
544
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
class AutoSubscribeToStoreMessage {
|
|
516
|
-
handle() {
|
|
517
|
-
if (!store) {
|
|
518
|
-
throw new Error("Store instance not available");
|
|
519
|
-
}
|
|
520
|
-
store.subscribe((state, prevState) => {
|
|
521
|
-
});
|
|
545
|
+
const updatedState = store.getState();
|
|
546
|
+
return updatedState;
|
|
522
547
|
}
|
|
523
548
|
}
|
|
524
549
|
return {
|
|
525
550
|
GetStoreStateMessage: AutoGetStoreStateMessage,
|
|
526
|
-
SetStoreStateMessage: AutoSetStoreStateMessage
|
|
527
|
-
SubscribeToStoreMessage: AutoSubscribeToStoreMessage
|
|
551
|
+
SetStoreStateMessage: AutoSetStoreStateMessage
|
|
528
552
|
};
|
|
529
553
|
}
|
|
530
554
|
|
|
@@ -538,7 +562,7 @@ async function init(storeDefinition) {
|
|
|
538
562
|
return {
|
|
539
563
|
def: storeDefinition,
|
|
540
564
|
store,
|
|
541
|
-
classes: autoRegisterStoreHandlers(store)
|
|
565
|
+
classes: autoRegisterStoreHandlers(store, storeDefinition.name)
|
|
542
566
|
};
|
|
543
567
|
} catch (error) {
|
|
544
568
|
console.error(`Failed to initialize store "${storeDefinition.name}":`, error);
|
|
@@ -551,8 +575,10 @@ exports.StoreBuilder = StoreBuilder;
|
|
|
551
575
|
exports.chromeStoragePersist = chromeStoragePersist;
|
|
552
576
|
exports.createActionHookForStore = createActionHookForStore;
|
|
553
577
|
exports.createBridgeStore = createBridgeStore;
|
|
578
|
+
exports.createServiceWorkerStore = createServiceWorkerStore;
|
|
554
579
|
exports.createStore = createStore;
|
|
555
580
|
exports.createStoreHooks = createStoreHooks;
|
|
581
|
+
exports.createUIStore = createUIStore;
|
|
556
582
|
exports.init = init;
|
|
557
583
|
exports.useCentralDispatch = useCentralDispatch;
|
|
558
584
|
exports.useCentralStore = useCentralStore;
|
package/dist/index.d.ts
CHANGED
|
@@ -162,6 +162,10 @@ declare class StoreBuilder<T = any> {
|
|
|
162
162
|
* Attach a bridge for cross-context communication
|
|
163
163
|
*/
|
|
164
164
|
withBridge(bridge?: BridgeWithEvents): this;
|
|
165
|
+
/**
|
|
166
|
+
* Enable persistence with Chrome storage
|
|
167
|
+
*/
|
|
168
|
+
withPersistence(options?: PersistOptions): this;
|
|
165
169
|
/**
|
|
166
170
|
* Create the store
|
|
167
171
|
*/
|
|
@@ -173,11 +177,21 @@ declare class StoreBuilder<T = any> {
|
|
|
173
177
|
* Create a new store builder
|
|
174
178
|
*/
|
|
175
179
|
declare function createStore<T = any>(name?: string): StoreBuilder<T>;
|
|
180
|
+
/**
|
|
181
|
+
* Create a service worker store directly (convenience function)
|
|
182
|
+
* This creates a store optimized for service worker context with persistence
|
|
183
|
+
*/
|
|
184
|
+
declare function createServiceWorkerStore<T = any>(slices: StateCreator$1<T, [], [], T>[] | StateCreator$1<T, [], [], T>, name?: string, persistOptions?: PersistOptions): Promise<CentralStore<T>>;
|
|
185
|
+
/**
|
|
186
|
+
* Create a bridge store directly (convenience function)
|
|
187
|
+
* This creates a store optimized for UI context that connects to service worker
|
|
188
|
+
*/
|
|
189
|
+
declare function createUIStore<T = any>(bridge: BridgeWithEvents, initialState?: T, name?: string): CentralStore<T>;
|
|
176
190
|
|
|
177
191
|
/**
|
|
178
192
|
* Initialize a store from a store definition
|
|
179
193
|
*/
|
|
180
194
|
declare function init(storeDefinition: StoreDefinition): Promise<any>;
|
|
181
195
|
|
|
182
|
-
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createStore, createStoreHooks, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
|
|
196
|
+
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
|
|
183
197
|
export type { Bridge, BridgeWithEvents, BridgeWithHandlers, CentralStore, ExtractSliceState, MergeSlices, PersistOptions, SliceCreator, StoreConfig, StoreDefinition };
|
package/dist/index.es.js
CHANGED
|
@@ -240,11 +240,15 @@ class BridgeStore {
|
|
|
240
240
|
}
|
|
241
241
|
setupStateSync() {
|
|
242
242
|
if (this.bridge.on) {
|
|
243
|
-
this.bridge.on(`store:${this.storeName}:stateChanged`, (
|
|
244
|
-
this.
|
|
245
|
-
|
|
246
|
-
|
|
243
|
+
this.bridge.on(`store:${this.storeName}:stateChanged`, () => {
|
|
244
|
+
this.bridge.send(`store:${this.storeName}:getState`).then((newState) => {
|
|
245
|
+
this.previousState = this.currentState;
|
|
246
|
+
this.currentState = newState;
|
|
247
|
+
this.notifyListeners();
|
|
248
|
+
});
|
|
247
249
|
});
|
|
250
|
+
} else {
|
|
251
|
+
console.warn(`BridgeStore[${this.storeName}]: Bridge does not support event listening`);
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
254
|
setState(partial, replace) {
|
|
@@ -290,7 +294,7 @@ function useStoreActions(store) {
|
|
|
290
294
|
store.setState((state) => ({ ...state, ...partial }));
|
|
291
295
|
},
|
|
292
296
|
updateWith: (updater) => {
|
|
293
|
-
store.setState((state) =>
|
|
297
|
+
store.setState((state) => updater(state));
|
|
294
298
|
},
|
|
295
299
|
replace: (newState) => {
|
|
296
300
|
store.setState(newState, true);
|
|
@@ -377,6 +381,13 @@ class StoreBuilder {
|
|
|
377
381
|
this.config.bridge = bridge;
|
|
378
382
|
return this;
|
|
379
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Enable persistence with Chrome storage
|
|
386
|
+
*/
|
|
387
|
+
withPersistence(options) {
|
|
388
|
+
this.config.persistence = options;
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
380
391
|
/**
|
|
381
392
|
* Create the store
|
|
382
393
|
*/
|
|
@@ -396,10 +407,13 @@ class StoreBuilder {
|
|
|
396
407
|
createServiceWorkerStore() {
|
|
397
408
|
let isReady = false;
|
|
398
409
|
let initialState = null;
|
|
410
|
+
let runtimeBridge;
|
|
399
411
|
const notifyReady = () => {
|
|
400
412
|
isReady = true;
|
|
401
413
|
readyCallbacks.forEach((callback) => callback());
|
|
414
|
+
this.onReadyCallbacks.forEach((callback) => callback());
|
|
402
415
|
readyCallbacks.clear();
|
|
416
|
+
this.onReadyCallbacks.clear();
|
|
403
417
|
};
|
|
404
418
|
const creator = (set, get, store2) => {
|
|
405
419
|
let state = {};
|
|
@@ -418,6 +432,11 @@ class StoreBuilder {
|
|
|
418
432
|
};
|
|
419
433
|
const persistedCreator = chromeStoragePersist(persistOptions)(creator);
|
|
420
434
|
const store = createStore$1(persistedCreator);
|
|
435
|
+
store.subscribe(() => {
|
|
436
|
+
if (runtimeBridge) {
|
|
437
|
+
runtimeBridge.broadcast(`store:${this.config.name}:stateChanged`, store.getState());
|
|
438
|
+
}
|
|
439
|
+
});
|
|
421
440
|
const centralStore = Object.assign(store, {
|
|
422
441
|
isReady: () => isReady,
|
|
423
442
|
reset: () => {
|
|
@@ -427,6 +446,9 @@ class StoreBuilder {
|
|
|
427
446
|
console.warn("ServiceWorkerStore: Cannot reset, initial state not available");
|
|
428
447
|
}
|
|
429
448
|
},
|
|
449
|
+
setBridge: (bridge) => {
|
|
450
|
+
runtimeBridge = bridge;
|
|
451
|
+
},
|
|
430
452
|
onReady: (callback) => {
|
|
431
453
|
if (isReady) {
|
|
432
454
|
callback();
|
|
@@ -444,8 +466,19 @@ class StoreBuilder {
|
|
|
444
466
|
function createStore(name) {
|
|
445
467
|
return new StoreBuilder(name);
|
|
446
468
|
}
|
|
469
|
+
function createServiceWorkerStore(slices, name = "default", persistOptions) {
|
|
470
|
+
const sliceArray = Array.isArray(slices) ? slices : [slices];
|
|
471
|
+
let builder = createStore(name).withSlices(...sliceArray);
|
|
472
|
+
if (persistOptions) {
|
|
473
|
+
builder = builder.withPersistence(persistOptions);
|
|
474
|
+
}
|
|
475
|
+
return builder.create();
|
|
476
|
+
}
|
|
477
|
+
function createUIStore(bridge, initialState, name = "default") {
|
|
478
|
+
return createBridgeStore(bridge, initialState, name);
|
|
479
|
+
}
|
|
447
480
|
|
|
448
|
-
function autoRegisterStoreHandlers(store) {
|
|
481
|
+
function autoRegisterStoreHandlers(store, storeName = "default") {
|
|
449
482
|
if (!store) {
|
|
450
483
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
451
484
|
}
|
|
@@ -466,8 +499,8 @@ function autoRegisterStoreHandlers(store) {
|
|
|
466
499
|
let replace = false;
|
|
467
500
|
if (args.length === 1 && args[0] && typeof args[0] === "object") {
|
|
468
501
|
const payload = args[0];
|
|
469
|
-
if ("partial" in payload
|
|
470
|
-
({ partial, replace } = payload);
|
|
502
|
+
if ("partial" in payload) {
|
|
503
|
+
({ partial, replace = false } = payload);
|
|
471
504
|
} else {
|
|
472
505
|
partial = payload;
|
|
473
506
|
replace = false;
|
|
@@ -489,22 +522,13 @@ function autoRegisterStoreHandlers(store) {
|
|
|
489
522
|
} else {
|
|
490
523
|
store.setState(partial);
|
|
491
524
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
495
|
-
class AutoSubscribeToStoreMessage {
|
|
496
|
-
handle() {
|
|
497
|
-
if (!store) {
|
|
498
|
-
throw new Error("Store instance not available");
|
|
499
|
-
}
|
|
500
|
-
store.subscribe((state, prevState) => {
|
|
501
|
-
});
|
|
525
|
+
const updatedState = store.getState();
|
|
526
|
+
return updatedState;
|
|
502
527
|
}
|
|
503
528
|
}
|
|
504
529
|
return {
|
|
505
530
|
GetStoreStateMessage: AutoGetStoreStateMessage,
|
|
506
|
-
SetStoreStateMessage: AutoSetStoreStateMessage
|
|
507
|
-
SubscribeToStoreMessage: AutoSubscribeToStoreMessage
|
|
531
|
+
SetStoreStateMessage: AutoSetStoreStateMessage
|
|
508
532
|
};
|
|
509
533
|
}
|
|
510
534
|
|
|
@@ -518,7 +542,7 @@ async function init(storeDefinition) {
|
|
|
518
542
|
return {
|
|
519
543
|
def: storeDefinition,
|
|
520
544
|
store,
|
|
521
|
-
classes: autoRegisterStoreHandlers(store)
|
|
545
|
+
classes: autoRegisterStoreHandlers(store, storeDefinition.name)
|
|
522
546
|
};
|
|
523
547
|
} catch (error) {
|
|
524
548
|
console.error(`Failed to initialize store "${storeDefinition.name}":`, error);
|
|
@@ -526,4 +550,4 @@ async function init(storeDefinition) {
|
|
|
526
550
|
}
|
|
527
551
|
}
|
|
528
552
|
|
|
529
|
-
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createStore, createStoreHooks, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
|
|
553
|
+
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createServiceWorkerStore, createStore, createStoreHooks, createUIStore, init, useCentralDispatch, useCentralStore, useStoreReady, useStoreReset };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chromahq/store",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
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",
|
|
@@ -50,10 +50,13 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/chrome": "^0.0.326",
|
|
52
52
|
"@types/react": "^18.2.7",
|
|
53
|
-
"typescript": "^5.8.3"
|
|
53
|
+
"typescript": "^5.8.3",
|
|
54
|
+
"vitest": "^3.2.4"
|
|
54
55
|
},
|
|
55
56
|
"scripts": {
|
|
56
57
|
"build": "rollup -c rollup.config.mjs",
|
|
57
|
-
"dev": "rollup -c rollup.config.mjs --watch"
|
|
58
|
+
"dev": "rollup -c rollup.config.mjs --watch",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:watch": "vitest"
|
|
58
61
|
}
|
|
59
62
|
}
|