attaform 0.21.2 → 0.23.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 (101) hide show
  1. package/README.md +7 -10
  2. package/dist/chunks/dev-key-collision-warnings.cjs +0 -33
  3. package/dist/chunks/dev-key-collision-warnings.cjs.map +1 -1
  4. package/dist/chunks/dev-key-collision-warnings.mjs +1 -33
  5. package/dist/chunks/dev-key-collision-warnings.mjs.map +1 -1
  6. package/dist/chunks/devtools.cjs +3 -5
  7. package/dist/chunks/devtools.cjs.map +1 -1
  8. package/dist/chunks/devtools.mjs +3 -5
  9. package/dist/chunks/devtools.mjs.map +1 -1
  10. package/dist/chunks/fingerprint2.cjs +1 -1
  11. package/dist/chunks/fingerprint2.mjs +1 -1
  12. package/dist/index.cjs +3 -5
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +6 -41
  15. package/dist/index.d.mts +6 -41
  16. package/dist/index.d.ts +6 -41
  17. package/dist/index.mjs +5 -5
  18. package/dist/nuxt.d.cts +1 -1
  19. package/dist/nuxt.d.mts +1 -1
  20. package/dist/nuxt.d.ts +1 -1
  21. package/dist/runtime/components/AttaformDevtoolsPanel.vue +3 -11
  22. package/dist/runtime/plugins/attaform.cjs +2 -2
  23. package/dist/runtime/plugins/attaform.mjs +2 -2
  24. package/dist/shared/{attaform.BGf_J22U.d.ts → attaform.BGMRvckW.d.ts} +11 -70
  25. package/dist/shared/{attaform.ory-3WhV.d.mts → attaform.BJnNK75Y.d.cts} +41 -491
  26. package/dist/shared/{attaform.ory-3WhV.d.ts → attaform.BJnNK75Y.d.mts} +41 -491
  27. package/dist/shared/{attaform.ory-3WhV.d.cts → attaform.BJnNK75Y.d.ts} +41 -491
  28. package/dist/shared/{attaform.DP-u7_tk.mjs → attaform.BhI9Icek.mjs} +17 -291
  29. package/dist/shared/attaform.BhI9Icek.mjs.map +1 -0
  30. package/dist/shared/{attaform.BwLp9KM7.cjs → attaform.BibT5AS_.cjs} +2 -2
  31. package/dist/shared/{attaform.BwLp9KM7.cjs.map → attaform.BibT5AS_.cjs.map} +1 -1
  32. package/dist/shared/{attaform.DkA5J8NW.d.cts → attaform.CO0e7YVY.d.cts} +1 -46
  33. package/dist/shared/{attaform.DkA5J8NW.d.ts → attaform.CO0e7YVY.d.mts} +1 -46
  34. package/dist/shared/{attaform.DkA5J8NW.d.mts → attaform.CO0e7YVY.d.ts} +1 -46
  35. package/dist/shared/{attaform.BwrowMp2.cjs → attaform.CaYj3ZfY.cjs} +3 -3
  36. package/dist/shared/{attaform.BwrowMp2.cjs.map → attaform.CaYj3ZfY.cjs.map} +1 -1
  37. package/dist/shared/{attaform.BBDIKtKY.cjs → attaform.Cmb_LCie.cjs} +4 -4
  38. package/dist/shared/{attaform.BVeLgfEh.mjs.map → attaform.Cmb_LCie.cjs.map} +1 -1
  39. package/dist/shared/{attaform.CTheKoTc.mjs → attaform.CtJOd7ox.mjs} +446 -525
  40. package/dist/shared/attaform.CtJOd7ox.mjs.map +1 -0
  41. package/dist/shared/{attaform.CrD73S4m.mjs → attaform.CzVta5o2.mjs} +116 -47
  42. package/dist/shared/attaform.CzVta5o2.mjs.map +1 -0
  43. package/dist/shared/{attaform.CnEl--PF.d.mts → attaform.D52oJiYC.d.cts} +1 -1
  44. package/dist/shared/{attaform.BoY6RZUl.d.cts → attaform.DCkSNnPr.d.mts} +1 -1
  45. package/dist/shared/{attaform.B5LNzqQh.cjs → attaform.Db4E4IW6.cjs} +18 -297
  46. package/dist/shared/attaform.Db4E4IW6.cjs.map +1 -0
  47. package/dist/shared/{attaform.CcnF1AKJ.cjs → attaform.DbyTD8N2.cjs} +116 -47
  48. package/dist/shared/attaform.DbyTD8N2.cjs.map +1 -0
  49. package/dist/shared/{attaform.D6GYGshL.mjs → attaform.Dd1Kmmaj.mjs} +3 -3
  50. package/dist/shared/{attaform.D6GYGshL.mjs.map → attaform.Dd1Kmmaj.mjs.map} +1 -1
  51. package/dist/shared/{attaform.BCcrLApm.d.mts → attaform.DrY8srOp.d.mts} +11 -70
  52. package/dist/shared/{attaform.D2ZuIOCf.cjs → attaform.DsQkXE3o.cjs} +445 -534
  53. package/dist/shared/attaform.DsQkXE3o.cjs.map +1 -0
  54. package/dist/shared/{attaform.BkjJfMvJ.d.cts → attaform.DuPneYR0.d.cts} +11 -70
  55. package/dist/shared/{attaform.C41gjp-a.mjs → attaform.Dx9-QQE2.mjs} +2 -2
  56. package/dist/shared/{attaform.C41gjp-a.mjs.map → attaform.Dx9-QQE2.mjs.map} +1 -1
  57. package/dist/shared/{attaform.BYgioWLF.d.ts → attaform.WEwfXcHq.d.ts} +1 -1
  58. package/dist/shared/{attaform.BVeLgfEh.mjs → attaform.alpG7rT7.mjs} +4 -4
  59. package/dist/shared/{attaform.BBDIKtKY.cjs.map → attaform.alpG7rT7.mjs.map} +1 -1
  60. package/dist/zod-v3.cjs +2 -2
  61. package/dist/zod-v3.d.cts +3 -3
  62. package/dist/zod-v3.d.mts +3 -3
  63. package/dist/zod-v3.d.ts +3 -3
  64. package/dist/zod-v3.mjs +2 -2
  65. package/dist/zod-v4.cjs +2 -2
  66. package/dist/zod-v4.d.cts +5 -5
  67. package/dist/zod-v4.d.mts +5 -5
  68. package/dist/zod-v4.d.ts +5 -5
  69. package/dist/zod-v4.mjs +2 -2
  70. package/dist/zod.cjs +5 -5
  71. package/dist/zod.d.cts +5 -5
  72. package/dist/zod.d.mts +5 -5
  73. package/dist/zod.d.ts +5 -5
  74. package/dist/zod.mjs +5 -5
  75. package/package.json +2 -2
  76. package/dist/chunks/indexeddb.cjs +0 -119
  77. package/dist/chunks/indexeddb.cjs.map +0 -1
  78. package/dist/chunks/indexeddb.mjs +0 -117
  79. package/dist/chunks/indexeddb.mjs.map +0 -1
  80. package/dist/chunks/local-storage.cjs +0 -58
  81. package/dist/chunks/local-storage.cjs.map +0 -1
  82. package/dist/chunks/local-storage.mjs +0 -56
  83. package/dist/chunks/local-storage.mjs.map +0 -1
  84. package/dist/chunks/multi-tab-sync.cjs +0 -367
  85. package/dist/chunks/multi-tab-sync.cjs.map +0 -1
  86. package/dist/chunks/multi-tab-sync.mjs +0 -364
  87. package/dist/chunks/multi-tab-sync.mjs.map +0 -1
  88. package/dist/chunks/session-storage.cjs +0 -58
  89. package/dist/chunks/session-storage.cjs.map +0 -1
  90. package/dist/chunks/session-storage.mjs +0 -56
  91. package/dist/chunks/session-storage.mjs.map +0 -1
  92. package/dist/chunks/wire-persistence.cjs +0 -396
  93. package/dist/chunks/wire-persistence.cjs.map +0 -1
  94. package/dist/chunks/wire-persistence.mjs +0 -394
  95. package/dist/chunks/wire-persistence.mjs.map +0 -1
  96. package/dist/shared/attaform.B5LNzqQh.cjs.map +0 -1
  97. package/dist/shared/attaform.CTheKoTc.mjs.map +0 -1
  98. package/dist/shared/attaform.CcnF1AKJ.cjs.map +0 -1
  99. package/dist/shared/attaform.CrD73S4m.mjs.map +0 -1
  100. package/dist/shared/attaform.D2ZuIOCf.cjs.map +0 -1
  101. package/dist/shared/attaform.DP-u7_tk.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { F as FormKey, _ as PathKey, p as DisplayCtx, d as GetDisplayState, q as DisplayMachine, Z as Path, ah as SlimPrimitiveKind, C as CoercionEntry, j as CoercionRegistry, G as GenericForm, V as ValidationError, a as AbstractSchema, aq as WriteMeta, m as DeepPartial, ar as WriteShape, ay as TransformAbortHolder, al as ValidateOn, az as PersistOptInRegistry, A as AttaformDefaults, b as UseFormReturnType, c as RegisterValue } from './attaform.ory-3WhV.cjs';
