@chromahq/store 0.1.1 → 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 -51
- package/dist/index.d.ts +46 -25
- package/dist/index.es.js +75 -53
- 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,57 +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: (partial) => {
|
|
260
|
-
store.setState((state) => ({ ...state, ...partial }));
|
|
261
|
-
},
|
|
262
|
-
updateWith: (updater) => {
|
|
263
|
-
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
264
|
-
},
|
|
265
|
-
replace: (newState) => {
|
|
266
|
-
store.setState(newState, true);
|
|
267
|
-
},
|
|
268
|
-
setState: store.setState.bind(store)
|
|
269
|
-
}),
|
|
270
|
-
[store]
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
function createStoreHooks() {
|
|
274
|
-
const StoreContext = React.createContext(null);
|
|
275
|
-
function StoreProvider({ store, children }) {
|
|
276
|
-
const storeRef = React.useRef(store);
|
|
277
|
-
return React__namespace.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
278
|
-
}
|
|
279
|
-
function useStore(selector) {
|
|
280
|
-
const store = React.useContext(StoreContext);
|
|
281
|
-
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
282
|
-
return useCentralStore(store, selector);
|
|
283
|
-
}
|
|
284
|
-
function useStoreInstance() {
|
|
285
|
-
const store = React.useContext(StoreContext);
|
|
286
|
-
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
287
|
-
return store;
|
|
288
|
-
}
|
|
289
|
-
function useActions() {
|
|
290
|
-
const store = useStoreInstance();
|
|
291
|
-
return useStoreActions(store);
|
|
292
|
-
}
|
|
293
|
-
function useAction(actionKey) {
|
|
294
|
-
const store = useStoreInstance();
|
|
295
|
-
const action = useCentralStore(store, (state) => state[actionKey]);
|
|
296
|
-
return action;
|
|
297
|
-
}
|
|
298
|
-
return {
|
|
299
|
-
StoreProvider,
|
|
300
|
-
useStore,
|
|
301
|
-
useStoreInstance,
|
|
302
|
-
useActions,
|
|
303
|
-
useAction
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
|
|
307
329
|
function autoRegisterStoreHandlers(store) {
|
|
308
330
|
if (!store) {
|
|
309
331
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
@@ -392,6 +414,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
392
414
|
exports.BridgeStore = BridgeStore;
|
|
393
415
|
exports.StoreBuilder = StoreBuilder;
|
|
394
416
|
exports.chromeStoragePersist = chromeStoragePersist;
|
|
417
|
+
exports.createActionHookForStore = createActionHookForStore;
|
|
395
418
|
exports.createBridgeStore = createBridgeStore;
|
|
396
419
|
exports.createStore = createStore;
|
|
397
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;
|
|
@@ -64,6 +64,50 @@ declare class BridgeStore<T> implements CentralStore<T> {
|
|
|
64
64
|
}
|
|
65
65
|
declare function createBridgeStore<T>(bridge: BridgeWithEvents, initialState?: T, storeName?: string): CentralStore<T>;
|
|
66
66
|
|
|
67
|
+
/**
|
|
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.
|
|
75
|
+
*/
|
|
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;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Store actions helper: exposes update, updateWith, replace, setState
|
|
80
|
+
* Actions should be defined in your slice and accessed via useActions.
|
|
81
|
+
*/
|
|
82
|
+
declare function useStoreActions<T extends Record<string, any>>(store: CentralStore<T>): {
|
|
83
|
+
update: (partial: Partial<T>) => void;
|
|
84
|
+
updateWith: (updater: (state: T) => Partial<T>) => void;
|
|
85
|
+
replace: (newState: T) => void;
|
|
86
|
+
setState: {
|
|
87
|
+
(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: false): void;
|
|
88
|
+
(state: T | ((state: T) => T), replace: true): void;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
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;
|
|
93
|
+
StoreProvider: ({ store, children }: {
|
|
94
|
+
store: CentralStore<T>;
|
|
95
|
+
children: ReactNode;
|
|
96
|
+
}) => React.FunctionComponentElement<React.ProviderProps<CentralStore<T> | null>>;
|
|
97
|
+
useStore: <U>(selector: (state: T) => U) => U;
|
|
98
|
+
useStoreInstance: () => CentralStore<T>;
|
|
99
|
+
useActions: () => {
|
|
100
|
+
update: (partial: Partial<T>) => void;
|
|
101
|
+
updateWith: (updater: (state: T) => Partial<T>) => void;
|
|
102
|
+
replace: (newState: T) => void;
|
|
103
|
+
setState: {
|
|
104
|
+
(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: false): void;
|
|
105
|
+
(state: T | ((state: T) => T), replace: true): void;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
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];
|
|
109
|
+
};
|
|
110
|
+
|
|
67
111
|
/**
|
|
68
112
|
* Core store builder with fluent API
|
|
69
113
|
*/
|
|
@@ -90,28 +134,5 @@ declare class StoreBuilder<T = any> {
|
|
|
90
134
|
*/
|
|
91
135
|
declare function createStore<T = any>(name?: string): StoreBuilder<T>;
|
|
92
136
|
|
|
93
|
-
|
|
94
|
-
* Create store hooks for context-based state and actions.
|
|
95
|
-
* Use useStore for state selection and useActions for auto-wired actions.
|
|
96
|
-
*/
|
|
97
|
-
declare function createStoreHooks<T extends Record<string, any>>(): {
|
|
98
|
-
StoreProvider: ({ store, children }: {
|
|
99
|
-
store: CentralStore<T>;
|
|
100
|
-
children: ReactNode;
|
|
101
|
-
}) => React.FunctionComponentElement<React.ProviderProps<CentralStore<T> | null>>;
|
|
102
|
-
useStore: <U>(selector: (state: T) => U) => U;
|
|
103
|
-
useStoreInstance: () => CentralStore<T>;
|
|
104
|
-
useActions: () => {
|
|
105
|
-
update: (partial: Partial<T>) => void;
|
|
106
|
-
updateWith: (updater: (state: T) => Partial<T>) => void;
|
|
107
|
-
replace: (newState: T) => void;
|
|
108
|
-
setState: {
|
|
109
|
-
(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: false): void;
|
|
110
|
-
(state: T | ((state: T) => T), replace: true): void;
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
useAction: <K extends keyof T>(actionKey: K) => T[K];
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export { BridgeStore, StoreBuilder, chromeStoragePersist, createBridgeStore, createStore, createStoreHooks, useCentralDispatch, useCentralStore };
|
|
137
|
+
export { BridgeStore, StoreBuilder, chromeStoragePersist, createActionHookForStore, createBridgeStore, createStore, createStoreHooks, useCentralDispatch, useCentralStore };
|
|
117
138
|
export type { Bridge, BridgeWithEvents, BridgeWithHandlers, CentralStore, ExtractSliceState, MergeSlices, PersistOptions, SliceCreator, StoreConfig, StoreDefinition };
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useSyncExternalStore, createContext, useContext, useRef
|
|
2
|
+
import { useSyncExternalStore, createContext, useMemo, useContext, useRef } from 'react';
|
|
3
3
|
import { createStore as createStore$1 } from 'zustand/vanilla';
|
|
4
4
|
|
|
5
5
|
function chromeStoragePersist(options) {
|
|
@@ -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,57 +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: (partial) => {
|
|
240
|
-
store.setState((state) => ({ ...state, ...partial }));
|
|
241
|
-
},
|
|
242
|
-
updateWith: (updater) => {
|
|
243
|
-
store.setState((state) => ({ ...state, ...updater(state) }));
|
|
244
|
-
},
|
|
245
|
-
replace: (newState) => {
|
|
246
|
-
store.setState(newState, true);
|
|
247
|
-
},
|
|
248
|
-
setState: store.setState.bind(store)
|
|
249
|
-
}),
|
|
250
|
-
[store]
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
function createStoreHooks() {
|
|
254
|
-
const StoreContext = createContext(null);
|
|
255
|
-
function StoreProvider({ store, children }) {
|
|
256
|
-
const storeRef = useRef(store);
|
|
257
|
-
return React.createElement(StoreContext.Provider, { value: storeRef.current }, children);
|
|
258
|
-
}
|
|
259
|
-
function useStore(selector) {
|
|
260
|
-
const store = useContext(StoreContext);
|
|
261
|
-
if (!store) throw new Error("useStore must be used within a StoreProvider");
|
|
262
|
-
return useCentralStore(store, selector);
|
|
263
|
-
}
|
|
264
|
-
function useStoreInstance() {
|
|
265
|
-
const store = useContext(StoreContext);
|
|
266
|
-
if (!store) throw new Error("useStoreInstance must be used within a StoreProvider");
|
|
267
|
-
return store;
|
|
268
|
-
}
|
|
269
|
-
function useActions() {
|
|
270
|
-
const store = useStoreInstance();
|
|
271
|
-
return useStoreActions(store);
|
|
272
|
-
}
|
|
273
|
-
function useAction(actionKey) {
|
|
274
|
-
const store = useStoreInstance();
|
|
275
|
-
const action = useCentralStore(store, (state) => state[actionKey]);
|
|
276
|
-
return action;
|
|
277
|
-
}
|
|
278
|
-
return {
|
|
279
|
-
StoreProvider,
|
|
280
|
-
useStore,
|
|
281
|
-
useStoreInstance,
|
|
282
|
-
useActions,
|
|
283
|
-
useAction
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
309
|
function autoRegisterStoreHandlers(store) {
|
|
288
310
|
if (!store) {
|
|
289
311
|
throw new Error("autoRegisterStoreHandlers: store parameter is required");
|
|
@@ -369,4 +391,4 @@ if (typeof globalThis !== "undefined") {
|
|
|
369
391
|
globalThis.initStores = init;
|
|
370
392
|
}
|
|
371
393
|
|
|
372
|
-
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",
|