attaform 0.31.1 → 0.31.2

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 (44) hide show
  1. package/dist/abstract.d.mts +5 -5
  2. package/dist/abstract.mjs +3 -2
  3. package/dist/dev/abstract.mjs +3 -2
  4. package/dist/dev/directive.mjs +1 -1
  5. package/dist/dev/history.mjs +118 -11
  6. package/dist/dev/index.mjs +4 -3
  7. package/dist/dev/shared/{attaform-dev.OceE0X3v.mjs → attaform-dev.BKWPjEB2.mjs} +4 -3
  8. package/dist/dev/shared/{attaform-dev.D7lKyM_7.mjs → attaform-dev.BnLLxX2l.mjs} +3 -3
  9. package/dist/dev/shared/{attaform-dev.Cbx0AiQF.mjs → attaform-dev.CKSqs_xQ.mjs} +1 -1
  10. package/dist/dev/shared/{attaform-dev.BpVGFSFa.mjs → attaform-dev.Cf_hZfbT.mjs} +3 -3
  11. package/dist/dev/shared/{attaform-dev.3uTCYwy8.mjs → attaform-dev.DLk51W7-.mjs} +111 -909
  12. package/dist/dev/shared/{attaform-dev.CwYTWyPX.mjs → attaform-dev.DoG8mZTq.mjs} +8 -1
  13. package/dist/dev/shared/attaform-dev.G-3XDl9F.mjs +1192 -0
  14. package/dist/dev/shared/{attaform-dev.PTGM9KE1.mjs → attaform-dev.oguHqv1W.mjs} +7 -6
  15. package/dist/dev/zod-v3.mjs +5 -4
  16. package/dist/dev/zod-v4.mjs +5 -4
  17. package/dist/dev/zod.mjs +4 -3
  18. package/dist/directive.d.mts +2 -2
  19. package/dist/directive.mjs +1 -1
  20. package/dist/history.d.mts +1 -1
  21. package/dist/history.mjs +118 -11
  22. package/dist/index.d.mts +6 -6
  23. package/dist/index.mjs +4 -3
  24. package/dist/shared/{attaform.j9xI_ObC.mjs → attaform.3kV6PqVJ.mjs} +7 -6
  25. package/dist/shared/{attaform.KEfNRDot.mjs → attaform.BJeiuJE2.mjs} +3 -3
  26. package/dist/shared/{attaform._1Zp3mDG.mjs → attaform.BNUhW4qC.mjs} +8 -1
  27. package/dist/shared/{attaform.B5b-HmhH.mjs → attaform.BlAmZ-WU.mjs} +3 -3
  28. package/dist/shared/{attaform.u6jfHoed.mjs → attaform.CMzc4bPI.mjs} +4 -3
  29. package/dist/shared/attaform.CgyyJVuq.mjs +1187 -0
  30. package/dist/shared/{attaform.CYlF4P6X.d.mts → attaform.CibLYe9-.d.mts} +185 -165
  31. package/dist/shared/{attaform.DAf4ehIe.mjs → attaform.DCUJCKyG.mjs} +111 -909
  32. package/dist/shared/{attaform.DZOynI6c.d.mts → attaform.DCyZT7u-.d.mts} +1 -1
  33. package/dist/shared/{attaform.B9PYKlhB.d.mts → attaform.DD0Y8krq.d.mts} +1 -1
  34. package/dist/shared/{attaform.BPMOl562.mjs → attaform.T0YjhjPU.mjs} +1 -1
  35. package/dist/shared/{attaform.i13OEHJF.d.mts → attaform.bI_4nKZp.d.mts} +61 -3
  36. package/dist/zod-v3.d.mts +4 -4
  37. package/dist/zod-v3.mjs +5 -4
  38. package/dist/zod-v4.d.mts +6 -6
  39. package/dist/zod-v4.mjs +5 -4
  40. package/dist/zod.d.mts +4 -4
  41. package/dist/zod.mjs +4 -3
  42. package/package.json +1 -1
  43. package/dist/dev/shared/attaform-dev.n6n00owJ.mjs +0 -279
  44. package/dist/shared/attaform.BPSqtU7a.mjs +0 -274
@@ -1,82 +1,9 @@
1
1
  import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, onBeforeMount, onBeforeUpdate, onMounted } from 'vue';
