attaform 0.22.0 → 0.23.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 (101) hide show
  1. package/README.md +7 -10
  2. package/dist/chunks/dev-key-collision-warnings.cjs +0 -33
  3. package/dist/chunks/dev-key-collision-warnings.cjs.map +1 -1
  4. package/dist/chunks/dev-key-collision-warnings.mjs +1 -33
  5. package/dist/chunks/dev-key-collision-warnings.mjs.map +1 -1
  6. package/dist/chunks/devtools.cjs +3 -5
  7. package/dist/chunks/devtools.cjs.map +1 -1
  8. package/dist/chunks/devtools.mjs +3 -5
  9. package/dist/chunks/devtools.mjs.map +1 -1
  10. package/dist/chunks/fingerprint2.cjs +1 -1
  11. package/dist/chunks/fingerprint2.mjs +1 -1
  12. package/dist/index.cjs +3 -5
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +6 -41
  15. package/dist/index.d.mts +6 -41
  16. package/dist/index.d.ts +6 -41
  17. package/dist/index.mjs +5 -5
  18. package/dist/nuxt.d.cts +1 -1
  19. package/dist/nuxt.d.mts +1 -1
  20. package/dist/nuxt.d.ts +1 -1
  21. package/dist/runtime/components/AttaformDevtoolsPanel.vue +3 -11
  22. package/dist/runtime/plugins/attaform.cjs +2 -2
  23. package/dist/runtime/plugins/attaform.mjs +2 -2
  24. package/dist/shared/{attaform.BGwNZ9GV.d.cts → attaform.BGMRvckW.d.ts} +10 -77
  25. package/dist/shared/{attaform.DvUH4a3o.d.ts → attaform.BJnNK75Y.d.cts} +45 -670
  26. package/dist/shared/{attaform.DvUH4a3o.d.mts → attaform.BJnNK75Y.d.mts} +45 -670
  27. package/dist/shared/{attaform.DvUH4a3o.d.cts → attaform.BJnNK75Y.d.ts} +45 -670
  28. package/dist/shared/{attaform.BKFwekY2.mjs → attaform.BhI9Icek.mjs} +3 -287
  29. package/dist/shared/attaform.BhI9Icek.mjs.map +1 -0
  30. package/dist/shared/{attaform.CRzpFCjV.cjs → attaform.BibT5AS_.cjs} +2 -2
  31. package/dist/shared/{attaform.CRzpFCjV.cjs.map → attaform.BibT5AS_.cjs.map} +1 -1
  32. package/dist/shared/{attaform.DkA5J8NW.d.cts → attaform.CO0e7YVY.d.cts} +1 -46
  33. package/dist/shared/{attaform.DkA5J8NW.d.ts → attaform.CO0e7YVY.d.mts} +1 -46
  34. package/dist/shared/{attaform.DkA5J8NW.d.mts → attaform.CO0e7YVY.d.ts} +1 -46
  35. package/dist/shared/{attaform.Q3eAD2wD.cjs → attaform.CaYj3ZfY.cjs} +3 -3
  36. package/dist/shared/{attaform.Q3eAD2wD.cjs.map → attaform.CaYj3ZfY.cjs.map} +1 -1
  37. package/dist/shared/{attaform.AyujQoHp.cjs → attaform.Cmb_LCie.cjs} +4 -4
  38. package/dist/shared/{attaform.DNuiFCXG.mjs.map → attaform.Cmb_LCie.cjs.map} +1 -1
  39. package/dist/shared/{attaform.CsB-iKbU.mjs → attaform.CtJOd7ox.mjs} +81 -591
  40. package/dist/shared/attaform.CtJOd7ox.mjs.map +1 -0
  41. package/dist/shared/{attaform.DgCfLqay.mjs → attaform.CzVta5o2.mjs} +4 -4
  42. package/dist/shared/attaform.CzVta5o2.mjs.map +1 -0
  43. package/dist/shared/{attaform.FN0vaQAg.d.mts → attaform.D52oJiYC.d.cts} +1 -1
  44. package/dist/shared/{attaform.aekT7mMx.d.cts → attaform.DCkSNnPr.d.mts} +1 -1
  45. package/dist/shared/{attaform.01iKS_lz.cjs → attaform.Db4E4IW6.cjs} +2 -294
  46. package/dist/shared/attaform.Db4E4IW6.cjs.map +1 -0
  47. package/dist/shared/{attaform.C-RtnCJM.cjs → attaform.DbyTD8N2.cjs} +4 -4
  48. package/dist/shared/attaform.DbyTD8N2.cjs.map +1 -0
  49. package/dist/shared/{attaform.DCjgGir_.mjs → attaform.Dd1Kmmaj.mjs} +3 -3
  50. package/dist/shared/{attaform.DCjgGir_.mjs.map → attaform.Dd1Kmmaj.mjs.map} +1 -1
  51. package/dist/shared/{attaform.D4XYaasQ.d.ts → attaform.DrY8srOp.d.mts} +10 -77
  52. package/dist/shared/{attaform.CjMcwV7W.cjs → attaform.DsQkXE3o.cjs} +79 -599
  53. package/dist/shared/attaform.DsQkXE3o.cjs.map +1 -0
  54. package/dist/shared/{attaform.CCCeEPwa.d.mts → attaform.DuPneYR0.d.cts} +10 -77
  55. package/dist/shared/{attaform.6xE0Lcfd.mjs → attaform.Dx9-QQE2.mjs} +2 -2
  56. package/dist/shared/{attaform.6xE0Lcfd.mjs.map → attaform.Dx9-QQE2.mjs.map} +1 -1
  57. package/dist/shared/{attaform.DUMWQefY.d.ts → attaform.WEwfXcHq.d.ts} +1 -1
  58. package/dist/shared/{attaform.DNuiFCXG.mjs → attaform.alpG7rT7.mjs} +4 -4
  59. package/dist/shared/{attaform.AyujQoHp.cjs.map → attaform.alpG7rT7.mjs.map} +1 -1
  60. package/dist/zod-v3.cjs +2 -2
  61. package/dist/zod-v3.d.cts +3 -3
  62. package/dist/zod-v3.d.mts +3 -3
  63. package/dist/zod-v3.d.ts +3 -3
  64. package/dist/zod-v3.mjs +2 -2
  65. package/dist/zod-v4.cjs +2 -2
  66. package/dist/zod-v4.d.cts +5 -5
  67. package/dist/zod-v4.d.mts +5 -5
  68. package/dist/zod-v4.d.ts +5 -5
  69. package/dist/zod-v4.mjs +2 -2
  70. package/dist/zod.cjs +5 -5
  71. package/dist/zod.d.cts +5 -5
  72. package/dist/zod.d.mts +5 -5
  73. package/dist/zod.d.ts +5 -5
  74. package/dist/zod.mjs +5 -5
  75. package/package.json +1 -1
  76. package/dist/chunks/indexeddb.cjs +0 -119
  77. package/dist/chunks/indexeddb.cjs.map +0 -1
  78. package/dist/chunks/indexeddb.mjs +0 -117
  79. package/dist/chunks/indexeddb.mjs.map +0 -1
  80. package/dist/chunks/local-storage.cjs +0 -58
  81. package/dist/chunks/local-storage.cjs.map +0 -1
  82. package/dist/chunks/local-storage.mjs +0 -56
  83. package/dist/chunks/local-storage.mjs.map +0 -1
  84. package/dist/chunks/multi-tab-sync.cjs +0 -367
  85. package/dist/chunks/multi-tab-sync.cjs.map +0 -1
  86. package/dist/chunks/multi-tab-sync.mjs +0 -364
  87. package/dist/chunks/multi-tab-sync.mjs.map +0 -1
  88. package/dist/chunks/session-storage.cjs +0 -58
  89. package/dist/chunks/session-storage.cjs.map +0 -1
  90. package/dist/chunks/session-storage.mjs +0 -56
  91. package/dist/chunks/session-storage.mjs.map +0 -1
  92. package/dist/chunks/wire-persistence.cjs +0 -396
  93. package/dist/chunks/wire-persistence.cjs.map +0 -1
  94. package/dist/chunks/wire-persistence.mjs +0 -394
  95. package/dist/chunks/wire-persistence.mjs.map +0 -1
  96. package/dist/shared/attaform.01iKS_lz.cjs.map +0 -1
  97. package/dist/shared/attaform.BKFwekY2.mjs.map +0 -1
  98. package/dist/shared/attaform.C-RtnCJM.cjs.map +0 -1
  99. package/dist/shared/attaform.CjMcwV7W.cjs.map +0 -1
  100. package/dist/shared/attaform.CsB-iKbU.mjs.map +0 -1
  101. package/dist/shared/attaform.DgCfLqay.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, isRef, toValue, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
