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

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.
Files changed (52) hide show
  1. package/dist/src/build/island-manifest.d.ts +3 -0
  2. package/dist/src/build/island-manifest.js +1 -1
  3. package/dist/src/client/custom-directives.js +1 -1
  4. package/dist/src/client/hydrate-runtime.d.ts +29 -0
  5. package/dist/src/client/hydrate-runtime.js +1 -0
  6. package/dist/src/client/hydration-mode.d.ts +11 -0
  7. package/dist/src/client/hydration-mode.js +1 -0
  8. package/dist/src/client/main-slim.js +1 -0
  9. package/dist/src/client/main.js +2 -15
  10. package/dist/src/client/router/a11y.d.ts +9 -0
  11. package/dist/src/client/router/a11y.js +1 -0
  12. package/dist/src/client/router/eligibility.d.ts +32 -0
  13. package/dist/src/client/router/eligibility.js +1 -0
  14. package/dist/src/client/router/events.d.ts +33 -0
  15. package/dist/src/client/router/events.js +1 -0
  16. package/dist/src/client/router/forms.d.ts +25 -0
  17. package/dist/src/client/router/forms.js +1 -0
  18. package/dist/src/client/router/index.d.ts +20 -0
  19. package/dist/src/client/router/index.js +1 -0
  20. package/dist/src/client/router/opt-out.d.ts +30 -0
  21. package/dist/src/client/router/opt-out.js +1 -0
  22. package/dist/src/client/router/persist.d.ts +21 -0
  23. package/dist/src/client/router/persist.js +1 -0
  24. package/dist/src/client/router/prefetch.d.ts +25 -0
  25. package/dist/src/client/router/prefetch.js +1 -0
  26. package/dist/src/client/router/swap.d.ts +21 -0
  27. package/dist/src/client/router/swap.js +1 -0
  28. package/dist/src/client/router/transitions.d.ts +17 -0
  29. package/dist/src/client/router/transitions.js +1 -0
  30. package/dist/src/client/server-islands-boot.d.ts +12 -0
  31. package/dist/src/client/server-islands-boot.js +1 -0
  32. package/dist/src/client/types/vite-virtual-modules.d.ts +7 -0
  33. package/dist/src/islands/island.d.ts +15 -3
  34. package/dist/src/islands/island.js +1 -1
  35. package/dist/src/islands/types.d.ts +2 -0
  36. package/dist/src/nitro/renderer.d.ts +2 -1
  37. package/dist/src/nitro/renderer.js +20 -20
  38. package/dist/src/nitro/types.d.ts +5 -0
  39. package/dist/src/post-build/index.d.ts +6 -0
  40. package/dist/src/post-build/index.js +3 -3
  41. package/dist/src/schemas/routing/index.d.ts +2 -0
  42. package/dist/src/schemas/routing.d.ts +1 -0
  43. package/dist/src/schemas/routing.js +1 -1
  44. package/dist/src/server-islands/renderer.js +6 -5
  45. package/dist/src/types/island-prop.d.ts +12 -3
  46. package/dist/src/types/virtual-modules.d.ts +15 -4
  47. package/dist/src/vite-plugin/config.js +1 -1
  48. package/dist/src/vite-plugin/nitro-integration.js +18 -18
  49. package/dist/src/vite-plugin/plugin.d.ts +2 -0
  50. package/dist/src/vite-plugin/plugin.js +1 -1
  51. package/dist/src/vite-plugin/types.d.ts +12 -0
  52. package/package.json +6 -2
