attaform 0.29.0 → 0.30.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 -5
- package/dist/abstract.mjs +4 -4
- package/dist/dev/abstract.mjs +4 -4
- package/dist/dev/chunks/dev-key-collision-warnings.mjs +47 -8
- package/dist/dev/chunks/devtools.mjs +1 -1
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +1 -2
- package/dist/dev/index.mjs +5 -5
- package/dist/dev/runtime/plugins/attaform.mjs +3 -3
- package/dist/dev/shared/{attaform-dev.BO-71R54.mjs → attaform-dev.BK6Ge2qR.mjs} +34 -188
- package/dist/dev/shared/{attaform-dev.A-TpJW0B.mjs → attaform-dev.BQc5QV3Y.mjs} +1 -19
- package/dist/dev/shared/{attaform-dev.DrzObAZo.mjs → attaform-dev.BcNtyOmf.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.ButTkwHd.mjs → attaform-dev.BcYT6tFh.mjs} +7 -8
- package/dist/dev/shared/{attaform-dev.BgM6FdtA.mjs → attaform-dev.BisFstxh.mjs} +91 -59
- package/dist/dev/shared/{attaform-dev.DHuydLAC.mjs → attaform-dev.CQ2rJiAX.mjs} +560 -631
- package/dist/dev/shared/{attaform-dev.D8aoKb89.mjs → attaform-dev.D6CLvaQT.mjs} +8 -8
- package/dist/dev/shared/{attaform-dev.q6UutkCx.mjs → attaform-dev.DTrHonpc.mjs} +69 -120
- package/dist/dev/shared/{attaform-dev.DD5m2W51.mjs → attaform-dev.DUZckyV8.mjs} +1 -3
- 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 +2 -2
- package/dist/directive.mjs +1 -1
- package/dist/history.d.mts +1 -1
- package/dist/history.mjs +1 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +5 -5
- package/dist/nuxt.d.mts +2 -11
- package/dist/nuxt.mjs +0 -1
- package/dist/runtime/plugins/attaform.mjs +3 -3
- package/dist/shared/{attaform.DffRL5pP.mjs → attaform.B3resMQ1.mjs} +8 -8
- package/dist/shared/{attaform.Cvao8bW5.mjs → attaform.BRDDQeHV.mjs} +6 -6
- package/dist/shared/{attaform.C2MVyuxC.mjs → attaform.BXneBxEj.mjs} +34 -188
- package/dist/shared/{attaform.BndjUUYX.mjs → attaform.ByWP6kSx.mjs} +4 -4
- package/dist/shared/{attaform.D1fnTifF.mjs → attaform.CJ8DpRGj.mjs} +69 -120
- package/dist/shared/{attaform.B0dKL8ST.mjs → attaform.CUfrMK7t.mjs} +91 -59
- package/dist/shared/{attaform.CZYt_5N_.mjs → attaform.CdZIEf7_.mjs} +1 -19
- package/dist/shared/{attaform.axHXVQO7.d.mts → attaform.Clz0ArIi.d.mts} +1 -1
- package/dist/shared/{attaform.CZMAYwSK.mjs → attaform.DNJOWjQw.mjs} +559 -588
- package/dist/shared/{attaform.CIWLMY-R.d.mts → attaform.Rc9u4Vfw.d.mts} +1 -1
- package/dist/shared/{attaform.DDtqHYv1.d.mts → attaform.UGyOK83T.d.mts} +115 -214
- package/dist/shared/{attaform.D0x-qSXm.mjs → attaform.WiGdIqgx.mjs} +1 -3
- package/dist/shared/{attaform.CsoeRi3P.d.mts → attaform.bKLzMU0o.d.mts} +99 -493
- package/dist/vite.mjs +5 -0
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.mjs +6 -6
- package/dist/zod-v4.d.mts +9 -9
- package/dist/zod-v4.mjs +6 -6
- package/dist/zod.d.mts +4 -4
- package/dist/zod.mjs +5 -5
- package/package.json +3 -2
- package/skills/attaform/SKILL.md +1 -1
- package/skills/attaform/references/custom-components.md +1 -1
- package/dist/chunks/fingerprint.mjs +0 -183
- package/dist/chunks/fingerprint2.mjs +0 -159
- package/dist/dev/chunks/fingerprint.mjs +0 -183
- package/dist/dev/chunks/fingerprint2.mjs +0 -159
- package/dist/dev/shared/attaform-dev.BxfsuwBR.mjs +0 -44
- package/dist/shared/attaform.BxfsuwBR.mjs +0 -44
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, reactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope } from 'vue';
|
|
2
|
-
import { A as ANONYMOUS_FORM_KEY_PREFIX,
|
|
3
|
-
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.
|
|
4
|
-
import { R as REGISTER_OWNER_MARKER, d as armDomBinding, V as V_REGISTER_MARKER } from './attaform-dev.
|
|
5
|
-
import { i as isPathPrefix, e as canonicalizePath,
|
|
1
|
+
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope } from 'vue';
|
|
2
|
+
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-dev.BcYT6tFh.mjs';
|
|
3
|
+
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.DUZckyV8.mjs';
|
|
4
|
+
import { R as REGISTER_OWNER_MARKER, d as armDomBinding, V as V_REGISTER_MARKER } from './attaform-dev.D6CLvaQT.mjs';
|
|
5
|
+
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-dev.BQc5QV3Y.mjs';
|
|
6
6
|
|
|
7
7
|
const AttaformErrorCode = {
|
|
8
8
|
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
@@ -77,11 +77,6 @@ function makeBlankRequiredError(segments) {
|
|
|
77
77
|
}
|
|
78
78
|
const NO_ERRORS = Object.freeze([]);
|
|
79
79
|
|
|
80
|
-
function crossCopyState(key, create) {
|
|
81
|
-
const carrier = globalThis;
|
|
82
|
-
return carrier[key] ?? (carrier[key] = create());
|
|
83
|
-
}
|
|
84
|
-
|
|
85
80
|
function isGateOpen(field, formMeta) {
|
|
86
81
|
return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
|
|
87
82
|
}
|
|
@@ -103,45 +98,32 @@ function earliestNonNull(a, b) {
|
|
|
103
98
|
return a < b ? a : b;
|
|
104
99
|
}
|
|
105
100
|
const DEFAULT_TIMINGS = { showDelay: 120, minVisible: 120 };
|
|
101
|
+
const { showDelay, minVisible } = DEFAULT_TIMINGS;
|
|
106
102
|
const FOCUS_OUT_GRACE = 16;
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
()
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (!isGateOpen(field, formMeta)) return { display: verdict };
|
|
121
|
-
const inFlightSince = earliestNonNull(validatingSince, transformingSince);
|
|
122
|
-
if (inFlightSince === null) {
|
|
123
|
-
if (prev.display === "pending") {
|
|
124
|
-
const shownAt = prev.pendingShownAt ?? now;
|
|
125
|
-
if (now < shownAt + minVisible)
|
|
126
|
-
return { display: "pending", pendingShownAt: shownAt, reviewAt: shownAt + minVisible };
|
|
127
|
-
}
|
|
128
|
-
return { display: verdict };
|
|
129
|
-
}
|
|
130
|
-
if (prev.display === "pending")
|
|
131
|
-
return { display: "pending", pendingShownAt: prev.pendingShownAt ?? now };
|
|
132
|
-
const window = field.focused === false ? Math.min(showDelay, FOCUS_OUT_GRACE) : showDelay;
|
|
133
|
-
if (now - inFlightSince < window) {
|
|
134
|
-
return { display: prev.display, reviewAt: inFlightSince + window };
|
|
103
|
+
const defaultDisplayState = (prev, { field, formMeta, validatingSince, transformingSince, now }) => {
|
|
104
|
+
const verdict = computeVerdict(field, formMeta);
|
|
105
|
+
if (!isGateOpen(field, formMeta)) return { display: verdict };
|
|
106
|
+
const inFlightSince = earliestNonNull(validatingSince, transformingSince);
|
|
107
|
+
if (inFlightSince === null) {
|
|
108
|
+
if (prev.display === "pending") {
|
|
109
|
+
const shownAt = prev.pendingShownAt ?? now;
|
|
110
|
+
if (now < shownAt + minVisible)
|
|
111
|
+
return {
|
|
112
|
+
display: "pending",
|
|
113
|
+
pendingShownAt: shownAt,
|
|
114
|
+
reviewAt: shownAt + minVisible
|
|
115
|
+
};
|
|
135
116
|
}
|
|
136
|
-
return { display:
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
117
|
+
return { display: verdict };
|
|
118
|
+
}
|
|
119
|
+
if (prev.display === "pending")
|
|
120
|
+
return { display: "pending", pendingShownAt: prev.pendingShownAt ?? now };
|
|
121
|
+
const window = field.focused === false ? Math.min(showDelay, FOCUS_OUT_GRACE) : showDelay;
|
|
122
|
+
if (now - inFlightSince < window) {
|
|
123
|
+
return { display: prev.display, reviewAt: inFlightSince + window };
|
|
124
|
+
}
|
|
125
|
+
return { display: "pending", pendingShownAt: now, reviewAt: now + minVisible };
|
|
126
|
+
};
|
|
145
127
|
|
|
146
128
|
function hashStableString(input, seed = 0) {
|
|
147
129
|
let h1 = 3735928559 ^ seed;
|
|
@@ -229,16 +211,27 @@ function descendStep(value, segment) {
|
|
|
229
211
|
}
|
|
230
212
|
function getAtPath(root, path) {
|
|
231
213
|
if (path.length === 0) return root;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
214
|
+
try {
|
|
215
|
+
let current = root;
|
|
216
|
+
for (const segment of path) {
|
|
217
|
+
const next = descendStep(current, segment);
|
|
218
|
+
if (next === NOT_FOUND) return void 0;
|
|
219
|
+
current = next;
|
|
220
|
+
}
|
|
221
|
+
return current;
|
|
222
|
+
} catch {
|
|
223
|
+
return void 0;
|
|
237
224
|
}
|
|
238
|
-
return current;
|
|
239
225
|
}
|
|
240
226
|
function hasAtPath(root, path) {
|
|
241
227
|
if (path.length === 0) return true;
|
|
228
|
+
try {
|
|
229
|
+
return hasAtPathUnguarded(root, path);
|
|
230
|
+
} catch {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function hasAtPathUnguarded(root, path) {
|
|
242
235
|
let current = root;
|
|
243
236
|
for (let i = 0; i < path.length - 1; i++) {
|
|
244
237
|
const segment = path[i];
|
|
@@ -265,29 +258,15 @@ function isPlainRecord(value) {
|
|
|
265
258
|
const proto = Object.getPrototypeOf(value);
|
|
266
259
|
return proto === null || proto === Object.prototype;
|
|
267
260
|
}
|
|
261
|
+
const NO_SCHEMA_DEFAULTS = /* @__PURE__ */ new Set();
|
|
262
|
+
const NO_SCHEMA_FILL = {
|
|
263
|
+
getDefaultAtPath: () => void 0,
|
|
264
|
+
arrayShapeAtPath: () => null,
|
|
265
|
+
getSlimPrimitiveTypesAtPath: () => NO_SCHEMA_DEFAULTS,
|
|
266
|
+
entryKeyKindAtPath: () => void 0
|
|
267
|
+
};
|
|
268
268
|
function setAtPath(root, path, value) {
|
|
269
|
-
return
|
|
270
|
-
}
|
|
271
|
-
function setAtPathOffset(root, path, value, offset) {
|
|
272
|
-
if (offset >= path.length) return value;
|
|
273
|
-
const head = path[offset];
|
|
274
|
-
const nextOffset = offset + 1;
|
|
275
|
-
if (root instanceof Map) {
|
|
276
|
-
const next = new Map(root);
|
|
277
|
-
const key = mapKeyForSegment(root, head);
|
|
278
|
-
next.set(key, setAtPathOffset(root.get(key), path, value, nextOffset));
|
|
279
|
-
return next;
|
|
280
|
-
}
|
|
281
|
-
if (!isRebuildableContainer(root, head)) return root;
|
|
282
|
-
if (typeof head === "number") {
|
|
283
|
-
const arr = Array.isArray(root) ? [...root] : [];
|
|
284
|
-
while (arr.length <= head) arr.push(void 0);
|
|
285
|
-
arr[head] = setAtPathOffset(arr[head], path, value, nextOffset);
|
|
286
|
-
return arr;
|
|
287
|
-
}
|
|
288
|
-
const rec = isPlainRecord(root) ? { ...root } : {};
|
|
289
|
-
safeAssign(rec, head, setAtPathOffset(safeOwnRead(rec, head), path, value, nextOffset));
|
|
290
|
-
return rec;
|
|
269
|
+
return setAtPathWithSchemaFill(root, NO_SCHEMA_FILL, path, value);
|
|
291
270
|
}
|
|
292
271
|
const NO_IN_PLACE = { applied: false };
|
|
293
272
|
function tryInPlaceLeafWrite(root, path, value) {
|
|
@@ -493,10 +472,10 @@ function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
|
|
|
493
472
|
}
|
|
494
473
|
const rec = isPlainRecord(root) ? { ...root } : {};
|
|
495
474
|
if (isLeafStep) {
|
|
496
|
-
rec
|
|
475
|
+
safeAssign(rec, head, value);
|
|
497
476
|
return rec;
|
|
498
477
|
}
|
|
499
|
-
const existing = rec
|
|
478
|
+
const existing = safeOwnRead(rec, head);
|
|
500
479
|
let childRoot;
|
|
501
480
|
if (existing === void 0 || existing !== null && typeof existing !== "object") {
|
|
502
481
|
const intermPath = [...fullPath.slice(0, startIdx + 1)];
|
|
@@ -505,11 +484,14 @@ function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
|
|
|
505
484
|
} else {
|
|
506
485
|
childRoot = existing;
|
|
507
486
|
}
|
|
508
|
-
|
|
487
|
+
safeAssign(
|
|
488
|
+
rec,
|
|
489
|
+
head,
|
|
490
|
+
setAtPathWithSchemaFillImpl(childRoot, schema, fullPath, value, startIdx + 1)
|
|
491
|
+
);
|
|
509
492
|
return rec;
|
|
510
493
|
}
|
|
511
494
|
|
|
512
|
-
const warnedDisplayStatePredicates = /* @__PURE__ */ new WeakSet();
|
|
513
495
|
function isUnderStubAncestor(state, segments) {
|
|
514
496
|
for (let i = 0; i < segments.length; i++) {
|
|
515
497
|
const ancestorPath = segments.slice(0, i);
|
|
@@ -523,16 +505,15 @@ function isUnderStubAncestor(state, segments) {
|
|
|
523
505
|
}
|
|
524
506
|
return false;
|
|
525
507
|
}
|
|
526
|
-
function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, sweep
|
|
508
|
+
function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, sweep) {
|
|
527
509
|
const cache = /* @__PURE__ */ new Map();
|
|
528
|
-
const predicate = options?.getDisplayState;
|
|
529
510
|
sweep.onEvict((key) => cache.delete(key));
|
|
530
511
|
return function getFieldState(pathInput) {
|
|
531
512
|
const { segments, key } = canonicalizePath(pathInput);
|
|
532
513
|
const cached = cache.get(key);
|
|
533
514
|
if (cached !== void 0) return cached;
|
|
534
515
|
const c = computed(
|
|
535
|
-
() => state.schema.isLeafAtPath(segments) ? buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase
|
|
516
|
+
() => state.schema.isLeafAtPath(segments) ? buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase) : buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase)
|
|
536
517
|
);
|
|
537
518
|
cache.set(key, c);
|
|
538
519
|
sweep.track(segments, key);
|
|
@@ -549,7 +530,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
549
530
|
const record = state.fields.get(key);
|
|
550
531
|
const value = state.getValueAtPath(segments);
|
|
551
532
|
const original = state.originals.get(key)?.value;
|
|
552
|
-
const pristine = state.
|
|
533
|
+
const pristine = state.isPristineAtPathByKey(key, segments);
|
|
553
534
|
const cell = state.errorCells.get(key);
|
|
554
535
|
const schemaForKey = cell !== void 0 && cell.schema.length > 0 ? cell.schema : void 0;
|
|
555
536
|
const blankForKey = state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments) ? [makeBlankRequiredError(segments)] : void 0;
|
|
@@ -561,7 +542,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
561
542
|
const validating = (state.fieldValidationCounts.get(key) ?? 0) > 0;
|
|
562
543
|
const transforming = (state.fieldTransformCounts.get(key) ?? 0) > 0;
|
|
563
544
|
const transformError = state.transformErrors.get(key) ?? null;
|
|
564
|
-
const gated = state.
|
|
545
|
+
const gated = state.pathHasAsyncValidationByKey(key, segments) && !state.firstValidationDone.value;
|
|
565
546
|
const isOrphan = segments.length > 0 && !hasAtPath(state.form.value, segments) && isUnderStubAncestor(state, segments);
|
|
566
547
|
const valid = !gated && errors.length === 0 && !validating && !isOrphan;
|
|
567
548
|
const elementRecord = state.domBinding.value?.elements.get(key);
|
|
@@ -604,7 +585,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
604
585
|
meta: resolved.meta
|
|
605
586
|
};
|
|
606
587
|
}
|
|
607
|
-
function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase
|
|
588
|
+
function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase) {
|
|
608
589
|
const base = buildLeafFieldStateBase(state, segments, key, formInstanceId);
|
|
609
590
|
const validatingSince = state.fieldValidatingSince.get(key) ?? null;
|
|
610
591
|
const transformingSince = state.fieldTransformingSince.get(key) ?? null;
|
|
@@ -617,9 +598,8 @@ function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBa
|
|
|
617
598
|
transformingSince,
|
|
618
599
|
false,
|
|
619
600
|
// revealedDescendantError: leaves have no descendants
|
|
620
|
-
false
|
|
601
|
+
false
|
|
621
602
|
// isRoot: a leaf is never the form root
|
|
622
|
-
getDisplayState
|
|
623
603
|
);
|
|
624
604
|
}
|
|
625
605
|
function visitActiveLeafPaths(value, base, visit) {
|
|
@@ -717,7 +697,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
717
697
|
pristine = false;
|
|
718
698
|
dirty = true;
|
|
719
699
|
}
|
|
720
|
-
const errors = aggregateErrorsAt(state, segments);
|
|
700
|
+
const errors = aggregateErrorsAt(state, segments, key);
|
|
721
701
|
const revealedDescendantError = errors.length > 0 && errors.some((e) => {
|
|
722
702
|
const ePath = e.path;
|
|
723
703
|
if (ePath.length === segments.length && ePath.every((s, i) => s === segments[i])) return false;
|
|
@@ -725,7 +705,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
725
705
|
if (ePath.length === 1 && ePath[0] === "") return blurredAfterInteraction;
|
|
726
706
|
return blurredLeafSegments.some((s) => isPathPrefix(ePath, s));
|
|
727
707
|
});
|
|
728
|
-
if (!asyncPending && state.
|
|
708
|
+
if (!asyncPending && state.pathHasAsyncValidationByKey(key, segments)) asyncPending = true;
|
|
729
709
|
if ((state.fieldValidationCounts.get(key) ?? 0) > 0) {
|
|
730
710
|
validating = true;
|
|
731
711
|
const since = state.fieldValidatingSince.get(key);
|
|
@@ -796,7 +776,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
796
776
|
revealedDescendantError
|
|
797
777
|
};
|
|
798
778
|
}
|
|
799
|
-
function buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase
|
|
779
|
+
function buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase) {
|
|
800
780
|
const { base, validatingSince, transformingSince, revealedDescendantError } = buildContainerFieldStateBase(state, segments, key, formInstanceId);
|
|
801
781
|
return decorateWithDerivedProps(
|
|
802
782
|
base,
|
|
@@ -806,14 +786,12 @@ function buildContainerFieldState(state, segments, key, formInstanceId, getFormM
|
|
|
806
786
|
validatingSince,
|
|
807
787
|
transformingSince,
|
|
808
788
|
revealedDescendantError,
|
|
809
|
-
segments.length === 0
|
|
810
|
-
getDisplayState
|
|
789
|
+
segments.length === 0
|
|
811
790
|
);
|
|
812
791
|
}
|
|
813
|
-
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, transformingSince, revealedDescendantError, isRoot
|
|
792
|
+
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, transformingSince, revealedDescendantError, isRoot) {
|
|
814
793
|
const firstError = base.errors[0];
|
|
815
794
|
const firstOwnError = base.ownErrors[0];
|
|
816
|
-
const predicate = getDisplayState ?? state.getDisplayState;
|
|
817
795
|
const formMeta = getFormMetaBase();
|
|
818
796
|
const ctx = {
|
|
819
797
|
field: base,
|
|
@@ -824,23 +802,9 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
824
802
|
// flight) so the reducer returns the plain verdict and hydration matches.
|
|
825
803
|
now: state.ssr ? 0 : Date.now()
|
|
826
804
|
};
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
machine = state.displayEngine.resolve(key, ctx, predicate);
|
|
831
|
-
} catch (err) {
|
|
832
|
-
if (!warnedDisplayStatePredicates.has(predicate)) {
|
|
833
|
-
warnedDisplayStatePredicates.add(predicate);
|
|
834
|
-
console.warn(
|
|
835
|
-
"[attaform] custom getDisplayState threw \u2014 falling back to defaultDisplayState. Subsequent throws from the same predicate will not warn again.",
|
|
836
|
-
err
|
|
837
|
-
);
|
|
838
|
-
}
|
|
839
|
-
machine = state.displayEngine.resolve(key, ctx, defaultDisplayState);
|
|
840
|
-
rollupApplies = true;
|
|
841
|
-
}
|
|
842
|
-
const submitValidating = rollupApplies && isRoot && state.submitting.value && state.activeValidations.value > 0;
|
|
843
|
-
const resolvedDisplayState = machine.display === "pending" || submitValidating ? "pending" : rollupApplies && revealedDescendantError ? "error" : machine.display;
|
|
805
|
+
const machine = state.displayEngine.resolve(key, ctx, defaultDisplayState);
|
|
806
|
+
const submitValidating = isRoot && state.submitting.value && state.activeValidations.value > 0;
|
|
807
|
+
const resolvedDisplayState = machine.display === "pending" || submitValidating ? "pending" : revealedDescendantError ? "error" : machine.display;
|
|
844
808
|
const displayState = base.disabled === true ? "idle" : resolvedDisplayState;
|
|
845
809
|
return {
|
|
846
810
|
...base,
|
|
@@ -853,26 +817,33 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
853
817
|
firstOwnError
|
|
854
818
|
};
|
|
855
819
|
}
|
|
856
|
-
function aggregateErrorsAt(state, prefix) {
|
|
820
|
+
function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
821
|
+
const candidates = state.errorWindowAt(prefix, prefixKey);
|
|
822
|
+
if (candidates.length === 0) return [];
|
|
857
823
|
const formValue = state.form.value;
|
|
824
|
+
const cells = state.errorCells;
|
|
858
825
|
const buckets = /* @__PURE__ */ new Map();
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
826
|
+
for (const { key, segments } of candidates) {
|
|
827
|
+
if (!isPathPrefix(prefix, segments)) continue;
|
|
828
|
+
if (segments.length > 0 && !hasAtPath(formValue, segments)) continue;
|
|
829
|
+
const cell = cells.get(key);
|
|
830
|
+
const blankList = state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments) ? [makeBlankRequiredError(segments)] : void 0;
|
|
831
|
+
const schemaList = cell?.schema;
|
|
832
|
+
const userList = cell?.user;
|
|
833
|
+
const total = (schemaList?.length ?? 0) + (blankList?.length ?? 0) + (userList?.length ?? 0);
|
|
834
|
+
if (total === 0) continue;
|
|
835
|
+
const ordinal = state.ensurePathOrdinal(key);
|
|
836
|
+
let bucket = buckets.get(ordinal);
|
|
837
|
+
if (bucket === void 0) {
|
|
838
|
+
bucket = [];
|
|
839
|
+
buckets.set(ordinal, bucket);
|
|
840
|
+
}
|
|
841
|
+
if (schemaList !== void 0) bucket.push(...schemaList);
|
|
842
|
+
if (blankList !== void 0) bucket.push(...blankList);
|
|
843
|
+
if (userList !== void 0) bucket.push(...userList);
|
|
844
|
+
}
|
|
875
845
|
if (buckets.size === 0) return [];
|
|
846
|
+
if (buckets.size === 1) return [...buckets.values()][0];
|
|
876
847
|
return [...buckets.entries()].sort(([a], [b]) => a - b).flatMap(([, errs]) => errs);
|
|
877
848
|
}
|
|
878
849
|
const EMPTY_ELEMENTS = Object.freeze([]);
|
|
@@ -967,7 +938,7 @@ function buildTree(spec) {
|
|
|
967
938
|
existsCache.delete(key);
|
|
968
939
|
});
|
|
969
940
|
function schemaHasPath(segs) {
|
|
970
|
-
const cacheKey =
|
|
941
|
+
const cacheKey = keyForSegments(segs).key;
|
|
971
942
|
const cached = existsCache.get(cacheKey);
|
|
972
943
|
if (cached !== void 0) return cached;
|
|
973
944
|
const result = spec.schema.getSlimPrimitiveTypesAtPath(segs).size > 0;
|
|
@@ -982,7 +953,7 @@ function buildTree(spec) {
|
|
|
982
953
|
}
|
|
983
954
|
function containerAt(segments) {
|
|
984
955
|
const isArrayLike = spec.isArrayAt(segments);
|
|
985
|
-
const pathKey =
|
|
956
|
+
const pathKey = keyForSegments(segments).key;
|
|
986
957
|
const cacheKey = `${pathKey}+${isArrayLike ? "A" : "O"}`;
|
|
987
958
|
const existing = containerCache.get(cacheKey);
|
|
988
959
|
if (existing !== void 0) return existing;
|
|
@@ -1082,7 +1053,7 @@ function buildErrorsSurface(state, sweep) {
|
|
|
1082
1053
|
const treeCache = /* @__PURE__ */ new Map();
|
|
1083
1054
|
sweep.onEvict((key) => treeCache.delete(key));
|
|
1084
1055
|
const materialize = (segments) => {
|
|
1085
|
-
const cacheKey =
|
|
1056
|
+
const cacheKey = keyForSegments(segments).key;
|
|
1086
1057
|
let tree = treeCache.get(cacheKey);
|
|
1087
1058
|
if (tree === void 0) {
|
|
1088
1059
|
const frozen = [...segments];
|
|
@@ -1094,28 +1065,21 @@ function buildErrorsSurface(state, sweep) {
|
|
|
1094
1065
|
};
|
|
1095
1066
|
const resolveLeaf = (path) => {
|
|
1096
1067
|
const isContainerSelfAccess = path.length > 1 && path[path.length - 1] === "";
|
|
1097
|
-
const collectAtKey = (key2, active2, into) => {
|
|
1098
|
-
const cell = state.errorCells.get(key2);
|
|
1099
|
-
if (active2) {
|
|
1100
|
-
const b = state.derivedBlankErrors.value.get(key2);
|
|
1101
|
-
if (cell !== void 0) into.push(...cell.schema);
|
|
1102
|
-
if (b !== void 0) into.push(...b);
|
|
1103
|
-
}
|
|
1104
|
-
if (cell !== void 0) into.push(...cell.user);
|
|
1105
|
-
};
|
|
1106
1068
|
const merged = [];
|
|
1107
1069
|
if (isContainerSelfAccess) {
|
|
1108
1070
|
const containerPath = path.slice(0, -1);
|
|
1109
|
-
const
|
|
1110
|
-
const
|
|
1071
|
+
const container = canonicalizePath(containerPath);
|
|
1072
|
+
const literal = canonicalizePath(path);
|
|
1111
1073
|
const active2 = hasAtPath(state.form.value, containerPath);
|
|
1112
|
-
|
|
1113
|
-
if (
|
|
1074
|
+
collectErrorsAt(state, container.key, container.segments, active2, merged);
|
|
1075
|
+
if (literal.key !== container.key) {
|
|
1076
|
+
collectErrorsAt(state, literal.key, literal.segments, active2, merged);
|
|
1077
|
+
}
|
|
1114
1078
|
return merged;
|
|
1115
1079
|
}
|
|
1116
|
-
const { key } = canonicalizePath(path);
|
|
1080
|
+
const { key, segments } = canonicalizePath(path);
|
|
1117
1081
|
const active = hasAtPath(state.form.value, path);
|
|
1118
|
-
|
|
1082
|
+
collectErrorsAt(state, key, segments, active, merged);
|
|
1119
1083
|
return merged;
|
|
1120
1084
|
};
|
|
1121
1085
|
return buildTree({
|
|
@@ -1133,65 +1097,80 @@ function buildErrorsSurface(state, sweep) {
|
|
|
1133
1097
|
// `errors()` / `errors([])` / `errors(path)` are all the subtree
|
|
1134
1098
|
// aggregate — the same helper `meta.errors` reads, so the surfaces
|
|
1135
1099
|
// never drift.
|
|
1136
|
-
call: (path) => aggregateErrorsAt(state, path),
|
|
1100
|
+
call: (path) => aggregateErrorsAt(state, path, keyForSegments(path).key),
|
|
1137
1101
|
surface: "form.errors",
|
|
1138
1102
|
sweep
|
|
1139
1103
|
});
|
|
1140
1104
|
}
|
|
1105
|
+
function collectErrorsAt(state, key, segments, active, into) {
|
|
1106
|
+
const cell = state.errorCells.get(key);
|
|
1107
|
+
if (active) {
|
|
1108
|
+
if (cell !== void 0) into.push(...cell.schema);
|
|
1109
|
+
if (state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments)) {
|
|
1110
|
+
into.push(makeBlankRequiredError(segments));
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
if (cell !== void 0) into.push(...cell.user);
|
|
1114
|
+
}
|
|
1141
1115
|
function errorAwareContainerKeys(state, segments) {
|
|
1142
1116
|
const keys = new Set(liveKeysAtPath(state, segments));
|
|
1143
1117
|
const formValue = state.form.value;
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1118
|
+
const errors = [];
|
|
1119
|
+
const found = [];
|
|
1120
|
+
for (const { key, segments: decoded } of state.errorWindowAt(
|
|
1121
|
+
segments,
|
|
1122
|
+
keyForSegments(segments).key
|
|
1123
|
+
)) {
|
|
1124
|
+
if (decoded.length <= segments.length) continue;
|
|
1125
|
+
if (!isPathPrefix(segments, decoded)) continue;
|
|
1126
|
+
errors.length = 0;
|
|
1127
|
+
collectErrorsAt(state, key, decoded, hasAtPath(formValue, decoded), errors);
|
|
1128
|
+
if (errors.length === 0) continue;
|
|
1129
|
+
const nextSeg = decoded[segments.length];
|
|
1130
|
+
found.push({
|
|
1131
|
+
childKey: typeof nextSeg === "number" ? String(nextSeg) : nextSeg,
|
|
1132
|
+
ordinal: state.ensurePathOrdinal(key)
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
found.sort((a, b) => a.ordinal - b.ordinal);
|
|
1136
|
+
for (const { childKey } of found) keys.add(childKey);
|
|
1159
1137
|
return [...keys];
|
|
1160
1138
|
}
|
|
1161
1139
|
function materializeErrors(state, containerSegments) {
|
|
1162
|
-
const
|
|
1140
|
+
const formValue = state.form.value;
|
|
1141
|
+
const liveContainer = getAtPath(formValue, containerSegments);
|
|
1163
1142
|
const tree = Array.isArray(liveContainer) ? [] : {};
|
|
1164
|
-
const
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
for (let i = 0; i < containerSegments.length; i++) {
|
|
1175
|
-
if (fullPath[i] !== containerSegments[i]) continue entries;
|
|
1176
|
-
}
|
|
1177
|
-
if (applyActivePathFilter && !hasAtPath(state.form.value, fullPath)) continue;
|
|
1178
|
-
const relativePath = fullPath.slice(containerSegments.length);
|
|
1179
|
-
let placePath;
|
|
1180
|
-
if (relativePath.length === 0) {
|
|
1181
|
-
placePath = [""];
|
|
1182
|
-
} else if (state.schema.isLeafAtPath(fullPath)) {
|
|
1183
|
-
placePath = relativePath;
|
|
1184
|
-
} else if (state.schema.getSlimPrimitiveTypesAtPath(fullPath).size > 0) {
|
|
1185
|
-
placePath = [...relativePath, ""];
|
|
1186
|
-
} else {
|
|
1187
|
-
placePath = relativePath;
|
|
1188
|
-
}
|
|
1189
|
-
placeAt(tree, placePath, errors);
|
|
1143
|
+
const placements = [];
|
|
1144
|
+
for (const { key, segments: fullPath } of state.errorWindowAt(
|
|
1145
|
+
containerSegments,
|
|
1146
|
+
keyForSegments(containerSegments).key
|
|
1147
|
+
)) {
|
|
1148
|
+
const isRoot = fullPath.length === 0;
|
|
1149
|
+
if (isRoot) {
|
|
1150
|
+
if (containerSegments.length !== 0) continue;
|
|
1151
|
+
} else if (!isPathPrefix(containerSegments, fullPath)) {
|
|
1152
|
+
continue;
|
|
1190
1153
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1154
|
+
const errors = [];
|
|
1155
|
+
collectErrorsAt(state, key, fullPath, isRoot || hasAtPath(formValue, fullPath), errors);
|
|
1156
|
+
if (errors.length === 0) continue;
|
|
1157
|
+
const relativePath = fullPath.slice(containerSegments.length);
|
|
1158
|
+
let placePath;
|
|
1159
|
+
if (isRoot) {
|
|
1160
|
+
placePath = [ROOT_PATH_KEY];
|
|
1161
|
+
} else if (relativePath.length === 0) {
|
|
1162
|
+
placePath = [""];
|
|
1163
|
+
} else if (state.schema.isLeafAtPath(fullPath)) {
|
|
1164
|
+
placePath = relativePath;
|
|
1165
|
+
} else if (state.schema.getSlimPrimitiveTypesAtPath(fullPath).size > 0) {
|
|
1166
|
+
placePath = [...relativePath, ""];
|
|
1167
|
+
} else {
|
|
1168
|
+
placePath = relativePath;
|
|
1169
|
+
}
|
|
1170
|
+
placements.push({ placePath, errors, ordinal: state.ensurePathOrdinal(key) });
|
|
1171
|
+
}
|
|
1172
|
+
placements.sort((a, b) => a.ordinal - b.ordinal);
|
|
1173
|
+
for (const { placePath, errors } of placements) placeAt(tree, placePath, errors);
|
|
1195
1174
|
return tree;
|
|
1196
1175
|
}
|
|
1197
1176
|
function placeAt(tree, path, errors) {
|
|
@@ -1264,7 +1243,7 @@ function buildFieldsSurface(state, getFieldStateAt, sweep) {
|
|
|
1264
1243
|
const viewCache = /* @__PURE__ */ new Map();
|
|
1265
1244
|
sweep.onEvict((key) => viewCache.delete(key));
|
|
1266
1245
|
function viewAt(segments) {
|
|
1267
|
-
const cacheKey =
|
|
1246
|
+
const cacheKey = keyForSegments(segments).key;
|
|
1268
1247
|
const existing = viewCache.get(cacheKey);
|
|
1269
1248
|
if (existing !== void 0) return existing;
|
|
1270
1249
|
const { toString, valueOf, toJSON, toPrimitive } = makeReadonlyCoercion(
|
|
@@ -1832,45 +1811,6 @@ function buildFieldArrayApi(state) {
|
|
|
1832
1811
|
};
|
|
1833
1812
|
}
|
|
1834
1813
|
|
|
1835
|
-
const SWEEP_SLICE = 8;
|
|
1836
|
-
function createDynamicPathSweep(state) {
|
|
1837
|
-
const dynamicKeys = /* @__PURE__ */ new Set();
|
|
1838
|
-
const evictors = [];
|
|
1839
|
-
const isDynamicPath = (segments) => {
|
|
1840
|
-
for (let i = 0; i < segments.length; i++) {
|
|
1841
|
-
if (typeof segments[i] === "number") return true;
|
|
1842
|
-
if (!state.schema.isFixedObjectAtPath(segments.slice(0, i))) return true;
|
|
1843
|
-
}
|
|
1844
|
-
return false;
|
|
1845
|
-
};
|
|
1846
|
-
let sweepCursor = null;
|
|
1847
|
-
state.onFormChange((next) => {
|
|
1848
|
-
if (dynamicKeys.size === 0) return;
|
|
1849
|
-
const raw = toRaw(next);
|
|
1850
|
-
for (let i = 0; i < SWEEP_SLICE; i++) {
|
|
1851
|
-
sweepCursor ?? (sweepCursor = dynamicKeys.values());
|
|
1852
|
-
const step = sweepCursor.next();
|
|
1853
|
-
if (step.done === true) {
|
|
1854
|
-
sweepCursor = null;
|
|
1855
|
-
break;
|
|
1856
|
-
}
|
|
1857
|
-
const segments = segmentsForPathKey(step.value);
|
|
1858
|
-
if (segments !== null && hasAtPath(raw, segments)) continue;
|
|
1859
|
-
dynamicKeys.delete(step.value);
|
|
1860
|
-
for (const evict of evictors) evict(step.value);
|
|
1861
|
-
}
|
|
1862
|
-
});
|
|
1863
|
-
return {
|
|
1864
|
-
track(segments, key) {
|
|
1865
|
-
if (dynamicKeys.has(key)) return;
|
|
1866
|
-
if (isDynamicPath(segments)) dynamicKeys.add(key);
|
|
1867
|
-
},
|
|
1868
|
-
onEvict(evict) {
|
|
1869
|
-
evictors.push(evict);
|
|
1870
|
-
}
|
|
1871
|
-
};
|
|
1872
|
-
}
|
|
1873
|
-
|
|
1874
1814
|
const warnedNoScopeStores = /* @__PURE__ */ new WeakSet() ;
|
|
1875
1815
|
function isErrorInputLike(value) {
|
|
1876
1816
|
if (value instanceof Error) return true;
|
|
@@ -1898,8 +1838,8 @@ function deriveSubmitErrors(err) {
|
|
|
1898
1838
|
messageless: true
|
|
1899
1839
|
};
|
|
1900
1840
|
}
|
|
1901
|
-
function buildProcessForm(state,
|
|
1902
|
-
const
|
|
1841
|
+
function buildProcessForm(state, options = {}) {
|
|
1842
|
+
const applyInvalidSubmit = options.applyInvalidSubmit;
|
|
1903
1843
|
function validate(pathInput) {
|
|
1904
1844
|
const result = ref({
|
|
1905
1845
|
pending: true,
|
|
@@ -1997,7 +1937,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1997
1937
|
};
|
|
1998
1938
|
}
|
|
1999
1939
|
async function runRefinementValidation(data, path) {
|
|
2000
|
-
return await state.schema.validateAtPath(data, path);
|
|
1940
|
+
return stampFormKey(await state.schema.validateAtPath(data, path), state.formKey);
|
|
2001
1941
|
}
|
|
2002
1942
|
function composeWithDerivedBlank(refinement, scope) {
|
|
2003
1943
|
const blankErrors = collectScopedBlankErrors(state, scope);
|
|
@@ -2048,7 +1988,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
2048
1988
|
}
|
|
2049
1989
|
}
|
|
2050
1990
|
if (generationStillValid) {
|
|
2051
|
-
|
|
1991
|
+
applyInvalidSubmit?.();
|
|
2052
1992
|
}
|
|
2053
1993
|
if (onError !== void 0) {
|
|
2054
1994
|
try {
|
|
@@ -2065,7 +2005,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
2065
2005
|
await onSubmit(merged.data);
|
|
2066
2006
|
if (hasUserErrorEntries(state)) {
|
|
2067
2007
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
2068
|
-
|
|
2008
|
+
applyInvalidSubmit?.();
|
|
2069
2009
|
}
|
|
2070
2010
|
return;
|
|
2071
2011
|
}
|
|
@@ -2083,7 +2023,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
2083
2023
|
if (segments === null) continue;
|
|
2084
2024
|
state.setUserErrorsForPath([...segments], bucket);
|
|
2085
2025
|
}
|
|
2086
|
-
|
|
2026
|
+
applyInvalidSubmit?.();
|
|
2087
2027
|
if (messageless) {
|
|
2088
2028
|
console.warn(
|
|
2089
2029
|
"[attaform] handleSubmit callback threw a non-Error value; throw an Error or a ValidationError ({ message, path? }) so the failure surfaces with a usable message."
|
|
@@ -2103,6 +2043,10 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
2103
2043
|
};
|
|
2104
2044
|
return { validate, parse, handleSubmit };
|
|
2105
2045
|
}
|
|
2046
|
+
function stampFormKey(verdict, formKey) {
|
|
2047
|
+
if (verdict.success) return { ...verdict, formKey };
|
|
2048
|
+
return verdict.data === void 0 ? { data: void 0, errors: verdict.errors, success: false, formKey } : { data: verdict.data, errors: verdict.errors, success: false, formKey };
|
|
2049
|
+
}
|
|
2106
2050
|
function toSegments(pathInput) {
|
|
2107
2051
|
return canonicalizePath(pathInput).segments;
|
|
2108
2052
|
}
|
|
@@ -2136,24 +2080,9 @@ function collectScopedBlankErrors(state, scope) {
|
|
|
2136
2080
|
}
|
|
2137
2081
|
return errors;
|
|
2138
2082
|
}
|
|
2139
|
-
function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
2140
|
-
if (policy === "none") return;
|
|
2141
|
-
const target = state.domBinding.value?.getFirstErrorElement(formInstanceId) ?? null;
|
|
2142
|
-
if (target === null) return;
|
|
2143
|
-
if (policy === "scroll-to-first-error") {
|
|
2144
|
-
target.element.scrollIntoView();
|
|
2145
|
-
return;
|
|
2146
|
-
}
|
|
2147
|
-
if (policy === "focus-first-error") {
|
|
2148
|
-
target.element.focus({ focusVisible: true });
|
|
2149
|
-
return;
|
|
2150
|
-
}
|
|
2151
|
-
target.element.scrollIntoView();
|
|
2152
|
-
target.element.focus({ preventScroll: true, focusVisible: true });
|
|
2153
|
-
}
|
|
2154
2083
|
|
|
2155
2084
|
const warnedRejections = /* @__PURE__ */ new WeakMap() ;
|
|
2156
|
-
function shouldWarnOnce
|
|
2085
|
+
function shouldWarnOnce(store, key) {
|
|
2157
2086
|
if (warnedRejections === null) return false;
|
|
2158
2087
|
let set = warnedRejections.get(store);
|
|
2159
2088
|
if (set === void 0) {
|
|
@@ -2229,7 +2158,7 @@ function walk(schema, store, path, value) {
|
|
|
2229
2158
|
function reportRejection(store, path, kind, accepted) {
|
|
2230
2159
|
const dotted = path.map((s) => String(s)).join(".") || "(root)";
|
|
2231
2160
|
const key = `${dotted}::${kind}`;
|
|
2232
|
-
if (!shouldWarnOnce
|
|
2161
|
+
if (!shouldWarnOnce(store, key)) return;
|
|
2233
2162
|
if (accepted.size === 0) {
|
|
2234
2163
|
console.warn(
|
|
2235
2164
|
`[attaform] Cannot write to '${dotted}' \u2014 this path is not in your schema.
|
|
@@ -2262,56 +2191,9 @@ function formatExpectedKinds(accepted) {
|
|
|
2262
2191
|
return `one of: ${list.join(", ")}`;
|
|
2263
2192
|
}
|
|
2264
2193
|
|
|
2265
|
-
function defineCoercion(entry) {
|
|
2266
|
-
return entry;
|
|
2267
|
-
}
|
|
2268
2194
|
const IDENTITY = (v) => v;
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
defineCoercion({
|
|
2272
|
-
input: "string",
|
|
2273
|
-
output: "number",
|
|
2274
|
-
transform: (s) => {
|
|
2275
|
-
const trimmed = s.trim();
|
|
2276
|
-
if (trimmed === "") return { coerced: false };
|
|
2277
|
-
const n = Number(trimmed);
|
|
2278
|
-
if (!Number.isFinite(n)) return { coerced: false };
|
|
2279
|
-
return { coerced: true, value: n };
|
|
2280
|
-
}
|
|
2281
|
-
}),
|
|
2282
|
-
defineCoercion({
|
|
2283
|
-
input: "string",
|
|
2284
|
-
output: "boolean",
|
|
2285
|
-
transform: (s) => {
|
|
2286
|
-
const normalized = s.trim().toLowerCase();
|
|
2287
|
-
if (normalized === "true") return { coerced: true, value: true };
|
|
2288
|
-
if (normalized === "false") return { coerced: true, value: false };
|
|
2289
|
-
return { coerced: false };
|
|
2290
|
-
}
|
|
2291
|
-
})
|
|
2292
|
-
];
|
|
2293
|
-
function resolveCoercionIndex(config) {
|
|
2294
|
-
if (config === false) return EMPTY_INDEX;
|
|
2295
|
-
const rules = config === void 0 || config === true ? defaultCoercionRules : config;
|
|
2296
|
-
return indexRules(rules);
|
|
2297
|
-
}
|
|
2298
|
-
function indexRules(rules) {
|
|
2299
|
-
const idx = /* @__PURE__ */ new Map();
|
|
2300
|
-
for (const entry of rules) {
|
|
2301
|
-
const candidate = entry;
|
|
2302
|
-
if (candidate === null || typeof candidate !== "object" || typeof candidate.transform !== "function") {
|
|
2303
|
-
{
|
|
2304
|
-
console.warn("[attaform] coercion entry missing or invalid `transform` \u2014 skipped.");
|
|
2305
|
-
}
|
|
2306
|
-
continue;
|
|
2307
|
-
}
|
|
2308
|
-
const key = `${entry.input}->${entry.output}`;
|
|
2309
|
-
if (idx.has(key) && true) {
|
|
2310
|
-
console.warn(`[attaform] duplicate coercion rule for '${key}' \u2014 last entry wins.`);
|
|
2311
|
-
}
|
|
2312
|
-
idx.set(key, entry);
|
|
2313
|
-
}
|
|
2314
|
-
return idx;
|
|
2195
|
+
function resolveCoerceEnabled(config) {
|
|
2196
|
+
return config !== false;
|
|
2315
2197
|
}
|
|
2316
2198
|
function memberSlimTypes(schema, segments, accepted) {
|
|
2317
2199
|
if (accepted.has("array")) return schema.getSlimPrimitiveTypesAtPath([...segments, 0]);
|
|
@@ -2320,119 +2202,84 @@ function memberSlimTypes(schema, segments, accepted) {
|
|
|
2320
2202
|
}
|
|
2321
2203
|
return void 0;
|
|
2322
2204
|
}
|
|
2323
|
-
function buildCoerceFn(schema, segments,
|
|
2324
|
-
if (
|
|
2325
|
-
if (index.size === 0) return IDENTITY;
|
|
2205
|
+
function buildCoerceFn(schema, segments, enabled) {
|
|
2206
|
+
if (!enabled) return IDENTITY;
|
|
2326
2207
|
const accepted = schema.getSlimPrimitiveTypesAtPath(segments);
|
|
2327
2208
|
const elementAccepted = memberSlimTypes(schema, segments, accepted);
|
|
2328
|
-
return (value) => coerceValue(value, accepted, elementAccepted
|
|
2209
|
+
return (value) => coerceValue(value, accepted, elementAccepted);
|
|
2329
2210
|
}
|
|
2330
|
-
function buildElementCoerceFn(schema, segments,
|
|
2331
|
-
if (
|
|
2332
|
-
if (index.size === 0) return void 0;
|
|
2211
|
+
function buildElementCoerceFn(schema, segments, enabled) {
|
|
2212
|
+
if (!enabled) return void 0;
|
|
2333
2213
|
const accepted = schema.getSlimPrimitiveTypesAtPath(segments);
|
|
2334
2214
|
const elementAccepted = memberSlimTypes(schema, segments, accepted);
|
|
2335
2215
|
if (elementAccepted === void 0) return void 0;
|
|
2336
|
-
return (value) => coerceScalar(value, elementAccepted
|
|
2216
|
+
return (value) => coerceScalar(value, elementAccepted);
|
|
2337
2217
|
}
|
|
2338
2218
|
function pickScalarTarget(accepted) {
|
|
2339
2219
|
if (accepted.has("string")) return null;
|
|
2340
2220
|
if (accepted.has("number")) return "number";
|
|
2341
2221
|
if (accepted.has("boolean")) return "boolean";
|
|
2342
|
-
if (accepted.has("bigint")) return "bigint";
|
|
2343
2222
|
return null;
|
|
2344
2223
|
}
|
|
2345
|
-
|
|
2346
|
-
const
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
if (
|
|
2355
|
-
|
|
2356
|
-
return true;
|
|
2224
|
+
function toNumber(source) {
|
|
2225
|
+
const trimmed = source.trim();
|
|
2226
|
+
if (trimmed === "") return source;
|
|
2227
|
+
const n = Number(trimmed);
|
|
2228
|
+
return Number.isFinite(n) ? n : source;
|
|
2229
|
+
}
|
|
2230
|
+
function toBoolean(source) {
|
|
2231
|
+
const normalized = source.trim().toLowerCase();
|
|
2232
|
+
if (normalized === "true") return true;
|
|
2233
|
+
if (normalized === "false") return false;
|
|
2234
|
+
return source;
|
|
2357
2235
|
}
|
|
2358
|
-
function coerceScalar(value, accepted
|
|
2236
|
+
function coerceScalar(value, accepted) {
|
|
2359
2237
|
if (accepted.size === 0) return value;
|
|
2360
2238
|
const sourceKind = slimKindOf(value);
|
|
2361
2239
|
if (accepted.has(sourceKind)) return value;
|
|
2240
|
+
if (sourceKind !== "string") return value;
|
|
2362
2241
|
const target = pickScalarTarget(accepted);
|
|
2363
|
-
if (target ===
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
let result;
|
|
2367
|
-
try {
|
|
2368
|
-
result = entry.transform(value);
|
|
2369
|
-
} catch (err) {
|
|
2370
|
-
if (shouldWarnOnce(`${entry.input}->${entry.output}::throw`)) {
|
|
2371
|
-
console.warn(
|
|
2372
|
-
`[attaform] coercion '${entry.input}->${entry.output}' threw \u2014 write passes through.`,
|
|
2373
|
-
err
|
|
2374
|
-
);
|
|
2375
|
-
}
|
|
2376
|
-
return value;
|
|
2377
|
-
}
|
|
2378
|
-
if (!result.coerced) return value;
|
|
2379
|
-
const returnedKind = slimKindOf(result.value);
|
|
2380
|
-
if (returnedKind !== entry.output) {
|
|
2381
|
-
if (shouldWarnOnce(`${entry.input}->${entry.output}::wrong-kind:${returnedKind}`)) {
|
|
2382
|
-
console.warn(
|
|
2383
|
-
`[attaform] coercion '${entry.input}->${entry.output}' produced a ${returnedKind} \u2014 write passes through.`
|
|
2384
|
-
);
|
|
2385
|
-
}
|
|
2386
|
-
return value;
|
|
2387
|
-
}
|
|
2388
|
-
if (entry.output === "number" && !Number.isFinite(result.value)) {
|
|
2389
|
-
if (shouldWarnOnce(`${entry.input}->${entry.output}::nan`)) {
|
|
2390
|
-
console.warn(
|
|
2391
|
-
`[attaform] coercion '${entry.input}->${entry.output}' produced a non-finite number \u2014 write passes through.`
|
|
2392
|
-
);
|
|
2393
|
-
}
|
|
2394
|
-
return value;
|
|
2395
|
-
}
|
|
2396
|
-
return result.value;
|
|
2242
|
+
if (target === "number") return toNumber(value);
|
|
2243
|
+
if (target === "boolean") return toBoolean(value);
|
|
2244
|
+
return value;
|
|
2397
2245
|
}
|
|
2398
|
-
function coerceArrayMembers(arr, elementAccepted
|
|
2246
|
+
function coerceArrayMembers(arr, elementAccepted) {
|
|
2399
2247
|
let changed = false;
|
|
2400
2248
|
const out = [];
|
|
2401
2249
|
for (const el of arr) {
|
|
2402
|
-
const next = coerceScalar(el, elementAccepted
|
|
2250
|
+
const next = coerceScalar(el, elementAccepted);
|
|
2403
2251
|
if (next !== el) changed = true;
|
|
2404
2252
|
out.push(next);
|
|
2405
2253
|
}
|
|
2406
2254
|
return changed ? out : arr;
|
|
2407
2255
|
}
|
|
2408
|
-
function coerceSetMembers(set, elementAccepted
|
|
2256
|
+
function coerceSetMembers(set, elementAccepted) {
|
|
2409
2257
|
let changed = false;
|
|
2410
2258
|
const out = [];
|
|
2411
2259
|
for (const el of set) {
|
|
2412
|
-
const next = coerceScalar(el, elementAccepted
|
|
2260
|
+
const next = coerceScalar(el, elementAccepted);
|
|
2413
2261
|
if (next !== el) changed = true;
|
|
2414
2262
|
out.push(next);
|
|
2415
2263
|
}
|
|
2416
2264
|
return changed ? new Set(out) : set;
|
|
2417
2265
|
}
|
|
2418
|
-
function coerceValue(value, accepted, elementAccepted
|
|
2266
|
+
function coerceValue(value, accepted, elementAccepted) {
|
|
2419
2267
|
if (Array.isArray(value)) {
|
|
2420
2268
|
if (!accepted.has("array") || elementAccepted === void 0) return value;
|
|
2421
|
-
return coerceArrayMembers(value, elementAccepted
|
|
2269
|
+
return coerceArrayMembers(value, elementAccepted);
|
|
2422
2270
|
}
|
|
2423
2271
|
if (value instanceof Set) {
|
|
2424
2272
|
if (!accepted.has("set") || elementAccepted === void 0) return value;
|
|
2425
|
-
return coerceSetMembers(value, elementAccepted
|
|
2273
|
+
return coerceSetMembers(value, elementAccepted);
|
|
2426
2274
|
}
|
|
2427
|
-
return coerceScalar(value, accepted
|
|
2275
|
+
return coerceScalar(value, accepted);
|
|
2428
2276
|
}
|
|
2429
2277
|
|
|
2430
2278
|
const warnedMultiRootHosts = /* @__PURE__ */ new Set();
|
|
2431
2279
|
const EMPTY_TRANSFORMS = Object.freeze([]);
|
|
2432
2280
|
function buildRegister(state, formInstanceId, instanceConfig) {
|
|
2433
|
-
const
|
|
2281
|
+
const coerceEnabled = instanceConfig?.coerce !== void 0 ? resolveCoerceEnabled(instanceConfig.coerce) : state.coerceEnabled;
|
|
2434
2282
|
const instanceMeta = instanceConfig?.instanceMeta;
|
|
2435
|
-
const formAutoAria = instanceConfig?.autoAria ?? true;
|
|
2436
2283
|
const getDisplayStateAt = instanceConfig?.getDisplayStateAt;
|
|
2437
2284
|
const withInstanceMeta = (meta) => {
|
|
2438
2285
|
if (instanceMeta === void 0) return meta;
|
|
@@ -2472,16 +2319,15 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2472
2319
|
const coerce = buildCoerceFn(
|
|
2473
2320
|
state.schema,
|
|
2474
2321
|
segments,
|
|
2475
|
-
|
|
2322
|
+
coerceEnabled
|
|
2476
2323
|
);
|
|
2477
2324
|
const coerceElement = buildElementCoerceFn(
|
|
2478
2325
|
state.schema,
|
|
2479
2326
|
segments,
|
|
2480
|
-
|
|
2327
|
+
coerceEnabled
|
|
2481
2328
|
);
|
|
2482
2329
|
const { aria } = computeFieldIdentity(formInstanceId, state.formKey, pathKey);
|
|
2483
2330
|
const isRequired = state.schema.isRequiredAtPath(segments);
|
|
2484
|
-
const ariaEnabled = options?.autoAria ?? formAutoAria;
|
|
2485
2331
|
const ariaDisplayState = getDisplayStateAt !== void 0 ? computed(() => getDisplayStateAt(segments)) : void 0;
|
|
2486
2332
|
const markBlank = () => state.setValueAtPath(segments, slimDefault, withInstanceMeta({ blank: true }));
|
|
2487
2333
|
const internalRv = {
|
|
@@ -2601,7 +2447,6 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2601
2447
|
// --- Aria (internal; consumed by the directive) ---
|
|
2602
2448
|
aria,
|
|
2603
2449
|
isRequired,
|
|
2604
|
-
ariaEnabled,
|
|
2605
2450
|
...ariaDisplayState !== void 0 ? { ariaDisplayState } : {}
|
|
2606
2451
|
};
|
|
2607
2452
|
return shallowReadonly(internalRv);
|
|
@@ -2765,11 +2610,50 @@ const DERIVED_DISPLAY_KEYS = /* @__PURE__ */ new Set([
|
|
|
2765
2610
|
"firstError",
|
|
2766
2611
|
"firstOwnError"
|
|
2767
2612
|
]);
|
|
2768
|
-
const
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2613
|
+
const META_KEYS = [
|
|
2614
|
+
...FIELD_STATE_KEYS,
|
|
2615
|
+
"submitting",
|
|
2616
|
+
"submissionAttempts",
|
|
2617
|
+
"departAttempts",
|
|
2618
|
+
"submitError",
|
|
2619
|
+
"submitted",
|
|
2620
|
+
"instanceId",
|
|
2621
|
+
"errorCount"
|
|
2622
|
+
];
|
|
2623
|
+
const BASE_META_KEYS = META_KEYS.filter((k) => !DERIVED_DISPLAY_KEYS.has(k));
|
|
2624
|
+
let INERT_HISTORY;
|
|
2625
|
+
function inertHistory() {
|
|
2626
|
+
INERT_HISTORY ?? (INERT_HISTORY = readonly({
|
|
2627
|
+
undo: () => false,
|
|
2628
|
+
redo: () => false,
|
|
2629
|
+
clear: () => {
|
|
2630
|
+
},
|
|
2631
|
+
canUndo: false,
|
|
2632
|
+
canRedo: false,
|
|
2633
|
+
size: 0
|
|
2634
|
+
}));
|
|
2635
|
+
return INERT_HISTORY;
|
|
2636
|
+
}
|
|
2637
|
+
const denyWrite = () => false;
|
|
2638
|
+
function buildMetaProxy(keys, read) {
|
|
2639
|
+
const target = {};
|
|
2640
|
+
const owns = new Set(keys);
|
|
2641
|
+
return new Proxy(target, {
|
|
2642
|
+
get: (_, key) => owns.has(key) ? read(key) : Reflect.get(target, key),
|
|
2643
|
+
has: (_, key) => owns.has(key) || Reflect.has(target, key),
|
|
2644
|
+
// Safe to hand back the same array every time: the spec copies a
|
|
2645
|
+
// trap's key list before using it.
|
|
2646
|
+
ownKeys: () => keys,
|
|
2647
|
+
getOwnPropertyDescriptor(_, key) {
|
|
2648
|
+
if (!owns.has(key)) return Reflect.getOwnPropertyDescriptor(target, key);
|
|
2649
|
+
return { configurable: true, enumerable: true, value: read(key), writable: false };
|
|
2650
|
+
},
|
|
2651
|
+
// A getter with no setter throws on assignment under strict mode,
|
|
2652
|
+
// which every module here is. `false` keeps that.
|
|
2653
|
+
set: denyWrite,
|
|
2654
|
+
deleteProperty: denyWrite,
|
|
2655
|
+
defineProperty: denyWrite
|
|
2656
|
+
});
|
|
2773
2657
|
}
|
|
2774
2658
|
function buildFormApi(state, formInstanceId, options = {}) {
|
|
2775
2659
|
const instanceBag = pickDefined({
|
|
@@ -2796,32 +2680,26 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2796
2680
|
const rootBaseComputed = computed(
|
|
2797
2681
|
() => buildContainerFieldStateBase(state, ROOT_PATH, ROOT_PATH_KEY, formInstanceId).base
|
|
2798
2682
|
);
|
|
2799
|
-
const metaBase = {
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2683
|
+
const metaBase = buildMetaProxy(BASE_META_KEYS, (key) => {
|
|
2684
|
+
switch (key) {
|
|
2685
|
+
case "instanceId":
|
|
2686
|
+
return formInstanceId;
|
|
2687
|
+
case "errorCount":
|
|
2688
|
+
return rootBaseComputed.value.errors.length;
|
|
2689
|
+
case "submitting":
|
|
2690
|
+
return state.submitting.value;
|
|
2691
|
+
case "submissionAttempts":
|
|
2692
|
+
return state.submissionAttempts.value;
|
|
2693
|
+
case "departAttempts":
|
|
2694
|
+
return state.departAttempts.value;
|
|
2695
|
+
case "submitError":
|
|
2696
|
+
return state.submitError.value;
|
|
2697
|
+
case "submitted":
|
|
2698
|
+
return state.submitted.value;
|
|
2699
|
+
default:
|
|
2700
|
+
return rootBaseComputed.value[key];
|
|
2815
2701
|
}
|
|
2816
|
-
};
|
|
2817
|
-
for (const k of BASE_MIRROR_KEYS) {
|
|
2818
|
-
defineGetter(
|
|
2819
|
-
metaBase,
|
|
2820
|
-
k,
|
|
2821
|
-
() => rootBaseComputed.value[k]
|
|
2822
|
-
);
|
|
2823
|
-
}
|
|
2824
|
-
defineGetter(metaBase, "errorCount", () => rootBaseComputed.value.errors.length);
|
|
2702
|
+
});
|
|
2825
2703
|
const getFormMetaBase = () => {
|
|
2826
2704
|
void state.submitting.value;
|
|
2827
2705
|
void state.submissionAttempts.value;
|
|
@@ -2830,28 +2708,41 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2830
2708
|
void state.submitted.value;
|
|
2831
2709
|
return metaBase;
|
|
2832
2710
|
};
|
|
2833
|
-
const
|
|
2834
|
-
const pathSweep = createDynamicPathSweep(state);
|
|
2711
|
+
const pathSweep = state.pathSweep;
|
|
2835
2712
|
const getRootFieldStateAt = buildFieldStateAccessor(
|
|
2836
2713
|
state,
|
|
2837
2714
|
formInstanceId,
|
|
2838
2715
|
getFormMetaBase,
|
|
2839
|
-
pathSweep
|
|
2840
|
-
fieldStateAccessorOptions
|
|
2716
|
+
pathSweep
|
|
2841
2717
|
);
|
|
2842
2718
|
const getDisplayStateAt = (segments) => getRootFieldStateAt(segments).value.displayState;
|
|
2843
2719
|
const registerConfig = {
|
|
2844
|
-
...pickDefined({ instanceMeta, coerce: options.coerce
|
|
2720
|
+
...pickDefined({ instanceMeta, coerce: options.coerce }),
|
|
2845
2721
|
getDisplayStateAt
|
|
2846
2722
|
};
|
|
2847
2723
|
const register = buildRegister(state, formInstanceId, registerConfig);
|
|
2848
|
-
const
|
|
2849
|
-
|
|
2724
|
+
const focusFirstError = (options2) => {
|
|
2725
|
+
const target = state.domBinding.value?.getFirstErrorElement(formInstanceId) ?? null;
|
|
2726
|
+
if (target === null) return false;
|
|
2727
|
+
target.element.focus({ focusVisible: true, ...options2 });
|
|
2728
|
+
return true;
|
|
2729
|
+
};
|
|
2730
|
+
const scrollToFirstError = (options2) => {
|
|
2731
|
+
const target = state.domBinding.value?.getFirstErrorElement(formInstanceId) ?? null;
|
|
2732
|
+
if (target === null) return false;
|
|
2733
|
+
target.element.scrollIntoView(options2);
|
|
2734
|
+
return true;
|
|
2735
|
+
};
|
|
2736
|
+
const applyInvalidSubmitPolicyPublic = () => {
|
|
2737
|
+
if (options.focusOnInvalidSubmit !== false) focusFirstError();
|
|
2738
|
+
};
|
|
2850
2739
|
const {
|
|
2851
2740
|
validate: validateBuilt,
|
|
2852
2741
|
parse: parseBuilt,
|
|
2853
2742
|
handleSubmit
|
|
2854
|
-
} = buildProcessForm(state,
|
|
2743
|
+
} = buildProcessForm(state, {
|
|
2744
|
+
applyInvalidSubmit: applyInvalidSubmitPolicyPublic
|
|
2745
|
+
});
|
|
2855
2746
|
const validate = (pathInput) => validateBuilt(pathInput);
|
|
2856
2747
|
const parse = (arg1, arg2) => {
|
|
2857
2748
|
const isPathArg = typeof arg1 === "string" || Array.isArray(arg1);
|
|
@@ -2979,22 +2870,21 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2979
2870
|
() => state.firstValidationDone.value && state.errorCells.size === 0 && state.derivedBlankErrors.value.size === 0 && !validating.value
|
|
2980
2871
|
);
|
|
2981
2872
|
const history = options.history;
|
|
2982
|
-
const formHistory = readonly(
|
|
2873
|
+
const formHistory = history === void 0 ? inertHistory() : readonly(
|
|
2983
2874
|
reactive({
|
|
2984
|
-
undo: history
|
|
2985
|
-
redo: history
|
|
2986
|
-
clear: history
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
size: history?.historySize ?? computed(() => 0)
|
|
2875
|
+
undo: history.undo,
|
|
2876
|
+
redo: history.redo,
|
|
2877
|
+
clear: history.clear,
|
|
2878
|
+
canUndo: history.canUndo,
|
|
2879
|
+
canRedo: history.canRedo,
|
|
2880
|
+
size: history.historySize
|
|
2991
2881
|
})
|
|
2992
2882
|
);
|
|
2993
2883
|
const metaErrors = computed(
|
|
2994
|
-
() => aggregateErrorsAt(state, [])
|
|
2884
|
+
() => aggregateErrorsAt(state, [], ROOT_PATH_KEY)
|
|
2995
2885
|
);
|
|
2996
2886
|
const rootFieldState = getRootFieldStateAt([]);
|
|
2997
|
-
const
|
|
2887
|
+
const metaOwn = {
|
|
2998
2888
|
// Whole-form work signals compose the LIFECYCLE counters with the
|
|
2999
2889
|
// per-leaf rollup: a submit-time validate shows up as
|
|
3000
2890
|
// activeValidations, per-field debounced validators as
|
|
@@ -3023,14 +2913,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3023
2913
|
// identifier).
|
|
3024
2914
|
instanceId: formInstanceId
|
|
3025
2915
|
};
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
);
|
|
3032
|
-
}
|
|
3033
|
-
defineGetter(metaTarget, "errorCount", () => metaErrors.value.length);
|
|
2916
|
+
const metaTarget = buildMetaProxy(META_KEYS, (key) => {
|
|
2917
|
+
if (key === "errorCount") return metaErrors.value.length;
|
|
2918
|
+
if (Object.hasOwn(metaOwn, key)) return metaOwn[key];
|
|
2919
|
+
return rootFieldState.value[key];
|
|
2920
|
+
});
|
|
3034
2921
|
const formMeta = readonly(reactive(metaTarget));
|
|
3035
2922
|
const reset = (nextDefaultValues) => {
|
|
3036
2923
|
if (nextDefaultValues === void 0) {
|
|
@@ -3070,21 +2957,6 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3070
2957
|
} catch {
|
|
3071
2958
|
}
|
|
3072
2959
|
}
|
|
3073
|
-
const focusFirstError = (options2) => {
|
|
3074
|
-
const target = state.domBinding.value?.getFirstErrorElement(formInstanceId) ?? null;
|
|
3075
|
-
if (target === null) return false;
|
|
3076
|
-
target.element.focus({ focusVisible: true, ...options2 });
|
|
3077
|
-
return true;
|
|
3078
|
-
};
|
|
3079
|
-
const scrollToFirstError = (options2) => {
|
|
3080
|
-
const target = state.domBinding.value?.getFirstErrorElement(formInstanceId) ?? null;
|
|
3081
|
-
if (target === null) return false;
|
|
3082
|
-
target.element.scrollIntoView(options2);
|
|
3083
|
-
return true;
|
|
3084
|
-
};
|
|
3085
|
-
const applyInvalidSubmitPolicyPublic = (policy) => {
|
|
3086
|
-
applyInvalidSubmitPolicy(state, formInstanceId, policy ?? defaultInvalidSubmitPolicy);
|
|
3087
|
-
};
|
|
3088
2960
|
const fieldArrays = buildFieldArrayApi(state);
|
|
3089
2961
|
const blankPathsView = computed(() => {
|
|
3090
2962
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -3259,6 +3131,45 @@ function shortenSourceFrame(frame) {
|
|
|
3259
3131
|
return `(${path}:${line})`;
|
|
3260
3132
|
}
|
|
3261
3133
|
|
|
3134
|
+
const SWEEP_SLICE = 8;
|
|
3135
|
+
function createDynamicPathSweep(deps) {
|
|
3136
|
+
const dynamicKeys = /* @__PURE__ */ new Set();
|
|
3137
|
+
const evictors = [];
|
|
3138
|
+
const isDynamicPath = (segments) => {
|
|
3139
|
+
for (let i = 0; i < segments.length; i++) {
|
|
3140
|
+
if (typeof segments[i] === "number") return true;
|
|
3141
|
+
if (!deps.isFixedObjectAtPath(segments.slice(0, i))) return true;
|
|
3142
|
+
}
|
|
3143
|
+
return false;
|
|
3144
|
+
};
|
|
3145
|
+
let sweepCursor = null;
|
|
3146
|
+
deps.onFormChange((next) => {
|
|
3147
|
+
if (dynamicKeys.size === 0) return;
|
|
3148
|
+
const raw = toRaw(next);
|
|
3149
|
+
for (let i = 0; i < SWEEP_SLICE; i++) {
|
|
3150
|
+
sweepCursor ?? (sweepCursor = dynamicKeys.values());
|
|
3151
|
+
const step = sweepCursor.next();
|
|
3152
|
+
if (step.done === true) {
|
|
3153
|
+
sweepCursor = null;
|
|
3154
|
+
break;
|
|
3155
|
+
}
|
|
3156
|
+
const segments = segmentsForPathKey(step.value);
|
|
3157
|
+
if (segments !== null && hasAtPath(raw, segments)) continue;
|
|
3158
|
+
dynamicKeys.delete(step.value);
|
|
3159
|
+
for (const evict of evictors) evict(step.value);
|
|
3160
|
+
}
|
|
3161
|
+
});
|
|
3162
|
+
return {
|
|
3163
|
+
track(segments, key) {
|
|
3164
|
+
if (dynamicKeys.has(key)) return;
|
|
3165
|
+
if (isDynamicPath(segments)) dynamicKeys.add(key);
|
|
3166
|
+
},
|
|
3167
|
+
onEvict(evict) {
|
|
3168
|
+
evictors.push(evict);
|
|
3169
|
+
}
|
|
3170
|
+
};
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3262
3173
|
const IDLE = Object.freeze({ display: "idle" });
|
|
3263
3174
|
const MAX_DELAY = 2147483647;
|
|
3264
3175
|
const PENDING_LIVENESS_MS = 250;
|
|
@@ -3352,6 +3263,58 @@ function createDisplayEngine(ssr) {
|
|
|
3352
3263
|
return engine;
|
|
3353
3264
|
}
|
|
3354
3265
|
|
|
3266
|
+
function buildErrorPathIndex(cells, blank) {
|
|
3267
|
+
const keys = /* @__PURE__ */ new Set();
|
|
3268
|
+
for (const [key, cell] of cells) {
|
|
3269
|
+
if (cell.schema.length > 0 || cell.user.length > 0) keys.add(key);
|
|
3270
|
+
}
|
|
3271
|
+
for (const [key, list] of blank) {
|
|
3272
|
+
if (list.length > 0) keys.add(key);
|
|
3273
|
+
}
|
|
3274
|
+
if (keys.size === 0) return EMPTY_INDEX;
|
|
3275
|
+
const entries = [];
|
|
3276
|
+
for (const key of keys) {
|
|
3277
|
+
const segments = segmentsForPathKey(key);
|
|
3278
|
+
if (segments !== null) entries.push({ key, segments });
|
|
3279
|
+
}
|
|
3280
|
+
entries.sort(compareByKey);
|
|
3281
|
+
return entries;
|
|
3282
|
+
}
|
|
3283
|
+
const EMPTY_INDEX = Object.freeze([]);
|
|
3284
|
+
function compareByKey(a, b) {
|
|
3285
|
+
return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
|
|
3286
|
+
}
|
|
3287
|
+
function windowUnder(index, prefix) {
|
|
3288
|
+
if (prefix.length === 0 || index.length === 0) return index;
|
|
3289
|
+
const prefixKey = keyForSegments(prefix).key;
|
|
3290
|
+
const marker = `${prefixKey.slice(0, -1)},`;
|
|
3291
|
+
const start = lowerBound(index, marker);
|
|
3292
|
+
if (start >= index.length) return EMPTY_INDEX;
|
|
3293
|
+
let end = start;
|
|
3294
|
+
for (; end < index.length; end += 1) {
|
|
3295
|
+
const entry = index[end];
|
|
3296
|
+
if (entry === void 0 || entry.key > prefixKey) break;
|
|
3297
|
+
}
|
|
3298
|
+
return start === 0 && end === index.length ? index : index.slice(start, end);
|
|
3299
|
+
}
|
|
3300
|
+
function isSameWindow(a, b) {
|
|
3301
|
+
if (a.length !== b.length) return false;
|
|
3302
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
3303
|
+
if (a[i]?.key !== b[i]?.key) return false;
|
|
3304
|
+
}
|
|
3305
|
+
return true;
|
|
3306
|
+
}
|
|
3307
|
+
function lowerBound(index, target) {
|
|
3308
|
+
let lo = 0;
|
|
3309
|
+
let hi = index.length;
|
|
3310
|
+
while (lo < hi) {
|
|
3311
|
+
const mid = lo + hi >>> 1;
|
|
3312
|
+
if ((index[mid]?.key ?? target) < target) lo = mid + 1;
|
|
3313
|
+
else hi = mid;
|
|
3314
|
+
}
|
|
3315
|
+
return lo;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3355
3318
|
function mergeSparseHydration(schemaDefaults, sparse, schema) {
|
|
3356
3319
|
return mergeDeep(schemaDefaults, sparse, [], schema);
|
|
3357
3320
|
}
|
|
@@ -3578,16 +3541,15 @@ function walkAuthoredFromSchemaDiff(withDefaults, withoutDefaults, prefix, out)
|
|
|
3578
3541
|
out.add(canonicalizePath(prefix).key);
|
|
3579
3542
|
}
|
|
3580
3543
|
}
|
|
3581
|
-
function computeBaselineResponse(schema,
|
|
3544
|
+
function computeBaselineResponse(schema, source) {
|
|
3582
3545
|
const completed = source === void 0 ? void 0 : mergeStructural(schema, [], source);
|
|
3583
3546
|
return schema.getDefaultValues({
|
|
3584
3547
|
useDefaultSchemaValues: true,
|
|
3585
|
-
constraints: completed
|
|
3586
|
-
strict
|
|
3548
|
+
constraints: completed
|
|
3587
3549
|
});
|
|
3588
3550
|
}
|
|
3589
|
-
function initialFirstValidationGate(schema
|
|
3590
|
-
return
|
|
3551
|
+
function initialFirstValidationGate(schema) {
|
|
3552
|
+
return schema.needsAsyncValidation?.() !== true;
|
|
3591
3553
|
}
|
|
3592
3554
|
function seedOriginalsFromBaseline(st, baseline, ensureOrdinals) {
|
|
3593
3555
|
st.originals.clear();
|
|
@@ -3599,7 +3561,7 @@ function seedOriginalsFromBaseline(st, baseline, ensureOrdinals) {
|
|
|
3599
3561
|
});
|
|
3600
3562
|
}
|
|
3601
3563
|
function queueInitialAsyncValidation(st) {
|
|
3602
|
-
if (!st.ssr && st.
|
|
3564
|
+
if (!st.ssr && st.schema.needsAsyncValidation?.() === true) {
|
|
3603
3565
|
queueMicrotask(() => scheduleFieldValidation(
|
|
3604
3566
|
st,
|
|
3605
3567
|
[],
|
|
@@ -3641,10 +3603,6 @@ function ensurePathOrdinal(st, key) {
|
|
|
3641
3603
|
}
|
|
3642
3604
|
return ordinal;
|
|
3643
3605
|
}
|
|
3644
|
-
function pathHasAsyncValidation(st, path) {
|
|
3645
|
-
const { key } = canonicalizePath(path);
|
|
3646
|
-
return pathHasAsyncValidationByKey(st, key, path);
|
|
3647
|
-
}
|
|
3648
3606
|
function pathHasAsyncValidationByKey(st, key, segments) {
|
|
3649
3607
|
const cached = st.pathAsyncCache.get(key);
|
|
3650
3608
|
if (cached !== void 0) return cached;
|
|
@@ -3787,10 +3745,15 @@ function commitWritePatches(st, patches, meta) {
|
|
|
3787
3745
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3788
3746
|
for (const patch of patches) {
|
|
3789
3747
|
const { key } = canonicalizePath(patch.path);
|
|
3790
|
-
if (
|
|
3748
|
+
if (!st.originals.has(key)) {
|
|
3791
3749
|
st.originals.set(key, { segments: patch.path, value: void 0 });
|
|
3792
3750
|
}
|
|
3793
3751
|
touchFieldRecord(st, key, patch.path, { updatedAt: now });
|
|
3752
|
+
st.pathSweep.track(patch.path, key);
|
|
3753
|
+
for (let i = 1; i < patch.path.length; i++) {
|
|
3754
|
+
const ancestor = patch.path.slice(0, i);
|
|
3755
|
+
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
3756
|
+
}
|
|
3794
3757
|
}
|
|
3795
3758
|
for (const listener of st.formChangeListeners) {
|
|
3796
3759
|
try {
|
|
@@ -4001,10 +3964,7 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
4001
3964
|
if (newlyAuthored && st.schema.isPreprocessOrCoerceLeaf(path)) {
|
|
4002
3965
|
const modeForAuthoringTransition = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
4003
3966
|
if (modeForAuthoringTransition === "change") {
|
|
4004
|
-
scheduleFieldValidation(st, path, false,
|
|
4005
|
-
...meta?.instance?.validateOn !== void 0 ? { mode: meta.instance.validateOn } : {},
|
|
4006
|
-
...meta?.instance?.debounceMs !== void 0 ? { debounceMs: meta.instance.debounceMs } : {}
|
|
4007
|
-
});
|
|
3967
|
+
scheduleFieldValidation(st, path, false, meta?.instance);
|
|
4008
3968
|
}
|
|
4009
3969
|
}
|
|
4010
3970
|
return true;
|
|
@@ -4020,15 +3980,12 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
4020
3980
|
st.arrayIdentity.realign(path);
|
|
4021
3981
|
} else if (isContainer(currentValue) && !isContainer(value)) {
|
|
4022
3982
|
if (subtreeHadRealBaseline(st, path, currentValue)) {
|
|
4023
|
-
st.removedSubtrees.add(
|
|
3983
|
+
st.removedSubtrees.add(pathKey);
|
|
4024
3984
|
}
|
|
4025
3985
|
}
|
|
4026
3986
|
const effectiveModeAfterWrite = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
4027
3987
|
if (effectiveModeAfterWrite === "change") {
|
|
4028
|
-
scheduleFieldValidation(st, path, false,
|
|
4029
|
-
...meta?.instance?.validateOn !== void 0 ? { mode: meta.instance.validateOn } : {},
|
|
4030
|
-
...meta?.instance?.debounceMs !== void 0 ? { debounceMs: meta.instance.debounceMs } : {}
|
|
4031
|
-
});
|
|
3988
|
+
scheduleFieldValidation(st, path, false, meta?.instance);
|
|
4032
3989
|
}
|
|
4033
3990
|
return true;
|
|
4034
3991
|
}
|
|
@@ -4089,12 +4046,11 @@ function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variant
|
|
|
4089
4046
|
path: [...parentPath, ...err.path]
|
|
4090
4047
|
}));
|
|
4091
4048
|
applySchemaErrorsForSubtree(st, parentPath, reStamped);
|
|
4092
|
-
const
|
|
4093
|
-
const prevValidation = st.fieldValidationState.get(parentKey2);
|
|
4049
|
+
const prevValidation = st.fieldValidationState.get(parentKey);
|
|
4094
4050
|
if (prevValidation !== void 0) {
|
|
4095
4051
|
if (prevValidation.timer !== null) clearTimeout(prevValidation.timer);
|
|
4096
4052
|
prevValidation.aborted = true;
|
|
4097
|
-
st.fieldValidationState.delete(
|
|
4053
|
+
st.fieldValidationState.delete(parentKey);
|
|
4098
4054
|
}
|
|
4099
4055
|
appliedSync = true;
|
|
4100
4056
|
}
|
|
@@ -4102,17 +4058,14 @@ function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variant
|
|
|
4102
4058
|
applyFormReplacement(st, nextForm, meta);
|
|
4103
4059
|
for (const k of newBlankPaths) st.blankPaths.add(k);
|
|
4104
4060
|
if (reshapeMode === "change" && !appliedSync) {
|
|
4105
|
-
scheduleFieldValidation(st, parentPath, false,
|
|
4106
|
-
...meta?.instance?.validateOn !== void 0 ? { mode: meta.instance.validateOn } : {},
|
|
4107
|
-
...meta?.instance?.debounceMs !== void 0 ? { debounceMs: meta.instance.debounceMs } : {}
|
|
4108
|
-
});
|
|
4061
|
+
scheduleFieldValidation(st, parentPath, false, meta?.instance);
|
|
4109
4062
|
}
|
|
4110
4063
|
return true;
|
|
4111
4064
|
}
|
|
4112
|
-
function scheduleFieldValidation(st, path, immediate,
|
|
4113
|
-
const effectiveMode =
|
|
4065
|
+
function scheduleFieldValidation(st, path, immediate, instance) {
|
|
4066
|
+
const effectiveMode = instance?.validateOn ?? st.fieldValidationMode;
|
|
4114
4067
|
if (effectiveMode === "submit") return;
|
|
4115
|
-
const effectiveDebounce =
|
|
4068
|
+
const effectiveDebounce = instance?.debounceMs ?? st.fieldValidationDebounceMs;
|
|
4116
4069
|
const { key } = canonicalizePath(path);
|
|
4117
4070
|
const prev = st.fieldValidationState.get(key);
|
|
4118
4071
|
if (prev !== void 0) {
|
|
@@ -4386,10 +4339,7 @@ function markFocused(st, path, focused, meta) {
|
|
|
4386
4339
|
});
|
|
4387
4340
|
}
|
|
4388
4341
|
if (changed) {
|
|
4389
|
-
scheduleFieldValidation(st, path, true,
|
|
4390
|
-
...meta?.instance?.validateOn !== void 0 ? { mode: meta.instance.validateOn } : {},
|
|
4391
|
-
...meta?.instance?.debounceMs !== void 0 ? { debounceMs: meta.instance.debounceMs } : {}
|
|
4392
|
-
});
|
|
4342
|
+
scheduleFieldValidation(st, path, true, meta?.instance);
|
|
4393
4343
|
}
|
|
4394
4344
|
}
|
|
4395
4345
|
}
|
|
@@ -4402,11 +4352,10 @@ function markInteracted(st, path) {
|
|
|
4402
4352
|
function touchAtPath(st, segments) {
|
|
4403
4353
|
const formValue = st.form.value;
|
|
4404
4354
|
let touchedAny = false;
|
|
4405
|
-
for (const [, entry] of st.originals) {
|
|
4355
|
+
for (const [leafKey, entry] of st.originals) {
|
|
4406
4356
|
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
4407
4357
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4408
4358
|
touchedAny = true;
|
|
4409
|
-
const leafKey = canonicalizePath(entry.segments).key;
|
|
4410
4359
|
const current = st.fields.get(leafKey);
|
|
4411
4360
|
if (current?.touched === true) continue;
|
|
4412
4361
|
touchFieldRecord(st, leafKey, entry.segments, { touched: true });
|
|
@@ -4421,11 +4370,10 @@ function interactAtPath(st, segments) {
|
|
|
4421
4370
|
if (st.effectiveDisabled.value) return false;
|
|
4422
4371
|
const formValue = st.form.value;
|
|
4423
4372
|
let interactedAny = false;
|
|
4424
|
-
for (const [, entry] of st.originals) {
|
|
4373
|
+
for (const [leafKey, entry] of st.originals) {
|
|
4425
4374
|
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
4426
4375
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4427
4376
|
interactedAny = true;
|
|
4428
|
-
const leafKey = canonicalizePath(entry.segments).key;
|
|
4429
4377
|
const current = st.fields.get(leafKey);
|
|
4430
4378
|
if (current?.touched === true && current.interacted === true && current.blurredAfterInteraction === true) {
|
|
4431
4379
|
continue;
|
|
@@ -4482,11 +4430,7 @@ function adoptResolvedDefaults(st, value) {
|
|
|
4482
4430
|
st.schema
|
|
4483
4431
|
)
|
|
4484
4432
|
);
|
|
4485
|
-
seedOriginalsFromBaseline(
|
|
4486
|
-
st,
|
|
4487
|
-
computeBaselineResponse(st.schema, st.strict, st.defaultValues).data,
|
|
4488
|
-
false
|
|
4489
|
-
);
|
|
4433
|
+
seedOriginalsFromBaseline(st, computeBaselineResponse(st.schema, st.defaultValues).data, false);
|
|
4490
4434
|
}
|
|
4491
4435
|
function reset(st, nextDefaultValues) {
|
|
4492
4436
|
const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
|
|
@@ -4495,7 +4439,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4495
4439
|
st.schema
|
|
4496
4440
|
);
|
|
4497
4441
|
st.defaultValues = structuralSnapshot(resetSource);
|
|
4498
|
-
const resetResponse = computeBaselineResponse(st.schema,
|
|
4442
|
+
const resetResponse = computeBaselineResponse(st.schema, resetSource);
|
|
4499
4443
|
const next = resetResponse.data;
|
|
4500
4444
|
rebuildAuthoredPaths(st, resetSource, next);
|
|
4501
4445
|
applyFormReplacement(st, next);
|
|
@@ -4512,16 +4456,14 @@ function reset(st, nextDefaultValues) {
|
|
|
4512
4456
|
st.blankPaths.add(key);
|
|
4513
4457
|
}
|
|
4514
4458
|
st.errorCells.clear();
|
|
4515
|
-
if (
|
|
4459
|
+
if (!resetResponse.success) {
|
|
4516
4460
|
replaceErrorChannel(st, "schema", resetResponse.errors);
|
|
4517
4461
|
}
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
applySchemaErrorsForSubtree(st, [], syncResult.errors);
|
|
4522
|
-
}
|
|
4462
|
+
const syncResult = st.schema.validateAtPath(st.form.value, void 0, { sync: true });
|
|
4463
|
+
if (!(syncResult instanceof Promise) && !syncResult.success) {
|
|
4464
|
+
applySchemaErrorsForSubtree(st, [], syncResult.errors);
|
|
4523
4465
|
}
|
|
4524
|
-
st.firstValidationDone.value = initialFirstValidationGate(st.schema
|
|
4466
|
+
st.firstValidationDone.value = initialFirstValidationGate(st.schema);
|
|
4525
4467
|
queueInitialAsyncValidation(st);
|
|
4526
4468
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4527
4469
|
for (const [pathKey, record] of st.fields) {
|
|
@@ -4611,10 +4553,6 @@ function clearFieldRecordFlags(st, pathKey) {
|
|
|
4611
4553
|
if (record === void 0) return;
|
|
4612
4554
|
st.fields.set(pathKey, withClearedHistoryFlags(record, (/* @__PURE__ */ new Date()).toISOString()));
|
|
4613
4555
|
}
|
|
4614
|
-
function isPristineAtPath(st, path) {
|
|
4615
|
-
const { key, segments } = canonicalizePath(path);
|
|
4616
|
-
return isPristineAtPathByKey(st, key, segments);
|
|
4617
|
-
}
|
|
4618
4556
|
function isPristineAtPathByKey(st, key, segments) {
|
|
4619
4557
|
if (st.blankPaths.has(key) !== st.originalBlankPaths.has(key)) return false;
|
|
4620
4558
|
const entry = st.originals.get(key);
|
|
@@ -4648,12 +4586,8 @@ function getFieldRecord(st, path) {
|
|
|
4648
4586
|
const { key } = canonicalizePath(path);
|
|
4649
4587
|
return st.fields.get(key);
|
|
4650
4588
|
}
|
|
4651
|
-
function getOriginalAtPath(st, path) {
|
|
4652
|
-
const { key } = canonicalizePath(path);
|
|
4653
|
-
return st.originals.get(key)?.value;
|
|
4654
|
-
}
|
|
4655
4589
|
function createFormStore(options) {
|
|
4656
|
-
const { formKey, schema, defaultValues,
|
|
4590
|
+
const { formKey, schema, defaultValues, hydration } = options;
|
|
4657
4591
|
const ssr = options.ssr === true;
|
|
4658
4592
|
const ssrPrefetch = options.ssrPrefetch;
|
|
4659
4593
|
const rememberVariants = options.rememberVariants !== false;
|
|
@@ -4661,22 +4595,16 @@ function createFormStore(options) {
|
|
|
4661
4595
|
const fieldValidationDebounceMs = normalizeNumericOption({
|
|
4662
4596
|
value: options.debounceMs ?? DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS,
|
|
4663
4597
|
source: "useForm.debounceMs",
|
|
4664
|
-
allowInfinity: false,
|
|
4665
4598
|
min: 0,
|
|
4666
4599
|
defaultValue: DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS
|
|
4667
4600
|
});
|
|
4668
|
-
const
|
|
4669
|
-
const resolvedGetDisplayState = resolveGetDisplayState(options.getDisplayState);
|
|
4601
|
+
const coerceEnabled = resolveCoerceEnabled(options.coerce);
|
|
4670
4602
|
const cleanupHooks = [];
|
|
4671
4603
|
const modules = /* @__PURE__ */ new Map();
|
|
4672
4604
|
const fieldValidatingSince = reactive(/* @__PURE__ */ new Map());
|
|
4673
4605
|
const displayEngine = createDisplayEngine(ssr);
|
|
4674
4606
|
cleanupHooks.push(() => displayEngine.dispose());
|
|
4675
|
-
const schemaResponse = computeBaselineResponse(
|
|
4676
|
-
schema,
|
|
4677
|
-
strict,
|
|
4678
|
-
defaultValues
|
|
4679
|
-
);
|
|
4607
|
+
const schemaResponse = computeBaselineResponse(schema, defaultValues);
|
|
4680
4608
|
const schemaInitialData = schemaResponse.data;
|
|
4681
4609
|
const authoredPaths = /* @__PURE__ */ new Set();
|
|
4682
4610
|
const initialData = hydration !== void 0 ? hydration.form : structuralSnapshot(schemaInitialData);
|
|
@@ -4689,16 +4617,15 @@ function createFormStore(options) {
|
|
|
4689
4617
|
const v = getAtPath(toRaw(form.value), arraySegs);
|
|
4690
4618
|
return Array.isArray(v) ? v.length : 0;
|
|
4691
4619
|
});
|
|
4692
|
-
const fields =
|
|
4620
|
+
const fields = shallowReactive(/* @__PURE__ */ new Map());
|
|
4693
4621
|
const domBinding = shallowRef(null);
|
|
4694
|
-
const errorCells =
|
|
4695
|
-
const originals =
|
|
4622
|
+
const errorCells = shallowReactive(/* @__PURE__ */ new Map());
|
|
4623
|
+
const originals = shallowReactive(/* @__PURE__ */ new Map());
|
|
4696
4624
|
const removedSubtrees = /* @__PURE__ */ new Set();
|
|
4697
|
-
const initialTransientList = hydration?.blankPaths ?? options.initialBlankPaths ?? [];
|
|
4698
4625
|
const blankPaths = reactive(/* @__PURE__ */ new Set());
|
|
4699
4626
|
const originalBlankPaths = /* @__PURE__ */ new Set();
|
|
4700
|
-
|
|
4701
|
-
|
|
4627
|
+
const seededBlankPaths = hydration !== void 0 ? (hydration.blankPaths ?? []).map((dotted) => canonicalizePath(dotted).key) : options.initialBlankPaths ?? [];
|
|
4628
|
+
for (const key of seededBlankPaths) {
|
|
4702
4629
|
blankPaths.add(key);
|
|
4703
4630
|
originalBlankPaths.add(key);
|
|
4704
4631
|
}
|
|
@@ -4715,6 +4642,9 @@ function createFormStore(options) {
|
|
|
4715
4642
|
}
|
|
4716
4643
|
return result;
|
|
4717
4644
|
});
|
|
4645
|
+
const errorPathIndex = computed(
|
|
4646
|
+
() => buildErrorPathIndex(errorCells, derivedBlankErrors.value)
|
|
4647
|
+
);
|
|
4718
4648
|
const submitting = ref(false);
|
|
4719
4649
|
const activeSubmissions = ref(0);
|
|
4720
4650
|
const submissionAttempts = ref(0);
|
|
@@ -4747,7 +4677,7 @@ function createFormStore(options) {
|
|
|
4747
4677
|
const defaultsResolved = ref(false);
|
|
4748
4678
|
const activated = ref(false);
|
|
4749
4679
|
const activationPromise = ref(void 0);
|
|
4750
|
-
const firstValidationDone = ref(initialFirstValidationGate(schema
|
|
4680
|
+
const firstValidationDone = ref(initialFirstValidationGate(schema));
|
|
4751
4681
|
watch(activeValidations, (now, prev) => {
|
|
4752
4682
|
if (prev > 0 && now === 0) {
|
|
4753
4683
|
firstValidationDone.value = true;
|
|
@@ -4765,6 +4695,33 @@ function createFormStore(options) {
|
|
|
4765
4695
|
const activeTransforms = ref(0);
|
|
4766
4696
|
const transformRuns = /* @__PURE__ */ new Map();
|
|
4767
4697
|
const transformWaiters = [];
|
|
4698
|
+
const errorWindows = /* @__PURE__ */ new Map();
|
|
4699
|
+
const pathSweep = createDynamicPathSweep({
|
|
4700
|
+
onFormChange: (listener) => {
|
|
4701
|
+
formChangeListeners.add(listener);
|
|
4702
|
+
},
|
|
4703
|
+
isFixedObjectAtPath: (path) => schema.isFixedObjectAtPath(path)
|
|
4704
|
+
});
|
|
4705
|
+
pathSweep.onEvict((key) => {
|
|
4706
|
+
fields.delete(key);
|
|
4707
|
+
fieldValidationState.delete(key);
|
|
4708
|
+
authoredPaths.delete(key);
|
|
4709
|
+
if (originals.get(key)?.value === void 0) originals.delete(key);
|
|
4710
|
+
errorWindows.delete(key);
|
|
4711
|
+
});
|
|
4712
|
+
const errorWindowAt = (prefix, prefixKey) => {
|
|
4713
|
+
let cached = errorWindows.get(prefixKey);
|
|
4714
|
+
if (cached === void 0) {
|
|
4715
|
+
const frozen = [...prefix];
|
|
4716
|
+
cached = computed((prev) => {
|
|
4717
|
+
const next = windowUnder(errorPathIndex.value, frozen);
|
|
4718
|
+
return prev !== void 0 && isSameWindow(prev, next) ? prev : next;
|
|
4719
|
+
});
|
|
4720
|
+
errorWindows.set(prefixKey, cached);
|
|
4721
|
+
pathSweep.track(frozen, prefixKey);
|
|
4722
|
+
}
|
|
4723
|
+
return cached.value;
|
|
4724
|
+
};
|
|
4768
4725
|
const arrayBookkeeping = createArrayBookkeeping({
|
|
4769
4726
|
form,
|
|
4770
4727
|
fields,
|
|
@@ -4782,6 +4739,7 @@ function createFormStore(options) {
|
|
|
4782
4739
|
touchFieldRecord: (pathKey, path, patch) => touchFieldRecord(st, pathKey, path, patch),
|
|
4783
4740
|
decFieldValidation: (key) => decFieldValidation(st, key)
|
|
4784
4741
|
});
|
|
4742
|
+
const bind = (fn) => (...args) => fn(st, ...args);
|
|
4785
4743
|
const st = {
|
|
4786
4744
|
// --- public data (the FormStore contract's state members) ---
|
|
4787
4745
|
formKey,
|
|
@@ -4789,10 +4747,11 @@ function createFormStore(options) {
|
|
|
4789
4747
|
fields,
|
|
4790
4748
|
errorCells,
|
|
4791
4749
|
derivedBlankErrors,
|
|
4750
|
+
errorWindowAt,
|
|
4792
4751
|
originals,
|
|
4752
|
+
pathSweep,
|
|
4793
4753
|
schema,
|
|
4794
4754
|
ssr,
|
|
4795
|
-
getDisplayState: resolvedGetDisplayState,
|
|
4796
4755
|
submitting,
|
|
4797
4756
|
activeSubmissions,
|
|
4798
4757
|
submissionAttempts,
|
|
@@ -4820,11 +4779,10 @@ function createFormStore(options) {
|
|
|
4820
4779
|
displayEngine,
|
|
4821
4780
|
domBinding,
|
|
4822
4781
|
modules,
|
|
4823
|
-
|
|
4782
|
+
coerceEnabled,
|
|
4824
4783
|
blankPaths,
|
|
4825
4784
|
originalBlankPaths,
|
|
4826
4785
|
// --- kernel-internal state ---
|
|
4827
|
-
strict,
|
|
4828
4786
|
// Defensive copy, not a fix for an observed alias: today
|
|
4829
4787
|
// `getDefaultValues` happens to build a fresh tree, so form storage
|
|
4830
4788
|
// does not currently share structure with the consumer's object.
|
|
@@ -4861,17 +4819,20 @@ function createFormStore(options) {
|
|
|
4861
4819
|
transformTokenSeq: 0,
|
|
4862
4820
|
warnedDisabledWrite: false,
|
|
4863
4821
|
// --- methods: thin per-instance skins over the module kernel ---
|
|
4864
|
-
rehydrate: (
|
|
4865
|
-
activate: (
|
|
4866
|
-
adoptResolvedDefaults: (
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4822
|
+
rehydrate: bind(rehydrate),
|
|
4823
|
+
activate: bind(activate),
|
|
4824
|
+
adoptResolvedDefaults: bind(adoptResolvedDefaults),
|
|
4825
|
+
pathHasAsyncValidationByKey: bind(pathHasAsyncValidationByKey),
|
|
4826
|
+
applyFormReplacement: bind(applyFormReplacement),
|
|
4827
|
+
setValueAtPath: bind(setValueAtPath),
|
|
4828
|
+
getValueAtPath: bind(getValueAtPath),
|
|
4829
|
+
arrayElementKey: bind(arrayElementKey),
|
|
4830
|
+
reset: bind(reset),
|
|
4831
|
+
resetField: bind(resetField),
|
|
4832
|
+
// The schema/user pair below reads as a fold waiting to happen. It was
|
|
4833
|
+
// tried: a `setErrorsForPathIn(channel)` factory measured 10 B LARGER,
|
|
4834
|
+
// because gzip had already collected the rent on two adjacent copies
|
|
4835
|
+
// and the helper added a name the original did not need.
|
|
4875
4836
|
setSchemaErrorsForPath: (path, entries) => setErrorChannelForKey(
|
|
4876
4837
|
st,
|
|
4877
4838
|
canonicalizePath(path).key,
|
|
@@ -4880,7 +4841,7 @@ function createFormStore(options) {
|
|
|
4880
4841
|
),
|
|
4881
4842
|
setAllSchemaErrors: (entries) => replaceErrorChannel(st, "schema", entries),
|
|
4882
4843
|
clearSchemaErrors: (path) => clearErrorChannel(st, "schema", path),
|
|
4883
|
-
applySchemaErrorsForSubtree: (
|
|
4844
|
+
applySchemaErrorsForSubtree: bind(applySchemaErrorsForSubtree),
|
|
4884
4845
|
setAllUserErrors: (entries) => replaceErrorChannel(st, "user", entries),
|
|
4885
4846
|
setUserErrorsForPath: (path, entries) => setErrorChannelForKey(
|
|
4886
4847
|
st,
|
|
@@ -4889,37 +4850,34 @@ function createFormStore(options) {
|
|
|
4889
4850
|
entries.length === 0 ? NO_ERRORS : [...entries]
|
|
4890
4851
|
),
|
|
4891
4852
|
clearUserErrors: (path) => clearErrorChannel(st, "user", path),
|
|
4892
|
-
restoreErrorCells: (
|
|
4893
|
-
getErrorsForPath: (
|
|
4894
|
-
ensurePathOrdinal: (
|
|
4895
|
-
noteDomConnected: (
|
|
4896
|
-
noteDomDisconnected: (
|
|
4897
|
-
markFocused: (
|
|
4898
|
-
markInteracted: (
|
|
4899
|
-
touchAtPath: (
|
|
4900
|
-
interactAtPath: (
|
|
4901
|
-
markConnectedOptimistically: (
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
emitSubmitSuccess: () => emitSubmitSuccess(st),
|
|
4921
|
-
registerCleanup: (fn) => registerCleanup(st, fn),
|
|
4922
|
-
dispose: () => dispose(st)
|
|
4853
|
+
restoreErrorCells: bind(restoreErrorCells),
|
|
4854
|
+
getErrorsForPath: bind(getErrorsForPath),
|
|
4855
|
+
ensurePathOrdinal: bind(ensurePathOrdinal),
|
|
4856
|
+
noteDomConnected: bind(noteDomConnected),
|
|
4857
|
+
noteDomDisconnected: bind(noteDomDisconnected),
|
|
4858
|
+
markFocused: bind(markFocused),
|
|
4859
|
+
markInteracted: bind(markInteracted),
|
|
4860
|
+
touchAtPath: bind(touchAtPath),
|
|
4861
|
+
interactAtPath: bind(interactAtPath),
|
|
4862
|
+
markConnectedOptimistically: bind(markConnectedOptimistically),
|
|
4863
|
+
isPristineAtPathByKey: bind(isPristineAtPathByKey),
|
|
4864
|
+
hasStructuralChangeUnder: bind(hasStructuralChangeUnder),
|
|
4865
|
+
hasRemovedSubtreeUnder: bind(hasRemovedSubtreeUnder),
|
|
4866
|
+
getFieldRecord: bind(getFieldRecord),
|
|
4867
|
+
cancelFieldValidation: bind(cancelFieldValidation),
|
|
4868
|
+
beginTransform: bind(beginTransform),
|
|
4869
|
+
isCurrentTransform: bind(isCurrentTransform),
|
|
4870
|
+
endTransform: bind(endTransform),
|
|
4871
|
+
setTransformError: bind(setTransformError),
|
|
4872
|
+
cancelTransformsUnder: bind(cancelTransformsUnder),
|
|
4873
|
+
settleTransforms: bind(settleTransforms),
|
|
4874
|
+
scheduleFieldValidation: bind(scheduleFieldValidation),
|
|
4875
|
+
onFormChange: bind(onFormChange),
|
|
4876
|
+
onSubmitSuccess: bind(onSubmitSuccess),
|
|
4877
|
+
onReset: bind(onReset),
|
|
4878
|
+
emitSubmitSuccess: bind(emitSubmitSuccess),
|
|
4879
|
+
registerCleanup: bind(registerCleanup),
|
|
4880
|
+
dispose: bind(dispose)
|
|
4923
4881
|
};
|
|
4924
4882
|
rebuildAuthoredPaths(st, defaultValues, schemaInitialData);
|
|
4925
4883
|
seedOriginalsFromBaseline(st, schemaInitialData, true);
|
|
@@ -4961,7 +4919,7 @@ function createFormStore(options) {
|
|
|
4961
4919
|
blurredAfterInteraction: false
|
|
4962
4920
|
});
|
|
4963
4921
|
});
|
|
4964
|
-
if (
|
|
4922
|
+
if (!schemaResponse.success) {
|
|
4965
4923
|
replaceErrorChannel(st, "schema", schemaResponse.errors);
|
|
4966
4924
|
}
|
|
4967
4925
|
}
|
|
@@ -4992,24 +4950,23 @@ function useAbstractForm(configuration, options) {
|
|
|
4992
4950
|
const resolvedDefaults = resolveTrichotomy(configuration.defaultValues);
|
|
4993
4951
|
const materialisedDefaults = resolvedDefaults.kind === "sync" ? resolvedDefaults.value : void 0;
|
|
4994
4952
|
const { defaultValues: _droppedDefaults, ...configWithoutDefaults } = configuration;
|
|
4995
|
-
const
|
|
4996
|
-
const merged = mergeWithDefaults(registry.defaults, trichotomyOverride);
|
|
4997
|
-
const maxRecursionDepth = normalizeNumericOption({
|
|
4998
|
-
value: merged.maxRecursionDepth ?? DEFAULT_MAX_RECURSION_DEPTH,
|
|
4999
|
-
source: "useForm.maxRecursionDepth",
|
|
5000
|
-
allowInfinity: true,
|
|
5001
|
-
min: 0,
|
|
5002
|
-
defaultValue: DEFAULT_MAX_RECURSION_DEPTH
|
|
5003
|
-
});
|
|
5004
|
-
const resolvedSchema = getComputedSchema(key, configuration.schema, { maxRecursionDepth });
|
|
4953
|
+
const materialisedConfiguration = materialisedDefaults === void 0 ? configWithoutDefaults : { ...configWithoutDefaults, defaultValues: materialisedDefaults };
|
|
5005
4954
|
const existing = registry.forms.get(key);
|
|
4955
|
+
const resolvedSchema = getComputedSchema(key, configuration.schema, {
|
|
4956
|
+
maxRecursionDepth: DEFAULT_MAX_RECURSION_DEPTH
|
|
4957
|
+
}) ;
|
|
5006
4958
|
if (existing !== void 0) {
|
|
5007
4959
|
void import('../chunks/dev-key-collision-warnings.mjs').then((m) => {
|
|
5008
4960
|
void m.warnOnSchemaFingerprintMismatch(key, existing.schema, resolvedSchema);
|
|
5009
4961
|
});
|
|
5010
4962
|
}
|
|
5011
4963
|
const hadPendingHydration = registry.pendingHydration.has(key);
|
|
5012
|
-
const state = existing ?? buildFreshState(
|
|
4964
|
+
const state = existing ?? buildFreshState(
|
|
4965
|
+
key,
|
|
4966
|
+
resolvedSchema,
|
|
4967
|
+
materialisedConfiguration,
|
|
4968
|
+
registry
|
|
4969
|
+
);
|
|
5013
4970
|
if (existing !== void 0) ; else if (resolvedDefaults.kind === "sync") {
|
|
5014
4971
|
state.defaultsResolved.value = true;
|
|
5015
4972
|
}
|
|
@@ -5034,8 +4991,8 @@ function useAbstractForm(configuration, options) {
|
|
|
5034
4991
|
const releaseConsumer = registry.trackConsumer(key);
|
|
5035
4992
|
onScopeDispose(releaseConsumer);
|
|
5036
4993
|
}
|
|
5037
|
-
if (existing === void 0 &&
|
|
5038
|
-
const historyModule =
|
|
4994
|
+
if (existing === void 0 && materialisedConfiguration.history !== void 0) {
|
|
4995
|
+
const historyModule = materialisedConfiguration.history.attach(state);
|
|
5039
4996
|
state.modules.set(HISTORY_MODULE_KEY, historyModule);
|
|
5040
4997
|
state.registerCleanup(() => historyModule.dispose());
|
|
5041
4998
|
}
|
|
@@ -5048,36 +5005,16 @@ function useAbstractForm(configuration, options) {
|
|
|
5048
5005
|
provide(kFormInstanceId, formInstanceId);
|
|
5049
5006
|
}
|
|
5050
5007
|
const apiOptions = pickDefined({
|
|
5051
|
-
|
|
5008
|
+
focusOnInvalidSubmit: materialisedConfiguration.focusOnInvalidSubmit,
|
|
5052
5009
|
history: state.modules.get(HISTORY_MODULE_KEY),
|
|
5053
|
-
validateOn:
|
|
5054
|
-
debounceMs:
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
rememberVariants: merged.rememberVariants,
|
|
5058
|
-
autoAria: merged.autoAria
|
|
5010
|
+
validateOn: materialisedConfiguration.validateOn,
|
|
5011
|
+
debounceMs: materialisedConfiguration.debounceMs,
|
|
5012
|
+
coerce: materialisedConfiguration.coerce,
|
|
5013
|
+
rememberVariants: materialisedConfiguration.rememberVariants
|
|
5059
5014
|
});
|
|
5060
5015
|
const api = buildFormApi(state, formInstanceId, apiOptions);
|
|
5061
5016
|
return api;
|
|
5062
5017
|
}
|
|
5063
|
-
function mergeWithDefaults(defaults, configuration) {
|
|
5064
|
-
return {
|
|
5065
|
-
...configuration,
|
|
5066
|
-
...pickDefined({
|
|
5067
|
-
strict: configuration.strict ?? defaults.strict,
|
|
5068
|
-
onInvalidSubmit: configuration.onInvalidSubmit ?? defaults.onInvalidSubmit,
|
|
5069
|
-
history: configuration.history ?? defaults.history,
|
|
5070
|
-
rememberVariants: configuration.rememberVariants ?? defaults.rememberVariants,
|
|
5071
|
-
disabled: configuration.disabled ?? defaults.disabled,
|
|
5072
|
-
coerce: configuration.coerce ?? defaults.coerce,
|
|
5073
|
-
validateOn: configuration.validateOn ?? defaults.validateOn,
|
|
5074
|
-
debounceMs: configuration.debounceMs ?? defaults.debounceMs,
|
|
5075
|
-
getDisplayState: configuration.getDisplayState ?? defaults.getDisplayState,
|
|
5076
|
-
maxRecursionDepth: configuration.maxRecursionDepth ?? defaults.maxRecursionDepth,
|
|
5077
|
-
autoAria: configuration.autoAria ?? defaults.autoAria
|
|
5078
|
-
})
|
|
5079
|
-
};
|
|
5080
|
-
}
|
|
5081
5018
|
const HISTORY_MODULE_KEY = "history";
|
|
5082
5019
|
function buildFreshState(key, schema, configuration, registry) {
|
|
5083
5020
|
const pending = registry.pendingHydration.get(key);
|
|
@@ -5097,13 +5034,11 @@ function buildFreshState(key, schema, configuration, registry) {
|
|
|
5097
5034
|
hydration: pending,
|
|
5098
5035
|
ssr: registry.ssr,
|
|
5099
5036
|
...pickDefined({
|
|
5100
|
-
strict: configuration.strict,
|
|
5101
5037
|
validateOn: configuration.validateOn,
|
|
5102
5038
|
debounceMs: configuration.debounceMs,
|
|
5103
5039
|
rememberVariants: configuration.rememberVariants,
|
|
5104
5040
|
disabled: configuration.disabled,
|
|
5105
5041
|
coerce: configuration.coerce,
|
|
5106
|
-
getDisplayState: configuration.getDisplayState,
|
|
5107
5042
|
initialBlankPaths
|
|
5108
5043
|
}),
|
|
5109
5044
|
// Server-only: bind the SSR prefetch coordination handles. `enqueue`
|
|
@@ -5417,25 +5352,18 @@ function createWizardHistory(param) {
|
|
|
5417
5352
|
};
|
|
5418
5353
|
}
|
|
5419
5354
|
|
|
5420
|
-
const NOOP_FINGERPRINT = "attaform:wizard-noop";
|
|
5421
5355
|
const EMPTY_SLIM_KINDS = /* @__PURE__ */ new Set();
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
errors: void 0,
|
|
5434
|
-
formKey
|
|
5435
|
-
};
|
|
5436
|
-
return {
|
|
5437
|
-
fingerprint: () => Promise.resolve(NOOP_FINGERPRINT),
|
|
5438
|
-
getDefaultValues: () => defaultsResponse,
|
|
5356
|
+
const EMPTY_VALUE = {};
|
|
5357
|
+
const NOOP_SUCCESS = {
|
|
5358
|
+
success: true,
|
|
5359
|
+
data: EMPTY_VALUE,
|
|
5360
|
+
errors: void 0
|
|
5361
|
+
};
|
|
5362
|
+
const NOOP_DEFAULTS = NOOP_SUCCESS;
|
|
5363
|
+
let NOOP_SCHEMA;
|
|
5364
|
+
function buildNoopWizardSchema() {
|
|
5365
|
+
NOOP_SCHEMA ?? (NOOP_SCHEMA = {
|
|
5366
|
+
getDefaultValues: () => NOOP_DEFAULTS,
|
|
5439
5367
|
getDefaultAtPath: () => void 0,
|
|
5440
5368
|
getEmptyValueAtPath: () => void 0,
|
|
5441
5369
|
isPreprocessOrCoerceLeaf: () => false,
|
|
@@ -5446,13 +5374,14 @@ function buildNoopWizardSchema(formKey) {
|
|
|
5446
5374
|
// addressable, root included.
|
|
5447
5375
|
entryKeyKindAtPath: () => void 0,
|
|
5448
5376
|
getSchemasAtPath: () => [],
|
|
5449
|
-
validateAtPath: () =>
|
|
5377
|
+
validateAtPath: () => NOOP_SUCCESS,
|
|
5450
5378
|
getSlimPrimitiveTypesAtPath: () => new Set(EMPTY_SLIM_KINDS),
|
|
5451
5379
|
isLeafAtPath: () => false,
|
|
5452
5380
|
isRequiredAtPath: () => false,
|
|
5453
5381
|
getUnionDiscriminatorAtPath: () => void 0,
|
|
5454
5382
|
hasDiscriminatedUnions: () => false
|
|
5455
|
-
};
|
|
5383
|
+
});
|
|
5384
|
+
return NOOP_SCHEMA;
|
|
5456
5385
|
}
|
|
5457
5386
|
|
|
5458
5387
|
function buildCallableReadonlySnapshotProxy(opts) {
|
|
@@ -5571,7 +5500,7 @@ function useWizard(options) {
|
|
|
5571
5500
|
if (typeof slot !== "string") continue;
|
|
5572
5501
|
if (noopForms.has(slot)) continue;
|
|
5573
5502
|
const noop = useAbstractForm({
|
|
5574
|
-
schema: buildNoopWizardSchema(
|
|
5503
|
+
schema: buildNoopWizardSchema(),
|
|
5575
5504
|
key: slot
|
|
5576
5505
|
});
|
|
5577
5506
|
noopForms.set(slot, noop);
|
|
@@ -5582,7 +5511,7 @@ function useWizard(options) {
|
|
|
5582
5511
|
const noop = lazyNoopScope.run(
|
|
5583
5512
|
() => useAbstractForm(
|
|
5584
5513
|
{
|
|
5585
|
-
schema: buildNoopWizardSchema(
|
|
5514
|
+
schema: buildNoopWizardSchema(),
|
|
5586
5515
|
key
|
|
5587
5516
|
},
|
|
5588
5517
|
{ registry }
|
|
@@ -6806,4 +6735,4 @@ function escapeForInlineScript(json) {
|
|
|
6806
6735
|
});
|
|
6807
6736
|
}
|
|
6808
6737
|
|
|
6809
|
-
export { AttaformErrorCode as A,
|
|
6738
|
+
export { AttaformErrorCode as A, injectWizard as a, isUnset as b, useAbstractForm as c, useRegister as d, escapeForInlineScript as e, useWizard as f, gate as g, getAtPath as h, injectForm as i, humanize as j, isPlainRecord as k, lazy as l, slimKindOf as s, unset as u };
|