attaform 0.31.0 → 0.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/abstract.d.mts +5 -5
  2. package/dist/abstract.mjs +5 -4
  3. package/dist/dev/abstract.mjs +5 -4
  4. package/dist/dev/chunks/devtools.mjs +1 -1
  5. package/dist/dev/directive.mjs +1 -1
  6. package/dist/dev/history.mjs +126 -6
  7. package/dist/dev/index.mjs +6 -5
  8. package/dist/dev/runtime/plugins/attaform.mjs +1 -1
  9. package/dist/dev/shared/{attaform-dev.zlvDr0WB.mjs → attaform-dev.04aupFBW.mjs} +3 -2
  10. package/dist/dev/shared/{attaform-dev.CtyqGia7.mjs → attaform-dev.BKWPjEB2.mjs} +5 -4
  11. package/dist/dev/shared/{attaform-dev.DlaT4xGd.mjs → attaform-dev.BnLLxX2l.mjs} +4 -4
  12. package/dist/dev/shared/{attaform-dev.B1q-x9R9.mjs → attaform-dev.Bu6wgrA5.mjs} +1 -1
  13. package/dist/dev/shared/{attaform-dev.k5X47GMD.mjs → attaform-dev.CKSqs_xQ.mjs} +3 -2
  14. package/dist/dev/shared/{attaform-dev.DJ3nsWw6.mjs → attaform-dev.Cf_hZfbT.mjs} +18 -9
  15. package/dist/dev/shared/{attaform-dev.y9x9Vp9F.mjs → attaform-dev.DLk51W7-.mjs} +565 -926
  16. package/dist/dev/shared/attaform-dev.DoG8mZTq.mjs +127 -0
  17. package/dist/dev/shared/attaform-dev.G-3XDl9F.mjs +1192 -0
  18. package/dist/dev/shared/{attaform-dev.Caibt7sb.mjs → attaform-dev.oguHqv1W.mjs} +11 -10
  19. package/dist/dev/zod-v3.mjs +7 -6
  20. package/dist/dev/zod-v4.mjs +7 -6
  21. package/dist/dev/zod.mjs +6 -5
  22. package/dist/directive.d.mts +2 -2
  23. package/dist/directive.mjs +1 -1
  24. package/dist/history.d.mts +1 -1
  25. package/dist/history.mjs +126 -6
  26. package/dist/index.d.mts +16 -55
  27. package/dist/index.mjs +6 -5
  28. package/dist/runtime/plugins/attaform.mjs +1 -1
  29. package/dist/shared/{attaform.DL2nl_QR.mjs → attaform.3kV6PqVJ.mjs} +11 -10
  30. package/dist/shared/{attaform.L011tHgJ.mjs → attaform.BJeiuJE2.mjs} +4 -4
  31. package/dist/shared/attaform.BNUhW4qC.mjs +103 -0
  32. package/dist/shared/{attaform.CdZIEf7_.mjs → attaform.BhtAZysa.mjs} +3 -2
  33. package/dist/shared/{attaform.BWUn8Kjy.mjs → attaform.BlAmZ-WU.mjs} +18 -9
  34. package/dist/shared/{attaform.LUPC-2Qg.mjs → attaform.CMzc4bPI.mjs} +5 -4
  35. package/dist/shared/{attaform.C4shmwyJ.mjs → attaform.CdA9bfRv.mjs} +1 -1
  36. package/dist/shared/attaform.CgyyJVuq.mjs +1187 -0
  37. package/dist/shared/{attaform.DAo0QBmS.d.mts → attaform.CibLYe9-.d.mts} +214 -173
  38. package/dist/shared/{attaform.DNPJPOO7.mjs → attaform.DCUJCKyG.mjs} +562 -925
  39. package/dist/shared/{attaform.D9RqPgGu.d.mts → attaform.DCyZT7u-.d.mts} +1 -1
  40. package/dist/shared/{attaform.CRVe8s82.d.mts → attaform.DD0Y8krq.d.mts} +43 -19
  41. package/dist/shared/{attaform.DxKQsqFZ.mjs → attaform.T0YjhjPU.mjs} +3 -2
  42. package/dist/shared/{attaform.DZnrDrNb.d.mts → attaform.bI_4nKZp.d.mts} +119 -8
  43. package/dist/zod-v3.d.mts +4 -4
  44. package/dist/zod-v3.mjs +7 -6
  45. package/dist/zod-v4.d.mts +15 -11
  46. package/dist/zod-v4.mjs +7 -6
  47. package/dist/zod.d.mts +4 -4
  48. package/dist/zod.mjs +6 -5
  49. package/package.json +2 -1
  50. package/skills/attaform/SKILL.md +1 -0
  51. package/dist/dev/shared/attaform-dev.CZz4GYZ6.mjs +0 -386
  52. package/dist/shared/attaform.8mfKZCwH.mjs +0 -358
@@ -1,5 +1,5 @@
1
1
  import { App } from 'vue';
2
- import { an as RegisterModelDynamicCustomDirective } from './attaform.DZnrDrNb.mjs';
2
+ import { an as RegisterModelDynamicCustomDirective } from './attaform.bI_4nKZp.mjs';
3
3
 
