attaform 0.27.6 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/dist/abstract.d.mts +5 -4
  2. package/dist/abstract.mjs +4 -3
  3. package/dist/chunks/fingerprint.mjs +0 -1
  4. package/dist/chunks/fingerprint2.mjs +1 -2
  5. package/dist/dev/abstract.mjs +4 -0
  6. package/dist/{chunks → dev/chunks}/dev-key-collision-warnings.mjs +0 -1
  7. package/dist/{chunks → dev/chunks}/devtools.mjs +5 -6
  8. package/dist/{chunks/fingerprint.cjs → dev/chunks/fingerprint.mjs} +7 -10
  9. package/dist/{chunks/fingerprint2.cjs → dev/chunks/fingerprint2.mjs} +32 -35
  10. package/dist/dev/directive.mjs +1 -0
  11. package/dist/dev/history.mjs +89 -0
  12. package/dist/dev/index.mjs +5 -0
  13. package/dist/dev/runtime/plugins/attaform.mjs +40 -0
  14. package/dist/{shared/attaform.D6tk90Rc.cjs → dev/shared/attaform-dev.6qxD-Yqo.mjs} +187 -43
  15. package/dist/{shared/attaform.CQN9R62B.cjs → dev/shared/attaform-dev.BJGA_UOS.mjs} +1 -4
  16. package/dist/{shared/attaform.DYEr28Pt.mjs → dev/shared/attaform-dev.BR8u0YOZ.mjs} +6 -7
  17. package/dist/dev/shared/attaform-dev.BXE2cr0L.mjs +220 -0
  18. package/dist/dev/shared/attaform-dev.By4PRjt0.mjs +248 -0
  19. package/dist/{shared/attaform.B1ZYt2Li.mjs → dev/shared/attaform-dev.D2I8e_Mm.mjs} +132 -568
  20. package/dist/dev/shared/attaform-dev.Dr2YzS5B.mjs +197 -0
  21. package/dist/{shared/attaform.nMaz2C5P.mjs → dev/shared/attaform-dev.P7cseiEG.mjs} +178 -397
  22. package/dist/{shared/attaform.CKH2lGdL.mjs → dev/shared/attaform-dev.WmuhD_CZ.mjs} +3944 -5056
  23. package/dist/{shared/attaform.DMxM2kol.mjs → dev/shared/attaform-dev.oYrkP9dj.mjs} +160 -508
  24. package/dist/dev/zod-v3.mjs +17 -0
  25. package/dist/dev/zod-v4.mjs +16 -0
  26. package/dist/dev/zod.mjs +5 -0
  27. package/dist/directive.d.mts +20 -0
  28. package/dist/directive.mjs +1 -0
  29. package/dist/esbuild.mjs +0 -1
  30. package/dist/history.d.mts +59 -0
  31. package/dist/history.mjs +89 -0
  32. package/dist/index.d.mts +11 -5
  33. package/dist/index.mjs +5 -4
  34. package/dist/nuxt.d.mts +1 -1
  35. package/dist/nuxt.mjs +5 -2
  36. package/dist/rollup.mjs +0 -1
  37. package/dist/rspack.d.mts +6 -1
  38. package/dist/rspack.mjs +0 -1
  39. package/dist/runtime/components/AttaformDevtoolsPanel.vue +9 -8
  40. package/dist/runtime/plugins/attaform.mjs +1 -2
  41. package/dist/shared/{attaform.Fp3sCrVs.d.ts → attaform.B4VkS43-.d.mts} +2 -2
  42. package/dist/shared/{attaform.DrvMscNX.cjs → attaform.B8k8JrmK.mjs} +4073 -5630
  43. package/dist/shared/attaform.BJGA_UOS.mjs +0 -1
  44. package/dist/shared/{attaform.CoR4mWfv.mjs → attaform.C09fpdLS.mjs} +172 -16
  45. package/dist/shared/{attaform.D8kliaKw.cjs → attaform.CJP3RkGa.mjs} +141 -590
  46. package/dist/shared/{attaform.DniawQLP.d.cts → attaform.Cgu-hdSb.d.mts} +268 -68
  47. package/dist/shared/attaform.Cs2Rbdlo.mjs +0 -1
  48. package/dist/shared/{attaform.CHlJLAiv.d.mts → attaform.D5V4tZWq.d.mts} +69 -179
  49. package/dist/shared/{attaform.B9Wyhfro.cjs → attaform.D6DCnnQu.mjs} +11 -16
  50. package/dist/shared/attaform.DhnPb6nK.mjs +0 -1
  51. package/dist/shared/attaform.Dq4vWxuG.mjs +197 -0
  52. package/dist/shared/attaform.JfSWdEcb.d.mts +44 -0
  53. package/dist/shared/attaform.KvlEedlF.mjs +0 -1
  54. package/dist/shared/{attaform.DdQN7sgN.cjs → attaform.NLmerepI.mjs} +175 -557
  55. package/dist/shared/attaform.h0i6LijT.mjs +242 -0
  56. package/dist/shared/{attaform.Biytrv0-.cjs → attaform.uLbun31C.mjs} +204 -544
  57. package/dist/shared/attaform.v0fQtWyA.mjs +0 -1
  58. package/dist/shared/attaform.wfY8XFvm.mjs +197 -0
  59. package/dist/transforms.mjs +0 -1
  60. package/dist/vite.d.mts +17 -5
  61. package/dist/vite.mjs +24 -2
  62. package/dist/webpack.d.mts +6 -1
  63. package/dist/webpack.mjs +0 -1
  64. package/dist/zod-v3.d.mts +11 -6
  65. package/dist/zod-v3.mjs +17 -4
  66. package/dist/zod-v4.d.mts +12 -6
  67. package/dist/zod-v4.mjs +16 -4
  68. package/dist/zod.d.mts +4 -3
  69. package/dist/zod.mjs +5 -4
  70. package/package.json +23 -8
  71. package/skills/attaform/SKILL.md +2 -1
  72. package/dist/abstract.cjs +0 -48
  73. package/dist/abstract.cjs.map +0 -1
  74. package/dist/abstract.d.cts +0 -42
  75. package/dist/abstract.d.ts +0 -42
  76. package/dist/abstract.mjs.map +0 -1
  77. package/dist/chunks/dev-key-collision-warnings.cjs +0 -25
  78. package/dist/chunks/dev-key-collision-warnings.cjs.map +0 -1
  79. package/dist/chunks/dev-key-collision-warnings.mjs.map +0 -1
  80. package/dist/chunks/devtools.cjs +0 -157
  81. package/dist/chunks/devtools.cjs.map +0 -1
  82. package/dist/chunks/devtools.mjs.map +0 -1
  83. package/dist/chunks/fingerprint.cjs.map +0 -1
  84. package/dist/chunks/fingerprint.mjs.map +0 -1
  85. package/dist/chunks/fingerprint2.cjs.map +0 -1
  86. package/dist/chunks/fingerprint2.mjs.map +0 -1
  87. package/dist/esbuild.cjs +0 -28
  88. package/dist/esbuild.cjs.map +0 -1
  89. package/dist/esbuild.d.cts +0 -56
  90. package/dist/esbuild.d.ts +0 -56
  91. package/dist/esbuild.mjs.map +0 -1
  92. package/dist/index.cjs +0 -51
  93. package/dist/index.cjs.map +0 -1
  94. package/dist/index.d.cts +0 -249
  95. package/dist/index.d.ts +0 -249
  96. package/dist/index.mjs.map +0 -1
  97. package/dist/nuxt.cjs +0 -84
  98. package/dist/nuxt.cjs.map +0 -1
  99. package/dist/nuxt.d.cts +0 -66
  100. package/dist/nuxt.d.ts +0 -66
  101. package/dist/nuxt.mjs.map +0 -1
  102. package/dist/rollup.cjs +0 -24
  103. package/dist/rollup.cjs.map +0 -1
  104. package/dist/rollup.d.cts +0 -35
  105. package/dist/rollup.d.ts +0 -35
  106. package/dist/rollup.mjs.map +0 -1
  107. package/dist/rspack.cjs +0 -10
  108. package/dist/rspack.cjs.map +0 -1
  109. package/dist/rspack.d.cts +0 -40
  110. package/dist/rspack.d.ts +0 -40
  111. package/dist/rspack.mjs.map +0 -1
  112. package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +0 -7
  113. package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +0 -35
  114. package/dist/runtime/plugins/attaform.cjs +0 -43
  115. package/dist/runtime/plugins/attaform.cjs.map +0 -1
  116. package/dist/runtime/plugins/attaform.d.cts +0 -5
  117. package/dist/runtime/plugins/attaform.d.ts +0 -5
  118. package/dist/runtime/plugins/attaform.mjs.map +0 -1
  119. package/dist/shared/attaform.B1ZYt2Li.mjs.map +0 -1
  120. package/dist/shared/attaform.B9Wyhfro.cjs.map +0 -1
  121. package/dist/shared/attaform.BGDV42hI.d.cts +0 -232
  122. package/dist/shared/attaform.BJGA_UOS.mjs.map +0 -1
  123. package/dist/shared/attaform.Biytrv0-.cjs.map +0 -1
  124. package/dist/shared/attaform.Bn0IzhD_.cjs +0 -800
  125. package/dist/shared/attaform.Bn0IzhD_.cjs.map +0 -1
  126. package/dist/shared/attaform.C9fPTxjB.d.cts +0 -41
  127. package/dist/shared/attaform.C9fPTxjB.d.ts +0 -41
  128. package/dist/shared/attaform.CKH2lGdL.mjs.map +0 -1
  129. package/dist/shared/attaform.CQN9R62B.cjs.map +0 -1
  130. package/dist/shared/attaform.CoR4mWfv.mjs.map +0 -1
  131. package/dist/shared/attaform.Cs2Rbdlo.mjs.map +0 -1
  132. package/dist/shared/attaform.D6tk90Rc.cjs.map +0 -1
  133. package/dist/shared/attaform.D8kliaKw.cjs.map +0 -1
  134. package/dist/shared/attaform.DLknk9nF.d.mts +0 -232
  135. package/dist/shared/attaform.DMxM2kol.mjs.map +0 -1
  136. package/dist/shared/attaform.DRUT703x.d.cts +0 -56
  137. package/dist/shared/attaform.DRUT703x.d.ts +0 -56
  138. package/dist/shared/attaform.DYEr28Pt.mjs.map +0 -1
  139. package/dist/shared/attaform.DdQN7sgN.cjs.map +0 -1
  140. package/dist/shared/attaform.DhnPb6nK.mjs.map +0 -1
  141. package/dist/shared/attaform.DniawQLP.d.mts +0 -4763
  142. package/dist/shared/attaform.DniawQLP.d.ts +0 -4763
  143. package/dist/shared/attaform.DoQm_Vkd.cjs +0 -58
  144. package/dist/shared/attaform.DoQm_Vkd.cjs.map +0 -1
  145. package/dist/shared/attaform.DrvMscNX.cjs.map +0 -1
  146. package/dist/shared/attaform.F2Q8iv38.d.ts +0 -2494
  147. package/dist/shared/attaform.FmqKO1Ex.d.cts +0 -2494
  148. package/dist/shared/attaform.KvlEedlF.mjs.map +0 -1
  149. package/dist/shared/attaform.RaTzp1WF.cjs +0 -26
  150. package/dist/shared/attaform.RaTzp1WF.cjs.map +0 -1
  151. package/dist/shared/attaform.nMaz2C5P.mjs.map +0 -1
  152. package/dist/shared/attaform.v0fQtWyA.mjs.map +0 -1
  153. package/dist/shared/attaform.yUrz7C2z.cjs +0 -29
  154. package/dist/shared/attaform.yUrz7C2z.cjs.map +0 -1
  155. package/dist/transforms.cjs +0 -12
  156. package/dist/transforms.cjs.map +0 -1
  157. package/dist/transforms.d.cts +0 -73
  158. package/dist/transforms.d.ts +0 -73
  159. package/dist/transforms.mjs.map +0 -1
  160. package/dist/vite.cjs +0 -363
  161. package/dist/vite.cjs.map +0 -1
  162. package/dist/vite.d.cts +0 -133
  163. package/dist/vite.d.ts +0 -133
  164. package/dist/vite.mjs.map +0 -1
  165. package/dist/webpack.cjs +0 -10
  166. package/dist/webpack.cjs.map +0 -1
  167. package/dist/webpack.d.cts +0 -37
  168. package/dist/webpack.d.ts +0 -37
  169. package/dist/webpack.mjs.map +0 -1
  170. package/dist/zod-v3.cjs +0 -53
  171. package/dist/zod-v3.cjs.map +0 -1
  172. package/dist/zod-v3.d.cts +0 -246
  173. package/dist/zod-v3.d.ts +0 -246
  174. package/dist/zod-v3.mjs.map +0 -1
  175. package/dist/zod-v4.cjs +0 -55
  176. package/dist/zod-v4.cjs.map +0 -1
  177. package/dist/zod-v4.d.cts +0 -172
  178. package/dist/zod-v4.d.ts +0 -172
  179. package/dist/zod-v4.mjs.map +0 -1
  180. package/dist/zod.cjs +0 -51
  181. package/dist/zod.cjs.map +0 -1
  182. package/dist/zod.d.cts +0 -7
  183. package/dist/zod.d.ts +0 -7
  184. package/dist/zod.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { G as GenericForm, F as FormKey, a as UseFormReturnType, a4 as RegisterValue, T as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, S as Path, a9 as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, af as ValidationError, A as AbstractSchema, aj as WriteMeta, h as DeepPartial, ak as WriteShape, as as TransformAbortHolder, ad as ValidateOn, d as AttaformDefaults, at as RegisterModelDynamicCustomDirective } from './attaform.DniawQLP.mjs';