1
+ import { F as FormKey, Y as PathKey, p as DisplayCtx, d as GetDisplayState, q as DisplayMachine, X as Path, ac as SlimPrimitiveKind, C as CoercionEntry, j as CoercionRegistry, G as GenericForm, V as ValidationError, a as AbstractSchema, al as WriteMeta, m as DeepPartial, am as WriteShape, at as TransformAbortHolder, ag as ValidateOn, A as AttaformDefaults, b as UseFormReturnType, c as RegisterValue } from './attaform.BJnNK75Y.cjs';
2
2
  import { Ref, ComputedRef, App, InjectionKey } from 'vue';
3
3
 
4
4
  /**
@@ -967,17 +967,13 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
967
967
  /**
968
968
  * Replace the form value wholesale. Optional `meta` is forwarded to
969
969
  * every `onFormChange` listener so they can decide whether THIS write
970
- * is one they care about most importantly, the persistence layer
971
- * only writes when `meta?.persist === true`. Internal callers that
972
- * don't pass meta default to no-persist.
970
+ * is one they care about (e.g. history tagging a hydration replay).
973
971
  */
974
972
  applyFormReplacement(next: F, meta?: WriteMeta): void;
975
973
  /**
976
974
  * Set a single path's value. `meta` is forwarded to listeners via
977
- * `applyFormReplacement` (see above). The directive's input handler
978
- * computes `meta.persist` from the per-element opt-in registry; other
979
- * internal call sites pass `meta.persist = hasAnyOptInForPath(path)`.
980
- * Public `form.setValue` passes no meta.
975
+ * `applyFormReplacement` (see above). Public `form.setValue` passes no
976
+ * meta.
981
977
  *
982
978
  * Returns `false` when the slim-primitive gate rejects the write
983
979
  * (the value's primitive shape doesn't match the schema's slim
@@ -1126,7 +1122,7 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
1126
1122
  } | null;
1127
1123
  /**
1128
1124
  * Cancel every in-flight field-level validation run — clears timers
1129
- * for debounced 'change' runs that haven't fired, aborts controllers
1125
+ * for debounced 'change' runs that haven't fired, latches `aborted`
1130
1126
  * for runs whose async parse is in flight. Called by `handleSubmit`
1131
1127
  * at entry (submit validation is authoritative) and by `reset()`.
1132
1128
  */
