attaform 0.20.2 → 0.21.1

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 (150) hide show
  1. package/dist/chunks/dev-key-collision-warnings.cjs +58 -0
  2. package/dist/chunks/dev-key-collision-warnings.cjs.map +1 -0
  3. package/dist/chunks/dev-key-collision-warnings.mjs +55 -0
  4. package/dist/chunks/dev-key-collision-warnings.mjs.map +1 -0
  5. package/dist/chunks/devtools.cjs +1 -1
  6. package/dist/chunks/devtools.mjs +1 -1
  7. package/dist/chunks/fingerprint.cjs +186 -0
  8. package/dist/chunks/fingerprint.cjs.map +1 -0
  9. package/dist/chunks/fingerprint.mjs +184 -0
  10. package/dist/chunks/fingerprint.mjs.map +1 -0
  11. package/dist/chunks/fingerprint2.cjs +162 -0
  12. package/dist/chunks/fingerprint2.cjs.map +1 -0
  13. package/dist/chunks/fingerprint2.mjs +160 -0
  14. package/dist/chunks/fingerprint2.mjs.map +1 -0
  15. package/dist/chunks/indexeddb.cjs +1 -1
  16. package/dist/chunks/indexeddb.mjs +1 -1
  17. package/dist/chunks/local-storage.cjs +1 -1
  18. package/dist/chunks/local-storage.mjs +1 -1
  19. package/dist/chunks/multi-tab-sync.cjs +367 -0
  20. package/dist/chunks/multi-tab-sync.cjs.map +1 -0
  21. package/dist/chunks/multi-tab-sync.mjs +364 -0
  22. package/dist/chunks/multi-tab-sync.mjs.map +1 -0
  23. package/dist/chunks/session-storage.cjs +1 -1
  24. package/dist/chunks/session-storage.mjs +1 -1
  25. package/dist/chunks/wire-persistence.cjs +396 -0
  26. package/dist/chunks/wire-persistence.cjs.map +1 -0
  27. package/dist/chunks/wire-persistence.mjs +394 -0
  28. package/dist/chunks/wire-persistence.mjs.map +1 -0
  29. package/dist/esbuild.cjs +28 -0
  30. package/dist/esbuild.cjs.map +1 -0
  31. package/dist/esbuild.d.cts +56 -0
  32. package/dist/esbuild.d.mts +56 -0
  33. package/dist/esbuild.d.ts +56 -0
  34. package/dist/esbuild.mjs +26 -0
  35. package/dist/esbuild.mjs.map +1 -0
  36. package/dist/index.cjs +5 -3
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +66 -70
  39. package/dist/index.d.mts +66 -70
  40. package/dist/index.d.ts +66 -70
  41. package/dist/index.mjs +5 -5
  42. package/dist/nuxt.d.cts +1 -1
  43. package/dist/nuxt.d.mts +1 -1
  44. package/dist/nuxt.d.ts +1 -1
  45. package/dist/rollup.cjs +24 -0
  46. package/dist/rollup.cjs.map +1 -0
  47. package/dist/rollup.d.cts +35 -0
  48. package/dist/rollup.d.mts +35 -0
  49. package/dist/rollup.d.ts +35 -0
  50. package/dist/rollup.mjs +22 -0
  51. package/dist/rollup.mjs.map +1 -0
  52. package/dist/rspack.cjs +10 -0
  53. package/dist/rspack.cjs.map +1 -0
  54. package/dist/rspack.d.cts +40 -0
  55. package/dist/rspack.d.mts +40 -0
  56. package/dist/rspack.d.ts +40 -0
  57. package/dist/rspack.mjs +8 -0
  58. package/dist/rspack.mjs.map +1 -0
  59. package/dist/runtime/plugins/attaform.cjs +2 -2
  60. package/dist/runtime/plugins/attaform.mjs +2 -2
  61. package/dist/shared/attaform.BJGA_UOS.mjs +37 -0
  62. package/dist/shared/attaform.BJGA_UOS.mjs.map +1 -0
  63. package/dist/shared/attaform.BRGIpZo4.cjs +26 -0
  64. package/dist/shared/attaform.BRGIpZo4.cjs.map +1 -0
  65. package/dist/shared/{attaform.DAKrGhxc.cjs → attaform.BSkvn43g.cjs} +101 -417
  66. package/dist/shared/attaform.BSkvn43g.cjs.map +1 -0
  67. package/dist/shared/{attaform.sWm8B15V.d.mts → attaform.BWfliRIK.d.cts} +172 -2
  68. package/dist/shared/{attaform.BGk8cfw2.mjs → attaform.Be8NZG9M.mjs} +178 -21
  69. package/dist/shared/attaform.Be8NZG9M.mjs.map +1 -0
  70. package/dist/shared/{attaform.D2SCCd4O.cjs → attaform.Bq5sX7TF.cjs} +2 -2
  71. package/dist/shared/{attaform.D2SCCd4O.cjs.map → attaform.Bq5sX7TF.cjs.map} +1 -1
  72. package/dist/shared/{attaform.ceGEAEMk.d.ts → attaform.Bv7dRDWK.d.ts} +172 -2
  73. package/dist/shared/attaform.C3Doa9Pt.mjs +24 -0
  74. package/dist/shared/attaform.C3Doa9Pt.mjs.map +1 -0
  75. package/dist/shared/{attaform.B_hph5AE.cjs → attaform.CICFZ1iS.cjs} +178 -20
  76. package/dist/shared/attaform.CICFZ1iS.cjs.map +1 -0
  77. package/dist/shared/attaform.CQN9R62B.cjs +39 -0
  78. package/dist/shared/attaform.CQN9R62B.cjs.map +1 -0
  79. package/dist/shared/{attaform.CwLjUqmQ.cjs → attaform.ClXwitZj.cjs} +735 -960
  80. package/dist/shared/attaform.ClXwitZj.cjs.map +1 -0
  81. package/dist/shared/{attaform.99cfHcIt.d.cts → attaform.D0dWZsJt.d.cts} +349 -77
  82. package/dist/shared/{attaform.99cfHcIt.d.mts → attaform.D0dWZsJt.d.mts} +349 -77
  83. package/dist/shared/{attaform.99cfHcIt.d.ts → attaform.D0dWZsJt.d.ts} +349 -77
  84. package/dist/shared/{attaform.z5j3LwJz.cjs → attaform.D32WwKk6.cjs} +216 -35
  85. package/dist/shared/attaform.D32WwKk6.cjs.map +1 -0
  86. package/dist/shared/{attaform.C5aYC_T8.mjs → attaform.DMEP_ENr.mjs} +39 -392
  87. package/dist/shared/attaform.DMEP_ENr.mjs.map +1 -0
  88. package/dist/shared/{attaform.tiWEVznj.mjs → attaform.DR6RmxWZ.mjs} +725 -962
  89. package/dist/shared/attaform.DR6RmxWZ.mjs.map +1 -0
  90. package/dist/shared/{attaform.Dt7dEcHk.mjs → attaform.DozgVlCE.mjs} +89 -405
  91. package/dist/shared/attaform.DozgVlCE.mjs.map +1 -0
  92. package/dist/shared/{attaform.DN5CvZrg.d.ts → attaform.Duecg2NO.d.mts} +2 -2
  93. package/dist/shared/attaform.DuzQYscR.d.cts +41 -0
  94. package/dist/shared/attaform.DuzQYscR.d.mts +41 -0
  95. package/dist/shared/attaform.DuzQYscR.d.ts +41 -0
  96. package/dist/shared/{attaform.BXinSW2T.d.mts → attaform.FudOcHaa.d.cts} +2 -2
  97. package/dist/shared/attaform.LEWUFqUw.cjs +54 -0
  98. package/dist/shared/attaform.LEWUFqUw.cjs.map +1 -0
  99. package/dist/shared/{attaform.CywE4y8x.d.cts → attaform.MtrpT6Ki.d.ts} +2 -2
  100. package/dist/shared/{attaform.DbRgDFa7.d.cts → attaform.NQ8mybyW.d.mts} +172 -2
  101. package/dist/shared/{attaform.Cd4AOfwu.cjs → attaform.S-pYLSo4.cjs} +68 -402
  102. package/dist/shared/attaform.S-pYLSo4.cjs.map +1 -0
  103. package/dist/shared/{attaform.CnrxbkB6.mjs → attaform.Y1ZGhM4k.mjs} +2 -2
  104. package/dist/shared/{attaform.CnrxbkB6.mjs.map → attaform.Y1ZGhM4k.mjs.map} +1 -1
  105. package/dist/shared/{attaform.QG5TG8lB.mjs → attaform.pmtahXKy.mjs} +216 -36
  106. package/dist/shared/attaform.pmtahXKy.mjs.map +1 -0
  107. package/dist/shared/attaform.sHkHv_98.mjs +51 -0
  108. package/dist/shared/attaform.sHkHv_98.mjs.map +1 -0
  109. package/dist/vite.cjs +9 -45
  110. package/dist/vite.cjs.map +1 -1
  111. package/dist/vite.d.cts +36 -0
  112. package/dist/vite.d.mts +36 -0
  113. package/dist/vite.d.ts +36 -0
  114. package/dist/vite.mjs +8 -44
  115. package/dist/vite.mjs.map +1 -1
  116. package/dist/webpack.cjs +10 -0
  117. package/dist/webpack.cjs.map +1 -0
  118. package/dist/webpack.d.cts +37 -0
  119. package/dist/webpack.d.mts +37 -0
  120. package/dist/webpack.d.ts +37 -0
  121. package/dist/webpack.mjs +8 -0
  122. package/dist/webpack.mjs.map +1 -0
  123. package/dist/zod-v3.cjs +3 -3
  124. package/dist/zod-v3.d.cts +3 -3
  125. package/dist/zod-v3.d.mts +3 -3
  126. package/dist/zod-v3.d.ts +3 -3
  127. package/dist/zod-v3.mjs +3 -3
  128. package/dist/zod-v4.cjs +3 -3
  129. package/dist/zod-v4.d.cts +4 -4
  130. package/dist/zod-v4.d.mts +4 -4
  131. package/dist/zod-v4.d.ts +4 -4
  132. package/dist/zod-v4.mjs +3 -3
  133. package/dist/zod.cjs +8 -8
  134. package/dist/zod.cjs.map +1 -1
  135. package/dist/zod.d.cts +52 -10
  136. package/dist/zod.d.mts +52 -10
  137. package/dist/zod.d.ts +52 -10
  138. package/dist/zod.mjs +6 -6
  139. package/dist/zod.mjs.map +1 -1
  140. package/package.json +19 -5
  141. package/dist/shared/attaform.BGk8cfw2.mjs.map +0 -1
  142. package/dist/shared/attaform.B_hph5AE.cjs.map +0 -1
  143. package/dist/shared/attaform.C5aYC_T8.mjs.map +0 -1
  144. package/dist/shared/attaform.Cd4AOfwu.cjs.map +0 -1
  145. package/dist/shared/attaform.CwLjUqmQ.cjs.map +0 -1
  146. package/dist/shared/attaform.DAKrGhxc.cjs.map +0 -1
  147. package/dist/shared/attaform.Dt7dEcHk.mjs.map +0 -1
  148. package/dist/shared/attaform.QG5TG8lB.mjs.map +0 -1
  149. package/dist/shared/attaform.tiWEVznj.mjs.map +0 -1
  150. package/dist/shared/attaform.z5j3LwJz.cjs.map +0 -1
