@mionjs/devtools 0.8.4-alpha.0 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.cjs +12 -3
  2. package/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.cjs.map +1 -1
  3. package/build/vite-plugin/cjs/src/vite-plugin/aotCacheGenerator.d.ts +2 -2
  4. package/build/vite-plugin/cjs/src/vite-plugin/aotDiskCache.cjs +3 -2
  5. package/build/vite-plugin/cjs/src/vite-plugin/aotDiskCache.cjs.map +1 -1
  6. package/build/vite-plugin/cjs/src/vite-plugin/mionVitePlugin.cjs +15 -5
  7. package/build/vite-plugin/cjs/src/vite-plugin/mionVitePlugin.cjs.map +1 -1
  8. package/build/vite-plugin/cjs/src/vite-plugin/types.d.ts +1 -0
  9. package/build/vite-plugin/cjs/src/vite-plugin/virtualModule.cjs +3 -2
  10. package/build/vite-plugin/cjs/src/vite-plugin/virtualModule.cjs.map +1 -1
  11. package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.d.ts +2 -2
  12. package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.js +12 -3
  13. package/build/vite-plugin/esm/src/vite-plugin/aotCacheGenerator.js.map +1 -1
  14. package/build/vite-plugin/esm/src/vite-plugin/aotDiskCache.js +3 -2
  15. package/build/vite-plugin/esm/src/vite-plugin/aotDiskCache.js.map +1 -1
  16. package/build/vite-plugin/esm/src/vite-plugin/mionVitePlugin.js +15 -5
  17. package/build/vite-plugin/esm/src/vite-plugin/mionVitePlugin.js.map +1 -1
  18. package/build/vite-plugin/esm/src/vite-plugin/types.d.ts +1 -0
  19. package/build/vite-plugin/esm/src/vite-plugin/virtualModule.js +3 -2
  20. package/build/vite-plugin/esm/src/vite-plugin/virtualModule.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/vite-plugin/virtual-modules.d.ts +1 -1
@@ -4,7 +4,7 @@ const child_process = require("child_process");
4
4
  const path = require("path");
5
5
  const src_vitePlugin_resolveModule = require("./resolveModule.cjs");
6
6
  const DEFAULT_TIMEOUT = 3e4;
