attaform 0.31.0 → 0.31.2
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 +5 -4
- package/dist/dev/abstract.mjs +5 -4
- package/dist/dev/chunks/devtools.mjs +1 -1
- package/dist/dev/directive.mjs +1 -1
- package/dist/dev/history.mjs +126 -6
- package/dist/dev/index.mjs +6 -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.CtyqGia7.mjs → attaform-dev.BKWPjEB2.mjs} +5 -4
- package/dist/dev/shared/{attaform-dev.DlaT4xGd.mjs → attaform-dev.BnLLxX2l.mjs} +4 -4
- 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.CKSqs_xQ.mjs} +3 -2
- package/dist/dev/shared/{attaform-dev.DJ3nsWw6.mjs → attaform-dev.Cf_hZfbT.mjs} +18 -9
- package/dist/dev/shared/{attaform-dev.y9x9Vp9F.mjs → attaform-dev.DLk51W7-.mjs} +565 -926
- package/dist/dev/shared/attaform-dev.DoG8mZTq.mjs +127 -0
- package/dist/dev/shared/attaform-dev.G-3XDl9F.mjs +1192 -0
- package/dist/dev/shared/{attaform-dev.Caibt7sb.mjs → attaform-dev.oguHqv1W.mjs} +11 -10
- package/dist/dev/zod-v3.mjs +7 -6
- package/dist/dev/zod-v4.mjs +7 -6
- package/dist/dev/zod.mjs +6 -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 +126 -6
- package/dist/index.d.mts +16 -55
- package/dist/index.mjs +6 -5
- package/dist/runtime/plugins/attaform.mjs +1 -1
- package/dist/shared/{attaform.DL2nl_QR.mjs → attaform.3kV6PqVJ.mjs} +11 -10
- package/dist/shared/{attaform.L011tHgJ.mjs → attaform.BJeiuJE2.mjs} +4 -4
- package/dist/shared/attaform.BNUhW4qC.mjs +103 -0
- package/dist/shared/{attaform.CdZIEf7_.mjs → attaform.BhtAZysa.mjs} +3 -2
- package/dist/shared/{attaform.BWUn8Kjy.mjs → attaform.BlAmZ-WU.mjs} +18 -9
- package/dist/shared/{attaform.LUPC-2Qg.mjs → attaform.CMzc4bPI.mjs} +5 -4
- package/dist/shared/{attaform.C4shmwyJ.mjs → attaform.CdA9bfRv.mjs} +1 -1
- package/dist/shared/attaform.CgyyJVuq.mjs +1187 -0
- package/dist/shared/{attaform.DAo0QBmS.d.mts → attaform.CibLYe9-.d.mts} +214 -173
- package/dist/shared/{attaform.DNPJPOO7.mjs → attaform.DCUJCKyG.mjs} +562 -925
- package/dist/shared/{attaform.D9RqPgGu.d.mts → attaform.DCyZT7u-.d.mts} +1 -1
- package/dist/shared/{attaform.CRVe8s82.d.mts → attaform.DD0Y8krq.d.mts} +43 -19
- package/dist/shared/{attaform.DxKQsqFZ.mjs → attaform.T0YjhjPU.mjs} +3 -2
- package/dist/shared/{attaform.DZnrDrNb.d.mts → attaform.bI_4nKZp.d.mts} +119 -8
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.mjs +7 -6
- package/dist/zod-v4.d.mts +15 -11
- package/dist/zod-v4.mjs +7 -6
- package/dist/zod.d.mts +4 -4
- package/dist/zod.mjs +6 -5
- package/package.json +2 -1
- package/skills/attaform/SKILL.md +1 -0
- package/dist/dev/shared/attaform-dev.CZz4GYZ6.mjs +0 -386
- package/dist/shared/attaform.8mfKZCwH.mjs +0 -358
|
@@ -1,82 +1,10 @@
|
|
|
1
1
|
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, onBeforeMount, onBeforeUpdate, onMounted, nextTick } from 'vue';
|
|
2
|
-
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.
|
|
3
|
-
import { c as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform.
|
|
2
|
+
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform.CdA9bfRv.mjs';
|
|
3
|
+
import { c as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform.T0YjhjPU.mjs';
|
|
4
4
|
import { R as REGISTER_OWNER_MARKER, b as V_REGISTER_MARKER } from './attaform.KvlEedlF.mjs';
|
|
5
|
-
import {
|
|
6
|
-
import { i as isPathPrefix,
|
|
7
|
-
|
|
8
|
-
const AttaformErrorCode = {
|
|
9
|
-
/** A required field is in the blank set: no value was supplied. */
|
|
10
|
-
NoValueSupplied: "atta:no-value-supplied",
|
|
11
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
12
|
-
AdapterThrew: "atta:adapter-threw",
|
|
13
|
-
/**
|
|
14
|
-
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
15
|
-
* threw (sync or async). The adapter caught the throw and surfaced
|
|
16
|
-
* it as a `ValidationError` at the field path so the form's normal
|
|
17
|
-
* error pipeline handles it instead of leaking as an unhandled
|
|
18
|
-
* rejection or routing through `submitError`.
|
|
19
|
-
*/
|
|
20
|
-
ValidatorThrew: "atta:validator-threw",
|
|
21
|
-
/**
|
|
22
|
-
* A function-form `defaultValues` factory threw or its promise
|
|
23
|
-
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
24
|
-
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
25
|
-
* the standard error pipeline carries the signal. Critical for the
|
|
26
|
-
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
27
|
-
* payload, but `schemaErrors` does, so the client sees the failure
|
|
28
|
-
* after rehydration without an extra channel.
|
|
29
|
-
*/
|
|
30
|
-
HydrationFailed: "atta:hydration-failed",
|
|
31
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
32
|
-
PathNotFound: "atta:path-not-found",
|
|
33
|
-
/**
|
|
34
|
-
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
35
|
-
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
36
|
-
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
37
|
-
* aggregate error pipeline can carry the failure alongside ordinary
|
|
38
|
-
* validation errors. The raw factory error remains on
|
|
39
|
-
* `form.hydrateError` for retry UX.
|
|
40
|
-
*/
|
|
41
|
-
ActivationFailed: "atta:activation-failed",
|
|
42
|
-
/**
|
|
43
|
-
* Default code stamped on a manual error set through `form.setErrors`
|
|
44
|
-
* when the caller omits an explicit `code`. The `setErrors` input is
|
|
45
|
-
* lenient (`code` optional), so this is the fallback that keeps every
|
|
46
|
-
* produced `ValidationError` carrying a stable, branchable identifier.
|
|
47
|
-
* Override it per error by passing your own `code` (`api:…`, `auth:…`).
|
|
48
|
-
*/
|
|
49
|
-
UserError: "atta:user-error",
|
|
50
|
-
/**
|
|
51
|
-
* Stamped on a `ValidationError` synthesized from a throw or rejection
|
|
52
|
-
* out of a `handleSubmit` `onSubmit` callback. The raw error also lands
|
|
53
|
-
* on `form.meta.submitError` (a raw-`Error` inspection channel); this
|
|
54
|
-
* code marks the copy piped into the user-error layer so the failure
|
|
55
|
-
* also surfaces on `form.errors` / `meta.ownErrors` / `firstOwnError`
|
|
56
|
-
* where the UI already reads. A throw carrying its own `path` / `code`
|
|
57
|
-
* keeps them; a bare `Error` or a non-Error throw defaults here at the
|
|
58
|
-
* form-level path `[]`.
|
|
59
|
-
*/
|
|
60
|
-
SubmitError: "atta:submit-error",
|
|
61
|
-
/**
|
|
62
|
-
* Synthesized by `wizard.handleSubmit` when the whole-wizard submit
|
|
63
|
-
* would otherwise succeed but a `gate()` step is still uncleared. A
|
|
64
|
-
* gate clears only on its member form's clean submit (confirmation), so
|
|
65
|
-
* a downstream step that happens to be valid-by-default must not let the
|
|
66
|
-
* wizard finish past an unconfirmed prerequisite. Emitted at the gate
|
|
67
|
-
* form's key (path `[]`) so the aggregate error pipeline routes focus to
|
|
68
|
-
* the gate, and `done` never latches.
|
|
69
|
-
*/
|
|
70
|
-
GateNotCleared: "atta:gate-not-cleared"
|
|
71
|
-
};
|
|
72
|
-
function makeBlankRequiredError(segments) {
|
|
73
|
-
return {
|
|
74
|
-
message: "No value supplied",
|
|
75
|
-
path: [...segments],
|
|
76
|
-
code: AttaformErrorCode.NoValueSupplied
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
const NO_ERRORS = Object.freeze([]);
|
|
5
|
+
import { a as ANONYMOUS_FORM_KEY_PREFIX, g as getAtPath, i as isPlainRecord, h as hasAtPath, b as makeBlankRequiredError, A as AttaformErrorCode, p as pickDefined, c as buildFieldArrayApi, s as structuralSnapshot, n as normalizeNumericOption, d as DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS, e as diffAndApply, f as mergeStructural, N as NO_ERRORS, j as createArrayBookkeeping, k as createVariantMemory, l as createArrayIdentity, o as isDescendable, q as migrateFieldRecords, r as setAtPath, t as remapForOp, u as isBarePatch, v as applyChangedKeys, w as cloneVariantSnapshot, x as setAtPathWithSchemaFill, y as tryInPlaceLeafWrite, R as RESERVED_KEY_PREFIX, z as DEFAULT_MAX_RECURSION_DEPTH, B as ANONYMOUS_WIZARD_KEY_PREFIX } from './attaform.CgyyJVuq.mjs';
|
|
6
|
+
import { e as canonicalizePath, i as isPathPrefix, f as pathsEqual, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, S as SubmitErrorHandlerError, t as toError, j as groupErrorsByKey, s as segmentsForPathKey, n as normalizeErrorInput, h as SET_MEMBER_SEGMENT, R as ROOT_PATH, l as normalizeErrorInputs, a as InvalidUseFormConfigError, d as ReservedFormKeyError } from './attaform.BhtAZysa.mjs';
|
|
7
|
+
import { r as readConsumerIndex, c as consumerKeys, b as readConsumerProp, d as safeOwnHas, i as isShadowedKey, s as safeAssign, a as safeOwnRead, h as callConsumerFn, j as consumerExtensible, k as consumerSymbolKeys } from './attaform.BNUhW4qC.mjs';
|
|
80
8
|
|
|
81
9
|
function isGateOpen(field, formMeta) {
|
|
82
10
|
return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
|
|
@@ -142,7 +70,7 @@ function hashStableString(input, seed = 0) {
|
|
|
142
70
|
const ANON_STEM = "atta";
|
|
143
71
|
function readableFormKeyStem(formKey) {
|
|
144
72
|
if (formKey === "" || formKey.startsWith(ANONYMOUS_FORM_KEY_PREFIX)) return ANON_STEM;
|
|
145
|
-
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|(
|
|
73
|
+
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|([^-])-+$/g, "$1");
|
|
146
74
|
return sanitized === "" ? ANON_STEM : sanitized;
|
|
147
75
|
}
|
|
148
76
|
function fieldIdToken(formInstanceId, pathKey) {
|
|
@@ -176,323 +104,6 @@ function humanize(segment) {
|
|
|
176
104
|
}).join(" ");
|
|
177
105
|
}
|
|
178
106
|
|
|
179
|
-
const NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
|
|
180
|
-
function mapKeyForSegment(map, segment, declared) {
|
|
181
|
-
if (map.has(segment)) return segment;
|
|
182
|
-
if (typeof segment !== "number") return segment;
|
|
183
|
-
const asString = String(segment);
|
|
184
|
-
if (map.has(asString)) return asString;
|
|
185
|
-
return declared === "string" ? asString : segment;
|
|
186
|
-
}
|
|
187
|
-
function isRebuildableContainer(root, segment) {
|
|
188
|
-
if (root === null || root === void 0 || typeof root !== "object") return true;
|
|
189
|
-
return typeof segment === "number" ? Array.isArray(root) : isPlainRecord(root);
|
|
190
|
-
}
|
|
191
|
-
function descendStep(value, segment) {
|
|
192
|
-
if (value === null || value === void 0) return NOT_FOUND;
|
|
193
|
-
if (typeof value !== "object") return NOT_FOUND;
|
|
194
|
-
if (Array.isArray(value)) {
|
|
195
|
-
if (typeof segment !== "number") return NOT_FOUND;
|
|
196
|
-
if (!(segment in value)) return NOT_FOUND;
|
|
197
|
-
return value[segment];
|
|
198
|
-
}
|
|
199
|
-
if (value instanceof Map) {
|
|
200
|
-
const key2 = mapKeyForSegment(value, segment);
|
|
201
|
-
if (!value.has(key2)) return NOT_FOUND;
|
|
202
|
-
return value.get(key2);
|
|
203
|
-
}
|
|
204
|
-
const record = value;
|
|
205
|
-
const key = typeof segment === "number" ? String(segment) : segment;
|
|
206
|
-
if (isShadowedKey(key)) {
|
|
207
|
-
if (!safeOwnHas(record, key)) return NOT_FOUND;
|
|
208
|
-
return safeOwnRead(record, key);
|
|
209
|
-
}
|
|
210
|
-
if (!(key in record)) return NOT_FOUND;
|
|
211
|
-
return record[key];
|
|
212
|
-
}
|
|
213
|
-
function getAtPath(root, path) {
|
|
214
|
-
if (path.length === 0) return root;
|
|
215
|
-
try {
|
|
216
|
-
let current = root;
|
|
217
|
-
for (const segment of path) {
|
|
218
|
-
const next = descendStep(current, segment);
|
|
219
|
-
if (next === NOT_FOUND) return void 0;
|
|
220
|
-
current = next;
|
|
221
|
-
}
|
|
222
|
-
return current;
|
|
223
|
-
} catch {
|
|
224
|
-
return void 0;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
function hasAtPath(root, path) {
|
|
228
|
-
if (path.length === 0) return true;
|
|
229
|
-
try {
|
|
230
|
-
return hasAtPathUnguarded(root, path);
|
|
231
|
-
} catch {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
function hasAtPathUnguarded(root, path) {
|
|
236
|
-
let current = root;
|
|
237
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
238
|
-
const segment = path[i];
|
|
239
|
-
const next = descendStep(current, segment);
|
|
240
|
-
if (next === NOT_FOUND) return false;
|
|
241
|
-
current = next;
|
|
242
|
-
}
|
|
243
|
-
const last = path[path.length - 1];
|
|
244
|
-
if (current === null || current === void 0) return false;
|
|
245
|
-
if (typeof current !== "object") return false;
|
|
246
|
-
if (Array.isArray(current)) {
|
|
247
|
-
return typeof last === "number" && consumerHas(current, last);
|
|
248
|
-
}
|
|
249
|
-
if (current instanceof Map) {
|
|
250
|
-
return current.has(mapKeyForSegment(current, last));
|
|
251
|
-
}
|
|
252
|
-
const key = typeof last === "number" ? String(last) : last;
|
|
253
|
-
if (isShadowedKey(key)) return safeOwnHas(current, key);
|
|
254
|
-
return consumerHas(current, key);
|
|
255
|
-
}
|
|
256
|
-
function isPlainRecord(value) {
|
|
257
|
-
if (value === null || typeof value !== "object") return false;
|
|
258
|
-
if (Array.isArray(value)) return false;
|
|
259
|
-
const proto = Object.getPrototypeOf(value);
|
|
260
|
-
return proto === null || proto === Object.prototype;
|
|
261
|
-
}
|
|
262
|
-
const NO_SCHEMA_DEFAULTS = /* @__PURE__ */ new Set();
|
|
263
|
-
const NO_SCHEMA_FILL = {
|
|
264
|
-
getDefaultAtPath: () => void 0,
|
|
265
|
-
arrayShapeAtPath: () => null,
|
|
266
|
-
getSlimPrimitiveTypesAtPath: () => NO_SCHEMA_DEFAULTS,
|
|
267
|
-
entryKeyKindAtPath: () => void 0
|
|
268
|
-
};
|
|
269
|
-
function setAtPath(root, path, value) {
|
|
270
|
-
return setAtPathWithSchemaFill(root, NO_SCHEMA_FILL, path, value);
|
|
271
|
-
}
|
|
272
|
-
const NO_IN_PLACE = { applied: false };
|
|
273
|
-
function tryInPlaceLeafWrite(root, path, value) {
|
|
274
|
-
if (path.length === 0) return NO_IN_PLACE;
|
|
275
|
-
try {
|
|
276
|
-
return descendAndWrite(root, path, value);
|
|
277
|
-
} catch {
|
|
278
|
-
return NO_IN_PLACE;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
function descendAndWrite(root, path, value) {
|
|
282
|
-
let node = root;
|
|
283
|
-
for (let i = 0; i < path.length; i++) {
|
|
284
|
-
const seg = path[i];
|
|
285
|
-
if (node instanceof Map) return NO_IN_PLACE;
|
|
286
|
-
if (Array.isArray(node)) {
|
|
287
|
-
if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
|
|
288
|
-
} else if (isPlainRecord(node)) {
|
|
289
|
-
if (typeof seg !== "string" || isShadowedKey(seg) || !(seg in node)) return NO_IN_PLACE;
|
|
290
|
-
} else {
|
|
291
|
-
return NO_IN_PLACE;
|
|
292
|
-
}
|
|
293
|
-
const container = node;
|
|
294
|
-
if (i < path.length - 1) {
|
|
295
|
-
node = container[seg];
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
const old = container[seg];
|
|
299
|
-
if (isPlainRecord(old) || Array.isArray(old)) return NO_IN_PLACE;
|
|
300
|
-
container[seg] = value;
|
|
301
|
-
return { applied: true, old };
|
|
302
|
-
}
|
|
303
|
-
return NO_IN_PLACE;
|
|
304
|
-
}
|
|
305
|
-
function mergeStructural(schema, path, consumer, defaultValue = schema.getDefaultAtPath(path)) {
|
|
306
|
-
const scratch = path.slice();
|
|
307
|
-
return mergeStructuralImpl(schema, scratch, consumer, defaultValue);
|
|
308
|
-
}
|
|
309
|
-
function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
|
|
310
|
-
if (consumer === void 0) {
|
|
311
|
-
if (schema.getSlimPrimitiveTypesAtPath(scratch).has("undefined")) {
|
|
312
|
-
return void 0;
|
|
313
|
-
}
|
|
314
|
-
return defaultValue;
|
|
315
|
-
}
|
|
316
|
-
if (consumer === null) return null;
|
|
317
|
-
if (Array.isArray(consumer)) {
|
|
318
|
-
return mergeStructuralArray(schema, scratch, consumer);
|
|
319
|
-
}
|
|
320
|
-
if (consumer instanceof Map) {
|
|
321
|
-
return mergeStructuralMap(schema, scratch, consumer);
|
|
322
|
-
}
|
|
323
|
-
if (isPlainRecord(consumer)) {
|
|
324
|
-
if (!isPlainRecord(defaultValue)) {
|
|
325
|
-
return consumer;
|
|
326
|
-
}
|
|
327
|
-
const out = spreadConsumerRecord(consumer);
|
|
328
|
-
const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
|
|
329
|
-
const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
|
|
330
|
-
return filledAny || recursedAny ? out : consumer;
|
|
331
|
-
}
|
|
332
|
-
return consumer;
|
|
333
|
-
}
|
|
334
|
-
function mergeStructuralMap(schema, scratch, consumer) {
|
|
335
|
-
if (consumer.size === 0) return consumer;
|
|
336
|
-
let entryDefault;
|
|
337
|
-
let entryDefaultRead = false;
|
|
338
|
-
let out = null;
|
|
339
|
-
for (const [key, entry] of consumer) {
|
|
340
|
-
if (typeof key !== "string" && typeof key !== "number") continue;
|
|
341
|
-
scratch.push(key);
|
|
342
|
-
if (!entryDefaultRead) {
|
|
343
|
-
entryDefault = schema.getDefaultAtPath(scratch);
|
|
344
|
-
entryDefaultRead = true;
|
|
345
|
-
}
|
|
346
|
-
const merged = mergeStructuralImpl(schema, scratch, entry, entryDefault);
|
|
347
|
-
scratch.pop();
|
|
348
|
-
if (merged === entry) continue;
|
|
349
|
-
out ?? (out = new Map(consumer));
|
|
350
|
-
out.set(key, merged);
|
|
351
|
-
}
|
|
352
|
-
return out ?? consumer;
|
|
353
|
-
}
|
|
354
|
-
function mergeStructuralArray(schema, scratch, consumer) {
|
|
355
|
-
const shape = schema.arrayShapeAtPath(scratch);
|
|
356
|
-
const isTuple = typeof shape === "number";
|
|
357
|
-
const targetLen = isTuple ? shape : consumer.length;
|
|
358
|
-
let cachedElementDefault;
|
|
359
|
-
let cachedElementDefaultRead = false;
|
|
360
|
-
let mutated = targetLen > consumer.length;
|
|
361
|
-
const out = copyConsumerArray(consumer);
|
|
362
|
-
while (out.length < targetLen) out.push(void 0);
|
|
363
|
-
for (let i = 0; i < targetLen; i++) {
|
|
364
|
-
scratch.push(i);
|
|
365
|
-
let elemDefault;
|
|
366
|
-
if (isTuple) {
|
|
367
|
-
elemDefault = schema.getDefaultAtPath(scratch);
|
|
368
|
-
} else {
|
|
369
|
-
if (!cachedElementDefaultRead) {
|
|
370
|
-
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
371
|
-
cachedElementDefaultRead = true;
|
|
372
|
-
}
|
|
373
|
-
elemDefault = cachedElementDefault;
|
|
374
|
-
}
|
|
375
|
-
const consumerElem = i < consumer.length ? readConsumerIndex(consumer, i) : void 0;
|
|
376
|
-
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
377
|
-
scratch.pop();
|
|
378
|
-
if (merged !== consumerElem) {
|
|
379
|
-
out[i] = merged;
|
|
380
|
-
mutated = true;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return mutated ? out : consumer;
|
|
384
|
-
}
|
|
385
|
-
function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
|
|
386
|
-
let mutated = false;
|
|
387
|
-
for (const key of Object.keys(defaultValue)) {
|
|
388
|
-
if (!safeOwnHas(consumer, key)) {
|
|
389
|
-
const defAtKey = safeOwnRead(defaultValue, key);
|
|
390
|
-
scratch.push(key);
|
|
391
|
-
const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
|
|
392
|
-
scratch.pop();
|
|
393
|
-
if (filled !== void 0) {
|
|
394
|
-
safeAssign(out, key, filled);
|
|
395
|
-
mutated = true;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
return mutated;
|
|
400
|
-
}
|
|
401
|
-
function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
|
|
402
|
-
let mutated = false;
|
|
403
|
-
for (const key of consumerKeys(consumer)) {
|
|
404
|
-
const cVal = safeOwnRead(consumer, key);
|
|
405
|
-
if (cVal === void 0) continue;
|
|
406
|
-
scratch.push(key);
|
|
407
|
-
const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
|
|
408
|
-
scratch.pop();
|
|
409
|
-
if (merged !== cVal) {
|
|
410
|
-
safeAssign(out, key, merged);
|
|
411
|
-
mutated = true;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return mutated;
|
|
415
|
-
}
|
|
416
|
-
function setAtPathWithSchemaFill(root, schema, fullPath, value) {
|
|
417
|
-
if (fullPath.length === 0) return value;
|
|
418
|
-
return setAtPathWithSchemaFillImpl(root, schema, fullPath, value, 0);
|
|
419
|
-
}
|
|
420
|
-
function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
|
|
421
|
-
if (startIdx >= fullPath.length) return value;
|
|
422
|
-
const head = fullPath[startIdx];
|
|
423
|
-
const isLeafStep = startIdx === fullPath.length - 1;
|
|
424
|
-
if (root instanceof Map) {
|
|
425
|
-
const next = new Map(root);
|
|
426
|
-
const key = mapKeyForSegment(root, head, schema.entryKeyKindAtPath(fullPath.slice(0, startIdx)));
|
|
427
|
-
if (isLeafStep) {
|
|
428
|
-
next.set(key, value);
|
|
429
|
-
return next;
|
|
430
|
-
}
|
|
431
|
-
let childRoot2 = next.get(key);
|
|
432
|
-
if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
|
|
433
|
-
childRoot2 = schema.getDefaultAtPath(fullPath.slice(0, startIdx + 1));
|
|
434
|
-
}
|
|
435
|
-
next.set(key, setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1));
|
|
436
|
-
return next;
|
|
437
|
-
}
|
|
438
|
-
if (!isRebuildableContainer(root, head)) return root;
|
|
439
|
-
if (typeof head === "number") {
|
|
440
|
-
const arr = Array.isArray(root) ? [...root] : [];
|
|
441
|
-
const prefix = fullPath.slice(0, startIdx);
|
|
442
|
-
if (arr.length < head) {
|
|
443
|
-
const scratch = prefix.slice();
|
|
444
|
-
const shape = schema.arrayShapeAtPath(scratch);
|
|
445
|
-
const tupleLike = typeof shape === "number";
|
|
446
|
-
let cachedArrayDefault;
|
|
447
|
-
if (!tupleLike) {
|
|
448
|
-
scratch.push(0);
|
|
449
|
-
cachedArrayDefault = schema.getDefaultAtPath(scratch);
|
|
450
|
-
scratch.pop();
|
|
451
|
-
}
|
|
452
|
-
while (arr.length < head) {
|
|
453
|
-
const idx = arr.length;
|
|
454
|
-
if (tupleLike) {
|
|
455
|
-
scratch.push(idx);
|
|
456
|
-
arr.push(schema.getDefaultAtPath(scratch));
|
|
457
|
-
scratch.pop();
|
|
458
|
-
} else {
|
|
459
|
-
arr.push(cachedArrayDefault);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
if (isLeafStep) {
|
|
464
|
-
arr[head] = value;
|
|
465
|
-
return arr;
|
|
466
|
-
}
|
|
467
|
-
let childRoot2 = arr[head];
|
|
468
|
-
if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
|
|
469
|
-
childRoot2 = schema.getDefaultAtPath([...prefix, head]);
|
|
470
|
-
}
|
|
471
|
-
arr[head] = setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1);
|
|
472
|
-
return arr;
|
|
473
|
-
}
|
|
474
|
-
const rec = isPlainRecord(root) ? { ...root } : {};
|
|
475
|
-
if (isLeafStep) {
|
|
476
|
-
safeAssign(rec, head, value);
|
|
477
|
-
return rec;
|
|
478
|
-
}
|
|
479
|
-
const existing = safeOwnRead(rec, head);
|
|
480
|
-
let childRoot;
|
|
481
|
-
if (existing === void 0 || existing !== null && typeof existing !== "object") {
|
|
482
|
-
const intermPath = [...fullPath.slice(0, startIdx + 1)];
|
|
483
|
-
const intermDefault = schema.getDefaultAtPath(intermPath);
|
|
484
|
-
childRoot = intermDefault;
|
|
485
|
-
} else {
|
|
486
|
-
childRoot = existing;
|
|
487
|
-
}
|
|
488
|
-
safeAssign(
|
|
489
|
-
rec,
|
|
490
|
-
head,
|
|
491
|
-
setAtPathWithSchemaFillImpl(childRoot, schema, fullPath, value, startIdx + 1)
|
|
492
|
-
);
|
|
493
|
-
return rec;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
107
|
function isUnderStubAncestor(state, segments) {
|
|
497
108
|
for (let i = 0; i < segments.length; i++) {
|
|
498
109
|
const ancestorPath = segments.slice(0, i);
|
|
@@ -628,7 +239,6 @@ function visitActiveLeafPaths(value, base, visit) {
|
|
|
628
239
|
function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
629
240
|
const formValue = state.form.value;
|
|
630
241
|
const value = getAtPath(formValue, segments);
|
|
631
|
-
const original = state.originals.get(key)?.value;
|
|
632
242
|
let pristine = true;
|
|
633
243
|
let blank = true;
|
|
634
244
|
let dirty = false;
|
|
@@ -646,6 +256,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
646
256
|
let asyncPending = false;
|
|
647
257
|
const submissionAttempts = state.submissionAttempts.value;
|
|
648
258
|
const blurredLeafSegments = [];
|
|
259
|
+
const errorsByKey = errorBucketsAt(state, segments, key);
|
|
649
260
|
const descendantLeaves = [];
|
|
650
261
|
visitActiveLeafPaths(value, segments, (leafSegments) => {
|
|
651
262
|
const { key: leafKey } = keyForSegments(leafSegments);
|
|
@@ -655,6 +266,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
655
266
|
});
|
|
656
267
|
for (const { key: leafKey, segments: leafSeg } of descendantLeaves) {
|
|
657
268
|
const leafRecord = state.fields.get(leafKey);
|
|
269
|
+
const leafErrors = errorsByKey.get(leafKey);
|
|
270
|
+
if (leafErrors !== void 0) leafErrors.walked = true;
|
|
658
271
|
if (!state.isPristineAtPathByKey(leafKey, leafSeg)) {
|
|
659
272
|
pristine = false;
|
|
660
273
|
dirty = true;
|
|
@@ -689,22 +302,28 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
689
302
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
690
303
|
}
|
|
691
304
|
}
|
|
692
|
-
if (!dirty && state.
|
|
305
|
+
if (!dirty && !(Array.isArray(value) || isPlainRecord(value)) && !state.isPristineAtPathByKey(key, segments)) {
|
|
693
306
|
pristine = false;
|
|
694
307
|
dirty = true;
|
|
695
308
|
}
|
|
696
|
-
if (!dirty && state.
|
|
309
|
+
if (!dirty && state.hasStructuralChangeUnder(segments, key)) {
|
|
697
310
|
pristine = false;
|
|
698
311
|
dirty = true;
|
|
699
312
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
313
|
+
if (!dirty && state.hasRemovedSubtreeUnder(segments, key)) {
|
|
314
|
+
pristine = false;
|
|
315
|
+
dirty = true;
|
|
316
|
+
}
|
|
317
|
+
const errorBuckets = sortErrorBuckets(errorsByKey);
|
|
318
|
+
const errors = flattenErrorBuckets(errorBuckets);
|
|
319
|
+
const revealedDescendantError = errors.length > 0 && descendantErrorRevealed(
|
|
320
|
+
state,
|
|
321
|
+
segments,
|
|
322
|
+
errorBuckets,
|
|
323
|
+
submissionAttempts,
|
|
324
|
+
blurredAfterInteraction,
|
|
325
|
+
blurredLeafSegments
|
|
326
|
+
);
|
|
708
327
|
if (!asyncPending && state.pathHasAsyncValidationByKey(key, segments)) asyncPending = true;
|
|
709
328
|
if ((state.fieldValidationCounts.get(key) ?? 0) > 0) {
|
|
710
329
|
validating = true;
|
|
@@ -726,6 +345,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
726
345
|
if (ownRecord.interacted === true) interacted = true;
|
|
727
346
|
if (ownRecord.blurredAfterInteraction === true) blurredAfterInteraction = true;
|
|
728
347
|
if (ownRecord.connected === true) connected = true;
|
|
348
|
+
const ts = ownRecord.updatedAt;
|
|
349
|
+
if (ts !== null && (updatedAt === null || ts > updatedAt)) updatedAt = ts;
|
|
729
350
|
}
|
|
730
351
|
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
731
352
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
@@ -734,7 +355,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
734
355
|
return {
|
|
735
356
|
base: {
|
|
736
357
|
value,
|
|
737
|
-
original,
|
|
358
|
+
original: state.getOriginalAtPath(segments),
|
|
738
359
|
pristine,
|
|
739
360
|
dirty,
|
|
740
361
|
focused,
|
|
@@ -817,9 +438,41 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
817
438
|
firstOwnError
|
|
818
439
|
};
|
|
819
440
|
}
|
|
441
|
+
function descendantErrorRevealed(state, segments, buckets, submissionAttempts, blurredAfterInteraction, blurredLeafSegments) {
|
|
442
|
+
for (const bucket of buckets) {
|
|
443
|
+
let ownHistory;
|
|
444
|
+
for (const e of bucket.errors) {
|
|
445
|
+
const ePath = e.path;
|
|
446
|
+
if (pathsEqual(ePath, segments)) continue;
|
|
447
|
+
if (submissionAttempts > 0) return true;
|
|
448
|
+
if (ePath.length === 1 && ePath[0] === "") {
|
|
449
|
+
if (blurredAfterInteraction) return true;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
for (const leaf of blurredLeafSegments) if (isPathPrefix(ePath, leaf)) return true;
|
|
453
|
+
if (bucket.walked) continue;
|
|
454
|
+
ownHistory ?? (ownHistory = state.fields.get(bucket.key)?.blurredAfterInteraction === true);
|
|
455
|
+
if (ownHistory) return true;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
820
460
|
function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
461
|
+
return flattenErrorBuckets(sortErrorBuckets(errorBucketsAt(state, prefix, prefixKey)));
|
|
462
|
+
}
|
|
463
|
+
const NO_ERROR_BUCKETS = /* @__PURE__ */ new Map();
|
|
464
|
+
function sortErrorBuckets(buckets) {
|
|
465
|
+
if (buckets.size <= 1) return [...buckets.values()];
|
|
466
|
+
return [...buckets.values()].sort((a, b) => a.ordinal - b.ordinal);
|
|
467
|
+
}
|
|
468
|
+
function flattenErrorBuckets(buckets) {
|
|
469
|
+
if (buckets.length === 0) return [];
|
|
470
|
+
if (buckets.length === 1) return buckets[0]?.errors ?? [];
|
|
471
|
+
return buckets.flatMap((bucket) => bucket.errors);
|
|
472
|
+
}
|
|
473
|
+
function errorBucketsAt(state, prefix, prefixKey) {
|
|
821
474
|
const candidates = state.errorWindowAt(prefix, prefixKey);
|
|
822
|
-
if (candidates.length === 0) return
|
|
475
|
+
if (candidates.length === 0) return NO_ERROR_BUCKETS;
|
|
823
476
|
const formValue = state.form.value;
|
|
824
477
|
const cells = state.errorCells();
|
|
825
478
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -832,19 +485,16 @@ function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
|
832
485
|
const userList = cell?.user;
|
|
833
486
|
const total = (schemaList?.length ?? 0) + (blankList?.length ?? 0) + (userList?.length ?? 0);
|
|
834
487
|
if (total === 0) continue;
|
|
835
|
-
|
|
836
|
-
let bucket = buckets.get(ordinal);
|
|
488
|
+
let bucket = buckets.get(key);
|
|
837
489
|
if (bucket === void 0) {
|
|
838
|
-
bucket = [];
|
|
839
|
-
buckets.set(
|
|
490
|
+
bucket = { key, ordinal: state.ensurePathOrdinal(key), errors: [], walked: false };
|
|
491
|
+
buckets.set(key, bucket);
|
|
840
492
|
}
|
|
841
|
-
if (schemaList !== void 0) bucket.push(...schemaList);
|
|
842
|
-
if (blankList !== void 0) bucket.push(...blankList);
|
|
843
|
-
if (userList !== void 0) bucket.push(...userList);
|
|
493
|
+
if (schemaList !== void 0) bucket.errors.push(...schemaList);
|
|
494
|
+
if (blankList !== void 0) bucket.errors.push(...blankList);
|
|
495
|
+
if (userList !== void 0) bucket.errors.push(...userList);
|
|
844
496
|
}
|
|
845
|
-
|
|
846
|
-
if (buckets.size === 1) return [...buckets.values()][0];
|
|
847
|
-
return [...buckets.entries()].sort(([a], [b]) => a - b).flatMap(([, errs]) => errs);
|
|
497
|
+
return buckets;
|
|
848
498
|
}
|
|
849
499
|
const EMPTY_ELEMENTS = Object.freeze([]);
|
|
850
500
|
|
|
@@ -876,7 +526,7 @@ function liveContainerHasKey(state, segments, key) {
|
|
|
876
526
|
return Number.isInteger(index) && index >= 0 && String(index) === key && value.has(index);
|
|
877
527
|
}
|
|
878
528
|
if (value instanceof Set) return false;
|
|
879
|
-
return
|
|
529
|
+
return safeOwnHas(value, key);
|
|
880
530
|
}
|
|
881
531
|
function isArrayPath(state, segments) {
|
|
882
532
|
if (segments.length === 0) return false;
|
|
@@ -1402,406 +1052,6 @@ function buildValuesSurface(form, onFormChange) {
|
|
|
1402
1052
|
});
|
|
1403
1053
|
}
|
|
1404
1054
|
|
|
1405
|
-
function remapForOp(op, oldLen) {
|
|
1406
|
-
const moved = /* @__PURE__ */ new Map();
|
|
1407
|
-
const vacated = /* @__PURE__ */ new Set();
|
|
1408
|
-
const fresh = /* @__PURE__ */ new Set();
|
|
1409
|
-
let newLen = oldLen;
|
|
1410
|
-
switch (op.kind) {
|
|
1411
|
-
case "insert":
|
|
1412
|
-
for (let i = op.index; i < oldLen; i++) moved.set(i, i + 1);
|
|
1413
|
-
fresh.add(op.index);
|
|
1414
|
-
newLen = oldLen + 1;
|
|
1415
|
-
break;
|
|
1416
|
-
case "remove":
|
|
1417
|
-
vacated.add(op.index);
|
|
1418
|
-
for (let i = op.index + 1; i < oldLen; i++) moved.set(i, i - 1);
|
|
1419
|
-
newLen = Math.max(0, oldLen - 1);
|
|
1420
|
-
break;
|
|
1421
|
-
case "move":
|
|
1422
|
-
if (op.from !== op.to) {
|
|
1423
|
-
moved.set(op.from, op.to);
|
|
1424
|
-
if (op.from < op.to) {
|
|
1425
|
-
for (let i = op.from + 1; i <= op.to; i++) moved.set(i, i - 1);
|
|
1426
|
-
} else {
|
|
1427
|
-
for (let i = op.to; i < op.from; i++) moved.set(i, i + 1);
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
break;
|
|
1431
|
-
case "swap":
|
|
1432
|
-
if (op.a !== op.b) {
|
|
1433
|
-
moved.set(op.a, op.b);
|
|
1434
|
-
moved.set(op.b, op.a);
|
|
1435
|
-
}
|
|
1436
|
-
break;
|
|
1437
|
-
case "replace-at":
|
|
1438
|
-
vacated.add(op.index);
|
|
1439
|
-
fresh.add(op.index);
|
|
1440
|
-
break;
|
|
1441
|
-
}
|
|
1442
|
-
return { moved, vacated, fresh, oldLen, newLen };
|
|
1443
|
-
}
|
|
1444
|
-
function changedIndices(remap) {
|
|
1445
|
-
const changed = new Set(remap.vacated);
|
|
1446
|
-
for (const [from, to] of remap.moved) {
|
|
1447
|
-
changed.add(from);
|
|
1448
|
-
changed.add(to);
|
|
1449
|
-
}
|
|
1450
|
-
for (const index of remap.fresh) changed.add(index);
|
|
1451
|
-
return changed;
|
|
1452
|
-
}
|
|
1453
|
-
function permuteList(list, remap, fill) {
|
|
1454
|
-
const claimed = new Array(remap.newLen);
|
|
1455
|
-
for (let i = 0; i < remap.oldLen; i++) {
|
|
1456
|
-
if (remap.vacated.has(i)) continue;
|
|
1457
|
-
const to = remap.moved.get(i) ?? i;
|
|
1458
|
-
if (to < remap.newLen) claimed[to] = list[i];
|
|
1459
|
-
}
|
|
1460
|
-
const next = [];
|
|
1461
|
-
for (let i = 0; i < remap.newLen; i++) {
|
|
1462
|
-
next.push(claimed[i] ?? fill());
|
|
1463
|
-
}
|
|
1464
|
-
return next;
|
|
1465
|
-
}
|
|
1466
|
-
function elementIndexUnder(arrayPath, key, idxPos) {
|
|
1467
|
-
const segments = segmentsForPathKey(key);
|
|
1468
|
-
if (segments === null) return null;
|
|
1469
|
-
if (!isPathPrefix(arrayPath, segments)) return null;
|
|
1470
|
-
if (segments.length <= idxPos) return null;
|
|
1471
|
-
const index = segments[idxPos];
|
|
1472
|
-
return typeof index === "number" ? index : null;
|
|
1473
|
-
}
|
|
1474
|
-
function collectKeysAtIndices(keys, arrayPath, member) {
|
|
1475
|
-
const idxPos = arrayPath.length;
|
|
1476
|
-
const hits = [];
|
|
1477
|
-
for (const key of keys) {
|
|
1478
|
-
const index = elementIndexUnder(arrayPath, key, idxPos);
|
|
1479
|
-
if (index === null || !member(index)) continue;
|
|
1480
|
-
const segments = segmentsForPathKey(key);
|
|
1481
|
-
if (segments === null) continue;
|
|
1482
|
-
hits.push({ key, segments: [...segments], index });
|
|
1483
|
-
}
|
|
1484
|
-
return hits;
|
|
1485
|
-
}
|
|
1486
|
-
function remapAffects(remap) {
|
|
1487
|
-
return (index) => remap.moved.has(index) || remap.vacated.has(index) || remap.fresh.has(index);
|
|
1488
|
-
}
|
|
1489
|
-
function migrateMapSubtree(map, arrayPath, remap, rewriteValue) {
|
|
1490
|
-
const hits = collectKeysAtIndices(map.keys(), arrayPath, remapAffects(remap));
|
|
1491
|
-
if (hits.length === 0) return;
|
|
1492
|
-
const idxPos = arrayPath.length;
|
|
1493
|
-
const snapshots = [];
|
|
1494
|
-
for (const hit of hits) {
|
|
1495
|
-
const value = map.get(hit.key);
|
|
1496
|
-
if (value !== void 0) snapshots.push({ ...hit, value });
|
|
1497
|
-
}
|
|
1498
|
-
for (const snap of snapshots) map.delete(snap.key);
|
|
1499
|
-
for (const snap of snapshots) {
|
|
1500
|
-
const target = remap.moved.get(snap.index);
|
|
1501
|
-
if (target === void 0) continue;
|
|
1502
|
-
const relocated = snap.segments.slice();
|
|
1503
|
-
relocated[idxPos] = target;
|
|
1504
|
-
map.set(canonicalizePath(relocated).key, rewriteValue(snap.value, relocated));
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
function migrateSetSubtree(set, arrayPath, remap) {
|
|
1508
|
-
const hits = collectKeysAtIndices(set, arrayPath, remapAffects(remap));
|
|
1509
|
-
if (hits.length === 0) return;
|
|
1510
|
-
const idxPos = arrayPath.length;
|
|
1511
|
-
for (const hit of hits) set.delete(hit.key);
|
|
1512
|
-
for (const hit of hits) {
|
|
1513
|
-
const target = remap.moved.get(hit.index);
|
|
1514
|
-
if (target === void 0) continue;
|
|
1515
|
-
const relocated = hit.segments.slice();
|
|
1516
|
-
relocated[idxPos] = target;
|
|
1517
|
-
set.add(canonicalizePath(relocated).key);
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
function evictSchemaVerdictsAtIndices(errorCells, arrayPath, indices) {
|
|
1521
|
-
for (const hit of collectKeysAtIndices(
|
|
1522
|
-
[...errorCells.keys()],
|
|
1523
|
-
arrayPath,
|
|
1524
|
-
(index) => indices.has(index)
|
|
1525
|
-
)) {
|
|
1526
|
-
const cell = errorCells.get(hit.key);
|
|
1527
|
-
if (cell === void 0) continue;
|
|
1528
|
-
if (cell.user.length === 0) errorCells.delete(hit.key);
|
|
1529
|
-
else if (cell.schema.length > 0) errorCells.set(hit.key, { schema: NO_ERRORS, user: cell.user });
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
function deleteKeysAtIndices(keys, del, arrayPath, indices) {
|
|
1533
|
-
for (const hit of collectKeysAtIndices(keys, arrayPath, (index) => indices.has(index))) {
|
|
1534
|
-
del(hit.key);
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
function createArrayIdentity(getArrayLength) {
|
|
1538
|
-
const tokens = /* @__PURE__ */ new Map();
|
|
1539
|
-
const baselines = /* @__PURE__ */ new Map();
|
|
1540
|
-
let counter = 0;
|
|
1541
|
-
const allocate = () => `k${(counter++).toString(36)}`;
|
|
1542
|
-
function ensure(arrayKey, expectedLen) {
|
|
1543
|
-
let ids = tokens.get(arrayKey);
|
|
1544
|
-
const firstTrack = ids === void 0;
|
|
1545
|
-
if (ids === void 0) {
|
|
1546
|
-
ids = [];
|
|
1547
|
-
tokens.set(arrayKey, ids);
|
|
1548
|
-
}
|
|
1549
|
-
while (ids.length < expectedLen) ids.push(allocate());
|
|
1550
|
-
if (ids.length > expectedLen) ids.length = expectedLen;
|
|
1551
|
-
if (firstTrack) baselines.set(arrayKey, [...ids]);
|
|
1552
|
-
return ids;
|
|
1553
|
-
}
|
|
1554
|
-
function orderPristineForKey(arrayKey) {
|
|
1555
|
-
const baseline = baselines.get(arrayKey);
|
|
1556
|
-
const current = tokens.get(arrayKey);
|
|
1557
|
-
if (baseline === void 0 || current === void 0) return true;
|
|
1558
|
-
if (baseline.length !== current.length) return false;
|
|
1559
|
-
for (let i = 0; i < current.length; i++) {
|
|
1560
|
-
if (current[i] !== baseline[i]) return false;
|
|
1561
|
-
}
|
|
1562
|
-
return true;
|
|
1563
|
-
}
|
|
1564
|
-
return {
|
|
1565
|
-
tokenAt(arraySegs, index) {
|
|
1566
|
-
const len = getArrayLength(arraySegs);
|
|
1567
|
-
if (index < 0 || index >= len) return "";
|
|
1568
|
-
const ids = ensure(canonicalizePath(arraySegs).key, len);
|
|
1569
|
-
return ids[index] ?? "";
|
|
1570
|
-
},
|
|
1571
|
-
applyOp(arraySegs, remap) {
|
|
1572
|
-
const arrayKey = canonicalizePath(arraySegs).key;
|
|
1573
|
-
const ids = ensure(arrayKey, remap.oldLen);
|
|
1574
|
-
tokens.set(arrayKey, permuteList(ids, remap, allocate));
|
|
1575
|
-
},
|
|
1576
|
-
applyRemap(arrayPath, remap) {
|
|
1577
|
-
if (remap.moved.size === 0 && remap.vacated.size === 0 && remap.fresh.size === 0) return;
|
|
1578
|
-
migrateMapSubtree(tokens, arrayPath, remap, (value) => value);
|
|
1579
|
-
migrateMapSubtree(baselines, arrayPath, remap, (value) => value);
|
|
1580
|
-
},
|
|
1581
|
-
realign(arraySegs) {
|
|
1582
|
-
ensure(canonicalizePath(arraySegs).key, getArrayLength(arraySegs));
|
|
1583
|
-
},
|
|
1584
|
-
hasStructuralChangeUnder(prefix) {
|
|
1585
|
-
for (const arrayKey of tokens.keys()) {
|
|
1586
|
-
if (orderPristineForKey(arrayKey)) continue;
|
|
1587
|
-
const segs = segmentsForPathKey(arrayKey);
|
|
1588
|
-
if (segs === null) continue;
|
|
1589
|
-
if (isPathPrefix(prefix, segs)) return true;
|
|
1590
|
-
}
|
|
1591
|
-
return false;
|
|
1592
|
-
},
|
|
1593
|
-
rebaselineAll() {
|
|
1594
|
-
for (const arrayKey of [...tokens.keys()]) {
|
|
1595
|
-
const segs = segmentsForPathKey(arrayKey);
|
|
1596
|
-
if (segs === null) continue;
|
|
1597
|
-
const ids = ensure(arrayKey, getArrayLength(segs));
|
|
1598
|
-
baselines.set(arrayKey, [...ids]);
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
};
|
|
1602
|
-
}
|
|
1603
|
-
function createVariantMemory() {
|
|
1604
|
-
const memory = /* @__PURE__ */ new Map();
|
|
1605
|
-
return {
|
|
1606
|
-
clear() {
|
|
1607
|
-
memory.clear();
|
|
1608
|
-
},
|
|
1609
|
-
clearUnderPath(parentPath) {
|
|
1610
|
-
for (const memKey of [...memory.keys()]) {
|
|
1611
|
-
const segs = segmentsForPathKey(memKey);
|
|
1612
|
-
if (segs === null) continue;
|
|
1613
|
-
if (isPathPrefix(parentPath, segs)) memory.delete(memKey);
|
|
1614
|
-
}
|
|
1615
|
-
},
|
|
1616
|
-
dropAtIndices(arrayPath, indices) {
|
|
1617
|
-
deleteKeysAtIndices([...memory.keys()], (key) => memory.delete(key), arrayPath, indices);
|
|
1618
|
-
},
|
|
1619
|
-
recordOutgoing(unionKey, discValue, snapshot) {
|
|
1620
|
-
let perUnion = memory.get(unionKey);
|
|
1621
|
-
if (perUnion === void 0) {
|
|
1622
|
-
perUnion = /* @__PURE__ */ new Map();
|
|
1623
|
-
memory.set(unionKey, perUnion);
|
|
1624
|
-
}
|
|
1625
|
-
perUnion.set(discValue, snapshot);
|
|
1626
|
-
},
|
|
1627
|
-
lookupIncoming(unionKey, discValue) {
|
|
1628
|
-
return memory.get(unionKey)?.get(discValue);
|
|
1629
|
-
}
|
|
1630
|
-
};
|
|
1631
|
-
}
|
|
1632
|
-
function cloneVariantSnapshot(value) {
|
|
1633
|
-
if (value === null || typeof value !== "object") return value;
|
|
1634
|
-
const raw = toRaw(value);
|
|
1635
|
-
if (raw instanceof Date) return new Date(raw.getTime());
|
|
1636
|
-
if (raw instanceof Map) {
|
|
1637
|
-
const out2 = /* @__PURE__ */ new Map();
|
|
1638
|
-
for (const [k, v] of raw.entries()) out2.set(cloneVariantSnapshot(k), cloneVariantSnapshot(v));
|
|
1639
|
-
return out2;
|
|
1640
|
-
}
|
|
1641
|
-
if (raw instanceof Set) {
|
|
1642
|
-
const out2 = /* @__PURE__ */ new Set();
|
|
1643
|
-
for (const v of raw) out2.add(cloneVariantSnapshot(v));
|
|
1644
|
-
return out2;
|
|
1645
|
-
}
|
|
1646
|
-
if (raw instanceof RegExp) return new RegExp(raw.source, raw.flags);
|
|
1647
|
-
if (Array.isArray(raw)) {
|
|
1648
|
-
const out2 = new Array(raw.length);
|
|
1649
|
-
for (let i = 0; i < raw.length; i++) out2[i] = cloneVariantSnapshot(raw[i]);
|
|
1650
|
-
return out2;
|
|
1651
|
-
}
|
|
1652
|
-
if (!isPlainRecord(raw)) return raw;
|
|
1653
|
-
const src = raw;
|
|
1654
|
-
const out = {};
|
|
1655
|
-
for (const k of consumerKeys(src)) {
|
|
1656
|
-
safeAssign(out, k, cloneVariantSnapshot(readConsumerProp(src, k)));
|
|
1657
|
-
}
|
|
1658
|
-
return out;
|
|
1659
|
-
}
|
|
1660
|
-
function createArrayBookkeeping(deps) {
|
|
1661
|
-
const {
|
|
1662
|
-
form,
|
|
1663
|
-
fields,
|
|
1664
|
-
errorCells,
|
|
1665
|
-
originals,
|
|
1666
|
-
blankPaths,
|
|
1667
|
-
originalBlankPaths,
|
|
1668
|
-
authoredPaths,
|
|
1669
|
-
fieldValidationCounts,
|
|
1670
|
-
fieldValidatingSince,
|
|
1671
|
-
fieldValidationState,
|
|
1672
|
-
activeValidations,
|
|
1673
|
-
arrayIdentity,
|
|
1674
|
-
variantMemory,
|
|
1675
|
-
touchFieldRecord,
|
|
1676
|
-
decFieldValidation
|
|
1677
|
-
} = deps;
|
|
1678
|
-
function migrateElementState(arrayPath, remap) {
|
|
1679
|
-
if (remap.moved.size === 0 && remap.vacated.size === 0) return;
|
|
1680
|
-
migrateMapSubtree(fields, arrayPath, remap, (record, segments) => ({
|
|
1681
|
-
...record,
|
|
1682
|
-
path: segments
|
|
1683
|
-
}));
|
|
1684
|
-
migrateMapSubtree(errorCells(), arrayPath, remap, (cell, segments) => ({
|
|
1685
|
-
schema: NO_ERRORS,
|
|
1686
|
-
user: cell.user.map((error) => ({ ...error, path: [...segments] }))
|
|
1687
|
-
}));
|
|
1688
|
-
migrateMapSubtree(originals, arrayPath, remap, (record, segments) => ({
|
|
1689
|
-
segments,
|
|
1690
|
-
value: record.value
|
|
1691
|
-
}));
|
|
1692
|
-
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
1693
|
-
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
1694
|
-
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
1695
|
-
migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
|
|
1696
|
-
migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
|
|
1697
|
-
arrayIdentity.applyRemap(arrayPath, remap);
|
|
1698
|
-
}
|
|
1699
|
-
function seedFreshElement(arrayPath, freshIndex) {
|
|
1700
|
-
const elementPath = [...arrayPath, freshIndex];
|
|
1701
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1702
|
-
diffAndApply(void 0, getAtPath(form.value, elementPath), elementPath, (patch) => {
|
|
1703
|
-
if (patch.kind !== "added") return;
|
|
1704
|
-
const { key } = canonicalizePath(patch.path);
|
|
1705
|
-
if (!originals.has(key)) originals.set(key, { segments: patch.path, value: void 0 });
|
|
1706
|
-
touchFieldRecord(key, patch.path, { updatedAt: now });
|
|
1707
|
-
});
|
|
1708
|
-
}
|
|
1709
|
-
function abortValidationAtVacatedIndices(arrayPath, remap) {
|
|
1710
|
-
if (remap.vacated.size === 0) return;
|
|
1711
|
-
const hits = collectKeysAtIndices(
|
|
1712
|
-
[...fieldValidationState.keys()],
|
|
1713
|
-
arrayPath,
|
|
1714
|
-
(index) => remap.vacated.has(index)
|
|
1715
|
-
);
|
|
1716
|
-
for (const hit of hits) {
|
|
1717
|
-
const entry = fieldValidationState.get(hit.key);
|
|
1718
|
-
if (entry === void 0) continue;
|
|
1719
|
-
if (entry.timer !== null) {
|
|
1720
|
-
clearTimeout(entry.timer);
|
|
1721
|
-
} else if (!entry.settled) {
|
|
1722
|
-
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
1723
|
-
decFieldValidation(hit.key);
|
|
1724
|
-
}
|
|
1725
|
-
entry.aborted = true;
|
|
1726
|
-
fieldValidationState.delete(hit.key);
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
return {
|
|
1730
|
-
applyStructuralOp(arrayPath, remap) {
|
|
1731
|
-
migrateElementState(arrayPath, remap);
|
|
1732
|
-
for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex);
|
|
1733
|
-
const changed = changedIndices(remap);
|
|
1734
|
-
evictSchemaVerdictsAtIndices(errorCells(), arrayPath, changed);
|
|
1735
|
-
abortValidationAtVacatedIndices(arrayPath, remap);
|
|
1736
|
-
variantMemory.dropAtIndices(arrayPath, changed);
|
|
1737
|
-
arrayIdentity.applyOp(arrayPath, remap);
|
|
1738
|
-
}
|
|
1739
|
-
};
|
|
1740
|
-
}
|
|
1741
|
-
function buildFieldArrayApi(state) {
|
|
1742
|
-
function readArray(path) {
|
|
1743
|
-
const segments = canonicalizePath(path).segments;
|
|
1744
|
-
const current = state.getValueAtPath(segments);
|
|
1745
|
-
return Array.isArray(current) ? current.slice() : [];
|
|
1746
|
-
}
|
|
1747
|
-
function writeArray(path, next, arrayOp) {
|
|
1748
|
-
const { segments } = canonicalizePath(path);
|
|
1749
|
-
const meta = {
|
|
1750
|
-
...arrayOp !== void 0 ? { arrayOp } : {}
|
|
1751
|
-
};
|
|
1752
|
-
return state.setValueAtPath(segments, next, meta);
|
|
1753
|
-
}
|
|
1754
|
-
return {
|
|
1755
|
-
append(path, value) {
|
|
1756
|
-
const next = readArray(path);
|
|
1757
|
-
next.push(value);
|
|
1758
|
-
return writeArray(path, next, { kind: "insert", index: next.length - 1 });
|
|
1759
|
-
},
|
|
1760
|
-
prepend(path, value) {
|
|
1761
|
-
const next = readArray(path);
|
|
1762
|
-
next.unshift(value);
|
|
1763
|
-
return writeArray(path, next, { kind: "insert", index: 0 });
|
|
1764
|
-
},
|
|
1765
|
-
insert(path, index, value) {
|
|
1766
|
-
const next = readArray(path);
|
|
1767
|
-
const preLen = next.length;
|
|
1768
|
-
const insertIndex = index < 0 ? Math.max(0, preLen + index) : Math.min(index, preLen);
|
|
1769
|
-
next.splice(insertIndex, 0, value);
|
|
1770
|
-
return writeArray(path, next, { kind: "insert", index: insertIndex });
|
|
1771
|
-
},
|
|
1772
|
-
remove(path, index) {
|
|
1773
|
-
const next = readArray(path);
|
|
1774
|
-
if (index < 0 || index >= next.length) return false;
|
|
1775
|
-
next.splice(index, 1);
|
|
1776
|
-
return writeArray(path, next, { kind: "remove", index });
|
|
1777
|
-
},
|
|
1778
|
-
swap(path, a, b) {
|
|
1779
|
-
const next = readArray(path);
|
|
1780
|
-
if (a < 0 || a >= next.length) return false;
|
|
1781
|
-
if (b < 0 || b >= next.length) return false;
|
|
1782
|
-
if (a === b) return false;
|
|
1783
|
-
const tmp = next[a];
|
|
1784
|
-
next[a] = next[b];
|
|
1785
|
-
next[b] = tmp;
|
|
1786
|
-
return writeArray(path, next, { kind: "swap", a, b });
|
|
1787
|
-
},
|
|
1788
|
-
move(path, from, to) {
|
|
1789
|
-
const next = readArray(path);
|
|
1790
|
-
if (from < 0 || from >= next.length) return false;
|
|
1791
|
-
const [item] = next.splice(from, 1);
|
|
1792
|
-
const clampedTo = Math.max(0, Math.min(to, next.length));
|
|
1793
|
-
next.splice(clampedTo, 0, item);
|
|
1794
|
-
return writeArray(path, next, { kind: "move", from, to: clampedTo });
|
|
1795
|
-
},
|
|
1796
|
-
replace(path, index, value) {
|
|
1797
|
-
const next = readArray(path);
|
|
1798
|
-
if (index < 0 || index >= next.length) return false;
|
|
1799
|
-
next[index] = value;
|
|
1800
|
-
return writeArray(path, next, { kind: "replace-at", index });
|
|
1801
|
-
}
|
|
1802
|
-
};
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
1055
|
function isErrorInputLike(value) {
|
|
1806
1056
|
if (value instanceof Error) return true;
|
|
1807
1057
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -2461,12 +1711,12 @@ function isPrimitiveOrEmpty(value) {
|
|
|
2461
1711
|
return t === "string" || t === "number" || t === "boolean" || t === "bigint";
|
|
2462
1712
|
}
|
|
2463
1713
|
function isSlimNumericPrimitive(value) {
|
|
2464
|
-
return value === 0 || value ===
|
|
1714
|
+
return value === 0 || typeof value === "bigint" && !value;
|
|
2465
1715
|
}
|
|
2466
1716
|
function blankForKind(slimDefault) {
|
|
2467
1717
|
if (typeof slimDefault === "string") return "";
|
|
2468
1718
|
if (typeof slimDefault === "number") return 0;
|
|
2469
|
-
if (typeof slimDefault === "bigint") return
|
|
1719
|
+
if (typeof slimDefault === "bigint") return typeof BigInt === "function" ? BigInt(0) : void 0;
|
|
2470
1720
|
if (typeof slimDefault === "boolean") return false;
|
|
2471
1721
|
if (slimDefault === null) return null;
|
|
2472
1722
|
return void 0;
|
|
@@ -2835,7 +2085,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2835
2085
|
};
|
|
2836
2086
|
const metaTarget = buildMetaProxy(META_KEYS, (key) => {
|
|
2837
2087
|
if (key === "errorCount") return metaErrors.value.length;
|
|
2838
|
-
if (
|
|
2088
|
+
if (safeOwnHas(metaOwn, key)) return metaOwn[key];
|
|
2839
2089
|
return rootFieldState.value[key];
|
|
2840
2090
|
});
|
|
2841
2091
|
const formMeta = readonly(reactive(metaTarget));
|
|
@@ -2850,8 +2100,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2850
2100
|
);
|
|
2851
2101
|
state.reset(walked.cleanedValues);
|
|
2852
2102
|
for (const pathKey of walked.paths) {
|
|
2853
|
-
state.blankPaths.add(pathKey);
|
|
2854
2103
|
state.originalBlankPaths.add(pathKey);
|
|
2104
|
+
state.blankPaths.add(pathKey);
|
|
2855
2105
|
}
|
|
2856
2106
|
}
|
|
2857
2107
|
};
|
|
@@ -3260,7 +2510,7 @@ function mergeObjectKeys(target, source, path, schema) {
|
|
|
3260
2510
|
|
|
3261
2511
|
async function runFactoryAndApply(st, factory) {
|
|
3262
2512
|
try {
|
|
3263
|
-
const value = await factory();
|
|
2513
|
+
const value = structuralSnapshot(await factory());
|
|
3264
2514
|
if (st.hasPreprocessOrCoerce) walkAuthoredFromConstraints(value, [], st.authoredPaths);
|
|
3265
2515
|
const full = mergeSparseHydration(
|
|
3266
2516
|
toRaw(st.form.value),
|
|
@@ -3304,16 +2554,15 @@ function appendHydrationFailedEntry(st, error) {
|
|
|
3304
2554
|
return entry;
|
|
3305
2555
|
}
|
|
3306
2556
|
|
|
3307
|
-
const isContainer = (value) => Array.isArray(value) || isPlainRecord(value);
|
|
3308
2557
|
function isHydratedFieldRecord(value) {
|
|
3309
2558
|
if (typeof value !== "object" || value === null) return false;
|
|
3310
2559
|
const r = value;
|
|
3311
2560
|
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";
|
|
3312
2561
|
}
|
|
3313
|
-
function withClearedHistoryFlags(record,
|
|
2562
|
+
function withClearedHistoryFlags(record, updatedAt) {
|
|
3314
2563
|
return {
|
|
3315
2564
|
path: record.path,
|
|
3316
|
-
updatedAt
|
|
2565
|
+
updatedAt,
|
|
3317
2566
|
connected: record.connected,
|
|
3318
2567
|
focused: record.focused,
|
|
3319
2568
|
blurred: record.blurred,
|
|
@@ -3371,7 +2620,7 @@ function walkDuStubs(schema, value, path, warned) {
|
|
|
3371
2620
|
function stripSymbolsDeep(value) {
|
|
3372
2621
|
if (value === null || typeof value !== "object") return value;
|
|
3373
2622
|
if (Array.isArray(value)) {
|
|
3374
|
-
let mutated2 =
|
|
2623
|
+
let mutated2 = !consumerExtensible(value);
|
|
3375
2624
|
const out2 = new Array(value.length);
|
|
3376
2625
|
for (let i = 0; i < value.length; i++) {
|
|
3377
2626
|
const original = readConsumerIndex(value, i);
|
|
@@ -3385,7 +2634,7 @@ function stripSymbolsDeep(value) {
|
|
|
3385
2634
|
if (proto !== Object.prototype && proto !== null) return value;
|
|
3386
2635
|
const symKeys = consumerSymbolKeys(value);
|
|
3387
2636
|
const stringKeys = consumerKeys(value);
|
|
3388
|
-
let mutated = symKeys.length > 0;
|
|
2637
|
+
let mutated = symKeys.length > 0 || !consumerExtensible(value);
|
|
3389
2638
|
const out = {};
|
|
3390
2639
|
const src = value;
|
|
3391
2640
|
for (const k of stringKeys) {
|
|
@@ -3428,14 +2677,27 @@ function initialFirstValidationGate(schema) {
|
|
|
3428
2677
|
return schema.needsAsyncValidation?.() !== true;
|
|
3429
2678
|
}
|
|
3430
2679
|
function seedOriginalsFromBaseline(st, baseline) {
|
|
3431
|
-
|
|
2680
|
+
const seeded = /* @__PURE__ */ new Map();
|
|
3432
2681
|
diffAndApply({}, baseline, [], (patch) => {
|
|
3433
|
-
if (patch.kind
|
|
3434
|
-
st.originals.set(canonicalizePath(patch.path).key, {
|
|
3435
|
-
segments: patch.path,
|
|
3436
|
-
value: patch.newValue
|
|
3437
|
-
});
|
|
2682
|
+
if (patch.kind === "added") seedBaseline(seeded, canonicalizePath(patch.path).key, patch);
|
|
3438
2683
|
});
|
|
2684
|
+
replaceOriginals(st, seeded);
|
|
2685
|
+
}
|
|
2686
|
+
function replaceOriginals(st, next) {
|
|
2687
|
+
for (const [key, entry] of next) st.originals.set(key, entry);
|
|
2688
|
+
for (const key of [...toRaw(st.originals).keys()]) {
|
|
2689
|
+
if (!next.has(key)) st.originals.delete(key);
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
function seedBaseline(originals, key, patch) {
|
|
2693
|
+
const value = patch.newValue;
|
|
2694
|
+
if (!isDescendable(value)) {
|
|
2695
|
+
originals.set(key, { segments: patch.path, value });
|
|
2696
|
+
return false;
|
|
2697
|
+
}
|
|
2698
|
+
if (!(value instanceof Map))
|
|
2699
|
+
originals.set(key, { segments: patch.path, value: Array.isArray(value) ? [] : {} });
|
|
2700
|
+
return true;
|
|
3439
2701
|
}
|
|
3440
2702
|
function queueInitialAsyncValidation(st) {
|
|
3441
2703
|
if (!st.ssr && st.schema.needsAsyncValidation?.() === true) {
|
|
@@ -3597,8 +2859,18 @@ function settleTransforms(st, path) {
|
|
|
3597
2859
|
st.transformWaiters.push({ key, resolve });
|
|
3598
2860
|
});
|
|
3599
2861
|
}
|
|
2862
|
+
function writeInstant(st) {
|
|
2863
|
+
const clock = (/* @__PURE__ */ new Date()).toISOString();
|
|
2864
|
+
if (clock > st.latestStamp) return clock;
|
|
2865
|
+
const after = new Date(new Date(st.latestStamp).getTime() + 1);
|
|
2866
|
+
return Number.isFinite(after.getTime()) ? after.toISOString() : clock;
|
|
2867
|
+
}
|
|
2868
|
+
function noteStamp(st, stamp) {
|
|
2869
|
+
if (stamp !== null && stamp > st.latestStamp) st.latestStamp = stamp;
|
|
2870
|
+
}
|
|
3600
2871
|
function touchFieldRecord(st, pathKey, path, patch) {
|
|
3601
2872
|
const current = st.fields.get(pathKey);
|
|
2873
|
+
if (patch.updatedAt !== void 0) noteStamp(st, patch.updatedAt);
|
|
3602
2874
|
st.fields.set(pathKey, {
|
|
3603
2875
|
path,
|
|
3604
2876
|
updatedAt: patch.updatedAt ?? current?.updatedAt ?? null,
|
|
@@ -3617,19 +2889,189 @@ function touchFieldRecord(st, pathKey, path, patch) {
|
|
|
3617
2889
|
blurredAfterInteraction: patch.blurredAfterInteraction ?? current?.blurredAfterInteraction ?? false
|
|
3618
2890
|
});
|
|
3619
2891
|
}
|
|
3620
|
-
function
|
|
3621
|
-
|
|
2892
|
+
function stampContainers(st, containers, now) {
|
|
2893
|
+
eachAncestorOnce(containers, (key, segments) => raiseStamp(st, key, segments, now));
|
|
2894
|
+
}
|
|
2895
|
+
function raiseStamp(st, key, segments, stamp) {
|
|
2896
|
+
if ((st.fields.get(key)?.updatedAt ?? "") < stamp) {
|
|
2897
|
+
touchFieldRecord(st, key, segments, { updatedAt: stamp });
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
function holdRemovedStamps(st, patches, next) {
|
|
2901
|
+
const held = /* @__PURE__ */ new Map();
|
|
2902
|
+
const hold = (path, depth, leaf) => noteHold(st, held, next, path, depth, leaf);
|
|
3622
2903
|
for (const patch of patches) {
|
|
3623
|
-
|
|
3624
|
-
|
|
2904
|
+
if (patch.kind === "added") continue;
|
|
2905
|
+
const { oldValue, path } = patch;
|
|
2906
|
+
if (Array.isArray(oldValue) || isPlainRecord(oldValue)) {
|
|
2907
|
+
if (patch.kind === "changed") {
|
|
2908
|
+
visitActiveLeafPaths(oldValue, path, (leaf) => hold(path, path.length, leaf));
|
|
2909
|
+
}
|
|
2910
|
+
} else if (patch.kind === "removed" ? !hasAtPath(next, path) : Array.isArray(patch.newValue) || isPlainRecord(patch.newValue)) {
|
|
2911
|
+
hold(path, path.length - 1, path);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
applyHolds(st, held);
|
|
2915
|
+
}
|
|
2916
|
+
function noteHold(st, held, next, path, depth, leaf) {
|
|
2917
|
+
const { key: leafKey } = keyForSegments(leaf);
|
|
2918
|
+
const stamp = toRaw(st.originals).has(leafKey) ? toRaw(st.fields).get(leafKey)?.updatedAt : null;
|
|
2919
|
+
if (stamp === null || stamp === void 0) return;
|
|
2920
|
+
let kept = false;
|
|
2921
|
+
for (let at = depth; at >= 0; at--) {
|
|
2922
|
+
const segments = path.slice(0, at);
|
|
2923
|
+
if (!kept && !hasAtPath(next, segments)) continue;
|
|
2924
|
+
kept = true;
|
|
2925
|
+
const { key } = keyForSegments(segments);
|
|
2926
|
+
const current = held.get(key);
|
|
2927
|
+
if (current === void 0) held.set(key, { segments, stamp });
|
|
2928
|
+
else if (stamp > current.stamp) current.stamp = stamp;
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
function applyHolds(st, held) {
|
|
2932
|
+
for (const [key, { segments, stamp }] of held) raiseStamp(st, key, segments, stamp);
|
|
2933
|
+
}
|
|
2934
|
+
function stampBareContainers(st, patches, bare, now) {
|
|
2935
|
+
for (const index of bare) {
|
|
2936
|
+
const path = patches[index]?.path ?? [];
|
|
2937
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
2938
|
+
const container = path.slice(0, depth);
|
|
2939
|
+
if (depth < path.length && reachedBesides(patches, index, container)) break;
|
|
2940
|
+
const { key, segments } = keyForSegments(container);
|
|
2941
|
+
raiseStamp(st, key, segments, now);
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
function reachedBesides(patches, index, container) {
|
|
2946
|
+
for (const step of [-1, 1]) {
|
|
2947
|
+
for (let i = index + step; ; i += step) {
|
|
2948
|
+
const patch = patches[i];
|
|
2949
|
+
if (patch === void 0 || !isPathPrefix(container, patch.path)) break;
|
|
2950
|
+
if (!isBarePatch(patch)) return true;
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
return false;
|
|
2954
|
+
}
|
|
2955
|
+
function eachAncestorOnce(paths, visit) {
|
|
2956
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2957
|
+
for (const path of paths) {
|
|
2958
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
2959
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
2960
|
+
if (seen.has(key)) break;
|
|
2961
|
+
seen.add(key);
|
|
2962
|
+
visit(key, segments);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
function foldInteractionHistory(st, path, released) {
|
|
2967
|
+
let touched = false;
|
|
2968
|
+
let interacted = false;
|
|
2969
|
+
let blurredAfterInteraction = false;
|
|
2970
|
+
for (const record of released) {
|
|
2971
|
+
touched || (touched = record.touched);
|
|
2972
|
+
interacted || (interacted = record.interacted);
|
|
2973
|
+
blurredAfterInteraction || (blurredAfterInteraction = record.blurredAfterInteraction);
|
|
2974
|
+
}
|
|
2975
|
+
if (!touched && !interacted && !blurredAfterInteraction) return;
|
|
2976
|
+
st.noteReleased?.(released);
|
|
2977
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
2978
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
2979
|
+
const current = st.fields.get(key);
|
|
2980
|
+
touchFieldRecord(st, key, segments, {
|
|
2981
|
+
touched: touched || current?.touched === true,
|
|
2982
|
+
interacted: interacted || current?.interacted === true,
|
|
2983
|
+
blurredAfterInteraction: blurredAfterInteraction || current?.blurredAfterInteraction === true
|
|
2984
|
+
});
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
function releaseRemovedRecords(st, segments, raw) {
|
|
2988
|
+
const released = [];
|
|
2989
|
+
let depth = segments.length;
|
|
2990
|
+
do {
|
|
2991
|
+
const { key } = keyForSegments(segments.slice(0, depth));
|
|
2992
|
+
abortValidationAt(st, key);
|
|
2993
|
+
const record = st.fields.get(key);
|
|
2994
|
+
if (record !== void 0) {
|
|
2995
|
+
released.push(record);
|
|
2996
|
+
if (record.connected) st.fields.set(key, withClearedHistoryFlags(record, null));
|
|
2997
|
+
else st.fields.delete(key);
|
|
2998
|
+
}
|
|
2999
|
+
depth--;
|
|
3000
|
+
} while (depth > 0 && !hasAtPath(raw, segments.slice(0, depth)));
|
|
3001
|
+
const present = segments.slice(0, depth);
|
|
3002
|
+
foldInteractionHistory(st, present, released);
|
|
3003
|
+
return present;
|
|
3004
|
+
}
|
|
3005
|
+
function noteRemovedBaseline(st, key, segments, notify) {
|
|
3006
|
+
if (st.originals.get(key)?.value === void 0) return;
|
|
3007
|
+
st.removedPaths.set(key, segments);
|
|
3008
|
+
notify.push(segments);
|
|
3009
|
+
}
|
|
3010
|
+
function trackForSweep(st, path, key) {
|
|
3011
|
+
st.pathSweep.track(path, key);
|
|
3012
|
+
for (let i = 1; i < path.length; i++) {
|
|
3013
|
+
const ancestor = path.slice(0, i);
|
|
3014
|
+
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
function commitWritePatches(st, patches, meta, structuralOp, now) {
|
|
3018
|
+
const arrayOpPath = structuralOp?.path;
|
|
3019
|
+
const reshaped = [];
|
|
3020
|
+
const removed = [];
|
|
3021
|
+
const resizing = [];
|
|
3022
|
+
const raw = toRaw(st.form.value);
|
|
3023
|
+
const bareAt = [];
|
|
3024
|
+
for (const [index, patch] of patches.entries()) {
|
|
3025
|
+
const { key, segments } = canonicalizePath(patch.path);
|
|
3026
|
+
const bare = isBarePatch(patch);
|
|
3027
|
+
if (!bare && !st.originals.has(key)) {
|
|
3625
3028
|
st.originals.set(key, { segments: patch.path, value: void 0 });
|
|
3626
3029
|
}
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
const ancestor = patch.path.slice(0, i);
|
|
3631
|
-
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
3030
|
+
const positional = arrayOpPath !== void 0 && segments.length > arrayOpPath.length && isPathPrefix(arrayOpPath, segments);
|
|
3031
|
+
if (structuralOp === null && (patch.kind !== "changed" || typeof patch.oldValue === "object" || typeof patch.newValue === "object")) {
|
|
3032
|
+
resizing.push(segments);
|
|
3632
3033
|
}
|
|
3034
|
+
if (!positional) {
|
|
3035
|
+
if (patch.kind === "removed" && !hasAtPath(raw, segments)) {
|
|
3036
|
+
reshaped.push(releaseRemovedRecords(st, segments, raw));
|
|
3037
|
+
noteRemovedBaseline(st, key, segments, removed);
|
|
3038
|
+
} else {
|
|
3039
|
+
touchFieldRecord(st, key, segments, { updatedAt: now });
|
|
3040
|
+
if (bare) bareAt.push(index);
|
|
3041
|
+
if (patch.kind === "changed" && typeof patch.oldValue === "object" && patch.oldValue !== null) {
|
|
3042
|
+
diffAndApply(patch.oldValue, void 0, segments, (gone) => {
|
|
3043
|
+
if (!hasAtPath(raw, gone.path)) {
|
|
3044
|
+
reshaped.push(releaseRemovedRecords(st, gone.path, raw));
|
|
3045
|
+
const goneAt = canonicalizePath(gone.path);
|
|
3046
|
+
noteRemovedBaseline(st, goneAt.key, goneAt.segments, removed);
|
|
3047
|
+
}
|
|
3048
|
+
});
|
|
3049
|
+
}
|
|
3050
|
+
if (patch.kind === "changed" && isDescendable(patch.newValue)) {
|
|
3051
|
+
diffAndApply(void 0, patch.newValue, segments, (fresh) => {
|
|
3052
|
+
const at = canonicalizePath(fresh.path);
|
|
3053
|
+
trackForSweep(st, fresh.path, at.key);
|
|
3054
|
+
if (fresh.kind === "added" && isDescendable(fresh.newValue)) {
|
|
3055
|
+
reshaped.push(at.segments);
|
|
3056
|
+
return;
|
|
3057
|
+
}
|
|
3058
|
+
if (!st.originals.has(at.key)) {
|
|
3059
|
+
st.originals.set(at.key, { segments: fresh.path, value: void 0 });
|
|
3060
|
+
}
|
|
3061
|
+
touchFieldRecord(st, at.key, at.segments, { updatedAt: now });
|
|
3062
|
+
});
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
trackForSweep(st, patch.path, key);
|
|
3067
|
+
}
|
|
3068
|
+
if (arrayOpPath !== void 0 && patches.length > 0) reshaped.push(arrayOpPath);
|
|
3069
|
+
if (reshaped.length > 0) stampContainers(st, reshaped, now);
|
|
3070
|
+
if (bareAt.length > 0) stampBareContainers(st, patches, bareAt, now);
|
|
3071
|
+
if (removed.length > 0) pulseStructure(st.structureSignal, removed);
|
|
3072
|
+
if (resizing.length > 0) st.arrayIdentity.realignContaining(resizing);
|
|
3073
|
+
if (structuralOp !== null) {
|
|
3074
|
+
st.arrayBookkeeping.applyStructuralOp(structuralOp.path, structuralOp.remap, now);
|
|
3633
3075
|
}
|
|
3634
3076
|
for (const listener of st.formChangeListeners) {
|
|
3635
3077
|
try {
|
|
@@ -3639,33 +3081,39 @@ function commitWritePatches(st, patches, meta) {
|
|
|
3639
3081
|
}
|
|
3640
3082
|
}
|
|
3641
3083
|
}
|
|
3642
|
-
function applyFormReplacementWithPath(st, next, meta,
|
|
3084
|
+
function applyFormReplacementWithPath(st, next, meta, structuralOp, now) {
|
|
3643
3085
|
const prev = st.form.value;
|
|
3644
3086
|
if (Object.is(prev, next)) return;
|
|
3645
3087
|
const patches = [];
|
|
3646
3088
|
diffAndApply(prev, next, [], (patch) => {
|
|
3647
3089
|
patches.push(patch);
|
|
3648
3090
|
});
|
|
3649
|
-
|
|
3091
|
+
holdRemovedStamps(st, patches, next);
|
|
3092
|
+
const reconciled = callConsumerFn(
|
|
3093
|
+
() => applyChangedKeys(prev, next, structuralOp?.path ?? null, [], patches),
|
|
3094
|
+
null);
|
|
3095
|
+
if (reconciled === null) return;
|
|
3096
|
+
if (!reconciled) {
|
|
3650
3097
|
st.form.value = next;
|
|
3651
3098
|
} else if (patches.some(
|
|
3652
3099
|
(p) => p.path.length > 0 && typeof p.path[0] === "string" && isShadowedKey(p.path[0])
|
|
3653
3100
|
)) {
|
|
3654
3101
|
triggerRef(st.form);
|
|
3655
3102
|
}
|
|
3656
|
-
commitWritePatches(st, patches, meta);
|
|
3103
|
+
commitWritePatches(st, patches, meta, structuralOp, now);
|
|
3657
3104
|
}
|
|
3658
3105
|
function applyFormReplacement(st, next, meta) {
|
|
3659
|
-
applyFormReplacementWithPath(st, next, meta, null);
|
|
3106
|
+
applyFormReplacementWithPath(st, next, meta, null, writeInstant(st));
|
|
3660
3107
|
}
|
|
3661
|
-
function applyTargetedWrite(st, path, completedValue, meta) {
|
|
3108
|
+
function applyTargetedWrite(st, path, completedValue, meta, structuralOp, now) {
|
|
3662
3109
|
const result = tryInPlaceLeafWrite(st.form.value, path, completedValue);
|
|
3663
3110
|
if (!result.applied) {
|
|
3664
3111
|
applyFormReplacementWithPath(
|
|
3665
3112
|
st,
|
|
3666
3113
|
setAtPathWithSchemaFill(st.form.value, st.schema, path, completedValue),
|
|
3667
3114
|
meta,
|
|
3668
|
-
|
|
3115
|
+
structuralOp,
|
|
3116
|
+
now
|
|
3669
3117
|
);
|
|
3670
3118
|
return;
|
|
3671
3119
|
}
|
|
@@ -3673,9 +3121,9 @@ function applyTargetedWrite(st, path, completedValue, meta) {
|
|
|
3673
3121
|
diffAndApply(result.old, completedValue, path, (patch) => {
|
|
3674
3122
|
patches.push(patch);
|
|
3675
3123
|
});
|
|
3676
|
-
commitWritePatches(st, patches, meta);
|
|
3124
|
+
commitWritePatches(st, patches, meta, null, now);
|
|
3677
3125
|
}
|
|
3678
|
-
function setValueAtPath(st, path, value, meta) {
|
|
3126
|
+
function setValueAtPath(st, path, value, meta, writeStamp) {
|
|
3679
3127
|
if (st.effectiveDisabled.value) {
|
|
3680
3128
|
return false;
|
|
3681
3129
|
}
|
|
@@ -3748,7 +3196,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3748
3196
|
value,
|
|
3749
3197
|
variantDefault,
|
|
3750
3198
|
void 0,
|
|
3751
|
-
meta
|
|
3199
|
+
meta,
|
|
3200
|
+
writeStamp
|
|
3752
3201
|
);
|
|
3753
3202
|
}
|
|
3754
3203
|
return reshapeUnionVariant(
|
|
@@ -3758,7 +3207,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3758
3207
|
value,
|
|
3759
3208
|
{ [last]: value },
|
|
3760
3209
|
void 0,
|
|
3761
|
-
meta
|
|
3210
|
+
meta,
|
|
3211
|
+
writeStamp
|
|
3762
3212
|
);
|
|
3763
3213
|
}
|
|
3764
3214
|
}
|
|
@@ -3782,7 +3232,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3782
3232
|
discValue,
|
|
3783
3233
|
variantDefault,
|
|
3784
3234
|
valueRecord,
|
|
3785
|
-
meta
|
|
3235
|
+
meta,
|
|
3236
|
+
writeStamp
|
|
3786
3237
|
);
|
|
3787
3238
|
}
|
|
3788
3239
|
return reshapeUnionVariant(
|
|
@@ -3792,10 +3243,20 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3792
3243
|
discValue,
|
|
3793
3244
|
{ [discKey]: discValue },
|
|
3794
3245
|
void 0,
|
|
3795
|
-
meta
|
|
3246
|
+
meta,
|
|
3247
|
+
writeStamp
|
|
3796
3248
|
);
|
|
3797
3249
|
}
|
|
3798
|
-
return reshapeUnionVariant(
|
|
3250
|
+
return reshapeUnionVariant(
|
|
3251
|
+
st,
|
|
3252
|
+
path,
|
|
3253
|
+
oldDiscValue,
|
|
3254
|
+
void 0,
|
|
3255
|
+
{},
|
|
3256
|
+
void 0,
|
|
3257
|
+
meta,
|
|
3258
|
+
writeStamp
|
|
3259
|
+
);
|
|
3799
3260
|
}
|
|
3800
3261
|
}
|
|
3801
3262
|
}
|
|
@@ -3845,16 +3306,17 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3845
3306
|
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3846
3307
|
st.arrayIdentity.realign(path);
|
|
3847
3308
|
}
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
st
|
|
3851
|
-
|
|
3309
|
+
const now = writeStamp ?? writeInstant(st);
|
|
3310
|
+
applyTargetedWrite(
|
|
3311
|
+
st,
|
|
3312
|
+
path,
|
|
3313
|
+
completedValue,
|
|
3314
|
+
meta,
|
|
3315
|
+
arrayOpRemap !== null ? { path, remap: arrayOpRemap } : null,
|
|
3316
|
+
now
|
|
3317
|
+
);
|
|
3318
|
+
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3852
3319
|
st.variantMemory.clearUnderPath(path);
|
|
3853
|
-
st.arrayIdentity.realign(path);
|
|
3854
|
-
} else if (isContainer(currentValue) && !isContainer(value)) {
|
|
3855
|
-
if (subtreeHadRealBaseline(st, path, currentValue)) {
|
|
3856
|
-
st.removedSubtrees.add(pathKey);
|
|
3857
|
-
}
|
|
3858
3320
|
}
|
|
3859
3321
|
const effectiveModeAfterWrite = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
3860
3322
|
if (effectiveModeAfterWrite === "change") {
|
|
@@ -3862,7 +3324,7 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3862
3324
|
}
|
|
3863
3325
|
return true;
|
|
3864
3326
|
}
|
|
3865
|
-
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta) {
|
|
3327
|
+
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta, writeStamp) {
|
|
3866
3328
|
const sameDisc = Object.is(oldDiscValue, newDiscValue);
|
|
3867
3329
|
const parentKey = canonicalizePath(parentPath).key;
|
|
3868
3330
|
let baseline = variantDefault;
|
|
@@ -3928,7 +3390,7 @@ function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variant
|
|
|
3928
3390
|
appliedSync = true;
|
|
3929
3391
|
}
|
|
3930
3392
|
}
|
|
3931
|
-
|
|
3393
|
+
applyFormReplacementWithPath(st, nextForm, meta, null, writeStamp ?? writeInstant(st));
|
|
3932
3394
|
for (const k of newBlankPaths) st.blankPaths.add(k);
|
|
3933
3395
|
if (reshapeMode === "change" && !appliedSync) {
|
|
3934
3396
|
scheduleFieldValidation(st, parentPath, false, meta?.instance);
|
|
@@ -3949,7 +3411,9 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
3949
3411
|
aborted: false,
|
|
3950
3412
|
timer: null,
|
|
3951
3413
|
settled: false,
|
|
3952
|
-
released: false
|
|
3414
|
+
released: false,
|
|
3415
|
+
key,
|
|
3416
|
+
path
|
|
3953
3417
|
};
|
|
3954
3418
|
st.fieldValidationState.set(key, fresh);
|
|
3955
3419
|
const myEpoch = ++st.scheduleEpoch;
|
|
@@ -3960,19 +3424,20 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
3960
3424
|
try {
|
|
3961
3425
|
st.activeValidations.value += 1;
|
|
3962
3426
|
activeIncremented = true;
|
|
3963
|
-
incFieldValidation(st, key);
|
|
3427
|
+
incFieldValidation(st, fresh.key);
|
|
3964
3428
|
} catch (err) {
|
|
3965
3429
|
if (activeIncremented) {
|
|
3966
3430
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
3967
3431
|
}
|
|
3968
3432
|
throw err;
|
|
3969
3433
|
}
|
|
3970
|
-
const
|
|
3971
|
-
const
|
|
3972
|
-
const dataAtScope = subtreeScope ? getAtPath(st.form.value,
|
|
3973
|
-
|
|
3974
|
-
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, scopePath)).then((response) => {
|
|
3434
|
+
const startPath = fresh.path;
|
|
3435
|
+
const subtreeScope = startPath.length > 0 && st.schema.hasContainerOrRootRefine?.() === false;
|
|
3436
|
+
const dataAtScope = subtreeScope ? getAtPath(st.form.value, startPath) : st.form.value;
|
|
3437
|
+
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, subtreeScope ? startPath : void 0)).then((response) => {
|
|
3975
3438
|
if (fresh.aborted) return;
|
|
3439
|
+
const scopePath = subtreeScope ? fresh.path : void 0;
|
|
3440
|
+
const scopeKey = subtreeScope ? fresh.key : ROOT_PATH_KEY;
|
|
3976
3441
|
if (myEpoch <= st.lastCommittedEpoch) return;
|
|
3977
3442
|
st.lastCommittedEpoch = myEpoch;
|
|
3978
3443
|
if (effectiveMode === "blur") {
|
|
@@ -3983,14 +3448,14 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
3983
3448
|
const filtered = filterAuthoredErrors(st, errors);
|
|
3984
3449
|
const restamped = subtreeScope ? filtered.map((err) => ({
|
|
3985
3450
|
...err,
|
|
3986
|
-
path: [...
|
|
3451
|
+
path: [...scopePath ?? [], ...err.path]
|
|
3987
3452
|
})) : filtered;
|
|
3988
3453
|
applySchemaErrorsForSubtree(st, scopePath ?? [], restamped);
|
|
3989
3454
|
}).catch(() => {
|
|
3990
3455
|
}).finally(() => {
|
|
3991
3456
|
if (!fresh.released) {
|
|
3992
3457
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
3993
|
-
decFieldValidation(st, key);
|
|
3458
|
+
decFieldValidation(st, fresh.key);
|
|
3994
3459
|
}
|
|
3995
3460
|
fresh.settled = true;
|
|
3996
3461
|
});
|
|
@@ -4029,6 +3494,19 @@ function cancelFieldValidationUnder(st, prefix) {
|
|
|
4029
3494
|
st.fieldValidationState.delete(key);
|
|
4030
3495
|
}
|
|
4031
3496
|
}
|
|
3497
|
+
function abortValidationAt(st, key) {
|
|
3498
|
+
const entry = st.fieldValidationState.get(key);
|
|
3499
|
+
if (entry === void 0) return;
|
|
3500
|
+
if (entry.timer !== null) {
|
|
3501
|
+
clearTimeout(entry.timer);
|
|
3502
|
+
} else if (!entry.settled && !entry.released) {
|
|
3503
|
+
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
3504
|
+
decFieldValidation(st, key);
|
|
3505
|
+
entry.released = true;
|
|
3506
|
+
}
|
|
3507
|
+
entry.aborted = true;
|
|
3508
|
+
st.fieldValidationState.delete(key);
|
|
3509
|
+
}
|
|
4032
3510
|
function onFormChange(st, listener) {
|
|
4033
3511
|
st.formChangeListeners.add(listener);
|
|
4034
3512
|
return () => {
|
|
@@ -4079,6 +3557,34 @@ function dispose(st) {
|
|
|
4079
3557
|
function getValueAtPath(st, path) {
|
|
4080
3558
|
return getAtPath(st.form.value, path);
|
|
4081
3559
|
}
|
|
3560
|
+
function freezeBaseline(value) {
|
|
3561
|
+
if (Object.isFrozen(value)) return value;
|
|
3562
|
+
if (Array.isArray(value)) {
|
|
3563
|
+
for (const item of value) freezeBaseline(item);
|
|
3564
|
+
return Object.freeze(value);
|
|
3565
|
+
}
|
|
3566
|
+
if (isPlainRecord(value)) {
|
|
3567
|
+
for (const k of Object.keys(value)) freezeBaseline(safeOwnRead(value, k));
|
|
3568
|
+
return Object.freeze(value);
|
|
3569
|
+
}
|
|
3570
|
+
return value;
|
|
3571
|
+
}
|
|
3572
|
+
function getOriginalAtPath(st, path) {
|
|
3573
|
+
let node = st.baselineValue;
|
|
3574
|
+
for (let i = 0; i < path.length; i++) {
|
|
3575
|
+
const segment = path[i];
|
|
3576
|
+
if (Array.isArray(node)) {
|
|
3577
|
+
const at = typeof segment === "number" ? st.arrayIdentity.baselineIndexOf(path.slice(0, i), segment) : -1;
|
|
3578
|
+
if (at < 0) return void 0;
|
|
3579
|
+
node = node[at];
|
|
3580
|
+
} else if (isPlainRecord(node) && typeof segment === "string") {
|
|
3581
|
+
node = safeOwnRead(node, segment);
|
|
3582
|
+
} else {
|
|
3583
|
+
return void 0;
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
return freezeBaseline(node);
|
|
3587
|
+
}
|
|
4082
3588
|
const ERROR_SOURCES = ["schema", "user"];
|
|
4083
3589
|
function createErrorCells(schema, pristine) {
|
|
4084
3590
|
const raw = /* @__PURE__ */ new Map();
|
|
@@ -4156,6 +3662,54 @@ function restoreErrorCells(st, entries) {
|
|
|
4156
3662
|
st.errorCells().set(key, { schema: [...cell.schema], user: [...cell.user] });
|
|
4157
3663
|
}
|
|
4158
3664
|
}
|
|
3665
|
+
function captureStructure(st) {
|
|
3666
|
+
return {
|
|
3667
|
+
identity: st.arrayIdentity.snapshot(),
|
|
3668
|
+
originals: [...toRaw(st.originals)],
|
|
3669
|
+
originalBlank: [...st.originalBlankPaths],
|
|
3670
|
+
removed: [...st.removedPaths]
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
function restoreStructure(st, snapshot, remaps, returning) {
|
|
3674
|
+
const originals = new Map(snapshot.originals);
|
|
3675
|
+
const raw = toRaw(st.form.value);
|
|
3676
|
+
const held = /* @__PURE__ */ new Map();
|
|
3677
|
+
for (const [key, { segments }] of toRaw(st.originals)) {
|
|
3678
|
+
if (!originals.has(key) && hasAtPath(raw, segments)) {
|
|
3679
|
+
noteHold(st, held, raw, segments, segments.length - 1, segments);
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
applyHolds(st, held);
|
|
3683
|
+
st.arrayIdentity.restore(snapshot.identity);
|
|
3684
|
+
replaceOriginals(st, originals);
|
|
3685
|
+
st.originalBlankPaths.clear();
|
|
3686
|
+
for (const key of snapshot.originalBlank) st.originalBlankPaths.add(key);
|
|
3687
|
+
const pulsed = [...st.removedPaths.values()];
|
|
3688
|
+
st.removedPaths.clear();
|
|
3689
|
+
for (const [key, segments] of snapshot.removed) {
|
|
3690
|
+
st.removedPaths.set(key, segments);
|
|
3691
|
+
pulsed.push(segments);
|
|
3692
|
+
}
|
|
3693
|
+
for (const [segments, remap] of remaps) {
|
|
3694
|
+
migrateFieldRecords(st.fields, segments, remap, (path, released) => {
|
|
3695
|
+
let stamp = "";
|
|
3696
|
+
for (const { updatedAt } of released) {
|
|
3697
|
+
if (updatedAt !== null && updatedAt > stamp) stamp = updatedAt;
|
|
3698
|
+
}
|
|
3699
|
+
if (stamp !== "") eachAncestorOnce([path], (key, at) => raiseStamp(st, key, at, stamp));
|
|
3700
|
+
foldInteractionHistory(st, path, released);
|
|
3701
|
+
});
|
|
3702
|
+
}
|
|
3703
|
+
for (const record of returning) {
|
|
3704
|
+
st.fields.set(canonicalizePath(record.path).key, {
|
|
3705
|
+
...record,
|
|
3706
|
+
connected: false,
|
|
3707
|
+
focused: null,
|
|
3708
|
+
blurred: null
|
|
3709
|
+
});
|
|
3710
|
+
}
|
|
3711
|
+
if (pulsed.length > 0) pulseStructure(st.structureSignal, pulsed);
|
|
3712
|
+
}
|
|
4159
3713
|
function getErrorsForPath(st, path) {
|
|
4160
3714
|
const { key } = canonicalizePath(path);
|
|
4161
3715
|
const cell = st.errorCells().get(key);
|
|
@@ -4180,6 +3734,7 @@ function noteDomConnected(st, path) {
|
|
|
4180
3734
|
}
|
|
4181
3735
|
function noteDomDisconnected(st, path) {
|
|
4182
3736
|
const { key } = canonicalizePath(path);
|
|
3737
|
+
if (!st.fields.has(key)) return;
|
|
4183
3738
|
touchFieldRecord(st, key, path, { connected: false, focused: null, blurred: null });
|
|
4184
3739
|
}
|
|
4185
3740
|
function markConnectedOptimistically(st, path) {
|
|
@@ -4239,22 +3794,44 @@ function markInteracted(st, path) {
|
|
|
4239
3794
|
if (st.fields.get(key)?.interacted === true) return;
|
|
4240
3795
|
touchFieldRecord(st, key, path, { interacted: true });
|
|
4241
3796
|
}
|
|
3797
|
+
function markBareContainers(st, segments, ladder) {
|
|
3798
|
+
const value = getAtPath(toRaw(st.form.value), segments);
|
|
3799
|
+
if (!isDescendable(value)) return false;
|
|
3800
|
+
const bare = [];
|
|
3801
|
+
diffAndApply(void 0, value, segments, (patch) => {
|
|
3802
|
+
if (isBarePatch(patch)) bare.push(patch.path);
|
|
3803
|
+
});
|
|
3804
|
+
eachAncestorOnce(bare, (key, path) => {
|
|
3805
|
+
const current = st.fields.get(key);
|
|
3806
|
+
if (current?.touched === true && (!ladder || current.interacted && current.blurredAfterInteraction)) {
|
|
3807
|
+
return;
|
|
3808
|
+
}
|
|
3809
|
+
touchFieldRecord(
|
|
3810
|
+
st,
|
|
3811
|
+
key,
|
|
3812
|
+
path,
|
|
3813
|
+
ladder ? { touched: true, interacted: true, blurredAfterInteraction: true } : { touched: true }
|
|
3814
|
+
);
|
|
3815
|
+
});
|
|
3816
|
+
return bare.length > 0;
|
|
3817
|
+
}
|
|
4242
3818
|
function touchAtPath(st, segments) {
|
|
4243
3819
|
const formValue = st.form.value;
|
|
4244
3820
|
for (const [leafKey, entry] of st.originals) {
|
|
4245
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
3821
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4246
3822
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4247
3823
|
const current = st.fields.get(leafKey);
|
|
4248
3824
|
if (current?.touched === true) continue;
|
|
4249
3825
|
touchFieldRecord(st, leafKey, entry.segments, { touched: true });
|
|
4250
3826
|
}
|
|
3827
|
+
if (markBareContainers(st, segments, false)) ;
|
|
4251
3828
|
}
|
|
4252
3829
|
function interactAtPath(st, segments) {
|
|
4253
3830
|
if (st.effectiveDisabled.value) return false;
|
|
4254
3831
|
const formValue = st.form.value;
|
|
4255
3832
|
let interactedAny = false;
|
|
4256
3833
|
for (const [leafKey, entry] of st.originals) {
|
|
4257
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
3834
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4258
3835
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4259
3836
|
interactedAny = true;
|
|
4260
3837
|
const current = st.fields.get(leafKey);
|
|
@@ -4267,6 +3844,7 @@ function interactAtPath(st, segments) {
|
|
|
4267
3844
|
blurredAfterInteraction: true
|
|
4268
3845
|
});
|
|
4269
3846
|
}
|
|
3847
|
+
if (markBareContainers(st, segments, true)) interactedAny = true;
|
|
4270
3848
|
return interactedAny;
|
|
4271
3849
|
}
|
|
4272
3850
|
function rehydrate(st) {
|
|
@@ -4308,14 +3886,31 @@ function adoptResolvedDefaults(st, value) {
|
|
|
4308
3886
|
st.schema
|
|
4309
3887
|
)
|
|
4310
3888
|
);
|
|
4311
|
-
|
|
4312
|
-
st,
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
st.defaultValues,
|
|
4316
|
-
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4317
|
-
)
|
|
3889
|
+
st.baselineValue = computeBaseline(
|
|
3890
|
+
st.schema,
|
|
3891
|
+
st.defaultValues,
|
|
3892
|
+
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4318
3893
|
);
|
|
3894
|
+
seedOriginalsFromBaseline(st, st.baselineValue);
|
|
3895
|
+
st.arrayIdentity.rebaseline((segments) => holdsListAt(value, segments));
|
|
3896
|
+
const dropped = [];
|
|
3897
|
+
for (const [key, segments] of st.removedPaths) {
|
|
3898
|
+
if (st.originals.get(key)?.value !== void 0) continue;
|
|
3899
|
+
st.removedPaths.delete(key);
|
|
3900
|
+
dropped.push(segments);
|
|
3901
|
+
}
|
|
3902
|
+
if (dropped.length > 0) pulseStructure(st.structureSignal, dropped);
|
|
3903
|
+
}
|
|
3904
|
+
function holdsListAt(value, segments) {
|
|
3905
|
+
let node = value;
|
|
3906
|
+
for (const segment of segments) {
|
|
3907
|
+
if (Array.isArray(node)) return true;
|
|
3908
|
+
if (!isPlainRecord(node) || typeof segment !== "string" || !safeOwnHas(node, segment)) {
|
|
3909
|
+
return false;
|
|
3910
|
+
}
|
|
3911
|
+
node = safeOwnRead(node, segment);
|
|
3912
|
+
}
|
|
3913
|
+
return Array.isArray(node);
|
|
4319
3914
|
}
|
|
4320
3915
|
function reset(st, nextDefaultValues) {
|
|
4321
3916
|
const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
|
|
@@ -4326,19 +3921,25 @@ function reset(st, nextDefaultValues) {
|
|
|
4326
3921
|
st.defaultValues = structuralSnapshot(resetSource);
|
|
4327
3922
|
const next = computeBaseline(
|
|
4328
3923
|
st.schema,
|
|
4329
|
-
|
|
3924
|
+
st.defaultValues,
|
|
4330
3925
|
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4331
3926
|
);
|
|
4332
3927
|
rebuildAuthoredPaths(st, resetSource, next);
|
|
4333
|
-
applyFormReplacement(st, next);
|
|
4334
|
-
st.arrayIdentity.rebaselineAll();
|
|
4335
|
-
st.removedSubtrees.clear();
|
|
4336
|
-
seedOriginalsFromBaseline(st, next);
|
|
4337
3928
|
if (nextDefaultValues !== void 0) {
|
|
4338
3929
|
const mentioned = /* @__PURE__ */ new Set();
|
|
4339
3930
|
walkAuthoredFromConstraints(nextDefaultValues, [], mentioned);
|
|
4340
3931
|
for (const key of mentioned) st.originalBlankPaths.delete(key);
|
|
4341
3932
|
}
|
|
3933
|
+
const now = writeInstant(st);
|
|
3934
|
+
applyFormReplacementWithPath(st, structuralSnapshot(next), void 0, null, now);
|
|
3935
|
+
st.arrayIdentity.rebaseline(() => true);
|
|
3936
|
+
if (st.removedPaths.size > 0) {
|
|
3937
|
+
const cleared = [...st.removedPaths.values()];
|
|
3938
|
+
st.removedPaths.clear();
|
|
3939
|
+
pulseStructure(st.structureSignal, cleared);
|
|
3940
|
+
}
|
|
3941
|
+
st.baselineValue = next;
|
|
3942
|
+
seedOriginalsFromBaseline(st, next);
|
|
4342
3943
|
st.blankPaths.clear();
|
|
4343
3944
|
for (const key of st.originalBlankPaths) {
|
|
4344
3945
|
st.blankPaths.add(key);
|
|
@@ -4347,7 +3948,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4347
3948
|
replaceErrorChannel(st, "schema", st.schema.validateSync(next));
|
|
4348
3949
|
st.firstValidationDone.value = initialFirstValidationGate(st.schema);
|
|
4349
3950
|
queueInitialAsyncValidation(st);
|
|
4350
|
-
|
|
3951
|
+
noteStamp(st, now);
|
|
4351
3952
|
for (const [pathKey, record] of st.fields) {
|
|
4352
3953
|
st.fields.set(pathKey, withClearedHistoryFlags(record, now));
|
|
4353
3954
|
}
|
|
@@ -4376,6 +3977,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4376
3977
|
}
|
|
4377
3978
|
function resetField(st, path) {
|
|
4378
3979
|
const { key: targetKey, segments: targetSegments } = canonicalizePath(path);
|
|
3980
|
+
const now = writeInstant(st);
|
|
4379
3981
|
st.variantMemory.clearUnderPath(targetSegments);
|
|
4380
3982
|
cancelFieldValidationUnder(st, targetSegments);
|
|
4381
3983
|
cancelTransformsUnder(st, targetSegments);
|
|
@@ -4384,9 +3986,21 @@ function resetField(st, path) {
|
|
|
4384
3986
|
if (segs === null) continue;
|
|
4385
3987
|
if (isPathPrefix(targetSegments, segs)) st.pathSnapshots.delete(snapKey);
|
|
4386
3988
|
}
|
|
3989
|
+
const cleared = [];
|
|
3990
|
+
for (const [fieldKey, record] of Array.from(st.fields.entries())) {
|
|
3991
|
+
if (!isPathPrefix(targetSegments, record.path)) continue;
|
|
3992
|
+
st.fields.set(fieldKey, withClearedHistoryFlags(record, record.updatedAt));
|
|
3993
|
+
cleared.push(fieldKey);
|
|
3994
|
+
}
|
|
4387
3995
|
const leafEntry = st.originals.get(targetKey);
|
|
4388
3996
|
if (leafEntry !== void 0) {
|
|
4389
|
-
const wrote = setValueAtPath(
|
|
3997
|
+
const wrote = setValueAtPath(
|
|
3998
|
+
st,
|
|
3999
|
+
targetSegments,
|
|
4000
|
+
structuralSnapshot(leafEntry.value),
|
|
4001
|
+
void 0,
|
|
4002
|
+
now
|
|
4003
|
+
);
|
|
4390
4004
|
if (!wrote) {
|
|
4391
4005
|
console.error(
|
|
4392
4006
|
`[attaform] AF11 attaform.dev/e/af11 '${targetKey}'`
|
|
@@ -4404,10 +4018,10 @@ function resetField(st, path) {
|
|
|
4404
4018
|
if (subtree === void 0) {
|
|
4405
4019
|
subtree = typeof relative[0] === "number" ? [] : {};
|
|
4406
4020
|
}
|
|
4407
|
-
subtree = setAtPath(subtree, relative, entry.value);
|
|
4021
|
+
subtree = setAtPath(subtree, relative, structuralSnapshot(entry.value));
|
|
4408
4022
|
}
|
|
4409
4023
|
if (anyMatch) {
|
|
4410
|
-
const wroteSubtree = setValueAtPath(st, targetSegments, subtree);
|
|
4024
|
+
const wroteSubtree = setValueAtPath(st, targetSegments, subtree, void 0, now);
|
|
4411
4025
|
if (!wroteSubtree) {
|
|
4412
4026
|
console.error(
|
|
4413
4027
|
`[attaform] AF12 attaform.dev/e/af12 '${targetKey}'`
|
|
@@ -4416,8 +4030,14 @@ function resetField(st, path) {
|
|
|
4416
4030
|
}
|
|
4417
4031
|
}
|
|
4418
4032
|
deleteErrorCellsUnderPrefix(st, targetSegments);
|
|
4419
|
-
|
|
4420
|
-
|
|
4033
|
+
const raw = toRaw(st.form.value);
|
|
4034
|
+
for (const fieldKey of cleared) {
|
|
4035
|
+
const record = st.fields.get(fieldKey);
|
|
4036
|
+
if (record === void 0 || !hasAtPath(raw, record.path)) continue;
|
|
4037
|
+
raiseStamp(st, fieldKey, record.path, now);
|
|
4038
|
+
}
|
|
4039
|
+
if (cleared.length > 0 && hasAtPath(raw, targetSegments)) {
|
|
4040
|
+
stampContainers(st, [targetSegments], now);
|
|
4421
4041
|
}
|
|
4422
4042
|
}
|
|
4423
4043
|
function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
@@ -4430,36 +4050,35 @@ function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
|
4430
4050
|
}
|
|
4431
4051
|
}
|
|
4432
4052
|
}
|
|
4433
|
-
function clearFieldRecordFlags(st, pathKey) {
|
|
4434
|
-
const record = st.fields.get(pathKey);
|
|
4435
|
-
if (record === void 0) return;
|
|
4436
|
-
st.fields.set(pathKey, withClearedHistoryFlags(record, (/* @__PURE__ */ new Date()).toISOString()));
|
|
4437
|
-
}
|
|
4438
4053
|
function isPristineAtPathByKey(st, key, segments) {
|
|
4439
4054
|
if (st.blankPaths.has(key) !== st.originalBlankPaths.has(key)) return false;
|
|
4440
4055
|
const entry = st.originals.get(key);
|
|
4441
4056
|
if (entry === void 0) return true;
|
|
4442
4057
|
return Object.is(getAtPath(st.form.value, segments), entry.value);
|
|
4443
4058
|
}
|
|
4444
|
-
function hasStructuralChangeUnder(st, path) {
|
|
4059
|
+
function hasStructuralChangeUnder(st, path, key) {
|
|
4060
|
+
subscribeStructure(st.structureSignal, key);
|
|
4445
4061
|
return st.arrayIdentity.hasStructuralChangeUnder(path);
|
|
4446
4062
|
}
|
|
4447
|
-
function
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4063
|
+
function pulseStructure(signal, paths) {
|
|
4064
|
+
const keys = signal.keys;
|
|
4065
|
+
if (keys === null) return;
|
|
4066
|
+
eachAncestorOnce(paths, (key) => {
|
|
4067
|
+
keys.add(key);
|
|
4068
|
+
keys.delete(key);
|
|
4453
4069
|
});
|
|
4454
|
-
return had;
|
|
4455
4070
|
}
|
|
4456
|
-
function
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4071
|
+
function subscribeStructure(signal, key) {
|
|
4072
|
+
signal.keys ?? (signal.keys = shallowReactive(/* @__PURE__ */ new Set()));
|
|
4073
|
+
void signal.keys.has(key);
|
|
4074
|
+
}
|
|
4075
|
+
function hasRemovedSubtreeUnder(st, prefix, key) {
|
|
4076
|
+
subscribeStructure(st.structureSignal, key);
|
|
4077
|
+
if (st.removedPaths.size === 0) return false;
|
|
4078
|
+
const raw = toRaw(st.form.value);
|
|
4079
|
+
for (const segments of st.removedPaths.values()) {
|
|
4461
4080
|
if (!isPathPrefix(prefix, segments)) continue;
|
|
4462
|
-
if (
|
|
4081
|
+
if (hasAtPath(raw, segments)) continue;
|
|
4463
4082
|
return true;
|
|
4464
4083
|
}
|
|
4465
4084
|
return false;
|
|
@@ -4495,10 +4114,14 @@ function createFormStore(options) {
|
|
|
4495
4114
|
warn: true
|
|
4496
4115
|
}) : initialData;
|
|
4497
4116
|
const form = ref(stubbedInitialData);
|
|
4498
|
-
const
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4117
|
+
const structureSignal = { keys: null };
|
|
4118
|
+
const arrayIdentity = createArrayIdentity(
|
|
4119
|
+
(arraySegs) => {
|
|
4120
|
+
const v = getAtPath(toRaw(form.value), arraySegs);
|
|
4121
|
+
return Array.isArray(v) ? v.length : 0;
|
|
4122
|
+
},
|
|
4123
|
+
(arrayPaths) => pulseStructure(structureSignal, arrayPaths)
|
|
4124
|
+
);
|
|
4502
4125
|
const fields = shallowReactive(/* @__PURE__ */ new Map());
|
|
4503
4126
|
const domBinding = shallowRef(null);
|
|
4504
4127
|
const errorStore = createErrorCells(
|
|
@@ -4507,7 +4130,7 @@ function createFormStore(options) {
|
|
|
4507
4130
|
);
|
|
4508
4131
|
const errorCells = () => errorStore(true);
|
|
4509
4132
|
const originals = shallowReactive(/* @__PURE__ */ new Map());
|
|
4510
|
-
const
|
|
4133
|
+
const removedPaths = /* @__PURE__ */ new Map();
|
|
4511
4134
|
const blankPaths = reactive(/* @__PURE__ */ new Set());
|
|
4512
4135
|
const originalBlankPaths = /* @__PURE__ */ new Set();
|
|
4513
4136
|
const seededBlankPaths = hydration !== void 0 ? (hydration.blankPaths ?? []).map((dotted) => canonicalizePath(dotted).key) : options.initialBlankPaths ?? [];
|
|
@@ -4608,6 +4231,8 @@ function createFormStore(options) {
|
|
|
4608
4231
|
blankPaths,
|
|
4609
4232
|
originalBlankPaths,
|
|
4610
4233
|
authoredPaths,
|
|
4234
|
+
removedPaths,
|
|
4235
|
+
notifyStructure: (paths) => pulseStructure(structureSignal, paths),
|
|
4611
4236
|
fieldValidationCounts,
|
|
4612
4237
|
fieldValidatingSince,
|
|
4613
4238
|
fieldValidationState,
|
|
@@ -4615,6 +4240,9 @@ function createFormStore(options) {
|
|
|
4615
4240
|
arrayIdentity,
|
|
4616
4241
|
variantMemory,
|
|
4617
4242
|
touchFieldRecord: (pathKey, path, patch) => touchFieldRecord(st, pathKey, path, patch),
|
|
4243
|
+
stampContainers: (containers, now) => stampContainers(st, containers, now),
|
|
4244
|
+
stampBareContainers: (patches, bare, now) => stampBareContainers(st, patches, bare, now),
|
|
4245
|
+
foldInteractionHistory: (path, released) => foldInteractionHistory(st, path, released),
|
|
4618
4246
|
decFieldValidation: (key) => decFieldValidation(st, key)
|
|
4619
4247
|
});
|
|
4620
4248
|
const bind = (fn) => (...args) => fn(st, ...args);
|
|
@@ -4665,6 +4293,8 @@ function createFormStore(options) {
|
|
|
4665
4293
|
// the literal they passed from mutating the form's defaults from outside.
|
|
4666
4294
|
// `reset()` snapshots for a harder reason, where an alias IS reachable.
|
|
4667
4295
|
defaultValues: ownDefaultValues,
|
|
4296
|
+
// The form holds a copy of it, or the hydration payload.
|
|
4297
|
+
baselineValue: schemaInitialData,
|
|
4668
4298
|
ssrPrefetch,
|
|
4669
4299
|
rememberVariants,
|
|
4670
4300
|
fieldValidationMode,
|
|
@@ -4678,7 +4308,8 @@ function createFormStore(options) {
|
|
|
4678
4308
|
cleanupHooks,
|
|
4679
4309
|
authoredPaths,
|
|
4680
4310
|
arrayIdentity,
|
|
4681
|
-
|
|
4311
|
+
removedPaths,
|
|
4312
|
+
structureSignal,
|
|
4682
4313
|
variantMemory,
|
|
4683
4314
|
pathOrdinals,
|
|
4684
4315
|
pathSnapshots,
|
|
@@ -4688,6 +4319,7 @@ function createFormStore(options) {
|
|
|
4688
4319
|
arrayBookkeeping,
|
|
4689
4320
|
skipErrorSeed: () => errorStore(false),
|
|
4690
4321
|
nextOrdinal: 0,
|
|
4322
|
+
latestStamp: "",
|
|
4691
4323
|
scheduleEpoch: 0,
|
|
4692
4324
|
lastCommittedEpoch: 0,
|
|
4693
4325
|
transformTokenSeq: 0,
|
|
@@ -4700,6 +4332,7 @@ function createFormStore(options) {
|
|
|
4700
4332
|
applyFormReplacement: bind(applyFormReplacement),
|
|
4701
4333
|
setValueAtPath: bind(setValueAtPath),
|
|
4702
4334
|
getValueAtPath: bind(getValueAtPath),
|
|
4335
|
+
getOriginalAtPath: bind(getOriginalAtPath),
|
|
4703
4336
|
arrayElementKey: bind(arrayElementKey),
|
|
4704
4337
|
reset: bind(reset),
|
|
4705
4338
|
resetField: bind(resetField),
|
|
@@ -4725,6 +4358,8 @@ function createFormStore(options) {
|
|
|
4725
4358
|
),
|
|
4726
4359
|
clearUserErrors: (path) => clearErrorChannel(st, "user", path),
|
|
4727
4360
|
restoreErrorCells: bind(restoreErrorCells),
|
|
4361
|
+
captureStructure: bind(captureStructure),
|
|
4362
|
+
restoreStructure: bind(restoreStructure),
|
|
4728
4363
|
getErrorsForPath: bind(getErrorsForPath),
|
|
4729
4364
|
ensurePathOrdinal: bind(ensurePathOrdinal),
|
|
4730
4365
|
noteDomConnected: bind(noteDomConnected),
|
|
@@ -4758,7 +4393,7 @@ function createFormStore(options) {
|
|
|
4758
4393
|
diffAndApply({}, schemaInitialData, [], (patch) => {
|
|
4759
4394
|
if (patch.kind !== "added") return;
|
|
4760
4395
|
const { key } = canonicalizePath(patch.path);
|
|
4761
|
-
originals
|
|
4396
|
+
if (seedBaseline(originals, key, patch)) return;
|
|
4762
4397
|
ensurePathOrdinal(st, key);
|
|
4763
4398
|
if (hydration === void 0) {
|
|
4764
4399
|
fields.set(key, {
|
|
@@ -4773,12 +4408,14 @@ function createFormStore(options) {
|
|
|
4773
4408
|
});
|
|
4774
4409
|
}
|
|
4775
4410
|
});
|
|
4411
|
+
if (fields.size > 0) noteStamp(st, initStamp);
|
|
4776
4412
|
if (hydration !== void 0) {
|
|
4777
4413
|
for (const [rawKey, record] of hydration.fields) {
|
|
4778
4414
|
if (typeof rawKey !== "string" || !isHydratedFieldRecord(record)) {
|
|
4779
4415
|
continue;
|
|
4780
4416
|
}
|
|
4781
4417
|
fields.set(rawKey, record);
|
|
4418
|
+
noteStamp(st, record.updatedAt);
|
|
4782
4419
|
}
|
|
4783
4420
|
for (const [rawKey, errs] of hydration.schemaErrors) {
|
|
4784
4421
|
if (typeof rawKey !== "string" || !isHydratedValidationErrorArray(errs)) {
|
|
@@ -5282,7 +4919,7 @@ function buildWizardStatusesProxy(statuses) {
|
|
|
5282
4919
|
// resolves to `undefined` (consistent with property-access).
|
|
5283
4920
|
resolveCall: (arg) => statuses[String(arg)]?.value,
|
|
5284
4921
|
ownKeys: () => Object.keys(statuses),
|
|
5285
|
-
hasKey: (key) =>
|
|
4922
|
+
hasKey: (key) => safeOwnHas(statuses, key)
|
|
5286
4923
|
});
|
|
5287
4924
|
}
|
|
5288
4925
|
|
|
@@ -6432,4 +6069,4 @@ function escapeForInlineScript(json) {
|
|
|
6432
6069
|
});
|
|
6433
6070
|
}
|
|
6434
6071
|
|
|
6435
|
-
export {
|
|
6072
|
+
export { injectWizard as a, isUnset as b, useAbstractForm as c, useRegister as d, escapeForInlineScript as e, useWizard as f, gate as g, humanize as h, injectForm as i, lazy as l, slimKindOf as s, unset as u };
|