@@ -1 +1 @@
1
- import{getIslandBundlePath as e}from"../build/island-manifest.js";import{shellH as t,shellFragment as n}from"../render/shell-engine.js";import{addToManifest as r,generateComponentId as i}from"../server-islands/manifest.js";import{renderServerIsland as a}from"../server-islands/renderer.js";import{devError as o,devLog as s,devWarn as c,isDev as l,logRenderTiming as u}from"../utils/dev-logger.js";import{analyzeComponentFile as d,renderComponentSSROnly as f}from"./component-analysis.js";import{detectFramework as p}from"./framework-detection.js";import{isCustomDirective as m,serializeDirectiveScript as h}from"./hydration-directives.js";import{detectFrameworkFromPath as g,loadIntegration as _}from"./integration-loader.js";import{addModulepreload as v}from"./modulepreload-collector.js";import{generatePerIslandScript as y}from"./per-island-script.js";import{addUniversalCSS as b}from"./universal-css-collector.js";import{addUniversalHead as x}from"./universal-head-collector.js";function S(e,r){return r==null?e:t(n(),{key:r},e)}export function withListKey(e,t){return S(t,e)}function w(e){return`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}`}function T(){return globalThis.__avalonHydrationMode===void 0?globalThis.__viteDevServer?!1:typeof __AVALON_PER_ISLAND__<`u`?__AVALON_PER_ISLAND__:!l():globalThis.__avalonHydrationMode===`per-island`}function E(r,i){if(!T()||i.shouldSkipHydration)return r;let a=e(i.src);i.condition===`on:client`&&v(a);let o=m(i.condition),s=o?h(i.condition):void 0,c=y({islandId:i.islandId,componentSrc:a,framework:i.framework,condition:i.condition,conditionArg:i.conditionArg,propsJson:JSON.stringify(i.props),isCustomDirective:o,directiveScript:s??void 0});return t(n(),null,r,t(`div`,{dangerouslySetInnerHTML:{__html:c},"data-island-script":``}))}function D(e){let t={};e.renderId&&(t[`data-solid-render-id`]=e.renderId);let n=e.metadata;return n?.tagName&&(t[`data-tag-name`]=n.tagName),t}function O(t,n,r,i,a){let o={"data-condition":n,"data-src":e(t),"data-props":JSON.stringify(r),"data-render-strategy":`hydrate`,...D(i)};if(m(n)){o[`data-custom-directive`]=n;let e=h(n);e&&(o[`data-directive-script`]=e)}return a&&(o[`data-condition-arg`]=a),o}function k(e){return e.startsWith(`<script`)?`script`:e.startsWith(`<style`)?`style`:e.startsWith(`<meta`)?`meta`:e.startsWith(`<link`)?`link`:e.includes(`window._$HY`)||e.includes(`_$HY=`)?`script`:`other`}function A(e){let t=e.match(/<style[^>]*>([\s\S]*?)<\/style>/i);return t?t[1].trim():null}function j(e,t,n,r){if(e.css&&b(e.css,t,n,e.scopeId),e.head){let i=e.head.trim(),a=k(i);if(a===`style`){let a=A(i);a&&(s(`${r} Extracting CSS from head <style> tag`),b(a,t,n,e.scopeId));return}x(e.head,t,n,a)}}function M(e){let{islandId:n,detectedFramework:r,shouldSkipHydration:i,src:a,condition:o,conditionArg:c,props:l,hydrationData:u,children:d}=e,f={id:n,"data-framework":r},p=i?{"data-render-strategy":`ssr-only`}:O(a,o,l,u,c);r===`lit`&&s(`🔍 [Island Component] ${a} - Lit hydration data:`,{hydrationDataKeys:Object.keys(u),metadata:u.metadata});let m={...f,...p},h;return h=typeof d==`string`?t(`avalon-island`,{...m,dangerouslySetInnerHTML:{__html:d}}):t(`avalon-island`,m,d),E(h,{islandId:n,src:a,condition:o,conditionArg:c,props:l,framework:r,shouldSkipHydration:i})}function N(n){let{islandId:r,detectedFramework:i,shouldSkipHydration:a,src:o,condition:s,props:c,hydrationData:l,conditionArg:u}=n;if(a)return t(`avalon-island`,{id:r,"data-render-strategy":`ssr-only`,"data-framework":i});let d={id:r,"data-condition":s,"data-src":e(o),"data-props":JSON.stringify(c),"data-render-strategy":`hydrate`,"data-framework":i,...D(l)};if(m(s)){d[`data-custom-directive`]=s;let e=h(s);e&&(d[`data-directive-script`]=e)}return u&&(d[`data-condition-arg`]=u),E(t(`avalon-island`,d),{islandId:r,src:o,condition:s,conditionArg:u,props:c,framework:i,shouldSkipHydration:a})}export default function P({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:a=t!==`on:client`,framework:o,ssrOnly:l=!1,renderOptions:u={},hydrationData:d={}}){let f=w(e),p=l||!!u.forceSSROnly,m=o||g(e),h=i!=null&&i!==``;return s(`🔍 [Island Component] ${e}`,{ssr:a,ssrOnly:l,hasChildren:h,framework:o,condition:t}),a&&h?M({islandId:f,detectedFramework:m,shouldSkipHydration:p,src:e,condition:t,conditionArg:n,props:r,hydrationData:d,children:i}):(a&&!h&&p&&c(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),N({islandId:f,detectedFramework:m,shouldSkipHydration:p,src:e,condition:t,props:r,hydrationData:d,conditionArg:n}))}function F(n,r){let i=r instanceof Error?r.message:String(r);return o(`🚨 Island SSR failed for ${n}:`,r),r instanceof Error&&r.stack&&o(`Stack trace:`,r.stack),t(`avalon-island`,{id:w(n),"data-src":e(n),"data-ssr-error":i,"data-render-strategy":`client-only`})}async function I({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:s,ssrOnly:c,renderOptions:u,component:d}){let f=`🏝️ [${e}]`;if(!a||i)return P({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:s,ssrOnly:c,renderOptions:u});let p;try{p=await _(s)}catch(i){return o(`${f} Failed to load ${s} integration:`,i),P({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u})}try{let i=await p.render({component:d??null,props:r,src:e,condition:t,ssrOnly:c,viteServer:globalThis.__viteDevServer,isDev:l()});return j(i,e,s,f),P({src:e,condition:t,conditionArg:n,props:r,children:i.html,ssr:!0,framework:s,ssrOnly:c,renderOptions:u,hydrationData:c?void 0:i.hydrationData})}catch(i){return o(`${f} Fast path SSR failed:`,i),P({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u})}}async function L(e,t,n,r){if(t||n.detectScripts===!1)return t;try{let t=await d(e,n);if(t.decision.warnings?.length)for(let e of t.decision.warnings)c(`${r} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return c(`${r} Component analysis failed:`,e),t}}async function R(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?p(e):`unknown`}async function z(e,t,n,r,i,a,o){let s=await R(e),c=s,u=await(await B(s,a)).render({component:o??null,props:n,src:e,condition:t,ssrOnly:r,viteServer:globalThis.__viteDevServer,isDev:l()});return j(u,e,s,a),P({src:e,condition:t,props:n,children:u.html,ssr:!0,framework:c,ssrOnly:r,renderOptions:i,hydrationData:r?void 0:u.hydrationData})}async function B(e,t){try{s(`${t} Loading integration for framework: ${e}`);let n=await _(e);return s(`${t} ✅ Integration loaded successfully`),n}catch(n){throw o(`${t} Failed to load ${e} integration:`,n),Error(`Failed to load integration for framework '${e}'. Make sure @useavalon/${e} is installed.\nInstall it with: deno add @useavalon/${e}`,{cause:n})}}export async function renderIsland({src:o,condition:s=`on:client`,conditionArg:c,props:d={},children:f,ssr:p=s!==`on:client`,framework:m,ssrOnly:h=!1,renderOptions:_={},component:v,server:y,island:b,key:x}){let C=l()?performance.now():0,w=`🏝️ [${o}]`;try{if(y){let s=i(o);r(s,o);let c=m||g(o),l=a(s,d,y,b,b?e(o):void 0,o,c);return S(t(n(),null,t(`div`,{dangerouslySetInnerHTML:{__html:l},"data-server-island-wrapper":``})),x)}return h&&!p&&(p=!0),S(m?await I({src:o,condition:s,conditionArg:c,props:d,children:f,ssr:p,framework:m,ssrOnly:h,renderOptions:_,component:v}):await V({src:o,condition:s,conditionArg:c,props:d,children:f,ssr:p,ssrOnly:h,renderOptions:_,logPrefix:w,component:v}),x)}catch(e){return S(F(o,e),x)}finally{l()&&u(o,performance.now()-C)}}async function V(e){let{src:t,condition:n,conditionArg:r,props:i,children:a,ssr:c,ssrOnly:l,renderOptions:u,logPrefix:d,component:f}=e;if(s(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:c,ssrOnly:l,hasChildren:!!a,condition:n}),await L(t,l,u,d))return H(t,n,i,a,c,u,d);if(!c||a)return P({src:t,condition:n,conditionArg:r,props:i,children:a,ssr:c,renderOptions:u});try{return await z(t,n,i,l,u,d,f)}catch(e){let a=await R(t);return o(`${d} Framework rendering failed:`,e),P({src:t,condition:n,conditionArg:r,props:i,ssr:!1,framework:a,renderOptions:u})}}function H(e,t,n,r,i,a,s){return i&&!r?f({src:e,condition:t,props:n,renderOptions:a}).catch(r=>(o(`${s} SSR failed for SSR-only component:`,r),P({src:e,condition:t,props:n,ssr:!1,ssrOnly:!0,renderOptions:a}))):P({src:e,condition:t,props:n,children:r,ssr:i,ssrOnly:!0,renderOptions:a})}
1
+ import{getIslandBundlePath as e}from"../build/island-manifest.js";import{shellH as t,shellFragment as n}from"../render/shell-engine.js";import{addToManifest as r,generateComponentId as i}from"../server-islands/manifest.js";import{renderServerIsland as a}from"../server-islands/renderer.js";import{devError as o,devLog as s,devWarn as c,isDev as l,logRenderTiming as u}from"../utils/dev-logger.js";import{analyzeComponentFile as d,renderComponentSSROnly as f}from"./component-analysis.js";import{detectFramework as p}from"./framework-detection.js";import{isCustomDirective as m,serializeDirectiveScript as h}from"./hydration-directives.js";import{detectFrameworkFromPath as g,loadIntegration as _}from"./integration-loader.js";import{addModulepreload as v}from"./modulepreload-collector.js";import{generatePerIslandScript as y}from"./per-island-script.js";import{addUniversalCSS as b}from"./universal-css-collector.js";import{addUniversalHead as x}from"./universal-head-collector.js";function S(e,r){return r==null?e:t(n(),{key:r},e)}export function withListKey(e,t){return S(t,e)}let w=0;function T(e,t){return t||`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}-${w++}`}function E(e,t){if(e===void 0)return;if(e===!0)return t;let n=e.trim();return n.length>0?n:void 0}function D(){return globalThis.__avalonHydrationMode===void 0?globalThis.__viteDevServer?!1:typeof __AVALON_PER_ISLAND__<`u`?__AVALON_PER_ISLAND__:!l():globalThis.__avalonHydrationMode===`per-island`}function O(r,i){if(!D()||i.shouldSkipHydration)return r;let a=e(i.src);i.condition===`on:client`&&v(a);let o=m(i.condition),s=o?h(i.condition):void 0,c=y({islandId:i.islandId,componentSrc:a,framework:i.framework,condition:i.condition,conditionArg:i.conditionArg,propsJson:JSON.stringify(i.props),isCustomDirective:o,directiveScript:s??void 0});return t(n(),null,r,t(`div`,{dangerouslySetInnerHTML:{__html:c},"data-island-script":``}))}function k(e){let t={};e.renderId&&(t[`data-solid-render-id`]=e.renderId);let n=e.metadata;return n?.tagName&&(t[`data-tag-name`]=n.tagName),t}function A(t,n,r,i,a){let o={"data-condition":n,"data-src":e(t),"data-props":JSON.stringify(r),"data-render-strategy":`hydrate`,...k(i)};if(m(n)){o[`data-custom-directive`]=n;let e=h(n);e&&(o[`data-directive-script`]=e)}return a&&(o[`data-condition-arg`]=a),o}function j(e){return e.startsWith(`<script`)?`script`:e.startsWith(`<style`)?`style`:e.startsWith(`<meta`)?`meta`:e.startsWith(`<link`)?`link`:e.includes(`window._$HY`)||e.includes(`_$HY=`)?`script`:`other`}function M(e){let t=/<style[^>]*>([\s\S]*?)<\/style>/i.exec(e);return t?t[1].trim():null}function N(e,t,n,r){if(e.css&&b(e.css,t,n,e.scopeId),e.head){let i=e.head.trim(),a=j(i);if(a===`style`){let a=M(i);a&&(s(`${r} Extracting CSS from head <style> tag`),b(a,t,n,e.scopeId));return}x(e.head,t,n,a)}}function P(e){let{islandId:n,detectedFramework:r,shouldSkipHydration:i,src:a,condition:o,conditionArg:c,props:l,hydrationData:u,children:d,persist:f}=e,p={id:n,"data-framework":r},m=E(f,a);m&&(p[`data-router-persist`]=m);let h=i?{"data-render-strategy":`ssr-only`}:A(a,o,l,u,c);r===`lit`&&s(`🔍 [Island Component] ${a} - Lit hydration data:`,{hydrationDataKeys:Object.keys(u),metadata:u.metadata});let g={...p,...h},_;return _=typeof d==`string`?t(`avalon-island`,{...g,dangerouslySetInnerHTML:{__html:d}}):t(`avalon-island`,g,d),O(_,{islandId:n,src:a,condition:o,conditionArg:c,props:l,framework:r,shouldSkipHydration:i})}function F(n){let{islandId:r,detectedFramework:i,shouldSkipHydration:a,src:o,condition:s,props:c,hydrationData:l,conditionArg:u,persist:d}=n,f=E(d,o);if(a)return t(`avalon-island`,{id:r,"data-render-strategy":`ssr-only`,"data-framework":i,...f?{"data-router-persist":f}:{}});let p={id:r,"data-condition":s,"data-src":e(o),"data-props":JSON.stringify(c),"data-render-strategy":`hydrate`,"data-framework":i,...k(l)};if(f&&(p[`data-router-persist`]=f),m(s)){p[`data-custom-directive`]=s;let e=h(s);e&&(p[`data-directive-script`]=e)}return u&&(p[`data-condition-arg`]=u),O(t(`avalon-island`,p),{islandId:r,src:o,condition:s,conditionArg:u,props:c,framework:i,shouldSkipHydration:a})}export default function I({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:a=t!==`on:client`,framework:o,ssrOnly:l=!1,renderOptions:u={},hydrationData:d={},id:f,persist:p}){let m=T(e,f),h=l||!!u.forceSSROnly,_=o||g(e),v=i!=null&&i!==``;return s(`🔍 [Island Component] ${e}`,{ssr:a,ssrOnly:l,hasChildren:v,framework:o,condition:t}),a&&v?P({islandId:m,detectedFramework:_,shouldSkipHydration:h,src:e,condition:t,conditionArg:n,props:r,hydrationData:d,children:i,persist:p}):(a&&!v&&h&&c(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),F({islandId:m,detectedFramework:_,shouldSkipHydration:h,src:e,condition:t,props:r,hydrationData:d,conditionArg:n,persist:p}))}function L(n,r){let i=r instanceof Error?r.message:String(r);return o(`🚨 Island SSR failed for ${n}:`,r),r instanceof Error&&r.stack&&o(`Stack trace:`,r.stack),t(`avalon-island`,{id:T(n),"data-src":e(n),"data-ssr-error":i,"data-render-strategy":`client-only`})}async function R({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:s,ssrOnly:c,renderOptions:u,component:d,id:f,persist:p}){let m=`🏝️ [${e}]`;if(!a||i)return I({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:s,ssrOnly:c,renderOptions:u,id:f,persist:p});let h;try{h=await _(s)}catch(i){return o(`${m} Failed to load ${s} integration:`,i),I({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u,id:f,persist:p})}try{let i=await h.render({component:d??null,props:r,src:e,condition:t,ssrOnly:c,viteServer:globalThis.__viteDevServer,isDev:l()});return N(i,e,s,m),I({src:e,condition:t,conditionArg:n,props:r,children:i.html,ssr:!0,framework:s,ssrOnly:c,renderOptions:u,hydrationData:c?void 0:i.hydrationData,id:f,persist:p})}catch(i){return o(`${m} Fast path SSR failed:`,i),I({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u,id:f,persist:p})}}async function z(e,t,n,r){if(t||n.detectScripts===!1)return t;try{let t=await d(e,n);if(t.decision.warnings?.length)for(let e of t.decision.warnings)c(`${r} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return c(`${r} Component analysis failed:`,e),t}}async function B(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?p(e):`unknown`}async function V(e){let{src:t,condition:n,props:r,ssrOnly:i,renderOptions:a,logPrefix:o,preloadedComponent:s,id:c,persist:u}=e,d=await B(t),f=d,p=await(await H(d,o)).render({component:s??null,props:r,src:t,condition:n,ssrOnly:i,viteServer:globalThis.__viteDevServer,isDev:l()});return N(p,t,d,o),I({src:t,condition:n,props:r,children:p.html,ssr:!0,framework:f,ssrOnly:i,renderOptions:a,hydrationData:i?void 0:p.hydrationData,id:c,persist:u})}async function H(e,t){try{s(`${t} Loading integration for framework: ${e}`);let n=await _(e);return s(`${t} ✅ Integration loaded successfully`),n}catch(n){throw o(`${t} Failed to load ${e} integration:`,n),Error(`Failed to load integration for framework '${e}'. Make sure @useavalon/${e} is installed.\nInstall it with: deno add @useavalon/${e}`,{cause:n})}}export async function renderIsland({src:o,condition:s=`on:client`,conditionArg:c,props:d={},children:f,ssr:p=s!==`on:client`,framework:m,ssrOnly:h=!1,renderOptions:_={},component:v,server:y,island:b,key:x,id:C,persist:w}){let T=l()?performance.now():0,E=`🏝️ [${o}]`;try{if(y){let s=i(o);r(s,o);let c=m||g(o),l=a(s,d,y,b,b?e(o):void 0,o,c);return S(t(n(),null,t(`div`,{dangerouslySetInnerHTML:{__html:l},"data-server-island-wrapper":``})),x)}return h&&!p&&(p=!0),S(m?await R({src:o,condition:s,conditionArg:c,props:d,children:f,ssr:p,framework:m,ssrOnly:h,renderOptions:_,component:v,id:C,persist:w}):await U({src:o,condition:s,conditionArg:c,props:d,children:f,ssr:p,ssrOnly:h,renderOptions:_,logPrefix:E,component:v,id:C,persist:w}),x)}catch(e){return S(L(o,e),x)}finally{l()&&u(o,performance.now()-T)}}async function U(e){let{src:t,condition:n,conditionArg:r,props:i,children:a,ssr:c,ssrOnly:l,renderOptions:u,logPrefix:d,component:f,id:p,persist:m}=e;if(s(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:c,ssrOnly:l,hasChildren:!!a,condition:n}),await z(t,l,u,d))return W({src:t,condition:n,props:i,children:a,ssr:c,renderOptions:u,logPrefix:d,id:p,persist:m});if(!c||a)return I({src:t,condition:n,conditionArg:r,props:i,children:a,ssr:c,renderOptions:u,id:p,persist:m});try{return await V({src:t,condition:n,props:i,ssrOnly:l,renderOptions:u,logPrefix:d,preloadedComponent:f,id:p,persist:m})}catch(e){let a=await B(t);return o(`${d} Framework rendering failed:`,e),I({src:t,condition:n,conditionArg:r,props:i,ssr:!1,framework:a,renderOptions:u,id:p,persist:m})}}function W(e){let{src:t,condition:n,props:r,children:i,ssr:a,renderOptions:s,logPrefix:c,id:l,persist:u}=e;return a&&!i?f({src:t,condition:n,props:r,renderOptions:s}).catch(e=>(o(`${c} SSR failed for SSR-only component:`,e),I({src:t,condition:n,props:r,ssr:!1,ssrOnly:!0,renderOptions:s,id:l,persist:u}))):I({src:t,condition:n,props:r,children:i,ssr:a,ssrOnly:!0,renderOptions:s,id:l,persist:u})}
@@ -31,6 +31,8 @@ export interface IslandProps {
31
31
  renderOptions?: AnalyzerOptions;
32
32
  /** Server island configuration — defers rendering to a server endpoint after page load */
33
33
  server?: ServerIslandProp;
34
+ /** Explicit HTML id for this island instance. Unique per instance when omitted. */
35
+ id?: string;
34
36
  /** React/Preact list key — set on the host VNode, never serialized into props */
35
37
  key?: string | number;
36
38
  }