7
- async function generateAOTCaches(serverConfig, startScriptOverride) {
7
+ async function generateAOTCaches(serverConfig, startScriptOverride, isClient) {
8
8
  const persist = serverConfig.runMode === "childProcess";
9
9
  const startScript = path.resolve(startScriptOverride ?? serverConfig.startScript);
10
10
  const scriptDir = path.dirname(startScript);
@@ -25,7 +25,12 @@ Original error: ${err instanceof Error ? err.message : String(err)}`
25
25
  let stderr = "";
26
26
  try {
27
27
  child = child_process.fork(viteNodePath, [...viteConfigArgs, startScript, ...serverConfig.args || []], {
28
- env: { ...process.env, ...serverConfig.env, MION_COMPILE: serverConfig.runMode },
28
+ env: {
29
+ ...process.env,
30
+ ...serverConfig.env,
31
+ MION_COMPILE: serverConfig.runMode,
32
+ ...isClient ? { MION_AOT_IS_CLIENT: "true" } : {}
33
+ },
29
34
  stdio: ["pipe", "pipe", "pipe", "ipc"],
30
35
  cwd: scriptDir
31
36
  });
@@ -111,9 +116,11 @@ Make sure the startScript calls initMionRouter() and the router is fully initial
111
116
  }, DEFAULT_TIMEOUT);
112
117
  });
113
118
  }
114
- async function loadSSRRouterAndGenerateAOTCaches(loadModule, startScript) {
119
+ async function loadSSRRouterAndGenerateAOTCaches(loadModule, startScript, isClient) {
115
120
  const prevCompile = process.env.MION_COMPILE;
121
+ const prevIsClient = process.env.MION_AOT_IS_CLIENT;
116
122
  process.env.MION_COMPILE = "middleware";
123
+ if (isClient) process.env.MION_AOT_IS_CLIENT = "true";
117
124
  try {
118
125
  const mod = await loadModule(startScript);
119
126
  const promises = Object.values(mod).filter((v) => v instanceof Promise);
@@ -124,6 +131,8 @@ async function loadSSRRouterAndGenerateAOTCaches(loadModule, startScript) {
124
131
  } finally {
125
132
  if (prevCompile === void 0) delete process.env.MION_COMPILE;
126
133
  else process.env.MION_COMPILE = prevCompile;
134
+ if (prevIsClient === void 0) delete process.env.MION_AOT_IS_CLIENT;
135
+ else process.env.MION_AOT_IS_CLIENT = prevIsClient;
127
136
  }
128
137
  }
129
138
  async function killPersistentChild(child) {
@@ -1 +1 @@
1
- {"version":3,"file":"aotCacheGenerator.cjs","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","dirname","resolveModule","fork"],"mappings":"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"}
1
+ {"version":3,"file":"aotCacheGenerator.cjs","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(\n serverConfig: MionServerConfig,\n startScriptOverride?: string,\n isClient?: boolean\n): 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: {\n ...process.env,\n ...serverConfig.env,\n MION_COMPILE: serverConfig.runMode,\n ...(isClient ? {MION_AOT_IS_CLIENT: 'true'} : {}),\n },\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(\n loadModule: ModuleLoader,\n startScript: string,\n isClient?: boolean\n): Promise<AOTCacheData> {\n const prevCompile = process.env.MION_COMPILE;\n const prevIsClient = process.env.MION_AOT_IS_CLIENT;\n process.env.MION_COMPILE = 'middleware';\n if (isClient) process.env.MION_AOT_IS_CLIENT = 'true';\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 if (prevIsClient === undefined) delete process.env.MION_AOT_IS_CLIENT;\n else process.env.MION_AOT_IS_CLIENT = prevIsClient;\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","dirname","resolveModule","fork"],"mappings":";;;;;AA+CA,MAAM,kBAAkB;AAaxB,eAAsB,kBAClB,cACA,qBACA,UACuB;AACvB,QAAM,UAAU,aAAa,YAAY;AACzC,QAAM,cAAcA,KAAAA,QAAQ,uBAAuB,aAAa,WAAW;AAC3E,QAAM,YAAYC,KAAAA,QAAQ,WAAW;AAIrC,QAAM,iBAAiB,aAAa,aAAa,CAAC,YAAYD,KAAAA,QAAQ,aAAa,UAAU,CAAC,IAAI,CAAA;AAGlG,MAAI;AACJ,MAAI;AACA,mBAAe,MAAME,6BAAAA,cAAc,iBAAiB,SAAS;AAAA,EACjE,SAAS,KAAK;AACV,UAAM,IAAI;AAAA,MACN;AAAA;AAAA,kBAEuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAAA;AAAA,EAE/E;AAEA,SAAO,IAAI,QAAQ,CAAC,gBAAgB,WAAW;AAC3C,QAAI;AACJ,QAAI,WAAW;AACf,QAAI,SAAS;AAEb,QAAI;AAGA,cAAQC,cAAAA,KAAK,cAAc,CAAC,GAAG,gBAAgB,aAAa,GAAI,aAAa,QAAQ,CAAA,CAAG,GAAG;AAAA,QACvF,KAAK;AAAA,UACD,GAAG,QAAQ;AAAA,UACX,GAAG,aAAa;AAAA,UAChB,cAAc,aAAa;AAAA,UAC3B,GAAI,WAAW,EAAC,oBAAoB,WAAU,CAAA;AAAA,QAAC;AAAA,QAEnD,OAAO,CAAC,QAAQ,QAAQ,QAAQ,KAAK;AAAA,QACrC,KAAK;AAAA,MAAA,CACR;AAAA,IACL,SAAS,KAAK;AAEV;AAAA,QACI,IAAI;AAAA,UACA;AAAA;AAAA,kBAEuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAAA;AAAA,MAC3E;AAEJ;AAAA,IACJ;AAIA,UAAM,UAAU,MAAM;AAClB,mBAAa,SAAS;AACtB,UAAI,CAAC,WAAW,MAAM,iBAAiB,WAAA;AACvC,UAAI,CAAC,QAAS,OAAM,KAAA;AAAA,IACxB;AAIA,QAAI;AACJ,UAAM,gBAAgB,UAChB,IAAI,QAA2B,CAAC,QAAQ;AACpC,6BAAuB;AAAA,IAC3B,CAAC,IACD;AAEN,UAAM,GAAG,WAAW,CAAC,QAAiB;AAClC,YAAM,UAAU;AAChB,UAAI,SAAS,SAAS,mBAAmB;AACrC,mBAAW;AACX,gBAAA;AACA,uBAAe;AAAA,UACX,MAAM;AAAA,YACF,YAAY,QAAQ;AAAA,YACpB,aAAa,QAAQ;AAAA,YACrB,iBAAiB,QAAQ;AAAA,UAAA;AAAA,UAE7B,cAAc,UAAU,QAAQ;AAAA,UAChC;AAAA,QAAA,CACH;AAAA,MACL,WAAW,SAAS,SAAS,yBAAyB,sBAAsB;AACxE,6BAAqB,EAAC,cAAc,QAAQ,cAAc,gBAAgB,QAAQ,gBAAe;AACjG,+BAAuB;AAAA,MAC3B;AAAA,IACJ,CAAC;AAGD,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACvC,YAAM,MAAM,KAAK,SAAA,EAAW,KAAA;AAC5B,UAAI,CAAC,SAAU,WAAU,MAAM;AAC/B,UAAI,WAAW,IAAK,SAAQ,MAAM,iBAAiB,GAAG,EAAE;AAAA,IAC5D,CAAC;AAGD,UAAM,QAAQ,GAAG,QAAQ,CAAC,SAAiB;AACvC,YAAM,MAAM,KAAK,SAAA,EAAW,KAAA;AAC5B,UAAI,WAAW,KAAK;AAChB,gBAAQ,IAAI,iBAAiB,GAAG,EAAE;AAAA,MACtC,WAAW,QAAQ,IAAI,aAAa,KAAK;AACrC,gBAAQ,IAAI,sBAAsB,GAAG;AAAA,MACzC;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,SAAS,CAAC,QAAQ;AACvB,UAAI,CAAC,UAAU;AACX,gBAAA;AACA,eAAO,IAAI,MAAM,8BAA8B,IAAI,OAAO,EAAE,CAAC;AAAA,MACjE;AAAA,IACJ,CAAC;AAED,UAAM,GAAG,QAAQ,CAAC,SAAS;AACvB,UAAI,CAAC,UAAU;AACX,gBAAA;AACA;AAAA,UACI,IAAI;AAAA,YACA,8BAA8B,IAAI;AAAA;AAAA,KAG7B,SAAS,WAAW,MAAM,KAAK;AAAA,UAAA;AAAA,QACxC;AAAA,MAER;AAAA,IACJ,CAAC;AAGD,UAAM,YAAY,WAAW,MAAM;AAC/B,UAAI,CAAC,UAAU;AACX,gBAAA;AACA,YAAI,eAAe,KAAA;AACnB;AAAA,UACI,IAAI;AAAA,YACA,mCAAmC,kBAAkB,GAAI;AAAA,UAAA;AAAA,QAE7D;AAAA,MAER;AAAA,IACJ,GAAG,eAAe;AAAA,EACtB,CAAC;AACL;AASA,eAAsB,kCAClB,YACA,aACA,UACqB;AACrB,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,eAAe,QAAQ,IAAI;AACjC,UAAQ,IAAI,eAAe;AAC3B,MAAI,SAAU,SAAQ,IAAI,qBAAqB;AAE/C,MAAI;AAGA,UAAM,MAAM,MAAM,WAAW,WAAW;AAExC,UAAM,WAAW,OAAO,OAAO,GAAG,EAAE,OAAO,CAAC,MAAyB,aAAa,OAAO;AACzF,QAAI,SAAS,SAAS,EAAG,OAAM,QAAQ,IAAI,QAAQ;AAGnD,UAAM,YAAY,MAAM,WAAW,oBAAoB;AACvD,UAAM,SAAuB,MAAM,UAAU,oBAAA;AAC7C,WAAO;AAAA,EACX,UAAA;AACI,QAAI,gBAAgB,OAAW,QAAO,QAAQ,IAAI;AAAA,QAC7C,SAAQ,IAAI,eAAe;AAChC,QAAI,iBAAiB,OAAW,QAAO,QAAQ,IAAI;AAAA,QAC9C,SAAQ,IAAI,qBAAqB;AAAA,EAC1C;AACJ;AAKA,eAAsB,oBAAoB,OAA2C;AACjF,MAAI,CAAC,SAAS,MAAM,OAAQ;AAC5B,QAAM,MAAM,MAAM;AAElB,MAAI,KAAK;AACL,QAAI;AACA,cAAQ,KAAK,CAAC,KAAK,SAAS;AAAA,IAChC,QAAQ;AACJ,YAAM,KAAK,SAAS;AAAA,IACxB;AAAA,EACJ,OAAO;AACH,UAAM,KAAK,SAAS;AAAA,EACxB;AAEA,QAAM,IAAI,QAAc,CAACH,aAAY;AACjC,UAAM,UAAU,WAAW,MAAM;AAC7B,UAAI,SAAS,CAAC,MAAM,QAAQ;AACxB,YAAI,KAAK;AACL,cAAI;AACA,oBAAQ,KAAK,CAAC,KAAK,SAAS;AAAA,UAChC,QAAQ;AACJ,kBAAM,KAAK,SAAS;AAAA,UACxB;AAAA,QACJ,OAAO;AACH,gBAAM,KAAK,SAAS;AAAA,QACxB;AAAA,MACJ;AACAA,eAAAA;AAAAA,IACJ,GAAG,GAAI;AAEP,UAAO,GAAG,QAAQ,MAAM;AACpB,mBAAa,OAAO;AACpBA,eAAAA;AAAAA,IACJ,CAAC;AAAA,EACL,CAAC;AACL;AAKA,SAAS,YAAY,OAAuB;AACxC,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,QAAM,KAAK,QAAQ;AACnB,MAAI,KAAK,KAAM,QAAO,GAAG,GAAG,QAAQ,CAAC,CAAC;AACtC,QAAM,KAAK,KAAK;AAChB,SAAO,GAAG,GAAG,QAAQ,CAAC,CAAC;AAC3B;AAGO,SAAS,aAAa,MAA0B;AACnD,QAAM,UAAU,YAAY,OAAO,WAAW,KAAK,YAAY,OAAO,CAAC;AACvE,QAAM,WAAW,YAAY,OAAO,WAAW,KAAK,aAAa,OAAO,CAAC;AACzE,QAAM,aAAa,YAAY,OAAO,WAAW,KAAK,iBAAiB,OAAO,CAAC;AAC/E,UAAQ,IAAI,oBAAoB,OAAO,cAAc,QAAQ,kBAAkB,UAAU,EAAE;AAE3F,MAAI,QAAQ,IAAI,WAAW;AACvB,YAAQ,IAAI,8BAA8B,KAAK,UAAU;AACzD,YAAQ,IAAI,+BAA+B,KAAK,WAAW;AAC3D,YAAQ,IAAI,6BAA6B,KAAK,eAAe;AAAA,EACjE;AACJ;AAKO,SAAS,qBAAqB,YAA4B;AAC7D,SAAO;AAAA,6BACkB,UAAU;AAAA;AAEvC;AAGO,SAAS,sBAAsB,aAA6B;AAC/D,SAAO;AAAA,8BACmB,WAAW;AAAA;AAEzC;AAGO,SAAS,0BAA0B,iBAAiC;AACvE,SAAO;AAAA,6BACkB,eAAe;AAAA;AAE5C;AAGO,SAAS,+BAAuC;AACnD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBX;AAGO,SAAS,mBAAmB,SAAyB;AACxD,SAAO,MAAM,OAAO;AAAA;AACxB;AAGO,SAAS,qBACZ,OACA,YAAY,KAC6E;AACzF,SAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,UAAM,YAAY,CAAC,QAAiB;AAChC,YAAM,UAAU;AAChB,UAAI,SAAS,SAAS,uBAAuB;AACzC,qBAAa,SAAS;AACtB,cAAM,eAAe,WAAW,SAAS;AACzCA,iBAAQ,EAAC,cAAc,QAAQ,cAAc,gBAAgB,QAAQ,gBAAe;AAAA,MACxF;AAAA,IACJ;AACA,UAAM,GAAG,WAAW,SAAS;AAC7B,UAAM,YAAY,WAAW,MAAM;AAC/B,YAAM,eAAe,WAAW,SAAS;AACzC;AAAA,QACI,IAAI;AAAA,UACA,kDAAkD,YAAY,GAAI;AAAA,QAAA;AAAA,MAEtE;AAAA,IAER,GAAG,SAAS;AAAA,EAChB,CAAC;AACL;AAGO,SAAS,6BAAqC;AACjD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOX;;;;;;;;;;;;"}
@@ -14,9 +14,9 @@ export interface PlatformReadyData {
14
14
  routerConfig: Record<string, unknown>;
15
15
  platformConfig: Record<string, unknown>;
16
16
  }
17
- export declare function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string): Promise<AOTCacheResult>;
17
+ export declare function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string, isClient?: boolean): Promise<AOTCacheResult>;
18
18
  export type ModuleLoader = (url: string) => Promise<Record<string, any>>;
19
- export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string): Promise<AOTCacheData>;
19
+ export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string, isClient?: boolean): Promise<AOTCacheData>;
20
20
  export declare function killPersistentChild(child: ChildProcess | null): Promise<void>;
21
21
  export declare function logAOTCaches(data: AOTCacheData): void;
22
22
  export declare function generateJitFnsModule(jitFnsCode: string): string;
@@ -57,7 +57,8 @@ function computeSourceHash(serverConfig, aotOptions) {
57
57
  `cacheVersion:${AOT_DISK_CACHE_VERSION}`,
58
58
  `devtoolsVersion:${getDevtoolsVersion()}`,
59
59
  `excludedFns:${JSON.stringify((aotOptions?.excludedFns || []).slice().sort())}`,
60
- `excludedPureFns:${JSON.stringify((aotOptions?.excludedPureFns || []).slice().sort())}`
60
+ `excludedPureFns:${JSON.stringify((aotOptions?.excludedPureFns || []).slice().sort())}`,
61
+ `isClient:${!!aotOptions?.isClient}`
61
62
  ].join("\n");
62
63
  return crypto.createHash("sha256").update(hashInput).digest("hex");
63
64
  }
@@ -114,7 +115,7 @@ async function getOrGenerateAOTCaches(serverConfig, aotOptions, cacheDir) {
114
115
  };
115
116
  }
116
117
  }
117
- const result = await src_vitePlugin_aotCacheGenerator.generateAOTCaches(serverConfig);
118
+ const result = await src_vitePlugin_aotCacheGenerator.generateAOTCaches(serverConfig, void 0, aotOptions?.isClient);
118
119
  if (cachingEnabled) {
119
120
  if (!hash) hash = computeSourceHash(serverConfig, aotOptions);
120
121
  writeDiskCache(cacheDir, hash, result.data);
@@ -1 +1 @@
1
- {"version":3,"file":"aotDiskCache.cjs","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":["resolve","dirname","readFileSync","readdirSync","join","statSync","relative","createHash","mkdirSync","writeFileSync","generateAOTCaches"],"mappings":";;;;;;;AAuBA,MAAM,yBAAyB;AAG/B,MAAM,iBAAiB;AAGvB,MAAM,YAAY,oBAAI,IAAI,CAAC,gBAAgB,SAAS,QAAQ,QAAQ,SAAS,SAAS,YAAY,WAAW,CAAC;AAG9G,MAAM,oBAAoB;AAG1B,MAAM,oBAAoB;AAG1B,IAAI,kBAAiC;AACrC,SAAS,qBAA6B;AAClC,MAAI,gBAAiB,QAAO;AAC5B,MAAI;AACA,UAAM,UAAUA,KAAAA,QAAQC,aAAQ,IAAI,6QAAmB,EAAE,QAAQ,GAAG,oBAAoB;AACxF,UAAM,MAAM,KAAK,MAAMC,GAAAA,aAAa,SAAS,OAAO,CAAC;AACrD,sBAAkB,IAAI,WAAW;AAAA,EACrC,QAAQ;AACJ,sBAAkB;AAAA,EACtB;AACA,SAAO;AACX;AAGA,SAAS,iBAAiB,KAAa,SAA2B;AAC9D,QAAM,UAAoB,CAAA;AAC1B,MAAI;AACJ,MAAI;AACA,YAAQC,GAAAA,YAAY,GAAG;AAAA,EAC3B,QAAQ;AACJ,WAAO;AAAA,EACX;AACA,aAAW,QAAQ,OAAO;AACtB,UAAM,WAAWC,KAAAA,KAAK,KAAK,IAAI;AAC/B,QAAI;AACJ,QAAI;AACA,aAAOC,GAAAA,SAAS,QAAQ;AAAA,IAC5B,QAAQ;AACJ;AAAA,IACJ;AACA,QAAI,KAAK,eAAe;AACpB,UAAI,UAAU,IAAI,IAAI,EAAG;AACzB,cAAQ,KAAK,GAAG,iBAAiB,UAAU,OAAO,CAAC;AAAA,IACvD,WAAW,kBAAkB,KAAK,IAAI,KAAK,CAAC,kBAAkB,KAAK,IAAI,GAAG;AACtE,YAAM,eAAeC,KAAAA,SAAS,SAAS,QAAQ;AAC/C,cAAQ,KAAK,GAAG,YAAY,IAAI,KAAK,OAAO,IAAI,KAAK,IAAI,EAAE;AAAA,IAC/D;AAAA,EACJ;AACA,SAAO;AACX;AAGO,SAAS,kBAAkB,cAAgC,YAAsC;AACpG,QAAM,YAAYL,KAAAA,QAAQD,KAAAA,QAAQ,aAAa,WAAW,CAAC;AAC3D,QAAM,YAAY,iBAAiB,WAAW,SAAS;AACvD,YAAU,KAAA;AAEV,QAAM,YAAY;AAAA,IACd,GAAG;AAAA,IACH,gBAAgB,sBAAsB;AAAA,IACtC,mBAAmB,oBAAoB;AAAA,IACvC,eAAe,KAAK,WAAW,YAAY,eAAe,CAAA,GAAI,MAAA,EAAQ,KAAA,CAAM,CAAC;AAAA,IAC7E,mBAAmB,KAAK,WAAW,YAAY,mBAAmB,CAAA,GAAI,MAAA,EAAQ,KAAA,CAAM,CAAC;AAAA,EAAA,EACvF,KAAK,IAAI;AAEX,SAAOO,OAAAA,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO,KAAK;AAC9D;AAGA,SAAS,cAAc,UAA2C;AAC9D,QAAM,YAAYH,KAAAA,KAAK,UAAU,cAAc;AAC/C,MAAI;AACA,UAAM,MAAMF,GAAAA,aAAa,WAAW,OAAO;AAC3C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QACI,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,gBAAgB,YAC9B,OAAO,OAAO,oBAAoB,UACpC;AACE,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAGA,SAAS,eAAe,UAAkB,MAAc,MAA0B;AAC9E,QAAM,YAAYE,KAAAA,KAAK,UAAU,cAAc;AAC/C,MAAI;AACAI,OAAAA,UAAU,UAAU,EAAC,WAAW,KAAA,CAAK;AACrC,UAAM,YAA8B;AAAA,MAChC,cAAc;AAAA,MACd;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,aAAa,KAAK;AAAA,MAClB,iBAAiB,KAAK;AAAA,IAAA;AAE1BC,OAAAA,cAAc,WAAW,KAAK,UAAU,SAAS,GAAG,OAAO;AAAA,EAC/D,SAAS,KAAK;AACV,YAAQ,KAAK,mDAAmD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,EACtH;AACJ;AAGO,SAAS,gBAAgB,SAA0B,cAA+B;AACrF,MAAI,QAAQ,UAAU,MAAO,QAAO;AACpC,MAAI,OAAO,QAAQ,UAAU,SAAU,QAAOT,KAAAA,QAAQ,QAAQ,KAAK;AACnE,SAAO,gBAAgBA,KAAAA,QAAQ,QAAQ,IAAA,GAAO,oBAAoB;AACtE;AAGA,eAAsB,uBAClB,cACA,YACA,UACuB;AACvB,QAAM,kBAAkB,QAAQ,IAAI,mBAAmB;AAEvD,QAAM,YAAY,aAAa,YAAY;AAC3C,QAAM,iBAAiB,aAAa,MAAM,CAAC,mBAAmB,CAAC;AAE/D,MAAI,OAAO;AACX,MAAI,gBAAgB;AAChB,WAAO,kBAAkB,cAAc,UAAU;AACjD,UAAM,SAAS,cAAc,QAAQ;AACrC,QAAI,UAAU,OAAO,iBAAiB,0BAA0B,OAAO,SAAS,MAAM;AAClF,cAAQ,IAAI,6DAA6D;AACzE,aAAO;AAAA,QACH,MAAM;AAAA,UACF,YAAY,OAAO;AAAA,UACnB,aAAa,OAAO;AAAA,UACpB,iBAAiB,OAAO;AAAA,QAAA;AAAA,MAC5B;AAAA,IAER;AAAA,EACJ;AAGA,QAAM,SAAS,MAAMU,iCAAAA,kBAAkB,YAAY;AAEnD,MAAI,gBAAgB;AAChB,QAAI,CAAC,KAAM,QAAO,kBAAkB,cAAc,UAAU;AAC5D,mBAAe,UAAU,MAAM,OAAO,IAAI;AAC1C,YAAQ,IAAI,uCAAuC;AAAA,EACvD;AAEA,SAAO;AACX;AAGO,SAAS,gBACZ,cACA,YACA,MACA,UACI;AACJ,MAAI,CAAC,YAAY,YAAY,UAAU,MAAO;AAC9C,QAAM,OAAO,kBAAkB,cAAc,UAAU;AACvD,iBAAe,UAAU,MAAM,IAAI;AACvC;;;;;"}
1
+ {"version":3,"file":"aotDiskCache.cjs","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 `isClient:${!!aotOptions?.isClient}`,\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, undefined, aotOptions?.isClient);\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":["resolve","dirname","readFileSync","readdirSync","join","statSync","relative","createHash","mkdirSync","writeFileSync","generateAOTCaches"],"mappings":"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"}
@@ -145,7 +145,7 @@ function mionVitePlugin(options) {
145
145
  let basePath = null;
146
146
  let initFailed = false;
147
147
  console.log("[mion] Generating SSR AOT caches...");
148
- ssrInitPromise = src_vitePlugin_aotCacheGenerator.loadSSRRouterAndGenerateAOTCaches(ssrLoadModule, startScript).then(async (data) => {
148
+ ssrInitPromise = src_vitePlugin_aotCacheGenerator.loadSSRRouterAndGenerateAOTCaches(ssrLoadModule, startScript, aotOptions?.isClient).then(async (data) => {
149
149
  aotData = data;
150
150
  aotGenerationPromise = Promise.resolve(data);
151
151
  console.log("[mion] SSR AOT caches generated successfully");
@@ -256,6 +256,8 @@ function mionVitePlugin(options) {
256
256
  transform(code, fileName) {
257
257
  const vueInfo = parseVueModuleId(fileName);
258
258
  const basePath = fileName.includes("?") ? fileName.slice(0, fileName.indexOf("?")) : fileName;
259
+ if (basePath.includes("@mionjs/") && (basePath.includes("/.dist/") || basePath.includes("/build/"))) return null;
260
+ if (basePath.includes("/.cache/vite/") || basePath.includes("/.vite/deps/")) return null;
259
261
  const filterPath = vueInfo ? vueInfo.basePath : basePath;
260
262
  if (basePath.endsWith(".vue") && !vueInfo) return null;
261
263
  const lang = vueInfo?.lang || "ts";
@@ -270,8 +272,12 @@ function mionVitePlugin(options) {
270
272
  if (hasPureFns) {
271
273
  before.push(src_vitePlugin_transformers.createPureFnTransformerFactory(code, tsFileName, collected, pureFnOptions?.noViteClient));
272
274
  }
273
- if (deepkitConfig) after.push(...deepkitConfig.afterTransformers);
274
- if (needsDeepkit) before.push(...deepkitConfig.beforeTransformers);
275
+ if (needsDeepkit) {
276
+ before.push(...deepkitConfig.beforeTransformers);
277
+ }
278
+ if (deepkitConfig) {
279
+ after.push(...deepkitConfig.afterTransformers);
280
+ }
275
281
  const baseCompilerOptions = deepkitConfig?.compilerOptions ?? defaultCompilerOptions;
276
282
  const compilerOptions = isTsx ? { ...baseCompilerOptions, jsx: ts__namespace.JsxEmit.ReactJSX } : baseCompilerOptions;
277
283
  const result = ts__namespace.transpileModule(code, {
@@ -327,11 +333,15 @@ function mionVitePlugin(options) {
327
333
  (async () => {
328
334
  const routerModule = await ssrLoadModule("@mionjs/router");
329
335
  routerModule.resetRouter();
330
- return src_vitePlugin_aotCacheGenerator.loadSSRRouterAndGenerateAOTCaches(ssrLoadModule, path.resolve(serverConfig.startScript));
336
+ return src_vitePlugin_aotCacheGenerator.loadSSRRouterAndGenerateAOTCaches(
337
+ ssrLoadModule,
338
+ path.resolve(serverConfig.startScript),
339
+ aotOptions?.isClient
340
+ );
331
341
  })()
332
342
  ) : (
333
343
  // IPC mode: wait for old child to die, then spawn new
334
- killPromise.then(() => src_vitePlugin_aotCacheGenerator.generateAOTCaches(serverConfig))
344
+ killPromise.then(() => src_vitePlugin_aotCacheGenerator.generateAOTCaches(serverConfig, void 0, aotOptions?.isClient))
335
345
  );
336
346
  aotGenerationPromise = regeneratePromise.then((r) => "data" in r ? r.data : r);
337
347
  regeneratePromise.then((result) => {
@@ -1 +1 @@
1
- {"version":3,"file":"mionVitePlugin.cjs","sources":["../../../../../src/vite-plugin/mionVitePlugin.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 {resolve} from 'path';\nimport {createRequire} from 'module';\nimport {existsSync} from 'fs';\nimport * as ts from 'typescript';\nimport {ChildProcess} from 'child_process';\nimport {createDeepkitConfig, DeepkitConfig, createPureFnTransformerFactory} from './transformers.ts';\nimport {ServerPureFunctionsOptions, ExtractedPureFn, DeepkitTypeOptions, AOTCacheOptions, MionServerConfig} from './types.ts';\nimport {scanClientSource} from './extractPureFn.ts';\nimport {generateServerPureFnsVirtualModule} from './virtualModule.ts';\nimport {\n VIRTUAL_SERVER_PURE_FNS,\n REFLECTION_MODULES,\n VIRTUAL_STUB_PREFIX,\n VIRTUAL_AOT_CACHES,\n AOT_CACHES_SHIM,\n SERVER_PURE_FNS_SHIM,\n resolveVirtualId,\n} from './constants.ts';\nimport {\n generateAOTCaches,\n loadSSRRouterAndGenerateAOTCaches,\n killPersistentChild,\n logAOTCaches,\n generateJitFnsModule,\n generatePureFnsModule,\n generateRouterCacheModule,\n generateCombinedCachesModule,\n generateNoopModule,\n generateNoopCombinedModule,\n AOTCacheData,\n} from './aotCacheGenerator.ts';\nimport {getOrGenerateAOTCaches, updateDiskCache, resolveCacheDir} from './aotDiskCache.ts';\n\nexport interface MionPluginOptions {\n /** Options for pure function extraction - omit to disable */\n serverPureFunctions?: ServerPureFunctionsOptions;\n /** Options for deepkit type transformation - omit to disable */\n runTypes?: DeepkitTypeOptions;\n /** Options for AOT cache generation - omit to disable */\n aotCaches?: AOTCacheOptions | true;\n /** Server configuration - controls how the server process is managed */\n server?: MionServerConfig;\n}\n\n/**\n * Creates the unified mion Vite plugin.\n * This plugin combines pure function extraction, type compiler transformations,\n * and AOT cache generation in a single plugin with correct execution order.\n *\n * Execution order:\n * 1. Extract pure functions from original TypeScript source\n * 2. Apply type metadata transformations to the code\n *\n * This ensures pure function extraction happens on clean, untransformed TypeScript.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import {mionPlugin} from '@mionjs/devtools/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * mionPlugin({\n * runTypes: {\n * tsConfig: './tsconfig.json',\n * },\n * server: {\n * startScript: '../server/src/init.ts',\n * runMode: 'buildOnly',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function mionVitePlugin(options: MionPluginOptions) {\n let extractedFns: ExtractedPureFn[] | null = null;\n const pureFnOptions = options.serverPureFunctions;\n const runTypesOptions = options.runTypes;\n const aotOptions: AOTCacheOptions | undefined = options.aotCaches === true ? {} : options.aotCaches;\n const serverConfig = options.server;\n const deepkitConfig: DeepkitConfig | null = runTypesOptions ? createDeepkitConfig(runTypesOptions) : null;\n\n // Default compiler options for when deepkit is disabled\n const defaultCompilerOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n sourceMap: true,\n };\n\n // Pure function injection counters — accumulated during transform, logged in buildEnd\n let pureServerFnCount = 0;\n let registerPureFnFactoryCount = 0;\n let pureFnFilesCount = 0;\n\n // AOT cache data - populated during buildStart (IPC) or configureServer (in-process)\n let aotData: AOTCacheData | null = null;\n let aotGenerationPromise: Promise<AOTCacheData> | null = null;\n\n // Resolved cache directory from Vite's config — set in configResolved\n let aotCacheDir = '';\n\n // SSR AOT: module loader (set in configureServer when SSR mode is active)\n let ssrLoadModule: ((url: string) => Promise<Record<string, any>>) | null = null;\n /** Whether SSR mode is active — resolved from server config */\n const ssrEnabled = serverConfig?.runMode === 'middleware';\n /** SSR init promise: AOT generation + router/platform module loading */\n let ssrInitPromise: Promise<void> | null = null;\n\n // Persistent child process for IPC mode\n let persistentChild: ChildProcess | null = null;\n let cleanupRegistered = false;\n\n const {aotVirtualModules, aotResolvedIds} = buildAOTVirtualModuleMaps(aotOptions?.customVirtualModuleId);\n\n /** Kill persistent child process and clear reference */\n async function cleanupChild() {\n if (persistentChild) {\n await killPersistentChild(persistentChild);\n persistentChild = null;\n }\n }\n\n /** Register process exit handlers (once) */\n function registerCleanupHandlers() {\n if (cleanupRegistered) return;\n cleanupRegistered = true;\n const onExit = () => {\n if (persistentChild && !persistentChild.killed) {\n persistentChild.kill('SIGTERM');\n persistentChild = null;\n }\n };\n process.on('exit', onExit);\n process.on('SIGINT', onExit);\n process.on('SIGTERM', onExit);\n }\n\n return {\n name: 'mion',\n enforce: 'pre' as const, // literal type required: inferred 'string' is not assignable to Vite's 'pre' | 'post'\n\n config(config, env) {\n // Strip reflection module aliases in bundle build mode so our resolveId can stub them.\n // Vite's alias plugin runs before our resolveId, so we remove aliases here to prevent\n // them from transforming bare package names into file paths before we can intercept.\n if (aotOptions?.excludeReflection && !isRunningAsChild()) {\n const aliases = config.resolve?.alias;\n if (aliases && !Array.isArray(aliases)) {\n for (const mod of REFLECTION_MODULES) {\n delete (aliases as Record<string, string>)[mod];\n }\n }\n }\n\n // Ensure Vite bundles shim modules instead of externalizing them\n const shimModules: string[] = [];\n if (pureFnOptions) shimModules.push(SERVER_PURE_FNS_SHIM);\n if (aotOptions) shimModules.push(AOT_CACHES_SHIM);\n addSsrNoExternal(config, shimModules);\n\n // Wrap build.rollupOptions.external so shim and virtual modules are never externalized\n if (env.command === 'build' && shimModules.length > 0) {\n wrapBuildExternal(config, shimModules);\n }\n },\n\n configResolved(config) {\n if (aotOptions) {\n aotCacheDir = resolveCacheDir(aotOptions, config.cacheDir);\n }\n },\n\n async buildStart() {\n // Generate AOT caches if server is configured\n // Skip when already running as a child process to prevent infinite recursion\n // Skip when SSR mode — configureServer will handle it\n if (serverConfig && !isRunningAsChild() && !ssrEnabled) {\n try {\n console.log('[mion] Generating AOT caches...');\n const resultPromise = getOrGenerateAOTCaches(serverConfig, aotOptions, aotCacheDir);\n aotGenerationPromise = resultPromise.then((r) => r.data);\n const result = await resultPromise;\n aotData = result.data;\n console.log('[mion] AOT caches generated successfully');\n logAOTCaches(aotData);\n\n // Store persistent child for IPC mode\n if (result.childProcess) {\n persistentChild = result.childProcess;\n registerCleanupHandlers();\n console.log(`[mion] Server process persisted (pid: ${persistentChild.pid})`);\n }\n\n // Non-blocking: wait for setPlatformConfig() IPC and resolve serverReady promise\n if (result.platformReady && serverConfig.waitTimeout && serverConfig.runMode === 'childProcess') {\n console.log('[mion] Waiting for server to call setPlatformConfig()...');\n const timeout = serverConfig.waitTimeout;\n const timeoutId = setTimeout(() => {\n if (result.childProcess?.connected) result.childProcess.disconnect();\n console.error(\n `[mion] Server did not call setPlatformConfig() within ${timeout / 1000}s. ` +\n `Ensure your platform adapter (startNodeServer, etc.) is called after initMionRouter().`\n );\n }, timeout);\n result.platformReady.then(() => {\n clearTimeout(timeoutId);\n if (result.childProcess?.connected) result.childProcess.disconnect();\n console.log('[mion] Server ready');\n onServerReady();\n });\n } else {\n // buildOnly mode or no waitTimeout: resolve immediately\n if (result.childProcess?.connected) result.childProcess.disconnect();\n onServerReady();\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`[mion] Failed to generate AOT caches: ${message}`);\n }\n }\n },\n\n configureServer(server) {\n if (!ssrEnabled || !serverConfig) return;\n // SSR mode: use ssrLoadModule to load the server in the same Vite process.\n // ssrLoadModule uses Vite's internal transform pipeline (not HTTP),\n ssrLoadModule = (url: string) => server.ssrLoadModule(url);\n const startScript = resolve(serverConfig.startScript);\n // Single init chain: generate AOT caches → load router + platform modules\n let nodeRequestHandler: ((req: any, res: any) => void) | null = null;\n let basePath: string | null = null;\n let initFailed = false;\n\n console.log('[mion] Generating SSR AOT caches...');\n ssrInitPromise = loadSSRRouterAndGenerateAOTCaches(ssrLoadModule, startScript)\n .then(async (data) => {\n aotData = data;\n aotGenerationPromise = Promise.resolve(data);\n console.log('[mion] SSR AOT caches generated successfully');\n logAOTCaches(data);\n // Invalidate virtual modules so they reload with real data\n for (const resolvedId of aotResolvedIds.keys()) {\n const mod = server.moduleGraph.getModuleById(resolvedId);\n if (mod) server.moduleGraph.invalidateModule(mod);\n }\n // Load router and platform modules now that caches are ready\n const routerModule = await server.ssrLoadModule('@mionjs/router');\n const opts = routerModule.getRouterOptions();\n basePath = '/' + (opts.basePath || '').replace(/^\\//, '');\n const platformNode = await server.ssrLoadModule('@mionjs/platform-node');\n nodeRequestHandler = platformNode.httpRequestHandler;\n console.log('[mion] Dev server proxy initialized');\n onServerReady();\n })\n .catch((err) => {\n initFailed = true;\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[mion] Failed to initialize SSR: ${message}`);\n });\n\n // Dev server proxy: route matching requests to mion's httpRequestHandler\n server.middlewares.use(async (req: any, res: any, next: () => void) => {\n try {\n if (!basePath && !initFailed) await ssrInitPromise;\n if (!basePath || !req.url?.startsWith(basePath)) return next();\n if (nodeRequestHandler) {\n nodeRequestHandler(req, res);\n } else {\n res.statusCode = 503;\n res.end('mion API failed to initialize');\n }\n } catch (err) {\n console.error('[mion] Dev server proxy error:', err);\n if (!res.writableEnded) {\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n }\n });\n },\n\n resolveId(id, importer) {\n // Pure functions virtual module — always resolve, returns empty cache if not configured\n if (id === VIRTUAL_SERVER_PURE_FNS) return resolveVirtualId(id);\n // AOT virtual modules (default + custom prefix both resolve)\n if (aotVirtualModules.has(id)) return resolveVirtualId(id);\n // Resolve shim modules: intercept empty cache imports and replace with virtual modules\n if (aotOptions) {\n const resolved = resolveShimModule(\n id,\n importer,\n AOT_CACHES_SHIM,\n VIRTUAL_AOT_CACHES,\n 'aot-caches',\n 'aotCaches.ts',\n 'emptyCaches.ts'\n );\n if (resolved) return resolved;\n }\n if (pureFnOptions) {\n const resolved = resolveShimModule(\n id,\n importer,\n SERVER_PURE_FNS_SHIM,\n VIRTUAL_SERVER_PURE_FNS,\n 'server-pure-fns',\n 'serverPureFnsCaches.ts',\n 'emptyServerPureFns.ts'\n );\n if (resolved) return resolved;\n }\n // Stub out reflection modules in the bundle build (not needed at runtime in AOT mode)\n if (aotOptions?.excludeReflection && !isRunningAsChild() && REFLECTION_MODULES.includes(id)) {\n return resolveVirtualId(VIRTUAL_STUB_PREFIX + id);\n }\n return null;\n },\n\n async load(id) {\n // Pure functions virtual module\n if (id === resolveVirtualId(VIRTUAL_SERVER_PURE_FNS)) {\n // No serverPureFunctions configured — return empty cache\n if (!pureFnOptions) return generateServerPureFnsVirtualModule([]);\n // Lazily scan client source on first load\n if (!extractedFns) extractedFns = scanClientSource(pureFnOptions);\n return generateServerPureFnsVirtualModule(extractedFns);\n }\n\n // AOT virtual modules — check resolved ID against the map\n const aotType = aotResolvedIds.get(id);\n if (aotType) {\n const initPromise = ssrInitPromise || aotGenerationPromise;\n if (!aotData && initPromise) await initPromise;\n\n switch (aotType) {\n case 'jit-fns': {\n if (!aotData) return generateNoopModule('No-op: AOT JIT caches not generated');\n return generateJitFnsModule(aotData.jitFnsCode);\n }\n case 'pure-fns': {\n if (!aotData) return generateNoopModule('No-op: AOT pure fns not generated');\n return generatePureFnsModule(aotData.pureFnsCode);\n }\n case 'router-cache': {\n if (!aotData) return generateNoopModule('No-op: AOT router cache not generated');\n return generateRouterCacheModule(aotData.routerCacheCode);\n }\n case 'caches': {\n if (!aotData) return generateNoopCombinedModule();\n return generateCombinedCachesModule();\n }\n }\n }\n\n // Reflection module stubs (empty modules — all reflection is pre-compiled in AOT caches)\n // syntheticNamedExports tells Rollup to derive named exports from the default export,\n // so any `import {foo} from '...'` resolves to undefined without build errors.\n for (const mod of REFLECTION_MODULES) {\n if (id === resolveVirtualId(VIRTUAL_STUB_PREFIX + mod)) {\n return {code: 'export default {}', syntheticNamedExports: true};\n }\n }\n\n return null;\n },\n\n transform(code: string, fileName: string) {\n // For Vue SFC virtual modules, resolve the base path and lang for downstream tools\n const vueInfo = parseVueModuleId(fileName);\n // Strip any query params (e.g. ?macro=true from Nuxt) to get the real file path\n const basePath = fileName.includes('?') ? fileName.slice(0, fileName.indexOf('?')) : fileName;\n const filterPath = vueInfo ? vueInfo.basePath : basePath;\n\n // Skip .vue files unless they are Vue script virtual modules (?vue&type=script).\n // Bare .vue files and other .vue queries (e.g. ?macro=true from Nuxt) contain raw\n // SFC content — wait for the Vue plugin to extract the <script> block first.\n if (basePath.endsWith('.vue') && !vueInfo) return null;\n\n const lang = vueInfo?.lang || 'ts';\n const tsFileName = vueInfo ? `${vueInfo.basePath}.${lang}` : fileName;\n const isTsx = tsFileName.endsWith('.tsx') || tsFileName.endsWith('.jsx');\n\n const hasPureFns =\n code.includes('pureServerFn') || code.includes('registerPureFnFactory') || code.includes('mapFrom');\n const needsDeepkit = deepkitConfig ? deepkitConfig.filter(filterPath) : false;\n\n if (!hasPureFns && !needsDeepkit) return null;\n\n const before: ts.CustomTransformerFactory[] = [];\n const after: ts.CustomTransformerFactory[] = [];\n\n // Pure function transformer (runs first — sees clean AST)\n const collected: ExtractedPureFn[] | undefined = hasPureFns ? [] : undefined;\n if (hasPureFns) {\n before.push(createPureFnTransformerFactory(code, tsFileName, collected, pureFnOptions?.noViteClient));\n }\n\n // Deepkit has two functions: type metadata emission (follows include/exclude filters)\n // and import restoration (always runs globally for all ts.transpileModule calls).\n // afterTransformers (including requireToImport) must always be included to convert\n // deepkit's CJS require() back to ESM imports in the restored import statements.\n if (deepkitConfig) after.push(...deepkitConfig.afterTransformers);\n if (needsDeepkit) before.push(...deepkitConfig!.beforeTransformers);\n\n const baseCompilerOptions = deepkitConfig?.compilerOptions ?? defaultCompilerOptions;\n const compilerOptions = isTsx ? {...baseCompilerOptions, jsx: ts.JsxEmit.ReactJSX} : baseCompilerOptions;\n\n const result = ts.transpileModule(code, {\n compilerOptions,\n fileName: tsFileName,\n transformers: {before, after},\n });\n\n // Count injected pure functions (collector is populated synchronously by transpileModule)\n if (collected && collected.length > 0) {\n pureFnFilesCount++;\n for (const fn of collected) {\n if (fn.isFactory) registerPureFnFactoryCount++;\n else pureServerFnCount++;\n }\n }\n\n // Strip the //# sourceMappingURL comment that ts.transpileModule appends —\n // Vite consumes the source map via the `map` property, not inline comments.\n const outputCode = result.outputText.replace(/\\n\\/\\/# sourceMappingURL=.*$/, '');\n return {code: outputCode, map: result.sourceMapText};\n },\n\n buildEnd() {\n if (pureServerFnCount > 0 || registerPureFnFactoryCount > 0) {\n const total = pureServerFnCount + registerPureFnFactoryCount;\n const parts = [\n pureServerFnCount > 0 ? `${pureServerFnCount} pureServerFn` : '',\n registerPureFnFactoryCount > 0 ? `${registerPureFnFactoryCount} registerPureFnFactory` : '',\n ].filter(Boolean);\n console.log(`[mion] Injected ${total} pure functions across ${pureFnFilesCount} files (${parts.join(', ')})`);\n }\n },\n\n async closeBundle() {\n await cleanupChild();\n },\n\n handleHotUpdate({file, server}) {\n // In dev mode, re-scan when client source changes (for pure functions)\n if (pureFnOptions) {\n const clientSrcPath = resolve(pureFnOptions.clientSrcPath);\n if (file.startsWith(clientSrcPath)) {\n const include = pureFnOptions.include || ['**/*.ts', '**/*.tsx', '**/*.vue'];\n const exclude = pureFnOptions.exclude || ['../node_modules/**', '**/.dist/**', '**/dist/**'];\n if (isIncluded(file, include, exclude)) {\n // Clear cache and invalidate virtual module\n extractedFns = null;\n const mod = server.moduleGraph.getModuleById(resolveVirtualId(VIRTUAL_SERVER_PURE_FNS));\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n return [mod];\n }\n }\n }\n }\n\n // In dev mode, regenerate AOT caches when server source changes\n // Skip when running as a child process\n if (serverConfig && !isRunningAsChild()) {\n const serverDir = resolve(serverConfig.startScript, '..');\n\n if (file.startsWith(serverDir)) {\n // Kill existing persistent child before regenerating\n const killPromise = cleanupChild();\n\n const regeneratePromise =\n ssrEnabled && ssrLoadModule\n ? // SSR mode: reset router and re-init via ssrLoadModule\n (async () => {\n const routerModule = await ssrLoadModule!('@mionjs/router');\n routerModule.resetRouter();\n return loadSSRRouterAndGenerateAOTCaches(ssrLoadModule!, resolve(serverConfig.startScript));\n })()\n : // IPC mode: wait for old child to die, then spawn new\n killPromise.then(() => generateAOTCaches(serverConfig));\n\n aotGenerationPromise = regeneratePromise.then((r) => ('data' in r ? r.data : r));\n regeneratePromise\n .then((result) => {\n const data = 'data' in result ? result.data : result;\n aotData = data;\n logAOTCaches(data);\n\n // Store new persistent child if IPC mode\n if ('childProcess' in result && result.childProcess) {\n persistentChild = result.childProcess;\n console.log(`[mion] Server process re-persisted (pid: ${persistentChild!.pid})`);\n }\n\n // Non-blocking: wait for setPlatformConfig() IPC from restarted server\n const platformReady = 'platformReady' in result ? result.platformReady : undefined;\n if (platformReady && serverConfig.waitTimeout && serverConfig.runMode === 'childProcess') {\n const timeout = serverConfig.waitTimeout;\n console.log('[mion] Waiting for restarted server to call setPlatformConfig()...');\n const timeoutId = setTimeout(() => {\n if (persistentChild?.connected) persistentChild.disconnect();\n console.error(\n `[mion] Restarted server did not call setPlatformConfig() within ${timeout / 1000}s.`\n );\n }, timeout);\n platformReady.then(() => {\n clearTimeout(timeoutId);\n if (persistentChild?.connected) persistentChild.disconnect();\n console.log('[mion] Restarted server ready');\n onServerReady();\n });\n } else if ('childProcess' in result && result.childProcess?.connected) {\n result.childProcess.disconnect();\n }\n\n if (!ssrEnabled) updateDiskCache(serverConfig, aotOptions, data, aotCacheDir);\n // Invalidate all AOT virtual modules\n let invalidatedCount = 0;\n for (const resolvedId of aotResolvedIds.keys()) {\n const mod = server.moduleGraph.getModuleById(resolvedId);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n invalidatedCount++;\n }\n }\n if (invalidatedCount > 0) {\n console.log('[mion] AOT caches regenerated, invalidating virtual modules');\n }\n })\n .catch((err) => {\n console.error('[mion] Failed to regenerate AOT caches:', err.message);\n });\n }\n }\n\n return undefined;\n },\n };\n}\n\n/** Whether the current process is a child spawned by the mion plugin */\nfunction isRunningAsChild(): boolean {\n return process.env.MION_COMPILE === 'buildOnly' || process.env.MION_COMPILE === 'childProcess';\n}\n\n/** Extracts the base file path and lang from a Vue SFC virtual module ID (e.g. Component.vue?vue&type=script&lang=ts) */\nexport function parseVueModuleId(id: string): {basePath: string; lang: string | null} | null {\n const qIdx = id.indexOf('?');\n if (qIdx === -1) return null;\n const basePath = id.slice(0, qIdx);\n if (!basePath.endsWith('.vue')) return null;\n const params = new URLSearchParams(id.slice(qIdx));\n if (!params.has('vue') || params.get('type') !== 'script') return null;\n return {basePath, lang: params.get('lang')};\n}\n\n/** Checks if a file path matches the include/exclude patterns */\nexport function isIncluded(filePath: string, include: string[], exclude: string[]): boolean {\n // For Vue virtual module IDs, use the base .vue path for matching\n const vueInfo = parseVueModuleId(filePath);\n const effectivePath = vueInfo ? vueInfo.basePath : filePath;\n\n const isTs = /\\.(ts|tsx|js|jsx)$/.test(effectivePath);\n const isVue = effectivePath.endsWith('.vue');\n const isDir = effectivePath.endsWith('/');\n if (!isTs && !isVue && !isDir) return false;\n\n // Check exclude patterns\n for (const pattern of exclude) {\n if (matchGlob(effectivePath, pattern)) return false;\n }\n\n return true;\n}\n\n/** Simple glob matching for common patterns */\nfunction matchGlob(filePath: string, pattern: string): boolean {\n // Handle **/ prefix\n if (pattern.startsWith('**/')) {\n const suffix = pattern.slice(3);\n return filePath.includes(suffix.replace(/\\*/g, ''));\n }\n // Handle simple wildcard\n const regex = new RegExp('^' + pattern.replace(/\\*\\*/g, '.*').replace(/\\*/g, '[^/]*') + '$');\n return regex.test(filePath);\n}\n\n/** AOT virtual module types — each maps to a different cache export */\nconst AOT_MODULE_TYPES = ['jit-fns', 'pure-fns', 'router-cache', 'caches'] as const;\ntype AOTModuleType = (typeof AOT_MODULE_TYPES)[number];\n\n/** Builds maps from virtual module names → AOT type for resolveId and load hooks.\n * Default 'virtual:mion-aot/*' is always registered. If customVirtualModuleId is set,\n * 'virtual:${custom}/*' is also registered — both map to the same cache data. */\nfunction buildAOTVirtualModuleMaps(customVirtualModuleId?: string) {\n const aotVirtualModules = new Map<string, AOTModuleType>();\n const aotResolvedIds = new Map<string, AOTModuleType>();\n for (const type of AOT_MODULE_TYPES) {\n const defaultId = `virtual:mion-aot/${type}`;\n aotVirtualModules.set(defaultId, type);\n aotResolvedIds.set(resolveVirtualId(defaultId), type);\n if (customVirtualModuleId) {\n const customId = `virtual:${customVirtualModuleId}/${type}`;\n aotVirtualModules.set(customId, type);\n aotResolvedIds.set(resolveVirtualId(customId), type);\n }\n }\n return {aotVirtualModules, aotResolvedIds};\n}\n\n/**\n * Resolves a shim module (e.g. @mionjs/core/aot-caches) to its source file,\n * and intercepts the empty cache import to replace it with the virtual module.\n * Returns the resolved id or null if no match.\n */\nfunction resolveShimModule(\n id: string,\n importer: string | undefined,\n shimSpecifier: string,\n virtualModuleId: string,\n entryName: string,\n sourceFileName: string,\n emptyFileName: string\n): string | null {\n // Bare specifier: resolve to the TS source file so Vite can process it through the plugin pipeline.\n // Using createRequire would return CJS built output whose require() calls bypass resolveId.\n if (id === shimSpecifier) {\n try {\n // Resolve the package directory via Node resolution, then find the source file\n const resolved = createRequire(import.meta.url).resolve(shimSpecifier);\n const sourceFile = resolve(resolved.replace(/[/\\\\].dist[/\\\\].*$/, ''), 'src/aot/' + sourceFileName);\n if (existsSync(sourceFile)) return sourceFile;\n // No source file (tarball/npm install) — resolve to virtual module directly.\n // Returning the .dist path would bypass resolveId (CJS require() calls skip Vite pipeline).\n return resolveVirtualId(virtualModuleId);\n } catch {\n return resolveVirtualId(virtualModuleId);\n }\n }\n // Alias-resolved absolute path (monorepo dev where source files always exist)\n if (id.endsWith('/' + entryName)) {\n const sourceFile = resolve(id, '..', 'src/aot/' + sourceFileName);\n if (existsSync(sourceFile)) return sourceFile;\n }\n // Intercept empty cache imports from the shim loader file (any extension)\n const emptyBase = emptyFileName.replace('.ts', '');\n const sourceBase = sourceFileName.replace('.ts', '');\n if (\n new RegExp(`${emptyBase}\\\\.(ts|js|mjs|cjs)$`).test(id) &&\n importer &&\n new RegExp(`${sourceBase}\\\\.(ts|js|mjs|cjs)$`).test(importer)\n ) {\n return resolveVirtualId(virtualModuleId);\n }\n return null;\n}\n\n/** Adds module specifiers to Vite's ssr.noExternal so they are bundled instead of externalized. */\nfunction addSsrNoExternal(config: Record<string, any>, moduleIds: string[]): void {\n if (moduleIds.length === 0) return;\n const noExternal = config.ssr?.noExternal;\n if (!config.ssr) config.ssr = {};\n if (Array.isArray(noExternal)) {\n for (const moduleId of moduleIds) {\n if (!noExternal.includes(moduleId)) noExternal.push(moduleId);\n }\n } else if (typeof noExternal === 'string') {\n config.ssr.noExternal = [noExternal, ...moduleIds];\n } else if (noExternal !== true) {\n config.ssr.noExternal = noExternal ? [noExternal, ...moduleIds] : [...moduleIds];\n }\n}\n\n/** Wraps build.rollupOptions.external so shim and virtual modules are always bundled. */\nfunction wrapBuildExternal(config: Record<string, any>, shimModules: string[]): void {\n if (!config.build) config.build = {};\n if (!config.build.rollupOptions) config.build.rollupOptions = {};\n const original = config.build.rollupOptions.external;\n if (!original) return; // no external config — nothing to wrap\n config.build.rollupOptions.external = (id: string, ...rest: any[]) => {\n // Never externalize shim modules or virtual modules (plugin replaces them with generated code)\n if (shimModules.includes(id) || id.startsWith('virtual:mion')) return false;\n // Delegate to original external config\n if (typeof original === 'function') return original(id, ...rest);\n if (Array.isArray(original)) return original.some((ext) => (ext instanceof RegExp ? ext.test(id) : ext === id));\n if (original instanceof RegExp) return original.test(id);\n return original === id;\n };\n}\n\n// #################### SERVER READY ####################\n\n// Uses globalThis with Symbol.for because vitest loads vitest.config.ts and globalSetup.ts\n// in separate module contexts — without globalThis they'd get different promise instances.\nconst READY_KEY = Symbol.for('mion.serverReady');\nfunction getOrCreateServerReady(): {promise: Promise<void>; resolve: () => void} {\n if (!(globalThis as any)[READY_KEY]) {\n let _resolve: () => void;\n (globalThis as any)[READY_KEY] = {\n promise: new Promise<void>((r) => {\n _resolve = r;\n }),\n resolve: () => _resolve(),\n };\n }\n return (globalThis as any)[READY_KEY];\n}\n\n/** Promise that resolves when the server is ready. Await this in vitest globalSetup. */\nexport const serverReady: Promise<void> = getOrCreateServerReady().promise;\nconst onServerReady: () => void = getOrCreateServerReady().resolve;\n"],"names":["createDeepkitConfig","ts","killPersistentChild","REFLECTION_MODULES","SERVER_PURE_FNS_SHIM","AOT_CACHES_SHIM","resolveCacheDir","getOrGenerateAOTCaches","logAOTCaches","resolve","loadSSRRouterAndGenerateAOTCaches","VIRTUAL_SERVER_PURE_FNS","resolveVirtualId","VIRTUAL_AOT_CACHES","VIRTUAL_STUB_PREFIX","generateServerPureFnsVirtualModule","scanClientSource","generateNoopModule","generateJitFnsModule","generatePureFnsModule","generateRouterCacheModule","generateNoopCombinedModule","generateCombinedCachesModule","createPureFnTransformerFactory","generateAOTCaches","updateDiskCache","createRequire","existsSync"],"mappings":"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"}
1
+ {"version":3,"file":"mionVitePlugin.cjs","sources":["../../../../../src/vite-plugin/mionVitePlugin.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 {resolve} from 'path';\nimport {createRequire} from 'module';\nimport {existsSync} from 'fs';\nimport * as ts from 'typescript';\nimport {ChildProcess} from 'child_process';\nimport {createDeepkitConfig, DeepkitConfig, createPureFnTransformerFactory} from './transformers.ts';\nimport {ServerPureFunctionsOptions, ExtractedPureFn, DeepkitTypeOptions, AOTCacheOptions, MionServerConfig} from './types.ts';\nimport {scanClientSource} from './extractPureFn.ts';\nimport {generateServerPureFnsVirtualModule} from './virtualModule.ts';\nimport {\n VIRTUAL_SERVER_PURE_FNS,\n REFLECTION_MODULES,\n VIRTUAL_STUB_PREFIX,\n VIRTUAL_AOT_CACHES,\n AOT_CACHES_SHIM,\n SERVER_PURE_FNS_SHIM,\n resolveVirtualId,\n} from './constants.ts';\nimport {\n generateAOTCaches,\n loadSSRRouterAndGenerateAOTCaches,\n killPersistentChild,\n logAOTCaches,\n generateJitFnsModule,\n generatePureFnsModule,\n generateRouterCacheModule,\n generateCombinedCachesModule,\n generateNoopModule,\n generateNoopCombinedModule,\n AOTCacheData,\n} from './aotCacheGenerator.ts';\nimport {getOrGenerateAOTCaches, updateDiskCache, resolveCacheDir} from './aotDiskCache.ts';\n\nexport interface MionPluginOptions {\n /** Options for pure function extraction - omit to disable */\n serverPureFunctions?: ServerPureFunctionsOptions;\n /** Options for deepkit type transformation - omit to disable */\n runTypes?: DeepkitTypeOptions;\n /** Options for AOT cache generation - omit to disable */\n aotCaches?: AOTCacheOptions | true;\n /** Server configuration - controls how the server process is managed */\n server?: MionServerConfig;\n}\n\n/**\n * Creates the unified mion Vite plugin.\n * This plugin combines pure function extraction, type compiler transformations,\n * and AOT cache generation in a single plugin with correct execution order.\n *\n * Execution order:\n * 1. Extract pure functions from original TypeScript source\n * 2. Apply type metadata transformations to the code\n *\n * This ensures pure function extraction happens on clean, untransformed TypeScript.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import {mionPlugin} from '@mionjs/devtools/vite-plugin';\n *\n * export default defineConfig({\n * plugins: [\n * mionPlugin({\n * runTypes: {\n * tsConfig: './tsconfig.json',\n * },\n * server: {\n * startScript: '../server/src/init.ts',\n * runMode: 'buildOnly',\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function mionVitePlugin(options: MionPluginOptions) {\n let extractedFns: ExtractedPureFn[] | null = null;\n const pureFnOptions = options.serverPureFunctions;\n const runTypesOptions = options.runTypes;\n const aotOptions: AOTCacheOptions | undefined = options.aotCaches === true ? {} : options.aotCaches;\n const serverConfig = options.server;\n const deepkitConfig: DeepkitConfig | null = runTypesOptions ? createDeepkitConfig(runTypesOptions) : null;\n\n // Default compiler options for when deepkit is disabled\n const defaultCompilerOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n sourceMap: true,\n };\n\n // Pure function injection counters — accumulated during transform, logged in buildEnd\n let pureServerFnCount = 0;\n let registerPureFnFactoryCount = 0;\n let pureFnFilesCount = 0;\n\n // AOT cache data - populated during buildStart (IPC) or configureServer (in-process)\n let aotData: AOTCacheData | null = null;\n let aotGenerationPromise: Promise<AOTCacheData> | null = null;\n\n // Resolved cache directory from Vite's config — set in configResolved\n let aotCacheDir = '';\n\n // SSR AOT: module loader (set in configureServer when SSR mode is active)\n let ssrLoadModule: ((url: string) => Promise<Record<string, any>>) | null = null;\n /** Whether SSR mode is active — resolved from server config */\n const ssrEnabled = serverConfig?.runMode === 'middleware';\n /** SSR init promise: AOT generation + router/platform module loading */\n let ssrInitPromise: Promise<void> | null = null;\n\n // Persistent child process for IPC mode\n let persistentChild: ChildProcess | null = null;\n let cleanupRegistered = false;\n\n const {aotVirtualModules, aotResolvedIds} = buildAOTVirtualModuleMaps(aotOptions?.customVirtualModuleId);\n\n /** Kill persistent child process and clear reference */\n async function cleanupChild() {\n if (persistentChild) {\n await killPersistentChild(persistentChild);\n persistentChild = null;\n }\n }\n\n /** Register process exit handlers (once) */\n function registerCleanupHandlers() {\n if (cleanupRegistered) return;\n cleanupRegistered = true;\n const onExit = () => {\n if (persistentChild && !persistentChild.killed) {\n persistentChild.kill('SIGTERM');\n persistentChild = null;\n }\n };\n process.on('exit', onExit);\n process.on('SIGINT', onExit);\n process.on('SIGTERM', onExit);\n }\n\n return {\n name: 'mion',\n enforce: 'pre' as const, // literal type required: inferred 'string' is not assignable to Vite's 'pre' | 'post'\n\n config(config, env) {\n // Strip reflection module aliases in bundle build mode so our resolveId can stub them.\n // Vite's alias plugin runs before our resolveId, so we remove aliases here to prevent\n // them from transforming bare package names into file paths before we can intercept.\n if (aotOptions?.excludeReflection && !isRunningAsChild()) {\n const aliases = config.resolve?.alias;\n if (aliases && !Array.isArray(aliases)) {\n for (const mod of REFLECTION_MODULES) {\n delete (aliases as Record<string, string>)[mod];\n }\n }\n }\n\n // Ensure Vite bundles shim modules instead of externalizing them\n const shimModules: string[] = [];\n if (pureFnOptions) shimModules.push(SERVER_PURE_FNS_SHIM);\n if (aotOptions) shimModules.push(AOT_CACHES_SHIM);\n addSsrNoExternal(config, shimModules);\n\n // Wrap build.rollupOptions.external so shim and virtual modules are never externalized\n if (env.command === 'build' && shimModules.length > 0) {\n wrapBuildExternal(config, shimModules);\n }\n },\n\n configResolved(config) {\n if (aotOptions) {\n aotCacheDir = resolveCacheDir(aotOptions, config.cacheDir);\n }\n },\n\n async buildStart() {\n // Generate AOT caches if server is configured\n // Skip when already running as a child process to prevent infinite recursion\n // Skip when SSR mode — configureServer will handle it\n if (serverConfig && !isRunningAsChild() && !ssrEnabled) {\n try {\n console.log('[mion] Generating AOT caches...');\n const resultPromise = getOrGenerateAOTCaches(serverConfig, aotOptions, aotCacheDir);\n aotGenerationPromise = resultPromise.then((r) => r.data);\n const result = await resultPromise;\n aotData = result.data;\n console.log('[mion] AOT caches generated successfully');\n logAOTCaches(aotData);\n\n // Store persistent child for IPC mode\n if (result.childProcess) {\n persistentChild = result.childProcess;\n registerCleanupHandlers();\n console.log(`[mion] Server process persisted (pid: ${persistentChild.pid})`);\n }\n\n // Non-blocking: wait for setPlatformConfig() IPC and resolve serverReady promise\n if (result.platformReady && serverConfig.waitTimeout && serverConfig.runMode === 'childProcess') {\n console.log('[mion] Waiting for server to call setPlatformConfig()...');\n const timeout = serverConfig.waitTimeout;\n const timeoutId = setTimeout(() => {\n if (result.childProcess?.connected) result.childProcess.disconnect();\n console.error(\n `[mion] Server did not call setPlatformConfig() within ${timeout / 1000}s. ` +\n `Ensure your platform adapter (startNodeServer, etc.) is called after initMionRouter().`\n );\n }, timeout);\n result.platformReady.then(() => {\n clearTimeout(timeoutId);\n if (result.childProcess?.connected) result.childProcess.disconnect();\n console.log('[mion] Server ready');\n onServerReady();\n });\n } else {\n // buildOnly mode or no waitTimeout: resolve immediately\n if (result.childProcess?.connected) result.childProcess.disconnect();\n onServerReady();\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`[mion] Failed to generate AOT caches: ${message}`);\n }\n }\n },\n\n configureServer(server) {\n if (!ssrEnabled || !serverConfig) return;\n // SSR mode: use ssrLoadModule to load the server in the same Vite process.\n // ssrLoadModule uses Vite's internal transform pipeline (not HTTP),\n ssrLoadModule = (url: string) => server.ssrLoadModule(url);\n const startScript = resolve(serverConfig.startScript);\n // Single init chain: generate AOT caches → load router + platform modules\n let nodeRequestHandler: ((req: any, res: any) => void) | null = null;\n let basePath: string | null = null;\n let initFailed = false;\n\n console.log('[mion] Generating SSR AOT caches...');\n ssrInitPromise = loadSSRRouterAndGenerateAOTCaches(ssrLoadModule, startScript, aotOptions?.isClient)\n .then(async (data) => {\n aotData = data;\n aotGenerationPromise = Promise.resolve(data);\n console.log('[mion] SSR AOT caches generated successfully');\n logAOTCaches(data);\n // Invalidate virtual modules so they reload with real data\n for (const resolvedId of aotResolvedIds.keys()) {\n const mod = server.moduleGraph.getModuleById(resolvedId);\n if (mod) server.moduleGraph.invalidateModule(mod);\n }\n // Load router and platform modules now that caches are ready\n const routerModule = await server.ssrLoadModule('@mionjs/router');\n const opts = routerModule.getRouterOptions();\n basePath = '/' + (opts.basePath || '').replace(/^\\//, '');\n const platformNode = await server.ssrLoadModule('@mionjs/platform-node');\n nodeRequestHandler = platformNode.httpRequestHandler;\n console.log('[mion] Dev server proxy initialized');\n onServerReady();\n })\n .catch((err) => {\n initFailed = true;\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[mion] Failed to initialize SSR: ${message}`);\n });\n\n // Dev server proxy: route matching requests to mion's httpRequestHandler\n server.middlewares.use(async (req: any, res: any, next: () => void) => {\n try {\n if (!basePath && !initFailed) await ssrInitPromise;\n if (!basePath || !req.url?.startsWith(basePath)) return next();\n if (nodeRequestHandler) {\n nodeRequestHandler(req, res);\n } else {\n res.statusCode = 503;\n res.end('mion API failed to initialize');\n }\n } catch (err) {\n console.error('[mion] Dev server proxy error:', err);\n if (!res.writableEnded) {\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n }\n });\n },\n\n resolveId(id, importer) {\n // Pure functions virtual module — always resolve, returns empty cache if not configured\n if (id === VIRTUAL_SERVER_PURE_FNS) return resolveVirtualId(id);\n // AOT virtual modules (default + custom prefix both resolve)\n if (aotVirtualModules.has(id)) return resolveVirtualId(id);\n // Resolve shim modules: intercept empty cache imports and replace with virtual modules\n if (aotOptions) {\n const resolved = resolveShimModule(\n id,\n importer,\n AOT_CACHES_SHIM,\n VIRTUAL_AOT_CACHES,\n 'aot-caches',\n 'aotCaches.ts',\n 'emptyCaches.ts'\n );\n if (resolved) return resolved;\n }\n if (pureFnOptions) {\n const resolved = resolveShimModule(\n id,\n importer,\n SERVER_PURE_FNS_SHIM,\n VIRTUAL_SERVER_PURE_FNS,\n 'server-pure-fns',\n 'serverPureFnsCaches.ts',\n 'emptyServerPureFns.ts'\n );\n if (resolved) return resolved;\n }\n // Stub out reflection modules in the bundle build (not needed at runtime in AOT mode)\n if (aotOptions?.excludeReflection && !isRunningAsChild() && REFLECTION_MODULES.includes(id)) {\n return resolveVirtualId(VIRTUAL_STUB_PREFIX + id);\n }\n return null;\n },\n\n async load(id) {\n // Pure functions virtual module\n if (id === resolveVirtualId(VIRTUAL_SERVER_PURE_FNS)) {\n // No serverPureFunctions configured — return empty cache\n if (!pureFnOptions) return generateServerPureFnsVirtualModule([]);\n // Lazily scan client source on first load\n if (!extractedFns) extractedFns = scanClientSource(pureFnOptions);\n return generateServerPureFnsVirtualModule(extractedFns);\n }\n\n // AOT virtual modules — check resolved ID against the map\n const aotType = aotResolvedIds.get(id);\n if (aotType) {\n const initPromise = ssrInitPromise || aotGenerationPromise;\n if (!aotData && initPromise) await initPromise;\n\n switch (aotType) {\n case 'jit-fns': {\n if (!aotData) return generateNoopModule('No-op: AOT JIT caches not generated');\n return generateJitFnsModule(aotData.jitFnsCode);\n }\n case 'pure-fns': {\n if (!aotData) return generateNoopModule('No-op: AOT pure fns not generated');\n return generatePureFnsModule(aotData.pureFnsCode);\n }\n case 'router-cache': {\n if (!aotData) return generateNoopModule('No-op: AOT router cache not generated');\n return generateRouterCacheModule(aotData.routerCacheCode);\n }\n case 'caches': {\n if (!aotData) return generateNoopCombinedModule();\n return generateCombinedCachesModule();\n }\n }\n }\n\n // Reflection module stubs (empty modules — all reflection is pre-compiled in AOT caches)\n // syntheticNamedExports tells Rollup to derive named exports from the default export,\n // so any `import {foo} from '...'` resolves to undefined without build errors.\n for (const mod of REFLECTION_MODULES) {\n if (id === resolveVirtualId(VIRTUAL_STUB_PREFIX + mod)) {\n return {code: 'export default {}', syntheticNamedExports: true};\n }\n }\n\n return null;\n },\n\n transform(code: string, fileName: string) {\n // For Vue SFC virtual modules, resolve the base path and lang for downstream tools\n const vueInfo = parseVueModuleId(fileName);\n // Strip any query params (e.g. ?macro=true from Nuxt) to get the real file path\n const basePath = fileName.includes('?') ? fileName.slice(0, fileName.indexOf('?')) : fileName;\n\n // Skip @mionjs build artifacts and Vite pre-bundled cache files — they already have\n // deepkit types and pure function metadata injected. Re-transpiling them through\n // ts.transpileModule would inject duplicate __assignType declarations.\n if (basePath.includes('@mionjs/') && (basePath.includes('/.dist/') || basePath.includes('/build/'))) return null;\n if (basePath.includes('/.cache/vite/') || basePath.includes('/.vite/deps/')) return null;\n\n const filterPath = vueInfo ? vueInfo.basePath : basePath;\n\n // Skip .vue files unless they are Vue script virtual modules (?vue&type=script).\n // Bare .vue files and other .vue queries (e.g. ?macro=true from Nuxt) contain raw\n // SFC content — wait for the Vue plugin to extract the <script> block first.\n if (basePath.endsWith('.vue') && !vueInfo) return null;\n\n const lang = vueInfo?.lang || 'ts';\n const tsFileName = vueInfo ? `${vueInfo.basePath}.${lang}` : fileName;\n const isTsx = tsFileName.endsWith('.tsx') || tsFileName.endsWith('.jsx');\n\n const hasPureFns =\n code.includes('pureServerFn') || code.includes('registerPureFnFactory') || code.includes('mapFrom');\n const needsDeepkit = deepkitConfig ? deepkitConfig.filter(filterPath) : false;\n\n if (!hasPureFns && !needsDeepkit) return null;\n\n const before: ts.CustomTransformerFactory[] = [];\n const after: ts.CustomTransformerFactory[] = [];\n\n // Pure function transformer (runs first — sees clean AST)\n const collected: ExtractedPureFn[] | undefined = hasPureFns ? [] : undefined;\n if (hasPureFns) {\n before.push(createPureFnTransformerFactory(code, tsFileName, collected, pureFnOptions?.noViteClient));\n }\n\n // Deepkit before-transformers emit type metadata and inject __assignType + CJS require().\n if (needsDeepkit) {\n before.push(...deepkitConfig!.beforeTransformers);\n }\n\n // After-transformers (declarationTransformer, requireToImport) must ALWAYS run when\n // deepkitConfig exists. Deepkit's install script patches typescript.js getTransformers()\n // to inject its transformer into every ts.transpileModule call — even for files outside\n // our include filter. Without requireToImport, those files end up with CJS require()\n // calls (with .ts extensions) that Rollup can't resolve, producing broken build output.\n if (deepkitConfig) {\n after.push(...deepkitConfig.afterTransformers);\n }\n\n const baseCompilerOptions = deepkitConfig?.compilerOptions ?? defaultCompilerOptions;\n const compilerOptions = isTsx ? {...baseCompilerOptions, jsx: ts.JsxEmit.ReactJSX} : baseCompilerOptions;\n\n const result = ts.transpileModule(code, {\n compilerOptions,\n fileName: tsFileName,\n transformers: {before, after},\n });\n\n // Count injected pure functions (collector is populated synchronously by transpileModule)\n if (collected && collected.length > 0) {\n pureFnFilesCount++;\n for (const fn of collected) {\n if (fn.isFactory) registerPureFnFactoryCount++;\n else pureServerFnCount++;\n }\n }\n\n // Strip the //# sourceMappingURL comment that ts.transpileModule appends —\n // Vite consumes the source map via the `map` property, not inline comments.\n const outputCode = result.outputText.replace(/\\n\\/\\/# sourceMappingURL=.*$/, '');\n return {code: outputCode, map: result.sourceMapText};\n },\n\n buildEnd() {\n if (pureServerFnCount > 0 || registerPureFnFactoryCount > 0) {\n const total = pureServerFnCount + registerPureFnFactoryCount;\n const parts = [\n pureServerFnCount > 0 ? `${pureServerFnCount} pureServerFn` : '',\n registerPureFnFactoryCount > 0 ? `${registerPureFnFactoryCount} registerPureFnFactory` : '',\n ].filter(Boolean);\n console.log(`[mion] Injected ${total} pure functions across ${pureFnFilesCount} files (${parts.join(', ')})`);\n }\n },\n\n async closeBundle() {\n await cleanupChild();\n },\n\n handleHotUpdate({file, server}) {\n // In dev mode, re-scan when client source changes (for pure functions)\n if (pureFnOptions) {\n const clientSrcPath = resolve(pureFnOptions.clientSrcPath);\n if (file.startsWith(clientSrcPath)) {\n const include = pureFnOptions.include || ['**/*.ts', '**/*.tsx', '**/*.vue'];\n const exclude = pureFnOptions.exclude || ['../node_modules/**', '**/.dist/**', '**/dist/**'];\n if (isIncluded(file, include, exclude)) {\n // Clear cache and invalidate virtual module\n extractedFns = null;\n const mod = server.moduleGraph.getModuleById(resolveVirtualId(VIRTUAL_SERVER_PURE_FNS));\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n return [mod];\n }\n }\n }\n }\n\n // In dev mode, regenerate AOT caches when server source changes\n // Skip when running as a child process\n if (serverConfig && !isRunningAsChild()) {\n const serverDir = resolve(serverConfig.startScript, '..');\n\n if (file.startsWith(serverDir)) {\n // Kill existing persistent child before regenerating\n const killPromise = cleanupChild();\n\n const regeneratePromise =\n ssrEnabled && ssrLoadModule\n ? // SSR mode: reset router and re-init via ssrLoadModule\n (async () => {\n const routerModule = await ssrLoadModule!('@mionjs/router');\n routerModule.resetRouter();\n return loadSSRRouterAndGenerateAOTCaches(\n ssrLoadModule!,\n resolve(serverConfig.startScript),\n aotOptions?.isClient\n );\n })()\n : // IPC mode: wait for old child to die, then spawn new\n killPromise.then(() => generateAOTCaches(serverConfig, undefined, aotOptions?.isClient));\n\n aotGenerationPromise = regeneratePromise.then((r) => ('data' in r ? r.data : r));\n regeneratePromise\n .then((result) => {\n const data = 'data' in result ? result.data : result;\n aotData = data;\n logAOTCaches(data);\n\n // Store new persistent child if IPC mode\n if ('childProcess' in result && result.childProcess) {\n persistentChild = result.childProcess;\n console.log(`[mion] Server process re-persisted (pid: ${persistentChild!.pid})`);\n }\n\n // Non-blocking: wait for setPlatformConfig() IPC from restarted server\n const platformReady = 'platformReady' in result ? result.platformReady : undefined;\n if (platformReady && serverConfig.waitTimeout && serverConfig.runMode === 'childProcess') {\n const timeout = serverConfig.waitTimeout;\n console.log('[mion] Waiting for restarted server to call setPlatformConfig()...');\n const timeoutId = setTimeout(() => {\n if (persistentChild?.connected) persistentChild.disconnect();\n console.error(\n `[mion] Restarted server did not call setPlatformConfig() within ${timeout / 1000}s.`\n );\n }, timeout);\n platformReady.then(() => {\n clearTimeout(timeoutId);\n if (persistentChild?.connected) persistentChild.disconnect();\n console.log('[mion] Restarted server ready');\n onServerReady();\n });\n } else if ('childProcess' in result && result.childProcess?.connected) {\n result.childProcess.disconnect();\n }\n\n if (!ssrEnabled) updateDiskCache(serverConfig, aotOptions, data, aotCacheDir);\n // Invalidate all AOT virtual modules\n let invalidatedCount = 0;\n for (const resolvedId of aotResolvedIds.keys()) {\n const mod = server.moduleGraph.getModuleById(resolvedId);\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n invalidatedCount++;\n }\n }\n if (invalidatedCount > 0) {\n console.log('[mion] AOT caches regenerated, invalidating virtual modules');\n }\n })\n .catch((err) => {\n console.error('[mion] Failed to regenerate AOT caches:', err.message);\n });\n }\n }\n\n return undefined;\n },\n };\n}\n\n/** Whether the current process is a child spawned by the mion plugin */\nfunction isRunningAsChild(): boolean {\n return process.env.MION_COMPILE === 'buildOnly' || process.env.MION_COMPILE === 'childProcess';\n}\n\n/** Extracts the base file path and lang from a Vue SFC virtual module ID (e.g. Component.vue?vue&type=script&lang=ts) */\nexport function parseVueModuleId(id: string): {basePath: string; lang: string | null} | null {\n const qIdx = id.indexOf('?');\n if (qIdx === -1) return null;\n const basePath = id.slice(0, qIdx);\n if (!basePath.endsWith('.vue')) return null;\n const params = new URLSearchParams(id.slice(qIdx));\n if (!params.has('vue') || params.get('type') !== 'script') return null;\n return {basePath, lang: params.get('lang')};\n}\n\n/** Checks if a file path matches the include/exclude patterns */\nexport function isIncluded(filePath: string, include: string[], exclude: string[]): boolean {\n // For Vue virtual module IDs, use the base .vue path for matching\n const vueInfo = parseVueModuleId(filePath);\n const effectivePath = vueInfo ? vueInfo.basePath : filePath;\n\n const isTs = /\\.(ts|tsx|js|jsx)$/.test(effectivePath);\n const isVue = effectivePath.endsWith('.vue');\n const isDir = effectivePath.endsWith('/');\n if (!isTs && !isVue && !isDir) return false;\n\n // Check exclude patterns\n for (const pattern of exclude) {\n if (matchGlob(effectivePath, pattern)) return false;\n }\n\n return true;\n}\n\n/** Simple glob matching for common patterns */\nfunction matchGlob(filePath: string, pattern: string): boolean {\n // Handle **/ prefix\n if (pattern.startsWith('**/')) {\n const suffix = pattern.slice(3);\n return filePath.includes(suffix.replace(/\\*/g, ''));\n }\n // Handle simple wildcard\n const regex = new RegExp('^' + pattern.replace(/\\*\\*/g, '.*').replace(/\\*/g, '[^/]*') + '$');\n return regex.test(filePath);\n}\n\n/** AOT virtual module types — each maps to a different cache export */\nconst AOT_MODULE_TYPES = ['jit-fns', 'pure-fns', 'router-cache', 'caches'] as const;\ntype AOTModuleType = (typeof AOT_MODULE_TYPES)[number];\n\n/** Builds maps from virtual module names → AOT type for resolveId and load hooks.\n * Default 'virtual:mion-aot/*' is always registered. If customVirtualModuleId is set,\n * 'virtual:${custom}/*' is also registered — both map to the same cache data. */\nfunction buildAOTVirtualModuleMaps(customVirtualModuleId?: string) {\n const aotVirtualModules = new Map<string, AOTModuleType>();\n const aotResolvedIds = new Map<string, AOTModuleType>();\n for (const type of AOT_MODULE_TYPES) {\n const defaultId = `virtual:mion-aot/${type}`;\n aotVirtualModules.set(defaultId, type);\n aotResolvedIds.set(resolveVirtualId(defaultId), type);\n if (customVirtualModuleId) {\n const customId = `virtual:${customVirtualModuleId}/${type}`;\n aotVirtualModules.set(customId, type);\n aotResolvedIds.set(resolveVirtualId(customId), type);\n }\n }\n return {aotVirtualModules, aotResolvedIds};\n}\n\n/**\n * Resolves a shim module (e.g. @mionjs/core/aot-caches) to its source file,\n * and intercepts the empty cache import to replace it with the virtual module.\n * Returns the resolved id or null if no match.\n */\nfunction resolveShimModule(\n id: string,\n importer: string | undefined,\n shimSpecifier: string,\n virtualModuleId: string,\n entryName: string,\n sourceFileName: string,\n emptyFileName: string\n): string | null {\n // Bare specifier: resolve to the TS source file so Vite can process it through the plugin pipeline.\n // Using createRequire would return CJS built output whose require() calls bypass resolveId.\n if (id === shimSpecifier) {\n try {\n // Resolve the package directory via Node resolution, then find the source file\n const resolved = createRequire(import.meta.url).resolve(shimSpecifier);\n const sourceFile = resolve(resolved.replace(/[/\\\\].dist[/\\\\].*$/, ''), 'src/aot/' + sourceFileName);\n if (existsSync(sourceFile)) return sourceFile;\n // No source file (tarball/npm install) — resolve to virtual module directly.\n // Returning the .dist path would bypass resolveId (CJS require() calls skip Vite pipeline).\n return resolveVirtualId(virtualModuleId);\n } catch {\n return resolveVirtualId(virtualModuleId);\n }\n }\n // Alias-resolved absolute path (monorepo dev where source files always exist)\n if (id.endsWith('/' + entryName)) {\n const sourceFile = resolve(id, '..', 'src/aot/' + sourceFileName);\n if (existsSync(sourceFile)) return sourceFile;\n }\n // Intercept empty cache imports from the shim loader file (any extension)\n const emptyBase = emptyFileName.replace('.ts', '');\n const sourceBase = sourceFileName.replace('.ts', '');\n if (\n new RegExp(`${emptyBase}\\\\.(ts|js|mjs|cjs)$`).test(id) &&\n importer &&\n new RegExp(`${sourceBase}\\\\.(ts|js|mjs|cjs)$`).test(importer)\n ) {\n return resolveVirtualId(virtualModuleId);\n }\n return null;\n}\n\n/** Adds module specifiers to Vite's ssr.noExternal so they are bundled instead of externalized. */\nfunction addSsrNoExternal(config: Record<string, any>, moduleIds: string[]): void {\n if (moduleIds.length === 0) return;\n const noExternal = config.ssr?.noExternal;\n if (!config.ssr) config.ssr = {};\n if (Array.isArray(noExternal)) {\n for (const moduleId of moduleIds) {\n if (!noExternal.includes(moduleId)) noExternal.push(moduleId);\n }\n } else if (typeof noExternal === 'string') {\n config.ssr.noExternal = [noExternal, ...moduleIds];\n } else if (noExternal !== true) {\n config.ssr.noExternal = noExternal ? [noExternal, ...moduleIds] : [...moduleIds];\n }\n}\n\n/** Wraps build.rollupOptions.external so shim and virtual modules are always bundled. */\nfunction wrapBuildExternal(config: Record<string, any>, shimModules: string[]): void {\n if (!config.build) config.build = {};\n if (!config.build.rollupOptions) config.build.rollupOptions = {};\n const original = config.build.rollupOptions.external;\n if (!original) return; // no external config — nothing to wrap\n config.build.rollupOptions.external = (id: string, ...rest: any[]) => {\n // Never externalize shim modules or virtual modules (plugin replaces them with generated code)\n if (shimModules.includes(id) || id.startsWith('virtual:mion')) return false;\n // Delegate to original external config\n if (typeof original === 'function') return original(id, ...rest);\n if (Array.isArray(original)) return original.some((ext) => (ext instanceof RegExp ? ext.test(id) : ext === id));\n if (original instanceof RegExp) return original.test(id);\n return original === id;\n };\n}\n\n// #################### SERVER READY ####################\n\n// Uses globalThis with Symbol.for because vitest loads vitest.config.ts and globalSetup.ts\n// in separate module contexts — without globalThis they'd get different promise instances.\nconst READY_KEY = Symbol.for('mion.serverReady');\nfunction getOrCreateServerReady(): {promise: Promise<void>; resolve: () => void} {\n if (!(globalThis as any)[READY_KEY]) {\n let _resolve: () => void;\n (globalThis as any)[READY_KEY] = {\n promise: new Promise<void>((r) => {\n _resolve = r;\n }),\n resolve: () => _resolve(),\n };\n }\n return (globalThis as any)[READY_KEY];\n}\n\n/** Promise that resolves when the server is ready. Await this in vitest globalSetup. */\nexport const serverReady: Promise<void> = getOrCreateServerReady().promise;\nconst onServerReady: () => void = getOrCreateServerReady().resolve;\n"],"names":["createDeepkitConfig","ts","killPersistentChild","REFLECTION_MODULES","SERVER_PURE_FNS_SHIM","AOT_CACHES_SHIM","resolveCacheDir","getOrGenerateAOTCaches","logAOTCaches","resolve","loadSSRRouterAndGenerateAOTCaches","VIRTUAL_SERVER_PURE_FNS","resolveVirtualId","VIRTUAL_AOT_CACHES","VIRTUAL_STUB_PREFIX","generateServerPureFnsVirtualModule","scanClientSource","generateNoopModule","generateJitFnsModule","generatePureFnsModule","generateRouterCacheModule","generateNoopCombinedModule","generateCombinedCachesModule","createPureFnTransformerFactory","generateAOTCaches","updateDiskCache","createRequire","existsSync"],"mappings":"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"}
@@ -5,6 +5,7 @@ export interface AOTCacheOptions {
5
5
  cache?: boolean | string;
6
6
  excludeReflection?: boolean;
7
7
  customVirtualModuleId?: string;
8
+ isClient?: boolean;
8
9
  }
