@pyreon/vite-plugin 0.13.1 → 0.15.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.
@@ -36,60 +36,67 @@ function createBuildPlugin(opts?: PyreonPluginOptions) {
36
36
  return plugin
37
37
  }
38
38
 
39
- function transform(plugin: ReturnType<typeof pyreonPlugin>, code: string, id: string) {
39
+ async function transform(plugin: ReturnType<typeof pyreonPlugin>, code: string, id: string) {
40
40
  const transformHook = plugin.transform as (
41
- this: { warn: (msg: string) => void },
41
+ this: { warn: (msg: string) => void; resolve: (id: string, importer?: string, options?: { skipSelf: boolean }) => Promise<{ id: string } | null> },
42
42
  code: string,
43
43
  id: string,
44
- ) => { code: string; map: null } | undefined
44
+ ) => Promise<{ code: string; map: null } | undefined>
45
45
  const warnings: string[] = []
46
- return transformHook.call({ warn: (msg: string) => warnings.push(msg) }, code, id)
46
+ return transformHook.call(
47
+ {
48
+ warn: (msg: string) => warnings.push(msg),
49
+ resolve: async () => null, // no cross-module resolution in unit tests
50
+ },
51
+ code,
52
+ id,
53
+ )
47
54
  }
48
55
 
49
56
  // ─── HMR injection ──────────────────────────────────────────────────────────
50
57
 