@@ -0,0 +1,41 @@
1
+ interface WebpackFamilyPluginOptions {
2
+ /**
3
+ * Rewrite `attaform/zod` imports at build time to the matching adapter
4
+ * subpath, based on the consumer's installed Zod major. Default `true`.
5
+ * Set to `false` to keep the runtime-dispatch unified entry (ships both
6
+ * adapters) when a project intentionally mixes Zod versions or resolves
7
+ * Zod in a non-standard way.
8
+ */
9
+ resolveZodAlias?: boolean;
10
+ /**
11
+ * Project root to resolve the installed Zod from. Defaults to the
12
+ * compiler's `context`, falling back to `process.cwd()`. Set this when
13
+ * the build runs from a directory other than the project that owns the
14
+ * Zod dependency (some monorepo layouts).
15
+ */
16
+ root?: string;
17
+ }
18
+ interface WebpackTapable<T> {
19
+ tap(name: string, fn: (arg: T) => void): void;
20
+ }
21
+ interface WebpackResolveData {
22
+ request: string;
23
+ }
24
+ interface WebpackNormalModuleFactory {
25
+ hooks: {
26
+ beforeResolve: WebpackTapable<WebpackResolveData>;
27
+ };
28
+ }
29
+ interface WebpackCompiler {
30
+ context?: string;
31
+ hooks: {
32
+ normalModuleFactory: WebpackTapable<WebpackNormalModuleFactory>;
33
+ };
34
+ }
35
+ /** The structural shape webpack/rspack require of a plugin: an object
36
+ * with an `apply(compiler)` method. */
37
+ interface WebpackFamilyPlugin {
38
+ apply(compiler: WebpackCompiler): void;
39
+ }
40
+
41
+ export type { WebpackFamilyPlugin as W, WebpackFamilyPluginOptions as a };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, q as FlatPath, B as NestedType, t as FormKey, ai as UseFormConfiguration, A as AbstractSchema, j as DefaultValuesInput, al as ValidateOnConfig, aj as UseFormReturnType } from './attaform.99cfHcIt.mjs';
2
+ import { G as GenericForm, s as FlatPath, P as NestedType, v as FormKey, al as UseFormConfiguration, A as AbstractSchema, j as DefaultValuesInput, ao as ValidateOnConfig, am as UseFormReturnType } from './attaform.D0dWZsJt.cjs';
3
3
 
