attaform 0.29.0 → 0.30.1

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 (79) hide show
  1. package/dist/abstract.d.mts +15 -21
  2. package/dist/abstract.mjs +4 -4
  3. package/dist/dev/abstract.mjs +4 -4
  4. package/dist/dev/chunks/dev-key-collision-warnings.mjs +47 -8
  5. package/dist/dev/chunks/devtools.mjs +2 -2
  6. package/dist/dev/directive.mjs +1 -1
  7. package/dist/dev/history.mjs +1 -2
  8. package/dist/dev/index.mjs +5 -5
  9. package/dist/dev/runtime/plugins/attaform.mjs +3 -3
  10. package/dist/dev/shared/{attaform-dev.BO-71R54.mjs → attaform-dev.BJK1kqHY.mjs} +44 -198
  11. package/dist/dev/shared/{attaform-dev.D8aoKb89.mjs → attaform-dev.BMQ3GcgD.mjs} +51 -64
  12. package/dist/dev/shared/{attaform-dev.BgM6FdtA.mjs → attaform-dev.BUIFcTYf.mjs} +94 -62
  13. package/dist/dev/shared/{attaform-dev.q6UutkCx.mjs → attaform-dev.CT7MDjPy.mjs} +92 -152
  14. package/dist/dev/shared/{attaform-dev.ButTkwHd.mjs → attaform-dev.CZz4GYZ6.mjs} +26 -15
  15. package/dist/dev/shared/{attaform-dev.DD5m2W51.mjs → attaform-dev.Chm4D6SJ.mjs} +2 -4
  16. package/dist/dev/shared/{attaform-dev.DrzObAZo.mjs → attaform-dev.DuEE4GU1.mjs} +4 -4
  17. package/dist/dev/shared/{attaform-dev.DHuydLAC.mjs → attaform-dev.DxHdkkPG.mjs} +674 -734
  18. package/dist/dev/shared/{attaform-dev.A-TpJW0B.mjs → attaform-dev.zlvDr0WB.mjs} +3 -21
  19. package/dist/dev/zod-v3.mjs +6 -6
  20. package/dist/dev/zod-v4.mjs +6 -6
  21. package/dist/dev/zod.mjs +5 -5
  22. package/dist/directive.d.mts +4 -4
  23. package/dist/directive.mjs +1 -1
  24. package/dist/esbuild.d.mts +11 -0
  25. package/dist/esbuild.mjs +1 -1
  26. package/dist/history.d.mts +3 -32
  27. package/dist/history.mjs +1 -2
  28. package/dist/index.d.mts +67 -70
  29. package/dist/index.mjs +5 -5
  30. package/dist/nuxt.d.mts +6 -14
  31. package/dist/nuxt.mjs +3 -7
  32. package/dist/rollup.d.mts +11 -0
  33. package/dist/rollup.mjs +1 -1
  34. package/dist/rspack.d.mts +19 -11
  35. package/dist/rspack.mjs +1 -1
  36. package/dist/runtime/components/AttaformDevtoolsPanel.vue +12 -12
  37. package/dist/runtime/components/DevtoolsValueTree.vue +2 -2
  38. package/dist/runtime/plugins/attaform.mjs +3 -3
  39. package/dist/shared/{attaform.CIWLMY-R.d.mts → attaform.2FslhB9R.d.mts} +83 -95
  40. package/dist/shared/{attaform.Cvao8bW5.mjs → attaform.8mfKZCwH.mjs} +7 -7
  41. package/dist/shared/{attaform.DRUT703x.d.mts → attaform.B-Tb62qV.d.mts} +12 -12
  42. package/dist/shared/{attaform.v0fQtWyA.mjs → attaform.B1rH9ht6.mjs} +1 -1
  43. package/dist/shared/{attaform.BndjUUYX.mjs → attaform.B2iebkPA.mjs} +4 -4
  44. package/dist/shared/{attaform.DhnPb6nK.mjs → attaform.BAf3UNn4.mjs} +1 -1
  45. package/dist/shared/{attaform.CZMAYwSK.mjs → attaform.BIWicztt.mjs} +651 -678
  46. package/dist/shared/attaform.BcQwgWaq.d.mts +2153 -0
  47. package/dist/shared/attaform.Br8EBn5B.d.mts +4553 -0
  48. package/dist/shared/{attaform.C2MVyuxC.mjs → attaform.CO918TdU.mjs} +44 -198
  49. package/dist/shared/{attaform.CZYt_5N_.mjs → attaform.CdZIEf7_.mjs} +1 -19
  50. package/dist/shared/{attaform.B0dKL8ST.mjs → attaform.DRsANMok.mjs} +94 -62
  51. package/dist/shared/{attaform.DffRL5pP.mjs → attaform.D_f1WgYf.mjs} +46 -59
  52. package/dist/shared/{attaform.D1fnTifF.mjs → attaform.D_pt1gOj.mjs} +92 -150
  53. package/dist/shared/attaform.L0kUn3vL.d.mts +42 -0
  54. package/dist/shared/{attaform.D0x-qSXm.mjs → attaform.WiGdIqgx.mjs} +1 -3
  55. package/dist/shared/{attaform.BK0cgu2K.mjs → attaform.ZYn2ahzJ.mjs} +3 -3
  56. package/dist/transforms.d.mts +153 -26
  57. package/dist/transforms.mjs +1 -1
  58. package/dist/vite.d.mts +29 -52
  59. package/dist/vite.mjs +8 -3
  60. package/dist/webpack.d.mts +20 -12
  61. package/dist/webpack.mjs +1 -1
  62. package/dist/zod-v3.d.mts +90 -96
  63. package/dist/zod-v3.mjs +6 -6
  64. package/dist/zod-v4.d.mts +119 -119
  65. package/dist/zod-v4.mjs +6 -6
  66. package/dist/zod.d.mts +5 -5
  67. package/dist/zod.mjs +5 -5
  68. package/package.json +9 -7
  69. package/skills/attaform/SKILL.md +1 -1
  70. package/skills/attaform/references/custom-components.md +1 -1
  71. package/dist/chunks/fingerprint.mjs +0 -183
  72. package/dist/chunks/fingerprint2.mjs +0 -159
  73. package/dist/dev/chunks/fingerprint.mjs +0 -183
  74. package/dist/dev/chunks/fingerprint2.mjs +0 -159
  75. package/dist/dev/shared/attaform-dev.BxfsuwBR.mjs +0 -44
  76. package/dist/shared/attaform.BxfsuwBR.mjs +0 -44
  77. package/dist/shared/attaform.CsoeRi3P.d.mts +0 -5155
  78. package/dist/shared/attaform.DDtqHYv1.d.mts +0 -2465
  79. package/dist/shared/attaform.axHXVQO7.d.mts +0 -44
