attaform 0.27.6 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abstract.d.mts +5 -4
- package/dist/abstract.mjs +4 -3
- package/dist/chunks/fingerprint.mjs +1 -2
- package/dist/chunks/fingerprint2.mjs +2 -3
- package/dist/dev/abstract.mjs +4 -0
- package/dist/{chunks → dev/chunks}/dev-key-collision-warnings.mjs +0 -1
- package/dist/{chunks → dev/chunks}/devtools.mjs +5 -6
- package/dist/{chunks/fingerprint.cjs → dev/chunks/fingerprint.mjs} +7 -10
- package/dist/{chunks/fingerprint2.cjs → dev/chunks/fingerprint2.mjs} +32 -35
- package/dist/dev/directive.mjs +1 -0
- package/dist/dev/history.mjs +89 -0
- package/dist/dev/index.mjs +5 -0
- package/dist/dev/runtime/plugins/attaform.mjs +40 -0
- package/dist/dev/shared/attaform-dev.A-TpJW0B.mjs +207 -0
- package/dist/dev/shared/attaform-dev.BO-71R54.mjs +820 -0
- package/dist/{shared/attaform.D6tk90Rc.cjs → dev/shared/attaform-dev.BgM6FdtA.mjs} +324 -73
- package/dist/dev/shared/attaform-dev.ButTkwHd.mjs +375 -0
- package/dist/{shared/attaform.BJGA_UOS.mjs → dev/shared/attaform-dev.BxfsuwBR.mjs} +8 -1
- package/dist/{shared/attaform.nMaz2C5P.mjs → dev/shared/attaform-dev.D8aoKb89.mjs} +190 -400
- package/dist/dev/shared/attaform-dev.DD5m2W51.mjs +220 -0
- package/dist/{shared/attaform.CKH2lGdL.mjs → dev/shared/attaform-dev.DHuydLAC.mjs} +3867 -4731
- package/dist/{shared/attaform.DYEr28Pt.mjs → dev/shared/attaform-dev.DrzObAZo.mjs} +6 -7
- package/dist/{shared/attaform.B1ZYt2Li.mjs → dev/shared/attaform-dev.q6UutkCx.mjs} +274 -672
- package/dist/dev/zod-v3.mjs +17 -0
- package/dist/dev/zod-v4.mjs +16 -0
- package/dist/dev/zod.mjs +5 -0
- package/dist/directive.d.mts +20 -0
- package/dist/directive.mjs +1 -0
- package/dist/esbuild.mjs +0 -1
- package/dist/history.d.mts +59 -0
- package/dist/history.mjs +89 -0
- package/dist/index.d.mts +14 -6
- package/dist/index.mjs +5 -4
- package/dist/nuxt.d.mts +10 -10
- package/dist/nuxt.mjs +5 -2
- package/dist/rollup.mjs +0 -1
- package/dist/rspack.d.mts +6 -1
- package/dist/rspack.mjs +0 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +9 -8
- package/dist/runtime/plugins/attaform.mjs +1 -2
- package/dist/shared/{attaform.CoR4mWfv.mjs → attaform.B0dKL8ST.mjs} +309 -46
- package/dist/shared/{attaform.Cs2Rbdlo.mjs → attaform.BK0cgu2K.mjs} +123 -140
- package/dist/shared/{attaform.B9Wyhfro.cjs → attaform.BndjUUYX.mjs} +11 -16
- package/dist/shared/{attaform.CQN9R62B.cjs → attaform.BxfsuwBR.mjs} +9 -4
- package/dist/shared/attaform.C2MVyuxC.mjs +811 -0
- package/dist/shared/{attaform.Fp3sCrVs.d.ts → attaform.CIWLMY-R.d.mts} +2 -2
- package/dist/shared/attaform.CZMAYwSK.mjs +6383 -0
- package/dist/shared/attaform.CZYt_5N_.mjs +207 -0
- package/dist/shared/{attaform.DniawQLP.d.cts → attaform.CsoeRi3P.d.mts} +490 -98
- package/dist/shared/attaform.Cvao8bW5.mjs +358 -0
- package/dist/shared/attaform.D0x-qSXm.mjs +197 -0
- package/dist/shared/{attaform.D8kliaKw.cjs → attaform.D1fnTifF.mjs} +279 -692
- package/dist/shared/{attaform.CHlJLAiv.d.mts → attaform.DDtqHYv1.d.mts} +155 -184
- package/dist/shared/{attaform.Biytrv0-.cjs → attaform.DffRL5pP.mjs} +215 -547
- package/dist/shared/attaform.DhnPb6nK.mjs +0 -1
- package/dist/shared/attaform.KvlEedlF.mjs +0 -1
- package/dist/shared/attaform.axHXVQO7.d.mts +44 -0
- package/dist/shared/attaform.v0fQtWyA.mjs +0 -1
- package/dist/transforms.d.mts +0 -22
- package/dist/transforms.mjs +1 -2
- package/dist/vite.d.mts +30 -9
- package/dist/vite.mjs +27 -4
- package/dist/webpack.d.mts +6 -1
- package/dist/webpack.mjs +0 -1
- package/dist/zod-v3.d.mts +13 -6
- package/dist/zod-v3.mjs +17 -4
- package/dist/zod-v4.d.mts +19 -26
- package/dist/zod-v4.mjs +16 -4
- package/dist/zod.d.mts +4 -3
- package/dist/zod.mjs +5 -4
- package/package.json +38 -20
- package/skills/attaform/SKILL.md +6 -2
- package/skills/attaform/references/custom-components.md +7 -2
- package/skills/attaform/references/errors.md +8 -3
- package/skills/attaform/references/saving.md +77 -0
- package/skills/attaform/references/wizards.md +10 -8
- package/dist/abstract.cjs +0 -48
- package/dist/abstract.cjs.map +0 -1
- package/dist/abstract.d.cts +0 -42
- package/dist/abstract.d.ts +0 -42
- package/dist/abstract.mjs.map +0 -1
- package/dist/chunks/dev-key-collision-warnings.cjs +0 -25
- package/dist/chunks/dev-key-collision-warnings.cjs.map +0 -1
- package/dist/chunks/dev-key-collision-warnings.mjs.map +0 -1
- package/dist/chunks/devtools.cjs +0 -157
- package/dist/chunks/devtools.cjs.map +0 -1
- package/dist/chunks/devtools.mjs.map +0 -1
- package/dist/chunks/fingerprint.cjs.map +0 -1
- package/dist/chunks/fingerprint.mjs.map +0 -1
- package/dist/chunks/fingerprint2.cjs.map +0 -1
- package/dist/chunks/fingerprint2.mjs.map +0 -1
- package/dist/esbuild.cjs +0 -28
- package/dist/esbuild.cjs.map +0 -1
- package/dist/esbuild.d.cts +0 -56
- package/dist/esbuild.d.ts +0 -56
- package/dist/esbuild.mjs.map +0 -1
- package/dist/index.cjs +0 -51
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -249
- package/dist/index.d.ts +0 -249
- package/dist/index.mjs.map +0 -1
- package/dist/nuxt.cjs +0 -84
- package/dist/nuxt.cjs.map +0 -1
- package/dist/nuxt.d.cts +0 -66
- package/dist/nuxt.d.ts +0 -66
- package/dist/nuxt.mjs.map +0 -1
- package/dist/rollup.cjs +0 -24
- package/dist/rollup.cjs.map +0 -1
- package/dist/rollup.d.cts +0 -35
- package/dist/rollup.d.ts +0 -35
- package/dist/rollup.mjs.map +0 -1
- package/dist/rspack.cjs +0 -10
- package/dist/rspack.cjs.map +0 -1
- package/dist/rspack.d.cts +0 -40
- package/dist/rspack.d.ts +0 -40
- package/dist/rspack.mjs.map +0 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue.d.ts +0 -7
- package/dist/runtime/components/DevtoolsValueTree.vue.d.ts +0 -35
- package/dist/runtime/plugins/attaform.cjs +0 -43
- package/dist/runtime/plugins/attaform.cjs.map +0 -1
- package/dist/runtime/plugins/attaform.d.cts +0 -5
- package/dist/runtime/plugins/attaform.d.ts +0 -5
- package/dist/runtime/plugins/attaform.mjs.map +0 -1
- package/dist/shared/attaform.B1ZYt2Li.mjs.map +0 -1
- package/dist/shared/attaform.B9Wyhfro.cjs.map +0 -1
- package/dist/shared/attaform.BGDV42hI.d.cts +0 -232
- package/dist/shared/attaform.BJGA_UOS.mjs.map +0 -1
- package/dist/shared/attaform.Biytrv0-.cjs.map +0 -1
- package/dist/shared/attaform.Bn0IzhD_.cjs +0 -800
- package/dist/shared/attaform.Bn0IzhD_.cjs.map +0 -1
- package/dist/shared/attaform.C9fPTxjB.d.cts +0 -41
- package/dist/shared/attaform.C9fPTxjB.d.ts +0 -41
- package/dist/shared/attaform.CKH2lGdL.mjs.map +0 -1
- package/dist/shared/attaform.CQN9R62B.cjs.map +0 -1
- package/dist/shared/attaform.CoR4mWfv.mjs.map +0 -1
- package/dist/shared/attaform.Cs2Rbdlo.mjs.map +0 -1
- package/dist/shared/attaform.D6tk90Rc.cjs.map +0 -1
- package/dist/shared/attaform.D8kliaKw.cjs.map +0 -1
- package/dist/shared/attaform.DLknk9nF.d.mts +0 -232
- package/dist/shared/attaform.DMxM2kol.mjs +0 -1275
- package/dist/shared/attaform.DMxM2kol.mjs.map +0 -1
- package/dist/shared/attaform.DRUT703x.d.cts +0 -56
- package/dist/shared/attaform.DRUT703x.d.ts +0 -56
- package/dist/shared/attaform.DYEr28Pt.mjs.map +0 -1
- package/dist/shared/attaform.DdQN7sgN.cjs +0 -1302
- package/dist/shared/attaform.DdQN7sgN.cjs.map +0 -1
- package/dist/shared/attaform.DhnPb6nK.mjs.map +0 -1
- package/dist/shared/attaform.DniawQLP.d.mts +0 -4763
- package/dist/shared/attaform.DniawQLP.d.ts +0 -4763
- package/dist/shared/attaform.DoQm_Vkd.cjs +0 -58
- package/dist/shared/attaform.DoQm_Vkd.cjs.map +0 -1
- package/dist/shared/attaform.DrvMscNX.cjs +0 -7697
- package/dist/shared/attaform.DrvMscNX.cjs.map +0 -1
- package/dist/shared/attaform.F2Q8iv38.d.ts +0 -2494
- package/dist/shared/attaform.FmqKO1Ex.d.cts +0 -2494
- package/dist/shared/attaform.KvlEedlF.mjs.map +0 -1
- package/dist/shared/attaform.RaTzp1WF.cjs +0 -26
- package/dist/shared/attaform.RaTzp1WF.cjs.map +0 -1
- package/dist/shared/attaform.nMaz2C5P.mjs.map +0 -1
- package/dist/shared/attaform.v0fQtWyA.mjs.map +0 -1
- package/dist/shared/attaform.yUrz7C2z.cjs +0 -29
- package/dist/shared/attaform.yUrz7C2z.cjs.map +0 -1
- package/dist/transforms.cjs +0 -12
- package/dist/transforms.cjs.map +0 -1
- package/dist/transforms.d.cts +0 -73
- package/dist/transforms.d.ts +0 -73
- package/dist/transforms.mjs.map +0 -1
- package/dist/vite.cjs +0 -363
- package/dist/vite.cjs.map +0 -1
- package/dist/vite.d.cts +0 -133
- package/dist/vite.d.ts +0 -133
- package/dist/vite.mjs.map +0 -1
- package/dist/webpack.cjs +0 -10
- package/dist/webpack.cjs.map +0 -1
- package/dist/webpack.d.cts +0 -37
- package/dist/webpack.d.ts +0 -37
- package/dist/webpack.mjs.map +0 -1
- package/dist/zod-v3.cjs +0 -53
- package/dist/zod-v3.cjs.map +0 -1
- package/dist/zod-v3.d.cts +0 -246
- package/dist/zod-v3.d.ts +0 -246
- package/dist/zod-v3.mjs.map +0 -1
- package/dist/zod-v4.cjs +0 -55
- package/dist/zod-v4.cjs.map +0 -1
- package/dist/zod-v4.d.cts +0 -172
- package/dist/zod-v4.d.ts +0 -172
- package/dist/zod-v4.mjs.map +0 -1
- package/dist/zod.cjs +0 -51
- package/dist/zod.cjs.map +0 -1
- package/dist/zod.d.cts +0 -7
- package/dist/zod.d.ts +0 -7
- package/dist/zod.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GenericForm, F as FormKey, a as UseFormReturnType,
|
|
2
|
-
import { Ref, ComputedRef, App, InjectionKey, Plugin } from 'vue';
|
|
1
|
+
import { G as GenericForm, F as FormKey, a as UseFormReturnType, a7 as RegisterValue, V as PathKey, k as DisplayCtx, w as GetDisplayState, l as DisplayMachine, ac as SlimPrimitiveKind, C as CoercionEntry, e as CoercionRegistry, aw as FieldRecord, ax as ErrorCell, ai as ValidationError, ay as OriginalsRecord, A as AbstractSchema, T as Path, am as WriteMeta, h as DeepPartial, an as WriteShape, az as AttaformDomBinding, aA as TransformAbortHolder, ag as ValidateOn, d as AttaformDefaults } from './attaform.CsoeRi3P.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
|
|
@@ -121,6 +121,22 @@ declare function injectForm<Form extends GenericForm, GetValueFormType extends G
|
|
|
121
121
|
* composable's `onMounted` warn fires once per instance to surface
|
|
122
122
|
* the misuse case at runtime.
|
|
123
123
|
*
|
|
124
|
+
* A wrapper meant to work both ways says so with
|
|
125
|
+
* `useRegister({ optional: true })`, which silences the unbound
|
|
126
|
+
* diagnostic and changes nothing else. Without it the diagnostic still
|
|
127
|
+
* earns its keep: a single-mode wrapper whose parent forgot
|
|
128
|
+
* `v-register` renders a field that looks fine and stores nothing.
|
|
129
|
+
*
|
|
130
|
+
* `rv?.isBound` is the test for "did a parent bind me", and it is the
|
|
131
|
+
* one to reach for: script-setup code holds the Proxy, which is an
|
|
132
|
+
* object and so always truthy, while a template holds the unwrapped
|
|
133
|
+
* ref, which is `undefined` when unbound. Those two disagree, and
|
|
134
|
+
* `isBound` reads the same on both. A dual-mode wrapper (one used
|
|
135
|
+
* both `v-register`-bound and plain `v-model`-bound) branches on it,
|
|
136
|
+
* and does not need to duplicate its element to do so: the
|
|
137
|
+
* compile-time value injection keeps an author-written `:value` /
|
|
138
|
+
* `:checked` as its unbound leg, so one element serves both (#620).
|
|
139
|
+
*
|
|
124
140
|
* Diagnostic: in dev mode, a single `console.warn` fires per instance
|
|
125
141
|
* at `onMounted` if the captured value is still `undefined` — by then
|
|
126
142
|
* the parent has had its full mount lifecycle to bind, so a missing
|
|
@@ -149,8 +165,48 @@ declare function injectForm<Form extends GenericForm, GetValueFormType extends G
|
|
|
149
165
|
* the hybrid's only `.value`. Older code that read `rv.value?.path`
|
|
150
166
|
* keeps working; new code can write `rv.path` directly.
|
|
151
167
|
*/
|
|
152
|
-
type UseRegisterReturn<V = unknown> = RegisterValue<V> & Ref<RegisterValue<V> | undefined
|
|
153
|
-
|
|
168
|
+
type UseRegisterReturn<V = unknown> = RegisterValue<V> & Ref<RegisterValue<V> | undefined> & {
|
|
169
|
+
/**
|
|
170
|
+
* Whether a parent has actually bound this wrapper. `false` until a
|
|
171
|
+
* `RegisterValue` lands, `true` once one has, and reactive in both
|
|
172
|
+
* directions: a parent that binds on a later render flips it, and
|
|
173
|
+
* so does one that stops binding.
|
|
174
|
+
*
|
|
175
|
+
* This is the test a dual-mode wrapper reaches for, and the reason
|
|
176
|
+
* it exists as a field rather than a truthiness check on the
|
|
177
|
+
* return: the composable cannot answer "is this bound" at setup
|
|
178
|
+
* time. A parent is free to bind on a later render
|
|
179
|
+
* (`v-register="ready ? form.register('x') : undefined"`), and
|
|
180
|
+
* `useRegister` has to keep serving that, so it can never return a
|
|
181
|
+
* plain `undefined` for "unbound right now". Script-setup code
|
|
182
|
+
* reading `rv` directly sees the hybrid Proxy, which is an object
|
|
183
|
+
* and therefore always truthy; a template sees the unwrapped ref,
|
|
184
|
+
* which IS `undefined` when unbound. `rv?.isBound` reads the same
|
|
185
|
+
* on both sides (#620).
|
|
186
|
+
*/
|
|
187
|
+
readonly isBound: boolean;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Options for `useRegister`.
|
|
191
|
+
*/
|
|
192
|
+
type UseRegisterOptions = {
|
|
193
|
+
/**
|
|
194
|
+
* Declares that this wrapper is used both with and without a form, so
|
|
195
|
+
* a render with no parent binding is intended rather than a mistake.
|
|
196
|
+
* Silences the unbound diagnostic; nothing else changes.
|
|
197
|
+
*
|
|
198
|
+
* The diagnostic exists because a single-mode wrapper whose parent
|
|
199
|
+
* forgot `v-register` renders a field that looks fine and stores
|
|
200
|
+
* nothing, which is an expensive afternoon. Once a wrapper is
|
|
201
|
+
* deliberately dual-mode, the same signal fires on correct code and
|
|
202
|
+
* tells the author to do something wrong, so this is the one fact
|
|
203
|
+
* that separates the two cases and only the author has it (#620).
|
|
204
|
+
*
|
|
205
|
+
* Pair it with `rv?.isBound` to branch on what actually happened.
|
|
206
|
+
*/
|
|
207
|
+
readonly optional?: boolean;
|
|
208
|
+
};
|
|
209
|
+
declare function useRegister<V = unknown>(options?: UseRegisterOptions): UseRegisterReturn<V> | undefined;
|
|
154
210
|
|
|
155
211
|
/**
|
|
156
212
|
* Per-form display engine: owns the clock and the timers that the pure
|
|
@@ -206,71 +262,12 @@ type DisplayEngine = {
|
|
|
206
262
|
clear(): void;
|
|
207
263
|
/** Tear down for good: `clear()` plus detaching the visibility listener. */
|
|
208
264
|
dispose(): void;
|
|
209
|
-
/** Introspection for tests: count of retained machines. */
|
|
210
|
-
size(): number;
|
|
211
|
-
/** Introspection for tests: whether a path
|
|
212
|
-
has(key: PathKey): boolean;
|
|
213
|
-
/** Introspection for tests: whether a deadline timer is
|
|
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;
|
|
265
|
+
/** Introspection for tests: count of retained machines. Dev builds only. */
|
|
266
|
+
size?(): number;
|
|
267
|
+
/** Introspection for tests: whether a path has a retained machine. Dev builds only. */
|
|
268
|
+
has?(key: PathKey): boolean;
|
|
269
|
+
/** Introspection for tests: whether a deadline timer is armed. Dev builds only. */
|
|
270
|
+
hasTimer?(): boolean;
|
|
274
271
|
};
|
|
275
272
|
|
|
276
273
|
/**
|
|
@@ -327,20 +324,21 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
327
324
|
readonly formKey: FormKey;
|
|
328
325
|
readonly form: Ref<F>;
|
|
329
326
|
readonly fields: Map<PathKey, FieldRecord>;
|
|
330
|
-
readonly elements: Map<PathKey, ElementRecord>;
|
|
331
327
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
* User-injected errors. Written ONLY by the `setErrors` / `clearErrors`
|
|
340
|
-
* API surface (and history / hydration replay). Survives schema revalidation and
|
|
328
|
+
* The tagged error store: one cell per error-bearing path, each cell
|
|
329
|
+
* segregating its two sources. The `schema` side is written ONLY by
|
|
330
|
+
* the validation pipeline (`scheduleFieldValidation`, `handleSubmit`,
|
|
331
|
+
* the construction-time seed, history restore, hydration) and cleared
|
|
332
|
+
* by `reset` / `resetField` and a successful submit; the `user` side
|
|
333
|
+
* is written ONLY by the `setErrors` / `clearErrors` API surface (and
|
|
334
|
+
* history / hydration replay) and survives schema revalidation and
|
|
341
335
|
* successful submits — the consumer owns its lifetime explicitly.
|
|
336
|
+
* A key exists iff a side is non-empty; cells are replaced, never
|
|
337
|
+
* mutated, so Vue's per-key Map tracking fires for either side's
|
|
338
|
+
* change. Derived blank entries are NOT stored here — they synthesize
|
|
339
|
+
* at read (`derivedBlankErrors`).
|
|
342
340
|
*/
|
|
343
|
-
readonly
|
|
341
|
+
readonly errorCells: Map<PathKey, ErrorCell>;
|
|
344
342
|
/**
|
|
345
343
|
* Reactively-derived "No value supplied" errors. Pure function of
|
|
346
344
|
* `(blankPaths, schema.isRequiredAtPath)` — no writers, no clears.
|
|
@@ -524,10 +522,22 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
524
522
|
* Resolves after `hydrating` flips back to `false`; consumers can
|
|
525
523
|
* `await form.rehydrate()` to gate UI on the fresh load.
|
|
526
524
|
*
|
|
527
|
-
* Does NOT touch
|
|
528
|
-
*
|
|
525
|
+
* Does NOT touch touched / submit state; chain `form.reset()` if you
|
|
526
|
+
* want a clean surface. It DOES re-seat the defaults (see
|
|
527
|
+
* `adoptResolvedDefaults`), so dirty afterwards means "differs from
|
|
528
|
+
* what the factory just returned", and `form.reset()` lands on the
|
|
529
|
+
* fresh values rather than throwing them away.
|
|
529
530
|
*/
|
|
530
531
|
rehydrate(): Promise<void>;
|
|
532
|
+
/**
|
|
533
|
+
* Adopt a resolved async-defaults value as the form's durable
|
|
534
|
+
* defaults and re-seed the dirty baseline from it. Called by the
|
|
535
|
+
* activate / rehydrate orchestrator once its factory settles.
|
|
536
|
+
* Exposed on the store (rather than imported) because
|
|
537
|
+
* `form-activation` is imported BY this module; a value import back
|
|
538
|
+
* the other way would close a cycle.
|
|
539
|
+
*/
|
|
540
|
+
adoptResolvedDefaults(value: unknown): void;
|
|
531
541
|
/**
|
|
532
542
|
* Incremented by every `reset()` call. The submit wrapper captures
|
|
533
543
|
* this at entry and skips writing `submitError` from a catch that
|
|
@@ -538,7 +548,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
538
548
|
readonly submissionGeneration: Ref<number>;
|
|
539
549
|
/**
|
|
540
550
|
* Counts in-flight validation calls across every `validate()` ref and
|
|
541
|
-
* every `
|
|
551
|
+
* every committing `parse(...)` / `handleSubmit` pre-check. `validating`
|
|
542
552
|
* on the public API mirrors `activeValidations.value > 0`. Tracked
|
|
543
553
|
* separately from submissions because a validate-while-submitting
|
|
544
554
|
* (e.g. a debounced field check overlapping a submit) needs to show
|
|
@@ -598,7 +608,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
598
608
|
* call) and decremented in the matching `.finally` — so the per-path
|
|
599
609
|
* bookkeeping is exactly co-extensive with the form-wide counter for
|
|
600
610
|
* the field-scheduled branch. Whole-form `validate()` /
|
|
601
|
-
* `
|
|
611
|
+
* `parse()` runs touch `activeValidations` only; they don't
|
|
602
612
|
* have a single field path and so don't contribute here.
|
|
603
613
|
*
|
|
604
614
|
* Counter (not Set) because two runs for the same path can briefly
|
|
@@ -687,7 +697,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
687
697
|
/**
|
|
688
698
|
* Stable identity for the array element at `path`. An array element
|
|
689
699
|
* (numeric last segment) carries its allocated identity token,
|
|
690
|
-
* maintained by
|
|
700
|
+
* maintained by the arrays engine across structural mutations.
|
|
691
701
|
* Empty for any non-array-element path: a record entry, a
|
|
692
702
|
* fixed-object field, a container, or the root. Backs `FieldState.key`.
|
|
693
703
|
*/
|
|
@@ -700,7 +710,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
700
710
|
/**
|
|
701
711
|
* Replace `schemaErrors` under `path` with `errors`, keying each
|
|
702
712
|
* error by its OWN absolute path. Used by validation pipelines
|
|
703
|
-
* (scheduleFieldValidation,
|
|
713
|
+
* (scheduleFieldValidation, the committing parse, handleSubmit, reset)
|
|
704
714
|
* to commit a parse result wholesale — entries not in the new
|
|
705
715
|
* pass get dropped from the subtree, surviving keys update in
|
|
706
716
|
* place to preserve insertion order. Pass `path === []` for the
|
|
@@ -711,10 +721,18 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
711
721
|
setUserErrorsForPath(path: Path, errors: readonly ValidationError[]): void;
|
|
712
722
|
clearUserErrors(path?: Path): void;
|
|
713
723
|
/**
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
724
|
+
* Rebuild the whole tagged store from a snapshot's `[key, cell]`
|
|
725
|
+
* entries — the history ring buffer's restore road. Entry arrays are
|
|
726
|
+
* cloned in, so the snapshot stays detached from the live store;
|
|
727
|
+
* cells with both sides empty are skipped.
|
|
728
|
+
*/
|
|
729
|
+
restoreErrorCells(entries: ReadonlyArray<readonly [PathKey, ErrorCell]>): void;
|
|
730
|
+
/**
|
|
731
|
+
* Merged read — the cell at `path` in schema -> blank -> user order.
|
|
732
|
+
* Schema errors come first (structural validation before business
|
|
733
|
+
* logic), the derived blank entry synthesizes between, and user
|
|
734
|
+
* entries close, matching the iteration order for
|
|
735
|
+
* `getFirstErrorElement` and the top-level `errors` drillable Proxy.
|
|
718
736
|
*/
|
|
719
737
|
getErrorsForPath(path: Path): ValidationError[];
|
|
720
738
|
/**
|
|
@@ -729,15 +747,29 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
729
747
|
*/
|
|
730
748
|
ensurePathOrdinal(key: PathKey): number;
|
|
731
749
|
/**
|
|
732
|
-
*
|
|
733
|
-
* `
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
* a `key` (e.g. sidebar + main rendering the same form), since both
|
|
737
|
-
* write into one shared element store.
|
|
750
|
+
* The store's DOM slice, `null` until the directive cluster or
|
|
751
|
+
* `useRegister` arms it via `RegisterValue.ensureDomBinding`. Element
|
|
752
|
+
* registration, host anchors, and first-error focus resolution all
|
|
753
|
+
* live behind it; eager readers treat `null` as an empty registry.
|
|
738
754
|
*/
|
|
739
|
-
|
|
740
|
-
|
|
755
|
+
readonly domBinding: ShallowRef<AttaformDomBinding | null>;
|
|
756
|
+
/**
|
|
757
|
+
* Field-record connect transition, driven by the DOM binding on
|
|
758
|
+
* element attach / host connect (and by the SSR-only
|
|
759
|
+
* `markConnectedOptimistically`): `connected: true`, with
|
|
760
|
+
* `focused` / `blurred` lifted from `null` to optimistic booleans
|
|
761
|
+
* only when currently null — an existing boolean from an early focus
|
|
762
|
+
* event is never clobbered.
|
|
763
|
+
*/
|
|
764
|
+
noteDomConnected(path: Path): void;
|
|
765
|
+
/**
|
|
766
|
+
* Field-record disconnect transition, driven by the DOM binding when
|
|
767
|
+
* a path's last element detaches or its host disconnects:
|
|
768
|
+
* `connected: false`, `focused` / `blurred` back to `null` (DOM-state
|
|
769
|
+
* properties are meaningless with nothing attached; interaction
|
|
770
|
+
* history stays).
|
|
771
|
+
*/
|
|
772
|
+
noteDomDisconnected(path: Path): void;
|
|
741
773
|
/**
|
|
742
774
|
* Optional `meta.instance` carries per-`useForm()`-instance overrides
|
|
743
775
|
* for `validateOn` / `debounceMs` so the blur-trigger respects the
|
|
@@ -777,20 +809,6 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
777
809
|
* source there).
|
|
778
810
|
*/
|
|
779
811
|
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
812
|
/**
|
|
795
813
|
* Leaf-only pristine check. `originals` is populated via
|
|
796
814
|
* `diffAndApply`'s `added` patches, which fire only on primitive
|
|
@@ -829,33 +847,6 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
829
847
|
hasRemovedSubtreeUnder(path: Path): boolean;
|
|
830
848
|
getFieldRecord(path: Path): FieldRecord | undefined;
|
|
831
849
|
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
850
|
/**
|
|
860
851
|
* Cancel every in-flight field-level validation run — clears timers
|
|
861
852
|
* for debounced 'change' runs that haven't fired, latches `aborted`
|
|
@@ -958,21 +949,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
|
|
|
958
949
|
*/
|
|
959
950
|
registerCleanup(fn: () => void): void;
|
|
960
951
|
/**
|
|
961
|
-
*
|
|
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
|
|
952
|
+
* Cache for per-state modules (chiefly history) that must
|
|
976
953
|
* outlive any single consumer. Subsequent `useForm` / `injectForm`
|
|
977
954
|
* calls for the same key read from this map so the public API shape
|
|
978
955
|
* is identical regardless of mount order. Keyed by a string identifier
|
|
@@ -1577,6 +1554,12 @@ type WizardForms<S> = FormsRecordOf<S> & Readonly<Record<FormKey, AnyForm>>;
|
|
|
1577
1554
|
* `back()` does not pop; the trail is the audit
|
|
1578
1555
|
* log, not the back-stack.
|
|
1579
1556
|
* - `next/back/goTo` — pure navigation. Refuses while `submitting`.
|
|
1557
|
+
* The one exception is `next()` on an UNCLEARED
|
|
1558
|
+
* `gate()` step, which behaves as `tryNext()` so
|
|
1559
|
+
* wiring Next straight to it can never skip the
|
|
1560
|
+
* gate's confirmation. Once that gate clears, `next()`
|
|
1561
|
+
* is plain navigation again and does not re-submit to
|
|
1562
|
+
* re-confirm.
|
|
1580
1563
|
* - `tryNext()` — submit the active step, and once that submit
|
|
1581
1564
|
* resolves clean, advance; invalid input keeps the pin
|
|
1582
1565
|
* put under the form's standard error reveal (first
|
|
@@ -1586,6 +1569,13 @@ type WizardForms<S> = FormsRecordOf<S> & Readonly<Record<FormKey, AnyForm>>;
|
|
|
1586
1569
|
* (`@click="wizard.tryNext()"`); resolves to whether
|
|
1587
1570
|
* the pin moved. No-ops to `false` on a degenerate or
|
|
1588
1571
|
* final-step wizard (finish via `handleSubmit`).
|
|
1572
|
+
* Called while the active step's form already has a
|
|
1573
|
+
* submit in flight (the usual case being from inside
|
|
1574
|
+
* that form's own callback), it rides that submit
|
|
1575
|
+
* rather than starting a second one, so one action
|
|
1576
|
+
* costs one submission. The pin has not moved by the
|
|
1577
|
+
* time it resolves, so the answer is `false`; the
|
|
1578
|
+
* advance lands with the in-flight submit.
|
|
1589
1579
|
* - `handleSubmit(onSubmit, onError?)` — always validates the entire
|
|
1590
1580
|
* step list, from any step, and never advances the
|
|
1591
1581
|
* pin: on success it latches `done`; on any error it
|
|
@@ -1783,13 +1773,6 @@ type AttaformRegistry = {
|
|
|
1783
1773
|
* @internal
|
|
1784
1774
|
*/
|
|
1785
1775
|
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
1776
|
};
|
|
1794
1777
|
/**
|
|
1795
1778
|
* The Vue `InjectionKey` under which the registry is provided on the
|
|
@@ -2167,6 +2150,8 @@ declare function createAttaform(options?: AttaformPluginOptions): Plugin;
|
|
|
2167
2150
|
* serialiser before embedding in your SSR payload.
|
|
2168
2151
|
*/
|
|
2169
2152
|
type SerializedAttaformState = {
|
|
2153
|
+
/** Envelope version — see {@link ATTAFORM_STATE_VERSION}. */
|
|
2154
|
+
readonly v: number;
|
|
2170
2155
|
/** Tuples of `[formKey, snapshot]` for every form in the app. */
|
|
2171
2156
|
readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>;
|
|
2172
2157
|
};
|
|
@@ -2206,10 +2191,16 @@ declare function renderAttaformState(app: App): SerializedAttaformState;
|
|
|
2206
2191
|
* app.mount('#app')
|
|
2207
2192
|
* ```
|
|
2208
2193
|
*
|
|
2194
|
+
* Accepts `unknown` because the payload crosses the wire untyped
|
|
2195
|
+
* (an inline `<script>` tag, `JSON.parse`): the envelope is
|
|
2196
|
+
* validated at runtime, and anything that isn't a version-matched
|
|
2197
|
+
* `renderAttaformState` snapshot is skipped wholesale, so forms
|
|
2198
|
+
* construct fresh from their schemas instead.
|
|
2199
|
+
*
|
|
2209
2200
|
* The next `useForm({ key })` call for each serialised form picks up
|
|
2210
2201
|
* the snapshot transparently — no further action is required.
|
|
2211
2202
|
*/
|
|
2212
|
-
declare function hydrateAttaformState(app: App, payload:
|
|
2203
|
+
declare function hydrateAttaformState(app: App, payload: unknown): void;
|
|
2213
2204
|
|
|
2214
2205
|
/**
|
|
2215
2206
|
* Escape a JSON string so it's safe to embed inside an inline
|
|
@@ -2242,26 +2233,6 @@ declare function escapeForInlineScript(json: string): string;
|
|
|
2242
2233
|
*/
|
|
2243
2234
|
declare const assignKey: unique symbol;
|
|
2244
2235
|
|
|
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
2236
|
/**
|
|
2266
2237
|
* Type guard for a `RegisterValue`. Returns `true` when `val` looks
|
|
2267
2238
|
* like the object returned from `form.register(path)`.
|
|
@@ -2490,5 +2461,5 @@ declare function makeDefaultDisplayState({ showDelay, minVisible, }: DisplayTimi
|
|
|
2490
2461
|
*/
|
|
2491
2462
|
declare const defaultDisplayState: GetDisplayState;
|
|
2492
2463
|
|
|
2493
|
-
export {
|
|
2494
|
-
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, GateMarker as G, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S,
|
|
2464
|
+
export { makeDefaultDisplayState as $, assignKey as B, DEFAULT_TIMINGS as D, createAttaform as E, createRegistry as H, defaultCoercionRules as J, defaultDisplayState as K, defineCoercion as M, escapeForInlineScript as N, OutsideSetupError as O, gate as P, getRegistryFromApp as Q, RegistryNotInstalledError as R, hydrateAttaformState as T, injectForm as V, injectWizard as X, isRegisterValue as Y, kAttaformRegistry as Z, lazy as _, renderAttaformState as a0, useRegister as a1, useRegistry as a2, useWizard 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 };
|
|
2465
|
+
export type { AttaformRegistry as A, CompiledStep as C, FormStatus as F, GateMarker as G, InjectWizardInput as I, LazyMarker as L, SerializedAttaformState as S, UseRegisterOptions 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, UseRegisterReturn as o, UseWizardReturnType as p, WizardCtx as q, WizardCtxForm as r, WizardOnError as s, WizardOnSubmit as t, WizardOptions as u, WizardPersistFn as v, WizardRestoreFn as w, WizardRestoreState as x, WizardStatusesProxy as y, WizardSubmitContext as z };
|