@useavalon/avalon 0.3.2-canary.8 → 0.3.2-canary.9
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.
|
@@ -7,7 +7,7 @@ import{existsSync as e,readdirSync as t,readFileSync as n,rmSync as r}from"node:
|
|
|
7
7
|
import{hydrateServerIsland}from"/@fs${N(`src/client/server-island-hydrate.ts`)}";
|
|
8
8
|
hydrateServerIsland(${JSON.stringify(a)},${JSON.stringify(o)},${s},${JSON.stringify(c)},${JSON.stringify(l)});
|
|
9
9
|
<\/script>`}function N(t){let n=s(o(a(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function fe(t,n){let r=s(o(a(s(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`,ACTIONS:`virtual:avalon/actions`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`,ACTIONS:`\0${VIRTUAL_MODULE_IDS.ACTIONS}`};function pe(e){return e===`react`?[]:[/^react/,/^react-dom/]}function me(e){return e===`react`?[`import { createElement as h } from 'react';`,`import { renderToString as preactRenderToString } from 'react-dom/server';`]:[`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`]}function he(e){return e===`react`?[`import { setShellRenderToString, setShellElementFactory } from '@useavalon/avalon/render/shell-engine';`,`import { renderToString as __reactRenderToString } from 'react-dom/server';`,`import { createElement as __reactCreateElement, Fragment as __reactFragment } from 'react';`,`setShellRenderToString((vnode) => __reactRenderToString(vnode));`,`setShellElementFactory(__reactCreateElement, __reactFragment);`]:[]}function ge(e){return e===`react`?`@useavalon/react/client`:`@useavalon/preact/client`}function _e(e){let t=N(`src/core/integrations/registry.ts`),n=[`solid`,`vue`,`svelte`,`lit`].filter(t=>e.includes(t));return`${[`import { registry } from "${t}";`,...n.map(e=>`import { ${e}Integration } from "@useavalon/${e}";`),...n.map(e=>`if (${e}Integration) registry.register(${e}Integration);`)].join(`
|
|
10
|
-
`)}\n`}export function createNitroIntegration(e,t={}){let n=b(t,e),r=process.cwd(),i=N(`src/server-islands/route.ts`),a=N(`src/actions/route.ts`),o={preset:n.preset,serverDir:t.serverDir??n.serverDir??`./server`,routeRules:n.routeRules,runtimeConfig:n.runtimeConfig,compatibilityDate:n.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...pe(e.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>ne(r),"virtual:avalon-actions-manifest":()=>ce(r),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>_e(e.integrations)}};t.renderer===!1?o.renderer=!1:n.renderer&&(o.renderer=n.renderer),n.publicRuntimeConfig&&(o.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(o.publicAssets=n.publicAssets),n.compressPublicAssets&&(o.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(o.serverEntry=n.serverEntry);let s=process.argv.includes(`build`)||process.env.NODE_ENV===`production`;n.experimentalTasks&&s&&(o.experimental={...o.experimental,tasks:!0},n.tasks&&Object.keys(n.tasks).length>0&&(o.tasks=n.tasks),n.scheduledTasks&&Object.keys(n.scheduledTasks).length>0&&(o.scheduledTasks=n.scheduledTasks));let c=n.traceDeps??[];o.traceDeps=[...new Set([`undici`,...c])],n.prerender&&(o.prerender={routes:[],crawlLinks:!1});let l=u(o),d=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),f=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),m=S(e,t),h=x(e,{verbose:e.verbose,generatePreloadHints:!0}),g=w(C(t.preset??`node_server`,e.isDev)),_=p(t.cron,e.verbose);return{nitroOptions:n,plugins:[...Array.isArray(l)?l:[l],d,f,m,h,g,_]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{f(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{f(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let l=!1,u=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||l?(l=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{l=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(l)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await u,n()});let p=null;async function m(){return p||=await v({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}Se(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let g=e.environments?.ssr,_=!!g&&d(g);_&&be(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!_)return i();try{let{decrypt:i}=await e.ssrLoadModule(N(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await H(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await k(n,`Timed out reading server island request body`)),!c){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Missing encrypted props`);return}let l=ue(c,i);if(!l.ok){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Bad Request: decryption failed`);return}let{props:u,srcPath:d,islandMeta:f}=l;if(!d){r.statusCode=404,r.setHeader(`Content-Type`,`text/plain`),r.end(`Component not found (no __src in payload)`);return}let p=(await e.ssrLoadModule(d)).default;if(typeof p!=`function`){r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Module "${d}" does not export a default component function`);return}let m=s(o(p,u));f&&(m+=de(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!_)return r();try{let r=M(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(N(`src/actions/endpoint.ts`)),e.ssrLoadModule(N(`src/actions/registry.ts`)),r?e.ssrLoadModule(r):Promise.resolve({server:{}})]),c=o.flattenActions(s.server),l=a.defineActionHandler({registry:c,isDev:!0}),u=new URL(i,`http://${t.headers.host||`localhost`}`),d=(t.method||`GET`).toUpperCase(),f;d===`POST`&&(f=await k(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!_)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await ve(e,o,r,i,m,n)||await Be(e,o,t,i))return;let a=await Ve(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await ye(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(D(e))}})},buildStart(){}}}async function ve(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await y({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function ye(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(O(t))}}async function be(e,t,n){let r=performance.now(),i=[{path:N(`src/render/ssr.ts`),assignTo:`ssr`},{path:N(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:N(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:fe(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(B=r),n===`layout`&&(V=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:n,nitroConfig:r,verbose:i}=e,a=null,o=s,u=c,d=l,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=o(e,t.name);if(t.isDirectory()&&t.name!==`node_modules`&&!t.name.startsWith(`.`))m(n);else if(t.isFile()&&t.name.endsWith(`.css`)){let e=u(f,n).replaceAll(`\\`,`/`);p.push(e.startsWith(`/`)?e:`/${e}`)}}}catch{}}function h(){p.length=0;for(let e of r.globalCSS??[])p.push(e.startsWith(`/`)?e:`/${e}`);n.modules&&m(d(f,n.modules.dir)),m(d(f,n.layoutsDir));let e=d(f,n.layoutsDir,`..`);e!==f&&e!==d(f,n.layoutsDir)&&e.startsWith(f)&&m(e)}return n.isDev&&h(),{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await Ce(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await we(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?Te():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?Ee(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(a||=await De(n,r,p),a):e===RESOLVED_VIRTUAL_IDS.ASSETS?Oe(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?ke(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await Me(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):e===RESOLVED_VIRTUAL_IDS.ACTIONS?le():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:i,isCss:o}=R(e);(n||r||i||o)&&(n&&(F(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(t)),i&&(a=null,h(),P(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),P(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY)),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),xe(e)&&P(t,RESOLVED_VIRTUAL_IDS.CONFIG)}}}function P(e,t){let n=e.moduleGraph.getModuleById(t);n&&e.moduleGraph.invalidateModule(n)}function F(e,t){P(e,t);let n=e.environments;if(n)for(let e of Object.values(n)){let n=e.moduleGraph;if(n)try{let e=n.getModuleById(t);e&&n.invalidateModule(e)}catch{}}}async function I(e){let t=e.environments?.nitro;if(t)try{await t.devServer?.reloadRoutes?.()}catch{}}function L(e){F(e,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(e,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(e),setTimeout(()=>{e.ws.send({type:`full-reload`,path:`*`})},500)}function R(e){let t=e.endsWith(`.css`);return{isPage:e.includes(`/pages/`)&&!t,isComponent:e.includes(`/components/`)&&/\.[tj]sx?$/.test(e),isLayout:(e.includes(`/layouts/`)||e.includes(`_layout`))&&/\.[tj]sx?$/.test(e),isCss:t}}function xe(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function Se(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(_(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(B=null,V=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)})}export function isPageFile(e){return R(e).isPage}async function Ce(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
|
|
10
|
+
`)}\n`}export function createNitroIntegration(e,t={}){let n=b(t,e),r=process.cwd(),i=N(`src/server-islands/route.ts`),a=N(`src/actions/route.ts`),o={preset:n.preset,serverDir:t.serverDir??n.serverDir??`./server`,routeRules:n.routeRules,runtimeConfig:n.runtimeConfig,compatibilityDate:n.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...pe(e.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>ne(r),"virtual:avalon-actions-manifest":()=>ce(r),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>_e(e.integrations)}};t.renderer===!1?o.renderer=!1:n.renderer&&(o.renderer=n.renderer),n.publicRuntimeConfig&&(o.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(o.publicAssets=n.publicAssets),n.compressPublicAssets&&(o.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(o.serverEntry=n.serverEntry);let s=process.argv.includes(`build`)||process.env.NODE_ENV===`production`;n.experimentalTasks&&s&&(o.experimental={...o.experimental,tasks:!0},n.tasks&&Object.keys(n.tasks).length>0&&(o.tasks=n.tasks),n.scheduledTasks&&Object.keys(n.scheduledTasks).length>0&&(o.scheduledTasks=n.scheduledTasks));let c=n.traceDeps??[];o.traceDeps=[...new Set([`undici`,...c])],n.prerender&&(o.prerender={routes:[],crawlLinks:!1});let l=u(o),d=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),f=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),m=S(e,t),h=x(e,{verbose:e.verbose,generatePreloadHints:!0}),g=w(C(t.preset??`node_server`,e.isDev)),_=p(t.cron,e.verbose);return{nitroOptions:n,plugins:[...Array.isArray(l)?l:[l],d,f,m,h,g,_]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{f(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{f(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let l=!1,u=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||l?(l=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{l=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(l)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await u,n()});let p=null;async function m(){return p||=await v({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}Se(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let g=e.environments?.ssr,_=!!g&&d(g);_&&be(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!_)return i();try{let{decrypt:i}=await e.ssrLoadModule(N(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await H(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await k(n,`Timed out reading server island request body`)),!c){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Missing encrypted props`);return}let l=ue(c,i);if(!l.ok){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Bad Request: decryption failed`);return}let{props:u,srcPath:d,islandMeta:f}=l;if(!d){r.statusCode=404,r.setHeader(`Content-Type`,`text/plain`),r.end(`Component not found (no __src in payload)`);return}let p=(await e.ssrLoadModule(d)).default;if(typeof p!=`function`){r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Module "${d}" does not export a default component function`);return}let m=s(o(p,u));f&&(m+=de(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!_)return r();try{let r=M(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(N(`src/actions/endpoint.ts`)),e.ssrLoadModule(N(`src/actions/registry.ts`)),r?e.ssrLoadModule(r):Promise.resolve({server:{}})]),c=o.flattenActions(s.server),l=a.defineActionHandler({registry:c,isDev:!0}),u=new URL(i,`http://${t.headers.host||`localhost`}`),d=(t.method||`GET`).toUpperCase(),f;d===`POST`&&(f=await k(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!_)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await ve(e,o,r,i,m,n)||await Be(e,o,t,i))return;let a=await Ve(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await ye(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(D(e))}})},buildStart(){}}}async function ve(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await y({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function ye(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(O(t))}}async function be(e,t,n){let r=performance.now(),i=[{path:N(`src/render/ssr.ts`),assignTo:`ssr`},{path:N(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:N(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:fe(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(B=r),n===`layout`&&(V=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:n,nitroConfig:r,verbose:i}=e,a=null,o=s,u=c,d=l,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=o(e,t.name);if(t.isDirectory()&&t.name!==`node_modules`&&!t.name.startsWith(`.`))m(n);else if(t.isFile()&&t.name.endsWith(`.css`)){let e=u(f,n).replaceAll(`\\`,`/`);p.push(e.startsWith(`/`)?e:`/${e}`)}}}catch{}}function h(){p.length=0;for(let e of r.globalCSS??[])p.push(e.startsWith(`/`)?e:`/${e}`);n.modules&&m(d(f,n.modules.dir)),m(d(f,n.layoutsDir));let e=d(f,n.layoutsDir,`..`);e!==f&&e!==d(f,n.layoutsDir)&&e.startsWith(f)&&m(e)}return n.isDev&&h(),{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await Ce(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await we(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?Te():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?Ee(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(a||=await De(n,r,p),a):e===RESOLVED_VIRTUAL_IDS.ASSETS?Oe(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?ke(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await Me(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):e===RESOLVED_VIRTUAL_IDS.ACTIONS?le():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:i,isCss:o}=R(e);(n||r||i||o)&&(n&&(F(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(t)),i&&(a=null,h(),P(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),P(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY)),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),xe(e)&&P(t,RESOLVED_VIRTUAL_IDS.CONFIG)}}}function P(e,t){let n=e.moduleGraph.getModuleById(t);n&&e.moduleGraph.invalidateModule(n)}function F(e,t){P(e,t);let n=e.environments;if(n)for(let e of Object.values(n)){let n=e.moduleGraph;if(n)try{let e=n.getModuleById(t);e&&n.invalidateModule(e)}catch{}}}async function I(e){let t=e.environments?.nitro;if(t)try{t.devServer?.sendMessage?.({type:`full-reload`}),await t.devServer?.reloadRoutes?.()}catch{}}function L(e){F(e,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(e,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(e),setTimeout(()=>{e.ws.send({type:`full-reload`,path:`*`})},500)}function R(e){let t=e.endsWith(`.css`);return{isPage:e.includes(`/pages/`)&&!t,isComponent:e.includes(`/components/`)&&/\.[tj]sx?$/.test(e),isLayout:(e.includes(`/layouts/`)||e.includes(`_layout`))&&/\.[tj]sx?$/.test(e),isCss:t}}function xe(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function Se(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(_(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(B=null,V=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(_(),r?.()),isPageFile(t)&&L(e)})}export function isPageFile(e){return R(e).isPage}async function Ce(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
|
|
11
11
|
export default pageRoutes;
|
|
12
12
|
`}}async function we(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
|
|
13
13
|
`),`];`,``,`/**`,` * Match a pathname against discovered routes and return the page module.`,` * Uses the same pattern matching as Avalon's route discovery.`,` */`,`/**`,` * Match a pathname against discovered routes, returning the matched`,` * page module AND the extracted dynamic route params (e.g. { id: "123" }).`,` */`,`export function loadPage(pathname) {`,` const cleanPath = pathname.split('?')[0];`,` for (const route of routes) {`,` const m = matchRoute(cleanPath, route.pattern);`,` if (m.matched) return { module: route.module, params: m.params };`,` }`,` return null;`,`}`,``,`/**`,` * Match one pattern and capture dynamic segments:`,` * /users/:id vs /users/123 -> { id: "123" }`,` * /blog/** vs /blog/a/b -> { slug: "a/b" }`,` */`,`function matchRoute(pathname, pattern) {`,String.raw` const normPath = pathname === '/' ? '/' : pathname.replace(/\/$/, '');`,String.raw` const normPattern = pattern === '/' ? '/' : pattern.replace(/\/$/, '');`,` if (normPath === normPattern) return { matched: true, params: {} };`,` const patternParts = normPattern.split('/');`,` const pathParts = normPath.split('/');`,` const params = {};`,` for (let i = 0; i < patternParts.length; i++) {`,` const seg = patternParts[i];`,` if (seg === '**') {`,` params.slug = pathParts.slice(i).join('/');`,` return { matched: true, params };`,` }`,` if (i >= pathParts.length) return { matched: false, params: {} };`,` if (seg.startsWith(':')) params[seg.slice(1)] = pathParts[i];`,` else if (seg !== pathParts[i]) return { matched: false, params: {} };`,` }`,` if (pathParts.length > patternParts.length) return { matched: false, params: {} };`,` return { matched: true, params };`,`}`,``,`export default { loadPage, routes };`,``].join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useavalon/avalon",
|
|
3
|
-
"version": "0.3.2-canary.
|
|
3
|
+
"version": "0.3.2-canary.9",
|
|
4
4
|
"description": "Multi-framework islands architecture for the modern web",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
}
|
|
160
160
|
},
|
|
161
161
|
"dependencies": {
|
|
162
|
-
"@useavalon/core": "^0.3.2-canary.
|
|
162
|
+
"@useavalon/core": "^0.3.2-canary.9",
|
|
163
163
|
"@mdx-js/rollup": "^3.0.0",
|
|
164
164
|
"h3": "^2.0.1-rc.16",
|
|
165
165
|
"marked": "^17.0.4",
|