@@ -1,50 +1,177 @@
1
1
  import { NodeTransform } from '@vue/compiler-core';
2
2
 
3
+ /**
4
+ * Vue compiler node transform that bridges `v-register` into the binding
5
+ * shapes its consumers expect, on two kinds of host.
6
+ *
7
+ * - `<select v-register>` gets `:value` on a single-select plus a
8
+ * per-`<option>` `:selected`, so the runtime directive can pre-mark
9
+ * selected options at SSR time.
10
+ * - `<MyComponent v-register>`, and a kebab-case custom-element host,
11
+ * gets a `:registerValue` bridge prop, so `useRegister` inside the
12
+ * child sees the parent's RegisterValue. Any parent-authored slotted
13
+ * `<option>` is marked exactly as the native path marks it, so a
14
+ * `<select>` wrapped in a styled component keeps its SSR-selected
15
+ * option (#394).
16
+ *
17
+ * `attaform/vite` and `attaform/nuxt` wire it for you; reach for it
18
+ * directly only when integrating a custom bundler.
19
+ */
20
+
3
21
  declare const componentBridgeTransform: NodeTransform;
4
22
 
5
23
  /**
6
- * Vue compiler node transform for `<input v-register>` and
7
- * `<textarea v-register>`. Injects the `:value` / `:checked`
8
- * bindings required for SSR-correct initial render.
24
+ * Vue compiler node transform for `<input v-register>` and `<textarea
25
+ * v-register>`, injecting the `:value` and `:checked` bindings an
26
+ * SSR-correct initial render needs.
9
27
  *
10
- * Wired automatically by `attaform/vite` and
11
- * `attaform/nuxt`. Use directly only when integrating with
12
- * a custom bundler.
28
+ * `attaform/vite` and `attaform/nuxt` wire it for you; reach for it
29
+ * directly only when integrating a custom bundler.
13
30
  */
14
31
  declare const inputTextAreaNodeTransform: NodeTransform;
15
32
 
