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.
Files changed (108) hide show
  1. package/dist/chunks/dev-key-collision-warnings.cjs +1 -1
  2. package/dist/chunks/dev-key-collision-warnings.mjs +1 -1
  3. package/dist/chunks/devtools.cjs +1 -1
  4. package/dist/chunks/devtools.mjs +1 -1
  5. package/dist/chunks/fingerprint2.cjs +1 -1
  6. package/dist/chunks/fingerprint2.mjs +1 -1
  7. package/dist/chunks/indexeddb.cjs +1 -1
  8. package/dist/chunks/indexeddb.mjs +1 -1
  9. package/dist/chunks/local-storage.cjs +1 -1
  10. package/dist/chunks/local-storage.mjs +1 -1
  11. package/dist/chunks/multi-tab-sync.cjs +2 -2
  12. package/dist/chunks/multi-tab-sync.mjs +2 -2
  13. package/dist/chunks/session-storage.cjs +1 -1
  14. package/dist/chunks/session-storage.mjs +1 -1
  15. package/dist/chunks/wire-persistence.cjs +2 -2
  16. package/dist/chunks/wire-persistence.mjs +2 -2
  17. package/dist/index.cjs +37 -24
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +20 -18
  20. package/dist/index.d.mts +20 -18
  21. package/dist/index.d.ts +20 -18
  22. package/dist/index.mjs +38 -25
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/nuxt.d.cts +1 -1
  25. package/dist/nuxt.d.mts +1 -1
  26. package/dist/nuxt.d.ts +1 -1
  27. package/dist/runtime/components/AttaformDevtoolsPanel.vue +396 -216
  28. package/dist/runtime/components/DevtoolsValueTree.vue +176 -114
  29. package/dist/runtime/plugins/attaform.cjs +2 -2
  30. package/dist/runtime/plugins/attaform.mjs +2 -2
  31. package/dist/shared/{attaform.D32WwKk6.cjs → attaform.01iKS_lz.cjs} +260 -356
  32. package/dist/shared/attaform.01iKS_lz.cjs.map +1 -0
  33. package/dist/shared/{attaform.Y1ZGhM4k.mjs → attaform.6xE0Lcfd.mjs} +2 -2
  34. package/dist/shared/{attaform.Y1ZGhM4k.mjs.map → attaform.6xE0Lcfd.mjs.map} +1 -1
  35. package/dist/shared/{attaform.S-pYLSo4.cjs → attaform.AyujQoHp.cjs} +13 -16
  36. package/dist/shared/attaform.AyujQoHp.cjs.map +1 -0
  37. package/dist/shared/{attaform.BupwXkj_.mjs → attaform.BFWb6hDk.mjs} +29 -23
  38. package/dist/shared/attaform.BFWb6hDk.mjs.map +1 -0
  39. package/dist/shared/{attaform.NQ8mybyW.d.mts → attaform.BGwNZ9GV.d.cts} +63 -64
  40. package/dist/shared/{attaform.pmtahXKy.mjs → attaform.BKFwekY2.mjs} +257 -356
  41. package/dist/shared/attaform.BKFwekY2.mjs.map +1 -0
  42. package/dist/shared/{attaform.BSkvn43g.cjs → attaform.C-RtnCJM.cjs} +116 -47
  43. package/dist/shared/attaform.C-RtnCJM.cjs.map +1 -0
  44. package/dist/shared/{attaform.Bv7dRDWK.d.ts → attaform.CCCeEPwa.d.mts} +63 -64
  45. package/dist/shared/{attaform.BM6YD9kZ.cjs → attaform.CR6wGvNu.cjs} +29 -23
  46. package/dist/shared/attaform.CR6wGvNu.cjs.map +1 -0
  47. package/dist/shared/{attaform.Bq5sX7TF.cjs → attaform.CRzpFCjV.cjs} +2 -2
  48. package/dist/shared/{attaform.Bq5sX7TF.cjs.map → attaform.CRzpFCjV.cjs.map} +1 -1
  49. package/dist/shared/{attaform.ClXwitZj.cjs → attaform.CjMcwV7W.cjs} +894 -342
  50. package/dist/shared/attaform.CjMcwV7W.cjs.map +1 -0
  51. package/dist/shared/{attaform.DR6RmxWZ.mjs → attaform.CsB-iKbU.mjs} +888 -337
  52. package/dist/shared/attaform.CsB-iKbU.mjs.map +1 -0
  53. package/dist/shared/{attaform.BWfliRIK.d.cts → attaform.D4XYaasQ.d.ts} +63 -64
  54. package/dist/shared/{attaform.Be8NZG9M.mjs → attaform.DCjgGir_.mjs} +19 -45
  55. package/dist/shared/attaform.DCjgGir_.mjs.map +1 -0
  56. package/dist/shared/{attaform.DMEP_ENr.mjs → attaform.DNuiFCXG.mjs} +14 -17
  57. package/dist/shared/attaform.DNuiFCXG.mjs.map +1 -0
  58. package/dist/shared/{attaform.MtrpT6Ki.d.ts → attaform.DUMWQefY.d.ts} +1 -1
  59. package/dist/shared/{attaform.DozgVlCE.mjs → attaform.DgCfLqay.mjs} +116 -47
  60. package/dist/shared/attaform.DgCfLqay.mjs.map +1 -0
  61. package/dist/shared/{attaform.D0dWZsJt.d.mts → attaform.DvUH4a3o.d.cts} +307 -133
  62. package/dist/shared/{attaform.D0dWZsJt.d.cts → attaform.DvUH4a3o.d.mts} +307 -133
  63. package/dist/shared/{attaform.D0dWZsJt.d.ts → attaform.DvUH4a3o.d.ts} +307 -133
  64. package/dist/shared/{attaform.Duecg2NO.d.mts → attaform.FN0vaQAg.d.mts} +1 -1
  65. package/dist/shared/{attaform.CICFZ1iS.cjs → attaform.Q3eAD2wD.cjs} +19 -45
  66. package/dist/shared/attaform.Q3eAD2wD.cjs.map +1 -0
  67. package/dist/shared/{attaform.FudOcHaa.d.cts → attaform.aekT7mMx.d.cts} +1 -1
  68. package/dist/transforms.cjs +1 -1
  69. package/dist/transforms.mjs +1 -1
  70. package/dist/vite.cjs +1 -1
  71. package/dist/vite.mjs +1 -1
  72. package/dist/zod-v3.cjs +3 -4
  73. package/dist/zod-v3.cjs.map +1 -1
  74. package/dist/zod-v3.d.cts +4 -4
  75. package/dist/zod-v3.d.mts +4 -4
  76. package/dist/zod-v3.d.ts +4 -4
  77. package/dist/zod-v3.mjs +2 -3
  78. package/dist/zod-v3.mjs.map +1 -1
  79. package/dist/zod-v4.cjs +3 -4
  80. package/dist/zod-v4.cjs.map +1 -1
  81. package/dist/zod-v4.d.cts +4 -4
  82. package/dist/zod-v4.d.mts +4 -4
  83. package/dist/zod-v4.d.ts +4 -4
  84. package/dist/zod-v4.mjs +2 -3
  85. package/dist/zod-v4.mjs.map +1 -1
  86. package/dist/zod.cjs +6 -6
  87. package/dist/zod.cjs.map +1 -1
  88. package/dist/zod.d.cts +31 -22
  89. package/dist/zod.d.mts +31 -22
  90. package/dist/zod.d.ts +31 -22
  91. package/dist/zod.mjs +5 -6
  92. package/dist/zod.mjs.map +1 -1
  93. package/package.json +4 -12
  94. package/dist/shared/attaform.BM6YD9kZ.cjs.map +0 -1
  95. package/dist/shared/attaform.BSkvn43g.cjs.map +0 -1
  96. package/dist/shared/attaform.Be8NZG9M.mjs.map +0 -1
  97. package/dist/shared/attaform.BupwXkj_.mjs.map +0 -1
  98. package/dist/shared/attaform.CICFZ1iS.cjs.map +0 -1
  99. package/dist/shared/attaform.ClXwitZj.cjs.map +0 -1
  100. package/dist/shared/attaform.D32WwKk6.cjs.map +0 -1
  101. package/dist/shared/attaform.DMEP_ENr.mjs.map +0 -1
  102. package/dist/shared/attaform.DR6RmxWZ.mjs.map +0 -1
  103. package/dist/shared/attaform.DozgVlCE.mjs.map +0 -1
  104. package/dist/shared/attaform.S-pYLSo4.cjs.map +0 -1
  105. package/dist/shared/attaform.pmtahXKy.mjs.map +0 -1
  106. package/dist/shared/{attaform.DSD85fHb.d.cts → attaform.nf83TIR5.d.cts} +10 -10
  107. package/dist/shared/{attaform.DSD85fHb.d.mts → attaform.nf83TIR5.d.mts} +10 -10
  108. package/dist/shared/{attaform.DSD85fHb.d.ts → attaform.nf83TIR5.d.ts} +10 -10
