react-f0rm 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -1140
- package/devtools.d.ts +1 -0
- package/devtools.js +1 -0
- package/dist/array-Bu7W8BSz.d.ts +54 -0
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.cjs.js.map +1 -1
- package/dist/devtools/index.d.cts +24 -0
- package/dist/devtools/index.d.mts +24 -0
- package/dist/devtools/index.d.ts +8 -17
- package/dist/devtools/index.mjs +1 -1
- package/dist/devtools/index.mjs.map +1 -1
- package/dist/errors-DA4ReEd9.mjs +2 -0
- package/dist/errors-DA4ReEd9.mjs.map +1 -0
- package/dist/errors-TzyWwBfw.cjs.js +2 -0
- package/dist/errors-TzyWwBfw.cjs.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.cts +1253 -0
- package/dist/index.d.mts +1253 -0
- package/dist/index.d.ts +570 -895
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1256 -535
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/persist.cjs.js +1 -1
- package/dist/persist.cjs.js.map +1 -1
- package/dist/persist.d.cts +28 -0
- package/dist/persist.d.mts +28 -0
- package/dist/persist.d.ts +9 -30
- package/dist/persist.mjs +1 -1
- package/dist/persist.mjs.map +1 -1
- package/dist/resolvers/standard-schema.cjs.js +1 -1
- package/dist/resolvers/standard-schema.cjs.js.map +1 -1
- package/dist/resolvers/standard-schema.d.cts +2 -0
- package/dist/resolvers/standard-schema.d.mts +2 -0
- package/dist/resolvers/standard-schema.d.ts +1 -67
- package/dist/resolvers/standard-schema.mjs +1 -1
- package/dist/resolvers/standard-schema.mjs.map +1 -1
- package/dist/resolvers/yup.cjs.js +1 -1
- package/dist/resolvers/yup.cjs.js.map +1 -1
- package/dist/resolvers/yup.d.cts +6 -0
- package/dist/resolvers/yup.d.mts +6 -0
- package/dist/resolvers/yup.d.ts +0 -1
- package/dist/resolvers/yup.mjs +1 -1
- package/dist/resolvers/yup.mjs.map +1 -1
- package/dist/resolvers/zod.cjs.js +1 -1
- package/dist/resolvers/zod.cjs.js.map +1 -1
- package/dist/resolvers/zod.d.cts +34 -0
- package/dist/resolvers/zod.d.mts +34 -0
- package/dist/resolvers/zod.d.ts +30 -3
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/resolvers/zod.mjs.map +1 -1
- package/dist/server/index.cjs.js +1 -1
- package/dist/server/index.cjs.js.map +1 -1
- package/dist/server/index.d.cts +38 -0
- package/dist/server/index.d.mts +38 -0
- package/dist/server/index.d.ts +26 -65
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/standard-schema-BAaTmAHh.d.ts +682 -0
- package/dist/standardSchema-5WezjHlp.mjs +2 -0
- package/dist/standardSchema-5WezjHlp.mjs.map +1 -0
- package/dist/standardSchema-DINHlsYR.cjs.js +2 -0
- package/dist/standardSchema-DINHlsYR.cjs.js.map +1 -0
- package/dist/validate-2pX-N1O6.cjs.js +2 -0
- package/dist/validate-2pX-N1O6.cjs.js.map +1 -0
- package/dist/validate-C0HOsP9v.mjs +2 -0
- package/dist/validate-C0HOsP9v.mjs.map +1 -0
- package/dist/values-BbPnLByD.cjs.js +2 -0
- package/dist/values-BbPnLByD.cjs.js.map +1 -0
- package/dist/values-CHsmcZk4.mjs +2 -0
- package/dist/values-CHsmcZk4.mjs.map +1 -0
- package/package.json +75 -28
- package/persist.d.ts +1 -0
- package/persist.js +1 -0
- package/resolvers/standard-schema.d.ts +1 -0
- package/resolvers/standard-schema.js +1 -0
- package/resolvers/yup.d.ts +1 -0
- package/resolvers/yup.js +1 -0
- package/resolvers/zod.d.ts +1 -0
- package/resolvers/zod.js +1 -0
- package/server.d.ts +1 -0
- package/server.js +1 -0
- package/dist/errors-BKrUdpfI.cjs.js +0 -2
- package/dist/errors-BKrUdpfI.cjs.js.map +0 -1
- package/dist/errors-CrQBddrJ.mjs +0 -2
- package/dist/errors-CrQBddrJ.mjs.map +0 -1
- package/dist/form-CeKSBs31.d.ts +0 -486
- package/dist/validate-CNtuUhmk.mjs +0 -2
- package/dist/validate-CNtuUhmk.mjs.map +0 -1
- package/dist/validate-Cl4ksNFu.cjs.js +0 -2
- package/dist/validate-Cl4ksNFu.cjs.js.map +0 -1
- package/dist/validate-nksgv1pR.d.ts +0 -272
- package/dist/values-Cu6awQOJ.cjs.js +0 -2
- package/dist/values-Cu6awQOJ.cjs.js.map +0 -1
- package/dist/values-DRY-a32G.mjs +0 -2
- package/dist/values-DRY-a32G.mjs.map +0 -1
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/util.ts","../src/path.ts","../src/core/internals.ts","../src/core/errors.ts","../src/core/dirty.ts","../src/core/touched.ts","../src/core/values.ts","../src/core/validate.ts","../src/core/change.ts","../src/core/submit.ts","../src/form.ts","../src/rules.ts","../src/subscribe.ts","../src/hooks/form.tsx","../src/hooks/path.ts","../src/hooks/stage.ts","../src/hooks/validate.ts","../src/core/unmount.ts","../src/hooks/field.tsx","../src/hooks/fieldArray.ts","../src/context.ts","../src/server.ts","../src/components/Field.tsx","../src/components/Form.tsx","../src/components/FormField.tsx","../src/core/focus.ts","../src/hooks/transform.ts"],"sourcesContent":["import {on} from './emitter';\nimport type {EventEmitter} from './emitter';\n\n/** FIFO bound for {@link pathCache}. Static field names ('user.email')\n * number in the dozens per app, so the cache barely grows in practice;\n * the cap is only a backstop for dynamic keys ('items[' + id + ']'\n * style — array inputs skip the cache entirely), where long-lived forms\n * would otherwise accumulate entries forever. Map preserves insertion\n * order, so eviction drops the oldest entry; a dropped string only\n * costs a re-parse the next time normalizePath sees it — results are\n * deterministic, so eviction affects performance, never behavior. */\nconst PATH_CACHE_LIMIT = 1e4;\n\nconst pathCache = new Map<string, (string | number)[]>();\n\n/** Test-only view of the path cache size. Not re-exported from the\n * package entry — tests import this module directly to assert the\n * FIFO bound above. */\nexport const pathCacheSize = () => pathCache.size;\n\nexport function normalizePath(\n path: string | (string | number)[]\n): (string | number)[] {\n if (Array.isArray(path)) return path;\n const cached = pathCache.get(path);\n if (cached) return cached;\n const value = parsePath(path);\n if (pathCache.size >= PATH_CACHE_LIMIT) {\n // Insertion order is FIFO order; the cache is non-empty here\n // because size >= 1e4.\n const oldest = pathCache.keys().next();\n if (!oldest.done) pathCache.delete(oldest.value);\n }\n pathCache.set(path, value);\n return value;\n}\n\n/** Does a segment string denote an integer array index (optionally\n * negative)? The parser feeds it bracket contents ('items[0]' → number)\n * and rejects dotted numerics outright ('items.0' throws), so parsed\n * paths never carry index-looking strings. Its remaining duty is\n * defending programmatic segments: normalizePath also accepts raw\n * (string | number)[] arrays, and index-shaped strings can still arrive\n * from internal callers (error-tree keys) or array containers met\n * during set/setOwned walks. */\nexport const isIndex = (segment: string) => /^-?\\d+$/.test(segment);\n\nfunction parsePath(path: string): (string | number)[] {\n const result: (string | number)[] = [];\n let identifier = '';\n const flushIdentifier = () => {\n if (isIndex(identifier)) {\n // Rebuild both spellings for an actionable message: the dotted\n // form the caller wrote vs. the bracket form the parser accepts.\n const dotted = [...result.map(String), identifier].join('.');\n const bracket = result.reduce(\n (acc: string, seg: string | number) =>\n acc +\n (typeof seg === 'number' ? `[${seg}]` : `${acc ? '.' : ''}${seg}`),\n ''\n );\n throw new TypeError(\n `Numeric path segment must use bracket notation: \"${dotted}\" → \"${bracket}[${identifier}]\" (path: ${path})`\n );\n }\n result.push(identifier);\n identifier = '';\n };\n\n for (let i = 0; i < path.length; i++) {\n const char = path[i];\n if (char === '.') {\n if (identifier !== '') flushIdentifier();\n } else if (char === '[') {\n if (identifier !== '') flushIdentifier();\n const quote = path[i + 1];\n if (quote === '\"' || quote === \"'\") {\n const close = path.indexOf(quote, i + 2);\n if (close === -1) {\n throw new TypeError(`Unterminated quote in path: ${path}`);\n }\n if (path[close + 1] !== ']') {\n throw new TypeError(\n `Expected \"]\" after quoted segment in path: ${path}`\n );\n }\n result.push(path.slice(i + 2, close));\n i = close + 1;\n } else {\n const close = path.indexOf(']', i + 1);\n if (close === -1) {\n throw new TypeError(`Unterminated bracket in path: ${path}`);\n }\n const content = path.slice(i + 1, close);\n result.push(isIndex(content) ? Number(content) : content);\n i = close;\n }\n } else {\n identifier += char;\n }\n }\n if (identifier !== '' || result.length === 0) flushIdentifier();\n return result;\n}\n\nexport function get(values: any, path: (string | number)[]): any {\n return path.reduce((current: any, p: string | number) => {\n if (current == null) return undefined;\n return current[p];\n }, values);\n}\n\n/**\n * Immutable counterpart of {@link set}: removes the path from the value\n * tree, copying only along the touched branch (untouched branches stay\n * shared with the source, like set). Deletes the key entirely rather than\n * writing undefined, so the result carries no `a: undefined` entries.\n */\nexport function unset(values: any, path: (string | number)[]): any {\n if (!path.length || values == null) return values;\n const [prop, ...props] = path;\n if (props.length) {\n const next = unset(values[prop], props);\n // Reattach the pruned child at its parent key — NOT at the full path,\n // which would write the pruned subtree back under the removed key.\n return next === values[prop] ? values : set(values, [prop], next);\n }\n if (Array.isArray(values)) {\n if (!(prop in values)) return values;\n const arr = values.slice();\n delete arr[prop as number];\n return arr;\n }\n if (typeof values !== 'object' || !(prop in values)) return values;\n const copy = {...values};\n delete copy[prop as string];\n return copy;\n}\n\nexport function set(values: any, path: (string | number)[], value: any): any {\n if (!path.length) return value;\n\n const [prop, ...props] = path;\n // A numeric segment lands with the array copy rule — numbers, and the\n // string form dotted paths parse to ('a.0'), on an array container: an\n // object spread there would corrupt the array into {'0': ...}.\n const index =\n typeof prop === 'number'\n ? prop\n : Array.isArray(values) && typeof prop === 'string' && isIndex(prop)\n ? Number(prop)\n : undefined;\n if (index !== undefined) {\n const arr = Array.isArray(values) ? values.slice() : [];\n arr[index] = set(arr[index], props, value);\n return arr;\n }\n return {...values, [prop]: set(values && values[prop], props, value)};\n}\n\n/**\n * Ownership-tracked {@link set}: merge many paths into one tree without\n * re-copying containers the merge itself already created.\n *\n * Containers present in `owned` (freshly created by an earlier call of the\n * same merge) are mutated in place; every other container -- nodes borrowed\n * from the seed tree and user leaf values -- is copied first with the exact\n * copy rules `set` applies (numeric prop: array slice, or a fresh array\n * when the node is not one; string prop: object spread). Chaining\n * `setOwned` over a list of paths therefore produces the tree chaining\n * `set` would, in the same insertion order, but allocates each distinct\n * container once (O(distinct path prefixes)) instead of re-copying the\n * whole branch for every path (O(paths x depth)).\n *\n * Use a fresh `owned` set per merge and thread the returned root (a copied\n * replacement when the seed root itself had to be copied) into the next\n * call. Borrowed containers are never mutated.\n */\nexport function setOwned(\n root: any,\n path: (string | number)[],\n value: any,\n owned: Set<object>\n): any {\n if (!path.length) return value;\n let container = root;\n let parent: any = null;\n let parentProp: string | number = '';\n for (let i = 0; i < path.length; i++) {\n const prop = path[i];\n if (!owned.has(container)) {\n let copy: any;\n if (\n typeof prop === 'number' ||\n (Array.isArray(container) && typeof prop === 'string' && isIndex(prop))\n ) {\n copy = Array.isArray(container) ? container.slice() : [];\n } else {\n copy = {...container};\n }\n owned.add(copy);\n if (i === 0) root = copy;\n else parent[parentProp] = copy;\n container = copy;\n }\n if (i === path.length - 1) {\n container[prop] = value;\n } else {\n parent = container;\n parentProp = prop;\n container = container[prop];\n }\n }\n return root;\n}\n\nexport function isEmpty(value: any): boolean {\n if (value == null) return true;\n if (typeof value !== 'object') return false;\n\n const values = Object.values(value);\n return values.length === 0 || values.every(isEmpty);\n}\n\nexport function isPromise(value: any): value is Promise<any> {\n return value && typeof value.then === 'function';\n}\n\n/** Structural equality for form default data (primitives, arrays, plain\n * objects, Dates). Class instances and other exotic objects compare as\n * unequal, which errs on the side of re-seeding when {@link\n * setInitialValues} uses it to tell a re-rendered inline literal from\n * genuinely changed content. */\nexport function isEqual(a: any, b: any): boolean {\n if (Object.is(a, b)) return true;\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false;\n const isArray = Array.isArray(a);\n if (isArray !== Array.isArray(b)) return false;\n if (isArray) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false;\n }\n return true;\n }\n const proto = Object.getPrototypeOf(a);\n if (proto !== Object.prototype && proto !== null) return false;\n if (Object.getPrototypeOf(b) !== proto) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!isEqual(a[key], b[key])) return false;\n }\n return true;\n}\n\nexport function waitUntil(\n emitter: EventEmitter<any>,\n event: string,\n isResolve: () => boolean,\n isReject: () => boolean\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (isReject()) return void reject();\n if (isResolve()) return void resolve();\n\n const off = on(emitter, event as any, () => {\n if (isReject()) {\n off();\n reject();\n return;\n }\n // Condition not reached yet — stay subscribed and keep waiting. (The\n // previous `if (isResolve()) return` was inverted: it hung forever\n // once the condition held and resolved prematurely while it didn't.)\n if (!isResolve()) return;\n off();\n resolve();\n });\n });\n}\n\n/**\n * DEV-only snapshot guard for {@link getValues}: deep-clones and freezes\n * plain objects and arrays so a consumer mutating the returned tree throws\n * immediately instead of silently corrupting the shared memoized result\n * (getValues hands the same cached reference to every reader between\n * writes). Non-plain values (Date, File, Blob, class instances, Map/Set)\n * pass through by reference, unfrozen — cloning would strip their\n * prototypes and freezing would break legitimate methods like\n * Date#setHours. Callers gate the call behind `__DEV__` so production\n * builds pay nothing.\n */\nexport function freezeValues(value: any): any {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return Object.freeze(value.map(freezeValues));\n }\n if (Object.getPrototypeOf(value) !== Object.prototype) return value;\n const clone: Record<string, any> = {};\n for (const key of Object.keys(value)) clone[key] = freezeValues(value[key]);\n return Object.freeze(clone);\n}\n","import {normalizePath} from './util';\n\nexport type PathSegments = (string | number)[];\nexport type Name = string | PathSegments;\nexport type Path = {value: PathSegments; key: string};\n\nexport default function create(name: Name): Path {\n const value = normalizePath(name);\n return {value, key: JSON.stringify(value)};\n}\n","import {emit} from '../emitter';\nimport {get} from '../util';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {FieldError, Form} from '../form';\n\n/** Per-form memoization of {@link getValues}, the same version-bump/read\n * pattern {@link dirtyFieldsCaches} gives {@link getDirtyFields}. */\ntype ValuesCache = {version: number; result: any};\n\nexport const valuesCaches = new WeakMap<Form, ValuesCache>();\n\n/**\n * Invalidate `form`'s cached {@link getValues} result. Called at every\n * point that can change values, parsedValues or initialValues\n * (setValueByPath, removeFieldByPath, setInitialValues, reset, resetField,\n * setParsedValues) so repeated reads hand back a stable reference until\n * the next write.\n */\nexport function bumpValuesVersion(form: Form): void {\n const cache = valuesCaches.get(form);\n if (cache) cache.version++;\n}\n\n/**\n * Get form values: the values Map layered over parsedValues (when a schema\n * validation produced them) layered over initialValues.\n *\n * Merged with copy-on-write ownership tracking ({@link setOwned}): every\n * distinct container on a written path is allocated once and shared by all\n * paths through it, instead of re-copying the whole branch for every key.\n * One owned set spans the whole merge, so containers borrowed from the\n * parsedValues tree are copied before mutation exactly like initialValues\n * ones. The result is a freshly merged tree per mutation, with untouched\n * branches sharing references with the baseline exactly like chained\n * `set` did.\n *\n * Memoized per form like {@link getDirtyFields}: every value write bumps a\n * `version` counter ({@link bumpValuesVersion}) while reads reset it, so\n * consecutive reads hand back the same reference (submit, changeValue and\n * form-level validate all read the whole tree, often several times per\n * interaction). Treat the result as read-only — the next read after a\n * write returns a fresh tree, but between writes the cached one is shared\n * with every other reader.\n *\n * parsedValues is the schema's complete output tree: once validation\n * succeeds it replaces the initialValues baseline (fields the schema\n * dropped disappear), while live edits in the values Map still win over\n * both. It never affects dirty state — {@link isDirty} and\n * {@link getDirtyFields} compare live edits against initialValues only,\n * because parsing is not a user edit.\n *\n * @param form\n */\n/** Per-path dirty-comparison baselines installed by writes with\n * `shouldDirty: false`: the written value becomes that field's baseline —\n * the write reads as a commit, not an edit. Module-private (like\n * {@link dirtyFieldsCaches}) so the Form shape is untouched for forms that\n * never opt in. */\nconst dirtyBaselines = new WeakMap<Form, Map<string, any>>();\n\n/** The value a field's dirtiness is measured against: its committed\n * baseline when one exists, initialValues at the path otherwise. */\nexport function getDirtyBaseline(\n form: Form,\n key: string,\n segments: PathSegments\n): any {\n const baselines = dirtyBaselines.get(form);\n if (baselines?.has(key)) return baselines.get(key);\n return get(form.initialValues, segments);\n}\n\n/** Install a committed baseline for a `shouldDirty: false` write: the\n * field reads clean until a later write diverges from the new baseline. */\nexport function setDirtyBaseline(form: Form, {key}: Path, value: any): void {\n let baselines = dirtyBaselines.get(form);\n if (!baselines) {\n baselines = new Map();\n dirtyBaselines.set(form, baselines);\n }\n baselines.set(key, value);\n}\n\n/** A wholesale write at a path replaces the subtree below it, so baselines\n * committed under the branch die with the data they were committed against\n * (array movers rewrite the parent path, re-aligning row indices). Called\n * from every write — a no-op unless the form ever opted in. */\nexport function pruneDirtyBaselines(form: Form, {key}: Path): void {\n const baselines = dirtyBaselines.get(form);\n if (!baselines?.size) return;\n const stem = `${key.slice(0, -1)},`;\n for (const baselineKey of baselines.keys()) {\n if (baselineKey.startsWith(stem)) baselines.delete(baselineKey);\n }\n}\n\n/** Drop committed baselines at one path ({@link removeFieldByPath} /\n * {@link resetField}) or all of them ({@link setInitialValues} /\n * {@link reset}) — the state they were measured against is gone. */\nexport function clearDirtyBaselines(form: Form, key?: string): void {\n const baselines = dirtyBaselines.get(form);\n if (!baselines) return;\n if (key === undefined) baselines.clear();\n else baselines.delete(key);\n}\n\n/** Per-form memoization of {@link getDirtyFields}. `version` counts value\n * mutations since the cached `result` was computed: bump points increment\n * it, reads reset it, so a non-zero version means the cache is stale. */\ntype DirtyFieldsCache = {version: number; result: Record<string, boolean>};\n\nexport const dirtyFieldsCaches = new WeakMap<Form, DirtyFieldsCache>();\n\n/**\n * Invalidate `form`'s cached {@link getDirtyFields} result. Called at every\n * point that can change values or initialValues (setValueByPath,\n * removeFieldByPath, setInitialValues, reset) so repeated reads hand out a\n * stable reference and useWatch's Object.is snapshot check can skip\n * re-renders.\n */\nexport function bumpDirtyVersion(form: Form): void {\n const cache = dirtyFieldsCaches.get(form);\n if (cache) cache.version++;\n}\n/** Numbers only occur inside a segments path (`['a', 0]`), never as\n * standalone names, so a top-level number marks `name` as one single path\n * rather than a list of names. */\nexport function isSegmentsPath(\n name: PathSegments | Name[]\n): name is PathSegments {\n return (name as (number | unknown)[]).some(part => typeof part === 'number');\n}\n\nexport function isFieldError(value: any): value is FieldError {\n return (\n !!value &&\n typeof value === 'object' &&\n typeof value.type === 'string' &&\n typeof value.message === 'string'\n );\n}\n\n/**\n * Flatten a form-level validate result and write each leaf error through\n * setError. Nested objects descend into deeper paths ({a: {b: 'msg'}} sets\n * the 'a.b' error), array values contribute every non-empty string they\n * hold as separate errors (zod flatten() formErrors style), and\n * FieldError-shaped objects are stored as-is. Falsy values are skipped.\n *\n * When `footprint` is passed (validateDeps forms only), every leaf this\n * round actually stored is recorded into it — the exact stored array —\n * so the next round can drop exactly what this one wrote.\n/** Store a schema validator's parsed output as the getValues baseline\n * layer above initialValues. Payload-less 'change' notifies value\n * watchers (useValue, useDirtyFields, ...); dirty state is untouched —\n * it only compares live edits against initialValues, and parsing is not\n * an edit. */\nexport function setParsedValues(form: Form, values: any): void {\n if (values === undefined || values === form.parsedValues) return;\n form.parsedValues = values;\n // parsedValues is a getValues layer above initialValues, so a new parse\n // invalidates the cached merge (dirty state is untouched — parsing is\n // not an edit, hence no bumpDirtyVersion here).\n bumpValuesVersion(form);\n emit(form.emitter, 'change');\n}\n\n/**\n * Land a form-level validate result. A plain record keeps the\n * long-standing behavior — flattened into field errors by\n * {@link setFormErrors}. A branded {@link ValidationOutcome} splits\n * instead: `errors` flattens exactly like a plain record, and `values`\n * (the schema's parsed output — coerced/transformed values included)\n * becomes the form's parsedValues baseline. Falsy results are skipped,\n * branded or not.\n *\n * Forms that opted into `validateDeps` additionally get round-scoped\n * error ownership: before the new result lands, the errors the previous\n * round wrote are dropped ({@link clearFormValidateErrors}), so a re-run\n * that passes makes the cross-field error disappear — and the new\n * round's own writes become the tracked footprint. Forms without the\n * option keep the historical write-only behavior untouched.\n */\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {FieldPath} from '../types';\nimport type {FieldError, FieldErrorEntry, Form} from '../form';\nimport {isFieldError, isSegmentsPath} from './internals';\n\n/** Reserved top-level path segment for form-level errors. The Standard\n * Schema form-level adapter lands path-less issues under this key; the\n * exported constant replaces the magic string, and readers consume it via\n * getError(form, FORM_ERROR) / getFieldErrors(form, FORM_ERROR). */\nexport const FORM_ERROR = '_form';\n\n/** When a field is validated:\n * - `'onSubmit'` (default): only on submit\n * - `'onBlur'`: when the field loses focus\n * - `'onChange'`: on every change\n * - `'onTouched'`: on first blur, then on every change\n * - `'all'`: on both change and blur\n */\n/** Brand marking a form-level validate result as a structured\n * {@link ValidationOutcome} (parsed values and/or errors) rather than a\n * plain nested error record. Symbols cannot collide with user error\n * records, so detection is an exact `VALIDATION_OUTCOME in result`. */\nexport const VALIDATION_OUTCOME: unique symbol = Symbol('validation-outcome');\n\n/** Structured form-level validate result: `errors` uses the same nested\n * shape a plain error record uses, `values` is the schema's parsed output\n * (coerce/transform results included). Either side may be omitted. */\n/**\n * Get field error\n * @param form\n * @param name\n * @return FieldError object or undefined\n */\nexport function getError<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): FieldError | undefined {\n return getErrorByPath(form, createPath(name));\n}\n\n/**\n * Get field error by path\n * @param form\n * @param path\n * @return first FieldError of the field, or undefined\n */\nexport function getErrorByPath(\n {errors}: Form,\n path: Path\n): FieldError | undefined {\n return errors.get(path.key)?.[0];\n}\n\n/** Shared empty result for {@link getFieldErrorsByPath}: a fresh `[]` per\n * call would allocate on the hot no-error path, and the stored arrays are\n * handed out by reference too, so callers must treat results as read-only. */\nconst NO_ERRORS: FieldError[] = [];\n\n/**\n * Get all errors of a field\n * @param form\n * @param name\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function getFieldErrors<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): FieldError[] {\n return getFieldErrorsByPath(form, createPath(name));\n}\n\n/**\n * Get all errors of a field by path\n * @param form\n * @param path\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function getFieldErrorsByPath({errors}: Form, path: Path): FieldError[] {\n return errors.get(path.key) ?? NO_ERRORS;\n}\n\n/**\n * Get all errors\n * @param form\n * @return array of {path, type, message} entries, in insertion order; path\n * is the user-facing dotted field path ('a.b', 'list.0'), and a\n * field holding several errors contributes one entry per error\n */\nexport function getErrors({errors}: Form): FieldErrorEntry[] {\n const entries: FieldErrorEntry[] = [];\n for (const [key, list] of errors) {\n const path = (JSON.parse(key) as PathSegments).join('.');\n for (const {type, message} of list) entries.push({path, type, message});\n }\n return entries;\n}\n\n/**\n * Get first error message\n * @param form\n * @return first error's message string, or undefined when there are no errors\n */\nexport function getFirstError({errors}: Form): string | undefined {\n return errors.values().next().value?.[0]?.message;\n}\n\n/** Snapshot of one field's aggregated state, as {@link getFieldState}\n * returns it. `errors` is the stored array shared with the form — treat it\n * as read-only, like every {@link getFieldErrors} result. */\n/** Options accepted by {@link setError}. */\nexport type SetErrorOptions = {\n /**\n * Focus the named field's element after the error lands (react-hook-form's\n * `setError` `shouldFocus`). Rides the same 'focusError' channel\n * `setFocus` and a failed submit's auto-focus use: only mounted bound\n * fields react, unmounted ones are silent no-ops.\n */\n shouldFocus?: boolean;\n};\n\n/**\n * Set field error\n * @param form\n * @param name\n * @param error string is normalized to {type: 'custom', message}; a\n * FieldError object is stored as-is; an array holds several errors\n * (falsy items dropped, strings normalized); undefined clears\n * @param options {@link SetErrorOptions} — `shouldFocus` focuses the field\n * after the error lands\n */\nexport function setError<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(\n form: Form<T>,\n name: P,\n error: string | FieldError | (string | FieldError)[] | undefined,\n options?: SetErrorOptions\n): void {\n setErrorByPath(form, createPath(name), error, options);\n}\n\n/**\n * Set field error\n * @param form\n * @param path\n * @param error string is normalized to {type: 'custom', message}; a\n * FieldError object is stored as-is; an array holds several errors\n * (falsy items dropped, strings normalized); undefined clears\n * @param options {@link SetErrorOptions} — `shouldFocus` focuses the field\n * after the error lands\n */\nexport function setErrorByPath(\n form: Form,\n path: Path,\n error: string | FieldError | (string | FieldError)[] | undefined,\n options?: SetErrorOptions\n): void {\n const {emitter, errors} = form;\n const list = normalizeErrors(error);\n // An empty result (undefined, '', or an array of only falsy items) clears\n // the key: the errors Map never stores an empty list, so hasErrors stays\n // a plain size check and readers can index [0] unguarded.\n if (list) errors.set(path.key, list);\n else errors.delete(path.key);\n // Path payload lets key-scoped subscribers (onKeyEvent) skip unrelated\n // fields; payload-less listeners ignore it.\n emit(emitter, 'errors', path);\n if (options?.shouldFocus) emit(emitter, 'focusError', path.key);\n}\n\n/** Normalize any {@link setErrorByPath} input into the stored non-empty\n * FieldError[] shape, or undefined when there is nothing to store. */\nfunction normalizeErrors(\n error: string | FieldError | (string | FieldError)[] | undefined\n): FieldError[] | undefined {\n if (typeof error === 'string') {\n return error ? [{type: 'custom', message: error}] : undefined;\n }\n if (isFieldError(error)) return [error];\n if (!error) return undefined;\n // Falsy items drop out before normalization, so '' never becomes a\n // stored {type: 'custom', message: ''} placeholder.\n const list: FieldError[] = [];\n error.forEach(item => {\n if (typeof item === 'string' && item) {\n list.push({type: 'custom', message: item});\n } else if (isFieldError(item)) {\n list.push(item);\n }\n });\n return list.length ? list : undefined;\n}\n\n/**\n * Clear errors\n * @param form\n * @param name a single path or a list of paths; omit to clear every error\n */\nexport function clearErrors(form: Form, name?: Name | Name[]): void {\n const {emitter, errors} = form;\n if (name === undefined) {\n errors.clear();\n // Payload-less broadcast: every error subscriber re-syncs.\n emit(emitter, 'errors');\n return;\n }\n // Same single-path vs list discrimination as trigger: a segment array\n // holding a number is one path ('a.0' shape), not a list of names.\n const paths =\n typeof name === 'string' || isSegmentsPath(name)\n ? [createPath(name)]\n : name.map(one => createPath(one));\n for (const {key} of paths) errors.delete(key);\n // Path-payload emits — the setErrorByPath scoping — wake exactly the\n // affected fields' subscribers.\n for (const path of paths) emit(emitter, 'errors', path);\n}\n\n/** Options accepted by {@link setServerErrors}. */\nexport type SetServerErrorsOptions = {\n /** Keep existing field errors instead of clearing them first. Defaults\n * to `false`: a fresh server response replaces the prior error state. */\n keepExisting?: boolean;\n};\n\n/**\n * Land a server-side error response on the form: each entry becomes the\n * named field's error(s) with `type: 'server'`, ready for the same\n * renderError/`useError` channel client-side validation uses. Takes the\n * flat `Record<string, string | string[]>` shape REST APIs commonly\n * return (RealWorld: `422 {errors: {email: ['has already been taken']}}`)\n * without a hand-rolled `Object.entries` + `setError` loop.\n *\n * A string value lands as one error, a string array as several (first one\n * is what `getError`/`error` expose); an empty array clears that field's\n * errors. By default every existing error is cleared first — a fresh\n * response describes the current state, not a patch onto stale client\n * errors; pass `keepExisting: true` to layer instead.\n * @param form\n * @param errors field errors keyed by name\n * @param options\n */\nexport function setServerErrors(\n form: Form,\n errors: Record<string, string | string[]>,\n options?: SetServerErrorsOptions\n): void {\n if (!options?.keepExisting) clearErrors(form);\n for (const [name, error] of Object.entries(errors)) {\n setError(\n form,\n name,\n (Array.isArray(error) ? error : [error]).map(message => ({\n type: 'server',\n message\n }))\n );\n }\n}\n\n/**\n * Set field touched state\n * @param form\n * @param name\n */\n/**\n * @param form\n */\nexport function hasErrors({errors}: Form): boolean {\n return errors.size > 0;\n}\n\n/** Options accepted by {@link trigger}. `shouldTouch` defaults to `false`;\n * omitting the options object entirely keeps the plain validate-only\n * behavior, so the historical two-argument calls are untouched. */\n","import type {Path, PathSegments} from '../path';\nimport type {Form} from '../form';\nimport {dirtyFieldsCaches, getDirtyBaseline} from './internals';\n\n/**\n * Is one field dirty — the per-field rule behind `getFieldState`'s\n * `isDirty` and {@link useIsFieldDirty}: a live value exists at the path\n * and differs from the field's effective baseline (committed\n * `shouldDirty: false` baselines included). A leaf under a wholesale\n * ancestor write reports clean — dirtiness belongs to the branch that\n * actually diverged, the same attribution {@link getDirtyFields} applies.\n */\nexport function isFieldDirtyByPath(form: Form, path: Path): boolean {\n const live = form.values.get(path.key);\n return (\n form.values.has(path.key) &&\n getDirtyBaseline(form, path.key, path.value) !== live\n );\n}\n\n/**\n * Is dirty -- any value differs from initialValues\n * @param form\n */\nexport function isDirty(form: Form): boolean {\n let dirty = false;\n forEachDirtyField(form, () => {\n dirty = true;\n });\n return dirty;\n}\n\nfunction forEachDirtyField(form: Form, fn: (dottedKey: string) => void): void {\n for (const [key, value] of form.values) {\n const path = JSON.parse(key) as PathSegments;\n if (getDirtyBaseline(form, key, path) !== value) fn(path.join('.'));\n }\n}\n\n/** Per-path dirty-comparison baselines installed by writes with\n * `shouldDirty: false`: the written value becomes that field's baseline —\n * the write reads as a commit, not an edit. Module-private (like\n * {@link dirtyFieldsCaches}) so the Form shape is untouched for forms that\n * never opt in. */\n\nfunction computeDirtyFields(form: Form): Record<string, boolean> {\n const dirtyFields: Record<string, boolean> = {};\n forEachDirtyField(form, key => {\n dirtyFields[key] = true;\n });\n return dirtyFields;\n}\n\n/** Dirty entries only ever map to `true`, so equal key sets mean shallow\n * equal results. */\nfunction sameDirtyKeys(\n a: Record<string, boolean>,\n b: Record<string, boolean>\n): boolean {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) return false;\n return aKeys.every(key => b[key] === true);\n}\n\n/**\n * Get dirty fields -- fields whose current value differs from initialValues.\n * Keys are user-facing dotted paths ('a.b', 'a.0.c'), unlike the JSON array\n * keys stored in the values Map.\n * @param form\n * @return object mapping each dirty field's dotted path to true; the same\n * reference is returned until the dirty set actually changes\n */\nexport function getDirtyFields(form: Form): Record<string, boolean> {\n let cache = dirtyFieldsCaches.get(form);\n if (!cache) {\n cache = {version: 0, result: computeDirtyFields(form)};\n dirtyFieldsCaches.set(form, cache);\n } else if (cache.version > 0) {\n const result = computeDirtyFields(form);\n // Keep the old reference when the dirty set is unchanged (values always\n // map to true) so subscribers see identity-stable snapshots.\n if (!sameDirtyKeys(cache.result, result)) cache.result = result;\n cache.version = 0;\n }\n return cache.result;\n}\n\n/**\n * Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'), unlike\n * the JSON array keys stored in the touched Set.\n * @param form\n * @return array of touched fields' dotted paths\n */\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {FieldPath} from '../types';\nimport type {Form} from '../form';\n\n/**\n * Set field touched state\n * @param form\n * @param name\n */\nexport function setTouched(form: Form, name: Name): void {\n setTouchedByPath(form, createPath(name));\n}\n\n/**\n * Set field touched state\n * @param form\n * @param path\n */\nexport function setTouchedByPath({emitter, touched}: Form, path: Path): void {\n if (touched.has(path.key)) return;\n touched.add(path.key);\n // Path payload lets key-scoped subscribers (onKeyEvent) skip unrelated\n // fields; payload-less listeners ignore it.\n emit(emitter, 'touched', path);\n}\n\n/**\n * Check if field has been touched\n * @param form\n * @param name\n */\nexport function hasTouched<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): boolean {\n return hasTouchedByPath(form, createPath(name));\n}\n\n/**\n * Check if field has been touched\n * @param form\n * @param path\n */\nexport function hasTouchedByPath({touched}: Form, path: Path): boolean {\n return touched.has(path.key);\n}\n\n/**\n * Is dirty -- any value differs from initialValues\n * @param form\n */\n/**\n * Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'), unlike\n * the JSON array keys stored in the touched Set.\n * @param form\n * @return array of touched fields' dotted paths\n */\nexport function getTouchedFields({touched}: Form): string[] {\n return Array.from(touched, key =>\n (JSON.parse(key) as PathSegments).join('.')\n );\n}\n\n/**\n * Is touched -- any field has been touched\n * @param form\n */\nexport function isTouched({touched}: Form): boolean {\n return touched.size > 0;\n}\n\n/**\n * Remove a field: by default its live value drops out of reads and\n * `getValues()` (the path is tombstoned, so it never falls back to\n * initialValues), its dirty baseline, touched flag and errors are cleared.\n * The keep-flags preserve slices of that state instead.\n *\n * @param form\n * @param name\n */\n/**\n * Options accepted by {@link removeField}. All flags default to `false` —\n * the historical remove semantics (value dropped, path tombstoned, dirty\n * baseline/touched/errors cleared). Names mirror react-hook-form's\n * `unregister` options to ease migration; RHF's `shouldValidate` and\n * `keepDefaultValue` have no counterparts (removal never validates, and\n * the tombstone is exactly the \"do not revive from initialValues\" choice).\n */\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {FieldPath, PathValueOf} from '../types';\nimport {freezeValues, get, isEqual, setOwned, unset} from '../util';\nimport type {FieldError, Form} from '../form';\nimport {clearErrors, getErrorByPath, getFieldErrorsByPath} from './errors';\nimport {isFieldDirtyByPath} from './dirty';\nimport {setTouchedByPath} from './touched';\nimport {\n bumpDirtyVersion,\n bumpValuesVersion,\n clearDirtyBaselines,\n getDirtyBaseline,\n pruneDirtyBaselines,\n setDirtyBaseline,\n valuesCaches\n} from './internals';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/**\n * Get form values: the values Map layered over parsedValues (when a schema\n * validation produced them) layered over initialValues.\n *\n * Merged with copy-on-write ownership tracking ({@link setOwned}): every\n * distinct container on a written path is allocated once and shared by all\n * paths through it, instead of re-copying the whole branch for every key.\n * One owned set spans the whole merge, so containers borrowed from the\n * parsedValues tree are copied before mutation exactly like initialValues\n * ones. The result is a freshly merged tree per mutation, with untouched\n * branches sharing references with the baseline exactly like chained\n * `set` did.\n *\n * Memoized per form like {@link getDirtyFields}: every value write bumps a\n * `version` counter ({@link bumpValuesVersion}) while reads reset it, so\n * consecutive reads hand back the same reference (submit, changeValue and\n * form-level validate all read the whole tree, often several times per\n * interaction). Treat the result as read-only — the next read after a\n * write returns a fresh tree, but between writes the cached one is shared\n * with every other reader.\n *\n * parsedValues is the schema's complete output tree: once validation\n * succeeds it replaces the initialValues baseline (fields the schema\n * dropped disappear), while live edits in the values Map still win over\n * both. It never affects dirty state — {@link isDirty} and\n * {@link getDirtyFields} compare live edits against initialValues only,\n * because parsing is not a user edit.\n *\n * @param form\n */\nexport function getValues<T extends Record<string, any> = any>(\n form: Form<T>\n): T {\n let cache = valuesCaches.get(form);\n if (!cache) {\n cache = {version: 0, result: computeValues(form)};\n valuesCaches.set(form, cache);\n } else if (cache.version > 0) {\n cache.result = computeValues(form);\n cache.version = 0;\n }\n return cache.result as T;\n}\n\nfunction computeValues(form: Form): any {\n const {initialValues, parsedValues, values, deleted} = form;\n const owned = new Set<object>();\n let merged = parsedValues ?? initialValues;\n for (const [key, value] of values) {\n merged = setOwned(merged, JSON.parse(key), value, owned);\n }\n // Unregistered fields leave a tombstone in `deleted`; remove those paths\n // from the merged result so they don't fall back to initialValues. unset\n // is immutable (set() shares untouched branches with initialValues, so a\n // mutating delete would corrupt them) and deletes the key outright rather\n // than writing undefined, which would leave `a: undefined` entries behind\n // in anything that spreads getValues().\n for (const key of deleted) {\n merged = unset(merged, JSON.parse(key));\n }\n // DEV-only: hand back a frozen snapshot (a clone — freezing the merged\n // tree in place would also freeze the initialValues/parsedValues\n // containers it borrows from). Consumer mutations then throw at the\n // offending site instead of silently corrupting the shared cache.\n return __DEV__ ? freezeValues(merged) : merged;\n}\n\n/**\n * Get field value\n * @param form\n * @param name\n */\nexport function getValue<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): PathValueOf<T, P> {\n return getValueByPath(form, createPath(name));\n}\n\n/**\n * Get field value by path\n * @param form\n * @param path\n */\nexport function getValueByPath(\n {initialValues, parsedValues, values, deleted}: Form,\n path: Path\n): any {\n const {key, value: segments} = path;\n if (values.has(key)) return values.get(key);\n // Unregistered path: the tombstone blocks the initialValues fallback.\n if (deleted.has(key)) return undefined;\n // A live ancestor key is a whole-branch write (setValue at a parent\n // path, every useFieldArray operation): it replaces the subtree below\n // it, the same way getValues' merge layers it over the baseline, so\n // reads under it resolve from that stored value instead of falling\n // back to the pre-edit initialValues snapshot. Nearest ancestor first:\n // a finer write is layered over a coarser one (setValueByPath drops the\n // superseded descendant keys), so the closest live ancestor is the\n // newest generation. Paths the ancestor's value does not carry read\n // undefined — the baseline must not fill holes inside a replaced\n // branch.\n for (let i = segments.length - 1; i > 0; i--) {\n const ancestorKey = JSON.stringify(segments.slice(0, i));\n if (values.has(ancestorKey)) {\n return get(values.get(ancestorKey), segments.slice(i));\n }\n }\n // Same layering as getValues: parsed values (when present) are the\n // baseline above initialValues.\n return get(parsedValues ?? initialValues, segments);\n}\n\n/** Options accepted by {@link setValue} / {@link setValueByPath} / {@link\n * changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`\n * default to `false`; omitting the options object entirely keeps the plain\n * set-value behavior (no validation, no touched marking, dirty stays\n * derived). */\nexport type SetFieldOptions = {\n /** Run the field's registered validator (if any) after the value lands,\n * same as triggering that single field. Defaults to `false`. */\n shouldValidate?: boolean;\n /** Mark the field as touched. Defaults to `false`. */\n shouldTouch?: boolean;\n /** Land the value as a commit instead of an edit: the value becomes the\n * field's dirty-comparison baseline, so `getDirtyFields`/`isDirty`/\n * `getFieldState().isDirty` read the field as clean, and a later write\n * dirties it only by differing from the new baseline. `true` (or\n * omitting the flag) keeps the default derived behavior — dirty while\n * the live value differs from initialValues. */\n shouldDirty?: boolean;\n};\n\n/**\n * Set field value. The value may also be an updater function receiving\n * the field's current value and returning the next one (TanStack Form's\n * `setFieldValue` contract) — handy for increments and array transforms:\n * `setValue(form, 'count', c => c + 1)`. The tradeoff: a function can\n * never itself be stored as a field value through this function.\n * @param form\n * @param name\n * @param value\n * @param options\n */\nexport function setValue<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(\n form: Form<T>,\n name: P,\n value: PathValueOf<T, P> | ((prev: PathValueOf<T, P>) => PathValueOf<T, P>),\n options?: SetFieldOptions\n): void {\n setValueByPath(form, createPath(name), value, options);\n}\n\n/**\n * Set field value. The value may also be an updater function receiving\n * the field's current value and returning the next one (TanStack Form's\n * `setFieldValue` contract) — note that a function can therefore never\n * itself be stored as a field value through this function.\n * @param form\n * @param path\n * @param value\n * @param options\n */\nexport function setValueByPath(\n form: Form,\n path: Path,\n value: any | ((prev: any) => any),\n options?: SetFieldOptions\n): void {\n const {emitter, values, deleted} = form;\n const next =\n typeof value === 'function' ? value(getValueByPath(form, path)) : value;\n values.set(path.key, next);\n // The write replaces the whole subtree below it, so descendant keys in\n // the values Map belong to an older generation of that subtree: without\n // this prune they would shadow the new value on exact-key reads and\n // double-apply over it in getValues' insertion-ordered merge (a stale\n // `a.b` would survive a fresh `a` write, or corrupt an array branch\n // into an object when applied later).\n pruneDescendantKeys(values, path);\n reviveBranch(deleted, path);\n // Baselines under the replaced subtree die with it — before the emit, so\n // subscribers reading dirty state inside the emission never see a stale\n // commit suppressing the write they are being told about.\n pruneDirtyBaselines(form, path);\n if (options?.shouldDirty === false) setDirtyBaseline(form, path, next);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n if (options?.shouldTouch) setTouchedByPath(form, path);\n if (options?.shouldValidate) form.validators.get(path.key)?.();\n emit(emitter, 'change', path);\n}\n\n/**\n * The write of {@link setValueByPath} minus the `'change'` emit: the\n * render-time {@link useField} `initialValue` seed. The field's first\n * paint (SSR included — effects never run on the server) must already\n * carry the value, so the write happens during render where emitting is\n * illegal; the seeding field announces it from its post-commit effect\n * through {@link emitChangeByPath} instead.\n *\n * Everything else matches a plain write: descendant keys of the seeded\n * path are pruned, the branch's tombstones and committed baselines are\n * revived/dropped, and both memo caches are invalidated. Like the effect\n * seed it replaces, the caller guards it to paths with no value yet.\n */\nexport function seedValueByPath(form: Form, path: Path, value: any): void {\n const {values, deleted} = form;\n values.set(path.key, value);\n pruneDescendantKeys(values, path);\n reviveBranch(deleted, path);\n pruneDirtyBaselines(form, path);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n}\n\n/** Announce a {@link seedValueByPath} that happened during render: the\n * payload-carrying `'change'` emit {@link setValueByPath} would have\n * fired, split out so it can run post-commit where emitting is safe.\n * Subscribers that rendered after the seed re-read an unchanged snapshot\n * and bail; subscribers from earlier commits resync. */\nexport function emitChangeByPath({emitter}: Form, path: Path): void {\n emit(emitter, 'change', path);\n}\n\n/** Per-form registry of mounted fields' validation-mode overrides: path\n * key -> the field's `mode` option (undefined = follow {@link Form.mode})\n * plus an owner token so competing mounts at one path clean up safely.\n * Presence of an entry is the \"a field is mounted at this path\" signal\n * that routes {@link changeValueByPath} into the gated user-change\n * pipeline ({@link userChangeByPath}). Held in a WeakMap so the Form\n * shape carries only plain state fields. */\n/** Snapshot of one field's aggregated state, as {@link getFieldState}\n * returns it. `errors` is the stored array shared with the form — treat it\n * as read-only, like every {@link getFieldErrors} result. */\nexport type FieldState<T = any> = {\n value: T;\n error: FieldError | undefined;\n errors: FieldError[];\n isDirty: boolean;\n isTouched: boolean;\n isValidating: boolean;\n};\n\n/**\n * Get one field's aggregated state: the layered value ({@link getValue}),\n * the first error ({@link getError}) and every error ({@link\n * getFieldErrors}), dirtiness, the touched flag, and whether a validator\n * is in flight. `isDirty` applies the same per-field rule as {@link\n * getDirtyFields}: a live value exists and differs from initialValues at\n * that path (parsedValues never counts — parsing is not an edit).\n *\n * @param form\n * @param name\n */\nexport function getFieldState<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): FieldState<PathValueOf<T, P>> {\n const path = createPath(name);\n const {touched, validating} = form;\n return {\n value: getValueByPath(form, path),\n error: getErrorByPath(form, path),\n errors: getFieldErrorsByPath(form, path),\n // The shared per-field rule (committed baselines included): the field\n // is dirty while its live value differs from its effective baseline.\n isDirty: isFieldDirtyByPath(form, path),\n isTouched: touched.has(path.key),\n isValidating: validating.has(path.key)\n };\n}\n\n/**\n * Remove a field: by default its live value drops out of reads and\n * `getValues()` (the path is tombstoned, so it never falls back to\n * initialValues), its dirty baseline, touched flag and errors are cleared.\n * The keep-flags preserve slices of that state instead.\n *\n * @param form\n * @param name\n */\n/**\n * Options accepted by {@link removeField}. All flags default to `false` —\n * the historical remove semantics (value dropped, path tombstoned, dirty\n * baseline/touched/errors cleared). Names mirror react-hook-form's\n * `unregister` options to ease migration; RHF's `shouldValidate` and\n * `keepDefaultValue` have no counterparts (removal never validates, and\n * the tombstone is exactly the \"do not revive from initialValues\" choice).\n */\nexport type RemoveFieldOptions = {\n /** Keep the field's live value and dirty baseline instead of\n * tombstoning: reads and `getValues()` keep returning the value, submit\n * includes it, and dirtiness against initialValues is preserved. */\n keepValue?: boolean;\n /** Keep the field's dirty baseline. Implies `keepValue` — a removed\n * value has nothing to be dirty about. */\n keepDirty?: boolean;\n /** Keep the field's touched flag instead of clearing it. */\n keepTouched?: boolean;\n /** Keep the field's errors instead of clearing them. */\n keepError?: boolean;\n};\n\nexport function removeField(\n form: Form,\n name: Name,\n options?: RemoveFieldOptions\n): void {\n removeFieldByPath(form, createPath(name), options);\n}\n\n/**\n * Remove field\n * @param form\n * @param path\n * @param options keep-flags to preserve slices of state through the removal\n */\nexport function removeFieldByPath(\n form: Form,\n path: Path,\n options?: RemoveFieldOptions\n): void {\n const {key, value: segments} = path;\n const {emitter, values, touched, errors, validating, deleted} = form;\n if (!options?.keepValue && !options?.keepDirty) {\n values.delete(key);\n // The field is gone; a remount starts fresh rather than inheriting a\n // baseline committed by the previous incarnation.\n clearDirtyBaselines(form, key);\n // Tombstone the unregistered path so later reads do not fall back to\n // initialValues and \"revive\" the field's old initial value. A tombstone\n // never shadows live values: skip it when the branch is already covered\n // by a live ancestor key (e.g. a FieldArray rewrite stored the whole\n // array at the parent path) or a still-mounted descendant key.\n if (!hasLiveBranch(values, segments)) deleted.add(key);\n }\n if (!options?.keepTouched) touched.delete(key);\n if (!options?.keepError) errors.delete(key);\n validating.delete(key);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n // Path-payload emits, scoped exactly like the writes above: every\n // mutation is bounded to this path's key (exact deletes in the four\n // stores, an exact-key tombstone), so the same matching the write sites\n // use decides who re-syncs. Leaf watchers on the path and BELOW it wake\n // (their reads fall back through the removed key), branch watchers on\n // ancestors wake (their subtree lost a leaf — the wizard/tab unmount\n // case), and global listeners (`on`, useWatch aggregates like\n // useDirtyFields/getValues readers) wake regardless — an emit with a\n // payload still reaches every plain listener. Sibling fields stay\n // asleep: unmounting one tab's fields no longer re-renders every other\n // field's subscriber.\n emit(emitter, 'change', path);\n emit(emitter, 'touched', path);\n emit(emitter, 'errors', path);\n emit(emitter, 'validating', path);\n}\n\n/**\n * Does a live value cover the branch at `segments` -- either at an ancestor\n * key or below it at a descendant key?\n */\nfunction hasLiveBranch(\n values: Map<string, any>,\n segments: PathSegments\n): boolean {\n for (let i = 1; i < segments.length; i++) {\n if (values.has(JSON.stringify(segments.slice(0, i)))) return true;\n }\n const stem = `${JSON.stringify(segments).slice(0, -1)},`;\n for (const key of values.keys()) {\n if (key.startsWith(stem)) return true;\n }\n return false;\n}\n\n/**\n * Writing a value replaces the subtree below the written path, so drop the\n * values Map keys under it: they were set against an older generation of\n * that subtree and would otherwise shadow the fresh value (exact-key reads\n * in {@link getValueByPath}) or re-apply over it (getValues' merge).\n * Deleting while iterating `keys()` is safe for a Map.\n */\nfunction pruneDescendantKeys(values: Map<string, any>, {key}: Path): void {\n if (!values.size) return;\n const stem = `${key.slice(0, -1)},`;\n for (const k of values.keys()) {\n if (k.startsWith(stem)) values.delete(k);\n }\n}\n\n/**\n * Writing a value revives its whole branch: drop any removal tombstone for\n * the path itself, its ancestors, or its descendants (a remounted field\n * overwrites its own tombstone; rewriting a parent array supersedes the\n * tombstones of shifted child paths).\n */\nfunction reviveBranch(deleted: Set<string>, {key}: Path): void {\n if (!deleted.size) return;\n for (const tombstone of deleted) {\n if (\n tombstone === key ||\n tombstone.startsWith(`${key.slice(0, -1)},`) ||\n key.startsWith(`${tombstone.slice(0, -1)},`)\n ) {\n deleted.delete(tombstone);\n }\n }\n}\n\n/**\n * Set form initialValues\n *\n * Content-based early return: a new reference with equal content (the\n * re-rendered inline literal) is a no-op, so committed edits survive, while\n * genuinely changed content swaps the baseline and re-seeds — live values\n * and tombstones are cleared, touched flags and errors survive.\n * @param form\n * @param initialValues\n */\nexport function setInitialValues(form: Form, initialValues: any): void {\n if (\n form.initialValues === initialValues ||\n isEqual(form.initialValues, initialValues)\n ) {\n return;\n }\n form.initialValues = initialValues;\n // A new baseline invalidates the previous schema parse.\n form.parsedValues = undefined;\n form.values.clear();\n form.deleted.clear();\n // ...and every baseline committed against the old one.\n clearDirtyBaselines(form);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n emit(form.emitter, 'change');\n}\n\n/** Options accepted by {@link reset}. Every flag defaults to `false` —\n * omitting the object (or any flag) keeps the plain full-reset behavior.\n * Names mirror react-hook-form's reset options to ease migration. */\nexport type ResetOptions = {\n /** Keep the current values of fields that are dirty — differ from the\n * pre-reset initialValues (the same rule {@link getDirtyFields} applies).\n * Clean fields fall back to the new initialValues as usual. */\n keepDirtyValues?: boolean;\n /** Keep every field's current live value instead of returning to the\n * baseline (react-hook-form's `keepValues` — a strict superset of\n * `keepDirtyValues`, which only preserves dirty fields' values).\n * Dirtiness is recomputed against the post-reset baseline, so kept\n * values that differ from a newly provided baseline count as dirty. */\n keepValues?: boolean;\n /** Ignore a newly provided `initialValues` argument and keep the current\n * baseline — fields still return to it (react-hook-form's\n * `keepDefaultValues`). */\n keepDefaultValues?: boolean;\n /** Keep the touched set instead of clearing it. */\n keepTouched?: boolean;\n /** Keep field errors instead of clearing them. */\n keepErrors?: boolean;\n /** Keep the submitted flag (`isSubmitted`) instead of clearing it —\n * react-hook-form's `keepIsSubmitted`. */\n keepIsSubmitted?: boolean;\n /** Keep the last submit's success flag (`isSubmitSuccessful`) instead of\n * clearing it. */\n keepIsSubmitSuccessful?: boolean;\n /** Keep `submitCount` instead of resetting it to 0. */\n keepSubmitCount?: boolean;\n /** Keep `isSubmitting` instead of resetting it to false. */\n keepIsSubmitting?: boolean;\n};\n\n/** Collect every leaf path of the merged values tree into `out` —\n * structured segments (numeric for array indexes) so each leaf can be\n * written back with setValueByPath. Objects with no enumerable keys\n * (Date, File, plain empty objects) are leaves themselves. */\nfunction collectValueLeaves(\n node: any,\n segments: PathSegments,\n out: {segments: PathSegments; value: any}[]\n): void {\n if (node !== null && typeof node === 'object') {\n if (Array.isArray(node)) {\n for (let i = 0; i < node.length; i++) {\n collectValueLeaves(node[i], [...segments, i], out);\n }\n return;\n }\n const keys = Object.keys(node);\n if (keys.length > 0) {\n for (const k of keys) {\n collectValueLeaves(node[k], [...segments, k], out);\n }\n return;\n }\n }\n out.push({segments, value: node});\n}\n\n/**\n * Reset form\n * @param form\n * @param initialValues new baseline — omitted (or undefined), the form\n * keeps its current initialValues and fields simply return to them\n * (react-hook-form's reset-without-values semantics)\n * @param options keep-flags to preserve slices of state through the reset\n */\nexport function reset(\n form: Form,\n initialValues?: any,\n options?: ResetOptions\n): void {\n // Snapshot the live values being preserved before the wipe: dirtiness\n // is measured against the pre-reset initialValues, so capture must\n // happen before form.values and form.initialValues are touched. The\n // snapshot carries structured segments, not dotted strings — a name\n // segment may itself contain '.' or quotes, and the dotted spelling does\n // not round-trip through the parser (dotted keys stay display-only, like\n // getDirtyFields' output). keepValues keeps every live value; the older\n // keepDirtyValues narrows the same snapshot to fields whose value\n // differs from their effective baseline.\n const keptValues: {segments: PathSegments; value: any}[] = [];\n if (options?.keepValues) {\n // Every leaf of the CURRENT merged tree — live edits and clean\n // baseline fields alike — is written back after the wipe, so a field\n // that never had a live edit keeps its pre-reset value instead of\n // adopting the new baseline's.\n collectValueLeaves(getValues(form), [], keptValues);\n } else if (options?.keepDirtyValues) {\n for (const [key, value] of form.values) {\n const segments = JSON.parse(key) as PathSegments;\n // Same predicate as getDirtyFields/forEachDirtyField: a live value\n // differing from its effective baseline (committed baselines read\n // clean and are not kept).\n if (getDirtyBaseline(form, key, segments) !== value) {\n keptValues.push({segments, value});\n }\n }\n }\n // Omitting values is a return-to-initialValues reset, not a wipe: an\n // undefined baseline would make getValues() return undefined (and every\n // consumer of it crash), so the current baseline survives when no new\n // one is provided.\n form.initialValues = options?.keepDefaultValues\n ? form.initialValues\n : (initialValues ?? form.initialValues);\n // The fresh baseline drops any schema parse from the previous cycle.\n form.parsedValues = undefined;\n if (!options?.keepErrors) clearErrors(form);\n const {emitter, touched, values, deleted, validating} = form;\n values.clear();\n deleted.clear();\n clearDirtyBaselines(form);\n if (!options?.keepTouched) touched.clear();\n validating.clear();\n if (!options?.keepIsSubmitting) form.isSubmitting = false;\n if (!options?.keepSubmitCount) form.submitCount = 0;\n if (!options?.keepIsSubmitted) form.isSubmitted = false;\n if (!options?.keepIsSubmitSuccessful) form.isSubmitSuccessful = undefined;\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n // Write the kept values back over the fresh baseline: plain\n // setValueByPath, so no validation fires and nothing is marked touched.\n for (const {segments, value} of keptValues) {\n setValueByPath(form, createPath(segments), value);\n }\n emit(emitter, 'change');\n emit(emitter, 'touched');\n emit(emitter, 'validating');\n emit(emitter, 'submitting');\n emit(emitter, 'submitCount');\n emit(emitter, 'submitSuccessful');\n emit(emitter, 'reset');\n}\n\n/** Options accepted by {@link resetField}. The flags default to `false`;\n * `value` has no default — omitted, the field falls back to initialValues;\n * provided, the explicit value becomes the live value with no fallback at\n * all. Mirrors react-hook-form's resetField options (`value` plays their\n * `defaultValue`'s role) to ease migration. */\nexport type ResetFieldOptions = {\n /** Keep the field's touched flag instead of clearing it. */\n keepTouched?: boolean;\n /** Keep the field's errors instead of clearing them. */\n keepErrors?: boolean;\n /** Explicit post-reset value for the field — never falls back to\n * initialValues. */\n value?: any;\n};\n\n/**\n * Reset a single field: drop its live value (reads fall back to the\n * baseline — initialValues, or the schema's parsed output when one\n * exists, in which case the path is removed from parsedValues and the\n * initial value pinned back so the field reads initialValues again),\n * clear its touched flag and errors, and revive the path's removal\n * tombstones — the inverse of {@link removeFieldByPath}. Other fields\n * and the submission flags are untouched; see {@link reset} for the\n * form-wide counterpart.\n *\n * @param form\n * @param name\n * @param options\n */\nexport function resetField<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P, options?: ResetFieldOptions): void {\n const path = createPath(name);\n const {emitter, values, touched, errors, deleted} = form;\n values.delete(path.key);\n // The field returns to its baseline; commits from before the reset no\n // longer shadow the comparison.\n clearDirtyBaselines(form, path.key);\n // A parse baseline wholesale-shadows initialValues in reads (see\n // getValues), so unset alone would read the path as undefined. Remove\n // the path from the tree (immutable — parsedValues shares branches with\n // the schema's own output) and pin the initial value back as the live\n // value: equal to initialValues, so the field stays clean.\n if (form.parsedValues !== undefined) {\n form.parsedValues = unset(form.parsedValues, path.value);\n const initial = get(form.initialValues, path.value);\n if (initial !== undefined) values.set(path.key, initial);\n }\n if (options && 'value' in options) {\n values.set(path.key, options.value);\n }\n // A reset re-registers the branch, same as a write: tombstones on the\n // path or around it stop applying.\n reviveBranch(deleted, path);\n // Payload-less by design (unlike removeFieldByPath, whose mutations are\n // key-bounded): reviveBranch can un-tombstone ancestor or descendant\n // paths, whose readers must re-sync too.\n emit(emitter, 'change');\n if (!options?.keepTouched && touched.delete(path.key)) {\n emit(emitter, 'touched', path);\n }\n if (!options?.keepErrors && errors.delete(path.key)) {\n emit(emitter, 'errors', path);\n }\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n}\n\n/**\n * @param form\n */\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport {isIndex, isPromise, normalizePath, waitUntil} from '../util';\nimport type {\n FieldError,\n FieldErrorEntry,\n Form,\n ValidationMode,\n ValidateResult,\n ValidationOutcome\n} from '../form';\nimport {\n VALIDATION_OUTCOME,\n getErrors,\n getFirstError,\n hasErrors,\n setError,\n setErrorByPath\n} from './errors';\nimport {hasTouchedByPath, setTouchedByPath} from './touched';\nimport {getValueByPath, getValues} from './values';\nimport {isFieldError, isSegmentsPath, setParsedValues} from './internals';\n\nexport function unsetValidatingByPath(\n {emitter, validating}: Form,\n path: Path\n): void {\n validating.delete(path.key);\n // Path payload lets key-scoped subscribers (onKeyEvent) skip unrelated\n // fields; payload-less listeners ignore it.\n emit(emitter, 'validating', path);\n}\n\nexport function setValidatingByPath(\n {emitter, validating}: Form,\n path: Path\n): void {\n validating.add(path.key);\n emit(emitter, 'validating', path);\n}\n\n/**\n * Field validator. Returns an error (a string, a FieldError, or an array\n * mixing both) or undefined when valid; may return a Promise for async\n * validation.\n *\n * The second argument carries the validation context. `meta.signal` is\n * aborted as soon as the round is superseded — a newer round started, or\n * the field unregistered — so async validators can cancel their underlying\n * work (fetch, timers) instead of racing a stale result home. Stale\n * results are dropped independently by the registration's lock\n * ({@link registerValidatorByPath}), so validators that ignore the signal\n * stay correct too. Validators written against the older two-argument\n * signature keep working.\n */\nexport type Validator = (\n value: any,\n meta: {form: Form; path: Path; signal: AbortSignal}\n) =>\n | string\n | FieldError\n | (string | FieldError)[]\n | undefined\n | Promise<string | FieldError | (string | FieldError)[] | undefined>;\n\n/**\n * Synchronous pre-validator for {@link registerValidatorByPath}'s `sync`\n * accessor — declarative `required` rules compiled by `rulesToValidator`\n * in practice, but any sync-only check works. Runs on every kick, never\n * debounced: its errors land immediately and, while present,\n * short-circuit the debounced validator for that kick (the expensive\n * check never sees a value the gate already rejects). Must be synchronous\n * — unlike a {@link Validator} it may not return a Promise — and its meta\n * carries no `signal`: there is nothing to abort in a synchronous check.\n */\nexport type SyncValidator = (\n value: any,\n meta: {form: Form; path: Path}\n) => string | FieldError | (string | FieldError)[] | undefined;\n\n/** Live options for {@link registerValidatorByPath}: read at every kick\n * through accessors, so callers (React's `useValidate`) can swap the\n * validator/debounce/sync-gate per render without re-subscribing the\n * registration mid-flight. */\nexport type ValidatorRegistration = {\n /** Current debounced validator (or undefined — a sync-only\n * registration). */\n validate: () => Validator | undefined;\n /** Debounce delay in milliseconds; 0 (default) runs immediately. */\n debounce: () => number;\n /** Synchronous pre-validator, run on every kick (never debounced). */\n sync: () => SyncValidator | undefined;\n /** Whether the debounced validator still runs when the sync gate\n * failed — TanStack Form's `asyncAlways`: the gate's errors land\n * immediately (never debounced), then the validator's own result lands\n * alongside them (per-source semantics) instead of the gate\n * short-circuiting the whole kick. Optional — absent means false\n * (gate failure owns the kick's outcome), so pre-existing\n * framework-free registrations keep working unchanged. */\n asyncAlways?: () => boolean;\n};\n\n/**\n * Register a field validator's kick at `path` in {@link Form.validators}\n * — the framework-free machinery behind `useValidate`. Returns a\n * disposer that drops the registration and cancels any pending debounce\n * window or in-flight round (its signal aborts and its validating mark\n * is released).\n *\n * Contract of the registered kick (the same contract `trigger` /\n * `ensureValidate` rely on when they run every entry, and the\n * user-change gate relies on when it runs the changed path's entry):\n * - the `sync` gate runs immediately on every kick — never debounced —\n * and while it returns errors, the debounced validator is skipped for\n * that kick and any pending window or in-flight round is superseded —\n * unless `asyncAlways` is set, in which case the validator still runs\n * and its result lands alongside the gate's errors (per-source);\n * - a positive `debounce` merges kicks inside the window: only the last\n * one runs the validator, and while the timer is pending the field\n * counts as validating so `trigger`/`ensureValidate` wait it out;\n * - async results land under a lock: a superseded round's outcome —\n * rejection included — is dropped, and only the owning round releases\n * the validating mark;\n * - a synchronous throw inside the validator propagates to the caller\n * (the validating mark is not left stuck behind it).\n *\n * Registering at a path already registered by another mount replaces it\n * (last-wins, the historical `useValidate` behavior); the disposer drops\n * its own registration unconditionally.\n *\n * @param form\n * @param path\n * @param registration live validator/debounce/sync accessors\n * @return disposer: unregister and cancel pending work\n */\nexport function registerValidatorByPath(\n form: Form,\n path: Path,\n registration: ValidatorRegistration\n): () => void {\n // The pending debounce timer and the current round's controller live in\n // this closure so the disposer below can cancel them.\n let timer: ReturnType<typeof setTimeout> | null = null;\n let controller: AbortController | null = null;\n // Whether this registration currently holds the path's slot in\n // form.validating. The mark is taken when a debounce window opens or an\n // async round starts, and released by whichever round settles last —\n // including a later sync round that supersedes an in-flight async one\n // (its own .finally is lock-gated out by then).\n let marked = false;\n // The async-round lock: only the latest round may land its result or\n // release the mark; a superseded round's outcome is dropped wholesale.\n let lock: object | null = null;\n // Which source wrote the error currently on display — the sync gate or\n // the debounced validator. Tracked so a passing sync check can clear\n // its own stale error immediately instead of leaving it on screen until\n // the debounced round lands. External writers (setError, form-level\n // validate) are invisible here; a passing round clearing them matches\n // the long-standing \"a field validator owns its whole key\" contract.\n let errorSource: 'sync' | 'validator' | null = null;\n /** Does a validator result land errors? `[]` normalizes away exactly\n * like undefined in setErrorByPath. */\n const hasErrors = (errors: any): boolean =>\n errors !== undefined && !(Array.isArray(errors) && errors.length === 0);\n const mark = () => {\n if (marked) return;\n marked = true;\n setValidatingByPath(form, path);\n };\n const unmark = () => {\n if (!marked) return;\n marked = false;\n unsetValidatingByPath(form, path);\n };\n\n /** Run the synchronous gate on the field's current value. Its errors\n * land immediately — the gate is never debounced. Returns true when\n * errors landed (the kick's whole outcome for the debounced validator).\n * A passing gate clears the field's errors when they were its own from\n * an earlier kick, or when no debounced validator exists to own the\n * round. */\n const runSync = (): boolean => {\n const sync = registration.sync();\n if (!sync) return false;\n const errors = sync(getValueByPath(form, path), {form, path});\n if (!hasErrors(errors)) {\n // A stale error the gate itself wrote is answered by the gate\n // alone; a rules-only registration's passing check is the whole\n // round. With a debounced validator registered, its upcoming round\n // owns the outcome and lands it later.\n if (!registration.validate() || errorSource === 'sync') {\n setErrorByPath(form, path, undefined);\n errorSource = null;\n }\n return false;\n }\n setErrorByPath(form, path, errors);\n errorSource = 'sync';\n return true;\n };\n\n /** Re-run the sync gate purely for its error list — no store write.\n * asyncAlways landings merge it with the validator's result so each\n * source keeps its own errors on display (TanStack's per-source\n * errorMap shape); the non-asyncAlways path never calls this. */\n const collectSyncErrors = (): (string | FieldError)[] | null => {\n const sync = registration.sync();\n if (!sync) return null;\n const errors = sync(getValueByPath(form, path), {form, path});\n if (errors === undefined) return null;\n const list = Array.isArray(errors) ? errors : [errors];\n return list.length ? list : null;\n };\n\n /** Land a validator result. asyncAlways merges the gate's current\n * verdict (re-collected — the value may have drifted since the round\n * started) ahead of the validator's errors, so a still-failing gate\n * keeps its own errors on screen; the default path stays the\n * historical \"validator owns the whole key\" write. */\n const land = (\n result: string | FieldError | (string | FieldError)[] | undefined\n ): void => {\n if (registration.asyncAlways?.()) {\n const gate = collectSyncErrors();\n const own =\n result === undefined ? [] : Array.isArray(result) ? result : [result];\n setErrorByPath(form, path, [...(gate ?? []), ...own]);\n errorSource = hasErrors(result) ? 'validator' : gate ? 'sync' : null;\n } else {\n setErrorByPath(form, path, result);\n errorSource = hasErrors(result) ? 'validator' : null;\n }\n };\n\n /** Drop any pending window or in-flight round without landing it: the\n * sync gate now owns the outcome, so the debounced validator must not\n * run for this value. */\n const supersede = () => {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n controller?.abort();\n lock = {};\n };\n\n /** Run the debounced validator on the field's current value and land\n * its result — the sync gate has already passed. */\n const runValidator = () => {\n const fn = registration.validate();\n if (!fn) {\n unmark();\n return;\n }\n // Abort the superseded round's signal: a listening validator should\n // stop its underlying work. The lock refresh below independently\n // drops any result that still arrives, signal or not.\n controller?.abort();\n controller = new AbortController();\n const round = (lock = {});\n let result;\n try {\n result = fn(getValueByPath(form, path), {\n form,\n path,\n signal: controller.signal\n });\n } catch (e) {\n // A throwing sync validator propagates to the caller as it always\n // has; just don't leave the validating mark stuck behind it.\n unmark();\n throw e;\n }\n if (!isPromise(result)) {\n land(result);\n // Error first, then release the mark: 'validating' subscribers\n // (trigger) re-read state on wake and must see the landed error.\n unmark();\n return;\n }\n mark();\n result\n .then(\n (error: string | FieldError | (string | FieldError)[] | undefined) => {\n if (lock === round) {\n land(error);\n }\n }\n )\n // A rejected round is the normal way a signal-listening validator\n // gives up (fetch throws AbortError once aborted); swallow it and\n // let the owning round write the outcome.\n .catch(() => {})\n .finally(() => {\n if (lock === round) {\n unmark();\n lock = null;\n }\n });\n };\n\n /** A debounce window fired: the value may have drifted since the last\n * kick (programmatic writes do not kick validators), so re-run the\n * sync gate before spending the debounced validator on a value the\n * gate already rejects. Under asyncAlways a failing gate does not own\n * the outcome — the validator still runs and both verdicts land. */\n const run = () => {\n timer = null;\n if (runSync() && !registration.asyncAlways?.()) {\n supersede();\n unmark();\n return;\n }\n runValidator();\n };\n\n const kick = () => {\n if (runSync() && !registration.asyncAlways?.()) {\n supersede();\n unmark();\n return;\n }\n if (!registration.validate()) return;\n const debounce = registration.debounce();\n if (debounce > 0) {\n // Only the last kick inside the window runs: restart the timer on\n // every kick. The mark keeps trigger/ensureValidate's\n // validating-set wait covering the pending timer, not just\n // in-flight promises.\n if (timer !== null) clearTimeout(timer);\n else mark();\n timer = setTimeout(run, debounce);\n return;\n }\n runValidator();\n };\n\n form.validators.set(path.key, kick);\n return () => {\n form.validators.delete(path.key);\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n unmark();\n controller?.abort();\n };\n}\n\n/**\n * Set field error\n * @param form\n * @param name\n * @param error string is normalized to {type: 'custom', message}; a\n * FieldError object is stored as-is; an array holds several errors\n * (falsy items dropped, strings normalized); undefined clears\n */\n/** Options accepted by {@link trigger}. `shouldTouch` defaults to `false`;\n * omitting the options object entirely keeps the plain validate-only\n * behavior, so the historical two-argument calls are untouched. */\nexport type TriggerOptions = {\n /** Mark every path in the triggered scope as touched — even when\n * validation fails — once the round settles. Mirrors react-hook-form's\n * trigger `shouldTouch`. Defaults to `false`. */\n shouldTouch?: boolean;\n /**\n * Focus the first errored field in the triggered scope once the round\n * settles (and only when the round left errors) — react-hook-form's\n * trigger `shouldFocus` counterpart. Rides the 'focusError' event\n * channel like a failed submit's auto-focus: only mounted bound fields\n * react, unmounted ones are silent no-ops. Without `name` the first key\n * of the errors Map wins (the same rule handleSubmit applies); with\n * `name` the first errored triggered key does. Defaults to `false`.\n */\n shouldFocus?: boolean;\n};\n\n/**\n * Trigger field validation.\n *\n * Without `name` every registered field validator runs. A single `name` —\n * dotted string or segments array — runs only that field's validator, and\n * an array of names runs each one in order. An empty array is a no-op, as\n * is any name with no registered validator. An array argument counts as\n * one segments path only when it mixes in numbers (`['items', 0]`); pure\n * string arrays are name lists, so `['a', 'b']` triggers fields `a` and\n * `b`, not the nested path `a.b`.\n *\n * `options.shouldTouch` marks the triggered scope — the given names, or\n * every registered field when `name` is omitted — as touched after the\n * round settles, whether validation passed or failed. The wait/settle\n * logic is untouched: the marking rides on top of the settled round, so\n * subscribers observe errors and touched together rather than mid-flight.\n *\n * The returned promise waits for the triggered validation to settle —\n * async validators included — so their errors have already landed in\n * `form.errors` when it resolves. It never rejects: landing errors is the\n * expected outcome here, not a failure. Resolves `true` when the triggered\n * scope is error-free, `false` otherwise. Without `name` the scope is all\n * fields plus the form-level `validate` result (which runs after field\n * validators settle, same pipeline as {@link ensureValidate}); with `name`\n * only those fields' own errors count and form-level `validate` is\n * skipped (RHF semantics).\n *\n * Fire-and-forget callers may ignore the promise: the validator kicks\n * still happen synchronously, matching the pre-promise behavior.\n *\n * @param form\n * @param name field name(s) to trigger, or all fields when omitted\n * @param options extra behavior toggles ({@link TriggerOptions}); omitted,\n * validation alone runs — no touched marking\n * @return whether the triggered scope is error-free once validation settles\n */\nexport async function trigger(\n form: Form,\n name?: Name | Name[],\n options?: TriggerOptions\n): Promise<boolean> {\n // Never reject (an error landing is a normal outcome, not a failure), so\n // waitUntil's isReject is permanently false. Without a name the wait is\n // deliberately conservative — every FIELD validator, unrelated in-flight\n // ones included, because the round covers the whole form (and the\n // form-level validate's own window is excluded via fieldsSettled —\n // callers wait that out through the kick's promise instead, so a pending\n // window never gates the next kick). With a name the wait narrows to the\n // triggered keys only: a slow async validator on field B must not hold\n // trigger('a') hostage when the round never reads B.\n const settle = (keys?: string[]) =>\n waitUntil(\n form.emitter,\n 'validating',\n () =>\n keys === undefined\n ? fieldsSettled(form)\n : keys.every(key => !form.validating.has(key)),\n () => false\n );\n\n if (name === undefined) {\n form.validators.forEach(validator => validator());\n await settle();\n if (form.validate) await runFormValidate(form);\n // shouldTouch marks the whole registered scope — every key the round\n // could have validated — pass or fail alike.\n if (options?.shouldTouch) touchKeys(form, [...form.validators.keys()]);\n // First error across the errors Map — the same rule a failed submit's\n // auto-focus applies (a form-level error may land first; it has no\n // element, so it is a silent no-op like every unbound path).\n if (options?.shouldFocus) {\n const firstKey = form.errors.keys().next().value;\n if (firstKey !== undefined) emit(form.emitter, 'focusError', firstKey);\n }\n return !hasErrors(form);\n }\n\n const keys: string[] =\n typeof name === 'string' || isSegmentsPath(name)\n ? [createPath(name).key]\n : name.map(one => createPath(one).key);\n keys.forEach(key => form.validators.get(key)?.());\n await settle(keys);\n if (options?.shouldTouch) touchKeys(form, keys);\n // Focus the first errored key among the triggered scope — trigger('a')\n // never focuses B's pre-existing error.\n if (options?.shouldFocus) {\n const firstKey = keys.find(key => form.errors.has(key));\n if (firstKey !== undefined) emit(form.emitter, 'focusError', firstKey);\n }\n return keys.every(key => !form.errors.has(key));\n}\n\n/** trigger's `shouldTouch` marking: touch every key in the triggered scope\n * through {@link setTouchedByPath}, which no-ops on already-touched keys\n * and emits the path-carrying 'touched' event per newly touched one. Keys\n * are the stored JSON-stringified segments shape, so parse them back into\n * Path — normalizePath passes segment arrays through untouched, making the\n * key round-trip exact. */\nfunction touchKeys(form: Form, keys: string[]): void {\n keys.forEach(key => setTouchedByPath(form, createPath(JSON.parse(key))));\n}\n\n/**\n * Flatten a form-level validate result and write each leaf error through\n * setError. Nested objects descend into deeper paths ({a: {b: 'msg'}} sets\n * the 'a.b' error), array values contribute every non-empty string they\n * hold as separate errors (zod flatten() formErrors style), and\n * FieldError-shaped objects are stored as-is. Falsy values are skipped.\n *\n * When `footprint` is passed (validateDeps forms only), every leaf this\n * round actually stored is recorded into it — the exact stored array —\n * so the next round can drop exactly what this one wrote.\n */\nfunction setFormErrors(\n form: Form,\n result: Record<string, any>,\n segments: PathSegments = [],\n footprint?: Map<string, FieldError[]>\n): void {\n Object.entries(result).forEach(([key, value]) => {\n // Error-tree keys are explicit object keys, not path expressions:\n // a numeric key ('0' — Standard Schema issue paths stringify array\n // indices) stays a literal string segment instead of feeding the\n // path parser, whose dotted-numeric rule governs path strings only.\n const path: PathSegments = [\n ...segments,\n ...(isIndex(key) ? [key] : normalizePath(key))\n ];\n if (typeof value === 'string') {\n if (value) {\n setError(form, path, value);\n recordFootprint(form, path, footprint);\n }\n } else if (Array.isArray(value)) {\n setError(form, path, value);\n recordFootprint(form, path, footprint);\n } else if (isFieldError(value)) {\n setError(form, path, value);\n recordFootprint(form, path, footprint);\n } else if (value && typeof value === 'object') {\n setFormErrors(form, value, path, footprint);\n }\n });\n}\n\n/** Record one leaf write of a form-level validate round: the path key and\n * the exact array now stored there. Nothing is recorded when the write\n * normalized away (all-empty arrays) — there is no error to own. The\n * stored array is read back from the errors Map because setErrorByPath\n * owns normalization. */\nfunction recordFootprint(\n form: Form,\n segments: PathSegments,\n footprint: Map<string, FieldError[]> | undefined\n): void {\n if (!footprint) return;\n const path = createPath(segments);\n const stored = form.errors.get(path.key);\n if (stored) footprint.set(path.key, stored);\n}\n\n/**\n * Land a form-level validate result. A plain record keeps the\n * long-standing behavior — flattened into field errors by\n * {@link setFormErrors}. A branded {@link ValidationOutcome} splits\n * instead: `errors` flattens exactly like a plain record, and `values`\n * (the schema's parsed output — coerced/transformed values included)\n * becomes the form's parsedValues baseline. Falsy results are skipped,\n * branded or not.\n *\n * Forms that opted into `validateDeps` additionally get round-scoped\n * error ownership: before the new result lands, the errors the previous\n * round wrote are dropped ({@link clearFormValidateErrors}), so a re-run\n * that passes makes the cross-field error disappear — and the new\n * round's own writes become the tracked footprint. Forms without the\n * option keep the historical write-only behavior untouched.\n */\nfunction applyValidateResult(\n form: Form,\n result: ValidateResult<any> | undefined\n): void {\n const footprint = form.validateDeps ? getFormErrorFootprint(form) : undefined;\n if (footprint) {\n clearFormValidateErrors(form, footprint);\n footprint.clear();\n }\n if (!result) return;\n if (typeof result === 'object' && VALIDATION_OUTCOME in result) {\n const outcome = result as ValidationOutcome<any>;\n if (outcome.errors) setFormErrors(form, outcome.errors, [], footprint);\n setParsedValues(form, outcome.values);\n return;\n }\n setFormErrors(form, result as Record<string, any>, [], footprint);\n}\n\n/** Per-form error footprint of the last form-level validate round: every\n * path key it flattened onto, with the exact array instance it stored.\n * Tracked only for forms that opted into `validateDeps` — held in a\n * WeakMap so the Form shape and the non-opted pipeline stay untouched. */\nconst formErrorFootprints = new WeakMap<Form, Map<string, FieldError[]>>();\n\nfunction getFormErrorFootprint(form: Form): Map<string, FieldError[]> {\n let footprint = formErrorFootprints.get(form);\n if (!footprint) {\n footprint = new Map();\n formErrorFootprints.set(form, footprint);\n }\n return footprint;\n}\n\n/** Does the form still show an error the last form-level round wrote?\n * Compared by identity, not key membership: once a field validator,\n * `setServerErrors`, a manual `setError` or `clearErrors` replaces the\n * stored array, that error is no longer the round's to own — neither the\n * dep-change gate nor the next round's clearing may touch it. */\nfunction hasFormValidateErrors(form: Form): boolean {\n const footprint = formErrorFootprints.get(form);\n if (!footprint) return false;\n for (const [key, written] of footprint) {\n if (form.errors.get(key) === written) return true;\n }\n return false;\n}\n\n/** Drop the last form-level round's errors before the next round lands.\n * Per key the stored array is identity-checked — an error overwritten or\n * cleared by anyone else in between survives — and each drop emits the\n * same path-payload 'errors' event {@link setErrorByPath} would, so\n * subscribed fields re-render exactly like on any error write. */\nfunction clearFormValidateErrors(\n form: Form,\n footprint: Map<string, FieldError[]>\n): void {\n for (const [key, written] of footprint) {\n const stored = form.errors.get(key);\n if (stored !== written) continue;\n form.errors.delete(key);\n emit(form.emitter, 'errors', createPath(JSON.parse(key)));\n }\n}\n\n/** Key the form-level validate round reserves in `form.validating` while\n * its debounce window is pending or its async round is in flight. Real\n * path keys are JSON-stringified segments (always bracketed), so a bare\n * word can never collide. */\nconst FORM_VALIDATING_KEY = '__form_validate__';\n\n/** Are all FIELD validation rounds drained? trigger/ensureValidate wait on\n * this before kicking the form-level validate (its errors gate whether the\n * form-level round may run at all). The form validate's own reserved key\n * is deliberately excluded: its window is waited out through the kick's\n * returned promise instead, so a pending window or in-flight form round\n * never gates the next kick — a kick during an in-flight round opens a\n * new window and the newer round supersedes, mirroring the per-field\n * `validateDebounce` contract. */\nfunction fieldsSettled(form: Form): boolean {\n for (const key of form.validating) {\n if (key !== FORM_VALIDATING_KEY) return false;\n }\n return true;\n}\n\n/** Sentinel telling {@link settleFormValidate} the round landed cleanly —\n * distinct from every rejection payload, including `undefined`. */\nconst SETTLED = Symbol('form-validate-settled');\n\n/** Per-form bookkeeping for the debounced form-level validate: the\n * pending window timer, the in-flight round, and the waiters merged into\n * the current window group. Held in a WeakMap so the Form instance shape\n * is untouched for forms that never set `validateDebounce`. */\ntype FormValidateState = {\n timer: ReturnType<typeof setTimeout> | null;\n controller: AbortController | null;\n /** Identity of the in-flight round; a superseded round's outcome\n * (rejection included) is dropped by comparing against it. */\n round: object | null;\n /** Whether this state currently holds FORM_VALIDATING_KEY in\n * form.validating. */\n marked: boolean;\n waiters: Array<{resolve: () => void; reject: (error: unknown) => void}>;\n};\n\nconst formValidateStates = new WeakMap<Form, FormValidateState>();\n\nfunction getFormValidateState(form: Form): FormValidateState {\n let state = formValidateStates.get(form);\n if (!state) {\n state = {\n timer: null,\n controller: null,\n round: null,\n marked: false,\n waiters: []\n };\n formValidateStates.set(form, state);\n }\n return state;\n}\n\n/**\n * Run the form-level `validate` and land its result, honoring the form's\n * `validateDebounce` option.\n *\n * Undebounced (`0`/undefined) the caller's await *is* the validate call —\n * the long-standing pipeline, unchanged: no validating mark, no round\n * gating, immediate values snapshot, rejection propagating to the caller.\n *\n * Debounced, the kick opens (or restarts — kicks inside the window merge)\n * a window during which the form counts as validating, so `trigger` /\n * `ensureValidate` / submit wait the window out exactly like a field's\n * `validateDebounce` window. When the timer fires, the round reads the\n * then-current values, supersedes (aborts) any in-flight round, and lands\n * its result. The returned promise settles once the window group's final\n * round has landed — rejecting when that round's validate callback threw\n * or its promise rejected, mirroring the undebounced propagation — so\n * merged callers all observe the same outcome.\n *\n * Only called under `if (form.validate)`. Public: the form-level-only\n * round (field validators excluded) — `useForm`'s `validateOnMount` run\n * and cross-cutting re-checks use it; `trigger`/`ensureValidate` compose\n * it after the field validators settle.\n */\nexport function runFormValidate(form: Form): Promise<void> {\n const validate = form.validate;\n if (!validate) return Promise.resolve();\n const debounce = form.validateDebounce ?? 0;\n if (debounce <= 0) {\n // Standalone controller: nothing supersedes an undebounced call, so\n // its signal never fires — it exists for argument-shape parity with\n // the debounced rounds (and with field-level meta.signal).\n const controller = new AbortController();\n return Promise.resolve(\n validate(getValues(form), {form, signal: controller.signal})\n ).then(result => {\n applyValidateResult(form, result);\n });\n }\n const state = getFormValidateState(form);\n // (Re)open the window: a kick while the timer is pending restarts it\n // (only the last kick's values run); one while a round is in flight\n // keeps the validating mark held and defers to the new window's round.\n if (state.timer !== null) clearTimeout(state.timer);\n else {\n state.marked = true;\n form.validating.add(FORM_VALIDATING_KEY);\n emit(form.emitter, 'validating');\n }\n state.timer = setTimeout(() => {\n state.timer = null;\n const round = (state.round = {});\n runFormValidateRound(form, state, round).then(\n () => settleFormValidate(form, state, round, SETTLED),\n error => settleFormValidate(form, state, round, error)\n );\n }, debounce);\n return new Promise<void>((resolve, reject) => {\n state.waiters.push({resolve, reject});\n });\n}\n\n/** Run one form-level validate round with the form's current values.\n * Aborts the previous in-flight round's signal; a superseded round's\n * outcome — rejection included — is dropped by the round gate, exactly\n * like the field-level lock. */\nfunction runFormValidateRound(\n form: Form,\n state: FormValidateState,\n round: object\n): Promise<void> {\n const validate = form.validate;\n if (!validate) return Promise.resolve();\n state.controller?.abort();\n const controller = (state.controller = new AbortController());\n let outcome: Promise<any>;\n try {\n outcome = Promise.resolve(\n validate(getValues(form), {form, signal: controller.signal})\n );\n } catch (error) {\n outcome = Promise.reject(error);\n }\n return outcome.then(\n result => {\n if (state.round === round) applyValidateResult(form, result);\n },\n error => {\n if (state.round === round) throw error;\n }\n );\n}\n\n/** Land the window group's outcome: release the validating mark — after\n * the round's errors/values have already landed, because 'validating'\n * subscribers (trigger, ensureValidate) re-read state on wake — and\n * settle every merged waiter. A superseded round never lands here (the\n * newer round owns the release), and a window that re-opened while the\n * round was in flight defers: the mark and the waiters carry over to the\n * pending timer's round. */\nfunction settleFormValidate(\n form: Form,\n state: FormValidateState,\n round: object,\n outcome: unknown\n): void {\n if (state.round !== round) return;\n state.round = null;\n if (state.timer !== null) return;\n if (state.marked) {\n state.marked = false;\n form.validating.delete(FORM_VALIDATING_KEY);\n emit(form.emitter, 'validating');\n }\n const waiters = state.waiters;\n state.waiters = [];\n for (const waiter of waiters) {\n if (outcome === SETTLED) waiter.resolve();\n else waiter.reject(outcome);\n }\n}\n\n/**\n * Form-level twin of the gated validator kick in `useField`'s onChange:\n * re-run the form-level `validate` after a user change to a field listed\n * in `validateDeps`. Called from the field's own change pipeline (typing\n * and `changeValue` alike — both route through the mounted field's\n * onChange), so programmatic `setValue` writes do not re-run it, exactly\n * like they do not re-run field validators.\n *\n * The gate mirrors the per-field matrix with the *changed field's*\n * effective `mode` (a per-field override governs when its changes may\n * fire validation) and the form-level `reValidateMode` against the last\n * round's error footprint ({@link hasFormValidateErrors} — field\n * validators' errors never arm this kick):\n * - `mode` `'onChange'`/`'all'` — every dep change re-runs;\n * - `mode` `'onTouched'` — dep changes re-run once the field was touched;\n * - otherwise the re-run waits for `reValidateMode: 'onChange'` (the\n * default) while the last round's error is still live — the\n * submit-then-fix flow: the mismatch lands on submit, editing the\n * dependency re-runs the validate and clears it.\n * `reValidateMode: 'onBlur'`/`'onSubmit'` never re-run on a change (a\n * change is not a blur; submit re-runs are the submit pipeline's job).\n *\n * The kick is fire-and-forget: async round rejections are swallowed\n * (nothing in an event handler can await them), while a synchronous\n * throw inside the validate callback propagates to the caller exactly\n * like a field validator's does.\n *\n * A no-op unless the form set `validateDeps` listing `path` — forms\n * without the option pay one property check here.\n */\nexport function revalidateFormOnChange(\n form: Form,\n path: Path,\n mode: ValidationMode\n): void {\n if (!form.validateDeps?.has(path.key) || !form.validate) return;\n if (\n mode === 'onChange' ||\n mode === 'all' ||\n (mode === 'onTouched' && hasTouchedByPath(form, path)) ||\n (form.reValidateMode === 'onChange' && hasFormValidateErrors(form))\n ) {\n runFormValidate(form).catch(() => {});\n }\n}\n\n/** Per-form registry of field-level `validateDeps` declarations ({@link\n * revalidateDependentsOnChange}): dep path key -> every dependent field key\n * that listed it. Held in a WeakMap so the Form shape is untouched for\n * forms whose fields never declare deps. */\nconst fieldValidateDeps = new WeakMap<Form, Map<string, Set<string>>>();\n\n/** Register one field's validateDeps declaration: `key` re-validates when\n * any path in `depKeys` takes a user change. Idempotent per (key, dep)\n * pair, so StrictMode's double effect is harmless. */\nexport function registerFieldValidateDeps(\n form: Form,\n key: string,\n depKeys: string[]\n): void {\n let deps = fieldValidateDeps.get(form);\n if (!deps) {\n deps = new Map();\n fieldValidateDeps.set(form, deps);\n }\n for (const depKey of depKeys) {\n let dependents = deps.get(depKey);\n if (!dependents) {\n dependents = new Set();\n deps.set(depKey, dependents);\n }\n dependents.add(key);\n }\n}\n\n/** Drop one field's validateDeps registration ({@link\n * registerFieldValidateDeps}). Entries nobody lists anymore are removed so\n * the registry never outlives its fields. */\nexport function unregisterFieldValidateDeps(\n form: Form,\n key: string,\n depKeys: string[]\n): void {\n const deps = fieldValidateDeps.get(form);\n if (!deps) return;\n for (const depKey of depKeys) {\n const dependents = deps.get(depKey);\n if (!dependents?.delete(key)) continue;\n if (!dependents.size) deps.delete(depKey);\n }\n}\n\n/**\n * Field-level twin of {@link revalidateFormOnChange}: after a user change\n * to `path`, re-run every field validator that declared `path` in its\n * `validateDeps` (useField option). Same channel, same gate: the kick\n * rides the changed field's own onChange pipeline (typing and\n * `changeValue` alike), so programmatic `setValue` writes never fire it —\n * exactly like field validators and the form-level `validateDeps`.\n *\n * The gate mirrors the form-level matrix with the *changed field's*\n * effective `mode` and the form-level `reValidateMode` against each\n * dependent's live error:\n * - `mode` `'onChange'`/`'all'` — every dep change re-runs the dependent;\n * - `mode` `'onTouched'` — once the changed field was touched;\n * - otherwise the re-run waits for `reValidateMode: 'onChange'` (the\n * default) while the dependent still shows an error — the\n * submit-then-fix flow: the mismatch lands on submit, editing the\n * dependency re-validates the dependent and a passing round clears it\n * (a field validator owns its whole key, so the re-run's result\n * replaces whatever the previous round wrote — the field-level shape\n * of the form-level footprint reclaim).\n *\n * The kick is an ordinary validator kick: the dependent's own\n * `validateDebounce` window applies, and a synchronous throw inside its\n * validate propagates to the caller like any field validator's would.\n *\n * A no-op unless some field declared `path` as a dep — forms without any\n * field-level `validateDeps` pay one property check here.\n */\nexport function revalidateDependentsOnChange(\n form: Form,\n path: Path,\n mode: ValidationMode\n): void {\n const dependents = fieldValidateDeps.get(form)?.get(path.key);\n if (!dependents?.size) return;\n for (const dependent of dependents) {\n // A self-dep changes nothing: the field's own onChange above already\n // validated it under the same gate.\n if (dependent === path.key) continue;\n if (\n mode === 'onChange' ||\n mode === 'all' ||\n (mode === 'onTouched' && hasTouchedByPath(form, path)) ||\n (form.reValidateMode === 'onChange' && form.errors.has(dependent))\n ) {\n form.validators.get(dependent)?.();\n }\n }\n}\n\n/** The Error {@link ensureValidate} rejects with: `message` is the first\n * error's display text ({@link getFirstError}) — the long-standing shape\n * — and `.errors` carries the complete flattened error list ({@link\n * getErrors}: `{path, type, message}` entries, dotted display paths) so\n * catchers can branch on types and locate fields without re-reading the\n * form. */\nexport type FormValidationError = Error & {errors: FieldErrorEntry[]};\n\n/** Build {@link ensureValidate}'s rejection: first error's message, every\n * error attached. */\nfunction validationError(form: Form): FormValidationError {\n const error = new Error(getFirstError(form)) as FormValidationError;\n error.errors = getErrors(form);\n return error;\n}\n\n/**\n * Validate and throw if any field error.\n * @param form\n * @return resolve if no error; reject and stop validate if has an error\n */\nexport async function ensureValidate(form: Form): Promise<void> {\n form.validators.forEach(validator => validator());\n\n await waitUntil(\n form.emitter,\n 'validating',\n () => fieldsSettled(form),\n () => hasErrors(form)\n ).catch(() => {\n throw validationError(form);\n });\n\n if (form.validate) {\n await runFormValidate(form);\n if (hasErrors(form)) throw validationError(form);\n }\n}\n\n/**\n * Validate and return if any field error.\n * @param form\n * @return error message string or void\n */\nexport async function validate(form: Form): Promise<void | string> {\n return ensureValidate(form).catch(e => e.message);\n}\n","import createPath from '../path';\nimport type {Path, PathSegments} from '../path';\nimport type {FieldPath, PathValueOf} from '../types';\nimport type {Form, ValidationMode} from '../form';\nimport {setValueByPath} from './values';\nimport type {SetFieldOptions} from './values';\nimport {revalidateFormOnChange, revalidateDependentsOnChange} from './validate';\nimport {hasTouchedByPath, setTouchedByPath} from './touched';\nimport {getFieldErrorsByPath} from './errors';\nimport {setDirtyBaseline} from './internals';\n\n/** Per-form registry of mounted fields' validation-mode overrides: path\n * key -> the field's `mode` option (undefined = follow {@link Form.mode})\n * plus an owner token so competing mounts at one path clean up safely.\n * Presence of an entry is the \"a field is mounted at this path\" signal\n * that routes {@link changeValueByPath} into the gated user-change\n * pipeline ({@link userChangeByPath}). Held in a WeakMap so the Form\n * shape carries only plain state fields. */\nconst fieldModes = new WeakMap<\n Form,\n Map<string, {mode: ValidationMode | undefined; token: object}>\n>();\n\n/**\n * Set a field value as a user change.\n *\n * The write rides the same gated user-change pipeline a user typing into\n * the field would fire when a field is mounted on the path (registered\n * through {@link registerFieldMode} — `useField` registers on mount): the\n * field's effective `mode` (per-field override included) and the form's\n * `reValidateMode` drive validation exactly as in {@link\n * userChangeByPath}. With no mounted field on the path it degrades to a\n * plain value set ({@link setValue}).\n *\n * This is the channel for component-library bridges that hand a control a\n * plain setter bound to a field — they cannot rebuild the gating from\n * public form state, because the per-field mode override and the\n * live-error view that gates `reValidateMode` live in the field\n * registration, not in public state.\n *\n * Contrast {@link setValue}: that is the imperative channel — its\n * `shouldValidate` option kicks the field's validator unconditionally,\n * ignoring any mode. Functional updaters are the caller's to evaluate\n * ({@link getValue}).\n *\n * `options` carries the same {@link SetFieldOptions}: on the fallback path\n * (no mounted field) they forward to {@link setValueByPath} wholesale,\n * while on the mounted-field path only `shouldDirty: false` applies — the\n * write lands as a commit while the field's own mode gating keeps driving\n * validation, which is the point of this channel.\n *\n * @param form\n * @param name\n * @param value\n * @param options\n */\nexport function changeValue<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(\n form: Form<T>,\n name: P,\n value: PathValueOf<T, P>,\n options?: SetFieldOptions\n): void {\n changeValueByPath(form, createPath(name), value, options);\n}\n\n/**\n * Set a field value as a user change, by parsed path\n * @param form\n * @param path\n * @param value\n * @param options\n */\nexport function changeValueByPath(\n form: Form,\n path: Path,\n value: any,\n options?: SetFieldOptions\n): void {\n // The baseline must land before the mounted field's change pipeline runs\n // — its write emits synchronously and subscribers read dirty state\n // inside the emission, so installing after the call would flash\n // dirty-then-clean.\n if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);\n if (fieldModes.get(form)?.get(path.key)) {\n // Mounted field: ride the gated user-change pipeline — the field's\n // own mode drives validation, so `shouldValidate`/`shouldTouch` have\n // no meaning here (forcing them would defeat the gating).\n userChangeByPath(form, path, value);\n } else {\n setValueByPath(form, path, value, options);\n }\n}\n\n/**\n * Register a mounted field's `mode` override at `path` for user-change\n * gating ({@link userChangeByPath} / {@link userBlur}). Returns the\n * registration token for {@link unregisterFieldMode} plus whether the\n * slot was already occupied — two fields mounted at one path is almost\n * always a bug: the latest mount's mode governs every user-change write\n * there, which the React layer warns about in DEV.\n *\n * @param form\n * @param path\n * @param mode the field's `mode` option, or undefined to follow\n * {@link Form.mode}\n * @return `token` to hand to {@link unregisterFieldMode}; `displaced`\n * true when a previous registration at the same path still owned\n * the slot\n */\nexport function registerFieldMode(\n form: Form,\n path: Path,\n mode: ValidationMode | undefined\n): {token: object; displaced: boolean} {\n let modes = fieldModes.get(form);\n if (!modes) {\n modes = new Map();\n fieldModes.set(form, modes);\n }\n const displaced = modes.has(path.key);\n const token = {};\n modes.set(path.key, {mode, token});\n return {token, displaced};\n}\n\n/** Drop a {@link registerFieldMode} registration. A later mount at the\n * same path keeps its slot: only the entry owned by `token` is removed. */\nexport function unregisterFieldMode(\n form: Form,\n path: Path,\n token: object\n): void {\n const modes = fieldModes.get(form);\n const entry = modes?.get(path.key);\n if (modes && entry && entry.token === token) modes.delete(path.key);\n}\n\n/** The user-change validation gate shared by a mounted field's onChange\n * and {@link changeValueByPath}: kick the field's validator, the\n * form-level `validateDeps` re-run and the field-level `validateDeps`\n * dependents under the mode/reValidateMode matrix. The live (stored)\n * error view arms the reValidate kick — an error hidden behind a render\n * layer's delayError window still counts, so typing can clear it before\n * it ever shows. */\nfunction runUserChangeGate(form: Form, path: Path, mode: ValidationMode): void {\n if (\n mode === 'onChange' ||\n mode === 'all' ||\n (mode === 'onTouched' && hasTouchedByPath(form, path)) ||\n (getFieldErrorsByPath(form, path).length > 0 &&\n form.reValidateMode === 'onChange')\n )\n form.validators.get(path.key)?.();\n // Form-level validate deps: a user change to a listed field re-runs the\n // form-level validate under the same mode/reValidateMode gating above\n // (evaluated against the last round's own error footprint). No-op for\n // forms without validateDeps.\n revalidateFormOnChange(form, path, mode);\n // Field-level validate deps: fields that declared this path re-run their\n // own validators under the same gate. No-op when nobody declared it.\n revalidateDependentsOnChange(form, path, mode);\n}\n\n/**\n * Write a bound field's user change by path: the write plus the\n * mode/reValidateMode-gated validation pipeline — what a bound field's\n * onChange does when the user types. Reads the effective mode from the\n * field-mode registry (the latest mount's override governs), so a plain\n * write happens when no field is registered at `path`. Framework\n * adapters (React's `useField`, a Solid binding) forward their field\n * change events here.\n *\n * @param form\n * @param path\n * @param value\n */\nexport function userChangeByPath(form: Form, path: Path, value: any): void {\n setValueByPath(form, path, value);\n const entry = fieldModes.get(form)?.get(path.key);\n if (entry) runUserChangeGate(form, path, entry.mode ?? form.mode);\n}\n\n/**\n * A bound field's blur: mark the path touched, then kick its validator\n * under the blur-side gate (`mode` `'onBlur'`/`'onTouched'`/`'all'`, or\n * `reValidateMode: 'onBlur'` while the field carries a live error). The\n * touched marking is unconditional — a field counts as touched on blur\n * regardless of mode. Framework adapters forward field blur events here.\n *\n * @param form\n * @param path\n */\nexport function userBlur(form: Form, path: Path): void {\n setTouchedByPath(form, path);\n const entry = fieldModes.get(form)?.get(path.key);\n if (!entry) return;\n const mode = entry.mode ?? form.mode;\n if (\n mode === 'onBlur' ||\n mode === 'onTouched' ||\n mode === 'all' ||\n (getFieldErrorsByPath(form, path).length > 0 &&\n form.reValidateMode === 'onBlur')\n )\n form.validators.get(path.key)?.();\n}\n\n/**\n * Get field error\n * @param form\n * @param name\n * @return FieldError object or undefined\n */\n","import {emit} from '../emitter';\nimport type {FieldErrorEntry, Form} from '../form';\nimport {getErrors} from './errors';\nimport {getValues} from './values';\nimport {validate} from './validate';\n\nexport function setIsSubmitting(form: Form, value: boolean): void {\n form.isSubmitting = value;\n emit(form.emitter, 'submitting');\n}\n\nexport function incrementSubmitCount(form: Form): void {\n form.submitCount++;\n emit(form.emitter, 'submitCount');\n}\n\nexport function setSubmitSuccessful(form: Form, value: boolean): void {\n form.isSubmitSuccessful = value;\n emit(form.emitter, 'submitSuccessful');\n}\n\n/**\n * Set the form-level disabled flag and emit a payload-less 'disabled'\n * event — subscribed fields (useField and the components built on it)\n * re-render with the merged disabled state: form flag || their own\n * `disabled` option.\n * @param form\n * @param value\n */\nexport function setDisabled(form: Form, value: boolean): void {\n form.disabled = value;\n emit(form.emitter, 'disabled');\n}\n\n/**\n * Set the form's user-owned metadata slot (Formik's `status` role): the\n * payload-less 'status' event wakes {@link useStatus} and any imperative\n * `subscribe(form, {event: 'status'})` listeners. Nothing else reads or\n * interprets the value — server session flags, step state, non-field\n * errors of any shape are all fair game. Starts `undefined`.\n * @param form\n * @param value\n */\nexport function setStatus(form: Form, value: any): void {\n form.status = value;\n emit(form.emitter, 'status');\n}\n\n/** Structural slice of a <form>-like element: an elements collection whose\n * controls expose the constraint-validation members we read. Matches the\n * DOM HTMLFormElement shape without coupling the core to DOM types. */\ntype NativeFormElement = {\n elements: ArrayLike<{\n name: string;\n checkValidity: () => boolean;\n validationMessage: string;\n }>;\n};\n\n/**\n * Converts a control's DOM name to the user-visible dotted path. Field\n * components render the path key (JSON.stringify'd segments, '[\"a\",\"0\"]')\n * as the name attribute, so JSON keys are parsed back and joined with\n * dots; any other name value is returned as-is.\n */\nfunction nameToPath(name: string): string {\n if (name.startsWith('[')) {\n try {\n const segments = JSON.parse(name);\n if (Array.isArray(segments)) return segments.join('.');\n } catch {\n // Not a JSON path key — fall through and use the raw name.\n }\n }\n return name;\n}\n\n/**\n * Collects the constraints failing native validation on a <form> as\n * {@link FieldErrorEntry} entries, in DOM order.\n *\n * Design note: native errors are deliberately NOT written into the form's\n * errors Map. That Map tracks custom validator state, while native\n * validity is transient DOM state owned by the browser (surfaced through\n * reportValidity); onInvalidSubmit receives this snapshot directly.\n */\nfunction getNativeErrors(formEl: NativeFormElement): FieldErrorEntry[] {\n const errors: FieldErrorEntry[] = [];\n const {elements} = formEl;\n for (let i = 0; i < elements.length; i++) {\n const el = elements[i];\n if (\n el.name &&\n typeof el.checkValidity === 'function' &&\n !el.checkValidity()\n ) {\n errors.push({\n path: nameToPath(el.name),\n type: 'native',\n message: el.validationMessage\n });\n }\n }\n return errors;\n}\n\n/** Submit callbacks for {@link handleSubmit}. All optional — a missing\n * callback is simply skipped, matching the <Form> component semantics. */\nexport type HandleSubmitOptions<T extends Record<string, any> = any> = {\n /** Called after validation passes, before onValidSubmit. */\n onSubmit?: (values: T, e?: any) => void | Promise<void>;\n /** Called after validation passes, following a successful onSubmit. */\n onValidSubmit?: (values: T, e?: any) => void | Promise<void>;\n /**\n * Called when validation fails.\n * @param errors array of {path, type, message} entries in insertion\n * order; path is the dotted field path ('a.b', 'list.0'), type is\n * the error kind ('custom' for plain string errors, 'native' for\n * failed DOM constraint validation), message is the display text\n * @param values current form values\n */\n onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;\n /**\n * Called after validation passes and the submit callbacks ran, with the\n * final (schema-coerced) values — the slot <Form>'s `action` prop uses\n * to dispatch React 19 server actions with FormData. Runs inside the\n * same isSubmitting window and is awaited like onSubmit/onValidSubmit.\n */\n onAction?: (values: T, e?: any) => void | Promise<void>;\n /**\n * Focus the first error field after a failed submit. Defaults to true —\n * only an explicit `false` disables it. When custom validation fails,\n * a 'focusError' event carrying the first error's path key is emitted\n * on the form (bound fields such as <Field> subscribe and focus their\n * input); when native constraint validation fails, the submitted\n * form's first ':invalid' control is focused directly.\n */\n shouldFocusError?: boolean;\n};\n\n/**\n * Create an async submit handler for `form` — the headless counterpart of\n * the <Form> component's onSubmit wiring.\n *\n * Behavior mirrors <Form> exactly: preventDefault when present, then the\n * submit state machine (isSubmitting/submitCount/isSubmitSuccessful) runs\n * around native constraint validation (via `e.currentTarget.checkValidity`,\n * skipped when the target has no checkValidity — e.g. React Native or\n * toolbar-button submits) and custom validators. Failed validation fires\n * onInvalidSubmit with the flattened error entries; a passing submit runs\n * onSubmit then onValidSubmit. Errors thrown by either are swallowed into\n * isSubmitSuccessful=false rather than rejecting the returned promise.\n * Failed validation also focuses the offending field (see\n * {@link HandleSubmitOptions.shouldFocusError}).\n *\n * @param form form instance\n * @param options submit callbacks\n * @return async event handler, callable without an event object\n */\nexport function handleSubmit<T extends Record<string, any> = any>(\n form: Form<T>,\n options?: HandleSubmitOptions<T>\n): (e?: {preventDefault?: () => void; currentTarget?: any}) => Promise<void> {\n const {\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n onAction,\n shouldFocusError = true\n } = options ?? {};\n return async e => {\n if (e && typeof e.preventDefault === 'function') {\n e.preventDefault();\n }\n const formEl = e?.currentTarget;\n // Land the submitted flag before the isSubmitting flip: the single\n // 'submitting' emit setIsSubmitting fires carries both state changes\n // to FormState subscribers.\n form.isSubmitted = true;\n setIsSubmitting(form, true);\n incrementSubmitCount(form);\n const values = getValues(form);\n\n if (\n formEl &&\n typeof formEl.checkValidity === 'function' &&\n formEl.checkValidity() === false\n ) {\n formEl.reportValidity();\n // Focus the first natively-invalid control directly off the DOM;\n // native failures never enter the errors Map (see below).\n if (shouldFocusError && typeof formEl.querySelector === 'function') {\n const invalid = formEl.querySelector(':invalid') as HTMLElement | null;\n if (invalid && typeof invalid.focus === 'function') invalid.focus();\n }\n setIsSubmitting(form, false);\n setSubmitSuccessful(form, false);\n // Native constraint failures are read from the DOM (not the errors\n // Map, which only holds custom validation state — see getNativeErrors).\n if (onInvalidSubmit) onInvalidSubmit(getNativeErrors(formEl), values);\n return;\n }\n\n const error = await validate(form);\n\n if (error) {\n setIsSubmitting(form, false);\n setSubmitSuccessful(form, false);\n // Notify bound fields (e.g. <Field>) so the first errored one can\n // focus its input; the payload is the errors Map's first key.\n if (shouldFocusError) {\n const firstKey = form.errors.keys().next().value;\n if (firstKey !== undefined) emit(form.emitter, 'focusError', firstKey);\n }\n if (onInvalidSubmit) onInvalidSubmit(getErrors(form), values);\n return;\n }\n\n try {\n // Re-read after validation: a schema validator's parsed output\n // (ValidationOutcome.values) landed in parsedValues during\n // validate(), and the submit callbacks must see the coerced /\n // transformed values, not the raw pre-validation snapshot.\n const submitted = getValues(form);\n if (onSubmit) await onSubmit(submitted, e);\n if (onValidSubmit) await onValidSubmit(submitted, e);\n if (onAction) await onAction(submitted, e);\n setSubmitSuccessful(form, true);\n } catch {\n setSubmitSuccessful(form, false);\n } finally {\n setIsSubmitting(form, false);\n }\n };\n}\n\n/** Options accepted by {@link setFocus}. All flags default to `false`. */\n","import {create as createEmitter, emit, setMaxListeners} from './emitter';\nimport type {EventEmitter} from './emitter';\nimport createPath from './path';\nimport type {Name, Path} from './path';\nimport type {FieldPath} from './types';\nimport {isPromise} from './util';\nimport {setInitialValues} from './core/values';\nimport type {SetFocusOptions} from './core/focus';\nimport type {VALIDATION_OUTCOME} from './core/errors';\n\n// The implementation is split by concern under ./core (values, errors,\n// touched, dirty, validate, change, submit, focus; module-private shared\n// state lives in ./core/internals, which is deliberately not re-exported).\n// This file keeps the public types and the create factory, and re-exports\n// every public function — the single import surface the rest of the\n// package (hooks, components, server, persist, resolvers) consumes.\nexport type {Name};\nexport type {FieldPath, PathValue} from './types';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/** A field error: `type` identifies the error kind ('custom' for plain\n * string errors), `message` is the display text. */\nexport type FieldError = {type: string; message: string};\n\n/** A flattened entry from {@link getErrors}. */\nexport type FieldErrorEntry = {path: string; type: string; message: string};\n\n/** When a field is validated:\n * - `'onSubmit'` (default): only on submit\n * - `'onBlur'`: when the field loses focus\n * - `'onChange'`: on every change\n * - `'onTouched'`: on first blur, then on every change\n * - `'all'`: on both change and blur\n */\nexport type ValidationMode =\n 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all';\n\n/** When a field is re-validated after it already has an error:\n * - `'onChange'` (default): on every change\n * - `'onBlur'`: when the field loses focus\n * - `'onSubmit'`: only on submit (no live re-validation)\n */\nexport type ReValidateMode = 'onChange' | 'onBlur' | 'onSubmit';\n\n/** Structured form-level validate result: `errors` uses the same nested\n * shape a plain error record uses, `values` is the schema's parsed output\n * (coerce/transform results included). Either side may be omitted.\n *\n * The brand constant itself lives in the errors module (the leaf module of\n * the core dependency graph — every consumer imports it from there) and is\n * re-exported below with `export *`. */\nexport type ValidationOutcome<T> = {\n [VALIDATION_OUTCOME]: true;\n errors?: Record<string, any>;\n values?: T;\n};\n\n/** What a form-level validate function may return: a plain nested error\n * record (flattened into field errors — the long-standing shape), or a\n * branded {@link ValidationOutcome} whose `values` become the form's\n * parsedValues baseline. */\nexport type ValidateResult<T> =\n | Record<string, any>\n | ValidationOutcome<T>\n | Promise<Record<string, any> | ValidationOutcome<T>>;\n\n/** Context passed to a form-level `validate` function's second argument.\n * `signal` aborts as soon as the round is superseded — a newer round\n * started (which only happens under a positive `validateDebounce`, where\n * kicks merge into windows) — so async validators can cancel their\n * underlying work instead of racing a stale result home. Stale results\n * are dropped independently by the round gate, so validators that ignore\n * the signal stay correct too; the same contract field-level validators\n * get through their own `meta`. */\nexport type FormValidateMeta<T extends Record<string, any> = any> = {\n form: Form<T>;\n signal: AbortSignal;\n};\n\n/** Form-level validator: receives all values (plus {@link\n * FormValidateMeta} as an optional second argument) and returns a\n * {@link ValidateResult} — sync or async — or `undefined`/nothing when\n * valid (the runtime skips falsy results, so implicit-return callbacks\n * type-check). */\nexport type FormValidateFn<T extends Record<string, any> = any> = (\n values: T,\n meta: FormValidateMeta<T>\n) => ValidateResult<T> | undefined;\n\n/**\n * The emitter event table for {@link Form.emitter}: each event's payload\n * tuple. Path-carrying events declare an optional single `Path` payload —\n * emit sites send it for single-field mutations and omit it for bulk\n * payload-less broadcasts (reset, setInitialValues, clear-all), both of\n * which subscribers handle. `focusError` carries the target's path key\n * plus optional {@link SetFocusOptions}.\n */\nexport type FormEvents =\n | ['change', [path?: Path]]\n | ['errors', [path?: Path]]\n | ['touched', [path?: Path]]\n | ['validating', [path?: Path]]\n | ['submitting', []]\n | ['submitCount', []]\n | ['submitSuccessful', []]\n | ['reset', []]\n | ['disabled', []]\n | ['status', []]\n | ['loading', []]\n | ['focusError', [key: string, options?: SetFocusOptions]];\n\nexport type Form<T extends Record<string, any> = any> = {\n emitter: EventEmitter<FormEvents>;\n mode: ValidationMode;\n reValidateMode: ReValidateMode;\n initialValues: T;\n values: Map<string, any>;\n /** Tombstones of unregistered field paths (JSON path keys): reading or\n * merging values must not fall back to initialValues for these paths. */\n deleted: Set<string>;\n /** Every error registered for a field, as a non-empty array (the\n * write-side {@link setErrorByPath} normalizes to this invariant, so\n * readers never need to guard against an empty list). Readers wanting\n * the display error take the first entry ({@link getError}); readers\n * wanting all of them use {@link getFieldErrors}. */\n errors: Map<string, FieldError[]>;\n touched: Set<string>;\n /** Per-field validation kicks, registered by {@link\n * registerValidatorByPath} (`useValidate` is the React-side\n * registration): each is the field's debounce/lock-aware kick —\n * invoking it validates the field's current value. `trigger` /\n * `ensureValidate` run every entry; the user-change gate ({@link\n * userChangeByPath}) runs the entry at the changed path. */\n validators: Map<string, () => void>;\n validating: Set<string>;\n /** Parsed values from the last successful schema validation: the\n * schema's complete output tree (coerced/transformed values included).\n * Sits between initialValues and the values Map in {@link getValues}\n * until `reset`/`setInitialValues` clears it. Never affects dirty\n * state — that compares live edits against initialValues only. */\n parsedValues: T | undefined;\n /** Form-level validator, seeded from {@link Options.validate}. May\n * receive a second {@link FormValidateMeta} argument. */\n validate?: FormValidateFn<T>;\n /** Delay in milliseconds before the form-level `validate` runs; seeded\n * from {@link Options.validateDebounce} and fixed at create time. */\n validateDebounce?: number;\n /** Path keys (JSON-stringified segments) of the fields whose user\n * changes re-run the form-level `validate`; normalized from {@link\n * Options.validateDeps} at create time and fixed thereafter. */\n validateDeps?: ReadonlySet<string>;\n isSubmitting: boolean;\n /** Whether a submit has been attempted — set by `handleSubmit` on every\n * attempt (validation outcome aside), cleared by `reset`.\n * `useFormState().isSubmitted` reads it (react-hook-form's\n * `formState.isSubmitted` semantics). */\n isSubmitted: boolean;\n submitCount: number;\n isSubmitSuccessful: boolean | undefined;\n /** True while an async {@link Options.initialValues} source (a Promise,\n * or a thunk returning one) is still pending — the form starts empty\n * and the resolved values become the baseline via setInitialValues when\n * it lands. Flips through the payload-less 'loading' event\n * (`useIsLoading` / `useFormState().isLoading`). */\n isLoading: boolean;\n /** Form-level default for a bound field's unmount behavior, seeded from\n * {@link Options.shouldUnregister}: `true` (the default) tombstones an\n * unmounted field, `false` keeps its value (react-hook-form's\n * `shouldUnregister` semantics). A field's own `shouldUnregister` option\n * overrides this. */\n shouldUnregister?: boolean;\n /** Form-level disabled flag, OR-ed into every bound field's `disabled`\n * (form flag || the field's own option). Seeded from\n * {@link Options}.disabled at create time and toggled at runtime with\n * {@link setDisabled}, which emits a payload-less 'disabled' event so\n * subscribed fields re-render. */\n disabled: boolean;\n /** Form-level default for mount validation, seeded from\n * {@link Options.validateOnMount}: `true` makes every mounted field\n * with a validator kick once after mount (deferred until an async\n * {@link Options.initialValues} source lands), and makes `useForm` run\n * the form-level `validate` once. A field's own `validateOnMount`\n * option overrides this flag in either direction. */\n validateOnMount: boolean;\n /** Form-level default for {@link UseValidateOptions.asyncAlways}:\n * whether a field's debounced validator still runs when its `required`\n * gate failed. A field's own `asyncAlways` option overrides this flag\n * in either direction. Seeded from {@link Options.asyncAlways}. */\n asyncAlways: boolean;\n /**\n * User-owned metadata slot for non-field state — session flags, server\n * backfill that belongs to no field, step indices (Formik's `status`\n * role). Written with {@link setStatus}, which emits the payload-less\n * 'status' event; read directly or reactively through {@link useStatus}.\n * Starts `undefined`.\n */\n status: any;\n};\n\nexport type Options<T extends Record<string, any> = any> = {\n /**\n * The values baseline. Sync objects seed immediately (SSR renders\n * them). Async sources — a Promise, or a thunk returning a value or\n * Promise (react-hook-form's async `defaultValues` shape) — start the\n * form empty with `isLoading: true` and land the resolved values as\n * the baseline via setInitialValues once they resolve: value\n * subscribers re-sync, dirty/touched state starts clean, and a later\n * `reset()` returns to the resolved baseline. A rejected source flips\n * isLoading back to false, keeps the form empty, and logs the error in\n * DEV — attach a `.catch` on the source itself to handle it. The thunk\n * runs at create time: keep its identity stable (module scope or\n * useMemo) when passing it inline, and note StrictMode double-invokes\n * it in development, like every render-phase call.\n */\n initialValues?: T | Promise<T> | (() => T | Promise<T>);\n /** When fields are validated. Defaults to `'onSubmit'`. See\n * {@link ValidationMode}. */\n mode?: ValidationMode;\n /** When a field is re-validated after it already has an error — it only\n * takes effect once the field has an error. Defaults to `'onChange'`. See\n * {@link ReValidateMode}. */\n reValidateMode?: ReValidateMode;\n /**\n * Form-level validator. Returns a record of errors keyed by field path;\n * nested objects are flattened ('a.b' style) and array values contribute\n * every non-empty string they hold as separate errors (zod `flatten()`\n * formErrors style). Schema adapters instead return a branded\n * {@link ValidationOutcome}: `errors` flattens the same way, `values`\n * (the schema's parsed output) becomes the form's parsedValues baseline\n * that {@link getValues} layers over initialValues.\n */\n validate?: FormValidateFn<T>;\n /**\n * Milliseconds to debounce the form-level `validate`: kicks from\n * `trigger`/`ensureValidate`/submit inside the window merge into one\n * run, and while the timer is pending the form counts as validating,\n * so `trigger` and submit wait the window out — the same contract the\n * per-field `validateDebounce` gives field validators. The merged run\n * reads the values current when its timer fires. Defaults to `0`\n * (validate runs immediately, exactly as before this option existed).\n */\n validateDebounce?: number;\n /** Fields whose user changes re-run the form-level `validate` — the\n * cross-field dependency list (password-confirm mismatch and friends).\n * Each entry is a field path ('password', 'user.email', 'items.0.qty');\n * a user change to a listed field re-runs the form-level `validate`\n * under the same mode/`reValidateMode` gating the field's own\n * validator gets. Omit it and the form-level `validate` only runs on\n * `trigger`/submit, exactly as before this option existed.\n *\n * Opting in also changes what a re-run may clear: each round first\n * drops the errors the previous round wrote (paths it flattened onto),\n * so a dep change that fixes the cross-field error makes it disappear.\n * Errors the round never wrote — field validators', `setServerErrors`,\n * manual `setError` — are never touched. TanStack Form's counterpart is\n * `onChangeListenTo` (v1) / validator `triggers` (v2 alpha). */\n validateDeps?: FieldPath<T>[];\n /**\n * Form-level default for a bound field's unmount behavior. `true` (the\n * default) tombstones an unmounted field — it drops out of\n * `getValues()` instead of reviving its initial value (this library's\n * historical default); `false` keeps the value, matching\n * react-hook-form's `shouldUnregister`. A field's own\n * `useField({shouldUnregister})` option overrides the form-level flag\n * in either direction.\n */\n shouldUnregister?: boolean;\n /** Start the form with every bound field disabled — the flag bound\n * fields OR with their own `disabled` option (a field cannot opt out\n * of a disabled form). Toggle later with {@link setDisabled}.\n * Defaults to `false`. */\n disabled?: boolean;\n /**\n * Form-level default for field validation's `asyncAlways`: when true,\n * a field whose `required` gate failed still runs its debounced\n * validator (the gate's errors land immediately, the validator's own\n * result lands alongside them per-source). TanStack Form's\n * `asyncAlways` counterpart. A field's own\n * `useField({asyncAlways})` option overrides the form-level flag in\n * either direction. Defaults to `false`.\n */\n asyncAlways?: boolean;\n /**\n * Validate on mount: `true` makes every mounted field with a validator\n * (declarative `rules` or a `validate` callback) run it once after\n * mount, instead of waiting for the first submit/change — errors show\n * immediately for an untouched form (Formik's `validateOnMount` /\n * TanStack Form's per-field `validateOnMount`). The form-level\n * `validate` also runs once after mount. Mount kicks are deferred\n * while an async `initialValues` source is still pending: validating\n * the empty shell would land spurious required errors, so the kicks\n * fire after the resolved baseline lands instead. A field's own\n * `useField({validateOnMount})` option overrides the form-level flag\n * in either direction. Defaults to `false`.\n */\n validateOnMount?: boolean;\n};\n\n/**\n * Create form instance\n * @param options\n * @return form instance\n */\nexport default function create<T extends Record<string, any> = any>(\n options?: Options<T>\n): Form<T> {\n const emitter = createEmitter<FormEvents>();\n // A form legitimately accumulates one listener per mounted field per\n // event (useField subscribes change/errors/disabled/focusError…), so\n // the emitter's default max-listener warning would fire in DEV for any\n // form over ~10 fields. Field subscriptions are removed on unmount —\n // there is nothing to leak — so the warning would only be noise: raise\n // the cap to unlimited for form emitters.\n setMaxListeners(emitter, 0);\n // Async initialValues: a thunk is invoked here (create-time, like every\n // other option resolution); a promise-typed result starts the loading\n // cycle below instead of seeding.\n let source: any = options?.initialValues ?? {};\n if (typeof source === 'function') source = (source as () => unknown)();\n const form: Form<T> = {\n emitter,\n ...options,\n mode: options?.mode ?? 'onSubmit',\n reValidateMode: options?.reValidateMode ?? 'onChange',\n disabled: options?.disabled ?? false,\n validateOnMount: options?.validateOnMount ?? false,\n asyncAlways: options?.asyncAlways ?? false,\n validateDeps: options?.validateDeps\n ? new Set(options.validateDeps.map(dep => createPath(dep).key))\n : undefined,\n initialValues: {} as T,\n values: new Map(),\n deleted: new Set(),\n errors: new Map(),\n touched: new Set(),\n validators: new Map(),\n validating: new Set(),\n parsedValues: undefined,\n isSubmitting: false,\n isSubmitted: false,\n submitCount: 0,\n isSubmitSuccessful: undefined,\n isLoading: false,\n status: undefined\n };\n if (isPromise(source)) {\n // The form starts empty; when the source resolves, its values become\n // the baseline through setInitialValues (payload-less 'change', so\n // every value subscriber re-syncs). The loading flag flips through\n // the 'loading' event before and after — no subscriber exists during\n // the first render, so the synchronous first emit is a safe no-op.\n form.isLoading = true;\n emit(emitter, 'loading');\n Promise.resolve(source).then(\n resolved => {\n // Values land first, then the flag flips and 'loading' fires —\n // subscribers waking on the event read the resolved baseline, not\n // the empty shell (mount-validation deferral among them).\n setInitialValues(form, resolved ?? {});\n form.isLoading = false;\n emit(emitter, 'loading');\n },\n error => {\n form.isLoading = false;\n emit(emitter, 'loading');\n // The caller's own catch on the source sees the rejection;\n // rethrowing here would only duplicate it as an unhandled\n // promise rejection. Surface it in DEV instead.\n if (__DEV__) {\n // eslint-disable-next-line no-console -- dev-only diagnostics\n console.error('react-f0rm: async initialValues rejected', error);\n }\n }\n );\n } else {\n form.initialValues = source as T;\n }\n return form;\n}\n\nexport * from './core/values';\nexport * from './core/errors';\nexport * from './core/touched';\nexport * from './core/dirty';\nexport * from './core/validate';\nexport * from './core/change';\nexport * from './core/submit';\nexport * from './core/focus';\n","import type {FieldError} from './form';\nimport type {SyncValidator} from './hooks/validate';\n\n/** Type tag of a failed rule, as stored on the resulting FieldError. */\nexport type RuleType =\n 'required' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern';\n\n/**\n * Declarative field rules — a subset of react-hook-form's `register` rules.\n *\n * Failed rules land in the form's error state as FieldErrors (`type` is the\n * rule name) instead of only surfacing through the browser's validity\n * bubble, so any design system can render the messages uniformly.\n */\nexport type FieldRules = {\n /**\n * Fails on empty values: `''`, `undefined`, `null` or an empty array\n * (`0` and `false` count as filled) — react-hook-form's `required`\n * semantics. A string is the error message; `true` uses the default.\n * When it fails, the remaining rules are skipped — an empty value\n * reports only its required error.\n */\n required?: string | true;\n /** Fails when `Number(value)` is below this bound; `NaN` values skip. */\n min?: number;\n /** Fails when `Number(value)` is above this bound; `NaN` values skip. */\n max?: number;\n /** Fails when a string value is shorter than this, or an array has\n * fewer entries; other values skip. */\n minLength?: number;\n /** Fails when a string value is longer than this, or an array has more\n * entries; other values skip. */\n maxLength?: number;\n /** Fails when the value does not match `pattern.value`. */\n pattern?: {value: RegExp; message: string};\n /**\n * Custom rule callbacks — react-hook-form's `register({validate})`\n * shape: one function, or a record of named functions. Each runs after\n * the declarative checks, and only when they passed (`required` failing\n * short-circuits the rest, RHF's first-error semantics). A returned\n * error keeps its message; its `type` becomes the record key\n * (`'validate'` for the single-function form) so consumers can switch\n * on `error.type`. Sync-only — async checks belong in the field's\n * `validate` option.\n */\n validate?: SyncValidator | Record<string, SyncValidator>;\n /**\n * Overrides the message per rule type — `min`, `max`, `minLength`,\n * `maxLength` defaults and pattern's inline `message` alike — e.g. for\n * centralizing or localizing messages.\n */\n messages?: Partial<Record<Exclude<RuleType, 'required'>, string>>;\n};\n\n/** Default English messages, aligned with RHF's default-message style. */\nfunction defaultMessage(type: RuleType, bound?: number): string {\n switch (type) {\n case 'required':\n return 'This field is required';\n case 'min':\n return `Must be at least ${bound}`;\n case 'max':\n return `Must be at most ${bound}`;\n case 'minLength':\n return `Must be at least ${bound} characters`;\n case 'maxLength':\n return `Must be at most ${bound} characters`;\n case 'pattern':\n return 'Invalid format';\n default:\n return 'Invalid value';\n }\n}\n\n/**\n * Compile declarative {@link FieldRules} into a {@link SyncValidator}.\n *\n * `required` is checked first and, when it fails on an empty value,\n * short-circuits the rest. Every other failing rule is collected into one\n * FieldError[] in declaration order (min, max, minLength, maxLength,\n * pattern); a fully passing value yields undefined. Messages resolve to\n * the rule's own string (required), `rules.messages`, or the default.\n *\n * @param rules declarative constraints\n * @return synchronous validator producing FieldError[] | undefined\n */\nexport function rulesToValidator(rules: FieldRules): SyncValidator {\n return (value, meta) => {\n if (rules.required) {\n if (\n value === '' ||\n value === undefined ||\n value === null ||\n (Array.isArray(value) && value.length === 0)\n ) {\n return [\n {\n type: 'required',\n message:\n typeof rules.required === 'string'\n ? rules.required\n : defaultMessage('required')\n }\n ];\n }\n }\n const errors: FieldError[] = [];\n const message = (type: Exclude<RuleType, 'required'>, bound: number) =>\n rules.messages?.[type] ?? defaultMessage(type, bound);\n if (rules.min !== undefined) {\n const n = Number(value);\n if (!Number.isNaN(n) && n < rules.min) {\n errors.push({type: 'min', message: message('min', rules.min)});\n }\n }\n if (rules.max !== undefined) {\n const n = Number(value);\n if (!Number.isNaN(n) && n > rules.max) {\n errors.push({type: 'max', message: message('max', rules.max)});\n }\n }\n const isSized = typeof value === 'string' || Array.isArray(value);\n if (\n rules.minLength !== undefined &&\n isSized &&\n value.length < rules.minLength\n ) {\n errors.push({\n type: 'minLength',\n message: message('minLength', rules.minLength)\n });\n }\n if (\n rules.maxLength !== undefined &&\n isSized &&\n value.length > rules.maxLength\n ) {\n errors.push({\n type: 'maxLength',\n message: message('maxLength', rules.maxLength)\n });\n }\n if (rules.pattern && !rules.pattern.value.test(value)) {\n errors.push({\n type: 'pattern',\n // pattern.message is type-required but JS consumers may omit it.\n message:\n rules.messages?.pattern ??\n rules.pattern.message ??\n defaultMessage('pattern')\n });\n }\n if (rules.validate !== undefined) {\n const fns =\n typeof rules.validate === 'function'\n ? {validate: rules.validate}\n : rules.validate;\n for (const [type, fn] of Object.entries(fns)) {\n const result = fn(value, meta);\n if (result === undefined) continue;\n // Each custom rule owns its `type`: the record key (or\n // 'validate' for the single-function form), so consumers can\n // switch on error.type like with every declarative rule.\n for (const entry of Array.isArray(result) ? result : [result]) {\n errors.push(\n typeof entry === 'string'\n ? {type, message: entry}\n : {...entry, type}\n );\n }\n }\n }\n return errors.length ? errors : undefined;\n };\n}\n\n/**\n * Map declarative {@link FieldRules} onto native HTML constraint\n * attributes — the subset the platform exposes: `required`, `min`,\n * `max`, `minLength`, `maxLength`, `pattern`. Rendered onto a bound\n * control they give browsers and assistive tech the native hints\n * (`:invalid`/`:user-invalid` styling, screen-reader announcements,\n * mobile input modes) while the store-based pipeline stays the source of\n * truth for messages: `rulesToValidator` still lands errors in the form\n * state and `renderError`/`aria-invalid` keep working. `validate`\n * callbacks have no native counterpart and are skipped. Native `min`/\n * `max` only constrain numeric/date inputs; the store checks apply\n * regardless of input type — render hints, not the validation gate.\n */\nexport function rulesToConstraintAttrs(rules: FieldRules): Record<string, any> {\n const attrs: Record<string, any> = {};\n if (rules.required) attrs.required = true;\n if (rules.min !== undefined) attrs.min = rules.min;\n if (rules.max !== undefined) attrs.max = rules.max;\n if (rules.minLength !== undefined) attrs.minLength = rules.minLength;\n if (rules.maxLength !== undefined) attrs.maxLength = rules.maxLength;\n if (rules.pattern) attrs.pattern = rules.pattern.value.source;\n return attrs;\n}\n","import {on} from './emitter';\nimport type {EventEmitter} from './emitter';\nimport createPath from './path';\nimport type {Name, Path} from './path';\nimport type {Form, FormEvents} from './form';\n\n/** Subscription granularity for {@link onPathEvent}.\n * - `'leaf'`: the subscriber reads exactly one key ({@link\n * useValueByPath}); only writes at that key or above it can change what\n * it reads.\n * - `'branch'`: the subscriber aggregates a whole subtree below a key\n * ({@link useFieldArray}); descendant writes matter too. */\nexport type WatchScope = 'leaf' | 'branch';\n\n/**\n * Is `key` a strict descendant of `ancestorKey`?\n *\n * Keys are JSON.stringify'd segment arrays ('[\"a\",\"b\"]'), so a descendant\n * key is the ancestor key minus its closing ']' followed by a ','\n * ('[\"a\",\"b\",'). The ',' separator is mandatory: a plain prefix match\n * would let the sibling '[\"tagsX\"]' pass as a descendant of '[\"tags\"]'.\n */\nfunction isDescendant(key: string, ancestorKey: string): boolean {\n return key.startsWith(`${ancestorKey.slice(0, -1)},`);\n}\n\n/**\n * Subscribe to `event`, invoking `cb` only when the emitted path is\n * relevant to `path`.\n *\n * Payload-less broadcasts (reset, setInitialValues) always invoke `cb` --\n * they are global syncs and the correctness fallback. (removeFieldByPath\n * emits with its path: its mutations are bounded to that key, so the path\n * matching below is exact.) When the emit carries a path P:\n * - `'leaf'`: P.key equals `path.key` or is one of its ancestors -- a leaf\n * read falls back to ancestor values (getValueByPath), so ancestor\n * writes must invalidate, while sibling and descendant writes cannot\n * change what the leaf reads.\n * - `'branch'`: `'leaf'` semantics plus P.key being a descendant of\n * `path.key` -- changed descendants re-aggregate the subtree.\n *\n * @param emitter emitter to subscribe to\n * @param event event name\n * @param path the watched path\n * @param scope which writes around `path` are relevant\n * @param cb listener, invoked with no arguments\n * @return unsubscribe function\n */\nexport function onPathEvent(\n emitter: EventEmitter<FormEvents>,\n event: SubscribeEvent,\n path: Path,\n scope: WatchScope,\n cb: () => void\n): () => void {\n const {key} = path;\n return on(emitter, event, (changed?: Path) => {\n if (\n changed === undefined ||\n changed.key === key ||\n isDescendant(key, changed.key) ||\n (scope === 'branch' && isDescendant(changed.key, key))\n ) {\n cb();\n }\n });\n}\n\n/**\n * Subscribe to `event`, invoking `cb` only when the emitted path's key is\n * exactly `key` (or the emit carries no payload -- a global sync).\n *\n * For state stored per exact key (errors, touched) no ancestor or\n * descendant matching is wanted: another field's key must not wake this\n * subscriber.\n *\n * @param emitter emitter to subscribe to\n * @param event event name\n * @param key exact path key to match\n * @param cb listener, invoked with no arguments\n * @return unsubscribe function\n */\nexport function onKeyEvent(\n emitter: EventEmitter<FormEvents>,\n event: SubscribeEvent,\n key: string,\n cb: () => void\n): () => void {\n return on(emitter, event, (changed?: Path) => {\n if (changed === undefined || changed.key === key) cb();\n });\n}\n\n/** Events {@link subscribe} can watch. `'errors'` and `'touched'` are\n * stored per exact key, so they match exact keys ({@link onKeyEvent});\n * `'change'`, `'validating'`, `'submitting'`, `'submitCount'`,\n * `'disabled'`, `'status'` and `'submitSuccessful'` go through\n * {@link onPathEvent}. `'validating'` carries paths (one per async\n * validator round) and matches by path exactly like `'change'`;\n * `'submitting'`, `'submitCount'`, `'disabled'`, `'status'` and\n * `'submitSuccessful'` are payload-less broadcasts, so `name` never\n * narrows them — every subscriber hears every emission. */\nexport type SubscribeEvent =\n | 'change'\n | 'errors'\n | 'touched'\n | 'validating'\n | 'submitting'\n | 'submitCount'\n | 'submitSuccessful'\n | 'disabled'\n | 'status'\n | 'loading';\n\n/** Options accepted by {@link subscribe}. */\nexport type SubscribeOptions = {\n /** Path (or list of paths) to watch. Omit to receive every emission of\n * `event`, payload-less broadcasts included. A single segments path\n * (`['tags', 0]`) and a list of names (`['tags', 'user.name']`) are told\n * apart by the same rule `trigger` uses: only a segments path can hold\n * a number. */\n name?: Name | Name[];\n /** Event to watch. Defaults to `'change'`. */\n event?: SubscribeEvent;\n /** Which writes around `name` are relevant — `'leaf'` or `'branch'`.\n * Only meaningful for the path-carrying events `'change'` and\n * `'validating'`: `'errors'`/`'touched'` match exact keys and\n * `'submitting'`/`'submitCount'`/`'disabled'`/`'status'`/\n * `'submitSuccessful'` are payload-less. Defaults to `'branch'` — the\n * intuitive linkage semantics, where subscribing to `'tags'` means the\n * whole branch. */\n scope?: WatchScope;\n /** Invoked with no arguments after each matching emission. Read fresh\n * state through the `get*` readers inside it. */\n callback: () => void;\n};\n\n/** Is `name` a list of names rather than one segments path? Numbers only\n * occur inside a segments path (`['a', 0]`), never as standalone names —\n * the same disambiguation `trigger` applies to its name argument. */\nfunction isNameList(name: Name | Name[]): name is Name[] {\n return (\n Array.isArray(name) &&\n (name as (number | unknown)[]).every(part => typeof part !== 'number')\n );\n}\n\n/**\n * Subscribe to form events imperatively — the non-render counterpart of\n * the `use*` hooks: linkages and side effects (province changed → clear\n * city, autosave, analytics) run without mounting a watching component.\n *\n * Without `name`, `callback` fires on every `event` emission, payload-less\n * broadcasts (reset, setInitialValues) included. With `name`, matching\n * follows the event's shape: `'errors'`/`'touched'` match the exact key\n * ({@link onKeyEvent}) — another field's error never wakes this\n * subscriber — while `'change'`/`'validating'`/`'submitting'`/\n * `'submitCount'`/`'disabled'`/`'submitSuccessful'` go through\n * {@link onPathEvent}, so the default `'branch'` scope wakes a `'tags'`\n * subscriber when any `tags.*` descendant is written. `'validating'`\n * carries a path per validator round and narrows by path like\n * `'change'`; `'disabled'`/`'submitSuccessful'` (like `'submitting'`)\n * are payload-less broadcasts that every named subscriber receives. A\n * `name` array builds one subscription per path and the returned\n * function unsubscribes them all.\n *\n * @param form the form to watch\n * @param options event, name(s), scope and callback\n * @return unsubscribe function\n */\nexport function subscribe(form: Form, options: SubscribeOptions): () => void {\n const {name, event = 'change', scope = 'branch', callback} = options;\n if (name === undefined) return on(form.emitter, event, callback);\n const names = isNameList(name) ? name : [name];\n const unsubscribes = names.map(one => {\n const path = createPath(one);\n return event === 'errors' || event === 'touched'\n ? onKeyEvent(form.emitter, event, path.key, callback)\n : onPathEvent(form.emitter, event, path, scope, callback);\n });\n return unsubscribes.length === 1\n ? unsubscribes[0]\n : () => unsubscribes.forEach(unsubscribe => unsubscribe());\n}\n","import {\n useState,\n useEffect,\n useCallback,\n useRef,\n useSyncExternalStore\n} from 'react';\nimport {on} from '../emitter';\nimport type {EventEmitter} from '../emitter';\nimport {onKeyEvent, onPathEvent} from '../subscribe';\nimport type {SubscribeEvent, WatchScope} from '../subscribe';\nimport createForm, {\n FORM_ERROR,\n getErrorByPath,\n getFieldErrorsByPath,\n getValueByPath,\n getValues,\n hasTouchedByPath,\n hasErrors,\n isDirty,\n isFieldDirtyByPath,\n getDirtyFields,\n getTouchedFields,\n setInitialValues,\n runFormValidate\n} from '../form';\nimport type {FieldError, Form, FormEvents, Options} from '../form';\nimport type {FieldPath, PathValueOf} from '../types';\nimport createPath from '../path';\nimport type {PathSegments, Path} from '../path';\nimport {get, isEqual, isPromise} from '../util';\n\n/**\n * Create a form instance bound to this component.\n *\n * Beyond {@link Options}, the optional `values` object enables controlled\n * usage: when it genuinely changes it is re-synced into the form with\n * setInitialValues semantics -- uncommitted user edits are discarded\n * (master-detail semantics: selecting another record replaces the draft),\n * while touched flags and errors survive. Change detection is\n * reference-first with a structural fallback, so re-renders that pass an\n * inline literal with equal content never re-sync -- the user's\n * in-progress typing is never clobbered.\n */\nexport default function useForm<T extends Record<string, any> = any>(\n options?: Options<T> & {values?: T}\n): Form<T> {\n // Lazy initialization: createForm runs once per mount and the returned\n // instance is stable across re-renders (and StrictMode double renders),\n // without writing to refs during render. A provided `values` object is\n // seeded synchronously here (createForm does the same for initialValues)\n // so the first paint and SSR already reflect the controlled values.\n const [form] = useState(() => {\n const created = createForm<T>(options);\n if (options && options.values !== undefined) {\n setInitialValues(created, options.values);\n }\n return created;\n });\n const initialValues = options && options.initialValues;\n const values = options && options.values;\n\n // Track which initialValues source object the form was last seeded from.\n // Inline options create a fresh object every render, and re-seeding\n // clears the values Map (setInitialValues semantics), which would revert\n // every committed edit right after each re-render -- on the client and\n // after hydration alike. Memoized callers are covered by the reference\n // check; inline literals by the structural one, so only genuinely new\n // content re-seeds.\n const seededRef = useRef<{done: boolean; source: any} | null>(null);\n if (seededRef.current === null)\n seededRef.current = {done: false, source: undefined};\n\n useEffect(() => {\n // undefined = no baseline requested (createForm already defaulted to\n // {}): installing it would clear the values Map on mount for no\n // semantic gain — wiping any render-time useField initialValue seeds.\n // Async sources (Promise or thunk) are excluded too: createForm owns\n // their one-shot resolution, and a thunk's identity changes every\n // render, so re-seeding here would clobber the resolution cycle with\n // the raw function itself.\n if (initialValues === undefined) return;\n if (typeof initialValues === 'function' || isPromise(initialValues)) {\n return;\n }\n const seeded = seededRef.current!;\n if (\n seeded.done &&\n (seeded.source === initialValues || isEqual(seeded.source, initialValues))\n ) {\n return;\n }\n seeded.done = true;\n seeded.source = initialValues;\n setInitialValues(form, initialValues);\n }, [form, initialValues]);\n\n // Controlled values: re-sync only when the incoming object genuinely\n // differs from what the form was last seeded from. The reference check\n // is the fast path (memoized callers); inline literals get a fresh\n // object identity every render, so without the structural comparison\n // each re-render would clear the values Map (setInitialValues\n // semantics) and revert the user's uncommitted edits -- same hazard the\n // initialValues seed guard above protects against. Master-detail\n // semantics still apply whenever the content actually changed.\n const controlledRef = useRef<{done: boolean; source: any} | null>(null);\n if (controlledRef.current === null) {\n controlledRef.current = {done: false, source: undefined};\n }\n\n useEffect(() => {\n if (values === undefined) return;\n const seeded = controlledRef.current!;\n if (\n seeded.done &&\n (seeded.source === values || isEqual(seeded.source, values))\n ) {\n return;\n }\n seeded.done = true;\n seeded.source = values;\n setInitialValues(form, values);\n }, [form, values]);\n\n // Mount validation: the form-level `validate` runs once after mount when\n // the form opted into `validateOnMount` (field kicks are the fields' own\n // — useValidate schedules them per registration). Children's effects run\n // before the parent's, so field registrations are in place by the time\n // this fires. While an async initialValues source is pending, defer to\n // the 'loading' event — it fires after the resolved baseline has landed.\n // The run is fire-and-forget: a rejected validator is the submit path's\n // business, and a sync throw propagates exactly like trigger's.\n useEffect(() => {\n if (!form.validateOnMount || !form.validate) return;\n const run = () => {\n void runFormValidate(form).catch(() => undefined);\n };\n if (!form.isLoading) {\n run();\n return;\n }\n return on(form.emitter, 'loading', () => {\n run();\n });\n }, [form]);\n\n return form;\n}\n\n/** Per-hook snapshot cache for {@link useWatch}. */\ntype WatchCache<T> = {hasValue: boolean; value?: T};\n\n/**\n * Shared core of {@link useWatch} and the path-scoped hooks: a\n * useSyncExternalStore binding over a custom event subscription.\n * `subscribeFactory` receives the invalidate callback (drop the snapshot\n * cache, then notify React) and returns its unsubscribe function, so the\n * core stays identical whether the subscription is global or scoped to\n * one path.\n *\n * The optional `isEqual` comparator redirects `invalidate`: instead of\n * dropping the cache and waking React unconditionally, an event first\n * recomputes the getter and asks `isEqual` whether anything observable\n * changed — an equal verdict keeps the cached snapshot and skips the\n * notify entirely (no render at all), an unequal one stores the fresh\n * snapshot and notifies. Omitted, the historical drop-and-notify pipeline\n * runs byte-for-byte unchanged.\n */\nexport function useWatchCore<T>(\n subscribeFactory: (invalidate: () => void) => () => void,\n getter: () => T,\n isEqual?: (prev: T, next: T) => boolean\n): T {\n // useSyncExternalStore requires getSnapshot to return the same reference\n // until the store actually changed, otherwise React warns and loops.\n // Cache the snapshot per hook instance and recompute it only on the first\n // read and after the watched event fired.\n const cacheRef = useRef<WatchCache<T> | null>(null);\n if (cacheRef.current === null) cacheRef.current = {hasValue: false};\n const cache = cacheRef.current;\n\n // Hold the latest getter in a ref so getSnapshot keeps a stable identity\n // (callers pass a freshly bound function on every render) while still\n // recomputing with the most recent getter when the cache is invalid.\n const getterRef = useRef(getter);\n getterRef.current = getter;\n // Same freshness treatment for the comparator: invalidate is created once\n // per subscription, so it must read the latest isEqual through a ref\n // rather than capturing whichever instance the first render passed.\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const getSnapshot = useCallback(() => {\n if (!cache.hasValue) {\n cache.value = getterRef.current();\n cache.hasValue = true;\n }\n return cache.value as T;\n }, [cache]);\n\n const subscribe = useCallback(\n (notify: () => void) => {\n // The form may have changed between render and this subscription, and\n // those events were missed: drop the cache. React's consistency check\n // right after subscribing recomputes and re-renders only when the\n // fresh value differs from the committed snapshot.\n cache.hasValue = false;\n const invalidate = () => {\n const compare = isEqualRef.current;\n if (compare && cache.hasValue) {\n // Custom comparator: decide before waking React. Equal means the\n // fresh getter result is observably the same — keep the cached\n // reference and return without notifying, so React never even\n // schedules a render. Unequal stores the fresh snapshot up front,\n // so React's own post-notify Object.is check reads it without\n // recomputing the getter.\n const next = getterRef.current();\n if (compare(cache.value as T, next)) return;\n cache.value = next;\n notify();\n return;\n }\n cache.hasValue = false;\n notify();\n };\n return subscribeFactory(invalidate);\n },\n [subscribeFactory, cache]\n );\n\n // Form state lives entirely in synchronously readable Map/Set structures\n // seeded from initialValues/values during the lazy useState initializer,\n // so the server snapshot is computed exactly like the client's first\n // render -- pass getSnapshot itself as getServerSnapshot and hydration\n // matches.\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to a form event and keep the component's snapshot of `getter()`\n * in sync with the form state.\n *\n * Built on useSyncExternalStore, so snapshots taken while React renders are\n * guaranteed consistent (no tearing under concurrent rendering) and changes\n * emitted before the subscription effect runs are still picked up.\n *\n * The first argument is the form for the unified `fn(form, ...)` context\n * shape every hook shares; the raw emitter form remains accepted for\n * back-compat and for subscription sources that are not a full form.\n *\n * By default the re-render surface is the event's own scope: every emit\n * the subscription hears drops the snapshot cache and wakes React, which\n * then bails out when the recomputed snapshot is reference-identical\n * (Object.is) — the path/leaf scoping every built-in reader relies on.\n * The optional `isEqual` comparator exists for wide-scope getters that\n * return a fresh reference per call (a whole-values selector, say): each\n * event recomputes the getter and asks `isEqual` whether the result is\n * observably the same, and an equal verdict skips notifying React\n * altogether — no render, not even a bailed-out one. An unequal verdict\n * stores the new snapshot and re-renders. Same contract as TanStack's\n * `useSelector` compare. Omitted, behavior is unchanged.\n */\nexport function useWatch<T>(\n formOrEmitter: Form | EventEmitter<FormEvents>,\n event: SubscribeEvent,\n getter: () => T,\n isEqual?: (prev: T, next: T) => boolean\n): T {\n // A form carries an `emitter` field the opaque emitter instance never\n // has, so the duck test cleanly discriminates the two accepted shapes.\n const emitter =\n 'emitter' in formOrEmitter ? formOrEmitter.emitter : formOrEmitter;\n const subscribeFactory = useCallback(\n (invalidate: () => void) => on(emitter, event, invalidate),\n [emitter, event]\n );\n return useWatchCore(subscribeFactory, getter, isEqual);\n}\n\n/** Options for {@link useValue} and {@link useValueByPath}. */\nexport type UseValueOptions<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n> = {\n /** Value to return while the field reads undefined — react-hook-form's\n * `useWatch` `defaultValue`: an untouched, never-seeded field reads\n * this instead of `undefined`. */\n defaultValue?: PathValueOf<T, P>;\n /** Watch descendants too (react-hook-form's `exact: false`): a write\n * to `a.b` invalidates a `useValue(form, 'a')` read, and the read\n * resolves the merged subtree (the copy-on-write `getValues` tree) so\n * descendant edits show up in the result. Defaults to true — the leaf\n * scope, where only the exact key and its ancestors invalidate (the\n * long-standing behavior). */\n exact?: boolean;\n};\n\n/**\n * Get field value state\n */\nexport function useValue<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P, options?: UseValueOptions<T, P>): PathValueOf<T, P> {\n return useValueByPath(form, createPath(name), options);\n}\n\n/**\n * Get field value state by path\n */\nexport function useValueByPath(\n form: Form,\n path: Path,\n options?: {defaultValue?: any; exact?: boolean}\n): any {\n const {emitter} = form;\n const {key} = path;\n const scope: WatchScope = options?.exact === false ? 'branch' : 'leaf';\n // 'leaf' scope: a leaf read depends only on its own key and its\n // ancestors' (getValueByPath fallback chain), so writes elsewhere --\n // siblings, descendants, string-prefix lookalikes ('[\"a\",\"bX\"]') -- never\n // invalidate the snapshot. 'branch' (exact: false) additionally wakes on\n // descendant writes and resolves the merged subtree through `getValues`\n // (getValueByPath only walks live ancestors, so a descendant edit would\n // otherwise read back a stale reference). Payload-less broadcasts\n // (reset, setInitialValues) still sync everything; removeField matches\n // by path.\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(emitter, 'change', path, scope, invalidate),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `key` on purpose: useValue creates a fresh Path per render, so the object must stay out of the deps while the key string pins the subscription\n [emitter, key, scope]\n );\n return useWatchCore(subscribeFactory, () => {\n if (options?.exact === false) {\n return get(getValues(form), path.value);\n }\n const value = getValueByPath(form, path);\n return value === undefined ? options?.defaultValue : value;\n });\n}\n\n/**\n * Get field touched state\n */\nexport function useTouched<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): boolean {\n return useTouchedByPath(form, createPath(name));\n}\n\n/**\n * Get field touched state by path\n */\nexport function useTouchedByPath(form: Form, path: Path): boolean {\n const {emitter} = form;\n const {key} = path;\n // Touched is stored per exact key, so only this field's own setTouched\n // (now emitted with its path) matters; payload-less broadcasts (reset,\n // removeField) still sync everything.\n const subscribeFactory = useCallback(\n (invalidate: () => void) => onKeyEvent(emitter, 'touched', key, invalidate),\n [emitter, key]\n );\n return useWatchCore(\n subscribeFactory,\n hasTouchedByPath.bind(null, form, path)\n );\n}\n\n/**\n * Get field error message state\n * @return current error's message string (display text), or undefined\n */\nexport function useError<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): string | undefined {\n return useErrorByPath(form, createPath(name))?.message;\n}\n\n/**\n * Get field error state by path\n * @return current FieldError object ({type, message}), or undefined\n */\nexport function useErrorByPath(form: Form, path: Path): FieldError | undefined {\n const {emitter} = form;\n const {key} = path;\n // Errors are stored per exact key, so only writes to this field's error\n // (setErrorByPath now emits with its path) matter; payload-less\n // broadcasts (clearErrors, reset, removeField) still sync everything.\n const subscribeFactory = useCallback(\n (invalidate: () => void) => onKeyEvent(emitter, 'errors', key, invalidate),\n [emitter, key]\n );\n return useWatchCore(subscribeFactory, getErrorByPath.bind(null, form, path));\n}\n\n/**\n * Get all field errors\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function useFieldErrors<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): FieldError[] {\n return useFieldErrorsByPath(form, createPath(name));\n}\n\n/**\n * Get all field errors by path\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function useFieldErrorsByPath(form: Form, path: Path): FieldError[] {\n const {emitter} = form;\n const {key} = path;\n // Same exact-key subscription and snapshot rules as useErrorByPath: the\n // getter returns the shared empty constant when clean and the stored\n // array by reference otherwise, so the useSyncExternalStore snapshot is\n // reference-stable between unrelated events.\n const subscribeFactory = useCallback(\n (invalidate: () => void) => onKeyEvent(emitter, 'errors', key, invalidate),\n [emitter, key]\n );\n return useWatchCore(\n subscribeFactory,\n getFieldErrorsByPath.bind(null, form, path)\n );\n}\n\nexport function useIsDirty(form: Form): boolean {\n // Dirty state is driven by value changes, not touch state: subscribe to\n // 'change' so typing flips this immediately, even before a blur.\n return useWatch(form, 'change', isDirty.bind(null, form));\n}\n\n/**\n * Get whether one field is dirty: its live value exists and differs from\n * the field's effective baseline — the same per-field rule\n * `getFieldState(form, name).isDirty` applies (committed\n * `shouldDirty: false` baselines included). Subscribes to 'change' at\n * leaf scope like {@link useValue}: own-key and ancestor writes re-check\n * the flag, payload-less broadcasts (reset, setInitialValues) always\n * sync, and writes elsewhere never re-render it.\n */\nexport function useIsFieldDirty<\n T extends Record<string, any> = any,\n P extends FieldPath<T> | PathSegments = FieldPath<T> | PathSegments\n>(form: Form<T>, name: P): boolean {\n return useIsFieldDirtyByPath(form, createPath(name));\n}\n\n/**\n * Get whether one field is dirty, by parsed path. See {@link\n * useIsFieldDirty}.\n */\nexport function useIsFieldDirtyByPath(form: Form, path: Path): boolean {\n const {emitter} = form;\n const {key} = path;\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(emitter, 'change', path, 'leaf', invalidate),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- same key-pinning convention as useValueByPath\n [emitter, key]\n );\n return useWatchCore(subscribeFactory, () => isFieldDirtyByPath(form, path));\n}\n\n/**\n * Get dirty fields state -- object mapping each dirty field's user-facing\n * dotted path ('a.b', 'a.0.c') to true; recalculated after 'change' events\n */\nexport function useDirtyFields(form: Form): Record<string, boolean> {\n return useWatch(form, 'change', getDirtyFields.bind(null, form));\n}\n\n/**\n * Get touched fields state -- array of touched fields' user-facing dotted\n * paths ('a.b', 'a.0.c'); recalculated after 'touched' events\n */\nexport function useTouchedFields(form: Form): string[] {\n return useWatch(form, 'touched', getTouchedFields.bind(null, form));\n}\n\n/**\n * Aggregate snapshot of the whole form's state flags — the one-subscription\n * counterpart of react-hook-form's `formState` object (no errors object;\n * per-field error state stays with `useError`/`useFieldErrors`, and\n * `hasErrors`/`isValid` cover the whole-form questions).\n *\n * Recomputed on every state-bearing event; the field-wise comparator keeps\n * the returned reference stable while nothing observably changed, so\n * `useFormState(form).isDirty` re-renders no more often than the dedicated\n * {@link useIsDirty}. Cheaper than calling the granular hooks one by one\n * (one subscription and one snapshot instead of one per flag).\n */\nexport type FormState = {\n /** Any live value differs from its baseline (see {@link isDirty}). */\n isDirty: boolean;\n /** Dirty fields keyed by user-facing dotted path ('a.b', 'a.0.c'). */\n dirtyFields: Record<string, boolean>;\n /** At least one field is touched. */\n isTouched: boolean;\n /** Touched fields' user-facing dotted paths. */\n touchedFields: string[];\n /** Any error registered (field or form level). */\n hasErrors: boolean;\n /** No errors are registered — react-hook-form's `isValid` semantics.\n * In-flight validation is NOT factored in ({@link isValidating} is the\n * separate signal; async rounds temporarily pass this flag like RHF's). */\n isValid: boolean;\n isSubmitting: boolean;\n /**\n * Whether a submit has been attempted on this form — set on the first\n * `handleSubmit` call (validation outcome aside) and cleared by\n * `reset`, react-hook-form's `formState.isSubmitted` semantics. Read\n * after a failed submit to render a \"fix the errors below\" panel.\n */\n isSubmitted: boolean;\n /** Any validation round is running (field, form-level, or a pending\n * debounce window). */\n isValidating: boolean;\n isSubmitSuccessful: boolean | undefined;\n submitCount: number;\n /** Async initialValues still pending ({@link Form.isLoading}). */\n isLoading: boolean;\n /** The form-level disabled flag (fields OR their own `disabled`). */\n disabled: boolean;\n};\n\n/** Events any FormState field can react to: each recomputes the whole\n * snapshot — the comparator, not per-flag subscriptions, keeps the\n * re-render surface minimal. */\nconst FORM_STATE_EVENTS: readonly SubscribeEvent[] = [\n 'change',\n 'errors',\n 'touched',\n 'validating',\n 'submitting',\n 'submitCount',\n 'submitSuccessful',\n 'disabled',\n 'loading'\n];\n\nfunction getFormState(form: Form): FormState {\n return {\n isDirty: isDirty(form),\n dirtyFields: getDirtyFields(form),\n isTouched: form.touched.size > 0,\n touchedFields: getTouchedFields(form),\n hasErrors: hasErrors(form),\n isValid: !hasErrors(form),\n isSubmitting: form.isSubmitting,\n isSubmitted: form.isSubmitted,\n isValidating: form.validating.size > 0,\n isSubmitSuccessful: form.isSubmitSuccessful,\n submitCount: form.submitCount,\n isLoading: form.isLoading,\n disabled: form.disabled\n };\n}\n\n/** Field-wise equality: reference checks where the getter already memoizes\n * (dirtyFields), element-wise for the fresh array getTouchedFields builds,\n * value checks for the flags. */\nfunction isSameFormState(a: FormState, b: FormState): boolean {\n const sameTouched =\n a.touchedFields.length === b.touchedFields.length &&\n a.touchedFields.every((path, i) => path === b.touchedFields[i]);\n return (\n a.isDirty === b.isDirty &&\n a.dirtyFields === b.dirtyFields &&\n a.isTouched === b.isTouched &&\n sameTouched &&\n a.hasErrors === b.hasErrors &&\n a.isValid === b.isValid &&\n a.isSubmitting === b.isSubmitting &&\n a.isSubmitted === b.isSubmitted &&\n a.isValidating === b.isValidating &&\n a.isSubmitSuccessful === b.isSubmitSuccessful &&\n a.submitCount === b.submitCount &&\n a.isLoading === b.isLoading &&\n a.disabled === b.disabled\n );\n}\n\nexport function useFormState(form: Form): FormState {\n const getter = useCallback(() => getFormState(form), [form]);\n const subscribeFactory = useCallback(\n (invalidate: () => void) => {\n const offs = FORM_STATE_EVENTS.map(event =>\n on(form.emitter, event, invalidate)\n );\n return () => {\n for (const off of offs) off();\n };\n },\n [form.emitter]\n );\n return useWatchCore(subscribeFactory, getter, isSameFormState);\n}\n\nexport function useHasErrors(form: Form): boolean {\n return useWatch(form, 'errors', hasErrors.bind(null, form));\n}\n\n/**\n * Get whether the form currently has no errors — react-hook-form's\n * `formState.isValid` counterpart. Subscribes to the `'errors'` event only;\n * in-flight validation does not flip it (see {@link useIsValidating}).\n */\nexport function useIsValid(form: Form): boolean {\n return useWatch(form, 'errors', () => !hasErrors(form));\n}\n\nexport function useIsSubmitting(form: Form): boolean {\n return useWatch(form, 'submitting', () => form.isSubmitting);\n}\n\n/**\n * Get whether an async {@link Options.initialValues} source is still\n * pending — the flag a loading skeleton or a disabled submit button gates\n * on until the resolved baseline lands. Subscribes to the 'loading' event\n * the core emits around the resolution cycle.\n */\nexport function useIsLoading(form: Form): boolean {\n return useWatch(form, 'loading', () => form.isLoading);\n}\n\n/**\n * Get the form's user-owned metadata slot reactively (Formik's `status`\n * counterpart): any value the app stores through {@link setStatus} —\n * server session flags, wizard step state, non-field errors. Subscribes\n * to the payload-less 'status' event, so unrelated events never re-render\n * the caller, and the returned reference is stable between writes that\n * store an equal value (useSyncExternalStore's Object.is bailout).\n */\nexport function useStatus<T = any>(form: Form): T {\n return useWatch(form, 'status', () => form.status);\n}\n\n/**\n * Get whether the form accepts a submit right now:\n * `!isSubmitting && !hasErrors`. This is the single flag a submit\n * button's `disabled` prop wants — it is `false` for the whole async\n * `onSubmit` span (not just the validation pass) and whenever any field\n * holds an error (client validation or server backfill), replacing the\n * hand-rolled `useHasErrors(form) || useIsSubmitting(form)` pair.\n * Deliberately no dirty or validating semantics: an untouched-but-clean\n * form can submit.\n */\nexport function useCanSubmit(form: Form): boolean {\n const {emitter} = form;\n // canSubmit folds two events into one boolean: error writes\n // ('errors') and submit-state flips ('submitting'). useWatch subscribes\n // to a single event, so subscribe to both through useWatchCore — the\n // snapshot recomputes on either wake and re-renders only when the\n // boolean itself flips, so unrelated single-field error churn costs no\n // extra render (the same granularity useHasErrors already has).\n const subscribeFactory = useCallback(\n (invalidate: () => void) => {\n const offErrors = on(emitter, 'errors', invalidate);\n const offSubmitting = on(emitter, 'submitting', invalidate);\n return () => {\n offErrors();\n offSubmitting();\n };\n },\n [emitter]\n );\n return useWatchCore(\n subscribeFactory,\n () => !form.isSubmitting && !hasErrors(form)\n );\n}\n\nexport function useSubmitCount(form: Form): number {\n return useWatch(form, 'submitCount', () => form.submitCount);\n}\n\n/**\n * Get whether any validation round is currently running: a field\n * validator's pending `validateDebounce` window, an async field validator\n * still in flight, or the form-level validate's debounce window / in-flight\n * round — every one of them holds a key in `form.validating`, and the\n * 'validating' events they emit (field rounds with a path payload, the\n * form-level round as a payload-less broadcast) are what this subscribes\n * to. The boolean snapshot is Object.is-stable, so churn among the marks\n * (a second field opening while the first settles) costs no render while\n * the flag holds. This is the flag a submit button disables itself on, or\n * spins a spinner with, through the pre-submit validation pass — it flips\n * true the moment the first round opens and back false when the last one\n * settles.\n */\nexport function useIsValidating(form: Form): boolean {\n return useWatch(form, 'validating', () => form.validating.size > 0);\n}\n\n/**\n * Get whether the last submit succeeded: `true` once a submit's validation\n * and `onSubmit` completed without throwing, `false` after a failed submit\n * (validation rejection or a thrown callback) and before any submit ran —\n * the falsy reading of the undefined initial/reset state. Subscribes to\n * the 'submitSuccessful' event the core's setSubmitSuccessful emits, so\n * the flag flips in the same tick the outcome lands: the usual consumers\n * are a success banner and a redirect-on-success effect.\n */\nexport function useIsSubmitSuccessful(form: Form): boolean {\n return useWatch(\n form.emitter,\n 'submitSuccessful',\n () => !!form.isSubmitSuccessful\n );\n}\n\n/**\n * Get the form-level error message: the first error stored under the\n * reserved {@link FORM_ERROR} key, as display text — or undefined while\n * the slot is clean. That key is where a form-level `validate` record's\n * `_form` entry lands and where the Standard Schema adapter drops\n * path-less issues, so errors that belong to no single field still have a\n * reader. The classic usage renders it once above the submit button —\n * `useFormError(form) || null` — and the imperative twin is\n * `getError(form, FORM_ERROR)`.\n */\nexport function useFormError(form: Form): string | undefined {\n return useErrorByPath(form, createPath(FORM_ERROR))?.message;\n}\n\n/**\n * Get every form-level error: all errors stored under the reserved\n * {@link FORM_ERROR} key (insertion order), an empty array when the slot\n * is clean. The plural twin of {@link useFormError} for forms that stack\n * several form-level issues — each path-less Standard Schema issue lands\n * in this slot. The array reference is stable between unrelated events\n * (the stored array or a shared empty constant), so consumers can memo on\n * it; the imperative counterpart is `getFieldErrors(form, FORM_ERROR)`.\n */\nexport function useFormErrors(form: Form): FieldError[] {\n return useFieldErrorsByPath(form, createPath(FORM_ERROR));\n}\n","import {useMemo} from 'react';\nimport create from '../path';\nimport type {Name, Path} from '../path';\nimport {normalizePath} from '../util';\n\nexport default function usePath(name: Name): Path {\n const path = useMemo(() => create(normalizePath(name)), [name]);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `path.key` on purpose: re-renders passing a fresh array for the same field name reuse the cached Path object (stable reference & Map key)\n return useMemo(() => path, [path.key]);\n}\n","import {useCallback, useEffect, useRef, type MutableRefObject} from 'react';\n\nexport default function useStage<T>(value: T): MutableRefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport function useStageFn<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useStage(fn);\n return useCallback(\n (...params: any[]) => ref.current(...params),\n [ref]\n ) as unknown as T;\n}\n\n/**\n * Run destructive unmount `teardown` synchronously on every cleanup —\n * real unmounts behave exactly like a plain effect cleanup — and let a\n * setup that immediately follows a cleanup (`restore`) undo it.\n *\n * React 19's StrictMode double-invokes effects on the initial mount\n * (setup → cleanup → setup), so a plain cleanup would run the teardown\n * and then remount with the state gone. The cycle's second setup finds\n * the `removed` flag and calls `restore` before any render or event can\n * observe the gap; a real unmount has no following setup and the\n * teardown simply stands.\n *\n * `teardown`/`restore` must be referentially stable (build them with\n * {@link useStageFn}); the effect intentionally runs once per mount.\n */\nexport function useUnmountRestore(\n teardown: () => void,\n restore: () => void\n): void {\n const removedRef = useRef(false);\n useEffect(() => {\n // The previous cleanup ran the teardown — this setup is the StrictMode\n // remount: put the state back.\n if (removedRef.current) {\n removedRef.current = false;\n restore();\n }\n return () => {\n removedRef.current = true;\n teardown();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- teardown/restore are stage-stable; the effect must run exactly once per mount\n }, []);\n}\n","import {useContext, useEffect, useRef} from 'react';\nimport {on} from '../emitter';\nimport {FormContext} from '../context';\nimport {registerValidatorByPath} from '../form';\nimport type {Form, SyncValidator, Validator} from '../form';\nimport type {Path} from '../path';\nimport {useStageFn} from './stage';\n\n// The validator contract itself is framework-free and lives in the core\n// (`src/form.ts`); re-exported here so historical imports keep working.\nexport type {SyncValidator, Validator};\n\n/**\n * Options for {@link useValidate} — the React-side registration of a field\n * validator. The registration machinery (debounce window, async-round\n * lock, signal abort, validating mark) lives in the core's\n * {@link registerValidatorByPath}; this hook only wires its React\n * lifecycle around it: register on mount, dispose on unmount, and read\n * the validator/debounce/sync-gate live through refs so re-renders never\n * re-subscribe the registration mid-flight.\n */\nexport type UseValidateOptions = {\n /**\n * Delay in milliseconds before a validation kick actually runs the\n * debounced validator. `0` (default) runs immediately; a positive value\n * debounces rapid kicks (e.g. typing) so only the last one executes.\n * While the timer is pending the field counts as validating, so\n * `trigger` / `ensureValidate` wait out the window. The `sync`\n * pre-validator is exempt: it runs immediately on every kick and never\n * waits out the window.\n */\n debounce?: number;\n /**\n * Synchronous pre-validator run immediately on every kick — never\n * debounced. While it returns errors, the debounced `validate` is\n * skipped for that kick (its errors land and the expensive check never\n * runs), and any pending debounce window or in-flight round is\n * superseded. When it passes, a stale error it produced earlier clears\n * at once, and a registration with no `validate` treats the passing\n * check as the whole round and clears the field's errors.\n */\n sync?: SyncValidator;\n /**\n * Run the debounced validator even when the `sync` gate failed —\n * TanStack Form's `asyncAlways`. The gate's errors land immediately\n * (never debounced) and the validator's own result lands alongside\n * them, per-source: a passing async round clears only its own errors,\n * the gate's verdict stays until the gate itself passes. Defaults to\n * false (gate failure owns the kick's outcome).\n */\n asyncAlways?: boolean;\n /**\n * Validate on mount: kick the registration once after it lands (Formik's\n * `validateOnMount` / TanStack Form's per-field flag). Falls back to the\n * form-level `createForm({validateOnMount})` when omitted, so a field\n * opts out with `validateOnMount: false`. Validator-less registrations\n * never kick on mount — an empty kick would clear a server error that\n * landed before the field mounted. While an async `initialValues` source\n * is still pending the kick is deferred until the resolved baseline\n * lands (validating the empty shell would land spurious required\n * errors); a field unmounted in between never kicks.\n */\n validateOnMount?: boolean;\n};\n\n/**\n * Register a field validator with the form and return its kick — a stable\n * function that validates the field's current value (debounce and sync\n * gate applied). The returned function is the one stored in\n * `form.validators`; `trigger`/`ensureValidate` run every stored kick,\n * and the field's user-change gate runs the changed path's kick. This is\n * the old \"useValidate\" behavior — the same public shape with the\n * machinery moved into the core, so non-React adapters can register\n * validators directly through `registerValidatorByPath`.\n */\nexport default function useValidate(\n validate: Validator | undefined,\n path: Path,\n formProp?: Form,\n options?: UseValidateOptions\n): () => void {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(FormContext);\n const form = formProp || contextForm;\n if (!form) throw new Error('no form provided');\n // Live accessors: the registration must always see the latest\n // validator/debounce/sync-gate, so swapping them per render (inline\n // validators, recompiled rules) never re-subscribes the registration\n // mid-flight.\n const validateRef = useRef(validate);\n validateRef.current = validate;\n const debounceRef = useRef(options?.debounce ?? 0);\n debounceRef.current = options?.debounce ?? 0;\n const syncRef = useRef(options?.sync);\n syncRef.current = options?.sync;\n const asyncAlwaysRef = useRef(options?.asyncAlways ?? false);\n asyncAlwaysRef.current = options?.asyncAlways ?? false;\n\n useEffect(() => {\n const dispose = registerValidatorByPath(form, path, {\n validate: () => validateRef.current,\n debounce: () => debounceRef.current,\n sync: () => syncRef.current,\n asyncAlways: () => asyncAlwaysRef.current\n });\n // Mount validation: kick the registration once after it lands. The\n // field's own option wins over the form-level flag in either\n // direction. Validator-less registrations never kick — an empty kick\n // clears whatever error was already stored at the path (a server\n // backfill that landed before mount, say).\n const validateOnMount = options?.validateOnMount ?? form.validateOnMount;\n if (!validateOnMount || (!validateRef.current && !syncRef.current)) {\n return dispose;\n }\n // A deferred kick must never fire after this mount's registration was\n // disposed (unmount, or StrictMode's setup→cleanup→setup remount): the\n // flag drops it, and a remounted field's own setup schedules its kick.\n let disposed = false;\n const kick = () => {\n if (disposed) return;\n form.validators.get(path.key)?.();\n };\n if (!form.isLoading) {\n kick();\n } else {\n // Async initialValues pending: the 'loading' event fires after the\n // resolved baseline has landed (setInitialValues first), so the kick\n // validates real values instead of the empty shell.\n const off = on(form.emitter, 'loading', () => {\n off();\n kick();\n });\n }\n return () => {\n disposed = true;\n dispose();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `path.key` on purpose: usePath returns a stable Path per key, so re-subscribing on key (not object identity) is enough\n }, [form, path.key]);\n\n return useStageFn(() => form.validators.get(path.key)?.());\n}\n","/**\n * Unmount-removal helpers: the snapshot/remove pair and its restore.\n *\n * React 19's StrictMode double-invokes effects on the initial mount\n * (setup → cleanup → setup), so a plain effect cleanup that calls\n * {@link removeFieldByPath} runs during the mount cycle and wipes a field\n * the very next setup expects to be there. `useUnmountRestore` in\n * src/hooks/stage.ts runs the teardown synchronously on every cleanup\n * (real unmounts stay exactly as before) and hands the restore to the\n * setup that follows — which exists only in the StrictMode cycle, so the\n * removal is undone before any render or subscriber can observe the gap.\n *\n * This module is internal: hooks import it directly, the facade never\n * re-exports it.\n */\nimport {emit} from '../emitter';\nimport type {FieldError, Form} from '../form';\nimport type {Path} from '../path';\nimport {setErrorByPath} from './errors';\nimport {bumpValuesVersion} from './internals';\nimport {setTouchedByPath} from './touched';\nimport {removeFieldByPath, setValueByPath} from './values';\n\n/** Everything {@link removeFieldByPath} destroys, captured before it runs\n * so {@link restoreRemovedField} can put it back. */\nexport type RemovedFieldSnapshot = {\n /** Whether the values Map held the key — restores the exact entry,\n * including an explicit `undefined` value. */\n present: boolean;\n value: any;\n touched: boolean;\n errors: FieldError[] | undefined;\n};\n\n/**\n * Snapshot the field's state, then remove it — the teardown half of the\n * StrictMode-safe unmount removal.\n */\nexport function removeFieldForUnmount(\n form: Form,\n path: Path\n): RemovedFieldSnapshot {\n const {key} = path;\n const snapshot: RemovedFieldSnapshot = {\n present: form.values.has(key),\n value: form.values.get(key),\n touched: form.touched.has(key),\n errors: form.errors.get(key)\n };\n removeFieldByPath(form, path);\n return snapshot;\n}\n\n/**\n * Undo {@link removeFieldForUnmount} — the restore half, run only by a\n * setup that immediately follows the cleanup (the StrictMode remount).\n * Rebuilds the exact pre-removal state:\n * - a Map-backed value re-lands through {@link setValueByPath} with\n * `shouldDirty: false` (the removal cleared committed baselines; the\n * restored value becomes the baseline — identical dirty reads, since\n * the StrictMode cycle happens at mount before any edit exists)\n * - a baseline-derived value (absent from the Map) only needs its\n * tombstone undone — no write, so no entry materializes in the Map\n * - touched/errors re-add without re-validating\n */\nexport function restoreRemovedField(\n form: Form,\n path: Path,\n snapshot: RemovedFieldSnapshot\n): void {\n const {key} = path;\n if (snapshot.present) {\n setValueByPath(form, path, snapshot.value, {shouldDirty: false});\n } else {\n form.deleted.delete(key);\n bumpValuesVersion(form);\n // The removal emitted with a path payload; the restore must wake the\n // same subscribers so snapshots taken in the gap re-sync.\n emit(form.emitter, 'change', path);\n }\n if (snapshot.touched) setTouchedByPath(form, path);\n if (snapshot.errors) setErrorByPath(form, path, snapshot.errors);\n}\n","import {useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport type {Context} from 'react';\nimport {on} from '../emitter';\nimport {FormContext} from '../context';\nimport {\n emitChangeByPath,\n getValueByPath,\n isFieldDirtyByPath,\n registerFieldMode,\n registerFieldValidateDeps,\n seedValueByPath,\n unregisterFieldMode,\n unregisterFieldValidateDeps,\n userBlur,\n userChangeByPath\n} from '../form';\nimport type {FieldError, Form, ValidationMode} from '../form';\nimport createPath from '../path';\nimport type {Path, PathSegments} from '../path';\nimport type {FieldPath, PathValueOf} from '../types';\nimport {rulesToValidator} from '../rules';\nimport type {FieldRules} from '../rules';\nimport {useFieldErrorsByPath, useWatch, useWatchCore} from './form';\nimport {onKeyEvent, onPathEvent} from '../subscribe';\nimport usePath from './path';\nimport useValidate from './validate';\nimport type {Validator} from './validate';\nimport {removeFieldForUnmount, restoreRemovedField} from '../core/unmount';\nimport type {RemovedFieldSnapshot} from '../core/unmount';\nimport {useStageFn, useUnmountRestore} from './stage';\nimport {isPromise} from '../util';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/** Module-private registry driving uncontrolled fields' DOM sync — one\n * 'change' listener per form (see the sync effect in {@link\n * useFieldCore}), the same module-scope registry pattern\n * `arrayIdsRegistry` uses in fieldArray.ts. Per-form cells map a field's\n * path key to a reader of its bound element and path; the shared listener\n * iterates them only on payload-less (bulk) emits. */\ntype UncontrolledSyncEntry = {\n cells: Map<string, () => {el: any; path: Path}>;\n off: () => void;\n};\nconst uncontrolledSyncRegistry = new WeakMap<Form, UncontrolledSyncEntry>();\n\nexport type UseFieldOptions<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = {\n form?: Form<TValues>;\n name: TPath;\n initialValue?: any;\n shouldUnregister?: boolean;\n /**\n * Field-level validator. The value argument follows the path: with a\n * typed form the callback receives `PathValueOf<TValues, TPath>` (the\n * TanStack-parity inference — `name: 'age'` on a `{age: number}` shape\n * types `value` as `number`), and falls back to `any` for untyped call\n * sites (segment arrays, dynamic names). The return shape mirrors\n * {@link Validator} — an error (string / FieldError / mixed array) or\n * undefined when valid, possibly a Promise for async validation. The\n * second argument carries the validation context (`meta.signal` aborts\n * when the round is superseded).\n */\n validate?: (\n value: PathValueOf<TValues, TPath>,\n meta: {form: Form<TValues>; path: Path; signal: AbortSignal}\n ) => ReturnType<Validator>;\n /**\n * Declarative rules (required/min/max/minLength/maxLength/pattern),\n * compiled into a synchronous validator. `required` is special: it runs\n * immediately on every kick — never debounced — and while it fails,\n * `validate` is skipped (the expensive check never sees an empty value).\n * The other rules compose with `validate` — rules run first, then\n * `validate` (awaited when async), merging both sources' errors with\n * rules errors ahead. Failures land in the form's error state with the\n * given or default messages.\n */\n rules?: FieldRules;\n /**\n * Milliseconds to debounce this field's validation kicks. Defaults to 0\n * (validate immediately); while the timer is pending the field counts as\n * validating, so `trigger`/`ensureValidate` wait out the window. Only the\n * last kick inside the window runs the validator. The `required` rule is\n * exempt: it runs synchronously on every kick, so a required failure\n * shows immediately instead of waiting out the window.\n */\n validateDebounce?: number;\n /**\n * Run this field's debounced validator even when its `required` gate\n * failed — TanStack Form's `asyncAlways`. The gate's errors land\n * immediately (never debounced) and the validator's own result lands\n * alongside them, per-source: a passing async round clears only its\n * own errors while the gate's verdict stays. Falls back to the\n * form-level `createForm({asyncAlways})` flag when omitted, so a field\n * opts out with `asyncAlways: false`. The use case: the cheap format\n * check fails (gate) but the expensive backend check should still run\n * (\"not in the right shape — and the backend says taken, too\").\n */\n asyncAlways?: boolean;\n /**\n * Milliseconds to delay showing a newly appearing error in the render\n * layer (`error`/`errorObject`/`errors` stay undefined/empty until the\n * window passes). The form's error state is never delayed — trigger,\n * submit and `getError` read it immediately. An error that clears inside\n * the window never shows; once an error is visible, later changes apply\n * immediately. Only the none → some transition waits.\n */\n delayError?: number;\n /**\n * Disable this field: OR-ed with the form-level flag\n * (`createForm({disabled})` / `setDisabled`) into the result's\n * `disabled`. A field cannot opt out of a disabled form.\n */\n disabled?: boolean;\n /**\n * Uncontrolled mode: the field never subscribes to its own value, so\n * typing re-renders nothing — the store still carries every write\n * (getValues/submit/validation read it), and errors/touched/disabled/\n * validating still re-render the field like react-hook-form's\n * `register`. The result's `value` is the mount-time snapshot (initial\n * value seed or baseline); it never refreshes, and bulk operations\n * (reset/setInitialValues) sync the DOM element directly through the\n * `focusRef`-held element instead of a render — the register-style\n * contract, RHF's reset clears the input the same way. Attach the\n * result with `<input defaultValue={field.value} ref={field.focusRef}>`\n * -style binding (no `value` prop), exactly like <Field uncontrolled />\n * does. The DOM sync writes the raw stored value (file inputs are\n * skipped); read live values with useValue/getValues.\n */\n uncontrolled?: boolean;\n /**\n * Field-level validation mode override: when given, this field validates\n * on its own schedule instead of `form.mode` — every other field keeps\n * the form-level timing (e.g. a form that defaults to `'onSubmit'` with\n * one field declared `'onBlur'` shows that field's error on blur while\n * the rest wait for submit). `reValidateMode` stays form-level: once any\n * field has an error (after a failed submit, say), re-validation follows\n * the form's `reValidateMode` for every field, overriding this one too.\n * See {@link ValidationMode}.\n */\n mode?: ValidationMode;\n /**\n * Field paths whose **user changes re-run this field's validator** —\n * the field-level counterpart of the form-level `validateDeps` option\n * (cross-field linkage: `password` changed → re-check\n * `passwordConfirm`). TanStack Form's `onChangeListenTo` / RHF trigger\n * chains are the ecosystem analogues.\n *\n * The re-run rides the changed field's own onChange pipeline, so typing\n * and `changeValue` both fire it while programmatic `setValue` does\n * not, and its timing is gated by the same mode matrix as the form\n * level: the changed field's effective `mode` (per-field override\n * included) and the form's `reValidateMode` — under the default\n * `'onSubmit'`/`'onChange'` pair, a dep change re-validates this field\n * once this field already shows an error (the submit-then-fix flow: the\n * mismatch lands on submit, editing the password re-checks the confirm\n * and a passing round clears the error, because a field validator owns\n * its whole key).\n *\n * `validateDebounce` applies to the re-run like to any kick. Declaring\n * the field's own path is a no-op (its own change already validates it).\n */\n validateDeps?: FieldPath<TValues>[];\n /**\n * Validate this field once on mount instead of waiting for the first\n * submit/change — errors show immediately for an untouched field.\n * Overrides the form-level `createForm({validateOnMount})` flag in\n * either direction (`false` opts a field out of a validating form).\n * While an async `initialValues` source is still pending the kick waits\n * for the resolved baseline; a field unmounted in between never kicks.\n */\n validateOnMount?: boolean;\n};\n\n/**\n * The result of {@link useField}. Deliberately a closed shape: no index\n * signature, so a typo'd property access (`field.vlaue`) is a type error\n * instead of silently reading `undefined`.\n */\nexport type UseFieldResult<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = {\n /** The form instance this field is bound to (explicit prop or context) —\n * handy for consumers that need direct access to the headless API. */\n form: Form<TValues>;\n value: PathValueOf<TValues, TPath>;\n /** Error message string (FieldError#message) for display, or undefined */\n error: string | undefined;\n /** Full FieldError object ({type, message}), or undefined */\n errorObject: FieldError | undefined;\n /** Every error registered for the field, in insertion order — `error`\n * and `errorObject` are its first entry. Empty (and reference-stable)\n * when the field has no errors. */\n errors: FieldError[];\n /**\n * Whether the field is dirty: its live value exists and differs from\n * the field's effective baseline (the same per-field rule\n * `getFieldState(form, name).isDirty` applies — committed\n * `shouldDirty: false` baselines included). Live in controlled mode;\n * pinned at mount in uncontrolled mode (like `value`) so typing never\n * re-renders the field — {@link useIsFieldDirty} is the live scoped\n * channel for either mode.\n */\n isDirty: boolean;\n /**\n * Whether a validator round for this field is currently in flight —\n * a pending debounce window or an unresolved async validator (the\n * `getFieldState(form, name).isValidating` reading, made reactive).\n */\n validating: boolean;\n onChange: (v: any) => void;\n onBlur: () => void;\n name: string;\n /** Merged disabled flag: the form-level flag (`createForm({disabled})`\n * toggled by `setDisabled`) OR-ed with this field's own `disabled`\n * option, updated live through the form's event core. */\n disabled: boolean;\n /**\n * Callback ref carrying the focus channel: attach it to your input\n * element (`<input ref={field.focusRef} />`) so `setFocus` and a failed\n * submit's first-error auto-focus (`shouldFocusError`) can focus this\n * headless field — the same 'focusError' wiring `<Field>` performs for\n * its own input. Without it, focus requests aimed at this field are\n * silent no-ops, matching `setFocus`'s contract: focusing a field\n * whose element is not bound neither throws nor focuses anything.\n */\n focusRef: (el: any) => void;\n};\n\n/** Does `rules` declare any constraint? `messages` alone does not\n * validate anything, and a constraint-free object would otherwise compile\n * into a validator that always passes — which would still open debounce\n * windows and hold the validating mark for nothing. `validate` callbacks\n * count: they are the only constraint a validate-only rules object\n * carries. */\nfunction hasRuleConstraints(rules: FieldRules): boolean {\n return (\n rules.required !== undefined ||\n rules.min !== undefined ||\n rules.max !== undefined ||\n rules.minLength !== undefined ||\n rules.maxLength !== undefined ||\n rules.pattern !== undefined ||\n rules.validate !== undefined\n );\n}\n\n/**\n * Compose declarative rules with a user validator: rules run first, then\n * the user's validator (awaited when async), and the results merge into\n * one error list with rules errors ahead. Either side may be absent —\n * the other passes through untouched. Errors are returned as an array (or\n * undefined when both sides pass), which setErrorByPath stores as-is.\n */\nfunction combineRulesAndValidate(\n rules: FieldRules | undefined,\n validate: Validator | undefined\n): Validator | undefined {\n if (!rules || !hasRuleConstraints(rules)) return validate;\n const ruleValidator = rulesToValidator(rules);\n if (!validate) return ruleValidator;\n return (value, meta) => {\n // rulesToValidator's contract is FieldError[] | undefined; the wider\n // Validator union here is only its declared type.\n const ruleErrors = ruleValidator(value, meta) as FieldError[] | undefined;\n const merge = (\n other: string | FieldError | (string | FieldError)[] | undefined\n ): (string | FieldError)[] | undefined => {\n const list: (string | FieldError)[] = [...(ruleErrors ?? [])];\n if (Array.isArray(other)) list.push(...other);\n else if (other) list.push(other);\n return list.length ? list : undefined;\n };\n const result = validate(value, meta);\n return isPromise(result) ? result.then(merge) : merge(result);\n };\n}\n\n/**\n * Render-layer gating for {@link UseFieldOptions}.delayError: hold a newly\n * appearing error back for `delay` ms while the form's error state stays\n * immediate. Only the none → some transition waits — an error that clears\n * inside the window never shows, and once an error is visible, later\n * changes (a new message, entries added or removed) apply immediately.\n * With `delay === undefined` the subscription value passes through\n * untouched: no timers and no state writes, so fields that do not opt in\n * pay nothing beyond the hook calls themselves.\n */\nfunction useDelayedErrors(\n errors: FieldError[],\n delay: number | undefined\n): FieldError[] {\n const [shown, setShown] = useState<FieldError[]>(errors);\n useEffect(() => {\n if (delay === undefined) return;\n // Clearing is always immediate: an error cleared inside the window is\n // cancelled before ever showing, a shown one hides at once (errors is\n // the shared empty constant on this branch).\n if (errors.length === 0) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- 取消窗口是设计行为:清空必须立刻生效\n setShown(errors);\n return;\n }\n // Already showing an error: swaps and list changes apply at once.\n if (shown.length > 0) {\n setShown(errors);\n return;\n }\n // Appearing from none: wait out the window. The cleanup clears the\n // timer when errors change again or the field unmounts.\n const timer = setTimeout(() => setShown(errors), delay);\n return () => clearTimeout(timer);\n }, [errors, delay, shown]);\n return delay === undefined ? errors : shown;\n}\n\n/**\n * Value snapshot for {@link useFieldCore}. Controlled fields subscribe to\n * 'change' at their own path (leaf scope) and track the store live.\n * Uncontrolled fields instead pin the value read at mount: no change\n * subscription, so typing re-renders nothing while the store still carries\n * every write (getValues/submit/validation read it). Errors, touched,\n * disabled and validating stay subscribed, so state-driven re-renders\n * behave like react-hook-form's `register`. The pinned snapshot is\n * deliberately never refreshed — reset/setInitialValues do not push into\n * it (or into a `defaultValue`-bound DOM element).\n */\nfunction useFieldValue(form: Form, path: Path, uncontrolled: boolean): any {\n const snapshotRef = useRef<{has: boolean; value: any}>({\n has: false,\n value: undefined\n });\n const getter = useCallback(() => {\n if (!uncontrolled) return getValueByPath(form, path);\n if (!snapshotRef.current.has) {\n snapshotRef.current = {has: true, value: getValueByPath(form, path)};\n }\n return snapshotRef.current.value;\n }, [uncontrolled, form, path]);\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n uncontrolled\n ? () => {}\n : onPathEvent(form.emitter, 'change', path, 'leaf', invalidate),\n [uncontrolled, form.emitter, path]\n );\n return useWatchCore(subscribeFactory, getter);\n}\n\n/**\n * Shared core of {@link useField} and the per-instance hooks returned by\n * `createFormContext()`: identical behavior, but the form is resolved from\n * whichever Context instance is passed in instead of the module-level one.\n *\n * `form` is always handed to `useValidate` explicitly, and an explicit form\n * wins over `useValidate`'s own context read — so scoped contexts need no\n * changes there.\n */\nexport function useFieldCore<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n>(\n {\n form: f1,\n name,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateDeps,\n validateOnMount,\n delayError,\n disabled,\n uncontrolled,\n asyncAlways,\n mode: modeOption\n }: UseFieldOptions<TValues, TPath>,\n Context: Context<Form<any> | null>\n): UseFieldResult<TValues, TPath> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = f1 || contextForm;\n if (!form) throw new Error('no form provided');\n const path = usePath(name);\n\n // Seed initialValue during render, not in an effect: the first paint\n // (SSR included — effects never run on the server) must already carry\n // the value, so the write lands here — before the value subscription\n // below takes its first snapshot. The write is emit-free (see\n // seedValueByPath) because emitting while rendering is illegal; the\n // post-commit effect announces it. The `=== undefined` guard keeps user\n // input and committed values safe across re-renders and remounts.\n const seededRef = useRef(false);\n const seeded =\n initialValue !== undefined && getValueByPath(form, path) === undefined;\n if (seeded) {\n seedValueByPath(form, path, initialValue);\n // Sticky until the announce effect consumes it, so StrictMode's second\n // render (which sees the value already seeded) still announces once.\n seededRef.current = true;\n }\n useEffect(() => {\n // Dep-less on purpose: the seed can land on a later render too (a\n // setInitialValues/reset wiped it; the guard re-seeds), and the\n // announcement must follow every actual seed. The flag makes the\n // steady state a cheap check.\n if (!seededRef.current) return;\n seededRef.current = false;\n // Wake path-scoped subscribers that rendered before this field in an\n // earlier commit — their snapshots predate the seed. Same-commit\n // subscribers self-heal through useSyncExternalStore's post-subscribe\n // snapshot check, and subscribers that already saw the seeded value\n // re-read an unchanged snapshot and bail out.\n emitChangeByPath(form, path);\n });\n\n // Undeclared options are dropped on purpose: the return value carries\n // only the fields declared on UseFieldResult, so nothing rides it back\n // onto DOM elements through a component's prop spread.\n //\n // `required` splits off into useValidate's synchronous gate: it runs\n // immediately on every kick (never debounced) and, while it fails, the\n // debounced validator is skipped — the other rules and `validate` never\n // see an empty value. The remaining rules still compose with `validate`\n // inside the debounced validator.\n const restRules: FieldRules | undefined = rules\n ? {...rules, required: undefined}\n : undefined;\n useValidate(combineRulesAndValidate(restRules, validate), path, form, {\n debounce: validateDebounce,\n validateOnMount,\n asyncAlways: asyncAlways ?? form.asyncAlways,\n sync:\n rules && rules.required !== undefined\n ? rulesToValidator({required: rules.required})\n : undefined\n });\n\n // All errors of the field through one subscription; the array reference\n // is stable (stored array or shared empty constant), so consumers can\n // memo on it. delayError gates only this render-layer view of the list;\n // the stored list keeps driving the reValidateMode kicks inside the\n // core's user-change gate.\n const liveErrors = useFieldErrorsByPath(form, path);\n const errors = useDelayedErrors(liveErrors, delayError);\n const errorObject = errors[0];\n const error = errorObject?.message;\n const value = useFieldValue(form, path, !!uncontrolled);\n // isDirty is a value-derived flag: like the value itself, it stays live\n // only in controlled mode. Uncontrolled fields pin it at mount — a live\n // subscription here would re-render the field on every keystroke and\n // break the register-parity contract (typing re-renders nothing). The\n // live scoped channel for either mode is useIsFieldDirty. `validating`\n // is a non-value flag: it stays subscribed in both modes (like errors/\n // touched/disabled), matching its exact key with payload-less\n // broadcasts still syncing everything.\n const isDirty = useWatchCore(\n useCallback(\n (invalidate: () => void) =>\n uncontrolled\n ? () => {}\n : onPathEvent(form.emitter, 'change', path, 'leaf', invalidate),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- usePath memoizes the Path per key, so key pins the subscription like every path-scoped hook\n [form.emitter, path.key, uncontrolled]\n ),\n () => isFieldDirtyByPath(form, path)\n );\n const validating = useWatchCore(\n useCallback(\n (invalidate: () => void) =>\n onKeyEvent(form.emitter, 'validating', path.key, invalidate),\n [form.emitter, path.key]\n ),\n () => form.validating.has(path.key)\n );\n\n // The form-level disabled flag, subscribed so setDisabled re-renders\n // this field; the field's own option is OR-ed in on every render.\n const formDisabled = useWatch(form, 'disabled', () => form.disabled);\n\n // The user-change pipeline lives in the core: onChange forwards to\n // userChangeByPath (write + mode/reValidateMode-gated validation, the\n // matrix registered below through registerFieldMode), onBlur to\n // userBlur (touched marking + blur-side gate). The stage keeps the\n // handler identities stable across re-renders.\n const onChange = useStageFn((v: any) => userChangeByPath(form, path, v));\n const onBlur = useStageFn(() => userBlur(form, path));\n\n // Register this field's validation-mode override so path-based\n // user-change writes (changeValue / changeValueByPath) route through\n // the same gated core pipeline as a user typing into the field.\n // Two fields mounted at the same path compete for the slot last-wins:\n // from here on every user-change write gates on the latest mount's\n // mode. That is almost always a bug (a stray duplicate name, a remount\n // racing the old instance) — say so in DEV.\n useEffect(() => {\n const {token, displaced} = registerFieldMode(form, path, modeOption);\n if (__DEV__ && displaced) {\n // eslint-disable-next-line no-console -- the whole point of this branch\n console.warn(\n `react-f0rm: two fields are mounted at the same path ${path.key}. ` +\n `The latest mount's mode registration owns the slot, so changeValue ` +\n `writes gate on it and the earlier field's validation mode no ` +\n `longer applies. Use distinct names if both must stay mounted.`\n );\n }\n return () => unregisterFieldMode(form, path, token);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `path.key` on purpose: usePath memoizes the Path per key, so re-registering on key (not object identity) is enough\n }, [form, path.key, modeOption]);\n\n // Publish this field's validateDeps declaration so the dep fields'\n // change pipelines can find it (revalidateDependentsOnChange). Keyed on\n // the serialized dep list, so a re-render passing an equal inline array\n // does not churn the registry; a genuinely changed list re-registers.\n const depsKey = validateDeps?.length ? validateDeps.join('\\n') : undefined;\n useEffect(() => {\n if (!depsKey) return;\n const depKeys = validateDeps!.map(dep => createPath(dep).key);\n registerFieldValidateDeps(form, path.key, depKeys);\n return () => unregisterFieldValidateDeps(form, path.key, depKeys);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `depsKey` on purpose: depKeys derive from the same option value the key serializes\n }, [form, path.key, depsKey]);\n\n // The focus channel. 'focusError' carries the target's path key —\n // emitted by handleSubmit's failed round (the first error's key, gated\n // by shouldFocusError) and by setFocus (with an optional\n // {shouldSelect} second argument). Subscribing here rather than inside\n // <Field> means headless useField consumers get focus support by\n // attaching focusRef; <Field> merely forwards it through its merged\n // ref. The callback ref is identity-stable, so re-renders never detach\n // the element, and the null guard keeps unbound fields silent no-ops.\n const elementRef = useRef<any>(null);\n const focusRef = useCallback((el: any) => {\n elementRef.current = el;\n }, []);\n useEffect(\n () =>\n on(\n form.emitter,\n 'focusError',\n (key: string, options?: {shouldSelect?: boolean}) => {\n if (key !== path.key) return;\n const el = elementRef.current;\n if (!el || typeof el.focus !== 'function') return;\n el.focus();\n if (options?.shouldSelect && typeof el.select === 'function') {\n el.select();\n }\n }\n ),\n [form, path.key]\n );\n\n // Uncontrolled DOM sync: a payload-less 'change' means a bulk operation\n // (reset, setInitialValues) rewrote values without a React render, and\n // an uncontrolled field deliberately never subscribes to its own value\n // — so its DOM element would keep stale text. Write the store's value\n // straight into the element held by the focus channel (register-style:\n // no re-render — exactly how RHF's reset clears uncontrolled inputs).\n //\n // One listener per form, not per field: a per-field subscription would\n // add O(mounted fields) handler calls to every keystroke — breaking the\n // O(affected-fields) change contract the uncontrolled parity bench\n // measures. The shared listener returns on the first check for\n // payload-carrying emits (typing, setValue), so bulk operations pay one\n // iteration over the registered cells and keystrokes pay one branch.\n useEffect(() => {\n if (!uncontrolled) return;\n let entry = uncontrolledSyncRegistry.get(form);\n if (!entry) {\n const cells = new Map<string, () => {el: any; path: Path}>();\n const off = on(form.emitter, 'change', (changed?: Path) => {\n if (changed) return;\n for (const read of cells.values()) {\n const {el, path} = read();\n // File inputs cannot be assigned a value at all.\n if (!el || el.type === 'file') continue;\n const next = getValueByPath(form, path);\n const asString = next == null ? '' : String(next);\n if (el.value !== asString) el.value = asString;\n }\n });\n entry = {cells, off};\n uncontrolledSyncRegistry.set(form, entry);\n }\n entry.cells.set(path.key, () => ({el: elementRef.current, path}));\n return () => {\n entry!.cells.delete(path.key);\n if (entry!.cells.size === 0) {\n entry!.off();\n uncontrolledSyncRegistry.delete(form);\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `path.key` on purpose: usePath returns a stable Path per key, and the closure's `path` changes identity only when the key does\n }, [form, path.key, uncontrolled]);\n\n // Effective unmount behavior: the field's own option, falling back\n // to the form-level default, then to this library's historical\n // default (tombstone). The removal snapshots first and a setup that\n // immediately follows the cleanup (StrictMode's dev\n // setup→cleanup→setup cycle) restores it — see useUnmountRestore.\n const removalSnapshotRef = useRef<RemovedFieldSnapshot | null>(null);\n const teardownOnUnmount = useStageFn(() => {\n if ((shouldUnregister ?? form.shouldUnregister) === false) return;\n removalSnapshotRef.current = removeFieldForUnmount(form, path);\n });\n const restoreAfterStrictMode = useStageFn(() => {\n const snapshot = removalSnapshotRef.current;\n removalSnapshotRef.current = null;\n if (snapshot) restoreRemovedField(form, path, snapshot);\n });\n useUnmountRestore(teardownOnUnmount, restoreAfterStrictMode);\n\n return {\n form,\n value,\n error,\n errorObject,\n errors,\n isDirty,\n validating,\n onChange,\n onBlur,\n name: path.key,\n disabled: formDisabled || !!disabled,\n focusRef\n };\n}\n\nexport default function useField<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n>(options: UseFieldOptions<TValues, TPath>): UseFieldResult<TValues, TPath> {\n return useFieldCore(options, FormContext);\n}\n","import {useCallback, useContext, useEffect, useReducer, useRef} from 'react';\nimport type {Context} from 'react';\nimport {FormContext} from '../context';\nimport {getValueByPath, setValueByPath} from '../form';\nimport type {FieldError, Form, Name} from '../form';\nimport {removeFieldForUnmount, restoreRemovedField} from '../core/unmount';\nimport type {RemovedFieldSnapshot} from '../core/unmount';\nimport {rulesToValidator} from '../rules';\nimport type {FieldRules} from '../rules';\nimport {onPathEvent} from '../subscribe';\nimport {useFieldErrorsByPath} from './form';\nimport usePath from './path';\nimport useStage, {useStageFn, useUnmountRestore} from './stage';\nimport useValidate from './validate';\n\n/** Per-form row-id counter. A module-level counter would grow across\n * every form on the page — and, on the server, across requests (ids like\n * `_4701` after a day of SSR). Keyed weakly so it dies with the form. */\nconst idCounters = new WeakMap<Form, number>();\n\nfunction generateId(form: Form): string {\n const next = (idCounters.get(form) ?? 0) + 1;\n idCounters.set(form, next);\n return `_${next}`;\n}\n\n/**\n * Live `id -> index` tables shared between {@link useFieldArray} and\n * {@link useFieldArrayItem}: one ids array per (form, array key), keyed\n * weakly so it dies with the form. The array is the hook's own `idsRef`\n * reference (mutated in place by the movers), so items always read the\n * latest order without owning a subscription of their own.\n */\nconst arrayIdsRegistry = new WeakMap<Form, Map<string, string[]>>();\n\nfunction getArrayIds(form: Form, key: string): string[] | undefined {\n return arrayIdsRegistry.get(form)?.get(key);\n}\n\nfunction registerArrayIds(form: Form, key: string, ids: string[]): void {\n let registry = arrayIdsRegistry.get(form);\n if (!registry) {\n registry = new Map();\n arrayIdsRegistry.set(form, registry);\n }\n registry.set(key, ids);\n}\n\n/** Stable identity for the render-count reducer below: never recreated,\n * so the dispatch path stays referentially clean. */\nfunction bumpReducer(count: number): number {\n return count + 1;\n}\n\ntype FieldArrayItem<K extends string> = {id: string; index: number} & Record<\n K,\n string\n>;\n\n/** Options accepted by {@link useFieldArray} and the per-instance hook\n * returned by `createFormContext()`. */\nexport type UseFieldArrayOptions<K extends string = 'id'> = {\n name: Name;\n form?: Form;\n /**\n * Property name the stable row key is exposed under on each `fields`\n * entry (react-hook-form's `keyName`): defaults to `'id'`, a custom\n * name (e.g. `'key'`) avoids clashing with a row data field of the\n * same name. The underlying id is unchanged.\n */\n keyName?: K;\n /**\n * Declarative rules validated against the whole array value\n * (react-hook-form's `useFieldArray` `rules`): `required` fails on an\n * empty array, `minLength`/`maxLength` read the array's length. Checked\n * on submit and `trigger`, like every registered validator.\n */\n rules?: FieldRules;\n /**\n * Whether unmounting this array removes its branch. Defaults to the\n * form-level `shouldUnregister` — tombstone (drop values) like a bound\n * field's unmount; pass `false` to keep the values.\n */\n shouldUnregister?: boolean;\n};\n\nexport type UseFieldArrayResult<K extends string = 'id'> = {\n fields: FieldArrayItem<K>[];\n append: (value: any) => void;\n prepend: (value: any) => void;\n insert: (index: number, value: any) => void;\n remove: (index: number) => void;\n swap: (from: number, to: number) => void;\n move: (from: number, to: number) => void;\n replace: (values: any[]) => void;\n update: (index: number, value: any) => void;\n};\n\n/**\n * Shared core of {@link useFieldArray} and the per-instance hook returned by\n * `createFormContext()`: identical behavior, but the form is resolved from\n * whichever Context instance is passed in instead of the module-level one.\n */\nexport function useFieldArrayCore<K extends string = 'id'>(\n options: UseFieldArrayOptions<K>,\n Context: Context<Form<any> | null>\n): UseFieldArrayResult<K> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = options.form || contextForm;\n if (!form) throw new Error('no form provided');\n const keyName = (options.keyName ?? 'id') as K;\n const {rules, shouldUnregister} = options;\n const path = usePath(options.name);\n const idsRef = useRef<string[]>([]);\n\n const getArray = useCallback(\n (): any[] => getValueByPath(form, path) || [],\n [form, path]\n );\n\n const setArray = useCallback(\n (arr: any[]) => {\n setValueByPath(form, path, arr);\n },\n [form, path]\n );\n\n const computeFields = useCallback(() => {\n const arr = getArray();\n while (idsRef.current.length < arr.length) {\n idsRef.current.push(generateId(form));\n }\n while (idsRef.current.length > arr.length) {\n idsRef.current.pop();\n }\n return idsRef.current.map((id, index) => ({\n id,\n index,\n [keyName]: id\n })) as FieldArrayItem<K>[];\n }, [getArray, form, keyName]);\n\n // Subscribe to 'change' events scoped to this array's branch: the array\n // key itself, its ancestors (an ancestor write replaces what the leaf\n // read falls back to) and its descendants (item edits), so typing into\n // unrelated fields does not re-render the array component. Payload-less\n // 'change' emits (reset, setInitialValues) always sync, and a field\n // unmounting inside the branch fires through the descendant match. The\n // comma-separated key prefix comparison lives in onPathEvent,\n // which keeps lookalike sibling keys ('[\"tagsX\"]') from matching.\n const [fields, syncFields] = useReducer(\n computeFields,\n undefined,\n computeFields\n );\n useEffect(\n () => onPathEvent(form.emitter, 'change', path, 'branch', syncFields),\n [form.emitter, path]\n );\n\n // Publish the live ids array so per-item hooks (useFieldArrayItem) can\n // resolve id -> index. Registered during render — not only in an effect —\n // so items rendered in the same first paint, and on the server, already\n // resolve; the set is idempotent (same reference every render, the\n // movers mutate it in place, `replace` swaps it and the next render\n // re-registers). The effect mirrors the registration because StrictMode\n // exercises the cleanup path on mount (unsubscribe, un-register, re-run)\n // without a fresh render in between — without it the table would stay\n // empty and every item would resolve to -1. Unmount drops the entry\n // only while this hook still owns it; a second useFieldArray at the\n // same path competes for the slot last-wins, same as the field-mode\n // registration in useField.\n registerArrayIds(form, path.key, idsRef.current);\n useEffect(() => {\n registerArrayIds(form, path.key, idsRef.current);\n return () => {\n const registry = arrayIdsRegistry.get(form);\n if (registry?.get(path.key) === idsRef.current) registry.delete(path.key);\n };\n }, [form, path.key]);\n\n // Unmount behavior mirrors a bound field's: the effective\n // shouldUnregister (this hook's option, falling back to the form-level\n // default — tombstone unless the form opts into RHF's keep-the-value\n // semantics) decides whether the branch drops out of reads and\n // getValues(). Removing the branch also clears its\n // errors/touched/dirty entries. The snapshot/restore pair rides\n // useUnmountRestore so StrictMode's dev setup→cleanup→setup cycle does\n // not wipe the branch on mount while real unmounts stay synchronous.\n const removalSnapshotRef = useRef<RemovedFieldSnapshot | null>(null);\n const teardownOnUnmount = useStageFn(() => {\n if ((shouldUnregister ?? form.shouldUnregister) === false) return;\n removalSnapshotRef.current = removeFieldForUnmount(form, path);\n });\n const restoreAfterStrictMode = useStageFn(() => {\n const snapshot = removalSnapshotRef.current;\n removalSnapshotRef.current = null;\n if (snapshot) restoreRemovedField(form, path, snapshot);\n });\n useUnmountRestore(teardownOnUnmount, restoreAfterStrictMode);\n\n // Declarative array rules: `required` splits into the synchronous gate\n // (runs immediately on every kick, never debounced) exactly like\n // useField's rules; the remaining rules land as the debounced validator.\n useValidate(\n rules ? rulesToValidator({...rules, required: undefined}) : undefined,\n path,\n form,\n {\n sync:\n rules && rules.required !== undefined\n ? rulesToValidator({required: rules.required})\n : undefined\n }\n );\n\n const append = useStageFn((value: any) => {\n const arr = getArray();\n idsRef.current.push(generateId(form));\n setArray([...arr, value]);\n });\n\n const prepend = useStageFn((value: any) => {\n const arr = getArray();\n idsRef.current.unshift(generateId(form));\n setArray([value, ...arr]);\n });\n\n const insert = useStageFn((index: number, value: any) => {\n const arr = getArray();\n idsRef.current.splice(index, 0, generateId(form));\n const newArr = [...arr.slice(0, index), value, ...arr.slice(index)];\n setArray(newArr);\n });\n\n const remove = useStageFn((index: number) => {\n const arr = getArray();\n idsRef.current.splice(index, 1);\n const newArr = arr.filter((_: any, i: number) => i !== index);\n setArray(newArr);\n });\n\n const swap = useStageFn((from: number, to: number) => {\n const arr = getArray();\n [idsRef.current[from], idsRef.current[to]] = [\n idsRef.current[to],\n idsRef.current[from]\n ];\n const newArr = [...arr];\n [newArr[from], newArr[to]] = [newArr[to], newArr[from]];\n setArray(newArr);\n });\n\n const move = useStageFn((from: number, to: number) => {\n const arr = getArray();\n const [id] = idsRef.current.splice(from, 1);\n idsRef.current.splice(to, 0, id);\n const newArr = [...arr];\n const [item] = newArr.splice(from, 1);\n newArr.splice(to, 0, item);\n setArray(newArr);\n });\n\n // replace is a full swap (length may change), so every row is conceptually\n // a new row: regenerate all ids to remount them, mirroring how reset works.\n const replace = useStageFn((values: any[]) => {\n idsRef.current = values.map(() => generateId(form));\n setArray([...values]);\n });\n\n // update only overwrites one value, so the id at that index is kept and the\n // row does not remount. Out-of-bounds indices are a silent no-op — plain\n // assignment would instead punch sparse-array holes into the form state.\n const update = useStageFn((index: number, value: any) => {\n const arr = getArray();\n if (index < 0 || index >= arr.length) return;\n const newArr = [...arr];\n newArr[index] = value;\n setArray(newArr);\n });\n\n return {fields, append, prepend, insert, remove, swap, move, replace, update};\n}\n\nexport default function useFieldArray<K extends string = 'id'>(\n options: UseFieldArrayOptions<K>\n): UseFieldArrayResult<K> {\n return useFieldArrayCore(options, FormContext);\n}\n\n/**\n * The result of {@link useFieldArrayItem}. Mirrors the {@link useField}\n * return shape (`value`/`errors`/`error`) plus the row's `index` and\n * `name` (path key) so nested fields can build on it —\n * `useField({name: ['tags', item.index, 'label']})`.\n */\nexport type UseFieldArrayItemResult<TValue = any> = {\n value: TValue;\n /** Overwrite this row's value in place (same array-layer write as\n * `update(index, value)`: the row's id and position are kept). */\n setValue: (value: TValue) => void;\n /** Every error registered for the row's path, insertion order; the\n * shared empty constant while clean, so consumers can memo on it. */\n errors: FieldError[];\n /** First error's message — the display text — or undefined. */\n error: string | undefined;\n /** The row's current path key (JSON-stringified segments, e.g.\n * `[\"tags\",0]`); moves with the row across reorder/remove. */\n name: string;\n /** The row's current position in the array. `-1` while the row is being\n * removed (or when no useFieldArray is mounted at `name`): reads return\n * undefined and nothing writes the dangling path. */\n index: number;\n form: Form;\n};\n\n/**\n * Shared core of {@link useFieldArrayItem} and the per-instance hook\n * returned by `createFormContext()`: identical behavior, but the form is\n * resolved from whichever Context instance is passed in instead of the\n * module-level one.\n */\nexport function useFieldArrayItemCore<TValue = any>(\n options: {name: Name; id: string; form?: Form},\n Context: Context<Form<any> | null>\n): UseFieldArrayItemResult<TValue> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = options.form || contextForm;\n if (!form) throw new Error('no form provided');\n const {id} = options;\n const arrayPath = usePath(options.name);\n\n // --- snapshots: locate the row by its stable id through the array's\n // published ids table, then read its value from the array layer — the\n // same layer every useFieldArray operation and `setValue` below write,\n // so `value` and update/append/swap/… always agree with each other.\n const computeIndex = useCallback(\n () => getArrayIds(form, arrayPath.key)?.indexOf(id) ?? -1,\n [form, arrayPath.key, id]\n );\n const computeValue = useCallback(\n (index: number) => {\n const arr = getValueByPath(form, arrayPath);\n return Array.isArray(arr) ? arr[index] : undefined;\n },\n [form, arrayPath]\n );\n\n // Both are read synchronously during render (SSR included: no effect is\n // involved), and the last-rendered pair is mirrored into refs for the\n // subscription below. Writing own refs during render follows the same\n // pattern as `useStage`.\n const index = computeIndex();\n const value = computeValue(index) as TValue;\n const lastRef = useRef({index, value});\n lastRef.current = {index, value};\n\n // A render is scheduled only when the row's own view would change. The\n // subscription is 'leaf'-scoped on the array key: every useFieldArray\n // operation rewrites that key (payload-less broadcasts — reset,\n // setInitialValues — always fire), so this fires exactly when the row\n // order or the array can have moved, while a write to one item's leaf\n // path (`['tags', 1]`) never fires it. The comparison happens in the\n // listener — not through React's equal-state bailout, which act/test\n // environments do not honor — so an unchanged row never dispatches at\n // all and its component function never runs: append, update and\n // single-row edits leave untouched rows completely quiet, and a\n // whole-array rewrite re-renders only rows whose value reference (or\n // index) actually changed — the shallow copies keep untouched items'\n // references stable. Rows whose index migrates (remove/move/swap/\n // insert) re-render by design; computing `next` with the fresh index\n // means a row that moved but kept its value still bumps.\n const computeRef = useStage({computeIndex, computeValue});\n const [, bump] = useReducer(bumpReducer, 0);\n useEffect(\n () =>\n onPathEvent(form.emitter, 'change', arrayPath, 'leaf', () => {\n const {computeIndex: idx, computeValue: val} = computeRef.current;\n const nextIndex = idx();\n if (\n nextIndex !== lastRef.current.index ||\n !Object.is(val(nextIndex), lastRef.current.value)\n )\n bump();\n }),\n [form.emitter, arrayPath, computeRef]\n );\n\n // --- errors: stored per exact key, so this is the one place the row's\n // indexed path is needed. A removed row resolves to index -1: the\n // parent is about to unmount this component (its key left `fields`),\n // and until that commit lands the dangling key is inert — reads return\n // undefined/no errors and the `setValue` guard refuses to write. -1\n // also surfaces when no useFieldArray is mounted at `name`; pairing\n // the two hooks is the documented contract.\n const itemPath = usePath([...arrayPath.value, index]);\n const errors = useFieldErrorsByPath(form, itemPath);\n\n const setValue = useStageFn((v: TValue) => {\n if (index < 0) return;\n const arr = [...(getValueByPath(form, arrayPath) ?? [])];\n if (index >= arr.length) return;\n arr[index] = v;\n setValueByPath(form, arrayPath, arr);\n });\n\n return {\n value,\n setValue,\n errors,\n error: errors[0]?.message,\n name: itemPath.key,\n index,\n form\n };\n}\n\n/**\n * Subscribe to a single row of a {@link useFieldArray} field — the\n * per-item counterpart `useFieldArray` alone cannot offer. `useFieldArray`\n * subscribes to the whole branch, so any row's edit re-renders the\n * component holding the array (and, without memoization, every row);\n * `useFieldArrayItem` scopes what re-renders to one row identified by its\n * stable id: editing row K re-renders only row K's component, and a\n * whole-array rewrite re-renders only rows whose value reference actually\n * changed. Pair it with a `React.memo` row component that takes stable\n * props (`form`, `id`) so the array component's own re-render cannot drag\n * the rows along.\n *\n * Rows whose index migrates — remove/move/swap/insert reshuffles —\n * re-render by design: the row's path contains the index, exactly like\n * TanStack Form's per-field api. The win is single-row edits staying\n * single-row.\n *\n * Value reads and writes live on the array layer — the same layer every\n * `useFieldArray` operation touches — so `value`, `setValue` and\n * `update`/`append`/… always agree with each other.\n *\n * @param options `name` of the array (a useFieldArray must be mounted at\n * the same path — it publishes the id table), the row's `id` from\n * `fields[i].id`, and optionally an explicit `form`\n */\nexport function useFieldArrayItem<TValue = any>(options: {\n name: Name;\n id: string;\n form?: Form;\n}): UseFieldArrayItemResult<TValue> {\n return useFieldArrayItemCore(options, FormContext);\n}\n","import {createContext, createElement, useContext, type ReactNode} from 'react';\nimport {\n useFieldCore,\n type UseFieldOptions,\n type UseFieldResult\n} from './hooks/field';\nimport {\n useFieldArrayCore,\n useFieldArrayItemCore,\n type UseFieldArrayOptions,\n type UseFieldArrayResult,\n type UseFieldArrayItemResult\n} from './hooks/fieldArray';\nimport type {FieldRules} from './rules';\nimport type {Form} from './form';\nimport type {Name, PathSegments} from './path';\nimport type {FieldPath} from './types';\n\nexport const FormContext = createContext<Form<any> | null>(null);\n\nexport const FormProvider = FormContext.Provider;\n\n/**\n * Read the form from the module-level {@link FormContext}. Pass the values\n * shape — `useFormContext<Values>()` — to get a fully typed `Form<Values>`\n * headless API; the `any` default keeps untyped call sites compiling.\n *\n * For multiple forms in one subtree use {@link createFormContext} instead.\n *\n * @throws when no `<FormProvider>` is mounted above the call site.\n */\nexport function useFormContext<T extends Record<string, any> = any>(): Form<T> {\n const form = useContext(FormContext);\n if (!form) throw new Error('no form provided');\n return form;\n}\n\n/**\n * Create an isolated bundle of form-context bindings: its own React context\n * plus `useField` / `useFieldArray` / `useFieldArrayItem` /\n * `useFormContext` hooks that resolve their form from it.\n *\n * Why: the module-level {@link FormContext} works fine for a single form per\n * subtree, but nesting two forms (or reusing a component inside a different\n * form) makes them fight over one context. Calling this factory once per app\n * area — `const Ctx = createFormContext<Values>()` — fixes the value shape\n * (`Ctx.useField({name: 'user.name'})` gets its `name` constrained by\n * `FieldPath<Values>` and its `value` typed accordingly), so call sites stop\n * hand-writing generics, and each instance's Provider scopes a strictly\n * separate form. The bundle also carries its raw React context\n * (`Ctx.context`) so `<Form context={Ctx.context}>` can provide into it.\n */\nexport function createFormContext<TValues extends Record<string, any> = any>() {\n const Context = createContext<Form<TValues> | null>(null);\n\n // A `form`-prop wrapper instead of exposing Context.Provider directly:\n // callers shouldn't have to know about the raw `value` prop shape.\n function FormProvider({\n form,\n children\n }: {\n form: Form<TValues>;\n children: ReactNode;\n }): ReactNode {\n return createElement(Context.Provider, {value: form}, children);\n }\n\n function useFormContext(): Form<TValues> {\n const form = useContext(Context);\n if (!form) throw new Error('no form provided');\n return form;\n }\n\n function useField<\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n >(\n // The bare `{name: TPath}` member keeps `name` a direct inference site\n // for TPath instead of routing it through the mapped Omit type.\n // `form` is omitted on purpose — the form always comes from this\n // factory's own Context.\n options: {name: TPath} & Omit<UseFieldOptions<TValues, TPath>, 'form'>\n ): UseFieldResult<TValues, TPath> {\n return useFieldCore(options as UseFieldOptions<TValues, TPath>, Context);\n }\n\n function useFieldArray<K extends string = 'id'>(options: {\n name: FieldPath<TValues> | Name;\n keyName?: K;\n rules?: FieldRules;\n shouldUnregister?: boolean;\n }): UseFieldArrayResult<K> {\n return useFieldArrayCore(options as UseFieldArrayOptions<K>, Context);\n }\n\n function useFieldArrayItem<TValue = any>(options: {\n name: FieldPath<TValues> | Name;\n id: string;\n }): UseFieldArrayItemResult<TValue> {\n return useFieldArrayItemCore(options as {name: Name; id: string}, Context);\n }\n\n // The raw React context, for `<Form context={...}>`: the component keeps\n // its submit machinery while providing into this instance's private\n // context, so the bound hooks above resolve the form it manages.\n return {\n context: Context,\n FormProvider,\n useFormContext,\n useField,\n useFieldArray,\n useFieldArrayItem\n };\n}\n\nexport const CheckboxGroupContext = createContext<any>(null);\n\nexport const CheckboxGroupProvider = CheckboxGroupContext.Provider;\n\nexport function useCheckboxGroupContext(): any {\n const group = useContext(CheckboxGroupContext);\n if (!group) throw new Error('no group provided');\n return group;\n}\n","/**\n * Server-side validation entry — `react-f0rm/server`.\n *\n * The core (`./form`) is pure TypeScript with zero React imports, so it\n * already runs anywhere Node does; what the server lacked is an entry\n * that never pulls React into the module graph at all — the main entry\n * re-exports the hooks/components, and a Server Action or RSC that only\n * wants to check a payload should not have to depend on them. This module\n * is that entry: values in, one whole-form validation round, structured\n * result out.\n *\n * It plays the role TanStack Form gives `createServerValidate`, minus the\n * action prop: their API wraps validation inside a generated server\n * action, while react-f0rm keeps the values store the single source of\n * truth — {@link validateValues} is a plain function over values (the\n * same contract the client-side `trigger` has over a form instance), so\n * it composes into any server framework's handler instead of owning it.\n *\n * Like the resolvers and devtools it is intentionally NOT re-exported\n * from the main entry: importing `react-f0rm/server` is the only way this\n * code reaches a bundle, so client builds that never validate on the\n * server stay at baseline size.\n */\nimport createForm, {getErrors, getValues, trigger} from './form';\nimport type {FieldErrorEntry, Options, ValidationOutcome} from './form';\n\n// Building a branded ValidationOutcome server-side (schema adapters, or a\n// hand-written validate that returns parsed values) needs the brand symbol\n// itself; importing it from the package root would drag the React graph\n// back in, so it is re-exported here together with its result type.\nexport {VALIDATION_OUTCOME} from './form';\nexport type {ValidationOutcome};\n\n/** The outcome of {@link validateValues}: the error-free flag, the values\n * once the round has landed (schema-coerced where the validator produced\n * parsed values), and every error the round wrote as flat entries. */\nexport type ValidateValuesResult<T extends Record<string, any> = any> = {\n /** Whether the round landed no errors — `trigger`'s boolean. An invalid\n * payload is a normal outcome, never a rejection: unlike\n * `ensureValidate`, server callers learn validity from data instead of\n * catching, because both branches are interesting on the server\n * (persist vs. bounce back to the client). */\n valid: boolean;\n /** The values after the round. When the validator returned a branded\n * {@link ValidationOutcome} with `values`, those parsed values are the\n * baseline `getValues` layers over the input — schema coerce/transform\n * output included — so this is the tree to persist or feed onward, not\n * necessarily the object passed in. Deep-equals the input otherwise. */\n values: T;\n /** Every error the round landed, flattened to `{path, type, message}`\n * entries — the same list {@link getErrors} hands out on the client.\n * Feed it to `setServerErrors` to land a failed round back on the\n * client form (the Server Actions bridge; see the docs' Server Actions\n * guide). */\n errors: FieldErrorEntry[];\n};\n\n/** Append one value under `key` into `fd`. Arrays and FileLists flatten\n * to one entry per item (FormData's multi-entry convention); Files keep\n * their name; Dates become ISO strings; other objects JSON.stringify;\n * booleans/numbers/strings String() as a native form submit would. */\nfunction appendFormDataValue(fd: FormData, key: string, value: any): void {\n if (value == null) return;\n if (Array.isArray(value)) {\n for (const item of value) appendFormDataValue(fd, key, item);\n return;\n }\n if (typeof FileList !== 'undefined' && value instanceof FileList) {\n for (let i = 0; i < value.length; i++) fd.append(key, value.item(i)!);\n return;\n }\n if (typeof File !== 'undefined' && value instanceof File) {\n fd.append(key, value, value.name);\n return;\n }\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n fd.append(key, value);\n return;\n }\n if (value instanceof Date) {\n fd.append(key, value.toISOString());\n return;\n }\n fd.append(\n key,\n typeof value === 'object' ? JSON.stringify(value) : String(value)\n );\n}\n\n/**\n * Convert a values object into FormData — the transport shape React 19\n * Server Actions and multipart handlers expect. Built to pair with the\n * `<Form action>` prop and `validateValues`: the validated (schema-coerced)\n * values tree lands in the server action as FormData, files included.\n *\n * Array values become multiple entries under the same key (FormData's\n * native multi-value convention); File values keep their name; Dates\n * become ISO strings; plain objects JSON.stringify; null/undefined are\n * skipped.\n */\nexport function formDataFromValues(values: Record<string, any>): FormData {\n const fd = new FormData();\n for (const key of Object.keys(values)) {\n appendFormDataValue(fd, key, values[key]);\n }\n return fd;\n}\n\n/**\n * Validate a payload of values on the server — no form instance, no\n * React.\n *\n * Spins up a throwaway form from `options` (with `initialValues` forced\n * to `values`), runs one whole-form `trigger`, and reads the outcome\n * back. `trigger` never rejects and waits out async validators and any\n * `validateDebounce` window, so a single `await` drains the whole round —\n * the returned `valid`/`errors` are final, not a snapshot mid-flight.\n *\n * Validation comes from `options.validate` — the form-level validator.\n * Field validators register through mounted fields (`useField`), and\n * nothing is mounted on the server, so they cannot participate by\n * construction; pass a schema-backed form validator\n * (`standardSchemaFormValidator(schema)` from\n * `react-f0rm/resolvers/standard-schema`) or a hand-written `validate`\n * instead. `mode`/`reValidateMode` are equally inert here — there are no\n * field events to gate — and may be omitted.\n *\n * When the validator returns a branded {@link ValidationOutcome} whose\n * `values` carry the schema's output, those parsed values become the\n * form's parsedValues baseline, so `result.values` flows coercion and\n * transforms forward (`z.coerce.number()` turning `'42'` into `42`, and\n * friends). Persist that tree; on the client the same schema round runs\n * again on submit, keeping one validation source across the boundary.\n *\n * Safe to call from Node, Server Actions and RSC — the module graph is\n * this file plus the pure core, zero React.\n *\n * @param values the payload to validate; becomes the form's initialValues\n * @param options form options; `validate` is where the rules come from\n * @return the settled round: `valid`, the (possibly parsed) values, and\n * the flat error entries\n */\nexport async function validateValues<T extends Record<string, any> = any>(\n values: T,\n options?: Options<T>\n): Promise<ValidateValuesResult<T>> {\n const form = createForm({...options, initialValues: values});\n const valid = await trigger(form);\n return {valid, values: getValues(form), errors: getErrors(form)};\n}\n","import * as React from 'react';\nimport useField from '../hooks/field';\nimport type {Validator} from '../hooks/validate';\nimport type {Form, ValidationMode} from '../form';\nimport {rulesToConstraintAttrs} from '../rules';\nimport type {FieldRules} from '../rules';\nimport type {Name, Path, PathSegments} from '../path';\nimport createPath from '../path';\nimport type {FieldPath, PathValueOf} from '../types';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/**\n * Props shared by Field/Checkbox/Select. Generic so a typed form flows into\n * the `validate` callback: with `form` (a `Form<Values>`) and `name`\n * (a `FieldPath<Values>`) provided, `validate` receives the value at that\n * path — `PathValueOf<Values, P>` — instead of `any`. The defaults keep the\n * bare `<Field name=\"x\" />` (context-resolved, untyped) call sites exactly\n * as permissive as before.\n */\ntype UseFieldOptions<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = {\n form?: Form<TValues>;\n name?: TPath;\n initialValue?: any;\n shouldUnregister?: boolean;\n /**\n * Field-level validator. The value argument is typed when the field is\n * tied to a typed form (via the `form` prop); the return shape mirrors\n * {@link Validator} — an error (string / FieldError / mixed array) or\n * undefined when valid, possibly a Promise for async validation. The\n * second argument carries the validation context (`meta.signal` aborts\n * when the round is superseded).\n */\n validate?: (\n value: PathValueOf<TValues, TPath>,\n meta: {form: Form; path: Path; signal: AbortSignal}\n ) => ReturnType<Validator>;\n /**\n * Declarative rules (required/min/max/minLength/maxLength/pattern,\n * plus custom `validate` callbacks), compiled into a validator that\n * runs before `validate`; failures land in the form's error state.\n * The declarative subset is also rendered as native constraint\n * attributes (`required`, `minLength`, `pattern`, …) onto the element\n * for browser/AT hints — `:invalid` styling, screen-reader\n * announcements — while the store pipeline stays the source of truth\n * for messages (`renderError`/`aria-invalid` keep working; a user-passed\n * `required`/`pattern`/… prop overrides the derived attribute). Passed\n * through to useField — like validateDebounce it is never spread onto\n * the DOM element.\n */\n rules?: FieldRules;\n /**\n * Milliseconds to debounce this field's validation kicks. Defaults to 0\n * (validate immediately); only the last kick inside the window runs the\n * validator, and `trigger` waits the window out. Passed through to\n * useField/useValidate.\n */\n validateDebounce?: number;\n /**\n * Run this field's debounced validator even when its `required` gate\n * failed (TanStack Form's `asyncAlways`): the gate's errors land\n * immediately, the validator's own result lands alongside them\n * per-source. Falls back to the form-level `createForm({asyncAlways})`.\n * Passed through to useField.\n */\n asyncAlways?: boolean;\n /**\n * Validate this field once on mount (see {@link\n * UseFieldOptions}' `validateOnMount`): overrides the form-level\n * `createForm({validateOnMount})` / `<Form validateOnMount>` flag in\n * either direction. Passed through to useField.\n */\n validateOnMount?: boolean;\n /**\n * Disable this field's control: OR-ed with the form-level flag\n * (`createForm({disabled})` / `setDisabled`) — a field cannot opt out\n * of a disabled form. Passed through to useField, like every option,\n * never spread onto the DOM element from props.\n */\n disabled?: boolean;\n /**\n * Milliseconds to delay showing a newly appearing error (render layer\n * only — `aria-invalid`/`renderError` wait out the window while the\n * form's error state stays immediate for trigger/submit). An error\n * that clears inside the window never shows; once visible, error\n * changes apply immediately. Passed through to useField.\n */\n delayError?: number;\n /**\n * Field-level validation mode override: this field validates on its own\n * schedule instead of the form's `mode` (other fields are unaffected);\n * the form's `reValidateMode` still governs re-validation once the\n * field has an error. Passed through to useField, never spread onto\n * the DOM element.\n */\n mode?: ValidationMode;\n /**\n * Uncontrolled mode: render the element with `defaultValue` instead of\n * `value` — typing re-renders nothing (the store still carries every\n * write; errors/touched/disabled still re-render the field). The\n * snapshot is pinned at mount; bulk operations (reset/setInitialValues)\n * sync the DOM element directly without a render — RHF-register\n * behavior (read live values with useValue/getValues). Passed through\n * to useField, never spread onto the DOM element.\n */\n uncontrolled?: boolean;\n [key: string]: any;\n};\n\ntype FieldProps<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = UseFieldOptions<TValues, TPath> & {\n as?: React.ComponentType<any>;\n asProps?: Record<string, any>;\n eventToValue?: (e: any) => any;\n valueToProps?: (value: any) => Record<string, any>;\n /**\n * Optional error renderer. When provided and the field has an error,\n * Field renders `<span id={id} role=\"alert\">{renderError(error, id)}</span>`\n * next to the input. The input's aria-describedby points at that span's\n * id (the same `fieldErrorId(name)` derivation) whenever the field has\n * an error — with or without renderError — so custom error components\n * that render the element themselves (using `fieldErrorId`) get the\n * wiring for free.\n */\n renderError?: (error: string, id: string) => React.ReactNode;\n /**\n * Store `e.target.valueAsNumber` instead of the string value —\n * react-hook-form's `register({valueAsNumber})` counterpart for number\n * inputs (`<input type=\"number\">`). `NaN` passes through as-is when the\n * input cannot be parsed, matching RHF. An explicit `eventToValue`\n * takes precedence.\n */\n valueAsNumber?: boolean;\n /**\n * Store `e.target.valueAsDate` instead of the string value — RHF's\n * `register({valueAsDate})` counterpart for date/time inputs. `null`\n * passes through when the input cannot be parsed. An explicit\n * `eventToValue` takes precedence; combining with `valueAsNumber` is a\n * TypeError.\n */\n valueAsDate?: boolean;\n};\n\nfunction setRef<T>(ref: React.Ref<T> | undefined, value: T | null) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref) {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n}\n\n/**\n * Converts a path key (the JSON.stringify'd path segments, e.g. '[\"a\",\"0\"]')\n * into a valid HTML id ('a-0'): quotes, brackets, commas and whitespace\n * become hyphens; leading/trailing hyphens are trimmed. Falls back to\n * 'field' if nothing remains.\n */\nfunction errorIdFromKey(key: string): string {\n const id = key.replace(/[\"'[\\],\\s]+/g, '-').replace(/^-+|-+$/g, '');\n return id || 'field';\n}\n\n/**\n * The aria wiring every bound field shares: `aria-invalid` when the field\n * has an error, and `aria-describedby` pointing at the error-message\n * element id derived from the field key — the same id `fieldErrorId(name)`\n * derives (the key is what useField returns as `name`). User-provided ids\n * survive, joined ahead of the error id.\n */\nfunction ariaProps(\n error: string | undefined,\n fieldKey: string,\n props: Record<string, any>\n) {\n return {\n 'aria-invalid': error ? true : props['aria-invalid'],\n 'aria-describedby': error\n ? [props['aria-describedby'], errorIdFromKey(fieldKey)]\n .filter(Boolean)\n .join(' ')\n : props['aria-describedby']\n };\n}\n\n/**\n * The error-message element id a field's `aria-describedby` points at —\n * `fieldErrorId('a[0].b')` is `'a-0-b'`, the same id `Field`'s built-in\n * `renderError` span carries. This is the library-level wiring convention:\n * whenever a bound field (Field/Checkbox/Select) has an error it sets\n * `aria-invalid` and describes the element with this id, so a custom error\n * component only needs `<span id={fieldErrorId(name)} role=\"alert\">` to\n * complete the accessible-name chain for screen readers.\n * @param name the same field name passed to the bound component\n */\nexport function fieldErrorId(name: Name): string {\n return errorIdFromKey(createPath(name).key);\n}\n\n/**\n * The callable shape of {@link Field}: `form` + `name` flow their generics\n * into `validate`'s value argument (`PathValueOf<TValues, TPath>`). A named\n * interface rather than an inline `as <TValues, ...>() => ...` signature —\n * same types, and the inline form trips no-use-before-define on the type\n * parameters.\n */\ntype FieldComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n >(\n props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>\n ): React.ReactElement | null;\n};\n\nexport const Field = React.forwardRef<HTMLInputElement, FieldProps>(\n (\n {\n validate,\n eventToValue,\n initialValue,\n name,\n asProps,\n renderError,\n as,\n valueToProps,\n form: formProp,\n shouldUnregister,\n rules,\n validateDebounce,\n validateOnMount,\n valueAsNumber,\n valueAsDate,\n asyncAlways,\n disabled,\n delayError,\n mode,\n uncontrolled,\n ...props\n },\n ref\n ) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const [nativeInvalidCount, setNativeInvalidCount] = React.useState(0);\n // Only declared options go into the hook; DOM props stay in `props` and\n // are spread onto the element below — useField no longer echoes unknown\n // options back, so `as`/`valueToProps`/DOM props are destructured here\n // instead of being fished out of its result.\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled,\n focusRef\n } = useField({\n name: name!,\n form: formProp,\n initialValue,\n shouldUnregister,\n rules,\n validateDebounce,\n validateOnMount,\n delayError,\n disabled,\n asyncAlways,\n mode,\n // File inputs cannot be value-controlled at all — force the\n // uncontrolled path so no `value` prop ever reaches the element.\n uncontrolled: uncontrolled || props.type === 'file',\n validate: (...params: [any, any]) => {\n const el = innerRef.current;\n if (el && typeof el.checkValidity === 'function') {\n el.setCustomValidity('');\n if (el.checkValidity() === false) {\n setNativeInvalidCount(count => count + 1);\n return undefined;\n }\n }\n if (validate) return validate(...params);\n }\n });\n // One merged ref, three duties: the private innerRef (validate's\n // setCustomValidity above), the focus channel (useField's focusRef —\n // setFocus and a failed submit's shouldFocusError focus through it),\n // and the user's forwarded ref. focusRef is identity-stable, so the\n // deps behave exactly as the previous [ref] did.\n const mergedRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n focusRef(node);\n setRef(ref, node);\n },\n [ref, focusRef]\n );\n const Component = as || 'input';\n\n React.useEffect(() => {\n const el = innerRef.current;\n if (!el || typeof el.setCustomValidity !== 'function') return;\n if (typeof error === 'string') {\n el.setCustomValidity(error);\n el.reportValidity();\n } else {\n el.setCustomValidity('');\n }\n }, [error]);\n\n React.useEffect(() => {\n if (nativeInvalidCount > 0) innerRef.current?.reportValidity();\n }, [nativeInvalidCount]);\n\n const isFile = props.type === 'file';\n if (__DEV__ && valueAsNumber && valueAsDate) {\n // eslint-disable-next-line no-console -- dev-only diagnostics\n console.warn(\n 'react-f0rm: valueAsNumber and valueAsDate are mutually exclusive — ' +\n 'valueAsNumber wins. Use eventToValue for anything else.'\n );\n }\n const toValue =\n eventToValue ??\n (isFile\n ? (e: any) => e.target.files\n : valueAsNumber\n ? (e: any) => e.target.valueAsNumber\n : valueAsDate\n ? (e: any) => e.target.valueAsDate\n : (e: any) => e.target.value);\n\n // file inputs never receive a value/defaultValue prop (they cannot be\n // value-controlled); uncontrolled renders defaultValue, controlled\n // renders value.\n const valueProps = valueToProps\n ? valueToProps(value)\n : isFile\n ? {}\n : uncontrolled\n ? {defaultValue: value}\n : {value};\n\n // fieldKey is the field's path key (set by useField), e.g. '[\"a\",\"0\"]'.\n const errorId = errorIdFromKey(fieldKey);\n // Declarative rules → native constraint attributes for browser/AT\n // hints (:invalid styling, screen-reader announcements). Spread\n // before `props` so a user-passed required/minLength/pattern always\n // wins over the derived one. The store pipeline keeps owning\n // messages: rules run ahead of the wrapper below, so their errors\n // land in the form state (renderError/aria-invalid) even when the\n // native checkValidity gate now also sees the derived attrs and\n // skips the user's `validate` for that kick (RHF first-error\n // semantics).\n const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : undefined;\n\n return (\n <>\n <Component\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n {...asProps}\n {...valueProps}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n onChange={(e: any) => onChange(toValue(e))}\n ref={mergedRef}\n />\n {error && renderError ? (\n <span id={errorId} role=\"alert\">\n {renderError(error, errorId)}\n </span>\n ) : null}\n </>\n );\n }\n) as FieldComponent;\n\ntype CheckboxProps<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = UseFieldOptions<TValues, TPath>;\n\n/**\n * Callable shape of {@link Checkbox}: the same form-typed `validate`\n * inference contract as {@link FieldComponent}.\n */\ntype CheckboxComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n >(\n props: CheckboxProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>\n ): React.ReactElement | null;\n};\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n name,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n disabled,\n delayError,\n mode,\n ...props\n },\n ref\n ) => {\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled\n } = useField({\n name: name!,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n delayError,\n disabled,\n mode\n });\n // Same error-id convention as Field: the checkbox describes the\n // fieldErrorId(name) element whenever it has an error.\n const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : undefined;\n return (\n <input\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n type=\"checkbox\"\n checked={!!value}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n onChange(e.target.checked)\n }\n ref={ref}\n />\n );\n }\n) as CheckboxComponent;\n\ntype SelectProps<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = UseFieldOptions<TValues, TPath> & {\n multiple?: boolean;\n children?: React.ReactNode;\n};\n\n/**\n * Controlled <select>. Options are passed as children (<option> elements).\n * Single-select stores the selected option's value as a string, matching\n * Field's default event-to-value behavior; a multiple select stores the\n * values of all selected options as a string array.\n */\n/** Normalize a field value for a <select>: multiple wants a string array,\n * single-select wants a string. */\nfunction toSelectValue(\n multiple: boolean | undefined,\n value: any\n): string | string[] {\n if (multiple) return Array.isArray(value) ? value : [];\n return value ?? '';\n}\n\n/**\n * Callable shape of {@link Select}: the same form-typed `validate`\n * inference contract as {@link FieldComponent}.\n */\ntype SelectComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n >(\n props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>\n ): React.ReactElement | null;\n};\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n (\n {\n name,\n multiple,\n children,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n disabled,\n delayError,\n mode,\n ...props\n },\n ref\n ) => {\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled\n } = useField({\n name: name!,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n delayError,\n disabled,\n mode\n });\n // Same error-id convention as Field: the select describes the\n // fieldErrorId(name) element whenever it has an error.\n const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : undefined;\n return (\n <select\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n multiple={multiple}\n value={toSelectValue(multiple, value)}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n onChange(\n multiple\n ? Array.from(e.target.selectedOptions, option => option.value)\n : e.target.value\n )\n }\n ref={ref}\n >\n {children}\n </select>\n );\n }\n) as SelectComponent;\n","import * as React from 'react';\nimport {handleSubmit, setDisabled} from '../form';\n// 别名规避 rollup-plugin-dts 对「type import 与本地 default export 同名」\n// 的 Identifier already declared 误报(类型引用语义不变)。\nimport type {Form as FormApi} from '../form';\nimport {formDataFromValues} from '../server';\nimport {FormContext} from '../context';\nimport useForm from '../hooks/form';\n\n/**\n * Props for <Form>.\n *\n * Native validation behavior: the rendered <form> always sets noValidate,\n * which suppresses the browser's built-in blocked-submit UI. However, native\n * constraint validation still gates submission — the form element's\n * checkValidity() runs before custom validators, and when it fails,\n * reportValidity() surfaces the offending constraints as native bubbles and\n * submission stops (onInvalidSubmit fires). onSubmit/onValidSubmit only run\n * once every native constraint (required, type=email, minLength, ...) passes.\n *\n * The submit flow itself lives in the headless `handleSubmit` (see form.ts);\n * this component is a thin wrapper that binds it to the rendered <form>.\n */\ntype FormProps<T extends Record<string, any> = any> = Omit<\n React.FormHTMLAttributes<HTMLFormElement>,\n 'onSubmit'\n> & {\n form?: FormApi<T>;\n /**\n * Provide into an isolated context from `createFormContext()` instead of\n * the module-level one — `<Form context={ProfileForm.context}>` keeps the\n * component's full submit machinery while the factory's bound hooks\n * (`ProfileForm.useField`, `ProfileForm.useFormContext`, ...) resolve this\n * form from their private context. The module-level `useFormContext()` /\n * `useField` do not see it; that is the point of the isolation. Omitted,\n * the form lands in the module-level FormContext as before.\n */\n context?: React.Context<FormApi<any> | null>;\n /**\n * The values baseline — a sync object, a Promise, or a thunk returning\n * either ({@link Options.initialValues}). Async sources render the form\n * empty and gate on `form.isLoading` until they resolve.\n */\n initialValues?: T | Promise<T> | (() => T | Promise<T>);\n /**\n * Form-level default for a bound field's unmount behavior\n * ({@link Options.shouldUnregister}): `true` (the default) tombstones\n * unmounted fields, `false` keeps their values.\n */\n shouldUnregister?: boolean;\n /**\n * Validate on mount (see {@link Options.validateOnMount}): every\n * mounted field with a validator kicks once after mount and the\n * form-level `validate` (if any) runs once. A field's own\n * `validateOnMount` prop overrides this flag.\n */\n validateOnMount?: boolean;\n /**\n * Disable every bound field: the form-level flag fields OR with their\n * own `disabled` option (a field cannot opt out). Seeded at create and\n * kept in sync while this prop changes (undefined leaves the current\n * flag untouched — toggle at runtime with `setDisabled`).\n */\n disabled?: boolean;\n /**\n * Form-level default for field validation's `asyncAlways`: a field\n * whose `required` gate failed still runs its debounced validator, its\n * result landing per-source alongside the gate's errors. A field's own\n * `asyncAlways` prop overrides this flag.\n */\n asyncAlways?: boolean;\n /**\n * Controlled external values. When the `values` reference changes, the\n * new object is synced into the form (via setInitialValues semantics):\n * uncommitted user edits are discarded -- master-detail semantics, where\n * selecting another record replaces the draft -- while touched flags and\n * errors are kept. Sync is reference-based: re-renders that pass the same\n * `values` reference never clobber what the user is typing.\n */\n values?: T;\n /** May be async — the submit flow awaits it, so form.isSubmitting\n * covers the entire flight. */\n onSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;\n /** May be async, same as onSubmit. */\n onValidSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;\n /**\n * React 19 Server Action target: after validation passes (and after\n * onSubmit/onValidSubmit), the validated, schema-coerced values are\n * converted to FormData ({@link formDataFromValues} — files, arrays and\n * nested objects included) and dispatched to this callback, e.g.\n * `action={createUser}` for a server action or\n * `action={formData => startTransition(() => dispatch(formData))}` in a\n * useActionState bridge. `isSubmitting` covers the whole flight.\n */\n action?: (formData: FormData) => void | Promise<void>;\n /**\n * Called when validation fails.\n * @param errors array of {path, type, message} entries in insertion\n * order; path is the dotted field path ('a.b', 'list.0'), type is\n * the error kind ('custom' for plain string errors, 'native' for\n * failed DOM constraint validation), message is the display text\n * @param values current form values\n */\n onInvalidSubmit?: (\n errors: {path: string; type: string; message: string}[],\n values: T\n ) => void;\n /**\n * Focus the first field with an error after a failed submit: custom\n * validation failures focus the first errored field, native constraint\n * failures focus the first ':invalid' control. Defaults to true; pass\n * false to disable.\n */\n shouldFocusError?: boolean;\n};\n\nexport default function Form<T extends Record<string, any> = any>({\n form: f1,\n context,\n initialValues,\n values,\n shouldUnregister,\n validateOnMount,\n disabled,\n asyncAlways,\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n action,\n shouldFocusError,\n ...props\n}: FormProps<T>) {\n const f2 = useForm<T>({\n initialValues,\n values,\n shouldUnregister,\n validateOnMount,\n disabled,\n asyncAlways\n });\n const form = f1 || f2;\n\n // The form instance outlives prop changes (useForm creates it once), so\n // a changing `disabled` prop re-applies through the runtime channel —\n // the same `setDisabled` consumers toggle imperatively. undefined means\n // \"not controlled here\": leave the flag as-is.\n React.useEffect(() => {\n if (disabled !== undefined) setDisabled(form, disabled);\n }, [form, disabled]);\n\n const submit = handleSubmit(form, {\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n shouldFocusError,\n onAction: action ? values => action(formDataFromValues(values)) : undefined\n });\n\n // Route the form into the caller's isolated context (createFormContext)\n // or the module-level default, whichever Provider we ended up with.\n const {Provider} = context ?? FormContext;\n\n return (\n <Provider value={form}>\n <form {...props} noValidate onSubmit={submit} />\n </Provider>\n );\n}\n","import * as React from 'react';\nimport useField from '../hooks/field';\nimport type {UseFieldOptions, UseFieldResult} from '../hooks/field';\nimport type {FieldPath} from '../types';\nimport type {PathSegments} from '../path';\n\n/**\n * Props for {@link FormField}: every {@link UseFieldOptions} option plus a\n * render-prop `children` receiving the bound field result.\n */\nexport type FormFieldProps<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n> = UseFieldOptions<TValues, TPath> & {\n children: (field: UseFieldResult<TValues, TPath>) => React.ReactNode;\n};\n\n/**\n * Headless field bound through a render prop — the non-hook counterpart of\n * {@link useField} for class components, callback-style consumers and\n * library bridges where a hook cannot be called (Formik `<Field>` /\n * TanStack `form.Field` shape).\n *\n * The child function receives the full {@link UseFieldResult} — value,\n * error(s), onChange/onBlur, `disabled`, `focusRef`, the bound `form` —\n * and renders whatever UI it wants; nothing is rendered when it returns\n * null/undefined, so it can also gate conditional layout. Resolves its\n * form from the module-level `FormContext` or the explicit `form` option\n * (per-instance contexts from `createFormContext()` keep using their own\n * `useField` hook).\n */\nexport default function FormField<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments\n>({children, ...options}: FormFieldProps<TValues, TPath>): React.ReactNode {\n const field = useField<TValues, TPath>(options);\n return children(field);\n}\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name} from '../path';\nimport type {Form} from '../form';\n\n/** Options accepted by {@link setFocus}. All flags default to `false`. */\nexport type SetFocusOptions = {\n /** Select the field's text after focusing it. Bound fields call\n * `select()` on their element; elements without one (custom `as`\n * components) just focus. */\n shouldSelect?: boolean;\n};\n\n/**\n * Programmatically focus a bound field's element (e.g. the <Field>'s\n * input).\n *\n * Rides the same 'focusError' event channel a failed handleSubmit uses to\n * focus the first errored field: the payload is the target's path key,\n * with the focus options as a second, backward-compatible argument (older\n * subscribers declared with a single `key` parameter simply ignore it).\n * Being event-driven, it is a silent no-op when the field is unmounted or\n * nothing subscribes — unknown names never throw.\n *\n * @param form form instance\n * @param name field name (dot path or segments path)\n * @param options focus options\n */\nexport function setFocus(\n form: Form,\n name: Name,\n options?: SetFocusOptions\n): void {\n const {key} = createPath(name);\n // Omit the options argument when absent so the payload is exactly the\n // shape handleSubmit emits after a failed submit.\n if (options) emit(form.emitter, 'focusError', key, options);\n else emit(form.emitter, 'focusError', key);\n}\n","import {useCallback} from 'react';\nimport {getValueByPath, userChangeByPath} from '../form';\nimport type {Form} from '../form';\nimport type {PathSegments} from '../path';\nimport type {FieldPath, PathValueOf} from '../types';\nimport {onPathEvent} from '../subscribe';\nimport {useWatchCore} from './form';\nimport usePath from './path';\n\n/**\n * Options accepted by {@link useTransform}.\n */\nexport type UseTransformOptions<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments,\n TDisplay = PathValueOf<TValues, TPath>\n> = {\n /**\n * Map the form's stored (raw) value to the display value the control\n * renders — the read direction. Omitted: the raw value is displayed\n * as-is (identity).\n */\n toDisplay?: (raw: PathValueOf<TValues, TPath>) => TDisplay;\n /**\n * Map a display value back to the raw value written into the form —\n * the write direction. Omitted: the display value is written as-is\n * (identity). The round trip should be an identity\n * (`toDisplay(fromDisplay(x)) === x`); a store value the transform\n * cannot invert (e.g. `undefined` for a not-yet-edited field) must be\n * handled by `toDisplay`, since it runs first.\n */\n fromDisplay?: (display: TDisplay) => PathValueOf<TValues, TPath>;\n};\n\n/**\n * Bind a control to a field whose stored value and display value differ\n * — TanStack Form's `useTransform` counterpart, with the round trip made\n * explicit: `toDisplay` maps the store value to what the control shows,\n * `fromDisplay` maps the control's display value back to what the store\n * holds. The store always carries the raw typed value, so\n * `getValues`/submit/validation never see display representations.\n *\n * ```jsx\n * const age = useTransform(form, 'age', {\n * toDisplay: (raw: number) => String(raw),\n * fromDisplay: (display: string) => Number(display)\n * });\n * <input value={age.value} onChange={e => age.onChange(e.target.value)} />\n * ```\n *\n * `value` subscribes to 'change' at leaf scope exactly like a controlled\n * `useField` value — typing, programmatic `setValue` and ancestor writes\n * all re-derive it, writes elsewhere never re-render it. `onChange`\n * writes through `userChangeByPath` (the user-change channel): with a\n * field mounted at the same path the mode/reValidateMode-gated\n * validation fires exactly as if the user typed into a bound field; with\n * no mounted field it degrades to a plain value write. Touched marking\n * stays a blur concern — pair this with `useField` at the same path, or\n * call `setTouched`, when blur semantics matter.\n *\n * The transform functions are read fresh on every render (inline\n * closures work), and `value` is recomputed per render — keep display\n * values primitive (string/number) so React's equal-state bailout holds.\n *\n * @param form the form instance (explicit; the hook is headless — no\n * context read, no provider required)\n * @param name the field's path (dotted string or segments)\n * @param options the two mapping directions; both optional (identity)\n */\nexport default function useTransform<\n TValues extends Record<string, any> = any,\n TPath extends FieldPath<TValues> | PathSegments =\n FieldPath<TValues> | PathSegments,\n TDisplay = PathValueOf<TValues, TPath>\n>(\n form: Form<TValues>,\n name: TPath,\n options: UseTransformOptions<TValues, TPath, TDisplay> = {}\n): {value: TDisplay; onChange: (display: TDisplay) => void} {\n const path = usePath(name);\n const {toDisplay, fromDisplay} = options;\n\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(form.emitter, 'change', path, 'leaf', invalidate),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- usePath memoizes the Path per key, so key pins the subscription like every path-scoped hook\n [form.emitter, path.key]\n );\n const raw = useWatchCore(subscribeFactory, () => getValueByPath(form, path));\n const value = toDisplay ? toDisplay(raw) : (raw as TDisplay);\n\n const onChange = useCallback(\n (display: TDisplay) => {\n userChangeByPath(\n form,\n path,\n fromDisplay ? fromDisplay(display) : display\n );\n },\n [form, path, fromDisplay]\n );\n\n return {value, onChange};\n}\n"],"names":["pathCache","Map","normalizePath","path","Array","isArray","cached","get","value","result","identifier","flushIdentifier","isIndex","dotted","map","String","join","bracket","reduce","acc","seg","TypeError","push","i","length","char","quote","close","indexOf","slice","content","Number","parsePath","size","oldest","keys","next","done","delete","set","segment","test","values","current","p","unset","prop","props","arr","copy","index","setOwned","root","owned","container","parent","parentProp","has","add","isPromise","then","isEqual","a","b","Object","is","Date","getTime","proto","getPrototypeOf","prototype","keysA","keysB","key","waitUntil","emitter","event","isResolve","isReject","Promise","resolve","reject","off","on","create","name","JSON","stringify","valuesCaches","WeakMap","bumpValuesVersion","form","cache","version","dirtyBaselines","getDirtyBaseline","segments","baselines","initialValues","setDirtyBaseline","pruneDirtyBaselines","stem","baselineKey","startsWith","clearDirtyBaselines","clear","dirtyFieldsCaches","bumpDirtyVersion","isSegmentsPath","some","part","isFieldError","type","message","FORM_ERROR","VALIDATION_OUTCOME","getErrorByPath","errors","NO_ERRORS","getFieldErrorsByPath","getErrors","entries","list","parse","getFirstError","setError","error","options","setErrorByPath","createPath","forEach","item","normalizeErrors","emit","shouldFocus","clearErrors","paths","one","hasErrors","isFieldDirtyByPath","live","isDirty","dirty","forEachDirtyField","fn","computeDirtyFields","dirtyFields","getDirtyFields","aKeys","every","sameDirtyKeys","setTouchedByPath","touched","hasTouchedByPath","getTouchedFields","from","getValues","computeValues","parsedValues","deleted","Set","merged","getValueByPath","ancestorKey","setValueByPath","pruneDescendantKeys","reviveBranch","shouldDirty","shouldTouch","shouldValidate","validators","seedValueByPath","emitChangeByPath","removeFieldByPath","validating","keepValue","keepDirty","hasLiveBranch","keepTouched","keepError","k","tombstone","setInitialValues","collectValueLeaves","node","out","unsetValidatingByPath","setValidatingByPath","registerValidatorByPath","registration","timer","controller","marked","lock","errorSource","mark","unmark","runSync","sync","validate","land","asyncAlways","gate","collectSyncErrors","own","supersede","clearTimeout","abort","runValidator","AbortController","round","signal","e","catch","finally","run","debounce","setTimeout","touchKeys","setFormErrors","footprint","recordFootprint","stored","applyValidateResult","validateDeps","formErrorFootprints","getFormErrorFootprint","written","clearFormValidateErrors","outcome","setParsedValues","FORM_VALIDATING_KEY","fieldsSettled","SETTLED","formValidateStates","runFormValidate","validateDebounce","state","waiters","getFormValidateState","runFormValidateRound","settleFormValidate","waiter","revalidateFormOnChange","mode","reValidateMode","hasFormValidateErrors","fieldValidateDeps","registerFieldValidateDeps","depKeys","deps","depKey","dependents","unregisterFieldValidateDeps","revalidateDependentsOnChange","dependent","validationError","Error","async","ensureValidate","validator","fieldModes","changeValueByPath","userChangeByPath","registerFieldMode","modes","displaced","token","unregisterFieldMode","entry","runUserChangeGate","userBlur","setIsSubmitting","isSubmitting","incrementSubmitCount","submitCount","setSubmitSuccessful","isSubmitSuccessful","setDisabled","disabled","nameToPath","handleSubmit","onSubmit","onValidSubmit","onInvalidSubmit","onAction","shouldFocusError","preventDefault","formEl","currentTarget","isSubmitted","checkValidity","reportValidity","querySelector","invalid","focus","elements","el","validationMessage","getNativeErrors","firstKey","submitted","createEmitter","setMaxListeners","source","validateOnMount","dep","isLoading","status","resolved","defaultMessage","bound","rulesToValidator","rules","meta","required","messages","min","n","isNaN","max","isSized","minLength","maxLength","pattern","fns","rulesToConstraintAttrs","attrs","isDescendant","onPathEvent","scope","cb","changed","onKeyEvent","useForm","useState","created","createForm","seededRef","useRef","useEffect","seeded","controlledRef","useWatchCore","subscribeFactory","getter","cacheRef","hasValue","getterRef","isEqualRef","getSnapshot","useCallback","subscribe","notify","compare","useSyncExternalStore","useWatch","formOrEmitter","invalidate","useValueByPath","exact","defaultValue","useTouchedByPath","bind","useErrorByPath","useFieldErrorsByPath","useIsFieldDirtyByPath","FORM_STATE_EVENTS","isSameFormState","sameTouched","touchedFields","isTouched","isValid","isValidating","usePath","useMemo","useStage","ref","useStageFn","params","useUnmountRestore","teardown","restore","removedRef","useValidate","formProp","contextForm","useContext","FormContext","validateRef","debounceRef","syncRef","asyncAlwaysRef","dispose","disposed","kick","removeFieldForUnmount","snapshot","present","restoreRemovedField","uncontrolledSyncRegistry","useFieldCore","f1","initialValue","shouldUnregister","delayError","uncontrolled","modeOption","Context","hasRuleConstraints","ruleValidator","ruleErrors","merge","other","combineRulesAndValidate","delay","shown","setShown","useDelayedErrors","errorObject","snapshotRef","useFieldValue","formDisabled","onChange","v","onBlur","depsKey","elementRef","focusRef","shouldSelect","select","cells","read","asString","removalSnapshotRef","useField","idCounters","generateId","arrayIdsRegistry","registerArrayIds","ids","registry","bumpReducer","count","useFieldArrayCore","keyName","idsRef","getArray","setArray","computeFields","pop","id","fields","syncFields","useReducer","append","prepend","unshift","insert","splice","newArr","remove","filter","_","swap","to","move","replace","update","useFieldArrayItemCore","arrayPath","computeIndex","getArrayIds","computeValue","lastRef","computeRef","bump","idx","val","nextIndex","itemPath","setValue","createContext","FormProvider","Provider","CheckboxGroupContext","CheckboxGroupProvider","appendFormDataValue","fd","FileList","File","Blob","toISOString","errorIdFromKey","ariaProps","fieldKey","Boolean","Field","React","forwardRef","eventToValue","asProps","renderError","as","valueToProps","valueAsNumber","valueAsDate","innerRef","nativeInvalidCount","setNativeInvalidCount","isDisabled","setCustomValidity","mergedRef","setRef","Component","isFile","toValue","target","files","valueProps","errorId","constraintAttrs","createElement","Fragment","role","Checkbox","checked","toSelectValue","multiple","Select","children","selectedOptions","option","context","action","f2","submit","FormData","formDataFromValues","noValidate","useFormContext","useFieldArray","useFieldArrayItem","keptValues","keepValues","keepDirtyValues","keepDefaultValues","keepErrors","keepIsSubmitting","keepSubmitCount","keepIsSubmitted","keepIsSubmitSuccessful","initial","keepExisting","callback","unsubscribes","isNameList","unsubscribe","settle","find","offErrors","offSubmitting","group","getFormState","offs","toDisplay","fromDisplay","raw","display"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/util.ts","../src/path.ts","../src/core/internals.ts","../src/core/errors.ts","../src/standardSchema.ts","../src/core/dirty.ts","../src/core/touched.ts","../src/core/values.ts","../src/core/validate.ts","../src/core/change.ts","../src/core/unmount.ts","../src/rules.ts","../src/core/register.ts","../src/core/array.ts","../src/core/submit.ts","../src/core/focus.ts","../src/form.ts","../src/errorId.ts","../src/core/disabled.ts","../src/subscribe.ts","../src/hooks/path.ts","../src/hooks/form.tsx","../src/hooks/stage.ts","../src/hooks/validate.ts","../src/hooks/field.tsx","../src/hooks/fieldArray.ts","../src/context.ts","../src/server.ts","../src/components/Field.tsx","../src/components/ErrorSummary.tsx","../src/components/Form.tsx","../src/components/FormField.tsx","../src/hooks/transform.ts"],"sourcesContent":["import {on} from './emitter';\nimport type {EventEmitter} from './emitter';\n\n/** FIFO bound for {@link pathCache} — a backstop for dynamic keys\n * ('items[' + id + ']'); eviction drops the oldest and only costs a\n * re-parse, never behavior. */\nconst PATH_CACHE_LIMIT = 1e4;\n\nconst pathCache = new Map<string, (string | number)[]>();\n\n/** Test-only view of the path cache size (not re-exported from the entry). */\nexport const pathCacheSize: () => number = () => pathCache.size;\n\nexport function normalizePath(\n path: string | (string | number)[]\n): (string | number)[] {\n if (Array.isArray(path)) return path;\n const cached = pathCache.get(path);\n if (cached) return cached;\n const value = parsePath(path);\n if (pathCache.size >= PATH_CACHE_LIMIT) {\n // Insertion order is FIFO order (non-empty since size >= 1e4).\n const oldest = pathCache.keys().next();\n if (!oldest.done) pathCache.delete(oldest.value);\n }\n pathCache.set(path, value);\n return value;\n}\n\n/** Integer array index (optionally negative)? Parsed paths never carry\n * index strings (dotted numerics throw); it defends programmatic\n * segments from raw arrays and internal callers. */\nexport const isIndex: (segment: string) => boolean = segment =>\n /^-?\\d+$/.test(segment);\n\nfunction parsePath(path: string): (string | number)[] {\n const result: (string | number)[] = [];\n let identifier = '';\n const flushIdentifier = () => {\n if (isIndex(identifier)) {\n // Rebuild both spellings for an actionable error message.\n const dotted = [...result.map(String), identifier].join('.');\n const bracket = result.reduce(\n (acc: string, seg: string | number) =>\n acc +\n (typeof seg === 'number' ? `[${seg}]` : `${acc ? '.' : ''}${seg}`),\n ''\n );\n throw new TypeError(\n `Numeric path segment must use bracket notation: \"${dotted}\" → \"${bracket}[${identifier}]\" (path: ${path})`\n );\n }\n result.push(identifier);\n identifier = '';\n };\n\n for (let i = 0; i < path.length; i++) {\n const char = path[i];\n if (char === '.') {\n if (identifier !== '') flushIdentifier();\n } else if (char === '[') {\n if (identifier !== '') flushIdentifier();\n const quote = path[i + 1];\n if (quote === '\"' || quote === \"'\") {\n const close = path.indexOf(quote, i + 2);\n if (close === -1) {\n throw new TypeError(`Unterminated quote in path: ${path}`);\n }\n if (path[close + 1] !== ']') {\n throw new TypeError(\n `Expected \"]\" after quoted segment in path: ${path}`\n );\n }\n result.push(path.slice(i + 2, close));\n i = close + 1;\n } else {\n const close = path.indexOf(']', i + 1);\n if (close === -1) {\n throw new TypeError(`Unterminated bracket in path: ${path}`);\n }\n const content = path.slice(i + 1, close);\n result.push(isIndex(content) ? Number(content) : content);\n i = close;\n }\n } else {\n identifier += char;\n }\n }\n if (identifier !== '' || result.length === 0) flushIdentifier();\n return result;\n}\n\nexport function get(values: any, path: (string | number)[]): any {\n return path.reduce((current: any, p: string | number) => {\n if (current == null) return undefined;\n return current[p];\n }, values);\n}\n\n/** Immutable counterpart of {@link set}: removes the path, copying only\n * the touched branch; deletes the key rather than writing undefined. */\nexport function unset(values: any, path: (string | number)[]): any {\n if (!path.length || values == null) return values;\n const [prop, ...props] = path;\n if (props.length) {\n const next = unset(values[prop], props);\n // Reattach at the parent key, not the full path (which would re-write\n // the removed subtree).\n return next === values[prop] ? values : set(values, [prop], next);\n }\n if (Array.isArray(values)) {\n if (!(prop in values)) return values;\n const arr = values.slice();\n delete arr[prop as number];\n return arr;\n }\n if (typeof values !== 'object' || !(prop in values)) return values;\n const copy = {...values};\n delete copy[prop as string];\n return copy;\n}\n\n/** The array index `prop` writes inside `container`, or `undefined` for\n * an object key. A numeric segment always addresses an array slot\n * (starting one when `container` isn't an array yet); a numeric string\n * does only when `container` is already an array. */\nfunction arraySlot(container: any, prop: string | number): number | undefined {\n if (typeof prop === 'number') return prop;\n if (Array.isArray(container) && typeof prop === 'string' && isIndex(prop)) {\n return Number(prop);\n }\n return undefined;\n}\n\n/** Copy-on-write for one descent step: array slots copy as an array (or\n * start one), object keys spread into a new object. */\nfunction copyForProp(container: any, prop: string | number): any {\n if (arraySlot(container, prop) !== undefined) {\n return Array.isArray(container) ? container.slice() : [];\n }\n return {...container};\n}\n\n/** Copy-on-write container for {@link setOwned}: returns `container` as-is\n * when this merge already owns it, otherwise copies it (registering the\n * copy) so later paths under it share the same allocation. */\nfunction ensureOwned(\n container: any,\n prop: string | number,\n owned: Set<object>\n): any {\n if (owned.has(container)) return container;\n const copy = copyForProp(container, prop);\n owned.add(copy);\n return copy;\n}\n\nexport function set(values: any, path: (string | number)[], value: any): any {\n if (!path.length) return value;\n\n const [prop, ...props] = path;\n // Numeric segments use the array copy rule; an object spread would\n // corrupt the array.\n const index = arraySlot(values, prop);\n if (index !== undefined) {\n const arr = copyForProp(values, prop);\n arr[index] = set(arr[index], props, value);\n return arr;\n }\n return {...values, [prop]: set(values && values[prop], props, value)};\n}\n\n/** Ownership-tracked {@link set}: merge many paths without re-copying\n * containers this merge already created. Containers in `owned` mutate in\n * place; borrowed containers are copied once (per `set`'s copy rules), so\n * a list of paths allocates each distinct prefix once. Use a fresh `owned`\n * per merge and thread the returned root onward. */\nexport function setOwned(\n root: any,\n path: (string | number)[],\n value: any,\n owned: Set<object>\n): any {\n if (!path.length) return value;\n let container = root;\n let parent: any = null;\n let parentProp: string | number = '';\n for (let i = 0; i < path.length; i++) {\n const prop = path[i];\n const copy = ensureOwned(container, prop, owned);\n if (copy !== container) {\n if (i === 0) root = copy;\n else parent[parentProp] = copy;\n container = copy;\n }\n if (i === path.length - 1) {\n container[prop] = value;\n } else {\n parent = container;\n parentProp = prop;\n container = container[prop];\n }\n }\n return root;\n}\n\nexport function isEmpty(value: any): boolean {\n if (value == null) return true;\n if (typeof value !== 'object') return false;\n\n const values = Object.values(value);\n return values.length === 0 || values.every(isEmpty);\n}\n\nexport function isPromise(value: any): value is Promise<any> {\n return value && typeof value.then === 'function';\n}\n\n/** Typed-accessor options shared by the event-value protocol. */\ntype TypedAccessorOptions = {valueAsNumber?: boolean; valueAsDate?: boolean};\n\n/** Shared DOM event → value protocol: file → FileList, checkbox →\n * `checked`, `valueAsNumber`/`valueAsDate` → typed accessors, else the\n * string `value`; a non-DOM argument passes through unchanged. */\nexport function extractEventValue(e: any, options?: TypedAccessorOptions): any {\n const target = e?.target;\n if (!target) return e;\n if (target.type === 'file') return target.files;\n if (target.type === 'checkbox') return target.checked;\n if (options?.valueAsNumber) return target.valueAsNumber;\n if (options?.valueAsDate) return target.valueAsDate;\n return target.value;\n}\n\n/** Default event-to-value binding: explicit `eventToValue` wins, else\n * extraction follows valueAsNumber/valueAsDate. */\nexport function eventToValueOrDefault(\n eventToValue: ((e: any) => any) | undefined,\n options?: TypedAccessorOptions\n): (e: any) => any {\n return eventToValue ?? ((e: any) => extractEventValue(e, options));\n}\n\n/** Structural equality for default data (primitives, arrays, plain\n * objects, Dates); class instances compare unequal, errs toward re-seeding. */\nexport function isEqual(a: any, b: any): boolean {\n if (Object.is(a, b)) return true;\n if (a instanceof Date && b instanceof Date)\n return a.getTime() === b.getTime();\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false;\n const isArray = Array.isArray(a);\n if (isArray !== Array.isArray(b)) return false;\n if (isArray) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false;\n }\n return true;\n }\n const proto = Object.getPrototypeOf(a);\n if (proto !== Object.prototype && proto !== null) return false;\n if (Object.getPrototypeOf(b) !== proto) return false;\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!isEqual(a[key], b[key])) return false;\n }\n return true;\n}\n\nexport function waitUntil(\n emitter: EventEmitter<any>,\n event: string,\n isResolve: () => boolean,\n isReject: () => boolean\n): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (isReject()) return void reject();\n if (isResolve()) return void resolve();\n\n const off = on(emitter, event as any, () => {\n if (isReject()) {\n off();\n reject();\n return;\n }\n // Not resolved yet — stay subscribed and keep waiting.\n if (!isResolve()) return;\n off();\n resolve();\n });\n });\n}\n\n/** DEV-only snapshot guard for {@link getValues}: deep-clones and freezes\n * plain objects/arrays so mutation throws instead of corrupting the shared\n * memoized result. Non-plain values pass through unfrozen (cloning would\n * strip prototypes, freezing breaks methods like Date#setHours). */\nexport function freezeValues(value: any): any {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) {\n return Object.freeze(value.map(freezeValues));\n }\n if (Object.getPrototypeOf(value) !== Object.prototype) return value;\n const clone: Record<string, any> = {};\n for (const key of Object.keys(value)) clone[key] = freezeValues(value[key]);\n return Object.freeze(clone);\n}\n","import {normalizePath} from './util';\n\nexport type PathSegments = (string | number)[];\nexport type Name = string | PathSegments;\nexport type Path = {value: PathSegments; key: string};\n\nexport default function create(name: Name): Path {\n const value = normalizePath(name);\n return {value, key: JSON.stringify(value)};\n}\n\n/** Parse a path key (the JSON form {@link create} produces) back into\n * segments. */\nexport function segmentsFromKey(key: string): PathSegments {\n return JSON.parse(key) as PathSegments;\n}\n","import {emit} from '../emitter';\nimport {get} from '../util';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {FieldError, Form} from '../form';\n\ntype Cache<V> = {version: number; result: V};\n\nexport function getOrCreate<V>(\n map: WeakMap<Form, V>,\n form: Form,\n create: () => V\n): V {\n if (map.has(form)) return map.get(form) as V;\n const value = create();\n map.set(form, value);\n return value;\n}\n\n/** Per-form memoization of {@link getValues}, the same version-bump/read\n * pattern {@link dirtyFieldsCaches} gives {@link getDirtyFields}. */\ntype ValuesCache = Cache<any>;\n\nexport const valuesCaches: WeakMap<Form, ValuesCache> = new WeakMap();\n\n/** Increment a memo cache's `version` — the write half of the\n * version-bump/read pattern that marks its result stale. */\nfunction bumpVersion<V extends {version: number}>(\n map: WeakMap<Form, V>,\n form: Form\n): void {\n const cache = map.get(form);\n if (cache) cache.version++;\n}\n\n/** Invalidate `form`'s cached {@link getValues} result — called at every\n * point that can change values/parsedValues/initialValues, so repeated\n * reads hand back a stable reference until the next write. */\nexport function bumpValuesVersion(form: Form): void {\n bumpVersion(valuesCaches, form);\n}\n\n/** Per-form memoization of {@link getErrorsRecord} / {@link getErrorsTree},\n * the same version-bump/read pattern {@link valuesCaches} gives {@link\n * getValues}: every errors-Map mutation bumps the counter, reads reset it,\n * so consecutive reads hand back one stable reference until the next write. */\ntype ErrorsCache = Cache<Record<string, FieldError[]>> & {tree: any};\n\nexport const errorsCaches: WeakMap<Form, ErrorsCache> = new WeakMap();\n\n/** Invalidate `form`'s cached {@link getErrorsRecord} result — called at\n * every point that mutates the errors Map. A no-op until the first read\n * installed a cache entry. */\nexport function bumpErrorsVersion(form: Form): void {\n bumpVersion(errorsCaches, form);\n}\n\n/** Per-path dirty-comparison baselines installed by writes with\n * `shouldDirty: false`: the written value becomes that field's baseline —\n * the write reads as a commit, not an edit. Module-private so the Form\n * shape is untouched for forms that never opt in. */\nconst dirtyBaselines = new WeakMap<Form, Map<string, any>>();\n\n/** The value a field's dirtiness is measured against: its committed\n * baseline when one exists, initialValues at the path otherwise. */\nexport function getDirtyBaseline(\n form: Form,\n key: string,\n segments: PathSegments\n): any {\n const baselines = dirtyBaselines.get(form);\n if (baselines?.has(key)) return baselines.get(key);\n return get(form.initialValues, segments);\n}\n\n/** Install a committed baseline for a `shouldDirty: false` write: the\n * field reads clean until a later write diverges. */\nexport function setDirtyBaseline(form: Form, {key}: Path, value: any): void {\n getOrCreate(dirtyBaselines, form, () => new Map()).set(key, value);\n}\n\n/** A wholesale write replaces the subtree below it, so baselines committed\n * under the branch die with the data they were committed against (array\n * movers rewrite the parent path, re-aligning row indices). */\nexport function pruneDirtyBaselines(form: Form, {key}: Path): void {\n const baselines = dirtyBaselines.get(form);\n if (!baselines?.size) return;\n const stem = `${key.slice(0, -1)},`;\n for (const baselineKey of baselines.keys()) {\n if (baselineKey.startsWith(stem)) baselines.delete(baselineKey);\n }\n}\n\n/** Drop committed baselines at one path or all of them — the state they\n * were measured against is gone. */\nexport function clearDirtyBaselines(form: Form, key?: string): void {\n const baselines = dirtyBaselines.get(form);\n if (!baselines) return;\n if (key === undefined) baselines.clear();\n else baselines.delete(key);\n}\n\n/** Per-form memoization of {@link getDirtyFields}. `version` counts value\n * mutations since the cached `result` was computed; bump points increment\n * it, reads reset it, so a non-zero version means the cache is stale. */\ntype DirtyFieldsCache = Cache<Record<string, boolean>>;\n\nexport const dirtyFieldsCaches: WeakMap<Form, DirtyFieldsCache> = new WeakMap();\n\n/** Invalidate `form`'s cached {@link getDirtyFields} result — called at\n * every point that can change values or initialValues, so repeated reads\n * hand out a stable reference and useWatch's Object.is check can skip\n * re-renders. */\nexport function bumpDirtyVersion(form: Form): void {\n bumpVersion(dirtyFieldsCaches, form);\n}\n/** Numbers only occur inside a segments path (`['a', 0]`), never as\n * standalone names, so a top-level number marks `name` as one path rather\n * than a list of names. */\nexport function isSegmentsPath(\n name: PathSegments | Name[]\n): name is PathSegments {\n return (name as (number | unknown)[]).some(part => typeof part === 'number');\n}\n\nexport function isFieldError(value: any): value is FieldError {\n return (\n !!value &&\n typeof value === 'object' &&\n typeof value.type === 'string' &&\n typeof value.message === 'string'\n );\n}\n\n/** Store a schema validator's parsed output as the getValues baseline layer\n * above initialValues. Dirty state is untouched — parsing is not an edit. */\nexport function setParsedValues(form: Form, values: any): void {\n if (values === undefined || values === form.parsedValues) return;\n form.parsedValues = values;\n // parsedValues is a getValues layer above initialValues, so a new parse\n // invalidates the cached merge (no bumpDirtyVersion — parsing isn't an\n // edit).\n bumpValuesVersion(form);\n emit(form.emitter, 'change');\n}\n","import {emit} from '../emitter';\nimport createPath, {segmentsFromKey} from '../path';\nimport type {Name, Path} from '../path';\nimport type {FieldPath, OpaqueTypes, AnyPath} from '../types';\nimport type {FieldError, FieldErrorEntry, Form} from '../form';\nimport {\n bumpErrorsVersion,\n errorsCaches,\n isFieldError,\n isSegmentsPath\n} from './internals';\n\n/** An error value as validators yield it and the error setters\n * accept it: one error, or a mixed list of them. */\nexport type ValidatorOutput = string | FieldError | (string | FieldError)[];\n\n/** Reserved top-level path segment for form-level errors: the Standard\n * Schema adapter lands path-less issues under this key, read via\n * getError(form, FORM_ERROR) / getFieldErrors(form, FORM_ERROR). */\nexport const FORM_ERROR = '_form';\n\n/** Brand marking a form-level validate result as a structured\n * {@link ValidationOutcome} rather than a plain nested error record.\n * Symbols can't collide with user records, so detection is\n * `VALIDATION_OUTCOME in result`. */\nexport const VALIDATION_OUTCOME: unique symbol = Symbol('validation-outcome');\n\n/** Get a field's first error, or undefined. */\nexport function getError<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): FieldError | undefined {\n return getErrorByPath(form, createPath(name));\n}\n\n/** Get a field's first error by path, or undefined. */\nexport function getErrorByPath(\n {errors}: Form,\n path: Path\n): FieldError | undefined {\n return errors.get(path.key)?.[0];\n}\n\n/** Shared empty result for {@link getFieldErrorsByPath}: avoids allocating\n * on the hot no-error path. Stored arrays are handed out by reference too,\n * so treat results as read-only. */\nconst NO_ERRORS: FieldError[] = [];\n\n/** Get all errors of a field (insertion order; empty array when none). */\nexport function getFieldErrors<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): FieldError[] {\n return getFieldErrorsByPath(form, createPath(name));\n}\n\n/** Get all errors of a field by path (insertion order; empty when none). */\nexport function getFieldErrorsByPath({errors}: Form, path: Path): FieldError[] {\n return errors.get(path.key) ?? NO_ERRORS;\n}\n\n/** Get all errors as {path, type, message} entries in insertion order;\n * `path` is the dotted field path ('a.b', 'list.0'), one entry per error. */\nexport function getErrors({errors}: Form): FieldErrorEntry[] {\n const entries: FieldErrorEntry[] = [];\n for (const [key, list] of errors) {\n const path = segmentsFromKey(key).join('.');\n for (const {type, message} of list) entries.push({path, type, message});\n }\n return entries;\n}\n\n/** A {@link FieldPath} string converted to the dotted key error records use\n * at runtime ('items[0].name' → 'items.0.name'); quoted segments drop\n * their quotes. Public so consumers can name the key style in their types. */\nexport type DottedPath<P extends string> =\n P extends `${infer H}[${infer N}]${infer R}`\n ? `${H extends '' ? '' : `${H}.`}${N extends `\"${infer K}\"` | `'${infer K}'` ? K : N}${DottedPath<R>}`\n : P;\n\n/** Every error as one record keyed by dotted path — react-hook-form's\n * `FieldErrors<T>` shape — plus the {@link FORM_ERROR} slot. Values are\n * the stored FieldError[] arrays shared with the form (read-only). */\nexport type FieldErrors<T extends Record<string, any> = any> = Partial<\n Record<DottedPath<Extract<FieldPath<T>, string>>, FieldError[]>\n> & {\n [FORM_ERROR]?: FieldError[];\n};\n\n/** `true` only for the `any` type (the same probe {@link FieldPath}\n * uses), so the tree of an untyped form degrades to `any` instead of an\n * infinite mapped-type expansion. */\ntype IsAnyTree<T> = 0 extends 1 & T ? true : false;\n\ntype TreePrimitive =\n null | undefined | string | number | boolean | symbol | bigint;\n\n/** One level of the nested error tree: arrays become arrays of the item's\n * tree, objects recurse per key, everything else is a leaf holding the\n * stored FieldError[] (shared with the form — read-only). */\ntype FieldErrorsTreeNode<T> =\n IsAnyTree<T> extends true\n ? any\n : T extends OpaqueTypes[keyof OpaqueTypes]\n ? FieldError[]\n : T extends\n | TreePrimitive\n | Function\n | Date\n | File\n | FileList\n | Map<any, any>\n | Set<any>\n ? FieldError[]\n : T extends ReadonlyArray<infer E>\n ? FieldErrorsTreeNode<E>[]\n : {[K in keyof T]?: FieldErrorsTreeNode<T[K]>};\n\n/** Every error as one nested object following the values tree — the typed\n * optional-chain counterpart of {@link FieldErrors}' flat dotted keys.\n * Leaves hold the stored FieldError[] arrays (read-only); {@link\n * FORM_ERROR} sits at the top level. A row-level error at `items[0]` and a\n * field error at `items[0].name` cannot both occupy the `items[0]` slot:\n * whichever landed later owns it (insertion order). The flat record never\n * conflicts — read it when both coexist. */\nexport type FieldErrorsTree<T = any> = FieldErrorsTreeNode<T> & {\n [FORM_ERROR]?: FieldError[];\n};\n\n/** Shared rebuild for {@link getErrorsRecord} / {@link getErrorsTree}:\n * one pass over the errors Map computes both views (the dotted record\n * and the nested tree), each sharing the stored FieldError[] references.\n * The version-bump/read pattern (see {@link errorsCaches}) guarantees\n * consecutive reads hand back stable references until the next error\n * write. */\nfunction computeErrorsViews(form: Form): void {\n const cached = errorsCaches.get(form);\n if (cached?.version === 0) return;\n const result: Record<string, FieldError[]> = {};\n const tree: any = {};\n for (const [key, list] of form.errors) {\n // The raw key preserves the parser's number-vs-string segment\n // distinction: 'items[0]' carries the number 0 (array index in the\n // tree), 'items[\"0\"]' the string '0' (object key).\n const segments = segmentsFromKey(key);\n result[segments.join('.')] = list;\n let node = tree;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n const slot = node[segment];\n // A shallower error inserted earlier yields to the deeper path —\n // insertion order owns the conflict, mirroring RHF's nested set.\n const container =\n slot &&\n !(Array.isArray(slot) && slot.length > 0 && isFieldError(slot[0]))\n ? slot\n : typeof segments[i + 1] === 'number'\n ? []\n : {};\n node[segment] = container;\n node = container;\n }\n node[segments[segments.length - 1]] = list;\n }\n if (cached) {\n cached.result = result;\n cached.tree = tree;\n cached.version = 0;\n } else {\n errorsCaches.set(form, {version: 0, result, tree});\n }\n}\n\n/** Get every error as one record keyed by dotted path ('a.b', 'list.0') —\n * react-hook-form's `formState.errors` shape. Values are the stored\n * FieldError[] arrays (read-only). Memoized per form with the same\n * version-bump/read pattern {@link getValues} uses, so consecutive reads\n * hand back one stable reference until an error actually changes. */\nexport function getErrorsRecord<T extends Record<string, any> = any>(\n form: Form<T>\n): FieldErrors<T> {\n computeErrorsViews(form);\n return errorsCaches.get(form)!.result;\n}\n\n/** Get every error as one nested object following the values tree\n * (`errors.items[0].name`), the optional-chaining counterpart of\n * {@link getErrorsRecord}. Leaves hold the stored FieldError[] arrays\n * (read-only); memoized via the same version-bump/read pattern. */\nexport function getErrorsTree<T extends Record<string, any> = any>(\n form: Form<T>\n): FieldErrorsTree<T> {\n computeErrorsViews(form);\n return errorsCaches.get(form)!.tree;\n}\n\n/** Convert a field path (bracket spelling, the `name` every API takes)\n * into the dotted key error records use: `'items[0].name'` →\n * `'items.0.name'`. */\nexport function fieldPathToDottedKey(name: Name): string {\n return createPath(name).value.join('.');\n}\n\n/** Convert a dotted errors-record key back into bracket path spelling\n * (`'items.0.name'` → `'items[0].name'`). Inherently lossy: the dotted key\n * cannot distinguish a segment containing a literal dot, so for such paths\n * keep the bracket spelling and read the record via\n * {@link fieldPathToDottedKey}. */\nexport function dottedKeyToFieldPath(key: string): string {\n const segments = key.split('.');\n const numeric = (segment: string) => /^(0|[1-9]\\d*)$/.test(segment);\n return segments\n .map((segment, i) =>\n i > 0 && numeric(segment)\n ? `[${segment}]`\n : `${i > 0 ? '.' : ''}${segment}`\n )\n .join('');\n}\n\n/** Get the first error's message, or undefined when there are no errors. */\nexport function getFirstError({errors}: Form): string | undefined {\n return errors.values().next().value?.[0]?.message;\n}\n\n/** Options accepted by {@link setError}. */\nexport type SetErrorOptions = {\n /** Focus the field's element after the error lands (react-hook-form's\n * `setError` `shouldFocus`); unmounted fields are silent no-ops. */\n shouldFocus?: boolean;\n};\n\n/** Set a field's error. A string is normalized to {type: 'custom',\n * message}; a FieldError is stored as-is; an array holds several (falsy\n * items dropped); undefined clears. */\nexport function setError<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(\n form: Form<T>,\n name: P,\n error: ValidatorOutput | undefined,\n options?: SetErrorOptions\n): void {\n setErrorByPath(form, createPath(name), error, options);\n}\n\n/** Set a field's error by path. See {@link setError} for the input shapes. */\nexport function setErrorByPath(\n form: Form,\n path: Path,\n error: ValidatorOutput | undefined,\n options?: SetErrorOptions\n): void {\n const {emitter, errors} = form;\n const list = normalizeErrors(error);\n // An empty result clears the key: the errors Map never stores an empty\n // list, so hasErrors stays a plain size check and readers index [0]\n // unguarded.\n if (list) errors.set(path.key, list);\n else errors.delete(path.key);\n bumpErrorsVersion(form);\n // Path payload lets key-scoped subscribers skip unrelated fields;\n // payload-less listeners ignore it.\n emit(emitter, 'errors', path);\n if (options?.shouldFocus) emit(emitter, 'focusError', path.key);\n}\n\n/** Normalize a {@link setErrorByPath} input into the stored non-empty\n * FieldError[] shape, or undefined when there is nothing to store. */\nfunction normalizeErrors(\n error: ValidatorOutput | undefined\n): FieldError[] | undefined {\n if (typeof error === 'string') {\n return error ? [{type: 'custom', message: error}] : undefined;\n }\n if (isFieldError(error)) return [error];\n if (!error) return undefined;\n // Falsy items drop out before normalization, so '' never becomes a\n // stored {type: 'custom', message: ''} placeholder.\n const list: FieldError[] = [];\n error.forEach(item => {\n if (typeof item === 'string' && item) {\n list.push({type: 'custom', message: item});\n } else if (isFieldError(item)) {\n list.push(item);\n }\n });\n return list.length ? list : undefined;\n}\n\n/** Clear errors: a single path, a list of paths, or (omitted) every error. */\nexport function clearErrors(form: Form, name?: Name | Name[]): void {\n const {emitter, errors} = form;\n if (name === undefined) {\n errors.clear();\n bumpErrorsVersion(form);\n // Payload-less broadcast: every error subscriber re-syncs.\n emit(emitter, 'errors');\n return;\n }\n // Same single-path vs list discrimination as trigger: a segment array\n // holding a number is one path ('a.0'), not a list of names.\n const paths =\n typeof name === 'string' || isSegmentsPath(name)\n ? [createPath(name)]\n : name.map(one => createPath(one));\n for (const {key} of paths) errors.delete(key);\n bumpErrorsVersion(form);\n // Path-payload emits wake exactly the affected fields' subscribers.\n for (const path of paths) emit(emitter, 'errors', path);\n}\n\n/** Options accepted by {@link setServerErrors}. */\nexport type SetServerErrorsOptions = {\n /** Keep existing field errors instead of clearing them first. Defaults\n * to `false`: a fresh response replaces the prior error state. */\n keepExisting?: boolean;\n};\n\n/** Land a server-side error response: each entry becomes the named field's\n * error(s) with `type: 'server'`. A string lands as one error, an array as\n * several, an empty array clears the field. By default existing errors are\n * cleared first; pass `keepExisting: true` to layer instead. */\nexport function setServerErrors(\n form: Form,\n errors: Record<string, string | string[]>,\n options?: SetServerErrorsOptions\n): void {\n if (!options?.keepExisting) clearErrors(form);\n for (const [name, error] of Object.entries(errors)) {\n setError(\n form,\n name,\n (Array.isArray(error) ? error : [error]).map(message => ({\n type: 'server',\n message\n }))\n );\n }\n}\n\n/** Drop every `type: 'server'` error — the round-trip state a previous\n * submit landed. {@link handleSubmit} runs this before its validation\n * round so a retry is judged fresh; client errors are untouched. Emits\n * payload-less 'errors' when anything changed. */\nexport function clearServerErrors(form: Form): void {\n const affected = Array.from(form.errors).filter(([, list]) =>\n list.some(error => error.type === 'server')\n );\n if (affected.length === 0) return;\n for (const [key, list] of affected) {\n const kept = list.filter(error => error.type !== 'server');\n if (kept.length) form.errors.set(key, kept);\n else form.errors.delete(key);\n }\n bumpErrorsVersion(form);\n emit(form.emitter, 'errors');\n}\n\nexport function hasErrors({errors}: Form): boolean {\n return errors.size > 0;\n}\n","/** Standard Schema v1 (standardschema.dev) contract and adapters, shared\n * by the resolver entry and direct-schema support. The types are a\n * structural copy of the spec — no dependency on any schema library, so\n * zod/valibot/arktype and every v1 implementer work without importing\n * them. */\nimport {FORM_ERROR, VALIDATION_OUTCOME} from './core/errors';\nimport type {FieldError, ValidationOutcome, Validator} from './form';\n\n/** A single Standard Schema issue. */\nexport type StandardSchemaIssue = {\n readonly message: string;\n readonly path?:\n ReadonlyArray<PropertyKey | {readonly key: PropertyKey}> | undefined;\n};\n\n/** The union Standard Schema's `validate` resolves to. */\nexport type StandardSchemaResult<Output = unknown> =\n | {readonly value: Output; readonly issues?: undefined}\n | {readonly issues: ReadonlyArray<StandardSchemaIssue>};\n\n/** Structural Standard Schema v1. `types` (optional in the spec) is what\n * {@link InferSchemaValues} and `createForm`'s inference read. */\nexport type StandardSchemaV1<Input = unknown, Output = Input> = {\n readonly '~standard': {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: Input\n ) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;\n readonly types?: {\n readonly input: Input;\n readonly output: Output;\n };\n };\n};\n\n/** The values type a Standard Schema produces: the `Output` of its\n * `~standard.types` (coercions/transforms included). `never` when the\n * schema lacks `types` — pass an explicit `TValues`. */\nexport type InferSchemaValues<S> = S extends {\n readonly '~standard': {readonly types: {readonly output: infer Out}};\n}\n ? Out\n : never;\n\n/** Implements Standard Schema v1 props? A boolean predicate, not a type\n * guard — narrowing the union through a guard fails either way, so call\n * sites cast after the check. */\nexport function hasStandardProps(schema: any): boolean {\n return (\n !!schema &&\n typeof schema === 'object' &&\n typeof schema['~standard']?.validate === 'function'\n );\n}\n\n/** Issue → stored error entry. */\nfunction toFieldError(issue: StandardSchemaIssue | undefined): FieldError {\n return {type: 'standard', message: issue?.message || 'Validation failed'};\n}\n\n/** Field-level adapter: validate one value with a schema and map every\n * issue to a FieldError (all issues surface; readers see the first). The\n * parsed output is validation-only — field validators never rewrite. */\nexport function schemaToFieldValidator(\n schema: StandardSchemaV1<any, any>\n): Validator {\n return async (value: any) => {\n const result = await schema['~standard'].validate(value);\n if (!result.issues?.length) return undefined;\n return result.issues.map(toFieldError);\n };\n}\n\n/** Form-level adapter: validate the whole values object and return a\n * ValidationOutcome. Failure nests errors ({a: {b: FieldError[]}});\n * pathless issues land on FORM_ERROR. Success exposes the schema's parsed\n * output as the parsedValues baseline. `createForm({validate: schema})`\n * wraps through this automatically. */\nexport function schemaToFormValidator<T extends Record<string, any>>(\n schema: StandardSchemaV1<any, T>\n): (values: T) => Promise<ValidationOutcome<T>> {\n return async (values: T) => {\n const result = await schema['~standard'].validate(values);\n const {issues} = result;\n if (!issues?.length) {\n // `in` keeps the union narrowed: the success variant carries `value`.\n return {\n [VALIDATION_OUTCOME]: true,\n values: 'value' in result ? result.value : undefined\n };\n }\n const errors: Record<string, any> = {};\n for (const issue of issues) {\n const segments = toPathSegments(issue);\n if (segments.length) {\n assignAtPath(errors, segments, toFieldError(issue));\n } else {\n // Pathless issues accumulate on FORM_ERROR instead of shadowing each other.\n const slot = (errors[FORM_ERROR] ??= []);\n if (Array.isArray(slot)) slot.push(toFieldError(issue));\n }\n }\n return {[VALIDATION_OUTCOME]: true, errors: pruneEmpty(errors) || {}};\n };\n}\n\n/** Stringify an issue path: PropertyKey or {key} segments → strings. */\nfunction toPathSegments(issue: StandardSchemaIssue): string[] {\n return (issue.path || []).map(segment =>\n String(\n typeof segment === 'object' && segment !== null\n ? (segment as {key: PropertyKey}).key\n : segment\n )\n );\n}\n\n/** Append an error at a nested path: leaves are FieldError[] (issues\n * accumulate in order); a path conflicting with a leaf is skipped. */\nfunction assignAtPath(\n root: Record<string, any>,\n segments: string[],\n error: FieldError\n): void {\n let node = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n if (node[segment] === undefined) node[segment] = {};\n const next = node[segment];\n if (!isBranch(next)) return;\n node = next;\n }\n const leaf = segments[segments.length - 1];\n const slot = node[leaf];\n if (slot === undefined) node[leaf] = [error];\n else if (Array.isArray(slot)) slot.push(error);\n}\n\n/** A branch is a plain container built while nesting; its leaves are the FieldError[] arrays. */\nfunction isBranch(value: any): value is Record<string, any> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/** Drop empty branch objects left behind by conflicting issue paths. */\nfunction pruneEmpty(\n node: Record<string, any>\n): Record<string, any> | undefined {\n const result: Record<string, any> = {};\n for (const [key, value] of Object.entries(node)) {\n if (isBranch(value)) {\n const pruned = pruneEmpty(value);\n if (pruned) result[key] = pruned;\n } else {\n result[key] = value;\n }\n }\n return Object.keys(result).length ? result : undefined;\n}\n","import {segmentsFromKey} from '../path';\nimport type {Path} from '../path';\nimport type {Form} from '../form';\nimport {dirtyFieldsCaches, getDirtyBaseline, getOrCreate} from './internals';\n\n/** Is one field dirty — the per-field rule behind `getFieldState`'s\n * `isDirty`: a live value exists at the path and differs from the field's\n * effective baseline (committed `shouldDirty: false` baselines included).\n * A leaf under a wholesale ancestor write reports clean — dirtiness\n * belongs to the branch that actually diverged. */\nexport function isFieldDirtyByPath(form: Form, path: Path): boolean {\n const live = form.values.get(path.key);\n return (\n form.values.has(path.key) &&\n getDirtyBaseline(form, path.key, path.value) !== live\n );\n}\n\n/** Is dirty — any value differs from initialValues. */\nexport function isDirty(form: Form): boolean {\n for (const [key, value] of form.values) {\n const path = segmentsFromKey(key);\n if (getDirtyBaseline(form, key, path) !== value) return true;\n }\n return false;\n}\n\nfunction forEachDirtyField(form: Form, fn: (dottedKey: string) => void): void {\n for (const [key, value] of form.values) {\n const path = segmentsFromKey(key);\n if (getDirtyBaseline(form, key, path) !== value) fn(path.join('.'));\n }\n}\n\nfunction computeDirtyFields(form: Form): Record<string, boolean> {\n const dirtyFields: Record<string, boolean> = {};\n forEachDirtyField(form, key => {\n dirtyFields[key] = true;\n });\n return dirtyFields;\n}\n\n/** Dirty entries only ever map to `true`, so equal key sets mean shallow\n * equal results. */\nfunction sameDirtyKeys(\n a: Record<string, boolean>,\n b: Record<string, boolean>\n): boolean {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) return false;\n return aKeys.every(key => b[key] === true);\n}\n\n/** Get dirty fields — fields whose current value differs from\n * initialValues. Keys are user-facing dotted paths ('a.b', 'a.0.c'); the\n * same reference is returned until the dirty set actually changes. */\nexport function getDirtyFields(form: Form): Record<string, boolean> {\n const cache = getOrCreate(dirtyFieldsCaches, form, () => ({\n version: 0,\n result: computeDirtyFields(form)\n }));\n if (cache.version > 0) {\n const result = computeDirtyFields(form);\n // Keep the old reference when the dirty set is unchanged so subscribers\n // see identity-stable snapshots.\n if (!sameDirtyKeys(cache.result, result)) cache.result = result;\n cache.version = 0;\n }\n return cache.result;\n}\n","import {emit} from '../emitter';\nimport createPath, {segmentsFromKey} from '../path';\nimport type {Name, Path} from '../path';\nimport type {AnyPath} from '../types';\nimport type {Form} from '../form';\n\n/** Set a field's touched state. */\nexport function setTouched(form: Form, name: Name): void {\n setTouchedByPath(form, createPath(name));\n}\n\n/** Set a field's touched state by path. */\nexport function setTouchedByPath({emitter, touched}: Form, path: Path): void {\n if (touched.has(path.key)) return;\n touched.add(path.key);\n // Path payload lets key-scoped subscribers skip unrelated fields;\n // payload-less listeners ignore it.\n emit(emitter, 'touched', path);\n}\n\n/** Check if a field has been touched. */\nexport function hasTouched<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): boolean {\n return hasTouchedByPath(form, createPath(name));\n}\n\n/** Check if a field has been touched by path. */\nexport function hasTouchedByPath({touched}: Form, path: Path): boolean {\n return touched.has(path.key);\n}\n\n/** Get touched fields as user-facing dotted paths ('a.b', 'a.0.c'). */\nexport function getTouchedFields({touched}: Form): string[] {\n return Array.from(touched, key => segmentsFromKey(key).join('.'));\n}\n\n/** Is touched — any field has been touched. */\nexport function isTouched({touched}: Form): boolean {\n return touched.size > 0;\n}\n","import {emit} from '../emitter';\nimport createPath, {segmentsFromKey} from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport type {PathValueOf, AnyPath} from '../types';\nimport {freezeValues, get, isEqual, setOwned, unset} from '../util';\nimport type {FieldError, Form} from '../form';\nimport {clearErrors, getErrorByPath, getFieldErrorsByPath} from './errors';\nimport {isFieldDirtyByPath} from './dirty';\nimport {setTouchedByPath} from './touched';\nimport {\n bumpDirtyVersion,\n bumpErrorsVersion,\n bumpValuesVersion,\n clearDirtyBaselines,\n getDirtyBaseline,\n getOrCreate,\n pruneDirtyBaselines,\n setDirtyBaseline,\n valuesCaches\n} from './internals';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/** Get form values: the values Map layered over parsedValues (when a\n * schema validation produced them) over initialValues. Merged with\n * copy-on-write ownership tracking ({@link setOwned}), so untouched\n * branches share references with the baseline. Memoized per form via a\n * version-bump/read counter ({@link bumpValuesVersion}): consecutive reads\n * hand back the same reference; treat it as read-only. parsedValues never\n * affects dirty state — dirty compares live edits against initialValues. */\nexport function getValues<T extends Record<string, any> = any>(\n form: Form<T>\n): T {\n const cache = getOrCreate(valuesCaches, form, () => ({\n version: 0,\n result: computeValues(form)\n }));\n if (cache.version > 0) {\n cache.result = computeValues(form);\n cache.version = 0;\n }\n return cache.result as T;\n}\n\nfunction computeValues(form: Form): any {\n const {initialValues, parsedValues, values, deleted} = form;\n const owned = new Set<object>();\n let merged = parsedValues ?? initialValues;\n for (const [key, value] of values) {\n merged = setOwned(merged, segmentsFromKey(key), value, owned);\n }\n // Tombstoned paths are removed so they don't fall back to initialValues.\n // unset is immutable (mutating delete would corrupt shared baseline\n // branches) and deletes outright rather than writing undefined.\n for (const key of deleted) {\n merged = unset(merged, segmentsFromKey(key));\n }\n // DEV-only: hand back a frozen clone (freezing in place would also\n // freeze the baseline containers it borrows from), so consumer mutations\n // throw at the offending site instead of corrupting the shared cache.\n return __DEV__ ? freezeValues(merged) : merged;\n}\n\n/** Get a field's value. */\nexport function getValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): PathValueOf<T, P> {\n return getValueByPath(form, createPath(name));\n}\n\n/** Get a field's value by path. */\nexport function getValueByPath(\n {initialValues, parsedValues, values, deleted}: Form,\n path: Path\n): any {\n const {key, value: segments} = path;\n if (values.has(key)) return values.get(key);\n // Unregistered path: the tombstone blocks the initialValues fallback.\n if (deleted.has(key)) return undefined;\n // A live ancestor key is a whole-branch write (setValue at a parent\n // path, every useFieldArray operation): it replaces the subtree below\n // it, so reads under it resolve from that stored value, nearest\n // ancestor first — a finer write is layered over a coarser one and\n // drops the superseded descendant keys, so the closest ancestor is the\n // newest generation. Paths the ancestor's value does not carry read\n // undefined — the baseline must not fill holes inside a replaced branch.\n for (let i = segments.length - 1; i > 0; i--) {\n const ancestorKey = JSON.stringify(segments.slice(0, i));\n if (values.has(ancestorKey)) {\n return get(values.get(ancestorKey), segments.slice(i));\n }\n }\n // Same layering as getValues: parsed values (when present) are the\n // baseline above initialValues.\n return get(parsedValues ?? initialValues, segments);\n}\n\n/** Options accepted by {@link setValue} / {@link setValueByPath} / {@link\n * changeValue} / {@link changeValueByPath}. `shouldValidate`/`shouldTouch`\n * default to `false`. */\nexport type SetFieldOptions = {\n /** Run the field's registered validator (if any) after the value lands.\n * Defaults to `false`. */\n shouldValidate?: boolean;\n /** Mark the field as touched. Defaults to `false`. */\n shouldTouch?: boolean;\n /** Land the value as a commit instead of an edit: it becomes the field's\n * dirty-comparison baseline. `true` (or omitting) keeps the default\n * derived behavior — dirty while the live value differs from\n * initialValues. */\n shouldDirty?: boolean;\n};\n\n/** Set a field's value. `value` may be an updater function receiving the\n * current value and returning the next (TanStack Form's `setFieldValue`\n * contract) — so a function can never itself be stored as a value. */\nexport function setValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(\n form: Form<T>,\n name: P,\n value: PathValueOf<T, P> | ((prev: PathValueOf<T, P>) => PathValueOf<T, P>),\n options?: SetFieldOptions\n): void {\n setValueByPath(form, createPath(name), value, options);\n}\n\n/** Set a field's value by path. `value` may be an updater function (see\n * {@link setValue}). */\nexport function setValueByPath(\n form: Form,\n path: Path,\n value: any | ((prev: any) => any),\n options?: SetFieldOptions\n): void {\n const {emitter, values, deleted} = form;\n const next =\n typeof value === 'function' ? value(getValueByPath(form, path)) : value;\n values.set(path.key, next);\n // The write replaces the whole subtree below it, so descendant keys in\n // the values Map belong to an older generation: without this prune they\n // would shadow the new value on exact-key reads and double-apply over it\n // in getValues' merge (a stale `a.b` would survive a fresh `a` write).\n pruneDescendantKeys(values, path);\n reviveBranch(deleted, path);\n // Baselines under the replaced subtree die with it — before the emit, so\n // subscribers reading dirty state in the emission never see a stale\n // commit suppressing the write they are being told about.\n pruneDirtyBaselines(form, path);\n if (options?.shouldDirty === false) setDirtyBaseline(form, path, next);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n if (options?.shouldTouch) setTouchedByPath(form, path);\n if (options?.shouldValidate) form.validators.get(path.key)?.();\n emit(emitter, 'change', path);\n}\n\n/** The write of {@link setValueByPath} minus the `'change'` emit: the\n * render-time `useField` `initialValue` seed. The field's first paint\n * (SSR included) must already carry the value, so the write happens during\n * render where emitting is illegal; the field announces it post-commit via\n * {@link emitChangeByPath}. */\nexport function seedValueByPath(form: Form, path: Path, value: any): void {\n const {values, deleted} = form;\n values.set(path.key, value);\n pruneDescendantKeys(values, path);\n reviveBranch(deleted, path);\n pruneDirtyBaselines(form, path);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n}\n\n/** Announce a {@link seedValueByPath} that happened during render: the\n * payload-carrying `'change'` emit {@link setValueByPath} would have\n * fired, split out so it runs post-commit where emitting is safe. */\nexport function emitChangeByPath({emitter}: Form, path: Path): void {\n emit(emitter, 'change', path);\n}\n\n/** One field's aggregated state, as {@link getFieldState} returns it.\n * `errors` is the stored array shared with the form — treat it read-only. */\nexport type FieldState<T = any> = {\n value: T;\n error: FieldError | undefined;\n errors: FieldError[];\n isDirty: boolean;\n isTouched: boolean;\n isValidating: boolean;\n};\n\n/** Get one field's aggregated state: layered value, first/every error,\n * dirtiness, touched flag, and validating flag. `isDirty` applies the same\n * per-field rule as {@link getDirtyFields}. */\nexport function getFieldState<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): FieldState<PathValueOf<T, P>> {\n const path = createPath(name);\n const {touched, validating} = form;\n return {\n value: getValueByPath(form, path),\n error: getErrorByPath(form, path),\n errors: getFieldErrorsByPath(form, path),\n // The shared per-field rule (committed baselines included): the field\n // is dirty while its live value differs from its effective baseline.\n isDirty: isFieldDirtyByPath(form, path),\n isTouched: touched.has(path.key),\n isValidating: validating.has(path.key)\n };\n}\n\n/** Options accepted by {@link removeField}. All flags default to `false` —\n * the historical remove semantics (value dropped, path tombstoned, dirty\n * baseline/touched/errors cleared). */\nexport type RemoveFieldOptions = {\n /** Keep the field's live value and dirty baseline instead of\n * tombstoning: reads, `getValues()`, and submit keep the value. */\n keepValue?: boolean;\n /** Keep the field's dirty baseline. Implies `keepValue`. */\n keepDirty?: boolean;\n /** Keep the field's touched flag instead of clearing it. */\n keepTouched?: boolean;\n /** Keep the field's errors instead of clearing them. */\n keepError?: boolean;\n};\n\nexport function removeField(\n form: Form,\n name: Name,\n options?: RemoveFieldOptions\n): void {\n removeFieldByPath(form, createPath(name), options);\n}\n\n/** Remove a field by path; the keep-flags preserve slices of state. */\nexport function removeFieldByPath(\n form: Form,\n path: Path,\n options?: RemoveFieldOptions\n): void {\n const {key, value: segments} = path;\n const {emitter, values, touched, errors, validating, deleted} = form;\n if (!options?.keepValue && !options?.keepDirty) {\n values.delete(key);\n // A remount starts fresh rather than inheriting a baseline committed\n // by the previous incarnation.\n clearDirtyBaselines(form, key);\n // Tombstone the unregistered path so later reads do not fall back to\n // initialValues and \"revive\" the old initial value. A tombstone never\n // shadows live values: skip it when a live ancestor or descendant key\n // already covers the branch.\n if (!hasLiveBranch(values, segments)) deleted.add(key);\n }\n if (!options?.keepTouched) touched.delete(key);\n if (!options?.keepError && errors.delete(key)) bumpErrorsVersion(form);\n validating.delete(key);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n // Path-payload emits, scoped exactly like the writes above (every\n // mutation is bounded to this path's key): leaf watchers on the path and\n // below it wake, ancestor branch watchers wake, and payload-less global\n // listeners wake regardless — while sibling fields stay asleep.\n emit(emitter, 'change', path);\n emit(emitter, 'touched', path);\n emit(emitter, 'errors', path);\n emit(emitter, 'validating', path);\n}\n\ntype ValuesMap = Map<string, any>;\n\n/** Does a live value cover the branch at `segments` — at an ancestor key\n * or below it at a descendant key? */\nfunction hasLiveBranch(values: ValuesMap, segments: PathSegments): boolean {\n for (let i = 1; i < segments.length; i++) {\n if (values.has(JSON.stringify(segments.slice(0, i)))) return true;\n }\n const stem = `${JSON.stringify(segments).slice(0, -1)},`;\n for (const key of values.keys()) {\n if (key.startsWith(stem)) return true;\n }\n return false;\n}\n\n/** Writing a value replaces the subtree below the written path, so drop\n * the values Map keys under it: they were set against an older generation\n * and would otherwise shadow the fresh value or re-apply over it. */\nfunction pruneDescendantKeys(values: ValuesMap, {key}: Path): void {\n if (!values.size) return;\n const stem = `${key.slice(0, -1)},`;\n for (const k of values.keys()) {\n if (k.startsWith(stem)) values.delete(k);\n }\n}\n\n/** Writing a value revives its whole branch: drop any removal tombstone\n * for the path itself, its ancestors, or its descendants. */\nfunction reviveBranch(deleted: Set<string>, {key}: Path): void {\n if (!deleted.size) return;\n for (const tombstone of deleted) {\n if (\n tombstone === key ||\n tombstone.startsWith(`${key.slice(0, -1)},`) ||\n key.startsWith(`${tombstone.slice(0, -1)},`)\n ) {\n deleted.delete(tombstone);\n }\n }\n}\n\n/** Set form initialValues. Content-based early return: a new reference with\n * equal content is a no-op (committed edits survive); genuinely changed\n * content swaps the baseline and re-seeds — live values and tombstones are\n * cleared, touched flags and errors survive. */\nexport function setInitialValues(form: Form, initialValues: any): void {\n if (\n form.initialValues === initialValues ||\n isEqual(form.initialValues, initialValues)\n ) {\n return;\n }\n form.initialValues = initialValues;\n // A new baseline invalidates the previous schema parse and every\n // baseline committed against the old one.\n form.parsedValues = undefined;\n form.values.clear();\n form.deleted.clear();\n clearDirtyBaselines(form);\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n emit(form.emitter, 'change');\n}\n\n/** Options accepted by {@link reset}. Every flag defaults to `false`. */\nexport type ResetOptions = {\n /** Keep the current values of fields that are dirty — differ from the\n * pre-reset initialValues (the same rule {@link getDirtyFields} applies). */\n keepDirtyValues?: boolean;\n /** Keep every field's current live value instead of returning to the\n * baseline (a superset of `keepDirtyValues`). Dirtiness is recomputed\n * against the post-reset baseline. */\n keepValues?: boolean;\n /** Ignore a newly provided `initialValues` and keep the current baseline. */\n keepDefaultValues?: boolean;\n /** Keep the touched set instead of clearing it. */\n keepTouched?: boolean;\n /** Keep field errors instead of clearing them. */\n keepErrors?: boolean;\n /** Keep the submitted flag (`isSubmitted`) instead of clearing it. */\n keepIsSubmitted?: boolean;\n /** Keep the last submit's success flag (`isSubmitSuccessful`). */\n keepIsSubmitSuccessful?: boolean;\n /** Keep `submitCount` instead of resetting it to 0. */\n keepSubmitCount?: boolean;\n /** Keep `isSubmitting` instead of resetting it to false. */\n keepIsSubmitting?: boolean;\n};\n\ntype KeptValue = {segments: PathSegments; value: any};\n\n/** Collect every leaf path of the merged values tree into `out` —\n * structured segments so each leaf can be written back with\n * setValueByPath. Objects with no enumerable keys are leaves themselves. */\nfunction collectValueLeaves(\n node: any,\n segments: PathSegments,\n out: KeptValue[]\n): void {\n if (node !== null && typeof node === 'object') {\n if (Array.isArray(node)) {\n node.forEach((item, i) =>\n collectValueLeaves(item, [...segments, i], out)\n );\n return;\n }\n const keys = Object.keys(node);\n if (keys.length > 0) {\n for (const k of keys) {\n collectValueLeaves(node[k], [...segments, k], out);\n }\n return;\n }\n }\n out.push({segments, value: node});\n}\n\n/** Snapshot the values {@link reset} re-seeds after the wipe: dirtiness is\n * measured against the pre-reset initialValues, so capture must happen\n * before form.values/form.initialValues are touched. The snapshot carries\n * structured segments, not dotted strings — dotted keys don't round-trip\n * through the parser. keepValues keeps every live value; keepDirtyValues\n * narrows the snapshot to fields differing from their effective baseline. */\nfunction collectKeptValues(form: Form, options?: ResetOptions): KeptValue[] {\n const kept: KeptValue[] = [];\n if (options?.keepValues) {\n // Every leaf of the CURRENT merged tree is written back after the\n // wipe, so a field with no live edit keeps its pre-reset value instead\n // of adopting the new baseline.\n collectValueLeaves(getValues(form), [], kept);\n } else if (options?.keepDirtyValues) {\n for (const [key, value] of form.values) {\n const segments = segmentsFromKey(key);\n // Same predicate as getDirtyFields: a live value differing from its\n // effective baseline (committed baselines read clean, not kept).\n if (getDirtyBaseline(form, key, segments) !== value) {\n kept.push({segments, value});\n }\n }\n }\n return kept;\n}\n\n/** Reset the form. Omitted (or undefined) `initialValues` keeps the current\n * baseline — fields simply return to it (react-hook-form's\n * reset-without-values semantics). */\nexport function reset(\n form: Form,\n initialValues?: any,\n options?: ResetOptions\n): void {\n const keptValues = collectKeptValues(form, options);\n // Omitting values is a return-to-initialValues reset, not a wipe: an\n // undefined baseline would make getValues() return undefined, so the\n // current baseline survives when no new one is provided.\n form.initialValues = options?.keepDefaultValues\n ? form.initialValues\n : (initialValues ?? form.initialValues);\n // The fresh baseline drops any schema parse from the previous cycle.\n form.parsedValues = undefined;\n if (!options?.keepErrors) clearErrors(form);\n const {emitter, touched, values, deleted, validating} = form;\n values.clear();\n deleted.clear();\n clearDirtyBaselines(form);\n if (!options?.keepTouched) touched.clear();\n validating.clear();\n if (!options?.keepIsSubmitting) form.isSubmitting = false;\n if (!options?.keepSubmitCount) form.submitCount = 0;\n if (!options?.keepIsSubmitted) form.isSubmitted = false;\n if (!options?.keepIsSubmitSuccessful) form.isSubmitSuccessful = undefined;\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n // Write the kept values back over the fresh baseline: plain\n // setValueByPath, so no validation fires and nothing is marked touched.\n for (const {segments, value} of keptValues) {\n setValueByPath(form, createPath(segments), value);\n }\n emit(emitter, 'change');\n emit(emitter, 'touched');\n emit(emitter, 'validating');\n emit(emitter, 'submitting');\n emit(emitter, 'submitCount');\n emit(emitter, 'submitSuccessful');\n emit(emitter, 'reset');\n}\n\n/** Options accepted by {@link resetField}. Flags default to `false`;\n * `value` has no default — omitted, the field falls back to initialValues. */\nexport type ResetFieldOptions = {\n /** Keep the field's touched flag instead of clearing it. */\n keepTouched?: boolean;\n /** Keep the field's errors instead of clearing them. */\n keepErrors?: boolean;\n /** Explicit post-reset value — never falls back to initialValues. */\n value?: any;\n};\n\n/** Reset a single field: drop its live value (reads fall back to the\n * baseline), clear touched/errors, and revive the path's tombstones — the\n * inverse of {@link removeFieldByPath}. Other fields are untouched. */\nexport function resetField<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, options?: ResetFieldOptions): void {\n const path = createPath(name);\n const {emitter, values, touched, errors, deleted} = form;\n values.delete(path.key);\n // Commits from before the reset no longer shadow the comparison.\n clearDirtyBaselines(form, path.key);\n // A parse baseline wholesale-shadows initialValues in reads, so unset\n // alone would read undefined. Remove the path from the tree (immutable —\n // parsedValues shares branches with the schema's output) and pin the\n // initial value back as the live value so the field stays clean.\n if (form.parsedValues !== undefined) {\n form.parsedValues = unset(form.parsedValues, path.value);\n const initial = get(form.initialValues, path.value);\n if (initial !== undefined) values.set(path.key, initial);\n }\n if (options && 'value' in options) {\n values.set(path.key, options.value);\n }\n // A reset re-registers the branch, same as a write: tombstones on the\n // path or around it stop applying.\n reviveBranch(deleted, path);\n // Payload-less by design (unlike removeFieldByPath): reviveBranch can\n // un-tombstone ancestor or descendant paths, whose readers must re-sync.\n emit(emitter, 'change');\n if (!options?.keepTouched && touched.delete(path.key)) {\n emit(emitter, 'touched', path);\n }\n if (!options?.keepErrors && errors.delete(path.key)) {\n bumpErrorsVersion(form);\n emit(emitter, 'errors', path);\n }\n bumpDirtyVersion(form);\n bumpValuesVersion(form);\n}\n","import {emit} from '../emitter';\nimport createPath, {segmentsFromKey} from '../path';\nimport type {Name, Path, PathSegments} from '../path';\nimport {isIndex, isPromise, normalizePath, waitUntil} from '../util';\nimport type {\n FieldError,\n FieldErrorEntry,\n Form,\n ReValidateMode,\n ValidationMode,\n ValidateResult,\n ValidationOutcome\n} from '../form';\nimport {\n VALIDATION_OUTCOME,\n ValidatorOutput,\n getErrors,\n getFirstError,\n hasErrors,\n setError,\n setErrorByPath\n} from './errors';\nimport {hasTouchedByPath, setTouchedByPath} from './touched';\nimport {getValueByPath, getValues} from './values';\nimport {\n bumpErrorsVersion,\n getOrCreate,\n isFieldError,\n isSegmentsPath,\n setParsedValues\n} from './internals';\n\ntype ErrorFootprint = Map<string, FieldError[]>;\n\n/** The meta bag passed to a validator's second argument. */\ntype ValidatorMeta = {form: Form; path: Path};\n\n/** A pending debounce-window handle, Node or DOM flavored. */\ntype Timer = ReturnType<typeof setTimeout> | null;\n\nexport function unsetValidatingByPath(\n {emitter, validating}: Form,\n path: Path\n): void {\n validating.delete(path.key);\n emit(emitter, 'validating', path);\n}\n\nexport function setValidatingByPath(\n {emitter, validating}: Form,\n path: Path\n): void {\n validating.add(path.key);\n emit(emitter, 'validating', path);\n}\n\n/** Field validator: an error (string, FieldError, or an array mixing\n * both) or undefined — synchronously or as a Promise. `meta.signal`\n * aborts when the round is superseded, so async work can be cancelled;\n * stale results are dropped by the round lock either way. Older\n * two-argument signatures keep working. */\nexport type Validator = (\n value: any,\n meta: ValidatorMeta & {signal: AbortSignal}\n) => ValidatorOutput | undefined | Promise<ValidatorOutput | undefined>;\n\n/** Synchronous pre-validator (declarative `required` gates in practice):\n * runs on every kick, never debounced; its errors land immediately and\n * short-circuit the debounced validator while present. No Promise, no\n * `signal` — nothing to abort. */\nexport type SyncValidator = (\n value: any,\n meta: ValidatorMeta\n) => ValidatorOutput | undefined;\n\n/** Live options for {@link registerValidatorByPath}: accessors, read at\n * every kick, so `useValidate` can swap them per render without\n * re-subscribing mid-flight. */\nexport type ValidatorRegistration = {\n validate: () => Validator | undefined;\n /** Debounce delay in milliseconds; 0 (default) runs immediately. */\n debounce: () => number;\n /** Runs on every kick, never debounced. */\n sync: () => SyncValidator | undefined;\n /** Keep the debounced validator running when the sync gate failed\n * (TanStack `asyncAlways`): gate errors land immediately, the\n * validator's result lands alongside them per-source. Absent = false\n * (gate owns the outcome). */\n asyncAlways?: () => boolean;\n};\n\n/** Normalize a validator verdict into its non-empty error list; null\n * when the verdict is clean. Field-error coercion stays with\n * setErrorByPath — this only answers \"is there anything to land\". */\nfunction asErrorList(\n output: ValidatorOutput | undefined\n): (string | FieldError)[] | null {\n if (output === undefined) return null;\n const list = Array.isArray(output) ? output : [output];\n return list.length ? list : null;\n}\n\n/**\n * Register a field validator's kick at `path` ({@link Form.validators})\n * — the framework-free machinery behind `useValidate`. Returns a\n * disposer that drops the registration and cancels pending work.\n *\n * Contract (what `trigger`/`ensureValidate`/the user-change gate rely\n * on): the `sync` gate runs on every kick, never debounced, and\n * short-circuits the debounced validator while failing — unless\n * `asyncAlways`, which lands the validator's result alongside the\n * gate's (per-source); a positive `debounce` merges kicks, and the\n * field counts as validating while the window is pending; async results\n * land under a round lock — superseded outcomes drop, only the owning\n * round releases the mark; a synchronous throw propagates. Registering\n * at an occupied path replaces the entry (last-wins).\n */\nexport function registerValidatorByPath(\n form: Form,\n path: Path,\n registration: ValidatorRegistration\n): () => void {\n let timer: Timer = null;\n let controller: AbortController | null = null;\n let marked = false;\n let lock: object | null = null;\n // Which source wrote the error on display — so a passing sync check\n // clears its own stale error immediately. External writers (setError,\n // form validate) are invisible here; clearing them on a pass is the\n // long-standing \"validator owns its whole key\" contract.\n let errorSource: 'sync' | 'validator' | null = null;\n const mark = () => {\n if (marked) return;\n marked = true;\n setValidatingByPath(form, path);\n };\n const unmark = () => {\n if (!marked) return;\n marked = false;\n unsetValidatingByPath(form, path);\n };\n\n /** Run the sync gate (never debounced). Errors land immediately; a\n * passing gate clears its own stale error — or any error when no\n * debounced validator exists to own the round. */\n const runSync = (): boolean => {\n const sync = registration.sync();\n if (!sync) return false;\n const gate = asErrorList(sync(getValueByPath(form, path), {form, path}));\n if (!gate) {\n if (!registration.validate() || errorSource === 'sync') {\n setErrorByPath(form, path, undefined);\n errorSource = null;\n }\n return false;\n }\n setErrorByPath(form, path, gate);\n errorSource = 'sync';\n return true;\n };\n\n /** Re-run the sync gate read-only: asyncAlways landings merge its\n * verdict with the validator's result (per-source). */\n const collectSyncErrors = (): (string | FieldError)[] | null => {\n const sync = registration.sync();\n if (!sync) return null;\n return asErrorList(sync(getValueByPath(form, path), {form, path}));\n };\n\n /** Land a validator result. asyncAlways merges the re-collected gate\n * verdict ahead of the validator's errors; the default path keeps the\n * historical \"validator owns the whole key\" write. */\n const land = (result: ValidatorOutput | undefined): void => {\n if (registration.asyncAlways?.()) {\n const gate = collectSyncErrors();\n const own = asErrorList(result) ?? [];\n setErrorByPath(form, path, [...(gate ?? []), ...own]);\n errorSource = own.length ? 'validator' : gate ? 'sync' : null;\n } else {\n setErrorByPath(form, path, result);\n errorSource = asErrorList(result) ? 'validator' : null;\n }\n };\n\n /** Terminal cancel: drop the pending window and in-flight round,\n * release the mark — one invariant, so no caller strands the mark (a\n * stranded mark hangs settle-waiters). Starting a NEW round\n * (runValidator) refreshes the lock inline instead: an unmark/remark\n * there would expose a false settled state to waiters. */\n const cancel = () => {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n controller?.abort();\n lock = {};\n unmark();\n };\n\n const runValidator = () => {\n const fn = registration.validate();\n if (!fn) {\n unmark();\n return;\n }\n // The lock refresh below drops results that ignore the abort.\n controller?.abort();\n controller = new AbortController();\n const round = (lock = {});\n let result;\n try {\n result = fn(getValueByPath(form, path), {\n form,\n path,\n signal: controller.signal\n });\n } catch (e) {\n // A throwing sync validator propagates to the caller as it always\n // has; just don't leave the validating mark stuck behind it.\n unmark();\n throw e;\n }\n if (!isPromise(result)) {\n land(result);\n // Error first, then release the mark: 'validating' subscribers\n // (trigger) re-read state on wake and must see the landed error.\n unmark();\n return;\n }\n mark();\n result\n .then((error: ValidatorOutput | undefined) => {\n if (lock === round) {\n land(error);\n }\n })\n // Rejection is how aborted validators give up (AbortError); the\n // owning round writes the outcome.\n .catch(() => {})\n .finally(() => {\n if (lock === round) {\n unmark();\n lock = null;\n }\n });\n };\n\n /** Run the sync gate; when it fails without asyncAlways, the gate owns\n * the outcome — supersede pending work, release the mark. */\n const gateOwnsKick = (): boolean => {\n if (!(runSync() && !registration.asyncAlways?.())) return false;\n cancel();\n return true;\n };\n\n /** Window fired: re-run the sync gate first — programmatic writes do\n * not kick validators, so the value may have drifted. */\n const run = () => {\n timer = null;\n if (gateOwnsKick()) return;\n runValidator();\n };\n\n const kick = () => {\n if (gateOwnsKick()) return;\n if (!registration.validate()) return;\n const debounce = registration.debounce();\n if (debounce > 0) {\n // The mark keeps trigger/ensureValidate waiting through the\n // pending timer, not just in-flight promises.\n if (timer !== null) clearTimeout(timer);\n else mark();\n timer = setTimeout(run, debounce);\n return;\n }\n runValidator();\n };\n\n form.validators.set(path.key, kick);\n return () => {\n form.validators.delete(path.key);\n cancel();\n };\n}\n\n/** Options accepted by {@link trigger}. `shouldTouch` defaults to `false`;\n * omitting the options object entirely keeps the plain validate-only\n * behavior, so the historical two-argument calls are untouched. */\nexport type TriggerOptions = {\n /** Mark the triggered scope touched once the round settles, pass or\n * fail (RHF trigger `shouldTouch`). Defaults to `false`. */\n shouldTouch?: boolean;\n /** Focus the first errored field in the triggered scope once the round\n * settles (RHF trigger `shouldFocus`). Rides the 'focusError' channel\n * like failed-submit auto-focus; unmounted paths are silent no-ops.\n * Defaults to `false`. */\n shouldFocus?: boolean;\n};\n\n/**\n * Trigger validation. Without `name`: every registered field validator,\n * then the form-level `validate` (after fields settle, same pipeline as\n * {@link ensureValidate}). One name runs that field only; a name array\n * runs each in order; `[]` is a no-op. A segments array mixes in numbers\n * (`['items', 0]`); pure string arrays are name lists (`['a', 'b']`\n * triggers fields `a` and `b`, not the nested path).\n *\n * The promise waits for the round to settle (async validators included)\n * and never rejects — it resolves whether the triggered scope is\n * error-free. With `name`, only those fields' errors count and\n * form-level `validate` is skipped (RHF semantics). Fire-and-forget\n * callers may ignore it: the kicks still run synchronously.\n */\nexport async function trigger(\n form: Form,\n name?: Name | Name[],\n options?: TriggerOptions\n): Promise<boolean> {\n // Never reject: an error landing is a normal outcome. Without a name\n // the wait is deliberately conservative — every field validator,\n // unrelated in-flight ones included, because the round covers the\n // whole form (the form-level validate's own window is excluded via\n // fieldsSettled — callers wait that out through the kick's promise).\n // With a name the wait narrows to the triggered keys: a slow async\n // validator on field B must not hold trigger('a') hostage.\n const settle = (keys?: string[]) =>\n waitUntil(\n form.emitter,\n 'validating',\n () =>\n keys === undefined\n ? fieldsSettled(form)\n : keys.every(key => !form.validating.has(key)),\n () => false\n );\n // First error wins, like failed-submit auto-focus; a form-level error\n // lands first but has no element — a silent no-op like every unbound\n // path.\n const focusFirstError = (keys?: string[]) => {\n const firstKey =\n keys === undefined\n ? form.errors.keys().next().value\n : keys.find(key => form.errors.has(key));\n if (firstKey !== undefined) emit(form.emitter, 'focusError', firstKey);\n };\n\n if (name === undefined) {\n form.validators.forEach(validator => validator());\n await settle();\n if (form.validate) await runFormValidate(form);\n if (options?.shouldTouch) touchKeys(form, [...form.validators.keys()]);\n if (options?.shouldFocus) focusFirstError();\n return !hasErrors(form);\n }\n\n const keys: string[] =\n typeof name === 'string' || isSegmentsPath(name)\n ? [createPath(name).key]\n : name.map(one => createPath(one).key);\n keys.forEach(key => form.validators.get(key)?.());\n await settle(keys);\n if (options?.shouldTouch) touchKeys(form, keys);\n if (options?.shouldFocus) focusFirstError(keys);\n return keys.every(key => !form.errors.has(key));\n}\n\n/** trigger's shouldTouch marking: setTouchedByPath no-ops on\n * already-touched keys and emits the path-payload 'touched' event per\n * newly touched one. */\nfunction touchKeys(form: Form, keys: string[]): void {\n keys.forEach(key => setTouchedByPath(form, createPath(segmentsFromKey(key))));\n}\n\n/** Flatten a form-level validate result into field errors: nested objects\n * descend ({a: {b: 'msg'}} → the 'a.b' error), arrays contribute every\n * non-empty string (zod formErrors style), FieldError objects are stored\n * as-is, falsy values skipped. With `footprint` (validateDeps / live\n * validateMode forms) each stored leaf is recorded — the exact stored\n * array — so the next round can drop exactly what this one wrote. */\nfunction setFormErrors(\n form: Form,\n result: Record<string, any>,\n segments: PathSegments = [],\n footprint?: ErrorFootprint\n): void {\n Object.entries(result).forEach(([key, value]) => {\n // Numeric keys are explicit object keys, not path expressions: '0'\n // (Standard Schema issue paths stringify array indices) stays a\n // literal string segment instead of feeding the path parser.\n const path: PathSegments = [\n ...segments,\n ...(isIndex(key) ? [key] : normalizePath(key))\n ];\n if (typeof value === 'string') {\n if (value) landLeafError(form, path, value, footprint);\n } else if (Array.isArray(value) || isFieldError(value)) {\n landLeafError(form, path, value, footprint);\n } else if (value && typeof value === 'object') {\n setFormErrors(form, value, path, footprint);\n }\n });\n}\n\n/** Record one leaf write into the round's footprint: the path key and\n * the exact stored array (read back — setErrorByPath owns\n * normalization; all-empty writes record nothing). */\nfunction recordFootprint(\n form: Form,\n segments: PathSegments,\n footprint: ErrorFootprint | undefined\n): void {\n if (!footprint) return;\n const path = createPath(segments);\n const stored = form.errors.get(path.key);\n if (stored) footprint.set(path.key, stored);\n}\n\nfunction landLeafError(\n form: Form,\n path: PathSegments,\n error: ValidatorOutput,\n footprint?: ErrorFootprint\n): void {\n setError(form, path, error);\n recordFootprint(form, path, footprint);\n}\n\n/** Land a form-level validate result. A plain record flattens into field\n * errors; a branded {@link ValidationOutcome} also sets `values` as the\n * parsedValues baseline. Forms re-running the validate on user input\n * (validateDeps or a live validateMode) get round-scoped ownership: the\n * previous round's errors are dropped first, so a passing re-run clears\n * its cross-field error; submit-only forms keep the write-only\n * behavior. */\nfunction applyValidateResult(\n form: Form,\n result: ValidateResult<any> | undefined\n): void {\n const footprint =\n form.validateDeps || form.validateMode !== 'onSubmit'\n ? getFormErrorFootprint(form)\n : undefined;\n if (footprint) {\n clearFormValidateErrors(form, footprint);\n footprint.clear();\n }\n if (!result) return;\n if (typeof result === 'object' && VALIDATION_OUTCOME in result) {\n const outcome = result as ValidationOutcome<any>;\n if (outcome.errors) setFormErrors(form, outcome.errors, [], footprint);\n setParsedValues(form, outcome.values);\n return;\n }\n setFormErrors(form, result as Record<string, any>, [], footprint);\n}\n\n/** Per-form footprint of the last form-level round: path key → the exact\n * stored array. WeakMap — the Form shape stays untouched. */\nconst formErrorFootprints = new WeakMap<Form, ErrorFootprint>();\n\nfunction getFormErrorFootprint(form: Form): ErrorFootprint {\n return getOrCreate(formErrorFootprints, form, () => new Map());\n}\n\n/** Does the form still show an error the last round wrote? Identity\n * comparison: once a field validator, setServerErrors, setError or\n * clearErrors replaces the stored array, the error is no longer the\n * round's to own. */\nfunction hasFormValidateErrors(form: Form): boolean {\n const footprint = formErrorFootprints.get(form);\n if (!footprint) return false;\n for (const [key, written] of footprint) {\n if (form.errors.get(key) === written) return true;\n }\n return false;\n}\n\n/** Drop the last round's errors before the next lands, per key\n * identity-checked (overwritten/cleared errors survive); each drop emits\n * the same path-payload 'errors' event as setErrorByPath. */\nfunction clearFormValidateErrors(form: Form, footprint: ErrorFootprint): void {\n for (const [key, written] of footprint) {\n const stored = form.errors.get(key);\n if (stored !== written) continue;\n form.errors.delete(key);\n bumpErrorsVersion(form);\n emit(form.emitter, 'errors', createPath(segmentsFromKey(key)));\n }\n}\n\n/** Reserved validating key for the form-level round; real path keys are\n * JSON arrays, so a bare word can never collide. */\nconst FORM_VALIDATING_KEY = '__form_validate__';\n\n/** Are all FIELD rounds drained? The form validate's own reserved key is\n * excluded — its window is waited out through the kick's promise, so a\n * pending form window never gates the next kick (a newer round\n * supersedes, mirroring per-field debounce). */\nfunction fieldsSettled(form: Form): boolean {\n for (const key of form.validating) {\n if (key !== FORM_VALIDATING_KEY) return false;\n }\n return true;\n}\n\n/** Sentinel telling {@link settleFormValidate} the round landed cleanly —\n * distinct from every rejection payload, including `undefined`. */\nconst SETTLED = Symbol('form-validate-settled');\n\ntype FormValidateState = {\n timer: Timer;\n controller: AbortController | null;\n /** Identity of the in-flight round; superseded outcomes (rejections\n * included) are dropped by comparing against it. */\n round: object | null;\n marked: boolean;\n waiters: Array<{resolve: () => void; reject: (error: unknown) => void}>;\n};\n\n/** Per-form debounced-validate bookkeeping — WeakMap, so the Form shape\n * stays untouched for forms that never set `validateDebounce`. */\nconst formValidateStates = new WeakMap<Form, FormValidateState>();\n\nfunction getFormValidateState(form: Form): FormValidateState {\n return getOrCreate(formValidateStates, form, () => ({\n timer: null,\n controller: null,\n round: null,\n marked: false,\n waiters: []\n }));\n}\n\n/**\n * Run the form-level `validate` and land its result, honoring\n * `validateDebounce`. Undebounced: the caller's await is the call — no\n * mark, no gating, rejection propagates. Debounced: kicks merge into a\n * window (the form counts as validating), the round reads then-current\n * values and supersedes in-flight rounds, and every merged caller's\n * promise settles with the final round's outcome. Form-level-only round:\n * `useForm`'s validateOnMount and cross-cutting re-checks; `trigger` /\n * `ensureValidate` compose it after fields settle.\n */\nexport function runFormValidate(form: Form): Promise<void> {\n const validate = form.validate;\n if (!validate) return Promise.resolve();\n const debounce = form.validateDebounce ?? 0;\n if (debounce <= 0) {\n // Argument-shape parity with the debounced rounds; the signal never\n // fires (nothing supersedes an undebounced call).\n const controller = new AbortController();\n return Promise.resolve(\n validate(getValues(form), {form, signal: controller.signal})\n ).then(result => {\n applyValidateResult(form, result);\n });\n }\n const state = getFormValidateState(form);\n // Re-open the window: pending kicks restart the timer; an in-flight\n // round keeps the mark held until the new window's round.\n if (state.timer !== null) clearTimeout(state.timer);\n else {\n state.marked = true;\n form.validating.add(FORM_VALIDATING_KEY);\n emit(form.emitter, 'validating');\n }\n state.timer = setTimeout(() => {\n state.timer = null;\n const round = (state.round = {});\n runFormValidateRound(form, state, round).then(\n () => settleFormValidate(form, state, round, SETTLED),\n error => settleFormValidate(form, state, round, error)\n );\n }, debounce);\n return new Promise<void>((resolve, reject) => {\n state.waiters.push({resolve, reject});\n });\n}\n\n/** One round with the current values; aborts and drops the superseded\n * round, field-lock style. */\nfunction runFormValidateRound(\n form: Form,\n state: FormValidateState,\n round: object\n): Promise<void> {\n const validate = form.validate;\n if (!validate) return Promise.resolve();\n state.controller?.abort();\n const controller = (state.controller = new AbortController());\n // The Promise constructor turns a synchronous validator throw into a\n // rejection — the try/catch comes for free.\n const outcome = new Promise<any>(resolve =>\n resolve(validate(getValues(form), {form, signal: controller.signal}))\n );\n return outcome.then(\n result => {\n if (state.round === round) applyValidateResult(form, result);\n },\n error => {\n if (state.round === round) throw error;\n }\n );\n}\n\n/** Land the window group: release the mark (after the round's errors\n * landed — 'validating' subscribers re-read state on wake), settle every\n * merged waiter. A superseded round never lands here; a re-opened window\n * carries the mark and waiters over to the pending round. */\nfunction settleFormValidate(\n form: Form,\n state: FormValidateState,\n round: object,\n outcome: unknown\n): void {\n if (state.round !== round) return;\n state.round = null;\n if (state.timer !== null) return;\n if (state.marked) {\n state.marked = false;\n form.validating.delete(FORM_VALIDATING_KEY);\n emit(form.emitter, 'validating');\n }\n const waiters = state.waiters;\n state.waiters = [];\n for (const waiter of waiters) {\n if (outcome === SETTLED) waiter.resolve();\n else waiter.reject(outcome);\n }\n}\n\n/** The mode/reValidateMode gate shared by change/blur kicks and both\n * validateDeps re-runs: fires for `cadence` and `'all'`, for\n * `'onTouched'` once touched, else when `reValidateMode` matches\n * `cadence` and an error is still live. `hasError` reads lazily. */\nexport function shouldKick(\n mode: ValidationMode,\n cadence: 'onChange' | 'onBlur',\n touched: boolean,\n hasError: () => boolean,\n reValidateMode: ReValidateMode\n): boolean {\n return (\n mode === cadence ||\n mode === 'all' ||\n (mode === 'onTouched' && touched) ||\n (reValidateMode === cadence && hasError())\n );\n}\n\n/**\n * Form-level twin of the gated change kick: re-run `validate` after a\n * user change to a field in `validateDeps`. Rides the changed field's\n * onChange pipeline, so programmatic setValue writes never fire it. The\n * gate uses the changed field's effective `mode` and the form-level\n * `reValidateMode` against the last round's error footprint:\n * onChange/all — every dep change; onTouched — once touched; otherwise\n * while the round's error is still live under reValidateMode onChange\n * (the submit-then-fix flow). Fire-and-forget: async rejections are\n * swallowed, sync throws propagate. A no-op (one property check) unless\n * `validateDeps` lists `path`.\n */\nexport function revalidateFormOnChange(\n form: Form,\n path: Path,\n mode: ValidationMode\n): void {\n if (!form.validateDeps?.has(path.key) || !form.validate) return;\n if (\n shouldKick(\n mode,\n 'onChange',\n hasTouchedByPath(form, path),\n () => hasFormValidateErrors(form),\n form.reValidateMode\n )\n ) {\n runFormValidate(form).catch(() => {});\n }\n}\n\n/** Field-level validateDeps registry: dep key → dependents listing it\n * (WeakMap — Form shape untouched). */\nconst fieldValidateDeps = new WeakMap<Form, Map<string, Set<string>>>();\n\n/** Register one field's deps: `key` re-validates when any path in\n * `depKeys` changes. Idempotent per pair — StrictMode's double effect is\n * harmless. */\nexport function registerFieldValidateDeps(\n form: Form,\n key: string,\n depKeys: string[]\n): void {\n const deps = getOrCreate(fieldValidateDeps, form, () => new Map());\n for (const depKey of depKeys) {\n const dependents = deps.get(depKey) ?? new Set<string>();\n dependents.add(key);\n deps.set(depKey, dependents);\n }\n}\n\n/** Drop one field's deps registration; empty entries are removed so the\n * registry never outlives its fields. */\nexport function unregisterFieldValidateDeps(\n form: Form,\n key: string,\n depKeys: string[]\n): void {\n const deps = fieldValidateDeps.get(form);\n if (!deps) return;\n for (const depKey of depKeys) {\n const dependents = deps.get(depKey);\n if (!dependents?.delete(key)) continue;\n if (!dependents.size) deps.delete(depKey);\n }\n}\n\n/**\n * Field-level twin: after a user change to `path`, re-run every field\n * validator that declared it as a dep. Same channel and gate as\n * {@link revalidateFormOnChange} — the dependent's own error arms\n * reValidateMode, and a passing re-run replaces it (a field validator\n * owns its whole key). Ordinary validator kicks: the dependent's\n * debounce applies, sync throws propagate. A no-op unless some field\n * declared `path` as a dep.\n */\nexport function revalidateDependentsOnChange(\n form: Form,\n path: Path,\n mode: ValidationMode\n): void {\n const dependents = fieldValidateDeps.get(form)?.get(path.key);\n if (!dependents?.size) return;\n for (const dependent of dependents) {\n // A self-dep: the field's own onChange already validated it.\n if (dependent === path.key) continue;\n if (\n shouldKick(\n mode,\n 'onChange',\n hasTouchedByPath(form, path),\n () => form.errors.has(dependent),\n form.reValidateMode\n )\n ) {\n form.validators.get(dependent)?.();\n }\n }\n}\n\n/** {@link ensureValidate}'s rejection: `message` is the first error's\n * display text; `.errors` carries the full flattened list ({@link\n * getErrors}) for branching without re-reading the form. */\nexport type FormValidationError = Error & {errors: FieldErrorEntry[]};\n\nfunction validationError(form: Form): FormValidationError {\n const error = new Error(getFirstError(form)) as FormValidationError;\n error.errors = getErrors(form);\n return error;\n}\n\n/**\n * Validate and throw if any field error.\n * @param form\n * @return resolve if no error; reject and stop validate if has an error\n */\nexport async function ensureValidate(form: Form): Promise<void> {\n form.validators.forEach(validator => validator());\n\n await waitUntil(\n form.emitter,\n 'validating',\n () => fieldsSettled(form),\n () => hasErrors(form)\n ).catch(() => {\n throw validationError(form);\n });\n\n if (form.validate) {\n await runFormValidate(form);\n if (hasErrors(form)) throw validationError(form);\n }\n}\n\n/**\n * Validate and return if any field error.\n * @param form\n * @return error message string or void\n */\nexport async function validate(form: Form): Promise<void | string> {\n return ensureValidate(form).catch(e => e.message);\n}\n","import createPath from '../path';\nimport type {Path} from '../path';\nimport type {PathValueOf, AnyPath} from '../types';\nimport type {Form, FormValidateMode, ValidationMode} from '../form';\nimport {setValueByPath} from './values';\nimport type {SetFieldOptions} from './values';\nimport {\n revalidateFormOnChange,\n revalidateDependentsOnChange,\n runFormValidate,\n shouldKick\n} from './validate';\nimport {hasTouchedByPath, setTouchedByPath} from './touched';\nimport {getFieldErrorsByPath} from './errors';\nimport {getOrCreate, setDirtyBaseline} from './internals';\n\n/** Per-form registry of mounted fields' validation-mode overrides: path\n * key -> the field's `mode` option plus an owner token. Presence of an\n * entry is the \"a field is mounted at this path\" signal that routes\n * {@link changeValueByPath} into the gated pipeline. WeakMap so the Form\n * shape carries only plain state fields. */\nconst fieldModes = new WeakMap<\n Form,\n Map<string, {mode: ValidationMode | undefined; token: object}>\n>();\n\n/** Set a field's value as a user change. When a field is mounted on the\n * path it rides the gated user-change pipeline (the field's effective\n * `mode` and the form's `reValidateMode` drive validation, as in\n * {@link userChangeByPath}); with no mounted field it degrades to a plain\n * {@link setValue}. Contrast {@link setValue}, whose `shouldValidate`\n * kicks the validator unconditionally. */\nexport function changeValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(\n form: Form<T>,\n name: P,\n value: PathValueOf<T, P>,\n options?: SetFieldOptions\n): void {\n changeValueByPath(form, createPath(name), value, options);\n}\n\n/** Set a field's value as a user change, by parsed path. */\nexport function changeValueByPath(\n form: Form,\n path: Path,\n value: any,\n options?: SetFieldOptions\n): void {\n // The baseline must land before the mounted field's pipeline runs — its\n // write emits synchronously and subscribers read dirty state in the\n // emission, so installing after would flash dirty-then-clean.\n if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);\n if (fieldModes.get(form)?.get(path.key)) {\n // Mounted field: the field's own mode drives validation, so\n // `shouldValidate`/`shouldTouch` have no meaning here.\n userChangeByPath(form, path, value);\n } else {\n setValueByPath(form, path, value, options);\n }\n}\n\n/** Register a mounted field's `mode` override at `path` for user-change\n * gating. Returns the registration token for {@link unregisterFieldMode}\n * plus whether the slot was already occupied — two fields at one path is\n * almost always a bug (the latest mount's mode governs). */\nexport function registerFieldMode(\n form: Form,\n path: Path,\n mode: ValidationMode | undefined\n): {token: object; displaced: boolean} {\n const modes = getOrCreate(fieldModes, form, () => new Map());\n const displaced = modes.has(path.key);\n const token = {};\n modes.set(path.key, {mode, token});\n return {token, displaced};\n}\n\n/** Drop a {@link registerFieldMode} registration; only the entry owned by\n * `token` is removed, so a later mount keeps its slot. */\nexport function unregisterFieldMode(\n form: Form,\n path: Path,\n token: object\n): void {\n const modes = fieldModes.get(form);\n const entry = modes?.get(path.key);\n if (modes && entry && entry.token === token) modes.delete(path.key);\n}\n\n/** First key in the mounted-field registry that is a strict descendant of\n * `ancestor`, in registration order — undefined when none is mounted.\n * Same descendant rule as `onPathEvent` ('['+','+segment keeps sibling\n * lookalike keys from matching). */\nexport function firstMountedDescendantKey(\n form: Form,\n ancestor: Path\n): string | undefined {\n const prefix = `${ancestor.key.slice(0, -1)},`;\n for (const key of fieldModes.get(form)?.keys() ?? []) {\n if (key.startsWith(prefix)) return key;\n }\n return undefined;\n}\n\n/** Fire the form-level validate cadence and swallow the async rejection —\n * nothing in a change/blur handler can await the round. */\nfunction fireFormValidate(form: Form, cadence: FormValidateMode): void {\n if (form.validateMode !== cadence || !form.validate) return;\n runFormValidate(form).catch(() => {});\n}\n\n/** Kick the path's field validator under the mode/reValidateMode gate.\n * The live (stored) error view arms the reValidate kick — an error\n * behind a delayError window still counts. */\nfunction kickFieldValidator(\n form: Form,\n path: Path,\n mode: ValidationMode,\n cadence: 'onChange' | 'onBlur',\n touched: boolean\n): void {\n if (\n shouldKick(\n mode,\n cadence,\n touched,\n () => getFieldErrorsByPath(form, path).length > 0,\n form.reValidateMode\n )\n )\n form.validators.get(path.key)?.();\n}\n\n/** The user-change validation gate shared by a mounted field's onChange\n * and {@link changeValueByPath}: kick the field's validator, the\n * form-level `validateDeps` re-run and field-level dependents under the\n * mode/reValidateMode matrix. */\nfunction runUserChangeGate(form: Form, path: Path, mode: ValidationMode): void {\n kickFieldValidator(\n form,\n path,\n mode,\n 'onChange',\n hasTouchedByPath(form, path)\n );\n // Form-level validate deps: a user change to a listed field re-runs the\n // form-level validate under the same gate. No-op without validateDeps.\n revalidateFormOnChange(form, path, mode);\n // Form-level validate cadence (Options.validateMode): 'onChange' re-runs\n // the form-level validate on every user change — no dep list required.\n fireFormValidate(form, 'onChange');\n // Field-level validate deps: fields that declared this path re-run their\n // own validators. No-op when nobody declared it.\n revalidateDependentsOnChange(form, path, mode);\n}\n\n/** Write a bound field's user change by path: the write plus the\n * mode/reValidateMode-gated validation pipeline. Reads the effective mode\n * from the field-mode registry, so a plain write happens when no field is\n * registered at `path`. Framework adapters forward their change events\n * here. */\nexport function userChangeByPath(form: Form, path: Path, value: any): void {\n setValueByPath(form, path, value);\n const entry = fieldModes.get(form)?.get(path.key);\n if (entry) runUserChangeGate(form, path, entry.mode ?? form.mode);\n}\n\n/** A bound field's blur: mark the path touched (unconditional), then kick\n * its validator under the blur-side gate. Framework adapters forward blur\n * events here. */\nexport function userBlur(form: Form, path: Path): void {\n setTouchedByPath(form, path);\n const entry = fieldModes.get(form)?.get(path.key);\n if (!entry) return;\n kickFieldValidator(form, path, entry.mode ?? form.mode, 'onBlur', true);\n // Form-level validate cadence (Options.validateMode): 'onBlur' re-runs\n // the form-level validate on every user blur.\n fireFormValidate(form, 'onBlur');\n}\n","/** Unmount-removal helpers: the snapshot/remove pair and its restore.\n * React 19's StrictMode double-invokes effects on the initial mount, so a\n * plain cleanup that calls {@link removeFieldByPath} wipes a field the\n * very next setup expects. `useUnmountRestore` runs the teardown on every\n * cleanup and restores on the setup that follows (which exists only in the\n * StrictMode cycle), undoing the removal before anything observes the gap.\n * Internal: hooks import it directly, the facade never re-exports it. */\nimport {emit} from '../emitter';\nimport type {FieldError, Form} from '../form';\nimport type {Path} from '../path';\nimport {setErrorByPath} from './errors';\nimport {bumpValuesVersion} from './internals';\nimport {setTouchedByPath} from './touched';\nimport {removeFieldByPath, setValueByPath} from './values';\n\n/** Everything {@link removeFieldByPath} destroys, captured before it runs\n * so {@link restoreRemovedField} can put it back. */\nexport type RemovedFieldSnapshot = {\n /** Whether the values Map held the key — restores the exact entry,\n * including an explicit `undefined` value. */\n present: boolean;\n value: any;\n touched: boolean;\n errors: FieldError[] | undefined;\n};\n\n/** Snapshot the field's state, then remove it — the teardown half of the\n * StrictMode-safe unmount removal. */\nexport function removeFieldForUnmount(\n form: Form,\n path: Path\n): RemovedFieldSnapshot {\n const {key} = path;\n const snapshot: RemovedFieldSnapshot = {\n present: form.values.has(key),\n value: form.values.get(key),\n touched: form.touched.has(key),\n errors: form.errors.get(key)\n };\n removeFieldByPath(form, path);\n return snapshot;\n}\n\n/** Undo {@link removeFieldForUnmount} — the restore half, run only by a\n * setup that immediately follows the cleanup (the StrictMode remount).\n * Rebuilds the exact pre-removal state:\n * - a Map-backed value re-lands via {@link setValueByPath} with\n * `shouldDirty: false` (the removal cleared committed baselines; the\n * restored value becomes the baseline — identical dirty reads)\n * - a baseline-derived value (absent from the Map) only needs its\n * tombstone undone — no write, so no entry materializes\n * - touched/errors re-add without re-validating\n */\nexport function restoreRemovedField(\n form: Form,\n path: Path,\n snapshot: RemovedFieldSnapshot\n): void {\n const {key} = path;\n if (snapshot.present) {\n setValueByPath(form, path, snapshot.value, {shouldDirty: false});\n } else {\n form.deleted.delete(key);\n bumpValuesVersion(form);\n // The removal emitted with a path payload; the restore must wake the\n // same subscribers so snapshots taken in the gap re-sync.\n emit(form.emitter, 'change', path);\n }\n if (snapshot.touched) setTouchedByPath(form, path);\n if (snapshot.errors) setErrorByPath(form, path, snapshot.errors);\n}\n","import type {FieldError} from './form';\nimport type {SyncValidator} from './hooks/validate';\n\n/** Type tag of a failed rule, as stored on the resulting FieldError. */\nexport type RuleType =\n 'required' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern';\n\n/** Form-level default rule messages — the `createForm({messages})` table\n * overriding the built-in English defaults for every field (i18n in one\n * place). A string may carry a `{bound}` placeholder (replaced with the\n * rule's bound); a function receives the bound. A field's own message\n * (the `required` string, `rules.messages`, `pattern.message`) still\n * wins. */\nexport type FormMessages = Partial<\n Record<RuleType, string | ((bound?: number) => string)>\n>;\n\n/** Declarative field rules — a subset of react-hook-form's `register`\n * rules. Failures land in the error state as FieldErrors (`type` = rule\n * name), so any design system can render them. */\nexport type FieldRules = {\n /** Fails on `''`, `undefined`, `null` or an empty array (`0`/`false`\n * count as filled). A string is the message, `true` the default; failing\n * skips the remaining rules. */\n required?: string | true;\n /** Fails when `Number(value)` is below this bound; `NaN` values skip. */\n min?: number;\n /** Fails when `Number(value)` is above this bound; `NaN` values skip. */\n max?: number;\n /** Fails when a string/array is shorter than this; other values skip. */\n minLength?: number;\n /** Fails when a string/array is longer than this; other values skip. */\n maxLength?: number;\n /** Fails when the value does not match `pattern.value`. */\n pattern?: {value: RegExp; message: string};\n /** Custom rule callbacks (one function or a named record), run after the\n * declarative checks pass. A returned error keeps its message; `type`\n * becomes the record key (`'validate'` for the single-function form).\n * Sync-only. */\n validate?: SyncValidator | Record<string, SyncValidator>;\n /** Per-rule-type message override (defaults and pattern's inline message). */\n messages?: Partial<Record<Exclude<RuleType, 'required'>, string>>;\n};\n\n/** Does `rules` declare any constraint? `messages` alone would still open\n * debounce windows and hold the validating mark for nothing; `validate`\n * callbacks count. */\nexport function hasRuleConstraints(rules: FieldRules): boolean {\n return (\n rules.required !== undefined ||\n rules.min !== undefined ||\n rules.max !== undefined ||\n rules.minLength !== undefined ||\n rules.maxLength !== undefined ||\n rules.pattern !== undefined ||\n rules.validate !== undefined\n );\n}\n\n/** Default English messages, aligned with RHF's default-message style. */\nfunction defaultMessage(type: RuleType, bound?: number): string {\n switch (type) {\n case 'required':\n return 'This field is required';\n case 'min':\n return `Must be at least ${bound}`;\n case 'max':\n return `Must be at most ${bound}`;\n case 'minLength':\n return `Must be at least ${bound} characters`;\n case 'maxLength':\n return `Must be at most ${bound} characters`;\n case 'pattern':\n return 'Invalid format';\n default:\n return 'Invalid value';\n }\n}\n\n/** Resolve a form-level override entry: a function takes the bound, a\n * string gets its `{bound}` placeholder replaced. */\nfunction resolveMessage(\n entry: string | ((bound?: number) => string) | undefined,\n bound?: number\n): string | undefined {\n return typeof entry === 'function'\n ? entry(bound)\n : entry?.replace('{bound}', String(bound));\n}\n\n/** One bound rule: the FieldRules key, how `value` is measured\n * (`undefined` skips — `NaN` numbers, unsized values), and which side of\n * the bound fails. */\ntype BoundCheck = readonly [\n type: Exclude<RuleType, 'required' | 'pattern'>,\n measure: (value: any) => number | undefined,\n fails: (metric: number, bound: number) => boolean\n];\n\nfunction numericMetric(value: any): number | undefined {\n const n = Number(value);\n return Number.isNaN(n) ? undefined : n;\n}\n\nfunction sizedMetric(value: any): number | undefined {\n return typeof value === 'string' || Array.isArray(value)\n ? value.length\n : undefined;\n}\n\n/** The bound checks in declaration order. */\nconst BOUND_CHECKS: readonly BoundCheck[] = [\n ['min', numericMetric, (metric, bound) => metric < bound],\n ['max', numericMetric, (metric, bound) => metric > bound],\n ['minLength', sizedMetric, (metric, bound) => metric < bound],\n ['maxLength', sizedMetric, (metric, bound) => metric > bound]\n];\n\n/** Compile {@link FieldRules} into a {@link SyncValidator}: `required`\n * short-circuits the rest when it fails; other failures collect into one\n * FieldError[] in declaration order. Messages resolve to the rule's own\n * string, `rules.messages`, the form-level {@link FormMessages} table,\n * or the default. */\nexport function rulesToValidator(\n rules: FieldRules,\n formMessages?: FormMessages\n): SyncValidator {\n return (value, meta) => {\n if (rules.required) {\n if (\n value === '' ||\n value === undefined ||\n value === null ||\n (Array.isArray(value) && value.length === 0)\n ) {\n return [\n {\n type: 'required',\n message:\n typeof rules.required === 'string'\n ? rules.required\n : (resolveMessage(formMessages?.required) ??\n defaultMessage('required'))\n }\n ];\n }\n }\n const errors: FieldError[] = [];\n const message = (type: Exclude<RuleType, 'required'>, bound: number) =>\n rules.messages?.[type] ??\n resolveMessage(formMessages?.[type], bound) ??\n defaultMessage(type, bound);\n for (const [type, measure, fails] of BOUND_CHECKS) {\n const bound = rules[type];\n if (bound === undefined) continue;\n const metric = measure(value);\n if (metric !== undefined && fails(metric, bound)) {\n errors.push({type, message: message(type, bound)});\n }\n }\n if (rules.pattern && !rules.pattern.value.test(value)) {\n errors.push({\n type: 'pattern',\n // pattern.message is type-required but JS consumers may omit it.\n message:\n rules.messages?.pattern ??\n rules.pattern.message ??\n resolveMessage(formMessages?.pattern) ??\n defaultMessage('pattern')\n });\n }\n if (rules.validate !== undefined) {\n const fns =\n typeof rules.validate === 'function'\n ? {validate: rules.validate}\n : rules.validate;\n for (const [type, fn] of Object.entries(fns)) {\n const result = fn(value, meta);\n if (result === undefined) continue;\n // Each custom rule owns its `type`: the record key (or 'validate').\n for (const entry of Array.isArray(result) ? result : [result]) {\n errors.push(\n typeof entry === 'string'\n ? {type, message: entry}\n : {...entry, type}\n );\n }\n }\n }\n return errors.length ? errors : undefined;\n };\n}\n\n/** Map {@link FieldRules} onto native constraint attributes (the subset\n * the platform exposes): browser/AT hints only — the store pipeline stays\n * the source of truth for messages. `validate` callbacks are skipped. */\nexport function rulesToConstraintAttrs(rules: FieldRules): Record<string, any> {\n const attrs: Record<string, any> = {};\n if (rules.required) attrs.required = true;\n for (const key of ['min', 'max', 'minLength', 'maxLength'] as const) {\n if (rules[key] !== undefined) attrs[key] = rules[key];\n }\n if (rules.pattern) attrs.pattern = rules.pattern.value.source;\n return attrs;\n}\n","import {on} from '../emitter';\nimport createPath from '../path';\nimport type {Name, Path} from '../path';\nimport type {Form, RegisterOptions, RegisterProps} from '../form';\nimport {\n changeValueByPath,\n registerFieldMode,\n unregisterFieldMode,\n userBlur\n} from './change';\nimport {emitChangeByPath, getValueByPath, seedValueByPath} from './values';\nimport {registerValidatorByPath} from './validate';\nimport type {ValidatorRegistration} from './validate';\nimport {removeFieldForUnmount, restoreRemovedField} from './unmount';\nimport type {RemovedFieldSnapshot} from './unmount';\nimport {hasRuleConstraints, rulesToValidator} from '../rules';\n\n/**\n * Create a non-hook field binding — react-hook-form's `register`\n * contract, wired onto this library's store: the bound element never\n * re-renders, every change still lands in the store through the gated\n * user-change pipeline, and `trigger`/submit/`getValues` read it like\n * any other field. `useField({uncontrolled: true})` already covers the\n * hook case; `register` exists for the call sites a hook cannot serve —\n * dynamic lists, conditional fields, non-React adapters — and for RHF\n * migration (`{...register('name')}` spreads unchanged).\n *\n * Lifecycle rides the returned `ref` callback, exactly like React's own\n * ref semantics guarantee attach/detach:\n * - **attach** (element handed over): restore a StrictMode-detached\n * snapshot (React 19 detaches refs on the dev remount), seed the\n * element's initial DOM content into the store when the path has no\n * live value yet (an uncontrolled element's `defaultValue`/`checked`\n * is invisible to React state, so the DOM is the source), register the\n * field-mode entry (the \"mounted field\" signal routing `changeValue`\n * into the gated pipeline), wire declarative `rules` through\n * `registerValidatorByPath`, and subscribe the `'focusError'` channel\n * (`setFocus`, failed-submit auto-focus) plus the bulk-reset DOM sync\n * (payload-less `'change'` rewrites the element, register-style);\n * - **detach** (`null`): unregister mode entry and validator, drop the\n * subscriptions, and tombstone the path unless\n * `shouldUnregister: false` — the library's historical unmount\n * default, snapshot/restore-safe under StrictMode.\n *\n * Event extraction defaults to the element's own protocol (files →\n * `target.files`, checkbox → `target.checked`, `valueAsNumber`/\n * `valueAsDate` under their flags, else `target.value`), overridable\n * with `eventToValue` — the same extraction `<Field>` performs.\n *\n * @param form\n * @param name path or segment array\n * @param options {@link RegisterOptions}\n * @return spreadable props {@link RegisterProps}\n */\nexport function registerField(\n form: Form,\n name: Name,\n options?: RegisterOptions\n): RegisterProps {\n const path = createPath(name);\n const {\n mode,\n shouldUnregister,\n eventToValue,\n valueAsNumber,\n valueAsDate,\n rules\n } = options ?? {};\n\n const toValue =\n eventToValue ??\n ((e: any) => {\n const target = e?.target;\n if (!target) return e;\n if (target.type === 'file') return target.files;\n if (target.type === 'checkbox') return target.checked;\n if (valueAsNumber) return target.valueAsNumber;\n if (valueAsDate) return target.valueAsDate;\n return target.value;\n });\n\n // Per-element lifecycle state — the ref callback's attach/detach pair is\n // the mount/unmount signal, the same contract React guarantees for refs.\n let el: any = null;\n let modeToken: object | null = null;\n let disposeValidator: (() => void) | null = null;\n let snapshot: RemovedFieldSnapshot | null = null;\n let offFocus: (() => void) | null = null;\n let offBulkSync: (() => void) | null = null;\n\n const syncDom = () => {\n // File inputs cannot be assigned a value at all.\n if (!el || el.type === 'file') return;\n const next = getValueByPath(form, path);\n const asString = next == null ? '' : String(next);\n if (el.value !== asString) el.value = asString;\n };\n\n const attach = (node: any) => {\n // React 19's StrictMode detaches and re-attaches refs on the dev\n // remount; a tombstone snapshot taken by the detach right before is\n // restored here, so no render or subscriber observes the gap.\n if (snapshot) {\n restoreRemovedField(form, path, snapshot);\n snapshot = null;\n }\n el = node;\n // Seed the DOM's initial content (defaultValue / checked) into the\n // store: uncontrolled elements are invisible to React state, and\n // getValues/submit read the store. Never clobbers an existing value.\n if (node.type !== 'file' && getValueByPath(form, path) === undefined) {\n seedValueByPath(\n form,\n path,\n node.type === 'checkbox' ? node.checked : node.value\n );\n // The seed is an emit-free write (the announce split out for\n // render-phase callers); a ref callback runs post-commit, so the\n // announce can fire directly.\n emitChangeByPath(form, path);\n }\n modeToken = registerFieldMode(form, path, mode).token;\n if (rules && hasRuleConstraints(rules)) {\n // The required gate splits off like useField's: synchronous, runs on\n // every kick; the remaining rules compose into the debounced\n // validator (debounce fixed at 0 — immediate).\n const {required, ...rest} = rules;\n const requiredGate =\n required !== undefined\n ? rulesToValidator({required}, form.messages)\n : undefined;\n disposeValidator = registerValidatorByPath(form, path, {\n validate: () =>\n hasRuleConstraints(rest)\n ? rulesToValidator(rest, form.messages)\n : undefined,\n debounce: () => 0,\n sync: () => requiredGate\n } as ValidatorRegistration);\n }\n offFocus = on(\n form.emitter,\n 'focusError',\n (key: string, options?: {shouldSelect?: boolean}) => {\n if (key !== path.key || !el || typeof el.focus !== 'function') return;\n el.focus();\n if (options?.shouldSelect && typeof el.select === 'function') {\n el.select();\n }\n }\n );\n // Bulk operations (reset, setInitialValues) emit payload-less and\n // rewrite the store without re-rendering this element — sync its DOM\n // directly, exactly how RHF's reset clears uncontrolled inputs.\n offBulkSync = on(form.emitter, 'change', (changed?: Path) => {\n if (changed) return;\n syncDom();\n });\n };\n\n const detach = () => {\n if (modeToken) {\n unregisterFieldMode(form, path, modeToken);\n modeToken = null;\n }\n if (disposeValidator) {\n disposeValidator();\n disposeValidator = null;\n }\n if (offFocus) {\n offFocus();\n offFocus = null;\n }\n if (offBulkSync) {\n offBulkSync();\n offBulkSync = null;\n }\n el = null;\n // The same effective unmount expression useField applies: the\n // binding's own option, then the form-level default, then the\n // library's historical default (tombstone).\n if ((shouldUnregister ?? form.shouldUnregister) !== false) {\n snapshot = removeFieldForUnmount(form, path);\n }\n };\n\n return {\n name: path.key,\n onChange: (e: any) => changeValueByPath(form, path, toValue(e)),\n onBlur: () => userBlur(form, path),\n ref: (node: any) => {\n if (node) attach(node);\n else detach();\n }\n };\n}\n","import createPath from '../path';\nimport type {Path} from '../path';\nimport type {Form} from '../form';\nimport type {ArrayItemOf, AnyPath} from '../types';\nimport {getValueByPath, setValueByPath} from './values';\n\n/** Framework-free array operations: the headless counterparts of\n * `useFieldArray`'s movers. Every operation reads the array at `path` and\n * lands the next array through {@link setValueByPath} — one whole-array\n * write. Guarded operations no-op on out-of-range indices and report the\n * outcome; a missing/non-array value reads as an empty array. */\n\n/** Read the array at `path`, tolerating a missing or non-array branch. */\nfunction readArray(form: Form, path: Path): any[] {\n const value = getValueByPath(form, path);\n return Array.isArray(value) ? value : [];\n}\n\n/** Append one value to the array at `path`. */\nexport function appendValueByPath(form: Form, path: Path, value: any): void {\n const arr = readArray(form, path);\n setValueByPath(form, path, [...arr, value]);\n}\n\n/** Prepend one value to the array at `path`. */\nexport function prependValueByPath(form: Form, path: Path, value: any): void {\n const arr = readArray(form, path);\n setValueByPath(form, path, [value, ...arr]);\n}\n\n/** Insert one value at `index` in the array at `path` (`index === length`\n * appends). Returns `false` — without touching the form — when the index\n * is out of range; `true` once the value landed. */\nexport function insertValueByPath(\n form: Form,\n path: Path,\n index: number,\n value: any\n): boolean {\n const arr = readArray(form, path);\n if (index < 0 || index > arr.length) return false;\n setValueByPath(form, path, [\n ...arr.slice(0, index),\n value,\n ...arr.slice(index)\n ]);\n return true;\n}\n\n/** Remove one or several rows from the array at `path` in a single write.\n * Indices may repeat; out-of-range entries are ignored. Returns the\n * indices actually dropped, sorted descending so caller-side row-id\n * bookkeeping can splice them without re-indexing drift; `[]` when nothing\n * was removable. */\nexport function removeValueByPath(\n form: Form,\n path: Path,\n indices: number | number[]\n): number[] {\n const arr = readArray(form, path);\n const drop = new Set<number>();\n for (const index of Array.isArray(indices) ? indices : [indices]) {\n if (index >= 0 && index < arr.length) drop.add(index);\n }\n if (drop.size === 0) return [];\n const dropped = [...drop].sort((a, b) => b - a);\n setValueByPath(\n form,\n path,\n arr.filter((_, i) => !drop.has(i))\n );\n return dropped;\n}\n\n/** Move the row at `from` to `to` (rows in between shift one position).\n * Returns `false` — without touching the form — when either index is out\n * of range or they are equal; `true` once the row moved. */\nexport function moveValueByPath(\n form: Form,\n path: Path,\n from: number,\n to: number\n): boolean {\n const arr = readArray(form, path);\n if (from < 0 || from >= arr.length || to < 0 || to >= arr.length) {\n return false;\n }\n if (from === to) return false;\n const next = [...arr];\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n setValueByPath(form, path, next);\n return true;\n}\n\n/** Swap the rows at `from` and `to`. Returns `false` — without touching\n * the form — when either index is out of range or they are equal; `true`\n * once the rows swapped. */\nexport function swapValuesByPath(\n form: Form,\n path: Path,\n from: number,\n to: number\n): boolean {\n const arr = readArray(form, path);\n if (from < 0 || from >= arr.length || to < 0 || to >= arr.length) {\n return false;\n }\n if (from === to) return false;\n const next = [...arr];\n [next[from], next[to]] = [next[to], next[from]];\n setValueByPath(form, path, next);\n return true;\n}\n\n/** Wholesale-replace the array at `path` (length may change) in one write. */\nexport function replaceValuesByPath(\n form: Form,\n path: Path,\n values: any[]\n): void {\n setValueByPath(form, path, [...values]);\n}\n\n/** Overwrite one row of the array at `path` in place (a whole-array write,\n * so the row's position and every other row are untouched). Returns\n * `false` when the index is out of range; `true` once the value landed. */\nexport function updateValueByPath(\n form: Form,\n path: Path,\n index: number,\n value: any\n): boolean {\n const arr = readArray(form, path);\n if (index < 0 || index >= arr.length) return false;\n const next = [...arr];\n next[index] = value;\n setValueByPath(form, path, next);\n return true;\n}\n\n/** Append one value to the array at `name`. */\nexport function appendValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, value: ArrayItemOf<T, P>): void {\n appendValueByPath(form, createPath(name), value);\n}\n\n/** Prepend one value to the array at `name`. See {@link appendValue}. */\nexport function prependValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, value: ArrayItemOf<T, P>): void {\n prependValueByPath(form, createPath(name), value);\n}\n\n/** Insert one value at `index` in the array at `name`. Returns `false` on\n * an out-of-range index (see {@link insertValueByPath}). */\nexport function insertValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, index: number, value: ArrayItemOf<T, P>): boolean {\n return insertValueByPath(form, createPath(name), index, value);\n}\n\n/** Remove one or several rows from the array at `name` in a single write.\n * Returns the indices actually dropped, descending (see\n * {@link removeValueByPath}). */\nexport function removeValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, indices: number | number[]): number[] {\n return removeValueByPath(form, createPath(name), indices);\n}\n\n/** Move the row at `from` to `to` in the array at `name`. Returns `false`\n * on an out-of-range or no-op move (see {@link moveValueByPath}). */\nexport function moveValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, from: number, to: number): boolean {\n return moveValueByPath(form, createPath(name), from, to);\n}\n\n/** Swap the rows at `from` and `to` in the array at `name`. Returns\n * `false` on an out-of-range or no-op swap (see {@link swapValuesByPath}). */\nexport function swapValues<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, from: number, to: number): boolean {\n return swapValuesByPath(form, createPath(name), from, to);\n}\n\n/** Wholesale-replace the array at `name` (see {@link replaceValuesByPath}). */\nexport function replaceValues<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, values: ArrayItemOf<T, P>[]): void {\n replaceValuesByPath(form, createPath(name), values);\n}\n\n/** Overwrite one row of the array at `name` in place. Returns `false` on\n * an out-of-range index (see {@link updateValueByPath}). */\nexport function updateValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, index: number, value: ArrayItemOf<T, P>): boolean {\n return updateValueByPath(form, createPath(name), index, value);\n}\n","import {emit} from '../emitter';\nimport type {FieldErrorEntry, Form} from '../form';\nimport {getErrors, setServerErrors, clearServerErrors} from './errors';\nimport {getValues} from './values';\nimport {validate} from './validate';\n\nexport function setIsSubmitting(form: Form, value: boolean): void {\n form.isSubmitting = value;\n emit(form.emitter, 'submitting');\n}\n\nexport function incrementSubmitCount(form: Form): void {\n form.submitCount++;\n emit(form.emitter, 'submitCount');\n}\n\nexport function setSubmitSuccessful(form: Form, value: boolean): void {\n form.isSubmitSuccessful = value;\n emit(form.emitter, 'submitSuccessful');\n}\n\n/** Set the form-level disabled flag and emit a payload-less 'disabled'\n * event — subscribed fields re-render with the merged state (form flag ||\n * their own `disabled` option). */\nexport function setDisabled(form: Form, value: boolean): void {\n form.disabled = value;\n emit(form.emitter, 'disabled');\n}\n\n/** Set the form's user-owned metadata slot (Formik's `status` role): the\n * payload-less 'status' event wakes {@link useStatus} and imperative\n * `subscribe` listeners. Nothing else interprets the value. */\nexport function setStatus(form: Form, value: any): void {\n form.status = value;\n emit(form.emitter, 'status');\n}\n\n/** Structural slice of a <form>-like element: controls exposing the\n * constraint-validation members we read, without coupling core to DOM\n * types. */\ntype NativeFormElement = {\n elements: Iterable<{\n name: string;\n checkValidity: () => boolean;\n validationMessage: string;\n }>;\n};\n\n/** Converts a control's DOM name to the user-visible dotted path. Field\n * components render the path key (JSON segments, '[\"a\",\"0\"]') as the name\n * attribute, so JSON keys are parsed back and joined with dots; any other\n * name is returned as-is. */\nfunction nameToPath(name: string): string {\n if (name.startsWith('[')) {\n try {\n const segments = JSON.parse(name);\n if (Array.isArray(segments)) return segments.join('.');\n } catch {\n // Not a JSON path key — fall through and use the raw name.\n }\n }\n return name;\n}\n\n/** Collect the constraints failing native validation on a <form> as\n * {@link FieldErrorEntry} entries, in DOM order. Native errors are NOT\n * written into the errors Map — it tracks custom validator state, while\n * native validity is transient browser-owned DOM state. */\nfunction getNativeErrors(formEl: NativeFormElement): FieldErrorEntry[] {\n const errors: FieldErrorEntry[] = [];\n for (const el of formEl.elements) {\n if (\n el.name &&\n typeof el.checkValidity === 'function' &&\n !el.checkValidity()\n ) {\n errors.push({\n path: nameToPath(el.name),\n type: 'native',\n message: el.validationMessage\n });\n }\n }\n return errors;\n}\n\n/** A submit callback: the submitted values plus the triggering event. */\ntype SubmitCallback<T> = (values: T, e?: any) => void | Promise<void>;\n\n/** Submit callbacks for {@link handleSubmit}. All optional — a missing\n * callback is simply skipped, matching the <Form> component semantics. */\nexport type HandleSubmitOptions<T extends Record<string, any> = any> = {\n /** Called after validation passes, before onValidSubmit. */\n onSubmit?: SubmitCallback<T>;\n /** Called after validation passes, following a successful onSubmit. */\n onValidSubmit?: SubmitCallback<T>;\n /** Called when validation fails, with the flattened error entries and\n * current values. */\n onInvalidSubmit?: (errors: FieldErrorEntry[], values: T) => void;\n /** Called after validation passes with the final (schema-coerced)\n * values — the slot <Form>'s `action` prop uses to dispatch React 19\n * server actions. May return an {@link ActionErrorResult}: its `errors`\n * record lands as `type: 'server'` errors and the submit counts\n * unsuccessful; any other return means success. */\n onAction?: (values: T, e?: any) => void | Promise<void | ActionErrorResult>;\n /** Focus the first error field after a failed submit. Defaults to true. */\n shouldFocusError?: boolean;\n /** Whether native constraint validation gates this attempt. Defaults to\n * the form's {@link Form.shouldUseNativeValidation} flag. Targets\n * without checkValidity never gate. */\n shouldUseNativeValidation?: boolean;\n};\n\n/** What a server action / onAction callback returns when the server\n * rejected the payload: a field-path → message(s) record, landed as\n * `type: 'server'` errors. Undefined (or anything else) means success. */\nexport type ActionErrorResult = {\n errors?: Record<string, string | string[]>;\n};\n\n/** Create an async submit handler for `form` — the headless counterpart of\n * the <Form> component's onSubmit wiring. Runs the submit state machine\n * around native constraint validation (skipped for targets without\n * checkValidity) and custom validators; failed validation fires\n * onInvalidSubmit, a passing submit runs onSubmit then onValidSubmit.\n * Errors thrown by either are swallowed into isSubmitSuccessful=false.\n * A new attempt while one is in flight is ignored outright (no state\n * changes at all) — including handleSubmit calls nested inside onSubmit. */\nexport function handleSubmit<T extends Record<string, any> = any>(\n form: Form<T>,\n options?: HandleSubmitOptions<T>\n): (e?: {preventDefault?: () => void; currentTarget?: any}) => Promise<void> {\n const {\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n onAction,\n shouldFocusError = true,\n shouldUseNativeValidation = form.shouldUseNativeValidation\n } = options ?? {};\n\n return async e => {\n if (e && typeof e.preventDefault === 'function') {\n e.preventDefault();\n }\n const formEl = e?.currentTarget;\n // One flight at a time: isSubmitting flips true synchronously before\n // the first await below, so any attempt arriving while a round is\n // pending — a double click, or handleSubmit nested inside onSubmit —\n // is ignored before touching any state. The settling finally resets\n // the flag and re-arms the next round.\n if (form.isSubmitting) return;\n // A fresh attempt supersedes the previous round trip's verdict: server\n // errors from the last submit must not veto this one (the server is\n // being asked again). Client errors stay.\n clearServerErrors(form);\n // Land the submitted flag before the isSubmitting flip: the single\n // 'submitting' emit carries both state changes to subscribers.\n form.isSubmitted = true;\n setIsSubmitting(form, true);\n incrementSubmitCount(form);\n const values = getValues(form);\n\n if (\n shouldUseNativeValidation &&\n formEl &&\n typeof formEl.checkValidity === 'function' &&\n formEl.checkValidity() === false\n ) {\n formEl.reportValidity();\n // Focus the first natively-invalid control directly off the DOM;\n // native failures never enter the errors Map (see getNativeErrors).\n if (shouldFocusError && typeof formEl.querySelector === 'function') {\n const invalid = formEl.querySelector(':invalid') as HTMLElement | null;\n if (invalid && typeof invalid.focus === 'function') invalid.focus();\n }\n setIsSubmitting(form, false);\n setSubmitSuccessful(form, false);\n // Native constraint failures are read from the DOM (not the errors\n // Map, which only holds custom validation state).\n if (onInvalidSubmit) onInvalidSubmit(getNativeErrors(formEl), values);\n return;\n }\n\n const error = await validate(form);\n if (error) {\n setIsSubmitting(form, false);\n setSubmitSuccessful(form, false);\n // Notify bound fields so the first errored one can focus its input;\n // the payload is the errors Map's first key.\n if (shouldFocusError) {\n const firstKey = form.errors.keys().next().value;\n if (firstKey !== undefined) emit(form.emitter, 'focusError', firstKey);\n }\n if (onInvalidSubmit) onInvalidSubmit(getErrors(form), values);\n return;\n }\n\n try {\n // Re-read after validation: a schema validator's parsed output\n // landed in parsedValues during validate(), and the submit\n // callbacks must see the coerced values, not the raw\n // pre-validation snapshot.\n const submitted = getValues(form);\n if (onSubmit) await onSubmit(submitted, e);\n if (onValidSubmit) await onValidSubmit(submitted, e);\n if (onAction) {\n const result = await onAction(submitted, e);\n // A server round trip that returns errors is an invalid submit:\n // land them as per-field 'server' errors and mark the attempt\n // unsuccessful.\n if (\n result &&\n typeof result === 'object' &&\n result.errors !== undefined &&\n typeof result.errors === 'object'\n ) {\n setServerErrors(form, result.errors);\n setSubmitSuccessful(form, false);\n return;\n }\n }\n setSubmitSuccessful(form, true);\n } catch {\n setSubmitSuccessful(form, false);\n } finally {\n setIsSubmitting(form, false);\n }\n };\n}\n","import {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Name} from '../path';\nimport type {Form} from '../form';\n\n/** Options accepted by {@link setFocus}. All flags default to `false`. */\nexport type SetFocusOptions = {\n /** Select the field's text after focusing it. */\n shouldSelect?: boolean;\n};\n\n/** Programmatically focus a bound field's element. Rides the same\n * 'focusError' event channel a failed handleSubmit uses; being\n * event-driven, it is a silent no-op when the field is unmounted or\n * nothing subscribes. */\nexport function setFocus(\n form: Form,\n name: Name,\n options?: SetFocusOptions\n): void {\n const {key} = createPath(name);\n // Omit the options argument when absent so the payload matches the shape\n // handleSubmit emits after a failed submit.\n if (options) emit(form.emitter, 'focusError', key, options);\n else emit(form.emitter, 'focusError', key);\n}\n","import {create as createEmitter, emit, setMaxListeners} from './emitter';\nimport {hasStandardProps, schemaToFormValidator} from './standardSchema';\nimport type {StandardSchemaV1} from './standardSchema';\nimport type {EventEmitter} from './emitter';\nimport createPath from './path';\nimport type {Name, Path} from './path';\nimport type {FieldPath} from './types';\nimport type {FieldRules, FormMessages} from './rules';\nimport {isPromise} from './util';\nimport {setInitialValues} from './core/values';\nimport {registerField} from './core/register';\nimport type {SetFocusOptions} from './core/focus';\nimport type {VALIDATION_OUTCOME} from './core/errors';\n\n// Implementation is split by concern under ./core; module-private shared\n// state lives in ./core/internals (deliberately not re-exported). This\n// file keeps the public types + create factory and re-exports every\n// public function — the single import surface the package consumes.\nexport type {Name};\nexport type {\n FieldPath,\n AnyPath,\n PathValue,\n PathValueOf,\n ArrayItemOf,\n OpaqueTypes\n} from './types';\nexport type {FormMessages} from './rules';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/** A field error: `type` is the error kind, `message` the display text. */\nexport type FieldError = {type: string; message: string};\n\n/** A flattened entry from {@link getErrors}. */\nexport type FieldErrorEntry = {path: string; type: string; message: string};\n\n/** When a field is validated:\n * - `'onSubmit'` (default): only on submit\n * - `'onBlur'`: when the field loses focus\n * - `'onChange'`: on every change\n * - `'onTouched'`: on first blur, then on every change\n * - `'all'`: on both change and blur\n */\nexport type ValidationMode =\n 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all';\n\n/** When a field is re-validated after it already has an error:\n * - `'onChange'` (default): on every change\n * - `'onBlur'`: when the field loses focus\n * - `'onSubmit'`: only on submit (no live re-validation)\n */\nexport type ReValidateMode = 'onChange' | 'onBlur' | 'onSubmit';\n\n/** When the form-level {@link Options.validate} re-runs outside\n * submit/`trigger`/`validateOnMount`:\n * - `'onSubmit'` (default): submit/trigger only — cross-field linkage via\n * {@link Options.validateDeps}\n * - `'onChange'`: every user change to a bound field\n * - `'onBlur'`: every user blur of a bound field\n */\nexport type FormValidateMode = 'onSubmit' | 'onChange' | 'onBlur';\n\n/**\n * Options accepted by {@link Form.register} — the non-hook binding for\n * uncontrolled fields (react-hook-form's `register` contract: the bound\n * element never re-renders; the store carries every write).\n */\nexport type RegisterOptions = {\n /** Field-level validation mode for this binding; defaults to the form's\n * `mode`. */\n mode?: ValidationMode;\n /** Unmount behavior: `true` (the library's historical default) tombstones\n * the path, `false` keeps the value. Falls back to the form-level\n * `createForm({shouldUnregister})` when omitted. */\n shouldUnregister?: boolean;\n /** DOM event → value extractor for the returned `onChange`. Defaults to\n * the element's protocol (`target.files`/`target.checked`/\n * `target.valueAsNumber`/`target.valueAsDate`, else `target.value`) —\n * the same extraction `<Field>` performs. */\n eventToValue?: (e: any) => any;\n /** Store `e.target.valueAsNumber` instead of the string value. An\n * explicit `eventToValue` takes precedence. */\n valueAsNumber?: boolean;\n /** Store `e.target.valueAsDate` instead of the string value. An explicit\n * `eventToValue` takes precedence; combining with `valueAsNumber` is a\n * TypeError. */\n valueAsDate?: boolean;\n /** Declarative rules for this binding — the same {@link FieldRules}\n * `useField`/`<Field>` take (`required` runs as the synchronous gate).\n * Wired through `registerValidatorByPath`, so `trigger`/submit/`mode`\n * gating see it like a hook-registered validator; `validateDebounce` is\n * fixed at 0. */\n rules?: FieldRules;\n};\n\n/** What {@link Form.register} returns: spread these onto an uncontrolled\n * DOM element (`<input {...form.register('name')} />`). `name` is the\n * store's path key; `onChange` writes through the gated user-change\n * pipeline; `ref` attach seeds the element's DOM content and detach\n * tombstones unless `shouldUnregister: false`. */\nexport type RegisterProps = {\n name: string;\n onChange: (e: any) => void;\n onBlur: () => void;\n ref: (el: any) => void;\n};\n\n/** Structured form-level validate result: `errors` uses the same nested\n * shape a plain error record uses, `values` is the schema's parsed output\n * (coerce/transform included). Either side may be omitted. The brand\n * constant lives in the errors module and is re-exported below. */\nexport type ValidationOutcome<T> = {\n [VALIDATION_OUTCOME]: true;\n errors?: Record<string, any>;\n values?: T;\n};\n\n/** What a form-level validate function may return: a plain nested error\n * record (flattened into field errors — the long-standing shape), or a\n * branded {@link ValidationOutcome} whose `values` become the form's\n * parsedValues baseline. */\nexport type ValidateResult<T> =\n | Record<string, any>\n | ValidationOutcome<T>\n | Promise<Record<string, any> | ValidationOutcome<T>>;\n\n/** Context passed to a form-level `validate`'s second argument. `signal`\n * aborts when the round is superseded (only under a positive\n * `validateDebounce`, where kicks merge), so async work can be cancelled;\n * stale results are dropped by the round gate either way. */\nexport type FormValidateMeta<T extends Record<string, any> = any> = {\n form: Form<T>;\n signal: AbortSignal;\n};\n\n/** Form-level validator: receives all values (plus an optional {@link\n * FormValidateMeta}) and returns a {@link ValidateResult} — sync or async\n * — or `undefined` when valid (falsy results are skipped). */\nexport type FormValidateFn<T extends Record<string, any> = any> = (\n values: T,\n meta: FormValidateMeta<T>\n) => ValidateResult<T> | undefined;\n\n/** The emitter event table for {@link Form.emitter}: path-carrying events\n * declare an optional single `Path` payload (sent for single-field\n * mutations, omitted for bulk payload-less broadcasts); `focusError`\n * carries the path key plus optional {@link SetFocusOptions}. */\nexport type FormEvents =\n | ['change', [path?: Path]]\n | ['errors', [path?: Path]]\n | ['touched', [path?: Path]]\n | ['validating', [path?: Path]]\n | ['submitting', []]\n | ['submitCount', []]\n | ['submitSuccessful', []]\n | ['reset', []]\n | ['disabled', [path?: Path]]\n | ['status', []]\n | ['loading', []]\n | ['focusError', [key: string, options?: SetFocusOptions]];\n\nexport type Form<T extends Record<string, any> = any> = {\n emitter: EventEmitter<FormEvents>;\n mode: ValidationMode;\n reValidateMode: ReValidateMode;\n initialValues: T;\n values: Map<string, any>;\n /** Tombstones of unregistered field paths (JSON path keys): reading or\n * merging values must not fall back to initialValues for these paths. */\n deleted: Set<string>;\n /** Every error registered for a field, as a non-empty array (the\n * write-side {@link setErrorByPath} normalizes to this invariant).\n * First entry via {@link getError}, all of them via\n * {@link getFieldErrors}. */\n errors: Map<string, FieldError[]>;\n touched: Set<string>;\n /** Per-field validation kicks registered by {@link\n * registerValidatorByPath}: invoking one validates the field's current\n * value. `trigger`/`ensureValidate` run every entry; the user-change\n * gate runs the entry at the changed path. */\n validators: Map<string, () => void>;\n validating: Set<string>;\n /** Parsed values from the last successful schema validation: layered\n * between initialValues and the values Map in {@link getValues}, cleared\n * by `reset`/`setInitialValues`. Never affects dirty state. */\n parsedValues: T | undefined;\n /** Form-level validator, seeded from {@link Options.validate}. */\n validate?: FormValidateFn<T>;\n /** Delay in ms before the form-level `validate` runs; seeded from\n * {@link Options.validateDebounce} and fixed at create time. */\n validateDebounce?: number;\n /** Path keys whose user changes re-run the form-level `validate`;\n * normalized from {@link Options.validateDeps} at create time. */\n validateDeps?: ReadonlySet<string>;\n /** When the form-level `validate` re-runs outside submit/trigger — the\n * cadence from {@link Options.validateMode}, seeded at create time. */\n validateMode: FormValidateMode;\n /** Form-level default messages for declarative rules, seeded from\n * {@link Options.messages}: one table overriding every field's built-in\n * English rule message (i18n in one place). Per-field messages still\n * win. */\n messages?: FormMessages;\n isSubmitting: boolean;\n /** Whether a submit has been attempted — set by `handleSubmit` on every\n * attempt, cleared by `reset` (react-hook-form's `isSubmitted`). */\n isSubmitted: boolean;\n submitCount: number;\n isSubmitSuccessful: boolean | undefined;\n /** True while an async {@link Options.initialValues} source is pending —\n * the form starts empty and the resolved values land as the baseline.\n * Flips through the payload-less 'loading' event. */\n isLoading: boolean;\n /** Form-level default for a bound field's unmount behavior: `true` (the\n * default) tombstones an unmounted field, `false` keeps its value. A\n * field's own `shouldUnregister` option overrides this. */\n shouldUnregister?: boolean;\n /** Form-level disabled flag, OR-ed into every bound field's `disabled`\n * (form flag || the field's own option). Toggled at runtime with\n * {@link setDisabled}, which emits a payload-less 'disabled' event. */\n disabled: boolean;\n /** Form-level default for mount validation: `true` kicks every mounted\n * field's validator once after mount (deferred until an async\n * {@link Options.initialValues} source lands) and runs the form-level\n * `validate` once. A field's own option overrides this. */\n validateOnMount: boolean;\n /** Form-level default for `asyncAlways`: whether a field's debounced\n * validator still runs when its `required` gate failed. A field's own\n * option overrides this flag. */\n asyncAlways: boolean;\n /** Whether native constraint validation gates submission and skips a\n * bound `<Field>`'s custom validators on a native-failing kick. Seeded\n * from {@link Options.shouldUseNativeValidation} (default `true`); a\n * submit may override per attempt. */\n shouldUseNativeValidation: boolean;\n /** User-owned metadata slot for non-field state (Formik's `status`\n * role). Written with {@link setStatus}, which emits the payload-less\n * 'status' event; read via {@link useStatus}. Starts `undefined`. */\n status: any;\n /** Non-hook field binding — react-hook-form's `register` contract:\n * spread the returned props onto an uncontrolled DOM element and the\n * element never re-renders while the store carries every write. No\n * React state involved, so it works anywhere. See {@link\n * RegisterOptions} / {@link RegisterProps}. */\n register: (name: Name, options?: RegisterOptions) => RegisterProps;\n};\n\nexport type Options<T extends Record<string, any> = any> = {\n /** The values baseline. Sync objects seed immediately; async sources (a\n * Promise, or a thunk returning a value/Promise) start the form empty\n * with `isLoading: true` and land the resolved values as the baseline\n * via setInitialValues. A rejected source keeps the form empty and logs\n * in DEV. The thunk runs at create time. */\n initialValues?: T | Promise<T> | (() => T | Promise<T>);\n /** When fields are validated. Defaults to `'onSubmit'`. See\n * {@link ValidationMode}. */\n mode?: ValidationMode;\n /** When a field is re-validated after it already has an error. Defaults\n * to `'onChange'`. See {@link ReValidateMode}. */\n reValidateMode?: ReValidateMode;\n /** Form-level validator: returns a record of errors keyed by field path\n * (nested objects flattened 'a.b' style, array values contribute each\n * non-empty string). A branded {@link ValidationOutcome} adds parsed\n * `values` as the parsedValues baseline. Alternatively pass a Standard\n * Schema v1 object directly — it is wrapped into a validator\n * automatically. */\n validate?: FormValidateFn<T> | StandardSchemaV1<unknown, T>;\n /** Milliseconds to debounce the form-level `validate`: kicks inside the\n * window merge into one run, and while the timer is pending the form\n * counts as validating. Defaults to `0` (runs immediately). */\n validateDebounce?: number;\n /** Fields whose user changes re-run the form-level `validate` — the\n * cross-field dependency list. A re-run only clears errors the previous\n * round wrote; errors the round never wrote are untouched. Omit it and\n * the form-level `validate` only runs on `trigger`/submit. */\n validateDeps?: FieldPath<T>[];\n /** When the form-level `validate` re-runs outside submit/`trigger`/\n * `validateOnMount` — a cadence declaration instead of enumerating\n * {@link Options.validateDeps}. See {@link FormValidateMode}. */\n validateMode?: FormValidateMode;\n /** Form-level default messages for declarative rules, keyed by rule\n * type — one table overriding the built-in English defaults for every\n * field (i18n in one place). A string may carry a `{bound}`\n * placeholder; a function receives the bound. A field's own message\n * (the `required` string, `rules.messages`, `pattern.message`) still\n * wins. See {@link FormMessages}. */\n messages?: FormMessages;\n /** Form-level default for a bound field's unmount behavior. `true` (the\n * default) tombstones an unmounted field; `false` keeps the value\n * (react-hook-form's `shouldUnregister`). A field's own option\n * overrides this. */\n shouldUnregister?: boolean;\n /** Start the form with every bound field disabled — bound fields OR this\n * flag with their own `disabled` option (a field cannot opt out).\n * Toggle later with {@link setDisabled}. Defaults to `false`. */\n disabled?: boolean;\n /** Form-level default for `asyncAlways`: when true, a field whose\n * `required` gate failed still runs its debounced validator (the gate's\n * errors land immediately, the validator's result lands alongside\n * them per-source). A field's own option overrides this. Defaults to\n * `false`. */\n asyncAlways?: boolean;\n /** Whether native constraint validation gates submission and skips a\n * bound `<Field>`'s custom validators on a native-failing kick\n * (react-hook-form's `shouldUseNativeValidation`). Defaults to `true`.\n * Fixed at create time; a single submit may override it. */\n shouldUseNativeValidation?: boolean;\n /** Validate on mount: `true` makes every mounted field's validator run\n * once after mount (errors show for an untouched form) and runs the\n * form-level `validate` once. Mount kicks are deferred while an async\n * `initialValues` source is pending. A field's own option overrides\n * this. Defaults to `false`. */\n validateOnMount?: boolean;\n};\n\n/** Seed the baseline: a sync value becomes initialValues immediately; an\n * async source starts the form empty and lands the resolved values via\n * setInitialValues, flipping isLoading and the 'loading' event around it. */\nfunction seedInitialValues<T extends Record<string, any>>(\n form: Form<T>,\n emitter: EventEmitter<FormEvents>,\n source: unknown\n): void {\n if (!isPromise(source)) {\n form.initialValues = source as T;\n return;\n }\n // The form starts empty; the resolved values become the baseline\n // through setInitialValues. No subscriber exists during the first\n // render, so the synchronous first 'loading' emit is a safe no-op.\n form.isLoading = true;\n emit(emitter, 'loading');\n Promise.resolve(source).then(\n resolved => {\n // Values land first, then the flag flips and 'loading' fires — so\n // subscribers waking on the event read the resolved baseline, not\n // the empty shell (mount-validation deferral among them).\n setInitialValues(form, resolved ?? {});\n form.isLoading = false;\n emit(emitter, 'loading');\n },\n error => {\n form.isLoading = false;\n emit(emitter, 'loading');\n // The caller's own catch sees the rejection; rethrowing would\n // duplicate it as an unhandled rejection. Surface it in DEV.\n if (__DEV__) {\n // eslint-disable-next-line no-console -- dev-only diagnostics\n console.error('react-f0rm: async initialValues rejected', error);\n }\n }\n );\n}\n\n/** Create a form instance. */\nexport default function create<T extends Record<string, any> = any>(\n options?: Options<T>\n): Form<T> {\n const emitter = createEmitter<FormEvents>();\n // A form accumulates one listener per mounted field per event, so the\n // emitter's default max-listener warning would fire in DEV for any form\n // over ~10 fields. Subscriptions are removed on unmount — nothing leaks\n // — so the warning is noise: raise the cap to unlimited.\n setMaxListeners(emitter, 0);\n // A thunk is invoked at create time; a promise result starts the\n // loading cycle in seedInitialValues instead of seeding here.\n const initialSource: any = options?.initialValues ?? {};\n const source =\n typeof initialSource === 'function'\n ? (initialSource as () => unknown)()\n : initialSource;\n const validateOption = options?.validate;\n // A Standard Schema passed to `validate` is wrapped into a form-level\n // validator — no resolver import needed. The casts split the union the\n // guard can't narrow (see hasStandardProps).\n const wrappedValidate: FormValidateFn<T> | undefined =\n validateOption && hasStandardProps(validateOption)\n ? (schemaToFormValidator(\n validateOption as StandardSchemaV1<unknown, T>\n ) as FormValidateFn<T>)\n : (validateOption as FormValidateFn<T> | undefined);\n const form: Form<T> = {\n emitter,\n ...options,\n validate: wrappedValidate,\n mode: options?.mode ?? 'onSubmit',\n reValidateMode: options?.reValidateMode ?? 'onChange',\n validateMode: options?.validateMode ?? 'onSubmit',\n disabled: options?.disabled ?? false,\n validateOnMount: options?.validateOnMount ?? false,\n asyncAlways: options?.asyncAlways ?? false,\n shouldUseNativeValidation: options?.shouldUseNativeValidation ?? true,\n validateDeps: options?.validateDeps\n ? new Set(options.validateDeps.map(dep => createPath(dep).key))\n : undefined,\n initialValues: {} as T,\n values: new Map(),\n deleted: new Set(),\n errors: new Map(),\n touched: new Set(),\n validators: new Map(),\n validating: new Set(),\n parsedValues: undefined,\n isSubmitting: false,\n isSubmitted: false,\n submitCount: 0,\n isSubmitSuccessful: undefined,\n isLoading: false,\n status: undefined,\n register: (name, registerOptions) =>\n registerField(form, name, registerOptions)\n };\n seedInitialValues(form, emitter, source);\n return form;\n}\n\nexport * from './core/values';\nexport * from './core/array';\nexport * from './core/errors';\nexport * from './core/touched';\nexport * from './core/dirty';\nexport * from './core/validate';\nexport * from './core/change';\nexport * from './core/register';\nexport * from './core/submit';\nexport * from './core/focus';\n","import createPath from './path';\nimport type {Name} from './path';\n\n/** Converts a path key (JSON-stringified segments, e.g. '[\"a\",\"0\"]') into\n * a valid HTML id ('a-0'); falls back to 'field'. */\nexport function errorIdFromKey(key: string): string {\n const id = key.replace(/[\"'[\\],\\s]+/g, '-').replace(/^-+|-+$/g, '');\n return id || 'field';\n}\n\n/** The error-message element id a field's `aria-describedby` points at\n * (same id `<Field>`'s renderError span carries). A custom error\n * component completes the accessible-name chain with\n * `<span id={fieldErrorId(name)} role=\"alert\">`. */\nexport function fieldErrorId(name: Name): string {\n return errorIdFromKey(createPath(name).key);\n}\n","import {emit} from '../emitter';\nimport type {Form} from '../form';\nimport type {Path} from '../path';\nimport {getOrCreate} from './internals';\n\n/** Per-form registry of bound fields' own `disabled` options — path key →\n * `{disabled, token}`, the signal behind subtree propagation: a field\n * declared `disabled: true` disables every descendant, and a descendant\n * declares `disabled: false` to opt back out. WeakMap so the Form shape\n * carries only plain state fields. Internal: hooks import it directly, the\n * facade never re-exports it. */\nconst fieldDisabledRegistry = new WeakMap<\n Form,\n Map<string, {disabled: boolean; token: object}>\n>();\n\n/** Register a bound field's `disabled` option at `path`. Returns the\n * registration token for {@link unregisterFieldDisabled}, or `null` when\n * the option is `undefined` — a field that never declares `disabled`\n * registers nothing. Emits a path-payload `'disabled'` event so\n * descendants re-render when an ancestor's flag flips. */\nexport function registerFieldDisabled(\n form: Form,\n path: Path,\n disabled: boolean | undefined\n): {token: object} | null {\n if (disabled === undefined) return null;\n const registry = getOrCreate(fieldDisabledRegistry, form, () => new Map());\n const token = {};\n registry.set(path.key, {disabled, token});\n emit(form.emitter, 'disabled', path);\n return {token};\n}\n\n/** Drop a {@link registerFieldDisabled} registration; only the entry owned\n * by `token` is removed. Emits the path-payload `'disabled'` so\n * descendants re-render. */\nexport function unregisterFieldDisabled(\n form: Form,\n path: Path,\n token: object\n): void {\n const registry = fieldDisabledRegistry.get(form);\n const entry = registry?.get(path.key);\n if (registry && entry && entry.token === token) {\n registry.delete(path.key);\n emit(form.emitter, 'disabled', path);\n }\n}\n\n/** Is any ancestor of `path` declared `disabled: true`? O(depth) prefix\n * lookups over the registry — the merged-disabled rule a bound field\n * evaluates on render:\n * `form.disabled || own === true || (own !== false && hasDisabledAncestor)`. */\nexport function hasDisabledAncestor(form: Form, path: Path): boolean {\n const registry = fieldDisabledRegistry.get(form);\n if (!registry?.size) return false;\n const segments = path.value;\n for (let i = 1; i < segments.length; i++) {\n const prefix = JSON.stringify(segments.slice(0, i));\n if (registry.get(prefix)?.disabled) return true;\n }\n return false;\n}\n","import {on} from './emitter';\nimport type {EventEmitter} from './emitter';\nimport createPath from './path';\nimport type {Name, Path} from './path';\nimport type {Form, FormEvents} from './form';\n\n/** Subscription granularity for {@link onPathEvent}: `'leaf'` reads one\n * key (only writes at it or above matter); `'branch'` aggregates a whole\n * subtree (descendant writes matter too). */\nexport type WatchScope = 'leaf' | 'branch';\n\n/**\n * Is `key` a strict descendant? Keys are JSON-stringified segment arrays,\n * so a descendant is the ancestor key minus its closing ']' plus ','; the\n * mandatory ',' keeps sibling '[\"tagsX\"]' from matching '[\"tags\"]'.\n */\nfunction isDescendant(key: string, ancestorKey: string): boolean {\n return key.startsWith(`${ancestorKey.slice(0, -1)},`);\n}\n\n/**\n * Subscribe to `event`, invoking `cb` only when the emitted path is\n * relevant. Payload-less broadcasts always invoke (global sync). With a\n * path P: `'leaf'` fires on P == path or an ancestor (leaf reads fall back\n * to ancestor values); `'branch'` also fires on descendants, which\n * re-aggregate the subtree.\n */\nexport function onPathEvent(\n emitter: EventEmitter<FormEvents>,\n event: SubscribeEvent,\n path: Path,\n scope: WatchScope,\n cb: () => void\n): () => void {\n const {key} = path;\n return on(emitter, event, (changed?: Path) => {\n if (\n changed === undefined ||\n changed.key === key ||\n isDescendant(key, changed.key) ||\n (scope === 'branch' && isDescendant(changed.key, key))\n ) {\n cb();\n }\n });\n}\n\n/**\n * Subscribe to `event`, invoking `cb` only on exact key matches (or a\n * payload-less global sync). Exact-key state (errors, touched) wants no\n * ancestor/descendant matching.\n */\nexport function onKeyEvent(\n emitter: EventEmitter<FormEvents>,\n event: SubscribeEvent,\n key: string,\n cb: () => void\n): () => void {\n return on(emitter, event, (changed?: Path) => {\n if (changed === undefined || changed.key === key) cb();\n });\n}\n\n/** Events {@link subscribe} can watch. `'errors'`/`'touched'` match exact\n * keys ({@link onKeyEvent}); `'change'`/`'validating'` match by path\n * ({@link onPathEvent}); the rest are payload-less broadcasts every\n * subscriber hears. */\nexport type SubscribeEvent =\n | 'change'\n | 'errors'\n | 'touched'\n | 'validating'\n | 'submitting'\n | 'submitCount'\n | 'submitSuccessful'\n | 'disabled'\n | 'status'\n | 'loading';\n\nexport type SubscribeOptions = {\n /** Path or paths to watch; omit to receive every emission. A segments\n * path vs a name list is told apart by `trigger`'s rule: only segments\n * hold a number. */\n name?: Name | Name[];\n /** Event to watch. Defaults to `'change'`. */\n event?: SubscribeEvent;\n /** Which writes around `name` are relevant. Only meaningful for the\n * path-carrying events; defaults to `'branch'` (subscribing to `'tags'`\n * means the whole branch). */\n scope?: WatchScope;\n /** Invoked after each matching emission; read fresh state through the\n * `get*` readers inside it. */\n callback: () => void;\n};\n\n/** A segments path can hold a number (`['a', 0]`), a name list never can —\n * the same disambiguation `trigger` applies to its name argument. */\nfunction isNameList(name: Name | Name[]): name is Name[] {\n return (\n Array.isArray(name) &&\n (name as (number | unknown)[]).every(part => typeof part !== 'number')\n );\n}\n\n/**\n * Subscribe to form events imperatively — the non-render counterpart of\n * the `use*` hooks. Without `name`, `callback` fires on every emission;\n * with `name`, matching follows the event's shape (`'errors'`/`'touched'`\n * match exact keys, the rest match by path or broadcast). A name array\n * builds one subscription per path.\n */\nexport function subscribe(form: Form, options: SubscribeOptions): () => void {\n const {name, event = 'change', scope = 'branch', callback} = options;\n if (name === undefined) return on(form.emitter, event, callback);\n const names = isNameList(name) ? name : [name];\n const unsubscribes = names.map(one => {\n const path = createPath(one);\n return event === 'errors' || event === 'touched'\n ? onKeyEvent(form.emitter, event, path.key, callback)\n : onPathEvent(form.emitter, event, path, scope, callback);\n });\n return unsubscribes.length === 1\n ? unsubscribes[0]\n : () => unsubscribes.forEach(unsubscribe => unsubscribe());\n}\n\n/** The handle {@link watch} returns: a subscribe/getSnapshot pair any\n * reactive runtime can bind to. One internal listener stays alive from\n * creation, so `getSnapshot()` is always fresh; `dispose` ends it. */\nexport type WatchHandle<T> = {\n /** Read the current snapshot, cached between events; repeated reads\n * share one reference until state changes. */\n getSnapshot: () => T;\n /** Register a change listener; fires only when the projection changed.\n * With `isEqual`, an equal verdict skips the callback; without one,\n * every event wakes it. */\n subscribe: (invalidate: () => void) => () => void;\n /** Remove the internal listener and every consumer callback; the handle\n * is dead afterwards. */\n dispose: () => void;\n};\n\n/**\n * Watch a projection of form state without React — the framework-free\n * {@link useWatch} (same `isEqual` bailout), tree-shaken when unused.\n * Returns a {@link WatchHandle}: read `getSnapshot()`, re-read/re-render\n * when `subscribe`'s listener fires. The handle subscribes eagerly, so\n * reads are never stale; `getter`/`isEqual` are captured at creation.\n */\nexport function watch<T>(\n form: Form,\n event: SubscribeEvent,\n getter: () => T,\n isEqual?: (prev: T, next: T) => boolean\n): WatchHandle<T> {\n const cache: {hasValue: boolean; value?: T} = {hasValue: false};\n const consumers = new Set<() => void>();\n const wake = () => {\n if (isEqual && cache.hasValue) {\n // Custom comparator: decide before waking consumers. Equal means\n // unchanged — keep the cache and skip; unequal stores the fresh\n // snapshot so the next read needs no recompute.\n const next = getter();\n if (isEqual(cache.value as T, next)) return;\n cache.value = next;\n } else {\n cache.value = getter();\n cache.hasValue = true;\n }\n consumers.forEach(invalidate => invalidate());\n };\n // Eager: the cache tracks the form from creation, so reads are fresh\n // even before any consumer subscribes.\n const off = on(form.emitter, event, wake);\n return {\n getSnapshot: () => {\n if (!cache.hasValue) {\n cache.value = getter();\n cache.hasValue = true;\n }\n return cache.value as T;\n },\n subscribe: (invalidate: () => void) => {\n consumers.add(invalidate);\n return () => {\n consumers.delete(invalidate);\n };\n },\n dispose: () => {\n off();\n consumers.clear();\n }\n };\n}\n","import {useMemo} from 'react';\nimport create, {segmentsFromKey} from '../path';\nimport type {Name, Path} from '../path';\nimport {normalizePath} from '../util';\n\n/** Rebuild a {@link Path} from its serialized key — the key-pinned\n * subscription pattern: rebuild inside the subscription setup so a\n * closure never captures a render-scope `name`/`Path` object. */\nexport function pathFromKey(key: string): Path {\n return create(segmentsFromKey(key));\n}\n\nexport default function usePath(name: Name): Path {\n // The outer memo rebuilds the Path from its key so subscriptions pin on\n // the key, never the per-render name array; the inner memo absorbs the\n // normalize+create work.\n const key = useMemo(() => create(normalizePath(name)).key, [name]);\n return useMemo<Path>(() => pathFromKey(key), [key]);\n}\n","import {\n useState,\n useEffect,\n useCallback,\n useRef,\n useSyncExternalStore\n} from 'react';\nimport {on} from '../emitter';\nimport type {EventEmitter} from '../emitter';\nimport {onKeyEvent, onPathEvent} from '../subscribe';\nimport type {SubscribeEvent, WatchScope} from '../subscribe';\nimport createForm, {\n FORM_ERROR,\n getErrorByPath,\n getErrorsRecord,\n getErrorsTree,\n getFieldErrorsByPath,\n getValueByPath,\n getValues,\n hasTouchedByPath,\n hasErrors,\n isDirty,\n isFieldDirtyByPath,\n getDirtyFields,\n getTouchedFields,\n setInitialValues,\n runFormValidate,\n reset\n} from '../form';\nimport type {\n FieldError,\n FieldErrors,\n FieldErrorsTree,\n Form,\n FormEvents,\n Options,\n ResetOptions\n} from '../form';\nimport type {AnyPath, PathValueOf} from '../types';\nimport createPath from '../path';\nimport type {Path} from '../path';\nimport {get, isEqual, isPromise} from '../util';\nimport {pathFromKey} from './path';\n\n/** Seed bookkeeping for {@link useForm}'s baseline sync effects: what\n * source object was last seeded (`done` false = nothing seeded yet). */\ntype SeedTracker = {done: boolean; source: any};\n\n/** Seed `source` unless it is the same object — or structurally equal to —\n * the one the previous seed used: reference-first for memoized callers,\n * structural fallback for inline option literals, so only genuinely new\n * content re-seeds (re-seeding clears the values Map, reverting committed\n * edits). Shared by useForm's initialValues and controlled-values\n * effects. */\nfunction seedIfChanged(\n form: Form,\n seeded: SeedTracker,\n source: any,\n resetOptions?: ResetOptions\n): void {\n if (\n seeded.done &&\n (seeded.source === source || isEqual(seeded.source, source))\n ) {\n return;\n }\n seeded.done = true;\n seeded.source = source;\n // resetOptions reroutes the changed-content sync from setInitialValues'\n // baseline swap into full reset semantics — the keep* flags decide what\n // survives (keepDirtyValues keeps the user's uncommitted edits).\n if (resetOptions !== undefined) {\n reset(form, source, resetOptions);\n } else {\n setInitialValues(form, source);\n }\n}\n\n/**\n * Create a form instance bound to this component.\n *\n * Beyond {@link Options}, the optional `values` object enables controlled\n * usage: when it genuinely changes it is re-synced into the form with\n * setInitialValues semantics -- uncommitted user edits are discarded\n * (master-detail semantics: selecting another record replaces the draft),\n * while touched flags and errors survive. Change detection is\n * reference-first with a structural fallback, so re-renders that pass an\n * inline literal with equal content never re-sync -- the user's\n * in-progress typing is never clobbered. Passing `resetOptions` reroutes\n * those changed-content syncs through {@link reset} instead, so its keep*\n * flags govern what survives (`keepDirtyValues: true` keeps the user's\n * uncommitted edits on dirty fields); the reference/structural guard\n * applies to both routes.\n */\nexport default function useForm<T extends Record<string, any> = any>(\n options?: Options<T> & {values?: T; resetOptions?: ResetOptions}\n): Form<T> {\n // Lazy initialization: createForm runs once per mount and the returned\n // instance is stable across re-renders (and StrictMode double renders),\n // without writing to refs during render. A provided `values` object is\n // seeded synchronously here (createForm does the same for initialValues)\n // so the first paint and SSR already reflect the controlled values.\n const [form] = useState(() => {\n const created = createForm<T>(options);\n if (options && options.values !== undefined) {\n setInitialValues(created, options.values);\n }\n return created;\n });\n const initialValues = options && options.initialValues;\n const values = options && options.values;\n const resetOptions = options && options.resetOptions;\n\n // Track which initialValues source object the form was last seeded from\n // (the same-source guard lives in seedIfChanged): inline options create\n // a fresh object every render, and re-seeding clears the values Map\n // (setInitialValues semantics), which would revert every committed edit\n // right after each re-render -- on the client and after hydration alike.\n const seededRef = useRef<SeedTracker | null>(null);\n if (seededRef.current === null)\n seededRef.current = {done: false, source: undefined};\n\n useEffect(() => {\n // undefined = no baseline requested (createForm already defaulted to\n // {}): installing it would clear the values Map on mount for no\n // semantic gain — wiping any render-time useField initialValue seeds.\n // Async sources (Promise or thunk) are excluded too: createForm owns\n // their one-shot resolution, and a thunk's identity changes every\n // render, so re-seeding here would clobber the resolution cycle with\n // the raw function itself.\n if (initialValues === undefined) return;\n if (typeof initialValues === 'function' || isPromise(initialValues)) {\n return;\n }\n seedIfChanged(form, seededRef.current!, initialValues);\n }, [form, initialValues]);\n\n // Controlled values: re-sync only when the incoming object genuinely\n // differs from what the form was last seeded from (seedIfChanged's\n // reference + structural check) — otherwise each re-render's fresh\n // inline literal would clear the values Map and revert the user's\n // uncommitted edits, the same hazard the initialValues guard above\n // protects against. Master-detail semantics still apply whenever the\n // content actually changed, unless `resetOptions` reroutes the sync\n // through reset() so its keep* flags decide what survives.\n const controlledRef = useRef<SeedTracker | null>(null);\n if (controlledRef.current === null)\n controlledRef.current = {done: false, source: undefined};\n\n useEffect(() => {\n if (values === undefined) return;\n seedIfChanged(form, controlledRef.current!, values, resetOptions);\n }, [form, values, resetOptions]);\n\n // Mount validation: the form-level `validate` runs once after mount when\n // the form opted into `validateOnMount` (field kicks are the fields' own\n // — useValidate schedules them per registration). Children's effects run\n // before the parent's, so field registrations are in place by the time\n // this fires. While an async initialValues source is pending, defer to\n // the 'loading' event — it fires after the resolved baseline has landed.\n // The run is fire-and-forget: a rejected validator is the submit path's\n // business, and a sync throw propagates exactly like trigger's.\n useEffect(() => {\n if (!form.validateOnMount || !form.validate) return;\n const run = () => {\n void runFormValidate(form).catch(() => undefined);\n };\n if (!form.isLoading) {\n run();\n return;\n }\n return on(form.emitter, 'loading', () => {\n run();\n });\n }, [form]);\n\n return form;\n}\n\n/** Per-hook snapshot cache for {@link useWatch}. */\ntype WatchCache<T> = {hasValue: boolean; value?: T};\n\n/** Snapshot equality comparator — the `isEqual` contract {@link\n * useWatchCore} documents. */\ntype SnapshotComparator<T> = (prev: T, next: T) => boolean;\n\n/**\n * Shared core of {@link useWatch} and the path-scoped hooks: a\n * useSyncExternalStore binding over a custom event subscription.\n * `subscribeFactory` receives the invalidate callback (drop the snapshot\n * cache, then notify React) and returns its unsubscribe function, so the\n * core stays identical whether the subscription is global or scoped to\n * one path.\n *\n * The optional `isEqual` comparator redirects `invalidate`: instead of\n * dropping the cache and waking React unconditionally, an event first\n * recomputes the getter and asks `isEqual` whether anything observable\n * changed — an equal verdict keeps the cached snapshot and skips the\n * notify entirely (no render at all), an unequal one stores the fresh\n * snapshot and notifies. Omitted, the historical drop-and-notify pipeline\n * runs byte-for-byte unchanged.\n */\nexport function useWatchCore<T>(\n subscribeFactory: (invalidate: () => void) => () => void,\n getter: () => T,\n isEqual?: SnapshotComparator<T>\n): T {\n // useSyncExternalStore requires getSnapshot to return the same reference\n // until the store actually changed, otherwise React warns and loops.\n // Cache the snapshot per hook instance and recompute it only on the first\n // read and after the watched event fired.\n const cacheRef = useRef<WatchCache<T> | null>(null);\n if (cacheRef.current === null) cacheRef.current = {hasValue: false};\n const cache = cacheRef.current;\n\n // Hold the latest getter in a ref so getSnapshot keeps a stable identity\n // (callers pass a freshly bound function on every render) while still\n // recomputing with the most recent getter when the cache is invalid.\n const getterRef = useRef(getter);\n getterRef.current = getter;\n // Same freshness treatment for the comparator: invalidate is created once\n // per subscription, so it must read the latest isEqual through a ref\n // rather than capturing whichever instance the first render passed.\n const isEqualRef = useRef(isEqual);\n isEqualRef.current = isEqual;\n\n const getSnapshot = useCallback(() => {\n if (!cache.hasValue) {\n cache.value = getterRef.current();\n cache.hasValue = true;\n }\n return cache.value as T;\n }, [cache]);\n\n const subscribe = useCallback(\n (notify: () => void) => {\n // The form may have changed between render and this subscription, and\n // those events were missed: drop the cache. React's consistency check\n // right after subscribing recomputes and re-renders only when the\n // fresh value differs from the committed snapshot.\n cache.hasValue = false;\n const invalidate = () => {\n const compare = isEqualRef.current;\n if (compare && cache.hasValue) {\n // Custom comparator: decide before waking React. Equal means the\n // fresh getter result is observably the same — keep the cached\n // reference and return without notifying, so React never even\n // schedules a render. Unequal stores the fresh snapshot up front,\n // so React's own post-notify Object.is check reads it without\n // recomputing the getter.\n const next = getterRef.current();\n if (compare(cache.value as T, next)) return;\n cache.value = next;\n notify();\n return;\n }\n cache.hasValue = false;\n notify();\n };\n return subscribeFactory(invalidate);\n },\n [subscribeFactory, cache]\n );\n\n // Form state lives entirely in synchronously readable Map/Set structures\n // seeded from initialValues/values during the lazy useState initializer,\n // so the server snapshot is computed exactly like the client's first\n // render -- pass getSnapshot itself as getServerSnapshot and hydration\n // matches.\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Subscribe to a form event and keep the component's snapshot of `getter()`\n * in sync with the form state.\n *\n * Built on useSyncExternalStore, so snapshots taken while React renders are\n * guaranteed consistent (no tearing under concurrent rendering) and changes\n * emitted before the subscription effect runs are still picked up.\n *\n * The first argument is the form for the unified `fn(form, ...)` context\n * shape every hook shares; the raw emitter form remains accepted for\n * back-compat and for subscription sources that are not a full form.\n *\n * Framework-free counterpart: {@link watch} — the same event/getter/\n * `isEqual` contract exposed as a named export returning a\n * subscribe/getSnapshot handle any reactive runtime can bind to\n * (useWatch is its React binding; the ref-based cache here keeps inline\n * getters from re-subscribing per render).\n *\n * By default the re-render surface is the event's own scope: every emit\n * the subscription hears drops the snapshot cache and wakes React, which\n * then bails out when the recomputed snapshot is reference-identical\n * (Object.is) — the path/leaf scoping every built-in reader relies on.\n * The optional `isEqual` comparator exists for wide-scope getters that\n * return a fresh reference per call (a whole-values selector, say): each\n * event recomputes the getter and asks `isEqual` whether the result is\n * observably the same, and an equal verdict skips notifying React\n * altogether — no render, not even a bailed-out one. An unequal verdict\n * stores the new snapshot and re-renders. Same contract as TanStack's\n * `useSelector` compare. Omitted, behavior is unchanged.\n */\nexport function useWatch<T>(\n formOrEmitter: Form | EventEmitter<FormEvents>,\n event: SubscribeEvent,\n getter: () => T,\n isEqual?: SnapshotComparator<T>\n): T {\n // A form carries an `emitter` field the opaque emitter instance never\n // has, so the duck test cleanly discriminates the two accepted shapes.\n const emitter =\n 'emitter' in formOrEmitter ? formOrEmitter.emitter : formOrEmitter;\n const subscribeFactory = useCallback(\n (invalidate: () => void) => on(emitter, event, invalidate),\n [emitter, event]\n );\n return useWatchCore(subscribeFactory, getter, isEqual);\n}\n\n/** Options for {@link useValue} and {@link useValueByPath}. */\nexport type UseValueOptions<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n> = {\n /** Value to return while the field reads undefined — react-hook-form's\n * `useWatch` `defaultValue`: an untouched, never-seeded field reads\n * this instead of `undefined`. */\n defaultValue?: PathValueOf<T, P>;\n /** Watch descendants too (react-hook-form's `exact: false`): a write\n * to `a.b` invalidates a `useValue(form, 'a')` read, and the read\n * resolves the merged subtree (the copy-on-write `getValues` tree) so\n * descendant edits show up in the result. Defaults to true — the leaf\n * scope, where only the exact key and its ancestors invalidate (the\n * long-standing behavior). */\n exact?: boolean;\n};\n\n/**\n * Get field value state\n */\nexport function useValue<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P, options?: UseValueOptions<T, P>): PathValueOf<T, P> {\n return useValueByPath(form, createPath(name), options);\n}\n\n/**\n * Get field value state by path\n */\nexport function useValueByPath(\n form: Form,\n path: Path,\n options?: {defaultValue?: any; exact?: boolean}\n): any {\n const {emitter} = form;\n const {key} = path;\n const scope: WatchScope = options?.exact === false ? 'branch' : 'leaf';\n // 'leaf' scope: a leaf read depends only on its own key and its\n // ancestors' (getValueByPath fallback chain), so writes elsewhere --\n // siblings, descendants, string-prefix lookalikes ('[\"a\",\"bX\"]') -- never\n // invalidate the snapshot. 'branch' (exact: false) additionally wakes on\n // descendant writes and resolves the merged subtree through `getValues`\n // (getValueByPath only walks live ancestors, so a descendant edit would\n // otherwise read back a stale reference). Payload-less broadcasts\n // (reset, setInitialValues) still sync everything; removeField matches\n // by path.\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(emitter, 'change', pathFromKey(key), scope, invalidate),\n [emitter, key, scope]\n );\n return useWatchCore(subscribeFactory, () => {\n if (options?.exact === false) {\n return get(getValues(form), path.value);\n }\n const value = getValueByPath(form, path);\n return value === undefined ? options?.defaultValue : value;\n });\n}\n\n/**\n * Subscribe to the whole values tree: re-renders the calling component\n * whenever any 'change' event lands — react-hook-form's `watch()` with no\n * arguments. The snapshot is the memoized `getValues(form)` result, so\n * repeated reads during one render share one reference and, under\n * `__DEV__`, one frozen copy.\n *\n * Broad scope by design: read it in components that must stay cheap and\n * need the full tree; per-field readers should reach for {@link useValue}\n * instead so a keystroke re-renders exactly the affected field.\n */\nexport function useValues<T extends Record<string, any> = any>(\n form: Form<T>\n): T {\n // Arrow wrapper, not getValues.bind: bind collapses the generic, so the\n // bound getter would type as () => Record<string, any> and lose the T.\n return useWatch<T>(form, 'change', () => getValues(form));\n}\n\n/**\n * Get field touched state\n */\nexport function useTouched<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): boolean {\n return useTouchedByPath(form, createPath(name));\n}\n\n/** Exact-key subscription shared by the per-path readers whose state is\n * stored per key (touched, errors): the getter is passed through to\n * {@link useWatchCore} unchanged. */\nfunction useKeyWatch<T>(\n form: Form,\n path: Path,\n event: SubscribeEvent,\n getter: () => T\n): T {\n const {emitter} = form;\n const {key} = path;\n const subscribeFactory = useCallback(\n (invalidate: () => void) => onKeyEvent(emitter, event, key, invalidate),\n [emitter, event, key]\n );\n return useWatchCore(subscribeFactory, getter);\n}\n\n/**\n * Get field touched state by path\n */\nexport function useTouchedByPath(form: Form, path: Path): boolean {\n // Touched is stored per exact key, so only this field's own setTouched\n // (now emitted with its path) matters; payload-less broadcasts (reset,\n // removeField) still sync everything.\n return useKeyWatch(\n form,\n path,\n 'touched',\n hasTouchedByPath.bind(null, form, path)\n );\n}\n\n/**\n * Get field error message state\n * @return current error's message string (display text), or undefined\n */\nexport function useError<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): string | undefined {\n return useErrorByPath(form, createPath(name))?.message;\n}\n\n/**\n * Get field error state by path\n * @return current FieldError object ({type, message}), or undefined\n */\nexport function useErrorByPath(form: Form, path: Path): FieldError | undefined {\n // Errors are stored per exact key, so only writes to this field's error\n // (setErrorByPath now emits with its path) matter; payload-less\n // broadcasts (clearErrors, reset, removeField) still sync everything.\n return useKeyWatch(\n form,\n path,\n 'errors',\n getErrorByPath.bind(null, form, path)\n );\n}\n\n/**\n * Get all field errors\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function useFieldErrors<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): FieldError[] {\n return useFieldErrorsByPath(form, createPath(name));\n}\n\n/**\n * Get all field errors by path\n * @return every error registered for the field (insertion order); an empty\n * array when the field has none\n */\nexport function useFieldErrorsByPath(form: Form, path: Path): FieldError[] {\n // Same exact-key subscription and snapshot rules as useErrorByPath: the\n // getter returns the shared empty constant when clean and the stored\n // array by reference otherwise, so the useSyncExternalStore snapshot is\n // reference-stable between unrelated events.\n return useKeyWatch(\n form,\n path,\n 'errors',\n getFieldErrorsByPath.bind(null, form, path)\n );\n}\n\nexport function useIsDirty(form: Form): boolean {\n // Dirty state is driven by value changes, not touch state: subscribe to\n // 'change' so typing flips this immediately, even before a blur.\n return useWatch(form, 'change', isDirty.bind(null, form));\n}\n\n/**\n * Get whether one field is dirty: its live value exists and differs from\n * the field's effective baseline — the same per-field rule\n * `getFieldState(form, name).isDirty` applies (committed\n * `shouldDirty: false` baselines included). Subscribes to 'change' at\n * leaf scope like {@link useValue}: own-key and ancestor writes re-check\n * the flag, payload-less broadcasts (reset, setInitialValues) always\n * sync, and writes elsewhere never re-render it.\n */\nexport function useIsFieldDirty<\n T extends Record<string, any> = any,\n P extends AnyPath<T> = AnyPath<T>\n>(form: Form<T>, name: P): boolean {\n return useIsFieldDirtyByPath(form, createPath(name));\n}\n\n/**\n * Get whether one field is dirty, by parsed path. See {@link\n * useIsFieldDirty}.\n */\nexport function useIsFieldDirtyByPath(form: Form, path: Path): boolean {\n const {emitter} = form;\n const {key} = path;\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(emitter, 'change', pathFromKey(key), 'leaf', invalidate),\n [emitter, key]\n );\n return useWatchCore(subscribeFactory, () => isFieldDirtyByPath(form, path));\n}\n\n/**\n * Get dirty fields state -- object mapping each dirty field's user-facing\n * dotted path ('a.b', 'a.0.c') to true; recalculated after 'change' events\n */\nexport function useDirtyFields(form: Form): Record<string, boolean> {\n return useWatch(form, 'change', getDirtyFields.bind(null, form));\n}\n\n/**\n * Get touched fields state -- array of touched fields' user-facing dotted\n * paths ('a.b', 'a.0.c'); recalculated after 'touched' events\n */\nexport function useTouchedFields(form: Form): string[] {\n return useWatch(form, 'touched', getTouchedFields.bind(null, form));\n}\n\n/**\n * Aggregate snapshot of the whole form's state flags — the one-subscription\n * counterpart of react-hook-form's `formState` object (no errors object;\n * per-field error state stays with `useError`/`useFieldErrors`, and\n * `hasErrors`/`isValid` cover the whole-form questions).\n *\n * Recomputed on every state-bearing event; the field-wise comparator keeps\n * the returned reference stable while nothing observably changed, so\n * `useFormState(form).isDirty` re-renders no more often than the dedicated\n * {@link useIsDirty}. Cheaper than calling the granular hooks one by one\n * (one subscription and one snapshot instead of one per flag).\n */\nexport type FormState<T extends Record<string, any> = any> = {\n /** Any live value differs from its baseline (see {@link isDirty}). */\n isDirty: boolean;\n /** Dirty fields keyed by user-facing dotted path ('a.b', 'a.0.c'). */\n dirtyFields: Record<string, boolean>;\n /** At least one field is touched. */\n isTouched: boolean;\n /** Touched fields' user-facing dotted paths. */\n touchedFields: string[];\n /** Any error registered (field or form level). */\n hasErrors: boolean;\n /** No errors are registered — react-hook-form's `isValid` semantics.\n * In-flight validation is NOT factored in ({@link isValidating} is the\n * separate signal; async rounds temporarily pass this flag like RHF's). */\n isValid: boolean;\n /** Every error as one record keyed by user-facing dotted path\n * ('a.b', 'list.0') — react-hook-form's `formState.errors` shape,\n * typed as {@link FieldErrors} (per-key values optional). Memoized\n * (see {@link getErrorsRecord}): the reference is stable between error\n * writes, so the snapshot comparator can bail on it. */\n errors: FieldErrors<T>;\n isSubmitting: boolean;\n /**\n * Whether a submit has been attempted on this form — set on the first\n * `handleSubmit` call (validation outcome aside) and cleared by\n * `reset`, react-hook-form's `formState.isSubmitted` semantics. Read\n * after a failed submit to render a \"fix the errors below\" panel.\n */\n isSubmitted: boolean;\n /** Any validation round is running (field, form-level, or a pending\n * debounce window). */\n isValidating: boolean;\n isSubmitSuccessful: boolean | undefined;\n submitCount: number;\n /** Async initialValues still pending ({@link Form.isLoading}). */\n isLoading: boolean;\n /** The form-level disabled flag (fields OR their own `disabled`). */\n disabled: boolean;\n};\n\n/** Events any FormState field can react to: each recomputes the whole\n * snapshot — the comparator, not per-flag subscriptions, keeps the\n * re-render surface minimal. */\nconst FORM_STATE_EVENTS: readonly SubscribeEvent[] = [\n 'change',\n 'errors',\n 'touched',\n 'validating',\n 'submitting',\n 'submitCount',\n 'submitSuccessful',\n 'disabled',\n 'loading'\n];\n\n/** Subscribe to every state-bearing event at once — the wiring\n * {@link useFormState} and {@link useStore} share. */\nfunction subscribeFormStateEvents(\n emitter: EventEmitter<FormEvents>,\n invalidate: () => void\n): () => void {\n const offs = FORM_STATE_EVENTS.map(event => on(emitter, event, invalidate));\n return () => {\n for (const off of offs) off();\n };\n}\n\nfunction getFormState<T extends Record<string, any>>(\n form: Form<T>\n): FormState<T> {\n const anyErrors = hasErrors(form);\n return {\n isDirty: isDirty(form),\n dirtyFields: getDirtyFields(form),\n isTouched: form.touched.size > 0,\n touchedFields: getTouchedFields(form),\n hasErrors: anyErrors,\n isValid: !anyErrors,\n errors: getErrorsRecord(form),\n isSubmitting: form.isSubmitting,\n isSubmitted: form.isSubmitted,\n isValidating: form.validating.size > 0,\n isSubmitSuccessful: form.isSubmitSuccessful,\n submitCount: form.submitCount,\n isLoading: form.isLoading,\n disabled: form.disabled\n };\n}\n\n/** Field-wise equality: reference checks where the getter already memoizes\n * (dirtyFields), element-wise for the fresh array getTouchedFields builds,\n * value checks for the flags. */\nfunction isSameFormState<T extends Record<string, any>>(\n a: FormState<T>,\n b: FormState<T>\n): boolean {\n const sameTouched =\n a.touchedFields.length === b.touchedFields.length &&\n a.touchedFields.every((path, i) => path === b.touchedFields[i]);\n return (\n a.isDirty === b.isDirty &&\n a.dirtyFields === b.dirtyFields &&\n a.isTouched === b.isTouched &&\n sameTouched &&\n a.hasErrors === b.hasErrors &&\n a.isValid === b.isValid &&\n a.errors === b.errors &&\n a.isSubmitting === b.isSubmitting &&\n a.isSubmitted === b.isSubmitted &&\n a.isValidating === b.isValidating &&\n a.isSubmitSuccessful === b.isSubmitSuccessful &&\n a.submitCount === b.submitCount &&\n a.isLoading === b.isLoading &&\n a.disabled === b.disabled\n );\n}\n\nexport function useFormState<T extends Record<string, any> = any>(\n form: Form<T>\n): FormState<T> {\n const getter = useCallback(() => getFormState(form), [form]);\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n subscribeFormStateEvents(form.emitter, invalidate),\n [form.emitter]\n );\n return useWatchCore(subscribeFactory, getter, isSameFormState);\n}\n\n/**\n * The official selector primitive — TanStack Form's\n * `useStore(store, selector)` counterpart. Subscribes to every\n * state-bearing form event and keeps `selector()`'s result as the\n * snapshot; the selector itself is a plain closure (read the form through\n * any getter — `getValue`, `getValues`, `form.errors.size`, …).\n *\n * Without `isEqual` the subscription is object-identity based: each event\n * recomputes the selector and React bails out when the result is\n * reference-identical (the contract every `useWatch` reader relies on).\n * The optional `isEqual(prev, next)` comparator is for wide-scope\n * selectors that return a fresh reference per call (a whole-values\n * projection, say): an equal verdict skips notifying React altogether —\n * no render, not even a bailed-out one (TanStack `useSelector` compare\n * contract).\n *\n * `useFormState` is the built-in aggregate selector; {@link useWatch} is\n * the single-event version. Reach for `useStore` when the projection is\n * yours and spans state events — e.g. `form.validating.size > 0 &&\n * form.isSubmitting` as one flag.\n */\nexport function useStore<T>(\n form: Form,\n selector: () => T,\n isEqual?: SnapshotComparator<T>\n): T {\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n subscribeFormStateEvents(form.emitter, invalidate),\n [form.emitter]\n );\n return useWatchCore(subscribeFactory, selector, isEqual);\n}\n\nexport function useHasErrors(form: Form): boolean {\n return useWatch(form, 'errors', hasErrors.bind(null, form));\n}\n\n/**\n * Get every error as one record keyed by user-facing dotted path\n * ('a.b', 'list.0') — react-hook-form's `formState.errors` shape, for\n * error-summary panels and a11y announcements. Values are the stored\n * FieldError[] arrays shared with the form (treat as read-only). The\n * record is memoized per form (see {@link getErrorsRecord}): the hook\n * re-renders only when an error write actually changed the record's\n * content.\n */\nexport function useErrors<T extends Record<string, any> = any>(\n form: Form<T>\n): FieldErrors<T> {\n return useWatch(form, 'errors', () => getErrorsRecord(form));\n}\n\n/**\n * Get every error as one nested object following the values tree\n * (`errors.items?.[0]?.name` reads) — the typed optional-chaining\n * counterpart of {@link useErrors}' flat dotted record. Leaves hold the\n * stored FieldError[] arrays shared with the form (treat as read-only).\n * Memoized alongside the record (see {@link getErrorsTree}): the hook\n * re-renders only when an error write actually changed the tree's\n * content.\n */\nexport function useErrorsTree<T extends Record<string, any> = any>(\n form: Form<T>\n): FieldErrorsTree<T> {\n return useWatch(form, 'errors', () => getErrorsTree(form));\n}\n\n/**\n * Get whether the form currently has no errors — react-hook-form's\n * `formState.isValid` counterpart. Subscribes to the `'errors'` event only;\n * in-flight validation does not flip it (see {@link useIsValidating}).\n */\nexport function useIsValid(form: Form): boolean {\n return useWatch(form, 'errors', () => !hasErrors(form));\n}\n\nexport function useIsSubmitting(form: Form): boolean {\n return useWatch(form, 'submitting', () => form.isSubmitting);\n}\n\n/**\n * Get whether an async {@link Options.initialValues} source is still\n * pending — the flag a loading skeleton or a disabled submit button gates\n * on until the resolved baseline lands. Subscribes to the 'loading' event\n * the core emits around the resolution cycle.\n */\nexport function useIsLoading(form: Form): boolean {\n return useWatch(form, 'loading', () => form.isLoading);\n}\n\n/**\n * Get the form's user-owned metadata slot reactively (Formik's `status`\n * counterpart): any value the app stores through {@link setStatus} —\n * server session flags, wizard step state, non-field errors. Subscribes\n * to the payload-less 'status' event, so unrelated events never re-render\n * the caller, and the returned reference is stable between writes that\n * store an equal value (useSyncExternalStore's Object.is bailout).\n */\nexport function useStatus<T = any>(form: Form): T {\n return useWatch(form, 'status', () => form.status);\n}\n\n/**\n * Get whether the form accepts a submit right now:\n * `!isSubmitting && !hasErrors`. This is the single flag a submit\n * button's `disabled` prop wants — it is `false` for the whole async\n * `onSubmit` span (not just the validation pass) and whenever any field\n * holds an error (client validation or server backfill), replacing the\n * hand-rolled `useHasErrors(form) || useIsSubmitting(form)` pair.\n * Deliberately no dirty or validating semantics: an untouched-but-clean\n * form can submit.\n */\nexport function useCanSubmit(form: Form): boolean {\n const {emitter} = form;\n // canSubmit folds two events into one boolean: error writes\n // ('errors') and submit-state flips ('submitting'). useWatch subscribes\n // to a single event, so subscribe to both through useWatchCore — the\n // snapshot recomputes on either wake and re-renders only when the\n // boolean itself flips, so unrelated single-field error churn costs no\n // extra render (the same granularity useHasErrors already has).\n const subscribeFactory = useCallback(\n (invalidate: () => void) => {\n const offErrors = on(emitter, 'errors', invalidate);\n const offSubmitting = on(emitter, 'submitting', invalidate);\n return () => {\n offErrors();\n offSubmitting();\n };\n },\n [emitter]\n );\n return useWatchCore(\n subscribeFactory,\n () => !form.isSubmitting && !hasErrors(form)\n );\n}\n\nexport function useSubmitCount(form: Form): number {\n return useWatch(form, 'submitCount', () => form.submitCount);\n}\n\n/**\n * Get whether any validation round is currently running: a field\n * validator's pending `validateDebounce` window, an async field validator\n * still in flight, or the form-level validate's debounce window / in-flight\n * round — every one of them holds a key in `form.validating`, and the\n * 'validating' events they emit (field rounds with a path payload, the\n * form-level round as a payload-less broadcast) are what this subscribes\n * to. The boolean snapshot is Object.is-stable, so churn among the marks\n * (a second field opening while the first settles) costs no render while\n * the flag holds. This is the flag a submit button disables itself on, or\n * spins a spinner with, through the pre-submit validation pass — it flips\n * true the moment the first round opens and back false when the last one\n * settles.\n */\nexport function useIsValidating(form: Form): boolean {\n return useWatch(form, 'validating', () => form.validating.size > 0);\n}\n\n/**\n * Get whether the last submit succeeded: `true` once a submit's validation\n * and `onSubmit` completed without throwing, `false` after a failed submit\n * (validation rejection or a thrown callback) and before any submit ran —\n * the falsy reading of the undefined initial/reset state. Subscribes to\n * the 'submitSuccessful' event the core's setSubmitSuccessful emits, so\n * the flag flips in the same tick the outcome lands: the usual consumers\n * are a success banner and a redirect-on-success effect.\n */\nexport function useIsSubmitSuccessful(form: Form): boolean {\n return useWatch(\n form.emitter,\n 'submitSuccessful',\n () => !!form.isSubmitSuccessful\n );\n}\n\n/**\n * Get the form-level error message: the first error stored under the\n * reserved {@link FORM_ERROR} key, as display text — or undefined while\n * the slot is clean. That key is where a form-level `validate` record's\n * `_form` entry lands and where the Standard Schema adapter drops\n * path-less issues, so errors that belong to no single field still have a\n * reader. The classic usage renders it once above the submit button —\n * `useFormError(form) || null` — and the imperative twin is\n * `getError(form, FORM_ERROR)`.\n */\nexport function useFormError(form: Form): string | undefined {\n return useErrorByPath(form, createPath(FORM_ERROR))?.message;\n}\n\n/**\n * Get every form-level error: all errors stored under the reserved\n * {@link FORM_ERROR} key (insertion order), an empty array when the slot\n * is clean. The plural twin of {@link useFormError} for forms that stack\n * several form-level issues — each path-less Standard Schema issue lands\n * in this slot. The array reference is stable between unrelated events\n * (the stored array or a shared empty constant), so consumers can memo on\n * it; the imperative counterpart is `getFieldErrors(form, FORM_ERROR)`.\n */\nexport function useFormErrors(form: Form): FieldError[] {\n return useFieldErrorsByPath(form, createPath(FORM_ERROR));\n}\n","import {useCallback, useEffect, useRef, type MutableRefObject} from 'react';\nimport {removeFieldForUnmount, restoreRemovedField} from '../core/unmount';\nimport type {RemovedFieldSnapshot} from '../core/unmount';\nimport type {Form} from '../form';\nimport type {Path} from '../path';\n\nexport default function useStage<T>(value: T): MutableRefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport function useStageFn<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useStage(fn);\n return useCallback(\n (...params: any[]) => ref.current(...params),\n [ref]\n ) as unknown as T;\n}\n\n/**\n * Run `teardown` synchronously on every cleanup, and let a setup that\n * immediately follows a cleanup undo it — StrictMode's dev\n * setup→cleanup→setup double-invoke would otherwise wipe state the\n * remount expects; a real unmount has no following setup, so the\n * teardown stands. `teardown`/`restore` must be referentially stable.\n */\nexport function useUnmountRestore(\n teardown: () => void,\n restore: () => void\n): void {\n const removedRef = useRef(false);\n const teardownRef = useStage(teardown);\n const restoreRef = useStage(restore);\n useEffect(() => {\n // Copy the staged callbacks at setup so the cleanup reads stable\n // locals, not `ref.current` (which may have changed by cleanup time).\n const teardownOnce = teardownRef.current;\n const restoreOnce = restoreRef.current;\n // The previous cleanup ran the teardown — StrictMode remount: restore.\n if (removedRef.current) {\n removedRef.current = false;\n restoreOnce();\n }\n return () => {\n removedRef.current = true;\n teardownOnce();\n };\n }, [removedRef, teardownRef, restoreRef]);\n}\n\n/**\n * Shared field/field-array unmount: snapshot-and-remove the branch unless\n * the effective `shouldUnregister` opts out, restoring on StrictMode\n * remount.\n */\nexport function useUnmountFieldRemoval(\n form: Form,\n path: Path,\n shouldUnregister: boolean | undefined\n): void {\n const removalSnapshotRef = useRef<RemovedFieldSnapshot | null>(null);\n const teardownOnUnmount = useStageFn(() => {\n if ((shouldUnregister ?? form.shouldUnregister) === false) return;\n removalSnapshotRef.current = removeFieldForUnmount(form, path);\n });\n const restoreAfterStrictMode = useStageFn(() => {\n const snapshot = removalSnapshotRef.current;\n removalSnapshotRef.current = null;\n if (snapshot) restoreRemovedField(form, path, snapshot);\n });\n useUnmountRestore(teardownOnUnmount, restoreAfterStrictMode);\n}\n","import {useContext, useEffect} from 'react';\nimport {on} from '../emitter';\nimport {FormContext} from '../context';\nimport {registerValidatorByPath} from '../form';\nimport type {Form, SyncValidator, Validator} from '../form';\nimport type {Path} from '../path';\nimport type {FieldRules} from '../rules';\nimport {hasStandardProps, schemaToFieldValidator} from '../standardSchema';\nimport type {StandardSchemaV1} from '../standardSchema';\nimport {pathFromKey} from './path';\nimport useStage, {useStageFn} from './stage';\n\n// The validator contract itself is framework-free and lives in the core\n// (`src/form.ts`); re-exported here so historical imports keep working.\nexport type {SyncValidator, Validator};\n\n/** Option spellings shared across the field, field-array and validator\n * hooks — private to the hooks slice, never part of the public facade. */\nexport type FieldOptionBase = {\n /** Declarative rules compiled into a sync validator. */\n rules?: FieldRules;\n /** Whether unmounting removes the branch; defaults to the form-level\n * `shouldUnregister` (tombstone). `false` keeps the values. */\n shouldUnregister?: boolean;\n /** Keep the debounced validator running when the sync gate failed\n * (TanStack `asyncAlways`): gate errors land immediately, the\n * validator's result lands alongside them per-source. */\n asyncAlways?: boolean;\n /** Validate once on mount (overrides the form-level flag in either\n * direction). Deferred while async `initialValues` is pending. */\n validateOnMount?: boolean;\n};\n\n/**\n * Options for {@link useValidate}: the registration machinery (debounce\n * window, async-round lock, signal abort, validating mark) lives in the\n * core's {@link registerValidatorByPath}; this hook wires its React\n * lifecycle — register on mount, dispose on unmount, read options live\n * through refs so re-renders never re-subscribe.\n */\nexport type UseValidateOptions = Pick<\n FieldOptionBase,\n 'asyncAlways' | 'validateOnMount'\n> & {\n /** Milliseconds to debounce this validator's kicks; `0` (default) runs\n * immediately, and the field counts as validating while the window is\n * pending. The `sync` pre-validator is exempt. */\n debounce?: number;\n /** Synchronous pre-validator run on every kick, never debounced; while\n * it fails, the debounced validator is skipped and pending work is\n * superseded. A passing check clears its own stale error. */\n sync?: SyncValidator;\n};\n\n/** Coerce a `validate` option that may be a Standard Schema into a plain\n * validator — a plain validator passes through, `undefined` stays. */\nexport function schemaAsValidator(\n validate: Validator | StandardSchemaV1<any, any> | undefined\n): Validator | undefined {\n return validate && hasStandardProps(validate)\n ? schemaToFieldValidator(validate as StandardSchemaV1<any, any>)\n : (validate as Validator | undefined);\n}\n\n/**\n * Register a field validator and return its kick (debounce + sync gate\n * applied) — stored in `form.validators` for `trigger`/`ensureValidate`\n * and the user-change gate. The machinery lives in the core's\n * {@link registerValidatorByPath}; this is its React binding.\n */\nexport default function useValidate(\n validate: Validator | StandardSchemaV1<any, any> | undefined,\n path: Path,\n formProp?: Form,\n options?: UseValidateOptions\n): () => void {\n // Unconditional context read keeps hook order stable; an explicit form\n // wins (no <FormProvider> needed).\n const contextForm = useContext(FormContext);\n const form = formProp || contextForm;\n if (!form) throw new Error('no form provided');\n // Live accessors: the registration always sees the latest\n // validator/debounce/sync-gate, so per-render swaps never re-subscribe.\n // A Standard Schema is wrapped into a validator here.\n const validateRef = useStage(schemaAsValidator(validate));\n const debounceRef = useStage(options?.debounce ?? 0);\n const syncRef = useStage(options?.sync);\n const asyncAlwaysRef = useStage(options?.asyncAlways ?? false);\n // Same live-ref pattern: the effect keys on [form, path.key], so the\n // option read must not appear in its closure (it would re-run the\n // registration per render).\n const validateOnMountRef = useStage(options?.validateOnMount);\n\n useEffect(() => {\n const spath = pathFromKey(path.key);\n const dispose = registerValidatorByPath(form, spath, {\n validate: () => validateRef.current,\n debounce: () => debounceRef.current,\n sync: () => syncRef.current,\n asyncAlways: () => asyncAlwaysRef.current\n });\n // Kick once after the registration lands (own option over form-level).\n // Validator-less registrations never kick — an empty kick would clear\n // a stored server error.\n const validateOnMount = validateOnMountRef.current ?? form.validateOnMount;\n if (!validateOnMount || (!validateRef.current && !syncRef.current)) {\n return dispose;\n }\n // A deferred kick must never fire after disposal (unmount, or\n // StrictMode's setup→cleanup→setup remount); the flag drops it.\n let disposed = false;\n const kick = () => {\n if (disposed) return;\n form.validators.get(path.key)?.();\n };\n if (!form.isLoading) {\n kick();\n } else {\n // Async initialValues pending: 'loading' fires after the resolved\n // baseline lands, so the kick validates real values.\n const off = on(form.emitter, 'loading', () => {\n off();\n kick();\n });\n }\n return () => {\n disposed = true;\n dispose();\n };\n }, [\n form,\n path.key,\n debounceRef,\n syncRef,\n asyncAlwaysRef,\n validateRef,\n validateOnMountRef\n ]);\n\n return useStageFn(() => form.validators.get(path.key)?.());\n}\n","import {useCallback, useContext, useEffect, useRef} from 'react';\nimport type {Context} from 'react';\nimport {on} from '../emitter';\nimport {FormContext} from '../context';\nimport {\n emitChangeByPath,\n getFieldErrorsByPath,\n getValueByPath,\n isFieldDirtyByPath,\n registerFieldMode,\n registerFieldValidateDeps,\n seedValueByPath,\n unregisterFieldMode,\n unregisterFieldValidateDeps,\n userBlur,\n userChangeByPath\n} from '../form';\nimport type {FieldError, Form, ValidationMode, ValidatorOutput} from '../form';\nimport createPath from '../path';\nimport type {Path} from '../path';\nimport type {StandardSchemaV1} from '../standardSchema';\nimport type {AnyPath, FieldPath, PathValueOf} from '../types';\nimport {hasRuleConstraints, rulesToValidator} from '../rules';\nimport type {FieldRules, FormMessages} from '../rules';\nimport {errorIdFromKey} from '../errorId';\nimport {eventToValueOrDefault, isPromise} from '../util';\nimport {\n hasDisabledAncestor,\n registerFieldDisabled,\n unregisterFieldDisabled\n} from '../core/disabled';\nimport {useWatchCore} from './form';\nimport {onKeyEvent, onPathEvent} from '../subscribe';\nimport usePath, {pathFromKey} from './path';\nimport useValidate, {schemaAsValidator} from './validate';\nimport type {Validator} from './validate';\nimport useStage, {useStageFn, useUnmountFieldRemoval} from './stage';\n\n/** Dev-only flag, replaced at build time (rollup.config.js `replace`);\n * defined for the test environment in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\ntype UncontrolledSyncCell = () => {el: any; path: Path};\n\n/** Module-private registry driving uncontrolled fields' DOM sync — one\n * 'change' listener per form (see the sync effect in {@link\n * useFieldCore}), the same module-scope registry pattern\n * `arrayIdsRegistry` uses in fieldArray.ts. Per-form cells map a field's\n * path key to a reader of its bound element and path; the shared listener\n * iterates them only on payload-less (bulk) emits. */\ntype UncontrolledSyncEntry = {\n cells: Map<string, UncontrolledSyncCell>;\n off: () => void;\n};\nconst uncontrolledSyncRegistry = new WeakMap<Form, UncontrolledSyncEntry>();\n\n/** Get-or-create the per-form sync entry: the first uncontrolled field\n * mounts the shared 'change' listener; later ones reuse it. */\nfunction getUncontrolledSyncEntry(form: Form): UncontrolledSyncEntry {\n const existing = uncontrolledSyncRegistry.get(form);\n if (existing) return existing;\n const cells = new Map<string, UncontrolledSyncCell>();\n const off = on(form.emitter, 'change', (changed?: Path) => {\n if (changed) return;\n for (const read of cells.values()) {\n const {el, path} = read();\n // File inputs cannot be assigned a value at all.\n if (!el || el.type === 'file') continue;\n const next = getValueByPath(form, path);\n const asString = next == null ? '' : String(next);\n if (el.value !== asString) el.value = asString;\n }\n });\n const entry = {cells, off};\n uncontrolledSyncRegistry.set(form, entry);\n return entry;\n}\n\nexport type UseFieldOptions<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = {\n form?: Form<TValues>;\n name: TPath;\n initialValue?: any;\n shouldUnregister?: boolean;\n /**\n * Field-level validator. The value argument follows the path: with a\n * typed form the callback receives `PathValueOf<TValues, TPath>` (the\n * TanStack-parity inference — `name: 'age'` on a `{age: number}` shape\n * types `value` as `number`), and falls back to `any` for untyped call\n * sites (segment arrays, dynamic names). The return shape mirrors\n * {@link Validator} — an error (string / FieldError / mixed array) or\n * undefined when valid, possibly a Promise for async validation. The\n * second argument carries the validation context (`meta.signal` aborts\n * when the round is superseded).\n */\n validate?:\n | ((\n value: PathValueOf<TValues, TPath>,\n meta: {form: Form<TValues>; path: Path; signal: AbortSignal}\n ) => ReturnType<Validator>)\n | StandardSchemaV1<PathValueOf<TValues, TPath>>;\n /**\n * Declarative rules (required/min/max/minLength/maxLength/pattern),\n * compiled into a synchronous validator. `required` is special: it runs\n * immediately on every kick — never debounced — and while it fails,\n * `validate` is skipped (the expensive check never sees an empty value).\n * The other rules compose with `validate` — rules run first, then\n * `validate` (awaited when async), merging both sources' errors with\n * rules errors ahead. Failures land in the form's error state with the\n * given or default messages.\n */\n rules?: FieldRules;\n /**\n * Milliseconds to debounce this field's validation kicks. Defaults to 0\n * (validate immediately); while the timer is pending the field counts as\n * validating, so `trigger`/`ensureValidate` wait out the window. Only the\n * last kick inside the window runs the validator. The `required` rule is\n * exempt: it runs synchronously on every kick, so a required failure\n * shows immediately instead of waiting out the window.\n */\n validateDebounce?: number;\n /**\n * Run this field's debounced validator even when its `required` gate\n * failed — TanStack Form's `asyncAlways`. The gate's errors land\n * immediately (never debounced) and the validator's own result lands\n * alongside them, per-source: a passing async round clears only its\n * own errors while the gate's verdict stays. Falls back to the\n * form-level `createForm({asyncAlways})` flag when omitted, so a field\n * opts out with `asyncAlways: false`. The use case: the cheap format\n * check fails (gate) but the expensive backend check should still run\n * (\"not in the right shape — and the backend says taken, too\").\n */\n asyncAlways?: boolean;\n /**\n * Milliseconds to delay showing a newly appearing error in the render\n * layer (`error`/`errorObject`/`errors` stay undefined/empty until the\n * window passes). The form's error state is never delayed — trigger,\n * submit and `getError` read it immediately. An error that clears inside\n * the window never shows; once an error is visible, later changes apply\n * immediately. Only the none → some transition waits.\n */\n delayError?: number;\n /**\n * Disable this field: merged into the result's `disabled` as\n * `form.disabled || own === true || (own !== false && an ancestor\n * declared disabled)`. `disabled: true` on a parent path disables every\n * descendant field too (react-hook-form subtree semantics), and a\n * descendant declares `disabled: false` to opt back out of that\n * ancestor. The form-level flag (`createForm({disabled})` /\n * `setDisabled`) cannot be opted out of.\n */\n disabled?: boolean;\n /**\n * Uncontrolled mode: the field never subscribes to its own value, so\n * typing re-renders nothing — the store still carries every write\n * (getValues/submit/validation read it), and errors/touched/disabled/\n * validating still re-render the field like react-hook-form's\n * `register`. The result's `value` is the mount-time snapshot (initial\n * value seed or baseline); it never refreshes, and bulk operations\n * (reset/setInitialValues) sync the DOM element directly through the\n * `focusRef`-held element instead of a render — the register-style\n * contract, RHF's reset clears the input the same way. Attach the\n * result with `<input defaultValue={field.value} ref={field.focusRef}>`\n * -style binding (no `value` prop), exactly like <Field uncontrolled />\n * does. The DOM sync writes the raw stored value (file inputs are\n * skipped); read live values with useValue/getValues.\n */\n uncontrolled?: boolean;\n /**\n * Field-level validation mode override: when given, this field validates\n * on its own schedule instead of `form.mode` — every other field keeps\n * the form-level timing (e.g. a form that defaults to `'onSubmit'` with\n * one field declared `'onBlur'` shows that field's error on blur while\n * the rest wait for submit). `reValidateMode` stays form-level: once any\n * field has an error (after a failed submit, say), re-validation follows\n * the form's `reValidateMode` for every field, overriding this one too.\n * See {@link ValidationMode}.\n */\n mode?: ValidationMode;\n /**\n * Field paths whose **user changes re-run this field's validator** —\n * the field-level counterpart of the form-level `validateDeps` option\n * (cross-field linkage: `password` changed → re-check\n * `passwordConfirm`). TanStack Form's `onChangeListenTo` / RHF trigger\n * chains are the ecosystem analogues.\n *\n * The re-run rides the changed field's own onChange pipeline, so typing\n * and `changeValue` both fire it while programmatic `setValue` does\n * not, and its timing is gated by the same mode matrix as the form\n * level: the changed field's effective `mode` (per-field override\n * included) and the form's `reValidateMode` — under the default\n * `'onSubmit'`/`'onChange'` pair, a dep change re-validates this field\n * once this field already shows an error (the submit-then-fix flow: the\n * mismatch lands on submit, editing the password re-checks the confirm\n * and a passing round clears the error, because a field validator owns\n * its whole key).\n *\n * `validateDebounce` applies to the re-run like to any kick. Declaring\n * the field's own path is a no-op (its own change already validates it).\n */\n validateDeps?: FieldPath<TValues>[];\n /**\n * Validate this field once on mount instead of waiting for the first\n * submit/change — errors show immediately for an untouched field.\n * Overrides the form-level `createForm({validateOnMount})` flag in\n * either direction (`false` opts a field out of a validating form).\n * While an async `initialValues` source is still pending the kick waits\n * for the resolved baseline; a field unmounted in between never kicks.\n */\n validateOnMount?: boolean;\n /**\n * DOM event → value extractor for the result's {@link\n * UseFieldResult.inputProps} binding. Defaults to the element's own\n * protocol (files → `target.files`, checkbox → `target.checked`,\n * `valueAsNumber`/`valueAsDate` under their flags, else\n * `target.value`); a non-DOM event passes through unchanged, so custom\n * controls can hand raw values. Only consumed by `inputProps` — the\n * headless `onChange` keeps taking raw values.\n */\n eventToValue?: (e: any) => any;\n /** `inputProps` stores `e.target.valueAsNumber` instead of the string\n * value (number inputs, RHF's `register({valueAsNumber})`). An\n * explicit `eventToValue` takes precedence. */\n valueAsNumber?: boolean;\n /** `inputProps` stores `e.target.valueAsDate` instead of the string\n * value (date/time inputs, RHF's `register({valueAsDate})`). An\n * explicit `eventToValue` takes precedence; combining with\n * `valueAsNumber` is a TypeError (`valueAsNumber` wins). */\n valueAsDate?: boolean;\n /**\n * Element type hint for {@link UseFieldResult.inputProps} only:\n * `'checkbox'` renders `checked` instead of `value`, `'file'` renders\n * neither (file inputs cannot be value-controlled). The extraction\n * itself already auto-detects both types from the event's target.\n */\n type?: string;\n};\n\n/**\n * The result of {@link useField}. Deliberately a closed shape: no index\n * signature, so a typo'd property access (`field.vlaue`) is a type error\n * instead of silently reading `undefined`.\n */\nexport type UseFieldResult<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = {\n /** The form instance this field is bound to (explicit prop or context) —\n * handy for consumers that need direct access to the headless API. */\n form: Form<TValues>;\n value: PathValueOf<TValues, TPath>;\n /** Error message string (FieldError#message) for display, or undefined */\n error: string | undefined;\n /** Full FieldError object ({type, message}), or undefined */\n errorObject: FieldError | undefined;\n /** Every error registered for the field, in insertion order — `error`\n * and `errorObject` are its first entry. Empty (and reference-stable)\n * when the field has no errors. */\n errors: FieldError[];\n /**\n * Whether the field is dirty: its live value exists and differs from\n * the field's effective baseline (the same per-field rule\n * `getFieldState(form, name).isDirty` applies — committed\n * `shouldDirty: false` baselines included). Live in controlled mode;\n * pinned at mount in uncontrolled mode (like `value`) so typing never\n * re-renders the field — {@link useIsFieldDirty} is the live scoped\n * channel for either mode.\n */\n isDirty: boolean;\n /**\n * Whether a validator round for this field is currently in flight —\n * a pending debounce window or an unresolved async validator (the\n * `getFieldState(form, name).isValidating` reading, made reactive).\n */\n validating: boolean;\n onChange: (v: any) => void;\n onBlur: () => void;\n name: string;\n /** Merged disabled flag: the form-level flag (`createForm({disabled})`\n * toggled by `setDisabled`) OR-ed with this field's own `disabled`\n * option, updated live through the form's event core. */\n disabled: boolean;\n /**\n * Callback ref carrying the focus channel: attach it to your input\n * element (`<input ref={field.focusRef} />`) so `setFocus` and a failed\n * submit's first-error auto-focus (`shouldFocusError`) can focus this\n * headless field — the same 'focusError' wiring `<Field>` performs for\n * its own input. Without it, focus requests aimed at this field are\n * silent no-ops, matching `setFocus`'s contract: focusing a field\n * whose element is not bound neither throws nor focuses anything.\n */\n focusRef: (el: any) => void;\n /**\n * DOM-ready props for an `<input>`: `<input {...field.inputProps} />`\n * binds the element to the field without hand-wiring value/onChange/\n * onBlur/ref/a11y. `onChange` takes the DOM event (extraction per\n * {@link UseFieldOptions}' `eventToValue`/`valueAsNumber`/`valueAsDate`\n * /`type`), `ref` is the focus channel, `aria-invalid`/`aria-describedby`\n * complete the {@link errorIdFromKey} chain — render the error element\n * with `fieldErrorId(name)` to finish it. The headless `value`/\n * `onChange`/`onBlur`/`focusRef` stay available for custom controls\n * that hand raw values (design systems) — `inputProps` is the DOM\n * boundary adapter, never a replacement.\n */\n inputProps: UseFieldInputProps;\n};\n\n/**\n * The spreadable DOM props {@link UseFieldResult.inputProps} carries:\n * `name`, `onChange` (event-based), `onBlur`, `ref`, `disabled`, the\n * error a11y wiring, and exactly one of `value` (controlled),\n * `defaultValue` (uncontrolled) or `checked` (`type: 'checkbox'`) —\n * `type: 'file'` carries none. Always spread `inputProps` FIRST, so the\n * caller's own props (placeholder, className, an explicit `ref` they\n * merge themselves) win.\n */\nexport type UseFieldInputProps = {\n name: string;\n value?: any;\n defaultValue?: any;\n checked?: boolean;\n onChange: (e: any) => void;\n onBlur: () => void;\n ref: (el: any) => void;\n disabled: boolean;\n 'aria-invalid'?: boolean;\n 'aria-describedby'?: string;\n};\n\n/**\n * Compose declarative rules with a user validator: rules run first, then\n * the user's validator (awaited when async), and the results merge into\n * one error list with rules errors ahead. Either side may be absent —\n * the other passes through untouched. Errors are returned as an array (or\n * undefined when both sides pass), which setErrorByPath stores as-is.\n */\nfunction combineRulesAndValidate(\n rules: FieldRules | undefined,\n validate: Validator | undefined,\n formMessages: FormMessages | undefined\n): Validator | undefined {\n if (!rules || !hasRuleConstraints(rules)) return validate;\n const ruleValidator = rulesToValidator(rules, formMessages);\n if (!validate) return ruleValidator;\n return (value, meta) => {\n // rulesToValidator's contract is FieldError[] | undefined; the wider\n // Validator union here is only its declared type.\n const ruleErrors = ruleValidator(value, meta) as FieldError[] | undefined;\n const merge = (\n other: ValidatorOutput | undefined\n ): (string | FieldError)[] | undefined => {\n const list: (string | FieldError)[] = [...(ruleErrors ?? [])];\n if (Array.isArray(other)) list.push(...other);\n else if (other) list.push(other);\n return list.length ? list : undefined;\n };\n const result = validate(value, meta);\n return isPromise(result) ? result.then(merge) : merge(result);\n };\n}\n\n/**\n * Render-layer gating for {@link UseFieldOptions}.delayError: hold a newly\n * appearing error back for `delay` ms while the form's error state stays\n * immediate. Only the none → some transition waits — an error that clears\n * inside the window never shows, and once an error is visible, later\n * changes (a new message, entries added or removed) apply immediately.\n *\n * The subscription rides {@link useWatchCore} (useSyncExternalStore), so\n * it is live before sibling passive effects kick mount validation and\n * re-renders synchronously on every error event — the same contract the\n * previous dedicated error watch held. The pending window is the only\n * mutable piece and lives in refs: the subscribe callback flips it and\n * the window's timer invalidates the snapshot at the deadline. No state\n * writes at all — the shown list is derived from the store plus the\n * window flag, so nothing runs in an effect body or during render. With\n * `delay === undefined` the subscription still drives re-renders but the\n * store's list passes through untouched: no timers, no window state —\n * fields that do not opt in pay nothing beyond the hook call itself.\n */\n\n/** Shared empty list returned while {@link useDelayedErrors} holds an\n * appearing error back — a stable reference so consumers can memo on it,\n * mirroring the core's shared NO_ERRORS constant. */\nconst NO_DELAYED_ERRORS: FieldError[] = [];\n\nfunction useDelayedErrors(\n form: Form<any>,\n path: Path,\n delay: number | undefined\n): FieldError[] {\n // The window flag and the last event's shape live in refs: the\n // subscribe callback reads them across events, and the snapshot reads\n // the flag at render. Single-threaded, so flag-then-invalidate is\n // always observed as one consistent state.\n const pendingRef = useRef(false);\n const prevRef = useRef(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const subscribeFactory = useCallback(\n (invalidate: () => void) => {\n // Rebuild the Path from its key so the callback never captures the\n // render-scope `path` object — the subscription pins on the key.\n const spath = pathFromKey(path.key);\n const clearTimer = () => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n };\n // A re-subscription (delay change, StrictMode remount) drops any\n // stale window: the new subscription re-derives from the store.\n pendingRef.current = false;\n prevRef.current = false;\n clearTimer();\n const startWindow = () => {\n clearTimer();\n pendingRef.current = true;\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n pendingRef.current = false;\n // Deadline reached with the errors stable through the window:\n // re-render so the snapshot reveals them.\n invalidate();\n }, delay);\n };\n const off = onKeyEvent(form.emitter, 'errors', spath.key, () => {\n const has = getFieldErrorsByPath(form, spath).length > 0;\n const was = prevRef.current;\n prevRef.current = has;\n if (delay !== undefined) {\n if (!has) {\n // Clearing is always immediate: an error cleared inside the\n // window is cancelled before ever showing, a shown one hides\n // at once.\n if (pendingRef.current) {\n clearTimer();\n pendingRef.current = false;\n }\n } else if (!was || pendingRef.current) {\n // Appearing from none — or changing inside the window, which\n // restarts it: wait out `delay` before showing. Already\n // showing: swaps and list changes apply at once (nothing to\n // do beyond the invalidate below).\n startWindow();\n }\n }\n invalidate();\n });\n return () => {\n off();\n clearTimer();\n };\n },\n [form, path.key, delay]\n );\n\n return useWatchCore(subscribeFactory, () =>\n delay === undefined || !pendingRef.current\n ? getFieldErrorsByPath(form, path)\n : NO_DELAYED_ERRORS\n );\n}\n\n/**\n * Value snapshot for {@link useFieldCore}. Controlled fields subscribe to\n * 'change' at their own path (leaf scope) and track the store live.\n * Uncontrolled fields instead pin the value read at mount: no change\n * subscription, so typing re-renders nothing while the store still carries\n * every write (getValues/submit/validation read it). Errors, touched,\n * disabled and validating stay subscribed, so state-driven re-renders\n * behave like react-hook-form's `register`. The pinned snapshot is\n * deliberately never refreshed — reset/setInitialValues do not push into\n * it (or into a `defaultValue`-bound DOM element).\n */\nfunction useFieldValue(form: Form, path: Path, uncontrolled: boolean): any {\n const snapshotRef = useRef<{has: boolean; value: any}>({\n has: false,\n value: undefined\n });\n const getter = useCallback(() => {\n if (!uncontrolled) return getValueByPath(form, path);\n if (!snapshotRef.current.has) {\n snapshotRef.current = {has: true, value: getValueByPath(form, path)};\n }\n return snapshotRef.current.value;\n }, [uncontrolled, form, path]);\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n uncontrolled\n ? () => {}\n : onPathEvent(form.emitter, 'change', path, 'leaf', invalidate),\n [uncontrolled, form.emitter, path]\n );\n return useWatchCore(subscribeFactory, getter);\n}\n\n/**\n * Shared core of {@link useField} and the per-instance hooks returned by\n * `createFormContext()`: identical behavior, but the form is resolved from\n * whichever Context instance is passed in instead of the module-level one.\n *\n * `form` is always handed to `useValidate` explicitly, and an explicit form\n * wins over `useValidate`'s own context read — so scoped contexts need no\n * changes there.\n */\nexport function useFieldCore<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n>(\n {\n form: f1,\n name,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateDeps,\n validateOnMount,\n delayError,\n disabled,\n uncontrolled,\n asyncAlways,\n mode: modeOption,\n eventToValue,\n valueAsNumber,\n valueAsDate,\n type\n }: UseFieldOptions<TValues, TPath>,\n Context: Context<Form<any> | null>\n): UseFieldResult<TValues, TPath> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = f1 || contextForm;\n if (!form) throw new Error('no form provided');\n const path = usePath(name);\n\n // Seed initialValue during render, not in an effect: the first paint\n // (SSR included — effects never run on the server) must already carry\n // the value, so the write lands here — before the value subscription\n // below takes its first snapshot. The write is emit-free (see\n // seedValueByPath) because emitting while rendering is illegal; the\n // post-commit effect announces it. The `=== undefined` guard keeps user\n // input and committed values safe across re-renders and remounts.\n const seededRef = useRef(false);\n const seeded =\n initialValue !== undefined && getValueByPath(form, path) === undefined;\n if (seeded) {\n seedValueByPath(form, path, initialValue);\n // Sticky until the announce effect consumes it, so StrictMode's second\n // render (which sees the value already seeded) still announces once.\n seededRef.current = true;\n }\n useEffect(() => {\n // Dep-less on purpose: the seed can land on a later render too (a\n // setInitialValues/reset wiped it; the guard re-seeds), and the\n // announcement must follow every actual seed. The flag makes the\n // steady state a cheap check.\n if (!seededRef.current) return;\n seededRef.current = false;\n // Wake path-scoped subscribers that rendered before this field in an\n // earlier commit — their snapshots predate the seed. Same-commit\n // subscribers self-heal through useSyncExternalStore's post-subscribe\n // snapshot check, and subscribers that already saw the seeded value\n // re-read an unchanged snapshot and bail out.\n emitChangeByPath(form, path);\n });\n\n // Undeclared options are dropped on purpose: the return value carries\n // only the fields declared on UseFieldResult, so nothing rides it back\n // onto DOM elements through a component's prop spread.\n //\n // `required` splits off into useValidate's synchronous gate: it runs\n // immediately on every kick (never debounced) and, while it fails, the\n // debounced validator is skipped — the other rules and `validate` never\n // see an empty value. The remaining rules still compose with `validate`\n // inside the debounced validator.\n const restRules: FieldRules | undefined = rules\n ? {...rules, required: undefined}\n : undefined;\n // A Standard Schema passed straight to `validate` becomes a validator\n // before composing with the rules (combineRulesAndValidate calls the\n // validator as a function, which a schema object is not).\n const validateWrapped = schemaAsValidator(validate);\n useValidate(\n combineRulesAndValidate(restRules, validateWrapped, form.messages),\n path,\n form,\n {\n debounce: validateDebounce,\n validateOnMount,\n asyncAlways: asyncAlways ?? form.asyncAlways,\n sync:\n rules && rules.required !== undefined\n ? rulesToValidator({required: rules.required}, form.messages)\n : undefined\n }\n );\n\n // All errors of the field through one subscription owned by\n // useDelayedErrors; the array reference is stable (stored array or\n // shared empty constants), so consumers can memo on it. delayError\n // gates only this render-layer view of the list; the stored list keeps\n // driving the reValidateMode kicks inside the core's user-change gate.\n const errors = useDelayedErrors(form, path, delayError);\n const errorObject = errors[0];\n const error = errorObject?.message;\n const value = useFieldValue(form, path, !!uncontrolled);\n // isDirty is a value-derived flag: like the value itself, it stays live\n // only in controlled mode. Uncontrolled fields pin it at mount — a live\n // subscription here would re-render the field on every keystroke and\n // break the register-parity contract (typing re-renders nothing). The\n // live scoped channel for either mode is useIsFieldDirty. `validating`\n // is a non-value flag: it stays subscribed in both modes (like errors/\n // touched/disabled), matching its exact key with payload-less\n // broadcasts still syncing everything.\n const isDirty = useWatchCore(\n useCallback(\n (invalidate: () => void) =>\n uncontrolled\n ? () => {}\n : onPathEvent(\n form.emitter,\n 'change',\n pathFromKey(path.key),\n 'leaf',\n invalidate\n ),\n [form.emitter, path.key, uncontrolled]\n ),\n () => isFieldDirtyByPath(form, path)\n );\n const validating = useWatchCore(\n useCallback(\n (invalidate: () => void) =>\n onKeyEvent(form.emitter, 'validating', path.key, invalidate),\n [form.emitter, path.key]\n ),\n () => form.validating.has(path.key)\n );\n\n // The disabled merge — computed INSIDE the watch snapshot, because\n // useSyncExternalStore bails out of re-rendering when the snapshot is\n // Object.is-equal: splitting the merge out of the getter would keep the\n // form-flag snapshot unchanged while an ancestor's option flips, and\n // the re-render (and with it the fresh registry read) would never run.\n // Subscribed with branch scope on the 'disabled' event: setDisabled's\n // payload-less emit wakes every field, while a path-payload emit (this\n // field's own or an ancestor's `disabled` option registering/flipping)\n // wakes exactly the affected subtree. The merge rule: the form-level\n // flag (no opt-out) OR this field's own `true`, OR — while this field\n // did not opt out with `false` — an ancestor declared disabled\n // (react-hook-form subtree semantics).\n const mergedDisabled = useWatchCore(\n useCallback(\n (invalidate: () => void) =>\n onPathEvent(\n form.emitter,\n 'disabled',\n pathFromKey(path.key),\n 'branch',\n invalidate\n ),\n [form.emitter, path.key]\n ),\n () =>\n form.disabled ||\n disabled === true ||\n (disabled !== false && hasDisabledAncestor(form, path))\n );\n\n // Publish this field's own `disabled` option into the subtree registry\n // so descendants merge it in — and re-render when it flips (the\n // registration emits the path-payload 'disabled' event). A field that\n // never declares the option registers nothing.\n const disabledTokenRef = useRef<object | null>(null);\n useEffect(() => {\n const spath = pathFromKey(path.key);\n const registration = registerFieldDisabled(form, spath, disabled);\n if (registration) disabledTokenRef.current = registration.token;\n return () => {\n if (disabledTokenRef.current !== null) {\n unregisterFieldDisabled(form, spath, disabledTokenRef.current);\n disabledTokenRef.current = null;\n }\n };\n }, [form, path.key, disabled]);\n\n // The user-change pipeline lives in the core: onChange forwards to\n // userChangeByPath (write + mode/reValidateMode-gated validation, the\n // matrix registered below through registerFieldMode), onBlur to\n // userBlur (touched marking + blur-side gate). The stage keeps the\n // handler identities stable across re-renders.\n const onChange = useStageFn((v: any) => userChangeByPath(form, path, v));\n const onBlur = useStageFn(() => userBlur(form, path));\n\n // Register this field's validation-mode override so path-based\n // user-change writes (changeValue / changeValueByPath) route through\n // the same gated core pipeline as a user typing into the field.\n // Two fields mounted at the same path compete for the slot last-wins:\n // from here on every user-change write gates on the latest mount's\n // mode. That is almost always a bug (a stray duplicate name, a remount\n // racing the old instance) — say so in DEV.\n useEffect(() => {\n const spath = pathFromKey(path.key);\n const {token, displaced} = registerFieldMode(form, spath, modeOption);\n if (__DEV__ && displaced) {\n // eslint-disable-next-line no-console -- the whole point of this branch\n console.warn(\n `react-f0rm: two fields are mounted at the same path ${path.key}. ` +\n `The latest mount's mode registration owns the slot, so changeValue ` +\n `writes gate on it and the earlier field's validation mode no ` +\n `longer applies. Use distinct names if both must stay mounted.`\n );\n }\n return () => unregisterFieldMode(form, spath, token);\n }, [form, path.key, modeOption]);\n\n // Publish this field's validateDeps declaration so the dep fields'\n // change pipelines can find it (revalidateDependentsOnChange). Keyed on\n // the serialized dep list, so a re-render passing an equal inline array\n // does not churn the registry; a genuinely changed list re-registers.\n const depsKey = validateDeps?.length ? validateDeps.join('\\n') : undefined;\n // Stage the dep list: the effect keys on `depsKey` (the serialized\n // list), and reads the live array through the ref so an equal inline\n // array per render never re-registers while a changed one always does.\n const validateDepsRef = useStage<string[] | undefined>(validateDeps);\n useEffect(() => {\n if (!depsKey) return;\n const depKeys = validateDepsRef.current!.map(dep => createPath(dep).key);\n registerFieldValidateDeps(form, path.key, depKeys);\n return () => unregisterFieldValidateDeps(form, path.key, depKeys);\n }, [form, path.key, depsKey, validateDepsRef]);\n\n // The focus channel. 'focusError' carries the target's path key —\n // emitted by handleSubmit's failed round (the first error's key, gated\n // by shouldFocusError) and by setFocus (with an optional\n // {shouldSelect} second argument). Subscribing here rather than inside\n // <Field> means headless useField consumers get focus support by\n // attaching focusRef; <Field> merely forwards it through its merged\n // ref. The callback ref is identity-stable, so re-renders never detach\n // the element, and the null guard keeps unbound fields silent no-ops.\n const elementRef = useRef<any>(null);\n const focusRef = useCallback((el: any) => {\n elementRef.current = el;\n }, []);\n useEffect(\n () =>\n on(\n form.emitter,\n 'focusError',\n (key: string, options?: {shouldSelect?: boolean}) => {\n if (key !== path.key) return;\n const el = elementRef.current;\n if (!el || typeof el.focus !== 'function') return;\n el.focus();\n if (options?.shouldSelect && typeof el.select === 'function') {\n el.select();\n }\n }\n ),\n [form, path.key]\n );\n\n // Uncontrolled DOM sync: a payload-less 'change' means a bulk operation\n // (reset, setInitialValues) rewrote values without a React render, and\n // an uncontrolled field deliberately never subscribes to its own value\n // — so its DOM element would keep stale text. Write the store's value\n // straight into the element held by the focus channel (register-style:\n // no re-render — exactly how RHF's reset clears uncontrolled inputs).\n //\n // One listener per form, not per field: a per-field subscription would\n // add O(mounted fields) handler calls to every keystroke — breaking the\n // O(affected-fields) change contract the uncontrolled parity bench\n // measures. The shared listener returns on the first check for\n // payload-carrying emits (typing, setValue), so bulk operations pay one\n // iteration over the registered cells and keystrokes pay one branch.\n useEffect(() => {\n const spath = pathFromKey(path.key);\n const entry = getUncontrolledSyncEntry(form);\n entry.cells.set(path.key, () => ({el: elementRef.current, path: spath}));\n return () => {\n entry.cells.delete(path.key);\n if (entry.cells.size === 0) {\n entry.off();\n uncontrolledSyncRegistry.delete(form);\n }\n };\n }, [form, path.key, uncontrolled]);\n\n // Effective unmount behavior: the field's own option, falling back\n // to the form-level default, then to this library's historical\n // default (tombstone). The removal snapshots first and a setup that\n // immediately follows the cleanup (StrictMode's dev\n // setup→cleanup→setup cycle) restores it — see useUnmountRestore.\n useUnmountFieldRemoval(form, path, shouldUnregister);\n\n // inputProps: the DOM-boundary adapter over the same headless handlers.\n // Its onChange takes the DOM event — extraction per the options above or\n // the element's own protocol — so `<input {...field.inputProps} />`\n // behaves exactly like <Field>'s default binding.\n if (__DEV__ && valueAsNumber && valueAsDate) {\n // eslint-disable-next-line no-console -- dev-only diagnostics\n console.warn(\n 'react-f0rm: valueAsNumber and valueAsDate are mutually exclusive — ' +\n 'valueAsNumber wins. Use eventToValue for anything else.'\n );\n }\n const extract = eventToValueOrDefault(eventToValue, {\n valueAsNumber,\n valueAsDate\n });\n const inputProps: UseFieldInputProps = {\n name: path.key,\n ref: focusRef,\n onChange: (e: any) => onChange(extract(e)),\n onBlur,\n disabled: mergedDisabled\n };\n // Exactly one of checked/value/defaultValue: a checkbox renders\n // `checked`, a file input is never value-controlled, and the remaining\n // types split controlled `value` from uncontrolled `defaultValue`.\n if (type === 'checkbox') {\n inputProps.checked = !!value;\n } else if (type !== 'file') {\n if (uncontrolled) inputProps.defaultValue = value;\n else inputProps.value = value ?? '';\n }\n if (error) {\n inputProps['aria-invalid'] = true;\n inputProps['aria-describedby'] = errorIdFromKey(path.key);\n }\n\n return {\n form,\n value,\n error,\n errorObject,\n errors,\n isDirty,\n validating,\n onChange,\n onBlur,\n name: path.key,\n disabled: mergedDisabled,\n focusRef,\n inputProps\n };\n}\n\nexport default function useField<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n>(options: UseFieldOptions<TValues, TPath>): UseFieldResult<TValues, TPath> {\n return useFieldCore(options, FormContext);\n}\n","import {useCallback, useContext, useEffect, useReducer, useRef} from 'react';\nimport type {Context} from 'react';\nimport {FormContext} from '../context';\nimport {getValueByPath, setValueByPath} from '../form';\nimport type {FieldError, Form, Name} from '../form';\nimport {emit} from '../emitter';\nimport createPath from '../path';\nimport type {Path} from '../path';\nimport {\n appendValueByPath,\n insertValueByPath,\n moveValueByPath,\n prependValueByPath,\n removeValueByPath,\n replaceValuesByPath,\n swapValuesByPath,\n updateValueByPath\n} from '../core/array';\nimport {firstMountedDescendantKey} from '../core/change';\nimport {rulesToValidator} from '../rules';\nimport {onPathEvent} from '../subscribe';\nimport {useFieldErrorsByPath} from './form';\nimport usePath from './path';\nimport useStage, {useStageFn, useUnmountFieldRemoval} from './stage';\nimport useValidate from './validate';\nimport type {FieldOptionBase} from './validate';\n\n/** Per-form row-id counter. A module-level counter would grow across\n * every form on the page — and, on the server, across requests (ids like\n * `_4701` after a day of SSR). Keyed weakly so it dies with the form. */\nconst idCounters = new WeakMap<Form, number>();\n\nfunction generateId(form: Form): string {\n const next = (idCounters.get(form) ?? 0) + 1;\n idCounters.set(form, next);\n return `_${next}`;\n}\n\n/**\n * Live `id -> index` tables shared between {@link useFieldArray} and\n * {@link useFieldArrayItem}: one ids array per (form, array key), keyed\n * weakly so it dies with the form. The array is the hook's own `idsRef`\n * reference (mutated in place by the movers), so items always read the\n * latest order without owning a subscription of their own.\n */\nconst arrayIdsRegistry = new WeakMap<Form, Map<string, string[]>>();\n\nfunction getArrayIds(form: Form, key: string): string[] | undefined {\n return arrayIdsRegistry.get(form)?.get(key);\n}\n\nfunction registerArrayIds(form: Form, key: string, ids: string[]): void {\n const registry = arrayIdsRegistry.get(form) ?? new Map<string, string[]>();\n registry.set(key, ids);\n arrayIdsRegistry.set(form, registry);\n}\n\n/** Resolve a just-added row's focus target one task later: at mover time\n * the row is only a write — its fields (and their 'focusError'\n * subscriptions) mount during the commit, so `focus: true` has no\n * descendants to find until then. No target means a silent no-op. */\nfunction scheduleArrayRowFocus(\n form: Form,\n path: Path,\n index: number,\n options: FieldArrayFocusOptions | undefined\n): void {\n // Destructured to a const: the narrowing must survive into the timer\n // callback (a parameter's would not).\n const {focus} = options ?? {};\n if (focus === undefined) return;\n setTimeout(() => {\n const segments = [...path.value, index];\n const key =\n typeof focus === 'string'\n ? createPath([...segments, focus]).key\n : firstMountedDescendantKey(form, createPath(segments));\n if (key !== undefined) emit(form.emitter, 'focusError', key);\n }, 0);\n}\n\n/** Stable identity for the render-count reducer below: never recreated,\n * so the dispatch path stays referentially clean. */\nfunction bumpReducer(count: number): number {\n return count + 1;\n}\n\ntype FieldArrayItem<K extends string> = {id: string; index: number} & Record<\n K,\n string\n>;\n\n/** Options accepted by {@link useFieldArray} and the per-instance hook\n * returned by `createFormContext()`. */\nexport type UseFieldArrayOptions<K extends string = 'id'> = Pick<\n FieldOptionBase,\n 'rules' | 'shouldUnregister'\n> & {\n name: Name;\n form?: Form;\n /**\n * Property name the stable row key is exposed under on each `fields`\n * entry (react-hook-form's `keyName`): defaults to `'id'`, a custom\n * name (e.g. `'key'`) avoids clashing with a row data field of the\n * same name. The underlying id is unchanged.\n */\n keyName?: K;\n};\n\n/** Second argument of the row-adding movers: `focus` decides whether the\n * new row takes focus once it commits — `true` targets its first mounted\n * child field, a string names the child field. */\nexport type FieldArrayFocusOptions = {focus?: boolean | string};\n\nexport type UseFieldArrayResult<TItem = any, K extends string = 'id'> = {\n fields: FieldArrayItem<K>[];\n /** Append one row. With the item type declared —\n * `useFieldArray<Item>({name: 'items'})` — the value is checked\n * against the array's element type. */\n append: (value: TItem, options?: FieldArrayFocusOptions) => void;\n prepend: (value: TItem, options?: FieldArrayFocusOptions) => void;\n insert: (\n index: number,\n value: TItem,\n options?: FieldArrayFocusOptions\n ) => void;\n /** Remove one row, or several in a single write (`remove([0, 2])` —\n * order-insensitive, duplicates ignored, out-of-range indices are\n * silent no-ops). */\n remove: (indices: number | number[]) => void;\n swap: (from: number, to: number) => void;\n move: (from: number, to: number) => void;\n replace: (values: TItem[]) => void;\n update: (index: number, value: TItem) => void;\n};\n\n/**\n * Shared core of {@link useFieldArray} and the per-instance hook returned by\n * `createFormContext()`: identical behavior, but the form is resolved from\n * whichever Context instance is passed in instead of the module-level one.\n * The `TItem` generic types the movers' value arguments; it defaults to\n * `any` so untyped call sites compile unchanged.\n */\nexport function useFieldArrayCore<TItem = any, K extends string = 'id'>(\n options: UseFieldArrayOptions<K>,\n Context: Context<Form<any> | null>\n): UseFieldArrayResult<TItem, K> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = options.form || contextForm;\n if (!form) throw new Error('no form provided');\n const keyName = (options.keyName ?? 'id') as K;\n const {rules, shouldUnregister} = options;\n const path = usePath(options.name);\n const idsRef = useRef<string[]>([]);\n\n const computeFields = useCallback(() => {\n const arr = getValueByPath(form, path) || [];\n while (idsRef.current.length < arr.length) {\n idsRef.current.push(generateId(form));\n }\n while (idsRef.current.length > arr.length) {\n idsRef.current.pop();\n }\n return idsRef.current.map((id, index) => ({\n id,\n index,\n [keyName]: id\n })) as FieldArrayItem<K>[];\n }, [form, path, keyName]);\n\n // Subscribe to 'change' events scoped to this array's branch: the array\n // key itself, its ancestors (an ancestor write replaces what the leaf\n // read falls back to) and its descendants (item edits), so typing into\n // unrelated fields does not re-render the array component. Payload-less\n // 'change' emits (reset, setInitialValues) always sync, and a field\n // unmounting inside the branch fires through the descendant match. The\n // comma-separated key prefix comparison lives in onPathEvent,\n // which keeps lookalike sibling keys ('[\"tagsX\"]') from matching.\n const [fields, syncFields] = useReducer(\n computeFields,\n undefined,\n computeFields\n );\n useEffect(\n () => onPathEvent(form.emitter, 'change', path, 'branch', syncFields),\n [form.emitter, path]\n );\n\n // Publish the live ids array so per-item hooks (useFieldArrayItem) can\n // resolve id -> index. Registered during render — not only in an effect —\n // so items rendered in the same first paint, and on the server, already\n // resolve; the set is idempotent (same reference every render, the\n // movers mutate it in place, `replace` swaps it and the next render\n // re-registers). The effect mirrors the registration because StrictMode\n // exercises the cleanup path on mount (unsubscribe, un-register, re-run)\n // without a fresh render in between — without it the table would stay\n // empty and every item would resolve to -1. Unmount drops the entry\n // only while this hook still owns it; a second useFieldArray at the\n // same path competes for the slot last-wins, same as the field-mode\n // registration in useField.\n registerArrayIds(form, path.key, idsRef.current);\n useEffect(() => {\n const ids = idsRef.current;\n registerArrayIds(form, path.key, ids);\n return () => {\n const registry = arrayIdsRegistry.get(form);\n if (registry?.get(path.key) === ids) registry.delete(path.key);\n };\n }, [form, path.key]);\n\n // Unmount behavior mirrors a bound field's: the effective\n // shouldUnregister (this hook's option, falling back to the form-level\n // default — tombstone unless the form opts into RHF's keep-the-value\n // semantics) decides whether the branch drops out of reads and\n // getValues(). Removing the branch also clears its\n // errors/touched/dirty entries. The snapshot/restore pair rides\n // useUnmountRestore so StrictMode's dev setup→cleanup→setup cycle does\n // not wipe the branch on mount while real unmounts stay synchronous.\n useUnmountFieldRemoval(form, path, shouldUnregister);\n\n // Declarative array rules: `required` splits into the synchronous gate\n // (runs immediately on every kick, never debounced) exactly like\n // useField's rules; the remaining rules land as the debounced validator.\n useValidate(\n rules\n ? rulesToValidator({...rules, required: undefined}, form.messages)\n : undefined,\n path,\n form,\n {\n sync:\n rules?.required !== undefined\n ? rulesToValidator({required: rules.required}, form.messages)\n : undefined\n }\n );\n\n // Every mover delegates to the framework-free core op (src/core/array.ts)\n // and mirrors its outcome onto the row-id table. The core op reports what\n // actually happened — the dropped indices for removals, a boolean for the\n // guarded movers — so the ids stay in exact lockstep with the values with\n // no duplicated range-check logic: a guarded no-op touches neither the\n // values nor the ids.\n const append = useStageFn(\n (value: TItem, options?: FieldArrayFocusOptions) => {\n idsRef.current.push(generateId(form));\n appendValueByPath(form, path, value);\n scheduleArrayRowFocus(form, path, idsRef.current.length - 1, options);\n }\n );\n\n const prepend = useStageFn(\n (value: TItem, options?: FieldArrayFocusOptions) => {\n idsRef.current.unshift(generateId(form));\n prependValueByPath(form, path, value);\n scheduleArrayRowFocus(form, path, 0, options);\n }\n );\n\n const insert = useStageFn(\n (index: number, value: TItem, options?: FieldArrayFocusOptions) => {\n if (!insertValueByPath(form, path, index, value)) return;\n idsRef.current.splice(index, 0, generateId(form));\n scheduleArrayRowFocus(form, path, index, options);\n }\n );\n\n const remove = useStageFn((indices: number | number[]) => {\n // Dropped indices come back descending — splice them in that order and\n // the remaining positions never shift mid-loop.\n const dropped = removeValueByPath(form, path, indices);\n for (const index of dropped) idsRef.current.splice(index, 1);\n });\n\n const swap = useStageFn((from: number, to: number) => {\n if (!swapValuesByPath(form, path, from, to)) return;\n [idsRef.current[from], idsRef.current[to]] = [\n idsRef.current[to],\n idsRef.current[from]\n ];\n });\n\n const move = useStageFn((from: number, to: number) => {\n if (!moveValueByPath(form, path, from, to)) return;\n const [id] = idsRef.current.splice(from, 1);\n idsRef.current.splice(to, 0, id);\n });\n\n // replace is a full swap (length may change), so every row is conceptually\n // a new row: regenerate all ids to remount them, mirroring how reset works.\n const replace = useStageFn((values: TItem[]) => {\n idsRef.current = values.map(() => generateId(form));\n replaceValuesByPath(form, path, values);\n });\n\n // update only overwrites one value, so the id at that index is kept and the\n // row does not remount. Out-of-bounds indices are a silent no-op — plain\n // assignment would instead punch sparse-array holes into the form state.\n const update = useStageFn((index: number, value: TItem) => {\n updateValueByPath(form, path, index, value);\n });\n\n return {fields, append, prepend, insert, remove, swap, move, replace, update};\n}\n\nexport default function useFieldArray<TItem = any, K extends string = 'id'>(\n options: UseFieldArrayOptions<K>\n): UseFieldArrayResult<TItem, K> {\n return useFieldArrayCore<TItem, K>(options, FormContext);\n}\n\n/**\n * The result of {@link useFieldArrayItem}. Mirrors the {@link useField}\n * return shape (`value`/`errors`/`error`) plus the row's `index` and\n * `name` (path key) so nested fields can build on it —\n * `useField({name: ['tags', item.index, 'label']})`.\n */\nexport type UseFieldArrayItemResult<TValue = any> = {\n value: TValue;\n /** Overwrite this row's value in place (same array-layer write as\n * `update(index, value)`: the row's id and position are kept). */\n setValue: (value: TValue) => void;\n /** Every error registered for the row's path, insertion order; the\n * shared empty constant while clean, so consumers can memo on it. */\n errors: FieldError[];\n /** First error's message — the display text — or undefined. */\n error: string | undefined;\n /** The row's current path key (JSON-stringified segments, e.g.\n * `[\"tags\",0]`); moves with the row across reorder/remove. */\n name: string;\n /** The row's current position in the array. `-1` while the row is being\n * removed (or when no useFieldArray is mounted at `name`): reads return\n * undefined and nothing writes the dangling path. */\n index: number;\n form: Form;\n};\n\n/** Options for {@link useFieldArrayItem} and its per-instance core: the\n * array's `name`, the row's stable `id` (from `fields[i].id`), and an\n * optional explicit `form`. */\ntype UseFieldArrayItemOptions = {name: Name; id: string; form?: Form};\n\n/**\n * Shared core of {@link useFieldArrayItem} and the per-instance hook\n * returned by `createFormContext()`: identical behavior, but the form is\n * resolved from whichever Context instance is passed in instead of the\n * module-level one.\n */\nexport function useFieldArrayItemCore<TValue = any>(\n options: UseFieldArrayItemOptions,\n Context: Context<Form<any> | null>\n): UseFieldArrayItemResult<TValue> {\n // Read the context unconditionally (hook call order must be stable), then\n // let an explicitly passed form win — works without a <FormProvider>.\n const contextForm = useContext(Context);\n const form = options.form || contextForm;\n if (!form) throw new Error('no form provided');\n const {id} = options;\n const arrayPath = usePath(options.name);\n\n // --- snapshots: locate the row by its stable id through the array's\n // published ids table, then read its value from the array layer — the\n // same layer every useFieldArray operation and `setValue` below write,\n // so `value` and update/append/swap/… always agree with each other.\n const computeIndex = useCallback(\n () => getArrayIds(form, arrayPath.key)?.indexOf(id) ?? -1,\n [form, arrayPath.key, id]\n );\n const computeValue = useCallback(\n (index: number) => {\n const arr = getValueByPath(form, arrayPath);\n return Array.isArray(arr) ? arr[index] : undefined;\n },\n [form, arrayPath]\n );\n\n // Both are read synchronously during render (SSR included: no effect is\n // involved), and the last-rendered pair is mirrored into refs for the\n // subscription below. Writing own refs during render follows the same\n // pattern as `useStage`.\n const index = computeIndex();\n const value = computeValue(index) as TValue;\n const lastRef = useRef({index, value});\n lastRef.current = {index, value};\n\n // A render is scheduled only when the row's own view would change. The\n // subscription is 'leaf'-scoped on the array key: every useFieldArray\n // operation rewrites that key (payload-less broadcasts — reset,\n // setInitialValues — always fire), so this fires exactly when the row\n // order or the array can have moved, while a write to one item's leaf\n // path (`['tags', 1]`) never fires it. The comparison happens in the\n // listener — not through React's equal-state bailout, which act/test\n // environments do not honor — so an unchanged row never dispatches at\n // all and its component function never runs: append, update and\n // single-row edits leave untouched rows completely quiet, and a\n // whole-array rewrite re-renders only rows whose value reference (or\n // index) actually changed — the shallow copies keep untouched items'\n // references stable. Rows whose index migrates (remove/move/swap/\n // insert) re-render by design; computing `next` with the fresh index\n // means a row that moved but kept its value still bumps.\n const computeRef = useStage({computeIndex, computeValue});\n const [, bump] = useReducer(bumpReducer, 0);\n useEffect(\n () =>\n onPathEvent(form.emitter, 'change', arrayPath, 'leaf', () => {\n const {computeIndex: idx, computeValue: val} = computeRef.current;\n const nextIndex = idx();\n if (\n nextIndex !== lastRef.current.index ||\n !Object.is(val(nextIndex), lastRef.current.value)\n )\n bump();\n }),\n [form.emitter, arrayPath, computeRef]\n );\n\n // --- errors: stored per exact key, so this is the one place the row's\n // indexed path is needed. A removed row resolves to index -1: the\n // parent is about to unmount this component (its key left `fields`),\n // and until that commit lands the dangling key is inert — reads return\n // undefined/no errors and the `setValue` guard refuses to write. -1\n // also surfaces when no useFieldArray is mounted at `name`; pairing\n // the two hooks is the documented contract.\n const itemPath = usePath([...arrayPath.value, index]);\n const errors = useFieldErrorsByPath(form, itemPath);\n\n const setValue = useStageFn((v: TValue) => {\n if (index < 0) return;\n const arr = [...(getValueByPath(form, arrayPath) ?? [])];\n if (index >= arr.length) return;\n arr[index] = v;\n setValueByPath(form, arrayPath, arr);\n });\n\n return {\n value,\n setValue,\n errors,\n error: errors[0]?.message,\n name: itemPath.key,\n index,\n form\n };\n}\n\n/**\n * Subscribe to a single row of a {@link useFieldArray} field — the\n * per-item counterpart `useFieldArray` alone cannot offer. `useFieldArray`\n * subscribes to the whole branch, so any row's edit re-renders the\n * component holding the array (and, without memoization, every row);\n * `useFieldArrayItem` scopes what re-renders to one row identified by its\n * stable id: editing row K re-renders only row K's component, and a\n * whole-array rewrite re-renders only rows whose value reference actually\n * changed. Pair it with a `React.memo` row component that takes stable\n * props (`form`, `id`) so the array component's own re-render cannot drag\n * the rows along.\n *\n * Rows whose index migrates — remove/move/swap/insert reshuffles —\n * re-render by design: the row's path contains the index, exactly like\n * TanStack Form's per-field api. The win is single-row edits staying\n * single-row.\n *\n * Value reads and writes live on the array layer — the same layer every\n * `useFieldArray` operation touches — so `value`, `setValue` and\n * `update`/`append`/… always agree with each other.\n *\n * @param options `name` of the array (a useFieldArray must be mounted at\n * the same path — it publishes the id table), the row's `id` from\n * `fields[i].id`, and optionally an explicit `form`\n */\nexport function useFieldArrayItem<TValue = any>(\n options: UseFieldArrayItemOptions\n): UseFieldArrayItemResult<TValue> {\n return useFieldArrayItemCore(options, FormContext);\n}\n","import {\n createContext,\n createElement,\n useContext,\n type Context,\n type Provider,\n type ReactNode\n} from 'react';\nimport {\n useFieldCore,\n type UseFieldOptions,\n type UseFieldResult\n} from './hooks/field';\nimport {\n useFieldArrayCore,\n useFieldArrayItemCore,\n type UseFieldArrayOptions,\n type UseFieldArrayResult,\n type UseFieldArrayItemResult\n} from './hooks/fieldArray';\nimport type {FieldRules} from './rules';\nimport type {Form} from './form';\nimport type {Name} from './path';\nimport type {AnyPath, FieldPath} from './types';\n\nexport const FormContext: Context<Form<any> | null> =\n createContext<Form<any> | null>(null);\n\nexport const FormProvider: Provider<Form<any> | null> = FormContext.Provider;\n\n/**\n * Read the form from the module-level {@link FormContext}; pass the values\n * shape (`useFormContext<Values>()`) for a typed `Form<Values>`. Use\n * {@link createFormContext} for multiple forms in one subtree.\n * @throws when no `<FormProvider>` is mounted above the call site.\n */\nexport function useFormContext<T extends Record<string, any> = any>(): Form<T> {\n const form = useContext(FormContext);\n if (!form) throw new Error('no form provided');\n return form;\n}\n\n/** Options the bundle's pre-bound hooks take: the underlying hook's\n * options minus `form` — this factory's own context supplies it. For\n * `useField`, `{name: TPath}` keeps `name` a direct TPath inference site. */\ntype BoundFieldOptions<\n TValues extends Record<string, any>,\n TPath extends AnyPath<TValues>\n> = {name: TPath} & Omit<UseFieldOptions<TValues, TPath>, 'form'>;\n\ntype BoundFieldArrayOptions<\n TValues extends Record<string, any>,\n K extends string = 'id'\n> = {\n name: FieldPath<TValues> | Name;\n keyName?: K;\n rules?: FieldRules;\n shouldUnregister?: boolean;\n};\n\ntype BoundFieldArrayItemOptions<TValues extends Record<string, any>> = {\n name: FieldPath<TValues> | Name;\n id: string;\n};\n\n/** The bundle {@link createFormContext} returns: a private React context\n * plus the hooks pre-bound to it, all typed against `TValues`. */\nexport type FormContextBundle<TValues extends Record<string, any> = any> = {\n /** The raw React context, for `<Form context={...}>`: the component\n * keeps its submit machinery while providing into this instance's\n * private context. */\n context: Context<Form<TValues> | null>;\n FormProvider: (props: {\n form: Form<TValues>;\n children: ReactNode;\n }) => ReactNode;\n useFormContext: () => Form<TValues>;\n useField: <TPath extends AnyPath<TValues> = AnyPath<TValues>>(\n options: BoundFieldOptions<TValues, TPath>\n ) => UseFieldResult<TValues, TPath>;\n useFieldArray: <TItem = any, K extends string = 'id'>(\n options: BoundFieldArrayOptions<TValues, K>\n ) => UseFieldArrayResult<TItem, K>;\n useFieldArrayItem: <TValue = any>(\n options: BoundFieldArrayItemOptions<TValues>\n ) => UseFieldArrayItemResult<TValue>;\n};\n\n/**\n * Create an isolated bundle of form-context bindings: its own React context\n * plus `useField`/`useFieldArray`/`useFieldArrayItem`/`useFormContext`\n * hooks resolving from it. One factory per app area scopes a separate\n * form and fixes the value shape (`Ctx.useField` gets typed `name`/`value`);\n * `Ctx.context` lets `<Form context={Ctx.context}>` provide into it.\n */\nexport function createFormContext<\n TValues extends Record<string, any> = any\n>(): FormContextBundle<TValues> {\n const Context = createContext<Form<TValues> | null>(null);\n\n // A `form`-prop wrapper, not a raw Context.Provider: callers shouldn't\n // have to know the `value` prop shape.\n function FormProvider({\n form,\n children\n }: {\n form: Form<TValues>;\n children: ReactNode;\n }): ReactNode {\n return createElement(Context.Provider, {value: form}, children);\n }\n\n function useFormContext(): Form<TValues> {\n const form = useContext(Context);\n if (!form) throw new Error('no form provided');\n return form;\n }\n\n function useField<TPath extends AnyPath<TValues> = AnyPath<TValues>>(\n options: BoundFieldOptions<TValues, TPath>\n ): UseFieldResult<TValues, TPath> {\n return useFieldCore(options as UseFieldOptions<TValues, TPath>, Context);\n }\n\n function useFieldArray<TItem = any, K extends string = 'id'>(\n options: BoundFieldArrayOptions<TValues, K>\n ): UseFieldArrayResult<TItem, K> {\n return useFieldArrayCore<TItem, K>(\n options as UseFieldArrayOptions<K>,\n Context\n );\n }\n\n function useFieldArrayItem<TValue = any>(\n options: BoundFieldArrayItemOptions<TValues>\n ): UseFieldArrayItemResult<TValue> {\n return useFieldArrayItemCore(options as {name: Name; id: string}, Context);\n }\n\n // The raw context, for `<Form context={...}>`: the component keeps its\n // submit machinery while providing into this instance's context.\n return {\n context: Context,\n FormProvider,\n useFormContext,\n useField,\n useFieldArray,\n useFieldArrayItem\n };\n}\n\nexport const CheckboxGroupContext: Context<any> = createContext<any>(null);\n\nexport const CheckboxGroupProvider: Provider<any> =\n CheckboxGroupContext.Provider;\n\nexport function useCheckboxGroupContext(): any {\n const group = useContext(CheckboxGroupContext);\n if (!group) throw new Error('no group provided');\n return group;\n}\n","/** Server-side validation entry — `react-f0rm/server`. A React-free entry\n * so Server Actions/RSC can validate a payload without pulling hooks into\n * the graph. {@link validateValues} is a plain function over values (the\n * `trigger` contract), composing into any framework handler; not\n * re-exported from the main entry so client bundles stay at baseline. */\nimport createForm, {getErrors, getValues, trigger} from './form';\nimport type {FieldErrorEntry, Options, ValidationOutcome} from './form';\n\n// Re-export the brand symbol here (not the root) so schema adapters can\n// build a ValidationOutcome without dragging the React graph in.\nexport {VALIDATION_OUTCOME} from './form';\nexport type {ValidationOutcome};\n\n// Framework-free array ops (useFieldArray's headless counterparts) for\n// server-side payload manipulation.\nexport {\n appendValue,\n prependValue,\n insertValue,\n removeValue,\n moveValue,\n swapValues,\n replaceValues,\n updateValue\n} from './form';\n\n/** The outcome of {@link validateValues}: `valid`, the (schema-coerced)\n * values, and the round's flat error entries. */\nexport type ValidateValuesResult<T extends Record<string, any> = any> = {\n /** Whether the round landed no errors. An invalid payload is data, not\n * a rejection — both branches are interesting server-side. */\n valid: boolean;\n /** The values after the round: parsed output when the validator\n * returned a branded outcome, the input otherwise. */\n values: T;\n /** Every error flattened to {path, type, message}; feed to\n * `setServerErrors` to land it back on the client form. */\n errors: FieldErrorEntry[];\n};\n\n/** Append one value under `key`: arrays/FileLists flatten per item, Files\n * keep their name, Dates become ISO strings, other objects JSON.stringify. */\nfunction appendFormDataValue(fd: FormData, key: string, value: any): void {\n if (value == null) return;\n if (Array.isArray(value)) {\n for (const item of value) appendFormDataValue(fd, key, item);\n return;\n }\n if (typeof FileList !== 'undefined' && value instanceof FileList) {\n for (let i = 0; i < value.length; i++) fd.append(key, value.item(i)!);\n return;\n }\n if (typeof File !== 'undefined' && value instanceof File) {\n fd.append(key, value, value.name);\n return;\n }\n if (typeof Blob !== 'undefined' && value instanceof Blob) {\n fd.append(key, value);\n return;\n }\n if (value instanceof Date) {\n fd.append(key, value.toISOString());\n return;\n }\n fd.append(\n key,\n typeof value === 'object' ? JSON.stringify(value) : String(value)\n );\n}\n\n/** Convert values into FormData (Server Actions/multipart shape). Arrays\n * become multiple entries per key; Files keep names; Dates → ISO; objects\n * JSON.stringify; null/undefined skipped. */\nexport function formDataFromValues(values: Record<string, any>): FormData {\n const fd = new FormData();\n for (const key of Object.keys(values)) {\n appendFormDataValue(fd, key, values[key]);\n }\n return fd;\n}\n\n/** Parse one FormData string: JSON-looking values (`{…}`, `[…]`) parse\n * back; everything else stays literal (quoted text is never parsed). */\nfunction parseFormDataString(raw: string): unknown {\n const value = raw.trim();\n if (value.startsWith('{') || value.startsWith('[')) {\n try {\n return JSON.parse(value);\n } catch {\n // Typed text that merely looks like JSON — keep the literal input.\n return raw;\n }\n }\n return raw;\n}\n\nfunction readFormDataEntry(entry: FormDataEntryValue): unknown {\n if (typeof File !== 'undefined' && entry instanceof File) return entry;\n return parseFormDataString(entry as string);\n}\n\n/** Convert FormData back into a values object — the inverse of\n * {@link formDataFromValues}. Multiple entries under a key collect into\n * an array, JSON-looking strings parse back, Files pass through, and\n * missing keys are omitted. */\nexport function valuesFromFormData(formData: FormData): Record<string, any> {\n const values: Record<string, any> = {};\n // Iterate unique keys (FormData.keys() repeats per entry); getAll\n // collects every entry under one key in insertion order.\n for (const key of new Set(formData.keys())) {\n const entries = formData.getAll(key);\n values[key] =\n entries.length === 1\n ? readFormDataEntry(entries[0])\n : entries.map(readFormDataEntry);\n }\n return values;\n}\n\n/** Validate a payload server-side — no form instance, no React. Spins up\n * a throwaway form from `options` (initialValues forced to `values`),\n * runs one whole-form `trigger`, and reads the settled round back (a\n * single await drains async validators and debounce windows). Field\n * validators can't participate (nothing is mounted); pass a form-level\n * schema validator. A branded outcome's parsed values become the baseline\n * `getValues` layers over. Safe in Node, Server Actions and RSC. */\nexport async function validateValues<T extends Record<string, any> = any>(\n values: T,\n options?: Options<T>\n): Promise<ValidateValuesResult<T>> {\n const form = createForm({...options, initialValues: values});\n const valid = await trigger(form);\n return {valid, values: getValues(form), errors: getErrors(form)};\n}\n","import * as React from 'react';\nimport useField from '../hooks/field';\nimport type {UseFieldOptions as HookFieldOptions} from '../hooks/field';\nimport {errorIdFromKey} from '../errorId';\nexport {fieldErrorId} from '../errorId';\nimport {FormContext} from '../context';\nimport {rulesToConstraintAttrs} from '../rules';\nimport type {FieldRules} from '../rules';\nimport type {StandardSchemaV1} from '../standardSchema';\nimport {hasStandardProps, schemaToFieldValidator} from '../standardSchema';\nimport type {AnyPath} from '../types';\nimport {eventToValueOrDefault} from '../util';\n\n/** Dev-only flag, replaced at build time (rollup); defined in vitest.config.ts. */\ndeclare const __DEV__: boolean;\n\n/** Props shared by Field/Checkbox/Select: the hook options minus the\n * required `name` (the components type it optional) and `validateDeps`\n * (the components do not forward it), plus the index signature that lets\n * DOM props flow through. */\ntype UseFieldOptions<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = Omit<HookFieldOptions<TValues, TPath>, 'name' | 'validateDeps'> & {\n name?: TPath;\n [key: string]: any;\n};\n\ntype FieldProps<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = UseFieldOptions<TValues, TPath> & {\n as?: React.ComponentType<any>;\n asProps?: Record<string, any>;\n valueToProps?: (value: any) => Record<string, any>;\n /** Error renderer: renders `<span id role=\"alert\">` beside the input;\n * `aria-describedby` always points at that id (`fieldErrorId`). */\n renderError?: (error: string, id: string) => React.ReactNode;\n};\n\nfunction setRef<T>(ref: React.Ref<T> | undefined, value: T | null) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref) {\n (ref as React.MutableRefObject<T | null>).current = value;\n }\n}\n\n/** Shared aria wiring: `aria-invalid` on error, `aria-describedby` pointed\n * at the error-message id (`fieldErrorId`); user ids survive ahead. */\nfunction ariaProps(\n error: string | undefined,\n fieldKey: string,\n props: Record<string, any>\n) {\n return {\n 'aria-invalid': error ? true : props['aria-invalid'],\n 'aria-describedby': error\n ? [props['aria-describedby'], errorIdFromKey(fieldKey)]\n .filter(Boolean)\n .join(' ')\n : props['aria-describedby']\n };\n}\n\n/** Declarative rules → native constraint attributes for browser/AT hints\n * (`required`, `minLength`, `pattern`, …). `undefined` when no rules. */\nfunction toConstraintAttrs(\n rules: FieldRules | undefined\n): Record<string, any> | undefined {\n return rules ? rulesToConstraintAttrs(rules) : undefined;\n}\n\n/** Callable shape of {@link Field}; a named interface because the inline\n * `as <TValues,...>() => ...` form trips no-use-before-define. */\ntype FieldComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n >(\n props: FieldProps<TValues, TPath> & React.RefAttributes<HTMLInputElement>\n ): React.ReactElement | null;\n};\n\nexport const Field = React.forwardRef<HTMLInputElement, FieldProps>(\n (\n {\n validate,\n eventToValue,\n initialValue,\n name,\n asProps,\n renderError,\n as,\n valueToProps,\n form: formProp,\n shouldUnregister,\n rules,\n validateDebounce,\n validateOnMount,\n valueAsNumber,\n valueAsDate,\n asyncAlways,\n disabled,\n delayError,\n mode,\n uncontrolled,\n ...props\n },\n ref\n ) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const [nativeInvalidCount, setNativeInvalidCount] = React.useState(0);\n // Raw useContext (not useFormContext) so a form-prop-only call site\n // with no provider still works.\n const contextForm = React.useContext(FormContext);\n const resolvedForm = formProp ?? contextForm;\n const isFile = props.type === 'file';\n // The native gate calls validate as a function, so wrap a Standard Schema here.\n const validateWrapped =\n validate && hasStandardProps(validate)\n ? schemaToFieldValidator(validate as StandardSchemaV1<any, any>)\n : (validate as ((value: any, meta: any) => any) | undefined);\n // Declared options go to the hook; `as`/`valueToProps`/DOM props stay\n // in `props` (useField no longer echoes unknown options).\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled,\n focusRef,\n validating\n } = useField({\n name: name!,\n form: formProp,\n initialValue,\n shouldUnregister,\n rules,\n validateDebounce,\n validateOnMount,\n delayError,\n disabled,\n asyncAlways,\n mode,\n // File inputs can't be value-controlled — force the uncontrolled path.\n uncontrolled: uncontrolled || isFile,\n validate: (...params: [any, any]) => {\n // Per-kick native gate: a control failing its own constraints skips\n // the custom validator (RHF first-error); shouldUseNativeValidation:\n // false disables it.\n if (resolvedForm?.shouldUseNativeValidation !== false) {\n const el = innerRef.current;\n if (el && typeof el.checkValidity === 'function') {\n el.setCustomValidity('');\n if (el.checkValidity() === false) {\n setNativeInvalidCount(count => count + 1);\n return undefined;\n }\n }\n }\n if (validateWrapped) return validateWrapped(...params);\n }\n });\n // Merged ref: innerRef (native gate), focusRef (setFocus/shouldFocusError),\n // and the forwarded ref.\n const mergedRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n focusRef(node);\n setRef(ref, node);\n },\n [ref, focusRef]\n );\n\n React.useEffect(() => {\n const el = innerRef.current;\n if (!el || typeof el.setCustomValidity !== 'function') return;\n if (typeof error === 'string') {\n el.setCustomValidity(error);\n el.reportValidity();\n } else {\n el.setCustomValidity('');\n }\n }, [error]);\n\n React.useEffect(() => {\n if (nativeInvalidCount > 0) innerRef.current?.reportValidity();\n }, [nativeInvalidCount]);\n\n if (__DEV__ && valueAsNumber && valueAsDate) {\n // eslint-disable-next-line no-console -- dev-only diagnostics\n console.warn(\n 'react-f0rm: valueAsNumber and valueAsDate are mutually exclusive — ' +\n 'valueAsNumber wins. Use eventToValue for anything else.'\n );\n }\n const Component = as || 'input';\n const toValue = eventToValueOrDefault(eventToValue, {\n valueAsNumber,\n valueAsDate\n });\n\n // File inputs never receive a value/defaultValue prop (they cannot\n // be value-controlled); uncontrolled renders defaultValue, controlled\n // renders value.\n const valueProps = valueToProps\n ? valueToProps(value)\n : isFile\n ? {}\n : uncontrolled\n ? {defaultValue: value}\n : {value};\n\n // fieldKey is the JSON-stringified path key, e.g. '[\"a\",\"0\"]'.\n const errorId = errorIdFromKey(fieldKey);\n // Spread constraint attrs before `props` so a user-passed required/pattern\n // wins; the store still owns error messages (renderError/aria-invalid).\n const constraintAttrs = toConstraintAttrs(rules);\n\n return (\n <>\n <Component\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n {...asProps}\n {...valueProps}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n aria-busy={validating || undefined}\n onChange={(e: any) => onChange(toValue(e))}\n ref={mergedRef}\n />\n {error && renderError ? (\n <span id={errorId} role=\"alert\">\n {renderError(error, errorId)}\n </span>\n ) : null}\n </>\n );\n }\n) as FieldComponent;\n\n/** Callable shape of {@link Checkbox}: same form-typed `validate` contract\n * as {@link FieldComponent}. */\ntype CheckboxComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n >(\n props: UseFieldOptions<TValues, TPath> &\n React.RefAttributes<HTMLInputElement>\n ): React.ReactElement | null;\n};\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, UseFieldOptions>(\n (\n {\n name,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n disabled,\n delayError,\n mode,\n ...props\n },\n ref\n ) => {\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled,\n validating\n } = useField({\n name: name!,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n delayError,\n disabled,\n mode\n });\n const constraintAttrs = toConstraintAttrs(rules);\n return (\n <input\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n type=\"checkbox\"\n checked={!!value}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n aria-busy={validating || undefined}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n onChange(e.target.checked)\n }\n ref={ref}\n />\n );\n }\n) as CheckboxComponent;\n\ntype SelectProps<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = UseFieldOptions<TValues, TPath> & {\n multiple?: boolean;\n children?: React.ReactNode;\n};\n\n/** Select value coercion: single → string, multiple → string[]. */\nfunction toSelectValue(\n multiple: boolean | undefined,\n value: any\n): string | string[] {\n if (multiple) return Array.isArray(value) ? value : [];\n return value ?? '';\n}\n\n/** Callable shape of {@link Select}: same form-typed `validate` contract\n * as {@link FieldComponent}. */\ntype SelectComponent = {\n <\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n >(\n props: SelectProps<TValues, TPath> & React.RefAttributes<HTMLSelectElement>\n ): React.ReactElement | null;\n};\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(\n (\n {\n name,\n multiple,\n children,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n disabled,\n delayError,\n mode,\n ...props\n },\n ref\n ) => {\n const {\n value,\n onChange,\n onBlur,\n error,\n name: fieldKey,\n disabled: isDisabled,\n validating\n } = useField({\n name: name!,\n form,\n initialValue,\n shouldUnregister,\n validate,\n rules,\n validateDebounce,\n validateOnMount,\n asyncAlways,\n delayError,\n disabled,\n mode\n });\n const constraintAttrs = toConstraintAttrs(rules);\n return (\n <select\n {...constraintAttrs}\n {...props}\n name={fieldKey}\n onBlur={onBlur}\n multiple={multiple}\n value={toSelectValue(multiple, value)}\n {...ariaProps(error, fieldKey, props)}\n disabled={isDisabled}\n aria-busy={validating || undefined}\n onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>\n onChange(\n multiple\n ? Array.from(e.target.selectedOptions, option => option.value)\n : e.target.value\n )\n }\n ref={ref}\n >\n {children}\n </select>\n );\n }\n) as SelectComponent;\n","import * as React from 'react';\nimport {on} from '../emitter';\nimport {FormContext} from '../context';\nimport {useErrors, useWatchCore} from '../hooks/form';\nimport {FORM_ERROR, dottedKeyToFieldPath, hasErrors, setFocus} from '../form';\nimport type {FieldError, Form} from '../form';\nimport {fieldErrorId} from '../errorId';\n\n/** Props for <ErrorSummary>: same form/context resolution <Form> itself\n * uses — an explicit `form` wins, otherwise the (optionally isolated)\n * context form. */\ntype ErrorSummaryProps<T extends Record<string, any> = any> = {\n form?: Form<T>;\n context?: React.Context<Form<any> | null>;\n heading?: string;\n};\n\n/** A GOV.UK-style error summary: one `role='alert'` box listing every\n * field error, each linking to the field's error element id. Clicking a\n * link focuses the field through the same `focusError` channel a failed\n * submit uses; after a failed submit the box itself takes focus (pair it\n * with `shouldFocusError={false}`, whose field focus lands later and\n * would otherwise win). {@link FORM_ERROR} entries have no field to focus\n * and render as plain list items. */\nexport default function ErrorSummary<T extends Record<string, any> = any>({\n form: formProp,\n context,\n heading\n}: ErrorSummaryProps<T>): React.ReactElement | null {\n const contextForm = React.useContext(context ?? FormContext);\n const form = formProp ?? contextForm;\n if (!form) throw new Error('no form provided');\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n const wasSubmittingRef = React.useRef(false);\n const headingId = React.useId();\n const errors = useErrors(form);\n // Focus the box on the failed-submit transition (isSubmitting\n // true→false with errors) — the same dual-event subscription useCanSubmit\n // folds its boolean from. The snapshot is inert (a constant never\n // triggers a re-render); the transition detection is a DOM focus in the\n // event callback, never setState.\n const subscribeFactory = React.useCallback(\n (invalidate: () => void) => {\n const check = () => {\n const wasSubmitting = wasSubmittingRef.current;\n wasSubmittingRef.current = form.isSubmitting;\n if (wasSubmitting && !form.isSubmitting && hasErrors(form)) {\n containerRef.current?.focus();\n }\n invalidate();\n };\n const offErrors = on(form.emitter, 'errors', check);\n const offSubmitting = on(form.emitter, 'submitting', check);\n return () => {\n offErrors();\n offSubmitting();\n };\n },\n [form]\n );\n useWatchCore(subscribeFactory, () => null);\n\n const entries = Object.entries(errors) as [string, FieldError[]][];\n if (entries.length === 0) return null;\n return (\n <div\n role=\"alert\"\n tabIndex={-1}\n ref={containerRef}\n aria-labelledby={headingId}\n >\n <h2 id={headingId}>{heading ?? 'There is a problem'}</h2>\n <ul>\n {entries.map(([dottedKey, list]) => {\n const message = list[0]?.message;\n // The form-level error has no field element to focus — no link.\n if (dottedKey === FORM_ERROR) {\n return (\n <li key={dottedKey}>\n <p>{message}</p>\n </li>\n );\n }\n const path = dottedKeyToFieldPath(dottedKey);\n return (\n <li key={dottedKey}>\n <a\n href={`#${fieldErrorId(path)}`}\n onClick={(e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n setFocus(form, path);\n }}\n >\n {message}\n </a>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n","import * as React from 'react';\nimport {handleSubmit, setDisabled} from '../form';\n// 别名规避 rollup-plugin-dts 对「type import 与本地 default export 同名」\n// 的 Identifier already declared 报错。\nimport type {ActionErrorResult} from '../core/submit';\nimport type {Form as FormApi} from '../form';\nimport {formDataFromValues} from '../server';\nimport {FormContext} from '../context';\nimport useForm from '../hooks/form';\n\n/** Props for <Form>. Native constraint validation gates submission: the\n * form always sets noValidate, but checkValidity() runs before custom\n * validators and a failure stops submission (onInvalidSubmit fires).\n * `shouldUseNativeValidation={false}` skips the gate (targets without\n * checkValidity are always exempt). The flow itself lives in the headless\n * `handleSubmit`; this is a thin wrapper binding it to the <form>. */\ntype FormProps<T extends Record<string, any> = any> = Omit<\n React.FormHTMLAttributes<HTMLFormElement>,\n 'onSubmit'\n> & {\n form?: FormApi<T>;\n /** Isolated context from `createFormContext()`: its bound hooks see this\n * form, the module-level ones do not. Defaults to FormContext. */\n context?: React.Context<FormApi<any> | null>;\n /** Values baseline — sync object, Promise, or thunk; async sources gate on `isLoading`. */\n initialValues?: T | Promise<T> | (() => T | Promise<T>);\n /** Default unmount behavior: `true` tombstones unmounted fields, `false` keeps values. */\n shouldUnregister?: boolean;\n /** Validate on mount: each validator kicks once; a field's own prop overrides. */\n validateOnMount?: boolean;\n /** Disable every bound field (fields OR with their own option); undefined leaves the flag untouched. */\n disabled?: boolean;\n /** Form-level default for `asyncAlways`; a field's own prop overrides. */\n asyncAlways?: boolean;\n /** Controlled external values: a new reference syncs via setInitialValues\n * (draft discarded, touched/errors kept); same reference never clobbers. */\n values?: T;\n /** May be async; `isSubmitting` covers the flight. */\n onSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;\n /** May be async, same as onSubmit. */\n onValidSubmit?: (values: T, e: React.FormEvent) => void | Promise<void>;\n /** Server Action target: after validation, schema-coerced values become\n * FormData and dispatch here. Returning {@link ActionErrorResult} lands\n * `type: 'server'` per-field errors (unsuccessful submit); a URL string\n * renders the native `action` for no-JS progressive enhancement. */\n action?:\n string | ((formData: FormData) => void | Promise<void | ActionErrorResult>);\n /** Called when validation fails; errors are {path, type, message} entries\n * (type: 'custom' | 'native'). */\n onInvalidSubmit?: (\n errors: {path: string; type: string; message: string}[],\n values: T\n ) => void;\n /** Focus the first errored field (or first ':invalid' control) after a failed submit. Default true. */\n shouldFocusError?: boolean;\n /** Whether native constraint validation gates submission (pass false for\n * custom-validator-only forms). Seeds the created form's flag and this\n * form's submit wiring. */\n shouldUseNativeValidation?: boolean;\n};\n\nexport default function Form<T extends Record<string, any> = any>({\n form: f1,\n context,\n initialValues,\n values,\n shouldUnregister,\n validateOnMount,\n disabled,\n asyncAlways,\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n action,\n shouldFocusError,\n shouldUseNativeValidation,\n ...props\n}: FormProps<T>): React.JSX.Element {\n const f2 = useForm<T>({\n initialValues,\n values,\n shouldUnregister,\n validateOnMount,\n disabled,\n asyncAlways,\n shouldUseNativeValidation\n });\n const form = f1 || f2;\n\n // The form outlives prop changes; a changing `disabled` re-applies via\n // setDisabled. undefined = not controlled here.\n React.useEffect(() => {\n if (disabled !== undefined) setDisabled(form, disabled);\n }, [form, disabled]);\n\n const submit = handleSubmit(form, {\n onSubmit,\n onValidSubmit,\n onInvalidSubmit,\n shouldFocusError,\n shouldUseNativeValidation,\n onAction:\n typeof action === 'function'\n ? values => action(formDataFromValues(values))\n : undefined\n });\n\n // Route the form into the isolated or module-level context.\n const {Provider} = context ?? FormContext;\n\n // String action → native attribute for no-JS progressive enhancement.\n const nativeAction = typeof action === 'string' ? action : undefined;\n\n return (\n <Provider value={form}>\n <form {...props} action={nativeAction} noValidate onSubmit={submit} />\n </Provider>\n );\n}\n","import * as React from 'react';\nimport useField from '../hooks/field';\nimport type {UseFieldOptions, UseFieldResult} from '../hooks/field';\nimport type {AnyPath} from '../types';\n\n/** Every {@link UseFieldOptions} option plus a render-prop `children`\n * receiving the bound field result. */\nexport type FormFieldProps<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n> = UseFieldOptions<TValues, TPath> & {\n children: (field: UseFieldResult<TValues, TPath>) => React.ReactNode;\n};\n\n/** Headless field via a render prop — the non-hook {@link useField} for\n * class components/callback consumers. The child receives the full\n * {@link UseFieldResult}; resolves its form from FormContext or the\n * `form` option. */\nexport default function FormField<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>\n>({children, ...options}: FormFieldProps<TValues, TPath>): React.ReactNode {\n const field = useField<TValues, TPath>(options);\n return children(field);\n}\n","import {useCallback, useEffect, useRef} from 'react';\nimport {getValueByPath, userChangeByPath} from '../form';\nimport type {Form} from '../form';\nimport type {AnyPath, PathValueOf} from '../types';\nimport {isPromise} from '../util';\nimport {onPathEvent} from '../subscribe';\nimport {useWatchCore} from './form';\nimport usePath, {pathFromKey} from './path';\nimport useStage from './stage';\n\nexport type UseTransformOptions<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>,\n TDisplay = PathValueOf<TValues, TPath>\n> = {\n /** Map the stored (raw) value to the display value (read direction);\n * omitted = identity. */\n toDisplay?: (raw: PathValueOf<TValues, TPath>) => TDisplay;\n /** Map a display value back to the raw value (write direction);\n * omitted = identity. May return a Promise — only the latest write\n * commits (stale resolutions drop). The round trip should be an\n * identity; non-invertible store values must be handled by\n * `toDisplay`, which runs first. */\n fromDisplay?: (\n display: TDisplay\n ) => PathValueOf<TValues, TPath> | Promise<PathValueOf<TValues, TPath>>;\n /** Debounce the display→raw commit; only the last write in the window\n * commits (TanStack `asyncDebounceMs`). `0`/omitted commits\n * immediately; validation fires at commit time through the\n * user-change pipeline. */\n asyncDebounceMs?: number;\n};\n\n/**\n * Bind a control whose display value differs from the stored raw value\n * (TanStack `useTransform`): `toDisplay` maps store→display,\n * `fromDisplay` maps display→store. The store always carries the raw\n * value. `value` subscribes to 'change' at leaf scope; `onChange` writes\n * through the user-change channel, so mode-gated validation fires as if\n * the user typed. Transform functions are read fresh each render.\n */\nexport default function useTransform<\n TValues extends Record<string, any> = any,\n TPath extends AnyPath<TValues> = AnyPath<TValues>,\n TDisplay = PathValueOf<TValues, TPath>\n>(\n form: Form<TValues>,\n name: TPath,\n options: UseTransformOptions<TValues, TPath, TDisplay> = {}\n): {value: TDisplay; onChange: (display: TDisplay) => void} {\n const path = usePath(name);\n const {toDisplay, fromDisplay, asyncDebounceMs} = options;\n\n const subscribeFactory = useCallback(\n (invalidate: () => void) =>\n onPathEvent(\n form.emitter,\n 'change',\n pathFromKey(path.key),\n 'leaf',\n invalidate\n ),\n [form.emitter, path.key]\n );\n const raw = useWatchCore(subscribeFactory, () => getValueByPath(form, path));\n const value = toDisplay ? toDisplay(raw) : (raw as TDisplay);\n\n // Async commit machinery: `asyncDebounceMs` debounces the display→raw\n // write (a newer write supersedes the pending one), and a sequence\n // token drops stale resolutions — only the latest write commits. Live\n // refs keep the latest transform/debounce visible to a stable onChange\n // without re-subscribing (the same pattern useValidate uses).\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const seqRef = useRef(0);\n const fromDisplayRef = useStage(fromDisplay);\n const debounceRef = useStage(asyncDebounceMs ?? 0);\n useEffect(\n () => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n },\n []\n );\n\n const onChange = useCallback(\n (display: TDisplay) => {\n const run = () => {\n const seq = ++seqRef.current;\n const transform = fromDisplayRef.current;\n const commit = (next: PathValueOf<TValues, TPath>) =>\n userChangeByPath(form, path, next);\n if (!transform) {\n commit(display as unknown as PathValueOf<TValues, TPath>);\n return;\n }\n const result = transform(display);\n if (isPromise(result)) {\n result.then(next => {\n // Stale resolution: a newer write took over — drop it. (An\n // in-flight commit after unmount still lands; losing a\n // resolved write would be worse.)\n if (seqRef.current === seq) commit(next);\n });\n } else if (seqRef.current === seq) {\n commit(result);\n }\n };\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = null;\n if (debounceRef.current > 0) {\n timerRef.current = setTimeout(run, debounceRef.current);\n } else {\n run();\n }\n },\n [form, path, fromDisplayRef, debounceRef]\n );\n\n return {value, onChange};\n}\n"],"names":["pathCache","Map","normalizePath","path","Array","isArray","cached","get","value","result","identifier","flushIdentifier","isIndex","dotted","map","String","join","bracket","reduce","acc","seg","TypeError","push","i","length","char","quote","close","indexOf","slice","content","Number","parsePath","size","oldest","keys","next","done","delete","set","segment","test","values","current","p","unset","prop","props","arr","copy","arraySlot","container","copyForProp","ensureOwned","owned","has","add","index","setOwned","root","parent","parentProp","isPromise","then","eventToValueOrDefault","eventToValue","options","e","target","type","files","checked","valueAsNumber","valueAsDate","extractEventValue","isEqual","a","b","Object","is","Date","getTime","proto","getPrototypeOf","prototype","keysA","keysB","key","waitUntil","emitter","event","isResolve","isReject","Promise","resolve","reject","off","on","create","name","JSON","stringify","segmentsFromKey","parse","getOrCreate","form","valuesCaches","WeakMap","bumpVersion","cache","version","bumpValuesVersion","errorsCaches","bumpErrorsVersion","dirtyBaselines","getDirtyBaseline","segments","baselines","initialValues","setDirtyBaseline","pruneDirtyBaselines","stem","baselineKey","startsWith","clearDirtyBaselines","clear","dirtyFieldsCaches","bumpDirtyVersion","isSegmentsPath","some","part","isFieldError","message","FORM_ERROR","VALIDATION_OUTCOME","getErrorByPath","errors","NO_ERRORS","getFieldErrorsByPath","getErrors","entries","list","computeErrorsViews","tree","node","slot","getErrorsRecord","getErrorsTree","dottedKeyToFieldPath","split","numeric","getFirstError","setError","error","setErrorByPath","createPath","forEach","item","normalizeErrors","emit","shouldFocus","clearErrors","paths","one","setServerErrors","keepExisting","clearServerErrors","affected","from","filter","kept","hasErrors","hasStandardProps","schema","validate","toFieldError","issue","schemaToFieldValidator","async","issues","toPathSegments","assignAtPath","isBranch","leaf","pruneEmpty","pruned","isFieldDirtyByPath","live","isDirty","computeDirtyFields","dirtyFields","fn","forEachDirtyField","getDirtyFields","aKeys","every","sameDirtyKeys","setTouchedByPath","touched","hasTouchedByPath","getTouchedFields","getValues","computeValues","parsedValues","deleted","Set","merged","getValueByPath","ancestorKey","setValueByPath","pruneDescendantKeys","reviveBranch","shouldDirty","shouldTouch","shouldValidate","validators","seedValueByPath","emitChangeByPath","removeFieldByPath","validating","keepValue","keepDirty","hasLiveBranch","keepTouched","keepError","k","tombstone","setInitialValues","collectValueLeaves","out","collectKeptValues","keepValues","keepDirtyValues","reset","keptValues","keepDefaultValues","keepErrors","keepIsSubmitting","isSubmitting","keepSubmitCount","submitCount","keepIsSubmitted","isSubmitted","keepIsSubmitSuccessful","isSubmitSuccessful","unsetValidatingByPath","setValidatingByPath","asErrorList","output","registerValidatorByPath","registration","timer","controller","marked","lock","errorSource","mark","unmark","land","asyncAlways","gate","sync","collectSyncErrors","own","cancel","clearTimeout","abort","runValidator","AbortController","round","signal","catch","finally","gateOwnsKick","runSync","run","debounce","setTimeout","touchKeys","setFormErrors","footprint","landLeafError","stored","recordFootprint","applyValidateResult","validateDeps","validateMode","formErrorFootprints","getFormErrorFootprint","written","clearFormValidateErrors","outcome","setParsedValues","FORM_VALIDATING_KEY","fieldsSettled","SETTLED","formValidateStates","runFormValidate","validateDebounce","state","waiters","getFormValidateState","runFormValidateRound","settleFormValidate","waiter","shouldKick","mode","cadence","hasError","reValidateMode","revalidateFormOnChange","hasFormValidateErrors","fieldValidateDeps","registerFieldValidateDeps","depKeys","deps","depKey","dependents","unregisterFieldValidateDeps","revalidateDependentsOnChange","dependent","validationError","Error","ensureValidate","validator","fieldModes","changeValueByPath","userChangeByPath","registerFieldMode","modes","displaced","token","unregisterFieldMode","entry","firstMountedDescendantKey","ancestor","prefix","fireFormValidate","kickFieldValidator","runUserChangeGate","userBlur","removeFieldForUnmount","snapshot","present","restoreRemovedField","hasRuleConstraints","rules","required","min","max","minLength","maxLength","pattern","defaultMessage","bound","resolveMessage","replace","numericMetric","n","isNaN","sizedMetric","BOUND_CHECKS","metric","rulesToValidator","formMessages","meta","messages","measure","fails","fns","registerField","shouldUnregister","toValue","el","modeToken","disposeValidator","offFocus","offBulkSync","attach","rest","requiredGate","focus","shouldSelect","select","changed","asString","syncDom","onChange","onBlur","ref","readArray","appendValueByPath","prependValueByPath","insertValueByPath","removeValueByPath","indices","drop","dropped","sort","_","moveValueByPath","to","splice","swapValuesByPath","replaceValuesByPath","updateValueByPath","setIsSubmitting","incrementSubmitCount","setSubmitSuccessful","setDisabled","disabled","nameToPath","handleSubmit","onSubmit","onValidSubmit","onInvalidSubmit","onAction","shouldFocusError","shouldUseNativeValidation","preventDefault","formEl","currentTarget","checkValidity","reportValidity","querySelector","invalid","elements","validationMessage","getNativeErrors","firstKey","submitted","setFocus","createEmitter","setMaxListeners","initialSource","source","validateOption","wrappedValidate","validateOnMount","dep","isLoading","status","register","registerOptions","resolved","seedInitialValues","errorIdFromKey","fieldErrorId","fieldDisabledRegistry","isDescendant","onPathEvent","scope","cb","onKeyEvent","pathFromKey","usePath","useMemo","seedIfChanged","seeded","resetOptions","useForm","useState","created","createForm","seededRef","useRef","useEffect","controlledRef","useWatchCore","subscribeFactory","getter","cacheRef","hasValue","getterRef","isEqualRef","getSnapshot","useCallback","subscribe","notify","compare","useSyncExternalStore","useWatch","formOrEmitter","invalidate","useValueByPath","exact","defaultValue","useKeyWatch","useTouchedByPath","bind","useErrorByPath","useFieldErrorsByPath","useIsFieldDirtyByPath","FORM_STATE_EVENTS","subscribeFormStateEvents","offs","isSameFormState","sameTouched","touchedFields","isTouched","isValid","isValidating","useErrors","useStage","useStageFn","params","useUnmountFieldRemoval","removalSnapshotRef","teardown","restore","removedRef","teardownRef","restoreRef","teardownOnce","restoreOnce","useUnmountRestore","schemaAsValidator","useValidate","formProp","contextForm","useContext","FormContext","validateRef","debounceRef","syncRef","asyncAlwaysRef","validateOnMountRef","spath","dispose","disposed","kick","uncontrolledSyncRegistry","NO_DELAYED_ERRORS","useDelayedErrors","delay","pendingRef","prevRef","timerRef","clearTimer","was","useFieldCore","f1","initialValue","delayError","uncontrolled","modeOption","Context","ruleValidator","ruleErrors","merge","other","combineRulesAndValidate","errorObject","snapshotRef","useFieldValue","mergedDisabled","registry","hasDisabledAncestor","disabledTokenRef","registerFieldDisabled","unregisterFieldDisabled","v","depsKey","validateDepsRef","elementRef","focusRef","existing","cells","read","getUncontrolledSyncEntry","extract","inputProps","useField","idCounters","generateId","arrayIdsRegistry","registerArrayIds","ids","scheduleArrayRowFocus","bumpReducer","count","useFieldArrayCore","keyName","idsRef","computeFields","pop","id","fields","syncFields","useReducer","append","prepend","unshift","insert","remove","swap","move","update","useFieldArrayItemCore","arrayPath","computeIndex","getArrayIds","computeValue","lastRef","computeRef","bump","idx","val","nextIndex","itemPath","setValue","createContext","FormProvider","Provider","CheckboxGroupContext","CheckboxGroupProvider","appendFormDataValue","fd","FileList","File","Blob","toISOString","ariaProps","fieldKey","Boolean","toConstraintAttrs","attrs","rulesToConstraintAttrs","Field","React","forwardRef","asProps","renderError","as","valueToProps","innerRef","nativeInvalidCount","setNativeInvalidCount","resolvedForm","isFile","validateWrapped","isDisabled","setCustomValidity","mergedRef","setRef","Component","valueProps","errorId","constraintAttrs","createElement","Fragment","role","Checkbox","toSelectValue","multiple","Select","children","selectedOptions","option","context","heading","containerRef","wasSubmittingRef","headingId","useId","check","wasSubmitting","offErrors","offSubmitting","tabIndex","dottedKey","href","onClick","action","f2","submit","FormData","formDataFromValues","nativeAction","noValidate","useFormContext","useFieldArray","useFieldArrayItem","initial","callback","unsubscribes","isNameList","unsubscribe","settle","focusFirstError","find","group","anyErrors","getFormState","selector","toDisplay","fromDisplay","asyncDebounceMs","raw","seqRef","fromDisplayRef","display","seq","transform","commit","consumers"],"mappings":"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"}
|