16
33
  /**
17
- * Vue compiler node transform that warns about a redundant state
18
- * binding co-located with `v-register`, and stamps the
19
- * compile-active marker so the runtime diagnostic stands down.
34
+ * The compile-time half of the redundant-binding guard (#464). On every
35
+ * element carrying `v-register` it does two things.
36
+ *
37
+ * 1. Warns at build time when a `v-model` sits beside `v-register` on
38
+ * a native `<input>`, `<select>` or `<textarea>`, which installs
39
+ * Vue's own model directive next to Attaform's: two writers driving
40
+ * one element with no fallback story between them.
41
+ * `findRedundantStateBinding` below carries the full reasoning for
42
+ * what does and does not count.
43
+ *
44
+ * 2. Stamps `V_REGISTER_COMPILED_MODIFIER` on the directive so the
45
+ * runtime diagnostic in `core/directive.ts` stands down. This
46
+ * transform runs BEFORE `inputTextAreaNodeTransform` and
47
+ * `componentBridgeTransform` strip and inject the value channel, so
48
+ * it sees the author's props verbatim where the runtime, seeing
49
+ * only the post-injection props, cannot. Exactly one layer fires
50
+ * per consumer.
51
+ *
52
+ * The carve-out: a `:value`, or a static `value=`, is the legitimate
53
+ * IDENTITY channel for a radio and an `<option>`, and `v-register` READS
54
+ * it. Those never warn; only the STATE attrs do.
55
+ *
56
+ * A dynamic `:type` cannot be classified at compile time, so that input
57
+ * is skipped for the warn, best-effort as in `inputTextAreaNodeTransform`
58
+ * and the runtime `resolveDynamicModel`. The marker is still stamped, so
59
+ * the runtime layer, which sees the resolved type, does not double-report.
60
+ *
61
+ * It is deliberately NOT `__DEV__`-gated: firing on every compile,
62
+ * production and CI included, is what lets a consumer retire a bespoke
63
+ * SFC-lint gate. Warnings only. A redundant binding never fails the
64
+ * build, the Vue compiler giving transforms no error channel and a
65
+ * library having no business nuking a consumer's build over a
66
+ * lint-level issue.
67
+ *
68
+ * `attaform/vite` and `attaform/nuxt` wire it first in `nodeTransforms`;
69
+ * reach for it directly only when integrating a custom bundler.
70
+ */
71
+
72
+ /**
73
+ * Vue compiler node transform that warns about a redundant state binding
74
+ * sitting beside `v-register`, and stamps the compile-active marker so
75
+ * the runtime diagnostic stands down.
20
76
  *
21
- * Must run BEFORE `inputTextAreaNodeTransform` and
22
- * `componentBridgeTransform` so it reads the author's props before they
23
- * are stripped / injected. Wired first by `attaform/vite` and
24
- * `attaform/nuxt`.
77
+ * It MUST run before `inputTextAreaNodeTransform` and
78
+ * `componentBridgeTransform`, so it reads the author's props before they
79
+ * are stripped and injected. `attaform/vite` and `attaform/nuxt` wire it
80
+ * first.
25
81
  */
26
82
  declare const redundantBindingWarnTransform: NodeTransform;
27
83
 
