@useavalon/avalon 0.1.13 → 0.1.14

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 (230) hide show
  1. package/dist/mod.js +1 -0
  2. package/dist/src/build/integration-bundler-plugin.js +1 -0
  3. package/dist/src/build/integration-config.js +1 -0
  4. package/dist/src/build/integration-detection-plugin.js +1 -0
  5. package/dist/src/build/integration-resolver-plugin.js +1 -0
  6. package/dist/src/build/island-manifest.js +1 -0
  7. package/dist/src/build/island-types-generator.js +5 -0
  8. package/dist/src/build/mdx-island-transform.js +2 -0
  9. package/dist/src/build/mdx-plugin.js +1 -0
  10. package/dist/src/build/page-island-transform.js +3 -0
  11. package/dist/src/build/prop-extractors/index.js +1 -0
  12. package/dist/src/build/prop-extractors/lit.js +1 -0
  13. package/dist/src/build/prop-extractors/qwik.js +1 -0
  14. package/dist/src/build/prop-extractors/solid.js +1 -0
  15. package/dist/src/build/prop-extractors/svelte.js +1 -0
  16. package/dist/src/build/prop-extractors/vue.js +1 -0
  17. package/dist/src/build/sidecar-file-manager.js +1 -0
  18. package/dist/src/build/sidecar-renderer.js +6 -0
  19. package/dist/src/client/adapters/index.js +1 -0
  20. package/dist/src/client/components.js +1 -0
  21. package/dist/src/client/css-hmr-handler.js +1 -0
  22. package/dist/src/client/framework-adapter.js +13 -0
  23. package/dist/src/client/hmr-coordinator.js +1 -0
  24. package/dist/src/client/hmr-error-overlay.js +214 -0
  25. package/dist/src/client/main.js +39 -0
  26. package/dist/src/components/Image.js +1 -0
  27. package/dist/src/components/IslandErrorBoundary.js +1 -0
  28. package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
  29. package/dist/src/components/LayoutErrorBoundary.js +1 -0
  30. package/dist/src/components/PersistentIsland.js +1 -0
  31. package/dist/src/components/StreamingErrorBoundary.js +1 -0
  32. package/dist/src/components/StreamingLayout.js +29 -0
  33. package/dist/src/core/components/component-analyzer.js +1 -0
  34. package/dist/src/core/components/component-detection.js +5 -0
  35. package/dist/src/core/components/enhanced-framework-detector.js +1 -0
  36. package/dist/src/core/components/framework-registry.js +1 -0
  37. package/dist/src/core/content/mdx-processor.js +1 -0
  38. package/dist/src/core/integrations/index.js +1 -0
  39. package/dist/src/core/integrations/loader.js +1 -0
  40. package/dist/src/core/integrations/registry.js +1 -0
  41. package/dist/src/core/islands/island-persistence.js +1 -0
  42. package/dist/src/core/islands/island-state-serializer.js +1 -0
  43. package/dist/src/core/islands/persistent-island-context.js +1 -0
  44. package/dist/src/core/islands/use-persistent-state.js +1 -0
  45. package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
  46. package/dist/src/core/layout/layout-cache-manager.js +1 -0
  47. package/dist/src/core/layout/layout-composer.js +1 -0
  48. package/dist/src/core/layout/layout-data-loader.js +1 -0
  49. package/dist/src/core/layout/layout-discovery.js +1 -0
  50. package/dist/src/core/layout/layout-matcher.js +1 -0
  51. package/dist/src/core/layout/layout-types.js +1 -0
  52. package/dist/src/core/modules/framework-module-resolver.js +1 -0
  53. package/dist/src/islands/component-analysis.js +1 -0
  54. package/dist/src/islands/css-utils.js +17 -0
  55. package/dist/src/islands/discovery/index.js +1 -0
  56. package/dist/src/islands/discovery/registry.js +1 -0
  57. package/dist/src/islands/discovery/resolver.js +2 -0
  58. package/dist/src/islands/discovery/scanner.js +1 -0
  59. package/dist/src/islands/discovery/types.js +1 -0
  60. package/dist/src/islands/discovery/validator.js +18 -0
  61. package/dist/src/islands/discovery/watcher.js +1 -0
  62. package/dist/src/islands/framework-detection.js +1 -0
  63. package/dist/src/islands/integration-loader.js +1 -0
  64. package/dist/src/islands/island.js +1 -0
  65. package/dist/src/islands/render-cache.js +1 -0
  66. package/dist/src/islands/types.js +1 -0
  67. package/dist/src/islands/universal-css-collector.js +5 -0
  68. package/dist/src/islands/universal-head-collector.js +2 -0
  69. package/dist/src/layout-system.js +1 -0
  70. package/dist/src/middleware/discovery.js +1 -0
  71. package/dist/src/middleware/executor.js +1 -0
  72. package/dist/src/middleware/index.js +1 -0
  73. package/dist/src/middleware/types.js +1 -0
  74. package/dist/src/nitro/build-config.js +1 -0
  75. package/dist/src/nitro/config.js +1 -0
  76. package/dist/src/nitro/error-handler.js +198 -0
  77. package/dist/src/nitro/index.js +1 -0
  78. package/dist/src/nitro/island-manifest.js +2 -0
  79. package/dist/src/nitro/middleware-adapter.js +1 -0
  80. package/dist/src/nitro/renderer.js +183 -0
  81. package/dist/src/nitro/route-discovery.js +1 -0
  82. package/dist/src/nitro/types.js +1 -0
  83. package/dist/src/render/collect-css.js +3 -0
  84. package/dist/src/render/error-pages.js +48 -0
  85. package/dist/src/render/isolated-ssr-renderer.js +1 -0
  86. package/dist/src/render/ssr.js +90 -0
  87. package/dist/src/schemas/api.js +1 -0
  88. package/dist/src/schemas/core.js +1 -0
  89. package/dist/src/schemas/index.js +1 -0
  90. package/dist/src/schemas/layout.js +1 -0
  91. package/dist/src/schemas/routing/index.js +1 -0
  92. package/dist/src/schemas/routing.js +1 -0
  93. package/dist/src/types/as-island.js +1 -0
  94. package/dist/src/types/layout.js +1 -0
  95. package/dist/src/types/routing.js +1 -0
  96. package/dist/src/types/types.js +1 -0
  97. package/dist/src/utils/dev-logger.js +12 -0
  98. package/dist/src/utils/fs.js +1 -0
  99. package/dist/src/vite-plugin/auto-discover.js +1 -0
  100. package/dist/src/vite-plugin/config.js +1 -0
  101. package/dist/src/vite-plugin/errors.js +1 -0
  102. package/dist/src/vite-plugin/image-optimization.js +45 -0
  103. package/dist/src/vite-plugin/integration-activator.js +1 -0
  104. package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
  105. package/dist/src/vite-plugin/module-discovery.js +1 -0
  106. package/dist/src/vite-plugin/nitro-integration.js +42 -0
  107. package/dist/src/vite-plugin/plugin.js +1 -0
  108. package/dist/src/vite-plugin/types.js +1 -0
  109. package/dist/src/vite-plugin/validation.js +2 -0
  110. package/package.json +14 -20
  111. package/mod.ts +0 -302
  112. package/src/build/integration-bundler-plugin.ts +0 -116
  113. package/src/build/integration-config.ts +0 -168
  114. package/src/build/integration-detection-plugin.ts +0 -117
  115. package/src/build/integration-resolver-plugin.ts +0 -90
  116. package/src/build/island-manifest.ts +0 -269
  117. package/src/build/island-types-generator.ts +0 -476
  118. package/src/build/mdx-island-transform.ts +0 -464
  119. package/src/build/mdx-plugin.ts +0 -98
  120. package/src/build/page-island-transform.ts +0 -598
  121. package/src/build/prop-extractors/index.ts +0 -21
  122. package/src/build/prop-extractors/lit.ts +0 -140
  123. package/src/build/prop-extractors/qwik.ts +0 -16
  124. package/src/build/prop-extractors/solid.ts +0 -125
  125. package/src/build/prop-extractors/svelte.ts +0 -194
  126. package/src/build/prop-extractors/vue.ts +0 -111
  127. package/src/build/sidecar-file-manager.ts +0 -104
  128. package/src/build/sidecar-renderer.ts +0 -30
  129. package/src/client/adapters/index.ts +0 -21
  130. package/src/client/components.ts +0 -35
  131. package/src/client/css-hmr-handler.ts +0 -344
  132. package/src/client/framework-adapter.ts +0 -462
  133. package/src/client/hmr-coordinator.ts +0 -396
  134. package/src/client/hmr-error-overlay.js +0 -533
  135. package/src/client/main.js +0 -824
  136. package/src/components/Image.tsx +0 -123
  137. package/src/components/IslandErrorBoundary.tsx +0 -145
  138. package/src/components/LayoutDataErrorBoundary.tsx +0 -141
  139. package/src/components/LayoutErrorBoundary.tsx +0 -127
  140. package/src/components/PersistentIsland.tsx +0 -52
  141. package/src/components/StreamingErrorBoundary.tsx +0 -233
  142. package/src/components/StreamingLayout.tsx +0 -538
  143. package/src/core/components/component-analyzer.ts +0 -192
  144. package/src/core/components/component-detection.ts +0 -508
  145. package/src/core/components/enhanced-framework-detector.ts +0 -500
  146. package/src/core/components/framework-registry.ts +0 -563
  147. package/src/core/content/mdx-processor.ts +0 -46
  148. package/src/core/integrations/index.ts +0 -19
  149. package/src/core/integrations/loader.ts +0 -125
  150. package/src/core/integrations/registry.ts +0 -175
  151. package/src/core/islands/island-persistence.ts +0 -325
  152. package/src/core/islands/island-state-serializer.ts +0 -258
  153. package/src/core/islands/persistent-island-context.tsx +0 -80
  154. package/src/core/islands/use-persistent-state.ts +0 -68
  155. package/src/core/layout/enhanced-layout-resolver.ts +0 -322
  156. package/src/core/layout/layout-cache-manager.ts +0 -485
  157. package/src/core/layout/layout-composer.ts +0 -357
  158. package/src/core/layout/layout-data-loader.ts +0 -516
  159. package/src/core/layout/layout-discovery.ts +0 -243
  160. package/src/core/layout/layout-matcher.ts +0 -299
  161. package/src/core/layout/layout-types.ts +0 -110
  162. package/src/core/modules/framework-module-resolver.ts +0 -273
  163. package/src/islands/component-analysis.ts +0 -213
  164. package/src/islands/css-utils.ts +0 -565
  165. package/src/islands/discovery/index.ts +0 -80
  166. package/src/islands/discovery/registry.ts +0 -340
  167. package/src/islands/discovery/resolver.ts +0 -477
  168. package/src/islands/discovery/scanner.ts +0 -386
  169. package/src/islands/discovery/types.ts +0 -117
  170. package/src/islands/discovery/validator.ts +0 -544
  171. package/src/islands/discovery/watcher.ts +0 -368
  172. package/src/islands/framework-detection.ts +0 -428
  173. package/src/islands/integration-loader.ts +0 -490
  174. package/src/islands/island.tsx +0 -565
  175. package/src/islands/render-cache.ts +0 -550
  176. package/src/islands/types.ts +0 -80
  177. package/src/islands/universal-css-collector.ts +0 -157
  178. package/src/islands/universal-head-collector.ts +0 -137
  179. package/src/layout-system.ts +0 -218
  180. package/src/middleware/discovery.ts +0 -268
  181. package/src/middleware/executor.ts +0 -315
  182. package/src/middleware/index.ts +0 -76
  183. package/src/middleware/types.ts +0 -99
  184. package/src/nitro/build-config.ts +0 -576
  185. package/src/nitro/config.ts +0 -483
  186. package/src/nitro/error-handler.ts +0 -636
  187. package/src/nitro/index.ts +0 -173
  188. package/src/nitro/island-manifest.ts +0 -584
  189. package/src/nitro/middleware-adapter.ts +0 -260
  190. package/src/nitro/renderer.ts +0 -1471
  191. package/src/nitro/route-discovery.ts +0 -439
  192. package/src/nitro/types.ts +0 -321
  193. package/src/render/collect-css.ts +0 -198
  194. package/src/render/error-pages.ts +0 -79
  195. package/src/render/isolated-ssr-renderer.ts +0 -654
  196. package/src/render/ssr.ts +0 -1030
  197. package/src/schemas/api.ts +0 -30
  198. package/src/schemas/core.ts +0 -64
  199. package/src/schemas/index.ts +0 -212
  200. package/src/schemas/layout.ts +0 -279
  201. package/src/schemas/routing/index.ts +0 -38
  202. package/src/schemas/routing.ts +0 -376
  203. package/src/types/as-island.ts +0 -20
  204. package/src/types/layout.ts +0 -285
  205. package/src/types/routing.ts +0 -555
  206. package/src/types/types.ts +0 -5
  207. package/src/utils/dev-logger.ts +0 -299
  208. package/src/utils/fs.ts +0 -151
  209. package/src/vite-plugin/auto-discover.ts +0 -551
  210. package/src/vite-plugin/config.ts +0 -266
  211. package/src/vite-plugin/errors.ts +0 -127
  212. package/src/vite-plugin/image-optimization.ts +0 -156
  213. package/src/vite-plugin/integration-activator.ts +0 -126
  214. package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
  215. package/src/vite-plugin/module-discovery.ts +0 -189
  216. package/src/vite-plugin/nitro-integration.ts +0 -1354
  217. package/src/vite-plugin/plugin.ts +0 -403
  218. package/src/vite-plugin/types.ts +0 -327
  219. package/src/vite-plugin/validation.ts +0 -228
  220. /package/{src → dist/src}/client/types/framework-runtime.d.ts +0 -0
  221. /package/{src → dist/src}/client/types/vite-hmr.d.ts +0 -0
  222. /package/{src → dist/src}/client/types/vite-virtual-modules.d.ts +0 -0
  223. /package/{src → dist/src}/layout-system.d.ts +0 -0
  224. /package/{src → dist/src}/types/image.d.ts +0 -0
  225. /package/{src → dist/src}/types/index.d.ts +0 -0
  226. /package/{src → dist/src}/types/island-jsx.d.ts +0 -0
  227. /package/{src → dist/src}/types/island-prop.d.ts +0 -0
  228. /package/{src → dist/src}/types/mdx.d.ts +0 -0
  229. /package/{src → dist/src}/types/urlpattern.d.ts +0 -0
  230. /package/{src → dist/src}/types/vite-env.d.ts +0 -0