4
4
  /**
5
5
  * The shape `form.values.<key>` returns at runtime.
@@ -143,7 +143,7 @@ type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema>
143
143
  /**
144
144
  * Type produced at `Path` after the full parse pipeline — the schema's
145
145
  * `z.output<Schema>` shape at that path. Matches the `data` payload of
146
- * `form.process()` and the value handed to `handleSubmit`'s callback.
146
+ * `form.parse()` and the value handed to `handleSubmit`'s callback.
147
147
  *
148
148
  * ```ts
149
149
  * const schema = z.object({
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ const node_fs = require('node:fs');
4
+ const node_url = require('node:url');
5
+ const node_path = require('node:path');
6
+
7
+ const ZOD_UNIFIED_SPECIFIER = "attaform/zod";
8
+ const ZOD_V3_SPECIFIER = "attaform/zod-v3";
9
+ const ZOD_V4_SPECIFIER = "attaform/zod-v4";
10
+ function detectZodMajor(consumerRootDir) {
11
+ const consumerURL = node_url.pathToFileURL(node_path.join(consumerRootDir, "package.json")).href;
12
+ let resolved;
13
+ try {
14
+ resolved = undefined("zod/package.json", consumerURL);
15
+ } catch {
16
+ return { major: "missing" };
17
+ }
18
+ try {
19
+ const pkg = JSON.parse(node_fs.readFileSync(node_url.fileURLToPath(resolved), "utf8"));
20
+ const version = pkg.version;
21
+ if (typeof version !== "string") return { major: "unknown" };
22
+ const major = Number.parseInt(version.split(".")[0] ?? "", 10);
23
+ if (major === 3) return { major: 3 };
24
+ if (major === 4) return { major: 4 };
25
+ return { major: "unknown" };
26
+ } catch {
27
+ return { major: "unknown" };
28
+ }
29
+ }
30
+ function missingZodError(tag) {
31
+ return `[${tag}] zod is not installed. attaform requires zod as a peer dependency. Install \`zod@^3\` or \`zod@^4\`, OR pass \`attaform({ resolveZodAlias: false })\` to keep the runtime-dispatch unified entry (and silence this check).`;
32
+ }
33
+ function unclassifiableZodWarning(tag) {
34
+ return `[${tag}] Could not classify the installed Zod major (corrupted package.json, monorepo edge case, or an unexpected version string). Falling through to runtime dispatch \u2014 both Zod adapters will ship in the bundle. Pass \`attaform({ resolveZodAlias: false })\` to silence this warning.`;
35
+ }
36
+ function resolveZodAliasTarget(consumerRootDir, tag, resolveZodAlias, warnState) {
37
+ if (!resolveZodAlias) return null;
38
+ const detection = detectZodMajor(consumerRootDir);
39
+ if (detection.major === "missing") {
40
+ throw new Error(missingZodError(tag));
41
+ }
42
+ if (detection.major === "unknown") {
43
+ if (!warnState.warned) {
44
+ warnState.warned = true;
45
+ console.warn(unclassifiableZodWarning(tag));
46
+ }
47
+ return null;
48
+ }
49
+ return detection.major === 4 ? ZOD_V4_SPECIFIER : ZOD_V3_SPECIFIER;
50
+ }
51
+
52
+ exports.ZOD_UNIFIED_SPECIFIER = ZOD_UNIFIED_SPECIFIER;
53
+ exports.resolveZodAliasTarget = resolveZodAliasTarget;
54
+ //# sourceMappingURL=attaform.LEWUFqUw.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attaform.LEWUFqUw.cjs","sources":["../../src/core/detect-zod-major.ts"],"sourcesContent":["/**\n * Shared build-time Zod-major detection and `attaform/zod` alias\n * resolution for the bundler plugins (`attaform/vite`, `attaform/rollup`,\n * `attaform/esbuild`, `attaform/webpack`, `attaform/rspack`).\n *\n * The unified `attaform/zod` entry runtime-dispatches between the v3 and\n * v4 adapters, so a bundler that does not rewrite the import ships BOTH.\n * Each plugin rewrites `attaform/zod` to the single matching adapter\n * subpath (`attaform/zod-v3` or `attaform/zod-v4`) based on the Zod major\n * resolved from the consumer's project, so the consumer bundle carries\n * one adapter instead of two. This module holds the detection (pure Node,\n * no bundler API) plus the shared diagnostic copy so every plugin behaves\n * and reads identically.\n *\n * Build-time only: imported by the build-tool entries at `src/*.ts`,\n * never by runtime code, so it never reaches a consumer's browser bundle.\n */\nimport { readFileSync } from 'node:fs'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { join } from 'node:path'\n\nexport const ZOD_UNIFIED_SPECIFIER = 'attaform/zod'\nexport const ZOD_V3_SPECIFIER = 'attaform/zod-v3'\nexport const ZOD_V4_SPECIFIER = 'attaform/zod-v4'\n\nexport type ZodMajorDetection =\n | { major: 3 }\n | { major: 4 }\n | { major: 'missing' }\n | { major: 'unknown' }\n\n/**\n * Read the consumer's installed Zod major by resolving\n * `zod/package.json` from their project root. ESM resolution\n * (`import.meta.resolve`) is sync and stable on Node 20.6+, follows\n * pnpm symlinks, and works with attaform's ESM-only `exports` map.\n *\n * Returns:\n * - `{ major: 3 | 4 }` when zod is resolvable AND its `version`\n * field parses to a known major;\n * - `{ major: 'missing' }` when zod can't be resolved at all;\n * - `{ major: 'unknown' }` for any other failure (corrupted\n * package.json, unexpected version string, monorepo edge case).\n */\nexport function detectZodMajor(consumerRootDir: string): ZodMajorDetection {\n const consumerURL = pathToFileURL(join(consumerRootDir, 'package.json')).href\n let resolved: string\n try {\n resolved = import.meta.resolve('zod/package.json', consumerURL)\n } catch {\n return { major: 'missing' }\n }\n try {\n const pkg = JSON.parse(readFileSync(fileURLToPath(resolved), 'utf8')) as { version?: unknown }\n const version = pkg.version\n if (typeof version !== 'string') return { major: 'unknown' }\n const major = Number.parseInt(version.split('.')[0] ?? '', 10)\n if (major === 3) return { major: 3 }\n if (major === 4) return { major: 4 }\n return { major: 'unknown' }\n } catch {\n return { major: 'unknown' }\n }\n}\n\n/**\n * One-shot latch so a plugin warns about an unclassifiable Zod version\n * only once, however many times its detection runs across a build.\n */\nexport interface ZodDetectionWarnState {\n warned: boolean\n}\n\nfunction missingZodError(tag: string): string {\n return (\n `[${tag}] zod is not installed. attaform requires zod as a peer dependency. ` +\n 'Install `zod@^3` or `zod@^4`, OR pass `attaform({ resolveZodAlias: false })` ' +\n 'to keep the runtime-dispatch unified entry (and silence this check).'\n )\n}\n\nfunction unclassifiableZodWarning(tag: string): string {\n return (\n `[${tag}] Could not classify the installed Zod major (corrupted package.json, ` +\n 'monorepo edge case, or an unexpected version string). Falling through to runtime ' +\n 'dispatch — both Zod adapters will ship in the bundle. ' +\n 'Pass `attaform({ resolveZodAlias: false })` to silence this warning.'\n )\n}\n\n/**\n * Resolve the rewrite target for the unified `attaform/zod` specifier,\n * shared by every bundler plugin so they diagnose identically:\n * - returns `attaform/zod-v3` / `attaform/zod-v4` when the consumer's\n * Zod major is detected;\n * - returns `null` to leave `attaform/zod` on its runtime-dispatch\n * entry, either because `resolveZodAlias` is off or because the\n * version could not be classified (warned once via `warnState`);\n * - throws when zod is not installed at all, a fatal misconfiguration\n * the consumer must fix.\n *\n * `tag` brands the diagnostics (`attaform/vite`, `attaform/rollup`, etc).\n * `resolveZodAlias` and `warnState` are supplied by the calling plugin:\n * its consumer-facing default and its per-instance warn latch live at the\n * plugin surface, not here.\n */\nexport function resolveZodAliasTarget(\n consumerRootDir: string,\n tag: string,\n resolveZodAlias: boolean,\n warnState: ZodDetectionWarnState\n): string | null {\n if (!resolveZodAlias) return null\n const detection = detectZodMajor(consumerRootDir)\n if (detection.major === 'missing') {\n throw new Error(missingZodError(tag))\n }\n if (detection.major === 'unknown') {\n if (!warnState.warned) {\n warnState.warned = true\n console.warn(unclassifiableZodWarning(tag))\n }\n return null\n }\n return detection.major === 4 ? ZOD_V4_SPECIFIER : ZOD_V3_SPECIFIER\n}\n"],"names":["pathToFileURL","join","readFileSync","fileURLToPath"],"mappings":";;;;;;AAqBO,MAAM,qBAAA,GAAwB;AAC9B,MAAM,gBAAA,GAAmB,iBAAA;AACzB,MAAM,gBAAA,GAAmB,iBAAA;AAqBzB,SAAS,eAAe,eAAA,EAA4C;AACzE,EAAA,MAAM,cAAcA,sBAAA,CAAcC,cAAA,CAAK,eAAA,EAAiB,cAAc,CAAC,CAAA,CAAE,IAAA;AACzE,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,SAAY,CAAQ,kBAAA,EAAoB,WAAW,CAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAAA,EAC5B;AACA,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAMC,oBAAA,CAAaC,uBAAc,QAAQ,CAAA,EAAG,MAAM,CAAC,CAAA;AACpE,IAAA,MAAM,UAAU,GAAA,CAAI,OAAA;AACpB,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,EAAE,OAAO,SAAA,EAAU;AAC3D,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,EAAI,EAAE,CAAA;AAC7D,IAAA,IAAI,KAAA,KAAU,CAAA,EAAG,OAAO,EAAE,OAAO,CAAA,EAAE;AACnC,IAAA,IAAI,KAAA,KAAU,CAAA,EAAG,OAAO,EAAE,OAAO,CAAA,EAAE;AACnC,IAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAAA,EAC5B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAAA,EAC5B;AACF;AAUA,SAAS,gBAAgB,GAAA,EAAqB;AAC5C,EAAA,OACE,IAAI,GAAG,CAAA,2NAAA,CAAA;AAIX;AAEA,SAAS,yBAAyB,GAAA,EAAqB;AACrD,EAAA,OACE,IAAI,GAAG,CAAA,wRAAA,CAAA;AAKX;AAkBO,SAAS,qBAAA,CACd,eAAA,EACA,GAAA,EACA,eAAA,EACA,SAAA,EACe;AACf,EAAA,IAAI,CAAC,iBAAiB,OAAO,IAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,eAAe,eAAe,CAAA;AAChD,EAAA,IAAI,SAAA,CAAU,UAAU,SAAA,EAAW;AACjC,IAAA,MAAM,IAAI,KAAA,CAAM,eAAA,CAAgB,GAAG,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,SAAA,CAAU,UAAU,SAAA,EAAW;AACjC,IAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,OAAA,CAAQ,IAAA,CAAK,wBAAA,CAAyB,GAAG,CAAC,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA,CAAU,KAAA,KAAU,CAAA,GAAI,gBAAA,GAAmB,gBAAA;AACpD;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, q as FlatPath, B as NestedType, t as FormKey, ai as UseFormConfiguration, A as AbstractSchema, j as DefaultValuesInput, al as ValidateOnConfig, aj as UseFormReturnType } from './attaform.99cfHcIt.cjs';
2
+ import { G as GenericForm, s as FlatPath, P as NestedType, v as FormKey, al as UseFormConfiguration, A as AbstractSchema, j as DefaultValuesInput, ao as ValidateOnConfig, am as UseFormReturnType } from './attaform.D0dWZsJt.js';
3
3
 