2
- import { Ref, ComputedRef, App, InjectionKey, Plugin } from 'vue';
1
+ import { G as GenericForm, F as FormKey, a as UseFormReturnType, a5 as RegisterValue, V as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, aa as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, au as FieldRecord, av as ErrorCell, ag as ValidationError, aw as OriginalsRecord, A as AbstractSchema, T as Path, ak as WriteMeta, h as DeepPartial, al as WriteShape, ax as AttaformDomBinding, ay as TransformAbortHolder, ae as ValidateOn, d as AttaformDefaults } from './attaform.Cgu-hdSb.mjs';
2
+ import { Ref, ComputedRef, ShallowRef, App, InjectionKey, Plugin } from 'vue';
3
3
 
4
4
  /**
5
5
  * Options accepted by `injectForm` when passing an object instead of
@@ -206,71 +206,12 @@ type DisplayEngine = {
206
206
  clear(): void;
207
207
  /** Tear down for good: `clear()` plus detaching the visibility listener. */
208
208
  dispose(): void;
209
- /** Introspection for tests: count of retained machines. */
210
- size(): number;
211
- /** Introspection for tests: whether a path currently has a retained machine. */
212
- has(key: PathKey): boolean;
213
- /** Introspection for tests: whether a deadline timer is currently armed. */
214
- hasTimer(): boolean;
215
- };
216
-
217
- /**
218
- * Per-path field status. Replaced wholesale (not mutated in place) on
219
- * every change. Five semantic groups:
220
- *
221
- * - `connected` — is a DOM element registered for this path?
222
- * - `focused` / `blurred` — DOM-state flags. `null` while no element
223
- * is connected (no DOM means the concepts don't apply); plain
224
- * booleans once connected, with the invariant `blurred === !focused`
225
- * enforced by `markFocused`.
226
- * - `touched` — focus/blur history, not DOM state. Always a plain
227
- * boolean: `false` at registration, sticky `true` after first blur,
228
- * cleared only by `form.reset()` / `form.resetField(path)`. Persists
229
- * across disconnects so v-if'd-away fields don't lose their touched
230
- * state on rehide (wizard "show review of touched fields" patterns
231
- * rely on this).
232
- * - `interacted` — value-mutation history, not DOM state. Plain
233
- * boolean: `false` at registration, sticky `true` once the user
234
- * issues a value edit through the directive's input listeners
235
- * (never on hydration, default seeding, or programmatic setValue);
236
- * cleared with `touched` by `form.reset()` / `form.resetField(path)`.
237
- * - `blurredAfterInteraction` — the first blur that follows a value
238
- * edit (the field has been edited and then left). Plain boolean,
239
- * sticky `true`. A tab-through blur with no prior edit does NOT set
240
- * it (`interacted` is still false at that blur). Composes
241
- * `interacted` with the departure; drives the default display gate.
242
- */
243
- type FieldRecord = {
244
- readonly path: Path;
245
- readonly updatedAt: string | null;
246
- readonly connected: boolean;
247
- readonly focused: boolean | null;
248
- readonly blurred: boolean | null;
249
- readonly touched: boolean;
250
- readonly interacted: boolean;
251
- readonly blurredAfterInteraction: boolean;
252
- };
253
- /** Per-path DOM element tracking. Client-only. */
254
- type ElementRecord = {
255
- /**
256
- * Original Path captured at first registration. Stored alongside the
257
- * elements Set so the DOM-order sort cache can recover the structured
258
- * Path without round-tripping through `JSON.parse(pathKey)`.
259
- */
260
- readonly path: Path;
261
- readonly elements: Set<HTMLElement>;
262
- };
263
- /**
264
- * Per-path record stored in `originals`. Pairing `segments` with the tracked
265
- * value means `dirty` and `resetField`'s container loop don't have to
266
- * `JSON.parse(pathKey)` on every iteration — the canonical Path is already
267
- * sitting next to the value it belongs to. PathKey still keys the Map (the
268
- * stable string is the only collision-free identifier), but downstream
269
- * iteration reads `segments` directly.
270
- */
271
- type OriginalsRecord = {
272
- readonly segments: Path;
273
- readonly value: unknown;
209
+ /** Introspection for tests: count of retained machines. Dev builds only. */
210
+ size?(): number;
211
+ /** Introspection for tests: whether a path has a retained machine. Dev builds only. */
212
+ has?(key: PathKey): boolean;
213
+ /** Introspection for tests: whether a deadline timer is armed. Dev builds only. */
214
+ hasTimer?(): boolean;
274
215
  };