@@ -86,6 +86,7 @@ export interface RenderHandlerOptions {
86
86
  */
87
87
  enableCustomErrorPages?: boolean;
88
88
  }
89
+ type WrapWithLayouts = NonNullable<RenderHandlerOptions["wrapWithLayouts"]>;
89
90
  /**
90
91
  * Creates a render context from an H3 event
91
92
  *
@@ -300,7 +301,7 @@ export interface NitroCatchAllOptions {
300
301
  /** Optional layout resolver */
301
302
  resolveLayouts?: (routePath: string, config: AvalonRuntimeConfig) => Promise<string[]>;
302
303
  /** Wrap rendered page HTML with layout components (same as RenderHandlerOptions) */
303
- wrapWithLayouts?: RenderHandlerOptions["wrapWithLayouts"];
304
+ wrapWithLayouts?: WrapWithLayouts;
304
305
  /**
305
306
  * Enable custom error pages (404.tsx, 500.tsx, _error.tsx)
306
307
  * When enabled, the renderer will look for custom error pages in the pages directory
@@ -1,4 +1,4 @@
1
- import{getRequestURL as e}from"h3";import{inlineCriticalCSS as t}from"../islands/critical-css.js";import{injectModulepreloadLinks as n}from"../islands/modulepreload-collector.js";import{discoverScopedMiddleware as r,executeScopedMiddleware as i}from"../middleware/index.js";import{renderShell as a}from"../render/shell-engine.js";import{discoverErrorPages as o,handleRenderError as s}from"./error-handler.js";import{createNotFoundError as c,isHttpError as l}from"./types.js";function u(e,t){return{...e.context.params??{},...t.params}}async function d(e,t,n,r){return e.context.route||(r?r(t,n):A(t,n))}export function createRenderContext(e,t={}){let n=getRequestURL(e);return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:toRequest(e),event:e}}export function createRenderContextFromRequest(e,t={}){let n=new URL(e.url,`http://localhost`),r={method:e.method,path:n.pathname+n.search,context:{params:t}};return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:e,event:r}}export function getRequestURL(t){return new URL(e(t).pathname,`http://localhost`)}export function toRequest(e){let t=getRequestURL(e);return new Request(t,{method:e.req.method,headers:getRequestHeaders(e)})}export function getRequestHeaders(e){return new Headers}export function setResponseHeader(e,t,n){e.context.responseHeaders||(e.context.responseHeaders={}),e.context.responseHeaders[t]=n}export function createErrorResponse(e,t){let n=l(e)?e.statusCode:500;if(t){let t=v(e,n);return new Response(t,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}let r=y(n);return new Response(r,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}function v(e,t){return`<!DOCTYPE html>
1
+ import{getRequestURL as e}from"h3";import{clientNavigationResponseHeaders as t,isClientNavigationDisabled as n,stampClientNavigationOptOut as r}from"../client/router/opt-out.js";import{inlineCriticalCSS as i}from"../islands/critical-css.js";import{injectModulepreloadLinks as a}from"../islands/modulepreload-collector.js";import{discoverScopedMiddleware as o,executeScopedMiddleware as s}from"../middleware/index.js";import{renderShell as c}from"../render/shell-engine.js";import{discoverErrorPages as l,handleRenderError as u}from"./error-handler.js";import{createNotFoundError as d,isHttpError as f}from"./types.js";function p(e,t){return{...e.context.params??{},...t.params}}async function m(e,t,n,r){return e.context.route||(r?r(t,n):L(t,n))}export function createRenderContext(e,t={}){let n=getRequestURL(e);return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:toRequest(e),event:e}}export function createRenderContextFromRequest(e,t={}){let n=new URL(e.url,`http://localhost`),r={method:e.method,path:n.pathname+n.search,context:{params:t}};return{url:n,params:t,query:Object.fromEntries(n.searchParams),request:e,event:r}}export function getRequestURL(t){return new URL(e(t).pathname,`http://localhost`)}export function toRequest(e){let t=getRequestURL(e);return new Request(t,{method:e.req.method,headers:getRequestHeaders(e)})}export function getRequestHeaders(e){return new Headers}export function setResponseHeader(e,t,n){e.context.responseHeaders||(e.context.responseHeaders={}),e.context.responseHeaders[t]=n}function g(e){return{"Content-Type":`text/html; charset=utf-8`,...t(n(e))}}function _(e,t){return a(i(injectHydrationScript(e,t)))}async function v(e,t,n,r){let i=await renderPage(e,t,{},r);return new Response(_(i.html,n),{status:i.statusCode,headers:i.headers})}async function y(e,t,n){let r=await renderPageStream(e,t,{onShellReady:()=>{for(let[t,r]of Object.entries(g(e)))setResponseHeader(n,t,r)}});return new Response(r,{headers:g(e)})}async function b(e,t,n,r,i,a){return i&&a?y(e,t,a):v(e,t,n,r)}async function x(e,t,n,r){try{return await e(t)}catch(i){try{return await e(n)}catch(e){return r&&(console.debug(`[renderer] Page not found: ${t}`,i),console.debug(`[renderer] Index fallback not found: ${n}`,e)),null}}}export function createErrorResponse(e,t){let n=f(e)?e.statusCode:500;if(t){let t=S(e,n);return new Response(t,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}let r=C(n);return new Response(r,{status:n,headers:{"Content-Type":`text/html; charset=utf-8`}})}function S(e,t){return`<!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8">
@@ -56,15 +56,15 @@ import{getRequestURL as e}from"h3";import{inlineCriticalCSS as t}from"../islands
56
56
  <body>
57
57
  <div class="error-container">
58
58
  <div class="status-code">${t}</div>
59
- <h1>${b(t)}</h1>
60
- <p class="message">${x(e.message)}</p>
59
+ <h1>${w(t)}</h1>
60
+ <p class="message">${T(e.message)}</p>
61
61
  ${e.stack?`
62
62
  <div class="stack-title">Stack Trace</div>
63
- <pre>${x(e.stack)}</pre>
63
+ <pre>${T(e.stack)}</pre>
64
64
  `:``}
65
65
  </div>
66
66
  </body>
67
- </html>`}function y(e){return`<!DOCTYPE html>
67
+ </html>`}function C(e){return`<!DOCTYPE html>
68
68
  <html lang="en">
69
69
  <head>
70
70
  <meta charset="utf-8">
@@ -113,47 +113,47 @@ import{getRequestURL as e}from"h3";import{inlineCriticalCSS as t}from"../islands
113
113
  <body>
114
114
  <div class="error-container">
115
115
  <div class="status-code">${e}</div>
116
- <h1>${b(e)}</h1>
116
+ <h1>${w(e)}</h1>
117
117
  <p><a href="/">Return to home</a></p>
118
118
  </div>
119
119
  </body>
120
- </html>`}function b(e){return{400:`Bad Request`,401:`Unauthorized`,403:`Forbidden`,404:`Page Not Found`,405:`Method Not Allowed`,500:`Internal Server Error`,502:`Bad Gateway`,503:`Service Unavailable`}[e]||`Error`}function x(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#039;`)}export function extractIslandMarkers(e){let t=[],n=/<[^>]*data-framework="([^"]+)"[^>]*>/g,r=n.exec(e);for(;r!==null;){let i=r[0],a=r[1],o=/data-src="([^"]+)"/.exec(i),s=o?o[1]:``,c=/data-props="([^"]*)"/.exec(i),l=c?c[1]:void 0,u=/data-hydrate="([^"]+)"/.exec(i),d=u?u[1]:void 0;t.push({framework:a,src:s,props:l,hydrate:d}),r=n.exec(e)}return t}export function ensureHydrationMarkers(e,t){let n=e;return t.framework&&!n.includes(`data-framework=`)&&(n=n.replace(/>/,` data-framework="${t.framework}">`)),t.src&&!n.includes(`data-src=`)&&(n=n.replace(/>/,` data-src="${t.src}">`)),t.props!==void 0&&!n.includes(`data-props=`)&&(n=n.replace(/>/,` data-props="${t.props}">`)),n}function S(e){return e.replaceAll(/<div[^>]*\bdata-island-script\b[^>]*>(<script[\s\S]*?<\/script>)<\/div>/g,`$1`)}export function injectHydrationScript(e,t,n={}){if(globalThis.__avalonHydrationMode===`per-island`||!t)return S(e);if(!(e.includes(`data-framework=`)||e.includes(`data-src=`))&&!n.forceInject||[`/src/client/main.js`,`/dist/client.js`,`client/main.js`,`entry-client`].some(t=>e.includes(t)))return e;let r=n.scriptPath||(t?`/src/client/main.js`:`/dist/client.js`),i=[];i.push(`<script type="module" src="${r}"><\/script>`),n.additionalScripts&&i.push(...n.additionalScripts);let a=i.join(`
121
- `);return e.includes(`</body>`)?e.replace(`</body>`,`${a}\n</body>`):e+a}export function validateHydrationMarkers(e){let t=extractIslandMarkers(e),n=e.match(/data-framework="[^"]+"/g)||[],r=e.match(/data-src="[^"]+"/g)||[],i=e.match(/data-props="[^"]*"/g)||[],a=e.includes(`/src/client/main.js`)||e.includes(`/dist/client.js`)||e.includes(`client/main.js`),o=t.every(e=>e.framework&&e.src),s=t.length===0||o&&a;return{hasFrameworkAttr:n.length>0,hasSrcAttr:r.length>0,hasPropsAttr:i.length>0,islandCount:n.length,islands:t,hasClientScript:a,isValid:s}}export function processHydrationRequirements(e,t){let n=injectHydrationScript(e,t);return{html:n,validation:validateHydrationMarkers(n)}}export async function renderPage(e,t,n={},r){try{let i={};return e.getServerSideProps&&(i=await e.getServerSideProps(t)),{html:await C(e,i,t,n,r),statusCode:200,headers:{"Content-Type":`text/html; charset=utf-8`}}}catch(e){throw console.error(`[SSR Error]`,e),n.onError&&e instanceof Error&&n.onError(e),e}}async function C(e,t,n,r,i){let o=e.default,s=e.metadata||{},c=process.env.NODE_ENV!==`production`,l,u=!1;try{let e=o(t);l=e instanceof Promise?await e:e}catch(e){console.error(`[renderer] Error calling page component:`,e),u=!0}let d;if(u)d=`<div>Error rendering page</div>`;else try{d=a(l)}catch(e){console.error(`[renderer] Error rendering page shell:`,e),d=`<div>Error rendering page</div>`}if(i)return await i(d,e,n);let f=c?`
120
+ </html>`}function w(e){return{400:`Bad Request`,401:`Unauthorized`,403:`Forbidden`,404:`Page Not Found`,405:`Method Not Allowed`,500:`Internal Server Error`,502:`Bad Gateway`,503:`Service Unavailable`}[e]||`Error`}function T(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#039;`)}function E(e,t){let n=`${t}="`,r=e.indexOf(n);if(r===-1)return;let i=r+n.length,a=e.indexOf(`"`,i);if(a!==-1)return e.slice(i,a)}export function extractIslandMarkers(e){let t=[],n=0;for(;n<e.length;){let r=e.indexOf(`data-framework="`,n);if(r===-1)break;let i=e.lastIndexOf(`<`,r),a=e.indexOf(`>`,r);if(i===-1||a===-1){n=r+16;continue}let o=e.slice(i,a+1),s=E(o,`data-framework`);if(!s){n=r+16;continue}t.push({framework:s,src:E(o,`data-src`)??``,props:E(o,`data-props`),hydrate:E(o,`data-hydrate`)}),n=a+1}return t}export function ensureHydrationMarkers(e,t){let n=e;return t.framework&&!n.includes(`data-framework=`)&&(n=n.replace(/>/,` data-framework="${t.framework}">`)),t.src&&!n.includes(`data-src=`)&&(n=n.replace(/>/,` data-src="${t.src}">`)),t.props!==void 0&&!n.includes(`data-props=`)&&(n=n.replace(/>/,` data-props="${t.props}">`)),n}function D(e){return e.replaceAll(/<div[^>]*\bdata-island-script\b[^>]*>(<script[\s\S]*?<\/script>)<\/div>/g,`$1`)}export function injectHydrationScript(e,t,n={}){e=D(e);let r=globalThis.__avalonHydrationMode;if(r===`per-island`||r===void 0&&!t||!(e.includes(`data-framework=`)||e.includes(`data-src=`))&&!n.forceInject||[`/src/client/main.js`,`/dist/client.js`,`client/main.js`,`entry-client`].some(t=>e.includes(t)))return e;let i=n.scriptPath||(t?`/src/client/main.js`:`/dist/client.js`),a=[];a.push(`<script type="module" src="${i}"><\/script>`),n.additionalScripts&&a.push(...n.additionalScripts);let o=a.join(`
121
+ `);return e.includes(`</body>`)?e.replace(`</body>`,`${o}\n</body>`):e+o}export function validateHydrationMarkers(e){let t=extractIslandMarkers(e),n=e.match(/data-framework="[^"]+"/g)||[],r=e.match(/data-src="[^"]+"/g)||[],i=e.match(/data-props="[^"]*"/g)||[],a=e.includes(`/src/client/main.js`)||e.includes(`/dist/client.js`)||e.includes(`client/main.js`),o=t.every(e=>e.framework&&e.src),s=t.length===0||o&&a;return{hasFrameworkAttr:n.length>0,hasSrcAttr:r.length>0,hasPropsAttr:i.length>0,islandCount:n.length,islands:t,hasClientScript:a,isValid:s}}export function processHydrationRequirements(e,t){let n=injectHydrationScript(e,t);return{html:n,validation:validateHydrationMarkers(n)}}export async function renderPage(e,t,i={},a){try{let o={};e.getServerSideProps&&(o=await e.getServerSideProps(t));let s=await O(e,o,t,i,a);return n(e)&&(s=r(s)),{html:s,statusCode:200,headers:g(e)}}catch(e){throw console.error(`[SSR Error]`,e),i.onError&&e instanceof Error&&i.onError(e),e}}async function O(e,t,n,r,i){let a=e.default,o=e.metadata||{},s=process.env.NODE_ENV!==`production`,l,u=!1;try{let e=a(t);l=e instanceof Promise?await e:e}catch(e){console.error(`[renderer] Error calling page component:`,e),u=!0}let d;if(u)d=`<div>Error rendering page</div>`;else try{d=c(l)}catch(e){console.error(`[renderer] Error rendering page shell:`,e),d=`<div>Error rendering page</div>`}if(i)return await i(d,e,n);let f=s?`
122
122
  <script type="module" src="/src/client/main.js"><\/script>`:``;return`<!DOCTYPE html>
123
123
  <html lang="en">
124
124
  <head>
125
125
  <meta charset="utf-8">
126
126
  <meta name="viewport" content="width=device-width, initial-scale=1">
127
- <title>${x(String(s.title||`Avalon App`))}</title>
128
- ${s.description?`<meta name="description" content="${x(String(s.description))}">`:``}
127
+ <title>${T(String(o.title||`Avalon App`))}</title>
128
+ ${o.description?`<meta name="description" content="${T(String(o.description))}">`:``}
129
129
  </head>
130
130
  <body>
131
131
  <div id="app">
132
132
  ${d}
133
133
  </div>${f}
134
134
  </body>
135
- </html>`}export async function renderPageStream(e,t,n={}){let r=new TextEncoder,i=null,o={shellSent:!1,contentSent:!1,closed:!1,error:null},s=n.shellReadyTimeout,c=n.allReadyTimeout,l=null,u=null,d=()=>{l&&=(clearTimeout(l),null),u&&=(clearTimeout(u),null)};function f(e,t,n,r,i,a,o){if(n.error=e,a(),console.error(`[Streaming Error]`,{message:e.message,stack:e.stack,shellSent:n.shellSent,isShellError:t,timestamp:new Date().toISOString()}),t&&o.onShellError&&o.onShellError(e),o.onError&&o.onError(e),!n.closed&&r){if(n.shellSent){let t=D(e);r.enqueue(i.encode(t));let n=E();r.enqueue(i.encode(n))}else{let t=v(e,500);r.enqueue(i.encode(t))}n.closed=!0,r.close()}}async function p(s){i=s;let p={};e.getServerSideProps&&(p=await e.getServerSideProps(t));let m=w(e.metadata||{},t);if(o.closed||(s.enqueue(r.encode(m)),o.shellSent=!0,l&&=(clearTimeout(l),null),n.onShellReady&&n.onShellReady()),c&&c>0&&(u=setTimeout(()=>{!o.contentSent&&!o.closed&&f(Error(`All ready timeout after ${c}ms`),!1,o,i,r,d,n)},c)),!o.closed){let t=e.default;if(t&&typeof t==`function`){let n=t(p);if(n&&typeof n.then==`function`)try{let e=a(await n);s.enqueue(r.encode(` <div id="app">${e}</div>\n`))}catch(t){console.error(`[streaming] Async component error:`,t);let n=T(e,p);s.enqueue(r.encode(n))}else{let t=T(e,p);s.enqueue(r.encode(t))}}else{let t=T(e,p);s.enqueue(r.encode(t))}o.contentSent=!0}if(!o.closed){let e=E();s.enqueue(r.encode(e))}d(),n.onAllReady&&!o.closed&&n.onAllReady(),o.closed||(o.closed=!0,s.close())}return new ReadableStream({async start(e){i=e,s&&s>0&&(l=setTimeout(()=>{!o.shellSent&&!o.closed&&f(Error(`Shell ready timeout after ${s}ms`),!0,o,i,r,d,n)},s));try{await p(e)}catch(e){f(e instanceof Error?e:Error(String(e)),!o.shellSent,o,i,r,d,n)}},cancel(){if(d(),!o.closed&&i){o.closed=!0;try{i.close()}catch{}}}})}function w(e,t){return`<!DOCTYPE html>
135
+ </html>`}function k(e,t,i,a,o,s,c){let l=j(i.metadata||{},a),u=n(i)?r(l):l;e.enqueue(t.encode(u)),o.shellSent=!0,s(),c?.()}async function A(e,t,n,r){let i=n.default;if(typeof i!=`function`){e.enqueue(t.encode(M(n,r)));return}let a=i(r);if(a&&typeof a.then==`function`)try{let n=c(await a);e.enqueue(t.encode(` <div id="app">${n}</div>\n`));return}catch(e){console.error(`[streaming] Async component error:`,e)}e.enqueue(t.encode(M(n,r)))}export async function renderPageStream(e,t,n={}){let r=new TextEncoder,i=null,a={shellSent:!1,contentSent:!1,closed:!1,error:null},o=n.shellReadyTimeout,s=n.allReadyTimeout,c=null,l=null,u=()=>{c&&=(clearTimeout(c),null),l&&=(clearTimeout(l),null)};function d(e,t,n,r,i,a,o){if(n.error=e,a(),console.error(`[Streaming Error]`,{message:e.message,stack:e.stack,shellSent:n.shellSent,isShellError:t,timestamp:new Date().toISOString()}),t&&o.onShellError&&o.onShellError(e),o.onError&&o.onError(e),!n.closed&&r){if(n.shellSent){let t=P(e);r.enqueue(i.encode(t));let n=N();r.enqueue(i.encode(n))}else{let t=S(e,500);r.enqueue(i.encode(t))}n.closed=!0,r.close()}}async function f(o){i=o;let f={};e.getServerSideProps&&(f=await e.getServerSideProps(t)),a.closed||k(o,r,e,t,a,()=>{c&&=(clearTimeout(c),null)},n.onShellReady),s&&s>0&&(l=setTimeout(()=>{!a.contentSent&&!a.closed&&d(Error(`All ready timeout after ${s}ms`),!1,a,i,r,u,n)},s)),a.closed||(await A(o,r,e,f),a.contentSent=!0),a.closed||o.enqueue(r.encode(N())),u(),n.onAllReady&&!a.closed&&n.onAllReady(),a.closed||(a.closed=!0,o.close())}return new ReadableStream({async start(e){i=e,o&&o>0&&(c=setTimeout(()=>{!a.shellSent&&!a.closed&&d(Error(`Shell ready timeout after ${o}ms`),!0,a,i,r,u,n)},o));try{await f(e)}catch(e){d(e instanceof Error?e:Error(String(e)),!a.shellSent,a,i,r,u,n)}},cancel(){if(u(),!a.closed&&i){a.closed=!0;try{i.close()}catch{}}}})}function j(e,t){return`<!DOCTYPE html>
136
136
  <html lang="en">
137
137
  <head>
138
138
  <meta charset="utf-8">
139
139
  <meta name="viewport" content="width=device-width, initial-scale=1">
140
- <title>${x(String(e.title||`Avalon App`))}</title>
141
- ${e.description?`<meta name="description" content="${x(String(e.description))}">`:``}
140
+ <title>${T(String(e.title||`Avalon App`))}</title>
141
+ ${e.description?`<meta name="description" content="${T(String(e.description))}">`:``}
142
142
  </head>
143
143
  <body>
144
- `}function T(e,t){let n=e.default;if(n&&typeof n==`function`)try{let e=n(t);if(e&&typeof e.then==`function`){let e=n.name||`Page`;return` <div id="app" data-page="${x(String(e))}" data-props='${x(JSON.stringify(t))}'>
144
+ `}function M(e,t){let n=e.default;if(n&&typeof n==`function`)try{let e=n(t);if(e&&typeof e.then==`function`){let e=n.name||`Page`;return` <div id="app" data-page="${T(String(e))}" data-props='${T(JSON.stringify(t))}'>
145
145
  <!-- Async component — awaiting hydration -->
146
- </div>\n`}return` <div id="app">${a(e)}</div>\n`}catch(e){console.error(`[streaming] Error rendering page component:`,e)}let r=e.default?.name||`Page`;return` <div id="app" data-page="${x(String(r))}" data-props='${x(JSON.stringify(t))}'>
146
+ </div>\n`}return` <div id="app">${c(e)}</div>\n`}catch(e){console.error(`[streaming] Error rendering page component:`,e)}let r=e.default?.name||`Page`;return` <div id="app" data-page="${T(String(r))}" data-props='${T(JSON.stringify(t))}'>
147
147
  <!-- Component render fallback -->
148
- </div>\n`}function E(){return` </body>
149
- </html>`}function D(e){let t=process.env.NODE_ENV!==`production`,n=e.stack?`<pre style="
148
+ </div>\n`}function N(){return` </body>
149
+ </html>`}function P(e){let t=process.env.NODE_ENV!==`production`,n=e.stack?`<pre style="
150
150
  background: #f5f5f5;
151
151
  padding: 10px;
152
152
  border-radius: 4px;
153
153
  overflow-x: auto;
154
154
  font-size: 12px;
155
155
  margin-top: 10px;
156
- ">${x(e.stack)}</pre>`:``;return`
156
+ ">${T(e.stack)}</pre>`:``;return`
157
157
  <div class="streaming-error-boundary" data-error-boundary="true" style="
158
158
  background: #fff3cd;
159
159
  border: 2px solid #ffc107;
@@ -175,10 +175,10 @@ import{getRequestURL as e}from"h3";import{inlineCriticalCSS as t}from"../islands
175
175
  Error Details (Development Mode)
176
176
  </summary>
177
177
  <div style="margin-top: 10px;">
178
- <p><strong>Error:</strong> ${x(e.message)}</p>
178
+ <p><strong>Error:</strong> ${T(e.message)}</p>
179
179
  ${n}
180
180
  </div>
181
181
  </details>
182
182
  `:``}
183
183
  </div>
184
- `}export function createStreamingResponse(e,t={}){let n=new Headers({"Content-Type":`text/html; charset=utf-8`,"Transfer-Encoding":`chunked`,...t.headers});return new Response(e,{status:t.status||200,headers:n})}function O(e,t,n){return async()=>(e.value??=await r({baseDir:t,devMode:n}),e.value)}function k(e,t,n){return async(r,i)=>e?s(r,i,t):createErrorResponse(r,n)}export function createNitroRenderer(e){let{avalonConfig:r,isDev:a=!1,enableCustomErrorPages:s=!0}=e,l={isDev:a,avalonConfig:r,loadPageModule:e.loadPageModule,pagesDir:r.pagesDir};s&&o(l).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let h=O({value:null},r.srcDir||`src`,a),g=k(s,l,a);async function v(o){let s=getRequestURL(o).pathname;if(s.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let l=await i(o,await h(),{devMode:a});if(l)return a&&console.log(`[renderer] Middleware terminated request for ${s}`),l;let p=await d(o,s,r.pagesDir,e.resolvePageRoute);if(!p)return g(c(`Page not found: ${s}`),o);let m=e.loadPageModule?await e.loadPageModule(p.filePath):await j(p.filePath),_=createRenderContext(o,u(o,p));if(e.resolveLayouts&&(_.layoutContext={layouts:await e.resolveLayouts(s,r)}),r.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(m,_,{onShellReady:()=>{setResponseHeader(o,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let r=await renderPage(m,_,{},e.wrapWithLayouts),i=injectHydrationScript(r.html,a);return i=t(i),i=n(i),new Response(i,{status:r.statusCode,headers:r.headers})}}catch(e){return console.error(`[Nitro Renderer Error]`,e),g(e instanceof Error?e:Error(String(e)),o)}}return Object.assign(v,{async fetch(i){let o=new URL(i.url,`http://localhost`).pathname;if(o.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let s=null;if(s=e.resolvePageRoute?await e.resolvePageRoute(o,r.pagesDir):await A(o,r.pagesDir),!s)return createErrorResponse(c(`Page not found: ${o}`),a);let l=await renderPage(e.loadPageModule?await e.loadPageModule(s.filePath):await j(s.filePath),createRenderContextFromRequest(i,s.params),{},e.wrapWithLayouts),u=injectHydrationScript(l.html,a);return u=t(u),u=n(u),new Response(u,{status:l.statusCode,headers:l.headers})}catch(e){return console.error(`[Nitro Renderer .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),a)}}})}async function A(e,t){return e===`/`||e===``?{filePath:`src/pages/index.tsx`,pattern:`/`,params:{}}:{filePath:`src/pages/${e.replace(/^\//,``).replace(/\/$/,``)}.tsx`,pattern:e,params:{}}}async function j(e){return{default:()=>null,metadata:{title:`Avalon Page`}}}export function createNitroCatchAllRenderer(e){let{avalonConfig:r,isDev:a=!1,loadPageModule:s,resolveLayouts:l,enableCustomErrorPages:u=!0}=e,d={isDev:a,avalonConfig:r,loadPageModule:s,pagesDir:r.pagesDir};u&&o(d).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let h=O({value:null},r.srcDir||`src`,a),g=k(u,d,a);async function v(o){let u=getRequestURL(o).pathname;if(u.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let d=await i(o,await h(),{devMode:a});if(d)return a&&console.log(`[renderer] Middleware terminated request for ${u}`),d;let p=o.context.params||{},m=p.slug||u.replace(/^\//,``)||`index`,_=`${r.pagesDir}/${m}.tsx`,v;try{v=await s(_)}catch(e){try{v=await s(`${r.pagesDir}/${m}/index.tsx`)}catch(t){return a&&(console.debug(`[renderer] Page not found: ${_}`,e),console.debug(`[renderer] Index fallback not found: ${r.pagesDir}/${m}/index.tsx`,t)),g(c(`Page not found: ${u}`),o)}}let y=createRenderContext(o,p);if(l&&(y.layoutContext={layouts:await l(u,r)}),r.streaming&&!e.wrapWithLayouts){let e=await renderPageStream(v,y,{onShellReady:()=>{setResponseHeader(o,`Content-Type`,`text/html; charset=utf-8`)}});return new Response(e,{headers:{"Content-Type":`text/html; charset=utf-8`}})}else{let r=await renderPage(v,y,{},e.wrapWithLayouts),i=injectHydrationScript(r.html,a);return i=t(i),i=n(i),new Response(i,{status:r.statusCode,headers:r.headers})}}catch(e){return console.error(`[Nitro Catch-All Renderer Error]`,e),g(e instanceof Error?e:Error(String(e)),o)}}return Object.assign(v,{async fetch(i){let o=new URL(i.url,`http://localhost`).pathname;if(o.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let l=o.replace(/^\//,``)||`index`,u=`${r.pagesDir}/${l}.tsx`,d;try{d=await s(u)}catch{try{d=await s(`${r.pagesDir}/${l}/index.tsx`)}catch{return createErrorResponse(c(`Page not found: ${o}`),a)}}let f=createRenderContextFromRequest(i),m=await renderPage(d,f,{},e.wrapWithLayouts),h=injectHydrationScript(m.html,a);return h=t(h),h=n(h),new Response(h,{status:m.statusCode,headers:m.headers})}catch(e){return console.error(`[Nitro CatchAll .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),a)}}})}export{clearMiddlewareCache as clearRendererMiddlewareCache}from"../middleware/index.js";
184
+ `}export function createStreamingResponse(e,t={}){let n=new Headers({"Content-Type":`text/html; charset=utf-8`,"Transfer-Encoding":`chunked`,...t.headers});return new Response(e,{status:t.status||200,headers:n})}function F(e,t,n){return async()=>(e.value??=await o({baseDir:t,devMode:n}),e.value)}function I(e,t,n){return async(r,i)=>e?u(r,i,t):createErrorResponse(r,n)}export function createNitroRenderer(e){let{avalonConfig:t,isDev:n=!1,enableCustomErrorPages:r=!0}=e,i={isDev:n,avalonConfig:t,loadPageModule:e.loadPageModule,pagesDir:t.pagesDir};r&&l(i).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let a=F({value:null},t.srcDir||`src`,n),o=I(r,i,n);async function c(r){let i=getRequestURL(r).pathname;if(i.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let c=await s(r,await a(),{devMode:n});if(c)return n&&console.log(`[renderer] Middleware terminated request for ${i}`),c;let l=await m(r,i,t.pagesDir,e.resolvePageRoute);if(!l)return o(d(`Page not found: ${i}`),r);let u=e.loadPageModule?await e.loadPageModule(l.filePath):await R(l.filePath),f=createRenderContext(r,p(r,l));return e.resolveLayouts&&(f.layoutContext={layouts:await e.resolveLayouts(i,t)}),b(u,f,n,e.wrapWithLayouts,!!(t.streaming&&!e.wrapWithLayouts),r)}catch(e){return console.error(`[Nitro Renderer Error]`,e),o(e instanceof Error?e:Error(String(e)),r)}}return Object.assign(c,{async fetch(r){let i=new URL(r.url,`http://localhost`).pathname;if(i.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let a=null;return a=e.resolvePageRoute?await e.resolvePageRoute(i,t.pagesDir):await L(i,t.pagesDir),a?v(e.loadPageModule?await e.loadPageModule(a.filePath):await R(a.filePath),createRenderContextFromRequest(r,a.params),n,e.wrapWithLayouts):createErrorResponse(d(`Page not found: ${i}`),n)}catch(e){return console.error(`[Nitro Renderer .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}async function L(e,t){return e===`/`||e===``?{filePath:`src/pages/index.tsx`,pattern:`/`,params:{}}:{filePath:`src/pages/${e.replace(/^\//,``).replace(/\/$/,``)}.tsx`,pattern:e,params:{}}}async function R(e){return{default:()=>null,metadata:{title:`Avalon Page`}}}export function createNitroCatchAllRenderer(e){let{avalonConfig:t,isDev:n=!1,loadPageModule:r,resolveLayouts:i,enableCustomErrorPages:a=!0}=e,o={isDev:n,avalonConfig:t,loadPageModule:r,pagesDir:t.pagesDir};a&&l(o).catch(e=>{console.warn(`[renderer] Failed to discover error pages:`,e)});let c=F({value:null},t.srcDir||`src`,n),u=I(a,o,n);async function f(a){let o=getRequestURL(a).pathname;if(o.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let l=await s(a,await c(),{devMode:n});if(l)return n&&console.log(`[renderer] Middleware terminated request for ${o}`),l;let f=a.context.params||{},p=f.slug||o.replace(/^\//,``)||`index`,m=await x(r,`${t.pagesDir}/${p}.tsx`,`${t.pagesDir}/${p}/index.tsx`,n);if(!m)return u(d(`Page not found: ${o}`),a);let h=createRenderContext(a,f);return i&&(h.layoutContext={layouts:await i(o,t)}),b(m,h,n,e.wrapWithLayouts,!!(t.streaming&&!e.wrapWithLayouts),a)}catch(e){return console.error(`[Nitro Catch-All Renderer Error]`,e),u(e instanceof Error?e:Error(String(e)),a)}}return Object.assign(f,{async fetch(i){let a=new URL(i.url,`http://localhost`).pathname;if(a.startsWith(`/_server-islands/`))return new Response(`Not handled by renderer`,{status:404});try{let o=a.replace(/^\//,``)||`index`,s=await x(r,`${t.pagesDir}/${o}.tsx`,`${t.pagesDir}/${o}/index.tsx`,!1);return s?v(s,createRenderContextFromRequest(i),n,e.wrapWithLayouts):createErrorResponse(d(`Page not found: ${a}`),n)}catch(e){return console.error(`[Nitro CatchAll .fetch() Error]`,e),createErrorResponse(e instanceof Error?e:Error(String(e)),n)}}})}export{clearMiddlewareCache as clearRendererMiddlewareCache}from"../middleware/index.js";
@@ -178,6 +178,11 @@ export interface PageModule {
178
178
  getStaticProps?: () => Promise<Record<string, unknown>>;
179
179
  /** Optional getServerSideProps for SSR */