@@ -1,654 +0,0 @@
1
- /**
2
- * Isolated SSR Renderer
3
- *
4
- * This module provides framework-specific SSR contexts to prevent cross-contamination
5
- * between different frameworks during server-side rendering. Each framework gets its
6
- * own isolated import context and rendering pipeline.
7
- */
8
-
9
- import type { JSX } from 'preact';
10
- import { render as preactRenderToString } from 'preact-render-to-string';
11
- import { readFile } from 'node:fs/promises';
12
- import { EnhancedFrameworkDetector } from '../core/components/enhanced-framework-detector.ts';
13
- import { toImportSpecifier } from '../middleware/executor.ts';
14
-
15
- export interface FrameworkSSRContext {
16
- framework: string;
17
- imports: Map<string, unknown>;
18
- renderFunction: (component: unknown, props: unknown) => Promise<string>;
19
- cleanup: () => void;
20
- isActive: boolean;
21
- }
22
-
23
- export interface SSRIsolationConfig {
24
- enableStrictIsolation: boolean;
25
- allowedCrossFrameworkImports: string[];
26
- errorHandling: 'strict' | 'fallback' | 'ignore';
27
- debugLogging: boolean;
28
- }
29
-
30
- export interface IsolatedRenderRequest {
31
- componentPath: string;
32
- component: () => JSX.Element | Promise<JSX.Element>;
33
- framework?: string;
34
- props?: Record<string, unknown>;
35
- }
36
-
37
- export interface IsolatedRenderResult {
38
- html: string;
39
- framework: string;
40
- success: boolean;
41
- errors: string[];
42
- warnings: string[];
43
- }
44
-
45
- /**
46
- * Isolated SSR Renderer with framework-specific contexts
47
- */
48
- export class IsolatedSSRRenderer {
49
- private readonly contexts: Map<string, FrameworkSSRContext>;
50
- private readonly detector: EnhancedFrameworkDetector;
51
- private config: SSRIsolationConfig;
52
- private activeContext: string | null = null;
53
-
54
- constructor(config: Partial<SSRIsolationConfig> = {}) {
55
- this.contexts = new Map();
56
- this.detector = new EnhancedFrameworkDetector();
57
- this.config = {
58
- enableStrictIsolation: true,
59
- allowedCrossFrameworkImports: ['preact', 'preact-render-to-string'],
60
- errorHandling: 'fallback',
61
- debugLogging: false,
62
- ...config,
63
- };
64
-
65
- this.initializeFrameworkContexts();
66
- }
67
-
68
- /**
69
- * Renders a component with framework isolation
70
- */
71
- async renderWithIsolation(request: IsolatedRenderRequest): Promise<IsolatedRenderResult> {
72
- const errors: string[] = [];
73
- const warnings: string[] = [];
74
-
75
- try {
76
- const framework = await this.resolveFramework(request, warnings);
77
- return await this.renderInContext(request, framework, errors, warnings);
78
- } catch (error) {
79
- errors.push(`SSR rendering failed: ${error instanceof Error ? error.message : String(error)}`);
80
- return await this.tryFallbackRender(request, errors, warnings);
81
- }
82
- }
83
-
84
- private async resolveFramework(request: IsolatedRenderRequest, warnings: string[]): Promise<string> {
85
- if (request.framework) return request.framework;
86
-
87
- try {
88
- const content = await this.getComponentContent(request.componentPath);
89
- const detection = this.detector.detectFramework(request.componentPath, content);
90
-
91
- if (detection.confidence === 'low') {
92
- warnings.push(`Low confidence framework detection for ${request.componentPath}: ${detection.framework}`);
93
- }
94
- if (this.config.debugLogging) {
95
- console.log(`[SSR Isolation] Detected framework: ${detection.framework} for ${request.componentPath}`);
96
- console.log(`[SSR Isolation] Evidence: ${detection.evidence.join(', ')}`);
97
- }
98
- return detection.framework;
99
- } catch {
100
- // Component path is a virtual/route path — can't read file, default to preact
101
- warnings.push(
102
- `Could not read component file for framework detection: ${request.componentPath}, defaulting to preact`,
103
- );
104
- return 'preact';
105
- }
106
- }
107
-
108
- private async renderInContext(
109
- request: IsolatedRenderRequest,
110
- framework: string,
111
- errors: string[],
112
- warnings: string[],
113
- ): Promise<IsolatedRenderResult> {
114
- const context = this.getFrameworkContext(framework);
115
- if (!context) throw new Error(`No SSR context available for framework: ${framework}`);
116
-
117
- await this.switchToContext(framework);
118
- try {
119
- const componentResult = request.component();
120
- const resolvedComponent = componentResult instanceof Promise ? await componentResult : componentResult;
121
- const html = await context.renderFunction(resolvedComponent, request.props || {});
122
- return { html, framework, success: true, errors, warnings };
123
- } finally {
124
- this.cleanupContext(framework);
125
- }
126
- }
127
-
128
- private async tryFallbackRender(
129
- request: IsolatedRenderRequest,
130
- errors: string[],
131
- warnings: string[],
132
- ): Promise<IsolatedRenderResult> {
133
- if (this.config.errorHandling !== 'fallback') {
134
- return { html: '', framework: request.framework || 'unknown', success: false, errors, warnings };
135
- }
136
- try {
137
- const resolvedComponent = await request.component();
138
- const html = preactRenderToString(resolvedComponent);
139
- warnings.push('Fell back to Preact rendering due to framework-specific error');
140
- return { html, framework: 'preact', success: true, errors, warnings };
141
- } catch (fallbackError) {
142
- errors.push(
143
- `Fallback rendering also failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
144
- );
145
- return { html: '', framework: request.framework || 'unknown', success: false, errors, warnings };
146
- }
147
- }
148
-
149
- /**
150
- * Initializes framework-specific SSR contexts
151
- */
152
- private initializeFrameworkContexts(): void {
153
- // Preact context
154
- this.contexts.set('preact', {
155
- framework: 'preact',
156
- imports: new Map(),
157
- renderFunction: (component: unknown) => {
158
- return Promise.resolve(preactRenderToString(component as JSX.Element));
159
- },
160
- cleanup: () => {
161
- this.clearFrameworkGlobals('preact');
162
- },
163
- isActive: false,
164
- });
165
-
166
- this.contexts.set('solid', {
167
- framework: 'solid',
168
- imports: new Map(),
169
- renderFunction: async (component: unknown) => {
170
- try {
171
- // Import Solid SSR modules in isolation
172
- const solidWeb = (await this.importFrameworkModule('solid-js/web', 'solid')) as Record<string, unknown>;
173
- if (solidWeb && typeof solidWeb.renderToString === 'function') {
174
- return (solidWeb.renderToString as (fn: () => unknown) => string)(() => component);
175
- }
176
- throw new Error('Solid renderToString not available');
177
- } catch (error) {
178
- throw new Error(`Solid SSR failed: ${error instanceof Error ? error.message : String(error)}`);
179
- }
180
- },
181
- cleanup: () => {
182
- this.clearFrameworkGlobals('solid');
183
- },
184
- isActive: false,
185
- });
186
-
187
- this.contexts.set('vue', {
188
- framework: 'vue',
189
- imports: new Map(),
190
- renderFunction: async (component: unknown) => {
191
- try {
192
- // Import Vue SSR modules in isolation
193
- const vueServerRenderer = (await this.importFrameworkModule('vue/server-renderer', 'vue')) as Record<
194
- string,
195
- unknown
196
- >;
197
- if (vueServerRenderer && typeof vueServerRenderer.renderToString === 'function') {
198
- return await (vueServerRenderer.renderToString as (component: unknown) => Promise<string>)(component);
199
- }
200
- throw new Error('Vue renderToString not available');
201
- } catch (error) {
202
- throw new Error(`Vue SSR failed: ${error instanceof Error ? error.message : String(error)}`);
203
- }
204
- },
205
- cleanup: () => {
206
- this.clearFrameworkGlobals('vue');
207
- },
208
- isActive: false,
209
- });
210
-
211
- this.contexts.set('svelte', {
212
- framework: 'svelte',
213
- imports: new Map(),
214
- renderFunction: (component: unknown) => {
215
- try {
216
- // Svelte components have a render method
217
- if (component && typeof component === 'object' && 'render' in component) {
218
- const renderResult = (component as { render: () => { html?: string } }).render();
219
- return Promise.resolve(renderResult.html || '');
220
- }
221
- throw new Error('Svelte component does not have render method');
222
- } catch (error) {
223
- throw new Error(`Svelte SSR failed: ${error instanceof Error ? error.message : String(error)}`);
224
- }
225
- },
226
- cleanup: () => {
227
- this.clearFrameworkGlobals('svelte');
228
- },
229
- isActive: false,
230
- });
231
-
232
- this.contexts.set('unknown', {
233
- framework: 'unknown',
234
- imports: new Map(),
235
- renderFunction: (component: unknown) => {
236
- // Fallback to Preact rendering
237
- return Promise.resolve(preactRenderToString(component as JSX.Element));
238
- },
239
- cleanup: () => {
240
- // No specific cleanup needed
241
- },
242
- isActive: false,
243
- });
244
- }
245
-
246
- /**
247
- * Gets or creates a framework context
248
- */
249
- private getFrameworkContext(framework: string): FrameworkSSRContext | null {
250
- const context = this.contexts.get(framework);
251
- if (context) {
252
- return context;
253
- }
254
-
255
- // If framework not found, use unknown/fallback context
256
- return this.contexts.get('unknown') || null;
257
- }
258
-
259
- /**
260
- * Switches to a specific framework context with isolation
261
- */
262
- private async switchToContext(framework: string): Promise<void> {
263
- // Cleanup previous context if active
264
- if (this.activeContext && this.activeContext !== framework) {
265
- this.cleanupContext(this.activeContext);
266
- }
267
-
268
- const context = this.contexts.get(framework);
269
- if (!context) {
270
- throw new Error(`Framework context not found: ${framework}`);
271
- }
272
-
273
- // Activate the context
274
- context.isActive = true;
275
- this.activeContext = framework;
276
-
277
- // Set up framework-specific environment
278
- await this.setupFrameworkEnvironment(framework);
279
- }
280
-
281
- /**
282
- * Cleans up a framework context
283
- */
284
- private cleanupContext(framework: string): void {
285
- const context = this.contexts.get(framework);
286
- if (!context) {
287
- return;
288
- }
289
-
290
- // Run framework-specific cleanup
291
- context.cleanup();
292
- context.isActive = false;
293
-
294
- // Clear framework-specific imports
295
- context.imports.clear();
296
-
297
- if (this.activeContext === framework) {
298
- this.activeContext = null;
299
- }
300
- }
301
-
302
- /**
303
- * Sets up framework-specific environment
304
- */
305
- private async setupFrameworkEnvironment(framework: string): Promise<void> {
306
- // Framework-specific setup logic
307
- switch (framework) {
308
- case 'solid':
309
- // Ensure Solid-specific globals are available
310
- await this.ensureSolidEnvironment();
311
- break;
312
- case 'vue':
313
- // Ensure Vue-specific globals are available
314
- await this.ensureVueEnvironment();
315
- break;
316
- case 'svelte':
317
- // Ensure Svelte-specific globals are available
318
- this.ensureSvelteEnvironment();
319
- break;
320
- case 'preact':
321
- default:
322
- // Preact is the default, no special setup needed
323
- break;
324
- }
325
- }
326
-
327
- /**
328
- * Imports a framework module with isolation
329
- */
330
- private async importFrameworkModule(modulePath: string, framework: string): Promise<unknown> {
331
- const context = this.contexts.get(framework);
332
- if (!context) {
333
- throw new Error(`No context for framework: ${framework}`);
334
- }
335
-
336
- // Check if module is already imported in this context
337
- if (context.imports.has(modulePath)) {
338
- return context.imports.get(modulePath);
339
- }
340
-
341
- // Validate import is allowed for this framework
342
- if (this.config.enableStrictIsolation && !this.isImportAllowed(modulePath, framework)) {
343
- throw new Error(`Import not allowed in ${framework} context: ${modulePath}`);
344
- }
345
-
346
- try {
347
- // Import the module
348
- const module = await import(/* @vite-ignore */ toImportSpecifier(modulePath));
349
-
350
- // Store in context-specific imports
351
- context.imports.set(modulePath, module);
352
-
353
- if (this.config.debugLogging) {
354
- console.log(`[SSR Isolation] Imported ${modulePath} in ${framework} context`);
355
- }
356
-
357
- return module;
358
- } catch (error) {
359
- throw new Error(
360
- `Failed to import ${modulePath} in ${framework} context: ${
361
- error instanceof Error ? error.message : String(error)
362
- }`,
363
- );
364
- }
365
- }
366
-
367
- /**
368
- * Checks if an import is allowed for a specific framework
369
- */
370
- private isImportAllowed(modulePath: string, framework: string): boolean {
371
- // Always allow framework-specific modules
372
- const frameworkConfig = this.detector.getFrameworkConfigs().get(framework);
373
- if (frameworkConfig) {
374
- const allowedModules = [...frameworkConfig.ssrModules, ...frameworkConfig.hydrationModules];
375
- if (allowedModules.some(allowed => modulePath.startsWith(allowed))) {
376
- return true;
377
- }
378
- }
379
-
380
- // Check globally allowed cross-framework imports
381
- return this.config.allowedCrossFrameworkImports.some(allowed => modulePath.startsWith(allowed));
382
- }
383
-
384
- /**
385
- * Clears framework-specific globals
386
- */
387
- private clearFrameworkGlobals(framework: string): void {
388
- // Clear framework-specific globals to prevent contamination
389
- const globals = globalThis as Record<string, unknown>;
390
- switch (framework) {
391
- case 'solid':
392
- // Clear Solid-specific globals if they exist
393
- if (typeof globalThis !== 'undefined') {
394
- delete globals._$HY;
395
- delete globals.Solid;
396
- }
397
- break;
398
- case 'vue':
399
- // Clear Vue-specific globals if they exist
400
- if (typeof globalThis !== 'undefined') {
401
- delete globals.__VUE__;
402
- delete globals.Vue;
403
- }
404
- break;
405
- case 'svelte':
406
- // Clear Svelte-specific globals if they exist
407
- if (typeof globalThis !== 'undefined') {
408
- delete globals.__SVELTE__;
409
- }
410
- break;
411
- }
412
- }
413
-
414
- /**
415
- * Ensures Solid environment is properly set up
416
- */
417
- private async ensureSolidEnvironment(): Promise<void> {
418
- try {
419
- // Import Solid modules needed for SSR
420
- await this.importFrameworkModule('solid-js/web', 'solid');
421
- } catch (error) {
422
- if (this.config.debugLogging) {
423
- console.warn('[SSR Isolation] Failed to set up Solid environment:', error);
424
- }
425
- }
426
- }
427
-
428
- /**
429
- * Ensures Vue environment is properly set up
430
- */
431
- private async ensureVueEnvironment(): Promise<void> {
432
- try {
433
- // Import Vue modules needed for SSR
434
- await this.importFrameworkModule('vue/server-renderer', 'vue');
435
- } catch (error) {
436
- if (this.config.debugLogging) {
437
- console.warn('[SSR Isolation] Failed to set up Vue environment:', error);
438
- }
439
- }
440
- }
441
-
442
- /**
443
- * Ensures Svelte environment is properly set up
444
- */
445
- private ensureSvelteEnvironment(): void {
446
- try {
447
- // Svelte components are typically pre-compiled, no special setup needed
448
- if (this.config.debugLogging) {
449
- console.log('[SSR Isolation] Svelte environment ready');
450
- }
451
- } catch (error) {
452
- if (this.config.debugLogging) {
453
- console.warn('[SSR Isolation] Failed to set up Svelte environment:', error);
454
- }
455
- }
456
- }
457
-
458
- /**
459
- * Gets component content for framework detection
460
- */
461
- private async getComponentContent(componentPath: string): Promise<string> {
462
- try {
463
- // Try to read the component file
464
- let resolvedPath = componentPath;
465
-
466
- // Handle different path formats
467
- if (componentPath.startsWith('/')) {
468
- resolvedPath = componentPath.substring(1);
469
- }
470
-
471
- // Try multiple path variations
472
- const pathVariations = [
473
- resolvedPath,
474
- `src/islands/${resolvedPath.split('/').pop()}`,
475
- `islands/${resolvedPath.split('/').pop()}`,
476
- `examples/${resolvedPath.split('/').pop()}`,
477
- ];
478
-
479
- for (const pathVariation of pathVariations) {
480
- try {
481
- return await readFile(pathVariation, 'utf-8');
482
- } catch {
483
- // Continue to next path variation
484
- continue;
485
- }
486
- }
487
-
488
- throw new Error(`Component file not found: ${componentPath}`);
489
- } catch (error) {
490
- throw new Error(`Failed to read component content: ${error instanceof Error ? error.message : String(error)}`);
491
- }
492
- }
493
-
494
- /**
495
- * Gets current active context
496
- */
497
- getActiveContext(): string | null {
498
- return this.activeContext;
499
- }
500
-
501
- /**
502
- * Gets all framework contexts
503
- */
504
- getContexts(): Map<string, FrameworkSSRContext> {
505
- return new Map(this.contexts);
506
- }
507
-
508
- /**
509
- * Updates configuration
510
- */
511
- updateConfig(config: Partial<SSRIsolationConfig>): void {
512
- this.config = { ...this.config, ...config };
513
- }
514
-
515
- /**
516
- * Resets all contexts
517
- */
518
- resetAllContexts(): void {
519
- for (const [framework] of this.contexts) {
520
- this.cleanupContext(framework);
521
- }
522
- this.activeContext = null;
523
- }
524
-
525
- /**
526
- * Creates fallback rendering when framework modules are unavailable
527
- */
528
- async renderWithFallback(
529
- component: () => JSX.Element | Promise<JSX.Element>,
530
- preferredFramework: string,
531
- ): Promise<IsolatedRenderResult> {
532
- const errors: string[] = [];
533
- const warnings: string[] = [];
534
-
535
- // Try preferred framework first
536
- try {
537
- const request: IsolatedRenderRequest = {
538
- componentPath: 'fallback-component',
539
- component,
540
- framework: preferredFramework,
541
- };
542
-
543
- const result = await this.renderWithIsolation(request);
544
- if (result.success) {
545
- return result;
546
- }
547
-
548
- errors.push(...result.errors);
549
- warnings.push(...result.warnings);
550
- } catch (error) {
551
- errors.push(
552
- `Preferred framework (${preferredFramework}) failed: ${error instanceof Error ? error.message : String(error)}`,
553
- );
554
- }
555
-
556
- // Try fallback frameworks in order of preference
557
- const fallbackOrder = ['preact', 'unknown'];
558
-
559
- for (const fallbackFramework of fallbackOrder) {
560
- if (fallbackFramework === preferredFramework) {
561
- continue; // Already tried
562
- }
563
-
564
- try {
565
- const request: IsolatedRenderRequest = {
566
- componentPath: 'fallback-component',
567
- component,
568
- framework: fallbackFramework,
569
- };
570
-
571
- const result = await this.renderWithIsolation(request);
572
- if (result.success) {
573
- warnings.push(`Fell back to ${fallbackFramework} rendering from ${preferredFramework}`);
574
- return {
575
- ...result,
576
- warnings: [...warnings, ...result.warnings],
577
- };
578
- }
579
-
580
- errors.push(...result.errors);
581
- } catch (error) {
582
- errors.push(
583
- `Fallback framework (${fallbackFramework}) failed: ${error instanceof Error ? error.message : String(error)}`,
584
- );
585
- }
586
- }
587
-
588
- // All frameworks failed, return error result
589
- return {
590
- html: '',
591
- framework: preferredFramework,
592
- success: false,
593
- errors,
594
- warnings,
595
- };
596
- }
597
-
598
- /**
599
- * Validates that a framework context is properly set up
600
- */
601
- async validateFrameworkContext(framework: string): Promise<boolean> {
602
- const context = this.contexts.get(framework);
603
- if (!context) {
604
- return false;
605
- }
606
-
607
- try {
608
- // Try to set up the framework environment
609
- await this.setupFrameworkEnvironment(framework);
610
- return true;
611
- } catch (error) {
612
- if (this.config.debugLogging) {
613
- console.warn(`[SSR Isolation] Framework context validation failed for ${framework}:`, error);
614
- }
615
- return false;
616
- }
617
- }
618
-
619
- /**
620
- * Gets framework-specific error recovery strategies
621
- */
622
- getErrorRecoveryStrategies(framework: string): string[] {
623
- const strategies: Record<string, string[]> = {
624
- solid: [
625
- 'Ensure solid-js and solid-js/web are installed',
626
- 'Check that Solid components use proper JSX import source: /** @jsxImportSource solid-js */',
627
- 'Verify Solid components export default function',
628
- ],
629
- vue: [
630
- 'Ensure vue and vue/server-renderer are installed',
631
- 'Check that Vue components have proper <template>, <script>, and <style> sections',
632
- 'Verify Vue components are properly compiled for SSR',
633
- ],
634
- svelte: [
635
- 'Ensure svelte is installed and components are compiled',
636
- 'Check that Svelte components export default class or function',
637
- 'Verify Svelte components have proper script and style sections',
638
- ],
639
- preact: [
640
- 'Ensure preact and preact-render-to-string are installed',
641
- 'Check that Preact components use proper JSX import source: /** @jsxImportSource preact */',
642
- 'Verify Preact components export default function',
643
- ],
644
- };
645
-
646
- return (
647
- strategies[framework] || [
648
- 'Check that the framework is properly installed',
649
- 'Verify component syntax is correct for the detected framework',
650
- 'Consider adding explicit framework detection hints',
651
- ]
652
- );
653
- }
654
- }