@molecule/app-react 2.0.1 → 3.0.0
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 +81 -12
- package/dist/hooks/useForm.d.ts +6 -6
- package/dist/hooks/useForm.d.ts.map +1 -1
- package/dist/hooks/useForm.js.map +1 -1
- package/dist/hooks/useProfileForm.d.ts +10 -5
- package/dist/hooks/useProfileForm.d.ts.map +1 -1
- package/dist/hooks/useProfileForm.js +18 -5
- package/dist/hooks/useProfileForm.js.map +1 -1
- package/dist/hooks/useStorage.d.ts +59 -1
- package/dist/hooks/useStorage.d.ts.map +1 -1
- package/dist/hooks/useStorage.js +108 -20
- package/dist/hooks/useStorage.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-10-
|
|
6
|
+
Generated: 2026-10-27T23:36:38.589Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/app-react
|
|
@@ -321,7 +321,7 @@ Form controller interface.
|
|
|
321
321
|
All form providers must implement this interface.
|
|
322
322
|
|
|
323
323
|
```typescript
|
|
324
|
-
interface FormController<T extends
|
|
324
|
+
interface FormController<T extends FormValuesConstraint<T> = Record<string, unknown>> {
|
|
325
325
|
/**
|
|
326
326
|
* Gets the current form state.
|
|
327
327
|
*/
|
|
@@ -429,7 +429,7 @@ interface FormController<T extends Record<string, unknown> = Record<string, unkn
|
|
|
429
429
|
Form creation options.
|
|
430
430
|
|
|
431
431
|
```typescript
|
|
432
|
-
interface FormOptions<T extends
|
|
432
|
+
interface FormOptions<T extends FormValuesConstraint<T>> {
|
|
433
433
|
/**
|
|
434
434
|
* Default values, captured as the form's clean baseline when the controller
|
|
435
435
|
* is created. Mutating this object afterwards does not change the baseline.
|
|
@@ -844,7 +844,7 @@ provider (`createForm` from `@molecule/app-forms`), which uses the built-in
|
|
|
844
844
|
native provider until the app bonds its own.
|
|
845
845
|
|
|
846
846
|
```typescript
|
|
847
|
-
interface UseFormOptions<T extends
|
|
847
|
+
interface UseFormOptions<T extends FormValuesConstraint<T>> extends FormOptions<T> {
|
|
848
848
|
/**
|
|
849
849
|
* Explicit form factory for this one form. Defaults to the bonded forms
|
|
850
850
|
* provider; pass it only to pin a specific provider instance.
|
|
@@ -858,7 +858,7 @@ interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<
|
|
|
858
858
|
Result of useForm hook.
|
|
859
859
|
|
|
860
860
|
```typescript
|
|
861
|
-
interface UseFormResult<T extends
|
|
861
|
+
interface UseFormResult<T extends FormValuesConstraint<T>> {
|
|
862
862
|
// State
|
|
863
863
|
formState: FormState<T>
|
|
864
864
|
isValid: boolean
|
|
@@ -1010,8 +1010,11 @@ interface UsePlatformResult {
|
|
|
1010
1010
|
|
|
1011
1011
|
Configuration for a profile form; transport stays in the auth bond.
|
|
1012
1012
|
|
|
1013
|
+
`TValues` is the page's own controlled-values type, named once as an
|
|
1014
|
+
`interface` or a type alias — both satisfy the shared form-values constraint.
|
|
1015
|
+
|
|
1013
1016
|
```typescript
|
|
1014
|
-
interface UseProfileFormOptions<TUser, TValues extends
|
|
1017
|
+
interface UseProfileFormOptions<TUser, TValues extends FormValuesConstraint<TValues>> extends Omit<
|
|
1015
1018
|
UseFormOptions<TValues>,
|
|
1016
1019
|
'defaultValues'
|
|
1017
1020
|
> {
|
|
@@ -1046,7 +1049,7 @@ interface UseProfileFormOptions<TUser, TValues extends Record<string, unknown>>
|
|
|
1046
1049
|
Controlled profile form state and native form bindings.
|
|
1047
1050
|
|
|
1048
1051
|
```typescript
|
|
1049
|
-
interface UseProfileFormResult<TUser, TValues extends
|
|
1052
|
+
interface UseProfileFormResult<TUser, TValues extends FormValuesConstraint<TValues>> extends Omit<
|
|
1050
1053
|
UseFormResult<TValues>,
|
|
1051
1054
|
'register' | 'handleSubmit' | 'reset'
|
|
1052
1055
|
> {
|
|
@@ -1171,6 +1174,43 @@ interface UseStorageValueResult<T> {
|
|
|
1171
1174
|
}
|
|
1172
1175
|
```
|
|
1173
1176
|
|
|
1177
|
+
#### `UseStoragePreferenceOptions`
|
|
1178
|
+
|
|
1179
|
+
Options for {@link useStoragePreference}.
|
|
1180
|
+
|
|
1181
|
+
```typescript
|
|
1182
|
+
interface UseStoragePreferenceOptions<T> {
|
|
1183
|
+
/**
|
|
1184
|
+
* Value reported until the provider supplies one. It is NEVER written to
|
|
1185
|
+
* storage: a default is a display fallback, not a decision the user made.
|
|
1186
|
+
*/
|
|
1187
|
+
defaultValue?: T
|
|
1188
|
+
}
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
#### `UseStoragePreferenceResult`
|
|
1192
|
+
|
|
1193
|
+
Result of {@link useStoragePreference}.
|
|
1194
|
+
|
|
1195
|
+
```typescript
|
|
1196
|
+
interface UseStoragePreferenceResult<T> {
|
|
1197
|
+
/** The persisted value, or `defaultValue` while none is known. */
|
|
1198
|
+
value: T | undefined
|
|
1199
|
+
/**
|
|
1200
|
+
* Writes the value through the preference store: subscribers update
|
|
1201
|
+
* immediately and persistence is best-effort.
|
|
1202
|
+
*/
|
|
1203
|
+
setValue: (next: T | ((previous: T | undefined) => T)) => void
|
|
1204
|
+
/** Removes the key through the preference store. */
|
|
1205
|
+
removeValue: () => void
|
|
1206
|
+
/**
|
|
1207
|
+
* `true` once the store has a definite answer — the synchronous snapshot on
|
|
1208
|
+
* a synchronous provider, or the hydration result on an asynchronous one.
|
|
1209
|
+
*/
|
|
1210
|
+
ready: boolean
|
|
1211
|
+
}
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1174
1214
|
#### `UseVerifyPaymentReturnOptions`
|
|
1175
1215
|
|
|
1176
1216
|
Options for {@link useVerifyPaymentReturn}.
|
|
@@ -2138,7 +2178,9 @@ wires a form library once (`setProvider` from `@molecule/app-forms`) and
|
|
|
2138
2178
|
every form picks it up. Passing `createForm` overrides that for one form.
|
|
2139
2179
|
|
|
2140
2180
|
```typescript
|
|
2141
|
-
function useForm<T extends Record<string, unknown>>(
|
|
2181
|
+
function useForm<T extends FormValuesConstraint<T> = Record<string, unknown>>(
|
|
2182
|
+
options?: UseFormOptions<T>,
|
|
2183
|
+
): UseFormResult<T>
|
|
2142
2184
|
```
|
|
2143
2185
|
|
|
2144
2186
|
- `options` — Form options. `defaultValues`, `mode` and the form-level `validate` are forwarded to the provider; omit the options entirely for a form whose fields are registered with their own defaults.
|
|
@@ -2150,7 +2192,7 @@ function useForm<T extends Record<string, unknown>>(options?: UseFormOptions<T>)
|
|
|
2150
2192
|
Hook to watch a specific field value.
|
|
2151
2193
|
|
|
2152
2194
|
```typescript
|
|
2153
|
-
function useWatch<T extends
|
|
2195
|
+
function useWatch<T extends FormValuesConstraint<T>, K extends keyof T>(
|
|
2154
2196
|
form: FormController<T>,
|
|
2155
2197
|
name: K,
|
|
2156
2198
|
): T[K]
|
|
@@ -2166,7 +2208,7 @@ function useWatch<T extends Record<string, unknown>, K extends keyof T>(
|
|
|
2166
2208
|
Hook to get field-level state.
|
|
2167
2209
|
|
|
2168
2210
|
```typescript
|
|
2169
|
-
function useFieldState<T extends
|
|
2211
|
+
function useFieldState<T extends FormValuesConstraint<T>>(
|
|
2170
2212
|
form: FormController<T>,
|
|
2171
2213
|
name: keyof T,
|
|
2172
2214
|
): FieldState<T[keyof T]>
|
|
@@ -2429,7 +2471,7 @@ the clean baseline; edits made while saving remain dirty. No request is made
|
|
|
2429
2471
|
for a patch with no fields. A failed request retains the edits and shared user.
|
|
2430
2472
|
|
|
2431
2473
|
```typescript
|
|
2432
|
-
function useProfileForm<TUser, TValues extends
|
|
2474
|
+
function useProfileForm<TUser, TValues extends FormValuesConstraint<TValues>>(
|
|
2433
2475
|
options: UseProfileFormOptions<TUser, TValues>,
|
|
2434
2476
|
): UseProfileFormResult<TUser, TValues>
|
|
2435
2477
|
```
|
|
@@ -2581,6 +2623,33 @@ function useStorageValue<T>(
|
|
|
2581
2623
|
|
|
2582
2624
|
**Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
|
|
2583
2625
|
|
|
2626
|
+
#### `useStoragePreference(key, options)`
|
|
2627
|
+
|
|
2628
|
+
Subscribes React state to ONE persisted preference.
|
|
2629
|
+
|
|
2630
|
+
This is the component-side half of `getPreferenceStore()`: a render-time value
|
|
2631
|
+
is available immediately when the bonded provider can answer synchronously,
|
|
2632
|
+
and an asynchronous provider's hydration CONVERGES onto the same component
|
|
2633
|
+
without a remount. Ordering is the store's: a read that started before a
|
|
2634
|
+
newer write, remove or external change is discarded, so a slow hydration
|
|
2635
|
+
never overwrites an edit the user already made.
|
|
2636
|
+
|
|
2637
|
+
Pass `null` for `key` while the real key is unknown (no project selected
|
|
2638
|
+
yet): the hook then behaves as local state around `defaultValue` and persists
|
|
2639
|
+
nothing.
|
|
2640
|
+
|
|
2641
|
+
```typescript
|
|
2642
|
+
function useStoragePreference<T = unknown>(
|
|
2643
|
+
key: string | null | undefined,
|
|
2644
|
+
options?: UseStoragePreferenceOptions<T>,
|
|
2645
|
+
): UseStoragePreferenceResult<T>
|
|
2646
|
+
```
|
|
2647
|
+
|
|
2648
|
+
- `key` — The storage key, or `null` when there is nothing to persist.
|
|
2649
|
+
- `options` — `defaultValue`, reported until the provider supplies one.
|
|
2650
|
+
|
|
2651
|
+
**Returns:** The current value, its mutators, and whether it is definite yet.
|
|
2652
|
+
|
|
2584
2653
|
#### `useStorage()`
|
|
2585
2654
|
|
|
2586
2655
|
Hook for simple storage operations without React state sync.
|
|
@@ -3170,7 +3239,7 @@ Peer dependencies:
|
|
|
3170
3239
|
|
|
3171
3240
|
- `@molecule/app-auth` ^3.0.0
|
|
3172
3241
|
- `@molecule/app-ai-models` ^1.0.1
|
|
3173
|
-
- `@molecule/app-forms` ^
|
|
3242
|
+
- `@molecule/app-forms` ^2.0.0
|
|
3174
3243
|
- `@molecule/app-utilities` ^1.0.1
|
|
3175
3244
|
- `@molecule/app-http` ^1.0.1
|
|
3176
3245
|
- `@molecule/app-i18n` ^1.0.1
|
package/dist/hooks/useForm.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { FieldRegistration, FieldState, FormController, FormOptions, FormState, RegisterOptions } from '@molecule/app-forms';
|
|
6
|
+
import type { FieldRegistration, FieldState, FormController, FormOptions, FormState, FormValuesConstraint, RegisterOptions } from '@molecule/app-forms';
|
|
7
7
|
/**
|
|
8
8
|
* Options for useForm hook.
|
|
9
9
|
*
|
|
@@ -12,7 +12,7 @@ import type { FieldRegistration, FieldState, FormController, FormOptions, FormSt
|
|
|
12
12
|
* provider (`createForm` from `@molecule/app-forms`), which uses the built-in
|
|
13
13
|
* native provider until the app bonds its own.
|
|
14
14
|
*/
|
|
15
|
-
export interface UseFormOptions<T extends
|
|
15
|
+
export interface UseFormOptions<T extends FormValuesConstraint<T>> extends FormOptions<T> {
|
|
16
16
|
/**
|
|
17
17
|
* Explicit form factory for this one form. Defaults to the bonded forms
|
|
18
18
|
* provider; pass it only to pin a specific provider instance.
|
|
@@ -22,7 +22,7 @@ export interface UseFormOptions<T extends Record<string, unknown>> extends FormO
|
|
|
22
22
|
/**
|
|
23
23
|
* Result of useForm hook.
|
|
24
24
|
*/
|
|
25
|
-
export interface UseFormResult<T extends
|
|
25
|
+
export interface UseFormResult<T extends FormValuesConstraint<T>> {
|
|
26
26
|
formState: FormState<T>;
|
|
27
27
|
isValid: boolean;
|
|
28
28
|
isDirty: boolean;
|
|
@@ -80,7 +80,7 @@ export interface UseFormResult<T extends Record<string, unknown>> {
|
|
|
80
80
|
* }
|
|
81
81
|
* ```
|
|
82
82
|
*/
|
|
83
|
-
export declare function useForm<T extends Record<string, unknown>>(options?: UseFormOptions<T>): UseFormResult<T>;
|
|
83
|
+
export declare function useForm<T extends FormValuesConstraint<T> = Record<string, unknown>>(options?: UseFormOptions<T>): UseFormResult<T>;
|
|
84
84
|
/**
|
|
85
85
|
* Hook to watch a specific field value.
|
|
86
86
|
*
|
|
@@ -88,7 +88,7 @@ export declare function useForm<T extends Record<string, unknown>>(options?: Use
|
|
|
88
88
|
* @param name - Field name to watch
|
|
89
89
|
* @returns Current field value
|
|
90
90
|
*/
|
|
91
|
-
export declare function useWatch<T extends
|
|
91
|
+
export declare function useWatch<T extends FormValuesConstraint<T>, K extends keyof T>(form: FormController<T>, name: K): T[K];
|
|
92
92
|
/**
|
|
93
93
|
* Hook to get field-level state.
|
|
94
94
|
*
|
|
@@ -96,5 +96,5 @@ export declare function useWatch<T extends Record<string, unknown>, K extends ke
|
|
|
96
96
|
* @param name - Field name
|
|
97
97
|
* @returns Field state (value, error, touched, dirty, valid)
|
|
98
98
|
*/
|
|
99
|
-
export declare function useFieldState<T extends
|
|
99
|
+
export declare function useFieldState<T extends FormValuesConstraint<T>>(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>;
|
|
100
100
|
//# sourceMappingURL=useForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAmC5B;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,WAAW,EACX,SAAS,EACT,oBAAoB,EACpB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAmC5B;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,CAAE,SAAQ,WAAW,CAAC,CAAC,CAAC;IACvF;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,CAAA;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC;IAE9D,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IAGrB,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,CAAC,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KACxD,iBAAiB,CAAA;IACtB,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9C,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC3D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,GAAG,SAAS,CAAA;IAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;IAC5D,WAAW,EAAE,MAAM,IAAI,CAAA;IAGvB,YAAY,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;IAClG,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjF,OAAO,GAAE,cAAc,CAAC,CAAC,CAAM,GAC9B,aAAa,CAAC,CAAC,CAAC,CAwElB;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,EAC3E,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,CAAC,GACN,CAAC,CAAC,CAAC,CAAC,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,EAC7D,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,MAAM,CAAC,GACZ,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAGxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.js","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"useForm.js","sourceRoot":"","sources":["../../src/hooks/useForm.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,10 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type { FieldRegistration } from '@molecule/app-forms';
|
|
6
|
+
import type { FieldRegistration, FormValuesConstraint } from '@molecule/app-forms';
|
|
7
7
|
import { type UseFormOptions, type UseFormResult } from './useForm.js';
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for a profile form; transport stays in the auth bond.
|
|
10
|
+
*
|
|
11
|
+
* `TValues` is the page's own controlled-values type, named once as an
|
|
12
|
+
* `interface` or a type alias — both satisfy the shared form-values constraint.
|
|
13
|
+
*/
|
|
14
|
+
export interface UseProfileFormOptions<TUser, TValues extends FormValuesConstraint<TValues>> extends Omit<UseFormOptions<TValues>, 'defaultValues'> {
|
|
10
15
|
/** Complete controlled-field defaults, including blank write-only fields. */
|
|
11
16
|
defaultValues: TValues;
|
|
12
17
|
/**
|
|
@@ -32,7 +37,7 @@ export interface UseProfileFormOptions<TUser, TValues extends Record<string, unk
|
|
|
32
37
|
onSaved?: (user: TUser) => void | Promise<void>;
|
|
33
38
|
}
|
|
34
39
|
/** Controlled profile form state and native form bindings. */
|
|
35
|
-
export interface UseProfileFormResult<TUser, TValues extends
|
|
40
|
+
export interface UseProfileFormResult<TUser, TValues extends FormValuesConstraint<TValues>> extends Omit<UseFormResult<TValues>, 'register' | 'handleSubmit' | 'reset'> {
|
|
36
41
|
/** The shared auth user's current profile. */
|
|
37
42
|
user: TUser | null;
|
|
38
43
|
/** A user has been loaded; disable submission until this is true. */
|
|
@@ -73,5 +78,5 @@ export interface UseProfileFormResult<TUser, TValues extends Record<string, unkn
|
|
|
73
78
|
* @param options - Controlled defaults, identity and wire adapters, optional cache/navigation callback.
|
|
74
79
|
* @returns Form state, typed control bindings, native submit binding and save error.
|
|
75
80
|
*/
|
|
76
|
-
export declare function useProfileForm<TUser, TValues extends
|
|
81
|
+
export declare function useProfileForm<TUser, TValues extends FormValuesConstraint<TValues>>(options: UseProfileFormOptions<TUser, TValues>): UseProfileFormResult<TUser, TValues>;
|
|
77
82
|
//# sourceMappingURL=useProfileForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProfileForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useProfileForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"useProfileForm.d.ts","sourceRoot":"","sources":["../../src/hooks/useProfileForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAGlF,OAAO,EAAW,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAgB/E;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB,CACpC,KAAK,EACL,OAAO,SAAS,oBAAoB,CAAC,OAAO,CAAC,CAC7C,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACtD,6EAA6E;IAC7E,aAAa,EAAE,OAAO,CAAA;IACtB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;IACrC,oFAAoF;IACpF,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAA;IAClC;;;;OAIG;IACH,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAA;IACjF;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAED,8DAA8D;AAC9D,MAAM,WAAW,oBAAoB,CACnC,KAAK,EACL,OAAO,SAAS,oBAAoB,CAAC,OAAO,CAAC,CAC7C,SAAQ,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC;IAC3E,8CAA8C;IAC9C,IAAI,EAAE,KAAK,GAAG,IAAI,CAAA;IAClB,qEAAqE;IACrE,KAAK,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAA;IACd,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAChC,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,KACxD,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAA;IAC7D,sEAAsE;IACtE,SAAS,EAAE;QAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;KAAE,CAAA;IAC1E;;;OAGG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAA;IACxC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,SAAS,oBAAoB,CAAC,OAAO,CAAC,EACjF,OAAO,EAAE,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,GAC7C,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAsMtC"}
|
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
import { useCallback, useInsertionEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
7
7
|
import { useAuth, useAuthClient } from './useAuth.js';
|
|
8
8
|
import { useForm } from './useForm.js';
|
|
9
|
+
/**
|
|
10
|
+
* Copies the shallow value snapshot the hook keeps as its baseline.
|
|
11
|
+
*
|
|
12
|
+
* Form values are a plain string-keyed object at runtime; the caller's values
|
|
13
|
+
* TYPE may be an `interface`, which has no index signature to spread from, so
|
|
14
|
+
* the copy goes through the record view and comes back as `TValues`.
|
|
15
|
+
*
|
|
16
|
+
* @param values - The values object to snapshot.
|
|
17
|
+
* @returns A new object with the same own fields.
|
|
18
|
+
*/
|
|
19
|
+
function copyValues(values) {
|
|
20
|
+
return { ...values };
|
|
21
|
+
}
|
|
9
22
|
/**
|
|
10
23
|
* Owns load → edit → submit → publish for the signed-in user's profile.
|
|
11
24
|
*
|
|
@@ -30,7 +43,7 @@ export function useProfileForm(options) {
|
|
|
30
43
|
const [isSaving, setIsSaving] = useState(false);
|
|
31
44
|
const optionsRef = useRef(options);
|
|
32
45
|
const committedClient = useRef(client);
|
|
33
|
-
const baseline = useRef(
|
|
46
|
+
const baseline = useRef(copyValues(defaultValues));
|
|
34
47
|
const owner = useRef(null);
|
|
35
48
|
const activeSave = useRef(null);
|
|
36
49
|
const pendingPropagation = useRef(undefined);
|
|
@@ -47,14 +60,14 @@ export function useProfileForm(options) {
|
|
|
47
60
|
};
|
|
48
61
|
}, []);
|
|
49
62
|
const readValues = useCallback(() => {
|
|
50
|
-
const values =
|
|
63
|
+
const values = copyValues(baseline.current);
|
|
51
64
|
for (const key of Object.keys(values))
|
|
52
65
|
values[key] = form.getValue(key);
|
|
53
66
|
return values;
|
|
54
67
|
}, [form.getValue]);
|
|
55
68
|
const rebase = useCallback((next, preserveAgainst) => {
|
|
56
69
|
const current = readValues();
|
|
57
|
-
baseline.current =
|
|
70
|
+
baseline.current = copyValues(next);
|
|
58
71
|
form.reset(next);
|
|
59
72
|
if (preserveAgainst) {
|
|
60
73
|
for (const key of Object.keys(current)) {
|
|
@@ -69,7 +82,7 @@ export function useProfileForm(options) {
|
|
|
69
82
|
if (owner.current) {
|
|
70
83
|
owner.current = null;
|
|
71
84
|
pendingPropagation.current = undefined;
|
|
72
|
-
rebase(
|
|
85
|
+
rebase(copyValues(config.defaultValues));
|
|
73
86
|
setError(undefined);
|
|
74
87
|
}
|
|
75
88
|
return;
|
|
@@ -115,7 +128,7 @@ export function useProfileForm(options) {
|
|
|
115
128
|
config.getIdentity?.(current) === identity);
|
|
116
129
|
};
|
|
117
130
|
const snapshot = readValues();
|
|
118
|
-
const before =
|
|
131
|
+
const before = copyValues(baseline.current);
|
|
119
132
|
const changes = {};
|
|
120
133
|
for (const key of Object.keys(snapshot)) {
|
|
121
134
|
if (!Object.is(snapshot[key], before[key]))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProfileForm.js","sourceRoot":"","sources":["../../src/hooks/useProfileForm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAI1F,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,OAAO,EAA2C,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"useProfileForm.js","sourceRoot":"","sources":["../../src/hooks/useProfileForm.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import type
|
|
6
|
+
import { type StorageProvider } from '@molecule/app-storage';
|
|
7
7
|
/**
|
|
8
8
|
* Hook to access the storage provider from context.
|
|
9
9
|
*
|
|
@@ -57,6 +57,64 @@ export interface UseStorageValueResult<T> {
|
|
|
57
57
|
* @returns Storage value state (value, loading, error) and mutators (setValue, removeValue).
|
|
58
58
|
*/
|
|
59
59
|
export declare function useStorageValue<T>(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>;
|
|
60
|
+
/**
|
|
61
|
+
* Options for {@link useStoragePreference}.
|
|
62
|
+
*/
|
|
63
|
+
export interface UseStoragePreferenceOptions<T> {
|
|
64
|
+
/**
|
|
65
|
+
* Value reported until the provider supplies one. It is NEVER written to
|
|
66
|
+
* storage: a default is a display fallback, not a decision the user made.
|
|
67
|
+
*/
|
|
68
|
+
defaultValue?: T;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Result of {@link useStoragePreference}.
|
|
72
|
+
*/
|
|
73
|
+
export interface UseStoragePreferenceResult<T> {
|
|
74
|
+
/** The persisted value, or `defaultValue` while none is known. */
|
|
75
|
+
value: T | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Writes the value through the preference store: subscribers update
|
|
78
|
+
* immediately and persistence is best-effort.
|
|
79
|
+
*/
|
|
80
|
+
setValue: (next: T | ((previous: T | undefined) => T)) => void;
|
|
81
|
+
/** Removes the key through the preference store. */
|
|
82
|
+
removeValue: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* `true` once the store has a definite answer — the synchronous snapshot on
|
|
85
|
+
* a synchronous provider, or the hydration result on an asynchronous one.
|
|
86
|
+
*/
|
|
87
|
+
ready: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Subscribes React state to ONE persisted preference.
|
|
91
|
+
*
|
|
92
|
+
* This is the component-side half of `getPreferenceStore()`: a render-time value
|
|
93
|
+
* is available immediately when the bonded provider can answer synchronously,
|
|
94
|
+
* and an asynchronous provider's hydration CONVERGES onto the same component
|
|
95
|
+
* without a remount. Ordering is the store's: a read that started before a
|
|
96
|
+
* newer write, remove or external change is discarded, so a slow hydration
|
|
97
|
+
* never overwrites an edit the user already made.
|
|
98
|
+
*
|
|
99
|
+
* Pass `null` for `key` while the real key is unknown (no project selected
|
|
100
|
+
* yet): the hook then behaves as local state around `defaultValue` and persists
|
|
101
|
+
* nothing.
|
|
102
|
+
*
|
|
103
|
+
* @param key - The storage key, or `null` when there is nothing to persist.
|
|
104
|
+
* @param options - `defaultValue`, reported until the provider supplies one.
|
|
105
|
+
* @returns The current value, its mutators, and whether it is definite yet.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* const { value: width, setValue: setWidth, ready } = useStoragePreference<number>(key, {
|
|
110
|
+
* defaultValue: 280,
|
|
111
|
+
* })
|
|
112
|
+
* // A drag calls setWidth(320): the UI updates now and the write persists.
|
|
113
|
+
* // `ready` is false until hydration lands, so an effect must not persist the
|
|
114
|
+
* // fallback before then.
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function useStoragePreference<T = unknown>(key: string | null | undefined, options?: UseStoragePreferenceOptions<T>): UseStoragePreferenceResult<T>;
|
|
60
118
|
/**
|
|
61
119
|
* Hook for simple storage operations without React state sync.
|
|
62
120
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useStorage.d.ts","sourceRoot":"","sources":["../../src/hooks/useStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAIhF;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAUpD;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,CAAA;IAChB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAClC,qBAAqB,CAAC,CAAC,CAAC,CAuF1B;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B,CAAC,CAAC;IAC5C;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,kEAAkE;IAClE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;IACpB;;;OAGG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,IAAI,CAAA;IAC9D,oDAAoD;IACpD,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAA;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,OAAO,EAC9C,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,OAAO,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACvC,0BAA0B,CAAC,CAAC,CAAC,CA8D/B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI;IAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC1C,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CAC9B,CAoBA"}
|
package/dist/hooks/useStorage.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { useCallback, useContext, useEffect, useState } from 'react';
|
|
6
|
+
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { t } from '@molecule/app-i18n';
|
|
8
|
+
import { getPreferenceStore } from '@molecule/app-storage';
|
|
8
9
|
import { StorageContext } from '../contexts.js';
|
|
9
10
|
/**
|
|
10
11
|
* Hook to access the storage provider from context.
|
|
@@ -49,19 +50,26 @@ export function useStorageValue(key, options) {
|
|
|
49
50
|
const [value, setValueState] = useState(defaultValue);
|
|
50
51
|
const [loading, setLoading] = useState(true);
|
|
51
52
|
const [error, setError] = useState(null);
|
|
53
|
+
/**
|
|
54
|
+
* Incremented by every local write. A read that started before it must not
|
|
55
|
+
* replace the newer value — the user editing before the first read lands is
|
|
56
|
+
* the common case on a slow (native, encrypted) backend.
|
|
57
|
+
*/
|
|
58
|
+
const writeVersion = useRef(0);
|
|
52
59
|
// Load initial value
|
|
53
60
|
useEffect(() => {
|
|
54
61
|
let mounted = true;
|
|
62
|
+
const version = writeVersion.current;
|
|
55
63
|
const loadValue = async () => {
|
|
56
64
|
try {
|
|
57
65
|
const stored = await storage.get(key);
|
|
58
|
-
if (mounted) {
|
|
66
|
+
if (mounted && writeVersion.current === version) {
|
|
59
67
|
setValueState(stored ?? defaultValue);
|
|
60
68
|
setLoading(false);
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
71
|
catch (err) {
|
|
64
|
-
if (mounted) {
|
|
72
|
+
if (mounted && writeVersion.current === version) {
|
|
65
73
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
66
74
|
setLoading(false);
|
|
67
75
|
}
|
|
@@ -72,26 +80,19 @@ export function useStorageValue(key, options) {
|
|
|
72
80
|
mounted = false;
|
|
73
81
|
};
|
|
74
82
|
}, [key, storage, defaultValue]);
|
|
75
|
-
// Sync across tabs if supported
|
|
83
|
+
// Sync across tabs if supported — through the PROVIDER's own subscription, so
|
|
84
|
+
// a non-browser backend (native, encrypted, memory) propagates the same way
|
|
85
|
+
// instead of being limited to the browser `storage` event.
|
|
76
86
|
useEffect(() => {
|
|
77
|
-
if (!sync)
|
|
87
|
+
if (!sync || !storage.subscribe)
|
|
78
88
|
return;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
catch (_error) {
|
|
86
|
-
// JSON.parse failed on newValue — the cross-tab sync is best-effort and the
|
|
87
|
-
// local state already holds the last good value, so ignoring is safe here.
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
window.addEventListener('storage', handleStorageChange);
|
|
92
|
-
return () => window.removeEventListener('storage', handleStorageChange);
|
|
93
|
-
}, [key, sync]);
|
|
89
|
+
return storage.subscribe(key, (next) => {
|
|
90
|
+
writeVersion.current += 1;
|
|
91
|
+
setValueState(next === null ? defaultValue : next);
|
|
92
|
+
});
|
|
93
|
+
}, [key, sync, storage, defaultValue]);
|
|
94
94
|
const setValue = useCallback(async (newValue) => {
|
|
95
|
+
writeVersion.current += 1;
|
|
95
96
|
try {
|
|
96
97
|
await storage.set(key, newValue);
|
|
97
98
|
setValueState(newValue);
|
|
@@ -103,6 +104,7 @@ export function useStorageValue(key, options) {
|
|
|
103
104
|
}
|
|
104
105
|
}, [key, storage]);
|
|
105
106
|
const removeValue = useCallback(async () => {
|
|
107
|
+
writeVersion.current += 1;
|
|
106
108
|
try {
|
|
107
109
|
await storage.remove(key);
|
|
108
110
|
setValueState(defaultValue);
|
|
@@ -121,6 +123,92 @@ export function useStorageValue(key, options) {
|
|
|
121
123
|
error,
|
|
122
124
|
};
|
|
123
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Subscribes React state to ONE persisted preference.
|
|
128
|
+
*
|
|
129
|
+
* This is the component-side half of `getPreferenceStore()`: a render-time value
|
|
130
|
+
* is available immediately when the bonded provider can answer synchronously,
|
|
131
|
+
* and an asynchronous provider's hydration CONVERGES onto the same component
|
|
132
|
+
* without a remount. Ordering is the store's: a read that started before a
|
|
133
|
+
* newer write, remove or external change is discarded, so a slow hydration
|
|
134
|
+
* never overwrites an edit the user already made.
|
|
135
|
+
*
|
|
136
|
+
* Pass `null` for `key` while the real key is unknown (no project selected
|
|
137
|
+
* yet): the hook then behaves as local state around `defaultValue` and persists
|
|
138
|
+
* nothing.
|
|
139
|
+
*
|
|
140
|
+
* @param key - The storage key, or `null` when there is nothing to persist.
|
|
141
|
+
* @param options - `defaultValue`, reported until the provider supplies one.
|
|
142
|
+
* @returns The current value, its mutators, and whether it is definite yet.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```tsx
|
|
146
|
+
* const { value: width, setValue: setWidth, ready } = useStoragePreference<number>(key, {
|
|
147
|
+
* defaultValue: 280,
|
|
148
|
+
* })
|
|
149
|
+
* // A drag calls setWidth(320): the UI updates now and the write persists.
|
|
150
|
+
* // `ready` is false until hydration lands, so an effect must not persist the
|
|
151
|
+
* // fallback before then.
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export function useStoragePreference(key, options) {
|
|
155
|
+
const store = getPreferenceStore();
|
|
156
|
+
const defaultValueRef = useRef(options?.defaultValue);
|
|
157
|
+
defaultValueRef.current = options?.defaultValue;
|
|
158
|
+
const read = useCallback(() => {
|
|
159
|
+
if (!key)
|
|
160
|
+
return defaultValueRef.current;
|
|
161
|
+
const stored = store.get(key);
|
|
162
|
+
return stored === null ? defaultValueRef.current : stored;
|
|
163
|
+
}, [store, key]);
|
|
164
|
+
const [value, setValueState] = useState(read);
|
|
165
|
+
const [ready, setReady] = useState(!key);
|
|
166
|
+
const valueRef = useRef(value);
|
|
167
|
+
valueRef.current = value;
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (!key) {
|
|
170
|
+
setReady(true);
|
|
171
|
+
setValueState(defaultValueRef.current);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
let cancelled = false;
|
|
175
|
+
const sync = () => {
|
|
176
|
+
if (!cancelled)
|
|
177
|
+
setValueState(read());
|
|
178
|
+
};
|
|
179
|
+
// Seed from whatever the store already knows, then let hydration converge
|
|
180
|
+
// it. With a synchronous provider this is a no-op change.
|
|
181
|
+
sync();
|
|
182
|
+
setReady(false);
|
|
183
|
+
const stop = store.subscribe(key, sync);
|
|
184
|
+
void store.hydrate([key]).then(() => {
|
|
185
|
+
if (cancelled)
|
|
186
|
+
return;
|
|
187
|
+
sync();
|
|
188
|
+
setReady(true);
|
|
189
|
+
});
|
|
190
|
+
return () => {
|
|
191
|
+
cancelled = true;
|
|
192
|
+
stop();
|
|
193
|
+
};
|
|
194
|
+
}, [store, key, read]);
|
|
195
|
+
const setValue = useCallback((next) => {
|
|
196
|
+
const resolved = typeof next === 'function'
|
|
197
|
+
? next(valueRef.current)
|
|
198
|
+
: next;
|
|
199
|
+
valueRef.current = resolved;
|
|
200
|
+
setValueState(resolved);
|
|
201
|
+
if (key)
|
|
202
|
+
store.set(key, resolved);
|
|
203
|
+
}, [store, key]);
|
|
204
|
+
const removeValue = useCallback(() => {
|
|
205
|
+
valueRef.current = defaultValueRef.current;
|
|
206
|
+
setValueState(defaultValueRef.current);
|
|
207
|
+
if (key)
|
|
208
|
+
store.remove(key);
|
|
209
|
+
}, [store, key]);
|
|
210
|
+
return { value, setValue, removeValue, ready };
|
|
211
|
+
}
|
|
124
212
|
/**
|
|
125
213
|
* Hook for simple storage operations without React state sync.
|
|
126
214
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStorage.js","sourceRoot":"","sources":["../../src/hooks/useStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"useStorage.js","sourceRoot":"","sources":["../../src/hooks/useStorage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "React framework bindings for molecule.dev",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@molecule/app-auth": "^3.0.0",
|
|
27
27
|
"@molecule/app-ai-models": "^1.0.1",
|
|
28
|
-
"@molecule/app-forms": "^
|
|
28
|
+
"@molecule/app-forms": "^2.0.0",
|
|
29
29
|
"@molecule/app-utilities": "^1.0.1",
|
|
30
30
|
"@molecule/app-http": "^1.0.1",
|
|
31
31
|
"@molecule/app-i18n": "^1.0.1",
|