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,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const vue = require('vue');
|
|
4
|
-
const paths = require('./attaform.
|
|
4
|
+
const paths = require('./attaform.01iKS_lz.cjs');
|
|
5
5
|
|
|
6
6
|
function safeAssign(target, key, value) {
|
|
7
7
|
if (key === "__proto__") {
|
|
@@ -36,7 +36,7 @@ function descendStep(value, segment) {
|
|
|
36
36
|
if (typeof value !== "object") return NOT_FOUND;
|
|
37
37
|
if (Array.isArray(value)) {
|
|
38
38
|
if (typeof segment !== "number") return NOT_FOUND;
|
|
39
|
-
if (segment
|
|
39
|
+
if (!(segment in value)) return NOT_FOUND;
|
|
40
40
|
return value[segment];
|
|
41
41
|
}
|
|
42
42
|
const record = value;
|
|
@@ -71,7 +71,7 @@ function hasAtPath(root, path) {
|
|
|
71
71
|
if (current === null || current === void 0) return false;
|
|
72
72
|
if (typeof current !== "object") return false;
|
|
73
73
|
if (Array.isArray(current)) {
|
|
74
|
-
return typeof last === "number" && last
|
|
74
|
+
return typeof last === "number" && last in current;
|
|
75
75
|
}
|
|
76
76
|
const key = typeof last === "number" ? String(last) : last;
|
|
77
77
|
if (isShadowedKey(key)) return safeOwnHas(current, key);
|
|
@@ -100,6 +100,31 @@ function setAtPathOffset(root, path, value, offset) {
|
|
|
100
100
|
safeAssign(rec, head, setAtPathOffset(safeOwnRead(rec, head), path, value, nextOffset));
|
|
101
101
|
return rec;
|
|
102
102
|
}
|
|
103
|
+
const NO_IN_PLACE = { applied: false };
|
|
104
|
+
function tryInPlaceLeafWrite(root, path, value) {
|
|
105
|
+
if (path.length === 0) return NO_IN_PLACE;
|
|
106
|
+
let node = root;
|
|
107
|
+
for (let i = 0; i < path.length; i++) {
|
|
108
|
+
const seg = path[i];
|
|
109
|
+
if (Array.isArray(node)) {
|
|
110
|
+
if (typeof seg !== "number" || seg < 0 || seg >= node.length) return NO_IN_PLACE;
|
|
111
|
+
} else if (isPlainRecord(node)) {
|
|
112
|
+
if (typeof seg !== "string" || isShadowedKey(seg) || !(seg in node)) return NO_IN_PLACE;
|
|
113
|
+
} else {
|
|
114
|
+
return NO_IN_PLACE;
|
|
115
|
+
}
|
|
116
|
+
const container = node;
|
|
117
|
+
if (i < path.length - 1) {
|
|
118
|
+
node = container[seg];
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const old = container[seg];
|
|
122
|
+
if (isPlainRecord(old) || Array.isArray(old)) return NO_IN_PLACE;
|
|
123
|
+
container[seg] = value;
|
|
124
|
+
return { applied: true, old };
|
|
125
|
+
}
|
|
126
|
+
return NO_IN_PLACE;
|
|
127
|
+
}
|
|
103
128
|
function deleteAtPath(root, path) {
|
|
104
129
|
return deleteAtPathOffset(root, path, 0);
|
|
105
130
|
}
|
|
@@ -162,68 +187,80 @@ function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
|
|
|
162
187
|
}
|
|
163
188
|
if (consumer === null) return null;
|
|
164
189
|
if (Array.isArray(consumer)) {
|
|
165
|
-
|
|
166
|
-
const isTuple = typeof shape === "number";
|
|
167
|
-
const targetLen = isTuple ? shape : consumer.length;
|
|
168
|
-
let cachedElementDefault;
|
|
169
|
-
let cachedElementDefaultRead = false;
|
|
170
|
-
let mutated = targetLen > consumer.length;
|
|
171
|
-
const out = consumer.slice();
|
|
172
|
-
while (out.length < targetLen) out.push(void 0);
|
|
173
|
-
for (let i = 0; i < targetLen; i++) {
|
|
174
|
-
scratch.push(i);
|
|
175
|
-
let elemDefault;
|
|
176
|
-
if (isTuple) {
|
|
177
|
-
elemDefault = schema.getDefaultAtPath(scratch);
|
|
178
|
-
} else {
|
|
179
|
-
if (!cachedElementDefaultRead) {
|
|
180
|
-
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
181
|
-
cachedElementDefaultRead = true;
|
|
182
|
-
}
|
|
183
|
-
elemDefault = cachedElementDefault;
|
|
184
|
-
}
|
|
185
|
-
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
186
|
-
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
187
|
-
scratch.pop();
|
|
188
|
-
if (merged !== consumerElem) {
|
|
189
|
-
out[i] = merged;
|
|
190
|
-
mutated = true;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return mutated ? out : consumer;
|
|
190
|
+
return mergeStructuralArray(schema, scratch, consumer);
|
|
194
191
|
}
|
|
195
192
|
if (isPlainRecord(consumer)) {
|
|
196
193
|
if (!isPlainRecord(defaultValue)) {
|
|
197
194
|
return consumer;
|
|
198
195
|
}
|
|
199
|
-
let mutated = false;
|
|
200
196
|
const out = { ...consumer };
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
197
|
+
const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
|
|
198
|
+
const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
|
|
199
|
+
return filledAny || recursedAny ? out : consumer;
|
|
200
|
+
}
|
|
201
|
+
return consumer;
|
|
202
|
+
}
|
|
203
|
+
function mergeStructuralArray(schema, scratch, consumer) {
|
|
204
|
+
const shape = resolveArrayShape(schema, scratch);
|
|
205
|
+
const isTuple = typeof shape === "number";
|
|
206
|
+
const targetLen = isTuple ? shape : consumer.length;
|
|
207
|
+
let cachedElementDefault;
|
|
208
|
+
let cachedElementDefaultRead = false;
|
|
209
|
+
let mutated = targetLen > consumer.length;
|
|
210
|
+
const out = consumer.slice();
|
|
211
|
+
while (out.length < targetLen) out.push(void 0);
|
|
212
|
+
for (let i = 0; i < targetLen; i++) {
|
|
213
|
+
scratch.push(i);
|
|
214
|
+
let elemDefault;
|
|
215
|
+
if (isTuple) {
|
|
216
|
+
elemDefault = schema.getDefaultAtPath(scratch);
|
|
217
|
+
} else {
|
|
218
|
+
if (!cachedElementDefaultRead) {
|
|
219
|
+
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
220
|
+
cachedElementDefaultRead = true;
|
|
211
221
|
}
|
|
222
|
+
elemDefault = cachedElementDefault;
|
|
223
|
+
}
|
|
224
|
+
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
225
|
+
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
226
|
+
scratch.pop();
|
|
227
|
+
if (merged !== consumerElem) {
|
|
228
|
+
out[i] = merged;
|
|
229
|
+
mutated = true;
|
|
212
230
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
}
|
|
232
|
+
return mutated ? out : consumer;
|
|
233
|
+
}
|
|
234
|
+
function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
|
|
235
|
+
let mutated = false;
|
|
236
|
+
for (const key of Object.keys(defaultValue)) {
|
|
237
|
+
if (!safeOwnHas(consumer, key)) {
|
|
238
|
+
const defAtKey = safeOwnRead(defaultValue, key);
|
|
216
239
|
scratch.push(key);
|
|
217
|
-
const
|
|
240
|
+
const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
|
|
218
241
|
scratch.pop();
|
|
219
|
-
if (
|
|
220
|
-
safeAssign(out, key,
|
|
242
|
+
if (filled !== void 0) {
|
|
243
|
+
safeAssign(out, key, filled);
|
|
221
244
|
mutated = true;
|
|
222
245
|
}
|
|
223
246
|
}
|
|
224
|
-
return mutated ? out : consumer;
|
|
225
247
|
}
|
|
226
|
-
return
|
|
248
|
+
return mutated;
|
|
249
|
+
}
|
|
250
|
+
function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
|
|
251
|
+
let mutated = false;
|
|
252
|
+
for (const key of Object.keys(consumer)) {
|
|
253
|
+
const cVal = safeOwnRead(consumer, key);
|
|
254
|
+
if (cVal === void 0) continue;
|
|
255
|
+
scratch.push(key);
|
|
256
|
+
const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
|
|
257
|
+
scratch.pop();
|
|
258
|
+
if (merged !== cVal) {
|
|
259
|
+
safeAssign(out, key, merged);
|
|
260
|
+
mutated = true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return mutated;
|
|
227
264
|
}
|
|
228
265
|
function setAtPathWithSchemaFill(root, schema, fullPath, value) {
|
|
229
266
|
if (fullPath.length === 0) return value;
|
|
@@ -306,55 +343,27 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
306
343
|
const oldIsDescendable = isDescendable(oldValue);
|
|
307
344
|
const newIsDescendable = isDescendable(newValue);
|
|
308
345
|
if (oldValue === void 0 && newIsDescendable) {
|
|
309
|
-
|
|
310
|
-
for (let i = 0; i < newValue.length; i++) {
|
|
311
|
-
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
const rec = newValue;
|
|
315
|
-
for (const k of Object.keys(rec)) {
|
|
316
|
-
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
346
|
+
walkNewDescendable(newValue, prefix, visit);
|
|
319
347
|
return;
|
|
320
348
|
}
|
|
321
349
|
if (oldIsDescendable && newValue === void 0) {
|
|
322
|
-
|
|
323
|
-
for (let i = 0; i < oldValue.length; i++) {
|
|
324
|
-
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
325
|
-
}
|
|
326
|
-
} else {
|
|
327
|
-
const rec = oldValue;
|
|
328
|
-
for (const k of Object.keys(rec)) {
|
|
329
|
-
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
350
|
+
walkOldDescendable(oldValue, prefix, visit);
|
|
332
351
|
return;
|
|
333
352
|
}
|
|
334
353
|
if (oldIsDescendable && newIsDescendable) {
|
|
335
354
|
const oldIsArray = Array.isArray(oldValue);
|
|
336
355
|
const newIsArray = Array.isArray(newValue);
|
|
337
356
|
if (oldIsArray && newIsArray) {
|
|
338
|
-
|
|
339
|
-
const newArr = newValue;
|
|
340
|
-
const max = Math.max(oldArr.length, newArr.length);
|
|
341
|
-
for (let i = 0; i < max; i++) {
|
|
342
|
-
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
343
|
-
}
|
|
357
|
+
diffArraysLockstep(oldValue, newValue, prefix, visit);
|
|
344
358
|
return;
|
|
345
359
|
}
|
|
346
360
|
if (!oldIsArray && !newIsArray) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
for (const k of Object.keys(newRec)) {
|
|
355
|
-
if (seen.has(k)) continue;
|
|
356
|
-
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
357
|
-
}
|
|
361
|
+
diffObjectsLockstep(
|
|
362
|
+
oldValue,
|
|
363
|
+
newValue,
|
|
364
|
+
prefix,
|
|
365
|
+
visit
|
|
366
|
+
);
|
|
358
367
|
return;
|
|
359
368
|
}
|
|
360
369
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
@@ -378,7 +387,48 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
378
387
|
}
|
|
379
388
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
380
389
|
}
|
|
381
|
-
function
|
|
390
|
+
function walkNewDescendable(newValue, prefix, visit) {
|
|
391
|
+
if (Array.isArray(newValue)) {
|
|
392
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
393
|
+
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
const rec = newValue;
|
|
397
|
+
for (const k of Object.keys(rec)) {
|
|
398
|
+
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function walkOldDescendable(oldValue, prefix, visit) {
|
|
403
|
+
if (Array.isArray(oldValue)) {
|
|
404
|
+
for (let i = 0; i < oldValue.length; i++) {
|
|
405
|
+
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
const rec = oldValue;
|
|
409
|
+
for (const k of Object.keys(rec)) {
|
|
410
|
+
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function diffArraysLockstep(oldArr, newArr, prefix, visit) {
|
|
415
|
+
const max = Math.max(oldArr.length, newArr.length);
|
|
416
|
+
for (let i = 0; i < max; i++) {
|
|
417
|
+
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function diffObjectsLockstep(oldRec, newRec, prefix, visit) {
|
|
421
|
+
const seen = /* @__PURE__ */ new Set();
|
|
422
|
+
for (const k of Object.keys(oldRec)) {
|
|
423
|
+
seen.add(k);
|
|
424
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
425
|
+
}
|
|
426
|
+
for (const k of Object.keys(newRec)) {
|
|
427
|
+
if (seen.has(k)) continue;
|
|
428
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function applyChangedKeys(target, source, arrayOpPath, currentPath) {
|
|
382
432
|
if (!isDescendable(target) || !isDescendable(source)) return false;
|
|
383
433
|
const targetIsArray = Array.isArray(target);
|
|
384
434
|
const sourceIsArray = Array.isArray(source);
|
|
@@ -396,11 +446,27 @@ function applyChangedKeys(target, source) {
|
|
|
396
446
|
if (targetIsArray) {
|
|
397
447
|
const t = target;
|
|
398
448
|
const s = source;
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
449
|
+
if (arrayOpPath === null || paths.pathsEqual(currentPath, arrayOpPath)) {
|
|
450
|
+
if (t.length > s.length) t.length = s.length;
|
|
451
|
+
for (const idx of changedFirstSegments) {
|
|
452
|
+
if (typeof idx === "symbol") continue;
|
|
453
|
+
const i = typeof idx === "number" ? idx : Number(idx);
|
|
454
|
+
if (i >= s.length) continue;
|
|
455
|
+
t[i] = s[i];
|
|
456
|
+
}
|
|
457
|
+
} else {
|
|
458
|
+
for (const idx of changedFirstSegments) {
|
|
459
|
+
if (typeof idx === "symbol") continue;
|
|
460
|
+
const i = typeof idx === "number" ? idx : Number(idx);
|
|
461
|
+
if (i >= s.length) continue;
|
|
462
|
+
const childPath = appendSegment(currentPath, i);
|
|
463
|
+
const curEl = t[i];
|
|
464
|
+
const nextEl = s[i];
|
|
465
|
+
if (paths.isPathPrefix(childPath, arrayOpPath) && isDescendable(curEl) && isDescendable(nextEl) && applyChangedKeys(curEl, nextEl, arrayOpPath, childPath)) {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
t[i] = nextEl;
|
|
469
|
+
}
|
|
404
470
|
}
|
|
405
471
|
} else {
|
|
406
472
|
const t = target;
|
|
@@ -412,7 +478,14 @@ function applyChangedKeys(target, source) {
|
|
|
412
478
|
for (const k of changedFirstSegments) {
|
|
413
479
|
if (typeof k === "symbol") continue;
|
|
414
480
|
const key = String(k);
|
|
415
|
-
|
|
481
|
+
const nextVal = safeOwnRead(s, key);
|
|
482
|
+
if (arrayOpPath !== null) {
|
|
483
|
+
const curVal = safeOwnRead(t, key);
|
|
484
|
+
if (isDescendable(curVal) && isDescendable(nextVal) && applyChangedKeys(curVal, nextVal, arrayOpPath, appendSegment(currentPath, key))) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
safeAssign(t, key, nextVal);
|
|
416
489
|
}
|
|
417
490
|
}
|
|
418
491
|
return true;
|
|
@@ -524,6 +597,50 @@ function resolveGetDisplayState(config) {
|
|
|
524
597
|
return config ?? defaultDisplayState;
|
|
525
598
|
}
|
|
526
599
|
|
|
600
|
+
const AttaformErrorCode = {
|
|
601
|
+
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
602
|
+
NoValueSupplied: "atta:no-value-supplied",
|
|
603
|
+
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
604
|
+
AdapterThrew: "atta:adapter-threw",
|
|
605
|
+
/**
|
|
606
|
+
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
607
|
+
* threw (sync or async). The adapter caught the throw and surfaced
|
|
608
|
+
* it as a `ValidationError` at the field path so the form's normal
|
|
609
|
+
* error pipeline handles it instead of leaking as an unhandled
|
|
610
|
+
* rejection or routing through `submitError`.
|
|
611
|
+
*/
|
|
612
|
+
ValidatorThrew: "atta:validator-threw",
|
|
613
|
+
/**
|
|
614
|
+
* A function-form `defaultValues` factory threw or its promise
|
|
615
|
+
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
616
|
+
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
617
|
+
* the standard error pipeline carries the signal. Critical for the
|
|
618
|
+
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
619
|
+
* payload, but `schemaErrors` does, so the client sees the failure
|
|
620
|
+
* after rehydration without an extra channel.
|
|
621
|
+
*/
|
|
622
|
+
HydrationFailed: "atta:hydration-failed",
|
|
623
|
+
/** The supplied path didn't resolve to any node in the schema. */
|
|
624
|
+
PathNotFound: "atta:path-not-found",
|
|
625
|
+
/**
|
|
626
|
+
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
627
|
+
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
628
|
+
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
629
|
+
* aggregate error pipeline can carry the failure alongside ordinary
|
|
630
|
+
* validation errors. The raw factory error remains on
|
|
631
|
+
* `form.hydrateError` for retry UX.
|
|
632
|
+
*/
|
|
633
|
+
ActivationFailed: "atta:activation-failed"
|
|
634
|
+
};
|
|
635
|
+
function makeBlankRequiredError(segments, formKey) {
|
|
636
|
+
return {
|
|
637
|
+
message: "No value supplied",
|
|
638
|
+
path: [...segments],
|
|
639
|
+
formKey,
|
|
640
|
+
code: AttaformErrorCode.NoValueSupplied
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
|
|
527
644
|
const DEFAULT_FIELD_VALIDATION_DEBOUNCE_MS = 0;
|
|
528
645
|
const DEFAULT_PERSISTENCE_DEBOUNCE_MS = 300;
|
|
529
646
|
const DEFAULT_HISTORY_MAX_SNAPSHOTS = 128;
|
|
@@ -625,13 +742,19 @@ function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options
|
|
|
625
742
|
return c;
|
|
626
743
|
};
|
|
627
744
|
}
|
|
745
|
+
function resolveFieldMetaAndLabel(state, segments) {
|
|
746
|
+
const resolved = state.schema.getFieldMetaAtPath ? state.schema.getFieldMetaAtPath(segments) : EMPTY_RESOLVED_FIELD_META;
|
|
747
|
+
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
748
|
+
const label = resolved.label || humanize(lastSegment);
|
|
749
|
+
return { resolved, label };
|
|
750
|
+
}
|
|
628
751
|
function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
629
752
|
const record = state.fields.get(key);
|
|
630
753
|
const value = state.getValueAtPath(segments);
|
|
631
754
|
const original = state.originals.get(key)?.value;
|
|
632
755
|
const pristine = state.isPristineAtPath(segments);
|
|
633
756
|
const schemaForKey = state.schemaErrors.get(key);
|
|
634
|
-
const blankForKey = state.
|
|
757
|
+
const blankForKey = state.blankPaths.has(key) && state.schema.isRequiredAtPath(segments) ? [makeBlankRequiredError(segments, state.formKey)] : void 0;
|
|
635
758
|
const userForKey = state.userErrors.get(key);
|
|
636
759
|
const errors = [];
|
|
637
760
|
if (schemaForKey !== void 0) errors.push(...schemaForKey);
|
|
@@ -646,9 +769,7 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
646
769
|
const elementRecord = state.elements.get(key);
|
|
647
770
|
const elementsArr = elementRecord ? Object.freeze([...elementRecord.elements]) : EMPTY_ELEMENTS;
|
|
648
771
|
const firstElement = elementsArr[0] ?? null;
|
|
649
|
-
const resolved = state
|
|
650
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
651
|
-
const label = resolved.label || humanize(lastSegment);
|
|
772
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
652
773
|
return {
|
|
653
774
|
value,
|
|
654
775
|
original,
|
|
@@ -697,9 +818,32 @@ function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBa
|
|
|
697
818
|
getDisplayState
|
|
698
819
|
);
|
|
699
820
|
}
|
|
821
|
+
function visitActiveLeafPaths(value, base, visit) {
|
|
822
|
+
if (Array.isArray(value)) {
|
|
823
|
+
for (let i = 0; i < value.length; i++) {
|
|
824
|
+
const child = value[i];
|
|
825
|
+
if (Array.isArray(child) || isPlainRecord(child)) {
|
|
826
|
+
visitActiveLeafPaths(child, [...base, i], visit);
|
|
827
|
+
} else {
|
|
828
|
+
visit([...base, i]);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
if (isPlainRecord(value)) {
|
|
834
|
+
for (const k of Object.keys(value)) {
|
|
835
|
+
const child = value[k];
|
|
836
|
+
if (Array.isArray(child) || isPlainRecord(child)) {
|
|
837
|
+
visitActiveLeafPaths(child, [...base, k], visit);
|
|
838
|
+
} else {
|
|
839
|
+
visit([...base, k]);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
700
844
|
function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
701
845
|
const formValue = state.form.value;
|
|
702
|
-
const value =
|
|
846
|
+
const value = getAtPath(formValue, segments);
|
|
703
847
|
const original = state.originals.get(key)?.value;
|
|
704
848
|
let pristine = true;
|
|
705
849
|
let blank = true;
|
|
@@ -718,12 +862,16 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
718
862
|
let asyncPending = false;
|
|
719
863
|
const submissionAttempts = state.submissionAttempts.value;
|
|
720
864
|
const blurredLeafSegments = [];
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
865
|
+
const descendantLeaves = [];
|
|
866
|
+
visitActiveLeafPaths(value, segments, (leafSegments) => {
|
|
867
|
+
const { key: leafKey } = paths.keyForSegments(leafSegments);
|
|
868
|
+
const entry = state.originals.get(leafKey);
|
|
869
|
+
if (entry === void 0) return;
|
|
870
|
+
descendantLeaves.push({ key: leafKey, segments: entry.segments });
|
|
871
|
+
});
|
|
872
|
+
for (const { key: leafKey, segments: leafSeg } of descendantLeaves) {
|
|
725
873
|
const leafRecord = state.fields.get(leafKey);
|
|
726
|
-
if (!state.isPristineAtPathByKey(leafKey,
|
|
874
|
+
if (!state.isPristineAtPathByKey(leafKey, leafSeg)) {
|
|
727
875
|
pristine = false;
|
|
728
876
|
dirty = true;
|
|
729
877
|
}
|
|
@@ -734,7 +882,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
734
882
|
if (leafRecord?.interacted === true) interacted = true;
|
|
735
883
|
if (leafRecord?.blurredAfterInteraction === true) {
|
|
736
884
|
blurredAfterInteraction = true;
|
|
737
|
-
blurredLeafSegments.push(
|
|
885
|
+
blurredLeafSegments.push(leafSeg);
|
|
738
886
|
}
|
|
739
887
|
if (leafRecord?.connected === true) connected = true;
|
|
740
888
|
if ((state.fieldValidationCounts.get(leafKey) ?? 0) > 0) {
|
|
@@ -751,7 +899,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
751
899
|
if (leafGateOpen && since !== void 0 && (transformingSince === null || since < transformingSince))
|
|
752
900
|
transformingSince = since;
|
|
753
901
|
}
|
|
754
|
-
if (state.pathHasAsyncValidationByKey(leafKey,
|
|
902
|
+
if (state.pathHasAsyncValidationByKey(leafKey, leafSeg)) asyncPending = true;
|
|
755
903
|
const ts = leafRecord?.updatedAt;
|
|
756
904
|
if (ts !== void 0 && ts !== null) {
|
|
757
905
|
if (updatedAt === null || ts > updatedAt) updatedAt = ts;
|
|
@@ -785,9 +933,7 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
785
933
|
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
786
934
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
787
935
|
const valid = !gated && errors.length === 0 && !validating;
|
|
788
|
-
const resolved = state
|
|
789
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
790
|
-
const label = resolved.label || humanize(lastSegment);
|
|
936
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
791
937
|
return {
|
|
792
938
|
base: {
|
|
793
939
|
value,
|
|
@@ -1380,7 +1526,7 @@ function buildFieldArrayApi(state) {
|
|
|
1380
1526
|
append(path, value) {
|
|
1381
1527
|
const next = readArray(path);
|
|
1382
1528
|
next.push(value);
|
|
1383
|
-
return writeArray(path, next);
|
|
1529
|
+
return writeArray(path, next, { kind: "insert", index: next.length - 1 });
|
|
1384
1530
|
},
|
|
1385
1531
|
prepend(path, value) {
|
|
1386
1532
|
const next = readArray(path);
|
|
@@ -1570,20 +1716,20 @@ function buildFieldStateProxy(state, formInstanceId, getFormMetaBase, options) {
|
|
|
1570
1716
|
}
|
|
1571
1717
|
function materializeFields(state, containerSegments, snapshotFieldStateAt) {
|
|
1572
1718
|
const liveValue = getAtPath(state.form.value, containerSegments);
|
|
1573
|
-
return walk$
|
|
1719
|
+
return walk$1(liveValue, containerSegments, state.schema, snapshotFieldStateAt);
|
|
1574
1720
|
}
|
|
1575
|
-
function walk$
|
|
1721
|
+
function walk$1(value, basePath, schema, snapshotFieldStateAt) {
|
|
1576
1722
|
if (schema.isLeafAtPath(basePath)) return snapshotFieldStateAt(basePath);
|
|
1577
1723
|
if (value === null || value === void 0) return value;
|
|
1578
1724
|
if (typeof value !== "object") {
|
|
1579
1725
|
return value;
|
|
1580
1726
|
}
|
|
1581
1727
|
if (Array.isArray(value)) {
|
|
1582
|
-
return value.map((_, i) => walk$
|
|
1728
|
+
return value.map((_, i) => walk$1(value[i], [...basePath, i], schema, snapshotFieldStateAt));
|
|
1583
1729
|
}
|
|
1584
1730
|
const result = {};
|
|
1585
1731
|
for (const key of Object.keys(value)) {
|
|
1586
|
-
result[key] = walk$
|
|
1732
|
+
result[key] = walk$1(
|
|
1587
1733
|
value[key],
|
|
1588
1734
|
[...basePath, key],
|
|
1589
1735
|
schema,
|
|
@@ -1667,87 +1813,46 @@ function mergeDeep(target, source, path, schema) {
|
|
|
1667
1813
|
if (!isPlainRecord(source)) return source;
|
|
1668
1814
|
if (schema !== void 0) {
|
|
1669
1815
|
const du = schema.getUnionDiscriminatorAtPath(path);
|
|
1670
|
-
if (du !== void 0)
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
out2,
|
|
1684
|
-
key,
|
|
1685
|
-
mergeDeep(
|
|
1686
|
-
safeOwnRead(out2, key),
|
|
1687
|
-
safeOwnRead(sourceRecord, key),
|
|
1688
|
-
[...path, key],
|
|
1689
|
-
schema
|
|
1690
|
-
)
|
|
1691
|
-
);
|
|
1692
|
-
}
|
|
1693
|
-
return out2;
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
return {};
|
|
1816
|
+
if (du !== void 0) return mergeDuAwareKeys(source, path, schema, du);
|
|
1817
|
+
}
|
|
1818
|
+
return mergeObjectKeys(target, source, path, schema);
|
|
1819
|
+
}
|
|
1820
|
+
function mergeDuAwareKeys(source, path, schema, du) {
|
|
1821
|
+
const sourceDisc = source[du.discriminatorKey];
|
|
1822
|
+
if (sourceDisc !== void 0 && !du.isVariantSelected(sourceDisc)) {
|
|
1823
|
+
return { [du.discriminatorKey]: sourceDisc };
|
|
1824
|
+
}
|
|
1825
|
+
if (sourceDisc !== void 0) {
|
|
1826
|
+
const variantDefault = du.getVariantDefault(sourceDisc);
|
|
1827
|
+
if (isPlainRecord(variantDefault)) {
|
|
1828
|
+
return mergeVariantKeys(source, variantDefault, path, schema, du);
|
|
1697
1829
|
}
|
|
1698
1830
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1831
|
+
return {};
|
|
1832
|
+
}
|
|
1833
|
+
function mergeVariantKeys(source, variantDefault, path, schema, du) {
|
|
1834
|
+
const out = { ...variantDefault };
|
|
1701
1835
|
for (const key of Object.keys(source)) {
|
|
1836
|
+
if (!safeOwnHas(variantDefault, key) && key !== du.discriminatorKey) continue;
|
|
1702
1837
|
safeAssign(
|
|
1703
1838
|
out,
|
|
1704
1839
|
key,
|
|
1705
|
-
mergeDeep(
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1840
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1843
|
+
return out;
|
|
1844
|
+
}
|
|
1845
|
+
function mergeObjectKeys(target, source, path, schema) {
|
|
1846
|
+
const out = isPlainRecord(target) ? { ...target } : {};
|
|
1847
|
+
for (const key of Object.keys(source)) {
|
|
1848
|
+
safeAssign(
|
|
1849
|
+
out,
|
|
1850
|
+
key,
|
|
1851
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1711
1852
|
);
|
|
1712
1853
|
}
|
|
1713
1854
|
return out;
|
|
1714
1855
|
}
|
|
1715
|
-
|
|
1716
|
-
const AttaformErrorCode = {
|
|
1717
|
-
/** A required field is in the blank set — user hasn't supplied a value. */
|
|
1718
|
-
NoValueSupplied: "atta:no-value-supplied",
|
|
1719
|
-
/** The schema adapter's `validateAtPath` threw synchronously. */
|
|
1720
|
-
AdapterThrew: "atta:adapter-threw",
|
|
1721
|
-
/**
|
|
1722
|
-
* User code inside a `z.preprocess`, `.refine`, or `.transform`
|
|
1723
|
-
* threw (sync or async). The adapter caught the throw and surfaced
|
|
1724
|
-
* it as a `ValidationError` at the field path so the form's normal
|
|
1725
|
-
* error pipeline handles it instead of leaking as an unhandled
|
|
1726
|
-
* rejection or routing through `submitError`.
|
|
1727
|
-
*/
|
|
1728
|
-
ValidatorThrew: "atta:validator-threw",
|
|
1729
|
-
/**
|
|
1730
|
-
* A function-form `defaultValues` factory threw or its promise
|
|
1731
|
-
* rejected. The runtime captures the raw error on `form.hydrateError`
|
|
1732
|
-
* and ALSO surfaces a form-level `ValidationError` (path `[]`) so
|
|
1733
|
-
* the standard error pipeline carries the signal. Critical for the
|
|
1734
|
-
* SSR round-trip: `hydrateError` itself does not ride the wire
|
|
1735
|
-
* payload, but `schemaErrors` does, so the client sees the failure
|
|
1736
|
-
* after rehydration without an extra channel.
|
|
1737
|
-
*/
|
|
1738
|
-
HydrationFailed: "atta:hydration-failed",
|
|
1739
|
-
/** The supplied path didn't resolve to any node in the schema. */
|
|
1740
|
-
PathNotFound: "atta:path-not-found",
|
|
1741
|
-
/**
|
|
1742
|
-
* A walked form's `activate()` (async `defaultValues` factory) threw
|
|
1743
|
-
* during `wizard.handleSubmit`'s path walk. Surfaced as a synthetic
|
|
1744
|
-
* `ValidationError` at the form-level path (`[]`) so the wizard's
|
|
1745
|
-
* aggregate error pipeline can carry the failure alongside ordinary
|
|
1746
|
-
* validation errors. The raw factory error remains on
|
|
1747
|
-
* `form.hydrateError` for retry UX.
|
|
1748
|
-
*/
|
|
1749
|
-
ActivationFailed: "atta:activation-failed"
|
|
1750
|
-
};
|
|
1751
1856
|
|
|
1752
1857
|
const warnedNoScopeStores = paths.__DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
1753
1858
|
function buildProcessForm(state, formInstanceId, options = {}) {
|
|
@@ -2006,6 +2111,33 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
|
2006
2111
|
target.element.focus({ preventScroll: true });
|
|
2007
2112
|
}
|
|
2008
2113
|
|
|
2114
|
+
function captureUserCallSite() {
|
|
2115
|
+
const raw = new Error().stack;
|
|
2116
|
+
if (typeof raw !== "string") return void 0;
|
|
2117
|
+
const lines = raw.split("\n");
|
|
2118
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2119
|
+
const frame = lines[i];
|
|
2120
|
+
if (frame === void 0) continue;
|
|
2121
|
+
if (/attaform[/-]forms?/i.test(frame)) continue;
|
|
2122
|
+
if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
|
|
2123
|
+
const trimmed = frame.trim();
|
|
2124
|
+
if (trimmed.length === 0) continue;
|
|
2125
|
+
return shortenSourceFrame(trimmed);
|
|
2126
|
+
}
|
|
2127
|
+
return void 0;
|
|
2128
|
+
}
|
|
2129
|
+
function shortenSourceFrame(frame) {
|
|
2130
|
+
const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
|
|
2131
|
+
if (match === null) return frame;
|
|
2132
|
+
const [, urlOrPath, line] = match;
|
|
2133
|
+
if (urlOrPath === void 0 || line === void 0) return frame;
|
|
2134
|
+
let path = urlOrPath;
|
|
2135
|
+
path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
|
|
2136
|
+
path = path.replace(/^_nuxt\//, "");
|
|
2137
|
+
path = path.replace(/^\//, "");
|
|
2138
|
+
return `(${path}:${line})`;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2009
2141
|
function extractSchemaFields(schema) {
|
|
2010
2142
|
try {
|
|
2011
2143
|
const root = schema.getDefaultAtPath([]);
|
|
@@ -2064,9 +2196,9 @@ function isLeafValue(value) {
|
|
|
2064
2196
|
return true;
|
|
2065
2197
|
}
|
|
2066
2198
|
function isSlimPrimitiveValid(schema, store, path, value) {
|
|
2067
|
-
return walk
|
|
2199
|
+
return walk(schema, store, path, value);
|
|
2068
2200
|
}
|
|
2069
|
-
function walk
|
|
2201
|
+
function walk(schema, store, path, value) {
|
|
2070
2202
|
if (schema.isPreprocessOrCoerceLeaf(path)) return true;
|
|
2071
2203
|
const accepted = schema.getSlimPrimitiveTypesAtPath(path);
|
|
2072
2204
|
const kind = isLeafValue(value) ? slimKindOf(value) : Array.isArray(value) ? "array" : "object";
|
|
@@ -2076,13 +2208,13 @@ function walk$1(schema, store, path, value) {
|
|
|
2076
2208
|
}
|
|
2077
2209
|
if (Array.isArray(value)) {
|
|
2078
2210
|
for (let i = 0; i < value.length; i++) {
|
|
2079
|
-
if (!walk
|
|
2211
|
+
if (!walk(schema, store, [...path, i], value[i])) return false;
|
|
2080
2212
|
}
|
|
2081
2213
|
return true;
|
|
2082
2214
|
}
|
|
2083
2215
|
if (isPlainRecord(value)) {
|
|
2084
2216
|
for (const key of Object.keys(value)) {
|
|
2085
|
-
if (!walk
|
|
2217
|
+
if (!walk(schema, store, [...path, key], value[key])) {
|
|
2086
2218
|
return false;
|
|
2087
2219
|
}
|
|
2088
2220
|
}
|
|
@@ -2370,7 +2502,7 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2370
2502
|
throw new paths.AnonPersistError({
|
|
2371
2503
|
cause: "register-without-config",
|
|
2372
2504
|
schemaFields: extractSchemaFields(state.schema),
|
|
2373
|
-
callSite:
|
|
2505
|
+
callSite: captureUserCallSite()
|
|
2374
2506
|
});
|
|
2375
2507
|
}
|
|
2376
2508
|
const { aria } = computeFieldIdentity(formInstanceId, state.formKey, pathKey);
|
|
@@ -2482,49 +2614,60 @@ function walkUnsetSentinels(values, schema) {
|
|
|
2482
2614
|
walkUnspecified(rootSlim, [], paths);
|
|
2483
2615
|
return { cleanedValues: void 0, paths };
|
|
2484
2616
|
}
|
|
2485
|
-
const cleaned =
|
|
2617
|
+
const cleaned = walkCore(values, [], schema, paths, true);
|
|
2486
2618
|
return { cleanedValues: cleaned, paths };
|
|
2487
2619
|
}
|
|
2488
|
-
function
|
|
2620
|
+
function isOpaqueLeaf(value) {
|
|
2621
|
+
return value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || typeof value === "function";
|
|
2622
|
+
}
|
|
2623
|
+
function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
2489
2624
|
if (isUnset(input)) {
|
|
2490
2625
|
return expandUnsetAt(segments, schema, paths);
|
|
2491
2626
|
}
|
|
2492
2627
|
if (input === void 0) {
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2628
|
+
if (synthesizeSchemaKeys) {
|
|
2629
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2630
|
+
return walkUnspecified(slim, segments, paths);
|
|
2631
|
+
}
|
|
2498
2632
|
return input;
|
|
2499
2633
|
}
|
|
2634
|
+
if (input === null) return null;
|
|
2635
|
+
if (isOpaqueLeaf(input)) return input;
|
|
2500
2636
|
if (Array.isArray(input)) {
|
|
2501
2637
|
const out = new Array(input.length);
|
|
2502
2638
|
let mutated = false;
|
|
2503
2639
|
for (let i = 0; i < input.length; i++) {
|
|
2504
|
-
const walked =
|
|
2640
|
+
const walked = walkCore(input[i], [...segments, i], schema, paths, synthesizeSchemaKeys);
|
|
2505
2641
|
out[i] = walked;
|
|
2506
2642
|
if (walked !== input[i]) mutated = true;
|
|
2507
2643
|
}
|
|
2508
2644
|
return mutated ? out : input;
|
|
2509
2645
|
}
|
|
2510
2646
|
if (typeof input === "object") {
|
|
2511
|
-
const
|
|
2512
|
-
const inputKeys = Object.keys(
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2647
|
+
const obj = input;
|
|
2648
|
+
const inputKeys = Object.keys(obj);
|
|
2649
|
+
let keys = inputKeys;
|
|
2650
|
+
let mutated = false;
|
|
2651
|
+
let inputKeysSet = null;
|
|
2652
|
+
if (synthesizeSchemaKeys) {
|
|
2653
|
+
inputKeysSet = new Set(inputKeys);
|
|
2654
|
+
const allKeys = new Set(inputKeys);
|
|
2655
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2656
|
+
if (slim !== null && slim !== void 0 && typeof slim === "object" && !Array.isArray(slim) && !isOpaqueLeaf(slim)) {
|
|
2657
|
+
for (const k of Object.keys(slim)) allKeys.add(k);
|
|
2658
|
+
}
|
|
2659
|
+
keys = allKeys;
|
|
2660
|
+
mutated = allKeys.size !== inputKeys.length;
|
|
2517
2661
|
}
|
|
2518
2662
|
const out = {};
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
if (orig === void 0 && inputKeysSet.has(key)) {
|
|
2663
|
+
for (const key of keys) {
|
|
2664
|
+
const orig = obj[key];
|
|
2665
|
+
if (synthesizeSchemaKeys && orig === void 0 && inputKeysSet?.has(key) === true) {
|
|
2523
2666
|
safeAssign(out, key, void 0);
|
|
2524
2667
|
mutated = true;
|
|
2525
2668
|
continue;
|
|
2526
2669
|
}
|
|
2527
|
-
const walked =
|
|
2670
|
+
const walked = walkCore(orig, [...segments, key], schema, paths, synthesizeSchemaKeys);
|
|
2528
2671
|
safeAssign(out, key, walked);
|
|
2529
2672
|
if (walked !== orig) mutated = true;
|
|
2530
2673
|
}
|
|
@@ -2539,7 +2682,7 @@ function walkUnspecified(slim, segments, paths$1) {
|
|
|
2539
2682
|
}
|
|
2540
2683
|
return slim;
|
|
2541
2684
|
}
|
|
2542
|
-
if (slim
|
|
2685
|
+
if (isOpaqueLeaf(slim)) {
|
|
2543
2686
|
return slim;
|
|
2544
2687
|
}
|
|
2545
2688
|
if (Array.isArray(slim)) return slim;
|
|
@@ -2558,40 +2701,9 @@ function walkUnspecified(slim, segments, paths$1) {
|
|
|
2558
2701
|
}
|
|
2559
2702
|
function substituteUnsetSentinels(value, prefix, schema) {
|
|
2560
2703
|
const paths = [];
|
|
2561
|
-
const cleaned =
|
|
2704
|
+
const cleaned = walkCore(value, [...prefix], schema, paths, false);
|
|
2562
2705
|
return { cleanedValues: cleaned, paths };
|
|
2563
2706
|
}
|
|
2564
|
-
function substitute(input, segments, schema, paths) {
|
|
2565
|
-
if (isUnset(input)) {
|
|
2566
|
-
return expandUnsetAt(segments, schema, paths);
|
|
2567
|
-
}
|
|
2568
|
-
if (input === void 0 || input === null) return input;
|
|
2569
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2570
|
-
return input;
|
|
2571
|
-
}
|
|
2572
|
-
if (Array.isArray(input)) {
|
|
2573
|
-
let mutated = false;
|
|
2574
|
-
const out = new Array(input.length);
|
|
2575
|
-
for (let i = 0; i < input.length; i++) {
|
|
2576
|
-
const walked = substitute(input[i], [...segments, i], schema, paths);
|
|
2577
|
-
out[i] = walked;
|
|
2578
|
-
if (walked !== input[i]) mutated = true;
|
|
2579
|
-
}
|
|
2580
|
-
return mutated ? out : input;
|
|
2581
|
-
}
|
|
2582
|
-
if (typeof input === "object") {
|
|
2583
|
-
let mutated = false;
|
|
2584
|
-
const out = {};
|
|
2585
|
-
for (const key of Object.keys(input)) {
|
|
2586
|
-
const orig = input[key];
|
|
2587
|
-
const walked = substitute(orig, [...segments, key], schema, paths);
|
|
2588
|
-
safeAssign(out, key, walked);
|
|
2589
|
-
if (walked !== orig) mutated = true;
|
|
2590
|
-
}
|
|
2591
|
-
return mutated ? out : input;
|
|
2592
|
-
}
|
|
2593
|
-
return input;
|
|
2594
|
-
}
|
|
2595
2707
|
function isPrimitiveOrEmpty(value) {
|
|
2596
2708
|
if (value === null || value === void 0) return true;
|
|
2597
2709
|
const t = typeof value;
|
|
@@ -2621,7 +2733,7 @@ function expandUnsetAt(segments, schema, paths$1) {
|
|
|
2621
2733
|
paths$1.push(paths.canonicalizePath(segments).key);
|
|
2622
2734
|
return slim;
|
|
2623
2735
|
}
|
|
2624
|
-
if (slim
|
|
2736
|
+
if (isOpaqueLeaf(slim)) {
|
|
2625
2737
|
paths$1.push(paths.canonicalizePath(segments).key);
|
|
2626
2738
|
return slim;
|
|
2627
2739
|
}
|
|
@@ -2755,20 +2867,128 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2755
2867
|
if (instanceMeta === void 0) return meta;
|
|
2756
2868
|
return meta === void 0 ? { instance: instanceMeta } : { ...meta, instance: instanceMeta };
|
|
2757
2869
|
};
|
|
2870
|
+
const reMarkBlanksAfterSubstitution = (paths$1) => {
|
|
2871
|
+
for (const pathKey of paths$1) {
|
|
2872
|
+
const blankSegments = paths.segmentsForPathKey(pathKey);
|
|
2873
|
+
if (blankSegments === null) continue;
|
|
2874
|
+
state.setValueAtPath(
|
|
2875
|
+
blankSegments,
|
|
2876
|
+
state.getValueAtPath(blankSegments),
|
|
2877
|
+
withInstanceMeta({ blank: true })
|
|
2878
|
+
);
|
|
2879
|
+
}
|
|
2880
|
+
};
|
|
2758
2881
|
const getFormMetaBase = () => {
|
|
2759
|
-
|
|
2882
|
+
let rollup;
|
|
2883
|
+
const rootBase = () => rollup ?? (rollup = buildContainerFieldStateBase(
|
|
2760
2884
|
state,
|
|
2761
2885
|
paths.ROOT_PATH,
|
|
2762
2886
|
paths.ROOT_PATH_KEY,
|
|
2763
2887
|
formInstanceId
|
|
2764
|
-
);
|
|
2888
|
+
).base);
|
|
2765
2889
|
return {
|
|
2766
|
-
|
|
2890
|
+
// Rollup-derived (FieldStateBase) — the whole rollup builds once, on the
|
|
2891
|
+
// first access of any of these.
|
|
2892
|
+
get value() {
|
|
2893
|
+
return rootBase().value;
|
|
2894
|
+
},
|
|
2895
|
+
get original() {
|
|
2896
|
+
return rootBase().original;
|
|
2897
|
+
},
|
|
2898
|
+
get pristine() {
|
|
2899
|
+
return rootBase().pristine;
|
|
2900
|
+
},
|
|
2901
|
+
get dirty() {
|
|
2902
|
+
return rootBase().dirty;
|
|
2903
|
+
},
|
|
2904
|
+
get focused() {
|
|
2905
|
+
return rootBase().focused;
|
|
2906
|
+
},
|
|
2907
|
+
get blurred() {
|
|
2908
|
+
return rootBase().blurred;
|
|
2909
|
+
},
|
|
2910
|
+
get touched() {
|
|
2911
|
+
return rootBase().touched;
|
|
2912
|
+
},
|
|
2913
|
+
get interacted() {
|
|
2914
|
+
return rootBase().interacted;
|
|
2915
|
+
},
|
|
2916
|
+
get blurredAfterInteraction() {
|
|
2917
|
+
return rootBase().blurredAfterInteraction;
|
|
2918
|
+
},
|
|
2919
|
+
get connected() {
|
|
2920
|
+
return rootBase().connected;
|
|
2921
|
+
},
|
|
2922
|
+
get element() {
|
|
2923
|
+
return rootBase().element;
|
|
2924
|
+
},
|
|
2925
|
+
get elements() {
|
|
2926
|
+
return rootBase().elements;
|
|
2927
|
+
},
|
|
2928
|
+
get updatedAt() {
|
|
2929
|
+
return rootBase().updatedAt;
|
|
2930
|
+
},
|
|
2931
|
+
get errors() {
|
|
2932
|
+
return rootBase().errors;
|
|
2933
|
+
},
|
|
2934
|
+
get validating() {
|
|
2935
|
+
return rootBase().validating;
|
|
2936
|
+
},
|
|
2937
|
+
get valid() {
|
|
2938
|
+
return rootBase().valid;
|
|
2939
|
+
},
|
|
2940
|
+
get transforming() {
|
|
2941
|
+
return rootBase().transforming;
|
|
2942
|
+
},
|
|
2943
|
+
get busy() {
|
|
2944
|
+
return rootBase().busy;
|
|
2945
|
+
},
|
|
2946
|
+
get transformError() {
|
|
2947
|
+
return rootBase().transformError;
|
|
2948
|
+
},
|
|
2949
|
+
get path() {
|
|
2950
|
+
return rootBase().path;
|
|
2951
|
+
},
|
|
2952
|
+
get id() {
|
|
2953
|
+
return rootBase().id;
|
|
2954
|
+
},
|
|
2955
|
+
get aria() {
|
|
2956
|
+
return rootBase().aria;
|
|
2957
|
+
},
|
|
2958
|
+
get key() {
|
|
2959
|
+
return rootBase().key;
|
|
2960
|
+
},
|
|
2961
|
+
get blank() {
|
|
2962
|
+
return rootBase().blank;
|
|
2963
|
+
},
|
|
2964
|
+
get label() {
|
|
2965
|
+
return rootBase().label;
|
|
2966
|
+
},
|
|
2967
|
+
get description() {
|
|
2968
|
+
return rootBase().description;
|
|
2969
|
+
},
|
|
2970
|
+
get placeholder() {
|
|
2971
|
+
return rootBase().placeholder;
|
|
2972
|
+
},
|
|
2973
|
+
get meta() {
|
|
2974
|
+
return rootBase().meta;
|
|
2975
|
+
},
|
|
2976
|
+
get errorCount() {
|
|
2977
|
+
return rootBase().errors.length;
|
|
2978
|
+
},
|
|
2979
|
+
// Form-level scalars — EAGER reads, tracked on every field-state eval.
|
|
2980
|
+
// They are O(1) refs that never change on a keystroke, so tracking them
|
|
2981
|
+
// per field costs nothing on the hot path. Kept eager (NOT lazy like the
|
|
2982
|
+
// rollup) because behaviors beyond the predicate's own output depend on
|
|
2983
|
+
// every field re-evaluating when they flip — most notably, the display
|
|
2984
|
+
// engine is cleared on submit (revealing held spinners), and that
|
|
2985
|
+
// imperative reset only becomes visible if `submitting` is a tracked dep
|
|
2986
|
+
// of each field. Matches the pre-bust dependency set for these scalars
|
|
2987
|
+
// exactly.
|
|
2767
2988
|
submitting: state.submitting.value,
|
|
2768
2989
|
submissionAttempts: state.submissionAttempts.value,
|
|
2769
2990
|
departAttempts: state.departAttempts.value,
|
|
2770
2991
|
submitError: state.submitError.value,
|
|
2771
|
-
errorCount: rootBase.errors.length,
|
|
2772
2992
|
submitted: state.submitted.value,
|
|
2773
2993
|
instanceId: formInstanceId
|
|
2774
2994
|
};
|
|
@@ -2803,24 +3023,21 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2803
3023
|
const segments = paths.canonicalizePath(pathInput).segments;
|
|
2804
3024
|
return vue.computed(() => getAtPath(state.form.value, segments));
|
|
2805
3025
|
}
|
|
2806
|
-
function setValueImpl(pathOrValue, maybeValue) {
|
|
2807
|
-
|
|
3026
|
+
function setValueImpl(pathOrValue, maybeValue, maybeOptions) {
|
|
3027
|
+
const argc = arguments.length;
|
|
3028
|
+
const isPathForm = argc >= 2 && (typeof pathOrValue === "string" || Array.isArray(pathOrValue));
|
|
3029
|
+
const options2 = isPathForm ? maybeOptions : argc >= 2 ? maybeValue : void 0;
|
|
3030
|
+
const silent = options2?.silent === true;
|
|
3031
|
+
const writeMeta = (extra) => withInstanceMeta(silent ? { ...extra, silent: true } : extra);
|
|
3032
|
+
if (!isPathForm) {
|
|
2808
3033
|
const next = typeof pathOrValue === "function" ? pathOrValue(structuralSnapshot(state.form.value)) : pathOrValue;
|
|
2809
3034
|
const walked2 = walkUnsetSentinels(
|
|
2810
3035
|
next,
|
|
2811
3036
|
state.schema
|
|
2812
3037
|
);
|
|
2813
|
-
const ok2 = state.setValueAtPath([], walked2.cleanedValues,
|
|
3038
|
+
const ok2 = state.setValueAtPath([], walked2.cleanedValues, writeMeta());
|
|
2814
3039
|
if (!ok2) return false;
|
|
2815
|
-
|
|
2816
|
-
const blankSegments = paths.segmentsForPathKey(pathKey);
|
|
2817
|
-
if (blankSegments === null) continue;
|
|
2818
|
-
state.setValueAtPath(
|
|
2819
|
-
blankSegments,
|
|
2820
|
-
state.getValueAtPath(blankSegments),
|
|
2821
|
-
withInstanceMeta({ blank: true })
|
|
2822
|
-
);
|
|
2823
|
-
}
|
|
3040
|
+
reMarkBlanksAfterSubstitution(walked2.paths);
|
|
2824
3041
|
return true;
|
|
2825
3042
|
}
|
|
2826
3043
|
const segments = paths.canonicalizePath(pathOrValue).segments;
|
|
@@ -2832,7 +3049,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2832
3049
|
if (parentDU?.discriminatorKey === last) {
|
|
2833
3050
|
const slimDefault = state.schema.getEmptyValueAtPath(segments);
|
|
2834
3051
|
const blank = blankForKind(slimDefault);
|
|
2835
|
-
return state.setValueAtPath(segments, blank,
|
|
3052
|
+
return state.setValueAtPath(segments, blank, writeMeta({ blank: true }));
|
|
2836
3053
|
}
|
|
2837
3054
|
}
|
|
2838
3055
|
const blankPaths = [];
|
|
@@ -2843,9 +3060,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2843
3060
|
);
|
|
2844
3061
|
const segmentsKey = paths.canonicalizePath(segments).key;
|
|
2845
3062
|
if (blankPaths.length === 1 && blankPaths[0] === segmentsKey) {
|
|
2846
|
-
return state.setValueAtPath(segments, expanded,
|
|
3063
|
+
return state.setValueAtPath(segments, expanded, writeMeta({ blank: true }));
|
|
2847
3064
|
}
|
|
2848
|
-
const ok2 = state.setValueAtPath(segments, expanded,
|
|
3065
|
+
const ok2 = state.setValueAtPath(segments, expanded, writeMeta());
|
|
2849
3066
|
if (!ok2) return false;
|
|
2850
3067
|
for (const pathKey of blankPaths) {
|
|
2851
3068
|
const blankSegments = paths.segmentsForPathKey(pathKey);
|
|
@@ -2853,7 +3070,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2853
3070
|
state.setValueAtPath(
|
|
2854
3071
|
blankSegments,
|
|
2855
3072
|
state.getValueAtPath(blankSegments),
|
|
2856
|
-
|
|
3073
|
+
writeMeta({ blank: true })
|
|
2857
3074
|
);
|
|
2858
3075
|
}
|
|
2859
3076
|
return true;
|
|
@@ -2873,17 +3090,9 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2873
3090
|
segments,
|
|
2874
3091
|
state.schema
|
|
2875
3092
|
);
|
|
2876
|
-
const ok = state.setValueAtPath(segments, walked.cleanedValues,
|
|
3093
|
+
const ok = state.setValueAtPath(segments, walked.cleanedValues, writeMeta());
|
|
2877
3094
|
if (!ok) return false;
|
|
2878
|
-
|
|
2879
|
-
const blankSegments = paths.segmentsForPathKey(pathKey);
|
|
2880
|
-
if (blankSegments === null) continue;
|
|
2881
|
-
state.setValueAtPath(
|
|
2882
|
-
blankSegments,
|
|
2883
|
-
state.getValueAtPath(blankSegments),
|
|
2884
|
-
withInstanceMeta({ blank: true })
|
|
2885
|
-
);
|
|
2886
|
-
}
|
|
3095
|
+
reMarkBlanksAfterSubstitution(walked.paths);
|
|
2887
3096
|
return true;
|
|
2888
3097
|
}
|
|
2889
3098
|
const errorsProxy = buildErrorsProxy(state);
|
|
@@ -3252,7 +3461,19 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3252
3461
|
}
|
|
3253
3462
|
return Object.freeze(out);
|
|
3254
3463
|
}
|
|
3255
|
-
|
|
3464
|
+
const formHandle = {
|
|
3465
|
+
current: void 0
|
|
3466
|
+
};
|
|
3467
|
+
function onChangeImpl(a, b, c) {
|
|
3468
|
+
const sourced = typeof b === "function";
|
|
3469
|
+
const source = sourced ? a : void 0;
|
|
3470
|
+
const handler = sourced ? b : a;
|
|
3471
|
+
const options2 = sourced ? c : b;
|
|
3472
|
+
const stop = state.registerOnChange(source, handler, options2, () => formHandle.current);
|
|
3473
|
+
if (vue.getCurrentScope() !== void 0) vue.onScopeDispose(stop);
|
|
3474
|
+
return stop;
|
|
3475
|
+
}
|
|
3476
|
+
const api = {
|
|
3256
3477
|
handleSubmit: gated(handleSubmit),
|
|
3257
3478
|
// Callable readonly Proxies (`values`, `fields`, `errors`) and the
|
|
3258
3479
|
// reactive containers (`meta`, `history`, `blankPaths`) are exposed
|
|
@@ -3339,8 +3560,11 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3339
3560
|
get blankPaths() {
|
|
3340
3561
|
void state.activate();
|
|
3341
3562
|
return blankPathsView;
|
|
3342
|
-
}
|
|
3563
|
+
},
|
|
3564
|
+
onChange: onChangeImpl
|
|
3343
3565
|
};
|
|
3566
|
+
formHandle.current = api;
|
|
3567
|
+
return api;
|
|
3344
3568
|
}
|
|
3345
3569
|
|
|
3346
3570
|
const IDLE = Object.freeze({ display: "idle" });
|
|
@@ -3767,6 +3991,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3767
3991
|
originals,
|
|
3768
3992
|
blankPaths,
|
|
3769
3993
|
originalBlankPaths,
|
|
3994
|
+
authoredPaths,
|
|
3770
3995
|
fieldValidationCounts,
|
|
3771
3996
|
fieldValidatingSince,
|
|
3772
3997
|
fieldValidationState,
|
|
@@ -3794,6 +4019,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3794
4019
|
}));
|
|
3795
4020
|
migrateSetSubtree(blankPaths, arrayPath, remap);
|
|
3796
4021
|
migrateSetSubtree(originalBlankPaths, arrayPath, remap);
|
|
4022
|
+
migrateSetSubtree(authoredPaths, arrayPath, remap);
|
|
3797
4023
|
migrateMapSubtree(fieldValidatingSince, arrayPath, remap, (since) => since);
|
|
3798
4024
|
migrateMapSubtree(fieldValidationCounts, arrayPath, remap, (count) => count);
|
|
3799
4025
|
arrayIdentity.applyRemap(arrayPath, remap);
|
|
@@ -3837,7 +4063,7 @@ function createArrayBookkeeping(deps) {
|
|
|
3837
4063
|
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
3838
4064
|
decFieldValidation(key);
|
|
3839
4065
|
}
|
|
3840
|
-
entry.
|
|
4066
|
+
entry.aborted = true;
|
|
3841
4067
|
fieldValidationState.delete(key);
|
|
3842
4068
|
}
|
|
3843
4069
|
}
|
|
@@ -3849,6 +4075,170 @@ function createArrayBookkeeping(deps) {
|
|
|
3849
4075
|
};
|
|
3850
4076
|
}
|
|
3851
4077
|
|
|
4078
|
+
const NOOP_STOP = () => {
|
|
4079
|
+
};
|
|
4080
|
+
function isThenable(value) {
|
|
4081
|
+
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
4082
|
+
}
|
|
4083
|
+
function isSuppressed(meta) {
|
|
4084
|
+
return meta?.hydration === true || meta?.crossTab === true || meta?.silent === true;
|
|
4085
|
+
}
|
|
4086
|
+
function canonicalizeSourceList(raw) {
|
|
4087
|
+
const list = typeof raw === "string" ? [raw] : raw;
|
|
4088
|
+
const out = [];
|
|
4089
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4090
|
+
for (const entry of list) {
|
|
4091
|
+
const { segments, key } = paths.canonicalizePath(entry);
|
|
4092
|
+
if (seen.has(key)) continue;
|
|
4093
|
+
seen.add(key);
|
|
4094
|
+
out.push({ segments, key, dotted: paths.segmentsToDotted(segments) });
|
|
4095
|
+
}
|
|
4096
|
+
return out;
|
|
4097
|
+
}
|
|
4098
|
+
function makeResolver(source) {
|
|
4099
|
+
if (source === void 0) {
|
|
4100
|
+
const root = [{ segments: paths.ROOT_PATH, key: paths.ROOT_PATH_KEY, dotted: "" }];
|
|
4101
|
+
return () => root;
|
|
4102
|
+
}
|
|
4103
|
+
if (typeof source !== "function" && !vue.isRef(source)) {
|
|
4104
|
+
const fixed = canonicalizeSourceList(source);
|
|
4105
|
+
return () => fixed;
|
|
4106
|
+
}
|
|
4107
|
+
return () => canonicalizeSourceList(vue.toValue(source));
|
|
4108
|
+
}
|
|
4109
|
+
function createOnChangeRegistry(deps) {
|
|
4110
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
4111
|
+
function isCurrent(reg, key, token) {
|
|
4112
|
+
return reg.runs.get(key)?.token === token;
|
|
4113
|
+
}
|
|
4114
|
+
function routeError(reg, error, source, changed, value, previous, attempt, token) {
|
|
4115
|
+
if (reg.onError === void 0) {
|
|
4116
|
+
if (paths.__DEV__) {
|
|
4117
|
+
console.error(
|
|
4118
|
+
`[attaform] onChange handler threw for path '${source.dotted}' \u2014 error swallowed. Pass { onError } to handle it. Original error:`,
|
|
4119
|
+
error
|
|
4120
|
+
);
|
|
4121
|
+
}
|
|
4122
|
+
return;
|
|
4123
|
+
}
|
|
4124
|
+
const retry = () => {
|
|
4125
|
+
if (!isCurrent(reg, source.key, token)) return;
|
|
4126
|
+
runHandler(reg, source, changed, value, previous, attempt + 1);
|
|
4127
|
+
};
|
|
4128
|
+
const errCtx = {
|
|
4129
|
+
path: source.dotted,
|
|
4130
|
+
value,
|
|
4131
|
+
attempt,
|
|
4132
|
+
retry,
|
|
4133
|
+
form: reg.getForm()
|
|
4134
|
+
};
|
|
4135
|
+
try {
|
|
4136
|
+
reg.onError(error, errCtx);
|
|
4137
|
+
} catch (err) {
|
|
4138
|
+
if (paths.__DEV__) console.error("[attaform] onChange onError threw:", err);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
function runHandler(reg, source, changed, value, previous, attempt) {
|
|
4142
|
+
const prior = reg.runs.get(source.key);
|
|
4143
|
+
if (prior) prior.controller.abort();
|
|
4144
|
+
const controller = new AbortController();
|
|
4145
|
+
const token = ++reg.seq;
|
|
4146
|
+
reg.runs.set(source.key, { token, controller });
|
|
4147
|
+
const ctx = {
|
|
4148
|
+
path: source.dotted,
|
|
4149
|
+
previous,
|
|
4150
|
+
signal: controller.signal,
|
|
4151
|
+
attempt,
|
|
4152
|
+
form: reg.getForm(),
|
|
4153
|
+
changed
|
|
4154
|
+
};
|
|
4155
|
+
let result;
|
|
4156
|
+
try {
|
|
4157
|
+
result = reg.handler(value, ctx);
|
|
4158
|
+
} catch (error) {
|
|
4159
|
+
routeError(reg, error, source, changed, value, previous, attempt, token);
|
|
4160
|
+
return;
|
|
4161
|
+
}
|
|
4162
|
+
if (isThenable(result)) {
|
|
4163
|
+
result.then(void 0, (error) => {
|
|
4164
|
+
if (isCurrent(reg, source.key, token)) {
|
|
4165
|
+
routeError(reg, error, source, changed, value, previous, attempt, token);
|
|
4166
|
+
}
|
|
4167
|
+
});
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
function dispatch(patches, meta) {
|
|
4171
|
+
if (handlers.size === 0 || isSuppressed(meta)) return;
|
|
4172
|
+
for (const reg of handlers) {
|
|
4173
|
+
let sources;
|
|
4174
|
+
try {
|
|
4175
|
+
sources = reg.resolve();
|
|
4176
|
+
} catch (error) {
|
|
4177
|
+
if (paths.__DEV__) console.error("[attaform] onChange source getter threw:", error);
|
|
4178
|
+
continue;
|
|
4179
|
+
}
|
|
4180
|
+
for (const source of sources) {
|
|
4181
|
+
let changed;
|
|
4182
|
+
for (const patch of patches) {
|
|
4183
|
+
if (paths.isPathPrefix(source.segments, patch.path) || paths.isPathPrefix(patch.path, source.segments)) {
|
|
4184
|
+
(changed ?? (changed = [])).push(paths.segmentsToDotted(patch.path));
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
if (changed === void 0) continue;
|
|
4188
|
+
const value = deps.getValueAtPath(source.segments);
|
|
4189
|
+
const previous = reg.previous.has(source.key) ? reg.previous.get(source.key) : value;
|
|
4190
|
+
reg.previous.set(source.key, value);
|
|
4191
|
+
runHandler(reg, source, changed, value, previous, 0);
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
function register(source, handler, options, getForm) {
|
|
4196
|
+
if (deps.ssr) return NOOP_STOP;
|
|
4197
|
+
const reg = {
|
|
4198
|
+
handler,
|
|
4199
|
+
onError: options?.onError,
|
|
4200
|
+
getForm,
|
|
4201
|
+
resolve: makeResolver(source),
|
|
4202
|
+
previous: /* @__PURE__ */ new Map(),
|
|
4203
|
+
runs: /* @__PURE__ */ new Map(),
|
|
4204
|
+
seq: 0
|
|
4205
|
+
};
|
|
4206
|
+
try {
|
|
4207
|
+
for (const { key, segments } of reg.resolve()) {
|
|
4208
|
+
reg.previous.set(key, deps.getValueAtPath(segments));
|
|
4209
|
+
}
|
|
4210
|
+
} catch (error) {
|
|
4211
|
+
if (paths.__DEV__) console.error("[attaform] onChange source getter threw at registration:", error);
|
|
4212
|
+
}
|
|
4213
|
+
handlers.add(reg);
|
|
4214
|
+
let stopped = false;
|
|
4215
|
+
return () => {
|
|
4216
|
+
if (stopped) return;
|
|
4217
|
+
stopped = true;
|
|
4218
|
+
handlers.delete(reg);
|
|
4219
|
+
for (const run of reg.runs.values()) run.controller.abort();
|
|
4220
|
+
reg.runs.clear();
|
|
4221
|
+
reg.previous.clear();
|
|
4222
|
+
};
|
|
4223
|
+
}
|
|
4224
|
+
function dispose() {
|
|
4225
|
+
for (const reg of handlers) {
|
|
4226
|
+
for (const run of reg.runs.values()) run.controller.abort();
|
|
4227
|
+
reg.runs.clear();
|
|
4228
|
+
reg.previous.clear();
|
|
4229
|
+
}
|
|
4230
|
+
handlers.clear();
|
|
4231
|
+
}
|
|
4232
|
+
return {
|
|
4233
|
+
get active() {
|
|
4234
|
+
return handlers.size > 0;
|
|
4235
|
+
},
|
|
4236
|
+
register,
|
|
4237
|
+
dispatch,
|
|
4238
|
+
dispose
|
|
4239
|
+
};
|
|
4240
|
+
}
|
|
4241
|
+
|
|
3852
4242
|
function isHydratedFieldRecord(value) {
|
|
3853
4243
|
if (typeof value !== "object" || value === null) return false;
|
|
3854
4244
|
const r = value;
|
|
@@ -3933,6 +4323,17 @@ function walkAuthoredFromConstraints(value, prefix, out) {
|
|
|
3933
4323
|
}
|
|
3934
4324
|
}
|
|
3935
4325
|
}
|
|
4326
|
+
function freshElementIndices(op) {
|
|
4327
|
+
switch (op.kind) {
|
|
4328
|
+
case "insert":
|
|
4329
|
+
case "replace-at":
|
|
4330
|
+
return [op.index];
|
|
4331
|
+
case "remove":
|
|
4332
|
+
case "swap":
|
|
4333
|
+
case "move":
|
|
4334
|
+
return [];
|
|
4335
|
+
}
|
|
4336
|
+
}
|
|
3936
4337
|
function walkAuthoredFromSchemaDiff(withDefaults, withoutDefaults, prefix, out) {
|
|
3937
4338
|
if (isPlainRecord(withDefaults) && isPlainRecord(withoutDefaults)) {
|
|
3938
4339
|
const left = withDefaults;
|
|
@@ -3971,6 +4372,7 @@ function createFormStore(options) {
|
|
|
3971
4372
|
const formChangeListeners = /* @__PURE__ */ new Set();
|
|
3972
4373
|
const submitSuccessListeners = /* @__PURE__ */ new Set();
|
|
3973
4374
|
const resetListeners = /* @__PURE__ */ new Set();
|
|
4375
|
+
const onChangeRegistry = createOnChangeRegistry({ getValueAtPath, ssr });
|
|
3974
4376
|
const persistOptIns = paths.createPersistOptInRegistry();
|
|
3975
4377
|
const noSyncPaths = /* @__PURE__ */ new Set();
|
|
3976
4378
|
const noSyncPathCounts = /* @__PURE__ */ new Map();
|
|
@@ -4009,11 +4411,8 @@ function createFormStore(options) {
|
|
|
4009
4411
|
if (constraints !== void 0) {
|
|
4010
4412
|
walkAuthoredFromConstraints(constraints, [], authoredPaths);
|
|
4011
4413
|
}
|
|
4012
|
-
const
|
|
4013
|
-
|
|
4014
|
-
strict
|
|
4015
|
-
});
|
|
4016
|
-
walkAuthoredFromSchemaDiff(schemaWithDefaultsData, slimResponse.data, [], authoredPaths);
|
|
4414
|
+
const slimBaseline = schema.getEmptyValueAtPath([]);
|
|
4415
|
+
walkAuthoredFromSchemaDiff(schemaWithDefaultsData, slimBaseline, [], authoredPaths);
|
|
4017
4416
|
}
|
|
4018
4417
|
rebuildAuthoredPaths(defaultValues, schemaInitialData);
|
|
4019
4418
|
function filterAuthoredErrors(errors) {
|
|
@@ -4032,7 +4431,7 @@ function createFormStore(options) {
|
|
|
4032
4431
|
});
|
|
4033
4432
|
const form = vue.ref(stubbedInitialData);
|
|
4034
4433
|
const arrayIdentity = createArrayIdentity((arraySegs) => {
|
|
4035
|
-
const v = getAtPath(form.value, arraySegs);
|
|
4434
|
+
const v = getAtPath(vue.toRaw(form.value), arraySegs);
|
|
4036
4435
|
return Array.isArray(v) ? v.length : 0;
|
|
4037
4436
|
});
|
|
4038
4437
|
function arrayElementKey(path) {
|
|
@@ -4075,14 +4474,7 @@ function createFormStore(options) {
|
|
|
4075
4474
|
const segments = paths.segmentsForPathKey(pathKey);
|
|
4076
4475
|
if (segments === null) continue;
|
|
4077
4476
|
if (!schema.isRequiredAtPath(segments)) continue;
|
|
4078
|
-
result.set(pathKey, [
|
|
4079
|
-
{
|
|
4080
|
-
message: "No value supplied",
|
|
4081
|
-
path: [...segments],
|
|
4082
|
-
formKey,
|
|
4083
|
-
code: AttaformErrorCode.NoValueSupplied
|
|
4084
|
-
}
|
|
4085
|
-
]);
|
|
4477
|
+
result.set(pathKey, [makeBlankRequiredError(segments, formKey)]);
|
|
4086
4478
|
}
|
|
4087
4479
|
return result;
|
|
4088
4480
|
});
|
|
@@ -4322,6 +4714,7 @@ function createFormStore(options) {
|
|
|
4322
4714
|
originals,
|
|
4323
4715
|
blankPaths,
|
|
4324
4716
|
originalBlankPaths,
|
|
4717
|
+
authoredPaths,
|
|
4325
4718
|
fieldValidationCounts,
|
|
4326
4719
|
fieldValidatingSince,
|
|
4327
4720
|
fieldValidationState,
|
|
@@ -4331,17 +4724,8 @@ function createFormStore(options) {
|
|
|
4331
4724
|
touchFieldRecord,
|
|
4332
4725
|
decFieldValidation
|
|
4333
4726
|
});
|
|
4334
|
-
function
|
|
4335
|
-
const prev = form.value;
|
|
4336
|
-
if (Object.is(prev, next)) return;
|
|
4727
|
+
function commitWritePatches(patches, meta) {
|
|
4337
4728
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4338
|
-
const patches = [];
|
|
4339
|
-
diffAndApply(prev, next, [], (patch) => {
|
|
4340
|
-
patches.push(patch);
|
|
4341
|
-
});
|
|
4342
|
-
if (!applyChangedKeys(prev, next)) {
|
|
4343
|
-
form.value = next;
|
|
4344
|
-
}
|
|
4345
4729
|
for (const patch of patches) {
|
|
4346
4730
|
const { key } = paths.canonicalizePath(patch.path);
|
|
4347
4731
|
if (patch.kind === "added" && !originals.has(key)) {
|
|
@@ -4356,10 +4740,63 @@ function createFormStore(options) {
|
|
|
4356
4740
|
console.error("[attaform] onFormChange threw:", err);
|
|
4357
4741
|
}
|
|
4358
4742
|
}
|
|
4743
|
+
if (onChangeRegistry.active) onChangeRegistry.dispatch(patches, meta);
|
|
4744
|
+
}
|
|
4745
|
+
function applyFormReplacementWithPath(next, meta, arrayOpPath) {
|
|
4746
|
+
const prev = form.value;
|
|
4747
|
+
if (Object.is(prev, next)) return;
|
|
4748
|
+
const patches = [];
|
|
4749
|
+
diffAndApply(prev, next, [], (patch) => {
|
|
4750
|
+
patches.push(patch);
|
|
4751
|
+
});
|
|
4752
|
+
if (!applyChangedKeys(prev, next, arrayOpPath, [])) {
|
|
4753
|
+
form.value = next;
|
|
4754
|
+
} else if (patches.some(
|
|
4755
|
+
(p) => p.path.length > 0 && typeof p.path[0] === "string" && isShadowedKey(p.path[0])
|
|
4756
|
+
)) {
|
|
4757
|
+
vue.triggerRef(form);
|
|
4758
|
+
}
|
|
4759
|
+
commitWritePatches(patches, meta);
|
|
4760
|
+
}
|
|
4761
|
+
function applyFormReplacement(next, meta) {
|
|
4762
|
+
applyFormReplacementWithPath(next, meta, null);
|
|
4763
|
+
}
|
|
4764
|
+
function applyTargetedWrite(path, completedValue, meta) {
|
|
4765
|
+
const result = tryInPlaceLeafWrite(form.value, path, completedValue);
|
|
4766
|
+
if (!result.applied) {
|
|
4767
|
+
applyFormReplacementWithPath(
|
|
4768
|
+
setAtPathWithSchemaFill(form.value, schema, path, completedValue),
|
|
4769
|
+
meta,
|
|
4770
|
+
meta?.arrayOp !== void 0 ? path : null
|
|
4771
|
+
);
|
|
4772
|
+
return;
|
|
4773
|
+
}
|
|
4774
|
+
const patches = [];
|
|
4775
|
+
diffAndApply(result.old, completedValue, path, (patch) => {
|
|
4776
|
+
patches.push(patch);
|
|
4777
|
+
});
|
|
4778
|
+
commitWritePatches(patches, meta);
|
|
4359
4779
|
}
|
|
4360
4780
|
function setValueAtPath(path, value, meta) {
|
|
4361
|
-
|
|
4362
|
-
|
|
4781
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4782
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4783
|
+
value[idx] = stripSymbolsDeep(value[idx]);
|
|
4784
|
+
}
|
|
4785
|
+
} else {
|
|
4786
|
+
value = stripSymbolsDeep(value);
|
|
4787
|
+
}
|
|
4788
|
+
let slimOk = true;
|
|
4789
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4790
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4791
|
+
if (!isSlimPrimitiveValid(schema, form, [...path, idx], value[idx])) {
|
|
4792
|
+
slimOk = false;
|
|
4793
|
+
break;
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
} else {
|
|
4797
|
+
slimOk = isSlimPrimitiveValid(schema, form, path, value);
|
|
4798
|
+
}
|
|
4799
|
+
if (!slimOk) {
|
|
4363
4800
|
return false;
|
|
4364
4801
|
}
|
|
4365
4802
|
if (path.length >= 2) {
|
|
@@ -4452,22 +4889,37 @@ function createFormStore(options) {
|
|
|
4452
4889
|
}
|
|
4453
4890
|
}
|
|
4454
4891
|
}
|
|
4892
|
+
const currentValue = getAtPath(form.value, path);
|
|
4455
4893
|
const pathKey = paths.canonicalizePath(path).key;
|
|
4456
4894
|
if (meta?.blank === true) {
|
|
4457
4895
|
blankPaths.add(pathKey);
|
|
4458
4896
|
} else {
|
|
4459
4897
|
if (blankPaths.has(pathKey)) blankPaths.delete(pathKey);
|
|
4460
|
-
if (meta?.arrayOp === void 0) {
|
|
4898
|
+
if (meta?.arrayOp === void 0 && (isPlainRecord(currentValue) || Array.isArray(currentValue))) {
|
|
4461
4899
|
for (const existingKey of [...blankPaths]) {
|
|
4462
4900
|
if (isPathKeyUnder(existingKey, path)) blankPaths.delete(existingKey);
|
|
4463
4901
|
}
|
|
4464
4902
|
}
|
|
4465
4903
|
}
|
|
4466
4904
|
const wasAuthoredBefore = authoredPaths.has(pathKey);
|
|
4467
|
-
|
|
4905
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4906
|
+
if (path.length > 0) authoredPaths.add(pathKey);
|
|
4907
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4908
|
+
walkAuthoredFromConstraints(value[idx], [...path, idx], authoredPaths);
|
|
4909
|
+
}
|
|
4910
|
+
} else {
|
|
4911
|
+
walkAuthoredFromConstraints(value, path, authoredPaths);
|
|
4912
|
+
}
|
|
4468
4913
|
const newlyAuthored = !wasAuthoredBefore && authoredPaths.has(pathKey);
|
|
4469
|
-
|
|
4470
|
-
|
|
4914
|
+
let completedValue;
|
|
4915
|
+
if (meta?.arrayOp !== void 0 && Array.isArray(value)) {
|
|
4916
|
+
for (const idx of freshElementIndices(meta.arrayOp)) {
|
|
4917
|
+
value[idx] = mergeStructural(schema, [...path, idx], value[idx]);
|
|
4918
|
+
}
|
|
4919
|
+
completedValue = value;
|
|
4920
|
+
} else {
|
|
4921
|
+
completedValue = mergeStructural(schema, path, value);
|
|
4922
|
+
}
|
|
4471
4923
|
if (Object.is(currentValue, completedValue)) {
|
|
4472
4924
|
if (newlyAuthored && schema.isPreprocessOrCoerceLeaf(path)) {
|
|
4473
4925
|
const modeForAuthoringTransition = meta?.instance?.validateOn ?? fieldValidationMode;
|
|
@@ -4481,8 +4933,7 @@ function createFormStore(options) {
|
|
|
4481
4933
|
return true;
|
|
4482
4934
|
}
|
|
4483
4935
|
const oldArrayLength = Array.isArray(currentValue) ? currentValue.length : 0;
|
|
4484
|
-
|
|
4485
|
-
applyFormReplacement(nextForm, meta);
|
|
4936
|
+
applyTargetedWrite(path, completedValue, meta);
|
|
4486
4937
|
if (meta?.arrayOp !== void 0) {
|
|
4487
4938
|
const remap = remapForOp(meta.arrayOp, oldArrayLength);
|
|
4488
4939
|
arrayBookkeeping.migrateElementState(path, remap);
|
|
@@ -4565,7 +5016,7 @@ function createFormStore(options) {
|
|
|
4565
5016
|
const prevValidation = fieldValidationState.get(parentKey2);
|
|
4566
5017
|
if (prevValidation !== void 0) {
|
|
4567
5018
|
if (prevValidation.timer !== null) clearTimeout(prevValidation.timer);
|
|
4568
|
-
prevValidation.
|
|
5019
|
+
prevValidation.aborted = true;
|
|
4569
5020
|
fieldValidationState.delete(parentKey2);
|
|
4570
5021
|
}
|
|
4571
5022
|
appliedSync = true;
|
|
@@ -4589,15 +5040,19 @@ function createFormStore(options) {
|
|
|
4589
5040
|
const prev = fieldValidationState.get(key);
|
|
4590
5041
|
if (prev !== void 0) {
|
|
4591
5042
|
if (prev.timer !== null) clearTimeout(prev.timer);
|
|
4592
|
-
prev.
|
|
5043
|
+
prev.aborted = true;
|
|
4593
5044
|
}
|
|
4594
|
-
const
|
|
4595
|
-
|
|
5045
|
+
const fresh = {
|
|
5046
|
+
aborted: false,
|
|
5047
|
+
timer: null,
|
|
5048
|
+
settled: false,
|
|
5049
|
+
released: false
|
|
5050
|
+
};
|
|
4596
5051
|
fieldValidationState.set(key, fresh);
|
|
4597
5052
|
const myEpoch = ++scheduleEpoch;
|
|
4598
5053
|
const run = () => {
|
|
4599
5054
|
fresh.timer = null;
|
|
4600
|
-
if (
|
|
5055
|
+
if (fresh.aborted) return;
|
|
4601
5056
|
let activeIncremented = false;
|
|
4602
5057
|
try {
|
|
4603
5058
|
activeValidations.value += 1;
|
|
@@ -4614,7 +5069,7 @@ function createFormStore(options) {
|
|
|
4614
5069
|
const dataAtScope = subtreeScope ? getAtPath(form.value, path) : form.value;
|
|
4615
5070
|
const scopeKey = subtreeScope ? paths.canonicalizePath(path).key : paths.ROOT_PATH_KEY;
|
|
4616
5071
|
void Promise.resolve().then(() => schema.validateAtPath(dataAtScope, scopePath)).then((response) => {
|
|
4617
|
-
if (
|
|
5072
|
+
if (fresh.aborted) return;
|
|
4618
5073
|
if (myEpoch <= lastCommittedEpoch) return;
|
|
4619
5074
|
lastCommittedEpoch = myEpoch;
|
|
4620
5075
|
if (effectiveMode === "blur") {
|
|
@@ -4651,7 +5106,7 @@ function createFormStore(options) {
|
|
|
4651
5106
|
activeValidations.value = Math.max(0, activeValidations.value - 1);
|
|
4652
5107
|
decFieldValidation(pkey);
|
|
4653
5108
|
}
|
|
4654
|
-
entry.
|
|
5109
|
+
entry.aborted = true;
|
|
4655
5110
|
}
|
|
4656
5111
|
fieldValidationState.clear();
|
|
4657
5112
|
}
|
|
@@ -4667,7 +5122,7 @@ function createFormStore(options) {
|
|
|
4667
5122
|
decFieldValidation(key);
|
|
4668
5123
|
entry.released = true;
|
|
4669
5124
|
}
|
|
4670
|
-
entry.
|
|
5125
|
+
entry.aborted = true;
|
|
4671
5126
|
fieldValidationState.delete(key);
|
|
4672
5127
|
}
|
|
4673
5128
|
}
|
|
@@ -4726,6 +5181,7 @@ function createFormStore(options) {
|
|
|
4726
5181
|
formChangeListeners.clear();
|
|
4727
5182
|
submitSuccessListeners.clear();
|
|
4728
5183
|
resetListeners.clear();
|
|
5184
|
+
onChangeRegistry.dispose();
|
|
4729
5185
|
persistOptIns.clear();
|
|
4730
5186
|
noSyncPaths.clear();
|
|
4731
5187
|
noSyncPathCounts.clear();
|
|
@@ -5031,7 +5487,7 @@ function createFormStore(options) {
|
|
|
5031
5487
|
});
|
|
5032
5488
|
const next = resetResponse.data;
|
|
5033
5489
|
rebuildAuthoredPaths(resetSource, next);
|
|
5034
|
-
applyFormReplacement(next);
|
|
5490
|
+
applyFormReplacement(next, { silent: true });
|
|
5035
5491
|
arrayIdentity.rebaselineAll();
|
|
5036
5492
|
originals.clear();
|
|
5037
5493
|
diffAndApply({}, next, [], (patch) => {
|
|
@@ -5277,6 +5733,7 @@ function createFormStore(options) {
|
|
|
5277
5733
|
settleTransforms,
|
|
5278
5734
|
scheduleFieldValidation,
|
|
5279
5735
|
onFormChange,
|
|
5736
|
+
registerOnChange: onChangeRegistry.register,
|
|
5280
5737
|
onSubmitSuccess,
|
|
5281
5738
|
onReset,
|
|
5282
5739
|
emitSubmitSuccess,
|
|
@@ -5306,6 +5763,13 @@ function captureErrorEntries(map) {
|
|
|
5306
5763
|
for (const [k, v] of map) out.push([k, [...v]]);
|
|
5307
5764
|
return out;
|
|
5308
5765
|
}
|
|
5766
|
+
function errorFieldsEqual(av, bvi) {
|
|
5767
|
+
if (av === bvi) return true;
|
|
5768
|
+
if (av.message !== bvi.message) return false;
|
|
5769
|
+
if (av.code !== bvi.code) return false;
|
|
5770
|
+
if (av.formKey !== bvi.formKey) return false;
|
|
5771
|
+
return av.path === bvi.path || paths.pathsEqual(av.path, bvi.path);
|
|
5772
|
+
}
|
|
5309
5773
|
function errorsEqual(a, b) {
|
|
5310
5774
|
if (a.length !== b.length) return false;
|
|
5311
5775
|
const bMap = /* @__PURE__ */ new Map();
|
|
@@ -5315,18 +5779,7 @@ function errorsEqual(a, b) {
|
|
|
5315
5779
|
if (bv === void 0) return false;
|
|
5316
5780
|
if (v.length !== bv.length) return false;
|
|
5317
5781
|
for (let i = 0; i < v.length; i++) {
|
|
5318
|
-
|
|
5319
|
-
const bvi = bv[i];
|
|
5320
|
-
if (av === bvi) continue;
|
|
5321
|
-
if (av.message !== bvi.message) return false;
|
|
5322
|
-
if (av.code !== bvi.code) return false;
|
|
5323
|
-
if (av.formKey !== bvi.formKey) return false;
|
|
5324
|
-
if (av.path !== bvi.path) {
|
|
5325
|
-
if (av.path.length !== bvi.path.length) return false;
|
|
5326
|
-
for (let j = 0; j < av.path.length; j++) {
|
|
5327
|
-
if (av.path[j] !== bvi.path[j]) return false;
|
|
5328
|
-
}
|
|
5329
|
-
}
|
|
5782
|
+
if (!errorFieldsEqual(v[i], bv[i])) return false;
|
|
5330
5783
|
}
|
|
5331
5784
|
}
|
|
5332
5785
|
return true;
|
|
@@ -5540,7 +5993,7 @@ function useAbstractForm(configuration, options) {
|
|
|
5540
5993
|
throw new paths.AnonPersistError({
|
|
5541
5994
|
cause: "no-key",
|
|
5542
5995
|
schemaFields: extractSchemaFields(resolvedSchema),
|
|
5543
|
-
callSite:
|
|
5996
|
+
callSite: captureUserCallSite()
|
|
5544
5997
|
});
|
|
5545
5998
|
}
|
|
5546
5999
|
const existing = registry.forms.get(key);
|
|
@@ -5694,11 +6147,16 @@ function useAbstractForm(configuration, options) {
|
|
|
5694
6147
|
if (merged.autoAria !== void 0) {
|
|
5695
6148
|
apiOptions.autoAria = merged.autoAria;
|
|
5696
6149
|
}
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
6150
|
+
const api = buildFormApi(state, formInstanceId, apiOptions);
|
|
6151
|
+
const onChangeConfig = configuration.onChange;
|
|
6152
|
+
if (onChangeConfig !== void 0) {
|
|
6153
|
+
const handler = typeof onChangeConfig === "function" ? onChangeConfig : onChangeConfig.handler;
|
|
6154
|
+
const onError = typeof onChangeConfig === "function" ? void 0 : onChangeConfig.onError;
|
|
6155
|
+
const options2 = onError === void 0 ? void 0 : { onError };
|
|
6156
|
+
const stop = state.registerOnChange(void 0, handler, options2, () => api);
|
|
6157
|
+
if (vue.getCurrentScope() !== void 0) vue.onScopeDispose(stop);
|
|
6158
|
+
}
|
|
6159
|
+
return api;
|
|
5702
6160
|
}
|
|
5703
6161
|
function mergeWithDefaults(defaults, configuration) {
|
|
5704
6162
|
const strict = configuration.strict ?? defaults.strict;
|
|
@@ -5789,7 +6247,7 @@ function recordAmbientProvide(ssr) {
|
|
|
5789
6247
|
if (instance === null) return;
|
|
5790
6248
|
const instanceKey = instance;
|
|
5791
6249
|
const entry = {
|
|
5792
|
-
source:
|
|
6250
|
+
source: captureUserCallSite()
|
|
5793
6251
|
};
|
|
5794
6252
|
const existing = ambientProvideHistory.get(instanceKey);
|
|
5795
6253
|
if (existing === void 0) {
|
|
@@ -5828,7 +6286,7 @@ function enforceAnonPersistRule(formKey, ssr) {
|
|
|
5828
6286
|
if (paths.__DEV__)
|
|
5829
6287
|
throw new paths.AnonPersistError({
|
|
5830
6288
|
cause: "no-key",
|
|
5831
|
-
callSite:
|
|
6289
|
+
callSite: captureUserCallSite()
|
|
5832
6290
|
});
|
|
5833
6291
|
if (!ssr && !warnedAnonPersistKeys.has(formKey)) {
|
|
5834
6292
|
warnedAnonPersistKeys.add(formKey);
|
|
@@ -5885,7 +6343,7 @@ function resolveState(key, registry) {
|
|
|
5885
6343
|
}
|
|
5886
6344
|
function warnMiss$1(detail, ssr) {
|
|
5887
6345
|
if (!paths.__DEV__ || ssr) return;
|
|
5888
|
-
const frame =
|
|
6346
|
+
const frame = captureUserCallSite();
|
|
5889
6347
|
console.warn(
|
|
5890
6348
|
`[attaform] injectForm: ${detail}. Returning null.` + (frame !== void 0 ? ` ${frame}` : "")
|
|
5891
6349
|
);
|
|
@@ -5908,6 +6366,99 @@ function warnIfAmbientProviderHadDuplicates() {
|
|
|
5908
6366
|
}
|
|
5909
6367
|
}
|
|
5910
6368
|
|
|
6369
|
+
const warnedNoParentRV = paths.__DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
6370
|
+
let warnedOutsideSetup = false;
|
|
6371
|
+
function makeRegisterValueProxy(capturedRegisterValue) {
|
|
6372
|
+
return new Proxy({}, {
|
|
6373
|
+
get(_target, prop) {
|
|
6374
|
+
if (prop === "__v_isRef") return true;
|
|
6375
|
+
if (prop === "value") return capturedRegisterValue.value;
|
|
6376
|
+
const v = capturedRegisterValue.value;
|
|
6377
|
+
if (v === void 0) return void 0;
|
|
6378
|
+
return Reflect.get(v, prop);
|
|
6379
|
+
},
|
|
6380
|
+
has(_target, prop) {
|
|
6381
|
+
if (prop === "__v_isRef" || prop === "value") return true;
|
|
6382
|
+
const v = capturedRegisterValue.value;
|
|
6383
|
+
if (v === void 0) return false;
|
|
6384
|
+
return Reflect.has(v, prop);
|
|
6385
|
+
},
|
|
6386
|
+
ownKeys(_target) {
|
|
6387
|
+
const v = capturedRegisterValue.value;
|
|
6388
|
+
if (v === void 0) return [];
|
|
6389
|
+
return Reflect.ownKeys(v);
|
|
6390
|
+
},
|
|
6391
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
6392
|
+
const v = capturedRegisterValue.value;
|
|
6393
|
+
if (v === void 0) return void 0;
|
|
6394
|
+
const desc = Reflect.getOwnPropertyDescriptor(v, prop);
|
|
6395
|
+
if (desc !== void 0) {
|
|
6396
|
+
desc.configurable = true;
|
|
6397
|
+
}
|
|
6398
|
+
return desc;
|
|
6399
|
+
}
|
|
6400
|
+
});
|
|
6401
|
+
}
|
|
6402
|
+
function useRegister() {
|
|
6403
|
+
const instance = vue.getCurrentInstance();
|
|
6404
|
+
if (instance === null) {
|
|
6405
|
+
warnOutsideSetup();
|
|
6406
|
+
return makeRegisterValueProxy(vue.shallowRef(void 0));
|
|
6407
|
+
}
|
|
6408
|
+
paths.ensureAttaformInstalled(instance.appContext.app);
|
|
6409
|
+
const capturedRegisterValue = vue.shallowRef(void 0);
|
|
6410
|
+
const refreshAndStripBridgeAttrs = () => {
|
|
6411
|
+
const rawAttrs = instance.attrs;
|
|
6412
|
+
if ("registerValue" in rawAttrs) {
|
|
6413
|
+
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
6414
|
+
delete rawAttrs["registerValue"];
|
|
6415
|
+
} else {
|
|
6416
|
+
const dirs = instance.vnode.dirs;
|
|
6417
|
+
if (dirs !== null && dirs !== void 0) {
|
|
6418
|
+
for (const dir of dirs) {
|
|
6419
|
+
const marked = dir.dir?.[paths.V_REGISTER_MARKER];
|
|
6420
|
+
if (marked === true) {
|
|
6421
|
+
capturedRegisterValue.value = dir.value;
|
|
6422
|
+
break;
|
|
6423
|
+
}
|
|
6424
|
+
}
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6427
|
+
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
6428
|
+
};
|
|
6429
|
+
refreshAndStripBridgeAttrs();
|
|
6430
|
+
vue.onBeforeMount(refreshAndStripBridgeAttrs);
|
|
6431
|
+
vue.onBeforeUpdate(refreshAndStripBridgeAttrs);
|
|
6432
|
+
vue.onMounted(() => {
|
|
6433
|
+
const el = instance.vnode.el;
|
|
6434
|
+
if (el !== null && el !== void 0 && typeof el === "object") {
|
|
6435
|
+
el[paths.REGISTER_OWNER_MARKER] = true;
|
|
6436
|
+
}
|
|
6437
|
+
if (capturedRegisterValue.value === void 0) {
|
|
6438
|
+
warnNoParentRV(instance);
|
|
6439
|
+
}
|
|
6440
|
+
});
|
|
6441
|
+
return makeRegisterValueProxy(capturedRegisterValue);
|
|
6442
|
+
}
|
|
6443
|
+
function warnOutsideSetup() {
|
|
6444
|
+
if (!paths.__DEV__) return;
|
|
6445
|
+
if (warnedOutsideSetup) return;
|
|
6446
|
+
warnedOutsideSetup = true;
|
|
6447
|
+
const frame = captureUserCallSite();
|
|
6448
|
+
console.warn(
|
|
6449
|
+
`[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}` : "")
|
|
6450
|
+
);
|
|
6451
|
+
}
|
|
6452
|
+
function warnNoParentRV(instance) {
|
|
6453
|
+
if (!paths.__DEV__ || warnedNoParentRV === null) return;
|
|
6454
|
+
if (warnedNoParentRV.has(instance)) return;
|
|
6455
|
+
warnedNoParentRV.add(instance);
|
|
6456
|
+
const frame = captureUserCallSite();
|
|
6457
|
+
console.warn(
|
|
6458
|
+
`[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}` : "")
|
|
6459
|
+
);
|
|
6460
|
+
}
|
|
6461
|
+
|
|
5911
6462
|
const LAZY_BRAND = Symbol.for("attaform/wizard-lazy");
|
|
5912
6463
|
function lazy(resolve) {
|
|
5913
6464
|
return { [LAZY_BRAND]: true, resolve };
|
|
@@ -6892,7 +7443,7 @@ function recordAmbientWizardProvide(ssr) {
|
|
|
6892
7443
|
if (instance === null) return;
|
|
6893
7444
|
const instanceKey = instance;
|
|
6894
7445
|
const entry = {
|
|
6895
|
-
source:
|
|
7446
|
+
source: captureUserCallSite()
|
|
6896
7447
|
};
|
|
6897
7448
|
const existing = ambientWizardProvideHistory.get(instanceKey);
|
|
6898
7449
|
if (existing === void 0) {
|
|
@@ -6947,7 +7498,7 @@ function availableKeysHint(wizards) {
|
|
|
6947
7498
|
}
|
|
6948
7499
|
function warnMiss(detail, ssr, hint) {
|
|
6949
7500
|
if (!paths.__DEV__ || ssr) return;
|
|
6950
|
-
const frame =
|
|
7501
|
+
const frame = captureUserCallSite();
|
|
6951
7502
|
const parts = [`[attaform] injectWizard: ${detail}. Returning null.`];
|
|
6952
7503
|
if (hint !== void 0) parts.push(hint);
|
|
6953
7504
|
if (frame !== void 0) parts.push(frame);
|
|
@@ -7001,5 +7552,6 @@ exports.slimKindOf = slimKindOf;
|
|
|
7001
7552
|
exports.structuralSnapshot = structuralSnapshot;
|
|
7002
7553
|
exports.unset = unset;
|
|
7003
7554
|
exports.useAbstractForm = useAbstractForm;
|
|
7555
|
+
exports.useRegister = useRegister;
|
|
7004
7556
|
exports.useWizard = useWizard;
|
|
7005
|
-
//# sourceMappingURL=attaform.
|
|
7557
|
+
//# sourceMappingURL=attaform.CjMcwV7W.cjs.map
|