attaform 0.17.2 → 0.18.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.
- package/README.md +77 -36
- package/dist/chunks/devtools.cjs +10 -37
- package/dist/chunks/devtools.cjs.map +1 -1
- package/dist/chunks/devtools.mjs +10 -37
- package/dist/chunks/devtools.mjs.map +1 -1
- package/dist/chunks/indexeddb.cjs +4 -4
- package/dist/chunks/indexeddb.cjs.map +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +2 -2
- package/dist/chunks/local-storage.cjs.map +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/session-storage.cjs +2 -2
- package/dist/chunks/session-storage.cjs.map +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/index.cjs +42 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -196
- package/dist/index.d.mts +159 -196
- package/dist/index.d.ts +159 -196
- package/dist/index.mjs +5 -7
- package/dist/index.mjs.map +1 -1
- package/dist/nuxt.cjs +31 -40
- package/dist/nuxt.cjs.map +1 -1
- package/dist/nuxt.d.cts +8 -1
- package/dist/nuxt.d.mts +8 -1
- package/dist/nuxt.d.ts +8 -1
- package/dist/nuxt.mjs +32 -41
- package/dist/nuxt.mjs.map +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.d.vue.ts +7 -0
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +453 -0
- package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +7 -0
- package/dist/runtime/components/DevtoolsValueTree.d.vue.ts +37 -0
- package/dist/runtime/components/DevtoolsValueTree.vue +192 -0
- package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +37 -0
- package/dist/runtime/plugins/attaform.cjs +17 -6
- package/dist/runtime/plugins/attaform.cjs.map +1 -1
- package/dist/runtime/plugins/attaform.mjs +15 -4
- package/dist/runtime/plugins/attaform.mjs.map +1 -1
- package/dist/shared/{attaform.C0iFnTN0.d.ts → attaform.2b7M2mww.d.mts} +57 -23
- package/dist/shared/attaform.5UhpSVFI.cjs +63 -0
- package/dist/shared/attaform.5UhpSVFI.cjs.map +1 -0
- package/dist/shared/attaform.BDdFdjeX.mjs +57 -0
- package/dist/shared/attaform.BDdFdjeX.mjs.map +1 -0
- package/dist/shared/{attaform.Dee2rU1P.cjs → attaform.BqK_L4gK.cjs} +310 -24
- package/dist/shared/attaform.BqK_L4gK.cjs.map +1 -0
- package/dist/shared/attaform.Bubm_slq.cjs.map +1 -1
- package/dist/shared/attaform.CXpzmj38.mjs.map +1 -1
- package/dist/shared/{attaform.Drt6fivF.mjs → attaform.CtNUB9nf.mjs} +74 -76
- package/dist/shared/attaform.CtNUB9nf.mjs.map +1 -0
- package/dist/shared/{attaform.C5MH4lNh.d.mts → attaform.DF8wo-ry.d.ts} +4 -4
- package/dist/shared/attaform.DK9aj0N8.d.ts +1651 -0
- package/dist/shared/{attaform.BPRHR3Zs.cjs → attaform.DUHru0OF.cjs} +83 -85
- package/dist/shared/attaform.DUHru0OF.cjs.map +1 -0
- package/dist/shared/{attaform.C6lbmMUe.d.ts → attaform.DVLB6CAn.d.mts} +4 -4
- package/dist/shared/{attaform.C_5aB6EQ.d.ts → attaform.Dj9mwbaV.d.cts} +756 -148
- package/dist/shared/{attaform.C_5aB6EQ.d.mts → attaform.Dj9mwbaV.d.mts} +756 -148
- package/dist/shared/{attaform.C_5aB6EQ.d.cts → attaform.Dj9mwbaV.d.ts} +756 -148
- package/dist/shared/{attaform.BV40t5y2.cjs → attaform.Dlk1jMuv.cjs} +245 -108
- package/dist/shared/attaform.Dlk1jMuv.cjs.map +1 -0
- package/dist/shared/attaform.DoSuaKMd.d.cts +1651 -0
- package/dist/shared/{attaform.B3ZaPIzS.mjs → attaform.DsC3rZHG.mjs} +1804 -219
- package/dist/shared/attaform.DsC3rZHG.mjs.map +1 -0
- package/dist/shared/{attaform.Cer8JO_P.cjs → attaform.II89Pcf4.cjs} +1860 -272
- package/dist/shared/attaform.II89Pcf4.cjs.map +1 -0
- package/dist/shared/{attaform.CHorcsIU.d.cts → attaform.M33WKVV4.d.cts} +57 -23
- package/dist/shared/{attaform.CIEQgJnM.mjs → attaform.Xhg0AYNa.mjs} +300 -26
- package/dist/shared/attaform.Xhg0AYNa.mjs.map +1 -0
- package/dist/shared/{attaform.CpERWz3u.mjs → attaform.Xt0A3QUd.mjs} +232 -95
- package/dist/shared/attaform.Xt0A3QUd.mjs.map +1 -0
- package/dist/shared/attaform.iTqxvl-P.d.mts +1651 -0
- package/dist/shared/{attaform.CuE-bS1C.d.mts → attaform.tsNFcEW7.d.ts} +57 -23
- package/dist/shared/{attaform.DtMN-MAm.d.cts → attaform.tts_OM7j.d.cts} +4 -4
- package/dist/vite.cjs +288 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +288 -2
- package/dist/vite.mjs.map +1 -1
- package/dist/zod-v3.cjs +11 -8
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.d.cts +6 -6
- package/dist/zod-v3.d.mts +6 -6
- package/dist/zod-v3.d.ts +6 -6
- package/dist/zod-v3.mjs +3 -3
- package/dist/zod-v4.cjs +11 -8
- package/dist/zod-v4.cjs.map +1 -1
- package/dist/zod-v4.d.cts +5 -5
- package/dist/zod-v4.d.mts +5 -5
- package/dist/zod-v4.d.ts +5 -5
- package/dist/zod-v4.mjs +3 -3
- package/dist/zod.cjs +15 -16
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +127 -40
- package/dist/zod.d.mts +127 -40
- package/dist/zod.d.ts +127 -40
- package/dist/zod.mjs +7 -11
- package/dist/zod.mjs.map +1 -1
- package/package.json +18 -7
- package/dist/shared/attaform.B1jvxsOF.d.mts +0 -156
- package/dist/shared/attaform.B3ZaPIzS.mjs.map +0 -1
- package/dist/shared/attaform.BBM2muQ9.cjs +0 -101
- package/dist/shared/attaform.BBM2muQ9.cjs.map +0 -1
- package/dist/shared/attaform.BPRHR3Zs.cjs.map +0 -1
- package/dist/shared/attaform.BV40t5y2.cjs.map +0 -1
- package/dist/shared/attaform.C6qzEdIM.d.cts +0 -156
- package/dist/shared/attaform.C8LVFVVe.cjs +0 -32
- package/dist/shared/attaform.C8LVFVVe.cjs.map +0 -1
- package/dist/shared/attaform.CIEQgJnM.mjs.map +0 -1
- package/dist/shared/attaform.CTwNcpLE.d.ts +0 -156
- package/dist/shared/attaform.Cer8JO_P.cjs.map +0 -1
- package/dist/shared/attaform.CpERWz3u.mjs.map +0 -1
- package/dist/shared/attaform.Dee2rU1P.cjs.map +0 -1
- package/dist/shared/attaform.Drt6fivF.mjs.map +0 -1
- package/dist/shared/attaform.Vo-Kft0t.mjs +0 -29
- package/dist/shared/attaform.Vo-Kft0t.mjs.map +0 -1
- package/dist/shared/attaform.h1sq3BFu.mjs +0 -92
- package/dist/shared/attaform.h1sq3BFu.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attaform.CIEQgJnM.mjs","sources":["../../src/runtime/core/dev.ts","../../src/runtime/core/errors.ts","../../src/runtime/core/ssr.ts","../../src/runtime/core/registry.ts","../../src/runtime/core/vue-shared-shim.ts","../../src/runtime/core/dev-stack-trace.ts","../../src/runtime/composables/use-register.ts","../../src/runtime/core/persistence/opt-in-registry.ts","../../src/runtime/core/persistence/sensitive-names.ts","../../src/runtime/core/directive.ts","../../src/runtime/core/plugin.ts"],"sourcesContent":["/**\n * Portable dev-mode flag. True when the consumer's bundle / runtime\n * signals a non-production build; false in production.\n *\n * Resolves in this order:\n * 1. `process.env.NODE_ENV` — replaced at build time by Vite,\n * Webpack, Rollup + `@rollup/plugin-replace`, and read directly\n * in Node.\n * 2. Falls back to `false` when `process` is undeclared (some\n * sandboxed runtimes).\n *\n * Using this instead of `import.meta.dev` (Vite / Nuxt-specific)\n * keeps the library portable across bundlers and avoids esbuild's\n * `empty-import-meta` warning in non-ESM contexts.\n *\n * **Trade-off (browser CDN consumers).** When the library is\n * imported directly via a browser-native ESM CDN (esm.sh, Skypack,\n * unpkg) WITHOUT a bundler in front, `process` is undeclared and\n * `__DEV__` permanently resolves to `false` — every dev-only warning\n * is silenced even when the consumer is debugging. The library\n * works correctly; only the diagnostic surface degrades. The fix is\n * to put a bundler (Vite, Webpack, Rollup, esbuild) in the consumer\n * pipeline so `process.env.NODE_ENV` gets replaced. This is the\n * recommended path for any production app; CDN imports are useful\n * for prototyping but lose tree-shaking + dev diagnostics either way.\n *\n * Switching to `import.meta.env.DEV` would resolve correctly under\n * Vite but break Node consumers (no `import.meta.env`) and\n * pre-bundled distributions (esbuild emits an `empty-import-meta`\n * warning when `import.meta` resolves to `{}`). The current\n * `process.env.NODE_ENV` choice is the broadest-compatibility option.\n */\nexport const __DEV__: boolean =\n typeof process !== 'undefined' && process.env['NODE_ENV'] !== 'production'\n","/**\n * Typed error classes thrown by the form library. Each one signals a\n * distinct misuse so calling code can branch on `instanceof` instead\n * of pattern-matching error messages.\n *\n * Every class extends `AttaformError`, so consumers can write a single\n * polymorphic catch (`catch (e) { if (e instanceof AttaformError) ... }`)\n * instead of OR-chaining checks for each subclass. `AttaformError` itself\n * extends the standard `Error`, so existing `instanceof Error` usage\n * keeps working.\n */\n\n/**\n * Base for every error class thrown by `attaform`. Sets\n * `this.name` from the constructor's `new.target.name`, so subclasses\n * don't have to redeclare their own name override.\n */\nexport class AttaformError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = new.target.name\n }\n}\n\n/**\n * Thrown when a path string is malformed — typically a dotted path\n * with empty segments (e.g. `'a..b'`, leading or trailing dots).\n * Use array form (`['a', 'b']`) for keys that contain literal dots.\n */\nexport class InvalidPathError extends AttaformError {}\n\n/**\n * Thrown when `useForm` receives an invalid configuration — most often\n * a schema passed directly as the first argument, or no argument at\n * all. The configuration is an options bag; the schema is one of\n * several fields, even when it's the only one in use.\n *\n * ```ts\n * // ✗ Crashes deep inside the validator with an opaque message:\n * const form = useForm(z.object({ ... }))\n * // ✗ Same:\n * const form = useForm()\n * // ✓ Pass the schema as the `schema` field:\n * const form = useForm({ schema: z.object({ ... }) })\n * ```\n *\n * The same shape applies to every entry point: `attaform/zod`,\n * `attaform/zod-v3`, `attaform/zod-v4`, and the schema-agnostic\n * `attaform` root.\n */\nexport class InvalidUseFormConfigError extends AttaformError {\n constructor() {\n super(\n '[attaform] useForm received an invalid configuration (a schema directly, no argument, ' +\n 'or no `schema` field). Pass it as `useForm({ schema })` — the schema is one of several ' +\n 'configuration options. See https://attaform.com/docs/api/use-form-return for the full ' +\n 'configuration shape.'\n )\n }\n}\n\n/**\n * Thrown when a `handleSubmit`-supplied `onError` callback itself\n * throws or rejects. Wraps the inner failure so both the original\n * cause (via `error.cause`) and the propagation site are visible.\n */\nexport class SubmitErrorHandlerError extends AttaformError {}\n\n/**\n * Thrown when an `attaform` API needs the registry attached to a Vue\n * app but it isn't there yet. Component-level entry points (`useForm`,\n * `injectForm`, `useRegister`) lazy-install the registry on first use,\n * so this error is mostly reached by SSR helpers — `renderAttaformState`\n * and `hydrateAttaformState` — which run outside a setup context and\n * have no current instance to install against.\n *\n * Fix: add `app.use(createAttaform())` (or `app.use(createAttaform({\n * ssr: true }))` on the server) to your SSR entry, before\n * `renderToString` / hydration. Under Nuxt, `attaform/nuxt` already\n * does this; the error usually points at a non-Nuxt SSR setup that\n * hasn't installed explicitly.\n */\nexport class RegistryNotInstalledError extends AttaformError {\n constructor() {\n super(\n '[attaform] No registry attached to this Vue app. Component-level useForm / injectForm / ' +\n 'useRegister auto-install the registry, but SSR helpers (renderAttaformState, ' +\n 'hydrateAttaformState) run outside setup and require an explicit ' +\n '`app.use(createAttaform())` at server-render time. Add it to your SSR entry, before ' +\n '`renderToString`.'\n )\n }\n}\n\n/**\n * Thrown when `useForm` / `injectForm` is called outside of a\n * Vue `setup()` function — typically from an event handler, watcher,\n * or async callback that runs after mount.\n *\n * Fix: move the call into `setup()`, or trigger it from a child\n * component whose `setup()` runs the composable.\n */\nexport class OutsideSetupError extends AttaformError {\n constructor() {\n super(\n '[attaform] useForm / injectForm called outside Vue setup(). ' +\n 'Move into setup or mount a child component to trigger from an event.'\n )\n }\n}\n\n/**\n * Thrown when a `useForm({ key })` call uses a key starting with\n * `__atta:`. That prefix is reserved for keys the library generates\n * internally (e.g. for anonymous `useForm()` calls without an\n * explicit key). Pick a different prefix for your form.\n */\nexport class ReservedFormKeyError extends AttaformError {\n constructor(key: string) {\n super(\n `[attaform] Form key \"${key}\" uses the reserved \"__atta:\" namespace. ` +\n `Use a different prefix — \"__atta:\" is for library-internal synthetic keys ` +\n `(anonymous useForm() calls without an explicit key).`\n )\n }\n}\n\n/**\n * Thrown (in dev) when `useForm({ persist: ... })` is configured on\n * an anonymous form (no `key:` provided). The synthetic `__atta:anon:`\n * identity isn't stable across remounts (Vue's `useId()` allocator\n * drifts under HMR, and any sibling `useId()` call shifts subsequent\n * IDs), so the persistence layer can't reliably find the previous\n * mount's draft. Result: stale entries pile up in storage and the\n * user's most recent edit doesn't always come back.\n *\n * Fix: pass an explicit `key` to `useForm()`.\n *\n * In production builds the runtime downgrades this to a one-shot\n * `console.warn` so a deployed third-party app shipping the\n * anti-pattern doesn't hard-crash.\n */\n// (AnonPersistError class declaration is below; this docblock is the\n// historical preamble — kept here so blame/PR review can trace the\n// original intent. The richer class supersedes the earlier basic version.)\n\n/**\n * Thrown when `register(path, { persist: true })` or `form.persist(path)`\n * targets a path whose name matches a sensitive-data heuristic\n * (password, cvv, ssn, token, etc.) without an explicit\n * `acknowledgeSensitive: true` override.\n *\n * Sensitive data in client-side storage (localStorage, sessionStorage,\n * IndexedDB) is a compliance risk — it survives logouts, is readable\n * by any same-origin script, and is unencrypted at rest.\n *\n * Fix: pass `acknowledgeSensitive: true` to confirm the persistence\n * is intentional, or persist the data server-side instead.\n */\nexport class SensitivePersistFieldError extends AttaformError {\n constructor(path: ReadonlyArray<string | number> | string) {\n const display = Array.isArray(path) ? path.join('.') : String(path)\n super(\n `[attaform] Refusing to persist \"${display}\" — this path matches a ` +\n `sensitive-name pattern (password / cvv / ssn / token / etc.). Storing sensitive ` +\n `data in client-side storage is a compliance risk (HIPAA / PII / PCI-DSS / SOC2). ` +\n `Fix: persist this server-side, OR pass \\`acknowledgeSensitive: true\\` to register() ` +\n `(or form.persist()) if the client-side persistence is intentional.`\n )\n }\n}\n\n/**\n * Thrown when persistence is misconfigured in a way that would either\n * (a) silently drop writes, or (b) namespace storage under a\n * non-deterministic synthetic key — both of which become security bugs\n * the moment encrypted persistence backends are added (the same key\n * may be derived for two unrelated forms).\n *\n * Two `cause` values, one error shape:\n *\n * - `'no-key'` — `useForm({ persist: ... })` called without `key:`.\n * Anonymous keys (`__atta:anon:*`) drift across mounts; persisting\n * to a non-deterministic location is refused outright.\n *\n * - `'register-without-config'` — `register(_, { persist: true })`\n * declared on a form whose `useForm()` options omit `persist:`.\n * The opt-in is recorded but nothing would ever land in storage.\n *\n * Fix: align the two layers — set `persist:` + `key:` on `useForm()`,\n * or remove `{ persist: true }` from the offending `register()` call.\n */\nexport class AnonPersistError extends AttaformError {\n readonly schemaFields: readonly string[] | undefined\n readonly callSite: string | undefined\n override readonly cause: 'no-key' | 'register-without-config'\n constructor(opts: {\n schemaFields?: readonly string[] | undefined\n callSite?: string | undefined\n cause: 'no-key' | 'register-without-config'\n }) {\n super(formatAnonPersistMessage(opts))\n this.schemaFields = opts.schemaFields\n this.callSite = opts.callSite\n this.cause = opts.cause\n }\n}\n\nfunction formatAnonPersistMessage(opts: {\n schemaFields?: readonly string[] | undefined\n callSite?: string | undefined\n cause: 'no-key' | 'register-without-config'\n}): string {\n const head =\n opts.cause === 'no-key'\n ? `useForm({ persist: ... }) requires an explicit \\`key:\\`. Anonymous synthetic keys (\\`__atta:anon:*\\`) drift across mounts and can collide between unrelated forms — refusing to persist to a non-deterministic location.`\n : `register(_, { persist: true }) declared on a form whose useForm() options have no \\`persist:\\` configured. The opt-in is recorded but nothing would ever land in storage.`\n const fields =\n opts.schemaFields !== undefined && opts.schemaFields.length > 0\n ? ` Form fields: { ${opts.schemaFields.join(', ')} }.`\n : ''\n const fix =\n opts.cause === 'no-key'\n ? ` Fix: add \\`key: '<stable-id>'\\` to useForm().`\n : ` Fix: add \\`persist: 'session'\\` (or 'local') and \\`key:\\` to useForm(), or remove \\`{ persist: true }\\` from this register() call.`\n const where = opts.callSite !== undefined ? ` ${opts.callSite}` : ''\n return `[attaform] ${head}${fields}${fix}${where}`\n}\n","/**\n * Portable SSR detection. The plugin captures this value at install time and\n * exposes it via the registry so every runtime branch reads a single source\n * of truth instead of sniffing `import.meta.*` (bundler-specific) at each\n * call site.\n *\n * Consumers can override the heuristic explicitly via\n * `createAttaform({ ssr: true })`; the default handles the common\n * Node-vs-browser split without relying on any bundler-injected flag.\n */\n\nexport interface SSRDetectOptions {\n /**\n * Force SSR-vs-client mode, bypassing the `typeof window` heuristic.\n * `true` activates the SSR code paths (no devtools, no persistence\n * wiring, payload serialisation enabled); `false` forces client mode.\n * The Nuxt plugin sets this from `import.meta.server` so SSR detection\n * never depends on whether `window` is polyfilled. Tests that need to\n * exercise the SSR code paths under jsdom pass `ssr: true`.\n */\n ssr?: boolean\n}\n\n/**\n * Returns true when running in a server-rendering context (no `window` / no\n * `document`). Explicit `ssr` flag always wins.\n *\n * Note: JSDOM-based test environments define `window`, so tests that need to\n * exercise SSR code paths must pass `{ ssr: true }` explicitly.\n */\nexport function detectSSR(options: SSRDetectOptions = {}): boolean {\n if (options.ssr !== undefined) return options.ssr\n return typeof window === 'undefined' && typeof document === 'undefined'\n}\n","import type { App, InjectionKey } from 'vue'\nimport { getCurrentInstance, inject, shallowReactive } from 'vue'\nimport type { AttaformDefaults, FormKey } from '../types/types-api'\nimport type { GenericForm } from '../types/types-core'\nimport type { FormStore } from './create-form-store'\nimport { OutsideSetupError, RegistryNotInstalledError } from './errors'\nimport { detectSSR, type SSRDetectOptions } from './ssr'\n\n/**\n * Per-Vue-app container for all form state instances. Each\n * `app.use(createAttaform())` call gets its own registry,\n * so the library runs under bare Vue 3 + SSR (via\n * `@vue/server-renderer`) and Nuxt with the same code path.\n *\n * Each form's state lives in `forms: Map<FormKey, FormStore<GenericForm>>`.\n * The type relaxation at storage time is necessary because different\n * forms in the same app have different `Form` generics; callers recover\n * the specific form type via `useForm`'s overloads.\n */\n\n/**\n * Serialised snapshot of one form's state, captured by\n * `renderAttaformState` for SSR and replayed by\n * `hydrateAttaformState` on the client. Round-trips through\n * JSON-safe tuples; field references are intentionally omitted\n * (DOM nodes don't survive serialisation).\n */\nexport type SerializedFormData = {\n /** The form's value at snapshot time. */\n readonly form: unknown\n /**\n * Errors produced by the schema at snapshot time. Replayed into\n * the client form's error state at hydration; cleared on\n * successful re-validation client-side.\n */\n readonly schemaErrors: ReadonlyArray<readonly [string, unknown]>\n /**\n * Errors set explicitly via `setFieldErrors` / `addFieldErrors`\n * (typically from a server response parsed via `parseApiErrors`)\n * at snapshot time. Replayed at hydration; persists across\n * client-side re-validation.\n */\n readonly userErrors: ReadonlyArray<readonly [string, unknown]>\n /** Per-field metadata (timestamps, raw values, connection flags) captured at snapshot time. */\n readonly fields: ReadonlyArray<readonly [string, unknown]>\n /**\n * Path keys that were in the form's `blankPaths` set at\n * snapshot time. Round-trips the \"displayed empty\" UI state across\n * the SSR boundary — without it, the client briefly renders\n * `String(slim-default)` (e.g. `'0'`) for fields the server\n * rendered as blank. Optional in the wire format so older payload\n * shapes deserialise cleanly.\n */\n readonly blankPaths?: ReadonlyArray<string>\n}\n\nexport type PendingHydration = Map<FormKey, SerializedFormData>\n\n/**\n * The library's per-Vue-app container. One `AttaformRegistry` is\n * created per `app.use(createAttaform())` call.\n *\n * Most consumers never touch this directly — `useForm` and\n * `injectForm` reach the registry on your behalf. Access it\n * explicitly only when wiring SSR or a custom plugin integration.\n */\nexport type AttaformRegistry = {\n /**\n * Live forms keyed by `FormKey`.\n * @internal\n */\n readonly forms: Map<FormKey, FormStore<GenericForm>>\n /**\n * Snapshots staged by `hydrateAttaformState` waiting to be consumed by the next `useForm` call.\n * @internal\n */\n readonly pendingHydration: PendingHydration\n /** `true` while running on the server during SSR; `false` on the client. */\n readonly ssr: boolean\n /** App-level defaults applied to every `useForm` call. */\n readonly defaults: AttaformDefaults\n /**\n * Track a consumer of `key`. Returns a dispose function — call it\n * when the consumer unmounts. The form is evicted automatically\n * when the last consumer disposes, so long-running SPAs don't\n * leak detached state across navigations.\n * @internal\n */\n readonly trackConsumer: (key: FormKey) => () => void\n /**\n * Wait for all pending persistence writes across every live form\n * to settle. Useful for SSR shutdown and integration tests that\n * need a deterministic teardown.\n * @internal\n */\n readonly shutdown: () => Promise<void>\n}\n\n/**\n * The Vue `InjectionKey` under which the registry is provided on the\n * app. Most consumers never need this — `useForm` and\n * `injectForm` resolve the registry automatically.\n */\n// `Symbol.for(...)` so the key survives module duplication. If Vite's\n// dep optimizer ends up serving attaform as two separate copies (one\n// live-ESM, one pre-bundled — the standard hazard for linked-source\n// installs that opt into `optimizeDeps.include`), each copy still\n// resolves the same global symbol from the well-known string. Plugin\n// install's `app.provide(kAttaformRegistry, ...)` and the page's\n// `inject(kAttaformRegistry, null)` agree on the key, so `useForm`\n// finds its registry regardless of which copy did the provide. The\n// `attaform:` prefix namespaces the key safely. Same reasoning\n// for `kFormContext` and `kFormInstanceId` below.\nexport const kAttaformRegistry: InjectionKey<AttaformRegistry> = Symbol.for('attaform:registry')\n\n/**\n * Provides the current form's FormStore to descendants. Installed by\n * `useAbstractForm` after it resolves the state, so any nested component\n * can call `injectForm()` without prop-threading the form API.\n *\n * Typed as `FormStore<GenericForm>` — the descendant that re-emerges the\n * shape must supply its own `Form` generic, because Vue's InjectionKey\n * erases the generic at the provide/inject boundary.\n */\nexport const kFormContext: InjectionKey<FormStore<GenericForm>> =\n Symbol.for('attaform:form-context')\n\n/**\n * Provide / inject key for the per-`useForm()`-call instance ID. Provided\n * alongside `kFormContext` so descendants reaching via `injectForm()`\n * inherit the ancestor's `formInstanceId` and their locally-registered\n * elements tag against the SAME instance — keeps parent-submit-focus\n * working for inputs registered by deep children.\n *\n * Sibling `useForm({ key })` calls (e.g. sidebar + main rendering the\n * same form) sit at distinct tree positions, so each provides its own\n * ID; descendants of each branch inherit the branch's ID. Two ID spaces\n * stay isolated even when the underlying FormStore is shared.\n */\nexport const kFormInstanceId: InjectionKey<string> = Symbol.for('attaform:form-instance-id')\n\ndeclare module 'vue' {\n interface App {\n /** @internal */\n _attaform?: AttaformRegistry\n }\n}\n\n/** Options for `createRegistry`. */\nexport type CreateRegistryOptions = SSRDetectOptions & {\n /**\n * App-level defaults applied to every `useForm` call. Per-form\n * options always win. Omitted is equivalent to `{}`.\n */\n defaults?: AttaformDefaults\n}\n\n/**\n * Create a fresh `AttaformRegistry`. `createAttaform()` calls\n * this internally — most consumers never need to call it directly.\n * Use it when building a custom plugin that doesn't want the\n * `createAttaform` plugin's auto-install behaviour (e.g. test\n * harnesses, embedded apps).\n */\nexport function createRegistry(options: CreateRegistryOptions = {}): AttaformRegistry {\n const ssr = detectSSR(options)\n // Frozen so accidental writes downstream throw in dev. Public surface\n // (`createAttaform({ defaults })`) treats this as data, not as\n // a mutation point — there's no public API to update defaults after\n // install, and adding one would invite race conditions with already-\n // mounted forms.\n const defaults: AttaformDefaults = Object.freeze({ ...(options.defaults ?? {}) })\n // The outer object is plain (it holds references we never rebind); inner\n // Maps are reactive via Vue's collection handlers so per-key reads track\n // per-key. `shallowReactive` avoids Vue's deep Ref-unwrapping, which would\n // mangle FormStore.form's Ref<F> type into F on lookup.\n const forms = shallowReactive(new Map<FormKey, FormStore<GenericForm>>())\n const pendingHydration = shallowReactive(new Map<FormKey, SerializedFormData>())\n // Consumer counts are bookkeeping — not reactive. No template should ever\n // depend on \"how many useForm calls are live\", and using a plain Map\n // avoids triggering watchers when we increment on every mount.\n const consumers = new Map<FormKey, number>()\n\n // Stores that have been evicted from `forms` but still have a\n // pending drain. `shutdown()` awaits these too so a process-exit\n // hook doesn't tear down before debounced writes from already-\n // unmounted forms have a chance to flush.\n const evicting = new Set<FormStore<GenericForm>>()\n\n function trackConsumer(key: FormKey): () => void {\n consumers.set(key, (consumers.get(key) ?? 0) + 1)\n let disposed = false\n return () => {\n if (disposed) return\n disposed = true\n const remaining = (consumers.get(key) ?? 1) - 1\n if (remaining <= 0) {\n // Tear down non-reactive resources the FormStore owns (field-\n // validation timers, abort controllers) BEFORE dropping the\n // registry reference — once the Map entry is gone we can't\n // reach the state anymore.\n const state = forms.get(key)\n consumers.delete(key)\n // Eviction from `forms` stays synchronous: any consumer that\n // reads `registry.forms` after unmount (tests, devtools) sees\n // the form gone immediately. Drain-then-dispose runs async in\n // the background so the persistence layer's debounced final\n // write can complete — the FormStore is reachable through the\n // closure here even after `forms.delete`.\n forms.delete(key)\n if (state !== undefined) {\n evicting.add(state)\n void state\n .awaitPendingWrites()\n .catch(() => undefined)\n .finally(() => {\n evicting.delete(state)\n state.dispose()\n })\n }\n } else {\n consumers.set(key, remaining)\n }\n }\n }\n\n async function shutdown(): Promise<void> {\n // Snapshot the keys — `awaitPendingWrites` may resolve mid-iteration\n // and trigger eviction that mutates `forms` while we're walking.\n // Include the evicting set so in-flight drains from already-\n // unmounted forms also flush before shutdown returns.\n const states = [...forms.values(), ...evicting]\n await Promise.allSettled(states.map((state) => state.awaitPendingWrites()))\n }\n\n return { forms, pendingHydration, ssr, defaults, trackConsumer, shutdown }\n}\n\n/**\n * Look up the current app's registry from inside a component's\n * `setup()` (or any synchronous code on the setup call stack).\n *\n * Most consumers don't need this — `useForm` and `injectForm`\n * call it on your behalf. Reach for it directly when building\n * custom integrations that need the raw registry.\n *\n * Throws:\n * - `OutsideSetupError` when called outside a Vue setup context\n * (e.g. from an event handler or async callback). Move the call\n * into setup, or trigger it from a child component.\n * - `RegistryNotInstalledError` when called inside setup but the\n * plugin wasn't installed. Add\n * `app.use(createAttaform())` to your app entry.\n */\nexport function useRegistry(): AttaformRegistry {\n const instance = getCurrentInstance()\n if (instance === null) {\n throw new OutsideSetupError()\n }\n const registry = inject(kAttaformRegistry, null)\n if (registry === null) {\n throw new RegistryNotInstalledError()\n }\n return registry\n}\n\n/**\n * Look up a Vue app's registry by `App` reference. Used by\n * SSR helpers (`renderAttaformState`, `hydrateAttaformState`) that\n * run outside a component setup context.\n *\n * Throws `RegistryNotInstalledError` when the app hasn't been wired\n * with `createAttaform()`.\n */\nexport function getRegistryFromApp(app: App): AttaformRegistry {\n const registry = app._attaform\n if (registry === undefined) {\n throw new RegistryNotInstalledError()\n }\n return registry\n}\n\nexport function attachRegistryToApp(app: App, registry: AttaformRegistry): void {\n app.provide(kAttaformRegistry, registry)\n app._attaform = registry\n}\n","/**\n * Inlined copies of the handful of utilities we use from @vue/shared.\n *\n * @vue/shared is technically an internal Vue package. Treating it as stable\n * API for a runtime-only form library is a fragility we don't need — these\n * implementations are six functions + ~40 lines, and keeping them in-tree\n * insulates us from future renames or semantic drift.\n *\n * Source (MIT © Vue.js contributors):\n * https://github.com/vuejs/core/blob/main/packages/shared/src/general.ts\n * https://github.com/vuejs/core/blob/main/packages/shared/src/looseEqual.ts\n * https://github.com/vuejs/core/blob/main/packages/shared/src/toDisplayString.ts\n *\n * Behavior preserved byte-for-byte where possible; minor cosmetic changes for\n * our stricter ESLint rules (strict-boolean-expressions, prefer-nullish-\n * coalescing). Any divergence from @vue/shared is a bug in this file.\n */\n\nexport const isArray = Array.isArray\n\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n return typeof value === 'function'\n}\n\nfunction toTypeString(value: unknown): string {\n return Object.prototype.toString.call(value)\n}\n\nexport function isSet(value: unknown): value is Set<unknown> {\n return toTypeString(value) === '[object Set]'\n}\n\nexport function isMap(value: unknown): value is Map<unknown, unknown> {\n return toTypeString(value) === '[object Map]'\n}\n\nexport function isDate(value: unknown): value is Date {\n return toTypeString(value) === '[object Date]'\n}\n\nexport function isSymbol(value: unknown): value is symbol {\n return typeof value === 'symbol'\n}\n\nexport function isObject(value: unknown): value is Record<string | symbol, unknown> {\n return value !== null && typeof value === 'object'\n}\n\nexport function looseToNumber<T>(val: T): T | number {\n const n = parseFloat(val as unknown as string)\n return isNaN(n) ? val : n\n}\n\nfunction looseCompareArrays(a: unknown[], b: unknown[]): boolean {\n if (a.length !== b.length) return false\n let equal = true\n for (let i = 0; equal && i < a.length; i++) {\n equal = looseEqual(a[i], b[i])\n }\n return equal\n}\n\nexport function looseEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n const aValidType = isDate(a)\n const bValidType = isDate(b)\n if (aValidType || bValidType) {\n return aValidType && bValidType ? a.getTime() === b.getTime() : false\n }\n const aSymbol = isSymbol(a)\n const bSymbol = isSymbol(b)\n if (aSymbol || bSymbol) return a === b\n const aIsArray = isArray(a)\n const bIsArray = isArray(b)\n if (aIsArray || bIsArray) {\n return aIsArray && bIsArray ? looseCompareArrays(a, b) : false\n }\n // Short-circuit on object/non-object mismatch BEFORE the deep-equality\n // block. Without this, the fallthrough to `String(a) === String(b)` at\n // the bottom would coerce `{}` to `'[object Object]'` and incorrectly\n // claim `looseEqual({}, '[object Object]') === true`. @vue/shared's\n // own implementation makes the same early return.\n const aIsObject = isObject(a)\n const bIsObject = isObject(b)\n if (aIsObject !== bIsObject) return false\n if (aIsObject && bIsObject) {\n const keysA = Object.keys(a)\n if (keysA.length !== Object.keys(b).length) return false\n for (const key of keysA) {\n const hasA = Object.prototype.hasOwnProperty.call(a, key)\n const hasB = Object.prototype.hasOwnProperty.call(b, key)\n if (!hasA || !hasB || !looseEqual(a[key], b[key])) return false\n }\n return true\n }\n return String(a) === String(b)\n}\n\nexport function looseIndexOf(arr: readonly unknown[], val: unknown): number {\n return arr.findIndex((item) => looseEqual(item, val))\n}\n\nexport function invokeArrayFns(fns: ((...args: unknown[]) => unknown)[], ...args: unknown[]): void {\n for (let i = 0; i < fns.length; i++) {\n const fn = fns[i]\n if (fn) fn(...args)\n }\n}\n","/**\n * Dev-only call-site capture for warnings that want to point the\n * reader at the offending line of their code (not at a attaform-internal\n * frame). Walks the stack past `attaform` frames, picks the\n * first frame that looks like user code, then strips the dev-server\n * scheme + host + Vite/Nuxt's `/_nuxt/` prefix so the warning doesn't\n * carry a wall of `https://localhost:3000/_nuxt/...` noise.\n *\n * Returns `undefined` on engines that don't expose `.stack` or when\n * parsing fails — callers should degrade to a generic message rather\n * than printing nothing.\n *\n * Click-through navigation isn't sacrificed: `console.warn` already\n * renders its own clickable stack trace below the message in\n * Chrome / Firefox DevTools (V8 frame format → Sources tab). The\n * captured frame is purely an inline pointer in the message text,\n * and short paths read better there than full URLs.\n *\n * The attaform-frame regex matches both the published path\n * (`attaform/...`) and the linked / source path\n * (`attaform/...`) so local dev via `make link-attaform` surfaces\n * the same trimmed frames.\n *\n * Dev-only; callers should gate on `__DEV__` before invoking.\n */\nexport function captureUserCallSite(): string | undefined {\n const raw = new Error().stack\n if (typeof raw !== 'string') return undefined\n const lines = raw.split('\\n')\n // Skip the \"Error\" message line and any frame inside attaform itself.\n for (let i = 1; i < lines.length; i++) {\n const frame = lines[i]\n if (frame === undefined) continue\n if (/attaform[/-]forms?/i.test(frame)) continue\n if (/\\bforms\\.[A-Za-z0-9_-]+\\.m?js\\b/.test(frame)) continue\n const trimmed = frame.trim()\n if (trimmed.length === 0) continue\n return shortenSourceFrame(trimmed)\n }\n return undefined\n}\n\n/**\n * Reduce a raw stack frame to `(<path>:<line>)`.\n *\n * Inputs we expect (V8, with or without `at fn (…)` wrapper):\n * - `at setup (https://example.test/_nuxt/pages/spike.vue:18:18)`\n * - `at https://example.com/foo.js:1:1`\n * - `at file:///Users/x/proj/spike.vue:18:18`\n * - `pages/foo.vue:18:18` (already path-like, no V8 wrapper)\n *\n * Outputs:\n * - `(pages/spike.vue:18)`\n * - `(foo.js:1)`\n * - `(Users/x/proj/spike.vue:18)`\n * - `(pages/foo.vue:18)`\n *\n * Why drop the column: Vite's sourcemaps round-trip line accurately\n * but column resolution is fuzzy in compiled contexts (Vue render\n * functions, JSX, anywhere the source-to-output mapping isn't\n * 1-to-1 per character). For a script-setup `useForm()` call the\n * column is meaningful; for a template-inlined `register(...)` it\n * lands somewhere mid-compiled-blob and is actively misleading. The\n * uniform `path:line` format avoids that asymmetry — line is enough\n * to navigate, the editor lands on the right region either way.\n *\n * If the frame doesn't match the trailing `…:line:col` shape at all,\n * the original trimmed frame is returned unchanged — better to\n * surface something than nothing.\n */\nexport function shortenSourceFrame(frame: string): string {\n const match = /(?:^|\\s|\\()([^\\s()]+):(\\d+):\\d+\\)?$/.exec(frame)\n if (match === null) return frame\n const [, urlOrPath, line] = match\n if (urlOrPath === undefined || line === undefined) return frame\n let path = urlOrPath\n // Strip `scheme://host/` (https://…, http://…). file:// gets the\n // same treatment, leaving the absolute filesystem path; we then\n // also strip its leading slash below so it reads as a relative path.\n path = path.replace(/^[a-z]+:\\/\\/[^/]+\\//i, '')\n // Strip Vite/Nuxt's dev-server prefix.\n path = path.replace(/^_nuxt\\//, '')\n // Strip leading slash (left over from file:// or absolute paths).\n path = path.replace(/^\\//, '')\n // Wrap in parens. Chrome's console auto-linker partial-matches\n // bare `pages/foo.vue:137` (it picks up `/foo.vue:137` and\n // drops the `pages` prefix). Parens are the V8 stack-frame\n // convention and Chrome reliably auto-links them end-to-end.\n return `(${path}:${line})`\n}\n","/**\n * Re-bind a parent's `v-register` onto an inner native element. Use\n * inside a component that wraps a single form field whose root is\n * NOT the input itself (e.g. a labelled-row that renders `<label>`\n * around the input).\n *\n * ```vue\n * <!-- Parent -->\n * <MyInput v-register=\"form.register('email')\" />\n *\n * <!-- MyInput.vue -->\n * <script setup lang=\"ts\">\n * import { useRegister } from 'attaform'\n * const rv = useRegister()\n * // rv.path / rv.segments / rv.formKey / rv.formInstanceId / rv.innerRef\n * // are all reachable directly — no `.value` unwrap.\n * </script>\n *\n * <template>\n * <label class=\"field\">\n * <span>Email</span>\n * <input v-register=\"rv\" />\n * </label>\n * </template>\n * ```\n *\n * Returns a hybrid Proxy: it answers `__v_isRef` / `.value` like a\n * Vue `Ref<RegisterValue | undefined>` (so templates auto-unwrap\n * correctly and `v-register=\"rv\"` feeds the underlying RV to the\n * directive — preserving the directive's path-migration diff across\n * renders), AND every other property read pierces to the captured\n * RV's field (so `rv.path` works directly in script setup). Reads\n * inside reactive scopes (`computed` / `watchEffect`) track the\n * underlying `shallowRef`, so `rv.path` re-runs when the parent\n * rebinds to a different path.\n *\n * Unbound state: when the parent didn't pass `v-register`, every\n * piercing read returns `undefined` at runtime, and the return type\n * surfaces this honestly as `UseRegisterReturn<V> | undefined`.\n * Consumers defend with optional chaining (`rv?.formKey`,\n * `rv?.segments`); the directive accepts `undefined` peacefully (its\n * binding value type is already `RegisterValue<V> | undefined`), so\n * `v-register=\"rv\"` works whether or not a parent has bound. The\n * composable's `onMounted` warn fires once per instance to surface\n * the misuse case at runtime.\n *\n * Diagnostic: in dev mode, a single `console.warn` fires per instance\n * at `onMounted` if the captured value is still `undefined` — by then\n * the parent has had its full mount lifecycle to bind, so a missing\n * binding is conclusive misuse. The warn does NOT fire on every read\n * of the proxy, and is intentionally silent under SSR\n * (`renderToString` skips `onMounted`); the CSR hydration pass\n * surfaces the same diagnostic without double-counting through Nuxt's\n * `dev:ssr-logs` channel.\n *\n * When the wrapper's root IS the input itself, Vue's attribute\n * fallthrough handles the binding and `useRegister` is unnecessary.\n * For wrappers that bind multiple fields (compound forms), use\n * `injectForm<Form>(key?)` and call `ctx.register(...)` directly.\n */\nimport {\n getCurrentInstance,\n onBeforeMount,\n onBeforeUpdate,\n onMounted,\n shallowRef,\n type Ref,\n} from 'vue'\nimport { __DEV__ } from '../core/dev'\nimport { captureUserCallSite } from '../core/dev-stack-trace'\nimport { ensureAttaformInstalled } from '../core/plugin'\nimport type { RegisterValue } from '../types/types-api'\n\n/**\n * Return type of `useRegister()`. Hybrid of `RegisterValue<V>` (so\n * `rv.path` / `rv.segments` / `rv.formKey` etc. work directly in\n * script setup) and `Ref<RegisterValue<V> | undefined>` (so Vue's\n * template auto-unwrap surfaces the underlying RV to `v-register`\n * and the directive's path-migration diff sees the real RV across\n * renders).\n *\n * The two surfaces don't clash at the type level: `RegisterValue`\n * doesn't carry a `value` field, and `Ref<T>`'s `value: T` becomes\n * the hybrid's only `.value`. Older code that read `rv.value?.path`\n * keeps working; new code can write `rv.path` directly.\n */\nexport type UseRegisterReturn<V = unknown> = RegisterValue<V> & Ref<RegisterValue<V> | undefined>\n\n/**\n * Marker on the rendered root DOM element. Set by `useRegister`'s\n * `onMounted` hook; read by the directive's deferred warn check to\n * skip the \"is a no-op\" warn for components that handle binding via\n * an inner v-register.\n *\n * `Symbol.for(...)` so the marker round-trips across duplicate copies\n * of attaform — see `assignKey` in core/directive.ts for the same\n * reasoning. `useRegister` and the directive are typically loaded\n * from the same module copy, but a consumer importing from\n * `attaform/zod` (Vite-optimized bundle) and the Nuxt\n * plugin's relative-path import (live ESM) can land on different\n * copies; a global symbol means the marker check still works.\n */\nexport const REGISTER_OWNER_MARKER: unique symbol = Symbol.for('attaform:register-owner-marker')\n\nconst warnedNoParentRV: WeakSet<object> | null = __DEV__ ? new WeakSet<object>() : null\nlet warnedOutsideSetup = false\n\n/**\n * Build the hybrid Proxy. The `__v_isRef` field makes Vue's `unref`\n * / template auto-unwrap treat the proxy as a `Ref<RegisterValue |\n * undefined>` and surface `value` (the captured RV) to consumers\n * that go through that path — including `v-register=\"rv\"` in a\n * template, which is what feeds the directive its `binding.value`.\n *\n * Every other property read pierces to `capturedRegisterValue.value`,\n * so `rv.path` / `rv.segments` / `rv.formKey` work in script setup.\n *\n * Methods don't need `this` rebinding: every method on a real\n * `RegisterValue` is an arrow-function closure built in\n * `register-api.ts`, capturing `state` / `segments` lexically. So\n * `rv.registerElement(el)` works through the proxy without a\n * `bind` pass. The `has` / `ownKeys` traps cooperate with\n * `'innerRef' in rv` / `Object.keys(rv)` — including the\n * `isRegisterValue` type guard the directive uses.\n */\nfunction makeRegisterValueProxy<V>(\n capturedRegisterValue: Ref<RegisterValue<V> | undefined>\n): UseRegisterReturn<V> {\n return new Proxy({} as object, {\n get(_target, prop) {\n if (prop === '__v_isRef') return true\n if (prop === 'value') return capturedRegisterValue.value\n const v = capturedRegisterValue.value\n if (v === undefined) return undefined\n return Reflect.get(v as object, prop)\n },\n has(_target, prop) {\n if (prop === '__v_isRef' || prop === 'value') return true\n const v = capturedRegisterValue.value\n if (v === undefined) return false\n return Reflect.has(v as object, prop)\n },\n ownKeys(_target) {\n const v = capturedRegisterValue.value\n if (v === undefined) return []\n return Reflect.ownKeys(v as object)\n },\n getOwnPropertyDescriptor(_target, prop) {\n const v = capturedRegisterValue.value\n if (v === undefined) return undefined\n const desc = Reflect.getOwnPropertyDescriptor(v as object, prop)\n if (desc !== undefined) {\n // Proxy invariant: any property reported via ownKeys must be\n // configurable on the target OR match a non-configurable\n // descriptor on the target. Empty target has no own props,\n // so we MUST return descriptors with `configurable: true`.\n desc.configurable = true\n }\n return desc\n },\n }) as unknown as UseRegisterReturn<V>\n}\n\nexport function useRegister<V = unknown>(): UseRegisterReturn<V> | undefined {\n const instance = getCurrentInstance()\n if (instance === null) {\n warnOutsideSetup()\n return makeRegisterValueProxy<V>(shallowRef<RegisterValue<V> | undefined>(undefined))\n }\n\n // Lazy-install: even though `useRegister` doesn't read the registry\n // directly, it's a public setup-context entry point and its template\n // typically renders `<input v-register=\"rv\" />` — the directive must\n // be registered on the app at render time. Without auto-install, a\n // wrapper component used in isolation (no `useForm` ancestor, no\n // `createAttaform()`) hits Vue's \"Failed to resolve directive\"\n // warning. Idempotent — explicit installs win when they ran first.\n ensureAttaformInstalled(instance.appContext.app)\n\n // Capture the bridge `registerValue` from instance.attrs into a\n // local ref, then STRIP the bridge keys (`registerValue` + `value`)\n // from the attrs object. This prevents fallthrough to the rendered\n // root: without the strip, Vue would merge attrs onto the root's\n // vnode and the wrapper would render with stringified DOM attrs\n // (`<label registerValue=\"[object Object]\">`). Class/style/aria/data\n // fallthrough is unaffected — only the bridge keys are removed, so\n // the consumer doesn't have to set `defineOptions({ inheritAttrs:\n // false })` and lose those legitimate fallthroughs.\n //\n // Vue's `setFullProps` repopulates attrs on every parent re-render\n // (it iterates rawProps and re-assigns each key into attrs). So the\n // capture+strip has to run on every update, not just at setup. The\n // `onBeforeUpdate` hook fires after `updateComponentPreRender`\n // (which calls setFullProps) and before `renderComponentRoot`\n // (which reads attrs for fallthrough), giving us a clean window.\n //\n // We don't read from `useAttrs()` proxy because the proxy reads\n // off the same target we're mutating — after the strip, the proxy\n // returns undefined for the bridge keys. The captured ref is the\n // source of truth instead, refreshed in lockstep with attrs.\n //\n // `shallowRef` (not `ref`) — `ref` calls `reactive()` on object\n // values, which would wrap the parent's RV in a reactive proxy and\n // break referential equality. The directive hooks downstream rely\n // on the rv being the same reference the parent holds, so we keep\n // it raw.\n const capturedRegisterValue = shallowRef<RegisterValue<V> | undefined>(undefined)\n\n const refreshAndStripBridgeAttrs = (): void => {\n const rawAttrs = instance.attrs as Record<string, unknown>\n // Capture only when the bridge key is present. The strip below\n // removes `registerValue` from attrs, so a second invocation of\n // this function (e.g. `onBeforeMount` after the synchronous setup\n // call) would otherwise overwrite the captured rv with `undefined`.\n // Vue's `setFullProps` re-populates attrs on every parent render,\n // so the `onBeforeUpdate` invocation correctly sees the key again\n // and re-captures.\n if ('registerValue' in rawAttrs) {\n capturedRegisterValue.value = rawAttrs['registerValue'] as RegisterValue<V> | undefined\n delete rawAttrs['registerValue']\n }\n if ('value' in rawAttrs) delete rawAttrs['value']\n }\n // Capture+strip three times: synchronously in setup, then on\n // beforeMount, then on every beforeUpdate. The synchronous call is\n // load-bearing for SSR — Vue skips lifecycle hooks during\n // `renderToString`, so an `onBeforeMount`-only capture leaves\n // `capturedRegisterValue` at `undefined` and the directive's first\n // server-side template read would otherwise misrender. Vue's\n // `setupComponent` runs `initProps` (which populates\n // `instance.attrs.registerValue` from the parent's `:registerValue`\n // binding injected by `selectNodeTransform`) before `setup()` runs,\n // so the sync read sees the correct value on both server and client.\n // The `onBeforeMount` hook stays as defence in depth against any\n // re-population that could happen after setup (e.g. from a parent's\n // directive re-running) — idempotent, safe to duplicate. The\n // `onBeforeUpdate` hook handles parent re-renders, where Vue's\n // `setFullProps` runs again and re-puts the bridge keys.\n refreshAndStripBridgeAttrs()\n onBeforeMount(refreshAndStripBridgeAttrs)\n onBeforeUpdate(refreshAndStripBridgeAttrs)\n\n // Single post-mount hook does two jobs: (1) marks the rendered root\n // DOM element with `REGISTER_OWNER_MARKER` so the parent directive's\n // deferred warn check skips the \"is a no-op\" warn for components that\n // handle binding via an inner v-register, and (2) emits the\n // no-parent-RV diagnostic exactly once per instance if the captured\n // value is still `undefined` by mount time — by then the parent has\n // had its full lifecycle to bind, so still-undefined is conclusive\n // misuse. The proxy stays pure: reads don't trigger diagnostics, so\n // a consumer that conditionally consumes the value (or reads it many\n // times) gets exactly the right behaviour. SSR is intentionally\n // silent — `onMounted` doesn't fire on the server, and the CSR\n // hydration pass surfaces the diagnostic on the only surface a\n // developer can act on without double-counting through the Nuxt\n // `dev:ssr-logs` channel.\n onMounted(() => {\n const el = instance.vnode.el\n if (el !== null && el !== undefined && typeof el === 'object') {\n ;(el as unknown as { [k: symbol]: unknown })[REGISTER_OWNER_MARKER] = true\n }\n if (capturedRegisterValue.value === undefined) {\n warnNoParentRV(instance as unknown as object)\n }\n })\n\n return makeRegisterValueProxy(capturedRegisterValue)\n}\n\nfunction warnOutsideSetup(): void {\n if (!__DEV__) return\n if (warnedOutsideSetup) return\n warnedOutsideSetup = true\n const frame = captureUserCallSite()\n console.warn(\n `[attaform] useRegister() called outside a component setup; returning an unbound RegisterValue proxy. ` +\n `Fix: call it inside <script setup> or a setup() function — not from an event handler ` +\n `or async callback.` +\n (frame !== undefined ? ` ${frame}` : '')\n )\n}\n\nfunction warnNoParentRV(instance: object): void {\n if (!__DEV__ || warnedNoParentRV === null) return\n if (warnedNoParentRV.has(instance)) return\n warnedNoParentRV.add(instance)\n const frame = captureUserCallSite()\n console.warn(\n `[attaform] useRegister: no parent registerValue prop; RegisterValue fields will read as undefined. ` +\n `Pass v-register on the parent: \\`<YourComponent v-register=\"form.register('field')\" />\\`.` +\n (frame !== undefined ? ` ${frame}` : '')\n )\n}\n","import type { PathKey } from '../paths'\n\n/**\n * Per-element identity for the persistence opt-in registry.\n *\n * Why WeakMap-keyed monotonic counter:\n * - **No DOM mutation.** A `data-atta-id` attribute would alter SSR\n * output and risk hydration discrepancies. WeakMap is invisible.\n * - **Auto-GC.** When the element is removed from the DOM and goes\n * out of all references, the WeakMap entry vanishes — no leak.\n * - **Counter over UUID.** Element IDs never cross runtime boundaries\n * (the directive that consumes them is client-only), so collision\n * resistance across processes is irrelevant. Smaller, easier to\n * debug (\"el-7\" vs a UUID).\n */\nconst idGenerator = (() => {\n let counter = 0\n return () => `el-${++counter}`\n})()\n\nconst elementIds = new WeakMap<HTMLElement, string>()\n\nexport function getOrAssignElementId(el: HTMLElement): string {\n let id = elementIds.get(el)\n if (id === undefined) {\n id = idGenerator()\n elementIds.set(el, id)\n }\n return id\n}\n\n/**\n * Per-FormStore registry tracking which DOM elements have opted into\n * persistence for which paths. Lives on the FormStore so that two SFCs\n * sharing a key share the registry — opt-ins are per-element, not\n * per-component.\n *\n * The directive's input handler computes `meta.persist` for each write\n * by calling `hasOptIn(elementId, path)` — only THIS element's writes\n * persist if THIS element opted in. Other call sites that aren't tied\n * to a single element (history undo/redo, field-array helpers, devtools\n * edits) use `hasAnyOptInForPath(path)` — persist if any element has\n * opted into that path.\n *\n * Internal data structure: `Map<PathKey, Set<elementId>>`. Small forms\n * have ~10-50 paths; iteration is cheap. All operations are O(1) given\n * (id, path).\n */\nexport type PersistOptInRegistry = {\n /** Add an opt-in entry; idempotent. */\n add(elementId: string, path: PathKey): void\n /** Remove a single (element, path) entry. */\n remove(elementId: string, path: PathKey): void\n /** Remove every opt-in for `elementId`. Called from directive's beforeUnmount. */\n removeAllFor(elementId: string): void\n /** Check whether THIS element has opted into THIS path. */\n hasOptIn(elementId: string, path: PathKey): boolean\n /** Check whether ANY element has opted into this path. */\n hasAnyOptInForPath(path: PathKey): boolean\n /** Iterate every path that currently has at least one opt-in. */\n optedInPaths(): IterableIterator<PathKey>\n /** True iff no element has opted into any path. */\n isEmpty(): boolean\n /** Drop every entry. Called from FormStore.dispose. */\n clear(): void\n}\n\nexport function createPersistOptInRegistry(): PersistOptInRegistry {\n const byPath = new Map<PathKey, Set<string>>()\n\n function add(elementId: string, path: PathKey): void {\n const existing = byPath.get(path)\n if (existing === undefined) {\n byPath.set(path, new Set([elementId]))\n return\n }\n existing.add(elementId)\n }\n\n function remove(elementId: string, path: PathKey): void {\n const existing = byPath.get(path)\n if (existing === undefined) return\n existing.delete(elementId)\n if (existing.size === 0) byPath.delete(path)\n }\n\n function removeAllFor(elementId: string): void {\n for (const [path, ids] of byPath) {\n if (!ids.delete(elementId)) continue\n if (ids.size === 0) byPath.delete(path)\n }\n }\n\n function hasOptIn(elementId: string, path: PathKey): boolean {\n return byPath.get(path)?.has(elementId) ?? false\n }\n\n function hasAnyOptInForPath(path: PathKey): boolean {\n const ids = byPath.get(path)\n return ids !== undefined && ids.size > 0\n }\n\n function optedInPaths(): IterableIterator<PathKey> {\n return byPath.keys()\n }\n\n function isEmpty(): boolean {\n return byPath.size === 0\n }\n\n function clear(): void {\n byPath.clear()\n }\n\n return {\n add,\n remove,\n removeAllFor,\n hasOptIn,\n hasAnyOptInForPath,\n optedInPaths,\n isEmpty,\n clear,\n }\n}\n","import { SensitivePersistFieldError } from '../errors'\nimport type { Path, PathKey, Segment } from '../paths'\n\n/**\n * The library's built-in conservative set of identifier name stems that\n * flag a path segment as \"this looks like data the consumer almost\n * certainly does not want serialised to client-side storage or\n * broadcast across tabs.\"\n *\n * Each entry is a NAME STEM, not a regex. Matching is case-insensitive\n * and tolerant of separator variants — `'card_number'` matches the\n * segments `'card_number'`, `'card-number'`, `'cardNumber'`, and\n * `'cardnumber'`. Short stems (compact length ≤ 5) get word-boundary\n * anchors to avoid common false positives — `'pin'` matches `'pin'`\n * and `'user_pin'` but not `'pinned'`; `'token'` matches `'token'` but\n * not `'tokenizer'`. Longer stems match anywhere (`'password'` matches\n * `'password'`, `'passwords'`, `'userPassword'`).\n *\n * Consumers extend or replace via per-form or global config:\n *\n * ```ts\n * createAttaform({\n * defaults: { sensitiveNames: [...DEFAULT_SENSITIVE_NAMES, 'mrn', 'tax_id'] }\n * })\n * ```\n *\n * The same resolved predicate gates persistence writes, multi-tab sync\n * broadcasts, AND the DevTools redact walk — one source of truth for\n * \"what counts as sensitive\" across every surface.\n *\n * **Non-goals.** This is not a soundness guarantee. Adversarial paths\n * (`'sensitive_data'`, `'CCV'` instead of `'CVV'`) can slip through.\n * The intent is a code-review trigger for the common-case footgun\n * plus a defense-in-depth filter on the cross-tab and DevTools\n * surfaces.\n */\nexport const DEFAULT_SENSITIVE_NAMES: readonly string[] = Object.freeze([\n // Passwords + PIN-like\n 'password',\n 'passwd',\n 'pwd',\n 'pin',\n // Card / payment\n 'cvv',\n 'cvc',\n 'card_number',\n 'card_num',\n 'card',\n 'iban',\n 'routing_number',\n 'account_number',\n // Government / identity\n 'ssn',\n 'social_security',\n 'dob',\n 'date_of_birth',\n 'passport',\n 'driver_license',\n // Tax IDs\n 'tin',\n 'ein',\n 'itin',\n 'tax_id',\n // Tokens / secrets / API auth\n 'token',\n 'tokens',\n 'secret',\n 'secrets',\n 'api_key',\n 'api_secret',\n 'api_token',\n 'private_key',\n 'bearer',\n 'oauth',\n 'auth_token',\n 'access_token',\n 'refresh_token',\n 'session_id',\n 'session_key',\n 'session_token',\n // MFA / OTP\n 'otp',\n 'one_time_password',\n 'one_time_code',\n 'mfa_secret',\n 'mfa_seed',\n 'mfa_code',\n 'mfa_token',\n 'two_factor_code',\n 'two_factor_token',\n '2fa',\n '2fa_code',\n '2fa_token',\n 'recovery_code',\n 'backup_code',\n])\n\n/**\n * Compact-length threshold below which a stem gets word-boundary\n * anchors. Tuned so `'pin'`, `'card'`, `'token'` get boundary\n * protection (avoiding `'pinned'`, `'cards'`, `'tokenizer'`) while\n * `'passwd'`, `'secret'`, `'tokens'` match as substring (catching\n * camelCase variants like `'userPassword'`).\n */\nconst WORD_BOUNDARY_THRESHOLD = 5\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Build a single case-insensitive regex from a name stem. Underscores,\n * hyphens, and spaces in the input become `[_\\s-]?` (optional\n * separator) so `'card_number'` tolerates `'cardNumber'`,\n * `'card-number'`, `'cardnumber'`, and `'card number'` alike.\n */\nfunction nameToRegex(name: string): RegExp {\n const parts = name.split(/[_\\s-]/).filter((p) => p.length > 0)\n if (parts.length === 0) {\n // Pathological input (empty / all-separator); produce a regex that\n // matches nothing rather than throwing — keeps the caller's\n // composition surface forgiving.\n return /(?!)/\n }\n const escaped = parts.map(escapeRegex).join('[_\\\\s-]?')\n const compactLength = parts.reduce((sum, p) => sum + p.length, 0)\n const useBoundary = compactLength <= WORD_BOUNDARY_THRESHOLD\n const source = useBoundary ? `\\\\b${escaped}\\\\b` : escaped\n return new RegExp(source, 'i')\n}\n\nfunction namesToPatterns(names: readonly string[]): readonly RegExp[] {\n const patterns: RegExp[] = []\n for (const name of names) {\n if (typeof name !== 'string' || name.length === 0) continue\n patterns.push(nameToRegex(name))\n }\n return patterns\n}\n\nconst DEFAULT_PATTERNS = namesToPatterns(DEFAULT_SENSITIVE_NAMES)\n\n/**\n * Factory: returns a closure that tests a single Segment against the\n * resolved name list. Reused by the DevTools redact walk to\n * short-circuit whole subtrees the moment any ancestor segment matches.\n *\n * Pass an empty array to disable the heuristic entirely (no segment\n * counts as sensitive). Omitting the argument uses the library\n * default list.\n */\nexport function createSegmentMatchesSensitive(\n names: readonly string[] = DEFAULT_SENSITIVE_NAMES\n): (segment: Segment) => boolean {\n const patterns = names === DEFAULT_SENSITIVE_NAMES ? DEFAULT_PATTERNS : namesToPatterns(names)\n return (segment: Segment) => {\n if (typeof segment !== 'string') return false\n for (const p of patterns) {\n if (p.test(segment)) return true\n }\n return false\n }\n}\n\n/**\n * Factory: returns a closure that tests a path (structured `Path`,\n * dotted-string, or canonical JSON `PathKey`) against the resolved\n * name list. True iff ANY segment matches.\n *\n * Same predicate gates persistence writes, multi-tab broadcasts, AND\n * the DevTools edit-rejection check — consumers configure once via\n * `sensitiveNames` and every surface respects it.\n */\nexport function createIsSensitivePath(\n names: readonly string[] = DEFAULT_SENSITIVE_NAMES\n): (path: Path | PathKey | string) => boolean {\n const segmentMatches = createSegmentMatchesSensitive(names)\n return (path: Path | PathKey | string) => {\n if (typeof path !== 'string') {\n for (const segment of path) {\n if (segmentMatches(segment)) return true\n }\n return false\n }\n // String input: try JSON-array first (PathKey), fall back to dotted.\n if (path.startsWith('[')) {\n try {\n const parsed = JSON.parse(path) as unknown[]\n if (Array.isArray(parsed)) {\n for (const segment of parsed) {\n if (segmentMatches(segment as Segment)) return true\n }\n return false\n }\n } catch {\n // fall through to dotted parse\n }\n }\n for (const segment of path.split('.')) {\n if (segmentMatches(segment)) return true\n }\n return false\n }\n}\n\nconst defaultSegmentMatches = createSegmentMatchesSensitive()\nconst defaultIsSensitivePath = createIsSensitivePath()\n\n/**\n * True iff `segment` itself matches the LIBRARY DEFAULT sensitive-name\n * list. For consumer-configurable matching, use\n * `createSegmentMatchesSensitive(list)` to build a per-form closure.\n */\nexport function segmentMatchesSensitive(segment: Segment): boolean {\n return defaultSegmentMatches(segment)\n}\n\n/**\n * True iff any segment of the path matches the LIBRARY DEFAULT\n * sensitive-name list. For consumer-configurable matching, use\n * `createIsSensitivePath(list)` to build a per-form closure.\n */\nexport function isSensitivePath(path: Path | PathKey | string): boolean {\n return defaultIsSensitivePath(path)\n}\n\n/**\n * Throw `SensitivePersistFieldError` if `path` matches sensitivity and\n * `acknowledged` is not true. The optional `isSensitive` predicate\n * lets call sites pass the per-form resolved closure; omit to use the\n * library default list.\n */\nexport function enforceSensitiveCheck(\n path: Path | PathKey | string,\n acknowledged: boolean,\n isSensitive: (p: Path | PathKey | string) => boolean = defaultIsSensitivePath\n): void {\n if (acknowledged) return\n if (!isSensitive(path)) return\n throw new SensitivePersistFieldError(path)\n}\n","/**\n * The `v-register` directive. Two-way binding with `v-model`-like\n * semantics, but writes go through the form's `RegisterValue` so\n * dirty / pristine / touched / errors stay coherent across the form.\n *\n * Bind to a native input, select, textarea, checkbox, or radio:\n *\n * ```vue\n * <input v-register=\"form.register('email')\" />\n * ```\n *\n * Installed automatically by `createAttaform()`; the export is\n * for advanced consumers who install directives manually. Works\n * identically under Nuxt, bare Vue CSR, and bare Vue +\n * `@vue/server-renderer` — Vue skips directive lifecycle hooks during\n * SSR, so the directive is a safe no-op server-side.\n */\nimport {\n invokeArrayFns,\n isArray,\n isFunction,\n isSet,\n looseEqual,\n looseIndexOf,\n looseToNumber,\n} from './vue-shared-shim'\nimport type { DirectiveBinding, DirectiveHook, ObjectDirective, VNode } from 'vue'\nimport { isRef, nextTick, warn } from 'vue'\nimport { REGISTER_OWNER_MARKER } from '../composables/use-register'\nimport { __DEV__ } from './dev'\nimport type {\n CustomDirectiveRegisterAssignerFn,\n InternalRegisterValue,\n RegisterCheckboxCustomDirective,\n RegisterModelDynamicCustomDirective,\n RegisterRadioCustomDirective,\n RegisterSelectCustomDirective,\n RegisterTextCustomDirective,\n RegisterTransform,\n RegisterValue,\n WriteMeta,\n} from '../types/types-api'\nimport type { PathKey } from './paths'\nimport { getOrAssignElementId } from './persistence/opt-in-registry'\nimport { enforceSensitiveCheck } from './persistence/sensitive-names'\n\n/**\n * Symbol slot used by custom directive integrations to install an\n * assigner on the bound element. Read by the v-register directive\n * when a DOM event fires:\n *\n * ```ts\n * import { assignKey } from 'attaform'\n * el[assignKey] = (value) => myCustomWriter(value)\n * ```\n *\n * Most consumers never need this — the built-in directives wire\n * default assigners for text inputs, checkboxes, radios, and selects.\n */\n// `Symbol.for(...)` so `el[assignKey] = ...` round-trips across\n// duplicate copies of attaform. The directive (which writes the\n// default assigner) and the consumer-side composables/utilities (which\n// may read or override it) must agree on the key, or the directive\n// stops recognising consumer-installed assigners after the page is\n// served from a Vite-optimised copy that's distinct from the one the\n// directive registration came from. Same reasoning for `listenersKey`\n// and `DEFAULT_ASSIGNER_TAG` below.\nexport const assignKey: unique symbol = Symbol.for('attaform:assign-key')\n\n/**\n * Per-element bag of listener tuples added by the active directive\n * variant in `created`. `vRegisterDynamic.beforeUnmount` drains the bag\n * so reused elements (KeepAlive, v-show) don't accumulate orphaned\n * handlers across activation cycles.\n */\nconst listenersKey: unique symbol = Symbol.for('attaform:directive-listeners')\n\ntype TrackedListener = {\n event: string\n handler: EventListener\n // Explicitly `undefined`-able so `exactOptionalPropertyTypes` lets us\n // stash tuples where the caller didn't pass options.\n options: EventListenerOptions | undefined\n}\n\ntype ListenerCarrier = { [listenersKey]?: TrackedListener[] }\n\n/**\n * Type guard for a `RegisterValue`. Returns `true` when `val` looks\n * like the object returned from `form.register(path)`.\n *\n * ```ts\n * if (isRegisterValue(slotValue)) {\n * // slotValue.innerRef is now a Ref<unknown>\n * }\n * ```\n *\n * Useful when building wrapper components that accept either a\n * `RegisterValue` or a plain ref via the same prop.\n */\nexport function isRegisterValue<Value = unknown>(val: unknown): val is RegisterValue<Value> {\n if (typeof val !== 'object' || val === null) return false\n if (!('innerRef' in val)) return false\n if (!isRef(val.innerRef)) return false\n if (!('registerElement' in val)) return false\n if (typeof val.registerElement !== 'function') return false\n if (!('setValueWithInternalPath' in val)) return false\n if (typeof val.setValueWithInternalPath !== 'function') return false\n return true\n}\n\ntype ComposingTarget = (EventTarget & { composing: boolean }) | null\nfunction addEventListener(\n el: Element,\n event: string,\n handler: EventListener,\n options?: EventListenerOptions\n): void {\n el.addEventListener(event, handler, options)\n // Stash the tuple on the element so `beforeUnmount` can detach it.\n // A bare `addEventListener` without tracking would leak across\n // KeepAlive re-activations where the DOM node is reused.\n const carrier = el as ListenerCarrier\n const bag = carrier[listenersKey] ?? []\n bag.push({ event, handler, options })\n carrier[listenersKey] = bag\n}\n\nfunction removeTrackedListeners(el: Element): void {\n const carrier = el as ListenerCarrier\n const bag = carrier[listenersKey]\n if (bag === undefined) return\n for (const { event, handler, options } of bag) {\n el.removeEventListener(event, handler, options)\n }\n delete carrier[listenersKey]\n}\n\n/**\n * Write the directive-private `lastTypedForm` ref. Lives on the\n * `InternalRegisterValue` extension of `RegisterValue` (it's not part\n * of the public type), but every RV constructed by `register-api.ts`\n * carries it — so the cast captures a runtime invariant the type\n * system can't otherwise express. Used by the numeric-text listener\n * to surface the user's typed form (`'1e2'`) to `displayValue`\n * mid-typing without yanking the caret on the next render.\n */\nfunction writeLastTypedForm(rv: RegisterValue, next: string | null): void {\n ;(rv as InternalRegisterValue).lastTypedForm.value = next\n}\n\n/**\n * Compute the WriteMeta the default assigner attaches to its\n * `setValueWithInternalPath` call. Per-element semantics: only THIS\n * element's writes carry `persist: true`, and only if THIS element opted\n * in via `register('foo', { persist: true })`. Other elements bound to\n * the same path get `persist: false` from their own assigners.\n *\n * The assigner closure captures `el` and `registerValue` directly.\n * `el` is stable across the assigner's lifetime; `registerValue` is the\n * latest one, since the assigner is recreated on every `beforeUpdate`\n * via `setAssignFunction`.\n */\nfunction computePersistMeta(el: HTMLElement, registerValue: RegisterValue): WriteMeta {\n const elementId = getOrAssignElementId(el)\n return { persist: registerValue.persistOptIns.hasOptIn(elementId, registerValue.path) }\n}\n\n/**\n * Symbol-tagged on default-installed assigners so listener bodies can\n * tell \"no consumer override\" from \"consumer-installed assigner\". The\n * bail check (`shouldBailListener`) uses this to avoid the bubbled-\n * write bug for non-supported roots: the default assigner reading\n * `el.value` off a `<div>` would clobber form state with `''` /\n * `undefined` on every keystroke from a descendant input. A consumer-\n * installed assigner (via `assignKey` or `onUpdate:registerValue`)\n * has explicitly opted into reading whatever the listener captures,\n * so the bail doesn't apply.\n */\nconst DEFAULT_ASSIGNER_TAG: unique symbol = Symbol.for('attaform:default-assigner-tag')\n\ntype DefaultAssignerCarrier = { [DEFAULT_ASSIGNER_TAG]?: boolean }\n\nfunction isDefaultAssigner(fn: unknown): boolean {\n return typeof fn === 'function' && (fn as DefaultAssignerCarrier)[DEFAULT_ASSIGNER_TAG] === true\n}\n\n/**\n * Listener-body bail. Called at the top of every event handler the\n * directive attaches. Bails when:\n * - the rendered root is a non-supported tag (where `el.value` is\n * meaningless), AND\n * - the assigner is the default (no consumer override).\n *\n * Catches two cases without needing instance-level sentinel detection:\n * 1. A `useRegister`-using child component — its rendered root is\n * usually a `<label>` / `<div>` / etc., and the inner\n * `<input v-register>` handles binding. The parent's directive's\n * listener on the rendered root would otherwise read `el.value`\n * off the wrapper and clobber the form.\n * 2. A bare `<div v-register>` with no escape hatch — same story,\n * the dev gets a deferred warn pointing at the recipe.\n *\n * Pre-installed `assignKey` AND `@update:registerValue` listener\n * shapes both bypass this bail (their assigner replaces the default,\n * stripping the tag). Post-installed `assignKey` (set via\n * `onMounted` or a ref callback) ALSO bypasses, because by the time\n * the next input event fires, the user's assigner is in place.\n */\nfunction shouldBailListener(el: HTMLElement): boolean {\n if (SUPPORTED_TAGS.has(el.tagName)) return false\n return isDefaultAssigner((el as unknown as { [k: symbol]: unknown })[assignKey])\n}\n\n/**\n * Result of running a field's `transforms: [...]` pipeline. Discriminated\n * so each assigner branch can short-circuit on failure without re-checking\n * a sentinel. `ok: false` means the write should be aborted (the helper\n * already logged via `console.error`); the caller returns `false` from\n * the assigner so the existing rejected-write contract carries through.\n */\ntype TransformResult = { ok: true; value: unknown } | { ok: false }\n\n/**\n * Apply the field's transform pipeline to a value. Each transform runs\n * inside a per-call try/catch so a buggy or defensive-throw transform\n * doesn't crash the host app. On throw the pipeline aborts (subsequent\n * transforms don't run), nothing is written to form state, and the\n * caller returns `false`. A `Promise` return is treated identically —\n * transforms must be sync; canonicalize-before-write patterns belong\n * in async field validation, not the assigner pipeline.\n *\n * `transforms` on `RegisterValue` is optional (test fixtures and\n * custom integrations can omit it); a missing array short-circuits to\n * the original value with no allocation.\n */\nfunction runTransforms(initial: unknown, registerValue: RegisterValue): TransformResult {\n const transforms = registerValue.transforms\n if (transforms === undefined || transforms.length === 0) {\n return { ok: true, value: initial }\n }\n let v = initial\n for (let i = 0; i < transforms.length; i++) {\n const fn = transforms[i] as RegisterTransform\n try {\n v = fn(v)\n } catch (err) {\n logTransformFailure(registerValue.path, i, fn, err)\n return { ok: false }\n }\n }\n if (v instanceof Promise) {\n logTransformAsync(registerValue.path)\n return { ok: false }\n }\n return { ok: true, value: v }\n}\n\n/**\n * Log a transform throw. Dev message includes path, index, transform name,\n * remediation hint, and the original error (with message + stack). Prod\n * message is a fixed string with NONE of those — transform bodies are\n * consumer code we don't control, so error messages and stack frames are\n * an information-leak surface (consumer-typed values, file paths, internal\n * function names). Set `NODE_ENV=development` to surface details.\n */\nfunction logTransformFailure(\n path: PathKey,\n index: number,\n fn: RegisterTransform,\n err: unknown\n): void {\n if (__DEV__) {\n const namePart = fn.name !== '' ? `, '${fn.name}'` : ''\n console.error(\n `[attaform] transform threw for path '${path}' (index ${index}${namePart}) — ` +\n `write aborted. Transforms must not throw; wrap your own try/catch if the throw is recoverable. ` +\n `Original error:`,\n err\n )\n } else {\n console.error(\n `[attaform] transform error — write aborted (set NODE_ENV=development for details).`\n )\n }\n}\n\n/**\n * Log a Promise-returning transform. Same dev/prod posture as\n * `logTransformFailure` — informative in dev, opaque in prod.\n */\n/**\n * Apply the field's coerce closure (built at register-time by\n * `buildCoerceFn`) to a post-transform value. Identity when the\n * RegisterValue is a hand-rolled mock that omits the field, or when\n * coercion was disabled / no coerction target was resolved at the\n * path. The closure itself runs the registry rule, post-validates\n * the result, and falls back to the original on any rule failure\n * (throw, wrong-kind, NaN) — see `schema-coerce.ts` for details.\n */\nfunction applyCoerce(value: unknown, registerValue: RegisterValue): unknown {\n return registerValue.coerce !== undefined ? registerValue.coerce(value) : value\n}\n\n/**\n * Apply the field's element-level coerce closure (built at\n * register-time by `buildElementCoerceFn`) to a scalar DOM-side\n * value that should match an array/Set member. `coerceElement` is\n * only set on container paths; for scalar paths or when coercion\n * is disabled it's `undefined` and the raw value passes through.\n * Mirrors `applyCoerce` for the path-level case.\n */\nfunction applyElementCoerce(value: unknown, registerValue: RegisterValue): unknown {\n return registerValue.coerceElement !== undefined ? registerValue.coerceElement(value) : value\n}\n\nfunction logTransformAsync(path: PathKey): void {\n if (__DEV__) {\n console.error(\n `[attaform] transform pipeline for path '${path}' returned a Promise — ` +\n `transforms must be sync. Use async field validation for canonicalize-before-write patterns. ` +\n `Write aborted.`\n )\n } else {\n console.error(\n `[attaform] transform error — write aborted (set NODE_ENV=development for details).`\n )\n }\n}\n\nconst getModelAssigner = (\n el: HTMLElement,\n vnode: VNode,\n registerValue: RegisterValue\n): CustomDirectiveRegisterAssignerFn => {\n // developer escape hatch — Vue wires `onUpdate:registerValue` as either a\n // single function or an array of functions depending on how many listeners\n // are bound. We narrow before dispatching.\n //\n // Both shapes invoke the consumer's handler as `(value, registerValue)` so\n // a top-level handler can call `rv.setValueWithInternalPath(value)` to\n // forward the write into form state without having to capture `rv` via\n // closure. Consumers wanting persistence-aware writes pass their own\n // `meta` to `setValueWithInternalPath`; the default assigner below\n // auto-attaches per-element meta.\n //\n // Vue 3.5's compiler emits TWO different prop keys for `@update:registerValue`\n // depending on context. For native elements with an uppercase letter in the\n // event name (e.g. the `V` in `registerValue`), the compiler preserves\n // casing via the `on:` prefix form: `\"on:update:registerValue\"`. For\n // components, vnode lifecycle events, or all-lowercase event names, it\n // emits `\"onUpdate:registerValue\"`. Render-function authors using `h(...)`\n // pick whichever key they like. We read both forms; for components the\n // `onUpdate:` form normally wins, for plain `<input v-register>` the\n // `on:update:` form is what survives the compiler.\n // See @vue/compiler-core/transformOn (search for `[A-Z]/.test(rawName)`).\n const fn: unknown =\n vnode.props?.['onUpdate:registerValue'] ?? vnode.props?.['on:update:registerValue']\n if (isArray(fn)) {\n const fnArr = fn.filter((x) => isFunction(x)) as ((...args: unknown[]) => unknown)[]\n return (value) => {\n // Transforms run BEFORE the override sees the value. A consumer\n // who declared `transforms: [...]` intended \"always normalize\"; a\n // silent bypass on override would be the surprise. If they want\n // raw, they don't register transforms.\n const r = runTransforms(value, registerValue)\n if (!r.ok) return false\n // Schema-driven coerce runs AFTER transforms — it's the final\n // type-fixup before storage. Custom override handlers receive\n // the coerced value, mirroring how transforms compose with\n // overrides today. Consumers who want raw don't enable coerce.\n const coerced = applyCoerce(r.value, registerValue)\n invokeArrayFns(fnArr, coerced, registerValue)\n // Multi-listener case: no single boolean to surface. Return\n // undefined so the listener treats this as \"succeeded\" — matches\n // the back-compat contract for consumer-installed assigners.\n return undefined\n }\n }\n if (isFunction(fn)) {\n const handler = fn as CustomDirectiveRegisterAssignerFn\n return (value) => {\n const r = runTransforms(value, registerValue)\n if (!r.ok) return false\n const coerced = applyCoerce(r.value, registerValue)\n return handler(coerced, registerValue)\n }\n }\n // Default-installed assigner. Tagged so the listener-body bail\n // (`shouldBailListener`) can distinguish it from consumer overrides\n // and prevent the bubbled-write bug on non-supported roots.\n //\n // Returns the underlying setValue boolean so listeners (e.g.\n // vRegisterSelect's change handler) can detect rejection and gate\n // post-write side effects like the `_assigning` flag.\n const defaultAssigner: CustomDirectiveRegisterAssignerFn = (value) => {\n const r = runTransforms(value, registerValue)\n if (!r.ok) return false\n const coerced = applyCoerce(r.value, registerValue)\n return registerValue.setValueWithInternalPath(coerced, computePersistMeta(el, registerValue))\n }\n ;(defaultAssigner as unknown as DefaultAssignerCarrier)[DEFAULT_ASSIGNER_TAG] = true\n return defaultAssigner\n}\n\n/**\n * Idempotent reconciliation of a single element's opt-in across the\n * directive lifecycle. Called from `created` (oldValue undefined),\n * `beforeUpdate` (oldValue the previous RegisterValue), and as a\n * convenience from `beforeUnmount` (value undefined).\n *\n * Handles every transition: persist flag flipping in either direction,\n * `register()` path changing (e.g. dynamic v-for index), and the\n * cross-form / cross-SFC case where `register()` returns a value bound\n * to a different FormStore (different `persistOptIns` instance).\n */\nfunction syncPersistOptIn(el: HTMLElement, value: unknown, oldValue: unknown): void {\n const wasOptedIn = isRegisterValue(oldValue) && oldValue.persist === true\n const wantsOptIn = isRegisterValue(value) && value.persist === true\n if (!wasOptedIn && !wantsOptIn) return\n const elementId = getOrAssignElementId(el)\n // Detach the old opt-in unless every dimension matches (persist still\n // requested, same canonical path, same registry instance).\n if (wasOptedIn) {\n const old = oldValue as RegisterValue\n const samePathAndRegistry =\n wantsOptIn &&\n (value as RegisterValue).path === old.path &&\n (value as RegisterValue).persistOptIns === old.persistOptIns\n if (!samePathAndRegistry) {\n old.persistOptIns.remove(elementId, old.path)\n }\n }\n // Attach the new opt-in. `add` is idempotent, so if oldValue already\n // had the same (path, registry) we just re-touch the same entry.\n // The sensitive-name check fires here (not on every keystroke) — it's\n // the act of OPTING IN that crosses the compliance threshold.\n if (wantsOptIn) {\n const v = value as RegisterValue\n enforceSensitiveCheck(v.path, v.acknowledgeSensitive, v.isSensitivePath)\n v.persistOptIns.add(elementId, v.path)\n }\n}\n\n/**\n * Reconcile the multi-tab sync OPT-OUT (`register('path',\n * { multiTab: false })`) across binding lifecycle transitions.\n * Symmetric with `syncPersistOptIn` for the multi-tab dimension.\n *\n * The RV's `markNoSync` / `unmarkNoSync` closures are pre-bound to\n * the canonical path key + the FormStore's ref-counted opt-out\n * registry (see `state.incrementNoSyncOptOut`). When `multiTab !==\n * false`, both closures are `undefined` and this function noops on\n * the hot path.\n *\n * Handles every transition:\n * - undefined → opted-out: increment\n * - opted-out → undefined: decrement\n * - opted-out → opted-out (same path): no-op (idempotent)\n * - opted-out → opted-out (path changed): decrement old, increment new\n */\nfunction syncMultiTabOptOut(value: unknown, oldValue: unknown): void {\n const wasOptedOut = isRegisterValue(oldValue) && oldValue.unmarkNoSync !== undefined\n const wantsOptOut = isRegisterValue(value) && value.markNoSync !== undefined\n if (!wasOptedOut && !wantsOptOut) return\n if (wasOptedOut) {\n const old = oldValue as RegisterValue\n const samePath = wantsOptOut && (value as RegisterValue).path === old.path\n if (!samePath) old.unmarkNoSync?.()\n }\n if (wantsOptOut) {\n const v = value as RegisterValue\n const samePathOld = wasOptedOut && (oldValue as RegisterValue).path === v.path\n if (!samePathOld) v.markNoSync?.()\n }\n}\n\n/**\n * Migrate the element's registration entry across binding-value\n * transitions. Symmetric with `syncPersistOptIn` for the\n * persistence opt-in dimension; this one tracks element-to-path\n * registration the form's element map relies on for\n * `getFieldState(path).meta.connected`, `focusFirstError`, and\n * `scrollToFirstError`.\n *\n * Cases:\n * - undefined → undefined: nothing to do.\n * - undefined → RV: register the new RV's element (the per-tag\n * `created` hook skipped this when the binding mounted with an\n * undefined value, so we have to catch up here).\n * - RV → undefined: deregister the old RV's element.\n * - RV → RV (same path + same form): no-op. `register('foo')`\n * returns a fresh closure on every parent re-render; without\n * the early-out, every tick would deregister-and-re-register\n * the element, thrashing the `connected` flag.\n * - RV → RV (different path or different form): deregister old,\n * register new. Covers dynamic-path templates\n * (`v-register=\"form.register(\\`item.${i}\\`)\"`) and the\n * cross-form case where a wrapper component switches the\n * `registerValue` it forwards.\n */\nfunction syncElementRegistration(el: HTMLElement, value: unknown, oldValue: unknown): void {\n const wasRegistered = isRegisterValue(oldValue)\n const isRegistered = isRegisterValue(value)\n if (!wasRegistered && !isRegistered) return\n\n if (wasRegistered && isRegistered) {\n const old = oldValue\n const next = value\n if (old.path === next.path && old.persistOptIns === next.persistOptIns) return\n }\n\n if (wasRegistered) {\n oldValue.deregisterElement(el)\n }\n if (isRegistered) {\n value.registerElement(el)\n }\n}\n\nfunction onCompositionStart(e: Event) {\n const target = e.target as ComposingTarget\n if (!target) return\n\n target.composing = true\n}\n\nfunction onCompositionEnd(e: Event) {\n const target = e.target as ComposingTarget\n if (target?.composing === true) {\n target.composing = false\n target.dispatchEvent(new Event('input'))\n }\n}\n\nfunction makeNoopAssigner(): CustomDirectiveRegisterAssignerFn {\n const noop: CustomDirectiveRegisterAssignerFn = (_) => undefined\n // Tag so `shouldBailListener` recognizes this as the default,\n // alongside the real default-model assigner.\n ;(noop as unknown as DefaultAssignerCarrier)[DEFAULT_ASSIGNER_TAG] = true\n return noop\n}\n\nfunction setAssignFunction(\n el: HTMLElement & { [AssignKey: symbol]: CustomDirectiveRegisterAssignerFn },\n vnode: VNode,\n value: RegisterValue<unknown> | undefined\n) {\n // Pre-install respect: if the consumer installed `el[assignKey]`\n // BEFORE this directive's `created` hook ran (e.g. via a companion\n // directive ordered first in `withDirectives`, or by a custom\n // element's constructor), preserve their assigner across the\n // entire directive lifecycle. The default assigner is a fallback\n // for the common case where nobody overrides; it should NEVER\n // clobber an explicit consumer override.\n if (el[assignKey] !== undefined && !isDefaultAssigner(el[assignKey])) {\n return\n }\n\n // Invariant 4: `v-register=\"undefined\"` is a graceful no-op. The\n // composable `useRegister()` returns `ComputedRef<undefined>` when\n // a child is rendered standalone (no parent passed registerValue);\n // the inner `<input v-register=\"register\">` lands undefined here\n // and we silently install a no-op assigner. The composable already\n // emitted its own dev-warn at the call site, so a second warn from\n // the directive would be redundant noise.\n //\n // Other non-RegisterValue types still fall through to the warn —\n // those are likely typos (passing a string, an object literal, the\n // form API itself, etc.) and the developer benefits from a hint.\n if (value === undefined) {\n el[assignKey] = makeNoopAssigner()\n return\n }\n if (!isRegisterValue(value)) {\n warn(\n `v-register expected a RegisterValue, got '${typeof value}'. ` +\n `Bind to form.register('field') — not the field's ref, value, or path string.`\n )\n el[assignKey] = makeNoopAssigner()\n return\n }\n\n el[assignKey] = getModelAssigner(el, vnode, value)\n}\n\n// We are exporting the v-model runtime directly as vnode hooks so that it can\n// be tree-shaken in case v-model is never used.\nconst vRegisterText: RegisterTextCustomDirective = {\n created(el, { value, modifiers: { lazy, trim, number } }, vnode) {\n const castToNumber = number === true || vnode.props?.['type'] === 'number'\n if (isRegisterValue(value)) {\n value.registerElement(el)\n setAssignFunction(el, vnode, value)\n }\n addEventListener(el, lazy === true ? 'change' : 'input', (e) => {\n // Bail if this listener was attached on a non-supported root\n // (a `<label>` / `<div>` etc.) AND the assigner is the default.\n // The bubbled-write bug fires here without this guard: a\n // descendant's `input` event reaches this handler, reads\n // `el.value` off the wrapper (`''` in jsdom, `undefined` in\n // browsers), and clobbers the form. See `shouldBailListener`.\n if (shouldBailListener(el)) return\n const target = e.target as ComposingTarget\n if (target === null || target.composing) return\n let domValue: string | number = el.value\n // Deferred-to-blur trim: only trim here when this listener is\n // already on `change` (i.e. `.lazy.trim`). Per-keystroke trim\n // on the `input` event fights Vue's `:value` patch — when the\n // user types a trailing space the trimmed write reaches the\n // model first, Vue's patch then sees `el.value` ahead of the\n // model and rewrites the DOM back to the trimmed form,\n // swallowing the space the user is still typing. The `change`-\n // bound normalization listener below catches the canonical\n // trimmed write at blur instead.\n if (trim === true && lazy === true) {\n domValue = domValue.trim()\n }\n if (castToNumber) {\n // Empty after the (deferred) trim — most commonly a backspace-\n // clear on `<input type=\"number\">` or a `.number` text input.\n // Mark the path blank rather than skipping silently:\n // storage gets the slim default (0), the UI shows blank via\n // `displayValue.value === ''`, and submit-time validation\n // raises \"No value supplied\" if the schema demands a number (the\n // public-housing footgun fix). Without this, the directive's\n // pre-fix skip-on-empty silently desynced storage from UI.\n //\n // `<input type=\"number\">` quirk: the browser blanks `el.value`\n // mid-typing for malformed input (`1e` is incomplete scientific\n // notation, so the browser hides the typed text from\n // `el.value` even though it's still visually in the DOM).\n // `validity.badInput` is `true` in that case and `false` for\n // a genuine empty field — we use it to distinguish a real\n // user-clear (mark) from a transient mid-edit (skip). Without\n // this guard, typing `1e` into a `type=\"number\"` field fires\n // `markBlank`, `displayValue` recomputes to `''`,\n // Vue patches the DOM and yanks the user's `1e` away.\n if (domValue === '') {\n // Guard against non-input elements with custom assigners\n // (the directive bails on default-assigner non-inputs via\n // `shouldBailListener`, but a consumer-installed assigner\n // can land on any tag — `validity` only exists on form\n // controls). The cast types `validity` as optional to\n // capture that shape.\n const validity = (el as { validity?: ValidityState }).validity\n if (validity?.badInput === true) {\n return\n }\n if (isRegisterValue(value)) {\n writeLastTypedForm(value, null)\n value.markBlank()\n }\n return\n }\n const typedString = domValue\n domValue = looseToNumber(domValue)\n if (typeof domValue !== 'number') {\n // Non-castable garbage like \"abc\" — text input with `.number`,\n // not protected by the beforeinput filter (e.g. consumer\n // pasted via JS or programmatic `el.value = 'abc'`). Treat\n // as the empty case so the gate's slim-primitive rejection\n // doesn't surface a dev warning for a transient mid-edit\n // state.\n if (isRegisterValue(value)) {\n writeLastTypedForm(value, null)\n value.markBlank()\n }\n return\n }\n if (!Number.isFinite(domValue)) {\n // Overflow: parseFloat returned Infinity / -Infinity for\n // values past Number.MAX_VALUE (e.g. `1e309`). Don't commit\n // — Zod's z.number() rejects non-finite, and\n // JSON.stringify() renders Infinity as `null`, both confusing\n // for devs and downstream consumers. Snap the DOM back to\n // the last good displayValue so the user gets immediate\n // visual feedback that their input was rejected (analogous\n // to a native `<input type=\"number\" max>` cap). Storage\n // stays at whatever the last finite write committed.\n if (isRegisterValue(value)) {\n const target = value.displayValue.value\n if (el.value !== target) el.value = target\n }\n return\n }\n // Castable: record the user's typed string so `displayValue`\n // surfaces it mid-typing. Storage commits real-time via the\n // assigner below; without `lastTypedForm`, Vue's `:value`\n // patch would write `String(cast)` (e.g. `'100'`) into the\n // DOM and yank the user away from the `1e2` they're typing.\n // The blur normalizer clears `lastTypedForm` so the post-blur\n // DOM matches storage exactly.\n if (isRegisterValue(value)) writeLastTypedForm(value, typedString)\n }\n el[assignKey]?.(domValue)\n // After the default assigner runs, force-sync the DOM when\n // storage diverges from the post-cast/post-trim `domValue`.\n // Two cases produce no Vue re-render and so leave the\n // imperative `beforeUpdate` DOM-from-storage sync stranded:\n // 1. A `transforms` pipeline mutated the write to a value\n // identical to current storage (a clamp at the cap, an\n // idempotent normalize, a coerce that re-emits the prior\n // stored shape) — `setValueWithInternalPath` produces no\n // patch, no reactive trigger, no render.\n // 2. The slim-primitive gate (or a transform-throw) silently\n // rejected the write — storage stays at the prior value,\n // again no render.\n // Either way the DOM keeps the user's raw typed text divorced\n // from storage. Comparing post-cast `domValue` (not the raw\n // typed string) preserves the typed-form contract: typing\n // `1e2` against a number schema casts to 100, storage updates\n // to 100, post-cast `domValue === storage`, no force-sync —\n // the user keeps seeing `1e2` mid-typing.\n //\n // Gated on `isDefaultAssigner` because custom assigners\n // (`@update:registerValue`, pre-installed `el[assignKey]`)\n // own their own DOM/storage relationship — they may write to\n // a different store, defer / batch / debounce, or intentionally\n // not update `innerRef.value`. The default assigner's contract\n // (\"a successful write reflects in `innerRef.value` immediately\")\n // is what makes the post-write storage comparison meaningful.\n if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {\n const storage = value.innerRef.value\n if (storage !== domValue) {\n const display = storage == null ? '' : String(storage)\n if (el.value !== display) el.value = display\n if (castToNumber) writeLastTypedForm(value, null)\n }\n }\n })\n if (trim === true || castToNumber) {\n addEventListener(el, 'change', () => {\n if (shouldBailListener(el)) return\n // Mirror Vue's `castValue(el.value, trim, castToNumber)` so the\n // visible DOM normalizes after blur for both modifiers — without\n // the cast branch, a user typing ` 12 ` into a `.number` input\n // sees ` 12 ` stick after blur instead of `12`.\n let normalized: string | number = el.value\n if (trim === true) normalized = normalized.trim()\n if (castToNumber) {\n const cast = looseToNumber(normalized)\n if (typeof cast === 'number' && Number.isFinite(cast)) {\n // Blur: clear the typed-form override so `displayValue`\n // returns `String(storage)`. The DOM then patches to the\n // canonical form (`'1e2'` → `'100'`, `'01'` → `'1'`,\n // `'1.'` → `'1'`). Honest by design — what the user sees\n // after blur matches what's in storage. The model commit\n // is gated on `lazy !== true` because the lazy listener\n // already wrote on the same change event ahead of this\n // handler.\n if (isRegisterValue(value)) writeLastTypedForm(value, null)\n el.value = String(cast)\n if (lazy !== true) el[assignKey]?.(cast)\n } else {\n // Uncastable mid-edit residue (lone '.', '-', 'abc') OR\n // overflow (`1e309` parses to Infinity). Native\n // `<input type=\"number\">` blur behaviour clears in both\n // cases; we match that. The keystroke listener has\n // already markBlank'd uncastable input under\n // non-lazy, but under `.lazy.number` (or for an overflow\n // pasted directly via the change event) this is the first\n // chance, so re-mark defensively.\n if (isRegisterValue(value)) {\n writeLastTypedForm(value, null)\n value.markBlank()\n }\n el.value = ''\n }\n return\n }\n el.value = typeof normalized === 'number' ? String(normalized) : normalized\n // Catch up the model on blur for non-lazy `.trim`. The input\n // listener wrote the raw mid-typing value (deferred trim);\n // here on `change` we commit the canonical trimmed form so\n // the DOM and the model agree once the user leaves the\n // field. Under `.lazy.trim`, the input listener (on\n // `change`) already wrote the trimmed value, so this branch\n // skips to avoid a redundant duplicate write.\n if (trim === true && lazy !== true) {\n el[assignKey]?.(normalized)\n }\n })\n }\n if (lazy !== true) {\n addEventListener(el, 'compositionstart', onCompositionStart)\n addEventListener(el, 'compositionend', onCompositionEnd)\n // Safari < 10.2 & UIWebView doesn't fire compositionend when\n // switching focus before confirming composition choice\n // this also fixes the issue where some browsers e.g. iOS Chrome\n // fires \"change\" instead of \"input\" on autocomplete.\n addEventListener(el, 'change', onCompositionEnd)\n }\n // `.number` × text input — block non-numeric characters at the\n // DOM layer so `el.value` never holds garbage. Native\n // `<input type=\"number\">` already filters at the browser layer,\n // so we skip the listener there to avoid double-filtering. The\n // regex allows an optional leading `-`, a single `.`, any number\n // of digits, and an optional scientific-notation suffix\n // (`[eE][+-]?\\d*`) so devs get parity with native `type=\"number\"`\n // for inputs like `1e3`. Partial states (just `-`, `1.`, `1e`,\n // `1e-`) are accepted as the user is still typing; the blur\n // normalizer commits the cast value (or clears the DOM if the\n // residue is non-castable). Composition events\n // (`insertCompositionText`) aren't blocked — IME input proceeds\n // normally and the directive's `compositionend` handler catches\n // the final value.\n if (number === true && vnode.props?.['type'] !== 'number') {\n addEventListener(el, 'beforeinput', (e) => {\n const ev = e as InputEvent\n if (\n ev.inputType !== 'insertText' &&\n ev.inputType !== 'insertFromPaste' &&\n ev.inputType !== 'insertFromDrop'\n ) {\n return\n }\n const data = ev.data\n if (data === null) return\n const start = el.selectionStart ?? 0\n const end = el.selectionEnd ?? 0\n const next = el.value.slice(0, start) + data + el.value.slice(end)\n if (!/^-?\\d*\\.?\\d*([eE][+-]?\\d*)?$/.test(next)) ev.preventDefault()\n })\n }\n },\n // set value on mounted so it's after min/max for type=\"range\"\n mounted(el, { value }) {\n if (!isRegisterValue(value)) return\n\n // Read through `displayValue` rather than `innerRef`: it's the\n // string projection that already honours `blankPaths` (returns\n // `''` for a numeric leaf marked blank, even though storage\n // holds the slim default `0`). Without this, the storage `0`\n // round-trips to `'0'` here and the change handler at blur\n // sees `el.value === '0'`, casts to 0, and writes-back through\n // the assigner — wiping the blank flag and locking the user\n // out of the empty display state.\n el.value = value.displayValue.value\n },\n beforeUpdate(el, { value, oldValue, modifiers: { lazy, trim } }, vnode) {\n setAssignFunction(el, vnode, value)\n // Skip the el.value sync while the user is mid-IME-composition;\n // overwriting `el.value` would clobber the unresolved input.\n if ((el as { composing?: boolean }).composing === true) return\n if (!isRegisterValue(value)) return\n\n // `displayValue` is the canonical string view: it folds in the\n // blank/unset rule (returns `''` for blank-marked numeric\n // leaves) AND the typed-form preference (`lastTypedForm` so\n // mid-typing `'1e2'` doesn't get clobbered by a sibling\n // re-render). String comparison against the live DOM is honest:\n // pre-fix this branch parsed `el.value` through `looseToNumber`\n // and compared against raw storage, which paints `'0'` over a\n // blank-empty DOM on every reactive update.\n const target = value.displayValue.value\n if (el.value === target) {\n return\n }\n\n // ShadowRoot-aware activeElement check: a v-register'd input mounted\n // inside a shadow tree's `activeElement` lives on the rootNode, not\n // on `document`. Falling back to `document.activeElement === el` for\n // shadow-mounted inputs would always be `false`, defeating the\n // lazy/trim escape-hatches below.\n const rootNode = el.getRootNode()\n const activeElement =\n rootNode instanceof Document || rootNode instanceof ShadowRoot ? rootNode.activeElement : null\n if (activeElement === el && el.type !== 'range') {\n // Lazy escape: the consumer chose `change`-only updates. While\n // the user is still editing, suppress reverse-syncs that would\n // otherwise revert their typing on every parent re-render.\n if (lazy === true && value.innerRef.value === oldValue) {\n return\n }\n // Trim escape: same rationale — the trimmed-but-otherwise-equal\n // value is what we'd land on at blur anyway, so don't fight the\n // user's whitespace mid-typing.\n if (trim === true && el.value.trim() === target) {\n return\n }\n }\n\n el.value = target\n },\n}\n\nconst vRegisterCheckbox: RegisterCheckboxCustomDirective = {\n // #4096 array checkboxes need to be deep traversed\n deep: true,\n created(el, { value }, vnode) {\n if (!isRegisterValue(value)) return\n\n value.registerElement(el)\n setAssignFunction(el, vnode, value)\n addEventListener(el, 'change', () => {\n if (shouldBailListener(el)) return\n const modelValue = value.innerRef.value ?? []\n\n // this side-steps subtle 2-way binding bugs where ref updates but input cannot be tracked by value\n const explicitValueRequired = true\n const rawElementValue = getValue(el, explicitValueRequired)\n\n const checked = el.checked\n const assign = el[assignKey]\n if (isArray(modelValue)) {\n if (rawElementValue === undefined) {\n warn(\n 'Checkbox bound to an array model is missing a `value` attribute — ' +\n 'cannot determine which item to add or remove. ' +\n 'Add value=\"...\" to each <input type=\"checkbox\">.'\n )\n return\n }\n // Element-level coerce on the raw DOM value so the\n // looseIndexOf lookup and the new array's element shape\n // match the post-coerce model. Without this, the change\n // handler builds a mixed-type array (e.g. boolean members\n // plus a raw string) and either fails to find the existing\n // entry on uncheck (case-sensitive looseEqual on booleans)\n // or appends a string to a typed-element array. The path-\n // level coerce in the assigner cleans up the new array\n // afterwards either way.\n const elementValue = applyElementCoerce(rawElementValue, value)\n const index = looseIndexOf(modelValue, elementValue)\n const found = index !== -1\n if (checked && !found) {\n assign?.(modelValue.concat(elementValue))\n } else if (!checked && found) {\n const filtered = [...modelValue]\n filtered.splice(index, 1)\n assign?.(filtered)\n }\n } else if (isSet(modelValue)) {\n if (rawElementValue === undefined) {\n warn(\n 'Checkbox bound to a Set model is missing a `value` attribute — ' +\n 'cannot determine which item to add or remove. ' +\n 'Add value=\"...\" to each <input type=\"checkbox\">.'\n )\n return\n }\n // Set's `.delete` uses strict ===, so coerce the element\n // BEFORE the Set ops or removals silently fail when the\n // model holds post-coerce booleans/numbers and the DOM\n // gives back the raw string.\n const elementValue = applyElementCoerce(rawElementValue, value)\n const cloned = new Set(modelValue)\n if (checked) {\n cloned.add(elementValue)\n } else {\n cloned.delete(elementValue)\n }\n assign?.(cloned)\n } else {\n assign?.(getCheckboxValue(el, checked))\n }\n // After the default assigner runs, force-sync `el.checked` to\n // current storage. Catches the no-op-write case: a transform\n // mapped the click's value to current storage (e.g. an always-\n // false transform on an already-false checkbox) — no patch, no\n // render, no `beforeUpdate` setChecked. Without this the DOM\n // stays at the user's click state, divorced from storage.\n // Skipped for custom assigners (they own DOM/storage sync).\n if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {\n setChecked(el, value)\n el._lastAppliedModel = value.innerRef.value\n }\n })\n },\n // set initial checked on mount to wait for true-value/false-value\n mounted(el, { value }) {\n setChecked(el, value)\n if (isRegisterValue(value)) el._lastAppliedModel = value.innerRef.value\n },\n // Skip the DOM sync when the model is identity-unchanged from the\n // last application. Pre-fix the scalar branch in `setChecked`\n // gated on `originalValue === oldValue`, comparing a primitive\n // scalar against the wrapper RegisterValue object — always !==,\n // so the guard was a silent no-op. Array / Set branches lacked\n // any guard. The per-render re-apply mirrors the just-fixed\n // `vRegisterSelect` shape: a sibling's reactive write triggers\n // `beforeUpdate` mid-click, `setChecked` re-applies the prior\n // model state, and the in-flight user toggle is clobbered before\n // the browser fires `change`. Identity comparison on\n // `innerRef.value` is sound for the same reason as multi-select —\n // every form write produces a fresh value at the path (new\n // primitives; new array/Set references along the spine), so\n // reference equality tracks \"did the model move\" exactly.\n beforeUpdate(el, binding, vnode) {\n setAssignFunction(el, vnode, binding.value)\n if (!isRegisterValue(binding.value)) return\n const currentModel = binding.value.innerRef.value\n if (el._lastAppliedModel === currentModel) return\n setChecked(el, binding.value)\n el._lastAppliedModel = currentModel\n },\n}\n\nfunction setChecked(el: HTMLInputElement, value: unknown): void {\n if (!isRegisterValue(value)) return\n\n const originalValue = value.innerRef.value\n let checked: boolean\n\n // Read the option-value via `getValue(el)` rather than\n // `vnode.props?.['value']`. On SSR + hydration, Vue skips\n // `patchProp` for hoisted static `value=\"...\"` attributes — vnode\n // props don't carry the value AND `el._value` is never set, so the\n // old code returned undefined and unchecked the box even when the\n // DOM `value` attribute matched the model. `getValue` (post the\n // static-attr fix) checks `_value` first, then the DOM property,\n // so all three paths (Vue dynamic, Vue hydrated static, manual\n // setAttribute) resolve identically.\n // All three branches compare the post-coerce model against the\n // RAW DOM-side value (the option's `value` attribute, or the\n // checkbox's `_trueValue`). Coerce normalizes the WRITE direction\n // (e.g. `\"True\"` → `true` for `z.boolean()`); without symmetric\n // normalization on the READ direction, `looseEqual` /\n // `looseIndexOf` / `Set.has` fight the user's click on every\n // re-render. Route the raw value through the same `applyCoerce`\n // closure to restore parity. See setChecked-mid-coerce regression\n // tests in coerce.test.ts.\n if (isArray(originalValue)) {\n // Element-level coerce: the DOM-side raw value is a SCALAR\n // matching against the array's element type, not the path's\n // top-level type (which would be `array`, with no scalar\n // coerce target).\n checked = looseIndexOf(originalValue, applyElementCoerce(getValue(el), value)) > -1\n } else if (isSet(originalValue)) {\n // Set.has uses SameValueZero (===), not loose comparison —\n // mismatch is fatal here, not just for case-sensitive booleans.\n checked = originalValue.has(applyElementCoerce(getValue(el), value))\n } else {\n const trueValueCoerced = applyCoerce(getCheckboxValue(el, true), value)\n checked = looseEqual(originalValue, trueValueCoerced)\n }\n\n if (el.checked !== checked) {\n el.checked = checked\n }\n}\n\nconst vRegisterRadio: RegisterRadioCustomDirective = {\n created(el, { value }, vnode) {\n if (!isRegisterValue(value)) return\n\n value.registerElement(el)\n setAssignFunction(el, vnode, value)\n addEventListener(el, 'change', () => {\n if (shouldBailListener(el)) return\n el[assignKey]?.(getValue(el))\n // After the default assigner runs, force-sync `el.checked` to\n // current storage. Catches the no-op-write case where a\n // transform maps the click's value to current storage — no\n // patch, no render, no `beforeUpdate` sync. Skipped for custom\n // assigners (they own DOM/storage sync).\n if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {\n const currentModel = value.innerRef.value\n const target = looseEqual(currentModel, applyCoerce(getValue(el), value))\n if (el.checked !== target) el.checked = target\n el._lastAppliedModel = currentModel\n }\n })\n },\n // Initial checked-state sync runs in `mounted`, NOT `created` —\n // Vue's directive lifecycle fires `created` BEFORE the element's\n // attributes are patched (`type`, `value`, `_value` etc. aren't on\n // the element yet), so `getValue(el)` would return `undefined` and\n // every radio in a group would mount unchecked regardless of the\n // model. Checkbox already uses `mounted: setChecked` for the same\n // reason.\n mounted(el, { value }) {\n if (!isRegisterValue(value)) return\n // Read the option-value via `getValue(el)` rather than\n // `vnode.props?.['value']` so SSR-hydrated static `value=\"...\"`\n // attributes (which don't surface in vnode.props because Vue's\n // static-attr fast path skips patchProp) still resolve correctly.\n // Coerce the raw value the same way the change handler will so\n // the comparison stays symmetric — see setChecked's note.\n el.checked = looseEqual(value.innerRef.value, applyCoerce(getValue(el), value))\n el._lastAppliedModel = value.innerRef.value\n },\n // Skip the DOM sync when the model is identity-unchanged from the\n // last application. Pre-fix the guard read `value.innerRef.value\n // !== oldValue`, comparing a primitive scalar against the previous\n // binding's wrapper RegisterValue object — always !==, so the\n // guard was a silent no-op and `el.checked = …` re-applied on\n // every parent re-render. Same shape as the just-fixed\n // `vRegisterSelect` and `setChecked` bugs: a sibling's reactive\n // write triggers `beforeUpdate` mid-click and writes back the\n // prior model state, clobbering the in-flight selection.\n beforeUpdate(el, { value }, vnode) {\n if (!isRegisterValue(value)) return\n\n setAssignFunction(el, vnode, value)\n const currentModel = value.innerRef.value\n if (el._lastAppliedModel === currentModel) return\n el.checked = looseEqual(currentModel, applyCoerce(getValue(el), value))\n el._lastAppliedModel = currentModel\n },\n}\n\nconst vRegisterSelect: RegisterSelectCustomDirective = {\n // <select multiple> value need to be deep traversed\n deep: true,\n created(el, { value, modifiers: { number } }, vnode) {\n if (!isRegisterValue(value)) return\n\n value.registerElement(el)\n const isSetModel = isSet(value.innerRef.value)\n addEventListener(el, 'change', () => {\n if (shouldBailListener(el)) return\n const selectedVal = Array.prototype.filter\n .call(el.options, (o: HTMLOptionElement) => o.selected)\n .map((o: HTMLOptionElement) => (number === true ? looseToNumber(getValue(o)) : getValue(o)))\n const wrote = el[assignKey]?.(\n el.multiple ? (isSetModel ? new Set(selectedVal) : selectedVal) : selectedVal[0]\n )\n // Only set `_assigning` when the write actually landed. A\n // rejected write (slim-primitive gate said no) should NOT\n // suppress the next `updated` hook's `setSelected` — we want\n // the DOM to revert to `innerRef.value` since the form state\n // didn't change. `undefined` from a consumer-installed assigner\n // counts as \"succeeded\" for back-compat (their assigner has no\n // way to signal otherwise).\n if (wrote !== false) {\n el._assigning = true\n void nextTick(() => {\n el._assigning = false\n })\n }\n // After the default assigner runs, force-sync the `<select>`\n // selection to current storage. Catches the no-op-write case:\n // a transform mapped the user's pick to current storage (e.g.\n // always-fixed transform) — no patch, no render, no `updated`\n // setSelected. Without this the DOM stays at the user's\n // selection, divorced from storage. Skipped for custom\n // assigners (they own DOM/storage sync).\n if (isRegisterValue(value) && isDefaultAssigner(el[assignKey])) {\n setSelected(el, value)\n el._lastAppliedModel = value.innerRef.value\n }\n })\n setAssignFunction(el, vnode, value)\n },\n // set value in mounted & updated because <select> relies on its children\n // <option>s.\n mounted(el, { value }) {\n setSelected(el, value)\n if (isRegisterValue(value)) el._lastAppliedModel = value.innerRef.value\n },\n beforeUpdate(el, binding, vnode) {\n setAssignFunction(el, vnode, binding.value)\n },\n // Skip the DOM sync when the model is identity-unchanged from the\n // last application. Parent re-renders fire `updated` whether or not\n // the bound model actually moved (a typed character in a sibling,\n // an async-validation tick, any reactive read elsewhere on the\n // page). Without this guard, every such render unconditionally re-\n // applies `setSelected` against the prior model, which on a\n // `<select multiple>` clobbers any in-progress user selection\n // between mousedown and the browser's change-event decision — the\n // browser then sees no net change, never fires `change`, and the\n // model never updates. Identity comparison is sound: every form\n // write produces a new array/Set reference at the path (the diff-\n // apply replacement of `form.value` rolls forward fresh structures\n // along the spine), so reference equality on `innerRef.value`\n // tracks \"did the model move\" exactly. The `_assigning` gate stays\n // — it short-circuits the immediate post-write render where the\n // DOM is already in sync from the user's click.\n updated(el, { value }) {\n if (el._assigning === true) return\n if (!isRegisterValue(value)) return\n const currentModel = value.innerRef.value\n if (el._lastAppliedModel === currentModel) return\n setSelected(el, value)\n el._lastAppliedModel = currentModel\n },\n}\n\nfunction setSelected(el: HTMLSelectElement, value: unknown) {\n if (!isRegisterValue(value)) return\n\n // Use the model value directly — mirrors Vue's reference\n // `vModelSelect.setSelected`. Pre-fix this went through a\n // `getBaseValue` indirection that read DOM-current selection state\n // instead of the model, returning an empty Set for single-select\n // numeric models. The downstream `looseEqual('1', Set{})` always\n // failed, so `selectedIndex` ended at `-1` (no option highlighted)\n // even though the bound value matched an option. Single-select with\n // number / string / boolean now correctly drives the DOM via\n // `looseEqual` (which coerces primitives through `String(...)`),\n // and multi-select uses the Array / Set membership it always did.\n const externalValue = value.innerRef.value\n const isMultiple = el.multiple\n const isArrayValue = isArray(externalValue)\n\n if (isMultiple && !isArrayValue && !isSet(externalValue)) {\n if (__DEV__) {\n warn(\n `<select multiple v-register> expected an Array or Set, got ` +\n `${Object.prototype.toString.call(externalValue).slice(8, -1)}. ` +\n `Bind to a list-typed schema (e.g. z.array(z.string()) or z.set(z.string())).`\n )\n }\n return\n }\n // Symmetric misuse: non-multiple select bound to an Array / Set\n // model. The change handler would write `selectedVal[0]` (scalar)\n // back, which the slim-primitive gate rejects against an Array\n // path — so the user's clicks silently fail. Mount-time\n // `looseEqual('a', ['a', 'b'])` also returns false, so no option\n // ever appears highlighted. Bail with a dev-warn pointing at the\n // fix (`add multiple` for list bindings, or use a scalar model).\n if (!isMultiple && (isArrayValue || isSet(externalValue))) {\n if (__DEV__) {\n warn(\n `<select v-register> (no \\`multiple\\` attribute) expected a scalar value for its ` +\n `binding, but got ${Object.prototype.toString.call(externalValue).slice(8, -1)}. ` +\n `Add the \\`multiple\\` attribute to bind to a list, or use a scalar schema (e.g. ` +\n `\\`z.string()\\`) for a single-select binding.`\n )\n }\n return\n }\n\n if (isMultiple) {\n // Precompute a `Set<string>` of stringified model members once,\n // then do O(1) lookups per option. Drops the per-option work\n // from O(N) to O(1), so total `setSelected` cost is O(N + M)\n // for an N-item model and an M-option <select> — matters for\n // long forms (thousands of options or selected items). Both\n // Array and Set primitive paths share this; only object-valued\n // option binds (rare) keep their original identity comparisons.\n //\n // Each option's raw `value` is routed through `applyCoerce`\n // before stringifying so the comparison stays symmetric with\n // the change handler's WRITE-side coerce — without it,\n // `String(true) === \"true\"` but the option's raw `\"True\"`\n // stringifies to `\"True\"` and the option silently never matches.\n const stringifiedMembers = new Set<string>()\n const iter: Iterable<unknown> = isArrayValue\n ? (externalValue as ReadonlyArray<unknown>)\n : (externalValue as Set<unknown>)\n for (const v of iter) stringifiedMembers.add(String(v))\n\n for (let i = 0, l = el.options.length; i < l; i++) {\n const option = el.options[i]\n if (!option) continue\n // Element-level coerce: a multi-select's option matches a\n // member of an array/Set model, so the comparison must run\n // against the element type, not the path's top-level type.\n const optionValue = applyElementCoerce(getValue(option), value)\n const optionType = typeof optionValue\n if (optionType === 'string' || optionType === 'number') {\n option.selected = stringifiedMembers.has(String(optionValue))\n } else if (optionType === 'boolean') {\n // Booleans go through the same stringify channel — covers\n // `<option value=\"True\">` × `z.array(z.boolean())` after\n // coerce normalises to `true`.\n option.selected = stringifiedMembers.has(String(optionValue))\n } else if (isArrayValue) {\n // Object option, Array model: structural equality via\n // `looseIndexOf` (mirrors Vue's reference).\n option.selected = looseIndexOf(externalValue, optionValue) > -1\n } else {\n // Object option, Set model: identity-based `.has` (Sets\n // can't structurally compare without iterating, and Vue's\n // reference uses identity here).\n option.selected = (externalValue as Set<unknown>).has(optionValue)\n }\n }\n return\n }\n\n // Non-multiple: find the first option matching the scalar model\n // and set selectedIndex; clear if nothing matches. Coerce the\n // raw option value to keep parity with the change handler.\n for (let i = 0, l = el.options.length; i < l; i++) {\n const option = el.options[i]\n if (!option) continue\n if (looseEqual(applyCoerce(getValue(option), value), externalValue)) {\n if (el.selectedIndex !== i) el.selectedIndex = i\n return\n }\n }\n if (el.selectedIndex !== -1) el.selectedIndex = -1\n}\n\n// retrieve raw value set via :value bindings\n//\n// `explicitRequired` is the checkbox-array / checkbox-Set caller's way\n// of saying \"the user must have provided an option-value via either a\n// dynamic `:value` binding (Vue sets `el._value`) OR a static `value`\n// attribute (DOM has `value` attribute set). If neither is present,\n// the default `el.value` of 'on' would silently add the bogus literal\n// 'on' to the array on every toggle — surface as undefined so the\n// caller can warn instead.\"\n//\n// Without the `hasAttribute('value')` fallback, the SSR + static-attr\n// hydration path fails: Vue's hydration skips patchProp for hoisted\n// static attributes, `el._value` is never set, but the DOM still\n// reflects the rendered `value=\"apple\"` attribute. We need to honor\n// either signal.\nfunction getValue(el: HTMLOptionElement | HTMLInputElement, explicitRequired = false) {\n if ('_value' in el) return el._value\n if (explicitRequired && !el.hasAttribute('value')) return undefined\n return el.value\n}\n\n// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings\nfunction getCheckboxValue(\n el: HTMLInputElement & { _trueValue?: unknown; _falseValue?: unknown },\n checked: boolean\n) {\n const key = checked ? '_trueValue' : '_falseValue'\n return key in el ? el[key] : checked\n}\n\n// Tags the directive's text/checkbox/radio/select variants handle\n// natively. A v-register binding on anything else (a `<div>`, a\n// `<span>`, a Vue component whose root is a non-form element) gets\n// listeners attached normally — but the listener bodies bail (via\n// `shouldBailListener`) when the assigner is still the default. This\n// prevents the bubbled-write bug while letting consumer-installed\n// `assignKey` / `@update:registerValue` shapes flow through.\n//\n// The dev-warn for the \"no escape hatch\" case is deferred to the\n// next tick after `created`, so `useRegister`'s `onMounted` marker\n// has a chance to set `REGISTER_OWNER_MARKER` on the rendered root\n// before the warn check runs. Without the deferral, deeply-nested\n// `useRegister` children would always warn (the directive can't\n// reach the child instance via `binding.instance` — that's the\n// page/parent component, whose `subTree` is the outer element tree,\n// not the child component vnode directly).\nconst SUPPORTED_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\n// One-shot dev-warn dedupe so a v-for over 100 unsupported elements\n// produces one warning, not 100. Keyed by element identity (WeakSet\n// for GC-friendliness).\nconst warnedUnsupportedElements: WeakSet<HTMLElement> | null = __DEV__\n ? new WeakSet<HTMLElement>()\n : null\n\nconst vRegisterDynamic: RegisterModelDynamicCustomDirective = {\n created(el, binding, vnode) {\n // Per-element persist opt-in is reconciled at the dynamic level so\n // the per-tag variants stay focused on their input semantics.\n syncPersistOptIn(el, binding.value, undefined)\n // Per-path multi-tab opt-out lives at the dynamic level too —\n // ref-counted on the FormStore so multiple bindings on the same\n // path balance correctly across conditional renders.\n syncMultiTabOptOut(binding.value, undefined)\n\n // Always run the per-tag variant's `created` — listener-body bail\n // (`shouldBailListener`) prevents the bubbled-write bug on\n // non-supported roots while letting consumer overrides through.\n callModelHook(el, binding, vnode, null, 'created')\n\n // Defer the unsupported-element warn to nextTick. By then:\n // - useRegister's onMounted has run, setting REGISTER_OWNER_MARKER\n // on the el if the child component called useRegister()\n // - any post-install assignKey override (via onMounted /\n // ref-callback) is in place, so the assigner isn't default\n // anymore. The warn fires only when neither escape hatch was used.\n if (\n __DEV__ &&\n warnedUnsupportedElements !== null &&\n !SUPPORTED_TAGS.has(el.tagName) &&\n !warnedUnsupportedElements.has(el)\n ) {\n void nextTick(() => {\n if (warnedUnsupportedElements.has(el)) return\n const hasMarker =\n (el as unknown as { [k: symbol]: unknown })[REGISTER_OWNER_MARKER] === true\n const hasUserAssigner = !isDefaultAssigner(\n (el as unknown as { [k: symbol]: unknown })[assignKey]\n )\n if (hasMarker || hasUserAssigner) return\n warnedUnsupportedElements.add(el)\n warn(\n `[attaform] v-register on <${el.tagName.toLowerCase()}> is a no-op — ` +\n `non-input roots aren't bound to text-input semantics. For custom components: ` +\n `call \\`useRegister()\\` in the child's setup and re-bind v-register to an inner ` +\n `native element. Lower-level: install a custom assigner via the \\`assignKey\\` ` +\n `symbol on the element.`\n )\n })\n }\n },\n mounted(el, binding, vnode) {\n callModelHook(el, binding, vnode, null, 'mounted')\n },\n beforeUpdate(el, binding, vnode, prevVNode) {\n // Reactive opt-in toggling: `register('foo', { persist: rememberMe })`\n // re-evaluates on every parent render. `binding.oldValue` holds the\n // prior RegisterValue so the helper can diff persist / path / registry\n // and migrate the entry without thrashing.\n syncPersistOptIn(el, binding.value, binding.oldValue)\n // Reactive multi-tab opt-out toggling — same diff strategy.\n syncMultiTabOptOut(binding.value, binding.oldValue)\n // Same diff for the form's element map. Catches the\n // `useRegister`-driven swap (binding mounted with `undefined`,\n // a real RV arrives on the next render), the dynamic-path case,\n // and the cross-form swap. Same-path + same-form transitions\n // short-circuit so identity-stable bindings don't thrash.\n syncElementRegistration(el, binding.value, binding.oldValue)\n callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate')\n },\n updated(el, binding, vnode, prevVNode) {\n callModelHook(el, binding, vnode, prevVNode, 'updated')\n },\n beforeUnmount(el, { value }) {\n // Detach every listener the variant attached in `created`, regardless\n // of whether the binding is still a valid RegisterValue. An element\n // re-used by KeepAlive / v-show would otherwise double its listener\n // count on the next activation cycle.\n removeTrackedListeners(el)\n\n // Drop every opt-in this element ever held — `removeAllFor` sweeps\n // by elementId rather than (id, path), which covers the case where\n // the binding's path changed across updates and we don't want to\n // hunt for the latest entry.\n if (isRegisterValue(value)) {\n value.persistOptIns.removeAllFor(getOrAssignElementId(el))\n // Mirror cleanup for multi-tab opt-out — decrement ref count so\n // the path doesn't stay tab-local after every opted-out binding\n // unmounts.\n value.unmarkNoSync?.()\n }\n\n if (!isRegisterValue(value)) return\n\n value.deregisterElement(el)\n\n // Remove internal state that the directive attaches directly to the\n // element. If the element is reused (<KeepAlive>, v-show), stale flags\n // like `composing: true` (IME in progress) would swallow user input.\n delete (el as { composing?: boolean }).composing\n delete (el as { _assigning?: boolean })._assigning\n delete (el as unknown as { [k: symbol]: unknown })[assignKey]\n },\n}\n\n// No-op variant for <input type=\"file\">. Setting el.value on a file input\n// throws a DOMException for security reasons; the compile-time transform\n// skips this case, and this runtime directive routes reactive type=\"file\"\n// (e.g. `:type=\"isUpload ? 'file' : 'text'\"`) to a no-op too, still tracking\n// the element for focus-state purposes.\nconst vRegisterFileNoop: RegisterModelDynamicCustomDirective = {\n created(el, { value }) {\n if (!isRegisterValue(value)) return\n value.registerElement(el)\n if (__DEV__) {\n warn(\n '[attaform] v-register on <input type=\"file\"> is not supported. ' +\n 'Handle uploads with a manual @change listener.'\n )\n }\n },\n beforeUnmount(el, { value }) {\n // The file-input variant attaches no listeners, but we still drain\n // the bag defensively — a runtime-typed `:type` binding that flipped\n // from 'text' to 'file' on a reused element would have left the text\n // variant's listeners attached.\n removeTrackedListeners(el)\n if (!isRegisterValue(value)) return\n value.deregisterElement(el)\n },\n}\n\nfunction resolveDynamicModel(tagName: string, type: unknown) {\n // tagName is always uppercase per DOM spec (el.tagName); type comes from\n // vnode.props and is usually a string, but reactive bindings (`:type=\"x\"`)\n // can pass other values — guard defensively.\n if (tagName === 'SELECT') return vRegisterSelect\n if (tagName === 'TEXTAREA') return vRegisterText\n if (typeof type !== 'string') return vRegisterText\n if (type === 'file') return vRegisterFileNoop\n if (type === 'checkbox') return vRegisterCheckbox\n if (type === 'radio') return vRegisterRadio\n return vRegisterText\n}\n\nfunction callModelHook(\n el: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement,\n binding: DirectiveBinding,\n vnode: VNode,\n prevVNode: VNode | null,\n hook: keyof ObjectDirective\n) {\n const modelToUse = resolveDynamicModel(el.tagName, vnode.props?.['type'])\n const fn = modelToUse[hook] as DirectiveHook | undefined\n fn?.(el, binding, vnode, prevVNode)\n}\n\nexport type VXCustomDirective =\n | typeof vRegisterText\n | typeof vRegisterCheckbox\n | typeof vRegisterSelect\n | typeof vRegisterRadio\n | typeof vRegisterDynamic\n\n/**\n * The `v-register` directive. Bind a form field to a native input,\n * select, textarea, checkbox, or radio:\n *\n * ```vue\n * <input v-register=\"form.register('email')\" />\n * <select v-register=\"form.register('country')\">\n * <option value=\"us\">US</option>\n * <option value=\"uk\">UK</option>\n * </select>\n * ```\n *\n * The directive picks the right binding strategy automatically based\n * on the element's `tagName` and `type`. Registered globally by\n * `createAttaform()` — most consumers never import it\n * directly, but it's exposed for advanced integrations that wire\n * directives manually.\n */\nexport const vRegister = vRegisterDynamic\n","import type { App, Plugin } from 'vue'\nimport { __DEV__ } from './dev'\nimport { attachRegistryToApp, createRegistry, type AttaformRegistry } from './registry'\nimport { vRegister } from './directive'\nimport type { SSRDetectOptions } from './ssr'\nimport type { AttaformDefaults } from '../types/types-api'\n\n/**\n * Options for `createAttaform()`.\n */\nexport type AttaformPluginOptions = SSRDetectOptions & {\n /**\n * Whether to install the Vue DevTools integration. Default `true`.\n * The DevTools peer dependency is loaded lazily — in production\n * builds where it's absent, the import fails silently and no\n * extra bundle is shipped. Pass `false` to skip even attempting\n * the import.\n */\n devtools?: boolean\n /**\n * App-level defaults applied to every `useForm` call in this app.\n * Per-form options always win. See `AttaformDefaults` for\n * the supported option set and the merge rules.\n *\n * ```ts\n * app.use(\n * createAttaform({\n * defaults: { debounceMs: 100 },\n * })\n * )\n * ```\n */\n defaults?: AttaformDefaults\n}\n\n/**\n * Install the form library on a Vue app. Idempotent: a second call\n * for the same `app` is a no-op (with a dev warning when explicit, no\n * warning when triggered by the lazy-install path).\n *\n * Used internally by:\n * - `createAttaform()` — the explicit plugin install path.\n * - `ensureAttaformInstalled()` — the lazy-install path triggered by\n * `useForm` / `injectForm` / `useRegister` when no explicit install\n * has happened yet.\n *\n * Both paths converge here so the `_attaform` slot, the\n * `kAttaformRegistry` provide, the `v-register` directive, and the\n * devtools attach happen in the same order regardless of how the\n * registry was first attached.\n */\nfunction installAttaformOnApp(\n app: App,\n options: AttaformPluginOptions,\n source: 'explicit' | 'lazy'\n): AttaformRegistry {\n // Idempotent install: a second call (e.g. createAttaform() registered\n // twice via vite.config + nuxt module, or createAttaform() after a\n // lazy useForm call) would otherwise overwrite the existing registry —\n // orphaning every FormStore the previous instance had built. Detect\n // via the `_attaform` slot `attachRegistryToApp` writes; bail with a\n // dev warning ONLY for the explicit path, since the lazy path is\n // expected to no-op when the user has already installed explicitly.\n if (app._attaform !== undefined) {\n if (__DEV__ && source === 'explicit') {\n console.warn(\n '[attaform] createAttaform() install was called twice on the same app; ' +\n 'the second call is a no-op. ' +\n 'Likely cause: registering the plugin via both the Nuxt module AND a manual `app.use(...)`.'\n )\n }\n return app._attaform\n }\n const registry = createRegistry(options)\n attachRegistryToApp(app, registry)\n app.directive('register', vRegister)\n\n if (options.devtools !== false && !registry.ssr) {\n void (async () => {\n try {\n const { setupAttaformDevtools } = await import('./devtools')\n await setupAttaformDevtools(app, registry)\n } catch {\n // Missing peer dep / DevTools not attached — silently skip.\n // The form runtime works without DevTools; this is pure-\n // observability tooling.\n }\n })()\n }\n\n return registry\n}\n\n/**\n * Lazy-install the form library on a Vue app from inside a setup\n * context. Called by `useForm`, `injectForm`, and `useRegister` so\n * `pnpm install attaform` is the entire setup story for the common\n * CSR case — no `app.use(createAttaform())` required in `main.ts`.\n *\n * If the app already has an attaform registry attached (because the\n * consumer installed `createAttaform({ defaults, devtools })` or the\n * Nuxt module ran), this is a no-op and the existing registry is\n * returned. App-wide options are preserved.\n *\n * SSR helpers (`renderAttaformState`, `hydrateAttaformState`) do NOT\n * use this path — they run outside setup and require explicit\n * `createAttaform()` install.\n */\nexport function ensureAttaformInstalled(app: App): AttaformRegistry {\n return installAttaformOnApp(app, {}, 'lazy')\n}\n\n/**\n * Create the Vue plugin that installs the form library on a Vue\n * application. Required only when you want app-wide options\n * (`defaults`, `devtools: false`, `ssr: true`) — for the default\n * setup, `useForm` / `injectForm` / `useRegister` lazy-install the\n * registry on first use.\n *\n * ```ts\n * import { createApp } from 'vue'\n * import { createAttaform } from 'attaform'\n *\n * createApp(App)\n * .use(createAttaform({ defaults: { debounceMs: 100 } }))\n * .mount('#app')\n * ```\n *\n * Under SSR with bare Vue 3, install explicitly with `{ ssr: true }`\n * from your server entry — the SSR serialization helpers\n * (`renderAttaformState` / `hydrateAttaformState`) require an\n * already-attached registry and don't trigger lazy install. Under\n * Nuxt, install via `attaform/nuxt` instead — the Nuxt module wires\n * both server and client automatically.\n *\n * Installing more than once on the same app is a no-op (the second\n * call logs a dev-mode warning).\n */\nexport function createAttaform(options: AttaformPluginOptions = {}): Plugin {\n const plugin: Plugin = {\n install(app: App) {\n installAttaformOnApp(app, options, 'explicit')\n },\n }\n return plugin\n}\n"],"names":["target"],"mappings":"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"}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, d as UseFormReturnType, R as RegisterValue } from './attaform.C_5aB6EQ.js';
|
|
2
|
-
import { Ref } from 'vue';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Access an existing form from a descendant component without passing
|
|
6
|
-
* it through props. Counterpart to `useForm` — `useForm` creates and
|
|
7
|
-
* provides; `injectForm` looks up via Vue's inject mechanism.
|
|
8
|
-
*
|
|
9
|
-
* Two ways to call it:
|
|
10
|
-
*
|
|
11
|
-
* ```ts
|
|
12
|
-
* // Reach the nearest ancestor's anonymous useForm() call.
|
|
13
|
-
* const form = injectForm<SignupShape>()
|
|
14
|
-
*
|
|
15
|
-
* // Reach a specific form by its key — works from anywhere in the app.
|
|
16
|
-
* const cart = injectForm<CartShape>('cart')
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* Resolution rules (no-key form):
|
|
20
|
-
* - Closest ambient ancestor wins.
|
|
21
|
-
* - Only anonymous `useForm()` (no `key`) fills the ambient slot;
|
|
22
|
-
* keyed forms are reachable only via `injectForm(key)`.
|
|
23
|
-
* - Inherits the resolved ancestor's `formInstanceId`.
|
|
24
|
-
*
|
|
25
|
-
* Resolution rules (keyed form): registry lookup by string key,
|
|
26
|
-
* independent of component-tree position.
|
|
27
|
-
*
|
|
28
|
-
* Returns `null` when no matching form exists (no ambient ancestor, or
|
|
29
|
-
* the named key isn't registered). A dev-mode warning points at the
|
|
30
|
-
* call site to help diagnose typos. Always narrow before using:
|
|
31
|
-
*
|
|
32
|
-
* ```ts
|
|
33
|
-
* const form = injectForm<Shape>('signup')
|
|
34
|
-
* if (!form) return
|
|
35
|
-
* form.register('email')
|
|
36
|
-
* ```
|
|
37
|
-
*
|
|
38
|
-
* Pass the `Form` generic explicitly — Vue's provide/inject erases
|
|
39
|
-
* generics, so the library can't recover the shape automatically.
|
|
40
|
-
*
|
|
41
|
-
* The form is kept alive for this component's lifetime; once every
|
|
42
|
-
* consumer unmounts, the form is cleaned up automatically.
|
|
43
|
-
*/
|
|
44
|
-
declare function injectForm<Form extends GenericForm, GetValueFormType extends GenericForm = Form>(key?: FormKey): UseFormReturnType<Form, GetValueFormType> | null;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Re-bind a parent's `v-register` onto an inner native element. Use
|
|
48
|
-
* inside a component that wraps a single form field whose root is
|
|
49
|
-
* NOT the input itself (e.g. a labelled-row that renders `<label>`
|
|
50
|
-
* around the input).
|
|
51
|
-
*
|
|
52
|
-
* ```vue
|
|
53
|
-
* <!-- Parent -->
|
|
54
|
-
* <MyInput v-register="form.register('email')" />
|
|
55
|
-
*
|
|
56
|
-
* <!-- MyInput.vue -->
|
|
57
|
-
* <script setup lang="ts">
|
|
58
|
-
* import { useRegister } from 'attaform'
|
|
59
|
-
* const rv = useRegister()
|
|
60
|
-
* // rv.path / rv.segments / rv.formKey / rv.formInstanceId / rv.innerRef
|
|
61
|
-
* // are all reachable directly — no `.value` unwrap.
|
|
62
|
-
* </script>
|
|
63
|
-
*
|
|
64
|
-
* <template>
|
|
65
|
-
* <label class="field">
|
|
66
|
-
* <span>Email</span>
|
|
67
|
-
* <input v-register="rv" />
|
|
68
|
-
* </label>
|
|
69
|
-
* </template>
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* Returns a hybrid Proxy: it answers `__v_isRef` / `.value` like a
|
|
73
|
-
* Vue `Ref<RegisterValue | undefined>` (so templates auto-unwrap
|
|
74
|
-
* correctly and `v-register="rv"` feeds the underlying RV to the
|
|
75
|
-
* directive — preserving the directive's path-migration diff across
|
|
76
|
-
* renders), AND every other property read pierces to the captured
|
|
77
|
-
* RV's field (so `rv.path` works directly in script setup). Reads
|
|
78
|
-
* inside reactive scopes (`computed` / `watchEffect`) track the
|
|
79
|
-
* underlying `shallowRef`, so `rv.path` re-runs when the parent
|
|
80
|
-
* rebinds to a different path.
|
|
81
|
-
*
|
|
82
|
-
* Unbound state: when the parent didn't pass `v-register`, every
|
|
83
|
-
* piercing read returns `undefined` at runtime, and the return type
|
|
84
|
-
* surfaces this honestly as `UseRegisterReturn<V> | undefined`.
|
|
85
|
-
* Consumers defend with optional chaining (`rv?.formKey`,
|
|
86
|
-
* `rv?.segments`); the directive accepts `undefined` peacefully (its
|
|
87
|
-
* binding value type is already `RegisterValue<V> | undefined`), so
|
|
88
|
-
* `v-register="rv"` works whether or not a parent has bound. The
|
|
89
|
-
* composable's `onMounted` warn fires once per instance to surface
|
|
90
|
-
* the misuse case at runtime.
|
|
91
|
-
*
|
|
92
|
-
* Diagnostic: in dev mode, a single `console.warn` fires per instance
|
|
93
|
-
* at `onMounted` if the captured value is still `undefined` — by then
|
|
94
|
-
* the parent has had its full mount lifecycle to bind, so a missing
|
|
95
|
-
* binding is conclusive misuse. The warn does NOT fire on every read
|
|
96
|
-
* of the proxy, and is intentionally silent under SSR
|
|
97
|
-
* (`renderToString` skips `onMounted`); the CSR hydration pass
|
|
98
|
-
* surfaces the same diagnostic without double-counting through Nuxt's
|
|
99
|
-
* `dev:ssr-logs` channel.
|
|
100
|
-
*
|
|
101
|
-
* When the wrapper's root IS the input itself, Vue's attribute
|
|
102
|
-
* fallthrough handles the binding and `useRegister` is unnecessary.
|
|
103
|
-
* For wrappers that bind multiple fields (compound forms), use
|
|
104
|
-
* `injectForm<Form>(key?)` and call `ctx.register(...)` directly.
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Return type of `useRegister()`. Hybrid of `RegisterValue<V>` (so
|
|
109
|
-
* `rv.path` / `rv.segments` / `rv.formKey` etc. work directly in
|
|
110
|
-
* script setup) and `Ref<RegisterValue<V> | undefined>` (so Vue's
|
|
111
|
-
* template auto-unwrap surfaces the underlying RV to `v-register`
|
|
112
|
-
* and the directive's path-migration diff sees the real RV across
|
|
113
|
-
* renders).
|
|
114
|
-
*
|
|
115
|
-
* The two surfaces don't clash at the type level: `RegisterValue`
|
|
116
|
-
* doesn't carry a `value` field, and `Ref<T>`'s `value: T` becomes
|
|
117
|
-
* the hybrid's only `.value`. Older code that read `rv.value?.path`
|
|
118
|
-
* keeps working; new code can write `rv.path` directly.
|
|
119
|
-
*/
|
|
120
|
-
type UseRegisterReturn<V = unknown> = RegisterValue<V> & Ref<RegisterValue<V> | undefined>;
|
|
121
|
-
declare function useRegister<V = unknown>(): UseRegisterReturn<V> | undefined;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Stable identifiers for library-emitted `ValidationError` codes.
|
|
125
|
-
*
|
|
126
|
-
* Convention: `<scope>:<kebab-case-identifier>`. Three scopes are
|
|
127
|
-
* recognised by the library:
|
|
128
|
-
*
|
|
129
|
-
* - `atta:` — emitted by the framework-agnostic core (this map).
|
|
130
|
-
* - `zod:` — emitted by the Zod adapter; computed inline from
|
|
131
|
-
* `issue.code` (e.g. `zod:too_small`). No enum here because
|
|
132
|
-
* Zod's code list evolves.
|
|
133
|
-
* - consumer-defined — anything the consumer's backend / app stamps
|
|
134
|
-
* onto a `ValidationError` (via the `parseApiErrors` wire payload
|
|
135
|
-
* or `setFieldErrors` directly). Pick a scope (`api:`, `auth:`,
|
|
136
|
-
* etc.) and stay consistent.
|
|
137
|
-
*
|
|
138
|
-
* Use these constants in tests and error-routing UI:
|
|
139
|
-
*
|
|
140
|
-
* ```ts
|
|
141
|
-
* if (error.code === AttaformErrorCode.NoValueSupplied) {
|
|
142
|
-
* // user hasn't filled this field
|
|
143
|
-
* }
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
declare const AttaformErrorCode: {
|
|
147
|
-
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
148
|
-
readonly NoValueSupplied: "atta:no-value-supplied";
|
|
149
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
150
|
-
readonly AdapterThrew: "atta:adapter-threw";
|
|
151
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
152
|
-
readonly PathNotFound: "atta:path-not-found";
|
|
153
|
-
};
|
|
154
|
-
type AttaformErrorCode = (typeof AttaformErrorCode)[keyof typeof AttaformErrorCode];
|
|
155
|
-
|
|
156
|
-
export { AttaformErrorCode as A, injectForm as i, useRegister as u };
|