@chromahq/store 0.1.0 → 0.1.2
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 +74 -57
- package/dist/index.d.ts +40 -31
- package/dist/index.es.js +74 -58
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -196,6 +196,79 @@ function createBridgeStore(bridge, initialState, storeName = "default") {
|
|
|
196
196
|
return new BridgeStore(bridge, initialState, storeName);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
function createActionHookForStore(store, actionsFactory) {
|
|
200
|
+
return function useCustomActions() {
|
|
201
|
+
const baseActions = useStoreActions(store);
|
|
202
|
+
return React.useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function useStoreActions(store) {
|
|
206
|
+
return React.useMemo(
|
|
207
|
+
() => ({
|
|
208
|
+
update: (partial) => {
|
|
209
|
+
store.setState((state) => ({ ...state, ...partial }));
|
|
210
|
+
},
|
|
211
|
+
updateWith: (updater) => {
|
|
212
|
+
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
213
|
+
},
|
|
214
|
+
replace: (newState) => {
|
|
215
|
+
store.setState(newState, true);
|
|
216
|
+
},
|
|
217
|
+
setState: store.setState.bind(store)
|
|
218
|
+
}),
|
|
219
|
+
[store]
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
function createStoreHooks() {
|
|
223
|
+
const StoreContext = React.createContext(null);
|
|
224
|
+
function StoreProvider({ store, children }) {
|
|
225
|
+
const storeRef = React.useRef(store);
|
|
226
|
+
return React__namespace.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
227
|
+
}
|
|
228
|
+
function useStore(selector) {
|
|
229
|
+
const store = React.useContext(StoreContext);
|
|
230
|
+
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
231
|
+
return useCentralStore(store, selector);
|
|
232
|
+
}
|
|
233
|
+
function useStoreInstance() {
|
|
234
|
+
const store = React.useContext(StoreContext);
|
|
235
|
+
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
236
|
+
return store;
|
|
237
|
+
}
|
|
238
|
+
function useActions() {
|
|
239
|
+
const store = useStoreInstance();
|
|
240
|
+
return useStoreActions(store);
|
|
241
|
+
}
|
|
242
|
+
function useAction(actionKey) {
|
|
243
|
+
const store = useStoreInstance();
|
|
244
|
+
return React__namespace.useCallback(
|
|
245
|
+
(...args) => {
|
|
246
|
+
const fn = store.getState()[actionKey];
|
|
247
|
+
if (typeof fn !== "function") {
|
|
248
|
+
throw new Error("useAction only supports function actions");
|
|
249
|
+
}
|
|
250
|
+
return fn(...args);
|
|
251
|
+
},
|
|
252
|
+
[store, actionKey]
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
function createActionHook(actionsFactory) {
|
|
256
|
+
return function useCustomActions() {
|
|
257
|
+
const store = useStoreInstance();
|
|
258
|
+
const baseActions = useStoreActions(store);
|
|
259
|
+
return React.useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
createActionHook,
|
|
264
|
+
StoreProvider,
|
|
265
|
+
useStore,
|
|
266
|
+
useStoreInstance,
|
|
267
|
+
useActions,
|
|
268
|
+
useAction
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
199
272
|
class StoreBuilder {
|
|
200
273
|
constructor(name = "default") {
|
|
201
274
|
this.config = {
|
|
@@ -253,63 +326,6 @@ function createStore(name) {
|
|
|
253
326
|
return new StoreBuilder(name);
|
|
254
327
|
}
|
|
255
328
|
|
|
256
|
-
function useStoreActions(store) {
|
|
257
|
-
return React.useMemo(
|
|
258
|
-
() => ({
|
|
259
|
-
// Update state with partial data
|
|
260
|
-
update: (partial) => {
|
|
261
|
-
store.setState((state) => ({ ...state, ...partial }));
|
|
262
|
-
},
|
|
263
|
-
// Update state with a function
|
|
264
|
-
updateWith: (updater) => {
|
|
265
|
-
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
266
|
-
},
|
|
267
|
-
// Replace entire state
|
|
268
|
-
replace: (newState) => {
|
|
269
|
-
store.setState(newState, true);
|
|
270
|
-
},
|
|
271
|
-
// Direct access to setState
|
|
272
|
-
setState: store.setState.bind(store)
|
|
273
|
-
}),
|
|
274
|
-
[store]
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
function createStoreHooks() {
|
|
278
|
-
const StoreContext = React.createContext(null);
|
|
279
|
-
function StoreProvider({ store, children }) {
|
|
280
|
-
const storeRef = React.useRef(store);
|
|
281
|
-
return React__namespace.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
282
|
-
}
|
|
283
|
-
function useStore(selector) {
|
|
284
|
-
const store = React.useContext(StoreContext);
|
|
285
|
-
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
286
|
-
return useCentralStore(store, selector);
|
|
287
|
-
}
|
|
288
|
-
function useStoreInstance() {
|
|
289
|
-
const store = React.useContext(StoreContext);
|
|
290
|
-
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
291
|
-
return store;
|
|
292
|
-
}
|
|
293
|
-
function useActions() {
|
|
294
|
-
const store = useStoreInstance();
|
|
295
|
-
return useStoreActions(store);
|
|
296
|
-
}
|
|
297
|
-
function createActionHook(actionsFactory) {
|
|
298
|
-
return function useCustomActions() {
|
|
299
|
-
const store = useStoreInstance();
|
|
300
|
-
const baseActions = useStoreActions(store);
|
|
301
|
-
return React.useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
return {
|
|
305
|
-
StoreProvider,
|
|
306
|
-
useStore,
|
|
307
|
-
useStoreInstance,
|
|
308
|
-
useActions,
|
|
309
|
-
createActionHook
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
329
|
function autoRegisterStoreHandlers(store) {
|
|
314
330
|
if (!store) {
|
|
315
331
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
@@ -398,6 +414,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
398
414
|
exports.BridgeStore = BridgeStore;
|
|
399
415
|
exports.StoreBuilder = StoreBuilder;
|
|
400
416
|
exports.chromeStoragePersist = chromeStoragePersist;
|
|
417
|
+
exports.createActionHookForStore = createActionHookForStore;
|
|
401
418
|
exports.createBridgeStore = createBridgeStore;
|
|
402
419
|
exports.createStore = createStore;
|
|
403
420
|
exports.createStoreHooks = createStoreHooks;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StoreApi, StateCreator } from 'zustand';
|
|
2
|
-
import { StateCreator as StateCreator$1 } from 'zustand/vanilla';
|
|
3
2
|
import * as React from 'react';
|
|
4
3
|
import { ReactNode } from 'react';
|
|
4
|
+
import { StateCreator as StateCreator$1 } from 'zustand/vanilla';
|
|
5
5
|
|
|
6
6
|
type PersistOptions = {
|
|
7
7
|
name: string;
|
|
@@ -65,33 +65,19 @@ declare class BridgeStore<T> implements CentralStore<T> {
|
|
|
65
65
|
declare function createBridgeStore<T>(bridge: BridgeWithEvents, initialState?: T, storeName?: string): CentralStore<T>;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
*
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*/
|
|
76
|
-
withSlices(...slices: StateCreator$1<any, [], [], any>[]): this;
|
|
77
|
-
/**
|
|
78
|
-
* Attach a bridge for cross-context communication
|
|
79
|
-
*/
|
|
80
|
-
withBridge(bridge?: BridgeWithEvents): this;
|
|
81
|
-
/**
|
|
82
|
-
* Create the store
|
|
83
|
-
*/
|
|
84
|
-
create(): Promise<CentralStore<T>>;
|
|
85
|
-
private createBaseStore;
|
|
86
|
-
private createServiceWorkerStore;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Create a new store builder
|
|
68
|
+
* Generic action hook factory for any store instance.
|
|
69
|
+
* Usage:
|
|
70
|
+
* const store = createStore(mergeSlices(sliceA, sliceB));
|
|
71
|
+
* <StoreProvider store={store}> ... </StoreProvider>
|
|
72
|
+
* export const useWalletActions = createActionHookForStore(store, walletActions);
|
|
73
|
+
* export const useCounterActions = createActionHookForStore(store, counterActions);
|
|
74
|
+
* All hooks and actions share the same StoreProvider/context.
|
|
90
75
|
*/
|
|
91
|
-
declare function
|
|
76
|
+
declare function createActionHookForStore<S extends Record<string, any>, ActionMap extends Record<string, (...args: any[]) => void>>(store: CentralStore<S>, actionsFactory: (actions: ReturnType<typeof useStoreActions<S>>) => ActionMap): () => ActionMap;
|
|
92
77
|
|
|
93
78
|
/**
|
|
94
|
-
* Store actions helper
|
|
79
|
+
* Store actions helper: exposes update, updateWith, replace, setState
|
|
80
|
+
* Actions should be defined in your slice and accessed via useActions.
|
|
95
81
|
*/
|
|
96
82
|
declare function useStoreActions<T extends Record<string, any>>(store: CentralStore<T>): {
|
|
97
83
|
update: (partial: Partial<T>) => void;
|
|
@@ -102,11 +88,8 @@ declare function useStoreActions<T extends Record<string, any>>(store: CentralSt
|
|
|
102
88
|
(state: T | ((state: T) => T), replace: true): void;
|
|
103
89
|
};
|
|
104
90
|
};
|
|
105
|
-
/**
|
|
106
|
-
* Create a complete store hook factory with typed providers and action creators
|
|
107
|
-
* This prevents confusion by providing only the hooks you need, not global ones
|
|
108
|
-
*/
|
|
109
91
|
declare function createStoreHooks<T extends Record<string, any>>(): {
|
|
92
|
+
createActionHook: <ActionMap extends Record<string, (...args: any[]) => void>>(actionsFactory: (actions: ReturnType<typeof useStoreActions<T>>) => ActionMap) => () => ActionMap;
|
|
110
93
|
StoreProvider: ({ store, children }: {
|
|
111
94
|
store: CentralStore<T>;
|
|
112
95
|
children: ReactNode;
|
|
@@ -122,8 +105,34 @@ declare function createStoreHooks<T extends Record<string, any>>(): {
|
|
|
122
105
|
(state: T | ((state: T) => T), replace: true): void;
|
|
123
106
|
};
|
|
124
107
|
};
|
|
125
|
-
|
|
108
|
+
useAction: <K extends { [K_1 in keyof T]: T[K_1] extends (...args: any[]) => any ? K_1 : never; }[keyof T]>(actionKey: K) => T[K];
|
|
126
109
|
};
|
|
127
110
|
|
|
128
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Core store builder with fluent API
|
|
113
|
+
*/
|
|
114
|
+
declare class StoreBuilder<T = any> {
|
|
115
|
+
private config;
|
|
116
|
+
constructor(name?: string);
|
|
117
|
+
/**
|
|
118
|
+
* Add state slices to the store
|
|
119
|
+
*/
|
|
120
|
+
withSlices(...slices: StateCreator$1<any, [], [], any>[]): this;
|
|
121
|
+
/**
|
|
122
|
+
* Attach a bridge for cross-context communication
|
|
123
|
+
*/
|
|
124
|
+
withBridge(bridge?: BridgeWithEvents): this;
|
|
125
|
+
/**
|
|
126
|
+
* Create the store
|
|
127
|
+
*/
|
|
128
|
+
create(): Promise<CentralStore<T>>;
|
|
129
|
+
private createBaseStore;
|
|
130
|
+
private createServiceWorkerStore;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a new store builder
|
|
134
|
+
*/
|
|
135
|
+
declare function createStore<T = any>(name?: string): StoreBuilder<T>;
|
|
136
|
+
|
|
137
|
+
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createStore, createStoreHooks, useCentralDispatch, useCentralStore };
|
|
129
138
|
export type { Bridge, BridgeWithEvents, BridgeWithHandlers, CentralStore, ExtractSliceState, MergeSlices, PersistOptions, SliceCreator, StoreConfig, StoreDefinition };
|
package/dist/index.es.js
CHANGED
|
@@ -176,6 +176,79 @@ function createBridgeStore(bridge, initialState, storeName = "default") {
|
|
|
176
176
|
return new BridgeStore(bridge, initialState, storeName);
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
function createActionHookForStore(store, actionsFactory) {
|
|
180
|
+
return function useCustomActions() {
|
|
181
|
+
const baseActions = useStoreActions(store);
|
|
182
|
+
return useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function useStoreActions(store) {
|
|
186
|
+
return useMemo(
|
|
187
|
+
() => ({
|
|
188
|
+
update: (partial) => {
|
|
189
|
+
store.setState((state) => ({ ...state, ...partial }));
|
|
190
|
+
},
|
|
191
|
+
updateWith: (updater) => {
|
|
192
|
+
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
193
|
+
},
|
|
194
|
+
replace: (newState) => {
|
|
195
|
+
store.setState(newState, true);
|
|
196
|
+
},
|
|
197
|
+
setState: store.setState.bind(store)
|
|
198
|
+
}),
|
|
199
|
+
[store]
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function createStoreHooks() {
|
|
203
|
+
const StoreContext = createContext(null);
|
|
204
|
+
function StoreProvider({ store, children }) {
|
|
205
|
+
const storeRef = useRef(store);
|
|
206
|
+
return React.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
207
|
+
}
|
|
208
|
+
function useStore(selector) {
|
|
209
|
+
const store = useContext(StoreContext);
|
|
210
|
+
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
211
|
+
return useCentralStore(store, selector);
|
|
212
|
+
}
|
|
213
|
+
function useStoreInstance() {
|
|
214
|
+
const store = useContext(StoreContext);
|
|
215
|
+
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
216
|
+
return store;
|
|
217
|
+
}
|
|
218
|
+
function useActions() {
|
|
219
|
+
const store = useStoreInstance();
|
|
220
|
+
return useStoreActions(store);
|
|
221
|
+
}
|
|
222
|
+
function useAction(actionKey) {
|
|
223
|
+
const store = useStoreInstance();
|
|
224
|
+
return React.useCallback(
|
|
225
|
+
(...args) => {
|
|
226
|
+
const fn = store.getState()[actionKey];
|
|
227
|
+
if (typeof fn !== "function") {
|
|
228
|
+
throw new Error("useAction only supports function actions");
|
|
229
|
+
}
|
|
230
|
+
return fn(...args);
|
|
231
|
+
},
|
|
232
|
+
[store, actionKey]
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
function createActionHook(actionsFactory) {
|
|
236
|
+
return function useCustomActions() {
|
|
237
|
+
const store = useStoreInstance();
|
|
238
|
+
const baseActions = useStoreActions(store);
|
|
239
|
+
return useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
createActionHook,
|
|
244
|
+
StoreProvider,
|
|
245
|
+
useStore,
|
|
246
|
+
useStoreInstance,
|
|
247
|
+
useActions,
|
|
248
|
+
useAction
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
179
252
|
class StoreBuilder {
|
|
180
253
|
constructor(name = "default") {
|
|
181
254
|
this.config = {
|
|
@@ -233,63 +306,6 @@ function createStore(name) {
|
|
|
233
306
|
return new StoreBuilder(name);
|
|
234
307
|
}
|
|
235
308
|
|
|
236
|
-
function useStoreActions(store) {
|
|
237
|
-
return useMemo(
|
|
238
|
-
() => ({
|
|
239
|
-
// Update state with partial data
|
|
240
|
-
update: (partial) => {
|
|
241
|
-
store.setState((state) => ({ ...state, ...partial }));
|
|
242
|
-
},
|
|
243
|
-
// Update state with a function
|
|
244
|
-
updateWith: (updater) => {
|
|
245
|
-
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
246
|
-
},
|
|
247
|
-
// Replace entire state
|
|
248
|
-
replace: (newState) => {
|
|
249
|
-
store.setState(newState, true);
|
|
250
|
-
},
|
|
251
|
-
// Direct access to setState
|
|
252
|
-
setState: store.setState.bind(store)
|
|
253
|
-
}),
|
|
254
|
-
[store]
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
function createStoreHooks() {
|
|
258
|
-
const StoreContext = createContext(null);
|
|
259
|
-
function StoreProvider({ store, children }) {
|
|
260
|
-
const storeRef = useRef(store);
|
|
261
|
-
return React.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
262
|
-
}
|
|
263
|
-
function useStore(selector) {
|
|
264
|
-
const store = useContext(StoreContext);
|
|
265
|
-
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
266
|
-
return useCentralStore(store, selector);
|
|
267
|
-
}
|
|
268
|
-
function useStoreInstance() {
|
|
269
|
-
const store = useContext(StoreContext);
|
|
270
|
-
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
271
|
-
return store;
|
|
272
|
-
}
|
|
273
|
-
function useActions() {
|
|
274
|
-
const store = useStoreInstance();
|
|
275
|
-
return useStoreActions(store);
|
|
276
|
-
}
|
|
277
|
-
function createActionHook(actionsFactory) {
|
|
278
|
-
return function useCustomActions() {
|
|
279
|
-
const store = useStoreInstance();
|
|
280
|
-
const baseActions = useStoreActions(store);
|
|
281
|
-
return useMemo(() => actionsFactory(baseActions), [baseActions]);
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
return {
|
|
285
|
-
StoreProvider,
|
|
286
|
-
useStore,
|
|
287
|
-
useStoreInstance,
|
|
288
|
-
useActions,
|
|
289
|
-
createActionHook
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
|
|
293
309
|
function autoRegisterStoreHandlers(store) {
|
|
294
310
|
if (!store) {
|
|
295
311
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
@@ -375,4 +391,4 @@ if (typeof globalThis !== "undefined") {
|
|
|
375
391
|
globalThis.initStores = init;
|
|
376
392
|
}
|
|
377
393
|
|
|
378
|
-
export { BridgeStore, StoreBuilder, chromeStoragePersist, createBridgeStore, createStore, createStoreHooks, useCentralDispatch, useCentralStore };
|
|
394
|
+
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createStore, createStoreHooks, useCentralDispatch, useCentralStore };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chromahq/store",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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",
|