@useavalon/avalon 0.1.70 → 0.1.72

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,4 +1,4 @@
1
1
  import{existsSync as e,readdirSync as t,readFileSync as n,statSync as r}from"node:fs";import{dirname as i,relative as a,resolve as o}from"node:path";export function islandClientBundlerPlugin(e,t,n){let r=process.cwd(),i=new Map,a=!1,o=c(e,r);for(let e of o)d(e,r,i);let s=`\0avalon-island-entry:`,l=!1,u=[],f={},p=`dist`;return{name:`avalon:island-client-bundler`,enforce:`pre`,configResolved(e){l=e.command===`serve`,a=e.command===`build`,u=e.resolve?.alias??[],f=e.define??{},p=e.build?.outDir??`dist`},resolveId(e){return e.startsWith(s)?e:null},load(e){if(!e.startsWith(s))return null;let t=e.slice(21),n=JSON.stringify(t);if(t.includes(`.qwik.`))return a?[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`].join(`
2
2
  `):[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`,`import __C from ${n};`,`export default __C;`,`if(typeof globalThis<"u")globalThis.__avalonIsland=__C;`].join(`
3
- `);let r=t.includes(`.lit.`),i=t.includes(`.solid.`),o=t.includes(`.preact.`),c=t.includes(`.react.`),l=t.includes(`.vue.`),u=t.includes(`.svelte.`),d=[];if(r&&a&&d.push(`import "@useavalon/lit/client";`),d.push(`import __C from ${n};`,`var Component = __C;`,`export { Component as default, Component };`,`if(typeof globalThis<"u")globalThis.__avalonIsland=Component;`),a){let e={solid:`@useavalon/solid/client`,preact:`@useavalon/preact/client`,react:`@useavalon/react/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,lit:`@useavalon/lit/client`},t=i?`solid`:o?`preact`:c?`react`:l?`vue`:u?`svelte`:r?`lit`:null;t&&e[t]?d.push(`export { hydrate as __hydrateIsland } from ${JSON.stringify(e[t])};`):d.push(`export { loadIntegrationModule } from "virtual:avalon/integration-loader";`)}return d.join(`
3
+ `);let r=t.includes(`.lit.`),i=t.includes(`.solid.`),o=t.includes(`.preact.`),c=t.includes(`.react.`),l=t.includes(`.vue.`)||t.endsWith(`.vue`),u=t.includes(`.svelte.`)||t.endsWith(`.svelte`),d=[];if(r&&a&&d.push(`import "@useavalon/lit/client";`),d.push(`import __C from ${n};`,`var Component = __C;`,`export { Component as default, Component };`,`if(typeof globalThis<"u")globalThis.__avalonIsland=Component;`),a){let e={solid:`@useavalon/solid/client`,preact:`@useavalon/preact/client`,react:`@useavalon/react/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,lit:`@useavalon/lit/client`},t=i?`solid`:o?`preact`:c?`react`:l?`vue`:u?`svelte`:r?`lit`:null;t&&e[t]?d.push(`export { hydrate as __hydrateIsland } from ${JSON.stringify(e[t])};`):d.push(`export { loadIntegrationModule } from "virtual:avalon/integration-loader";`)}return d.join(`
4
4
  `)},async buildStart(){if(l)return;let t=this.environment;if(!(t&&t.name!==`client`)&&i.size>0){for(let[,e]of i)this.emitFile({type:`chunk`,id:s+e.filePath,fileName:`islands/${e.bundleKey}.js`,preserveSignature:`exports-only`});e.verbose&&console.log(`🏝️ Emitting ${i.size} island client bundles`)}},async closeBundle(){if(l||!a||i.size===0||globalThis.__avalonIslandsRebuilt)return;globalThis.__avalonIslandsRebuilt=!0;let{buildIsolatedIslands:e}=await import(`../post-build/isolated-island-builder.js`),t=new Map;for(let[e,n]of i){let r=n.filePath.includes(`.solid.`)?`solid`:n.filePath.includes(`.preact.`)?`preact`:n.filePath.includes(`.react.`)?`react`:n.filePath.includes(`.vue.`)||n.filePath.endsWith(`.vue`)?`vue`:n.filePath.includes(`.svelte.`)||n.filePath.endsWith(`.svelte`)?`svelte`:n.filePath.includes(`.lit.`)?`lit`:n.filePath.includes(`.qwik.`)?`qwik`:`preact`;t.set(e,{...n,framework:r})}await e(r,p,t,u,f,n?{treeshake:n}:void 0)}}}function c(n,r){let i=[];if(n.pagesDir){let t=o(r,n.pagesDir);e(t)&&i.push(t)}if(n.layoutsDir){let t=o(r,n.layoutsDir);e(t)&&i.push(t)}if(n.modules){let a=o(r,n.modules.dir);if(e(a))try{for(let n of t(a,{withFileTypes:!0}))if(n.isDirectory())for(let t of[`pages`,`layouts`,`components`]){let r=o(a,n.name,t);e(r)&&i.push(r)}}catch{}}return i}const l=[`.qwik.`];function u(e){return l.some(t=>e.includes(t))}function d(e,r,i){let a;try{a=t(e,{withFileTypes:!0})}catch{return}for(let t of a){let a=o(e,t.name);if(t.isDirectory()){d(a,r,i);continue}if(/\.(tsx?|jsx?|mdx?)$/.test(t.name))try{let e=n(a,`utf-8`),t=e.includes(`island=`)||e.includes(`island `),o=/import\s+\w+\s+from\s+['"][^'"]*\.qwik\.[^'"]*['"]/m.test(e);if(!t&&!o)continue;f(e,a,r,i)}catch{}}}function f(e,t,n,r){let i=/<([A-Z]\w*)\s+[^>]*\bisland\b/g,o=new Set,s=null;for(s=i.exec(e);s!==null;s=i.exec(e))o.add(s[1]);let c=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,l=new Set,d=[];for(s=c.exec(e);s!==null;s=c.exec(e))d.push([s[1],s[2]]),u(s[2])&&RegExp(`<${s[1]}[\\s/>]`).test(e)&&l.add(s[1]);if(!(o.size===0&&l.size===0))for(let[e,i]of d){if(!o.has(e)&&!l.has(e))continue;let s=p(i,t,n);if(!s)continue;let c=a(n,s).replaceAll(`\\`,`/`).replace(/\.(tsx?|jsx?)$/,``);r.has(s)||r.set(s,{filePath:s,bundleKey:c})}}function p(t,n,a){let s;if(t.startsWith(`@shared/`))s=o(a,`app/shared`,t.slice(8));else if(t.startsWith(`@modules/`))s=o(a,`app/modules`,t.slice(9));else if(t.startsWith(`@/`))s=o(a,`app`,t.slice(2));else if(t.startsWith(`.`))s=o(i(n),t);else return null;if(e(s)&&r(s).isFile())return s;for(let t of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(e(s+t))return s+t;return null}
@@ -1,4 +1,4 @@
1
- import{getRequestURL as e}from"h3";import{h as t}from"preact";import n from"preact-render-to-string";import{discoverScopedMiddleware as r,executeScopedMiddleware as i}from"../middleware/index.js";import{discoverErrorPages as a,handleRenderError as o}from"./error-handler.js";import{createNotFoundError as s,isHttpError as c}from"./types.js";import{inlineCriticalCSS as l}from"../islands/critical-css.js";import{injectModulepreloadLinks as u}from"../islands/modulepreload-collector.js";export function createRenderContext(e,t={}){let n=getRequestURL(e);return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:toRequest(e),event:e}}export function createRenderContextFromRequest(e,t={}){let n=new URL(e.url,`http://localhost`),r={method:e.method,path:n.pathname+n.search,context:{params:t}};return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:e,event:r}}export function getRequestURL(t){return new URL(e(t).pathname,`http://localhost`)}export function toRequest(e){let t=getRequestURL(e);return new Request(t,{method:e.req.method,headers:getRequestHeaders(e)})}export function getRequestHeaders(e){return new Headers}export function setResponseHeader(e,t,n){e.context.responseHeaders||(e.context.responseHeaders={}),e.context.responseHeaders[t]=n}export function createErrorResponse(e,t){let n=c(e)?e.statusCode:500;if(t){let t=_(e,n);return new Response(t,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}let r=v(n);return new Response(r,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}function _(e,t){return`<!DOCTYPE html>
1
+ import{getRequestURL as e}from"h3";import{h as t}from"preact";import n from"preact-render-to-string";import{inlineCriticalCSS as r}from"../islands/critical-css.js";import{injectModulepreloadLinks as i}from"../islands/modulepreload-collector.js";import{discoverScopedMiddleware as a,executeScopedMiddleware as o}from"../middleware/index.js";import{discoverErrorPages as s,handleRenderError as c}from"./error-handler.js";import{createNotFoundError as l,isHttpError as u}from"./types.js";export function createRenderContext(e,t={}){let n=getRequestURL(e);return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:toRequest(e),event:e}}export function createRenderContextFromRequest(e,t={}){let n=new URL(e.url,`http://localhost`),r={method:e.method,path:n.pathname+n.search,context:{params:t}};return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:e,event:r}}export function getRequestURL(t){return new URL(e(t).pathname,`http://localhost`)}export function toRequest(e){let t=getRequestURL(e);return new Request(t,{method:e.req.method,headers:getRequestHeaders(e)})}export function getRequestHeaders(e){return new Headers}export function setResponseHeader(e,t,n){e.context.responseHeaders||(e.context.responseHeaders={}),e.context.responseHeaders[t]=n}export function createErrorResponse(e,t){let n=u(e)?e.statusCode:500;if(t){let t=_(e,n);return new Response(t,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}let r=v(n);return new Response(r,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}function _(e,t){return`<!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
@@ -117,7 +117,7 @@ import{getRequestURL as e}from"h3";import{h as t}from"preact";import n from"prea
117
117
  <p><a href="/">Return to home</a></p>
118
118
  </div>
119
119
  </body>
120
- </html>`}function y(e){return{400:`Bad Request`,401:`Unauthorized`,403:`Forbidden`,404:`Page Not Found`,405:`Method Not Allowed`,500:`Internal Server Error`,502:`Bad Gateway`,503:`Service Unavailable`}[e]||`Error`}function b(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#039;`)}export function extractIslandMarkers(e){let t=[],n=/<[^>]*data-framework="([^"]+)"[^>]*>/g,r=n.exec(e);for(;r!==null;){let i=r[0],a=r[1],o=/data-src="([^"]+)"/.exec(i),s=o?o[1]:``,c=/data-props="([^"]*)"/.exec(i),l=c?c[1]:void 0,u=/data-hydrate="([^"]+)"/.exec(i),d=u?u[1]:void 0;t.push({framework:a,src:s,props:l,hydrate:d}),r=n.exec(e)}return t}export function ensureHydrationMarkers(e,t){let n=e;return t.framework&&!n.includes(`data-framework=`)&&(n=n.replace(/>/,` data-framework="${t.framework}">`)),t.src&&!n.includes(`data-src=`)&&(n=n.replace(/>/,` data-src="${t.src}">`)),t.props!==void 0&&!n.includes(`data-props=`)&&(n=n.replace(/>/,` data-props="${t.props}">`)),n}function x(e){return e.replaceAll(/<div data-island-script="" style="display:contents">(<script[\s\S]*?<\/script>)<\/div>/g,`$1`)}export function injectHydrationScript(e,t,n={}){if(globalThis.__avalonHydrationMode===`per-island`||!t)return x(e);if(!(e.includes(`data-framework=`)||e.includes(`data-src=`))&&!n.forceInject||[`/src/client/main.js`,`/dist/client.js`,`client/main.js`,`entry-client`].some(t=>e.includes(t)))return e;let r=n.scriptPath||(t?`/src/client/main.js`:`/dist/client.js`),i=[];i.push(`<script type="module" src="${r}"><\/script>`),n.additionalScripts&&i.push(...n.additionalScripts);let a=i.join(`
120
+ </html>`}function y(e){return{400:`Bad Request`,401:`Unauthorized`,403:`Forbidden`,404:`Page Not Found`,405:`Method Not Allowed`,500:`Internal Server Error`,502:`Bad Gateway`,503:`Service Unavailable`}[e]||`Error`}function b(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#039;`)}export function extractIslandMarkers(e){let t=[],n=/<[^>]*data-framework="([^"]+)"[^>]*>/g,r=n.exec(e);for(;r!==null;){let i=r[0],a=r[1],o=/data-src="([^"]+)"/.exec(i),s=o?o[1]:``,c=/data-props="([^"]*)"/.exec(i),l=c?c[1]:void 0,u=/data-hydrate="([^"]+)"/.exec(i),d=u?u[1]:void 0;t.push({framework:a,src:s,props:l,hydrate:d}),r=n.exec(e)}return t}export function ensureHydrationMarkers(e,t){let n=e;return t.framework&&!n.includes(`data-framework=`)&&(n=n.replace(/>/,` data-framework="${t.framework}">`)),t.src&&!n.includes(`data-src=`)&&(n=n.replace(/>/,` data-src="${t.src}">`)),t.props!==void 0&&!n.includes(`data-props=`)&&(n=n.replace(/>/,` data-props="${t.props}">`)),n}function x(e){return e.replaceAll(/<div[^>]*\bdata-island-script\b[^>]*>(<script[\s\S]*?<\/script>)<\/div>/g,`$1`)}export function injectHydrationScript(e,t,n={}){if(globalThis.__avalonHydrationMode===`per-island`||!t)return x(e);if(!(e.includes(`data-framework=`)||e.includes(`data-src=`))&&!n.forceInject||[`/src/client/main.js`,`/dist/client.js`,`client/main.js`,`entry-client`].some(t=>e.includes(t)))return e;let r=n.scriptPath||(t?`/src/client/main.js`:`/dist/client.js`),i=[];i.push(`<script type="module" src="${r}"><\/script>`),n.additionalScripts&&i.push(...n.additionalScripts);let a=i.join(`
121
121
  `);return e.includes(`</body>`)?e.replace(`</body>`,`${a}\n</body>`):e+a}export function validateHydrationMarkers(e){let t=extractIslandMarkers(e),n=e.match(/data-framework="[^"]+"/g)||[],r=e.match(/data-src="[^"]+"/g)||[],i=e.match(/data-props="[^"]*"/g)||[],a=e.includes(`/src/client/main.js`)||e.includes(`/dist/client.js`)||e.includes(`client/main.js`),o=t.every(e=>e.framework&&e.src),s=t.length===0||o&&a;return{hasFrameworkAttr:n.length>0,hasSrcAttr:r.length>0,hasPropsAttr:i.length>0,islandCount:n.length,islands:t,hasClientScript:a,isValid:s}}export function processHydrationRequirements(e,t){let n=injectHydrationScript(e,t);return{html:n,validation:validateHydrationMarkers(n)}}export async function renderPage(e,t,n={},r){try{let i={};return e.getServerSideProps&&(i=await e.getServerSideProps(t)),{html:await S(e,i,t,n,r),statusCode:200,headers:{"Content-Type":`text/html; charset=utf-8`}}}catch(e){throw console.error(`[SSR Error]`,e),n.onError&&e instanceof Error&&n.onError(e),e}}async function S(e,r,i,a,o){let s=e.default,c=e.metadata||{},l=process.env.NODE_ENV!==`production`,u;try{let e=s(r);u=e instanceof Promise?await e:e}catch(e){console.error(`[renderer] Error calling page component:`,e),u=t(`div`,null,`Error rendering page`)}let d;try{d=n(u)}catch(e){console.error(`[renderer] Error in preactRenderToString:`,e),d=`<div>Error rendering page</div>`}if(o)return await o(d,e,i);let f=l?`
122
122
  <script type="module" src="/src/client/main.js"><\/script>`:``;return`<!DOCTYPE html>
123
123
  <html lang="en">
@@ -181,4 +181,4 @@ import{getRequestURL as e}from"h3";import{h as t}from"preact";import n from"prea
181
181
  </details>
182
182
  `:``}
183
183
  </div>
184
- `}export function createStreamingResponse(e,t={}){let n=new Headers({"Content-Type":`text/html; charset=utf-8`,"Transfer-Encoding":`chunked`,...t.headers});return new Response(e,{status:t.status||200,headers:n})}function D(e,t,n){return async()=>(e.value??=await r({baseDir:t,devMode:n}),e.value)}function O(e,t,n){return async(r,i)=>e?o(r,i,t):createErrorResponse(r,n)}export function createNitroRenderer(e){let{avalonConfig:t,isDev:n=!1,enableCustomErrorPages:r=!0}=e,o={isDev:n,avalonConfig:t,loadPageModule:e.loadPageModule,pagesDir:t.pagesDir};r&&a(o).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let c=D({value:null},t.srcDir||`src`,n),m=O(r,o,n);async function h(r){let a=getRequestURL(r).pathname;try{let o=await i(r,await c(),{devMode:n});if(o)return n&&console.log(`[renderer] Middleware terminated request for ${a}`),o;let f=r.context.route,p=null;if(p=f||(e.resolvePageRoute?await e.resolvePageRoute(a,t.pagesDir):await k(a,t.pagesDir)),!p)return m(s(`Page not found: ${a}`),r);let h=e.loadPageModule?await e.loadPageModule(p.filePath):await A(p.filePath),g=createRenderContext(r,r.context.params||p.params);if(e.resolveLayouts&&(g.layoutContext={layouts:await e.resolveLayouts(a,t)}),t.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(h,g,{onShellReady:()=>{setResponseHeader(r,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let t=await renderPage(h,g,{},e.wrapWithLayouts),r=injectHydrationScript(t.html,n);return r=l(r),r=u(r),new Response(r,{status:t.statusCode,headers:t.headers})}}catch(e){return console.error(`[Nitro Renderer Error]`,e),m(e instanceof Error?e:Error(String(e)),r)}}return Object.assign(h,{async fetch(r){let i=new URL(r.url,`http://localhost`).pathname;try{let a=null;if(a=e.resolvePageRoute?await e.resolvePageRoute(i,t.pagesDir):await k(i,t.pagesDir),!a)return createErrorResponse(s(`Page not found: ${i}`),n);let o=await renderPage(e.loadPageModule?await e.loadPageModule(a.filePath):await A(a.filePath),createRenderContextFromRequest(r,a.params),{},e.wrapWithLayouts),c=injectHydrationScript(o.html,n);return c=l(c),c=u(c),new Response(c,{status:o.statusCode,headers:o.headers})}catch(e){return console.error(`[Nitro Renderer .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}async function k(e,t){return e===`/`||e===``?{filePath:`src/pages/index.tsx`,pattern:`/`,params:{}}:{filePath:`src/pages/${e.replace(/^\//,``).replace(/\/$/,``)}.tsx`,pattern:e,params:{}}}async function A(e){return{default:()=>null,metadata:{title:`Avalon Page`}}}export function createNitroCatchAllRenderer(e){let{avalonConfig:t,isDev:n=!1,loadPageModule:r,resolveLayouts:o,enableCustomErrorPages:c=!0}=e,m={isDev:n,avalonConfig:t,loadPageModule:r,pagesDir:t.pagesDir};c&&a(m).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let h=D({value:null},t.srcDir||`src`,n),_=O(c,m,n);async function v(a){let c=getRequestURL(a).pathname;try{let f=await i(a,await h(),{devMode:n});if(f)return n&&console.log(`[renderer] Middleware terminated request for ${c}`),f;let p=a.context.params||{},m=p.slug||c.replace(/^\//,``)||`index`,g=`${t.pagesDir}/${m}.tsx`,v;try{v=await r(g)}catch(e){try{v=await r(`${t.pagesDir}/${m}/index.tsx`)}catch(r){return n&&(console.debug(`[renderer] Page not found: ${g}`,e),console.debug(`[renderer] Index fallback not found: ${t.pagesDir}/${m}/index.tsx`,r)),_(s(`Page not found: ${c}`),a)}}let y=createRenderContext(a,p);if(o&&(y.layoutContext={layouts:await o(c,t)}),t.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(v,y,{onShellReady:()=>{setResponseHeader(a,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let t=await renderPage(v,y,{},e.wrapWithLayouts),r=injectHydrationScript(t.html,n);return r=l(r),r=u(r),new Response(r,{status:t.statusCode,headers:t.headers})}}catch(e){return console.error(`[Nitro Catch-All Renderer Error]`,e),_(e instanceof Error?e:Error(String(e)),a)}}return Object.assign(v,{async fetch(i){let a=new URL(i.url,`http://localhost`).pathname;try{let o=a.replace(/^\//,``)||`index`,c=`${t.pagesDir}/${o}.tsx`,d;try{d=await r(c)}catch{try{d=await r(`${t.pagesDir}/${o}/index.tsx`)}catch{return createErrorResponse(s(`Page not found: ${a}`),n)}}let p=createRenderContextFromRequest(i),m=await renderPage(d,p,{},e.wrapWithLayouts),h=injectHydrationScript(m.html,n);return h=l(h),h=u(h),new Response(h,{status:m.statusCode,headers:m.headers})}catch(e){return console.error(`[Nitro CatchAll .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}export{clearMiddlewareCache as clearRendererMiddlewareCache}from"../middleware/index.js";
184
+ `}export function createStreamingResponse(e,t={}){let n=new Headers({"Content-Type":`text/html; charset=utf-8`,"Transfer-Encoding":`chunked`,...t.headers});return new Response(e,{status:t.status||200,headers:n})}function D(e,t,n){return async()=>(e.value??=await a({baseDir:t,devMode:n}),e.value)}function O(e,t,n){return async(r,i)=>e?c(r,i,t):createErrorResponse(r,n)}export function createNitroRenderer(e){let{avalonConfig:t,isDev:n=!1,enableCustomErrorPages:a=!0}=e,c={isDev:n,avalonConfig:t,loadPageModule:e.loadPageModule,pagesDir:t.pagesDir};a&&s(c).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let u=D({value:null},t.srcDir||`src`,n),m=O(a,c,n);async function h(a){let s=getRequestURL(a).pathname;try{let c=await o(a,await u(),{devMode:n});if(c)return n&&console.log(`[renderer] Middleware terminated request for ${s}`),c;let f=a.context.route,p=null;if(p=f||(e.resolvePageRoute?await e.resolvePageRoute(s,t.pagesDir):await k(s,t.pagesDir)),!p)return m(l(`Page not found: ${s}`),a);let h=e.loadPageModule?await e.loadPageModule(p.filePath):await A(p.filePath),g=createRenderContext(a,a.context.params||p.params);if(e.resolveLayouts&&(g.layoutContext={layouts:await e.resolveLayouts(s,t)}),t.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(h,g,{onShellReady:()=>{setResponseHeader(a,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let t=await renderPage(h,g,{},e.wrapWithLayouts),a=injectHydrationScript(t.html,n);return a=r(a),a=i(a),new Response(a,{status:t.statusCode,headers:t.headers})}}catch(e){return console.error(`[Nitro Renderer Error]`,e),m(e instanceof Error?e:Error(String(e)),a)}}return Object.assign(h,{async fetch(a){let o=new URL(a.url,`http://localhost`).pathname;try{let s=null;if(s=e.resolvePageRoute?await e.resolvePageRoute(o,t.pagesDir):await k(o,t.pagesDir),!s)return createErrorResponse(l(`Page not found: ${o}`),n);let c=await renderPage(e.loadPageModule?await e.loadPageModule(s.filePath):await A(s.filePath),createRenderContextFromRequest(a,s.params),{},e.wrapWithLayouts),u=injectHydrationScript(c.html,n);return u=r(u),u=i(u),new Response(u,{status:c.statusCode,headers:c.headers})}catch(e){return console.error(`[Nitro Renderer .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}async function k(e,t){return e===`/`||e===``?{filePath:`src/pages/index.tsx`,pattern:`/`,params:{}}:{filePath:`src/pages/${e.replace(/^\//,``).replace(/\/$/,``)}.tsx`,pattern:e,params:{}}}async function A(e){return{default:()=>null,metadata:{title:`Avalon Page`}}}export function createNitroCatchAllRenderer(e){let{avalonConfig:t,isDev:n=!1,loadPageModule:a,resolveLayouts:c,enableCustomErrorPages:u=!0}=e,m={isDev:n,avalonConfig:t,loadPageModule:a,pagesDir:t.pagesDir};u&&s(m).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let h=D({value:null},t.srcDir||`src`,n),_=O(u,m,n);async function v(s){let u=getRequestURL(s).pathname;try{let f=await o(s,await h(),{devMode:n});if(f)return n&&console.log(`[renderer] Middleware terminated request for ${u}`),f;let p=s.context.params||{},m=p.slug||u.replace(/^\//,``)||`index`,g=`${t.pagesDir}/${m}.tsx`,v;try{v=await a(g)}catch(e){try{v=await a(`${t.pagesDir}/${m}/index.tsx`)}catch(r){return n&&(console.debug(`[renderer] Page not found: ${g}`,e),console.debug(`[renderer] Index fallback not found: ${t.pagesDir}/${m}/index.tsx`,r)),_(l(`Page not found: ${u}`),s)}}let y=createRenderContext(s,p);if(c&&(y.layoutContext={layouts:await c(u,t)}),t.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(v,y,{onShellReady:()=>{setResponseHeader(s,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let t=await renderPage(v,y,{},e.wrapWithLayouts),a=injectHydrationScript(t.html,n);return a=r(a),a=i(a),new Response(a,{status:t.statusCode,headers:t.headers})}}catch(e){return console.error(`[Nitro Catch-All Renderer Error]`,e),_(e instanceof Error?e:Error(String(e)),s)}}return Object.assign(v,{async fetch(o){let s=new URL(o.url,`http://localhost`).pathname;try{let c=s.replace(/^\//,``)||`index`,u=`${t.pagesDir}/${c}.tsx`,d;try{d=await a(u)}catch{try{d=await a(`${t.pagesDir}/${c}/index.tsx`)}catch{return createErrorResponse(l(`Page not found: ${s}`),n)}}let p=createRenderContextFromRequest(o),m=await renderPage(d,p,{},e.wrapWithLayouts),h=injectHydrationScript(m.html,n);return h=r(h),h=i(h),new Response(h,{status:m.statusCode,headers:m.headers})}catch(e){return console.error(`[Nitro CatchAll .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}export{clearMiddlewareCache as clearRendererMiddlewareCache}from"../middleware/index.js";
@@ -1,7 +1,7 @@
1
- import{copyFileSync as e,cpSync as t,existsSync as n,mkdirSync as r,readdirSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u}from"node:path";function d(e,t,r=[]){if(!n(e))return r;for(let n of i(e,{withFileTypes:!0})){let i=l(e,n.name);n.isDirectory()?d(i,t,r):t(n.name)&&r.push(i)}return r}function f(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.length<500&&!t.includes(`data-framework`)&&!t.includes(`avalon`)}function p(e){for(let t of[`dist/index.html`,`.netlify/functions-internal/server/public/index.html`,`.output/public/index.html`]){let r=l(e,t);f(r)?(o(r),console.log(`[cleanup] Removed stale Vite template ${t}`)):n(r)&&console.log(`[cleanup] Preserved prerendered ${t}`)}}function m(e,t,r){if(!n(e))return;let i=[l(t,`assets`),l(r,`.netlify`,`functions-internal`,`server`,`public`,`assets`),l(r,`.output`,`public`,`assets`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.css`)).filter(e=>{let t=(e.split(`/`).pop()||``).toLowerCase();return t.includes(`_isolated-island-entry`)?!1:!!(t.startsWith(`ssr-index`)||t.startsWith(`index-`)||t.startsWith(`entry-client`))}).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);console.log(`[patch] Found ${o.length} CSS files in ${i}`);let c=a(e,`utf-8`);for(let{re:t,hrefRe:n,q:r}of[{re:/css:\[(\{href:`[^`]+`\}(?:,\{href:`[^`]+`\})*)\]/,hrefRe:/href:`([^`]+)`/g,q:"`"},{re:/css:\[(\{href:"[^"]+"\}(?:,\{href:"[^"]+"\})*)\]/,hrefRe:/href:"([^"]+)"/g,q:`"`}]){let i=t.exec(c);if(!i)continue;let a=new Set([...i[1].matchAll(n)].map(e=>e[1])),l=o.filter(e=>!a.has(e));if(l.length===0){console.log(`[patch] All CSS already included`);return}let u=l.map(e=>`{href:${r}${e}${r}}`).join(`,`);c=c.replace(i[0],`css:[${i[1]},${u}]`),s(e,c),console.log(`[patch] ✅ Added ${l.length} CSS files to SSR bundle`);return}console.warn(`[patch] Could not find CSS array in SSR bundle`)}function h(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,>~+])\s*/g,`$1`).replaceAll(/;}/g,`}`).trim()}function g(e,t){let o=[l(e,`node_modules`,`.nitro`,`vite`,`services`,`ssr`,`assets`)];for(let c of o){if(!n(c))continue;let o=i(c).filter(e=>e.endsWith(`.css`));if(o.length===0)continue;let u=[l(t,`assets`),l(e,`.output`,`public`,`assets`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`assets`)];for(let e of u){r(e,{recursive:!0});for(let t of o){let n=a(l(c,t),`utf-8`);n=h(n),s(l(e,`ssr-${t}`),n)}}let d=`ssr-${o[0]}`,f=l(u.find(e=>n(e))||u[0],d),p=n(f)?a(f).length:0;console.log(`[ssr-css] Copied SSR CSS → /assets/${d} (${p} bytes, minified)`);let m=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of m){if(!n(e))continue;let t=a(e,`utf-8`),r=`/assets/${d}`;if(t.includes(r))continue;let i=/"\/assets\/[^"]+\.css":\{type:`text\/css[^}]+\}/.exec(t);if(i){let n=new Date().toISOString(),a=`,"${r}":{type:\`text/css; charset=utf-8\`,etag:\`${`"${p.toString(16)}-ssr"`}\`,mtime:\`${n}\`,size:${p},path:\`../public/assets/${d}\`}`;t=t.replace(i[0],i[0]+a),s(e,t),console.log(`[ssr-css] ✅ Patched asset manifest in ${e}`)}}return}console.log(`[ssr-css] No SSR CSS files found`)}function _(t,r){let i=l(r,`islands`);if(!n(i))return;let a=[l(t,`.output`,`public`,`islands`),l(t,`.netlify`,`functions-internal`,`server`,`public`,`islands`)],o=0,s=d(i,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));for(let t of a)if(n(t))for(let r of s){let a=l(t,r.substring(i.length));n(a)&&(e(r,a),o++)}o>0&&console.log(`[islands] ✅ Synced ${o} isolated island build(s) to output`)}function v(t){let i=[l(t,`assets`,`islands`),l(t,`islands`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(o.length===0)return;let f=o.filter(e=>/-[A-Za-z0-9_-]{6,12}\.js$/.test(e));if(f.length===0){console.log(`[redirects] ${o.length} island(s) found with clean paths — no redirects needed`);return}let p=[];for(let n of f){let i=`/${u(t,n).replaceAll(`\\`,`/`)}`,a=i.replace(`/assets/`,`/`).replace(/-[A-Za-z0-9_-]{6,12}\.js$/,`.js`);p.push(`${a} ${i} 200`);let o=l(t,a.slice(1));r(c(o),{recursive:!0}),e(n,o)}let m=l(t,`_redirects`),h=n(m)?a(m,`utf-8`):``;h=h.replaceAll(/# Island JS path rewrites[^\n]*\n(?:\/islands\/[^\n]*\n)*/g,``).trim();let g=`# Island JS path rewrites (generated by Avalon post-build)
1
+ import{copyFileSync as e,cpSync as t,existsSync as n,mkdirSync as r,readdirSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u}from"node:path";function d(e,t,r=[]){if(!n(e))return r;for(let n of i(e,{withFileTypes:!0})){let i=l(e,n.name);n.isDirectory()?d(i,t,r):t(n.name)&&r.push(i)}return r}function f(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.length<500&&!t.includes(`data-framework`)&&!t.includes(`avalon`)}function p(e){for(let t of[`dist/index.html`,`.netlify/functions-internal/server/public/index.html`,`.output/public/index.html`]){let r=l(e,t);f(r)?(o(r),console.log(`[cleanup] Removed stale Vite template ${t}`)):n(r)&&console.log(`[cleanup] Preserved prerendered ${t}`)}}function m(e,t,r){if(!n(e))return;let i=[l(t,`assets`),l(r,`.netlify`,`functions-internal`,`server`,`public`,`assets`),l(r,`.output`,`public`,`assets`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.css`)).filter(e=>{let t=(e.split(`/`).pop()||``).toLowerCase();return t.includes(`_isolated-island-entry`)?!1:!!(t.startsWith(`entry-client`)||t.startsWith(`index-`))}).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);if(!o.some(e=>/\/index-[^/]+\.css$/.test(e))){let e=d(i,e=>e.endsWith(`.css`)).filter(e=>(e.split(`/`).pop()||``).toLowerCase().startsWith(`ssr-index`)).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);o.push(...e)}console.log(`[patch] Found ${o.length} CSS files in ${i}`);let c=a(e,`utf-8`);for(let{re:t,hrefRe:n,q:r}of[{re:/css:\[(\{href:`[^`]+`\}(?:,\{href:`[^`]+`\})*)\]/,hrefRe:/href:`([^`]+)`/g,q:"`"},{re:/css:\[(\{href:"[^"]+"\}(?:,\{href:"[^"]+"\})*)\]/,hrefRe:/href:"([^"]+)"/g,q:`"`}]){let i=t.exec(c);if(!i)continue;let a=new Set([...i[1].matchAll(n)].map(e=>e[1])),l=o.filter(e=>!a.has(e));if(l.length===0){console.log(`[patch] All CSS already included`);return}let u=l.map(e=>`{href:${r}${e}${r}}`).join(`,`);c=c.replace(i[0],`css:[${i[1]},${u}]`),s(e,c),console.log(`[patch] ✅ Added ${l.length} CSS files to SSR bundle`);return}console.warn(`[patch] Could not find CSS array in SSR bundle`)}function h(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,>~+])\s*/g,`$1`).replaceAll(/;}/g,`}`).trim()}function g(e,t){let o=l(t,`assets`);if(n(o)&&i(o).some(e=>e.startsWith(`entry-client`)&&e.endsWith(`.css`))){console.log(`[ssr-css] Skipped — client build already includes entry-client CSS`);return}let c=[l(e,`node_modules`,`.nitro`,`vite`,`services`,`ssr`,`assets`)];for(let o of c){if(!n(o))continue;let c=i(o).filter(e=>e.endsWith(`.css`));if(c.length===0)continue;let u=[l(t,`assets`),l(e,`.output`,`public`,`assets`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`assets`)];for(let e of u){r(e,{recursive:!0});for(let t of c){let n=a(l(o,t),`utf-8`);n=h(n),s(l(e,`ssr-${t}`),n)}}let d=`ssr-${c[0]}`,f=l(u.find(e=>n(e))||u[0],d),p=n(f)?a(f).length:0;console.log(`[ssr-css] Copied SSR CSS → /assets/${d} (${p} bytes, minified)`);let m=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of m){if(!n(e))continue;let t=a(e,`utf-8`),r=`/assets/${d}`;if(t.includes(r))continue;let i=/"\/assets\/[^"]+\.css":\{type:`text\/css[^}]+\}/.exec(t);if(i){let n=new Date().toISOString(),a=`,"${r}":{type:\`text/css; charset=utf-8\`,etag:\`${`"${p.toString(16)}-ssr"`}\`,mtime:\`${n}\`,size:${p},path:\`../public/assets/${d}\`}`;t=t.replace(i[0],i[0]+a),s(e,t),console.log(`[ssr-css] ✅ Patched asset manifest in ${e}`)}}return}console.log(`[ssr-css] No SSR CSS files found`)}async function _(e,t){let r=l(t,`islands`);if(!n(r))return;let i=d(r,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(i.length===0)return;let o=[];for(let t of i){let i=a(t,`utf-8`);if(!/from\s*["']\.\.\//.test(i))continue;let s=t.substring(r.length+1).replace(/\.js$/,``),c=`preact`;if(t.includes(`.solid.`)?c=`solid`:t.includes(`.vue.`)||t.endsWith(`.vue.js`)?c=`vue`:t.includes(`.svelte.`)?c=`svelte`:t.includes(`.react.`)?c=`react`:t.includes(`.lit.`)?c=`lit`:t.includes(`.qwik.`)&&(c=`qwik`),c===`qwik`||c===`lit`)continue;let u=l(e,`${s}.tsx`),d=l(e,`${s}.ts`),f=l(e,`${s}`).replace(/\.vue$/,`.vue`),p=l(e,`${s}`).replace(/\.svelte$/,`.svelte`),m=null;for(let e of[u,d,f,p])if(n(e)){m=e;break}if(!m){console.warn(`[islands] ⚠ Cannot find source for stale island: ${s}`);continue}o.push({filePath:m,bundleKey:s,framework:c})}if(o.length!==0){console.log(`[islands] Found ${o.length} island(s) still code-split, rebuilding...`);try{let{buildIsolatedIslands:t}=await import(`./isolated-island-builder.js`),n=new Map;for(let e of o)n.set(e.filePath,e);await t(e,`dist`,n,[],{})}catch(e){console.error(`[islands] ❌ Failed to rebuild stale islands: ${e instanceof Error?e.message:e}`)}}}function v(t,i){let a=l(i,`islands`);if(!n(a))return;let s=[l(t,`.output`,`public`),l(t,`.netlify`,`functions-internal`,`server`,`public`)],u=0,f=d(a,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));for(let t of s){if(!n(t))continue;let i=l(t,`islands`);for(let t of f){let s=l(i,t.substring(a.length));r(c(s),{recursive:!0}),e(t,s),u++;for(let e of[`.br`,`.gz`,`.zst`]){let t=s+e;n(t)&&o(t)}}}u>0&&console.log(`[islands] ✅ Synced ${u} isolated island build(s) to output`)}function y(t){let i=[l(t,`assets`,`islands`),l(t,`islands`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(o.length===0)return;let f=o.filter(e=>/-[A-Za-z0-9_-]{6,12}\.js$/.test(e));if(f.length===0){console.log(`[redirects] ${o.length} island(s) found with clean paths — no redirects needed`);return}let p=[];for(let n of f){let i=`/${u(t,n).replaceAll(`\\`,`/`)}`,a=i.replace(`/assets/`,`/`).replace(/-[A-Za-z0-9_-]{6,12}\.js$/,`.js`);p.push(`${a} ${i} 200`);let o=l(t,a.slice(1));r(c(o),{recursive:!0}),e(n,o)}let m=l(t,`_redirects`),h=n(m)?a(m,`utf-8`):``;h=h.replaceAll(/# Island JS path rewrites[^\n]*\n(?:\/islands\/[^\n]*\n)*/g,``).trim();let g=`# Island JS path rewrites (generated by Avalon post-build)
2
2
  `;s(m,h?`${h}\n\n${g}${p.join(`
3
3
  `)}\n`:`${g+p.join(`
4
- `)}\n`),console.log(`[redirects] ✅ Wrote ${p.length} island redirects + local copies`)}function y(t,a){let o=[l(t,`.output`,`public`,`_adapters`),l(a,`_adapters`)];for(let t of o){if(!n(t))continue;let o=i(t).filter(e=>e.endsWith(`.js`));if(o.length===0)continue;let s=l(a,`_adapters`);r(s,{recursive:!0});for(let n of o){let r=l(t,n),i=l(s,n);r!==i&&e(r,i)}console.log(`[adapters] ✅ Copied ${o.length} framework adapters`);return}console.log(`[adapters] No _adapters/ directory found`)}function b(e){let r=l(e,`.netlify`,`functions-internal`,`server`);if(!n(r))return;let i=[l(e,`.netlify`,`v1`,`functions`,`server`)];for(let n of i){t(r,n,{recursive:!0,force:!0});let i=n.substring(e.length).replaceAll(`\\`,`/`);console.log(`[netlify-fn] ✅ Copied server function to ${i}/`)}}function x(e){let t=a(e,`utf-8`);return t.includes(`path: "/*"`)||t.includes("path:`/*`")}function S(e,t,r){let i=l(c(e),`_prerender-server.mjs`),a=``,o=[l(r,`node_modules`,`urlpattern-polyfill`,`index.js`),l(r,`node_modules`,`urlpattern-polyfill`,`dist`,`urlpattern.js`)].find(e=>n(e));return o&&(a=`import '${o.replaceAll(`\\`,`/`)}';`),s(i,`
4
+ `)}\n`),console.log(`[redirects] ✅ Wrote ${p.length} island redirects + local copies`)}function b(t,a){let o=[l(t,`.output`,`public`,`_adapters`),l(a,`_adapters`)];for(let t of o){if(!n(t))continue;let o=i(t).filter(e=>e.endsWith(`.js`));if(o.length===0)continue;let s=l(a,`_adapters`);r(s,{recursive:!0});for(let n of o){let r=l(t,n),i=l(s,n);r!==i&&e(r,i)}console.log(`[adapters] ✅ Copied ${o.length} framework adapters`);return}console.log(`[adapters] No _adapters/ directory found`)}function x(e){let r=l(e,`.netlify`,`functions-internal`,`server`);if(!n(r))return;let i=[l(e,`.netlify`,`v1`,`functions`,`server`)];for(let n of i){t(r,n,{recursive:!0,force:!0});let i=n.substring(e.length).replaceAll(`\\`,`/`);console.log(`[netlify-fn] ✅ Copied server function to ${i}/`)}}function S(e){let t=a(e,`utf-8`);return t.includes(`path: "/*"`)||t.includes("path:`/*`")}function C(e,t,r){let i=l(c(e),`_prerender-server.mjs`),a=``,o=[l(r,`node_modules`,`urlpattern-polyfill`,`index.js`),l(r,`node_modules`,`urlpattern-polyfill`,`dist`,`urlpattern.js`)].find(e=>n(e));return o&&(a=`import '${o.replaceAll(`\\`,`/`)}';`),s(i,`
5
5
  ${a}
6
6
  import { createServer } from 'node:http';
7
7
  import handler from './main.mjs';
@@ -27,6 +27,6 @@ const server = createServer(async (req, res) => {
27
27
  server.listen(PORT, '127.0.0.1', () => {
28
28
  console.log('[prerender-wrapper] Listening on http://127.0.0.1:' + PORT);
29
29
  });
30
- `),i}function C(e){let t=[],n=/<a\s[^>]*href=["']([^"'#?]+)/gi,r=null;for(r=n.exec(e);r!==null;r=n.exec(e)){let e=r[1];e.startsWith(`/`)&&!e.startsWith(`//`)&&!e.startsWith(`/assets/`)&&!e.startsWith(`/islands/`)&&!e.startsWith(`/chunks/`)&&!e.startsWith(`/_`)&&!e.match(/\.\w{2,5}$/)&&t.push(e)}return[...new Set(t)]}async function w(t,i,d,f){let p=[l(t,`.netlify`,`functions-internal`,`server`,`server.mjs`),l(t,`.netlify`,`v1`,`functions`,`server`,`server.mjs`),l(t,`.output`,`server`,`index.mjs`)].find(e=>n(e));if(!p){console.log(`[prerender] No server entry found, skipping prerender`);return}let m=[l(t,`.output`,`public`),i].find(e=>n(e));if(!m){console.log(`[prerender] No output directory found, skipping prerender`);return}let h={routes:d.routes??[`/`],crawlLinks:d.crawlLinks??!0,ignore:d.ignore??[],failOnError:d.failOnError??!1,concurrency:d.concurrency??4,autoSubfolderIndex:d.autoSubfolderIndex??!0,retry:d.retry??3,retryDelay:d.retryDelay??500},g=`http://localhost:${f}`,_=x(p),v=p;if(_){let e=l(c(p),`main.mjs`);if(!n(e)){console.error(`[prerender] Netlify handler detected but main.mjs not found`);return}v=S(e,f,t),console.log(`[prerender] Netlify handler detected — using wrapper`)}{let e=[p,l(c(p),`main.mjs`)].filter(e=>n(e));for(let n of e){let e=a(n,`utf-8`),r=/"\/[^"]*\.html":\{[^}]+\},?/g,i=e.length;e=e.replaceAll(r,``),i!==e.length&&(s(n,e),console.log(`[prerender] Patched ${u(t,n)}: removed HTML asset entries`))}}console.log(`[prerender] Starting prerender with server: ${u(t,v)}`);let{spawn:y}=await import(`node:child_process`),b;try{b=y(`node`,[v],{env:{...process.env,PORT:String(f),NITRO_PORT:String(f),HOST:`127.0.0.1`,NITRO_HOST:`127.0.0.1`,NODE_ENV:`production`},stdio:[`ignore`,`pipe`,`pipe`]}),b.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.log(`[prerender:server] ${t}`)}),b.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`[prerender:server:err] ${t}`)});let e=Date.now(),t=!1;for(;Date.now()-e<15e3;){try{let e=await fetch(`${g}/`);if(e.ok||e.status<500){t=!0;break}}catch{}await new Promise(e=>setTimeout(e,200))}if(!t)throw Error(`Server did not become ready within 15s`);console.log(`[prerender] Server ready at ${g}`)}catch(e){b?.kill(`SIGKILL`),console.error(`[prerender] Failed to start server:`,e.message);return}let w=new Set,T=[...h.routes],E=[],D=[];function O(e){for(let t of h.ignore)if(typeof t==`string`&&e===t||typeof t==`string`&&t.endsWith(`/**`)&&e.startsWith(t.slice(0,-2)))return!0;return!1}try{for(;T.length>0;){let e=T.splice(0,h.concurrency);await Promise.all(e.map(async e=>{let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;if(w.has(t)||(w.add(t),O(t)))return;let n=null;for(let e=1;e<=h.retry;e++)try{let e=await fetch(`${g}${t}`);n={html:await e.text(),status:e.status};break}catch{e<h.retry&&await new Promise(e=>setTimeout(e,h.retryDelay))}if(!n){D.push({route:t,error:`Failed after ${h.retry} attempts`});return}if(n.status>=400){D.push({route:t,error:`Returned ${n.status}`});return}let i=h.autoSubfolderIndex?l(t,`index.html`):`${t}.html`,a=l(m,i);if(r(c(a),{recursive:!0}),s(a,n.html.replace(`<!DOCTYPE html>`,`<!DOCTYPE html>
31
- <!-- SSG: prerendered at build time -->`).replaceAll(/<link rel="stylesheet" href="\/assets\/[^"]*\.css">\n?/g,e=>e.includes(`_isolated-island-entry`)?``:e)),E.push(t),console.log(`[prerender] ✅ ${t} → ${i}`),h.crawlLinks)for(let e of C(n.html)){let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;!w.has(t)&&!O(t)&&T.push(t)}}))}}finally{console.log(`[prerender] Shutting down server...`),b?.kill(`SIGKILL`)}if(console.log(`[prerender] Done: ${E.length} page(s) prerendered`+(D.length>0?`, ${D.length} error(s)`:``)),_){let e=l(c(p),`_prerender-server.mjs`);n(e)&&(o(e),console.log(`[prerender] Cleaned up wrapper script`))}if(E.length>0){let a=[i,l(t,`.netlify`,`functions-internal`,`server`,`public`),l(t,`.netlify`,`v1`,`functions`,`server`,`public`)].filter(e=>e!==m&&n(c(e)));for(let t of a)for(let i of E){let a=l(i,`index.html`),o=l(m,a),s=l(t,a);n(o)&&(r(c(s),{recursive:!0}),e(o,s))}a.length>0&&console.log(`[prerender] Copied prerendered HTML to ${a.length} additional output dir(s)`)}}function T(e,t){let r={},i=l(t,`island-deps.json`);if(n(i))try{r=JSON.parse(a(i,`utf-8`))}catch{}let o=l(e,`.output`,`public`);if(Object.keys(r).length===0&&n(o)){let e=d(l(o,`islands`),e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));for(let t of e){let e=`/${t.substring(o.length+1).replaceAll(`\\`,`/`)}`,n=a(t,`utf-8`),i=/\bfrom\s*["']([^"']+)["']|import\s*["']([^"']+)["']/g,s=[],u;for(u=i.exec(n);u!==null;u=i.exec(n)){let t=u[1]||u[2];if(t&&(t.includes(`/assets/`)||t.startsWith(`.`))){let n=(t.startsWith(`.`)?`/${l(c(e.slice(1)),t).replaceAll(`\\`,`/`).replace(/^\/+/,``)}`:t).split(`/`).filter(Boolean),r=[];for(let e of n)e===`..`?r.pop():e!==`.`&&r.push(e);s.push(`/${r.join(`/`)}`)}}s.length>0&&(r[e]=s)}}if(Object.keys(r).length===0)return;let u=[l(e,`.output`,`public`),t],f=0;for(let e of u){if(!n(e))continue;let t=d(e,e=>e===`index.html`);for(let e of t){let t=a(e,`utf-8`),n=new Set;for(let[e,i]of Object.entries(r))if(t.includes(e))for(let e of i)t.includes(`href="${e}"`)||n.add(e);if(n.size===0)continue;let i=Array.from(n).map(e=>`<link rel="modulepreload" href="${e}">`).join(`
32
- `);t.includes(`</head>`)&&(t=t.replace(`</head>`,`${i}\n</head>`),s(e,t),f++)}}f>0&&console.log(`[modulepreload] ✅ Injected dependency preloads into ${f} HTML file(s)`)}export async function runPostBuild(e={}){let t=e.cwd??process.cwd(),r=l(t,`dist`),i=e.prerenderPort??13172;p(t),g(t,r);for(let e of[l(t,`.netlify`,`functions-internal`,`server`,`_ssr`,`ssr.mjs`),l(t,`.netlify`,`v1`,`functions`,`server`,`_ssr`,`ssr.mjs`),l(t,`.output`,`server`,`_ssr`,`ssr.mjs`)])n(e)&&(console.log(`[patch] Patching ${e}`),m(e,r,t));_(t,r),v(r),y(t,r),b(t),e.prerender!==!1&&await w(t,r,e.prerender??{},i),T(t,r),console.log(`[post-build] ✅ Complete`)}
30
+ `),i}function w(e){let t=[],n=/<a\s[^>]*href=["']([^"'#?]+)/gi,r=null;for(r=n.exec(e);r!==null;r=n.exec(e)){let e=r[1];e.startsWith(`/`)&&!e.startsWith(`//`)&&!e.startsWith(`/assets/`)&&!e.startsWith(`/islands/`)&&!e.startsWith(`/chunks/`)&&!e.startsWith(`/_`)&&!e.match(/\.\w{2,5}$/)&&t.push(e)}return[...new Set(t)]}async function T(t,i,d,f){let p=[l(t,`.netlify`,`functions-internal`,`server`,`server.mjs`),l(t,`.netlify`,`v1`,`functions`,`server`,`server.mjs`),l(t,`.output`,`server`,`index.mjs`)].find(e=>n(e));if(!p){console.log(`[prerender] No server entry found, skipping prerender`);return}let m=[l(t,`.output`,`public`),i].find(e=>n(e));if(!m){console.log(`[prerender] No output directory found, skipping prerender`);return}let h={routes:d.routes??[`/`],crawlLinks:d.crawlLinks??!0,ignore:d.ignore??[],failOnError:d.failOnError??!1,concurrency:d.concurrency??4,autoSubfolderIndex:d.autoSubfolderIndex??!0,retry:d.retry??3,retryDelay:d.retryDelay??500},g=`http://localhost:${f}`,_=S(p),v=p;if(_){let e=l(c(p),`main.mjs`);if(!n(e)){console.error(`[prerender] Netlify handler detected but main.mjs not found`);return}v=C(e,f,t),console.log(`[prerender] Netlify handler detected — using wrapper`)}{let e=[p,l(c(p),`main.mjs`)].filter(e=>n(e));for(let n of e){let e=a(n,`utf-8`),r=/"\/[^"]*\.html":\{[^}]+\},?/g,i=e.length;e=e.replaceAll(r,``),i!==e.length&&(s(n,e),console.log(`[prerender] Patched ${u(t,n)}: removed HTML asset entries`))}}console.log(`[prerender] Starting prerender with server: ${u(t,v)}`);let{spawn:y}=await import(`node:child_process`),b;try{b=y(`node`,[v],{env:{...process.env,PORT:String(f),NITRO_PORT:String(f),HOST:`127.0.0.1`,NITRO_HOST:`127.0.0.1`,NODE_ENV:`production`},stdio:[`ignore`,`pipe`,`pipe`]}),b.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.log(`[prerender:server] ${t}`)}),b.stderr?.on(`data`,e=>{let t=e.toString().trim();t&&console.error(`[prerender:server:err] ${t}`)});let e=Date.now(),t=!1;for(;Date.now()-e<15e3;){try{let e=await fetch(`${g}/`);if(e.ok||e.status<500){t=!0;break}}catch{}await new Promise(e=>setTimeout(e,200))}if(!t)throw Error(`Server did not become ready within 15s`);console.log(`[prerender] Server ready at ${g}`)}catch(e){b?.kill(`SIGKILL`),console.error(`[prerender] Failed to start server:`,e.message);return}let x=new Set,T=[...h.routes],E=[],D=[];function O(e){for(let t of h.ignore)if(typeof t==`string`&&e===t||typeof t==`string`&&t.endsWith(`/**`)&&e.startsWith(t.slice(0,-2)))return!0;return!1}try{for(;T.length>0;){let e=T.splice(0,h.concurrency);await Promise.all(e.map(async e=>{let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;if(x.has(t)||(x.add(t),O(t)))return;let n=null;for(let e=1;e<=h.retry;e++)try{let e=await fetch(`${g}${t}`);n={html:await e.text(),status:e.status};break}catch{e<h.retry&&await new Promise(e=>setTimeout(e,h.retryDelay))}if(!n){D.push({route:t,error:`Failed after ${h.retry} attempts`});return}if(n.status>=400){D.push({route:t,error:`Returned ${n.status}`});return}let i=h.autoSubfolderIndex?l(t,`index.html`):`${t}.html`,a=l(m,i);if(r(c(a),{recursive:!0}),s(a,n.html.replace(`<!DOCTYPE html>`,`<!DOCTYPE html>
31
+ <!-- SSG: prerendered at build time -->`).replaceAll(/<link rel="stylesheet" href="\/assets\/[^"]*\.css">\n?/g,e=>e.includes(`_isolated-island-entry`)?``:e)),E.push(t),console.log(`[prerender] ✅ ${t} → ${i}`),h.crawlLinks)for(let e of w(n.html)){let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;!x.has(t)&&!O(t)&&T.push(t)}}))}}finally{console.log(`[prerender] Shutting down server...`),b?.kill(`SIGKILL`)}if(console.log(`[prerender] Done: ${E.length} page(s) prerendered`+(D.length>0?`, ${D.length} error(s)`:``)),_){let e=l(c(p),`_prerender-server.mjs`);n(e)&&(o(e),console.log(`[prerender] Cleaned up wrapper script`))}if(E.length>0){let a=[i,l(t,`.netlify`,`functions-internal`,`server`,`public`),l(t,`.netlify`,`v1`,`functions`,`server`,`public`)].filter(e=>e!==m&&n(c(e)));for(let t of a)for(let i of E){let a=l(i,`index.html`),o=l(m,a),s=l(t,a);n(o)&&(r(c(s),{recursive:!0}),e(o,s))}a.length>0&&console.log(`[prerender] Copied prerendered HTML to ${a.length} additional output dir(s)`)}}function E(e,t){let r={},i=l(t,`island-deps.json`);if(n(i))try{r=JSON.parse(a(i,`utf-8`))}catch{}let o=l(e,`.output`,`public`);if(Object.keys(r).length===0&&n(o)){let e=d(l(o,`islands`),e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));for(let t of e){let e=`/${t.substring(o.length+1).replaceAll(`\\`,`/`)}`,n=a(t,`utf-8`),i=/\bfrom\s*["']([^"']+)["']|import\s*["']([^"']+)["']/g,s=[],u;for(u=i.exec(n);u!==null;u=i.exec(n)){let t=u[1]||u[2];if(t&&(t.includes(`/assets/`)||t.startsWith(`.`))){let n=(t.startsWith(`.`)?`/${l(c(e.slice(1)),t).replaceAll(`\\`,`/`).replace(/^\/+/,``)}`:t).split(`/`).filter(Boolean),r=[];for(let e of n)e===`..`?r.pop():e!==`.`&&r.push(e);s.push(`/${r.join(`/`)}`)}}s.length>0&&(r[e]=s)}}if(Object.keys(r).length===0)return;let u=[l(e,`.output`,`public`),t],f=0;for(let e of u){if(!n(e))continue;let t=d(e,e=>e===`index.html`);for(let e of t){let t=a(e,`utf-8`),n=new Set;for(let[e,i]of Object.entries(r))if(t.includes(e))for(let e of i)t.includes(`href="${e}"`)||n.add(e);if(n.size===0)continue;let i=Array.from(n).map(e=>`<link rel="modulepreload" href="${e}">`).join(`
32
+ `);t.includes(`</head>`)&&(t=t.replace(`</head>`,`${i}\n</head>`),s(e,t),f++)}}f>0&&console.log(`[modulepreload] ✅ Injected dependency preloads into ${f} HTML file(s)`)}async function D(e){let{promisify:t}=await import(`node:util`),r=await import(`node:zlib`),i=t(r.brotliCompress),o=t(r.gzip),c=[l(e,`.output`,`public`),l(e,`.netlify`,`functions-internal`,`server`,`public`)],u=e=>e.endsWith(`.js`)||e.endsWith(`.css`)||e.endsWith(`.html`)||e.endsWith(`.svg`)||e.endsWith(`.txt`)||e.endsWith(`.xml`)||e.endsWith(`.json`),f=0;for(let e of c){if(!n(e))continue;let t=d(e,e=>u(e)&&!e.endsWith(`.map`));for(let e of t){let t=a(e);if(!(t.length<256))try{let[n,a]=await Promise.all([i(t,{params:{[r.constants.BROTLI_PARAM_QUALITY]:11}}),o(t,{level:9})]);s(`${e}.br`,n),s(`${e}.gz`,a),f++}catch{}}}f>0&&console.log(`[compress] ✅ Compressed ${f} public asset(s) (brotli + gzip)`)}export async function runPostBuild(e={}){let t=e.cwd??process.cwd(),r=l(t,`dist`),i=e.prerenderPort??13172;p(t),g(t,r);for(let e of[l(t,`.netlify`,`functions-internal`,`server`,`_ssr`,`ssr.mjs`),l(t,`.netlify`,`v1`,`functions`,`server`,`_ssr`,`ssr.mjs`),l(t,`.output`,`server`,`_ssr`,`ssr.mjs`)])n(e)&&(console.log(`[patch] Patching ${e}`),m(e,r,t));await _(t,r),v(t,r),y(r),b(t,r),x(t),e.prerender!==!1&&await T(t,r,e.prerender??{},i),E(t,r),await D(t),console.log(`[post-build] ✅ Complete`)}
@@ -35,7 +35,14 @@ export interface TreeshakeConfig {
35
35
  unknownGlobalSideEffects: boolean;
36
36
  manualPureFunctions: string[];
37
37
  }
38
- /** Default tree-shaking config with aggressive settings and Solid runtime pure functions */
38
+ /**
39
+ * Default tree-shaking config for isolated island builds.
40
+ *
41
+ * manualPureFunctions is intentionally empty — framework runtime functions
42
+ * like createSignal, createEffect, template, insert, and delegateEvents
43
+ * have side effects that are required for hydration. Marking them as pure
44
+ * causes the tree-shaker to strip hydration code paths and event delegation.
45
+ */
39
46
  export declare const DEFAULT_TREESHAKE_CONFIG: TreeshakeConfig;
40
47
  /**
41
48
  * Deep-merge treeshake overrides into defaults.
@@ -1,3 +1,3 @@
1
- import{existsSync as e,statSync as t}from"node:fs";import{resolve as n}from"node:path";export const DEFAULT_TREESHAKE_CONFIG={annotations:!0,moduleSideEffects:!1,propertyReadSideEffects:!1,unknownGlobalSideEffects:!1,manualPureFunctions:[`createSignal`,`createEffect`,`createMemo`,`createComponent`,`template`,`insert`,`delegateEvents`,`setAttribute`,`effect`,`memo`,`spread`,`mergeProps`,`splitProps`,`className`,`classList`,`style`,`addEventListener`]};export function mergeTreeshakeConfig(e,t){return{annotations:t.annotations??e.annotations,moduleSideEffects:t.moduleSideEffects??e.moduleSideEffects,propertyReadSideEffects:t.propertyReadSideEffects??e.propertyReadSideEffects,unknownGlobalSideEffects:t.unknownGlobalSideEffects??e.unknownGlobalSideEffects,manualPureFunctions:[...e.manualPureFunctions,...t.manualPureFunctions??[]]}}const a={solid:`@useavalon/solid/client`,preact:`@useavalon/preact/client`,react:`@useavalon/react/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`};export function generateWrapperCode(e,t){let n=JSON.stringify(e);if(t===`qwik`)return[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`].join(`
1
+ import{existsSync as e,statSync as t}from"node:fs";import{resolve as n}from"node:path";export const DEFAULT_TREESHAKE_CONFIG={annotations:!0,moduleSideEffects:!0,propertyReadSideEffects:!1,unknownGlobalSideEffects:!1,manualPureFunctions:[]};export function mergeTreeshakeConfig(e,t){return{annotations:t.annotations??e.annotations,moduleSideEffects:t.moduleSideEffects??e.moduleSideEffects,propertyReadSideEffects:t.propertyReadSideEffects??e.propertyReadSideEffects,unknownGlobalSideEffects:t.unknownGlobalSideEffects??e.unknownGlobalSideEffects,manualPureFunctions:[...e.manualPureFunctions,...t.manualPureFunctions??[]]}}const a={solid:`@useavalon/solid/client`,preact:`@useavalon/preact/client`,react:`@useavalon/react/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`};export function generateWrapperCode(e,t){let n=JSON.stringify(e);if(t===`qwik`)return[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`].join(`
2
2
  `);let r=a[t],i=[`import __C from ${n};`,`var Component = __C;`,`export { Component as default, Component };`,`if(typeof globalThis<"u")globalThis.__avalonIsland=Component;`];return r&&i.push(`export { hydrate as __hydrateIsland } from ${JSON.stringify(r)};`),i.join(`
3
3
  `)}export function generateIntegrationLoaderForFramework(e){let t=a[e];return t?`export { hydrate } from ${JSON.stringify(t)};`:`export {};`}async function c(e,t){let n=[],{resolve:r}=await import(`node:path`),{existsSync:i}=await import(`node:fs`),{pathToFileURL:a}=await import(`node:url`),o={solid:{pkg:`vite-plugin-solid`,esmEntry:`dist/esm/index.mjs`},vue:{pkg:`@vitejs/plugin-vue`,esmEntry:`dist/index.mjs`},svelte:{pkg:`@sveltejs/vite-plugin-svelte`,esmEntry:`src/index.js`}}[e];if(!o)return n;try{let s=null,c=t;for(let e=0;e<8;e++){let e=r(c,`node_modules`,o.pkg,o.esmEntry);if(i(e)){s=e;break}for(let e of[`solid`,`vue`,`svelte`,`preact`,`react`,`lit`]){let t=r(c,`packages`,`integrations`,e,`node_modules`,o.pkg,o.esmEntry);if(i(t)){s=t;break}}if(s)break;c=r(c,`..`)}if(!s)throw Error(`Cannot find package '${o.pkg}'`);let l=await import(a(s).href);switch(e){case`solid`:n.push((l.default??l)({ssr:!1,hot:!1}));break;case`vue`:n.push((l.default??l)());break;case`svelte`:n.push((l.svelte??l.default)());break}}catch(t){console.warn(` ⚠ Could not load ${e} plugin: ${t instanceof Error?t.message:t}`)}return n}async function l(e){let{createRequire:t}=await import(`node:module`),{existsSync:n}=await import(`node:fs`),r=t(`${e}/package.json`),i=e=>{try{let t=r.resolve(e);return t.endsWith(`.js`)&&n(t.replace(/\.js$/,`.mjs`))?t.replace(/\.js$/,`.mjs`):t}catch{return null}},a={preact:i(`preact`),"preact/hooks":i(`preact/hooks`),"preact/compat":i(`preact/compat`),"preact/compat/client":i(`preact/compat/client`),"preact/compat/server":i(`preact/compat/server`),"preact/jsx-runtime":i(`preact/jsx-runtime`),react:i(`preact/compat`),"react/jsx-runtime":i(`preact/jsx-runtime`),"react/jsx-dev-runtime":i(`preact/jsx-runtime`),"react-dom":i(`preact/compat`),"react-dom/client":i(`preact/compat/client`),"react-dom/server":i(`preact/compat/server`)};return{name:`avalon:isolated-preact-compat`,enforce:`pre`,resolveId(e){return a[e]??null}}}export async function buildIsolatedIslands(a,u,d,f,p,m){if(d.size===0)return[];let{build:h}=await import(`vite`);console.log(`🏝️ Building ${d.size} islands in isolation...`);let g=performance.now(),_=m?.treeshake?mergeTreeshakeConfig(DEFAULT_TREESHAKE_CONFIG,m.treeshake):DEFAULT_TREESHAKE_CONFIG,v=[];for(let[,r]of d){let{filePath:i,bundleKey:d,framework:m}=r,g=`islands/${d}.js`;if(m===`qwik`||m===`lit`){v.push({island:g,success:!0});continue}let y=generateWrapperCode(i,m),b=`\0isolated-island-entry`,x=`\0virtual:avalon/integration-loader`;try{let r=await c(m,a),i=await l(a),o=performance.now(),S=await h({configFile:!1,root:a,logLevel:`silent`,plugins:[{name:`avalon:isolated-island-virtual`,resolveId(e){return e===b?e:e===`virtual:avalon/integration-loader`||e===x?x:null},load(e){return e===b?y:e===x?generateIntegrationLoaderForFramework(m):null}},i,...r],build:{write:!0,outDir:n(a,u),emptyOutDir:!1,minify:`oxc`,target:`es2020`,rollupOptions:{input:b,output:{format:`es`,entryFileNames:g},preserveEntrySignatures:`exports-only`,treeshake:_}},resolve:{alias:f},define:{...p,__DEV__:`false`,__PROD__:`true`,"process.env.NODE_ENV":`"production"`}}),C=performance.now()-o,w=n(a,u,g),T=e(w)?t(w).size:0,E=[],D=Array.isArray(S)?S:[S];for(let e of D)if(e&&`output`in e)for(let t of e.output)t.type===`chunk`&&t.fileName!==g&&E.push(`/${t.fileName}`);v.push({island:g,success:!0,size:T,elapsedMs:C,deps:E}),console.log(` ✅ ${d} (${m}): ${(T/1024).toFixed(1)} KiB`),C>2e3&&console.warn(` ⚠ ${d} (${m}): build took ${C.toFixed(0)}ms (>2s)`)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ❌ ${d} (${m}): ${t}`),v.push({island:g,success:!1,error:t})}}let y=((performance.now()-g)/1e3).toFixed(1),b=v.filter(e=>e.success).length,x=v.filter(e=>!e.success).length;console.log(`🏝️ Done in ${y}s: ${b} built${x?`, ${x} failed`:``}`);let S={};for(let e of v)e.success&&e.deps&&e.deps.length>0&&(S[`/${e.island}`]=e.deps);if(Object.keys(S).length>0){let e=n(a,u,`island-deps.json`),{writeFileSync:t}=await import(`node:fs`);t(e,JSON.stringify(S))}return v}
@@ -22,16 +22,16 @@ export declare const VIRTUAL_MODULE_IDS: {
22
22
  readonly INTEGRATION_LOADER: "virtual:avalon/integration-loader";
23
23
  };
24
24
  export declare const RESOLVED_VIRTUAL_IDS: {
25
- readonly PAGE_ROUTES: string;
26
- readonly PAGE_LOADER: string;
27
- readonly ISLAND_MANIFEST: string;
28
- readonly RUNTIME_CONFIG: string;
29
- readonly CONFIG: string;
30
- readonly LAYOUTS: string;
31
- readonly ASSETS: string;
32
- readonly RENDERER: string;
33
- readonly CLIENT_ENTRY: string;
34
- readonly INTEGRATION_LOADER: string;
25
+ readonly PAGE_ROUTES: "\0virtual:avalon/page-routes";
26
+ readonly PAGE_LOADER: "\0virtual:avalon/page-loader";
27
+ readonly ISLAND_MANIFEST: "\0virtual:avalon/island-manifest";
28
+ readonly RUNTIME_CONFIG: "\0virtual:avalon/runtime-config";
29
+ readonly CONFIG: "\0virtual:avalon/config";
30
+ readonly LAYOUTS: "\0virtual:avalon/layouts";
31
+ readonly ASSETS: "\0virtual:avalon/assets";
32
+ readonly RENDERER: "\0virtual:avalon/renderer";
33
+ readonly CLIENT_ENTRY: "\0virtual:avalon/client-entry";
34
+ readonly INTEGRATION_LOADER: "\0virtual:avalon/integration-loader";
35
35
  };
36
36
  export interface NitroIntegrationResult {
37
37
  nitroOptions: NitroConfigOutput;
@@ -1,20 +1,19 @@
1
- import{existsSync as e,readdirSync as t}from"node:fs";import{stat as n}from"node:fs/promises";import{createRequire as r}from"node:module";import{dirname as i,join as a,relative as o,resolve as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{getUniversalCSSForHead as u}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as d,injectSolidHydrationScriptIfNeeded as f}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as p,discoverScopedMiddleware as m,executeScopedMiddleware as h}from"../middleware/index.js";import{createNitroConfig as g}from"../nitro/config.js";import{createIslandManifestPlugin as _,createNitroBuildPlugin as v,createSourceMapConfig as y,createSourceMapPlugin as b}from"../nitro/index.js";import{collectCssFromModuleGraph as x,injectSsrCss as S}from"../render/collect-css.js";import{generateErrorPage as C,generateFallback404 as w}from"../render/error-pages.js";function T(t){let n=a(i(r(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 E(t,n){let o=a(i(r(a(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(o)){let t=o.replace(/\.ts$/,`.js`);if(e(t))return t}return o}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`};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};export function createNitroIntegration(e,t={}){let n=g(t,e),r={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/]};t.renderer===!1?r.renderer=!1:n.renderer&&(r.renderer=n.renderer),n.publicRuntimeConfig&&(r.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(r.publicAssets=n.publicAssets),n.compressPublicAssets&&(r.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(r.serverEntry=n.serverEntry);let i=n.traceDeps??[];r.traceDeps=[...new Set([`undici`,...i])],n.prerender&&(r.prerender={routes:[],crawlLinks:!1});let a=c(r),o=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),s=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),l=v(e,t),u=_(e,{verbose:e.verbose,generatePreloadHints:!0}),d=b(y(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(a)?a:[a],o,s,l,u,d]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonConfig=t,globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`},configureServer(e){globalThis.__viteDevServer=e;let n=null;async function i(){return n||=await m({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),n}function a(){n=null}F(e,t,r,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let o=e.environments?.ssr,s=!!o&&l(o);s&&N(e,t.integrations,r).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,a,o)=>{if(!s)return o();let c=n.url||`/`;if(c.endsWith(`.html`)&&(c=c.slice(0,-5)||`/`),c===`/index`&&(c=`/`),c.startsWith(`/@`)||c.startsWith(`/__`)||c.startsWith(`/node_modules/`)||c.startsWith(`/src/client/`)||c.startsWith(`/packages/`)||c.includes(`.`)&&!c.endsWith(`/`)||c.startsWith(`/api/`))return o();try{if(await j(e,c,n,a,i,r)||await q(e,c,t,a))return;let o=await J(e,c,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await M(e,c,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(C(e))}})},buildStart(){}}}async function j(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 h({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 M(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(w(t))}}async function N(e,t,n){let r=performance.now(),i=[{path:T(`src/render/ssr.ts`),assignTo:`ssr`},{path:T(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:T(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:E(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`&&(G=r),n===`layout`&&(K=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,c=null,l=a,u=o,d=s,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=l(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))}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:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await I(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await L(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?R():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?z(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(c||=await B(n,r,p),c):e===RESOLVED_VIRTUAL_IDS.ASSETS?V(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?H(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await U(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):null},handleHotUpdate({file:e,server:t}){if(e.includes(n.pagesDir)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&t.moduleGraph.invalidateModule(e)}if(e.includes(`/layouts/`)||e.includes(`_layout`)||e.endsWith(`.css`)){c=null,h();let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&t.moduleGraph.invalidateModule(e);let n=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);n&&t.moduleGraph.invalidateModule(n)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&t.moduleGraph.invalidateModule(e)}}}}function F(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(p(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(G=null,K=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(p(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(p(),r?.())})}async function I(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 = [];
1
+ import{existsSync as e,readdirSync as t}from"node:fs";import{stat as n}from"node:fs/promises";import{createRequire as r}from"node:module";import{dirname as i,join as a,relative as o,resolve as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{getUniversalCSSForHead as u}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as d,injectSolidHydrationScriptIfNeeded as f}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as p,discoverScopedMiddleware as m,executeScopedMiddleware as h}from"../middleware/index.js";import{createNitroConfig as g}from"../nitro/config.js";import{createIslandManifestPlugin as _,createNitroBuildPlugin as v,createSourceMapConfig as y,createSourceMapPlugin as b}from"../nitro/index.js";import{collectCssFromModuleGraph as x,injectSsrCss as S}from"../render/collect-css.js";import{generateErrorPage as C,generateFallback404 as w}from"../render/error-pages.js";function T(t){let n=a(i(r(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 E(t,n){let o=a(i(r(a(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(o)){let t=o.replace(/\.ts$/,`.js`);if(e(t))return t}return o}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`};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}`};export function createNitroIntegration(e,t={}){let n=g(t,e),r={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/]};t.renderer===!1?r.renderer=!1:n.renderer&&(r.renderer=n.renderer),n.publicRuntimeConfig&&(r.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(r.publicAssets=n.publicAssets),n.compressPublicAssets&&(r.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(r.serverEntry=n.serverEntry);let i=n.traceDeps??[];r.traceDeps=[...new Set([`undici`,...i])],n.prerender&&(r.prerender={routes:[],crawlLinks:!1});let a=c(r),o=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),s=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),l=v(e,t),u=_(e,{verbose:e.verbose,generatePreloadHints:!0}),d=b(y(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(a)?a:[a],o,s,l,u,d]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`},configureServer(e){globalThis.__viteDevServer=e;let r=null;async function i(){return r||=await m({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),r}function a(){r=null}F(e,t,n,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let o=e.environments?.ssr,s=!!o&&l(o);s&&N(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(r,a,o)=>{if(!s)return o();let c=r.url||`/`;if(c.endsWith(`.html`)&&(c=c.slice(0,-5)||`/`),c===`/index`&&(c=`/`),c.startsWith(`/@`)||c.startsWith(`/__`)||c.startsWith(`/node_modules/`)||c.startsWith(`/src/client/`)||c.startsWith(`/packages/`)||c.includes(`.`)&&!c.endsWith(`/`)||c.startsWith(`/api/`))return o();try{if(await j(e,c,r,a,i,n)||await q(e,c,t,a))return;let o=await J(e,c,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await M(e,c,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(C(e))}})},buildStart(){}}}async function j(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 h({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 M(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(w(t))}}async function N(e,t,n){let r=performance.now(),i=[{path:T(`src/render/ssr.ts`),assignTo:`ssr`},{path:T(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:T(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:E(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`&&(G=r),n===`layout`&&(K=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,c=null,l=a,u=o,d=s,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=l(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))}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:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await I(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await L(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?R():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?z(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(c||=await B(n,r,p),c):e===RESOLVED_VIRTUAL_IDS.ASSETS?V(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?H(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await U(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):null},handleHotUpdate({file:e,server:t}){if(e.includes(n.pagesDir)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&t.moduleGraph.invalidateModule(e)}if(e.includes(`/layouts/`)||e.includes(`_layout`)||e.endsWith(`.css`)){c=null,h();let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&t.moduleGraph.invalidateModule(e);let n=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);n&&t.moduleGraph.invalidateModule(n)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&t.moduleGraph.invalidateModule(e)}}}}function F(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(p(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(G=null,K=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(p(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(p(),r?.())})}async function I(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 = [];
2
2
  export default pageRoutes;
3
- `}}async function L(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(`,
3
+ `}}async function L(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(`,
4
4
  `),`];`,``,`/**`,` * Match a pathname against discovered routes and return the page module.`,` * Uses the same pattern matching as Avalon's route discovery.`,` */`,`export function loadPage(pathname) {`,` const cleanPath = pathname.split('?')[0];`,` for (const route of routes) {`,` if (matchRoute(cleanPath, route.pattern, route.params)) {`,` return route.module;`,` }`,` }`,` return null;`,`}`,``,`function matchRoute(pathname, pattern, paramNames) {`,` // Exact match`,` if (pattern === pathname) return true;`,` // Normalize trailing slashes`,` const normPath = pathname === '/' ? '/' : pathname.replace(/\\/$/, '');`,` const normPattern = pattern === '/' ? '/' : pattern.replace(/\\/$/, '');`,` if (normPath === normPattern) return true;`,` // Dynamic segments: /users/:id matches /users/123`,` if (paramNames.length > 0) {`,` const patternParts = normPattern.split('/');`,` const pathParts = normPath.split('/');`,` if (patternParts.length !== pathParts.length) return false;`,` return patternParts.every((part, i) => part.startsWith(':') || part === pathParts[i]);`,` }`,` return false;`,`}`,``,`export default { loadPage, routes };`,``].join(`
5
5
  `)}catch(e){return console.error(`[page-loader] Failed to generate page loader:`,e),`export function loadPage() { return null; }
6
6
  export default { loadPage, routes: [] };
7
7
  `}}function R(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
8
8
  export default islandManifest;
9
- `}function z(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={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev,...t.runtimeConfig};return`const config = ${JSON.stringify(n,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function B(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:i,resolve:o}=await import(`node:path`),{stat:s}=await import(`node:fs/promises`),c=process.cwd(),l=await r(e.layoutsDir,e.modules,c),u=[],d=0,f=o(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let r=a(t,`_layout.tsx`);try{if(!(await s(r)).isFile())continue}catch{continue}let o=i(c,r).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}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=u.map(e=>`import ${e.varName} from '${e.importPath}';`),g=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${t} }`}),_=p.length>0?p[0].varName:`null`,v=JSON.stringify(n);return[`// Auto-generated by Avalon — do not edit`,`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`,`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,...h,``,`const RootLayoutComponent = ${_};`,`const _cssLinks = ${v};`,``,`const moduleLayouts = [`,g.join(`,
9
+ `}function z(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`const config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function B(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:i,resolve:o}=await import(`node:path`),{stat:s}=await import(`node:fs/promises`),c=process.cwd(),l=await r(e.layoutsDir,e.modules,c),u=[],d=0,f=o(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let r=a(t,`_layout.tsx`);try{if(!(await s(r)).isFile())continue}catch{continue}let o=i(c,r).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}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=u.map(e=>`import ${e.varName} from '${e.importPath}';`),g=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${t} }`}),_=p.length>0?p[0].varName:`null`,v=JSON.stringify(n);return[`// Auto-generated by Avalon — do not edit`,`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`,`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,...h,``,`const RootLayoutComponent = ${_};`,`const _cssLinks = ${v};`,``,`const moduleLayouts = [`,g.join(`,
10
10
  `),`];`,``,`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">';`,` }).join('\\n');`,` if (html.includes('</head>')) {`,` html = html.replace('</head>', links + '\\n</head>');`,` }`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,` html = html.replace('</head>', universalCSS + '\\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,` 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('div', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` html = '<!DOCTYPE html>\\n' + preactRenderToString(resolvedRoot);`,` } 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>',`,` ].join('\\n');`,` }`,` } else {`,` const layoutProps = {`,` children: h('div', { 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 (!layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('div', { dangerouslySetInnerHTML: { __html: wrappedHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,` html = '<!DOCTYPE html>\\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
11
- `)}function V(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 || '';`,` // Only include global CSS entry-client and index (layout/global styles)`,` // Island-specific CSS (Counter-*, DocsSidebar-*, _isolated-island-entry-*, etc.)`,` // is loaded on-demand when the island's JS chunk imports it.`,` if (href.includes('entry-client')) return true;`,` if (href.includes('ssr-index')) return true;`,` // The main index CSS contains all CSS module styles — needed globally`,` if (/\\/index-[^/]+\\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,` .join('\\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,` .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>')) {`,` html = html.replace('</head>', cssLinks + '\\n' + jsPreloads + '\\n</head>');`,` }`,` if (html.includes('</body>')) {`,` html = html.replace('</body>', entryScript + '\\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
11
+ `)}function V(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;`,` if (/\\/index-[^/]+\\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,` .join('\\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,` .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>')) {`,` html = html.replace('</head>', cssLinks + '\\n' + jsPreloads + '\\n</head>');`,` }`,` if (html.includes('</body>')) {`,` html = html.replace('</body>', entryScript + '\\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
12
12
  `)}function H(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});`)}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,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const mod = loadPage(pathname);`,` if (!mod || !('default' in mod)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: {} };`,` },`,` loadPageModule: async (filePath) => {`,` const match = filePath.match(/^\\[virtual:(.+)\\]$/);`,` const pathname = match ? match[1] : filePath;`,` const mod = loadPage(pathname);`,` if (mod) return mod;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
13
- `)}async function U(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{readdir:r}=await import(`node:fs/promises`),{relative:i,join:a}=await import(`node:path`),o=process.cwd(),s=await n(e.layoutsDir,e.modules,o),c=[];for(let{dir:e}of s)try{let t=await r(e,{withFileTypes:!0});for(let n of t){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let t=i(o,a(e,n.name)).replaceAll(`\\`,`/`),r=t.startsWith(`/`)?t:`/`+t;c.push(r)}}catch{}let l=globalThis.__avalonConfig?.isDev??e.isDev?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,u=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?u.push(`import '${l}';`):u.push(`// Per-island hydration mode — no shared runtime needed`),u.push(``);let d=t.globalCSS??[];for(let e of d){let t=e.startsWith(`/`)?e:`/`+e;u.push(`// Global CSS`),u.push(`import '${t}';`)}if(d.length>0&&u.push(``),c.length>0){u.push(`// Layout CSS (auto-discovered)`);let e=0;for(let t of c)t.includes(`.module.`)?(u.push(`import _lcss${e} from '${t}';`),e++):u.push(`import '${t}';`)}return u.push(``),u.join(`
13
+ `)}async function U(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{readdir:r}=await import(`node:fs/promises`),{relative:i,join:a}=await import(`node:path`),o=process.cwd(),s=await n(e.layoutsDir,e.modules,o),c=[];for(let{dir:e}of s)try{let t=await r(e,{withFileTypes:!0});for(let n of t){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let t=i(o,a(e,n.name)).replaceAll(`\\`,`/`),r=t.startsWith(`/`)?t:`/${t}`;c.push(r)}}catch{}let l=globalThis.__avalonConfig?.isDev??e.isDev?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,u=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?u.push(`import '${l}';`):u.push(`// Per-island hydration mode — no shared runtime needed`),u.push(``);let d=t.globalCSS??[];for(let e of d){let t=e.startsWith(`/`)?e:`/${e}`;u.push(`// Global CSS`),u.push(`import '${t}';`)}if(d.length>0&&u.push(``),c.length>0){u.push(`// Layout CSS (auto-discovered)`);let e=0;for(let t of c)t.includes(`.module.`)?(u.push(`import _lcss${e} from '${t}';`),e++):u.push(`import '${t}';`)}return u.push(``),u.join(`
14
14
  `)}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:`@useavalon/preact/client`,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`,``];a&&!o&&(s.push(`// --- Inlined Solid adapter (production) ---`),s.push(`// Eliminates a separate chunk + network request for the Solid client adapter.`),s.push(`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`),s.push(`function _ensureHydrationContext() {`),s.push(` if (!globalThis._$HY) {`),s.push(` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`),s.push(` }`),s.push(`}`),s.push(``),s.push(`async function _solidHydrate(container, Component, props) {`),s.push(` if (!container) throw new Error("Container element is required for hydration");`),s.push(` if (!Component || typeof Component !== "function") {`),s.push(` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`),s.push(` }`),s.push(` var el = container;`),s.push(` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`),s.push(` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`),s.push(` _ensureHydrationContext();`),s.push(` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`),s.push(`}`),s.push(``),s.push(`var _solidModule = { hydrate: _solidHydrate };`),s.push(``)),s.push(`// --- loadIntegrationModule ---`),s.push(`export async function loadIntegrationModule(framework) {`),s.push(` switch (framework) {`);for(let e of t){let t=n[e];t&&(e===`solid`&&!o?(s.push(` case "solid":`),s.push(` return _solidModule;`)):e===`react`?s.push(` case "react":`):e===`preact`?(s.push(` case "preact":`),s.push(` return import("${t}");`)):(s.push(` case "${e}":`),s.push(` return import("${t}");`)))}t.includes(`react`)&&!t.includes(`preact`)&&s.push(` return import("${n.react}");`),s.push(` default:`),s.push(" throw new Error(`Unknown or unconfigured framework: ${framework}`);"),s.push(` }`),s.push(`}`),s.push(``),s.push(`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?(s.push(`export async function preLitHydration() {`),s.push(` await import("@useavalon/lit/client");`),s.push(`}`)):s.push(`export async function preLitHydration() {}`),s.push(``),s.push(`// --- HMR adapter loader ---`),s.push(`export async function loadHMRAdapter(framework) {`),s.push(` switch (framework) {`);for(let e of t){let t=r[e];t&&(s.push(` case "${e}":`),s.push(` return import("${t}").then(m => m.${e}Adapter);`))}return s.push(` default: return null;`),s.push(` }`),s.push(`}`),s.join(`
15
15
  `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const W=`<!--AVALON_STREAM_BOUNDARY-->`;let G=null,K=null;async function q(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),n=t.default;if(!n)return!1;let o=t.layoutConfig,s=await x(e,a),c=await Z(i,e),l=[];for(let t of c){let n=await e.ssrLoadModule(t);l.push({file:t,module:n})}for(let t of c){let n=await x(e,t);s.push(...n)}if(l.length===0)return!1;let{render:p}=await e.ssrLoadModule(`preact-render-to-string`),{h:m}=await e.ssrLoadModule(`preact`),h=o?.skipLayouts||[],g=l.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!h.includes(t)}),_=t.frontmatter,v=t.metadata,y={children:null,frontmatter:{..._,...v,currentPath:i},params:{},url:i},b=[],S=[];for(let e of g){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...y,children:m(`div`,null,`test`)}),r=p(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?b.push(e):S.push(e)}catch{S.push(e)}}if(b.length===0)return!1;let{module:C}=b[b.length-1],w=C.default;if(!w||typeof w!=`function`)return!1;let T;try{let e=w({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:W}})});T=p(e instanceof Promise?await e:e)}catch{return!1}let E=T.indexOf(W);if(E===-1)return!1;let D=T.slice(0,E),O=T.slice(E+29),k=D;if(s.length>0){let e=`<style data-avalon-ssr-css>${s.join(`
16
- `)}</style>`;k=D.includes(`</head>`)?D.replace(`</head>`,`${e}\n</head>`):D+e}k.trim().toLowerCase().startsWith(`<!doctype`)||(k=`<!DOCTYPE html>
17
- `+k);let A=u(!0);A&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${A}\n</head>`));let j=d(!0);j&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${j}\n</head>`)),k=f(k),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(k);let M;try{let e=typeof n==`function`?n():n;M=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering page component:`,e),M=`<div>Error rendering page</div>`}if(M.trim().startsWith(`<!DOCTYPE html>`)||M.trim().startsWith(`<html`))return r.end(M),!0;let N=M;for(let{module:e}of S){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:N}})});N=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering wrapper layout:`,e)}}let P=N+O;if(!P.includes(`/src/client/main.js`)&&!P.includes(`/@vite/client`)){let e=P.lastIndexOf(`</body>`);e!==-1&&(P=P.slice(0,e)+`
16
+ `)}</style>`;k=D.includes(`</head>`)?D.replace(`</head>`,`${e}\n</head>`):D+e}k.trim().toLowerCase().startsWith(`<!doctype`)||(k=`<!DOCTYPE html>\n${k}`);let A=u(!0);A&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${A}\n</head>`));let j=d(!0);j&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${j}\n</head>`)),k=f(k),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(k);let M;try{let e=typeof n==`function`?n():n;M=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering page component:`,e),M=`<div>Error rendering page</div>`}if(M.trim().startsWith(`<!DOCTYPE html>`)||M.trim().startsWith(`<html`))return r.end(M),!0;let N=M;for(let{module:e}of S){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:N}})});N=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering wrapper layout:`,e)}}let P=N+O;if(!P.includes(`/src/client/main.js`)&&!P.includes(`/@vite/client`)){let e=P.lastIndexOf(`</body>`);e!==-1&&(P=P.slice(0,e)+`
18
17
  <script type="module" src="/@vite/client"><\/script>
19
18
  <script type="module" src="/src/client/main.js"><\/script>
20
19
  `+P.slice(e))}return r.end(P),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function J(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 x(e,i),s=await Z(r,e),c=[];for(let t of s){let n=await e.ssrLoadModule(t);c.push({file:t,module:n})}for(let t of s){let n=await x(e,t);o.push(...n)}let l;return l=n.modules&&c.length>0?await Y(a,t,c,r,n,e):await ee(a,t,r,n,e),o.length>0&&(l=S(l,o)),l}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Y(e,t,n,r,i,a){let{render:o}=await a.ssrLoadModule(`preact-render-to-string`),{h:s}=await a.ssrLoadModule(`preact`),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!c.includes(t)}),u;try{let t=typeof e==`function`?e():e;u=o(t instanceof Promise?await t:t)}catch(e){console.error(`[SSR] Error rendering page component:`,e),u=`<div>Error rendering page</div>`}if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return X(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},m=[],h=[];for(let e of l){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...p,children:s(`div`,null,`test`)}),r=o(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?m.push(e):h.push(e)}catch{h.push(e)}}let g=u;for(let{module:e}of h){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering wrapper layout:`,e)}}if(m.length>0){let{module:e}=m[m.length-1],t=e.default;if(t&&typeof t==`function`)try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering shell layout:`,e)}}if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return X(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
@@ -30,13 +29,12 @@ export default islandManifest;
30
29
  ${g}
31
30
  <script type="module" src="/src/client/main.js"><\/script>
32
31
  </body>
33
- </html>`}function X(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>
34
- `+t),!t.includes(`data-universal-ssr="true"`)){let e=u(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=d(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=f(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
32
+ </html>`}function X(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=u(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=d(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=f(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
35
33
  <script type="module" src="/@vite/client"><\/script>
36
34
  <script type="module" src="/src/client/main.js"><\/script>`:t.slice(0,r)+`
37
35
  <script type="module" src="/@vite/client"><\/script>
38
36
  <script type="module" src="/src/client/main.js"><\/script>
39
- `+t.slice(r)}async function Z(e,t){let r=t.config.root||process.cwd(),i=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 n(e)).isFile()){let t=e.slice(r.length);o.includes(t)||o.push(t)}}catch{}}if(i?.layoutsDir&&await l(`${`${r}/${i.layoutsDir}`}/${a}`),i?.modules){let e=`${r}/${i.modules.dir}`,t=i.modules.layoutsDirName,n=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!n||o.includes(n.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${n}/${t}/${a}`)}let u=`${r}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function Q(e,t,r){let i=e;i.endsWith(`/`)&&i!==`/`&&(i=i.slice(0,-1)),i===`/`&&(i=`/index`);let a=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],o=r.config.root||process.cwd();async function s(e){try{if((await n(`${o}/${e}`)).isFile())return`/${e}`}catch{}return null}if(t.modules){let n=t.modules.dir,r=t.modules.pagesDirName,o=e.split(`/`).filter(Boolean),c=o[0]||``,l=[`home`,`root`,`main`,`index`],u,d;if(!c||l.includes(c.toLowerCase()))u=`home`,d=i;else{u=c;let e=o.slice(1);d=e.length>0?`/`+e.join(`/`):`/index`}for(let e of a){let t=await s(`${n}/${u}/${r}${d}${e}`);if(t)return t}if(!d.endsWith(`/index`))for(let e of a){let t=await s(`${n}/${u}/${r}${d}/index${e}`);if(t)return t}}let c=t.pagesDir;for(let e of a){let t=await s(`${c}${i}${e}`);if(t)return t}if(!i.endsWith(`/index`))for(let e of a){let t=await s(`${c}${i}/index${e}`);if(t)return t}return null}async function ee(e,t,n,r,i){let a=t.metadata||{};try{G||=await i.ssrLoadModule(T(`src/render/ssr.ts`));let o=G;K||=await i.ssrLoadModule(T(`src/core/layout/enhanced-layout-resolver.ts`));let s=K,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter};if(o.renderToHtmlWithLayouts&&s.EnhancedLayoutResolver&&s.EnhancedLayoutResolverUtils)try{let e=i.config.root||process.cwd();if(!globalThis.__avalonLayoutResolver){let t=s.EnhancedLayoutResolver,n=r.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new t({baseDirectory:`${e}/${n}`,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:r.modules?`${e}/${r.modules.dir}`:void 0,modulesLayoutsDirName:r.modules?.layoutsDirName})}let t=`http://localhost${n}`,l={params:{},query:{},url:t,request:{method:`GET`,url:t,headers:new Headers}};return await o.renderToHtmlWithLayouts(c,globalThis.__avalonLayoutResolver,l,n,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}let o=a.title||`Avalon App`,s=a.description||``,c=``;try{let t=await i.ssrLoadModule(`preact-render-to-string`);t.render&&typeof e==`function`&&(c=t.render(e()))}catch{c=`<p>Loading page: ${$(n)}</p>`}return`<!DOCTYPE html>
37
+ `+t.slice(r)}async function Z(e,t){let r=t.config.root||process.cwd(),i=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 n(e)).isFile()){let t=e.slice(r.length);o.includes(t)||o.push(t)}}catch{}}if(i?.layoutsDir&&await l(`${`${r}/${i.layoutsDir}`}/${a}`),i?.modules){let e=`${r}/${i.modules.dir}`,t=i.modules.layoutsDirName,n=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!n||o.includes(n.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${n}/${t}/${a}`)}let u=`${r}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function Q(e,t,r){let i=e;i.endsWith(`/`)&&i!==`/`&&(i=i.slice(0,-1)),i===`/`&&(i=`/index`);let a=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],o=r.config.root||process.cwd();async function s(e){try{if((await n(`${o}/${e}`)).isFile())return`/${e}`}catch{}return null}if(t.modules){let n=t.modules.dir,r=t.modules.pagesDirName,o=e.split(`/`).filter(Boolean),c=o[0]||``,l=[`home`,`root`,`main`,`index`],u,d;if(!c||l.includes(c.toLowerCase()))u=`home`,d=i;else{u=c;let e=o.slice(1);d=e.length>0?`/${e.join(`/`)}`:`/index`}for(let e of a){let t=await s(`${n}/${u}/${r}${d}${e}`);if(t)return t}if(!d.endsWith(`/index`))for(let e of a){let t=await s(`${n}/${u}/${r}${d}/index${e}`);if(t)return t}}let c=t.pagesDir;for(let e of a){let t=await s(`${c}${i}${e}`);if(t)return t}if(!i.endsWith(`/index`))for(let e of a){let t=await s(`${c}${i}/index${e}`);if(t)return t}return null}async function ee(e,t,n,r,i){let a=t.metadata||{};try{G||=await i.ssrLoadModule(T(`src/render/ssr.ts`));let o=G;K||=await i.ssrLoadModule(T(`src/core/layout/enhanced-layout-resolver.ts`));let s=K,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter};if(o.renderToHtmlWithLayouts&&s.EnhancedLayoutResolver&&s.EnhancedLayoutResolverUtils)try{let e=i.config.root||process.cwd();if(!globalThis.__avalonLayoutResolver){let t=s.EnhancedLayoutResolver,n=r.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new t({baseDirectory:`${e}/${n}`,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:r.modules?`${e}/${r.modules.dir}`:void 0,modulesLayoutsDirName:r.modules?.layoutsDirName})}let t=`http://localhost${n}`,l={params:{},query:{},url:t,request:{method:`GET`,url:t,headers:new Headers}};return await o.renderToHtmlWithLayouts(c,globalThis.__avalonLayoutResolver,l,n,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}let o=a.title||`Avalon App`,s=a.description||``,c=``;try{let t=await i.ssrLoadModule(`preact-render-to-string`);t.render&&typeof e==`function`&&(c=t.render(e()))}catch{c=`<p>Loading page: ${$(n)}</p>`}return`<!DOCTYPE html>
40
38
  <html lang="en">
41
39
  <head>
42
40
  <meta charset="utf-8">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useavalon/avalon",
3
- "version": "0.1.70",
3
+ "version": "0.1.72",
4
4
  "description": "Multi-framework islands architecture for the modern web",
5
5
  "license": "MIT",
6
6
  "type": "module",