@@ -282,125 +282,20 @@ function invokeArrayFns(fns, ...args) {
282
282
  }
283
283
  }
284
284
 
285
- function captureUserCallSite() {
286
- const raw = new Error().stack;
287
- if (typeof raw !== "string") return void 0;
288
- const lines = raw.split("\n");
289
- for (let i = 1; i < lines.length; i++) {
290
- const frame = lines[i];
291
- if (frame === void 0) continue;
292
- if (/attaform[/-]forms?/i.test(frame)) continue;
293
- if (/\bforms\.[A-Za-z0-9_-]+\.m?js\b/.test(frame)) continue;
294
- const trimmed = frame.trim();
295
- if (trimmed.length === 0) continue;
296
- return shortenSourceFrame(trimmed);
297
- }
298
- return void 0;
299
- }
300
- function shortenSourceFrame(frame) {
301
- const match = /(?:^|\s|\()([^\s()]+):(\d+):\d+\)?$/.exec(frame);
302
- if (match === null) return frame;
303
- const [, urlOrPath, line] = match;
304
- if (urlOrPath === void 0 || line === void 0) return frame;
305
- let path = urlOrPath;
306
- path = path.replace(/^[a-z]+:\/\/[^/]+\//i, "");
307
- path = path.replace(/^_nuxt\//, "");
308
- path = path.replace(/^\//, "");
309
- return `(${path}:${line})`;
310
- }
311
-
285
+ const V_REGISTER_MARKER = Symbol.for("attaform:v-register-directive");
312
286
  const REGISTER_OWNER_MARKER = Symbol.for("attaform:register-owner-marker");
313
- const warnedNoParentRV = __DEV__ ? /* @__PURE__ */ new WeakSet() : null;
314
- let warnedOutsideSetup = false;
315
- function makeRegisterValueProxy(capturedRegisterValue) {
316
- return new Proxy({}, {
317
- get(_target, prop) {
318
- if (prop === "__v_isRef") return true;
319
- if (prop === "value") return capturedRegisterValue.value;
320
- const v = capturedRegisterValue.value;
321
- if (v === void 0) return void 0;
322
- return Reflect.get(v, prop);
323
- },
324
- has(_target, prop) {
325
- if (prop === "__v_isRef" || prop === "value") return true;
326
- const v = capturedRegisterValue.value;
327
- if (v === void 0) return false;
328
- return Reflect.has(v, prop);
329
- },
330
- ownKeys(_target) {
331
- const v = capturedRegisterValue.value;
332
- if (v === void 0) return [];
333
- return Reflect.ownKeys(v);
334
- },
335
- getOwnPropertyDescriptor(_target, prop) {
336
- const v = capturedRegisterValue.value;
337
- if (v === void 0) return void 0;
338
- const desc = Reflect.getOwnPropertyDescriptor(v, prop);
339
- if (desc !== void 0) {
340
- desc.configurable = true;
341
- }
342
- return desc;
343
- }
344
- });
345
- }
346
- function useRegister() {
347
- const instance = vue.getCurrentInstance();
348
- if (instance === null) {
349
- warnOutsideSetup();
350
- return makeRegisterValueProxy(vue.shallowRef(void 0));
351
- }
352
- ensureAttaformInstalled(instance.appContext.app);
353
- const capturedRegisterValue = vue.shallowRef(void 0);
354
- const refreshAndStripBridgeAttrs = () => {
355
- const rawAttrs = instance.attrs;
356
- if ("registerValue" in rawAttrs) {
357
- capturedRegisterValue.value = rawAttrs["registerValue"];
358
- delete rawAttrs["registerValue"];
359
- } else {
360
- const dirs = instance.vnode.dirs;
361
- if (dirs !== null && dirs !== void 0) {
362
- for (const dir of dirs) {
363
- const marked = dir.dir?.[V_REGISTER_MARKER];
364
- if (marked === true) {
365
- capturedRegisterValue.value = dir.value;
366
- break;
367
- }
368
- }
369
- }
370
- }
371
- if ("value" in rawAttrs) delete rawAttrs["value"];
372
- };
373
- refreshAndStripBridgeAttrs();
374
- vue.onBeforeMount(refreshAndStripBridgeAttrs);
375
- vue.onBeforeUpdate(refreshAndStripBridgeAttrs);
376
- vue.onMounted(() => {
377
- const el = instance.vnode.el;
378
- if (el !== null && el !== void 0 && typeof el === "object") {
379
- el[REGISTER_OWNER_MARKER] = true;
380
- }
381
- if (capturedRegisterValue.value === void 0) {
382
- warnNoParentRV(instance);
383
- }
384
- });
385
- return makeRegisterValueProxy(capturedRegisterValue);
386
- }
387
- function warnOutsideSetup() {
388
- if (!__DEV__) return;
389
- if (warnedOutsideSetup) return;
390
- warnedOutsideSetup = true;
391
- const frame = captureUserCallSite();
392
- console.warn(
393
- `[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}` : "")
394
- );
287
+ function isRegisterValue(val) {
288
+ if (typeof val !== "object" || val === null) return false;
289
+ if (!("innerRef" in val)) return false;
290
+ if (!vue.isRef(val.innerRef)) return false;
291
+ if (!("registerElement" in val)) return false;
292
+ if (typeof val.registerElement !== "function") return false;
293
+ if (!("setValueWithInternalPath" in val)) return false;
294
+ if (typeof val.setValueWithInternalPath !== "function") return false;
295
+ return true;
395
296
  }
396
- function warnNoParentRV(instance) {
397
- if (!__DEV__ || warnedNoParentRV === null) return;
398
- if (warnedNoParentRV.has(instance)) return;
399
- warnedNoParentRV.add(instance);
400
- const frame = captureUserCallSite();
401
- console.warn(
402
- `[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}` : "")
403
- );
297
+ function isTransforming(value) {
298
+ return isRegisterValue(value) && value.transforming;
404
299
  }
405
300
 
406
301
  const MANAGED_ARIA_ATTRS = [
@@ -511,6 +406,199 @@ function isRegisterValueLike(val) {
511
406
  return typeof val === "object" && val !== null && "markInteracted" in val && typeof val.markInteracted === "function";
512
407
  }
513
408
 
409
+ const assignKey = Symbol.for("attaform:assign-key");
410
+ const DEFAULT_ASSIGNER_TAG = Symbol.for("attaform:default-assigner-tag");
411
+ function isDefaultAssigner(fn) {
412
+ return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
413
+ }
414
+ const CONSUMER_WRAPPED_TAG = Symbol.for("attaform:consumer-wrapped-assigner");
415
+ function isConsumerWrapped(fn) {
416
+ return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
417
+ }
418
+ function fireAssigner(el, registerValue, value) {
419
+ const fn = el[assignKey];
420
+ if (fn === void 0) return void 0;
421
+ if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
422
+ return fn(value);
423
+ }
424
+ if (!isRegisterValue(registerValue)) {
425
+ return fn(value, void 0);
426
+ }
427
+ return wrapWithTransforms(
428
+ value,
429
+ registerValue,
430
+ (coerced) => fn(coerced, registerValue),
431
+ void 0
432
+ );
433
+ }
434
+ function isThenable(x) {
435
+ return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
436
+ }
437
+ function makeTransformContext() {
438
+ const holder = { controller: null, aborted: false };
439
+ const ctx = {
440
+ get signal() {
441
+ if (holder.controller === null) {
442
+ holder.controller = new AbortController();
443
+ if (holder.aborted) holder.controller.abort();
444
+ }
445
+ return holder.controller.signal;
446
+ }
447
+ };
448
+ return { ctx, holder };
449
+ }
450
+ function runTransforms(initial, registerValue) {
451
+ const transforms = registerValue.transforms;
452
+ if (transforms === void 0 || transforms.length === 0) {
453
+ return { kind: "sync", ok: true, value: initial };
454
+ }
455
+ const { ctx, holder } = makeTransformContext();
456
+ let v = initial;
457
+ for (let i = 0; i < transforms.length; i++) {
458
+ const fn = transforms[i];
459
+ let out;
460
+ try {
461
+ out = fn(v, ctx);
462
+ } catch (err) {
463
+ logTransformFailure(registerValue.path, i, fn, err);
464
+ return { kind: "sync", ok: false };
465
+ }
466
+ if (isThenable(out)) {
467
+ const rest = transforms.slice(i + 1);
468
+ const seed = out;
469
+ const run = () => rest.reduce(
470
+ (acc, next) => acc.then((value) => next(value, ctx)),
471
+ Promise.resolve(seed)
472
+ );
473
+ return { kind: "async", run, holder };
474
+ }
475
+ v = out;
476
+ }
477
+ return { kind: "sync", ok: true, value: v };
478
+ }
479
+ function kickoffAsyncTransform(rv, holder, run, commit, syncDom) {
480
+ const token = rv.beginTransform(holder);
481
+ void run().then(
482
+ (value) => {
483
+ const live = rv.isCurrentTransform(token);
484
+ rv.endTransform(token);
485
+ if (!live) return;
486
+ const coerced = applyCoerce(value, rv);
487
+ const wrote = commit(coerced);
488
+ if (wrote === false) rv.setTransformError(transformGateRejectedError(rv.path));
489
+ else syncDom?.();
490
+ },
491
+ (err) => {
492
+ if (rv.isCurrentTransform(token)) rv.setTransformError(toTransformError(err));
493
+ rv.endTransform(token);
494
+ }
495
+ );
496
+ }
497
+ function logTransformFailure(path, index, fn, err) {
498
+ if (__DEV__) {
499
+ const namePart = fn.name !== "" ? `, '${fn.name}'` : "";
500
+ console.error(
501
+ `[attaform] transform threw for path '${path}' (index ${index}${namePart}) \u2014 write aborted. Transforms must not throw; wrap your own try/catch if the throw is recoverable. Original error:`,
502
+ err
503
+ );
504
+ } else {
505
+ console.error(
506
+ `[attaform] transform error \u2014 write aborted (set NODE_ENV=development for details).`
507
+ );
508
+ }
509
+ }
510
+ function applyCoerce(value, registerValue) {
511
+ return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
512
+ }
513
+ function wrapWithTransforms(value, registerValue, commit, syncDom) {
514
+ const r = runTransforms(value, registerValue);
515
+ if (r.kind === "async") {
516
+ kickoffAsyncTransform(registerValue, r.holder, r.run, commit, syncDom);
517
+ return true;
518
+ }
519
+ if (!r.ok) return false;
520
+ const coerced = applyCoerce(r.value, registerValue);
521
+ return commit(coerced);
522
+ }
523
+ function toTransformError(value) {
524
+ if (value instanceof Error) return value;
525
+ const message = typeof value === "string" && value.length > 0 ? value : `Transform rejected with a non-Error value (${typeof value})`;
526
+ return new Error(message, { cause: value });
527
+ }
528
+ function transformGateRejectedError(path) {
529
+ return new Error(
530
+ `[attaform] transform result for path '${path}' was rejected by the field's type gate (the resolved value did not fit the schema slot).`
531
+ );
532
+ }
533
+ const getModelAssigner = (el, vnode, registerValue) => {
534
+ const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
535
+ if (isArray(fn)) {
536
+ const fnArr = fn.filter((x) => isFunction(x));
537
+ const wrapped = (value) => {
538
+ return wrapWithTransforms(
539
+ value,
540
+ registerValue,
541
+ (coerced) => {
542
+ invokeArrayFns(fnArr, coerced, registerValue);
543
+ return void 0;
544
+ },
545
+ void 0
546
+ );
547
+ };
548
+ wrapped[CONSUMER_WRAPPED_TAG] = true;
549
+ return wrapped;
550
+ }
551
+ if (isFunction(fn)) {
552
+ const handler = fn;
553
+ const wrapped = (value) => {
554
+ return wrapWithTransforms(
555
+ value,
556
+ registerValue,
557
+ (coerced) => handler(coerced, registerValue),
558
+ void 0
559
+ );
560
+ };
561
+ wrapped[CONSUMER_WRAPPED_TAG] = true;
562
+ return wrapped;
563
+ }
564
+ const defaultAssigner = (value) => {
565
+ if (value === void 0 && registerValue.acceptsUndefined) {
566
+ return registerValue.setValueWithInternalPath(void 0);
567
+ }
568
+ return wrapWithTransforms(
569
+ value,
570
+ registerValue,
571
+ (coerced) => registerValue.setValueWithInternalPath(coerced),
572
+ el._syncFromStorage
573
+ );
574
+ };
575
+ defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
576
+ return defaultAssigner;
577
+ };
578
+ function makeNoopAssigner() {
579
+ const noop = (_) => void 0;
580
+ noop[DEFAULT_ASSIGNER_TAG] = true;
581
+ return noop;
582
+ }
583
+ function setAssignFunction(el, vnode, value) {
584
+ const current = el[assignKey];
585
+ if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
586
+ return;
587
+ }
588
+ if (value === void 0) {
589
+ el[assignKey] = makeNoopAssigner();
590
+ return;
591
+ }
592
+ if (!isRegisterValue(value)) {
593
+ vue.warn(
594
+ `v-register expected a RegisterValue, got '${typeof value}'. Bind to form.register('field') \u2014 not the field's ref, value, or path string.`
595
+ );
596
+ el[assignKey] = makeNoopAssigner();
597
+ return;
598
+ }
599
+ el[assignKey] = getModelAssigner(el, vnode, value);
600
+ }
601
+
514
602
  function isBlankFileValue(value) {
515
603
  if (value === null || value === void 0) return true;
516
604
  if (Array.isArray(value) && value.length === 0) return true;
@@ -887,220 +975,16 @@ function teardownValueSync(el) {
887
975
 
888
976
  const INTERACTIVE_TAG_NAMES = /* @__PURE__ */ new Set(["INPUT", "SELECT", "TEXTAREA"]);
889
977
 
890
- const assignKey = Symbol.for("attaform:assign-key");
891
- function isRegisterValue(val) {
892
- if (typeof val !== "object" || val === null) return false;
893
- if (!("innerRef" in val)) return false;
894
- if (!vue.isRef(val.innerRef)) return false;
895
- if (!("registerElement" in val)) return false;
896
- if (typeof val.registerElement !== "function") return false;
897
- if (!("setValueWithInternalPath" in val)) return false;
898
- if (typeof val.setValueWithInternalPath !== "function") return false;
899
- return true;
900
- }
901
978
  function writeLastTypedForm(rv, next) {
902
979
  rv.lastTypedForm.value = next;
903
980
  }
904
- const DEFAULT_ASSIGNER_TAG = Symbol.for("attaform:default-assigner-tag");
905
- function isDefaultAssigner(fn) {
906
- return typeof fn === "function" && fn[DEFAULT_ASSIGNER_TAG] === true;
907
- }
908
- const CONSUMER_WRAPPED_TAG = Symbol.for("attaform:consumer-wrapped-assigner");
909
- function isConsumerWrapped(fn) {
910
- return typeof fn === "function" && fn[CONSUMER_WRAPPED_TAG] === true;
911
- }
912
- function fireAssigner(el, registerValue, value) {
913
- const fn = el[assignKey];
914
- if (fn === void 0) return void 0;
915
- if (isDefaultAssigner(fn) || isConsumerWrapped(fn)) {
916
- return fn(value);
917
- }
918
- if (!isRegisterValue(registerValue)) {
919
- return fn(value, void 0);
920
- }
921
- const r = runTransforms(value, registerValue);
922
- if (r.kind === "async") {
923
- kickoffAsyncTransform(
924
- registerValue,
925
- r.holder,
926
- r.run,
927
- (coerced2) => fn(coerced2, registerValue),
928
- void 0
929
- );
930
- return true;
931
- }
932
- if (!r.ok) return false;
933
- const coerced = applyCoerce(r.value, registerValue);
934
- return fn(coerced, registerValue);
935
- }
936
981
  function shouldBailListener(el) {
937
982
  if (INTERACTIVE_TAG_NAMES.has(el.tagName)) return false;
938
983
  return isDefaultAssigner(el[assignKey]);
939
984
  }
940
- function isThenable(x) {
941
- return x !== null && (typeof x === "object" || typeof x === "function") && typeof x.then === "function";
942
- }
943
- function makeTransformContext() {
944
- const holder = { controller: null, aborted: false };
945
- const ctx = {
946
- get signal() {
947
- if (holder.controller === null) {
948
- holder.controller = new AbortController();
949
- if (holder.aborted) holder.controller.abort();
950
- }
951
- return holder.controller.signal;
952
- }
953
- };
954
- return { ctx, holder };
955
- }
956
- function runTransforms(initial, registerValue) {
957
- const transforms = registerValue.transforms;
958
- if (transforms === void 0 || transforms.length === 0) {
959
- return { kind: "sync", ok: true, value: initial };
960
- }
961
- const { ctx, holder } = makeTransformContext();
962
- let v = initial;
963
- for (let i = 0; i < transforms.length; i++) {
964
- const fn = transforms[i];
965
- let out;
966
- try {
967
- out = fn(v, ctx);
968
- } catch (err) {
969
- logTransformFailure(registerValue.path, i, fn, err);
970
- return { kind: "sync", ok: false };
971
- }
972
- if (isThenable(out)) {
973
- const rest = transforms.slice(i + 1);
974
- const seed = out;
975
- const run = () => rest.reduce(
976
- (acc, next) => acc.then((value) => next(value, ctx)),
977
- Promise.resolve(seed)
978
- );
979
- return { kind: "async", run, holder };
980
- }
981
- v = out;
982
- }
983
- return { kind: "sync", ok: true, value: v };
984
- }
985
- function kickoffAsyncTransform(rv, holder, run, commit, syncDom) {
986
- const token = rv.beginTransform(holder);
987
- void run().then(
988
- (value) => {
989
- const live = rv.isCurrentTransform(token);
990
- rv.endTransform(token);
991
- if (!live) return;
992
- const coerced = applyCoerce(value, rv);
993
- const wrote = commit(coerced);
994
- if (wrote === false) rv.setTransformError(transformGateRejectedError(rv.path));
995
- else syncDom?.();
996
- },
997
- (err) => {
998
- if (rv.isCurrentTransform(token)) rv.setTransformError(toTransformError(err));
999
- rv.endTransform(token);
1000
- }
1001
- );
1002
- }
1003
- function logTransformFailure(path, index, fn, err) {
1004
- if (__DEV__) {
1005
- const namePart = fn.name !== "" ? `, '${fn.name}'` : "";
1006
- console.error(
1007
- `[attaform] transform threw for path '${path}' (index ${index}${namePart}) \u2014 write aborted. Transforms must not throw; wrap your own try/catch if the throw is recoverable. Original error:`,
1008
- err
1009
- );
1010
- } else {
1011
- console.error(
1012
- `[attaform] transform error \u2014 write aborted (set NODE_ENV=development for details).`
1013
- );
1014
- }
1015
- }
1016
- function applyCoerce(value, registerValue) {
1017
- return registerValue.coerce !== void 0 ? registerValue.coerce(value) : value;
1018
- }
1019
985
  function applyElementCoerce(value, registerValue) {
1020
986
  return registerValue.coerceElement !== void 0 ? registerValue.coerceElement(value) : value;
1021
987
  }
1022
- function toTransformError(value) {
1023
- if (value instanceof Error) return value;
1024
- const message = typeof value === "string" && value.length > 0 ? value : `Transform rejected with a non-Error value (${typeof value})`;
1025
- return new Error(message, { cause: value });
1026
- }
1027
- function transformGateRejectedError(path) {
1028
- return new Error(
1029
- `[attaform] transform result for path '${path}' was rejected by the field's type gate (the resolved value did not fit the schema slot).`
1030
- );
1031
- }
1032
- function isTransforming(value) {
1033
- return isRegisterValue(value) && value.transforming;
1034
- }
1035
- const getModelAssigner = (el, vnode, registerValue) => {
1036
- const fn = vnode.props?.["onUpdate:registerValue"] ?? vnode.props?.["on:update:registerValue"];
1037
- if (isArray(fn)) {
1038
- const fnArr = fn.filter((x) => isFunction(x));
1039
- const wrapped = (value) => {
1040
- const r = runTransforms(value, registerValue);
1041
- if (r.kind === "async") {
1042
- kickoffAsyncTransform(
1043
- registerValue,
1044
- r.holder,
1045
- r.run,
1046
- (coerced2) => {
1047
- invokeArrayFns(fnArr, coerced2, registerValue);
1048
- },
1049
- void 0
1050
- );
1051
- return true;
1052
- }
1053
- if (!r.ok) return false;
1054
- const coerced = applyCoerce(r.value, registerValue);
1055
- invokeArrayFns(fnArr, coerced, registerValue);
1056
- return void 0;
1057
- };
1058
- wrapped[CONSUMER_WRAPPED_TAG] = true;
1059
- return wrapped;
1060
- }
1061
- if (isFunction(fn)) {
1062
- const handler = fn;
1063
- const wrapped = (value) => {
1064
- const r = runTransforms(value, registerValue);
1065
- if (r.kind === "async") {
1066
- kickoffAsyncTransform(
1067
- registerValue,
1068
- r.holder,
1069
- r.run,
1070
- (coerced2) => handler(coerced2, registerValue),
1071
- void 0
1072
- );
1073
- return true;
1074
- }
1075
- if (!r.ok) return false;
1076
- const coerced = applyCoerce(r.value, registerValue);
1077
- return handler(coerced, registerValue);
1078
- };
1079
- wrapped[CONSUMER_WRAPPED_TAG] = true;
1080
- return wrapped;
1081
- }
1082
- const defaultAssigner = (value) => {
1083
- if (value === void 0 && registerValue.acceptsUndefined) {
1084
- return registerValue.setValueWithInternalPath(void 0);
1085
- }
1086
- const r = runTransforms(value, registerValue);
1087
- if (r.kind === "async") {
1088
- kickoffAsyncTransform(
1089
- registerValue,
1090
- r.holder,
1091
- r.run,
1092
- (coerced2) => registerValue.setValueWithInternalPath(coerced2),
1093
- el._syncFromStorage
1094
- );
1095
- return true;
1096
- }
1097
- if (!r.ok) return false;
1098
- const coerced = applyCoerce(r.value, registerValue);
1099
- return registerValue.setValueWithInternalPath(coerced);
1100
- };
1101
- defaultAssigner[DEFAULT_ASSIGNER_TAG] = true;
1102
- return defaultAssigner;
1103
- };
1104
988
  function onCompositionStart(e) {
1105
989
  const target = e.target;
1106
990
  if (!target) return;
@@ -1113,29 +997,6 @@ function onCompositionEnd(e) {
1113
997
  target.dispatchEvent(new Event("input"));
1114
998
  }
1115
999
  }
1116
- function makeNoopAssigner() {
1117
- const noop = (_) => void 0;
1118
- noop[DEFAULT_ASSIGNER_TAG] = true;
1119
- return noop;
1120
- }
1121
- function setAssignFunction(el, vnode, value) {
1122
- const current = el[assignKey];
1123
- if (current !== void 0 && !isDefaultAssigner(current) && !isConsumerWrapped(current)) {
1124
- return;
1125
- }
1126
- if (value === void 0) {
1127
- el[assignKey] = makeNoopAssigner();
1128
- return;
1129
- }
1130
- if (!isRegisterValue(value)) {
1131
- vue.warn(
1132
- `v-register expected a RegisterValue, got '${typeof value}'. Bind to form.register('field') \u2014 not the field's ref, value, or path string.`
1133
- );
1134
- el[assignKey] = makeNoopAssigner();
1135
- return;
1136
- }
1137
- el[assignKey] = getModelAssigner(el, vnode, value);
1138
- }
1139
1000
  const vRegisterText = {
1140
1001
  created(el, { value, modifiers: { lazy, trim, number } }, vnode) {
1141
1002
  const castToNumberAtCreated = number === true || vnode.props?.["type"] === "number";
@@ -1598,6 +1459,9 @@ const vRegisterDynamic = {
1598
1459
  syncMultiTabOptOut(binding.value, void 0);
1599
1460
  callModelHook(el, binding, vnode, null, "created");
1600
1461
  if (isRegisterValue(binding.value)) setupAria(el, binding.value, vnode);
1462
+ },
1463
+ mounted(el, binding, vnode) {
1464
+ callModelHook(el, binding, vnode, null, "mounted");
1601
1465
  if (__DEV__ && warnedUnsupportedElements !== null && !INTERACTIVE_TAG_NAMES.has(el.tagName) && !warnedUnsupportedElements.has(el)) {
1602
1466
  void vue.nextTick(() => {
1603
1467
  if (warnedUnsupportedElements.has(el)) return;
@@ -1613,9 +1477,6 @@ const vRegisterDynamic = {
1613
1477
  });
1614
1478
  }
1615
1479
  },
1616
- mounted(el, binding, vnode) {
1617
- callModelHook(el, binding, vnode, null, "mounted");
1618
- },
1619
1480
  beforeUpdate(el, binding, vnode, prevVNode) {
1620
1481
  syncPersistOptIn(el, binding.value, binding.oldValue, vnode.props?.["type"]);
1621
1482
  syncMultiTabOptOut(binding.value, binding.oldValue);
@@ -1665,7 +1526,11 @@ const vRegisterDynamic = {
1665
1526
  getSSRProps(binding, vnode) {
1666
1527
  const rv = binding.value;
1667
1528
  if (!isRegisterValue(rv)) return void 0;
1668
- return getSSRAriaProps(rv, vnode ?? null);
1529
+ const realVnode = vnode ?? null;
1530
+ const ariaProps = getSSRAriaProps(rv, realVnode);
1531
+ const formStateProps = realVnode !== null ? getSSRFormStateProps(rv, realVnode) : void 0;
1532
+ if (ariaProps === void 0 && formStateProps === void 0) return void 0;
1533
+ return { ...ariaProps, ...formStateProps };
1669
1534
  }
1670
1535
  };
1671
1536
  function resolveDynamicModel(tagName, type) {
@@ -1677,12 +1542,38 @@ function resolveDynamicModel(tagName, type) {
1677
1542
  if (type === "radio") return vRegisterRadio;
1678
1543
  return vRegisterText;
1679
1544
  }
1545
+ function ssrCheckboxProps(rv, props) {
1546
+ const model = rv.innerRef.value;
1547
+ const optionValue = props?.["value"];
1548
+ let checked;
1549
+ if (isArray(model)) {
1550
+ checked = looseIndexOf(model, applyElementCoerce(optionValue, rv)) > -1;
1551
+ } else if (isSet(model)) {
1552
+ checked = model.has(applyElementCoerce(optionValue, rv));
1553
+ } else {
1554
+ const trueValue = props !== null && "true-value" in props ? props["true-value"] : true;
1555
+ checked = looseEqual(model, applyCoerce(trueValue, rv));
1556
+ }
1557
+ return checked ? { checked: "" } : void 0;
1558
+ }
1559
+ function getSSRFormStateProps(rv, vnode) {
1560
+ if (typeof vnode.type !== "string") return void 0;
1561
+ const props = vnode.props ?? null;
1562
+ const variant = resolveDynamicModel(vnode.type.toUpperCase(), props?.["type"]);
1563
+ if (variant === vRegisterFile || variant === vRegisterSelect) return void 0;
1564
+ if (variant === vRegisterCheckbox) return ssrCheckboxProps(rv, props);
1565
+ if (variant === vRegisterRadio) {
1566
+ const matches = looseEqual(rv.innerRef.value, applyCoerce(props?.["value"], rv));
1567
+ return matches ? { checked: "" } : void 0;
1568
+ }
1569
+ const value = rv.displayValue.value;
1570
+ return value === "" ? void 0 : { value };
1571
+ }
1680
1572
  function callModelHook(el, binding, vnode, prevVNode, hook) {
1681
1573
  const modelToUse = resolveDynamicModel(el.tagName, vnode.props?.["type"]);
1682
1574
  const fn = modelToUse[hook];
1683
1575
  fn?.(el, binding, vnode, prevVNode);
1684
1576
  }
1685
- const V_REGISTER_MARKER = Symbol.for("attaform:v-register-directive");
1686
1577
  const vRegister = vRegisterDynamic;
1687
1578
  vRegisterDynamic[V_REGISTER_MARKER] = true;
1688
1579
 
@@ -1781,17 +1672,20 @@ function canonicalizePath(input) {
1781
1672
  if (typeof input === "string") {
1782
1673
  const cached = canonicalStringCache.get(input);
1783
1674
  if (cached !== void 0) return cached;
1784
- const segments2 = parseDottedPath(input);
1785
- const key2 = JSON.stringify(segments2);
1786
- const entry = { segments: segments2, key: key2 };
1675
+ const segments = parseDottedPath(input);
1676
+ const key = JSON.stringify(segments);
1677
+ const entry = { segments, key };
1787
1678
  if (canonicalStringCache.size >= CANONICAL_STRING_CACHE_MAX) {
1788
1679
  const oldest = canonicalStringCache.keys().next().value;
1789
1680
  if (oldest !== void 0) canonicalStringCache.delete(oldest);
1790
1681
  }
1791
1682
  canonicalStringCache.set(input, entry);
1792
- rememberSegmentsForPathKey(key2, segments2);
1683
+ rememberSegmentsForPathKey(key, segments);
1793
1684
  return entry;
1794
1685
  }
1686
+ return keyForSegments(input);
1687
+ }
1688
+ function keyForSegments(input) {
1795
1689
  const segments = Array.from(input).map(normalizeSegment);
1796
1690
  const key = JSON.stringify(segments);
1797
1691
  rememberSegmentsForPathKey(key, segments);
@@ -1828,6 +1722,13 @@ function isPathPrefix(prefix, path) {
1828
1722
  }
1829
1723
  return true;
1830
1724
  }
1725
+ function pathsEqual(a, b) {
1726
+ if (a.length !== b.length) return false;
1727
+ for (let i = 0; i < a.length; i++) {
1728
+ if (a[i] !== b[i]) return false;
1729
+ }
1730
+ return true;
1731
+ }
1831
1732
 
1832
1733
  exports.AnonPersistError = AnonPersistError;
1833
1734
  exports.AttaformError = AttaformError;
@@ -1838,16 +1739,17 @@ exports.INTERACTIVE_TAG_NAMES = INTERACTIVE_TAG_NAMES;
1838
1739
  exports.InvalidPathError = InvalidPathError;
1839
1740
  exports.InvalidUseFormConfigError = InvalidUseFormConfigError;
1840
1741
  exports.OutsideSetupError = OutsideSetupError;
1742
+ exports.REGISTER_OWNER_MARKER = REGISTER_OWNER_MARKER;
1841
1743
  exports.ROOT_PATH = ROOT_PATH;
1842
1744
  exports.ROOT_PATH_KEY = ROOT_PATH_KEY;
1843
1745
  exports.RegistryNotInstalledError = RegistryNotInstalledError;
1844
1746
  exports.ReservedFormKeyError = ReservedFormKeyError;
1845
1747
  exports.SubmitErrorHandlerError = SubmitErrorHandlerError;
1748
+ exports.V_REGISTER_MARKER = V_REGISTER_MARKER;
1846
1749
  exports.__DEV__ = __DEV__;
1847
1750
  exports.allowSensitivePersist = allowSensitivePersist;
1848
1751
  exports.assignKey = assignKey;
1849
1752
  exports.canonicalizePath = canonicalizePath;
1850
- exports.captureUserCallSite = captureUserCallSite;
1851
1753
  exports.coerceToPathKey = coerceToPathKey;
1852
1754
  exports.createAttaform = createAttaform;
1853
1755
  exports.createIsSensitivePath = createIsSensitivePath;
@@ -1864,11 +1766,13 @@ exports.kAttaformRegistry = kAttaformRegistry;
1864
1766
  exports.kAttaformWizardActiveStepResolver = kAttaformWizardActiveStepResolver;
1865
1767
  exports.kFormContext = kFormContext;
1866
1768
  exports.kFormInstanceId = kFormInstanceId;
1769
+ exports.keyForSegments = keyForSegments;
1867
1770
  exports.parseDottedPath = parseDottedPath;
1868
1771
  exports.pathKeyToDotted = pathKeyToDotted;
1772
+ exports.pathsEqual = pathsEqual;
1869
1773
  exports.segmentsForPathKey = segmentsForPathKey;
1774
+ exports.segmentsToDotted = segmentsToDotted;
1870
1775
  exports.toError = toError;
1871
- exports.useRegister = useRegister;
1872
1776
  exports.useRegistry = useRegistry;
1873
1777
  exports.vRegister = vRegister;
1874
- //# sourceMappingURL=attaform.D32WwKk6.cjs.map
1778
+ //# sourceMappingURL=attaform.01iKS_lz.cjs.map