attaform 0.21.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/dev-key-collision-warnings.cjs +1 -1
- package/dist/chunks/dev-key-collision-warnings.mjs +1 -1
- package/dist/chunks/devtools.cjs +1 -1
- package/dist/chunks/devtools.mjs +1 -1
- package/dist/chunks/fingerprint2.cjs +1 -1
- package/dist/chunks/fingerprint2.mjs +1 -1
- package/dist/chunks/indexeddb.cjs +1 -1
- package/dist/chunks/indexeddb.mjs +1 -1
- package/dist/chunks/local-storage.cjs +1 -1
- package/dist/chunks/local-storage.mjs +1 -1
- package/dist/chunks/multi-tab-sync.cjs +2 -2
- package/dist/chunks/multi-tab-sync.mjs +2 -2
- package/dist/chunks/session-storage.cjs +1 -1
- package/dist/chunks/session-storage.mjs +1 -1
- package/dist/chunks/wire-persistence.cjs +2 -2
- package/dist/chunks/wire-persistence.mjs +2 -2
- package/dist/index.cjs +37 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -18
- package/dist/index.d.mts +20 -18
- package/dist/index.d.ts +20 -18
- package/dist/index.mjs +38 -25
- package/dist/index.mjs.map +1 -1
- package/dist/nuxt.d.cts +1 -1
- package/dist/nuxt.d.mts +1 -1
- package/dist/nuxt.d.ts +1 -1
- package/dist/runtime/components/AttaformDevtoolsPanel.vue +396 -216
- package/dist/runtime/components/DevtoolsValueTree.vue +176 -114
- package/dist/runtime/plugins/attaform.cjs +2 -2
- package/dist/runtime/plugins/attaform.mjs +2 -2
- package/dist/shared/{attaform.D32WwKk6.cjs → attaform.01iKS_lz.cjs} +260 -356
- package/dist/shared/attaform.01iKS_lz.cjs.map +1 -0
- package/dist/shared/{attaform.Y1ZGhM4k.mjs → attaform.6xE0Lcfd.mjs} +2 -2
- package/dist/shared/{attaform.Y1ZGhM4k.mjs.map → attaform.6xE0Lcfd.mjs.map} +1 -1
- package/dist/shared/{attaform.S-pYLSo4.cjs → attaform.AyujQoHp.cjs} +13 -16
- package/dist/shared/attaform.AyujQoHp.cjs.map +1 -0
- package/dist/shared/{attaform.BupwXkj_.mjs → attaform.BFWb6hDk.mjs} +29 -23
- package/dist/shared/attaform.BFWb6hDk.mjs.map +1 -0
- package/dist/shared/{attaform.NQ8mybyW.d.mts → attaform.BGwNZ9GV.d.cts} +63 -64
- package/dist/shared/{attaform.pmtahXKy.mjs → attaform.BKFwekY2.mjs} +257 -356
- package/dist/shared/attaform.BKFwekY2.mjs.map +1 -0
- package/dist/shared/{attaform.BSkvn43g.cjs → attaform.C-RtnCJM.cjs} +116 -47
- package/dist/shared/attaform.C-RtnCJM.cjs.map +1 -0
- package/dist/shared/{attaform.Bv7dRDWK.d.ts → attaform.CCCeEPwa.d.mts} +63 -64
- package/dist/shared/{attaform.BM6YD9kZ.cjs → attaform.CR6wGvNu.cjs} +29 -23
- package/dist/shared/attaform.CR6wGvNu.cjs.map +1 -0
- package/dist/shared/{attaform.Bq5sX7TF.cjs → attaform.CRzpFCjV.cjs} +2 -2
- package/dist/shared/{attaform.Bq5sX7TF.cjs.map → attaform.CRzpFCjV.cjs.map} +1 -1
- package/dist/shared/{attaform.ClXwitZj.cjs → attaform.CjMcwV7W.cjs} +894 -342
- package/dist/shared/attaform.CjMcwV7W.cjs.map +1 -0
- package/dist/shared/{attaform.DR6RmxWZ.mjs → attaform.CsB-iKbU.mjs} +888 -337
- package/dist/shared/attaform.CsB-iKbU.mjs.map +1 -0
- package/dist/shared/{attaform.BWfliRIK.d.cts → attaform.D4XYaasQ.d.ts} +63 -64
- package/dist/shared/{attaform.Be8NZG9M.mjs → attaform.DCjgGir_.mjs} +19 -45
- package/dist/shared/attaform.DCjgGir_.mjs.map +1 -0
- package/dist/shared/{attaform.DMEP_ENr.mjs → attaform.DNuiFCXG.mjs} +14 -17
- package/dist/shared/attaform.DNuiFCXG.mjs.map +1 -0
- package/dist/shared/{attaform.MtrpT6Ki.d.ts → attaform.DUMWQefY.d.ts} +1 -1
- package/dist/shared/{attaform.DozgVlCE.mjs → attaform.DgCfLqay.mjs} +116 -47
- package/dist/shared/attaform.DgCfLqay.mjs.map +1 -0
- package/dist/shared/{attaform.D0dWZsJt.d.mts → attaform.DvUH4a3o.d.cts} +307 -133
- package/dist/shared/{attaform.D0dWZsJt.d.cts → attaform.DvUH4a3o.d.mts} +307 -133
- package/dist/shared/{attaform.D0dWZsJt.d.ts → attaform.DvUH4a3o.d.ts} +307 -133
- package/dist/shared/{attaform.Duecg2NO.d.mts → attaform.FN0vaQAg.d.mts} +1 -1
- package/dist/shared/{attaform.CICFZ1iS.cjs → attaform.Q3eAD2wD.cjs} +19 -45
- package/dist/shared/attaform.Q3eAD2wD.cjs.map +1 -0
- package/dist/shared/{attaform.FudOcHaa.d.cts → attaform.aekT7mMx.d.cts} +1 -1
- package/dist/transforms.cjs +1 -1
- package/dist/transforms.mjs +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/dist/zod-v3.cjs +3 -4
- package/dist/zod-v3.cjs.map +1 -1
- package/dist/zod-v3.d.cts +4 -4
- package/dist/zod-v3.d.mts +4 -4
- package/dist/zod-v3.d.ts +4 -4
- package/dist/zod-v3.mjs +2 -3
- package/dist/zod-v3.mjs.map +1 -1
- package/dist/zod-v4.cjs +3 -4
- package/dist/zod-v4.cjs.map +1 -1
- package/dist/zod-v4.d.cts +4 -4
- package/dist/zod-v4.d.mts +4 -4
- package/dist/zod-v4.d.ts +4 -4
- package/dist/zod-v4.mjs +2 -3
- package/dist/zod-v4.mjs.map +1 -1
- package/dist/zod.cjs +6 -6
- package/dist/zod.cjs.map +1 -1
- package/dist/zod.d.cts +31 -22
- package/dist/zod.d.mts +31 -22
- package/dist/zod.d.ts +31 -22
- package/dist/zod.mjs +5 -6
- package/dist/zod.mjs.map +1 -1
- package/package.json +4 -12
- package/dist/shared/attaform.BM6YD9kZ.cjs.map +0 -1
- package/dist/shared/attaform.BSkvn43g.cjs.map +0 -1
- package/dist/shared/attaform.Be8NZG9M.mjs.map +0 -1
- package/dist/shared/attaform.BupwXkj_.mjs.map +0 -1
- package/dist/shared/attaform.CICFZ1iS.cjs.map +0 -1
- package/dist/shared/attaform.ClXwitZj.cjs.map +0 -1
- package/dist/shared/attaform.D32WwKk6.cjs.map +0 -1
- package/dist/shared/attaform.DMEP_ENr.mjs.map +0 -1
- package/dist/shared/attaform.DR6RmxWZ.mjs.map +0 -1
- package/dist/shared/attaform.DozgVlCE.mjs.map +0 -1
- package/dist/shared/attaform.S-pYLSo4.cjs.map +0 -1
- package/dist/shared/attaform.pmtahXKy.mjs.map +0 -1
- package/dist/shared/{attaform.DSD85fHb.d.cts → attaform.nf83TIR5.d.cts} +10 -10
- package/dist/shared/{attaform.DSD85fHb.d.mts → attaform.nf83TIR5.d.mts} +10 -10
- package/dist/shared/{attaform.DSD85fHb.d.ts → attaform.nf83TIR5.d.ts} +10 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, watch, markRaw, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, effectScope, nextTick } from 'vue';
|
|
2
|
-
import { _ as __DEV__,
|
|
1
|
+
import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, isRef, toValue, watch, markRaw, triggerRef, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
|
|
2
|
+
import { q as pathsEqual, l as isPathPrefix, _ as __DEV__, a as canonicalizePath, s as segmentsForPathKey, F as FORM_ERRORS_PATH_KEY, r as keyForSegments, S as SubmitErrorHandlerError, t as toError, A as AnonPersistError, w as INTERACTIVE_TAG_NAMES, x as getOrAssignElementId, R as ROOT_PATH, y as allowSensitivePersist, z as FORM_ERRORS_PATH, e as ROOT_PATH_KEY, B as segmentsToDotted, C as coerceToPathKey, E as isSensitivePath, G as createPersistOptInRegistry, d as InvalidUseFormConfigError, H as ensureAttaformInstalled, u as useRegistry, J as kFormContext, K as kFormInstanceId, h as ReservedFormKeyError, L as createIsSensitivePath, M as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, k as kAttaformWizardActiveStepResolver, N as kAttaformAncestorWizard } from './attaform.BKFwekY2.mjs';
|
|
3
3
|
|
|
4
4
|
function safeAssign(target, key, value) {
|
|
5
5
|
if (key === "__proto__") {
|
|
@@ -34,7 +34,7 @@ function descendStep(value, segment) {
|
|
|
34
34
|
if (typeof value !== "object") return NOT_FOUND;
|
|
35
35
|
if (Array.isArray(value)) {
|
|
36
36
|
if (typeof segment !== "number") return NOT_FOUND;
|
|
37
|
-
if (segment
|
|
37
|
+
if (!(segment in value)) return NOT_FOUND;
|
|
38
38
|
return value[segment];
|
|
39
39
|
}
|
|
40
40
|
const record = value;
|
|
@@ -69,7 +69,7 @@ function hasAtPath(root, path) {
|
|
|
69
69
|
if (current === null || current === void 0) return false;
|
|
70
70
|
if (typeof current !== "object") return false;
|
|
71
71
|
if (Array.isArray(current)) {
|
|
72
|
-
return typeof last === "number" && last
|
|
72
|
+
return typeof last === "number" && last in current;
|
|
73
73
|
}
|
|
74
74
|
const key = typeof last === "number" ? String(last) : last;
|
|
75
75
|
if (isShadowedKey(key)) return safeOwnHas(current, key);
|
|
@@ -98,6 +98,31 @@ function setAtPathOffset(root, path, value, offset) {
|
|
|
98
98
|
safeAssign(rec, head, setAtPathOffset(safeOwnRead(rec, head), path, value, nextOffset));
|
|
99
99
|
return rec;
|
|
100
100
|
}
|
|
101
|
+
const NO_IN_PLACE = { applied: false };
|
|
102
|
+
function tryInPlaceLeafWrite(root, path, value) {
|
|
103
|
+
if (path.length === 0) return NO_IN_PLACE;
|
|
104
|
+
let node = root;
|
|
105
|
+
for (let i = 0; i < path.length; i++) {
|
|
106
|
+
const seg = path[i];
|
|
107
|
+
if (Array.isArray(node)) {
|
|
108
|
+
if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
|
|
109
|
+
} else if (isPlainRecord(node)) {
|
|
110
|
+
if (typeof seg !== "string" || isShadowedKey(seg) || !(seg in node)) return NO_IN_PLACE;
|
|
111
|
+
} else {
|
|
112
|
+
return NO_IN_PLACE;
|
|
113
|
+
}
|
|
114
|
+
const container = node;
|
|
115
|
+
if (i < path.length - 1) {
|
|
116
|
+
node = container[seg];
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const old = container[seg];
|
|
120
|
+
if (isPlainRecord(old) || Array.isArray(old)) return NO_IN_PLACE;
|
|
121
|
+
container[seg] = value;
|
|
122
|
+
return { applied: true, old };
|
|
123
|
+
}
|
|
124
|
+
return NO_IN_PLACE;
|
|
125
|
+
}
|
|
101
126
|
function deleteAtPath(root, path) {
|
|
102
127
|
return deleteAtPathOffset(root, path, 0);
|
|
103
128
|
}
|
|
@@ -160,68 +185,80 @@ function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
|
|
|
160
185
|
}
|
|
161
186
|
if (consumer === null) return null;
|
|
162
187
|
if (Array.isArray(consumer)) {
|
|
163
|
-
|
|
164
|
-
const isTuple = typeof shape === "number";
|
|
165
|
-
const targetLen = isTuple ? shape : consumer.length;
|
|
166
|
-
let cachedElementDefault;
|
|
167
|
-
let cachedElementDefaultRead = false;
|
|
168
|
-
let mutated = targetLen > consumer.length;
|
|
169
|
-
const out = consumer.slice();
|
|
170
|
-
while (out.length < targetLen) out.push(void 0);
|
|
171
|
-
for (let i = 0; i < targetLen; i++) {
|
|
172
|
-
scratch.push(i);
|
|
173
|
-
let elemDefault;
|
|
174
|
-
if (isTuple) {
|
|
175
|
-
elemDefault = schema.getDefaultAtPath(scratch);
|
|
176
|
-
} else {
|
|
177
|
-
if (!cachedElementDefaultRead) {
|
|
178
|
-
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
179
|
-
cachedElementDefaultRead = true;
|
|
180
|
-
}
|
|
181
|
-
elemDefault = cachedElementDefault;
|
|
182
|
-
}
|
|
183
|
-
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
184
|
-
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
185
|
-
scratch.pop();
|
|
186
|
-
if (merged !== consumerElem) {
|
|
187
|
-
out[i] = merged;
|
|
188
|
-
mutated = true;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return mutated ? out : consumer;
|
|
188
|
+
return mergeStructuralArray(schema, scratch, consumer);
|
|
192
189
|
}
|
|
193
190
|
if (isPlainRecord(consumer)) {
|
|
194
191
|
if (!isPlainRecord(defaultValue)) {
|
|
195
192
|
return consumer;
|
|
196
193
|
}
|
|
197
|
-
let mutated = false;
|
|
198
194
|
const out = { ...consumer };
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
195
|
+
const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
|
|
196
|
+
const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
|
|
197
|
+
return filledAny || recursedAny ? out : consumer;
|
|
198
|
+
}
|
|
199
|
+
return consumer;
|
|
200
|
+
}
|
|
201
|
+
function mergeStructuralArray(schema, scratch, consumer) {
|
|
202
|
+
const shape = resolveArrayShape(schema, scratch);
|
|
203
|
+
const isTuple = typeof shape === "number";
|
|
204
|
+
const targetLen = isTuple ? shape : consumer.length;
|
|
205
|
+
let cachedElementDefault;
|
|
206
|
+
let cachedElementDefaultRead = false;
|
|
207
|
+
let mutated = targetLen > consumer.length;
|
|
208
|
+
const out = consumer.slice();
|
|
209
|
+
while (out.length < targetLen) out.push(void 0);
|
|
210
|
+
for (let i = 0; i < targetLen; i++) {
|
|
211
|
+
scratch.push(i);
|
|
212
|
+
let elemDefault;
|
|
213
|
+
if (isTuple) {
|
|
214
|
+
elemDefault = schema.getDefaultAtPath(scratch);
|
|
215
|
+
} else {
|
|
216
|
+
if (!cachedElementDefaultRead) {
|
|
217
|
+
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
218
|
+
cachedElementDefaultRead = true;
|
|
209
219
|
}
|
|
220
|
+
elemDefault = cachedElementDefault;
|
|
221
|
+
}
|
|
222
|
+
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
223
|
+
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
224
|
+
scratch.pop();
|
|
225
|
+
if (merged !== consumerElem) {
|
|
226
|
+
out[i] = merged;
|
|
227
|
+
mutated = true;
|
|
210
228
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
229
|
+
}
|
|
230
|
+
return mutated ? out : consumer;
|
|
231
|
+
}
|
|
232
|
+
function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
|
|
233
|
+
let mutated = false;
|
|
234
|
+
for (const key of Object.keys(defaultValue)) {
|
|
235
|
+
if (!safeOwnHas(consumer, key)) {
|
|
236
|
+
const defAtKey = safeOwnRead(defaultValue, key);
|
|
214
237
|
scratch.push(key);
|
|
215
|
-
const
|
|
238
|
+
const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
|
|
216
239
|
scratch.pop();
|
|
217
|
-
if (
|
|
218
|
-
safeAssign(out, key,
|
|
240
|
+
if (filled !== void 0) {
|
|
241
|
+
safeAssign(out, key, filled);
|
|
219
242
|
mutated = true;
|
|
220
243
|
}
|
|
221
244
|
}
|
|
222
|
-
return mutated ? out : consumer;
|
|
223
245
|
}
|
|
224
|
-
return
|
|
246
|
+
return mutated;
|
|
247
|
+
}
|
|
248
|
+
function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
|
|
249
|
+
let mutated = false;
|
|
250
|
+
for (const key of Object.keys(consumer)) {
|
|
251
|
+
const cVal = safeOwnRead(consumer, key);
|
|
252
|
+
if (cVal === void 0) continue;
|
|
253
|
+
scratch.push(key);
|
|
254
|
+
const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
|
|
255
|
+
scratch.pop();
|
|
256
|
+
if (merged !== cVal) {
|
|
257
|
+
safeAssign(out, key, merged);
|
|
258
|
+
mutated = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return mutated;
|
|
225
262
|
}
|
|
226
263
|
function setAtPathWithSchemaFill(root, schema, fullPath, value) {
|
|
227
264
|
if (fullPath.length === 0) return value;
|
|
@@ -304,55 +341,27 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
304
341
|
const oldIsDescendable = isDescendable(oldValue);
|
|
305
342
|
const newIsDescendable = isDescendable(newValue);
|
|
306
343
|
if (oldValue === void 0 && newIsDescendable) {
|
|
307
|
-
|
|
308
|
-
for (let i = 0; i < newValue.length; i++) {
|
|
309
|
-
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
const rec = newValue;
|
|
313
|
-
for (const k of Object.keys(rec)) {
|
|
314
|
-
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
344
|
+
walkNewDescendable(newValue, prefix, visit);
|
|
317
345
|
return;
|
|
318
346
|
}
|
|
319
347
|
if (oldIsDescendable && newValue === void 0) {
|
|
320
|
-
|
|
321
|
-
for (let i = 0; i < oldValue.length; i++) {
|
|
322
|
-
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
323
|
-
}
|
|
324
|
-
} else {
|
|
325
|
-
const rec = oldValue;
|
|
326
|
-
for (const k of Object.keys(rec)) {
|
|
327
|
-
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
348
|
+
walkOldDescendable(oldValue, prefix, visit);
|
|
330
349
|
return;
|
|
331
350
|
}
|
|
332
351
|
if (oldIsDescendable && newIsDescendable) {
|
|
333
352
|
const oldIsArray = Array.isArray(oldValue);
|
|
334
353
|
const newIsArray = Array.isArray(newValue);
|
|
335
354
|
if (oldIsArray && newIsArray) {
|
|
336
|
-
|
|
337
|
-
const newArr = newValue;
|
|
338
|
-
const max = Math.max(oldArr.length, newArr.length);
|
|
339
|
-
for (let i = 0; i < max; i++) {
|
|
340
|
-
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
341
|
-
}
|
|
355
|
+
diffArraysLockstep(oldValue, newValue, prefix, visit);
|
|
342
356
|
return;
|
|
343
357
|
}
|
|
344
358
|
if (!oldIsArray && !newIsArray) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
for (const k of Object.keys(newRec)) {
|
|
353
|
-
if (seen.has(k)) continue;
|
|
354
|
-
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
355
|
-
}
|
|
359
|
+
diffObjectsLockstep(
|
|
360
|
+
oldValue,
|
|
361
|
+
newValue,
|
|
362
|
+
prefix,
|
|
363
|
+
visit
|
|
364
|
+
);
|
|
356
365
|
return;
|
|
357
366
|
}
|
|
358
367
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
@@ -376,7 +385,48 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
376
385
|
}
|
|
377
386
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
378
387
|
}
|
|
379
|
-
function
|
|
388
|
+
function walkNewDescendable(newValue, prefix, visit) {
|
|
389
|
+
if (Array.isArray(newValue)) {
|
|
390
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
391
|
+
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
392
|
+
}
|
|
393
|
+
} else {
|
|
394
|
+
const rec = newValue;
|
|
395
|
+
for (const k of Object.keys(rec)) {
|
|
396
|
+
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function walkOldDescendable(oldValue, prefix, visit) {
|
|
401
|
+
if (Array.isArray(oldValue)) {
|
|
402
|
+
for (let i = 0; i < oldValue.length; i++) {
|
|
403
|
+
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
const rec = oldValue;
|
|
407
|
+
for (const k of Object.keys(rec)) {
|
|
408
|
+
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function diffArraysLockstep(oldArr, newArr, prefix, visit) {
|
|
413
|
+
const max = Math.max(oldArr.length, newArr.length);
|
|
414
|
+
for (let i = 0; i < max; i++) {
|
|
415
|
+
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function diffObjectsLockstep(oldRec, newRec, prefix, visit) {
|
|
419
|
+
const seen = /* @__PURE__ */ new Set();
|
|
420
|
+
for (const k of Object.keys(oldRec)) {
|
|
421
|
+
seen.add(k);
|
|
422
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
423
|
+
}
|
|
424
|
+
for (const k of Object.keys(newRec)) {
|
|
425
|
+
if (seen.has(k)) continue;
|
|
426
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
function applyChangedKeys(target, source, arrayOpPath, currentPath) {
|
|
380
430
|
if (!isDescendable(target) || !isDescendable(source)) return false;
|
|
381
431
|
const targetIsArray = Array.isArray(target);
|
|
382
432
|
const sourceIsArray = Array.isArray(source);
|
|
@@ -394,11 +444,27 @@ function applyChangedKeys(target, source) {
|
|
|
394
444
|
if (targetIsArray) {
|
|
395
445
|
const t = target;
|
|
396
446
|
const s = source;
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
447
|
+
if (arrayOpPath === null || pathsEqual(currentPath, arrayOpPath)) {
|
|
448
|
+
if (t.length > s.length) t.length = s.length;
|
|
449
|
+
for (const idx of changedFirstSegments) {
|
|
450
|
+
if (typeof idx === "symbol") continue;
|
|
451
|
+
const i = typeof idx === "number" ? idx : Number(idx);
|
|
452
|
+
if (i >= s.length) continue;
|
|
453
|
+
t[i] = s[i];
|
|
454
|
+
}
|
|
455
|
+
} else {
|
|
456
|
+
for (const idx of changedFirstSegments) {
|
|
457
|
+
if (typeof idx === "symbol") continue;
|
|
458
|
+
const i = typeof idx === "number" ? idx : Number(idx);
|
|
459
|
+
if (i >= s.length) continue;
|
|
460
|
+
const childPath = appendSegment(currentPath, i);
|
|
461
|
+
const curEl = t[i];
|
|
462
|
+
const nextEl = s[i];
|
|
463
|
+
if (isPathPrefix(childPath, arrayOpPath) && isDescendable(curEl) && isDescendable(nextEl) && applyChangedKeys(curEl, nextEl, arrayOpPath, childPath)) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
t[i] = nextEl;
|
|
467
|
+
}
|
|
402
468
|
}
|
|
403
469
|
} else {
|
|
404
470
|
const t = target;
|
|
@@ -410,7 +476,14 @@ function applyChangedKeys(target, source) {
|
|
|
410
476
|
for (const k of changedFirstSegments) {
|
|
411
477
|
if (typeof k === "symbol") continue;
|
|
412
478
|
const key = String(k);
|
|
413
|
-
|
|
479
|
+
const nextVal = safeOwnRead(s, key);
|
|
480
|
+
if (arrayOpPath !== null) {
|
|
481
|
+
const curVal = safeOwnRead(t, key);
|
|
482
|
+
if (isDescendable(curVal) && isDescendable(nextVal) && applyChangedKeys(curVal, nextVal, arrayOpPath, appendSegment(currentPath, key))) {
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
safeAssign(t, key, nextVal);
|
|
414
487
|
}
|
|
415
488
|
}
|
|
416
489
|
return true;
|
|
@@ -522,6 +595,50 @@ function resolveGetDisplayState(config) {
|
|
|
522
595
|
return config ?? defaultDisplayState;
|
|
523
596
|
}
|
|
524
597
|
|
|
598
|
+
const AttaformErrorCode = {
|
|
599
|
+
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
600
|
+
NoValueSupplied: "atta:no-value-supplied",
|
|
601
|
+
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
602
|
+
AdapterThrew: "atta:adapter-threw",
|
|
603
|
+
/**
|
|
604
|
+
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
605
|
+
* threw (sync or async). The adapter caught the throw and surfaced
|
|
606
|
+
* it as a `ValidationError` at the field path so the form's normal
|
|
607
|
+
* error pipeline handles it instead of leaking as an unhandled
|
|
608
|
+
* rejection or routing through `submitError`.
|
|
609
|
+
*/
|
|
610
|
+
ValidatorThrew: "atta:validator-threw",
|
|
611
|
+
/**
|
|
612
|
+
* A function-form `defaultValues` factory threw or its promise
|
|
613
|
+
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
614
|
+
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
615
|
+
* the standard error pipeline carries the signal. Critical for the
|
|
616
|
+
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
617
|
+
* payload, but `schemaErrors` does, so the client sees the failure
|
|
618
|
+
* after rehydration without an extra channel.
|
|
619
|
+
*/
|
|
620
|
+
HydrationFailed: "atta:hydration-failed",
|
|
621
|
+
/** The supplied path didn't resolve to any node in the schema. */
|
|
622
|
+
PathNotFound: "atta:path-not-found",
|
|
623
|
+
/**
|
|
624
|
+
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
625
|
+
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
626
|
+
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
627
|
+
* aggregate error pipeline can carry the failure alongside ordinary
|
|
628
|
+
* validation errors. The raw factory error remains on
|
|
629
|
+
* `form.hydrateError` for retry UX.
|
|
630
|
+
*/
|
|
631
|
+
ActivationFailed: "atta:activation-failed"
|
|
632
|
+
};
|
|
633
|
+
function makeBlankRequiredError(segments, formKey) {
|
|
634
|
+
return {
|
|
635
|
+
message: "No value supplied",
|
|
636
|
+
path: [...segments],
|
|
637
|
+
formKey,
|
|
638
|
+
code: AttaformErrorCode.NoValueSupplied
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
|
|
525
642
|
const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
|
|
526
643
|
const DEFAULT_PERSISTENCE_DEBOUNCE_MS = 300;
|
|
527
644
|
const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
|
|
@@ -623,13 +740,19 @@ function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options
|
|
|
623
740
|
return c;
|
|
624
741
|
};
|
|
625
742
|
}
|
|
743
|
+
function resolveFieldMetaAndLabel(state, segments) {
|
|
744
|
+
const resolved = state.schema.getFieldMetaAtPath ? state.schema.getFieldMetaAtPath(segments) : EMPTY_RESOLVED_FIELD_META;
|
|
745
|
+
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
746
|
+
const label = resolved.label || humanize(lastSegment);
|
|
747
|
+
return { resolved, label };
|
|
748
|
+
}
|
|
626
749
|
function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
627
750
|
const record = state.fields.get(key);
|
|
628
751
|
const value = state.getValueAtPath(segments);
|
|
629
752
|
const original = state.originals.get(key)?.value;
|
|
630
753
|
const pristine = state.isPristineAtPath(segments);
|
|
631
754
|
const schemaForKey = state.schemaErrors.get(key);
|
|
632
|
-
const blankForKey = state.
|
|
755
|
+
const blankForKey = state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments) ? [makeBlankRequiredError(segments, state.formKey)] : void 0;
|
|
633
756
|
const userForKey = state.userErrors.get(key);
|
|
634
757
|
const errors = [];
|
|
635
758
|
if (schemaForKey !== void 0) errors.push(...schemaForKey);
|
|
@@ -644,9 +767,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
644
767
|
const elementRecord = state.elements.get(key);
|
|
645
768
|
const elementsArr = elementRecord ? Object.freeze([...elementRecord.elements]) : EMPTY_ELEMENTS;
|
|
646
769
|
const firstElement = elementsArr[0] ?? null;
|
|
647
|
-
const resolved = state
|
|
648
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
649
|
-
const label = resolved.label || humanize(lastSegment);
|
|
770
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
650
771
|
return {
|
|
651
772
|
value,
|
|
652
773
|
original,
|
|
@@ -695,9 +816,32 @@ function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBa
|
|
|
695
816
|
getDisplayState
|
|
696
817
|
);
|
|
697
818
|
}
|
|
819
|
+
function visitActiveLeafPaths(value, base, visit) {
|
|
820
|
+
if (Array.isArray(value)) {
|
|
821
|
+
for (let i = 0; i < value.length; i++) {
|
|
822
|
+
const child = value[i];
|
|
823
|
+
if (Array.isArray(child) || isPlainRecord(child)) {
|
|
824
|
+
visitActiveLeafPaths(child, [...base, i], visit);
|
|
825
|
+
} else {
|
|
826
|
+
visit([...base, i]);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (isPlainRecord(value)) {
|
|
832
|
+
for (const k of Object.keys(value)) {
|
|
833
|
+
const child = value[k];
|
|
834
|
+
if (Array.isArray(child) || isPlainRecord(child)) {
|
|
835
|
+
visitActiveLeafPaths(child, [...base, k], visit);
|
|
836
|
+
} else {
|
|
837
|
+
visit([...base, k]);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
698
842
|
function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
699
843
|
const formValue = state.form.value;
|
|
700
|
-
const value =
|
|
844
|
+
const value = getAtPath(formValue, segments);
|
|
701
845
|
const original = state.originals.get(key)?.value;
|
|
702
846
|
let pristine = true;
|
|
703
847
|
let blank = true;
|
|
@@ -716,12 +860,16 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
716
860
|
let asyncPending = false;
|
|
717
861
|
const submissionAttempts = state.submissionAttempts.value;
|
|
718
862
|
const blurredLeafSegments = [];
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
863
|
+
const descendantLeaves = [];
|
|
864
|
+
visitActiveLeafPaths(value, segments, (leafSegments) => {
|
|
865
|
+
const { key: leafKey } = keyForSegments(leafSegments);
|
|
866
|
+
const entry = state.originals.get(leafKey);
|
|
867
|
+
if (entry === void 0) return;
|
|
868
|
+
descendantLeaves.push({ key: leafKey, segments: entry.segments });
|
|
869
|
+
});
|
|
870
|
+
for (const { key: leafKey, segments: leafSeg } of descendantLeaves) {
|
|
723
871
|
const leafRecord = state.fields.get(leafKey);
|
|
724
|
-
if (!state.isPristineAtPathByKey(leafKey,
|
|
872
|
+
if (!state.isPristineAtPathByKey(leafKey, leafSeg)) {
|
|
725
873
|
pristine = false;
|
|
726
874
|
dirty = true;
|
|
727
875
|
}
|
|
@@ -732,7 +880,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
732
880
|
if (leafRecord?.interacted === true) interacted = true;
|
|
733
881
|
if (leafRecord?.blurredAfterInteraction === true) {
|
|
734
882
|
blurredAfterInteraction = true;
|
|
735
|
-
blurredLeafSegments.push(
|
|
883
|
+
blurredLeafSegments.push(leafSeg);
|
|
736
884
|
}
|
|
737
885
|
if (leafRecord?.connected === true) connected = true;
|
|
738
886
|
if ((state.fieldValidationCounts.get(leafKey) ?? 0) > 0) {
|
|
@@ -749,7 +897,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
749
897
|
if (leafGateOpen && since !== void 0 && (transformingSince === null || since < transformingSince))
|
|
750
898
|
transformingSince = since;
|
|
751
899
|
}
|
|
752
|
-
if (state.pathHasAsyncValidationByKey(leafKey,
|
|
900
|
+
if (state.pathHasAsyncValidationByKey(leafKey, leafSeg)) asyncPending = true;
|
|
753
901
|
const ts = leafRecord?.updatedAt;
|
|
754
902
|
if (ts !== void 0 && ts !== null) {
|
|
755
903
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
@@ -783,9 +931,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
783
931
|
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
784
932
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
785
933
|
const valid = !gated && errors.length === 0 && !validating;
|
|
786
|
-
const resolved = state
|
|
787
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
788
|
-
const label = resolved.label || humanize(lastSegment);
|
|
934
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
789
935
|
return {
|
|
790
936
|
base: {
|
|
791
937
|
value,
|
|
@@ -1378,7 +1524,7 @@ function buildFieldArrayApi(state) {
|
|
|
1378
1524
|
append(path, value) {
|
|
1379
1525
|
const next = readArray(path);
|
|
1380
1526
|
next.push(value);
|
|
1381
|
-
return writeArray(path, next);
|
|
1527
|
+
return writeArray(path, next, { kind: "insert", index: next.length - 1 });
|
|
1382
1528
|
},
|
|
1383
1529
|
prepend(path, value) {
|
|
1384
1530
|
const next = readArray(path);
|
|
@@ -1568,20 +1714,20 @@ function buildFieldStateProxy(state, formInstanceId, getFormMetaBase, options) {
|
|
|
1568
1714
|
}
|
|
1569
1715
|
function materializeFields(state, containerSegments, snapshotFieldStateAt) {
|
|
1570
1716
|
const liveValue = getAtPath(state.form.value, containerSegments);
|
|
1571
|
-
return walk$
|
|
1717
|
+
return walk$1(liveValue, containerSegments, state.schema, snapshotFieldStateAt);
|
|
1572
1718
|
}
|
|
1573
|
-
function walk$
|
|
1719
|
+
function walk$1(value, basePath, schema, snapshotFieldStateAt) {
|
|
1574
1720
|
if (schema.isLeafAtPath(basePath)) return snapshotFieldStateAt(basePath);
|
|
1575
1721
|
if (value === null || value === void 0) return value;
|
|
1576
1722
|
if (typeof value !== "object") {
|
|
1577
1723
|
return value;
|
|
1578
1724
|
}
|
|
1579
1725
|
if (Array.isArray(value)) {
|
|
1580
|
-
return value.map((_, i) => walk$
|
|
1726
|
+
return value.map((_, i) => walk$1(value[i], [...basePath, i], schema, snapshotFieldStateAt));
|
|
1581
1727
|
}
|
|
1582
1728
|
const result = {};
|
|
1583
1729
|
for (const key of Object.keys(value)) {
|
|
1584
|
-
result[key] = walk$
|
|
1730
|
+
result[key] = walk$1(
|
|
1585
1731
|
value[key],
|
|
1586
1732
|
[...basePath, key],
|
|
1587
1733
|
schema,
|
|
@@ -1665,87 +1811,46 @@ function mergeDeep(target, source, path, schema) {
|
|
|
1665
1811
|
if (!isPlainRecord(source)) return source;
|
|
1666
1812
|
if (schema !== void 0) {
|
|
1667
1813
|
const du = schema.getUnionDiscriminatorAtPath(path);
|
|
1668
|
-
if (du !== void 0)
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
out2,
|
|
1682
|
-
key,
|
|
1683
|
-
mergeDeep(
|
|
1684
|
-
safeOwnRead(out2, key),
|
|
1685
|
-
safeOwnRead(sourceRecord, key),
|
|
1686
|
-
[...path, key],
|
|
1687
|
-
schema
|
|
1688
|
-
)
|
|
1689
|
-
);
|
|
1690
|
-
}
|
|
1691
|
-
return out2;
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
return {};
|
|
1814
|
+
if (du !== void 0) return mergeDuAwareKeys(source, path, schema, du);
|
|
1815
|
+
}
|
|
1816
|
+
return mergeObjectKeys(target, source, path, schema);
|
|
1817
|
+
}
|
|
1818
|
+
function mergeDuAwareKeys(source, path, schema, du) {
|
|
1819
|
+
const sourceDisc = source[du.discriminatorKey];
|
|
1820
|
+
if (sourceDisc !== void 0 && !du.isVariantSelected(sourceDisc)) {
|
|
1821
|
+
return { [du.discriminatorKey]: sourceDisc };
|
|
1822
|
+
}
|
|
1823
|
+
if (sourceDisc !== void 0) {
|
|
1824
|
+
const variantDefault = du.getVariantDefault(sourceDisc);
|
|
1825
|
+
if (isPlainRecord(variantDefault)) {
|
|
1826
|
+
return mergeVariantKeys(source, variantDefault, path, schema, du);
|
|
1695
1827
|
}
|
|
1696
1828
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1829
|
+
return {};
|
|
1830
|
+
}
|
|
1831
|
+
function mergeVariantKeys(source, variantDefault, path, schema, du) {
|
|
1832
|
+
const out = { ...variantDefault };
|
|
1699
1833
|
for (const key of Object.keys(source)) {
|
|
1834
|
+
if (!safeOwnHas(variantDefault, key) && key !== du.discriminatorKey) continue;
|
|
1700
1835
|
safeAssign(
|
|
1701
1836
|
out,
|
|
1702
1837
|
key,
|
|
1703
|
-
mergeDeep(
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1838
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
return out;
|
|
1842
|
+
}
|
|
1843
|
+
function mergeObjectKeys(target, source, path, schema) {
|
|
1844
|
+
const out = isPlainRecord(target) ? { ...target } : {};
|
|
1845
|
+
for (const key of Object.keys(source)) {
|
|
1846
|
+
safeAssign(
|
|
1847
|
+
out,
|
|
1848
|
+
key,
|
|
1849
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1709
1850
|
);
|
|
1710
1851
|
}
|
|
1711
1852
|
return out;
|
|
1712
1853
|
}
|
|
1713
|
-
|
|
1714
|
-
const AttaformErrorCode = {
|
|
1715
|
-
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
1716
|
-
NoValueSupplied: "atta:no-value-supplied",
|
|
1717
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
1718
|
-
AdapterThrew: "atta:adapter-threw",
|
|
1719
|
-
/**
|
|
1720
|
-
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
1721
|
-
* threw (sync or async). The adapter caught the throw and surfaced
|
|
1722
|
-
* it as a `ValidationError` at the field path so the form's normal
|
|
1723
|
-
* error pipeline handles it instead of leaking as an unhandled
|
|
1724
|
-
* rejection or routing through `submitError`.
|
|
1725
|
-
*/
|
|
1726
|
-
ValidatorThrew: "atta:validator-threw",
|
|
1727
|
-
/**
|
|
1728
|
-
* A function-form `defaultValues` factory threw or its promise
|
|
1729
|
-
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
1730
|
-
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
1731
|
-
* the standard error pipeline carries the signal. Critical for the
|
|
1732
|
-
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
1733
|
-
* payload, but `schemaErrors` does, so the client sees the failure
|
|
1734
|
-
* after rehydration without an extra channel.
|
|
1735
|
-
*/
|
|
1736
|
-
HydrationFailed: "atta:hydration-failed",
|
|
1737
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
1738
|
-
PathNotFound: "atta:path-not-found",
|
|
1739
|
-
/**
|
|
1740
|
-
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
1741
|
-
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
1742
|
-
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
1743
|
-
* aggregate error pipeline can carry the failure alongside ordinary
|
|
1744
|
-
* validation errors. The raw factory error remains on
|
|
1745
|
-
* `form.hydrateError` for retry UX.
|
|
1746
|
-
*/
|
|
1747
|
-
ActivationFailed: "atta:activation-failed"
|
|
1748
|
-
};
|
|
1749
1854
|
|
|
1750
1855
|
const warnedNoScopeStores = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
1751
1856
|
function buildProcessForm(state, formInstanceId, options = {}) {
|
|
@@ -2004,6 +2109,33 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
|
2004
2109
|
target.element.focus({ preventScroll: true });
|
|
2005
2110
|
}
|
|
2006
2111
|
|
|
2112
|
+
function captureUserCallSite() {
|
|
2113
|
+
const raw = new Error().stack;
|
|
2114
|
+
if (typeof raw !== "string") return void 0;
|
|
2115
|
+
const lines = raw.split("\n");
|
|
2116
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2117
|
+
const frame = lines[i];
|
|
2118
|
+
if (frame === void 0) continue;
|
|
2119
|
+
if (/attaform[/-]forms?/i.test(frame)) continue;
|
|
2120
|
+
if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
|
|
2121
|
+
const trimmed = frame.trim();
|
|
2122
|
+
if (trimmed.length === 0) continue;
|
|
2123
|
+
return shortenSourceFrame(trimmed);
|
|
2124
|
+
}
|
|
2125
|
+
return void 0;
|
|
2126
|
+
}
|
|
2127
|
+
function shortenSourceFrame(frame) {
|
|
2128
|
+
const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
|
|
2129
|
+
if (match === null) return frame;
|
|
2130
|
+
const [, urlOrPath, line] = match;
|
|
2131
|
+
if (urlOrPath === void 0 || line === void 0) return frame;
|
|
2132
|
+
let path = urlOrPath;
|
|
2133
|
+
path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
|
|
2134
|
+
path = path.replace(/^_nuxt\//, "");
|
|
2135
|
+
path = path.replace(/^\//, "");
|
|
2136
|
+
return `(${path}:${line})`;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2007
2139
|
function extractSchemaFields(schema) {
|
|
2008
2140
|
try {
|
|
2009
2141
|
const root = schema.getDefaultAtPath([]);
|
|
@@ -2062,9 +2194,9 @@ function isLeafValue(value) {
|
|
|
2062
2194
|
return true;
|
|
2063
2195
|
}
|
|
2064
2196
|
function isSlimPrimitiveValid(schema, store, path, value) {
|
|
2065
|
-
return walk
|
|
2197
|
+
return walk(schema, store, path, value);
|
|
2066
2198
|
}
|
|
2067
|
-
function walk
|
|
2199
|
+
function walk(schema, store, path, value) {
|
|
2068
2200
|
if (schema.isPreprocessOrCoerceLeaf(path)) return true;
|
|
2069
2201
|
const accepted = schema.getSlimPrimitiveTypesAtPath(path);
|
|
2070
2202
|
const kind = isLeafValue(value) ? slimKindOf(value) : Array.isArray(value) ? "array" : "object";
|
|
@@ -2074,13 +2206,13 @@ function walk$1(schema, store, path, value) {
|
|
|
2074
2206
|
}
|
|
2075
2207
|
if (Array.isArray(value)) {
|
|
2076
2208
|
for (let i = 0; i < value.length; i++) {
|
|
2077
|
-
if (!walk
|
|
2209
|
+
if (!walk(schema, store, [...path, i], value[i])) return false;
|
|
2078
2210
|
}
|
|
2079
2211
|
return true;
|
|
2080
2212
|
}
|
|
2081
2213
|
if (isPlainRecord(value)) {
|
|
2082
2214
|
for (const key of Object.keys(value)) {
|
|
2083
|
-
if (!walk
|
|
2215
|
+
if (!walk(schema, store, [...path, key], value[key])) {
|
|
2084
2216
|
return false;
|
|
2085
2217
|
}
|
|
2086
2218
|
}
|
|
@@ -2480,49 +2612,60 @@ function walkUnsetSentinels(values, schema) {
|
|
|
2480
2612
|
walkUnspecified(rootSlim, [], paths);
|
|
2481
2613
|
return { cleanedValues: void 0, paths };
|
|
2482
2614
|
}
|
|
2483
|
-
const cleaned =
|
|
2615
|
+
const cleaned = walkCore(values, [], schema, paths, true);
|
|
2484
2616
|
return { cleanedValues: cleaned, paths };
|
|
2485
2617
|
}
|
|
2486
|
-
function
|
|
2618
|
+
function isOpaqueLeaf(value) {
|
|
2619
|
+
return value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || typeof value === "function";
|
|
2620
|
+
}
|
|
2621
|
+
function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
2487
2622
|
if (isUnset(input)) {
|
|
2488
2623
|
return expandUnsetAt(segments, schema, paths);
|
|
2489
2624
|
}
|
|
2490
2625
|
if (input === void 0) {
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2626
|
+
if (synthesizeSchemaKeys) {
|
|
2627
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2628
|
+
return walkUnspecified(slim, segments, paths);
|
|
2629
|
+
}
|
|
2496
2630
|
return input;
|
|
2497
2631
|
}
|
|
2632
|
+
if (input === null) return null;
|
|
2633
|
+
if (isOpaqueLeaf(input)) return input;
|
|
2498
2634
|
if (Array.isArray(input)) {
|
|
2499
2635
|
const out = new Array(input.length);
|
|
2500
2636
|
let mutated = false;
|
|
2501
2637
|
for (let i = 0; i < input.length; i++) {
|
|
2502
|
-
const walked =
|
|
2638
|
+
const walked = walkCore(input[i], [...segments, i], schema, paths, synthesizeSchemaKeys);
|
|
2503
2639
|
out[i] = walked;
|
|
2504
2640
|
if (walked !== input[i]) mutated = true;
|
|
2505
2641
|
}
|
|
2506
2642
|
return mutated ? out : input;
|
|
2507
2643
|
}
|
|
2508
2644
|
if (typeof input === "object") {
|
|
2509
|
-
const
|
|
2510
|
-
const inputKeys = Object.keys(
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2645
|
+
const obj = input;
|
|
2646
|
+
const inputKeys = Object.keys(obj);
|
|
2647
|
+
let keys = inputKeys;
|
|
2648
|
+
let mutated = false;
|
|
2649
|
+
let inputKeysSet = null;
|
|
2650
|
+
if (synthesizeSchemaKeys) {
|
|
2651
|
+
inputKeysSet = new Set(inputKeys);
|
|
2652
|
+
const allKeys = new Set(inputKeys);
|
|
2653
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2654
|
+
if (slim !== null && slim !== void 0 && typeof slim === "object" && !Array.isArray(slim) && !isOpaqueLeaf(slim)) {
|
|
2655
|
+
for (const k of Object.keys(slim)) allKeys.add(k);
|
|
2656
|
+
}
|
|
2657
|
+
keys = allKeys;
|
|
2658
|
+
mutated = allKeys.size !== inputKeys.length;
|
|
2515
2659
|
}
|
|
2516
2660
|
const out = {};
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
if (orig === void 0 && inputKeysSet.has(key)) {
|
|
2661
|
+
for (const key of keys) {
|
|
2662
|
+
const orig = obj[key];
|
|
2663
|
+
if (synthesizeSchemaKeys && orig === void 0 && inputKeysSet?.has(key) === true) {
|
|
2521
2664
|
safeAssign(out, key, void 0);
|
|
2522
2665
|
mutated = true;
|
|
2523
2666
|
continue;
|
|
2524
2667
|
}
|
|
2525
|
-
const walked =
|
|
2668
|
+
const walked = walkCore(orig, [...segments, key], schema, paths, synthesizeSchemaKeys);
|
|
2526
2669
|
safeAssign(out, key, walked);
|
|
2527
2670
|
if (walked !== orig) mutated = true;
|
|
2528
2671
|
}
|
|
@@ -2537,7 +2680,7 @@ function walkUnspecified(slim, segments, paths) {
|
|
|
2537
2680
|
}
|
|
2538
2681
|
return slim;
|
|
2539
2682
|
}
|
|
2540
|
-
if (slim
|
|
2683
|
+
if (isOpaqueLeaf(slim)) {
|
|
2541
2684
|
return slim;
|
|
2542
2685
|
}
|
|
2543
2686
|
if (Array.isArray(slim)) return slim;
|
|
@@ -2556,40 +2699,9 @@ function walkUnspecified(slim, segments, paths) {
|
|
|
2556
2699
|
}
|
|
2557
2700
|
function substituteUnsetSentinels(value, prefix, schema) {
|
|
2558
2701
|
const paths = [];
|
|
2559
|
-
const cleaned =
|
|
2702
|
+
const cleaned = walkCore(value, [...prefix], schema, paths, false);
|
|
2560
2703
|
return { cleanedValues: cleaned, paths };
|
|
2561
2704
|
}
|
|
2562
|
-
function substitute(input, segments, schema, paths) {
|
|
2563
|
-
if (isUnset(input)) {
|
|
2564
|
-
return expandUnsetAt(segments, schema, paths);
|
|
2565
|
-
}
|
|
2566
|
-
if (input === void 0 || input === null) return input;
|
|
2567
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2568
|
-
return input;
|
|
2569
|
-
}
|
|
2570
|
-
if (Array.isArray(input)) {
|
|
2571
|
-
let mutated = false;
|
|
2572
|
-
const out = new Array(input.length);
|
|
2573
|
-
for (let i = 0; i < input.length; i++) {
|
|
2574
|
-
const walked = substitute(input[i], [...segments, i], schema, paths);
|
|
2575
|
-
out[i] = walked;
|
|
2576
|
-
if (walked !== input[i]) mutated = true;
|
|
2577
|
-
}
|
|
2578
|
-
return mutated ? out : input;
|
|
2579
|
-
}
|
|
2580
|
-
if (typeof input === "object") {
|
|
2581
|
-
let mutated = false;
|
|
2582
|
-
const out = {};
|
|
2583
|
-
for (const key of Object.keys(input)) {
|
|
2584
|
-
const orig = input[key];
|
|
2585
|
-
const walked = substitute(orig, [...segments, key], schema, paths);
|
|
2586
|
-
safeAssign(out, key, walked);
|
|
2587
|
-
if (walked !== orig) mutated = true;
|
|
2588
|
-
}
|
|
2589
|
-
return mutated ? out : input;
|
|
2590
|
-
}
|
|
2591
|
-
return input;
|
|
2592
|
-
}
|
|
2593
2705
|
function isPrimitiveOrEmpty(value) {
|
|
2594
2706
|
if (value === null || value === void 0) return true;
|
|
2595
2707
|
const t = typeof value;
|
|
@@ -2619,7 +2731,7 @@ function expandUnsetAt(segments, schema, paths) {
|
|
|
2619
2731
|
paths.push(canonicalizePath(segments).key);
|
|
2620
2732
|
return slim;
|
|
2621
2733
|
}
|
|
2622
|
-
if (slim
|
|
2734
|
+
if (isOpaqueLeaf(slim)) {
|
|
2623
2735
|
paths.push(canonicalizePath(segments).key);
|
|
2624
2736
|
return slim;
|
|
2625
2737
|
}
|
|
@@ -2753,20 +2865,128 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2753
2865
|
if (instanceMeta === void 0) return meta;
|
|
2754
2866
|
return meta === void 0 ? { instance: instanceMeta } : { ...meta, instance: instanceMeta };
|
|
2755
2867
|
};
|
|
2868
|
+
const reMarkBlanksAfterSubstitution = (paths) => {
|
|
2869
|
+
for (const pathKey of paths) {
|
|
2870
|
+
const blankSegments = segmentsForPathKey(pathKey);
|
|
2871
|
+
if (blankSegments === null) continue;
|
|
2872
|
+
state.setValueAtPath(
|
|
2873
|
+
blankSegments,
|
|
2874
|
+
state.getValueAtPath(blankSegments),
|
|
2875
|
+
withInstanceMeta({ blank: true })
|
|
2876
|
+
);
|
|
2877
|
+
}
|
|
2878
|
+
};
|
|
2756
2879
|
const getFormMetaBase = () => {
|
|
2757
|
-
|
|
2880
|
+
let rollup;
|
|
2881
|
+
const rootBase = () => rollup ?? (rollup = buildContainerFieldStateBase(
|
|
2758
2882
|
state,
|
|
2759
2883
|
ROOT_PATH,
|
|
2760
2884
|
ROOT_PATH_KEY,
|
|
2761
2885
|
formInstanceId
|
|
2762
|
-
);
|
|
2886
|
+
).base);
|
|
2763
2887
|
return {
|
|
2764
|
-
|
|
2888
|
+
// Rollup-derived (FieldStateBase) — the whole rollup builds once, on the
|
|
2889
|
+
// first access of any of these.
|
|
2890
|
+
get value() {
|
|
2891
|
+
return rootBase().value;
|
|
2892
|
+
},
|
|
2893
|
+
get original() {
|
|
2894
|
+
return rootBase().original;
|
|
2895
|
+
},
|
|
2896
|
+
get pristine() {
|
|
2897
|
+
return rootBase().pristine;
|
|
2898
|
+
},
|
|
2899
|
+
get dirty() {
|
|
2900
|
+
return rootBase().dirty;
|
|
2901
|
+
},
|
|
2902
|
+
get focused() {
|
|
2903
|
+
return rootBase().focused;
|
|
2904
|
+
},
|
|
2905
|
+
get blurred() {
|
|
2906
|
+
return rootBase().blurred;
|
|
2907
|
+
},
|
|
2908
|
+
get touched() {
|
|
2909
|
+
return rootBase().touched;
|
|
2910
|
+
},
|
|
2911
|
+
get interacted() {
|
|
2912
|
+
return rootBase().interacted;
|
|
2913
|
+
},
|
|
2914
|
+
get blurredAfterInteraction() {
|
|
2915
|
+
return rootBase().blurredAfterInteraction;
|
|
2916
|
+
},
|
|
2917
|
+
get connected() {
|
|
2918
|
+
return rootBase().connected;
|
|
2919
|
+
},
|
|
2920
|
+
get element() {
|
|
2921
|
+
return rootBase().element;
|
|
2922
|
+
},
|
|
2923
|
+
get elements() {
|
|
2924
|
+
return rootBase().elements;
|
|
2925
|
+
},
|
|
2926
|
+
get updatedAt() {
|
|
2927
|
+
return rootBase().updatedAt;
|
|
2928
|
+
},
|
|
2929
|
+
get errors() {
|
|
2930
|
+
return rootBase().errors;
|
|
2931
|
+
},
|
|
2932
|
+
get validating() {
|
|
2933
|
+
return rootBase().validating;
|
|
2934
|
+
},
|
|
2935
|
+
get valid() {
|
|
2936
|
+
return rootBase().valid;
|
|
2937
|
+
},
|
|
2938
|
+
get transforming() {
|
|
2939
|
+
return rootBase().transforming;
|
|
2940
|
+
},
|
|
2941
|
+
get busy() {
|
|
2942
|
+
return rootBase().busy;
|
|
2943
|
+
},
|
|
2944
|
+
get transformError() {
|
|
2945
|
+
return rootBase().transformError;
|
|
2946
|
+
},
|
|
2947
|
+
get path() {
|
|
2948
|
+
return rootBase().path;
|
|
2949
|
+
},
|
|
2950
|
+
get id() {
|
|
2951
|
+
return rootBase().id;
|
|
2952
|
+
},
|
|
2953
|
+
get aria() {
|
|
2954
|
+
return rootBase().aria;
|
|
2955
|
+
},
|
|
2956
|
+
get key() {
|
|
2957
|
+
return rootBase().key;
|
|
2958
|
+
},
|
|
2959
|
+
get blank() {
|
|
2960
|
+
return rootBase().blank;
|
|
2961
|
+
},
|
|
2962
|
+
get label() {
|
|
2963
|
+
return rootBase().label;
|
|
2964
|
+
},
|
|
2965
|
+
get description() {
|
|
2966
|
+
return rootBase().description;
|
|
2967
|
+
},
|
|
2968
|
+
get placeholder() {
|
|
2969
|
+
return rootBase().placeholder;
|
|
2970
|
+
},
|
|
2971
|
+
get meta() {
|
|
2972
|
+
return rootBase().meta;
|
|
2973
|
+
},
|
|
2974
|
+
get errorCount() {
|
|
2975
|
+
return rootBase().errors.length;
|
|
2976
|
+
},
|
|
2977
|
+
// Form-level scalars — EAGER reads, tracked on every field-state eval.
|
|
2978
|
+
// They are O(1) refs that never change on a keystroke, so tracking them
|
|
2979
|
+
// per field costs nothing on the hot path. Kept eager (NOT lazy like the
|
|
2980
|
+
// rollup) because behaviors beyond the predicate's own output depend on
|
|
2981
|
+
// every field re-evaluating when they flip — most notably, the display
|
|
2982
|
+
// engine is cleared on submit (revealing held spinners), and that
|
|
2983
|
+
// imperative reset only becomes visible if `submitting` is a tracked dep
|
|
2984
|
+
// of each field. Matches the pre-bust dependency set for these scalars
|
|
2985
|
+
// exactly.
|
|
2765
2986
|
submitting: state.submitting.value,
|
|
2766
2987
|
submissionAttempts: state.submissionAttempts.value,
|
|
2767
2988
|
departAttempts: state.departAttempts.value,
|
|
2768
2989
|
submitError: state.submitError.value,
|
|
2769
|
-
errorCount: rootBase.errors.length,
|
|
2770
2990
|
submitted: state.submitted.value,
|
|
2771
2991
|
instanceId: formInstanceId
|
|
2772
2992
|
};
|
|
@@ -2801,24 +3021,21 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2801
3021
|
const segments = canonicalizePath(pathInput).segments;
|
|
2802
3022
|
return computed(() => getAtPath(state.form.value, segments));
|
|
2803
3023
|
}
|
|
2804
|
-
function setValueImpl(pathOrValue, maybeValue) {
|
|
2805
|
-
|
|
3024
|
+
function setValueImpl(pathOrValue, maybeValue, maybeOptions) {
|
|
3025
|
+
const argc = arguments.length;
|
|
3026
|
+
const isPathForm = argc >= 2 && (typeof pathOrValue === "string" || Array.isArray(pathOrValue));
|
|
3027
|
+
const options2 = isPathForm ? maybeOptions : argc >= 2 ? maybeValue : void 0;
|
|
3028
|
+
const silent = options2?.silent === true;
|
|
3029
|
+
const writeMeta = (extra) => withInstanceMeta(silent ? { ...extra, silent: true } : extra);
|
|
3030
|
+
if (!isPathForm) {
|
|
2806
3031
|
const next = typeof pathOrValue === "function" ? pathOrValue(structuralSnapshot(state.form.value)) : pathOrValue;
|
|
2807
3032
|
const walked2 = walkUnsetSentinels(
|
|
2808
3033
|
next,
|
|
2809
3034
|
state.schema
|
|
2810
3035
|
);
|
|
2811
|
-
const ok2 = state.setValueAtPath([], walked2.cleanedValues,
|
|
3036
|
+
const ok2 = state.setValueAtPath([], walked2.cleanedValues, writeMeta());
|
|
2812
3037
|
if (!ok2) return false;
|
|
2813
|
-
|
|
2814
|
-
const blankSegments = segmentsForPathKey(pathKey);
|
|
2815
|
-
if (blankSegments === null) continue;
|
|
2816
|
-
state.setValueAtPath(
|
|
2817
|
-
blankSegments,
|
|
2818
|
-
state.getValueAtPath(blankSegments),
|
|
2819
|
-
withInstanceMeta({ blank: true })
|
|
2820
|
-
);
|
|
2821
|
-
}
|
|
3038
|
+
reMarkBlanksAfterSubstitution(walked2.paths);
|
|
2822
3039
|
return true;
|
|
2823
3040
|
}
|
|
2824
3041
|
const segments = canonicalizePath(pathOrValue).segments;
|
|
@@ -2830,7 +3047,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2830
3047
|
if (parentDU?.discriminatorKey === last) {
|
|
2831
3048
|
const slimDefault = state.schema.getEmptyValueAtPath(segments);
|
|
2832
3049
|
const blank = blankForKind(slimDefault);
|
|
2833
|
-
return state.setValueAtPath(segments, blank,
|
|
3050
|
+
return state.setValueAtPath(segments, blank, writeMeta({ blank: true }));
|
|
2834
3051
|
}
|
|
2835
3052
|
}
|
|
2836
3053
|
const blankPaths = [];
|
|
@@ -2841,9 +3058,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2841
3058
|
);
|
|
2842
3059
|
const segmentsKey = canonicalizePath(segments).key;
|
|
2843
3060
|
if (blankPaths.length === 1 && blankPaths[0] === segmentsKey) {
|
|
2844
|
-
return state.setValueAtPath(segments, expanded,
|
|
3061
|
+
return state.setValueAtPath(segments, expanded, writeMeta({ blank: true }));
|
|
2845
3062
|
}
|
|
2846
|
-
const ok2 = state.setValueAtPath(segments, expanded,
|
|
3063
|
+
const ok2 = state.setValueAtPath(segments, expanded, writeMeta());
|
|
2847
3064
|
if (!ok2) return false;
|
|
2848
3065
|
for (const pathKey of blankPaths) {
|
|
2849
3066
|
const blankSegments = segmentsForPathKey(pathKey);
|
|
@@ -2851,7 +3068,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2851
3068
|
state.setValueAtPath(
|
|
2852
3069
|
blankSegments,
|
|
2853
3070
|
state.getValueAtPath(blankSegments),
|
|
2854
|
-
|
|
3071
|
+
writeMeta({ blank: true })
|
|
2855
3072
|
);
|
|
2856
3073
|
}
|
|
2857
3074
|
return true;
|
|
@@ -2871,17 +3088,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2871
3088
|
segments,
|
|
2872
3089
|
state.schema
|
|
2873
3090
|
);
|
|
2874
|
-
const ok = state.setValueAtPath(segments, walked.cleanedValues,
|
|
3091
|
+
const ok = state.setValueAtPath(segments, walked.cleanedValues, writeMeta());
|
|
2875
3092
|
if (!ok) return false;
|
|
2876
|
-
|
|
2877
|
-
const blankSegments = segmentsForPathKey(pathKey);
|
|
2878
|
-
if (blankSegments === null) continue;
|
|
2879
|
-
state.setValueAtPath(
|
|
2880
|
-
blankSegments,
|
|
2881
|
-
state.getValueAtPath(blankSegments),
|
|
2882
|
-
withInstanceMeta({ blank: true })
|
|
2883
|
-
);
|
|
2884
|
-
}
|
|
3093
|
+
reMarkBlanksAfterSubstitution(walked.paths);
|
|
2885
3094
|
return true;
|
|
2886
3095
|
}
|
|
2887
3096
|
const errorsProxy = buildErrorsProxy(state);
|
|
@@ -3250,7 +3459,19 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3250
3459
|
}
|
|
3251
3460
|
return Object.freeze(out);
|
|
3252
3461
|
}
|
|
3253
|
-
|
|
3462
|
+
const formHandle = {
|
|
3463
|
+
current: void 0
|
|
3464
|
+
};
|
|
3465
|
+
function onChangeImpl(a, b, c) {
|
|
3466
|
+
const sourced = typeof b === "function";
|
|
3467
|
+
const source = sourced ? a : void 0;
|
|
3468
|
+
const handler = sourced ? b : a;
|
|
3469
|
+
const options2 = sourced ? c : b;
|
|
3470
|
+
const stop = state.registerOnChange(source, handler, options2, () => formHandle.current);
|
|
3471
|
+
if (getCurrentScope() !== void 0) onScopeDispose(stop);
|
|
3472
|
+
return stop;
|
|
3473
|
+
}
|
|
3474
|
+
const api = {
|
|
3254
3475
|
handleSubmit: gated(handleSubmit),
|
|
3255
3476
|
// Callable readonly Proxies (`values`, `fields`, `errors`) and the
|
|
3256
3477
|
// reactive containers (`meta`, `history`, `blankPaths`) are exposed
|
|
@@ -3337,8 +3558,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3337
3558
|
get blankPaths() {
|
|
3338
3559
|
void state.activate();
|
|
3339
3560
|
return blankPathsView;
|
|
3340
|
-
}
|
|
3561
|
+
},
|
|
3562
|
+
onChange: onChangeImpl
|
|
3341
3563
|
};
|
|
3564
|
+
formHandle.current = api;
|
|
3565
|
+
return api;
|
|
3342
3566
|
}
|
|
3343
3567
|
|
|
3344
3568
|
const IDLE = Object.freeze({ display: "idle" });
|
|
@@ -3765,6 +3989,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3765
3989
|
originals,
|
|
3766
3990
|
blankPaths,
|
|
3767
3991
|
originalBlankPaths,
|
|
3992
|
+
authoredPaths,
|
|
3768
3993
|
fieldValidationCounts,
|
|
3769
3994
|
fieldValidatingSince,
|
|
3770
3995
|
fieldValidationState,
|
|
@@ -3792,6 +4017,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3792
4017
|
}));
|
|
3793
4018
|
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
3794
4019
|
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
4020
|
+
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
3795
4021
|
migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
|
|
3796
4022
|
migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
|
|
3797
4023
|
arrayIdentity.applyRemap(arrayPath, remap);
|
|
@@ -3835,7 +4061,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3835
4061
|
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
3836
4062
|
decFieldValidation(key);
|
|
3837
4063
|
}
|
|
3838
|
-
entry.
|
|
4064
|
+
entry.aborted = true;
|
|
3839
4065
|
fieldValidationState.delete(key);
|
|
3840
4066
|
}
|
|
3841
4067
|
}
|
|
@@ -3847,6 +4073,170 @@ function createArrayBookkeeping(deps) {
|
|
|
3847
4073
|
};
|
|
3848
4074
|
}
|
|
3849
4075
|
|
|
4076
|
+
const NOOP_STOP = () => {
|
|
4077
|
+
};
|
|
4078
|
+
function isThenable(value) {
|
|
4079
|
+
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
4080
|
+
}
|
|
4081
|
+
function isSuppressed(meta) {
|
|
4082
|
+
return meta?.hydration === true || meta?.crossTab === true || meta?.silent === true;
|
|
4083
|
+
}
|
|
4084
|
+
function canonicalizeSourceList(raw) {
|
|
4085
|
+
const list = typeof raw === "string" ? [raw] : raw;
|
|
4086
|
+
const out = [];
|
|
4087
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4088
|
+
for (const entry of list) {
|
|
4089
|
+
const { segments, key } = canonicalizePath(entry);
|
|
4090
|
+
if (seen.has(key)) continue;
|
|
4091
|
+
seen.add(key);
|
|
4092
|
+
out.push({ segments, key, dotted: segmentsToDotted(segments) });
|
|
4093
|
+
}
|
|
4094
|
+
return out;
|
|
4095
|
+
}
|
|
4096
|
+
function makeResolver(source) {
|
|
4097
|
+
if (source === void 0) {
|
|
4098
|
+
const root = [{ segments: ROOT_PATH, key: ROOT_PATH_KEY, dotted: "" }];
|
|
4099
|
+
return () => root;
|
|
4100
|
+
}
|
|
4101
|
+
if (typeof source !== "function" && !isRef(source)) {
|
|
4102
|
+
const fixed = canonicalizeSourceList(source);
|
|
4103
|
+
return () => fixed;
|
|
4104
|
+
}
|
|
4105
|
+
return () => canonicalizeSourceList(toValue(source));
|
|
4106
|
+
}
|
|
4107
|
+
function createOnChangeRegistry(deps) {
|
|
4108
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
4109
|
+
function isCurrent(reg, key, token) {
|
|
4110
|
+
return reg.runs.get(key)?.token === token;
|
|
4111
|
+
}
|
|
4112
|
+
function routeError(reg, error, source, changed, value, previous, attempt, token) {
|
|
4113
|
+
if (reg.onError === void 0) {
|
|
4114
|
+
if (__DEV__) {
|
|
4115
|
+
console.error(
|
|
4116
|
+
`[attaform] onChange handler threw for path '${source.dotted}' \u2014 error swallowed. Pass { onError } to handle it. Original error:`,
|
|
4117
|
+
error
|
|
4118
|
+
);
|
|
4119
|
+
}
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
const retry = () => {
|
|
4123
|
+
if (!isCurrent(reg, source.key, token)) return;
|
|
4124
|
+
runHandler(reg, source, changed, value, previous, attempt + 1);
|
|
4125
|
+
};
|
|
4126
|
+
const errCtx = {
|
|
4127
|
+
path: source.dotted,
|
|
4128
|
+
value,
|
|
4129
|
+
attempt,
|
|
4130
|
+
retry,
|
|
4131
|
+
form: reg.getForm()
|
|
4132
|
+
};
|
|
4133
|
+
try {
|
|
4134
|
+
reg.onError(error, errCtx);
|
|
4135
|
+
} catch (err) {
|
|
4136
|
+
if (__DEV__) console.error("[attaform] onChange onError threw:", err);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
function runHandler(reg, source, changed, value, previous, attempt) {
|
|
4140
|
+
const prior = reg.runs.get(source.key);
|
|
4141
|
+
if (prior) prior.controller.abort();
|
|
4142
|
+
const controller = new AbortController();
|
|
4143
|
+
const token = ++reg.seq;
|
|
4144
|
+
reg.runs.set(source.key, { token, controller });
|
|
4145
|
+
const ctx = {
|
|
4146
|
+
path: source.dotted,
|
|
4147
|
+
previous,
|
|
4148
|
+
signal: controller.signal,
|
|
4149
|
+
attempt,
|
|
4150
|
+
form: reg.getForm(),
|
|
4151
|
+
changed
|
|
4152
|
+
};
|
|
4153
|
+
let result;
|
|
4154
|
+
try {
|
|
4155
|
+
result = reg.handler(value, ctx);
|
|
4156
|
+
} catch (error) {
|
|
4157
|
+
routeError(reg, error, source, changed, value, previous, attempt, token);
|
|
4158
|
+
return;
|
|
4159
|
+
}
|
|
4160
|
+
if (isThenable(result)) {
|
|
4161
|
+
result.then(void 0, (error) => {
|
|
4162
|
+
if (isCurrent(reg, source.key, token)) {
|
|
4163
|
+
routeError(reg, error, source, changed, value, previous, attempt, token);
|
|
4164
|
+
}
|
|
4165
|
+
});
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
function dispatch(patches, meta) {
|
|
4169
|
+
if (handlers.size === 0 || isSuppressed(meta)) return;
|
|
4170
|
+
for (const reg of handlers) {
|
|
4171
|
+
let sources;
|
|
4172
|
+
try {
|
|
4173
|
+
sources = reg.resolve();
|
|
4174
|
+
} catch (error) {
|
|
4175
|
+
if (__DEV__) console.error("[attaform] onChange source getter threw:", error);
|
|
4176
|
+
continue;
|
|
4177
|
+
}
|
|
4178
|
+
for (const source of sources) {
|
|
4179
|
+
let changed;
|
|
4180
|
+
for (const patch of patches) {
|
|
4181
|
+
if (isPathPrefix(source.segments, patch.path) || isPathPrefix(patch.path, source.segments)) {
|
|
4182
|
+
(changed ?? (changed = [])).push(segmentsToDotted(patch.path));
|
|
4183
|
+
}
|
|
4184
|
+
}
|
|
4185
|
+
if (changed === void 0) continue;
|
|
4186
|
+
const value = deps.getValueAtPath(source.segments);
|
|
4187
|
+
const previous = reg.previous.has(source.key) ? reg.previous.get(source.key) : value;
|
|
4188
|
+
reg.previous.set(source.key, value);
|
|
4189
|
+
runHandler(reg, source, changed, value, previous, 0);
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
function register(source, handler, options, getForm) {
|
|
4194
|
+
if (deps.ssr) return NOOP_STOP;
|
|
4195
|
+
const reg = {
|
|
4196
|
+
handler,
|
|
4197
|
+
onError: options?.onError,
|
|
4198
|
+
getForm,
|
|
4199
|
+
resolve: makeResolver(source),
|
|
4200
|
+
previous: /* @__PURE__ */ new Map(),
|
|
4201
|
+
runs: /* @__PURE__ */ new Map(),
|
|
4202
|
+
seq: 0
|
|
4203
|
+
};
|
|
4204
|
+
try {
|
|
4205
|
+
for (const { key, segments } of reg.resolve()) {
|
|
4206
|
+
reg.previous.set(key, deps.getValueAtPath(segments));
|
|
4207
|
+
}
|
|
4208
|
+
} catch (error) {
|
|
4209
|
+
if (__DEV__) console.error("[attaform] onChange source getter threw at registration:", error);
|
|
4210
|
+
}
|
|
4211
|
+
handlers.add(reg);
|
|
4212
|
+
let stopped = false;
|
|
4213
|
+
return () => {
|
|
4214
|
+
if (stopped) return;
|
|
4215
|
+
stopped = true;
|
|
4216
|
+
handlers.delete(reg);
|
|
4217
|
+
for (const run of reg.runs.values()) run.controller.abort();
|
|
4218
|
+
reg.runs.clear();
|
|
4219
|
+
reg.previous.clear();
|
|
4220
|
+
};
|
|
4221
|
+
}
|
|
4222
|
+
function dispose() {
|
|
4223
|
+
for (const reg of handlers) {
|
|
4224
|
+
for (const run of reg.runs.values()) run.controller.abort();
|
|
4225
|
+
reg.runs.clear();
|
|
4226
|
+
reg.previous.clear();
|
|
4227
|
+
}
|
|
4228
|
+
handlers.clear();
|
|
4229
|
+
}
|
|
4230
|
+
return {
|
|
4231
|
+
get active() {
|
|
4232
|
+
return handlers.size > 0;
|
|
4233
|
+
},
|
|
4234
|
+
register,
|
|
4235
|
+
dispatch,
|
|
4236
|
+
dispose
|
|
4237
|
+
};
|
|
4238
|
+
}
|
|
4239
|
+
|
|
3850
4240
|
function isHydratedFieldRecord(value) {
|
|
3851
4241
|
if (typeof value !== "object" || value === null) return false;
|
|
3852
4242
|
const r = value;
|
|
@@ -3931,6 +4321,17 @@ function walkAuthoredFromConstraints(value, prefix, out) {
|
|
|
3931
4321
|
}
|
|
3932
4322
|
}
|
|
3933
4323
|
}
|
|
4324
|
+
function freshElementIndices(op) {
|
|
4325
|
+
switch (op.kind) {
|
|
4326
|
+
case "insert":
|
|
4327
|
+
case "replace-at":
|
|
4328
|
+
return [op.index];
|
|
4329
|
+
case "remove":
|
|
4330
|
+
case "swap":
|
|
4331
|
+
case "move":
|
|
4332
|
+
return [];
|
|
4333
|
+
}
|
|
4334
|
+
}
|
|
3934
4335
|
function walkAuthoredFromSchemaDiff(withDefaults, withoutDefaults, prefix, out) {
|
|
3935
4336
|
if (isPlainRecord(withDefaults) && isPlainRecord(withoutDefaults)) {
|
|
3936
4337
|
const left = withDefaults;
|
|
@@ -3969,6 +4370,7 @@ function createFormStore(options) {
|
|
|
3969
4370
|
const formChangeListeners = /* @__PURE__ */ new Set();
|
|
3970
4371
|
const submitSuccessListeners = /* @__PURE__ */ new Set();
|
|
3971
4372
|
const resetListeners = /* @__PURE__ */ new Set();
|
|
4373
|
+
const onChangeRegistry = createOnChangeRegistry({ getValueAtPath, ssr });
|
|
3972
4374
|
const persistOptIns = createPersistOptInRegistry();
|
|
3973
4375
|
const noSyncPaths = /* @__PURE__ */ new Set();
|
|
3974
4376
|
const noSyncPathCounts = /* @__PURE__ */ new Map();
|
|
@@ -4007,11 +4409,8 @@ function createFormStore(options) {
|
|
|
4007
4409
|
if (constraints !== void 0) {
|
|
4008
4410
|
walkAuthoredFromConstraints(constraints, [], authoredPaths);
|
|
4009
4411
|
}
|
|
4010
|
-
const
|
|
4011
|
-
|
|
4012
|
-
strict
|
|
4013
|
-
});
|
|
4014
|
-
walkAuthoredFromSchemaDiff(schemaWithDefaultsData, slimResponse.data, [], authoredPaths);
|
|
4412
|
+
const slimBaseline = schema.getEmptyValueAtPath([]);
|
|
4413
|
+
walkAuthoredFromSchemaDiff(schemaWithDefaultsData, slimBaseline, [], authoredPaths);
|
|
4015
4414
|
}
|
|
4016
4415
|
rebuildAuthoredPaths(defaultValues, schemaInitialData);
|
|
4017
4416
|
function filterAuthoredErrors(errors) {
|
|
@@ -4030,7 +4429,7 @@ function createFormStore(options) {
|
|
|
4030
4429
|
});
|
|
4031
4430
|
const form = ref(stubbedInitialData);
|
|
4032
4431
|
const arrayIdentity = createArrayIdentity((arraySegs) => {
|
|
4033
|
-
const v = getAtPath(form.value, arraySegs);
|
|
4432
|
+
const v = getAtPath(toRaw(form.value), arraySegs);
|
|
4034
4433
|
return Array.isArray(v) ? v.length : 0;
|
|
4035
4434
|
});
|
|
4036
4435
|
function arrayElementKey(path) {
|
|
@@ -4073,14 +4472,7 @@ function createFormStore(options) {
|
|
|
4073
4472
|
const segments = segmentsForPathKey(pathKey);
|
|
4074
4473
|
if (segments === null) continue;
|
|
4075
4474
|
if (!schema.isRequiredAtPath(segments)) continue;
|
|
4076
|
-
result.set(pathKey, [
|
|
4077
|
-
{
|
|
4078
|
-
message: "No value supplied",
|
|
4079
|
-
path: [...segments],
|
|
4080
|
-
formKey,
|
|
4081
|
-
code: AttaformErrorCode.NoValueSupplied
|
|
4082
|
-
}
|
|
4083
|
-
]);
|
|
4475
|
+
result.set(pathKey, [makeBlankRequiredError(segments, formKey)]);
|
|
4084
4476
|
}
|
|
4085
4477
|
return result;
|
|
4086
4478
|
});
|
|
@@ -4320,6 +4712,7 @@ function createFormStore(options) {
|
|
|
4320
4712
|
originals,
|
|
4321
4713
|
blankPaths,
|
|
4322
4714
|
originalBlankPaths,
|
|
4715
|
+
authoredPaths,
|
|
4323
4716
|
fieldValidationCounts,
|
|
4324
4717
|
fieldValidatingSince,
|
|
4325
4718
|
fieldValidationState,
|
|
@@ -4329,17 +4722,8 @@ function createFormStore(options) {
|
|
|
4329
4722
|
touchFieldRecord,
|
|
4330
4723
|
decFieldValidation
|
|
4331
4724
|
});
|
|
4332
|
-
function
|
|
4333
|
-
const prev = form.value;
|
|
4334
|
-
if (Object.is(prev, next)) return;
|
|
4725
|
+
function commitWritePatches(patches, meta) {
|
|
4335
4726
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4336
|
-
const patches = [];
|
|
4337
|
-
diffAndApply(prev, next, [], (patch) => {
|
|
4338
|
-
patches.push(patch);
|
|
4339
|
-
});
|
|
4340
|
-
if (!applyChangedKeys(prev, next)) {
|
|
4341
|
-
form.value = next;
|
|
4342
|
-
}
|
|
4343
4727
|
for (const patch of patches) {
|
|
4344
4728
|
const { key } = canonicalizePath(patch.path);
|
|
4345
4729
|
if (patch.kind === "added" && !originals.has(key)) {
|
|
@@ -4354,10 +4738,63 @@ function createFormStore(options) {
|
|
|
4354
4738
|
console.error("[attaform] onFormChange threw:", err);
|
|
4355
4739
|
}
|
|
4356
4740
|
}
|
|
4741
|
+
if (onChangeRegistry.active) onChangeRegistry.dispatch(patches, meta);
|
|
4742
|
+
}
|
|
4743
|
+
function applyFormReplacementWithPath(next, meta, arrayOpPath) {
|
|
4744
|
+
const prev = form.value;
|
|
4745
|
+
if (Object.is(prev, next)) return;
|
|
4746
|
+
const patches = [];
|
|
4747
|
+
diffAndApply(prev, next, [], (patch) => {
|
|
4748
|
+
patches.push(patch);
|
|
4749
|
+
});
|
|
4750
|
+
if (!applyChangedKeys(prev, next, arrayOpPath, [])) {
|
|
4751
|
+
form.value = next;
|
|
4752
|
+
} else if (patches.some(
|
|
4753
|
+
(p) => p.path.length > 0 && typeof p.path[0] === "string" && isShadowedKey(p.path[0])
|
|
4754
|
+
)) {
|
|
4755
|
+
triggerRef(form);
|
|
4756
|
+
}
|
|
4757
|
+
commitWritePatches(patches, meta);
|
|
4758
|
+
}
|
|
4759
|
+
function applyFormReplacement(next, meta) {
|
|
4760
|
+
applyFormReplacementWithPath(next, meta, null);
|
|
4761
|
+
}
|
|
4762
|
+
function applyTargetedWrite(path, completedValue, meta) {
|
|
4763
|
+
const result = tryInPlaceLeafWrite(form.value, path, completedValue);
|
|
4764
|
+
if (!result.applied) {
|
|
4765
|
+
applyFormReplacementWithPath(
|
|
4766
|
+
setAtPathWithSchemaFill(form.value, schema, path, completedValue),
|
|
4767
|
+
meta,
|
|
4768
|
+
meta?.arrayOp !== void 0 ? path : null
|
|
4769
|
+
);
|
|
4770
|
+
return;
|
|
4771
|
+
}
|
|
4772
|
+
const patches = [];
|
|
4773
|
+
diffAndApply(result.old, completedValue, path, (patch) => {
|
|
4774
|
+
patches.push(patch);
|
|
4775
|
+
});
|
|
4776
|
+
commitWritePatches(patches, meta);
|
|
4357
4777
|
}
|
|
4358
4778
|
function setValueAtPath(path, value, meta) {
|
|
4359
|
-
|
|
4360
|
-
|
|
4779
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4780
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4781
|
+
value[idx] = stripSymbolsDeep(value[idx]);
|
|
4782
|
+
}
|
|
4783
|
+
} else {
|
|
4784
|
+
value = stripSymbolsDeep(value);
|
|
4785
|
+
}
|
|
4786
|
+
let slimOk = true;
|
|
4787
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4788
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4789
|
+
if (!isSlimPrimitiveValid(schema, form, [...path, idx], value[idx])) {
|
|
4790
|
+
slimOk = false;
|
|
4791
|
+
break;
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
} else {
|
|
4795
|
+
slimOk = isSlimPrimitiveValid(schema, form, path, value);
|
|
4796
|
+
}
|
|
4797
|
+
if (!slimOk) {
|
|
4361
4798
|
return false;
|
|
4362
4799
|
}
|
|
4363
4800
|
if (path.length >= 2) {
|
|
@@ -4450,22 +4887,37 @@ function createFormStore(options) {
|
|
|
4450
4887
|
}
|
|
4451
4888
|
}
|
|
4452
4889
|
}
|
|
4890
|
+
const currentValue = getAtPath(form.value, path);
|
|
4453
4891
|
const pathKey = canonicalizePath(path).key;
|
|
4454
4892
|
if (meta?.blank === true) {
|
|
4455
4893
|
blankPaths.add(pathKey);
|
|
4456
4894
|
} else {
|
|
4457
4895
|
if (blankPaths.has(pathKey)) blankPaths.delete(pathKey);
|
|
4458
|
-
if (meta?.arrayOp === void 0) {
|
|
4896
|
+
if (meta?.arrayOp === void 0 && (isPlainRecord(currentValue) || Array.isArray(currentValue))) {
|
|
4459
4897
|
for (const existingKey of [...blankPaths]) {
|
|
4460
4898
|
if (isPathKeyUnder(existingKey, path)) blankPaths.delete(existingKey);
|
|
4461
4899
|
}
|
|
4462
4900
|
}
|
|
4463
4901
|
}
|
|
4464
4902
|
const wasAuthoredBefore = authoredPaths.has(pathKey);
|
|
4465
|
-
|
|
4903
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4904
|
+
if (path.length > 0) authoredPaths.add(pathKey);
|
|
4905
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4906
|
+
walkAuthoredFromConstraints(value[idx], [...path, idx], authoredPaths);
|
|
4907
|
+
}
|
|
4908
|
+
} else {
|
|
4909
|
+
walkAuthoredFromConstraints(value, path, authoredPaths);
|
|
4910
|
+
}
|
|
4466
4911
|
const newlyAuthored = !wasAuthoredBefore && authoredPaths.has(pathKey);
|
|
4467
|
-
|
|
4468
|
-
|
|
4912
|
+
let completedValue;
|
|
4913
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4914
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4915
|
+
value[idx] = mergeStructural(schema, [...path, idx], value[idx]);
|
|
4916
|
+
}
|
|
4917
|
+
completedValue = value;
|
|
4918
|
+
} else {
|
|
4919
|
+
completedValue = mergeStructural(schema, path, value);
|
|
4920
|
+
}
|
|
4469
4921
|
if (Object.is(currentValue, completedValue)) {
|
|
4470
4922
|
if (newlyAuthored && schema.isPreprocessOrCoerceLeaf(path)) {
|
|
4471
4923
|
const modeForAuthoringTransition = meta?.instance?.validateOn ?? fieldValidationMode;
|
|
@@ -4479,8 +4931,7 @@ function createFormStore(options) {
|
|
|
4479
4931
|
return true;
|
|
4480
4932
|
}
|
|
4481
4933
|
const oldArrayLength = Array.isArray(currentValue) ? currentValue.length : 0;
|
|
4482
|
-
|
|
4483
|
-
applyFormReplacement(nextForm, meta);
|
|
4934
|
+
applyTargetedWrite(path, completedValue, meta);
|
|
4484
4935
|
if (meta?.arrayOp !== void 0) {
|
|
4485
4936
|
const remap = remapForOp(meta.arrayOp, oldArrayLength);
|
|
4486
4937
|
arrayBookkeeping.migrateElementState(path, remap);
|
|
@@ -4563,7 +5014,7 @@ function createFormStore(options) {
|
|
|
4563
5014
|
const prevValidation = fieldValidationState.get(parentKey2);
|
|
4564
5015
|
if (prevValidation !== void 0) {
|
|
4565
5016
|
if (prevValidation.timer !== null) clearTimeout(prevValidation.timer);
|
|
4566
|
-
prevValidation.
|
|
5017
|
+
prevValidation.aborted = true;
|
|
4567
5018
|
fieldValidationState.delete(parentKey2);
|
|
4568
5019
|
}
|
|
4569
5020
|
appliedSync = true;
|
|
@@ -4587,15 +5038,19 @@ function createFormStore(options) {
|
|
|
4587
5038
|
const prev = fieldValidationState.get(key);
|
|
4588
5039
|
if (prev !== void 0) {
|
|
4589
5040
|
if (prev.timer !== null) clearTimeout(prev.timer);
|
|
4590
|
-
prev.
|
|
5041
|
+
prev.aborted = true;
|
|
4591
5042
|
}
|
|
4592
|
-
const
|
|
4593
|
-
|
|
5043
|
+
const fresh = {
|
|
5044
|
+
aborted: false,
|
|
5045
|
+
timer: null,
|
|
5046
|
+
settled: false,
|
|
5047
|
+
released: false
|
|
5048
|
+
};
|
|
4594
5049
|
fieldValidationState.set(key, fresh);
|
|
4595
5050
|
const myEpoch = ++scheduleEpoch;
|
|
4596
5051
|
const run = () => {
|
|
4597
5052
|
fresh.timer = null;
|
|
4598
|
-
if (
|
|
5053
|
+
if (fresh.aborted) return;
|
|
4599
5054
|
let activeIncremented = false;
|
|
4600
5055
|
try {
|
|
4601
5056
|
activeValidations.value += 1;
|
|
@@ -4612,7 +5067,7 @@ function createFormStore(options) {
|
|
|
4612
5067
|
const dataAtScope = subtreeScope ? getAtPath(form.value, path) : form.value;
|
|
4613
5068
|
const scopeKey = subtreeScope ? canonicalizePath(path).key : ROOT_PATH_KEY;
|
|
4614
5069
|
void Promise.resolve().then(() => schema.validateAtPath(dataAtScope, scopePath)).then((response) => {
|
|
4615
|
-
if (
|
|
5070
|
+
if (fresh.aborted) return;
|
|
4616
5071
|
if (myEpoch <= lastCommittedEpoch) return;
|
|
4617
5072
|
lastCommittedEpoch = myEpoch;
|
|
4618
5073
|
if (effectiveMode === "blur") {
|
|
@@ -4649,7 +5104,7 @@ function createFormStore(options) {
|
|
|
4649
5104
|
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
4650
5105
|
decFieldValidation(pkey);
|
|
4651
5106
|
}
|
|
4652
|
-
entry.
|
|
5107
|
+
entry.aborted = true;
|
|
4653
5108
|
}
|
|
4654
5109
|
fieldValidationState.clear();
|
|
4655
5110
|
}
|
|
@@ -4665,7 +5120,7 @@ function createFormStore(options) {
|
|
|
4665
5120
|
decFieldValidation(key);
|
|
4666
5121
|
entry.released = true;
|
|
4667
5122
|
}
|
|
4668
|
-
entry.
|
|
5123
|
+
entry.aborted = true;
|
|
4669
5124
|
fieldValidationState.delete(key);
|
|
4670
5125
|
}
|
|
4671
5126
|
}
|
|
@@ -4724,6 +5179,7 @@ function createFormStore(options) {
|
|
|
4724
5179
|
formChangeListeners.clear();
|
|
4725
5180
|
submitSuccessListeners.clear();
|
|
4726
5181
|
resetListeners.clear();
|
|
5182
|
+
onChangeRegistry.dispose();
|
|
4727
5183
|
persistOptIns.clear();
|
|
4728
5184
|
noSyncPaths.clear();
|
|
4729
5185
|
noSyncPathCounts.clear();
|
|
@@ -5029,7 +5485,7 @@ function createFormStore(options) {
|
|
|
5029
5485
|
});
|
|
5030
5486
|
const next = resetResponse.data;
|
|
5031
5487
|
rebuildAuthoredPaths(resetSource, next);
|
|
5032
|
-
applyFormReplacement(next);
|
|
5488
|
+
applyFormReplacement(next, { silent: true });
|
|
5033
5489
|
arrayIdentity.rebaselineAll();
|
|
5034
5490
|
originals.clear();
|
|
5035
5491
|
diffAndApply({}, next, [], (patch) => {
|
|
@@ -5275,6 +5731,7 @@ function createFormStore(options) {
|
|
|
5275
5731
|
settleTransforms,
|
|
5276
5732
|
scheduleFieldValidation,
|
|
5277
5733
|
onFormChange,
|
|
5734
|
+
registerOnChange: onChangeRegistry.register,
|
|
5278
5735
|
onSubmitSuccess,
|
|
5279
5736
|
onReset,
|
|
5280
5737
|
emitSubmitSuccess,
|
|
@@ -5304,6 +5761,13 @@ function captureErrorEntries(map) {
|
|
|
5304
5761
|
for (const [k, v] of map) out.push([k, [...v]]);
|
|
5305
5762
|
return out;
|
|
5306
5763
|
}
|
|
5764
|
+
function errorFieldsEqual(av, bvi) {
|
|
5765
|
+
if (av === bvi) return true;
|
|
5766
|
+
if (av.message !== bvi.message) return false;
|
|
5767
|
+
if (av.code !== bvi.code) return false;
|
|
5768
|
+
if (av.formKey !== bvi.formKey) return false;
|
|
5769
|
+
return av.path === bvi.path || pathsEqual(av.path, bvi.path);
|
|
5770
|
+
}
|
|
5307
5771
|
function errorsEqual(a, b) {
|
|
5308
5772
|
if (a.length !== b.length) return false;
|
|
5309
5773
|
const bMap = /* @__PURE__ */ new Map();
|
|
@@ -5313,18 +5777,7 @@ function errorsEqual(a, b) {
|
|
|
5313
5777
|
if (bv === void 0) return false;
|
|
5314
5778
|
if (v.length !== bv.length) return false;
|
|
5315
5779
|
for (let i = 0; i < v.length; i++) {
|
|
5316
|
-
|
|
5317
|
-
const bvi = bv[i];
|
|
5318
|
-
if (av === bvi) continue;
|
|
5319
|
-
if (av.message !== bvi.message) return false;
|
|
5320
|
-
if (av.code !== bvi.code) return false;
|
|
5321
|
-
if (av.formKey !== bvi.formKey) return false;
|
|
5322
|
-
if (av.path !== bvi.path) {
|
|
5323
|
-
if (av.path.length !== bvi.path.length) return false;
|
|
5324
|
-
for (let j = 0; j < av.path.length; j++) {
|
|
5325
|
-
if (av.path[j] !== bvi.path[j]) return false;
|
|
5326
|
-
}
|
|
5327
|
-
}
|
|
5780
|
+
if (!errorFieldsEqual(v[i], bv[i])) return false;
|
|
5328
5781
|
}
|
|
5329
5782
|
}
|
|
5330
5783
|
return true;
|
|
@@ -5692,11 +6145,16 @@ function useAbstractForm(configuration, options) {
|
|
|
5692
6145
|
if (merged.autoAria !== void 0) {
|
|
5693
6146
|
apiOptions.autoAria = merged.autoAria;
|
|
5694
6147
|
}
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
6148
|
+
const api = buildFormApi(state, formInstanceId, apiOptions);
|
|
6149
|
+
const onChangeConfig = configuration.onChange;
|
|
6150
|
+
if (onChangeConfig !== void 0) {
|
|
6151
|
+
const handler = typeof onChangeConfig === "function" ? onChangeConfig : onChangeConfig.handler;
|
|
6152
|
+
const onError = typeof onChangeConfig === "function" ? void 0 : onChangeConfig.onError;
|
|
6153
|
+
const options2 = onError === void 0 ? void 0 : { onError };
|
|
6154
|
+
const stop = state.registerOnChange(void 0, handler, options2, () => api);
|
|
6155
|
+
if (getCurrentScope() !== void 0) onScopeDispose(stop);
|
|
6156
|
+
}
|
|
6157
|
+
return api;
|
|
5700
6158
|
}
|
|
5701
6159
|
function mergeWithDefaults(defaults, configuration) {
|
|
5702
6160
|
const strict = configuration.strict ?? defaults.strict;
|
|
@@ -5906,6 +6364,99 @@ function warnIfAmbientProviderHadDuplicates() {
|
|
|
5906
6364
|
}
|
|
5907
6365
|
}
|
|
5908
6366
|
|
|
6367
|
+
const warnedNoParentRV = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
6368
|
+
let warnedOutsideSetup = false;
|
|
6369
|
+
function makeRegisterValueProxy(capturedRegisterValue) {
|
|
6370
|
+
return new Proxy({}, {
|
|
6371
|
+
get(_target, prop) {
|
|
6372
|
+
if (prop === "__v_isRef") return true;
|
|
6373
|
+
if (prop === "value") return capturedRegisterValue.value;
|
|
6374
|
+
const v = capturedRegisterValue.value;
|
|
6375
|
+
if (v === void 0) return void 0;
|
|
6376
|
+
return Reflect.get(v, prop);
|
|
6377
|
+
},
|
|
6378
|
+
has(_target, prop) {
|
|
6379
|
+
if (prop === "__v_isRef" || prop === "value") return true;
|
|
6380
|
+
const v = capturedRegisterValue.value;
|
|
6381
|
+
if (v === void 0) return false;
|
|
6382
|
+
return Reflect.has(v, prop);
|
|
6383
|
+
},
|
|
6384
|
+
ownKeys(_target) {
|
|
6385
|
+
const v = capturedRegisterValue.value;
|
|
6386
|
+
if (v === void 0) return [];
|
|
6387
|
+
return Reflect.ownKeys(v);
|
|
6388
|
+
},
|
|
6389
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
6390
|
+
const v = capturedRegisterValue.value;
|
|
6391
|
+
if (v === void 0) return void 0;
|
|
6392
|
+
const desc = Reflect.getOwnPropertyDescriptor(v, prop);
|
|
6393
|
+
if (desc !== void 0) {
|
|
6394
|
+
desc.configurable = true;
|
|
6395
|
+
}
|
|
6396
|
+
return desc;
|
|
6397
|
+
}
|
|
6398
|
+
});
|
|
6399
|
+
}
|
|
6400
|
+
function useRegister() {
|
|
6401
|
+
const instance = getCurrentInstance();
|
|
6402
|
+
if (instance === null) {
|
|
6403
|
+
warnOutsideSetup();
|
|
6404
|
+
return makeRegisterValueProxy(shallowRef(void 0));
|
|
6405
|
+
}
|
|
6406
|
+
ensureAttaformInstalled(instance.appContext.app);
|
|
6407
|
+
const capturedRegisterValue = shallowRef(void 0);
|
|
6408
|
+
const refreshAndStripBridgeAttrs = () => {
|
|
6409
|
+
const rawAttrs = instance.attrs;
|
|
6410
|
+
if ("registerValue" in rawAttrs) {
|
|
6411
|
+
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
6412
|
+
delete rawAttrs["registerValue"];
|
|
6413
|
+
} else {
|
|
6414
|
+
const dirs = instance.vnode.dirs;
|
|
6415
|
+
if (dirs !== null && dirs !== void 0) {
|
|
6416
|
+
for (const dir of dirs) {
|
|
6417
|
+
const marked = dir.dir?.[V_REGISTER_MARKER];
|
|
6418
|
+
if (marked === true) {
|
|
6419
|
+
capturedRegisterValue.value = dir.value;
|
|
6420
|
+
break;
|
|
6421
|
+
}
|
|
6422
|
+
}
|
|
6423
|
+
}
|
|
6424
|
+
}
|
|
6425
|
+
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
6426
|
+
};
|
|
6427
|
+
refreshAndStripBridgeAttrs();
|
|
6428
|
+
onBeforeMount(refreshAndStripBridgeAttrs);
|
|
6429
|
+
onBeforeUpdate(refreshAndStripBridgeAttrs);
|
|
6430
|
+
onMounted(() => {
|
|
6431
|
+
const el = instance.vnode.el;
|
|
6432
|
+
if (el !== null && el !== void 0 && typeof el === "object") {
|
|
6433
|
+
el[REGISTER_OWNER_MARKER] = true;
|
|
6434
|
+
}
|
|
6435
|
+
if (capturedRegisterValue.value === void 0) {
|
|
6436
|
+
warnNoParentRV(instance);
|
|
6437
|
+
}
|
|
6438
|
+
});
|
|
6439
|
+
return makeRegisterValueProxy(capturedRegisterValue);
|
|
6440
|
+
}
|
|
6441
|
+
function warnOutsideSetup() {
|
|
6442
|
+
if (!__DEV__) return;
|
|
6443
|
+
if (warnedOutsideSetup) return;
|
|
6444
|
+
warnedOutsideSetup = true;
|
|
6445
|
+
const frame = captureUserCallSite();
|
|
6446
|
+
console.warn(
|
|
6447
|
+
`[attaform] useRegister() called outside a component setup; returning an unbound RegisterValue proxy. Fix: call it inside <script setup> or a setup() function \u2014 not from an event handler or async callback.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
6448
|
+
);
|
|
6449
|
+
}
|
|
6450
|
+
function warnNoParentRV(instance) {
|
|
6451
|
+
if (!__DEV__ || warnedNoParentRV === null) return;
|
|
6452
|
+
if (warnedNoParentRV.has(instance)) return;
|
|
6453
|
+
warnedNoParentRV.add(instance);
|
|
6454
|
+
const frame = captureUserCallSite();
|
|
6455
|
+
console.warn(
|
|
6456
|
+
`[attaform] useRegister: no parent registerValue prop; RegisterValue fields will read as undefined. Pass v-register on the parent: \`<YourComponent v-register="form.register('field')" />\`.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
6457
|
+
);
|
|
6458
|
+
}
|
|
6459
|
+
|
|
5909
6460
|
const LAZY_BRAND = Symbol.for("attaform/wizard-lazy");
|
|
5910
6461
|
function lazy(resolve) {
|
|
5911
6462
|
return { [LAZY_BRAND]: true, resolve };
|
|
@@ -6969,5 +7520,5 @@ function warnIfAmbientWizardProviderHadDuplicates() {
|
|
|
6969
7520
|
}
|
|
6970
7521
|
}
|
|
6971
7522
|
|
|
6972
|
-
export { AttaformErrorCode as A,
|
|
6973
|
-
//# sourceMappingURL=attaform.
|
|
7523
|
+
export { AttaformErrorCode as A, deleteAtPath as B, safeOwnRead as C, DEFAULT_TIMINGS as D, humanize as E, PERSISTENCE_MODULE_KEY as P, injectWizard as a, isUnset as b, useRegister as c, useWizard as d, isPlainRecord as e, safeAssign as f, diffAndApply as g, slimKindOf as h, injectForm as i, applyPatchesForward as j, normalizeNumericOption as k, lazy as l, defaultCoercionRules as m, normalizePersistConfig as n, defaultDisplayState as o, defineCoercion as p, makeDefaultDisplayState as q, useAbstractForm as r, structuralSnapshot as s, getAtPath as t, unset as u, setAtPath as v, resolveStorageKeyBase as w, DEFAULT_PERSISTENCE_DEBOUNCE_MS as x, cleanupOrphanKeys as y, mergeSparseHydration as z };
|
|
7524
|
+
//# sourceMappingURL=attaform.CsB-iKbU.mjs.map
|