@mionjs/devtools 0.8.0-alpha.0 → 0.8.4-alpha.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/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.cjs +52 -25
- package/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.cjs.map +1 -1
- package/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.d.ts +10 -2
- package/build/vite-plugin/cjs/src/vite-plugin/aotDiskCache.cjs +2 -2
- package/build/vite-plugin/cjs/src/vite-plugin/aotDiskCache.cjs.map +1 -1
- package/build/vite-plugin/cjs/src/vite-plugin/constants.cjs +4 -0
- package/build/vite-plugin/cjs/src/vite-plugin/constants.cjs.map +1 -1
- package/build/vite-plugin/cjs/src/vite-plugin/constants.d.ts +2 -0
- package/build/vite-plugin/cjs/src/vite-plugin/mionVitePlugin.cjs +127 -30
- package/build/vite-plugin/cjs/src/vite-plugin/mionVitePlugin.cjs.map +1 -1
- package/build/vite-plugin/cjs/src/vite-plugin/mionVitePlugin.d.ts +2 -2
- package/build/vite-plugin/cjs/src/vite-plugin/transformers.cjs +1 -0
- package/build/vite-plugin/cjs/src/vite-plugin/transformers.cjs.map +1 -1
- package/build/vite-plugin/cjs/src/vite-plugin/types.d.ts +5 -4
- package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.d.ts +10 -2
- package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.js +52 -25
- package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.js.map +1 -1
- package/build/vite-plugin/esm/src/vite-plugin/aotDiskCache.js +2 -2
- package/build/vite-plugin/esm/src/vite-plugin/aotDiskCache.js.map +1 -1
- package/build/vite-plugin/esm/src/vite-plugin/constants.d.ts +2 -0
- package/build/vite-plugin/esm/src/vite-plugin/constants.js +4 -0
- package/build/vite-plugin/esm/src/vite-plugin/constants.js.map +1 -1
- package/build/vite-plugin/esm/src/vite-plugin/mionVitePlugin.d.ts +2 -2
- package/build/vite-plugin/esm/src/vite-plugin/mionVitePlugin.js +128 -32
- package/build/vite-plugin/esm/src/vite-plugin/mionVitePlugin.js.map +1 -1
- package/build/vite-plugin/esm/src/vite-plugin/transformers.js +1 -0
- package/build/vite-plugin/esm/src/vite-plugin/transformers.js.map +1 -1
- package/build/vite-plugin/esm/src/vite-plugin/types.d.ts +5 -4
- package/package.json +2 -2
|
@@ -8,10 +8,15 @@ export interface AOTCacheData {
|
|
|
8
8
|
export interface AOTCacheResult {
|
|
9
9
|
data: AOTCacheData;
|
|
10
10
|
childProcess?: ChildProcess;
|
|
11
|
+
platformReady?: Promise<PlatformReadyData>;
|
|
12
|
+
}
|
|
13
|
+
export interface PlatformReadyData {
|
|
14
|
+
routerConfig: Record<string, unknown>;
|
|
15
|
+
platformConfig: Record<string, unknown>;
|
|
11
16
|
}
|
|
12
17
|
export declare function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string): Promise<AOTCacheResult>;
|
|
13
18
|
export type ModuleLoader = (url: string) => Promise<Record<string, any>>;
|
|
14
|
-
export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader,
|
|
19
|
+
export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string): Promise<AOTCacheData>;
|
|
15
20
|
export declare function killPersistentChild(child: ChildProcess | null): Promise<void>;
|
|
16
21
|
export declare function logAOTCaches(data: AOTCacheData): void;
|
|
17
22
|
export declare function generateJitFnsModule(jitFnsCode: string): string;
|
|
@@ -19,5 +24,8 @@ export declare function generatePureFnsModule(pureFnsCode: string): string;
|
|
|
19
24
|
export declare function generateRouterCacheModule(routerCacheCode: string): string;
|
|
20
25
|
export declare function generateCombinedCachesModule(): string;
|
|
21
26
|
export declare function generateNoopModule(comment: string): string;
|
|
22
|
-
export declare function
|
|
27
|
+
export declare function waitForPlatformReady(child: ChildProcess, timeoutMs?: number): Promise<{
|
|
28
|
+
routerConfig: Record<string, unknown>;
|
|
29
|
+
platformConfig: Record<string, unknown>;
|
|
30
|
+
}>;
|
|
23
31
|
export declare function generateNoopCombinedModule(): string;
|
|
@@ -3,10 +3,10 @@ import { resolve, dirname } from "path";
|
|
|
3
3
|
import { resolveModule } from "./resolveModule.js";
|
|
4
4
|
const DEFAULT_TIMEOUT = 3e4;
|
|
5
5
|
async function generateAOTCaches(serverConfig, startScriptOverride) {
|
|
6
|
-
const persist = serverConfig.
|
|
7
|
-
const startScript = resolve(startScriptOverride ?? serverConfig.
|
|
6
|
+
const persist = serverConfig.runMode === "childProcess";
|
|
7
|
+
const startScript = resolve(startScriptOverride ?? serverConfig.startScript);
|
|
8
8
|
const scriptDir = dirname(startScript);
|
|
9
|
-
const viteConfigArgs = serverConfig.
|
|
9
|
+
const viteConfigArgs = serverConfig.viteConfig ? ["--config", resolve(serverConfig.viteConfig)] : [];
|
|
10
10
|
let viteNodePath;
|
|
11
11
|
try {
|
|
12
12
|
viteNodePath = await resolveModule("vite-node/cli", scriptDir);
|
|
@@ -22,8 +22,8 @@ Original error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
22
22
|
let resolved = false;
|
|
23
23
|
let stderr = "";
|
|
24
24
|
try {
|
|
25
|
-
child = fork(viteNodePath, [...viteConfigArgs, startScript], {
|
|
26
|
-
env: { ...process.env, MION_COMPILE:
|
|
25
|
+
child = fork(viteNodePath, [...viteConfigArgs, startScript, ...serverConfig.args || []], {
|
|
26
|
+
env: { ...process.env, ...serverConfig.env, MION_COMPILE: serverConfig.runMode },
|
|
27
27
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
28
28
|
cwd: scriptDir
|
|
29
29
|
});
|
|
@@ -39,9 +39,13 @@ Original error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
39
39
|
}
|
|
40
40
|
const cleanup = () => {
|
|
41
41
|
clearTimeout(timeoutId);
|
|
42
|
-
if (child.connected) child.disconnect();
|
|
42
|
+
if (!persist && child.connected) child.disconnect();
|
|
43
43
|
if (!persist) child.kill();
|
|
44
44
|
};
|
|
45
|
+
let platformReadyResolve;
|
|
46
|
+
const platformReady = persist ? new Promise((res) => {
|
|
47
|
+
platformReadyResolve = res;
|
|
48
|
+
}) : void 0;
|
|
45
49
|
child.on("message", (msg) => {
|
|
46
50
|
const message = msg;
|
|
47
51
|
if (message?.type === "mion-aot-caches") {
|
|
@@ -53,8 +57,12 @@ Original error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
53
57
|
pureFnsCode: message.pureFnsCode,
|
|
54
58
|
routerCacheCode: message.routerCacheCode
|
|
55
59
|
},
|
|
56
|
-
childProcess: persist ? child : void 0
|
|
60
|
+
childProcess: persist ? child : void 0,
|
|
61
|
+
platformReady
|
|
57
62
|
});
|
|
63
|
+
} else if (message?.type === "mion-platform-ready" && platformReadyResolve) {
|
|
64
|
+
platformReadyResolve({ routerConfig: message.routerConfig, platformConfig: message.platformConfig });
|
|
65
|
+
platformReadyResolve = void 0;
|
|
58
66
|
}
|
|
59
67
|
});
|
|
60
68
|
child.stderr?.on("data", (data) => {
|
|
@@ -82,7 +90,7 @@ Original error: ${err instanceof Error ? err.message : String(err)}`
|
|
|
82
90
|
reject(
|
|
83
91
|
new Error(
|
|
84
92
|
`vite-node exited with code ${code} before emitting AOT caches.
|
|
85
|
-
Make sure the
|
|
93
|
+
Make sure the startScript calls initMionRouter() and the router is fully initialized.
|
|
86
94
|
` + (stderr ? `stderr: ${stderr}` : "")
|
|
87
95
|
)
|
|
88
96
|
);
|
|
@@ -101,11 +109,11 @@ Make sure the startServerScript calls initMionRouter() and the router is fully i
|
|
|
101
109
|
}, DEFAULT_TIMEOUT);
|
|
102
110
|
});
|
|
103
111
|
}
|
|
104
|
-
async function loadSSRRouterAndGenerateAOTCaches(loadModule,
|
|
112
|
+
async function loadSSRRouterAndGenerateAOTCaches(loadModule, startScript) {
|
|
105
113
|
const prevCompile = process.env.MION_COMPILE;
|
|
106
|
-
process.env.MION_COMPILE = "
|
|
114
|
+
process.env.MION_COMPILE = "middleware";
|
|
107
115
|
try {
|
|
108
|
-
const mod = await loadModule(
|
|
116
|
+
const mod = await loadModule(startScript);
|
|
109
117
|
const promises = Object.values(mod).filter((v) => v instanceof Promise);
|
|
110
118
|
if (promises.length > 0) await Promise.all(promises);
|
|
111
119
|
const aotModule = await loadModule("@mionjs/router/aot");
|
|
@@ -184,39 +192,58 @@ export const routerCache = ${routerCacheCode};
|
|
|
184
192
|
}
|
|
185
193
|
function generateCombinedCachesModule() {
|
|
186
194
|
return `/* Auto-generated combined AOT caches - do not edit */
|
|
187
|
-
import { addAOTCaches, addRoutesToCache } from '@mionjs/core';
|
|
188
195
|
import { pureFnsCache } from 'virtual:mion-aot/pure-fns';
|
|
189
196
|
import { jitFnsCache } from 'virtual:mion-aot/jit-fns';
|
|
190
197
|
import { routerCache } from 'virtual:mion-aot/router-cache';
|
|
198
|
+
import { addAOTCaches, addRoutesToCache } from '@mionjs/core';
|
|
191
199
|
|
|
200
|
+
// Auto-register AOT caches as a side effect so they survive tree-shaking
|
|
192
201
|
addAOTCaches(jitFnsCache, pureFnsCache);
|
|
193
202
|
addRoutesToCache(routerCache);
|
|
194
203
|
|
|
195
204
|
export { jitFnsCache, pureFnsCache, routerCache };
|
|
205
|
+
|
|
206
|
+
/** Loads pre-compiled AOT caches (no-op: caches are auto-registered on import). */
|
|
207
|
+
export function loadAOTCaches() {}
|
|
208
|
+
|
|
209
|
+
/** Returns the raw AOT caches. */
|
|
210
|
+
export function getRawAOTCaches() {
|
|
211
|
+
return { jitFnsCache, pureFnsCache, routerCache };
|
|
212
|
+
}
|
|
196
213
|
`;
|
|
197
214
|
}
|
|
198
215
|
function generateNoopModule(comment) {
|
|
199
216
|
return `/* ${comment} */
|
|
200
217
|
`;
|
|
201
218
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
219
|
+
function waitForPlatformReady(child, timeoutMs = 3e4) {
|
|
220
|
+
return new Promise((resolve2, reject) => {
|
|
221
|
+
const onMessage = (msg) => {
|
|
222
|
+
const message = msg;
|
|
223
|
+
if (message?.type === "mion-platform-ready") {
|
|
224
|
+
clearTimeout(timeoutId);
|
|
225
|
+
child.removeListener("message", onMessage);
|
|
226
|
+
resolve2({ routerConfig: message.routerConfig, platformConfig: message.platformConfig });
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
child.on("message", onMessage);
|
|
230
|
+
const timeoutId = setTimeout(() => {
|
|
231
|
+
child.removeListener("message", onMessage);
|
|
232
|
+
reject(
|
|
233
|
+
new Error(
|
|
234
|
+
`Server did not call setPlatformConfig() within ${timeoutMs / 1e3}s. Ensure your platform adapter (startNodeServer, startBunServer, etc.) is called after initMionRouter().`
|
|
235
|
+
)
|
|
236
|
+
);
|
|
237
|
+
}, timeoutMs);
|
|
238
|
+
});
|
|
214
239
|
}
|
|
215
240
|
function generateNoopCombinedModule() {
|
|
216
241
|
return `/* No-op: AOT caches not generated */
|
|
217
242
|
export const jitFnsCache = {};
|
|
218
243
|
export const pureFnsCache = {};
|
|
219
244
|
export const routerCache = {};
|
|
245
|
+
export function loadAOTCaches() {}
|
|
246
|
+
export function getRawAOTCaches() { return { jitFnsCache, pureFnsCache, routerCache }; }
|
|
220
247
|
`;
|
|
221
248
|
}
|
|
222
249
|
export {
|
|
@@ -230,6 +257,6 @@ export {
|
|
|
230
257
|
killPersistentChild,
|
|
231
258
|
loadSSRRouterAndGenerateAOTCaches,
|
|
232
259
|
logAOTCaches,
|
|
233
|
-
|
|
260
|
+
waitForPlatformReady
|
|
234
261
|
};
|
|
235
262
|
//# sourceMappingURL=aotCacheGenerator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aotCacheGenerator.js","sources":["../../../../../src/vite-plugin/aotCacheGenerator.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {fork, ChildProcess} from 'child_process';\nimport {resolve, dirname} from 'path';\nimport {MionServerConfig} from './types.ts';\nimport {resolveModule} from './resolveModule.ts';\n\n/** AOT cache data returned from the generator */\nexport interface AOTCacheData {\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** AOT cache result including optional persistent child process */\nexport interface AOTCacheResult {\n data: AOTCacheData;\n /** The child process, only present when server mode is 'IPC' (persist) */\n childProcess?: ChildProcess;\n}\n\n/** IPC message type from the router's aotEmitter */\ninterface AOTCacheMessage {\n type: 'mion-aot-caches';\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** Default timeout for AOT cache generation (30 seconds) */\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * Generates AOT caches by spawning vite-node to run the server's start script.\n *\n * vite-node is used instead of plain node/ts-node because:\n * 1. The server needs deepkit type compiler transformations\n * 2. The server's vite.config.ts has aliases and plugins that must be applied\n * 3. vite-node provides the same environment as the actual server build\n *\n * The router's emitAOTCaches() (called automatically from initMionRouter)\n * detects MION_COMPILE and sends the serialized caches via IPC.\n */\nexport async function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string): Promise<AOTCacheResult> {\n const persist = serverConfig.mode === 'IPC';\n const startScript = resolve(startScriptOverride ?? serverConfig.startServerScript);\n const scriptDir = dirname(startScript);\n\n // Determine the vite config to use\n // If serverViteConfig is provided, use it; otherwise let vite-node auto-discover\n const viteConfigArgs = serverConfig.serverViteConfig ? ['--config', resolve(serverConfig.serverViteConfig)] : [];\n\n // Resolve vite-node path in both CJS and ESM environments\n let viteNodePath: string;\n try {\n viteNodePath = await resolveModule('vite-node/cli', scriptDir);\n } catch (err) {\n throw new Error(\n `Failed to resolve vite-node. Make sure vite-node is installed.\\n` +\n `You can install it with: npm install -D vite-node\\n` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n return new Promise((resolvePromise, reject) => {\n let child: ChildProcess;\n let resolved = false;\n let stderr = '';\n\n try {\n // Spawn vite-node as a child process with IPC channel\n // 'serve' mode tells platform adapters to proceed with server.listen()\n child = fork(viteNodePath, [...viteConfigArgs, startScript], {\n env: {...process.env, MION_COMPILE: persist ? 'serve' : 'onlyAOT'},\n stdio: ['pipe', 'pipe', 'pipe', 'ipc'],\n cwd: scriptDir,\n });\n } catch (err) {\n // If vite-node is not found, provide a helpful error message\n reject(\n new Error(\n `Failed to spawn vite-node. Make sure vite-node is installed.\\n` +\n `You can install it with: npm install -D vite-node\\n` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`\n )\n );\n return;\n }\n\n /** Cleanup child process: disconnect IPC, clear timeout, and optionally kill */\n const cleanup = () => {\n clearTimeout(timeoutId);\n if (child.connected) child.disconnect();\n if (!persist) child.kill();\n };\n\n child.on('message', (msg: unknown) => {\n const message = msg as AOTCacheMessage;\n if (message?.type === 'mion-aot-caches') {\n resolved = true;\n cleanup();\n resolvePromise({\n data: {\n jitFnsCode: message.jitFnsCode,\n pureFnsCode: message.pureFnsCode,\n routerCacheCode: message.routerCacheCode,\n },\n childProcess: persist ? child : undefined,\n });\n }\n });\n\n // Capture stderr for error reporting (and pipe through in persist mode)\n child.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (!resolved) stderr += msg + '\\n';\n if (persist && msg) console.error(`[mion-server] ${msg}`);\n });\n\n // Pipe stdout through (always in persist mode, only with DEBUG_AOT otherwise)\n child.stdout?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (persist && msg) {\n console.log(`[mion-server] ${msg}`);\n } else if (process.env.DEBUG_AOT && msg) {\n console.log('[mion-aot] stdout:', msg);\n }\n });\n\n child.on('error', (err) => {\n if (!resolved) {\n cleanup();\n reject(new Error(`vite-node failed to start: ${err.message}`));\n }\n });\n\n child.on('exit', (code) => {\n if (!resolved) {\n cleanup();\n reject(\n new Error(\n `vite-node exited with code ${code} before emitting AOT caches.\\n` +\n `Make sure the startServerScript calls initMionRouter() and the router ` +\n `is fully initialized.\\n` +\n (stderr ? `stderr: ${stderr}` : '')\n )\n );\n }\n });\n\n // Timeout safety\n const timeoutId = setTimeout(() => {\n if (!resolved) {\n cleanup();\n if (persist) child.kill();\n reject(\n new Error(\n `AOT cache generation timed out (${DEFAULT_TIMEOUT / 1000}s). ` +\n `Make sure the server start script completes initialization.`\n )\n );\n }\n }, DEFAULT_TIMEOUT);\n });\n}\n\n/** Loads a module by URL — abstracts over ssrLoadModule and Environment Runner */\nexport type ModuleLoader = (url: string) => Promise<Record<string, any>>;\n\n/**\n * Loads the startServerScript with MION_COMPILE=SSR so platform adapters skip server.listen().\n * Generates AOT caches via SSR using a module loader (for same-Vite-process scenarios like Nuxt).\n * After loading, retrieves the caches directly from the router's global state via getSerializedCaches(). */\nexport async function loadSSRRouterAndGenerateAOTCaches(\n loadModule: ModuleLoader,\n startServerScript: string\n): Promise<AOTCacheData> {\n const prevCompile = process.env.MION_COMPILE;\n process.env.MION_COMPILE = 'viteSSR';\n\n try {\n // Load the start server script — triggers initMionRouter(), populates caches,\n // skips process.send (SSR mode) and skips server.listen() (platform adapters)\n const mod = await loadModule(startServerScript);\n // Await any Promise-valued exports (e.g. initMionRouter() without top-level await)\n const promises = Object.values(mod).filter((v): v is Promise<any> => v instanceof Promise);\n if (promises.length > 0) await Promise.all(promises);\n\n // Get caches directly from the router's global state\n const aotModule = await loadModule('@mionjs/router/aot');\n const caches: AOTCacheData = await aotModule.getSerializedCaches();\n return caches;\n } finally {\n if (prevCompile === undefined) delete process.env.MION_COMPILE;\n else process.env.MION_COMPILE = prevCompile;\n }\n}\n\n// ============ Persistent child management ============\n\n/** Kills a persistent child process gracefully (SIGTERM then SIGKILL after 5s) */\nexport async function killPersistentChild(child: ChildProcess | null): Promise<void> {\n if (!child || child.killed) return;\n const pid = child.pid;\n\n if (pid) {\n try {\n process.kill(-pid, 'SIGTERM');\n } catch {\n child.kill('SIGTERM');\n }\n } else {\n child.kill('SIGTERM');\n }\n\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n if (child && !child.killed) {\n if (pid) {\n try {\n process.kill(-pid, 'SIGKILL');\n } catch {\n child.kill('SIGKILL');\n }\n } else {\n child.kill('SIGKILL');\n }\n }\n resolve();\n }, 5000);\n\n child!.on('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n}\n\n// ============ Logging ============\n\n/** Formats byte size to human-readable string */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n const kb = bytes / 1024;\n if (kb < 1024) return `${kb.toFixed(1)} KB`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)} MB`;\n}\n\n/** Logs AOT cache sizes and optionally full contents in verbose mode (DEBUG_AOT) */\nexport function logAOTCaches(data: AOTCacheData): void {\n const jitSize = formatBytes(Buffer.byteLength(data.jitFnsCode, 'utf-8'));\n const pureSize = formatBytes(Buffer.byteLength(data.pureFnsCode, 'utf-8'));\n const routerSize = formatBytes(Buffer.byteLength(data.routerCacheCode, 'utf-8'));\n console.log(`[mion] jitFns: ${jitSize}, pureFns: ${pureSize}, routerCache: ${routerSize}`);\n\n if (process.env.DEBUG_AOT) {\n console.log('[mion] AOT jitFns cache:\\n', data.jitFnsCode);\n console.log('[mion] AOT pureFns cache:\\n', data.pureFnsCode);\n console.log('[mion] AOT routerCache:\\n', data.routerCacheCode);\n }\n}\n\n// ============ Module Generators ============\n\n/** Generates the virtual module code for JIT functions cache (exports only). */\nexport function generateJitFnsModule(jitFnsCode: string): string {\n return `/* Auto-generated AOT JIT functions cache - do not edit */\nexport const jitFnsCache = ${jitFnsCode};\n`;\n}\n\n/** Generates the virtual module code for pure functions cache (exports only). */\nexport function generatePureFnsModule(pureFnsCode: string): string {\n return `/* Auto-generated AOT pure functions cache - do not edit */\nexport const pureFnsCache = ${pureFnsCode};\n`;\n}\n\n/** Generates the virtual module code for router methods cache (exports only). */\nexport function generateRouterCacheModule(routerCacheCode: string): string {\n return `/* Auto-generated AOT router cache - do not edit */\nexport const routerCache = ${routerCacheCode};\n`;\n}\n\n/** Generates the combined virtual module that imports all 3 caches, registers them, and re-exports. */\nexport function generateCombinedCachesModule(): string {\n return `/* Auto-generated combined AOT caches - do not edit */\nimport { addAOTCaches, addRoutesToCache } from '@mionjs/core';\nimport { pureFnsCache } from 'virtual:mion-aot/pure-fns';\nimport { jitFnsCache } from 'virtual:mion-aot/jit-fns';\nimport { routerCache } from 'virtual:mion-aot/router-cache';\n\naddAOTCaches(jitFnsCache, pureFnsCache);\naddRoutesToCache(routerCache);\n\nexport { jitFnsCache, pureFnsCache, routerCache };\n`;\n}\n\n/** Generates a no-op module for when AOT caches are disabled. */\nexport function generateNoopModule(comment: string): string {\n return `/* ${comment} */\\n`;\n}\n\n/** Poll an HTTP port until the server responds (2xx or 404). */\nexport async function waitForServer(port: number, timeoutMs = 30000): Promise<void> {\n const startTime = Date.now();\n const checkInterval = 100;\n while (Date.now() - startTime < timeoutMs) {\n try {\n const response = await fetch(`http://localhost:${port}/`);\n if (response.ok || response.status === 404) return;\n } catch {\n // Server not ready yet\n }\n await new Promise((r) => setTimeout(r, checkInterval));\n }\n throw new Error(`[mion] Server failed to become ready on port ${port} within ${timeoutMs}ms`);\n}\n\n/** Generates a no-op combined module that exports empty caches. */\nexport function generateNoopCombinedModule(): string {\n return `/* No-op: AOT caches not generated */\nexport const jitFnsCache = {};\nexport const pureFnsCache = {};\nexport const routerCache = {};\n`;\n}\n"],"names":["resolve"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"aotCacheGenerator.js","sources":["../../../../../src/vite-plugin/aotCacheGenerator.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {fork, ChildProcess} from 'child_process';\nimport {resolve, dirname} from 'path';\nimport {MionServerConfig} from './types.ts';\nimport {resolveModule} from './resolveModule.ts';\n\n/** AOT cache data returned from the generator */\nexport interface AOTCacheData {\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** AOT cache result including optional persistent child process */\nexport interface AOTCacheResult {\n data: AOTCacheData;\n /** The child process, only present when runMode is 'childProcess' (persist) */\n childProcess?: ChildProcess;\n /** Promise that resolves when the server calls setPlatformConfig() (childProcess mode only) */\n platformReady?: Promise<PlatformReadyData>;\n}\n\n/** IPC message type from the router's aotEmitter */\ninterface AOTCacheMessage {\n type: 'mion-aot-caches';\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** Platform config received from the server via IPC */\nexport interface PlatformReadyData {\n routerConfig: Record<string, unknown>;\n platformConfig: Record<string, unknown>;\n}\n\ninterface PlatformReadyMessage extends PlatformReadyData {\n type: 'mion-platform-ready';\n}\n\n/** Default timeout for AOT cache generation (30 seconds) */\nconst DEFAULT_TIMEOUT = 30000;\n\n/**\n * Generates AOT caches by spawning vite-node to run the server's start script.\n *\n * vite-node is used instead of plain node/ts-node because:\n * 1. The server needs deepkit type compiler transformations\n * 2. The server's vite.config.ts has aliases and plugins that must be applied\n * 3. vite-node provides the same environment as the actual server build\n *\n * The router's emitAOTCaches() (called automatically from initMionRouter)\n * detects MION_COMPILE and sends the serialized caches via IPC.\n */\nexport async function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string): Promise<AOTCacheResult> {\n const persist = serverConfig.runMode === 'childProcess';\n const startScript = resolve(startScriptOverride ?? serverConfig.startScript);\n const scriptDir = dirname(startScript);\n\n // Determine the vite config to use\n // If viteConfig is provided, use it; otherwise let vite-node auto-discover\n const viteConfigArgs = serverConfig.viteConfig ? ['--config', resolve(serverConfig.viteConfig)] : [];\n\n // Resolve vite-node path in both CJS and ESM environments\n let viteNodePath: string;\n try {\n viteNodePath = await resolveModule('vite-node/cli', scriptDir);\n } catch (err) {\n throw new Error(\n `Failed to resolve vite-node. Make sure vite-node is installed.\\n` +\n `You can install it with: npm install -D vite-node\\n` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n return new Promise((resolvePromise, reject) => {\n let child: ChildProcess;\n let resolved = false;\n let stderr = '';\n\n try {\n // Spawn vite-node as a child process with IPC channel\n // 'serve' mode tells platform adapters to proceed with server.listen()\n child = fork(viteNodePath, [...viteConfigArgs, startScript, ...(serverConfig.args || [])], {\n env: {...process.env, ...serverConfig.env, MION_COMPILE: serverConfig.runMode},\n stdio: ['pipe', 'pipe', 'pipe', 'ipc'],\n cwd: scriptDir,\n });\n } catch (err) {\n // If vite-node is not found, provide a helpful error message\n reject(\n new Error(\n `Failed to spawn vite-node. Make sure vite-node is installed.\\n` +\n `You can install it with: npm install -D vite-node\\n` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`\n )\n );\n return;\n }\n\n /** Cleanup child process: clear timeout, disconnect IPC (only in non-persist mode), and optionally kill.\n * In persist mode, IPC stays open for the mion-platform-ready message. */\n const cleanup = () => {\n clearTimeout(timeoutId);\n if (!persist && child.connected) child.disconnect();\n if (!persist) child.kill();\n };\n\n // Set up platform-ready listener BEFORE any messages arrive to avoid race conditions.\n // The child may send mion-platform-ready very quickly after mion-aot-caches.\n let platformReadyResolve: ((value: PlatformReadyData) => void) | undefined;\n const platformReady = persist\n ? new Promise<PlatformReadyData>((res) => {\n platformReadyResolve = res;\n })\n : undefined;\n\n child.on('message', (msg: unknown) => {\n const message = msg as AOTCacheMessage | PlatformReadyMessage;\n if (message?.type === 'mion-aot-caches') {\n resolved = true;\n cleanup();\n resolvePromise({\n data: {\n jitFnsCode: message.jitFnsCode,\n pureFnsCode: message.pureFnsCode,\n routerCacheCode: message.routerCacheCode,\n },\n childProcess: persist ? child : undefined,\n platformReady,\n });\n } else if (message?.type === 'mion-platform-ready' && platformReadyResolve) {\n platformReadyResolve({routerConfig: message.routerConfig, platformConfig: message.platformConfig});\n platformReadyResolve = undefined;\n }\n });\n\n // Capture stderr for error reporting (and pipe through in persist mode)\n child.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (!resolved) stderr += msg + '\\n';\n if (persist && msg) console.error(`[mion-server] ${msg}`);\n });\n\n // Pipe stdout through (always in persist mode, only with DEBUG_AOT otherwise)\n child.stdout?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (persist && msg) {\n console.log(`[mion-server] ${msg}`);\n } else if (process.env.DEBUG_AOT && msg) {\n console.log('[mion-aot] stdout:', msg);\n }\n });\n\n child.on('error', (err) => {\n if (!resolved) {\n cleanup();\n reject(new Error(`vite-node failed to start: ${err.message}`));\n }\n });\n\n child.on('exit', (code) => {\n if (!resolved) {\n cleanup();\n reject(\n new Error(\n `vite-node exited with code ${code} before emitting AOT caches.\\n` +\n `Make sure the startScript calls initMionRouter() and the router ` +\n `is fully initialized.\\n` +\n (stderr ? `stderr: ${stderr}` : '')\n )\n );\n }\n });\n\n // Timeout safety\n const timeoutId = setTimeout(() => {\n if (!resolved) {\n cleanup();\n if (persist) child.kill();\n reject(\n new Error(\n `AOT cache generation timed out (${DEFAULT_TIMEOUT / 1000}s). ` +\n `Make sure the server start script completes initialization.`\n )\n );\n }\n }, DEFAULT_TIMEOUT);\n });\n}\n\n/** Loads a module by URL — abstracts over ssrLoadModule and Environment Runner */\nexport type ModuleLoader = (url: string) => Promise<Record<string, any>>;\n\n/**\n * Loads the startScript with MION_COMPILE=middleware so platform adapters skip server.listen().\n * Generates AOT caches via SSR using a module loader (for same-Vite-process scenarios like Nuxt).\n * After loading, retrieves the caches directly from the router's global state via getSerializedCaches(). */\nexport async function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string): Promise<AOTCacheData> {\n const prevCompile = process.env.MION_COMPILE;\n process.env.MION_COMPILE = 'middleware';\n\n try {\n // Load the start server script — triggers initMionRouter(), populates caches,\n // skips process.send (SSR mode) and skips server.listen() (platform adapters)\n const mod = await loadModule(startScript);\n // Await any Promise-valued exports (e.g. initMionRouter() without top-level await)\n const promises = Object.values(mod).filter((v): v is Promise<any> => v instanceof Promise);\n if (promises.length > 0) await Promise.all(promises);\n\n // Get caches directly from the router's global state\n const aotModule = await loadModule('@mionjs/router/aot');\n const caches: AOTCacheData = await aotModule.getSerializedCaches();\n return caches;\n } finally {\n if (prevCompile === undefined) delete process.env.MION_COMPILE;\n else process.env.MION_COMPILE = prevCompile;\n }\n}\n\n// ============ Persistent child management ============\n\n/** Kills a persistent child process gracefully (SIGTERM then SIGKILL after 5s) */\nexport async function killPersistentChild(child: ChildProcess | null): Promise<void> {\n if (!child || child.killed) return;\n const pid = child.pid;\n\n if (pid) {\n try {\n process.kill(-pid, 'SIGTERM');\n } catch {\n child.kill('SIGTERM');\n }\n } else {\n child.kill('SIGTERM');\n }\n\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n if (child && !child.killed) {\n if (pid) {\n try {\n process.kill(-pid, 'SIGKILL');\n } catch {\n child.kill('SIGKILL');\n }\n } else {\n child.kill('SIGKILL');\n }\n }\n resolve();\n }, 5000);\n\n child!.on('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n}\n\n// ============ Logging ============\n\n/** Formats byte size to human-readable string */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n const kb = bytes / 1024;\n if (kb < 1024) return `${kb.toFixed(1)} KB`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)} MB`;\n}\n\n/** Logs AOT cache sizes and optionally full contents in verbose mode (DEBUG_AOT) */\nexport function logAOTCaches(data: AOTCacheData): void {\n const jitSize = formatBytes(Buffer.byteLength(data.jitFnsCode, 'utf-8'));\n const pureSize = formatBytes(Buffer.byteLength(data.pureFnsCode, 'utf-8'));\n const routerSize = formatBytes(Buffer.byteLength(data.routerCacheCode, 'utf-8'));\n console.log(`[mion] jitFns: ${jitSize}, pureFns: ${pureSize}, routerCache: ${routerSize}`);\n\n if (process.env.DEBUG_AOT) {\n console.log('[mion] AOT jitFns cache:\\n', data.jitFnsCode);\n console.log('[mion] AOT pureFns cache:\\n', data.pureFnsCode);\n console.log('[mion] AOT routerCache:\\n', data.routerCacheCode);\n }\n}\n\n// ============ Module Generators ============\n\n/** Generates the virtual module code for JIT functions cache (exports only). */\nexport function generateJitFnsModule(jitFnsCode: string): string {\n return `/* Auto-generated AOT JIT functions cache - do not edit */\nexport const jitFnsCache = ${jitFnsCode};\n`;\n}\n\n/** Generates the virtual module code for pure functions cache (exports only). */\nexport function generatePureFnsModule(pureFnsCode: string): string {\n return `/* Auto-generated AOT pure functions cache - do not edit */\nexport const pureFnsCache = ${pureFnsCode};\n`;\n}\n\n/** Generates the virtual module code for router methods cache (exports only). */\nexport function generateRouterCacheModule(routerCacheCode: string): string {\n return `/* Auto-generated AOT router cache - do not edit */\nexport const routerCache = ${routerCacheCode};\n`;\n}\n\n/** Generates the combined virtual module that imports all 3 caches and re-exports them. */\nexport function generateCombinedCachesModule(): string {\n return `/* Auto-generated combined AOT caches - do not edit */\nimport { pureFnsCache } from 'virtual:mion-aot/pure-fns';\nimport { jitFnsCache } from 'virtual:mion-aot/jit-fns';\nimport { routerCache } from 'virtual:mion-aot/router-cache';\nimport { addAOTCaches, addRoutesToCache } from '@mionjs/core';\n\n// Auto-register AOT caches as a side effect so they survive tree-shaking\naddAOTCaches(jitFnsCache, pureFnsCache);\naddRoutesToCache(routerCache);\n\nexport { jitFnsCache, pureFnsCache, routerCache };\n\n/** Loads pre-compiled AOT caches (no-op: caches are auto-registered on import). */\nexport function loadAOTCaches() {}\n\n/** Returns the raw AOT caches. */\nexport function getRawAOTCaches() {\n return { jitFnsCache, pureFnsCache, routerCache };\n}\n`;\n}\n\n/** Generates a no-op module for when AOT caches are disabled. */\nexport function generateNoopModule(comment: string): string {\n return `/* ${comment} */\\n`;\n}\n\n/** Waits for the server child process to send a mion-platform-ready IPC message. */\nexport function waitForPlatformReady(\n child: ChildProcess,\n timeoutMs = 30000\n): Promise<{routerConfig: Record<string, unknown>; platformConfig: Record<string, unknown>}> {\n return new Promise((resolve, reject) => {\n const onMessage = (msg: unknown) => {\n const message = msg as PlatformReadyMessage;\n if (message?.type === 'mion-platform-ready') {\n clearTimeout(timeoutId);\n child.removeListener('message', onMessage);\n resolve({routerConfig: message.routerConfig, platformConfig: message.platformConfig});\n }\n };\n child.on('message', onMessage);\n const timeoutId = setTimeout(() => {\n child.removeListener('message', onMessage);\n reject(\n new Error(\n `Server did not call setPlatformConfig() within ${timeoutMs / 1000}s. ` +\n `Ensure your platform adapter (startNodeServer, startBunServer, etc.) is called after initMionRouter().`\n )\n );\n }, timeoutMs);\n });\n}\n\n/** Generates a no-op combined module that exports empty caches. */\nexport function generateNoopCombinedModule(): string {\n return `/* No-op: AOT caches not generated */\nexport const jitFnsCache = {};\nexport const pureFnsCache = {};\nexport const routerCache = {};\nexport function loadAOTCaches() {}\nexport function getRawAOTCaches() { return { jitFnsCache, pureFnsCache, routerCache }; }\n`;\n}\n"],"names":["resolve"],"mappings":"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"}
|
|
@@ -46,7 +46,7 @@ function collectFileStats(dir, baseDir) {
|
|
|
46
46
|
return entries;
|
|
47
47
|
}
|
|
48
48
|
function computeSourceHash(serverConfig, aotOptions) {
|
|
49
|
-
const serverDir = dirname(resolve(serverConfig.
|
|
49
|
+
const serverDir = dirname(resolve(serverConfig.startScript));
|
|
50
50
|
const fileStats = collectFileStats(serverDir, serverDir);
|
|
51
51
|
fileStats.sort();
|
|
52
52
|
const hashInput = [
|
|
@@ -94,7 +94,7 @@ function resolveCacheDir(options, viteCacheDir) {
|
|
|
94
94
|
}
|
|
95
95
|
async function getOrGenerateAOTCaches(serverConfig, aotOptions, cacheDir) {
|
|
96
96
|
const forceRegenerate = process.env.MION_AOT_FORCE === "true";
|
|
97
|
-
const isIPCMode = serverConfig.
|
|
97
|
+
const isIPCMode = serverConfig.runMode === "childProcess";
|
|
98
98
|
const cachingEnabled = cacheDir !== "" && !forceRegenerate && !isIPCMode;
|
|
99
99
|
let hash = "";
|
|
100
100
|
if (cachingEnabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aotDiskCache.js","sources":["../../../../../src/vite-plugin/aotDiskCache.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {createHash} from 'crypto';\nimport {readFileSync, writeFileSync, mkdirSync, readdirSync, statSync} from 'fs';\nimport {join, resolve, dirname, relative} from 'path';\nimport {AOTCacheOptions, MionServerConfig} from './types.ts';\nimport {generateAOTCaches, AOTCacheData, AOTCacheResult} from './aotCacheGenerator.ts';\n\n/** Schema for the on-disk cache file */\ninterface AOTDiskCacheFile {\n cacheVersion: string;\n hash: string;\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** Bump when mion internals change in a way that invalidates cached output */\nconst AOT_DISK_CACHE_VERSION = '2';\n\n/** Cache file name */\nconst CACHE_FILENAME = 'mion-aot-cache.json';\n\n/** Directories to skip when walking the server source tree */\nconst SKIP_DIRS = new Set(['node_modules', '.dist', 'dist', '.git', '.vite', 'build', 'coverage', '.coverage']);\n\n/** File extensions to include in hash computation */\nconst SOURCE_EXTENSIONS = /\\.(ts|tsx)$/;\n\n/** Test file patterns to exclude from hash computation */\nconst TEST_FILE_PATTERN = /\\.(spec|test)\\.(ts|tsx)$/;\n\n/** Read the devtools package version (cached after first call) */\nlet devtoolsVersion: string | null = null;\nfunction getDevtoolsVersion(): string {\n if (devtoolsVersion) return devtoolsVersion;\n try {\n const pkgPath = resolve(dirname(new URL(import.meta.url).pathname), '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n devtoolsVersion = pkg.version || '0.0.0';\n } catch {\n devtoolsVersion = '0.0.0';\n }\n return devtoolsVersion as string;\n}\n\n/** Recursively collect file stats (relativePath:mtimeMs:size) for source files */\nfunction collectFileStats(dir: string, baseDir: string): string[] {\n const entries: string[] = [];\n let files: string[];\n try {\n files = readdirSync(dir);\n } catch {\n return entries;\n }\n for (const file of files) {\n const fullPath = join(dir, file);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isDirectory()) {\n if (SKIP_DIRS.has(file)) continue;\n entries.push(...collectFileStats(fullPath, baseDir));\n } else if (SOURCE_EXTENSIONS.test(file) && !TEST_FILE_PATTERN.test(file)) {\n const relativePath = relative(baseDir, fullPath);\n entries.push(`${relativePath}:${stat.mtimeMs}:${stat.size}`);\n }\n }\n return entries;\n}\n\n/** Compute a SHA-256 hash of the server source directory + options */\nexport function computeSourceHash(serverConfig: MionServerConfig, aotOptions?: AOTCacheOptions): string {\n const serverDir = dirname(resolve(serverConfig.startServerScript));\n const fileStats = collectFileStats(serverDir, serverDir);\n fileStats.sort();\n\n const hashInput = [\n ...fileStats,\n `cacheVersion:${AOT_DISK_CACHE_VERSION}`,\n `devtoolsVersion:${getDevtoolsVersion()}`,\n `excludedFns:${JSON.stringify((aotOptions?.excludedFns || []).slice().sort())}`,\n `excludedPureFns:${JSON.stringify((aotOptions?.excludedPureFns || []).slice().sort())}`,\n ].join('\\n');\n\n return createHash('sha256').update(hashInput).digest('hex');\n}\n\n/** Read and validate the disk cache file. Returns null on any error. */\nfunction readDiskCache(cacheDir: string): AOTDiskCacheFile | null {\n const cachePath = join(cacheDir, CACHE_FILENAME);\n try {\n const raw = readFileSync(cachePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (\n typeof parsed.cacheVersion === 'string' &&\n typeof parsed.hash === 'string' &&\n typeof parsed.jitFnsCode === 'string' &&\n typeof parsed.pureFnsCode === 'string' &&\n typeof parsed.routerCacheCode === 'string'\n ) {\n return parsed as AOTDiskCacheFile;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Write cache data to disk. Best-effort — logs warning on failure. */\nfunction writeDiskCache(cacheDir: string, hash: string, data: AOTCacheData): void {\n const cachePath = join(cacheDir, CACHE_FILENAME);\n try {\n mkdirSync(cacheDir, {recursive: true});\n const cacheFile: AOTDiskCacheFile = {\n cacheVersion: AOT_DISK_CACHE_VERSION,\n hash,\n jitFnsCode: data.jitFnsCode,\n pureFnsCode: data.pureFnsCode,\n routerCacheCode: data.routerCacheCode,\n };\n writeFileSync(cachePath, JSON.stringify(cacheFile), 'utf-8');\n } catch (err) {\n console.warn(`[mion] Warning: Could not write AOT disk cache: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\n/** Resolve the cache directory from options and Vite's cacheDir */\nexport function resolveCacheDir(options: AOTCacheOptions, viteCacheDir?: string): string {\n if (options.cache === false) return '';\n if (typeof options.cache === 'string') return resolve(options.cache);\n return viteCacheDir || resolve(process.cwd(), 'node_modules/.vite');\n}\n\n/** Load AOT caches from disk if valid, otherwise generate fresh and save to disk. */\nexport async function getOrGenerateAOTCaches(\n serverConfig: MionServerConfig,\n aotOptions: AOTCacheOptions | undefined,\n cacheDir: string\n): Promise<AOTCacheResult> {\n const forceRegenerate = process.env.MION_AOT_FORCE === 'true';\n // IPC mode always needs a live child process (the server), so skip disk caching entirely\n const isIPCMode = serverConfig.mode === 'IPC';\n const cachingEnabled = cacheDir !== '' && !forceRegenerate && !isIPCMode;\n\n let hash = '';\n if (cachingEnabled) {\n hash = computeSourceHash(serverConfig, aotOptions);\n const cached = readDiskCache(cacheDir);\n if (cached && cached.cacheVersion === AOT_DISK_CACHE_VERSION && cached.hash === hash) {\n console.log('[mion] AOT caches loaded from disk cache (source unchanged)');\n return {\n data: {\n jitFnsCode: cached.jitFnsCode,\n pureFnsCode: cached.pureFnsCode,\n routerCacheCode: cached.routerCacheCode,\n },\n };\n }\n }\n\n // Cache miss or caching disabled — generate fresh\n const result = await generateAOTCaches(serverConfig);\n\n if (cachingEnabled) {\n if (!hash) hash = computeSourceHash(serverConfig, aotOptions);\n writeDiskCache(cacheDir, hash, result.data);\n console.log('[mion] AOT caches saved to disk cache');\n }\n\n return result;\n}\n\n/** Update the disk cache after HMR regeneration */\nexport function updateDiskCache(\n serverConfig: MionServerConfig,\n aotOptions: AOTCacheOptions | undefined,\n data: AOTCacheData,\n cacheDir: string\n): void {\n if (!cacheDir || aotOptions?.cache === false) return;\n const hash = computeSourceHash(serverConfig, aotOptions);\n writeDiskCache(cacheDir, hash, data);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"aotDiskCache.js","sources":["../../../../../src/vite-plugin/aotDiskCache.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {createHash} from 'crypto';\nimport {readFileSync, writeFileSync, mkdirSync, readdirSync, statSync} from 'fs';\nimport {join, resolve, dirname, relative} from 'path';\nimport {AOTCacheOptions, MionServerConfig} from './types.ts';\nimport {generateAOTCaches, AOTCacheData, AOTCacheResult} from './aotCacheGenerator.ts';\n\n/** Schema for the on-disk cache file */\ninterface AOTDiskCacheFile {\n cacheVersion: string;\n hash: string;\n jitFnsCode: string;\n pureFnsCode: string;\n routerCacheCode: string;\n}\n\n/** Bump when mion internals change in a way that invalidates cached output */\nconst AOT_DISK_CACHE_VERSION = '2';\n\n/** Cache file name */\nconst CACHE_FILENAME = 'mion-aot-cache.json';\n\n/** Directories to skip when walking the server source tree */\nconst SKIP_DIRS = new Set(['node_modules', '.dist', 'dist', '.git', '.vite', 'build', 'coverage', '.coverage']);\n\n/** File extensions to include in hash computation */\nconst SOURCE_EXTENSIONS = /\\.(ts|tsx)$/;\n\n/** Test file patterns to exclude from hash computation */\nconst TEST_FILE_PATTERN = /\\.(spec|test)\\.(ts|tsx)$/;\n\n/** Read the devtools package version (cached after first call) */\nlet devtoolsVersion: string | null = null;\nfunction getDevtoolsVersion(): string {\n if (devtoolsVersion) return devtoolsVersion;\n try {\n const pkgPath = resolve(dirname(new URL(import.meta.url).pathname), '../../package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n devtoolsVersion = pkg.version || '0.0.0';\n } catch {\n devtoolsVersion = '0.0.0';\n }\n return devtoolsVersion as string;\n}\n\n/** Recursively collect file stats (relativePath:mtimeMs:size) for source files */\nfunction collectFileStats(dir: string, baseDir: string): string[] {\n const entries: string[] = [];\n let files: string[];\n try {\n files = readdirSync(dir);\n } catch {\n return entries;\n }\n for (const file of files) {\n const fullPath = join(dir, file);\n let stat;\n try {\n stat = statSync(fullPath);\n } catch {\n continue;\n }\n if (stat.isDirectory()) {\n if (SKIP_DIRS.has(file)) continue;\n entries.push(...collectFileStats(fullPath, baseDir));\n } else if (SOURCE_EXTENSIONS.test(file) && !TEST_FILE_PATTERN.test(file)) {\n const relativePath = relative(baseDir, fullPath);\n entries.push(`${relativePath}:${stat.mtimeMs}:${stat.size}`);\n }\n }\n return entries;\n}\n\n/** Compute a SHA-256 hash of the server source directory + options */\nexport function computeSourceHash(serverConfig: MionServerConfig, aotOptions?: AOTCacheOptions): string {\n const serverDir = dirname(resolve(serverConfig.startScript));\n const fileStats = collectFileStats(serverDir, serverDir);\n fileStats.sort();\n\n const hashInput = [\n ...fileStats,\n `cacheVersion:${AOT_DISK_CACHE_VERSION}`,\n `devtoolsVersion:${getDevtoolsVersion()}`,\n `excludedFns:${JSON.stringify((aotOptions?.excludedFns || []).slice().sort())}`,\n `excludedPureFns:${JSON.stringify((aotOptions?.excludedPureFns || []).slice().sort())}`,\n ].join('\\n');\n\n return createHash('sha256').update(hashInput).digest('hex');\n}\n\n/** Read and validate the disk cache file. Returns null on any error. */\nfunction readDiskCache(cacheDir: string): AOTDiskCacheFile | null {\n const cachePath = join(cacheDir, CACHE_FILENAME);\n try {\n const raw = readFileSync(cachePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (\n typeof parsed.cacheVersion === 'string' &&\n typeof parsed.hash === 'string' &&\n typeof parsed.jitFnsCode === 'string' &&\n typeof parsed.pureFnsCode === 'string' &&\n typeof parsed.routerCacheCode === 'string'\n ) {\n return parsed as AOTDiskCacheFile;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Write cache data to disk. Best-effort — logs warning on failure. */\nfunction writeDiskCache(cacheDir: string, hash: string, data: AOTCacheData): void {\n const cachePath = join(cacheDir, CACHE_FILENAME);\n try {\n mkdirSync(cacheDir, {recursive: true});\n const cacheFile: AOTDiskCacheFile = {\n cacheVersion: AOT_DISK_CACHE_VERSION,\n hash,\n jitFnsCode: data.jitFnsCode,\n pureFnsCode: data.pureFnsCode,\n routerCacheCode: data.routerCacheCode,\n };\n writeFileSync(cachePath, JSON.stringify(cacheFile), 'utf-8');\n } catch (err) {\n console.warn(`[mion] Warning: Could not write AOT disk cache: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\n/** Resolve the cache directory from options and Vite's cacheDir */\nexport function resolveCacheDir(options: AOTCacheOptions, viteCacheDir?: string): string {\n if (options.cache === false) return '';\n if (typeof options.cache === 'string') return resolve(options.cache);\n return viteCacheDir || resolve(process.cwd(), 'node_modules/.vite');\n}\n\n/** Load AOT caches from disk if valid, otherwise generate fresh and save to disk. */\nexport async function getOrGenerateAOTCaches(\n serverConfig: MionServerConfig,\n aotOptions: AOTCacheOptions | undefined,\n cacheDir: string\n): Promise<AOTCacheResult> {\n const forceRegenerate = process.env.MION_AOT_FORCE === 'true';\n // IPC mode always needs a live child process (the server), so skip disk caching entirely\n const isIPCMode = serverConfig.runMode === 'childProcess';\n const cachingEnabled = cacheDir !== '' && !forceRegenerate && !isIPCMode;\n\n let hash = '';\n if (cachingEnabled) {\n hash = computeSourceHash(serverConfig, aotOptions);\n const cached = readDiskCache(cacheDir);\n if (cached && cached.cacheVersion === AOT_DISK_CACHE_VERSION && cached.hash === hash) {\n console.log('[mion] AOT caches loaded from disk cache (source unchanged)');\n return {\n data: {\n jitFnsCode: cached.jitFnsCode,\n pureFnsCode: cached.pureFnsCode,\n routerCacheCode: cached.routerCacheCode,\n },\n };\n }\n }\n\n // Cache miss or caching disabled — generate fresh\n const result = await generateAOTCaches(serverConfig);\n\n if (cachingEnabled) {\n if (!hash) hash = computeSourceHash(serverConfig, aotOptions);\n writeDiskCache(cacheDir, hash, result.data);\n console.log('[mion] AOT caches saved to disk cache');\n }\n\n return result;\n}\n\n/** Update the disk cache after HMR regeneration */\nexport function updateDiskCache(\n serverConfig: MionServerConfig,\n aotOptions: AOTCacheOptions | undefined,\n data: AOTCacheData,\n cacheDir: string\n): void {\n if (!cacheDir || aotOptions?.cache === false) return;\n const hash = computeSourceHash(serverConfig, aotOptions);\n writeDiskCache(cacheDir, hash, data);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@ export declare const VIRTUAL_AOT_JIT_FNS = "virtual:mion-aot/jit-fns";
|
|
|
4
4
|
export declare const VIRTUAL_AOT_PURE_FNS = "virtual:mion-aot/pure-fns";
|
|
5
5
|
export declare const VIRTUAL_AOT_ROUTER_CACHE = "virtual:mion-aot/router-cache";
|
|
6
6
|
export declare const VIRTUAL_AOT_CACHES = "virtual:mion-aot/caches";
|
|
7
|
+
export declare const AOT_CACHES_SHIM = "@mionjs/core/aot-caches";
|
|
8
|
+
export declare const SERVER_PURE_FNS_SHIM = "@mionjs/core/server-pure-fns";
|
|
7
9
|
export declare const PURE_SERVER_FN_NAMESPACE = "pureServerFn";
|
|
8
10
|
export declare function resolveVirtualId(id: string): string;
|
|
9
11
|
export declare const REFLECTION_MODULES: string[];
|
|
@@ -4,6 +4,8 @@ const VIRTUAL_AOT_JIT_FNS = "virtual:mion-aot/jit-fns";
|
|
|
4
4
|
const VIRTUAL_AOT_PURE_FNS = "virtual:mion-aot/pure-fns";
|
|
5
5
|
const VIRTUAL_AOT_ROUTER_CACHE = "virtual:mion-aot/router-cache";
|
|
6
6
|
const VIRTUAL_AOT_CACHES = "virtual:mion-aot/caches";
|
|
7
|
+
const AOT_CACHES_SHIM = "@mionjs/core/aot-caches";
|
|
8
|
+
const SERVER_PURE_FNS_SHIM = "@mionjs/core/server-pure-fns";
|
|
7
9
|
const PURE_SERVER_FN_NAMESPACE = "pureServerFn";
|
|
8
10
|
function resolveVirtualId(id) {
|
|
9
11
|
return "\0" + id + ".ts";
|
|
@@ -11,9 +13,11 @@ function resolveVirtualId(id) {
|
|
|
11
13
|
const REFLECTION_MODULES = ["@mionjs/run-types", "@deepkit/type", "@deepkit/core"];
|
|
12
14
|
const VIRTUAL_STUB_PREFIX = "virtual:mion-stub/";
|
|
13
15
|
export {
|
|
16
|
+
AOT_CACHES_SHIM,
|
|
14
17
|
BODY_HASH_LENGTH,
|
|
15
18
|
PURE_SERVER_FN_NAMESPACE,
|
|
16
19
|
REFLECTION_MODULES,
|
|
20
|
+
SERVER_PURE_FNS_SHIM,
|
|
17
21
|
VIRTUAL_AOT_CACHES,
|
|
18
22
|
VIRTUAL_AOT_JIT_FNS,
|
|
19
23
|
VIRTUAL_AOT_PURE_FNS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../../../src/vite-plugin/constants.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nexport const BODY_HASH_LENGTH = 14;\n\n/** Virtual module ID for the pure functions registry (client-extracted pure functions) */\nexport const VIRTUAL_SERVER_PURE_FNS = 'virtual:mion-server-pure-fns';\n\n// ============ AOT Virtual Modules ============\n\n/** Virtual module ID for JIT functions + pure functions cache (from running the router) */\nexport const VIRTUAL_AOT_JIT_FNS = 'virtual:mion-aot/jit-fns';\n\n/** Virtual module ID for pure functions cache (standalone, from client AST extraction) */\nexport const VIRTUAL_AOT_PURE_FNS = 'virtual:mion-aot/pure-fns';\n\n/** Virtual module ID for router methods cache */\nexport const VIRTUAL_AOT_ROUTER_CACHE = 'virtual:mion-aot/router-cache';\n\n/** Virtual module ID for combined AOT caches (re-exports all 3 cache modules) */\nexport const VIRTUAL_AOT_CACHES = 'virtual:mion-aot/caches';\n\n/** The namespace used for all pureServerFn functions */\nexport const PURE_SERVER_FN_NAMESPACE = 'pureServerFn';\n\n/** Resolves a virtual module ID to its internal Vite ID (\\0 prefix + .ts extension) */\nexport function resolveVirtualId(id: string): string {\n return '\\0' + id + '.ts';\n}\n\n// ============ Reflection Stubs (for excludeReflection) ============\n\n/** Modules stubbed out when excludeReflection is enabled (not needed at runtime in AOT mode) */\nexport const REFLECTION_MODULES = ['@mionjs/run-types', '@deepkit/type', '@deepkit/core'];\n\n/** Prefix for virtual stub module IDs */\nexport const VIRTUAL_STUB_PREFIX = 'virtual:mion-stub/';\n\n// Purity validation constants (ALLOWED_GLOBALS, FORBIDDEN_IDENTIFIERS, FACTORY_FORBIDDEN_IDENTIFIERS)\n// are in ../pureFns/purityRules.ts, shared with the eslint plugin.\n"],"names":[],"mappings":"AAOO,MAAM,mBAAmB;AAGzB,MAAM,0BAA0B;AAKhC,MAAM,sBAAsB;AAG5B,MAAM,uBAAuB;AAG7B,MAAM,2BAA2B;AAGjC,MAAM,qBAAqB;AAG3B,MAAM,2BAA2B;AAGjC,SAAS,iBAAiB,IAAoB;AACjD,SAAO,OAAO,KAAK;AACvB;AAKO,MAAM,qBAAqB,CAAC,qBAAqB,iBAAiB,eAAe;AAGjF,MAAM,sBAAsB;"}
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../../src/vite-plugin/constants.ts"],"sourcesContent":["/* ########\n * 2026 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nexport const BODY_HASH_LENGTH = 14;\n\n/** Virtual module ID for the pure functions registry (client-extracted pure functions) */\nexport const VIRTUAL_SERVER_PURE_FNS = 'virtual:mion-server-pure-fns';\n\n// ============ AOT Virtual Modules ============\n\n/** Virtual module ID for JIT functions + pure functions cache (from running the router) */\nexport const VIRTUAL_AOT_JIT_FNS = 'virtual:mion-aot/jit-fns';\n\n/** Virtual module ID for pure functions cache (standalone, from client AST extraction) */\nexport const VIRTUAL_AOT_PURE_FNS = 'virtual:mion-aot/pure-fns';\n\n/** Virtual module ID for router methods cache */\nexport const VIRTUAL_AOT_ROUTER_CACHE = 'virtual:mion-aot/router-cache';\n\n/** Virtual module ID for combined AOT caches (re-exports all 3 cache modules) */\nexport const VIRTUAL_AOT_CACHES = 'virtual:mion-aot/caches';\n\n/** The real module that acts as a shim for AOT caches (empty caches). Swapped by the plugin when AOT is enabled. */\nexport const AOT_CACHES_SHIM = '@mionjs/core/aot-caches';\n\n/** The real module that acts as a shim for server pure functions (empty cache). Swapped by the plugin when serverPureFunctions is enabled. */\nexport const SERVER_PURE_FNS_SHIM = '@mionjs/core/server-pure-fns';\n\n/** The namespace used for all pureServerFn functions */\nexport const PURE_SERVER_FN_NAMESPACE = 'pureServerFn';\n\n/** Resolves a virtual module ID to its internal Vite ID (\\0 prefix + .ts extension) */\nexport function resolveVirtualId(id: string): string {\n return '\\0' + id + '.ts';\n}\n\n// ============ Reflection Stubs (for excludeReflection) ============\n\n/** Modules stubbed out when excludeReflection is enabled (not needed at runtime in AOT mode) */\nexport const REFLECTION_MODULES = ['@mionjs/run-types', '@deepkit/type', '@deepkit/core'];\n\n/** Prefix for virtual stub module IDs */\nexport const VIRTUAL_STUB_PREFIX = 'virtual:mion-stub/';\n\n// Purity validation constants (ALLOWED_GLOBALS, FORBIDDEN_IDENTIFIERS, FACTORY_FORBIDDEN_IDENTIFIERS)\n// are in ../pureFns/purityRules.ts, shared with the eslint plugin.\n"],"names":[],"mappings":"AAOO,MAAM,mBAAmB;AAGzB,MAAM,0BAA0B;AAKhC,MAAM,sBAAsB;AAG5B,MAAM,uBAAuB;AAG7B,MAAM,2BAA2B;AAGjC,MAAM,qBAAqB;AAG3B,MAAM,kBAAkB;AAGxB,MAAM,uBAAuB;AAG7B,MAAM,2BAA2B;AAGjC,SAAS,iBAAiB,IAAoB;AACjD,SAAO,OAAO,KAAK;AACvB;AAKO,MAAM,qBAAqB,CAAC,qBAAqB,iBAAiB,eAAe;AAGjF,MAAM,sBAAsB;"}
|
|
@@ -8,11 +8,11 @@ export interface MionPluginOptions {
|
|
|
8
8
|
export declare function mionVitePlugin(options: MionPluginOptions): {
|
|
9
9
|
name: string;
|
|
10
10
|
enforce: "pre";
|
|
11
|
-
config(config: any): void;
|
|
11
|
+
config(config: any, env: any): void;
|
|
12
12
|
configResolved(config: any): void;
|
|
13
13
|
buildStart(): Promise<void>;
|
|
14
14
|
configureServer(server: any): void;
|
|
15
|
-
resolveId(id: any): string | null;
|
|
15
|
+
resolveId(id: any, importer: any): string | null;
|
|
16
16
|
load(id: any): Promise<string | {
|
|
17
17
|
code: string;
|
|
18
18
|
syntheticNamedExports: boolean;
|