@useavalon/avalon 0.1.85 → 0.1.88

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.
package/dist/mod.d.ts CHANGED
@@ -23,7 +23,6 @@ export type { CacheConfig as IslandCacheConfig, CacheStats as IslandCacheStats,
23
23
  export { clearCache, clearIslandCache, configureCache, getCacheConfig, getCacheStats, invalidateCacheForFile, invalidateCacheForPath, logCacheStats, } from "./src/islands/render-cache.ts";
24
24
  export type { Framework, RenderParams, SvelteSSRCSSEntry } from "./src/islands/types.ts";
25
25
  export { renderToHtml } from "./src/render/ssr.ts";
26
- export { asIsland } from "./src/types/as-island.ts";
27
26
  export type { IslandDirective } from "./src/types/island-prop.d.ts";
28
27
  export type { NitroCoordinationPluginOptions, NitroIntegrationResult, } from "./src/vite-plugin/nitro-integration.ts";
29
28
  export { createNitroCoordinationPlugin, createNitroIntegration, createVirtualModulesPlugin, getAvalonConfig, getViteDevServer, isDevelopmentMode, RESOLVED_VIRTUAL_IDS, VIRTUAL_MODULE_IDS, } from "./src/vite-plugin/nitro-integration.ts";
package/dist/mod.js CHANGED
@@ -1 +1 @@
1
- export{generateIslandManifest,getIslandBundlePath,loadIslandManifest}from"./src/build/island-manifest.js";export{generateIslandTypes,watchAndGenerateTypes}from"./src/build/island-types-generator.js";export{mdxIslandTransform}from"./src/build/mdx-island-transform.js";export{pageIslandTransform}from"./src/build/page-island-transform.js";export{registry as integrationRegistry}from"./src/core/integrations/registry.js";export{registerBuiltinDirectives}from"./src/islands/builtin-directives.js";export{analyzeComponentFile,renderComponentSSROnly}from"./src/islands/component-analysis.js";export{addSvelteSSRCSS,clearSvelteComponentCSS,generateComponentScopeId,getSvelteComponentCSS,getSvelteSSRCSS,getSvelteSSRCSSForHead,getSvelteSSRCSSStats}from"./src/islands/css-utils.js";export{createIslandRegistry,createIslandResolver,createIslandValidator,createIslandWatcher,DEFAULT_DISCOVERY_CONFIG,discoverAllIslands,discoverIslandDirectories,discoverIslandsInDirectory,formatCircularDependency,formatValidationError,formatValidationResult,formatValidationWarning,getDefaultIslandsPath,getQualifiedIslandName,hasDefaultIslandsDirectory,ISLAND_FILE_EXTENSIONS,IslandRegistry,IslandResolver,IslandValidator,IslandWatcher,isIslandsDirectory,isSupportedIslandExtension,parseQualifiedIslandName,validateAllIslands}from"./src/islands/discovery/index.js";export{detectFramework,detectFrameworkFromSrc,resolveIslandPath}from"./src/islands/framework-detection.js";export{getDirective,getRegisteredDirectives,isCustomDirective,registerHydrationDirective,unregisterHydrationDirective}from"./src/islands/hydration-directives.js";export{DEFAULT_PRELOAD_FRAMEWORKS,detectAndLoadIntegration,detectFrameworksFromPageContent,loadIntegration,preloadIntegrations}from"./src/islands/integration-loader.js";export{default as Island,renderIsland}from"./src/islands/island.js";export{clearCache,clearIslandCache,configureCache,getCacheConfig,getCacheStats,invalidateCacheForFile,invalidateCacheForPath,logCacheStats}from"./src/islands/render-cache.js";export{renderToHtml}from"./src/render/ssr.js";export{asIsland}from"./src/types/as-island.js";export{createNitroCoordinationPlugin,createNitroIntegration,createVirtualModulesPlugin,getAvalonConfig,getViteDevServer,isDevelopmentMode,RESOLVED_VIRTUAL_IDS,VIRTUAL_MODULE_IDS}from"./src/vite-plugin/nitro-integration.js";export{avalon,getLayoutsDir,getNitroConfig,getPagesDir,getResolvedConfig,isNitroEnabled}from"./src/vite-plugin/plugin.js";export async function build(e){throw Error("avalon build() is not available in the published package. Use `vite build` or the Avalon CLI instead.")}export{IslandErrorBoundary,withIslandErrorBoundary}from"./src/components/IslandErrorBoundary.js";export{LayoutErrorBoundary}from"./src/components/LayoutErrorBoundary.js";export*from"./src/layout-system.js";export{clearDiscoveryCache,clearMiddlewareCache,discoverScopedMiddleware,executeScopedMiddleware,getContextValue,getMatchingMiddleware,getMiddlewareCacheSize,hasContextValue,invalidateMiddleware,setContextValue}from"./src/middleware/index.js";export{usePersistentState}from"./src/persistence/use-persistent-state.js";
1
+ export{generateIslandManifest,getIslandBundlePath,loadIslandManifest}from"./src/build/island-manifest.js";export{generateIslandTypes,watchAndGenerateTypes}from"./src/build/island-types-generator.js";export{mdxIslandTransform}from"./src/build/mdx-island-transform.js";export{pageIslandTransform}from"./src/build/page-island-transform.js";export{registry as integrationRegistry}from"./src/core/integrations/registry.js";export{registerBuiltinDirectives}from"./src/islands/builtin-directives.js";export{analyzeComponentFile,renderComponentSSROnly}from"./src/islands/component-analysis.js";export{addSvelteSSRCSS,clearSvelteComponentCSS,generateComponentScopeId,getSvelteComponentCSS,getSvelteSSRCSS,getSvelteSSRCSSForHead,getSvelteSSRCSSStats}from"./src/islands/css-utils.js";export{createIslandRegistry,createIslandResolver,createIslandValidator,createIslandWatcher,DEFAULT_DISCOVERY_CONFIG,discoverAllIslands,discoverIslandDirectories,discoverIslandsInDirectory,formatCircularDependency,formatValidationError,formatValidationResult,formatValidationWarning,getDefaultIslandsPath,getQualifiedIslandName,hasDefaultIslandsDirectory,ISLAND_FILE_EXTENSIONS,IslandRegistry,IslandResolver,IslandValidator,IslandWatcher,isIslandsDirectory,isSupportedIslandExtension,parseQualifiedIslandName,validateAllIslands}from"./src/islands/discovery/index.js";export{detectFramework,detectFrameworkFromSrc,resolveIslandPath}from"./src/islands/framework-detection.js";export{getDirective,getRegisteredDirectives,isCustomDirective,registerHydrationDirective,unregisterHydrationDirective}from"./src/islands/hydration-directives.js";export{DEFAULT_PRELOAD_FRAMEWORKS,detectAndLoadIntegration,detectFrameworksFromPageContent,loadIntegration,preloadIntegrations}from"./src/islands/integration-loader.js";export{default as Island,renderIsland}from"./src/islands/island.js";export{clearCache,clearIslandCache,configureCache,getCacheConfig,getCacheStats,invalidateCacheForFile,invalidateCacheForPath,logCacheStats}from"./src/islands/render-cache.js";export{renderToHtml}from"./src/render/ssr.js";export{createNitroCoordinationPlugin,createNitroIntegration,createVirtualModulesPlugin,getAvalonConfig,getViteDevServer,isDevelopmentMode,RESOLVED_VIRTUAL_IDS,VIRTUAL_MODULE_IDS}from"./src/vite-plugin/nitro-integration.js";export{avalon,getLayoutsDir,getNitroConfig,getPagesDir,getResolvedConfig,isNitroEnabled}from"./src/vite-plugin/plugin.js";export async function build(e){throw Error("avalon build() is not available in the published package. Use `vite build` or the Avalon CLI instead.")}export{IslandErrorBoundary,withIslandErrorBoundary}from"./src/components/IslandErrorBoundary.js";export{LayoutErrorBoundary}from"./src/components/LayoutErrorBoundary.js";export*from"./src/layout-system.js";export{clearDiscoveryCache,clearMiddlewareCache,discoverScopedMiddleware,executeScopedMiddleware,getContextValue,getMatchingMiddleware,getMiddlewareCacheSize,hasContextValue,invalidateMiddleware,setContextValue}from"./src/middleware/index.js";export{usePersistentState}from"./src/persistence/use-persistent-state.js";
@@ -1 +1 @@
1
- import{readFile as e}from"node:fs/promises";import{getQualifiedIslandName as t,createIslandRegistry as n}from"../islands/discovery/index.js";export async function generateIslandManifest(){let r={},s=process.cwd();try{let c=await n(s),l=c.getAllIslands(),u=c.directories,d=c.collisions;for(let n of l){let s=t(n),c=`/${n.relativePath}`,l=await e(n.filePath,`utf-8`),u=i(n.framework),d=a(l),f=await o(l);r[s]={src:c,bundle:n.namespace===``?`/islands/${n.name}.${f}.js`:`/islands/${s}.${f}.js`,hash:f,framework:u,deps:d,namespace:n.namespace,qualifiedName:s,sourceDirectory:n.directory.relativePath}}return{islands:r,directories:u,collisions:d,version:`1.0.0`,buildTime:Date.now()}}catch(e){return console.warn(`Failed to generate island manifest:`,e),{islands:{},directories:[],collisions:[],version:`1.0.0`,buildTime:Date.now()}}}function i(e){switch(e){case`preact`:return`preact`;case`react`:return`react`;case`solid`:return`solid`;case`vue`:return`vue`;case`svelte`:return`svelte`;case`lit`:return`lit`;case`qwik`:return`qwik`;default:return`unknown`}}function a(e){let t=[],n=/import\s+.*?\s+from\s+['"]([^'"]+)['"]/g,r;for(;(r=n.exec(e))!==null;){let e=r[1];!e.startsWith(`.`)&&!e.startsWith(`/`)&&t.push(e)}return[...new Set(t)]}async function o(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest(`SHA-256`,t);return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,8)}export async function loadIslandManifest(){try{let t=await e(`dist/island-manifest.json`,`utf-8`);return JSON.parse(t)}catch(e){return console.warn(`Failed to load island manifest:`,e),null}}export function getIslandBundlePath(e,t){let n=globalThis.__avalonHydrationMode===void 0?process.env.NODE_ENV!==`production`:globalThis.__avalonHydrationMode===`entry-client`;if(t){let n=l(e),r=t;if(r.islands[n])return r.islands[n].bundle;let i=e.replace(/^\/islands\//,``).replace(/\.(tsx?|jsx?)$/,``),a=t.islands[i];if(a)return a.bundle}return n?e.startsWith(`/islands/`)?e.replaceAll(`/islands/`,`/src/islands/`):e.startsWith(`/src/`)||e.startsWith(`/app/`)||e.startsWith(`/`)?e:`/src/${e}`:`/islands/${l(e)}.js`}function l(e){let t=e.replace(/^\//,``);t=t.replace(/\.(tsx?|jsx?)$/,``);let n=new RegExp(/^src\/(.+)\/islands\/([^/]+)$/).exec(t);if(n){let[,e,t]=n;return`${e}/${t}`}let r=new RegExp(/^(?:src\/)?islands\/([^/]+)$/).exec(t);return r?r[1]:t}export function getIslandEntry(e,t){if(t.islands[e])return t.islands[e];if(t.directories){for(let[n,r]of Object.entries(t.islands))if(n.split(`/`).pop()===e)return r}return null}
1
+ import{readFile as e}from"node:fs/promises";import{getQualifiedIslandName as t,createIslandRegistry as n}from"../islands/discovery/index.js";export async function generateIslandManifest(){let r={},s=process.cwd();try{let c=await n(s),l=c.getAllIslands(),u=c.directories,d=c.collisions;for(let n of l){let s=t(n),c=`/${n.relativePath}`,l=await e(n.filePath,`utf-8`),u=i(n.framework),d=a(l),f=await o(l);r[s]={src:c,bundle:n.namespace===``?`/islands/${n.name}.${f}.js`:`/islands/${s}.${f}.js`,hash:f,framework:u,deps:d,namespace:n.namespace,qualifiedName:s,sourceDirectory:n.directory.relativePath}}return{islands:r,directories:u,collisions:d,version:`1.0.0`,buildTime:Date.now()}}catch(e){return console.warn(`Failed to generate island manifest:`,e),{islands:{},directories:[],collisions:[],version:`1.0.0`,buildTime:Date.now()}}}function i(e){switch(e){case`preact`:return`preact`;case`react`:return`react`;case`solid`:return`solid`;case`vue`:return`vue`;case`svelte`:return`svelte`;case`lit`:return`lit`;case`qwik`:return`qwik`;default:return`unknown`}}function a(e){let t=[],n=/import\s+.*?\s+from\s+['"]([^'"]+)['"]/g,r;for(;(r=n.exec(e))!==null;){let e=r[1];!e.startsWith(`.`)&&!e.startsWith(`/`)&&t.push(e)}return[...new Set(t)]}async function o(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest(`SHA-256`,t);return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,8)}export async function loadIslandManifest(){try{let t=await e(`dist/island-manifest.json`,`utf-8`);return JSON.parse(t)}catch(e){return console.warn(`Failed to load island manifest:`,e),null}}export function getIslandBundlePath(e,t){let n=globalThis.__avalonHydrationMode===void 0?process.env.NODE_ENV!==`production`:globalThis.__avalonHydrationMode===`entry-client`,r=process.cwd();if(r&&e.startsWith(r+`/`)&&(e=e.slice(r.length)),t){let n=l(e),r=t;if(r.islands[n])return r.islands[n].bundle;let i=e.replace(/^\/islands\//,``).replace(/\.(tsx?|jsx?)$/,``),a=t.islands[i];if(a)return a.bundle}return n?e.startsWith(`/islands/`)?e.replaceAll(`/islands/`,`/src/islands/`):e.startsWith(`/src/`)||e.startsWith(`/app/`)||e.startsWith(`/`)?e:`/src/${e}`:`/islands/${l(e)}.js`}function l(e){let t=e.replace(/^\//,``);t=t.replace(/\.(tsx?|jsx?)$/,``);let n=new RegExp(/^src\/(.+)\/islands\/([^/]+)$/).exec(t);if(n){let[,e,t]=n;return`${e}/${t}`}let r=new RegExp(/^(?:src\/)?islands\/([^/]+)$/).exec(t);return r?r[1]:t}export function getIslandEntry(e,t){if(t.islands[e])return t.islands[e];if(t.directories){for(let[n,r]of Object.entries(t.islands))if(n.split(`/`).pop()===e)return r}return null}
@@ -1,15 +1,4 @@
1
1
  /**
2
- * Framework HMR Adapters
3
- *
4
- * HMR adapters have been moved to their respective integration packages:
5
- * - @useavalon/react/client/hmr
6
- * - @useavalon/preact/client/hmr
7
- * - @useavalon/vue/client/hmr
8
- * - @useavalon/svelte/client/hmr
9
- * - @useavalon/solid/client/hmr
10
- * - @useavalon/lit/client/hmr
11
- * - @useavalon/qwik/client/hmr
12
- *
13
- * This barrel re-exports from the base framework adapter for backward compatibility.
2
+ * Framework HMR Adapter base types and registry.
14
3
  */
15
4
  export { BaseFrameworkAdapter, AdapterRegistry, type FrameworkHMRAdapter, type StateSnapshot, } from '../framework-adapter.ts';
@@ -1,4 +1,4 @@
1
- import{loadHMRAdapter as e,loadIntegrationModule as t,preLitHydration as n}from"virtual:avalon/integration-loader";import{executeCustomDirective as r,hasClientDirective as i}from"./custom-directives.js";document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,a):a();function a(){let e=document.querySelectorAll(`[data-framework]`);e.length!==0&&e.forEach(e=>{try{let t=e.dataset.framework,n=e.dataset.condition||`on:client`;if(e.dataset.renderStrategy===`ssr-only`||!o(e,n))return;n===`on:client`?f(e,t):n===`on:visible`?s(e,t):n===`on:interaction`?c(e,t):n===`on:idle`?l(e,t):n.startsWith(`media:`)?u(e,t,n.slice(6)):e.dataset.customDirective||i(n)?r(e,n,()=>{f(e,t)})||(console.warn(`[avalon] Unknown hydration condition: "${n}". Hydrating immediately.`),f(e,t)):f(e,t)}catch(t){console.error(`Error processing island:`,t),p(e,e.dataset.framework||`unknown`,e.dataset.src||`unknown`,t)}})}function o(e,t){if(!t||t===`on:client`)return!0;if(t.startsWith(`media:`)){let e=t.slice(6);try{return globalThis.matchMedia(e).matches}catch(t){return console.error(`Invalid media query:`,e,t),!0}}return t===`on:visible`||t===`on:interaction`||t===`on:idle`||console.warn(`Unknown hydration condition:`,t),!0}function s(e,t){try{let n=new IntersectionObserver(r=>{r[0].isIntersecting&&(f(e,t),n.disconnect())},{rootMargin:`50px`,threshold:0});n.observe(e)}catch(n){console.error(`Failed to setup intersection observer:`,n),f(e,t)}}function c(e,t){let n=[`click`,`touchstart`,`mouseenter`,`focusin`],r=!1,i=()=>{r||(r=!0,n.forEach(t=>{e.removeEventListener(t,i)}),f(e,t))};try{n.forEach(t=>{e.addEventListener(t,i,{once:!0,passive:!0})})}catch(n){console.error(`Failed to setup interaction observer:`,n),f(e,t)}}function l(e,t){try{`requestIdleCallback`in globalThis?globalThis.requestIdleCallback(()=>{f(e,t)},{timeout:5e3}):document.readyState===`complete`?setTimeout(()=>{f(e,t)},200):globalThis.addEventListener(`load`,()=>{setTimeout(()=>{f(e,t)},200)},{once:!0})}catch(n){console.error(`Failed to setup idle callback:`,n),f(e,t)}}function u(e,t,n){try{let r=globalThis.matchMedia(n);if(r.matches){f(e,t);return}let i=n=>{n.matches&&(f(e,t),r.removeEventListener(`change`,i))};r.addEventListener(`change`,i)}catch(r){console.error(`Failed to setup media query:`,n,r),f(e,t)}}function d(e,t){let n=e.default;if(!n){let t=Object.keys(e).filter(e=>e!==`default`);for(let r of t){let t=e[r];if(typeof t==`function`&&t.prototype){n=t;break}}n||=e}if(!n)throw Error(`Component ${t} has no default export`);return n}async function f(e,r){if(e.dataset.hydrated)return;let i=e.dataset.src,a=e.dataset.props;if(!i){console.warn(`Island missing data-src attribute`);return}try{let o=a?JSON.parse(a):{};r===`lit`&&await n();let s=d(await import(i),i);try{let n=await t(r);if(!n.hydrate||typeof n.hydrate!=`function`)throw Error(`Integration ${r} does not export a hydrate function`);await n.hydrate(e,s,o),e.dataset.hydrated=`true`}catch(t){import.meta.env?.DEV&&console.error(`Integration hydration failed for ${r}: ${i}`,t),e.dataset.hydrationStatus=`failed`,e.dataset.hydrationError=t.message,e.dispatchEvent(new CustomEvent(`hydration-error`,{detail:{framework:r,src:i,error:t.message,timestamp:Date.now(),hydrationType:`integration-level`},bubbles:!0}))}}catch(t){console.error(`❌ Critical error hydrating ${r} island ${i}:`,t),p(e,r,i,t)}}function p(e,t,n,r){console.error(`Hydration error for ${t} island:`,{src:n,error:r.message,stack:r.stack}),e.dataset.hydrationStatus=`failed`,e.dataset.renderStrategy=`ssr-only`,e.classList.add(`hydration-failed`),e.dispatchEvent(new CustomEvent(`hydration-error`,{detail:{framework:t,src:n,error:r.message,timestamp:Date.now()},bubbles:!0})),h()&&m(e,t,n,r)}function m(e,t,n,r){let i=document.createElement(`div`);i.className=`hydration-error-indicator`,i.style.cssText=`
1
+ import{loadHMRAdapter as e,loadIntegrationModule as t,preLitHydration as n}from"virtual:avalon/integration-loader";import{executeCustomDirective as r,hasClientDirective as i}from"./custom-directives.js";document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,a):a();function a(){let e=document.querySelectorAll(`[data-framework]`);e.length!==0&&e.forEach(e=>{try{let t=e.dataset.framework,n=e.dataset.condition||`on:client`;if(e.dataset.renderStrategy===`ssr-only`||!o(e,n))return;n===`on:client`?f(e,t):n===`on:visible`?s(e,t):n===`on:interaction`?c(e,t):n===`on:idle`?l(e,t):n.startsWith(`media:`)?u(e,t,n.slice(6)):e.dataset.customDirective||e.dataset.directiveScript||i(n)?r(e,n,()=>{f(e,t)})||(console.warn(`[avalon] Unknown hydration condition: "${n}". Hydrating immediately.`),f(e,t)):f(e,t)}catch(t){console.error(`Error processing island:`,t),p(e,e.dataset.framework||`unknown`,e.dataset.src||`unknown`,t)}})}function o(e,t){if(!t||t===`on:client`)return!0;if(t.startsWith(`media:`)){let e=t.slice(6);try{return globalThis.matchMedia(e).matches}catch(t){return console.error(`Invalid media query:`,e,t),!0}}return t===`on:visible`||t===`on:interaction`||t===`on:idle`||e.dataset.customDirective||e.dataset.directiveScript||i(t)||console.warn(`Unknown hydration condition:`,t),!0}function s(e,t){try{let n=new IntersectionObserver(r=>{r[0].isIntersecting&&(f(e,t),n.disconnect())},{rootMargin:`50px`,threshold:0});n.observe(e)}catch(n){console.error(`Failed to setup intersection observer:`,n),f(e,t)}}function c(e,t){let n=[`click`,`touchstart`,`mouseenter`,`focusin`],r=!1,i=()=>{r||(r=!0,n.forEach(t=>{e.removeEventListener(t,i)}),f(e,t))};try{n.forEach(t=>{e.addEventListener(t,i,{once:!0,passive:!0})})}catch(n){console.error(`Failed to setup interaction observer:`,n),f(e,t)}}function l(e,t){try{`requestIdleCallback`in globalThis?globalThis.requestIdleCallback(()=>{f(e,t)},{timeout:5e3}):document.readyState===`complete`?setTimeout(()=>{f(e,t)},200):globalThis.addEventListener(`load`,()=>{setTimeout(()=>{f(e,t)},200)},{once:!0})}catch(n){console.error(`Failed to setup idle callback:`,n),f(e,t)}}function u(e,t,n){try{let r=globalThis.matchMedia(n);if(r.matches){f(e,t);return}let i=n=>{n.matches&&(f(e,t),r.removeEventListener(`change`,i))};r.addEventListener(`change`,i)}catch(r){console.error(`Failed to setup media query:`,n,r),f(e,t)}}function d(e,t){let n=e.default;if(!n){let t=Object.keys(e).filter(e=>e!==`default`);for(let r of t){let t=e[r];if(typeof t==`function`&&t.prototype){n=t;break}}n||=e}if(!n)throw Error(`Component ${t} has no default export`);return n}async function f(e,r){if(e.dataset.hydrated)return;let i=e.dataset.src,a=e.dataset.props;if(!i){console.warn(`Island missing data-src attribute`);return}try{let o=a?JSON.parse(a):{};r===`lit`&&await n();let s=d(await import(i),i);try{let n=await t(r);if(!n.hydrate||typeof n.hydrate!=`function`)throw Error(`Integration ${r} does not export a hydrate function`);await n.hydrate(e,s,o),e.dataset.hydrated=`true`}catch(t){import.meta.env?.DEV&&console.error(`Integration hydration failed for ${r}: ${i}`,t),e.dataset.hydrationStatus=`failed`,e.dataset.hydrationError=t.message,e.dispatchEvent(new CustomEvent(`hydration-error`,{detail:{framework:r,src:i,error:t.message,timestamp:Date.now(),hydrationType:`integration-level`},bubbles:!0}))}}catch(t){console.error(`❌ Critical error hydrating ${r} island ${i}:`,t),p(e,r,i,t)}}function p(e,t,n,r){console.error(`Hydration error for ${t} island:`,{src:n,error:r.message,stack:r.stack}),e.dataset.hydrationStatus=`failed`,e.dataset.renderStrategy=`ssr-only`,e.classList.add(`hydration-failed`),e.dispatchEvent(new CustomEvent(`hydration-error`,{detail:{framework:t,src:n,error:r.message,timestamp:Date.now()},bubbles:!0})),h()&&m(e,t,n,r)}function m(e,t,n,r){let i=document.createElement(`div`);i.className=`hydration-error-indicator`,i.style.cssText=`
2
2
  position: absolute;
3
3
  top: 0;
4
4
  right: 0;
@@ -6,6 +6,8 @@ declare global {
6
6
  var __viteDevServer: ViteDevServer | undefined;
7
7
  /** Hydration mode — automatically set: "entry-client" in dev (HMR), "per-island" in production */
8
8
  var __avalonHydrationMode: "entry-client" | "per-island" | undefined;
9
+ /** Compile-time constant set by Vite define — true in production, false in dev */
10
+ var __AVALON_PER_ISLAND__: boolean;
9
11
  }
10
12
  /** Supported hydration conditions for island components */
11
13
  export type HydrationCondition = "on:visible" | "on:interaction" | "on:idle" | "on:client" | `media:${string}` | `on:${string}`;
@@ -1 +1 @@
1
- import{Fragment as e,h as t}from"preact";import{getIslandBundlePath as n}from"../build/island-manifest.js";import{devError as r,devLog as i,devWarn as a,isDev as o,logRenderTiming as s}from"../utils/dev-logger.js";import{analyzeComponentFile as c,renderComponentSSROnly as l}from"./component-analysis.js";import{detectFramework as u}from"./framework-detection.js";import{isCustomDirective as d,serializeDirectiveScript as f}from"./hydration-directives.js";import{detectFrameworkFromPath as p,loadIntegration as m}from"./integration-loader.js";import{generatePerIslandScript as h}from"./per-island-script.js";import{addModulepreload as g}from"./modulepreload-collector.js";import{addUniversalCSS as _}from"./universal-css-collector.js";import{addUniversalHead as v}from"./universal-head-collector.js";function y(e){return`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}`}function b(){return globalThis.__avalonHydrationMode===void 0?!o():globalThis.__avalonHydrationMode===`per-island`}function x(r,i){if(!b()||i.shouldSkipHydration)return r;let a=n(i.src);i.condition===`on:client`&&g(a);let o=d(i.condition),s=o?f(i.condition):void 0;return t(e,null,r,t(`div`,{dangerouslySetInnerHTML:{__html:h({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})},style:`display:contents`,"data-island-script":``}))}function S(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 C(e,t,r,i,a){let o={"data-condition":t,"data-src":n(e),"data-props":JSON.stringify(r),"data-render-strategy":`hydrate`,...S(i)};if(d(t)){o[`data-custom-directive`]=t;let e=f(t);e&&(o[`data-directive-script`]=e)}return a&&(o[`data-condition-arg`]=a),o}function w(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 T(e){let t=e.match(/<style[^>]*>([\s\S]*?)<\/style>/i);return t?t[1].trim():null}function E(e,t,n,r){if(e.css&&_(e.css,t,n,e.scopeId),e.head){let a=e.head.trim(),o=w(a);if(o===`style`){let o=T(a);o&&(i(`${r} Extracting CSS from head <style> tag`),_(o,t,n,e.scopeId));return}v(e.head,t,n,o)}}function D(e){let{islandId:n,detectedFramework:r,shouldSkipHydration:a,src:o,condition:s,conditionArg:c,props:l,hydrationData:u,children:d}=e,f={id:n,"data-framework":r},p=a?{"data-render-strategy":`ssr-only`}:C(o,s,l,u,c);r===`lit`&&i(`🔍 [Island Component] ${o} - 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),x(h,{islandId:n,src:o,condition:s,conditionArg:c,props:l,framework:r,shouldSkipHydration:a})}function O(e){let{islandId:r,detectedFramework:i,shouldSkipHydration:a,src:o,condition:s,props:c,hydrationData:l,conditionArg:u}=e;if(a)return t(`avalon-island`,{id:r,"data-render-strategy":`ssr-only`,"data-framework":i});let p={id:r,"data-condition":s,"data-src":n(o),"data-props":JSON.stringify(c),"data-render-strategy":`hydrate`,"data-framework":i,...S(l)};if(d(s)){p[`data-custom-directive`]=s;let e=f(s);e&&(p[`data-directive-script`]=e)}return u&&(p[`data-condition-arg`]=u),x(t(`avalon-island`,p),{islandId:r,src:o,condition:s,conditionArg:u,props:c,framework:i,shouldSkipHydration:a})}export default function k({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:o,ssr:s=t!==`on:client`,framework:c,ssrOnly:l=!1,renderOptions:u={},hydrationData:d={}}){let f=y(e),m=l||!!u.forceSSROnly,h=c||p(e),g=o!=null&&o!==``;return i(`🔍 [Island Component] ${e}`,{ssr:s,ssrOnly:l,hasChildren:g,framework:c,condition:t}),s&&g?D({islandId:f,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,conditionArg:n,props:r,hydrationData:d,children:o}):(s&&!g&&m&&a(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),O({islandId:f,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,props:r,hydrationData:d,conditionArg:n}))}function A(e,i){let a=i instanceof Error?i.message:String(i);return r(`🚨 Island SSR failed for ${e}:`,i),i instanceof Error&&i.stack&&r(`Stack trace:`,i.stack),t(`avalon-island`,{id:y(e),"data-src":n(e),"data-ssr-error":a,"data-render-strategy":`client-only`})}async function j({src:e,condition:t,conditionArg:n,props:i,children:a,ssr:s,framework:c,ssrOnly:l,renderOptions:u,component:d}){let f=`🏝️ [${e}]`;if(!s||a)return k({src:e,condition:t,conditionArg:n,props:i,children:a,ssr:s,framework:c,ssrOnly:l,renderOptions:u});let p;try{p=await m(c)}catch(a){return r(`${f} Failed to load ${c} integration:`,a),k({src:e,condition:t,conditionArg:n,props:i,ssr:!1,framework:c,ssrOnly:l,renderOptions:u})}try{let r=await p.render({component:d??null,props:i,src:e,condition:t,ssrOnly:l,viteServer:globalThis.__viteDevServer,isDev:o()});return E(r,e,c,f),k({src:e,condition:t,conditionArg:n,props:i,children:r.html,ssr:!0,framework:c,ssrOnly:l,renderOptions:u,hydrationData:l?void 0:r.hydrationData})}catch(a){return r(`${f} Fast path SSR failed:`,a),k({src:e,condition:t,conditionArg:n,props:i,ssr:!1,framework:c,ssrOnly:l,renderOptions:u})}}async function M(e,t,n,r){if(t||n.detectScripts===!1)return t;try{let t=await c(e,n);if(t.decision.warnings?.length)for(let e of t.decision.warnings)a(`${r} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return a(`${r} Component analysis failed:`,e),t}}async function N(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?u(e):`unknown`}async function P(e,t,n,r,i,a,s){let c=await N(e),l=c,u=await(await F(c,a)).render({component:s??null,props:n,src:e,condition:t,ssrOnly:r,viteServer:globalThis.__viteDevServer,isDev:o()});return E(u,e,c,a),k({src:e,condition:t,props:n,children:u.html,ssr:!0,framework:l,ssrOnly:r,renderOptions:i,hydrationData:r?void 0:u.hydrationData})}async function F(e,t){try{i(`${t} Loading integration for framework: ${e}`);let n=await m(e);return i(`${t} ✅ Integration loaded successfully`),n}catch(n){throw r(`${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:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:a=t!==`on:client`,framework:c,ssrOnly:l=!1,renderOptions:u={},component:d}){let f=o()?performance.now():0,p=`🏝️ [${e}]`;try{return l&&!a&&(a=!0),c?await j({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:c,ssrOnly:l,renderOptions:u,component:d}):await I({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,ssrOnly:l,renderOptions:u,logPrefix:p,component:d})}catch(t){return A(e,t)}finally{o()&&s(e,performance.now()-f)}}async function I(e){let{src:t,condition:n,conditionArg:a,props:o,children:s,ssr:c,ssrOnly:l,renderOptions:u,logPrefix:d,component:f}=e;if(i(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:c,ssrOnly:l,hasChildren:!!s,condition:n}),await M(t,l,u,d))return L(t,n,o,s,c,u,d);if(!c||s)return k({src:t,condition:n,conditionArg:a,props:o,children:s,ssr:c,renderOptions:u});try{return await P(t,n,o,l,u,d,f)}catch(e){let i=await N(t);return r(`${d} Framework rendering failed:`,e),k({src:t,condition:n,conditionArg:a,props:o,ssr:!1,framework:i,renderOptions:u})}}function L(e,t,n,i,a,o,s){return a&&!i?l({src:e,condition:t,props:n,renderOptions:o}).catch(i=>(r(`${s} SSR failed for SSR-only component:`,i),k({src:e,condition:t,props:n,ssr:!1,ssrOnly:!0,renderOptions:o}))):k({src:e,condition:t,props:n,children:i,ssr:a,ssrOnly:!0,renderOptions:o})}
1
+ import{Fragment as e,h as t}from"preact";import{getIslandBundlePath as n}from"../build/island-manifest.js";import{devError as r,devLog as i,devWarn as a,isDev as o,logRenderTiming as s}from"../utils/dev-logger.js";import{analyzeComponentFile as c,renderComponentSSROnly as l}from"./component-analysis.js";import{detectFramework as u}from"./framework-detection.js";import{isCustomDirective as d,serializeDirectiveScript as f}from"./hydration-directives.js";import{detectFrameworkFromPath as p,loadIntegration as m}from"./integration-loader.js";import{generatePerIslandScript as h}from"./per-island-script.js";import{addModulepreload as g}from"./modulepreload-collector.js";import{addUniversalCSS as _}from"./universal-css-collector.js";import{addUniversalHead as v}from"./universal-head-collector.js";function y(e){return`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}`}function b(){return globalThis.__avalonHydrationMode===void 0?globalThis.__viteDevServer?!1:typeof __AVALON_PER_ISLAND__<`u`?__AVALON_PER_ISLAND__:!o():globalThis.__avalonHydrationMode===`per-island`}function x(r,i){if(!b()||i.shouldSkipHydration)return r;let a=n(i.src);i.condition===`on:client`&&g(a);let o=d(i.condition),s=o?f(i.condition):void 0;return t(e,null,r,t(`div`,{dangerouslySetInnerHTML:{__html:h({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})},style:`display:contents`,"data-island-script":``}))}function S(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 C(e,t,r,i,a){let o={"data-condition":t,"data-src":n(e),"data-props":JSON.stringify(r),"data-render-strategy":`hydrate`,...S(i)};if(d(t)){o[`data-custom-directive`]=t;let e=f(t);e&&(o[`data-directive-script`]=e)}return a&&(o[`data-condition-arg`]=a),o}function w(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 T(e){let t=e.match(/<style[^>]*>([\s\S]*?)<\/style>/i);return t?t[1].trim():null}function E(e,t,n,r){if(e.css&&_(e.css,t,n,e.scopeId),e.head){let a=e.head.trim(),o=w(a);if(o===`style`){let o=T(a);o&&(i(`${r} Extracting CSS from head <style> tag`),_(o,t,n,e.scopeId));return}v(e.head,t,n,o)}}function D(e){let{islandId:n,detectedFramework:r,shouldSkipHydration:a,src:o,condition:s,conditionArg:c,props:l,hydrationData:u,children:d}=e,f={id:n,"data-framework":r},p=a?{"data-render-strategy":`ssr-only`}:C(o,s,l,u,c);r===`lit`&&i(`🔍 [Island Component] ${o} - 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),x(h,{islandId:n,src:o,condition:s,conditionArg:c,props:l,framework:r,shouldSkipHydration:a})}function O(e){let{islandId:r,detectedFramework:i,shouldSkipHydration:a,src:o,condition:s,props:c,hydrationData:l,conditionArg:u}=e;if(a)return t(`avalon-island`,{id:r,"data-render-strategy":`ssr-only`,"data-framework":i});let p={id:r,"data-condition":s,"data-src":n(o),"data-props":JSON.stringify(c),"data-render-strategy":`hydrate`,"data-framework":i,...S(l)};if(d(s)){p[`data-custom-directive`]=s;let e=f(s);e&&(p[`data-directive-script`]=e)}return u&&(p[`data-condition-arg`]=u),x(t(`avalon-island`,p),{islandId:r,src:o,condition:s,conditionArg:u,props:c,framework:i,shouldSkipHydration:a})}export default function k({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:o,ssr:s=t!==`on:client`,framework:c,ssrOnly:l=!1,renderOptions:u={},hydrationData:d={}}){let f=y(e),m=l||!!u.forceSSROnly,h=c||p(e),g=o!=null&&o!==``;return i(`🔍 [Island Component] ${e}`,{ssr:s,ssrOnly:l,hasChildren:g,framework:c,condition:t}),s&&g?D({islandId:f,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,conditionArg:n,props:r,hydrationData:d,children:o}):(s&&!g&&m&&a(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),O({islandId:f,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,props:r,hydrationData:d,conditionArg:n}))}function A(e,i){let a=i instanceof Error?i.message:String(i);return r(`🚨 Island SSR failed for ${e}:`,i),i instanceof Error&&i.stack&&r(`Stack trace:`,i.stack),t(`avalon-island`,{id:y(e),"data-src":n(e),"data-ssr-error":a,"data-render-strategy":`client-only`})}async function j({src:e,condition:t,conditionArg:n,props:i,children:a,ssr:s,framework:c,ssrOnly:l,renderOptions:u,component:d}){let f=`🏝️ [${e}]`;if(!s||a)return k({src:e,condition:t,conditionArg:n,props:i,children:a,ssr:s,framework:c,ssrOnly:l,renderOptions:u});let p;try{p=await m(c)}catch(a){return r(`${f} Failed to load ${c} integration:`,a),k({src:e,condition:t,conditionArg:n,props:i,ssr:!1,framework:c,ssrOnly:l,renderOptions:u})}try{let r=await p.render({component:d??null,props:i,src:e,condition:t,ssrOnly:l,viteServer:globalThis.__viteDevServer,isDev:o()});return E(r,e,c,f),k({src:e,condition:t,conditionArg:n,props:i,children:r.html,ssr:!0,framework:c,ssrOnly:l,renderOptions:u,hydrationData:l?void 0:r.hydrationData})}catch(a){return r(`${f} Fast path SSR failed:`,a),k({src:e,condition:t,conditionArg:n,props:i,ssr:!1,framework:c,ssrOnly:l,renderOptions:u})}}async function M(e,t,n,r){if(t||n.detectScripts===!1)return t;try{let t=await c(e,n);if(t.decision.warnings?.length)for(let e of t.decision.warnings)a(`${r} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return a(`${r} Component analysis failed:`,e),t}}async function N(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?u(e):`unknown`}async function P(e,t,n,r,i,a,s){let c=await N(e),l=c,u=await(await F(c,a)).render({component:s??null,props:n,src:e,condition:t,ssrOnly:r,viteServer:globalThis.__viteDevServer,isDev:o()});return E(u,e,c,a),k({src:e,condition:t,props:n,children:u.html,ssr:!0,framework:l,ssrOnly:r,renderOptions:i,hydrationData:r?void 0:u.hydrationData})}async function F(e,t){try{i(`${t} Loading integration for framework: ${e}`);let n=await m(e);return i(`${t} ✅ Integration loaded successfully`),n}catch(n){throw r(`${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:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:a=t!==`on:client`,framework:c,ssrOnly:l=!1,renderOptions:u={},component:d}){let f=o()?performance.now():0,p=`🏝️ [${e}]`;try{return l&&!a&&(a=!0),c?await j({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:c,ssrOnly:l,renderOptions:u,component:d}):await I({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,ssrOnly:l,renderOptions:u,logPrefix:p,component:d})}catch(t){return A(e,t)}finally{o()&&s(e,performance.now()-f)}}async function I(e){let{src:t,condition:n,conditionArg:a,props:o,children:s,ssr:c,ssrOnly:l,renderOptions:u,logPrefix:d,component:f}=e;if(i(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:c,ssrOnly:l,hasChildren:!!s,condition:n}),await M(t,l,u,d))return L(t,n,o,s,c,u,d);if(!c||s)return k({src:t,condition:n,conditionArg:a,props:o,children:s,ssr:c,renderOptions:u});try{return await P(t,n,o,l,u,d,f)}catch(e){let i=await N(t);return r(`${d} Framework rendering failed:`,e),k({src:t,condition:n,conditionArg:a,props:o,ssr:!1,framework:i,renderOptions:u})}}function L(e,t,n,i,a,o,s){return a&&!i?l({src:e,condition:t,props:n,renderOptions:o}).catch(i=>(r(`${s} SSR failed for SSR-only component:`,i),k({src:e,condition:t,props:n,ssr:!1,ssrOnly:!0,renderOptions:o}))):k({src:e,condition:t,props:n,children:i,ssr:a,ssrOnly:!0,renderOptions:o})}
@@ -1,4 +1,4 @@
1
- import{copyFileSync as e,cpSync as t,existsSync as n,mkdirSync as r,readdirSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u}from"node:path";function d(e,t,r=[]){if(!n(e))return r;for(let n of i(e,{withFileTypes:!0})){let i=l(e,n.name);n.isDirectory()?d(i,t,r):t(n.name)&&r.push(i)}return r}function f(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.length<500&&!t.includes(`data-framework`)&&!t.includes(`avalon`)}function p(e){for(let t of[`dist/index.html`,`.netlify/functions-internal/server/public/index.html`,`.output/public/index.html`]){let r=l(e,t);f(r)?(o(r),console.log(`[cleanup] Removed stale Vite template ${t}`)):n(r)&&console.log(`[cleanup] Kept ${t} (not a Vite template)`)}}function m(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,])\s*/g,`$1`).trim()}function h(e,t,r){if(!n(e))return;let i=[l(t,`assets`),l(r,`.netlify`,`functions-internal`,`server`,`public`,`assets`),l(r,`.output`,`public`,`assets`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.css`)).filter(e=>{let t=(e.split(`/`).pop()||``).toLowerCase();return t.includes(`_isolated-island-entry`)?!1:!!(t.startsWith(`entry-client`)||t.startsWith(`index-`))}).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);if(!o.some(e=>/\/index-[^/]+\.css$/.test(e))){let e=d(i,e=>e.endsWith(`.css`)).filter(e=>(e.split(`/`).pop()||``).toLowerCase().startsWith(`ssr-index`)).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);o.push(...e)}console.log(`[patch] Found ${o.length} CSS files in ${i}`);let c=a(e,`utf-8`);for(let{re:t,hrefRe:n,q:r}of[{re:/css:\[(\{href:`[^`]+`\}(?:,\{href:`[^`]+`\})*)\]/,hrefRe:/href:`([^`]+)`/g,q:"`"},{re:/css:\[(\{href:"[^"]+"\}(?:,\{href:"[^"]+"\})*)\]/,hrefRe:/href:"([^"]+)"/g,q:`"`}]){let i=t.exec(c);if(!i)continue;let a=new Set([...i[1].matchAll(n)].map(e=>e[1])),l=o.filter(e=>!a.has(e));if(l.length===0){console.log(`[patch] All CSS already included`);return}let u=l.map(e=>`{href:${r}${e}${r}}`).join(`,`);c=c.replace(i[0],`css:[${i[1]},${u}]`),s(e,c),console.log(`[patch] ✅ Added ${l.length} CSS files to SSR bundle`);return}console.warn(`[patch] Could not find CSS array in SSR bundle`)}function g(e,t){let o=l(t,`assets`);if(n(o)&&i(o).some(e=>e.startsWith(`entry-client`)&&e.endsWith(`.css`))){console.log(`[ssr-css] Skipped — client build already includes entry-client CSS`);return}let c=[l(e,`node_modules`,`.nitro`,`vite`,`services`,`ssr`,`assets`)];for(let o of c){if(!n(o))continue;let c=i(o).filter(e=>e.endsWith(`.css`));if(c.length===0)continue;let u=[l(t,`assets`),l(e,`.output`,`public`,`assets`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`assets`)];for(let e of u){r(e,{recursive:!0});for(let t of c){let n=a(l(o,t),`utf-8`);n=m(n),s(l(e,`ssr-${t}`),n)}}let d=`ssr-${c[0]}`,f=l(u.find(e=>n(e))||u[0],d),p=n(f)?a(f).length:0;console.log(`[ssr-css] Copied SSR CSS → /assets/${d} (${p} bytes, minified)`);let h=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of h){if(!n(e))continue;let t=a(e,`utf-8`),r=`/assets/${d}`;if(t.includes(r))continue;let i=/"\/assets\/[^"]+\.css":\{type:`text\/css[^}]+\}/.exec(t);if(i){let n=new Date().toISOString(),a=`,"${r}":{type:\`text/css; charset=utf-8\`,etag:\`${`"${p.toString(16)}-ssr"`}\`,mtime:\`${n}\`,size:${p},path:\`../public/assets/${d}\`}`;t=t.replace(i[0],i[0]+a),s(e,t),console.log(`[ssr-css] ✅ Patched asset manifest in ${e}`)}}return}console.log(`[ssr-css] No SSR CSS files found`)}async function _(e,t){let r=l(t,`islands`);if(!n(r)){console.log(`[islands] No islands directory found, skipping isolation`);return}let i=d(r,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(!i.some(e=>{let t=a(e,`utf-8`);return t.includes(`from"../`)||t.includes(`from'../`)})){console.log(`[islands] All islands are self-contained`);return}try{let{buildIsolatedIslands:r}=await import(`./isolated-island-builder.js`),o=new Map;for(let r of i){let i=u(t,r).replaceAll(`\\`,`/`).replace(/^islands\//,``).replace(/\.js$/,``),s=a(r,`utf-8`),c=`preact`;s.includes(`solid`)||s.includes(`createSignal`)?c=`solid`:s.includes(`vue`)||s.includes(`createApp`)?c=`vue`:s.includes(`svelte`)&&(c=`svelte`);let d=/from["']((?:\/|\.\/)[^"']+\.(tsx|ts|jsx|js|vue|svelte))["']/i.exec(s),f;if(d&&!d[1].includes(`/assets/`)&&!d[1].startsWith(`../`))f=d[1];else{let t=i;f=[`${t}.tsx`,`${t}.ts`,`${t}.jsx`,`${t}.js`,`${t}`].find(t=>n(l(e,t)))??`${t}.tsx`}f.startsWith(`src/islands/`)&&(f=f.slice(12)),f.startsWith(`/`)||(f=`/${f}`),o.set(i,{filePath:f,bundleKey:i,framework:c})}await r(e,t,o,[],{})}catch{console.warn(`[islands] Isolated rebuild failed, falling back to inline-islands`);try{let{inlineIslandChunks:e}=await import(`./inline-islands.js`);await e(t,{verbose:!0})}catch(e){console.error(`[islands] Inline fallback also failed:`,e)}}}function v(e,r){let i=l(r,`islands`);if(!n(i))return;let a=[l(e,`.output`,`public`),l(e,`.netlify`,`functions-internal`,`server`,`public`)];for(let e of a)n(e)&&t(i,l(e,`islands`),{recursive:!0,force:!0});console.log(`[islands] Synced isolated islands to output directories`)}function y(e){let t=l(e,`islands`);if(!n(t))return;let r=d(t,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(r.length===0)return;let i=[];for(let t of r){let n=t.substring(e.length).replaceAll(`\\`,`/`);i.push(`${n} ${n} 200`)}let o=l(e,`_redirects`),c=n(o)?a(o,`utf-8`):``;s(o,c?`${c}\n${i.join(`
1
+ import{copyFileSync as e,cpSync as t,existsSync as n,mkdirSync as r,readdirSync as i,readFileSync as a,unlinkSync as o,writeFileSync as s}from"node:fs";import{dirname as c,join as l,relative as u}from"node:path";function d(e,t,r=[]){if(!n(e))return r;for(let n of i(e,{withFileTypes:!0})){let i=l(e,n.name);n.isDirectory()?d(i,t,r):t(n.name)&&r.push(i)}return r}function f(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.length<500&&!t.includes(`data-framework`)&&!t.includes(`avalon`)}function p(e){for(let t of[`dist/index.html`,`.netlify/functions-internal/server/public/index.html`,`.output/public/index.html`]){let r=l(e,t);f(r)?(o(r),console.log(`[cleanup] Removed stale Vite template ${t}`)):n(r)&&console.log(`[cleanup] Kept ${t} (not a Vite template)`)}}function m(e){return e.replaceAll(/\/\*[\s\S]*?\*\//g,``).replaceAll(/\s+/g,` `).replaceAll(/\s*([{}:;,])\s*/g,`$1`).trim()}function h(e,t,r){if(!n(e))return;let i=[l(t,`assets`),l(r,`.netlify`,`functions-internal`,`server`,`public`,`assets`),l(r,`.output`,`public`,`assets`)].find(e=>n(e));if(!i)return;let o=d(i,e=>e.endsWith(`.css`)).filter(e=>{let t=(e.split(`/`).pop()||``).toLowerCase();return t.includes(`_isolated-island-entry`)?!1:!!(t.startsWith(`entry-client`)||t.startsWith(`index-`))}).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);if(!o.some(e=>/\/index-[^/]+\.css$/.test(e))){let e=d(i,e=>e.endsWith(`.css`)).filter(e=>(e.split(`/`).pop()||``).toLowerCase().startsWith(`ssr-index`)).map(e=>`/assets${e.substring(i.length).replaceAll(`\\`,`/`)}`);o.push(...e)}console.log(`[patch] Found ${o.length} CSS files in ${i}`);let c=a(e,`utf-8`);for(let{re:t,hrefRe:n,q:r}of[{re:/css:\[(\{href:`[^`]+`\}(?:,\{href:`[^`]+`\})*)\]/,hrefRe:/href:`([^`]+)`/g,q:"`"},{re:/css:\[(\{href:"[^"]+"\}(?:,\{href:"[^"]+"\})*)\]/,hrefRe:/href:"([^"]+)"/g,q:`"`}]){let i=t.exec(c);if(!i)continue;let a=new Set([...i[1].matchAll(n)].map(e=>e[1])),l=o.filter(e=>!a.has(e));if(l.length===0){console.log(`[patch] All CSS already included`);return}let u=l.map(e=>`{href:${r}${e}${r}}`).join(`,`);c=c.replace(i[0],`css:[${i[1]},${u}]`),s(e,c),console.log(`[patch] ✅ Added ${l.length} CSS files to SSR bundle`);return}console.warn(`[patch] Could not find CSS array in SSR bundle`)}function g(e,t){let o=l(t,`assets`);if(n(o)&&i(o).some(e=>e.startsWith(`entry-client`)&&e.endsWith(`.css`))){console.log(`[ssr-css] Skipped — client build already includes entry-client CSS`);return}let c=[l(e,`node_modules`,`.nitro`,`vite`,`services`,`ssr`,`assets`)];for(let o of c){if(!n(o))continue;let c=i(o).filter(e=>e.endsWith(`.css`));if(c.length===0)continue;let u=[l(t,`assets`),l(e,`.output`,`public`,`assets`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`assets`)];for(let e of u){r(e,{recursive:!0});for(let t of c){let n=a(l(o,t),`utf-8`);n=m(n),s(l(e,`ssr-${t}`),n)}}let d=`ssr-${c[0]}`,f=l(u.find(e=>n(e))||u[0],d),p=n(f)?a(f).length:0;console.log(`[ssr-css] Copied SSR CSS → /assets/${d} (${p} bytes, minified)`);let h=[l(e,`.output`,`server`,`index.mjs`),l(e,`.netlify`,`functions-internal`,`server`,`main.mjs`)];for(let e of h){if(!n(e))continue;let t=a(e,`utf-8`),r=`/assets/${d}`;if(t.includes(r))continue;let i=/"\/assets\/[^"]+\.css":\{type:`text\/css[^}]+\}/.exec(t);if(i){let n=new Date().toISOString(),a=`,"${r}":{type:\`text/css; charset=utf-8\`,etag:\`${`"${p.toString(16)}-ssr"`}\`,mtime:\`${n}\`,size:${p},path:\`../public/assets/${d}\`}`;t=t.replace(i[0],i[0]+a),s(e,t),console.log(`[ssr-css] ✅ Patched asset manifest in ${e}`)}}return}console.log(`[ssr-css] No SSR CSS files found`)}async function _(e,t){let r=l(t,`islands`);if(!n(r)){console.log(`[islands] No islands directory found, skipping isolation`);return}let i=d(r,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(!i.some(e=>{let t=a(e,`utf-8`);return t.includes(`from"../`)||t.includes(`from'../`)})){console.log(`[islands] All islands are self-contained`);return}try{let{buildIsolatedIslands:r}=await import(`./isolated-island-builder.js`),o=new Map;for(let r of i){let i=u(t,r).replaceAll(`\\`,`/`).replace(/^islands\//,``).replace(/\.js$/,``),s=a(r,`utf-8`),c=`preact`;i.includes(`.solid`)?c=`solid`:i.includes(`.vue`)||i.endsWith(`.vue`)?c=`vue`:i.includes(`.svelte`)||i.endsWith(`.svelte`)?c=`svelte`:i.includes(`.lit`)?c=`lit`:i.includes(`.qwik`)?c=`qwik`:i.includes(`.react`)?c=`react`:i.includes(`.preact`)&&(c=`preact`);let d=/from["']((?:\/|\.\/)[^"']+\.(tsx|ts|jsx|js|vue|svelte))["']/i.exec(s),f;if(d&&!d[1].includes(`/assets/`)&&!d[1].startsWith(`../`))f=d[1];else{let t=i;f=[`${t}.tsx`,`${t}.ts`,`${t}.jsx`,`${t}.js`,`${t}`].find(t=>n(l(e,t)))??`${t}.tsx`}f.startsWith(`src/islands/`)&&(f=f.slice(12)),f.startsWith(`/`)||(f=`/${f}`),o.set(i,{filePath:f,bundleKey:i,framework:c})}await r(e,t,o,[],{})}catch{console.warn(`[islands] Isolated rebuild failed, falling back to inline-islands`);try{let{inlineIslandChunks:e}=await import(`./inline-islands.js`);await e(t,{verbose:!0})}catch(e){console.error(`[islands] Inline fallback also failed:`,e)}}}function v(e,r){let i=l(r,`islands`);if(!n(i))return;let a=[l(e,`.output`,`public`),l(e,`.netlify`,`functions-internal`,`server`,`public`)];for(let e of a)n(e)&&t(i,l(e,`islands`),{recursive:!0,force:!0});console.log(`[islands] Synced isolated islands to output directories`)}function y(e){let t=l(e,`islands`);if(!n(t))return;let r=d(t,e=>e.endsWith(`.js`)&&!e.endsWith(`.js.map`));if(r.length===0)return;let i=[];for(let t of r){let n=t.substring(e.length).replaceAll(`\\`,`/`);i.push(`${n} ${n} 200`)}let o=l(e,`_redirects`),c=n(o)?a(o,`utf-8`):``;s(o,c?`${c}\n${i.join(`
2
2
  `)}`:i.join(`
3
3
  `)),console.log(`[redirects] Generated ${i.length} island redirect(s)`)}function b(e,a){let o=l(e,`node_modules`,`@useavalon`);if(!n(o))return;let s=[l(a,`adapters`),l(e,`.output`,`public`,`adapters`),l(e,`.netlify`,`functions-internal`,`server`,`public`,`adapters`)];for(let e of s){if(!n(c(e)))continue;let a=i(o).map(e=>l(o,e,`client`)).filter(e=>n(e));for(let n of a){let i=l(e,n.split(`/`).at(-2)||``);r(i,{recursive:!0}),t(n,i,{recursive:!0,force:!0})}}console.log(`[adapters] Copied framework adapters to output directories`)}function x(e){let i=l(e,`.netlify`,`functions-internal`),a=l(e,`.netlify`,`v1`,`functions`);n(i)&&(r(a,{recursive:!0}),t(i,a,{recursive:!0,force:!0}),console.log(`[netlify] Copied server function to v1 API paths`))}function S(e){if(!n(e))return!1;let t=a(e,`utf-8`);return t.includes(`netlify`)||t.includes(`lambda`)}function C(e,t,n){let r=l(c(e),`_prerender-server.mjs`);return s(r,`
4
4
  import 'urlpattern-polyfill';
@@ -16,6 +16,7 @@
16
16
  export interface IslandBuildResult {
17
17
  island: string;
18
18
  success: boolean;
19
+ skipped?: boolean;
19
20
  size?: number;
20
21
  error?: string;
21
22
  elapsedMs?: number;
@@ -1,3 +1,3 @@
1
1
  import{existsSync as e,statSync as t}from"node:fs";import{resolve as n}from"node:path";export const DEFAULT_TREESHAKE_CONFIG={annotations:!0,moduleSideEffects:!0,propertyReadSideEffects:!1,unknownGlobalSideEffects:!1,manualPureFunctions:[]};export function mergeTreeshakeConfig(e,t){return{annotations:t.annotations??e.annotations,moduleSideEffects:t.moduleSideEffects??e.moduleSideEffects,propertyReadSideEffects:t.propertyReadSideEffects??e.propertyReadSideEffects,unknownGlobalSideEffects:t.unknownGlobalSideEffects??e.unknownGlobalSideEffects,manualPureFunctions:[...e.manualPureFunctions,...t.manualPureFunctions??[]]}}const a={solid:`@useavalon/solid/client`,preact:`@useavalon/preact/client`,react:`@useavalon/react/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`};export function generateWrapperCode(e,t){let n=JSON.stringify(e);if(t===`qwik`)return[`export * from ${n};`,`export { _hW } from "@builder.io/qwik";`].join(`
2
2
  `);let r=a[t],i=[`import __C from ${n};`,`var Component = __C;`,`export { Component as default, Component };`,`if(typeof globalThis<"u")globalThis.__avalonIsland=Component;`];return r&&i.push(`export { hydrate as __hydrateIsland } from ${JSON.stringify(r)};`),i.join(`
3
- `)}export function generateIntegrationLoaderForFramework(e){let t=a[e];return t?`export { hydrate } from ${JSON.stringify(t)};`:`export {};`}async function c(e,t){let n=[],{resolve:r}=await import(`node:path`),{existsSync:i}=await import(`node:fs`),{pathToFileURL:a}=await import(`node:url`),o={solid:{pkg:`vite-plugin-solid`,esmEntry:`dist/esm/index.mjs`},vue:{pkg:`@vitejs/plugin-vue`,esmEntry:`dist/index.mjs`},svelte:{pkg:`@sveltejs/vite-plugin-svelte`,esmEntry:`src/index.js`}}[e];if(!o)return n;try{let s=null,c=t;for(let e=0;e<8;e++){let e=r(c,`node_modules`,o.pkg,o.esmEntry);if(i(e)){s=e;break}for(let e of[`solid`,`vue`,`svelte`,`preact`,`react`,`lit`]){let t=r(c,`packages`,`integrations`,e,`node_modules`,o.pkg,o.esmEntry);if(i(t)){s=t;break}}if(s)break;c=r(c,`..`)}if(!s)throw Error(`Cannot find package '${o.pkg}'`);let l=await import(a(s).href);switch(e){case`solid`:n.push((l.default??l)({ssr:!1,hot:!1}));break;case`vue`:n.push((l.default??l)());break;case`svelte`:n.push((l.svelte??l.default)());break}}catch(t){console.warn(` ⚠ Could not load ${e} plugin: ${t instanceof Error?t.message:t}`)}return n}async function l(e){let{createRequire:t}=await import(`node:module`),{existsSync:n}=await import(`node:fs`),r=t(`${e}/package.json`),i=e=>{try{let t=r.resolve(e);return t.endsWith(`.js`)&&n(t.replace(/\.js$/,`.mjs`))?t.replace(/\.js$/,`.mjs`):t}catch{return null}},a={preact:i(`preact`),"preact/hooks":i(`preact/hooks`),"preact/compat":i(`preact/compat`),"preact/compat/client":i(`preact/compat/client`),"preact/compat/server":i(`preact/compat/server`),"preact/jsx-runtime":i(`preact/jsx-runtime`),react:i(`preact/compat`),"react/jsx-runtime":i(`preact/jsx-runtime`),"react/jsx-dev-runtime":i(`preact/jsx-runtime`),"react-dom":i(`preact/compat`),"react-dom/client":i(`preact/compat/client`),"react-dom/server":i(`preact/compat/server`)};return{name:`avalon:isolated-preact-compat`,enforce:`pre`,resolveId(e){return a[e]??null}}}export async function buildIsolatedIslands(a,u,d,f,p,m){if(d.size===0)return[];let{build:h}=await import(`vite`);console.log(`🏝️ Building ${d.size} islands in isolation...`);let g=performance.now(),_=m?.treeshake?mergeTreeshakeConfig(DEFAULT_TREESHAKE_CONFIG,m.treeshake):DEFAULT_TREESHAKE_CONFIG,v=[];for(let[,r]of d){let{filePath:i,bundleKey:d,framework:m}=r,g=`islands/${d}.js`;if(m===`qwik`||m===`lit`||m===`preact`||m===`react`){v.push({island:g,success:!0});continue}let y=generateWrapperCode(i,m),b=`\0isolated-island-entry`,x=`\0virtual:avalon/integration-loader`;try{let r=await c(m,a),i=await l(a),o=performance.now(),S=await h({configFile:!1,root:a,logLevel:`silent`,plugins:[{name:`avalon:isolated-island-virtual`,resolveId(e){return e===b?e:e===`virtual:avalon/integration-loader`||e===x?x:null},load(e){return e===b?y:e===x?generateIntegrationLoaderForFramework(m):null}},i,...r],build:{write:!0,outDir:n(a,u),emptyOutDir:!1,minify:`oxc`,target:`es2022`,rollupOptions:{input:b,output:{format:`es`,entryFileNames:g},preserveEntrySignatures:`exports-only`,treeshake:_}},resolve:{alias:f},define:{...p,__DEV__:`false`,__PROD__:`true`,"process.env.NODE_ENV":`"production"`}}),C=performance.now()-o,w=n(a,u,g),T=e(w)?t(w).size:0,E=[],D=Array.isArray(S)?S:[S];for(let e of D)if(e&&`output`in e)for(let t of e.output)t.type===`chunk`&&t.fileName!==g&&E.push(`/${t.fileName}`);v.push({island:g,success:!0,size:T,elapsedMs:C,deps:E}),console.log(` ✅ ${d} (${m}): ${(T/1024).toFixed(1)} KiB`),C>2e3&&console.warn(` ⚠ ${d} (${m}): build took ${C.toFixed(0)}ms (>2s)`)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ❌ ${d} (${m}): ${t}`),v.push({island:g,success:!1,error:t})}}let y=((performance.now()-g)/1e3).toFixed(1),b=v.filter(e=>e.success).length,x=v.filter(e=>!e.success).length;console.log(`🏝️ Done in ${y}s: ${b} built${x?`, ${x} failed`:``}`);let S={};for(let e of v)e.success&&e.deps&&e.deps.length>0&&(S[`/${e.island}`]=e.deps);if(Object.keys(S).length>0){let e=n(a,u,`island-deps.json`),{writeFileSync:t}=await import(`node:fs`);t(e,JSON.stringify(S))}return v}
3
+ `)}export function generateIntegrationLoaderForFramework(e){let t=a[e];return t?`export { hydrate } from ${JSON.stringify(t)};`:`export {};`}async function c(e,t){let n=[],{resolve:r}=await import(`node:path`),{existsSync:i}=await import(`node:fs`),{pathToFileURL:a}=await import(`node:url`),o={solid:{pkg:`vite-plugin-solid`,esmEntry:`dist/esm/index.mjs`},vue:{pkg:`@vitejs/plugin-vue`,esmEntry:`dist/index.mjs`},svelte:{pkg:`@sveltejs/vite-plugin-svelte`,esmEntry:`src/index.js`}}[e];if(!o)return n;try{let s=null,c=t;for(let e=0;e<8;e++){let e=r(c,`node_modules`,o.pkg,o.esmEntry);if(i(e)){s=e;break}for(let e of[`solid`,`vue`,`svelte`,`preact`,`react`,`lit`]){let t=r(c,`packages`,`integrations`,e,`node_modules`,o.pkg,o.esmEntry);if(i(t)){s=t;break}}if(s)break;c=r(c,`..`)}if(!s)throw Error(`Cannot find package '${o.pkg}'`);let l=await import(a(s).href);switch(e){case`solid`:n.push((l.default??l)({ssr:!1,hot:!1}));break;case`vue`:n.push((l.default??l)());break;case`svelte`:n.push((l.svelte??l.default)());break}}catch(t){console.warn(` ⚠ Could not load ${e} plugin: ${t instanceof Error?t.message:t}`)}return n}async function l(e){let{createRequire:t}=await import(`node:module`),{existsSync:n}=await import(`node:fs`),r=t(`${e}/package.json`),i=e=>{try{let t=r.resolve(e);return t.endsWith(`.js`)&&n(t.replace(/\.js$/,`.mjs`))?t.replace(/\.js$/,`.mjs`):t}catch{return null}},a={preact:i(`preact`),"preact/hooks":i(`preact/hooks`),"preact/compat":i(`preact/compat`),"preact/compat/client":i(`preact/compat/client`),"preact/compat/server":i(`preact/compat/server`),"preact/jsx-runtime":i(`preact/jsx-runtime`),react:i(`preact/compat`),"react/jsx-runtime":i(`preact/jsx-runtime`),"react/jsx-dev-runtime":i(`preact/jsx-runtime`),"react-dom":i(`preact/compat`),"react-dom/client":i(`preact/compat/client`),"react-dom/server":i(`preact/compat/server`)};return{name:`avalon:isolated-preact-compat`,enforce:`pre`,resolveId(e){return a[e]??null}}}export async function buildIsolatedIslands(a,u,d,f,p,m){if(d.size===0)return[];let{build:h}=await import(`vite`),g=new Set([`qwik`,`lit`,`preact`,`react`]),_=[...d.values()].filter(e=>!g.has(e.framework));console.log(`🏝️ Building ${_.length} island(s) in isolation (${d.size-_.length} skipped)...`);let v=performance.now(),y=m?.treeshake?mergeTreeshakeConfig(DEFAULT_TREESHAKE_CONFIG,m.treeshake):DEFAULT_TREESHAKE_CONFIG,b=[];for(let[,r]of d){let{filePath:i,bundleKey:d,framework:m}=r,g=`islands/${d}.js`;if(m===`qwik`||m===`lit`||m===`preact`||m===`react`){b.push({island:g,success:!0,skipped:!0});continue}let _=generateWrapperCode(i,m),v=`\0isolated-island-entry`,x=`\0virtual:avalon/integration-loader`;try{let r=await c(m,a),i=await l(a),o=performance.now(),S=await h({configFile:!1,root:a,logLevel:`silent`,plugins:[{name:`avalon:isolated-island-virtual`,resolveId(e){return e===v?e:e===`virtual:avalon/integration-loader`||e===x?x:null},load(e){return e===v?_:e===x?generateIntegrationLoaderForFramework(m):null}},i,...r],build:{write:!0,outDir:n(a,u),emptyOutDir:!1,minify:`oxc`,target:`es2022`,rollupOptions:{input:v,output:{format:`es`,entryFileNames:g},preserveEntrySignatures:`exports-only`,treeshake:y}},resolve:{alias:f},define:{...p,__DEV__:`false`,__PROD__:`true`,"process.env.NODE_ENV":`"production"`}}),C=performance.now()-o,w=n(a,u,g),T=e(w)?t(w).size:0,E=[],D=Array.isArray(S)?S:[S];for(let e of D)if(e&&`output`in e)for(let t of e.output)t.type===`chunk`&&t.fileName!==g&&E.push(`/${t.fileName}`);b.push({island:g,success:!0,size:T,elapsedMs:C,deps:E}),console.log(` ✅ ${d} (${m}): ${(T/1024).toFixed(1)} KiB`),C>2e3&&console.warn(` ⚠ ${d} (${m}): build took ${C.toFixed(0)}ms (>2s)`)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(` ❌ ${d} (${m}): ${t}`),b.push({island:g,success:!1,error:t})}}let x=((performance.now()-v)/1e3).toFixed(1),S=b.filter(e=>e.success&&!e.skipped).length,C=b.filter(e=>e.skipped).length,w=b.filter(e=>!e.success).length,T=`🏝️ Done in ${x}s: ${S} built`;C&&(T+=`, ${C} skipped`),w&&(T+=`, ${w} failed`),console.log(T);let E={};for(let e of b)e.success&&e.deps&&e.deps.length>0&&(E[`/${e.island}`]=e.deps);if(Object.keys(E).length>0){let e=n(a,u,`island-deps.json`),{writeFileSync:t}=await import(`node:fs`);t(e,JSON.stringify(E))}return b}
@@ -6,28 +6,27 @@
6
6
 
7
7
  import type { IslandDirective } from './island-prop.d.ts';
8
8
 
9
+ /** Force TypeScript to expand the type inline on hover instead of showing the alias name */
10
+ type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
11
+
9
12
  declare module 'preact' {
10
13
  namespace JSX {
11
14
  interface IntrinsicAttributes {
12
- island?: IslandDirective;
15
+ island?: Expand<IslandDirective>;
13
16
  }
14
17
  }
15
18
  }
16
19
 
17
- // Augment the global JSX namespace so the `island` prop is accepted on
18
- // non-Preact components (Svelte, Solid) when used in a Preact JSX context.
19
20
  declare global {
20
21
  namespace JSX {
21
22
  interface IntrinsicAttributes {
22
- island?: IslandDirective;
23
+ island?: Expand<IslandDirective>;
23
24
  }
24
25
  }
25
26
  }
26
27
 
27
- // Augment Vue's ComponentCustomProps so Volar accepts `island` on all Vue SFCs.
28
28
  declare module '@vue/runtime-core' {
29
29
  interface ComponentCustomProps {
30
- island?: IslandDirective;
30
+ island?: Expand<IslandDirective>;
31
31
  }
32
32
  }
33
-
@@ -8,10 +8,27 @@
8
8
  * Usage:
9
9
  * import Counter from '../islands/Counter.tsx';
10
10
  * <Counter island={{ condition: 'on:interaction' }} someProp={42} />
11
+ *
12
+ * Custom directives:
13
+ * <Counter island={{ condition: 'on:delay' }} />
11
14
  */
12
15
 
13
- export interface IslandDirective {
14
- /** Hydration condition (built-in or custom directive name) */
16
+ export type IslandDirective = {
17
+ /**
18
+ * Hydration condition — controls when the island's JavaScript loads and executes.
19
+ *
20
+ * Built-in conditions:
21
+ * - `on:client` — hydrates immediately on page load
22
+ * - `on:visible` — hydrates when the element enters the viewport
23
+ * - `on:interaction` — hydrates on first click or hover
24
+ * - `on:idle` — hydrates when the browser is idle
25
+ * - `media:<query>` — hydrates when a CSS media query matches
26
+ *
27
+ * Custom conditions:
28
+ * - `on:<name>` — uses a registered custom hydration directive
29
+ *
30
+ * @default 'on:client'
31
+ */
15
32
  condition?:
16
33
  | "on:visible"
17
34
  | "on:interaction"
@@ -19,10 +36,22 @@ export interface IslandDirective {
19
36
  | "on:client"
20
37
  | `media:${string}`
21
38
  | `on:${string}`;
22
- /** Optional argument passed to custom hydration directives */
39
+
40
+ /**
41
+ * Stable identifier for the island instance.
42
+ * Used for state persistence with PersistentIsland.
43
+ * If omitted, Avalon generates one automatically from the component path.
44
+ */
45
+ id?: string;
46
+
47
+ /**
48
+ * Optional argument passed to custom hydration directives.
49
+ * For example, `on:delay` uses this as the delay in milliseconds.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * <Counter island={{ condition: 'on:delay', conditionArg: '5000' }} />
54
+ * ```
55
+ */
23
56
  conditionArg?: string;
24
- /** Force SSR-only rendering without client hydration */
25
- ssrOnly?: boolean;
26
- /** Whether to render server-side (default: true) */
27
- ssr?: boolean;
28
- }
57
+ };
@@ -1,4 +1,4 @@
1
- import{existsSync as e,readdirSync as t}from"node:fs";import{stat as n}from"node:fs/promises";import{createRequire as r}from"node:module";import{dirname as i,join as a,relative as o,resolve as s}from"node:path";import{nitro as c}from"nitro/vite";import{isRunnableDevEnvironment as l}from"vite";import{getUniversalCSSForHead as u}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as d,injectSolidHydrationScriptIfNeeded as f}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as p,discoverScopedMiddleware as m,executeScopedMiddleware as h}from"../middleware/index.js";import{createNitroConfig as g}from"../nitro/config.js";import{createIslandManifestPlugin as _,createNitroBuildPlugin as v,createSourceMapConfig as y,createSourceMapPlugin as b}from"../nitro/index.js";import{collectCssFromModuleGraph as x,injectSsrCss as S}from"../render/collect-css.js";import{generateErrorPage as C,generateFallback404 as w}from"../render/error-pages.js";function T(t){let n=a(i(r(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function E(t,n){let o=a(i(r(a(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(o)){let t=o.replace(/\.ts$/,`.js`);if(e(t))return t}return o}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`};export function createNitroIntegration(e,t={}){let n=g(t,e),r={preset:n.preset,serverDir:t.serverDir??n.serverDir??`./server`,routeRules:n.routeRules,runtimeConfig:n.runtimeConfig,compatibilityDate:n.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/]};t.renderer===!1?r.renderer=!1:n.renderer&&(r.renderer=n.renderer),n.publicRuntimeConfig&&(r.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(r.publicAssets=n.publicAssets),n.compressPublicAssets&&(r.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(r.serverEntry=n.serverEntry);let i=n.traceDeps??[];r.traceDeps=[...new Set([`undici`,...i])],n.prerender&&(r.prerender={routes:[],crawlLinks:!1});let a=c(r),o=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),s=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),l=v(e,t),u=_(e,{verbose:e.verbose,generatePreloadHints:!0}),d=b(y(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(a)?a:[a],o,s,l,u,d]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`},configureServer(e){globalThis.__viteDevServer=e;let r=null;async function i(){return r||=await m({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),r}function a(){r=null}F(e,t,n,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let o=e.environments?.ssr,s=!!o&&l(o);s&&N(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(r,a,o)=>{if(!s)return o();let c=r.url||`/`;if(c.endsWith(`.html`)&&(c=c.slice(0,-5)||`/`),c===`/index`&&(c=`/`),c.startsWith(`/@`)||c.startsWith(`/__`)||c.startsWith(`/node_modules/`)||c.startsWith(`/src/client/`)||c.startsWith(`/packages/`)||c.includes(`.`)&&!c.endsWith(`/`)||c.startsWith(`/api/`))return o();try{if(await j(e,c,r,a,i,n)||await q(e,c,t,a))return;let o=await J(e,c,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await M(e,c,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(C(e))}})},buildStart(){}}}async function j(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await h({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function M(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(w(t))}}async function N(e,t,n){let r=performance.now(),i=[{path:T(`src/render/ssr.ts`),assignTo:`ssr`},{path:T(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:T(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:E(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(G=r),n===`layout`&&(K=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:n,nitroConfig:r,verbose:i}=e,c=null,l=a,u=o,d=s,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=l(e,t.name);if(t.isDirectory()&&t.name!==`node_modules`&&!t.name.startsWith(`.`))m(n);else if(t.isFile()&&t.name.endsWith(`.css`)){let e=u(f,n).replaceAll(`\\`,`/`);p.push(e.startsWith(`/`)?e:`/${e}`)}}}catch{}}function h(){p.length=0;for(let e of r.globalCSS??[])p.push(e.startsWith(`/`)?e:`/${e}`);n.modules&&m(d(f,n.modules.dir)),m(d(f,n.layoutsDir))}return n.isDev&&h(),{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await I(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await L(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?R():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?z(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(c||=await B(n,r,p),c):e===RESOLVED_VIRTUAL_IDS.ASSETS?V(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?H(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await U(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):null},handleHotUpdate({file:e,server:t}){if(e.includes(n.pagesDir)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&t.moduleGraph.invalidateModule(e)}if(e.includes(`/layouts/`)||e.includes(`_layout`)||e.endsWith(`.css`)){c=null,h();let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&t.moduleGraph.invalidateModule(e);let n=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);n&&t.moduleGraph.invalidateModule(n)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&t.moduleGraph.invalidateModule(e)}}}}function F(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(p(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(G=null,K=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(p(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(p(),r?.())})}async function I(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
1
+ import{existsSync as e,readdirSync as t,rmSync as n}from"node:fs";import{stat as r}from"node:fs/promises";import{createRequire as i}from"node:module";import{dirname as a,join as o,relative as s,resolve as c}from"node:path";import{nitro as l}from"nitro/vite";import{isRunnableDevEnvironment as u}from"vite";import{getUniversalCSSForHead as d}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as f,injectSolidHydrationScriptIfNeeded as p}from"../islands/universal-head-collector.js";import{clearMiddlewareCache as m,discoverScopedMiddleware as h,executeScopedMiddleware as g}from"../middleware/index.js";import{createNitroConfig as _}from"../nitro/config.js";import{createIslandManifestPlugin as v,createNitroBuildPlugin as y,createSourceMapConfig as b,createSourceMapPlugin as x}from"../nitro/index.js";import{collectCssFromModuleGraph as S,injectSsrCss as C}from"../render/collect-css.js";import{generateErrorPage as w,generateFallback404 as T}from"../render/error-pages.js";function E(t){let n=o(a(i(import.meta.url).resolve(`@useavalon/avalon`)),t);if(t.endsWith(`.ts`)&&!e(n)){let t=n.replace(/\.ts$/,`.js`);if(e(t))return t}return n}function D(t,n){let r=o(a(i(o(process.cwd(),`package.json`)).resolve(`@useavalon/${t}`)),n);if(n.endsWith(`.ts`)&&!e(r)){let t=r.replace(/\.ts$/,`.js`);if(e(t))return t}return r}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,PAGE_LOADER:`virtual:avalon/page-loader`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`,LAYOUTS:`virtual:avalon/layouts`,ASSETS:`virtual:avalon/assets`,RENDERER:`virtual:avalon/renderer`,CLIENT_ENTRY:`virtual:avalon/client-entry`,INTEGRATION_LOADER:`virtual:avalon/integration-loader`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0${VIRTUAL_MODULE_IDS.PAGE_ROUTES}`,PAGE_LOADER:`\0${VIRTUAL_MODULE_IDS.PAGE_LOADER}`,ISLAND_MANIFEST:`\0${VIRTUAL_MODULE_IDS.ISLAND_MANIFEST}`,RUNTIME_CONFIG:`\0${VIRTUAL_MODULE_IDS.RUNTIME_CONFIG}`,CONFIG:`\0${VIRTUAL_MODULE_IDS.CONFIG}`,LAYOUTS:`\0${VIRTUAL_MODULE_IDS.LAYOUTS}`,ASSETS:`\0${VIRTUAL_MODULE_IDS.ASSETS}`,RENDERER:`\0${VIRTUAL_MODULE_IDS.RENDERER}`,CLIENT_ENTRY:`\0${VIRTUAL_MODULE_IDS.CLIENT_ENTRY}`,INTEGRATION_LOADER:`\0${VIRTUAL_MODULE_IDS.INTEGRATION_LOADER}`};export function createNitroIntegration(e,t={}){let n=_(t,e),r={preset:n.preset,serverDir:t.serverDir??n.serverDir??`./server`,routeRules:n.routeRules,runtimeConfig:n.runtimeConfig,compatibilityDate:n.compatibilityDate,scanDirs:[`.`],noExternals:[`estree-walker`,/^@useavalon\//,/^estree-util/]};t.renderer===!1?r.renderer=!1:n.renderer&&(r.renderer=n.renderer),n.publicRuntimeConfig&&(r.publicRuntimeConfig=n.publicRuntimeConfig),n.publicAssets&&(r.publicAssets=n.publicAssets),n.compressPublicAssets&&(r.compressPublicAssets=n.compressPublicAssets),n.serverEntry&&(r.serverEntry=n.serverEntry);let i=n.traceDeps??[];r.traceDeps=[...new Set([`undici`,...i])],n.prerender&&(r.prerender={routes:[],crawlLinks:!1});let a=l(r),o=createNitroCoordinationPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),s=createVirtualModulesPlugin({avalonConfig:e,nitroConfig:t,verbose:e.verbose}),c=y(e,t),u=v(e,{verbose:e.verbose,generatePreloadHints:!0}),d=x(b(t.preset??`node_server`,e.isDev));return{nitroOptions:n,plugins:[...Array.isArray(a)?a:[a],o,s,c,u,d]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:r}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,config(e,{command:t}){if(t===`serve`)return{server:{watch:{ignored:[`**/.output/**`,`**/dist/**`,`**/.netlify/**`,`**/.vercel/**`,`**/.cloudflare/**`,`**/.wrangler/**`,`**/.firebase/**`,`**/.amplify-hosting/**`]},fs:{deny:[`.output`,`dist`,`.netlify`,`.vercel`,`.cloudflare`,`.wrangler`,`.firebase`,`.amplify-hosting`]}}}},configResolved(e){globalThis.__avalonHydrationMode=e.command===`serve`?`entry-client`:`per-island`},configureServer(e){globalThis.__viteDevServer=e;let i=e.config.root||process.cwd(),a=e.config.build?.outDir?o(i,e.config.build.outDir):o(i,`dist`);try{n(a,{recursive:!0,force:!0})}catch{}try{n(o(i,`.output`),{recursive:!0,force:!0})}catch{}let s=!1,c=new Promise(t=>{let n=()=>{(e.environments?.nitro)?.devServer?.entry||s?(s=!0,t()):setTimeout(n,50)};setTimeout(n,100),setTimeout(()=>{s=!0,t()},15e3)});e.middlewares.use(async(e,t,n)=>{if(s)return n();let r=e.url||`/`;if(r.startsWith(`/@`)||r.startsWith(`/__`)||/\/[^/]+\.[a-z0-9]+(\?|$)/i.test(r))return n();await c,n()});let l=null;async function d(){return l||=await h({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),l}function f(){l=null}F(e,t,r,f),d().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)});let p=e.environments?.ssr,m=!!p&&u(p);m&&P(e,t.integrations,r).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(n,i,a)=>{if(!m)return a();let o=n.url||`/`;if(o.endsWith(`.html`)&&(o=o.slice(0,-5)||`/`),o===`/index`&&(o=`/`),o.startsWith(`/@`)||o.startsWith(`/__`)||o.startsWith(`/node_modules/`)||o.startsWith(`/src/client/`)||o.startsWith(`/packages/`)||o.includes(`.`)&&!o.endsWith(`/`)||o.startsWith(`/api/`))return a();try{if(await M(e,o,n,i,d,r)||await q(e,o,t,i))return;let a=await J(e,o,t);if(a){i.statusCode=200,i.setHeader(`Content-Type`,`text/html`),i.end(a);return}await N(e,o,i,t)}catch(e){console.error(`[SSR Error]`,e),i.statusCode=500,i.setHeader(`Content-Type`,`text/html`),i.end(w(e))}})},buildStart(){}}}async function M(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await g({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function N(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(T(t))}}async function P(e,t,n){let r=performance.now(),i=[{path:E(`src/render/ssr.ts`),assignTo:`ssr`},{path:E(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:E(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:D(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(G=r),n===`layout`&&(K=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:n,nitroConfig:r,verbose:i}=e,a=null,l=o,u=s,d=c,f=process.cwd(),p=[];function m(e){try{let n=t(e,{withFileTypes:!0});for(let t of n){let n=l(e,t.name);if(t.isDirectory()&&t.name!==`node_modules`&&!t.name.startsWith(`.`))m(n);else if(t.isFile()&&t.name.endsWith(`.css`)){let e=u(f,n).replaceAll(`\\`,`/`);p.push(e.startsWith(`/`)?e:`/${e}`)}}}catch{}}function h(){p.length=0;for(let e of r.globalCSS??[])p.push(e.startsWith(`/`)?e:`/${e}`);n.modules&&m(d(f,n.modules.dir)),m(d(f,n.layoutsDir));let e=d(f,n.layoutsDir,`..`);e!==f&&e!==d(f,n.layoutsDir)&&e.startsWith(f)&&m(e)}return n.isDev&&h(),{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.PAGE_LOADER?RESOLVED_VIRTUAL_IDS.PAGE_LOADER:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:e===VIRTUAL_MODULE_IDS.LAYOUTS?RESOLVED_VIRTUAL_IDS.LAYOUTS:e===VIRTUAL_MODULE_IDS.ASSETS?RESOLVED_VIRTUAL_IDS.ASSETS:e===VIRTUAL_MODULE_IDS.RENDERER?RESOLVED_VIRTUAL_IDS.RENDERER:e===VIRTUAL_MODULE_IDS.CLIENT_ENTRY?RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY:e===VIRTUAL_MODULE_IDS.INTEGRATION_LOADER?RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await I(n,i):e===RESOLVED_VIRTUAL_IDS.PAGE_LOADER?await L(n,i):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?R():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?z(n,r):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(n,r):e===RESOLVED_VIRTUAL_IDS.LAYOUTS?(a||=await B(n,r,p),a):e===RESOLVED_VIRTUAL_IDS.ASSETS?V(r):e===RESOLVED_VIRTUAL_IDS.RENDERER?H(n):e===RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY?await U(n,r):e===RESOLVED_VIRTUAL_IDS.INTEGRATION_LOADER?generateIntegrationLoaderModule(n):null},handleHotUpdate({file:e,server:t}){let n=e.includes(`/pages/`)&&!e.endsWith(`.css`),r=e.includes(`/components/`)&&/\.[tj]sx?$/.test(e),i=(e.includes(`/layouts/`)||e.includes(`_layout`))&&/\.[tj]sx?$/.test(e),o=e.endsWith(`.css`);if(n||r||i||o){if(n){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&t.moduleGraph.invalidateModule(e);let n=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_LOADER);n&&t.moduleGraph.invalidateModule(n)}if(i){a=null,h();let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.LAYOUTS);e&&t.moduleGraph.invalidateModule(e);let n=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CLIENT_ENTRY);n&&t.moduleGraph.invalidateModule(n)}setTimeout(()=>{t.ws.send({type:`full-reload`,path:`*`})},500)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=t.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&t.moduleGraph.invalidateModule(e)}}}}function F(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(m(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(G=null,K=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(m(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(m(),r?.())})}async function I(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
2
2
  export default pageRoutes;
3
3
  `}}async function L(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),{relative:r}=await import(`node:path`),i=process.cwd(),a=await n(await t(e.pagesDir,e.modules,i),{developmentMode:e.isDev}),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=`page_${e}`,c=r(i,t.filePath).replaceAll(`\\`,`/`),l=c.startsWith(`/`)?c:`/${c}`;o.push(`import * as ${n} from '${l}';`),s.push(` { pattern: ${JSON.stringify(t.pattern)}, params: ${JSON.stringify(t.params)}, module: ${n} }`)}return[...o,``,`const routes = [`,s.join(`,
4
4
  `),`];`,``,`/**`,` * Match a pathname against discovered routes and return the page module.`,` * Uses the same pattern matching as Avalon's route discovery.`,` */`,`export function loadPage(pathname) {`,` const cleanPath = pathname.split('?')[0];`,` for (const route of routes) {`,` if (matchRoute(cleanPath, route.pattern, route.params)) {`,` return route.module;`,` }`,` }`,` return null;`,`}`,``,`function matchRoute(pathname, pattern, paramNames) {`,` // Exact match`,` if (pattern === pathname) return true;`,` // Normalize trailing slashes`,` const normPath = pathname === '/' ? '/' : pathname.replace(/\\/$/, '');`,` const normPattern = pattern === '/' ? '/' : pattern.replace(/\\/$/, '');`,` if (normPath === normPattern) return true;`,` // Dynamic segments: /users/:id matches /users/123`,` if (paramNames.length > 0) {`,` const patternParts = normPattern.split('/');`,` const pathParts = normPath.split('/');`,` if (patternParts.length !== pathParts.length) return false;`,` return patternParts.every((part, i) => part.startsWith(':') || part === pathParts[i]);`,` }`,` return false;`,`}`,``,`export default { loadPage, routes };`,``].join(`
@@ -6,17 +6,17 @@ export default pageRoutes;
6
6
  export default { loadPage, routes: [] };
7
7
  `}}function R(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
8
8
  export default islandManifest;
9
- `}function z(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`const config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function B(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:i,resolve:o}=await import(`node:path`),{stat:s}=await import(`node:fs/promises`),c=process.cwd(),l=await r(e.layoutsDir,e.modules,c),u=[],d=0,f=o(c,e.layoutsDir);for(let{dir:t,prefix:n}of l){let r=a(t,`_layout.tsx`);try{if(!(await s(r)).isFile())continue}catch{continue}let o=i(c,r).replaceAll(`\\`,`/`),l=o.startsWith(`/`)?o:`/${o}`,p=t.startsWith(f),m=p&&!e.modules?`RootLayout`:`Layout_${d}`;u.push({prefix:n,importPath:l,varName:m,isShared:p}),d++}let p=u.filter(e=>e.isShared),m=u.filter(e=>!e.isShared),h=u.map(e=>`import ${e.varName} from '${e.importPath}';`),g=m.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${t} }`}),_=p.length>0?p[0].varName:`null`,v=JSON.stringify(n);return[`// Auto-generated by Avalon — do not edit`,`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`,`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,...h,``,`const RootLayoutComponent = ${_};`,`const _cssLinks = ${v};`,``,`const moduleLayouts = [`,g.join(`,
10
- `),`];`,``,`function getLayoutsForPath(pathname) {`,` for (const entry of moduleLayouts) {`,` if (entry.prefix === '/' ? pathname === '/' : pathname.startsWith(entry.prefix)) {`,` return entry;`,` }`,` }`,` return null;`,`}`,``,`function injectUniversalAssets(html) {`,` // In dev, inject <link> tags for all discovered CSS files.`,` // The ?direct suffix makes Vite return raw CSS (text/css) instead`,` // of a JS module wrapper, so <link rel="stylesheet"> works.`,` if (process.env.NODE_ENV !== 'production' && _cssLinks.length > 0) {`,` var links = _cssLinks.map(function(href) {`,` return '<link rel="stylesheet" href="' + href + '?direct">';`,` }).join('\\n');`,` if (html.includes('</head>')) {`,` html = html.replace('</head>', links + '\\n</head>');`,` }`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,` html = html.replace('</head>', universalCSS + '\\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,` html = html.replace('</head>', universalHead + '\\n</head>');`,` }`,` html = injectSolidHydrationScriptIfNeeded(html);`,` return html;`,`}`,``,`export async function wrapWithLayouts(pageHtml, pageModule, context, injectAssets) {`,` const pathname = context.url.pathname;`,` const frontmatter = {`,` ...(pageModule.frontmatter || {}),`,` ...(pageModule.metadata || {}),`,` currentPath: pathname,`,` };`,` const pageLayoutConfig = pageModule.layoutConfig;`,` const skipAll = pageLayoutConfig?.skipLayouts?.includes('_layout');`,``,` const layoutEntry = getLayoutsForPath(pathname);`,` const routeInfo = { path: pathname, params: context.params, query: context.url.searchParams };`,` let html;`,``,` if (!layoutEntry || skipAll) {`,` if (RootLayoutComponent && !skipAll) {`,` const rootProps = {`,` children: h('div', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` html = '<!DOCTYPE html>\\n' + preactRenderToString(resolvedRoot);`,` } else {`,` const title = String(frontmatter.title || 'Avalon');`,` html = [`,` '<!DOCTYPE html>',`,` '<html lang="en">',`,` '<head>',`,` '<meta charset="utf-8">',`,` '<meta name="viewport" content="width=device-width, initial-scale=1">',`,` '<title>' + title + '</title>',`,` '</head>',`,` '<body>',`,` '<div id="app">' + pageHtml + '</div>',`,` '</body>',`,` '</html>',`,` ].join('\\n');`,` }`,` } else {`,` const layoutProps = {`,` children: h('div', { dangerouslySetInnerHTML: { __html: pageHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const layoutResult = layoutEntry.Layout(layoutProps);`,` const resolvedLayout = layoutResult instanceof Promise ? await layoutResult : layoutResult;`,` let wrappedHtml = preactRenderToString(resolvedLayout);`,``,` if (!layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('div', { dangerouslySetInnerHTML: { __html: wrappedHtml } }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,` html = '<!DOCTYPE html>\\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
9
+ `}function z(e,t){let n={avalon:{streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:e.isDev},...t.runtimeConfig};return`export const runtimeConfig = ${JSON.stringify(n,null,2)};\nexport function useRuntimeConfig() { return runtimeConfig; }\nexport default runtimeConfig;\n`}export function generateConfigModule(e,t){let n=globalThis.__avalonConfig?.isDev??e.isDev,r={streaming:t.streaming??!0,pagesDir:e.pagesDir,layoutsDir:e.layoutsDir,isDev:n,...t.runtimeConfig};return`globalThis.__avalonHydrationMode = "${n?`entry-client`:`per-island`}";\nconst config = ${JSON.stringify(r,null,2)};\nexport function useAvalonConfig() { return config; }\nexport default config;\n`}async function B(e,t,n){let{getAllLayoutDirs:r}=await import(`./module-discovery.js`),{relative:i,resolve:a}=await import(`node:path`),{stat:s,readFile:c}=await import(`node:fs/promises`),l=process.cwd(),u=await r(e.layoutsDir,e.modules,l),d=[],f=0,p=a(l,e.layoutsDir);for(let{dir:t,prefix:n}of u){let r=o(t,`_layout.tsx`);try{if(!(await s(r)).isFile())continue}catch{continue}let a=i(l,r).replaceAll(`\\`,`/`),c=a.startsWith(`/`)?a:`/${a}`,u=t.startsWith(p),m=u&&!e.modules?`RootLayout`:`Layout_${f}`;d.push({prefix:n,importPath:c,varName:m,isShared:u,filePath:r}),f++}let m=d.filter(e=>e.isShared),h=d.filter(e=>!e.isShared),g=new Map;for(let e of h)try{let t=(await c(e.filePath,`utf8`)).match(/layoutConfig\s*=\s*{[\s\S]*?skipLayouts\s*:\s*\[([^\]]*)\]/)?.[1]??``,n=/['"`]_layout['"`]/.test(t);g.set(e.importPath,n)}catch{g.set(e.importPath,!1)}let _=d.map(e=>`import ${e.varName} from '${e.importPath}';`),v=h.toSorted((e,t)=>t.prefix.length-e.prefix.length).map(e=>{let t=e.prefix===`/`,n=g.get(e.importPath)??!1,r=t||n;return` { prefix: ${JSON.stringify(e.prefix)}, Layout: ${e.varName}, skipRoot: ${r} }`}),y=m.length>0?m[0].varName:`null`,b=JSON.stringify(n);return[`// Auto-generated by Avalon — do not edit`,`import { h } from 'preact';`,`import preactRenderToString from 'preact-render-to-string';`,`import { getUniversalCSSForHead } from '@useavalon/avalon/islands/universal-css-collector';`,`import { getUniversalHeadForInjection, injectSolidHydrationScriptIfNeeded } from '@useavalon/avalon/islands/universal-head-collector';`,..._,``,`const RootLayoutComponent = ${y};`,`const _cssLinks = ${b};`,``,`const moduleLayouts = [`,v.join(`,
10
+ `),`];`,``,`function getLayoutsForPath(pathname) {`,` for (const entry of moduleLayouts) {`,` if (entry.prefix === '/' ? pathname === '/' : pathname.startsWith(entry.prefix)) {`,` return entry;`,` }`,` }`,` return null;`,`}`,``,`function injectUniversalAssets(html) {`,` // In dev, inject <link> tags for all discovered CSS files.`,` // The ?direct suffix makes Vite return raw CSS (text/css) instead`,` // of a JS module wrapper, so <link rel="stylesheet"> works.`,` if (process.env.NODE_ENV !== 'production' && _cssLinks.length > 0) {`,` var links = _cssLinks.map(function(href) {`,` return '<link rel="stylesheet" href="' + href + '?direct">';`,` }).join('\\n');`,` if (html.includes('</head>')) {`,` html = html.replace('</head>', links + '\\n</head>');`,` }`,` }`,` const universalCSS = getUniversalCSSForHead(true);`,` if (universalCSS && html.includes('</head>')) {`,` html = html.replace('</head>', universalCSS + '\\n</head>');`,` }`,` const universalHead = getUniversalHeadForInjection(true);`,` if (universalHead && html.includes('</head>')) {`,` html = html.replace('</head>', universalHead + '\\n</head>');`,` }`,` html = injectSolidHydrationScriptIfNeeded(html);`,` return html;`,`}`,``,`export async function wrapWithLayouts(pageHtml, pageModule, context, injectAssets) {`,` const pathname = context.url.pathname;`,` const frontmatter = {`,` ...(pageModule.frontmatter || {}),`,` ...(pageModule.metadata || {}),`,` currentPath: pathname,`,` };`,` const pageLayoutConfig = pageModule.layoutConfig;`,` const skipAll = pageLayoutConfig?.skipLayouts?.includes('_layout');`,``,` const layoutEntry = getLayoutsForPath(pathname);`,` const routeInfo = { path: pathname, params: context.params, query: context.url.searchParams };`,` let html;`,``,` if (!layoutEntry || skipAll) {`,` if (RootLayoutComponent && !skipAll) {`,` const rootProps = {`,` children: h('avalon-page', { id: 'app', dangerouslySetInnerHTML: { __html: pageHtml }, style: 'display:contents' }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` html = '<!DOCTYPE html>\\n' + preactRenderToString(resolvedRoot);`,` } else {`,` // skipAll is true — page provides its own HTML shell or needs a minimal one`,` if (pageHtml.trimStart().startsWith('<html')) {`,` html = '<!DOCTYPE html>\\n' + pageHtml;`,` } else {`,` const title = String(frontmatter.title || 'Avalon');`,` html = [`,` '<!DOCTYPE html>',`,` '<html lang="en">',`,` '<head>',`,` '<meta charset="utf-8">',`,` '<meta name="viewport" content="width=device-width, initial-scale=1">',`,` '<title>' + title + '</title>',`,` '</head>',`,` '<body>',`,` '<div id="app">' + pageHtml + '</div>',`,` '</body>',`,` '</html>',`,` ].join('\\n');`,` }`,` }`,` } else {`,` const layoutProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: pageHtml }, style: 'display:contents' }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const layoutResult = layoutEntry.Layout(layoutProps);`,` const resolvedLayout = layoutResult instanceof Promise ? await layoutResult : layoutResult;`,` let wrappedHtml = preactRenderToString(resolvedLayout);`,``,` // If the layout provides its own HTML shell (starts with <html),`,` // skip root wrapping regardless of skipRoot flag — the layout IS the document.`,` const layoutProvidesShell = wrappedHtml.trimStart().startsWith('<html');`,``,` if (!layoutProvidesShell && !layoutEntry.skipRoot && RootLayoutComponent) {`,` const rootProps = {`,` children: h('avalon-page', { dangerouslySetInnerHTML: { __html: wrappedHtml }, style: 'display:contents' }),`,` frontmatter,`,` data: {},`,` route: routeInfo,`,` };`,` const rootResult = RootLayoutComponent(rootProps);`,` const resolvedRoot = rootResult instanceof Promise ? await rootResult : rootResult;`,` wrappedHtml = preactRenderToString(resolvedRoot);`,` }`,``,` html = '<!DOCTYPE html>\\n' + wrappedHtml;`,` }`,``,` if (injectAssets) {`,` html = injectAssets(html);`,` }`,` return injectUniversalAssets(html);`,`}`,``,`export default { wrapWithLayouts };`,``].join(`
11
11
  `)}function V(e){let t=e.clientEntry??`app/entry-client`;return[`// Auto-generated by Avalon — do not edit`,`// @ts-ignore — virtual import resolved by Nitro's Vite assets plugin at build time`,`import clientAssets from '${t.startsWith(`/`)?t:`/${t}`}?assets=client';`,``,`function buildAssetTags() {`,` const cssLinks = (clientAssets?.css ?? [])`,` .filter(attr => {`,` const href = attr.href || '';`,` // The SSR build produces ssr-index-*.css containing all global, reset,`,` // token, and layout CSS module styles. The client build may also emit`,` // entry-client-*.css (a subset) and index-*.css. To avoid duplicates,`,` // prefer ssr-index when it exists; otherwise fall back to the others.`,` var hasSsrIndex = (clientAssets?.css ?? []).some(function(a) { return (a.href || '').includes('ssr-index'); });`,` if (hasSsrIndex) return href.includes('ssr-index');`,` if (href.includes('entry-client') && href.endsWith('.css')) return true;`,` if (/\\/index-[^/]+\\.css$/.test(href)) return true;`,` return false;`,` })`,` .map(attr => '<link rel="stylesheet" href="' + attr.href + '">')`,` .join('\\n');`,` const jsPreloads = (clientAssets?.js ?? [])`,` .map(attr => '<link rel="modulepreload" href="' + attr.href + '">')`,` .join('\\n');`,` const entryScript = clientAssets?.entry`,` ? '<script type="module" src="' + clientAssets.entry + '"><\/script>'`,` : '';`,` return { cssLinks, jsPreloads, entryScript };`,`}`,``,`export function injectAssets(html) {`,` const { cssLinks, jsPreloads, entryScript } = buildAssetTags();`,` if (html.includes('</head>')) {`,` html = html.replace('</head>', cssLinks + '\\n' + jsPreloads + '\\n</head>');`,` }`,` if (html.includes('</body>')) {`,` html = html.replace('</body>', entryScript + '\\n</body>');`,` }`,` return html;`,`}`,``,`export { clientAssets };`,`export default { injectAssets, clientAssets };`,``].join(`
12
- `)}function H(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}return[`// Auto-generated by Avalon — do not edit`,`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const mod = loadPage(pathname);`,` if (!mod || !('default' in mod)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: {} };`,` },`,` loadPageModule: async (filePath) => {`,` const match = filePath.match(/^\\[virtual:(.+)\\]$/);`,` const pathname = match ? match[1] : filePath;`,` const mod = loadPage(pathname);`,` if (mod) return mod;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
12
+ `)}function H(e){let t=Array.isArray(e.integrations)?e.integrations:[],n=[],r=[];for(let e of t){let t=`${e}Integration`;n.push(`import { ${t} } from '@useavalon/${e}';`),r.push(`registry.register(${t});`)}return[`// Auto-generated by Avalon — do not edit`,`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,`import { registerBuiltinDirectives } from '@useavalon/avalon';`,`import { registry } from '@useavalon/avalon/islands/integration-registry';`,`import avalonConfig from 'virtual:avalon/config';`,`import { loadPage } from 'virtual:avalon/page-loader';`,`import { wrapWithLayouts } from 'virtual:avalon/layouts';`,`import { injectAssets } from 'virtual:avalon/assets';`,...n,``,`// Pre-register framework integrations for SSR`,...r,``,`// Register built-in custom hydration directives (on:delay, on:scroll, etc.)`,`registerBuiltinDirectives();`,``,`// Set hydration mode flag — intentionally duplicated from virtual:avalon/config`,`// for module-load-order resilience (config import may be tree-shaken or deferred).`,`globalThis.__avalonHydrationMode = avalonConfig.isDev ? "entry-client" : "per-island";`,``,`export default createNitroRenderer({`,` avalonConfig,`,` isDev: avalonConfig.isDev,`,` resolvePageRoute: async (pathname) => {`,` const mod = loadPage(pathname);`,` if (!mod || !('default' in mod)) return null;`,` return { filePath: '[virtual:' + pathname + ']', pattern: pathname, params: {} };`,` },`,` loadPageModule: async (filePath) => {`,` const match = filePath.match(/^\\[virtual:(.+)\\]$/);`,` const pathname = match ? match[1] : filePath;`,` const mod = loadPage(pathname);`,` if (mod) return mod;`,` return { default: () => null, metadata: { title: 'Avalon' } };`,` },`,` wrapWithLayouts: (pageHtml, pageModule, context) =>`,` wrapWithLayouts(pageHtml, pageModule, context, injectAssets),`,`});`,``].join(`
13
13
  `)}async function U(e,t){let{getAllLayoutDirs:n}=await import(`./module-discovery.js`),{readdir:r}=await import(`node:fs/promises`),{relative:i,join:a}=await import(`node:path`),o=process.cwd(),s=await n(e.layoutsDir,e.modules,o),c=[];for(let{dir:e}of s)try{let t=await r(e,{withFileTypes:!0});for(let n of t){if(!n.isFile()||!n.name.endsWith(`.css`))continue;let t=i(o,a(e,n.name)).replaceAll(`\\`,`/`),r=t.startsWith(`/`)?t:`/${t}`;c.push(r)}}catch{}let l=globalThis.__avalonConfig?.isDev??e.isDev?`@useavalon/avalon/client/main`:`@useavalon/avalon/client/main-slim`,u=[`// Auto-generated by Avalon — do not edit`,`// Island hydration runtime`];(globalThis.__avalonHydrationMode??`entry-client`)===`entry-client`?u.push(`import '${l}';`):u.push(`// Per-island hydration mode — no shared runtime needed`),u.push(``);let d=t.globalCSS??[];for(let e of d){let t=e.startsWith(`/`)?e:`/${e}`;u.push(`// Global CSS`),u.push(`import '${t}';`)}if(d.length>0&&u.push(``),c.length>0){u.push(`// Layout CSS (auto-discovered)`);let e=0;for(let t of c)t.includes(`.module.`)?(u.push(`import _lcss${e} from '${t}';`),e++):u.push(`import '${t}';`)}return u.push(``),u.join(`
14
14
  `)}export function generateIntegrationLoaderModule(e){let t=(e.integrations??[]).map(e=>typeof e==`string`?e:e.name),n={preact:`@useavalon/preact/client`,react:`@useavalon/preact/client`,vue:`@useavalon/vue/client`,svelte:`@useavalon/svelte/client`,solid:`@useavalon/solid/client`,lit:`@useavalon/lit/client`,qwik:`@useavalon/qwik/client`},r={preact:`@useavalon/preact/client/hmr`,react:`@useavalon/react/client/hmr`,vue:`@useavalon/vue/client/hmr`,svelte:`@useavalon/svelte/client/hmr`,solid:`@useavalon/solid/client/hmr`,lit:`@useavalon/lit/client/hmr`,qwik:`@useavalon/qwik/client/hmr`},i=t.includes(`lit`),a=t.includes(`solid`),o=(globalThis.__avalonConfig?.isDev??e.isDev)===!0,s=[`// Auto-generated by Avalon — only includes configured integrations`,``];a&&!o&&(s.push(`// --- Inlined Solid adapter (production) ---`),s.push(`// Eliminates a separate chunk + network request for the Solid client adapter.`),s.push(`// Only imports hydrate/createComponent — no render() fallback (saves ~1-2 KiB).`),s.push(`function _ensureHydrationContext() {`),s.push(` if (!globalThis._$HY) {`),s.push(` globalThis._$HY = { events: [], completed: new WeakSet(), r: {}, fe() {} };`),s.push(` }`),s.push(`}`),s.push(``),s.push(`async function _solidHydrate(container, Component, props) {`),s.push(` if (!container) throw new Error("Container element is required for hydration");`),s.push(` if (!Component || typeof Component !== "function") {`),s.push(` throw new Error("Invalid Solid component: expected function, got " + typeof Component);`),s.push(` }`),s.push(` var el = container;`),s.push(` var renderId = el.dataset.solidRenderId || el.dataset.renderId;`),s.push(` var { hydrate: solidHydrate, createComponent } = await import("solid-js/web");`),s.push(` _ensureHydrationContext();`),s.push(` solidHydrate(function() { return createComponent(Component, props || {}); }, el, { renderId: renderId || "" });`),s.push(`}`),s.push(``),s.push(`var _solidModule = { hydrate: _solidHydrate };`),s.push(``)),s.push(`// --- loadIntegrationModule ---`),s.push(`export async function loadIntegrationModule(framework) {`),s.push(` switch (framework) {`);for(let e of t){let t=n[e];t&&(e===`solid`&&!o?(s.push(` case "solid":`),s.push(` return _solidModule;`)):e===`react`?s.push(` case "react":`):e===`preact`?(s.push(` case "preact":`),s.push(` return import("${t}");`)):(s.push(` case "${e}":`),s.push(` return import("${t}");`)))}t.includes(`react`)&&!t.includes(`preact`)&&s.push(` return import("${n.react}");`),s.push(` default:`),s.push(" throw new Error(`Unknown or unconfigured framework: ${framework}`);"),s.push(` }`),s.push(`}`),s.push(``),s.push(`// --- Lit hydration pre-load (only if Lit is configured) ---`),i?(s.push(`export async function preLitHydration() {`),s.push(` await import("@useavalon/lit/client");`),s.push(`}`)):s.push(`export async function preLitHydration() {}`),s.push(``),s.push(`// --- HMR adapter loader ---`),s.push(`export async function loadHMRAdapter(framework) {`),s.push(` switch (framework) {`);for(let e of t){let t=r[e];t&&(s.push(` case "${e}":`),s.push(` return import("${t}").then(m => m.${e}Adapter);`))}return s.push(` default: return null;`),s.push(` }`),s.push(`}`),s.join(`
15
- `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const W=`<!--AVALON_STREAM_BOUNDARY-->`;let G=null,K=null;async function q(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Q(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),n=t.default;if(!n)return!1;let o=t.layoutConfig,s=await x(e,a),c=await Z(i,e),l=[];for(let t of c){let n=await e.ssrLoadModule(t);l.push({file:t,module:n})}for(let t of c){let n=await x(e,t);s.push(...n)}if(l.length===0)return!1;let{render:p}=await e.ssrLoadModule(`preact-render-to-string`),{h:m}=await e.ssrLoadModule(`preact`),h=o?.skipLayouts||[],g=l.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!h.includes(t)}),_=t.frontmatter,v=t.metadata,y={children:null,frontmatter:{..._,...v,currentPath:i},params:{},url:i},b=[],S=[];for(let e of g){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...y,children:m(`div`,null,`test`)}),r=p(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?b.push(e):S.push(e)}catch{S.push(e)}}if(b.length===0)return!1;let{module:C}=b[b.length-1],w=C.default;if(!w||typeof w!=`function`)return!1;let T;try{let e=w({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:W}})});T=p(e instanceof Promise?await e:e)}catch{return!1}let E=T.indexOf(W);if(E===-1)return!1;let D=T.slice(0,E),O=T.slice(E+29),k=D;if(s.length>0){let e=`<style data-avalon-ssr-css>${s.join(`
16
- `)}</style>`;k=D.includes(`</head>`)?D.replace(`</head>`,`${e}\n</head>`):D+e}k.trim().toLowerCase().startsWith(`<!doctype`)||(k=`<!DOCTYPE html>\n${k}`);let A=u(!0);A&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${A}\n</head>`));let j=d(!0);j&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${j}\n</head>`)),k=f(k),r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(k);let M;try{let e=typeof n==`function`?n():n;M=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering page component:`,e),M=`<div>Error rendering page</div>`}if(M.trim().startsWith(`<!DOCTYPE html>`)||M.trim().startsWith(`<html`))return r.end(M),!0;let N=M;for(let{module:e}of S){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:N}})});N=p(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering wrapper layout:`,e)}}let P=N+O;if(!P.includes(`/src/client/main.js`)&&!P.includes(`/@vite/client`)){let e=P.lastIndexOf(`</body>`);e!==-1&&(P=P.slice(0,e)+`
15
+ `)}export function getViteDevServer(){return globalThis.__viteDevServer}export function getAvalonConfig(){return globalThis.__avalonConfig}export function isDevelopmentMode(){return globalThis.__avalonConfig?.isDev??!0}const W=`<!--AVALON_STREAM_BOUNDARY-->`;let G=null,K=null;async function q(e,t,n,r){if(!n.modules)return!1;let i=t.split(`?`)[0],a=await Q(i,n,e);if(!a)return!1;try{let t=await e.ssrLoadModule(a),n=t.default;if(!n)return!1;let o=t.layoutConfig,s=await S(e,a),c=await Z(i,e),l=[];for(let t of c){let n=await e.ssrLoadModule(t);l.push({file:t,module:n})}for(let t of c){let n=await S(e,t);s.push(...n)}if(l.length===0)return!1;let{render:u}=await e.ssrLoadModule(`preact-render-to-string`),{h:m}=await e.ssrLoadModule(`preact`),h=o?.skipLayouts||[],g=l.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!h.includes(t)}),_=t.frontmatter,v=t.metadata,y={children:null,frontmatter:{..._,...v,currentPath:i},params:{},url:i},b=[],x=[];for(let e of g){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...y,children:m(`div`,null,`test`)}),r=u(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?b.push(e):x.push(e)}catch{x.push(e)}}if(b.length===0)return!1;let{module:C}=b[b.length-1],w=C.default;if(!w||typeof w!=`function`)return!1;let T;try{let e=w({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:W}})});T=u(e instanceof Promise?await e:e)}catch{return!1}let E=T.indexOf(W);if(E===-1)return!1;let D=T.slice(0,E),O=T.slice(E+29),k=D;if(s.length>0){let e=`<style data-avalon-ssr-css>${s.join(`
16
+ `)}</style>`;k=D.includes(`</head>`)?D.replace(`</head>`,`${e}\n</head>`):D+e}k.trim().toLowerCase().startsWith(`<!doctype`)||(k=`<!DOCTYPE html>\n${k}`);let A=d(!0);A&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${A}\n</head>`));let j=f(!0);j&&k.includes(`</head>`)&&(k=k.replace(`</head>`,`${j}\n</head>`)),k=p(k),r.statusCode=200,r.setHeader(`Content-Type`,`text/html; charset=utf-8`),r.setHeader(`Transfer-Encoding`,`chunked`),r.setHeader(`X-Avalon-Streaming`,`1`),r.flushHeaders(),r.write(k);let M;try{let e=typeof n==`function`?n():n;M=u(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering page component:`,e),M=`<div>Error rendering page</div>`}if(M.trim().startsWith(`<!DOCTYPE html>`)||M.trim().startsWith(`<html`))return r.end(M),!0;let N=M;for(let{module:e}of x){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...y,children:m(`div`,{dangerouslySetInnerHTML:{__html:N}})});N=u(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR Streaming] Error rendering wrapper layout:`,e)}}let P=N+O;if(!P.includes(`/src/client/main.js`)&&!P.includes(`/@vite/client`)){let e=P.lastIndexOf(`</body>`);e!==-1&&(P=P.slice(0,e)+`
17
17
  <script type="module" src="/@vite/client"><\/script>
18
18
  <script type="module" src="/src/client/main.js"><\/script>
19
- `+P.slice(e))}return r.end(P),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function J(e,t,n){let r=t.split(`?`)[0],i=await Q(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await x(e,i),s=await Z(r,e),c=[];for(let t of s){let n=await e.ssrLoadModule(t);c.push({file:t,module:n})}for(let t of s){let n=await x(e,t);o.push(...n)}let l;return l=n.modules&&c.length>0?await Y(a,t,c,r,n,e):await ee(a,t,r,n,e),o.length>0&&(l=S(l,o)),l}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Y(e,t,n,r,i,a){let{render:o}=await a.ssrLoadModule(`preact-render-to-string`),{h:s}=await a.ssrLoadModule(`preact`),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!c.includes(t)}),u;try{let t=typeof e==`function`?e():e;u=o(t instanceof Promise?await t:t)}catch(e){console.error(`[SSR] Error rendering page component:`,e),u=`<div>Error rendering page</div>`}if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return X(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},m=[],h=[];for(let e of l){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...p,children:s(`div`,null,`test`)}),r=o(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?m.push(e):h.push(e)}catch{h.push(e)}}let g=u;for(let{module:e}of h){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering wrapper layout:`,e)}}if(m.length>0){let{module:e}=m[m.length-1],t=e.default;if(t&&typeof t==`function`)try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering shell layout:`,e)}}if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return X(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
19
+ `+P.slice(e))}return r.end(P),!0}catch(e){return r.headersSent?(r.end(`<div>Streaming SSR error: ${e.message}</div></body></html>`),!0):!1}}async function J(e,t,n){let r=t.split(`?`)[0],i=await Q(r,n,e);if(!i)return null;try{let t=await e.ssrLoadModule(i),a=t.default;if(!a)return console.warn(`[SSR] Page ${i} has no default export`),null;let o=await S(e,i),s=await Z(r,e),c=[];for(let t of s){let n=await e.ssrLoadModule(t);c.push({file:t,module:n})}for(let t of s){let n=await S(e,t);o.push(...n)}let l;return l=n.modules&&c.length>0?await Y(a,t,c,r,n,e):await ee(a,t,r,n,e),o.length>0&&(l=C(l,o)),l}catch(e){throw console.error(`[SSR] Error rendering ${i}:`,e),e}}async function Y(e,t,n,r,i,a){let{render:o}=await a.ssrLoadModule(`preact-render-to-string`),{h:s}=await a.ssrLoadModule(`preact`),c=t.layoutConfig?.skipLayouts||[],l=n.filter(({file:e})=>{let t=e.split(`/`).pop()?.replace(/\.[^.]+$/,``)||``;return!c.includes(t)}),u;try{let t=typeof e==`function`?e():e;u=o(t instanceof Promise?await t:t)}catch(e){console.error(`[SSR] Error rendering page component:`,e),u=`<div>Error rendering page</div>`}if(u.trim().startsWith(`<!DOCTYPE html>`)||u.trim().startsWith(`<html`))return X(u);let d=t.frontmatter,f=t.metadata,p={children:null,frontmatter:{...d,...f,currentPath:r},params:{},url:r},m=[],h=[];for(let e of l){let t=e.module.default;if(!(!t||typeof t!=`function`))try{let n=t({...p,children:s(`div`,null,`test`)}),r=o(n instanceof Promise?await n:n);r.trim().startsWith(`<html`)||r.includes(`<!DOCTYPE`)?m.push(e):h.push(e)}catch{h.push(e)}}let g=u;for(let{module:e}of h){let t=e.default;if(!(!t||typeof t!=`function`))try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering wrapper layout:`,e)}}if(m.length>0){let{module:e}=m[m.length-1],t=e.default;if(t&&typeof t==`function`)try{let e=t({...p,children:s(`div`,{dangerouslySetInnerHTML:{__html:g}})});g=o(e instanceof Promise?await e:e)}catch(e){console.error(`[SSR] Error rendering shell layout:`,e)}}if(g.trim().startsWith(`<!DOCTYPE html>`)||g.trim().startsWith(`<html`))return X(g);let _=t.metadata||{},v=_.title||`Avalon App`,y=_.description||``;return`<!DOCTYPE html>
20
20
  <html lang="en">
21
21
  <head>
22
22
  <meta charset="utf-8">
@@ -29,12 +29,12 @@ export default islandManifest;
29
29
  ${g}
30
30
  <script type="module" src="/src/client/main.js"><\/script>
31
31
  </body>
32
- </html>`}function X(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=u(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=d(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=f(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
32
+ </html>`}function X(e){let t=e;if(t.trim().toLowerCase().startsWith(`<!doctype`)||(t=`<!DOCTYPE html>\n${t}`),!t.includes(`data-universal-ssr="true"`)){let e=d(!0);e&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${e}\n</head>`))}let n=f(!0);if(n&&t.includes(`</head>`)&&(t=t.replace(`</head>`,`${n}\n</head>`)),t=p(t),t.includes(`/src/client/main.js`)||t.includes(`/@vite/client`))return t;let r=t.lastIndexOf(`</body>`);return r===-1?t+`
33
33
  <script type="module" src="/@vite/client"><\/script>
34
34
  <script type="module" src="/src/client/main.js"><\/script>`:t.slice(0,r)+`
35
35
  <script type="module" src="/@vite/client"><\/script>
36
36
  <script type="module" src="/src/client/main.js"><\/script>
37
- `+t.slice(r)}async function Z(e,t){let r=t.config.root||process.cwd(),i=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await n(e)).isFile()){let t=e.slice(r.length);o.includes(t)||o.push(t)}}catch{}}if(i?.layoutsDir&&await l(`${`${r}/${i.layoutsDir}`}/${a}`),i?.modules){let e=`${r}/${i.modules.dir}`,t=i.modules.layoutsDirName,n=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!n||o.includes(n.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${n}/${t}/${a}`)}let u=`${r}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function Q(e,t,r){let i=e;i.endsWith(`/`)&&i!==`/`&&(i=i.slice(0,-1)),i===`/`&&(i=`/index`);let a=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],o=r.config.root||process.cwd();async function s(e){try{if((await n(`${o}/${e}`)).isFile())return`/${e}`}catch{}return null}if(t.modules){let n=t.modules.dir,r=t.modules.pagesDirName,o=e.split(`/`).filter(Boolean),c=o[0]||``,l=[`home`,`root`,`main`,`index`],u,d;if(!c||l.includes(c.toLowerCase()))u=`home`,d=i;else{u=c;let e=o.slice(1);d=e.length>0?`/${e.join(`/`)}`:`/index`}for(let e of a){let t=await s(`${n}/${u}/${r}${d}${e}`);if(t)return t}if(!d.endsWith(`/index`))for(let e of a){let t=await s(`${n}/${u}/${r}${d}/index${e}`);if(t)return t}}let c=t.pagesDir;for(let e of a){let t=await s(`${c}${i}${e}`);if(t)return t}if(!i.endsWith(`/index`))for(let e of a){let t=await s(`${c}${i}/index${e}`);if(t)return t}return null}async function ee(e,t,n,r,i){let a=t.metadata||{};try{G||=await i.ssrLoadModule(T(`src/render/ssr.ts`));let o=G;K||=await i.ssrLoadModule(T(`src/core/layout/enhanced-layout-resolver.ts`));let s=K,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter};if(o.renderToHtmlWithLayouts&&s.EnhancedLayoutResolver&&s.EnhancedLayoutResolverUtils)try{let e=i.config.root||process.cwd();if(!globalThis.__avalonLayoutResolver){let t=s.EnhancedLayoutResolver,n=r.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new t({baseDirectory:`${e}/${n}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:r.modules?`${e}/${r.modules.dir}`:void 0,modulesLayoutsDirName:r.modules?.layoutsDirName})}let t=`http://localhost${n}`,l={params:{},query:{},url:t,request:{method:`GET`,url:t,headers:new Headers}};return await o.renderToHtmlWithLayouts(c,globalThis.__avalonLayoutResolver,l,n,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}let o=a.title||`Avalon App`,s=a.description||``,c=``;try{let t=await i.ssrLoadModule(`preact-render-to-string`);t.render&&typeof e==`function`&&(c=t.render(e()))}catch{c=`<p>Loading page: ${$(n)}</p>`}return`<!DOCTYPE html>
37
+ `+t.slice(r)}async function Z(e,t){let n=t.config.root||process.cwd(),i=globalThis.__avalonConfig,a=`_layout.tsx`,o=[],s=e.split(`/`).filter(Boolean),c=[``];for(let e=0;e<s.length;e++)c.push(`/${s.slice(0,e+1).join(`/`)}`);async function l(e){try{if((await r(e)).isFile()){let t=e.slice(n.length);o.includes(t)||o.push(t)}}catch{}}if(i?.layoutsDir&&await l(`${`${n}/${i.layoutsDir}`}/${a}`),i?.modules){let e=`${n}/${i.modules.dir}`,t=i.modules.layoutsDirName,r=s[0]||``,o=[`home`,`root`,`main`,`index`];if(!r||o.includes(r.toLowerCase()))for(let n of o)await l(`${e}/${n}/${t}/${a}`);else await l(`${e}/${r}/${t}/${a}`)}let u=`${n}/src/layouts`;for(let e of c)await l(e===``?`${u}/${a}`:`${u}${e}/${a}`);return o}async function Q(e,t,n){let i=e;i.endsWith(`/`)&&i!==`/`&&(i=i.slice(0,-1)),i===`/`&&(i=`/index`);let a=[`.tsx`,`.ts`,`.jsx`,`.js`,`.mdx`,`.md`],o=n.config.root||process.cwd();async function s(e){try{if((await r(`${o}/${e}`)).isFile())return`/${e}`}catch{}return null}if(t.modules){let n=t.modules.dir,r=t.modules.pagesDirName,o=e.split(`/`).filter(Boolean),c=o[0]||``,l=[`home`,`root`,`main`,`index`],u,d;if(!c||l.includes(c.toLowerCase()))u=`home`,d=i;else{u=c;let e=o.slice(1);d=e.length>0?`/${e.join(`/`)}`:`/index`}for(let e of a){let t=await s(`${n}/${u}/${r}${d}${e}`);if(t)return t}if(!d.endsWith(`/index`))for(let e of a){let t=await s(`${n}/${u}/${r}${d}/index${e}`);if(t)return t}}let c=t.pagesDir;for(let e of a){let t=await s(`${c}${i}${e}`);if(t)return t}if(!i.endsWith(`/index`))for(let e of a){let t=await s(`${c}${i}/index${e}`);if(t)return t}return null}async function ee(e,t,n,r,i){let a=t.metadata||{};try{G||=await i.ssrLoadModule(E(`src/render/ssr.ts`));let o=G;K||=await i.ssrLoadModule(E(`src/core/layout/enhanced-layout-resolver.ts`));let s=K,c={component:()=>typeof e==`function`?e():e,options:{title:a.title||`Avalon App`},frontmatter:t.frontmatter};if(o.renderToHtmlWithLayouts&&s.EnhancedLayoutResolver&&s.EnhancedLayoutResolverUtils)try{let e=i.config.root||process.cwd();if(!globalThis.__avalonLayoutResolver){let t=s.EnhancedLayoutResolver,n=r.layoutsDir||`src/layouts`;globalThis.__avalonLayoutResolver=new t({baseDirectory:`${e}/${n}`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`,`build`],enableWatching:!0,developmentMode:!1,enableCaching:!0,cacheTTL:60*1e3,maxCacheSize:100,enableStreaming:!0,enableErrorBoundaries:!0,enableMetrics:!1,enableDebugInfo:!1,modulesDir:r.modules?`${e}/${r.modules.dir}`:void 0,modulesLayoutsDirName:r.modules?.layoutsDirName})}let t=`http://localhost${n}`,l={params:{},query:{},url:t,request:{method:`GET`,url:t,headers:new Headers}};return await o.renderToHtmlWithLayouts(c,globalThis.__avalonLayoutResolver,l,n,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}if(o.renderToHtml)return await o.renderToHtml(c,{title:a.title||`Avalon App`},void 0,{suppressWarnings:!0})}catch{}let o=a.title||`Avalon App`,s=a.description||``,c=``;try{let t=await i.ssrLoadModule(`preact-render-to-string`);t.render&&typeof e==`function`&&(c=t.render(e()))}catch{c=`<p>Loading page: ${$(n)}</p>`}return`<!DOCTYPE html>
38
38
  <html lang="en">
39
39
  <head>
40
40
  <meta charset="utf-8">
@@ -1 +1 @@
1
- import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{resolveConfig as r,checkDirectoriesExist as i}from"./config.js";import{activateIntegrations as a,activateSingleIntegration as o}from"./integration-activator.js";import{discoverIntegrationsFromIslandUsage as s}from"./auto-discover.js";import{validateActiveIntegrations as c,formatValidationResults as l}from"./validation.js";import{createMDXPlugin as u}from"../build/mdx-plugin.js";import{mdxIslandTransform as d}from"../build/mdx-island-transform.js";import{pageIslandTransform as f}from"../build/page-island-transform.js";import{registry as p}from"../core/integrations/registry.js";import{createNitroIntegration as m}from"./nitro-integration.js";import{islandSidecarPlugin as h}from"./island-sidecar-plugin.js";import{createImagePlugin as g}from"./image-optimization.js";import{islandClientBundlerPlugin as _}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as v}from"../build/island-code-splitting.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await y(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function y(e,t){let n=p.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function b(e,t){let n=new Set;try{let r=await s(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function x(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await b(e);return t.size===0?[...e.integrations]:Array.from(t)}async function S(e){try{let t=await u({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(d({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function C(e,t,n){let{plugins:r,nitroOptions:i}=m(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function w(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await s(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await o(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function T(e,t){if(!e.validateIntegrations||t.size===0)return;let n=c(t,e.showWarnings);n.allValid||(console.error(l(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(o){let s,c,l=new Set,u=r(o,!0),d=await x(u);d.length>0&&await a({...u,integrations:d},l);let p=await S(u),m=await g(u.image,u.verbose),y=[];l.size>0&&(y=await collectIntegrationPlugins(l,u.verbose));let b=[];if(o?.nitro){let{plugins:e}=C(u,o.nitro,u.verbose);b=e}let E=h({verbose:u.verbose}),D=e(import.meta.url),O=null;try{O=n(t(D.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let k=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),A={name:`avalon`,enforce:`pre`,config(){let e={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},t=d.flatMap(t=>e[t]??[]);return{oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...d.map(e=>`@useavalon/${e}`)],include:t}}},configResolved(e){c=e,s=r(o,e.command===`serve`),globalThis.__avalonConfig=s,i(s,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&O)return O;if(k.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await w(s,c?.root,l),T(s,l)},configureServer(e){globalThis.__viteDevServer=e}},j=y.filter(e=>e.name?.includes(`lit`)),M=y.filter(e=>!e.name?.includes(`lit`));return[f({pagesDir:u.pagesDir,layoutsDir:u.layoutsDir,modules:u.modules,verbose:u.verbose}),_(u,o?.nitro),v(u,o?.nitro),...m,...j,...p,A,E,...b,...M]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
1
+ import{createRequire as e}from"node:module";import{dirname as t,join as n}from"node:path";import{resolveConfig as r,checkDirectoriesExist as i}from"./config.js";import{activateIntegrations as a,activateSingleIntegration as o}from"./integration-activator.js";import{discoverIntegrationsFromIslandUsage as s}from"./auto-discover.js";import{validateActiveIntegrations as c,formatValidationResults as l}from"./validation.js";import{createMDXPlugin as u}from"../build/mdx-plugin.js";import{mdxIslandTransform as d}from"../build/mdx-island-transform.js";import{pageIslandTransform as f}from"../build/page-island-transform.js";import{registry as p}from"../core/integrations/registry.js";import{createNitroIntegration as m}from"./nitro-integration.js";import{islandSidecarPlugin as h}from"./island-sidecar-plugin.js";import{createImagePlugin as g}from"./image-optimization.js";import{islandClientBundlerPlugin as _}from"../build/island-client-bundler.js";import{islandCodeSplittingPlugin as v}from"../build/island-code-splitting.js";export async function collectIntegrationPlugins(e,t=!1){let n=[],r=[];for(let i of e){let e=await y(i,t);i===`lit`?r.push(...e):n.push(...e)}return[...r,...n]}async function y(e,t){let n=p.get(e);if(!n||typeof n.vitePlugin!=`function`)return[];try{let e=await n.vitePlugin();return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}catch(t){return console.warn(`[avalon] Failed to load vite plugin for ${e}:`,t instanceof Error?t.message:t),[]}}async function b(e,t){let n=new Set;try{let r=await s(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)e.integrations.includes(t)&&n.add(t)}catch{for(let t of e.integrations)n.add(t)}return n}async function x(e){if(!e.lazyIntegrations||e.integrations.length===0)return[...e.integrations];let t=await b(e);return t.size===0?[...e.integrations]:Array.from(t)}async function S(e){try{let t=await u({jsxImportSource:e.mdx.jsxImportSource,syntaxHighlighting:e.mdx.syntaxHighlighting,remarkPlugins:e.mdx.remarkPlugins,rehypePlugins:e.mdx.rehypePlugins,development:!0});return t.push(d({verbose:e.verbose})),t}catch(t){return e.showWarnings&&console.warn(`⚠️ Could not configure MDX plugin:`,t),[]}}function C(e,t,n){let{plugins:r,nitroOptions:i}=m(e,t);return globalThis.__nitroConfig=i,{plugins:r,options:i}}async function w(e,t,n){if(e.autoDiscoverIntegrations)try{let r=await s(e.pagesDir,e.layoutsDir,t,e.modules?.dir);for(let t of r)if(!n.has(t))try{await o(t,n,e.verbose)}catch(n){e.showWarnings&&console.warn(` ⚠️ Could not auto-load integration: ${t}`,n)}}catch(t){e.showWarnings&&console.warn(` ⚠️ Auto-discovery failed:`,t)}}function T(e,t){if(!e.validateIntegrations||t.size===0)return;let n=c(t,e.showWarnings);n.allValid||(console.error(l(n)),e.showWarnings&&console.warn(` ⚠️ Some integrations have validation issues.`))}export async function avalon(o){let s,c,l=new Set,u=r(o,!0),d=await x(u);d.length>0&&await a({...u,integrations:d},l);let p=await S(u),m=await g(u.image,u.verbose),y=[];l.size>0&&(y=await collectIntegrationPlugins(l,u.verbose));let b=[];if(o?.nitro){let{plugins:e}=C(u,o.nitro,u.verbose);b=e}let E=h({verbose:u.verbose}),D=e(import.meta.url),O=null;try{O=n(t(D.resolve(`@useavalon/avalon/client`)),`main.js`)}catch{}let k=new Set([`preact`,`react`,`vue`,`svelte`,`solid`,`lit`,`qwik`].flatMap(e=>[`/@useavalon/${e}/client`,`/@useavalon/${e}/client/hmr`,`@useavalon/${e}/client`,`@useavalon/${e}/client/hmr`])),A={name:`avalon`,enforce:`pre`,config(e,{command:t}){let n={preact:[`preact`,`preact/hooks`],react:[`react`,`react-dom`,`react-dom/client`],vue:[`vue`],svelte:[`svelte`,`svelte/internal`],solid:[`solid-js`,`solid-js/web`],lit:[`lit`,`@lit-labs/ssr-client`],qwik:[`@builder.io/qwik`]},r=d.flatMap(e=>n[e]??[]);return{define:{__AVALON_PER_ISLAND__:JSON.stringify(t===`build`)},oxc:{exclude:[/node_modules\/@useavalon\/.*\.tsx?$/]},ssr:{noExternal:[/^@useavalon\//]},optimizeDeps:{exclude:[`@useavalon/avalon`,...d.map(e=>`@useavalon/${e}`)],include:r}}},configResolved(e){c=e,s=r(o,e.command===`serve`),globalThis.__avalonConfig=s,i(s,e.root)},async resolveId(e){if(e===`/src/client/main.js`&&O)return O;if(k.has(e)){let t=e.startsWith(`/`)?e.slice(1):e;return(await this.resolve(t))?.id??null}return null},async transform(e,t){if(t.includes(`@useavalon/`)&&/\.tsx?$/.test(t)){let{transform:n}=await import(`oxc-transform`),r=await n(t,e,{sourcemap:!0,typescript:{onlyRemoveTypeImports:!1}});return{code:r.code,map:r.map,moduleType:`js`}}},async buildStart(){await w(s,c?.root,l),T(s,l)},configureServer(e){globalThis.__viteDevServer=e}},j=y.filter(e=>e.name?.includes(`lit`)),M=y.filter(e=>!e.name?.includes(`lit`));return[f({pagesDir:u.pagesDir,layoutsDir:u.layoutsDir,modules:u.modules,verbose:u.verbose}),_(u,o?.nitro),v(u,o?.nitro),...m,...j,...p,A,E,...b,...M]}export function getResolvedConfig(){return globalThis.__avalonConfig}export function getPagesDir(){return globalThis.__avalonConfig?.pagesDir??`src/pages`}export function getLayoutsDir(){return globalThis.__avalonConfig?.layoutsDir??`src/layouts`}export function getNitroConfig(){return globalThis.__nitroConfig}export function isNitroEnabled(){return globalThis.__nitroConfig!==void 0}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useavalon/avalon",
3
- "version": "0.1.85",
3
+ "version": "0.1.88",
4
4
  "description": "Multi-framework islands architecture for the modern web",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class LitHMRAdapter extends e{name=`lit`;elementConstructors=new WeakMap;tagNames=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`){let t=e;if(t.__litElement)return!0;try{let t=e.prototype;if(t){if(`render`in t&&`requestUpdate`in t&&`updateComplete`in t)return!0;let e=t;for(;e&&e!==Object.prototype;){let t=e.constructor;if(t&&t.name===`LitElement`)return!0;e=Object.getPrototypeOf(e)}}}catch{}if(t.elementName||t.tagName)return!0;try{let t=e.toString();if(t.includes(`LitElement`)||t.includes(`customElement`)||t.includes("html`")||t.includes("css`")||t.includes(`render()`)||t.includes(`requestUpdate`))return!0}catch{}}if(typeof e!=`object`)return!1;let t=e;return t.default&&typeof t.default==`function`?this.canHandle(t.default):!!t.__litElement}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i),o=e.getAttribute(`data-tag-name`)||this.tagNames.get(e),s=o?e.querySelector(o):e.querySelector(`[data-lit-element]`),c={},l={};if(s){for(let e in s)if(Object.hasOwn(s,e)&&!e.startsWith(`_`))try{let t=s[e];t!=null&&typeof t!=`function`&&typeof t!=`symbol`&&(c[e]=t)}catch{}for(let e=0;e<s.attributes.length;e++){let t=s.attributes[e];l[t.name]=t.value}}return{...t,framework:`lit`,data:{componentName:a,tagName:o||void 0,capturedProps:r,elementProperties:c,elementAttributes:l}}}catch(e){return console.warn(`Failed to preserve Lit state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Lit component`);let r;if(typeof t==`object`&&t){let e=t;if(e.default&&typeof e.default==`function`)r=e.default;else throw Error(`Lit component object must have a default export`)}else if(typeof t==`function`)r=t;else throw Error(`Invalid Lit component type`);try{let t=e.getAttribute(`data-tag-name`);if(t||=r.elementName,t||=r.name.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),!t||!t.includes(`-`))throw Error(`Invalid custom element tag name: `+t);this.tagNames.set(e,t),e.setAttribute(`data-tag-name`,t);let i=Array.from(e.querySelectorAll(t));if(i.length===0){let i=customElements.get(t);i?i!==r&&await this.reregisterCustomElement(t,r):customElements.define(t,r);let a=document.createElement(t);Object.entries(n).forEach(([e,t])=>{try{a[e]=t}catch(t){console.warn(`Failed to set property ${e} on Lit element:`,t)}}),e.appendChild(a),this.elementConstructors.set(e,r),e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`);return}let a=customElements.get(t);if(a&&a!==r){await this.reregisterCustomElement(t,r);for(let e of i){let n={},r={};for(let t in e)if(Object.hasOwn(e,t)&&!t.startsWith(`_`))try{let r=e[t];r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&(n[t]=r)}catch{}for(let t=0;t<e.attributes.length;t++){let n=e.attributes[t];r[n.name]=n.value}let i=document.createElement(t);Object.entries(r).forEach(([e,t])=>{i.setAttribute(e,t)}),Object.entries(n).forEach(([e,t])=>{try{i[e]=t}catch(t){console.warn(`Failed to restore property ${e}:`,t)}}),e.parentNode?.replaceChild(i,e)}}else if(a)for(let e of i)Object.entries(n).forEach(([t,n])=>{try{e[t]=n}catch(e){console.warn(`Failed to update property ${t}:`,e)}}),e.requestUpdate&&e.requestUpdate();else{customElements.define(t,r);for(let e of i)e.requestUpdate&&e.requestUpdate()}this.elementConstructors.set(e,r),e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`Lit HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}async reregisterCustomElement(e,t){console.warn(`Custom element ${e} is already defined. Replacing all instances with new definition.`)}restoreState(e,t){try{super.restoreState(e,t);let n=t,r=n.data.tagName;if(r){let t=e.querySelector(r);t&&(n.data.elementProperties&&Object.entries(n.data.elementProperties).forEach(([e,n])=>{try{t[e]=n}catch(t){console.warn(`Failed to restore property ${e}:`,t)}}),n.data.elementAttributes&&Object.entries(n.data.elementAttributes).forEach(([e,n])=>{try{t.setAttribute(e,n)}catch(t){console.warn(`Failed to restore attribute ${e}:`,t)}}),t.requestUpdate&&t.requestUpdate())}}catch(e){console.warn(`Failed to restore Lit state:`,e)}}handleError(e,t){console.error(`Lit HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`custom element`)||e.includes(`define`)?r=` (Hint: Check that your element has a valid tag name with a hyphen)`:e.includes(`tag name`)?r=` (Hint: Custom element tag names must contain a hyphen)`:e.includes(`property`)||e.includes(`attribute`)?r=` (Hint: Check @property decorators and attribute names)`:e.includes(`render`)?r=` (Hint: Check the render() method for errors)`:e.includes(`shadow`)&&(r=` (Hint: Check Shadow DOM usage and styles)`),n.textContent=`Lit HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.lit\.(ts|js)$/,``).replace(/\.(ts|js)$/,``)}unmount(e){try{let t=this.tagNames.get(e);t&&(e.querySelectorAll(t).forEach(e=>{e.remove()}),this.tagNames.delete(e)),this.elementConstructors.delete(e)}catch(e){console.warn(`Failed to unmount Lit element:`,e)}}}export const litAdapter=new LitHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class PreactHMRAdapter extends e{name=`preact`;instances=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`){let t=e,n=e.prototype;return n&&n.isReactComponent||t.$typeof,!0}if(typeof e!=`object`)return!1;let t=e;return!!(t.$typeof||t.type&&typeof t.type==`function`)}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i);return{...t,framework:`preact`,data:{componentName:a,capturedProps:r}}}catch(e){return console.warn(`Failed to preserve Preact state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Preact component`);let r=t;try{let{h:t,hydrate:i}=await import(`preact`);this.instances.get(e)?i(t(r,n),e):(i(t(r,n),e),this.instances.set(e,r)),e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`Preact HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore Preact state:`,e)}}handleError(e,t){console.error(`Preact HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`hooks`)?r=` (Hint: Check hooks usage - hooks must be called in the same order)`:e.includes(`render`)?r=` (Hint: Check component render method for errors)`:(e.includes(`hydration`)||e.includes(`hydrate`))&&(r=` (Hint: Server and client render must match)`),n.textContent=`Preact HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.(tsx?|jsx?)$/,``)}unmount(e){if(this.instances.get(e))try{this.instances.delete(e),e.innerHTML=``}catch(e){console.warn(`Failed to unmount Preact component:`,e)}}}export const preactAdapter=new PreactHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class QwikHMRAdapter extends e{name=`qwik`;containers=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`){let t=e;if(t.__brand===`QwikComponent`||t.__qrl||t.getSymbol||t.getHash)return!0;try{let t=e.toString();if(t.includes(`component$`)||t.includes(`qrl`)||t.includes(`useSignal`)||t.includes(`useStore`)||t.includes(`useTask$`)||t.includes(`useVisibleTask$`)||t.includes(`_qrl`)||t.includes(`qwik`))return!0}catch{}}if(typeof e==`object`&&e){let t=e;if(t.default&&typeof t.default==`function`)return this.canHandle(t.default);if(t.__qrl||t.__brand===`QwikComponent`)return!0}return!1}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i),o=e.closest(`[q\\:container]`)||e,s=o.querySelector(`script[type="qwik/json"]`)?.textContent||null,c={},l=o.attributes;if(l)for(let e=0;e<l.length;e++){let t=l[e];t.name.startsWith(`q:`)&&(c[t.name]=t.value)}return{...t,framework:`qwik`,data:{componentName:a,capturedProps:r,containerState:s,qContainerAttrs:c}}}catch(e){return console.warn(`Failed to preserve Qwik state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Qwik component`);let r;if(typeof t==`object`&&t){let e=t;if(e.default&&typeof e.default==`function`)r=e.default;else throw Error(`Qwik component object must have a default export`)}else if(typeof t==`function`)r=t;else throw Error(`Invalid Qwik component type`);try{let t=this.containers.get(e);if(t?.cleanup)try{t.cleanup()}catch(e){console.warn(`Failed to clean up existing Qwik container:`,e)}let i=await import(`@builder.io/qwik`);if(i.render){let t=typeof i.jsx==`function`?i.jsx(r,n):r(n);await i.render(e,t)}else{console.warn(`Qwik render API not available, using innerHTML fallback`);let t=r(n);typeof t==`string`&&(e.innerHTML=t)}this.containers.set(e,{}),e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`Qwik HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore Qwik state:`,e)}}handleError(e,t){console.error(`Qwik HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`component$`)||e.includes(`component\\$`)?r=` (Hint: Ensure component is wrapped with component$())`:e.includes(`useSignal`)||e.includes(`useStore`)?r=` (Hint: Qwik hooks must be called inside component$() body)`:e.includes(`QRL`)||e.includes(`qrl`)?r=` (Hint: Check that lazy-loaded boundaries use $ correctly)`:e.includes(`serialize`)||e.includes(`container`)?r=` (Hint: Ensure all state is serializable — Qwik serializes state to the DOM)`:(e.includes(`resumable`)||e.includes(`resume`))&&(r=` (Hint: Server and client container state must match for resumability)`),n.textContent=`Qwik HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.qwik\.(tsx?|jsx?)$/,``).replace(/\.(tsx?|jsx?)$/,``)}unmount(e){let t=this.containers.get(e);if(t)try{t.cleanup&&t.cleanup(),this.containers.delete(e)}catch(e){console.warn(`Failed to unmount Qwik component:`,e)}}}export const qwikAdapter=new QwikHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class ReactHMRAdapter extends e{name=`react`;roots=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`){let t=e,n=e.prototype;return n&&n.isReactComponent||t.$$typeof,!0}if(typeof e!=`object`)return!1;let t=e;return!!(t.$$typeof||t.type&&typeof t.type==`function`)}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i);return{...t,framework:`react`,data:{componentName:a,capturedProps:r}}}catch(e){return console.warn(`Failed to preserve React state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid React component`);let r=t;try{let[t,i]=await Promise.all([import(`react`),import(`react-dom/client`)]),{createElement:a}=t,{hydrateRoot:o}=i,s=this.roots.get(e);if(s){let e=a(r,n);s.render(e)}else{let t=o(e,a(r,n),{onRecoverableError:e=>{console.warn(`React hydration recoverable error during HMR:`,e)}});this.roots.set(e,t)}e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`React HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore React state:`,e)}}handleError(e,t){console.error(`React HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`hooks`)?r=` (Hint: Check hooks usage - hooks must be called in the same order)`:e.includes(`render`)?r=` (Hint: Check component render method for errors)`:e.includes(`hydration`)&&(r=` (Hint: Server and client render must match)`),n.textContent=`React HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.(tsx?|jsx?)$/,``)}unmount(e){let t=this.roots.get(e);if(t)try{t.unmount(),this.roots.delete(e)}catch(e){console.warn(`Failed to unmount React root:`,e)}}}export const reactAdapter=new ReactHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class SolidHMRAdapter extends e{name=`solid`;disposers=new WeakMap;componentIds=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`){if(e.__solid)return!0;try{let t=e.toString();if(t.includes(`createSignal`)||t.includes(`createEffect`)||t.includes(`createMemo`)||t.includes(`createResource`)||t.includes(`createStore`)||t.includes(`_$`)||t.includes(`_tmpl$`))return!0}catch{}return!0}if(typeof e!=`object`)return!1;let t=e;return t.default&&typeof t.default==`function`?this.canHandle(t.default):!!t.__solid}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i),o=e.dataset.solidRenderId||e.dataset.renderId;return{...t,framework:`solid`,data:{componentName:a,capturedProps:r,renderId:o}}}catch(e){return console.warn(`Failed to preserve Solid state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Solid component`);let r;if(typeof t==`object`&&t){let e=t;if(e.default&&typeof e.default==`function`)r=e.default;else throw Error(`Solid component object must have a default export`)}else if(typeof t==`function`)r=t;else throw Error(`Invalid Solid component type`);try{let t=this.disposers.get(e),i=this.componentIds.get(e),a=globalThis.__SOLID_HMR__;if(a&&i)try{if(a.reload(i,r),t)return}catch(e){console.warn(`Solid HMR runtime reload failed, falling back to full remount:`,e)}if(t)try{t(),this.disposers.delete(e)}catch(e){console.warn(`Failed to dispose existing Solid component:`,e)}let{hydrate:o,createComponent:s}=await import(`solid-js/web`),c=o(()=>s(r,n),e,{renderId:e.dataset.solidRenderId||e.dataset.renderId});this.disposers.set(e,c);let l=e.getAttribute(`data-src`)||``,u=this.generateComponentId(l);if(this.componentIds.set(e,u),a)try{a.createRecord(u,r)}catch(e){console.warn(`Failed to register with Solid HMR runtime:`,e)}e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`Solid HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore Solid state:`,e)}}handleError(e,t){console.error(`Solid HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`signal`)||e.includes(`Signal`)?r=` (Hint: Check signal usage - signals must be called as functions)`:e.includes(`effect`)||e.includes(`Effect`)?r=` (Hint: Check effect usage - effects run after render)`:e.includes(`hydration`)||e.includes(`hydrate`)?r=` (Hint: Server and client render must match)`:e.includes(`createSignal`)||e.includes(`createEffect`)?r=` (Hint: Solid primitives must be called inside component functions)`:e.includes(`reactive`)&&(r=` (Hint: Check reactive dependencies - they must be accessed inside tracking scopes)`),n.textContent=`Solid HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.solid\.(tsx?|jsx?)$/,``).replace(/\.(tsx?|jsx?)$/,``)}generateComponentId(e){return e.replace(/[^a-zA-Z0-9]/g,`_`)}unmount(e){let t=this.disposers.get(e);if(t)try{t(),this.disposers.delete(e),this.componentIds.delete(e)}catch(e){console.warn(`Failed to unmount Solid component:`,e)}}}export const solidAdapter=new SolidHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class SvelteHMRAdapter extends e{name=`svelte`;instances=new WeakMap;componentIds=new WeakMap;storeSubscriptions=new WeakMap;isSvelteFunction(e){if(e.$$render)return!0;let t=e.prototype;if(t&&(t.$set&&t.$destroy||t.$$))return!0;try{let t=e.toString();if(t.includes(`$set`)||t.includes(`$destroy`)||t.includes(`$$`))return!0}catch{}return!1}canHandle(e){if(!e)return!1;if(typeof e==`function`)return this.isSvelteFunction(e);if(typeof e!=`object`)return!1;let t=e;return t.default&&typeof t.default==`function`?this.canHandle(t.default):t.$$render!==void 0}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.dataset.props,r=n?JSON.parse(n):{},i=e.dataset.src||``,a=this.extractComponentName(i),o=this.captureLocalState(e),s=this.captureStoreValues(e);return{...t,framework:`svelte`,data:{componentName:a,capturedProps:r,localState:o,storeValues:s}}}catch(e){return console.warn(`Failed to preserve Svelte state:`,e),null}}extractComponent(e){if(typeof e==`object`&&e){let t=e;if(t.default&&typeof t.default==`function`)return t.default;throw Error(`Svelte component object must have a default export`)}if(typeof e==`function`)return e;throw TypeError(`Invalid Svelte component type`)}async cleanupInstance(e,t){try{let n=this.storeSubscriptions.get(e);n&&(n.forEach(e=>e()),this.storeSubscriptions.delete(e));let r=(await import(`svelte`)).unmount;r?r(t):t.$destroy&&t.$destroy()}catch{t.$destroy&&t.$destroy()}}async mountComponent(e,t,n){try{let r=(await import(`svelte`)).mount;return r?r(e,{target:t,props:n}):new e({target:t,props:n,hydrate:!1,intro:!1})}catch(r){return console.debug(`Svelte 5 API not available, using constructor API:`,r),new e({target:t,props:n,hydrate:!1,intro:!1})}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Svelte component`);let r=this.extractComponent(t);try{let t=this.instances.get(e);t&&await this.cleanupInstance(e,t).catch(e=>{console.warn(`Failed to destroy existing Svelte instance:`,e)}),e.innerHTML=``;let i=await this.mountComponent(r,e,n);this.instances.set(e,i);let a=e.dataset.src||``;this.componentIds.set(e,this.generateComponentId(a)),e.dataset.hydrated=`true`,e.dataset.hydrationStatus=`success`}catch(t){throw console.error(`Svelte HMR update failed:`,t),e.dataset.hydrationStatus=`error`,t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore Svelte state:`,e)}}handleError(e,t){console.error(`Svelte HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`$:`)||e.includes(`reactive`)?r=` (Hint: Check reactive statements ($:) - they must be at component top level)`:e.includes(`store`)?r=` (Hint: Check store usage - stores must be imported and subscribed correctly)`:e.includes(`hydration`)||e.includes(`hydrate`)?r=` (Hint: Server and client render must match)`:e.includes(`target`)?r=` (Hint: Check component target - it must be a valid DOM element)`:e.includes(`props`)&&(r=` (Hint: Check component props - they must match the component definition)`),n.textContent=`Svelte HMR Error: ${e}${r}`}}extractComponentName(e){return(e.split(`/`).at(-1)??``).replace(/\.svelte$/,``)}detectSSRContent(e){let t=e.textContent&&e.textContent.trim().length>0,n=e.children&&e.children.length>0,r=e.dataset.ssrContent!==void 0||e.dataset.svelteRendered!==void 0;return t||n||r}generateComponentId(e){return e.replaceAll(/[^a-zA-Z0-9]/g,`_`)}captureLocalState(e){try{let t=this.instances.get(e);if(!t)return;let n=t.$$;return n?.ctx?{ctx:n.ctx,props:n.props,bound:n.bound}:void 0}catch(e){console.debug(`Could not capture Svelte local state:`,e);return}}captureStoreValues(e){}async unmount(e){let t=this.instances.get(e);if(t)try{await this.cleanupInstance(e,t),this.instances.delete(e),this.componentIds.delete(e)}catch(e){console.warn(`Failed to unmount Svelte component:`,e)}}}export const svelteAdapter=new SvelteHMRAdapter;
@@ -1 +0,0 @@
1
- import{BaseFrameworkAdapter as e}from"../framework-adapter.js";export class VueHMRAdapter extends e{name=`vue`;apps=new WeakMap;componentIds=new WeakMap;canHandle(e){if(!e)return!1;if(typeof e==`function`)return!0;if(typeof e!=`object`)return!1;let t=e;return`setup`in t||`data`in t||`render`in t||`template`in t||`props`in t||`computed`in t||`methods`in t||`components`in t||`emits`in t||`mounted`in t||`created`in t||`beforeMount`in t||`beforeCreate`in t||`__vccOpts`in t}preserveState(e){try{let t=super.preserveState(e);if(!t)return null;let n=e.getAttribute(`data-props`),r=n?JSON.parse(n):{},i=e.getAttribute(`data-src`)||``,a=this.extractComponentName(i),o=this.captureReactiveData(e);return{...t,framework:`vue`,data:{componentName:a,capturedProps:r,reactiveData:o}}}catch(e){return console.warn(`Failed to preserve Vue state:`,e),null}}async update(e,t,n){if(!this.canHandle(t))throw Error(`Component is not a valid Vue component`);let r=t;try{let{createApp:t}=await import(`vue`),i=this.apps.get(e),a=this.componentIds.get(e),o=globalThis.__VUE_HMR_RUNTIME__;if(o&&a)try{if(o.reload(a,r),i)return}catch(e){console.warn(`Vue HMR runtime reload failed, falling back to full remount:`,e)}if(i)try{i.unmount()}catch(e){console.warn(`Failed to unmount existing Vue app:`,e)}let s=t(r,n);s.config.errorHandler=(e,t,n)=>{console.error(`Vue component error during HMR:`,e,n)},s.mount(e,!0),this.apps.set(e,s);let c=e.getAttribute(`data-src`)||``,l=this.generateComponentId(c);this.componentIds.set(e,l),o&&o.createRecord(l,r),e.setAttribute(`data-hydrated`,`true`),e.setAttribute(`data-hydration-status`,`success`)}catch(t){throw console.error(`Vue HMR update failed:`,t),e.setAttribute(`data-hydration-status`,`error`),t}}restoreState(e,t){try{super.restoreState(e,t)}catch(e){console.warn(`Failed to restore Vue state:`,e)}}handleError(e,t){console.error(`Vue HMR error:`,t),super.handleError(e,t);let n=e.querySelector(`.hmr-error-indicator`);if(n){let e=t.message,r=``;e.includes(`reactive`)||e.includes(`ref`)?r=` (Hint: Check reactive state usage - refs must be accessed with .value)`:e.includes(`render`)?r=` (Hint: Check component render function or template for errors)`:e.includes(`hydration`)||e.includes(`mismatch`)?r=` (Hint: Server and client render must match)`:e.includes(`setup`)&&(r=` (Hint: Check setup function - it should return render function or object)`),n.textContent=`Vue HMR Error: ${e}${r}`}}extractComponentName(e){let t=e.split(`/`);return t[t.length-1].replace(/\.(vue|tsx?|jsx?)$/,``)}generateComponentId(e){return e.replace(/[^a-zA-Z0-9]/g,`_`)}captureReactiveData(e){try{let t=e.__vueParentComponent;if(t&&typeof t==`object`){let e=t.data;if(e&&typeof e==`object`)return{...e}}}catch(e){console.debug(`Could not capture Vue reactive data:`,e)}}unmount(e){let t=this.apps.get(e);if(t)try{t.unmount(),this.apps.delete(e),this.componentIds.delete(e)}catch(e){console.warn(`Failed to unmount Vue app:`,e)}}}export const vueAdapter=new VueHMRAdapter;
@@ -1,14 +0,0 @@
1
- import type { RoutePageModule } from '../../schemas/routing.ts';
2
- /**
3
- * Server-side MDX processor for handling MDX files in the routing system
4
- */
5
- export declare class MDXProcessor {
6
- /**
7
- * Process an MDX file and return a valid page module
8
- */
9
- processMDXFile(filePath: string): Promise<RoutePageModule>;
10
- /**
11
- * Check if a file is an MDX file
12
- */
13
- static isMDXFile(filePath: string): boolean;
14
- }
@@ -1 +0,0 @@
1
- import{extname as e}from"node:path";import{readFile as t}from"node:fs/promises";import{h as n}from"preact";import{marked as r}from"marked";export class MDXProcessor{async processMDXFile(e){try{let i=await t(e,`utf-8`);return{default:()=>n(`div`,{dangerouslySetInnerHTML:{__html:r(i)}})}}catch(t){throw Error(`Failed to process MDX file ${e}: ${t instanceof Error?t.message:String(t)}`)}}static isMDXFile(t){let n=e(t);return n===`.mdx`||n===`.md`}}
@@ -1,85 +0,0 @@
1
- /**
2
- * Framework-aware module resolver for handling framework-specific path transformations
3
- * and MIME type resolution during hydration and module serving.
4
- */
5
- export interface ModuleResolutionConfig {
6
- framework: string;
7
- baseUrl: string;
8
- extensions: string[];
9
- transformPath: (path: string) => string;
10
- mimeType: string;
11
- }
12
- export interface ResolvedModule {
13
- originalPath: string;
14
- resolvedPath: string;
15
- framework: string;
16
- shouldTransform: boolean;
17
- mimeType: string;
18
- url: string;
19
- }
20
- export interface FrameworkModuleConfig {
21
- extensions: string[];
22
- hydrationExtension: string;
23
- mimeType: string;
24
- transformPath: (path: string, mode: 'development' | 'production') => string;
25
- }
26
- export declare class FrameworkModuleResolver {
27
- private mode;
28
- private baseUrl;
29
- constructor(mode?: 'development' | 'production', baseUrl?: string);
30
- /**
31
- * Resolve a module path for a specific framework
32
- */
33
- resolveModule(originalPath: string, framework: string, options?: {
34
- forHydration?: boolean;
35
- baseUrl?: string;
36
- }): ResolvedModule;
37
- /**
38
- * Check if a path needs transformation for the given framework
39
- */
40
- needsTransformation(path: string, framework: string): boolean;
41
- /**
42
- * Get the appropriate MIME type for a file path
43
- */
44
- getMimeType(path: string): string;
45
- /**
46
- * Generate a module URL for the given path
47
- */
48
- generateModuleUrl(path: string, baseUrl?: string): string;
49
- /**
50
- * Get supported frameworks
51
- */
52
- getSupportedFrameworks(): string[];
53
- /**
54
- * Get framework configuration
55
- */
56
- getFrameworkConfig(framework: string): FrameworkModuleConfig | undefined;
57
- /**
58
- * Check if a framework is supported
59
- */
60
- isFrameworkSupported(framework: string): boolean;
61
- /**
62
- * Get file extension from path
63
- */
64
- private getFileExtension;
65
- /**
66
- * Set the resolver mode (development/production)
67
- */
68
- setMode(mode: 'development' | 'production'): void;
69
- /**
70
- * Get current mode
71
- */
72
- getMode(): 'development' | 'production';
73
- /**
74
- * Set base URL for module resolution
75
- */
76
- setBaseUrl(baseUrl: string): void;
77
- /**
78
- * Get current base URL
79
- */
80
- getBaseUrl(): string;
81
- }
82
- /**
83
- * Default instance for common usage
84
- */
85
- export declare const frameworkModuleResolver: FrameworkModuleResolver;
@@ -1 +0,0 @@
1
- const e={solid:{extensions:[`.tsx`,`.jsx`],hydrationExtension:`.js`,mimeType:`application/javascript`,transformPath:(e,t)=>e.endsWith(`.tsx`)?e.replace(/\.tsx$/,`.js`):e.endsWith(`.jsx`)?e.replace(/\.jsx$/,`.js`):e},preact:{extensions:[`.tsx`,`.jsx`],hydrationExtension:`.js`,mimeType:`application/javascript`,transformPath:(e,t)=>e.endsWith(`.tsx`)?e.replace(/\.tsx$/,`.js`):e.endsWith(`.jsx`)?e.replace(/\.jsx$/,`.js`):e},vue:{extensions:[`.vue`],hydrationExtension:`.js`,mimeType:`application/javascript`,transformPath:(e,t)=>e.endsWith(`.vue`)?e.replace(/\.vue$/,`.js`):e},svelte:{extensions:[`.svelte`],hydrationExtension:`.js`,mimeType:`application/javascript`,transformPath:(e,t)=>e.endsWith(`.svelte`)?e.replace(/\.svelte$/,`.js`):e},qwik:{extensions:[`.tsx`,`.jsx`],hydrationExtension:`.js`,mimeType:`application/javascript`,transformPath:(e,t)=>e.endsWith(`.tsx`)?e.replace(/\.tsx$/,`.js`):e.endsWith(`.jsx`)?e.replace(/\.jsx$/,`.js`):e}};export class FrameworkModuleResolver{mode;baseUrl;constructor(e=`development`,t=``){this.mode=e,this.baseUrl=t}resolveModule(t,n,r={}){let i=e[n];if(!i)throw Error(`Unknown framework: ${n}`);let{forHydration:a=!1,baseUrl:o=this.baseUrl}=r,s=t,c=!1,l=this.getMimeType(t);if(a){let e=i.transformPath(t,this.mode);e!==t&&(s=e,c=!0,l=i.mimeType)}let u=this.generateModuleUrl(s,o);return{originalPath:t,resolvedPath:s,framework:n,shouldTransform:c,mimeType:l,url:u}}needsTransformation(t,n){let r=e[n];return r?r.transformPath(t,this.mode)!==t:!1}getMimeType(e){switch(this.getFileExtension(e)){case`.js`:case`.mjs`:return`application/javascript`;case`.ts`:case`.tsx`:case`.jsx`:return`application/javascript`;case`.css`:return`text/css`;case`.json`:return`application/json`;case`.vue`:case`.svelte`:return`application/javascript`;default:return`text/plain`}}generateModuleUrl(e,t=this.baseUrl){let n=e.startsWith(`/`)?e:`/${e}`;return t?`${t.replace(/\/$/,``)}${n}`:n}getSupportedFrameworks(){return Object.keys(e)}getFrameworkConfig(t){return e[t]}isFrameworkSupported(t){return t in e}getFileExtension(e){let t=e.lastIndexOf(`.`);return t===-1?``:e.substring(t)}setMode(e){this.mode=e}getMode(){return this.mode}setBaseUrl(e){this.baseUrl=e}getBaseUrl(){return this.baseUrl}}export const frameworkModuleResolver=new FrameworkModuleResolver;
@@ -1,17 +0,0 @@
1
- import type { IslandDirective } from './island-prop.d.ts';
2
- import type { ComponentType } from 'preact';
3
- /**
4
- * Cast a cross-framework component (Vue, Svelte, Lit, Solid) to be usable
5
- * in Preact JSX with the `island` prop and correct prop types.
6
- *
7
- * The Vite transform handles these components at build time — this cast is
8
- * purely for TypeScript's benefit.
9
- *
10
- * @example
11
- * import _VueCounter from '../islands/VueCounter.vue';
12
- * const VueCounter = asIsland<{ initialCount?: number }>(_VueCounter);
13
- * // Now usable as: <VueCounter island={{ condition: 'on:visible' }} initialCount={0} />
14
- */
15
- export declare function asIsland<P extends Record<string, unknown> = Record<string, unknown>>(_component: unknown): ComponentType<P & {
16
- island?: IslandDirective;
17
- }>;
@@ -1 +0,0 @@
1
- export function asIsland(e){return e}
@@ -1,6 +0,0 @@
1
- export type ImportConfig = {
2
- names: string[];
3
- from: string;
4
- };
5
- export type CleanupFunction = () => void;
6
- export * from './layout.ts';
@@ -1 +0,0 @@
1
- export*from"./layout.js";