cross-state 0.19.3 → 0.20.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.
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ function hash(value) {
3
+ if (value instanceof Set) {
4
+ return `s[${[...value].map(hash).sort().join(",")}]`;
5
+ }
6
+ if (value instanceof Map) {
7
+ return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
8
+ }
9
+ if (Array.isArray(value)) {
10
+ return `[${value.map(hash).join(",")}]`;
11
+ }
12
+ if (value instanceof Object) {
13
+ return `o[${Object.entries(value).map(hash).sort().join(",")}]`;
14
+ }
15
+ return JSON.stringify(value);
16
+ }
17
+ exports.hash = hash;
18
+ //# sourceMappingURL=hash.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.cjs","sources":["../../src/lib/hash.ts"],"sourcesContent":["export function hash(value: unknown): string {\n if (value instanceof Set) {\n return `s[${[...value].map(hash).sort().join(',')}]`;\n }\n\n if (value instanceof Map) {\n return `m[${[...value.entries()].map(hash).sort().join(',')}]`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(hash).join(',')}]`;\n }\n\n if (value instanceof Object) {\n return `o[${Object.entries(value).map(hash).sort().join(',')}]`;\n }\n\n return JSON.stringify(value);\n}\n"],"names":[],"mappings":";AAAO,SAAS,KAAK,OAAwB;AAC3C,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EACnD;AAEA,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,MAAM,QAAS,CAAA,EAAE,IAAI,IAAI,EAAE,KAAA,EAAO,KAAK,GAAG,CAAC;AAAA,EAC7D;AAEI,MAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,EACtC;AAEA,MAAI,iBAAiB,QAAQ;AAC3B,WAAO,KAAK,OAAO,QAAQ,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9D;AAEO,SAAA,KAAK,UAAU,KAAK;AAC7B;;"}
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const store = require("./store.cjs");
4
- const cache = require("./cache.cjs");
5
- const scope = require("./scope.cjs");
4
+ const scope = require("./scope2.cjs");
6
5
  const urlStore = require("./urlStore.cjs");
