@useavalon/avalon 0.3.2-canary.10 → 0.3.2-canary.11

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.
@@ -1,94 +1,11 @@
1
1
  /**
2
- * CSS HMR Handler
3
- *
4
- * Handles Hot Module Replacement for CSS files including:
5
- * - Global CSS files
6
- * - CSS modules
7
- * - Component-scoped styles (Svelte, Vue)
2
+ * Apply Avalon-owned CSS HMR. Writes `textContent` on a `<style>` tag so
3
+ * previous rules stay until the new ones are in the DOM.
8
4
  */
9
- import type { Update } from "./hmr-coordinator.ts";
5
+ export declare function normalizeCssHref(path: string): string;
10
6
  /**
11
- * CSS update types
7
+ * Cache-bust the matching `<link>` (`v=`, Vite strips `t=`) and write the
8
+ * payload into a `<style>` tag so the change is visible before the refetch.
12
9
  */
13
- export type CSSUpdateType = "global" | "module" | "scoped";
14
- /**
15
- * CSS update information
16
- */
17
- export interface CSSUpdateInfo {
18
- type: CSSUpdateType;
19
- path: string;
20
- timestamp: number;
21
- affectedComponents?: string[];
22
- }
23
- /**
24
- * CSS HMR Handler class
25
- * Manages CSS hot updates without page reload
26
- */
27
- export declare class CSSHMRHandler {
28
- private cssModuleMap;
29
- private styleElementMap;
30
- /**
31
- * Handle CSS update from Vite HMR
32
- */
33
- handleCSSUpdate(update: Update): void;
34
- /**
35
- * Classify the type of CSS update
36
- */
37
- private classifyCSSUpdate;
38
- /**
39
- * Handle global CSS file update
40
- * Injects updated styles without page reload
41
- */
42
- private handleGlobalCSSUpdate;
43
- /**
44
- * Handle CSS module update
45
- * Re-renders components using the updated CSS module
46
- */
47
- private handleCSSModuleUpdate;
48
- /**
49
- * Handle scoped CSS update (Svelte/Vue)
50
- * Updates only the affected component's styles
51
- */
52
- private handleScopedCSSUpdate;
53
- /**
54
- * Find islands that use a specific CSS module
55
- */
56
- private findIslandsUsingCSSModule;
57
- /**
58
- * Find islands using a specific component file
59
- */
60
- private findIslandsUsingComponent;
61
- /**
62
- * Trigger re-render of an island to apply new CSS module classes
63
- */
64
- private triggerIslandRerender;
65
- /**
66
- * Dispatch CSS update event for feedback
67
- */
68
- private dispatchCSSUpdateEvent;
69
- /**
70
- * Normalize a file path for comparison
71
- */
72
- private normalizePath;
73
- /**
74
- * Get directory from a file path
75
- */
76
- private getDirectory;
77
- /**
78
- * Get file ID from path (for Vite's data-vite-dev-id)
79
- */
80
- private getFileId;
81
- /**
82
- * Clear cached mappings
83
- */
84
- clearCache(): void;
85
- /**
86
- * Register an island as using a CSS module
87
- * Useful for explicit tracking
88
- */
89
- registerCSSModuleUsage(cssPath: string, island: HTMLElement): void;
90
- }
91
- /**
92
- * Get or create the global CSS HMR handler instance
93
- */
94
- export declare function getCSSHMRHandler(): CSSHMRHandler;
10
+ export declare function applyDevCssHot(doc: Document, href: string, css: string): void;
11
+ export declare function applyCssText(doc: Document, href: string, css: string): void;
@@ -1 +1 @@
1
- export class CSSHMRHandler{cssModuleMap=new Map;styleElementMap=new Map;handleCSSUpdate(e){let t=this.classifyCSSUpdate(e);switch(t.type){case`global`:this.handleGlobalCSSUpdate(t);break;case`module`:this.handleCSSModuleUpdate(t);break;case`scoped`:this.handleScopedCSSUpdate(t);break}}classifyCSSUpdate(e){let t=e.path||e.acceptedPath;return t.includes(`.module.css`)||t.includes(`.module.scss`)?{type:`module`,path:t,timestamp:e.timestamp}:t.includes(`.svelte`)||t.includes(`.vue`)?{type:`scoped`,path:t,timestamp:e.timestamp}:{type:`global`,path:t,timestamp:e.timestamp}}handleGlobalCSSUpdate(e){try{let t=this.styleElementMap.get(e.path);t&&(t.remove(),this.styleElementMap.delete(e.path));let n=document.querySelector(`style[data-vite-dev-id*="${this.getFileId(e.path)}"]`);n&&this.styleElementMap.set(e.path,n),this.dispatchCSSUpdateEvent(e,!0)}catch(t){throw console.error(`Failed to update global CSS: ${e.path}`,t),this.dispatchCSSUpdateEvent(e,!1,t),t}}handleCSSModuleUpdate(e){try{let t=this.findIslandsUsingCSSModule(e.path);if(t.length===0)return;for(let n of t)this.triggerIslandRerender(n,e);this.dispatchCSSUpdateEvent(e,!0)}catch(t){throw console.error(`[HMR] Failed to update CSS module: ${e.path}`,t),this.dispatchCSSUpdateEvent(e,!1,t),t}}handleScopedCSSUpdate(e){try{if(this.findIslandsUsingComponent(e.path).length===0)return;this.dispatchCSSUpdateEvent(e,!0)}catch(t){throw console.error(`[HMR] Failed to update scoped CSS: ${e.path}`,t),this.dispatchCSSUpdateEvent(e,!1,t),t}}findIslandsUsingCSSModule(e){let t=[],n=this.normalizePath(e),r=this.cssModuleMap.get(n);if(r)return Array.from(r);let i=document.querySelectorAll(`[data-src]`);for(let n of i){let r=n.getAttribute(`data-src`);r&&this.getDirectory(r)===this.getDirectory(e)&&t.push(n)}return t.length>0&&this.cssModuleMap.set(n,new Set(t)),t}findIslandsUsingComponent(e){let t=[],n=this.normalizePath(e),r=document.querySelectorAll(`[data-src]`);for(let e of r){let r=e.getAttribute(`data-src`);if(!r)continue;let i=this.normalizePath(r);(i===n||i.includes(n))&&t.push(e)}return t}triggerIslandRerender(e,t){e.dispatchEvent(new CustomEvent(`css-module-update`,{detail:{cssPath:t.path,timestamp:t.timestamp},bubbles:!0}));let n=e.getAttribute(`data-src`);n&&e.dispatchEvent(new CustomEvent(`hmr-update-required`,{detail:{src:n,reason:`css-module-update`,cssPath:t.path},bubbles:!0}))}dispatchCSSUpdateEvent(e,t,n){let r=new CustomEvent(`css-hmr-update`,{detail:{type:e.type,path:e.path,timestamp:e.timestamp,success:t,error:n?.message},bubbles:!0});document.dispatchEvent(r)}normalizePath(e){return e.replace(/\\/g,`/`).replace(/^\//,``).replace(/\?.*$/,``).replace(/#.*$/,``)}getDirectory(e){let t=this.normalizePath(e),n=t.lastIndexOf(`/`);return n>=0?t.substring(0,n):``}getFileId(e){return this.normalizePath(e)}clearCache(){this.cssModuleMap.clear(),this.styleElementMap.clear()}registerCSSModuleUsage(e,t){let n=this.normalizePath(e);this.cssModuleMap.has(n)||this.cssModuleMap.set(n,new Set),this.cssModuleMap.get(n).add(t)}}let t=null;export function getCSSHMRHandler(){return t||=new CSSHMRHandler,t}
1
+ export function normalizeCssHref(e){let t=(e.split(`?`)[0]?.split(`#`)[0]??e).replaceAll(`\\`,`/`);return t.startsWith(`/`)?t:`/${t}`}function t(e){return e.dataset.avalonCss}export function applyDevCssHot(n,i,a){let o=normalizeCssHref(i);for(let e of n.querySelectorAll(`link[data-avalon-css]`))t(e)===o&&(e.href=`${o}?direct&v=${Date.now()}`);a&&applyCssText(n,i,a)}export function applyCssText(n,r,i){if(!i||i.includes(`__vite__updateStyle`)||i.includes(`import.meta.hot`))return;let a=normalizeCssHref(r),o;for(let e of n.querySelectorAll(`style[data-avalon-css]`))if(t(e)===a){o=e;break}o||(o=n.createElement(`style`),o.dataset.avalonCss=a,n.head.appendChild(o)),o.textContent=i}
@@ -72,7 +72,6 @@ export declare class HMRCoordinator {
72
72
  registerAdapter(framework: string, adapter: FrameworkHMRAdapter): void;
73
73
  getRegistry(): AdapterRegistry;
74
74
  handleUpdate(payload: HMRUpdatePayload): Promise<void>;
75
- private processCSSUpdates;
76
75
  private queueJSUpdates;
77
76
  private processUpdateQueue;
78
77
  findAffectedIslands(modulePath: string): HTMLElement[];
@@ -1 +1 @@
1
- import{getCSSHMRHandler as e}from"./css-hmr-handler.js";import{AdapterRegistry as t}from"./framework-adapter.js";export class HMRCoordinator{registry=new t;stateSnapshots=new Map;updateQueue=new Set;isProcessing=!1;initialize(){import.meta.hot&&(import.meta.hot.accept(),import.meta.hot.on(`vite:beforeUpdate`,e=>{this.handleUpdate(e)}),import.meta.hot.on(`vite:beforeFullReload`,()=>{this.handleBeforeFullReload()}),import.meta.hot.on(`vite:error`,e=>{console.error(`[HMR] error:`,e),this.handleError(e)}),document.addEventListener(`hmr-update-required`,e=>{let{src:t,reason:n}=e.detail;n===`css-module-update`&&(this.updateQueue.add(this.normalizePath(t)),this.isProcessing||this.processUpdateQueue().catch(e=>{console.error(`[HMR] Failed to process CSS module update:`,e)}))}))}registerAdapter(e,t){this.registry.register(e,t)}getRegistry(){return this.registry}async handleUpdate(e){if(e.type!==`update`||!e.updates)return;let t=[],n=[];for(let r of e.updates)r.type===`css-update`?t.push(r):n.push(r);this.processCSSUpdates(t),this.queueJSUpdates(n),!this.isProcessing&&this.updateQueue.size>0&&await this.processUpdateQueue()}processCSSUpdates(t){if(t.length===0)return;let n=e();for(let e of t)try{n.handleCSSUpdate(e)}catch(e){console.error(`[HMR] CSS update failed:`,e)}}queueJSUpdates(e){for(let t of e){let e=this.normalizePath(t.path||t.acceptedPath);this.isIslandModule(e)&&this.updateQueue.add(e)}}async processUpdateQueue(){if(this.updateQueue.size!==0){this.isProcessing=!0;try{let e=Array.from(this.updateQueue);this.updateQueue.clear();for(let t of e){let e=this.findAffectedIslands(t);for(let t of e)try{await this.updateIsland(t)}catch(e){console.error(`[HMR] Failed to update island:`,e)}}}finally{this.isProcessing=!1}}}findAffectedIslands(e){let t=[],n=this.normalizePath(e),r=document.querySelectorAll(`[data-src]`);for(let e of r){let r=e.dataset.src;if(!r)continue;let i=this.normalizePath(r);(i===n||i.endsWith(n)||n.endsWith(i)||i.split(`/`).pop()===n.split(`/`).pop())&&t.push(e)}return t}async updateIsland(e){let t=e.dataset.framework,n=e.dataset.src,r=e.dataset.props;if(!t||!n){console.warn(`[HMR] Island missing framework or src attribute`,e);return}let i=this.registry.get(t.toLowerCase());if(!i){console.warn(`[HMR] No adapter registered for framework: ${t}`);return}try{let a=r?JSON.parse(r):{},o=i.preserveState(e);o&&this.stateSnapshots.set(this.getIslandId(e),o),delete e.dataset.hydrated,delete e.dataset.hydrationStatus,e.querySelector(`.hydration-error-indicator, .hmr-error-indicator`)?.remove();let s=Date.now(),c=await import(n.includes(`?`)?`${n}&t=${s}`:`${n}?t=${s}`),l=this.resolveComponent(c,n);await i.update(e,l,a),o&&(i.restoreState(e,o),this.stateSnapshots.delete(this.getIslandId(e))),e.dataset.hydrated=`true`,e.dispatchEvent(new CustomEvent(`hmr-update`,{detail:{framework:t,src:n,timestamp:Date.now(),success:!0},bubbles:!0}))}catch(r){throw console.error(`[HMR] Failed to update ${t} island ${n}:`,r),i.handleError(e,r),e.dispatchEvent(new CustomEvent(`hmr-error`,{detail:{framework:t,src:n,error:r.message,timestamp:Date.now()},bubbles:!0})),r}}resolveComponent(e,t){if(e.default)return e.default;for(let t of Object.keys(e)){if(t===`default`)continue;let n=e[t];if(typeof n==`function`&&n.prototype)return n}throw Error(`Component ${t} has no default export`)}handleBeforeFullReload(){let e=document.querySelectorAll(`[data-hydrated="true"]`),t={};for(let n of e){let e=n.dataset.framework,r=n.dataset.src;if(!e||!r)continue;let i=this.registry.get(e.toLowerCase());if(!i)continue;let a=i.preserveState(n);a&&(t[r]=a)}try{sessionStorage.setItem(`__avalon_hmr_states__`,JSON.stringify(t))}catch(e){console.warn(`[HMR] Failed to save states:`,e)}}handleError(e){let t=Error(e.err.message);t.stack=e.err.stack,console.error(`[HMR] Error:`,t),globalThis.window!==void 0&&import(`./hmr-error-overlay.js`).then(({showHMRErrorOverlay:n})=>{n({framework:`unknown`,src:`unknown`,error:t,filePath:e.err.id||e.err.loc?.file||`unknown`,line:e.err.loc?.line,column:e.err.loc?.column})}).catch(()=>{console.error(`[HMR] Failed to show error overlay`)})}normalizePath(e){return e.replaceAll(`\\`,`/`).replace(/^\//,``).replace(/\?.*$/,``).replace(/#.*$/,``).replace(/^src\//,``)}isIslandModule(e){return e.includes(`/islands/`)||e.includes(`\\islands\\`)}getIslandId(e){let t=e.dataset.src??``;return`${e.dataset.framework??``}:${t}:${Array.from(document.querySelectorAll(`[data-src="${t}"]`)).indexOf(e)}`}}let r=null;export function getHMRCoordinator(){return r??=new HMRCoordinator,r}export function initializeHMR(){import.meta.hot&&getHMRCoordinator().initialize()}
1
+ import{AdapterRegistry as e}from"./framework-adapter.js";export class HMRCoordinator{registry=new e;stateSnapshots=new Map;updateQueue=new Set;isProcessing=!1;initialize(){import.meta.hot&&(import.meta.hot.accept(),import.meta.hot.on(`vite:beforeUpdate`,e=>this.handleUpdate(e)),import.meta.hot.on(`vite:beforeFullReload`,()=>{this.handleBeforeFullReload()}),import.meta.hot.on(`vite:error`,e=>{console.error(`[HMR] error:`,e),this.handleError(e)}),document.addEventListener(`hmr-update-required`,e=>{let{src:t,reason:n}=e.detail;n===`css-module-update`&&(this.updateQueue.add(this.normalizePath(t)),this.isProcessing||this.processUpdateQueue().catch(e=>{console.error(`[HMR] Failed to process CSS module update:`,e)}))}))}registerAdapter(e,t){this.registry.register(e,t)}getRegistry(){return this.registry}async handleUpdate(e){if(e.type!==`update`||!e.updates)return;let t=[];for(let n of e.updates)n.type===`js-update`&&t.push(n);this.queueJSUpdates(t),!this.isProcessing&&this.updateQueue.size>0&&await this.processUpdateQueue()}queueJSUpdates(e){for(let t of e){let e=this.normalizePath(t.path||t.acceptedPath);this.isIslandModule(e)&&this.updateQueue.add(e)}}async processUpdateQueue(){if(this.updateQueue.size!==0){this.isProcessing=!0;try{let e=Array.from(this.updateQueue);this.updateQueue.clear();for(let t of e){let e=this.findAffectedIslands(t);for(let t of e)try{await this.updateIsland(t)}catch(e){console.error(`[HMR] Failed to update island:`,e)}}}finally{this.isProcessing=!1}}}findAffectedIslands(e){let t=[],n=this.normalizePath(e),r=document.querySelectorAll(`[data-src]`);for(let e of r){let r=e.dataset.src;if(!r)continue;let i=this.normalizePath(r);(i===n||i.endsWith(n)||n.endsWith(i)||i.split(`/`).pop()===n.split(`/`).pop())&&t.push(e)}return t}async updateIsland(e){let t=e.dataset.framework,n=e.dataset.src,r=e.dataset.props;if(!t||!n){console.warn(`[HMR] Island missing framework or src attribute`,e);return}let i=this.registry.get(t.toLowerCase());if(!i){console.warn(`[HMR] No adapter registered for framework: ${t}`);return}try{let a=r?JSON.parse(r):{},o=i.preserveState(e);o&&this.stateSnapshots.set(this.getIslandId(e),o),delete e.dataset.hydrated,delete e.dataset.hydrationStatus,e.querySelector(`.hydration-error-indicator, .hmr-error-indicator`)?.remove();let s=Date.now(),c=await import(n.includes(`?`)?`${n}&t=${s}`:`${n}?t=${s}`),l=this.resolveComponent(c,n);await i.update(e,l,a),o&&(i.restoreState(e,o),this.stateSnapshots.delete(this.getIslandId(e))),e.dataset.hydrated=`true`,e.dispatchEvent(new CustomEvent(`hmr-update`,{detail:{framework:t,src:n,timestamp:Date.now(),success:!0},bubbles:!0}))}catch(r){throw console.error(`[HMR] Failed to update ${t} island ${n}:`,r),i.handleError(e,r),e.dispatchEvent(new CustomEvent(`hmr-error`,{detail:{framework:t,src:n,error:r.message,timestamp:Date.now()},bubbles:!0})),r}}resolveComponent(e,t){if(e.default)return e.default;for(let t of Object.keys(e)){if(t===`default`)continue;let n=e[t];if(typeof n==`function`&&n.prototype)return n}throw Error(`Component ${t} has no default export`)}handleBeforeFullReload(){let e=document.querySelectorAll(`[data-hydrated="true"]`),t={};for(let n of e){let e=n.dataset.framework,r=n.dataset.src;if(!e||!r)continue;let i=this.registry.get(e.toLowerCase());if(!i)continue;let a=i.preserveState(n);a&&(t[r]=a)}try{sessionStorage.setItem(`__avalon_hmr_states__`,JSON.stringify(t))}catch(e){console.warn(`[HMR] Failed to save states:`,e)}}handleError(e){let t=Error(e.err.message);t.stack=e.err.stack,console.error(`[HMR] Error:`,t),globalThis.window!==void 0&&import(`./hmr-error-overlay.js`).then(({showHMRErrorOverlay:n})=>{n({framework:`unknown`,src:`unknown`,error:t,filePath:e.err.id||e.err.loc?.file||`unknown`,line:e.err.loc?.line,column:e.err.loc?.column})}).catch(()=>{console.error(`[HMR] Failed to show error overlay`)})}normalizePath(e){let t=e.replaceAll(`\\`,`/`);t.startsWith(`/`)&&(t=t.slice(1));let n=t.indexOf(`?`);n!==-1&&(t=t.slice(0,n));let r=t.indexOf(`#`);return r!==-1&&(t=t.slice(0,r)),t.startsWith(`src/`)&&(t=t.slice(4)),t}isIslandModule(e){return e.includes(`/islands/`)||e.includes(`\\islands\\`)}getIslandId(e){let t=e.dataset.src??``;return`${e.dataset.framework??``}:${t}:${Array.from(document.querySelectorAll(`[data-src="${t}"]`)).indexOf(e)}`}}let n=null;export function getHMRCoordinator(){return n??=new HMRCoordinator,n}export function initializeHMR(){import.meta.hot&&getHMRCoordinator().initialize()}
@@ -0,0 +1,18 @@
1
+ export interface HMRErrorOverlayOptions {
2
+ framework: string;
3
+ src: string;
4
+ error: Error;
5
+ filePath?: string;
6
+ line?: number;
7
+ column?: number;
8
+ }
9
+
10
+ export interface HMRToastOptions {
11
+ message: string;
12
+ type?: "info" | "error" | "success";
13
+ duration?: number;
14
+ }
15
+
16
+ export declare function showHMRErrorOverlay(options: HMRErrorOverlayOptions): void;
17
+ export declare function removeHMRErrorOverlay(): void;
18
+ export declare function showHMRToast(options: HMRToastOptions): void;
@@ -18,6 +18,13 @@ import type { ViteDevServer } from "vite";
18
18
  * @returns Array of CSS strings ready to be injected as <style> tags
19
19
  */
20
20
  export declare function collectCssFromModuleGraph(server: ViteDevServer, moduleUrl: string): Promise<string[]>;
21
+ /**
22
+ * Extract raw CSS from Vite's transformed CSS module JS wrapper.
23
+ *
24
+ * Vite 8 writes `const __vite__css = ${JSON.stringify(css)}`. `?direct`
25
+ * skips that wrapper and returns hashed CSS as `result.code`.
26
+ */
27
+ export declare function extractCssFromTransformedModule(code: string): string | null;
21
28
  /**
22
29
  * Inject collected CSS into an HTML string before </head>.
23
30
  *
@@ -26,3 +33,25 @@ export declare function collectCssFromModuleGraph(server: ViteDevServer, moduleU
26
33
  * If no </head> is found, styles are prepended to the HTML.
27
34
  */
28
35
  export declare function injectSsrCss(html: string, cssContents: string[]): string;
36
+ /**
37
+ * Sanitize CSS content for safe injection inside a <style> tag.
38
+ *
39
+ * The only way to break out of a <style> tag is with a closing </style> tag
40
+ * (case-insensitive, with optional whitespace). We neutralize this by escaping
41
+ * any occurrence of `</style` in the CSS content.
42
+ *
43
+ * This prevents XSS via:
44
+ * .foo {} </style><script>alert('xss')</script><style>
45
+ *
46
+ * The CSS source comes from Vite's module graph (local project files and
47
+ * npm dependencies), so this is defense-in-depth against compromised deps.
48
+ */
49
+ export declare function sanitizeCssForStyleTag(css: string): string;
50
+ /**
51
+ * Vite strips `t=<13 digits>` from transform URLs (HMR timestamp). `v=`
52
+ * stays, so each read is a new module id and cannot reuse a stale
53
+ * `transformResult` for `?direct`.
54
+ */
55
+ export declare function directCssRequestUrl(href: string, bust?: number): string;
56
+ /** Transform a `/`-rooted project CSS href to hashed CSS text for SSR/HMR. */
57
+ export declare function readDirectCss(server: ViteDevServer, href: string): Promise<string>;
@@ -1,3 +1,3 @@
1
- export async function collectCssFromModuleGraph(e,r){let i=[],a=new Set,o=await e.moduleGraph.getModuleByUrl(r);if(!o)return i;let s=[o];for(;s.length>0;){let r=s.shift(),o=r.id??r.url;if(!a.has(o)){if(a.add(o),t(o)){let t=await n(e,r);t&&i.push(t)}for(let e of r.importedModules){let t=e.id??e.url;a.has(t)||s.push(e)}}}return i}function t(e){let t=e.split(`?`)[0];return t.endsWith(`.css`)||t.endsWith(`.scss`)||t.endsWith(`.sass`)||t.endsWith(`.less`)||t.endsWith(`.styl`)||t.endsWith(`.stylus`)}async function n(e,t){try{let n=t.url,i=await e.transformRequest(n+`?direct`);return i&&typeof i.code==`string`?r(i.code):null}catch{return null}}function r(e){let t=new RegExp(/const\s+__vite__css\s*=\s*"((?:[^"\\]|\\.)*)"/).exec(e);if(t)return i(t[1]);let n=new RegExp(/__vite_ssr_exports__\.default\s*=\s*"((?:[^"\\]|\\.)*)"/).exec(e);if(n)return i(n[1]);let r=new RegExp(/export\s+default\s+"((?:[^"\\]|\\.)*)"/).exec(e);return r?i(r[1]):!e.includes(`export `)&&!e.includes(`__vite`)?e:null}function i(e){return e.replaceAll(String.raw`\n`,`
2
- `).replaceAll(String.raw`\t`,` `).replaceAll(String.raw`\r`,`\r`).replaceAll(String.raw`\"`,`"`).replaceAll(`\\\\`,`\\`)}export function injectSsrCss(e,t){if(t.length===0)return e;let n=t.map(e=>`<style data-avalon-ssr-css>${o(e)}</style>`).join(`
3
- `);return e.includes(`</head>`)?e.replace(`</head>`,`${n}\n</head>`):e.includes(`<head>`)?e.replace(`<head>`,`<head>\n${n}`):n+e}function o(e){return e.replaceAll(/<\/style/gi,String.raw`<\/style`)}
1
+ export async function collectCssFromModuleGraph(e,r){let i=[],a=new Set,o=await e.moduleGraph.getModuleByUrl(r);if(!o)return i;let s=[o];for(;s.length>0;){let r=s.shift(),o=r.id??r.url;if(!a.has(o)){if(a.add(o),t(o)){let t=await n(e,r);t&&i.push(t)}for(let e of r.importedModules){let t=e.id??e.url;a.has(t)||s.push(e)}}}return i}function t(e){let t=e.split(`?`)[0];return t.endsWith(`.css`)||t.endsWith(`.scss`)||t.endsWith(`.sass`)||t.endsWith(`.less`)||t.endsWith(`.styl`)||t.endsWith(`.stylus`)}async function n(e,t){try{let n=t.url,i=await e.transformRequest(n+`?direct`);return i&&typeof i.code==`string`?extractCssFromTransformedModule(i.code):null}catch{return null}}export function extractCssFromTransformedModule(e){if(!e)return null;let t=/const\s+__vite__css\s*=\s*("(?:[^"\\]|\\.)*")/.exec(e);if(t?.[1])return a(t[1]);let n=/__vite_ssr_exports__\.default\s*=\s*("(?:[^"\\]|\\.)*")/.exec(e);if(n?.[1])return a(n[1]);let r=/export\s+default\s+("(?:[^"\\]|\\.)*")/.exec(e);return r?.[1]?a(r[1]):i(e)?e:null}function i(e){return!(e.includes(`__vite__updateStyle`)||e.includes(`import.meta.hot`)||e.includes(`export `)||e.includes(`import `))}function a(e){try{return JSON.parse(e)}catch{return o(e.slice(1,-1))}}function o(e){return e.replaceAll(String.raw`\n`,`
2
+ `).replaceAll(String.raw`\t`,` `).replaceAll(String.raw`\r`,`\r`).replaceAll(String.raw`\"`,`"`).replaceAll(`\\\\`,`\\`)}export function injectSsrCss(e,t){if(t.length===0)return e;let n=t.map(e=>`<style data-avalon-ssr-css>${sanitizeCssForStyleTag(e)}</style>`).join(`
3
+ `);return e.includes(`</head>`)?e.replace(`</head>`,`${n}\n</head>`):e.includes(`<head>`)?e.replace(`<head>`,`<head>\n${n}`):n+e}export function sanitizeCssForStyleTag(e){return e.replaceAll(/<\/style/gi,String.raw`<\/style`)}export function directCssRequestUrl(e,t=Date.now()){return`${e}?direct&v=${t}`}export async function readDirectCss(e,t){try{let n=await e.transformRequest(directCssRequestUrl(t));return!n||typeof n.code!=`string`?``:extractCssFromTransformedModule(n.code)??``}catch{return``}}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Route → CSS href matching for Nitro SSR. Pure: the layouts virtual module
3
+ * imports this; a filesystem walker must not leak into the Nitro bundle.
4
+ */
5
+ export interface DevCssRouteEntry {
6
+ pattern: string;
7
+ /** Page + matching layouts + global CSS. */
8
+ hrefs: string[];
9
+ /** Page + global CSS (used when the page skips layouts). */
10
+ pageHrefs: string[];
11
+ }
12
+ export interface DevCssRouteTable {
13
+ routes: DevCssRouteEntry[];
14
+ /** Global CSS + root layout graph — used when no page matches. */
15
+ fallbackHrefs: string[];
16
+ globalHrefs: string[];
17
+ }
18
+ export declare function stripTrailingSlash(path: string): string;
19
+ /** Avalon page-pattern match (`:param`, `**`) used for CSS table lookup. */
20
+ export declare function matchPathPattern(pathname: string, pattern: string): boolean;
21
+ /** Layout prefix match: `/` is root-only; `/blog` does not match `/blogger`. */
22
+ export declare function layoutPrefixMatches(pathname: string, prefix: string): boolean;
23
+ export declare function selectDevCssHrefs(table: DevCssRouteTable, pathname: string, skipLayouts: boolean): string[];
24
+ /** Vite URL for `\0virtual:avalon/dev-css-hmr` — loaded as its own module graph entry. */
25
+ export declare const DEV_CSS_HMR_CLIENT_SRC = "/@id/__x00__virtual:avalon/dev-css-hmr";
26
+ /**
27
+ * Insert per-route `<link rel="stylesheet" href="…?direct">`. The browser
28
+ * fetches hashed CSS from Vite on every document load, so a reload cannot
29
+ * serve a baked snapshot. Also injects `/@vite/client` and the CSS HMR
30
+ * listener — Nitro HTML never runs `transformIndexHtml`.
31
+ */
32
+ export declare function appendDevCssLinks(html: string, hrefs: string[]): string;
33
+ /**
34
+ * Insert hashed CSS as `<style data-avalon-css>` so HMR can update
35
+ * `textContent` in place. `</style` is neutralized so the tag cannot close early.
36
+ */
37
+ export declare function appendDevStyleTags(html: string, sheets: Array<{
38
+ href: string;
39
+ css: string;
40
+ }>): string;
@@ -0,0 +1,5 @@
1
+ export function stripTrailingSlash(e){return e===`/`?`/`:e.endsWith(`/`)?e.slice(0,-1):e}export function matchPathPattern(t,n){let r=stripTrailingSlash(t),i=stripTrailingSlash(n);if(r===i)return!0;let a=i.split(`/`),o=r.split(`/`);for(let e=0;e<a.length;e++){let t=a[e];if(t===`**`)return!0;if(e>=o.length)return!1;if(t.startsWith(`:`)){if(!o[e])return!1;continue}if(t!==o[e])return!1}return o.length<=a.length}export function layoutPrefixMatches(t,n){if(n===`/`)return t===`/`;let r=stripTrailingSlash(t),i=stripTrailingSlash(n);return r===i||r.startsWith(`${i}/`)}export function selectDevCssHrefs(e,n,r){let i=n.split(`?`)[0]??n,a=e.routes.find(e=>matchPathPattern(i,e.pattern));return a?r?a.pageHrefs:a.hrefs:r?e.globalHrefs:e.fallbackHrefs}function i(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`"`,`&quot;`).replaceAll(`<`,`&lt;`)}export const DEV_CSS_HMR_CLIENT_SRC=`/@id/__x00__virtual:avalon/dev-css-hmr`;export function appendDevCssLinks(e,t){if(!e.includes(`</head>`))return e;let n=t.map(e=>{let t=i(e);return`<link rel="stylesheet" href="${t}?direct" data-avalon-css="${t}">`}).join(`
2
+ `),r=[];n&&r.push(n),e.includes(`/@vite/client`)||r.push(`<script type="module" src="/@vite/client"><\/script>`),e.includes(`virtual:avalon/dev-css-hmr`)||r.push(`<script type="module" src="/@id/__x00__virtual:avalon/dev-css-hmr"><\/script>`);let a=r.join(`
3
+ `);return e.replace(`</head>`,`${a}${a?`
4
+ `:``}</head>`)}export function appendDevStyleTags(e,t){if(t.length===0||!e.includes(`</head>`))return e;let n=t.map(e=>{let t=e.css.replaceAll(/<\/style/gi,String.raw`<\/style`);return`<style type="text/css" data-avalon-css="${i(e.href)}">${t}</style>`}).join(`
5
+ `);return e.replace(`</head>`,`${n}\n</head>`)}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Dev CSS for Nitro SSR is collected from each page's static import graph
3
+ * (plus layouts and global CSS), not by globbing every `.css` file on disk.
4
+ * The layouts virtual module lives in Nitro's realm, so this walk is filesystem
5
+ * based — Vite's module graph is not available there.
6
+ */
7
+ import { type DevCssRouteEntry, type DevCssRouteTable } from "../render/dev-css-select.ts";
8
+ export { matchPathPattern, selectDevCssHrefs } from "../render/dev-css-select.ts";
9
+ export type { DevCssRouteEntry, DevCssRouteTable };
10
+ export interface LayoutCssEntry {
11
+ prefix: string;
12
+ filePath: string;
13
+ isRoot: boolean;
14
+ skipRoot: boolean;
15
+ }
16
+ /** Resolve a relative or root-absolute specifier to an existing file. */
17
+ export declare function resolveProjectImport(fromFile: string, spec: string, cwd: string): string | null;
18
+ /**
19
+ * Collect `/`-rooted CSS hrefs reachable from `entryFile` via static imports
20
+ * and CSS `@import`. Skips `node_modules`.
21
+ */
22
+ export declare function collectCssHrefsFromEntry(entryFile: string, cwd: string): string[];
23
+ /**
24
+ * Build the per-route CSS table used by `virtual:avalon/layouts` in development.
25
+ */
26
+ export declare function buildDevCssRouteTable(options: {
27
+ cwd: string;
28
+ routes: Array<{
29
+ pattern: string;
30
+ filePath: string;
31
+ }>;
32
+ layouts: LayoutCssEntry[];
33
+ globalCSS: string[];
34
+ }): DevCssRouteTable;
@@ -0,0 +1 @@
1
+ import{readFileSync as e,statSync as t}from"node:fs";import{dirname as n,extname as r,join as i,relative as a,resolve as o}from"node:path";import{stripTrailingSlash as s}from"../render/dev-css-select.js";export{matchPathPattern,selectDevCssHrefs}from"../render/dev-css-select.js";const c=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mjs`,`.cjs`,`.vue`,`.svelte`,`.mdx`,`.md`,`.css`,`.scss`,`.sass`,`.less`,`.styl`,`.stylus`],l=new Set([`.css`,`.scss`,`.sass`,`.less`,`.styl`,`.stylus`]),u=c.map(e=>`index${e}`),d=/(?:from|import)\s+['"]([^'"]+)['"]/g,f=/import\s*\(\s*['"]([^'"]+)['"]\s*\)/g,p=/@import\s+(?:url\s*\(\s*)?['"]([^'"]+)['"]/g;function m(e){return l.has(r(e.split(`?`)[0]).toLowerCase())}function h(e,t){let n=a(e,t).replaceAll(`\\`,`/`);return n.startsWith(`/`)?n:`/${n}`}function g(e){let n=e.split(`?`)[0];try{if(!t(n).isFile())return null}catch{return null}return n}function _(e){for(let t of e){let e=g(t);if(e)return e}return null}export function resolveProjectImport(e,t,a){let s=t.split(`?`)[0].split(`#`)[0];if(!s||/^(https?:|data:|virtual:)/i.test(s)||s.startsWith(`\0`)||!(s.startsWith(`.`)||s.startsWith(`/`)))return null;let l=s.startsWith(`/`)?i(a,s.slice(1)):o(n(e),s);return g(l)||(r(l)?null:_([...c.map(e=>l+e),...u.map(e=>i(l,e))]))}function v(e,t){return[...e.matchAll(t)].flatMap(e=>e[1]?[e[1]]:[])}function y(e,t){return t?v(e,p):[...v(e,d),...v(e,f),...v(e,p)]}function b(e){return e.includes(`/node_modules/`)||e.includes(`\\node_modules\\`)}function x(t){try{return e(t,`utf8`)}catch{return null}}export function collectCssHrefsFromEntry(e,t){let n=[],r=new Set,i=[o(e)];for(;i.length>0;){let e=i.pop();if(!e||r.has(e)||b(e))continue;r.add(e);let a=x(e);if(a===null)continue;let o=m(e);o&&n.push(h(t,e));for(let n of y(a,o)){let a=resolveProjectImport(e,n,t);a&&!r.has(a)&&i.push(a)}}return S(n)}function S(e){return[...new Set(e)]}function C(...e){return S(e.flat())}function w(e,t){if(t===`/`)return!0;let n=s(e),r=s(t);return n===r||n.startsWith(`${r}/`)}function T(e,t){let n=[];for(let r of t){let t=r.startsWith(`/`)?r:`/${r}`,i=g(o(e,t.slice(1)));if(i){n.push(...collectCssHrefsFromEntry(i,e));continue}n.push(t)}return S(n)}function E(e,t,n,r){let i=collectCssHrefsFromEntry(e.filePath,t),a=r.filter(t=>w(e.pattern,t.prefix)),o=a.some(e=>!e.isRoot&&e.skipRoot),s=a.filter(e=>!(e.isRoot&&o)).flatMap(e=>e.hrefs);return{pattern:e.pattern,pageHrefs:C(n,i),hrefs:C(n,s,i)}}export function buildDevCssRouteTable(e){let t=T(e.cwd,e.globalCSS),n=e.layouts.map(t=>({...t,hrefs:collectCssHrefsFromEntry(t.filePath,e.cwd)}));return{globalHrefs:t,fallbackHrefs:C(t,C(...n.filter(e=>e.isRoot).map(e=>e.hrefs))),routes:e.routes.map(r=>E(r,e.cwd,t,n))}}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Dev CSS HMR is owned by Avalon, not Vite's link rewriter or Nitro's
3
+ * document reload.
4
+ *
5
+ * Pipeline:
6
+ * 1. SSR injects `<link rel="stylesheet" href="…?direct">`.
7
+ * 2. `hotUpdate` returns [] so Vite does not css-update and Nitro does not
8
+ * treat SSR-only CSS as a document reload.
9
+ * 3. Hard-invalidate the file (and `?direct`) in every environment, then
10
+ * transform with `?direct&v=` — Vite strips `t=<13 digits>`.
11
+ * 4. Send `{ href, css }` on the client hot channel. The client writes `css`
12
+ * into a `<style data-avalon-css>` tag (does not refetch the link).
13
+ */
14
+ import type { Plugin, ViteDevServer } from "vite";
15
+ export declare function isCssHotFile(file: string): boolean;
16
+ export declare function fileToDevHref(root: string, file: string): string;
17
+ export declare function isBrowserFullReloadPayload(payload: unknown): boolean;
18
+ /**
19
+ * Drop only the document reload that is correlated with this CSS save.
20
+ * Unrelated JS / HTML / config reloads in the same 250 ms window still pass.
21
+ */
22
+ export declare function isCssCorrelatedReload(payload: unknown): boolean;
23
+ /** Drop a document reload that Nitro emits for server-only CSS modules. */
24
+ export declare function shouldDropCssFullReload(cssSaveInFlight: boolean, payload: unknown): boolean;
25
+ /**
26
+ * One in-flight CSS push per file. A save while that push is running is
27
+ * marked pending; when the active push settles, one follow-up runs for
28
+ * the latest CSS.
29
+ */
30
+ export declare function scheduleCssPush(file: string, pushing: Set<string>, pending: Set<string>, run: (file: string) => Promise<void>): void;
31
+ /** Standalone client listener. Nitro HTML never runs `transformIndexHtml`. */
32
+ export declare function generateDevCssHmrModule(): string;
33
+ export declare function createDevCssHmrPlugin(): Plugin;
34
+ export declare function invalidateCssFile(server: ViteDevServer, file: string): void;
35
+ export declare function cssHotPayload(href: string, css: string): {
36
+ type: "custom";
37
+ event: "avalon:css";
38
+ data: {
39
+ href: string;
40
+ css: string;
41
+ };
42
+ };
@@ -0,0 +1,2 @@
1
+ import{relative as e}from"node:path";import{readDirectCss as t}from"../render/collect-css.js";const n=/\.(css|scss|sass|less|styl|stylus)$/;export function isCssHotFile(e){return n.test(e.split(`?`)[0]??e)}export function fileToDevHref(t,n){let r=e(t,n).replaceAll(`\\`,`/`);return r.startsWith(`/`)?r:`/${r}`}export function isBrowserFullReloadPayload(e){return!e||typeof e!=`object`?!1:e.type===`full-reload`}function o(e){let t=e.path;return typeof t==`string`?t:``}function s(e){let t=e.triggeredBy;return typeof t==`string`?t:``}export function isCssCorrelatedReload(e){if(!e||typeof e!=`object`)return!1;let t=s(e);if(t)return isCssHotFile(t);let n=o(e);return!n||n===`*`?!0:isCssHotFile(n)}export function shouldDropCssFullReload(e,t){return e&&isBrowserFullReloadPayload(t)&&isCssCorrelatedReload(t)}export function scheduleCssPush(e,t,n,r){if(t.has(e)){n.add(e);return}t.add(e),r(e).finally(()=>{t.delete(e),n.has(e)&&(n.delete(e),scheduleCssPush(e,t,n,r))})}export function generateDevCssHmrModule(){return[`if (import.meta.hot) {`,` import.meta.hot.on('avalon:css', function (data) {`,` if (!data || typeof data.href !== 'string') return;`,` var href = data.href.split('?')[0];`,` var id = href.charAt(0) === '/' ? href : '/' + href;`,` var css = typeof data.css === 'string' ? data.css : '';`,` var links = document.querySelectorAll('link[data-avalon-css]');`,` for (var i = 0; i < links.length; i++) {`,` if (links[i].getAttribute('data-avalon-css') === id) {`,` links[i].href = id + '?direct&v=' + Date.now();`,` }`,` }`,` if (!css || css.indexOf('__vite__updateStyle') !== -1 || css.indexOf('import.meta.hot') !== -1) return;`,` var style;`,` var nodes = document.querySelectorAll('style[data-avalon-css]');`,` for (var j = 0; j < nodes.length; j++) {`,` if (nodes[j].getAttribute('data-avalon-css') === id) { style = nodes[j]; break; }`,` }`,` if (!style) {`,` style = document.createElement('style');`,` style.setAttribute('type', 'text/css');`,` style.setAttribute('data-avalon-css', id);`,` document.head.appendChild(style);`,` }`,` style.textContent = css;`,` });`,`}`,``].join(`
2
+ `)}export function createDevCssHmrPlugin(){let e=!1,t,n=new Set,i=new Set,a=()=>{e=!0,t!==void 0&&clearTimeout(t),t=setTimeout(()=>{e=!1,t=void 0},250)};return{name:`avalon:dev-css-hmr`,apply:`serve`,enforce:`pre`,applyToEnvironment:()=>!0,configureServer(t){return()=>{let n=t.ws.send.bind(t.ws);t.ws.send=((...t)=>{if(!shouldDropCssFullReload(e,t[0]))return n(...t)})}},hotUpdate({file:e,server:t}){if(isCssHotFile(e))return a(),scheduleCssPush(e,n,i,e=>d(t,e)),[]}}}function c(e,t,n){let r=new Set(e.getModulesByFile?.(t)??[]);for(let t of n){let n=e.getModuleById?.(t);n&&r.add(n);let i=e.urlToModuleMap?.get(t);i&&r.add(i)}return r}function l(e,t){let n=e._pendingRequests;if(n)for(let e of t)n.delete(e)}export function invalidateCssFile(e,t){let n=e.config?.root?fileToDevHref(e.config.root,t):``,r=n?[n,`${n}?direct`]:[];for(let n of Object.values(e.environments??{})){let e=n.moduleGraph;for(let n of c(e,t,r))e.invalidateModule(n);l(n,r)}}export function cssHotPayload(e,t){return{type:`custom`,event:`avalon:css`,data:{href:e,css:t}}}function u(e,t,n){let r=cssHotPayload(t,n),i=new Set,a=e=>{!e||i.has(e)||(i.add(e),e.send(r))};a(e.ws),a(e.environments?.client?.hot)}async function d(e,n){invalidateCssFile(e,n);let r=fileToDevHref(e.config.root,n),a=await t(e,r);u(e,r,a),e.config.logger.info(`css hmr ${r} (${a.length}b)`,{timestamp:!0})}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Vite's default CSS-module hash includes file contents. After a save, the
3
+ * Nitro page still exports the previous class names while `?direct` CSS uses
4
+ * new hashes — the document looks unstyled. Dev hashes only the file path
5
+ * and local name so a value edit keeps the same selectors.
6
+ */
7
+ export declare function stableDevScopedName(name: string, filename: string): string;
8
+ export declare function shouldSetDevScopedName(modules: unknown): boolean;
@@ -0,0 +1 @@
1
+ import{createHash as e}from"node:crypto";import{basename as t}from"node:path";export function stableDevScopedName(n,r){let i=(r.split(`?`)[0]??r).replaceAll(`\\`,`/`),a=e(`sha1`).update(`${i}\0${n}`).digest(`hex`).slice(0,5);return`_${t(i).replace(/\.module\.\w+$/,``).replace(/[^\w-]/g,`_`)}_${n.replace(/[^\w-]/g,`_`)}_${a}`}export function shouldSetDevScopedName(e){return e===!1?!1:e&&typeof e==`object`&&`generateScopedName`in e?e.generateScopedName==null:!0}
@@ -19,6 +19,7 @@ export declare const VIRTUAL_MODULE_IDS: {
19
19
  readonly ASSETS: "virtual:avalon/assets";
20
20
  readonly RENDERER: "virtual:avalon/renderer";
21
21
  readonly CLIENT_ENTRY: "virtual:avalon/client-entry";
22
+ readonly DEV_CSS_HMR: "virtual:avalon/dev-css-hmr";
22
23
  readonly INTEGRATION_LOADER: "virtual:avalon/integration-loader";
23
24
  readonly ACTIONS: "virtual:avalon/actions";
24
25
  };
@@ -32,6 +33,7 @@ export declare const RESOLVED_VIRTUAL_IDS: {
32
33
  readonly ASSETS: "\0virtual:avalon/assets";
33
34
  readonly RENDERER: "\0virtual:avalon/renderer";
34
35
  readonly CLIENT_ENTRY: "\0virtual:avalon/client-entry";
36
+ readonly DEV_CSS_HMR: "\0virtual:avalon/dev-css-hmr";
35
37
  readonly INTEGRATION_LOADER: "\0virtual:avalon/integration-loader";
36
38
  readonly ACTIONS: "\0virtual:avalon/actions";
37
39
  };
@@ -1,31 +1,31 @@
1
- import{existsSync as e,readdirSync as t,readFileSync as n,rmSync as r}from"node:fs";import{stat as i}from"node:fs/promises";import{createRequire as a}from"node:module";import{dirname as o,join as s,relative as c,resolve as l}from"node:path";import{nitro as u}from"nitro/vite";import{isRunnableDevEnvironment as d}from"vite";import{generateActionTypes as f}from"../build/actions-types-generator.js";import{createCronDevSchedulerPlugin as p}from"../cron/dev-scheduler.js";import{getUniversalCSSForHead as m}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as h,injectSolidHydrationScriptIfNeeded as g}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as _,discoverScopedMiddleware as v,executeScopedMiddleware as y}from"../middleware/index.js";import{createNitroConfig as b}from"../nitro/config.js";import{createIslandManifestPlugin as x,createNitroBuildPlugin as S,createSourceMapConfig as C,createSourceMapPlugin as w}from"../nitro/index.js";import{collectCssFromModuleGraph as T,injectSsrCss as E}from"../render/collect-css.js";import{generateErrorPage as D,generateFallback404 as O}from"../render/error-pages.js";import{generateComponentId as ee}from"../server-islands/manifest.js";import{resolveToRelativePath as te}from"./server-islands-plugin.js";function ne(e){let t=se(e),r=Object.entries(t),i=`export const serverIslandManifest = ${JSON.stringify(t)};\n\n`;i+=`export const serverIslandLoaders = {
1
+ import{existsSync as e,readdirSync as t,readFileSync as n,rmSync as r}from"node:fs";import{stat as i}from"node:fs/promises";import{createRequire as a}from"node:module";import{dirname as o,join as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{generateActionTypes as u}from"../build/actions-types-generator.js";import{createCronDevSchedulerPlugin as d}from"../cron/dev-scheduler.js";import{getUniversalCSSForHead as f}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as p,injectSolidHydrationScriptIfNeeded as m}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as h,discoverScopedMiddleware as g,executeScopedMiddleware as _}from"../middleware/index.js";import{createNitroConfig as v}from"../nitro/config.js";import{createIslandManifestPlugin as y,createNitroBuildPlugin as b,createSourceMapConfig as x,createSourceMapPlugin as S}from"../nitro/index.js";import{collectCssFromModuleGraph as C,injectSsrCss as w}from"../render/collect-css.js";import{generateErrorPage as T,generateFallback404 as E}from"../render/error-pages.js";import{generateComponentId as D}from"../server-islands/manifest.js";import{buildDevCssRouteTable as O}from"./dev-css-graph.js";import{createDevCssHmrPlugin as ee,generateDevCssHmrModule as te}from"./dev-css-hmr.js";import{resolveToRelativePath as ne}from"./server-islands-plugin.js";function re(e){let t=ce(e),r=Object.entries(t),i=`export const serverIslandManifest = ${JSON.stringify(t)};\n\n`;i+=`export const serverIslandLoaders = {
2
2
  `;for(let[e,t]of r)i+=` ${JSON.stringify(e)}: () => import(${JSON.stringify(t)}),\n`;i+=`};
3
3
 
4
- `;let a={};for(let[t,i]of r)if(i.endsWith(`.svelte`))try{let r=n(s(e,i.startsWith(`/`)?i.slice(1):i),`utf8`).match(/<style[^>]*>([\s\S]*?)<\/style>/);r&&(a[t]=r[1].trim())}catch{}return i+=`export const serverIslandCSS = ${JSON.stringify(a)};\n`,i}function k(e,t){return new Promise((n,r)=>{let i=[],a=e=>i.push(e),o=()=>{l(),n(Buffer.concat(i).toString(`utf8`))},s=e=>{l(),r(e)},c=setTimeout(()=>{l(),r(Error(t))},15e3);function l(){clearTimeout(c),e.off(`data`,a),e.off(`end`,o),e.off(`error`,s)}e.on(`data`,a),e.on(`end`,o),e.on(`error`,s)})}const A=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,re=new Set([`node_modules`,`dist`,`.output`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`,`.git`]);function ie(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}function ae(e,t){return!(!/\.(tsx|jsx)$/.test(e)||/\.(test|spec)\.[jt]sx$/.test(e)||t.includes(`__tests__`))}function j(e,n){let r;try{r=t(e,{withFileTypes:!0})}catch{return}for(let t of r){let r=s(e,t.name);t.isDirectory()?re.has(t.name)||j(r,n):t.isFile()&&ae(t.name,r)&&n.push(r)}}function oe(e,t,n,r){A.lastIndex=0;let i=A.exec(t);for(;i!==null;i=A.exec(t)){let a=i[1],o=i[2].slice(1,-1);if(!ie(t,a))continue;let s=te(o,e,n),c=ee(s);c in r||(r[c]=s)}}function se(t){let r={},i=[];for(let n of[`app`,`src`]){let r=s(t,n);e(r)&&j(r,i)}for(let e of i){let i;try{i=n(e,`utf8`)}catch{continue}/\bserver\s*[={/>]/.test(i)&&oe(e,i,t,r)}return r}function M(t){let n=[`ts`,`tsx`,`js`,`jsx`,`mts`,`mjs`];for(let r of[`app`,`src`])for(let i of n){let n=`/${r}/actions/index.${i}`;if(e(s(t,n.slice(1))))return n}}function ce(e){let t=M(e);return t?`export { server } from ${JSON.stringify(t)};\n`:`export const server = {};
5
- `}function le(){return[`import { createActionClient } from "@useavalon/avalon/actions";`,`export const actions = createActionClient();`,`export default actions;`,``].join(`
6
- `)}function ue(e,t){try{let n;if(e.startsWith(`dev.`)){let t=e.slice(4);n=Buffer.from(t,`base64url`).toString(`utf8`)}else n=t(e);let r=JSON.parse(n),i,a;return r.__island&&(i=r.__island,delete r.__island),r.__src&&(a=r.__src,delete r.__src),{ok:!0,props:r,srcPath:a,islandMeta:i}}catch{return{ok:!1}}}function de(e,t,n,r){let i=e.split(`/`)[2]?.split(`?`)[0]||``,a=t.elementId??`si-${i}`,o=t.componentSrc??n,s=JSON.stringify(r),c=t.condition??`on:client`,l=t.framework??`preact`;return`<script type="module">
4
+ `;let a={};for(let[t,i]of r)if(i.endsWith(`.svelte`))try{let r=n(s(e,i.startsWith(`/`)?i.slice(1):i),`utf8`).match(/<style[^>]*>([\s\S]*?)<\/style>/);r&&(a[t]=r[1].trim())}catch{}return i+=`export const serverIslandCSS = ${JSON.stringify(a)};\n`,i}function k(e,t){return new Promise((n,r)=>{let i=[],a=e=>i.push(e),o=()=>{l(),n(Buffer.concat(i).toString(`utf8`))},s=e=>{l(),r(e)},c=setTimeout(()=>{l(),r(Error(t))},15e3);function l(){clearTimeout(c),e.off(`data`,a),e.off(`end`,o),e.off(`error`,s)}e.on(`data`,a),e.on(`end`,o),e.on(`error`,s)})}const A=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,ie=new Set([`node_modules`,`dist`,`.output`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`,`.git`]);function ae(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}function oe(e,t){return!(!/\.(tsx|jsx)$/.test(e)||/\.(test|spec)\.[jt]sx$/.test(e)||t.includes(`__tests__`))}function j(e,n){let r;try{r=t(e,{withFileTypes:!0})}catch{return}for(let t of r){let r=s(e,t.name);t.isDirectory()?ie.has(t.name)||j(r,n):t.isFile()&&oe(t.name,r)&&n.push(r)}}function se(e,t,n,r){A.lastIndex=0;let i=A.exec(t);for(;i!==null;i=A.exec(t)){let a=i[1],o=i[2].slice(1,-1);if(!ae(t,a))continue;let s=ne(o,e,n),c=D(s);c in r||(r[c]=s)}}function ce(t){let r={},i=[];for(let n of[`app`,`src`]){let r=s(t,n);e(r)&&j(r,i)}for(let e of i){let i;try{i=n(e,`utf8`)}catch{continue}/\bserver\s*[={/>]/.test(i)&&se(e,i,t,r)}return r}function M(t){let n=[`ts`,`tsx`,`js`,`jsx`,`mts`,`mjs`];for(let r of[`app`,`src`])for(let i of n){let n=`/${r}/actions/index.${i}`;if(e(s(t,n.slice(1))))return n}}function le(e){let t=M(e);return t?`export { server } from ${JSON.stringify(t)};\n`:`export const server = {};
5
+ `}function ue(){return[`import { createActionClient } from "@useavalon/avalon/actions";`,`export const actions = createActionClient();`,`export default actions;`,``].join(`
6
+ `)}function de(e,t){try{let n;if(e.startsWith(`dev.`)){let t=e.slice(4);n=Buffer.from(t,`base64url`).toString(`utf8`)}else n=t(e);let r=JSON.parse(n),i,a;return r.__island&&(i=r.__island,delete r.__island),r.__src&&(a=r.__src,delete r.__src),{ok:!0,props:r,srcPath:a,islandMeta:i}}catch{return{ok:!1}}}function fe(e,t,n,r){let i=e.split(`/`)[2]?.split(`?`)[0]||``,a=t.elementId??`si-${i}`,o=t.componentSrc??n,s=JSON.stringify(r),c=t.condition??`on:client`,l=t.framework??`preact`;return`<script type="module">
7
7
  import{hydrateServerIsland}from"/@fs${N(`src/client/server-island-hydrate.ts`)}";
8
8
  hydrateServerIsland(${JSON.stringify(a)},${JSON.stringify(o)},${s},${JSON.stringify(c)},${JSON.stringify(l)});
9
- <\/script>`}function N(t){let n=s(o(a(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function fe(t,n){let r=s(o(a(s(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`,ACTIONS:`virtual:avalon/actions`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`,ACTIONS:`\0${VIRTUAL_MODULE_IDS.ACTIONS}`};function pe(e){return e===`react`?[]:[/^react/,/^react-dom/]}function me(e){return e===`react`?[`import { createElement as h } from 'react';`,`import { renderToString as preactRenderToString } from 'react-dom/server';`]:[`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`]}function he(e){return e===`react`?[`import { setShellRenderToString, setShellElementFactory } from '@useavalon/avalon/render/shell-engine';`,`import { renderToString as __reactRenderToString } from 'react-dom/server';`,`import { createElement as __reactCreateElement, Fragment as __reactFragment } from 'react';`,`setShellRenderToString((vnode) => __reactRenderToString(vnode));`,`setShellElementFactory(__reactCreateElement, __reactFragment);`]:[]}function ge(e){return e===`react`?`@useavalon/react/client`:`@useavalon/preact/client`}function _e(e){let t=N(`src/core/integrations/registry.ts`),n=[`solid`,`vue`,`svelte`,`lit`].filter(t=>e.includes(t));return`${[`import { registry } from "${t}";`,...n.map(e=>`import { ${e}Integration } from "@useavalon/${e}";`),...n.map(e=>`if (${e}Integration) registry.register(${e}Integration);`)].join(`
10
- `)}\n`}export function createNitroIntegration(e,t={}){let n=b(t,e),r=process.cwd(),i=N(`src/server-islands/route.ts`),a=N(`src/actions/route.ts`),o={preset:n.preset,serverDir:t.serverDir??n.serverDir??`./server`,routeRules:n.routeRules,runtimeConfig:n.runtimeConfig,compatibilityDate:n.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...pe(e.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>ne(r),"virtual:avalon-actions-manifest":()=>ce(r),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>_e(e.integrations)}};t.renderer===!1?o.renderer=!1:n.renderer&&(o.renderer=n.renderer),n.publicRuntimeConfig&&(o.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(o.publicAssets=n.publicAssets),n.compressPublicAssets&&(o.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(o.serverEntry=n.serverEntry);let s=process.argv.includes(`build`)||process.env.NODE_ENV===`production`;n.experimentalTasks&&s&&(o.experimental={...o.experimental,tasks:!0},n.tasks&&Object.keys(n.tasks).length>0&&(o.tasks=n.tasks),n.scheduledTasks&&Object.keys(n.scheduledTasks).length>0&&(o.scheduledTasks=n.scheduledTasks));let c=n.traceDeps??[];o.traceDeps=[...new Set([`undici`,...c])],n.prerender&&(o.prerender={routes:[],crawlLinks:!1});let l=u(o),d=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),f=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),m=S(e,t),h=x(e,{verbose:e.verbose,generatePreloadHints:!0}),g=w(C(t.preset??`node_server`,e.isDev)),_=p(t.cron,e.verbose);return{nitroOptions:n,plugins:[...Array.isArray(l)?l:[l],d,f,m,h,g,_]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{f(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{f(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let l=!1,u=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||l?(l=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{l=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(l)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await u,n()});let p=null;async function m(){return p||=await v({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}Se(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let g=e.environments?.ssr,_=!!g&&d(g);_&&be(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!_)return i();try{let{decrypt:i}=await e.ssrLoadModule(N(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await H(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await k(n,`Timed out reading server island request body`)),!c){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Missing encrypted props`);return}let l=ue(c,i);if(!l.ok){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Bad Request: decryption failed`);return}let{props:u,srcPath:d,islandMeta:f}=l;if(!d){r.statusCode=404,r.setHeader(`Content-Type`,`text/plain`),r.end(`Component not found (no __src in payload)`);return}let p=(await e.ssrLoadModule(d)).default;if(typeof p!=`function`){r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Module "${d}" does not export a default component function`);return}let m=s(o(p,u));f&&(m+=de(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!_)return r();try{let r=M(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(N(`src/actions/endpoint.ts`)),e.ssrLoadModule(N(`src/actions/registry.ts`)),r?e.ssrLoadModule(r):Promise.resolve({server:{}})]),c=o.flattenActions(s.server),l=a.defineActionHandler({registry:c,isDev:!0}),u=new URL(i,`http://${t.headers.host||`localhost`}`),d=(t.method||`GET`).toUpperCase(),f;d===`POST`&&(f=await k(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!_)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await ve(e,o,r,i,m,n)||await Be(e,o,t,i))return;let a=await Ve(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await ye(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(D(e))}})},buildStart(){}}}async function ve(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await y({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function ye(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(O(t))}}async function be(e,t,n){let r=performance.now(),i=[{path:N(`src/render/ssr.ts`),assignTo:`ssr`},{path:N(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:N(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:fe(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(B=r),n===`layout`&&(V=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:n,nitroConfig:r,verbose:i}=e,a=null,o=s,u=c,d=l,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=o(e,t.name);if(t.isDirectory()&&t.name!==`node_modules`&&!t.name.startsWith(`.`))m(n);else if(t.isFile()&&t.name.endsWith(`.css`)){let e=u(f,n).replaceAll(`\\`,`/`);p.push(e.startsWith(`/`)?e:`/${e}`)}}}catch{}}function h(){p.length=0;for(let e of r.globalCSS??[])p.push(e.startsWith(`/`)?e:`/${e}`);n.modules&&m(d(f,n.modules.dir)),m(d(f,n.layoutsDir));let e=d(f,n.layoutsDir,`..`);e!==f&&e!==d(f,n.layoutsDir)&&e.startsWith(f)&&m(e)}return n.isDev&&h(),{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await Ce(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await we(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?Te():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?Ee(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(a||=await De(n,r,p),a):e===RESOLVED_VIRTUAL_IDS.ASSETS?Oe(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?ke(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await Me(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):e===RESOLVED_VIRTUAL_IDS.ACTIONS?le():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:i,isCss:o}=R(e);(n||r||i||o)&&(n&&(F(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(t)),i&&(a=null,h(),P(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),P(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY)),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),xe(e)&&P(t,RESOLVED_VIRTUAL_IDS.CONFIG)}}}function P(e,t){let n=e.moduleGraph.getModuleById(t);n&&e.moduleGraph.invalidateModule(n)}function F(e,t){P(e,t);let n=e.environments;if(n)for(let e of Object.values(n)){let n=e.moduleGraph;if(n)try{let e=n.getModuleById(t);e&&n.invalidateModule(e)}catch{}}}async function I(e){let t=e.environments?.nitro;if(t)try{t.devServer?.sendMessage?.({type:`full-reload`}),await t.devServer?.reloadRoutes?.()}catch{}}function L(e){F(e,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(e,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(e),setTimeout(()=>{e.ws.send({type:`full-reload`,path:`*`})},500)}function R(e){let t=e.endsWith(`.css`);return{isPage:e.includes(`/pages/`)&&!t,isComponent:e.includes(`/components/`)&&/\.[tj]sx?$/.test(e),isLayout:(e.includes(`/layouts/`)||e.includes(`_layout`))&&/\.[tj]sx?$/.test(e),isCss:t}}function xe(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function Se(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(_(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(B=null,V=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)})}export function isPageFile(e){return R(e).isPage}async function Ce(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
9
+ <\/script>`}function N(t){let n=s(o(a(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function pe(t,n){let r=s(o(a(s(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,DEV_CSS_HMR:`virtual:avalon/dev-css-hmr`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`,ACTIONS:`virtual:avalon/actions`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,DEV_CSS_HMR:`\0${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`,ACTIONS:`\0${VIRTUAL_MODULE_IDS.ACTIONS}`};function me(e){return e===`react`?[]:[/^react/,/^react-dom/]}function he(e){return e===`react`?[`import { createElement as h } from 'react';`,`import { renderToString as preactRenderToString } from 'react-dom/server';`]:[`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`]}function ge(e){return e===`react`?[`import { setShellRenderToString, setShellElementFactory } from '@useavalon/avalon/render/shell-engine';`,`import { renderToString as __reactRenderToString } from 'react-dom/server';`,`import { createElement as __reactCreateElement, Fragment as __reactFragment } from 'react';`,`setShellRenderToString((vnode) => __reactRenderToString(vnode));`,`setShellElementFactory(__reactCreateElement, __reactFragment);`]:[]}function _e(e){return e===`react`?`@useavalon/react/client`:`@useavalon/preact/client`}function ve(e){let t=N(`src/core/integrations/registry.ts`),n=[`solid`,`vue`,`svelte`,`lit`].filter(t=>e.includes(t));return`${[`import { registry } from "${t}";`,...n.map(e=>`import { ${e}Integration } from "@useavalon/${e}";`),...n.map(e=>`if (${e}Integration) registry.register(${e}Integration);`)].join(`
10
+ `)}\n`}function ye(e,t,n,r,i,a){let o={preset:e.preset,serverDir:t.serverDir??e.serverDir??`./server`,routeRules:e.routeRules,runtimeConfig:e.runtimeConfig,compatibilityDate:e.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...me(r.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>re(n),"virtual:avalon-actions-manifest":()=>le(n),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>ve(r.integrations)},traceDeps:[...new Set([`undici`,...e.traceDeps??[]])]};return be(o,e,t),o}function be(e,t,n){n.renderer===!1?e.renderer=!1:t.renderer&&(e.renderer=t.renderer),t.publicRuntimeConfig&&(e.publicRuntimeConfig=t.publicRuntimeConfig),t.publicAssets&&(e.publicAssets=t.publicAssets),t.compressPublicAssets&&(e.compressPublicAssets=t.compressPublicAssets),t.serverEntry&&(e.serverEntry=t.serverEntry);let r=process.argv.includes(`build`)||process.env.NODE_ENV===`production`;t.experimentalTasks&&r&&(e.experimental={...e.experimental,tasks:!0},t.tasks&&Object.keys(t.tasks).length>0&&(e.tasks=t.tasks),t.scheduledTasks&&Object.keys(t.scheduledTasks).length>0&&(e.scheduledTasks=t.scheduledTasks)),t.prerender&&(e.prerender={routes:[],crawlLinks:!1})}export function createNitroIntegration(e,t={}){let n=v(t,e),r=c(ye(n,t,process.cwd(),e,N(`src/server-islands/route.ts`),N(`src/actions/route.ts`))),i=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),a=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),o=b(e,t),s=y(e,{verbose:e.verbose,generatePreloadHints:!0}),l=S(x(t.preset??`node_server`,e.isDev)),u=d(t.cron,e.verbose);return{nitroOptions:n,plugins:[ee(),...Array.isArray(r)?r:[r],i,a,o,s,l,u]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{u(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{u(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let d=!1,f=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||d?(d=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{d=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(d)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await f,n()});let p=null;async function m(){return p||=await g({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}Te(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let _=e.environments?.ssr,v=!!_&&l(_);v&&Ce(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!v)return i();try{let{decrypt:i}=await e.ssrLoadModule(N(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await H(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await k(n,`Timed out reading server island request body`)),!c){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Missing encrypted props`);return}let l=de(c,i);if(!l.ok){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Bad Request: decryption failed`);return}let{props:u,srcPath:d,islandMeta:f}=l;if(!d){r.statusCode=404,r.setHeader(`Content-Type`,`text/plain`),r.end(`Component not found (no __src in payload)`);return}let p=(await e.ssrLoadModule(d)).default;if(typeof p!=`function`){r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Module "${d}" does not export a default component function`);return}let m=s(o(p,u));f&&(m+=fe(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!v)return r();try{let r=M(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(N(`src/actions/endpoint.ts`)),e.ssrLoadModule(N(`src/actions/registry.ts`)),r?e.ssrLoadModule(r):Promise.resolve({server:{}})]),c=o.flattenActions(s.server),l=a.defineActionHandler({registry:c,isDev:!0}),u=new URL(i,`http://${t.headers.host||`localhost`}`),d=(t.method||`GET`).toUpperCase(),f;d===`POST`&&(f=await k(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!v)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await xe(e,o,r,i,m,n)||await Ue(e,o,t,i))return;let a=await We(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await Se(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(T(e))}})},buildStart(){}}}async function xe(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await _({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function Se(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(E(t))}}async function Ce(e,t,n){let r=performance.now(),i=[{path:N(`src/render/ssr.ts`),assignTo:`ssr`},{path:N(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:N(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:pe(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(B=r),n===`layout`&&(V=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e,i=null;return{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.DEV_CSS_HMR?RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await Ee(t,r):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await De(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?Oe():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?ke(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(i||=await Ae(t,n),i):e===RESOLVED_VIRTUAL_IDS.ASSETS?je(n):e===RESOLVED_VIRTUAL_IDS.RENDERER?Me(t):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await Fe(t,n):e===RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR?te():e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(t):e===RESOLVED_VIRTUAL_IDS.ACTIONS?ue():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:a,isCss:o}=R(e);o&&(i=null),n&&(F(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(t)),(n||r||a)&&(i=null,F(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),a&&P(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),we(e)&&P(t,RESOLVED_VIRTUAL_IDS.CONFIG)}}}function P(e,t){let n=e.moduleGraph.getModuleById(t);n&&e.moduleGraph.invalidateModule(n)}function F(e,t){P(e,t);let n=e.environments;if(n)for(let e of Object.values(n)){let n=e.moduleGraph;if(n)try{let e=n.getModuleById(t);e&&n.invalidateModule(e)}catch{}}}async function I(e){let t=e.environments?.nitro;if(t)try{t.devServer?.sendMessage?.({type:`full-reload`}),await t.devServer?.reloadRoutes?.()}catch{}}function L(e){F(e,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(e,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(e),setTimeout(()=>{e.ws.send({type:`full-reload`,path:`*`})},500)}function R(e){let t=e.endsWith(`.css`);return{isPage:e.includes(`/pages/`)&&!t,isComponent:e.includes(`/components/`)&&/\.[tj]sx?$/.test(e),isLayout:(e.includes(`/layouts/`)||e.includes(`_layout`))&&/\.[tj]sx?$/.test(e),isCss:t}}function we(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function Te(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(h(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(B=null,V=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&L(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&L(e)})}export function isPageFile(e){return R(e).isPage}async function Ee(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
11
11
  export default pageRoutes;
12
- `}}async function we(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
12
+ `}}async function De(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
13
13
  `),`];`,``,`/**`,` * Match a pathname against discovered routes and return the page module.`,` * Uses the same pattern matching as Avalon's route discovery.`,` */`,`/**`,` * Match a pathname against discovered routes, returning the matched`,` * page module AND the extracted dynamic route params (e.g. { id: "123" }).`,` */`,`export function loadPage(pathname) {`,` const cleanPath = pathname.split('?')[0];`,` for (const route of routes) {`,` const m = matchRoute(cleanPath, route.pattern);`,` if (m.matched) return { module: route.module, params: m.params };`,` }`,` return null;`,`}`,``,`/**`,` * Match one pattern and capture dynamic segments:`,` * /users/:id vs /users/123 -> { id: "123" }`,` * /blog/** vs /blog/a/b -> { slug: "a/b" }`,` */`,`function matchRoute(pathname, pattern) {`,String.raw` const normPath = pathname === '/' ? '/' : pathname.replace(/\/$/, '');`,String.raw` const normPattern = pattern === '/' ? '/' : pattern.replace(/\/$/, '');`,` if (normPath === normPattern) return { matched: true, params: {} };`,` const patternParts = normPattern.split('/');`,` const pathParts = normPath.split('/');`,` const params = {};`,` for (let i = 0; i < patternParts.length; i++) {`,` const seg = patternParts[i];`,` if (seg === '**') {`,` params.slug = pathParts.slice(i).join('/');`,` return { matched: true, params };`,` }`,` if (i >= pathParts.length) return { matched: false, params: {} };`,` if (seg.startsWith(':')) params[seg.slice(1)] = pathParts[i];`,` else if (seg !== pathParts[i]) return { matched: false, params: {} };`,` }`,` if (pathParts.length > patternParts.length) return { matched: false, params: {} };`,` return { matched: true, params };`,`}`,``,`export default { loadPage, routes };`,``].join(`
14
14
  `)}catch(e){return console.error(`[page-loader] Failed to generate page loader:`,e),`export function loadPage() { return null; }
15
15
  export default { loadPage, routes: [] };
16
- `}}function Te(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
16
+ `}}function Oe(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
17
17
  export default islandManifest;
18
- `}function Ee(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`globalThis.__avalonHydrationMode = "${n?`entry-client`:`per-island`}";\nconst config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function De(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:i,resolve:a}=await import(`node:path`),{stat:o,readFile:c}=await import(`node:fs/promises`),l=process.cwd(),u=await r(e.layoutsDir,e.modules,l),d=[],f=0,p=a(l,e.layoutsDir);for(let{dir:t,prefix:n}of u){let r=s(t,`_layout.tsx`);try{if(!(await o(r)).isFile())continue}catch{continue}let a=i(l,r).replaceAll(`\\`,`/`),c=a.startsWith(`/`)?a:`/${a}`,u=t.startsWith(p),m=u&&!e.modules?`RootLayout`:`Layout_${f}`;d.push({prefix:n,importPath:c,varName:m,isShared:u,filePath:r}),f++}let m=d.filter(e=>e.isShared),h=d.filter(e=>!e.isShared),g=new Map;for(let e of h)try{let t=(await c(e.filePath,`utf8`)).match(/layoutConfig\s*=\s*{[\s\S]*?skipLayouts\s*:\s*\[([^\]]*)\]/)?.[1]??``,n=/['"`]_layout['"`]/.test(t);g.set(e.importPath,n)}catch{g.set(e.importPath,!1)}let _=d.map(e=>`import ${e.varName} from '${e.importPath}';`),v=h.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`,n=g.get(e.importPath)??!1,r=t||n;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${r} }`}),y=m.length>0?m[0].varName:`null`,b=JSON.stringify(n);return[`// Auto-generated by Avalon — do not edit`,...me(e.core),`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,..._,``,`const RootLayoutComponent = ${y};`,`const _cssLinks = ${b};`,``,`const moduleLayouts = [`,v.join(`,
19
- `),`];`,``,`function getLayoutsForPath(pathname) {`,` for (const entry of moduleLayouts) {`,` if (entry.prefix === '/' ? pathname === '/' : pathname.startsWith(entry.prefix)) {`,` return entry;`,` }`,` }`,` return null;`,`}`,``,`function injectUniversalAssets(html) {`,` // In dev, inject <link> tags for all discovered CSS files.`,` // The ?direct suffix makes Vite return raw CSS (text/css) instead`,` // of a JS module wrapper, so <link rel="stylesheet"> works.`,` if (process.env.NODE_ENV !== 'production' && _cssLinks.length > 0) {`,` var links = _cssLinks.map(function(href) {`,` return '<link rel="stylesheet" href="' + href + '?direct">';`,String.raw` }).join('\n');`,` if (html.includes('</head>')) {`,String.raw` html = html.replace('</head>', links + '\n</head>');`,` }`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalCSS + '\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalHead + '\n</head>');`,` }`,` html = injectSolidHydrationScriptIfNeeded(html);`,` return html;`,`}`,``,`export async function wrapWithLayouts(pageHtml, pageModule, context, injectAssets) {`,` const pathname = context.url.pathname;`,` const frontmatter = {`,` ...(pageModule.frontmatter || {}),`,` ...(pageModule.metadata || {}),`,` currentPath: pathname,`,` };`,` const pageLayoutConfig = pageModule.layoutConfig;`,` const skipAll = pageLayoutConfig?.skipLayouts?.includes('_layout');`,``,` const layoutEntry = getLayoutsForPath(pathname);`,` const routeInfo = { path: pathname, params: context.params, query: context.url.searchParams };`,` let html;`,``,` if (!layoutEntry || skipAll) {`,` if (RootLayoutComponent && !skipAll) {`,` const rootProps = {`,` children: h('avalon-page', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,String.raw` html = '<!DOCTYPE html>\n' + preactRenderToString(resolvedRoot);`,` } else {`,` // skipAll is true — page provides its own HTML shell or needs a minimal one`,` if (pageHtml.trimStart().startsWith('<html')) {`,String.raw` html = '<!DOCTYPE html>\n' + pageHtml;`,` } else {`,` const title = String(frontmatter.title || 'Avalon');`,` html = [`,` '<!DOCTYPE html>',`,` '<html lang="en">',`,` '<head>',`,` '<meta charset="utf-8">',`,` '<meta name="viewport" content="width=device-width, initial-scale=1">',`,` '<title>' + title + '</title>',`,` '</head>',`,` '<body>',`,` '<div id="app">' + pageHtml + '</div>',`,` '</body>',`,` '</html>',`,String.raw` ].join('\n');`,` }`,` }`,` } else {`,` const layoutProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const layoutResult = layoutEntry.Layout(layoutProps);`,` const resolvedLayout = layoutResult instanceof Promise ? await layoutResult : layoutResult;`,` let wrappedHtml = preactRenderToString(resolvedLayout);`,``,` // If the layout provides its own HTML shell (starts with <html),`,` // skip root wrapping regardless of skipRoot flag — the layout IS the document.`,` const layoutProvidesShell = wrappedHtml.trimStart().startsWith('<html');`,``,` if (!layoutProvidesShell && !layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: wrappedHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,String.raw` html = '<!DOCTYPE html>\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
20
- `)}function Oe(e){let t=e.clientEntry??`app/entry-client`;return[`// Auto-generated by Avalon — do not edit`,`// @ts-ignore — virtual import resolved by Nitro's Vite assets plugin at build time`,`import clientAssets from '${t.startsWith(`/`)?t:`/${t}`}?assets=client';`,``,`function buildAssetTags() {`,` const cssLinks = (clientAssets?.css ?? [])`,` .filter(attr => {`,` const href = attr.href || '';`,` // The SSR build produces ssr-index-*.css containing all global, reset,`,` // token, and layout CSS module styles. The client build may also emit`,` // entry-client-*.css (a subset) and index-*.css. To avoid duplicates,`,` // prefer ssr-index when it exists; otherwise fall back to the others.`,` var hasSsrIndex = (clientAssets?.css ?? []).some(function(a) { return (a.href || '').includes('ssr-index'); });`,` if (hasSsrIndex) return href.includes('ssr-index');`,` if (href.includes('entry-client') && href.endsWith('.css')) return true;`,String.raw` if (/\/index-[^/]+\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const entryScript = clientAssets?.entry`,` ? '<script type="module" src="' + clientAssets.entry + '"><\/script>'`,` : '';`,` return { cssLinks, jsPreloads, entryScript };`,`}`,``,`export function injectAssets(html) {`,` const { cssLinks, jsPreloads, entryScript } = buildAssetTags();`,` if (html.includes('</head>')) {`,String.raw` html = html.replace('</head>', cssLinks + '\n' + jsPreloads + '\n</head>');`,` }`,` if (html.includes('</body>')) {`,String.raw` html = html.replace('</body>', entryScript + '\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
21
- `)}function ke(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}let i=he(e.core);return[`// Auto-generated by Avalon — do not edit`,`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,...i,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`// Set hydration mode flag — intentionally duplicated from virtual:avalon/config`,`// for module-load-order resilience (config import may be tree-shaken or deferred).`,`globalThis.__avalonHydrationMode = avalonConfig.isDev ? "entry-client" : "per-island";`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const match = loadPage(pathname);`,` if (!match || !('default' in match.module)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: match.params };`,` },`,` loadPageModule: async (filePath) => {`,String.raw` const m = filePath.match(/^\[virtual:(.+)\]$/);`,` const pathname = m ? m[1] : filePath;`,` const match = loadPage(pathname);`,` if (match) return match.module;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
22
- `)}async function Ae(e,t){let{readdir:n}=await import(`node:fs/promises`),{relative:r,join:i}=await import(`node:path`),a=[];for(let{dir:o}of e){let e;try{e=await n(o,{withFileTypes:!0})}catch{continue}for(let n of e){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let e=r(t,i(o,n.name)).replaceAll(`\\`,`/`);a.push(e.startsWith(`/`)?e:`/${e}`)}}return a}function je(e){if(e.length===0)return[];let t=[`// Layout CSS (auto-discovered)`],n=0;for(let r of e)r.includes(`.module.`)?(t.push(`import _lcss${n} from '${r}';`),n++):t.push(`import '${r}';`);return t}async function Me(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),r=process.cwd(),i=await Ae(await n(e.layoutsDir,e.modules,r),r),a=globalThis.__avalonConfig?.isDev??e.isDev?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,o=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?o.push(`import '${a}';`):o.push(`// Per-island hydration mode — no shared runtime needed`),o.push(``);let s=t.globalCSS??[];for(let e of s){let t=e.startsWith(`/`)?e:`/${e}`;o.push(`// Global CSS`,`import '${t}';`)}return s.length>0&&o.push(``),o.push(...je(i),``),o.join(`
23
- `)}function Ne(){return[`// --- Inlined Solid adapter (production) ---`,`// Eliminates a separate chunk + network request for the Solid client adapter.`,`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`,`function _ensureHydrationContext() {`,` if (!globalThis._$HY) {`,` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`,` }`,`}`,``,`async function _solidHydrate(container, Component, props) {`,` if (!container) throw new Error("Container element is required for hydration");`,` if (!Component || typeof Component !== "function") {`,` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`,` }`,` var el = container;`,` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`,` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`,` _ensureHydrationContext();`,` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`,`}`,``,`var _solidModule = { hydrate: _solidHydrate };`,``]}function Pe(e,t,n){let r=[];for(let i of e){let e=t[i];e&&(i===`solid`&&!n?r.push(` case "solid":`,` return _solidModule;`):i===`react`?r.push(` case "react":`):r.push(` case "${i}":`,` return import("${e}");`))}return e.includes(`react`)&&!e.includes(`preact`)&&r.push(` return import("${t.react}");`),r}function Fe(e,t){let n=[];for(let r of e){let e=t[r];e&&n.push(` case "${r}":`,` return import("${e}").then(m => m.${r}Adapter);`)}return n}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:ge(e.core),vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,solid:`@useavalon/solid/client`,lit:`@useavalon/lit/client`,qwik:`@useavalon/qwik/client`},r={preact:`@useavalon/preact/client/hmr`,react:`@useavalon/react/client/hmr`,vue:`@useavalon/vue/client/hmr`,svelte:`@useavalon/svelte/client/hmr`,solid:`@useavalon/solid/client/hmr`,lit:`@useavalon/lit/client/hmr`,qwik:`@useavalon/qwik/client/hmr`},i=t.includes(`lit`),a=t.includes(`solid`),o=(globalThis.__avalonConfig?.isDev??e.isDev)===!0,s=[`// Auto-generated by Avalon — only includes configured integrations`,``];return a&&!o&&s.push(...Ne()),s.push(`// --- loadIntegrationModule ---`,`export async function loadIntegrationModule(framework) {`,` switch (framework) {`,...Pe(t,n,o),` default:`," throw new Error(`Unknown or unconfigured framework: ${framework}`);",` }`,`}`,``,`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?s.push(`export async function preLitHydration() {`,` await import("@useavalon/lit/client");`,`}`):s.push(`export async function preLitHydration() {}`),s.push(``,`// --- HMR adapter loader ---`,`export async function loadHMRAdapter(framework) {`,` switch (framework) {`,...Fe(t,r),` default: return null;`,` }`,`}`),s.join(`
24
- `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const z=`<!--AVALON_STREAM_BOUNDARY-->`;let B=null,V=null;async function H(e,t){if(t===`react`){let e=await import(`react`),t=await import(`react-dom/server`),n=e.default??e,r=t.default??t;return{h:e.createElement??n.createElement,renderToString:t.renderToString??r.renderToString}}let n=await e.ssrLoadModule(`preact`),r=await e.ssrLoadModule(`preact-render-to-string`);return{h:n.h,renderToString:r.render??r.default}}function U(e){return e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``}async function W(e,t,n){let r=[];for(let n of t){let t=await e.ssrLoadModule(n);r.push({file:n,module:t})}for(let r of t){let t=await T(e,r);n.push(...t)}return r}async function G(e,t,n,r){let i=[],a=[];for(let o of e){let e=o.module.default;if(!(!e||typeof e!=`function`))try{let s=e({...t,children:n(`div`,null,`test`)}),c=r(s instanceof Promise?await s:s);c.trim().startsWith(`<html`)||c.includes(`<!DOCTYPE`)?i.push(o):a.push(o)}catch{a.push(o)}}return{shellLayouts:i,wrapperLayouts:a}}async function Ie(e,t,n,r){try{let i=e({...t,children:n(`div`,{dangerouslySetInnerHTML:{__html:z}})});return r(i instanceof Promise?await i:i)}catch{return null}}function Le(e,t){let n=e;if(t.length>0){let e=`<style data-avalon-ssr-css>${t.join(`
25
- `)}</style>`;n.includes(`</head>`)?n=n.replace(`</head>`,`${e}\n</head>`):n+=e}n.trim().toLowerCase().startsWith(`<!doctype`)||(n=`<!DOCTYPE html>\n${n}`);let r=m(!0);r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`));let i=h(!0);return i&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${i}\n</head>`)),g(n)}async function K(e,t,n){try{let n=typeof e==`function`?e():e;return t(n instanceof Promise?await n:n)}catch(e){return console.error(`${n} Error rendering page component:`,e),`<div>Error rendering page</div>`}}async function q(e,t,n,r,i,a){let o=e;for(let{module:e}of t){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:o}})});o=i(e instanceof Promise?await e:e)}catch(e){console.error(`${a} Error rendering wrapper layout:`,e)}}return o}async function Re(e,t,n,r,i){if(t.length===0)return e;let{module:a}=t.at(-1),o=a.default;if(!o||typeof o!=`function`)return e;try{let t=o({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:e}})});return i(t instanceof Promise?await t:t)}catch(t){return console.error(`[SSR] Error rendering shell layout:`,t),e}}function ze(e){if(e.includes(`/src/client/main.js`)||e.includes(`/@vite/client`))return e;let t=e.lastIndexOf(`</body>`);return t===-1?e:e.slice(0,t)+`
18
+ `}function ke(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`globalThis.__avalonHydrationMode = "${n?`entry-client`:`per-island`}";\nconst config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function Ae(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{relative:r,resolve:i}=await import(`node:path`),{stat:a,readFile:o}=await import(`node:fs/promises`),c=process.cwd(),l=await n(e.layoutsDir,e.modules,c),u=[],d=0,f=i(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let i=s(t,`_layout.tsx`);try{if(!(await a(i)).isFile())continue}catch{continue}let o=r(c,i).replaceAll(`\\`,`/`),l=o.startsWith(`/`)?o:`/${o}`,p=t.startsWith(f),m=p&&!e.modules?`RootLayout`:`Layout_${d}`;u.push({prefix:n,importPath:l,varName:m,isShared:p,filePath:i}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=new Map;for(let e of m)try{let t=(await o(e.filePath,`utf8`)).match(/layoutConfig\s*=\s*{[\s\S]*?skipLayouts\s*:\s*\[([^\]]*)\]/)?.[1]??``,n=/['"`]_layout['"`]/.test(t);h.set(e.importPath,n)}catch{h.set(e.importPath,!1)}let g=u.map(e=>`import ${e.varName} from '${e.importPath}';`),_=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`,n=h.get(e.importPath)??!1,r=t||n;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${r} }`}),v=p.length>0?p[0].varName:`null`,y=`{"routes":[],"fallbackHrefs":[],"globalHrefs":[]}`;if(e.isDev){let{getAllPageDirs:n}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:r}=await import(`../nitro/route-discovery.js`),i=await r(await n(e.pagesDir,e.modules,c),{developmentMode:e.isDev}),a=O({cwd:c,globalCSS:t.globalCSS??[],routes:i.map(e=>({pattern:e.pattern,filePath:e.filePath})),layouts:u.map(e=>({prefix:e.prefix,filePath:e.filePath,isRoot:e.isShared,skipRoot:h.get(e.importPath)??!1}))});y=JSON.stringify(a)}return[`// Auto-generated by Avalon — do not edit`,...he(e.core),`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,`import { appendDevCssLinks, layoutPrefixMatches, selectDevCssHrefs } from '@useavalon/avalon/render/dev-css-select';`,...g,``,`const RootLayoutComponent = ${v};`,`const _cssTable = ${y};`,``,`const moduleLayouts = [`,_.join(`,
19
+ `),`];`,``,`function getLayoutsForPath(pathname) {`,` return moduleLayouts.find((entry) => layoutPrefixMatches(pathname, entry.prefix)) ?? null;`,`}`,``,`function injectUniversalAssets(html, pathname, skipLayouts) {`,` if (process.env.NODE_ENV !== 'production') {`,` var hrefs = selectDevCssHrefs(_cssTable, pathname, skipLayouts);`,` html = appendDevCssLinks(html, hrefs);`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalCSS + '\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalHead + '\n</head>');`,` }`,` html = injectSolidHydrationScriptIfNeeded(html);`,` return html;`,`}`,``,`export async function wrapWithLayouts(pageHtml, pageModule, context, injectAssets) {`,` const pathname = context.url.pathname;`,` const frontmatter = {`,` ...(pageModule.frontmatter || {}),`,` ...(pageModule.metadata || {}),`,` currentPath: pathname,`,` };`,` const pageLayoutConfig = pageModule.layoutConfig;`,` const skipAll = pageLayoutConfig?.skipLayouts?.includes('_layout');`,``,` const layoutEntry = getLayoutsForPath(pathname);`,` const routeInfo = { path: pathname, params: context.params, query: context.url.searchParams };`,` let html;`,``,` if (!layoutEntry || skipAll) {`,` if (RootLayoutComponent && !skipAll) {`,` const rootProps = {`,` children: h('avalon-page', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,String.raw` html = '<!DOCTYPE html>\n' + preactRenderToString(resolvedRoot);`,` } else {`,` // skipAll is true — page provides its own HTML shell or needs a minimal one`,` if (pageHtml.trimStart().startsWith('<html')) {`,String.raw` html = '<!DOCTYPE html>\n' + pageHtml;`,` } else {`,` const title = String(frontmatter.title || 'Avalon');`,` html = [`,` '<!DOCTYPE html>',`,` '<html lang="en">',`,` '<head>',`,` '<meta charset="utf-8">',`,` '<meta name="viewport" content="width=device-width, initial-scale=1">',`,` '<title>' + title + '</title>',`,` '</head>',`,` '<body>',`,` '<div id="app">' + pageHtml + '</div>',`,` '</body>',`,` '</html>',`,String.raw` ].join('\n');`,` }`,` }`,` } else {`,` const layoutProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const layoutResult = layoutEntry.Layout(layoutProps);`,` const resolvedLayout = layoutResult instanceof Promise ? await layoutResult : layoutResult;`,` let wrappedHtml = preactRenderToString(resolvedLayout);`,``,` // If the layout provides its own HTML shell (starts with <html),`,` // skip root wrapping regardless of skipRoot flag — the layout IS the document.`,` const layoutProvidesShell = wrappedHtml.trimStart().startsWith('<html');`,``,` if (!layoutProvidesShell && !layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: wrappedHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,String.raw` html = '<!DOCTYPE html>\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html, pathname, skipAll);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
20
+ `)}function je(e){let t=e.clientEntry??`app/entry-client`;return[`// Auto-generated by Avalon — do not edit`,`// @ts-ignore — virtual import resolved by Nitro's Vite assets plugin at build time`,`import clientAssets from '${t.startsWith(`/`)?t:`/${t}`}?assets=client';`,``,`function buildAssetTags() {`,` const cssLinks = (clientAssets?.css ?? [])`,` .filter(attr => {`,` const href = attr.href || '';`,` // The SSR build produces ssr-index-*.css containing all global, reset,`,` // token, and layout CSS module styles. The client build may also emit`,` // entry-client-*.css (a subset) and index-*.css. To avoid duplicates,`,` // prefer ssr-index when it exists; otherwise fall back to the others.`,` var hasSsrIndex = (clientAssets?.css ?? []).some(function(a) { return (a.href || '').includes('ssr-index'); });`,` if (hasSsrIndex) return href.includes('ssr-index');`,` if (href.includes('entry-client') && href.endsWith('.css')) return true;`,String.raw` if (/\/index-[^/]+\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const entryScript = clientAssets?.entry`,` ? '<script type="module" src="' + clientAssets.entry + '"><\/script>'`,` : '';`,` return { cssLinks, jsPreloads, entryScript };`,`}`,``,`export function injectAssets(html) {`,` const { cssLinks, jsPreloads, entryScript } = buildAssetTags();`,` if (html.includes('</head>')) {`,String.raw` html = html.replace('</head>', cssLinks + '\n' + jsPreloads + '\n</head>');`,` }`,` if (html.includes('</body>')) {`,String.raw` html = html.replace('</body>', entryScript + '\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
21
+ `)}function Me(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}let i=ge(e.core);return[`// Auto-generated by Avalon — do not edit`,`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,...i,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`// Set hydration mode flag — intentionally duplicated from virtual:avalon/config`,`// for module-load-order resilience (config import may be tree-shaken or deferred).`,`globalThis.__avalonHydrationMode = avalonConfig.isDev ? "entry-client" : "per-island";`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const match = loadPage(pathname);`,` if (!match || !('default' in match.module)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: match.params };`,` },`,` loadPageModule: async (filePath) => {`,String.raw` const m = filePath.match(/^\[virtual:(.+)\]$/);`,` const pathname = m ? m[1] : filePath;`,` const match = loadPage(pathname);`,` if (match) return match.module;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
22
+ `)}async function Ne(e,t){let{readdir:n}=await import(`node:fs/promises`),{relative:r,join:i}=await import(`node:path`),a=[];for(let{dir:o}of e){let e;try{e=await n(o,{withFileTypes:!0})}catch{continue}for(let n of e){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let e=r(t,i(o,n.name)).replaceAll(`\\`,`/`);a.push(e.startsWith(`/`)?e:`/${e}`)}}return a}function Pe(e){if(e.length===0)return[];let t=[`// Layout CSS (auto-discovered)`],n=0;for(let r of e)r.includes(`.module.`)?(t.push(`import _lcss${n} from '${r}';`),n++):t.push(`import '${r}';`);return t}async function Fe(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),r=process.cwd(),i=await Ne(await n(e.layoutsDir,e.modules,r),r),a=globalThis.__avalonConfig?.isDev??e.isDev,o=a?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,s=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?s.push(`import '${o}';`):s.push(`// Per-island hydration mode — no shared runtime needed`),a&&s.push(`import '${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}';`),s.push(``);let c=t.globalCSS??[];for(let e of c){let t=e.startsWith(`/`)?e:`/${e}`;s.push(`// Global CSS`,`import '${t}';`)}return c.length>0&&s.push(``),s.push(...Pe(i),``),s.join(`
23
+ `)}function Ie(){return[`// --- Inlined Solid adapter (production) ---`,`// Eliminates a separate chunk + network request for the Solid client adapter.`,`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`,`function _ensureHydrationContext() {`,` if (!globalThis._$HY) {`,` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`,` }`,`}`,``,`async function _solidHydrate(container, Component, props) {`,` if (!container) throw new Error("Container element is required for hydration");`,` if (!Component || typeof Component !== "function") {`,` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`,` }`,` var el = container;`,` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`,` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`,` _ensureHydrationContext();`,` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`,`}`,``,`var _solidModule = { hydrate: _solidHydrate };`,``]}function Le(e,t,n){let r=[];for(let i of e){let e=t[i];e&&(i===`solid`&&!n?r.push(` case "solid":`,` return _solidModule;`):i===`react`?r.push(` case "react":`):r.push(` case "${i}":`,` return import("${e}");`))}return e.includes(`react`)&&!e.includes(`preact`)&&r.push(` return import("${t.react}");`),r}function Re(e,t){let n=[];for(let r of e){let e=t[r];e&&n.push(` case "${r}":`,` return import("${e}").then(m => m.${r}Adapter);`)}return n}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:_e(e.core),vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,solid:`@useavalon/solid/client`,lit:`@useavalon/lit/client`,qwik:`@useavalon/qwik/client`},r={preact:`@useavalon/preact/client/hmr`,react:`@useavalon/react/client/hmr`,vue:`@useavalon/vue/client/hmr`,svelte:`@useavalon/svelte/client/hmr`,solid:`@useavalon/solid/client/hmr`,lit:`@useavalon/lit/client/hmr`,qwik:`@useavalon/qwik/client/hmr`},i=t.includes(`lit`),a=t.includes(`solid`),o=(globalThis.__avalonConfig?.isDev??e.isDev)===!0,s=[`// Auto-generated by Avalon — only includes configured integrations`,``];return a&&!o&&s.push(...Ie()),s.push(`// --- loadIntegrationModule ---`,`export async function loadIntegrationModule(framework) {`,` switch (framework) {`,...Le(t,n,o),` default:`," throw new Error(`Unknown or unconfigured framework: ${framework}`);",` }`,`}`,``,`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?s.push(`export async function preLitHydration() {`,` await import("@useavalon/lit/client");`,`}`):s.push(`export async function preLitHydration() {}`),s.push(``,`// --- HMR adapter loader ---`,`export async function loadHMRAdapter(framework) {`,` switch (framework) {`,...Re(t,r),` default: return null;`,` }`,`}`),s.join(`
24
+ `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const z=`<!--AVALON_STREAM_BOUNDARY-->`;let B=null,V=null;async function H(e,t){if(t===`react`){let e=await import(`react`),t=await import(`react-dom/server`),n=e.default??e,r=t.default??t;return{h:e.createElement??n.createElement,renderToString:t.renderToString??r.renderToString}}let n=await e.ssrLoadModule(`preact`),r=await e.ssrLoadModule(`preact-render-to-string`);return{h:n.h,renderToString:r.render??r.default}}function U(e){return e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``}async function W(e,t,n){let r=[];for(let n of t){let t=await e.ssrLoadModule(n);r.push({file:n,module:t})}for(let r of t){let t=await C(e,r);n.push(...t)}return r}async function G(e,t,n,r){let i=[],a=[];for(let o of e){let e=o.module.default;if(!(!e||typeof e!=`function`))try{let s=e({...t,children:n(`div`,null,`test`)}),c=r(s instanceof Promise?await s:s);c.trim().startsWith(`<html`)||c.includes(`<!DOCTYPE`)?i.push(o):a.push(o)}catch{a.push(o)}}return{shellLayouts:i,wrapperLayouts:a}}async function ze(e,t,n,r){try{let i=e({...t,children:n(`div`,{dangerouslySetInnerHTML:{__html:z}})});return r(i instanceof Promise?await i:i)}catch{return null}}function Be(e,t){let n=e;if(t.length>0){let e=`<style data-avalon-ssr-css>${t.join(`
25
+ `)}</style>`;n.includes(`</head>`)?n=n.replace(`</head>`,`${e}\n</head>`):n+=e}n.trim().toLowerCase().startsWith(`<!doctype`)||(n=`<!DOCTYPE html>\n${n}`);let r=f(!0);r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`));let i=p(!0);return i&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${i}\n</head>`)),m(n)}async function K(e,t,n){try{let n=typeof e==`function`?e():e;return t(n instanceof Promise?await n:n)}catch(e){return console.error(`${n} Error rendering page component:`,e),`<div>Error rendering page</div>`}}async function q(e,t,n,r,i,a){let o=e;for(let{module:e}of t){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:o}})});o=i(e instanceof Promise?await e:e)}catch(e){console.error(`${a} Error rendering wrapper layout:`,e)}}return o}async function Ve(e,t,n,r,i){if(t.length===0)return e;let{module:a}=t.at(-1),o=a.default;if(!o||typeof o!=`function`)return e;try{let t=o({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:e}})});return i(t instanceof Promise?await t:t)}catch(t){return console.error(`[SSR] Error rendering shell layout:`,t),e}}function He(e){if(e.includes(`/src/client/main.js`)||e.includes(`/@vite/client`))return e;let t=e.lastIndexOf(`</body>`);return t===-1?e:e.slice(0,t)+`
26
26
  <script type="module" src="/@vite/client"><\/script>
27
27
  <script type="module" src="/src/client/main.js"><\/script>
28
- `+e.slice(t)}async function Be(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Q(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),o=t.default;if(!o)return!1;let s=t.layoutConfig,c=await T(e,a),l=await W(e,await Y(i,e),c);if(l.length===0)return!1;let{h:u,renderToString:d}=await H(e,n.core),f=s?.skipLayouts||[],p=l.filter(({file:e})=>!f.includes(U(e))),m=t.frontmatter,h=t.metadata,g={children:null,frontmatter:{...m,...h,currentPath:i},params:{},url:i},{shellLayouts:_,wrapperLayouts:v}=await G(p,g,u,d);if(_.length===0)return!1;let{module:y}=_.at(-1),b=y.default;if(!b||typeof b!=`function`)return!1;let x=await Ie(b,g,u,d);if(x===null)return!1;let S=x.indexOf(z);if(S===-1)return!1;let C=x.slice(0,S),w=x.slice(S+29),E=Le(C,c);r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(E);let D=await K(o,d,`[SSR Streaming]`);if(D.trim().startsWith(`<!DOCTYPE html>`)||D.trim().startsWith(`<html`))return r.end(D),!0;let O=ze(await q(D,v,g,u,d,`[SSR Streaming]`)+w);return r.end(O),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function Ve(e,t,n){let r=t.split(`?`)[0],i=await Q(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await T(e,i),s=await W(e,await Y(r,e),o),c;return c=n.modules&&s.length>0?await He(a,t,s,r,n,e):await Je(a,t,r,n,e),o.length>0&&(c=E(c,o)),c}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function He(e,t,n,r,i,a){let{h:o,renderToString:s}=await H(a,i.core),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>!c.includes(U(e))),u=await K(e,s,`[SSR]`);if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return J(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},{shellLayouts:m,wrapperLayouts:h}=await G(l,p,o,s),g=await Re(await q(u,h,p,o,s,`[SSR]`),m,p,o,s);if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return J(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
28
+ `+e.slice(t)}async function Ue(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Q(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),o=t.default;if(!o)return!1;let s=t.layoutConfig,c=await C(e,a),l=await W(e,await Y(i,e),c);if(l.length===0)return!1;let{h:u,renderToString:d}=await H(e,n.core),f=s?.skipLayouts||[],p=l.filter(({file:e})=>!f.includes(U(e))),m=t.frontmatter,h=t.metadata,g={children:null,frontmatter:{...m,...h,currentPath:i},params:{},url:i},{shellLayouts:_,wrapperLayouts:v}=await G(p,g,u,d);if(_.length===0)return!1;let{module:y}=_.at(-1),b=y.default;if(!b||typeof b!=`function`)return!1;let x=await ze(b,g,u,d);if(x===null)return!1;let S=x.indexOf(z);if(S===-1)return!1;let w=x.slice(0,S),T=x.slice(S+29),E=Be(w,c);r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(E);let D=await K(o,d,`[SSR Streaming]`);if(D.trim().startsWith(`<!DOCTYPE html>`)||D.trim().startsWith(`<html`))return r.end(D),!0;let O=He(await q(D,v,g,u,d,`[SSR Streaming]`)+T);return r.end(O),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function We(e,t,n){let r=t.split(`?`)[0],i=await Q(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await C(e,i),s=await W(e,await Y(r,e),o),c;return c=n.modules&&s.length>0?await Ge(a,t,s,r,n,e):await Ze(a,t,r,n,e),o.length>0&&(c=w(c,o)),c}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Ge(e,t,n,r,i,a){let{h:o,renderToString:s}=await H(a,i.core),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>!c.includes(U(e))),u=await K(e,s,`[SSR]`);if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return J(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},{shellLayouts:m,wrapperLayouts:h}=await G(l,p,o,s),g=await Ve(await q(u,h,p,o,s,`[SSR]`),m,p,o,s);if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return J(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
29
29
  <html lang="en">
30
30
  <head>
31
31
  <meta charset="utf-8">
@@ -38,12 +38,12 @@ export default islandManifest;
38
38
  ${g}
39
39
  <script type="module" src="/src/client/main.js"><\/script>
40
40
  </body>
41
- </html>`}function J(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=m(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=h(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=g(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
41
+ </html>`}function J(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=f(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=p(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=m(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
42
42
  <script type="module" src="/@vite/client"><\/script>
43
43
  <script type="module" src="/src/client/main.js"><\/script>`:t.slice(0,r)+`
44
44
  <script type="module" src="/@vite/client"><\/script>
45
45
  <script type="module" src="/src/client/main.js"><\/script>
46
- `+t.slice(r)}async function Y(e,t){let n=t.config.root||process.cwd(),r=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await i(e)).isFile()){let t=e.slice(n.length);o.includes(t)||o.push(t)}}catch{}}if(r?.layoutsDir&&await l(`${`${n}/${r.layoutsDir}`}/${a}`),r?.modules){let e=`${n}/${r.modules.dir}`,t=r.modules.layoutsDirName,i=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!i||o.includes(i.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${i}/${t}/${a}`)}let u=`${n}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function X(e,t){try{if((await i(`${e}/${t}`)).isFile())return`/${t}`}catch{}return null}async function Z(e,t,n){for(let r of n){let n=await X(e,`${t}${r}`);if(n)return n}if(!t.endsWith(`/index`))for(let r of n){let n=await X(e,`${t}/index${r}`);if(n)return n}return null}function Ue(e,t,n){let r=t.split(`/`).filter(Boolean),i=r[0]||``,a=[`home`,`root`,`main`,`index`],o,s;if(!i||a.includes(i.toLowerCase()))o=`home`,s=n;else{o=i;let e=r.slice(1);s=e.length>0?`/${e.join(`/`)}`:`/index`}return`${e.dir}/${o}/${e.pagesDirName}${s}`}async function Q(e,t,n){let r=e;r.endsWith(`/`)&&r!==`/`&&(r=r.slice(0,-1)),r===`/`&&(r=`/index`);let i=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],a=n.config.root||process.cwd();if(t.modules){let n=await Z(a,Ue(t.modules,e,r),i);if(n)return n}return Z(a,`${t.pagesDir}${r}`,i)}function We(e,t,n){if(globalThis.__avalonLayoutResolver)return;let r=e.EnhancedLayoutResolver,i=t.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new r({baseDirectory:`${n}/${i}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:t.modules?`${n}/${t.modules.dir}`:void 0,modulesLayoutsDirName:t.modules?.layoutsDirName})}async function Ge(e,t,n,r){try{let{renderToString:r}=await H(t,n.core);return typeof e==`function`?r(e()):``}catch{return`<p>Loading page: ${$(r)}</p>`}}async function Ke(e,t,n,r,i,a,o){if(!e.renderToHtmlWithLayouts||!t.EnhancedLayoutResolver||!t.EnhancedLayoutResolverUtils)return null;try{We(t,r,i.config.root||process.cwd());let s=`http://localhost${a}`,c={params:{},query:{},url:s,request:{method:`GET`,url:s,headers:new Headers}};return await e.renderToHtmlWithLayouts(n,globalThis.__avalonLayoutResolver,c,a,{title:o.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{return null}}async function qe(e,t,n,r,i,a){try{B||=await i.ssrLoadModule(N(`src/render/ssr.ts`));let o=B;V||=await i.ssrLoadModule(N(`src/core/layout/enhanced-layout-resolver.ts`));let s=V,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter},l=await Ke(o,s,c,r,i,n,a);if(l!==null)return l;if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}return null}async function Je(e,t,n,r,i){let a=t.metadata||{},o=await qe(e,t,n,r,i,a);if(o!==null)return o;let s=a.title||`Avalon App`,c=a.description||``,l=await Ge(e,i,r,n);return`<!DOCTYPE html>
46
+ `+t.slice(r)}async function Y(e,t){let n=t.config.root||process.cwd(),r=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await i(e)).isFile()){let t=e.slice(n.length);o.includes(t)||o.push(t)}}catch{}}if(r?.layoutsDir&&await l(`${`${n}/${r.layoutsDir}`}/${a}`),r?.modules){let e=`${n}/${r.modules.dir}`,t=r.modules.layoutsDirName,i=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!i||o.includes(i.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${i}/${t}/${a}`)}let u=`${n}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function X(e,t){try{if((await i(`${e}/${t}`)).isFile())return`/${t}`}catch{}return null}async function Z(e,t,n){for(let r of n){let n=await X(e,`${t}${r}`);if(n)return n}if(!t.endsWith(`/index`))for(let r of n){let n=await X(e,`${t}/index${r}`);if(n)return n}return null}function Ke(e,t,n){let r=t.split(`/`).filter(Boolean),i=r[0]||``,a=[`home`,`root`,`main`,`index`],o,s;if(!i||a.includes(i.toLowerCase()))o=`home`,s=n;else{o=i;let e=r.slice(1);s=e.length>0?`/${e.join(`/`)}`:`/index`}return`${e.dir}/${o}/${e.pagesDirName}${s}`}async function Q(e,t,n){let r=e;r.endsWith(`/`)&&r!==`/`&&(r=r.slice(0,-1)),r===`/`&&(r=`/index`);let i=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],a=n.config.root||process.cwd();if(t.modules){let n=await Z(a,Ke(t.modules,e,r),i);if(n)return n}return Z(a,`${t.pagesDir}${r}`,i)}function qe(e,t,n){if(globalThis.__avalonLayoutResolver)return;let r=e.EnhancedLayoutResolver,i=t.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new r({baseDirectory:`${n}/${i}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:t.modules?`${n}/${t.modules.dir}`:void 0,modulesLayoutsDirName:t.modules?.layoutsDirName})}async function Je(e,t,n,r){try{let{renderToString:r}=await H(t,n.core);return typeof e==`function`?r(e()):``}catch{return`<p>Loading page: ${$(r)}</p>`}}async function Ye(e,t,n,r,i,a,o){if(!e.renderToHtmlWithLayouts||!t.EnhancedLayoutResolver||!t.EnhancedLayoutResolverUtils)return null;try{qe(t,r,i.config.root||process.cwd());let s=`http://localhost${a}`,c={params:{},query:{},url:s,request:{method:`GET`,url:s,headers:new Headers}};return await e.renderToHtmlWithLayouts(n,globalThis.__avalonLayoutResolver,c,a,{title:o.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{return null}}async function Xe(e,t,n,r,i,a){try{B||=await i.ssrLoadModule(N(`src/render/ssr.ts`));let o=B;V||=await i.ssrLoadModule(N(`src/core/layout/enhanced-layout-resolver.ts`));let s=V,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter},l=await Ye(o,s,c,r,i,n,a);if(l!==null)return l;if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}return null}async function Ze(e,t,n,r,i){let a=t.metadata||{},o=await Xe(e,t,n,r,i,a);if(o!==null)return o;let s=a.title||`Avalon App`,c=a.description||``,l=await Je(e,i,r,n);return`<!DOCTYPE html>
47
47
  <html lang="en">
48
48
  <head>
49
49
  <meta charset="utf-8">
@@ -1 +1 @@
1
- import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{islandClientBundlerPlugin as r}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as i}from"../build/island-code-splitting.js";import{mdxIslandTransform as a}from"../build/mdx-island-transform.js";import{createMDXPlugin as o}from"../build/mdx-plugin.js";import{pageIslandTransform as s}from"../build/page-island-transform.js";import{registry as c}from"../core/integrations/registry.js";import{discoverIntegrationsFromIslandUsage as l}from"./auto-discover.js";import{checkDirectoriesExist as u,resolveConfig as d}from"./config.js";import{createImagePlugin as f}from"./image-optimization.js";import{activateIntegrations as p,activateSingleIntegration as m}from"./integration-activator.js";import{islandSidecarPlugin as h}from"./island-sidecar-plugin.js";import{createNitroIntegration as g}from"./nitro-integration.js";import{serverIslandsPlugin as _}from"./server-islands-plugin.js";import{formatValidationResults as v,validateActiveIntegrations as y}from"./validation.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await b(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function b(e,t){let n=c.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function x(e,t){let n=new Set;try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function S(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await x(e);return t.size===0?[...e.integrations]:Array.from(t)}async function C(e){try{let t=await o({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(a({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function w(e,t,n){let{plugins:r,nitroOptions:i}=g(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function T(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await m(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function E(e,t){if(!e.validateIntegrations||t.size===0)return;let n=y(t,e.showWarnings);n.allValid||(console.error(v(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(a){let o,c,l=new Set,m=d(a,!0),g=await S(m);g.length>0&&await p({...m,integrations:g},l);let v=await C(m),y=await f(m.image,m.verbose),b=[];l.size>0&&(b=await collectIntegrationPlugins(l,m.verbose));let x=[];if(a?.nitro){let{plugins:e}=w(m,a.nitro,m.verbose);x=e}let D=h({verbose:m.verbose}),O=_({verbose:m.verbose}),k=e(import.meta.url),A=null;try{A=n(t(k.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let j=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),M={name:`avalon`,enforce:`pre`,config(e,{command:t}){let n={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},r=g.flatMap(e=>n[e]??[]);return a?.core===`react`&&r.push(`react-dom/server`,`react/jsx-runtime`),{define:{__AVALON_PER_ISLAND__:JSON.stringify(t===`build`)},oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...g.map(e=>`@useavalon/${e}`)],include:r}}},configResolved(e){c=e,o=d(a,e.command===`serve`),globalThis.__avalonConfig=o,u(o,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&A)return A;if(j.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await T(o,c?.root,l),E(o,l)},configureServer(e){globalThis.__viteDevServer=e}},N=b.filter(e=>e.name?.includes(`lit`)),P=b.filter(e=>!e.name?.includes(`lit`)),F,I=t=>{try{return F||=e(n(c?.root??process.cwd(),`package.json`)),F.resolve(t).replace(/\.js$/,`.mjs`)}catch{return}},L=new Set([`preact`,`preact/hooks`,`preact/compat`,`preact/compat/server`,`preact/compat/client`]),R={name:`avalon:preact-compat-resolver`,enforce:`pre`,resolveId(e){let t=this.environment?.name;return t!==`ssr`&&t!==`nitro`||!L.has(e)?null:I(e)??null}},z=[`@preact/preset-vite`,`@vitejs/plugin-react`,`@vitejs/plugin-vue`,`@sveltejs/vite-plugin-svelte`,`vite-plugin-solid`,`@builder.io/qwik/optimizer`,`vite-prerender-plugin`];return[R,{name:`avalon:stub-build-time-plugins`,enforce:`pre`,resolveId(e){let t=this.environment?.name;if(!(t!==`ssr`&&t!==`nitro`)&&z.some(t=>e===t||e.startsWith(`${t}/`)))return`\0stub:${e}`},load(e){if(e.startsWith(`\0stub:`))return`export default function() { return []; }; export {};`}},s({pagesDir:m.pagesDir,layoutsDir:m.layoutsDir,modules:m.modules,verbose:m.verbose}),r(m,a?.nitro),i(m,a?.nitro),...y,...N,...v,M,D,O,...x,...P]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
1
+ import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{islandClientBundlerPlugin as r}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as i}from"../build/island-code-splitting.js";import{mdxIslandTransform as a}from"../build/mdx-island-transform.js";import{createMDXPlugin as o}from"../build/mdx-plugin.js";import{pageIslandTransform as s}from"../build/page-island-transform.js";import{registry as c}from"../core/integrations/registry.js";import{discoverIntegrationsFromIslandUsage as l}from"./auto-discover.js";import{checkDirectoriesExist as u,resolveConfig as d}from"./config.js";import{shouldSetDevScopedName as f,stableDevScopedName as p}from"./dev-css-modules.js";import{createImagePlugin as m}from"./image-optimization.js";import{activateIntegrations as h,activateSingleIntegration as g}from"./integration-activator.js";import{islandSidecarPlugin as _}from"./island-sidecar-plugin.js";import{createNitroIntegration as v}from"./nitro-integration.js";import{serverIslandsPlugin as y}from"./server-islands-plugin.js";import{formatValidationResults as b,validateActiveIntegrations as x}from"./validation.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await S(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function S(e,t){let n=c.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function C(e,t){let n=new Set;try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function w(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await C(e);return t.size===0?[...e.integrations]:Array.from(t)}async function T(e){try{let t=await o({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(a({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function E(e,t,n){let{plugins:r,nitroOptions:i}=v(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function D(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await g(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function O(e,t){if(!e.validateIntegrations||t.size===0)return;let n=x(t,e.showWarnings);n.allValid||(console.error(b(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(a){let o,c,l=new Set,g=d(a,!0),v=await w(g);v.length>0&&await h({...g,integrations:v},l);let b=await T(g),x=await m(g.image,g.verbose),S=[];l.size>0&&(S=await collectIntegrationPlugins(l,g.verbose));let C=[];if(a?.nitro){let{plugins:e}=E(g,a.nitro,g.verbose);C=e}let k=_({verbose:g.verbose}),A=y({verbose:g.verbose}),j=e(import.meta.url),M=null;try{M=n(t(j.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let N=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),P={name:`avalon`,enforce:`pre`,config(e,{command:t}){let n={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},r=v.flatMap(e=>n[e]??[]);return a?.core===`react`&&r.push(`react-dom/server`,`react/jsx-runtime`),{define:{__AVALON_PER_ISLAND__:JSON.stringify(t===`build`)},oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...v.map(e=>`@useavalon/${e}`)],include:r},...t===`serve`&&f(e.css?.modules)?{css:{modules:{generateScopedName:p}}}:{}}},configResolved(e){c=e,o=d(a,e.command===`serve`),globalThis.__avalonConfig=o,u(o,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&M)return M;if(N.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await D(o,c?.root,l),O(o,l)},configureServer(e){globalThis.__viteDevServer=e}},F=S.filter(e=>e.name?.includes(`lit`)),I=S.filter(e=>!e.name?.includes(`lit`)),L,R=t=>{try{return L||=e(n(c?.root??process.cwd(),`package.json`)),L.resolve(t).replace(/\.js$/,`.mjs`)}catch{return}},z=new Set([`preact`,`preact/hooks`,`preact/compat`,`preact/compat/server`,`preact/compat/client`]),B={name:`avalon:preact-compat-resolver`,enforce:`pre`,resolveId(e){let t=this.environment?.name;return t!==`ssr`&&t!==`nitro`||!z.has(e)?null:R(e)??null}},V=[`@preact/preset-vite`,`@vitejs/plugin-react`,`@vitejs/plugin-vue`,`@sveltejs/vite-plugin-svelte`,`vite-plugin-solid`,`@builder.io/qwik/optimizer`,`vite-prerender-plugin`];return[B,{name:`avalon:stub-build-time-plugins`,enforce:`pre`,resolveId(e){let t=this.environment?.name;if(!(t!==`ssr`&&t!==`nitro`)&&V.some(t=>e===t||e.startsWith(`${t}/`)))return`\0stub:${e}`},load(e){if(e.startsWith(`\0stub:`))return`export default function() { return []; }; export {};`}},s({pagesDir:g.pagesDir,layoutsDir:g.layoutsDir,modules:g.modules,verbose:g.verbose}),r(g,a?.nitro),i(g,a?.nitro),...x,...F,...b,P,k,A,...C,...I]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useavalon/avalon",
3
- "version": "0.3.2-canary.10",
3
+ "version": "0.3.2-canary.11",
4
4
  "description": "Multi-framework islands architecture for the modern web",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -117,6 +117,10 @@
117
117
  "types": "./dist/src/render/collect-css.d.ts",
118
118
  "default": "./dist/src/render/collect-css.js"
119
119
  },
120
+ "./render/dev-css-select": {
121
+ "types": "./dist/src/render/dev-css-select.d.ts",
122
+ "default": "./dist/src/render/dev-css-select.js"
123
+ },
120
124
  "./render/shell-engine": {
121
125
  "types": "./dist/src/render/shell-engine.d.ts",
122
126
  "default": "./dist/src/render/shell-engine.js"
@@ -160,7 +164,7 @@
160
164
  },
161
165
  "dependencies": {
162
166
  "@mdx-js/rollup": "^3.0.0",
163
- "@useavalon/core": "^0.3.2-canary.10",
167
+ "@useavalon/core": "^0.3.2-canary.11",
164
168
  "h3": "^2.0.1-rc.16",
165
169
  "marked": "^17.0.4",
166
170
  "oxc-parser": "^0.120.0",