@superutils/store 0.1.17 → 0.1.19
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/README.md +69 -50
- package/dist/browser/index.min.js +2 -2
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.cjs +59 -25
- package/dist/index.d.cts +426 -330
- package/dist/index.d.ts +426 -330
- package/dist/index.js +59 -26
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,48 +1,6 @@
|
|
|
1
|
-
import { Subject, BehaviorSubject } from 'rxjs';
|
|
2
1
|
import { ThrottleOptions, DebounceOptions, sort, SortOptions, DropFirst, search, ValueOrPromise, filter, FindOptions, find, TypedMap } from '@superutils/core';
|
|
3
2
|
export { TypedMap, objToMap } from '@superutils/core';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Literal union of all operations that can be intercepted by a validator.
|
|
7
|
-
*/
|
|
8
|
-
type Store_ValidateAction = 'clear' | 'delete' | 'set' | 'setAll' | 'write';
|
|
9
|
-
/**
|
|
10
|
-
* Function signature for an operation-specific validation hook.
|
|
11
|
-
*
|
|
12
|
-
* **Behavior:**
|
|
13
|
-
* - Invoked immediately before the store's internal state is updated.
|
|
14
|
-
* - If validation fails (throw error), the write operation is aborted and error is propagated to the caller.
|
|
15
|
-
*
|
|
16
|
-
* @param params - The specific payload for the action:
|
|
17
|
-
* - `clear`: `[]`
|
|
18
|
-
* - `delete`: `[keys: Key[]]`
|
|
19
|
-
* - `set`: `[key: Key, value: Value]`
|
|
20
|
-
* - `setAll`: `[data: Map<Key, Value>, replace: boolean]`
|
|
21
|
-
* - 'write': `[data: Map<Key, Value>]`
|
|
22
|
-
* @param action - The literal name of the action being performed.
|
|
23
|
-
*
|
|
24
|
-
* @template Key - The type of keys in the store.
|
|
25
|
-
* @template Value - The type of values in the store.
|
|
26
|
-
* @template CacheDisabled - Whether caching is disabled.
|
|
27
|
-
*/
|
|
28
|
-
type Store_ValidateFn<Key, Value, CacheDisabled extends boolean, Action extends keyof IStore<Key, Value> & Store_ValidateAction> = (this: IStore<Key, Value, CacheDisabled>, params: 'clear' extends Action ? [] : 'delete' extends Action ? [keys: Key[]] : 'set' extends Action ? [key: Key, value: Value] : 'setAll' extends Action ? [data?: Map<Key, Value>, replace?: boolean] : 'write' extends Action ? [data: Map<Key, Value>] : [], action: Action) => void | undefined | boolean;
|
|
29
|
-
/**
|
|
30
|
-
* A configuration object containing optional validation hooks for specific store operations.
|
|
31
|
-
*
|
|
32
|
-
* This structure allows for granular control over write operations, enabling you
|
|
33
|
-
* to define custom logic to intercept and prevent invalid state updates.
|
|
34
|
-
*
|
|
35
|
-
* @template Key - The type of keys in the store.
|
|
36
|
-
* @template Value - The type of values in the store.
|
|
37
|
-
* @template CacheDisabled - Whether caching is disabled for the store.
|
|
38
|
-
*/
|
|
39
|
-
type Store_Validate<Key, Value, CacheDisabled extends boolean> = {
|
|
40
|
-
clear?: Store_ValidateFn<Key, Value, CacheDisabled, 'clear'>;
|
|
41
|
-
delete?: Store_ValidateFn<Key, Value, CacheDisabled, 'delete'>;
|
|
42
|
-
set?: Store_ValidateFn<Key, Value, CacheDisabled, 'set'>;
|
|
43
|
-
setAll?: Store_ValidateFn<Key, Value, CacheDisabled, 'setAll'>;
|
|
44
|
-
write?: Store_ValidateFn<Key, Value, CacheDisabled, 'write'>;
|
|
45
|
-
};
|
|
3
|
+
import { Subject, BehaviorSubject } from 'rxjs';
|
|
46
4
|
|
|
47
5
|
/**
|
|
48
6
|
* Represents the minimal subset of the `Storage` interface required for persistence.
|
|
@@ -85,34 +43,6 @@ declare enum Store_OnErrorType {
|
|
|
85
43
|
/** Occurs when the attempt to save data to the underlying storage (e.g., `localStorage.setItem`) fails. */
|
|
86
44
|
write = "write"
|
|
87
45
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Configuration options for initializing a {@link Store} or {@link ObjectStore}.
|
|
90
|
-
*
|
|
91
|
-
* These options define the behavior of caching, persistence, error handling, and validation.
|
|
92
|
-
*/
|
|
93
|
-
type Store_Options<Key, Value, CacheDisabled extends boolean = false> = {
|
|
94
|
-
/**
|
|
95
|
-
* An optional `Map` used to seed the storage if no persistent data is found for the instance.
|
|
96
|
-
*
|
|
97
|
-
* **Data Precedence:**
|
|
98
|
-
* Persistent data associated with the instance's specific `name` takes priority. This value is
|
|
99
|
-
* only utilized if the storage entry for that `name` does not exist (e.g., first-time use).
|
|
100
|
-
*
|
|
101
|
-
* **Initialization Behavior:**
|
|
102
|
-
* - If provided and non-empty, the instance initializes immediately during construction.
|
|
103
|
-
* - Otherwise, initialization is lazy, occurring upon an explicit `init()` call or the first read/write operation.
|
|
104
|
-
*
|
|
105
|
-
* **Type Inference:**
|
|
106
|
-
* When provided, it enables automatic inference of the `Key` and `Value` generic types.
|
|
107
|
-
* If omitted, these default to `unknown` and `object` respectively, unless explicitly defined.
|
|
108
|
-
*
|
|
109
|
-
* Default: `undefined`
|
|
110
|
-
*/
|
|
111
|
-
initialValue?: Map<Key, Value>;
|
|
112
|
-
} & Pick<Partial<IStore<Key, Value, CacheDisabled>>, 'cacheDisabled' | 'onChange' | 'onError' | 'parse' | 'spaces' | 'storage' | 'stringify' | 'validate'> & (CacheDisabled extends false ? Pick<Partial<IStore<Key, Value, CacheDisabled>>, 'delay' | 'delayOptions'> : {
|
|
113
|
-
delay?: never;
|
|
114
|
-
delayOptions?: never;
|
|
115
|
-
});
|
|
116
46
|
/**
|
|
117
47
|
* Function signature for custom data deserialization.
|
|
118
48
|
*
|
|
@@ -171,6 +101,36 @@ type Store_Stringify<Data, ThisArg> = (this: ThisArg, data: Data) => string | un
|
|
|
171
101
|
*/
|
|
172
102
|
type Store_ToJSON<K, V> = (replacer?: null | ((key: K, value: V) => unknown), spacing?: string | number, data?: Map<K, V>) => string;
|
|
173
103
|
|
|
104
|
+
/** Store properties accepted in {@link Store_Options} */
|
|
105
|
+
type Store_OptionKeys = 'cacheDisabled' | 'delay' | 'delayOptions' | 'name' | 'onChange' | 'onError' | 'parse' | 'spaces' | 'storage' | 'stringify' | 'validate';
|
|
106
|
+
/**
|
|
107
|
+
* Configuration options for initializing {@link IStore} instances.
|
|
108
|
+
*
|
|
109
|
+
* These options define the behavior of caching, persistence, error handling, and validation.
|
|
110
|
+
*/
|
|
111
|
+
type Store_Options<Key = unknown, Value = unknown, CacheDisabled extends boolean = false> = {
|
|
112
|
+
/**
|
|
113
|
+
* An optional `Map` used to seed the storage if no persistent data is found for the instance.
|
|
114
|
+
*
|
|
115
|
+
* **Data Precedence:**
|
|
116
|
+
* Persistent data associated with the instance's specific `name` takes priority. This value is
|
|
117
|
+
* only utilized if the storage entry for that `name` does not exist (e.g., first-time use).
|
|
118
|
+
*
|
|
119
|
+
* **Initialization Behavior:**
|
|
120
|
+
* - If provided and non-empty, the instance initializes immediately during construction.
|
|
121
|
+
* - Otherwise, initialization is lazy, occurring upon an explicit `init()` call or the first read/write operation.
|
|
122
|
+
*
|
|
123
|
+
* **Type Inference:**
|
|
124
|
+
* When provided, it enables automatic inference of the `Key` and `Value` generic types.
|
|
125
|
+
* If omitted, these default to `unknown` and `object` respectively, unless explicitly defined.
|
|
126
|
+
*
|
|
127
|
+
* Default: `undefined`
|
|
128
|
+
*/
|
|
129
|
+
initialValue?: Map<Key, Value>;
|
|
130
|
+
} & Pick<Partial<IStore<Key, Value, CacheDisabled>>, Store_OptionKeys> & (CacheDisabled extends false ? Pick<Partial<IStore<Key, Value, CacheDisabled>>, 'delay' | 'delayOptions'> : {
|
|
131
|
+
delay?: never;
|
|
132
|
+
delayOptions?: never;
|
|
133
|
+
});
|
|
174
134
|
/**
|
|
175
135
|
* Represents a generic, reactive, and persistent Map-like data store.
|
|
176
136
|
*
|
|
@@ -186,9 +146,9 @@ type Store_ToJSON<K, V> = (replacer?: null | ((key: K, value: V) => unknown), sp
|
|
|
186
146
|
* @template CacheDisabled - A boolean flag; if `true`, the store operates without an in-memory cache,
|
|
187
147
|
* reading and writing directly to the underlying storage on every operation.
|
|
188
148
|
*/
|
|
189
|
-
interface IStore<Key, Value,
|
|
149
|
+
interface IStore<Key, Value, CD extends boolean = false> {
|
|
190
150
|
/** Disable in-memory cache and only directly read/write from storage (local storage or JSON fle) */
|
|
191
|
-
readonly cacheDisabled:
|
|
151
|
+
readonly cacheDisabled: CD;
|
|
192
152
|
/**
|
|
193
153
|
* Debounce/throttle delay duration in milliseconds for writing to storage when caching is enabled.
|
|
194
154
|
*
|
|
@@ -220,7 +180,7 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
220
180
|
* Note: Execution of this callback is managed by internal subscriptions and will stop
|
|
221
181
|
* firing once {@link unsubscribe} is called.
|
|
222
182
|
*/
|
|
223
|
-
onChange?: (this: IStore<Key, Value,
|
|
183
|
+
onChange?: (this: IStore<Key, Value, CD>, data: Map<Key, Value>) => ValueOrPromise<void | Map<Key, Value>>;
|
|
224
184
|
/**
|
|
225
185
|
* A global error handler invoked whenever an internal operation fails.
|
|
226
186
|
*
|
|
@@ -232,7 +192,7 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
232
192
|
* **Note:** If this handler itself throws an error, the exception is
|
|
233
193
|
* ignored gracefully to prevent application crashes during storage cycles.
|
|
234
194
|
*/
|
|
235
|
-
onError?: (this: IStore<Key, Value,
|
|
195
|
+
onError?: (this: IStore<Key, Value, CD>, err: unknown, type: Store_OnErrorType) => ValueOrPromise<void>;
|
|
236
196
|
/**
|
|
237
197
|
* A callback to customize the deserialization of data read from storage.
|
|
238
198
|
*
|
|
@@ -249,7 +209,7 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
249
209
|
* - If this custom `parse` function fails: {@link onError} is triggered with {@link Store_OnErrorType.parse}.
|
|
250
210
|
* - If the default `JSON.parse` fallback fails: {@link onError} is triggered with {@link Store_OnErrorType.parse_json}.
|
|
251
211
|
*/
|
|
252
|
-
parse?: Store_Parse<Map<Key, Value>, IStore<Key, Value,
|
|
212
|
+
parse?: Store_Parse<Map<Key, Value>, IStore<Key, Value, CD>>;
|
|
253
213
|
/** Get the number of items */
|
|
254
214
|
readonly size: number;
|
|
255
215
|
/** Number of spaces to use when stringifying. Default: `undefined` */
|
|
@@ -312,16 +272,15 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
312
272
|
* const storage = new Store('users', { stringify })
|
|
313
273
|
* ```
|
|
314
274
|
*/
|
|
315
|
-
stringify?: Store_Stringify<Map<Key, Value>, IStore<Key, Value,
|
|
275
|
+
stringify?: Store_Stringify<Map<Key, Value>, IStore<Key, Value, CD>>;
|
|
316
276
|
/**
|
|
317
277
|
* Indicates type of data parsed as
|
|
318
278
|
*
|
|
319
279
|
* Default: 'map'
|
|
320
280
|
*/
|
|
321
281
|
type: string;
|
|
322
|
-
validate?: Store_Validate<Key, Value, CacheDisabled>;
|
|
323
282
|
/**
|
|
324
|
-
* The underlying RxJS
|
|
283
|
+
* The underlying RxJS subject that serves as the primary reactive interface for observing data modifications.
|
|
325
284
|
*
|
|
326
285
|
* Its implementation type is determined by the caching strategy:
|
|
327
286
|
* - **BehaviorSubject**: Used when caching is enabled.
|
|
@@ -329,15 +288,15 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
329
288
|
* - **Subject**: Used when caching is disabled.
|
|
330
289
|
* It acts as a pure event pipe, emitting updates only at the moment they occur without retaining an in-memory copy.
|
|
331
290
|
*/
|
|
332
|
-
readonly subject$:
|
|
291
|
+
readonly subject$: CD extends true ? Subject<Map<Key, Value>> : BehaviorSubject<Map<Key, Value>>;
|
|
333
292
|
/** Clear all items */
|
|
334
|
-
readonly clear: () => IStore<Key, Value,
|
|
293
|
+
readonly clear: () => IStore<Key, Value, CD>;
|
|
335
294
|
/** Delete one or more items by their respective keys */
|
|
336
|
-
readonly delete: (key: Key | Key[]) => IStore<Key, Value,
|
|
295
|
+
readonly delete: (key: Key | Key[]) => IStore<Key, Value, CD>;
|
|
337
296
|
/** Filter items by predicate */
|
|
338
297
|
readonly filter: <AsArray extends boolean = false>(...args: DropFirst<Parameters<typeof filter<Key, Value, AsArray>>>) => ReturnType<typeof filter<Key, Value, AsArray>>;
|
|
339
298
|
/** Find an item by predicate or search criteria */
|
|
340
|
-
readonly find: <IncludeKey extends boolean = false>(predicateOrOptions: FindOptions<Key, Value, IncludeKey> | Parameters<IStore<Key, Value,
|
|
299
|
+
readonly find: <IncludeKey extends boolean = false>(predicateOrOptions: FindOptions<Key, Value, IncludeKey> | Parameters<IStore<Key, Value, CD>['filter']>[0]) => ReturnType<typeof find<Key, Value, IncludeKey>>;
|
|
341
300
|
/** Get item by key */
|
|
342
301
|
readonly get: (key: Key) => Value | undefined;
|
|
343
302
|
/**
|
|
@@ -421,7 +380,7 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
421
380
|
* store.set('count', (prevCount = 0) => prevCount + 1)
|
|
422
381
|
* ```
|
|
423
382
|
*/
|
|
424
|
-
readonly set: (key: Key, value: Value | ((currentValue?: Value) => Value)) => IStore<Key, Value,
|
|
383
|
+
readonly set: (key: Key, value: Value | ((currentValue?: Value) => Value)) => IStore<Key, Value, CD>;
|
|
425
384
|
/**
|
|
426
385
|
* Set multiple entries at once and/or replace the storage entries
|
|
427
386
|
*
|
|
@@ -432,7 +391,7 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
432
391
|
*
|
|
433
392
|
* Default: `false`
|
|
434
393
|
*/
|
|
435
|
-
readonly setAll: (data?: Map<Key, Value>, replace?: boolean) => IStore<Key, Value,
|
|
394
|
+
readonly setAll: (data?: Map<Key, Value>, replace?: boolean) => IStore<Key, Value, CD>;
|
|
436
395
|
/**
|
|
437
396
|
* Sort items in the storage.
|
|
438
397
|
*
|
|
@@ -473,40 +432,400 @@ interface IStore<Key, Value, CacheDisabled extends boolean = false> {
|
|
|
473
432
|
* - If not provided, the current in-memory data is used (if cache is enabled).
|
|
474
433
|
* @returns `true` if the write was successful, `false` otherwise.
|
|
475
434
|
*/
|
|
476
|
-
readonly write: (data?: Map<Key, Value>) =>
|
|
435
|
+
readonly write: (data?: Map<Key, Value>) => boolean;
|
|
477
436
|
}
|
|
478
437
|
|
|
479
|
-
|
|
438
|
+
/** Utility to exclude store props & o in context */
|
|
439
|
+
type ContextExcludeProps<Context> = Context extends object ? {
|
|
440
|
+
[K in keyof Context]: K extends keyof IStore<any, any, any> ? never : Context[K];
|
|
441
|
+
} : never;
|
|
442
|
+
/** Extract context return type */
|
|
443
|
+
type ContextReturn<Context> = Context extends (...args: any[]) => infer R ? R : Context extends object ? Context : unknown;
|
|
444
|
+
/** Validate and exclude store properties from context */
|
|
445
|
+
type ContextValidate<Context, Store> = Context extends (...args: unknown[]) => infer R ? (store: Store) => ContextExcludeProps<R> : ContextExcludeProps<Context>;
|
|
446
|
+
|
|
447
|
+
interface IObjectStore<T extends object = object, CacheDisabled extends boolean = false> extends IStore<keyof T, T[keyof T], CacheDisabled> {
|
|
480
448
|
/**
|
|
481
449
|
* Default: `object`
|
|
482
450
|
*/
|
|
483
451
|
type: string;
|
|
484
452
|
get<Key extends keyof T>(key: Key): T[Key] | undefined;
|
|
485
453
|
getAll(forceRead?: boolean): TypedMap<T>;
|
|
486
|
-
parse?: Store_Parse<
|
|
454
|
+
parse?: Store_Parse<TypedMap<T>, IObjectStore<T, CacheDisabled>>;
|
|
487
455
|
set<Key extends keyof T, Value extends T[Key]>(key: Key, value: Value | ((currentValue?: Value) => Value)): IObjectStore<T, CacheDisabled>;
|
|
488
|
-
setAll(data?:
|
|
489
|
-
stringify?: Store_Stringify<
|
|
490
|
-
|
|
456
|
+
setAll(data?: T | TypedMap<T>, replace?: boolean): IObjectStore<T, CacheDisabled>;
|
|
457
|
+
stringify?: Store_Stringify<TypedMap<T>, IObjectStore<T, CacheDisabled>>;
|
|
458
|
+
/** Convert data/object to typed map */
|
|
459
|
+
toMap(data?: T): TypedMap<T>;
|
|
460
|
+
toObject<O extends object = T>(data?: Map<keyof T, T[keyof T]> | TypedMap<T>): O;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Configuration options for initializing {@link IStore} instances.
|
|
464
|
+
*
|
|
465
|
+
* These options define the behavior of caching, persistence, error handling, and validation.
|
|
466
|
+
*/
|
|
467
|
+
type ObjectStore_Options<T extends object = Record<PropertyKey, unknown>, CacheDisabled extends boolean = false> = {
|
|
468
|
+
/**
|
|
469
|
+
* An optional `Map` used to seed the storage if no persistent data is found for the instance.
|
|
470
|
+
*
|
|
471
|
+
* **Data Precedence:**
|
|
472
|
+
* Persistent data associated with the instance's specific `name` takes priority. This value is
|
|
473
|
+
* only utilized if the storage entry for that `name` does not exist (e.g., first-time use).
|
|
474
|
+
*
|
|
475
|
+
* **Initialization Behavior:**
|
|
476
|
+
* - If provided and non-empty, the instance initializes immediately during construction.
|
|
477
|
+
* - Otherwise, initialization is lazy, occurring upon an explicit `init()` call or the first read/write operation.
|
|
478
|
+
*
|
|
479
|
+
* **Type Inference:**
|
|
480
|
+
* When provided, it enables automatic inference of the `Key` and `Value` generic types.
|
|
481
|
+
* If omitted, these default to `unknown` and `object` respectively, unless explicitly defined.
|
|
482
|
+
*
|
|
483
|
+
* Default: `undefined`
|
|
484
|
+
*/
|
|
485
|
+
initialValue?: T;
|
|
486
|
+
} & Pick<Partial<IObjectStore<T, CacheDisabled>>, Store_OptionKeys> & (CacheDisabled extends false ? Pick<Partial<IObjectStore<T, CacheDisabled>>, 'delay' | 'delayOptions'> : {
|
|
487
|
+
delay?: never;
|
|
488
|
+
delayOptions?: never;
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
declare module './IStore' {
|
|
492
|
+
interface IStore<Key, Value, CD extends boolean = false> {
|
|
493
|
+
/**
|
|
494
|
+
* A configuration object containing optional validation hooks for specific store operations.
|
|
495
|
+
*
|
|
496
|
+
* This structure allows for granular control over write operations, enabling you
|
|
497
|
+
* to define custom logic to intercept and prevent invalid state updates.
|
|
498
|
+
*
|
|
499
|
+
* **Behavior:**
|
|
500
|
+
* - Invoked immediately before the store's internal state is updated.
|
|
501
|
+
* - If validation fails (throw error), the operation is aborted and the error is propagated to the caller.
|
|
502
|
+
* - The `write` validator is invoked during every persistence cycle, serving as a final check
|
|
503
|
+
* after operation-specific hooks (e.g., `set` or `delete`).
|
|
504
|
+
* - For reference-type values (e.g., Objects, Maps, Arrays), validators can be used to mutate the data
|
|
505
|
+
* (e.g., for normalization) before it is committed.
|
|
506
|
+
* - `thisArg`: all validators are bound to the store instance.
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```javascript
|
|
510
|
+
* import { createObjectStore } from '@superutils/store'
|
|
511
|
+
*
|
|
512
|
+
* const settingsStore = createObjectStore({
|
|
513
|
+
* name: 'app-settings',
|
|
514
|
+
* initialValue: {
|
|
515
|
+
* theme: 'light',
|
|
516
|
+
* version: '1.0.0',
|
|
517
|
+
* },
|
|
518
|
+
* validate: {
|
|
519
|
+
* set([key, value]) {
|
|
520
|
+
* console.log(this.size) // "this" refers to the store instance
|
|
521
|
+
* if (key !== 'theme' || ['light', 'dark', 'system'].includes(value)) return
|
|
522
|
+
*
|
|
523
|
+
* // throw error to abort operation
|
|
524
|
+
* throw new Error(`Invalid theme: ${value}`)
|
|
525
|
+
* },
|
|
526
|
+
* delete: ([keys]) => {
|
|
527
|
+
* if (!keys.includes('version')) return
|
|
528
|
+
*
|
|
529
|
+
* throw new Error('The "version" key is protected and cannot be deleted')
|
|
530
|
+
* },
|
|
531
|
+
* },
|
|
532
|
+
* })
|
|
533
|
+
*
|
|
534
|
+
* settingsStore.set('theme', 'system')
|
|
535
|
+
* console.log(settingsStore.get('theme')) // 'system'
|
|
536
|
+
* try {
|
|
537
|
+
* settingsStore.set('theme', 'invalid') // throws error
|
|
538
|
+
* } catch (err) {
|
|
539
|
+
* console.error(err.message)
|
|
540
|
+
* }
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
validate?: Store_Validate<Key, Value, CD>;
|
|
544
|
+
}
|
|
491
545
|
}
|
|
492
546
|
/**
|
|
493
|
-
*
|
|
547
|
+
* A configuration object containing optional validation hooks for specific store operations.
|
|
494
548
|
*
|
|
495
|
-
*
|
|
496
|
-
* - A plain object containing utility methods or properties.
|
|
497
|
-
* - A factory function that receives the {@link IObjectStore} instance and returns an object.
|
|
498
|
-
* This is useful for creating methods that need to interact with the store's data
|
|
499
|
-
* using the store instance itself.
|
|
549
|
+
* See {@link IStore.validate} or inidivdual actions for more details.
|
|
500
550
|
*
|
|
501
551
|
* @template Key - The type of keys in the store.
|
|
502
552
|
* @template Value - The type of values in the store.
|
|
503
|
-
* @template CacheDisabled - Whether caching is disabled for
|
|
553
|
+
* @template CacheDisabled - Whether caching is disabled for the store.
|
|
504
554
|
*/
|
|
505
|
-
type
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
555
|
+
type Store_Validate<Key, Value, CacheDisabled extends boolean, ThisArg extends IStore<Key, Value, CacheDisabled> = IStore<Key, Value, CacheDisabled>> = {
|
|
556
|
+
/**
|
|
557
|
+
* Validator for the `clear()` operation.
|
|
558
|
+
* Invoked before all entries are removed from the store.
|
|
559
|
+
*
|
|
560
|
+
* **Throw an error to invalidate and abort the operation.**
|
|
561
|
+
*
|
|
562
|
+
* @param actionParams - Empty array for this action.
|
|
563
|
+
* @param action - The literal action name: `'clear'`.
|
|
564
|
+
*/
|
|
565
|
+
clear?: (this: ThisArg, actionParams: [], action: 'clear') => void;
|
|
566
|
+
/**
|
|
567
|
+
* Validator for the `delete()` operation.
|
|
568
|
+
* Invoked before one or more entries are removed by their keys.
|
|
569
|
+
*
|
|
570
|
+
* **Throw an error to invalidate and abort the operation.**
|
|
571
|
+
*
|
|
572
|
+
* @param actionParams - Tuple containing the array of keys: `[keys: Key[]]`.
|
|
573
|
+
* @param action - The literal action name: `'delete'`.
|
|
574
|
+
*/
|
|
575
|
+
delete?: (this: ThisArg, actionParams: [keys: Key[]], action: 'delete') => void;
|
|
576
|
+
/**
|
|
577
|
+
* Validator for the `set()` operation.
|
|
578
|
+
* Invoked before a single key-value pair is added or updated.
|
|
579
|
+
*
|
|
580
|
+
* **Throw an error to invalidate and abort the operation.**
|
|
581
|
+
*
|
|
582
|
+
* @param actionParams - Tuple containing the key and value: `[key: Key, value: Value]`.
|
|
583
|
+
* @param action - The literal action name: `'set'`.
|
|
584
|
+
*/
|
|
585
|
+
set?: (this: ThisArg, actionParams: [key: Key, value: Value], action: 'set') => void;
|
|
586
|
+
/**
|
|
587
|
+
* Validator for the `setAll()` operation.
|
|
588
|
+
* Invoked before merging or replacing the entire dataset.
|
|
589
|
+
*
|
|
590
|
+
* **Throw an error to invalidate and abort the operation.**
|
|
591
|
+
*
|
|
592
|
+
* @param actionParams - Tuple containing the data Map and replace flag:
|
|
593
|
+
* `[data?: Map<Key, Value>, replace?: boolean]`.
|
|
594
|
+
* @param action - The literal action name: `'setAll'`.
|
|
595
|
+
*/
|
|
596
|
+
setAll?: (this: ThisArg, actionParams: [data?: Map<Key, Value>, replace?: boolean], action: 'setAll') => void;
|
|
597
|
+
/**
|
|
598
|
+
* Validator for the `write()` operation.
|
|
599
|
+
* Invoked immediately before data is serialized and committed to the underlying storage.
|
|
600
|
+
* This acts as a final gatekeeper for the entire state during persistence.
|
|
601
|
+
*
|
|
602
|
+
* The `write` validator is invoked during every persistence cycle, serving as a final check
|
|
603
|
+
* after operation-specific hooks (like `set` or `delete`).
|
|
604
|
+
*
|
|
605
|
+
* **Throw an error to invalidate and abort the operation.**
|
|
606
|
+
*
|
|
607
|
+
* @param actionParams - Tuple containing the full data Map to be persisted: `[data: Map<Key, Value>]`.
|
|
608
|
+
* @param action - The literal action name: `'write'`.
|
|
609
|
+
*/
|
|
610
|
+
write?: (this: ThisArg, actionParams: [data: Map<Key, Value>], action: 'write') => void;
|
|
509
611
|
};
|
|
612
|
+
/**
|
|
613
|
+
* Literal union of all operations that can be intercepted by a validator.
|
|
614
|
+
*/
|
|
615
|
+
type Store_ValidateAction = 'clear' | 'delete' | 'set' | 'setAll' | 'write';
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Creates a {@link IObjectStore} instance initialized from a plain object.
|
|
619
|
+
*
|
|
620
|
+
* This factory method automatically configures `parse` and `stringify` logic to
|
|
621
|
+
* treat the underlying storage as a serialized object, while providing a
|
|
622
|
+
* type-safe Map-like interface for individual properties.
|
|
623
|
+
*
|
|
624
|
+
* This default behavior can be overridden by providing custom `parse` and `stringify` implementations in `options`.
|
|
625
|
+
*
|
|
626
|
+
* @param options (optional) Configuration options for the storage instance. See {@link ObjectStore_Options} for more.
|
|
627
|
+
* @param options.initialValue (optional) An optional object to populate the storage if it's currently empty.
|
|
628
|
+
* @param options.name (optional) locaStorage key (or JSON filename in NodeJS) for persistence storage.
|
|
629
|
+
* @param context - (optional) A plain object or a factory function that returns an object.
|
|
630
|
+
*
|
|
631
|
+
* **Purpose:**
|
|
632
|
+
* Use `context` to encapsulate domain-specific business logic, helper methods, or non-reactive state
|
|
633
|
+
* directly into the store instance.
|
|
634
|
+
*
|
|
635
|
+
* **Behavior:** See {@link createStore}.
|
|
636
|
+
*
|
|
637
|
+
* @template T (optional) The structure of the object being stored. Can auto-infer from `options.initialValue`.
|
|
638
|
+
* @template CacheDisabled - Whether store data caching is disabled.
|
|
639
|
+
* @template Context - The type of the context object or factory function.
|
|
640
|
+
*
|
|
641
|
+
* @returns A new Store instance mapped to the object's keys and values.
|
|
642
|
+
*
|
|
643
|
+
* @example
|
|
644
|
+
* #### Basic property-based access
|
|
645
|
+
*
|
|
646
|
+
* ```javascript
|
|
647
|
+
* import { createObjectStore } from '@superutils/store'
|
|
648
|
+
*
|
|
649
|
+
* const userStore = createObjectStore('user', {
|
|
650
|
+
* initialValue: {
|
|
651
|
+
* age: 99,
|
|
652
|
+
* name: 'Ninety Nine'
|
|
653
|
+
* }
|
|
654
|
+
* })
|
|
655
|
+
*
|
|
656
|
+
* // Keys are strictly inferred from the interface
|
|
657
|
+
* const name = userStore.get('name') // Type: string | undefined
|
|
658
|
+
* console.log(name) // Prints: 'Ninety Nine'
|
|
659
|
+
*
|
|
660
|
+
* // Update properties with type safety
|
|
661
|
+
* userStore.set('age', 100) // Only numbers are accepted for 'age'
|
|
662
|
+
*
|
|
663
|
+
* // Export the underlying data back to a plain object
|
|
664
|
+
* const user = userStore.toObject()
|
|
665
|
+
* console.log(user) // { age: 100, name: 'Ninety Nine' }
|
|
666
|
+
* ```
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* #### Usage with context
|
|
670
|
+
*
|
|
671
|
+
* ```javascript
|
|
672
|
+
* import { createObjectStore } from '@superutils/store'
|
|
673
|
+
*
|
|
674
|
+
* const getContext = store => ({
|
|
675
|
+
* isAdmin: () => !!store.get('roles')?.includes('admin'),
|
|
676
|
+
* promoteToAdmin() {
|
|
677
|
+
* if (this.isAdmin()) return
|
|
678
|
+
*
|
|
679
|
+
* // Use functional updates to safely modify the roles array
|
|
680
|
+
* store.set('roles', (prev = []) => [...prev, 'admin'])
|
|
681
|
+
* }
|
|
682
|
+
* }
|
|
683
|
+
* // Functional context allows you to attach business logic directly to the store
|
|
684
|
+
* const userStore = createObjectStore(
|
|
685
|
+
* 'user',
|
|
686
|
+
* {
|
|
687
|
+
* initialValue: {
|
|
688
|
+
* age: 25,
|
|
689
|
+
* name: 'Jane Doe',
|
|
690
|
+
* roles: ['guest']
|
|
691
|
+
* },
|
|
692
|
+
* },
|
|
693
|
+
* getContext
|
|
694
|
+
* )
|
|
695
|
+
*
|
|
696
|
+
* // Logic is encapsulated and easy to invoke
|
|
697
|
+
* userStore.promoteToAdmin()
|
|
698
|
+
* console.log(userStore.get('roles')) // ['guest', 'admin']
|
|
699
|
+
* ```
|
|
700
|
+
*
|
|
701
|
+
*/
|
|
702
|
+
declare function createObjectStore<Context extends object | ((store: IObjectStore<T, CacheDisabled>) => object), T extends object = Record<string, unknown>, CacheDisabled extends boolean = false>(options: undefined | null | ObjectStore_Options<T, CacheDisabled>, context: Context & ContextValidate<Context, IObjectStore<T, CacheDisabled>>): IObjectStore<T, CacheDisabled> & ContextReturn<Context>;
|
|
703
|
+
declare function createObjectStore<T extends object = Record<string, unknown>, CacheDisabled extends boolean = false>(options?: ObjectStore_Options<T, CacheDisabled>): IObjectStore<T, CacheDisabled>;
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Store property names that are optional/user-provided and should not be allowed in context.
|
|
707
|
+
*
|
|
708
|
+
* This is used to avoid optional store properties being overriden by context properties
|
|
709
|
+
*/
|
|
710
|
+
declare const OPTIONAL_STORE_PROPS: readonly ["delayOptions", "name", "onChange", "onError", "parse", "spaces", "storage", "stringify", "validate"];
|
|
711
|
+
/**
|
|
712
|
+
* Factory function to create a {@link Store} instance with optional business logic augmented into the store instance.
|
|
713
|
+
*
|
|
714
|
+
* This function provides a convenient way to instantiate a store and attach supplemental
|
|
715
|
+
* logic (context) to it. It supports full type inference for both the store's data
|
|
716
|
+
* and the attached context.
|
|
717
|
+
*
|
|
718
|
+
* @param options - (optional) Configuration options for the store.
|
|
719
|
+
* @param context - (optional) A plain object or a factory function that returns an object.
|
|
720
|
+
* If function provided, it is executed only once during instantiation.
|
|
721
|
+
*
|
|
722
|
+
* **Purpose:**
|
|
723
|
+
* Use `context` to encapsulate domain-specific business logic, helper methods, or non-reactive state
|
|
724
|
+
* directly into the store instance.
|
|
725
|
+
*
|
|
726
|
+
* **Behavior:**
|
|
727
|
+
* - **Non-Reactive:** Updates to context properties do **not** trigger `onChange` or RxJS emissions.
|
|
728
|
+
* - **Non-Persistent:** Context data is purely in-memory and is **not** saved to persistent storage.
|
|
729
|
+
* - **Access to Store:** When a factory function is used, it receives the store instance as an argument.
|
|
730
|
+
* - **Notes**:
|
|
731
|
+
* - Built-in store properties are not allowed
|
|
732
|
+
* - Augmented methods' "thisArg" will be the context as per default JavaScript behavior.
|
|
733
|
+
* - Custom class instances are supported as context. Built-in {@link Store} properties take precedence
|
|
734
|
+
* in the event of a naming conflict.
|
|
735
|
+
*
|
|
736
|
+
* @template Key - The type of keys stored in the map.
|
|
737
|
+
* @template Value - The type of values stored in the map.
|
|
738
|
+
* @template CacheDisabled - Whether store data caching is disabled.
|
|
739
|
+
* @template Context - The type of the context object or factory function.
|
|
740
|
+
*
|
|
741
|
+
* @returns A {@link Store} instance with augmented properties (if any).
|
|
742
|
+
*
|
|
743
|
+
* @example
|
|
744
|
+
* #### Basic usage
|
|
745
|
+
* ```javascript
|
|
746
|
+
* import { createStore } from '@superutils/store'
|
|
747
|
+
*
|
|
748
|
+
* const store = createStore({ initialValue: new Map([['count', 0]])})
|
|
749
|
+
* store.set('count', 1)
|
|
750
|
+
* store.set('count', prevCount => prevCount + 1)
|
|
751
|
+
* console.log(store.get('count')) // 2
|
|
752
|
+
* ```
|
|
753
|
+
*
|
|
754
|
+
* @example
|
|
755
|
+
* #### Store augmented with custom business logic
|
|
756
|
+
* ```javascript
|
|
757
|
+
* import { createStore } from '@superutils/store'
|
|
758
|
+
*
|
|
759
|
+
* const store = createStore({ name: 'user-settings'}, {
|
|
760
|
+
* count: 0,
|
|
761
|
+
* log(msg) {
|
|
762
|
+
* console.log(`[${++this.count}] ${msg}`)
|
|
763
|
+
* }
|
|
764
|
+
* })
|
|
765
|
+
*
|
|
766
|
+
* store.log('Settings updated')
|
|
767
|
+
* console.log(store.count)
|
|
768
|
+
* ```
|
|
769
|
+
*
|
|
770
|
+
* @example
|
|
771
|
+
* #### In-memory store
|
|
772
|
+
* ```javascript
|
|
773
|
+
* import fetch from '@superutils/fetch'
|
|
774
|
+
* import { createStore } from '@superutils/store'
|
|
775
|
+
*
|
|
776
|
+
* // Bypass the name property to create an in-memory store
|
|
777
|
+
* const store = createStore()
|
|
778
|
+
*
|
|
779
|
+
* // This will NOT save the data to localStorage
|
|
780
|
+
* store.set('key', 'value')
|
|
781
|
+
* ```
|
|
782
|
+
*
|
|
783
|
+
* @example
|
|
784
|
+
* #### Store with a functional context
|
|
785
|
+
* ```javascript
|
|
786
|
+
* import { createStore } from '@superutils/store'
|
|
787
|
+
*
|
|
788
|
+
* const authStore = createStore(null, store => ({
|
|
789
|
+
* isAuthenticated: () => store.has('token'),
|
|
790
|
+
* logout: () => {
|
|
791
|
+
* store.delete('token')
|
|
792
|
+
* console.log('logged out')
|
|
793
|
+
* }
|
|
794
|
+
* }))
|
|
795
|
+
*
|
|
796
|
+
* if (authStore.isAuthenticated()) {
|
|
797
|
+
* authStore.logout()
|
|
798
|
+
* }
|
|
799
|
+
* ```
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* #### Augmenting with a custom class instance
|
|
803
|
+
*
|
|
804
|
+
* ```typescript
|
|
805
|
+
* import { createStore } from '@superutils/store'
|
|
806
|
+
*
|
|
807
|
+
* class MyCustomClass {
|
|
808
|
+
* private _count = 0
|
|
809
|
+
* get count() {
|
|
810
|
+
* return this._count
|
|
811
|
+
* }
|
|
812
|
+
* increment = () => this._count++
|
|
813
|
+
* decrement() {
|
|
814
|
+
* return --this._count
|
|
815
|
+
* }
|
|
816
|
+
* }
|
|
817
|
+
*
|
|
818
|
+
* const store = createStore(null, new MyCustomClass())
|
|
819
|
+
* console.log(
|
|
820
|
+
* store.count, // 0
|
|
821
|
+
* store.increment(),// function
|
|
822
|
+
* store.count, // 1
|
|
823
|
+
* store.decrement(), // undefined
|
|
824
|
+
* )
|
|
825
|
+
*```
|
|
826
|
+
*/
|
|
827
|
+
declare function createStore<Context extends object | ((store: IStore<Key, Value, CacheDisabled>) => object), Key, Value, CacheDisabled extends boolean = false>(options: undefined | null | Store_Options<Key, Value, CacheDisabled>, context: Context & ContextValidate<Context, IStore<Key, Value, CacheDisabled>>): IStore<Key, Value, CacheDisabled> & ContextReturn<Context>;
|
|
828
|
+
declare function createStore<Key, Value, CacheDisabled extends boolean = false>(options?: Store_Options<Key, Value, CacheDisabled>): IStore<Key, Value, CacheDisabled>;
|
|
510
829
|
|
|
511
830
|
/**
|
|
512
831
|
* RxJS Subject to trigger forced update of cached data from underlying storage of {@link Store} instances.
|
|
@@ -584,16 +903,15 @@ declare const forceUpdateCache$: Subject<string | boolean | string[]>;
|
|
|
584
903
|
* reference their return types and other method signatures through the interface definition.
|
|
585
904
|
*
|
|
586
905
|
* @see {@link forceUpdateCache$} for cache invalidation across instances.
|
|
587
|
-
* @see {@link Store.fromObject} for object-oriented storage initialization.
|
|
588
906
|
*
|
|
589
907
|
* @example
|
|
590
908
|
* #### Browser Usage 1: use like a map
|
|
591
909
|
* ```javascript
|
|
592
910
|
* import { Store } from '@superutils/store'
|
|
593
911
|
*
|
|
594
|
-
* const
|
|
595
|
-
*
|
|
596
|
-
* const user =
|
|
912
|
+
* const userStore = new Store('users')
|
|
913
|
+
* userStore.set(1, { name: 'Alice', age: 30 })
|
|
914
|
+
* const user = userStore.get(1)
|
|
597
915
|
* console.log(user) // prints: {name: 'Alice', age: 30}
|
|
598
916
|
* ```
|
|
599
917
|
*
|
|
@@ -704,7 +1022,7 @@ This extends IStore<Key, Value, CacheDisabled> = IStore<Key, Value, CacheDisable
|
|
|
704
1022
|
private subscriptions;
|
|
705
1023
|
type: This['type'];
|
|
706
1024
|
validate?: This['validate'];
|
|
707
|
-
constructor(name?: This['name'], options?: Store_Options<Key, Value, CacheDisabled>);
|
|
1025
|
+
constructor(name?: This['name'], options?: Store_Options<Key, Value, CacheDisabled> | null);
|
|
708
1026
|
clear: This['clear'];
|
|
709
1027
|
delete: This['delete'];
|
|
710
1028
|
static messages: {
|
|
@@ -747,226 +1065,4 @@ This extends IStore<Key, Value, CacheDisabled> = IStore<Key, Value, CacheDisable
|
|
|
747
1065
|
write: This['write'];
|
|
748
1066
|
}
|
|
749
1067
|
|
|
750
|
-
|
|
751
|
-
* Defines the shape of the context object that can be attached to a {@link Store}.
|
|
752
|
-
*
|
|
753
|
-
* A context can be:
|
|
754
|
-
* - A plain object containing utility methods or properties.
|
|
755
|
-
* - A factory function that receives the {@link IStore} instance and returns an object.
|
|
756
|
-
* This is useful for creating methods that need to interact with the store's data
|
|
757
|
-
* using the store instance itself.
|
|
758
|
-
*
|
|
759
|
-
* @template Key - The type of keys in the store.
|
|
760
|
-
* @template Value - The type of values in the store.
|
|
761
|
-
* @template CacheDisabled - Whether caching is disabled for this store.
|
|
762
|
-
*/
|
|
763
|
-
type Store_Context<Key, Value, CacheDisabled extends boolean = false> = undefined | object | ((store: IStore<Key, Value, CacheDisabled>) => object);
|
|
764
|
-
type Store_ContextReturn<T> = {
|
|
765
|
-
context: undefined extends T ? never : T extends (...args: any[]) => infer R ? R : T;
|
|
766
|
-
};
|
|
767
|
-
type IStoreWithContext<Key, Value, CacheDisabled extends boolean, Context extends Store_Context<Key, Value, CacheDisabled>> = IStore<Key, Value, CacheDisabled> & Store_ContextReturn<Context>;
|
|
768
|
-
type IObjectStoreWithContext<T extends object, CacheDisabled extends boolean, Context extends Store_Context<keyof T, T[keyof T], CacheDisabled>> = IObjectStore<T, CacheDisabled> & Store_ContextReturn<Context>;
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* Creates a {@link Store} instance initialized from a plain object.
|
|
772
|
-
*
|
|
773
|
-
* This factory method automatically configures `parse` and `stringify` logic to
|
|
774
|
-
* treat the underlying storage as a serialized object, while providing a
|
|
775
|
-
* type-safe Map-like interface for individual properties.
|
|
776
|
-
*
|
|
777
|
-
* This default behavior can be overridden by providing custom `parse` and `stringify` implementations in `options`.
|
|
778
|
-
*
|
|
779
|
-
* @param name (optional) The name for the storage (e.g., localStorage key or filename).
|
|
780
|
-
* @param options (optional) Configuration options for the storage instance.
|
|
781
|
-
* @param options.initialValue (optional) An optional object to populate the storage if it's currently empty.
|
|
782
|
-
* @param options.context - (optional) A plain object or a factory function that returns an object.
|
|
783
|
-
*
|
|
784
|
-
* **Purpose:**
|
|
785
|
-
* Use `context` to encapsulate domain-specific business logic, helper methods, or non-reactive state
|
|
786
|
-
* directly alongside the store instance.
|
|
787
|
-
*
|
|
788
|
-
* **Behavior:**
|
|
789
|
-
* - **Non-Reactive:** Updates to context properties do **not** trigger `onChange` or RxJS emissions.
|
|
790
|
-
* - **Non-Persistent:** Context data is purely in-memory and is **not** saved to persistent storage.
|
|
791
|
-
* - **Access to Store:** When a factory function is used, it receives the store instance as an argument.
|
|
792
|
-
*
|
|
793
|
-
* @template T (optional) The structure of the object being stored. Can auto-infer from `options.initialValue`.
|
|
794
|
-
* @template CacheDisabled (optional) Literal type determining whether to disable in-memory caching.
|
|
795
|
-
*
|
|
796
|
-
* @returns A new Store instance mapped to the object's keys and values.
|
|
797
|
-
*
|
|
798
|
-
* @example
|
|
799
|
-
* #### Basic property-based access
|
|
800
|
-
*
|
|
801
|
-
* ```typescript
|
|
802
|
-
* import { createObjectStore } from '@superutils/store'
|
|
803
|
-
*
|
|
804
|
-
* const storage = createObjectStore('user-profile', {
|
|
805
|
-
* initialValue: {
|
|
806
|
-
* age: 99,
|
|
807
|
-
* name: 'Ninety Nine'
|
|
808
|
-
* }
|
|
809
|
-
* })
|
|
810
|
-
*
|
|
811
|
-
* // Keys are strictly inferred from the interface
|
|
812
|
-
* const name = storage.get('name') // Type: string | undefined
|
|
813
|
-
* console.log(name) // Prints: 'Ninety Nine'
|
|
814
|
-
*
|
|
815
|
-
* // Update properties with type safety
|
|
816
|
-
* storage.set('age', 100) // Only numbers are accepted for 'age'
|
|
817
|
-
*
|
|
818
|
-
* // Export the underlying data back to a plain object
|
|
819
|
-
* const userObj = storage.toObject<User>()
|
|
820
|
-
* console.log(userObj) // { age: 100, name: 'Ninety Nine' }
|
|
821
|
-
* ```
|
|
822
|
-
*
|
|
823
|
-
* @example
|
|
824
|
-
* #### Usage with context
|
|
825
|
-
*
|
|
826
|
-
* ```javascript
|
|
827
|
-
* import { createObjectStore } from '@superutils/store'
|
|
828
|
-
*
|
|
829
|
-
* // Functional context allows you to attach business logic directly to the store
|
|
830
|
-
* const userStore = createObjectStore('user-profile', {
|
|
831
|
-
* initialValue: {
|
|
832
|
-
* age: 25,
|
|
833
|
-
* name: 'Jane Doe',
|
|
834
|
-
* roles: ['guest']
|
|
835
|
-
* },
|
|
836
|
-
* context: store => ({
|
|
837
|
-
* isAdmin: () => !!store.get('roles')?.includes('admin'),
|
|
838
|
-
* promoteToAdmin() {
|
|
839
|
-
* if (this.isAdmin()) return
|
|
840
|
-
*
|
|
841
|
-
* // Use functional updates to safely modify the roles array
|
|
842
|
-
* store.set('roles', (prev = []) => [...prev, 'admin'])
|
|
843
|
-
* }
|
|
844
|
-
* })
|
|
845
|
-
* })
|
|
846
|
-
*
|
|
847
|
-
* // Logic is encapsulated and easy to invoke
|
|
848
|
-
* userStore.context.promoteToAdmin()
|
|
849
|
-
* console.log(userStore.get('roles')) // ['guest', 'admin']
|
|
850
|
-
* ```
|
|
851
|
-
*
|
|
852
|
-
*/
|
|
853
|
-
declare function createObjectStore<T extends object = Record<string, unknown>, CacheDisabled extends boolean = false, Context extends ObjectStore_Context<T, CacheDisabled> = ObjectStore_Context<T, CacheDisabled>>(name?: string | null, options?: ObjectStore_Options<T, CacheDisabled, Context>): IObjectStoreWithContext<T, CacheDisabled, Context>;
|
|
854
|
-
declare function createObjectStore<T extends object = Record<string, unknown>, CacheDisabled extends boolean = false, Context extends ObjectStore_Context<T, CacheDisabled> = ObjectStore_Context<T, CacheDisabled>>(options: ObjectStore_Options<T, CacheDisabled, Context>): IObjectStoreWithContext<T, CacheDisabled, Context>;
|
|
855
|
-
/**
|
|
856
|
-
* Create a {@link Store} instance from an object using `options.initialValue`.
|
|
857
|
-
*/
|
|
858
|
-
declare function createObjectStore<T extends object = Record<string, unknown>, Key extends keyof T = keyof T, Value extends T[Key] = T[Key], CacheDisabled extends boolean = false>(...args: ConstructorParameters<typeof Store<Key, Value, CacheDisabled>>): IObjectStore<T, CacheDisabled>;
|
|
859
|
-
|
|
860
|
-
/**
|
|
861
|
-
* Factory function to create a {@link Store} instance with optional context.
|
|
862
|
-
*
|
|
863
|
-
* This function provides a convenient way to instantiate a store and attach supplemental
|
|
864
|
-
* logic (context) to it. It supports full type inference for both the store's data
|
|
865
|
-
* and the attached context.
|
|
866
|
-
*
|
|
867
|
-
* @param name - The name of the storage (e.g., localStorage key). If null/undefined, the store remains in-memory.
|
|
868
|
-
* @param options - Configuration options for the store
|
|
869
|
-
* @param options.context - (optional) A plain object or a factory function that returns an object.
|
|
870
|
-
*
|
|
871
|
-
* **Purpose:**
|
|
872
|
-
* Use `context` to encapsulate domain-specific business logic, helper methods, or non-reactive state
|
|
873
|
-
* directly alongside the store instance.
|
|
874
|
-
*
|
|
875
|
-
* **Behavior:**
|
|
876
|
-
* - **Non-Reactive:** Updates to context properties do **not** trigger `onChange` or RxJS emissions.
|
|
877
|
-
* - **Non-Persistent:** Context data is purely in-memory and is **not** saved to persistent storage.
|
|
878
|
-
* - **Access to Store:** When a factory function is used, it receives the store instance as an argument.
|
|
879
|
-
*
|
|
880
|
-
* @template Context - The type of the context object or factory function.
|
|
881
|
-
* @template Key - The type of keys stored in the map.
|
|
882
|
-
* @template Value - The type of values stored in the map.
|
|
883
|
-
* @template CacheDisabled - Literal type determining whether to disable in-memory caching.
|
|
884
|
-
*
|
|
885
|
-
* @returns A {@link Store} instance augmented with a `context` property.
|
|
886
|
-
*
|
|
887
|
-
* @example
|
|
888
|
-
* #### Basic store without context
|
|
889
|
-
* ```javascript
|
|
890
|
-
* import { createStore } from '@superutils/store'
|
|
891
|
-
*
|
|
892
|
-
* const store = createStore<string, number>()
|
|
893
|
-
* store.set('count', 1)
|
|
894
|
-
* store.set('count', prevCount => prevCount + 1)
|
|
895
|
-
* ```
|
|
896
|
-
*
|
|
897
|
-
* @example
|
|
898
|
-
* #### Store with a static context object
|
|
899
|
-
* ```javascript
|
|
900
|
-
* import { createStore } from '@superutils/store'
|
|
901
|
-
*
|
|
902
|
-
* const store = createStore('user-settings', {
|
|
903
|
-
* context: {
|
|
904
|
-
* count: 0,
|
|
905
|
-
* log(msg) {
|
|
906
|
-
* console.log(`[${++this.count}] ${msg}`)
|
|
907
|
-
* }
|
|
908
|
-
* }
|
|
909
|
-
* })
|
|
910
|
-
*
|
|
911
|
-
* store.context.log('Setting updated')
|
|
912
|
-
* console.log(store.context.count)
|
|
913
|
-
* ```
|
|
914
|
-
*
|
|
915
|
-
* @example
|
|
916
|
-
* #### In-memory store
|
|
917
|
-
* ```javascript
|
|
918
|
-
* import fetch from '@superutils/fetch'
|
|
919
|
-
* import { createStore } from '@superutils/store'
|
|
920
|
-
*
|
|
921
|
-
* const store = createStore({
|
|
922
|
-
* context: store => ({
|
|
923
|
-
* async getProducts() {
|
|
924
|
-
* const { products } = await fetch.get('https://dummyjson.com/products')
|
|
925
|
-
*
|
|
926
|
-
* const productsMap = new Map(products.map(p => [p.id, p]))
|
|
927
|
-
* store.setAll(productsMap)
|
|
928
|
-
*
|
|
929
|
-
* return productsMap
|
|
930
|
-
* },
|
|
931
|
-
* }),
|
|
932
|
-
* })
|
|
933
|
-
*
|
|
934
|
-
* store.context.getProducts().then(() => {
|
|
935
|
-
* console.log(store.getAll())
|
|
936
|
-
* })
|
|
937
|
-
* ```
|
|
938
|
-
*
|
|
939
|
-
* @example
|
|
940
|
-
* #### Store with a functional context (access to store instance)
|
|
941
|
-
* ```javascript
|
|
942
|
-
* import { createStore } from '@superutils/store'
|
|
943
|
-
*
|
|
944
|
-
* const authStore = createStore('auth', {
|
|
945
|
-
* context: store => ({
|
|
946
|
-
* isAuthenticated: () => store.has('token'),
|
|
947
|
-
* logout: () => store.delete('token')
|
|
948
|
-
* })
|
|
949
|
-
* })
|
|
950
|
-
*
|
|
951
|
-
* if (authStore.context.isAuthenticated()) {
|
|
952
|
-
* authStore.context.logout()
|
|
953
|
-
* }
|
|
954
|
-
* ```
|
|
955
|
-
*/
|
|
956
|
-
declare function createStore<Context extends Store_Context<Key, Value, CacheDisabled>, Key, Value, CacheDisabled extends boolean = false>(name?: ConstructorParameters<typeof Store<Key, Value, CacheDisabled>>[0], options?: Store_Options<Key, Value, CacheDisabled> & {
|
|
957
|
-
context?: Context;
|
|
958
|
-
}): IStoreWithContext<Key, Value, CacheDisabled, Context>;
|
|
959
|
-
declare function createStore<Context extends Store_Context<Key, Value, CacheDisabled>, Key, Value, CacheDisabled extends boolean = false>(options: Store_Options<Key, Value, CacheDisabled> & {
|
|
960
|
-
context?: Context;
|
|
961
|
-
}): IStoreWithContext<Key, Value, CacheDisabled, Context>;
|
|
962
|
-
/**
|
|
963
|
-
* Factory method to create a {@link Store} instance.
|
|
964
|
-
*
|
|
965
|
-
* @param args - Arguments passed directly to the {@link Store} constructor.
|
|
966
|
-
* @template Key - The type of keys stored in the map.
|
|
967
|
-
* @template Value - The type of values stored in the map.
|
|
968
|
-
* @template CacheDisabled - Whether to disable in-memory caching.
|
|
969
|
-
*/
|
|
970
|
-
declare function createStore<Key, Value, CacheDisabled extends boolean = false>(...args: ConstructorParameters<typeof Store<Key, Value, CacheDisabled>>): Store<Key, Value, CacheDisabled>;
|
|
971
|
-
|
|
972
|
-
export { type IObjectStore, type IStore, type ObjectStore_Context, type ObjectStore_Options, type StorageCompact, Store, type Store_DelayOptions, Store_OnErrorType, type Store_Options, type Store_Parse, type Store_Search, type Store_Sort, type Store_SortByComparator, type Store_SortByKey, type Store_SortByPropertyName, type Store_SortOptions, type Store_Stringify, type Store_ToJSON, createObjectStore, createStore, Store as default, forceUpdateCache$ };
|
|
1068
|
+
export { type ContextExcludeProps, type ContextReturn, type ContextValidate, type IObjectStore, type IStore, OPTIONAL_STORE_PROPS, type ObjectStore_Options, type StorageCompact, Store, type Store_DelayOptions, Store_OnErrorType, type Store_OptionKeys, type Store_Options, type Store_Parse, type Store_Search, type Store_Sort, type Store_SortByComparator, type Store_SortByKey, type Store_SortByPropertyName, type Store_SortOptions, type Store_Stringify, type Store_ToJSON, type Store_Validate, type Store_ValidateAction, createObjectStore, createStore, Store as default, forceUpdateCache$ };
|