2
- import { q as pathsEqual, l as isPathPrefix, _ as __DEV__, a as canonicalizePath, s as segmentsForPathKey, F as FORM_ERRORS_PATH_KEY, r as keyForSegments, S as SubmitErrorHandlerError, t as toError, A as AnonPersistError, w as INTERACTIVE_TAG_NAMES, x as getOrAssignElementId, R as ROOT_PATH, y as allowSensitivePersist, z as FORM_ERRORS_PATH, e as ROOT_PATH_KEY, B as segmentsToDotted, C as coerceToPathKey, E as isSensitivePath, G as createPersistOptInRegistry, d as InvalidUseFormConfigError, H as ensureAttaformInstalled, u as useRegistry, J as kFormContext, K as kFormInstanceId, h as ReservedFormKeyError, L as createIsSensitivePath, M as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, k as kAttaformWizardActiveStepResolver, N as kAttaformAncestorWizard } from './attaform.BKFwekY2.mjs';
1
+ import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
2
+ import { o as pathsEqual, j as isPathPrefix, _ as __DEV__, a as canonicalizePath, s as segmentsForPathKey, F as FORM_ERRORS_PATH_KEY, q as keyForSegments, S as SubmitErrorHandlerError, t as toError, r as INTERACTIVE_TAG_NAMES, R as ROOT_PATH, w as FORM_ERRORS_PATH, d as ROOT_PATH_KEY, x as coerceToPathKey, b as InvalidUseFormConfigError, y as ensureAttaformInstalled, u as useRegistry, z as kFormContext, B as kFormInstanceId, f as ReservedFormKeyError, C as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, k as kAttaformWizardActiveStepResolver, D as kAttaformAncestorWizard } from './attaform.BhI9Icek.mjs';
3
3
 