275
216
 
276
217
  /**
@@ -327,20 +268,21 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
327
268
  readonly formKey: FormKey;
328
269
  readonly form: Ref<F>;
329
270
  readonly fields: Map<PathKey, FieldRecord>;
330
- readonly elements: Map<PathKey, ElementRecord>;
331
- /**
332
- * Schema-driven errors. Written ONLY by the schema validation pipeline:
333
- * `scheduleFieldValidation`, `handleSubmit`, the construction-time seed,
334
- * history restore, and hydration. Cleared by `reset` / `resetField` and by
335
- * a successful submit. `setErrors` / `clearErrors` do NOT touch this Map.
336
- */
337
- readonly schemaErrors: Map<PathKey, ValidationError[]>;
338
271
  /**
339
- * User-injected errors. Written ONLY by the `setErrors` / `clearErrors`
340
- * API surface (and history / hydration replay). Survives schema revalidation and
272
+ * The tagged error store: one cell per error-bearing path, each cell
273
+ * segregating its two sources. The `schema` side is written ONLY by
274
+ * the validation pipeline (`scheduleFieldValidation`, `handleSubmit`,
275
+ * the construction-time seed, history restore, hydration) and cleared
276
+ * by `reset` / `resetField` and a successful submit; the `user` side
277
+ * is written ONLY by the `setErrors` / `clearErrors` API surface (and
278
+ * history / hydration replay) and survives schema revalidation and
341
279
  * successful submits — the consumer owns its lifetime explicitly.
280
+ * A key exists iff a side is non-empty; cells are replaced, never
281
+ * mutated, so Vue's per-key Map tracking fires for either side's
282
+ * change. Derived blank entries are NOT stored here — they synthesize
283
+ * at read (`derivedBlankErrors`).
342
284
  */