180
180
  getServerSideProps?: (context: NitroRenderContext) => Promise<Record<string, unknown>>;
181
+ /**
182
+ * When `false`, client navigation falls back to a full load for this route.
183
+ * MDX can set the same flag via frontmatter.
184
+ */
185
+ clientNavigation?: boolean;
181
186
  }
182
187
  /**
183
188
  * Page metadata for SEO and configuration
@@ -41,6 +41,12 @@ export interface PostBuildOptions {
41
41
  prerender?: PrerenderConfig | false;
42
42
  /** Port for prerender server (default: 13172) */
43
43
  prerenderPort?: number;
44
+ /**
45
+ * Keep the shared `entry-client` script (and its modulepreload) in
46
+ * prerendered HTML. Required when `clientRouter` is enabled so client
47
+ * navigation can rescan islands after a swap.
48
+ */
49
+ clientRouter?: boolean;
44
50
  }
45
51
  /**
46
52
  * Ensure the SSR client-assets `css` array lists global stylesheets (`index-*.css`
@@ -1,7 +1,7 @@
1
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 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(`
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,p=!1){let m=_(t),h=[d(t,`.netlify`,`functions-internal`,`server`,`server.mjs`),d(t,`.netlify`,`v1`,`functions`,`server`,`server.mjs`),d(t,`.output`,`server`,`index.mjs`),...m?[m]:[]].find(e=>n(e));if(!h){console.log(`[prerender] No server entry found, skipping prerender`);return}let v=[d(t,`.output`,`public`),i].find(e=>n(e));if(!v){console.log(`[prerender] No output directory found, skipping prerender`);return}let y={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},b=`http://localhost:${l}`,x=k(h),S=m!==null&&h===m,C=h;if(x){let e=d(u(h),`main.mjs`);if(!n(e)){console.error(`[prerender] Netlify handler detected but main.mjs not found`);return}C=A(e,l),console.log(`[prerender] Netlify handler detected — using wrapper`)}else S&&(C=A(h,l),console.log(`[prerender] Cloudflare worker detected — using wrapper`));{let e=[h,d(u(h),`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,C)}`);let{spawn:w}=await import(`node:child_process`),T;try{T=w(`node`,[C],{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`]}),T.stdout?.on(`data`,e=>{let t=e.toString().trim();t&&console.log(`[prerender:server] ${t}`)}),T.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(`${b}/`);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 ${b}`)}catch(e){T?.kill(`SIGKILL`),console.error(`[prerender] Failed to start server:`,e.message);return}let E=new Set,D=[...y.routes],O=[],M=[];function N(e){for(let t of y.ignore)if(typeof t==`string`&&e===t||typeof t==`string`&&t.endsWith(`/**`)&&e.startsWith(t.slice(0,-2)))return!0;return!1}try{for(;D.length>0;){let e=D.splice(0,y.concurrency);await Promise.all(e.map(async e=>{let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;if(E.has(t)||(E.add(t),N(t)))return;let n=null;for(let e=1;e<=y.retry;e++)try{let e=await fetch(`${b}${t}`);n={html:await e.text(),status:e.status};break}catch{e<y.retry&&await new Promise(e=>setTimeout(e,y.retryDelay))}if(!n){M.push({route:t,error:`Failed after ${y.retry} attempts`});return}if(n.status>=400){M.push({route:t,error:`Returned ${n.status}`});return}let i=y.autoSubfolderIndex?d(t,`index.html`):`${t}.html`,a=d(v,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(p||(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,``)),p||(o=o.replaceAll(/<link rel="modulepreload" href="\/assets\/entry-client[^"]*\.js">\n?/g,``)),c(a,o),O.push(t),console.log(`[prerender] ✅ ${t} → ${i}`),y.crawlLinks)for(let e of j(n.html)){let t=e.endsWith(`/`)&&e!==`/`?e.slice(0,-1):e;!E.has(t)&&!N(t)&&D.push(t)}}))}}finally{console.log(`[prerender] Shutting down server...`),T?.kill(`SIGKILL`)}if(console.log(`[prerender] Done: ${O.length} page(s) prerendered`+(M.length>0?`, ${M.length} error(s)`:``)),x||S){let e=d(u(h),`_prerender-server.mjs`);n(e)&&(s(e),console.log(`[prerender] Cleaned up wrapper script`))}if(O.length>0){let a=[i,d(t,`.netlify`,`functions-internal`,`server`,`public`),d(t,`.netlify`,`v1`,`functions`,`server`,`public`)].filter(e=>e!==v&&n(u(e)));for(let t of a)for(let i of O){let a=d(i,`index.html`),o=d(v,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
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
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`)}
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,e.clientRouter),N(t,n),F(t,n),await V(t),H(t),console.log(`[post-build] ✅ Complete`)}
@@ -15,6 +15,7 @@ export declare const routingValidators: {
15
15
  generateMetadata?: any;
16
16
  loader?: any;
17
17
  frontmatter?: Record<string, any>;
18
+ clientNavigation?: boolean;
18
19
  };
19
20
  readonly routeDiscoveryOptions: (data: unknown) => {
20
21
  pagesDirectory: string;
@@ -105,6 +106,7 @@ export declare const safeRoutingValidators: {
105
106
  generateMetadata?: any;
106
107
  loader?: any;
107
108
  frontmatter?: Record<string, any>;
109
+ clientNavigation?: boolean;
108
110
  }>;
109
111
  readonly routeDiscoveryOptions: (data: unknown) => import("../index.ts").ValidationResult<{
110
112
  pagesDirectory: string;
@@ -37,6 +37,7 @@ export declare const RoutePageModuleSchema: z.ZodObject<{
37
37
  generateMetadata: z.ZodOptional<z.ZodAny>;
38
38
  loader: z.ZodOptional<z.ZodAny>;
39
39
  frontmatter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
40
+ clientNavigation: z.ZodOptional<z.ZodBoolean>;
40
41
  }, z.core.$strip>;
41
42
  /**
42
43
  * Route Parameters Schema - Parameters extracted from dynamic routes
@@ -1 +1 @@
1
- import{z as e}from"zod";export const RouteTypeSchema=e.enum([`static`,`dynamic`,`catch-all`,`index`,`group`]);export const FileSystemRouteSchema=e.object({pattern:e.any(),filePath:e.string().min(1),routeType:RouteTypeSchema,dynamicSegments:e.array(e.string()),priority:e.number().int().min(0),isPrivate:e.boolean(),routeGroup:e.string().optional()});export const RoutePageModuleSchema=e.object({default:e.any(),layoutConfig:e.any().optional(),generateMetadata:e.any().optional(),loader:e.any().optional(),frontmatter:e.record(e.string(),e.any()).optional()});export const RouteParamsSchema=e.record(e.string(),e.string());export const LoaderContextSchema=e.object({request:e.instanceof(Request),url:e.instanceof(URL),params:RouteParamsSchema,query:e.instanceof(URLSearchParams),state:e.instanceof(Map)});export const PagePropsSchema=e.object({params:RouteParamsSchema,query:e.instanceof(URLSearchParams),data:e.unknown().optional()});export const MetadataSchema=e.object({title:e.string().optional(),description:e.string().optional(),keywords:e.array(e.string()).optional(),openGraph:e.object({title:e.string().optional(),description:e.string().optional(),image:e.url().optional(),url:e.url().optional(),type:e.string().optional(),siteName:e.string().optional()}).optional(),twitter:e.object({card:e.enum([`summary`,`summary_large_image`,`app`,`player`]).optional(),title:e.string().optional(),description:e.string().optional(),image:e.url().optional(),site:e.string().optional()}).optional(),schema:e.array(e.record(e.string(),e.unknown())).optional(),canonical:e.url().optional(),robots:e.string().optional()});export const ResolvedMetadataSchema=MetadataSchema.extend({sources:e.array(e.string()).optional(),resolvedAt:e.number().optional()});export const MetadataChainSchema=e.object({global:MetadataSchema.optional(),sections:e.array(e.object({path:e.string(),metadata:MetadataSchema})),page:MetadataSchema.optional()});export const RouteDiscoveryOptionsSchema=e.object({pagesDirectory:e.string().min(1).default(`src/pages`),apiDirectory:e.string().min(1).default(`src/api`),extensions:e.array(e.string()).default([`.tsx`,`.ts`,`.jsx`,`.js`]),excludeDirectories:e.array(e.string()).default([`node_modules`,`.git`]),enableWatching:e.boolean().default(!1),developmentMode:e.boolean().default(!1),quietMode:e.boolean().default(!1)});export const FileSystemRouterConfigSchema=e.object({discovery:RouteDiscoveryOptionsSchema.optional(),enabled:e.boolean().default(!0),fallbackToManual:e.boolean().default(!0),enableCaching:e.boolean().default(!0),cacheTTL:e.number().positive().default(3e5)});export const PageFileSchema=e.object({filePath:e.string().min(1),relativePath:e.string().min(1),extension:e.string().min(1),isPrivate:e.boolean(),routeGroup:e.string().optional(),mtime:e.number().optional()});export const RouteHandlerSchema=e.object({pattern:e.any(),handler:e.any(),metadata:e.object({filePath:e.string(),routeType:RouteTypeSchema,priority:e.number(),dynamicSegments:e.array(e.string())})});export const RouteCacheEntrySchema=e.object({routes:e.array(FileSystemRouteSchema),timestamp:e.number(),fileMtimes:e.record(e.string(),e.number())});export const FileSystemApiRouteSchema=e.object({pattern:e.any(),filePath:e.string().min(1),methods:e.array(e.enum([`GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`HEAD`,`OPTIONS`])),priority:e.number().int().min(0),dynamicSegments:e.array(e.string())});export const FileSystemApiModuleSchema=e.object({GET:e.any().optional(),POST:e.any().optional(),PUT:e.any().optional(),DELETE:e.any().optional(),PATCH:e.any().optional(),HEAD:e.any().optional(),OPTIONS:e.any().optional()});export function isFileSystemRoute(e){return FileSystemRouteSchema.safeParse(e).success}export function isRoutePageModule(e){return RoutePageModuleSchema.safeParse(e).success}export function isMetadata(e){return MetadataSchema.safeParse(e).success}export function isRouteParams(e){return RouteParamsSchema.safeParse(e).success}export function isFileSystemApiModule(e){return FileSystemApiModuleSchema.safeParse(e).success}export{createTypedApiHandler,createTypedMetadataGenerator,createTypedPageComponent,createTypedPageLoader,isValidPageProps,isValidRouteParams,isValidRoutePattern,validatePageComponent}from"../types/routing.js";
1
+ import{z as e}from"zod";export const RouteTypeSchema=e.enum([`static`,`dynamic`,`catch-all`,`index`,`group`]);export const FileSystemRouteSchema=e.object({pattern:e.any(),filePath:e.string().min(1),routeType:RouteTypeSchema,dynamicSegments:e.array(e.string()),priority:e.number().int().min(0),isPrivate:e.boolean(),routeGroup:e.string().optional()});export const RoutePageModuleSchema=e.object({default:e.any(),layoutConfig:e.any().optional(),generateMetadata:e.any().optional(),loader:e.any().optional(),frontmatter:e.record(e.string(),e.any()).optional(),clientNavigation:e.boolean().optional()});export const RouteParamsSchema=e.record(e.string(),e.string());export const LoaderContextSchema=e.object({request:e.instanceof(Request),url:e.instanceof(URL),params:RouteParamsSchema,query:e.instanceof(URLSearchParams),state:e.instanceof(Map)});export const PagePropsSchema=e.object({params:RouteParamsSchema,query:e.instanceof(URLSearchParams),data:e.unknown().optional()});export const MetadataSchema=e.object({title:e.string().optional(),description:e.string().optional(),keywords:e.array(e.string()).optional(),openGraph:e.object({title:e.string().optional(),description:e.string().optional(),image:e.url().optional(),url:e.url().optional(),type:e.string().optional(),siteName:e.string().optional()}).optional(),twitter:e.object({card:e.enum([`summary`,`summary_large_image`,`app`,`player`]).optional(),title:e.string().optional(),description:e.string().optional(),image:e.url().optional(),site:e.string().optional()}).optional(),schema:e.array(e.record(e.string(),e.unknown())).optional(),canonical:e.url().optional(),robots:e.string().optional()});export const ResolvedMetadataSchema=MetadataSchema.extend({sources:e.array(e.string()).optional(),resolvedAt:e.number().optional()});export const MetadataChainSchema=e.object({global:MetadataSchema.optional(),sections:e.array(e.object({path:e.string(),metadata:MetadataSchema})),page:MetadataSchema.optional()});export const RouteDiscoveryOptionsSchema=e.object({pagesDirectory:e.string().min(1).default(`src/pages`),apiDirectory:e.string().min(1).default(`src/api`),extensions:e.array(e.string()).default([`.tsx`,`.ts`,`.jsx`,`.js`]),excludeDirectories:e.array(e.string()).default([`node_modules`,`.git`]),enableWatching:e.boolean().default(!1),developmentMode:e.boolean().default(!1),quietMode:e.boolean().default(!1)});export const FileSystemRouterConfigSchema=e.object({discovery:RouteDiscoveryOptionsSchema.optional(),enabled:e.boolean().default(!0),fallbackToManual:e.boolean().default(!0),enableCaching:e.boolean().default(!0),cacheTTL:e.number().positive().default(3e5)});export const PageFileSchema=e.object({filePath:e.string().min(1),relativePath:e.string().min(1),extension:e.string().min(1),isPrivate:e.boolean(),routeGroup:e.string().optional(),mtime:e.number().optional()});export const RouteHandlerSchema=e.object({pattern:e.any(),handler:e.any(),metadata:e.object({filePath:e.string(),routeType:RouteTypeSchema,priority:e.number(),dynamicSegments:e.array(e.string())})});export const RouteCacheEntrySchema=e.object({routes:e.array(FileSystemRouteSchema),timestamp:e.number(),fileMtimes:e.record(e.string(),e.number())});export const FileSystemApiRouteSchema=e.object({pattern:e.any(),filePath:e.string().min(1),methods:e.array(e.enum([`GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`HEAD`,`OPTIONS`])),priority:e.number().int().min(0),dynamicSegments:e.array(e.string())});export const FileSystemApiModuleSchema=e.object({GET:e.any().optional(),POST:e.any().optional(),PUT:e.any().optional(),DELETE:e.any().optional(),PATCH:e.any().optional(),HEAD:e.any().optional(),OPTIONS:e.any().optional()});export function isFileSystemRoute(e){return FileSystemRouteSchema.safeParse(e).success}export function isRoutePageModule(e){return RoutePageModuleSchema.safeParse(e).success}export function isMetadata(e){return MetadataSchema.safeParse(e).success}export function isRouteParams(e){return RouteParamsSchema.safeParse(e).success}export function isFileSystemApiModule(e){return FileSystemApiModuleSchema.safeParse(e).success}export{createTypedApiHandler,createTypedMetadataGenerator,createTypedPageComponent,createTypedPageLoader,isValidPageProps,isValidRouteParams,isValidRoutePattern,validatePageComponent}from"../types/routing.js";
@@ -1,13 +1,14 @@
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">
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=`/_server-islands/${t}`,y=s({elementId:p,endpointPath:v,timeout:_,islandProp:l});return`${`<avalon-server-island id="${p}" data-endpoint="${c(v)}" data-timeout="${_}" data-p="${c(h)}">`}${g}</avalon-server-island>\n${y}`}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
- if(!el)return;
4
+ if(!el||el.dataset.siStarted)return;
5
+ el.dataset.siStarted="1";
5
6
  const p=el.dataset.p;
6
- const url="${n}?p="+encodeURIComponent(p);
7
+ const url=(el.dataset.endpoint||"${n}")+"?p="+encodeURIComponent(p);
7
8
  const ctrl=new AbortController();
8
- const t=setTimeout(()=>ctrl.abort(),${r});
9
+ const t=setTimeout(()=>ctrl.abort(),Number(el.dataset.timeout)||${r});
9
10
  try{
10
- const r=await fetch(...(url.length>2048?["${n}",{method:"POST",body:p,headers:{"content-type":"text/plain"},signal:ctrl.signal}]:[url,{signal:ctrl.signal}]));
11
+ const r=await fetch(...(url.length>2048?[el.dataset.endpoint||"${n}",{method:"POST",body:p,headers:{"content-type":"text/plain"},signal:ctrl.signal}]:[url,{signal:ctrl.signal}]));
11
12
  clearTimeout(t);
12
13
  if(!r.ok)return;
13
14
  const html=await r.text();
@@ -45,12 +45,21 @@ export type IslandDirective = {
45
45
  | `on:${string}`;
46
46
 
47
47
  /**
48
- * Stable identifier for the island instance.
49
- * Used for state persistence with PersistentIsland.
50
- * If omitted, Avalon generates one automatically from the component path.
48
+ * Stable HTML `id` for this island instance.
49
+ * Required when two copies of the same component appear on one page.
50
+ * If omitted, Avalon generates a unique id from the component path plus an instance counter.
51
51
  */
