@pyreon/vite-plugin 0.22.0 → 0.24.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.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @pyreon/vite-plugin
2
2
 
3
- Vite plugin for the Pyreon framework. Applies the Pyreon JSX reactive transform to `.tsx`, `.jsx`, and `.pyreon` files, and optionally adds SSR dev middleware.
3
+ Vite plugin for Pyreon JSX transform, signal-preserving HMR, SSR middleware, islands auto-registry, compat aliasing.
4
+
5
+ `@pyreon/vite-plugin` is the single Vite integration Pyreon needs. It wires `@pyreon/compiler` into Vite's transform pipeline, sets `resolve.conditions: ["bun"]` so workspace source files resolve via the `bun` condition, configures the JSX runtime to `@pyreon/core`, and provides signal-preserving HMR (top-level `signal()` values survive hot reload). Optional features: SSR dev middleware (`ssr.entry`), an auto-discovered islands registry (`islands: true`, the `virtual:pyreon/islands-registry` module fed to `hydrateIslandsAuto()`), drop-in compat-mode aliasing (`compat: 'react' | 'preact' | 'vue' | 'solid' | 'svelte'`), and the opt-in compile-time rocketstyle wrapper collapse (`collapse: true`, build-only).
4
6
 
5
7
  ## Install
6
8
 
@@ -8,7 +10,7 @@ Vite plugin for the Pyreon framework. Applies the Pyreon JSX reactive transform
8
10
  bun add -D @pyreon/vite-plugin
9
11
  ```
10
12
 
11
- ## Quick Start (SPA)
13
+ ## Quick start (SPA)
12
14
 
13
15
  ```ts
14
16
  // vite.config.ts
@@ -20,21 +22,30 @@ export default defineConfig({
20
22
  })
21
23
  ```
22
24
 
23
- ## SSR Mode
25
+ `tsconfig.json`:
24
26
 
25
- Pass an `ssr` option to enable SSR dev middleware. The plugin will load your server entry via Vite's `ssrLoadModule` and call its exported `handler` function for every non-asset GET request.
27
+ ```jsonc
28
+ {
29
+ "extends": "@pyreon/typescript/app",
30
+ "compilerOptions": {
31
+ "jsx": "react-jsx",
32
+ "jsxImportSource": "@pyreon/core"
33
+ }
34
+ }
35
+ ```
36
+
37
+ ## SSR dev mode
26
38
 
27
39
  ```ts
28
40
  // vite.config.ts
29
41
  import pyreon from '@pyreon/vite-plugin'
30
- import { defineConfig } from 'vite'
31
42
 
32
- export default defineConfig({
43
+ export default {
33
44
  plugins: [pyreon({ ssr: { entry: './src/entry-server.ts' } })],
34
- })
45
+ }
35
46
  ```
36
47
 
37
- Your server entry must export a `handler` (or default export) with the signature `(req: Request) => Promise<Response>`:
48
+ The entry must export a `handler` (or default export) of shape `(req: Request) => Promise<Response>`:
38
49
 
39
50
  ```tsx
40
51
  // src/entry-server.ts
@@ -43,35 +54,96 @@ import App from './App'
43
54
 
44
55
  export async function handler(req: Request): Promise<Response> {
45
56
  const html = await renderToString(<App />)
46
- return new Response(html, {
47
- headers: { 'Content-Type': 'text/html' },
48
- })
57
+ return new Response(html, { headers: { 'Content-Type': 'text/html' } })
49
58
  }
50
59
  ```
51
60
 
52
- For production, build client and server bundles separately:
61
+ Production builds:
53
62
 
54
63
  ```bash
55
64
  vite build # client bundle
56
65
  vite build --ssr src/entry-server.ts --outDir dist/server # server bundle
