attaform 0.21.0 → 0.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +31 -28
- package/dist/index.d.mts +31 -28
- package/dist/index.d.ts +31 -28
- 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.BA3vRDos.cjs → attaform.B5LNzqQh.cjs} +349 -277
- package/dist/shared/attaform.B5LNzqQh.cjs.map +1 -0
- package/dist/shared/{attaform.PnqML3xW.cjs → attaform.BBDIKtKY.cjs} +13 -16
- package/dist/shared/attaform.BBDIKtKY.cjs.map +1 -0
- package/dist/shared/{attaform.CRsXyy-Y.d.ts → attaform.BCcrLApm.d.mts} +131 -64
- package/dist/shared/{attaform.BupwXkj_.mjs → attaform.BFWb6hDk.mjs} +29 -23
- package/dist/shared/attaform.BFWb6hDk.mjs.map +1 -0
- package/dist/shared/{attaform.7lzO9pdM.d.mts → attaform.BGf_J22U.d.ts} +131 -64
- package/dist/shared/{attaform.BnK_bfcb.mjs → attaform.BVeLgfEh.mjs} +14 -17
- package/dist/shared/attaform.BVeLgfEh.mjs.map +1 -0
- package/dist/shared/{attaform.BK1RE2ha.d.ts → attaform.BYgioWLF.d.ts} +2 -2
- package/dist/shared/{attaform.F8LMHHWV.d.cts → attaform.BkjJfMvJ.d.cts} +131 -64
- package/dist/shared/{attaform.BDIEq9qP.d.cts → attaform.BoY6RZUl.d.cts} +2 -2
- package/dist/shared/{attaform.CEf6wYfD.cjs → attaform.BwLp9KM7.cjs} +2 -2
- package/dist/shared/{attaform.CEf6wYfD.cjs.map → attaform.BwLp9KM7.cjs.map} +1 -1
- package/dist/shared/{attaform._rsCZy2j.cjs → attaform.BwrowMp2.cjs} +25 -45
- package/dist/shared/attaform.BwrowMp2.cjs.map +1 -0
- package/dist/shared/{attaform.ezb5Nh2t.mjs → attaform.C41gjp-a.mjs} +2 -2
- package/dist/shared/{attaform.ezb5Nh2t.mjs.map → attaform.C41gjp-a.mjs.map} +1 -1
- package/dist/shared/{attaform.BM6YD9kZ.cjs → attaform.CR6wGvNu.cjs} +29 -23
- package/dist/shared/attaform.CR6wGvNu.cjs.map +1 -0
- package/dist/shared/{attaform.DSqO6Db7.mjs → attaform.CTheKoTc.mjs} +705 -282
- package/dist/shared/attaform.CTheKoTc.mjs.map +1 -0
- package/dist/shared/{attaform.BzvOdiSI.cjs → attaform.CcnF1AKJ.cjs} +4 -4
- package/dist/shared/attaform.CcnF1AKJ.cjs.map +1 -0
- package/dist/shared/{attaform.BQ6drorq.d.mts → attaform.CnEl--PF.d.mts} +2 -2
- package/dist/shared/{attaform.CkjTapyq.mjs → attaform.CrD73S4m.mjs} +4 -4
- package/dist/shared/attaform.CrD73S4m.mjs.map +1 -0
- package/dist/shared/{attaform.BUszFoKq.cjs → attaform.D2ZuIOCf.cjs} +711 -287
- package/dist/shared/attaform.D2ZuIOCf.cjs.map +1 -0
- package/dist/shared/{attaform.r3PePkDR.mjs → attaform.D6GYGshL.mjs} +25 -45
- package/dist/shared/attaform.D6GYGshL.mjs.map +1 -0
- package/dist/shared/{attaform.Y_Mgg0Yp.mjs → attaform.DP-u7_tk.mjs} +348 -277
- package/dist/shared/attaform.DP-u7_tk.mjs.map +1 -0
- package/dist/shared/{attaform.B1nyO4ec.d.cts → attaform.ory-3WhV.d.cts} +395 -176
- package/dist/shared/{attaform.B1nyO4ec.d.mts → attaform.ory-3WhV.d.mts} +395 -176
- package/dist/shared/{attaform.B1nyO4ec.d.ts → attaform.ory-3WhV.d.ts} +395 -176
- 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 +77 -26
- package/dist/zod.d.mts +77 -26
- package/dist/zod.d.ts +77 -26
- package/dist/zod.mjs +5 -6
- package/dist/zod.mjs.map +1 -1
- package/package.json +3 -11
- package/dist/shared/attaform.BA3vRDos.cjs.map +0 -1
- package/dist/shared/attaform.BM6YD9kZ.cjs.map +0 -1
- package/dist/shared/attaform.BUszFoKq.cjs.map +0 -1
- package/dist/shared/attaform.BnK_bfcb.mjs.map +0 -1
- package/dist/shared/attaform.BupwXkj_.mjs.map +0 -1
- package/dist/shared/attaform.BzvOdiSI.cjs.map +0 -1
- package/dist/shared/attaform.CkjTapyq.mjs.map +0 -1
- package/dist/shared/attaform.DSqO6Db7.mjs.map +0 -1
- package/dist/shared/attaform.PnqML3xW.cjs.map +0 -1
- package/dist/shared/attaform.Y_Mgg0Yp.mjs.map +0 -1
- package/dist/shared/attaform._rsCZy2j.cjs.map +0 -1
- package/dist/shared/attaform.r3PePkDR.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,
|
|
2
|
-
import { _ as __DEV__,
|
|
1
|
+
import { computed, ref, watchEffect, getCurrentScope, onScopeDispose, shallowReadonly, readonly, toRaw, reactive, watch, markRaw, shallowRef, getCurrentInstance, onServerPrefetch, provide, useId, inject, onBeforeMount, onBeforeUpdate, onMounted, effectScope, nextTick } from 'vue';
|
|
2
|
+
import { _ as __DEV__, a as canonicalizePath, s as segmentsForPathKey, l as isPathPrefix, F as FORM_ERRORS_PATH_KEY, S as SubmitErrorHandlerError, t as toError, A as AnonPersistError, q as INTERACTIVE_TAG_NAMES, r as getOrAssignElementId, e as ROOT_PATH_KEY, R as ROOT_PATH, w as allowSensitivePersist, x as FORM_ERRORS_PATH, y as coerceToPathKey, z as isSensitivePath, B as createPersistOptInRegistry, d as InvalidUseFormConfigError, C as ensureAttaformInstalled, u as useRegistry, E as kFormContext, G as kFormInstanceId, h as ReservedFormKeyError, H as createIsSensitivePath, J as REGISTER_OWNER_MARKER, V as V_REGISTER_MARKER, k as kAttaformWizardActiveStepResolver, K as kAttaformAncestorWizard } from './attaform.DP-u7_tk.mjs';
|
|
3
3
|
|
|
4
4
|
function safeAssign(target, key, value) {
|
|
5
5
|
if (key === "__proto__") {
|
|
@@ -13,10 +13,14 @@ function safeAssign(target, key, value) {
|
|
|
13
13
|
}
|
|
14
14
|
target[key] = value;
|
|
15
15
|
}
|
|
16
|
+
function isShadowedKey(key) {
|
|
17
|
+
return key in Object.prototype;
|
|
18
|
+
}
|
|
16
19
|
function safeOwnRead(target, key) {
|
|
17
|
-
if (key
|
|
18
|
-
const desc = Object.getOwnPropertyDescriptor(target,
|
|
19
|
-
return
|
|
20
|
+
if (isShadowedKey(key)) {
|
|
21
|
+
const desc = Object.getOwnPropertyDescriptor(target, key);
|
|
22
|
+
if (desc === void 0) return void 0;
|
|
23
|
+
return "value" in desc ? desc.value : target[key];
|
|
20
24
|
}
|
|
21
25
|
return target[key];
|
|
22
26
|
}
|
|
@@ -35,6 +39,10 @@ function descendStep(value, segment) {
|
|
|
35
39
|
}
|
|
36
40
|
const record = value;
|
|
37
41
|
const key = typeof segment === "number" ? String(segment) : segment;
|
|
42
|
+
if (isShadowedKey(key)) {
|
|
43
|
+
if (!safeOwnHas(record, key)) return NOT_FOUND;
|
|
44
|
+
return safeOwnRead(record, key);
|
|
45
|
+
}
|
|
38
46
|
if (!(key in record)) return NOT_FOUND;
|
|
39
47
|
return record[key];
|
|
40
48
|
}
|
|
@@ -64,6 +72,7 @@ function hasAtPath(root, path) {
|
|
|
64
72
|
return typeof last === "number" && last >= 0 && last < current.length;
|
|
65
73
|
}
|
|
66
74
|
const key = typeof last === "number" ? String(last) : last;
|
|
75
|
+
if (isShadowedKey(key)) return safeOwnHas(current, key);
|
|
67
76
|
return key in current;
|
|
68
77
|
}
|
|
69
78
|
function isPlainRecord(value) {
|
|
@@ -151,68 +160,80 @@ function mergeStructuralImpl(schema, scratch, consumer, defaultValue) {
|
|
|
151
160
|
}
|
|
152
161
|
if (consumer === null) return null;
|
|
153
162
|
if (Array.isArray(consumer)) {
|
|
154
|
-
|
|
155
|
-
const isTuple = typeof shape === "number";
|
|
156
|
-
const targetLen = isTuple ? shape : consumer.length;
|
|
157
|
-
let cachedElementDefault;
|
|
158
|
-
let cachedElementDefaultRead = false;
|
|
159
|
-
let mutated = targetLen > consumer.length;
|
|
160
|
-
const out = consumer.slice();
|
|
161
|
-
while (out.length < targetLen) out.push(void 0);
|
|
162
|
-
for (let i = 0; i < targetLen; i++) {
|
|
163
|
-
scratch.push(i);
|
|
164
|
-
let elemDefault;
|
|
165
|
-
if (isTuple) {
|
|
166
|
-
elemDefault = schema.getDefaultAtPath(scratch);
|
|
167
|
-
} else {
|
|
168
|
-
if (!cachedElementDefaultRead) {
|
|
169
|
-
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
170
|
-
cachedElementDefaultRead = true;
|
|
171
|
-
}
|
|
172
|
-
elemDefault = cachedElementDefault;
|
|
173
|
-
}
|
|
174
|
-
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
175
|
-
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
176
|
-
scratch.pop();
|
|
177
|
-
if (merged !== consumerElem) {
|
|
178
|
-
out[i] = merged;
|
|
179
|
-
mutated = true;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return mutated ? out : consumer;
|
|
163
|
+
return mergeStructuralArray(schema, scratch, consumer);
|
|
183
164
|
}
|
|
184
165
|
if (isPlainRecord(consumer)) {
|
|
185
166
|
if (!isPlainRecord(defaultValue)) {
|
|
186
167
|
return consumer;
|
|
187
168
|
}
|
|
188
|
-
let mutated = false;
|
|
189
169
|
const out = { ...consumer };
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
170
|
+
const filledAny = fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out);
|
|
171
|
+
const recursedAny = recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out);
|
|
172
|
+
return filledAny || recursedAny ? out : consumer;
|
|
173
|
+
}
|
|
174
|
+
return consumer;
|
|
175
|
+
}
|
|
176
|
+
function mergeStructuralArray(schema, scratch, consumer) {
|
|
177
|
+
const shape = resolveArrayShape(schema, scratch);
|
|
178
|
+
const isTuple = typeof shape === "number";
|
|
179
|
+
const targetLen = isTuple ? shape : consumer.length;
|
|
180
|
+
let cachedElementDefault;
|
|
181
|
+
let cachedElementDefaultRead = false;
|
|
182
|
+
let mutated = targetLen > consumer.length;
|
|
183
|
+
const out = consumer.slice();
|
|
184
|
+
while (out.length < targetLen) out.push(void 0);
|
|
185
|
+
for (let i = 0; i < targetLen; i++) {
|
|
186
|
+
scratch.push(i);
|
|
187
|
+
let elemDefault;
|
|
188
|
+
if (isTuple) {
|
|
189
|
+
elemDefault = schema.getDefaultAtPath(scratch);
|
|
190
|
+
} else {
|
|
191
|
+
if (!cachedElementDefaultRead) {
|
|
192
|
+
cachedElementDefault = schema.getDefaultAtPath(scratch);
|
|
193
|
+
cachedElementDefaultRead = true;
|
|
200
194
|
}
|
|
195
|
+
elemDefault = cachedElementDefault;
|
|
201
196
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
197
|
+
const consumerElem = i < consumer.length ? consumer[i] : void 0;
|
|
198
|
+
const merged = mergeStructuralImpl(schema, scratch, consumerElem, elemDefault);
|
|
199
|
+
scratch.pop();
|
|
200
|
+
if (merged !== consumerElem) {
|
|
201
|
+
out[i] = merged;
|
|
202
|
+
mutated = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return mutated ? out : consumer;
|
|
206
|
+
}
|
|
207
|
+
function fillMissingKeysFromDefault(schema, scratch, consumer, defaultValue, out) {
|
|
208
|
+
let mutated = false;
|
|
209
|
+
for (const key of Object.keys(defaultValue)) {
|
|
210
|
+
if (!safeOwnHas(consumer, key)) {
|
|
211
|
+
const defAtKey = safeOwnRead(defaultValue, key);
|
|
205
212
|
scratch.push(key);
|
|
206
|
-
const
|
|
213
|
+
const filled = mergeStructuralImpl(schema, scratch, void 0, defAtKey);
|
|
207
214
|
scratch.pop();
|
|
208
|
-
if (
|
|
209
|
-
safeAssign(out, key,
|
|
215
|
+
if (filled !== void 0) {
|
|
216
|
+
safeAssign(out, key, filled);
|
|
210
217
|
mutated = true;
|
|
211
218
|
}
|
|
212
219
|
}
|
|
213
|
-
return mutated ? out : consumer;
|
|
214
220
|
}
|
|
215
|
-
return
|
|
221
|
+
return mutated;
|
|
222
|
+
}
|
|
223
|
+
function recurseIntoConsumerKeys(schema, scratch, consumer, defaultValue, out) {
|
|
224
|
+
let mutated = false;
|
|
225
|
+
for (const key of Object.keys(consumer)) {
|
|
226
|
+
const cVal = safeOwnRead(consumer, key);
|
|
227
|
+
if (cVal === void 0) continue;
|
|
228
|
+
scratch.push(key);
|
|
229
|
+
const merged = mergeStructuralImpl(schema, scratch, cVal, safeOwnRead(defaultValue, key));
|
|
230
|
+
scratch.pop();
|
|
231
|
+
if (merged !== cVal) {
|
|
232
|
+
safeAssign(out, key, merged);
|
|
233
|
+
mutated = true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return mutated;
|
|
216
237
|
}
|
|
217
238
|
function setAtPathWithSchemaFill(root, schema, fullPath, value) {
|
|
218
239
|
if (fullPath.length === 0) return value;
|
|
@@ -295,55 +316,27 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
295
316
|
const oldIsDescendable = isDescendable(oldValue);
|
|
296
317
|
const newIsDescendable = isDescendable(newValue);
|
|
297
318
|
if (oldValue === void 0 && newIsDescendable) {
|
|
298
|
-
|
|
299
|
-
for (let i = 0; i < newValue.length; i++) {
|
|
300
|
-
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
301
|
-
}
|
|
302
|
-
} else {
|
|
303
|
-
const rec = newValue;
|
|
304
|
-
for (const k of Object.keys(rec)) {
|
|
305
|
-
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
319
|
+
walkNewDescendable(newValue, prefix, visit);
|
|
308
320
|
return;
|
|
309
321
|
}
|
|
310
322
|
if (oldIsDescendable && newValue === void 0) {
|
|
311
|
-
|
|
312
|
-
for (let i = 0; i < oldValue.length; i++) {
|
|
313
|
-
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
314
|
-
}
|
|
315
|
-
} else {
|
|
316
|
-
const rec = oldValue;
|
|
317
|
-
for (const k of Object.keys(rec)) {
|
|
318
|
-
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
323
|
+
walkOldDescendable(oldValue, prefix, visit);
|
|
321
324
|
return;
|
|
322
325
|
}
|
|
323
326
|
if (oldIsDescendable && newIsDescendable) {
|
|
324
327
|
const oldIsArray = Array.isArray(oldValue);
|
|
325
328
|
const newIsArray = Array.isArray(newValue);
|
|
326
329
|
if (oldIsArray && newIsArray) {
|
|
327
|
-
|
|
328
|
-
const newArr = newValue;
|
|
329
|
-
const max = Math.max(oldArr.length, newArr.length);
|
|
330
|
-
for (let i = 0; i < max; i++) {
|
|
331
|
-
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
332
|
-
}
|
|
330
|
+
diffArraysLockstep(oldValue, newValue, prefix, visit);
|
|
333
331
|
return;
|
|
334
332
|
}
|
|
335
333
|
if (!oldIsArray && !newIsArray) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
for (const k of Object.keys(newRec)) {
|
|
344
|
-
if (seen.has(k)) continue;
|
|
345
|
-
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
346
|
-
}
|
|
334
|
+
diffObjectsLockstep(
|
|
335
|
+
oldValue,
|
|
336
|
+
newValue,
|
|
337
|
+
prefix,
|
|
338
|
+
visit
|
|
339
|
+
);
|
|
347
340
|
return;
|
|
348
341
|
}
|
|
349
342
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
@@ -367,6 +360,47 @@ function diffAndApply(oldValue, newValue, prefix, visit) {
|
|
|
367
360
|
}
|
|
368
361
|
visit({ kind: "changed", path: prefix, oldValue, newValue });
|
|
369
362
|
}
|
|
363
|
+
function walkNewDescendable(newValue, prefix, visit) {
|
|
364
|
+
if (Array.isArray(newValue)) {
|
|
365
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
366
|
+
diffAndApply(void 0, newValue[i], appendSegment(prefix, i), visit);
|
|
367
|
+
}
|
|
368
|
+
} else {
|
|
369
|
+
const rec = newValue;
|
|
370
|
+
for (const k of Object.keys(rec)) {
|
|
371
|
+
diffAndApply(void 0, rec[k], appendSegment(prefix, k), visit);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function walkOldDescendable(oldValue, prefix, visit) {
|
|
376
|
+
if (Array.isArray(oldValue)) {
|
|
377
|
+
for (let i = 0; i < oldValue.length; i++) {
|
|
378
|
+
diffAndApply(oldValue[i], void 0, appendSegment(prefix, i), visit);
|
|
379
|
+
}
|
|
380
|
+
} else {
|
|
381
|
+
const rec = oldValue;
|
|
382
|
+
for (const k of Object.keys(rec)) {
|
|
383
|
+
diffAndApply(rec[k], void 0, appendSegment(prefix, k), visit);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function diffArraysLockstep(oldArr, newArr, prefix, visit) {
|
|
388
|
+
const max = Math.max(oldArr.length, newArr.length);
|
|
389
|
+
for (let i = 0; i < max; i++) {
|
|
390
|
+
diffAndApply(oldArr[i], newArr[i], appendSegment(prefix, i), visit);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function diffObjectsLockstep(oldRec, newRec, prefix, visit) {
|
|
394
|
+
const seen = /* @__PURE__ */ new Set();
|
|
395
|
+
for (const k of Object.keys(oldRec)) {
|
|
396
|
+
seen.add(k);
|
|
397
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
398
|
+
}
|
|
399
|
+
for (const k of Object.keys(newRec)) {
|
|
400
|
+
if (seen.has(k)) continue;
|
|
401
|
+
diffAndApply(oldRec[k], newRec[k], appendSegment(prefix, k), visit);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
370
404
|
function applyChangedKeys(target, source) {
|
|
371
405
|
if (!isDescendable(target) || !isDescendable(source)) return false;
|
|
372
406
|
const targetIsArray = Array.isArray(target);
|
|
@@ -470,7 +504,12 @@ function computeVerdict(field, formMeta) {
|
|
|
470
504
|
if (field.valid === true && field.blank !== true && field.dirty === true) return "success";
|
|
471
505
|
return "idle";
|
|
472
506
|
}
|
|
473
|
-
|
|
507
|
+
function earliestNonNull(a, b) {
|
|
508
|
+
if (a === null) return b;
|
|
509
|
+
if (b === null) return a;
|
|
510
|
+
return a < b ? a : b;
|
|
511
|
+
}
|
|
512
|
+
const DEFAULT_TIMINGS = { showDelay: 120, minVisible: 120 };
|
|
474
513
|
const FOCUS_OUT_GRACE = 16;
|
|
475
514
|
const defaultFamily = /* @__PURE__ */ new WeakSet();
|
|
476
515
|
function isDefaultDisplayState(fn) {
|
|
@@ -480,10 +519,11 @@ function makeDefaultDisplayState({
|
|
|
480
519
|
showDelay,
|
|
481
520
|
minVisible
|
|
482
521
|
}) {
|
|
483
|
-
const reducer = (prev, { field, formMeta, validatingSince, now }) => {
|
|
522
|
+
const reducer = (prev, { field, formMeta, validatingSince, transformingSince, now }) => {
|
|
484
523
|
const verdict = computeVerdict(field, formMeta);
|
|
485
524
|
if (!isGateOpen(field, formMeta)) return { display: verdict };
|
|
486
|
-
|
|
525
|
+
const inFlightSince = earliestNonNull(validatingSince, transformingSince);
|
|
526
|
+
if (inFlightSince === null) {
|
|
487
527
|
if (prev.display === "pending") {
|
|
488
528
|
const shownAt = prev.pendingShownAt ?? now;
|
|
489
529
|
if (now < shownAt + minVisible)
|
|
@@ -494,8 +534,8 @@ function makeDefaultDisplayState({
|
|
|
494
534
|
if (prev.display === "pending")
|
|
495
535
|
return { display: "pending", pendingShownAt: prev.pendingShownAt ?? now };
|
|
496
536
|
const window = field.focused === false ? Math.min(showDelay, FOCUS_OUT_GRACE) : showDelay;
|
|
497
|
-
if (now -
|
|
498
|
-
return { display: prev.display, reviewAt:
|
|
537
|
+
if (now - inFlightSince < window) {
|
|
538
|
+
return { display: prev.display, reviewAt: inFlightSince + window };
|
|
499
539
|
}
|
|
500
540
|
return { display: "pending", pendingShownAt: now, reviewAt: now + minVisible };
|
|
501
541
|
};
|
|
@@ -608,6 +648,12 @@ function buildFieldStateAccessor(state, formInstanceId, getFormMetaBase, options
|
|
|
608
648
|
return c;
|
|
609
649
|
};
|
|
610
650
|
}
|
|
651
|
+
function resolveFieldMetaAndLabel(state, segments) {
|
|
652
|
+
const resolved = state.schema.getFieldMetaAtPath ? state.schema.getFieldMetaAtPath(segments) : EMPTY_RESOLVED_FIELD_META;
|
|
653
|
+
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
654
|
+
const label = resolved.label || humanize(lastSegment);
|
|
655
|
+
return { resolved, label };
|
|
656
|
+
}
|
|
611
657
|
function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
612
658
|
const record = state.fields.get(key);
|
|
613
659
|
const value = state.getValueAtPath(segments);
|
|
@@ -621,15 +667,15 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
621
667
|
if (blankForKey !== void 0) errors.push(...blankForKey);
|
|
622
668
|
if (userForKey !== void 0) errors.push(...userForKey);
|
|
623
669
|
const validating = (state.fieldValidationCounts.get(key) ?? 0) > 0;
|
|
670
|
+
const transforming = (state.fieldTransformCounts.get(key) ?? 0) > 0;
|
|
671
|
+
const transformError = state.transformErrors.get(key) ?? null;
|
|
624
672
|
const gated = state.pathHasAsyncValidation(segments) && !state.firstValidationDone.value;
|
|
625
673
|
const isOrphan = segments.length > 0 && !hasAtPath(state.form.value, segments) && isUnderStubAncestor(state, segments);
|
|
626
674
|
const valid = !gated && errors.length === 0 && !validating && !isOrphan;
|
|
627
675
|
const elementRecord = state.elements.get(key);
|
|
628
676
|
const elementsArr = elementRecord ? Object.freeze([...elementRecord.elements]) : EMPTY_ELEMENTS;
|
|
629
677
|
const firstElement = elementsArr[0] ?? null;
|
|
630
|
-
const resolved = state
|
|
631
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
632
|
-
const label = resolved.label || humanize(lastSegment);
|
|
678
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
633
679
|
return {
|
|
634
680
|
value,
|
|
635
681
|
original,
|
|
@@ -647,6 +693,9 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
647
693
|
errors,
|
|
648
694
|
validating,
|
|
649
695
|
valid,
|
|
696
|
+
transforming,
|
|
697
|
+
busy: transforming || validating,
|
|
698
|
+
transformError,
|
|
650
699
|
path: segments,
|
|
651
700
|
...computeFieldIdentity(formInstanceId, state.formKey, key),
|
|
652
701
|
key: state.arrayElementKey(segments),
|
|
@@ -660,12 +709,14 @@ function buildLeafFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
660
709
|
function buildLeafFieldState(state, segments, key, formInstanceId, getFormMetaBase, getDisplayState) {
|
|
661
710
|
const base = buildLeafFieldStateBase(state, segments, key, formInstanceId);
|
|
662
711
|
const validatingSince = state.fieldValidatingSince.get(key) ?? null;
|
|
712
|
+
const transformingSince = state.fieldTransformingSince.get(key) ?? null;
|
|
663
713
|
return decorateWithDerivedProps(
|
|
664
714
|
base,
|
|
665
715
|
state,
|
|
666
716
|
getFormMetaBase,
|
|
667
717
|
key,
|
|
668
718
|
validatingSince,
|
|
719
|
+
transformingSince,
|
|
669
720
|
false,
|
|
670
721
|
// revealedDescendantError: leaves have no descendants
|
|
671
722
|
false,
|
|
@@ -688,6 +739,8 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
688
739
|
let connected = false;
|
|
689
740
|
let validating = false;
|
|
690
741
|
let validatingSince = null;
|
|
742
|
+
let transforming = false;
|
|
743
|
+
let transformingSince = null;
|
|
691
744
|
let updatedAt = null;
|
|
692
745
|
let asyncPending = false;
|
|
693
746
|
const submissionAttempts = state.submissionAttempts.value;
|
|
@@ -718,6 +771,13 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
718
771
|
if (leafGateOpen && since !== void 0 && (validatingSince === null || since < validatingSince))
|
|
719
772
|
validatingSince = since;
|
|
720
773
|
}
|
|
774
|
+
if ((state.fieldTransformCounts.get(leafKey) ?? 0) > 0) {
|
|
775
|
+
transforming = true;
|
|
776
|
+
const leafGateOpen = submissionAttempts > 0 || leafRecord?.blurredAfterInteraction === true;
|
|
777
|
+
const since = state.fieldTransformingSince.get(leafKey);
|
|
778
|
+
if (leafGateOpen && since !== void 0 && (transformingSince === null || since < transformingSince))
|
|
779
|
+
transformingSince = since;
|
|
780
|
+
}
|
|
721
781
|
if (state.pathHasAsyncValidationByKey(leafKey, entry.segments)) asyncPending = true;
|
|
722
782
|
const ts = leafRecord?.updatedAt;
|
|
723
783
|
if (ts !== void 0 && ts !== null) {
|
|
@@ -737,11 +797,22 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
737
797
|
return blurredLeafSegments.some((s) => isPathPrefix(ePath, s));
|
|
738
798
|
});
|
|
739
799
|
if (!asyncPending && state.pathHasAsyncValidation(segments)) asyncPending = true;
|
|
800
|
+
if ((state.fieldValidationCounts.get(key) ?? 0) > 0) {
|
|
801
|
+
validating = true;
|
|
802
|
+
const since = state.fieldValidatingSince.get(key);
|
|
803
|
+
if (since !== void 0 && (validatingSince === null || since < validatingSince))
|
|
804
|
+
validatingSince = since;
|
|
805
|
+
}
|
|
806
|
+
if ((state.fieldTransformCounts.get(key) ?? 0) > 0) {
|
|
807
|
+
transforming = true;
|
|
808
|
+
const since = state.fieldTransformingSince.get(key);
|
|
809
|
+
if (since !== void 0 && (transformingSince === null || since < transformingSince))
|
|
810
|
+
transformingSince = since;
|
|
811
|
+
}
|
|
812
|
+
const ownTransformError = state.transformErrors.get(key) ?? null;
|
|
740
813
|
const gated = asyncPending && !state.firstValidationDone.value;
|
|
741
814
|
const valid = !gated && errors.length === 0 && !validating;
|
|
742
|
-
const resolved = state
|
|
743
|
-
const lastSegment = segments.length === 0 ? "" : segments[segments.length - 1] ?? "";
|
|
744
|
-
const label = resolved.label || humanize(lastSegment);
|
|
815
|
+
const { resolved, label } = resolveFieldMetaAndLabel(state, segments);
|
|
745
816
|
return {
|
|
746
817
|
base: {
|
|
747
818
|
value,
|
|
@@ -760,6 +831,12 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
760
831
|
errors,
|
|
761
832
|
validating,
|
|
762
833
|
valid,
|
|
834
|
+
transforming,
|
|
835
|
+
busy: transforming || validating,
|
|
836
|
+
// A container surfaces its OWN transform failure (a transform registered
|
|
837
|
+
// on the container path, e.g. a file normalizer) but never rolls up a
|
|
838
|
+
// descendant leaf's failure — that stays a per-field channel.
|
|
839
|
+
transformError: ownTransformError,
|
|
763
840
|
path: segments,
|
|
764
841
|
...computeFieldIdentity(formInstanceId, state.formKey, key),
|
|
765
842
|
key: state.arrayElementKey(segments),
|
|
@@ -770,28 +847,25 @@ function buildContainerFieldStateBase(state, segments, key, formInstanceId) {
|
|
|
770
847
|
meta: resolved.meta
|
|
771
848
|
},
|
|
772
849
|
validatingSince,
|
|
850
|
+
transformingSince,
|
|
773
851
|
revealedDescendantError
|
|
774
852
|
};
|
|
775
853
|
}
|
|
776
854
|
function buildContainerFieldState(state, segments, key, formInstanceId, getFormMetaBase, getDisplayState) {
|
|
777
|
-
const { base, validatingSince, revealedDescendantError } = buildContainerFieldStateBase(
|
|
778
|
-
state,
|
|
779
|
-
segments,
|
|
780
|
-
key,
|
|
781
|
-
formInstanceId
|
|
782
|
-
);
|
|
855
|
+
const { base, validatingSince, transformingSince, revealedDescendantError } = buildContainerFieldStateBase(state, segments, key, formInstanceId);
|
|
783
856
|
return decorateWithDerivedProps(
|
|
784
857
|
base,
|
|
785
858
|
state,
|
|
786
859
|
getFormMetaBase,
|
|
787
860
|
key,
|
|
788
861
|
validatingSince,
|
|
862
|
+
transformingSince,
|
|
789
863
|
revealedDescendantError,
|
|
790
864
|
segments.length === 0,
|
|
791
865
|
getDisplayState
|
|
792
866
|
);
|
|
793
867
|
}
|
|
794
|
-
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, revealedDescendantError, isRoot, getDisplayState) {
|
|
868
|
+
function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingSince, transformingSince, revealedDescendantError, isRoot, getDisplayState) {
|
|
795
869
|
const firstError = base.errors[0];
|
|
796
870
|
const predicate = getDisplayState ?? state.getDisplayState;
|
|
797
871
|
const formMeta = getFormMetaBase();
|
|
@@ -799,6 +873,7 @@ function decorateWithDerivedProps(base, state, getFormMetaBase, key, validatingS
|
|
|
799
873
|
field: base,
|
|
800
874
|
formMeta,
|
|
801
875
|
validatingSince,
|
|
876
|
+
transformingSince,
|
|
802
877
|
// The engine's clock. Frozen to 0 under SSR (no clock, nothing in
|
|
803
878
|
// flight) so the reducer returns the plain verdict and hydration matches.
|
|
804
879
|
now: state.ssr ? 0 : Date.now()
|
|
@@ -865,6 +940,15 @@ function liveKeysAtPath(state, segments) {
|
|
|
865
940
|
if (typeof value === "object") return Object.keys(value);
|
|
866
941
|
return [];
|
|
867
942
|
}
|
|
943
|
+
function liveContainerHasKey(state, segments, key) {
|
|
944
|
+
const value = getAtPath(state.form.value, segments);
|
|
945
|
+
if (value === null || value === void 0 || typeof value !== "object") return false;
|
|
946
|
+
if (Array.isArray(value)) {
|
|
947
|
+
const index = Number(key);
|
|
948
|
+
return Number.isInteger(index) && index >= 0 && index < value.length && String(index) === key;
|
|
949
|
+
}
|
|
950
|
+
return Object.hasOwn(value, key);
|
|
951
|
+
}
|
|
868
952
|
function isArrayPath(state, segments) {
|
|
869
953
|
if (segments.length === 0) return false;
|
|
870
954
|
return Array.isArray(getAtPath(state.form.value, segments));
|
|
@@ -893,6 +977,21 @@ const INTEGER_SEGMENT = /^(?:0|[1-9]\d*)$/;
|
|
|
893
977
|
function keyToSegment(key) {
|
|
894
978
|
return INTEGER_SEGMENT.test(key) ? Number(key) : key;
|
|
895
979
|
}
|
|
980
|
+
function callableInvokeShim(method, surface, getDescent) {
|
|
981
|
+
const fnMethod = Reflect.get(Function.prototype, method);
|
|
982
|
+
return new Proxy((() => {
|
|
983
|
+
}), {
|
|
984
|
+
apply: (_target, _thisArg, args) => Reflect.apply(fnMethod, surface, args),
|
|
985
|
+
get: (_target, key) => Reflect.get(getDescent(), key),
|
|
986
|
+
has: (_target, key) => Reflect.has(getDescent(), key),
|
|
987
|
+
ownKeys: () => Reflect.ownKeys(getDescent()),
|
|
988
|
+
getOwnPropertyDescriptor: (_target, key) => {
|
|
989
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(getDescent(), key);
|
|
990
|
+
if (descriptor !== void 0) descriptor.configurable = true;
|
|
991
|
+
return descriptor;
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
}
|
|
896
995
|
function buildSurfaceProxy(opts) {
|
|
897
996
|
const containerCache = /* @__PURE__ */ new Map();
|
|
898
997
|
const leafViewCache = /* @__PURE__ */ new Map();
|
|
@@ -919,6 +1018,8 @@ function buildSurfaceProxy(opts) {
|
|
|
919
1018
|
const cacheKey = `${JSON.stringify(segments)}+${isArrayLike ? "A" : "O"}`;
|
|
920
1019
|
const existing = containerCache.get(cacheKey);
|
|
921
1020
|
if (existing !== void 0) return existing;
|
|
1021
|
+
const isFixedObject = opts.schema.isFixedObjectAtPath(segments);
|
|
1022
|
+
const containerHasKey = (k) => opts.containerHasOwnKey !== void 0 ? opts.containerHasOwnKey(segments, k) : opts.containerOwnKeys?.(segments).includes(k) === true;
|
|
922
1023
|
const snapshotContainer = () => opts.materializeContainer === void 0 ? {} : opts.materializeContainer(segments);
|
|
923
1024
|
const {
|
|
924
1025
|
toString: containerToString,
|
|
@@ -926,8 +1027,9 @@ function buildSurfaceProxy(opts) {
|
|
|
926
1027
|
toJSON: containerToJSON,
|
|
927
1028
|
toPrimitive: containerToPrimitive
|
|
928
1029
|
} = makeReadonlyCoercion(snapshotContainer);
|
|
929
|
-
const
|
|
930
|
-
|
|
1030
|
+
const isRoot = segments.length === 0;
|
|
1031
|
+
const target = isRoot ? (() => {
|
|
1032
|
+
}) : isArrayLike ? [] : {};
|
|
931
1033
|
const proxy = new Proxy(target, {
|
|
932
1034
|
apply(_, __, args) {
|
|
933
1035
|
const arg = args[0];
|
|
@@ -958,7 +1060,16 @@ function buildSurfaceProxy(opts) {
|
|
|
958
1060
|
return key === "toString" ? containerToString : containerValueOf;
|
|
959
1061
|
}
|
|
960
1062
|
}
|
|
961
|
-
|
|
1063
|
+
if (key === "hasOwnProperty" && !schemaHasPath(childSegs)) {
|
|
1064
|
+
return Object.prototype.hasOwnProperty;
|
|
1065
|
+
}
|
|
1066
|
+
if (isRoot && (key === "call" || key === "apply" || key === "bind")) {
|
|
1067
|
+
return callableInvokeShim(key, proxy, () => descendOrTerminate(childSegs));
|
|
1068
|
+
}
|
|
1069
|
+
if (opts.isTerminalAt?.(childSegs) === true || isFixedObject && schemaHasPath(childSegs) || containerHasKey(key)) {
|
|
1070
|
+
return descendOrTerminate(childSegs);
|
|
1071
|
+
}
|
|
1072
|
+
return void 0;
|
|
962
1073
|
},
|
|
963
1074
|
has(_, key) {
|
|
964
1075
|
if (typeof key === "symbol") return Reflect.has(target, key);
|
|
@@ -1043,15 +1154,8 @@ function buildSurfaceProxy(opts) {
|
|
|
1043
1154
|
toJSON: leafToJSONHandler,
|
|
1044
1155
|
toPrimitive: leafToPrimitive
|
|
1045
1156
|
} = makeReadonlyCoercion(snapshotLeaf);
|
|
1046
|
-
const target =
|
|
1047
|
-
});
|
|
1157
|
+
const target = {};
|
|
1048
1158
|
const proxy = new Proxy(target, {
|
|
1049
|
-
apply(_, __, args) {
|
|
1050
|
-
const arg = args[0];
|
|
1051
|
-
if (arg === void 0) return opts.resolveCallTarget(segments);
|
|
1052
|
-
const { segments: argSegs } = canonicalizePath(arg);
|
|
1053
|
-
return opts.resolveCallTarget(argSegs);
|
|
1054
|
-
},
|
|
1055
1159
|
get(_, key) {
|
|
1056
1160
|
if (typeof key === "symbol") {
|
|
1057
1161
|
if (key === Symbol.toPrimitive) return leafToPrimitive;
|
|
@@ -1061,6 +1165,9 @@ function buildSurfaceProxy(opts) {
|
|
|
1061
1165
|
if (key === "toString") return leafToString;
|
|
1062
1166
|
if (key === "valueOf") return leafValueOf;
|
|
1063
1167
|
if (key === "toJSON") return leafToJSONHandler;
|
|
1168
|
+
if (key === "hasOwnProperty" && !schemaHasPath([...segments, keyToSegment(key)])) {
|
|
1169
|
+
return Object.prototype.hasOwnProperty;
|
|
1170
|
+
}
|
|
1064
1171
|
if (leafKeys.has(key)) {
|
|
1065
1172
|
const leaf = opts.resolveLeaf(segments);
|
|
1066
1173
|
return readLeafKey(leaf, key);
|
|
@@ -1073,8 +1180,8 @@ function buildSurfaceProxy(opts) {
|
|
|
1073
1180
|
return true;
|
|
1074
1181
|
},
|
|
1075
1182
|
// Iteration: leaf-views expose the leaf-key set so
|
|
1076
|
-
// `
|
|
1077
|
-
//
|
|
1183
|
+
// `Object.keys(form.fields.email)` / spread enumerate the
|
|
1184
|
+
// FieldState props. (`JSON.stringify` routes through `toJSON` above.)
|
|
1078
1185
|
ownKeys: () => Array.from(leafKeys),
|
|
1079
1186
|
getOwnPropertyDescriptor(_, key) {
|
|
1080
1187
|
if (typeof key !== "string") return void 0;
|
|
@@ -1183,6 +1290,12 @@ function buildErrorsProxy(state) {
|
|
|
1183
1290
|
// library-produced verdicts (schema + derived-blank) at unreachable
|
|
1184
1291
|
// paths stay hidden; user-supplied errors are unconditional.
|
|
1185
1292
|
containerOwnKeys: (segments) => errorAwareContainerKeys(state, segments),
|
|
1293
|
+
// Fast path: a key the live form data holds short-circuits before the
|
|
1294
|
+
// O(n) error-store scan, so iterating `form.errors.<array>` over live
|
|
1295
|
+
// indices stays linear. The scan still runs for a key with no live
|
|
1296
|
+
// home — a server error at a non-schema key (`form.errors.ghost`) —
|
|
1297
|
+
// so it keeps surfacing while a genuinely-absent key reads undefined.
|
|
1298
|
+
containerHasOwnKey: (segments, key) => liveContainerHasKey(state, segments, key) || errorAwareContainerKeys(state, segments).includes(key),
|
|
1186
1299
|
isArrayContainer: (segments) => isArrayPath(state, segments)
|
|
1187
1300
|
});
|
|
1188
1301
|
}
|
|
@@ -1356,6 +1469,9 @@ const FIELD_STATE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1356
1469
|
"errors",
|
|
1357
1470
|
"validating",
|
|
1358
1471
|
"valid",
|
|
1472
|
+
"transforming",
|
|
1473
|
+
"busy",
|
|
1474
|
+
"transformError",
|
|
1359
1475
|
"displayState",
|
|
1360
1476
|
"showErrors",
|
|
1361
1477
|
"showPending",
|
|
@@ -1458,33 +1574,41 @@ function buildFieldStateProxy(state, formInstanceId, getFormMetaBase, options) {
|
|
|
1458
1574
|
terminalCache.set(cacheKey, proxy);
|
|
1459
1575
|
return proxy;
|
|
1460
1576
|
}
|
|
1577
|
+
const surfaceSchema = state.schema;
|
|
1461
1578
|
return buildSurfaceProxy({
|
|
1462
|
-
schema:
|
|
1579
|
+
schema: surfaceSchema,
|
|
1463
1580
|
resolveLeaf: (path) => getFieldStateAt(path),
|
|
1464
1581
|
leafKeys: FIELD_STATE_KEYS,
|
|
1465
1582
|
readLeafKey: (computed, key) => computed.value[key],
|
|
1466
1583
|
materializeContainer: (segments) => materializeFields(state, segments, snapshotFieldStateAt),
|
|
1467
|
-
|
|
1584
|
+
// `form.fields(path)` resolves a FieldState for any path the SCHEMA
|
|
1585
|
+
// declares — a leaf, a container, an inactive discriminated-union
|
|
1586
|
+
// variant key, or an out-of-bounds array index (the element schema
|
|
1587
|
+
// admits any index). A path the schema doesn't have is a typo, not a
|
|
1588
|
+
// field, so it reads `undefined` rather than a phantom stub. The
|
|
1589
|
+
// empty path (`form.fields()`) is the root object, always valid.
|
|
1590
|
+
resolveCallTarget: (path) => surfaceSchema.getSlimPrimitiveTypesAtPath(path).size > 0 ? fieldStateTerminalAt(path) : void 0,
|
|
1468
1591
|
containerOwnKeys: (segments) => liveKeysAtPath(state, segments),
|
|
1592
|
+
containerHasOwnKey: (segments, key) => liveContainerHasKey(state, segments, key),
|
|
1469
1593
|
isArrayContainer: (segments) => isArrayPath(state, segments)
|
|
1470
1594
|
});
|
|
1471
1595
|
}
|
|
1472
1596
|
function materializeFields(state, containerSegments, snapshotFieldStateAt) {
|
|
1473
1597
|
const liveValue = getAtPath(state.form.value, containerSegments);
|
|
1474
|
-
return walk$
|
|
1598
|
+
return walk$1(liveValue, containerSegments, state.schema, snapshotFieldStateAt);
|
|
1475
1599
|
}
|
|
1476
|
-
function walk$
|
|
1600
|
+
function walk$1(value, basePath, schema, snapshotFieldStateAt) {
|
|
1477
1601
|
if (schema.isLeafAtPath(basePath)) return snapshotFieldStateAt(basePath);
|
|
1478
1602
|
if (value === null || value === void 0) return value;
|
|
1479
1603
|
if (typeof value !== "object") {
|
|
1480
1604
|
return value;
|
|
1481
1605
|
}
|
|
1482
1606
|
if (Array.isArray(value)) {
|
|
1483
|
-
return value.map((_, i) => walk$
|
|
1607
|
+
return value.map((_, i) => walk$1(value[i], [...basePath, i], schema, snapshotFieldStateAt));
|
|
1484
1608
|
}
|
|
1485
1609
|
const result = {};
|
|
1486
1610
|
for (const key of Object.keys(value)) {
|
|
1487
|
-
result[key] = walk$
|
|
1611
|
+
result[key] = walk$1(
|
|
1488
1612
|
value[key],
|
|
1489
1613
|
[...basePath, key],
|
|
1490
1614
|
schema,
|
|
@@ -1568,47 +1692,42 @@ function mergeDeep(target, source, path, schema) {
|
|
|
1568
1692
|
if (!isPlainRecord(source)) return source;
|
|
1569
1693
|
if (schema !== void 0) {
|
|
1570
1694
|
const du = schema.getUnionDiscriminatorAtPath(path);
|
|
1571
|
-
if (du !== void 0)
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
out2,
|
|
1585
|
-
key,
|
|
1586
|
-
mergeDeep(
|
|
1587
|
-
safeOwnRead(out2, key),
|
|
1588
|
-
safeOwnRead(sourceRecord, key),
|
|
1589
|
-
[...path, key],
|
|
1590
|
-
schema
|
|
1591
|
-
)
|
|
1592
|
-
);
|
|
1593
|
-
}
|
|
1594
|
-
return out2;
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
return {};
|
|
1695
|
+
if (du !== void 0) return mergeDuAwareKeys(source, path, schema, du);
|
|
1696
|
+
}
|
|
1697
|
+
return mergeObjectKeys(target, source, path, schema);
|
|
1698
|
+
}
|
|
1699
|
+
function mergeDuAwareKeys(source, path, schema, du) {
|
|
1700
|
+
const sourceDisc = source[du.discriminatorKey];
|
|
1701
|
+
if (sourceDisc !== void 0 && !du.isVariantSelected(sourceDisc)) {
|
|
1702
|
+
return { [du.discriminatorKey]: sourceDisc };
|
|
1703
|
+
}
|
|
1704
|
+
if (sourceDisc !== void 0) {
|
|
1705
|
+
const variantDefault = du.getVariantDefault(sourceDisc);
|
|
1706
|
+
if (isPlainRecord(variantDefault)) {
|
|
1707
|
+
return mergeVariantKeys(source, variantDefault, path, schema, du);
|
|
1598
1708
|
}
|
|
1599
1709
|
}
|
|
1600
|
-
|
|
1601
|
-
|
|
1710
|
+
return {};
|
|
1711
|
+
}
|
|
1712
|
+
function mergeVariantKeys(source, variantDefault, path, schema, du) {
|
|
1713
|
+
const out = { ...variantDefault };
|
|
1602
1714
|
for (const key of Object.keys(source)) {
|
|
1715
|
+
if (!safeOwnHas(variantDefault, key) && key !== du.discriminatorKey) continue;
|
|
1603
1716
|
safeAssign(
|
|
1604
1717
|
out,
|
|
1605
1718
|
key,
|
|
1606
|
-
mergeDeep(
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1719
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
return out;
|
|
1723
|
+
}
|
|
1724
|
+
function mergeObjectKeys(target, source, path, schema) {
|
|
1725
|
+
const out = isPlainRecord(target) ? { ...target } : {};
|
|
1726
|
+
for (const key of Object.keys(source)) {
|
|
1727
|
+
safeAssign(
|
|
1728
|
+
out,
|
|
1729
|
+
key,
|
|
1730
|
+
mergeDeep(safeOwnRead(out, key), safeOwnRead(source, key), [...path, key], schema)
|
|
1612
1731
|
);
|
|
1613
1732
|
}
|
|
1614
1733
|
return out;
|
|
@@ -1741,7 +1860,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1741
1860
|
if (!result.ok) return result.error;
|
|
1742
1861
|
return stripData(composeWithDerivedBlank(result.refinement, result.segments));
|
|
1743
1862
|
}
|
|
1744
|
-
async function
|
|
1863
|
+
async function parse(pathInput) {
|
|
1745
1864
|
const result = await runImperativeValidation(pathInput, {
|
|
1746
1865
|
cancelInFlight: false,
|
|
1747
1866
|
commitToSchemaErrors: false
|
|
@@ -1794,6 +1913,8 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1794
1913
|
state.activeSubmissions.value += 1;
|
|
1795
1914
|
state.submitting.value = true;
|
|
1796
1915
|
state.submitError.value = null;
|
|
1916
|
+
state.clearUserErrors();
|
|
1917
|
+
while (state.activeTransforms.value > 0) await state.settleTransforms();
|
|
1797
1918
|
state.cancelFieldValidation();
|
|
1798
1919
|
state.displayEngine.clear();
|
|
1799
1920
|
state.activeValidations.value += 1;
|
|
@@ -1832,9 +1953,8 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1832
1953
|
state.emitSubmitSuccess();
|
|
1833
1954
|
} catch (err) {
|
|
1834
1955
|
if (state.submissionGeneration.value === genAtEntry) {
|
|
1835
|
-
state.submitError.value = err;
|
|
1956
|
+
state.submitError.value = toError(err);
|
|
1836
1957
|
}
|
|
1837
|
-
throw err;
|
|
1838
1958
|
} finally {
|
|
1839
1959
|
if (!validationSettled) {
|
|
1840
1960
|
state.activeValidations.value = Math.max(0, state.activeValidations.value - 1);
|
|
@@ -1848,7 +1968,7 @@ function buildProcessForm(state, formInstanceId, options = {}) {
|
|
|
1848
1968
|
};
|
|
1849
1969
|
return submitHandler;
|
|
1850
1970
|
};
|
|
1851
|
-
return { validate, validateAsync,
|
|
1971
|
+
return { validate, validateAsync, parse, handleSubmit };
|
|
1852
1972
|
}
|
|
1853
1973
|
function toSegments(pathInput) {
|
|
1854
1974
|
return canonicalizePath(pathInput).segments;
|
|
@@ -1906,6 +2026,33 @@ function applyInvalidSubmitPolicy(state, formInstanceId, policy) {
|
|
|
1906
2026
|
target.element.focus({ preventScroll: true });
|
|
1907
2027
|
}
|
|
1908
2028
|
|
|
2029
|
+
function captureUserCallSite() {
|
|
2030
|
+
const raw = new Error().stack;
|
|
2031
|
+
if (typeof raw !== "string") return void 0;
|
|
2032
|
+
const lines = raw.split("\n");
|
|
2033
|
+
for (let i = 1; i < lines.length; i++) {
|
|
2034
|
+
const frame = lines[i];
|
|
2035
|
+
if (frame === void 0) continue;
|
|
2036
|
+
if (/attaform[/-]forms?/i.test(frame)) continue;
|
|
2037
|
+
if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
|
|
2038
|
+
const trimmed = frame.trim();
|
|
2039
|
+
if (trimmed.length === 0) continue;
|
|
2040
|
+
return shortenSourceFrame(trimmed);
|
|
2041
|
+
}
|
|
2042
|
+
return void 0;
|
|
2043
|
+
}
|
|
2044
|
+
function shortenSourceFrame(frame) {
|
|
2045
|
+
const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
|
|
2046
|
+
if (match === null) return frame;
|
|
2047
|
+
const [, urlOrPath, line] = match;
|
|
2048
|
+
if (urlOrPath === void 0 || line === void 0) return frame;
|
|
2049
|
+
let path = urlOrPath;
|
|
2050
|
+
path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
|
|
2051
|
+
path = path.replace(/^_nuxt\//, "");
|
|
2052
|
+
path = path.replace(/^\//, "");
|
|
2053
|
+
return `(${path}:${line})`;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
1909
2056
|
function extractSchemaFields(schema) {
|
|
1910
2057
|
try {
|
|
1911
2058
|
const root = schema.getDefaultAtPath([]);
|
|
@@ -1964,9 +2111,9 @@ function isLeafValue(value) {
|
|
|
1964
2111
|
return true;
|
|
1965
2112
|
}
|
|
1966
2113
|
function isSlimPrimitiveValid(schema, store, path, value) {
|
|
1967
|
-
return walk
|
|
2114
|
+
return walk(schema, store, path, value);
|
|
1968
2115
|
}
|
|
1969
|
-
function walk
|
|
2116
|
+
function walk(schema, store, path, value) {
|
|
1970
2117
|
if (schema.isPreprocessOrCoerceLeaf(path)) return true;
|
|
1971
2118
|
const accepted = schema.getSlimPrimitiveTypesAtPath(path);
|
|
1972
2119
|
const kind = isLeafValue(value) ? slimKindOf(value) : Array.isArray(value) ? "array" : "object";
|
|
@@ -1976,13 +2123,13 @@ function walk$1(schema, store, path, value) {
|
|
|
1976
2123
|
}
|
|
1977
2124
|
if (Array.isArray(value)) {
|
|
1978
2125
|
for (let i = 0; i < value.length; i++) {
|
|
1979
|
-
if (!walk
|
|
2126
|
+
if (!walk(schema, store, [...path, i], value[i])) return false;
|
|
1980
2127
|
}
|
|
1981
2128
|
return true;
|
|
1982
2129
|
}
|
|
1983
2130
|
if (isPlainRecord(value)) {
|
|
1984
2131
|
for (const key of Object.keys(value)) {
|
|
1985
|
-
if (!walk
|
|
2132
|
+
if (!walk(schema, store, [...path, key], value[key])) {
|
|
1986
2133
|
return false;
|
|
1987
2134
|
}
|
|
1988
2135
|
}
|
|
@@ -2321,6 +2468,23 @@ function buildRegister(state, formInstanceId, instanceConfig) {
|
|
|
2321
2468
|
markConnectedOptimistically: () => {
|
|
2322
2469
|
state.markConnectedOptimistically(segments);
|
|
2323
2470
|
},
|
|
2471
|
+
// --- Async transform lifecycle (internal; the directive's
|
|
2472
|
+
// deferred orchestrator is the only legitimate consumer). Thin
|
|
2473
|
+
// path-bound delegates to the store's per-path token / counter
|
|
2474
|
+
// machinery — same pattern as `markBlank` / `setValueWithInternalPath`,
|
|
2475
|
+
// so the directive (which holds only this RegisterValue, never the
|
|
2476
|
+
// store) can drive the busy/discard/error bookkeeping. ---
|
|
2477
|
+
beginTransform: (holder) => state.beginTransform(pathKey, holder),
|
|
2478
|
+
isCurrentTransform: (token) => state.isCurrentTransform(pathKey, token),
|
|
2479
|
+
endTransform: (token) => state.endTransform(pathKey, token),
|
|
2480
|
+
setTransformError: (err) => state.setTransformError(pathKey, err),
|
|
2481
|
+
// Synchronous read of "is a transform in flight at this path". The
|
|
2482
|
+
// orchestrator's `beginTransform` bumps the count before the
|
|
2483
|
+
// listener's force-sync block runs, so the directive reads this to
|
|
2484
|
+
// skip reverting the DOM to stale storage mid-flight.
|
|
2485
|
+
get transforming() {
|
|
2486
|
+
return (state.fieldTransformCounts.get(pathKey) ?? 0) > 0;
|
|
2487
|
+
},
|
|
2324
2488
|
path: pathKey,
|
|
2325
2489
|
// Frozen so a wrapper component can pass `rv.segments` directly
|
|
2326
2490
|
// to `form.fields(...)` without defensive copying — and so test
|
|
@@ -2365,49 +2529,60 @@ function walkUnsetSentinels(values, schema) {
|
|
|
2365
2529
|
walkUnspecified(rootSlim, [], paths);
|
|
2366
2530
|
return { cleanedValues: void 0, paths };
|
|
2367
2531
|
}
|
|
2368
|
-
const cleaned =
|
|
2532
|
+
const cleaned = walkCore(values, [], schema, paths, true);
|
|
2369
2533
|
return { cleanedValues: cleaned, paths };
|
|
2370
2534
|
}
|
|
2371
|
-
function
|
|
2535
|
+
function isOpaqueLeaf(value) {
|
|
2536
|
+
return value instanceof Date || value instanceof RegExp || value instanceof Map || value instanceof Set || typeof value === "function";
|
|
2537
|
+
}
|
|
2538
|
+
function walkCore(input, segments, schema, paths, synthesizeSchemaKeys) {
|
|
2372
2539
|
if (isUnset(input)) {
|
|
2373
2540
|
return expandUnsetAt(segments, schema, paths);
|
|
2374
2541
|
}
|
|
2375
2542
|
if (input === void 0) {
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2543
|
+
if (synthesizeSchemaKeys) {
|
|
2544
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2545
|
+
return walkUnspecified(slim, segments, paths);
|
|
2546
|
+
}
|
|
2381
2547
|
return input;
|
|
2382
2548
|
}
|
|
2549
|
+
if (input === null) return null;
|
|
2550
|
+
if (isOpaqueLeaf(input)) return input;
|
|
2383
2551
|
if (Array.isArray(input)) {
|
|
2384
2552
|
const out = new Array(input.length);
|
|
2385
2553
|
let mutated = false;
|
|
2386
2554
|
for (let i = 0; i < input.length; i++) {
|
|
2387
|
-
const walked =
|
|
2555
|
+
const walked = walkCore(input[i], [...segments, i], schema, paths, synthesizeSchemaKeys);
|
|
2388
2556
|
out[i] = walked;
|
|
2389
2557
|
if (walked !== input[i]) mutated = true;
|
|
2390
2558
|
}
|
|
2391
2559
|
return mutated ? out : input;
|
|
2392
2560
|
}
|
|
2393
2561
|
if (typeof input === "object") {
|
|
2394
|
-
const
|
|
2395
|
-
const inputKeys = Object.keys(
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2562
|
+
const obj = input;
|
|
2563
|
+
const inputKeys = Object.keys(obj);
|
|
2564
|
+
let keys = inputKeys;
|
|
2565
|
+
let mutated = false;
|
|
2566
|
+
let inputKeysSet = null;
|
|
2567
|
+
if (synthesizeSchemaKeys) {
|
|
2568
|
+
inputKeysSet = new Set(inputKeys);
|
|
2569
|
+
const allKeys = new Set(inputKeys);
|
|
2570
|
+
const slim = schema.getDefaultAtPath(segments);
|
|
2571
|
+
if (slim !== null && slim !== void 0 && typeof slim === "object" && !Array.isArray(slim) && !isOpaqueLeaf(slim)) {
|
|
2572
|
+
for (const k of Object.keys(slim)) allKeys.add(k);
|
|
2573
|
+
}
|
|
2574
|
+
keys = allKeys;
|
|
2575
|
+
mutated = allKeys.size !== inputKeys.length;
|
|
2400
2576
|
}
|
|
2401
2577
|
const out = {};
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
if (orig === void 0 && inputKeysSet.has(key)) {
|
|
2578
|
+
for (const key of keys) {
|
|
2579
|
+
const orig = obj[key];
|
|
2580
|
+
if (synthesizeSchemaKeys && orig === void 0 && inputKeysSet?.has(key) === true) {
|
|
2406
2581
|
safeAssign(out, key, void 0);
|
|
2407
2582
|
mutated = true;
|
|
2408
2583
|
continue;
|
|
2409
2584
|
}
|
|
2410
|
-
const walked =
|
|
2585
|
+
const walked = walkCore(orig, [...segments, key], schema, paths, synthesizeSchemaKeys);
|
|
2411
2586
|
safeAssign(out, key, walked);
|
|
2412
2587
|
if (walked !== orig) mutated = true;
|
|
2413
2588
|
}
|
|
@@ -2422,7 +2597,7 @@ function walkUnspecified(slim, segments, paths) {
|
|
|
2422
2597
|
}
|
|
2423
2598
|
return slim;
|
|
2424
2599
|
}
|
|
2425
|
-
if (slim
|
|
2600
|
+
if (isOpaqueLeaf(slim)) {
|
|
2426
2601
|
return slim;
|
|
2427
2602
|
}
|
|
2428
2603
|
if (Array.isArray(slim)) return slim;
|
|
@@ -2441,40 +2616,9 @@ function walkUnspecified(slim, segments, paths) {
|
|
|
2441
2616
|
}
|
|
2442
2617
|
function substituteUnsetSentinels(value, prefix, schema) {
|
|
2443
2618
|
const paths = [];
|
|
2444
|
-
const cleaned =
|
|
2619
|
+
const cleaned = walkCore(value, [...prefix], schema, paths, false);
|
|
2445
2620
|
return { cleanedValues: cleaned, paths };
|
|
2446
2621
|
}
|
|
2447
|
-
function substitute(input, segments, schema, paths) {
|
|
2448
|
-
if (isUnset(input)) {
|
|
2449
|
-
return expandUnsetAt(segments, schema, paths);
|
|
2450
|
-
}
|
|
2451
|
-
if (input === void 0 || input === null) return input;
|
|
2452
|
-
if (input instanceof Date || input instanceof RegExp || input instanceof Map || input instanceof Set || typeof input === "function") {
|
|
2453
|
-
return input;
|
|
2454
|
-
}
|
|
2455
|
-
if (Array.isArray(input)) {
|
|
2456
|
-
let mutated = false;
|
|
2457
|
-
const out = new Array(input.length);
|
|
2458
|
-
for (let i = 0; i < input.length; i++) {
|
|
2459
|
-
const walked = substitute(input[i], [...segments, i], schema, paths);
|
|
2460
|
-
out[i] = walked;
|
|
2461
|
-
if (walked !== input[i]) mutated = true;
|
|
2462
|
-
}
|
|
2463
|
-
return mutated ? out : input;
|
|
2464
|
-
}
|
|
2465
|
-
if (typeof input === "object") {
|
|
2466
|
-
let mutated = false;
|
|
2467
|
-
const out = {};
|
|
2468
|
-
for (const key of Object.keys(input)) {
|
|
2469
|
-
const orig = input[key];
|
|
2470
|
-
const walked = substitute(orig, [...segments, key], schema, paths);
|
|
2471
|
-
safeAssign(out, key, walked);
|
|
2472
|
-
if (walked !== orig) mutated = true;
|
|
2473
|
-
}
|
|
2474
|
-
return mutated ? out : input;
|
|
2475
|
-
}
|
|
2476
|
-
return input;
|
|
2477
|
-
}
|
|
2478
2622
|
function isPrimitiveOrEmpty(value) {
|
|
2479
2623
|
if (value === null || value === void 0) return true;
|
|
2480
2624
|
const t = typeof value;
|
|
@@ -2504,7 +2648,7 @@ function expandUnsetAt(segments, schema, paths) {
|
|
|
2504
2648
|
paths.push(canonicalizePath(segments).key);
|
|
2505
2649
|
return slim;
|
|
2506
2650
|
}
|
|
2507
|
-
if (slim
|
|
2651
|
+
if (isOpaqueLeaf(slim)) {
|
|
2508
2652
|
paths.push(canonicalizePath(segments).key);
|
|
2509
2653
|
return slim;
|
|
2510
2654
|
}
|
|
@@ -2519,7 +2663,9 @@ function expandUnsetAt(segments, schema, paths) {
|
|
|
2519
2663
|
function buildCallableReadonlySnapshotProxy(opts) {
|
|
2520
2664
|
const target = (() => {
|
|
2521
2665
|
});
|
|
2522
|
-
const { toString, valueOf, toJSON, toPrimitive } = makeReadonlyCoercion(
|
|
2666
|
+
const { toString, valueOf, toJSON, toPrimitive } = makeReadonlyCoercion(
|
|
2667
|
+
opts.coercionSnapshot ?? opts.snapshot
|
|
2668
|
+
);
|
|
2523
2669
|
const callResolve = opts.resolveCall ?? ((arg) => opts.resolveKey(String(arg)));
|
|
2524
2670
|
return new Proxy(target, {
|
|
2525
2671
|
apply(_, __, args) {
|
|
@@ -2568,27 +2714,52 @@ function buildCallableReadonlySnapshotProxy(opts) {
|
|
|
2568
2714
|
});
|
|
2569
2715
|
}
|
|
2570
2716
|
|
|
2717
|
+
function materializeFormValue(node) {
|
|
2718
|
+
if (node === null || typeof node !== "object") return node;
|
|
2719
|
+
if (Array.isArray(node)) {
|
|
2720
|
+
const out2 = new Array(node.length);
|
|
2721
|
+
for (let i = 0; i < node.length; i++) out2[i] = materializeFormValue(node[i]);
|
|
2722
|
+
return out2;
|
|
2723
|
+
}
|
|
2724
|
+
if (!isPlainRecord(node)) return toRaw(node);
|
|
2725
|
+
const rec = node;
|
|
2726
|
+
const out = {};
|
|
2727
|
+
for (const key of Object.keys(rec)) {
|
|
2728
|
+
safeAssign(out, key, materializeFormValue(safeOwnRead(rec, key)));
|
|
2729
|
+
}
|
|
2730
|
+
return out;
|
|
2731
|
+
}
|
|
2571
2732
|
function buildValuesProxy(form) {
|
|
2572
2733
|
const inner = computed(() => readonly(form.value));
|
|
2573
2734
|
return buildCallableReadonlySnapshotProxy({
|
|
2574
2735
|
surface: "form.values",
|
|
2575
2736
|
snapshot: () => inner.value,
|
|
2737
|
+
// Faithful, reactivity-preserving serialisation: walk the reactive
|
|
2738
|
+
// proxy with own-safe reads so `JSON.stringify(form.values)` /
|
|
2739
|
+
// `String(form.values)` reflect the stored data — including a field
|
|
2740
|
+
// literally named `hasOwnProperty` that Vue would otherwise shim —
|
|
2741
|
+
// while still tracking the per-key reads that drive re-render.
|
|
2742
|
+
coercionSnapshot: () => materializeFormValue(inner.value),
|
|
2576
2743
|
// Read through the readonly proxy at access time so Vue's
|
|
2577
2744
|
// dependency tracking lands inside the consumer's active effect
|
|
2578
2745
|
// — `inner.value[key]` is what triggers per-key tracking.
|
|
2579
|
-
|
|
2580
|
-
//
|
|
2581
|
-
//
|
|
2582
|
-
//
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2746
|
+
//
|
|
2747
|
+
// Prototype-shadowed names (`hasOwnProperty`, `constructor`, …) read
|
|
2748
|
+
// off the RAW target instead: own-shadows-inherited semantics still
|
|
2749
|
+
// hold (a data field by that name returns its stored value), but
|
|
2750
|
+
// when there's no such field the inherited member resolves — so
|
|
2751
|
+
// `form.values.hasOwnProperty('x')` keeps working as the real
|
|
2752
|
+
// method. The raw read dodges Vue's `hasOwnProperty` proxy shim,
|
|
2753
|
+
// which would otherwise mask a data field of that name. (`toString`
|
|
2754
|
+
// / `valueOf` / `toJSON` never reach here — the base get trap
|
|
2755
|
+
// intercepts them as coercion handlers first.)
|
|
2756
|
+
resolveKey: (key) => isShadowedKey(key) ? toRaw(inner.value)[key] : inner.value[key],
|
|
2757
|
+
// Dynamic path: walk segments through the readonly proxy with the
|
|
2758
|
+
// same own-property-safe descent the rest of the runtime uses
|
|
2759
|
+
// (`getAtPath`), so `form.values('a.hasOwnProperty')` resolves the
|
|
2760
|
+
// stored value. Per-level reads still propagate Vue's tracking for
|
|
2761
|
+
// ordinary keys.
|
|
2762
|
+
resolveCall: (arg) => getAtPath(inner.value, canonicalizePath(arg).segments),
|
|
2592
2763
|
ownKeys: () => Reflect.ownKeys(inner.value),
|
|
2593
2764
|
hasKey: (key) => Reflect.has(inner.value, key),
|
|
2594
2765
|
describeKey: (key) => {
|
|
@@ -2611,6 +2782,17 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2611
2782
|
if (instanceMeta === void 0) return meta;
|
|
2612
2783
|
return meta === void 0 ? { instance: instanceMeta } : { ...meta, instance: instanceMeta };
|
|
2613
2784
|
};
|
|
2785
|
+
const reMarkBlanksAfterSubstitution = (paths) => {
|
|
2786
|
+
for (const pathKey of paths) {
|
|
2787
|
+
const blankSegments = segmentsForPathKey(pathKey);
|
|
2788
|
+
if (blankSegments === null) continue;
|
|
2789
|
+
state.setValueAtPath(
|
|
2790
|
+
blankSegments,
|
|
2791
|
+
state.getValueAtPath(blankSegments),
|
|
2792
|
+
withInstanceMeta({ blank: true })
|
|
2793
|
+
);
|
|
2794
|
+
}
|
|
2795
|
+
};
|
|
2614
2796
|
const getFormMetaBase = () => {
|
|
2615
2797
|
const { base: rootBase } = buildContainerFieldStateBase(
|
|
2616
2798
|
state,
|
|
@@ -2649,12 +2831,12 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2649
2831
|
const {
|
|
2650
2832
|
validate: validateBuilt,
|
|
2651
2833
|
validateAsync: validateAsyncBuilt,
|
|
2652
|
-
|
|
2834
|
+
parse: parseBuilt,
|
|
2653
2835
|
handleSubmit
|
|
2654
2836
|
} = buildProcessForm(state, formInstanceId, processOptions);
|
|
2655
2837
|
const validate = (pathInput) => validateBuilt(pathInput);
|
|
2656
2838
|
const validateAsync = (pathInput) => validateAsyncBuilt(pathInput);
|
|
2657
|
-
const
|
|
2839
|
+
const parse = (pathInput) => parseBuilt(pathInput);
|
|
2658
2840
|
function pathToRef(pathInput) {
|
|
2659
2841
|
const segments = canonicalizePath(pathInput).segments;
|
|
2660
2842
|
return computed(() => getAtPath(state.form.value, segments));
|
|
@@ -2668,15 +2850,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2668
2850
|
);
|
|
2669
2851
|
const ok2 = state.setValueAtPath([], walked2.cleanedValues, withInstanceMeta());
|
|
2670
2852
|
if (!ok2) return false;
|
|
2671
|
-
|
|
2672
|
-
const blankSegments = segmentsForPathKey(pathKey);
|
|
2673
|
-
if (blankSegments === null) continue;
|
|
2674
|
-
state.setValueAtPath(
|
|
2675
|
-
blankSegments,
|
|
2676
|
-
state.getValueAtPath(blankSegments),
|
|
2677
|
-
withInstanceMeta({ blank: true })
|
|
2678
|
-
);
|
|
2679
|
-
}
|
|
2853
|
+
reMarkBlanksAfterSubstitution(walked2.paths);
|
|
2680
2854
|
return true;
|
|
2681
2855
|
}
|
|
2682
2856
|
const segments = canonicalizePath(pathOrValue).segments;
|
|
@@ -2731,15 +2905,7 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2731
2905
|
);
|
|
2732
2906
|
const ok = state.setValueAtPath(segments, walked.cleanedValues, withInstanceMeta());
|
|
2733
2907
|
if (!ok) return false;
|
|
2734
|
-
|
|
2735
|
-
const blankSegments = segmentsForPathKey(pathKey);
|
|
2736
|
-
if (blankSegments === null) continue;
|
|
2737
|
-
state.setValueAtPath(
|
|
2738
|
-
blankSegments,
|
|
2739
|
-
state.getValueAtPath(blankSegments),
|
|
2740
|
-
withInstanceMeta({ blank: true })
|
|
2741
|
-
);
|
|
2742
|
-
}
|
|
2908
|
+
reMarkBlanksAfterSubstitution(walked.paths);
|
|
2743
2909
|
return true;
|
|
2744
2910
|
}
|
|
2745
2911
|
const errorsProxy = buildErrorsProxy(state);
|
|
@@ -2882,6 +3048,21 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
2882
3048
|
// keep the explicit form-level computation for the gate.
|
|
2883
3049
|
valid,
|
|
2884
3050
|
errors: metaErrors,
|
|
3051
|
+
// Whole-form transforming mirrors the global `activeTransforms`
|
|
3052
|
+
// counter ORed with any per-leaf transform in flight (the root
|
|
3053
|
+
// rollup), exactly as `validating` composes its lifecycle and
|
|
3054
|
+
// per-field sources. `busy` is the union of both work signals at
|
|
3055
|
+
// the form level. `transformError` is leaf-only, so the root
|
|
3056
|
+
// rollup reads it as `null` (kept for FieldState-shape parity).
|
|
3057
|
+
transforming: computed(
|
|
3058
|
+
() => state.activeTransforms.value > 0 || rootFieldState.value.transforming
|
|
3059
|
+
),
|
|
3060
|
+
busy: computed(
|
|
3061
|
+
() => state.activeValidations.value > 0 || state.activeTransforms.value > 0 || rootFieldState.value.validating || rootFieldState.value.transforming
|
|
3062
|
+
),
|
|
3063
|
+
get transformError() {
|
|
3064
|
+
return rootFieldState.value.transformError;
|
|
3065
|
+
},
|
|
2885
3066
|
// `displayState` / the `show*` booleans / `firstError` flow
|
|
2886
3067
|
// through the same root field-state computed as the rest of the
|
|
2887
3068
|
// FieldState surface, so `form.meta.displayState` matches
|
|
@@ -3110,7 +3291,8 @@ function buildFormApi(state, formInstanceId, options = {}) {
|
|
|
3110
3291
|
setValue: gated(setValueImpl),
|
|
3111
3292
|
validate: gated(validate),
|
|
3112
3293
|
validateAsync: gated(validateAsync),
|
|
3113
|
-
|
|
3294
|
+
parse: gated(parse),
|
|
3295
|
+
settleTransforms: gated(state.settleTransforms),
|
|
3114
3296
|
register: gated(register),
|
|
3115
3297
|
key: state.formKey,
|
|
3116
3298
|
// Auto-unwrapping views over the per-store async-defaults lifecycle
|
|
@@ -3977,6 +4159,106 @@ function createFormStore(options) {
|
|
|
3977
4159
|
fieldValidationCounts.set(key, next);
|
|
3978
4160
|
}
|
|
3979
4161
|
}
|
|
4162
|
+
const fieldTransformCounts = reactive(/* @__PURE__ */ new Map());
|
|
4163
|
+
const fieldTransformingSince = reactive(/* @__PURE__ */ new Map());
|
|
4164
|
+
const transformErrors = reactive(/* @__PURE__ */ new Map());
|
|
4165
|
+
const activeTransforms = ref(0);
|
|
4166
|
+
const transformRuns = /* @__PURE__ */ new Map();
|
|
4167
|
+
let transformTokenSeq = 0;
|
|
4168
|
+
const transformWaiters = [];
|
|
4169
|
+
function incFieldTransform(key) {
|
|
4170
|
+
fieldTransformingSince.set(key, ssr ? 0 : Date.now());
|
|
4171
|
+
fieldTransformCounts.set(key, (fieldTransformCounts.get(key) ?? 0) + 1);
|
|
4172
|
+
}
|
|
4173
|
+
function decFieldTransform(key) {
|
|
4174
|
+
const next = (fieldTransformCounts.get(key) ?? 0) - 1;
|
|
4175
|
+
if (next <= 0) {
|
|
4176
|
+
fieldTransformCounts.delete(key);
|
|
4177
|
+
fieldTransformingSince.delete(key);
|
|
4178
|
+
} else {
|
|
4179
|
+
fieldTransformCounts.set(key, next);
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
function flushSettledTransformWaiters() {
|
|
4183
|
+
if (transformWaiters.length === 0) return;
|
|
4184
|
+
const globalIdle = activeTransforms.value === 0;
|
|
4185
|
+
for (let i = transformWaiters.length - 1; i >= 0; i--) {
|
|
4186
|
+
const w = transformWaiters[i];
|
|
4187
|
+
if (w === void 0) continue;
|
|
4188
|
+
const idle = w.key === null ? globalIdle : (fieldTransformCounts.get(w.key) ?? 0) === 0;
|
|
4189
|
+
if (idle) {
|
|
4190
|
+
transformWaiters.splice(i, 1);
|
|
4191
|
+
w.resolve();
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
function releaseTransformRun(key, run) {
|
|
4196
|
+
if (run.released) return;
|
|
4197
|
+
run.released = true;
|
|
4198
|
+
run.holder.aborted = true;
|
|
4199
|
+
run.holder.controller?.abort();
|
|
4200
|
+
activeTransforms.value = Math.max(0, activeTransforms.value - 1);
|
|
4201
|
+
decFieldTransform(key);
|
|
4202
|
+
}
|
|
4203
|
+
function beginTransform(key, holder) {
|
|
4204
|
+
const prior = transformRuns.get(key);
|
|
4205
|
+
if (prior !== void 0) releaseTransformRun(key, prior);
|
|
4206
|
+
const token = ++transformTokenSeq;
|
|
4207
|
+
transformRuns.set(key, { token, holder, released: false });
|
|
4208
|
+
incFieldTransform(key);
|
|
4209
|
+
activeTransforms.value += 1;
|
|
4210
|
+
if (transformErrors.has(key)) transformErrors.delete(key);
|
|
4211
|
+
return token;
|
|
4212
|
+
}
|
|
4213
|
+
function isCurrentTransform(key, token) {
|
|
4214
|
+
return transformRuns.get(key)?.token === token;
|
|
4215
|
+
}
|
|
4216
|
+
function endTransform(key, token) {
|
|
4217
|
+
const run = transformRuns.get(key);
|
|
4218
|
+
if (run?.token === token) {
|
|
4219
|
+
if (!run.released) {
|
|
4220
|
+
activeTransforms.value = Math.max(0, activeTransforms.value - 1);
|
|
4221
|
+
decFieldTransform(key);
|
|
4222
|
+
}
|
|
4223
|
+
transformRuns.delete(key);
|
|
4224
|
+
}
|
|
4225
|
+
flushSettledTransformWaiters();
|
|
4226
|
+
}
|
|
4227
|
+
function setTransformError(key, err) {
|
|
4228
|
+
transformErrors.set(key, err);
|
|
4229
|
+
}
|
|
4230
|
+
function cancelTransforms() {
|
|
4231
|
+
for (const [key, run] of [...transformRuns]) {
|
|
4232
|
+
releaseTransformRun(key, run);
|
|
4233
|
+
transformRuns.delete(key);
|
|
4234
|
+
}
|
|
4235
|
+
if (transformErrors.size > 0) transformErrors.clear();
|
|
4236
|
+
flushSettledTransformWaiters();
|
|
4237
|
+
}
|
|
4238
|
+
function cancelTransformsUnder(prefix) {
|
|
4239
|
+
for (const [key, run] of [...transformRuns]) {
|
|
4240
|
+
const segs = segmentsForPathKey(key);
|
|
4241
|
+
if (segs === null) continue;
|
|
4242
|
+
if (!isPathPrefix(prefix, segs)) continue;
|
|
4243
|
+
releaseTransformRun(key, run);
|
|
4244
|
+
transformRuns.delete(key);
|
|
4245
|
+
transformErrors.delete(key);
|
|
4246
|
+
}
|
|
4247
|
+
flushSettledTransformWaiters();
|
|
4248
|
+
}
|
|
4249
|
+
function settleTransforms(path) {
|
|
4250
|
+
if (path === void 0) {
|
|
4251
|
+
if (activeTransforms.value === 0) return Promise.resolve();
|
|
4252
|
+
return new Promise((resolve) => {
|
|
4253
|
+
transformWaiters.push({ key: null, resolve });
|
|
4254
|
+
});
|
|
4255
|
+
}
|
|
4256
|
+
const { key } = canonicalizePath(path);
|
|
4257
|
+
if ((fieldTransformCounts.get(key) ?? 0) === 0) return Promise.resolve();
|
|
4258
|
+
return new Promise((resolve) => {
|
|
4259
|
+
transformWaiters.push({ key, resolve });
|
|
4260
|
+
});
|
|
4261
|
+
}
|
|
3980
4262
|
const initStamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3981
4263
|
diffAndApply({}, schemaInitialData, [], (patch) => {
|
|
3982
4264
|
if (patch.kind !== "added") return;
|
|
@@ -4126,6 +4408,7 @@ function createFormStore(options) {
|
|
|
4126
4408
|
}
|
|
4127
4409
|
}
|
|
4128
4410
|
}
|
|
4411
|
+
if (transformRuns.size !== 0) cancelTransformsUnder(path);
|
|
4129
4412
|
if (meta?.skipDiscriminatorReshape !== true) {
|
|
4130
4413
|
if (path.length > 0) {
|
|
4131
4414
|
const last = path[path.length - 1];
|
|
@@ -4460,6 +4743,7 @@ function createFormStore(options) {
|
|
|
4460
4743
|
drainHooks.length = 0;
|
|
4461
4744
|
modules.clear();
|
|
4462
4745
|
cancelFieldValidation();
|
|
4746
|
+
cancelTransforms();
|
|
4463
4747
|
fieldValidatingSince.clear();
|
|
4464
4748
|
formChangeListeners.clear();
|
|
4465
4749
|
submitSuccessListeners.clear();
|
|
@@ -4596,6 +4880,7 @@ function createFormStore(options) {
|
|
|
4596
4880
|
if (remaining === 0) {
|
|
4597
4881
|
elements.delete(key);
|
|
4598
4882
|
touchFieldRecord(key, path, { connected: false, focused: null, blurred: null });
|
|
4883
|
+
if (transformRuns.size !== 0) cancelTransformsUnder(path);
|
|
4599
4884
|
}
|
|
4600
4885
|
return remaining;
|
|
4601
4886
|
}
|
|
@@ -4817,6 +5102,7 @@ function createFormStore(options) {
|
|
|
4817
5102
|
submitError.value = null;
|
|
4818
5103
|
departAttempts.value = 0;
|
|
4819
5104
|
cancelFieldValidation();
|
|
5105
|
+
cancelTransforms();
|
|
4820
5106
|
displayEngine.clear();
|
|
4821
5107
|
fieldValidatingSince.clear();
|
|
4822
5108
|
pathSnapshots.clear();
|
|
@@ -4835,6 +5121,7 @@ function createFormStore(options) {
|
|
|
4835
5121
|
const { key: targetKey, segments: targetSegments } = canonicalizePath(path);
|
|
4836
5122
|
variantMemory.clearUnderPath(targetSegments);
|
|
4837
5123
|
cancelFieldValidationUnder(targetSegments);
|
|
5124
|
+
cancelTransformsUnder(targetSegments);
|
|
4838
5125
|
for (const [snapKey] of [...pathSnapshots]) {
|
|
4839
5126
|
const segs = segmentsForPathKey(snapKey);
|
|
4840
5127
|
if (segs === null) continue;
|
|
@@ -4970,6 +5257,10 @@ function createFormStore(options) {
|
|
|
4970
5257
|
pathHasAsyncValidationByKey,
|
|
4971
5258
|
fieldValidationCounts,
|
|
4972
5259
|
fieldValidatingSince,
|
|
5260
|
+
fieldTransformCounts,
|
|
5261
|
+
fieldTransformingSince,
|
|
5262
|
+
transformErrors,
|
|
5263
|
+
activeTransforms,
|
|
4973
5264
|
displayEngine,
|
|
4974
5265
|
applyFormReplacement,
|
|
4975
5266
|
setValueAtPath,
|
|
@@ -4999,6 +5290,13 @@ function createFormStore(options) {
|
|
|
4999
5290
|
getOriginalAtPath,
|
|
5000
5291
|
getFirstErrorElement,
|
|
5001
5292
|
cancelFieldValidation,
|
|
5293
|
+
beginTransform,
|
|
5294
|
+
isCurrentTransform,
|
|
5295
|
+
endTransform,
|
|
5296
|
+
setTransformError,
|
|
5297
|
+
cancelTransforms,
|
|
5298
|
+
cancelTransformsUnder,
|
|
5299
|
+
settleTransforms,
|
|
5002
5300
|
scheduleFieldValidation,
|
|
5003
5301
|
onFormChange,
|
|
5004
5302
|
onSubmitSuccess,
|
|
@@ -5030,6 +5328,20 @@ function captureErrorEntries(map) {
|
|
|
5030
5328
|
for (const [k, v] of map) out.push([k, [...v]]);
|
|
5031
5329
|
return out;
|
|
5032
5330
|
}
|
|
5331
|
+
function pathsEqual(a, b) {
|
|
5332
|
+
if (a.length !== b.length) return false;
|
|
5333
|
+
for (let j = 0; j < a.length; j++) {
|
|
5334
|
+
if (a[j] !== b[j]) return false;
|
|
5335
|
+
}
|
|
5336
|
+
return true;
|
|
5337
|
+
}
|
|
5338
|
+
function errorFieldsEqual(av, bvi) {
|
|
5339
|
+
if (av === bvi) return true;
|
|
5340
|
+
if (av.message !== bvi.message) return false;
|
|
5341
|
+
if (av.code !== bvi.code) return false;
|
|
5342
|
+
if (av.formKey !== bvi.formKey) return false;
|
|
5343
|
+
return av.path === bvi.path || pathsEqual(av.path, bvi.path);
|
|
5344
|
+
}
|
|
5033
5345
|
function errorsEqual(a, b) {
|
|
5034
5346
|
if (a.length !== b.length) return false;
|
|
5035
5347
|
const bMap = /* @__PURE__ */ new Map();
|
|
@@ -5039,18 +5351,7 @@ function errorsEqual(a, b) {
|
|
|
5039
5351
|
if (bv === void 0) return false;
|
|
5040
5352
|
if (v.length !== bv.length) return false;
|
|
5041
5353
|
for (let i = 0; i < v.length; i++) {
|
|
5042
|
-
|
|
5043
|
-
const bvi = bv[i];
|
|
5044
|
-
if (av === bvi) continue;
|
|
5045
|
-
if (av.message !== bvi.message) return false;
|
|
5046
|
-
if (av.code !== bvi.code) return false;
|
|
5047
|
-
if (av.formKey !== bvi.formKey) return false;
|
|
5048
|
-
if (av.path !== bvi.path) {
|
|
5049
|
-
if (av.path.length !== bvi.path.length) return false;
|
|
5050
|
-
for (let j = 0; j < av.path.length; j++) {
|
|
5051
|
-
if (av.path[j] !== bvi.path[j]) return false;
|
|
5052
|
-
}
|
|
5053
|
-
}
|
|
5354
|
+
if (!errorFieldsEqual(v[i], bv[i])) return false;
|
|
5054
5355
|
}
|
|
5055
5356
|
}
|
|
5056
5357
|
return true;
|
|
@@ -5632,6 +5933,99 @@ function warnIfAmbientProviderHadDuplicates() {
|
|
|
5632
5933
|
}
|
|
5633
5934
|
}
|
|
5634
5935
|
|
|
5936
|
+
const warnedNoParentRV = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
|
|
5937
|
+
let warnedOutsideSetup = false;
|
|
5938
|
+
function makeRegisterValueProxy(capturedRegisterValue) {
|
|
5939
|
+
return new Proxy({}, {
|
|
5940
|
+
get(_target, prop) {
|
|
5941
|
+
if (prop === "__v_isRef") return true;
|
|
5942
|
+
if (prop === "value") return capturedRegisterValue.value;
|
|
5943
|
+
const v = capturedRegisterValue.value;
|
|
5944
|
+
if (v === void 0) return void 0;
|
|
5945
|
+
return Reflect.get(v, prop);
|
|
5946
|
+
},
|
|
5947
|
+
has(_target, prop) {
|
|
5948
|
+
if (prop === "__v_isRef" || prop === "value") return true;
|
|
5949
|
+
const v = capturedRegisterValue.value;
|
|
5950
|
+
if (v === void 0) return false;
|
|
5951
|
+
return Reflect.has(v, prop);
|
|
5952
|
+
},
|
|
5953
|
+
ownKeys(_target) {
|
|
5954
|
+
const v = capturedRegisterValue.value;
|
|
5955
|
+
if (v === void 0) return [];
|
|
5956
|
+
return Reflect.ownKeys(v);
|
|
5957
|
+
},
|
|
5958
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
5959
|
+
const v = capturedRegisterValue.value;
|
|
5960
|
+
if (v === void 0) return void 0;
|
|
5961
|
+
const desc = Reflect.getOwnPropertyDescriptor(v, prop);
|
|
5962
|
+
if (desc !== void 0) {
|
|
5963
|
+
desc.configurable = true;
|
|
5964
|
+
}
|
|
5965
|
+
return desc;
|
|
5966
|
+
}
|
|
5967
|
+
});
|
|
5968
|
+
}
|
|
5969
|
+
function useRegister() {
|
|
5970
|
+
const instance = getCurrentInstance();
|
|
5971
|
+
if (instance === null) {
|
|
5972
|
+
warnOutsideSetup();
|
|
5973
|
+
return makeRegisterValueProxy(shallowRef(void 0));
|
|
5974
|
+
}
|
|
5975
|
+
ensureAttaformInstalled(instance.appContext.app);
|
|
5976
|
+
const capturedRegisterValue = shallowRef(void 0);
|
|
5977
|
+
const refreshAndStripBridgeAttrs = () => {
|
|
5978
|
+
const rawAttrs = instance.attrs;
|
|
5979
|
+
if ("registerValue" in rawAttrs) {
|
|
5980
|
+
capturedRegisterValue.value = rawAttrs["registerValue"];
|
|
5981
|
+
delete rawAttrs["registerValue"];
|
|
5982
|
+
} else {
|
|
5983
|
+
const dirs = instance.vnode.dirs;
|
|
5984
|
+
if (dirs !== null && dirs !== void 0) {
|
|
5985
|
+
for (const dir of dirs) {
|
|
5986
|
+
const marked = dir.dir?.[V_REGISTER_MARKER];
|
|
5987
|
+
if (marked === true) {
|
|
5988
|
+
capturedRegisterValue.value = dir.value;
|
|
5989
|
+
break;
|
|
5990
|
+
}
|
|
5991
|
+
}
|
|
5992
|
+
}
|
|
5993
|
+
}
|
|
5994
|
+
if ("value" in rawAttrs) delete rawAttrs["value"];
|
|
5995
|
+
};
|
|
5996
|
+
refreshAndStripBridgeAttrs();
|
|
5997
|
+
onBeforeMount(refreshAndStripBridgeAttrs);
|
|
5998
|
+
onBeforeUpdate(refreshAndStripBridgeAttrs);
|
|
5999
|
+
onMounted(() => {
|
|
6000
|
+
const el = instance.vnode.el;
|
|
6001
|
+
if (el !== null && el !== void 0 && typeof el === "object") {
|
|
6002
|
+
el[REGISTER_OWNER_MARKER] = true;
|
|
6003
|
+
}
|
|
6004
|
+
if (capturedRegisterValue.value === void 0) {
|
|
6005
|
+
warnNoParentRV(instance);
|
|
6006
|
+
}
|
|
6007
|
+
});
|
|
6008
|
+
return makeRegisterValueProxy(capturedRegisterValue);
|
|
6009
|
+
}
|
|
6010
|
+
function warnOutsideSetup() {
|
|
6011
|
+
if (!__DEV__) return;
|
|
6012
|
+
if (warnedOutsideSetup) return;
|
|
6013
|
+
warnedOutsideSetup = true;
|
|
6014
|
+
const frame = captureUserCallSite();
|
|
6015
|
+
console.warn(
|
|
6016
|
+
`[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}` : "")
|
|
6017
|
+
);
|
|
6018
|
+
}
|
|
6019
|
+
function warnNoParentRV(instance) {
|
|
6020
|
+
if (!__DEV__ || warnedNoParentRV === null) return;
|
|
6021
|
+
if (warnedNoParentRV.has(instance)) return;
|
|
6022
|
+
warnedNoParentRV.add(instance);
|
|
6023
|
+
const frame = captureUserCallSite();
|
|
6024
|
+
console.warn(
|
|
6025
|
+
`[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}` : "")
|
|
6026
|
+
);
|
|
6027
|
+
}
|
|
6028
|
+
|
|
5635
6029
|
const LAZY_BRAND = Symbol.for("attaform/wizard-lazy");
|
|
5636
6030
|
function lazy(resolve) {
|
|
5637
6031
|
return { [LAZY_BRAND]: true, resolve };
|
|
@@ -5641,6 +6035,8 @@ function isLazyMarker(value) {
|
|
|
5641
6035
|
}
|
|
5642
6036
|
|
|
5643
6037
|
const NOOP_WIZARD_HISTORY = {
|
|
6038
|
+
push() {
|
|
6039
|
+
},
|
|
5644
6040
|
replace() {
|
|
5645
6041
|
},
|
|
5646
6042
|
read() {
|
|
@@ -5655,6 +6051,9 @@ function createWizardHistory(param) {
|
|
|
5655
6051
|
if (typeof window === "undefined") return NOOP_WIZARD_HISTORY;
|
|
5656
6052
|
const subscribers = [];
|
|
5657
6053
|
let disposed = false;
|
|
6054
|
+
function currentKey() {
|
|
6055
|
+
return new URL(window.location.href).searchParams.get(param) ?? void 0;
|
|
6056
|
+
}
|
|
5658
6057
|
function buildUrl(key) {
|
|
5659
6058
|
const url = new URL(window.location.href);
|
|
5660
6059
|
url.searchParams.set(param, key);
|
|
@@ -5662,25 +6061,29 @@ function createWizardHistory(param) {
|
|
|
5662
6061
|
}
|
|
5663
6062
|
function handlePopstate() {
|
|
5664
6063
|
if (disposed) return;
|
|
5665
|
-
const
|
|
5666
|
-
const value = url.searchParams.get(param) ?? void 0;
|
|
6064
|
+
const value = currentKey();
|
|
5667
6065
|
for (const subscriber of subscribers) subscriber(value);
|
|
5668
6066
|
}
|
|
5669
6067
|
window.addEventListener("popstate", handlePopstate);
|
|
5670
|
-
function
|
|
6068
|
+
function safeWrite(key, mode) {
|
|
5671
6069
|
try {
|
|
5672
|
-
window.history.
|
|
6070
|
+
if (mode === "push") window.history.pushState({}, "", buildUrl(key));
|
|
6071
|
+
else window.history.replaceState({}, "", buildUrl(key));
|
|
5673
6072
|
} catch {
|
|
5674
6073
|
}
|
|
5675
6074
|
}
|
|
5676
6075
|
return {
|
|
6076
|
+
push(key) {
|
|
6077
|
+
if (disposed) return;
|
|
6078
|
+
if (currentKey() === key) return;
|
|
6079
|
+
safeWrite(key, "push");
|
|
6080
|
+
},
|
|
5677
6081
|
replace(key) {
|
|
5678
6082
|
if (disposed) return;
|
|
5679
|
-
|
|
6083
|
+
safeWrite(key, "replace");
|
|
5680
6084
|
},
|
|
5681
6085
|
read() {
|
|
5682
|
-
|
|
5683
|
-
return url.searchParams.get(param) ?? void 0;
|
|
6086
|
+
return currentKey();
|
|
5684
6087
|
},
|
|
5685
6088
|
subscribe(callback) {
|
|
5686
6089
|
if (disposed) return;
|
|
@@ -5718,6 +6121,7 @@ function buildNoopWizardSchema(formKey) {
|
|
|
5718
6121
|
getEmptyValueAtPath: () => void 0,
|
|
5719
6122
|
isPreprocessOrCoerceLeaf: () => false,
|
|
5720
6123
|
arrayShapeAtPath: () => void 0,
|
|
6124
|
+
isFixedObjectAtPath: (path) => path.length === 0,
|
|
5721
6125
|
getSchemasAtPath: () => [],
|
|
5722
6126
|
validateAtPath: () => success,
|
|
5723
6127
|
getSlimPrimitiveTypesAtPath: () => new Set(EMPTY_SLIM_KINDS),
|
|
@@ -6171,7 +6575,10 @@ function useWizard(options) {
|
|
|
6171
6575
|
};
|
|
6172
6576
|
const persistCallback = options.persist === false ? void 0 : options.persist !== void 0 ? options.persist : (state) => {
|
|
6173
6577
|
if (state.step === void 0) return;
|
|
6174
|
-
historyHandle.
|
|
6578
|
+
const current = historyHandle.read();
|
|
6579
|
+
const effectiveCurrent = current !== void 0 && isCompiledKey(current) ? current : firstKey();
|
|
6580
|
+
if (state.step === effectiveCurrent) historyHandle.replace(state.step);
|
|
6581
|
+
else historyHandle.push(state.step);
|
|
6175
6582
|
};
|
|
6176
6583
|
function isCompiledKey(key) {
|
|
6177
6584
|
const list = compiledSteps.value;
|
|
@@ -6252,6 +6659,7 @@ function useWizard(options) {
|
|
|
6252
6659
|
}
|
|
6253
6660
|
const submitting = ref(false);
|
|
6254
6661
|
const submissionAttempts = ref(0);
|
|
6662
|
+
const submitError = ref(null);
|
|
6255
6663
|
const done = ref(false);
|
|
6256
6664
|
function activateForm(form) {
|
|
6257
6665
|
const source = asSubmissionSource(form);
|
|
@@ -6379,7 +6787,7 @@ function useWizard(options) {
|
|
|
6379
6787
|
formKey: form.key
|
|
6380
6788
|
};
|
|
6381
6789
|
}
|
|
6382
|
-
return full.
|
|
6790
|
+
return full.parse();
|
|
6383
6791
|
}
|
|
6384
6792
|
function collectErrors(results) {
|
|
6385
6793
|
const out = [];
|
|
@@ -6410,6 +6818,7 @@ function useWizard(options) {
|
|
|
6410
6818
|
return;
|
|
6411
6819
|
}
|
|
6412
6820
|
submitting.value = true;
|
|
6821
|
+
submitError.value = null;
|
|
6413
6822
|
try {
|
|
6414
6823
|
const currentKey = activeKey.value;
|
|
6415
6824
|
const final = isFinalStep.value;
|
|
@@ -6418,12 +6827,14 @@ function useWizard(options) {
|
|
|
6418
6827
|
if (final) {
|
|
6419
6828
|
await Promise.all(
|
|
6420
6829
|
list.map(async (step) => {
|
|
6830
|
+
registry.forms.get(step.key)?.clearUserErrors();
|
|
6421
6831
|
const result = await processOne(step.form);
|
|
6422
6832
|
results.set(step.key, result);
|
|
6423
6833
|
})
|
|
6424
6834
|
);
|
|
6425
6835
|
} else {
|
|
6426
6836
|
const active = activeForm.value;
|
|
6837
|
+
registry.forms.get(active.key)?.clearUserErrors();
|
|
6427
6838
|
const result = await processOne(active);
|
|
6428
6839
|
results.set(active.key, result);
|
|
6429
6840
|
}
|
|
@@ -6458,7 +6869,6 @@ function useWizard(options) {
|
|
|
6458
6869
|
if (target !== void 0) moveTo(target.key);
|
|
6459
6870
|
}
|
|
6460
6871
|
} else {
|
|
6461
|
-
if (onError !== void 0) await onError(errors);
|
|
6462
6872
|
if (options.focusFirstError !== false) {
|
|
6463
6873
|
const firstFailedKey = errors[0]?.formKey;
|
|
6464
6874
|
if (firstFailedKey !== void 0 && isCompiledKey(firstFailedKey)) {
|
|
@@ -6473,7 +6883,16 @@ function useWizard(options) {
|
|
|
6473
6883
|
}
|
|
6474
6884
|
}
|
|
6475
6885
|
}
|
|
6886
|
+
if (onError !== void 0) {
|
|
6887
|
+
try {
|
|
6888
|
+
await onError(errors);
|
|
6889
|
+
} catch (cause) {
|
|
6890
|
+
throw new SubmitErrorHandlerError("User-provided onError threw", { cause });
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6476
6893
|
}
|
|
6894
|
+
} catch (err) {
|
|
6895
|
+
submitError.value = toError(err);
|
|
6477
6896
|
} finally {
|
|
6478
6897
|
submitting.value = false;
|
|
6479
6898
|
}
|
|
@@ -6482,6 +6901,7 @@ function useWizard(options) {
|
|
|
6482
6901
|
function reset() {
|
|
6483
6902
|
submissionAttempts.value = 0;
|
|
6484
6903
|
done.value = false;
|
|
6904
|
+
submitError.value = null;
|
|
6485
6905
|
lazyEpoch.value += 1;
|
|
6486
6906
|
for (const step of compiledSteps.value) {
|
|
6487
6907
|
const full = asSubmissionSource(step.form);
|
|
@@ -6557,6 +6977,9 @@ function useWizard(options) {
|
|
|
6557
6977
|
get submissionAttempts() {
|
|
6558
6978
|
return submissionAttempts.value;
|
|
6559
6979
|
},
|
|
6980
|
+
get submitError() {
|
|
6981
|
+
return submitError.value;
|
|
6982
|
+
},
|
|
6560
6983
|
get visited() {
|
|
6561
6984
|
return visited.value;
|
|
6562
6985
|
}
|
|
@@ -6666,5 +7089,5 @@ function warnIfAmbientWizardProviderHadDuplicates() {
|
|
|
6666
7089
|
}
|
|
6667
7090
|
}
|
|
6668
7091
|
|
|
6669
|
-
export { AttaformErrorCode as A,
|
|
6670
|
-
//# sourceMappingURL=attaform.
|
|
7092
|
+
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 };
|
|
7093
|
+
//# sourceMappingURL=attaform.CTheKoTc.mjs.map
|