4
4
  function safeAssign(target, key, value) {
5
5
  if (key === "__proto__") {
@@ -640,9 +640,7 @@ function makeBlankRequiredError(segments, formKey) {
640
640
  }
641
641
 
642
642
  const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
643
- const DEFAULT_PERSISTENCE_DEBOUNCE_MS = 300;
644
643
  const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
645
- const PERSISTENCE_KEY_PREFIX = "attaform:";
646
644
  const RESERVED_KEY_PREFIX = "__atta:";
647
645
  const ANONYMOUS_FORM_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon:`;
648
646
  const ANONYMOUS_WIZARD_KEY_PREFIX = `${RESERVED_KEY_PREFIX}anon-wizard:`;
@@ -1513,9 +1511,8 @@ function buildFieldArrayApi(state) {
1513
1511
  return Array.isArray(current) ? current.slice() : [];
1514
1512
  }
1515
1513
  function writeArray(path, next, arrayOp) {
1516
- const { segments, key } = canonicalizePath(path);
1514
+ const { segments } = canonicalizePath(path);
1517
1515
  const meta = {
1518
- persist: state.persistOptIns.hasAnyOptInForPath(key),
1519
1516
  ...arrayOp !== void 0 ? { arrayOp } : {}
1520
1517
  };
1521
1518
  return state.setValueAtPath(segments, next, meta);
@@ -1737,121 +1734,6 @@ function walk$1(value, basePath, schema, snapshotFieldStateAt) {
1737
1734
  return result;
1738
1735
  }
1739
1736
 
1740
- const PERSISTENCE_MODULE_KEY = "persistence";
1741
- async function getStorageAdapter(storage) {
1742
- if (typeof storage === "object") return storage;
1743
- switch (storage) {
1744
- case "local": {
1745
- const { createLocalStorageAdapter } = await import('../chunks/local-storage.mjs');
1746
- return createLocalStorageAdapter();
1747
- }
1748
- case "session": {
1749
- const { createSessionStorageAdapter } = await import('../chunks/session-storage.mjs');
1750
- return createSessionStorageAdapter();
1751
- }
1752
- case "indexeddb": {
1753
- const { createIndexedDbAdapter } = await import('../chunks/indexeddb.mjs');
1754
- return createIndexedDbAdapter();
1755
- }
1756
- }
1757
- }
1758
- function resolveStorageKeyBase(config, formKey) {
1759
- return config.key ?? `${PERSISTENCE_KEY_PREFIX}${formKey}`;
1760
- }
1761
- async function removeMatchingKeys(adapter, base, keepKey) {
1762
- let keys;
1763
- try {
1764
- keys = await adapter.listKeys(base);
1765
- } catch {
1766
- return;
1767
- }
1768
- for (const key of keys) {
1769
- if (key === keepKey) continue;
1770
- if (key === base || key.startsWith(`${base}:`)) {
1771
- void adapter.removeItem(key).catch(() => void 0);
1772
- }
1773
- }
1774
- }
1775
- async function cleanupOrphanKeys(adapter, base, currentKey) {
1776
- await removeMatchingKeys(adapter, base, currentKey);
1777
- }
1778
- const STANDARD_STORAGE_KINDS = ["local", "session", "indexeddb"];
1779
- function normalizePersistConfig(input) {
1780
- if (typeof input === "string") return { storage: input };
1781
- if ("storage" in input) return input;
1782
- return { storage: input };
1783
- }
1784
- async function sweepAllOrphansAcrossStandardStores(base) {
1785
- for (const kind of STANDARD_STORAGE_KINDS) {
1786
- try {
1787
- const adapter = await getStorageAdapter(kind);
1788
- await removeMatchingKeys(adapter, base);
1789
- } catch {
1790
- }
1791
- }
1792
- }
1793
- async function sweepNonConfiguredStandardStoresForOrphans(configured, base) {
1794
- const configuredKind = typeof configured === "string" ? configured : null;
1795
- for (const kind of STANDARD_STORAGE_KINDS) {
1796
- if (kind === configuredKind) continue;
1797
- try {
1798
- const adapter = await getStorageAdapter(kind);
1799
- await removeMatchingKeys(adapter, base);
1800
- } catch {
1801
- }
1802
- }
1803
- }
1804
- function mergeSparseHydration(schemaDefaults, sparse, schema) {
1805
- return mergeDeep(schemaDefaults, sparse, [], schema);
1806
- }
1807
- function mergeDeep(target, source, path, schema) {
1808
- if (source === void 0) return target;
1809
- if (source === null || typeof source !== "object") return source;
1810
- if (Array.isArray(source)) return source;
1811
- if (!isPlainRecord(source)) return source;
1812
- if (schema !== void 0) {
1813
- const du = schema.getUnionDiscriminatorAtPath(path);
1814
- if (du !== void 0) return mergeDuAwareKeys(source, path, schema, du);
1815
- }
1816
- return mergeObjectKeys(target, source, path, schema);
1817
- }
1818
- function mergeDuAwareKeys(source, path, schema, du) {
1819
- const sourceDisc = source[du.discriminatorKey];
1820
- if (sourceDisc !== void 0 && !du.isVariantSelected(sourceDisc)) {
1821
- return { [du.discriminatorKey]: sourceDisc };
1822
- }
1823
- if (sourceDisc !== void 0) {
1824
- const variantDefault = du.getVariantDefault(sourceDisc);
1825
- if (isPlainRecord(variantDefault)) {
1826
- return mergeVariantKeys(source, variantDefault, path, schema, du);
1827
- }
1828
- }
1829
- return {};
1830
- }
1831
- function mergeVariantKeys(source, variantDefault, path, schema, du) {
1832
- const out = { ...variantDefault };
1833
- for (const key of Object.keys(source)) {
1834
- if (!safeOwnHas(variantDefault, key) && key !== du.discriminatorKey) continue;
1835
- safeAssign(
1836
- out,
1837
- key,
1838
- mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
1839
- );
1840
- }
1841
- return out;
1842
- }
1843
- function mergeObjectKeys(target, source, path, schema) {
1844
- const out = isPlainRecord(target) ? { ...target } : {};
1845
- for (const key of Object.keys(source)) {
1846
- safeAssign(
1847
- out,
1848
- key,
1849
- mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
1850
- );
1851
- }
1852
- return out;
1853
- }
1854
-
1855
1737
  const warnedNoScopeStores = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
1856
1738
  function buildProcessForm(state, formInstanceId, options = {}) {
1857
1739
  const invalidPolicy = options.onInvalidSubmit ?? "focus-first-error";
@@ -2109,44 +1991,6 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
2109
1991
  target.element.focus({ preventScroll: true });
2110
1992
  }
2111
1993
 
2112
- function captureUserCallSite() {
2113
- const raw = new Error().stack;
2114
- if (typeof raw !== "string") return void 0;
2115
- const lines = raw.split("\n");
2116
- for (let i = 1; i < lines.length; i++) {
2117
- const frame = lines[i];
2118
- if (frame === void 0) continue;
2119
- if (/attaform[/-]forms?/i.test(frame)) continue;
2120
- if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
2121
- const trimmed = frame.trim();
2122
- if (trimmed.length === 0) continue;
2123
- return shortenSourceFrame(trimmed);
2124
- }
2125
- return void 0;
2126
- }
2127
- function shortenSourceFrame(frame) {
2128
- const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
2129
- if (match === null) return frame;
2130
- const [, urlOrPath, line] = match;
2131
- if (urlOrPath === void 0 || line === void 0) return frame;
2132
- let path = urlOrPath;
2133
- path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
2134
- path = path.replace(/^_nuxt\//, "");
2135
- path = path.replace(/^\//, "");
2136
- return `(${path}:${line})`;
2137
- }
2138
-
2139
- function extractSchemaFields(schema) {
2140
- try {
2141
- const root = schema.getDefaultAtPath([]);
2142
- if (root !== null && typeof root === "object" && !Array.isArray(root)) {
2143
- return Object.keys(root);
2144
- }
2145
- } catch {
2146
- }
2147
- return [];
2148
- }
2149
-
2150
1994
  const warnedRejections = __DEV__ ? /* @__PURE__ */ new WeakMap() : null;
2151
1995
  function shouldWarnOnce$1(store, key) {
2152
1996
  if (warnedRejections === null) return false;
@@ -2476,16 +2320,7 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2476
2320
  const slimTypes = state.schema.getSlimPrimitiveTypesAtPath(segments);
2477
2321
  const acceptsUndefined = slimTypes.has("undefined");
2478
2322
  const acceptsString = slimTypes.has("string");
2479
- const persist = options?.persist === true;
2480
- const acknowledgeSensitive = options?.acknowledgeSensitive === true;
2481
- const multiTab = options?.multiTab !== false;
2482
2323
  const transforms = options?.transforms ?? EMPTY_TRANSFORMS;
2483
- const markNoSync = !multiTab ? () => {
2484
- state.incrementNoSyncOptOut(pathKey);
2485
- } : void 0;
2486
- const unmarkNoSync = !multiTab ? () => {
2487
- state.decrementNoSyncOptOut(pathKey);
2488
- } : void 0;
2489
2324
  const coerce = buildCoerceFn(
2490
2325
  state.schema,
2491
2326
  segments,
@@ -2496,18 +2331,10 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2496
2331
  segments,
2497
2332
  coerceIndex
2498
2333
  );
2499
- if (persist && !state.ssr && !state.modules.has(PERSISTENCE_MODULE_KEY)) {
2500
- throw new AnonPersistError({
2501
- cause: "register-without-config",
2502
- schemaFields: extractSchemaFields(state.schema),
2503
- callSite: captureUserCallSite()
2504
- });
2505
- }
2506
2334
  const { aria } = computeFieldIdentity(formInstanceId, state.formKey, pathKey);
2507
2335
  const isRequired = state.schema.isRequiredAtPath(segments);
2508
2336
  const ariaEnabled = options?.autoAria ?? formAutoAria;
2509
2337
  const ariaDisplayState = getDisplayStateAt !== void 0 ? computed(() => getDisplayStateAt(segments)) : void 0;
2510
- let boundElement = null;
2511
2338
  const internalRv = {
2512
2339
  innerRef,
2513
2340
  displayValue,
@@ -2517,8 +2344,7 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2517
2344
  segments,
2518
2345
  slimDefault,
2519
2346
  withInstanceMeta({
2520
- blank: true,
2521
- persist
2347
+ blank: true
2522
2348
  })
2523
2349
  );
2524
2350
  },
@@ -2526,7 +2352,6 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2526
2352
  state.markInteracted(segments);
2527
2353
  },
2528
2354
  registerElement: (element) => {
2529
- boundElement = element;
2530
2355
  if (!INTERACTIVE_TAG_NAMES.has(element.tagName)) return;
2531
2356
  const added = state.registerElement(segments, element, formInstanceId);
2532
2357
  if (added) attachFocusListeners(state, segments, element, instanceMeta);
@@ -2534,11 +2359,9 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2534
2359
  deregisterElement: (element) => {
2535
2360
  detachFocusListeners(element);
2536
2361
  state.deregisterElement(segments, element);
2537
- if (boundElement === element) boundElement = null;
2538
2362
  },
2539
2363
  setValueWithInternalPath: (value, meta) => {
2540
- const resolvedMeta = meta === void 0 && boundElement !== null ? { persist: state.persistOptIns.hasOptIn(getOrAssignElementId(boundElement), pathKey) } : meta;
2541
- return state.setValueAtPath(segments, value, withInstanceMeta(resolvedMeta));
2364
+ return state.setValueAtPath(segments, value, withInstanceMeta(meta));
2542
2365
  },
2543
2366
  // Called by the `vRegisterHint` compile-time transform's wrapping
2544
2367
  // IIFE on every server-side render of `<element v-register="…">`.
@@ -2576,15 +2399,6 @@ function buildRegister(state, formInstanceId, instanceConfig) {
2576
2399
  segments: Object.freeze(segments.slice()),
2577
2400
  formKey: state.formKey,
2578
2401
  formInstanceId,
2579
- // --- Persistence opt-in (internal; the directive is the only
2580
- // legitimate consumer) ---
2581
- persist,
2582
- acknowledgeSensitive,
2583
- persistOptIns: state.persistOptIns,
2584
- isSensitivePath: state.isSensitivePath,
2585
- multiTab,
2586
- ...markNoSync !== void 0 ? { markNoSync } : {},
2587
- ...unmarkNoSync !== void 0 ? { unmarkNoSync } : {},
2588
2402
  transforms,
2589
2403
  coerce,
2590
2404
  ...coerceElement !== void 0 ? { coerceElement } : {},
@@ -3021,12 +2835,10 @@ function buildFormApi(state, formInstanceId, options = {}) {
3021
2835
  const segments = canonicalizePath(pathInput).segments;
3022
2836
  return computed(() => getAtPath(state.form.value, segments));
3023
2837
  }
3024
- function setValueImpl(pathOrValue, maybeValue, maybeOptions) {
2838
+ function setValueImpl(pathOrValue, maybeValue) {
3025
2839
  const argc = arguments.length;
3026
2840
  const isPathForm = argc >= 2 && (typeof pathOrValue === "string" || Array.isArray(pathOrValue));
3027
- const options2 = isPathForm ? maybeOptions : argc >= 2 ? maybeValue : void 0;
3028
- const silent = options2?.silent === true;
3029
- const writeMeta = (extra) => withInstanceMeta(silent ? { ...extra, silent: true } : extra);
2841
+ const writeMeta = (extra) => withInstanceMeta(extra);
3030
2842
  if (!isPathForm) {
3031
2843
  const next = typeof pathOrValue === "function" ? pathOrValue(structuralSnapshot(state.form.value)) : pathOrValue;
3032
2844
  const walked2 = walkUnsetSentinels(
@@ -3318,7 +3130,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
3318
3130
  instanceId: formInstanceId
3319
3131
  })
3320
3132
  );
3321
- const persistenceHandle = state.modules.get(PERSISTENCE_MODULE_KEY);
3322
3133
  const reset = (nextDefaultValues) => {
3323
3134
  if (nextDefaultValues === void 0) {
3324
3135
  state.reset();
@@ -3333,16 +3144,10 @@ function buildFormApi(state, formInstanceId, options = {}) {
3333
3144
  state.originalBlankPaths.add(pathKey);
3334
3145
  }
3335
3146
  }
3336
- if (persistenceHandle !== void 0) {
3337
- void persistenceHandle.ready.then((m) => m?.clearPersistedDraft()).catch(() => void 0);
3338
- }
3339
3147
  };
3340
3148
  const resetField = (pathInput) => {
3341
3149
  const segments = canonicalizePath(pathInput).segments;
3342
3150
  state.resetField(segments);
3343
- if (persistenceHandle !== void 0) {
3344
- void persistenceHandle.ready.then((m) => m?.clearPersistedDraft(segments)).catch(() => void 0);
3345
- }
3346
3151
  };
3347
3152
  function clear(pathInput) {
3348
3153
  if (pathInput === void 0) {
@@ -3350,31 +3155,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
3350
3155
  }
3351
3156
  return setValueImpl(pathInput, unset);
3352
3157
  }
3353
- const persist = async (pathInput, options2) => {
3354
- const segments = canonicalizePath(pathInput).segments;
3355
- if (!allowSensitivePersist(
3356
- segments,
3357
- options2?.acknowledgeSensitive === true,
3358
- state.isSensitivePath
3359
- )) {
3360
- return;
3361
- }
3362
- if (persistenceHandle === void 0) return;
3363
- const persistence = await persistenceHandle.ready;
3364
- if (persistence === void 0) return;
3365
- await persistence.writePathImmediately(segments);
3366
- };
3367
- const clearPersistedDraft = async (pathInput) => {
3368
- if (persistenceHandle === void 0) return;
3369
- const persistence = await persistenceHandle.ready;
3370
- if (persistence === void 0) return;
3371
- if (pathInput === void 0) {
3372
- await persistence.clearPersistedDraft();
3373
- return;
3374
- }
3375
- const segments = canonicalizePath(pathInput).segments;
3376
- await persistence.clearPersistedDraft(segments);
3377
- };
3378
3158
  function touch(pathInput) {
3379
3159
  const segments = pathInput === void 0 ? ROOT_PATH : canonicalizePath(pathInput).segments;
3380
3160
  state.touchAtPath(segments);
@@ -3459,18 +3239,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
3459
3239
  }
3460
3240
  return Object.freeze(out);
3461
3241
  }
3462
- const formHandle = {
3463
- current: void 0
3464
- };
3465
- function onChangeImpl(a, b, c) {
3466
- const sourced = typeof b === "function";
3467
- const source = sourced ? a : void 0;
3468
- const handler = sourced ? b : a;
3469
- const options2 = sourced ? c : b;
3470
- const stop = state.registerOnChange(source, handler, options2, () => formHandle.current);
3471
- if (getCurrentScope() !== void 0) onScopeDispose(stop);
3472
- return stop;
3473
- }
3474
3242
  const api = {
3475
3243
  handleSubmit: gated(handleSubmit),
3476
3244
  // Callable readonly Proxies (`values`, `fields`, `errors`) and the
@@ -3536,8 +3304,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
3536
3304
  reset: gated(reset),
3537
3305
  resetField: gated(resetField),
3538
3306
  clear: gated(clear),
3539
- persist: gated(persist),
3540
- clearPersistedDraft: gated(clearPersistedDraft),
3541
3307
  focusFirstError: gated(focusFirstError),
3542
3308
  scrollToFirstError: gated(scrollToFirstError),
3543
3309
  applyInvalidSubmitPolicy: gated(applyInvalidSubmitPolicyPublic),
@@ -3558,10 +3324,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
3558
3324
  get blankPaths() {
3559
3325
  void state.activate();
3560
3326
  return blankPathsView;
3561
- },
3562
- onChange: onChangeImpl
3327
+ }
3563
3328
  };
3564
- formHandle.current = api;
3565
3329
  return api;
3566
3330
  }
3567
3331
 
@@ -4073,168 +3837,55 @@ function createArrayBookkeeping(deps) {
4073
3837
  };
4074
3838
  }
4075
3839
 
4076
- const NOOP_STOP = () => {
4077
- };
4078
- function isThenable(value) {
4079
- return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
4080
- }
4081
- function isSuppressed(meta) {
4082
- return meta?.hydration === true || meta?.crossTab === true || meta?.silent === true;
4083
- }
4084
- function canonicalizeSourceList(raw) {
4085
- const list = typeof raw === "string" ? [raw] : raw;
4086
- const out = [];
4087
- const seen = /* @__PURE__ */ new Set();
4088
- for (const entry of list) {
4089
- const { segments, key } = canonicalizePath(entry);
4090
- if (seen.has(key)) continue;
4091
- seen.add(key);
4092
- out.push({ segments, key, dotted: segmentsToDotted(segments) });
4093
- }
4094
- return out;
3840
+ function mergeSparseHydration(schemaDefaults, sparse, schema) {
3841
+ return mergeDeep(schemaDefaults, sparse, [], schema);
4095
3842
  }
4096
- function makeResolver(source) {
4097
- if (source === void 0) {
4098
- const root = [{ segments: ROOT_PATH, key: ROOT_PATH_KEY, dotted: "" }];
4099
- return () => root;
4100
- }
4101
- if (typeof source !== "function" && !isRef(source)) {
4102
- const fixed = canonicalizeSourceList(source);
4103
- return () => fixed;
3843
+ function mergeDeep(target, source, path, schema) {
3844
+ if (source === void 0) return target;
3845
+ if (source === null || typeof source !== "object") return source;
3846
+ if (Array.isArray(source)) return source;
3847
+ if (!isPlainRecord(source)) return source;
3848
+ if (schema !== void 0) {
3849
+ const du = schema.getUnionDiscriminatorAtPath(path);
3850
+ if (du !== void 0) return mergeDuAwareKeys(source, path, schema, du);
4104
3851
  }
4105
- return () => canonicalizeSourceList(toValue(source));
3852
+ return mergeObjectKeys(target, source, path, schema);
4106
3853
  }
4107
- function createOnChangeRegistry(deps) {
4108
- const handlers = /* @__PURE__ */ new Set();
4109
- function isCurrent(reg, key, token) {
4110
- return reg.runs.get(key)?.token === token;
4111
- }
4112
- function routeError(reg, error, source, changed, value, previous, attempt, token) {
4113
- if (reg.onError === void 0) {
4114
- if (__DEV__) {
4115
- console.error(
4116
- `[attaform] onChange handler threw for path '${source.dotted}' \u2014 error swallowed. Pass { onError } to handle it. Original error:`,
4117
- error
4118
- );
4119
- }
4120
- return;
4121
- }
4122
- const retry = () => {
4123
- if (!isCurrent(reg, source.key, token)) return;
4124
- runHandler(reg, source, changed, value, previous, attempt + 1);
4125
- };
4126
- const errCtx = {
4127
- path: source.dotted,
4128
- value,
4129
- attempt,
4130
- retry,
4131
- form: reg.getForm()
4132
- };
4133
- try {
4134
- reg.onError(error, errCtx);
4135
- } catch (err) {
4136
- if (__DEV__) console.error("[attaform] onChange onError threw:", err);
4137
- }
4138
- }
4139
- function runHandler(reg, source, changed, value, previous, attempt) {
4140
- const prior = reg.runs.get(source.key);
4141
- if (prior) prior.controller.abort();
4142
- const controller = new AbortController();
4143
- const token = ++reg.seq;
4144
- reg.runs.set(source.key, { token, controller });
4145
- const ctx = {
4146
- path: source.dotted,
4147
- previous,
4148
- signal: controller.signal,
4149
- attempt,
4150
- form: reg.getForm(),
4151
- changed
4152
- };
4153
- let result;
4154
- try {
4155
- result = reg.handler(value, ctx);
4156
- } catch (error) {
4157
- routeError(reg, error, source, changed, value, previous, attempt, token);
4158
- return;
4159
- }
4160
- if (isThenable(result)) {
4161
- result.then(void 0, (error) => {
4162
- if (isCurrent(reg, source.key, token)) {
4163
- routeError(reg, error, source, changed, value, previous, attempt, token);
4164
- }
4165
- });
4166
- }
3854
+ function mergeDuAwareKeys(source, path, schema, du) {
3855
+ const sourceDisc = source[du.discriminatorKey];
3856
+ if (sourceDisc !== void 0 && !du.isVariantSelected(sourceDisc)) {
3857
+ return { [du.discriminatorKey]: sourceDisc };
4167
3858
  }
4168
- function dispatch(patches, meta) {
4169
- if (handlers.size === 0 || isSuppressed(meta)) return;
4170
- for (const reg of handlers) {
4171
- let sources;
4172
- try {
4173
- sources = reg.resolve();
4174
- } catch (error) {
4175
- if (__DEV__) console.error("[attaform] onChange source getter threw:", error);
4176
- continue;
4177
- }
4178
- for (const source of sources) {
4179
- let changed;
4180
- for (const patch of patches) {
4181
- if (isPathPrefix(source.segments, patch.path) || isPathPrefix(patch.path, source.segments)) {
4182
- (changed ?? (changed = [])).push(segmentsToDotted(patch.path));
4183
- }
4184
- }
4185
- if (changed === void 0) continue;
4186
- const value = deps.getValueAtPath(source.segments);
4187
- const previous = reg.previous.has(source.key) ? reg.previous.get(source.key) : value;
4188
- reg.previous.set(source.key, value);
4189
- runHandler(reg, source, changed, value, previous, 0);
4190
- }
3859
+ if (sourceDisc !== void 0) {
3860
+ const variantDefault = du.getVariantDefault(sourceDisc);
3861
+ if (isPlainRecord(variantDefault)) {
3862
+ return mergeVariantKeys(source, variantDefault, path, schema, du);
4191
3863
  }
4192
3864
  }
4193
- function register(source, handler, options, getForm) {
4194
- if (deps.ssr) return NOOP_STOP;
4195
- const reg = {
4196
- handler,
4197
- onError: options?.onError,
4198
- getForm,
4199
- resolve: makeResolver(source),
4200
- previous: /* @__PURE__ */ new Map(),
4201
- runs: /* @__PURE__ */ new Map(),
4202
- seq: 0
4203
- };
4204
- try {
4205
- for (const { key, segments } of reg.resolve()) {
4206
- reg.previous.set(key, deps.getValueAtPath(segments));
4207
- }
4208
- } catch (error) {
4209
- if (__DEV__) console.error("[attaform] onChange source getter threw at registration:", error);
4210
- }
4211
- handlers.add(reg);
4212
- let stopped = false;
4213
- return () => {
4214
- if (stopped) return;
4215
- stopped = true;
4216
- handlers.delete(reg);
4217
- for (const run of reg.runs.values()) run.controller.abort();
4218
- reg.runs.clear();
4219
- reg.previous.clear();
4220
- };
3865
+ return {};
3866
+ }
3867
+ function mergeVariantKeys(source, variantDefault, path, schema, du) {
3868
+ const out = { ...variantDefault };
3869
+ for (const key of Object.keys(source)) {
3870
+ if (!safeOwnHas(variantDefault, key) && key !== du.discriminatorKey) continue;
3871
+ safeAssign(
3872
+ out,
3873
+ key,
3874
+ mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
3875
+ );
4221
3876
  }
4222
- function dispose() {
4223
- for (const reg of handlers) {
4224
- for (const run of reg.runs.values()) run.controller.abort();
4225
- reg.runs.clear();
4226
- reg.previous.clear();
4227
- }
4228
- handlers.clear();
3877
+ return out;
3878
+ }
3879
+ function mergeObjectKeys(target, source, path, schema) {
3880
+ const out = isPlainRecord(target) ? { ...target } : {};
3881
+ for (const key of Object.keys(source)) {
3882
+ safeAssign(
3883
+ out,
3884
+ key,
3885
+ mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
3886
+ );
4229
3887
  }
4230
- return {
4231
- get active() {
4232
- return handlers.size > 0;
4233
- },
4234
- register,
4235
- dispatch,
4236
- dispose
4237
- };
3888
+ return out;
4238
3889
  }
4239
3890
 
4240
3891
  function isHydratedFieldRecord(value) {
@@ -4370,27 +4021,8 @@ function createFormStore(options) {
4370
4021
  const formChangeListeners = /* @__PURE__ */ new Set();
4371
4022
  const submitSuccessListeners = /* @__PURE__ */ new Set();
4372
4023
  const resetListeners = /* @__PURE__ */ new Set();
4373
- const onChangeRegistry = createOnChangeRegistry({ getValueAtPath, ssr });
4374
- const persistOptIns = createPersistOptInRegistry();
4375
- const noSyncPaths = /* @__PURE__ */ new Set();
4376
- const noSyncPathCounts = /* @__PURE__ */ new Map();
4377
- function incrementNoSyncOptOut(path) {
4378
- const next = (noSyncPathCounts.get(path) ?? 0) + 1;
4379
- noSyncPathCounts.set(path, next);
4380
- if (next === 1) noSyncPaths.add(path);
4381
- }
4382
- function decrementNoSyncOptOut(path) {
4383
- const current = noSyncPathCounts.get(path) ?? 0;
4384
- if (current <= 1) {
4385
- noSyncPathCounts.delete(path);
4386
- noSyncPaths.delete(path);
4387
- return;
4388
- }
4389
- noSyncPathCounts.set(path, current - 1);
4390
- }
4391
4024
  const coerceIndex = resolveCoercionIndex(options.coerce);
4392
4025
  const resolvedGetDisplayState = resolveGetDisplayState(options.getDisplayState);
4393
- const resolvedIsSensitivePath = options.isSensitivePath ?? isSensitivePath;
4394
4026
  const cleanupHooks = [];
4395
4027
  const modules = /* @__PURE__ */ new Map();
4396
4028
  const fieldValidatingSince = reactive(/* @__PURE__ */ new Map());
@@ -4738,7 +4370,6 @@ function createFormStore(options) {
4738
4370
  console.error("[attaform] onFormChange threw:", err);
4739
4371
  }
4740
4372
  }
4741
- if (onChangeRegistry.active) onChangeRegistry.dispatch(patches, meta);
4742
4373
  }
4743
4374
  function applyFormReplacementWithPath(next, meta, arrayOpPath) {
4744
4375
  const prev = form.value;
@@ -5179,10 +4810,6 @@ function createFormStore(options) {
5179
4810
  formChangeListeners.clear();
5180
4811
  submitSuccessListeners.clear();
5181
4812
  resetListeners.clear();
5182
- onChangeRegistry.dispose();
5183
- persistOptIns.clear();
5184
- noSyncPaths.clear();
5185
- noSyncPathCounts.clear();
5186
4813
  }
5187
4814
  function getValueAtPath(path) {
5188
4815
  return getAtPath(form.value, path);
@@ -5485,7 +5112,7 @@ function createFormStore(options) {
5485
5112
  });
5486
5113
  const next = resetResponse.data;
5487
5114
  rebuildAuthoredPaths(resetSource, next);
5488
- applyFormReplacement(next, { silent: true });
5115
+ applyFormReplacement(next);
5489
5116
  arrayIdentity.rebaselineAll();
5490
5117
  originals.clear();
5491
5118
  diffAndApply({}, next, [], (patch) => {
@@ -5731,7 +5358,6 @@ function createFormStore(options) {
5731
5358
  settleTransforms,
5732
5359
  scheduleFieldValidation,
5733
5360
  onFormChange,
5734
- registerOnChange: onChangeRegistry.register,
5735
5361
  onSubmitSuccess,
5736
5362
  onReset,
5737
5363
  emitSubmitSuccess,
@@ -5739,11 +5365,6 @@ function createFormStore(options) {
5739
5365
  registerDrain,
5740
5366
  awaitPendingWrites,
5741
5367
  modules,
5742
- persistOptIns,
5743
- isSensitivePath: resolvedIsSensitivePath,
5744
- noSyncPaths,
5745
- incrementNoSyncOptOut,
5746
- decrementNoSyncOptOut,
5747
5368
  coerceIndex,
5748
5369
  blankPaths,
5749
5370
  originalBlankPaths,
@@ -5751,6 +5372,33 @@ function createFormStore(options) {
5751
5372
  };
5752
5373
  }
5753
5374
 
5375
+ function captureUserCallSite() {
5376
+ const raw = new Error().stack;
5377
+ if (typeof raw !== "string") return void 0;
5378
+ const lines = raw.split("\n");
5379
+ for (let i = 1; i < lines.length; i++) {
5380
+ const frame = lines[i];
5381
+ if (frame === void 0) continue;
5382
+ if (/attaform[/-]forms?/i.test(frame)) continue;
5383
+ if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
5384
+ const trimmed = frame.trim();
5385
+ if (trimmed.length === 0) continue;
5386
+ return shortenSourceFrame(trimmed);
5387
+ }
5388
+ return void 0;
5389
+ }
5390
+ function shortenSourceFrame(frame) {
5391
+ const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
5392
+ if (match === null) return frame;
5393
+ const [, urlOrPath, line] = match;
5394
+ if (urlOrPath === void 0 || line === void 0) return frame;
5395
+ let path = urlOrPath;
5396
+ path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
5397
+ path = path.replace(/^_nuxt\//, "");
5398
+ path = path.replace(/^\//, "");
5399
+ return `(${path}:${line})`;
5400
+ }
5401
+
5754
5402
  function getComputedSchema(formKey, schemaOrCallback, options) {
5755
5403
  if (typeof schemaOrCallback === "function") return schemaOrCallback(formKey, options);
5756
5404
  return schemaOrCallback;
@@ -5860,10 +5508,6 @@ function createHistoryModule(state, config) {
5860
5508
  clear();
5861
5509
  return;
5862
5510
  }
5863
- if (meta?.crossTab === true) {
5864
- currentSnapshot.value = captureSnapshot();
5865
- return;
5866
- }
5867
5511
  const newSnap = captureSnapshot();
5868
5512
  const prevSnap = currentSnapshot.value;
5869
5513
  const formPatches = [];
@@ -5884,9 +5528,7 @@ function createHistoryModule(state, config) {
5884
5528
  suppressNext = true;
5885
5529
  state.blankPaths.clear();
5886
5530
  for (const key of snap.blankPaths) state.blankPaths.add(key);
5887
- state.applyFormReplacement(snap.form, {
5888
- persist: !state.persistOptIns.isEmpty()
5889
- });
5531
+ state.applyFormReplacement(snap.form);
5890
5532
  const schemaFlat = snap.schemaErrors.flatMap(([, errs]) => errs);
5891
5533
  const userFlat = snap.userErrors.flatMap(([, errs]) => errs);
5892
5534
  state.setAllSchemaErrors(schemaFlat);
@@ -5937,28 +5579,6 @@ function createHistoryModule(state, config) {
5937
5579
  };
5938
5580
  }
5939
5581
 
5940
- const warned = /* @__PURE__ */ new Set();
5941
- function warnOnceInsecureContext(feature) {
5942
- if (!__DEV__) return;
5943
- if (warned.has(feature)) return;
5944
- warned.add(feature);
5945
- const message = featureMessage(feature);
5946
- console.warn(`[attaform] ${message}`);
5947
- }
5948
- function featureMessage(feature) {
5949
- switch (feature) {
5950
- case "multiTab":
5951
- return "Multi-tab sync requires a secure context (HTTPS or localhost). Plain HTTP on a real hostname is interceptable by network observers, so the sync module is disabled. Serve over HTTPS in production (or develop on `localhost`) to enable cross-tab synchronisation. Use `multiTab: false` on `useForm` to silence this warning.";
5952
- case "persist:local":
5953
- return "Built-in `persist: 'local'` storage requires a secure context (HTTPS or localhost). Plain HTTP on a real hostname is MITM-interceptable, so the persistence layer is disabled. Serve over HTTPS to enable localStorage persistence, or pass a custom storage adapter to opt out of the secure-context gate.";
5954
- case "persist:session":
5955
- return "Built-in `persist: 'session'` storage requires a secure context (HTTPS or localhost). Plain HTTP on a real hostname is MITM-interceptable, so the persistence layer is disabled. Serve over HTTPS to enable sessionStorage persistence, or pass a custom storage adapter to opt out of the secure-context gate.";
5956
- }
5957
- }
5958
- function isSecureContext() {
5959
- return typeof window !== "undefined" && window.isSecureContext === true;
5960
- }
5961
-
5962
5582
  function resolveTrichotomy(input) {
5963
5583
  if (typeof input === "function") {
5964
5584
  return { kind: "async", factory: input };
@@ -5987,18 +5607,10 @@ function useAbstractForm(configuration, options) {
5987
5607
  defaultValue: DEFAULT_MAX_RECURSION_DEPTH
5988
5608
  });
5989
5609
  const resolvedSchema = getComputedSchema(key, configuration.schema, { maxRecursionDepth });
5990
- if (configuration.persist !== void 0 && configuration.key === void 0) {
5991
- throw new AnonPersistError({
5992
- cause: "no-key",
5993
- schemaFields: extractSchemaFields(resolvedSchema),
5994
- callSite: captureUserCallSite()
5995
- });
5996
- }
5997
5610
  const existing = registry.forms.get(key);
5998
5611
  if (__DEV__ && existing !== void 0) {
5999
5612
  void import('../chunks/dev-key-collision-warnings.mjs').then((m) => {
6000
5613
  void m.warnOnSchemaFingerprintMismatch(key, existing.schema, resolvedSchema);
6001
- m.warnOnPersistDivergence(key, existing, configuration.persist);
6002
5614
  });
6003
5615
  }
6004
5616
  const hadPendingHydration = registry.pendingHydration.has(key);
@@ -6026,85 +5638,6 @@ function useAbstractForm(configuration, options) {
6026
5638
  const releaseConsumer = registry.trackConsumer(key);
6027
5639
  onScopeDispose(releaseConsumer);
6028
5640
  }
6029
- const persistDisabledByAnonRule = merged.persist !== void 0 && enforceAnonPersistRule(state.formKey, registry.ssr);
6030
- if (existing === void 0 && !registry.ssr) {
6031
- if (merged.persist !== void 0 && !persistDisabledByAnonRule) {
6032
- const resolvedPersist = normalizePersistConfig(merged.persist);
6033
- const storageKind = resolvedPersist.storage;
6034
- const isBuiltinStorage = typeof storageKind === "string";
6035
- const secureContextOk = !isBuiltinStorage || isSecureContext();
6036
- if (!secureContextOk) {
6037
- const feature = storageKind === "session" ? "persist:session" : "persist:local";
6038
- warnOnceInsecureContext(feature);
6039
- void sweepAllOrphansAcrossStandardStores(`${PERSISTENCE_KEY_PREFIX}${state.formKey}`);
6040
- } else {
6041
- const persistenceBase = resolveStorageKeyBase(resolvedPersist, state.formKey);
6042
- void sweepNonConfiguredStandardStoresForOrphans(resolvedPersist.storage, persistenceBase);
6043
- const adapterPromise = getStorageAdapter(resolvedPersist.storage);
6044
- let persistDisposed = false;
6045
- state.registerCleanup(() => {
6046
- persistDisposed = true;
6047
- });
6048
- const ready = (async () => {
6049
- try {
6050
- const [{ wirePersistence }, fingerprintToken] = await Promise.all([
6051
- import('../chunks/wire-persistence.mjs'),
6052
- resolvePersistFingerprintToken(state)
6053
- ]);
6054
- if (persistDisposed) return void 0;
6055
- const persistenceModule = wirePersistence(
6056
- state,
6057
- resolvedPersist,
6058
- adapterPromise,
6059
- fingerprintToken
6060
- );
6061
- state.registerDrain(() => persistenceModule.awaitPendingWrites());
6062
- state.registerCleanup(() => persistenceModule.dispose());
6063
- return persistenceModule;
6064
- } catch {
6065
- return void 0;
6066
- }
6067
- })();
6068
- const persistenceHandle = { config: resolvedPersist, ready };
6069
- state.modules.set(PERSISTENCE_MODULE_KEY, persistenceHandle);
6070
- }
6071
- } else {
6072
- void sweepAllOrphansAcrossStandardStores(`${PERSISTENCE_KEY_PREFIX}${state.formKey}`);
6073
- }
6074
- }
6075
- if (existing === void 0 && merged.multiTab === true && configuration.key !== void 0 && !registry.ssr) {
6076
- const hasBroadcastChannel = typeof BroadcastChannel !== "undefined";
6077
- const secureContext = isSecureContext();
6078
- if (hasBroadcastChannel && secureContext) {
6079
- let formDisposed = false;
6080
- state.registerCleanup(() => {
6081
- formDisposed = true;
6082
- });
6083
- void (async () => {
6084
- try {
6085
- const [{ createMultiTabSyncModule, MULTI_TAB_SYNC_MODULE_KEY }, fingerprint] = await Promise.all([import('../chunks/multi-tab-sync.mjs'), state.schema.fingerprint()]);
6086
- if (formDisposed) return;
6087
- const channelName = `attaform:sync:${state.formKey}:${hashStableString(fingerprint)}`;
6088
- const syncModule = createMultiTabSyncModule(state, channelName, {
6089
- isSensitivePath: state.isSensitivePath,
6090
- noSyncPaths: state.noSyncPaths,
6091
- validateForm: (form) => {
6092
- const result = state.schema.validateAtPath(form, void 0, { sync: true });
6093
- if (result instanceof Promise) return;
6094
- if (!result.success) {
6095
- throw new Error("attaform multi-tab sync: post-apply schema validation failed");
6096
- }
6097
- }
6098
- });
6099
- state.modules.set(MULTI_TAB_SYNC_MODULE_KEY, syncModule);
6100
- state.registerCleanup(() => syncModule.dispose());
6101
- } catch {
6102
- }
6103
- })();
6104
- } else if (hasBroadcastChannel && !secureContext) {
6105
- warnOnceInsecureContext("multiTab");
6106
- }
6107
- }
6108
5641
  if (existing === void 0 && merged.history !== void 0) {
6109
5642
  const historyModule = createHistoryModule(state, merged.history);
6110
5643
  state.modules.set(HISTORY_MODULE_KEY, historyModule);
@@ -6146,14 +5679,6 @@ function useAbstractForm(configuration, options) {
6146
5679
  apiOptions.autoAria = merged.autoAria;
6147
5680
  }
6148
5681
  const api = buildFormApi(state, formInstanceId, apiOptions);
6149
- const onChangeConfig = configuration.onChange;
6150
- if (onChangeConfig !== void 0) {
6151
- const handler = typeof onChangeConfig === "function" ? onChangeConfig : onChangeConfig.handler;
6152
- const onError = typeof onChangeConfig === "function" ? void 0 : onChangeConfig.onError;
6153
- const options2 = onError === void 0 ? void 0 : { onError };
6154
- const stop = state.registerOnChange(void 0, handler, options2, () => api);
6155
- if (getCurrentScope() !== void 0) onScopeDispose(stop);
6156
- }
6157
5682
  return api;
6158
5683
  }
6159
5684
  function mergeWithDefaults(defaults, configuration) {
@@ -6166,8 +5691,6 @@ function mergeWithDefaults(defaults, configuration) {
6166
5691
  const debounceMs = configuration.debounceMs ?? defaults.debounceMs;
6167
5692
  const getDisplayState = configuration.getDisplayState ?? defaults.getDisplayState;
6168
5693
  const maxRecursionDepth = configuration.maxRecursionDepth ?? defaults.maxRecursionDepth;
6169
- const sensitiveNames = configuration.sensitiveNames ?? defaults.sensitiveNames;
6170
- const multiTab = configuration.multiTab ?? defaults.multiTab;
6171
5694
  const autoAria = configuration.autoAria ?? defaults.autoAria;
6172
5695
  return {
6173
5696
  ...configuration,
@@ -6180,8 +5703,6 @@ function mergeWithDefaults(defaults, configuration) {
6180
5703
  ...debounceMs === void 0 ? {} : { debounceMs },
6181
5704
  ...getDisplayState === void 0 ? {} : { getDisplayState },
6182
5705
  ...maxRecursionDepth === void 0 ? {} : { maxRecursionDepth },
6183
- ...sensitiveNames === void 0 ? {} : { sensitiveNames },
6184
- ...multiTab === void 0 ? {} : { multiTab },
6185
5706
  ...autoAria === void 0 ? {} : { autoAria }
6186
5707
  };
6187
5708
  }
@@ -6197,8 +5718,6 @@ function buildFreshState(key, schema, configuration, registry) {
6197
5718
  if (pending === void 0) {
6198
5719
  initialBlankPaths = walked.paths;
6199
5720
  }
6200
- const resolvedSensitiveNames = configuration.sensitiveNames;
6201
- const resolvedIsSensitivePath = resolvedSensitiveNames === void 0 ? void 0 : createIsSensitivePath(resolvedSensitiveNames);
6202
5721
  const createOptions = {
6203
5722
  formKey: key,
6204
5723
  schema,
@@ -6226,8 +5745,7 @@ function buildFreshState(key, schema, configuration, registry) {
6226
5745
  ...configuration.rememberVariants !== void 0 ? { rememberVariants: configuration.rememberVariants } : {},
6227
5746
  ...configuration.coerce !== void 0 ? { coerce: configuration.coerce } : {},
6228
5747
  ...configuration.getDisplayState !== void 0 ? { getDisplayState: configuration.getDisplayState } : {},
6229
- ...initialBlankPaths !== void 0 ? { initialBlankPaths } : {},
6230
- ...resolvedIsSensitivePath !== void 0 ? { isSensitivePath: resolvedIsSensitivePath } : {}
5748
+ ...initialBlankPaths !== void 0 ? { initialBlankPaths } : {}
6231
5749
  };
6232
5750
  const state = createFormStore(createOptions);
6233
5751
  registry.forms.set(
@@ -6266,34 +5784,6 @@ function resolveFormKey(key) {
6266
5784
  }
6267
5785
  return `${ANONYMOUS_FORM_KEY_PREFIX}${anonCounter++}`;
6268
5786
  }
6269
- async function resolvePersistFingerprintToken(state) {
6270
- try {
6271
- return hashStableString(await state.schema.fingerprint());
6272
- } catch (err) {
6273
- if (__DEV__) {
6274
- console.warn(
6275
- `[attaform] Could not fingerprint the schema for form '${state.formKey}': ${err instanceof Error ? err.message : String(err)}. Persistence falls back to a fingerprint-free key, so a schema change won't auto-invalidate a saved draft.`
6276
- );
6277
- }
6278
- return "unfingerprinted";
6279
- }
6280
- }
6281
- const warnedAnonPersistKeys = /* @__PURE__ */ new Set();
6282
- function enforceAnonPersistRule(formKey, ssr) {
6283
- if (!formKey.startsWith(ANONYMOUS_FORM_KEY_PREFIX)) return false;
6284
- if (__DEV__)
6285
- throw new AnonPersistError({
6286
- cause: "no-key",
6287
- callSite: captureUserCallSite()
6288
- });
6289
- if (!ssr && !warnedAnonPersistKeys.has(formKey)) {
6290
- warnedAnonPersistKeys.add(formKey);
6291
- console.warn(
6292
- "[attaform] persist: ignored \u2014 anonymous useForm() can't safely persist (key drift + cross-form collision risk).\n Persistence is disabled for this form; the app keeps working.\n Fix: useForm({ schema, key: 'login', persist: '...' })"
6293
- );
6294
- }
6295
- return true;
6296
- }
6297
5787
 
