react-mnemonic 1.0.0-beta.0 → 1.1.0-beta0
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 +236 -19
- package/dist/index.cjs +1355 -643
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +387 -37
- package/dist/index.d.ts +387 -37
- package/dist/index.js +1352 -645
- package/dist/index.js.map +1 -1
- package/package.json +9 -1
package/dist/index.d.ts
CHANGED
|
@@ -304,6 +304,51 @@ declare function compileSchema(schema: JsonSchema): CompiledValidator;
|
|
|
304
304
|
*/
|
|
305
305
|
declare function validateJsonSchema(value: unknown, schema: JsonSchema, path?: string): JsonSchemaValidationError[];
|
|
306
306
|
|
|
307
|
+
declare const typedSchemaBrand: unique symbol;
|
|
308
|
+
declare const optionalSchemaBrand: unique symbol;
|
|
309
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
310
|
+
type JsonConstValue = JsonPrimitive | readonly JsonConstValue[] | {
|
|
311
|
+
readonly [key: string]: JsonConstValue;
|
|
312
|
+
};
|
|
313
|
+
type TypedJsonSchema<T> = JsonSchema & {
|
|
314
|
+
readonly [typedSchemaBrand]?: T;
|
|
315
|
+
};
|
|
316
|
+
type OptionalTypedJsonSchema<T> = TypedJsonSchema<T> & {
|
|
317
|
+
readonly [optionalSchemaBrand]: true;
|
|
318
|
+
};
|
|
319
|
+
type InferJsonSchemaValue<TSchema> = TSchema extends TypedJsonSchema<infer TValue> ? TValue : unknown;
|
|
320
|
+
type ObjectValueFromSchemas<TShape extends Record<string, TypedJsonSchema<unknown> | OptionalTypedJsonSchema<unknown>>> = {
|
|
321
|
+
[K in keyof TShape as TShape[K] extends OptionalTypedJsonSchema<unknown> ? never : K]: InferJsonSchemaValue<TShape[K]>;
|
|
322
|
+
} & {
|
|
323
|
+
[K in keyof TShape as TShape[K] extends OptionalTypedJsonSchema<unknown> ? K : never]?: InferJsonSchemaValue<TShape[K]>;
|
|
324
|
+
};
|
|
325
|
+
type StringSchemaOptions = Pick<JsonSchema, "minLength" | "maxLength">;
|
|
326
|
+
type NumberSchemaOptions = Pick<JsonSchema, "minimum" | "maximum" | "exclusiveMinimum" | "exclusiveMaximum">;
|
|
327
|
+
type ArraySchemaOptions = Pick<JsonSchema, "minItems" | "maxItems">;
|
|
328
|
+
type ObjectSchemaOptions = Pick<JsonSchema, "additionalProperties">;
|
|
329
|
+
/**
|
|
330
|
+
* Builder helpers for strongly typed schemas backed by Mnemonic's built-in
|
|
331
|
+
* JSON Schema subset.
|
|
332
|
+
*
|
|
333
|
+
* The returned schemas are plain `JsonSchema` objects at runtime, so they can
|
|
334
|
+
* be registered directly in `createSchemaRegistry(...)` while also carrying a
|
|
335
|
+
* phantom TypeScript type for inference.
|
|
336
|
+
*/
|
|
337
|
+
declare const mnemonicSchema: {
|
|
338
|
+
string(options?: StringSchemaOptions): TypedJsonSchema<string>;
|
|
339
|
+
number(options?: NumberSchemaOptions): TypedJsonSchema<number>;
|
|
340
|
+
integer(options?: NumberSchemaOptions): TypedJsonSchema<number>;
|
|
341
|
+
boolean(): TypedJsonSchema<boolean>;
|
|
342
|
+
nullValue(): TypedJsonSchema<null>;
|
|
343
|
+
literal<const TValue extends JsonConstValue>(value: TValue): TypedJsonSchema<TValue>;
|
|
344
|
+
enum<const TValues extends readonly [JsonPrimitive, ...JsonPrimitive[]]>(values: TValues): TypedJsonSchema<TValues[number]>;
|
|
345
|
+
optional<T>(schema: TypedJsonSchema<T>): OptionalTypedJsonSchema<T>;
|
|
346
|
+
nullable<T>(schema: TypedJsonSchema<T>): TypedJsonSchema<T | null>;
|
|
347
|
+
array<TItemSchema extends TypedJsonSchema<unknown>>(itemSchema: TItemSchema, options?: ArraySchemaOptions): TypedJsonSchema<InferJsonSchemaValue<TItemSchema>[]>;
|
|
348
|
+
object<TShape extends Record<string, TypedJsonSchema<unknown> | OptionalTypedJsonSchema<unknown>>>(shape: TShape, options?: ObjectSchemaOptions): TypedJsonSchema<ObjectValueFromSchemas<TShape>>;
|
|
349
|
+
record<TValueSchema extends TypedJsonSchema<unknown>>(valueSchema: TValueSchema): TypedJsonSchema<Record<string, InferJsonSchemaValue<TValueSchema>>>;
|
|
350
|
+
};
|
|
351
|
+
|
|
307
352
|
/**
|
|
308
353
|
* @fileoverview Type definitions for the Mnemonic library.
|
|
309
354
|
*
|
|
@@ -311,6 +356,7 @@ declare function validateJsonSchema(value: unknown, schema: JsonSchema, path?: s
|
|
|
311
356
|
* library for type-safe, persistent state management in React applications.
|
|
312
357
|
*/
|
|
313
358
|
|
|
359
|
+
declare const keySchemaValueBrand: unique symbol;
|
|
314
360
|
/**
|
|
315
361
|
* Codec for encoding and decoding values to and from storage.
|
|
316
362
|
*
|
|
@@ -388,7 +434,8 @@ interface MnemonicProviderOptions {
|
|
|
388
434
|
* Storage backend to use for persistence.
|
|
389
435
|
*
|
|
390
436
|
* Defaults to `window.localStorage` in browser environments. You can provide
|
|
391
|
-
* a custom implementation (e.g., sessionStorage,
|
|
437
|
+
* a synchronous custom implementation (e.g., sessionStorage, an in-memory
|
|
438
|
+
* cache facade over IndexedDB, or a mock for testing).
|
|
392
439
|
*
|
|
393
440
|
* @default window.localStorage
|
|
394
441
|
*
|
|
@@ -425,7 +472,7 @@ interface MnemonicProviderOptions {
|
|
|
425
472
|
* enableDevTools: process.env.NODE_ENV === 'development'
|
|
426
473
|
*
|
|
427
474
|
* // Then in browser console:
|
|
428
|
-
* const provider = window.__REACT_MNEMONIC_DEVTOOLS__
|
|
475
|
+
* const provider = window.__REACT_MNEMONIC_DEVTOOLS__?.resolve('myApp')
|
|
429
476
|
* provider?.dump()
|
|
430
477
|
* provider?.get('user')
|
|
431
478
|
* provider?.set('user', { name: 'Test' })
|
|
@@ -466,6 +513,24 @@ interface MnemonicProviderOptions {
|
|
|
466
513
|
* @see {@link KeySchema} - Schema definition stored in the registry
|
|
467
514
|
*/
|
|
468
515
|
schemaRegistry?: SchemaRegistry;
|
|
516
|
+
/**
|
|
517
|
+
* Server-rendering and hydration defaults for descendant hooks.
|
|
518
|
+
*
|
|
519
|
+
* Provider-level SSR settings establish the default hydration strategy for
|
|
520
|
+
* all `useMnemonicKey(...)` calls in this namespace. Individual hooks may
|
|
521
|
+
* still override the strategy when a specific key needs different behavior.
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```tsx
|
|
525
|
+
* <MnemonicProvider
|
|
526
|
+
* namespace="app"
|
|
527
|
+
* ssr={{ hydration: "client-only" }}
|
|
528
|
+
* >
|
|
529
|
+
* <App />
|
|
530
|
+
* </MnemonicProvider>
|
|
531
|
+
* ```
|
|
532
|
+
*/
|
|
533
|
+
ssr?: MnemonicProviderSSRConfig;
|
|
469
534
|
}
|
|
470
535
|
/**
|
|
471
536
|
* Controls how the provider enforces versioned schemas on stored values.
|
|
@@ -499,6 +564,57 @@ interface MnemonicProviderOptions {
|
|
|
499
564
|
* @see {@link KeySchema} - Individual schema definition
|
|
500
565
|
*/
|
|
501
566
|
type SchemaMode = "strict" | "default" | "autoschema";
|
|
567
|
+
/**
|
|
568
|
+
* Controls when a hook should read persisted storage during client rendering.
|
|
569
|
+
*
|
|
570
|
+
* - `"immediate"` — Default. The server snapshot is used during SSR/hydration,
|
|
571
|
+
* and the hook reads persisted storage as soon as React switches to the
|
|
572
|
+
* client snapshot.
|
|
573
|
+
*
|
|
574
|
+
* - `"client-only"` — Defers all storage reads until after the component has
|
|
575
|
+
* mounted on the client. This is useful when you want a deterministic server
|
|
576
|
+
* placeholder and prefer the persisted value to appear only after hydration
|
|
577
|
+
* completes.
|
|
578
|
+
*/
|
|
579
|
+
type MnemonicHydrationMode = "immediate" | "client-only";
|
|
580
|
+
/**
|
|
581
|
+
* Provider-level SSR defaults shared by descendant hooks.
|
|
582
|
+
*/
|
|
583
|
+
interface MnemonicProviderSSRConfig {
|
|
584
|
+
/**
|
|
585
|
+
* Default hydration strategy for descendant `useMnemonicKey(...)` hooks.
|
|
586
|
+
*
|
|
587
|
+
* @default "immediate"
|
|
588
|
+
*/
|
|
589
|
+
hydration?: MnemonicHydrationMode;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Hook-level SSR controls for `useMnemonicKey(...)`.
|
|
593
|
+
*
|
|
594
|
+
* Lets a key render a deterministic server snapshot and optionally delay
|
|
595
|
+
* reading persisted storage until after client mount.
|
|
596
|
+
*
|
|
597
|
+
* @template T - The decoded value type for the key
|
|
598
|
+
*/
|
|
599
|
+
interface MnemonicKeySSRConfig<T> {
|
|
600
|
+
/**
|
|
601
|
+
* Value to expose during SSR and hydration instead of `defaultValue`.
|
|
602
|
+
*
|
|
603
|
+
* This value is not persisted automatically. Once hydration completes,
|
|
604
|
+
* the hook transitions to the stored value (if any) or back to
|
|
605
|
+
* `defaultValue`.
|
|
606
|
+
*
|
|
607
|
+
* Factory functions should be deterministic across server render and
|
|
608
|
+
* client hydration to avoid markup mismatches.
|
|
609
|
+
*/
|
|
610
|
+
serverValue?: T | (() => T);
|
|
611
|
+
/**
|
|
612
|
+
* Hydration strategy for this key.
|
|
613
|
+
*
|
|
614
|
+
* When omitted, inherits the provider default.
|
|
615
|
+
*/
|
|
616
|
+
hydration?: MnemonicHydrationMode;
|
|
617
|
+
}
|
|
502
618
|
/**
|
|
503
619
|
* Weak-reference shape used by the devtools registry.
|
|
504
620
|
*
|
|
@@ -635,11 +751,11 @@ interface MnemonicDevToolsRegistry {
|
|
|
635
751
|
* @see {@link MigrationRule} - How values migrate between schema versions
|
|
636
752
|
* @see {@link JsonSchema} - The JSON Schema subset used for validation
|
|
637
753
|
*/
|
|
638
|
-
type KeySchema = {
|
|
754
|
+
type KeySchema<TValue = unknown, K extends string = string, TSchema extends JsonSchema = JsonSchema> = {
|
|
639
755
|
/**
|
|
640
756
|
* The unprefixed storage key this schema applies to.
|
|
641
757
|
*/
|
|
642
|
-
key:
|
|
758
|
+
key: K;
|
|
643
759
|
/**
|
|
644
760
|
* The version number for this schema.
|
|
645
761
|
*
|
|
@@ -652,7 +768,15 @@ type KeySchema = {
|
|
|
652
768
|
* Only the subset of JSON Schema keywords defined in {@link JsonSchema}
|
|
653
769
|
* are supported. An empty schema `{}` accepts any value.
|
|
654
770
|
*/
|
|
655
|
-
schema:
|
|
771
|
+
schema: TSchema;
|
|
772
|
+
/**
|
|
773
|
+
* Phantom type linking this runtime schema to its decoded TypeScript value.
|
|
774
|
+
*
|
|
775
|
+
* This field is never set at runtime. It exists only so helpers such as
|
|
776
|
+
* `defineKeySchema(...)`, `defineMnemonicKey(...)`, and `defineMigration(...)`
|
|
777
|
+
* can preserve a single source of truth between schema shape and value type.
|
|
778
|
+
*/
|
|
779
|
+
readonly [keySchemaValueBrand]?: TValue;
|
|
656
780
|
};
|
|
657
781
|
/**
|
|
658
782
|
* A single migration step that transforms data from one schema version to
|
|
@@ -695,11 +819,11 @@ type KeySchema = {
|
|
|
695
819
|
* @see {@link SchemaRegistry.getMigrationPath} - How the path is resolved
|
|
696
820
|
* @see {@link SchemaRegistry.getWriteMigration} - How write-time normalizers are resolved
|
|
697
821
|
*/
|
|
698
|
-
type MigrationRule = {
|
|
822
|
+
type MigrationRule<TFrom = unknown, TTo = unknown, K extends string = string> = {
|
|
699
823
|
/**
|
|
700
824
|
* The unprefixed storage key this rule applies to.
|
|
701
825
|
*/
|
|
702
|
-
key:
|
|
826
|
+
key: K;
|
|
703
827
|
/**
|
|
704
828
|
* The version the stored data is migrating **from**.
|
|
705
829
|
*
|
|
@@ -723,7 +847,7 @@ type MigrationRule = {
|
|
|
723
847
|
* @param value - The decoded value at `fromVersion`
|
|
724
848
|
* @returns The transformed value for `toVersion`
|
|
725
849
|
*/
|
|
726
|
-
migrate
|
|
850
|
+
migrate(value: TFrom): TTo;
|
|
727
851
|
};
|
|
728
852
|
/**
|
|
729
853
|
* An ordered sequence of {@link MigrationRule} steps that upgrades stored
|
|
@@ -737,13 +861,17 @@ type MigrationRule = {
|
|
|
737
861
|
* @see {@link MigrationRule} - Individual migration step
|
|
738
862
|
* @see {@link SchemaRegistry.getMigrationPath} - Resolves a path between versions
|
|
739
863
|
*/
|
|
740
|
-
type MigrationPath = MigrationRule[];
|
|
864
|
+
type MigrationPath<K extends string = string> = MigrationRule<unknown, unknown, K>[];
|
|
741
865
|
/**
|
|
742
866
|
* Input options for {@link createSchemaRegistry}.
|
|
743
867
|
*
|
|
744
868
|
* Use this helper when your registry contents are known up front and do not
|
|
745
869
|
* need runtime mutation. The returned registry is immutable and optimized for
|
|
746
870
|
* the common `"default"` / `"strict"` setup.
|
|
871
|
+
*
|
|
872
|
+
* For most apps, this should be your default entry point for schema-managed
|
|
873
|
+
* persistence. Implement {@link SchemaRegistry} manually only when you need
|
|
874
|
+
* custom lookup behavior or runtime schema registration beyond autoschema mode.
|
|
747
875
|
*/
|
|
748
876
|
interface CreateSchemaRegistryOptions {
|
|
749
877
|
/**
|
|
@@ -776,15 +904,19 @@ interface CreateSchemaRegistryOptions {
|
|
|
776
904
|
* read/write hot paths fast. `"autoschema"` remains mutable to support
|
|
777
905
|
* inferred schema registration.
|
|
778
906
|
*
|
|
907
|
+
* Most applications should prefer {@link createSchemaRegistry} instead of
|
|
908
|
+
* implementing this interface manually. Manual implementations are mainly for
|
|
909
|
+
* advanced cases such as custom backing stores, dynamic schema discovery, or
|
|
910
|
+
* adapter layers around an existing registry system.
|
|
911
|
+
*
|
|
779
912
|
* @example
|
|
780
913
|
* ```typescript
|
|
781
|
-
* const registry
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
* };
|
|
914
|
+
* const registry = createSchemaRegistry({
|
|
915
|
+
* schemas: [
|
|
916
|
+
* { key: "settings", version: 1, schema: { type: "object", required: ["theme"] } },
|
|
917
|
+
* ],
|
|
918
|
+
* migrations: [],
|
|
919
|
+
* });
|
|
788
920
|
*
|
|
789
921
|
* <MnemonicProvider namespace="app" schemaRegistry={registry} schemaMode="strict">
|
|
790
922
|
* <App />
|
|
@@ -856,12 +988,17 @@ interface SchemaRegistry {
|
|
|
856
988
|
registerSchema?(schema: KeySchema): void;
|
|
857
989
|
}
|
|
858
990
|
/**
|
|
859
|
-
* Storage interface compatible with localStorage and custom storage implementations.
|
|
991
|
+
* Storage interface compatible with localStorage and synchronous custom storage implementations.
|
|
860
992
|
*
|
|
861
993
|
* Defines the minimum contract required for a storage backend. Compatible with
|
|
862
994
|
* browser Storage API (localStorage, sessionStorage) and custom implementations
|
|
863
995
|
* for testing or alternative storage solutions.
|
|
864
996
|
*
|
|
997
|
+
* All methods in this contract are intentionally synchronous. Promise-returning
|
|
998
|
+
* adapters such as React Native `AsyncStorage` are not directly supported by
|
|
999
|
+
* `StorageLike`; instead, keep a synchronous in-memory cache and flush to async
|
|
1000
|
+
* persistence outside the hook contract.
|
|
1001
|
+
*
|
|
865
1002
|
* @remarks
|
|
866
1003
|
* **Error handling contract**
|
|
867
1004
|
*
|
|
@@ -885,6 +1022,10 @@ interface SchemaRegistry {
|
|
|
885
1022
|
* In all error cases the library falls back to its in-memory cache, so
|
|
886
1023
|
* components continue to function when the storage backend is unavailable.
|
|
887
1024
|
*
|
|
1025
|
+
* Promise-returning `getItem`, `setItem`, or `removeItem` implementations are
|
|
1026
|
+
* treated as an invalid contract at runtime. Mnemonic logs the misuse once and
|
|
1027
|
+
* falls back to its in-memory cache for safety.
|
|
1028
|
+
*
|
|
888
1029
|
* @example
|
|
889
1030
|
* ```typescript
|
|
890
1031
|
* // In-memory storage for testing
|
|
@@ -906,6 +1047,8 @@ type StorageLike = {
|
|
|
906
1047
|
*
|
|
907
1048
|
* @param key - The storage key to retrieve
|
|
908
1049
|
* @returns The stored value as a string, or null if not found
|
|
1050
|
+
*
|
|
1051
|
+
* @remarks Must return synchronously. Returning a Promise is unsupported.
|
|
909
1052
|
*/
|
|
910
1053
|
getItem(key: string): string | null;
|
|
911
1054
|
/**
|
|
@@ -913,12 +1056,16 @@ type StorageLike = {
|
|
|
913
1056
|
*
|
|
914
1057
|
* @param key - The storage key
|
|
915
1058
|
* @param value - The string value to store
|
|
1059
|
+
*
|
|
1060
|
+
* @remarks Must complete synchronously. Returning a Promise is unsupported.
|
|
916
1061
|
*/
|
|
917
1062
|
setItem(key: string, value: string): void;
|
|
918
1063
|
/**
|
|
919
1064
|
* Removes a key-value pair from storage.
|
|
920
1065
|
*
|
|
921
1066
|
* @param key - The storage key to remove
|
|
1067
|
+
*
|
|
1068
|
+
* @remarks Must complete synchronously. Returning a Promise is unsupported.
|
|
922
1069
|
*/
|
|
923
1070
|
removeItem(key: string): void;
|
|
924
1071
|
/**
|
|
@@ -1085,6 +1232,19 @@ type Mnemonic = {
|
|
|
1085
1232
|
* @see {@link SchemaMode}
|
|
1086
1233
|
*/
|
|
1087
1234
|
schemaMode: SchemaMode;
|
|
1235
|
+
/**
|
|
1236
|
+
* Default hydration strategy inherited by descendant hooks.
|
|
1237
|
+
*/
|
|
1238
|
+
ssrHydration: MnemonicHydrationMode;
|
|
1239
|
+
/**
|
|
1240
|
+
* How this provider can observe external changes from other tabs/processes.
|
|
1241
|
+
*
|
|
1242
|
+
* Hooks use this for development diagnostics when callers opt into
|
|
1243
|
+
* cross-tab synchronization on a backend that cannot actually deliver it.
|
|
1244
|
+
*
|
|
1245
|
+
* When omitted, consumers should treat this as equivalent to `"none"`.
|
|
1246
|
+
*/
|
|
1247
|
+
crossTabSyncMode?: "browser-storage-event" | "custom-external-change" | "none";
|
|
1088
1248
|
/**
|
|
1089
1249
|
* The schema registry for this provider, if one was supplied.
|
|
1090
1250
|
*
|
|
@@ -1172,6 +1332,96 @@ interface MnemonicRecoveryHook {
|
|
|
1172
1332
|
*/
|
|
1173
1333
|
clearMatching: (predicate: (key: string) => boolean) => string[];
|
|
1174
1334
|
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Return shape from {@link useMnemonicKey}.
|
|
1337
|
+
*
|
|
1338
|
+
* This mirrors the familiar `useState` mental model while making the storage
|
|
1339
|
+
* semantics explicit:
|
|
1340
|
+
*
|
|
1341
|
+
* - `set(...)` writes a new persisted value
|
|
1342
|
+
* - `reset()` writes `defaultValue` back into storage
|
|
1343
|
+
* - `remove()` deletes the key entirely so reads fall back to `defaultValue`
|
|
1344
|
+
*
|
|
1345
|
+
* See the
|
|
1346
|
+
* [Clearable Persisted Values guide](https://thirtytwobits.github.io/react-mnemonic/docs/guides/clearable-persisted-values)
|
|
1347
|
+
* for the semantic differences between clearing, resetting, and removing a key.
|
|
1348
|
+
*
|
|
1349
|
+
* @template T - The decoded value type for the key
|
|
1350
|
+
*
|
|
1351
|
+
* @see {@link UseMnemonicKeyOptions} - Hook configuration and lifecycle details
|
|
1352
|
+
*/
|
|
1353
|
+
interface MnemonicKeyState<T> {
|
|
1354
|
+
/**
|
|
1355
|
+
* Current decoded value, or the default when the key is absent or invalid.
|
|
1356
|
+
*/
|
|
1357
|
+
value: T;
|
|
1358
|
+
/**
|
|
1359
|
+
* Persist a new value.
|
|
1360
|
+
*
|
|
1361
|
+
* Accepts either a direct replacement value or an updater function that
|
|
1362
|
+
* receives the current decoded value.
|
|
1363
|
+
*/
|
|
1364
|
+
set: (next: T | ((current: T) => T)) => void;
|
|
1365
|
+
/**
|
|
1366
|
+
* Reset the key back to `defaultValue` and persist that default.
|
|
1367
|
+
*/
|
|
1368
|
+
reset: () => void;
|
|
1369
|
+
/**
|
|
1370
|
+
* Delete the key from storage entirely.
|
|
1371
|
+
*
|
|
1372
|
+
* Future reads will fall back to `defaultValue` until the key is written
|
|
1373
|
+
* again.
|
|
1374
|
+
*/
|
|
1375
|
+
remove: () => void;
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Reusable, importable contract for a single persisted key.
|
|
1379
|
+
*
|
|
1380
|
+
* Descriptors package the key name and its `useMnemonicKey(...)` options into
|
|
1381
|
+
* a stable object that can be defined once at module scope and reused across
|
|
1382
|
+
* components. This helps keep persistence behavior explicit and consistent,
|
|
1383
|
+
* especially when the same key appears in multiple parts of an application.
|
|
1384
|
+
*
|
|
1385
|
+
* @template T - The decoded value type for the key
|
|
1386
|
+
* @template K - The literal key name
|
|
1387
|
+
*
|
|
1388
|
+
* @example
|
|
1389
|
+
* ```typescript
|
|
1390
|
+
* const themeKey = defineMnemonicKey("theme", {
|
|
1391
|
+
* defaultValue: "light" as "light" | "dark",
|
|
1392
|
+
* listenCrossTab: true,
|
|
1393
|
+
* });
|
|
1394
|
+
*
|
|
1395
|
+
* const { value, set } = useMnemonicKey(themeKey);
|
|
1396
|
+
* ```
|
|
1397
|
+
*
|
|
1398
|
+
* @see {@link defineMnemonicKey} - Helper for creating descriptors
|
|
1399
|
+
* @see {@link useMnemonicKey} - Hook that consumes descriptors
|
|
1400
|
+
*/
|
|
1401
|
+
interface MnemonicKeyDescriptor<T, K extends string = string> {
|
|
1402
|
+
/**
|
|
1403
|
+
* Unprefixed storage key name.
|
|
1404
|
+
*/
|
|
1405
|
+
readonly key: K;
|
|
1406
|
+
/**
|
|
1407
|
+
* Canonical options for this key.
|
|
1408
|
+
*/
|
|
1409
|
+
readonly options: UseMnemonicKeyOptions<T>;
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Key descriptor options inferred from a typed key schema.
|
|
1413
|
+
*
|
|
1414
|
+
* This mirrors `UseMnemonicKeyOptions<T>` but intentionally omits the `schema`
|
|
1415
|
+
* override so the descriptor stays pinned to the supplied key schema version.
|
|
1416
|
+
*/
|
|
1417
|
+
type SchemaBoundKeyOptions<T> = Omit<UseMnemonicKeyOptions<T>, "schema">;
|
|
1418
|
+
/**
|
|
1419
|
+
* Typed key schema shape inferred from a schema helper or branded JSON Schema.
|
|
1420
|
+
*
|
|
1421
|
+
* Useful when you want a versioned schema object to carry its decoded
|
|
1422
|
+
* TypeScript value through registries, descriptors, and migration helpers.
|
|
1423
|
+
*/
|
|
1424
|
+
type TypedKeySchema<TSchema extends JsonSchema, K extends string = string> = KeySchema<InferJsonSchemaValue<TSchema>, K, TSchema>;
|
|
1175
1425
|
/**
|
|
1176
1426
|
* Configuration options for the useMnemonicKey hook.
|
|
1177
1427
|
*
|
|
@@ -1286,6 +1536,9 @@ type UseMnemonicKeyOptions<T> = {
|
|
|
1286
1536
|
* adjustments that depend on application policy rather than a strict schema
|
|
1287
1537
|
* upgrade step.
|
|
1288
1538
|
*
|
|
1539
|
+
* See the Schema Migration guide for migration-vs-reconciliation guidance:
|
|
1540
|
+
* https://thirtytwobits.github.io/react-mnemonic/docs/guides/schema-migration
|
|
1541
|
+
*
|
|
1289
1542
|
* If `reconcile` throws a `SchemaError`, that error is preserved and passed
|
|
1290
1543
|
* to `defaultValue`. Any other thrown error is wrapped as
|
|
1291
1544
|
* `SchemaError("RECONCILE_FAILED")`.
|
|
@@ -1360,6 +1613,22 @@ type UseMnemonicKeyOptions<T> = {
|
|
|
1360
1613
|
* automatically via React's state management.
|
|
1361
1614
|
*/
|
|
1362
1615
|
listenCrossTab?: boolean;
|
|
1616
|
+
/**
|
|
1617
|
+
* Server-rendering controls for this key.
|
|
1618
|
+
*
|
|
1619
|
+
* Use this when the server should render a value other than
|
|
1620
|
+
* `defaultValue`, or when persisted storage should only be read after the
|
|
1621
|
+
* component has mounted on the client.
|
|
1622
|
+
*
|
|
1623
|
+
* @example
|
|
1624
|
+
* ```typescript
|
|
1625
|
+
* ssr: {
|
|
1626
|
+
* serverValue: { theme: "system" },
|
|
1627
|
+
* hydration: "client-only",
|
|
1628
|
+
* }
|
|
1629
|
+
* ```
|
|
1630
|
+
*/
|
|
1631
|
+
ssr?: MnemonicKeySSRConfig<T>;
|
|
1363
1632
|
/**
|
|
1364
1633
|
* Optional schema controls for this key.
|
|
1365
1634
|
*
|
|
@@ -1418,11 +1687,11 @@ type ReconcileContext = {
|
|
|
1418
1687
|
* @see {@link MnemonicProviderOptions} - Configuration options
|
|
1419
1688
|
* @see {@link MnemonicProvider} - Provider component
|
|
1420
1689
|
*/
|
|
1421
|
-
interface MnemonicProviderProps extends MnemonicProviderOptions {
|
|
1690
|
+
interface MnemonicProviderProps extends Readonly<MnemonicProviderOptions> {
|
|
1422
1691
|
/**
|
|
1423
1692
|
* React children to render within the provider.
|
|
1424
1693
|
*/
|
|
1425
|
-
children: ReactNode;
|
|
1694
|
+
readonly children: ReactNode;
|
|
1426
1695
|
}
|
|
1427
1696
|
/**
|
|
1428
1697
|
* React Context provider for namespace-isolated persistent state.
|
|
@@ -1437,10 +1706,11 @@ interface MnemonicProviderProps extends MnemonicProviderOptions {
|
|
|
1437
1706
|
* @param props - Provider configuration and children
|
|
1438
1707
|
* @param props.children - React children to render within the provider
|
|
1439
1708
|
* @param props.namespace - Unique namespace for isolating storage keys
|
|
1440
|
-
* @param props.storage - Optional custom storage backend (defaults to localStorage)
|
|
1709
|
+
* @param props.storage - Optional synchronous custom storage backend (defaults to localStorage)
|
|
1441
1710
|
* @param props.enableDevTools - Enable DevTools debugging interface (defaults to false)
|
|
1442
1711
|
* @param props.schemaMode - Schema enforcement mode (default: "default")
|
|
1443
1712
|
* @param props.schemaRegistry - Optional schema registry for storing schemas and migrations
|
|
1713
|
+
* @param props.ssr - Optional SSR defaults for descendant hooks
|
|
1444
1714
|
*
|
|
1445
1715
|
* @example
|
|
1446
1716
|
* ```tsx
|
|
@@ -1456,7 +1726,7 @@ interface MnemonicProviderProps extends MnemonicProviderOptions {
|
|
|
1456
1726
|
*
|
|
1457
1727
|
* @example
|
|
1458
1728
|
* ```tsx
|
|
1459
|
-
* // With custom storage backend
|
|
1729
|
+
* // With a synchronous custom storage backend
|
|
1460
1730
|
* function App() {
|
|
1461
1731
|
* return (
|
|
1462
1732
|
* <MnemonicProvider
|
|
@@ -1505,17 +1775,34 @@ interface MnemonicProviderProps extends MnemonicProviderOptions {
|
|
|
1505
1775
|
* }
|
|
1506
1776
|
* ```
|
|
1507
1777
|
*
|
|
1778
|
+
* @example
|
|
1779
|
+
* ```tsx
|
|
1780
|
+
* // Delay persisted storage reads until after client mount
|
|
1781
|
+
* function App() {
|
|
1782
|
+
* return (
|
|
1783
|
+
* <MnemonicProvider
|
|
1784
|
+
* namespace="myApp"
|
|
1785
|
+
* ssr={{ hydration: "client-only" }}
|
|
1786
|
+
* >
|
|
1787
|
+
* <MyComponents />
|
|
1788
|
+
* </MnemonicProvider>
|
|
1789
|
+
* );
|
|
1790
|
+
* }
|
|
1791
|
+
* ```
|
|
1792
|
+
*
|
|
1508
1793
|
* @remarks
|
|
1509
1794
|
* - Creates a stable store instance that only recreates when namespace, storage, or enableDevTools change
|
|
1510
1795
|
* - All storage operations are cached in memory for fast reads
|
|
1511
1796
|
* - Storage failures are handled gracefully (logged but not thrown)
|
|
1512
|
-
* -
|
|
1797
|
+
* - `StorageLike` is intentionally synchronous for v1; async persistence must sit behind a sync facade
|
|
1798
|
+
* - In SSR environments, the provider is safe by default: hooks render
|
|
1799
|
+
* `defaultValue` unless configured with an explicit `ssr.serverValue`
|
|
1513
1800
|
* - The store implements React's useSyncExternalStore contract for efficient updates
|
|
1514
1801
|
*
|
|
1515
1802
|
* @see {@link useMnemonicKey} - Hook for using persistent state
|
|
1516
1803
|
* @see {@link MnemonicProviderOptions} - Configuration options
|
|
1517
1804
|
*/
|
|
1518
|
-
declare function MnemonicProvider({ children, namespace, storage, enableDevTools, schemaMode, schemaRegistry, }: MnemonicProviderProps): react_jsx_runtime.JSX.Element;
|
|
1805
|
+
declare function MnemonicProvider({ children, namespace, storage, enableDevTools, schemaMode, schemaRegistry, ssr, }: MnemonicProviderProps): react_jsx_runtime.JSX.Element;
|
|
1519
1806
|
|
|
1520
1807
|
/**
|
|
1521
1808
|
* React hook for persistent, type-safe state management.
|
|
@@ -1527,25 +1814,33 @@ declare function MnemonicProvider({ children, namespace, storage, enableDevTools
|
|
|
1527
1814
|
* Must be used within a `MnemonicProvider`. Uses React's `useSyncExternalStore`
|
|
1528
1815
|
* internally for efficient, tearing-free state synchronization.
|
|
1529
1816
|
*
|
|
1817
|
+
* Read lifecycle, in order:
|
|
1818
|
+
* 1. Load the raw stored envelope for `key`
|
|
1819
|
+
* 2. Decode the payload (codec or schema-managed JSON)
|
|
1820
|
+
* 3. Validate and migrate when schemas are registered
|
|
1821
|
+
* 4. Run `reconcile(...)` if provided
|
|
1822
|
+
* 5. Fall back to `defaultValue` when the key is absent or invalid
|
|
1823
|
+
*
|
|
1824
|
+
* Write semantics:
|
|
1825
|
+
* - `set(...)` persists a new value
|
|
1826
|
+
* - `reset()` persists `defaultValue`
|
|
1827
|
+
* - `remove()` deletes the key entirely so future reads fall back to `defaultValue`
|
|
1828
|
+
*
|
|
1829
|
+
* For guide-level background, see the
|
|
1830
|
+
* [Schema Migration guide](https://thirtytwobits.github.io/react-mnemonic/docs/guides/schema-migration)
|
|
1831
|
+
* and the
|
|
1832
|
+
* [Clearable Persisted Values guide](https://thirtytwobits.github.io/react-mnemonic/docs/guides/clearable-persisted-values).
|
|
1833
|
+
*
|
|
1530
1834
|
* @template T - The TypeScript type of the stored value
|
|
1531
1835
|
*
|
|
1532
|
-
* @
|
|
1533
|
-
* @param options - Configuration options controlling persistence, encoding, and behavior
|
|
1836
|
+
* @returns Persistent state handle with the current value and mutation helpers
|
|
1534
1837
|
*
|
|
1535
|
-
* @
|
|
1838
|
+
* @see {@link UseMnemonicKeyOptions} - Hook configuration and lifecycle details
|
|
1536
1839
|
*
|
|
1537
1840
|
* @throws {Error} If used outside of a MnemonicProvider
|
|
1538
1841
|
*/
|
|
1539
|
-
declare function useMnemonicKey<T>(
|
|
1540
|
-
|
|
1541
|
-
value: T;
|
|
1542
|
-
/** Persist a new value (direct or updater function). */
|
|
1543
|
-
set: (next: T | ((cur: T) => T)) => void;
|
|
1544
|
-
/** Reset to `defaultValue` and persist it. */
|
|
1545
|
-
reset: () => void;
|
|
1546
|
-
/** Delete the key from storage entirely. */
|
|
1547
|
-
remove: () => void;
|
|
1548
|
-
};
|
|
1842
|
+
declare function useMnemonicKey<T, K extends string>(descriptor: MnemonicKeyDescriptor<T, K>): MnemonicKeyState<T>;
|
|
1843
|
+
declare function useMnemonicKey<T>(key: string, options: UseMnemonicKeyOptions<T>): MnemonicKeyState<T>;
|
|
1549
1844
|
|
|
1550
1845
|
/**
|
|
1551
1846
|
* Hook for namespace-scoped recovery actions such as hard reset and selective clear.
|
|
@@ -1553,6 +1848,10 @@ declare function useMnemonicKey<T>(key: string, options: UseMnemonicKeyOptions<T
|
|
|
1553
1848
|
* Applications can use this to offer self-service recovery UX for corrupt or
|
|
1554
1849
|
* legacy persisted state. The hook operates on the current provider namespace.
|
|
1555
1850
|
*
|
|
1851
|
+
* See the
|
|
1852
|
+
* [Reset and Recovery guide](https://thirtytwobits.github.io/react-mnemonic/docs/guides/reset-and-recovery)
|
|
1853
|
+
* for soft-reset and hard-reset patterns.
|
|
1854
|
+
*
|
|
1556
1855
|
* @param options - Optional recovery callback for telemetry/auditing
|
|
1557
1856
|
* @returns Namespace recovery helpers
|
|
1558
1857
|
*
|
|
@@ -1560,6 +1859,33 @@ declare function useMnemonicKey<T>(key: string, options: UseMnemonicKeyOptions<T
|
|
|
1560
1859
|
*/
|
|
1561
1860
|
declare function useMnemonicRecovery(options?: UseMnemonicRecoveryOptions): MnemonicRecoveryHook;
|
|
1562
1861
|
|
|
1862
|
+
/**
|
|
1863
|
+
* Define a reusable, importable contract for a persisted key.
|
|
1864
|
+
*
|
|
1865
|
+
* This packages the storage key and the canonical `useMnemonicKey(...)`
|
|
1866
|
+
* options into a single object that can be shared across components, docs,
|
|
1867
|
+
* and generated code.
|
|
1868
|
+
*
|
|
1869
|
+
* @template K - The literal storage key name
|
|
1870
|
+
* @template T - The decoded value type for the key
|
|
1871
|
+
*
|
|
1872
|
+
* @param key - The unprefixed storage key
|
|
1873
|
+
* @param options - Canonical hook options for the key
|
|
1874
|
+
* @returns A descriptor that can be passed directly to `useMnemonicKey(...)`
|
|
1875
|
+
*
|
|
1876
|
+
* @example
|
|
1877
|
+
* ```typescript
|
|
1878
|
+
* const themeKey = defineMnemonicKey("theme", {
|
|
1879
|
+
* defaultValue: "light" as "light" | "dark",
|
|
1880
|
+
* listenCrossTab: true,
|
|
1881
|
+
* });
|
|
1882
|
+
*
|
|
1883
|
+
* const { value, set } = useMnemonicKey(themeKey);
|
|
1884
|
+
* ```
|
|
1885
|
+
*/
|
|
1886
|
+
declare function defineMnemonicKey<const K extends string, T>(key: K, options: UseMnemonicKeyOptions<T>): MnemonicKeyDescriptor<T, K>;
|
|
1887
|
+
declare function defineMnemonicKey<const K extends string, TSchema extends KeySchema<unknown, K, JsonSchema>>(keySchema: TSchema, options: SchemaBoundKeyOptions<TSchema extends KeySchema<infer TValue, string, JsonSchema> ? TValue : never>): MnemonicKeyDescriptor<TSchema extends KeySchema<infer TValue, string, JsonSchema> ? TValue : never, TSchema["key"]>;
|
|
1888
|
+
|
|
1563
1889
|
/**
|
|
1564
1890
|
* Create an immutable schema registry for common default/strict-mode setups.
|
|
1565
1891
|
*
|
|
@@ -1567,6 +1893,13 @@ declare function useMnemonicRecovery(options?: UseMnemonicRecoveryOptions): Mnem
|
|
|
1567
1893
|
* ambiguous definitions, and returns a {@link SchemaRegistry} ready to pass to
|
|
1568
1894
|
* `MnemonicProvider`.
|
|
1569
1895
|
*
|
|
1896
|
+
* Most applications should prefer this helper over manually implementing
|
|
1897
|
+
* {@link SchemaRegistry}.
|
|
1898
|
+
*
|
|
1899
|
+
* See the
|
|
1900
|
+
* [Schema Migration guide](https://thirtytwobits.github.io/react-mnemonic/docs/guides/schema-migration)
|
|
1901
|
+
* for end-to-end registry and migration patterns.
|
|
1902
|
+
*
|
|
1570
1903
|
* @param options - Initial schema and migration definitions
|
|
1571
1904
|
* @returns An indexed immutable schema registry
|
|
1572
1905
|
*
|
|
@@ -1575,6 +1908,23 @@ declare function useMnemonicRecovery(options?: UseMnemonicRecoveryOptions): Mnem
|
|
|
1575
1908
|
*/
|
|
1576
1909
|
declare function createSchemaRegistry(options?: CreateSchemaRegistryOptions): SchemaRegistry;
|
|
1577
1910
|
|
|
1911
|
+
/**
|
|
1912
|
+
* Create a versioned key schema that preserves the decoded value type inferred
|
|
1913
|
+
* from a typed schema helper.
|
|
1914
|
+
*/
|
|
1915
|
+
declare function defineKeySchema<const K extends string, TSchema extends JsonSchema>(key: K, version: number, schema: TSchema): KeySchema<InferJsonSchemaValue<TSchema>, K, TSchema>;
|
|
1916
|
+
/**
|
|
1917
|
+
* Create a typed migration rule between two key schema versions.
|
|
1918
|
+
*
|
|
1919
|
+
* The `migrate(...)` callback is inferred from the source and target schemas,
|
|
1920
|
+
* which keeps migration logic aligned with the registered runtime schemas.
|
|
1921
|
+
*/
|
|
1922
|
+
declare function defineMigration<const K extends string, TFrom, TTo>(fromSchema: KeySchema<TFrom, K>, toSchema: KeySchema<TTo, K>, migrate: (value: TFrom) => TTo): MigrationRule<TFrom, TTo, K>;
|
|
1923
|
+
/**
|
|
1924
|
+
* Create a typed write-time normalization rule for a single key schema.
|
|
1925
|
+
*/
|
|
1926
|
+
declare function defineWriteMigration<const K extends string, TValue>(schema: KeySchema<TValue, K>, migrate: (value: TValue) => TValue): MigrationRule<TValue, TValue, K>;
|
|
1927
|
+
|
|
1578
1928
|
/**
|
|
1579
1929
|
* Adapter functions for structural migration helpers.
|
|
1580
1930
|
*
|
|
@@ -1716,4 +2066,4 @@ declare function dedupeChildrenBy<T extends StructuralNode<T>, K>(root: T, getKe
|
|
|
1716
2066
|
*/
|
|
1717
2067
|
declare function dedupeChildrenBy<T, K>(root: T, getKey: (node: T) => K, helpers: StructuralTreeHelpers<T>): T;
|
|
1718
2068
|
|
|
1719
|
-
export { type Codec, CodecError, type CompiledValidator, type CreateSchemaRegistryOptions, JSONCodec, type JsonSchema, type JsonSchemaType, type JsonSchemaValidationError, type KeySchema, type Listener, type MigrationPath, type MigrationRule, type Mnemonic, type MnemonicDevToolsCapabilities, type MnemonicDevToolsMeta, type MnemonicDevToolsProviderApi, type MnemonicDevToolsProviderDescriptor, type MnemonicDevToolsProviderEntry, type MnemonicDevToolsRegistry, type MnemonicDevToolsWeakRef, MnemonicProvider, type MnemonicProviderOptions, type MnemonicProviderProps, type MnemonicRecoveryAction, type MnemonicRecoveryEvent, type MnemonicRecoveryHook, type ReconcileContext, SchemaError, type SchemaMode, type SchemaRegistry, type StorageLike, type StructuralNode, type StructuralTreeHelpers, type Unsubscribe, type UseMnemonicKeyOptions, type UseMnemonicRecoveryOptions, compileSchema, createCodec, createSchemaRegistry, dedupeChildrenBy, findNodeById, insertChildIfMissing, renameNode, useMnemonicKey, useMnemonicRecovery, validateJsonSchema };
|
|
2069
|
+
export { type Codec, CodecError, type CompiledValidator, type CreateSchemaRegistryOptions, type InferJsonSchemaValue, JSONCodec, type JsonSchema, type JsonSchemaType, type JsonSchemaValidationError, type KeySchema, type Listener, type MigrationPath, type MigrationRule, type Mnemonic, type MnemonicDevToolsCapabilities, type MnemonicDevToolsMeta, type MnemonicDevToolsProviderApi, type MnemonicDevToolsProviderDescriptor, type MnemonicDevToolsProviderEntry, type MnemonicDevToolsRegistry, type MnemonicDevToolsWeakRef, type MnemonicHydrationMode, type MnemonicKeyDescriptor, type MnemonicKeySSRConfig, type MnemonicKeyState, MnemonicProvider, type MnemonicProviderOptions, type MnemonicProviderProps, type MnemonicProviderSSRConfig, type MnemonicRecoveryAction, type MnemonicRecoveryEvent, type MnemonicRecoveryHook, type ReconcileContext, type SchemaBoundKeyOptions, SchemaError, type SchemaMode, type SchemaRegistry, type StorageLike, type StructuralNode, type StructuralTreeHelpers, type TypedJsonSchema, type TypedKeySchema, type Unsubscribe, type UseMnemonicKeyOptions, type UseMnemonicRecoveryOptions, compileSchema, createCodec, createSchemaRegistry, dedupeChildrenBy, defineKeySchema, defineMigration, defineMnemonicKey, defineWriteMigration, findNodeById, insertChildIfMissing, mnemonicSchema, renameNode, useMnemonicKey, useMnemonicRecovery, validateJsonSchema };
|