4
4
  /**
5
5
  * The shape `form.values.<key>` returns at runtime.
@@ -143,7 +143,7 @@ type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema>
143
143
  /**
144
144
  * Type produced at `Path` after the full parse pipeline — the schema's
145
145
  * `z.output<Schema>` shape at that path. Matches the `data` payload of
146
- * `form.process()` and the value handed to `handleSubmit`'s callback.
146
+ * `form.parse()` and the value handed to `handleSubmit`'s callback.
147
147
  *
148
148
  * ```ts
149
149
  * const schema = z.object({
@@ -1,4 +1,4 @@
1
- import { t as FormKey, ae as SlimPrimitiveKind, C as CoercionEntry, g as CoercionRegistry, G as GenericForm, T as PathKey, S as Path, am as ValidationError, A as AbstractSchema, x as GetDisplayState, aq as WriteMeta, D as DeepPartial, ar as WriteShape, ak as ValidateOn, Y as PersistOptInRegistry, f as AttaformDefaults, aj as UseFormReturnType, a8 as RegisterValue } from './attaform.99cfHcIt.cjs';
1
+ import { v as FormKey, V as PathKey, m as DisplayCtx, z as GetDisplayState, n as DisplayMachine, ag as SlimPrimitiveKind, C as CoercionEntry, g as CoercionRegistry, G as GenericForm, U as Path, ap as ValidationError, A as AbstractSchema, at as WriteMeta, D as DeepPartial, au as WriteShape, aj as TransformAbortHolder, an as ValidateOn, _ as PersistOptInRegistry, f as AttaformDefaults, am as UseFormReturnType, aa as RegisterValue } from './attaform.D0dWZsJt.mjs';
2
2
  import { Ref, ComputedRef, App, InjectionKey } from 'vue';
3
3
 
4
4
  /**
@@ -414,6 +414,13 @@ type WizardForms<S> = FormsRecordOf<S> & Readonly<Record<FormKey, AnyForm>>;
414
414
  * - `submissionAttempts` — count of `wizard.handleSubmit` invocations
415
415
  * (success or failure). Always bumps, including on
416
416
  * noop-form steps.
417
+ * - `submitError` — the error thrown by the most recent
418
+ * `wizard.handleSubmit` callback (or its `onError`),
419
+ * coerced to a real `Error`. Mirrors
420
+ * `form.meta.submitError`: cleared at submit entry and
421
+ * by `reset()`, parked here rather than re-thrown, so
422
+ * the handler resolves and never manufactures a
423
+ * `window` unhandledrejection. `null` on success.
417
424
  * - `visited` — append-only breadcrumb of navigated step keys.
418
425
  * `back()` does not pop; the trail is the audit
419
426
  * log, not the back-stack.
@@ -447,6 +454,7 @@ type UseWizardReturnType<S extends ReadonlyArray<StepSlot> = ReadonlyArray<StepS
447
454
  readonly done: boolean;
448
455
  readonly submitting: boolean;
449
456
  readonly submissionAttempts: number;
457
+ readonly submitError: Error | null;
450
458
  readonly visited: readonly FormKey[];
451
459
  readonly next: () => Promise<void>;
452
460
  readonly back: () => void;
@@ -455,6 +463,68 @@ type UseWizardReturnType<S extends ReadonlyArray<StepSlot> = ReadonlyArray<StepS
455
463
  readonly reset: () => void;
456
464
  };
457
465
 
466
+ /**
467
+ * Per-form display engine: owns the clock and the timers that the pure
468
+ * `getDisplayState` reducer policy needs, so the reducer itself stays a
469
+ * deterministic `(prev, ctx) => next` function.
470
+ *
471
+ * It keeps a `Map` of the machines that are still *active* (a spinner is
472
+ * showing, a verdict is being held, or a `reviewAt` deadline is pending),
473
+ * a single reactive `tick` ref, and a single `setTimeout` aimed at the
474
+ * nearest `reviewAt` across every active field. When a field-state
475
+ * computed reads `resolve`, it subscribes to `tick`; when the timer
476
+ * fires, `tick` bumps and every dependent computed re-runs the reducer,
477
+ * so a field whose deadline elapsed transitions (verdict → spinner, or
478
+ * spinner → settled verdict) without any per-field watcher.
479
+ *
480
+ * Eviction: a machine is dropped once it reaches a terminal *idle* state
481
+ * with no pending review. Error / success / pending machines are retained
482
+ * so the reducer can hold the prior verdict under the show-delay window of
483
+ * the *next* validation streak (no success → idle → success flicker). The
484
+ * retained set is bounded by the rendered non-idle fields; none of them
485
+ * arm a timer, so retention costs memory, never CPU.
486
+ *
487
+ * Untrusted reducer: `getDisplayState` is consumer-overridable, so the
488
+ * engine treats the returned `reviewAt` as untrusted. A non-finite deadline
489
+ * (NaN / ±Infinity from a custom predicate's bad arithmetic) is ignored
490
+ * rather than handed to `setTimeout`, where it coerces to 0 and spins; an
491
+ * over-large finite deadline is clamped below the 32-bit `setTimeout`
492
+ * overflow; and the timer refuses to re-arm for the exact deadline it just
493
+ * fired, so a predicate re-emitting a fixed or past `reviewAt` can't drive an
494
+ * infinite fire loop. None of these arise from the library default, which
495
+ * always advances its deadline or drops it.
496
+ *
497
+ * Background tabs: `setTimeout` is throttled to >= 1s while a tab is hidden,
498
+ * so a min-visible hold can overshoot. A `visibilitychange` listener bumps
499
+ * the clock on return to the foreground, so any overdue deadline resolves at
500
+ * once instead of lingering.
501
+ *
502
+ * SSR: no clock, no timers, no listener. With `now` frozen and nothing
503
+ * validating at render, the reducer returns the plain verdict (never
504
+ * pending) and the engine stores nothing, so the server HTML and the
505
+ * client's first render agree — no hydration mismatch on the display
506
+ * projection.
507
+ */
508
+ type DisplayEngine = {
509
+ /**
510
+ * Resolve a path's next `DisplayMachine`. Subscribes the calling
511
+ * computed to the engine clock, threads the path's previous machine
512
+ * through `reducer`, persists or evicts the result, and re-arms the
513
+ * single timer to the nearest deadline.
514
+ */
515
+ resolve(key: PathKey, ctx: DisplayCtx, reducer: GetDisplayState): DisplayMachine;
516
+ /** Drop every retained machine and cancel the timer (used by `reset()`). */
517
+ clear(): void;
518
+ /** Tear down for good: `clear()` plus detaching the visibility listener. */
519
+ dispose(): void;
520
+ /** Introspection for tests: count of retained machines. */
521
+ size(): number;
522
+ /** Introspection for tests: whether a path currently has a retained machine. */
523
+ has(key: PathKey): boolean;
524
+ /** Introspection for tests: whether a deadline timer is currently armed. */
525
+ hasTimer(): boolean;
526
+ };
527
+
458
528
  /**
459
529
  * Schema-driven coercion of user-typed DOM values at the v-register
460
530
  * directive layer. When the slim schema declares a numeric or
@@ -669,6 +739,16 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
669
739
  * read.
670
740
  */
