attaform 0.30.0 → 0.31.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 +15 -21
- package/dist/abstract.mjs +3 -3
- package/dist/dev/abstract.mjs +4 -4
- package/dist/dev/chunks/devtools.mjs +4 -4
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +2 -2
- package/dist/dev/index.mjs +5 -5
- package/dist/dev/runtime/plugins/attaform.mjs +1 -1
- package/dist/dev/shared/{attaform-dev.DUZckyV8.mjs → attaform-dev.B1q-x9R9.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.BcYT6tFh.mjs → attaform-dev.CZz4GYZ6.mjs} +21 -9
- package/dist/dev/shared/{attaform-dev.BisFstxh.mjs → attaform-dev.Caibt7sb.mjs} +16 -15
- package/dist/dev/shared/{attaform-dev.DTrHonpc.mjs → attaform-dev.CtyqGia7.mjs} +176 -260
- package/dist/dev/shared/{attaform-dev.BK6Ge2qR.mjs → attaform-dev.DJ3nsWw6.mjs} +86 -122
- package/dist/dev/shared/{attaform-dev.BcNtyOmf.mjs → attaform-dev.DlaT4xGd.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.D6CLvaQT.mjs → attaform-dev.k5X47GMD.mjs} +520 -395
- package/dist/dev/shared/{attaform-dev.CQ2rJiAX.mjs → attaform-dev.y9x9Vp9F.mjs} +324 -234
- package/dist/dev/shared/{attaform-dev.BQc5QV3Y.mjs → attaform-dev.zlvDr0WB.mjs} +2 -2
- package/dist/dev/zod-v3.mjs +6 -6
- package/dist/dev/zod-v4.mjs +6 -6
- package/dist/dev/zod.mjs +5 -5
- package/dist/directive.d.mts +4 -4
- package/dist/directive.mjs +1 -1
- package/dist/esbuild.d.mts +11 -0
- package/dist/esbuild.mjs +1 -1
- package/dist/history.d.mts +3 -32
- package/dist/history.mjs +2 -2
- package/dist/index.d.mts +67 -70
- package/dist/index.mjs +4 -4
- package/dist/nuxt.d.mts +4 -3
- package/dist/nuxt.mjs +3 -6
- package/dist/rollup.d.mts +11 -0
- package/dist/rollup.mjs +1 -1
- package/dist/rspack.d.mts +19 -11
- package/dist/rspack.mjs +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +15 -15
- package/dist/runtime/components/DevtoolsValueTree.vue +2 -2
- package/dist/runtime/plugins/attaform.mjs +1 -1
- package/dist/shared/{attaform.BRDDQeHV.mjs → attaform.8mfKZCwH.mjs} +2 -2
- package/dist/shared/{attaform.DRUT703x.d.mts → attaform.B-Tb62qV.d.mts} +12 -12
- package/dist/shared/{attaform.v0fQtWyA.mjs → attaform.B1rH9ht6.mjs} +1 -1
- package/dist/shared/{attaform.DhnPb6nK.mjs → attaform.BAf3UNn4.mjs} +1 -1
- package/dist/shared/{attaform.BXneBxEj.mjs → attaform.BWUn8Kjy.mjs} +85 -121
- package/dist/shared/{attaform.WiGdIqgx.mjs → attaform.C4shmwyJ.mjs} +2 -2
- package/dist/shared/{attaform.Rc9u4Vfw.d.mts → attaform.CRVe8s82.d.mts} +83 -95
- package/dist/shared/attaform.D9RqPgGu.d.mts +42 -0
- package/dist/shared/attaform.DAo0QBmS.d.mts +2173 -0
- package/dist/shared/{attaform.BK0cgu2K.mjs → attaform.DBCbxlyk.mjs} +62 -4
- package/dist/shared/{attaform.CUfrMK7t.mjs → attaform.DL2nl_QR.mjs} +15 -14
- package/dist/shared/{attaform.DNJOWjQw.mjs → attaform.DNPJPOO7.mjs} +299 -218
- package/dist/shared/attaform.DZnrDrNb.d.mts +4657 -0
- package/dist/shared/{attaform.B3resMQ1.mjs → attaform.DxKQsqFZ.mjs} +496 -371
- package/dist/shared/{attaform.ByWP6kSx.mjs → attaform.L011tHgJ.mjs} +3 -3
- package/dist/shared/{attaform.CJ8DpRGj.mjs → attaform.LUPC-2Qg.mjs} +175 -257
- package/dist/transforms.d.mts +153 -26
- package/dist/transforms.mjs +1 -1
- package/dist/vite.d.mts +29 -52
- package/dist/vite.mjs +3 -3
- package/dist/webpack.d.mts +20 -12
- package/dist/webpack.mjs +1 -1
- package/dist/zod-v3.d.mts +90 -96
- package/dist/zod-v3.mjs +5 -5
- package/dist/zod-v4.d.mts +120 -118
- package/dist/zod-v4.mjs +5 -5
- package/dist/zod.d.mts +5 -5
- package/dist/zod.mjs +4 -4
- package/package.json +7 -6
- package/skills/attaform/SKILL.md +1 -1
- package/skills/attaform/references/custom-components.md +4 -0
- package/dist/shared/attaform.Clz0ArIi.d.mts +0 -44
- package/dist/shared/attaform.UGyOK83T.d.mts +0 -2366
- package/dist/shared/attaform.bKLzMU0o.d.mts +0 -4761
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted,
|
|
2
|
-
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.
|
|
3
|
-
import { c as armDomBinding } from './attaform.
|
|
1
|
+
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, onBeforeMount, onBeforeUpdate, onMounted, nextTick } from 'vue';
|
|
2
|
+
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.C4shmwyJ.mjs';
|
|
3
|
+
import { c as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform.DxKQsqFZ.mjs';
|
|
4
4
|
import { R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.KvlEedlF.mjs';
|
|
5
|
-
import { A as ANONYMOUS_FORM_KEY_PREFIX, i as isShadowedKey, d as safeOwnHas, a as safeOwnRead, e as consumerHas, f as spreadConsumerRecord, g as copyConsumerArray, r as readConsumerIndex, b as safeAssign, h as consumerKeys, j as readConsumerProp, k as diffAndApply, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, l as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, m as consumerSymbolKeys, o as applyChangedKeys, R as RESERVED_KEY_PREFIX, q as DEFAULT_MAX_RECURSION_DEPTH, t as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform.
|
|
5
|
+
import { A as ANONYMOUS_FORM_KEY_PREFIX, i as isShadowedKey, d as safeOwnHas, a as safeOwnRead, e as consumerHas, f as spreadConsumerRecord, g as copyConsumerArray, r as readConsumerIndex, b as safeAssign, h as consumerKeys, j as readConsumerProp, k as diffAndApply, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, l as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, m as consumerSymbolKeys, o as applyChangedKeys, R as RESERVED_KEY_PREFIX, q as DEFAULT_MAX_RECURSION_DEPTH, c as callConsumerFn, t as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform.8mfKZCwH.mjs';
|
|
6
6
|
import { i as isPathPrefix, e as canonicalizePath, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, s as segmentsForPathKey, S as SubmitErrorHandlerError, t as toError, j as groupErrorsByKey, n as normalizeErrorInput, h as SET_MEMBER_SEGMENT, R as ROOT_PATH, l as normalizeErrorInputs, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform.CdZIEf7_.mjs';
|
|
7
7
|
|
|
8
8
|
const AttaformErrorCode = {
|
|
9
|
-
/** A required field is in the blank set
|
|
9
|
+
/** A required field is in the blank set: no value was supplied. */
|
|
10
10
|
NoValueSupplied: "atta:no-value-supplied",
|
|
11
11
|
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
12
12
|
AdapterThrew: "atta:adapter-threw",
|
|
@@ -532,7 +532,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
532
532
|
const value = state.getValueAtPath(segments);
|
|
533
533
|
const original = state.originals.get(key)?.value;
|
|
534
534
|
const pristine = state.isPristineAtPathByKey(key, segments);
|
|
535
|
-
const cell = state.errorCells.get(key);
|
|
535
|
+
const cell = state.errorCells().get(key);
|
|
536
536
|
const schemaForKey = cell !== void 0 && cell.schema.length > 0 ? cell.schema : void 0;
|
|
537
537
|
const blankForKey = state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments) ? [makeBlankRequiredError(segments)] : void 0;
|
|
538
538
|
const userForKey = cell !== void 0 && cell.user.length > 0 ? cell.user : void 0;
|
|
@@ -566,9 +566,8 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
566
566
|
updatedAt: record?.updatedAt ?? null,
|
|
567
567
|
errors,
|
|
568
568
|
// A leaf has no descendants, so its own-bucket errors ARE its subtree
|
|
569
|
-
// errors. Reuse the
|
|
570
|
-
//
|
|
571
|
-
// map (preserves the P3 blank-reactivity optimization above).
|
|
569
|
+
// errors. Reuse the array reference, which makes `ownErrors === errors`
|
|
570
|
+
// and avoids a second read of the whole-form `derivedBlankErrors` map.
|
|
572
571
|
ownErrors: errors,
|
|
573
572
|
validating,
|
|
574
573
|
valid,
|
|
@@ -748,19 +747,19 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
748
747
|
elements: EMPTY_ELEMENTS,
|
|
749
748
|
updatedAt,
|
|
750
749
|
errors,
|
|
751
|
-
// The container's OWN bucket
|
|
752
|
-
// descendant
|
|
753
|
-
//
|
|
754
|
-
//
|
|
755
|
-
//
|
|
750
|
+
// The container's OWN bucket at this exact path, excluding every
|
|
751
|
+
// descendant `errors` rolls up: a cross-field `.refine()` here, or a
|
|
752
|
+
// `setErrors` pinned at this node. The same raw union the leaf builds
|
|
753
|
+
// from the three stores, and the container already depends on all three
|
|
754
|
+
// through `aggregateErrorsAt`, so it costs no new reactivity.
|
|
756
755
|
ownErrors: state.getErrorsForPath(segments),
|
|
757
756
|
validating,
|
|
758
757
|
valid,
|
|
759
758
|
transforming,
|
|
760
759
|
busy: transforming || validating,
|
|
761
|
-
// A container surfaces its OWN transform failure
|
|
762
|
-
// on the container path
|
|
763
|
-
// descendant
|
|
760
|
+
// A container surfaces its OWN transform failure, from a transform
|
|
761
|
+
// registered on the container path such as a file normalizer, and never
|
|
762
|
+
// rolls up a descendant's: that stays a per-field channel.
|
|
764
763
|
transformError: ownTransformError,
|
|
765
764
|
path: segments,
|
|
766
765
|
...computeFieldIdentity(formInstanceId, state.formKey, key),
|
|
@@ -822,7 +821,7 @@ function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
|
822
821
|
const candidates = state.errorWindowAt(prefix, prefixKey);
|
|
823
822
|
if (candidates.length === 0) return [];
|
|
824
823
|
const formValue = state.form.value;
|
|
825
|
-
const cells = state.errorCells;
|
|
824
|
+
const cells = state.errorCells();
|
|
826
825
|
const buckets = /* @__PURE__ */ new Map();
|
|
827
826
|
for (const { key, segments } of candidates) {
|
|
828
827
|
if (!isPathPrefix(prefix, segments)) continue;
|
|
@@ -1092,16 +1091,16 @@ function buildErrorsSurface(state, sweep) {
|
|
|
1092
1091
|
// non-schema keys reachable while a genuinely-absent key stays out.
|
|
1093
1092
|
hasOwn: (segments, key) => liveContainerHasKey(state, segments, key) || errorAwareContainerKeys(state, segments).includes(key),
|
|
1094
1093
|
isArrayAt: (segments) => isArrayPath(state, segments),
|
|
1095
|
-
// `errors()
|
|
1096
|
-
// aggregate
|
|
1097
|
-
//
|
|
1094
|
+
// `errors()`, `errors([])` and `errors(path)` are all the subtree
|
|
1095
|
+
// aggregate, through the helper `meta.errors` reads, so they cannot
|
|
1096
|
+
// drift.
|
|
1098
1097
|
call: (path) => aggregateErrorsAt(state, path, keyForSegments(path).key),
|
|
1099
1098
|
surface: "form.errors",
|
|
1100
1099
|
sweep
|
|
1101
1100
|
});
|
|
1102
1101
|
}
|
|
1103
1102
|
function collectErrorsAt(state, key, segments, active, into) {
|
|
1104
|
-
const cell = state.errorCells.get(key);
|
|
1103
|
+
const cell = state.errorCells().get(key);
|
|
1105
1104
|
if (active) {
|
|
1106
1105
|
if (cell !== void 0) into.push(...cell.schema);
|
|
1107
1106
|
if (state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments)) {
|
|
@@ -1682,7 +1681,7 @@ function createArrayBookkeeping(deps) {
|
|
|
1682
1681
|
...record,
|
|
1683
1682
|
path: segments
|
|
1684
1683
|
}));
|
|
1685
|
-
migrateMapSubtree(errorCells, arrayPath, remap, (cell, segments) => ({
|
|
1684
|
+
migrateMapSubtree(errorCells(), arrayPath, remap, (cell, segments) => ({
|
|
1686
1685
|
schema: NO_ERRORS,
|
|
1687
1686
|
user: cell.user.map((error) => ({ ...error, path: [...segments] }))
|
|
1688
1687
|
}));
|
|
@@ -1732,7 +1731,7 @@ function createArrayBookkeeping(deps) {
|
|
|
1732
1731
|
migrateElementState(arrayPath, remap);
|
|
1733
1732
|
for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex);
|
|
1734
1733
|
const changed = changedIndices(remap);
|
|
1735
|
-
evictSchemaVerdictsAtIndices(errorCells, arrayPath, changed);
|
|
1734
|
+
evictSchemaVerdictsAtIndices(errorCells(), arrayPath, changed);
|
|
1736
1735
|
abortValidationAtVacatedIndices(arrayPath, remap);
|
|
1737
1736
|
variantMemory.dropAtIndices(arrayPath, changed);
|
|
1738
1737
|
arrayIdentity.applyOp(arrayPath, remap);
|
|
@@ -2037,7 +2036,7 @@ function adapterThrowMessage(err) {
|
|
|
2037
2036
|
return "Adapter validateAtPath threw a non-Error value";
|
|
2038
2037
|
}
|
|
2039
2038
|
function hasUserErrorEntries(state) {
|
|
2040
|
-
for (const cell of state.errorCells.values()) {
|
|
2039
|
+
for (const cell of state.errorCells().values()) {
|
|
2041
2040
|
if (cell.user.length > 0) return true;
|
|
2042
2041
|
}
|
|
2043
2042
|
return false;
|
|
@@ -2257,6 +2256,7 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2257
2256
|
const isRequired = state.schema.isRequiredAtPath(segments);
|
|
2258
2257
|
const ariaDisplayState = getDisplayStateAt !== void 0 ? computed(() => getDisplayStateAt(segments)) : void 0;
|
|
2259
2258
|
const markBlank = () => state.setValueAtPath(segments, slimDefault, withInstanceMeta({ blank: true }));
|
|
2259
|
+
const commitFromHost = (value) => value === "" && !acceptsString || value === null && !slimTypes.has("null") || value === void 0 && !acceptsUndefined ? markBlank() : state.setValueAtPath(segments, value, withInstanceMeta(void 0));
|
|
2260
2260
|
const internalRv = {
|
|
2261
2261
|
innerRef,
|
|
2262
2262
|
displayValue,
|
|
@@ -2273,7 +2273,7 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2273
2273
|
},
|
|
2274
2274
|
ensureDomBinding: (factory) => {
|
|
2275
2275
|
var _a;
|
|
2276
|
-
(_a = state.domBinding).value ?? (_a.value = factory(state));
|
|
2276
|
+
return (_a = state.domBinding).value ?? (_a.value = factory(state));
|
|
2277
2277
|
},
|
|
2278
2278
|
registerElement: (element) => {
|
|
2279
2279
|
const dom = state.domBinding.value;
|
|
@@ -2288,13 +2288,14 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2288
2288
|
setValueWithInternalPath: (value, meta) => {
|
|
2289
2289
|
return state.setValueAtPath(segments, value, withInstanceMeta(meta));
|
|
2290
2290
|
},
|
|
2291
|
-
|
|
2291
|
+
commitFromHost,
|
|
2292
|
+
setValueFromHost: (value, modifiers) => {
|
|
2292
2293
|
state.markInteracted(segments);
|
|
2293
|
-
const
|
|
2294
|
-
const accepted = isBlankSignal ? markBlank() : state.setValueAtPath(segments, value, withInstanceMeta(void 0));
|
|
2294
|
+
const accepted = state.domBinding.value?.hostChannel.write(internalRv, value, modifiers) ?? commitFromHost(value);
|
|
2295
2295
|
return accepted;
|
|
2296
2296
|
},
|
|
2297
|
-
|
|
2297
|
+
setValueFromHostInput: (payload, modifiers) => state.domBinding.value?.hostChannel.writeInput(internalRv, payload, modifiers) ?? false,
|
|
2298
|
+
// Called by the `vRegisterHintTransform` compile-time transform's wrapping
|
|
2298
2299
|
// IIFE on every server-side render of `<element v-register="…">`.
|
|
2299
2300
|
// Without it, every SSR'd FieldState serialises `connected: false`
|
|
2300
2301
|
// (because Vue skips directive lifecycle during SSR) and the client
|
|
@@ -2323,12 +2324,12 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2323
2324
|
}
|
|
2324
2325
|
return false;
|
|
2325
2326
|
},
|
|
2326
|
-
// --- Async transform lifecycle (internal; the directive's
|
|
2327
|
-
//
|
|
2328
|
-
//
|
|
2329
|
-
//
|
|
2330
|
-
//
|
|
2331
|
-
//
|
|
2327
|
+
// --- Async transform lifecycle (internal; the directive's deferred
|
|
2328
|
+
// orchestrator is the only legitimate consumer). Thin path-bound
|
|
2329
|
+
// delegates to the store's per-path token and counter machinery,
|
|
2330
|
+
// the same pattern as `markBlank` and `setValueWithInternalPath`, so
|
|
2331
|
+
// the directive (which holds this RegisterValue and never the store)
|
|
2332
|
+
// can drive the busy / discard / error bookkeeping. ---
|
|
2332
2333
|
beginTransform: (holder) => state.beginTransform(pathKey, holder),
|
|
2333
2334
|
isCurrentTransform: (token) => state.isCurrentTransform(pathKey, token),
|
|
2334
2335
|
endTransform: (token) => state.endTransform(pathKey, token),
|
|
@@ -2341,10 +2342,10 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2341
2342
|
return (state.fieldTransformCounts.get(pathKey) ?? 0) > 0;
|
|
2342
2343
|
},
|
|
2343
2344
|
path: pathKey,
|
|
2344
|
-
// Frozen so a wrapper component can pass `rv.segments`
|
|
2345
|
-
//
|
|
2346
|
-
//
|
|
2347
|
-
//
|
|
2345
|
+
// Frozen so a wrapper component can pass `rv.segments` straight to
|
|
2346
|
+
// `form.fields(...)` with no defensive copy, and so neither a test
|
|
2347
|
+
// fixture nor downstream code can mutate the canonical segment list
|
|
2348
|
+
// out from under the directive.
|
|
2348
2349
|
segments: Object.freeze(segments.slice()),
|
|
2349
2350
|
formKey: state.formKey,
|
|
2350
2351
|
formInstanceId,
|
|
@@ -2367,25 +2368,24 @@ function isUnset(value) {
|
|
|
2367
2368
|
return value === unset;
|
|
2368
2369
|
}
|
|
2369
2370
|
|
|
2370
|
-
function walkUnsetSentinels(values, schema) {
|
|
2371
|
+
function walkUnsetSentinels(values, schema, rootDefault) {
|
|
2371
2372
|
const paths = [];
|
|
2372
2373
|
if (values === void 0) {
|
|
2373
|
-
|
|
2374
|
-
walkUnspecified(rootSlim, [], paths);
|
|
2374
|
+
walkUnspecified(rootDefault, [], paths);
|
|
2375
2375
|
return { cleanedValues: void 0, paths };
|
|
2376
2376
|
}
|
|
2377
|
-
const cleaned = walkCore(values, [], schema, paths,
|
|
2377
|
+
const cleaned = walkCore(values, [], schema, paths, { rootDefault });
|
|
2378
2378
|
return { cleanedValues: cleaned, paths };
|
|
2379
2379
|
}
|
|
2380
2380
|
function isRecursable(value) {
|
|
2381
2381
|
return Array.isArray(value) || isPlainRecord(value);
|
|
2382
2382
|
}
|
|
2383
|
-
function walkCore(input, segments, schema, paths,
|
|
2383
|
+
function walkCore(input, segments, schema, paths, synthesis) {
|
|
2384
2384
|
if (isUnset(input)) {
|
|
2385
2385
|
return expandUnsetAt(segments, schema, paths);
|
|
2386
2386
|
}
|
|
2387
2387
|
if (input === void 0) {
|
|
2388
|
-
if (
|
|
2388
|
+
if (synthesis !== null) {
|
|
2389
2389
|
const slim = schema.getDefaultAtPath(segments);
|
|
2390
2390
|
return walkUnspecified(slim, segments, paths);
|
|
2391
2391
|
}
|
|
@@ -2398,7 +2398,7 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
|
2398
2398
|
let mutated = false;
|
|
2399
2399
|
for (let i = 0; i < input.length; i++) {
|
|
2400
2400
|
const original = readConsumerIndex(input, i);
|
|
2401
|
-
const walked = walkCore(original, [...segments, i], schema, paths,
|
|
2401
|
+
const walked = walkCore(original, [...segments, i], schema, paths, synthesis);
|
|
2402
2402
|
out[i] = walked;
|
|
2403
2403
|
if (walked !== original) mutated = true;
|
|
2404
2404
|
}
|
|
@@ -2410,10 +2410,10 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
|
2410
2410
|
let keys = inputKeys;
|
|
2411
2411
|
let mutated = false;
|
|
2412
2412
|
let inputKeysSet = null;
|
|
2413
|
-
if (
|
|
2413
|
+
if (synthesis !== null) {
|
|
2414
2414
|
inputKeysSet = new Set(inputKeys);
|
|
2415
2415
|
const allKeys = new Set(inputKeys);
|
|
2416
|
-
const slim = schema.getDefaultAtPath(segments);
|
|
2416
|
+
const slim = segments.length === 0 ? synthesis.rootDefault : schema.getDefaultAtPath(segments);
|
|
2417
2417
|
if (isPlainRecord(slim)) {
|
|
2418
2418
|
for (const k of Object.keys(slim)) allKeys.add(k);
|
|
2419
2419
|
}
|
|
@@ -2423,12 +2423,12 @@ function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
|
2423
2423
|
const out = {};
|
|
2424
2424
|
for (const key of keys) {
|
|
2425
2425
|
const orig = readConsumerProp(obj, key);
|
|
2426
|
-
if (
|
|
2426
|
+
if (synthesis !== null && orig === void 0 && inputKeysSet?.has(key) === true) {
|
|
2427
2427
|
safeAssign(out, key, void 0);
|
|
2428
2428
|
mutated = true;
|
|
2429
2429
|
continue;
|
|
2430
2430
|
}
|
|
2431
|
-
const walked = walkCore(orig, [...segments, key], schema, paths,
|
|
2431
|
+
const walked = walkCore(orig, [...segments, key], schema, paths, synthesis);
|
|
2432
2432
|
safeAssign(out, key, walked);
|
|
2433
2433
|
if (walked !== orig) mutated = true;
|
|
2434
2434
|
}
|
|
@@ -2452,7 +2452,7 @@ function walkUnspecified(slim, segments, paths) {
|
|
|
2452
2452
|
}
|
|
2453
2453
|
function substituteUnsetSentinels(value, prefix, schema) {
|
|
2454
2454
|
const paths = [];
|
|
2455
|
-
const cleaned = walkCore(value, [...prefix], schema, paths,
|
|
2455
|
+
const cleaned = walkCore(value, [...prefix], schema, paths, null);
|
|
2456
2456
|
return { cleanedValues: cleaned, paths };
|
|
2457
2457
|
}
|
|
2458
2458
|
function isPrimitiveOrEmpty(value) {
|
|
@@ -2550,15 +2550,15 @@ function buildMetaProxy(keys, read) {
|
|
|
2550
2550
|
return new Proxy(target, {
|
|
2551
2551
|
get: (_, key) => owns.has(key) ? read(key) : Reflect.get(target, key),
|
|
2552
2552
|
has: (_, key) => owns.has(key) || Reflect.has(target, key),
|
|
2553
|
-
// Safe to hand back the same array every time: the spec copies a
|
|
2554
|
-
//
|
|
2553
|
+
// Safe to hand back the same array every time: the spec copies a trap's
|
|
2554
|
+
// key list before using it.
|
|
2555
2555
|
ownKeys: () => keys,
|
|
2556
2556
|
getOwnPropertyDescriptor(_, key) {
|
|
2557
2557
|
if (!owns.has(key)) return Reflect.getOwnPropertyDescriptor(target, key);
|
|
2558
2558
|
return { configurable: true, enumerable: true, value: read(key), writable: false };
|
|
2559
2559
|
},
|
|
2560
|
-
// A getter with no setter throws on assignment under strict mode,
|
|
2561
|
-
//
|
|
2560
|
+
// A getter with no setter throws on assignment under strict mode, which
|
|
2561
|
+
// every module here is; `false` keeps that.
|
|
2562
2562
|
set: denyWrite,
|
|
2563
2563
|
deleteProperty: denyWrite,
|
|
2564
2564
|
defineProperty: denyWrite
|
|
@@ -2617,7 +2617,18 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2617
2617
|
void state.submitted.value;
|
|
2618
2618
|
return metaBase;
|
|
2619
2619
|
};
|
|
2620
|
-
const
|
|
2620
|
+
const releases = [];
|
|
2621
|
+
const lease = (release) => {
|
|
2622
|
+
releases.push(release);
|
|
2623
|
+
return release;
|
|
2624
|
+
};
|
|
2625
|
+
onScopeDispose(() => {
|
|
2626
|
+
for (const release of releases) release();
|
|
2627
|
+
}, true);
|
|
2628
|
+
const pathSweep = {
|
|
2629
|
+
track: state.pathSweep.track,
|
|
2630
|
+
onEvict: (evict) => lease(state.pathSweep.onEvict(evict))
|
|
2631
|
+
};
|
|
2621
2632
|
const getRootFieldStateAt = buildFieldStateAccessor(
|
|
2622
2633
|
state,
|
|
2623
2634
|
formInstanceId,
|
|
@@ -2675,7 +2686,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2675
2686
|
const next = typeof pathOrValue === "function" ? pathOrValue(structuralSnapshot(state.form.value)) : pathOrValue;
|
|
2676
2687
|
const walked2 = walkUnsetSentinels(
|
|
2677
2688
|
next,
|
|
2678
|
-
state.schema
|
|
2689
|
+
state.schema,
|
|
2690
|
+
state.schema.getDefaultAtPath([])
|
|
2679
2691
|
);
|
|
2680
2692
|
const ok2 = state.setValueAtPath([], walked2.cleanedValues, writeMeta());
|
|
2681
2693
|
if (!ok2) return false;
|
|
@@ -2740,7 +2752,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2740
2752
|
const errorsProxy = buildErrorsSurface(state, pathSweep);
|
|
2741
2753
|
function flattenUserErrors() {
|
|
2742
2754
|
const all = [];
|
|
2743
|
-
for (const cell of state.errorCells.values()) all.push(...cell.user);
|
|
2755
|
+
for (const cell of state.errorCells().values()) all.push(...cell.user);
|
|
2744
2756
|
return all;
|
|
2745
2757
|
}
|
|
2746
2758
|
function setErrors(arg1, arg2) {
|
|
@@ -2748,7 +2760,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2748
2760
|
if (isScoped) {
|
|
2749
2761
|
const { segments, key } = canonicalizePath(arg1);
|
|
2750
2762
|
const input2 = arg2;
|
|
2751
|
-
const resolved2 = typeof input2 === "function" ? input2([...state.errorCells.get(key)?.user ?? []]) : input2;
|
|
2763
|
+
const resolved2 = typeof input2 === "function" ? input2([...state.errorCells().get(key)?.user ?? []]) : input2;
|
|
2752
2764
|
state.setUserErrorsForPath(
|
|
2753
2765
|
segments,
|
|
2754
2766
|
normalizeErrorInputs(resolved2, segments, AttaformErrorCode.UserError)
|
|
@@ -2776,7 +2788,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2776
2788
|
const departAttempts = computed(() => state.departAttempts.value);
|
|
2777
2789
|
const validating = computed(() => state.activeValidations.value > 0);
|
|
2778
2790
|
const valid = computed(
|
|
2779
|
-
() => state.firstValidationDone.value && state.errorCells.size === 0 && state.derivedBlankErrors.value.size === 0 && !validating.value
|
|
2791
|
+
() => state.firstValidationDone.value && state.errorCells().size === 0 && state.derivedBlankErrors.value.size === 0 && !validating.value
|
|
2780
2792
|
);
|
|
2781
2793
|
const history = options.history;
|
|
2782
2794
|
const formHistory = history === void 0 ? inertHistory() : readonly(
|
|
@@ -2794,12 +2806,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2794
2806
|
);
|
|
2795
2807
|
const rootFieldState = getRootFieldStateAt([]);
|
|
2796
2808
|
const metaOwn = {
|
|
2797
|
-
// Whole-form work signals compose the LIFECYCLE counters with the
|
|
2798
|
-
//
|
|
2799
|
-
//
|
|
2800
|
-
//
|
|
2801
|
-
//
|
|
2802
|
-
// unfiltered whole-form aggregate.
|
|
2809
|
+
// Whole-form work signals compose the LIFECYCLE counters with the per-leaf
|
|
2810
|
+
// rollup: a submit-time validate shows up in `activeValidations` and a
|
|
2811
|
+
// per-field debounced validator in `fieldValidationCounts`, and either
|
|
2812
|
+
// flips the flag. `valid` keeps the form-level mount gate, and `errors` is
|
|
2813
|
+
// the unfiltered whole-form aggregate.
|
|
2803
2814
|
validating: computed(
|
|
2804
2815
|
() => state.activeValidations.value > 0 || rootFieldState.value.validating
|
|
2805
2816
|
),
|
|
@@ -2811,7 +2822,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2811
2822
|
busy: computed(
|
|
2812
2823
|
() => state.activeValidations.value > 0 || state.activeTransforms.value > 0 || rootFieldState.value.validating || rootFieldState.value.transforming
|
|
2813
2824
|
),
|
|
2814
|
-
// Lifecycle
|
|
2825
|
+
// Lifecycle, form-level only and never on FieldState.
|
|
2815
2826
|
submitting,
|
|
2816
2827
|
submissionAttempts,
|
|
2817
2828
|
departAttempts,
|
|
@@ -2893,7 +2904,10 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2893
2904
|
};
|
|
2894
2905
|
return Object.freeze(view);
|
|
2895
2906
|
});
|
|
2896
|
-
const valuesProxy = buildValuesSurface(
|
|
2907
|
+
const valuesProxy = buildValuesSurface(
|
|
2908
|
+
state.form,
|
|
2909
|
+
(listener) => lease(state.onFormChange(listener))
|
|
2910
|
+
);
|
|
2897
2911
|
const fieldStateProxy = buildFieldsSurface(state, getRootFieldStateAt, pathSweep);
|
|
2898
2912
|
const needsLazyGate = state.defaultValuesFactory.value !== void 0 || state.hasSsrPrefetch;
|
|
2899
2913
|
function gated(fn) {
|
|
@@ -2928,10 +2942,10 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2928
2942
|
}
|
|
2929
2943
|
const api = {
|
|
2930
2944
|
handleSubmit: gated(handleSubmit),
|
|
2931
|
-
//
|
|
2932
|
-
// reactive containers (`meta`, `history`, `blankPaths`) are exposed
|
|
2933
|
-
//
|
|
2934
|
-
//
|
|
2945
|
+
// The callable readonly Proxies (`values`, `fields`, `errors`) and the
|
|
2946
|
+
// reactive containers (`meta`, `history`, `blankPaths`) are exposed through
|
|
2947
|
+
// getters, so reading one activates the form on first touch. Each
|
|
2948
|
+
// underlying object is identity-stable across reads.
|
|
2935
2949
|
get values() {
|
|
2936
2950
|
void state.activate();
|
|
2937
2951
|
return valuesProxy;
|
|
@@ -2948,7 +2962,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2948
2962
|
key: state.formKey,
|
|
2949
2963
|
// Auto-unwrapping views over the per-store async-defaults lifecycle
|
|
2950
2964
|
// refs (see FormStore.hydrating / hydrateError). Reading either
|
|
2951
|
-
// activates the form
|
|
2965
|
+
// activates the form: observing factory state implies use.
|
|
2952
2966
|
get hydrating() {
|
|
2953
2967
|
void state.activate();
|
|
2954
2968
|
return state.hydrating.value;
|
|
@@ -2957,20 +2971,18 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2957
2971
|
void state.activate();
|
|
2958
2972
|
return state.hydrateError.value;
|
|
2959
2973
|
},
|
|
2960
|
-
// Orthogonal to `hydrating` and `hydrateError
|
|
2961
|
-
//
|
|
2962
|
-
// resolved
|
|
2963
|
-
// refetches even when those
|
|
2964
|
-
//
|
|
2965
|
-
// `hydrateError` surfaces the refresh failure.
|
|
2974
|
+
// Orthogonal to `hydrating` and `hydrateError`. `ready` flips true once
|
|
2975
|
+
// defaults are applied, whether sync at construction or from a factory
|
|
2976
|
+
// that resolved, and it is a one-way latch: it stays true through later
|
|
2977
|
+
// refetches even when those fail, so a stale-while-revalidate UI keeps
|
|
2978
|
+
// rendering the prior values while `hydrateError` surfaces the failure.
|
|
2966
2979
|
get ready() {
|
|
2967
2980
|
void state.activate();
|
|
2968
2981
|
return state.defaultsResolved.value;
|
|
2969
2982
|
},
|
|
2970
|
-
// `rehydrate` and `activate` are
|
|
2971
|
-
//
|
|
2972
|
-
//
|
|
2973
|
-
// so they call `state` directly.
|
|
2983
|
+
// `rehydrate` and `activate` are activation entry points themselves and
|
|
2984
|
+
// fire the factory by design, so wrapping them in `gated` would
|
|
2985
|
+
// double-fire. They call `state` directly.
|
|
2974
2986
|
rehydrate: () => state.rehydrate(),
|
|
2975
2987
|
activate: () => state.activate(),
|
|
2976
2988
|
get errors() {
|
|
@@ -3016,7 +3028,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3016
3028
|
const SWEEP_SLICE = 8;
|
|
3017
3029
|
function createDynamicPathSweep(deps) {
|
|
3018
3030
|
const dynamicKeys = /* @__PURE__ */ new Set();
|
|
3019
|
-
const evictors =
|
|
3031
|
+
const evictors = /* @__PURE__ */ new Set();
|
|
3020
3032
|
const isDynamicPath = (segments) => {
|
|
3021
3033
|
for (let i = 0; i < segments.length; i++) {
|
|
3022
3034
|
if (typeof segments[i] === "number") return true;
|
|
@@ -3047,7 +3059,10 @@ function createDynamicPathSweep(deps) {
|
|
|
3047
3059
|
if (isDynamicPath(segments)) dynamicKeys.add(key);
|
|
3048
3060
|
},
|
|
3049
3061
|
onEvict(evict) {
|
|
3050
|
-
evictors.
|
|
3062
|
+
evictors.add(evict);
|
|
3063
|
+
return () => {
|
|
3064
|
+
evictors.delete(evict);
|
|
3065
|
+
};
|
|
3051
3066
|
}
|
|
3052
3067
|
};
|
|
3053
3068
|
}
|
|
@@ -3246,7 +3261,7 @@ function mergeObjectKeys(target, source, path, schema) {
|
|
|
3246
3261
|
async function runFactoryAndApply(st, factory) {
|
|
3247
3262
|
try {
|
|
3248
3263
|
const value = await factory();
|
|
3249
|
-
walkAuthoredFromConstraints(value, [], st.authoredPaths);
|
|
3264
|
+
if (st.hasPreprocessOrCoerce) walkAuthoredFromConstraints(value, [], st.authoredPaths);
|
|
3250
3265
|
const full = mergeSparseHydration(
|
|
3251
3266
|
toRaw(st.form.value),
|
|
3252
3267
|
value,
|
|
@@ -3270,7 +3285,7 @@ async function runFactoryAndApply(st, factory) {
|
|
|
3270
3285
|
}
|
|
3271
3286
|
}
|
|
3272
3287
|
function clearHydrationFailedEntry(st) {
|
|
3273
|
-
const existing = st.errorCells.get(ROOT_PATH_KEY)?.schema;
|
|
3288
|
+
const existing = st.errorCells().get(ROOT_PATH_KEY)?.schema;
|
|
3274
3289
|
if (existing === void 0 || existing.length === 0) return;
|
|
3275
3290
|
const filtered = existing.filter((e) => e.code !== AttaformErrorCode.HydrationFailed);
|
|
3276
3291
|
if (filtered.length !== existing.length) {
|
|
@@ -3284,7 +3299,7 @@ function appendHydrationFailedEntry(st, error) {
|
|
|
3284
3299
|
path: [...ROOT_PATH],
|
|
3285
3300
|
code: AttaformErrorCode.HydrationFailed
|
|
3286
3301
|
};
|
|
3287
|
-
const existing = st.errorCells.get(ROOT_PATH_KEY)?.schema ?? [];
|
|
3302
|
+
const existing = st.errorCells().get(ROOT_PATH_KEY)?.schema ?? [];
|
|
3288
3303
|
st.setSchemaErrorsForPath([...ROOT_PATH], [...existing, entry]);
|
|
3289
3304
|
return entry;
|
|
3290
3305
|
}
|
|
@@ -3402,23 +3417,24 @@ function walkAuthoredFromSchemaDiff(withDefaults, withoutDefaults, prefix, out)
|
|
|
3402
3417
|
out.add(canonicalizePath(prefix).key);
|
|
3403
3418
|
}
|
|
3404
3419
|
}
|
|
3405
|
-
function
|
|
3406
|
-
|
|
3420
|
+
function computeBaseline(schema, source, schemaDefaults) {
|
|
3421
|
+
if (source === void 0) return schemaDefaults;
|
|
3407
3422
|
return schema.getDefaultValues({
|
|
3408
3423
|
useDefaultSchemaValues: true,
|
|
3409
|
-
constraints:
|
|
3424
|
+
constraints: mergeStructural(schema, [], source, schemaDefaults)
|
|
3410
3425
|
});
|
|
3411
3426
|
}
|
|
3412
3427
|
function initialFirstValidationGate(schema) {
|
|
3413
3428
|
return schema.needsAsyncValidation?.() !== true;
|
|
3414
3429
|
}
|
|
3415
|
-
function seedOriginalsFromBaseline(st, baseline
|
|
3430
|
+
function seedOriginalsFromBaseline(st, baseline) {
|
|
3416
3431
|
st.originals.clear();
|
|
3417
3432
|
diffAndApply({}, baseline, [], (patch) => {
|
|
3418
3433
|
if (patch.kind !== "added") return;
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3434
|
+
st.originals.set(canonicalizePath(patch.path).key, {
|
|
3435
|
+
segments: patch.path,
|
|
3436
|
+
value: patch.newValue
|
|
3437
|
+
});
|
|
3422
3438
|
});
|
|
3423
3439
|
}
|
|
3424
3440
|
function queueInitialAsyncValidation(st) {
|
|
@@ -3432,6 +3448,7 @@ function queueInitialAsyncValidation(st) {
|
|
|
3432
3448
|
}
|
|
3433
3449
|
}
|
|
3434
3450
|
function rebuildAuthoredPaths(st, constraints, schemaWithDefaultsData) {
|
|
3451
|
+
if (!st.hasPreprocessOrCoerce) return;
|
|
3435
3452
|
st.authoredPaths.clear();
|
|
3436
3453
|
if (constraints !== void 0) {
|
|
3437
3454
|
walkAuthoredFromConstraints(constraints, [], st.authoredPaths);
|
|
@@ -3465,6 +3482,7 @@ function ensurePathOrdinal(st, key) {
|
|
|
3465
3482
|
return ordinal;
|
|
3466
3483
|
}
|
|
3467
3484
|
function pathHasAsyncValidationByKey(st, key, segments) {
|
|
3485
|
+
if (st.schema.needsAsyncValidation?.() === false) return false;
|
|
3468
3486
|
const cached = st.pathAsyncCache.get(key);
|
|
3469
3487
|
if (cached !== void 0) return cached;
|
|
3470
3488
|
const candidates = st.schema.getSchemasAtPath(segments);
|
|
@@ -3585,19 +3603,16 @@ function touchFieldRecord(st, pathKey, path, patch) {
|
|
|
3585
3603
|
path,
|
|
3586
3604
|
updatedAt: patch.updatedAt ?? current?.updatedAt ?? null,
|
|
3587
3605
|
connected: patch.connected ?? current?.connected ?? false,
|
|
3588
|
-
// focused/blurred
|
|
3589
|
-
//
|
|
3590
|
-
//
|
|
3591
|
-
// `current`, losing the intent. `!== undefined` honours an
|
|
3592
|
-
// explicit null and preserves current only on absence.
|
|
3606
|
+
// `focused` / `blurred` need an explicit-undefined guard: a patch
|
|
3607
|
+
// legitimately carries `null` to mark a disconnect, and `??` would
|
|
3608
|
+
// short-circuit on it and fall through to `current`, losing the intent.
|
|
3593
3609
|
focused: patch.focused !== void 0 ? patch.focused : current?.focused ?? null,
|
|
3594
3610
|
blurred: patch.blurred !== void 0 ? patch.blurred : current?.blurred ?? null,
|
|
3595
|
-
// touched is plain
|
|
3596
|
-
// guard here because `false` is not nullish.
|
|
3611
|
+
// `touched` is a plain boolean, so `??` is equivalent to the guard above.
|
|
3597
3612
|
touched: patch.touched ?? current?.touched ?? false,
|
|
3598
|
-
// interacted is sticky-true
|
|
3599
|
-
//
|
|
3600
|
-
//
|
|
3613
|
+
// `interacted` is sticky-true and a merge patch only ever sets it, so `??`
|
|
3614
|
+
// preserves the current bit. Only the reset paths clear it, and they
|
|
3615
|
+
// reconstruct the record outright.
|
|
3601
3616
|
interacted: patch.interacted ?? current?.interacted ?? false,
|
|
3602
3617
|
blurredAfterInteraction: patch.blurredAfterInteraction ?? current?.blurredAfterInteraction ?? false
|
|
3603
3618
|
});
|
|
@@ -3796,16 +3811,19 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3796
3811
|
}
|
|
3797
3812
|
}
|
|
3798
3813
|
}
|
|
3799
|
-
|
|
3800
|
-
if (
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3814
|
+
let newlyAuthored = false;
|
|
3815
|
+
if (st.hasPreprocessOrCoerce) {
|
|
3816
|
+
const wasAuthoredBefore = st.authoredPaths.has(pathKey);
|
|
3817
|
+
if (arrayOpRemap !== null && Array.isArray(value)) {
|
|
3818
|
+
if (path.length > 0) st.authoredPaths.add(pathKey);
|
|
3819
|
+
for (const idx of arrayOpRemap.fresh) {
|
|
3820
|
+
walkAuthoredFromConstraints(value[idx], [...path, idx], st.authoredPaths);
|
|
3821
|
+
}
|
|
3822
|
+
} else {
|
|
3823
|
+
walkAuthoredFromConstraints(value, path, st.authoredPaths);
|
|
3804
3824
|
}
|
|
3805
|
-
|
|
3806
|
-
walkAuthoredFromConstraints(value, path, st.authoredPaths);
|
|
3825
|
+
newlyAuthored = !wasAuthoredBefore && st.authoredPaths.has(pathKey);
|
|
3807
3826
|
}
|
|
3808
|
-
const newlyAuthored = !wasAuthoredBefore && st.authoredPaths.has(pathKey);
|
|
3809
3827
|
let completedValue;
|
|
3810
3828
|
if (arrayOpRemap !== null && Array.isArray(value)) {
|
|
3811
3829
|
for (const idx of arrayOpRemap.fresh) {
|
|
@@ -4062,22 +4080,38 @@ function getValueAtPath(st, path) {
|
|
|
4062
4080
|
return getAtPath(st.form.value, path);
|
|
4063
4081
|
}
|
|
4064
4082
|
const ERROR_SOURCES = ["schema", "user"];
|
|
4083
|
+
function createErrorCells(schema, pristine) {
|
|
4084
|
+
const raw = /* @__PURE__ */ new Map();
|
|
4085
|
+
const cells = shallowReactive(raw);
|
|
4086
|
+
return (seed) => {
|
|
4087
|
+
const data = pristine;
|
|
4088
|
+
if (data !== void 0) {
|
|
4089
|
+
pristine = void 0;
|
|
4090
|
+
if (seed) {
|
|
4091
|
+
for (const [key, list] of groupErrorsByKey(schema.validateSync(data))) {
|
|
4092
|
+
raw.set(key, { schema: list, user: NO_ERRORS });
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
return cells;
|
|
4097
|
+
};
|
|
4098
|
+
}
|
|
4065
4099
|
function setErrorChannelForKey(st, key, src, entries) {
|
|
4066
|
-
const current = st.errorCells.get(key);
|
|
4100
|
+
const current = st.errorCells().get(key);
|
|
4067
4101
|
const schema = src === "schema" ? entries : current?.schema ?? NO_ERRORS;
|
|
4068
4102
|
const user = src === "user" ? entries : current?.user ?? NO_ERRORS;
|
|
4069
4103
|
if (schema.length === 0 && user.length === 0) {
|
|
4070
|
-
if (current !== void 0) st.errorCells.delete(key);
|
|
4104
|
+
if (current !== void 0) st.errorCells().delete(key);
|
|
4071
4105
|
return;
|
|
4072
4106
|
}
|
|
4073
|
-
st.errorCells.set(key, { schema, user });
|
|
4107
|
+
st.errorCells().set(key, { schema, user });
|
|
4074
4108
|
}
|
|
4075
4109
|
function replaceErrorChannel(st, src, entries) {
|
|
4076
4110
|
const other = src === "schema" ? "user" : "schema";
|
|
4077
4111
|
const grouped = groupErrorsByKey(entries);
|
|
4078
|
-
for (const [key, cell] of st.errorCells) {
|
|
4112
|
+
for (const [key, cell] of st.errorCells()) {
|
|
4079
4113
|
if (cell[other].length === 0) {
|
|
4080
|
-
st.errorCells.delete(key);
|
|
4114
|
+
st.errorCells().delete(key);
|
|
4081
4115
|
continue;
|
|
4082
4116
|
}
|
|
4083
4117
|
const fresh = grouped.get(key);
|
|
@@ -4102,8 +4136,9 @@ function clearErrorChannel(st, src, path) {
|
|
|
4102
4136
|
function applySchemaErrorsForSubtree(st, path, entries) {
|
|
4103
4137
|
const parentKey = canonicalizePath(path).key;
|
|
4104
4138
|
const grouped = groupErrorsByKey(entries);
|
|
4139
|
+
if (path.length === 0) st.skipErrorSeed();
|
|
4105
4140
|
if (!grouped.has(parentKey)) setErrorChannelForKey(st, parentKey, "schema", NO_ERRORS);
|
|
4106
|
-
for (const [existingKey, cell] of st.errorCells) {
|
|
4141
|
+
for (const [existingKey, cell] of st.errorCells()) {
|
|
4107
4142
|
if (existingKey === parentKey) continue;
|
|
4108
4143
|
if (cell.schema.length === 0) continue;
|
|
4109
4144
|
if (isPathKeyUnder(existingKey, path) && !grouped.has(existingKey)) {
|
|
@@ -4115,15 +4150,15 @@ function applySchemaErrorsForSubtree(st, path, entries) {
|
|
|
4115
4150
|
}
|
|
4116
4151
|
}
|
|
4117
4152
|
function restoreErrorCells(st, entries) {
|
|
4118
|
-
st.
|
|
4153
|
+
st.skipErrorSeed().clear();
|
|
4119
4154
|
for (const [key, cell] of entries) {
|
|
4120
4155
|
if (cell.schema.length === 0 && cell.user.length === 0) continue;
|
|
4121
|
-
st.errorCells.set(key, { schema: [...cell.schema], user: [...cell.user] });
|
|
4156
|
+
st.errorCells().set(key, { schema: [...cell.schema], user: [...cell.user] });
|
|
4122
4157
|
}
|
|
4123
4158
|
}
|
|
4124
4159
|
function getErrorsForPath(st, path) {
|
|
4125
4160
|
const { key } = canonicalizePath(path);
|
|
4126
|
-
const cell = st.errorCells.get(key);
|
|
4161
|
+
const cell = st.errorCells().get(key);
|
|
4127
4162
|
const blankForKey = st.derivedBlankErrors.value.get(key);
|
|
4128
4163
|
if (cell === void 0 && blankForKey === void 0) {
|
|
4129
4164
|
return [];
|
|
@@ -4160,13 +4195,13 @@ function markFocused(st, path, focused, meta) {
|
|
|
4160
4195
|
touchFieldRecord(st, key, path, {
|
|
4161
4196
|
focused,
|
|
4162
4197
|
blurred: !focused,
|
|
4163
|
-
// `touched` flips
|
|
4164
|
-
//
|
|
4198
|
+
// `touched` flips true on blur and stays; a focused field keeps whatever
|
|
4199
|
+
// it held.
|
|
4165
4200
|
touched: focused ? current?.touched ?? false : true,
|
|
4166
|
-
// `blurredAfterInteraction` flips true on the first blur
|
|
4167
|
-
//
|
|
4168
|
-
//
|
|
4169
|
-
//
|
|
4201
|
+
// `blurredAfterInteraction` flips true on the first blur after a value
|
|
4202
|
+
// edit and stays. A tab-through blur before any edit leaves it false,
|
|
4203
|
+
// since `interacted` is still false, which is what keeps a clean
|
|
4204
|
+
// tab-through from arming the gate.
|
|
4170
4205
|
blurredAfterInteraction: !focused && current?.interacted === true ? true : current?.blurredAfterInteraction ?? false
|
|
4171
4206
|
});
|
|
4172
4207
|
const focusMode = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
@@ -4273,7 +4308,14 @@ function adoptResolvedDefaults(st, value) {
|
|
|
4273
4308
|
st.schema
|
|
4274
4309
|
)
|
|
4275
4310
|
);
|
|
4276
|
-
seedOriginalsFromBaseline(
|
|
4311
|
+
seedOriginalsFromBaseline(
|
|
4312
|
+
st,
|
|
4313
|
+
computeBaseline(
|
|
4314
|
+
st.schema,
|
|
4315
|
+
st.defaultValues,
|
|
4316
|
+
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4317
|
+
)
|
|
4318
|
+
);
|
|
4277
4319
|
}
|
|
4278
4320
|
function reset(st, nextDefaultValues) {
|
|
4279
4321
|
const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
|
|
@@ -4282,13 +4324,16 @@ function reset(st, nextDefaultValues) {
|
|
|
4282
4324
|
st.schema
|
|
4283
4325
|
);
|
|
4284
4326
|
st.defaultValues = structuralSnapshot(resetSource);
|
|
4285
|
-
const
|
|
4286
|
-
|
|
4327
|
+
const next = computeBaseline(
|
|
4328
|
+
st.schema,
|
|
4329
|
+
resetSource,
|
|
4330
|
+
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4331
|
+
);
|
|
4287
4332
|
rebuildAuthoredPaths(st, resetSource, next);
|
|
4288
4333
|
applyFormReplacement(st, next);
|
|
4289
4334
|
st.arrayIdentity.rebaselineAll();
|
|
4290
4335
|
st.removedSubtrees.clear();
|
|
4291
|
-
seedOriginalsFromBaseline(st, next
|
|
4336
|
+
seedOriginalsFromBaseline(st, next);
|
|
4292
4337
|
if (nextDefaultValues !== void 0) {
|
|
4293
4338
|
const mentioned = /* @__PURE__ */ new Set();
|
|
4294
4339
|
walkAuthoredFromConstraints(nextDefaultValues, [], mentioned);
|
|
@@ -4298,14 +4343,8 @@ function reset(st, nextDefaultValues) {
|
|
|
4298
4343
|
for (const key of st.originalBlankPaths) {
|
|
4299
4344
|
st.blankPaths.add(key);
|
|
4300
4345
|
}
|
|
4301
|
-
st.
|
|
4302
|
-
|
|
4303
|
-
replaceErrorChannel(st, "schema", resetResponse.errors);
|
|
4304
|
-
}
|
|
4305
|
-
const syncResult = st.schema.validateAtPath(st.form.value, void 0, { sync: true });
|
|
4306
|
-
if (!(syncResult instanceof Promise) && !syncResult.success) {
|
|
4307
|
-
applySchemaErrorsForSubtree(st, [], syncResult.errors);
|
|
4308
|
-
}
|
|
4346
|
+
st.skipErrorSeed().clear();
|
|
4347
|
+
replaceErrorChannel(st, "schema", st.schema.validateSync(next));
|
|
4309
4348
|
st.firstValidationDone.value = initialFirstValidationGate(st.schema);
|
|
4310
4349
|
queueInitialAsyncValidation(st);
|
|
4311
4350
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -4382,7 +4421,7 @@ function resetField(st, path) {
|
|
|
4382
4421
|
}
|
|
4383
4422
|
}
|
|
4384
4423
|
function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
4385
|
-
for (const [errorKey, cell] of st.errorCells) {
|
|
4424
|
+
for (const [errorKey, cell] of st.errorCells()) {
|
|
4386
4425
|
for (const src of ERROR_SOURCES) {
|
|
4387
4426
|
const first = cell[src][0];
|
|
4388
4427
|
if (first !== void 0 && isPathPrefix(prefix, first.path)) {
|
|
@@ -4447,8 +4486,8 @@ function createFormStore(options) {
|
|
|
4447
4486
|
const fieldValidatingSince = reactive(/* @__PURE__ */ new Map());
|
|
4448
4487
|
const displayEngine = createDisplayEngine(ssr);
|
|
4449
4488
|
cleanupHooks.push(() => displayEngine.dispose());
|
|
4450
|
-
const
|
|
4451
|
-
const schemaInitialData =
|
|
4489
|
+
const ownDefaultValues = structuralSnapshot(defaultValues);
|
|
4490
|
+
const schemaInitialData = computeBaseline(schema, ownDefaultValues, options.schemaDefaults);
|
|
4452
4491
|
const authoredPaths = /* @__PURE__ */ new Set();
|
|
4453
4492
|
const initialData = hydration !== void 0 ? hydration.form : structuralSnapshot(schemaInitialData);
|
|
4454
4493
|
const hasDU = schema.hasDiscriminatedUnions?.() !== false;
|
|
@@ -4462,7 +4501,11 @@ function createFormStore(options) {
|
|
|
4462
4501
|
});
|
|
4463
4502
|
const fields = shallowReactive(/* @__PURE__ */ new Map());
|
|
4464
4503
|
const domBinding = shallowRef(null);
|
|
4465
|
-
const
|
|
4504
|
+
const errorStore = createErrorCells(
|
|
4505
|
+
schema,
|
|
4506
|
+
hydration === void 0 ? schemaInitialData : void 0
|
|
4507
|
+
);
|
|
4508
|
+
const errorCells = () => errorStore(true);
|
|
4466
4509
|
const originals = shallowReactive(/* @__PURE__ */ new Map());
|
|
4467
4510
|
const removedSubtrees = /* @__PURE__ */ new Set();
|
|
4468
4511
|
const blankPaths = reactive(/* @__PURE__ */ new Set());
|
|
@@ -4486,7 +4529,7 @@ function createFormStore(options) {
|
|
|
4486
4529
|
return result;
|
|
4487
4530
|
});
|
|
4488
4531
|
const errorPathIndex = computed(
|
|
4489
|
-
() => buildErrorPathIndex(errorCells, derivedBlankErrors.value)
|
|
4532
|
+
() => buildErrorPathIndex(errorCells(), derivedBlankErrors.value)
|
|
4490
4533
|
);
|
|
4491
4534
|
const submitting = ref(false);
|
|
4492
4535
|
const activeSubmissions = ref(0);
|
|
@@ -4618,21 +4661,16 @@ function createFormStore(options) {
|
|
|
4618
4661
|
blankPaths,
|
|
4619
4662
|
originalBlankPaths,
|
|
4620
4663
|
// --- kernel-internal state ---
|
|
4621
|
-
//
|
|
4622
|
-
//
|
|
4623
|
-
//
|
|
4624
|
-
|
|
4625
|
-
// and this field is now durable state that every `reset()` reads, so
|
|
4626
|
-
// it should not depend on it. The copy also means a consumer who
|
|
4627
|
-
// keeps a reference to the literal they passed cannot mutate the
|
|
4628
|
-
// form's defaults from outside. `reset()` snapshots for a harder
|
|
4629
|
-
// reason (see there) where an alias IS reachable.
|
|
4630
|
-
defaultValues: structuralSnapshot(defaultValues),
|
|
4664
|
+
// The copy taken above, which also stops a consumer holding a reference to
|
|
4665
|
+
// the literal they passed from mutating the form's defaults from outside.
|
|
4666
|
+
// `reset()` snapshots for a harder reason, where an alias IS reachable.
|
|
4667
|
+
defaultValues: ownDefaultValues,
|
|
4631
4668
|
ssrPrefetch,
|
|
4632
4669
|
rememberVariants,
|
|
4633
4670
|
fieldValidationMode,
|
|
4634
4671
|
fieldValidationDebounceMs,
|
|
4635
4672
|
hasDU,
|
|
4673
|
+
hasPreprocessOrCoerce: schema.hasPreprocessOrCoerce?.() !== false,
|
|
4636
4674
|
fieldValidationState,
|
|
4637
4675
|
formChangeListeners,
|
|
4638
4676
|
submitSuccessListeners,
|
|
@@ -4648,6 +4686,7 @@ function createFormStore(options) {
|
|
|
4648
4686
|
transformRuns,
|
|
4649
4687
|
transformWaiters,
|
|
4650
4688
|
arrayBookkeeping,
|
|
4689
|
+
skipErrorSeed: () => errorStore(false),
|
|
4651
4690
|
nextOrdinal: 0,
|
|
4652
4691
|
scheduleEpoch: 0,
|
|
4653
4692
|
lastCommittedEpoch: 0,
|
|
@@ -4664,10 +4703,10 @@ function createFormStore(options) {
|
|
|
4664
4703
|
arrayElementKey: bind(arrayElementKey),
|
|
4665
4704
|
reset: bind(reset),
|
|
4666
4705
|
resetField: bind(resetField),
|
|
4667
|
-
// The schema/user pair below reads as a fold waiting to happen.
|
|
4668
|
-
//
|
|
4669
|
-
//
|
|
4670
|
-
//
|
|
4706
|
+
// The schema/user pair below reads as a fold waiting to happen. Folding
|
|
4707
|
+
// them into a `setErrorsForPathIn(channel)` factory measures 10 B LARGER:
|
|
4708
|
+
// gzip has already collected the rent on two adjacent copies, and the
|
|
4709
|
+
// helper adds a name the original does not need.
|
|
4671
4710
|
setSchemaErrorsForPath: (path, entries) => setErrorChannelForKey(
|
|
4672
4711
|
st,
|
|
4673
4712
|
canonicalizePath(path).key,
|
|
@@ -4715,7 +4754,25 @@ function createFormStore(options) {
|
|
|
4715
4754
|
dispose: bind(dispose)
|
|
4716
4755
|
};
|
|
4717
4756
|
rebuildAuthoredPaths(st, defaultValues, schemaInitialData);
|
|
4718
|
-
|
|
4757
|
+
const initStamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4758
|
+
diffAndApply({}, schemaInitialData, [], (patch) => {
|
|
4759
|
+
if (patch.kind !== "added") return;
|
|
4760
|
+
const { key } = canonicalizePath(patch.path);
|
|
4761
|
+
originals.set(key, { segments: patch.path, value: patch.newValue });
|
|
4762
|
+
ensurePathOrdinal(st, key);
|
|
4763
|
+
if (hydration === void 0) {
|
|
4764
|
+
fields.set(key, {
|
|
4765
|
+
path: patch.path,
|
|
4766
|
+
updatedAt: initStamp,
|
|
4767
|
+
connected: false,
|
|
4768
|
+
focused: null,
|
|
4769
|
+
blurred: null,
|
|
4770
|
+
touched: false,
|
|
4771
|
+
interacted: false,
|
|
4772
|
+
blurredAfterInteraction: false
|
|
4773
|
+
});
|
|
4774
|
+
}
|
|
4775
|
+
});
|
|
4719
4776
|
if (hydration !== void 0) {
|
|
4720
4777
|
for (const [rawKey, record] of hydration.fields) {
|
|
4721
4778
|
if (typeof rawKey !== "string" || !isHydratedFieldRecord(record)) {
|
|
@@ -4735,25 +4792,6 @@ function createFormStore(options) {
|
|
|
4735
4792
|
}
|
|
4736
4793
|
setErrorChannelForKey(st, rawKey, "user", errs);
|
|
4737
4794
|
}
|
|
4738
|
-
} else {
|
|
4739
|
-
const initStamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4740
|
-
diffAndApply({}, initialData, [], (patch) => {
|
|
4741
|
-
if (patch.kind !== "added") return;
|
|
4742
|
-
const { key } = canonicalizePath(patch.path);
|
|
4743
|
-
fields.set(key, {
|
|
4744
|
-
path: patch.path,
|
|
4745
|
-
updatedAt: initStamp,
|
|
4746
|
-
connected: false,
|
|
4747
|
-
focused: null,
|
|
4748
|
-
blurred: null,
|
|
4749
|
-
touched: false,
|
|
4750
|
-
interacted: false,
|
|
4751
|
-
blurredAfterInteraction: false
|
|
4752
|
-
});
|
|
4753
|
-
});
|
|
4754
|
-
if (!schemaResponse.success) {
|
|
4755
|
-
replaceErrorChannel(st, "schema", schemaResponse.errors);
|
|
4756
|
-
}
|
|
4757
4795
|
}
|
|
4758
4796
|
queueInitialAsyncValidation(st);
|
|
4759
4797
|
return st;
|
|
@@ -4846,9 +4884,11 @@ const HISTORY_MODULE_KEY = "history";
|
|
|
4846
4884
|
function buildFreshState(key, schema, configuration, registry) {
|
|
4847
4885
|
const pending = registry.pendingHydration.get(key);
|
|
4848
4886
|
if (pending !== void 0) registry.pendingHydration.delete(key);
|
|
4887
|
+
const schemaDefaults = schema.getDefaultValues({ useDefaultSchemaValues: true });
|
|
4849
4888
|
const walked = walkUnsetSentinels(
|
|
4850
4889
|
configuration.defaultValues,
|
|
4851
|
-
schema
|
|
4890
|
+
schema,
|
|
4891
|
+
schemaDefaults
|
|
4852
4892
|
);
|
|
4853
4893
|
let initialBlankPaths;
|
|
4854
4894
|
if (pending === void 0) {
|
|
@@ -4858,6 +4898,7 @@ function buildFreshState(key, schema, configuration, registry) {
|
|
|
4858
4898
|
formKey: key,
|
|
4859
4899
|
schema,
|
|
4860
4900
|
defaultValues: walked.cleanedValues,
|
|
4901
|
+
schemaDefaults,
|
|
4861
4902
|
hydration: pending,
|
|
4862
4903
|
ssr: registry.ssr,
|
|
4863
4904
|
...pickDefined({
|
|
@@ -4868,12 +4909,10 @@ function buildFreshState(key, schema, configuration, registry) {
|
|
|
4868
4909
|
coerce: configuration.coerce,
|
|
4869
4910
|
initialBlankPaths
|
|
4870
4911
|
}),
|
|
4871
|
-
// Server
|
|
4872
|
-
//
|
|
4873
|
-
//
|
|
4874
|
-
//
|
|
4875
|
-
// wizard explicitly skipped this key — even an explicit
|
|
4876
|
-
// `form.activate()` defers to the wizard's render-efficiency
|
|
4912
|
+
// Server only. `enqueue` records intent on every `state.activate()`
|
|
4913
|
+
// so a wizard skip-list override has a consistent set to diff
|
|
4914
|
+
// against; `shouldFire` lets the activate path bail on a key the
|
|
4915
|
+
// wizard skipped. Even an explicit `form.activate()` defers to that
|
|
4877
4916
|
// skip-list on the server.
|
|
4878
4917
|
...registry.ssr ? {
|
|
4879
4918
|
ssrPrefetch: {
|
|
@@ -4910,6 +4949,7 @@ function resolveFormKey(key) {
|
|
|
4910
4949
|
}
|
|
4911
4950
|
|
|
4912
4951
|
let injectedInstanceCounter = 0;
|
|
4952
|
+
const sharedApis = /* @__PURE__ */ new WeakMap();
|
|
4913
4953
|
function injectForm(input) {
|
|
4914
4954
|
const key = typeof input === "string" ? input : input?.key;
|
|
4915
4955
|
const ssrAccessed = typeof input === "object" && input !== null ? input.__ssrAccessed === true : false;
|
|
@@ -4932,12 +4972,37 @@ function injectForm(input) {
|
|
|
4932
4972
|
apiOptions.history = history;
|
|
4933
4973
|
}
|
|
4934
4974
|
const ambientInstanceId = getCurrentInstance() !== null ? inject(kFormInstanceId, null) : null;
|
|
4935
|
-
const
|
|
4936
|
-
return buildFormApi(
|
|
4975
|
+
const api = ambientInstanceId !== null ? shareApi(state, ambientInstanceId, apiOptions) : buildFormApi(
|
|
4937
4976
|
state,
|
|
4938
|
-
|
|
4977
|
+
getCurrentInstance() !== null ? useId() : `atta:form-instance-injected:${injectedInstanceCounter++}`,
|
|
4939
4978
|
apiOptions
|
|
4940
4979
|
);
|
|
4980
|
+
return api;
|
|
4981
|
+
}
|
|
4982
|
+
function shareApi(state, formInstanceId, options) {
|
|
4983
|
+
let instances = sharedApis.get(state);
|
|
4984
|
+
if (instances === void 0) {
|
|
4985
|
+
instances = /* @__PURE__ */ new Map();
|
|
4986
|
+
sharedApis.set(state, instances);
|
|
4987
|
+
}
|
|
4988
|
+
const byInstance = instances;
|
|
4989
|
+
let shared = byInstance.get(formInstanceId);
|
|
4990
|
+
if (shared === void 0) {
|
|
4991
|
+
const scope = effectScope(true);
|
|
4992
|
+
const api = scope.run(() => buildFormApi(state, formInstanceId, options));
|
|
4993
|
+
if (api === void 0) return buildFormApi(state, formInstanceId, options);
|
|
4994
|
+
shared = { api, scope, users: 0 };
|
|
4995
|
+
byInstance.set(formInstanceId, shared);
|
|
4996
|
+
}
|
|
4997
|
+
const entry = shared;
|
|
4998
|
+
entry.users += 1;
|
|
4999
|
+
onScopeDispose(() => {
|
|
5000
|
+
entry.users -= 1;
|
|
5001
|
+
if (entry.users > 0) return;
|
|
5002
|
+
entry.scope.stop();
|
|
5003
|
+
byInstance.delete(formInstanceId);
|
|
5004
|
+
});
|
|
5005
|
+
return entry.api;
|
|
4941
5006
|
}
|
|
4942
5007
|
function resolveState(key, registry) {
|
|
4943
5008
|
if (key !== void 0) {
|
|
@@ -4997,22 +5062,23 @@ function useRegister(options) {
|
|
|
4997
5062
|
const capturedRegisterValue = shallowRef(void 0);
|
|
4998
5063
|
const refreshAndStripBridgeAttrs = () => {
|
|
4999
5064
|
const rawAttrs = instance.attrs;
|
|
5065
|
+
const parentBinding = instance.vnode.dirs?.find(
|
|
5066
|
+
(dir) => dir.dir?.[V_REGISTER_MARKER] === true
|
|
5067
|
+
);
|
|
5000
5068
|
if ("registerValue" in rawAttrs) {
|
|
5001
5069
|
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
5002
5070
|
delete rawAttrs["registerValue"];
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
}
|
|
5015
|
-
}
|
|
5071
|
+
} else if (parentBinding !== void 0) {
|
|
5072
|
+
capturedRegisterValue.value = parentBinding.value;
|
|
5073
|
+
}
|
|
5074
|
+
const captured = capturedRegisterValue.value;
|
|
5075
|
+
if (captured !== void 0) {
|
|
5076
|
+
armDomBinding(captured);
|
|
5077
|
+
if (parentBinding !== void 0) {
|
|
5078
|
+
recordInheritedModifiers(
|
|
5079
|
+
captured,
|
|
5080
|
+
withInheritedModifiers(parentBinding.value, parentBinding.modifiers)
|
|
5081
|
+
);
|
|
5016
5082
|
}
|
|
5017
5083
|
}
|
|
5018
5084
|
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
@@ -5119,11 +5185,11 @@ const NOOP_SUCCESS = {
|
|
|
5119
5185
|
data: EMPTY_VALUE,
|
|
5120
5186
|
errors: void 0
|
|
5121
5187
|
};
|
|
5122
|
-
const NOOP_DEFAULTS = NOOP_SUCCESS;
|
|
5123
5188
|
let NOOP_SCHEMA;
|
|
5124
5189
|
function buildNoopWizardSchema() {
|
|
5125
5190
|
NOOP_SCHEMA ?? (NOOP_SCHEMA = {
|
|
5126
|
-
getDefaultValues: () =>
|
|
5191
|
+
getDefaultValues: () => EMPTY_VALUE,
|
|
5192
|
+
validateSync: () => [],
|
|
5127
5193
|
getDefaultAtPath: () => void 0,
|
|
5128
5194
|
getEmptyValueAtPath: () => void 0,
|
|
5129
5195
|
isPreprocessOrCoerceLeaf: () => false,
|
|
@@ -5139,7 +5205,8 @@ function buildNoopWizardSchema() {
|
|
|
5139
5205
|
isLeafAtPath: () => false,
|
|
5140
5206
|
isRequiredAtPath: () => false,
|
|
5141
5207
|
getUnionDiscriminatorAtPath: () => void 0,
|
|
5142
|
-
hasDiscriminatedUnions: () => false
|
|
5208
|
+
hasDiscriminatedUnions: () => false,
|
|
5209
|
+
hasPreprocessOrCoerce: () => false
|
|
5143
5210
|
});
|
|
5144
5211
|
return NOOP_SCHEMA;
|
|
5145
5212
|
}
|
|
@@ -5335,27 +5402,33 @@ function useWizard(options) {
|
|
|
5335
5402
|
return activeKey.value === "" ? void 0 : activeKey.value;
|
|
5336
5403
|
}
|
|
5337
5404
|
};
|
|
5338
|
-
function lazyComputedFor(marker) {
|
|
5405
|
+
function lazyComputedFor(marker, index) {
|
|
5339
5406
|
const cached = lazyComputeds.get(marker);
|
|
5340
5407
|
if (cached !== void 0) return cached;
|
|
5341
5408
|
const c = computed(() => {
|
|
5342
5409
|
void lazyEpoch.value;
|
|
5343
|
-
return
|
|
5410
|
+
return callConsumerFn(
|
|
5411
|
+
() => marker.resolve(slotCtx),
|
|
5412
|
+
void 0);
|
|
5344
5413
|
});
|
|
5345
5414
|
lazyComputeds.set(marker, c);
|
|
5346
5415
|
return c;
|
|
5347
5416
|
}
|
|
5348
5417
|
const MAX_SLOT_DEPTH = 32;
|
|
5349
|
-
function normalizeSlot(slot, ctx, gated, depth) {
|
|
5418
|
+
function normalizeSlot(slot, ctx, gated, depth, index) {
|
|
5350
5419
|
if (depth > MAX_SLOT_DEPTH) {
|
|
5351
5420
|
return void 0;
|
|
5352
5421
|
}
|
|
5353
5422
|
if (slot === void 0 || slot === null) return void 0;
|
|
5354
5423
|
if (typeof slot === "string") return { form: getOrBuildNoop(slot), gated };
|
|
5355
5424
|
if (isGateMarker(slot)) return normalizeSlot(slot.inner, ctx, true, depth + 1);
|
|
5356
|
-
if (isLazyMarker(slot))
|
|
5425
|
+
if (isLazyMarker(slot)) {
|
|
5426
|
+
return normalizeSlot(lazyComputedFor(slot).value, ctx, gated, depth + 1);
|
|
5427
|
+
}
|
|
5357
5428
|
if (typeof slot === "function") {
|
|
5358
|
-
const result =
|
|
5429
|
+
const result = callConsumerFn(
|
|
5430
|
+
() => slot(ctx),
|
|
5431
|
+
void 0);
|
|
5359
5432
|
return normalizeSlot(result, ctx, gated, depth + 1);
|
|
5360
5433
|
}
|
|
5361
5434
|
if (isAnyForm(slot)) return { form: slot, gated };
|
|
@@ -5673,13 +5746,14 @@ function useWizard(options) {
|
|
|
5673
5746
|
seedRef.value = resolved.value;
|
|
5674
5747
|
applyGateSeed(resolved.value);
|
|
5675
5748
|
} else {
|
|
5676
|
-
const eager = resolved.factory();
|
|
5749
|
+
const eager = callConsumerFn(() => resolved.factory(), void 0);
|
|
5677
5750
|
if (eager instanceof Promise) {
|
|
5678
5751
|
void eager.then((value) => {
|
|
5679
5752
|
seedRef.value = value;
|
|
5680
5753
|
applyGateSeed(value);
|
|
5754
|
+
}).catch((err) => {
|
|
5681
5755
|
});
|
|
5682
|
-
} else {
|
|
5756
|
+
} else if (eager !== void 0) {
|
|
5683
5757
|
seedRef.value = eager;
|
|
5684
5758
|
applyGateSeed(eager);
|
|
5685
5759
|
}
|
|
@@ -5752,10 +5826,13 @@ function useWizard(options) {
|
|
|
5752
5826
|
const statuses = buildWizardStatusesProxy(statusesRecord);
|
|
5753
5827
|
const progressOverride = options.progress;
|
|
5754
5828
|
const progress = computed(() => {
|
|
5829
|
+
const list = compiledSteps.value;
|
|
5755
5830
|
if (progressOverride !== void 0) {
|
|
5756
|
-
|
|
5831
|
+
const override = callConsumerFn(
|
|
5832
|
+
() => progressOverride(list),
|
|
5833
|
+
null);
|
|
5834
|
+
if (override !== null) return override;
|
|
5757
5835
|
}
|
|
5758
|
-
const list = compiledSteps.value;
|
|
5759
5836
|
if (list.length === 0) return 0;
|
|
5760
5837
|
let valid = 0;
|
|
5761
5838
|
for (const step of list) {
|
|
@@ -5783,11 +5860,15 @@ function useWizard(options) {
|
|
|
5783
5860
|
historyHandle.subscribe((value) => {
|
|
5784
5861
|
urlMirror.value = value;
|
|
5785
5862
|
});
|
|
5786
|
-
const
|
|
5863
|
+
const consumerRestore = options.restore;
|
|
5864
|
+
const restoreCallback = consumerRestore === false ? void 0 : consumerRestore !== void 0 ? () => callConsumerFn(() => consumerRestore(), void 0) : () => {
|
|
5787
5865
|
const value = urlMirror.value;
|
|
5788
5866
|
return value === void 0 ? void 0 : { step: value };
|
|
5789
5867
|
};
|
|
5790
|
-
const
|
|
5868
|
+
const consumerPersist = options.persist;
|
|
5869
|
+
const persistCallback = consumerPersist === false ? void 0 : consumerPersist !== void 0 ? (state) => {
|
|
5870
|
+
callConsumerFn(() => consumerPersist(state), void 0);
|
|
5871
|
+
} : (state) => {
|
|
5791
5872
|
if (state.step === void 0) return;
|
|
5792
5873
|
const current = historyHandle.read();
|
|
5793
5874
|
const effectiveCurrent = current !== void 0 && isCompiledKey(current) ? current : firstKey();
|
|
@@ -6038,7 +6119,7 @@ function useWizard(options) {
|
|
|
6038
6119
|
for (const key of keys) {
|
|
6039
6120
|
const store = registry.forms.get(key);
|
|
6040
6121
|
if (store === void 0) continue;
|
|
6041
|
-
for (const cell of store.errorCells.values()) {
|
|
6122
|
+
for (const cell of store.errorCells().values()) {
|
|
6042
6123
|
for (const err of cell.user) out.push(toWizardAggregateError(err, key));
|
|
6043
6124
|
}
|
|
6044
6125
|
}
|