6298
5788
  let injectedInstanceCounter = 0;
6299
5789
  function injectForm(input) {
@@ -7520,5 +7010,5 @@ function warnIfAmbientWizardProviderHadDuplicates() {
7520
7010
  }
7521
7011
  }
7522
7012
 
7523
- export { AttaformErrorCode as A, deleteAtPath as B, safeOwnRead as C, DEFAULT_TIMINGS as D, humanize as E, PERSISTENCE_MODULE_KEY as P, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, isPlainRecord as e, safeAssign as f, diffAndApply as g, slimKindOf as h, injectForm as i, applyPatchesForward as j, normalizeNumericOption as k, lazy as l, defaultCoercionRules as m, normalizePersistConfig as n, defaultDisplayState as o, defineCoercion as p, makeDefaultDisplayState as q, useAbstractForm as r, structuralSnapshot as s, getAtPath as t, unset as u, setAtPath as v, resolveStorageKeyBase as w, DEFAULT_PERSISTENCE_DEBOUNCE_MS as x, cleanupOrphanKeys as y, mergeSparseHydration as z };
7524
- //# sourceMappingURL=attaform.CsB-iKbU.mjs.map
7013
+ export { AttaformErrorCode as A, DEFAULT_TIMINGS as D, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, defaultCoercionRules as e, defaultDisplayState as f, defineCoercion as g, useAbstractForm as h, injectForm as i, isPlainRecord as j, safeAssign as k, lazy as l, makeDefaultDisplayState as m, normalizeNumericOption as n, slimKindOf as o, humanize as p, getAtPath as q, setAtPath as r, safeOwnRead as s, unset as u };
7014
+ //# sourceMappingURL=attaform.CtJOd7ox.mjs.map