@superutils/rx 0.1.3 → 0.1.5
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 +32 -0
- package/dist/browser/index.min.js +2 -2
- package/dist/browser/index.min.js.map +1 -1
- package/dist/index.cjs +252 -147
- package/dist/index.d.cts +173 -80
- package/dist/index.d.ts +173 -80
- package/dist/index.js +253 -148
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -143,50 +143,71 @@ declare namespace copyRxSubject {
|
|
|
143
143
|
var IGNORE_UPDATE_SYMBOL: typeof IGNORE_UPDATE_SYMBOL;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
/** Throttle & debounce related options */
|
|
146
147
|
type DelayOptions = ({
|
|
147
148
|
throttle: true;
|
|
148
149
|
} & Omit<ThrottleOptions, 'onError' | 'thisArg'>) | ({
|
|
149
150
|
throttle?: false;
|
|
150
151
|
} & Omit<DebounceOptions, 'onError' | 'thisArg'>);
|
|
151
|
-
type OnErrorType = 'onChange' | 'parse' | 'parse-json' | 'stringify' | 'stringify-json' | 'write';
|
|
152
|
-
/** Storage type with only properties that are used by `DataStorage` */
|
|
153
|
-
type StorageCompact = Pick<Storage, 'getItem' | 'setItem'>;
|
|
154
|
-
type StorageFilter<K, V extends StorageValue> = <IncludeKey extends boolean = false>(...args: DropFirst<Parameters<typeof filter<K, V, IncludeKey>>>) => ReturnType<typeof filter<K, V, IncludeKey>>;
|
|
155
|
-
type StorageFind<K, V extends StorageValue> = (predicateOrOptions: Parameters<StorageFilter<K, V>>[0] | Parameters<StorageSearch<K, V>>[0]) => V | undefined;
|
|
156
|
-
type StorageMap<K, V extends StorageValue> = <T>(callback: (value: V, key: K, data: [K, V][], index: number) => T) => T[];
|
|
157
152
|
/**
|
|
158
|
-
*
|
|
153
|
+
* Categorizes errors encountered during DataStorage operations.
|
|
154
|
+
*
|
|
155
|
+
* These types are passed to the `onError` callback to help identify which phase of the
|
|
156
|
+
* data lifecycle (reading, writing, or processing) failed.
|
|
159
157
|
*/
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
declare enum OnErrorType {
|
|
159
|
+
/** Occurs when the user-provided `onChange` callback throws an exception. */
|
|
160
|
+
onChange = "onChange",
|
|
161
|
+
/** Occurs when the user-provided `parse` function fails to process the raw storage string. */
|
|
162
|
+
parse = "parse",
|
|
163
|
+
/**
|
|
164
|
+
* Occurs when the default `JSON.parse` fallback fails.
|
|
165
|
+
* This usually happens if the data in the underlying storage is corrupted or not valid JSON.
|
|
166
|
+
*/
|
|
167
|
+
parse_json = "parse-json",
|
|
168
|
+
/** Occurs when the user-provided `stringify` function fails to serialize the data Map. */
|
|
169
|
+
stringify = "stringify",
|
|
170
|
+
/**
|
|
171
|
+
* Occurs when the default `JSON.stringify` fallback fails.
|
|
172
|
+
* This may happen if the Map contains circular references or other non-serializable values.
|
|
173
|
+
*/
|
|
174
|
+
stringify_json = "stringify-json",
|
|
175
|
+
/** Occurs when the attempt to save data to the underlying storage (e.g., `localStorage.setItem`) fails. */
|
|
176
|
+
write = "write"
|
|
177
|
+
}
|
|
178
|
+
/** Storage type with only properties that are used by `DataStorage` */
|
|
179
|
+
type StorageCompact = Pick<Storage, 'getItem' | 'setItem'>;
|
|
180
|
+
type StorageFilter<K, V, AsArray extends boolean = false> = (...args: DropFirst<Parameters<typeof filter<K, V, AsArray>>>) => ReturnType<typeof filter<K, V>>;
|
|
181
|
+
type StorageFind<K, V, AsArray extends boolean = false> = (predicateOrOptions: Parameters<StorageFilter<K, V, AsArray>>[0] | Parameters<StorageSearch<K, V>>[0]) => V | undefined;
|
|
182
|
+
type StorageMap<K, V, T = unknown> = (callback: (value: V, key: K, data: [K, V][], index: number) => T) => T[];
|
|
183
|
+
type StorageOnChangeFn<K, V, CD extends boolean = false> = (this: IDataStorage<K, V, CD>, data: Map<K, V>) => ValueOrPromise<void | Map<K, V>>;
|
|
184
|
+
type StorageOnErrorFn<K, V, CD extends boolean = false> = (this: IDataStorage<K, V, CD>, err: unknown, type: OnErrorType) => ValueOrPromise<void>;
|
|
162
185
|
/** Initial options provided through the constructor */
|
|
163
|
-
type StorageOptions<Key
|
|
186
|
+
type StorageOptions<Key, Value, CacheDisabled extends boolean = false> = {
|
|
164
187
|
/** value to set, only if storage is empty. Default: `new Map()` */
|
|
165
188
|
initialValue?: Map<Key, Value>;
|
|
166
189
|
} & Pick<Partial<IDataStorage<Key, Value, CacheDisabled>>, 'cacheDisabled' | 'onChange' | 'onError' | 'parse' | 'spaces' | 'storage' | 'stringify'> & (CacheDisabled extends false ? Pick<Partial<IDataStorage<Key, Value, CacheDisabled>>, 'delay' | 'delayOptions'> : {
|
|
167
190
|
delay?: never;
|
|
168
191
|
delayOptions?: never;
|
|
169
192
|
});
|
|
170
|
-
type StorageParseFn<K, V extends
|
|
171
|
-
type StorageSearch<K, V
|
|
172
|
-
type StorageSort<K, V
|
|
173
|
-
type StorageSortByComparator<K, V
|
|
193
|
+
type StorageParseFn<K, V, CD extends boolean = false> = (this: IDataStorage<K, V, CD>, data: string) => Map<K, V>;
|
|
194
|
+
type StorageSearch<K, V, MatchExact extends boolean = false, AsMap extends boolean = true> = (...args: DropFirst<Parameters<typeof search<K, V, MatchExact, AsMap>>>) => ReturnType<typeof search<K, V, MatchExact, AsMap>>;
|
|
195
|
+
type StorageSort<K, V> = (...args: StorageSortByComparator<K, V> | StorageSortByPropertyName<V> | StorageSortByKey) => Map<K, V>;
|
|
196
|
+
type StorageSortByComparator<K, V> = [
|
|
174
197
|
comparator: Parameters<typeof sort<K, V>>[1],
|
|
175
198
|
options?: StorageSortOptions
|
|
176
199
|
];
|
|
177
200
|
type StorageSortByKey = [byKey: true, options?: StorageSortOptions];
|
|
178
|
-
type StorageSortByPropertyName<V
|
|
201
|
+
type StorageSortByPropertyName<V> = [
|
|
179
202
|
propertyName: keyof V & string,
|
|
180
203
|
options?: StorageSortOptions
|
|
181
204
|
];
|
|
182
205
|
type StorageSortOptions = SortOptions & {
|
|
183
206
|
save?: boolean;
|
|
184
207
|
};
|
|
185
|
-
type StorageStringifyFn<K, V extends
|
|
208
|
+
type StorageStringifyFn<K, V, CD extends boolean = false> = (this: IDataStorage<K, V, CD>, data: Map<K, V>) => string;
|
|
186
209
|
type StorageToJSON<K, V> = (replacer?: null | ((key: K, value: V) => unknown), spacing?: string | number, data?: Map<K, V>) => string;
|
|
187
|
-
|
|
188
|
-
type StorageValue = object;
|
|
189
|
-
interface IDataStorage<Key extends StorageKey, Value extends StorageValue, CacheDisabled extends boolean = false> {
|
|
210
|
+
interface IDataStorage<Key, Value, CacheDisabled extends boolean = false> {
|
|
190
211
|
/** Disable in-memory cache and only directly read/write from storage (local storage or JSON fle) */
|
|
191
212
|
readonly cacheDisabled: CacheDisabled;
|
|
192
213
|
/**
|
|
@@ -273,25 +294,43 @@ interface IDataStorage<Key extends StorageKey, Value extends StorageValue, Cache
|
|
|
273
294
|
/** Map each item on the data to an Array */
|
|
274
295
|
readonly map: StorageMap<Key, Value>;
|
|
275
296
|
/**
|
|
276
|
-
*
|
|
297
|
+
* A callback function executed whenever a data change occurs within the storage.
|
|
277
298
|
*
|
|
278
|
-
* If
|
|
299
|
+
* This hook allows for reactive side-effects. If the callback throws an error or returns a
|
|
300
|
+
* rejected Promise, the exception is caught gracefully and redirected to the {@link onError}
|
|
301
|
+
* callback with the type {@link OnErrorType.onChange}.
|
|
302
|
+
*
|
|
303
|
+
* Note: Execution of this callback is managed by internal subscriptions and will stop
|
|
304
|
+
* firing once {@link unsubscribe} is called.
|
|
279
305
|
*/
|
|
280
|
-
onChange?: StorageOnChangeFn<Key, Value>;
|
|
306
|
+
onChange?: StorageOnChangeFn<Key, Value, CacheDisabled>;
|
|
281
307
|
/**
|
|
282
|
-
*
|
|
308
|
+
* A global error handler invoked whenever an internal operation fails.
|
|
309
|
+
*
|
|
310
|
+
* It captures failures in the following areas:
|
|
311
|
+
* - Data parsing and serialization (JSON or custom logic).
|
|
312
|
+
* - Storage access (e.g., `localStorage` quota or permission errors).
|
|
313
|
+
* - Execution of user-provided callbacks like {@link onChange}.
|
|
283
314
|
*
|
|
284
|
-
* If
|
|
315
|
+
* **Note:** If this handler itself throws an error, the exception is
|
|
316
|
+
* ignored gracefully to prevent application crashes during storage cycles.
|
|
285
317
|
*/
|
|
286
|
-
onError?: StorageOnErrorFn
|
|
318
|
+
onError?: StorageOnErrorFn<Key, Value, CacheDisabled>;
|
|
287
319
|
/**
|
|
288
320
|
* A callback to customize the deserialization of data read from storage.
|
|
289
321
|
*
|
|
290
|
-
* This
|
|
291
|
-
*
|
|
292
|
-
*
|
|
322
|
+
* This allows you to transform the raw string from the underlying storage back into a
|
|
323
|
+
* `Map<Key, Value>`. It serves as the functional inverse of {@link stringify}.
|
|
324
|
+
*
|
|
325
|
+
* **Fallback Behavior:**
|
|
326
|
+
* If this function is not defined, throws an error, or returns a non-Map value,
|
|
327
|
+
* the system falls back to internal `JSON.parse` logic.
|
|
328
|
+
*
|
|
329
|
+
* **Error Triggers:**
|
|
330
|
+
* - If this custom `parse` function fails: {@link onError} is triggered with {@link OnErrorType.parse}.
|
|
331
|
+
* - If the default `JSON.parse` fallback fails: {@link onError} is triggered with {@link OnErrorType.parse_json}.
|
|
293
332
|
*/
|
|
294
|
-
readonly parse?: StorageParseFn<Key, Value>;
|
|
333
|
+
readonly parse?: StorageParseFn<Key, Value, CacheDisabled>;
|
|
295
334
|
/** Read directly from the localStorage (browser) or file (NodeJS) without triggering the `this.subject`. */
|
|
296
335
|
readonly read: () => Map<Key, Value>;
|
|
297
336
|
/** Search items */
|
|
@@ -323,41 +362,44 @@ interface IDataStorage<Key extends StorageKey, Value extends StorageValue, Cache
|
|
|
323
362
|
*/
|
|
324
363
|
readonly sort: StorageSort<Key, Value>;
|
|
325
364
|
/**
|
|
326
|
-
*
|
|
365
|
+
* A callback function to customize the serialization of data before it is written to storage.
|
|
366
|
+
*
|
|
367
|
+
* This allows you to transform the data `Map<Key, Value>` into a string format suitable
|
|
368
|
+
* for the underlying storage (e.g., JSON). It serves as the functional inverse of {@link parse}.
|
|
369
|
+
*
|
|
370
|
+
* Use this to sanitize data, remove circular references, or optimize the storage size by
|
|
371
|
+
* only persisting necessary fields.
|
|
372
|
+
*
|
|
373
|
+
* **Fallback Behavior:**
|
|
374
|
+
* If this function is not defined, throws an error, or returns a non-string value,
|
|
375
|
+
* the system falls back to internal `JSON.stringify` logic.
|
|
327
376
|
*
|
|
328
|
-
*
|
|
377
|
+
* **Error Triggers:**
|
|
378
|
+
* - If this custom `stringify` function fails: {@link onError} is triggered with {@link OnErrorType.stringify}.
|
|
379
|
+
* - If the default `JSON.stringify` fallback fails: {@link onError} is triggered with {@link OnErrorType.stringify_json}.
|
|
329
380
|
*
|
|
330
381
|
* @example
|
|
382
|
+
* #### Sanitize data before saving
|
|
331
383
|
* ```javascript
|
|
332
|
-
* import fetch from '@superutils/fetch'
|
|
333
384
|
* import { DataStorage } from '@superutils/rx'
|
|
334
|
-
* import { LocalStorage } from 'node-localstorage'
|
|
335
385
|
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
* { id: product.id, title: product.title } // only store what's needed
|
|
346
|
-
* ])
|
|
347
|
-
*
|
|
348
|
-
* const { products } = await fetch('[DUMMYJSON-DOT-COM]/products)
|
|
349
|
-
* const productsMap = result.products.map(p => [p.id, p])
|
|
350
|
-
* storage.setAll(productsMap, true)
|
|
351
|
-
* console.log(storage.getAll())
|
|
352
|
-
* ```
|
|
386
|
+
* const stringify = data => {
|
|
387
|
+
* // Convert Map to an array of entries, removing sensitive fields
|
|
388
|
+
* const entries = Array.from(data).map(([id, user]) => {
|
|
389
|
+
* const { password, ...publicData } = user
|
|
390
|
+
* return [id, publicData]
|
|
391
|
+
* })
|
|
392
|
+
* return JSON.stringify(entries)
|
|
393
|
+
* }
|
|
394
|
+
* const storage = new DataStorage('users', { stringify })
|
|
353
395
|
*/
|
|
354
|
-
readonly stringify?: StorageStringifyFn<Key, Value>;
|
|
396
|
+
readonly stringify?: StorageStringifyFn<Key, Value, CacheDisabled>;
|
|
355
397
|
/** Convert list of items (Map) to 2D Array */
|
|
356
398
|
readonly toArray: () => [Key, Value][];
|
|
357
399
|
/** Convert list of items (Map) to JSON string of 2D Array */
|
|
358
400
|
readonly toJSON: StorageToJSON<Key, Value>;
|
|
359
401
|
/** Convert list of items into an object */
|
|
360
|
-
readonly toObject: () => Record<Key, Value>;
|
|
402
|
+
readonly toObject: (data?: Map<Key, Value>) => Record<Key & string, Value>;
|
|
361
403
|
/** Convert list of items (Map) to JSON string of 2D Array */
|
|
362
404
|
readonly toString: () => string;
|
|
363
405
|
/**
|
|
@@ -403,7 +445,7 @@ interface IDataStorage<Key extends StorageKey, Value extends StorageValue, Cache
|
|
|
403
445
|
* ```
|
|
404
446
|
*/
|
|
405
447
|
declare const forceUpdateCache$: Subject<string | boolean | string[]>;
|
|
406
|
-
declare class DataStorage<Key
|
|
448
|
+
declare class DataStorage<Key, Value, CacheDisabled extends boolean = false> implements IDataStorage<Key, Value, CacheDisabled> {
|
|
407
449
|
readonly cacheDisabled: CacheDisabled;
|
|
408
450
|
readonly delay: number;
|
|
409
451
|
/** Debounce and throttle related options */
|
|
@@ -504,10 +546,59 @@ declare class DataStorage<Key extends StorageKey, Value extends StorageValue, Ca
|
|
|
504
546
|
* ```
|
|
505
547
|
*/
|
|
506
548
|
constructor(name?: string | null, options?: StorageOptions<Key, Value, CacheDisabled>);
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
549
|
+
clear(): this;
|
|
550
|
+
delete(keys: Key | Key[]): this;
|
|
551
|
+
find(predicateOrOptions: Parameters<StorageFind<Key, Value>>[0]): Value | undefined;
|
|
552
|
+
filter<AsArray extends boolean = false>(...args: Parameters<StorageFilter<Key, Value, AsArray>>): AsArray extends true ? Value[] : Map<Key, Value>;
|
|
553
|
+
/**
|
|
554
|
+
* Creates a {@link DataStorage} instance initialized from a plain object.
|
|
555
|
+
*
|
|
556
|
+
* This factory method automatically configures `parse` and `stringify` logic to
|
|
557
|
+
* treat the underlying storage as a serialized object, while providing a
|
|
558
|
+
* type-safe Map-like interface for individual properties.
|
|
559
|
+
*
|
|
560
|
+
* @param name (optional) The name for the storage (e.g., localStorage key or filename).
|
|
561
|
+
* @param options (optional) Configuration options for the storage instance.
|
|
562
|
+
* @param options.initialValue (optional) An optional object to populate the storage if it's currently empty.
|
|
563
|
+
*
|
|
564
|
+
* @template T (optional) The structure of the object being stored. Can auto-infer from `options.initialValue`.
|
|
565
|
+
* @template CacheDisabled (optional) Literal type determining whether to disable in-memory caching.
|
|
566
|
+
*
|
|
567
|
+
* @returns A new DataStorage instance mapped to the object's keys and values.
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* #### Store and access a User object
|
|
571
|
+
* ```typescript
|
|
572
|
+
* import { DataStorage } from '@superutils/rx'
|
|
573
|
+
*
|
|
574
|
+
* interface User {
|
|
575
|
+
* age: number;
|
|
576
|
+
* name: string;
|
|
577
|
+
* }
|
|
578
|
+
*
|
|
579
|
+
* const initialValue: User = {
|
|
580
|
+
* age: 99,
|
|
581
|
+
* name: 'Ninety Nine'
|
|
582
|
+
* }
|
|
583
|
+
*
|
|
584
|
+
* // Initialize storage from the object
|
|
585
|
+
* const storage = DataStorage.fromObject<User>('user-profile', { initialValue })
|
|
586
|
+
*
|
|
587
|
+
* // Keys are inferred from the User interface
|
|
588
|
+
* const name = storage.get('name') // Inferred as: string | undefined
|
|
589
|
+
* console.log(name) // Prints: 'Ninety Nine'
|
|
590
|
+
*
|
|
591
|
+
* // Update properties safely
|
|
592
|
+
* storage.set('age', 100)
|
|
593
|
+
*
|
|
594
|
+
* // Reconstruct the updated object
|
|
595
|
+
* const userObj = storage.toObject<User>()
|
|
596
|
+
* console.log(userObj) // { age: 100, name: 'Ninety Nine' }
|
|
597
|
+
* ```
|
|
598
|
+
*/
|
|
599
|
+
static fromObject: <T extends object, CacheDisabled_1 extends boolean = false>(name?: string, options?: Omit<StorageOptions<keyof T, T[keyof T], CacheDisabled_1>, "initialValue"> & {
|
|
600
|
+
initialValue?: T;
|
|
601
|
+
}) => DataStorage<keyof T, T[keyof T], CacheDisabled_1>;
|
|
511
602
|
/**
|
|
512
603
|
* Trigger forced update of cached data from storage.
|
|
513
604
|
*
|
|
@@ -528,29 +619,31 @@ declare class DataStorage<Key extends StorageKey, Value extends StorageValue, Ca
|
|
|
528
619
|
* ```
|
|
529
620
|
*/
|
|
530
621
|
static forceUpdateCache: (name: string | string[] | true) => void;
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
readonly
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
readonly
|
|
548
|
-
|
|
549
|
-
|
|
622
|
+
get(key: Key): Value | undefined;
|
|
623
|
+
getAll(forceRead?: boolean): Map<Key, Value>;
|
|
624
|
+
private handleForceUpdateCacheChange;
|
|
625
|
+
private handleSubjectChange;
|
|
626
|
+
has(key: Key): boolean;
|
|
627
|
+
init(initialValue?: Map<Key, Value>): boolean;
|
|
628
|
+
keys(): Key[];
|
|
629
|
+
map<T>(callback: Parameters<StorageMap<Key, Value, T>>[0]): T[];
|
|
630
|
+
onChange?: StorageOnChangeFn<Key, Value, CacheDisabled>;
|
|
631
|
+
onError?: StorageOnErrorFn<Key, Value, CacheDisabled>;
|
|
632
|
+
readonly parse?: StorageParseFn<Key, Value, CacheDisabled>;
|
|
633
|
+
read(): Map<Key, Value>;
|
|
634
|
+
search<MatchExact extends boolean = false, AsMap extends boolean = true>(options: Parameters<StorageSearch<Key, Value, MatchExact, AsMap>>[0]): AsMap extends true ? Map<Key, Value> : Value[];
|
|
635
|
+
set(key: Key, value: Value): this;
|
|
636
|
+
setAll(data?: Map<Key, Value>, replace?: boolean): this;
|
|
637
|
+
sort(...args: Parameters<StorageSort<Key, Value>>): Map<Key, Value>;
|
|
638
|
+
readonly stringify?: StorageStringifyFn<Key, Value, CacheDisabled>;
|
|
639
|
+
toArray(): [Key, Value][];
|
|
640
|
+
toJSON(...[replacer, spacing, data]: Parameters<StorageToJSON<Key, Value>>): string;
|
|
641
|
+
toObject<T extends object = object>(data?: Map<Key, Value>): T;
|
|
642
|
+
toString(data?: Map<Key, Value>): string;
|
|
550
643
|
private triggerOnError;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
644
|
+
unsubscribe(): void;
|
|
645
|
+
values(): Value[];
|
|
646
|
+
write(data?: Map<Key, Value>): boolean;
|
|
554
647
|
}
|
|
555
648
|
|
|
556
649
|
/**
|
|
@@ -740,4 +833,4 @@ declare const isSubscriptionLike: (value: unknown, strict?: boolean) => value is
|
|
|
740
833
|
*/
|
|
741
834
|
declare const unsubscribeAll: (unsub?: UnsubscribeCandidates, onError?: (err: unknown) => void) => void;
|
|
742
835
|
|
|
743
|
-
export { type CopyRxSubjectOptions, DataStorage, type DelayOptions, type IDataStorage, IGNORE_UPDATE_SYMBOL, IntervalRunner, IntervalSubject,
|
|
836
|
+
export { type CopyRxSubjectOptions, DataStorage, type DelayOptions, type IDataStorage, IGNORE_UPDATE_SYMBOL, IntervalRunner, IntervalSubject, OnErrorType, type OnResultType, type StorageCompact, type StorageFilter, type StorageFind, type StorageMap, type StorageOnChangeFn, type StorageOnErrorFn, type StorageOptions, type StorageParseFn, type StorageSearch, type StorageSort, type StorageSortByComparator, type StorageSortByKey, type StorageSortByPropertyName, type StorageSortOptions, type StorageStringifyFn, type StorageToJSON, type SubjectLike, type SubscriptionLike, type Unsubscribe, type UnsubscribeCandidates, type UnwrapSubjectValue, type ValueModifier, asPromise, copyRxSubject, forceUpdateCache$, isSubjectLike, isSubscriptionLike, type onBeforeExecType, unsubscribeAll };
|