4
4
  /**
5
5
  * The `v-register` directive. Bind a form field to a native input, select,
@@ -1,6 +1,23 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, l as FlatPath, s as NestedType, F as FormKey, U as UseFormConfiguration, A as AbstractSchema, ap as AcceptableDefaults, ab as ValidateOnConfig, a as UseFormReturnType } from './attaform.DZnrDrNb.mjs';
2
+ import { G as GenericForm, l as FlatPath, s as NestedType, F as FormKey, U as UseFormConfiguration, A as AbstractSchema, ap as AcceptableDefaults, ab as ValidateOnConfig, a as UseFormReturnType } from './attaform.bI_4nKZp.mjs';
3
3
 
4
+ /**
5
+ * A Zod v4 schema whose core definition matches `Def`, named by the
6
+ * `_zod` internals that classic `zod` and `zod/mini` schemas both carry.
7
+ */
8
+ type ZodV4SchemaOf<Def> = {
9
+ _zod: {
10
+ def: Def;
11
+ };
12
+ };
13
+ /**
14
+ * Any Zod v4 schema, from `zod` or `zod/mini`. The public signatures that
15
+ * take a v4 schema below the root (`PathInput`, `PathOutput`, `withMeta`)
16
+ * constrain on it, for the reasons `SupportedRootSchema` gives.
17
+ */
18
+ type ZodV4Schema = ZodV4SchemaOf<{
19
+ type: string;
20
+ }>;
4
21
  /**
5
22
  * The Zod v4 schema roots `useForm` accepts. A fixed-shape
6
23
  * `z.object({ … })` is the common case; `z.record(K, V)` admits a
@@ -16,22 +33,29 @@ import { G as GenericForm, l as FlatPath, s as NestedType, F as FormKey, U as Us
16
33
  * `z.map` / `z.set`) are not form roots; wrap them under a key. The
17
34
  * adapter's runtime construction rejects them with a legible error.
18
35
  *
19
- * `z.ZodObject` MUST keep its `z.ZodRawShape` argument, and the
20
- * discriminated-union arm MUST stay fully applied. The unified entry's
21
- * v4 overload constrains on `SupportedRootSchema & ZodV4Internals` to
22
- * keep v3 schemas out (see `../unified/types-zod-major.ts`). In a
23
- * single-major (v3-only) consumer install, the published `.d.mts`
24
- * resolves this `z` to v3, where a bare or under-applied Zod class is
25
- * missing its required arguments and degrades to an `any`-like error
26
- * type; `any` then absorbs the union and `any & ZodV4Internals`
27
- * collapses back to `any`, so the marker stops excluding v3 schemas and
28
- * the read slot poisons to `never`. `z.ZodRecord` carries defaults for
29
- * both arguments, so it stays concrete in either major.
30
- * `z.ZodDiscriminatedUnion` does NOT (v3 requires both arguments, and
31
- * its parameter order is the reverse of v4's), so the arm is written
32
- * fully applied; the v3-only bundled-types fixture guards it.
36
+ * Each arm is structural on `_zod.def.type`, Zod's core internals, so a
37
+ * `zod/mini` root binds exactly as its classic twin does, and the form
38
+ * types project through `z.input` / `z.output`, which are core's too. A
39
+ * plain union's `def` has no `discriminator`, which keeps it out of the
40
+ * third arm.
41
+ *
42
+ * The alias names nothing from `zod`, and the unified `attaform/zod`
43
+ * entry depends on that. Its published `.d.mts` resolves `zod` against
44
+ * the one major a consumer installed, and in a v3-only install a classic
45
+ * class reference such as `z.ZodObject` degrades to an `any`-like error
46
+ * type, which a v3 schema satisfies: the v4 overload would capture it and
47
+ * collapse its read slot to `never`. No v3 schema carries `_zod`, so this
48
+ * constraint sends every v3 schema to the v3 overload however `zod`
49
+ * resolves. The v3-only bundled-types fixture guards it.
33
50
  */
34
- type SupportedRootSchema = z.ZodObject<z.ZodRawShape> | z.ZodRecord | z.ZodDiscriminatedUnion<readonly z.ZodObject<z.ZodRawShape>[], string>;
51
+ type SupportedRootSchema = ZodV4SchemaOf<{
52
+ type: 'object';
53
+ }> | ZodV4SchemaOf<{
54
+ type: 'record';
55
+ }> | ZodV4SchemaOf<{
56
+ type: 'union';
57
+ discriminator: string;
58
+ }>;
35
59
 
36
60
  /**
37
61
  * The shape `form.values.<key>` returns at runtime. Four cases per leaf:
@@ -164,7 +188,7 @@ type StorageLeaf<L> = InputIsUnknown<L> extends true ? unknown : L extends {
164
188
  * type FlagWriteIn = PathInput<typeof schema, 'flag'> // string
165
189
  * ```
166
190
  */
167
- type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema> extends GenericForm ? Path extends FlatPath<z.input<Schema>> ? NestedType<z.input<Schema>, Path> : never : never;
191
+ type PathInput<Schema extends ZodV4Schema, Path extends string> = z.input<Schema> extends GenericForm ? Path extends FlatPath<z.input<Schema>> ? NestedType<z.input<Schema>, Path> : never : never;
168
192
  /**
169
193
  * What `Path` holds after the full parse pipeline: the schema's
170
194
  * `z.output<Schema>` shape there. It matches `form.parse()`'s `data` and
@@ -177,7 +201,7 @@ type PathInput<Schema extends z.ZodType, Path extends string> = z.input<Schema>
177
201
  * type FlagParsedOut = PathOutput<typeof schema, 'flag'> // boolean
178
202
  * ```
179
203
  */
