@useavalon/avalon 0.3.2-canary.13 → 0.3.2-canary.15

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 +1 @@
1
- export{Image}from"../components/Image.js";export{IslandErrorBoundary,withIslandErrorBoundary}from"../components/IslandErrorBoundary.js";export{LayoutErrorBoundary}from"../components/LayoutErrorBoundary.js";export{usePersistentState}from"../persistence/use-persistent-state.js";export{registerClientDirective}from"./custom-directives.js";
1
+ export{Image}from"../components/Image.tsx";export{IslandErrorBoundary,withIslandErrorBoundary}from"../components/IslandErrorBoundary.tsx";export{LayoutDataErrorBoundary}from"../components/LayoutDataErrorBoundary.tsx";export{LayoutErrorBoundary}from"../components/LayoutErrorBoundary.tsx";export{PersistentIsland}from"../components/PersistentIsland.tsx";export{StreamingErrorBoundary,withStreamingErrorBoundary}from"../components/StreamingErrorBoundary.tsx";export{StreamingLayout,StreamingSuspense,useStreamingState,withStreaming}from"../components/StreamingLayout.tsx";export{defaultIslandPersistence,IslandPersistence}from"../core/islands/island-persistence.js";export{IslandStateSerializer}from"../core/islands/island-state-serializer.js";export{createPersistentIslandContext,PersistentIslandProvider,usePersistentIslandContext}from"../core/islands/persistent-island-context.tsx";export{usePersistentState}from"../core/islands/use-persistent-state.js";export{registerClientDirective}from"./custom-directives.js";
@@ -1,4 +1,4 @@
1
1
  import{minifyCSS as e}from"./css-utils.js";import{injectFrameworkBaseCSS as t}from"./framework-base-css.js";import{getUniversalCSS as n}from"./universal-css-collector.js";function r(e){let t=0;for(let n of e)n===`{`?t++:n===`}`&&t--;return t}function i(e,t,n){let r=e.replaceAll(/\s+/g,` `).trim();if(r.startsWith(`/*`)&&r.endsWith(`*/`)){n.push(e.trimEnd());return}t.has(r)||(t.add(r),n.push(e.trimEnd()))}export function deduplicateCSSRules(e){if(!e.trim())return``;let t=new Set,n=e.split(`
2
2
  `),a=[],o=``,s=0;for(let e of n)s+=r(e),o+=`${e}\n`,s<=0&&o.trim()&&(i(o,t,a),o=``,s=0);return o.trim()&&a.push(o.trimEnd()),a.join(`
3
- `)}export function extractCriticalCSS(t=!0){let r=n(t);if(!r.trim())return``;let i=e(deduplicateCSSRules(r));return i.trim()?`<style data-critical-css="true">${i}</style>`:``}export function deferNonCriticalStylesheets(e){let t=/<link\s+([^>]*rel=["']stylesheet["'][^>]*)>/gi,n=[/syntax-highlight/i,/hljs/i,/prism/i,/highlight\.js/i];return e.replaceAll(t,(e,t)=>{if(/\bmedia\s*=/i.test(t)||/data-critical/i.test(t))return e;let r=/href=["']([^"']+)["']/i.exec(t);if(!r)return e;let i=r[1],a=i.startsWith(`https://`)||i.startsWith(`http://`),o=/data-defer/i.test(t),s=!a&&n.some(e=>e.test(i));return!a&&!o&&!s?e:`${`<link ${t.replace(/\s*data-defer(?:=["'][^"']*["'])?\s*/gi,` `).trim()} media="print" onload="this.media='all'">`}\n${`<noscript><link rel="stylesheet" href="${i}"></noscript>`}`})}export function inlineCriticalCSS(e){let n=t(e),r=extractCriticalCSS(!0);return r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`)),n=deferNonCriticalStylesheets(n),n=c(n),n}function c(e){let t=/href=["'](https:\/\/fonts\.googleapis\.com\/css2[^"']+)["']/gi,n=new Set,r;for(r=t.exec(e);r!==null;r=t.exec(e))n.add(r[1]);if(n.size===0)return e;let i=[];for(let t of n){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`);new RegExp(String.raw`<link\s+[^>]*rel=["']preload["'][^>]*href=["']${n}["'][^>]*>`,`i`).test(e)||i.push(`<link rel="preload" href="${t}" as="style">`)}if(i.length===0)return e;let a=i.join(`
3
+ `)}export function extractCriticalCSS(t=!0){let r=n(t);if(!r.trim())return``;let i=e(deduplicateCSSRules(r));return i.trim()?`<style data-critical-css="true">${i}</style>`:``}export function deferNonCriticalStylesheets(e){let t=/<link\s+([^>]*rel=["']stylesheet["'][^>]*)>/gi,n=[/syntax-highlight/i,/hljs/i,/prism/i,/highlight\.js/i];return e.replaceAll(t,(t,r,i)=>{if(e.slice(Math.max(0,i-32),i).toLowerCase().includes(`<noscript`))return t;let a=r.replace(/\s*\/\s*$/,``).trim();if(/\bmedia\s*=/i.test(a)||/data-critical/i.test(a))return t;let o=/href=["']([^"']+)["']/i.exec(a);if(!o)return t;let s=o[1],c=s.startsWith(`https://`)||s.startsWith(`http://`),l=/data-defer/i.test(a),u=!c&&n.some(e=>e.test(s));return!c&&!l&&!u?t:`${`<link ${a.replace(/\s*data-defer(?:=["'][^"']*["'])?\s*/gi,` `).trim()} media="print" onload="this.media='all'">`}\n${`<noscript><link rel="stylesheet" href="${s}"></noscript>`}`})}export function inlineCriticalCSS(e){let n=t(e),r=extractCriticalCSS(!0);return r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`)),n=deferNonCriticalStylesheets(n),n=l(n),n}function l(e){let t=/href=["'](https:\/\/fonts\.googleapis\.com\/css2[^"']+)["']/gi,n=new Set,r;for(r=t.exec(e);r!==null;r=t.exec(e))n.add(r[1]);if(n.size===0)return e;let i=[];for(let t of n){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`);new RegExp(String.raw`<link\s+[^>]*rel=["']preload["'][^>]*href=["']${n}["'][^>]*>`,`i`).test(e)||i.push(`<link rel="preload" href="${t}" as="style">`)}if(i.length===0)return e;let a=i.join(`
4
4
  `);return e.includes(`</title>`)?e.replace(`</title>`,`</title>\n${a}`):e}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Cloudflare Pages worker post-build patches.
3
+ *
4
+ * 1. Rolldown emits `createRequire(import.meta.url)` — undefined on workerd.
5
+ * 2. Lit SSR reads `document` at module eval; the inlined DOM stub runs too late
6
+ * because ESM static imports of `@lit-labs/ssr` evaluate first.
7
+ * 3. Nitro's `_routes.json` includes `/*`, so prerendered HTML hits the Function
8
+ * instead of ASSETS — amplify any SSR boot failure into a site-wide 500.
9
+ */
10
+ /** Rewrite createRequire(import.meta.url) so workerd can boot the worker. */
11
+ export declare function patchCloudflareCreateRequire(workerDir: string): number;
12
+ export interface CloudflareWranglerPatch {
13
+ compatibilityDate: string;
14
+ compatibilityFlags: string[];
15
+ }
16
+ /** Merge compatibility_date / flags into Nitro's emitted wrangler.json. */
17
+ export declare function patchCloudflareWranglerJson(workerDir: string, patch: CloudflareWranglerPatch): boolean;
18
+ /**
19
+ * Install a separate DOM stub module and import it before Lit / the SSR graph.
20
+ * Inlined stubs cannot run before static `import` of `@lit-labs/ssr`.
21
+ */
22
+ export declare function injectCloudflareDomStub(workerDir: string): boolean;
23
+ /**
24
+ * Prefer ASSETS for prerendered HTML: only send dynamic routes to the Function.
25
+ * Nitro defaults to `include: ["/*"]`, which forces every page through SSR.
26
+ */
27
+ export declare function patchCloudflareRoutesForStaticHtml(cwd: string): boolean;
28
+ /**
29
+ * Apply Cloudflare worker fixes under `dist/_worker.js` (file or directory).
30
+ * Returns false when no Cloudflare worker output is present.
31
+ */
32
+ export declare function patchCloudflareWorkerOutput(cwd: string, wrangler?: CloudflareWranglerPatch): boolean;
@@ -0,0 +1 @@
1
+ import{existsSync as e,readdirSync as t,readFileSync as n,statSync as r,writeFileSync as i}from"node:fs";import{join as a}from"node:path";import{ssrDomStubFileSource as o}from"../vite-plugin/ssr-dom-shim-module.js";const s=/createRequire\(\s*import\.meta\.url\s*\)/g,c=`_dom_stub.mjs`;function l(n,r=[]){if(!e(n))return r;for(let e of t(n,{withFileTypes:!0})){let t=a(n,e.name);if(e.isDirectory()){l(t,r);continue}e.isFile()&&/\.(?:m?js)$/.test(e.name)&&r.push(t)}return r}export function patchCloudflareCreateRequire(e){let t=0;for(let r of l(e)){let e=n(r,`utf-8`);if(!s.test(e))continue;s.lastIndex=0;let a=e.replaceAll(s,`createRequire(import.meta.url || "file:///")`);a!==e&&(i(r,a),t+=1)}return t}export function patchCloudflareWranglerJson(t,o){let s=a(t,`wrangler.json`);if(!e(s)||!r(s).isFile())return!1;let c=JSON.parse(n(s,`utf-8`));c.compatibility_date=o.compatibilityDate;let l=new Set(c.compatibility_flags??[]);for(let e of o.compatibilityFlags)l.add(e);return c.compatibility_flags=[...l],i(s,`${JSON.stringify(c,null,2)}\n`),!0}function u(t,a){if(!e(t)||!r(t).isFile())return!1;let o=n(t,`utf-8`),s=`import "${a}";\n`;return o.startsWith(s)||o.includes(`import "${a}"`)?!1:(i(t,`${s}${o}`),!0)}export function injectCloudflareDomStub(n){i(a(n,c),`${o().trim()}\n`);let r=!1;r=u(a(n,`index.js`),`./${c}`)||r,r=u(a(n,`_ssr`,`ssr.mjs`),`../${c}`)||r;let s=a(n,`_libs`,`@lit-labs`);if(e(s))for(let e of t(s))e.startsWith(`ssr`)&&(r=u(a(s,e),`../../${c}`)||r);return r}export function patchCloudflareRoutesForStaticHtml(t){let n=a(t,`dist`,`_routes.json`);if(!e(n))return!1;let r=new Set([`/api/*`,`/_server-islands/*`,`/_actions/*`]);e(a(t,`dist`,`_worker.js`,`_routes`,`api`))&&r.add(`/api/*`);let o={version:1,include:[...r],exclude:[`/`,`/assets/*`,`/islands/*`,`/pagefind/*`,`/*.html`,`/*.svg`,`/*.ico`,`/*.txt`,`/*.xml`,`/*.css`,`/*.js`]};return i(n,`${JSON.stringify(o,null,2)}\n`),!0}export function patchCloudflareWorkerOutput(t,n={compatibilityDate:`2026-09-04`,compatibilityFlags:[`nodejs_compat`,`enable_nodejs_fs_module`]}){let i=a(t,`dist`,`_worker.js`);if(!e(i))return!1;let o=r(i).isDirectory()?i:null;if(!o)return!1;let s=patchCloudflareCreateRequire(o),c=patchCloudflareWranglerJson(o,n),l=injectCloudflareDomStub(o),u=patchCloudflareRoutesForStaticHtml(t);return s>0&&console.log(`[cloudflare] Patched createRequire(import.meta.url) in ${s} worker file(s)`),c&&console.log(`[cloudflare] Synced wrangler.json compatibility_date=${n.compatibilityDate}`),l&&console.log(`[cloudflare] Injected _dom_stub.mjs before Lit / SSR imports`),u&&console.log(`[cloudflare] Limited _routes.json include to dynamic SSR paths`),s>0||c||l||u}
@@ -0,0 +1 @@
1
+ export declare function fetchHandlerWrapperSource(importSpec: string, port: number): string;
@@ -0,0 +1,56 @@
1
+ import{ssrDomShimModuleSource as e}from"../vite-plugin/ssr-dom-shim-module.js";export function fetchHandlerWrapperSource(t,n){return`
2
+ import 'urlpattern-polyfill';
3
+ import { createServer } from 'node:http';
4
+
5
+ ${e()}
6
+
7
+ const mod = await import(${JSON.stringify(t)});
8
+ const handler = mod.handler || mod.default;
9
+ if (!handler) { console.error('No handler found in ${t}'); process.exit(1); }
10
+
11
+ const cfCtx = {
12
+ waitUntil(promise) {
13
+ if (promise && typeof promise.then === 'function') {
14
+ promise.catch(() => {});
15
+ }
16
+ },
17
+ passThroughOnException() {},
18
+ };
19
+
20
+ const server = createServer(async (req, res) => {
21
+ const url = new URL(req.url, 'http://localhost:${n}');
22
+ try {
23
+ const hdrs = new Headers();
24
+ for (const [k, v] of Object.entries(req.headers)) {
25
+ if (v) hdrs.set(k, Array.isArray(v) ? v.join(', ') : v);
26
+ }
27
+ const request = new Request(url.href, { method: req.method, headers: hdrs });
28
+
29
+ let response;
30
+ if (handler.fetch) {
31
+ response = await handler.fetch(request, {}, cfCtx);
32
+ } else if (typeof handler === 'function') {
33
+ response = await handler(request);
34
+ } else {
35
+ res.writeHead(500);
36
+ res.end('Unknown handler format');
37
+ return;
38
+ }
39
+
40
+ const body = await response.text();
41
+ const resHdrs = {};
42
+ if (response.headers && typeof response.headers.forEach === 'function') {
43
+ response.headers.forEach((v, k) => { resHdrs[k] = v; });
44
+ } else if (response.headers && typeof response.headers === 'object') {
45
+ Object.assign(resHdrs, response.headers);
46
+ }
47
+ res.writeHead(response.status || 200, resHdrs);
48
+ res.end(body);
49
+ } catch (err) {
50
+ console.error('Prerender request error:', err);
51
+ res.writeHead(500);
52
+ res.end('Internal Server Error');
53
+ }
54
+ });
55
+ server.listen(${n}, '127.0.0.1', () => console.log('Listening on http://127.0.0.1:${n}'));
56
+ `}
@@ -42,4 +42,12 @@ export interface PostBuildOptions {
42
42
  /** Port for prerender server (default: 13172) */
43
43
  prerenderPort?: number;
44
44
  }
45
+ /**
46
+ * Ensure the SSR client-assets `css` array lists global stylesheets (`index-*.css`
47
+ * / `entry-client-*.css`). Prerender strips `entry-client` CSS for per-island
48
+ * hydration, so without `index-*.css` in this array pages ship with no styles.
49
+ *
50
+ * Exported for unit tests.
51
+ */
52
+ export declare function patchSSRBundleCSS(ssrBundlePath: string, distDir: string, cwd: string): boolean;
45
53
  export declare function runPostBuild(options?: PostBuildOptions): Promise<void>;
@@ -1,52 +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] Kept ${t} (not a Vite template)`)}}function m(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,])\s*/g,`$1`).trim()}function h(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 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=m(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 h=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of h){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)){console.log(`[islands] No islands directory found, skipping isolation`);return}let i=d(r,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(!i.some(e=>{let t=a(e,`utf-8`);return t.includes(`from"../`)||t.includes(`from'../`)})){console.log(`[islands] All islands are self-contained`);return}try{let{buildIsolatedIslands:r}=await import(`./isolated-island-builder.js`),o=new Map;for(let r of i){let i=u(t,r).replaceAll(`\\`,`/`).replace(/^islands\//,``).replace(/\.js$/,``),s=a(r,`utf-8`),c=`preact`;i.includes(`.solid`)?c=`solid`:i.includes(`.vue`)||i.endsWith(`.vue`)?c=`vue`:i.includes(`.svelte`)||i.endsWith(`.svelte`)?c=`svelte`:i.includes(`.lit`)?c=`lit`:i.includes(`.qwik`)?c=`qwik`:i.includes(`.react`)?c=`react`:i.includes(`.preact`)&&(c=`preact`);let d=/from["']((?:\/|\.\/)[^"']+\.(tsx|ts|jsx|js|vue|svelte))["']/i.exec(s),f;if(d&&!d[1].includes(`/assets/`)&&!d[1].startsWith(`../`))f=d[1];else{let t=i;f=[`${t}.tsx`,`${t}.ts`,`${t}.jsx`,`${t}.js`,`${t}`].find(t=>n(l(e,t)))??`${t}.tsx`}f.startsWith(`src/islands/`)&&(f=f.slice(12)),f.startsWith(`/`)||(f=`/${f}`),o.set(i,{filePath:f,bundleKey:i,framework:c})}await r(e,t,o,[],{})}catch{console.warn(`[islands] Isolated rebuild failed, falling back to inline-islands`);try{let{inlineIslandChunks:e}=await import(`./inline-islands.js`);await e(t,{verbose:!0})}catch(e){console.error(`[islands] Inline fallback also failed:`,e)}}}function v(e,r){let i=l(r,`islands`);if(!n(i))return;let a=[l(e,`.output`,`public`),l(e,`.netlify`,`functions-internal`,`server`,`public`)];for(let e of a)n(e)&&t(i,l(e,`islands`),{recursive:!0,force:!0});console.log(`[islands] Synced isolated islands to output directories`)}function y(e){let t=l(e,`islands`);if(!n(t))return;let r=d(t,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(r.length===0)return;let i=[];for(let t of r){let n=t.substring(e.length).replaceAll(`\\`,`/`);i.push(`${n} ${n} 200`)}let o=l(e,`_redirects`),c=n(o)?a(o,`utf-8`):``;s(o,c?`${c}\n${i.join(`
1
+ import{copyFileSync as e,cpSync as t,existsSync as n,mkdirSync as r,readdirSync as i,readFileSync as a,statSync as o,unlinkSync as s,writeFileSync as c}from"node:fs";import{basename as l,dirname as u,join as d,relative as f}from"node:path";import{patchCloudflareWorkerOutput as p}from"./cloudflare-worker-patch.js";import{fetchHandlerWrapperSource as m}from"./fetch-handler-wrapper.js";function h(e,t,r=[]){if(!n(e))return r;for(let n of i(e,{withFileTypes:!0})){let i=d(e,n.name);n.isDirectory()?h(i,t,r):t(n.name)&&r.push(i)}return r}function g(e){try{return o(e).isFile()}catch{return!1}}function _(e){let t=d(e,`dist`,`_worker.js`);if(g(t))return t;if(!n(t))return null;for(let e of[`index.js`,`index.mjs`]){let n=d(t,e);if(g(n))return n}return null}function v(e){let t=d(e,`dist`,`_worker.js`,`_ssr`,`ssr.mjs`);return g(t)?t:null}function y(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.length<500&&!t.includes(`data-framework`)&&!t.includes(`avalon`)}function b(e){for(let t of[`dist/index.html`,`.netlify/functions-internal/server/public/index.html`,`.output/public/index.html`]){let r=d(e,t);y(r)?(s(r),console.log(`[cleanup] Removed stale Vite template ${t}`)):n(r)&&console.log(`[cleanup] Kept ${t} (not a Vite template)`)}}function x(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,])\s*/g,`$1`).trim()}export function patchSSRBundleCSS(e,t,r){if(!g(e))return!1;let i=[d(t,`assets`),d(r,`.netlify`,`functions-internal`,`server`,`public`,`assets`),d(r,`.output`,`public`,`assets`)].find(e=>n(e));if(!i)return!1;let o=h(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=h(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 s=a(e,`utf-8`),l=[{re:/"css"\s*:\s*\[((?:\s*\{\s*"href"\s*:\s*"[^"]+"\s*\}\s*,?)*)\]/,hrefRe:/"href"\s*:\s*"([^"]+)"/g,formatEntry:e=>`{ "href": "${e}" }`,rebuild:(e,t)=>{let n=e.trim().replace(/,\s*$/,``);return`"css": [${[...n?[n]:[],...t].join(`, `)}]`}},{re:/css:\[(\{href:`[^`]+`\}(?:,\{href:`[^`]+`\})*)\]/,hrefRe:/href:`([^`]+)`/g,formatEntry:e=>`{href:\`${e}\`}`,rebuild:(e,t)=>`css:[${e},${t.join(`,`)}]`},{re:/css:\[(\{href:"[^"]+"\}(?:,\{href:"[^"]+"\})*)\]/,hrefRe:/href:"([^"]+)"/g,formatEntry:e=>`{href:"${e}"}`,rebuild:(e,t)=>`css:[${e},${t.join(`,`)}]`}];for(let{re:t,hrefRe:n,formatEntry:r,rebuild:i}of l){let a=t.exec(s);if(!a)continue;let l=new Set([...a[1].matchAll(n)].map(e=>e[1])),u=o.filter(e=>!l.has(e));if(u.length===0)return console.log(`[patch] All CSS already included`),!0;let d=u.map(r);return s=s.replace(a[0],i(a[1],d)),c(e,s),console.log(`[patch] ✅ Added ${u.length} CSS files to SSR bundle`),!0}return console.warn(`[patch] Could not find CSS array in SSR bundle`),!1}function C(e,t){let o=d(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 s=[d(e,`node_modules`,`.nitro`,`vite`,`services`,`ssr`,`assets`)];for(let o of s){if(!n(o))continue;let s=i(o).filter(e=>e.endsWith(`.css`));if(s.length===0)continue;let l=[d(t,`assets`),d(e,`.output`,`public`,`assets`),d(e,`.netlify`,`functions-internal`,`server`,`public`,`assets`)];for(let e of l){r(e,{recursive:!0});for(let t of s){let n=a(d(o,t),`utf-8`);n=x(n),c(d(e,`ssr-${t}`),n)}}let u=`ssr-${s[0]}`,f=d(l.find(e=>n(e))||l[0],u),p=n(f)?a(f).length:0;console.log(`[ssr-css] Copied SSR CSS → /assets/${u} (${p} bytes, minified)`);let m=[d(e,`.output`,`server`,`index.mjs`),d(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of m){if(!n(e))continue;let t=a(e,`utf-8`),r=`/assets/${u}`;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/${u}\`}`;t=t.replace(i[0],i[0]+a),c(e,t),console.log(`[ssr-css] ✅ Patched asset manifest in ${e}`)}}return}console.log(`[ssr-css] No SSR CSS files found`)}async function w(e,t){let r=d(t,`islands`);if(!n(r)){console.log(`[islands] No islands directory found, skipping isolation`);return}let i=h(r,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(!i.some(e=>{let t=a(e,`utf-8`);return t.includes(`from"../`)||t.includes(`from'../`)})){console.log(`[islands] All islands are self-contained`);return}try{let{buildIsolatedIslands:r}=await import(`./isolated-island-builder.js`),o=new Map;for(let r of i){let i=f(t,r).replaceAll(`\\`,`/`).replace(/^islands\//,``).replace(/\.js$/,``),s=a(r,`utf-8`),c=`preact`;i.includes(`.solid`)?c=`solid`:i.includes(`.vue`)||i.endsWith(`.vue`)?c=`vue`:i.includes(`.svelte`)||i.endsWith(`.svelte`)?c=`svelte`:i.includes(`.lit`)?c=`lit`:i.includes(`.qwik`)?c=`qwik`:i.includes(`.react`)?c=`react`:i.includes(`.preact`)&&(c=`preact`);let l=/from["']((?:\/|\.\/)[^"']+\.(tsx|ts|jsx|js|vue|svelte))["']/i.exec(s),u;if(l&&!l[1].includes(`/assets/`)&&!l[1].startsWith(`../`))u=l[1];else{let t=i;u=[`${t}.tsx`,`${t}.ts`,`${t}.jsx`,`${t}.js`,`${t}`].find(t=>n(d(e,t)))??`${t}.tsx`}u.startsWith(`src/islands/`)&&(u=u.slice(12)),u.startsWith(`/`)||(u=`/${u}`),o.set(i,{filePath:u,bundleKey:i,framework:c})}await r(e,t,o,[],{})}catch{console.warn(`[islands] Isolated rebuild failed, falling back to inline-islands`);try{let{inlineIslandChunks:e}=await import(`./inline-islands.js`);await e(t,{verbose:!0})}catch(e){console.error(`[islands] Inline fallback also failed:`,e)}}}function T(e,r){let i=d(r,`islands`);if(!n(i))return;let a=[d(e,`.output`,`public`),d(e,`.netlify`,`functions-internal`,`server`,`public`)];for(let e of a)n(e)&&t(i,d(e,`islands`),{recursive:!0,force:!0});console.log(`[islands] Synced isolated islands to output directories`)}function E(e){let t=d(e,`islands`);if(!n(t))return;let r=h(t,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(r.length===0)return;let i=[];for(let t of r){let n=t.substring(e.length).replaceAll(`\\`,`/`);i.push(`${n} ${n} 200`)}let o=d(e,`_redirects`),s=n(o)?a(o,`utf-8`):``;c(o,s?`${s}\n${i.join(`
2
2
  `)}`:i.join(`
3
- `)),console.log(`[redirects] Generated ${i.length} island redirect(s)`)}function b(e,a){let o=l(e,`node_modules`,`@useavalon`);if(!n(o))return;let s=[l(a,`adapters`),l(e,`.output`,`public`,`adapters`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`adapters`)];for(let e of s){if(!n(c(e)))continue;let a=i(o).map(e=>l(o,e,`client`)).filter(e=>n(e));for(let n of a){let i=l(e,n.split(`/`).at(-2)||``);r(i,{recursive:!0}),t(n,i,{recursive:!0,force:!0})}}console.log(`[adapters] Copied framework adapters to output directories`)}function x(e){let i=l(e,`.netlify`,`functions-internal`),a=l(e,`.netlify`,`v1`,`functions`);n(i)&&(r(a,{recursive:!0}),t(i,a,{recursive:!0,force:!0}),console.log(`[netlify] Copied server function to v1 API paths`))}function S(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.includes(`netlify`)||t.includes(`lambda`)}function C(e,t,n){let r=l(c(e),`_prerender-server.mjs`);return s(r,`
4
- import 'urlpattern-polyfill';
5
- import { createServer } from 'node:http';
6
-
7
- // Nitro's main.mjs may export handler as named or default export
8
- const mod = await import('./main.mjs');
9
- const handler = mod.handler || mod.default;
10
- if (!handler) { console.error('No handler found in main.mjs'); process.exit(1); }
11
-
12
- const server = createServer(async (req, res) => {
13
- const url = new URL(req.url, 'http://localhost:${t}');
14
- try {
15
- const hdrs = new Headers();
16
- for (const [k, v] of Object.entries(req.headers)) {
17
- if (v) hdrs.set(k, Array.isArray(v) ? v.join(', ') : v);
18
- }
19
- const request = new Request(url.href, { method: req.method, headers: hdrs });
20
-
21
- let response;
22
- if (handler.fetch) {
23
- response = await handler.fetch(request);
24
- } else if (typeof handler === 'function') {
25
- response = await handler(request);
26
- } else {
27
- res.writeHead(500);
28
- res.end('Unknown handler format');
29
- return;
30
- }
31
-
32
- const body = await response.text();
33
- const resHdrs = {};
34
- if (response.headers && typeof response.headers.forEach === 'function') {
35
- response.headers.forEach((v, k) => { resHdrs[k] = v; });
36
- } else if (response.headers && typeof response.headers === 'object') {
37
- Object.assign(resHdrs, response.headers);
38
- }
39
- res.writeHead(response.status || 200, resHdrs);
40
- res.end(body);
41
- } catch (err) {
42
- console.error('Prerender request error:', err);
43
- res.writeHead(500);
44
- res.end('Internal Server Error');
45
- }
46
- });
47
- server.listen(${t}, '127.0.0.1', () => console.log('Listening on http://127.0.0.1:${t}'));
48
- `),r}function w(e){let t=/<a\s+[^>]*href=["']([^"']+)["'][^>]*>/gi,n=[],r;for(r=t.exec(e);r!==null;r=t.exec(e)){let e=r[1],t=e.indexOf(`#`);t!==-1&&(e=e.substring(0,t));let i=e.indexOf(`?`);i!==-1&&(e=e.substring(0,i)),e&&e.startsWith(`/`)&&!e.startsWith(`//`)&&!e.includes(`.`)&&n.push(e)}return n}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);r(c(a),{recursive:!0});let o=n.html.replace(`<!DOCTYPE html>`,`<!DOCTYPE html>
49
- <!-- SSG: prerendered at build time -->`).replaceAll(/<link rel="stylesheet" href="\/assets\/[^"]*\.css">\n?/g,e=>e.includes(`_isolated-island-entry`)?``:e);if(o=o.replaceAll(/<script type="module" src="\/assets\/entry-client[^"]*\.js"><\/script>\n?/g,``),o=o.replaceAll(/<link rel="stylesheet" href="\/assets\/entry-client[^"]*\.css">\n?/g,``),o=o.replaceAll(/<link rel="modulepreload" href="\/assets\/entry-client[^"]*\.js">\n?/g,``),s(a,o),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(`
50
- `);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)`)}const D=[/syntax-highlight/i,/hljs/i,/prism/i,/highlight\.js/i];function O(e,t){let r=[l(e,`.output`,`public`),t],i=A(r),o=0;for(let e of r){if(!n(e))continue;let t=d(e,e=>e===`index.html`);for(let e of t){let t=a(e,`utf-8`),n=t;t=j(t,i),t=k(t),t=M(t),t=N(t),t!==n&&(s(e,t),o++)}}o>0&&console.log(`[post-build] Optimized ${o} HTML file(s) — deferred non-critical CSS, added font preload hints`)}function k(e){if(!e.includes(`</head>`)||!e.includes(`<body`))return e;let t=e.indexOf(`</head>`),n=e.indexOf(`<body`);if(t===-1||n===-1||n<t)return e;let r=e.substring(n),i=new Set,a=[],o=``,s=0,c=0;for(;c<r.length;){if(r[c]===`<`){if(r.startsWith(`<template`,c)){s++;let e=r.indexOf(`>`,c);if(e===-1)break;o+=r.substring(c,e+1),c=e+1;continue}if(r.startsWith(`</template>`,c)){s=Math.max(0,s-1),o+=`</template>`,c+=11;continue}if(s===0&&r.startsWith(`<style`,c)){let e=r.indexOf(`</style>`,c);if(e===-1)break;let t=r.substring(c,e+8),n=/<style[^>]*>([\s\S]*?)<\/style>/.exec(t);if(n){let e=n[1].replaceAll(/\s+/g,` `).trim();e&&!i.has(e)&&(i.add(e),a.push(`<style>${e}</style>`))}c=e+8;continue}}o+=r[c],c++}return a.length===0?e:`${e.substring(0,t)}\n${a.join(`
51
- `)}\n</head>${o}`}function A(e){let t=new Map;for(let r of e){let e=l(r,`assets`);if(n(e))for(let n of i(e))n.endsWith(`.css`)&&t.set(`/assets/${n}`,a(l(e,n),`utf-8`))}return t}function j(e,t){let n=/<link\s+rel="stylesheet"\s+href="(\/assets\/(?:ssr-)?index-[^"]+\.css)">/i.exec(e);if(!n)return e;let r=n[1],i=t.get(r);if(!i)return e;if(Buffer.byteLength(i,`utf-8`)<=14336){let t=`<style data-inlined-from="${r}">${i}</style>`;return e.replace(n[0],t)}let a=`<link rel="preload" href="${r}" as="style">`;return e.includes(`</title>`)&&!e.includes(`preload" href="${r}"`)&&(e=e.replace(`</title>`,`</title>\n${a}`)),e}function M(e){return e.replaceAll(/<link\s+([^>]*rel=["']stylesheet["'][^>]*)>/gi,(e,t)=>{if(/\bmedia\s*=/i.test(t)||/data-critical/i.test(t))return e;let n=/href=["']([^"']+)["']/i.exec(t);if(!n)return e;let r=n[1],i=r.startsWith(`https://`)||r.startsWith(`http://`),a=!i&&D.some(e=>e.test(r));return!i&&!a?e:`<link ${t} media="print" onload="this.media='all'">\n<noscript><link ${t}></noscript>`})}function N(e){let t=/href=["'](https:\/\/fonts\.googleapis\.com\/css2[^"']+)["']/gi,n=new Set,r;for(r=t.exec(e);r!==null;r=t.exec(e))n.add(r[1]);if(n.size===0)return e;let i=[];for(let t of n){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`);new RegExp(String.raw`<link\s+[^>]*rel=["']preload["'][^>]*href=["']${n}["'][^>]*>`,`i`).test(e)||i.push(`<link rel="preload" href="${t}" as="style">`)}if(i.length===0)return e;let a=i.join(`
52
- `);return e.includes(`</title>`)?e.replace(`</title>`,`</title>\n${a}`):e}async function P(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)`)}function F(e){let t=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`index.mjs`)],r=l(e,`.output`,`public`);if(!n(r))return;let i=I(r);if(i.length===0)return;let a=0;for(let e of t)L(e,i,r)&&a++;a>0&&console.log(`[manifest] ✅ Registered ${i.length} prerendered HTML file(s) in Nitro asset manifest`)}function I(e){let t=d(e,e=>e===`index.html`||e===`index.html.br`||e===`index.html.gz`||e===`index.html.zst`),n=[],r=new Date().toISOString();for(let i of t){let t=`/${i.substring(e.length+1).replaceAll(`\\`,`/`)}`,o=a(i).length,s=`"${o.toString(16)}-prerender"`,c=``;t.endsWith(`.br`)?c=`br`:t.endsWith(`.gz`)?c=`gzip`:t.endsWith(`.zst`)&&(c=`zstd`);let l=`"${t}":{type:\`text/html; charset=utf-8\``;c&&(l+=`,encoding:\`${c}\``),l+=`,etag:\`${s}\`,mtime:\`${r}\`,size:${o},path:\`../public${t}\`}`,n.push(l)}return n}function L(e,t,r){if(!n(e))return!1;let i=a(e,`utf-8`),o=/("\/favicon\.ico":\{[^}]+\})/.exec(i);if(!o)return!1;let c=t.filter(e=>{let t=/^"([^"]+)"/.exec(e);return t&&!i.includes(`"${t[1]}":{`)});c.length>0&&(i=i.replace(o[0],`${o[0]},${c.join(`,`)}`));let l=R(r),u="u===`/favicon.ico`&&d.unshift({data:e})";for(let e of l){if(i.includes(`route:\`${e}\``))continue;let t=`[{name:\`headers\`,route:\`${e}\`,handler:x,options:{"Cache-Control":\`public, max-age=0, must-revalidate\`}}]`;i=i.replace(u,`${u};u===\`${e}\`&&d.unshift({data:${t}})`)}return s(e,i),c.length>0||l.length>0}function R(e){let t=[];if(!n(e))return t;for(let r of i(e,{withFileTypes:!0}))!r.isDirectory()&&r.name===`index.html`?t.push(`/`):r.isDirectory()&&n(l(e,r.name,`index.html`))&&t.push(`/${r.name}`);return t}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}`),h(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),O(t,r),await P(t),F(t),console.log(`[post-build] ✅ Complete`)}
3
+ `)),console.log(`[redirects] Generated ${i.length} island redirect(s)`)}function D(e,a){let o=d(e,`node_modules`,`@useavalon`);if(!n(o))return;let s=[d(a,`adapters`),d(e,`.output`,`public`,`adapters`),d(e,`.netlify`,`functions-internal`,`server`,`public`,`adapters`)];for(let e of s){if(!n(u(e)))continue;let a=i(o).map(e=>d(o,e,`client`)).filter(e=>n(e));for(let n of a){let i=d(e,n.split(`/`).at(-2)||``);r(i,{recursive:!0}),t(n,i,{recursive:!0,force:!0})}}console.log(`[adapters] Copied framework adapters to output directories`)}function O(e){let i=d(e,`.netlify`,`functions-internal`),a=d(e,`.netlify`,`v1`,`functions`);n(i)&&(r(a,{recursive:!0}),t(i,a,{recursive:!0,force:!0}),console.log(`[netlify] Copied server function to v1 API paths`))}function k(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.includes(`netlify`)||t.includes(`lambda`)}function A(e,t){let n=d(u(e),`_prerender-server.mjs`);return c(n,m(`./${l(e)}`,t)),n}function j(e){let t=/<a\s+[^>]*href=["']([^"']+)["'][^>]*>/gi,n=[],r;for(r=t.exec(e);r!==null;r=t.exec(e)){let e=r[1],t=e.indexOf(`#`);t!==-1&&(e=e.substring(0,t));let i=e.indexOf(`?`);i!==-1&&(e=e.substring(0,i)),e&&e.startsWith(`/`)&&!e.startsWith(`//`)&&!e.includes(`.`)&&n.push(e)}return n}async function M(t,i,o,l){let p=_(t),m=[d(t,`.netlify`,`functions-internal`,`server`,`server.mjs`),d(t,`.netlify`,`v1`,`functions`,`server`,`server.mjs`),d(t,`.output`,`server`,`index.mjs`),...p?[p]:[]].find(e=>n(e));if(!m){console.log(`[prerender] No server entry found, skipping prerender`);return}let h=[d(t,`.output`,`public`),i].find(e=>n(e));if(!h){console.log(`[prerender] No output directory found, skipping prerender`);return}let v={routes:o.routes??[`/`],crawlLinks:o.crawlLinks??!0,ignore:o.ignore??[],failOnError:o.failOnError??!1,concurrency:o.concurrency??4,autoSubfolderIndex:o.autoSubfolderIndex??!0,retry:o.retry??3,retryDelay:o.retryDelay??500},y=`http://localhost:${l}`,b=k(m),x=p!==null&&m===p,S=m;if(b){let e=d(u(m),`main.mjs`);if(!n(e)){console.error(`[prerender] Netlify handler detected but main.mjs not found`);return}S=A(e,l),console.log(`[prerender] Netlify handler detected — using wrapper`)}else x&&(S=A(m,l),console.log(`[prerender] Cloudflare worker detected — using wrapper`));{let e=[m,d(u(m),`main.mjs`)].filter(e=>g(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&&(c(n,e),console.log(`[prerender] Patched ${f(t,n)}: removed HTML asset entries`))}}console.log(`[prerender] Starting prerender with server: ${f(t,S)}`);let{spawn:C}=await import(`node:child_process`),w;try{w=C(`node`,[S],{env:{...process.env,PORT:String(l),NITRO_PORT:String(l),HOST:`127.0.0.1`,NITRO_HOST:`127.0.0.1`,NODE_ENV:`production`},stdio:[`ignore`,`pipe`,`pipe`]}),w.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.log(`[prerender:server] ${t}`)}),w.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(`${y}/`);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 ${y}`)}catch(e){w?.kill(`SIGKILL`),console.error(`[prerender] Failed to start server:`,e.message);return}let T=new Set,E=[...v.routes],D=[],O=[];function M(e){for(let t of v.ignore)if(typeof t==`string`&&e===t||typeof t==`string`&&t.endsWith(`/**`)&&e.startsWith(t.slice(0,-2)))return!0;return!1}try{for(;E.length>0;){let e=E.splice(0,v.concurrency);await Promise.all(e.map(async e=>{let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;if(T.has(t)||(T.add(t),M(t)))return;let n=null;for(let e=1;e<=v.retry;e++)try{let e=await fetch(`${y}${t}`);n={html:await e.text(),status:e.status};break}catch{e<v.retry&&await new Promise(e=>setTimeout(e,v.retryDelay))}if(!n){O.push({route:t,error:`Failed after ${v.retry} attempts`});return}if(n.status>=400){O.push({route:t,error:`Returned ${n.status}`});return}let i=v.autoSubfolderIndex?d(t,`index.html`):`${t}.html`,a=d(h,i);r(u(a),{recursive:!0});let o=n.html.replace(`<!DOCTYPE html>`,`<!DOCTYPE html>
4
+ <!-- SSG: prerendered at build time -->`).replaceAll(/<link rel="stylesheet" href="\/assets\/[^"]*\.css">\n?/g,e=>e.includes(`_isolated-island-entry`)?``:e);if(o=o.replaceAll(/<script type="module" src="\/assets\/entry-client[^"]*\.js"><\/script>\n?/g,``),(/\/assets\/(?:ssr-)?index-[^"]+\.css/.test(o)||/<style data-inlined-from="\/assets\/(?:ssr-)?index-/.test(o))&&(o=o.replaceAll(/<link rel="stylesheet" href="\/assets\/entry-client[^"]*\.css">\n?/g,``)),o=o.replaceAll(/<link rel="modulepreload" href="\/assets\/entry-client[^"]*\.js">\n?/g,``),c(a,o),D.push(t),console.log(`[prerender] ✅ ${t} → ${i}`),v.crawlLinks)for(let e of j(n.html)){let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;!T.has(t)&&!M(t)&&E.push(t)}}))}}finally{console.log(`[prerender] Shutting down server...`),w?.kill(`SIGKILL`)}if(console.log(`[prerender] Done: ${D.length} page(s) prerendered`+(O.length>0?`, ${O.length} error(s)`:``)),b||x){let e=d(u(m),`_prerender-server.mjs`);n(e)&&(s(e),console.log(`[prerender] Cleaned up wrapper script`))}if(D.length>0){let a=[i,d(t,`.netlify`,`functions-internal`,`server`,`public`),d(t,`.netlify`,`v1`,`functions`,`server`,`public`)].filter(e=>e!==h&&n(u(e)));for(let t of a)for(let i of D){let a=d(i,`index.html`),o=d(h,a),s=d(t,a);n(o)&&(r(u(s),{recursive:!0}),e(o,s))}a.length>0&&console.log(`[prerender] Copied prerendered HTML to ${a.length} additional output dir(s)`)}}function N(e,t){let r={},i=d(t,`island-deps.json`);if(n(i))try{r=JSON.parse(a(i,`utf-8`))}catch{}let o=d(e,`.output`,`public`);if(Object.keys(r).length===0&&n(o)){let e=h(d(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=[],c;for(c=i.exec(n);c!==null;c=i.exec(n)){let t=c[1]||c[2];if(t&&(t.includes(`/assets/`)||t.startsWith(`.`))){let n=(t.startsWith(`.`)?`/${d(u(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 s=[d(e,`.output`,`public`),t],l=0;for(let e of s){if(!n(e))continue;let t=h(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(`
5
+ `);t.includes(`</head>`)&&(t=t.replace(`</head>`,`${i}\n</head>`),c(e,t),l++)}}l>0&&console.log(`[modulepreload] ✅ Injected dependency preloads into ${l} HTML file(s)`)}const P=[/syntax-highlight/i,/hljs/i,/prism/i,/highlight\.js/i];function F(e,t){let r=[d(e,`.output`,`public`),t],i=L(r),o=0;for(let e of r){if(!n(e))continue;let t=h(e,e=>e===`index.html`);for(let e of t){let t=a(e,`utf-8`),n=t;t=R(t,i),t=I(t),t=z(t),t=B(t),t!==n&&(c(e,t),o++)}}o>0&&console.log(`[post-build] Optimized ${o} HTML file(s) — deferred non-critical CSS, added font preload hints`)}function I(e){if(!e.includes(`</head>`)||!e.includes(`<body`))return e;let t=e.indexOf(`</head>`),n=e.indexOf(`<body`);if(t===-1||n===-1||n<t)return e;let r=e.substring(n),i=new Set,a=[],o=``,s=0,c=0;for(;c<r.length;){if(r[c]===`<`){if(r.startsWith(`<template`,c)){s++;let e=r.indexOf(`>`,c);if(e===-1)break;o+=r.substring(c,e+1),c=e+1;continue}if(r.startsWith(`</template>`,c)){s=Math.max(0,s-1),o+=`</template>`,c+=11;continue}if(s===0&&r.startsWith(`<style`,c)){let e=r.indexOf(`</style>`,c);if(e===-1)break;let t=r.substring(c,e+8),n=/<style[^>]*>([\s\S]*?)<\/style>/.exec(t);if(n){let e=n[1].replaceAll(/\s+/g,` `).trim();e&&!i.has(e)&&(i.add(e),a.push(`<style>${e}</style>`))}c=e+8;continue}}o+=r[c],c++}return a.length===0?e:`${e.substring(0,t)}\n${a.join(`
6
+ `)}\n</head>${o}`}function L(e){let t=new Map;for(let r of e){let e=d(r,`assets`);if(n(e))for(let n of i(e))n.endsWith(`.css`)&&t.set(`/assets/${n}`,a(d(e,n),`utf-8`))}return t}function R(e,t){let n=/<link\s+rel="stylesheet"\s+href="(\/assets\/(?:ssr-)?index-[^"]+\.css)">/i.exec(e);if(!n)return e;let r=n[1],i=t.get(r);if(!i)return e;if(Buffer.byteLength(i,`utf-8`)<=14336){let t=`<style data-inlined-from="${r}">${i}</style>`;return e.replace(n[0],t)}let a=`<link rel="preload" href="${r}" as="style">`;return e.includes(`</title>`)&&!e.includes(`preload" href="${r}"`)&&(e=e.replace(`</title>`,`</title>\n${a}`)),e}function z(e){return e.replaceAll(/<link\s+([^>]*rel=["']stylesheet["'][^>]*)>/gi,(t,n,r)=>{if(e.slice(Math.max(0,r-32),r).toLowerCase().includes(`<noscript`))return t;let i=n.replace(/\s*\/\s*$/,``).trim();if(/\bmedia\s*=/i.test(i)||/data-critical/i.test(i))return t;let a=/href=["']([^"']+)["']/i.exec(i);if(!a)return t;let o=a[1],s=o.startsWith(`https://`)||o.startsWith(`http://`),c=!s&&P.some(e=>e.test(o));return!s&&!c?t:`<link ${i} media="print" onload="this.media='all'">\n<noscript><link ${i}></noscript>`})}function B(e){let t=/href=["'](https:\/\/fonts\.googleapis\.com\/css2[^"']+)["']/gi,n=new Set,r;for(r=t.exec(e);r!==null;r=t.exec(e))n.add(r[1]);if(n.size===0)return e;let i=[];for(let t of n){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`);new RegExp(String.raw`<link\s+[^>]*rel=["']preload["'][^>]*href=["']${n}["'][^>]*>`,`i`).test(e)||i.push(`<link rel="preload" href="${t}" as="style">`)}if(i.length===0)return e;let a=i.join(`
7
+ `);return e.includes(`</title>`)?e.replace(`</title>`,`</title>\n${a}`):e}async function V(e){let{promisify:t}=await import(`node:util`),r=await import(`node:zlib`),i=t(r.brotliCompress),o=t(r.gzip),s=[d(e,`.output`,`public`),d(e,`.netlify`,`functions-internal`,`server`,`public`)],l=e=>e.endsWith(`.js`)||e.endsWith(`.css`)||e.endsWith(`.html`)||e.endsWith(`.svg`)||e.endsWith(`.txt`)||e.endsWith(`.xml`)||e.endsWith(`.json`),u=0;for(let e of s){if(!n(e))continue;let t=h(e,e=>l(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})]);c(`${e}.br`,n),c(`${e}.gz`,a),u++}catch{}}}u>0&&console.log(`[compress] ✅ Compressed ${u} public asset(s) (brotli + gzip)`)}function H(e){let t=[d(e,`.output`,`server`,`index.mjs`),d(e,`.netlify`,`functions-internal`,`server`,`index.mjs`)],r=d(e,`.output`,`public`);if(!n(r))return;let i=U(r);if(i.length===0)return;let a=0;for(let e of t)W(e,i,r)&&a++;a>0&&console.log(`[manifest] ✅ Registered ${i.length} prerendered HTML file(s) in Nitro asset manifest`)}function U(e){let t=h(e,e=>e===`index.html`||e===`index.html.br`||e===`index.html.gz`||e===`index.html.zst`),n=[],r=new Date().toISOString();for(let i of t){let t=`/${i.substring(e.length+1).replaceAll(`\\`,`/`)}`,o=a(i).length,s=`"${o.toString(16)}-prerender"`,c=``;t.endsWith(`.br`)?c=`br`:t.endsWith(`.gz`)?c=`gzip`:t.endsWith(`.zst`)&&(c=`zstd`);let l=`"${t}":{type:\`text/html; charset=utf-8\``;c&&(l+=`,encoding:\`${c}\``),l+=`,etag:\`${s}\`,mtime:\`${r}\`,size:${o},path:\`../public${t}\`}`,n.push(l)}return n}function W(e,t,r){if(!n(e))return!1;let i=a(e,`utf-8`),o=/("\/favicon\.ico":\{[^}]+\})/.exec(i);if(!o)return!1;let s=t.filter(e=>{let t=/^"([^"]+)"/.exec(e);return t&&!i.includes(`"${t[1]}":{`)});s.length>0&&(i=i.replace(o[0],`${o[0]},${s.join(`,`)}`));let l=G(r),u="u===`/favicon.ico`&&d.unshift({data:e})";for(let e of l){if(i.includes(`route:\`${e}\``))continue;let t=`[{name:\`headers\`,route:\`${e}\`,handler:x,options:{"Cache-Control":\`public, max-age=0, must-revalidate\`}}]`;i=i.replace(u,`${u};u===\`${e}\`&&d.unshift({data:${t}})`)}return c(e,i),s.length>0||l.length>0}function G(e){let t=[];if(!n(e))return t;for(let r of i(e,{withFileTypes:!0}))!r.isDirectory()&&r.name===`index.html`?t.push(`/`):r.isDirectory()&&n(d(e,r.name,`index.html`))&&t.push(`/${r.name}`);return t}export async function runPostBuild(e={}){let t=e.cwd??process.cwd(),n=d(t,`dist`),r=e.prerenderPort??13172;b(t),C(t,n);for(let e of[d(t,`.netlify`,`functions-internal`,`server`,`_ssr`,`ssr.mjs`),d(t,`.netlify`,`v1`,`functions`,`server`,`_ssr`,`ssr.mjs`),d(t,`.output`,`server`,`_ssr`,`ssr.mjs`),v(t)])e&&g(e)&&(console.log(`[patch] Patching ${e}`),patchSSRBundleCSS(e,n,t));await w(t,n),T(t,n),E(n),D(t,n),O(t),p(t),e.prerender!==!1&&await M(t,n,e.prerender??{},r),N(t,n),F(t,n),await V(t),H(t),console.log(`[post-build] ✅ Complete`)}
@@ -1 +1 @@
1
- import{createCipheriv as e,createDecipheriv as t,randomBytes as n}from"node:crypto";let r=``;try{r=(await import(`virtual:server-island-key`)).serverIslandKey??``}catch{}const i=`aes-256-gcm`;let a,o=!1;export function generateKey(){return n(32).toString(`base64`)}export function getKey(){let e=globalThis.process?.env??{},t=e.AVALON_KEY;if(t){let e=Buffer.from(t,`base64`);if(e.length!==32)throw Error(`AVALON_KEY must be a base64-encoded 256-bit (32-byte) key. Got ${e.length} bytes.`);return t}if(r&&Buffer.from(r,`base64`).length===32)return r;if((e.NODE_ENV??globalThis.process?.env?.NODE_ENV)===`production`)throw Error("AVALON_KEY is required in production for server islands. Generate one with `npx avalon key` and set it as an environment variable so all server instances share the same encryption secret.");return o||(o=!0,console.warn(`[avalon] AVALON_KEY not set — using a per-process key for server islands. This only works for single-process development. Set AVALON_KEY for production.`)),a||=generateKey(),a}function c(e){return e.replaceAll(`+`,`-`).replaceAll(`/`,`_`).replace(/=+$/,``)}function l(e){let t=e.replaceAll(`-`,`+`).replaceAll(`_`,`/`),n=t.length%4;return n===2?t+=`==`:n===3&&(t+=`=`),t}export function encrypt(t,r){let a=Buffer.from(r??getKey(),`base64`);if(a.length!==32)throw Error(`Encryption key must be 32 bytes. Got ${a.length} bytes.`);let o=n(12),s=e(i,a,o),l=Buffer.concat([s.update(t,`utf8`),s.final()]),u=s.getAuthTag();return c(Buffer.concat([o,l,u]).toString(`base64`))}export function decrypt(e,n){let r=Buffer.from(n??getKey(),`base64`);if(r.length!==32)throw Error(`Encryption key must be 32 bytes. Got ${r.length} bytes.`);let a=Buffer.from(l(e),`base64`);if(a.length<28)throw Error(`Invalid encrypted data: too short`);let o=a.subarray(0,12),s=a.subarray(a.length-16),c=a.subarray(12,a.length-16),u=t(i,r,o);return u.setAuthTag(s),Buffer.concat([u.update(c),u.final()]).toString(`utf8`)}
1
+ import{createCipheriv as e,createDecipheriv as t,randomBytes as n}from"node:crypto";let r=``;try{r=(await import(`virtual:server-island-key`)).serverIslandKey??``}catch{}const i=`aes-256-gcm`;let a,o=!1;export function generateKey(){return n(32).toString(`base64`)}function c(){try{let e=globalThis.process?.env;if(e&&typeof e==`object`)return e}catch{}return{}}export function getKey(){let e=c(),t=e.AVALON_KEY;if(t){let e=Buffer.from(t,`base64`);if(e.length!==32)throw Error(`AVALON_KEY must be a base64-encoded 256-bit (32-byte) key. Got ${e.length} bytes.`);return t}if(r&&Buffer.from(r,`base64`).length===32)return r;if(e.NODE_ENV===`production`)throw Error("AVALON_KEY is required in production for server islands. Generate one with `npx avalon key` and set it as an environment variable so all server instances share the same encryption secret.");return o||(o=!0,console.warn(`[avalon] AVALON_KEY not set — using a per-process key for server islands. This only works for single-process development. Set AVALON_KEY for production.`)),a||=generateKey(),a}function l(e){return e.replaceAll(`+`,`-`).replaceAll(`/`,`_`).replace(/=+$/,``)}function u(e){let t=e.replaceAll(`-`,`+`).replaceAll(`_`,`/`),n=t.length%4;return n===2?t+=`==`:n===3&&(t+=`=`),t}export function encrypt(t,r){let a=Buffer.from(r??getKey(),`base64`);if(a.length!==32)throw Error(`Encryption key must be 32 bytes. Got ${a.length} bytes.`);let o=n(12),s=e(i,a,o),c=Buffer.concat([s.update(t,`utf8`),s.final()]),u=s.getAuthTag();return l(Buffer.concat([o,c,u]).toString(`base64`))}export function decrypt(e,n){let r=Buffer.from(n??getKey(),`base64`);if(r.length!==32)throw Error(`Encryption key must be 32 bytes. Got ${r.length} bytes.`);let a=Buffer.from(u(e),`base64`);if(a.length<28)throw Error(`Invalid encrypted data: too short`);let o=a.subarray(0,12),s=a.subarray(a.length-16),c=a.subarray(12,a.length-16),l=t(i,r,o);return l.setAuthTag(s),Buffer.concat([l.update(c),l.final()]).toString(`utf8`)}
@@ -1,4 +1,4 @@
1
- import{serverIslandCSS as e,serverIslandLoaders as t}from"virtual:server-island-manifest";import{h as n}from"preact";import r from"preact-render-to-string";import{loadIntegration as i}from"../islands/integration-loader.js";import{escapeJsonForScript as a,generatePerIslandScript as o}from"../islands/per-island-script.js";import{decrypt as s}from"./encryption.js";import{lookupComponent as c}from"./manifest.js";const l=t??{};function u(){return l}function d(e,t){return new Response(e,{status:t,headers:{"Content-Type":`text/plain`}})}export function defineServerIslandHandler(e={}){let{isDev:t=process.env.NODE_ENV!==`production`,defaultCacheControl:n=`private, no-store`}=e;return async e=>{let r=y(e);if(!r)return d(`Missing component ID`,400);let i=await p(e);if(i instanceof Response)return i;let a=m(i,t);if(a instanceof Response)return a;let{props:o,islandMeta:s,srcPath:l}=a,u=c(r)??(t?l:void 0);if(!u)return d(`Component not found`,404);let f=await h(r,u,t,!!s);if(f instanceof Response)return f;let _=await g({componentModule:f,props:o,islandMeta:s,componentId:r,modulePath:u,isDev:t});if(_ instanceof Response)return _;let b=_.html;return s&&(b+=v({componentId:r,islandMeta:s,modulePath:u,props:o,ssrFailed:_.ssrFailed,hydrationRenderId:_.hydrationRenderId,isDev:t})),new Response(b,{status:200,headers:{"Content-Type":`text/html`,"Cache-Control":n}})}}async function p(e){let t;try{t=await S(e)}catch{return d(`Failed to read request body`,400)}return t||d(`Missing encrypted props`,400)}function m(e,t){try{let n;n=t&&e.startsWith(`dev.`)?Buffer.from(e.slice(4),`base64url`).toString(`utf8`):s(e);let r=JSON.parse(n),i={props:r};return r.__island&&(i.islandMeta=r.__island,delete r.__island),r.__src&&(i.srcPath=r.__src,delete r.__src),i}catch{return d(`Bad Request: decryption failed`,400)}}async function h(e,t,n,r){try{let r=u()[e],i;if(r?i=await r():(n&&console.log(`[server-islands] Loading component from:`,t),i=await import(t)),!i.default)throw TypeError(`Module "${t}" does not have a default export`);return i}catch(e){return r&&n?(console.warn(`[server-islands] Component import failed (will render client-side):`,t,e instanceof Error?e.message:e),{default:null}):d(n&&e instanceof Error?e.message:`Component import failed`,500)}}async function g(e){let{componentModule:t,props:i,islandMeta:a,componentId:o,modulePath:s,isDev:c}=e;if(!t.default)return{html:``,ssrFailed:!0};let l=a?.framework??`preact`;try{if(l===`preact`||l===`react`){let e=t.default;return{html:r(n(e,i)),ssrFailed:!1}}return await _({framework:l,component:t.default,props:i,islandMeta:a,componentId:o,modulePath:s,isDev:c})}catch(e){if(a&&c)return{html:``,ssrFailed:!0};let t=c&&e instanceof Error?`${e.message}\n${e.stack}`:``;return console.error(`[server-islands] Render error for`,s,e),d(t||`Internal Server Error`,500)}}async function _(t){let{framework:n,component:r,props:a,islandMeta:o,componentId:s,modulePath:c,isDev:l}=t,u=await(await i(n)).render({component:r,props:a,src:c,condition:o?.condition??`on:client`,ssrOnly:!1,viteServer:void 0,isDev:l}),d=u.html;u.css?d=`${d}<style>${u.css}</style>`:e[s]&&(d=`${d}<style>${e[s]}</style>`);let f=u.hydrationData?.renderId;return{html:d,ssrFailed:!1,hydrationRenderId:f}}function v(e){let{componentId:t,islandMeta:n,modulePath:r,props:i,ssrFailed:s,hydrationRenderId:c,isDev:l}=e,u=n.elementId??`si-${t}`,d=n.componentSrc??r,f;try{f=JSON.stringify(i)}catch(e){let n=e instanceof Error?e.message:String(e);throw Error(`Failed to serialize props for server island (componentId=${t}, module=${r}, elementId=${u}): ${n}`)}if(l){let e=s?`on:client`:n.condition??`on:client`,t=new URL(`../client/server-island-hydrate.ts`,import.meta.url).pathname,r=n.framework??`preact`,i=c?JSON.stringify(c):`undefined`;return`<script type="module">
1
+ import{ensureServerIslandIntegrations as e}from"virtual:server-island-integrations";import{serverIslandCSS as t,serverIslandLoaders as n,serverIslandManifest as r}from"virtual:server-island-manifest";import{h as i}from"preact";import a from"preact-render-to-string";import{loadIntegration as o}from"../islands/integration-loader.js";import{escapeJsonForScript as s,generatePerIslandScript as c}from"../islands/per-island-script.js";import{decrypt as l}from"./encryption.js";import{lookupComponent as u}from"./manifest.js";const d=n??{};function f(){return d}function p(e,t){return new Response(e,{status:t,headers:{"Content-Type":`text/plain`}})}export function defineServerIslandHandler(t={}){let{isDev:n=process.env.NODE_ENV!==`production`,defaultCacheControl:i=`private, no-store`}=t;return async t=>{e();let a=x(t);if(!a)return p(`Missing component ID`,400);let o=await h(t);if(o instanceof Response)return o;let s=g(o,n);if(s instanceof Response)return s;let{props:c,islandMeta:l,srcPath:d}=s,f=u(a)??r?.[a]??(n?d:void 0);if(!f)return p(`Component not found`,404);let m=await _(a,f,n,!!l);if(m instanceof Response)return m;let y=await v({componentModule:m,props:c,islandMeta:l,componentId:a,modulePath:f,isDev:n});if(y instanceof Response)return y;let S=y.html;return l&&(S+=b({componentId:a,islandMeta:l,modulePath:f,props:c,ssrFailed:y.ssrFailed,hydrationRenderId:y.hydrationRenderId,isDev:n})),new Response(S,{status:200,headers:{"Content-Type":`text/html`,"Cache-Control":i}})}}async function h(e){let t;try{t=await w(e)}catch{return p(`Failed to read request body`,400)}return t||p(`Missing encrypted props`,400)}function g(e,t){try{let n;n=t&&e.startsWith(`dev.`)?Buffer.from(e.slice(4),`base64url`).toString(`utf8`):l(e);let r=JSON.parse(n),i={props:r};return r.__island&&(i.islandMeta=r.__island,delete r.__island),r.__src&&(i.srcPath=r.__src,delete r.__src),i}catch{return p(`Bad Request: decryption failed`,400)}}async function _(e,t,n,r){try{let r=f()[e],i;if(r?i=await r():(n&&console.log(`[server-islands] Loading component from:`,t),i=await import(t)),!i.default)throw TypeError(`Module "${t}" does not have a default export`);return i}catch(e){return r&&n?(console.warn(`[server-islands] Component import failed (will render client-side):`,t,e instanceof Error?e.message:e),{default:null}):p(n&&e instanceof Error?e.message:`Component import failed`,500)}}async function v(e){let{componentModule:t,props:n,islandMeta:r,componentId:o,modulePath:s,isDev:c}=e;if(!t.default)return{html:``,ssrFailed:!0};let l=r?.framework??`preact`;try{if(l===`preact`||l===`react`){let e=t.default;return{html:a(i(e,n)),ssrFailed:!1}}return await y({framework:l,component:t.default,props:n,islandMeta:r,componentId:o,modulePath:s,isDev:c})}catch(e){if(r&&c)return{html:``,ssrFailed:!0};let t=c&&e instanceof Error?`${e.message}\n${e.stack}`:``;return console.error(`[server-islands] Render error for`,s,e),p(t||`Internal Server Error`,500)}}async function y(e){let{framework:n,component:r,props:i,islandMeta:a,componentId:s,modulePath:c,isDev:l}=e,u=await(await o(n)).render({component:r,props:i,src:c,condition:a?.condition??`on:client`,ssrOnly:!1,viteServer:void 0,isDev:l}),d=u.html;u.css?d=`${d}<style>${u.css}</style>`:t[s]&&(d=`${d}<style>${t[s]}</style>`);let f=u.hydrationData?.renderId;return{html:d,ssrFailed:!1,hydrationRenderId:f}}function b(e){let{componentId:t,islandMeta:n,modulePath:r,props:i,ssrFailed:a,hydrationRenderId:o,isDev:l}=e,u=n.elementId??`si-${t}`,d=n.componentSrc??r,f;try{f=JSON.stringify(i)}catch(e){let n=e instanceof Error?e.message:String(e);throw Error(`Failed to serialize props for server island (componentId=${t}, module=${r}, elementId=${u}): ${n}`)}if(l){let e=a?`on:client`:n.condition??`on:client`,t=new URL(`../client/server-island-hydrate.ts`,import.meta.url).pathname,r=n.framework??`preact`,i=o?JSON.stringify(o):`undefined`;return`<script type="module">
2
2
  import{hydrateServerIsland}from"/@fs${t}";
3
- hydrateServerIsland(${JSON.stringify(u)},${JSON.stringify(d)},${a(f)},${JSON.stringify(e)},${JSON.stringify(r)},${i});
4
- <\/script>`}return o({islandId:u,componentSrc:d,framework:n.framework,condition:n.condition,conditionArg:n.conditionArg,propsJson:f})}function y(e){let t=e.context?.params;if(t?.componentId)return t.componentId;let n=b(e);return/\/_server-islands\/([^/?]+)/.exec(n)?.[1]}function b(e){if(e.url)return e.url.pathname;let t=e.req?.url;return t?new URL(t,`http://localhost`).pathname:`/`}function x(e){return e.req?.method??`GET`}async function S(e){let t=x(e).toUpperCase();if(t===`GET`)return(e.url?e.url.searchParams:new URLSearchParams(``)).get(`p`)||void 0;if(t===`POST`){let t=e.web?.request;if(t)return await t.text();if(e.node?.req)return await C(e.node.req);if(e._body!==void 0)return String(e._body)}}function C(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>r.push(e)),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}
3
+ hydrateServerIsland(${JSON.stringify(u)},${JSON.stringify(d)},${s(f)},${JSON.stringify(e)},${JSON.stringify(r)},${i});
4
+ <\/script>`}return c({islandId:u,componentSrc:d,framework:n.framework,condition:n.condition,conditionArg:n.conditionArg,propsJson:f})}function x(e){let t=e.context?.params;if(t?.componentId)return t.componentId;let n=S(e);return/\/_server-islands\/([^/?]+)/.exec(n)?.[1]}function S(e){if(e.url)return e.url.pathname;let t=e.req?.url;return t?new URL(t,`http://localhost`).pathname:`/`}function C(e){return e.req?.method??`GET`}async function w(e){let t=C(e).toUpperCase();if(t===`GET`)return(e.url?e.url.searchParams:new URLSearchParams(``)).get(`p`)||void 0;if(t===`POST`){let t=e.web?.request;if(t)return await t.text();if(e.node?.req)return await T(e.node.req);if(e._body!==void 0)return String(e._body)}}function T(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>r.push(e)),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}
@@ -1,4 +1,4 @@
1
- import e from"preact-render-to-string";import{encrypt as t}from"./encryption.js";const n=(globalThis.process?.env??{}).NODE_ENV!==`production`;function r(e){return n?`dev.${Buffer.from(e,`utf8`).toString(`base64url`)}`:t(e)}let i=0;function a(e,t){try{return JSON.stringify(e)}catch(e){let n=e instanceof Error?e.message:String(e);throw Error(`Failed to serialize server island props (elementId=${t.elementId}, componentSrc=${t.componentSrc??`unknown`}, combinedIsland=${t.hasIsland}). Props must be JSON-serializable (no functions, circular refs, or BigInt): ${n}`)}}export function renderServerIsland(t,n,o,l,u,d,f){let p=`si-${t}-${i++}`,m={...n};d&&(m.__src=d),l&&(m.__island={condition:l.condition??`on:client`,conditionArg:l.conditionArg,framework:f??`preact`,componentSrc:u,elementId:p});let h=r(a(m,{componentSrc:u,elementId:p,hasIsland:!!l})),g=o.fallback?e(o.fallback):``,_=o.timeout??1e4,v=s({elementId:p,endpointPath:`/_server-islands/${t}`,timeout:_,islandProp:l});return`${`<avalon-server-island id="${p}" data-p="${c(h)}">`}${g}</avalon-server-island>\n${v}`}function s(e){let{elementId:t,endpointPath:n,timeout:r,islandProp:i}=e,a=i?`el.querySelectorAll('script[type="module"]').forEach(s=>{const n=document.createElement("script");n.type="module";n.textContent=s.textContent;s.replaceWith(n);});`:``;return`<script type="module">
1
+ import e from"preact-render-to-string";import{encrypt as t}from"./encryption.js";function n(){try{if(import.meta.env?.DEV===!0)return!0;if(import.meta.env?.PROD===!0)return!1}catch{}return!1}function r(e){return n()?`dev.${Buffer.from(e,`utf8`).toString(`base64url`)}`:t(e)}let i=0;function a(e,t){try{return JSON.stringify(e)}catch(e){let n=e instanceof Error?e.message:String(e);throw Error(`Failed to serialize server island props (elementId=${t.elementId}, componentSrc=${t.componentSrc??`unknown`}, combinedIsland=${t.hasIsland}). Props must be JSON-serializable (no functions, circular refs, or BigInt): ${n}`)}}export function renderServerIsland(t,n,o,l,u,d,f){let p=`si-${t}-${i++}`,m={...n};d&&(m.__src=d),l&&(m.__island={condition:l.condition??`on:client`,conditionArg:l.conditionArg,framework:f??`preact`,componentSrc:u,elementId:p});let h=r(a(m,{componentSrc:u,elementId:p,hasIsland:!!l})),g=o.fallback?e(o.fallback):``,_=o.timeout??1e4,v=s({elementId:p,endpointPath:`/_server-islands/${t}`,timeout:_,islandProp:l});return`${`<avalon-server-island id="${p}" data-p="${c(h)}">`}${g}</avalon-server-island>\n${v}`}function s(e){let{elementId:t,endpointPath:n,timeout:r,islandProp:i}=e,a=i?`el.querySelectorAll('script[type="module"]').forEach(s=>{const n=document.createElement("script");n.type="module";n.textContent=s.textContent;s.replaceWith(n);});`:``;return`<script type="module">
2
2
  (async()=>{
3
3
  const el=document.getElementById("${t}");
4
4
  if(!el)return;
@@ -9,8 +9,10 @@
9
9
  * - GET: encrypted props in the `p` query parameter
10
10
  * - POST: encrypted props in the request body
11
11
  *
12
+ * Framework SSR integrations are registered via the import in `endpoint.ts`
13
+ * (`virtual:server-island-integrations`).
14
+ *
12
15
  * @module server-islands/route
13
16
  */
14
- import "virtual:server-island-integrations";
15
17
  declare const handler: (event: import("h3").H3Event) => Promise<Response>;
16
18
  export default handler;
@@ -1 +1 @@
1
- import"virtual:server-island-integrations";import{defineServerIslandHandler as e}from"./endpoint.js";const t=e();export default t;
1
+ import{defineServerIslandHandler as e}from"./endpoint.js";const t=e();export default t;
@@ -42,6 +42,10 @@ declare module "virtual:avalon/assets" {
42
42
  };
43
43
  }
44
44
 
45
+ declare module "virtual:avalon/ssr-dom" {
46
+ // Side-effect module: installs a `document` stub before Lit SSR loads.
47
+ }
48
+
45
49
  declare module "virtual:avalon/renderer" {
46
50
  const handler: {
47
51
  (event: unknown): Promise<Response>;
@@ -76,8 +80,8 @@ declare module "virtual:server-island-key" {
76
80
  }
77
81
 
78
82
  declare module "virtual:server-island-integrations" {
79
- // Side-effect module that registers framework integrations in the global registry.
80
- // No exports — import for side effects only.
83
+ /** Registers framework SSR integrations into the global registry (idempotent). */
84
+ export function ensureServerIslandIntegrations(): void;
81
85
  }
82
86
 
83
87
  declare module "virtual:avalon-actions-manifest" {
@@ -2,6 +2,10 @@
2
2
 
3
3
  interface ImportMetaEnv {
4
4
  readonly VITE_APP_TITLE: string;
5
+ readonly DEV: boolean;
6
+ readonly PROD: boolean;
7
+ readonly MODE: string;
8
+ readonly SSR: boolean;
5
9
  // more env variables...
6
10
  }
7
11
 
@@ -22,6 +22,7 @@ export declare const VIRTUAL_MODULE_IDS: {
22
22
  readonly DEV_CSS_HMR: "virtual:avalon/dev-css-hmr";
23
23
  readonly INTEGRATION_LOADER: "virtual:avalon/integration-loader";
24
24
  readonly ACTIONS: "virtual:avalon/actions";
25
+ readonly SSR_DOM: "virtual:avalon/ssr-dom";
25
26
  };
26
27
  export declare const RESOLVED_VIRTUAL_IDS: {
27
28
  readonly PAGE_ROUTES: "\0virtual:avalon/page-routes";
@@ -36,6 +37,7 @@ export declare const RESOLVED_VIRTUAL_IDS: {
36
37
  readonly DEV_CSS_HMR: "\0virtual:avalon/dev-css-hmr";
37
38
  readonly INTEGRATION_LOADER: "\0virtual:avalon/integration-loader";
38
39
  readonly ACTIONS: "\0virtual:avalon/actions";
40
+ readonly SSR_DOM: "\0virtual:avalon/ssr-dom";
39
41
  };
40
42
  export interface NitroIntegrationResult {
41
43
  nitroOptions: NitroConfigOutput;
@@ -1,31 +1,31 @@
1
- import{existsSync as e,readdirSync as t,readFileSync as n,rmSync as r}from"node:fs";import{stat as i}from"node:fs/promises";import{createRequire as a}from"node:module";import{dirname as o,join as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{generateActionTypes as u}from"../build/actions-types-generator.js";import{createCronDevSchedulerPlugin as d}from"../cron/dev-scheduler.js";import{getUniversalCSSForHead as f}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as p,injectSolidHydrationScriptIfNeeded as m}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as h,discoverScopedMiddleware as g,executeScopedMiddleware as _}from"../middleware/index.js";import{createNitroConfig as v}from"../nitro/config.js";import{createIslandManifestPlugin as y,createNitroBuildPlugin as b,createSourceMapConfig as x,createSourceMapPlugin as S}from"../nitro/index.js";import{collectCssFromModuleGraph as C,injectSsrCss as w}from"../render/collect-css.js";import{generateErrorPage as T,generateFallback404 as E}from"../render/error-pages.js";import{generateComponentId as D}from"../server-islands/manifest.js";import{buildDevCssRouteTable as O}from"./dev-css-graph.js";import{createDevCssHmrPlugin as ee,generateDevCssHmrModule as te}from"./dev-css-hmr.js";import{resolveToRelativePath as ne}from"./server-islands-plugin.js";function re(e){let t=ce(e),r=Object.entries(t),i=`export const serverIslandManifest = ${JSON.stringify(t)};\n\n`;i+=`export const serverIslandLoaders = {
1
+ import{existsSync as e,readdirSync as t,readFileSync as n,rmSync as r}from"node:fs";import{stat as i}from"node:fs/promises";import{createRequire as a}from"node:module";import{dirname as o,join as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{generateActionTypes as u}from"../build/actions-types-generator.js";import{createCronDevSchedulerPlugin as d}from"../cron/dev-scheduler.js";import{getUniversalCSSForHead as f}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as p,injectSolidHydrationScriptIfNeeded as m}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as h,discoverScopedMiddleware as g,executeScopedMiddleware as _}from"../middleware/index.js";import{createNitroConfig as v}from"../nitro/config.js";import{createIslandManifestPlugin as y,createNitroBuildPlugin as b,createSourceMapConfig as x,createSourceMapPlugin as S}from"../nitro/index.js";import{collectCssFromModuleGraph as C,injectSsrCss as w}from"../render/collect-css.js";import{generateErrorPage as T,generateFallback404 as ee}from"../render/error-pages.js";import{generateComponentId as E}from"../server-islands/manifest.js";import{buildDevCssRouteTable as D}from"./dev-css-graph.js";import{createDevCssHmrPlugin as te,generateDevCssHmrModule as ne}from"./dev-css-hmr.js";import{resolveToRelativePath as re}from"./server-islands-plugin.js";import{SSR_DOM_VIRTUAL_ID as O,ssrDomShimModuleSource as k}from"./ssr-dom-shim-module.js";function ie(e){let t=le(e),r=Object.entries(t),i=`export const serverIslandManifest = ${JSON.stringify(t)};\n\n`;i+=`export const serverIslandLoaders = {
2
2
  `;for(let[e,t]of r)i+=` ${JSON.stringify(e)}: () => import(${JSON.stringify(t)}),\n`;i+=`};
3
3
 
4
- `;let a={};for(let[t,i]of r)if(i.endsWith(`.svelte`))try{let r=n(s(e,i.startsWith(`/`)?i.slice(1):i),`utf8`).match(/<style[^>]*>([\s\S]*?)<\/style>/);r&&(a[t]=r[1].trim())}catch{}return i+=`export const serverIslandCSS = ${JSON.stringify(a)};\n`,i}function k(e,t){return new Promise((n,r)=>{let i=[],a=e=>i.push(e),o=()=>{l(),n(Buffer.concat(i).toString(`utf8`))},s=e=>{l(),r(e)},c=setTimeout(()=>{l(),r(Error(t))},15e3);function l(){clearTimeout(c),e.off(`data`,a),e.off(`end`,o),e.off(`error`,s)}e.on(`data`,a),e.on(`end`,o),e.on(`error`,s)})}const A=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,ie=new Set([`node_modules`,`dist`,`.output`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`,`.git`]);function ae(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}function oe(e,t){return!(!/\.(tsx|jsx)$/.test(e)||/\.(test|spec)\.[jt]sx$/.test(e)||t.includes(`__tests__`))}function j(e,n){let r;try{r=t(e,{withFileTypes:!0})}catch{return}for(let t of r){let r=s(e,t.name);t.isDirectory()?ie.has(t.name)||j(r,n):t.isFile()&&oe(t.name,r)&&n.push(r)}}function se(e,t,n,r){A.lastIndex=0;let i=A.exec(t);for(;i!==null;i=A.exec(t)){let a=i[1],o=i[2].slice(1,-1);if(!ae(t,a))continue;let s=ne(o,e,n),c=D(s);c in r||(r[c]=s)}}function ce(t){let r={},i=[];for(let n of[`app`,`src`]){let r=s(t,n);e(r)&&j(r,i)}for(let e of i){let i;try{i=n(e,`utf8`)}catch{continue}/\bserver\s*[={/>]/.test(i)&&se(e,i,t,r)}return r}function M(t){let n=[`ts`,`tsx`,`js`,`jsx`,`mts`,`mjs`];for(let r of[`app`,`src`])for(let i of n){let n=`/${r}/actions/index.${i}`;if(e(s(t,n.slice(1))))return n}}function le(e){let t=M(e);return t?`export { server } from ${JSON.stringify(t)};\n`:`export const server = {};
5
- `}function ue(){return[`import { createActionClient } from "@useavalon/avalon/actions";`,`export const actions = createActionClient();`,`export default actions;`,``].join(`
6
- `)}function de(e,t){try{let n;if(e.startsWith(`dev.`)){let t=e.slice(4);n=Buffer.from(t,`base64url`).toString(`utf8`)}else n=t(e);let r=JSON.parse(n),i,a;return r.__island&&(i=r.__island,delete r.__island),r.__src&&(a=r.__src,delete r.__src),{ok:!0,props:r,srcPath:a,islandMeta:i}}catch{return{ok:!1}}}function fe(e,t,n,r){let i=e.split(`/`)[2]?.split(`?`)[0]||``,a=t.elementId??`si-${i}`,o=t.componentSrc??n,s=JSON.stringify(r),c=t.condition??`on:client`,l=t.framework??`preact`;return`<script type="module">
7
- import{hydrateServerIsland}from"/@fs${N(`src/client/server-island-hydrate.ts`)}";
4
+ `;let a={};for(let[t,i]of r)if(i.endsWith(`.svelte`))try{let r=n(s(e,i.startsWith(`/`)?i.slice(1):i),`utf8`).match(/<style[^>]*>([\s\S]*?)<\/style>/);r&&(a[t]=r[1].trim())}catch{}return i+=`export const serverIslandCSS = ${JSON.stringify(a)};\n`,i}function A(e,t){return new Promise((n,r)=>{let i=[],a=e=>i.push(e),o=()=>{l(),n(Buffer.concat(i).toString(`utf8`))},s=e=>{l(),r(e)},c=setTimeout(()=>{l(),r(Error(t))},15e3);function l(){clearTimeout(c),e.off(`data`,a),e.off(`end`,o),e.off(`error`,s)}e.on(`data`,a),e.on(`end`,o),e.on(`error`,s)})}const j=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,ae=new Set([`node_modules`,`dist`,`.output`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`,`.git`]);function oe(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}function se(e,t){return!(!/\.(tsx|jsx)$/.test(e)||/\.(test|spec)\.[jt]sx$/.test(e)||t.includes(`__tests__`))}function M(e,n){let r;try{r=t(e,{withFileTypes:!0})}catch{return}for(let t of r){let r=s(e,t.name);t.isDirectory()?ae.has(t.name)||M(r,n):t.isFile()&&se(t.name,r)&&n.push(r)}}function ce(e,t,n,r){j.lastIndex=0;let i=j.exec(t);for(;i!==null;i=j.exec(t)){let a=i[1],o=i[2].slice(1,-1);if(!oe(t,a))continue;let s=re(o,e,n),c=E(s);c in r||(r[c]=s)}}function le(t){let r={},i=[];for(let n of[`app`,`src`]){let r=s(t,n);e(r)&&M(r,i)}for(let e of i){let i;try{i=n(e,`utf8`)}catch{continue}/\bserver\s*[={/>]/.test(i)&&ce(e,i,t,r)}return r}function N(t){let n=[`ts`,`tsx`,`js`,`jsx`,`mts`,`mjs`];for(let r of[`app`,`src`])for(let i of n){let n=`/${r}/actions/index.${i}`;if(e(s(t,n.slice(1))))return n}}function ue(e){let t=N(e);return t?`export { server } from ${JSON.stringify(t)};\n`:`export const server = {};
5
+ `}function de(){return[`import { createActionClient } from "@useavalon/avalon/actions";`,`export const actions = createActionClient();`,`export default actions;`,``].join(`
6
+ `)}function fe(e,t){try{let n;if(e.startsWith(`dev.`)){let t=e.slice(4);n=Buffer.from(t,`base64url`).toString(`utf8`)}else n=t(e);let r=JSON.parse(n),i,a;return r.__island&&(i=r.__island,delete r.__island),r.__src&&(a=r.__src,delete r.__src),{ok:!0,props:r,srcPath:a,islandMeta:i}}catch{return{ok:!1}}}function pe(e,t,n,r){let i=e.split(`/`)[2]?.split(`?`)[0]||``,a=t.elementId??`si-${i}`,o=t.componentSrc??n,s=JSON.stringify(r),c=t.condition??`on:client`,l=t.framework??`preact`;return`<script type="module">
7
+ import{hydrateServerIsland}from"/@fs${P(`src/client/server-island-hydrate.ts`)}";
8
8
  hydrateServerIsland(${JSON.stringify(a)},${JSON.stringify(o)},${s},${JSON.stringify(c)},${JSON.stringify(l)});
9
- <\/script>`}function N(t){let n=s(o(a(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function pe(t,n){let r=s(o(a(s(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,DEV_CSS_HMR:`virtual:avalon/dev-css-hmr`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`,ACTIONS:`virtual:avalon/actions`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,DEV_CSS_HMR:`\0${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`,ACTIONS:`\0${VIRTUAL_MODULE_IDS.ACTIONS}`};function me(e){return e===`react`?[]:[/^react/,/^react-dom/]}function he(e){return e===`react`?[`import { createElement as h } from 'react';`,`import { renderToString as preactRenderToString } from 'react-dom/server';`]:[`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`]}function ge(e){return e===`react`?[`import { setShellRenderToString, setShellElementFactory } from '@useavalon/avalon/render/shell-engine';`,`import { renderToString as __reactRenderToString } from 'react-dom/server';`,`import { createElement as __reactCreateElement, Fragment as __reactFragment } from 'react';`,`setShellRenderToString((vnode) => __reactRenderToString(vnode));`,`setShellElementFactory(__reactCreateElement, __reactFragment);`]:[]}function _e(e){return e===`react`?`@useavalon/react/client`:`@useavalon/preact/client`}function ve(e){let t=N(`src/core/integrations/registry.ts`),n=[`solid`,`vue`,`svelte`,`lit`].filter(t=>e.includes(t));return`${[`import { registry } from "${t}";`,...n.map(e=>`import { ${e}Integration } from "@useavalon/${e}";`),...n.map(e=>`if (${e}Integration) registry.register(${e}Integration);`)].join(`
10
- `)}\n`}function ye(e,t,n,r,i,a){let o={preset:e.preset,serverDir:t.serverDir??e.serverDir??`./server`,routeRules:e.routeRules,runtimeConfig:e.runtimeConfig,compatibilityDate:e.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...me(r.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>re(n),"virtual:avalon-actions-manifest":()=>le(n),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>ve(r.integrations)},traceDeps:[...new Set([`undici`,...e.traceDeps??[]])]};return Ce(o,e,t),o}function be(e,t,n){if(n.renderer===!1){e.renderer=!1;return}t.renderer&&(e.renderer=t.renderer)}function xe(){return process.argv.includes(`build`)||process.env.NODE_ENV===`production`}function Se(e,t){t.experimentalTasks&&xe()&&(e.experimental={...e.experimental,tasks:!0},t.tasks&&Object.keys(t.tasks).length>0&&(e.tasks=t.tasks),t.scheduledTasks&&Object.keys(t.scheduledTasks).length>0&&(e.scheduledTasks=t.scheduledTasks))}function Ce(e,t,n){be(e,t,n),t.publicRuntimeConfig&&(e.publicRuntimeConfig=t.publicRuntimeConfig),t.publicAssets&&(e.publicAssets=t.publicAssets),t.compressPublicAssets&&(e.compressPublicAssets=t.compressPublicAssets),t.serverEntry&&(e.serverEntry=t.serverEntry),Se(e,t),t.prerender&&(e.prerender={routes:[],crawlLinks:!1})}export function createNitroIntegration(e,t={}){let n=v(t,e),r=c(ye(n,t,process.cwd(),e,N(`src/server-islands/route.ts`),N(`src/actions/route.ts`))),i=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),a=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),o=b(e,t),s=y(e,{verbose:e.verbose,generatePreloadHints:!0}),l=S(x(t.preset??`node_server`,e.isDev)),u=d(t.cron,e.verbose);return{nitroOptions:n,plugins:[ee(),...Array.isArray(r)?r:[r],i,a,o,s,l,u]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{u(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{u(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let d=!1,f=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||d?(d=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{d=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(d)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await f,n()});let p=null;async function m(){return p||=await g({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}Oe(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let _=e.environments?.ssr,v=!!_&&l(_);v&&Ee(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!v)return i();try{let{decrypt:i}=await e.ssrLoadModule(N(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await H(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await k(n,`Timed out reading server island request body`)),!c){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Missing encrypted props`);return}let l=de(c,i);if(!l.ok){r.statusCode=400,r.setHeader(`Content-Type`,`text/plain`),r.end(`Bad Request: decryption failed`);return}let{props:u,srcPath:d,islandMeta:f}=l;if(!d){r.statusCode=404,r.setHeader(`Content-Type`,`text/plain`),r.end(`Component not found (no __src in payload)`);return}let p=(await e.ssrLoadModule(d)).default;if(typeof p!=`function`){r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Module "${d}" does not export a default component function`);return}let m=s(o(p,u));f&&(m+=fe(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!v)return r();try{let r=M(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(N(`src/actions/endpoint.ts`)),e.ssrLoadModule(N(`src/actions/registry.ts`)),r?e.ssrLoadModule(r):Promise.resolve({server:{}})]),c=o.flattenActions(s.server),l=a.defineActionHandler({registry:c,isDev:!0}),u=new URL(i,`http://${t.headers.host||`localhost`}`),d=(t.method||`GET`).toUpperCase(),f;d===`POST`&&(f=await k(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!v)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await we(e,o,r,i,m,n)||await Ke(e,o,t,i))return;let a=await qe(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await Te(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(T(e))}})},buildStart(){}}}async function we(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await _({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function Te(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(E(t))}}async function Ee(e,t,n){let r=performance.now(),i=[{path:N(`src/render/ssr.ts`),assignTo:`ssr`},{path:N(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:N(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:pe(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(B=r),n===`layout`&&(V=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e,i=null;return{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.DEV_CSS_HMR?RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await ke(t,r):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await Ae(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?je():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?Me(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(i||=await Ne(t,n),i):e===RESOLVED_VIRTUAL_IDS.ASSETS?Pe(n):e===RESOLVED_VIRTUAL_IDS.RENDERER?Fe(t):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await Re(t,n):e===RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR?te():e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(t):e===RESOLVED_VIRTUAL_IDS.ACTIONS?ue():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:a,isCss:o}=R(e);o&&(i=null),n&&(F(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),F(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),I(t)),(n||r||a)&&(i=null,F(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),a&&P(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),De(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 De(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function Oe(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(h(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(B=null,V=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&L(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&L(e)})}export function isPageFile(e){return R(e).isPage}async function ke(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
9
+ <\/script>`}function P(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 me(t,n){let r=s(o(a(s(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,DEV_CSS_HMR:`virtual:avalon/dev-css-hmr`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`,ACTIONS:`virtual:avalon/actions`,SSR_DOM:O};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,DEV_CSS_HMR:`\0${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`,ACTIONS:`\0${VIRTUAL_MODULE_IDS.ACTIONS}`,SSR_DOM:`\0${VIRTUAL_MODULE_IDS.SSR_DOM}`};function he(e){return e===`react`?[]:[/^react/,/^react-dom/]}function ge(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 _e(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 ve(e){return e===`react`?`@useavalon/react/client`:`@useavalon/preact/client`}function ye(e){let t=P(`src/core/integrations/registry.ts`),n=[`solid`,`vue`,`svelte`,`lit`].filter(t=>e.includes(t));return`${[...n.includes(`lit`)?[`import "${O}";`]:[],`import { registry } from "${t}";`,...n.map(e=>`import { ${e}Integration } from "@useavalon/${e}";`),`let registered = false;`,`export function ensureServerIslandIntegrations() {`,` if (registered) return;`,` registered = true;`,...n.map(e=>` if (${e}Integration) registry.register(${e}Integration);`),`}`].join(`
10
+ `)}\n`}function be(e,t,n,r,i,a){let o={preset:e.preset,serverDir:t.serverDir??e.serverDir??`./server`,routeRules:e.routeRules,runtimeConfig:e.runtimeConfig,compatibilityDate:e.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/,/^preact/,...he(r.core),/^vue/,/^@vue\//],handlers:[{route:`/_server-islands/**`,handler:i},{route:`/_actions/**`,handler:a}],virtual:{"virtual:server-island-manifest":()=>ie(n),"virtual:avalon-actions-manifest":()=>ue(n),"virtual:server-island-key":()=>{let e=process.env.AVALON_KEY??``;return`export const serverIslandKey = ${JSON.stringify(e)};\n`},"virtual:server-island-integrations":()=>ye(r.integrations),[O]:()=>k()},traceDeps:[...new Set([`undici`,...e.traceDeps??[]])]};return we(o,e,t),o}function xe(e,t,n){if(n.renderer===!1){e.renderer=!1;return}t.renderer&&(e.renderer=t.renderer)}function Se(){return process.argv.includes(`build`)||process.env.NODE_ENV===`production`}function Ce(e,t){t.experimentalTasks&&Se()&&(e.experimental={...e.experimental,tasks:!0},t.tasks&&Object.keys(t.tasks).length>0&&(e.tasks=t.tasks),t.scheduledTasks&&Object.keys(t.scheduledTasks).length>0&&(e.scheduledTasks=t.scheduledTasks))}function we(e,t,n){xe(e,t,n),t.publicRuntimeConfig&&(e.publicRuntimeConfig=t.publicRuntimeConfig),t.publicAssets&&(e.publicAssets=t.publicAssets),t.compressPublicAssets&&(e.compressPublicAssets=t.compressPublicAssets),t.serverEntry&&(e.serverEntry=t.serverEntry),Ce(e,t),t.prerender&&(e.prerender={routes:[],crawlLinks:!1})}export function createNitroIntegration(e,t={}){let n=v(t,e),r=c(be(n,t,process.cwd(),e,P(`src/server-islands/route.ts`),P(`src/actions/route.ts`))),i=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),a=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),o=b(e,t),s=y(e,{verbose:e.verbose,generatePreloadHints:!0}),l=S(x(t.preset??`node_server`,e.isDev)),u=d(t.cron,e.verbose);return{nitroOptions:n,plugins:[te(),...Array.isArray(r)?r:[r],i,a,o,s,l,u]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`;try{u(e.root||process.cwd())}catch{}},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e=>{if(e.includes(`/actions/`))try{u(i)}catch{}};e.watcher.on(`add`,a),e.watcher.on(`unlink`,a);let o=e.config.root||process.cwd(),c=e.config.build?.outDir?s(o,e.config.build.outDir):s(o,`dist`);try{r(c,{recursive:!0,force:!0})}catch{}try{r(s(o,`.output`),{recursive:!0,force:!0})}catch{}let d=!1,f=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||d?(d=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{d=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(d)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await f,n()});let p=null;async function m(){return p||=await g({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),p}function h(){p=null}ke(e,t,n,h),m().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let _=e.environments?.ssr,v=!!_&&l(_);v&&De(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,r,i)=>{let a=n.url||`/`;if(!a.startsWith(`/_server-islands/`)||!v)return i();try{let{decrypt:i}=await e.ssrLoadModule(P(`src/server-islands/encryption.ts`)),{h:o,renderToString:s}=await U(e,t.core),c=new URL(a,`http://${n.headers.host||`localhost`}`).searchParams.get(`p`)||``;if(!c&&n.method===`POST`&&(c=await A(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=fe(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+=pe(a,f,d,u)),r.statusCode=200,r.setHeader(`Content-Type`,`text/html`),r.setHeader(`Cache-Control`,`private, no-store`),r.end(m)}catch(e){console.error(`[server-islands] Dev handler error:`,e),r.statusCode=500,r.setHeader(`Content-Type`,`text/plain`),r.end(`Server island render failed: ${e instanceof Error?e.message:String(e)}`)}}),e.middlewares.use(async(t,n,r)=>{let i=t.url||`/`;if(!i.startsWith(`/_actions/`)||!v)return r();try{let r=N(e.config.root||process.cwd()),[a,o,s]=await Promise.all([e.ssrLoadModule(P(`src/actions/endpoint.ts`)),e.ssrLoadModule(P(`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 A(t,`Timed out reading action request body`));let p=await l({url:u,web:{request:new Request(u,{method:d,headers:t.headers,body:f})},context:{}});n.statusCode=p.status,p.headers.forEach((e,t)=>{n.setHeader(t,e)}),n.end(await p.text())}catch(e){console.error(`[actions] Dev handler error:`,e),n.statusCode=500,n.setHeader(`Content-Type`,`application/json`),n.end(JSON.stringify({error:{code:`INTERNAL_SERVER_ERROR`,message:e instanceof Error?e.message:String(e)}}))}}),e.middlewares.use(async(r,i,a)=>{if(!v)return a();let o=r.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await Te(e,o,r,i,m,n)||await qe(e,o,t,i))return;let a=await Je(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await Ee(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(T(e))}})},buildStart(){}}}async function Te(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await _({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function Ee(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(ee(t))}}async function De(e,t,n){let r=performance.now(),i=[{path:P(`src/render/ssr.ts`),assignTo:`ssr`},{path:P(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:P(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:me(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`&&(V=r),n===`layout`&&(H=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e,i=null;return{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.DEV_CSS_HMR?RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:e===VIRTUAL_MODULE_IDS.ACTIONS?RESOLVED_VIRTUAL_IDS.ACTIONS:e===VIRTUAL_MODULE_IDS.SSR_DOM?RESOLVED_VIRTUAL_IDS.SSR_DOM:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await Ae(t,r):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await je(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?Me():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?Ne(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(i||=await Pe(t,n),i):e===RESOLVED_VIRTUAL_IDS.ASSETS?Fe(n):e===RESOLVED_VIRTUAL_IDS.RENDERER?Ie(t):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await ze(t,n):e===RESOLVED_VIRTUAL_IDS.DEV_CSS_HMR?ne():e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(t):e===RESOLVED_VIRTUAL_IDS.ACTIONS?de():e===RESOLVED_VIRTUAL_IDS.SSR_DOM?k():null},handleHotUpdate({file:e,server:t}){let{isPage:n,isComponent:r,isLayout:a,isCss:o}=z(e);o&&(i=null),n&&(I(t,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),I(t,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),L(t)),(n||r||a)&&(i=null,I(t,RESOLVED_VIRTUAL_IDS.LAYOUTS),a&&F(t,RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY),setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)),Oe(e)&&F(t,RESOLVED_VIRTUAL_IDS.CONFIG)}}}function F(e,t){let n=e.moduleGraph.getModuleById(t);n&&e.moduleGraph.invalidateModule(n)}function I(e,t){F(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 L(e){let t=e.environments?.nitro;if(t)try{t.devServer?.sendMessage?.({type:`full-reload`}),await t.devServer?.reloadRoutes?.()}catch{}}function R(e){I(e,RESOLVED_VIRTUAL_IDS.PAGE_ROUTES),I(e,RESOLVED_VIRTUAL_IDS.PAGE_LOADER),L(e),setTimeout(()=>{e.ws.send({type:`full-reload`,path:`*`})},500)}function z(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 Oe(e){return e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)}function ke(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(h(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(V=null,H=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&R(e)}),e.watcher.on(`unlink`,t=>{t.includes(`_middleware`)&&(h(),r?.()),isPageFile(t)&&R(e)})}export function isPageFile(e){return z(e).isPage}async function Ae(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
11
11
  export default pageRoutes;
12
- `}}async function Ae(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
12
+ `}}async function je(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
13
13
  `),`];`,``,`/**`,` * Match a pathname against discovered routes and return the page module.`,` * Uses the same pattern matching as Avalon's route discovery.`,` */`,`/**`,` * Match a pathname against discovered routes, returning the matched`,` * page module AND the extracted dynamic route params (e.g. { id: "123" }).`,` */`,`export function loadPage(pathname) {`,` const cleanPath = pathname.split('?')[0];`,` for (const route of routes) {`,` const m = matchRoute(cleanPath, route.pattern);`,` if (m.matched) return { module: route.module, params: m.params };`,` }`,` return null;`,`}`,``,`/**`,` * Match one pattern and capture dynamic segments:`,` * /users/:id vs /users/123 -> { id: "123" }`,` * /blog/** vs /blog/a/b -> { slug: "a/b" }`,` */`,`function matchRoute(pathname, pattern) {`,String.raw` const normPath = pathname === '/' ? '/' : pathname.replace(/\/$/, '');`,String.raw` const normPattern = pattern === '/' ? '/' : pattern.replace(/\/$/, '');`,` if (normPath === normPattern) return { matched: true, params: {} };`,` const patternParts = normPattern.split('/');`,` const pathParts = normPath.split('/');`,` const params = {};`,` for (let i = 0; i < patternParts.length; i++) {`,` const seg = patternParts[i];`,` if (seg === '**') {`,` params.slug = pathParts.slice(i).join('/');`,` return { matched: true, params };`,` }`,` if (i >= pathParts.length) return { matched: false, params: {} };`,` if (seg.startsWith(':')) params[seg.slice(1)] = pathParts[i];`,` else if (seg !== pathParts[i]) return { matched: false, params: {} };`,` }`,` if (pathParts.length > patternParts.length) return { matched: false, params: {} };`,` return { matched: true, params };`,`}`,``,`export default { loadPage, routes };`,``].join(`
14
14
  `)}catch(e){return console.error(`[page-loader] Failed to generate page loader:`,e),`export function loadPage() { return null; }
15
15
  export default { loadPage, routes: [] };
16
- `}}function je(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
16
+ `}}function Me(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
17
17
  export default islandManifest;
18
- `}function Me(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`globalThis.__avalonHydrationMode = "${n?`entry-client`:`per-island`}";\nconst config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function Ne(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{relative:r,resolve:i}=await import(`node:path`),{stat:a,readFile:o}=await import(`node:fs/promises`),c=process.cwd(),l=await n(e.layoutsDir,e.modules,c),u=[],d=0,f=i(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let i=s(t,`_layout.tsx`);try{if(!(await a(i)).isFile())continue}catch{continue}let o=r(c,i).replaceAll(`\\`,`/`),l=o.startsWith(`/`)?o:`/${o}`,p=t.startsWith(f),m=p&&!e.modules?`RootLayout`:`Layout_${d}`;u.push({prefix:n,importPath:l,varName:m,isShared:p,filePath:i}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=new Map;for(let e of m)try{let t=(await o(e.filePath,`utf8`)).match(/layoutConfig\s*=\s*{[\s\S]*?skipLayouts\s*:\s*\[([^\]]*)\]/)?.[1]??``,n=/['"`]_layout['"`]/.test(t);h.set(e.importPath,n)}catch{h.set(e.importPath,!1)}let g=u.map(e=>`import ${e.varName} from '${e.importPath}';`),_=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`,n=h.get(e.importPath)??!1,r=t||n;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${r} }`}),v=p.length>0?p[0].varName:`null`,y=`{"routes":[],"fallbackHrefs":[],"globalHrefs":[]}`;if(e.isDev){let{getAllPageDirs:n}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:r}=await import(`../nitro/route-discovery.js`),i=await r(await n(e.pagesDir,e.modules,c),{developmentMode:e.isDev}),a=O({cwd:c,globalCSS:t.globalCSS??[],routes:i.map(e=>({pattern:e.pattern,filePath:e.filePath})),layouts:u.map(e=>({prefix:e.prefix,filePath:e.filePath,isRoot:e.isShared,skipRoot:h.get(e.importPath)??!1}))});y=JSON.stringify(a)}return[`// Auto-generated by Avalon — do not edit`,...he(e.core),`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,`import { appendDevCssLinks, layoutPrefixMatches, selectDevCssHrefs } from '@useavalon/avalon/render/dev-css-select';`,...g,``,`const RootLayoutComponent = ${v};`,`const _cssTable = ${y};`,``,`const moduleLayouts = [`,_.join(`,
18
+ `}function Ne(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`globalThis.__avalonHydrationMode = "${n?`entry-client`:`per-island`}";\nconst config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function Pe(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{relative:r,resolve:i}=await import(`node:path`),{stat:a,readFile:o}=await import(`node:fs/promises`),c=process.cwd(),l=await n(e.layoutsDir,e.modules,c),u=[],d=0,f=i(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let i=s(t,`_layout.tsx`);try{if(!(await a(i)).isFile())continue}catch{continue}let o=r(c,i).replaceAll(`\\`,`/`),l=o.startsWith(`/`)?o:`/${o}`,p=t.startsWith(f),m=p&&!e.modules?`RootLayout`:`Layout_${d}`;u.push({prefix:n,importPath:l,varName:m,isShared:p,filePath:i}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=new Map;for(let e of m)try{let t=(await o(e.filePath,`utf8`)).match(/layoutConfig\s*=\s*{[\s\S]*?skipLayouts\s*:\s*\[([^\]]*)\]/)?.[1]??``,n=/['"`]_layout['"`]/.test(t);h.set(e.importPath,n)}catch{h.set(e.importPath,!1)}let g=u.map(e=>`import ${e.varName} from '${e.importPath}';`),_=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`,n=h.get(e.importPath)??!1,r=t||n;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${r} }`}),v=p.length>0?p[0].varName:`null`,y=`{"routes":[],"fallbackHrefs":[],"globalHrefs":[]}`;if(e.isDev){let{getAllPageDirs:n}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:r}=await import(`../nitro/route-discovery.js`),i=await r(await n(e.pagesDir,e.modules,c),{developmentMode:e.isDev}),a=D({cwd:c,globalCSS:t.globalCSS??[],routes:i.map(e=>({pattern:e.pattern,filePath:e.filePath})),layouts:u.map(e=>({prefix:e.prefix,filePath:e.filePath,isRoot:e.isShared,skipRoot:h.get(e.importPath)??!1}))});y=JSON.stringify(a)}return[`// Auto-generated by Avalon — do not edit`,...ge(e.core),`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,`import { appendDevCssLinks, layoutPrefixMatches, selectDevCssHrefs } from '@useavalon/avalon/render/dev-css-select';`,...g,``,`const RootLayoutComponent = ${v};`,`const _cssTable = ${y};`,``,`const moduleLayouts = [`,_.join(`,
19
19
  `),`];`,``,`function getLayoutsForPath(pathname) {`,` return moduleLayouts.find((entry) => layoutPrefixMatches(pathname, entry.prefix)) ?? null;`,`}`,``,`function injectUniversalAssets(html, pathname, skipLayouts) {`,` if (process.env.NODE_ENV !== 'production') {`,` var hrefs = selectDevCssHrefs(_cssTable, pathname, skipLayouts);`,` html = appendDevCssLinks(html, hrefs);`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalCSS + '\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,String.raw` html = html.replace('</head>', universalHead + '\n</head>');`,` }`,` html = injectSolidHydrationScriptIfNeeded(html);`,` return html;`,`}`,``,`export async function wrapWithLayouts(pageHtml, pageModule, context, injectAssets) {`,` const pathname = context.url.pathname;`,` const frontmatter = {`,` ...(pageModule.frontmatter || {}),`,` ...(pageModule.metadata || {}),`,` currentPath: pathname,`,` };`,` const pageLayoutConfig = pageModule.layoutConfig;`,` const skipAll = pageLayoutConfig?.skipLayouts?.includes('_layout');`,``,` const layoutEntry = getLayoutsForPath(pathname);`,` const routeInfo = { path: pathname, params: context.params, query: context.url.searchParams };`,` let html;`,``,` if (!layoutEntry || skipAll) {`,` if (RootLayoutComponent && !skipAll) {`,` const rootProps = {`,` children: h('avalon-page', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,String.raw` html = '<!DOCTYPE html>\n' + preactRenderToString(resolvedRoot);`,` } else {`,` // skipAll is true — page provides its own HTML shell or needs a minimal one`,` if (pageHtml.trimStart().startsWith('<html')) {`,String.raw` html = '<!DOCTYPE html>\n' + pageHtml;`,` } else {`,` const title = String(frontmatter.title || 'Avalon');`,` html = [`,` '<!DOCTYPE html>',`,` '<html lang="en">',`,` '<head>',`,` '<meta charset="utf-8">',`,` '<meta name="viewport" content="width=device-width, initial-scale=1">',`,` '<title>' + title + '</title>',`,` '</head>',`,` '<body>',`,` '<div id="app">' + pageHtml + '</div>',`,` '</body>',`,` '</html>',`,String.raw` ].join('\n');`,` }`,` }`,` } else {`,` const layoutProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const layoutResult = layoutEntry.Layout(layoutProps);`,` const resolvedLayout = layoutResult instanceof Promise ? await layoutResult : layoutResult;`,` let wrappedHtml = preactRenderToString(resolvedLayout);`,``,` // If the layout provides its own HTML shell (starts with <html),`,` // skip root wrapping regardless of skipRoot flag — the layout IS the document.`,` const layoutProvidesShell = wrappedHtml.trimStart().startsWith('<html');`,``,` if (!layoutProvidesShell && !layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: wrappedHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,String.raw` html = '<!DOCTYPE html>\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html, pathname, skipAll);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
20
- `)}function Pe(e){let t=e.clientEntry??`app/entry-client`;return[`// Auto-generated by Avalon — do not edit`,`// @ts-ignore — virtual import resolved by Nitro's Vite assets plugin at build time`,`import clientAssets from '${t.startsWith(`/`)?t:`/${t}`}?assets=client';`,``,`function buildAssetTags() {`,` const cssLinks = (clientAssets?.css ?? [])`,` .filter(attr => {`,` const href = attr.href || '';`,` // The SSR build produces ssr-index-*.css containing all global, reset,`,` // token, and layout CSS module styles. The client build may also emit`,` // entry-client-*.css (a subset) and index-*.css. To avoid duplicates,`,` // prefer ssr-index when it exists; otherwise fall back to the others.`,` var hasSsrIndex = (clientAssets?.css ?? []).some(function(a) { return (a.href || '').includes('ssr-index'); });`,` if (hasSsrIndex) return href.includes('ssr-index');`,` if (href.includes('entry-client') && href.endsWith('.css')) return true;`,String.raw` if (/\/index-[^/]+\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const entryScript = clientAssets?.entry`,` ? '<script type="module" src="' + clientAssets.entry + '"><\/script>'`,` : '';`,` return { cssLinks, jsPreloads, entryScript };`,`}`,``,`export function injectAssets(html) {`,` const { cssLinks, jsPreloads, entryScript } = buildAssetTags();`,` if (html.includes('</head>')) {`,String.raw` html = html.replace('</head>', cssLinks + '\n' + jsPreloads + '\n</head>');`,` }`,` if (html.includes('</body>')) {`,String.raw` html = html.replace('</body>', entryScript + '\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
21
- `)}function Fe(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}let i=ge(e.core);return[`// Auto-generated by Avalon — do not edit`,`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,...i,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`// Set hydration mode flag — intentionally duplicated from virtual:avalon/config`,`// for module-load-order resilience (config import may be tree-shaken or deferred).`,`globalThis.__avalonHydrationMode = avalonConfig.isDev ? "entry-client" : "per-island";`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const match = loadPage(pathname);`,` if (!match || !('default' in match.module)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: match.params };`,` },`,` loadPageModule: async (filePath) => {`,String.raw` const m = filePath.match(/^\[virtual:(.+)\]$/);`,` const pathname = m ? m[1] : filePath;`,` const match = loadPage(pathname);`,` if (match) return match.module;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
22
- `)}async function Ie(e,t){let{readdir:n}=await import(`node:fs/promises`),{relative:r,join:i}=await import(`node:path`),a=[];for(let{dir:o}of e){let e;try{e=await n(o,{withFileTypes:!0})}catch{continue}for(let n of e){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let e=r(t,i(o,n.name)).replaceAll(`\\`,`/`);a.push(e.startsWith(`/`)?e:`/${e}`)}}return a}function Le(e){if(e.length===0)return[];let t=[`// Layout CSS (auto-discovered)`],n=0;for(let r of e)r.includes(`.module.`)?(t.push(`import _lcss${n} from '${r}';`),n++):t.push(`import '${r}';`);return t}async function Re(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),r=process.cwd(),i=await Ie(await n(e.layoutsDir,e.modules,r),r),a=globalThis.__avalonConfig?.isDev??e.isDev,o=a?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,s=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?s.push(`import '${o}';`):s.push(`// Per-island hydration mode — no shared runtime needed`),a&&s.push(`import '${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}';`),s.push(``);let c=t.globalCSS??[];for(let e of c){let t=e.startsWith(`/`)?e:`/${e}`;s.push(`// Global CSS`,`import '${t}';`)}return c.length>0&&s.push(``),s.push(...Le(i),``),s.join(`
23
- `)}function ze(){return[`// --- Inlined Solid adapter (production) ---`,`// Eliminates a separate chunk + network request for the Solid client adapter.`,`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`,`function _ensureHydrationContext() {`,` if (!globalThis._$HY) {`,` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`,` }`,`}`,``,`async function _solidHydrate(container, Component, props) {`,` if (!container) throw new Error("Container element is required for hydration");`,` if (!Component || typeof Component !== "function") {`,` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`,` }`,` var el = container;`,` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`,` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`,` _ensureHydrationContext();`,` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`,`}`,``,`var _solidModule = { hydrate: _solidHydrate };`,``]}function Be(e,t,n){let r=[];for(let i of e){let e=t[i];e&&(i===`solid`&&!n?r.push(` case "solid":`,` return _solidModule;`):i===`react`?r.push(` case "react":`):r.push(` case "${i}":`,` return import("${e}");`))}return e.includes(`react`)&&!e.includes(`preact`)&&r.push(` return import("${t.react}");`),r}function Ve(e,t){let n=[];for(let r of e){let e=t[r];e&&n.push(` case "${r}":`,` return import("${e}").then(m => m.${r}Adapter);`)}return n}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:_e(e.core),vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,solid:`@useavalon/solid/client`,lit:`@useavalon/lit/client`,qwik:`@useavalon/qwik/client`},r={preact:`@useavalon/preact/client/hmr`,react:`@useavalon/react/client/hmr`,vue:`@useavalon/vue/client/hmr`,svelte:`@useavalon/svelte/client/hmr`,solid:`@useavalon/solid/client/hmr`,lit:`@useavalon/lit/client/hmr`,qwik:`@useavalon/qwik/client/hmr`},i=t.includes(`lit`),a=t.includes(`solid`),o=(globalThis.__avalonConfig?.isDev??e.isDev)===!0,s=[`// Auto-generated by Avalon — only includes configured integrations`,``];return a&&!o&&s.push(...ze()),s.push(`// --- loadIntegrationModule ---`,`export async function loadIntegrationModule(framework) {`,` switch (framework) {`,...Be(t,n,o),` default:`," throw new Error(`Unknown or unconfigured framework: ${framework}`);",` }`,`}`,``,`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?s.push(`export async function preLitHydration() {`,` await import("@useavalon/lit/client");`,`}`):s.push(`export async function preLitHydration() {}`),s.push(``,`// --- HMR adapter loader ---`,`export async function loadHMRAdapter(framework) {`,` switch (framework) {`,...Ve(t,r),` default: return null;`,` }`,`}`),s.join(`
24
- `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const z=`<!--AVALON_STREAM_BOUNDARY-->`;let B=null,V=null;async function H(e,t){if(t===`react`){let e=await import(`react`),t=await import(`react-dom/server`),n=e.default??e,r=t.default??t;return{h:e.createElement??n.createElement,renderToString:t.renderToString??r.renderToString}}let n=await e.ssrLoadModule(`preact`),r=await e.ssrLoadModule(`preact-render-to-string`);return{h:n.h,renderToString:r.render??r.default}}function U(e){return e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``}async function W(e,t,n){let r=[];for(let n of t){let t=await e.ssrLoadModule(n);r.push({file:n,module:t})}for(let r of t){let t=await C(e,r);n.push(...t)}return r}async function G(e,t,n,r){let i=[],a=[];for(let o of e){let e=o.module.default;if(!(!e||typeof e!=`function`))try{let s=e({...t,children:n(`div`,null,`test`)}),c=r(s instanceof Promise?await s:s);c.trim().startsWith(`<html`)||c.includes(`<!DOCTYPE`)?i.push(o):a.push(o)}catch{a.push(o)}}return{shellLayouts:i,wrapperLayouts:a}}async function He(e,t,n,r){try{let i=e({...t,children:n(`div`,{dangerouslySetInnerHTML:{__html:z}})});return r(i instanceof Promise?await i:i)}catch{return null}}function Ue(e,t){let n=e;if(t.length>0){let e=`<style data-avalon-ssr-css>${t.join(`
25
- `)}</style>`;n.includes(`</head>`)?n=n.replace(`</head>`,`${e}\n</head>`):n+=e}n.trim().toLowerCase().startsWith(`<!doctype`)||(n=`<!DOCTYPE html>\n${n}`);let r=f(!0);r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`));let i=p(!0);return i&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${i}\n</head>`)),m(n)}async function K(e,t,n){try{let n=typeof e==`function`?e():e;return t(n instanceof Promise?await n:n)}catch(e){return console.error(`${n} Error rendering page component:`,e),`<div>Error rendering page</div>`}}async function q(e,t,n,r,i,a){let o=e;for(let{module:e}of t){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:o}})});o=i(e instanceof Promise?await e:e)}catch(e){console.error(`${a} Error rendering wrapper layout:`,e)}}return o}async function We(e,t,n,r,i){if(t.length===0)return e;let{module:a}=t.at(-1),o=a.default;if(!o||typeof o!=`function`)return e;try{let t=o({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:e}})});return i(t instanceof Promise?await t:t)}catch(t){return console.error(`[SSR] Error rendering shell layout:`,t),e}}function Ge(e){if(e.includes(`/src/client/main.js`)||e.includes(`/@vite/client`))return e;let t=e.lastIndexOf(`</body>`);return t===-1?e:e.slice(0,t)+`
20
+ `)}function Fe(e){let t=e.clientEntry??`app/entry-client`;return[`// Auto-generated by Avalon — do not edit`,`// @ts-ignore — virtual import resolved by Nitro's Vite assets plugin at build time`,`import clientAssets from '${t.startsWith(`/`)?t:`/${t}`}?assets=client';`,``,`function buildAssetTags() {`,` const cssLinks = (clientAssets?.css ?? [])`,` .filter(attr => {`,` const href = attr.href || '';`,` // The SSR build produces ssr-index-*.css containing all global, reset,`,` // token, and layout CSS module styles. The client build may also emit`,` // entry-client-*.css (a subset) and index-*.css. To avoid duplicates,`,` // prefer ssr-index when it exists; otherwise fall back to the others.`,` var hasSsrIndex = (clientAssets?.css ?? []).some(function(a) { return (a.href || '').includes('ssr-index'); });`,` if (hasSsrIndex) return href.includes('ssr-index');`,` if (href.includes('entry-client') && href.endsWith('.css')) return true;`,String.raw` if (/\/index-[^/]+\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,String.raw` .join('\n');`,` const entryScript = clientAssets?.entry`,` ? '<script type="module" src="' + clientAssets.entry + '"><\/script>'`,` : '';`,` return { cssLinks, jsPreloads, entryScript };`,`}`,``,`export function injectAssets(html) {`,` const { cssLinks, jsPreloads, entryScript } = buildAssetTags();`,` if (html.includes('</head>')) {`,String.raw` html = html.replace('</head>', cssLinks + '\n' + jsPreloads + '\n</head>');`,` }`,` if (html.includes('</body>')) {`,String.raw` html = html.replace('</body>', entryScript + '\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
21
+ `)}function Ie(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}let i=_e(e.core);return[`// Auto-generated by Avalon — do not edit`,...t.includes(`lit`)?[`import "${O}";`]:[],`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,...i,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`// Set hydration mode flag — intentionally duplicated from virtual:avalon/config`,`// for module-load-order resilience (config import may be tree-shaken or deferred).`,`globalThis.__avalonHydrationMode = avalonConfig.isDev ? "entry-client" : "per-island";`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const match = loadPage(pathname);`,` if (!match || !('default' in match.module)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: match.params };`,` },`,` loadPageModule: async (filePath) => {`,String.raw` const m = filePath.match(/^\[virtual:(.+)\]$/);`,` const pathname = m ? m[1] : filePath;`,` const match = loadPage(pathname);`,` if (match) return match.module;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
22
+ `)}async function Le(e,t){let{readdir:n}=await import(`node:fs/promises`),{relative:r,join:i}=await import(`node:path`),a=[];for(let{dir:o}of e){let e;try{e=await n(o,{withFileTypes:!0})}catch{continue}for(let n of e){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let e=r(t,i(o,n.name)).replaceAll(`\\`,`/`);a.push(e.startsWith(`/`)?e:`/${e}`)}}return a}function Re(e){if(e.length===0)return[];let t=[`// Layout CSS (auto-discovered)`],n=0;for(let r of e)r.includes(`.module.`)?(t.push(`import _lcss${n} from '${r}';`),n++):t.push(`import '${r}';`);return t}async function ze(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),r=process.cwd(),i=await Le(await n(e.layoutsDir,e.modules,r),r),a=globalThis.__avalonConfig?.isDev??e.isDev,o=a?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,s=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?s.push(`import '${o}';`):s.push(`// Per-island hydration mode — no shared runtime needed`),a&&s.push(`import '${VIRTUAL_MODULE_IDS.DEV_CSS_HMR}';`),s.push(``);let c=t.globalCSS??[];for(let e of c){let t=e.startsWith(`/`)?e:`/${e}`;s.push(`// Global CSS`,`import '${t}';`)}return c.length>0&&s.push(``),s.push(...Re(i),``),s.join(`
23
+ `)}function Be(){return[`// --- Inlined Solid adapter (production) ---`,`// Eliminates a separate chunk + network request for the Solid client adapter.`,`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`,`function _ensureHydrationContext() {`,` if (!globalThis._$HY) {`,` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`,` }`,`}`,``,`async function _solidHydrate(container, Component, props) {`,` if (!container) throw new Error("Container element is required for hydration");`,` if (!Component || typeof Component !== "function") {`,` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`,` }`,` var el = container;`,` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`,` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`,` _ensureHydrationContext();`,` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`,`}`,``,`var _solidModule = { hydrate: _solidHydrate };`,``]}function Ve(e,t,n){let r=[];for(let i of e){let e=t[i];e&&(i===`solid`&&!n?r.push(` case "solid":`,` return _solidModule;`):i===`react`?r.push(` case "react":`):r.push(` case "${i}":`,` return import("${e}");`))}return e.includes(`react`)&&!e.includes(`preact`)&&r.push(` return import("${t.react}");`),r}function He(e,t){let n=[];for(let r of e){let e=t[r];e&&n.push(` case "${r}":`,` return import("${e}").then(m => m.${r}Adapter);`)}return n}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:ve(e.core),vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,solid:`@useavalon/solid/client`,lit:`@useavalon/lit/client`,qwik:`@useavalon/qwik/client`},r={preact:`@useavalon/preact/client/hmr`,react:`@useavalon/react/client/hmr`,vue:`@useavalon/vue/client/hmr`,svelte:`@useavalon/svelte/client/hmr`,solid:`@useavalon/solid/client/hmr`,lit:`@useavalon/lit/client/hmr`,qwik:`@useavalon/qwik/client/hmr`},i=t.includes(`lit`),a=t.includes(`solid`),o=(globalThis.__avalonConfig?.isDev??e.isDev)===!0,s=[`// Auto-generated by Avalon — only includes configured integrations`,``];return a&&!o&&s.push(...Be()),s.push(`// --- loadIntegrationModule ---`,`export async function loadIntegrationModule(framework) {`,` switch (framework) {`,...Ve(t,n,o),` default:`," throw new Error(`Unknown or unconfigured framework: ${framework}`);",` }`,`}`,``,`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?s.push(`export async function preLitHydration() {`,` await import("@useavalon/lit/client");`,`}`):s.push(`export async function preLitHydration() {}`),s.push(``,`// --- HMR adapter loader ---`,`export async function loadHMRAdapter(framework) {`,` switch (framework) {`,...He(t,r),` default: return null;`,` }`,`}`),s.join(`
24
+ `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const B=`<!--AVALON_STREAM_BOUNDARY-->`;let V=null,H=null;async function U(e,t){if(t===`react`){let e=await import(`react`),t=await import(`react-dom/server`),n=e.default??e,r=t.default??t;return{h:e.createElement??n.createElement,renderToString:t.renderToString??r.renderToString}}let n=await e.ssrLoadModule(`preact`),r=await e.ssrLoadModule(`preact-render-to-string`);return{h:n.h,renderToString:r.render??r.default}}function W(e){return e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``}async function G(e,t,n){let r=[];for(let n of t){let t=await e.ssrLoadModule(n);r.push({file:n,module:t})}for(let r of t){let t=await C(e,r);n.push(...t)}return r}async function K(e,t,n,r){let i=[],a=[];for(let o of e){let e=o.module.default;if(!(!e||typeof e!=`function`))try{let s=e({...t,children:n(`div`,null,`test`)}),c=r(s instanceof Promise?await s:s);c.trim().startsWith(`<html`)||c.includes(`<!DOCTYPE`)?i.push(o):a.push(o)}catch{a.push(o)}}return{shellLayouts:i,wrapperLayouts:a}}async function Ue(e,t,n,r){try{let i=e({...t,children:n(`div`,{dangerouslySetInnerHTML:{__html:B}})});return r(i instanceof Promise?await i:i)}catch{return null}}function We(e,t){let n=e;if(t.length>0){let e=`<style data-avalon-ssr-css>${t.join(`
25
+ `)}</style>`;n.includes(`</head>`)?n=n.replace(`</head>`,`${e}\n</head>`):n+=e}n.trim().toLowerCase().startsWith(`<!doctype`)||(n=`<!DOCTYPE html>\n${n}`);let r=f(!0);r&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${r}\n</head>`));let i=p(!0);return i&&n.includes(`</head>`)&&(n=n.replace(`</head>`,`${i}\n</head>`)),m(n)}async function q(e,t,n){try{let n=typeof e==`function`?e():e;return t(n instanceof Promise?await n:n)}catch(e){return console.error(`${n} Error rendering page component:`,e),`<div>Error rendering page</div>`}}async function J(e,t,n,r,i,a){let o=e;for(let{module:e}of t){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:o}})});o=i(e instanceof Promise?await e:e)}catch(e){console.error(`${a} Error rendering wrapper layout:`,e)}}return o}async function Ge(e,t,n,r,i){if(t.length===0)return e;let{module:a}=t.at(-1),o=a.default;if(!o||typeof o!=`function`)return e;try{let t=o({...n,children:r(`div`,{dangerouslySetInnerHTML:{__html:e}})});return i(t instanceof Promise?await t:t)}catch(t){return console.error(`[SSR] Error rendering shell layout:`,t),e}}function Ke(e){if(e.includes(`/src/client/main.js`)||e.includes(`/@vite/client`))return e;let t=e.lastIndexOf(`</body>`);return t===-1?e:e.slice(0,t)+`
26
26
  <script type="module" src="/@vite/client"><\/script>
27
27
  <script type="module" src="/src/client/main.js"><\/script>
28
- `+e.slice(t)}async function Ke(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Q(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),o=t.default;if(!o)return!1;let s=t.layoutConfig,c=await C(e,a),l=await W(e,await Y(i,e),c);if(l.length===0)return!1;let{h:u,renderToString:d}=await H(e,n.core),f=s?.skipLayouts||[],p=l.filter(({file:e})=>!f.includes(U(e))),m=t.frontmatter,h=t.metadata,g={children:null,frontmatter:{...m,...h,currentPath:i},params:{},url:i},{shellLayouts:_,wrapperLayouts:v}=await G(p,g,u,d);if(_.length===0)return!1;let{module:y}=_.at(-1),b=y.default;if(!b||typeof b!=`function`)return!1;let x=await He(b,g,u,d);if(x===null)return!1;let S=x.indexOf(z);if(S===-1)return!1;let w=x.slice(0,S),T=x.slice(S+29),E=Ue(w,c);r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(E);let D=await K(o,d,`[SSR Streaming]`);if(D.trim().startsWith(`<!DOCTYPE html>`)||D.trim().startsWith(`<html`))return r.end(D),!0;let O=Ge(await q(D,v,g,u,d,`[SSR Streaming]`)+T);return r.end(O),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function qe(e,t,n){let r=t.split(`?`)[0],i=await Q(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await C(e,i),s=await W(e,await Y(r,e),o),c;return c=n.modules&&s.length>0?await Je(a,t,s,r,n,e):await et(a,t,r,n,e),o.length>0&&(c=w(c,o)),c}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Je(e,t,n,r,i,a){let{h:o,renderToString:s}=await H(a,i.core),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>!c.includes(U(e))),u=await K(e,s,`[SSR]`);if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return J(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},{shellLayouts:m,wrapperLayouts:h}=await G(l,p,o,s),g=await We(await q(u,h,p,o,s,`[SSR]`),m,p,o,s);if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return J(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
28
+ `+e.slice(t)}async function qe(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Ze(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),o=t.default;if(!o)return!1;let s=t.layoutConfig,c=await C(e,a),l=await G(e,await X(i,e),c);if(l.length===0)return!1;let{h:u,renderToString:d}=await U(e,n.core),f=s?.skipLayouts||[],p=l.filter(({file:e})=>!f.includes(W(e))),m=t.frontmatter,h=t.metadata,g={children:null,frontmatter:{...m,...h,currentPath:i},params:{},url:i},{shellLayouts:_,wrapperLayouts:v}=await K(p,g,u,d);if(_.length===0)return!1;let{module:y}=_.at(-1),b=y.default;if(!b||typeof b!=`function`)return!1;let x=await Ue(b,g,u,d);if(x===null)return!1;let S=x.indexOf(B);if(S===-1)return!1;let w=x.slice(0,S),T=x.slice(S+29),ee=We(w,c);r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(ee);let E=await q(o,d,`[SSR Streaming]`);if(E.trim().startsWith(`<!DOCTYPE html>`)||E.trim().startsWith(`<html`))return r.end(E),!0;let D=Ke(await J(E,v,g,u,d,`[SSR Streaming]`)+T);return r.end(D),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function Je(e,t,n){let r=t.split(`?`)[0],i=await Ze(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await C(e,i),s=await G(e,await X(r,e),o),c;return c=n.modules&&s.length>0?await Ye(a,t,s,r,n,e):await nt(a,t,r,n,e),o.length>0&&(c=w(c,o)),c}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Ye(e,t,n,r,i,a){let{h:o,renderToString:s}=await U(a,i.core),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>!c.includes(W(e))),u=await q(e,s,`[SSR]`);if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return Y(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},{shellLayouts:m,wrapperLayouts:h}=await K(l,p,o,s),g=await Ge(await J(u,h,p,o,s,`[SSR]`),m,p,o,s);if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return Y(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
29
29
  <html lang="en">
30
30
  <head>
31
31
  <meta charset="utf-8">
@@ -38,12 +38,12 @@ export default islandManifest;
38
38
  ${g}
39
39
  <script type="module" src="/src/client/main.js"><\/script>
40
40
  </body>
41
- </html>`}function J(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=f(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=p(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=m(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
41
+ </html>`}function Y(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=f(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=p(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=m(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
42
42
  <script type="module" src="/@vite/client"><\/script>
43
43
  <script type="module" src="/src/client/main.js"><\/script>`:t.slice(0,r)+`
44
44
  <script type="module" src="/@vite/client"><\/script>
45
45
  <script type="module" src="/src/client/main.js"><\/script>
46
- `+t.slice(r)}async function Y(e,t){let n=t.config.root||process.cwd(),r=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await i(e)).isFile()){let t=e.slice(n.length);o.includes(t)||o.push(t)}}catch{}}if(r?.layoutsDir&&await l(`${`${n}/${r.layoutsDir}`}/${a}`),r?.modules){let e=`${n}/${r.modules.dir}`,t=r.modules.layoutsDirName,i=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!i||o.includes(i.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${i}/${t}/${a}`)}let u=`${n}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function X(e,t){try{if((await i(`${e}/${t}`)).isFile())return`/${t}`}catch{}return null}async function Z(e,t,n){for(let r of n){let n=await X(e,`${t}${r}`);if(n)return n}if(!t.endsWith(`/index`))for(let r of n){let n=await X(e,`${t}/index${r}`);if(n)return n}return null}function Ye(e,t,n){let r=t.split(`/`).filter(Boolean),i=r[0]||``,a=[`home`,`root`,`main`,`index`],o,s;if(!i||a.includes(i.toLowerCase()))o=`home`,s=n;else{o=i;let e=r.slice(1);s=e.length>0?`/${e.join(`/`)}`:`/index`}return`${e.dir}/${o}/${e.pagesDirName}${s}`}async function Q(e,t,n){let r=e;r.endsWith(`/`)&&r!==`/`&&(r=r.slice(0,-1)),r===`/`&&(r=`/index`);let i=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],a=n.config.root||process.cwd();if(t.modules){let n=await Z(a,Ye(t.modules,e,r),i);if(n)return n}return Z(a,`${t.pagesDir}${r}`,i)}function Xe(e,t,n){if(globalThis.__avalonLayoutResolver)return;let r=e.EnhancedLayoutResolver,i=t.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new r({baseDirectory:`${n}/${i}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:t.modules?`${n}/${t.modules.dir}`:void 0,modulesLayoutsDirName:t.modules?.layoutsDirName})}async function Ze(e,t,n,r){try{let{renderToString:r}=await H(t,n.core);return typeof e==`function`?r(e()):``}catch{return`<p>Loading page: ${$(r)}</p>`}}async function Qe(e,t,n,r,i,a,o){if(!e.renderToHtmlWithLayouts||!t.EnhancedLayoutResolver||!t.EnhancedLayoutResolverUtils)return null;try{Xe(t,r,i.config.root||process.cwd());let s=`http://localhost${a}`,c={params:{},query:{},url:s,request:{method:`GET`,url:s,headers:new Headers}};return await e.renderToHtmlWithLayouts(n,globalThis.__avalonLayoutResolver,c,a,{title:o.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{return null}}async function $e(e,t,n,r,i,a){try{B||=await i.ssrLoadModule(N(`src/render/ssr.ts`));let o=B;V||=await i.ssrLoadModule(N(`src/core/layout/enhanced-layout-resolver.ts`));let s=V,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter},l=await Qe(o,s,c,r,i,n,a);if(l!==null)return l;if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}return null}async function et(e,t,n,r,i){let a=t.metadata||{},o=await $e(e,t,n,r,i,a);if(o!==null)return o;let s=a.title||`Avalon App`,c=a.description||``,l=await Ze(e,i,r,n);return`<!DOCTYPE html>
46
+ `+t.slice(r)}async function X(e,t){let n=t.config.root||process.cwd(),r=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await i(e)).isFile()){let t=e.slice(n.length);o.includes(t)||o.push(t)}}catch{}}if(r?.layoutsDir&&await l(`${`${n}/${r.layoutsDir}`}/${a}`),r?.modules){let e=`${n}/${r.modules.dir}`,t=r.modules.layoutsDirName,i=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!i||o.includes(i.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${i}/${t}/${a}`)}let u=`${n}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function Z(e,t){try{if((await i(`${e}/${t}`)).isFile())return`/${t}`}catch{}return null}async function Q(e,t,n){for(let r of n){let n=await Z(e,`${t}${r}`);if(n)return n}if(!t.endsWith(`/index`))for(let r of n){let n=await Z(e,`${t}/index${r}`);if(n)return n}return null}function Xe(e,t,n){let r=t.split(`/`).filter(Boolean),i=r[0]||``,a=[`home`,`root`,`main`,`index`],o,s;if(!i||a.includes(i.toLowerCase()))o=`home`,s=n;else{o=i;let e=r.slice(1);s=e.length>0?`/${e.join(`/`)}`:`/index`}return`${e.dir}/${o}/${e.pagesDirName}${s}`}async function Ze(e,t,n){let r=e;r.endsWith(`/`)&&r!==`/`&&(r=r.slice(0,-1)),r===`/`&&(r=`/index`);let i=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],a=n.config.root||process.cwd();if(t.modules){let n=await Q(a,Xe(t.modules,e,r),i);if(n)return n}return Q(a,`${t.pagesDir}${r}`,i)}function Qe(e,t,n){if(globalThis.__avalonLayoutResolver)return;let r=e.EnhancedLayoutResolver,i=t.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new r({baseDirectory:`${n}/${i}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:t.modules?`${n}/${t.modules.dir}`:void 0,modulesLayoutsDirName:t.modules?.layoutsDirName})}async function $e(e,t,n,r){try{let{renderToString:r}=await U(t,n.core);return typeof e==`function`?r(e()):``}catch{return`<p>Loading page: ${$(r)}</p>`}}async function et(e,t,n,r,i,a,o){if(!e.renderToHtmlWithLayouts||!t.EnhancedLayoutResolver||!t.EnhancedLayoutResolverUtils)return null;try{Qe(t,r,i.config.root||process.cwd());let s=`http://localhost${a}`,c={params:{},query:{},url:s,request:{method:`GET`,url:s,headers:new Headers}};return await e.renderToHtmlWithLayouts(n,globalThis.__avalonLayoutResolver,c,a,{title:o.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{return null}}async function tt(e,t,n,r,i,a){try{V||=await i.ssrLoadModule(P(`src/render/ssr.ts`));let o=V;H||=await i.ssrLoadModule(P(`src/core/layout/enhanced-layout-resolver.ts`));let s=H,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter},l=await et(o,s,c,r,i,n,a);if(l!==null)return l;if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}return null}async function nt(e,t,n,r,i){let a=t.metadata||{},o=await tt(e,t,n,r,i,a);if(o!==null)return o;let s=a.title||`Avalon App`,c=a.description||``,l=await $e(e,i,r,n);return`<!DOCTYPE html>
47
47
  <html lang="en">
48
48
  <head>
49
49
  <meta charset="utf-8">
@@ -1 +1 @@
1
- import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{islandClientBundlerPlugin as r}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as i}from"../build/island-code-splitting.js";import{mdxIslandTransform as a}from"../build/mdx-island-transform.js";import{createMDXPlugin as o}from"../build/mdx-plugin.js";import{pageIslandTransform as s}from"../build/page-island-transform.js";import{registry as c}from"../core/integrations/registry.js";import{discoverIntegrationsFromIslandUsage as l}from"./auto-discover.js";import{checkDirectoriesExist as u,resolveConfig as d}from"./config.js";import{shouldSetDevScopedName as f,stableDevScopedName as p}from"./dev-css-modules.js";import{createImagePlugin as m}from"./image-optimization.js";import{activateIntegrations as h,activateSingleIntegration as g}from"./integration-activator.js";import{islandSidecarPlugin as _}from"./island-sidecar-plugin.js";import{createNitroIntegration as v}from"./nitro-integration.js";import{serverIslandsPlugin as y}from"./server-islands-plugin.js";import{formatValidationResults as b,validateActiveIntegrations as x}from"./validation.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await S(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function S(e,t){let n=c.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function C(e,t){let n=new Set;try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function w(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await C(e);return t.size===0?[...e.integrations]:Array.from(t)}async function T(e){try{let t=await o({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(a({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function E(e,t,n){let{plugins:r,nitroOptions:i}=v(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function D(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await g(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function O(e,t){if(!e.validateIntegrations||t.size===0)return;let n=x(t,e.showWarnings);n.allValid||(console.error(b(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(a){let o,c,l=new Set,g=d(a,!0),v=await w(g);v.length>0&&await h({...g,integrations:v},l);let b=await T(g),x=await m(g.image,g.verbose),S=[];l.size>0&&(S=await collectIntegrationPlugins(l,g.verbose));let C=[];if(a?.nitro){let{plugins:e}=E(g,a.nitro,g.verbose);C=e}let k=_({verbose:g.verbose}),A=y({verbose:g.verbose}),j=e(import.meta.url),M=null;try{M=n(t(j.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let N=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),P={name:`avalon`,enforce:`pre`,config(e,{command:t}){let n={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},r=v.flatMap(e=>n[e]??[]);return a?.core===`react`&&r.push(`react-dom/server`,`react/jsx-runtime`),{define:{__AVALON_PER_ISLAND__:JSON.stringify(t===`build`)},oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...v.map(e=>`@useavalon/${e}`)],include:r},...t===`serve`&&f(e.css?.modules)?{css:{modules:{generateScopedName:p}}}:{}}},configResolved(e){c=e,o=d(a,e.command===`serve`),globalThis.__avalonConfig=o,u(o,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&M)return M;if(N.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await D(o,c?.root,l),O(o,l)},configureServer(e){globalThis.__viteDevServer=e}},F=S.filter(e=>e.name?.includes(`lit`)),I=S.filter(e=>!e.name?.includes(`lit`)),L,R=t=>{try{return L||=e(n(c?.root??process.cwd(),`package.json`)),L.resolve(t).replace(/\.js$/,`.mjs`)}catch{return}},z=new Set([`preact`,`preact/hooks`,`preact/compat`,`preact/compat/server`,`preact/compat/client`]),B={name:`avalon:preact-compat-resolver`,enforce:`pre`,resolveId(e){let t=this.environment?.name;return t!==`ssr`&&t!==`nitro`||!z.has(e)?null:R(e)??null}},V=[`@preact/preset-vite`,`@vitejs/plugin-react`,`@vitejs/plugin-vue`,`@sveltejs/vite-plugin-svelte`,`vite-plugin-solid`,`@builder.io/qwik/optimizer`,`vite-prerender-plugin`];return[B,{name:`avalon:stub-build-time-plugins`,enforce:`pre`,resolveId(e){let t=this.environment?.name;if(!(t!==`ssr`&&t!==`nitro`)&&V.some(t=>e===t||e.startsWith(`${t}/`)))return`\0stub:${e}`},load(e){if(e.startsWith(`\0stub:`))return`export default function() { return []; }; export {};`}},s({pagesDir:g.pagesDir,layoutsDir:g.layoutsDir,modules:g.modules,verbose:g.verbose}),r(g,a?.nitro),i(g,a?.nitro),...x,...F,...b,P,k,A,...C,...I]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
1
+ import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{islandClientBundlerPlugin as r}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as i}from"../build/island-code-splitting.js";import{mdxIslandTransform as a}from"../build/mdx-island-transform.js";import{createMDXPlugin as o}from"../build/mdx-plugin.js";import{pageIslandTransform as s}from"../build/page-island-transform.js";import{registry as c}from"../core/integrations/registry.js";import{discoverIntegrationsFromIslandUsage as l}from"./auto-discover.js";import{checkDirectoriesExist as u,resolveConfig as d}from"./config.js";import{shouldSetDevScopedName as f,stableDevScopedName as p}from"./dev-css-modules.js";import{createImagePlugin as m}from"./image-optimization.js";import{activateIntegrations as h,activateSingleIntegration as g}from"./integration-activator.js";import{islandSidecarPlugin as _}from"./island-sidecar-plugin.js";import{createNitroIntegration as v}from"./nitro-integration.js";import{serverIslandsPlugin as y}from"./server-islands-plugin.js";import{STUB_BUILD_TIME_MODULE as b,shouldStubBuildTimeSpecifier as x}from"./stub-build-time-packages.js";import{formatValidationResults as S,validateActiveIntegrations as C}from"./validation.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await w(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function w(e,t){let n=c.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function T(e,t){let n=new Set;try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function E(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await T(e);return t.size===0?[...e.integrations]:Array.from(t)}async function D(e){try{let t=await o({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(a({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function O(e,t,n){let{plugins:r,nitroOptions:i}=v(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function k(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await l(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await g(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function A(e,t){if(!e.validateIntegrations||t.size===0)return;let n=C(t,e.showWarnings);n.allValid||(console.error(S(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(a){let o,c,l=new Set,g=d(a,!0),v=await E(g);v.length>0&&await h({...g,integrations:v},l);let S=await D(g),C=await m(g.image,g.verbose),w=[];l.size>0&&(w=await collectIntegrationPlugins(l,g.verbose));let T=[];if(a?.nitro){let{plugins:e}=O(g,a.nitro,g.verbose);T=e}let j=_({verbose:g.verbose}),M=y({verbose:g.verbose}),N=e(import.meta.url),P=null;try{P=n(t(N.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let F=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),I={name:`avalon`,enforce:`pre`,config(e,{command:t}){let n={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},r=v.flatMap(e=>n[e]??[]);return a?.core===`react`&&r.push(`react-dom/server`,`react/jsx-runtime`),{define:{__AVALON_PER_ISLAND__:JSON.stringify(t===`build`)},oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...v.map(e=>`@useavalon/${e}`)],include:r},...t===`serve`&&f(e.css?.modules)?{css:{modules:{generateScopedName:p}}}:{}}},configResolved(e){c=e,o=d(a,e.command===`serve`),globalThis.__avalonConfig=o,u(o,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&P)return P;if(F.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await k(o,c?.root,l),A(o,l)},configureServer(e){globalThis.__viteDevServer=e}},L=w.filter(e=>e.name?.includes(`lit`)),R=w.filter(e=>!e.name?.includes(`lit`)),z,B=t=>{try{return z||=e(n(c?.root??process.cwd(),`package.json`)),z.resolve(t).replace(/\.js$/,`.mjs`)}catch{return}},V=new Set([`preact`,`preact/hooks`,`preact/compat`,`preact/compat/server`,`preact/compat/client`]);return[{name:`avalon:preact-compat-resolver`,enforce:`pre`,resolveId(e){let t=this.environment?.name;return t!==`ssr`&&t!==`nitro`||!V.has(e)?null:B(e)??null}},{name:`avalon:stub-build-time-plugins`,enforce:`pre`,resolveId(e){let t=this.environment?.name;if(!(t!==`ssr`&&t!==`nitro`)&&x(e))return`\0stub:${e}`},load(e){if(e.startsWith(`\0stub:`))return b;let t=this.environment?.name;if(!(t!==`ssr`&&t!==`nitro`)&&x(e))return b}},s({pagesDir:g.pagesDir,layoutsDir:g.layoutsDir,modules:g.modules,verbose:g.verbose}),r(g,a?.nitro),i(g,a?.nitro),...C,...L,...S,I,j,M,...T,...R]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
@@ -1,3 +1,3 @@
1
- import{dirname as e,relative as t,resolve as n}from"node:path";import{generateKey as r,getKey as i}from"../server-islands/encryption.js";import{addToManifest as a,clearManifest as o,generateComponentId as s,getManifest as c}from"../server-islands/manifest.js";const l=`virtual:server-island-manifest`,u=`\0`+l,d=`virtual:server-island-key`,f=`\0`+d,p=/<([A-Z][a-zA-Z0-9_$]*)\s[\s\S]*?\bserver\s*[={/>]/;function m(e){let t=[],n=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,r=null;for(r=n.exec(e);r!==null;r=n.exec(e))t.push({localName:r[1],importPath:r[2].slice(1,-1)});return t}function h(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}export function resolveToRelativePath(r,i,a){return r.startsWith(`/src/`)||r.startsWith(`/app/`)?r:r.startsWith(`@/`)?`/app/${r.slice(2)}`:r.startsWith(`@shared/`)?`/app/shared/${r.slice(8)}`:r.startsWith(`@modules/`)?`/app/modules/${r.slice(9)}`:r.startsWith(`~/`)?`/src/${r.slice(2)}`:r.startsWith(`$components/`)?`/src/components/${r.slice(12)}`:r.startsWith(`$islands/`)?`/src/islands/${r.slice(9)}`:r.startsWith(`.`)?`/`+t(a,n(e(i),r)).replaceAll(`\\`,`/`):r}export function serverIslandsPlugin(e={}){let t,n,g=!!process.env.AVALON_KEY;return{name:`avalon:server-islands`,enforce:`pre`,config(){process.env.AVALON_KEY||(process.env.AVALON_KEY=r())},configResolved(e){t=e.root},buildStart(){o(),n=i(),e.verbose&&console.log(`[avalon:server-islands] Encryption key source: ${g?`AVALON_KEY env var`:`generated per-build`}`)},resolveId(e){return e===l?u:e===d?f:e===`virtual:server-island-integrations`?`\0virtual:server-island-integrations`:null},load(e){if(e===`\0virtual:server-island-integrations`)return`export {};`;if(e===u){let e=c(),t=Object.entries(e),n=`export const serverIslandManifest = ${JSON.stringify(e)};\n\n`;n+=`export const serverIslandLoaders = {
1
+ import{dirname as e,relative as t,resolve as n}from"node:path";import{generateKey as r,getKey as i}from"../server-islands/encryption.js";import{addToManifest as a,clearManifest as o,generateComponentId as s,getManifest as c}from"../server-islands/manifest.js";const l=`virtual:server-island-manifest`,u=`\0`+l,d=`virtual:server-island-key`,f=`\0`+d,p=/<([A-Z][a-zA-Z0-9_$]*)\s[\s\S]*?\bserver\s*[={/>]/;function m(e){let t=[],n=/^[ \t]*import\s+([A-Z]\w*)\s+from\s+(['"][^'"]+['"])/gm,r=null;for(r=n.exec(e);r!==null;r=n.exec(e))t.push({localName:r[1],importPath:r[2].slice(1,-1)});return t}function h(e,t){return new RegExp(String.raw`<${t}\s[\s\S]*?\bserver\s*[={/>]`).test(e)}export function resolveToRelativePath(r,i,a){return r.startsWith(`/src/`)||r.startsWith(`/app/`)?r:r.startsWith(`@/`)?`/app/${r.slice(2)}`:r.startsWith(`@shared/`)?`/app/shared/${r.slice(8)}`:r.startsWith(`@modules/`)?`/app/modules/${r.slice(9)}`:r.startsWith(`~/`)?`/src/${r.slice(2)}`:r.startsWith(`$components/`)?`/src/components/${r.slice(12)}`:r.startsWith(`$islands/`)?`/src/islands/${r.slice(9)}`:r.startsWith(`.`)?`/`+t(a,n(e(i),r)).replaceAll(`\\`,`/`):r}export function serverIslandsPlugin(e={}){let t,n,g=!!process.env.AVALON_KEY;return{name:`avalon:server-islands`,enforce:`pre`,config(){process.env.AVALON_KEY||(process.env.AVALON_KEY=r())},configResolved(e){t=e.root},buildStart(){o(),n=i(),e.verbose&&console.log(`[avalon:server-islands] Encryption key source: ${g?`AVALON_KEY env var`:`generated per-build`}`)},resolveId(e){return e===l?u:e===d?f:null},load(e){if(e===u){let e=c(),t=Object.entries(e),n=`export const serverIslandManifest = ${JSON.stringify(e)};\n\n`;n+=`export const serverIslandLoaders = {
2
2
  `;for(let[e,r]of t)n+=` ${JSON.stringify(e)}: () => import(${JSON.stringify(r)}),\n`;return n+=`};
3
3
  `,n}return e===f?`export const serverIslandKey = ${JSON.stringify(n)};`:null},transform(n,r){if(!/\.(tsx|jsx)$/.test(r)||r.includes(`node_modules`)||!p.test(n))return null;let i=m(n);if(i.length===0)return null;for(let o of i)if(h(n,o.localName)){let n=resolveToRelativePath(o.importPath,r,t),i=s(n);a(i,n),e.verbose&&console.log(`[avalon:server-islands] Registered: ${o.localName} → ${i} (${n})`)}return null},generateBundle(){let t=c(),n=Object.keys(t).length;n>0&&e.verbose&&console.log(`[avalon:server-islands] Manifest contains ${n} server island(s)`)}}}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Separate module so ESM evaluates this stub before `@useavalon/lit`
3
+ * (and `lit-html`, which reads `document` at module eval). Imports in the
4
+ * same file are hoisted together; a dedicated first import is the only
5
+ * ordering guarantee.
6
+ *
7
+ * Prefer `@lit-labs/ssr-dom-shim` for HTMLElement / customElements so Lit SSR
8
+ * can emit declarative shadow DOM. A no-op `customElements.define` left Lit
9
+ * islands as empty tags until client hydration.
10
+ *
11
+ * Cloudflare's on-disk `_dom_stub.mjs` cannot use bare package imports (the
12
+ * Pages worker has no node_modules). Use {@link ssrDomStubFileSource} there.
13
+ */
14
+ export declare const SSR_DOM_VIRTUAL_ID = "virtual:avalon/ssr-dom";
15
+ /**
16
+ * Nitro virtual module + prerender Node wrapper: real ssr-dom-shim classes.
17
+ * Rolldown / Node resolve `@lit-labs/ssr-dom-shim` from the project graph.
18
+ * CSSStyleSheet must exist before CustomElementRegistry.define runs Lit
19
+ * finalizeStyles (constructable stylesheets).
20
+ */
21
+ export declare function ssrDomShimModuleSource(): string;
22
+ /**
23
+ * Self-contained stub for Cloudflare `_dom_stub.mjs` (no bare imports).
24
+ * Keeps a working customElements Map so dynamic Lit SSR in the Worker does not
25
+ * fall back to empty tags when the real shim package is unavailable.
26
+ */
27
+ export declare function ssrDomStubFileSource(): string;
@@ -0,0 +1,121 @@
1
+ export const SSR_DOM_VIRTUAL_ID=`virtual:avalon/ssr-dom`;function e(){return`
2
+ if (typeof globalThis.CSSStyleSheet === "undefined") {
3
+ globalThis.CSSStyleSheet = class CSSStyleSheet {
4
+ constructor() { this.cssRules = []; }
5
+ replaceSync() {}
6
+ replace() { return Promise.resolve(this); }
7
+ insertRule() { return 0; }
8
+ deleteRule() {}
9
+ };
10
+ }
11
+ if (typeof globalThis.document === "undefined") {
12
+ const createEl = () => ({
13
+ nodeType: 1,
14
+ childNodes: [],
15
+ attributes: {},
16
+ style: {},
17
+ setAttribute() {},
18
+ getAttribute() { return null; },
19
+ appendChild(c) { return c; },
20
+ addEventListener() {},
21
+ removeEventListener() {},
22
+ });
23
+ globalThis.document = {
24
+ createComment() { return { nodeType: 8 }; },
25
+ createTextNode(t) { return { nodeType: 3, data: t }; },
26
+ createElement() { return createEl(); },
27
+ createElementNS() { return createEl(); },
28
+ createTreeWalker() { return { nextNode() { return null; } }; },
29
+ createDocumentFragment() { return createEl(); },
30
+ implementation: { createHTMLDocument() { return globalThis.document; } },
31
+ body: createEl(),
32
+ head: createEl(),
33
+ documentElement: createEl(),
34
+ };
35
+ }
36
+ if (typeof globalThis.Node === "undefined") {
37
+ globalThis.Node = class Node {};
38
+ }
39
+ `}export function ssrDomShimModuleSource(){return`
40
+ ${e()}
41
+ import {
42
+ CustomElementRegistry,
43
+ CustomEvent as ShimCustomEvent,
44
+ Element as ShimElement,
45
+ Event as ShimEvent,
46
+ EventTarget as ShimEventTarget,
47
+ HTMLElement as ShimHTMLElement,
48
+ } from "@lit-labs/ssr-dom-shim";
49
+
50
+ globalThis.HTMLElement = ShimHTMLElement;
51
+ globalThis.Element = ShimElement;
52
+ globalThis.EventTarget = ShimEventTarget;
53
+ globalThis.Event = ShimEvent;
54
+ globalThis.CustomEvent = ShimCustomEvent;
55
+ globalThis.customElements = new CustomElementRegistry();
56
+ `}export function ssrDomStubFileSource(){return`
57
+ if (typeof globalThis.HTMLElement === "undefined") {
58
+ globalThis.HTMLElement = class HTMLElement {};
59
+ }
60
+ if (typeof globalThis.Element === "undefined") {
61
+ globalThis.Element = class Element {};
62
+ }
63
+ if (typeof globalThis.EventTarget === "undefined") {
64
+ globalThis.EventTarget = class EventTarget {
65
+ addEventListener() {}
66
+ removeEventListener() {}
67
+ dispatchEvent() { return true; }
68
+ };
69
+ }
70
+ if (typeof globalThis.Event === "undefined") {
71
+ globalThis.Event = class Event { constructor(type) { this.type = type; } };
72
+ }
73
+ if (typeof globalThis.CustomEvent === "undefined") {
74
+ globalThis.CustomEvent = class CustomEvent extends Event {
75
+ constructor(type, init) { super(type); this.detail = init?.detail; }
76
+ };
77
+ }
78
+ if (typeof globalThis.customElements === "undefined") {
79
+ const registry = new Map();
80
+ globalThis.customElements = {
81
+ define(name, ctor) { registry.set(name, ctor); },
82
+ get(name) { return registry.get(name); },
83
+ whenDefined(name) {
84
+ const ctor = registry.get(name);
85
+ return ctor ? Promise.resolve(ctor) : Promise.resolve();
86
+ },
87
+ getName(ctor) {
88
+ for (const [name, registered] of registry) {
89
+ if (registered === ctor) return name;
90
+ }
91
+ return null;
92
+ },
93
+ };
94
+ } else if (typeof globalThis.customElements.get === "function") {
95
+ const probeName = "avalon-ce-probe";
96
+ try {
97
+ const Probe = class extends globalThis.HTMLElement {};
98
+ globalThis.customElements.define(probeName, Probe);
99
+ if (globalThis.customElements.get(probeName) !== Probe) {
100
+ const registry = new Map();
101
+ globalThis.customElements = {
102
+ define(name, ctor) { registry.set(name, ctor); },
103
+ get(name) { return registry.get(name); },
104
+ whenDefined(name) {
105
+ const ctor = registry.get(name);
106
+ return ctor ? Promise.resolve(ctor) : Promise.resolve();
107
+ },
108
+ getName(ctor) {
109
+ for (const [name, registered] of registry) {
110
+ if (registered === ctor) return name;
111
+ }
112
+ return null;
113
+ },
114
+ };
115
+ }
116
+ } catch {
117
+ /* leave existing registry */
118
+ }
119
+ }
120
+ ${e()}
121
+ `}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Specifiers that must not be bundled into SSR / Nitro / Cloudflare workers.
3
+ *
4
+ * The `@useavalon/avalon` barrel re-exports the Vite plugin, so Cloudflare's
5
+ * worker pass inlines transform-time deps: oxc-parser (wasm32-wasi), Vite
6
+ * itself (chokidar → fsevents.node), and integration Vite plugins.
7
+ */
8
+ /** True when this import must be replaced by a stub in the SSR/Nitro graph. */
9
+ export declare function shouldStubBuildTimeSpecifier(id: string): boolean;
10
+ /**
11
+ * Stub module source. Named exports exist so Rolldown does not fail
12
+ * `import { parseSync } from "oxc-parser"` or
13
+ * `import { isRunnableDevEnvironment } from "vite"` when the barrel is inlined.
14
+ * These functions are never called at request time.
15
+ */
16
+ export declare const STUB_BUILD_TIME_MODULE: string;
@@ -0,0 +1,2 @@
1
+ const e=[`@preact/preset-vite`,`@vitejs/plugin-react`,`@vitejs/plugin-vue`,`@sveltejs/vite-plugin-svelte`,`vite-plugin-solid`,`@builder.io/qwik/optimizer`,`vite-prerender-plugin`],t=[`chokidar`,`fsevents`],n=[`oxc-parser`,`oxc-transform`,`oxc-minify`],r=[`@oxc-parser/`,`@oxc-transform/`,`@oxc-minify/`];function i(e,t){return e===t||e.startsWith(`${t}/`)}export function shouldStubBuildTimeSpecifier(a){return(a.split(`?`)[0]??a).endsWith(`.node`)||e.some(e=>i(a,e))||t.some(e=>i(a,e))||n.some(e=>i(a,e))?!0:r.some(e=>a.startsWith(e))}export const STUB_BUILD_TIME_MODULE=[`const noop = () => ({});`,`export default noop;`,`export const parseSync = noop;`,`export const visitorKeys = {};`,`export const transform = noop;`,`export const minify = noop;`,`export const isRunnableDevEnvironment = () => false;`,`export const watch = () => ({ on() {}, close() {} });`,`export const FSWatcher = class {};`].join(`
2
+ `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useavalon/avalon",
3
- "version": "0.3.2-canary.13",
3
+ "version": "0.3.2-canary.15",
4
4
  "description": "Multi-framework islands architecture for the modern web",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -164,7 +164,7 @@
164
164
  },
165
165
  "dependencies": {
166
166
  "@mdx-js/rollup": "^3.0.0",
167
- "@useavalon/core": "^0.3.2-canary.13",
167
+ "@useavalon/core": "^0.3.2-canary.15",
168
168
  "h3": "^2.0.1-rc.16",
169
169
  "marked": "^17.0.4",
170
170
  "oxc-parser": "^0.120.0",