attaform 0.28.0 → 0.29.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.
Files changed (64) hide show
  1. package/dist/abstract.d.mts +5 -5
  2. package/dist/abstract.mjs +4 -4
  3. package/dist/chunks/fingerprint.mjs +1 -1
  4. package/dist/chunks/fingerprint2.mjs +2 -2
  5. package/dist/dev/abstract.mjs +4 -4
  6. package/dist/dev/chunks/devtools.mjs +1 -1
  7. package/dist/dev/chunks/fingerprint.mjs +1 -1
  8. package/dist/dev/chunks/fingerprint2.mjs +2 -2
  9. package/dist/dev/directive.mjs +1 -1
  10. package/dist/dev/history.mjs +1 -1
  11. package/dist/dev/index.mjs +5 -5
  12. package/dist/dev/runtime/plugins/attaform.mjs +1 -1
  13. package/dist/dev/shared/{attaform-dev.Dr2YzS5B.mjs → attaform-dev.A-TpJW0B.mjs} +11 -1
  14. package/dist/dev/shared/{attaform-dev.oYrkP9dj.mjs → attaform-dev.BO-71R54.mjs} +51 -158
  15. package/dist/dev/shared/{attaform-dev.6qxD-Yqo.mjs → attaform-dev.BgM6FdtA.mjs} +143 -36
  16. package/dist/{shared/attaform.h0i6LijT.mjs → dev/shared/attaform-dev.ButTkwHd.mjs} +149 -16
  17. package/dist/{shared/attaform.BJGA_UOS.mjs → dev/shared/attaform-dev.BxfsuwBR.mjs} +8 -0
  18. package/dist/dev/shared/{attaform-dev.P7cseiEG.mjs → attaform-dev.D8aoKb89.mjs} +13 -4
  19. package/dist/dev/shared/{attaform-dev.BXE2cr0L.mjs → attaform-dev.DD5m2W51.mjs} +1 -1
  20. package/dist/dev/shared/{attaform-dev.WmuhD_CZ.mjs → attaform-dev.DHuydLAC.mjs} +344 -96
  21. package/dist/dev/shared/{attaform-dev.BR8u0YOZ.mjs → attaform-dev.DrzObAZo.mjs} +4 -4
  22. package/dist/dev/shared/{attaform-dev.D2I8e_Mm.mjs → attaform-dev.q6UutkCx.mjs} +170 -132
  23. package/dist/dev/zod-v3.mjs +6 -6
  24. package/dist/dev/zod-v4.mjs +6 -6
  25. package/dist/dev/zod.mjs +5 -5
  26. package/dist/directive.d.mts +2 -2
  27. package/dist/directive.mjs +1 -1
  28. package/dist/history.d.mts +1 -1
  29. package/dist/history.mjs +1 -1
  30. package/dist/index.d.mts +9 -7
  31. package/dist/index.mjs +5 -5
  32. package/dist/nuxt.d.mts +10 -10
  33. package/dist/runtime/plugins/attaform.mjs +1 -1
  34. package/dist/shared/{attaform.C09fpdLS.mjs → attaform.B0dKL8ST.mjs} +143 -36
  35. package/dist/shared/{attaform.Cs2Rbdlo.mjs → attaform.BK0cgu2K.mjs} +123 -139
  36. package/dist/shared/{attaform.D6DCnnQu.mjs → attaform.BndjUUYX.mjs} +4 -4
  37. package/dist/{dev/shared/attaform-dev.BJGA_UOS.mjs → shared/attaform.BxfsuwBR.mjs} +8 -0
  38. package/dist/shared/{attaform.NLmerepI.mjs → attaform.C2MVyuxC.mjs} +42 -151
  39. package/dist/shared/{attaform.B4VkS43-.d.mts → attaform.CIWLMY-R.d.mts} +1 -1
  40. package/dist/shared/{attaform.B8k8JrmK.mjs → attaform.CZMAYwSK.mjs} +338 -95
  41. package/dist/shared/{attaform.wfY8XFvm.mjs → attaform.CZYt_5N_.mjs} +11 -1
  42. package/dist/shared/{attaform.Cgu-hdSb.d.mts → attaform.CsoeRi3P.d.mts} +224 -32
  43. package/dist/{dev/shared/attaform-dev.By4PRjt0.mjs → shared/attaform.Cvao8bW5.mjs} +132 -22
  44. package/dist/shared/{attaform.Dq4vWxuG.mjs → attaform.D0x-qSXm.mjs} +1 -1
  45. package/dist/shared/{attaform.CJP3RkGa.mjs → attaform.D1fnTifF.mjs} +168 -132
  46. package/dist/shared/{attaform.D5V4tZWq.d.mts → attaform.DDtqHYv1.d.mts} +88 -7
  47. package/dist/shared/{attaform.uLbun31C.mjs → attaform.DffRL5pP.mjs} +12 -4
  48. package/dist/shared/{attaform.JfSWdEcb.d.mts → attaform.axHXVQO7.d.mts} +1 -1
  49. package/dist/transforms.d.mts +0 -22
  50. package/dist/transforms.mjs +1 -1
  51. package/dist/vite.d.mts +13 -4
  52. package/dist/vite.mjs +3 -2
  53. package/dist/zod-v3.d.mts +6 -4
  54. package/dist/zod-v3.mjs +6 -6
  55. package/dist/zod-v4.d.mts +14 -27
  56. package/dist/zod-v4.mjs +6 -6
  57. package/dist/zod.d.mts +4 -4
  58. package/dist/zod.mjs +5 -5
  59. package/package.json +17 -14
  60. package/skills/attaform/SKILL.md +5 -2
  61. package/skills/attaform/references/custom-components.md +7 -2
  62. package/skills/attaform/references/errors.md +8 -3
  63. package/skills/attaform/references/saving.md +77 -0
  64. package/skills/attaform/references/wizards.md +10 -8
@@ -1,9 +1,9 @@
1
1
  import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, reactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