6
+ require("./hash.cjs");
7
7
  class SubstriptionCache extends store.Store {
8
8
  constructor(connectFunction, options, derivedFromSubscriptionCache, _call) {
9
9
  super(options.default, options, void 0, _call);
@@ -68,7 +68,7 @@ function create(cacheFunction, ...[options = {}]) {
68
68
  options = Object.assign({}, defaultOptions, options);
69
69
  const { clearUnusedAfter, resourceGroup } = options;
70
70
  let baseInstance;
71
- const instanceCache = new cache.InstanceCache(
71
+ const instanceCache = new scope.InstanceCache(
72
72
  (...args) => {
73
73
  if (args.length === 0 && baseInstance) {
74
74
  return baseInstance;
@@ -107,7 +107,7 @@ function create(cacheFunction, ...[options = {}]) {
107
107
  }
108
108
  );
109
109
  const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
110
- for (const group of groups.concat(cache.allResources)) {
110
+ for (const group of groups.concat(scope.allResources)) {
111
111
  group.add(baseInstance);
112
112
  }
113
113
  get(...[]);
@@ -429,13 +429,13 @@ exports.mapMethods = store.mapMethods;
429
429
  exports.recordMethods = store.recordMethods;
430
430
  exports.set = store.set;
431
431
  exports.setMethods = store.setMethods;
432
- exports.Cache = cache.Cache;
433
- exports.InstanceCache = cache.InstanceCache;
434
- exports.ResourceGroup = cache.ResourceGroup;
435
- exports.allResources = cache.allResources;
436
- exports.createCache = cache.createCache;
437
- exports.createResourceGroup = cache.createResourceGroup;
432
+ exports.Cache = scope.Cache;
433
+ exports.InstanceCache = scope.InstanceCache;
434
+ exports.ResourceGroup = scope.ResourceGroup;
438
435
  exports.Scope = scope.Scope;
436
+ exports.allResources = scope.allResources;
437
+ exports.createCache = scope.createCache;
438
+ exports.createResourceGroup = scope.createResourceGroup;
439
439
  exports.createScope = scope.createScope;
440
440
  exports.connectUrl = urlStore.connectUrl;
441
441
  exports.createUrlStore = urlStore.createUrlStore;
@@ -1,20 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const useCache = require("../useCache.cjs");
3
+ const scope = require("../scope.cjs");
4
4
  const require$$0 = require("react");
5
5
  const store = require("../store.cjs");
6
- const scope = require("../scope.cjs");
6
+ const hash = require("../hash.cjs");
7
7
  const jsxRuntime = require("react/jsx-runtime");
8
8
  const urlStore = require("../urlStore.cjs");
9
- function wildcardMatch(s, w) {
10
- if (typeof s === "string") {
11
- s = store.castArrayPath(s);
12
- }
13
- if (typeof w === "string") {
14
- w = store.castArrayPath(w);
15
- }
16
- return s.length === w.length && s.every((s2, i) => w[i] === "*" || s2 === w[i]);
17
- }
18
9
  function getWildCardMatches(object, path) {
19
10
  const matches = {};
20
11
  const [first, second, ...rest] = store.castArrayPath(path);
@@ -40,8 +31,8 @@ function getWildCardMatches(object, path) {
40
31
  }
41
32
  function FormArray({ name, renderElement, children }) {
42
33
  const form = this.useForm();
43
- const names = this.useFormState((form2) => {
44
- const field = form2.getField(name);
34
+ const names = this.useFormState(() => {
35
+ const field = form.getField(name);
45
36
  return field.names;
46
37
  });
47
38
  const append = require$$0.useCallback(
@@ -80,8 +71,9 @@ function FormArray({ name, renderElement, children }) {
80
71
  ] });
81
72
  }
82
73
  function FormError({ name }) {
83
- const { errors, isDirty } = this.useField(name);
84
- return isDirty ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: errors.join(", ") }) : null;
74
+ const hasTriggeredValidations = this.useFormState((form) => form.hasTriggeredValidations);
75
+ const { errors } = this.useField(name);
76
+ return hasTriggeredValidations ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: errors.join(", ") }) : null;
85
77
  }
86
78
  function FormField({
87
79
  // id,
@@ -96,16 +88,12 @@ function FormField({
96
88
  ...restProps
97
89
  }) {
98
90
  const id = "";
99
- const form = this.useForm();
100
- const state = useCache.useScope(this.state);
91
+ const { options } = this.useForm();
101
92
  const { value, setValue, errors } = this.useField(name);
102
- const errorString = require$$0.useMemo(
103
- () => errors.map((error) => {
104
- var _a, _b;
105
- return ((_b = (_a = form.options).localizeError) == null ? void 0 : _b.call(_a, error, name)) ?? error;
106
- }).join("\n"),
107
- [errors, form.options.localizeError]
108
- );
93
+ const errorString = errors.map((error) => {
94
+ var _a;
95
+ return ((_a = options.localizeError) == null ? void 0 : _a.call(options, error, name)) ?? error;
96
+ }).join("\n");
109
97
  const [localValue, setLocalValue] = require$$0.useState();
110
98
  const _id = require$$0.useMemo(
111
99
  () => `f${Math.random().toString(36).slice(2, 15)}${Math.random().toString(36).slice(2, 15)}`,
@@ -148,15 +136,6 @@ function FormField({
148
136
  }
149
137
  (_a = restProps.onChange) == null ? void 0 : _a.call(restProps, event, ...moreArgs);
150
138
  },
151
- onFocus(...args) {
152
- var _a;
153
- state.set("touched", (touched) => {
154
- touched = new Set(touched);
155
- touched.add(_id);
156
- return touched;
157
- });
158
- (_a = restProps.onFocus) == null ? void 0 : _a.apply(null, args);
159
- },
160
139
  onBlur(...args) {
161
140
  var _a;
162
141
  if (localValue !== void 0) {
@@ -171,11 +150,65 @@ function FormField({
171
150
  }
172
151
  return require$$0.createElement(component, props);
173
152
  }
153
+ function useFormAutosave(form) {
154
+ var _a;
155
+ const { formState, options, getDraft } = form;
156
+ const debounceTime = store.calcDuration(((_a = options.autoSave) == null ? void 0 : _a.debounce) ?? 2e3);
157
+ const latestRef = require$$0.useRef({ options });
158
+ const lastValue = require$$0.useRef();
159
+ const q = require$$0.useMemo(() => store.queue(), []);
160
+ const run = require$$0.useMemo(
161
+ () => store.debounce(async () => {
162
+ var _a2;
163
+ const { options: options2 } = latestRef.current;
164
+ const save = (_a2 = options2.autoSave) == null ? void 0 : _a2.save;
165
+ const draft = getDraft();
166
+ lastValue.current = draft;
167
+ q.clear();
168
+ q(async () => {
169
+ var _a3;
170
+ try {
171
+ formState.set("saveInProgress", true);
172
+ await (save == null ? void 0 : save(draft, form));
173
+ if (q.size === 0 && ((_a3 = options2.autoSave) == null ? void 0 : _a3.resetAfterSave)) {
174
+ form.reset();
175
+ }
176
+ } finally {
177
+ formState.set("saveInProgress", false);
178
+ if (q.size === 0) {
179
+ formState.set("saveScheduled", false);
180
+ }
181
+ }
182
+ });
183
+ }, debounceTime),
184
+ [formState, debounceTime]
185
+ );
186
+ require$$0.useEffect(() => {
187
+ var _a2;
188
+ if (!((_a2 = options.autoSave) == null ? void 0 : _a2.save)) {
189
+ return;
190
+ }
191
+ return formState.map((state) => state.draft).subscribe(
192
+ () => {
193
+ if (store.deepEqual(getDraft(), lastValue.current)) {
194
+ return;
195
+ }
196
+ run();
197
+ formState.set("saveScheduled", true);
198
+ },
199
+ { runNow: false }
200
+ );
201
+ }, [formState]);
202
+ require$$0.useEffect(() => {
203
+ latestRef.current = { options };
204
+ });
205
+ }
174
206
  function FormContainer({
175
207
  form,
176
208
  ...formProps
177
209
  }) {
178
- const _form = form.useForm();
210
+ const { validate, options, getErrors: getErrors2 } = form.useForm();
211
+ const errors = getErrors2();
179
212
  const hasTriggeredValidations = form.useFormState((state) => state.hasTriggeredValidations);
180
213
  return /* @__PURE__ */ jsxRuntime.jsx(
181
214
  "form",
@@ -186,16 +219,16 @@ function FormContainer({
186
219
  onSubmit: (event) => {
187
220
  var _a;
188
221
  event.preventDefault();
189
- const isValid = _form.validate();
222
+ const isValid = validate();
190
223
  let button;
191
224
  if (event.nativeEvent instanceof SubmitEvent && (button = event.nativeEvent.submitter) && (button instanceof HTMLButtonElement || button instanceof HTMLInputElement) && button.setCustomValidity) {
192
- const errors = _form.errors.map(
193
- ({ field, error }) => {
194
- var _a2, _b;
195
- return ((_b = (_a2 = _form.options).localizeError) == null ? void 0 : _b.call(_a2, error, field)) ?? error;
196
- }
197
- );
198
- button.setCustomValidity(errors.join("\n"));
225
+ const errorString = [...errors.entries()].flatMap(
226
+ ([field, errors2]) => errors2.map((error) => {
227
+ var _a2;
228
+ return ((_a2 = options.localizeError) == null ? void 0 : _a2.call(options, error, field)) ?? error;
229
+ })
230
+ ).join("\n");
231
+ button.setCustomValidity(errorString);
199
232
  }
200
233
  event.currentTarget.reportValidity();
201
234
  if (isValid) {
@@ -205,147 +238,92 @@ function FormContainer({
205
238
  }
206
239
  );
207
240
  }
208
- function getFormInstance(original, options, state) {
209
- const instance = {
210
- original,
211
- draft: state.map(
212
- (state2) => state2.draft ?? original ?? options.defaultValue,
213
- (draft) => (state2) => ({ ...state2, draft })
214
- ),
215
- options,
216
- getField: (path) => {
217
- const { draft } = instance;
218
- return {
219
- get originalValue() {
220
- return original !== void 0 ? store.get(original, path) : void 0;
221
- },
222
- get value() {
223
- return store.get(draft.get(), path);
224
- },
225
- setValue(update) {
226
- draft.set(path, update);
227
- },
228
- get isDirty() {
229
- const comparisonValue = this.originalValue ?? store.get(options.defaultValue, path);
230
- return state.get().hasTriggeredValidations || !store.deepEqual(comparisonValue, this.value);
231
- },
232
- get errors() {
233
- const blocks = Object.entries(options.validations ?? {}).filter(([key]) => wildcardMatch(path, key)).map(([, value2]) => value2);
234
- const value = this.value;
235
- const draftValue = draft.get();
236
- const errors = [];
237
- for (const block of blocks ?? []) {
238
- for (const [validationName, validate] of Object.entries(block)) {
239
- if (!validate(value, { draft: draftValue, original, field: path })) {
240
- errors.push(validationName);
241
- }
242
- }
243
- }
244
- return errors;
245
- },
246
- get names() {
247
- const { value } = this;
248
- return Array.isArray(value) ? value.map((_, index) => `${path}.${index}`) : [];
249
- },
250
- append(...elements) {
251
- this.setValue(
252
- (value) => Array.isArray(value) ? [...value, ...elements] : elements
253
- );
254
- },
255
- remove(index) {
256
- this.setValue(
257
- (value) => Array.isArray(value) ? [...value.slice(0, index), ...value.slice(index + 1)] : value
258
- );
259
- }
260
- };
241
+ function getField(derivedState, original, path) {
242
+ return {
243
+ get originalValue() {
244
+ return original !== void 0 ? store.get(original, path) : void 0;
261
245
  },
262
- get hasChanges() {
263
- const { draft } = state.get();
264
- return !!draft && !store.deepEqual(draft, original ?? options.defaultValue);
246
+ get value() {
247
+ const { draft } = derivedState.get();
248
+ return store.get(draft, path);
265
249
  },
266
- get errors() {
267
- const draft = instance.draft.get();
268
- const errors = /* @__PURE__ */ new Set();
269
- for (const [path, block] of Object.entries(options.validations ?? {})) {
270
- for (const [validationName, validate] of Object.entries(
271
- block
272
- )) {
273
- let matched = false;
274
- for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {
275
- matched = true;
276
- if (!validate(value, { draft, original, field })) {
277
- errors.add({ field, error: validationName });
278
- }
279
- }
280
- if (!matched && !path.includes("*")) {
281
- if (!validate(void 0, { draft, original, field: path })) {
282
- errors.add({ field: path, error: validationName });
283
- }
284
- }
285
- }
286
- }
287
- return [...errors];
250
+ setValue(update) {
251
+ derivedState.set(`draft.${path}`, update);
252
+ },
253
+ get hasChange() {
254
+ return !store.deepEqual(this.originalValue, this.value);
288
255
  },
289
- get isValid() {
290
- return instance.errors.length === 0;
256
+ get errors() {
257
+ const { errors } = derivedState.get();
258
+ return errors.get(path) ?? [];
291
259
  },
292
- validate: () => {
293
- state.set("hasTriggeredValidations", true);
294
- return instance.isValid;
260
+ get names() {
261
+ const { value } = this;
262
+ return Array.isArray(value) ? value.map((_, index) => `${path}.${index}`) : [];
295
263
  },
296
- get hasTriggeredValidations() {
297
- return state.get().hasTriggeredValidations;
264
+ append(...elements) {
265
+ this.setValue((value) => Array.isArray(value) ? [...value, ...elements] : elements);
298
266
  },
299
- reset() {
300
- state.set("draft", void 0);
301
- state.set("hasTriggeredValidations", false);
267
+ remove(index) {
268
+ this.setValue(
269
+ (value) => Array.isArray(value) ? [...value.slice(0, index), ...value.slice(index + 1)] : value
270
+ );
302
271
  }
303
272
  };
304
- return instance;
273
+ }
274
+ function getErrors(draft, original, validations) {
275
+ const errors = /* @__PURE__ */ new Map();
276
+ for (const [path, block] of Object.entries(validations ?? {})) {
277
+ for (const [validationName, validate] of Object.entries(
278
+ block
279
+ )) {
280
+ let matched = false;
281
+ for (const [field, value] of Object.entries(getWildCardMatches(draft, path))) {
282
+ matched = true;
283
+ if (!validate(value, { draft, original, field })) {
284
+ const fieldErrors = errors.get(field) ?? [];
285
+ fieldErrors.push(validationName);
286
+ errors.set(field, fieldErrors);
287
+ }
288
+ }
289
+ if (!matched && !path.includes("*")) {
290
+ if (!validate(void 0, { draft, original, field: path })) {
291
+ const fieldErrors = errors.get(path) ?? [];
292
+ fieldErrors.push(validationName);
293
+ errors.set(path, fieldErrors);
294
+ }
295
+ }
296
+ }
297
+ }
298
+ return errors;
305
299
  }
306
300
  class Form {
307
301
  constructor(options) {
308
302
  this.options = options;
309
- this.context = require$$0.createContext({
310
- original: void 0,
311
- options: this.options
312
- });
313
- this.state = new scope.Scope({
314
- touched: /* @__PURE__ */ new Set(),
315
- errors: /* @__PURE__ */ new Map()
316
- });
303
+ this.context = require$$0.createContext(null);
317
304
  store.autobind(Form);
318
305
  }
319
306
  useForm() {
320
- const { original, options } = require$$0.useContext(this.context);
321
- const state = useCache.useScope(this.state);
322
- return require$$0.useMemo(() => getFormInstance(original, options, state), [original, options, state]);
323
- }
324
- useFormState(selector) {
325
- const { original, options } = require$$0.useContext(this.context);
326
- const state = useCache.useScope(this.state);
327
- return useCache.useStore(state.map(() => selector(getFormInstance(original, options, state))));
307
+ const context = require$$0.useContext(this.context);
308
+ if (!context) {
309
+ throw new Error("Form context not found");
310
+ }
311
+ return context;
328
312
  }
329
- useField(path, useStoreOptions) {
313
+ useFormState(selector, useStoreOptions) {
330
314
  const form = this.useForm();
331
- const state = useCache.useScope(this.state);
332
- useCache.useStore(
333
- form.draft.map((draft) => store.get(draft, path)),
334
- useStoreOptions
335
- );
336
- useCache.useStore(
337
- state.map((state2) => state2.hasTriggeredValidations),
315
+ return scope.useStore(
316
+ form.derivedState.map(
317
+ (state) => selector({
318
+ ...form,
319
+ ...state
320
+ })
321
+ ),
338
322
  useStoreOptions
339
323
  );
340
- return form.getField(path);
341
324
  }
342
- useHasChanges() {
343
- const form = this.useForm();
344
- return useCache.useStore(form.draft.map(() => form.hasChanges));
345
- }
346
- useIsValid() {
347
- const form = this.useForm();
348
- return useCache.useStore(form.draft.map(() => form.isValid));
325
+ useField(path, useStoreOptions) {
326
+ return this.useFormState((form) => form.getField(path), useStoreOptions);
349
327
  }
350
328
  // ///////////////////////////////////////////////////////////////////////////
351
329
  // React Components
@@ -356,34 +334,117 @@ class Form {
356
334
  validations,
357
335
  localizeError,
358
336
  urlState,
337
+ autoSave,
338
+ transform,
359
339
  ...formProps
360
340
  }) {
361
- const value = require$$0.useMemo(
362
- () => ({
341
+ const options = {
342
+ defaultValue: { ...this.options.defaultValue, ...defaultValue },
343
+ validations: { ...this.options.validations, ...validations },
344
+ localizeError: localizeError ?? this.options.localizeError,
345
+ autoSave: autoSave ?? this.options.autoSave,
346
+ transform: transform ?? this.options.transform
347
+ };
348
+ const formState = require$$0.useMemo(() => {
349
+ return store.createStore({
350
+ draft: void 0,
351
+ hasTriggeredValidations: false,
352
+ saveScheduled: false,
353
+ saveInProgress: false
354
+ });
355
+ }, []);
356
+ const derivedState = require$$0.useMemo(() => {
357
+ return formState.map(
358
+ (state) => {
359
+ const {
360
+ draft = original ?? options.defaultValue,
361
+ hasTriggeredValidations,
362
+ saveScheduled,
363
+ saveInProgress
364
+ } = state;
365
+ const errors = getErrors(draft, original, options.validations);
366
+ return {
367
+ draft,
368
+ hasTriggeredValidations,
369
+ saveScheduled,
370
+ saveInProgress,
371
+ hasChanges: !!draft && !store.deepEqual(draft, original),
372
+ errors,
373
+ isValid: errors.size === 0
374
+ };
375
+ },
376
+ (newState) => ({
377
+ draft: newState.draft,
378
+ hasTriggeredValidations: newState.hasTriggeredValidations,
379
+ saveScheduled: newState.saveScheduled,
380
+ saveInProgress: newState.saveInProgress
381
+ })
382
+ );
383
+ }, [formState, original, options.validations, options.defaultValue]);
384
+ const context = require$$0.useMemo(() => {
385
+ return {
386
+ formState,
387
+ derivedState,
388
+ options,
363
389
  original,
364
- options: {
365
- defaultValue: { ...this.options.defaultValue, ...defaultValue },
366
- validations: { ...this.options.validations, ...validations },
367
- localizeError: localizeError ?? this.options.localizeError
390
+ getField(path) {
391
+ return getField(derivedState, original, path);
392
+ },
393
+ getDraft() {
394
+ return formState.get().draft ?? original ?? options.defaultValue;
395
+ },
396
+ hasTriggeredValidations() {
397
+ return formState.get().hasTriggeredValidations;
398
+ },
399
+ hasChanges() {
400
+ return derivedState.get().hasChanges;
401
+ },
402
+ getErrors() {
403
+ return derivedState.get().errors;
404
+ },
405
+ isValid() {
406
+ return derivedState.get().isValid;
407
+ },
408
+ validate() {
409
+ formState.set("hasTriggeredValidations", true);
410
+ return derivedState.get().isValid;
411
+ },
412
+ reset() {
413
+ formState.set("draft", void 0);
414
+ formState.set("hasTriggeredValidations", false);
368
415
  }
369
- }),
370
- [original, defaultValue, validations]
371
- );
372
- const store$1 = require$$0.useMemo(() => {
373
- return store.createStore(this.state.defaultValue);
374
- }, []);
416
+ };
417
+ }, [formState, derivedState, original, defaultValue, validations, localizeError, urlState]);
375
418
  require$$0.useEffect(() => {
376
419
  if (urlState) {
377
420
  return urlStore.connectUrl(
378
- store$1.map("draft"),
421
+ formState.map("draft"),
379
422
  typeof urlState === "object" ? urlState : { key: "form" }
380
423
  );
381
424
  }
382
425
  return void 0;
383
- }, [store$1, scope.hash(urlState)]);
384
- return /* @__PURE__ */ jsxRuntime.jsx(this.context.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsx(useCache.ScopeProvider, { scope: this.state, store: store$1, children: /* @__PURE__ */ jsxRuntime.jsx(FormContainer, { ...formProps, form: this }) }) });
426
+ }, [formState, hash.hash(urlState)]);
427
+ require$$0.useEffect(() => {
428
+ var _a;
429
+ const handles = (_a = options.transform) == null ? void 0 : _a.map(({ trigger, update }) => {
430
+ const draft = derivedState.map("draft");
431
+ const triggerStore = trigger ? draft.map(trigger) : draft;
432
+ return triggerStore.subscribe(() => {
433
+ const value = trigger ? store.get(draft.get(), trigger) : draft.get();
434
+ const result = update(value, draft);
435
+ if (result !== void 0) {
436
+ draft.set(result);
437
+ }
438
+ });
439
+ });
440
+ return () => {
441
+ handles == null ? void 0 : handles.forEach((handle) => handle());
442
+ };
443
+ }, [options.transform]);
444
+ useFormAutosave(context);
445
+ return /* @__PURE__ */ jsxRuntime.jsx(this.context.Provider, { value: context, children: /* @__PURE__ */ jsxRuntime.jsx(FormContainer, { ...formProps, form: this }) });
385
446
  }
386
- Subscribe({
447
+ FormState({
387
448
  selector,
388
449
  children
389
450
  }) {
@@ -404,7 +465,7 @@ function createForm(options) {
404
465
  return new Form(options);
405
466
  }
406
467
  function read(cache, options) {
407
- const { status, value, error } = useCache.useCache(cache, options);
468
+ const { status, value, error } = scope.useCache(cache, options);
408
469
  if (status === "value") {
409
470
  return value;
410
471
  }
@@ -438,7 +499,7 @@ function useDecoupledState(value, onChange, options = {}) {
438
499
  setDirty({ v: value2 });
439
500
  delayedUpdate(value2);
440
501
  };
441
- }, [scope.hash([options.debounce, options.throttle])]);
502
+ }, [hash.hash([options.debounce, options.throttle])]);
442
503
  return [dirty ? dirty.v : value, update];
443
504
  }
444
505
  function castArray(value) {
@@ -458,15 +519,15 @@ function useUrlParamScope({
458
519
  url[type] = parameters.toString();
459
520
  window.history.replaceState(null, "", url.toString());
460
521
  },
461
- [scope.hash(key), type]
522
+ [hash.hash(key), type]
462
523
  );
463
524
  }
464
- exports.ScopeProvider = useCache.ScopeProvider;
465
- exports.reactMethods = useCache.reactMethods;
466
- exports.useCache = useCache.useCache;
467
- exports.useProp = useCache.useProp;
468
- exports.useScope = useCache.useScope;
469
- exports.useStore = useCache.useStore;
525
+ exports.ScopeProvider = scope.ScopeProvider;
526
+ exports.reactMethods = scope.reactMethods;
527
+ exports.useCache = scope.useCache;
528
+ exports.useProp = scope.useProp;
529
+ exports.useScope = scope.useScope;
530
+ exports.useStore = scope.useStore;
470
531
  exports.Form = Form;
471
532
  exports.createForm = createForm;
472
533
  exports.read = read;