51
58
  describe('HMR injection', () => {
52
- it('injects HMR accept for modules with component exports', () => {
59
+ it('injects HMR accept for modules with component exports', async () => {
53
60
  const plugin = createPlugin()
54
61
  const code = `
55
62
  import { h } from "@pyreon/core"
56
63
  export function App() { return h("div", null, "hello") }
57
64
  `
58
- const result = transform(plugin, code, '/src/App.tsx')
65
+ const result = await transform(plugin, code, '/src/App.tsx')
59
66
  expect(result).toBeDefined()
60
67
  expect(result!.code).toContain('import.meta.hot.accept()')
61
68
  })
62
69
 
63
- it('injects HMR for exported const components', () => {
70
+ it('injects HMR for exported const components', async () => {
64
71
  const plugin = createPlugin()
65
72
  const code = `
66
73
  import { h } from "@pyreon/core"
67
74
  export const Header = () => h("header", null, "nav")
68
75
  `
69
- const result = transform(plugin, code, '/src/Header.tsx')
76
+ const result = await transform(plugin, code, '/src/Header.tsx')
70
77
  expect(result).toBeDefined()
71
78
  expect(result!.code).toContain('import.meta.hot')
72
79
  })
73
80
 
74
- it('does not inject HMR for modules without component exports or signals', () => {
81
+ it('does not inject HMR for modules without component exports or signals', async () => {
75
82
  const plugin = createPlugin()
76
83
  // Only lowercase exports — no component-like names (uppercase first letter)
77
84
  const code = `
78
85
  export const formatDate = (d) => d.toISOString()
79
86
  export const maxItems = 100
80
87
  `
81
- const result = transform(plugin, code, '/src/utils.tsx')
88
+ const result = await transform(plugin, code, '/src/utils.tsx')
82
89
  expect(result).toBeDefined()
83
90
  expect(result!.code).not.toContain('import.meta.hot')
84
91
  })
85
92
 
86
- it('does not inject HMR in build mode', () => {
93
+ it('does not inject HMR in build mode', async () => {
87
94
  const plugin = createBuildPlugin()
88
95
  const code = `
89
96
  import { h } from "@pyreon/core"
90
97
  export function App() { return h("div", null, "hello") }
91
98
  `
92
- const result = transform(plugin, code, '/src/App.tsx')
99
+ const result = await transform(plugin, code, '/src/App.tsx')
93
100
  expect(result).toBeDefined()
94
101
  expect(result!.code).not.toContain('import.meta.hot')
95
102
  })
@@ -98,7 +105,7 @@ export function App() { return h("div", null, "hello") }
98
105
  // ─── Signal rewriting ────────────────────────────────────────────────────────
99
106
 
100
107
  describe('signal rewriting', () => {
101
- it('rewrites module-scope signal() to __hmr_signal()', () => {
108
+ it('rewrites module-scope signal() to __hmr_signal()', async () => {
102
109
  const plugin = createPlugin()
103
110
  const code = `
104
111
  import { signal } from "@pyreon/reactivity"
@@ -106,7 +113,7 @@ import { h } from "@pyreon/core"
106
113
  const count = signal(0)
107
114
  export function Counter() { return h("div", null, count()) }
108
115
  `
109
- const result = transform(plugin, code, '/src/Counter.tsx')
116
+ const result = await transform(plugin, code, '/src/Counter.tsx')
110
117
  expect(result).toBeDefined()
111
118
  expect(result!.code).toContain('__hmr_signal(')
112
119
  expect(result!.code).toContain('"count"')
@@ -114,19 +121,45 @@ export function Counter() { return h("div", null, count()) }
114
121
  expect(result!.code).toContain('__hmr_dispose')
115
122
  })
116
123
 
117
- it('rewrites exported signals', () => {
124
+ it('rewrites exported signals', async () => {
118
125
  const plugin = createPlugin()
119
126
  const code = `
120
127
  import { signal } from "@pyreon/reactivity"
121
128
  export const theme = signal("light")
122
129
  export function App() { return null }
123
130
  `
124
- const result = transform(plugin, code, '/src/theme.tsx')
131
+ const result = await transform(plugin, code, '/src/theme.tsx')
125
132
  expect(result).toBeDefined()
126
133
  expect(result!.code).toContain('__hmr_signal("/src/theme.tsx", "theme", signal, "light")')
127
134
  })
128
135
 
129
- it('does not rewrite signal() inside functions to __hmr_signal (but injects name)', () => {
136
+ it('rewrites generic-typed signals (signal<T>(value))', async () => {
137
+ // Regression for the silent-skip bug: SIGNAL_PREFIX_RE used to match
138
+ // `signal(` but not `signal<T>(`. Pre-rewrite TypeScript still has type
139
+ // parameters; declarations like `signal<string>('')` would skip HMR
140
+ // preservation silently and produce an empty-string-valued signal that
141
+ // — under a separate `__hmr_signal` interaction — could read as
142
+ // undefined. Discovered via PR #329 (perf-dashboard form section).
143
+ const plugin = createPlugin()
144
+ const code = `
145
+ import { signal } from "@pyreon/reactivity"
146
+ export const password = signal<string>("")
147
+ export const items = signal<Array<{ id: number }>>([])
148
+ export const count = signal<number>(0)
149
+ export function App() { return null }
150
+ `
151
+ const result = await transform(plugin, code, '/src/state.tsx')
152
+ expect(result).toBeDefined()
153
+ expect(result!.code).toContain(
154
+ '__hmr_signal("/src/state.tsx", "password", signal, "")',
155
+ )
156
+ expect(result!.code).toContain(
157
+ '__hmr_signal("/src/state.tsx", "items", signal, [])',
158
+ )
159
+ expect(result!.code).toContain('__hmr_signal("/src/state.tsx", "count", signal, 0)')
160
+ })
161
+
162
+ it('does not rewrite signal() inside functions to __hmr_signal (but injects name)', async () => {
130
163
  const plugin = createPlugin()
131
164
  const code = `
132
165
  import { signal } from "@pyreon/reactivity"
@@ -136,7 +169,7 @@ export function Counter() {
136
169
  return h("div", null, local())
137
170
  }
138
171
  `
139
- const result = transform(plugin, code, '/src/Counter.tsx')
172
+ const result = await transform(plugin, code, '/src/Counter.tsx')
140
173
  expect(result).toBeDefined()
141
174
  // The signal inside the function body should NOT be rewritten to __hmr_signal
142
175
  expect(result!.code).not.toContain('__hmr_signal')
@@ -144,7 +177,7 @@ export function Counter() {
144
177
  expect(result!.code).toContain('signal(0, { name: "local" })')
145
178
  })
146
179
 
147
- it('rewrites multiple module-scope signals', () => {
180
+ it('rewrites multiple module-scope signals', async () => {
148
181
  const plugin = createPlugin()
149
182
  const code = `
150
183
  import { signal } from "@pyreon/reactivity"
@@ -152,13 +185,13 @@ const count = signal(0)
152
185
  const name = signal("world")
153
186
  export function App() { return null }
154
187
  `
155
- const result = transform(plugin, code, '/src/App.tsx')
188
+ const result = await transform(plugin, code, '/src/App.tsx')
156
189
  expect(result).toBeDefined()
157
190
  expect(result!.code).toContain('"count"')
158
191
  expect(result!.code).toContain('"name"')
159
192
  })
160
193
 
161
- it('handles signal with complex initial values', () => {
194
+ it('handles signal with complex initial values', async () => {
162
195
  const plugin = createPlugin()
163
196
  const code = `
164
197
  import { signal } from "@pyreon/reactivity"
@@ -166,21 +199,21 @@ const items = signal([1, 2, 3])
166
199
  const config = signal({ theme: "dark", size: 14 })
167
200
  export function App() { return null }
168
201
  `
169
- const result = transform(plugin, code, '/src/App.tsx')
202
+ const result = await transform(plugin, code, '/src/App.tsx')
170
203
  expect(result).toBeDefined()
171
204
  expect(result!.code).toContain('__hmr_signal')
172
205
  expect(result!.code).toContain('[1, 2, 3]')
173
206
  expect(result!.code).toContain('{ theme: "dark", size: 14 }')
174
207
  })
175
208
 
176
- it('does not rewrite signal in build mode', () => {
209
+ it('does not rewrite signal in build mode', async () => {
177
210
  const plugin = createBuildPlugin()
178
211
  const code = `
179
212
  import { signal } from "@pyreon/reactivity"
180
213
  const count = signal(0)
181
214
  export function App() { return null }
182
215
  `
183
- const result = transform(plugin, code, '/src/App.tsx')
216
+ const result = await transform(plugin, code, '/src/App.tsx')
184
217
  expect(result).toBeDefined()
185
218
  expect(result!.code).not.toContain('__hmr_signal')
186
219
  // No signal names in production builds
@@ -188,7 +221,7 @@ export function App() { return null }
188
221
  expect(result!.code).not.toContain('{ name:')
189
222
  })
190
223
 
191
- it('skips signal naming when options already provided', () => {
224
+ it('skips signal naming when options already provided', async () => {
192
225
  const plugin = createPlugin()
193
226
  const code = `
194
227
  import { signal } from "@pyreon/reactivity"
@@ -197,7 +230,7 @@ export function App() {
197
230
  return null
198
231
  }
199
232
  `
200
- const result = transform(plugin, code, '/src/App.tsx')
233
+ const result = await transform(plugin, code, '/src/App.tsx')
201
234
  expect(result).toBeDefined()
202
235
  // Should not double-inject name
203
236
  expect(result!.code).toContain('signal(0, { name: "custom" })')
@@ -207,38 +240,38 @@ export function App() {
207
240
  // ─── File extension filtering ────────────────────────────────────────────────
208
241
 
209
242
  describe('file extension filtering', () => {
210
- it('transforms .tsx files', () => {
243
+ it('transforms .tsx files', async () => {
211
244
  const plugin = createPlugin()
212
245
  const code = `export function App() { return null }`
213
- const result = transform(plugin, code, '/src/App.tsx')
246
+ const result = await transform(plugin, code, '/src/App.tsx')
214
247
  expect(result).toBeDefined()
215
248
  })
216
249
 
217
- it('transforms .jsx files', () => {
250
+ it('transforms .jsx files', async () => {
218
251
  const plugin = createPlugin()
219
252
  const code = `export function App() { return null }`
220
- const result = transform(plugin, code, '/src/App.jsx')
253
+ const result = await transform(plugin, code, '/src/App.jsx')
221
254
  expect(result).toBeDefined()
222
255
  })
223
256
 
224
- it('ignores .ts files', () => {
257
+ it('ignores .ts files', async () => {
225
258
  const plugin = createPlugin()
226
259
  const code = `export const x = 1`
227
- const result = transform(plugin, code, '/src/utils.ts')
260
+ const result = await transform(plugin, code, '/src/utils.ts')
228
261
  expect(result).toBeUndefined()
229
262
  })
230
263
 
231
- it('ignores .js files', () => {
264
+ it('ignores .js files', async () => {
232
265
  const plugin = createPlugin()
233
266
  const code = `export const x = 1`
234
- const result = transform(plugin, code, '/src/utils.js')
267
+ const result = await transform(plugin, code, '/src/utils.js')
235
268
  expect(result).toBeUndefined()
236
269
  })
237
270
 
238
- it('handles query strings in file paths', () => {
271
+ it('handles query strings in file paths', async () => {
239
272
  const plugin = createPlugin()
240
273
  const code = `export function App() { return null }`
241
- const result = transform(plugin, code, '/src/App.tsx?v=123')
274
+ const result = await transform(plugin, code, '/src/App.tsx?v=123')
242
275
  expect(result).toBeDefined()
243
276
  })
244
277
  })
@@ -246,31 +279,31 @@ describe('file extension filtering', () => {
246
279
  // ─── Compat mode ─────────────────────────────────────────────────────────────
247
280
 
248
281
  describe('compat mode', () => {
249
- it('skips Pyreon JSX transform in react compat mode', () => {
282
+ it('skips Pyreon JSX transform in react compat mode', async () => {
250
283
  const plugin = createPlugin({ compat: 'react' })
251
284
  const code = `
252
285
  import { useState } from "react"
253
286
  export function App() { const [x] = useState(0); return null }
254
287
  `
255
- const result = transform(plugin, code, '/src/App.tsx')
288
+ const result = await transform(plugin, code, '/src/App.tsx')
256
289
  expect(result).toBeUndefined()
257
290
  })
258
291
 
259
- it('skips transform in preact compat mode', () => {
292
+ it('skips transform in preact compat mode', async () => {
260
293
  const plugin = createPlugin({ compat: 'preact' })
261
- const result = transform(plugin, 'export function App() { return null }', '/src/App.tsx')
294
+ const result = await transform(plugin, 'export function App() { return null }', '/src/App.tsx')
262
295
  expect(result).toBeUndefined()
263
296
  })
264
297
 
265
- it('skips transform in vue compat mode', () => {
298
+ it('skips transform in vue compat mode', async () => {
266
299
  const plugin = createPlugin({ compat: 'vue' })
267
- const result = transform(plugin, 'export function App() { return null }', '/src/App.tsx')
300
+ const result = await transform(plugin, 'export function App() { return null }', '/src/App.tsx')
268
301
  expect(result).toBeUndefined()
269
302
  })
270
303
 
271
- it('skips transform in solid compat mode', () => {
304
+ it('skips transform in solid compat mode', async () => {
272
305
  const plugin = createPlugin({ compat: 'solid' })
273
- const result = transform(plugin, 'export function App() { return null }', '/src/App.tsx')
306
+ const result = await transform(plugin, 'export function App() { return null }', '/src/App.tsx')
274
307
  expect(result).toBeUndefined()
275
308
  })
276
309
  })
@@ -278,13 +311,13 @@ export function App() { const [x] = useState(0); return null }
278
311
  // ─── Plugin config ───────────────────────────────────────────────────────────
279
312
 
280
313
  describe('plugin config', () => {
281
- it('sets resolve.conditions: ["bun"] for workspace source resolution', () => {
314
+ it('sets resolve.conditions: ["bun"] for workspace source resolution', async () => {
282
315
  const plugin = pyreonPlugin()
283
316
  const config = getConfigHook(plugin)({}, { command: 'serve' }) as Record<string, any>
284
317
  expect(config.resolve.conditions).toEqual(['bun'])
285
318
  })
286
319
 
287
- it('sets JSX import source to @pyreon/core by default', () => {
320
+ it('sets JSX import source to @pyreon/core by default', async () => {
288
321
  const plugin = pyreonPlugin()
289
322
  const config = getConfigHook(plugin)({}, { command: 'serve' }) as {
290
323
  oxc: { jsx: { importSource: string } }
@@ -292,15 +325,22 @@ describe('plugin config', () => {
292
325
  expect(config.oxc.jsx.importSource).toBe('@pyreon/core')
293
326
  })
294
327
 
295
- it('sets JSX import source to compat package in compat mode', () => {
328
+ it('keeps JSX import source as @pyreon/core in compat mode', async () => {
329
+ // OXC's `importSource` is project-wide (one setting for the whole build),
330
+ // so pointing it at the compat package would force the compat runtime
331
+ // on `@pyreon/*` framework files too — which they cannot handle. Instead
332
+ // the plugin keeps OXC at `@pyreon/core` and redirects the resulting
333
+ // `@pyreon/core/jsx-runtime` import to the compat package via `resolveId`,
334
+ // gated on the importer (user code only). See `compat-resolve.test.ts`
335
+ // "framework-importer carve-out". Caught by `cpa-smoke-app-*-compat`.
296
336
  const plugin = pyreonPlugin({ compat: 'react' })
297
337
  const config = getConfigHook(plugin)({}, { command: 'serve' }) as {
298
338
  oxc: { jsx: { importSource: string } }
299
339
  }
300
- expect(config.oxc.jsx.importSource).toBe('@pyreon/react-compat')
340
+ expect(config.oxc.jsx.importSource).toBe('@pyreon/core')
301
341
  })
302
342
 
303
- it('excludes compat packages from optimizeDeps', () => {
343
+ it('excludes compat packages from optimizeDeps', async () => {
304
344
  const plugin = pyreonPlugin({ compat: 'react' })
305
345
  const config = getConfigHook(plugin)({}, { command: 'serve' }) as {
306
346
  optimizeDeps: { exclude: string[] }
@@ -309,7 +349,7 @@ describe('plugin config', () => {
309
349
  expect(config.optimizeDeps.exclude).toContain('react-dom')
310
350
  })
311
351
 
312
- it('adds SSR build config when isSsrBuild', () => {
352
+ it('adds SSR build config when isSsrBuild', async () => {
313
353
  const plugin = pyreonPlugin({ ssr: { entry: './src/entry-server.ts' } })
314
354
  const config = getConfigHook(plugin)({}, { command: 'build', isSsrBuild: true }) as {
315
355
  build: { ssr: boolean; rollupOptions: { input: string } }
@@ -331,7 +371,7 @@ describe('virtual module resolution', () => {
331
371
  expect(resolved).toBe('\0pyreon/hmr-runtime')
332
372
  })
333
373
 
334
- it('loads HMR runtime source for internal ID', () => {
374
+ it('loads HMR runtime source for internal ID', async () => {
335
375
  const plugin = createPlugin()
336
376
  const load = plugin.load as (id: string) => string | undefined
337
377
  const source = load('\0pyreon/hmr-runtime')
@@ -341,7 +381,7 @@ describe('virtual module resolution', () => {
341
381
  expect(source).toContain('__pyreon_hmr_registry__')
342
382
  })
343
383
 
344
- it('returns undefined for non-virtual IDs', () => {
384
+ it('returns undefined for non-virtual IDs', async () => {
345
385
  const plugin = createPlugin()
346
386
  const load = plugin.load as (id: string) => string | undefined
347
387
  expect(load('/src/App.tsx')).toBeUndefined()
@@ -356,12 +396,12 @@ describe('asset request filtering', () => {
356
396
  // For direct testing, we'd need to export it — instead we verify
357
397
  // the plugin's SSR middleware config exists when ssr option is set.
358
398
 
359
- it('configureServer returns middleware function when SSR enabled', () => {
399
+ it('configureServer returns middleware function when SSR enabled', async () => {
360
400
  const plugin = pyreonPlugin({ ssr: { entry: './src/entry-server.ts' } })
361
401
  expect(plugin.configureServer).toBeDefined()
362
402
  })
363
403
 
364
- it('configureServer is defined even without SSR (for context generation)', () => {
404
+ it('configureServer is defined even without SSR (for context generation)', async () => {
365
405
  const plugin = pyreonPlugin()
366
406
  expect(plugin.configureServer).toBeDefined()
367
407
  })
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["pathJoin"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @pyreon/vite-plugin — Vite integration for Pyreon framework.\n *\n * Applies Pyreon's JSX reactive transform to .tsx, .jsx, and .pyreon files,\n * and configures Vite to use Pyreon's JSX runtime.\n *\n * ## Basic usage (SPA)\n *\n * import pyreon from \"@pyreon/vite-plugin\"\n * export default { plugins: [pyreon()] }\n *\n * ## Drop-in compat mode (zero code changes)\n *\n * import pyreon from \"@pyreon/vite-plugin\"\n * export default { plugins: [pyreon({ compat: \"react\" })] }\n *\n * Aliases `react`, `react-dom`, `vue`, `solid-js`, or `preact` imports to\n * Pyreon's compat packages — existing code works without changing imports.\n *\n * ## SSR mode\n *\n * import pyreon from \"@pyreon/vite-plugin\"\n * export default { plugins: [pyreon({ ssr: { entry: \"./src/entry-server.ts\" } })] }\n *\n * In SSR mode, the plugin adds dev server middleware that:\n * 1. Loads your server entry via Vite's `ssrLoadModule`\n * 2. Calls the exported `handler` or default export (Request → Response)\n * 3. Returns the SSR'd HTML for every non-asset request\n *\n * For production, build separately:\n * vite build # client bundle\n * vite build --ssr src/entry-server.ts --outDir dist/server # server bundle\n */\n\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join as pathJoin } from 'node:path'\nimport { generateContext, transformJSX } from '@pyreon/compiler'\nimport type { Plugin, ViteDevServer } from 'vite'\n\n// Virtual module ID for the HMR runtime\nconst HMR_RUNTIME_ID = '\\0pyreon/hmr-runtime'\nconst HMR_RUNTIME_IMPORT = 'virtual:pyreon/hmr-runtime'\n\nexport type CompatFramework = 'react' | 'preact' | 'vue' | 'solid'\n\nexport interface PyreonPluginOptions {\n /**\n * Alias imports from an existing framework to Pyreon's compat layer.\n *\n * This lets you drop Pyreon into an existing project with zero code changes —\n * `import { useState } from \"react\"` will resolve to `@pyreon/react-compat`.\n *\n * @example\n * pyreon({ compat: \"react\" }) // react + react-dom → @pyreon/react-compat\n * pyreon({ compat: \"vue\" }) // vue → @pyreon/vue-compat\n * pyreon({ compat: \"solid\" }) // solid-js → @pyreon/solid-compat\n * pyreon({ compat: \"preact\" }) // preact + hooks + signals → @pyreon/preact-compat\n */\n compat?: CompatFramework\n\n /**\n * Enable SSR dev middleware.\n *\n * Pass an object with `entry` pointing to your server entry file.\n * The entry must export a `handler` function: `(req: Request) => Promise<Response>`\n * or a default export of the same type.\n *\n * @example\n * pyreonPlugin({ ssr: { entry: \"./src/entry-server.ts\" } })\n */\n ssr?: {\n /** Server entry file path (e.g. \"./src/entry-server.ts\") */\n entry: string\n }\n}\n\n// ── Compat JSX import sources ─────────────────────────────────────────────────\n\nconst COMPAT_JSX_SOURCE: Record<CompatFramework, string> = {\n react: '@pyreon/react-compat',\n preact: '@pyreon/preact-compat',\n vue: '@pyreon/vue-compat',\n solid: '@pyreon/solid-compat',\n}\n\n// ── Compat alias maps ─────────────────────────────────────────────────────────\n\nconst COMPAT_ALIASES: Record<CompatFramework, Record<string, string>> = {\n react: {\n react: '@pyreon/react-compat',\n 'react/jsx-runtime': '@pyreon/react-compat/jsx-runtime',\n 'react/jsx-dev-runtime': '@pyreon/react-compat/jsx-runtime',\n 'react-dom': '@pyreon/react-compat/dom',\n 'react-dom/client': '@pyreon/react-compat/dom',\n },\n preact: {\n preact: '@pyreon/preact-compat',\n 'preact/hooks': '@pyreon/preact-compat/hooks',\n 'preact/jsx-runtime': '@pyreon/preact-compat/jsx-runtime',\n 'preact/jsx-dev-runtime': '@pyreon/preact-compat/jsx-runtime',\n '@preact/signals': '@pyreon/preact-compat/signals',\n },\n vue: {\n vue: '@pyreon/vue-compat',\n 'vue/jsx-runtime': '@pyreon/vue-compat/jsx-runtime',\n 'vue/jsx-dev-runtime': '@pyreon/vue-compat/jsx-runtime',\n },\n solid: {\n 'solid-js': '@pyreon/solid-compat',\n 'solid-js/jsx-runtime': '@pyreon/solid-compat/jsx-runtime',\n 'solid-js/jsx-dev-runtime': '@pyreon/solid-compat/jsx-runtime',\n },\n}\n\n/**\n * Return the Pyreon compat target for an import specifier, or undefined if\n * the import should not be redirected.\n */\nfunction getCompatTarget(compat: CompatFramework | undefined, id: string): string | undefined {\n if (!compat) return undefined\n const aliased = COMPAT_ALIASES[compat][id]\n if (aliased) return aliased\n // OXC's JSX transform reads jsxImportSource from tsconfig (@pyreon/core),\n // not from our plugin config. Redirect JSX runtime imports in compat mode.\n if (id === '@pyreon/core/jsx-runtime' || id === '@pyreon/core/jsx-dev-runtime') {\n if (compat === 'react') return '@pyreon/react-compat/jsx-runtime'\n if (compat === 'preact') return '@pyreon/preact-compat/jsx-runtime'\n if (compat === 'vue') return '@pyreon/vue-compat/jsx-runtime'\n if (compat === 'solid') return '@pyreon/solid-compat/jsx-runtime'\n }\n return undefined\n}\n\nexport default function pyreonPlugin(options?: PyreonPluginOptions): Plugin {\n const ssrConfig = options?.ssr\n const compat = options?.compat\n let isBuild = false\n let projectRoot = ''\n\n return {\n name: 'pyreon',\n enforce: 'pre',\n\n config(userConfig, env) {\n isBuild = env.command === 'build'\n // Capture the project root for package resolution in resolveId\n projectRoot = userConfig.root ?? process.cwd()\n\n // Tell Vite's dep scanner not to pre-bundle the aliased framework imports —\n // they resolve to workspace packages via our resolveId hook, not node_modules.\n const optimizeDepsExclude = compat ? Object.keys(COMPAT_ALIASES[compat]) : []\n\n const jsxSource = compat ? COMPAT_JSX_SOURCE[compat] : '@pyreon/core'\n\n return {\n // Use \"bun\" condition for workspace resolution — source .ts/.tsx files\n // for HMR, fast refresh, and type-safe imports.\n resolve: { conditions: ['bun'] },\n optimizeDeps: {\n exclude: optimizeDepsExclude,\n },\n // Vite 8 uses oxc for JSX transform (not esbuildOptions or rolldownOptions)\n oxc: {\n jsx: {\n runtime: 'automatic',\n importSource: jsxSource,\n },\n },\n // In SSR build mode, configure the entry\n ...(env.isSsrBuild && ssrConfig\n ? {\n build: {\n ssr: true,\n rollupOptions: {\n input: ssrConfig.entry,\n },\n },\n }\n : {}),\n }\n },\n\n // ── Virtual module + compat alias resolution ─────────────────────────────\n async resolveId(id, importer) {\n if (id === HMR_RUNTIME_IMPORT) return HMR_RUNTIME_ID\n const target = getCompatTarget(compat, id)\n if (!target) return\n\n // Vite 8 resolves the \"bun\" condition natively via resolve.conditions.\n // Delegate to Vite's resolver instead of manual package.json parsing.\n const resolved = await this.resolve(target, importer, { skipSelf: true })\n return resolved?.id\n },\n\n load(id) {\n if (id === HMR_RUNTIME_ID) {\n return HMR_RUNTIME_SOURCE\n }\n },\n\n transform(code, id, transformOptions) {\n const ext = getExt(id)\n if (ext !== '.tsx' && ext !== '.jsx' && ext !== '.pyreon') return\n\n // In compat mode, skip Pyreon's reactive JSX transform but apply\n // attribute renames (className → class, htmlFor → for) so source code\n // that uses React-style attribute names works correctly.\n if (compat === 'react' || compat === 'preact' || compat === 'vue' || compat === 'solid') {\n if (compat === 'react' || compat === 'preact') {\n const transformed = transformCompatAttributes(code)\n if (transformed !== code) return { code: transformed, map: null }\n }\n return\n }\n\n // Vite passes `ssr: true` when transforming for the SSR module graph\n // (both build --ssr and dev `ssrLoadModule`). The compiler emits plain\n // `h()` calls in that mode so `runtime-server` can render to a string.\n const isSsr = transformOptions?.ssr === true\n const result = transformJSX(code, id, { ssr: isSsr })\n // Surface compiler warnings in the terminal\n for (const w of result.warnings) {\n this.warn(`${w.message} (${id}:${w.line}:${w.column})`)\n }\n\n let output = result.code\n\n // ── Dev-only transforms ────────────────────────────────────────────\n if (!isBuild) {\n output = injectHmr(output, id)\n // Inject debug names for signal() calls not rewritten by HMR\n output = injectSignalNames(output)\n }\n\n return { code: output, map: null }\n },\n\n // ── SSR dev middleware ───────────────────────────────────────────────────\n configureServer(server: ViteDevServer) {\n // Generate .pyreon/context.json for AI tools on dev server start\n generateProjectContext(projectRoot)\n\n // Debounced regeneration on file changes\n let contextTimer: ReturnType<typeof setTimeout> | null = null\n server.watcher.on('change', (file) => {\n if (/\\.(tsx|jsx|ts|js)$/.test(file) && !file.includes('node_modules')) {\n if (contextTimer) clearTimeout(contextTimer)\n contextTimer = setTimeout(() => generateProjectContext(projectRoot), 500)\n }\n })\n\n if (!ssrConfig) return\n\n // Return a function so the middleware runs AFTER Vite's built-in middleware\n // (static files, HMR, etc.) — only handle requests that Vite doesn't serve.\n return () => {\n server.middlewares.use(async (req, res, next) => {\n if (req.method !== 'GET') return next()\n const url = req.url ?? '/'\n if (isAssetRequest(url)) return next()\n\n try {\n await handleSsrRequest(server, ssrConfig.entry, url, req, res, next)\n } catch (err) {\n server.ssrFixStacktrace(err as Error)\n next(err)\n }\n })\n }\n },\n }\n}\n\nasync function handleSsrRequest(\n server: ViteDevServer,\n entry: string,\n url: string,\n req: import('node:http').IncomingMessage,\n res: import('node:http').ServerResponse,\n next: (err?: unknown) => void,\n): Promise<void> {\n const mod = await server.ssrLoadModule(entry)\n const handler = mod.handler ?? mod.default\n\n if (typeof handler !== 'function') {\n next()\n return\n }\n\n const origin = `http://${req.headers.host ?? 'localhost'}`\n const fullUrl = new URL(url, origin)\n const request = new Request(fullUrl.href, {\n method: req.method ?? 'GET',\n headers: Object.entries(req.headers).reduce((h, [k, v]) => {\n if (v) h.set(k, Array.isArray(v) ? v.join(', ') : v)\n return h\n }, new Headers()),\n })\n\n const response: Response = await handler(request)\n let html = await response.text()\n\n html = await server.transformIndexHtml(url, html)\n\n res.statusCode = response.status\n response.headers.forEach((v, k) => {\n res.setHeader(k, v)\n })\n res.end(html)\n}\n\n// ── AI context generation ─────────────────────────────────────────────────────\n\n/**\n * Generate .pyreon/context.json — project map for AI coding assistants.\n * Delegates to @pyreon/compiler's unified project scanner.\n */\nfunction generateProjectContext(root: string): void {\n try {\n const context = generateContext(root)\n const outDir = pathJoin(root, '.pyreon')\n if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true })\n writeFileSync(pathJoin(outDir, 'context.json'), JSON.stringify(context, null, 2), 'utf-8')\n } catch {\n // Silently fail — context generation is best-effort\n }\n}\n\n// ── HMR injection ─────────────────────────────────────────────────────────────\n\n/**\n * Regex that detects signal declarations (prefix + variable name).\n * The arguments are extracted via balanced-paren matching in `injectHmr`.\n * A brace-depth check filters out matches inside functions/blocks — only\n * module-scope (depth 0) signals are rewritten for HMR state preservation.\n */\nconst SIGNAL_PREFIX_RE = /^((?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*)signal\\(/gm\n\n/**\n * Detect whether the module exports any component-like functions\n * (uppercase first letter — standard convention for JSX components).\n */\nconst EXPORT_COMPONENT_RE =\n /export\\s+(?:default\\s+)?(?:function\\s+([A-Z]\\w*)|const\\s+([A-Z]\\w*)\\s*[=:])/\n\nfunction skipStringLiteral(code: string, start: number, quote: string): number {\n let j = start + 1\n while (j < code.length) {\n if (code[j] === '\\\\') {\n j += 2\n continue\n }\n if (code[j] === quote) break\n j++\n }\n return j\n}\n\nfunction extractBalancedArgs(code: string, start: number): string | null {\n let depth = 1\n for (let i = start; i < code.length; i++) {\n const ch = code[i]\n if (ch === '(') depth++\n else if (ch === ')') {\n depth--\n if (depth === 0) return code.slice(start, i)\n } else if (ch === '\"' || ch === \"'\" || ch === '`') {\n i = skipStringLiteral(code, i, ch)\n }\n }\n return null\n}\n\n/**\n * Compute brace depth at position `pos` — returns 0 for module scope.\n * Skips string literals to avoid counting braces inside strings.\n */\nfunction braceDepthAt(code: string, pos: number): number {\n let depth = 0\n for (let i = 0; i < pos; i++) {\n const ch = code[i]\n if (ch === '{') depth++\n else if (ch === '}') depth--\n else if (ch === '\"' || ch === \"'\" || ch === '`') {\n i = skipStringLiteral(code, i, ch)\n }\n }\n return depth\n}\n\n/** Rewrite module-scope `signal()` calls to `__hmr_signal()` for state preservation. */\nfunction rewriteSignals(code: string, moduleId: string): string {\n const escapedId = JSON.stringify(moduleId)\n const matches: {\n start: number\n end: number\n prefix: string\n name: string\n args: string\n }[] = []\n let m: RegExpExecArray | null = SIGNAL_PREFIX_RE.exec(code)\n while (m !== null) {\n const argsStart = m.index + m[0].length\n const args = extractBalancedArgs(code, argsStart)\n if (args === null) {\n m = SIGNAL_PREFIX_RE.exec(code)\n continue // unbalanced — skip\n }\n // Only rewrite module-scope signals (brace depth 0).\n if (braceDepthAt(code, m.index) === 0) {\n matches.push({\n start: m.index,\n end: argsStart + args.length + 1, // +1 for closing paren\n prefix: m[1] ?? '',\n name: m[2] ?? '',\n args,\n })\n }\n m = SIGNAL_PREFIX_RE.exec(code)\n }\n SIGNAL_PREFIX_RE.lastIndex = 0\n\n // Replace in reverse to preserve offsets\n let output = code\n for (let i = matches.length - 1; i >= 0; i--) {\n const { start, end, prefix, name, args } = matches[i] as (typeof matches)[number]\n const replacement = `${prefix}__hmr_signal(${escapedId}, ${JSON.stringify(name)}, signal, ${args})`\n output = output.slice(0, start) + replacement + output.slice(end)\n }\n return output\n}\n\n/** Check if an argument string contains a top-level comma (i.e. has multiple arguments). */\nfunction hasMultipleArgs(args: string): boolean {\n let depth = 0\n for (const ch of args) {\n if (ch === '(' || ch === '[' || ch === '{') depth++\n else if (ch === ')' || ch === ']' || ch === '}') depth--\n else if (ch === ',' && depth === 0) return true\n }\n return false\n}\n\n/**\n * Inject `{ name: \"varName\" }` into signal() calls that don't already have\n * an options argument. Only runs in dev mode for debugging/devtools.\n *\n * `const count = signal(0)` → `const count = signal(0, { name: \"count\" })`\n *\n * Module-scope signals rewritten to __hmr_signal() are naturally skipped\n * because the regex matches `signal(` not `__hmr_signal(`.\n */\nfunction injectSignalNames(code: string): string {\n const re = /(?:const|let)\\s+(\\w+)\\s*=\\s*signal\\(/gm\n const matches: { start: number; end: number; name: string; args: string }[] = []\n\n let m: RegExpExecArray | null = re.exec(code)\n while (m !== null) {\n const argsStart = m.index + m[0].length\n const args = extractBalancedArgs(code, argsStart)\n if (args !== null && !hasMultipleArgs(args)) {\n matches.push({ start: argsStart, end: argsStart + args.length, name: m[1] ?? '', args })\n }\n m = re.exec(code)\n }\n re.lastIndex = 0\n\n let output = code\n for (let i = matches.length - 1; i >= 0; i--) {\n const { start, end, name, args } = matches[i] as (typeof matches)[number]\n output = `${output.slice(0, start)}${args}, { name: ${JSON.stringify(name)} }${output.slice(end)}`\n }\n return output\n}\n\nfunction injectHmr(code: string, moduleId: string): string {\n const hasSignals = SIGNAL_PREFIX_RE.test(code)\n SIGNAL_PREFIX_RE.lastIndex = 0\n\n const hasComponentExport = EXPORT_COMPONENT_RE.test(code)\n\n // Only inject HMR if the module exports components or has module-scope signals\n if (!hasComponentExport && !hasSignals) return code\n\n let output = hasSignals ? rewriteSignals(code, moduleId) : code\n\n // Build the HMR footer\n const escapedId = JSON.stringify(moduleId)\n const lines: string[] = []\n\n if (hasSignals) {\n lines.push(`import { __hmr_signal, __hmr_dispose } from \"${HMR_RUNTIME_IMPORT}\";`)\n }\n\n lines.push(`if (import.meta.hot) {`)\n\n if (hasSignals) {\n lines.push(` import.meta.hot.dispose(() => __hmr_dispose(${escapedId}));`)\n }\n\n lines.push(` import.meta.hot.accept();`)\n lines.push(`}`)\n\n output = `${output}\\n\\n${lines.join('\\n')}\\n`\n\n return output\n}\n\n// ── Compat attribute transforms ──────────────────────────────────────────────\n\n/**\n * Transform React-style JSX attribute names to standard HTML attribute names.\n * This is a lightweight string transform that runs on JSX source before OXC's\n * JSX transform converts it to jsx() calls.\n *\n * - `className` → `class`\n * - `htmlFor` → `for`\n *\n * Only matches attribute position in JSX (after `<tag ` or whitespace).\n * Does not transform property access (e.g. `props.className` stays as-is since\n * the compat JSX runtime handles that at call time).\n */\nfunction transformCompatAttributes(code: string): string {\n // Match className/htmlFor in JSX attribute position:\n // After < and tag name, or after whitespace between attributes\n // Pattern: word boundary + attribute name + = (with optional whitespace)\n return code\n .replace(/(\\s)className(\\s*=)/g, '$1class$2')\n .replace(/(\\s)htmlFor(\\s*=)/g, '$1for$2')\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction getExt(id: string): string {\n const clean = id.split('?')[0] ?? id\n const dot = clean.lastIndexOf('.')\n return dot >= 0 ? clean.slice(dot) : ''\n}\n\n/** Skip Vite-handled asset requests (CSS, images, HMR, etc.) */\nfunction isAssetRequest(url: string): boolean {\n return (\n url.startsWith('/@') || // @vite/client, @id, @fs, etc.\n url.startsWith('/__') || // __open-in-editor, etc.\n url.includes('/node_modules/') ||\n /\\.(css|js|ts|tsx|jsx|json|ico|png|jpg|jpeg|gif|svg|woff2?|ttf|eot|map)(\\?|$)/.test(url)\n )\n}\n\n// ── HMR runtime source (served as virtual module) ─────────────────────────────\n//\n// Inlined here so it's available without a filesystem read. This is the\n// compiled-to-JS version of hmr-runtime.ts — kept in sync manually.\n\nconst HMR_RUNTIME_SOURCE = `\nconst REGISTRY_KEY = \"__pyreon_hmr_registry__\";\n\nfunction getRegistry() {\n if (!globalThis[REGISTRY_KEY]) {\n globalThis[REGISTRY_KEY] = new Map();\n }\n return globalThis[REGISTRY_KEY];\n}\n\nconst moduleSignals = new Map();\n\nexport function __hmr_signal(moduleId, name, signalFn, initialValue) {\n const registry = getRegistry();\n const saved = registry.get(moduleId);\n const value = saved?.has(name) ? saved.get(name) : initialValue;\n const s = signalFn(value, { name: name });\n\n let mod = moduleSignals.get(moduleId);\n if (!mod) {\n mod = { entries: new Map() };\n moduleSignals.set(moduleId, mod);\n }\n mod.entries.set(name, s);\n\n return s;\n}\n\nexport function __hmr_dispose(moduleId) {\n const mod = moduleSignals.get(moduleId);\n if (!mod) return;\n\n const registry = getRegistry();\n const saved = new Map();\n for (const [name, s] of mod.entries) {\n saved.set(name, s.peek());\n }\n registry.set(moduleId, saved);\n moduleSignals.delete(moduleId);\n}\n`\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/index.ts"],"mappings":";;;KA2CY,eAAA;AAAA,UAEK,mBAAA;;;;;;;;;;;;;EAaf,MAAA,GAAS,eAAA;;;;;;;;;;;EAYT,GAAA;gEAEE,KAAA;EAAA;AAAA;AAAA,iBA6DoB,YAAA,CAAa,OAAA,GAAU,mBAAA,GAAsB,MAAA"}