attaform 0.31.0 → 0.31.1
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/devtools.mjs +1 -1
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +15 -2
- package/dist/dev/index.mjs +5 -5
- package/dist/dev/runtime/plugins/attaform.mjs +1 -1
- package/dist/dev/shared/{attaform-dev.zlvDr0WB.mjs → attaform-dev.04aupFBW.mjs} +3 -2
- package/dist/dev/shared/{attaform-dev.y9x9Vp9F.mjs → attaform-dev.3uTCYwy8.mjs} +572 -135
- package/dist/dev/shared/{attaform-dev.DJ3nsWw6.mjs → attaform-dev.BpVGFSFa.mjs} +18 -9
- package/dist/dev/shared/{attaform-dev.B1q-x9R9.mjs → attaform-dev.Bu6wgrA5.mjs} +1 -1
- package/dist/dev/shared/{attaform-dev.k5X47GMD.mjs → attaform-dev.Cbx0AiQF.mjs} +3 -2
- package/dist/dev/shared/attaform-dev.CwYTWyPX.mjs +120 -0
- package/dist/dev/shared/{attaform-dev.DlaT4xGd.mjs → attaform-dev.D7lKyM_7.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.CtyqGia7.mjs → attaform-dev.OceE0X3v.mjs} +4 -4
- package/dist/dev/shared/{attaform-dev.Caibt7sb.mjs → attaform-dev.PTGM9KE1.mjs} +6 -6
- package/dist/{shared/attaform.8mfKZCwH.mjs → dev/shared/attaform-dev.n6n00owJ.mjs} +49 -128
- 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 +15 -2
- package/dist/index.d.mts +16 -55
- package/dist/index.mjs +5 -5
- package/dist/runtime/plugins/attaform.mjs +1 -1
- package/dist/shared/{attaform.BWUn8Kjy.mjs → attaform.B5b-HmhH.mjs} +18 -9
- package/dist/shared/{attaform.CRVe8s82.d.mts → attaform.B9PYKlhB.d.mts} +43 -19
- package/dist/shared/{attaform.DxKQsqFZ.mjs → attaform.BPMOl562.mjs} +3 -2
- package/dist/{dev/shared/attaform-dev.CZz4GYZ6.mjs → shared/attaform.BPSqtU7a.mjs} +44 -156
- package/dist/shared/{attaform.CdZIEf7_.mjs → attaform.BhtAZysa.mjs} +3 -2
- package/dist/shared/{attaform.DAo0QBmS.d.mts → attaform.CYlF4P6X.d.mts} +31 -10
- package/dist/shared/{attaform.C4shmwyJ.mjs → attaform.CdA9bfRv.mjs} +1 -1
- package/dist/shared/{attaform.DNPJPOO7.mjs → attaform.DAf4ehIe.mjs} +569 -134
- package/dist/shared/{attaform.D9RqPgGu.d.mts → attaform.DZOynI6c.d.mts} +1 -1
- package/dist/shared/{attaform.L011tHgJ.mjs → attaform.KEfNRDot.mjs} +4 -4
- package/dist/shared/attaform._1Zp3mDG.mjs +96 -0
- package/dist/shared/{attaform.DZnrDrNb.d.mts → attaform.i13OEHJF.d.mts} +60 -7
- package/dist/shared/{attaform.DL2nl_QR.mjs → attaform.j9xI_ObC.mjs} +6 -6
- package/dist/shared/{attaform.LUPC-2Qg.mjs → attaform.u6jfHoed.mjs} +4 -4
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.mjs +6 -6
- package/dist/zod-v4.d.mts +15 -11
- package/dist/zod-v4.mjs +6 -6
- package/dist/zod.d.mts +4 -4
- package/dist/zod.mjs +5 -5
- package/package.json +2 -1
- package/skills/attaform/SKILL.md +1 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, onBeforeMount, onBeforeUpdate, onMounted } 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, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.
|
|
5
|
-
import { i as isPathPrefix,
|
|
2
|
+
import { A as ANONYMOUS_FORM_KEY_PREFIX, d as diffAndApply, i as isBarePatch, p as pickDefined, s as structuralSnapshot, n as normalizeNumericOption, a as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, b as isDescendable, c as applyChangedKeys, R as RESERVED_KEY_PREFIX, e as DEFAULT_MAX_RECURSION_DEPTH, f as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform-dev.n6n00owJ.mjs';
|
|
3
|
+
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.Bu6wgrA5.mjs';
|
|
4
|
+
import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.Cbx0AiQF.mjs';
|
|
5
|
+
import { e as canonicalizePath, i as isPathPrefix, f as pathsEqual, 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.04aupFBW.mjs';
|
|
6
|
+
import { i as isShadowedKey, e as safeOwnHas, a as safeOwnRead, f as consumerHas, g as spreadConsumerRecord, h as copyConsumerArray, r as readConsumerIndex, s as safeAssign, c as consumerKeys, b as readConsumerProp, d as callConsumerFn, j as consumerSymbolKeys, k as reportConsumerThrow } from './attaform-dev.CwYTWyPX.mjs';
|
|
6
7
|
|
|
7
8
|
const AttaformErrorCode = {
|
|
8
9
|
/** A required field is in the blank set: no value was supplied. */
|
|
@@ -141,7 +142,7 @@ function hashStableString(input, seed = 0) {
|
|
|
141
142
|
const ANON_STEM = "atta";
|
|
142
143
|
function readableFormKeyStem(formKey) {
|
|
143
144
|
if (formKey === "" || formKey.startsWith(ANONYMOUS_FORM_KEY_PREFIX)) return ANON_STEM;
|
|
144
|
-
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|(
|
|
145
|
+
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|([^-])-+$/g, "$1");
|
|
145
146
|
return sanitized === "" ? ANON_STEM : sanitized;
|
|
146
147
|
}
|
|
147
148
|
function fieldIdToken(formInstanceId, pathKey) {
|
|
@@ -645,6 +646,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
645
646
|
let asyncPending = false;
|
|
646
647
|
const submissionAttempts = state.submissionAttempts.value;
|
|
647
648
|
const blurredLeafSegments = [];
|
|
649
|
+
const errorsByKey = errorBucketsAt(state, segments, key);
|
|
648
650
|
const descendantLeaves = [];
|
|
649
651
|
visitActiveLeafPaths(value, segments, (leafSegments) => {
|
|
650
652
|
const { key: leafKey } = keyForSegments(leafSegments);
|
|
@@ -654,6 +656,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
654
656
|
});
|
|
655
657
|
for (const { key: leafKey, segments: leafSeg } of descendantLeaves) {
|
|
656
658
|
const leafRecord = state.fields.get(leafKey);
|
|
659
|
+
const leafErrors = errorsByKey.get(leafKey);
|
|
660
|
+
if (leafErrors !== void 0) leafErrors.walked = true;
|
|
657
661
|
if (!state.isPristineAtPathByKey(leafKey, leafSeg)) {
|
|
658
662
|
pristine = false;
|
|
659
663
|
dirty = true;
|
|
@@ -688,22 +692,28 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
688
692
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
689
693
|
}
|
|
690
694
|
}
|
|
691
|
-
if (!dirty && state.
|
|
695
|
+
if (!dirty && !(Array.isArray(value) || isPlainRecord(value)) && !state.isPristineAtPathByKey(key, segments)) {
|
|
692
696
|
pristine = false;
|
|
693
697
|
dirty = true;
|
|
694
698
|
}
|
|
695
|
-
if (!dirty && state.
|
|
699
|
+
if (!dirty && state.hasStructuralChangeUnder(segments, key)) {
|
|
696
700
|
pristine = false;
|
|
697
701
|
dirty = true;
|
|
698
702
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
703
|
+
if (!dirty && state.hasRemovedSubtreeUnder(segments, key)) {
|
|
704
|
+
pristine = false;
|
|
705
|
+
dirty = true;
|
|
706
|
+
}
|
|
707
|
+
const errorBuckets = sortErrorBuckets(errorsByKey);
|
|
708
|
+
const errors = flattenErrorBuckets(errorBuckets);
|
|
709
|
+
const revealedDescendantError = errors.length > 0 && descendantErrorRevealed(
|
|
710
|
+
state,
|
|
711
|
+
segments,
|
|
712
|
+
errorBuckets,
|
|
713
|
+
submissionAttempts,
|
|
714
|
+
blurredAfterInteraction,
|
|
715
|
+
blurredLeafSegments
|
|
716
|
+
);
|
|
707
717
|
if (!asyncPending && state.pathHasAsyncValidationByKey(key, segments)) asyncPending = true;
|
|
708
718
|
if ((state.fieldValidationCounts.get(key) ?? 0) > 0) {
|
|
709
719
|
validating = true;
|
|
@@ -725,6 +735,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
725
735
|
if (ownRecord.interacted === true) interacted = true;
|
|
726
736
|
if (ownRecord.blurredAfterInteraction === true) blurredAfterInteraction = true;
|
|
727
737
|
if (ownRecord.connected === true) connected = true;
|
|
738
|
+
const ts = ownRecord.updatedAt;
|
|
739
|
+
if (ts !== null && (updatedAt === null || ts > updatedAt)) updatedAt = ts;
|
|
728
740
|
}
|
|
729
741
|
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
730
742
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
@@ -816,9 +828,41 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
816
828
|
firstOwnError
|
|
817
829
|
};
|
|
818
830
|
}
|
|
831
|
+
function descendantErrorRevealed(state, segments, buckets, submissionAttempts, blurredAfterInteraction, blurredLeafSegments) {
|
|
832
|
+
for (const bucket of buckets) {
|
|
833
|
+
let ownHistory;
|
|
834
|
+
for (const e of bucket.errors) {
|
|
835
|
+
const ePath = e.path;
|
|
836
|
+
if (pathsEqual(ePath, segments)) continue;
|
|
837
|
+
if (submissionAttempts > 0) return true;
|
|
838
|
+
if (ePath.length === 1 && ePath[0] === "") {
|
|
839
|
+
if (blurredAfterInteraction) return true;
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
for (const leaf of blurredLeafSegments) if (isPathPrefix(ePath, leaf)) return true;
|
|
843
|
+
if (bucket.walked) continue;
|
|
844
|
+
ownHistory ?? (ownHistory = state.fields.get(bucket.key)?.blurredAfterInteraction === true);
|
|
845
|
+
if (ownHistory) return true;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return false;
|
|
849
|
+
}
|
|
819
850
|
function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
851
|
+
return flattenErrorBuckets(sortErrorBuckets(errorBucketsAt(state, prefix, prefixKey)));
|
|
852
|
+
}
|
|
853
|
+
const NO_ERROR_BUCKETS = /* @__PURE__ */ new Map();
|
|
854
|
+
function sortErrorBuckets(buckets) {
|
|
855
|
+
if (buckets.size <= 1) return [...buckets.values()];
|
|
856
|
+
return [...buckets.values()].sort((a, b) => a.ordinal - b.ordinal);
|
|
857
|
+
}
|
|
858
|
+
function flattenErrorBuckets(buckets) {
|
|
859
|
+
if (buckets.length === 0) return [];
|
|
860
|
+
if (buckets.length === 1) return buckets[0]?.errors ?? [];
|
|
861
|
+
return buckets.flatMap((bucket) => bucket.errors);
|
|
862
|
+
}
|
|
863
|
+
function errorBucketsAt(state, prefix, prefixKey) {
|
|
820
864
|
const candidates = state.errorWindowAt(prefix, prefixKey);
|
|
821
|
-
if (candidates.length === 0) return
|
|
865
|
+
if (candidates.length === 0) return NO_ERROR_BUCKETS;
|
|
822
866
|
const formValue = state.form.value;
|
|
823
867
|
const cells = state.errorCells();
|
|
824
868
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -831,19 +875,16 @@ function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
|
831
875
|
const userList = cell?.user;
|
|
832
876
|
const total = (schemaList?.length ?? 0) + (blankList?.length ?? 0) + (userList?.length ?? 0);
|
|
833
877
|
if (total === 0) continue;
|
|
834
|
-
|
|
835
|
-
let bucket = buckets.get(ordinal);
|
|
878
|
+
let bucket = buckets.get(key);
|
|
836
879
|
if (bucket === void 0) {
|
|
837
|
-
bucket = [];
|
|
838
|
-
buckets.set(
|
|
880
|
+
bucket = { key, ordinal: state.ensurePathOrdinal(key), errors: [], walked: false };
|
|
881
|
+
buckets.set(key, bucket);
|
|
839
882
|
}
|
|
840
|
-
if (schemaList !== void 0) bucket.push(...schemaList);
|
|
841
|
-
if (blankList !== void 0) bucket.push(...blankList);
|
|
842
|
-
if (userList !== void 0) bucket.push(...userList);
|
|
883
|
+
if (schemaList !== void 0) bucket.errors.push(...schemaList);
|
|
884
|
+
if (blankList !== void 0) bucket.errors.push(...blankList);
|
|
885
|
+
if (userList !== void 0) bucket.errors.push(...userList);
|
|
843
886
|
}
|
|
844
|
-
|
|
845
|
-
if (buckets.size === 1) return [...buckets.values()][0];
|
|
846
|
-
return [...buckets.entries()].sort(([a], [b]) => a - b).flatMap(([, errs]) => errs);
|
|
887
|
+
return buckets;
|
|
847
888
|
}
|
|
848
889
|
const EMPTY_ELEMENTS = Object.freeze([]);
|
|
849
890
|
|
|
@@ -875,7 +916,7 @@ function liveContainerHasKey(state, segments, key) {
|
|
|
875
916
|
return Number.isInteger(index) && index >= 0 && String(index) === key && value.has(index);
|
|
876
917
|
}
|
|
877
918
|
if (value instanceof Set) return false;
|
|
878
|
-
return
|
|
919
|
+
return safeOwnHas(value, key);
|
|
879
920
|
}
|
|
880
921
|
function isArrayPath(state, segments) {
|
|
881
922
|
if (segments.length === 0) return false;
|
|
@@ -1542,7 +1583,7 @@ function deleteKeysAtIndices(keys, del, arrayPath, indices) {
|
|
|
1542
1583
|
del(hit.key);
|
|
1543
1584
|
}
|
|
1544
1585
|
}
|
|
1545
|
-
function createArrayIdentity(getArrayLength) {
|
|
1586
|
+
function createArrayIdentity(getArrayLength, onChange) {
|
|
1546
1587
|
const tokens = /* @__PURE__ */ new Map();
|
|
1547
1588
|
const baselines = /* @__PURE__ */ new Map();
|
|
1548
1589
|
let counter = 0;
|
|
@@ -1554,7 +1595,13 @@ function createArrayIdentity(getArrayLength) {
|
|
|
1554
1595
|
ids = [];
|
|
1555
1596
|
tokens.set(arrayKey, ids);
|
|
1556
1597
|
}
|
|
1557
|
-
|
|
1598
|
+
if (ids.length < expectedLen) {
|
|
1599
|
+
const baseline = baselines.get(arrayKey);
|
|
1600
|
+
while (ids.length < expectedLen) {
|
|
1601
|
+
const anchored = baseline?.[ids.length];
|
|
1602
|
+
ids.push(anchored !== void 0 && !ids.includes(anchored) ? anchored : allocate());
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1558
1605
|
if (ids.length > expectedLen) ids.length = expectedLen;
|
|
1559
1606
|
if (firstTrack) baselines.set(arrayKey, [...ids]);
|
|
1560
1607
|
return ids;
|
|
@@ -1580,15 +1627,39 @@ function createArrayIdentity(getArrayLength) {
|
|
|
1580
1627
|
const arrayKey = canonicalizePath(arraySegs).key;
|
|
1581
1628
|
const ids = ensure(arrayKey, remap.oldLen);
|
|
1582
1629
|
tokens.set(arrayKey, permuteList(ids, remap, allocate));
|
|
1630
|
+
onChange([arraySegs]);
|
|
1583
1631
|
},
|
|
1584
1632
|
applyRemap(arrayPath, remap) {
|
|
1585
1633
|
if (remap.moved.size === 0 && remap.vacated.size === 0 && remap.fresh.size === 0) return;
|
|
1586
|
-
|
|
1634
|
+
const moved = [];
|
|
1635
|
+
for (const hit of collectKeysAtIndices(tokens.keys(), arrayPath, remapAffects(remap))) {
|
|
1636
|
+
moved.push(hit.segments);
|
|
1637
|
+
}
|
|
1638
|
+
migrateMapSubtree(tokens, arrayPath, remap, (value, segments) => {
|
|
1639
|
+
moved.push(segments);
|
|
1640
|
+
return value;
|
|
1641
|
+
});
|
|
1587
1642
|
migrateMapSubtree(baselines, arrayPath, remap, (value) => value);
|
|
1643
|
+
if (moved.length > 0) onChange(moved);
|
|
1588
1644
|
},
|
|
1589
1645
|
realign(arraySegs) {
|
|
1590
1646
|
ensure(canonicalizePath(arraySegs).key, getArrayLength(arraySegs));
|
|
1591
1647
|
},
|
|
1648
|
+
realignContaining(paths) {
|
|
1649
|
+
if (tokens.size === 0 || paths.length === 0) return;
|
|
1650
|
+
const resized = [];
|
|
1651
|
+
for (const [arrayKey, ids] of tokens) {
|
|
1652
|
+
const segs = segmentsForPathKey(arrayKey);
|
|
1653
|
+
if (segs === null || !paths.some((path) => isPathPrefix(segs, path) || isPathPrefix(path, segs))) {
|
|
1654
|
+
continue;
|
|
1655
|
+
}
|
|
1656
|
+
const len = getArrayLength(segs);
|
|
1657
|
+
if (ids.length === len) continue;
|
|
1658
|
+
ensure(arrayKey, len);
|
|
1659
|
+
resized.push(segs);
|
|
1660
|
+
}
|
|
1661
|
+
if (resized.length > 0) onChange(resized);
|
|
1662
|
+
},
|
|
1592
1663
|
hasStructuralChangeUnder(prefix) {
|
|
1593
1664
|
for (const arrayKey of tokens.keys()) {
|
|
1594
1665
|
if (orderPristineForKey(arrayKey)) continue;
|
|
@@ -1599,15 +1670,39 @@ function createArrayIdentity(getArrayLength) {
|
|
|
1599
1670
|
return false;
|
|
1600
1671
|
},
|
|
1601
1672
|
rebaselineAll() {
|
|
1673
|
+
const rebased = [];
|
|
1602
1674
|
for (const arrayKey of [...tokens.keys()]) {
|
|
1603
1675
|
const segs = segmentsForPathKey(arrayKey);
|
|
1604
1676
|
if (segs === null) continue;
|
|
1605
1677
|
const ids = ensure(arrayKey, getArrayLength(segs));
|
|
1606
1678
|
baselines.set(arrayKey, [...ids]);
|
|
1679
|
+
rebased.push(segs);
|
|
1607
1680
|
}
|
|
1681
|
+
if (rebased.length > 0) onChange(rebased);
|
|
1682
|
+
},
|
|
1683
|
+
snapshot() {
|
|
1684
|
+
return { tokens: copyLists(tokens), baselines: copyLists(baselines) };
|
|
1685
|
+
},
|
|
1686
|
+
restore(orders) {
|
|
1687
|
+
const keys = /* @__PURE__ */ new Set([...tokens.keys(), ...orders.tokens.keys()]);
|
|
1688
|
+
tokens.clear();
|
|
1689
|
+
for (const [key, ids] of orders.tokens) tokens.set(key, [...ids]);
|
|
1690
|
+
baselines.clear();
|
|
1691
|
+
for (const [key, ids] of orders.baselines) baselines.set(key, [...ids]);
|
|
1692
|
+
const restored = [];
|
|
1693
|
+
for (const key of keys) {
|
|
1694
|
+
const segs = segmentsForPathKey(key);
|
|
1695
|
+
if (segs !== null) restored.push(segs);
|
|
1696
|
+
}
|
|
1697
|
+
if (restored.length > 0) onChange(restored);
|
|
1608
1698
|
}
|
|
1609
1699
|
};
|
|
1610
1700
|
}
|
|
1701
|
+
function copyLists(lists) {
|
|
1702
|
+
const out = /* @__PURE__ */ new Map();
|
|
1703
|
+
for (const [key, ids] of lists) out.set(key, [...ids]);
|
|
1704
|
+
return out;
|
|
1705
|
+
}
|
|
1611
1706
|
function createVariantMemory() {
|
|
1612
1707
|
const memory = /* @__PURE__ */ new Map();
|
|
1613
1708
|
return {
|
|
@@ -1674,6 +1769,8 @@ function createArrayBookkeeping(deps) {
|
|
|
1674
1769
|
blankPaths,
|
|
1675
1770
|
originalBlankPaths,
|
|
1676
1771
|
authoredPaths,
|
|
1772
|
+
removedPaths,
|
|
1773
|
+
notifyStructure,
|
|
1677
1774
|
fieldValidationCounts,
|
|
1678
1775
|
fieldValidatingSince,
|
|
1679
1776
|
fieldValidationState,
|
|
@@ -1681,10 +1778,35 @@ function createArrayBookkeeping(deps) {
|
|
|
1681
1778
|
arrayIdentity,
|
|
1682
1779
|
variantMemory,
|
|
1683
1780
|
touchFieldRecord,
|
|
1781
|
+
stampContainers,
|
|
1782
|
+
stampBareContainers,
|
|
1783
|
+
foldInteractionHistory,
|
|
1684
1784
|
decFieldValidation
|
|
1685
1785
|
} = deps;
|
|
1686
1786
|
function migrateElementState(arrayPath, remap) {
|
|
1687
1787
|
if (remap.moved.size === 0 && remap.vacated.size === 0) return;
|
|
1788
|
+
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
1789
|
+
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
1790
|
+
const removedMoved = [];
|
|
1791
|
+
for (const hit of collectKeysAtIndices(removedPaths.keys(), arrayPath, remapAffects(remap))) {
|
|
1792
|
+
removedMoved.push(hit.segments);
|
|
1793
|
+
}
|
|
1794
|
+
migrateMapSubtree(removedPaths, arrayPath, remap, (_, segments) => {
|
|
1795
|
+
removedMoved.push(segments);
|
|
1796
|
+
return segments;
|
|
1797
|
+
});
|
|
1798
|
+
if (remap.vacated.size > 0) {
|
|
1799
|
+
const released = [];
|
|
1800
|
+
for (const { key } of collectKeysAtIndices(
|
|
1801
|
+
fields.keys(),
|
|
1802
|
+
arrayPath,
|
|
1803
|
+
(index) => remap.vacated.has(index)
|
|
1804
|
+
)) {
|
|
1805
|
+
const record = fields.get(key);
|
|
1806
|
+
if (record !== void 0) released.push(record);
|
|
1807
|
+
}
|
|
1808
|
+
foldInteractionHistory(arrayPath, released);
|
|
1809
|
+
}
|
|
1688
1810
|
migrateMapSubtree(fields, arrayPath, remap, (record, segments) => ({
|
|
1689
1811
|
...record,
|
|
1690
1812
|
path: segments
|
|
@@ -1698,21 +1820,37 @@ function createArrayBookkeeping(deps) {
|
|
|
1698
1820
|
value: record.value
|
|
1699
1821
|
}));
|
|
1700
1822
|
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
1701
|
-
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
1702
|
-
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
1703
1823
|
migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
|
|
1704
1824
|
migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
|
|
1825
|
+
migrateMapSubtree(fieldValidationState, arrayPath, remap, (entry, segments) => {
|
|
1826
|
+
entry.key = keyForSegments(segments).key;
|
|
1827
|
+
entry.path = segments;
|
|
1828
|
+
return entry;
|
|
1829
|
+
});
|
|
1705
1830
|
arrayIdentity.applyRemap(arrayPath, remap);
|
|
1831
|
+
if (removedMoved.length > 0) notifyStructure(removedMoved);
|
|
1706
1832
|
}
|
|
1707
|
-
function seedFreshElement(arrayPath, freshIndex) {
|
|
1833
|
+
function seedFreshElement(arrayPath, freshIndex, now) {
|
|
1708
1834
|
const elementPath = [...arrayPath, freshIndex];
|
|
1709
|
-
const
|
|
1835
|
+
const patches = [];
|
|
1710
1836
|
diffAndApply(void 0, getAtPath(form.value, elementPath), elementPath, (patch) => {
|
|
1837
|
+
patches.push(patch);
|
|
1838
|
+
});
|
|
1839
|
+
const bare = [];
|
|
1840
|
+
patches.forEach((patch, index) => {
|
|
1711
1841
|
if (patch.kind !== "added") return;
|
|
1712
|
-
|
|
1842
|
+
if (isBarePatch(patch)) {
|
|
1843
|
+
bare.push(index);
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
const { key, segments } = canonicalizePath(patch.path);
|
|
1713
1847
|
if (!originals.has(key)) originals.set(key, { segments: patch.path, value: void 0 });
|
|
1714
|
-
touchFieldRecord(key,
|
|
1848
|
+
touchFieldRecord(key, segments, { updatedAt: now });
|
|
1715
1849
|
});
|
|
1850
|
+
if (bare.length > 0) stampBareContainers(patches, bare, now);
|
|
1851
|
+
else if (patches.length === 0 && hasAtPath(form.value, elementPath)) {
|
|
1852
|
+
stampContainers([elementPath], now);
|
|
1853
|
+
}
|
|
1716
1854
|
}
|
|
1717
1855
|
function abortValidationAtVacatedIndices(arrayPath, remap) {
|
|
1718
1856
|
if (remap.vacated.size === 0) return;
|
|
@@ -1726,21 +1864,22 @@ function createArrayBookkeeping(deps) {
|
|
|
1726
1864
|
if (entry === void 0) continue;
|
|
1727
1865
|
if (entry.timer !== null) {
|
|
1728
1866
|
clearTimeout(entry.timer);
|
|
1729
|
-
} else if (!entry.settled) {
|
|
1867
|
+
} else if (!entry.settled && !entry.released) {
|
|
1730
1868
|
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
1731
1869
|
decFieldValidation(hit.key);
|
|
1870
|
+
entry.released = true;
|
|
1732
1871
|
}
|
|
1733
1872
|
entry.aborted = true;
|
|
1734
1873
|
fieldValidationState.delete(hit.key);
|
|
1735
1874
|
}
|
|
1736
1875
|
}
|
|
1737
1876
|
return {
|
|
1738
|
-
applyStructuralOp(arrayPath, remap) {
|
|
1877
|
+
applyStructuralOp(arrayPath, remap, now) {
|
|
1878
|
+
abortValidationAtVacatedIndices(arrayPath, remap);
|
|
1739
1879
|
migrateElementState(arrayPath, remap);
|
|
1740
|
-
for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex);
|
|
1880
|
+
for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex, now);
|
|
1741
1881
|
const changed = changedIndices(remap);
|
|
1742
1882
|
evictSchemaVerdictsAtIndices(errorCells(), arrayPath, changed);
|
|
1743
|
-
abortValidationAtVacatedIndices(arrayPath, remap);
|
|
1744
1883
|
variantMemory.dropAtIndices(arrayPath, changed);
|
|
1745
1884
|
arrayIdentity.applyOp(arrayPath, remap);
|
|
1746
1885
|
}
|
|
@@ -2552,12 +2691,12 @@ function isPrimitiveOrEmpty(value) {
|
|
|
2552
2691
|
return t === "string" || t === "number" || t === "boolean" || t === "bigint";
|
|
2553
2692
|
}
|
|
2554
2693
|
function isSlimNumericPrimitive(value) {
|
|
2555
|
-
return value === 0 || value ===
|
|
2694
|
+
return value === 0 || typeof value === "bigint" && !value;
|
|
2556
2695
|
}
|
|
2557
2696
|
function blankForKind(slimDefault) {
|
|
2558
2697
|
if (typeof slimDefault === "string") return "";
|
|
2559
2698
|
if (typeof slimDefault === "number") return 0;
|
|
2560
|
-
if (typeof slimDefault === "bigint") return
|
|
2699
|
+
if (typeof slimDefault === "bigint") return typeof BigInt === "function" ? BigInt(0) : void 0;
|
|
2561
2700
|
if (typeof slimDefault === "boolean") return false;
|
|
2562
2701
|
if (slimDefault === null) return null;
|
|
2563
2702
|
return void 0;
|
|
@@ -2926,7 +3065,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2926
3065
|
};
|
|
2927
3066
|
const metaTarget = buildMetaProxy(META_KEYS, (key) => {
|
|
2928
3067
|
if (key === "errorCount") return metaErrors.value.length;
|
|
2929
|
-
if (
|
|
3068
|
+
if (safeOwnHas(metaOwn, key)) return metaOwn[key];
|
|
2930
3069
|
return rootFieldState.value[key];
|
|
2931
3070
|
});
|
|
2932
3071
|
const formMeta = readonly(reactive(metaTarget));
|
|
@@ -2941,8 +3080,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2941
3080
|
);
|
|
2942
3081
|
state.reset(walked.cleanedValues);
|
|
2943
3082
|
for (const pathKey of walked.paths) {
|
|
2944
|
-
state.blankPaths.add(pathKey);
|
|
2945
3083
|
state.originalBlankPaths.add(pathKey);
|
|
3084
|
+
state.blankPaths.add(pathKey);
|
|
2946
3085
|
}
|
|
2947
3086
|
}
|
|
2948
3087
|
};
|
|
@@ -3427,16 +3566,15 @@ function appendHydrationFailedEntry(st, error) {
|
|
|
3427
3566
|
return entry;
|
|
3428
3567
|
}
|
|
3429
3568
|
|
|
3430
|
-
const isContainer = (value) => Array.isArray(value) || isPlainRecord(value);
|
|
3431
3569
|
function isHydratedFieldRecord(value) {
|
|
3432
3570
|
if (typeof value !== "object" || value === null) return false;
|
|
3433
3571
|
const r = value;
|
|
3434
3572
|
return Array.isArray(r.path) && (typeof r.updatedAt === "string" || r.updatedAt === null) && typeof r.connected === "boolean" && (typeof r.focused === "boolean" || r.focused === null) && (typeof r.blurred === "boolean" || r.blurred === null) && typeof r.touched === "boolean" && typeof r.interacted === "boolean" && typeof r.blurredAfterInteraction === "boolean";
|
|
3435
3573
|
}
|
|
3436
|
-
function withClearedHistoryFlags(record,
|
|
3574
|
+
function withClearedHistoryFlags(record, updatedAt) {
|
|
3437
3575
|
return {
|
|
3438
3576
|
path: record.path,
|
|
3439
|
-
updatedAt
|
|
3577
|
+
updatedAt,
|
|
3440
3578
|
connected: record.connected,
|
|
3441
3579
|
focused: record.focused,
|
|
3442
3580
|
blurred: record.blurred,
|
|
@@ -3485,7 +3623,7 @@ function walkDuStubs(schema, value, path, warned) {
|
|
|
3485
3623
|
if (du !== void 0) {
|
|
3486
3624
|
const discValue = rec[du.discriminatorKey];
|
|
3487
3625
|
if (discValue !== void 0 && !du.isVariantSelected(discValue)) {
|
|
3488
|
-
const isKindBlank = discValue === "" || discValue === 0 || discValue ===
|
|
3626
|
+
const isKindBlank = discValue === "" || discValue === 0 || typeof discValue === "bigint" && !discValue || discValue === false || discValue === null;
|
|
3489
3627
|
if (!isKindBlank && warned !== void 0 && true) {
|
|
3490
3628
|
const dotted = path.map((s) => String(s)).join(".") || "(root)";
|
|
3491
3629
|
const key = `${dotted}::${String(discValue)}`;
|
|
@@ -3567,14 +3705,27 @@ function initialFirstValidationGate(schema) {
|
|
|
3567
3705
|
return schema.needsAsyncValidation?.() !== true;
|
|
3568
3706
|
}
|
|
3569
3707
|
function seedOriginalsFromBaseline(st, baseline) {
|
|
3570
|
-
|
|
3708
|
+
const seeded = /* @__PURE__ */ new Map();
|
|
3571
3709
|
diffAndApply({}, baseline, [], (patch) => {
|
|
3572
|
-
if (patch.kind
|
|
3573
|
-
st.originals.set(canonicalizePath(patch.path).key, {
|
|
3574
|
-
segments: patch.path,
|
|
3575
|
-
value: patch.newValue
|
|
3576
|
-
});
|
|
3710
|
+
if (patch.kind === "added") seedBaseline(seeded, canonicalizePath(patch.path).key, patch);
|
|
3577
3711
|
});
|
|
3712
|
+
replaceOriginals(st, seeded);
|
|
3713
|
+
}
|
|
3714
|
+
function replaceOriginals(st, next) {
|
|
3715
|
+
for (const [key, entry] of next) st.originals.set(key, entry);
|
|
3716
|
+
for (const key of [...toRaw(st.originals).keys()]) {
|
|
3717
|
+
if (!next.has(key)) st.originals.delete(key);
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
function seedBaseline(originals, key, patch) {
|
|
3721
|
+
const value = patch.newValue;
|
|
3722
|
+
if (!isDescendable(value)) {
|
|
3723
|
+
originals.set(key, { segments: patch.path, value });
|
|
3724
|
+
return false;
|
|
3725
|
+
}
|
|
3726
|
+
if (!(value instanceof Map))
|
|
3727
|
+
originals.set(key, { segments: patch.path, value: Array.isArray(value) ? [] : {} });
|
|
3728
|
+
return true;
|
|
3578
3729
|
}
|
|
3579
3730
|
function queueInitialAsyncValidation(st) {
|
|
3580
3731
|
if (!st.ssr && st.schema.needsAsyncValidation?.() === true) {
|
|
@@ -3736,8 +3887,18 @@ function settleTransforms(st, path) {
|
|
|
3736
3887
|
st.transformWaiters.push({ key, resolve });
|
|
3737
3888
|
});
|
|
3738
3889
|
}
|
|
3890
|
+
function writeInstant(st) {
|
|
3891
|
+
const clock = (/* @__PURE__ */ new Date()).toISOString();
|
|
3892
|
+
if (clock > st.latestStamp) return clock;
|
|
3893
|
+
const after = new Date(new Date(st.latestStamp).getTime() + 1);
|
|
3894
|
+
return Number.isFinite(after.getTime()) ? after.toISOString() : clock;
|
|
3895
|
+
}
|
|
3896
|
+
function noteStamp(st, stamp) {
|
|
3897
|
+
if (stamp !== null && stamp > st.latestStamp) st.latestStamp = stamp;
|
|
3898
|
+
}
|
|
3739
3899
|
function touchFieldRecord(st, pathKey, path, patch) {
|
|
3740
3900
|
const current = st.fields.get(pathKey);
|
|
3901
|
+
if (patch.updatedAt !== void 0) noteStamp(st, patch.updatedAt);
|
|
3741
3902
|
st.fields.set(pathKey, {
|
|
3742
3903
|
path,
|
|
3743
3904
|
updatedAt: patch.updatedAt ?? current?.updatedAt ?? null,
|
|
@@ -3756,19 +3917,188 @@ function touchFieldRecord(st, pathKey, path, patch) {
|
|
|
3756
3917
|
blurredAfterInteraction: patch.blurredAfterInteraction ?? current?.blurredAfterInteraction ?? false
|
|
3757
3918
|
});
|
|
3758
3919
|
}
|
|
3759
|
-
function
|
|
3760
|
-
|
|
3920
|
+
function stampContainers(st, containers, now) {
|
|
3921
|
+
eachAncestorOnce(containers, (key, segments) => raiseStamp(st, key, segments, now));
|
|
3922
|
+
}
|
|
3923
|
+
function raiseStamp(st, key, segments, stamp) {
|
|
3924
|
+
if ((st.fields.get(key)?.updatedAt ?? "") < stamp) {
|
|
3925
|
+
touchFieldRecord(st, key, segments, { updatedAt: stamp });
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
function holdRemovedStamps(st, patches, next) {
|
|
3929
|
+
const held = /* @__PURE__ */ new Map();
|
|
3930
|
+
const hold = (path, depth, leaf) => noteHold(st, held, next, path, depth, leaf);
|
|
3761
3931
|
for (const patch of patches) {
|
|
3762
|
-
|
|
3763
|
-
|
|
3932
|
+
if (patch.kind === "added") continue;
|
|
3933
|
+
const { oldValue, path } = patch;
|
|
3934
|
+
if (Array.isArray(oldValue) || isPlainRecord(oldValue)) {
|
|
3935
|
+
if (patch.kind === "changed") {
|
|
3936
|
+
visitActiveLeafPaths(oldValue, path, (leaf) => hold(path, path.length, leaf));
|
|
3937
|
+
}
|
|
3938
|
+
} else if (patch.kind === "removed" ? !hasAtPath(next, path) : Array.isArray(patch.newValue) || isPlainRecord(patch.newValue)) {
|
|
3939
|
+
hold(path, path.length - 1, path);
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
applyHolds(st, held);
|
|
3943
|
+
}
|
|
3944
|
+
function noteHold(st, held, next, path, depth, leaf) {
|
|
3945
|
+
const { key: leafKey } = keyForSegments(leaf);
|
|
3946
|
+
const stamp = toRaw(st.originals).has(leafKey) ? toRaw(st.fields).get(leafKey)?.updatedAt : null;
|
|
3947
|
+
if (stamp === null || stamp === void 0) return;
|
|
3948
|
+
let kept = false;
|
|
3949
|
+
for (let at = depth; at >= 0; at--) {
|
|
3950
|
+
const segments = path.slice(0, at);
|
|
3951
|
+
if (!kept && !hasAtPath(next, segments)) continue;
|
|
3952
|
+
kept = true;
|
|
3953
|
+
const { key } = keyForSegments(segments);
|
|
3954
|
+
const current = held.get(key);
|
|
3955
|
+
if (current === void 0) held.set(key, { segments, stamp });
|
|
3956
|
+
else if (stamp > current.stamp) current.stamp = stamp;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
function applyHolds(st, held) {
|
|
3960
|
+
for (const [key, { segments, stamp }] of held) raiseStamp(st, key, segments, stamp);
|
|
3961
|
+
}
|
|
3962
|
+
function stampBareContainers(st, patches, bare, now) {
|
|
3963
|
+
for (const index of bare) {
|
|
3964
|
+
const path = patches[index]?.path ?? [];
|
|
3965
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
3966
|
+
const container = path.slice(0, depth);
|
|
3967
|
+
if (depth < path.length && reachedBesides(patches, index, container)) break;
|
|
3968
|
+
const { key, segments } = keyForSegments(container);
|
|
3969
|
+
raiseStamp(st, key, segments, now);
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
function reachedBesides(patches, index, container) {
|
|
3974
|
+
for (const step of [-1, 1]) {
|
|
3975
|
+
for (let i = index + step; ; i += step) {
|
|
3976
|
+
const patch = patches[i];
|
|
3977
|
+
if (patch === void 0 || !isPathPrefix(container, patch.path)) break;
|
|
3978
|
+
if (!isBarePatch(patch)) return true;
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3981
|
+
return false;
|
|
3982
|
+
}
|
|
3983
|
+
function eachAncestorOnce(paths, visit) {
|
|
3984
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3985
|
+
for (const path of paths) {
|
|
3986
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
3987
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
3988
|
+
if (seen.has(key)) break;
|
|
3989
|
+
seen.add(key);
|
|
3990
|
+
visit(key, segments);
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
function foldInteractionHistory(st, path, released) {
|
|
3995
|
+
let touched = false;
|
|
3996
|
+
let interacted = false;
|
|
3997
|
+
let blurredAfterInteraction = false;
|
|
3998
|
+
for (const record of released) {
|
|
3999
|
+
touched || (touched = record.touched);
|
|
4000
|
+
interacted || (interacted = record.interacted);
|
|
4001
|
+
blurredAfterInteraction || (blurredAfterInteraction = record.blurredAfterInteraction);
|
|
4002
|
+
}
|
|
4003
|
+
if (!touched && !interacted && !blurredAfterInteraction) return;
|
|
4004
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
4005
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
4006
|
+
const current = st.fields.get(key);
|
|
4007
|
+
touchFieldRecord(st, key, segments, {
|
|
4008
|
+
touched: touched || current?.touched === true,
|
|
4009
|
+
interacted: interacted || current?.interacted === true,
|
|
4010
|
+
blurredAfterInteraction: blurredAfterInteraction || current?.blurredAfterInteraction === true
|
|
4011
|
+
});
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
function releaseRemovedRecords(st, segments, raw) {
|
|
4015
|
+
const released = [];
|
|
4016
|
+
let depth = segments.length;
|
|
4017
|
+
do {
|
|
4018
|
+
const { key } = keyForSegments(segments.slice(0, depth));
|
|
4019
|
+
abortValidationAt(st, key);
|
|
4020
|
+
const record = st.fields.get(key);
|
|
4021
|
+
if (record !== void 0) {
|
|
4022
|
+
released.push(record);
|
|
4023
|
+
if (record.connected) st.fields.set(key, withClearedHistoryFlags(record, null));
|
|
4024
|
+
else st.fields.delete(key);
|
|
4025
|
+
}
|
|
4026
|
+
depth--;
|
|
4027
|
+
} while (depth > 0 && !hasAtPath(raw, segments.slice(0, depth)));
|
|
4028
|
+
const present = segments.slice(0, depth);
|
|
4029
|
+
foldInteractionHistory(st, present, released);
|
|
4030
|
+
return present;
|
|
4031
|
+
}
|
|
4032
|
+
function noteRemovedBaseline(st, key, segments, notify) {
|
|
4033
|
+
if (st.originals.get(key)?.value === void 0) return;
|
|
4034
|
+
st.removedPaths.set(key, segments);
|
|
4035
|
+
notify.push(segments);
|
|
4036
|
+
}
|
|
4037
|
+
function trackForSweep(st, path, key) {
|
|
4038
|
+
st.pathSweep.track(path, key);
|
|
4039
|
+
for (let i = 1; i < path.length; i++) {
|
|
4040
|
+
const ancestor = path.slice(0, i);
|
|
4041
|
+
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
function commitWritePatches(st, patches, meta, structuralOp, now) {
|
|
4045
|
+
const arrayOpPath = structuralOp?.path;
|
|
4046
|
+
const reshaped = [];
|
|
4047
|
+
const removed = [];
|
|
4048
|
+
const resizing = [];
|
|
4049
|
+
const raw = toRaw(st.form.value);
|
|
4050
|
+
const bareAt = [];
|
|
4051
|
+
for (const [index, patch] of patches.entries()) {
|
|
4052
|
+
const { key, segments } = canonicalizePath(patch.path);
|
|
4053
|
+
const bare = isBarePatch(patch);
|
|
4054
|
+
if (!bare && !st.originals.has(key)) {
|
|
3764
4055
|
st.originals.set(key, { segments: patch.path, value: void 0 });
|
|
3765
4056
|
}
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
4057
|
+
const positional = arrayOpPath !== void 0 && segments.length > arrayOpPath.length && isPathPrefix(arrayOpPath, segments);
|
|
4058
|
+
if (structuralOp === null && (patch.kind !== "changed" || typeof patch.oldValue === "object" || typeof patch.newValue === "object")) {
|
|
4059
|
+
resizing.push(segments);
|
|
4060
|
+
}
|
|
4061
|
+
if (!positional) {
|
|
4062
|
+
if (patch.kind === "removed" && !hasAtPath(raw, segments)) {
|
|
4063
|
+
reshaped.push(releaseRemovedRecords(st, segments, raw));
|
|
4064
|
+
noteRemovedBaseline(st, key, segments, removed);
|
|
4065
|
+
} else {
|
|
4066
|
+
touchFieldRecord(st, key, segments, { updatedAt: now });
|
|
4067
|
+
if (bare) bareAt.push(index);
|
|
4068
|
+
if (patch.kind === "changed" && typeof patch.oldValue === "object" && patch.oldValue !== null) {
|
|
4069
|
+
diffAndApply(patch.oldValue, void 0, segments, (gone) => {
|
|
4070
|
+
if (!hasAtPath(raw, gone.path)) {
|
|
4071
|
+
reshaped.push(releaseRemovedRecords(st, gone.path, raw));
|
|
4072
|
+
const goneAt = canonicalizePath(gone.path);
|
|
4073
|
+
noteRemovedBaseline(st, goneAt.key, goneAt.segments, removed);
|
|
4074
|
+
}
|
|
4075
|
+
});
|
|
4076
|
+
}
|
|
4077
|
+
if (patch.kind === "changed" && isDescendable(patch.newValue)) {
|
|
4078
|
+
diffAndApply(void 0, patch.newValue, segments, (fresh) => {
|
|
4079
|
+
const at = canonicalizePath(fresh.path);
|
|
4080
|
+
trackForSweep(st, fresh.path, at.key);
|
|
4081
|
+
if (fresh.kind === "added" && isDescendable(fresh.newValue)) {
|
|
4082
|
+
reshaped.push(at.segments);
|
|
4083
|
+
return;
|
|
4084
|
+
}
|
|
4085
|
+
if (!st.originals.has(at.key)) {
|
|
4086
|
+
st.originals.set(at.key, { segments: fresh.path, value: void 0 });
|
|
4087
|
+
}
|
|
4088
|
+
touchFieldRecord(st, at.key, at.segments, { updatedAt: now });
|
|
4089
|
+
});
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
3771
4092
|
}
|
|
4093
|
+
trackForSweep(st, patch.path, key);
|
|
4094
|
+
}
|
|
4095
|
+
if (arrayOpPath !== void 0 && patches.length > 0) reshaped.push(arrayOpPath);
|
|
4096
|
+
if (reshaped.length > 0) stampContainers(st, reshaped, now);
|
|
4097
|
+
if (bareAt.length > 0) stampBareContainers(st, patches, bareAt, now);
|
|
4098
|
+
if (removed.length > 0) pulseStructure(st.structureSignal, removed);
|
|
4099
|
+
if (resizing.length > 0) st.arrayIdentity.realignContaining(resizing);
|
|
4100
|
+
if (structuralOp !== null) {
|
|
4101
|
+
st.arrayBookkeeping.applyStructuralOp(structuralOp.path, structuralOp.remap, now);
|
|
3772
4102
|
}
|
|
3773
4103
|
for (const listener of st.formChangeListeners) {
|
|
3774
4104
|
try {
|
|
@@ -3778,33 +4108,41 @@ function commitWritePatches(st, patches, meta) {
|
|
|
3778
4108
|
}
|
|
3779
4109
|
}
|
|
3780
4110
|
}
|
|
3781
|
-
function applyFormReplacementWithPath(st, next, meta,
|
|
4111
|
+
function applyFormReplacementWithPath(st, next, meta, structuralOp, now) {
|
|
3782
4112
|
const prev = st.form.value;
|
|
3783
4113
|
if (Object.is(prev, next)) return;
|
|
3784
4114
|
const patches = [];
|
|
3785
4115
|
diffAndApply(prev, next, [], (patch) => {
|
|
3786
4116
|
patches.push(patch);
|
|
3787
4117
|
});
|
|
3788
|
-
|
|
4118
|
+
holdRemovedStamps(st, patches, next);
|
|
4119
|
+
const reconciled = callConsumerFn(
|
|
4120
|
+
() => applyChangedKeys(prev, next, structuralOp?.path ?? null, [], patches),
|
|
4121
|
+
null,
|
|
4122
|
+
"stored-value"
|
|
4123
|
+
);
|
|
4124
|
+
if (reconciled === null) return;
|
|
4125
|
+
if (!reconciled) {
|
|
3789
4126
|
st.form.value = next;
|
|
3790
4127
|
} else if (patches.some(
|
|
3791
4128
|
(p) => p.path.length > 0 && typeof p.path[0] === "string" && isShadowedKey(p.path[0])
|
|
3792
4129
|
)) {
|
|
3793
4130
|
triggerRef(st.form);
|
|
3794
4131
|
}
|
|
3795
|
-
commitWritePatches(st, patches, meta);
|
|
4132
|
+
commitWritePatches(st, patches, meta, structuralOp, now);
|
|
3796
4133
|
}
|
|
3797
4134
|
function applyFormReplacement(st, next, meta) {
|
|
3798
|
-
applyFormReplacementWithPath(st, next, meta, null);
|
|
4135
|
+
applyFormReplacementWithPath(st, next, meta, null, writeInstant(st));
|
|
3799
4136
|
}
|
|
3800
|
-
function applyTargetedWrite(st, path, completedValue, meta) {
|
|
4137
|
+
function applyTargetedWrite(st, path, completedValue, meta, structuralOp, now) {
|
|
3801
4138
|
const result = tryInPlaceLeafWrite(st.form.value, path, completedValue);
|
|
3802
4139
|
if (!result.applied) {
|
|
3803
4140
|
applyFormReplacementWithPath(
|
|
3804
4141
|
st,
|
|
3805
4142
|
setAtPathWithSchemaFill(st.form.value, st.schema, path, completedValue),
|
|
3806
4143
|
meta,
|
|
3807
|
-
|
|
4144
|
+
structuralOp,
|
|
4145
|
+
now
|
|
3808
4146
|
);
|
|
3809
4147
|
return;
|
|
3810
4148
|
}
|
|
@@ -3812,9 +4150,9 @@ function applyTargetedWrite(st, path, completedValue, meta) {
|
|
|
3812
4150
|
diffAndApply(result.old, completedValue, path, (patch) => {
|
|
3813
4151
|
patches.push(patch);
|
|
3814
4152
|
});
|
|
3815
|
-
commitWritePatches(st, patches, meta);
|
|
4153
|
+
commitWritePatches(st, patches, meta, null, now);
|
|
3816
4154
|
}
|
|
3817
|
-
function setValueAtPath(st, path, value, meta) {
|
|
4155
|
+
function setValueAtPath(st, path, value, meta, writeStamp) {
|
|
3818
4156
|
if (st.effectiveDisabled.value) {
|
|
3819
4157
|
if (!st.warnedDisabledWrite) {
|
|
3820
4158
|
st.warnedDisabledWrite = true;
|
|
@@ -3893,7 +4231,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3893
4231
|
value,
|
|
3894
4232
|
variantDefault,
|
|
3895
4233
|
void 0,
|
|
3896
|
-
meta
|
|
4234
|
+
meta,
|
|
4235
|
+
writeStamp
|
|
3897
4236
|
);
|
|
3898
4237
|
}
|
|
3899
4238
|
return reshapeUnionVariant(
|
|
@@ -3903,7 +4242,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3903
4242
|
value,
|
|
3904
4243
|
{ [last]: value },
|
|
3905
4244
|
void 0,
|
|
3906
|
-
meta
|
|
4245
|
+
meta,
|
|
4246
|
+
writeStamp
|
|
3907
4247
|
);
|
|
3908
4248
|
}
|
|
3909
4249
|
}
|
|
@@ -3927,7 +4267,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3927
4267
|
discValue,
|
|
3928
4268
|
variantDefault,
|
|
3929
4269
|
valueRecord,
|
|
3930
|
-
meta
|
|
4270
|
+
meta,
|
|
4271
|
+
writeStamp
|
|
3931
4272
|
);
|
|
3932
4273
|
}
|
|
3933
4274
|
return reshapeUnionVariant(
|
|
@@ -3937,10 +4278,20 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3937
4278
|
discValue,
|
|
3938
4279
|
{ [discKey]: discValue },
|
|
3939
4280
|
void 0,
|
|
3940
|
-
meta
|
|
4281
|
+
meta,
|
|
4282
|
+
writeStamp
|
|
3941
4283
|
);
|
|
3942
4284
|
}
|
|
3943
|
-
return reshapeUnionVariant(
|
|
4285
|
+
return reshapeUnionVariant(
|
|
4286
|
+
st,
|
|
4287
|
+
path,
|
|
4288
|
+
oldDiscValue,
|
|
4289
|
+
void 0,
|
|
4290
|
+
{},
|
|
4291
|
+
void 0,
|
|
4292
|
+
meta,
|
|
4293
|
+
writeStamp
|
|
4294
|
+
);
|
|
3944
4295
|
}
|
|
3945
4296
|
}
|
|
3946
4297
|
}
|
|
@@ -3990,16 +4341,17 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3990
4341
|
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3991
4342
|
st.arrayIdentity.realign(path);
|
|
3992
4343
|
}
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
st
|
|
3996
|
-
|
|
4344
|
+
const now = writeStamp ?? writeInstant(st);
|
|
4345
|
+
applyTargetedWrite(
|
|
4346
|
+
st,
|
|
4347
|
+
path,
|
|
4348
|
+
completedValue,
|
|
4349
|
+
meta,
|
|
4350
|
+
arrayOpRemap !== null ? { path, remap: arrayOpRemap } : null,
|
|
4351
|
+
now
|
|
4352
|
+
);
|
|
4353
|
+
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3997
4354
|
st.variantMemory.clearUnderPath(path);
|
|
3998
|
-
st.arrayIdentity.realign(path);
|
|
3999
|
-
} else if (isContainer(currentValue) && !isContainer(value)) {
|
|
4000
|
-
if (subtreeHadRealBaseline(st, path, currentValue)) {
|
|
4001
|
-
st.removedSubtrees.add(pathKey);
|
|
4002
|
-
}
|
|
4003
4355
|
}
|
|
4004
4356
|
const effectiveModeAfterWrite = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
4005
4357
|
if (effectiveModeAfterWrite === "change") {
|
|
@@ -4007,7 +4359,7 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
4007
4359
|
}
|
|
4008
4360
|
return true;
|
|
4009
4361
|
}
|
|
4010
|
-
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta) {
|
|
4362
|
+
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta, writeStamp) {
|
|
4011
4363
|
const sameDisc = Object.is(oldDiscValue, newDiscValue);
|
|
4012
4364
|
const parentKey = canonicalizePath(parentPath).key;
|
|
4013
4365
|
let baseline = variantDefault;
|
|
@@ -4073,7 +4425,7 @@ function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variant
|
|
|
4073
4425
|
appliedSync = true;
|
|
4074
4426
|
}
|
|
4075
4427
|
}
|
|
4076
|
-
|
|
4428
|
+
applyFormReplacementWithPath(st, nextForm, meta, null, writeStamp ?? writeInstant(st));
|
|
4077
4429
|
for (const k of newBlankPaths) st.blankPaths.add(k);
|
|
4078
4430
|
if (reshapeMode === "change" && !appliedSync) {
|
|
4079
4431
|
scheduleFieldValidation(st, parentPath, false, meta?.instance);
|
|
@@ -4094,7 +4446,9 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4094
4446
|
aborted: false,
|
|
4095
4447
|
timer: null,
|
|
4096
4448
|
settled: false,
|
|
4097
|
-
released: false
|
|
4449
|
+
released: false,
|
|
4450
|
+
key,
|
|
4451
|
+
path
|
|
4098
4452
|
};
|
|
4099
4453
|
st.fieldValidationState.set(key, fresh);
|
|
4100
4454
|
const myEpoch = ++st.scheduleEpoch;
|
|
@@ -4105,19 +4459,20 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4105
4459
|
try {
|
|
4106
4460
|
st.activeValidations.value += 1;
|
|
4107
4461
|
activeIncremented = true;
|
|
4108
|
-
incFieldValidation(st, key);
|
|
4462
|
+
incFieldValidation(st, fresh.key);
|
|
4109
4463
|
} catch (err) {
|
|
4110
4464
|
if (activeIncremented) {
|
|
4111
4465
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
4112
4466
|
}
|
|
4113
4467
|
throw err;
|
|
4114
4468
|
}
|
|
4115
|
-
const
|
|
4116
|
-
const
|
|
4117
|
-
const dataAtScope = subtreeScope ? getAtPath(st.form.value,
|
|
4118
|
-
|
|
4119
|
-
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, scopePath)).then((response) => {
|
|
4469
|
+
const startPath = fresh.path;
|
|
4470
|
+
const subtreeScope = startPath.length > 0 && st.schema.hasContainerOrRootRefine?.() === false;
|
|
4471
|
+
const dataAtScope = subtreeScope ? getAtPath(st.form.value, startPath) : st.form.value;
|
|
4472
|
+
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, subtreeScope ? startPath : void 0)).then((response) => {
|
|
4120
4473
|
if (fresh.aborted) return;
|
|
4474
|
+
const scopePath = subtreeScope ? fresh.path : void 0;
|
|
4475
|
+
const scopeKey = subtreeScope ? fresh.key : ROOT_PATH_KEY;
|
|
4121
4476
|
if (myEpoch <= st.lastCommittedEpoch) return;
|
|
4122
4477
|
st.lastCommittedEpoch = myEpoch;
|
|
4123
4478
|
if (effectiveMode === "blur") {
|
|
@@ -4128,14 +4483,14 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4128
4483
|
const filtered = filterAuthoredErrors(st, errors);
|
|
4129
4484
|
const restamped = subtreeScope ? filtered.map((err) => ({
|
|
4130
4485
|
...err,
|
|
4131
|
-
path: [...
|
|
4486
|
+
path: [...scopePath ?? [], ...err.path]
|
|
4132
4487
|
})) : filtered;
|
|
4133
4488
|
applySchemaErrorsForSubtree(st, scopePath ?? [], restamped);
|
|
4134
4489
|
}).catch(() => {
|
|
4135
4490
|
}).finally(() => {
|
|
4136
4491
|
if (!fresh.released) {
|
|
4137
4492
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
4138
|
-
decFieldValidation(st, key);
|
|
4493
|
+
decFieldValidation(st, fresh.key);
|
|
4139
4494
|
}
|
|
4140
4495
|
fresh.settled = true;
|
|
4141
4496
|
});
|
|
@@ -4174,6 +4529,19 @@ function cancelFieldValidationUnder(st, prefix) {
|
|
|
4174
4529
|
st.fieldValidationState.delete(key);
|
|
4175
4530
|
}
|
|
4176
4531
|
}
|
|
4532
|
+
function abortValidationAt(st, key) {
|
|
4533
|
+
const entry = st.fieldValidationState.get(key);
|
|
4534
|
+
if (entry === void 0) return;
|
|
4535
|
+
if (entry.timer !== null) {
|
|
4536
|
+
clearTimeout(entry.timer);
|
|
4537
|
+
} else if (!entry.settled && !entry.released) {
|
|
4538
|
+
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
4539
|
+
decFieldValidation(st, key);
|
|
4540
|
+
entry.released = true;
|
|
4541
|
+
}
|
|
4542
|
+
entry.aborted = true;
|
|
4543
|
+
st.fieldValidationState.delete(key);
|
|
4544
|
+
}
|
|
4177
4545
|
function onFormChange(st, listener) {
|
|
4178
4546
|
st.formChangeListeners.add(listener);
|
|
4179
4547
|
return () => {
|
|
@@ -4301,6 +4669,36 @@ function restoreErrorCells(st, entries) {
|
|
|
4301
4669
|
st.errorCells().set(key, { schema: [...cell.schema], user: [...cell.user] });
|
|
4302
4670
|
}
|
|
4303
4671
|
}
|
|
4672
|
+
function captureStructure(st) {
|
|
4673
|
+
return {
|
|
4674
|
+
identity: st.arrayIdentity.snapshot(),
|
|
4675
|
+
originals: [...toRaw(st.originals)],
|
|
4676
|
+
originalBlank: [...st.originalBlankPaths],
|
|
4677
|
+
removed: [...st.removedPaths]
|
|
4678
|
+
};
|
|
4679
|
+
}
|
|
4680
|
+
function restoreStructure(st, snapshot) {
|
|
4681
|
+
const originals = new Map(snapshot.originals);
|
|
4682
|
+
const raw = toRaw(st.form.value);
|
|
4683
|
+
const held = /* @__PURE__ */ new Map();
|
|
4684
|
+
for (const [key, { segments }] of toRaw(st.originals)) {
|
|
4685
|
+
if (!originals.has(key) && hasAtPath(raw, segments)) {
|
|
4686
|
+
noteHold(st, held, raw, segments, segments.length - 1, segments);
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
applyHolds(st, held);
|
|
4690
|
+
st.arrayIdentity.restore(snapshot.identity);
|
|
4691
|
+
replaceOriginals(st, originals);
|
|
4692
|
+
st.originalBlankPaths.clear();
|
|
4693
|
+
for (const key of snapshot.originalBlank) st.originalBlankPaths.add(key);
|
|
4694
|
+
const pulsed = [...st.removedPaths.values()];
|
|
4695
|
+
st.removedPaths.clear();
|
|
4696
|
+
for (const [key, segments] of snapshot.removed) {
|
|
4697
|
+
st.removedPaths.set(key, segments);
|
|
4698
|
+
pulsed.push(segments);
|
|
4699
|
+
}
|
|
4700
|
+
if (pulsed.length > 0) pulseStructure(st.structureSignal, pulsed);
|
|
4701
|
+
}
|
|
4304
4702
|
function getErrorsForPath(st, path) {
|
|
4305
4703
|
const { key } = canonicalizePath(path);
|
|
4306
4704
|
const cell = st.errorCells().get(key);
|
|
@@ -4325,6 +4723,7 @@ function noteDomConnected(st, path) {
|
|
|
4325
4723
|
}
|
|
4326
4724
|
function noteDomDisconnected(st, path) {
|
|
4327
4725
|
const { key } = canonicalizePath(path);
|
|
4726
|
+
if (!st.fields.has(key)) return;
|
|
4328
4727
|
touchFieldRecord(st, key, path, { connected: false, focused: null, blurred: null });
|
|
4329
4728
|
}
|
|
4330
4729
|
function markConnectedOptimistically(st, path) {
|
|
@@ -4388,7 +4787,7 @@ function touchAtPath(st, segments) {
|
|
|
4388
4787
|
const formValue = st.form.value;
|
|
4389
4788
|
let touchedAny = false;
|
|
4390
4789
|
for (const [leafKey, entry] of st.originals) {
|
|
4391
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
4790
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4392
4791
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4393
4792
|
touchedAny = true;
|
|
4394
4793
|
const current = st.fields.get(leafKey);
|
|
@@ -4406,7 +4805,7 @@ function interactAtPath(st, segments) {
|
|
|
4406
4805
|
const formValue = st.form.value;
|
|
4407
4806
|
let interactedAny = false;
|
|
4408
4807
|
for (const [leafKey, entry] of st.originals) {
|
|
4409
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
4808
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4410
4809
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4411
4810
|
interactedAny = true;
|
|
4412
4811
|
const current = st.fields.get(leafKey);
|
|
@@ -4487,15 +4886,20 @@ function reset(st, nextDefaultValues) {
|
|
|
4487
4886
|
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4488
4887
|
);
|
|
4489
4888
|
rebuildAuthoredPaths(st, resetSource, next);
|
|
4490
|
-
applyFormReplacement(st, next);
|
|
4491
|
-
st.arrayIdentity.rebaselineAll();
|
|
4492
|
-
st.removedSubtrees.clear();
|
|
4493
|
-
seedOriginalsFromBaseline(st, next);
|
|
4494
4889
|
if (nextDefaultValues !== void 0) {
|
|
4495
4890
|
const mentioned = /* @__PURE__ */ new Set();
|
|
4496
4891
|
walkAuthoredFromConstraints(nextDefaultValues, [], mentioned);
|
|
4497
4892
|
for (const key of mentioned) st.originalBlankPaths.delete(key);
|
|
4498
4893
|
}
|
|
4894
|
+
const now = writeInstant(st);
|
|
4895
|
+
applyFormReplacementWithPath(st, next, void 0, null, now);
|
|
4896
|
+
st.arrayIdentity.rebaselineAll();
|
|
4897
|
+
if (st.removedPaths.size > 0) {
|
|
4898
|
+
const cleared = [...st.removedPaths.values()];
|
|
4899
|
+
st.removedPaths.clear();
|
|
4900
|
+
pulseStructure(st.structureSignal, cleared);
|
|
4901
|
+
}
|
|
4902
|
+
seedOriginalsFromBaseline(st, next);
|
|
4499
4903
|
st.blankPaths.clear();
|
|
4500
4904
|
for (const key of st.originalBlankPaths) {
|
|
4501
4905
|
st.blankPaths.add(key);
|
|
@@ -4504,7 +4908,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4504
4908
|
replaceErrorChannel(st, "schema", st.schema.validateSync(next));
|
|
4505
4909
|
st.firstValidationDone.value = initialFirstValidationGate(st.schema);
|
|
4506
4910
|
queueInitialAsyncValidation(st);
|
|
4507
|
-
|
|
4911
|
+
noteStamp(st, now);
|
|
4508
4912
|
for (const [pathKey, record] of st.fields) {
|
|
4509
4913
|
st.fields.set(pathKey, withClearedHistoryFlags(record, now));
|
|
4510
4914
|
}
|
|
@@ -4533,6 +4937,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4533
4937
|
}
|
|
4534
4938
|
function resetField(st, path) {
|
|
4535
4939
|
const { key: targetKey, segments: targetSegments } = canonicalizePath(path);
|
|
4940
|
+
const now = writeInstant(st);
|
|
4536
4941
|
st.variantMemory.clearUnderPath(targetSegments);
|
|
4537
4942
|
cancelFieldValidationUnder(st, targetSegments);
|
|
4538
4943
|
cancelTransformsUnder(st, targetSegments);
|
|
@@ -4541,9 +4946,21 @@ function resetField(st, path) {
|
|
|
4541
4946
|
if (segs === null) continue;
|
|
4542
4947
|
if (isPathPrefix(targetSegments, segs)) st.pathSnapshots.delete(snapKey);
|
|
4543
4948
|
}
|
|
4949
|
+
const cleared = [];
|
|
4950
|
+
for (const [fieldKey, record] of Array.from(st.fields.entries())) {
|
|
4951
|
+
if (!isPathPrefix(targetSegments, record.path)) continue;
|
|
4952
|
+
st.fields.set(fieldKey, withClearedHistoryFlags(record, record.updatedAt));
|
|
4953
|
+
cleared.push(fieldKey);
|
|
4954
|
+
}
|
|
4544
4955
|
const leafEntry = st.originals.get(targetKey);
|
|
4545
4956
|
if (leafEntry !== void 0) {
|
|
4546
|
-
const wrote = setValueAtPath(
|
|
4957
|
+
const wrote = setValueAtPath(
|
|
4958
|
+
st,
|
|
4959
|
+
targetSegments,
|
|
4960
|
+
structuralSnapshot(leafEntry.value),
|
|
4961
|
+
void 0,
|
|
4962
|
+
now
|
|
4963
|
+
);
|
|
4547
4964
|
if (!wrote) {
|
|
4548
4965
|
console.error(
|
|
4549
4966
|
`[attaform] resetField: leaf write rejected for path '${targetKey}'. Originals contain a value that doesn't satisfy the slim primitive shape. This is a bug in the construction pipeline.`
|
|
@@ -4561,10 +4978,10 @@ function resetField(st, path) {
|
|
|
4561
4978
|
if (subtree === void 0) {
|
|
4562
4979
|
subtree = typeof relative[0] === "number" ? [] : {};
|
|
4563
4980
|
}
|
|
4564
|
-
subtree = setAtPath(subtree, relative, entry.value);
|
|
4981
|
+
subtree = setAtPath(subtree, relative, structuralSnapshot(entry.value));
|
|
4565
4982
|
}
|
|
4566
4983
|
if (anyMatch) {
|
|
4567
|
-
const wroteSubtree = setValueAtPath(st, targetSegments, subtree);
|
|
4984
|
+
const wroteSubtree = setValueAtPath(st, targetSegments, subtree, void 0, now);
|
|
4568
4985
|
if (!wroteSubtree) {
|
|
4569
4986
|
console.error(
|
|
4570
4987
|
`[attaform] resetField: subtree write rejected at path '${targetKey}'. Originals contain values that don't satisfy the slim primitive shape. This is a bug in the construction pipeline.`
|
|
@@ -4573,8 +4990,14 @@ function resetField(st, path) {
|
|
|
4573
4990
|
}
|
|
4574
4991
|
}
|
|
4575
4992
|
deleteErrorCellsUnderPrefix(st, targetSegments);
|
|
4576
|
-
|
|
4577
|
-
|
|
4993
|
+
const raw = toRaw(st.form.value);
|
|
4994
|
+
for (const fieldKey of cleared) {
|
|
4995
|
+
const record = st.fields.get(fieldKey);
|
|
4996
|
+
if (record === void 0 || !hasAtPath(raw, record.path)) continue;
|
|
4997
|
+
raiseStamp(st, fieldKey, record.path, now);
|
|
4998
|
+
}
|
|
4999
|
+
if (cleared.length > 0 && hasAtPath(raw, targetSegments)) {
|
|
5000
|
+
stampContainers(st, [targetSegments], now);
|
|
4578
5001
|
}
|
|
4579
5002
|
}
|
|
4580
5003
|
function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
@@ -4587,36 +5010,35 @@ function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
|
4587
5010
|
}
|
|
4588
5011
|
}
|
|
4589
5012
|
}
|
|
4590
|
-
function clearFieldRecordFlags(st, pathKey) {
|
|
4591
|
-
const record = st.fields.get(pathKey);
|
|
4592
|
-
if (record === void 0) return;
|
|
4593
|
-
st.fields.set(pathKey, withClearedHistoryFlags(record, (/* @__PURE__ */ new Date()).toISOString()));
|
|
4594
|
-
}
|
|
4595
5013
|
function isPristineAtPathByKey(st, key, segments) {
|
|
4596
5014
|
if (st.blankPaths.has(key) !== st.originalBlankPaths.has(key)) return false;
|
|
4597
5015
|
const entry = st.originals.get(key);
|
|
4598
5016
|
if (entry === void 0) return true;
|
|
4599
5017
|
return Object.is(getAtPath(st.form.value, segments), entry.value);
|
|
4600
5018
|
}
|
|
4601
|
-
function hasStructuralChangeUnder(st, path) {
|
|
5019
|
+
function hasStructuralChangeUnder(st, path, key) {
|
|
5020
|
+
subscribeStructure(st.structureSignal, key);
|
|
4602
5021
|
return st.arrayIdentity.hasStructuralChangeUnder(path);
|
|
4603
5022
|
}
|
|
4604
|
-
function
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
5023
|
+
function pulseStructure(signal, paths) {
|
|
5024
|
+
const keys = signal.keys;
|
|
5025
|
+
if (keys === null) return;
|
|
5026
|
+
eachAncestorOnce(paths, (key) => {
|
|
5027
|
+
keys.add(key);
|
|
5028
|
+
keys.delete(key);
|
|
4610
5029
|
});
|
|
4611
|
-
return had;
|
|
4612
5030
|
}
|
|
4613
|
-
function
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
5031
|
+
function subscribeStructure(signal, key) {
|
|
5032
|
+
signal.keys ?? (signal.keys = shallowReactive(/* @__PURE__ */ new Set()));
|
|
5033
|
+
void signal.keys.has(key);
|
|
5034
|
+
}
|
|
5035
|
+
function hasRemovedSubtreeUnder(st, prefix, key) {
|
|
5036
|
+
subscribeStructure(st.structureSignal, key);
|
|
5037
|
+
if (st.removedPaths.size === 0) return false;
|
|
5038
|
+
const raw = toRaw(st.form.value);
|
|
5039
|
+
for (const segments of st.removedPaths.values()) {
|
|
4618
5040
|
if (!isPathPrefix(prefix, segments)) continue;
|
|
4619
|
-
if (
|
|
5041
|
+
if (hasAtPath(raw, segments)) continue;
|
|
4620
5042
|
return true;
|
|
4621
5043
|
}
|
|
4622
5044
|
return false;
|
|
@@ -4652,10 +5074,14 @@ function createFormStore(options) {
|
|
|
4652
5074
|
warn: true
|
|
4653
5075
|
}) : initialData;
|
|
4654
5076
|
const form = ref(stubbedInitialData);
|
|
4655
|
-
const
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
5077
|
+
const structureSignal = { keys: null };
|
|
5078
|
+
const arrayIdentity = createArrayIdentity(
|
|
5079
|
+
(arraySegs) => {
|
|
5080
|
+
const v = getAtPath(toRaw(form.value), arraySegs);
|
|
5081
|
+
return Array.isArray(v) ? v.length : 0;
|
|
5082
|
+
},
|
|
5083
|
+
(arrayPaths) => pulseStructure(structureSignal, arrayPaths)
|
|
5084
|
+
);
|
|
4659
5085
|
const fields = shallowReactive(/* @__PURE__ */ new Map());
|
|
4660
5086
|
const domBinding = shallowRef(null);
|
|
4661
5087
|
const errorStore = createErrorCells(
|
|
@@ -4664,7 +5090,7 @@ function createFormStore(options) {
|
|
|
4664
5090
|
);
|
|
4665
5091
|
const errorCells = () => errorStore(true);
|
|
4666
5092
|
const originals = shallowReactive(/* @__PURE__ */ new Map());
|
|
4667
|
-
const
|
|
5093
|
+
const removedPaths = /* @__PURE__ */ new Map();
|
|
4668
5094
|
const blankPaths = reactive(/* @__PURE__ */ new Set());
|
|
4669
5095
|
const originalBlankPaths = /* @__PURE__ */ new Set();
|
|
4670
5096
|
const seededBlankPaths = hydration !== void 0 ? (hydration.blankPaths ?? []).map((dotted) => canonicalizePath(dotted).key) : options.initialBlankPaths ?? [];
|
|
@@ -4773,6 +5199,8 @@ function createFormStore(options) {
|
|
|
4773
5199
|
blankPaths,
|
|
4774
5200
|
originalBlankPaths,
|
|
4775
5201
|
authoredPaths,
|
|
5202
|
+
removedPaths,
|
|
5203
|
+
notifyStructure: (paths) => pulseStructure(structureSignal, paths),
|
|
4776
5204
|
fieldValidationCounts,
|
|
4777
5205
|
fieldValidatingSince,
|
|
4778
5206
|
fieldValidationState,
|
|
@@ -4780,6 +5208,9 @@ function createFormStore(options) {
|
|
|
4780
5208
|
arrayIdentity,
|
|
4781
5209
|
variantMemory,
|
|
4782
5210
|
touchFieldRecord: (pathKey, path, patch) => touchFieldRecord(st, pathKey, path, patch),
|
|
5211
|
+
stampContainers: (containers, now) => stampContainers(st, containers, now),
|
|
5212
|
+
stampBareContainers: (patches, bare, now) => stampBareContainers(st, patches, bare, now),
|
|
5213
|
+
foldInteractionHistory: (path, released) => foldInteractionHistory(st, path, released),
|
|
4783
5214
|
decFieldValidation: (key) => decFieldValidation(st, key)
|
|
4784
5215
|
});
|
|
4785
5216
|
const bind = (fn) => (...args) => fn(st, ...args);
|
|
@@ -4843,7 +5274,8 @@ function createFormStore(options) {
|
|
|
4843
5274
|
cleanupHooks,
|
|
4844
5275
|
authoredPaths,
|
|
4845
5276
|
arrayIdentity,
|
|
4846
|
-
|
|
5277
|
+
removedPaths,
|
|
5278
|
+
structureSignal,
|
|
4847
5279
|
variantMemory,
|
|
4848
5280
|
pathOrdinals,
|
|
4849
5281
|
pathSnapshots,
|
|
@@ -4853,6 +5285,7 @@ function createFormStore(options) {
|
|
|
4853
5285
|
arrayBookkeeping,
|
|
4854
5286
|
skipErrorSeed: () => errorStore(false),
|
|
4855
5287
|
nextOrdinal: 0,
|
|
5288
|
+
latestStamp: "",
|
|
4856
5289
|
scheduleEpoch: 0,
|
|
4857
5290
|
lastCommittedEpoch: 0,
|
|
4858
5291
|
transformTokenSeq: 0,
|
|
@@ -4890,6 +5323,8 @@ function createFormStore(options) {
|
|
|
4890
5323
|
),
|
|
4891
5324
|
clearUserErrors: (path) => clearErrorChannel(st, "user", path),
|
|
4892
5325
|
restoreErrorCells: bind(restoreErrorCells),
|
|
5326
|
+
captureStructure: bind(captureStructure),
|
|
5327
|
+
restoreStructure: bind(restoreStructure),
|
|
4893
5328
|
getErrorsForPath: bind(getErrorsForPath),
|
|
4894
5329
|
ensurePathOrdinal: bind(ensurePathOrdinal),
|
|
4895
5330
|
noteDomConnected: bind(noteDomConnected),
|
|
@@ -4923,7 +5358,7 @@ function createFormStore(options) {
|
|
|
4923
5358
|
diffAndApply({}, schemaInitialData, [], (patch) => {
|
|
4924
5359
|
if (patch.kind !== "added") return;
|
|
4925
5360
|
const { key } = canonicalizePath(patch.path);
|
|
4926
|
-
originals
|
|
5361
|
+
if (seedBaseline(originals, key, patch)) return;
|
|
4927
5362
|
ensurePathOrdinal(st, key);
|
|
4928
5363
|
if (hydration === void 0) {
|
|
4929
5364
|
fields.set(key, {
|
|
@@ -4938,6 +5373,7 @@ function createFormStore(options) {
|
|
|
4938
5373
|
});
|
|
4939
5374
|
}
|
|
4940
5375
|
});
|
|
5376
|
+
if (fields.size > 0) noteStamp(st, initStamp);
|
|
4941
5377
|
if (hydration !== void 0) {
|
|
4942
5378
|
for (const [rawKey, record] of hydration.fields) {
|
|
4943
5379
|
if (typeof rawKey !== "string" || !isHydratedFieldRecord(record)) {
|
|
@@ -4945,6 +5381,7 @@ function createFormStore(options) {
|
|
|
4945
5381
|
continue;
|
|
4946
5382
|
}
|
|
4947
5383
|
fields.set(rawKey, record);
|
|
5384
|
+
noteStamp(st, record.updatedAt);
|
|
4948
5385
|
}
|
|
4949
5386
|
for (const [rawKey, errs] of hydration.schemaErrors) {
|
|
4950
5387
|
if (typeof rawKey !== "string" || !isHydratedValidationErrorArray(errs)) {
|
|
@@ -5522,7 +5959,7 @@ function buildWizardStatusesProxy(statuses) {
|
|
|
5522
5959
|
// resolves to `undefined` (consistent with property-access).
|
|
5523
5960
|
resolveCall: (arg) => statuses[String(arg)]?.value,
|
|
5524
5961
|
ownKeys: () => Object.keys(statuses),
|
|
5525
|
-
hasKey: (key) =>
|
|
5962
|
+
hasKey: (key) => safeOwnHas(statuses, key)
|
|
5526
5963
|
});
|
|
5527
5964
|
}
|
|
5528
5965
|
|