52
52
  id?: string;
53
53
 
54
+ /**
55
+ * Keep this island's live instance across client navigations.
56
+ * The value is a stable key matched against the same key on the next page.
57
+ * `true` uses the component `src` as the key. Qwik islands are never persisted.
58
+ *
59
+ * Equivalent markup: `data-router-persist="key"` on a wrapper element.
60
+ */
61
+ persist?: string | true;
62
+
54
63
  /**
55
64
  * Optional argument passed to custom hydration directives.
56
65
  * For example, `on:delay` uses this as the delay in milliseconds.
@@ -7,9 +7,11 @@
7
7
  */
8
8
 
9
9
  declare module "virtual:avalon/page-loader" {
10
- export function loadPage(
11
- pathname: string,
12
- ): { default: unknown; metadata?: Record<string, unknown> } | null;
10
+ export function loadPage(pathname: string): {
11
+ default: unknown;
12
+ metadata?: Record<string, unknown>;
13
+ clientNavigation?: boolean;
14
+ } | null;
13
15
  }
14
16
 
15
17
  declare module "virtual:avalon/config" {
@@ -18,6 +20,7 @@ declare module "virtual:avalon/config" {
18
20
  pagesDir: string;
19
21
  layoutsDir: string;
20
22
  isDev: boolean;
23
+ clientRouter?: boolean;
21
24
  [key: string]: unknown;
22
25
  };
23
26
  export default config;
@@ -60,7 +63,15 @@ declare module "virtual:avalon/client-entry" {
60
63
  }
61
64
 
62
65
  declare module "virtual:avalon/integration-loader" {
63
- export function loadIntegrationModule(framework: string): Promise<unknown>;
66
+ export function loadIntegrationModule(framework: string): Promise<{
67
+ hydrate?: (
68
+ el: HTMLElement,
69
+ component: unknown,
70
+ props: Record<string, unknown>,
71
+ ) => void | Promise<void>;
72
+ unmount?: (el: HTMLElement) => void | Promise<void>;
73
+ preLitHydration?: () => Promise<void>;
74
+ }>;
64
75
  export function preLitHydration(): Promise<void>;
65
76
  export function loadHMRAdapter(framework: string): Promise<unknown>;
66
77
  }
@@ -1 +1 @@
1
- import{existsSync as e}from"node:fs";import{resolve as t}from"node:path";import n from"node:process";export const DEFAULT_MDX_CONFIG={jsxImportSource:`preact`,syntaxHighlighting:!0,remarkPlugins:[],rehypePlugins:[]};export const DEFAULT_IMAGE_CONFIG={enabled:!0,defaultFormat:`webp`,quality:80,widths:[200,400,600,800,1200],removeMetadata:!0,include:/^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,exclude:`public/**/*`};export const DEFAULT_CONFIG={core:`preact`,pagesDir:`src/pages`,layoutsDir:`src/layouts`,modules:null,integrations:[],mdx:DEFAULT_MDX_CONFIG,image:DEFAULT_IMAGE_CONFIG,verbose:!1,autoDiscoverIntegrations:!0,validateIntegrations:!0,showWarnings:!0,lazyIntegrations:!0};export const DEFAULT_MODULES_CONFIG={pagesDirName:`pages`,layoutsDirName:`layouts`};function s(e){return e?typeof e==`string`?{dir:e,pagesDirName:DEFAULT_MODULES_CONFIG.pagesDirName,layoutsDirName:DEFAULT_MODULES_CONFIG.layoutsDirName}:{dir:e.dir,pagesDirName:e.pagesDirName??DEFAULT_MODULES_CONFIG.pagesDirName,layoutsDirName:e.layoutsDirName??DEFAULT_MODULES_CONFIG.layoutsDirName}:null}function c(e){return e===!1?{...DEFAULT_IMAGE_CONFIG,enabled:!1}:e===void 0||e===!0?DEFAULT_IMAGE_CONFIG:{enabled:e.enabled??DEFAULT_IMAGE_CONFIG.enabled,defaultFormat:e.defaultFormat??DEFAULT_IMAGE_CONFIG.defaultFormat,quality:e.quality??DEFAULT_IMAGE_CONFIG.quality,widths:e.widths??DEFAULT_IMAGE_CONFIG.widths,removeMetadata:e.removeMetadata??DEFAULT_IMAGE_CONFIG.removeMetadata,include:e.include??DEFAULT_IMAGE_CONFIG.include,exclude:e.exclude??DEFAULT_IMAGE_CONFIG.exclude}}export function resolveConfig(e,t){let n=e??{},i=s(n.modules),o=c(n.image),l=n.core??DEFAULT_CONFIG.core;return{core:l,pagesDir:n.pagesDir??DEFAULT_CONFIG.pagesDir,layoutsDir:n.layoutsDir??DEFAULT_CONFIG.layoutsDir,modules:i,integrations:n.integrations??DEFAULT_CONFIG.integrations,mdx:{jsxImportSource:n.mdx?.jsxImportSource??l,syntaxHighlighting:n.mdx?.syntaxHighlighting??DEFAULT_MDX_CONFIG.syntaxHighlighting,remarkPlugins:n.mdx?.remarkPlugins??DEFAULT_MDX_CONFIG.remarkPlugins,rehypePlugins:n.mdx?.rehypePlugins??DEFAULT_MDX_CONFIG.rehypePlugins},image:o,verbose:n.verbose??DEFAULT_CONFIG.verbose,autoDiscoverIntegrations:n.autoDiscoverIntegrations??DEFAULT_CONFIG.autoDiscoverIntegrations,validateIntegrations:n.validateIntegrations??DEFAULT_CONFIG.validateIntegrations,showWarnings:n.showWarnings??DEFAULT_CONFIG.showWarnings,lazyIntegrations:n.lazyIntegrations??DEFAULT_CONFIG.lazyIntegrations,isDev:t}}export function checkDirectoriesExist(r,i=n.cwd()){let a=[];!r.modules&&r.pagesDir&&a.push({path:r.pagesDir,type:`pages`}),r.layoutsDir&&a.push({path:r.layoutsDir,type:`layouts`});let o=[];for(let{path:n,type:s}of a){let a=t(i,n),c=e(a);o.push({path:n,absolutePath:a,exists:c,type:s}),!c&&r.showWarnings&&console.warn(`⚠️ Avalon: ${s} directory '${n}' does not exist (resolved to: ${a}). This directory will be skipped.`)}return o}export function logDirectoryCheckSummary(e,t){let n=e.filter(e=>!e.exists),r=e.filter(e=>e.exists);t&&(r.length>0&&console.log(` ✅ Found directories: ${r.map(e=>e.path).join(`, `)}`),n.length>0&&console.log(` ⚠️ Missing directories: ${n.map(e=>e.path).join(`, `)}`))}
1
+ import{existsSync as e}from"node:fs";import{resolve as t}from"node:path";import n from"node:process";export const DEFAULT_MDX_CONFIG={jsxImportSource:`preact`,syntaxHighlighting:!0,remarkPlugins:[],rehypePlugins:[]};export const DEFAULT_IMAGE_CONFIG={enabled:!0,defaultFormat:`webp`,quality:80,widths:[200,400,600,800,1200],removeMetadata:!0,include:/^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/,exclude:`public/**/*`};export const DEFAULT_CONFIG={core:`preact`,pagesDir:`src/pages`,layoutsDir:`src/layouts`,modules:null,integrations:[],mdx:DEFAULT_MDX_CONFIG,image:DEFAULT_IMAGE_CONFIG,verbose:!1,autoDiscoverIntegrations:!0,validateIntegrations:!0,showWarnings:!0,lazyIntegrations:!0,clientRouter:!1};export const DEFAULT_MODULES_CONFIG={pagesDirName:`pages`,layoutsDirName:`layouts`};function s(e){return e?typeof e==`string`?{dir:e,pagesDirName:DEFAULT_MODULES_CONFIG.pagesDirName,layoutsDirName:DEFAULT_MODULES_CONFIG.layoutsDirName}:{dir:e.dir,pagesDirName:e.pagesDirName??DEFAULT_MODULES_CONFIG.pagesDirName,layoutsDirName:e.layoutsDirName??DEFAULT_MODULES_CONFIG.layoutsDirName}:null}function c(e){return e===!1?{...DEFAULT_IMAGE_CONFIG,enabled:!1}:e===void 0||e===!0?DEFAULT_IMAGE_CONFIG:{enabled:e.enabled??DEFAULT_IMAGE_CONFIG.enabled,defaultFormat:e.defaultFormat??DEFAULT_IMAGE_CONFIG.defaultFormat,quality:e.quality??DEFAULT_IMAGE_CONFIG.quality,widths:e.widths??DEFAULT_IMAGE_CONFIG.widths,removeMetadata:e.removeMetadata??DEFAULT_IMAGE_CONFIG.removeMetadata,include:e.include??DEFAULT_IMAGE_CONFIG.include,exclude:e.exclude??DEFAULT_IMAGE_CONFIG.exclude}}export function resolveConfig(e,t){let n=e??{},i=s(n.modules),o=c(n.image),l=n.core??DEFAULT_CONFIG.core;return{core:l,pagesDir:n.pagesDir??DEFAULT_CONFIG.pagesDir,layoutsDir:n.layoutsDir??DEFAULT_CONFIG.layoutsDir,modules:i,integrations:n.integrations??DEFAULT_CONFIG.integrations,mdx:{jsxImportSource:n.mdx?.jsxImportSource??l,syntaxHighlighting:n.mdx?.syntaxHighlighting??DEFAULT_MDX_CONFIG.syntaxHighlighting,remarkPlugins:n.mdx?.remarkPlugins??DEFAULT_MDX_CONFIG.remarkPlugins,rehypePlugins:n.mdx?.rehypePlugins??DEFAULT_MDX_CONFIG.rehypePlugins},image:o,verbose:n.verbose??DEFAULT_CONFIG.verbose,autoDiscoverIntegrations:n.autoDiscoverIntegrations??DEFAULT_CONFIG.autoDiscoverIntegrations,validateIntegrations:n.validateIntegrations??DEFAULT_CONFIG.validateIntegrations,showWarnings:n.showWarnings??DEFAULT_CONFIG.showWarnings,lazyIntegrations:n.lazyIntegrations??DEFAULT_CONFIG.lazyIntegrations,clientRouter:n.clientRouter??DEFAULT_CONFIG.clientRouter,isDev:t}}export function checkDirectoriesExist(r,i=n.cwd()){let a=[];!r.modules&&r.pagesDir&&a.push({path:r.pagesDir,type:`pages`}),r.layoutsDir&&a.push({path:r.layoutsDir,type:`layouts`});let o=[];for(let{path:n,type:s}of a){let a=t(i,n),c=e(a);o.push({path:n,absolutePath:a,exists:c,type:s}),!c&&r.showWarnings&&console.warn(`⚠️ Avalon: ${s} directory '${n}' does not exist (resolved to: ${a}). This directory will be skipped.`)}return o}export function logDirectoryCheckSummary(e,t){let n=e.filter(e=>!e.exists),r=e.filter(e=>e.exists);t&&(r.length>0&&console.log(` ✅ Found directories: ${r.map(e=>e.path).join(`, `)}`),n.length>0&&console.log(` ⚠️ Missing directories: ${n.map(e=>e.path).join(`, `)}`))}