671
741
  readonly getDisplayState: GetDisplayState;
742
+ /**
743
+ * Per-form display engine: owns the clock and the single timer the timed
744
+ * `getDisplayState` reducer policy needs, keeping the reducer itself a
745
+ * pure `(prev, ctx) => next` function. The field-state computeds route
746
+ * every `displayState` read through `displayEngine.resolve(...)`, which
747
+ * threads the path's previous machine, persists or evicts the result, and
748
+ * re-arms the nearest-deadline timer. Constructed once at form
749
+ * construction; torn down via `registerCleanup` on store eviction.
750
+ */
751
+ readonly displayEngine: DisplayEngine;
672
752
  readonly submitting: Ref<boolean>;
673
753
  readonly activeSubmissions: Ref<number>;
674
754
  readonly submissionAttempts: Ref<number>;
@@ -679,7 +759,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
679
759
  * alongside the rest of the submission surface.
680
760
  */
681
761
  readonly submitted: Ref<boolean>;
682
- readonly submitError: Ref<unknown>;
762
+ readonly submitError: Ref<Error | null>;
683
763
  readonly departAttempts: Ref<number>;
684
764
  /**
685
765
  * `true` while a function-form `defaultValues` factory is in flight.
@@ -838,6 +918,61 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
838
918
  * computed only re-runs when the count for ITS key changes.
839
919
  */
