@effuse/store 1.0.2 → 1.0.3
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 +219 -130
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +219 -130
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/actions/async.ts +0 -15
- package/src/actions/cancellation.ts +0 -5
- package/src/core/store.test.ts +261 -0
- package/src/core/store.ts +56 -152
- package/src/core/types.ts +0 -8
- package/src/devtools/connector.ts +0 -6
- package/src/handlers/index.ts +57 -0
- package/src/handlers/operations.test.ts +232 -0
- package/src/handlers/operations.ts +214 -0
- package/src/handlers/persistence.test.ts +182 -0
- package/src/handlers/persistence.ts +82 -0
- package/src/handlers/subscriptions.test.ts +147 -0
- package/src/handlers/subscriptions.ts +58 -0
- package/src/handlers/types.ts +80 -0
- package/src/persistence/adapters.ts +63 -26
- package/src/reactivity/streams.ts +0 -3
- package/src/registry/index.ts +1 -7
- package/src/validation/schema.ts +0 -7
package/src/core/store.ts
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { Effect, Option, pipe
|
|
25
|
+
import { Effect, Option, pipe } from 'effect';
|
|
26
26
|
import { signal, type Signal } from '@effuse/core';
|
|
27
27
|
import type {
|
|
28
28
|
Store,
|
|
@@ -43,41 +43,23 @@ import {
|
|
|
43
43
|
import {
|
|
44
44
|
createCancellationScope,
|
|
45
45
|
createCancellationToken,
|
|
46
|
-
type CancellationScope,
|
|
47
|
-
type CancellationToken,
|
|
48
46
|
} from '../actions/cancellation.js';
|
|
47
|
+
import {
|
|
48
|
+
setValue,
|
|
49
|
+
resetState,
|
|
50
|
+
batchUpdates,
|
|
51
|
+
updateState,
|
|
52
|
+
addSubscriber,
|
|
53
|
+
addKeySubscriber,
|
|
54
|
+
getSnapshot,
|
|
55
|
+
type StoreInternals,
|
|
56
|
+
type StoreHandlerDeps,
|
|
57
|
+
} from '../handlers/index.js';
|
|
49
58
|
|
|
50
|
-
interface StoreInternals {
|
|
51
|
-
signalMap: Map<string, Signal<unknown>>;
|
|
52
|
-
initialState: Record<string, unknown>;
|
|
53
|
-
actions: Record<string, (...args: unknown[]) => unknown>;
|
|
54
|
-
subscribers: Set<() => void>;
|
|
55
|
-
keySubscribers: Map<string, Set<(value: unknown) => void>>;
|
|
56
|
-
computedSelectors: Map<
|
|
57
|
-
(s: Record<string, unknown>) => unknown,
|
|
58
|
-
Signal<unknown>
|
|
59
|
-
>;
|
|
60
|
-
isBatching: boolean;
|
|
61
|
-
cancellationScope: CancellationScope;
|
|
62
|
-
pendingActions: Map<string, CancellationToken>;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const getSnapshot = (
|
|
66
|
-
signalMap: Map<string, Signal<unknown>>
|
|
67
|
-
): Record<string, unknown> => {
|
|
68
|
-
const snapshot: Record<string, unknown> = {};
|
|
69
|
-
for (const [key, sig] of signalMap) {
|
|
70
|
-
snapshot[key] = sig.value;
|
|
71
|
-
}
|
|
72
|
-
return snapshot;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Store configuration options
|
|
76
59
|
export interface CreateStoreOptions extends StoreOptions {
|
|
77
60
|
storage?: StorageAdapter;
|
|
78
61
|
}
|
|
79
62
|
|
|
80
|
-
// Initialize reactive store
|
|
81
63
|
export const createStore = <T extends object>(
|
|
82
64
|
name: string,
|
|
83
65
|
definition: StoreDefinition<T>,
|
|
@@ -106,6 +88,7 @@ export const createStore = <T extends object>(
|
|
|
106
88
|
);
|
|
107
89
|
|
|
108
90
|
if (config.debug) {
|
|
91
|
+
// eslint-disable-next-line no-console
|
|
109
92
|
console.log(`[store] Creating: ${name}`);
|
|
110
93
|
}
|
|
111
94
|
|
|
@@ -134,6 +117,19 @@ export const createStore = <T extends object>(
|
|
|
134
117
|
|
|
135
118
|
const atomicState = createAtomicState({ ...internals.initialState });
|
|
136
119
|
|
|
120
|
+
const handlerDeps: StoreHandlerDeps = {
|
|
121
|
+
internals,
|
|
122
|
+
atomicState,
|
|
123
|
+
middlewareManager,
|
|
124
|
+
config: {
|
|
125
|
+
name,
|
|
126
|
+
shouldPersist,
|
|
127
|
+
storageKey,
|
|
128
|
+
enableDevtools,
|
|
129
|
+
adapter,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
137
133
|
if (shouldPersist) {
|
|
138
134
|
pipe(
|
|
139
135
|
runAdapter.getItem(adapter, storageKey),
|
|
@@ -158,31 +154,6 @@ export const createStore = <T extends object>(
|
|
|
158
154
|
);
|
|
159
155
|
}
|
|
160
156
|
|
|
161
|
-
const notifySubscribers = (): void => {
|
|
162
|
-
if (internals.isBatching) return;
|
|
163
|
-
for (const callback of internals.subscribers) callback();
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const notifyKeySubscribers = (key: string, value: unknown): void => {
|
|
167
|
-
if (internals.isBatching) return;
|
|
168
|
-
const subs = internals.keySubscribers.get(key);
|
|
169
|
-
if (subs) for (const cb of subs) cb(value);
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const persistState = (): void => {
|
|
173
|
-
if (!shouldPersist) return;
|
|
174
|
-
const snapshot = getSnapshot(internals.signalMap);
|
|
175
|
-
runAdapter.setItem(adapter, storageKey, JSON.stringify(snapshot));
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const updateComputed = (): void => {
|
|
179
|
-
const snapshot = getSnapshot(internals.signalMap);
|
|
180
|
-
for (const [selector, sig] of internals.computedSelectors) {
|
|
181
|
-
const newValue = selector(snapshot);
|
|
182
|
-
if (sig.value !== newValue) sig.value = newValue;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
157
|
const stateProxy = new Proxy({} as Record<string, unknown>, {
|
|
187
158
|
get(_, prop: string) {
|
|
188
159
|
const sig = internals.signalMap.get(prop);
|
|
@@ -192,48 +163,7 @@ export const createStore = <T extends object>(
|
|
|
192
163
|
return undefined;
|
|
193
164
|
},
|
|
194
165
|
set(_, prop: string, value: unknown) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const sig = internals.signalMap.get(prop);
|
|
198
|
-
if (!sig) return false;
|
|
199
|
-
const newState = middlewareManager.execute(
|
|
200
|
-
{ ...atomicState.get(), [prop]: value },
|
|
201
|
-
`set:${prop}`,
|
|
202
|
-
[value]
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
sig.value = newState[prop];
|
|
206
|
-
atomicState.update((s) => ({ ...s, [prop]: newState[prop] }));
|
|
207
|
-
|
|
208
|
-
if (enableDevtools) {
|
|
209
|
-
const time = new Date().toLocaleTimeString();
|
|
210
|
-
console.groupCollapsed(
|
|
211
|
-
`%caction %c${name}/set:${prop} %c@ ${time}`,
|
|
212
|
-
'color: gray; font-weight: lighter;',
|
|
213
|
-
'color: inherit; font-weight: bold;',
|
|
214
|
-
'color: gray; font-weight: lighter;'
|
|
215
|
-
);
|
|
216
|
-
console.log(
|
|
217
|
-
'%cprev state',
|
|
218
|
-
'color: #9E9E9E; font-weight: bold;',
|
|
219
|
-
atomicState.get()
|
|
220
|
-
);
|
|
221
|
-
console.log('%caction', 'color: #03A9F4; font-weight: bold;', {
|
|
222
|
-
type: `set:${prop}`,
|
|
223
|
-
payload: value,
|
|
224
|
-
});
|
|
225
|
-
console.log('%cnext state', 'color: #4CAF50; font-weight: bold;', {
|
|
226
|
-
...atomicState.get(),
|
|
227
|
-
[prop]: newState[prop],
|
|
228
|
-
});
|
|
229
|
-
console.groupEnd();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
notifySubscribers();
|
|
233
|
-
notifyKeySubscribers(prop, newState[prop]);
|
|
234
|
-
persistState();
|
|
235
|
-
updateComputed();
|
|
236
|
-
return true;
|
|
166
|
+
return setValue(handlerDeps, { prop, value });
|
|
237
167
|
},
|
|
238
168
|
});
|
|
239
169
|
|
|
@@ -264,30 +194,35 @@ export const createStore = <T extends object>(
|
|
|
264
194
|
|
|
265
195
|
if (enableDevtools) {
|
|
266
196
|
const time = new Date().toLocaleTimeString();
|
|
197
|
+
// eslint-disable-next-line no-console
|
|
267
198
|
console.groupCollapsed(
|
|
268
199
|
`%caction %c${name}/${key} (async) %c@ ${time}`,
|
|
269
200
|
'color: gray; font-weight: lighter;',
|
|
270
201
|
'color: inherit; font-weight: bold;',
|
|
271
202
|
'color: gray; font-weight: lighter;'
|
|
272
203
|
);
|
|
204
|
+
// eslint-disable-next-line no-console
|
|
273
205
|
console.log(
|
|
274
206
|
'%cprev state',
|
|
275
207
|
'color: #9E9E9E; font-weight: bold;',
|
|
276
208
|
prevState
|
|
277
209
|
);
|
|
210
|
+
// eslint-disable-next-line no-console
|
|
278
211
|
console.log('%caction', 'color: #03A9F4; font-weight: bold;', {
|
|
279
212
|
type: `${name}/${key}`,
|
|
280
213
|
payload: args,
|
|
281
214
|
});
|
|
215
|
+
// eslint-disable-next-line no-console
|
|
282
216
|
console.log(
|
|
283
217
|
'%cnext state',
|
|
284
218
|
'color: #4CAF50; font-weight: bold;',
|
|
285
219
|
currentState
|
|
286
220
|
);
|
|
221
|
+
// eslint-disable-next-line no-console
|
|
287
222
|
console.groupEnd();
|
|
288
223
|
}
|
|
289
224
|
|
|
290
|
-
|
|
225
|
+
for (const callback of internals.subscribers) callback();
|
|
291
226
|
}
|
|
292
227
|
return value;
|
|
293
228
|
})
|
|
@@ -302,30 +237,35 @@ export const createStore = <T extends object>(
|
|
|
302
237
|
|
|
303
238
|
if (enableDevtools) {
|
|
304
239
|
const time = new Date().toLocaleTimeString();
|
|
240
|
+
// eslint-disable-next-line no-console
|
|
305
241
|
console.groupCollapsed(
|
|
306
242
|
`%caction %c${name}/${key} %c@ ${time}`,
|
|
307
243
|
'color: gray; font-weight: lighter;',
|
|
308
244
|
'color: inherit; font-weight: bold;',
|
|
309
245
|
'color: gray; font-weight: lighter;'
|
|
310
246
|
);
|
|
247
|
+
// eslint-disable-next-line no-console
|
|
311
248
|
console.log(
|
|
312
249
|
'%cprev state',
|
|
313
250
|
'color: #9E9E9E; font-weight: bold;',
|
|
314
251
|
prevState
|
|
315
252
|
);
|
|
253
|
+
// eslint-disable-next-line no-console
|
|
316
254
|
console.log('%caction', 'color: #03A9F4; font-weight: bold;', {
|
|
317
255
|
type: `${name}/${key}`,
|
|
318
256
|
payload: args,
|
|
319
257
|
});
|
|
258
|
+
// eslint-disable-next-line no-console
|
|
320
259
|
console.log(
|
|
321
260
|
'%cnext state',
|
|
322
261
|
'color: #4CAF50; font-weight: bold;',
|
|
323
262
|
currentState
|
|
324
263
|
);
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
325
265
|
console.groupEnd();
|
|
326
266
|
}
|
|
327
267
|
|
|
328
|
-
|
|
268
|
+
for (const callback of internals.subscribers) callback();
|
|
329
269
|
|
|
330
270
|
return result;
|
|
331
271
|
};
|
|
@@ -340,28 +280,15 @@ export const createStore = <T extends object>(
|
|
|
340
280
|
name,
|
|
341
281
|
state: storeState as StoreState<T>,
|
|
342
282
|
|
|
343
|
-
subscribe: (callback) => {
|
|
344
|
-
internals.subscribers.add(callback);
|
|
345
|
-
return () => {
|
|
346
|
-
internals.subscribers.delete(callback);
|
|
347
|
-
};
|
|
348
|
-
},
|
|
283
|
+
subscribe: (callback) => addSubscriber(internals, { callback }),
|
|
349
284
|
|
|
350
285
|
subscribeToKey: (key, callback) => {
|
|
351
286
|
const keyStr = String(key);
|
|
352
|
-
let subs = internals.keySubscribers.get(keyStr);
|
|
353
|
-
if (!subs) {
|
|
354
|
-
subs = new Set();
|
|
355
|
-
internals.keySubscribers.set(keyStr, subs);
|
|
356
|
-
}
|
|
357
287
|
const typedCallback = callback as (value: unknown) => void;
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
subsSet.delete(typedCallback);
|
|
363
|
-
}
|
|
364
|
-
};
|
|
288
|
+
return addKeySubscriber(internals, {
|
|
289
|
+
key: keyStr,
|
|
290
|
+
callback: typedCallback,
|
|
291
|
+
});
|
|
365
292
|
},
|
|
366
293
|
|
|
367
294
|
getSnapshot: () =>
|
|
@@ -381,23 +308,11 @@ export const createStore = <T extends object>(
|
|
|
381
308
|
},
|
|
382
309
|
|
|
383
310
|
batch: (updates) => {
|
|
384
|
-
|
|
385
|
-
updates();
|
|
386
|
-
internals.isBatching = false;
|
|
387
|
-
notifySubscribers();
|
|
388
|
-
persistState();
|
|
389
|
-
updateComputed();
|
|
311
|
+
batchUpdates(handlerDeps, updates);
|
|
390
312
|
},
|
|
391
313
|
|
|
392
314
|
reset: () => {
|
|
393
|
-
|
|
394
|
-
const sig = internals.signalMap.get(key);
|
|
395
|
-
if (sig) sig.value = value;
|
|
396
|
-
}
|
|
397
|
-
atomicState.set({ ...internals.initialState });
|
|
398
|
-
notifySubscribers();
|
|
399
|
-
persistState();
|
|
400
|
-
updateComputed();
|
|
315
|
+
resetState(handlerDeps);
|
|
401
316
|
},
|
|
402
317
|
|
|
403
318
|
use: (middleware: Middleware<Record<string, unknown>>) =>
|
|
@@ -407,27 +322,9 @@ export const createStore = <T extends object>(
|
|
|
407
322
|
getSnapshot(internals.signalMap) as ReturnType<Store<T>['getSnapshot']>,
|
|
408
323
|
|
|
409
324
|
update: (updater) => {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
: T[K];
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
updater(draft);
|
|
417
|
-
|
|
418
|
-
internals.isBatching = true;
|
|
419
|
-
for (const [key, val] of Object.entries(draft)) {
|
|
420
|
-
const sig = internals.signalMap.get(key);
|
|
421
|
-
if (sig && sig.value !== val) {
|
|
422
|
-
sig.value = val;
|
|
423
|
-
atomicState.update((s) => ({ ...s, [key]: val }));
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
internals.isBatching = false;
|
|
427
|
-
|
|
428
|
-
notifySubscribers();
|
|
429
|
-
persistState();
|
|
430
|
-
updateComputed();
|
|
325
|
+
updateState(handlerDeps, {
|
|
326
|
+
updater: updater as (d: Record<string, unknown>) => void,
|
|
327
|
+
});
|
|
431
328
|
},
|
|
432
329
|
|
|
433
330
|
select: <R>(
|
|
@@ -460,6 +357,13 @@ export const createStore = <T extends object>(
|
|
|
460
357
|
if (propStr in boundActions) return boundActions[propStr];
|
|
461
358
|
return undefined;
|
|
462
359
|
},
|
|
360
|
+
set(target, prop: string | symbol, value: unknown): boolean {
|
|
361
|
+
const propStr = String(prop);
|
|
362
|
+
if (propStr in target) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
return setValue(handlerDeps, { prop: propStr, value });
|
|
366
|
+
},
|
|
463
367
|
}) as Store<T> & StoreState<T>;
|
|
464
368
|
|
|
465
369
|
registerStore(name, storeProxy);
|
package/src/core/types.ts
CHANGED
|
@@ -31,41 +31,34 @@ export const StoreOptionsSchema = Schema.Struct({
|
|
|
31
31
|
devtools: Schema.optional(Schema.Boolean),
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
// Store configuration schema
|
|
35
34
|
export type StoreOptions = Schema.Schema.Type<typeof StoreOptionsSchema>;
|
|
36
35
|
|
|
37
|
-
// Reactive store state
|
|
38
36
|
export type StoreState<T> = {
|
|
39
37
|
[K in keyof T]: T[K] extends (...args: infer A) => infer R
|
|
40
38
|
? (...args: A) => R
|
|
41
39
|
: Signal<T[K]>;
|
|
42
40
|
};
|
|
43
41
|
|
|
44
|
-
// Internal store context
|
|
45
42
|
export type StoreContext<T> = {
|
|
46
43
|
[K in keyof T]: T[K] extends (...args: unknown[]) => unknown
|
|
47
44
|
? T[K]
|
|
48
45
|
: Signal<T[K]>;
|
|
49
46
|
};
|
|
50
47
|
|
|
51
|
-
// Store definition structure
|
|
52
48
|
export type StoreDefinition<T> = {
|
|
53
49
|
[K in keyof T]: T[K] extends (...args: infer A) => infer R
|
|
54
50
|
? (this: StoreContext<T>, ...args: A) => R
|
|
55
51
|
: T[K];
|
|
56
52
|
};
|
|
57
53
|
|
|
58
|
-
// Action execution context
|
|
59
54
|
export type ActionContext<T> = StoreContext<T>;
|
|
60
55
|
|
|
61
|
-
// Global state middleware
|
|
62
56
|
export type Middleware<T> = (
|
|
63
57
|
state: T,
|
|
64
58
|
action: string,
|
|
65
59
|
args: unknown[]
|
|
66
60
|
) => T | undefined;
|
|
67
61
|
|
|
68
|
-
// Reactive store instance
|
|
69
62
|
export interface Store<T> {
|
|
70
63
|
readonly name: string;
|
|
71
64
|
readonly state: StoreState<T>;
|
|
@@ -96,7 +89,6 @@ export interface Store<T> {
|
|
|
96
89
|
select: <R>(selector: (snapshot: Record<string, unknown>) => R) => Signal<R>;
|
|
97
90
|
}
|
|
98
91
|
|
|
99
|
-
// Extract state type from store
|
|
100
92
|
export type InferStoreState<S> =
|
|
101
93
|
S extends Store<infer T>
|
|
102
94
|
? {
|
|
@@ -35,7 +35,6 @@ interface DevToolsConnection {
|
|
|
35
35
|
subscribe: (listener: (message: { type: string }) => void) => () => void;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// Detect Redux DevTools extension
|
|
39
38
|
export const hasDevTools = (): boolean => {
|
|
40
39
|
if (typeof globalThis === 'undefined') return false;
|
|
41
40
|
const w = globalThis as unknown as {
|
|
@@ -46,7 +45,6 @@ export const hasDevTools = (): boolean => {
|
|
|
46
45
|
|
|
47
46
|
const connections = new Map<string, DevToolsConnection>();
|
|
48
47
|
|
|
49
|
-
// Connect store to DevTools
|
|
50
48
|
export const connectDevTools = <T>(
|
|
51
49
|
store: Store<T>,
|
|
52
50
|
options?: { name?: string }
|
|
@@ -86,7 +84,6 @@ export const connectDevTools = <T>(
|
|
|
86
84
|
};
|
|
87
85
|
};
|
|
88
86
|
|
|
89
|
-
// DevTools reporting middleware
|
|
90
87
|
export const devToolsMiddleware = <T>(storeName: string) => {
|
|
91
88
|
return (state: T, action: string, args: unknown[]): T | undefined => {
|
|
92
89
|
const connection = connections.get(storeName);
|
|
@@ -100,16 +97,13 @@ export const devToolsMiddleware = <T>(storeName: string) => {
|
|
|
100
97
|
};
|
|
101
98
|
};
|
|
102
99
|
|
|
103
|
-
// Build DevTools middleware
|
|
104
100
|
export const createDevToolsMiddleware = <T>(storeName: string) =>
|
|
105
101
|
devToolsMiddleware<T>(storeName);
|
|
106
102
|
|
|
107
|
-
// Disconnect store from DevTools
|
|
108
103
|
export const disconnectDevTools = (storeName: string): void => {
|
|
109
104
|
connections.delete(storeName);
|
|
110
105
|
};
|
|
111
106
|
|
|
112
|
-
// Disconnect all DevTools connections
|
|
113
107
|
export const disconnectAllDevTools = (): void => {
|
|
114
108
|
connections.clear();
|
|
115
109
|
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIT License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 Chris M. Perez
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export type {
|
|
26
|
+
StoreInternals,
|
|
27
|
+
StoreConfig,
|
|
28
|
+
StoreHandlerDeps,
|
|
29
|
+
SetValueInput,
|
|
30
|
+
} from './types.js';
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
setValue,
|
|
34
|
+
resetState,
|
|
35
|
+
batchUpdates,
|
|
36
|
+
updateState,
|
|
37
|
+
getSnapshot,
|
|
38
|
+
} from './operations.js';
|
|
39
|
+
|
|
40
|
+
export { addSubscriber, addKeySubscriber } from './subscriptions.js';
|
|
41
|
+
|
|
42
|
+
export type {
|
|
43
|
+
StorageHandlerDeps,
|
|
44
|
+
StorageGetInput,
|
|
45
|
+
StorageSetInput,
|
|
46
|
+
StorageRemoveInput,
|
|
47
|
+
} from './persistence.js';
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
getItem,
|
|
51
|
+
setItem,
|
|
52
|
+
removeItem,
|
|
53
|
+
hasItem,
|
|
54
|
+
clearStorage,
|
|
55
|
+
getStorageKeys,
|
|
56
|
+
getStorageSize,
|
|
57
|
+
} from './persistence.js';
|