180
- type PathOutput<Schema extends z.ZodType, Path extends string> = z.output<Schema> extends GenericForm ? Path extends FlatPath<z.output<Schema>> ? NestedType<z.output<Schema>, Path> : never : never;
204
+ type PathOutput<Schema extends ZodV4Schema, Path extends string> = z.output<Schema> extends GenericForm ? Path extends FlatPath<z.output<Schema>> ? NestedType<z.output<Schema>, Path> : never : never;
181
205
  /**
182
206
  * Factor the three identical-shape conditionals out of `useForm`'s public
183
207
  * signature, so the bundled `.d.ts` carries one alias per shape instead
@@ -217,4 +241,4 @@ declare function useForm<Schema extends SupportedRootSchema, K extends FormKey =
217
241
  } & ValidateOnConfig): UseFormReturnType<FormOf<Schema>, OutOf<Schema>, ReadOf<Schema>, K>;
218
242
 
219
243
  export { useForm as u };
220
- export type { PathInput as P, SupportedRootSchema as S, PathOutput as a, StorageShape as b };
244
+ export type { PathInput as P, SupportedRootSchema as S, ZodV4Schema as Z, PathOutput as a, StorageShape as b };
@@ -1,6 +1,7 @@
1
1
  import { toRaw, reactive, markRaw, effectScope, watch, nextTick } from 'vue';
2
2
  import { i as isRegisterValue, a as isTransforming, S as SSR_COMPONENT_HOST_MODIFIER, R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.KvlEedlF.mjs';
3
- import { e as canonicalizePath } from './attaform.CdZIEf7_.mjs';
3
+ import { e as canonicalizePath } from './attaform.BhtAZysa.mjs';
4
+ import { d as safeOwnHas } from './attaform.BNUhW4qC.mjs';
4
5
 
5
6
  function activeElementOf(node) {
6
7
  const rootNode = node.getRootNode();
@@ -304,7 +305,7 @@ function createHostChannel() {
304
305
  return commit(rv, value, modifiers);
305
306
  },
306
307
  writeInput(rv, payload, modifiers) {
307
- if (typeof payload !== "object" || payload === null || payload instanceof Event || !("value" in payload) || !Object.hasOwn(payload, "value")) {
308
+ if (typeof payload !== "object" || payload === null || payload instanceof Event || !("value" in payload) || !safeOwnHas(payload, "value")) {
308
309
  return false;
309
310
  }
310
311
  return rv.setValueFromHost(payload.value, modifiers);
@@ -215,6 +215,25 @@ type OriginalsRecord = {
215
215
  readonly segments: Path;
216
216
  readonly value: unknown;
217
217
  };
218
+ /** Every tracked array's identity tokens and baseline order, by array key. */
219
+ type IdentityOrders = {
220
+ readonly tokens: ReadonlyMap<PathKey, readonly string[]>;
221
+ readonly baselines: ReadonlyMap<PathKey, readonly string[]>;
222
+ };
223
+ /**
224
+ * The per-element bookkeeping a history position puts back with its value.
225
+ * A typed array op moves each element's baseline with its identity and drops
226
+ * a removed element's, as it does the element's blank membership, so a value
227
+ * alone, restored by position, would compare each row against the baseline of
228
+ * whichever row sits there now. With them come the identity orders and the
229
+ * removed-baseline set those baselines are read against. Opaque to the history module, which keeps it and hands it back.
230
+ */
231
+ type StructureSnapshot = {
232
+ readonly identity: IdentityOrders;
233
+ readonly originals: ReadonlyArray<readonly [PathKey, OriginalsRecord]>;
234
+ readonly originalBlank: ReadonlyArray<PathKey>;
235
+ readonly removed: ReadonlyArray<readonly [PathKey, Path]>;
236
+ };
218
237
 
219
238
  /** Internal brand for the `Unset` type. Never exposed at runtime. */
220
239
  declare const _unsetBrand: unique symbol;
@@ -744,6 +763,50 @@ type DefaultValuesInput<T> = T extends string ? string | Unset : T extends numbe
744
763
  type AcceptableDefaults<Form, SchemaInput> = AcceptableDefaultsOf<DefaultValuesInput<Form>, SchemaInput>;
745
764
  type AcceptableDefaultsOf<DVI, SchemaInput> = DVI | SchemaInput | (() => DVI | SchemaInput) | (() => Promise<DVI | SchemaInput>);
746
765
 
766
+ /**
767
+ * The arrays engine: everything keeping per-element state truthful across a
768
+ * structural array mutation, in one module around one permutation core.
769
+ *
770
+ * A structural mutation, which the typed helpers below tag with an `arrayOp`,
771
+ * is decoded exactly once into an {@link IndexRemap}, and `remapForOp` is the
772
+ * single source of permutation truth. Every consumer derives from that remap:
773
+ *
774
+ * - the identity tracker replays it onto its token lists (`permuteList`);
775
+ * - per-element state relocation walks it (`migrateMapSubtree` /
776
+ * `migrateSetSubtree`);
777
+ * - derived-state eviction, schema verdicts and variant memory, drops at its
778
+ * `changedIndices`;
779
+ * - the write funnel scopes its per-element work to `remap.fresh`.
780
+ *
781
+ * One decode and many readers, so the permutation cannot drift between the
782
+ * consumer-facing `:key` token and the state that must travel with it.
783
+ */
784
+
785
+ /**
786
+ * The exact index permutation an array operation produced, recovered from
787
+ * its `arrayOp` hint. Three disjoint facts drive every downstream rewrite:
788
+ *
789
+ * - `moved`: an old element index and the new index it now sits at.
790
+ * Identity entries (`i -> i`) are omitted, so an unmoved element's state
791
+ * is left untouched in place.
792
+ * - `vacated`: old indices whose element no longer exists (a `remove`
793
+ * target, or the outgoing occupant of a `replace-at`). Their non-derived
794
+ * state is dropped, not relocated.
795
+ * - `fresh`: new indices holding a brand-new element (an `insert` slot, or
796
+ * a `replace-at` target). They start with no carried-over state.
797
+ *
798
+ * `oldLen` / `newLen` carry the array's pre- and post-op lengths so a
799
+ * consumer replaying the permutation (the identity tracker's token
800
+ * lists) never re-derives them from the op kind.
801
+ */
802
+ type IndexRemap = {
803
+ readonly moved: ReadonlyMap<number, number>;
804
+ readonly vacated: ReadonlySet<number>;
805
+ readonly fresh: ReadonlySet<number>;
806
+ readonly oldLen: number;
807
+ readonly newLen: number;
808
+ };
809
+
747
810
  /**
748
811
  * Identifier for a form: the string passed to `useForm({ key })`, used
749
812
  * to look a form up by name from a distant component and to label
@@ -1622,10 +1685,16 @@ type WriteMeta = {
1622
1685
  type HistoryKernel = {
1623
1686
  readonly form: Ref<unknown>;
1624
1687
  readonly blankPaths: Set<PathKey>;
1688
+ readonly fields: ReadonlyMap<PathKey, FieldRecord>;
1625
1689
  readonly errorCells: () => Map<PathKey, ErrorCell>;
1626
1690
  onFormChange(listener: (next: unknown, meta?: WriteMeta) => void): () => void;
1691
+ onReset(listener: () => void): () => void;
1627
1692
  applyFormReplacement(next: unknown): void;
1628
1693
  restoreErrorCells(entries: ReadonlyArray<readonly [PathKey, ErrorCell]>): void;
1694
+ captureStructure(): StructureSnapshot;
1695
+ restoreStructure(snapshot: StructureSnapshot, remaps: ReadonlyArray<readonly [Path, IndexRemap]>, returning: readonly FieldRecord[]): void;
1696
+ /** Set while attached: hears the records each removal releases. */
1697
+ noteReleased?: ((records: readonly FieldRecord[]) => void) | undefined;
1629
1698
  };