840
920
  readonly fieldValidationCounts: Map<PathKey, number>;
921
+ /**
922
+ * Per-path `Date.now()` stamp marking when the field's LATEST validation
923
+ * run started, re-anchored on every run start (every increment), deleted
924
+ * on the `→ 0` edge. The display reducer reads it as `ctx.validatingSince`
925
+ * to time the anti-flash spinner, which measures `now - validatingSince`:
926
+ * re-anchoring on each run means a burst of keystrokes (each aborting the
927
+ * prior run and starting a new one) keeps pushing the stamp forward, so the
928
+ * spinner stays suppressed until the user pauses rather than surfacing
929
+ * mid-typing. Anchoring only at the streak start would pin it to the first
930
+ * keystroke, because with `debounceMs: 0` the aborted run's decrement lands
931
+ * after the next run's increment and the count never returns to 0 between
932
+ * fast keystrokes. The field-state container walk takes the descendant-min
933
+ * so a row spinner anchors at its earliest still-active leaf. Runtime-only,
934
+ * never hydrated, like the counts. REACTIVE: the display computed reads this
935
+ * (as `ctx.validatingSince`) but not the `validating` flag, and a long
936
+ * validation that settles with an unchanged verdict (same error, still
937
+ * invalid) leaves `errors` / `valid` untouched — so a non-reactive map would
938
+ * leave a held `pending` spinner stranded after the run ends, until some
939
+ * unrelated reactive change happened to re-run the computed. Reactivity ties
940
+ * the computed to both the streak start (set) and end (delete).
941
+ */
942
+ readonly fieldValidatingSince: Map<PathKey, number>;
943
+ /**
944
+ * Per-path counter of in-flight async-transform runs (the async
945
+ * branch of the `register({ transforms })` pipeline). `> 0` drives
946
+ * `field.transforming` / `field.busy`. Counter, not flag, for the
947
+ * same overlap reason as `fieldValidationCounts`, except a superseding
948
+ * input releases the prior run synchronously before incrementing the
949
+ * new one — so the count is the live in-flight depth at the path
950
+ * (effectively 0 or 1). Reactive Map, like the validation counters.
951
+ */
952
+ readonly fieldTransformCounts: Map<PathKey, number>;
953
+ /**
954
+ * Per-path `ssr ? 0 : Date.now()` stamp marking when the path's latest
955
+ * async transform opened; the display reducer reads it (as
956
+ * `ctx.transformingSince`) to time the gated busy spinner. Mirrors
957
+ * `fieldValidatingSince` exactly: re-anchored on each run start,
958
+ * deleted on the `→ 0` edge, reactive for the held-spinner reason.
959
+ */
960
+ readonly fieldTransformingSince: Map<PathKey, number>;
961
+ /**
962
+ * Per-path latest async-transform failure (a rejected transform, or a
963
+ * resolved value the write gate refused), surfaced as
964
+ * `field.transformError`. Cleared when a fresh run opens at the path
965
+ * and on `reset()`. A channel separate from validation `errors`.
966
+ */
967
+ readonly transformErrors: Map<PathKey, Error | null>;
968
+ /**
969
+ * Form-wide count of in-flight async-transform runs. Drives the
970
+ * `settleTransforms` quiescence guard and the `handleSubmit` drain
971
+ * barrier. `Math.max(0, …)`-clamped on release so a doubled decrement
972
+ * (a run's own `endTransform` after a synchronous cancel release)
973
+ * can't drive it negative.
974
+ */
975
+ readonly activeTransforms: Ref<number>;
841
976
  /**
842
977
  * Replace the form value wholesale. Optional `meta` is forwarded to
843
978
  * every `onFormChange` listener so they can decide whether THIS write
@@ -1005,6 +1140,41 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
1005
1140
  * at entry (submit validation is authoritative) and by `reset()`.
1006
1141
  */
