@useavalon/avalon 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/README.md +54 -54
  2. package/dist/mod.js +1 -0
  3. package/dist/src/build/integration-bundler-plugin.js +1 -0
  4. package/dist/src/build/integration-config.js +1 -0
  5. package/dist/src/build/integration-detection-plugin.js +1 -0
  6. package/dist/src/build/integration-resolver-plugin.js +1 -0
  7. package/dist/src/build/island-manifest.js +1 -0
  8. package/dist/src/build/island-types-generator.js +5 -0
  9. package/dist/src/build/mdx-island-transform.js +2 -0
  10. package/dist/src/build/mdx-plugin.js +1 -0
  11. package/dist/src/build/page-island-transform.js +3 -0
  12. package/dist/src/build/prop-extractors/index.js +1 -0
  13. package/dist/src/build/prop-extractors/lit.js +1 -0
  14. package/dist/src/build/prop-extractors/qwik.js +1 -0
  15. package/dist/src/build/prop-extractors/solid.js +1 -0
  16. package/dist/src/build/prop-extractors/svelte.js +1 -0
  17. package/dist/src/build/prop-extractors/vue.js +1 -0
  18. package/dist/src/build/sidecar-file-manager.js +1 -0
  19. package/dist/src/build/sidecar-renderer.js +6 -0
  20. package/dist/src/client/adapters/index.js +1 -0
  21. package/dist/src/client/components.js +1 -0
  22. package/dist/src/client/css-hmr-handler.js +1 -0
  23. package/dist/src/client/framework-adapter.js +13 -0
  24. package/dist/src/client/hmr-coordinator.js +1 -0
  25. package/dist/src/client/hmr-error-overlay.js +214 -0
  26. package/dist/src/client/main.js +39 -0
  27. package/{src → dist/src}/client/types/framework-runtime.d.ts +68 -68
  28. package/{src → dist/src}/client/types/vite-hmr.d.ts +46 -46
  29. package/dist/src/client/types/vite-virtual-modules.d.ts +70 -0
  30. package/dist/src/components/Image.js +1 -0
  31. package/dist/src/components/IslandErrorBoundary.js +1 -0
  32. package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
  33. package/dist/src/components/LayoutErrorBoundary.js +1 -0
  34. package/dist/src/components/PersistentIsland.js +1 -0
  35. package/dist/src/components/StreamingErrorBoundary.js +1 -0
  36. package/dist/src/components/StreamingLayout.js +29 -0
  37. package/dist/src/core/components/component-analyzer.js +1 -0
  38. package/dist/src/core/components/component-detection.js +5 -0
  39. package/dist/src/core/components/enhanced-framework-detector.js +1 -0
  40. package/dist/src/core/components/framework-registry.js +1 -0
  41. package/dist/src/core/content/mdx-processor.js +1 -0
  42. package/dist/src/core/integrations/index.js +1 -0
  43. package/dist/src/core/integrations/loader.js +1 -0
  44. package/dist/src/core/integrations/registry.js +1 -0
  45. package/dist/src/core/islands/island-persistence.js +1 -0
  46. package/dist/src/core/islands/island-state-serializer.js +1 -0
  47. package/dist/src/core/islands/persistent-island-context.js +1 -0
  48. package/dist/src/core/islands/use-persistent-state.js +1 -0
  49. package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
  50. package/dist/src/core/layout/layout-cache-manager.js +1 -0
  51. package/dist/src/core/layout/layout-composer.js +1 -0
  52. package/dist/src/core/layout/layout-data-loader.js +1 -0
  53. package/dist/src/core/layout/layout-discovery.js +1 -0
  54. package/dist/src/core/layout/layout-matcher.js +1 -0
  55. package/dist/src/core/layout/layout-types.js +1 -0
  56. package/dist/src/core/modules/framework-module-resolver.js +1 -0
  57. package/dist/src/islands/component-analysis.js +1 -0
  58. package/dist/src/islands/css-utils.js +17 -0
  59. package/dist/src/islands/discovery/index.js +1 -0
  60. package/dist/src/islands/discovery/registry.js +1 -0
  61. package/dist/src/islands/discovery/resolver.js +2 -0
  62. package/dist/src/islands/discovery/scanner.js +1 -0
  63. package/dist/src/islands/discovery/types.js +1 -0
  64. package/dist/src/islands/discovery/validator.js +18 -0
  65. package/dist/src/islands/discovery/watcher.js +1 -0
  66. package/dist/src/islands/framework-detection.js +1 -0
  67. package/dist/src/islands/integration-loader.js +1 -0
  68. package/dist/src/islands/island.js +1 -0
  69. package/dist/src/islands/render-cache.js +1 -0
  70. package/dist/src/islands/types.js +1 -0
  71. package/dist/src/islands/universal-css-collector.js +5 -0
  72. package/dist/src/islands/universal-head-collector.js +2 -0
  73. package/{src → dist/src}/layout-system.d.ts +592 -592
  74. package/dist/src/layout-system.js +1 -0
  75. package/dist/src/middleware/discovery.js +1 -0
  76. package/dist/src/middleware/executor.js +1 -0
  77. package/dist/src/middleware/index.js +1 -0
  78. package/dist/src/middleware/types.js +1 -0
  79. package/dist/src/nitro/build-config.js +1 -0
  80. package/dist/src/nitro/config.js +1 -0
  81. package/dist/src/nitro/error-handler.js +198 -0
  82. package/dist/src/nitro/index.js +1 -0
  83. package/dist/src/nitro/island-manifest.js +2 -0
  84. package/dist/src/nitro/middleware-adapter.js +1 -0
  85. package/dist/src/nitro/renderer.js +183 -0
  86. package/dist/src/nitro/route-discovery.js +1 -0
  87. package/dist/src/nitro/types.js +1 -0
  88. package/dist/src/render/collect-css.js +3 -0
  89. package/{src/render/error-pages.ts → dist/src/render/error-pages.js} +7 -38
  90. package/dist/src/render/isolated-ssr-renderer.js +1 -0
  91. package/dist/src/render/ssr.js +90 -0
  92. package/dist/src/schemas/api.js +1 -0
  93. package/dist/src/schemas/core.js +1 -0
  94. package/dist/src/schemas/index.js +1 -0
  95. package/dist/src/schemas/layout.js +1 -0
  96. package/dist/src/schemas/routing/index.js +1 -0
  97. package/dist/src/schemas/routing.js +1 -0
  98. package/dist/src/types/as-island.js +1 -0
  99. package/{src → dist/src}/types/image.d.ts +106 -106
  100. package/{src → dist/src}/types/index.d.ts +22 -22
  101. package/{src → dist/src}/types/island-jsx.d.ts +33 -33
  102. package/{src → dist/src}/types/island-prop.d.ts +20 -20
  103. package/dist/src/types/layout.js +1 -0
  104. package/{src → dist/src}/types/mdx.d.ts +6 -6
  105. package/dist/src/types/routing.js +1 -0
  106. package/dist/src/types/types.js +1 -0
  107. package/{src → dist/src}/types/urlpattern.d.ts +49 -49
  108. package/{src → dist/src}/types/vite-env.d.ts +11 -11
  109. package/dist/src/utils/dev-logger.js +12 -0
  110. package/dist/src/utils/fs.js +1 -0
  111. package/dist/src/vite-plugin/auto-discover.js +1 -0
  112. package/dist/src/vite-plugin/config.js +1 -0
  113. package/dist/src/vite-plugin/errors.js +1 -0
  114. package/dist/src/vite-plugin/image-optimization.js +45 -0
  115. package/dist/src/vite-plugin/integration-activator.js +1 -0
  116. package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
  117. package/dist/src/vite-plugin/module-discovery.js +1 -0
  118. package/dist/src/vite-plugin/nitro-integration.js +42 -0
  119. package/dist/src/vite-plugin/plugin.js +1 -0
  120. package/dist/src/vite-plugin/types.js +1 -0
  121. package/dist/src/vite-plugin/validation.js +2 -0
  122. package/package.json +57 -26
  123. package/mod.ts +0 -302
  124. package/src/build/integration-bundler-plugin.ts +0 -116
  125. package/src/build/integration-config.ts +0 -168
  126. package/src/build/integration-detection-plugin.ts +0 -117
  127. package/src/build/integration-resolver-plugin.ts +0 -90
  128. package/src/build/island-manifest.ts +0 -269
  129. package/src/build/island-types-generator.ts +0 -476
  130. package/src/build/mdx-island-transform.ts +0 -464
  131. package/src/build/mdx-plugin.ts +0 -98
  132. package/src/build/page-island-transform.ts +0 -598
  133. package/src/build/prop-extractors/index.ts +0 -21
  134. package/src/build/prop-extractors/lit.ts +0 -140
  135. package/src/build/prop-extractors/qwik.ts +0 -16
  136. package/src/build/prop-extractors/solid.ts +0 -125
  137. package/src/build/prop-extractors/svelte.ts +0 -194
  138. package/src/build/prop-extractors/vue.ts +0 -111
  139. package/src/build/sidecar-file-manager.ts +0 -104
  140. package/src/build/sidecar-renderer.ts +0 -30
  141. package/src/client/adapters/index.js +0 -12
  142. package/src/client/adapters/index.ts +0 -13
  143. package/src/client/adapters/lit-adapter.js +0 -467
  144. package/src/client/adapters/lit-adapter.ts +0 -654
  145. package/src/client/adapters/preact-adapter.js +0 -223
  146. package/src/client/adapters/preact-adapter.ts +0 -331
  147. package/src/client/adapters/qwik-adapter.js +0 -259
  148. package/src/client/adapters/qwik-adapter.ts +0 -345
  149. package/src/client/adapters/react-adapter.js +0 -220
  150. package/src/client/adapters/react-adapter.ts +0 -353
  151. package/src/client/adapters/solid-adapter.js +0 -295
  152. package/src/client/adapters/solid-adapter.ts +0 -451
  153. package/src/client/adapters/svelte-adapter.js +0 -368
  154. package/src/client/adapters/svelte-adapter.ts +0 -524
  155. package/src/client/adapters/vue-adapter.js +0 -278
  156. package/src/client/adapters/vue-adapter.ts +0 -467
  157. package/src/client/components.js +0 -23
  158. package/src/client/components.ts +0 -35
  159. package/src/client/css-hmr-handler.js +0 -263
  160. package/src/client/css-hmr-handler.ts +0 -344
  161. package/src/client/framework-adapter.js +0 -283
  162. package/src/client/framework-adapter.ts +0 -462
  163. package/src/client/hmr-coordinator.js +0 -274
  164. package/src/client/hmr-coordinator.ts +0 -396
  165. package/src/client/hmr-error-overlay.js +0 -533
  166. package/src/client/main.js +0 -816
  167. package/src/client/types/vite-virtual-modules.d.ts +0 -60
  168. package/src/components/Image.tsx +0 -123
  169. package/src/components/IslandErrorBoundary.tsx +0 -145
  170. package/src/components/LayoutDataErrorBoundary.tsx +0 -141
  171. package/src/components/LayoutErrorBoundary.tsx +0 -127
  172. package/src/components/PersistentIsland.tsx +0 -52
  173. package/src/components/StreamingErrorBoundary.tsx +0 -233
  174. package/src/components/StreamingLayout.tsx +0 -538
  175. package/src/core/components/component-analyzer.ts +0 -192
  176. package/src/core/components/component-detection.ts +0 -508
  177. package/src/core/components/enhanced-framework-detector.ts +0 -500
  178. package/src/core/components/framework-registry.ts +0 -563
  179. package/src/core/content/mdx-processor.ts +0 -46
  180. package/src/core/integrations/index.ts +0 -19
  181. package/src/core/integrations/loader.ts +0 -125
  182. package/src/core/integrations/registry.ts +0 -175
  183. package/src/core/islands/island-persistence.ts +0 -325
  184. package/src/core/islands/island-state-serializer.ts +0 -258
  185. package/src/core/islands/persistent-island-context.tsx +0 -80
  186. package/src/core/islands/use-persistent-state.ts +0 -68
  187. package/src/core/layout/enhanced-layout-resolver.ts +0 -322
  188. package/src/core/layout/layout-cache-manager.ts +0 -485
  189. package/src/core/layout/layout-composer.ts +0 -357
  190. package/src/core/layout/layout-data-loader.ts +0 -516
  191. package/src/core/layout/layout-discovery.ts +0 -243
  192. package/src/core/layout/layout-matcher.ts +0 -299
  193. package/src/core/layout/layout-types.ts +0 -110
  194. package/src/core/modules/framework-module-resolver.ts +0 -273
  195. package/src/islands/component-analysis.ts +0 -213
  196. package/src/islands/css-utils.ts +0 -565
  197. package/src/islands/discovery/index.ts +0 -80
  198. package/src/islands/discovery/registry.ts +0 -340
  199. package/src/islands/discovery/resolver.ts +0 -477
  200. package/src/islands/discovery/scanner.ts +0 -386
  201. package/src/islands/discovery/types.ts +0 -117
  202. package/src/islands/discovery/validator.ts +0 -544
  203. package/src/islands/discovery/watcher.ts +0 -368
  204. package/src/islands/framework-detection.ts +0 -428
  205. package/src/islands/integration-loader.ts +0 -490
  206. package/src/islands/island.tsx +0 -565
  207. package/src/islands/render-cache.ts +0 -550
  208. package/src/islands/types.ts +0 -80
  209. package/src/islands/universal-css-collector.ts +0 -157
  210. package/src/islands/universal-head-collector.ts +0 -137
  211. package/src/layout-system.ts +0 -218
  212. package/src/middleware/discovery.ts +0 -268
  213. package/src/middleware/executor.ts +0 -315
  214. package/src/middleware/index.ts +0 -76
  215. package/src/middleware/types.ts +0 -99
  216. package/src/nitro/build-config.ts +0 -576
  217. package/src/nitro/config.ts +0 -483
  218. package/src/nitro/error-handler.ts +0 -636
  219. package/src/nitro/index.ts +0 -173
  220. package/src/nitro/island-manifest.ts +0 -584
  221. package/src/nitro/middleware-adapter.ts +0 -260
  222. package/src/nitro/renderer.ts +0 -1471
  223. package/src/nitro/route-discovery.ts +0 -439
  224. package/src/nitro/types.ts +0 -321
  225. package/src/render/collect-css.ts +0 -198
  226. package/src/render/isolated-ssr-renderer.ts +0 -654
  227. package/src/render/ssr.ts +0 -1030
  228. package/src/schemas/api.ts +0 -30
  229. package/src/schemas/core.ts +0 -64
  230. package/src/schemas/index.ts +0 -212
  231. package/src/schemas/layout.ts +0 -279
  232. package/src/schemas/routing/index.ts +0 -38
  233. package/src/schemas/routing.ts +0 -376
  234. package/src/types/as-island.ts +0 -20
  235. package/src/types/layout.ts +0 -285
  236. package/src/types/routing.ts +0 -555
  237. package/src/types/types.ts +0 -5
  238. package/src/utils/dev-logger.ts +0 -299
  239. package/src/utils/fs.ts +0 -151
  240. package/src/vite-plugin/auto-discover.ts +0 -551
  241. package/src/vite-plugin/config.ts +0 -266
  242. package/src/vite-plugin/errors.ts +0 -127
  243. package/src/vite-plugin/image-optimization.ts +0 -156
  244. package/src/vite-plugin/integration-activator.ts +0 -126
  245. package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
  246. package/src/vite-plugin/module-discovery.ts +0 -189
  247. package/src/vite-plugin/nitro-integration.ts +0 -1354
  248. package/src/vite-plugin/plugin.ts +0 -409
  249. package/src/vite-plugin/types.ts +0 -327
  250. package/src/vite-plugin/validation.ts +0 -228