343
- readonly userErrors: Map<PathKey, ValidationError[]>;
285
+ readonly errorCells: Map<PathKey, ErrorCell>;
344
286
  /**
345
287
  * Reactively-derived "No value supplied" errors. Pure function of
346
288
  * `(blankPaths, schema.isRequiredAtPath)` — no writers, no clears.
@@ -538,7 +480,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
538
480
  readonly submissionGeneration: Ref<number>;
539
481
  /**
540
482
  * Counts in-flight validation calls across every `validate()` ref and
541
- * every `validateAsync(...)` / `handleSubmit` pre-check. `validating`
483
+ * every committing `parse(...)` / `handleSubmit` pre-check. `validating`
542
484
  * on the public API mirrors `activeValidations.value > 0`. Tracked
543
485
  * separately from submissions because a validate-while-submitting
544
486
  * (e.g. a debounced field check overlapping a submit) needs to show
@@ -598,7 +540,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
598
540
  * call) and decremented in the matching `.finally` — so the per-path
599
541
  * bookkeeping is exactly co-extensive with the form-wide counter for
600
542
  * the field-scheduled branch. Whole-form `validate()` /
601
- * `validateAsync()` runs touch `activeValidations` only; they don't
543
+ * `parse()` runs touch `activeValidations` only; they don't
602
544
  * have a single field path and so don't contribute here.
603
545
  *
604
546
  * Counter (not Set) because two runs for the same path can briefly
@@ -687,7 +629,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
687
629
  /**
688
630
  * Stable identity for the array element at `path`. An array element
689
631
  * (numeric last segment) carries its allocated identity token,
690
- * maintained by `array-identity.ts` across structural mutations.
632
+ * maintained by the arrays engine across structural mutations.
691
633
  * Empty for any non-array-element path: a record entry, a
692
634
  * fixed-object field, a container, or the root. Backs `FieldState.key`.
693
635
  */
@@ -700,7 +642,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
700
642
  /**
701
643
  * Replace `schemaErrors` under `path` with `errors`, keying each
702
644
  * error by its OWN absolute path. Used by validation pipelines
703
- * (scheduleFieldValidation, validateAsync, handleSubmit, reset)
645
+ * (scheduleFieldValidation, the committing parse, handleSubmit, reset)
704
646
  * to commit a parse result wholesale — entries not in the new
705
647
  * pass get dropped from the subtree, surviving keys update in
706
648
  * place to preserve insertion order. Pass `path === []` for the
@@ -711,10 +653,18 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
711
653
  setUserErrorsForPath(path: Path, errors: readonly ValidationError[]): void;
712
654
  clearUserErrors(path?: Path): void;
713
655
  /**
714
- * Merged read — returns `[...schemaErrors[path], ...userErrors[path]]`.
715
- * Schema errors come first (structural validation before business logic),
716
- * matching the iteration order for `getFirstErrorElement` and the
717
- * top-level `errors` drillable Proxy.
656
+ * Rebuild the whole tagged store from a snapshot's `[key, cell]`
657
+ * entries — the history ring buffer's restore road. Entry arrays are
658
+ * cloned in, so the snapshot stays detached from the live store;
659
+ * cells with both sides empty are skipped.
660
+ */
661
+ restoreErrorCells(entries: ReadonlyArray<readonly [PathKey, ErrorCell]>): void;
662
+ /**
663
+ * Merged read — the cell at `path` in schema -> blank -> user order.
664
+ * Schema errors come first (structural validation before business
665
+ * logic), the derived blank entry synthesizes between, and user
666
+ * entries close, matching the iteration order for
667
+ * `getFirstErrorElement` and the top-level `errors` drillable Proxy.
718
668
  */
719
669
  getErrorsForPath(path: Path): ValidationError[];
720
670
  /**
@@ -729,15 +679,29 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
729
679
  */
730
680
  ensurePathOrdinal(key: PathKey): number;
731
681
  /**
732
- * Register `element` as a binding for `path`, tagged with the calling
733
- * `useForm()` instance's `formInstanceId`. The ID is the disambiguator
734
- * used by `getFirstErrorElement` to scope focus / scroll to elements
735
- * THIS form instance owns — important when two `useForm()` calls share
736
- * a `key` (e.g. sidebar + main rendering the same form), since both
737
- * write into one shared element store.
682
+ * The store's DOM slice, `null` until the directive cluster or
683
+ * `useRegister` arms it via `RegisterValue.ensureDomBinding`. Element
684
+ * registration, host anchors, and first-error focus resolution all
685
+ * live behind it; eager readers treat `null` as an empty registry.
686
+ */
687
+ readonly domBinding: ShallowRef<AttaformDomBinding | null>;
688
+ /**
689
+ * Field-record connect transition, driven by the DOM binding on
690
+ * element attach / host connect (and by the SSR-only
691
+ * `markConnectedOptimistically`): `connected: true`, with
692
+ * `focused` / `blurred` lifted from `null` to optimistic booleans
693
+ * only when currently null — an existing boolean from an early focus
694
+ * event is never clobbered.
738
695
  */