1630
1699
  /**
1631
1700
  * The live undo/redo runtime a {@link HistoryPlugin} attaches to one
@@ -2072,7 +2141,13 @@ type HandleSubmit<Form extends GenericForm> = (onSubmit: OnSubmit<Form>, onError
2072
2141
  * fields appear in friendlier shape on `FieldState`.
2073
2142
  */
2074
2143
  type MetaTrackerValue = {
2075
- /** ISO timestamp of the most recent write at this path. `null` if never written. */
2144
+ /**
2145
+ * ISO timestamp of the most recent write at this path or under it,
2146
+ * counting the form's creation. A removal is a write too, so the stamp
2147
+ * never moves backwards, and every write reads later than the one before
2148
+ * it, whatever the device's clock says. `null` only for a path never
2149
+ * written or no longer present.
2150
+ */
2076
2151
  updatedAt: string | null;
2077
2152
  /** Value as it arrived, before any transforms. Distinguishes a parse-coerced read from raw user input. */
2078
2153
  rawValue: unknown;
@@ -2954,11 +3029,25 @@ type PathSetValuePayload<Leaf> = IsAny<Leaf> extends true ? any : unknown extend
2954
3029
  */
2955
3030
  type FieldState<Value = unknown> = {
2956
3031
  readonly value: Value;
3032
+ /**
3033
+ * The value this path started as: the defaults, re-seated by `reset()` and
3034
+ * by async defaults. At a container, the subtree it started as, each row
3035
+ * read at its own baseline wherever the typed array ops have moved it, and
3036
+ * frozen, since every read shares it. `undefined` for a field or row added
3037
+ * since.
3038
+ */
2957
3039
  readonly original: Value;
2958
3040
  readonly pristine: boolean;
2959
3041
  readonly dirty: boolean;
2960
3042
  readonly focused: boolean | null;
2961
3043
  readonly blurred: boolean | null;
3044
+ /**
3045
+ * `true` once this field has been blurred, with or without an edit.
3046
+ * Sticky thereafter, including through a value round trip; cleared by
3047
+ * `form.reset()` / `form.resetField(path)`. Containers roll it up as
3048
+ * a disjunction, and keep it after the descendant that set it is
3049
+ * removed.
3050
+ */
2962
3051
  readonly touched: boolean;
2963
3052
  /**
2964
3053
  * `true` once the user has issued at least one value edit on this
@@ -2970,7 +3059,8 @@ type FieldState<Value = unknown> = {
2970
3059
  * flips `touched` but never `interacted`. Set only by user input,
2971
3060
  * never by hydration or programmatic `setValue`; cleared by
2972
3061
  * `form.reset()` / `form.resetField(path)`. Containers roll it up as
2973
- * a disjunction (any descendant interacted).
3062
+ * a disjunction (any descendant interacted), and keep it after the
3063
+ * descendant that set it is removed.
2974
3064
  */
2975
3065
  readonly interacted: boolean;
2976
3066
  /**
@@ -2983,7 +3073,8 @@ type FieldState<Value = unknown> = {
2983
3073
  * visible through a re-focus to be fixed live. Set only by user
2984
3074
  * input/blur, never by hydration or programmatic writes; cleared by
2985
3075
  * `form.reset()` / `form.resetField(path)`. Containers roll it up as a
2986
- * disjunction.
3076
+ * disjunction, and keep it after the descendant that set it is
3077
+ * removed.
2987
3078
  */
2988
3079
  readonly blurredAfterInteraction: boolean;
2989
3080
  readonly connected: boolean;
@@ -3019,6 +3110,18 @@ type FieldState<Value = unknown> = {
3019
3110
  * `elements[0] ?? null`.
3020
3111
  */
3021
3112
  readonly elements: readonly HTMLElement[];
3113
+ /**
3114
+ * ISO timestamp of the most recent write at this path or anywhere
3115
+ * under it, counting the form's creation. A removal is a write too, so
3116
+ * a container's stamp moves forward when a row leaves and never moves
3117
+ * backwards. A survivor keeps its own stamp when a removal or a reorder
3118
+ * moves it to a new index, and a write that changes nothing stamps
3119
+ * nothing. Every write that changes a value reads later than the one
3120
+ * before it: two writes in one millisecond, or a write on a device whose
3121
+ * clock runs behind the server that rendered the page, take one
3122
+ * millisecond past the latest stamp the form holds. `null` only for a
3123
+ * path never written or no longer present.
3124
+ */
3022
3125
  readonly updatedAt: string | null;
3023
3126
  /**
3024
3127
  * Every `ValidationError` in this path's SUBTREE: the node's own
@@ -4356,7 +4459,9 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
4356
4459
  * - the form value back to defaults;
4357
4460
  * - the dirty baseline (so the next edit flips `dirty` correctly);
4358
4461
  * - field errors;
4359
- * - touched / focused / blurred per-field flags;
4462
+ * - the interaction history (`touched` / `interacted` /
4463
+ * `blurredAfterInteraction`) at every path, containers included;
4464
+ * `focused`, `blurred` and `connected` follow the DOM and stay;
4360
4465
  * - submission state (`submitting` / `submissionAttempts` /
4361
4466
  * `submitted` / `submitError`).
4362
4467
  *
@@ -4383,8 +4488,10 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
4383
4488
  reset: (nextDefaultValues?: DefaultValuesInput<Form>) => void;
4384
4489
  /**
4385
4490
  * Restore a single field (or a sub-tree like `'user'`) to its
4386
- * initial value. Clears errors and touched flags for the field
4387
- * and its descendants; leaves siblings and submission state alone.
4491
+ * initial value. Clears errors and the interaction history
4492
+ * (`touched` / `interacted` / `blurredAfterInteraction`) for the
4493
+ * field and its descendants; leaves siblings, ancestors and
4494
+ * submission state alone.
4388
4495
  *
4389
4496
  * No-op when the path doesn't exist on the form (e.g. a typo'd
4390
4497
  * dynamic key).
@@ -4495,6 +4602,8 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
4495
4602
  * form.touch() // every leaf in the form
4496
4603
  * ```
4497
4604
  *
4605
+ * An empty list under `path` is marked too, though it holds no leaf.
4606
+ *
4498
4607
  * **This does not reveal errors under the default display
4499
4608
  * heuristic.** `touched` also flips on a bare focus and blur with no
4500
4609
  * edit, so the library-default gate ignores it and reads
@@ -4532,7 +4641,9 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
4532
4641
  *
4533
4642
  * Walks schema leaves, so it reaches fields that are currently
4534
4643
  * `v-if`'d away or were never mounted; the flags are sticky, so
4535
- * such a subtree stays revealed when it remounts.
4644
+ * such a subtree stays revealed when it remounts. An empty list
4645
+ * under `path` is marked too, so its own error (a `.min(1)`)
4646
+ * reveals.
4536
4647
  *
4537
4648
  * Flags land synchronously, and the returned promise resolves once
4538
4649
  * the subtree's validation has committed, so an awaiting caller reads
@@ -4654,4 +4765,4 @@ type UseFormReturnType<Form extends GenericForm, GetValueFormType extends Generi
4654
4765
  };
4655
4766
 
4656
4767
  export { ROOT_PATH as R, canonicalizePath as ai, isPathPrefix as aj, isUnset as ak, parseDottedPath as al, unset as am, ROOT_PATH_KEY as z };
4657
- export type { SchemaParseErrorWithData as $, AbstractSchema as A, ReactiveValidationStatus as B, CustomDirectiveRegisterAssignerFn as C, DefaultValuesInput as D, ErrorInput as E, FormKey as F, GenericForm as G, HandleSubmit as H, IsTuple as I, JoinSegments as J, KeyofUnion as K, LiftedValueShape as L, MetaTrackerValue as M, NestedReadType as N, OnError as O, ParseOptions as P, RecordPath as Q, RecordValue as S, RegisterDirective as T, UseFormConfiguration as U, RegisterFlatPath as V, RegisterOptions as W, RegisterSelectModifier as X, RegisterTextModifier as Y, RegisterTransform as Z, RegisterValue as _, UseFormReturnType as a, SchemaParseErrorWithoutData as a0, SchemaParseResult as a1, SchemaParseSuccess as a2, Segment as a3, SetValueCallback as a4, SetValuePayload as a5, SettledValidationStatus as a6, SlimPrimitiveKind as a7, SubmitHandler as a8, Unset as a9, ValidateOn as aa, ValidateOnConfig as ab, ValidationError as ac, ValidationResponse as ad, ValidationResponseWithoutValue as ae, ValueOfUnion as af, WriteMeta as ag, WriteShape as ah, RegisterModelDynamicCustomDirective as an, SchemaFactoryOptions as ao, AcceptableDefaults as ap, DisplayCtx as aq, GetDisplayState as ar, DisplayMachine as as, FieldRecord as at, ErrorCell as au, OriginalsRecord as av, AttaformDomBinding as aw, TransformAbortHolder as ax, ArrayItem as b, ArrayPath as c, DeepPartial as d, DefaultValuesShape as e, DisplayState as f, ErrorsProxyShape as g, FieldMetaPayload as h, FieldState as i, FieldStateMap as j, FieldStateMapEntry as k, FlatPath as l, FormErrorRecord as m, FormErrorsSurface as n, FormMeta as o, HistoryPlugin as p, IsUnion as q, Json as r, NestedType as s, OnSubmit as t, PartialFlatPath as u, Path as v, PathKey as w, PendingValidationStatus as x, Primitive as y };
4768
+ export type { SchemaParseErrorWithData as $, AbstractSchema as A, ReactiveValidationStatus as B, CustomDirectiveRegisterAssignerFn as C, DefaultValuesInput as D, ErrorInput as E, FormKey as F, GenericForm as G, HandleSubmit as H, IsTuple as I, JoinSegments as J, KeyofUnion as K, LiftedValueShape as L, MetaTrackerValue as M, NestedReadType as N, OnError as O, ParseOptions as P, RecordPath as Q, RecordValue as S, RegisterDirective as T, UseFormConfiguration as U, RegisterFlatPath as V, RegisterOptions as W, RegisterSelectModifier as X, RegisterTextModifier as Y, RegisterTransform as Z, RegisterValue as _, UseFormReturnType as a, SchemaParseErrorWithoutData as a0, SchemaParseResult as a1, SchemaParseSuccess as a2, Segment as a3, SetValueCallback as a4, SetValuePayload as a5, SettledValidationStatus as a6, SlimPrimitiveKind as a7, SubmitHandler as a8, Unset as a9, ValidateOn as aa, ValidateOnConfig as ab, ValidationError as ac, ValidationResponse as ad, ValidationResponseWithoutValue as ae, ValueOfUnion as af, WriteMeta as ag, WriteShape as ah, RegisterModelDynamicCustomDirective as an, SchemaFactoryOptions as ao, AcceptableDefaults as ap, DisplayCtx as aq, GetDisplayState as ar, DisplayMachine as as, FieldRecord as at, ErrorCell as au, OriginalsRecord as av, StructureSnapshot as aw, IndexRemap as ax, AttaformDomBinding as ay, TransformAbortHolder as az, ArrayItem as b, ArrayPath as c, DeepPartial as d, DefaultValuesShape as e, DisplayState as f, ErrorsProxyShape as g, FieldMetaPayload as h, FieldState as i, FieldStateMap as j, FieldStateMapEntry as k, FlatPath as l, FormErrorRecord as m, FormErrorsSurface as n, FormMeta as o, HistoryPlugin as p, IsUnion as q, Json as r, NestedType as s, OnSubmit as t, PartialFlatPath as u, Path as v, PathKey as w, PendingValidationStatus as x, Primitive as y };
package/dist/zod-v3.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, F as FormKey, U as UseFormConfiguration, ap as AcceptableDefaults, a as UseFormReturnType, ab as ValidateOnConfig, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.DZnrDrNb.mjs';
2
+ import { G as GenericForm, F as FormKey, U as UseFormConfiguration, ap as AcceptableDefaults, a as UseFormReturnType, ab as ValidateOnConfig, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.bI_4nKZp.mjs';
3
3
  import { AbstractSchema } from './abstract.mjs';
4
- export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, aa as ValidateOn, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.DZnrDrNb.mjs';
4
+ export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, aa as ValidateOn, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.bI_4nKZp.mjs';
5
5
  import { S as SupportedRootSchema, U as UnwrapZodRoot, a as StorageShape } from './shared/attaform.B-Tb62qV.mjs';
6
- export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.DAo0QBmS.mjs';
7
- export { v as vRegister } from './shared/attaform.D9RqPgGu.mjs';
6
+ export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.CibLYe9-.mjs';
7
+ export { v as vRegister } from './shared/attaform.DCyZT7u-.mjs';
8
8
  import 'vue';
9
9
 
10
10
  /**
package/dist/zod-v3.mjs CHANGED
@@ -1,9 +1,10 @@
1
- export { i as isZodSchemaType, u as useForm, z as zodAdapter } from './shared/attaform.LUPC-2Qg.mjs';
2
- import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.DL2nl_QR.mjs';
3
- export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.CdZIEf7_.mjs';
4
- export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNPJPOO7.mjs';
5
- export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.C4shmwyJ.mjs';
6
- export { a as assignKey, v as vRegister } from './shared/attaform.DxKQsqFZ.mjs';
1
+ export { i as isZodSchemaType, u as useForm, z as zodAdapter } from './shared/attaform.CMzc4bPI.mjs';
2
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.3kV6PqVJ.mjs';
3
+ export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.BhtAZysa.mjs';
4
+ export { A as AttaformErrorCode } from './shared/attaform.CgyyJVuq.mjs';
5
+ export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.CdA9bfRv.mjs';
6
+ export { a as assignKey, v as vRegister } from './shared/attaform.T0YjhjPU.mjs';
7
+ export { e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DCUJCKyG.mjs';
7
8
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
8
9
 
9
10
  const fieldMeta = installingFieldMetaStore;
package/dist/zod-v4.d.mts CHANGED
@@ -1,16 +1,18 @@
1
- import { S as SupportedRootSchema } from './shared/attaform.CRVe8s82.mjs';
2
- export { P as PathInput, a as PathOutput, u as useForm } from './shared/attaform.CRVe8s82.mjs';
3
- import { F as FormKey, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.DZnrDrNb.mjs';
1
+ import { S as SupportedRootSchema, Z as ZodV4Schema } from './shared/attaform.DD0Y8krq.mjs';
2
+ export { P as PathInput, a as PathOutput, u as useForm } from './shared/attaform.DD0Y8krq.mjs';
3
+ import { F as FormKey, ao as SchemaFactoryOptions, h as FieldMetaPayload } from './shared/attaform.bI_4nKZp.mjs';
4
4
  import { AbstractSchema } from './abstract.mjs';
5
- export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, U as UseFormConfiguration, a as UseFormReturnType, aa as ValidateOn, ab as ValidateOnConfig, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.DZnrDrNb.mjs';
6
- export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.DAo0QBmS.mjs';
7
- export { v as vRegister } from './shared/attaform.D9RqPgGu.mjs';
5
+ export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, U as UseFormConfiguration, a as UseFormReturnType, aa as ValidateOn, ab as ValidateOnConfig, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.bI_4nKZp.mjs';
6
+ export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.CibLYe9-.mjs';
7
+ export { v as vRegister } from './shared/attaform.DCyZT7u-.mjs';
8
8
  import { z } from 'zod';
9
9
  import 'vue';
10
10
 
11
11
  /**
12
12
  * The Zod v4 adapter: `AbstractSchema` implemented against Zod v4's
13
- * public surface. Internal `def.*` access is quarantined to
13
+ * public surface, for schemas built by `zod` and by `zod/mini` alike;
14
+ * every node is a `ZodV4Node`, the surface the two builds share.
15
+ * Internal `def.*` access is quarantined to
14
16
  * `introspect.ts` and the modules beside it (default-values,
15
17
  * path-walker, discriminator, errors), leaving this file as the wiring
16
18
  * between them and the `AbstractSchema` contract.
@@ -66,9 +68,9 @@ type ZodKind = 'object' | 'array' | 'set' | 'record' | 'tuple' | 'union' | 'disc
66
68
  declare function kindOf(schema: unknown): ZodKind;
67
69
  /**
68
70
  * Verify a schema is Zod v4, throwing a clear error for a v3 schema
69
- * imported through `attaform/zod` by mistake. The adapter calls it on
70
- * every schema; reach for it directly only in a custom adapter that
71
- * wants the same guard.
71
+ * imported through `attaform/zod` by mistake. The adapter runs the same
72
+ * check on every schema; reach for it directly only in a custom adapter
73
+ * that wants the same guard.
72
74
  */
73
75
  declare function assertZodVersion(schema: unknown): void;
74
76
 
@@ -161,7 +163,9 @@ declare const fieldMeta: ZodFieldMetaRegistry;
161
163
  * several paths and each needs its own payload: the clone per call is
162
164
  * what gives each call site its own registry slot.
163
165
  */
164
- declare function withMeta<S extends z.ZodType>(schema: S, payload: FieldMetaPayload): S;
166
+ declare function withMeta<S extends ZodV4Schema & {
167
+ clone(): S;
168
+ }>(schema: S, payload: FieldMetaPayload): S;
165
169
 
166
170
  export { FieldMetaPayload, FormKey, assertZodVersion, fieldMeta, kindOf, withMeta, zodV4Adapter as zodAdapter };
167
171
  export type { ZodKind };
package/dist/zod-v4.mjs CHANGED
@@ -1,9 +1,10 @@
1
- export { a as assertZodVersion, k as kindOf, u as useForm, z as zodAdapter } from './shared/attaform.BWUn8Kjy.mjs';
2
- import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.DL2nl_QR.mjs';
3
- export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.CdZIEf7_.mjs';
4
- export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNPJPOO7.mjs';
5
- export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.C4shmwyJ.mjs';
6
- export { a as assignKey, v as vRegister } from './shared/attaform.DxKQsqFZ.mjs';
1
+ export { a as assertZodVersion, k as kindOf, u as useForm, z as zodAdapter } from './shared/attaform.BlAmZ-WU.mjs';
2
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './shared/attaform.3kV6PqVJ.mjs';
3
+ export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.BhtAZysa.mjs';
4
+ export { A as AttaformErrorCode } from './shared/attaform.CgyyJVuq.mjs';
5
+ export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.CdA9bfRv.mjs';
6
+ export { a as assignKey, v as vRegister } from './shared/attaform.T0YjhjPU.mjs';
7
+ export { e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DCUJCKyG.mjs';
7
8
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
8
9
 
9
10
  const fieldMeta = installingFieldMetaStore;
package/dist/zod.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.DAo0QBmS.mjs';
2
- export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, h as FieldMetaPayload, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, F as FormKey, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, U as UseFormConfiguration, a as UseFormReturnType, aa as ValidateOn, ab as ValidateOnConfig, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.DZnrDrNb.mjs';
3
- export { v as vRegister } from './shared/attaform.D9RqPgGu.mjs';
1
+ export { a as AnyForm, b as AttaformDevtoolsBridge, c as AttaformError, d as AttaformErrorCode, e as AttaformPluginOptions, A as AttaformRegistry, C as CompiledStep, D as DEVTOOLS_WINDOW_KEY, F as FormStatus, f as FormStatusSeed, G as GateMarker, I as InjectWizardInput, g as InvalidPathError, h as InvalidUseFormConfigError, L as LazyMarker, O as OutsideSetupError, R as RegistryNotInstalledError, i as ReservedFormKeyError, S as SerializedAttaformState, j as SerializedFormData, k as StepSlot, l as SubmitErrorHandlerError, U as UseRegisterOptions, m as UseRegisterReturn, n as UseWizardReturnType, W as WizardAggregateError, o as WizardCtx, p as WizardCtxForm, q as WizardOnError, r as WizardOnSubmit, s as WizardOptions, t as WizardPersistFn, u as WizardRestoreFn, v as WizardRestoreState, w as WizardStatusesProxy, x as WizardSubmitContext, y as assignKey, z as createAttaform, B as createRegistry, E as escapeForInlineScript, H as gate, J as getRegistryFromApp, K as hydrateAttaformState, M as injectForm, N as injectWizard, P as isRegisterValue, Q as kAttaformRegistry, T as lazy, V as renderAttaformState, X as useRegister, Y as useRegistry, Z as useWizard } from './shared/attaform.CibLYe9-.mjs';
2
+ export { b as ArrayItem, c as ArrayPath, C as CustomDirectiveRegisterAssignerFn, d as DeepPartial, D as DefaultValuesInput, e as DefaultValuesShape, f as DisplayState, E as ErrorInput, g as ErrorsProxyShape, h as FieldMetaPayload, i as FieldState, j as FieldStateMap, k as FieldStateMapEntry, l as FlatPath, m as FormErrorRecord, n as FormErrorsSurface, F as FormKey, o as FormMeta, G as GenericForm, H as HandleSubmit, p as HistoryPlugin, I as IsTuple, q as IsUnion, J as JoinSegments, r as Json, K as KeyofUnion, L as LiftedValueShape, M as MetaTrackerValue, N as NestedReadType, s as NestedType, O as OnError, t as OnSubmit, P as ParseOptions, u as PartialFlatPath, v as Path, w as PathKey, x as PendingValidationStatus, y as Primitive, R as ROOT_PATH, z as ROOT_PATH_KEY, B as ReactiveValidationStatus, Q as RecordPath, S as RecordValue, T as RegisterDirective, V as RegisterFlatPath, W as RegisterOptions, X as RegisterSelectModifier, Y as RegisterTextModifier, Z as RegisterTransform, _ as RegisterValue, $ as SchemaParseErrorWithData, a0 as SchemaParseErrorWithoutData, a1 as SchemaParseResult, a2 as SchemaParseSuccess, a3 as Segment, a4 as SetValueCallback, a5 as SetValuePayload, a6 as SettledValidationStatus, a7 as SlimPrimitiveKind, a8 as SubmitHandler, a9 as Unset, U as UseFormConfiguration, a as UseFormReturnType, aa as ValidateOn, ab as ValidateOnConfig, ac as ValidationError, ad as ValidationResponse, ae as ValidationResponseWithoutValue, af as ValueOfUnion, ag as WriteMeta, ah as WriteShape, ai as canonicalizePath, aj as isPathPrefix, ak as isUnset, al as parseDottedPath, am as unset } from './shared/attaform.bI_4nKZp.mjs';
3
+ export { v as vRegister } from './shared/attaform.DCyZT7u-.mjs';
4
4
  export { UseFormConfig, UseFormConfigV3, UseFormConfigV4, UseFormReturn, UseFormReturnV3, UseFormReturnV4, fieldMeta, useForm, withMeta } from './index.mjs';
5
- export { P as PathInput, a as PathOutput } from './shared/attaform.CRVe8s82.mjs';
5
+ export { P as PathInput, a as PathOutput } from './shared/attaform.DD0Y8krq.mjs';
6
6
  import 'vue';
7
7
  import './shared/attaform.B-Tb62qV.mjs';
8
8
  import 'zod';
package/dist/zod.mjs CHANGED
@@ -1,6 +1,7 @@
1
- export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.CdZIEf7_.mjs';
2
- export { A as AttaformErrorCode, e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DNPJPOO7.mjs';
3
- export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.C4shmwyJ.mjs';
4
- export { a as assignKey, v as vRegister } from './shared/attaform.DxKQsqFZ.mjs';
5
- export { f as fieldMeta, u as useForm, w as withMeta } from './shared/attaform.L011tHgJ.mjs';
1
+ export { A as AttaformError, I as InvalidPathError, a as InvalidUseFormConfigError, O as OutsideSetupError, R as ROOT_PATH, b as ROOT_PATH_KEY, c as RegistryNotInstalledError, d as ReservedFormKeyError, S as SubmitErrorHandlerError, e as canonicalizePath, i as isPathPrefix, p as parseDottedPath } from './shared/attaform.BhtAZysa.mjs';
2
+ export { A as AttaformErrorCode } from './shared/attaform.CgyyJVuq.mjs';
3
+ export { D as DEVTOOLS_WINDOW_KEY, c as createAttaform, a as createRegistry, g as getRegistryFromApp, h as hydrateAttaformState, k as kAttaformRegistry, r as renderAttaformState, u as useRegistry } from './shared/attaform.CdA9bfRv.mjs';
4
+ export { a as assignKey, v as vRegister } from './shared/attaform.T0YjhjPU.mjs';
5
+ export { e as escapeForInlineScript, g as gate, i as injectForm, a as injectWizard, b as isUnset, l as lazy, u as unset, d as useRegister, f as useWizard } from './shared/attaform.DCUJCKyG.mjs';
6
+ export { f as fieldMeta, u as useForm, w as withMeta } from './shared/attaform.BJeiuJE2.mjs';
6
7
  export { i as isRegisterValue } from './shared/attaform.KvlEedlF.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "attaform",
3
- "version": "0.31.0",
3
+ "version": "0.31.2",
4
4
  "types": "./dist/index.d.mts",
5
5
  "files": [
6
6
  "dist",
@@ -233,6 +233,7 @@
233
233
  "bench:delta": "node scripts/bench-delta.mjs",
234
234
  "check:bundled-types": "node scripts/check-bundled-types.mjs",
235
235
  "check:doc-snippets": "node scripts/check-doc-snippets.mjs",
236
+ "check:browser-floor": "node scripts/check-browser-floor.mjs",
236
237
  "check:comment-only": "node scripts/check-comment-only.mjs",
237
238
  "check:site": "pnpm dev:prepare && pnpm --filter attaform-site typecheck",
238
239
  "fallow": "DO_NOT_TRACK=1 FALLOW_TELEMETRY=0 npx --yes fallow@2.88.3 --score",
@@ -31,6 +31,7 @@ import {
31
31
  - **Do not import `useForm` from `attaform/abstract`.** That entry is the bring-your-own-adapter escape hatch: it exports `useAbstractForm`, which needs a schema adapter wired by hand. A Zod project wants `useForm` from `attaform`. This mismatch is the single most common first-try mistake.
32
32
  - Types come from the same barrel: `import type { AnyForm, WizardCtx, Json, ValidationError } from 'attaform'`.
33
33
  - `attaform/zod` is the same surface named explicitly; `attaform/zod-v3` and `attaform/zod-v4` pin a Zod major. Any of these works; default to `attaform`.
34
+ - A `zod/mini` schema (`import * as z from 'zod/mini'`) works on every v4 entry with the same API, types and behavior as classic `zod`. Mini loads no locale, so give each check its own message or call `z.config(z.locales.en())` once at startup; otherwise unmessaged checks report `Invalid input`.
34
35
  - In **Nuxt** with the module installed (`attaform/nuxt`), the whole block above auto-imports and the `v-register` directive is bound into each compiled template, so a component needs no import lines at all. Writing them anyway is always safe and always portable: an explicit import beats an auto-import of the same name, which is why every snippet below keeps its import line. In **plain Vite**, add the Attaform plugin from `attaform/vite` (it binds `v-register` the same way) plus the auto-import preset it exports. Without either build plugin, register the directive once per app: `import { installVRegister } from 'attaform/directive'` then `installVRegister(app)`.
35
36
  - Undo/redo ships from its own entry: `import { historyPlugin } from 'attaform/history'`, then `useForm({ schema, history: historyPlugin({ max: 200 }) })` unlocks a live `form.history` namespace (`undo` / `redo` / `clear` / `canUndo` / `canRedo` / `size`). Without the plugin the namespace is inert stubs.
36
37