28
84
  /**
29
- * Vue compiler node transform that wraps every `v-register`
30
- * expression in a small IIFE so the directive can flag a field as
31
- * connected during SSR. Eliminates the `false → true` flicker on
32
- * `getFieldState(path).connected` after hydration.
85
+ * Rewrites every `<element v-register="<expr>">` so the binding
86
+ * expression wraps `<expr>` in an IIFE that calls
87
+ * `markConnectedOptimistically()` on the resulting `RegisterValue` and
88
+ * hands back the same object:
89
+ *
90
+ * ((__attaRv) => (__attaRv?.markConnectedOptimistically?.(), __attaRv))(<expr>)
91
+ *
92
+ * Vue deliberately skips directive lifecycle hooks during SSR (see the
93
+ * header of `core/directive.ts`), so the `v-register` directive's
94
+ * `created` hook, the one that flips `connected: true`, never fires on
95
+ * the server. Every SSR'd FieldState therefore serialises `connected:
96
+ * false`, then flickers to `true` when the directive runs on hydration,
97
+ * and anything reading `getFieldState(path).connected` in a
98
+ * server-rendered template sees the stale value baked into the HTML.
33
99
  *
34
- * Must run after `vRegisterPreambleTransform`. Wired automatically
35
- * by `attaform/vite` and `attaform/nuxt`.
100
+ * The IIFE captures the `RegisterValue` `<expr>` produced, fires the
101
+ * optimistic mark, itself guarded by `state.ssr` so it is a free no-op
102
+ * on the client, and returns the same object, so the directive receives
103
+ * exactly what the author wrote.
104
+ *
105
+ * It is agnostic to the shape of `<expr>`, inline, hoisted into a
106
+ * variable, or dynamically built: all three produce a `RegisterValue` at
107
+ * runtime and the wrapper never needs the path string. A setup-time
108
+ * `register()` call NEVER bound to `v-register` gets no wrapper, no
109
+ * mark, and stays `connected: false` after hydration, which is correct:
110
+ * it represents no rendered DOM element.
111
+ *
112
+ * Idempotent. Running twice on one AST, as some bundler configurations
113
+ * do, detects the marker on the second pass and skips re-wrapping.
114
+ */
115
+
116
+ /**
117
+ * Vue compiler node transform that wraps every `v-register` expression
118
+ * in a small IIFE, so the directive can flag a field connected during
119
+ * SSR and `getFieldState(path).connected` does not flicker after
120
+ * hydration.
121
+ *
122
+ * It must run after `vRegisterPreambleTransform`. `attaform/vite` and
123
+ * `attaform/nuxt` wire both.
36
124
  */
37
125
  declare const vRegisterHintTransform: NodeTransform;
38
126
 
39
127
  /**
40
- * Vue compiler node transform that hoists `v-register`'s SSR
41
- * connection marks to the root of the template. Together with
42
- * `vRegisterHintTransform`, ensures expressions earlier in the
43
- * template that read `getFieldState(path).connected` see the
44
- * correct value during the server's single-pass render.
128
+ * Closes the render-order edge `vRegisterHintTransform` alone leaves
129
+ * open.
130
+ *
131
+ * The hint transform wraps each `v-register` expression in an IIFE that
132
+ * calls `markConnectedOptimistically()` when the element's vnode is
133
+ * created, which covers any expression evaluated AT or AFTER the input
134
+ * in render order. Vue's SSR is single-pass top to bottom, though, so in
135
+ *
136
+ * <pre>{{ form.fields.password.connected }}</pre>
137
+ * <input v-register="form.register('password')" />
138
+ *
139
+ * the `<pre>` evaluates BEFORE the wrapper has fired. The serialized
140
+ * HTML carries `connected: false`, the post-hydration steady state says
141
+ * `true`, and the user sees a one-tick flicker.
142
+ *
143
+ * So the marks hoist one level up. The walk collects every static
144
+ * `v-register` binding, skipping `v-for` descendants, whose expressions
145
+ * reference loop locals unavailable at root scope, and prepends a
146
+ * synthetic `:data-atta-pre-mark` directive to the first root element.
147
+ * Vue evaluates an element's prop bindings before recursing into its
148
+ * children, so that IIFE fires every collected mark before any
149
+ * descendant expression runs. Its own expression resolves to
150
+ * `undefined`, which the SSR renderer drops, so no attribute appears and
151
+ * the marks are the only output.
152
+ *
153
+ * Register it BEFORE `vRegisterHintTransform`. The pre-order pass here
154
+ * captures each expression's original, un-wrapped text into a
155
+ * per-template state map, the hint transform then wraps the in-place
156
+ * directive expression, and the exit hook on the first root element
157
+ * builds the preamble from the captured originals. An element's exit
158
+ * hooks fire before `transformElement`'s codegen exit, so the injected
159
+ * prop lands in the rendered output.
160
+ *
161
+ * For a `v-for` descendant the hint transform's per-element wrapper
162
+ * stays load-bearing: those bindings cannot hoist, their path
163
+ * expressions referencing loop-scoped identifiers.
164
+ */
165
+
166
+ /**
167
+ * Vue compiler node transform that hoists `v-register`'s SSR connection
168
+ * marks to the root of the template. With `vRegisterHintTransform`, it
169
+ * is what lets an expression EARLIER in the template read
170
+ * `getFieldState(path).connected` correctly during the server's
171
+ * single-pass render.
45
172
  *
46
- * Must run before `vRegisterHintTransform`. Wired automatically
47
- * by `attaform/vite` and `attaform/nuxt`.
173
+ * It must run before `vRegisterHintTransform`. `attaform/vite` and
174
+ * `attaform/nuxt` wire both.
48
175
  */