739
- registerElement(path: Path, element: HTMLElement, formInstanceId: string): boolean;
740
- deregisterElement(path: Path, element: HTMLElement): number;
696
+ noteDomConnected(path: Path): void;
697
+ /**
698
+ * Field-record disconnect transition, driven by the DOM binding when
699
+ * a path's last element detaches or its host disconnects:
700
+ * `connected: false`, `focused` / `blurred` back to `null` (DOM-state
701
+ * properties are meaningless with nothing attached; interaction
702
+ * history stays).
703
+ */
704
+ noteDomDisconnected(path: Path): void;
741
705
  /**
742
706
  * Optional `meta.instance` carries per-`useForm()`-instance overrides
743
707
  * for `validateOn` / `debounceMs` so the blur-trigger respects the
@@ -777,20 +741,6 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
777
741
  * source there).
778
742
  */
779
743
  markConnectedOptimistically(path: Path): void;
780
- /**
781
- * Client-side connected mark for a `v-register` component host that binds
782
- * value via the v-model channel but has no single inner control to latch
783
- * (a composite widget, or none found). The directive calls it on mount
784
- * (`true`) and unmount (`false`). Distinct from the SSR-only
785
- * `markConnectedOptimistically`; idempotent on the leading edge.
786
- *
787
- * `hostEl` (the host root) is recorded on connect as this path's
788
- * focus-first-error anchor, scoped to `formInstanceId` the same way a
789
- * registered control is. A no-latch host enters no `elements` record, so
790
- * without this it is absent from `getFirstErrorElement`'s walk; the anchor
791
- * lets that walk resolve a focus target from the host subtree.
792
- */
793
- markHostConnected(path: Path, connected: boolean, hostEl: HTMLElement, formInstanceId: string): void;
794
744
  /**
795
745
  * Leaf-only pristine check. `originals` is populated via
796
746
  * `diffAndApply`'s `added` patches, which fire only on primitive
@@ -829,33 +779,6 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
829
779
  hasRemovedSubtreeUnder(path: Path): boolean;
830
780
  getFieldRecord(path: Path): FieldRecord | undefined;
831
781
  getOriginalAtPath(path: Path): unknown;
832
- /**
833
- * Returns the first errored field's first connected, visible DOM
834
- * element scoped to `formInstanceId` — the target that
835
- * `focusFirstError` / `scrollToFirstError` act on. "First" is
836
- * VISUAL-first (DOM-tree order via `compareDocumentPosition`), not
837
- * schema-declaration order, so a field rendered above another in the
838
- * template focuses first regardless of which one the schema declared
839
- * earlier. CSS `order:` flexbox/grid reordering is NOT respected
840
- * (DOM-tree order wins) — documented as a tradeoff against forcing
841
- * sync layout on every comparison.
842
- *
843
- * The `formInstanceId` filter scopes focus to elements registered
844
- * through THIS form instance. When two `useForm({ key })` calls share
845
- * a key, both register into the same element store; without the
846
- * filter, the sidebar form's submit could focus the main form's
847
- * input. With it, each `useForm()` callsite focuses only its own
848
- * elements.
849
- *
850
- * Returns `null` when every errored path has no currently-attached
851
- * element registered to this instance (fields behind `v-if="false"`,
852
- * unmounted components, or a hidden `display:none` parent). Callers
853
- * get the choice of no-op or a dev-only warning.
854
- */
855
- getFirstErrorElement(formInstanceId: string): {
856
- path: Path;
857
- element: HTMLElement;
858
- } | null;
859
782
  /**
860
783
  * Cancel every in-flight field-level validation run — clears timers
861
784
  * for debounced 'change' runs that haven't fired, latches `aborted`
@@ -958,21 +881,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
958
881
  */
959
882
  registerCleanup(fn: () => void): void;
960
883
  /**
961
- * Register an async drain function. Called by the registry before
962
- * `dispose()` so async background work — chiefly the persistence
963
- * layer's debounced storage writes — has a chance to settle without
964
- * losing the last keystroke. Each registered function is awaited in
965
- * parallel; failures are swallowed to keep eviction reliable.
966
- */
967
- registerDrain(fn: () => Promise<void>): void;
968
- /**
969
- * Drain async work registered via `registerDrain`. Resolves once
970
- * every registered drain has settled (in parallel). Safe to call
971
- * repeatedly — registered drains decide their own idempotency.
972
- */
973
- awaitPendingWrites(): Promise<void>;
974
- /**
975
- * Cache for per-state modules (history, persistence) that must
884
+ * Cache for per-state modules (chiefly history) that must
976
885
  * outlive any single consumer. Subsequent `useForm` / `injectForm`
977
886
  * calls for the same key read from this map so the public API shape
978
887
  * is identical regardless of mount order. Keyed by a string identifier
@@ -1783,13 +1692,6 @@ type AttaformRegistry = {
1783
1692
  * @internal
1784
1693
  */
1785
1694
  readonly shouldPrefetch: (key: FormKey) => boolean;
1786
- /**
1787
- * Wait for all pending persistence writes across every live form
1788
- * to settle. Useful for SSR shutdown and integration tests that
1789
- * need a deterministic teardown.
1790
- * @internal
1791
- */
1792
- readonly shutdown: () => Promise<void>;
1793
1695
  };
1794
1696
  /**
1795
1697
  * The Vue `InjectionKey` under which the registry is provided on the
@@ -2167,6 +2069,8 @@ declare function createAttaform(options?: AttaformPluginOptions): Plugin;
2167
2069
  * serialiser before embedding in your SSR payload.
2168
2070
  */
2169
2071
  type SerializedAttaformState = {
2072
+ /** Envelope version — see {@link ATTAFORM_STATE_VERSION}. */
2073
+ readonly v: number;
2170
2074
  /** Tuples of `[formKey, snapshot]` for every form in the app. */
2171
2075
  readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>;
2172
2076
  };
@@ -2206,10 +2110,16 @@ declare function renderAttaformState(app: App): SerializedAttaformState;
2206
2110
  * app.mount('#app')
