@pyreon/vite-plugin 0.1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/lib/analysis/index.js.html +5406 -0
- package/lib/index.js +256 -0
- package/lib/index.js.map +1 -0
- package/lib/types/index.d.ts +217 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index2.d.ts +22 -0
- package/lib/types/index2.d.ts.map +1 -0
- package/package.json +49 -0
- package/src/hmr-runtime.ts +92 -0
- package/src/index.ts +376 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { transformJSX } from "@pyreon/compiler";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* @pyreon/vite-plugin — Vite integration for Pyreon framework.
|
|
6
|
+
*
|
|
7
|
+
* Applies Pyreon's JSX reactive transform to .tsx, .jsx, and .pyreon files,
|
|
8
|
+
* and configures Vite to use Pyreon's JSX runtime.
|
|
9
|
+
*
|
|
10
|
+
* ## Basic usage (SPA)
|
|
11
|
+
*
|
|
12
|
+
* import pyreon from "@pyreon/vite-plugin"
|
|
13
|
+
* export default { plugins: [pyreon()] }
|
|
14
|
+
*
|
|
15
|
+
* ## SSR mode
|
|
16
|
+
*
|
|
17
|
+
* import pyreon from "@pyreon/vite-plugin"
|
|
18
|
+
* export default { plugins: [pyreon({ ssr: { entry: "./src/entry-server.ts" } })] }
|
|
19
|
+
*
|
|
20
|
+
* In SSR mode, the plugin adds dev server middleware that:
|
|
21
|
+
* 1. Loads your server entry via Vite's `ssrLoadModule`
|
|
22
|
+
* 2. Calls the exported `handler` or default export (Request → Response)
|
|
23
|
+
* 3. Returns the SSR'd HTML for every non-asset request
|
|
24
|
+
*
|
|
25
|
+
* For production, build separately:
|
|
26
|
+
* vite build # client bundle
|
|
27
|
+
* vite build --ssr src/entry-server.ts --outDir dist/server # server bundle
|
|
28
|
+
*/
|
|
29
|
+
const HMR_RUNTIME_ID = "\0pyreon/hmr-runtime";
|
|
30
|
+
const HMR_RUNTIME_IMPORT = "virtual:pyreon/hmr-runtime";
|
|
31
|
+
function pyreonPlugin(options) {
|
|
32
|
+
const ssrConfig = options?.ssr;
|
|
33
|
+
let isBuild = false;
|
|
34
|
+
return {
|
|
35
|
+
name: "pyreon",
|
|
36
|
+
enforce: "pre",
|
|
37
|
+
config(_, env) {
|
|
38
|
+
isBuild = env.command === "build";
|
|
39
|
+
return {
|
|
40
|
+
resolve: { conditions: ["bun"] },
|
|
41
|
+
esbuild: {
|
|
42
|
+
jsx: "automatic",
|
|
43
|
+
jsxImportSource: "@pyreon/core"
|
|
44
|
+
},
|
|
45
|
+
...env.isSsrBuild && ssrConfig ? { build: {
|
|
46
|
+
ssr: true,
|
|
47
|
+
rollupOptions: { input: ssrConfig.entry }
|
|
48
|
+
} } : {}
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
resolveId(id) {
|
|
52
|
+
if (id === HMR_RUNTIME_IMPORT) return HMR_RUNTIME_ID;
|
|
53
|
+
},
|
|
54
|
+
load(id) {
|
|
55
|
+
if (id === HMR_RUNTIME_ID) return HMR_RUNTIME_SOURCE;
|
|
56
|
+
},
|
|
57
|
+
transform(code, id) {
|
|
58
|
+
const ext = getExt(id);
|
|
59
|
+
if (ext !== ".tsx" && ext !== ".jsx" && ext !== ".pyreon") return;
|
|
60
|
+
const result = transformJSX(code, id);
|
|
61
|
+
for (const w of result.warnings) this.warn(`${w.message} (${id}:${w.line}:${w.column})`);
|
|
62
|
+
let output = result.code;
|
|
63
|
+
if (!isBuild) output = injectHmr(output, id);
|
|
64
|
+
return {
|
|
65
|
+
code: output,
|
|
66
|
+
map: null
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
configureServer(server) {
|
|
70
|
+
if (!ssrConfig) return;
|
|
71
|
+
return () => {
|
|
72
|
+
server.middlewares.use(async (req, res, next) => {
|
|
73
|
+
if (req.method !== "GET") return next();
|
|
74
|
+
const url = req.url ?? "/";
|
|
75
|
+
if (isAssetRequest(url)) return next();
|
|
76
|
+
try {
|
|
77
|
+
await handleSsrRequest(server, ssrConfig.entry, url, req, res, next);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
server.ssrFixStacktrace(err);
|
|
80
|
+
next(err);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
async function handleSsrRequest(server, entry, url, req, res, next) {
|
|
88
|
+
const mod = await server.ssrLoadModule(entry);
|
|
89
|
+
const handler = mod.handler ?? mod.default;
|
|
90
|
+
if (typeof handler !== "function") {
|
|
91
|
+
next();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const origin = `http://${req.headers.host ?? "localhost"}`;
|
|
95
|
+
const fullUrl = new URL(url, origin);
|
|
96
|
+
const response = await handler(new Request(fullUrl.href, {
|
|
97
|
+
method: req.method ?? "GET",
|
|
98
|
+
headers: Object.entries(req.headers).reduce((h, [k, v]) => {
|
|
99
|
+
if (v) h.set(k, Array.isArray(v) ? v.join(", ") : v);
|
|
100
|
+
return h;
|
|
101
|
+
}, new Headers())
|
|
102
|
+
}));
|
|
103
|
+
let html = await response.text();
|
|
104
|
+
html = await server.transformIndexHtml(url, html);
|
|
105
|
+
res.statusCode = response.status;
|
|
106
|
+
response.headers.forEach((v, k) => {
|
|
107
|
+
res.setHeader(k, v);
|
|
108
|
+
});
|
|
109
|
+
res.end(html);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Regex that detects signal declarations (prefix + variable name).
|
|
113
|
+
* The arguments are extracted via balanced-paren matching in `injectHmr`.
|
|
114
|
+
* A brace-depth check filters out matches inside functions/blocks — only
|
|
115
|
+
* module-scope (depth 0) signals are rewritten for HMR state preservation.
|
|
116
|
+
*/
|
|
117
|
+
const SIGNAL_PREFIX_RE = /^((?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*)signal\(/gm;
|
|
118
|
+
/**
|
|
119
|
+
* Detect whether the module exports any component-like functions
|
|
120
|
+
* (uppercase first letter — standard convention for JSX components).
|
|
121
|
+
*/
|
|
122
|
+
const EXPORT_COMPONENT_RE = /export\s+(?:default\s+)?(?:function\s+([A-Z]\w*)|const\s+([A-Z]\w*)\s*[=:])/;
|
|
123
|
+
function skipStringLiteral(code, start, quote) {
|
|
124
|
+
let j = start + 1;
|
|
125
|
+
while (j < code.length) {
|
|
126
|
+
if (code[j] === "\\") {
|
|
127
|
+
j += 2;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (code[j] === quote) break;
|
|
131
|
+
j++;
|
|
132
|
+
}
|
|
133
|
+
return j;
|
|
134
|
+
}
|
|
135
|
+
function extractBalancedArgs(code, start) {
|
|
136
|
+
let depth = 1;
|
|
137
|
+
for (let i = start; i < code.length; i++) {
|
|
138
|
+
const ch = code[i];
|
|
139
|
+
if (ch === "(") depth++;
|
|
140
|
+
else if (ch === ")") {
|
|
141
|
+
depth--;
|
|
142
|
+
if (depth === 0) return code.slice(start, i);
|
|
143
|
+
} else if (ch === "\"" || ch === "'" || ch === "`") i = skipStringLiteral(code, i, ch);
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Compute brace depth at position `pos` — returns 0 for module scope.
|
|
149
|
+
* Skips string literals to avoid counting braces inside strings.
|
|
150
|
+
*/
|
|
151
|
+
function braceDepthAt(code, pos) {
|
|
152
|
+
let depth = 0;
|
|
153
|
+
for (let i = 0; i < pos; i++) {
|
|
154
|
+
const ch = code[i];
|
|
155
|
+
if (ch === "{") depth++;
|
|
156
|
+
else if (ch === "}") depth--;
|
|
157
|
+
else if (ch === "\"" || ch === "'" || ch === "`") i = skipStringLiteral(code, i, ch);
|
|
158
|
+
}
|
|
159
|
+
return depth;
|
|
160
|
+
}
|
|
161
|
+
function injectHmr(code, moduleId) {
|
|
162
|
+
const hasSignals = SIGNAL_PREFIX_RE.test(code);
|
|
163
|
+
SIGNAL_PREFIX_RE.lastIndex = 0;
|
|
164
|
+
if (!EXPORT_COMPONENT_RE.test(code) && !hasSignals) return code;
|
|
165
|
+
let output = code;
|
|
166
|
+
if (hasSignals) {
|
|
167
|
+
const escapedId = JSON.stringify(moduleId);
|
|
168
|
+
const matches = [];
|
|
169
|
+
let m = SIGNAL_PREFIX_RE.exec(code);
|
|
170
|
+
while (m !== null) {
|
|
171
|
+
const argsStart = m.index + m[0].length;
|
|
172
|
+
const args = extractBalancedArgs(code, argsStart);
|
|
173
|
+
if (args === null) {
|
|
174
|
+
m = SIGNAL_PREFIX_RE.exec(code);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (braceDepthAt(code, m.index) === 0) matches.push({
|
|
178
|
+
start: m.index,
|
|
179
|
+
end: argsStart + args.length + 1,
|
|
180
|
+
prefix: m[1] ?? "",
|
|
181
|
+
name: m[2] ?? "",
|
|
182
|
+
args
|
|
183
|
+
});
|
|
184
|
+
m = SIGNAL_PREFIX_RE.exec(code);
|
|
185
|
+
}
|
|
186
|
+
SIGNAL_PREFIX_RE.lastIndex = 0;
|
|
187
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
188
|
+
const { start, end, prefix, name, args } = matches[i];
|
|
189
|
+
const replacement = `${prefix}__hmr_signal(${escapedId}, ${JSON.stringify(name)}, signal, ${args})`;
|
|
190
|
+
output = output.slice(0, start) + replacement + output.slice(end);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const escapedId = JSON.stringify(moduleId);
|
|
194
|
+
const lines = [];
|
|
195
|
+
if (hasSignals) lines.push(`import { __hmr_signal, __hmr_dispose } from "${HMR_RUNTIME_IMPORT}";`);
|
|
196
|
+
lines.push(`if (import.meta.hot) {`);
|
|
197
|
+
if (hasSignals) lines.push(` import.meta.hot.dispose(() => __hmr_dispose(${escapedId}));`);
|
|
198
|
+
lines.push(` import.meta.hot.accept();`);
|
|
199
|
+
lines.push(`}`);
|
|
200
|
+
output = `${output}\n\n${lines.join("\n")}\n`;
|
|
201
|
+
return output;
|
|
202
|
+
}
|
|
203
|
+
function getExt(id) {
|
|
204
|
+
const clean = id.split("?")[0] ?? id;
|
|
205
|
+
const dot = clean.lastIndexOf(".");
|
|
206
|
+
return dot >= 0 ? clean.slice(dot) : "";
|
|
207
|
+
}
|
|
208
|
+
/** Skip Vite-handled asset requests (CSS, images, HMR, etc.) */
|
|
209
|
+
function isAssetRequest(url) {
|
|
210
|
+
return url.startsWith("/@") || url.startsWith("/__") || url.includes("/node_modules/") || /\.(css|js|ts|tsx|jsx|json|ico|png|jpg|jpeg|gif|svg|woff2?|ttf|eot|map)(\?|$)/.test(url);
|
|
211
|
+
}
|
|
212
|
+
const HMR_RUNTIME_SOURCE = `
|
|
213
|
+
const REGISTRY_KEY = "__pyreon_hmr_registry__";
|
|
214
|
+
|
|
215
|
+
function getRegistry() {
|
|
216
|
+
if (!globalThis[REGISTRY_KEY]) {
|
|
217
|
+
globalThis[REGISTRY_KEY] = new Map();
|
|
218
|
+
}
|
|
219
|
+
return globalThis[REGISTRY_KEY];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const moduleSignals = new Map();
|
|
223
|
+
|
|
224
|
+
export function __hmr_signal(moduleId, name, signalFn, initialValue) {
|
|
225
|
+
const registry = getRegistry();
|
|
226
|
+
const saved = registry.get(moduleId);
|
|
227
|
+
const value = saved?.has(name) ? saved.get(name) : initialValue;
|
|
228
|
+
const s = signalFn(value);
|
|
229
|
+
|
|
230
|
+
let mod = moduleSignals.get(moduleId);
|
|
231
|
+
if (!mod) {
|
|
232
|
+
mod = { entries: new Map() };
|
|
233
|
+
moduleSignals.set(moduleId, mod);
|
|
234
|
+
}
|
|
235
|
+
mod.entries.set(name, s);
|
|
236
|
+
|
|
237
|
+
return s;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function __hmr_dispose(moduleId) {
|
|
241
|
+
const mod = moduleSignals.get(moduleId);
|
|
242
|
+
if (!mod) return;
|
|
243
|
+
|
|
244
|
+
const registry = getRegistry();
|
|
245
|
+
const saved = new Map();
|
|
246
|
+
for (const [name, s] of mod.entries) {
|
|
247
|
+
saved.set(name, s.peek());
|
|
248
|
+
}
|
|
249
|
+
registry.set(moduleId, saved);
|
|
250
|
+
moduleSignals.delete(moduleId);
|
|
251
|
+
}
|
|
252
|
+
`;
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
export { pyreonPlugin as default };
|
|
256
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"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 * ## 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 { 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 interface PyreonPluginOptions {\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\nexport default function pyreonPlugin(options?: PyreonPluginOptions): Plugin {\n const ssrConfig = options?.ssr\n let isBuild = false\n\n return {\n name: \"pyreon\",\n enforce: \"pre\",\n\n config(_, env) {\n isBuild = env.command === \"build\"\n\n return {\n resolve: {\n conditions: [\"bun\"],\n },\n esbuild: {\n jsx: \"automatic\",\n jsxImportSource: \"@pyreon/core\",\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: HMR runtime ─────────────────────────────────────────\n resolveId(id) {\n if (id === HMR_RUNTIME_IMPORT) return HMR_RUNTIME_ID\n },\n\n load(id) {\n if (id === HMR_RUNTIME_ID) {\n return HMR_RUNTIME_SOURCE\n }\n },\n\n transform(code, id) {\n const ext = getExt(id)\n if (ext !== \".tsx\" && ext !== \".jsx\" && ext !== \".pyreon\") return\n const result = transformJSX(code, id)\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 // ── HMR injection (dev only) ────────────────────────────────────────\n if (!isBuild) {\n output = injectHmr(output, id)\n }\n\n return { code: output, map: null }\n },\n\n // ── SSR dev middleware ───────────────────────────────────────────────────\n configureServer(server: ViteDevServer) {\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// ── 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\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 = code\n\n // Rewrite top-level signal() calls to use __hmr_signal for state preservation\n if (hasSignals) {\n const escapedId = JSON.stringify(moduleId)\n // Process matches in reverse order so indices stay valid after replacement\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 // esbuild may strip indentation, so we can't rely on column position.\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 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 }\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// ── 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);\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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"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { transformJSX } from "@pyreon/compiler";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* @pyreon/vite-plugin — Vite integration for Pyreon framework.
|
|
6
|
+
*
|
|
7
|
+
* Applies Pyreon's JSX reactive transform to .tsx, .jsx, and .pyreon files,
|
|
8
|
+
* and configures Vite to use Pyreon's JSX runtime.
|
|
9
|
+
*
|
|
10
|
+
* ## Basic usage (SPA)
|
|
11
|
+
*
|
|
12
|
+
* import pyreon from "@pyreon/vite-plugin"
|
|
13
|
+
* export default { plugins: [pyreon()] }
|
|
14
|
+
*
|
|
15
|
+
* ## SSR mode
|
|
16
|
+
*
|
|
17
|
+
* import pyreon from "@pyreon/vite-plugin"
|
|
18
|
+
* export default { plugins: [pyreon({ ssr: { entry: "./src/entry-server.ts" } })] }
|
|
19
|
+
*
|
|
20
|
+
* In SSR mode, the plugin adds dev server middleware that:
|
|
21
|
+
* 1. Loads your server entry via Vite's `ssrLoadModule`
|
|
22
|
+
* 2. Calls the exported `handler` or default export (Request → Response)
|
|
23
|
+
* 3. Returns the SSR'd HTML for every non-asset request
|
|
24
|
+
*
|
|
25
|
+
* For production, build separately:
|
|
26
|
+
* vite build # client bundle
|
|
27
|
+
* vite build --ssr src/entry-server.ts --outDir dist/server # server bundle
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
function pyreonPlugin(options) {
|
|
31
|
+
const ssrConfig = options?.ssr;
|
|
32
|
+
let isBuild = false;
|
|
33
|
+
return {
|
|
34
|
+
name: "pyreon",
|
|
35
|
+
enforce: "pre",
|
|
36
|
+
config(_, env) {
|
|
37
|
+
isBuild = env.command === "build";
|
|
38
|
+
return {
|
|
39
|
+
resolve: {
|
|
40
|
+
conditions: ["bun"]
|
|
41
|
+
},
|
|
42
|
+
esbuild: {
|
|
43
|
+
jsx: "automatic",
|
|
44
|
+
jsxImportSource: "@pyreon/core"
|
|
45
|
+
},
|
|
46
|
+
...(env.isSsrBuild && ssrConfig ? {
|
|
47
|
+
build: {
|
|
48
|
+
ssr: true,
|
|
49
|
+
rollupOptions: {
|
|
50
|
+
input: ssrConfig.entry
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} : {})
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
resolveId(id) {
|
|
57
|
+
if (id === HMR_RUNTIME_IMPORT) return HMR_RUNTIME_ID;
|
|
58
|
+
},
|
|
59
|
+
load(id) {
|
|
60
|
+
if (id === HMR_RUNTIME_ID) return HMR_RUNTIME_SOURCE;
|
|
61
|
+
},
|
|
62
|
+
transform(code, id) {
|
|
63
|
+
const ext = getExt(id);
|
|
64
|
+
if (ext !== ".tsx" && ext !== ".jsx" && ext !== ".pyreon") return;
|
|
65
|
+
const result = transformJSX(code, id);
|
|
66
|
+
for (const w of result.warnings) this.warn(`${w.message} (${id}:${w.line}:${w.column})`);
|
|
67
|
+
let output = result.code;
|
|
68
|
+
if (!isBuild) output = injectHmr(output, id);
|
|
69
|
+
return {
|
|
70
|
+
code: output,
|
|
71
|
+
map: null
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
configureServer(server) {
|
|
75
|
+
if (!ssrConfig) return;
|
|
76
|
+
return () => {
|
|
77
|
+
server.middlewares.use(async (req, res, next) => {
|
|
78
|
+
if (req.method !== "GET") return next();
|
|
79
|
+
const url = req.url ?? "/";
|
|
80
|
+
if (isAssetRequest(url)) return next();
|
|
81
|
+
try {
|
|
82
|
+
await handleSsrRequest(server, ssrConfig.entry, url, req, res, next);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
server.ssrFixStacktrace(err);
|
|
85
|
+
next(err);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function handleSsrRequest(server, entry, url, req, res, next) {
|
|
93
|
+
const mod = await server.ssrLoadModule(entry);
|
|
94
|
+
const handler = mod.handler ?? mod.default;
|
|
95
|
+
if (typeof handler !== "function") {
|
|
96
|
+
next();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const origin = `http://${req.headers.host ?? "localhost"}`;
|
|
100
|
+
const fullUrl = new URL(url, origin);
|
|
101
|
+
const response = await handler(new Request(fullUrl.href, {
|
|
102
|
+
method: req.method ?? "GET",
|
|
103
|
+
headers: Object.entries(req.headers).reduce((h, [k, v]) => {
|
|
104
|
+
if (v) h.set(k, Array.isArray(v) ? v.join(", ") : v);
|
|
105
|
+
return h;
|
|
106
|
+
}, new Headers())
|
|
107
|
+
}));
|
|
108
|
+
let html = await response.text();
|
|
109
|
+
html = await server.transformIndexHtml(url, html);
|
|
110
|
+
res.statusCode = response.status;
|
|
111
|
+
response.headers.forEach((v, k) => {
|
|
112
|
+
res.setHeader(k, v);
|
|
113
|
+
});
|
|
114
|
+
res.end(html);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Regex that detects signal declarations (prefix + variable name).
|
|
118
|
+
* The arguments are extracted via balanced-paren matching in `injectHmr`.
|
|
119
|
+
* A brace-depth check filters out matches inside functions/blocks — only
|
|
120
|
+
* module-scope (depth 0) signals are rewritten for HMR state preservation.
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
function skipStringLiteral(code, start, quote) {
|
|
124
|
+
let j = start + 1;
|
|
125
|
+
while (j < code.length) {
|
|
126
|
+
if (code[j] === "\\") {
|
|
127
|
+
j += 2;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (code[j] === quote) break;
|
|
131
|
+
j++;
|
|
132
|
+
}
|
|
133
|
+
return j;
|
|
134
|
+
}
|
|
135
|
+
function extractBalancedArgs(code, start) {
|
|
136
|
+
let depth = 1;
|
|
137
|
+
for (let i = start; i < code.length; i++) {
|
|
138
|
+
const ch = code[i];
|
|
139
|
+
if (ch === "(") depth++;else if (ch === ")") {
|
|
140
|
+
depth--;
|
|
141
|
+
if (depth === 0) return code.slice(start, i);
|
|
142
|
+
} else if (ch === "\"" || ch === "'" || ch === "`") i = skipStringLiteral(code, i, ch);
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Compute brace depth at position `pos` — returns 0 for module scope.
|
|
148
|
+
* Skips string literals to avoid counting braces inside strings.
|
|
149
|
+
*/
|
|
150
|
+
function braceDepthAt(code, pos) {
|
|
151
|
+
let depth = 0;
|
|
152
|
+
for (let i = 0; i < pos; i++) {
|
|
153
|
+
const ch = code[i];
|
|
154
|
+
if (ch === "{") depth++;else if (ch === "}") depth--;else if (ch === "\"" || ch === "'" || ch === "`") i = skipStringLiteral(code, i, ch);
|
|
155
|
+
}
|
|
156
|
+
return depth;
|
|
157
|
+
}
|
|
158
|
+
function injectHmr(code, moduleId) {
|
|
159
|
+
const hasSignals = SIGNAL_PREFIX_RE.test(code);
|
|
160
|
+
SIGNAL_PREFIX_RE.lastIndex = 0;
|
|
161
|
+
if (!EXPORT_COMPONENT_RE.test(code) && !hasSignals) return code;
|
|
162
|
+
let output = code;
|
|
163
|
+
if (hasSignals) {
|
|
164
|
+
const escapedId = JSON.stringify(moduleId);
|
|
165
|
+
const matches = [];
|
|
166
|
+
let m = SIGNAL_PREFIX_RE.exec(code);
|
|
167
|
+
while (m !== null) {
|
|
168
|
+
const argsStart = m.index + m[0].length;
|
|
169
|
+
const args = extractBalancedArgs(code, argsStart);
|
|
170
|
+
if (args === null) {
|
|
171
|
+
m = SIGNAL_PREFIX_RE.exec(code);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (braceDepthAt(code, m.index) === 0) matches.push({
|
|
175
|
+
start: m.index,
|
|
176
|
+
end: argsStart + args.length + 1,
|
|
177
|
+
prefix: m[1] ?? "",
|
|
178
|
+
name: m[2] ?? "",
|
|
179
|
+
args
|
|
180
|
+
});
|
|
181
|
+
m = SIGNAL_PREFIX_RE.exec(code);
|
|
182
|
+
}
|
|
183
|
+
SIGNAL_PREFIX_RE.lastIndex = 0;
|
|
184
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
185
|
+
const {
|
|
186
|
+
start,
|
|
187
|
+
end,
|
|
188
|
+
prefix,
|
|
189
|
+
name,
|
|
190
|
+
args
|
|
191
|
+
} = matches[i];
|
|
192
|
+
const replacement = `${prefix}__hmr_signal(${escapedId}, ${JSON.stringify(name)}, signal, ${args})`;
|
|
193
|
+
output = output.slice(0, start) + replacement + output.slice(end);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const escapedId = JSON.stringify(moduleId);
|
|
197
|
+
const lines = [];
|
|
198
|
+
if (hasSignals) lines.push(`import { __hmr_signal, __hmr_dispose } from "${HMR_RUNTIME_IMPORT}";`);
|
|
199
|
+
lines.push(`if (import.meta.hot) {`);
|
|
200
|
+
if (hasSignals) lines.push(` import.meta.hot.dispose(() => __hmr_dispose(${escapedId}));`);
|
|
201
|
+
lines.push(` import.meta.hot.accept();`);
|
|
202
|
+
lines.push(`}`);
|
|
203
|
+
output = `${output}\n\n${lines.join("\n")}\n`;
|
|
204
|
+
return output;
|
|
205
|
+
}
|
|
206
|
+
function getExt(id) {
|
|
207
|
+
const clean = id.split("?")[0] ?? id;
|
|
208
|
+
const dot = clean.lastIndexOf(".");
|
|
209
|
+
return dot >= 0 ? clean.slice(dot) : "";
|
|
210
|
+
}
|
|
211
|
+
/** Skip Vite-handled asset requests (CSS, images, HMR, etc.) */
|
|
212
|
+
function isAssetRequest(url) {
|
|
213
|
+
return url.startsWith("/@") || url.startsWith("/__") || url.includes("/node_modules/") || /\.(css|js|ts|tsx|jsx|json|ico|png|jpg|jpeg|gif|svg|woff2?|ttf|eot|map)(\?|$)/.test(url);
|
|
214
|
+
}
|
|
215
|
+
//#endregion
|
|
216
|
+
export { pyreonPlugin as default };
|
|
217
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/index.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
interface PyreonPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Enable SSR dev middleware.
|
|
7
|
+
*
|
|
8
|
+
* Pass an object with `entry` pointing to your server entry file.
|
|
9
|
+
* The entry must export a `handler` function: `(req: Request) => Promise<Response>`
|
|
10
|
+
* or a default export of the same type.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* pyreonPlugin({ ssr: { entry: "./src/entry-server.ts" } })
|
|
14
|
+
*/
|
|
15
|
+
ssr?: {
|
|
16
|
+
/** Server entry file path (e.g. "./src/entry-server.ts") */entry: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
declare function pyreonPlugin(options?: PyreonPluginOptions): Plugin;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { PyreonPluginOptions, pyreonPlugin as default };
|
|
22
|
+
//# sourceMappingURL=index2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/index.ts"],"mappings":";;;UAiCiB,mBAAA;;;;;;;;;;;EAWf,GAAA;gEAEE,KAAA;EAAA;AAAA;AAAA,iBAIoB,YAAA,CAAa,OAAA,GAAU,mBAAA,GAAsB,MAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pyreon/vite-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vite plugin for Pyreon — .pyreon SFC support, HMR, compiler integration",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/pyreon/pyreon.git",
|
|
9
|
+
"directory": "packages/vite-plugin"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/vite-plugin#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/pyreon/pyreon/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib",
|
|
17
|
+
"src",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./lib/index.js",
|
|
24
|
+
"module": "./lib/index.js",
|
|
25
|
+
"types": "./lib/types/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"bun": "./src/index.ts",
|
|
29
|
+
"import": "./lib/index.js",
|
|
30
|
+
"types": "./lib/types/index.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "vl_rolldown_build",
|
|
35
|
+
"dev": "vl_rolldown_build-watch",
|
|
36
|
+
"test": "echo 'no tests yet'",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"prepublishOnly": "bun run build"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@pyreon/compiler": "workspace:*"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"vite": ">=5.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"vite": "^7.3.1"
|
|
48
|
+
}
|
|
49
|
+
}
|