49
176
  declare const vRegisterPreambleTransform: NodeTransform;
50
177
 
@@ -1 +1 @@
1
- export { c as componentBridgeTransform, i as inputTextAreaNodeTransform, r as redundantBindingWarnTransform, v as vRegisterHintTransform, a as vRegisterPreambleTransform } from './shared/attaform.BK0cgu2K.mjs';
1
+ export { c as componentBridgeTransform, i as inputTextAreaNodeTransform, r as redundantBindingWarnTransform, v as vRegisterHintTransform, a as vRegisterPreambleTransform } from './shared/attaform.ZYn2ahzJ.mjs';
package/dist/vite.d.mts CHANGED
@@ -28,9 +28,9 @@ import { Plugin } from 'vite';
28
28
  * can be called at all.
29
29
  *
30
30
  * Deliberately absent (reach for these with an explicit import):
31
- * - `useAbstractForm` — the schema-agnostic escape hatch on
32
- * `attaform/abstract`, an advanced surface, not the default form.
33
- * - `createAttaform` — the plugin install, a setup-level one-liner that
31
+ * - `useAbstractForm`, the schema-agnostic escape hatch on
32
+ * `attaform/abstract`: an advanced surface, not the default form.
33
+ * - `createAttaform`, the plugin install, a setup-level one-liner that
34
34
  * belongs beside the app bootstrap, not in every component's scope.
35
35
  * - `unset` / `isUnset` and the serialize helpers: plain values and
36
36
  * functions with no component affinity, equally at home in a store, a
@@ -63,41 +63,14 @@ declare const attaformAutoImports: AttaformAutoImport[];
63
63
  declare const attaformAutoImportsMap: Record<string, string[]>;
64
64
 
65
65
  /**
66
- * `attaform/vite` — Vite plugin that wires the compile-time node
67
- * transforms with @vitejs/plugin-vue, binds `v-register` into each
68
- * compiled template that uses it (so no app-level directive
69
- * registration exists or is needed), AND rewrites `attaform` and
70
- * `attaform/zod` imports to either `attaform/zod-v3` or `attaform/zod-v4`
71
- * at build time, based on the consumer's installed Zod major. The result
72
- * is one Zod adapter shipped per bundle, with no manual subpath choice.
66
+ * `attaform/vite`, the Vite plugin. See {@link attaform} for what it
67
+ * does and how to register it.
73
68
  *
74
- * Usage (bare Vue 3 consumers):
75
- *
76
- * // vite.config.ts
77
- * import vue from '@vitejs/plugin-vue'
78
- * import { attaform } from 'attaform/vite'
79
- *
80
- * export default defineConfig({
81
- * plugins: [vue(), attaform()],
82
- * })
83
- *
84
- * The transforms inject `:value`, `:checked`, and `:selected` bindings
85
- * into elements that use the `v-register` directive — load-bearing for
86
- * SSR initial-render correctness. Omitting this plugin under CSR is
87
- * tolerable (one-frame flash on mount); omitting it under SSR produces
88
- * visibly wrong initial HTML.
89
- *
90
- * The `resolveZodAlias` option (default `true`) controls the build-time
91
- * rewrite of `attaform` / `attaform/zod`. Set to `false` if your project
92
- * intentionally mixes Zod versions or has a non-standard Zod resolution;
93
- * the unified entry's runtime dispatch covers that case at the cost of
94
- * bundling both adapters.
95
- *
96
- * Implementation note: this plugin mutates @vitejs/plugin-vue's options
97
- * via the documented but somewhat informal `api.options` surface used
98
- * by VueUse, Vite PWA, and other Vue ecosystem plugins. If you're
99
- * using a custom Vue plugin wrapper, fall back to `attaform/transforms`
100
- * and wire them yourself.
69
+ * It mutates @vitejs/plugin-vue's options through the documented but
70
+ * somewhat informal `api.options` surface that VueUse, Vite PWA and
71
+ * other Vue ecosystem plugins also use. Behind a custom Vue plugin
72
+ * wrapper, fall back to `attaform/transforms` and wire the transforms
73
+ * yourself.
101
74
  */
102
75
 
103
76
  /** Options for `attaform()`. */