57
66
  ```
58
67
 
59
- ## API
68
+ ## Drop-in compat mode
69
+
70
+ Alias an existing framework's imports to Pyreon's compat layer — zero code changes:
71
+
72
+ ```ts
73
+ pyreon({ compat: 'react' }) // react + react-dom → @pyreon/react-compat
74
+ pyreon({ compat: 'preact' }) // preact + hooks + signals → @pyreon/preact-compat
75
+ pyreon({ compat: 'vue' }) // vue → @pyreon/vue-compat
76
+ pyreon({ compat: 'solid' }) // solid-js → @pyreon/solid-compat
77
+ pyreon({ compat: 'svelte' }) // svelte + svelte/store → @pyreon/svelte-compat
78
+ ```
79
+
80
+ Framework-internal `@pyreon/*` files are detected and skip the redirect so published `@pyreon/zero` etc. still load their real JSX runtime.
81
+
82
+ ## Islands auto-registry
83
+
84
+ ```ts
85
+ pyreon({ islands: true }) // default on
86
+ ```
87
+
88
+ Pre-scans `island(() => import('PATH'), { name, hydrate })` calls at `buildStart` and emits `virtual:pyreon/islands-registry`. Consume it in your client entry:
89
+
90
+ ```ts
91
+ // src/entry-client.ts
92
+ import { hydrateIslandsAuto } from '@pyreon/server/client'
93
+ import islands from 'virtual:pyreon/islands-registry'
94
+
95
+ hydrateIslandsAuto(islands)
96
+ ```
97
+
98
+ `hydrate: 'never'` islands are deliberately OMITTED from the registry — the strategy ships zero client JS, so registering a loader (which would pull the component into the client bundle graph) would defeat it. Manual `hydrateIslands({ … })` stays public for non-Vite consumers.
99
+
100
+ ## Rocketstyle collapse (opt-in, build-only)
101
+
102
+ ```ts
103
+ pyreon({ collapse: true })
104
+ // or with overrides
105
+ pyreon({ collapse: { sources: ['@pyreon/ui-components'], components: ['Button'] } })
106
+ ```
107
+
108
+ A literal-prop rocketstyle call site (`<Button state="primary" size="medium">Save</Button>`) collapses from a 5-layer wrapper mount into one `_rsCollapse` cloneNode. The plugin SSR-resolves the real component twice (light + dark) and the compiler bakes the classes into a `_tpl` template. **Build-only** by design — dev keeps the normal mount so theme-source HMR edits stay reactive.
109
+
110
+ ## Options
111
+
112
+ | Option | Type | Description |
113
+ | ------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
114
+ | `compat` | `'react' \| 'preact' \| 'vue' \| 'solid' \| 'svelte'` | Alias an existing framework's imports to the matching `@pyreon/*-compat` package. |
115
+ | `ssr.entry` | `string` | Server entry path. Enables SSR dev middleware. |
116
+ | `islands` | `boolean` | Auto-discover `island()` declarations into `virtual:pyreon/islands-registry`. Default `true`. |
117
+ | `collapse` | `boolean \| PyreonCollapseOptions` | Opt-in compile-time rocketstyle wrapper collapse. OFF by default. Build-only. |
118
+
119
+ `PyreonCollapseOptions`: `sources?: string[]` (default `['@pyreon/ui-components']`), `components?: string[]` (optional local-name allowlist), `provider?: { name, source }` (default `PyreonUI@@pyreon/ui-core`), `theme?: { name, source }` (default `theme@@pyreon/ui-theme`), `mode?: { name, source }` (default `useMode@@pyreon/ui-core`).
120
+
121
+ ## What it does
122
+
123
+ - Wires `@pyreon/compiler`'s JSX reactive transform into `.tsx` / `.jsx` / `.pyreon` files (auto-call signals, hoist static subtrees, `_tpl` + `_bind`).
124
+ - Sets `resolve.conditions: ["bun"]` so Pyreon workspace source files resolve through the `bun` condition (no separate build step in dev).
125
+ - Configures the JSX runtime to `@pyreon/core` via `esbuild.jsx = 'automatic'` + `jsxImportSource`.
126
+ - In dev: auto-injects debug names into `signal()` calls so devtools show meaningful labels.
127
+ - In dev SSR: catch-all middleware loads the server entry via `ssrLoadModule` and renders every non-asset request.
128
+ - Provides signal-preserving HMR via `virtual:pyreon/hmr-runtime` — top-level signal values survive hot reload.
129
+ - Component-level fast-refresh: edits to a route component re-render in place via the router's `_hmrSwap` coordinator (registered on `globalThis.__pyreon_hmr_swap__`).
130
+ - Pre-scans signal exports across files so cross-module signal references auto-call correctly.
131
+
132
+ ## Gotchas
133
+
134
+ - **Vite's config bundler hardcodes `conditions: ["node"]`** — plugin source changes are INVISIBLE to a running dev server until `lib/` is rebuilt. After editing the plugin, `bun run --filter='@pyreon/vite-plugin' build` + restart Vite.
135
+ - **Compat-mode applies `jsxImportSource`** automatically for the user's code. Set `jsxImportSource: "@pyreon/<compat>-compat"` in your tsconfig for type resolution.
136
+ - **`collapse` is build-only by design.** Dev keeps the normal mount (HMR-reactive); the plugin emits `this.info('[Pyreon] collapse is build-only …')` once per dev process if `collapse: true` is set in `vite dev`.
137
+ - **HMR accept callback uses the fresh module Vite hands it** — NOT a re-run of the lazy import thunk (that would return the frozen `?t=` old module).
60
138
 
61
- ### `pyreonPlugin(options?)`
139
+ ## Peer dependencies
62
140
 
63
- Default export. Returns a Vite `Plugin`.
141
+ - `vite >= 8.0.0`
64
142
 
65
- ### Options
143
+ ## Documentation
66
144
 
67
- | Option | Type | Description |
68
- | ----------- | -------- | --------------------------------------------------- |
69
- | `ssr.entry` | `string` | Server entry file path. Enables SSR dev middleware. |
145
+ Full docs: [docs.pyreon.dev/docs/vite-plugin](https://docs.pyreon.dev/docs/vite-plugin) (or `docs/docs/vite-plugin.md` in this repo).
70
146
 
71
- ## What It Does
147
+ ## License
72
148
 
73
- - Configures `resolve.conditions: ["bun"]` so Vite resolves Pyreon workspace source files.
74
- - Sets `esbuild.jsx` to `automatic` with `@pyreon/core` as the JSX import source.
75
- - Transforms `.tsx`, `.jsx`, and `.pyreon` files through `@pyreon/compiler` for reactive JSX optimizations.
76
- - In dev mode, auto-injects debug names into `signal()` calls so devtools show meaningful labels instead of "anonymous".
77
- - In SSR mode, adds a catch-all middleware that renders pages through your server entry with full HMR support.
149
+ MIT
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src/index.ts","uid":"f3fd0c0b-1"}]},{"name":"rocketstyle-collapse-C4eMAnwR.js","children":[{"name":"src/rocketstyle-collapse.ts","uid":"f3fd0c0b-3"}]}],"isRoot":true},"nodeParts":{"f3fd0c0b-1":{"renderedLength":33323,"gzipLength":10763,"brotliLength":0,"metaUid":"f3fd0c0b-0"},"f3fd0c0b-3":{"renderedLength":3424,"gzipLength":1530,"brotliLength":0,"metaUid":"f3fd0c0b-2"}},"nodeMetas":{"f3fd0c0b-0":{"id":"/src/index.ts","moduleParts":{"index.js":"f3fd0c0b-1"},"imported":[{"uid":"f3fd0c0b-4"},{"uid":"f3fd0c0b-5"},{"uid":"f3fd0c0b-6"},{"uid":"f3fd0c0b-2","dynamic":true}],"importedBy":[],"isEntry":true},"f3fd0c0b-2":{"id":"/src/rocketstyle-collapse.ts","moduleParts":{"rocketstyle-collapse-C4eMAnwR.js":"f3fd0c0b-3"},"imported":[{"uid":"f3fd0c0b-7","dynamic":true}],"importedBy":[{"uid":"f3fd0c0b-0"}]},"f3fd0c0b-4":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"f3fd0c0b-0"}]},"f3fd0c0b-5":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"f3fd0c0b-0"}]},"f3fd0c0b-6":{"id":"@pyreon/compiler","moduleParts":{},"imported":[],"importedBy":[{"uid":"f3fd0c0b-0"}]},"f3fd0c0b-7":{"id":"vite","moduleParts":{},"imported":[],"importedBy":[{"uid":"f3fd0c0b-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src/index.ts","uid":"e04d9c6c-1"}]},{"name":"rocketstyle-collapse-C4eMAnwR.js","children":[{"name":"src/rocketstyle-collapse.ts","uid":"e04d9c6c-3"}]}],"isRoot":true},"nodeParts":{"e04d9c6c-1":{"renderedLength":45559,"gzipLength":14773,"brotliLength":0,"metaUid":"e04d9c6c-0"},"e04d9c6c-3":{"renderedLength":3424,"gzipLength":1530,"brotliLength":0,"metaUid":"e04d9c6c-2"}},"nodeMetas":{"e04d9c6c-0":{"id":"/src/index.ts","moduleParts":{"index.js":"e04d9c6c-1"},"imported":[{"uid":"e04d9c6c-4"},{"uid":"e04d9c6c-5"},{"uid":"e04d9c6c-6"},{"uid":"e04d9c6c-2","dynamic":true},{"uid":"e04d9c6c-7","dynamic":true}],"importedBy":[],"isEntry":true},"e04d9c6c-2":{"id":"/src/rocketstyle-collapse.ts","moduleParts":{"rocketstyle-collapse-C4eMAnwR.js":"e04d9c6c-3"},"imported":[{"uid":"e04d9c6c-8","dynamic":true}],"importedBy":[{"uid":"e04d9c6c-0"}]},"e04d9c6c-4":{"id":"node:fs","moduleParts":{},"imported":[],"importedBy":[{"uid":"e04d9c6c-0"}]},"e04d9c6c-5":{"id":"node:path","moduleParts":{},"imported":[],"importedBy":[{"uid":"e04d9c6c-0"}]},"e04d9c6c-6":{"id":"@pyreon/compiler","moduleParts":{},"imported":[],"importedBy":[{"uid":"e04d9c6c-0"}]},"e04d9c6c-7":{"id":"node:fs/promises","moduleParts":{},"imported":[],"importedBy":[{"uid":"e04d9c6c-0"}]},"e04d9c6c-8":{"id":"vite","moduleParts":{},"imported":[],"importedBy":[{"uid":"e04d9c6c-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;