2
- import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.Dq4vWxuG.mjs';
3
- import { c as armDomBinding } from './attaform.uLbun31C.mjs';
2
+ import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.D0x-qSXm.mjs';
3
+ import { c as armDomBinding } from './attaform.DffRL5pP.mjs';
4
4
  import { R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.KvlEedlF.mjs';
5
- import { A as ANONYMOUS_FORM_KEY_PREFIX, i as isShadowedKey, c as safeOwnHas, a as safeOwnRead, b as safeAssign, d as diffAndApply, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, e as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, f as applyChangedKeys, R as RESERVED_KEY_PREFIX, g as DEFAULT_MAX_RECURSION_DEPTH, h as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform.h0i6LijT.mjs';
6
- import { i as isPathPrefix, e as canonicalizePath, h as cellEntriesFor, s as segmentsForPathKey, k as keyForSegments, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, j as groupErrorsByKey, n as normalizeErrorInput, R as ROOT_PATH, l as normalizeErrorInputs, m as coerceToPathKey, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform.wfY8XFvm.mjs';
5
+ import { A as ANONYMOUS_FORM_KEY_PREFIX, d as consumerHas, i as isShadowedKey, e as safeOwnHas, a as safeOwnRead, f as spreadConsumerRecord, g as copyConsumerArray, r as readConsumerIndex, b as safeAssign, h as consumerKeys, j as readConsumerProp, k as diffAndApply, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, l as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, m as consumerSymbolKeys, o as applyChangedKeys, R as RESERVED_KEY_PREFIX, q as DEFAULT_MAX_RECURSION_DEPTH, t as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform.Cvao8bW5.mjs';
6
+ import { i as isPathPrefix, e as canonicalizePath, j as cellEntriesFor, s as segmentsForPathKey, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, l as groupErrorsByKey, n as normalizeErrorInput, h as SET_MEMBER_SEGMENT, R as ROOT_PATH, o as normalizeErrorInputs, q as coerceToPathKey, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform.CZYt_5N_.mjs';
7
7
 
8
8
  const AttaformErrorCode = {
9
9
  /** A required field is in the blank set — user hasn't supplied a value. */
@@ -78,6 +78,11 @@ function makeBlankRequiredError(segments) {
78
78
  }
79
79
  const NO_ERRORS = Object.freeze([]);
80
80
 
81
+ function crossCopyState(key, create) {
82
+ const carrier = globalThis;
83
+ return carrier[key] ?? (carrier[key] = create());
84
+ }
85
+
81
86
  function isGateOpen(field, formMeta) {
82
87
  return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
83
88
  }
@@ -100,7 +105,10 @@ function earliestNonNull(a, b) {
100
105
  }
101
106
  const DEFAULT_TIMINGS = { showDelay: 120, minVisible: 120 };
102
107
  const FOCUS_OUT_GRACE = 16;
103
- const defaultFamily = /* @__PURE__ */ new WeakSet();
108
+ const defaultFamily = crossCopyState(
109
+ /* @__PURE__ */ Symbol.for("attaform:default-display-state-family"),
110
+ () => /* @__PURE__ */ new WeakSet()
111
+ );
104
112
  function isDefaultDisplayState(fn) {
105
113
  return defaultFamily.has(fn);
106
114
  }
@@ -187,6 +195,17 @@ function humanize(segment) {
187
195
  }
188
196
 
189
197
  const NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
198
+ function mapKeyForSegment(map, segment, declared) {
199
+ if (map.has(segment)) return segment;
200
+ if (typeof segment !== "number") return segment;
201
+ const asString = String(segment);
202
+ if (map.has(asString)) return asString;
203
+ return declared === "string" ? asString : segment;
204
+ }
205
+ function isRebuildableContainer(root, segment) {
206
+ if (root === null || root === void 0 || typeof root !== "object") return true;
207
+ return typeof segment === "number" ? Array.isArray(root) : isPlainRecord(root);
208
+ }
190
209
  function descendStep(value, segment) {
191
210
  if (value === null || value === void 0) return NOT_FOUND;
192
211
  if (typeof value !== "object") return NOT_FOUND;
@@ -195,6 +214,11 @@ function descendStep(value, segment) {
195
214
  if (!(segment in value)) return NOT_FOUND;
196
215
  return value[segment];
197
216
  }
217
+ if (value instanceof Map) {
218
+ const key2 = mapKeyForSegment(value, segment);
219
+ if (!value.has(key2)) return NOT_FOUND;
220
+ return value.get(key2);
221
+ }
198
222
  const record = value;
199
223
  const key = typeof segment === "number" ? String(segment) : segment;
200
224
  if (isShadowedKey(key)) {
@@ -227,11 +251,14 @@ function hasAtPath(root, path) {
227
251
  if (current === null || current === void 0) return false;
228
252
  if (typeof current !== "object") return false;
229
253
  if (Array.isArray(current)) {
230
- return typeof last === "number" && last in current;
254
+ return typeof last === "number" && consumerHas(current, last);
255
+ }
256
+ if (current instanceof Map) {
257
+ return current.has(mapKeyForSegment(current, last));
231
258
  }
232
259
  const key = typeof last === "number" ? String(last) : last;
233
260
  if (isShadowedKey(key)) return safeOwnHas(current, key);
234
- return key in current;
261
+ return consumerHas(current, key);
235
262
  }
236
263
  function isPlainRecord(value) {
237
264
  if (value === null || typeof value !== "object") return false;
@@ -246,6 +273,13 @@ function setAtPathOffset(root, path, value, offset) {
246
273
  if (offset >= path.length) return value;
247
274
  const head = path[offset];
248
275
  const nextOffset = offset + 1;
276
+ if (root instanceof Map) {
277
+ const next = new Map(root);
278
+ const key = mapKeyForSegment(root, head);
279
+ next.set(key, setAtPathOffset(root.get(key), path, value, nextOffset));
280
+ return next;
281
+ }
282
+ if (!isRebuildableContainer(root, head)) return root;
249
283
  if (typeof head === "number") {
250
284
  const arr = Array.isArray(root) ? [...root] : [];
251
285
  while (arr.length <= head) arr.push(void 0);
@@ -259,9 +293,17 @@ function setAtPathOffset(root, path, value, offset) {
259
293
  const NO_IN_PLACE = { applied: false };
260
294
  function tryInPlaceLeafWrite(root, path, value) {
261
295
  if (path.length === 0) return NO_IN_PLACE;
296
+ try {
297
+ return descendAndWrite(root, path, value);
298
+ } catch {
299
+ return NO_IN_PLACE;
300
+ }
301
+ }
302
+ function descendAndWrite(root, path, value) {
262
303
  let node = root;
263
304
  for (let i = 0; i < path.length; i++) {
264
305
  const seg = path[i];
306
+ if (node instanceof Map) return NO_IN_PLACE;
265
307
  if (Array.isArray(node)) {
266
308
  if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
267
309
  } else if (isPlainRecord(node)) {
@@ -296,17 +338,40 @@ function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
296
338
  if (Array.isArray(consumer)) {
297
339
  return mergeStructuralArray(schema, scratch, consumer);
298
340
  }
341
+ if (consumer instanceof Map) {
342
+ return mergeStructuralMap(schema, scratch, consumer);
343
+ }
299
344
  if (isPlainRecord(consumer)) {
300
345
  if (!isPlainRecord(defaultValue)) {
301
346
  return consumer;
302
347
  }
303
- const out = { ...consumer };
348
+ const out = spreadConsumerRecord(consumer);
304
349
  const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
305
350
  const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
306
351
  return filledAny || recursedAny ? out : consumer;
307
352
  }
308
353
  return consumer;
309
354
  }
355
+ function mergeStructuralMap(schema, scratch, consumer) {
356
+ if (consumer.size === 0) return consumer;
357
+ let entryDefault;
358
+ let entryDefaultRead = false;
359
+ let out = null;
360
+ for (const [key, entry] of consumer) {
361
+ if (typeof key !== "string" && typeof key !== "number") continue;
362
+ scratch.push(key);
363
+ if (!entryDefaultRead) {
364
+ entryDefault = schema.getDefaultAtPath(scratch);
365
+ entryDefaultRead = true;
366
+ }
367
+ const merged = mergeStructuralImpl(schema, scratch, entry, entryDefault);
368
+ scratch.pop();
369
+ if (merged === entry) continue;
370
+ out ?? (out = new Map(consumer));
371
+ out.set(key, merged);
372
+ }
373
+ return out ?? consumer;
374
+ }
310
375
  function mergeStructuralArray(schema, scratch, consumer) {
311
376
  const shape = schema.arrayShapeAtPath(scratch);
312
377
  const isTuple = typeof shape === "number";
@@ -314,7 +379,7 @@ function mergeStructuralArray(schema, scratch, consumer) {
314
379
  let cachedElementDefault;
315
380
  let cachedElementDefaultRead = false;
316
381
  let mutated = targetLen > consumer.length;
317
- const out = consumer.slice();
382
+ const out = copyConsumerArray(consumer);
318
383
  while (out.length < targetLen) out.push(void 0);
319
384
  for (let i = 0; i < targetLen; i++) {
320
385
  scratch.push(i);
@@ -328,7 +393,7 @@ function mergeStructuralArray(schema, scratch, consumer) {
328
393
  }
329
394
  elemDefault = cachedElementDefault;
330
395
  }
331
- const consumerElem = i < consumer.length ? consumer[i] : void 0;
396
+ const consumerElem = i < consumer.length ? readConsumerIndex(consumer, i) : void 0;
332
397
  const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
333
398
  scratch.pop();
334
399
  if (merged !== consumerElem) {
@@ -356,7 +421,7 @@ function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out
356
421
  }
357
422
  function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
358
423
  let mutated = false;
359
- for (const key of Object.keys(consumer)) {
424
+ for (const key of consumerKeys(consumer)) {
360
425
  const cVal = safeOwnRead(consumer, key);
361
426
  if (cVal === void 0) continue;
362
427
  scratch.push(key);
@@ -377,6 +442,21 @@ function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
377
442
  if (startIdx >= fullPath.length) return value;
378
443
  const head = fullPath[startIdx];
379
444
  const isLeafStep = startIdx === fullPath.length - 1;
445
+ if (root instanceof Map) {
446
+ const next = new Map(root);
447
+ const key = mapKeyForSegment(root, head, schema.entryKeyKindAtPath(fullPath.slice(0, startIdx)));
448
+ if (isLeafStep) {
449
+ next.set(key, value);
450
+ return next;
451
+ }
452
+ let childRoot2 = next.get(key);
453
+ if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
454
+ childRoot2 = schema.getDefaultAtPath(fullPath.slice(0, startIdx + 1));
455
+ }
456
+ next.set(key, setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1));
457
+ return next;
458
+ }
459
+ if (!isRebuildableContainer(root, head)) return root;
380
460
  if (typeof head === "number") {
381
461
  const arr = Array.isArray(root) ? [...root] : [];
382
462
  const prefix = fullPath.slice(0, startIdx);
@@ -443,9 +523,10 @@ function isUnderStubAncestor(state, segments) {
443
523
  }
444
524
  return false;
445
525
  }
446
- function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options) {
526
+ function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, sweep, options) {
447
527
  const cache = /* @__PURE__ */ new Map();
448
528
  const predicate = options?.getDisplayState;
529
+ sweep.onEvict((key) => cache.delete(key));
449
530
  return function getFieldState(pathInput) {
450
531
  const { segments, key } = canonicalizePath(pathInput);
451
532
  const cached = cache.get(key);
@@ -454,6 +535,7 @@ function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options
454
535
  () => state.schema.isLeafAtPath(segments) ? buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase, predicate) : buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase, predicate)
455
536
  );
456
537
  cache.set(key, c);
538
+ sweep.track(segments, key);
457
539
  return c;
458
540
  };
459
541
  }
@@ -543,7 +625,7 @@ function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBa
543
625
  function visitActiveLeafPaths(value, base, visit) {
544
626
  if (Array.isArray(value)) {
545
627
  for (let i = 0; i < value.length; i++) {
546
- const child = value[i];
628
+ const child = readConsumerIndex(value, i);
547
629
  if (Array.isArray(child) || isPlainRecord(child)) {
548
630
  visitActiveLeafPaths(child, [...base, i], visit);
549
631
  } else {
@@ -553,8 +635,8 @@ function visitActiveLeafPaths(value, base, visit) {
553
635
  return;
554
636
  }
555
637
  if (isPlainRecord(value)) {
556
- for (const k of Object.keys(value)) {
557
- const child = value[k];
638
+ for (const k of consumerKeys(value)) {
639
+ const child = readConsumerProp(value, k);
558
640
  if (Array.isArray(child) || isPlainRecord(child)) {
559
641
  visitActiveLeafPaths(child, [...base, k], visit);
560
642
  } else {
@@ -796,6 +878,10 @@ function liveKeysAtPath(state, segments) {
796
878
  for (let i = 0; i < value.length; i += 1) keys[i] = String(i);
797
879
  return keys;
798
880
  }
881
+ if (value instanceof Map) {
882
+ return mapSegmentKeys(value)?.map(String) ?? [];
883
+ }
884
+ if (value instanceof Set) return [];
799
885
  if (typeof value === "object") return Object.keys(value);
800
886
  return [];
801
887
  }
@@ -806,6 +892,12 @@ function liveContainerHasKey(state, segments, key) {
806
892
  const index = Number(key);
807
893
  return Number.isInteger(index) && index >= 0 && index < value.length && String(index) === key;
808
894
  }
895
+ if (value instanceof Map) {
896
+ if (value.has(key)) return true;
897
+ const index = Number(key);
898
+ return Number.isInteger(index) && index >= 0 && String(index) === key && value.has(index);
899
+ }
900
+ if (value instanceof Set) return false;
809
901
  return Object.hasOwn(value, key);
810
902
  }
811
903
  function isArrayPath(state, segments) {
@@ -829,6 +921,7 @@ function makeReadonlyCoercion(snapshot) {
829
921
  }
830
922
 
831
923
  const INTEGER_SEGMENT = /^(?:0|[1-9]\d*)$/;
924
+ const RELEASED = /* @__PURE__ */ Symbol();
832
925
  const EMPTY_DESCENT = Object.freeze({});
833
926
  function keyToSegment(key) {
834
927
  return INTEGER_SEGMENT.test(key) ? Number(key) : key;
@@ -858,12 +951,18 @@ function callableInvokeShim(method, surface, getDescent) {
858
951
  function buildTree(spec) {
859
952
  const containerCache = /* @__PURE__ */ new Map();
860
953
  const existsCache = /* @__PURE__ */ new Map();
954
+ spec.sweep.onEvict((key) => {
955
+ containerCache.delete(`${key}+A`);
956
+ containerCache.delete(`${key}+O`);
957
+ existsCache.delete(key);
958
+ });
861
959
  function schemaHasPath(segs) {
862
960
  const cacheKey = JSON.stringify(segs);
863
961
  const cached = existsCache.get(cacheKey);
864
962
  if (cached !== void 0) return cached;
865
963
  const result = spec.schema.getSlimPrimitiveTypesAtPath(segs).size > 0;
866
964
  existsCache.set(cacheKey, result);
965
+ spec.sweep.track(segs, cacheKey);
867
966
  return result;
868
967
  }
869
968
  function descend(segs) {
@@ -873,7 +972,8 @@ function buildTree(spec) {
873
972
  }
874
973
  function containerAt(segments) {
875
974
  const isArrayLike = spec.isArrayAt(segments);
876
- const cacheKey = `${JSON.stringify(segments)}+${isArrayLike ? "A" : "O"}`;
975
+ const pathKey = JSON.stringify(segments);
976
+ const cacheKey = `${pathKey}+${isArrayLike ? "A" : "O"}`;
877
977
  const existing = containerCache.get(cacheKey);
878
978
  if (existing !== void 0) return existing;
879
979
  const isFixedObject = spec.schema.isFixedObjectAtPath(segments);
@@ -963,12 +1063,14 @@ function buildTree(spec) {
963
1063
  }
964
1064
  });
965
1065
  containerCache.set(cacheKey, proxy);
1066
+ spec.sweep.track(segments, pathKey);
966
1067
  return proxy;
967
1068
  }
968
1069
  return containerAt([]);
969
1070
  }
970
- function buildErrorsSurface(state) {
1071
+ function buildErrorsSurface(state, sweep) {
971
1072
  const treeCache = /* @__PURE__ */ new Map();
1073
+ sweep.onEvict((key) => treeCache.delete(key));
972
1074
  const materialize = (segments) => {
973
1075
  const cacheKey = JSON.stringify(segments);
974
1076
  let tree = treeCache.get(cacheKey);
@@ -976,6 +1078,7 @@ function buildErrorsSurface(state) {
976
1078
  const frozen = [...segments];
977
1079
  tree = computed(() => materializeErrors(state, frozen));
978
1080
  treeCache.set(cacheKey, tree);
1081
+ sweep.track(segments, cacheKey);
979
1082
  }
980
1083
  return tree.value;
981
1084
  };
@@ -1021,7 +1124,8 @@ function buildErrorsSurface(state) {
1021
1124
  // aggregate — the same helper `meta.errors` reads, so the surfaces
1022
1125
  // never drift.
1023
1126
  call: (path) => aggregateErrorsAt(state, path),
1024
- surface: "form.errors"
1127
+ surface: "form.errors",
1128
+ sweep
1025
1129
  });
1026
1130
  }
1027
1131
  function errorAwareContainerKeys(state, segments) {
@@ -1140,7 +1244,7 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
1140
1244
  "placeholder",
1141
1245
  "meta"
1142
1246
  ]);
1143
- function buildFieldsSurface(state, getFieldStateAt) {
1247
+ function buildFieldsSurface(state, getFieldStateAt, sweep) {
1144
1248
  const snapshotAt = (segments) => {
1145
1249
  const view = getFieldStateAt(segments).value;
1146
1250
  const snapshot = {};
@@ -1148,6 +1252,7 @@ function buildFieldsSurface(state, getFieldStateAt) {
1148
1252
  return snapshot;
1149
1253
  };
1150
1254
  const viewCache = /* @__PURE__ */ new Map();
1255
+ sweep.onEvict((key) => viewCache.delete(key));
1151
1256
  function viewAt(segments) {
1152
1257
  const cacheKey = JSON.stringify(segments);
1153
1258
  const existing = viewCache.get(cacheKey);
@@ -1199,6 +1304,7 @@ function buildFieldsSurface(state, getFieldStateAt) {
1199
1304
  }
1200
1305
  });
1201
1306
  viewCache.set(cacheKey, proxy);
1307
+ sweep.track(segments, cacheKey);
1202
1308
  return proxy;
1203
1309
  }
1204
1310
  return buildTree({
@@ -1213,7 +1319,8 @@ function buildFieldsSurface(state, getFieldStateAt) {
1213
1319
  // container's rollup); a path the schema doesn't have is a typo and
1214
1320
  // reads `undefined`. The root (`fields()`) is always declared.
1215
1321
  call: (path) => state.schema.getSlimPrimitiveTypesAtPath(path).size > 0 ? viewAt(path) : void 0,
1216
- surface: "form.fields"
1322
+ surface: "form.fields",
1323
+ sweep
1217
1324
  });
1218
1325
  }
1219
1326
  function materializeFields(state, containerSegments, snapshotAt) {
@@ -1247,18 +1354,34 @@ function materializeFormValue(node) {
1247
1354
  }
1248
1355
  return out;
1249
1356
  }
1250
- function buildValuesSurface(form) {
1357
+ function buildValuesSurface(form, onFormChange) {
1251
1358
  const inner = computed(() => readonly(form.value));
1252
- const { toString, valueOf, toJSON, toPrimitive } = makeReadonlyCoercion(
1253
- () => materializeFormValue(inner.value)
1254
- );
1359
+ let held = null;
1360
+ const snapshot = computed(() => {
1361
+ const box = { value: materializeFormValue(inner.value) };
1362
+ held = box;
1363
+ return box;
1364
+ });
1365
+ onFormChange(() => {
1366
+ if (held === null) return;
1367
+ held.value = RELEASED;
1368
+ held = null;
1369
+ });
1370
+ const readSnapshot = () => {
1371
+ const box = snapshot.value;
1372
+ return box.value === RELEASED ? materializeFormValue(inner.value) : box.value;
1373
+ };
1374
+ const { toString, valueOf, toJSON, toPrimitive } = makeReadonlyCoercion(() => readSnapshot());
1255
1375
  const target = (() => {
1256
1376
  });
1257
1377
  return new Proxy(target, {
1258
1378
  apply(_, __, args) {
1259
1379
  const arg = args[0];
1260
- if (arg === void 0) return inner.value;
1261
- return getAtPath(inner.value, canonicalizePath(arg).segments);
1380
+ if (arg === void 0) return readSnapshot();
1381
+ const segments = canonicalizePath(arg).segments;
1382
+ const node = getAtPath(inner.value, segments);
1383
+ if (node === null || typeof node !== "object") return node;
1384
+ return getAtPath(readSnapshot(), segments);
1262
1385
  },
1263
1386
  get(_, key) {
1264
1387
  if (typeof key === "symbol") {
@@ -1540,9 +1663,12 @@ function cloneVariantSnapshot(value) {
1540
1663
  for (let i = 0; i < raw.length; i++) out2[i] = cloneVariantSnapshot(raw[i]);
1541
1664
  return out2;
1542
1665
  }
1666
+ if (!isPlainRecord(raw)) return raw;
1543
1667
  const src = raw;
1544
1668
  const out = {};
1545
- for (const k of Object.keys(src)) safeAssign(out, k, cloneVariantSnapshot(src[k]));
1669
+ for (const k of consumerKeys(src)) {
1670
+ safeAssign(out, k, cloneVariantSnapshot(readConsumerProp(src, k)));
1671
+ }
1546
1672
  return out;
1547
1673
  }
1548
1674
  function createArrayBookkeeping(deps) {
@@ -1690,6 +1816,45 @@ function buildFieldArrayApi(state) {
1690
1816
  };
1691
1817
  }
1692
1818
 
1819
+ const SWEEP_SLICE = 8;
1820
+ function createDynamicPathSweep(state) {
1821
+ const dynamicKeys = /* @__PURE__ */ new Set();
1822
+ const evictors = [];
1823
+ const isDynamicPath = (segments) => {
1824
+ for (let i = 0; i < segments.length; i++) {
1825
+ if (typeof segments[i] === "number") return true;
1826
+ if (!state.schema.isFixedObjectAtPath(segments.slice(0, i))) return true;
1827
+ }
1828
+ return false;
1829
+ };
1830
+ let sweepCursor = null;
1831
+ state.onFormChange((next) => {
1832
+ if (dynamicKeys.size === 0) return;
1833
+ const raw = toRaw(next);
1834
+ for (let i = 0; i < SWEEP_SLICE; i++) {
1835
+ sweepCursor ?? (sweepCursor = dynamicKeys.values());
1836
+ const step = sweepCursor.next();
1837
+ if (step.done === true) {
1838
+ sweepCursor = null;
1839
+ break;
1840
+ }
1841
+ const segments = segmentsForPathKey(step.value);
1842
+ if (segments !== null && hasAtPath(raw, segments)) continue;
1843
+ dynamicKeys.delete(step.value);
1844
+ for (const evict of evictors) evict(step.value);
1845
+ }
1846
+ });
1847
+ return {
1848
+ track(segments, key) {
1849
+ if (dynamicKeys.has(key)) return;
1850
+ if (isDynamicPath(segments)) dynamicKeys.add(key);
1851
+ },
1852
+ onEvict(evict) {
1853
+ evictors.push(evict);
1854
+ }
1855
+ };
1856
+ }
1857
+
1693
1858
  function isErrorInputLike(value) {
1694
1859
  if (value instanceof Error) return true;
1695
1860
  if (typeof value !== "object" || value === null) return false;
@@ -1999,15 +2164,16 @@ function walk(schema, store, path, value) {
1999
2164
  if (!accepted.has(kind)) {
2000
2165
  return false;
2001
2166
  }
2167
+ if (schema.isOpaqueLeafAtPath(path)) return true;
2002
2168
  if (Array.isArray(value)) {
2003
2169
  for (let i = 0; i < value.length; i++) {
2004
- if (!walk(schema, store, [...path, i], value[i])) return false;
2170
+ if (!walk(schema, store, [...path, i], readConsumerIndex(value, i))) return false;
2005
2171
  }
2006
2172
  return true;
2007
2173
  }
2008
2174
  if (isPlainRecord(value)) {
2009
- for (const key of Object.keys(value)) {
2010
- if (!walk(schema, store, [...path, key], value[key])) {
2175
+ for (const key of consumerKeys(value)) {
2176
+ if (!walk(schema, store, [...path, key], readConsumerProp(value, key))) {
2011
2177
  return false;
2012
2178
  }
2013
2179
  }
@@ -2062,19 +2228,26 @@ function indexRules(rules) {
2062
2228
  }
2063
2229
  return idx;
2064
2230
  }
2231
+ function memberSlimTypes(schema, segments, accepted) {
2232
+ if (accepted.has("array")) return schema.getSlimPrimitiveTypesAtPath([...segments, 0]);
2233
+ if (accepted.has("set")) {
2234
+ return schema.getSlimPrimitiveTypesAtPath([...segments, SET_MEMBER_SEGMENT]);
2235
+ }
2236
+ return void 0;
2237
+ }
2065
2238
  function buildCoerceFn(schema, segments, index) {
2066
2239
  if (index === EMPTY_INDEX) return IDENTITY;
2067
2240
  if (index.size === 0) return IDENTITY;
2068
2241
  const accepted = schema.getSlimPrimitiveTypesAtPath(segments);
2069
- const elementAccepted = accepted.has("array") || accepted.has("set") ? schema.getSlimPrimitiveTypesAtPath([...segments, 0]) : void 0;
2242
+ const elementAccepted = memberSlimTypes(schema, segments, accepted);
2070
2243
  return (value) => coerceValue(value, accepted, elementAccepted, index);
2071
2244
  }
2072
2245
  function buildElementCoerceFn(schema, segments, index) {
2073
2246
  if (index === EMPTY_INDEX) return void 0;
2074
2247
  if (index.size === 0) return void 0;
2075
2248
  const accepted = schema.getSlimPrimitiveTypesAtPath(segments);
2076
- if (!accepted.has("array") && !accepted.has("set")) return void 0;
2077
- const elementAccepted = schema.getSlimPrimitiveTypesAtPath([...segments, 0]);
2249
+ const elementAccepted = memberSlimTypes(schema, segments, accepted);
2250
+ if (elementAccepted === void 0) return void 0;
2078
2251
  return (value) => coerceScalar(value, elementAccepted, index);
2079
2252
  }
2080
2253
  function pickScalarTarget(accepted) {
@@ -2317,8 +2490,8 @@ function walkUnsetSentinels(values, schema) {
2317
2490
  const cleaned = walkCore(values, [], schema, paths, true);
2318
2491
  return { cleanedValues: cleaned, paths };
2319
2492
  }
2320
- function isOpaqueLeaf(value) {
2321
- return value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || typeof value === "function";
2493
+ function isRecursable(value) {
2494
+ return Array.isArray(value) || isPlainRecord(value);
2322
2495
  }
2323
2496
  function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
2324
2497
  if (isUnset(input)) {
@@ -2332,20 +2505,21 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
2332
2505
  return input;
2333
2506
  }
2334
2507
  if (input === null) return null;
2335
- if (isOpaqueLeaf(input)) return input;
2508
+ if (!isRecursable(input)) return input;
2336
2509
  if (Array.isArray(input)) {
2337
2510
  const out = new Array(input.length);
2338
2511
  let mutated = false;
2339
2512
  for (let i = 0; i < input.length; i++) {
2340
- const walked = walkCore(input[i], [...segments, i], schema, paths, synthesizeSchemaKeys);
2513
+ const original = readConsumerIndex(input, i);
2514
+ const walked = walkCore(original, [...segments, i], schema, paths, synthesizeSchemaKeys);
2341
2515
  out[i] = walked;
2342
- if (walked !== input[i]) mutated = true;
2516
+ if (walked !== original) mutated = true;
2343
2517
  }
2344
2518
  return mutated ? out : input;
2345
2519
  }
2346
2520
  if (typeof input === "object") {
2347
2521
  const obj = input;
2348
- const inputKeys = Object.keys(obj);
2522
+ const inputKeys = consumerKeys(obj);
2349
2523
  let keys = inputKeys;
2350
2524
  let mutated = false;
2351
2525
  let inputKeysSet = null;
@@ -2353,7 +2527,7 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
2353
2527
  inputKeysSet = new Set(inputKeys);
2354
2528
  const allKeys = new Set(inputKeys);
2355
2529
  const slim = schema.getDefaultAtPath(segments);
2356
- if (slim !== null && slim !== void 0 && typeof slim === "object" && !Array.isArray(slim) && !isOpaqueLeaf(slim)) {
2530
+ if (isPlainRecord(slim)) {
2357
2531
  for (const k of Object.keys(slim)) allKeys.add(k);
2358
2532
  }
2359
2533
  keys = allKeys;
@@ -2361,7 +2535,7 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
2361
2535
  }
2362
2536
  const out = {};
2363
2537
  for (const key of keys) {
2364
- const orig = obj[key];
2538
+ const orig = readConsumerProp(obj, key);
2365
2539
  if (synthesizeSchemaKeys && orig === void 0 && inputKeysSet?.has(key) === true) {
2366
2540
  safeAssign(out, key, void 0);
2367
2541
  mutated = true;
@@ -2382,22 +2556,12 @@ function walkUnspecified(slim, segments, paths) {
2382
2556
  }
2383
2557
  return slim;
2384
2558
  }
2385
- if (isOpaqueLeaf(slim)) {
2386
- return slim;
2387
- }
2388
- if (Array.isArray(slim)) return slim;
2389
- if (slim !== null && typeof slim === "object") {
2390
- const out = {};
2391
- for (const key of Object.keys(slim)) {
2392
- safeAssign(
2393
- out,
2394
- key,
2395
- walkUnspecified(slim[key], [...segments, key], paths)
2396
- );
2397
- }
2398
- return out;
2559
+ if (!isPlainRecord(slim)) return slim;
2560
+ const out = {};
2561
+ for (const key of Object.keys(slim)) {
2562
+ safeAssign(out, key, walkUnspecified(slim[key], [...segments, key], paths));
2399
2563
  }
2400
- return slim;
2564
+ return out;
2401
2565
  }
2402
2566
  function substituteUnsetSentinels(value, prefix, schema) {
2403
2567
  const paths = [];
@@ -2433,11 +2597,11 @@ function expandUnsetAt(segments, schema, paths) {
2433
2597
  paths.push(canonicalizePath(segments).key);
2434
2598
  return slim;
2435
2599
  }
2436
- if (isOpaqueLeaf(slim)) {
2600
+ if (Array.isArray(slim)) return slim;
2601
+ if (!isPlainRecord(slim)) {
2437
2602
  paths.push(canonicalizePath(segments).key);
2438
2603
  return slim;
2439
2604
  }
2440
- if (Array.isArray(slim)) return slim;
2441
2605
  const result = {};
2442
2606
  for (const key of Object.keys(slim)) {
2443
2607
  result[key] = expandUnsetAt([...segments, key], schema, paths);
@@ -2447,14 +2611,14 @@ function expandUnsetAt(segments, schema, paths) {
2447
2611
  function walkAuthoredFromConstraints(value, prefix, out) {
2448
2612
  if (prefix.length > 0) out.add(canonicalizePath(prefix).key);
2449
2613
  if (isPlainRecord(value)) {
2450
- for (const k of Object.keys(value)) {
2451
- walkAuthoredFromConstraints(value[k], [...prefix, k], out);
2614
+ for (const k of consumerKeys(value)) {
2615
+ walkAuthoredFromConstraints(readConsumerProp(value, k), [...prefix, k], out);
2452
2616
  }
2453
2617
  return;
2454
2618
  }
2455
2619
  if (Array.isArray(value)) {
2456
2620
  for (let i = 0; i < value.length; i++) {
2457
- walkAuthoredFromConstraints(value[i], [...prefix, i], out);
2621
+ walkAuthoredFromConstraints(readConsumerIndex(value, i), [...prefix, i], out);
2458
2622
  }
2459
2623
  }
2460
2624
  }
@@ -2534,10 +2698,12 @@ function buildFormApi(state, formInstanceId, options = {}) {
2534
2698
  return metaBase;
2535
2699
  };
2536
2700
  const fieldStateAccessorOptions = options.getDisplayState !== void 0 ? { getDisplayState: options.getDisplayState } : void 0;
2701
+ const pathSweep = createDynamicPathSweep(state);
2537
2702
  const getRootFieldStateAt = buildFieldStateAccessor(
2538
2703
  state,
2539
2704
  formInstanceId,
2540
2705
  getFormMetaBase,
2706
+ pathSweep,
2541
2707
  fieldStateAccessorOptions
2542
2708
  );
2543
2709
  const getDisplayStateAt = (segments) => getRootFieldStateAt(segments).value.displayState;
@@ -2564,6 +2730,10 @@ function buildFormApi(state, formInstanceId, options = {}) {
2564
2730
  const segments = canonicalizePath(pathInput).segments;
2565
2731
  return computed(() => getAtPath(state.form.value, segments));
2566
2732
  }
2733
+ function pathStoresFunctions(segments) {
2734
+ if (state.schema.isOpaqueLeafAtPath(segments)) return false;
2735
+ return state.schema.getSlimPrimitiveTypesAtPath(segments).has("function");
2736
+ }
2567
2737
  function setValueImpl(pathOrValue, maybeValue) {
2568
2738
  const argc = arguments.length;
2569
2739
  const isPathForm = argc >= 2 && (typeof pathOrValue === "string" || Array.isArray(pathOrValue));
@@ -2616,7 +2786,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
2616
2786
  };
2617
2787
  if (isUnset(maybeValue)) return writeUnsetAt();
2618
2788
  let resolvedValue;
2619
- if (typeof maybeValue === "function") {
2789
+ if (typeof maybeValue === "function" && !pathStoresFunctions(segments)) {
2620
2790
  const current = state.getValueAtPath(segments);
2621
2791
  const prev = current === void 0 ? state.schema.getDefaultAtPath(segments) : current;
2622
2792
  resolvedValue = maybeValue(prev);
@@ -2634,7 +2804,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
2634
2804
  reMarkBlanksAfterSubstitution(walked.paths);
2635
2805
  return true;
2636
2806
  }
2637
- const errorsProxy = buildErrorsSurface(state);
2807
+ const errorsProxy = buildErrorsSurface(state, pathSweep);
2638
2808
  function flattenUserErrors() {
2639
2809
  const all = [];
2640
2810
  for (const cell of state.errorCells.values()) all.push(...cell.user);
@@ -2733,8 +2903,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
2733
2903
  if (nextDefaultValues === void 0) {
2734
2904
  state.reset();
2735
2905
  } else {
2736
- const walked = walkUnsetSentinels(
2906
+ const walked = substituteUnsetSentinels(
2737
2907
  nextDefaultValues,
2908
+ [],
2738
2909
  state.schema
2739
2910
  );
2740
2911
  state.reset(walked.cleanedValues);
@@ -2808,8 +2979,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
2808
2979
  };
2809
2980
  return Object.freeze(view);
2810
2981
  });
2811
- const valuesProxy = buildValuesSurface(state.form);
2812
- const fieldStateProxy = buildFieldsSurface(state, getRootFieldStateAt);
2982
+ const valuesProxy = buildValuesSurface(state.form, state.onFormChange);
2983
+ const fieldStateProxy = buildFieldsSurface(state, getRootFieldStateAt, pathSweep);
2813
2984
  const needsLazyGate = state.defaultValuesFactory.value !== void 0 || state.hasSsrPrefetch;
2814
2985
  function gated(fn) {
2815
2986
  if (!needsLazyGate) return fn;
@@ -2930,6 +3101,12 @@ function buildFormApi(state, formInstanceId, options = {}) {
2930
3101
 
2931
3102
  const IDLE = Object.freeze({ display: "idle" });
2932
3103
  const MAX_DELAY = 2147483647;
3104
+ const PENDING_LIVENESS_MS = 250;
3105
+ function withLiveness(machine, now) {
3106
+ if (machine.display !== "pending") return machine;
3107
+ if (machine.reviewAt !== void 0 && Number.isFinite(machine.reviewAt)) return machine;
3108
+ return { ...machine, reviewAt: now + PENDING_LIVENESS_MS };
3109
+ }
2933
3110
  function createDisplayEngine(ssr) {
2934
3111
  const machines = /* @__PURE__ */ new Map();
2935
3112
  const tick = ref(0);
@@ -2958,7 +3135,7 @@ function createDisplayEngine(ssr) {
2958
3135
  return;
2959
3136
  }
2960
3137
  if (timer !== null && timerTarget === target) return;
2961
- if (target === lastFiredTarget) {
3138
+ if (target === lastFiredTarget && target <= now) {
2962
3139
  clearTimer();
2963
3140
  return;
2964
3141
  }
@@ -2977,8 +3154,9 @@ function createDisplayEngine(ssr) {
2977
3154
  function resolve(key, ctx, reducer) {
2978
3155
  void tick.value;
2979
3156
  const prev = machines.get(key) ?? IDLE;
2980
- const machine = reducer(prev, ctx);
2981
- if (ssr) return machine;
3157
+ const reduced = reducer(prev, ctx);
3158
+ if (ssr) return reduced;
3159
+ const machine = withLiveness(reduced, ctx.now);
2982
3160
  const active = machine.display !== "idle" || machine.reviewAt !== void 0 && Number.isFinite(machine.reviewAt);
2983
3161
  if (active) machines.set(key, machine);
2984
3162
  else machines.delete(key);
@@ -3070,6 +3248,7 @@ async function runFactoryAndApply(st, factory) {
3070
3248
  st.schema
3071
3249
  );
3072
3250
  st.applyFormReplacement(full, { hydration: true });
3251
+ st.adoptResolvedDefaults(value);
3073
3252
  st.scheduleFieldValidation(
3074
3253
  [],
3075
3254
  true
@@ -3149,12 +3328,10 @@ function applyDuStubs(schema, data, options = {}) {
3149
3328
  }
3150
3329
  function walkDuStubs(schema, value, path, warned) {
3151
3330
  if (value === null || value === void 0 || typeof value !== "object") return value;
3152
- if (value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || typeof value === "function") {
3153
- return value;
3154
- }
3155
3331
  if (Array.isArray(value)) {
3156
3332
  return value.map((item, i) => walkDuStubs(schema, item, [...path, i]));
3157
3333
  }
3334
+ if (!isPlainRecord(value)) return value;
3158
3335
  const rec = value;
3159
3336
  const du = schema.getUnionDiscriminatorAtPath(path);
3160
3337
  if (du !== void 0) {
@@ -3166,8 +3343,8 @@ function walkDuStubs(schema, value, path, warned) {
3166
3343
  }
3167
3344
  }
3168
3345
  const out = {};
3169
- for (const k of Object.keys(rec)) {
3170
- safeAssign(out, k, walkDuStubs(schema, rec[k], [...path, k]));
3346
+ for (const k of consumerKeys(rec)) {
3347
+ safeAssign(out, k, walkDuStubs(schema, readConsumerProp(rec, k), [...path, k]));
3171
3348
  }
3172
3349
  return out;
3173
3350
  }
@@ -3177,23 +3354,25 @@ function stripSymbolsDeep(value) {
3177
3354
  let mutated2 = false;
3178
3355
  const out2 = new Array(value.length);
3179
3356
  for (let i = 0; i < value.length; i++) {
3180
- const cleaned = stripSymbolsDeep(value[i]);
3357
+ const original = readConsumerIndex(value, i);
3358
+ const cleaned = stripSymbolsDeep(original);
3181
3359
  out2[i] = cleaned;
3182
- if (cleaned !== value[i]) mutated2 = true;
3360
+ if (cleaned !== original) mutated2 = true;
3183
3361
  }
3184
3362
  return mutated2 ? out2 : value;
3185
3363
  }
3186
3364
  const proto = Object.getPrototypeOf(value);
3187
3365
  if (proto !== Object.prototype && proto !== null) return value;
3188
- const symKeys = Object.getOwnPropertySymbols(value);
3189
- const stringKeys = Object.keys(value);
3366
+ const symKeys = consumerSymbolKeys(value);
3367
+ const stringKeys = consumerKeys(value);
3190
3368
  let mutated = symKeys.length > 0;
3191
3369
  const out = {};
3192
3370
  const src = value;
3193
3371
  for (const k of stringKeys) {
3194
- const cleaned = stripSymbolsDeep(src[k]);
3372
+ const original = readConsumerProp(src, k);
3373
+ const cleaned = stripSymbolsDeep(original);
3195
3374
  out[k] = cleaned;
3196
- if (cleaned !== src[k]) mutated = true;
3375
+ if (cleaned !== original) mutated = true;
3197
3376
  }
3198
3377
  return mutated ? out : value;
3199
3378
  }
@@ -4096,8 +4275,27 @@ function activate(st) {
4096
4275
  if (factory === void 0) return Promise.resolve();
4097
4276
  return fireFactory(st, factory);
4098
4277
  }
4278
+ function adoptResolvedDefaults(st, value) {
4279
+ st.defaultValues = structuralSnapshot(
4280
+ mergeSparseHydration(
4281
+ st.defaultValues,
4282
+ value,
4283
+ st.schema
4284
+ )
4285
+ );
4286
+ seedOriginalsFromBaseline(
4287
+ st,
4288
+ computeBaselineResponse(st.schema, st.strict, st.defaultValues).data,
4289
+ false
4290
+ );
4291
+ }
4099
4292
  function reset(st, nextDefaultValues) {
4100
- const resetSource = nextDefaultValues ?? st.defaultValues;
4293
+ const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
4294
+ st.defaultValues,
4295
+ nextDefaultValues,
4296
+ st.schema
4297
+ );
4298
+ st.defaultValues = structuralSnapshot(resetSource);
4101
4299
  const resetResponse = computeBaselineResponse(st.schema, st.strict, resetSource);
4102
4300
  const next = resetResponse.data;
4103
4301
  rebuildAuthoredPaths(st, resetSource, next);
@@ -4106,13 +4304,13 @@ function reset(st, nextDefaultValues) {
4106
4304
  st.removedSubtrees.clear();
4107
4305
  seedOriginalsFromBaseline(st, next, false);
4108
4306
  if (nextDefaultValues !== void 0) {
4109
- st.blankPaths.clear();
4110
- st.originalBlankPaths.clear();
4111
- } else {
4112
- st.blankPaths.clear();
4113
- for (const key of st.originalBlankPaths) {
4114
- st.blankPaths.add(key);
4115
- }
4307
+ const mentioned = /* @__PURE__ */ new Set();
4308
+ walkAuthoredFromConstraints(nextDefaultValues, [], mentioned);
4309
+ for (const key of mentioned) st.originalBlankPaths.delete(key);
4310
+ }
4311
+ st.blankPaths.clear();
4312
+ for (const key of st.originalBlankPaths) {
4313
+ st.blankPaths.add(key);
4116
4314
  }
4117
4315
  st.errorCells.clear();
4118
4316
  if (st.strict && !resetResponse.success) {
@@ -4420,7 +4618,16 @@ function createFormStore(options) {
4420
4618
  originalBlankPaths,
4421
4619
  // --- kernel-internal state ---
4422
4620
  strict,
4423
- defaultValues,
4621
+ // Defensive copy, not a fix for an observed alias: today
4622
+ // `getDefaultValues` happens to build a fresh tree, so form storage
4623
+ // does not currently share structure with the consumer's object.
4624
+ // That is an adapter implementation detail rather than a contract,
4625
+ // and this field is now durable state that every `reset()` reads, so
4626
+ // it should not depend on it. The copy also means a consumer who
4627
+ // keeps a reference to the literal they passed cannot mutate the
4628
+ // form's defaults from outside. `reset()` snapshots for a harder
4629
+ // reason (see there) where an alias IS reachable.
4630
+ defaultValues: structuralSnapshot(defaultValues),
4424
4631
  ssrPrefetch,
4425
4632
  rememberVariants,
4426
4633
  fieldValidationMode,
@@ -4449,6 +4656,7 @@ function createFormStore(options) {
4449
4656
  // --- methods: thin per-instance skins over the module kernel ---
4450
4657
  rehydrate: () => rehydrate(st),
4451
4658
  activate: () => activate(st),
4659
+ adoptResolvedDefaults: (value) => adoptResolvedDefaults(st, value),
4452
4660
  pathHasAsyncValidation: (path) => pathHasAsyncValidation(st, path),
4453
4661
  pathHasAsyncValidationByKey: (key, segments) => pathHasAsyncValidationByKey(st, key, segments),
4454
4662
  applyFormReplacement: (next, meta) => applyFormReplacement(st, next, meta),
@@ -4594,6 +4802,7 @@ function useAbstractForm(configuration, options) {
4594
4802
  const factory = resolvedDefaults.factory;
4595
4803
  state.defaultValuesFactory.value = factory;
4596
4804
  if (hadPendingHydration) {
4805
+ state.adoptResolvedDefaults(toRaw(state.form.value));
4597
4806
  state.hydrating.value = false;
4598
4807
  state.defaultsResolved.value = true;
4599
4808
  } else if (registry.ssr) {
@@ -4775,12 +4984,13 @@ function makeRegisterValueProxy(capturedRegisterValue) {
4775
4984
  get(_target, prop) {
4776
4985
  if (prop === "__v_isRef") return true;
4777
4986
  if (prop === "value") return capturedRegisterValue.value;
4987
+ if (prop === "isBound") return capturedRegisterValue.value !== void 0;
4778
4988
  const v = capturedRegisterValue.value;
4779
4989
  if (v === void 0) return void 0;
4780
4990
  return Reflect.get(v, prop);
4781
4991
  },
4782
4992
  has(_target, prop) {
4783
- if (prop === "__v_isRef" || prop === "value") return true;
4993
+ if (prop === "__v_isRef" || prop === "value" || prop === "isBound") return true;
4784
4994
  const v = capturedRegisterValue.value;
4785
4995
  if (v === void 0) return false;
4786
4996
  return Reflect.has(v, prop);
@@ -4801,7 +5011,7 @@ function makeRegisterValueProxy(capturedRegisterValue) {
4801
5011
  }
4802
5012
  });
4803
5013
  }
4804
- function useRegister() {
5014
+ function useRegister(options) {
4805
5015
  const instance = getCurrentInstance();
4806
5016
  if (instance === null) {
4807
5017
  return makeRegisterValueProxy(shallowRef(void 0));
@@ -4840,7 +5050,7 @@ function useRegister() {
4840
5050
  if (el !== null && el !== void 0 && typeof el === "object") {
4841
5051
  el[REGISTER_OWNER_MARKER] = true;
4842
5052
  }
4843
- if (capturedRegisterValue.value === void 0) ;
5053
+ if (capturedRegisterValue.value === void 0 && options?.optional !== true) ;
4844
5054
  });
4845
5055
  return makeRegisterValueProxy(capturedRegisterValue);
4846
5056
  }
@@ -4947,8 +5157,12 @@ function buildNoopWizardSchema(formKey) {
4947
5157
  getDefaultAtPath: () => void 0,
4948
5158
  getEmptyValueAtPath: () => void 0,
4949
5159
  isPreprocessOrCoerceLeaf: () => false,
5160
+ isOpaqueLeafAtPath: () => false,
4950
5161
  arrayShapeAtPath: () => null,
4951
5162
  isFixedObjectAtPath: (path) => path.length === 0,
5163
+ // The noop schema declares no shape at all, so nothing under it is
5164
+ // addressable, root included.
5165
+ entryKeyKindAtPath: () => void 0,
4952
5166
  getSchemasAtPath: () => [],
4953
5167
  validateAtPath: () => success,
4954
5168
  getSlimPrimitiveTypesAtPath: () => new Set(EMPTY_SLIM_KINDS),
@@ -5710,6 +5924,24 @@ function useWizard(options) {
5710
5924
  const target = list[idx + 1];
5711
5925
  moveTo(target.key);
5712
5926
  }
5927
+ let cancelDeferredAdvance = null;
5928
+ function advanceWhenInFlightSubmitLands(store, key) {
5929
+ cancelDeferredAdvance?.();
5930
+ const attemptsAtRequest = store.submissionAttempts.value;
5931
+ const off = store.onSubmitSuccess(() => {
5932
+ off();
5933
+ cancelDeferredAdvance = null;
5934
+ if (store.submissionAttempts.value !== attemptsAtRequest) return;
5935
+ if (activeKey.value !== key) return;
5936
+ advanceOne();
5937
+ });
5938
+ cancelDeferredAdvance = off;
5939
+ }
5940
+ function inFlightActiveStore() {
5941
+ const store = registry.forms.get(activeKey.value);
5942
+ if (store === void 0 || store.activeSubmissions.value === 0) return void 0;
5943
+ return store;
5944
+ }
5713
5945
  async function next() {
5714
5946
  if (submitting.value) {
5715
5947
  return;
@@ -5723,7 +5955,12 @@ function useWizard(options) {
5723
5955
  return;
5724
5956
  }
5725
5957
  const active = list[idx];
5726
- if (active !== void 0 && active.isGate) {
5958
+ if (active !== void 0 && active.isGate && !clearedGates.has(active.key)) {
5959
+ const inFlight = inFlightActiveStore();
5960
+ if (inFlight !== void 0) {
5961
+ advanceWhenInFlightSubmitLands(inFlight, activeKey.value);
5962
+ return;
5963
+ }
5727
5964
  await tryNext();
5728
5965
  return;
5729
5966
  }
@@ -5744,11 +5981,16 @@ function useWizard(options) {
5744
5981
  const form = activeForm.value;
5745
5982
  if (form === void 0) return false;
5746
5983
  const before = activeKey.value;
5984
+ const inFlight = inFlightActiveStore();
5985
+ if (inFlight !== void 0) {
5986
+ advanceWhenInFlightSubmitLands(inFlight, before);
5987
+ return false;
5988
+ }
5747
5989
  let ranClean = false;
5748
5990
  await asHandleSubmitSource(form).handleSubmit(() => {
5749
5991
  ranClean = true;
5750
5992
  })();
5751
- if (ranClean) advanceOne();
5993
+ if (ranClean && activeKey.value === before) advanceOne();
5752
5994
  return activeKey.value !== before;
5753
5995
  }
5754
5996
  function back() {
@@ -5988,6 +6230,7 @@ function useWizard(options) {
5988
6230
  onScopeDispose(() => {
5989
6231
  historyHandle.dispose();
5990
6232
  lazyNoopScope.stop();
6233
+ cancelDeferredAdvance?.();
5991
6234
  });
5992
6235
  }
5993
6236
  const explicitKey = options.key;
@@ -6137,4 +6380,4 @@ function escapeForInlineScript(json) {
6137
6380
  });
6138
6381
  }
6139
6382
 
6140
- export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, defaultDisplayState as a, defineCoercion as b, injectWizard as c, defaultCoercionRules as d, escapeForInlineScript as e, isUnset as f, gate as g, useAbstractForm as h, injectForm as i, useRegister as j, useWizard as k, lazy as l, makeDefaultDisplayState as m, isPlainRecord as n, humanize as o, slimKindOf as s, unset as u };
6383
+ export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, defaultDisplayState as a, defineCoercion as b, injectWizard as c, defaultCoercionRules as d, escapeForInlineScript as e, isUnset as f, gate as g, useAbstractForm as h, injectForm as i, useRegister as j, useWizard as k, lazy as l, makeDefaultDisplayState as m, isPlainRecord as n, crossCopyState as o, getAtPath as p, humanize as q, slimKindOf as s, unset as u };