@@ -105,8 +78,8 @@ interface AttaformVitePluginOptions {
105
78
  /**
106
79
  * Rewrite `attaform` and `attaform/zod` imports at build time to
107
80
  * either `attaform/zod-v3` or `attaform/zod-v4`, based on the
108
- * consumer's installed Zod major. Default `true` — produces a leaner
109
- * bundle for the common case of one Zod version per project.
81
+ * consumer's installed Zod major. Default `true`, which produces a
82
+ * leaner bundle for the common case of one Zod version per project.
110
83
  *
111
84
  * Set to `false` to fall through to the unified entry's runtime
112
85
  * dispatch. Useful when:
@@ -120,12 +93,10 @@ interface AttaformVitePluginOptions {
120
93
  resolveZodAlias?: boolean;
121
94
  }
122
95
  /**
123
- * Vite plugin that wires the form library's compile-time template
124
- * transforms into `@vitejs/plugin-vue`, binds the `v-register`
125
- * directive into each compiled template that uses it, and rewrites the
126
- * bare `attaform` barrel and the unified `attaform/zod` import to the
127
- * matching adapter subpath. Required for SSR and for hydration
128
- * accuracy under bare Vue 3.
96
+ * Vite plugin that wires Attaform's compile-time template transforms
97
+ * into `@vitejs/plugin-vue`, binds `v-register` into each compiled
98
+ * template that uses it, and rewrites the bare `attaform` barrel and
99
+ * the unified `attaform/zod` import to the matching adapter subpath.
129
100
  *
130
101
  * ```ts
131
102
  * // vite.config.ts
@@ -137,14 +108,20 @@ interface AttaformVitePluginOptions {
137
108
  * })
138
109
  * ```
139
110
  *
140
- * Place the call after `vue()` in the plugins array. Nuxt projects
141
- * don't need this — `attaform/nuxt` handles it.
111
+ * Place the call after `vue()`. Nuxt projects do not need it;
112
+ * `attaform/nuxt` handles this.
113
+ *
114
+ * The transforms inject `:value`, `:checked` and `:selected` onto
115
+ * elements using `v-register`, which is load-bearing for SSR
116
+ * initial-render correctness. Omitting the plugin under CSR costs a
117
+ * one-frame flash on mount; omitting it under SSR produces visibly
118
+ * wrong initial HTML.
142
119
  *
143
- * Returns a two-plugin array (Vite flattens nested plugin arrays): the
144
- * main pre-plugin above, plus a post-plugin that rewrites each compiled
145
- * SFC's `resolveDirective("register")` to a static import from
146
- * `attaform/directive`. The rewrite is why no app-level directive
147
- * registration exists or is needed here — see
120
+ * Returns a two-plugin array, since Vite flattens nested plugin arrays:
121
+ * the main pre-plugin, plus a post-plugin rewriting each compiled SFC's
122
+ * `resolveDirective("register")` to a static import from
123
+ * `attaform/directive`. That rewrite is why no app-level directive
124
+ * registration is needed here; see
148
125
  * `runtime/lib/core/transforms/directive-delivery-transform.ts` for the
149
126
  * mechanism and its scope.
150
127
  */
package/dist/vite.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { r as resolveZodAliasTarget, i as isRewritableZodSpecifier } from './shared/attaform.DhnPb6nK.mjs';
2
- import { a as vRegisterPreambleTransform, r as redundantBindingWarnTransform, c as componentBridgeTransform, i as inputTextAreaNodeTransform, v as vRegisterHintTransform } from './shared/attaform.BK0cgu2K.mjs';
1
+ import { r as resolveZodAliasTarget, i as isRewritableZodSpecifier } from './shared/attaform.BAf3UNn4.mjs';
2
+ import { a as vRegisterPreambleTransform, r as redundantBindingWarnTransform, c as componentBridgeTransform, i as inputTextAreaNodeTransform, v as vRegisterHintTransform } from './shared/attaform.ZYn2ahzJ.mjs';
3
3
  import { parse, babelParse } from '@vue/compiler-sfc';
4
4
  import { NodeTypes } from '@vue/compiler-core';
5
5
 
@@ -60,8 +60,13 @@ class SourceEditor {
60
60
  return out;
61
61
  }
62
62
  }
