@useavalon/avalon 0.1.58 → 0.1.60

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,3 +1,3 @@
1
- import{readFileSync as e,existsSync as t,readdirSync as n,statSync as r}from"node:fs";import{resolve as i,dirname as a,relative as o}from"node:path";export function islandClientBundlerPlugin(e){let t=process.cwd(),n=new Map,r=c(e,t);for(let e of r)d(e,t,n);let i=`\0avalon-island-entry:`;return{name:`avalon:island-client-bundler`,enforce:`pre`,resolveId(e){return e.startsWith(i)?e:null},load(e){if(!e.startsWith(i))return null;let t=e.slice(21),n=JSON.stringify(t);return t.includes(`.qwik.`)?[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`,`import __C from ${n};`,`export default __C;`,`if(typeof globalThis<"u")globalThis.__avalonIsland=__C;`].join(`
1
+ import{readFileSync as e,existsSync as t,readdirSync as n,statSync as r}from"node:fs";import{resolve as i,dirname as a,relative as o}from"node:path";export function islandClientBundlerPlugin(e){let t=process.cwd(),n=new Map,r=c(e,t);for(let e of r)d(e,t,n);let i=`\0avalon-island-entry:`,a=!1;return{name:`avalon:island-client-bundler`,enforce:`pre`,configResolved(e){a=e.command===`serve`},resolveId(e){return e.startsWith(i)?e:null},load(e){if(!e.startsWith(i))return null;let t=e.slice(21),n=JSON.stringify(t);return t.includes(`.qwik.`)?[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`,`import __C from ${n};`,`export default __C;`,`if(typeof globalThis<"u")globalThis.__avalonIsland=__C;`].join(`
2
2
  `):[`import __C from ${n};`,`var Component = __C;`,`export { Component as default, Component };`,`if(typeof globalThis<"u")globalThis.__avalonIsland=Component;`].join(`
3
- `)},async buildStart(){let t=this.environment;if(!(t&&t.name!==`client`)&&n.size>0){for(let[,e]of n)this.emitFile({type:`chunk`,id:i+e.filePath,fileName:`islands/${e.bundleKey}.js`,preserveSignature:`exports-only`});e.verbose&&console.log(`🏝️ Emitting ${n.size} island client bundles`)}}}}function c(e,r){let a=[];if(e.pagesDir){let n=i(r,e.pagesDir);t(n)&&a.push(n)}if(e.layoutsDir){let n=i(r,e.layoutsDir);t(n)&&a.push(n)}if(e.modules){let o=i(r,e.modules.dir);if(t(o))try{for(let e of n(o,{withFileTypes:!0}))if(e.isDirectory())for(let n of[`pages`,`layouts`,`components`]){let r=i(o,e.name,n);t(r)&&a.push(r)}}catch{}}return a}const l=[`.qwik.`];function u(e){return l.some(t=>e.includes(t))}function d(t,r,a){let o;try{o=n(t,{withFileTypes:!0})}catch{return}for(let n of o){let o=i(t,n.name);if(n.isDirectory()){d(o,r,a);continue}if(/\.(tsx?|jsx?|mdx?)$/.test(n.name))try{let t=e(o,`utf-8`),n=t.includes(`island=`)||t.includes(`island `),i=/import\s+\w+\s+from\s+['"][^'"]*\.qwik\.[^'"]*['"]/m.test(t);if(!n&&!i)continue;f(t,o,r,a)}catch{}}}function f(e,t,n,r){let i=/<([A-Z]\w*)\s+[^>]*\bisland\b/g,a=new Set,s;for(;(s=i.exec(e))!==null;)a.add(s[1]);let c=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,l=new Set,d=[];for(;(s=c.exec(e))!==null;)d.push([s[1],s[2]]),u(s[2])&&RegExp(`<`+s[1]+`[\\s/>]`).test(e)&&l.add(s[1]);if(!(a.size===0&&l.size===0))for(let[e,i]of d){if(!a.has(e)&&!l.has(e))continue;let s=p(i,t,n);if(!s)continue;let c=o(n,s).replaceAll(`\\`,`/`).replace(/\.(tsx?|jsx?)$/,``);r.has(s)||r.set(s,{filePath:s,bundleKey:c})}}function p(e,n,o){let s;if(e.startsWith(`@shared/`))s=i(o,`app/shared`,e.slice(8));else if(e.startsWith(`@modules/`))s=i(o,`app/modules`,e.slice(9));else if(e.startsWith(`@/`))s=i(o,`app`,e.slice(2));else if(e.startsWith(`.`))s=i(a(n),e);else return null;if(t(s)&&r(s).isFile())return s;for(let e of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(t(s+e))return s+e;return null}
3
+ `)},async buildStart(){if(a)return;let t=this.environment;if(!(t&&t.name!==`client`)&&n.size>0){for(let[,e]of n)this.emitFile({type:`chunk`,id:i+e.filePath,fileName:`islands/${e.bundleKey}.js`,preserveSignature:`exports-only`});e.verbose&&console.log(`🏝️ Emitting ${n.size} island client bundles`)}}}}function c(e,r){let a=[];if(e.pagesDir){let n=i(r,e.pagesDir);t(n)&&a.push(n)}if(e.layoutsDir){let n=i(r,e.layoutsDir);t(n)&&a.push(n)}if(e.modules){let o=i(r,e.modules.dir);if(t(o))try{for(let e of n(o,{withFileTypes:!0}))if(e.isDirectory())for(let n of[`pages`,`layouts`,`components`]){let r=i(o,e.name,n);t(r)&&a.push(r)}}catch{}}return a}const l=[`.qwik.`];function u(e){return l.some(t=>e.includes(t))}function d(t,r,a){let o;try{o=n(t,{withFileTypes:!0})}catch{return}for(let n of o){let o=i(t,n.name);if(n.isDirectory()){d(o,r,a);continue}if(/\.(tsx?|jsx?|mdx?)$/.test(n.name))try{let t=e(o,`utf-8`),n=t.includes(`island=`)||t.includes(`island `),i=/import\s+\w+\s+from\s+['"][^'"]*\.qwik\.[^'"]*['"]/m.test(t);if(!n&&!i)continue;f(t,o,r,a)}catch{}}}function f(e,t,n,r){let i=/<([A-Z]\w*)\s+[^>]*\bisland\b/g,a=new Set,s;for(;(s=i.exec(e))!==null;)a.add(s[1]);let c=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,l=new Set,d=[];for(;(s=c.exec(e))!==null;)d.push([s[1],s[2]]),u(s[2])&&RegExp(`<`+s[1]+`[\\s/>]`).test(e)&&l.add(s[1]);if(!(a.size===0&&l.size===0))for(let[e,i]of d){if(!a.has(e)&&!l.has(e))continue;let s=p(i,t,n);if(!s)continue;let c=o(n,s).replaceAll(`\\`,`/`).replace(/\.(tsx?|jsx?)$/,``);r.has(s)||r.set(s,{filePath:s,bundleKey:c})}}function p(e,n,o){let s;if(e.startsWith(`@shared/`))s=i(o,`app/shared`,e.slice(8));else if(e.startsWith(`@modules/`))s=i(o,`app/modules`,e.slice(9));else if(e.startsWith(`@/`))s=i(o,`app`,e.slice(2));else if(e.startsWith(`.`))s=i(a(n),e);else return null;if(t(s)&&r(s).isFile())return s;for(let e of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(t(s+e))return s+e;return null}
@@ -1 +1 @@
1
- import{loadIntegrationModule as e,preLitHydration as t}from"virtual:avalon/integration-loader";(function(){var n=document.querySelectorAll(`[data-framework]`);if(!n.length)return;var r=!1;n.forEach(function(e){var t=e.dataset.framework,n=e.dataset.condition||`on:client`;e.dataset.renderStrategy!==`ssr-only`&&(n===`on:client`?i(e,t):r=!0)}),r&&import(`./strategies.js`).then(function(e){n.forEach(function(t){var n=t.dataset.condition||`on:client`;n!==`on:client`&&t.dataset.renderStrategy!==`ssr-only`&&!t.dataset.hydrated&&e.setup(t,t.dataset.framework,n,i)})});async function i(n,r){if(!n.dataset.hydrated){var i=n.dataset.src;if(i)try{var a=n.dataset.props?JSON.parse(n.dataset.props):{};r===`lit`&&await t();var o=await import(i),s=o.default||Object.values(o).find(function(e){return typeof e==`function`&&e.prototype})||o,c=await e(r);c.hydrate&&await c.hydrate(n,s,a),n.dataset.hydrated=`true`}catch(e){console.error(`Hydration error for `+r+` island `+i+`:`,e)}}}})();
1
+ (function(){var e=document.querySelectorAll(`[data-framework]`);if(!e.length)return;var t=!1;e.forEach(function(e){var r=e.dataset.framework,i=e.dataset.condition||`on:client`;e.dataset.renderStrategy!==`ssr-only`&&(i===`on:client`?(window.requestIdleCallback||requestAnimationFrame)(function(){n(e,r)}):t=!0)}),t&&import(`./strategies.js`).then(function(t){e.forEach(function(e){var r=e.dataset.condition||`on:client`;r!==`on:client`&&e.dataset.renderStrategy!==`ssr-only`&&!e.dataset.hydrated&&t.setup(e,e.dataset.framework,r,n)})});async function n(e,t){if(!e.dataset.hydrated){var n=e.dataset.src;if(n)try{var r=e.dataset.props?JSON.parse(e.dataset.props):{},i=await import(`virtual:avalon/integration-loader`);t===`lit`&&await i.preLitHydration();var a=await import(n),o=a.default||Object.values(a).find(function(e){return typeof e==`function`&&e.prototype})||a,s=await i.loadIntegrationModule(t);s.hydrate&&await s.hydrate(e,o,r),e.dataset.hydrated=`true`}catch(e){console.error(`Hydration error for `+t+` island `+n+`:`,e)}}}})();
@@ -74,4 +74,5 @@ export declare function getAvalonConfig(): ResolvedAvalonConfig | undefined;
74
74
  export declare function isDevelopmentMode(): boolean;
75
75
  declare global {
76
76
  var __avalonLayoutResolver: unknown;
77
+ var __avalonCollectLayoutCss: ((pathname: string) => Promise<string[]>) | undefined;
77
78
  }
@@ -1,4 +1,4 @@
1
- import{existsSync as e}from"node:fs";import{stat as t}from"node:fs/promises";import{createRequire as n}from"node:module";import{dirname as r,join as i}from"node:path";import{nitro as a}from"nitro/vite";import{isRunnableDevEnvironment as o}from"vite";import{getUniversalCSSForHead as s}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as c,injectSolidHydrationScriptIfNeeded as l}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as u,discoverScopedMiddleware as d,executeScopedMiddleware as f}from"../middleware/index.js";import{createNitroConfig as p}from"../nitro/config.js";import{createIslandManifestPlugin as m,createNitroBuildPlugin as h,createSourceMapConfig as g,createSourceMapPlugin as _}from"../nitro/index.js";import{collectCssFromModuleGraph as v,injectSsrCss as y}from"../render/collect-css.js";import{generateErrorPage as b,generateFallback404 as x}from"../render/error-pages.js";function S(t){let a=i(r(n(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(a)){let t=a.replace(/\.ts$/,`.js`);if(e(t))return t}return a}function C(t,a){let o=i(r(n(i(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),a);if(a.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=p(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 o=a(r),s=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),c=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),l=h(e,t),u=m(e,{verbose:e.verbose,generatePreloadHints:!0}),d=_(g(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(o)?o:[o],s,c,l,u,d]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonConfig=t},configureServer(e){globalThis.__viteDevServer=e;let r=null;async function i(){return r||=await d({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),r}function a(){r=null}M(e,t,n,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let s=e.environments?.ssr,c=!!s&&o(s);c&&A(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(r,a,o)=>{if(!c)return o();let s=r.url||`/`;if(s.endsWith(`.html`)&&(s=s.slice(0,-5)||`/`),s===`/index`&&(s=`/`),s.startsWith(`/@`)||s.startsWith(`/__`)||s.startsWith(`/node_modules/`)||s.startsWith(`/src/client/`)||s.startsWith(`/packages/`)||s.includes(`.`)&&!s.endsWith(`/`)||s.startsWith(`/api/`))return o();try{if(await O(e,s,r,a,i,n)||await W(e,s,t,a))return;let o=await G(e,s,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await k(e,s,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(b(e))}})},buildStart(){}}}async function O(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 f({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 k(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(x(t))}}async function A(e,t,n){let r=performance.now(),i=[{path:S(`src/render/ssr.ts`),assignTo:`ssr`},{path:S(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:S(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:C(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`&&(H=r),n===`layout`&&(U=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e;return{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await N(t,r):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await P(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?F():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?I(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?await L(t):e===RESOLVED_VIRTUAL_IDS.ASSETS?R(n):e===RESOLVED_VIRTUAL_IDS.RENDERER?z(t):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await B(t,n):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(t):null},handleHotUpdate({file:e,server:n}){if(e.includes(t.pagesDir)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&n.moduleGraph.invalidateModule(e)}if(e.includes(`/layouts/`)||e.includes(`_layout`)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&n.moduleGraph.invalidateModule(e);let t=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);t&&n.moduleGraph.invalidateModule(t)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&n.moduleGraph.invalidateModule(e)}}}}function M(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(u(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(H=null,U=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(u(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(u(),r?.())})}async function N(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}from"node:fs";import{stat as t}from"node:fs/promises";import{createRequire as n}from"node:module";import{dirname as r,join as i}from"node:path";import{nitro as a}from"nitro/vite";import{isRunnableDevEnvironment as o}from"vite";import{getUniversalCSSForHead as s}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as c,injectSolidHydrationScriptIfNeeded as l}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as u,discoverScopedMiddleware as d,executeScopedMiddleware as f}from"../middleware/index.js";import{createNitroConfig as p}from"../nitro/config.js";import{createIslandManifestPlugin as m,createNitroBuildPlugin as h,createSourceMapConfig as g,createSourceMapPlugin as _}from"../nitro/index.js";import{collectCssFromModuleGraph as v,injectSsrCss as y}from"../render/collect-css.js";import{generateErrorPage as b,generateFallback404 as x}from"../render/error-pages.js";function S(t){let a=i(r(n(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(a)){let t=a.replace(/\.ts$/,`.js`);if(e(t))return t}return a}function C(t,a){let o=i(r(n(i(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),a);if(a.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=p(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 o=a(r),s=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),c=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),l=h(e,t),u=m(e,{verbose:e.verbose,generatePreloadHints:!0}),d=_(g(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(o)?o:[o],s,c,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},configureServer(e){globalThis.__viteDevServer=e;let n=null;async function i(){return n||=await d({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),n}function a(){n=null}M(e,t,r,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let s=e.environments?.ssr,c=!!s&&o(s);c&&A(e,t.integrations,r).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,a,o)=>{if(!c)return o();let s=n.url||`/`;if(s.endsWith(`.html`)&&(s=s.slice(0,-5)||`/`),s===`/index`&&(s=`/`),s.startsWith(`/@`)||s.startsWith(`/__`)||s.startsWith(`/node_modules/`)||s.startsWith(`/src/client/`)||s.startsWith(`/packages/`)||s.includes(`.`)&&!s.endsWith(`/`)||s.startsWith(`/api/`))return o();try{if(await O(e,s,n,a,i,r)||await W(e,s,t,a))return;let o=await G(e,s,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await k(e,s,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(b(e))}})},buildStart(){}}}async function O(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 f({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 k(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(x(t))}}async function A(e,t,n){let r=performance.now(),i=[{path:S(`src/render/ssr.ts`),assignTo:`ssr`},{path:S(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:S(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:C(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`&&(H=r),n===`layout`&&(U=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e,i=null,{readdirSync:a}=require(`node:fs`),{join:o,relative:s,resolve:c}=require(`node:path`),l=process.cwd(),u=[];function d(e){try{let t=a(e,{withFileTypes:!0});for(let n of t){let t=o(e,n.name);if(n.isDirectory()&&n.name!==`node_modules`&&!n.name.startsWith(`.`))d(t);else if(n.isFile()&&n.name.endsWith(`.css`)){let e=s(l,t).replaceAll(`\\`,`/`);u.push(e.startsWith(`/`)?e:`/`+e)}}}catch{}}function f(){u.length=0;for(let e of n.globalCSS??[])u.push(e.startsWith(`/`)?e:`/`+e);t.modules&&d(c(l,t.modules.dir)),d(c(l,t.layoutsDir))}return t.isDev&&f(),{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 N(t,r):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await P(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?F():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?I(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(i||=await L(t,n,u),i):e===RESOLVED_VIRTUAL_IDS.ASSETS?R(n):e===RESOLVED_VIRTUAL_IDS.RENDERER?z(t):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await B(t,n):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(t):null},handleHotUpdate({file:e,server:n}){if(e.includes(t.pagesDir)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&n.moduleGraph.invalidateModule(e)}if(e.includes(`/layouts/`)||e.includes(`_layout`)||e.endsWith(`.css`)){i=null,f();let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&n.moduleGraph.invalidateModule(e);let t=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);t&&n.moduleGraph.invalidateModule(t)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&n.moduleGraph.invalidateModule(e)}}}}function M(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(u(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(H=null,U=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(u(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(u(),r?.())})}async function N(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
3
  `}}async function P(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(`
@@ -6,11 +6,11 @@ export default pageRoutes;
6
6
  export default { loadPage, routes: [] };
7
7
  `}}function F(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
8
8
  export default islandManifest;
9
- `}function I(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 L(e){let{getAllLayoutDirs:t}=await import(`./module-discovery.js`),{relative:n,resolve:r}=await import(`node:path`),{stat:a}=await import(`node:fs/promises`),o=process.cwd(),s=await t(e.layoutsDir,e.modules,o),c=[],l=0,u=r(o,e.layoutsDir);for(let{dir:t,prefix:r}of s){let s=i(t,`_layout.tsx`);try{if(!(await a(s)).isFile())continue}catch{continue}let d=n(o,s).replaceAll(`\\`,`/`),f=d.startsWith(`/`)?d:`/`+d,p=t.startsWith(u),m=p&&!e.modules?`RootLayout`:`Layout_${l}`;c.push({prefix:r,importPath:f,varName:m,isShared:p}),l++}let d=c.filter(e=>e.isShared),f=c.filter(e=>!e.isShared),p=c.map(e=>`import ${e.varName} from '${e.importPath}';`),m=f.sort((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} }`}),h=d.length>0?d[0].varName:`null`;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';`,...p,``,`const RootLayoutComponent = ${h};`,``,`const moduleLayouts = [`,m.join(`,
10
- `),`];`,``,`function getLayoutsForPath(pathname) {`,` for (const entry of moduleLayouts) {`,` if (entry.prefix === '/' ? pathname === '/' : pathname.startsWith(entry.prefix)) {`,` return entry;`,` }`,` }`,` return null;`,`}`,``,`function injectUniversalAssets(html) {`,` 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(`
9
+ `}function I(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 L(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:a,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=i(t,`_layout.tsx`);try{if(!(await s(r)).isFile())continue}catch{continue}let o=a(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.sort((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=e.isDev===!0,y=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 _isDev = ${v};`,`const _cssLinks = ${y};`,``,`const moduleLayouts = [`,g.join(`,
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 (_isDev && _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
11
  `)}function R(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 ?? [])`,` .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 z(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 B(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=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`,`import '${e.isDev===!0?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`}';`,``],u=t.globalCSS??[];for(let e of u){let t=e.startsWith(`/`)?e:`/`+e;l.push(`// Global CSS`),l.push(`import '${t}';`)}if(u.length>0&&l.push(``),c.length>0){l.push(`// Layout CSS (auto-discovered)`);for(let e of c)l.push(`import '${e}';`)}return l.push(``),l.join(`
13
+ `)}async function B(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=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`,`import '${e.isDev===!0?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`}';`,``],u=t.globalCSS??[];for(let e of u){let t=e.startsWith(`/`)?e:`/`+e;l.push(`// Global CSS`),l.push(`import '${t}';`)}if(u.length>0&&l.push(``),c.length>0){l.push(`// Layout CSS (auto-discovered)`);let e=0;for(let t of c)t.includes(`.module.`)?(l.push(`import _lcss${e} from '${t}';`),e++):l.push(`import '${t}';`)}return l.push(``),l.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=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 V=`<!--AVALON_STREAM_BOUNDARY-->`;let H=null,U=null;async function W(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Y(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,u=await v(e,a),d=await J(i,e),f=[];for(let t of d){let n=await e.ssrLoadModule(t);f.push({file:t,module:n})}for(let t of d){let n=await v(e,t);u.push(...n)}if(f.length===0)return!1;let{render:p}=await e.ssrLoadModule(`preact-render-to-string`),{h:m}=await e.ssrLoadModule(`preact`),h=o?.skipLayouts||[],g=f.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!h.includes(t)}),_=t.frontmatter,y=t.metadata,b={children:null,frontmatter:{..._,...y,currentPath:i},params:{},url:i},x=[],S=[];for(let e of g){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...b,children:m(`div`,null,`test`)}),r=p(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?x.push(e):S.push(e)}catch{S.push(e)}}if(x.length===0)return!1;let{module:C}=x[x.length-1],w=C.default;if(!w||typeof w!=`function`)return!1;let T;try{let e=w({...b,children:m(`div`,{dangerouslySetInnerHTML:{__html:V}})});T=p(e instanceof Promise?await e:e)}catch{return!1}let E=T.indexOf(V);if(E===-1)return!1;let D=T.slice(0,E),O=T.slice(E+29),k=D;if(u.length>0){let e=`<style data-avalon-ssr-css>${u.join(`
16
16
  `)}</style>`;k=D.includes(`</head>`)?D.replace(`</head>`,`${e}\n</head>`):D+e}k.trim().toLowerCase().startsWith(`<!doctype`)||(k=`<!DOCTYPE html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useavalon/avalon",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "description": "Multi-framework islands architecture for the modern web",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -101,6 +101,10 @@
101
101
  "./post-build": {
102
102
  "types": "./dist/src/post-build/index.d.ts",
103
103
  "default": "./dist/src/post-build/index.js"
104
+ },
105
+ "./render/collect-css": {
106
+ "types": "./dist/src/render/collect-css.d.ts",
107
+ "default": "./dist/src/render/collect-css.js"
104
108
  }
105
109
  },
106
110
  "typesVersions": {