2
- import { A as ANONYMOUS_FORM_KEY_PREFIX, d as diffAndApply, i as isBarePatch, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, a as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, b as isDescendable, c as applyChangedKeys, R as RESERVED_KEY_PREFIX, e as DEFAULT_MAX_RECURSION_DEPTH, f as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform-dev.n6n00owJ.mjs';
2
+ import { a as ANONYMOUS_FORM_KEY_PREFIX, g as getAtPath, i as isPlainRecord, h as hasAtPath, b as makeBlankRequiredError, A as AttaformErrorCode, p as pickDefined, c as buildFieldArrayApi, s as structuralSnapshot, n as normalizeNumericOption, d as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, e as diffAndApply, f as mergeStructural, N as NO_ERRORS, j as createArrayBookkeeping, k as createVariantMemory, l as createArrayIdentity, o as isDescendable, q as migrateFieldRecords, r as setAtPath, t as remapForOp, u as isBarePatch, v as applyChangedKeys, w as cloneVariantSnapshot, x as setAtPathWithSchemaFill, y as tryInPlaceLeafWrite, R as RESERVED_KEY_PREFIX, z as DEFAULT_MAX_RECURSION_DEPTH, B as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform-dev.G-3XDl9F.mjs';
3
3
  import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.Bu6wgrA5.mjs';
4
- import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.Cbx0AiQF.mjs';
5
- import { e as canonicalizePath, i as isPathPrefix, f as pathsEqual, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, s as segmentsForPathKey, S as SubmitErrorHandlerError, t as toError, j as groupErrorsByKey, n as normalizeErrorInput, h as SET_MEMBER_SEGMENT, R as ROOT_PATH, l as normalizeErrorInputs, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform-dev.04aupFBW.mjs';
6
- import { i as isShadowedKey, e as safeOwnHas, a as safeOwnRead, f as consumerHas, g as spreadConsumerRecord, h as copyConsumerArray, r as readConsumerIndex, s as safeAssign, c as consumerKeys, b as readConsumerProp, d as callConsumerFn, j as consumerSymbolKeys, k as reportConsumerThrow } from './attaform-dev.CwYTWyPX.mjs';
7
-
8
- const AttaformErrorCode = {
9
- /** A required field is in the blank set: no value was supplied. */
10
- NoValueSupplied: "atta:no-value-supplied",
11
- /** The schema adapter's `validateAtPath` threw synchronously. */
12
- AdapterThrew: "atta:adapter-threw",
13
- /**
14
- * User code inside a `z.preprocess`, `.refine`, or `.transform`
15
- * threw (sync or async). The adapter caught the throw and surfaced
16
- * it as a `ValidationError` at the field path so the form's normal
17
- * error pipeline handles it instead of leaking as an unhandled
18
- * rejection or routing through `submitError`.
19
- */
20
- ValidatorThrew: "atta:validator-threw",
21
- /**
22
- * A function-form `defaultValues` factory threw or its promise
23
- * rejected. The runtime captures the raw error on `form.hydrateError`
24
- * and ALSO surfaces a form-level `ValidationError` (path `[]`) so
25
- * the standard error pipeline carries the signal. Critical for the
26
- * SSR round-trip: `hydrateError` itself does not ride the wire
27
- * payload, but `schemaErrors` does, so the client sees the failure
28
- * after rehydration without an extra channel.
29
- */
30
- HydrationFailed: "atta:hydration-failed",
31
- /** The supplied path didn't resolve to any node in the schema. */
32
- PathNotFound: "atta:path-not-found",
33
- /**
34
- * A walked form's `activate()` (async `defaultValues` factory) threw
35
- * during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
36
- * `ValidationError` at the form-level path (`[]`) so the wizard's
37
- * aggregate error pipeline can carry the failure alongside ordinary
38
- * validation errors. The raw factory error remains on
39
- * `form.hydrateError` for retry UX.
40
- */
41
- ActivationFailed: "atta:activation-failed",
42
- /**
43
- * Default code stamped on a manual error set through `form.setErrors`
44
- * when the caller omits an explicit `code`. The `setErrors` input is
45
- * lenient (`code` optional), so this is the fallback that keeps every
46
- * produced `ValidationError` carrying a stable, branchable identifier.
47
- * Override it per error by passing your own `code` (`api:…`, `auth:…`).
48
- */
49
- UserError: "atta:user-error",
50
- /**
51
- * Stamped on a `ValidationError` synthesized from a throw or rejection
52
- * out of a `handleSubmit` `onSubmit` callback. The raw error also lands
53
- * on `form.meta.submitError` (a raw-`Error` inspection channel); this
54
- * code marks the copy piped into the user-error layer so the failure
55
- * also surfaces on `form.errors` / `meta.ownErrors` / `firstOwnError`
56
- * where the UI already reads. A throw carrying its own `path` / `code`
57
- * keeps them; a bare `Error` or a non-Error throw defaults here at the
58
- * form-level path `[]`.
59
- */
60
- SubmitError: "atta:submit-error",
61
- /**
62
- * Synthesized by `wizard.handleSubmit` when the whole-wizard submit
63
- * would otherwise succeed but a `gate()` step is still uncleared. A
64
- * gate clears only on its member form's clean submit (confirmation), so
65
- * a downstream step that happens to be valid-by-default must not let the
66
- * wizard finish past an unconfirmed prerequisite. Emitted at the gate
67
- * form's key (path `[]`) so the aggregate error pipeline routes focus to
68
- * the gate, and `done` never latches.
69
- */
70
- GateNotCleared: "atta:gate-not-cleared"
71
- };
72
- function makeBlankRequiredError(segments) {
73
- return {
74
- message: "No value supplied",
75
- path: [...segments],
76
- code: AttaformErrorCode.NoValueSupplied
77
- };
78
- }
79
- const NO_ERRORS = Object.freeze([]);
4
+ import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.CKSqs_xQ.mjs';
5
+ import { e as canonicalizePath, i as isPathPrefix, f as pathsEqual, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, j as groupErrorsByKey, s as segmentsForPathKey, n as normalizeErrorInput, h as SET_MEMBER_SEGMENT, R as ROOT_PATH, l as normalizeErrorInputs, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform-dev.04aupFBW.mjs';
6
+ import { r as readConsumerIndex, c as consumerKeys, b as readConsumerProp, d as safeOwnHas, i as isShadowedKey, s as safeAssign, a as safeOwnRead, h as callConsumerFn, j as consumerExtensible, k as consumerSymbolKeys, l as reportConsumerThrow } from './attaform-dev.DoG8mZTq.mjs';
80
7
 
81
8
  function isGateOpen(field, formMeta) {
82
9
  return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
@@ -176,323 +103,6 @@ function humanize(segment) {
176
103
  }).join(" ");
177
104
  }
178
105
 
179
- const NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
180
- function mapKeyForSegment(map, segment, declared) {
181
- if (map.has(segment)) return segment;
182
- if (typeof segment !== "number") return segment;
183
- const asString = String(segment);
184
- if (map.has(asString)) return asString;
185
- return declared === "string" ? asString : segment;
186
- }
187
- function isRebuildableContainer(root, segment) {
188
- if (root === null || root === void 0 || typeof root !== "object") return true;
189
- return typeof segment === "number" ? Array.isArray(root) : isPlainRecord(root);
190
- }
191
- function descendStep(value, segment) {
192
- if (value === null || value === void 0) return NOT_FOUND;
193
- if (typeof value !== "object") return NOT_FOUND;
194
- if (Array.isArray(value)) {
195
- if (typeof segment !== "number") return NOT_FOUND;
196
- if (!(segment in value)) return NOT_FOUND;
197
- return value[segment];
198
- }
199
- if (value instanceof Map) {
200
- const key2 = mapKeyForSegment(value, segment);
201
- if (!value.has(key2)) return NOT_FOUND;
202
- return value.get(key2);
203
- }
204
- const record = value;
205
- const key = typeof segment === "number" ? String(segment) : segment;
206
- if (isShadowedKey(key)) {
207
- if (!safeOwnHas(record, key)) return NOT_FOUND;
208
- return safeOwnRead(record, key);
209
- }
210
- if (!(key in record)) return NOT_FOUND;
211
- return record[key];
212
- }
213
- function getAtPath(root, path) {
214
- if (path.length === 0) return root;
215
- try {
216
- let current = root;
217
- for (const segment of path) {
218
- const next = descendStep(current, segment);
219
- if (next === NOT_FOUND) return void 0;
220
- current = next;
221
- }
222
- return current;
223
- } catch {
224
- return void 0;
225
- }
226
- }
227
- function hasAtPath(root, path) {
228
- if (path.length === 0) return true;
229
- try {
230
- return hasAtPathUnguarded(root, path);
231
- } catch {
232
- return false;
233
- }
234
- }
235
- function hasAtPathUnguarded(root, path) {
236
- let current = root;
237
- for (let i = 0; i < path.length - 1; i++) {
238
- const segment = path[i];
239
- const next = descendStep(current, segment);
240
- if (next === NOT_FOUND) return false;
241
- current = next;
242
- }
243
- const last = path[path.length - 1];
244
- if (current === null || current === void 0) return false;
245
- if (typeof current !== "object") return false;
246
- if (Array.isArray(current)) {
247
- return typeof last === "number" && consumerHas(current, last);
248
- }
249
- if (current instanceof Map) {
250
- return current.has(mapKeyForSegment(current, last));
251
- }
252
- const key = typeof last === "number" ? String(last) : last;
253
- if (isShadowedKey(key)) return safeOwnHas(current, key);
254
- return consumerHas(current, key);
255
- }
256
- function isPlainRecord(value) {
257
- if (value === null || typeof value !== "object") return false;
258
- if (Array.isArray(value)) return false;
259
- const proto = Object.getPrototypeOf(value);
260
- return proto === null || proto === Object.prototype;
261
- }
262
- const NO_SCHEMA_DEFAULTS = /* @__PURE__ */ new Set();
263
- const NO_SCHEMA_FILL = {
264
- getDefaultAtPath: () => void 0,
265
- arrayShapeAtPath: () => null,
266
- getSlimPrimitiveTypesAtPath: () => NO_SCHEMA_DEFAULTS,
267
- entryKeyKindAtPath: () => void 0
268
- };
269
- function setAtPath(root, path, value) {
270
- return setAtPathWithSchemaFill(root, NO_SCHEMA_FILL, path, value);
271
- }
272
- const NO_IN_PLACE = { applied: false };
273
- function tryInPlaceLeafWrite(root, path, value) {
274
- if (path.length === 0) return NO_IN_PLACE;
275
- try {
276
- return descendAndWrite(root, path, value);
277
- } catch {
278
- return NO_IN_PLACE;
279
- }
280
- }
281
- function descendAndWrite(root, path, value) {
282
- let node = root;
283
- for (let i = 0; i < path.length; i++) {
284
- const seg = path[i];
285
- if (node instanceof Map) return NO_IN_PLACE;
286
- if (Array.isArray(node)) {
287
- if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
288
- } else if (isPlainRecord(node)) {
289
- if (typeof seg !== "string" || isShadowedKey(seg) || !(seg in node)) return NO_IN_PLACE;
290
- } else {
291
- return NO_IN_PLACE;
292
- }
293
- const container = node;
294
- if (i < path.length - 1) {
295
- node = container[seg];
296
- continue;
297
- }
298
- const old = container[seg];
299
- if (isPlainRecord(old) || Array.isArray(old)) return NO_IN_PLACE;
300
- container[seg] = value;
301
- return { applied: true, old };
302
- }
303
- return NO_IN_PLACE;
304
- }
305
- function mergeStructural(schema, path, consumer, defaultValue = schema.getDefaultAtPath(path)) {
306
- const scratch = path.slice();
307
- return mergeStructuralImpl(schema, scratch, consumer, defaultValue);
308
- }
309
- function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
310
- if (consumer === void 0) {
311
- if (schema.getSlimPrimitiveTypesAtPath(scratch).has("undefined")) {
312
- return void 0;
313
- }
314
- return defaultValue;
315
- }
316
- if (consumer === null) return null;
317
- if (Array.isArray(consumer)) {
318
- return mergeStructuralArray(schema, scratch, consumer);
319
- }
320
- if (consumer instanceof Map) {
321
- return mergeStructuralMap(schema, scratch, consumer);
322
- }
323
- if (isPlainRecord(consumer)) {
324
- if (!isPlainRecord(defaultValue)) {
325
- return consumer;
326
- }
327
- const out = spreadConsumerRecord(consumer);
328
- const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
329
- const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
330
- return filledAny || recursedAny ? out : consumer;
331
- }
332
- return consumer;
333
- }
334
- function mergeStructuralMap(schema, scratch, consumer) {
335
- if (consumer.size === 0) return consumer;
336
- let entryDefault;
337
- let entryDefaultRead = false;
338
- let out = null;
339
- for (const [key, entry] of consumer) {
340
- if (typeof key !== "string" && typeof key !== "number") continue;
341
- scratch.push(key);
342
- if (!entryDefaultRead) {
343
- entryDefault = schema.getDefaultAtPath(scratch);
344
- entryDefaultRead = true;
345
- }
346
- const merged = mergeStructuralImpl(schema, scratch, entry, entryDefault);
347
- scratch.pop();
348
- if (merged === entry) continue;
349
- out ?? (out = new Map(consumer));
350
- out.set(key, merged);
351
- }
352
- return out ?? consumer;
353
- }
354
- function mergeStructuralArray(schema, scratch, consumer) {
355
- const shape = schema.arrayShapeAtPath(scratch);
356
- const isTuple = typeof shape === "number";
357
- const targetLen = isTuple ? shape : consumer.length;
358
- let cachedElementDefault;
359
- let cachedElementDefaultRead = false;
360
- let mutated = targetLen > consumer.length;
361
- const out = copyConsumerArray(consumer);
362
- while (out.length < targetLen) out.push(void 0);
363
- for (let i = 0; i < targetLen; i++) {
364
- scratch.push(i);
365
- let elemDefault;
366
- if (isTuple) {
367
- elemDefault = schema.getDefaultAtPath(scratch);
368
- } else {
369
- if (!cachedElementDefaultRead) {
370
- cachedElementDefault = schema.getDefaultAtPath(scratch);
371
- cachedElementDefaultRead = true;
372
- }
373
- elemDefault = cachedElementDefault;
374
- }
375
- const consumerElem = i < consumer.length ? readConsumerIndex(consumer, i) : void 0;
376
- const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
377
- scratch.pop();
378
- if (merged !== consumerElem) {
379
- out[i] = merged;
380
- mutated = true;
381
- }
382
- }
383
- return mutated ? out : consumer;
384
- }
385
- function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
386
- let mutated = false;
387
- for (const key of Object.keys(defaultValue)) {
388
- if (!safeOwnHas(consumer, key)) {
389
- const defAtKey = safeOwnRead(defaultValue, key);
390
- scratch.push(key);
391
- const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
392
- scratch.pop();
393
- if (filled !== void 0) {
394
- safeAssign(out, key, filled);
395
- mutated = true;
396
- }
397
- }
398
- }
399
- return mutated;
400
- }
401
- function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
402
- let mutated = false;
403
- for (const key of consumerKeys(consumer)) {
404
- const cVal = safeOwnRead(consumer, key);
405
- if (cVal === void 0) continue;
406
- scratch.push(key);
407
- const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
408
- scratch.pop();
409
- if (merged !== cVal) {
410
- safeAssign(out, key, merged);
411
- mutated = true;
412
- }
413
- }
414
- return mutated;
415
- }
416
- function setAtPathWithSchemaFill(root, schema, fullPath, value) {
417
- if (fullPath.length === 0) return value;
418
- return setAtPathWithSchemaFillImpl(root, schema, fullPath, value, 0);
419
- }
420
- function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
421
- if (startIdx >= fullPath.length) return value;
422
- const head = fullPath[startIdx];
423
- const isLeafStep = startIdx === fullPath.length - 1;
424
- if (root instanceof Map) {
425
- const next = new Map(root);
426
- const key = mapKeyForSegment(root, head, schema.entryKeyKindAtPath(fullPath.slice(0, startIdx)));
427
- if (isLeafStep) {
428
- next.set(key, value);
429
- return next;
430
- }
431
- let childRoot2 = next.get(key);
432
- if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
433
- childRoot2 = schema.getDefaultAtPath(fullPath.slice(0, startIdx + 1));
434
- }
435
- next.set(key, setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1));
436
- return next;
437
- }
438
- if (!isRebuildableContainer(root, head)) return root;
439
- if (typeof head === "number") {
440
- const arr = Array.isArray(root) ? [...root] : [];
441
- const prefix = fullPath.slice(0, startIdx);
442
- if (arr.length < head) {
443
- const scratch = prefix.slice();
444
- const shape = schema.arrayShapeAtPath(scratch);
445
- const tupleLike = typeof shape === "number";
446
- let cachedArrayDefault;
447
- if (!tupleLike) {
448
- scratch.push(0);
449
- cachedArrayDefault = schema.getDefaultAtPath(scratch);
450
- scratch.pop();
451
- }
452
- while (arr.length < head) {
453
- const idx = arr.length;
454
- if (tupleLike) {
455
- scratch.push(idx);
456
- arr.push(schema.getDefaultAtPath(scratch));
457
- scratch.pop();
458
- } else {
459
- arr.push(cachedArrayDefault);
460
- }
461
- }
462
- }
463
- if (isLeafStep) {
464
- arr[head] = value;
465
- return arr;
466
- }
467
- let childRoot2 = arr[head];
468
- if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
469
- childRoot2 = schema.getDefaultAtPath([...prefix, head]);
470
- }
471
- arr[head] = setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1);
472
- return arr;
473
- }
474
- const rec = isPlainRecord(root) ? { ...root } : {};
475
- if (isLeafStep) {
476
- safeAssign(rec, head, value);
477
- return rec;
478
- }
479
- const existing = safeOwnRead(rec, head);
480
- let childRoot;
481
- if (existing === void 0 || existing !== null && typeof existing !== "object") {
482
- const intermPath = [...fullPath.slice(0, startIdx + 1)];
483
- const intermDefault = schema.getDefaultAtPath(intermPath);
484
- childRoot = intermDefault;
485
- } else {
486
- childRoot = existing;
487
- }
488
- safeAssign(
489
- rec,
490
- head,
491
- setAtPathWithSchemaFillImpl(childRoot, schema, fullPath, value, startIdx + 1)
492
- );
493
- return rec;
494
- }
495
-
496
106
  function isUnderStubAncestor(state, segments) {
497
107
  for (let i = 0; i < segments.length; i++) {
498
108
  const ancestorPath = segments.slice(0, i);
@@ -628,7 +238,6 @@ function visitActiveLeafPaths(value, base, visit) {
628
238
  function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
629
239
  const formValue = state.form.value;
630
240
  const value = getAtPath(formValue, segments);
631
- const original = state.originals.get(key)?.value;
632
241
  let pristine = true;
633
242
  let blank = true;
634
243
  let dirty = false;
@@ -745,7 +354,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
745
354
  return {
746
355
  base: {
747
356
  value,
748
- original,
357
+ original: state.getOriginalAtPath(segments),
749
358
  pristine,
750
359
  dirty,
751
360
  focused,
@@ -1451,504 +1060,6 @@ function buildValuesSurface(form, onFormChange) {
1451
1060
  });
1452
1061
  }
1453
1062
 
1454
- function remapForOp(op, oldLen) {
1455
- const moved = /* @__PURE__ */ new Map();
1456
- const vacated = /* @__PURE__ */ new Set();
1457
- const fresh = /* @__PURE__ */ new Set();
1458
- let newLen = oldLen;
1459
- switch (op.kind) {
1460
- case "insert":
1461
- for (let i = op.index; i < oldLen; i++) moved.set(i, i + 1);
1462
- fresh.add(op.index);
1463
- newLen = oldLen + 1;
1464
- break;
1465
- case "remove":
1466
- vacated.add(op.index);
1467
- for (let i = op.index + 1; i < oldLen; i++) moved.set(i, i - 1);
1468
- newLen = Math.max(0, oldLen - 1);
1469
- break;
1470
- case "move":
1471
- if (op.from !== op.to) {
1472
- moved.set(op.from, op.to);
1473
- if (op.from < op.to) {
1474
- for (let i = op.from + 1; i <= op.to; i++) moved.set(i, i - 1);
1475
- } else {
1476
- for (let i = op.to; i < op.from; i++) moved.set(i, i + 1);
1477
- }
1478
- }
1479
- break;
1480
- case "swap":
1481
- if (op.a !== op.b) {
1482
- moved.set(op.a, op.b);
1483
- moved.set(op.b, op.a);
1484
- }
1485
- break;
1486
- case "replace-at":
1487
- vacated.add(op.index);
1488
- fresh.add(op.index);
1489
- break;
1490
- }
1491
- return { moved, vacated, fresh, oldLen, newLen };
1492
- }
1493
- function changedIndices(remap) {
1494
- const changed = new Set(remap.vacated);
1495
- for (const [from, to] of remap.moved) {
1496
- changed.add(from);
1497
- changed.add(to);
1498
- }
1499
- for (const index of remap.fresh) changed.add(index);
1500
- return changed;
1501
- }
1502
- function permuteList(list, remap, fill) {
1503
- const claimed = new Array(remap.newLen);
1504
- for (let i = 0; i < remap.oldLen; i++) {
1505
- if (remap.vacated.has(i)) continue;
1506
- const to = remap.moved.get(i) ?? i;
1507
- if (to < remap.newLen) claimed[to] = list[i];
1508
- }
1509
- const next = [];
1510
- for (let i = 0; i < remap.newLen; i++) {
1511
- next.push(claimed[i] ?? fill());
1512
- }
1513
- return next;
1514
- }
1515
- function elementIndexUnder(arrayPath, key, idxPos) {
1516
- const segments = segmentsForPathKey(key);
1517
- if (segments === null) return null;
1518
- if (!isPathPrefix(arrayPath, segments)) return null;
1519
- if (segments.length <= idxPos) return null;
1520
- const index = segments[idxPos];
1521
- return typeof index === "number" ? index : null;
1522
- }
1523
- function collectKeysAtIndices(keys, arrayPath, member) {
1524
- const idxPos = arrayPath.length;
1525
- const hits = [];
1526
- for (const key of keys) {
1527
- const index = elementIndexUnder(arrayPath, key, idxPos);
1528
- if (index === null || !member(index)) continue;
1529
- const segments = segmentsForPathKey(key);
1530
- if (segments === null) continue;
1531
- hits.push({ key, segments: [...segments], index });
1532
- }
1533
- return hits;
1534
- }
1535
- function remapAffects(remap) {
1536
- return (index) => remap.moved.has(index) || remap.vacated.has(index) || remap.fresh.has(index);
1537
- }
1538
- function migrateMapSubtree(map, arrayPath, remap, rewriteValue) {
1539
- const hits = collectKeysAtIndices(map.keys(), arrayPath, remapAffects(remap));
1540
- if (hits.length === 0) return;
1541
- const idxPos = arrayPath.length;
1542
- const snapshots = [];
1543
- for (const hit of hits) {
1544
- const value = map.get(hit.key);
1545
- if (value !== void 0) snapshots.push({ ...hit, value });
1546
- }
1547
- for (const snap of snapshots) map.delete(snap.key);
1548
- for (const snap of snapshots) {
1549
- const target = remap.moved.get(snap.index);
1550
- if (target === void 0) continue;
1551
- const relocated = snap.segments.slice();
1552
- relocated[idxPos] = target;
1553
- map.set(canonicalizePath(relocated).key, rewriteValue(snap.value, relocated));
1554
- }
1555
- }
1556
- function migrateSetSubtree(set, arrayPath, remap) {
1557
- const hits = collectKeysAtIndices(set, arrayPath, remapAffects(remap));
1558
- if (hits.length === 0) return;
1559
- const idxPos = arrayPath.length;
1560
- for (const hit of hits) set.delete(hit.key);
1561
- for (const hit of hits) {
1562
- const target = remap.moved.get(hit.index);
1563
- if (target === void 0) continue;
1564
- const relocated = hit.segments.slice();
1565
- relocated[idxPos] = target;
1566
- set.add(canonicalizePath(relocated).key);
1567
- }
1568
- }
1569
- function evictSchemaVerdictsAtIndices(errorCells, arrayPath, indices) {
1570
- for (const hit of collectKeysAtIndices(
1571
- [...errorCells.keys()],
1572
- arrayPath,
1573
- (index) => indices.has(index)
1574
- )) {
1575
- const cell = errorCells.get(hit.key);
1576
- if (cell === void 0) continue;
1577
- if (cell.user.length === 0) errorCells.delete(hit.key);
1578
- else if (cell.schema.length > 0) errorCells.set(hit.key, { schema: NO_ERRORS, user: cell.user });
1579
- }
1580
- }
1581
- function deleteKeysAtIndices(keys, del, arrayPath, indices) {
1582
- for (const hit of collectKeysAtIndices(keys, arrayPath, (index) => indices.has(index))) {
1583
- del(hit.key);
1584
- }
1585
- }
1586
- function createArrayIdentity(getArrayLength, onChange) {
1587
- const tokens = /* @__PURE__ */ new Map();
1588
- const baselines = /* @__PURE__ */ new Map();
1589
- let counter = 0;
1590
- const allocate = () => `k${(counter++).toString(36)}`;
1591
- function ensure(arrayKey, expectedLen) {
1592
- let ids = tokens.get(arrayKey);
1593
- const firstTrack = ids === void 0;
1594
- if (ids === void 0) {
1595
- ids = [];
1596
- tokens.set(arrayKey, ids);
1597
- }
1598
- if (ids.length < expectedLen) {
1599
- const baseline = baselines.get(arrayKey);
1600
- while (ids.length < expectedLen) {
1601
- const anchored = baseline?.[ids.length];
1602
- ids.push(anchored !== void 0 && !ids.includes(anchored) ? anchored : allocate());
1603
- }
1604
- }
1605
- if (ids.length > expectedLen) ids.length = expectedLen;
1606
- if (firstTrack) baselines.set(arrayKey, [...ids]);
1607
- return ids;
1608
- }
1609
- function orderPristineForKey(arrayKey) {
1610
- const baseline = baselines.get(arrayKey);
1611
- const current = tokens.get(arrayKey);
1612
- if (baseline === void 0 || current === void 0) return true;
1613
- if (baseline.length !== current.length) return false;
1614
- for (let i = 0; i < current.length; i++) {
1615
- if (current[i] !== baseline[i]) return false;
1616
- }
1617
- return true;
1618
- }
1619
- return {
1620
- tokenAt(arraySegs, index) {
1621
- const len = getArrayLength(arraySegs);
1622
- if (index < 0 || index >= len) return "";
1623
- const ids = ensure(canonicalizePath(arraySegs).key, len);
1624
- return ids[index] ?? "";
1625
- },
1626
- applyOp(arraySegs, remap) {
1627
- const arrayKey = canonicalizePath(arraySegs).key;
1628
- const ids = ensure(arrayKey, remap.oldLen);
1629
- tokens.set(arrayKey, permuteList(ids, remap, allocate));
1630
- onChange([arraySegs]);
1631
- },
1632
- applyRemap(arrayPath, remap) {
1633
- if (remap.moved.size === 0 && remap.vacated.size === 0 && remap.fresh.size === 0) return;
1634
- const moved = [];
1635
- for (const hit of collectKeysAtIndices(tokens.keys(), arrayPath, remapAffects(remap))) {
1636
- moved.push(hit.segments);
1637
- }
1638
- migrateMapSubtree(tokens, arrayPath, remap, (value, segments) => {
1639
- moved.push(segments);
1640
- return value;
1641
- });
1642
- migrateMapSubtree(baselines, arrayPath, remap, (value) => value);
1643
- if (moved.length > 0) onChange(moved);
1644
- },
1645
- realign(arraySegs) {
1646
- ensure(canonicalizePath(arraySegs).key, getArrayLength(arraySegs));
1647
- },
1648
- realignContaining(paths) {
1649
- if (tokens.size === 0 || paths.length === 0) return;
1650
- const resized = [];
1651
- for (const [arrayKey, ids] of tokens) {
1652
- const segs = segmentsForPathKey(arrayKey);
1653
- if (segs === null || !paths.some((path) => isPathPrefix(segs, path) || isPathPrefix(path, segs))) {
1654
- continue;
1655
- }
1656
- const len = getArrayLength(segs);
1657
- if (ids.length === len) continue;
1658
- ensure(arrayKey, len);
1659
- resized.push(segs);
1660
- }
1661
- if (resized.length > 0) onChange(resized);
1662
- },
1663
- hasStructuralChangeUnder(prefix) {
1664
- for (const arrayKey of tokens.keys()) {
1665
- if (orderPristineForKey(arrayKey)) continue;
1666
- const segs = segmentsForPathKey(arrayKey);
1667
- if (segs === null) continue;
1668
- if (isPathPrefix(prefix, segs)) return true;
1669
- }
1670
- return false;
1671
- },
1672
- rebaselineAll() {
1673
- const rebased = [];
1674
- for (const arrayKey of [...tokens.keys()]) {
1675
- const segs = segmentsForPathKey(arrayKey);
1676
- if (segs === null) continue;
1677
- const ids = ensure(arrayKey, getArrayLength(segs));
1678
- baselines.set(arrayKey, [...ids]);
1679
- rebased.push(segs);
1680
- }
1681
- if (rebased.length > 0) onChange(rebased);
1682
- },
1683
- snapshot() {
1684
- return { tokens: copyLists(tokens), baselines: copyLists(baselines) };
1685
- },
1686
- restore(orders) {
1687
- const keys = /* @__PURE__ */ new Set([...tokens.keys(), ...orders.tokens.keys()]);
1688
- tokens.clear();
1689
- for (const [key, ids] of orders.tokens) tokens.set(key, [...ids]);
1690
- baselines.clear();
1691
- for (const [key, ids] of orders.baselines) baselines.set(key, [...ids]);
1692
- const restored = [];
1693
- for (const key of keys) {
1694
- const segs = segmentsForPathKey(key);
1695
- if (segs !== null) restored.push(segs);
1696
- }
1697
- if (restored.length > 0) onChange(restored);
1698
- }
1699
- };
1700
- }
1701
- function copyLists(lists) {
1702
- const out = /* @__PURE__ */ new Map();
1703
- for (const [key, ids] of lists) out.set(key, [...ids]);
1704
- return out;
1705
- }
1706
- function createVariantMemory() {
1707
- const memory = /* @__PURE__ */ new Map();
1708
- return {
1709
- clear() {
1710
- memory.clear();
1711
- },
1712
- clearUnderPath(parentPath) {
1713
- for (const memKey of [...memory.keys()]) {
1714
- const segs = segmentsForPathKey(memKey);
1715
- if (segs === null) continue;
1716
- if (isPathPrefix(parentPath, segs)) memory.delete(memKey);
1717
- }
1718
- },
1719
- dropAtIndices(arrayPath, indices) {
1720
- deleteKeysAtIndices([...memory.keys()], (key) => memory.delete(key), arrayPath, indices);
1721
- },
1722
- recordOutgoing(unionKey, discValue, snapshot) {
1723
- let perUnion = memory.get(unionKey);
1724
- if (perUnion === void 0) {
1725
- perUnion = /* @__PURE__ */ new Map();
1726
- memory.set(unionKey, perUnion);
1727
- }
1728
- perUnion.set(discValue, snapshot);
1729
- },
1730
- lookupIncoming(unionKey, discValue) {
1731
- return memory.get(unionKey)?.get(discValue);
1732
- }
1733
- };
1734
- }
1735
- function cloneVariantSnapshot(value) {
1736
- if (value === null || typeof value !== "object") return value;
1737
- const raw = toRaw(value);
1738
- if (raw instanceof Date) return new Date(raw.getTime());
1739
- if (raw instanceof Map) {
1740
- const out2 = /* @__PURE__ */ new Map();
1741
- for (const [k, v] of raw.entries()) out2.set(cloneVariantSnapshot(k), cloneVariantSnapshot(v));
1742
- return out2;
1743
- }
1744
- if (raw instanceof Set) {
1745
- const out2 = /* @__PURE__ */ new Set();
1746
- for (const v of raw) out2.add(cloneVariantSnapshot(v));
1747
- return out2;
1748
- }
1749
- if (raw instanceof RegExp) return new RegExp(raw.source, raw.flags);
1750
- if (Array.isArray(raw)) {
1751
- const out2 = new Array(raw.length);
1752
- for (let i = 0; i < raw.length; i++) out2[i] = cloneVariantSnapshot(raw[i]);
1753
- return out2;
1754
- }
1755
- if (!isPlainRecord(raw)) return raw;
1756
- const src = raw;
1757
- const out = {};
1758
- for (const k of consumerKeys(src)) {
1759
- safeAssign(out, k, cloneVariantSnapshot(readConsumerProp(src, k)));
1760
- }
1761
- return out;
1762
- }
1763
- function createArrayBookkeeping(deps) {
1764
- const {
1765
- form,
1766
- fields,
1767
- errorCells,
1768
- originals,
1769
- blankPaths,
1770
- originalBlankPaths,
1771
- authoredPaths,
1772
- removedPaths,
1773
- notifyStructure,
1774
- fieldValidationCounts,
1775
- fieldValidatingSince,
1776
- fieldValidationState,
1777
- activeValidations,
1778
- arrayIdentity,
1779
- variantMemory,
1780
- touchFieldRecord,
1781
- stampContainers,
1782
- stampBareContainers,
1783
- foldInteractionHistory,
1784
- decFieldValidation
1785
- } = deps;
1786
- function migrateElementState(arrayPath, remap) {
1787
- if (remap.moved.size === 0 && remap.vacated.size === 0) return;
1788
- migrateSetSubtree(originalBlankPaths, arrayPath, remap);
1789
- migrateSetSubtree(authoredPaths, arrayPath, remap);
1790
- const removedMoved = [];
1791
- for (const hit of collectKeysAtIndices(removedPaths.keys(), arrayPath, remapAffects(remap))) {
1792
- removedMoved.push(hit.segments);
1793
- }
1794
- migrateMapSubtree(removedPaths, arrayPath, remap, (_, segments) => {
1795
- removedMoved.push(segments);
1796
- return segments;
1797
- });
1798
- if (remap.vacated.size > 0) {
1799
- const released = [];
1800
- for (const { key } of collectKeysAtIndices(
1801
- fields.keys(),
1802
- arrayPath,
1803
- (index) => remap.vacated.has(index)
1804
- )) {
1805
- const record = fields.get(key);
1806
- if (record !== void 0) released.push(record);
1807
- }
1808
- foldInteractionHistory(arrayPath, released);
1809
- }
1810
- migrateMapSubtree(fields, arrayPath, remap, (record, segments) => ({
1811
- ...record,
1812
- path: segments
1813
- }));
1814
- migrateMapSubtree(errorCells(), arrayPath, remap, (cell, segments) => ({
1815
- schema: NO_ERRORS,
1816
- user: cell.user.map((error) => ({ ...error, path: [...segments] }))
1817
- }));
1818
- migrateMapSubtree(originals, arrayPath, remap, (record, segments) => ({
1819
- segments,
1820
- value: record.value
1821
- }));
1822
- migrateSetSubtree(blankPaths, arrayPath, remap);
1823
- migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
1824
- migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
1825
- migrateMapSubtree(fieldValidationState, arrayPath, remap, (entry, segments) => {
1826
- entry.key = keyForSegments(segments).key;
1827
- entry.path = segments;
1828
- return entry;
1829
- });
1830
- arrayIdentity.applyRemap(arrayPath, remap);
1831
- if (removedMoved.length > 0) notifyStructure(removedMoved);
1832
- }
1833
- function seedFreshElement(arrayPath, freshIndex, now) {
1834
- const elementPath = [...arrayPath, freshIndex];
1835
- const patches = [];
1836
- diffAndApply(void 0, getAtPath(form.value, elementPath), elementPath, (patch) => {
1837
- patches.push(patch);
1838
- });
1839
- const bare = [];
1840
- patches.forEach((patch, index) => {
1841
- if (patch.kind !== "added") return;
1842
- if (isBarePatch(patch)) {
1843
- bare.push(index);
1844
- return;
1845
- }
1846
- const { key, segments } = canonicalizePath(patch.path);
1847
- if (!originals.has(key)) originals.set(key, { segments: patch.path, value: void 0 });
1848
- touchFieldRecord(key, segments, { updatedAt: now });
1849
- });
1850
- if (bare.length > 0) stampBareContainers(patches, bare, now);
1851
- else if (patches.length === 0 && hasAtPath(form.value, elementPath)) {
1852
- stampContainers([elementPath], now);
1853
- }
1854
- }
1855
- function abortValidationAtVacatedIndices(arrayPath, remap) {
1856
- if (remap.vacated.size === 0) return;
1857
- const hits = collectKeysAtIndices(
1858
- [...fieldValidationState.keys()],
1859
- arrayPath,
1860
- (index) => remap.vacated.has(index)
1861
- );
1862
- for (const hit of hits) {
1863
- const entry = fieldValidationState.get(hit.key);
1864
- if (entry === void 0) continue;
1865
- if (entry.timer !== null) {
1866
- clearTimeout(entry.timer);
1867
- } else if (!entry.settled && !entry.released) {
1868
- activeValidations.value = Math.max(0, activeValidations.value - 1);
1869
- decFieldValidation(hit.key);
1870
- entry.released = true;
1871
- }
1872
- entry.aborted = true;
1873
- fieldValidationState.delete(hit.key);
1874
- }
1875
- }
1876
- return {
1877
- applyStructuralOp(arrayPath, remap, now) {
1878
- abortValidationAtVacatedIndices(arrayPath, remap);
1879
- migrateElementState(arrayPath, remap);
1880
- for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex, now);
1881
- const changed = changedIndices(remap);
1882
- evictSchemaVerdictsAtIndices(errorCells(), arrayPath, changed);
1883
- variantMemory.dropAtIndices(arrayPath, changed);
1884
- arrayIdentity.applyOp(arrayPath, remap);
1885
- }
1886
- };
1887
- }
1888
- function buildFieldArrayApi(state) {
1889
- function readArray(path) {
1890
- const segments = canonicalizePath(path).segments;
1891
- const current = state.getValueAtPath(segments);
1892
- return Array.isArray(current) ? current.slice() : [];
1893
- }
1894
- function writeArray(path, next, arrayOp) {
1895
- const { segments } = canonicalizePath(path);
1896
- const meta = {
1897
- ...arrayOp !== void 0 ? { arrayOp } : {}
1898
- };
1899
- return state.setValueAtPath(segments, next, meta);
1900
- }
1901
- return {
1902
- append(path, value) {
1903
- const next = readArray(path);
1904
- next.push(value);
1905
- return writeArray(path, next, { kind: "insert", index: next.length - 1 });
1906
- },
1907
- prepend(path, value) {
1908
- const next = readArray(path);
1909
- next.unshift(value);
1910
- return writeArray(path, next, { kind: "insert", index: 0 });
1911
- },
1912
- insert(path, index, value) {
1913
- const next = readArray(path);
1914
- const preLen = next.length;
1915
- const insertIndex = index < 0 ? Math.max(0, preLen + index) : Math.min(index, preLen);
1916
- next.splice(insertIndex, 0, value);
1917
- return writeArray(path, next, { kind: "insert", index: insertIndex });
1918
- },
1919
- remove(path, index) {
1920
- const next = readArray(path);
1921
- if (index < 0 || index >= next.length) return false;
1922
- next.splice(index, 1);
1923
- return writeArray(path, next, { kind: "remove", index });
1924
- },
1925
- swap(path, a, b) {
1926
- const next = readArray(path);
1927
- if (a < 0 || a >= next.length) return false;
1928
- if (b < 0 || b >= next.length) return false;
1929
- if (a === b) return false;
1930
- const tmp = next[a];
1931
- next[a] = next[b];
1932
- next[b] = tmp;
1933
- return writeArray(path, next, { kind: "swap", a, b });
1934
- },
1935
- move(path, from, to) {
1936
- const next = readArray(path);
1937
- if (from < 0 || from >= next.length) return false;
1938
- const [item] = next.splice(from, 1);
1939
- const clampedTo = Math.max(0, Math.min(to, next.length));
1940
- next.splice(clampedTo, 0, item);
1941
- return writeArray(path, next, { kind: "move", from, to: clampedTo });
1942
- },
1943
- replace(path, index, value) {
1944
- const next = readArray(path);
1945
- if (index < 0 || index >= next.length) return false;
1946
- next[index] = value;
1947
- return writeArray(path, next, { kind: "replace-at", index });
1948
- }
1949
- };
1950
- }
1951
-
1952
1063
  const warnedNoScopeStores = /* @__PURE__ */ new WeakSet() ;
1953
1064
  function isErrorInputLike(value) {
1954
1065
  if (value instanceof Error) return true;
@@ -3522,7 +2633,7 @@ function mergeObjectKeys(target, source, path, schema) {
3522
2633
 
3523
2634
  async function runFactoryAndApply(st, factory) {
3524
2635
  try {
3525
- const value = await factory();
2636
+ const value = structuralSnapshot(await factory());
3526
2637
  if (st.hasPreprocessOrCoerce) walkAuthoredFromConstraints(value, [], st.authoredPaths);
3527
2638
  const full = mergeSparseHydration(
3528
2639
  toRaw(st.form.value),
@@ -3648,7 +2759,7 @@ function walkDuStubs(schema, value, path, warned) {
3648
2759
  function stripSymbolsDeep(value) {
3649
2760
  if (value === null || typeof value !== "object") return value;
3650
2761
  if (Array.isArray(value)) {
3651
- let mutated2 = false;
2762
+ let mutated2 = !consumerExtensible(value);
3652
2763
  const out2 = new Array(value.length);
3653
2764
  for (let i = 0; i < value.length; i++) {
3654
2765
  const original = readConsumerIndex(value, i);
@@ -3662,7 +2773,7 @@ function stripSymbolsDeep(value) {
3662
2773
  if (proto !== Object.prototype && proto !== null) return value;
3663
2774
  const symKeys = consumerSymbolKeys(value);
3664
2775
  const stringKeys = consumerKeys(value);
3665
- let mutated = symKeys.length > 0;
2776
+ let mutated = symKeys.length > 0 || !consumerExtensible(value);
3666
2777
  const out = {};
3667
2778
  const src = value;
3668
2779
  for (const k of stringKeys) {
@@ -4001,6 +3112,7 @@ function foldInteractionHistory(st, path, released) {
4001
3112
  blurredAfterInteraction || (blurredAfterInteraction = record.blurredAfterInteraction);
4002
3113
  }
4003
3114
  if (!touched && !interacted && !blurredAfterInteraction) return;
3115
+ st.noteReleased?.(released);
4004
3116
  for (let depth = path.length; depth >= 0; depth--) {
4005
3117
  const { key, segments } = keyForSegments(path.slice(0, depth));
4006
3118
  const current = st.fields.get(key);
@@ -4592,6 +3704,34 @@ function dispose(st) {
4592
3704
  function getValueAtPath(st, path) {
4593
3705
  return getAtPath(st.form.value, path);
4594
3706
  }
3707
+ function freezeBaseline(value) {
3708
+ if (Object.isFrozen(value)) return value;
3709
+ if (Array.isArray(value)) {
3710
+ for (const item of value) freezeBaseline(item);
3711
+ return Object.freeze(value);
3712
+ }
3713
+ if (isPlainRecord(value)) {
3714
+ for (const k of Object.keys(value)) freezeBaseline(safeOwnRead(value, k));
3715
+ return Object.freeze(value);
3716
+ }
3717
+ return value;
3718
+ }
3719
+ function getOriginalAtPath(st, path) {
3720
+ let node = st.baselineValue;
3721
+ for (let i = 0; i < path.length; i++) {
3722
+ const segment = path[i];
3723
+ if (Array.isArray(node)) {
3724
+ const at = typeof segment === "number" ? st.arrayIdentity.baselineIndexOf(path.slice(0, i), segment) : -1;
3725
+ if (at < 0) return void 0;
3726
+ node = node[at];
3727
+ } else if (isPlainRecord(node) && typeof segment === "string") {
3728
+ node = safeOwnRead(node, segment);
3729
+ } else {
3730
+ return void 0;
3731
+ }
3732
+ }
3733
+ return freezeBaseline(node);
3734
+ }
4595
3735
  const ERROR_SOURCES = ["schema", "user"];
4596
3736
  function createErrorCells(schema, pristine) {
4597
3737
  const raw = /* @__PURE__ */ new Map();
@@ -4677,7 +3817,7 @@ function captureStructure(st) {
4677
3817
  removed: [...st.removedPaths]
4678
3818
  };
4679
3819
  }
4680
- function restoreStructure(st, snapshot) {
3820
+ function restoreStructure(st, snapshot, remaps, returning) {
4681
3821
  const originals = new Map(snapshot.originals);
4682
3822
  const raw = toRaw(st.form.value);
4683
3823
  const held = /* @__PURE__ */ new Map();
@@ -4697,6 +3837,24 @@ function restoreStructure(st, snapshot) {
4697
3837
  st.removedPaths.set(key, segments);
4698
3838
  pulsed.push(segments);
4699
3839
  }
3840
+ for (const [segments, remap] of remaps) {
3841
+ migrateFieldRecords(st.fields, segments, remap, (path, released) => {
3842
+ let stamp = "";
3843
+ for (const { updatedAt } of released) {
3844
+ if (updatedAt !== null && updatedAt > stamp) stamp = updatedAt;
3845
+ }
3846
+ if (stamp !== "") eachAncestorOnce([path], (key, at) => raiseStamp(st, key, at, stamp));
3847
+ foldInteractionHistory(st, path, released);
3848
+ });
3849
+ }
3850
+ for (const record of returning) {
3851
+ st.fields.set(canonicalizePath(record.path).key, {
3852
+ ...record,
3853
+ connected: false,
3854
+ focused: null,
3855
+ blurred: null
3856
+ });
3857
+ }
4700
3858
  if (pulsed.length > 0) pulseStructure(st.structureSignal, pulsed);
4701
3859
  }
4702
3860
  function getErrorsForPath(st, path) {
@@ -4783,6 +3941,27 @@ function markInteracted(st, path) {
4783
3941
  if (st.fields.get(key)?.interacted === true) return;
4784
3942
  touchFieldRecord(st, key, path, { interacted: true });
4785
3943
  }
3944
+ function markBareContainers(st, segments, ladder) {
3945
+ const value = getAtPath(toRaw(st.form.value), segments);
3946
+ if (!isDescendable(value)) return false;
3947
+ const bare = [];
3948
+ diffAndApply(void 0, value, segments, (patch) => {
3949
+ if (isBarePatch(patch)) bare.push(patch.path);
3950
+ });
3951
+ eachAncestorOnce(bare, (key, path) => {
3952
+ const current = st.fields.get(key);
3953
+ if (current?.touched === true && (!ladder || current.interacted && current.blurredAfterInteraction)) {
3954
+ return;
3955
+ }
3956
+ touchFieldRecord(
3957
+ st,
3958
+ key,
3959
+ path,
3960
+ ladder ? { touched: true, interacted: true, blurredAfterInteraction: true } : { touched: true }
3961
+ );
3962
+ });
3963
+ return bare.length > 0;
3964
+ }
4786
3965
  function touchAtPath(st, segments) {
4787
3966
  const formValue = st.form.value;
4788
3967
  let touchedAny = false;
@@ -4794,6 +3973,7 @@ function touchAtPath(st, segments) {
4794
3973
  if (current?.touched === true) continue;
4795
3974
  touchFieldRecord(st, leafKey, entry.segments, { touched: true });
4796
3975
  }
3976
+ if (markBareContainers(st, segments, false)) touchedAny = true;
4797
3977
  if (!touchedAny && true) {
4798
3978
  console.warn(
4799
3979
  `[attaform] form.touch(): no fields resolved at path ${JSON.stringify(segments)}. Check the path matches an existing field or container.`
@@ -4818,6 +3998,7 @@ function interactAtPath(st, segments) {
4818
3998
  blurredAfterInteraction: true
4819
3999
  });
4820
4000
  }
4001
+ if (markBareContainers(st, segments, true)) interactedAny = true;
4821
4002
  if (!interactedAny && true) {
4822
4003
  console.warn(
4823
4004
  `[attaform] form.interact(): no fields resolved at path ${JSON.stringify(segments)}. Check the path matches an existing field or container.`
@@ -4864,14 +4045,31 @@ function adoptResolvedDefaults(st, value) {
4864
4045
  st.schema
4865
4046
  )
4866
4047
  );
4867
- seedOriginalsFromBaseline(
4868
- st,
4869
- computeBaseline(
4870
- st.schema,
4871
- st.defaultValues,
4872
- st.schema.getDefaultValues({ useDefaultSchemaValues: true })
4873
- )
4048
+ st.baselineValue = computeBaseline(
4049
+ st.schema,
4050
+ st.defaultValues,
4051
+ st.schema.getDefaultValues({ useDefaultSchemaValues: true })
4874
4052
  );
4053
+ seedOriginalsFromBaseline(st, st.baselineValue);
4054
+ st.arrayIdentity.rebaseline((segments) => holdsListAt(value, segments));
4055
+ const dropped = [];
4056
+ for (const [key, segments] of st.removedPaths) {
4057
+ if (st.originals.get(key)?.value !== void 0) continue;
4058
+ st.removedPaths.delete(key);
4059
+ dropped.push(segments);
4060
+ }
4061
+ if (dropped.length > 0) pulseStructure(st.structureSignal, dropped);
4062
+ }
4063
+ function holdsListAt(value, segments) {
4064
+ let node = value;
4065
+ for (const segment of segments) {
4066
+ if (Array.isArray(node)) return true;
4067
+ if (!isPlainRecord(node) || typeof segment !== "string" || !safeOwnHas(node, segment)) {
4068
+ return false;
4069
+ }
4070
+ node = safeOwnRead(node, segment);
4071
+ }
4072
+ return Array.isArray(node);
4875
4073
  }
4876
4074
  function reset(st, nextDefaultValues) {
4877
4075
  const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
@@ -4882,7 +4080,7 @@ function reset(st, nextDefaultValues) {
4882
4080
  st.defaultValues = structuralSnapshot(resetSource);
4883
4081
  const next = computeBaseline(
4884
4082
  st.schema,
4885
- resetSource,
4083
+ st.defaultValues,
4886
4084
  st.schema.getDefaultValues({ useDefaultSchemaValues: true })
4887
4085
  );
4888
4086
  rebuildAuthoredPaths(st, resetSource, next);
@@ -4892,13 +4090,14 @@ function reset(st, nextDefaultValues) {
4892
4090
  for (const key of mentioned) st.originalBlankPaths.delete(key);
4893
4091
  }
4894
4092
  const now = writeInstant(st);
4895
- applyFormReplacementWithPath(st, next, void 0, null, now);
4896
- st.arrayIdentity.rebaselineAll();
4093
+ applyFormReplacementWithPath(st, structuralSnapshot(next), void 0, null, now);
4094
+ st.arrayIdentity.rebaseline(() => true);
4897
4095
  if (st.removedPaths.size > 0) {
4898
4096
  const cleared = [...st.removedPaths.values()];
4899
4097
  st.removedPaths.clear();
4900
4098
  pulseStructure(st.structureSignal, cleared);
4901
4099
  }
4100
+ st.baselineValue = next;
4902
4101
  seedOriginalsFromBaseline(st, next);
4903
4102
  st.blankPaths.clear();
4904
4103
  for (const key of st.originalBlankPaths) {
@@ -5261,6 +4460,8 @@ function createFormStore(options) {
5261
4460
  // the literal they passed from mutating the form's defaults from outside.
5262
4461
  // `reset()` snapshots for a harder reason, where an alias IS reachable.
5263
4462
  defaultValues: ownDefaultValues,
4463
+ // The form holds a copy of it, or the hydration payload.
4464
+ baselineValue: schemaInitialData,
5264
4465
  ssrPrefetch,
5265
4466
  rememberVariants,
5266
4467
  fieldValidationMode,
@@ -5298,6 +4499,7 @@ function createFormStore(options) {
5298
4499
  applyFormReplacement: bind(applyFormReplacement),
5299
4500
  setValueAtPath: bind(setValueAtPath),
5300
4501
  getValueAtPath: bind(getValueAtPath),
4502
+ getOriginalAtPath: bind(getOriginalAtPath),
5301
4503
  arrayElementKey: bind(arrayElementKey),
5302
4504
  reset: bind(reset),
5303
4505
  resetField: bind(resetField),
@@ -7262,4 +6464,4 @@ function escapeForInlineScript(json) {
7262
6464
  });
7263
6465
  }
7264
6466
 
7265
- export { AttaformErrorCode as A, injectWizard as a, isUnset as b, useAbstractForm as c, useRegister as d, escapeForInlineScript as e, useWizard as f, gate as g, getAtPath as h, injectForm as i, humanize as j, isPlainRecord as k, lazy as l, slimKindOf as s, unset as u };
6467
+ export { injectWizard as a, isUnset as b, useAbstractForm as c, useRegister as d, escapeForInlineScript as e, useWizard as f, gate as g, humanize as h, injectForm as i, lazy as l, slimKindOf as s, unset as u };