63
+ function canPossiblyInject(code) {
64
+ if (!code.includes("attaform")) return false;
65
+ return code.includes("useForm") || code.includes("injectForm");
66
+ }
63
67
  function transformSsrAccessed(code, id) {
64
68
  if (!id.endsWith(".vue")) return null;
69
+ if (!canPossiblyInject(code)) return null;
65
70
  const { descriptor } = parse(code, { filename: id });
66
71
  if (descriptor.scriptSetup === null || descriptor.template === null) return null;
67
72
  const scriptSource = descriptor.scriptSetup.content;
@@ -303,7 +308,7 @@ function attaform(options = {}) {
303
308
 
304
309
  // The panel runs inside Nuxt DevTools' overlay iframe, which itself
305
310
  // is nested in the consumer's main page. \`window.parent\` only
306
- // crosses one frame boundary \u2014 the overlay UI \u2014 which doesn't have
311
+ // crosses one frame boundary (the overlay UI), which doesn't have
307
312
  // the bridge attached. The bridge lives on the consumer's main
308
313
  // page, which sits at the top of the frame hierarchy. Walk the
309
314
  // chain checking each ancestor frame so the same code works whether
@@ -1,13 +1,14 @@
1
1
  import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './shared/attaform.C9fPTxjB.mjs';
2
2
 
3
3
  /**
4
- * `attaform/webpack` — webpack plugin that rewrites `attaform/zod`
4
+ * `attaform/webpack`, the webpack plugin that rewrites `attaform/zod`
5
5
  * imports to the single matching adapter subpath (`attaform/zod-v3` or
6
6
  * `attaform/zod-v4`) at build time, based on the consumer's installed Zod
7
7
  * major. Without it, webpack ships both adapters because the unified
8
8
  * `attaform/zod` entry imports both for runtime dispatch.
9
9
  *
10
- * Usage (ESM config — the plugin is ESM-only, matching attaform's package):
10
+ * Usage, in an ESM config, since the plugin is ESM-only like the rest of
11
+ * the package:
11
12
  *
12
13
  * // webpack.config.mjs
13
14
  * import { attaform } from 'attaform/webpack'
@@ -16,16 +17,12 @@ import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './sha
16
17
  * plugins: [attaform()],
17
18
  * }
18
19
  *
19
- * This plugin only does the adapter rewrite. The Vue SFC `v-register`
20
- * transforms that `attaform/vite` wires (load-bearing for SSR initial
21
- * render) are `@vitejs/plugin-vue`-specific and do not transfer; a
22
- * non-Vite consumer that needs them wires `attaform/transforms` into
23
- * their Vue compiler separately. The `v-register` directive itself is
24
- * also delivered by the Vite plugin's compile-time binding, so outside
25
- * that pipeline register it once per app:
26
- *
27
- * import { installVRegister } from 'attaform/directive'
28
- * installVRegister(app)
20
+ * The adapter rewrite is all this plugin does. Two things
21
+ * `attaform/vite` also provides do NOT transfer, because both are
22
+ * `@vitejs/plugin-vue`-specific: wire `attaform/transforms` into your
23
+ * Vue compiler for the SSR-critical template transforms, and register
24
+ * the directive once per app with `installVRegister(app)` from
25
+ * `attaform/directive`.
29
26
  *
30
27
  * Zero-dep: the plugin imports nothing from `webpack` (it taps the resolve
31
28
  * hook the compiler injects at the consumer's build). Shares its body with
@@ -36,6 +33,17 @@ import { W as WebpackFamilyPlugin, a as WebpackFamilyPluginOptions } from './sha
36
33
  type AttaformWebpackPluginOptions = WebpackFamilyPluginOptions;
37
34
  /** The structural shape webpack requires of the plugin. */
38
35
  type AttaformWebpackPlugin = WebpackFamilyPlugin;
36
+ /**
37
+ * webpack plugin that resolves `attaform/zod` to the one adapter subpath
38
+ * matching the installed Zod major, so the build ships a single adapter
39
+ * instead of both.
40
+ *
41
+ * ```js
42
+ * const { attaform } = require('attaform/webpack')
43
+ *
44
+ * module.exports = { plugins: [attaform()] }
45
+ * ```
46
+ */
39
47
  declare function attaform(options?: AttaformWebpackPluginOptions): AttaformWebpackPlugin;
40
48
 
41
49
  export { attaform };
package/dist/webpack.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as createWebpackFamilyPlugin } from './shared/attaform.v0fQtWyA.mjs';
1
+ import { c as createWebpackFamilyPlugin } from './shared/attaform.B1rH9ht6.mjs';
2
2
 
3
3
  function attaform(options = {}) {
4
4
  return createWebpackFamilyPlugin("attaform/webpack", options);