@@ -0,0 +1,17 @@
1
+ typeof globalThis<`u`&&!globalThis.__svelteSSRCSS&&(globalThis.__svelteSSRCSS=new Map);export function addSvelteSSRCSS(e,t,n,r=!1){globalThis.__svelteSSRCSS||(globalThis.__svelteSSRCSS=new Map);let i={css:e.trim(),scopeId:t,src:n,isGlobal:r,timestamp:Date.now()};globalThis.__svelteSSRCSS.set(t,i)}export function getSvelteSSRCSS(e=!1){if(!globalThis.__svelteSSRCSS||globalThis.__svelteSSRCSS.size===0)return``;let t=Array.from(globalThis.__svelteSSRCSS.values());t.sort((e,t)=>e.isGlobal&&!t.isGlobal?-1:!e.isGlobal&&t.isGlobal?1:e.timestamp-t.timestamp);let n=t.filter(e=>e.isGlobal),r=t.filter(e=>!e.isGlobal),i=o([n.map(e=>`${`/* Global CSS from: ${e.src} */`}\n${e.css}`).join(`
2
+
3
+ `),r.map(e=>`${`/* Component CSS: ${e.src} (${e.scopeId}) */`}\n${e.css}`).join(`
4
+
5
+ `)].filter(e=>e.trim()).join(`
6
+
7
+ `));return e&&globalThis.__svelteSSRCSS.clear(),i}export function getSvelteSSRCSSForHead(e=!1){let n=getSvelteSSRCSS(e);return n.trim()?`<style data-svelte-ssr="true" data-generated="${new Date().toISOString()}">\n${n}\n</style>`:``}export function getSvelteSSRCSSStats(){if(!globalThis.__svelteSSRCSS||globalThis.__svelteSSRCSS.size===0)return{totalComponents:0,globalComponents:0,scopedComponents:0,totalCSSSize:0,averageCSSSize:0,oldestTimestamp:0,newestTimestamp:0};let e=Array.from(globalThis.__svelteSSRCSS.values()),t=e.filter(e=>e.isGlobal),n=e.filter(e=>!e.isGlobal),r=e.reduce((e,t)=>e+t.css.length,0),i=e.map(e=>e.timestamp);return{totalComponents:e.length,globalComponents:t.length,scopedComponents:n.length,totalCSSSize:r,averageCSSSize:e.length>0?Math.round(r/e.length):0,oldestTimestamp:Math.min(...i),newestTimestamp:Math.max(...i)}}export function getSvelteComponentCSS(e){if(!globalThis.__svelteSSRCSS)return null;let t=globalThis.__svelteSSRCSS.get(e);return t?t.css:null}export function clearSvelteComponentCSS(e){return globalThis.__svelteSSRCSS?globalThis.__svelteSSRCSS.delete(e):!1}function o(e){try{return s(optimizeComponentCSS(e))}catch(t){return console.warn(`⚠️ Failed to optimize Svelte SSR CSS:`,t),e}}function s(e){try{let t=l(c(e));return process.env.NODE_ENV===`production`?minifyCSS(t):u(t)}catch(t){return console.warn(`⚠️ Failed to apply SSR CSS collection optimizations:`,t),e}}function c(e){let t=new Set;return e.replace(/\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\//g,e=>e.includes(`!important`)||e.includes(`@preserve`)||e.includes(`license`)?e:t.has(e)?``:(t.add(e),e))}function l(e){return e.replace(/\n\s*\n\s*\n/g,`
8
+
9
+ `).replace(/^\s*\n/gm,``).trim()}function u(e){return e.replace(/\{/g,` {
10
+ `).replace(/;/g,`;
11
+ `).replace(/\}/g,`
12
+ }
13
+ `).replace(/\n {2}\n/g,`
14
+ `).replace(/\n\n+/g,`
15
+
16
+ `).trim()}export function applyCSSScoping(e,t){return e.replace(/([^{}]+){/g,(e,n)=>{let r=n.trim();return r.startsWith(`@`)||r.includes(`[data-${t}]`)?e:r.includes(`:global(`)?`${r.replace(/:global\(([^)]+)\)/g,`$1`)} {`:`${r.split(`,`).map(e=>applySelectorScoping(e.trim(),t)).join(`, `)} {`})}export function applySelectorScoping(e,t){if(!e||e.length===0||e.includes(`[data-${t}]`))return e;let n=e.split(/(\s*[>+~]\s*|\s+)/);if(n.length>1){let e=n[0].trim(),r=n.slice(1).join(``);return d(e,t)+r}return d(e,t)}function d(e,t){let n=e.match(/^([^:]+)(::.*)?$/);if(n){let[,e,r]=n;return`${e}[data-${t}]${r||``}`}let r=e.match(/^([^:]+)(:.*)?$/);if(r){let[,e,n]=r;return`${e}[data-${t}]${n||``}`}return`${e}[data-${t}]`}export function optimizeComponentCSS(e){try{let t=p(f(e)).join(`
17
+ `);return process.env.NODE_ENV===`production`?minifyCSS(t):t}catch(t){return console.warn(`⚠️ Failed to optimize component CSS:`,t),e}}function f(e){let t=[],n=``,r=0,i=!1,a=``;for(let o=0;o<e.length;o++){let s=e[o],c=o>0?e[o-1]:``;if((s===`"`||s===`'`)&&c!==`\\`&&(i?s===a&&(i=!1,a=``):(i=!0,a=s)),!i){if(s===`{`)r++;else if(s===`}`&&(r--,r===0)){n+=s;let e=n.trim();e&&!h(e)&&t.push(e),n=``;continue}}n+=s}return n.trim()&&t.push(n.trim()),t}function p(e){let t=new Map,n=[];for(let r=0;r<e.length;r++){let i=e[r],a=m(i);if(a){let e=t.get(a);if(e)n[e.index]=i,t.set(a,{rule:i,index:e.index});else{let e=n.length;n.push(i),t.set(a,{rule:i,index:e})}}else n.push(i)}return n.filter(e=>e!==null)}function m(e){let t=e.match(/^([^{]+)\{([^}]+)\}/);if(!t)return null;let n=t[1].trim();return t[2].trim(),n}function h(e){let t=e.match(/^[^{]+\{([^}]*)\}/);if(!t)return!0;let n=t[1].trim();return n.length===0||n===`;`}export function minifyCSS(e){return e.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\s+/g,` `).replace(/\s*{\s*/g,`{`).replace(/\s*}\s*/g,`}`).replace(/\s*;\s*/g,`;`).replace(/;\s*}/g,`}`).replace(/;}/g,`}`).trim()}export function generateComponentScopeId(e,t=`component`){return`${t}-${e.replace(/^\/+/,``).replace(/\.(svelte|tsx|jsx|vue|ts|js)$/,``).replace(/[^a-zA-Z0-9\/]/g,`-`).replace(/\/+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).toLowerCase()}-${simpleHash(e)}`}export function simpleHash(e){let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);t=(t<<5)-t+r,t&=t}return Math.abs(t).toString(36).substring(0,6)}
@@ -0,0 +1 @@
1
+ export{ISLAND_FILE_EXTENSIONS,DEFAULT_DISCOVERY_CONFIG,isSupportedIslandExtension}from"./types.js";export{discoverIslandDirectories,discoverIslandsInDirectory,discoverAllIslands,isIslandsDirectory,getDefaultIslandsPath,hasDefaultIslandsDirectory,getQualifiedIslandName,parseQualifiedIslandName}from"./scanner.js";export{IslandRegistry,createIslandRegistry}from"./registry.js";export{IslandResolver,createIslandResolver}from"./resolver.js";export{IslandValidator,createIslandValidator,validateAllIslands,formatValidationError,formatValidationWarning,formatCircularDependency,formatValidationResult}from"./validator.js";export{IslandWatcher,createIslandWatcher}from"./watcher.js";
@@ -0,0 +1 @@
1
+ import{discoverIslandDirectories as e,discoverIslandsInDirectory as t,getQualifiedIslandName as n,parseQualifiedIslandName as r}from"./scanner.js";export class IslandRegistry{_islands=new Map;_directories=[];_byName=new Map;_collisions=[];_projectRoot;_config;constructor(e,t={}){this._projectRoot=e,this._config=t}get islands(){return new Map(this._islands)}get directories(){return[...this._directories]}get collisions(){return[...this._collisions]}get size(){return this._islands.size}register(e){let t=n(e);this._islands.set(t,e);let r=this._byName.get(e.name)||[];r.push(e),this._byName.set(e.name,r)}resolve(e,t){if(t!==void 0){let n=t===``?e:`${t}/${e}`,r=this._islands.get(n);if(r)return r}if(e.includes(`/`)){let t=this._islands.get(e);if(t)return t;let{namespace:n,name:i}=r(e),a=n===``?i:`${n}/${i}`;return this._islands.get(a)||null}let n=this._byName.get(e);return!n||n.length===0?null:n.length===1?n[0]:n.find(e=>e.directory.isDefault)||n[0]}findByName(e){return this._byName.get(e)||[]}getQualifiedName(e){return n(e)}has(e){return this._islands.has(e)?!0:this._byName.has(e)}detectCollisions(){let e=[];for(let[t,n]of this._byName)if(n.length>1){let r=n.some(e=>e.directory.isDefault)?`priority`:`namespace`;e.push({name:t,islands:[...n],resolution:r})}return this._collisions=e,e}async rebuild(){this._islands.clear(),this._byName.clear(),this._directories=[],this._collisions=[],this._directories=await e(this._projectRoot,this._config);for(let e of this._directories){let n=await t(e,this._projectRoot);for(let e of n)this.register(e)}this.detectCollisions()}getAllIslands(){return Array.from(this._islands.values())}getIslandsInDirectory(e){return this.getAllIslands().filter(t=>t.directory.path===e.path)}getIslandsByNamespace(e){return this.getAllIslands().filter(t=>t.namespace===e)}unregister(e){let t=this._islands.get(e);if(!t)return!1;this._islands.delete(e);let r=this._byName.get(t.name);if(r){let i=r.filter(t=>n(t)!==e);i.length===0?this._byName.delete(t.name):this._byName.set(t.name,i)}return!0}toJSON(){return{islands:Object.fromEntries(this._islands),directories:this._directories,collisions:this._collisions}}}export async function createIslandRegistry(e,t={}){let n=new IslandRegistry(e,t);return await n.rebuild(),n}
@@ -0,0 +1,2 @@
1
+ import{relative as e}from"node:path";import{parseQualifiedIslandName as t,getQualifiedIslandName as n}from"./scanner.js";const r={isDevelopment:!0,basePath:`/`,projectRoot:``,absolute:!1};export class IslandResolver{_registry;_projectRoot;constructor(e,t){this._registry=e,this._projectRoot=t}get registry(){return this._registry}get projectRoot(){return this._projectRoot}resolve(e){let t=this.normalizeReference(e),n=this.resolveExplicitPath(t);if(n)return n;if(t.includes(`/`)){let e=this.resolveQualifiedName(t);if(e)return e}return this.resolveByName(t)}normalizeReference(e){let t=e.trim().replace(/^\/+|\/+$/g,``);t=t.replace(/\\/g,`/`);for(let e of[/\.solid\.(tsx|jsx)$/,/\.react\.(tsx|jsx)$/,/\.lit\.(ts|js)$/,/\.preact\.(tsx|jsx)$/,/\.(tsx|ts|jsx|js|vue|svelte)$/])if(e.test(t)){t=t.replace(e,``);break}return t}resolveExplicitPath(e){if(!e.includes(`islands/`))return null;let t=this._registry.getAllIslands();for(let n of t){let t=n.relativePath.replace(/\.[^.]+$/,``),r=[/\.solid$/,/\.react$/,/\.lit$/,/\.preact$/],i=t;for(let e of r)i=i.replace(e,``);if(i===e||i.endsWith(`/`+e)||t===e||t.endsWith(`/`+e))return{island:n,importPath:this.generateImportPath(n),ambiguous:!1}}return null}resolveQualifiedName(e){let{namespace:n,name:r}=t(e),i=this._registry.resolve(r,n);if(!i)return null;let a=this._registry.findByName(r),o=a.length>1;return{island:i,importPath:this.generateImportPath(i),ambiguous:o,alternatives:o?a.filter(e=>e!==i):void 0}}resolveByName(e){let t=this._registry.findByName(e);if(t.length===0)return null;let n=[...t].sort((e,t)=>e.directory.isDefault&&!t.directory.isDefault?-1:!e.directory.isDefault&&t.directory.isDefault?1:e.namespace.localeCompare(t.namespace)),r=n[0],i=t.length>1;return{island:r,importPath:this.generateImportPath(r),ambiguous:i,alternatives:i?n.slice(1):void 0}}generateImportPath(t,n={}){let i={...r,...n},a=i.projectRoot||this._projectRoot;if(i.absolute)return t.filePath;if(i.isDevelopment){let n=e(a,t.filePath).replace(/\\/g,`/`);return`${i.basePath}${n}`}return`${i.basePath}${t.relativePath}`}generateQualifiedImportPath(e){return n(e)}getResolutionOrder(){return[`Island Resolution Order:`,`1. Explicit path-based references (e.g., 'src/modules/auth/islands/Counter')`,`2. Qualified name matches (e.g., 'modules/auth/Counter')`,`3. Default /src/islands/ directory (highest priority for unqualified names)`,`4. Nested directories in alphabetical order by namespace`,``,`Discovered directories (in priority order):`,...this._registry.directories.map((e,t)=>` ${t+1}. ${e.relativePath}${e.isDefault?` (default)`:``}`)]}isAmbiguous(e){return this.resolve(e)?.ambiguous??!1}getAllMatches(e){let n=this.normalizeReference(e);if(n.includes(`/`)&&!n.includes(`islands/`)){let{namespace:e,name:r}=t(n),i=this._registry.resolve(r,e);return i?[i]:[]}return this._registry.findByName(n)}suggestQualifiedNames(e){return this._registry.findByName(e).map(e=>n(e))}resolveOrThrow(e){let t=this.resolve(e);if(!t){let t=this.findSimilarNames(e),n=`Island not found: "${e}"`;throw t.length>0&&(n+=`\n\nDid you mean one of these?\n${t.map(e=>` - ${e}`).join(`
2
+ `)}`),Error(n)}return t}findSimilarNames(e){let t=this._registry.getAllIslands(),r=e.toLowerCase();return t.filter(e=>{let t=e.name.toLowerCase(),i=n(e).toLowerCase();return t.includes(r)||r.includes(t)||i.includes(r)||this.levenshteinDistance(t,r)<=3}).map(e=>n(e)).slice(0,5)}levenshteinDistance(e,t){let n=[];for(let e=0;e<=t.length;e++)n[e]=[e];for(let t=0;t<=e.length;t++)n[0][t]=t;for(let r=1;r<=t.length;r++)for(let i=1;i<=e.length;i++)t.charAt(r-1)===e.charAt(i-1)?n[r][i]=n[r-1][i-1]:n[r][i]=Math.min(n[r-1][i-1]+1,n[r][i-1]+1,n[r-1][i]+1);return n[t.length][e.length]}}export function createIslandResolver(e,t){return new IslandResolver(e,t)}
@@ -0,0 +1 @@
1
+ import{resolve as e,relative as t,dirname as n,basename as r,extname as i}from"node:path";import{stat as a,readdir as o}from"node:fs/promises";import{DEFAULT_DISCOVERY_CONFIG as s,isSupportedIslandExtension as c}from"./types.js";export async function discoverIslandDirectories(t,n={}){let r={...s,...n},i=e(t,r.rootDir),o=[];try{if(!(await a(i)).isDirectory())return o}catch{return o}return await u(i,t,r,o),o.sort((e,t)=>e.isDefault&&!t.isDefault?-1:!e.isDefault&&t.isDefault?1:e.relativePath.localeCompare(t.relativePath)),o}async function u(n,r,i,a){try{let s=await o(n,{withFileTypes:!0});for(let o of s){if(!o.isDirectory())continue;let s=e(n,o.name);if(!d(t(r,s),i.exclude)){if(o.name===`islands`){let e=f(s,r,i);a.push(e);continue}await u(s,r,i,a)}}}catch(e){(!(e instanceof Error)||e.code!==`EACCES`)&&console.warn(`Warning: Could not scan directory ${n}:`,e)}}function d(e,t){let n=e.replace(/\\/g,`/`);for(let e of t)if(n===e||n.startsWith(e+`/`)||n.includes(`/`+e+`/`)||n.endsWith(`/`+e))return!0;return!1}function f(r,i,a){let o=t(e(i,a.rootDir),r),s=o===`islands`,c=``;return s||(c=n(o).replace(/\\/g,`/`),a.namespaces[c]&&(c=a.namespaces[c])),{path:r,relativePath:o.replace(/\\/g,`/`),namespace:c,isDefault:s}}export function isIslandsDirectory(e){return r(e)===`islands`}export function getDefaultIslandsPath(t,n=`src`){return e(t,n,`islands`)}export async function hasDefaultIslandsDirectory(e,t=`src`){let n=getDefaultIslandsPath(e,t);try{return(await a(n)).isDirectory()}catch{return!1}}export async function discoverIslandsInDirectory(e,t){let n=[];try{let r=await o(e.path,{withFileTypes:!0});for(let a of r){if(!a.isFile()||!c(i(a.name)))continue;let r=p(a.name,e,t);n.push(r)}}catch(t){console.warn(`Warning: Could not scan islands directory ${e.path}:`,t)}return n.sort((e,t)=>e.name.localeCompare(t.name)),n}export async function discoverAllIslands(e,t={}){let n=await discoverIslandDirectories(e,t),r=[];for(let t of n){let n=await discoverIslandsInDirectory(t,e);r.push(...n)}return r}function p(n,r,a){let o=i(n),s=m(n),c=e(r.path,n),l=t(a,c).replace(/\\/g,`/`),u=h(n);return{name:s,filePath:c,relativePath:l,namespace:r.namespace,framework:u,extension:o,directory:r}}function m(e){let t=e;for(let e of[`.solid.tsx`,`.solid.jsx`,`.react.tsx`,`.react.jsx`,`.lit.ts`,`.lit.js`,`.preact.tsx`,`.preact.jsx`])if(t.endsWith(e))return t.slice(0,-e.length);for(let e of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(t.endsWith(e))return t.slice(0,-e.length);return t}function h(e){let t=e.toLowerCase();if(t.includes(`.solid.`))return`solid`;if(t.includes(`.react.`))return`react`;if(t.includes(`.lit.`))return`lit`;if(t.includes(`.preact.`))return`preact`;if(t.includes(`.qwik.`))return`qwik`;if(e.endsWith(`.vue`))return`vue`;if(e.endsWith(`.svelte`))return`svelte`;if((e.endsWith(`.ts`)||e.endsWith(`.js`))&&!e.endsWith(`.d.ts`)){let t=m(e);if(/^[A-Z]/.test(t))return`lit`}return e.endsWith(`.tsx`)||e.endsWith(`.jsx`)?`preact`:`unknown`}export function getQualifiedIslandName(e){return e.namespace===``?e.name:`${e.namespace}/${e.name}`}export function parseQualifiedIslandName(e){let t=e.lastIndexOf(`/`);return t===-1?{namespace:``,name:e}:{namespace:e.slice(0,t),name:e.slice(t+1)}}
@@ -0,0 +1 @@
1
+ export const ISLAND_FILE_EXTENSIONS=[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`];export function isSupportedIslandExtension(e){return ISLAND_FILE_EXTENSIONS.includes(e)}export const DEFAULT_DISCOVERY_CONFIG={rootDir:`src`,include:[],exclude:[`node_modules`,`.git`,`dist`,`build`],namespaces:{},strictCollisions:!1};
@@ -0,0 +1,18 @@
1
+ import{resolve as e,relative as t,basename as n,extname as r}from"node:path";import{readFile as i,stat as a,readdir as o}from"node:fs/promises";import{isSupportedIslandExtension as s}from"./types.js";const c={pascalCase:/^[A-Z][a-zA-Z0-9]*$/,validFileName:/^[a-zA-Z][a-zA-Z0-9._-]*$/,frameworkSuffixes:[`.solid`,`.react`,`.lit`,`.preact`]},l=`https://avalon.dev/docs/islands`;export class IslandValidator{_projectRoot;constructor(e){this._projectRoot=e}get projectRoot(){return this._projectRoot}extractComponentName(e){let t=n(e);for(let e of c.frameworkSuffixes)if(t.includes(e)){let n=t.indexOf(e);return t.slice(0,n)}let i=r(t);return t.slice(0,-i.length)}toPascalCase(e){return e.split(/[-_\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``)}hasValidJsExport(e){let t=/export\s+default\s+/.test(e)||/export\s*\{\s*[^}]*\s+as\s+default\s*[,}]/.test(e),n=/export\s+(function|class|const)\s+[A-Z]/.test(e),r=/@customElement\s*\(/.test(e)||/customElements\.define\s*\(/.test(e);return t||n||r}isValidVueComponent(e){return/<template[\s>]/.test(e)||/<script[\s>]/.test(e)}isValidSvelteComponent(e){return e.trim().length>0}createExportError(e,t){let n=this.extractComponentName(e),r;switch(t){case`vue`:r=`Add a <template> or <script> section to your Vue component`;break;case`svelte`:r=`Add component markup to your Svelte file`;break;default:r=`Add a default export: export default function ${n}() { return <div>...</div>; }`}return{type:`invalid-export`,message:`Island component "${n}" does not export a valid component`,filePath:e,line:1,column:1,suggestion:`${r}\n\nSee: ${l}#component-exports`}}async validateExports(e){let t=[],n=[];try{let n=await i(e,`utf-8`),a=r(e).toLowerCase();a===`.vue`?this.isValidVueComponent(n)||t.push(this.createExportError(e,`vue`)):a===`.svelte`?this.isValidSvelteComponent(n)||t.push(this.createExportError(e,`svelte`)):this.hasValidJsExport(n)||t.push(this.createExportError(e,`js`))}catch{t.push({type:`invalid-export`,message:`Cannot read file: ${e}`,filePath:e,suggestion:`Check file permissions and encoding`})}return{valid:t.length===0,errors:t,warnings:n}}extractJsImports(e){let t=[],n=/import\s+(?:[\w\s{},*]+\s+from\s+)?['"]([^'"]+)['"]/g,r;for(;(r=n.exec(e))!==null;)t.push(r[1]);let i=/import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(;(r=i.exec(e))!==null;)t.push(r[1]);let a=/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;for(;(r=a.exec(e))!==null;)t.push(r[1]);return t}extractImports(e,t){let n=[],i=r(t).toLowerCase();if(i===`.vue`||i===`.svelte`){let t=e.match(/<script[^>]*>([\s\S]*?)<\/script>/gi);if(t)for(let e of t)n.push(...this.extractJsImports(e))}else n.push(...this.extractJsImports(e));return n}resolveImportToIsland(t,i,a,o){if(!t.startsWith(`.`)&&!t.startsWith(`/`))return null;if(t.startsWith(`.`)){let n=e(e(i.filePath,`..`),t);if(!r(n)){for(let e of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(o.has(n+e)){for(let t of a.values())if(t.filePath===n+e)return t}}if(o.has(n)){for(let e of a.values())if(e.filePath===n)return e}}let s=n(t).replace(/\.[^.]+$/,``);return a.get(s)||null}async buildImportGraph(e){let t=new Map,n=new Set(e.map(e=>e.filePath)),r=new Map;for(let t of e){r.set(t.name,t);let e=t.relativePath.replace(/\.[^.]+$/,``);r.set(e,t)}for(let a of e){let e=[];try{let t=await i(a.filePath,`utf-8`),o=this.extractImports(t,a.filePath);for(let t of o){let i=this.resolveImportToIsland(t,a,r,n);i&&e.push(i.filePath)}}catch{}t.set(a.filePath,e)}return t}cycleExists(e,t){let n=new Set(t);for(let r of e){if(r.length!==t.length-1)continue;let e=new Set(r),i=!0;for(let t of n)if(!e.has(t)){i=!1;break}if(i)return!0}return!1}findCycles(e){let t=[],n=new Set,r=new Set,i=[],a=o=>{n.add(o),r.add(o),i.push(o);let s=e.get(o)||[];for(let e of s)if(!n.has(e))a(e);else if(r.has(e)){let n=i.indexOf(e);if(n!==-1){let r=[...i.slice(n),e];this.cycleExists(t,r)||t.push(r)}}i.pop(),r.delete(o)};for(let t of e.keys())n.has(t)||a(t);return t}formatCycleDescription(e){return`Circular dependency detected:\n ${e.map(e=>t(this._projectRoot,e)).join(`
2
+ → `)}`}async validateComponent(e){let t=[],n=[];try{if(!(await a(e)).isFile())return t.push({type:`invalid-export`,message:`Path is not a file: ${e}`,filePath:e}),{valid:!1,errors:t,warnings:n}}catch{return t.push({type:`invalid-export`,message:`File not found: ${e}`,filePath:e}),{valid:!1,errors:t,warnings:n}}let i=r(e);if(!s(i))return t.push({type:`invalid-export`,message:`Unsupported file extension: ${i}`,filePath:e,suggestion:`Use one of: .tsx, .ts, .jsx, .js, .vue, .svelte`}),{valid:!1,errors:t,warnings:n};let o=this.validateNamingConvention(this.extractComponentName(e),e);t.push(...o.errors),n.push(...o.warnings);let c=await this.validateExports(e);return t.push(...c.errors),n.push(...c.warnings),{valid:t.length===0,errors:t,warnings:n}}async validateDirectory(t){let n=[],i=[],a=!1;try{let c=await o(t.path,{withFileTypes:!0});for(let o of c){if(!o.isFile()||!s(r(o.name)))continue;a=!0;let c=e(t.path,o.name),l=await this.validateComponent(c);n.push(...l.errors),i.push(...l.warnings)}}catch{return n.push({type:`invalid-export`,message:`Cannot read directory: ${t.path}`,filePath:t.path,suggestion:`Check directory permissions`}),{valid:!1,errors:n,warnings:i}}return a||i.push({type:`empty-directory`,message:`Islands directory is empty: ${t.relativePath}`,filePath:t.path,suggestion:`Add island components or remove the empty directory`}),{valid:n.length===0,errors:n,warnings:i}}validateNamingConvention(e,t){let n=[],r=[];return c.pascalCase.test(e)||(e.length===0?n.push({type:`naming-convention`,message:`Invalid component name: empty name`,filePath:t,suggestion:`Use PascalCase naming (e.g., "Counter", "UserProfile")`}):/^[a-z]/.test(e)?r.push({type:`deprecated-pattern`,message:`Component name "${e}" should use PascalCase`,filePath:t,suggestion:`Rename to "${this.toPascalCase(e)}"`}):/[^a-zA-Z0-9]/.test(e)&&r.push({type:`deprecated-pattern`,message:`Component name "${e}" contains special characters`,filePath:t,suggestion:`Use only letters and numbers in component names`})),{valid:n.length===0,errors:n,warnings:r}}async detectCircularDependencies(e){let t=await this.buildImportGraph(e);return this.findCycles(t).map(e=>({cycle:e,description:this.formatCycleDescription(e)}))}}export function formatValidationError(e,n){let r=t(n,e.filePath),i=e.line?`${r}:${e.line}${e.column?`:${e.column}`:``}`:r,a=`Error: ${e.message}\n\n`;return a+=` File: ${i}\n`,e.suggestion&&(a+=`\n ${e.suggestion}\n`),a}export function formatValidationWarning(e,n){let r=`Warning: ${e.message}\n`;if(e.filePath){let i=t(n,e.filePath);r+=` File: ${i}\n`}return e.suggestion&&(r+=` Suggestion: ${e.suggestion}\n`),r}export function formatCircularDependency(e,n){let r=e.cycle.map(e=>t(n,e)),i=`Error: Circular dependency detected
3
+
4
+ `;i+=` Dependency chain:
5
+ `;for(let e=0;e<r.length;e++){let t=e===r.length-1;i+=`${t?` └─`:` ├─`} ${r[e]}\n`,t||(i+=` │ ↓
6
+ `)}return i+=`
7
+ Suggestion: Break the cycle by:
8
+ `,i+=` - Moving shared code to a separate module
9
+ `,i+=` - Using dynamic imports for one of the dependencies
10
+ `,i+=` - Restructuring the component hierarchy
11
+ `,i+=`\n See: ${l}#circular-dependencies\n`,i}export function formatValidationResult(e,t){let n=[];if(e.errors.length>0){n.push(`Found ${e.errors.length} error(s):\n`);for(let r of e.errors)n.push(formatValidationError(r,t))}if(e.warnings.length>0){n.length>0&&n.push(`
12
+ `),n.push(`Found ${e.warnings.length} warning(s):\n`);for(let r of e.warnings)n.push(formatValidationWarning(r,t))}return e.valid&&e.warnings.length===0?n.push(`✓ Validation passed
13
+ `):e.valid?n.push(`
14
+ ✓ Validation passed with warnings
15
+ `):n.push(`
16
+ ✗ Validation failed
17
+ `),n.join(`
18
+ `)}export function createIslandValidator(e){return new IslandValidator(e)}export async function validateAllIslands(e,t){let n=createIslandValidator(t),r=[],i=[];for(let t of e){let e=await n.validateComponent(t.filePath);r.push(...e.errors),i.push(...e.warnings)}let a=await n.detectCircularDependencies(e);for(let e of a)r.push({type:`circular-dependency`,message:e.description,filePath:e.cycle[0]});return{valid:r.length===0,errors:r,warnings:i}}
@@ -0,0 +1 @@
1
+ import{resolve as e,relative as t,extname as n,basename as r}from"node:path";import{watch as i}from"node:fs";import{isSupportedIslandExtension as a}from"./types.js";import{discoverIslandsInDirectory as o}from"./scanner.js";const s={debounceMs:100,emitInitial:!1};export class IslandWatcher{_projectRoot;_config;_options;_registry;_watchers=[];_callbacks=new Set;_isWatching=!1;_debounceTimers=new Map;constructor(e,t,n={},r={}){this._projectRoot=e,this._registry=t,this._config=n,this._options={...s,...r}}get isWatching(){return this._isWatching}get callbackCount(){return this._callbacks.size}async watch(e){return this._callbacks.add(e),this._isWatching||await this._startWatching(),()=>{this._callbacks.delete(e),this._callbacks.size===0&&this.stop()}}stop(){this._isWatching=!1;for(let e of this._watchers)try{e.close()}catch{}this._watchers=[];for(let e of this._debounceTimers.values())clearTimeout(e);this._debounceTimers.clear()}async _startWatching(){if(this._isWatching)return;this._isWatching=!0;let e=this._registry.directories;for(let t of e)try{this._watchDirectory(t)}catch(e){console.warn(`⚠️ Failed to watch island directory ${t.relativePath}:`,e)}}_watchDirectory(t){try{let r=i(t.path,{recursive:!1},(r,i)=>{if(!this._isWatching||!i)return;let o=e(t.path,i);if(!a(n(i)))return;let s=r;this._debounceEvent(o,s,t)});this._watchers.push(r)}catch(e){if(e instanceof Error&&e.code===`ENOENT`)console.warn(`⚠️ Island directory not found: ${t.relativePath}`);else throw e}}_debounceEvent(e,t,n){let r=this._debounceTimers.get(e);r&&clearTimeout(r);let i=setTimeout(()=>{this._debounceTimers.delete(e),this._handleFileChange(e,t,n)},this._options.debounceMs);this._debounceTimers.set(e,i)}async _handleFileChange(e,n,r){let i=t(this._projectRoot,e).replace(/\\/g,`/`),a;if(n===`change`)a=`change`;else try{let{stat:t}=await import(`node:fs/promises`);await t(e),a=`add`}catch{a=`remove`}let s=null;if(a===`remove`){let t=this._getQualifiedNameFromPath(e,r);s=this._registry.resolve(t)||null,s&&this._registry.unregister(t)}else try{s=(await o(r,this._projectRoot)).find(t=>t.filePath===e)||null,a===`add`&&s&&this._registry.register(s)}catch{s=null}let c={type:a,island:s,filePath:i,timestamp:Date.now()};this._emitEvent(c)}_getQualifiedNameFromPath(e,t){let n=r(e),i=this._extractComponentName(n);return t.namespace===``?i:`${t.namespace}/${i}`}_extractComponentName(e){for(let t of[`.solid.tsx`,`.solid.jsx`,`.react.tsx`,`.react.jsx`,`.lit.ts`,`.lit.js`,`.preact.tsx`,`.preact.jsx`])if(e.endsWith(t))return e.slice(0,-t.length);for(let t of[`.tsx`,`.ts`,`.jsx`,`.js`,`.vue`,`.svelte`])if(e.endsWith(t))return e.slice(0,-t.length);return e}_emitEvent(e){for(let t of this._callbacks)try{t(e)}catch(e){console.error(`Error in island change callback:`,e)}}async refresh(){if(!this._isWatching)return;for(let e of this._watchers)try{e.close()}catch{}this._watchers=[];let e=this._registry.directories;for(let t of e)try{this._watchDirectory(t)}catch(e){console.warn(`⚠️ Failed to watch island directory ${t.relativePath}:`,e)}}}export function createIslandWatcher(e,t,n={},r={}){return new IslandWatcher(e,t,n,r)}
@@ -0,0 +1 @@
1
+ import{registry as e}from"../core/integrations/registry.js";import{createIslandRegistry as t}from"./discovery/index.js";import{getCachedPath as n,setCachedPath as r}from"./render-cache.js";import{stat as i,readFile as a}from"node:fs/promises";function o(e,t){let n=s(e);if(!n)return null;let r=t.resolve(n);if(r)return`/`+r.relativePath;if(e.includes(`/`)){let r=c(e);if(r){let e=t.resolve(n,r);if(e)return`/`+e.relativePath}}return null}function s(e){let t=e.split(`/`).filter(Boolean);if(t.length===0)return null;let n=t.at(-1);for(let e of[/\.solid\.(tsx|jsx)$/,/\.react\.(tsx|jsx)$/,/\.lit\.(ts|js)$/,/\.preact\.(tsx|jsx)$/])if(e.test(n)){n=n.replace(e,``);break}return n=n.replace(/\.(tsx|ts|jsx|js|vue|svelte)$/,``),n||null}function c(e){let t=new RegExp(/(?:\/src)?\/(.+?)\/islands\//).exec(e);return t?t[1]:``}async function l(e){try{return await i(e),!0}catch{return!1}}function u(e){if(e.includes(`/islands/`)&&!e.startsWith(`/src/`)){if(/^\/(?:modules\/)?[^/]+\/islands\//.test(e))return`/src`+e;if(e.startsWith(`/islands/`))return e.replace(`/islands/`,`/src/islands/`)}return e}async function d(t){let n=e.getAll(),r=[],i=t.replace(`.tsx`,``);for(let e of n){let t=e.config();for(let e of t.fileExtensions)e===`.tsx`||e===`.jsx`?r.push(`${i}.${t.name}${e}`):r.push(`${i}${e}`)}r.push(t);for(let e of r)if(await l(e.startsWith(`/`)?e.substring(1):e))return e;return null}export async function resolveIslandPath(e){let t=n(e);if(t!==null)return t;let i=u(e.replaceAll(`\\`,`/`)),a=f.__islandRegistry;if(a){let t=o(i,a);if(t)return r(e,t),t}if(i.endsWith(`.tsx`)&&!i.includes(`.solid.`)&&!i.includes(`.preact.`)){let t=await d(i);if(t)return r(e,t),t}return r(e,i),i}export function isNestedIslandPath(e){let t=e.replaceAll(`\\`,`/`);if(!t.includes(`/islands/`))return!1;for(let e of[/^\/islands\//,/^\/src\/islands\//,/^src\/islands\//,/^islands\//])if(e.test(t))return!1;return!0}const f=globalThis;export async function getOrCreateIslandRegistry(e=process.cwd()){return f.__islandRegistry??=await t(e),f.__islandRegistry}export function setIslandRegistry(e){f.__islandRegistry=e}export function clearIslandRegistry(){f.__islandRegistry=void 0}export function detectFrameworkFromSrc(t){let n=t.replaceAll(`\\`,`/`),r=e.getAll();for(let e of r){let t=e.config();if(n.includes(`.${t.name}.`))return t.name}for(let e of r){let t=e.config();for(let e of t.fileExtensions)if(n.endsWith(e))return t.name}return p(n)}function p(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.includes(`.solid.`)||e.toLowerCase().includes(`solid`)?`solid`:e.includes(`.qwik.`)||e.toLowerCase().includes(`qwik`)?`qwik`:e.includes(`react`)||e.toLowerCase().includes(`react`)?`react`:`preact`}function m(e,t){for(let n of t){let t=n.config();for(let n of t.detectionPatterns.imports)if(n.test(e))return t.name;for(let n of t.detectionPatterns.content)if(n.test(e))return t.name}return null}function h(e){for(let t of[{pattern:/solid-js|@jsxImportSource solid-js/,framework:`solid`},{pattern:/@builder\.io\/qwik|@jsxImportSource @builder\.io\/qwik/,framework:`qwik`},{pattern:/vue|Vue/,framework:`vue`},{pattern:/svelte/,framework:`svelte`},{pattern:/react/,framework:`react`},{pattern:/preact/,framework:`preact`}])if(t.pattern.test(e))return t.framework;return`preact`}async function g(e){try{return await a((await resolveIslandPath(e)).replace(/^\//,``),`utf-8`)}catch{let t=f.__viteDevServer;if(t){let n=await resolveIslandPath(e),r=await t.ssrLoadModule(n);return JSON.stringify(r)}return null}}export async function detectFramework(t){let n=e.getAll();for(let e of n){let n=e.config();for(let e of n.fileExtensions)if(t.endsWith(e))return n.name;if(t.includes(`.${n.name}.`))return n.name}try{let e=await g(t);return e?m(e,n)||(n.length===0?h(e):`preact`):`unknown`}catch{return`unknown`}}
@@ -0,0 +1 @@
1
+ import{registry as e}from"../core/integrations/registry.js";import{devWarn as t}from"../utils/dev-logger.js";const n=new Map;export async function loadIntegration(t){if(n.has(t))return n.get(t);if(e.has(t)){let r=e.get(t);return n.set(t,r),r}try{let r=await e.load(t);return n.set(t,r),r}catch(e){throw Error(`Integration '${t}' could not be loaded. Make sure @useavalon/${t} is installed.`,{cause:e})}}export async function detectAndLoadIntegration(e){return await loadIntegration(detectFrameworkFromPath(e))}export function detectFrameworkFromPath(e){let t=e.replaceAll(`\\`,`/`);return t.endsWith(`.vue`)?`vue`:t.endsWith(`.svelte`)?`svelte`:t.includes(`.solid.`)?`solid`:t.includes(`.qwik.`)?`qwik`:t.includes(`.react.`)?`react`:t.includes(`.lit.`)||(t.split(`/`).pop()||``).startsWith(`Lit`)&&(t.endsWith(`.ts`)||t.endsWith(`.js`))||isInIslandsDirectory(t)&&(t.endsWith(`.ts`)||t.endsWith(`.js`))?`lit`:(t.endsWith(`.tsx`)||t.endsWith(`.jsx`),`preact`)}export function isInIslandsDirectory(e){return e.replaceAll(`\\`,`/`).includes(`/islands/`)}export function isNestedIslandPath(e){let t=e.replaceAll(`\\`,`/`);if(!t.includes(`/islands/`))return!1;for(let e of[/^\/islands\//,/^\/src\/islands\//,/^src\/islands\//,/^islands\//])if(e.test(t))return!1;return!0}export function extractNamespaceFromPath(e){let t=e.replaceAll(`\\`,`/`),n=new RegExp(/(?:\/src)?\/(.+?)\/islands\//).exec(t);return n?n[1]:``}export function detectFrameworkFromContent(e,t){let n=detectFrameworkFromPath(e);return n===`vue`||n===`svelte`||n===`react`||n===`lit`?n:t.includes(`from 'react'`)||t.includes(`from "react"`)||t.includes(`from 'react-dom'`)||t.includes(`from "react-dom"`)||t.includes(`"use client"`)||t.includes(`'use client'`)||t.includes(`"use server"`)||t.includes(`'use server'`)?`react`:t.includes(`from 'lit'`)||t.includes(`from "lit"`)||t.includes(`@lit-labs/ssr`)||t.includes(`LitElement`)||t.includes(`@customElement`)?`lit`:t.includes(`solid-js`)||t.includes(`from 'solid-js'`)||t.includes(`from "solid-js"`)?`solid`:t.includes(`from 'preact'`)||t.includes(`from "preact"`)||t.includes(`preact/hooks`)?`preact`:t.includes(`extends LitElement`)||t.includes(`@property`)||t.includes(`@state`)||t.includes("html`")||t.includes("css`")?`lit`:t.includes(`createSignal`)||t.includes(`createEffect`)||t.includes(`createMemo`)?`solid`:t.includes(`useState`)||t.includes(`useEffect`)||t.includes(`useRef`)?`preact`:n}export async function getIntegration(e){try{return await loadIntegration(e)}catch(t){return console.error(`Failed to load integration for ${e}:`,t),null}}export async function hasIntegration(e){try{return await loadIntegration(e),!0}catch{return!1}}export function getLoadedIntegrations(){return Array.from(n.values())}export function getLoadedFrameworks(){return Array.from(n.keys())}export function clearIntegrationCache(){n.clear()}export function isIntegrationLoaded(e){return n.has(e)}export const DEFAULT_PRELOAD_FRAMEWORKS=[`preact`,`react`,`vue`,`svelte`,`solid`,`lit`];export async function preloadIntegrations(e){let n,i=!1,a;if(e?(n=e.frameworks??DEFAULT_PRELOAD_FRAMEWORKS,i=e.lazy??!1,a=e.detectedFrameworks):n=DEFAULT_PRELOAD_FRAMEWORKS,i&&a&&a.length>0){let e=n.filter(e=>a.includes(e));if(e.length===0)return;n=e}else if(i&&(!a||a.length===0))return;let o=await Promise.allSettled(n.map(e=>loadIntegration(e))),s=0,c=0;o.forEach((e,r)=>{e.status===`rejected`?(c++,t(`⚠️ Failed to preload integration '${n[r]}':`,e.reason)):s++})}export function detectFrameworksFromPageContent(e){let t=new Set,n=e.matchAll(/framework\s*=\s*["'](\w+)["']/g);for(let e of n)t.add(e[1]);let r=e.matchAll(/src\s*=\s*["']([^"']+)["']/g);for(let e of r){let n=e[1],r=detectFrameworkFromPath(n);t.add(r)}return(e.includes(`from 'react'`)||e.includes(`from "react"`))&&t.add(`react`),(e.includes(`from 'preact'`)||e.includes(`from "preact"`))&&t.add(`preact`),(e.includes(`from 'vue'`)||e.includes(`from "vue"`))&&t.add(`vue`),(e.includes(`from 'svelte'`)||e.includes(`from "svelte"`))&&t.add(`svelte`),(e.includes(`from 'solid-js'`)||e.includes(`from "solid-js"`))&&t.add(`solid`),(e.includes(`from 'lit'`)||e.includes(`from "lit"`))&&t.add(`lit`),Array.from(t)}
@@ -0,0 +1 @@
1
+ import{h as e}from"preact";import{detectFramework as t}from"./framework-detection.js";import{analyzeComponentFile as n,renderComponentSSROnly as r}from"./component-analysis.js";import{loadIntegration as i,detectFrameworkFromPath as a}from"./integration-loader.js";import{addUniversalCSS as o}from"./universal-css-collector.js";import{addUniversalHead as s}from"./universal-head-collector.js";import{getIslandBundlePath as c}from"../build/island-manifest.js";import{isDev as l,devLog as u,devWarn as d,devError as f,logRenderTiming as p}from"../utils/dev-logger.js";function m(e){return`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}`}function h(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 g(e,t,n,r){return{"data-condition":t,"data-src":c(e),"data-props":JSON.stringify(n),"data-render-strategy":`hydrate`,...h(r)}}function _(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 v(e){let t=e.match(/<style[^>]*>([\s\S]*?)<\/style>/i);return t?t[1].trim():null}function y(e,t,n,r){if(e.css&&o(e.css,t,n,e.scopeId),e.head){let i=e.head.trim(),a=_(i);if(a===`style`){let a=v(i);a&&(u(`${r} Extracting CSS from head <style> tag`),o(a,t,n,e.scopeId));return}s(e.head,t,n,a)}}function b(t){let{islandId:n,detectedFramework:r,shouldSkipHydration:i,src:a,condition:o,props:s,hydrationData:c,children:l}=t,d={id:n,"data-framework":r},f=i?{"data-render-strategy":`ssr-only`}:g(a,o,s,c);r===`lit`&&u(`🔍 [Island Component] ${a} - Lit hydration data:`,{hydrationDataKeys:Object.keys(c),metadata:c.metadata});let p={...d,...f};return typeof l==`string`?e(`avalon-island`,{...p,dangerouslySetInnerHTML:{__html:l}}):e(`avalon-island`,p,l)}function x(t,n,r,i,a,o,s){return r?e(`avalon-island`,{id:t,"data-render-strategy":`ssr-only`,"data-framework":n}):e(`avalon-island`,{id:t,"data-condition":a,"data-src":c(i),"data-props":JSON.stringify(o),"data-render-strategy":`hydrate`,"data-framework":n,...h(s)})}export default function S({src:e,condition:t=`on:client`,props:n={},children:r,ssr:i=t!==`on:client`,framework:o,ssrOnly:s=!1,renderOptions:c={},hydrationData:l={}}){let f=m(e),p=s||!!c.forceSSROnly,h=o||a(e),g=r!=null&&r!==``;return u(`🔍 [Island Component] ${e}`,{ssr:i,ssrOnly:s,hasChildren:g,framework:o,condition:t}),i&&g?b({islandId:f,detectedFramework:h,shouldSkipHydration:p,src:e,condition:t,props:n,hydrationData:l,children:r}):(i&&!g&&p&&d(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),x(f,h,p,e,t,n,l))}function C(t,n){let r=n instanceof Error?n.message:String(n);return f(`🚨 Island SSR failed for ${t}:`,n),n instanceof Error&&n.stack&&f(`Stack trace:`,n.stack),e(`avalon-island`,{id:m(t),"data-src":c(t),"data-ssr-error":r,"data-render-strategy":`client-only`})}async function w({src:e,condition:t,props:n,children:r,ssr:a,framework:o,ssrOnly:s,renderOptions:c}){let u=`🏝️ [${e}]`;if(!a||r)return S({src:e,condition:t,props:n,children:r,ssr:a,framework:o,ssrOnly:s,renderOptions:c});let d;try{d=await i(o)}catch(r){return f(`${u} Failed to load ${o} integration:`,r),S({src:e,condition:t,props:n,ssr:!1,framework:o,ssrOnly:s,renderOptions:c})}try{let r=await d.render({component:null,props:n,src:e,condition:t,ssrOnly:s,viteServer:globalThis.__viteDevServer,isDev:l()});return y(r,e,o,u),S({src:e,condition:t,props:n,children:r.html,ssr:!0,framework:o,ssrOnly:s,renderOptions:c,hydrationData:s?void 0:r.hydrationData})}catch(r){return f(`${u} Fast path SSR failed:`,r),S({src:e,condition:t,props:n,ssr:!1,framework:o,ssrOnly:s,renderOptions:c})}}async function T(e,t,r,i){if(t||r.detectScripts===!1)return t;try{let t=await n(e,r);if(t.decision.warnings?.length)for(let e of t.decision.warnings)d(`${i} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return d(`${i} Component analysis failed:`,e),t}}async function E(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?t(e):`unknown`}async function D(e,t,n,r,i,a){let o=await E(e),s=o,c=await(await O(o,a)).render({component:null,props:n,src:e,condition:t,ssrOnly:r,viteServer:globalThis.__viteDevServer,isDev:l()});return y(c,e,o,a),S({src:e,condition:t,props:n,children:c.html,ssr:!0,framework:s,ssrOnly:r,renderOptions:i,hydrationData:r?void 0:c.hydrationData})}async function O(e,t){try{u(`${t} Loading integration for framework: ${e}`);let n=await i(e);return u(`${t} ✅ Integration loaded successfully`),n}catch(n){throw f(`${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`,props:n={},children:r,ssr:i=t!==`on:client`,framework:a,ssrOnly:o=!1,renderOptions:s={}}){let c=l()?performance.now():0,u=`🏝️ [${e}]`;try{return o&&!i&&(i=!0),a?await w({src:e,condition:t,props:n,children:r,ssr:i,framework:a,ssrOnly:o,renderOptions:s}):await k({src:e,condition:t,props:n,children:r,ssr:i,ssrOnly:o,renderOptions:s,logPrefix:u})}catch(t){return C(e,t)}finally{l()&&p(e,performance.now()-c)}}async function k(e){let{src:t,condition:n,props:r,children:i,ssr:a,ssrOnly:o,renderOptions:s,logPrefix:c}=e;if(u(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:a,ssrOnly:o,hasChildren:!!i,condition:n}),await T(t,o,s,c))return A(t,n,r,i,a,s,c);if(!a||i)return S({src:t,condition:n,props:r,children:i,ssr:a,renderOptions:s});try{return await D(t,n,r,o,s,c)}catch(e){let i=await E(t);return f(`${c} Framework rendering failed:`,e),S({src:t,condition:n,props:r,ssr:!1,framework:i,renderOptions:s})}}function A(e,t,n,i,a,o,s){return a&&!i?r({src:e,condition:t,props:n,renderOptions:o}).catch(r=>(f(`${s} SSR failed for SSR-only component:`,r),S({src:e,condition:t,props:n,ssr:!1,ssrOnly:!0,renderOptions:o}))):S({src:e,condition:t,props:n,children:i,ssr:a,ssrOnly:!0,renderOptions:o})}
@@ -0,0 +1 @@
1
+ const e={analysisTTL:6e4,pathTTL:6e4,frameworkTTL:6e4,maxEntries:1e3},t={analysisSize:0,pathsSize:0,frameworksSize:0,analysisHits:0,analysisMisses:0,pathHits:0,pathMisses:0,frameworkHits:0,frameworkMisses:0},n={analysis:new Map,paths:new Map,frameworks:new Map,config:{...e},stats:{...t}};function r(){try{return process.env.NODE_ENV!==`production`}catch{return!0}}function i(){try{return process.env.AVALON_VERBOSE===`1`}catch{return!1}}function a(e,t){return Date.now()-e>t}function o(e,t){if(e.size<=t)return;let n=Array.from(e.entries()).sort((e,t)=>e[1].timestamp-t[1].timestamp).slice(0,e.size-t);for(let[t]of n)e.delete(t)}export function getCachedAnalysis(e){let t=n.analysis.get(e);if(t){if(!a(t.timestamp,n.config.analysisTTL))return n.stats.analysisHits++,t.result;n.analysis.delete(e)}return n.stats.analysisMisses++,null}export function setCachedAnalysis(e,t){n.analysis.set(e,{result:t,timestamp:Date.now()}),n.stats.analysisSize=n.analysis.size,o(n.analysis,n.config.maxEntries)}export function getCachedPath(e){let t=n.paths.get(e);if(t){if(!a(t.timestamp,n.config.pathTTL))return n.stats.pathHits++,t.resolved;n.paths.delete(e)}return n.stats.pathMisses++,null}export function setCachedPath(e,t){n.paths.set(e,{resolved:t,timestamp:Date.now()}),n.stats.pathsSize=n.paths.size,o(n.paths,n.config.maxEntries)}export function getCachedFramework(e){let t=n.frameworks.get(e);if(t){if(!a(t.timestamp,n.config.frameworkTTL))return n.stats.frameworkHits++,t.framework;n.frameworks.delete(e)}return n.stats.frameworkMisses++,null}export function setCachedFramework(e,t){n.frameworks.set(e,{framework:t,timestamp:Date.now()}),n.stats.frameworksSize=n.frameworks.size,o(n.frameworks,n.config.maxEntries)}export function clearCache(){n.analysis.clear(),n.paths.clear(),n.frameworks.clear(),n.stats={...t}}export function invalidateCacheForPath(e){n.analysis.delete(e),n.paths.delete(e),n.frameworks.delete(e),n.stats.analysisSize=n.analysis.size,n.stats.pathsSize=n.paths.size,n.stats.frameworksSize=n.frameworks.size}export function configureCache(e){n.config={...n.config,...e}}export function getCacheConfig(){return{...n.config}}export function getCacheStats(){return{analysisSize:n.analysis.size,pathsSize:n.paths.size,frameworksSize:n.frameworks.size,analysisHits:n.stats.analysisHits,analysisMisses:n.stats.analysisMisses,pathHits:n.stats.pathHits,pathMisses:n.stats.pathMisses,frameworkHits:n.stats.frameworkHits,frameworkMisses:n.stats.frameworkMisses}}export function logCacheStats(){if(!r()||!i())return;let e=getCacheStats(),t=e.analysisHits+e.pathHits+e.frameworkHits,n=e.analysisMisses+e.pathMisses+e.frameworkMisses,a=t+n>0?(t/(t+n)*100).toFixed(1):`0.0`;console.log(`📊 Island Render Cache Stats:`),console.log(` Analysis: ${e.analysisSize} entries (${e.analysisHits} hits / ${e.analysisMisses} misses)`),console.log(` Paths: ${e.pathsSize} entries (${e.pathHits} hits / ${e.pathMisses} misses)`),console.log(` Frameworks: ${e.frameworksSize} entries (${e.frameworkHits} hits / ${e.frameworkMisses} misses)`),console.log(` Overall hit rate: ${a}%`)}export function _getCache(){return n}function s(e){return e.replace(/\\/g,`/`).replace(/^\//,``).replace(/\?.*$/,``).replace(/#.*$/,``)}function c(e,t){let n=s(e),r=s(t);if(n===r||n.endsWith(r)||r.endsWith(n))return!0;let i=n.split(`/`).pop(),a=r.split(`/`).pop();return!!(i&&a&&i===a)}export function invalidateCacheForFile(e){let t=0;for(let r of n.analysis.keys())c(e,r)&&(n.analysis.delete(r),t++,i()&&console.log(`🗑️ [Cache] Invalidated analysis cache for: ${r}`));for(let r of n.paths.keys())c(e,r)&&(n.paths.delete(r),t++,i()&&console.log(`🗑️ [Cache] Invalidated path cache for: ${r}`));for(let r of n.frameworks.keys())c(e,r)&&(n.frameworks.delete(r),t++,i()&&console.log(`🗑️ [Cache] Invalidated framework cache for: ${r}`));return n.stats.analysisSize=n.analysis.size,n.stats.pathsSize=n.paths.size,n.stats.frameworksSize=n.frameworks.size,t}export function isIslandComponentFile(e){let t=s(e);return t.includes(`/islands/`)||t.includes(`\\islands\\`)?!0:[`.tsx`,`.jsx`,`.vue`,`.svelte`,`.solid.tsx`,`.lit.ts`].some(e=>t.endsWith(e))}export function clearPathCacheOnStructureChange(){n.paths.clear(),n.stats.pathsSize=0,i()&&console.log(`🗑️ [Cache] Cleared path cache due to file structure change`)}export function clearIslandCache(){clearCache(),i()&&console.log(`🗑️ [Cache] Cleared all island render caches`)}
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,5 @@
1
+ typeof globalThis<`u`&&!globalThis.__universalSSRCSS&&(globalThis.__universalSSRCSS=new Map);export function addUniversalCSS(e,t,n,r){if(!e||!e.trim())return;globalThis.__universalSSRCSS||(globalThis.__universalSSRCSS=new Map);let i=r||`${n}-${t}`,a={css:e.trim(),scopeId:i,src:t,framework:n,timestamp:Date.now()};globalThis.__universalSSRCSS.set(i,a)}export function getUniversalCSS(e=!1){if(!globalThis.__universalSSRCSS||globalThis.__universalSSRCSS.size===0)return``;let t=Array.from(globalThis.__universalSSRCSS.values());t.sort((e,t)=>e.timestamp-t.timestamp);let n=t.reduce((e,t)=>(e[t.framework]||(e[t.framework]=[]),e[t.framework].push(t),e),{}),r=[];for(let[e,t]of Object.entries(n)){let n=t.map(t=>`${`/* ${e}: ${t.src} (${t.scopeId}) */`}\n${t.css}`).join(`
2
+
3
+ `);r.push(n)}let i=r.join(`
4
+
5
+ `);return e&&globalThis.__universalSSRCSS.clear(),i}export function getUniversalCSSForHead(e=!1){let n=getUniversalCSS(e);return n.trim()?`<style data-universal-ssr="true" data-generated="${new Date().toISOString()}">\n${n}\n</style>`:``}export function clearUniversalCSS(){globalThis.__universalSSRCSS&&globalThis.__universalSSRCSS.clear()}export function getUniversalCSSStats(){if(!globalThis.__universalSSRCSS||globalThis.__universalSSRCSS.size===0)return{totalComponents:0,byFramework:{},totalCSSSize:0,averageCSSSize:0};let e=Array.from(globalThis.__universalSSRCSS.values()),t=e.reduce((e,t)=>(e[t.framework]=(e[t.framework]||0)+1,e),{}),n=e.reduce((e,t)=>e+t.css.length,0);return{totalComponents:e.length,byFramework:t,totalCSSSize:n,averageCSSSize:e.length>0?Math.round(n/e.length):0}}
@@ -0,0 +1,2 @@
1
+ function e(){return globalThis.__universalSSRHead||(globalThis.__universalSSRHead=new Map),globalThis.__universalSSRHead}export function addUniversalHead(t,n,r,i=`other`){let a=e(),o=`${r}-${n}-${i}`;a.set(o,{content:t,src:n,framework:r,type:i})}export function getUniversalHeadForInjection(t=!1){let n=e();if(n.size===0)return``;let r=Array.from(n.values()),i=r.filter(e=>e.type===`script`),a=r.filter(e=>e.type===`meta`),o=r.filter(e=>e.type===`link`),s=r.filter(e=>e.type===`other`),c=[];a.length>0&&(c.push(`<!-- Framework Meta Tags -->`),c.push(...a.map(e=>e.content))),o.length>0&&(c.push(`<!-- Framework Links -->`),c.push(...o.map(e=>e.content))),i.length>0&&(c.push(`<!-- Framework Hydration Scripts -->`),c.push(...i.map(e=>{let t=e.content.trim();return t.startsWith(`<script`)?t:`<script>${t}<\/script>`}))),s.length>0&&(c.push(`<!-- Framework Head Content -->`),c.push(...s.map(e=>e.content)));let l=c.join(`
2
+ `);return t&&n.clear(),l}export function clearUniversalHead(){e().clear()}export function getHeadCollectorSize(){return e().size}