9
10
  export interface MionServerConfig {
10
11
  startScript: string;
@@ -29,13 +29,14 @@ function generateEntryCode(fn) {
29
29
  return JSON.stringify(parts.length === 2 ? parts[1] : d);
30
30
  });
31
31
  const fnCode = fn.isFactory ? generateFactoryFn(fn) : generateDirectFn(fn);
32
+ const depsLine = depsArray.length > 0 ? `
33
+ pureFnDependencies: [${depsArray.join(", ")}],` : "";
32
34
  return ` ${JSON.stringify(fn.fnName)}: {
33
35
  namespace: ${JSON.stringify(fn.namespace)},
34
36
  fnName: ${JSON.stringify(fn.fnName)},
35
37
  paramNames: [${paramsArray}],
36
38
  code: ${JSON.stringify(fn.fnBody)},
37
- bodyHash: ${JSON.stringify(fn.bodyHash)},
38
- pureFnDependencies: [${depsArray.join(", ")}],
39
+ bodyHash: ${JSON.stringify(fn.bodyHash)},${depsLine}
39
40
  isFactory: ${fn.isFactory},
40
41
  ${fnCode}
41
42
  }`;
@@ -1 +1 @@
1
- {"version":3,"file":"virtualModule.cjs","sources":["../../../../../src/vite-plugin/virtualModule.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 {ExtractedPureFn} from './types.ts';\n\n/** Generates the virtual module source code from extracted server pure functions */\nexport function generateServerPureFnsVirtualModule(extractedFns: ExtractedPureFn[]): string {\n // Group functions by namespace\n const byNamespace = new Map<string, ExtractedPureFn[]>();\n for (const fn of extractedFns) {\n const list = byNamespace.get(fn.namespace) || [];\n list.push(fn);\n byNamespace.set(fn.namespace, list);\n }\n\n // Generate nested namespace entries\n const namespaceEntries: string[] = [];\n for (const [namespace, fns] of byNamespace) {\n const fnEntries = fns.map((fn) => generateEntryCode(fn));\n namespaceEntries.push(` ${JSON.stringify(namespace)}: {\\n${fnEntries.join(',\\n')}\\n }`);\n }\n\n return `// Auto-generated by @mionjs/server-pure-functions\n// Do not edit manually\n\nexport const serverPureFnsCache = {\n${namespaceEntries.join(',\\n')}\n};\n`;\n}\n\n/** Generates the code for a single server pure function entry */\nfunction generateEntryCode(fn: ExtractedPureFn): string {\n const paramsArray = fn.paramNames.map((p) => JSON.stringify(p)).join(', ');\n\n // Convert dependencies from \"namespace::fnName\" to just \"fnName\" (same-namespace resolution)\n const depsArray = [...fn.dependencies].map((d) => {\n const parts = d.split('::');\n return JSON.stringify(parts.length === 2 ? parts[1] : d);\n });\n\n // Generate the function code\n const fnCode = fn.isFactory ? generateFactoryFn(fn) : generateDirectFn(fn);\n\n return ` ${JSON.stringify(fn.fnName)}: {\n namespace: ${JSON.stringify(fn.namespace)},\n fnName: ${JSON.stringify(fn.fnName)},\n paramNames: [${paramsArray}],\n code: ${JSON.stringify(fn.fnBody)},\n bodyHash: ${JSON.stringify(fn.bodyHash)},\n pureFnDependencies: [${depsArray.join(', ')}],\n isFactory: ${fn.isFactory},\n${fnCode}\n }`;\n}\n\n/** Generates a direct fn property for a regular pure function */\nfunction generateDirectFn(fn: ExtractedPureFn): string {\n const params = fn.paramNames.join(', ');\n const safeName = makeSafeFunctionName(fn.fnName);\n\n return ` fn: function ${safeName}(${params}) {\n ${fn.fnBody}\n },`;\n}\n\n/** Generates createFn + fn: undefined for a factory function */\nfunction generateFactoryFn(fn: ExtractedPureFn): string {\n const params = fn.paramNames.join(', ');\n const safeName = makeSafeFunctionName(fn.fnName);\n\n return ` fn: undefined,\n createFn: function ${safeName}(jitUtils) {\n return (function factory(${params}) {\n ${fn.fnBody}\n })(jitUtils);\n },`;\n}\n\n/** Makes a function name safe for use as a JavaScript identifier */\nfunction makeSafeFunctionName(name: string): string {\n // Replace any non-alphanumeric characters with underscores\n const safe = name.replace(/[^a-zA-Z0-9_$]/g, '_');\n // Ensure it starts with a letter or underscore\n if (/^[0-9]/.test(safe)) {\n return '_' + safe;\n }\n return safe || 'anonymous';\n}\n"],"names":[],"mappings":";;AAUO,SAAS,mCAAmC,cAAyC;AAExF,QAAM,kCAAkB,IAAA;AACxB,aAAW,MAAM,cAAc;AAC3B,UAAM,OAAO,YAAY,IAAI,GAAG,SAAS,KAAK,CAAA;AAC9C,SAAK,KAAK,EAAE;AACZ,gBAAY,IAAI,GAAG,WAAW,IAAI;AAAA,EACtC;AAGA,QAAM,mBAA6B,CAAA;AACnC,aAAW,CAAC,WAAW,GAAG,KAAK,aAAa;AACxC,UAAM,YAAY,IAAI,IAAI,CAAC,OAAO,kBAAkB,EAAE,CAAC;AACvD,qBAAiB,KAAK,OAAO,KAAK,UAAU,SAAS,CAAC;AAAA,EAAQ,UAAU,KAAK,KAAK,CAAC;AAAA,MAAS;AAAA,EAChG;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA,EAIT,iBAAiB,KAAK,KAAK,CAAC;AAAA;AAAA;AAG9B;AAGA,SAAS,kBAAkB,IAA6B;AACpD,QAAM,cAAc,GAAG,WAAW,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI;AAGzE,QAAM,YAAY,CAAC,GAAG,GAAG,YAAY,EAAE,IAAI,CAAC,MAAM;AAC9C,UAAM,QAAQ,EAAE,MAAM,IAAI;AAC1B,WAAO,KAAK,UAAU,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC;AAAA,EAC3D,CAAC;AAGD,QAAM,SAAS,GAAG,YAAY,kBAAkB,EAAE,IAAI,iBAAiB,EAAE;AAEzE,SAAO,WAAW,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,yBACtB,KAAK,UAAU,GAAG,SAAS,CAAC;AAAA,sBAC/B,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,2BACpB,WAAW;AAAA,oBAClB,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,wBACrB,KAAK,UAAU,GAAG,QAAQ,CAAC;AAAA,mCAChB,UAAU,KAAK,IAAI,CAAC;AAAA,yBAC9B,GAAG,SAAS;AAAA,EACnC,MAAM;AAAA;AAER;AAGA,SAAS,iBAAiB,IAA6B;AACnD,QAAM,SAAS,GAAG,WAAW,KAAK,IAAI;AACtC,QAAM,WAAW,qBAAqB,GAAG,MAAM;AAE/C,SAAO,4BAA4B,QAAQ,IAAI,MAAM;AAAA,kBACvC,GAAG,MAAM;AAAA;AAE3B;AAGA,SAAS,kBAAkB,IAA6B;AACpD,QAAM,SAAS,GAAG,WAAW,KAAK,IAAI;AACtC,QAAM,WAAW,qBAAqB,GAAG,MAAM;AAE/C,SAAO;AAAA,iCACsB,QAAQ;AAAA,2CACE,MAAM;AAAA,sBAC3B,GAAG,MAAM;AAAA;AAAA;AAG/B;AAGA,SAAS,qBAAqB,MAAsB;AAEhD,QAAM,OAAO,KAAK,QAAQ,mBAAmB,GAAG;AAEhD,MAAI,SAAS,KAAK,IAAI,GAAG;AACrB,WAAO,MAAM;AAAA,EACjB;AACA,SAAO,QAAQ;AACnB;;"}
1
+ {"version":3,"file":"virtualModule.cjs","sources":["../../../../../src/vite-plugin/virtualModule.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 {ExtractedPureFn} from './types.ts';\n\n/** Generates the virtual module source code from extracted server pure functions */\nexport function generateServerPureFnsVirtualModule(extractedFns: ExtractedPureFn[]): string {\n // Group functions by namespace\n const byNamespace = new Map<string, ExtractedPureFn[]>();\n for (const fn of extractedFns) {\n const list = byNamespace.get(fn.namespace) || [];\n list.push(fn);\n byNamespace.set(fn.namespace, list);\n }\n\n // Generate nested namespace entries\n const namespaceEntries: string[] = [];\n for (const [namespace, fns] of byNamespace) {\n const fnEntries = fns.map((fn) => generateEntryCode(fn));\n namespaceEntries.push(` ${JSON.stringify(namespace)}: {\\n${fnEntries.join(',\\n')}\\n }`);\n }\n\n return `// Auto-generated by @mionjs/server-pure-functions\n// Do not edit manually\n\nexport const serverPureFnsCache = {\n${namespaceEntries.join(',\\n')}\n};\n`;\n}\n\n/** Generates the code for a single server pure function entry */\nfunction generateEntryCode(fn: ExtractedPureFn): string {\n const paramsArray = fn.paramNames.map((p) => JSON.stringify(p)).join(', ');\n\n // Convert dependencies from \"namespace::fnName\" to just \"fnName\" (same-namespace resolution)\n const depsArray = [...fn.dependencies].map((d) => {\n const parts = d.split('::');\n return JSON.stringify(parts.length === 2 ? parts[1] : d);\n });\n\n // Generate the function code\n const fnCode = fn.isFactory ? generateFactoryFn(fn) : generateDirectFn(fn);\n\n const depsLine = depsArray.length > 0 ? `\\n pureFnDependencies: [${depsArray.join(', ')}],` : '';\n\n return ` ${JSON.stringify(fn.fnName)}: {\n namespace: ${JSON.stringify(fn.namespace)},\n fnName: ${JSON.stringify(fn.fnName)},\n paramNames: [${paramsArray}],\n code: ${JSON.stringify(fn.fnBody)},\n bodyHash: ${JSON.stringify(fn.bodyHash)},${depsLine}\n isFactory: ${fn.isFactory},\n${fnCode}\n }`;\n}\n\n/** Generates a direct fn property for a regular pure function */\nfunction generateDirectFn(fn: ExtractedPureFn): string {\n const params = fn.paramNames.join(', ');\n const safeName = makeSafeFunctionName(fn.fnName);\n\n return ` fn: function ${safeName}(${params}) {\n ${fn.fnBody}\n },`;\n}\n\n/** Generates createFn + fn: undefined for a factory function */\nfunction generateFactoryFn(fn: ExtractedPureFn): string {\n const params = fn.paramNames.join(', ');\n const safeName = makeSafeFunctionName(fn.fnName);\n\n return ` fn: undefined,\n createFn: function ${safeName}(jitUtils) {\n return (function factory(${params}) {\n ${fn.fnBody}\n })(jitUtils);\n },`;\n}\n\n/** Makes a function name safe for use as a JavaScript identifier */\nfunction makeSafeFunctionName(name: string): string {\n // Replace any non-alphanumeric characters with underscores\n const safe = name.replace(/[^a-zA-Z0-9_$]/g, '_');\n // Ensure it starts with a letter or underscore\n if (/^[0-9]/.test(safe)) {\n return '_' + safe;\n }\n return safe || 'anonymous';\n}\n"],"names":[],"mappings":";;AAUO,SAAS,mCAAmC,cAAyC;AAExF,QAAM,kCAAkB,IAAA;AACxB,aAAW,MAAM,cAAc;AAC3B,UAAM,OAAO,YAAY,IAAI,GAAG,SAAS,KAAK,CAAA;AAC9C,SAAK,KAAK,EAAE;AACZ,gBAAY,IAAI,GAAG,WAAW,IAAI;AAAA,EACtC;AAGA,QAAM,mBAA6B,CAAA;AACnC,aAAW,CAAC,WAAW,GAAG,KAAK,aAAa;AACxC,UAAM,YAAY,IAAI,IAAI,CAAC,OAAO,kBAAkB,EAAE,CAAC;AACvD,qBAAiB,KAAK,OAAO,KAAK,UAAU,SAAS,CAAC;AAAA,EAAQ,UAAU,KAAK,KAAK,CAAC;AAAA,MAAS;AAAA,EAChG;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA,EAIT,iBAAiB,KAAK,KAAK,CAAC;AAAA;AAAA;AAG9B;AAGA,SAAS,kBAAkB,IAA6B;AACpD,QAAM,cAAc,GAAG,WAAW,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI;AAGzE,QAAM,YAAY,CAAC,GAAG,GAAG,YAAY,EAAE,IAAI,CAAC,MAAM;AAC9C,UAAM,QAAQ,EAAE,MAAM,IAAI;AAC1B,WAAO,KAAK,UAAU,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC;AAAA,EAC3D,CAAC;AAGD,QAAM,SAAS,GAAG,YAAY,kBAAkB,EAAE,IAAI,iBAAiB,EAAE;AAEzE,QAAM,WAAW,UAAU,SAAS,IAAI;AAAA,mCAAsC,UAAU,KAAK,IAAI,CAAC,OAAO;AAEzG,SAAO,WAAW,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,yBACtB,KAAK,UAAU,GAAG,SAAS,CAAC;AAAA,sBAC/B,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,2BACpB,WAAW;AAAA,oBAClB,KAAK,UAAU,GAAG,MAAM,CAAC;AAAA,wBACrB,KAAK,UAAU,GAAG,QAAQ,CAAC,IAAI,QAAQ;AAAA,yBACtC,GAAG,SAAS;AAAA,EACnC,MAAM;AAAA;AAER;AAGA,SAAS,iBAAiB,IAA6B;AACnD,QAAM,SAAS,GAAG,WAAW,KAAK,IAAI;AACtC,QAAM,WAAW,qBAAqB,GAAG,MAAM;AAE/C,SAAO,4BAA4B,QAAQ,IAAI,MAAM;AAAA,kBACvC,GAAG,MAAM;AAAA;AAE3B;AAGA,SAAS,kBAAkB,IAA6B;AACpD,QAAM,SAAS,GAAG,WAAW,KAAK,IAAI;AACtC,QAAM,WAAW,qBAAqB,GAAG,MAAM;AAE/C,SAAO;AAAA,iCACsB,QAAQ;AAAA,2CACE,MAAM;AAAA,sBAC3B,GAAG,MAAM;AAAA;AAAA;AAG/B;AAGA,SAAS,qBAAqB,MAAsB;AAEhD,QAAM,OAAO,KAAK,QAAQ,mBAAmB,GAAG;AAEhD,MAAI,SAAS,KAAK,IAAI,GAAG;AACrB,WAAO,MAAM;AAAA,EACjB;AACA,SAAO,QAAQ;AACnB;;"}
@@ -14,9 +14,9 @@ export interface PlatformReadyData {
14
14
  routerConfig: Record<string, unknown>;
15
15
  platformConfig: Record<string, unknown>;
16
16
  }
17
- export declare function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string): Promise<AOTCacheResult>;
17
+ export declare function generateAOTCaches(serverConfig: MionServerConfig, startScriptOverride?: string, isClient?: boolean): Promise<AOTCacheResult>;
18
18
  export type ModuleLoader = (url: string) => Promise<Record<string, any>>;
19
- export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string): Promise<AOTCacheData>;
19
+ export declare function loadSSRRouterAndGenerateAOTCaches(loadModule: ModuleLoader, startScript: string, isClient?: boolean): Promise<AOTCacheData>;
20
20
  export declare function killPersistentChild(child: ChildProcess | null): Promise<void>;
21
21
  export declare function logAOTCaches(data: AOTCacheData): void;
22
22
  export declare function generateJitFnsModule(jitFnsCode: string): string;