@@ -1191,20 +1187,17 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
1191
1187
  /**
1192
1188
  * Subscribe to every `applyFormReplacement`. Fires synchronously
1193
1189
  * after `form.value` has been swapped to `next` and all field /
1194
- * originals bookkeeping has run. Used by persistence + undo/redo
1195
- * to hook the single mutation funnel. The optional `meta` carries
1196
- * the originating call site's intent the persistence subscription
1197
- * filters on `meta?.persist === true`; subscribers that don't care
1198
- * about meta can ignore the parameter. Returns an unsubscribe
1199
- * function.
1190
+ * originals bookkeeping has run. Used by undo/redo to hook the single
1191
+ * mutation funnel. The optional `meta` carries the originating call
1192
+ * site's intent; subscribers that don't care about meta can ignore the
1193
+ * parameter. Returns an unsubscribe function.
1200
1194
  */
1201
1195
  onFormChange(listener: (next: F, meta?: WriteMeta) => void): () => void;
1202
1196
  /**
1203
1197
  * Subscribe to successful submissions. Fires after the consumer's
1204
1198
  * `onSubmit` callback has resolved — not on validation failure,
1205
- * not on callback throw. Used by persistence's `clearOnSubmitSuccess`
1206
- * to drop the stored payload once the form is safely through the
1207
- * server round-trip. Returns an unsubscribe function.
1199
+ * not on callback throw. The DevTools panel rides this to surface a
1200
+ * submit event. Returns an unsubscribe function.
1208
1201
  */