1007
1142
  cancelFieldValidation(): void;
1143
+ /**
1144
+ * Open an async-transform run at `key` — bump the run token, increment
1145
+ * the in-flight counters, stamp `transformingSince`, clear any prior
1146
+ * `transformError`, register `holder` for later abort. Returns the run
1147
+ * token. See `InternalRegisterValue.beginTransform`.
1148
+ */
1149
+ beginTransform(key: PathKey, holder: TransformAbortHolder): number;
1150
+ /** `true` while `token` is the live async-transform run at `key`. */
1151
+ isCurrentTransform(key: PathKey, token: number): boolean;
1152
+ /**
1153
+ * Close the run `token` at `key`: release the counters (no-op if the
1154
+ * run was already released by a supersede / cancel) and flush settled
1155
+ * `settleTransforms` waiters.
1156
+ */
1157
+ endTransform(key: PathKey, token: number): void;
1158
+ /** Record a per-field normalization failure at `key` (`field.transformError`). */
1159
+ setTransformError(key: PathKey, err: Error): void;
1160
+ /**
1161
+ * Abort + release every in-flight async-transform run (all paths) and
1162
+ * clear `transformErrors`. Mirrors `cancelFieldValidation`; called by
1163
+ * `reset()` and store teardown.
1164
+ */
1165
+ cancelTransforms(): void;
1166
+ /**
1167
+ * Path-scoped counterpart to `cancelTransforms`: abort + release only
1168
+ * the runs at-or-under `prefix`, clearing their `transformError`.
1169
+ * Called by `resetField`.
1170
+ */
1171
+ cancelTransformsUnder(prefix: Path): void;
1172
+ /**
1173
+ * Resolve once async transforms are quiescent — globally (`path`
1174
+ * omitted) or at-or-under `path`. Resolve-never-reject. See
1175
+ * `UseFormReturnType.settleTransforms`.
1176
+ */
1177
+ settleTransforms(path?: string | Path): Promise<void>;
1008
1178
  /**
1009
1179
  * Kick off (or schedule) a field-level validation run for `path`. Pass
1010
1180
  * `path = []` to cover the whole form; `applySchemaErrorsForSubtree`