2207
2111
  * ```
2208
2112
  *
2113
+ * Accepts `unknown` because the payload crosses the wire untyped
2114
+ * (an inline `<script>` tag, `JSON.parse`): the envelope is
2115
+ * validated at runtime, and anything that isn't a version-matched
2116
+ * `renderAttaformState` snapshot is skipped wholesale, so forms
2117
+ * construct fresh from their schemas instead.
2118
+ *
2209
2119
  * The next `useForm({ key })` call for each serialised form picks up
2210
2120
  * the snapshot transparently — no further action is required.
2211
2121
  */
2212
- declare function hydrateAttaformState(app: App, payload: SerializedAttaformState): void;
2122
+ declare function hydrateAttaformState(app: App, payload: unknown): void;
2213
2123
 
2214
2124
  /**
2215
2125
  * Escape a JSON string so it's safe to embed inside an inline
@@ -2242,26 +2152,6 @@ declare function escapeForInlineScript(json: string): string;
2242
2152
  */
2243
2153
  declare const assignKey: unique symbol;
2244
2154
 
2245
- /**
2246
- * The `v-register` directive. Bind a form field to a native input,
2247
- * select, textarea, checkbox, or radio:
2248
- *
2249
- * ```vue
2250
- * <input v-register="form.register('email')" />
2251
- * <select v-register="form.register('country')">
2252
- * <option value="us">US</option>
2253
- * <option value="uk">UK</option>
2254
- * </select>
2255
- * ```
2256
- *
2257
- * The directive picks the right binding strategy automatically based
2258
- * on the element's `tagName` and `type`. Registered globally by
2259
- * `createAttaform()`. Most consumers never import it directly, but
2260
- * it's exposed for advanced integrations that wire directives
2261
- * manually.
2262
- */
2263
- declare const vRegister: RegisterModelDynamicCustomDirective;
2264
-
2265
2155
  /**
2266
2156
  * Type guard for a `RegisterValue`. Returns `true` when `val` looks
2267
2157
  * like the object returned from `form.register(path)`.
@@ -2490,5 +2380,5 @@ declare function makeDefaultDisplayState({ showDelay, minVisible, }: DisplayTimi
2490
2380
  */
2491
2381
  declare const defaultDisplayState: GetDisplayState;
2492
2382
 
2493
- export { renderAttaformState as $, createAttaform as B, DEFAULT_TIMINGS as D, createRegistry as E, defaultCoercionRules as H, defaultDisplayState as J, defineCoercion as K, escapeForInlineScript as M, gate as N, OutsideSetupError as O, getRegistryFromApp as P, hydrateAttaformState as Q, RegistryNotInstalledError as R, injectForm as T, injectWizard as V, isRegisterValue as X, kAttaformRegistry as Y, lazy as Z, makeDefaultDisplayState as _, useRegister as a0, useRegistry as a1, useWizard as a2, vRegister as a3, AttaformError as c, AttaformErrorCode as d, DEVTOOLS_WINDOW_KEY as f, InvalidPathError as i, InvalidUseFormConfigError as j, ReservedFormKeyError as k, SubmitErrorHandlerError as n, assignKey as z };
2383
+ export { renderAttaformState as $, createAttaform as B, DEFAULT_TIMINGS as D, createRegistry as E, defaultCoercionRules as H, defaultDisplayState as J, defineCoercion as K, escapeForInlineScript as M, gate as N, OutsideSetupError as O, getRegistryFromApp as P, hydrateAttaformState as Q, RegistryNotInstalledError as R, injectForm as T, injectWizard as V, isRegisterValue as X, kAttaformRegistry as Y, lazy as Z, makeDefaultDisplayState as _, useRegister as a0, useRegistry as a1, useWizard as a2, AttaformError as c, AttaformErrorCode as d, DEVTOOLS_WINDOW_KEY as f, InvalidPathError as i, InvalidUseFormConfigError as j, ReservedFormKeyError as k, SubmitErrorHandlerError as n, assignKey as z };
2494
2384
  export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, GateMarker as G, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterReturn as U, WizardAggregateError as W, AnyForm as a, AttaformDevtoolsBridge as b, AttaformPluginOptions as e, DisplayTimings as g, FormStatusSeed as h, SerializedFormData as l, StepSlot as m, UseWizardReturnType as o, WizardCtx as p, WizardCtxForm as q, WizardOnError as r, WizardOnSubmit as s, WizardOptions as t, WizardPersistFn as u, WizardRestoreFn as v, WizardRestoreState as w, WizardStatusesProxy as x, WizardSubmitContext as y };
@@ -1,9 +1,7 @@
1
- 'use strict';
2
-
3
- const devtoolsShared = require('./attaform.Biytrv0-.cjs');
4
- const useForm$1 = require('./attaform.D8kliaKw.cjs');
5
- const index = require('./attaform.DdQN7sgN.cjs');
6
- const walkFieldMeta = require('./attaform.D6tk90Rc.cjs');
1
+ import { a as InvalidUseFormConfigError } from './attaform.wfY8XFvm.mjs';
2
+ import { u as useForm$2 } from './attaform.CJP3RkGa.mjs';
3
+ import { u as useForm$1 } from './attaform.NLmerepI.mjs';
4
+ import { i as installingFieldMetaStore, g as getFieldMetaForSchema } from './attaform.C09fpdLS.mjs';
7
5
 
8
6
  function isZodV4SchemaShape(value) {
9
7
  if (typeof value !== "object" || value === null) return false;
@@ -14,21 +12,21 @@ function isZodV4SchemaShape(value) {
14
12
 
15
13
  function useForm(configuration) {
16
14
  if (configuration === void 0 || configuration === null || configuration.schema === void 0) {
17
- throw new devtoolsShared.InvalidUseFormConfigError();
15
+ throw new InvalidUseFormConfigError();
18
16
  }
19
17
  const { schema } = configuration;
20
18
  if (isZodV4SchemaShape(schema)) {
21
- return index.useForm(configuration);
19
+ return useForm$1(configuration);
22
20
  }
23
- return useForm$1.useForm(configuration);
21
+ return useForm$2(configuration);
24
22
  }
25
23
 
26
- const fieldMeta = walkFieldMeta.fieldMetaStore;
24
+ const fieldMeta = installingFieldMetaStore;
27
25
  function withMeta(schema, payload) {
28
26
  const target = schema;
29
- const existing = walkFieldMeta.getFieldMetaForSchema(target) ?? {};
27
+ const existing = getFieldMetaForSchema(target) ?? {};
30
28
  const cloned = cloneSchema(schema);
31
- walkFieldMeta.fieldMetaStore.add(cloned, { ...existing, ...payload });
29
+ installingFieldMetaStore.add(cloned, { ...existing, ...payload });
32
30
  return cloned;
33
31
  }
34
32
  function cloneSchema(schema) {
@@ -40,7 +38,4 @@ function cloneSchema(schema) {
40
38
  return new Ctor(candidate._def);
41
39
  }
42
40
 
43
- exports.fieldMeta = fieldMeta;
44
- exports.useForm = useForm;
45
- exports.withMeta = withMeta;
46
- //# sourceMappingURL=attaform.B9Wyhfro.cjs.map
41
+ export { fieldMeta as f, useForm as u, withMeta as w };
@@ -51,4 +51,3 @@ function resolveZodAliasTarget(consumerRootDir, tag, resolveZodAlias, warnState)
51
51
  }
52
52
 
53
53
  export { REWRITABLE_ZOD_SPECIFIER_FILTER as R, isRewritableZodSpecifier as i, resolveZodAliasTarget as r };
54
- //# sourceMappingURL=attaform.DhnPb6nK.mjs.map
@@ -0,0 +1,197 @@
1
+ import { c as RegistryNotInstalledError, O as OutsideSetupError, g as pathKeyToDotted } from './attaform.wfY8XFvm.mjs';
2
+ import { shallowReactive, getCurrentInstance, inject } from 'vue';
3
+
4
+ function detectSSR(options = {}) {
5
+ if (options.ssr !== void 0) return options.ssr;
6
+ return typeof window === "undefined" && typeof document === "undefined";
7
+ }
8
+
9
+ const kAttaformRegistry = /* @__PURE__ */ Symbol.for("attaform:registry");
10
+ const kAttaformAncestorWizard = /* @__PURE__ */ Symbol.for(
11
+ "attaform:ancestor-wizard"
12
+ );
13
+ const kAttaformWizardActiveStepResolver = /* @__PURE__ */ Symbol.for(
14
+ "attaform:wizard-active-step-resolver"
15
+ );
16
+ const kFormContext = /* @__PURE__ */ Symbol.for("attaform:form-context");
17
+ const kFormInstanceId = /* @__PURE__ */ Symbol.for("attaform:form-instance-id");
18
+ function createRegistry(options = {}) {
19
+ const ssr = detectSSR(options);
20
+ const defaults = Object.freeze({ ...options.defaults ?? {} });
21
+ const forms = shallowReactive(/* @__PURE__ */ new Map());
22
+ const wizards = shallowReactive(/* @__PURE__ */ new Map());
23
+ const pendingHydration = shallowReactive(/* @__PURE__ */ new Map());
24
+ const consumers = /* @__PURE__ */ new Map();
25
+ const pendingEvictions = /* @__PURE__ */ new Map();
26
+ function cancelPendingEviction(key) {
27
+ const pending = pendingEvictions.get(key);
28
+ if (pending === void 0) return;
29
+ pending.cancelled = true;
30
+ pendingEvictions.delete(key);
31
+ }
32
+ function trackConsumer(key) {
33
+ cancelPendingEviction(key);
34
+ consumers.set(key, (consumers.get(key) ?? 0) + 1);
35
+ let disposed = false;
36
+ return () => {
37
+ if (disposed) return;
38
+ disposed = true;
39
+ const remaining = (consumers.get(key) ?? 1) - 1;
40
+ if (remaining > 0) {
41
+ consumers.set(key, remaining);
42
+ return;
43
+ }
44
+ consumers.delete(key);
45
+ const token = { cancelled: false };
46
+ pendingEvictions.set(key, token);
47
+ queueMicrotask(() => {
48
+ if (token.cancelled) return;
49
+ if (pendingEvictions.get(key) !== token) return;
50
+ pendingEvictions.delete(key);
51
+ const state = forms.get(key);
52
+ forms.delete(key);
53
+ if (state === void 0) return;
54
+ state.dispose();
55
+ });
56
+ };
57
+ }
58
+ const wizardConsumers = /* @__PURE__ */ new Map();
59
+ const pendingWizardEvictions = /* @__PURE__ */ new Map();
60
+ function cancelPendingWizardEviction(key) {
61
+ const pending = pendingWizardEvictions.get(key);
62
+ if (pending === void 0) return;
63
+ pending.cancelled = true;
64
+ pendingWizardEvictions.delete(key);
65
+ }
66
+ function trackWizardConsumer(key) {
67
+ cancelPendingWizardEviction(key);
68
+ wizardConsumers.set(key, (wizardConsumers.get(key) ?? 0) + 1);
69
+ let disposed = false;
70
+ return () => {
71
+ if (disposed) return;
72
+ disposed = true;
73
+ const remaining = (wizardConsumers.get(key) ?? 1) - 1;
74
+ if (remaining > 0) {
75
+ wizardConsumers.set(key, remaining);
76
+ return;
77
+ }
78
+ wizardConsumers.delete(key);
79
+ const token = { cancelled: false };
80
+ pendingWizardEvictions.set(key, token);
81
+ queueMicrotask(() => {
82
+ if (token.cancelled) return;
83
+ if (pendingWizardEvictions.get(key) !== token) return;
84
+ pendingWizardEvictions.delete(key);
85
+ wizards.delete(key);
86
+ });
87
+ };
88
+ }
89
+ const prefetchEnqueued = /* @__PURE__ */ new Set();
90
+ const prefetchSkipped = /* @__PURE__ */ new Set();
91
+ function enqueuePrefetch(key) {
92
+ prefetchEnqueued.add(key);
93
+ }
94
+ function skipPrefetch(key) {
95
+ prefetchSkipped.add(key);
96
+ }
97
+ function shouldPrefetch(key) {
98
+ return prefetchEnqueued.has(key) && !prefetchSkipped.has(key);
99
+ }
100
+ return {
101
+ forms,
102
+ wizards,
103
+ pendingHydration,
104
+ ssr,
105
+ defaults,
106
+ trackConsumer,
107
+ trackWizardConsumer,
108
+ enqueuePrefetch,
109
+ skipPrefetch,
110
+ shouldPrefetch
111
+ };
112
+ }
113
+ function useRegistry() {
114
+ const instance = getCurrentInstance();
115
+ if (instance === null) {
116
+ throw new OutsideSetupError();
117
+ }
118
+ const registry = inject(kAttaformRegistry, null);
119
+ if (registry === null) {
120
+ throw new RegistryNotInstalledError();
121
+ }
122
+ return registry;
123
+ }
124
+ function getRegistryFromApp(app) {
125
+ const registry = app._attaform;
126
+ if (registry === void 0) {
127
+ throw new RegistryNotInstalledError();
128
+ }
129
+ return registry;
130
+ }
131
+ function attachRegistryToApp(app, registry) {
132
+ app.provide(kAttaformRegistry, registry);
133
+ app._attaform = registry;
134
+ }
135
+
136
+ function installAttaformOnApp(app, options, source) {
137
+ if (app._attaform !== void 0) {
138
+ return app._attaform;
139
+ }
140
+ const registry = createRegistry(options);
141
+ attachRegistryToApp(app, registry);
142
+ return registry;
143
+ }
144
+ function ensureAttaformInstalled(app) {
145
+ return installAttaformOnApp(app, {});
146
+ }
147
+ function createAttaform(options = {}) {
148
+ const plugin = {
149
+ install(app) {
150
+ installAttaformOnApp(app, options);
151
+ }
152
+ };
153
+ return plugin;
154
+ }
155
+
156
+ const ATTAFORM_STATE_VERSION = 1;
157
+ function renderAttaformState(app) {
158
+ const registry = getRegistryFromApp(app);
159
+ const forms = [];
160
+ for (const [key, state] of registry.forms) {
161
+ const transientList = [];
162
+ for (const pk of state.blankPaths) {
163
+ const d = pathKeyToDotted(pk);
164
+ if (d !== null) transientList.push(d);
165
+ }
166
+ forms.push([
167
+ key,
168
+ {
169
+ form: state.form.value,
170
+ // The wire shape stays two per-source arrays; the tagged store
171
+ // splits at the boundary and the client replays each side into
172
+ // its cell half.
173
+ schemaErrors: [...state.errorCells.entries()].filter(([, cell]) => cell.schema.length > 0).map(([key2, cell]) => [key2, cell.schema]),
174
+ userErrors: [...state.errorCells.entries()].filter(([, cell]) => cell.user.length > 0).map(([key2, cell]) => [key2, cell.user]),
175
+ fields: Array.from(state.fields.entries()),
176
+ ...transientList.length > 0 ? { blankPaths: transientList } : {}
177
+ }
178
+ ]);
179
+ }
180
+ return { v: ATTAFORM_STATE_VERSION, forms };
181
+ }
182
+ function hydrateAttaformState(app, payload) {
183
+ if (!isHydratableEnvelope(payload)) {
184
+ return;
185
+ }
186
+ const registry = getRegistryFromApp(app);
187
+ for (const [key, data] of payload.forms) {
188
+ registry.pendingHydration.set(key, data);
189
+ }
190
+ }
191
+ function isHydratableEnvelope(payload) {
192
+ return payload !== null && typeof payload === "object" && "v" in payload && payload.v === ATTAFORM_STATE_VERSION && "forms" in payload && Array.isArray(payload.forms);
193
+ }
194
+
195
+ const DEVTOOLS_WINDOW_KEY = "__attaform_devtools__";
196
+
197
+ export { DEVTOOLS_WINDOW_KEY as D, createRegistry as a, kAttaformWizardActiveStepResolver as b, createAttaform as c, kFormContext as d, ensureAttaformInstalled as e, kFormInstanceId as f, getRegistryFromApp as g, hydrateAttaformState as h, kAttaformAncestorWizard as i, kAttaformRegistry as k, renderAttaformState as r, useRegistry as u };
@@ -0,0 +1,44 @@
1
+ import { App } from 'vue';
2
+ import { ar as RegisterModelDynamicCustomDirective } from './attaform.Cgu-hdSb.mjs';
3
+
4
+ /**
5
+ * The `v-register` directive. Bind a form field to a native input,
6
+ * select, textarea, checkbox, or radio:
7
+ *
8
+ * ```vue
9
+ * <input v-register="form.register('email')" />
10
+ * <select v-register="form.register('country')">
11
+ * <option value="us">US</option>
12
+ * <option value="uk">UK</option>
13
+ * </select>
14
+ * ```
15
+ *
16
+ * The directive picks the right binding strategy automatically based
17
+ * on the element's `tagName` and `type`. Delivered by the Vite / Nuxt
18
+ * plugin's compile-time binding, or by `installVRegister(app)`
19
+ * everywhere else. Most consumers never import it directly, but it's
20
+ * exposed for advanced integrations that wire directives manually.
21
+ */
22
+ declare const vRegister: RegisterModelDynamicCustomDirective;
23
+ /**
24
+ * Register the `v-register` directive app-wide. The one-line setup for
25
+ * apps whose templates are compiled without Attaform's Vite or Nuxt
26
+ * plugin — a webpack-family bundler, a no-build / CDN page, or
27
+ * runtime-compiled templates:
28
+ *
29
+ * ```ts
30
+ * import { createApp } from 'vue'
31
+ * import { installVRegister } from 'attaform/directive'
32
+ *
33
+ * const app = createApp(App)
34
+ * installVRegister(app)
35
+ * ```
36
+ *
37
+ * Vite and Nuxt consumers don't call this: the build plugin binds each
38
+ * template's `v-register` to the directive at compile time. Idempotent —
39
+ * a second call for the same app is a no-op, and an app-level directive
40
+ * a consumer registered under the same name is left in place.
41
+ */
42
+ declare function installVRegister(app: App): void;
43
+
44
+ export { installVRegister as i, vRegister as v };
@@ -19,4 +19,3 @@ function isTransforming(value) {
19
19
  }
20
20
 
21
21
  export { REGISTER_OWNER_MARKER as R, SSR_COMPONENT_HOST_MODIFIER as S, V_REGISTER_COMPILED_MODIFIER as V, isTransforming as a, V_REGISTER_MARKER as b, isRegisterValue as i };
22
- //# sourceMappingURL=attaform.KvlEedlF.mjs.map