1209
1202
  onSubmitSuccess(listener: () => void): () => void;
1210
1203
  /**
@@ -1250,58 +1243,6 @@ type FormStore<F extends GenericForm, G extends GenericForm = F> = {
1250
1243
  * owned by the caller (e.g. `'history'`).
1251
1244
  */
1252
1245
  readonly modules: Map<string, unknown>;
1253
- /**
1254
- * Per-element persistence opt-in tracker. Empty by default; the
1255
- * `v-register` directive populates entries on `mount` for each binding
1256
- * that passed `register('foo', { persist: true })` and clears them on
1257
- * `beforeUnmount`. Two SFCs sharing a key share this registry — opt-ins
1258
- * are per-DOM-element, not per-component. Internal to the persistence
1259
- * subsystem; not part of the consumer API surface.
1260
- */
1261
- readonly persistOptIns: PersistOptInRegistry;
1262
- /**
1263
- * Resolved sensitive-path predicate for THIS form. Honors the
1264
- * cascade (`useForm({ sensitiveNames })` > global default >
1265
- * library `DEFAULT_SENSITIVE_NAMES`). Used by:
1266
- * - the persistence opt-in gate (`allowSensitivePersist`);
1267
- * - the multi-tab sync module (outbound strip + inbound reject);
1268
- * - DevTools edit rejection;
1269
- * - any future surface that needs to flag "this path holds
1270
- * sensitive data."
1271
- *
1272
- * Frozen at FormStore construction. Two callsites sharing a key
1273
- * share the predicate — consistent with the rest of the per-form
1274
- * resolved-config surface.
1275
- */
1276
- readonly isSensitivePath: (path: Path | PathKey | string) => boolean;
1277
- /**
1278
- * Canonical path keys explicitly opted OUT of multi-tab sync by
1279
- * `register(path, { multiTab: false })`. The sync module's outbound
1280
- * broadcaster strips patches at these paths AND the inbound listener
1281
- * rejects them — symmetric tab-local behaviour for selected fields.
1282
- *
1283
- * Read-only Set view; mutate via `incrementNoSyncOptOut` /
1284
- * `decrementNoSyncOptOut` which maintain a per-path ref count so
1285
- * multiple bindings on the same path balance correctly across
1286
- * dynamic conditional renders. Empty by default.
1287
- */
1288
- readonly noSyncPaths: ReadonlySet<PathKey>;
1289
- /**
1290
- * Ref-counted "this path is tab-local" registration. Called by
1291
- * `v-register`'s `created` hook for any binding that declared
1292
- * `register('x', { multiTab: false })`. The first call for a given
1293
- * path adds it to `noSyncPaths`; subsequent calls just bump the
1294
- * ref count. Pair with `decrementNoSyncOptOut`.
1295
- */
1296
- incrementNoSyncOptOut(path: PathKey): void;
1297
- /**
1298
- * Symmetric companion to `incrementNoSyncOptOut`. Called by
1299
- * `v-register`'s `beforeUnmount` hook. When the ref count for a
1300
- * path drops to zero, the path is removed from `noSyncPaths` —
1301
- * dynamic toggling (the binding rendered conditionally) restores
1302
- * full sync to the path when the last opt-out unmounts.
1303
- */
1304
- decrementNoSyncOptOut(path: PathKey): void;
1305
1246
  /**
1306
1247
  * Resolved schema-coercion index — the merged config from
1307
1248
  * `createAttaform({ defaults: { coerce } })` ∪ `useForm({ coerce })`,
@@ -1,4 +1,4 @@
1
- import { g as getRegistryFromApp, o as pathKeyToDotted } from './attaform.DP-u7_tk.mjs';
1
+ import { g as getRegistryFromApp, n as pathKeyToDotted } from './attaform.BhI9Icek.mjs';
2
2
 
3
3
  function renderAttaformState(app) {
4
4
  const registry = getRegistryFromApp(app);
@@ -32,4 +32,4 @@ function hydrateAttaformState(app, payload) {
32
32
  const DEVTOOLS_WINDOW_KEY = "__attaform_devtools__";
33
33
 
34
34
  export { DEVTOOLS_WINDOW_KEY as D, hydrateAttaformState as h, renderAttaformState as r };
35
- //# sourceMappingURL=attaform.C41gjp-a.mjs.map
35
+ //# sourceMappingURL=attaform.Dx9-QQE2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"attaform.C41gjp-a.mjs","sources":["../../src/runtime/core/serialize.ts","../../src/runtime/core/devtools-shared.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormKey } from '../types/types-api'\nimport { pathKeyToDotted, type PathKey } from './paths'\nimport { getRegistryFromApp, type SerializedFormData } from './registry'\n\n/**\n * Serialised snapshot of every form in a Vue app, produced by\n * `renderAttaformState` and consumed by `hydrateAttaformState`.\n *\n * JSON-safe — pass to `JSON.stringify`, `devalue`, or any other\n * serialiser before embedding in your SSR payload.\n */\nexport type SerializedAttaformState = {\n /** Tuples of `[formKey, snapshot]` for every form in the app. */\n readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>\n}\n\n/**\n * Snapshot every form on a Vue app for SSR. Call from your server\n * entry after rendering the app:\n *\n * ```ts\n * import { renderToString } from '@vue/server-renderer'\n * import { renderAttaformState, escapeForInlineScript } from 'attaform'\n *\n * const html = await renderToString(app)\n * const state = renderAttaformState(app)\n * const payload = escapeForInlineScript(JSON.stringify(state))\n *\n * return `\n * ${html}\n * <script>window.__ATTAFORM_STATE__ = ${payload}</script>\n * `\n * ```\n *\n * Pair with `hydrateAttaformState` on the client to restore the\n * forms in their server-rendered state. Nuxt users don't need this —\n * `attaform/nuxt` wires SSR automatically.\n */\nexport function renderAttaformState(app: App): SerializedAttaformState {\n const registry = getRegistryFromApp(app)\n const forms: Array<readonly [FormKey, SerializedFormData]> = []\n for (const [key, state] of registry.forms) {\n // Skip the blank field when the set is empty so the\n // wire payload stays minimal for forms that don't use it. The\n // optional shape on the consuming side handles the absence\n // cleanly (defaults to \"no blank paths\"). PathKey → dotted at\n // the boundary so the wire shape matches the rest of the\n // public path notation.\n const transientList: string[] = []\n for (const pk of state.blankPaths) {\n const d = pathKeyToDotted(pk as PathKey)\n if (d !== null) transientList.push(d)\n }\n forms.push([\n key,\n {\n form: state.form.value,\n schemaErrors: Array.from(state.schemaErrors.entries()),\n userErrors: Array.from(state.userErrors.entries()),\n fields: Array.from(state.fields.entries()),\n ...(transientList.length > 0 ? { blankPaths: transientList } : {}),\n },\n ])\n }\n return { forms }\n}\n\n/**\n * Restore forms from a server-rendered snapshot on the client. Call\n * from your client entry before mounting:\n *\n * ```ts\n * import { createApp } from 'vue'\n * import { createAttaform, hydrateAttaformState } from 'attaform'\n *\n * const app = createApp(App).use(createAttaform())\n * hydrateAttaformState(app, window.__ATTAFORM_STATE__)\n * app.mount('#app')\n * ```\n *\n * The next `useForm({ key })` call for each serialised form picks up\n * the snapshot transparently — no further action is required.\n */\nexport function hydrateAttaformState(app: App, payload: SerializedAttaformState): void {\n const registry = getRegistryFromApp(app)\n for (const [key, data] of payload.forms) {\n registry.pendingHydration.set(key, data)\n }\n}\n","/**\n * Shared building blocks for Attaform's two devtools surfaces — the Vue\n * DevTools (Chrome-extension) inspector wired up in `./devtools.ts`, and\n * the Nuxt DevTools (overlay) panel wired up via `../../nuxt.ts` +\n * `../pages/_attaform_devtools.vue`.\n *\n * Houses the window-bridge contract both surfaces consume so a new\n * bridge field lands in one file. Both surfaces render RAW form values\n * by design — DevTools is a dev-only surface, and redaction across every\n * place a value surfaces is impractical security theater rather than a\n * real safeguard.\n */\nimport type { AttaformRegistry } from './registry'\n\n/**\n * Property key on `window` that the Nuxt-side dev plugin attaches the\n * bridge object to. The iframe-mounted overlay panel reads\n * `window.parent[DEVTOOLS_WINDOW_KEY]` to reach the host app's registry.\n *\n * Underscored + namespaced to make accidental collision with consumer\n * globals vanishingly unlikely. Stable across versions — bumping it\n * would silently disconnect older library builds from newer overlay\n * panels in the same browser tab during a library upgrade.\n */\nexport const DEVTOOLS_WINDOW_KEY = '__attaform_devtools__'\n\n/**\n * Shape of the object the host plugin attaches to `window` in dev mode.\n * The iframe overlay panel reads this to discover the live registry and\n * render its forms.\n *\n * Single-registry assumption: the latest `createAttaform()` install\n * wins. Multi-app pages (rare; typically only seen in micro-frontend\n * setups) will only see one app's forms in the panel. Documented but\n * not actively supported — the alternative (a Set of registries with\n * union-rendering) is a future call if a real consumer hits it.\n */\nexport interface AttaformDevtoolsBridge {\n registry: AttaformRegistry\n /**\n * The library version, surfaced in the panel's footer for support /\n * bug-report context. Read from `package.json` at host-plugin init.\n */\n version: string\n}\n\ndeclare global {\n interface Window {\n [DEVTOOLS_WINDOW_KEY]?: AttaformDevtoolsBridge\n }\n}\n"],"names":[],"mappings":";;AAuCO,SAAS,oBAAoB,GAAA,EAAmC;AACrE,EAAA,MAAM,QAAA,GAAW,mBAAmB,GAAG,CAAA;AACvC,EAAA,MAAM,QAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,SAAS,KAAA,EAAO;AAOzC,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,EAAA,IAAM,MAAM,UAAA,EAAY;AACjC,MAAA,MAAM,CAAA,GAAI,gBAAgB,EAAa,CAAA;AACvC,MAAA,IAAI,CAAA,KAAM,IAAA,EAAM,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,GAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,MAAM,IAAA,CAAK,KAAA;AAAA,QACjB,cAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,SAAS,CAAA;AAAA,QACrD,YAAY,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA;AAAA,QACjD,QAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,QACzC,GAAI,cAAc,MAAA,GAAS,CAAA,GAAI,EAAE,UAAA,EAAY,aAAA,KAAkB;AAAC;AAClE,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;AAkBO,SAAS,oBAAA,CAAqB,KAAU,OAAA,EAAwC;AACrF,EAAA,MAAM,QAAA,GAAW,mBAAmB,GAAG,CAAA;AACvC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAQ,KAAA,EAAO;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,EACzC;AACF;;ACjEO,MAAM,mBAAA,GAAsB;;;;"}
1
+ {"version":3,"file":"attaform.Dx9-QQE2.mjs","sources":["../../src/runtime/core/serialize.ts","../../src/runtime/core/devtools-shared.ts"],"sourcesContent":["import type { App } from 'vue'\nimport type { FormKey } from '../types/types-api'\nimport { pathKeyToDotted, type PathKey } from './paths'\nimport { getRegistryFromApp, type SerializedFormData } from './registry'\n\n/**\n * Serialised snapshot of every form in a Vue app, produced by\n * `renderAttaformState` and consumed by `hydrateAttaformState`.\n *\n * JSON-safe — pass to `JSON.stringify`, `devalue`, or any other\n * serialiser before embedding in your SSR payload.\n */\nexport type SerializedAttaformState = {\n /** Tuples of `[formKey, snapshot]` for every form in the app. */\n readonly forms: ReadonlyArray<readonly [FormKey, SerializedFormData]>\n}\n\n/**\n * Snapshot every form on a Vue app for SSR. Call from your server\n * entry after rendering the app:\n *\n * ```ts\n * import { renderToString } from '@vue/server-renderer'\n * import { renderAttaformState, escapeForInlineScript } from 'attaform'\n *\n * const html = await renderToString(app)\n * const state = renderAttaformState(app)\n * const payload = escapeForInlineScript(JSON.stringify(state))\n *\n * return `\n * ${html}\n * <script>window.__ATTAFORM_STATE__ = ${payload}</script>\n * `\n * ```\n *\n * Pair with `hydrateAttaformState` on the client to restore the\n * forms in their server-rendered state. Nuxt users don't need this —\n * `attaform/nuxt` wires SSR automatically.\n */\nexport function renderAttaformState(app: App): SerializedAttaformState {\n const registry = getRegistryFromApp(app)\n const forms: Array<readonly [FormKey, SerializedFormData]> = []\n for (const [key, state] of registry.forms) {\n // Skip the blank field when the set is empty so the\n // wire payload stays minimal for forms that don't use it. The\n // optional shape on the consuming side handles the absence\n // cleanly (defaults to \"no blank paths\"). PathKey → dotted at\n // the boundary so the wire shape matches the rest of the\n // public path notation.\n const transientList: string[] = []\n for (const pk of state.blankPaths) {\n const d = pathKeyToDotted(pk as PathKey)\n if (d !== null) transientList.push(d)\n }\n forms.push([\n key,\n {\n form: state.form.value,\n schemaErrors: Array.from(state.schemaErrors.entries()),\n userErrors: Array.from(state.userErrors.entries()),\n fields: Array.from(state.fields.entries()),\n ...(transientList.length > 0 ? { blankPaths: transientList } : {}),\n },\n ])\n }\n return { forms }\n}\n\n/**\n * Restore forms from a server-rendered snapshot on the client. Call\n * from your client entry before mounting:\n *\n * ```ts\n * import { createApp } from 'vue'\n * import { createAttaform, hydrateAttaformState } from 'attaform'\n *\n * const app = createApp(App).use(createAttaform())\n * hydrateAttaformState(app, window.__ATTAFORM_STATE__)\n * app.mount('#app')\n * ```\n *\n * The next `useForm({ key })` call for each serialised form picks up\n * the snapshot transparently — no further action is required.\n */\nexport function hydrateAttaformState(app: App, payload: SerializedAttaformState): void {\n const registry = getRegistryFromApp(app)\n for (const [key, data] of payload.forms) {\n registry.pendingHydration.set(key, data)\n }\n}\n","/**\n * Shared building blocks for Attaform's two devtools surfaces — the Vue\n * DevTools (Chrome-extension) inspector wired up in `./devtools.ts`, and\n * the Nuxt DevTools (overlay) panel wired up via `../../nuxt.ts` +\n * `../pages/_attaform_devtools.vue`.\n *\n * Houses the window-bridge contract both surfaces consume so a new\n * bridge field lands in one file. Both surfaces render RAW form values\n * by design — DevTools is a dev-only surface, and redaction across every\n * place a value surfaces is impractical security theater rather than a\n * real safeguard.\n */\nimport type { AttaformRegistry } from './registry'\n\n/**\n * Property key on `window` that the Nuxt-side dev plugin attaches the\n * bridge object to. The iframe-mounted overlay panel reads\n * `window.parent[DEVTOOLS_WINDOW_KEY]` to reach the host app's registry.\n *\n * Underscored + namespaced to make accidental collision with consumer\n * globals vanishingly unlikely. Stable across versions — bumping it\n * would silently disconnect older library builds from newer overlay\n * panels in the same browser tab during a library upgrade.\n */\nexport const DEVTOOLS_WINDOW_KEY = '__attaform_devtools__'\n\n/**\n * Shape of the object the host plugin attaches to `window` in dev mode.\n * The iframe overlay panel reads this to discover the live registry and\n * render its forms.\n *\n * Single-registry assumption: the latest `createAttaform()` install\n * wins. Multi-app pages (rare; typically only seen in micro-frontend\n * setups) will only see one app's forms in the panel. Documented but\n * not actively supported — the alternative (a Set of registries with\n * union-rendering) is a future call if a real consumer hits it.\n */\nexport interface AttaformDevtoolsBridge {\n registry: AttaformRegistry\n /**\n * The library version, surfaced in the panel's footer for support /\n * bug-report context. Read from `package.json` at host-plugin init.\n */\n version: string\n}\n\ndeclare global {\n interface Window {\n [DEVTOOLS_WINDOW_KEY]?: AttaformDevtoolsBridge\n }\n}\n"],"names":[],"mappings":";;AAuCO,SAAS,oBAAoB,GAAA,EAAmC;AACrE,EAAA,MAAM,QAAA,GAAW,mBAAmB,GAAG,CAAA;AACvC,EAAA,MAAM,QAAuD,EAAC;AAC9D,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,SAAS,KAAA,EAAO;AAOzC,IAAA,MAAM,gBAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,EAAA,IAAM,MAAM,UAAA,EAAY;AACjC,MAAA,MAAM,CAAA,GAAI,gBAAgB,EAAa,CAAA;AACvC,MAAA,IAAI,CAAA,KAAM,IAAA,EAAM,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,GAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,MAAM,IAAA,CAAK,KAAA;AAAA,QACjB,cAAc,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,SAAS,CAAA;AAAA,QACrD,YAAY,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,UAAA,CAAW,SAAS,CAAA;AAAA,QACjD,QAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,QACzC,GAAI,cAAc,MAAA,GAAS,CAAA,GAAI,EAAE,UAAA,EAAY,aAAA,KAAkB;AAAC;AAClE,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;AAkBO,SAAS,oBAAA,CAAqB,KAAU,OAAA,EAAwC;AACrF,EAAA,MAAM,QAAA,GAAW,mBAAmB,GAAG,CAAA;AACvC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAQ,KAAA,EAAO;AACvC,IAAA,QAAA,CAAS,gBAAA,CAAiB,GAAA,CAAI,GAAA,EAAK,IAAI,CAAA;AAAA,EACzC;AACF;;ACjEO,MAAM,mBAAA,GAAsB;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { G as GenericForm, w as FlatPath, S as NestedType, F as FormKey, U as UseFormConfiguration, a as AbstractSchema, D as DefaultValuesInput, am as ValidateOnConfig, b as UseFormReturnType } from './attaform.ory-3WhV.js';
2
+ import { G as GenericForm, w as FlatPath, P as NestedType, F as FormKey, U as UseFormConfiguration, a as AbstractSchema, D as DefaultValuesInput, ah as ValidateOnConfig, b as UseFormReturnType } from './attaform.BJnNK75Y.js';
3
3
 
4
4
  /**
5
5
  * The shape `form.values.<key>` returns at runtime.
@@ -1,6 +1,6 @@
1
- import { t as getAtPath, h as slimKindOf, v as setAtPath, E as humanize, r as useAbstractForm } from './attaform.CTheKoTc.mjs';
2
- import { b as AttaformError, _ as __DEV__, a as canonicalizePath, d as InvalidUseFormConfigError } from './attaform.DP-u7_tk.mjs';
3
- import { f as fieldMetaStore, g as getFieldMetaForSchema, a as getFieldMetaListForSchema, s as slimPrimitivesWalk, w as walkPathSegments, d as deriveDefaultWalk, m as mergeDeep, c as createAbstractSchema, b as getFieldMetaPathMap } from './attaform.D6GYGshL.mjs';
1
+ import { q as getAtPath, o as slimKindOf, r as setAtPath, p as humanize, h as useAbstractForm } from './attaform.CtJOd7ox.mjs';
2
+ import { A as AttaformError, _ as __DEV__, a as canonicalizePath, b as InvalidUseFormConfigError } from './attaform.BhI9Icek.mjs';
3
+ import { f as fieldMetaStore, g as getFieldMetaForSchema, a as getFieldMetaListForSchema, s as slimPrimitivesWalk, w as walkPathSegments, d as deriveDefaultWalk, m as mergeDeep, c as createAbstractSchema, b as getFieldMetaPathMap } from './attaform.Dd1Kmmaj.mjs';
4
4
  import { z } from 'zod';
5
5
 
6
6
  const fieldMeta = fieldMetaStore;
@@ -1272,4 +1272,4 @@ function useForm(configuration) {
1272
1272
  }
1273
1273
 
1274
1274
  export { UnsupportedSchemaError as U, assertZodVersion as a, getIntersectionRight as b, unwrapLazy as c, unwrapInner as d, unwrapPipe as e, fieldMeta as f, getIntersectionLeft as g, getDiscriminator as h, getDiscriminatedOptions as i, getUnionOptions as j, kindOf as k, getRecordKeyType as l, getRecordValueType as m, getTupleItems as n, getSetValueType as o, getArrayElement as p, getObjectShape as q, getEnumValues as r, getLiteralValues as s, getChecks as t, useForm as u, getCatchDefault as v, withMeta as w, getDefaultValue as x, zodV4Adapter as z };
1275
- //# sourceMappingURL=attaform.BVeLgfEh.mjs.map
1275
+ //# sourceMappingURL=attaform.alpG7rT7.mjs.map