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,81 +1,9 @@
|
|
|
1
1
|
import { computed, readonly, toRaw, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, nextTick, warn, reactive, shallowReactive, shallowRef, toValue, watch, triggerRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, onBeforeMount, onBeforeUpdate, onMounted } from 'vue';
|
|
2
|
-
import {
|
|
3
|
-
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.
|
|
4
|
-
import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.
|
|
5
|
-
import { i as isPathPrefix,
|
|
6
|
-
|
|
7
|
-
const AttaformErrorCode = {
|
|
8
|
-
/** A required field is in the blank set: no value was supplied. */
|
|
9
|
-
NoValueSupplied: "atta:no-value-supplied",
|
|
10
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
11
|
-
AdapterThrew: "atta:adapter-threw",
|
|
12
|
-
/**
|
|
13
|
-
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
14
|
-
* threw (sync or async). The adapter caught the throw and surfaced
|
|
15
|
-
* it as a `ValidationError` at the field path so the form's normal
|
|
16
|
-
* error pipeline handles it instead of leaking as an unhandled
|
|
17
|
-
* rejection or routing through `submitError`.
|
|
18
|
-
*/
|
|
19
|
-
ValidatorThrew: "atta:validator-threw",
|
|
20
|
-
/**
|
|
21
|
-
* A function-form `defaultValues` factory threw or its promise
|
|
22
|
-
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
23
|
-
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
24
|
-
* the standard error pipeline carries the signal. Critical for the
|
|
25
|
-
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
26
|
-
* payload, but `schemaErrors` does, so the client sees the failure
|
|
27
|
-
* after rehydration without an extra channel.
|
|
28
|
-
*/
|
|
29
|
-
HydrationFailed: "atta:hydration-failed",
|
|
30
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
31
|
-
PathNotFound: "atta:path-not-found",
|
|
32
|
-
/**
|
|
33
|
-
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
34
|
-
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
35
|
-
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
36
|
-
* aggregate error pipeline can carry the failure alongside ordinary
|
|
37
|
-
* validation errors. The raw factory error remains on
|
|
38
|
-
* `form.hydrateError` for retry UX.
|
|
39
|
-
*/
|
|
40
|
-
ActivationFailed: "atta:activation-failed",
|
|
41
|
-
/**
|
|
42
|
-
* Default code stamped on a manual error set through `form.setErrors`
|
|
43
|
-
* when the caller omits an explicit `code`. The `setErrors` input is
|
|
44
|
-
* lenient (`code` optional), so this is the fallback that keeps every
|
|
45
|
-
* produced `ValidationError` carrying a stable, branchable identifier.
|
|
46
|
-
* Override it per error by passing your own `code` (`api:…`, `auth:…`).
|
|
47
|
-
*/
|
|
48
|
-
UserError: "atta:user-error",
|
|
49
|
-
/**
|
|
50
|
-
* Stamped on a `ValidationError` synthesized from a throw or rejection
|
|
51
|
-
* out of a `handleSubmit` `onSubmit` callback. The raw error also lands
|
|
52
|
-
* on `form.meta.submitError` (a raw-`Error` inspection channel); this
|
|
53
|
-
* code marks the copy piped into the user-error layer so the failure
|
|
54
|
-
* also surfaces on `form.errors` / `meta.ownErrors` / `firstOwnError`
|
|
55
|
-
* where the UI already reads. A throw carrying its own `path` / `code`
|
|
56
|
-
* keeps them; a bare `Error` or a non-Error throw defaults here at the
|
|
57
|
-
* form-level path `[]`.
|
|
58
|
-
*/
|
|
59
|
-
SubmitError: "atta:submit-error",
|
|
60
|
-
/**
|
|
61
|
-
* Synthesized by `wizard.handleSubmit` when the whole-wizard submit
|
|
62
|
-
* would otherwise succeed but a `gate()` step is still uncleared. A
|
|
63
|
-
* gate clears only on its member form's clean submit (confirmation), so
|
|
64
|
-
* a downstream step that happens to be valid-by-default must not let the
|
|
65
|
-
* wizard finish past an unconfirmed prerequisite. Emitted at the gate
|
|
66
|
-
* form's key (path `[]`) so the aggregate error pipeline routes focus to
|
|
67
|
-
* the gate, and `done` never latches.
|
|
68
|
-
*/
|
|
69
|
-
GateNotCleared: "atta:gate-not-cleared"
|
|
70
|
-
};
|
|
71
|
-
function makeBlankRequiredError(segments) {
|
|
72
|
-
return {
|
|
73
|
-
message: "No value supplied",
|
|
74
|
-
path: [...segments],
|
|
75
|
-
code: AttaformErrorCode.NoValueSupplied
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
const NO_ERRORS = Object.freeze([]);
|
|
2
|
+
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-dev.G-3XDl9F.mjs';
|
|
3
|
+
import { e as ensureAttaformInstalled, u as useRegistry, d as kFormContext, f as kFormInstanceId, b as kAttaformWizardActiveStepResolver, i as kAttaformAncestorWizard } from './attaform-dev.Bu6wgrA5.mjs';
|
|
4
|
+
import { R as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, d as armDomBinding, r as recordInheritedModifiers, w as withInheritedModifiers } from './attaform-dev.CKSqs_xQ.mjs';
|
|
5
|
+
import { e as canonicalizePath, i as isPathPrefix, f as pathsEqual, k as keyForSegments, m as mapSegmentKeys, b as ROOT_PATH_KEY, S as 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-dev.04aupFBW.mjs';
|
|
6
|
+
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, l as reportConsumerThrow } from './attaform-dev.DoG8mZTq.mjs';
|
|
79
7
|
|
|
80
8
|
function isGateOpen(field, formMeta) {
|
|
81
9
|
return formMeta.submissionAttempts > 0 || field.blurredAfterInteraction === true;
|
|
@@ -141,7 +69,7 @@ function hashStableString(input, seed = 0) {
|
|
|
141
69
|
const ANON_STEM = "atta";
|
|
142
70
|
function readableFormKeyStem(formKey) {
|
|
143
71
|
if (formKey === "" || formKey.startsWith(ANONYMOUS_FORM_KEY_PREFIX)) return ANON_STEM;
|
|
144
|
-
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|(
|
|
72
|
+
const sanitized = formKey.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|([^-])-+$/g, "$1");
|
|
145
73
|
return sanitized === "" ? ANON_STEM : sanitized;
|
|
146
74
|
}
|
|
147
75
|
function fieldIdToken(formInstanceId, pathKey) {
|
|
@@ -175,323 +103,6 @@ function humanize(segment) {
|
|
|
175
103
|
}).join(" ");
|
|
176
104
|
}
|
|
177
105
|
|
|
178
|
-
const NOT_FOUND = /* @__PURE__ */ Symbol("NOT_FOUND");
|
|
179
|
-
function mapKeyForSegment(map, segment, declared) {
|
|
180
|
-
if (map.has(segment)) return segment;
|
|
181
|
-
if (typeof segment !== "number") return segment;
|
|
182
|
-
const asString = String(segment);
|
|
183
|
-
if (map.has(asString)) return asString;
|
|
184
|
-
return declared === "string" ? asString : segment;
|
|
185
|
-
}
|
|
186
|
-
function isRebuildableContainer(root, segment) {
|
|
187
|
-
if (root === null || root === void 0 || typeof root !== "object") return true;
|
|
188
|
-
return typeof segment === "number" ? Array.isArray(root) : isPlainRecord(root);
|
|
189
|
-
}
|
|
190
|
-
function descendStep(value, segment) {
|
|
191
|
-
if (value === null || value === void 0) return NOT_FOUND;
|
|
192
|
-
if (typeof value !== "object") return NOT_FOUND;
|
|
193
|
-
if (Array.isArray(value)) {
|
|
194
|
-
if (typeof segment !== "number") return NOT_FOUND;
|
|
195
|
-
if (!(segment in value)) return NOT_FOUND;
|
|
196
|
-
return value[segment];
|
|
197
|
-
}
|
|
198
|
-
if (value instanceof Map) {
|
|
199
|
-
const key2 = mapKeyForSegment(value, segment);
|
|
200
|
-
if (!value.has(key2)) return NOT_FOUND;
|
|
201
|
-
return value.get(key2);
|
|
202
|
-
}
|
|
203
|
-
const record = value;
|
|
204
|
-
const key = typeof segment === "number" ? String(segment) : segment;
|
|
205
|
-
if (isShadowedKey(key)) {
|
|
206
|
-
if (!safeOwnHas(record, key)) return NOT_FOUND;
|
|
207
|
-
return safeOwnRead(record, key);
|
|
208
|
-
}
|
|
209
|
-
if (!(key in record)) return NOT_FOUND;
|
|
210
|
-
return record[key];
|
|
211
|
-
}
|
|
212
|
-
function getAtPath(root, path) {
|
|
213
|
-
if (path.length === 0) return root;
|
|
214
|
-
try {
|
|
215
|
-
let current = root;
|
|
216
|
-
for (const segment of path) {
|
|
217
|
-
const next = descendStep(current, segment);
|
|
218
|
-
if (next === NOT_FOUND) return void 0;
|
|
219
|
-
current = next;
|
|
220
|
-
}
|
|
221
|
-
return current;
|
|
222
|
-
} catch {
|
|
223
|
-
return void 0;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function hasAtPath(root, path) {
|
|
227
|
-
if (path.length === 0) return true;
|
|
228
|
-
try {
|
|
229
|
-
return hasAtPathUnguarded(root, path);
|
|
230
|
-
} catch {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
function hasAtPathUnguarded(root, path) {
|
|
235
|
-
let current = root;
|
|
236
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
237
|
-
const segment = path[i];
|
|
238
|
-
const next = descendStep(current, segment);
|
|
239
|
-
if (next === NOT_FOUND) return false;
|
|
240
|
-
current = next;
|
|
241
|
-
}
|
|
242
|
-
const last = path[path.length - 1];
|
|
243
|
-
if (current === null || current === void 0) return false;
|
|
244
|
-
if (typeof current !== "object") return false;
|
|
245
|
-
if (Array.isArray(current)) {
|
|
246
|
-
return typeof last === "number" && consumerHas(current, last);
|
|
247
|
-
}
|
|
248
|
-
if (current instanceof Map) {
|
|
249
|
-
return current.has(mapKeyForSegment(current, last));
|
|
250
|
-
}
|
|
251
|
-
const key = typeof last === "number" ? String(last) : last;
|
|
252
|
-
if (isShadowedKey(key)) return safeOwnHas(current, key);
|
|
253
|
-
return consumerHas(current, key);
|
|
254
|
-
}
|
|
255
|
-
function isPlainRecord(value) {
|
|
256
|
-
if (value === null || typeof value !== "object") return false;
|
|
257
|
-
if (Array.isArray(value)) return false;
|
|
258
|
-
const proto = Object.getPrototypeOf(value);
|
|
259
|
-
return proto === null || proto === Object.prototype;
|
|
260
|
-
}
|
|
261
|
-
const NO_SCHEMA_DEFAULTS = /* @__PURE__ */ new Set();
|
|
262
|
-
const NO_SCHEMA_FILL = {
|
|
263
|
-
getDefaultAtPath: () => void 0,
|
|
264
|
-
arrayShapeAtPath: () => null,
|
|
265
|
-
getSlimPrimitiveTypesAtPath: () => NO_SCHEMA_DEFAULTS,
|
|
266
|
-
entryKeyKindAtPath: () => void 0
|
|
267
|
-
};
|
|
268
|
-
function setAtPath(root, path, value) {
|
|
269
|
-
return setAtPathWithSchemaFill(root, NO_SCHEMA_FILL, path, value);
|
|
270
|
-
}
|
|
271
|
-
const NO_IN_PLACE = { applied: false };
|
|
272
|
-
function tryInPlaceLeafWrite(root, path, value) {
|
|
273
|
-
if (path.length === 0) return NO_IN_PLACE;
|
|
274
|
-
try {
|
|
275
|
-
return descendAndWrite(root, path, value);
|
|
276
|
-
} catch {
|
|
277
|
-
return NO_IN_PLACE;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
function descendAndWrite(root, path, value) {
|
|
281
|
-
let node = root;
|
|
282
|
-
for (let i = 0; i < path.length; i++) {
|
|
283
|
-
const seg = path[i];
|
|
284
|
-
if (node instanceof Map) return NO_IN_PLACE;
|
|
285
|
-
if (Array.isArray(node)) {
|
|
286
|
-
if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
|
|
287
|
-
} else if (isPlainRecord(node)) {
|
|
288
|
-
if (typeof seg !== "string" || isShadowedKey(seg) || !(seg in node)) return NO_IN_PLACE;
|
|
289
|
-
} else {
|
|
290
|
-
return NO_IN_PLACE;
|
|
291
|
-
}
|
|
292
|
-
const container = node;
|
|
293
|
-
if (i < path.length - 1) {
|
|
294
|
-
node = container[seg];
|
|
295
|
-
continue;
|
|
296
|
-
}
|
|
297
|
-
const old = container[seg];
|
|
298
|
-
if (isPlainRecord(old) || Array.isArray(old)) return NO_IN_PLACE;
|
|
299
|
-
container[seg] = value;
|
|
300
|
-
return { applied: true, old };
|
|
301
|
-
}
|
|
302
|
-
return NO_IN_PLACE;
|
|
303
|
-
}
|
|
304
|
-
function mergeStructural(schema, path, consumer, defaultValue = schema.getDefaultAtPath(path)) {
|
|
305
|
-
const scratch = path.slice();
|
|
306
|
-
return mergeStructuralImpl(schema, scratch, consumer, defaultValue);
|
|
307
|
-
}
|
|
308
|
-
function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
|
|
309
|
-
if (consumer === void 0) {
|
|
310
|
-
if (schema.getSlimPrimitiveTypesAtPath(scratch).has("undefined")) {
|
|
311
|
-
return void 0;
|
|
312
|
-
}
|
|
313
|
-
return defaultValue;
|
|
314
|
-
}
|
|
315
|
-
if (consumer === null) return null;
|
|
316
|
-
if (Array.isArray(consumer)) {
|
|
317
|
-
return mergeStructuralArray(schema, scratch, consumer);
|
|
318
|
-
}
|
|
319
|
-
if (consumer instanceof Map) {
|
|
320
|
-
return mergeStructuralMap(schema, scratch, consumer);
|
|
321
|
-
}
|
|
322
|
-
if (isPlainRecord(consumer)) {
|
|
323
|
-
if (!isPlainRecord(defaultValue)) {
|
|
324
|
-
return consumer;
|
|
325
|
-
}
|
|
326
|
-
const out = spreadConsumerRecord(consumer);
|
|
327
|
-
const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
|
|
328
|
-
const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
|
|
329
|
-
return filledAny || recursedAny ? out : consumer;
|
|
330
|
-
}
|
|
331
|
-
return consumer;
|
|
332
|
-
}
|
|
333
|
-
function mergeStructuralMap(schema, scratch, consumer) {
|
|
334
|
-
if (consumer.size === 0) return consumer;
|
|
335
|
-
let entryDefault;
|
|
336
|
-
let entryDefaultRead = false;
|
|
337
|
-
let out = null;
|
|
338
|
-
for (const [key, entry] of consumer) {
|
|
339
|
-
if (typeof key !== "string" && typeof key !== "number") continue;
|
|
340
|
-
scratch.push(key);
|
|
341
|
-
if (!entryDefaultRead) {
|
|
342
|
-
entryDefault = schema.getDefaultAtPath(scratch);
|
|
343
|
-
entryDefaultRead = true;
|
|
344
|
-
}
|
|
345
|
-
const merged = mergeStructuralImpl(schema, scratch, entry, entryDefault);
|
|
346
|
-
scratch.pop();
|
|
347
|
-
if (merged === entry) continue;
|
|
348
|
-
out ?? (out = new Map(consumer));
|
|
349
|
-
out.set(key, merged);
|
|
350
|
-
}
|
|
351
|
-
return out ?? consumer;
|
|
352
|
-
}
|
|
353
|
-
function mergeStructuralArray(schema, scratch, consumer) {
|
|
354
|
-
const shape = schema.arrayShapeAtPath(scratch);
|
|
355
|
-
const isTuple = typeof shape === "number";
|
|
356
|
-
const targetLen = isTuple ? shape : consumer.length;
|
|
357
|
-
let cachedElementDefault;
|
|
358
|
-
let cachedElementDefaultRead = false;
|
|
359
|
-
let mutated = targetLen > consumer.length;
|
|
360
|
-
const out = copyConsumerArray(consumer);
|
|
361
|
-
while (out.length < targetLen) out.push(void 0);
|
|
362
|
-
for (let i = 0; i < targetLen; i++) {
|
|
363
|
-
scratch.push(i);
|
|
364
|
-
let elemDefault;
|
|
365
|
-
if (isTuple) {
|
|
366
|
-
elemDefault = schema.getDefaultAtPath(scratch);
|
|
367
|
-
} else {
|
|
368
|
-
if (!cachedElementDefaultRead) {
|
|
369
|
-
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
370
|
-
cachedElementDefaultRead = true;
|
|
371
|
-
}
|
|
372
|
-
elemDefault = cachedElementDefault;
|
|
373
|
-
}
|
|
374
|
-
const consumerElem = i < consumer.length ? readConsumerIndex(consumer, i) : void 0;
|
|
375
|
-
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
376
|
-
scratch.pop();
|
|
377
|
-
if (merged !== consumerElem) {
|
|
378
|
-
out[i] = merged;
|
|
379
|
-
mutated = true;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return mutated ? out : consumer;
|
|
383
|
-
}
|
|
384
|
-
function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
|
|
385
|
-
let mutated = false;
|
|
386
|
-
for (const key of Object.keys(defaultValue)) {
|
|
387
|
-
if (!safeOwnHas(consumer, key)) {
|
|
388
|
-
const defAtKey = safeOwnRead(defaultValue, key);
|
|
389
|
-
scratch.push(key);
|
|
390
|
-
const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
|
|
391
|
-
scratch.pop();
|
|
392
|
-
if (filled !== void 0) {
|
|
393
|
-
safeAssign(out, key, filled);
|
|
394
|
-
mutated = true;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
return mutated;
|
|
399
|
-
}
|
|
400
|
-
function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
|
|
401
|
-
let mutated = false;
|
|
402
|
-
for (const key of consumerKeys(consumer)) {
|
|
403
|
-
const cVal = safeOwnRead(consumer, key);
|
|
404
|
-
if (cVal === void 0) continue;
|
|
405
|
-
scratch.push(key);
|
|
406
|
-
const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
|
|
407
|
-
scratch.pop();
|
|
408
|
-
if (merged !== cVal) {
|
|
409
|
-
safeAssign(out, key, merged);
|
|
410
|
-
mutated = true;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return mutated;
|
|
414
|
-
}
|
|
415
|
-
function setAtPathWithSchemaFill(root, schema, fullPath, value) {
|
|
416
|
-
if (fullPath.length === 0) return value;
|
|
417
|
-
return setAtPathWithSchemaFillImpl(root, schema, fullPath, value, 0);
|
|
418
|
-
}
|
|
419
|
-
function setAtPathWithSchemaFillImpl(root, schema, fullPath, value, startIdx) {
|
|
420
|
-
if (startIdx >= fullPath.length) return value;
|
|
421
|
-
const head = fullPath[startIdx];
|
|
422
|
-
const isLeafStep = startIdx === fullPath.length - 1;
|
|
423
|
-
if (root instanceof Map) {
|
|
424
|
-
const next = new Map(root);
|
|
425
|
-
const key = mapKeyForSegment(root, head, schema.entryKeyKindAtPath(fullPath.slice(0, startIdx)));
|
|
426
|
-
if (isLeafStep) {
|
|
427
|
-
next.set(key, value);
|
|
428
|
-
return next;
|
|
429
|
-
}
|
|
430
|
-
let childRoot2 = next.get(key);
|
|
431
|
-
if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
|
|
432
|
-
childRoot2 = schema.getDefaultAtPath(fullPath.slice(0, startIdx + 1));
|
|
433
|
-
}
|
|
434
|
-
next.set(key, setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1));
|
|
435
|
-
return next;
|
|
436
|
-
}
|
|
437
|
-
if (!isRebuildableContainer(root, head)) return root;
|
|
438
|
-
if (typeof head === "number") {
|
|
439
|
-
const arr = Array.isArray(root) ? [...root] : [];
|
|
440
|
-
const prefix = fullPath.slice(0, startIdx);
|
|
441
|
-
if (arr.length < head) {
|
|
442
|
-
const scratch = prefix.slice();
|
|
443
|
-
const shape = schema.arrayShapeAtPath(scratch);
|
|
444
|
-
const tupleLike = typeof shape === "number";
|
|
445
|
-
let cachedArrayDefault;
|
|
446
|
-
if (!tupleLike) {
|
|
447
|
-
scratch.push(0);
|
|
448
|
-
cachedArrayDefault = schema.getDefaultAtPath(scratch);
|
|
449
|
-
scratch.pop();
|
|
450
|
-
}
|
|
451
|
-
while (arr.length < head) {
|
|
452
|
-
const idx = arr.length;
|
|
453
|
-
if (tupleLike) {
|
|
454
|
-
scratch.push(idx);
|
|
455
|
-
arr.push(schema.getDefaultAtPath(scratch));
|
|
456
|
-
scratch.pop();
|
|
457
|
-
} else {
|
|
458
|
-
arr.push(cachedArrayDefault);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
if (isLeafStep) {
|
|
463
|
-
arr[head] = value;
|
|
464
|
-
return arr;
|
|
465
|
-
}
|
|
466
|
-
let childRoot2 = arr[head];
|
|
467
|
-
if (childRoot2 === void 0 || childRoot2 !== null && typeof childRoot2 !== "object") {
|
|
468
|
-
childRoot2 = schema.getDefaultAtPath([...prefix, head]);
|
|
469
|
-
}
|
|
470
|
-
arr[head] = setAtPathWithSchemaFillImpl(childRoot2, schema, fullPath, value, startIdx + 1);
|
|
471
|
-
return arr;
|
|
472
|
-
}
|
|
473
|
-
const rec = isPlainRecord(root) ? { ...root } : {};
|
|
474
|
-
if (isLeafStep) {
|
|
475
|
-
safeAssign(rec, head, value);
|
|
476
|
-
return rec;
|
|
477
|
-
}
|
|
478
|
-
const existing = safeOwnRead(rec, head);
|
|
479
|
-
let childRoot;
|
|
480
|
-
if (existing === void 0 || existing !== null && typeof existing !== "object") {
|
|
481
|
-
const intermPath = [...fullPath.slice(0, startIdx + 1)];
|
|
482
|
-
const intermDefault = schema.getDefaultAtPath(intermPath);
|
|
483
|
-
childRoot = intermDefault;
|
|
484
|
-
} else {
|
|
485
|
-
childRoot = existing;
|
|
486
|
-
}
|
|
487
|
-
safeAssign(
|
|
488
|
-
rec,
|
|
489
|
-
head,
|
|
490
|
-
setAtPathWithSchemaFillImpl(childRoot, schema, fullPath, value, startIdx + 1)
|
|
491
|
-
);
|
|
492
|
-
return rec;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
106
|
function isUnderStubAncestor(state, segments) {
|
|
496
107
|
for (let i = 0; i < segments.length; i++) {
|
|
497
108
|
const ancestorPath = segments.slice(0, i);
|
|
@@ -627,7 +238,6 @@ function visitActiveLeafPaths(value, base, visit) {
|
|
|
627
238
|
function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
628
239
|
const formValue = state.form.value;
|
|
629
240
|
const value = getAtPath(formValue, segments);
|
|
630
|
-
const original = state.originals.get(key)?.value;
|
|
631
241
|
let pristine = true;
|
|
632
242
|
let blank = true;
|
|
633
243
|
let dirty = false;
|
|
@@ -645,6 +255,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
645
255
|
let asyncPending = false;
|
|
646
256
|
const submissionAttempts = state.submissionAttempts.value;
|
|
647
257
|
const blurredLeafSegments = [];
|
|
258
|
+
const errorsByKey = errorBucketsAt(state, segments, key);
|
|
648
259
|
const descendantLeaves = [];
|
|
649
260
|
visitActiveLeafPaths(value, segments, (leafSegments) => {
|
|
650
261
|
const { key: leafKey } = keyForSegments(leafSegments);
|
|
@@ -654,6 +265,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
654
265
|
});
|
|
655
266
|
for (const { key: leafKey, segments: leafSeg } of descendantLeaves) {
|
|
656
267
|
const leafRecord = state.fields.get(leafKey);
|
|
268
|
+
const leafErrors = errorsByKey.get(leafKey);
|
|
269
|
+
if (leafErrors !== void 0) leafErrors.walked = true;
|
|
657
270
|
if (!state.isPristineAtPathByKey(leafKey, leafSeg)) {
|
|
658
271
|
pristine = false;
|
|
659
272
|
dirty = true;
|
|
@@ -688,22 +301,28 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
688
301
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
689
302
|
}
|
|
690
303
|
}
|
|
691
|
-
if (!dirty && state.
|
|
304
|
+
if (!dirty && !(Array.isArray(value) || isPlainRecord(value)) && !state.isPristineAtPathByKey(key, segments)) {
|
|
692
305
|
pristine = false;
|
|
693
306
|
dirty = true;
|
|
694
307
|
}
|
|
695
|
-
if (!dirty && state.
|
|
308
|
+
if (!dirty && state.hasStructuralChangeUnder(segments, key)) {
|
|
696
309
|
pristine = false;
|
|
697
310
|
dirty = true;
|
|
698
311
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
312
|
+
if (!dirty && state.hasRemovedSubtreeUnder(segments, key)) {
|
|
313
|
+
pristine = false;
|
|
314
|
+
dirty = true;
|
|
315
|
+
}
|
|
316
|
+
const errorBuckets = sortErrorBuckets(errorsByKey);
|
|
317
|
+
const errors = flattenErrorBuckets(errorBuckets);
|
|
318
|
+
const revealedDescendantError = errors.length > 0 && descendantErrorRevealed(
|
|
319
|
+
state,
|
|
320
|
+
segments,
|
|
321
|
+
errorBuckets,
|
|
322
|
+
submissionAttempts,
|
|
323
|
+
blurredAfterInteraction,
|
|
324
|
+
blurredLeafSegments
|
|
325
|
+
);
|
|
707
326
|
if (!asyncPending && state.pathHasAsyncValidationByKey(key, segments)) asyncPending = true;
|
|
708
327
|
if ((state.fieldValidationCounts.get(key) ?? 0) > 0) {
|
|
709
328
|
validating = true;
|
|
@@ -725,6 +344,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
725
344
|
if (ownRecord.interacted === true) interacted = true;
|
|
726
345
|
if (ownRecord.blurredAfterInteraction === true) blurredAfterInteraction = true;
|
|
727
346
|
if (ownRecord.connected === true) connected = true;
|
|
347
|
+
const ts = ownRecord.updatedAt;
|
|
348
|
+
if (ts !== null && (updatedAt === null || ts > updatedAt)) updatedAt = ts;
|
|
728
349
|
}
|
|
729
350
|
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
730
351
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
@@ -733,7 +354,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
733
354
|
return {
|
|
734
355
|
base: {
|
|
735
356
|
value,
|
|
736
|
-
original,
|
|
357
|
+
original: state.getOriginalAtPath(segments),
|
|
737
358
|
pristine,
|
|
738
359
|
dirty,
|
|
739
360
|
focused,
|
|
@@ -816,9 +437,41 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
816
437
|
firstOwnError
|
|
817
438
|
};
|
|
818
439
|
}
|
|
440
|
+
function descendantErrorRevealed(state, segments, buckets, submissionAttempts, blurredAfterInteraction, blurredLeafSegments) {
|
|
441
|
+
for (const bucket of buckets) {
|
|
442
|
+
let ownHistory;
|
|
443
|
+
for (const e of bucket.errors) {
|
|
444
|
+
const ePath = e.path;
|
|
445
|
+
if (pathsEqual(ePath, segments)) continue;
|
|
446
|
+
if (submissionAttempts > 0) return true;
|
|
447
|
+
if (ePath.length === 1 && ePath[0] === "") {
|
|
448
|
+
if (blurredAfterInteraction) return true;
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
for (const leaf of blurredLeafSegments) if (isPathPrefix(ePath, leaf)) return true;
|
|
452
|
+
if (bucket.walked) continue;
|
|
453
|
+
ownHistory ?? (ownHistory = state.fields.get(bucket.key)?.blurredAfterInteraction === true);
|
|
454
|
+
if (ownHistory) return true;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
819
459
|
function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
460
|
+
return flattenErrorBuckets(sortErrorBuckets(errorBucketsAt(state, prefix, prefixKey)));
|
|
461
|
+
}
|
|
462
|
+
const NO_ERROR_BUCKETS = /* @__PURE__ */ new Map();
|
|
463
|
+
function sortErrorBuckets(buckets) {
|
|
464
|
+
if (buckets.size <= 1) return [...buckets.values()];
|
|
465
|
+
return [...buckets.values()].sort((a, b) => a.ordinal - b.ordinal);
|
|
466
|
+
}
|
|
467
|
+
function flattenErrorBuckets(buckets) {
|
|
468
|
+
if (buckets.length === 0) return [];
|
|
469
|
+
if (buckets.length === 1) return buckets[0]?.errors ?? [];
|
|
470
|
+
return buckets.flatMap((bucket) => bucket.errors);
|
|
471
|
+
}
|
|
472
|
+
function errorBucketsAt(state, prefix, prefixKey) {
|
|
820
473
|
const candidates = state.errorWindowAt(prefix, prefixKey);
|
|
821
|
-
if (candidates.length === 0) return
|
|
474
|
+
if (candidates.length === 0) return NO_ERROR_BUCKETS;
|
|
822
475
|
const formValue = state.form.value;
|
|
823
476
|
const cells = state.errorCells();
|
|
824
477
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -831,19 +484,16 @@ function aggregateErrorsAt(state, prefix, prefixKey) {
|
|
|
831
484
|
const userList = cell?.user;
|
|
832
485
|
const total = (schemaList?.length ?? 0) + (blankList?.length ?? 0) + (userList?.length ?? 0);
|
|
833
486
|
if (total === 0) continue;
|
|
834
|
-
|
|
835
|
-
let bucket = buckets.get(ordinal);
|
|
487
|
+
let bucket = buckets.get(key);
|
|
836
488
|
if (bucket === void 0) {
|
|
837
|
-
bucket = [];
|
|
838
|
-
buckets.set(
|
|
489
|
+
bucket = { key, ordinal: state.ensurePathOrdinal(key), errors: [], walked: false };
|
|
490
|
+
buckets.set(key, bucket);
|
|
839
491
|
}
|
|
840
|
-
if (schemaList !== void 0) bucket.push(...schemaList);
|
|
841
|
-
if (blankList !== void 0) bucket.push(...blankList);
|
|
842
|
-
if (userList !== void 0) bucket.push(...userList);
|
|
492
|
+
if (schemaList !== void 0) bucket.errors.push(...schemaList);
|
|
493
|
+
if (blankList !== void 0) bucket.errors.push(...blankList);
|
|
494
|
+
if (userList !== void 0) bucket.errors.push(...userList);
|
|
843
495
|
}
|
|
844
|
-
|
|
845
|
-
if (buckets.size === 1) return [...buckets.values()][0];
|
|
846
|
-
return [...buckets.entries()].sort(([a], [b]) => a - b).flatMap(([, errs]) => errs);
|
|
496
|
+
return buckets;
|
|
847
497
|
}
|
|
848
498
|
const EMPTY_ELEMENTS = Object.freeze([]);
|
|
849
499
|
|
|
@@ -875,7 +525,7 @@ function liveContainerHasKey(state, segments, key) {
|
|
|
875
525
|
return Number.isInteger(index) && index >= 0 && String(index) === key && value.has(index);
|
|
876
526
|
}
|
|
877
527
|
if (value instanceof Set) return false;
|
|
878
|
-
return
|
|
528
|
+
return safeOwnHas(value, key);
|
|
879
529
|
}
|
|
880
530
|
function isArrayPath(state, segments) {
|
|
881
531
|
if (segments.length === 0) return false;
|
|
@@ -1410,406 +1060,6 @@ function buildValuesSurface(form, onFormChange) {
|
|
|
1410
1060
|
});
|
|
1411
1061
|
}
|
|
1412
1062
|
|
|
1413
|
-
function remapForOp(op, oldLen) {
|
|
1414
|
-
const moved = /* @__PURE__ */ new Map();
|
|
1415
|
-
const vacated = /* @__PURE__ */ new Set();
|
|
1416
|
-
const fresh = /* @__PURE__ */ new Set();
|
|
1417
|
-
let newLen = oldLen;
|
|
1418
|
-
switch (op.kind) {
|
|
1419
|
-
case "insert":
|
|
1420
|
-
for (let i = op.index; i < oldLen; i++) moved.set(i, i + 1);
|
|
1421
|
-
fresh.add(op.index);
|
|
1422
|
-
newLen = oldLen + 1;
|
|
1423
|
-
break;
|
|
1424
|
-
case "remove":
|
|
1425
|
-
vacated.add(op.index);
|
|
1426
|
-
for (let i = op.index + 1; i < oldLen; i++) moved.set(i, i - 1);
|
|
1427
|
-
newLen = Math.max(0, oldLen - 1);
|
|
1428
|
-
break;
|
|
1429
|
-
case "move":
|
|
1430
|
-
if (op.from !== op.to) {
|
|
1431
|
-
moved.set(op.from, op.to);
|
|
1432
|
-
if (op.from < op.to) {
|
|
1433
|
-
for (let i = op.from + 1; i <= op.to; i++) moved.set(i, i - 1);
|
|
1434
|
-
} else {
|
|
1435
|
-
for (let i = op.to; i < op.from; i++) moved.set(i, i + 1);
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
break;
|
|
1439
|
-
case "swap":
|
|
1440
|
-
if (op.a !== op.b) {
|
|
1441
|
-
moved.set(op.a, op.b);
|
|
1442
|
-
moved.set(op.b, op.a);
|
|
1443
|
-
}
|
|
1444
|
-
break;
|
|
1445
|
-
case "replace-at":
|
|
1446
|
-
vacated.add(op.index);
|
|
1447
|
-
fresh.add(op.index);
|
|
1448
|
-
break;
|
|
1449
|
-
}
|
|
1450
|
-
return { moved, vacated, fresh, oldLen, newLen };
|
|
1451
|
-
}
|
|
1452
|
-
function changedIndices(remap) {
|
|
1453
|
-
const changed = new Set(remap.vacated);
|
|
1454
|
-
for (const [from, to] of remap.moved) {
|
|
1455
|
-
changed.add(from);
|
|
1456
|
-
changed.add(to);
|
|
1457
|
-
}
|
|
1458
|
-
for (const index of remap.fresh) changed.add(index);
|
|
1459
|
-
return changed;
|
|
1460
|
-
}
|
|
1461
|
-
function permuteList(list, remap, fill) {
|
|
1462
|
-
const claimed = new Array(remap.newLen);
|
|
1463
|
-
for (let i = 0; i < remap.oldLen; i++) {
|
|
1464
|
-
if (remap.vacated.has(i)) continue;
|
|
1465
|
-
const to = remap.moved.get(i) ?? i;
|
|
1466
|
-
if (to < remap.newLen) claimed[to] = list[i];
|
|
1467
|
-
}
|
|
1468
|
-
const next = [];
|
|
1469
|
-
for (let i = 0; i < remap.newLen; i++) {
|
|
1470
|
-
next.push(claimed[i] ?? fill());
|
|
1471
|
-
}
|
|
1472
|
-
return next;
|
|
1473
|
-
}
|
|
1474
|
-
function elementIndexUnder(arrayPath, key, idxPos) {
|
|
1475
|
-
const segments = segmentsForPathKey(key);
|
|
1476
|
-
if (segments === null) return null;
|
|
1477
|
-
if (!isPathPrefix(arrayPath, segments)) return null;
|
|
1478
|
-
if (segments.length <= idxPos) return null;
|
|
1479
|
-
const index = segments[idxPos];
|
|
1480
|
-
return typeof index === "number" ? index : null;
|
|
1481
|
-
}
|
|
1482
|
-
function collectKeysAtIndices(keys, arrayPath, member) {
|
|
1483
|
-
const idxPos = arrayPath.length;
|
|
1484
|
-
const hits = [];
|
|
1485
|
-
for (const key of keys) {
|
|
1486
|
-
const index = elementIndexUnder(arrayPath, key, idxPos);
|
|
1487
|
-
if (index === null || !member(index)) continue;
|
|
1488
|
-
const segments = segmentsForPathKey(key);
|
|
1489
|
-
if (segments === null) continue;
|
|
1490
|
-
hits.push({ key, segments: [...segments], index });
|
|
1491
|
-
}
|
|
1492
|
-
return hits;
|
|
1493
|
-
}
|
|
1494
|
-
function remapAffects(remap) {
|
|
1495
|
-
return (index) => remap.moved.has(index) || remap.vacated.has(index) || remap.fresh.has(index);
|
|
1496
|
-
}
|
|
1497
|
-
function migrateMapSubtree(map, arrayPath, remap, rewriteValue) {
|
|
1498
|
-
const hits = collectKeysAtIndices(map.keys(), arrayPath, remapAffects(remap));
|
|
1499
|
-
if (hits.length === 0) return;
|
|
1500
|
-
const idxPos = arrayPath.length;
|
|
1501
|
-
const snapshots = [];
|
|
1502
|
-
for (const hit of hits) {
|
|
1503
|
-
const value = map.get(hit.key);
|
|
1504
|
-
if (value !== void 0) snapshots.push({ ...hit, value });
|
|
1505
|
-
}
|
|
1506
|
-
for (const snap of snapshots) map.delete(snap.key);
|
|
1507
|
-
for (const snap of snapshots) {
|
|
1508
|
-
const target = remap.moved.get(snap.index);
|
|
1509
|
-
if (target === void 0) continue;
|
|
1510
|
-
const relocated = snap.segments.slice();
|
|
1511
|
-
relocated[idxPos] = target;
|
|
1512
|
-
map.set(canonicalizePath(relocated).key, rewriteValue(snap.value, relocated));
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
function migrateSetSubtree(set, arrayPath, remap) {
|
|
1516
|
-
const hits = collectKeysAtIndices(set, arrayPath, remapAffects(remap));
|
|
1517
|
-
if (hits.length === 0) return;
|
|
1518
|
-
const idxPos = arrayPath.length;
|
|
1519
|
-
for (const hit of hits) set.delete(hit.key);
|
|
1520
|
-
for (const hit of hits) {
|
|
1521
|
-
const target = remap.moved.get(hit.index);
|
|
1522
|
-
if (target === void 0) continue;
|
|
1523
|
-
const relocated = hit.segments.slice();
|
|
1524
|
-
relocated[idxPos] = target;
|
|
1525
|
-
set.add(canonicalizePath(relocated).key);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
function evictSchemaVerdictsAtIndices(errorCells, arrayPath, indices) {
|
|
1529
|
-
for (const hit of collectKeysAtIndices(
|
|
1530
|
-
[...errorCells.keys()],
|
|
1531
|
-
arrayPath,
|
|
1532
|
-
(index) => indices.has(index)
|
|
1533
|
-
)) {
|
|
1534
|
-
const cell = errorCells.get(hit.key);
|
|
1535
|
-
if (cell === void 0) continue;
|
|
1536
|
-
if (cell.user.length === 0) errorCells.delete(hit.key);
|
|
1537
|
-
else if (cell.schema.length > 0) errorCells.set(hit.key, { schema: NO_ERRORS, user: cell.user });
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
function deleteKeysAtIndices(keys, del, arrayPath, indices) {
|
|
1541
|
-
for (const hit of collectKeysAtIndices(keys, arrayPath, (index) => indices.has(index))) {
|
|
1542
|
-
del(hit.key);
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
function createArrayIdentity(getArrayLength) {
|
|
1546
|
-
const tokens = /* @__PURE__ */ new Map();
|
|
1547
|
-
const baselines = /* @__PURE__ */ new Map();
|
|
1548
|
-
let counter = 0;
|
|
1549
|
-
const allocate = () => `k${(counter++).toString(36)}`;
|
|
1550
|
-
function ensure(arrayKey, expectedLen) {
|
|
1551
|
-
let ids = tokens.get(arrayKey);
|
|
1552
|
-
const firstTrack = ids === void 0;
|
|
1553
|
-
if (ids === void 0) {
|
|
1554
|
-
ids = [];
|
|
1555
|
-
tokens.set(arrayKey, ids);
|
|
1556
|
-
}
|
|
1557
|
-
while (ids.length < expectedLen) ids.push(allocate());
|
|
1558
|
-
if (ids.length > expectedLen) ids.length = expectedLen;
|
|
1559
|
-
if (firstTrack) baselines.set(arrayKey, [...ids]);
|
|
1560
|
-
return ids;
|
|
1561
|
-
}
|
|
1562
|
-
function orderPristineForKey(arrayKey) {
|
|
1563
|
-
const baseline = baselines.get(arrayKey);
|
|
1564
|
-
const current = tokens.get(arrayKey);
|
|
1565
|
-
if (baseline === void 0 || current === void 0) return true;
|
|
1566
|
-
if (baseline.length !== current.length) return false;
|
|
1567
|
-
for (let i = 0; i < current.length; i++) {
|
|
1568
|
-
if (current[i] !== baseline[i]) return false;
|
|
1569
|
-
}
|
|
1570
|
-
return true;
|
|
1571
|
-
}
|
|
1572
|
-
return {
|
|
1573
|
-
tokenAt(arraySegs, index) {
|
|
1574
|
-
const len = getArrayLength(arraySegs);
|
|
1575
|
-
if (index < 0 || index >= len) return "";
|
|
1576
|
-
const ids = ensure(canonicalizePath(arraySegs).key, len);
|
|
1577
|
-
return ids[index] ?? "";
|
|
1578
|
-
},
|
|
1579
|
-
applyOp(arraySegs, remap) {
|
|
1580
|
-
const arrayKey = canonicalizePath(arraySegs).key;
|
|
1581
|
-
const ids = ensure(arrayKey, remap.oldLen);
|
|
1582
|
-
tokens.set(arrayKey, permuteList(ids, remap, allocate));
|
|
1583
|
-
},
|
|
1584
|
-
applyRemap(arrayPath, remap) {
|
|
1585
|
-
if (remap.moved.size === 0 && remap.vacated.size === 0 && remap.fresh.size === 0) return;
|
|
1586
|
-
migrateMapSubtree(tokens, arrayPath, remap, (value) => value);
|
|
1587
|
-
migrateMapSubtree(baselines, arrayPath, remap, (value) => value);
|
|
1588
|
-
},
|
|
1589
|
-
realign(arraySegs) {
|
|
1590
|
-
ensure(canonicalizePath(arraySegs).key, getArrayLength(arraySegs));
|
|
1591
|
-
},
|
|
1592
|
-
hasStructuralChangeUnder(prefix) {
|
|
1593
|
-
for (const arrayKey of tokens.keys()) {
|
|
1594
|
-
if (orderPristineForKey(arrayKey)) continue;
|
|
1595
|
-
const segs = segmentsForPathKey(arrayKey);
|
|
1596
|
-
if (segs === null) continue;
|
|
1597
|
-
if (isPathPrefix(prefix, segs)) return true;
|
|
1598
|
-
}
|
|
1599
|
-
return false;
|
|
1600
|
-
},
|
|
1601
|
-
rebaselineAll() {
|
|
1602
|
-
for (const arrayKey of [...tokens.keys()]) {
|
|
1603
|
-
const segs = segmentsForPathKey(arrayKey);
|
|
1604
|
-
if (segs === null) continue;
|
|
1605
|
-
const ids = ensure(arrayKey, getArrayLength(segs));
|
|
1606
|
-
baselines.set(arrayKey, [...ids]);
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
};
|
|
1610
|
-
}
|
|
1611
|
-
function createVariantMemory() {
|
|
1612
|
-
const memory = /* @__PURE__ */ new Map();
|
|
1613
|
-
return {
|
|
1614
|
-
clear() {
|
|
1615
|
-
memory.clear();
|
|
1616
|
-
},
|
|
1617
|
-
clearUnderPath(parentPath) {
|
|
1618
|
-
for (const memKey of [...memory.keys()]) {
|
|
1619
|
-
const segs = segmentsForPathKey(memKey);
|
|
1620
|
-
if (segs === null) continue;
|
|
1621
|
-
if (isPathPrefix(parentPath, segs)) memory.delete(memKey);
|
|
1622
|
-
}
|
|
1623
|
-
},
|
|
1624
|
-
dropAtIndices(arrayPath, indices) {
|
|
1625
|
-
deleteKeysAtIndices([...memory.keys()], (key) => memory.delete(key), arrayPath, indices);
|
|
1626
|
-
},
|
|
1627
|
-
recordOutgoing(unionKey, discValue, snapshot) {
|
|
1628
|
-
let perUnion = memory.get(unionKey);
|
|
1629
|
-
if (perUnion === void 0) {
|
|
1630
|
-
perUnion = /* @__PURE__ */ new Map();
|
|
1631
|
-
memory.set(unionKey, perUnion);
|
|
1632
|
-
}
|
|
1633
|
-
perUnion.set(discValue, snapshot);
|
|
1634
|
-
},
|
|
1635
|
-
lookupIncoming(unionKey, discValue) {
|
|
1636
|
-
return memory.get(unionKey)?.get(discValue);
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
}
|
|
1640
|
-
function cloneVariantSnapshot(value) {
|
|
1641
|
-
if (value === null || typeof value !== "object") return value;
|
|
1642
|
-
const raw = toRaw(value);
|
|
1643
|
-
if (raw instanceof Date) return new Date(raw.getTime());
|
|
1644
|
-
if (raw instanceof Map) {
|
|
1645
|
-
const out2 = /* @__PURE__ */ new Map();
|
|
1646
|
-
for (const [k, v] of raw.entries()) out2.set(cloneVariantSnapshot(k), cloneVariantSnapshot(v));
|
|
1647
|
-
return out2;
|
|
1648
|
-
}
|
|
1649
|
-
if (raw instanceof Set) {
|
|
1650
|
-
const out2 = /* @__PURE__ */ new Set();
|
|
1651
|
-
for (const v of raw) out2.add(cloneVariantSnapshot(v));
|
|
1652
|
-
return out2;
|
|
1653
|
-
}
|
|
1654
|
-
if (raw instanceof RegExp) return new RegExp(raw.source, raw.flags);
|
|
1655
|
-
if (Array.isArray(raw)) {
|
|
1656
|
-
const out2 = new Array(raw.length);
|
|
1657
|
-
for (let i = 0; i < raw.length; i++) out2[i] = cloneVariantSnapshot(raw[i]);
|
|
1658
|
-
return out2;
|
|
1659
|
-
}
|
|
1660
|
-
if (!isPlainRecord(raw)) return raw;
|
|
1661
|
-
const src = raw;
|
|
1662
|
-
const out = {};
|
|
1663
|
-
for (const k of consumerKeys(src)) {
|
|
1664
|
-
safeAssign(out, k, cloneVariantSnapshot(readConsumerProp(src, k)));
|
|
1665
|
-
}
|
|
1666
|
-
return out;
|
|
1667
|
-
}
|
|
1668
|
-
function createArrayBookkeeping(deps) {
|
|
1669
|
-
const {
|
|
1670
|
-
form,
|
|
1671
|
-
fields,
|
|
1672
|
-
errorCells,
|
|
1673
|
-
originals,
|
|
1674
|
-
blankPaths,
|
|
1675
|
-
originalBlankPaths,
|
|
1676
|
-
authoredPaths,
|
|
1677
|
-
fieldValidationCounts,
|
|
1678
|
-
fieldValidatingSince,
|
|
1679
|
-
fieldValidationState,
|
|
1680
|
-
activeValidations,
|
|
1681
|
-
arrayIdentity,
|
|
1682
|
-
variantMemory,
|
|
1683
|
-
touchFieldRecord,
|
|
1684
|
-
decFieldValidation
|
|
1685
|
-
} = deps;
|
|
1686
|
-
function migrateElementState(arrayPath, remap) {
|
|
1687
|
-
if (remap.moved.size === 0 && remap.vacated.size === 0) return;
|
|
1688
|
-
migrateMapSubtree(fields, arrayPath, remap, (record, segments) => ({
|
|
1689
|
-
...record,
|
|
1690
|
-
path: segments
|
|
1691
|
-
}));
|
|
1692
|
-
migrateMapSubtree(errorCells(), arrayPath, remap, (cell, segments) => ({
|
|
1693
|
-
schema: NO_ERRORS,
|
|
1694
|
-
user: cell.user.map((error) => ({ ...error, path: [...segments] }))
|
|
1695
|
-
}));
|
|
1696
|
-
migrateMapSubtree(originals, arrayPath, remap, (record, segments) => ({
|
|
1697
|
-
segments,
|
|
1698
|
-
value: record.value
|
|
1699
|
-
}));
|
|
1700
|
-
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
1701
|
-
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
1702
|
-
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
1703
|
-
migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
|
|
1704
|
-
migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
|
|
1705
|
-
arrayIdentity.applyRemap(arrayPath, remap);
|
|
1706
|
-
}
|
|
1707
|
-
function seedFreshElement(arrayPath, freshIndex) {
|
|
1708
|
-
const elementPath = [...arrayPath, freshIndex];
|
|
1709
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1710
|
-
diffAndApply(void 0, getAtPath(form.value, elementPath), elementPath, (patch) => {
|
|
1711
|
-
if (patch.kind !== "added") return;
|
|
1712
|
-
const { key } = canonicalizePath(patch.path);
|
|
1713
|
-
if (!originals.has(key)) originals.set(key, { segments: patch.path, value: void 0 });
|
|
1714
|
-
touchFieldRecord(key, patch.path, { updatedAt: now });
|
|
1715
|
-
});
|
|
1716
|
-
}
|
|
1717
|
-
function abortValidationAtVacatedIndices(arrayPath, remap) {
|
|
1718
|
-
if (remap.vacated.size === 0) return;
|
|
1719
|
-
const hits = collectKeysAtIndices(
|
|
1720
|
-
[...fieldValidationState.keys()],
|
|
1721
|
-
arrayPath,
|
|
1722
|
-
(index) => remap.vacated.has(index)
|
|
1723
|
-
);
|
|
1724
|
-
for (const hit of hits) {
|
|
1725
|
-
const entry = fieldValidationState.get(hit.key);
|
|
1726
|
-
if (entry === void 0) continue;
|
|
1727
|
-
if (entry.timer !== null) {
|
|
1728
|
-
clearTimeout(entry.timer);
|
|
1729
|
-
} else if (!entry.settled) {
|
|
1730
|
-
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
1731
|
-
decFieldValidation(hit.key);
|
|
1732
|
-
}
|
|
1733
|
-
entry.aborted = true;
|
|
1734
|
-
fieldValidationState.delete(hit.key);
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
return {
|
|
1738
|
-
applyStructuralOp(arrayPath, remap) {
|
|
1739
|
-
migrateElementState(arrayPath, remap);
|
|
1740
|
-
for (const freshIndex of remap.fresh) seedFreshElement(arrayPath, freshIndex);
|
|
1741
|
-
const changed = changedIndices(remap);
|
|
1742
|
-
evictSchemaVerdictsAtIndices(errorCells(), arrayPath, changed);
|
|
1743
|
-
abortValidationAtVacatedIndices(arrayPath, remap);
|
|
1744
|
-
variantMemory.dropAtIndices(arrayPath, changed);
|
|
1745
|
-
arrayIdentity.applyOp(arrayPath, remap);
|
|
1746
|
-
}
|
|
1747
|
-
};
|
|
1748
|
-
}
|
|
1749
|
-
function buildFieldArrayApi(state) {
|
|
1750
|
-
function readArray(path) {
|
|
1751
|
-
const segments = canonicalizePath(path).segments;
|
|
1752
|
-
const current = state.getValueAtPath(segments);
|
|
1753
|
-
return Array.isArray(current) ? current.slice() : [];
|
|
1754
|
-
}
|
|
1755
|
-
function writeArray(path, next, arrayOp) {
|
|
1756
|
-
const { segments } = canonicalizePath(path);
|
|
1757
|
-
const meta = {
|
|
1758
|
-
...arrayOp !== void 0 ? { arrayOp } : {}
|
|
1759
|
-
};
|
|
1760
|
-
return state.setValueAtPath(segments, next, meta);
|
|
1761
|
-
}
|
|
1762
|
-
return {
|
|
1763
|
-
append(path, value) {
|
|
1764
|
-
const next = readArray(path);
|
|
1765
|
-
next.push(value);
|
|
1766
|
-
return writeArray(path, next, { kind: "insert", index: next.length - 1 });
|
|
1767
|
-
},
|
|
1768
|
-
prepend(path, value) {
|
|
1769
|
-
const next = readArray(path);
|
|
1770
|
-
next.unshift(value);
|
|
1771
|
-
return writeArray(path, next, { kind: "insert", index: 0 });
|
|
1772
|
-
},
|
|
1773
|
-
insert(path, index, value) {
|
|
1774
|
-
const next = readArray(path);
|
|
1775
|
-
const preLen = next.length;
|
|
1776
|
-
const insertIndex = index < 0 ? Math.max(0, preLen + index) : Math.min(index, preLen);
|
|
1777
|
-
next.splice(insertIndex, 0, value);
|
|
1778
|
-
return writeArray(path, next, { kind: "insert", index: insertIndex });
|
|
1779
|
-
},
|
|
1780
|
-
remove(path, index) {
|
|
1781
|
-
const next = readArray(path);
|
|
1782
|
-
if (index < 0 || index >= next.length) return false;
|
|
1783
|
-
next.splice(index, 1);
|
|
1784
|
-
return writeArray(path, next, { kind: "remove", index });
|
|
1785
|
-
},
|
|
1786
|
-
swap(path, a, b) {
|
|
1787
|
-
const next = readArray(path);
|
|
1788
|
-
if (a < 0 || a >= next.length) return false;
|
|
1789
|
-
if (b < 0 || b >= next.length) return false;
|
|
1790
|
-
if (a === b) return false;
|
|
1791
|
-
const tmp = next[a];
|
|
1792
|
-
next[a] = next[b];
|
|
1793
|
-
next[b] = tmp;
|
|
1794
|
-
return writeArray(path, next, { kind: "swap", a, b });
|
|
1795
|
-
},
|
|
1796
|
-
move(path, from, to) {
|
|
1797
|
-
const next = readArray(path);
|
|
1798
|
-
if (from < 0 || from >= next.length) return false;
|
|
1799
|
-
const [item] = next.splice(from, 1);
|
|
1800
|
-
const clampedTo = Math.max(0, Math.min(to, next.length));
|
|
1801
|
-
next.splice(clampedTo, 0, item);
|
|
1802
|
-
return writeArray(path, next, { kind: "move", from, to: clampedTo });
|
|
1803
|
-
},
|
|
1804
|
-
replace(path, index, value) {
|
|
1805
|
-
const next = readArray(path);
|
|
1806
|
-
if (index < 0 || index >= next.length) return false;
|
|
1807
|
-
next[index] = value;
|
|
1808
|
-
return writeArray(path, next, { kind: "replace-at", index });
|
|
1809
|
-
}
|
|
1810
|
-
};
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
1063
|
const warnedNoScopeStores = /* @__PURE__ */ new WeakSet() ;
|
|
1814
1064
|
function isErrorInputLike(value) {
|
|
1815
1065
|
if (value instanceof Error) return true;
|
|
@@ -2552,12 +1802,12 @@ function isPrimitiveOrEmpty(value) {
|
|
|
2552
1802
|
return t === "string" || t === "number" || t === "boolean" || t === "bigint";
|
|
2553
1803
|
}
|
|
2554
1804
|
function isSlimNumericPrimitive(value) {
|
|
2555
|
-
return value === 0 || value ===
|
|
1805
|
+
return value === 0 || typeof value === "bigint" && !value;
|
|
2556
1806
|
}
|
|
2557
1807
|
function blankForKind(slimDefault) {
|
|
2558
1808
|
if (typeof slimDefault === "string") return "";
|
|
2559
1809
|
if (typeof slimDefault === "number") return 0;
|
|
2560
|
-
if (typeof slimDefault === "bigint") return
|
|
1810
|
+
if (typeof slimDefault === "bigint") return typeof BigInt === "function" ? BigInt(0) : void 0;
|
|
2561
1811
|
if (typeof slimDefault === "boolean") return false;
|
|
2562
1812
|
if (slimDefault === null) return null;
|
|
2563
1813
|
return void 0;
|
|
@@ -2926,7 +2176,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2926
2176
|
};
|
|
2927
2177
|
const metaTarget = buildMetaProxy(META_KEYS, (key) => {
|
|
2928
2178
|
if (key === "errorCount") return metaErrors.value.length;
|
|
2929
|
-
if (
|
|
2179
|
+
if (safeOwnHas(metaOwn, key)) return metaOwn[key];
|
|
2930
2180
|
return rootFieldState.value[key];
|
|
2931
2181
|
});
|
|
2932
2182
|
const formMeta = readonly(reactive(metaTarget));
|
|
@@ -2941,8 +2191,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2941
2191
|
);
|
|
2942
2192
|
state.reset(walked.cleanedValues);
|
|
2943
2193
|
for (const pathKey of walked.paths) {
|
|
2944
|
-
state.blankPaths.add(pathKey);
|
|
2945
2194
|
state.originalBlankPaths.add(pathKey);
|
|
2195
|
+
state.blankPaths.add(pathKey);
|
|
2946
2196
|
}
|
|
2947
2197
|
}
|
|
2948
2198
|
};
|
|
@@ -3383,7 +2633,7 @@ function mergeObjectKeys(target, source, path, schema) {
|
|
|
3383
2633
|
|
|
3384
2634
|
async function runFactoryAndApply(st, factory) {
|
|
3385
2635
|
try {
|
|
3386
|
-
const value = await factory();
|
|
2636
|
+
const value = structuralSnapshot(await factory());
|
|
3387
2637
|
if (st.hasPreprocessOrCoerce) walkAuthoredFromConstraints(value, [], st.authoredPaths);
|
|
3388
2638
|
const full = mergeSparseHydration(
|
|
3389
2639
|
toRaw(st.form.value),
|
|
@@ -3427,16 +2677,15 @@ function appendHydrationFailedEntry(st, error) {
|
|
|
3427
2677
|
return entry;
|
|
3428
2678
|
}
|
|
3429
2679
|
|
|
3430
|
-
const isContainer = (value) => Array.isArray(value) || isPlainRecord(value);
|
|
3431
2680
|
function isHydratedFieldRecord(value) {
|
|
3432
2681
|
if (typeof value !== "object" || value === null) return false;
|
|
3433
2682
|
const r = value;
|
|
3434
2683
|
return Array.isArray(r.path) && (typeof r.updatedAt === "string" || r.updatedAt === null) && typeof r.connected === "boolean" && (typeof r.focused === "boolean" || r.focused === null) && (typeof r.blurred === "boolean" || r.blurred === null) && typeof r.touched === "boolean" && typeof r.interacted === "boolean" && typeof r.blurredAfterInteraction === "boolean";
|
|
3435
2684
|
}
|
|
3436
|
-
function withClearedHistoryFlags(record,
|
|
2685
|
+
function withClearedHistoryFlags(record, updatedAt) {
|
|
3437
2686
|
return {
|
|
3438
2687
|
path: record.path,
|
|
3439
|
-
updatedAt
|
|
2688
|
+
updatedAt,
|
|
3440
2689
|
connected: record.connected,
|
|
3441
2690
|
focused: record.focused,
|
|
3442
2691
|
blurred: record.blurred,
|
|
@@ -3485,7 +2734,7 @@ function walkDuStubs(schema, value, path, warned) {
|
|
|
3485
2734
|
if (du !== void 0) {
|
|
3486
2735
|
const discValue = rec[du.discriminatorKey];
|
|
3487
2736
|
if (discValue !== void 0 && !du.isVariantSelected(discValue)) {
|
|
3488
|
-
const isKindBlank = discValue === "" || discValue === 0 || discValue ===
|
|
2737
|
+
const isKindBlank = discValue === "" || discValue === 0 || typeof discValue === "bigint" && !discValue || discValue === false || discValue === null;
|
|
3489
2738
|
if (!isKindBlank && warned !== void 0 && true) {
|
|
3490
2739
|
const dotted = path.map((s) => String(s)).join(".") || "(root)";
|
|
3491
2740
|
const key = `${dotted}::${String(discValue)}`;
|
|
@@ -3510,7 +2759,7 @@ function walkDuStubs(schema, value, path, warned) {
|
|
|
3510
2759
|
function stripSymbolsDeep(value) {
|
|
3511
2760
|
if (value === null || typeof value !== "object") return value;
|
|
3512
2761
|
if (Array.isArray(value)) {
|
|
3513
|
-
let mutated2 =
|
|
2762
|
+
let mutated2 = !consumerExtensible(value);
|
|
3514
2763
|
const out2 = new Array(value.length);
|
|
3515
2764
|
for (let i = 0; i < value.length; i++) {
|
|
3516
2765
|
const original = readConsumerIndex(value, i);
|
|
@@ -3524,7 +2773,7 @@ function stripSymbolsDeep(value) {
|
|
|
3524
2773
|
if (proto !== Object.prototype && proto !== null) return value;
|
|
3525
2774
|
const symKeys = consumerSymbolKeys(value);
|
|
3526
2775
|
const stringKeys = consumerKeys(value);
|
|
3527
|
-
let mutated = symKeys.length > 0;
|
|
2776
|
+
let mutated = symKeys.length > 0 || !consumerExtensible(value);
|
|
3528
2777
|
const out = {};
|
|
3529
2778
|
const src = value;
|
|
3530
2779
|
for (const k of stringKeys) {
|
|
@@ -3567,14 +2816,27 @@ function initialFirstValidationGate(schema) {
|
|
|
3567
2816
|
return schema.needsAsyncValidation?.() !== true;
|
|
3568
2817
|
}
|
|
3569
2818
|
function seedOriginalsFromBaseline(st, baseline) {
|
|
3570
|
-
|
|
2819
|
+
const seeded = /* @__PURE__ */ new Map();
|
|
3571
2820
|
diffAndApply({}, baseline, [], (patch) => {
|
|
3572
|
-
if (patch.kind
|
|
3573
|
-
st.originals.set(canonicalizePath(patch.path).key, {
|
|
3574
|
-
segments: patch.path,
|
|
3575
|
-
value: patch.newValue
|
|
3576
|
-
});
|
|
2821
|
+
if (patch.kind === "added") seedBaseline(seeded, canonicalizePath(patch.path).key, patch);
|
|
3577
2822
|
});
|
|
2823
|
+
replaceOriginals(st, seeded);
|
|
2824
|
+
}
|
|
2825
|
+
function replaceOriginals(st, next) {
|
|
2826
|
+
for (const [key, entry] of next) st.originals.set(key, entry);
|
|
2827
|
+
for (const key of [...toRaw(st.originals).keys()]) {
|
|
2828
|
+
if (!next.has(key)) st.originals.delete(key);
|
|
2829
|
+
}
|
|
2830
|
+
}
|
|
2831
|
+
function seedBaseline(originals, key, patch) {
|
|
2832
|
+
const value = patch.newValue;
|
|
2833
|
+
if (!isDescendable(value)) {
|
|
2834
|
+
originals.set(key, { segments: patch.path, value });
|
|
2835
|
+
return false;
|
|
2836
|
+
}
|
|
2837
|
+
if (!(value instanceof Map))
|
|
2838
|
+
originals.set(key, { segments: patch.path, value: Array.isArray(value) ? [] : {} });
|
|
2839
|
+
return true;
|
|
3578
2840
|
}
|
|
3579
2841
|
function queueInitialAsyncValidation(st) {
|
|
3580
2842
|
if (!st.ssr && st.schema.needsAsyncValidation?.() === true) {
|
|
@@ -3736,8 +2998,18 @@ function settleTransforms(st, path) {
|
|
|
3736
2998
|
st.transformWaiters.push({ key, resolve });
|
|
3737
2999
|
});
|
|
3738
3000
|
}
|
|
3001
|
+
function writeInstant(st) {
|
|
3002
|
+
const clock = (/* @__PURE__ */ new Date()).toISOString();
|
|
3003
|
+
if (clock > st.latestStamp) return clock;
|
|
3004
|
+
const after = new Date(new Date(st.latestStamp).getTime() + 1);
|
|
3005
|
+
return Number.isFinite(after.getTime()) ? after.toISOString() : clock;
|
|
3006
|
+
}
|
|
3007
|
+
function noteStamp(st, stamp) {
|
|
3008
|
+
if (stamp !== null && stamp > st.latestStamp) st.latestStamp = stamp;
|
|
3009
|
+
}
|
|
3739
3010
|
function touchFieldRecord(st, pathKey, path, patch) {
|
|
3740
3011
|
const current = st.fields.get(pathKey);
|
|
3012
|
+
if (patch.updatedAt !== void 0) noteStamp(st, patch.updatedAt);
|
|
3741
3013
|
st.fields.set(pathKey, {
|
|
3742
3014
|
path,
|
|
3743
3015
|
updatedAt: patch.updatedAt ?? current?.updatedAt ?? null,
|
|
@@ -3756,19 +3028,189 @@ function touchFieldRecord(st, pathKey, path, patch) {
|
|
|
3756
3028
|
blurredAfterInteraction: patch.blurredAfterInteraction ?? current?.blurredAfterInteraction ?? false
|
|
3757
3029
|
});
|
|
3758
3030
|
}
|
|
3759
|
-
function
|
|
3760
|
-
|
|
3031
|
+
function stampContainers(st, containers, now) {
|
|
3032
|
+
eachAncestorOnce(containers, (key, segments) => raiseStamp(st, key, segments, now));
|
|
3033
|
+
}
|
|
3034
|
+
function raiseStamp(st, key, segments, stamp) {
|
|
3035
|
+
if ((st.fields.get(key)?.updatedAt ?? "") < stamp) {
|
|
3036
|
+
touchFieldRecord(st, key, segments, { updatedAt: stamp });
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
function holdRemovedStamps(st, patches, next) {
|
|
3040
|
+
const held = /* @__PURE__ */ new Map();
|
|
3041
|
+
const hold = (path, depth, leaf) => noteHold(st, held, next, path, depth, leaf);
|
|
3761
3042
|
for (const patch of patches) {
|
|
3762
|
-
|
|
3763
|
-
|
|
3043
|
+
if (patch.kind === "added") continue;
|
|
3044
|
+
const { oldValue, path } = patch;
|
|
3045
|
+
if (Array.isArray(oldValue) || isPlainRecord(oldValue)) {
|
|
3046
|
+
if (patch.kind === "changed") {
|
|
3047
|
+
visitActiveLeafPaths(oldValue, path, (leaf) => hold(path, path.length, leaf));
|
|
3048
|
+
}
|
|
3049
|
+
} else if (patch.kind === "removed" ? !hasAtPath(next, path) : Array.isArray(patch.newValue) || isPlainRecord(patch.newValue)) {
|
|
3050
|
+
hold(path, path.length - 1, path);
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
3053
|
+
applyHolds(st, held);
|
|
3054
|
+
}
|
|
3055
|
+
function noteHold(st, held, next, path, depth, leaf) {
|
|
3056
|
+
const { key: leafKey } = keyForSegments(leaf);
|
|
3057
|
+
const stamp = toRaw(st.originals).has(leafKey) ? toRaw(st.fields).get(leafKey)?.updatedAt : null;
|
|
3058
|
+
if (stamp === null || stamp === void 0) return;
|
|
3059
|
+
let kept = false;
|
|
3060
|
+
for (let at = depth; at >= 0; at--) {
|
|
3061
|
+
const segments = path.slice(0, at);
|
|
3062
|
+
if (!kept && !hasAtPath(next, segments)) continue;
|
|
3063
|
+
kept = true;
|
|
3064
|
+
const { key } = keyForSegments(segments);
|
|
3065
|
+
const current = held.get(key);
|
|
3066
|
+
if (current === void 0) held.set(key, { segments, stamp });
|
|
3067
|
+
else if (stamp > current.stamp) current.stamp = stamp;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
function applyHolds(st, held) {
|
|
3071
|
+
for (const [key, { segments, stamp }] of held) raiseStamp(st, key, segments, stamp);
|
|
3072
|
+
}
|
|
3073
|
+
function stampBareContainers(st, patches, bare, now) {
|
|
3074
|
+
for (const index of bare) {
|
|
3075
|
+
const path = patches[index]?.path ?? [];
|
|
3076
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
3077
|
+
const container = path.slice(0, depth);
|
|
3078
|
+
if (depth < path.length && reachedBesides(patches, index, container)) break;
|
|
3079
|
+
const { key, segments } = keyForSegments(container);
|
|
3080
|
+
raiseStamp(st, key, segments, now);
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
function reachedBesides(patches, index, container) {
|
|
3085
|
+
for (const step of [-1, 1]) {
|
|
3086
|
+
for (let i = index + step; ; i += step) {
|
|
3087
|
+
const patch = patches[i];
|
|
3088
|
+
if (patch === void 0 || !isPathPrefix(container, patch.path)) break;
|
|
3089
|
+
if (!isBarePatch(patch)) return true;
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
return false;
|
|
3093
|
+
}
|
|
3094
|
+
function eachAncestorOnce(paths, visit) {
|
|
3095
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3096
|
+
for (const path of paths) {
|
|
3097
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
3098
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
3099
|
+
if (seen.has(key)) break;
|
|
3100
|
+
seen.add(key);
|
|
3101
|
+
visit(key, segments);
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
3105
|
+
function foldInteractionHistory(st, path, released) {
|
|
3106
|
+
let touched = false;
|
|
3107
|
+
let interacted = false;
|
|
3108
|
+
let blurredAfterInteraction = false;
|
|
3109
|
+
for (const record of released) {
|
|
3110
|
+
touched || (touched = record.touched);
|
|
3111
|
+
interacted || (interacted = record.interacted);
|
|
3112
|
+
blurredAfterInteraction || (blurredAfterInteraction = record.blurredAfterInteraction);
|
|
3113
|
+
}
|
|
3114
|
+
if (!touched && !interacted && !blurredAfterInteraction) return;
|
|
3115
|
+
st.noteReleased?.(released);
|
|
3116
|
+
for (let depth = path.length; depth >= 0; depth--) {
|
|
3117
|
+
const { key, segments } = keyForSegments(path.slice(0, depth));
|
|
3118
|
+
const current = st.fields.get(key);
|
|
3119
|
+
touchFieldRecord(st, key, segments, {
|
|
3120
|
+
touched: touched || current?.touched === true,
|
|
3121
|
+
interacted: interacted || current?.interacted === true,
|
|
3122
|
+
blurredAfterInteraction: blurredAfterInteraction || current?.blurredAfterInteraction === true
|
|
3123
|
+
});
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
function releaseRemovedRecords(st, segments, raw) {
|
|
3127
|
+
const released = [];
|
|
3128
|
+
let depth = segments.length;
|
|
3129
|
+
do {
|
|
3130
|
+
const { key } = keyForSegments(segments.slice(0, depth));
|
|
3131
|
+
abortValidationAt(st, key);
|
|
3132
|
+
const record = st.fields.get(key);
|
|
3133
|
+
if (record !== void 0) {
|
|
3134
|
+
released.push(record);
|
|
3135
|
+
if (record.connected) st.fields.set(key, withClearedHistoryFlags(record, null));
|
|
3136
|
+
else st.fields.delete(key);
|
|
3137
|
+
}
|
|
3138
|
+
depth--;
|
|
3139
|
+
} while (depth > 0 && !hasAtPath(raw, segments.slice(0, depth)));
|
|
3140
|
+
const present = segments.slice(0, depth);
|
|
3141
|
+
foldInteractionHistory(st, present, released);
|
|
3142
|
+
return present;
|
|
3143
|
+
}
|
|
3144
|
+
function noteRemovedBaseline(st, key, segments, notify) {
|
|
3145
|
+
if (st.originals.get(key)?.value === void 0) return;
|
|
3146
|
+
st.removedPaths.set(key, segments);
|
|
3147
|
+
notify.push(segments);
|
|
3148
|
+
}
|
|
3149
|
+
function trackForSweep(st, path, key) {
|
|
3150
|
+
st.pathSweep.track(path, key);
|
|
3151
|
+
for (let i = 1; i < path.length; i++) {
|
|
3152
|
+
const ancestor = path.slice(0, i);
|
|
3153
|
+
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
function commitWritePatches(st, patches, meta, structuralOp, now) {
|
|
3157
|
+
const arrayOpPath = structuralOp?.path;
|
|
3158
|
+
const reshaped = [];
|
|
3159
|
+
const removed = [];
|
|
3160
|
+
const resizing = [];
|
|
3161
|
+
const raw = toRaw(st.form.value);
|
|
3162
|
+
const bareAt = [];
|
|
3163
|
+
for (const [index, patch] of patches.entries()) {
|
|
3164
|
+
const { key, segments } = canonicalizePath(patch.path);
|
|
3165
|
+
const bare = isBarePatch(patch);
|
|
3166
|
+
if (!bare && !st.originals.has(key)) {
|
|
3764
3167
|
st.originals.set(key, { segments: patch.path, value: void 0 });
|
|
3765
3168
|
}
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
const ancestor = patch.path.slice(0, i);
|
|
3770
|
-
st.pathSweep.track(ancestor, canonicalizePath(ancestor).key);
|
|
3169
|
+
const positional = arrayOpPath !== void 0 && segments.length > arrayOpPath.length && isPathPrefix(arrayOpPath, segments);
|
|
3170
|
+
if (structuralOp === null && (patch.kind !== "changed" || typeof patch.oldValue === "object" || typeof patch.newValue === "object")) {
|
|
3171
|
+
resizing.push(segments);
|
|
3771
3172
|
}
|
|
3173
|
+
if (!positional) {
|
|
3174
|
+
if (patch.kind === "removed" && !hasAtPath(raw, segments)) {
|
|
3175
|
+
reshaped.push(releaseRemovedRecords(st, segments, raw));
|
|
3176
|
+
noteRemovedBaseline(st, key, segments, removed);
|
|
3177
|
+
} else {
|
|
3178
|
+
touchFieldRecord(st, key, segments, { updatedAt: now });
|
|
3179
|
+
if (bare) bareAt.push(index);
|
|
3180
|
+
if (patch.kind === "changed" && typeof patch.oldValue === "object" && patch.oldValue !== null) {
|
|
3181
|
+
diffAndApply(patch.oldValue, void 0, segments, (gone) => {
|
|
3182
|
+
if (!hasAtPath(raw, gone.path)) {
|
|
3183
|
+
reshaped.push(releaseRemovedRecords(st, gone.path, raw));
|
|
3184
|
+
const goneAt = canonicalizePath(gone.path);
|
|
3185
|
+
noteRemovedBaseline(st, goneAt.key, goneAt.segments, removed);
|
|
3186
|
+
}
|
|
3187
|
+
});
|
|
3188
|
+
}
|
|
3189
|
+
if (patch.kind === "changed" && isDescendable(patch.newValue)) {
|
|
3190
|
+
diffAndApply(void 0, patch.newValue, segments, (fresh) => {
|
|
3191
|
+
const at = canonicalizePath(fresh.path);
|
|
3192
|
+
trackForSweep(st, fresh.path, at.key);
|
|
3193
|
+
if (fresh.kind === "added" && isDescendable(fresh.newValue)) {
|
|
3194
|
+
reshaped.push(at.segments);
|
|
3195
|
+
return;
|
|
3196
|
+
}
|
|
3197
|
+
if (!st.originals.has(at.key)) {
|
|
3198
|
+
st.originals.set(at.key, { segments: fresh.path, value: void 0 });
|
|
3199
|
+
}
|
|
3200
|
+
touchFieldRecord(st, at.key, at.segments, { updatedAt: now });
|
|
3201
|
+
});
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
trackForSweep(st, patch.path, key);
|
|
3206
|
+
}
|
|
3207
|
+
if (arrayOpPath !== void 0 && patches.length > 0) reshaped.push(arrayOpPath);
|
|
3208
|
+
if (reshaped.length > 0) stampContainers(st, reshaped, now);
|
|
3209
|
+
if (bareAt.length > 0) stampBareContainers(st, patches, bareAt, now);
|
|
3210
|
+
if (removed.length > 0) pulseStructure(st.structureSignal, removed);
|
|
3211
|
+
if (resizing.length > 0) st.arrayIdentity.realignContaining(resizing);
|
|
3212
|
+
if (structuralOp !== null) {
|
|
3213
|
+
st.arrayBookkeeping.applyStructuralOp(structuralOp.path, structuralOp.remap, now);
|
|
3772
3214
|
}
|
|
3773
3215
|
for (const listener of st.formChangeListeners) {
|
|
3774
3216
|
try {
|
|
@@ -3778,33 +3220,41 @@ function commitWritePatches(st, patches, meta) {
|
|
|
3778
3220
|
}
|
|
3779
3221
|
}
|
|
3780
3222
|
}
|
|
3781
|
-
function applyFormReplacementWithPath(st, next, meta,
|
|
3223
|
+
function applyFormReplacementWithPath(st, next, meta, structuralOp, now) {
|
|
3782
3224
|
const prev = st.form.value;
|
|
3783
3225
|
if (Object.is(prev, next)) return;
|
|
3784
3226
|
const patches = [];
|
|
3785
3227
|
diffAndApply(prev, next, [], (patch) => {
|
|
3786
3228
|
patches.push(patch);
|
|
3787
3229
|
});
|
|
3788
|
-
|
|
3230
|
+
holdRemovedStamps(st, patches, next);
|
|
3231
|
+
const reconciled = callConsumerFn(
|
|
3232
|
+
() => applyChangedKeys(prev, next, structuralOp?.path ?? null, [], patches),
|
|
3233
|
+
null,
|
|
3234
|
+
"stored-value"
|
|
3235
|
+
);
|
|
3236
|
+
if (reconciled === null) return;
|
|
3237
|
+
if (!reconciled) {
|
|
3789
3238
|
st.form.value = next;
|
|
3790
3239
|
} else if (patches.some(
|
|
3791
3240
|
(p) => p.path.length > 0 && typeof p.path[0] === "string" && isShadowedKey(p.path[0])
|
|
3792
3241
|
)) {
|
|
3793
3242
|
triggerRef(st.form);
|
|
3794
3243
|
}
|
|
3795
|
-
commitWritePatches(st, patches, meta);
|
|
3244
|
+
commitWritePatches(st, patches, meta, structuralOp, now);
|
|
3796
3245
|
}
|
|
3797
3246
|
function applyFormReplacement(st, next, meta) {
|
|
3798
|
-
applyFormReplacementWithPath(st, next, meta, null);
|
|
3247
|
+
applyFormReplacementWithPath(st, next, meta, null, writeInstant(st));
|
|
3799
3248
|
}
|
|
3800
|
-
function applyTargetedWrite(st, path, completedValue, meta) {
|
|
3249
|
+
function applyTargetedWrite(st, path, completedValue, meta, structuralOp, now) {
|
|
3801
3250
|
const result = tryInPlaceLeafWrite(st.form.value, path, completedValue);
|
|
3802
3251
|
if (!result.applied) {
|
|
3803
3252
|
applyFormReplacementWithPath(
|
|
3804
3253
|
st,
|
|
3805
3254
|
setAtPathWithSchemaFill(st.form.value, st.schema, path, completedValue),
|
|
3806
3255
|
meta,
|
|
3807
|
-
|
|
3256
|
+
structuralOp,
|
|
3257
|
+
now
|
|
3808
3258
|
);
|
|
3809
3259
|
return;
|
|
3810
3260
|
}
|
|
@@ -3812,9 +3262,9 @@ function applyTargetedWrite(st, path, completedValue, meta) {
|
|
|
3812
3262
|
diffAndApply(result.old, completedValue, path, (patch) => {
|
|
3813
3263
|
patches.push(patch);
|
|
3814
3264
|
});
|
|
3815
|
-
commitWritePatches(st, patches, meta);
|
|
3265
|
+
commitWritePatches(st, patches, meta, null, now);
|
|
3816
3266
|
}
|
|
3817
|
-
function setValueAtPath(st, path, value, meta) {
|
|
3267
|
+
function setValueAtPath(st, path, value, meta, writeStamp) {
|
|
3818
3268
|
if (st.effectiveDisabled.value) {
|
|
3819
3269
|
if (!st.warnedDisabledWrite) {
|
|
3820
3270
|
st.warnedDisabledWrite = true;
|
|
@@ -3893,7 +3343,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3893
3343
|
value,
|
|
3894
3344
|
variantDefault,
|
|
3895
3345
|
void 0,
|
|
3896
|
-
meta
|
|
3346
|
+
meta,
|
|
3347
|
+
writeStamp
|
|
3897
3348
|
);
|
|
3898
3349
|
}
|
|
3899
3350
|
return reshapeUnionVariant(
|
|
@@ -3903,7 +3354,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3903
3354
|
value,
|
|
3904
3355
|
{ [last]: value },
|
|
3905
3356
|
void 0,
|
|
3906
|
-
meta
|
|
3357
|
+
meta,
|
|
3358
|
+
writeStamp
|
|
3907
3359
|
);
|
|
3908
3360
|
}
|
|
3909
3361
|
}
|
|
@@ -3927,7 +3379,8 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3927
3379
|
discValue,
|
|
3928
3380
|
variantDefault,
|
|
3929
3381
|
valueRecord,
|
|
3930
|
-
meta
|
|
3382
|
+
meta,
|
|
3383
|
+
writeStamp
|
|
3931
3384
|
);
|
|
3932
3385
|
}
|
|
3933
3386
|
return reshapeUnionVariant(
|
|
@@ -3937,10 +3390,20 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3937
3390
|
discValue,
|
|
3938
3391
|
{ [discKey]: discValue },
|
|
3939
3392
|
void 0,
|
|
3940
|
-
meta
|
|
3393
|
+
meta,
|
|
3394
|
+
writeStamp
|
|
3941
3395
|
);
|
|
3942
3396
|
}
|
|
3943
|
-
return reshapeUnionVariant(
|
|
3397
|
+
return reshapeUnionVariant(
|
|
3398
|
+
st,
|
|
3399
|
+
path,
|
|
3400
|
+
oldDiscValue,
|
|
3401
|
+
void 0,
|
|
3402
|
+
{},
|
|
3403
|
+
void 0,
|
|
3404
|
+
meta,
|
|
3405
|
+
writeStamp
|
|
3406
|
+
);
|
|
3944
3407
|
}
|
|
3945
3408
|
}
|
|
3946
3409
|
}
|
|
@@ -3990,16 +3453,17 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
3990
3453
|
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3991
3454
|
st.arrayIdentity.realign(path);
|
|
3992
3455
|
}
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
st
|
|
3996
|
-
|
|
3456
|
+
const now = writeStamp ?? writeInstant(st);
|
|
3457
|
+
applyTargetedWrite(
|
|
3458
|
+
st,
|
|
3459
|
+
path,
|
|
3460
|
+
completedValue,
|
|
3461
|
+
meta,
|
|
3462
|
+
arrayOpRemap !== null ? { path, remap: arrayOpRemap } : null,
|
|
3463
|
+
now
|
|
3464
|
+
);
|
|
3465
|
+
if (arrayOpRemap === null && Array.isArray(value) && Array.isArray(currentValue)) {
|
|
3997
3466
|
st.variantMemory.clearUnderPath(path);
|
|
3998
|
-
st.arrayIdentity.realign(path);
|
|
3999
|
-
} else if (isContainer(currentValue) && !isContainer(value)) {
|
|
4000
|
-
if (subtreeHadRealBaseline(st, path, currentValue)) {
|
|
4001
|
-
st.removedSubtrees.add(pathKey);
|
|
4002
|
-
}
|
|
4003
3467
|
}
|
|
4004
3468
|
const effectiveModeAfterWrite = meta?.instance?.validateOn ?? st.fieldValidationMode;
|
|
4005
3469
|
if (effectiveModeAfterWrite === "change") {
|
|
@@ -4007,7 +3471,7 @@ function setValueAtPath(st, path, value, meta) {
|
|
|
4007
3471
|
}
|
|
4008
3472
|
return true;
|
|
4009
3473
|
}
|
|
4010
|
-
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta) {
|
|
3474
|
+
function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variantDefault, consumerOverrides, meta, writeStamp) {
|
|
4011
3475
|
const sameDisc = Object.is(oldDiscValue, newDiscValue);
|
|
4012
3476
|
const parentKey = canonicalizePath(parentPath).key;
|
|
4013
3477
|
let baseline = variantDefault;
|
|
@@ -4073,7 +3537,7 @@ function reshapeUnionVariant(st, parentPath, oldDiscValue, newDiscValue, variant
|
|
|
4073
3537
|
appliedSync = true;
|
|
4074
3538
|
}
|
|
4075
3539
|
}
|
|
4076
|
-
|
|
3540
|
+
applyFormReplacementWithPath(st, nextForm, meta, null, writeStamp ?? writeInstant(st));
|
|
4077
3541
|
for (const k of newBlankPaths) st.blankPaths.add(k);
|
|
4078
3542
|
if (reshapeMode === "change" && !appliedSync) {
|
|
4079
3543
|
scheduleFieldValidation(st, parentPath, false, meta?.instance);
|
|
@@ -4094,7 +3558,9 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4094
3558
|
aborted: false,
|
|
4095
3559
|
timer: null,
|
|
4096
3560
|
settled: false,
|
|
4097
|
-
released: false
|
|
3561
|
+
released: false,
|
|
3562
|
+
key,
|
|
3563
|
+
path
|
|
4098
3564
|
};
|
|
4099
3565
|
st.fieldValidationState.set(key, fresh);
|
|
4100
3566
|
const myEpoch = ++st.scheduleEpoch;
|
|
@@ -4105,19 +3571,20 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4105
3571
|
try {
|
|
4106
3572
|
st.activeValidations.value += 1;
|
|
4107
3573
|
activeIncremented = true;
|
|
4108
|
-
incFieldValidation(st, key);
|
|
3574
|
+
incFieldValidation(st, fresh.key);
|
|
4109
3575
|
} catch (err) {
|
|
4110
3576
|
if (activeIncremented) {
|
|
4111
3577
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
4112
3578
|
}
|
|
4113
3579
|
throw err;
|
|
4114
3580
|
}
|
|
4115
|
-
const
|
|
4116
|
-
const
|
|
4117
|
-
const dataAtScope = subtreeScope ? getAtPath(st.form.value,
|
|
4118
|
-
|
|
4119
|
-
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, scopePath)).then((response) => {
|
|
3581
|
+
const startPath = fresh.path;
|
|
3582
|
+
const subtreeScope = startPath.length > 0 && st.schema.hasContainerOrRootRefine?.() === false;
|
|
3583
|
+
const dataAtScope = subtreeScope ? getAtPath(st.form.value, startPath) : st.form.value;
|
|
3584
|
+
void Promise.resolve().then(() => st.schema.validateAtPath(dataAtScope, subtreeScope ? startPath : void 0)).then((response) => {
|
|
4120
3585
|
if (fresh.aborted) return;
|
|
3586
|
+
const scopePath = subtreeScope ? fresh.path : void 0;
|
|
3587
|
+
const scopeKey = subtreeScope ? fresh.key : ROOT_PATH_KEY;
|
|
4121
3588
|
if (myEpoch <= st.lastCommittedEpoch) return;
|
|
4122
3589
|
st.lastCommittedEpoch = myEpoch;
|
|
4123
3590
|
if (effectiveMode === "blur") {
|
|
@@ -4128,14 +3595,14 @@ function scheduleFieldValidation(st, path, immediate, instance) {
|
|
|
4128
3595
|
const filtered = filterAuthoredErrors(st, errors);
|
|
4129
3596
|
const restamped = subtreeScope ? filtered.map((err) => ({
|
|
4130
3597
|
...err,
|
|
4131
|
-
path: [...
|
|
3598
|
+
path: [...scopePath ?? [], ...err.path]
|
|
4132
3599
|
})) : filtered;
|
|
4133
3600
|
applySchemaErrorsForSubtree(st, scopePath ?? [], restamped);
|
|
4134
3601
|
}).catch(() => {
|
|
4135
3602
|
}).finally(() => {
|
|
4136
3603
|
if (!fresh.released) {
|
|
4137
3604
|
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
4138
|
-
decFieldValidation(st, key);
|
|
3605
|
+
decFieldValidation(st, fresh.key);
|
|
4139
3606
|
}
|
|
4140
3607
|
fresh.settled = true;
|
|
4141
3608
|
});
|
|
@@ -4174,6 +3641,19 @@ function cancelFieldValidationUnder(st, prefix) {
|
|
|
4174
3641
|
st.fieldValidationState.delete(key);
|
|
4175
3642
|
}
|
|
4176
3643
|
}
|
|
3644
|
+
function abortValidationAt(st, key) {
|
|
3645
|
+
const entry = st.fieldValidationState.get(key);
|
|
3646
|
+
if (entry === void 0) return;
|
|
3647
|
+
if (entry.timer !== null) {
|
|
3648
|
+
clearTimeout(entry.timer);
|
|
3649
|
+
} else if (!entry.settled && !entry.released) {
|
|
3650
|
+
st.activeValidations.value = Math.max(0, st.activeValidations.value - 1);
|
|
3651
|
+
decFieldValidation(st, key);
|
|
3652
|
+
entry.released = true;
|
|
3653
|
+
}
|
|
3654
|
+
entry.aborted = true;
|
|
3655
|
+
st.fieldValidationState.delete(key);
|
|
3656
|
+
}
|
|
4177
3657
|
function onFormChange(st, listener) {
|
|
4178
3658
|
st.formChangeListeners.add(listener);
|
|
4179
3659
|
return () => {
|
|
@@ -4224,6 +3704,34 @@ function dispose(st) {
|
|
|
4224
3704
|
function getValueAtPath(st, path) {
|
|
4225
3705
|
return getAtPath(st.form.value, path);
|
|
4226
3706
|
}
|
|
3707
|
+
function freezeBaseline(value) {
|
|
3708
|
+
if (Object.isFrozen(value)) return value;
|
|
3709
|
+
if (Array.isArray(value)) {
|
|
3710
|
+
for (const item of value) freezeBaseline(item);
|
|
3711
|
+
return Object.freeze(value);
|
|
3712
|
+
}
|
|
3713
|
+
if (isPlainRecord(value)) {
|
|
3714
|
+
for (const k of Object.keys(value)) freezeBaseline(safeOwnRead(value, k));
|
|
3715
|
+
return Object.freeze(value);
|
|
3716
|
+
}
|
|
3717
|
+
return value;
|
|
3718
|
+
}
|
|
3719
|
+
function getOriginalAtPath(st, path) {
|
|
3720
|
+
let node = st.baselineValue;
|
|
3721
|
+
for (let i = 0; i < path.length; i++) {
|
|
3722
|
+
const segment = path[i];
|
|
3723
|
+
if (Array.isArray(node)) {
|
|
3724
|
+
const at = typeof segment === "number" ? st.arrayIdentity.baselineIndexOf(path.slice(0, i), segment) : -1;
|
|
3725
|
+
if (at < 0) return void 0;
|
|
3726
|
+
node = node[at];
|
|
3727
|
+
} else if (isPlainRecord(node) && typeof segment === "string") {
|
|
3728
|
+
node = safeOwnRead(node, segment);
|
|
3729
|
+
} else {
|
|
3730
|
+
return void 0;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
return freezeBaseline(node);
|
|
3734
|
+
}
|
|
4227
3735
|
const ERROR_SOURCES = ["schema", "user"];
|
|
4228
3736
|
function createErrorCells(schema, pristine) {
|
|
4229
3737
|
const raw = /* @__PURE__ */ new Map();
|
|
@@ -4301,6 +3809,54 @@ function restoreErrorCells(st, entries) {
|
|
|
4301
3809
|
st.errorCells().set(key, { schema: [...cell.schema], user: [...cell.user] });
|
|
4302
3810
|
}
|
|
4303
3811
|
}
|
|
3812
|
+
function captureStructure(st) {
|
|
3813
|
+
return {
|
|
3814
|
+
identity: st.arrayIdentity.snapshot(),
|
|
3815
|
+
originals: [...toRaw(st.originals)],
|
|
3816
|
+
originalBlank: [...st.originalBlankPaths],
|
|
3817
|
+
removed: [...st.removedPaths]
|
|
3818
|
+
};
|
|
3819
|
+
}
|
|
3820
|
+
function restoreStructure(st, snapshot, remaps, returning) {
|
|
3821
|
+
const originals = new Map(snapshot.originals);
|
|
3822
|
+
const raw = toRaw(st.form.value);
|
|
3823
|
+
const held = /* @__PURE__ */ new Map();
|
|
3824
|
+
for (const [key, { segments }] of toRaw(st.originals)) {
|
|
3825
|
+
if (!originals.has(key) && hasAtPath(raw, segments)) {
|
|
3826
|
+
noteHold(st, held, raw, segments, segments.length - 1, segments);
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
applyHolds(st, held);
|
|
3830
|
+
st.arrayIdentity.restore(snapshot.identity);
|
|
3831
|
+
replaceOriginals(st, originals);
|
|
3832
|
+
st.originalBlankPaths.clear();
|
|
3833
|
+
for (const key of snapshot.originalBlank) st.originalBlankPaths.add(key);
|
|
3834
|
+
const pulsed = [...st.removedPaths.values()];
|
|
3835
|
+
st.removedPaths.clear();
|
|
3836
|
+
for (const [key, segments] of snapshot.removed) {
|
|
3837
|
+
st.removedPaths.set(key, segments);
|
|
3838
|
+
pulsed.push(segments);
|
|
3839
|
+
}
|
|
3840
|
+
for (const [segments, remap] of remaps) {
|
|
3841
|
+
migrateFieldRecords(st.fields, segments, remap, (path, released) => {
|
|
3842
|
+
let stamp = "";
|
|
3843
|
+
for (const { updatedAt } of released) {
|
|
3844
|
+
if (updatedAt !== null && updatedAt > stamp) stamp = updatedAt;
|
|
3845
|
+
}
|
|
3846
|
+
if (stamp !== "") eachAncestorOnce([path], (key, at) => raiseStamp(st, key, at, stamp));
|
|
3847
|
+
foldInteractionHistory(st, path, released);
|
|
3848
|
+
});
|
|
3849
|
+
}
|
|
3850
|
+
for (const record of returning) {
|
|
3851
|
+
st.fields.set(canonicalizePath(record.path).key, {
|
|
3852
|
+
...record,
|
|
3853
|
+
connected: false,
|
|
3854
|
+
focused: null,
|
|
3855
|
+
blurred: null
|
|
3856
|
+
});
|
|
3857
|
+
}
|
|
3858
|
+
if (pulsed.length > 0) pulseStructure(st.structureSignal, pulsed);
|
|
3859
|
+
}
|
|
4304
3860
|
function getErrorsForPath(st, path) {
|
|
4305
3861
|
const { key } = canonicalizePath(path);
|
|
4306
3862
|
const cell = st.errorCells().get(key);
|
|
@@ -4325,6 +3881,7 @@ function noteDomConnected(st, path) {
|
|
|
4325
3881
|
}
|
|
4326
3882
|
function noteDomDisconnected(st, path) {
|
|
4327
3883
|
const { key } = canonicalizePath(path);
|
|
3884
|
+
if (!st.fields.has(key)) return;
|
|
4328
3885
|
touchFieldRecord(st, key, path, { connected: false, focused: null, blurred: null });
|
|
4329
3886
|
}
|
|
4330
3887
|
function markConnectedOptimistically(st, path) {
|
|
@@ -4384,17 +3941,39 @@ function markInteracted(st, path) {
|
|
|
4384
3941
|
if (st.fields.get(key)?.interacted === true) return;
|
|
4385
3942
|
touchFieldRecord(st, key, path, { interacted: true });
|
|
4386
3943
|
}
|
|
3944
|
+
function markBareContainers(st, segments, ladder) {
|
|
3945
|
+
const value = getAtPath(toRaw(st.form.value), segments);
|
|
3946
|
+
if (!isDescendable(value)) return false;
|
|
3947
|
+
const bare = [];
|
|
3948
|
+
diffAndApply(void 0, value, segments, (patch) => {
|
|
3949
|
+
if (isBarePatch(patch)) bare.push(patch.path);
|
|
3950
|
+
});
|
|
3951
|
+
eachAncestorOnce(bare, (key, path) => {
|
|
3952
|
+
const current = st.fields.get(key);
|
|
3953
|
+
if (current?.touched === true && (!ladder || current.interacted && current.blurredAfterInteraction)) {
|
|
3954
|
+
return;
|
|
3955
|
+
}
|
|
3956
|
+
touchFieldRecord(
|
|
3957
|
+
st,
|
|
3958
|
+
key,
|
|
3959
|
+
path,
|
|
3960
|
+
ladder ? { touched: true, interacted: true, blurredAfterInteraction: true } : { touched: true }
|
|
3961
|
+
);
|
|
3962
|
+
});
|
|
3963
|
+
return bare.length > 0;
|
|
3964
|
+
}
|
|
4387
3965
|
function touchAtPath(st, segments) {
|
|
4388
3966
|
const formValue = st.form.value;
|
|
4389
3967
|
let touchedAny = false;
|
|
4390
3968
|
for (const [leafKey, entry] of st.originals) {
|
|
4391
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
3969
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4392
3970
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4393
3971
|
touchedAny = true;
|
|
4394
3972
|
const current = st.fields.get(leafKey);
|
|
4395
3973
|
if (current?.touched === true) continue;
|
|
4396
3974
|
touchFieldRecord(st, leafKey, entry.segments, { touched: true });
|
|
4397
3975
|
}
|
|
3976
|
+
if (markBareContainers(st, segments, false)) touchedAny = true;
|
|
4398
3977
|
if (!touchedAny && true) {
|
|
4399
3978
|
console.warn(
|
|
4400
3979
|
`[attaform] form.touch(): no fields resolved at path ${JSON.stringify(segments)}. Check the path matches an existing field or container.`
|
|
@@ -4406,7 +3985,7 @@ function interactAtPath(st, segments) {
|
|
|
4406
3985
|
const formValue = st.form.value;
|
|
4407
3986
|
let interactedAny = false;
|
|
4408
3987
|
for (const [leafKey, entry] of st.originals) {
|
|
4409
|
-
if (!isPathPrefix(segments, entry.segments)) continue;
|
|
3988
|
+
if (!isPathPrefix(segments, entry.segments) || isDescendable(entry.value)) continue;
|
|
4410
3989
|
if (!hasAtPath(formValue, entry.segments)) continue;
|
|
4411
3990
|
interactedAny = true;
|
|
4412
3991
|
const current = st.fields.get(leafKey);
|
|
@@ -4419,6 +3998,7 @@ function interactAtPath(st, segments) {
|
|
|
4419
3998
|
blurredAfterInteraction: true
|
|
4420
3999
|
});
|
|
4421
4000
|
}
|
|
4001
|
+
if (markBareContainers(st, segments, true)) interactedAny = true;
|
|
4422
4002
|
if (!interactedAny && true) {
|
|
4423
4003
|
console.warn(
|
|
4424
4004
|
`[attaform] form.interact(): no fields resolved at path ${JSON.stringify(segments)}. Check the path matches an existing field or container.`
|
|
@@ -4465,14 +4045,31 @@ function adoptResolvedDefaults(st, value) {
|
|
|
4465
4045
|
st.schema
|
|
4466
4046
|
)
|
|
4467
4047
|
);
|
|
4468
|
-
|
|
4469
|
-
st,
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
st.defaultValues,
|
|
4473
|
-
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4474
|
-
)
|
|
4048
|
+
st.baselineValue = computeBaseline(
|
|
4049
|
+
st.schema,
|
|
4050
|
+
st.defaultValues,
|
|
4051
|
+
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4475
4052
|
);
|
|
4053
|
+
seedOriginalsFromBaseline(st, st.baselineValue);
|
|
4054
|
+
st.arrayIdentity.rebaseline((segments) => holdsListAt(value, segments));
|
|
4055
|
+
const dropped = [];
|
|
4056
|
+
for (const [key, segments] of st.removedPaths) {
|
|
4057
|
+
if (st.originals.get(key)?.value !== void 0) continue;
|
|
4058
|
+
st.removedPaths.delete(key);
|
|
4059
|
+
dropped.push(segments);
|
|
4060
|
+
}
|
|
4061
|
+
if (dropped.length > 0) pulseStructure(st.structureSignal, dropped);
|
|
4062
|
+
}
|
|
4063
|
+
function holdsListAt(value, segments) {
|
|
4064
|
+
let node = value;
|
|
4065
|
+
for (const segment of segments) {
|
|
4066
|
+
if (Array.isArray(node)) return true;
|
|
4067
|
+
if (!isPlainRecord(node) || typeof segment !== "string" || !safeOwnHas(node, segment)) {
|
|
4068
|
+
return false;
|
|
4069
|
+
}
|
|
4070
|
+
node = safeOwnRead(node, segment);
|
|
4071
|
+
}
|
|
4072
|
+
return Array.isArray(node);
|
|
4476
4073
|
}
|
|
4477
4074
|
function reset(st, nextDefaultValues) {
|
|
4478
4075
|
const resetSource = nextDefaultValues === void 0 ? st.defaultValues : mergeSparseHydration(
|
|
@@ -4483,19 +4080,25 @@ function reset(st, nextDefaultValues) {
|
|
|
4483
4080
|
st.defaultValues = structuralSnapshot(resetSource);
|
|
4484
4081
|
const next = computeBaseline(
|
|
4485
4082
|
st.schema,
|
|
4486
|
-
|
|
4083
|
+
st.defaultValues,
|
|
4487
4084
|
st.schema.getDefaultValues({ useDefaultSchemaValues: true })
|
|
4488
4085
|
);
|
|
4489
4086
|
rebuildAuthoredPaths(st, resetSource, next);
|
|
4490
|
-
applyFormReplacement(st, next);
|
|
4491
|
-
st.arrayIdentity.rebaselineAll();
|
|
4492
|
-
st.removedSubtrees.clear();
|
|
4493
|
-
seedOriginalsFromBaseline(st, next);
|
|
4494
4087
|
if (nextDefaultValues !== void 0) {
|
|
4495
4088
|
const mentioned = /* @__PURE__ */ new Set();
|
|
4496
4089
|
walkAuthoredFromConstraints(nextDefaultValues, [], mentioned);
|
|
4497
4090
|
for (const key of mentioned) st.originalBlankPaths.delete(key);
|
|
4498
4091
|
}
|
|
4092
|
+
const now = writeInstant(st);
|
|
4093
|
+
applyFormReplacementWithPath(st, structuralSnapshot(next), void 0, null, now);
|
|
4094
|
+
st.arrayIdentity.rebaseline(() => true);
|
|
4095
|
+
if (st.removedPaths.size > 0) {
|
|
4096
|
+
const cleared = [...st.removedPaths.values()];
|
|
4097
|
+
st.removedPaths.clear();
|
|
4098
|
+
pulseStructure(st.structureSignal, cleared);
|
|
4099
|
+
}
|
|
4100
|
+
st.baselineValue = next;
|
|
4101
|
+
seedOriginalsFromBaseline(st, next);
|
|
4499
4102
|
st.blankPaths.clear();
|
|
4500
4103
|
for (const key of st.originalBlankPaths) {
|
|
4501
4104
|
st.blankPaths.add(key);
|
|
@@ -4504,7 +4107,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4504
4107
|
replaceErrorChannel(st, "schema", st.schema.validateSync(next));
|
|
4505
4108
|
st.firstValidationDone.value = initialFirstValidationGate(st.schema);
|
|
4506
4109
|
queueInitialAsyncValidation(st);
|
|
4507
|
-
|
|
4110
|
+
noteStamp(st, now);
|
|
4508
4111
|
for (const [pathKey, record] of st.fields) {
|
|
4509
4112
|
st.fields.set(pathKey, withClearedHistoryFlags(record, now));
|
|
4510
4113
|
}
|
|
@@ -4533,6 +4136,7 @@ function reset(st, nextDefaultValues) {
|
|
|
4533
4136
|
}
|
|
4534
4137
|
function resetField(st, path) {
|
|
4535
4138
|
const { key: targetKey, segments: targetSegments } = canonicalizePath(path);
|
|
4139
|
+
const now = writeInstant(st);
|
|
4536
4140
|
st.variantMemory.clearUnderPath(targetSegments);
|
|
4537
4141
|
cancelFieldValidationUnder(st, targetSegments);
|
|
4538
4142
|
cancelTransformsUnder(st, targetSegments);
|
|
@@ -4541,9 +4145,21 @@ function resetField(st, path) {
|
|
|
4541
4145
|
if (segs === null) continue;
|
|
4542
4146
|
if (isPathPrefix(targetSegments, segs)) st.pathSnapshots.delete(snapKey);
|
|
4543
4147
|
}
|
|
4148
|
+
const cleared = [];
|
|
4149
|
+
for (const [fieldKey, record] of Array.from(st.fields.entries())) {
|
|
4150
|
+
if (!isPathPrefix(targetSegments, record.path)) continue;
|
|
4151
|
+
st.fields.set(fieldKey, withClearedHistoryFlags(record, record.updatedAt));
|
|
4152
|
+
cleared.push(fieldKey);
|
|
4153
|
+
}
|
|
4544
4154
|
const leafEntry = st.originals.get(targetKey);
|
|
4545
4155
|
if (leafEntry !== void 0) {
|
|
4546
|
-
const wrote = setValueAtPath(
|
|
4156
|
+
const wrote = setValueAtPath(
|
|
4157
|
+
st,
|
|
4158
|
+
targetSegments,
|
|
4159
|
+
structuralSnapshot(leafEntry.value),
|
|
4160
|
+
void 0,
|
|
4161
|
+
now
|
|
4162
|
+
);
|
|
4547
4163
|
if (!wrote) {
|
|
4548
4164
|
console.error(
|
|
4549
4165
|
`[attaform] resetField: leaf write rejected for path '${targetKey}'. Originals contain a value that doesn't satisfy the slim primitive shape. This is a bug in the construction pipeline.`
|
|
@@ -4561,10 +4177,10 @@ function resetField(st, path) {
|
|
|
4561
4177
|
if (subtree === void 0) {
|
|
4562
4178
|
subtree = typeof relative[0] === "number" ? [] : {};
|
|
4563
4179
|
}
|
|
4564
|
-
subtree = setAtPath(subtree, relative, entry.value);
|
|
4180
|
+
subtree = setAtPath(subtree, relative, structuralSnapshot(entry.value));
|
|
4565
4181
|
}
|
|
4566
4182
|
if (anyMatch) {
|
|
4567
|
-
const wroteSubtree = setValueAtPath(st, targetSegments, subtree);
|
|
4183
|
+
const wroteSubtree = setValueAtPath(st, targetSegments, subtree, void 0, now);
|
|
4568
4184
|
if (!wroteSubtree) {
|
|
4569
4185
|
console.error(
|
|
4570
4186
|
`[attaform] resetField: subtree write rejected at path '${targetKey}'. Originals contain values that don't satisfy the slim primitive shape. This is a bug in the construction pipeline.`
|
|
@@ -4573,8 +4189,14 @@ function resetField(st, path) {
|
|
|
4573
4189
|
}
|
|
4574
4190
|
}
|
|
4575
4191
|
deleteErrorCellsUnderPrefix(st, targetSegments);
|
|
4576
|
-
|
|
4577
|
-
|
|
4192
|
+
const raw = toRaw(st.form.value);
|
|
4193
|
+
for (const fieldKey of cleared) {
|
|
4194
|
+
const record = st.fields.get(fieldKey);
|
|
4195
|
+
if (record === void 0 || !hasAtPath(raw, record.path)) continue;
|
|
4196
|
+
raiseStamp(st, fieldKey, record.path, now);
|
|
4197
|
+
}
|
|
4198
|
+
if (cleared.length > 0 && hasAtPath(raw, targetSegments)) {
|
|
4199
|
+
stampContainers(st, [targetSegments], now);
|
|
4578
4200
|
}
|
|
4579
4201
|
}
|
|
4580
4202
|
function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
@@ -4587,36 +4209,35 @@ function deleteErrorCellsUnderPrefix(st, prefix) {
|
|
|
4587
4209
|
}
|
|
4588
4210
|
}
|
|
4589
4211
|
}
|
|
4590
|
-
function clearFieldRecordFlags(st, pathKey) {
|
|
4591
|
-
const record = st.fields.get(pathKey);
|
|
4592
|
-
if (record === void 0) return;
|
|
4593
|
-
st.fields.set(pathKey, withClearedHistoryFlags(record, (/* @__PURE__ */ new Date()).toISOString()));
|
|
4594
|
-
}
|
|
4595
4212
|
function isPristineAtPathByKey(st, key, segments) {
|
|
4596
4213
|
if (st.blankPaths.has(key) !== st.originalBlankPaths.has(key)) return false;
|
|
4597
4214
|
const entry = st.originals.get(key);
|
|
4598
4215
|
if (entry === void 0) return true;
|
|
4599
4216
|
return Object.is(getAtPath(st.form.value, segments), entry.value);
|
|
4600
4217
|
}
|
|
4601
|
-
function hasStructuralChangeUnder(st, path) {
|
|
4218
|
+
function hasStructuralChangeUnder(st, path, key) {
|
|
4219
|
+
subscribeStructure(st.structureSignal, key);
|
|
4602
4220
|
return st.arrayIdentity.hasStructuralChangeUnder(path);
|
|
4603
4221
|
}
|
|
4604
|
-
function
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4222
|
+
function pulseStructure(signal, paths) {
|
|
4223
|
+
const keys = signal.keys;
|
|
4224
|
+
if (keys === null) return;
|
|
4225
|
+
eachAncestorOnce(paths, (key) => {
|
|
4226
|
+
keys.add(key);
|
|
4227
|
+
keys.delete(key);
|
|
4610
4228
|
});
|
|
4611
|
-
return had;
|
|
4612
4229
|
}
|
|
4613
|
-
function
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4230
|
+
function subscribeStructure(signal, key) {
|
|
4231
|
+
signal.keys ?? (signal.keys = shallowReactive(/* @__PURE__ */ new Set()));
|
|
4232
|
+
void signal.keys.has(key);
|
|
4233
|
+
}
|
|
4234
|
+
function hasRemovedSubtreeUnder(st, prefix, key) {
|
|
4235
|
+
subscribeStructure(st.structureSignal, key);
|
|
4236
|
+
if (st.removedPaths.size === 0) return false;
|
|
4237
|
+
const raw = toRaw(st.form.value);
|
|
4238
|
+
for (const segments of st.removedPaths.values()) {
|
|
4618
4239
|
if (!isPathPrefix(prefix, segments)) continue;
|
|
4619
|
-
if (
|
|
4240
|
+
if (hasAtPath(raw, segments)) continue;
|
|
4620
4241
|
return true;
|
|
4621
4242
|
}
|
|
4622
4243
|
return false;
|
|
@@ -4652,10 +4273,14 @@ function createFormStore(options) {
|
|
|
4652
4273
|
warn: true
|
|
4653
4274
|
}) : initialData;
|
|
4654
4275
|
const form = ref(stubbedInitialData);
|
|
4655
|
-
const
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4276
|
+
const structureSignal = { keys: null };
|
|
4277
|
+
const arrayIdentity = createArrayIdentity(
|
|
4278
|
+
(arraySegs) => {
|
|
4279
|
+
const v = getAtPath(toRaw(form.value), arraySegs);
|
|
4280
|
+
return Array.isArray(v) ? v.length : 0;
|
|
4281
|
+
},
|
|
4282
|
+
(arrayPaths) => pulseStructure(structureSignal, arrayPaths)
|
|
4283
|
+
);
|
|
4659
4284
|
const fields = shallowReactive(/* @__PURE__ */ new Map());
|
|
4660
4285
|
const domBinding = shallowRef(null);
|
|
4661
4286
|
const errorStore = createErrorCells(
|
|
@@ -4664,7 +4289,7 @@ function createFormStore(options) {
|
|
|
4664
4289
|
);
|
|
4665
4290
|
const errorCells = () => errorStore(true);
|
|
4666
4291
|
const originals = shallowReactive(/* @__PURE__ */ new Map());
|
|
4667
|
-
const
|
|
4292
|
+
const removedPaths = /* @__PURE__ */ new Map();
|
|
4668
4293
|
const blankPaths = reactive(/* @__PURE__ */ new Set());
|
|
4669
4294
|
const originalBlankPaths = /* @__PURE__ */ new Set();
|
|
4670
4295
|
const seededBlankPaths = hydration !== void 0 ? (hydration.blankPaths ?? []).map((dotted) => canonicalizePath(dotted).key) : options.initialBlankPaths ?? [];
|
|
@@ -4773,6 +4398,8 @@ function createFormStore(options) {
|
|
|
4773
4398
|
blankPaths,
|
|
4774
4399
|
originalBlankPaths,
|
|
4775
4400
|
authoredPaths,
|
|
4401
|
+
removedPaths,
|
|
4402
|
+
notifyStructure: (paths) => pulseStructure(structureSignal, paths),
|
|
4776
4403
|
fieldValidationCounts,
|
|
4777
4404
|
fieldValidatingSince,
|
|
4778
4405
|
fieldValidationState,
|
|
@@ -4780,6 +4407,9 @@ function createFormStore(options) {
|
|
|
4780
4407
|
arrayIdentity,
|
|
4781
4408
|
variantMemory,
|
|
4782
4409
|
touchFieldRecord: (pathKey, path, patch) => touchFieldRecord(st, pathKey, path, patch),
|
|
4410
|
+
stampContainers: (containers, now) => stampContainers(st, containers, now),
|
|
4411
|
+
stampBareContainers: (patches, bare, now) => stampBareContainers(st, patches, bare, now),
|
|
4412
|
+
foldInteractionHistory: (path, released) => foldInteractionHistory(st, path, released),
|
|
4783
4413
|
decFieldValidation: (key) => decFieldValidation(st, key)
|
|
4784
4414
|
});
|
|
4785
4415
|
const bind = (fn) => (...args) => fn(st, ...args);
|
|
@@ -4830,6 +4460,8 @@ function createFormStore(options) {
|
|
|
4830
4460
|
// the literal they passed from mutating the form's defaults from outside.
|
|
4831
4461
|
// `reset()` snapshots for a harder reason, where an alias IS reachable.
|
|
4832
4462
|
defaultValues: ownDefaultValues,
|
|
4463
|
+
// The form holds a copy of it, or the hydration payload.
|
|
4464
|
+
baselineValue: schemaInitialData,
|
|
4833
4465
|
ssrPrefetch,
|
|
4834
4466
|
rememberVariants,
|
|
4835
4467
|
fieldValidationMode,
|
|
@@ -4843,7 +4475,8 @@ function createFormStore(options) {
|
|
|
4843
4475
|
cleanupHooks,
|
|
4844
4476
|
authoredPaths,
|
|
4845
4477
|
arrayIdentity,
|
|
4846
|
-
|
|
4478
|
+
removedPaths,
|
|
4479
|
+
structureSignal,
|
|
4847
4480
|
variantMemory,
|
|
4848
4481
|
pathOrdinals,
|
|
4849
4482
|
pathSnapshots,
|
|
@@ -4853,6 +4486,7 @@ function createFormStore(options) {
|
|
|
4853
4486
|
arrayBookkeeping,
|
|
4854
4487
|
skipErrorSeed: () => errorStore(false),
|
|
4855
4488
|
nextOrdinal: 0,
|
|
4489
|
+
latestStamp: "",
|
|
4856
4490
|
scheduleEpoch: 0,
|
|
4857
4491
|
lastCommittedEpoch: 0,
|
|
4858
4492
|
transformTokenSeq: 0,
|
|
@@ -4865,6 +4499,7 @@ function createFormStore(options) {
|
|
|
4865
4499
|
applyFormReplacement: bind(applyFormReplacement),
|
|
4866
4500
|
setValueAtPath: bind(setValueAtPath),
|
|
4867
4501
|
getValueAtPath: bind(getValueAtPath),
|
|
4502
|
+
getOriginalAtPath: bind(getOriginalAtPath),
|
|
4868
4503
|
arrayElementKey: bind(arrayElementKey),
|
|
4869
4504
|
reset: bind(reset),
|
|
4870
4505
|
resetField: bind(resetField),
|
|
@@ -4890,6 +4525,8 @@ function createFormStore(options) {
|
|
|
4890
4525
|
),
|
|
4891
4526
|
clearUserErrors: (path) => clearErrorChannel(st, "user", path),
|
|
4892
4527
|
restoreErrorCells: bind(restoreErrorCells),
|
|
4528
|
+
captureStructure: bind(captureStructure),
|
|
4529
|
+
restoreStructure: bind(restoreStructure),
|
|
4893
4530
|
getErrorsForPath: bind(getErrorsForPath),
|
|
4894
4531
|
ensurePathOrdinal: bind(ensurePathOrdinal),
|
|
4895
4532
|
noteDomConnected: bind(noteDomConnected),
|
|
@@ -4923,7 +4560,7 @@ function createFormStore(options) {
|
|
|
4923
4560
|
diffAndApply({}, schemaInitialData, [], (patch) => {
|
|
4924
4561
|
if (patch.kind !== "added") return;
|
|
4925
4562
|
const { key } = canonicalizePath(patch.path);
|
|
4926
|
-
originals
|
|
4563
|
+
if (seedBaseline(originals, key, patch)) return;
|
|
4927
4564
|
ensurePathOrdinal(st, key);
|
|
4928
4565
|
if (hydration === void 0) {
|
|
4929
4566
|
fields.set(key, {
|
|
@@ -4938,6 +4575,7 @@ function createFormStore(options) {
|
|
|
4938
4575
|
});
|
|
4939
4576
|
}
|
|
4940
4577
|
});
|
|
4578
|
+
if (fields.size > 0) noteStamp(st, initStamp);
|
|
4941
4579
|
if (hydration !== void 0) {
|
|
4942
4580
|
for (const [rawKey, record] of hydration.fields) {
|
|
4943
4581
|
if (typeof rawKey !== "string" || !isHydratedFieldRecord(record)) {
|
|
@@ -4945,6 +4583,7 @@ function createFormStore(options) {
|
|
|
4945
4583
|
continue;
|
|
4946
4584
|
}
|
|
4947
4585
|
fields.set(rawKey, record);
|
|
4586
|
+
noteStamp(st, record.updatedAt);
|
|
4948
4587
|
}
|
|
4949
4588
|
for (const [rawKey, errs] of hydration.schemaErrors) {
|
|
4950
4589
|
if (typeof rawKey !== "string" || !isHydratedValidationErrorArray(errs)) {
|
|
@@ -5522,7 +5161,7 @@ function buildWizardStatusesProxy(statuses) {
|
|
|
5522
5161
|
// resolves to `undefined` (consistent with property-access).
|
|
5523
5162
|
resolveCall: (arg) => statuses[String(arg)]?.value,
|
|
5524
5163
|
ownKeys: () => Object.keys(statuses),
|
|
5525
|
-
hasKey: (key) =>
|
|
5164
|
+
hasKey: (key) => safeOwnHas(statuses, key)
|
|
5526
5165
|
});
|
|
5527
5166
|
}
|
|
5528
5167
|
|
|
@@ -6825,4 +6464,4 @@ function escapeForInlineScript(json) {
|
|
|
6825
6464
|
});
|
|
6826
6465
|
}
|
|
6827
6466
|
|
|
6828
|
-
export {
|
|
6467
|
+
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 };
|