@useavalon/avalon 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -54
- package/mod.ts +302 -302
- package/package.json +49 -26
- package/src/build/integration-bundler-plugin.ts +116 -116
- package/src/build/integration-config.ts +168 -168
- package/src/build/integration-detection-plugin.ts +117 -117
- package/src/build/integration-resolver-plugin.ts +90 -90
- package/src/build/island-manifest.ts +269 -269
- package/src/build/island-types-generator.ts +476 -476
- package/src/build/mdx-island-transform.ts +464 -464
- package/src/build/mdx-plugin.ts +98 -98
- package/src/build/page-island-transform.ts +598 -598
- package/src/build/prop-extractors/index.ts +21 -21
- package/src/build/prop-extractors/lit.ts +140 -140
- package/src/build/prop-extractors/qwik.ts +16 -16
- package/src/build/prop-extractors/solid.ts +125 -125
- package/src/build/prop-extractors/svelte.ts +194 -194
- package/src/build/prop-extractors/vue.ts +111 -111
- package/src/build/sidecar-file-manager.ts +104 -104
- package/src/build/sidecar-renderer.ts +30 -30
- package/src/client/adapters/index.ts +21 -13
- package/src/client/components.ts +35 -35
- package/src/client/css-hmr-handler.ts +344 -344
- package/src/client/framework-adapter.ts +462 -462
- package/src/client/hmr-coordinator.ts +396 -396
- package/src/client/hmr-error-overlay.js +533 -533
- package/src/client/main.js +824 -816
- package/src/client/types/framework-runtime.d.ts +68 -68
- package/src/client/types/vite-hmr.d.ts +46 -46
- package/src/client/types/vite-virtual-modules.d.ts +70 -60
- package/src/components/Image.tsx +123 -123
- package/src/components/IslandErrorBoundary.tsx +145 -145
- package/src/components/LayoutDataErrorBoundary.tsx +141 -141
- package/src/components/LayoutErrorBoundary.tsx +127 -127
- package/src/components/PersistentIsland.tsx +52 -52
- package/src/components/StreamingErrorBoundary.tsx +233 -233
- package/src/components/StreamingLayout.tsx +538 -538
- package/src/core/components/component-analyzer.ts +192 -192
- package/src/core/components/component-detection.ts +508 -508
- package/src/core/components/enhanced-framework-detector.ts +500 -500
- package/src/core/components/framework-registry.ts +563 -563
- package/src/core/content/mdx-processor.ts +46 -46
- package/src/core/integrations/index.ts +19 -19
- package/src/core/integrations/loader.ts +125 -125
- package/src/core/integrations/registry.ts +175 -175
- package/src/core/islands/island-persistence.ts +325 -325
- package/src/core/islands/island-state-serializer.ts +258 -258
- package/src/core/islands/persistent-island-context.tsx +80 -80
- package/src/core/islands/use-persistent-state.ts +68 -68
- package/src/core/layout/enhanced-layout-resolver.ts +322 -322
- package/src/core/layout/layout-cache-manager.ts +485 -485
- package/src/core/layout/layout-composer.ts +357 -357
- package/src/core/layout/layout-data-loader.ts +516 -516
- package/src/core/layout/layout-discovery.ts +243 -243
- package/src/core/layout/layout-matcher.ts +299 -299
- package/src/core/layout/layout-types.ts +110 -110
- package/src/core/modules/framework-module-resolver.ts +273 -273
- package/src/islands/component-analysis.ts +213 -213
- package/src/islands/css-utils.ts +565 -565
- package/src/islands/discovery/index.ts +80 -80
- package/src/islands/discovery/registry.ts +340 -340
- package/src/islands/discovery/resolver.ts +477 -477
- package/src/islands/discovery/scanner.ts +386 -386
- package/src/islands/discovery/types.ts +117 -117
- package/src/islands/discovery/validator.ts +544 -544
- package/src/islands/discovery/watcher.ts +368 -368
- package/src/islands/framework-detection.ts +428 -428
- package/src/islands/integration-loader.ts +490 -490
- package/src/islands/island.tsx +565 -565
- package/src/islands/render-cache.ts +550 -550
- package/src/islands/types.ts +80 -80
- package/src/islands/universal-css-collector.ts +157 -157
- package/src/islands/universal-head-collector.ts +137 -137
- package/src/layout-system.d.ts +592 -592
- package/src/layout-system.ts +218 -218
- package/src/middleware/discovery.ts +268 -268
- package/src/middleware/executor.ts +315 -315
- package/src/middleware/index.ts +76 -76
- package/src/middleware/types.ts +99 -99
- package/src/nitro/build-config.ts +575 -575
- package/src/nitro/config.ts +483 -483
- package/src/nitro/error-handler.ts +636 -636
- package/src/nitro/index.ts +173 -173
- package/src/nitro/island-manifest.ts +584 -584
- package/src/nitro/middleware-adapter.ts +260 -260
- package/src/nitro/renderer.ts +1471 -1471
- package/src/nitro/route-discovery.ts +439 -439
- package/src/nitro/types.ts +321 -321
- package/src/render/collect-css.ts +198 -198
- package/src/render/error-pages.ts +79 -79
- package/src/render/isolated-ssr-renderer.ts +654 -654
- package/src/render/ssr.ts +1030 -1030
- package/src/schemas/api.ts +30 -30
- package/src/schemas/core.ts +64 -64
- package/src/schemas/index.ts +212 -212
- package/src/schemas/layout.ts +279 -279
- package/src/schemas/routing/index.ts +38 -38
- package/src/schemas/routing.ts +376 -376
- package/src/types/as-island.ts +20 -20
- package/src/types/image.d.ts +106 -106
- package/src/types/index.d.ts +22 -22
- package/src/types/island-jsx.d.ts +33 -33
- package/src/types/island-prop.d.ts +20 -20
- package/src/types/layout.ts +285 -285
- package/src/types/mdx.d.ts +6 -6
- package/src/types/routing.ts +555 -555
- package/src/types/types.ts +5 -5
- package/src/types/urlpattern.d.ts +49 -49
- package/src/types/vite-env.d.ts +11 -11
- package/src/utils/dev-logger.ts +299 -299
- package/src/utils/fs.ts +151 -151
- package/src/vite-plugin/auto-discover.ts +551 -551
- package/src/vite-plugin/config.ts +266 -266
- package/src/vite-plugin/errors.ts +127 -127
- package/src/vite-plugin/image-optimization.ts +156 -156
- package/src/vite-plugin/integration-activator.ts +126 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +176 -176
- package/src/vite-plugin/module-discovery.ts +189 -189
- package/src/vite-plugin/nitro-integration.ts +1354 -1354
- package/src/vite-plugin/plugin.ts +403 -409
- package/src/vite-plugin/types.ts +327 -327
- package/src/vite-plugin/validation.ts +228 -228
- package/src/client/adapters/index.js +0 -12
- package/src/client/adapters/lit-adapter.js +0 -467
- package/src/client/adapters/lit-adapter.ts +0 -654
- package/src/client/adapters/preact-adapter.js +0 -223
- package/src/client/adapters/preact-adapter.ts +0 -331
- package/src/client/adapters/qwik-adapter.js +0 -259
- package/src/client/adapters/qwik-adapter.ts +0 -345
- package/src/client/adapters/react-adapter.js +0 -220
- package/src/client/adapters/react-adapter.ts +0 -353
- package/src/client/adapters/solid-adapter.js +0 -295
- package/src/client/adapters/solid-adapter.ts +0 -451
- package/src/client/adapters/svelte-adapter.js +0 -368
- package/src/client/adapters/svelte-adapter.ts +0 -524
- package/src/client/adapters/vue-adapter.js +0 -278
- package/src/client/adapters/vue-adapter.ts +0 -467
- package/src/client/components.js +0 -23
- package/src/client/css-hmr-handler.js +0 -263
- package/src/client/framework-adapter.js +0 -283
- package/src/client/hmr-coordinator.js +0 -274
|
@@ -1,273 +1,273 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Framework-aware module resolver for handling framework-specific path transformations
|
|
3
|
-
* and MIME type resolution during hydration and module serving.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface ModuleResolutionConfig {
|
|
7
|
-
framework: string;
|
|
8
|
-
baseUrl: string;
|
|
9
|
-
extensions: string[];
|
|
10
|
-
transformPath: (path: string) => string;
|
|
11
|
-
mimeType: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ResolvedModule {
|
|
15
|
-
originalPath: string;
|
|
16
|
-
resolvedPath: string;
|
|
17
|
-
framework: string;
|
|
18
|
-
shouldTransform: boolean;
|
|
19
|
-
mimeType: string;
|
|
20
|
-
url: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface FrameworkModuleConfig {
|
|
24
|
-
extensions: string[];
|
|
25
|
-
hydrationExtension: string;
|
|
26
|
-
mimeType: string;
|
|
27
|
-
transformPath: (path: string, mode: 'development' | 'production') => string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Framework-specific module configurations
|
|
32
|
-
*/
|
|
33
|
-
const FRAMEWORK_MODULE_CONFIGS: Record<string, FrameworkModuleConfig> = {
|
|
34
|
-
solid: {
|
|
35
|
-
extensions: ['.tsx', '.jsx'],
|
|
36
|
-
hydrationExtension: '.js',
|
|
37
|
-
mimeType: 'application/javascript',
|
|
38
|
-
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
39
|
-
// For Solid, transform .tsx to .js for hydration
|
|
40
|
-
if (path.endsWith('.tsx')) {
|
|
41
|
-
return path.replace(/\.tsx$/, '.js');
|
|
42
|
-
}
|
|
43
|
-
if (path.endsWith('.jsx')) {
|
|
44
|
-
return path.replace(/\.jsx$/, '.js');
|
|
45
|
-
}
|
|
46
|
-
return path;
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
preact: {
|
|
50
|
-
extensions: ['.tsx', '.jsx'],
|
|
51
|
-
hydrationExtension: '.js',
|
|
52
|
-
mimeType: 'application/javascript',
|
|
53
|
-
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
54
|
-
// For Preact, transform .tsx/.jsx to .js for hydration
|
|
55
|
-
if (path.endsWith('.tsx')) {
|
|
56
|
-
return path.replace(/\.tsx$/, '.js');
|
|
57
|
-
}
|
|
58
|
-
if (path.endsWith('.jsx')) {
|
|
59
|
-
return path.replace(/\.jsx$/, '.js');
|
|
60
|
-
}
|
|
61
|
-
return path;
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
vue: {
|
|
65
|
-
extensions: ['.vue'],
|
|
66
|
-
hydrationExtension: '.js',
|
|
67
|
-
mimeType: 'application/javascript',
|
|
68
|
-
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
69
|
-
// Vue components are typically compiled to .js
|
|
70
|
-
if (path.endsWith('.vue')) {
|
|
71
|
-
return path.replace(/\.vue$/, '.js');
|
|
72
|
-
}
|
|
73
|
-
return path;
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
svelte: {
|
|
77
|
-
extensions: ['.svelte'],
|
|
78
|
-
hydrationExtension: '.js',
|
|
79
|
-
mimeType: 'application/javascript',
|
|
80
|
-
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
81
|
-
// Svelte components are compiled to .js
|
|
82
|
-
if (path.endsWith('.svelte')) {
|
|
83
|
-
return path.replace(/\.svelte$/, '.js');
|
|
84
|
-
}
|
|
85
|
-
return path;
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
qwik: {
|
|
89
|
-
extensions: ['.tsx', '.jsx'],
|
|
90
|
-
hydrationExtension: '.js',
|
|
91
|
-
mimeType: 'application/javascript',
|
|
92
|
-
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
93
|
-
// Qwik components are compiled to .js via the Qwik optimizer
|
|
94
|
-
if (path.endsWith('.tsx')) {
|
|
95
|
-
return path.replace(/\.tsx$/, '.js');
|
|
96
|
-
}
|
|
97
|
-
if (path.endsWith('.jsx')) {
|
|
98
|
-
return path.replace(/\.jsx$/, '.js');
|
|
99
|
-
}
|
|
100
|
-
return path;
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
export class FrameworkModuleResolver {
|
|
106
|
-
private mode: 'development' | 'production';
|
|
107
|
-
private baseUrl: string;
|
|
108
|
-
|
|
109
|
-
constructor(mode: 'development' | 'production' = 'development', baseUrl = '') {
|
|
110
|
-
this.mode = mode;
|
|
111
|
-
this.baseUrl = baseUrl;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Resolve a module path for a specific framework
|
|
116
|
-
*/
|
|
117
|
-
resolveModule(
|
|
118
|
-
originalPath: string,
|
|
119
|
-
framework: string,
|
|
120
|
-
options: {
|
|
121
|
-
forHydration?: boolean;
|
|
122
|
-
baseUrl?: string;
|
|
123
|
-
} = {}
|
|
124
|
-
): ResolvedModule {
|
|
125
|
-
const config = FRAMEWORK_MODULE_CONFIGS[framework];
|
|
126
|
-
if (!config) {
|
|
127
|
-
throw new Error(`Unknown framework: ${framework}`);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const { forHydration = false, baseUrl = this.baseUrl } = options;
|
|
131
|
-
|
|
132
|
-
let resolvedPath = originalPath;
|
|
133
|
-
let shouldTransform = false;
|
|
134
|
-
let mimeType = this.getMimeType(originalPath);
|
|
135
|
-
|
|
136
|
-
// Apply framework-specific path transformation for hydration
|
|
137
|
-
if (forHydration) {
|
|
138
|
-
const transformedPath = config.transformPath(originalPath, this.mode);
|
|
139
|
-
if (transformedPath !== originalPath) {
|
|
140
|
-
resolvedPath = transformedPath;
|
|
141
|
-
shouldTransform = true;
|
|
142
|
-
mimeType = config.mimeType;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Generate the full URL
|
|
147
|
-
const url = this.generateModuleUrl(resolvedPath, baseUrl);
|
|
148
|
-
|
|
149
|
-
return {
|
|
150
|
-
originalPath,
|
|
151
|
-
resolvedPath,
|
|
152
|
-
framework,
|
|
153
|
-
shouldTransform,
|
|
154
|
-
mimeType,
|
|
155
|
-
url,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Check if a path needs transformation for the given framework
|
|
161
|
-
*/
|
|
162
|
-
needsTransformation(path: string, framework: string): boolean {
|
|
163
|
-
const config = FRAMEWORK_MODULE_CONFIGS[framework];
|
|
164
|
-
if (!config) {
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const transformedPath = config.transformPath(path, this.mode);
|
|
169
|
-
return transformedPath !== path;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Get the appropriate MIME type for a file path
|
|
174
|
-
*/
|
|
175
|
-
getMimeType(path: string): string {
|
|
176
|
-
const ext = this.getFileExtension(path);
|
|
177
|
-
|
|
178
|
-
switch (ext) {
|
|
179
|
-
case '.js':
|
|
180
|
-
case '.mjs':
|
|
181
|
-
return 'application/javascript';
|
|
182
|
-
case '.ts':
|
|
183
|
-
case '.tsx':
|
|
184
|
-
case '.jsx':
|
|
185
|
-
return 'application/javascript'; // These are typically compiled to JS
|
|
186
|
-
case '.css':
|
|
187
|
-
return 'text/css';
|
|
188
|
-
case '.json':
|
|
189
|
-
return 'application/json';
|
|
190
|
-
case '.vue':
|
|
191
|
-
case '.svelte':
|
|
192
|
-
return 'application/javascript'; // Compiled components
|
|
193
|
-
default:
|
|
194
|
-
return 'text/plain';
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Generate a module URL for the given path
|
|
200
|
-
*/
|
|
201
|
-
generateModuleUrl(path: string, baseUrl = this.baseUrl): string {
|
|
202
|
-
// Ensure path starts with /
|
|
203
|
-
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
204
|
-
|
|
205
|
-
if (baseUrl) {
|
|
206
|
-
return `${baseUrl.replace(/\/$/, '')}${normalizedPath}`;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return normalizedPath;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Get supported frameworks
|
|
214
|
-
*/
|
|
215
|
-
getSupportedFrameworks(): string[] {
|
|
216
|
-
return Object.keys(FRAMEWORK_MODULE_CONFIGS);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Get framework configuration
|
|
221
|
-
*/
|
|
222
|
-
getFrameworkConfig(framework: string): FrameworkModuleConfig | undefined {
|
|
223
|
-
return FRAMEWORK_MODULE_CONFIGS[framework];
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Check if a framework is supported
|
|
228
|
-
*/
|
|
229
|
-
isFrameworkSupported(framework: string): boolean {
|
|
230
|
-
return framework in FRAMEWORK_MODULE_CONFIGS;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Get file extension from path
|
|
235
|
-
*/
|
|
236
|
-
private getFileExtension(path: string): string {
|
|
237
|
-
const lastDot = path.lastIndexOf('.');
|
|
238
|
-
return lastDot === -1 ? '' : path.substring(lastDot);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Set the resolver mode (development/production)
|
|
243
|
-
*/
|
|
244
|
-
setMode(mode: 'development' | 'production'): void {
|
|
245
|
-
this.mode = mode;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Get current mode
|
|
250
|
-
*/
|
|
251
|
-
getMode(): 'development' | 'production' {
|
|
252
|
-
return this.mode;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Set base URL for module resolution
|
|
257
|
-
*/
|
|
258
|
-
setBaseUrl(baseUrl: string): void {
|
|
259
|
-
this.baseUrl = baseUrl;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Get current base URL
|
|
264
|
-
*/
|
|
265
|
-
getBaseUrl(): string {
|
|
266
|
-
return this.baseUrl;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Default instance for common usage
|
|
272
|
-
*/
|
|
273
|
-
export const frameworkModuleResolver = new FrameworkModuleResolver();
|
|
1
|
+
/**
|
|
2
|
+
* Framework-aware module resolver for handling framework-specific path transformations
|
|
3
|
+
* and MIME type resolution during hydration and module serving.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface ModuleResolutionConfig {
|
|
7
|
+
framework: string;
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
extensions: string[];
|
|
10
|
+
transformPath: (path: string) => string;
|
|
11
|
+
mimeType: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ResolvedModule {
|
|
15
|
+
originalPath: string;
|
|
16
|
+
resolvedPath: string;
|
|
17
|
+
framework: string;
|
|
18
|
+
shouldTransform: boolean;
|
|
19
|
+
mimeType: string;
|
|
20
|
+
url: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface FrameworkModuleConfig {
|
|
24
|
+
extensions: string[];
|
|
25
|
+
hydrationExtension: string;
|
|
26
|
+
mimeType: string;
|
|
27
|
+
transformPath: (path: string, mode: 'development' | 'production') => string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Framework-specific module configurations
|
|
32
|
+
*/
|
|
33
|
+
const FRAMEWORK_MODULE_CONFIGS: Record<string, FrameworkModuleConfig> = {
|
|
34
|
+
solid: {
|
|
35
|
+
extensions: ['.tsx', '.jsx'],
|
|
36
|
+
hydrationExtension: '.js',
|
|
37
|
+
mimeType: 'application/javascript',
|
|
38
|
+
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
39
|
+
// For Solid, transform .tsx to .js for hydration
|
|
40
|
+
if (path.endsWith('.tsx')) {
|
|
41
|
+
return path.replace(/\.tsx$/, '.js');
|
|
42
|
+
}
|
|
43
|
+
if (path.endsWith('.jsx')) {
|
|
44
|
+
return path.replace(/\.jsx$/, '.js');
|
|
45
|
+
}
|
|
46
|
+
return path;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
preact: {
|
|
50
|
+
extensions: ['.tsx', '.jsx'],
|
|
51
|
+
hydrationExtension: '.js',
|
|
52
|
+
mimeType: 'application/javascript',
|
|
53
|
+
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
54
|
+
// For Preact, transform .tsx/.jsx to .js for hydration
|
|
55
|
+
if (path.endsWith('.tsx')) {
|
|
56
|
+
return path.replace(/\.tsx$/, '.js');
|
|
57
|
+
}
|
|
58
|
+
if (path.endsWith('.jsx')) {
|
|
59
|
+
return path.replace(/\.jsx$/, '.js');
|
|
60
|
+
}
|
|
61
|
+
return path;
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
vue: {
|
|
65
|
+
extensions: ['.vue'],
|
|
66
|
+
hydrationExtension: '.js',
|
|
67
|
+
mimeType: 'application/javascript',
|
|
68
|
+
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
69
|
+
// Vue components are typically compiled to .js
|
|
70
|
+
if (path.endsWith('.vue')) {
|
|
71
|
+
return path.replace(/\.vue$/, '.js');
|
|
72
|
+
}
|
|
73
|
+
return path;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
svelte: {
|
|
77
|
+
extensions: ['.svelte'],
|
|
78
|
+
hydrationExtension: '.js',
|
|
79
|
+
mimeType: 'application/javascript',
|
|
80
|
+
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
81
|
+
// Svelte components are compiled to .js
|
|
82
|
+
if (path.endsWith('.svelte')) {
|
|
83
|
+
return path.replace(/\.svelte$/, '.js');
|
|
84
|
+
}
|
|
85
|
+
return path;
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
qwik: {
|
|
89
|
+
extensions: ['.tsx', '.jsx'],
|
|
90
|
+
hydrationExtension: '.js',
|
|
91
|
+
mimeType: 'application/javascript',
|
|
92
|
+
transformPath: (path: string, mode: 'development' | 'production') => {
|
|
93
|
+
// Qwik components are compiled to .js via the Qwik optimizer
|
|
94
|
+
if (path.endsWith('.tsx')) {
|
|
95
|
+
return path.replace(/\.tsx$/, '.js');
|
|
96
|
+
}
|
|
97
|
+
if (path.endsWith('.jsx')) {
|
|
98
|
+
return path.replace(/\.jsx$/, '.js');
|
|
99
|
+
}
|
|
100
|
+
return path;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export class FrameworkModuleResolver {
|
|
106
|
+
private mode: 'development' | 'production';
|
|
107
|
+
private baseUrl: string;
|
|
108
|
+
|
|
109
|
+
constructor(mode: 'development' | 'production' = 'development', baseUrl = '') {
|
|
110
|
+
this.mode = mode;
|
|
111
|
+
this.baseUrl = baseUrl;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Resolve a module path for a specific framework
|
|
116
|
+
*/
|
|
117
|
+
resolveModule(
|
|
118
|
+
originalPath: string,
|
|
119
|
+
framework: string,
|
|
120
|
+
options: {
|
|
121
|
+
forHydration?: boolean;
|
|
122
|
+
baseUrl?: string;
|
|
123
|
+
} = {}
|
|
124
|
+
): ResolvedModule {
|
|
125
|
+
const config = FRAMEWORK_MODULE_CONFIGS[framework];
|
|
126
|
+
if (!config) {
|
|
127
|
+
throw new Error(`Unknown framework: ${framework}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const { forHydration = false, baseUrl = this.baseUrl } = options;
|
|
131
|
+
|
|
132
|
+
let resolvedPath = originalPath;
|
|
133
|
+
let shouldTransform = false;
|
|
134
|
+
let mimeType = this.getMimeType(originalPath);
|
|
135
|
+
|
|
136
|
+
// Apply framework-specific path transformation for hydration
|
|
137
|
+
if (forHydration) {
|
|
138
|
+
const transformedPath = config.transformPath(originalPath, this.mode);
|
|
139
|
+
if (transformedPath !== originalPath) {
|
|
140
|
+
resolvedPath = transformedPath;
|
|
141
|
+
shouldTransform = true;
|
|
142
|
+
mimeType = config.mimeType;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Generate the full URL
|
|
147
|
+
const url = this.generateModuleUrl(resolvedPath, baseUrl);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
originalPath,
|
|
151
|
+
resolvedPath,
|
|
152
|
+
framework,
|
|
153
|
+
shouldTransform,
|
|
154
|
+
mimeType,
|
|
155
|
+
url,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Check if a path needs transformation for the given framework
|
|
161
|
+
*/
|
|
162
|
+
needsTransformation(path: string, framework: string): boolean {
|
|
163
|
+
const config = FRAMEWORK_MODULE_CONFIGS[framework];
|
|
164
|
+
if (!config) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const transformedPath = config.transformPath(path, this.mode);
|
|
169
|
+
return transformedPath !== path;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get the appropriate MIME type for a file path
|
|
174
|
+
*/
|
|
175
|
+
getMimeType(path: string): string {
|
|
176
|
+
const ext = this.getFileExtension(path);
|
|
177
|
+
|
|
178
|
+
switch (ext) {
|
|
179
|
+
case '.js':
|
|
180
|
+
case '.mjs':
|
|
181
|
+
return 'application/javascript';
|
|
182
|
+
case '.ts':
|
|
183
|
+
case '.tsx':
|
|
184
|
+
case '.jsx':
|
|
185
|
+
return 'application/javascript'; // These are typically compiled to JS
|
|
186
|
+
case '.css':
|
|
187
|
+
return 'text/css';
|
|
188
|
+
case '.json':
|
|
189
|
+
return 'application/json';
|
|
190
|
+
case '.vue':
|
|
191
|
+
case '.svelte':
|
|
192
|
+
return 'application/javascript'; // Compiled components
|
|
193
|
+
default:
|
|
194
|
+
return 'text/plain';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Generate a module URL for the given path
|
|
200
|
+
*/
|
|
201
|
+
generateModuleUrl(path: string, baseUrl = this.baseUrl): string {
|
|
202
|
+
// Ensure path starts with /
|
|
203
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
204
|
+
|
|
205
|
+
if (baseUrl) {
|
|
206
|
+
return `${baseUrl.replace(/\/$/, '')}${normalizedPath}`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return normalizedPath;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get supported frameworks
|
|
214
|
+
*/
|
|
215
|
+
getSupportedFrameworks(): string[] {
|
|
216
|
+
return Object.keys(FRAMEWORK_MODULE_CONFIGS);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get framework configuration
|
|
221
|
+
*/
|
|
222
|
+
getFrameworkConfig(framework: string): FrameworkModuleConfig | undefined {
|
|
223
|
+
return FRAMEWORK_MODULE_CONFIGS[framework];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Check if a framework is supported
|
|
228
|
+
*/
|
|
229
|
+
isFrameworkSupported(framework: string): boolean {
|
|
230
|
+
return framework in FRAMEWORK_MODULE_CONFIGS;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get file extension from path
|
|
235
|
+
*/
|
|
236
|
+
private getFileExtension(path: string): string {
|
|
237
|
+
const lastDot = path.lastIndexOf('.');
|
|
238
|
+
return lastDot === -1 ? '' : path.substring(lastDot);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Set the resolver mode (development/production)
|
|
243
|
+
*/
|
|
244
|
+
setMode(mode: 'development' | 'production'): void {
|
|
245
|
+
this.mode = mode;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Get current mode
|
|
250
|
+
*/
|
|
251
|
+
getMode(): 'development' | 'production' {
|
|
252
|
+
return this.mode;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Set base URL for module resolution
|
|
257
|
+
*/
|
|
258
|
+
setBaseUrl(baseUrl: string): void {
|
|
259
|
+
this.baseUrl = baseUrl;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get current base URL
|
|
264
|
+
*/
|
|
265
|
+
getBaseUrl(): string {
|
|
266
|
+
return this.baseUrl;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Default instance for common usage
|
|
272
|
+
*/
|
|
273
|
+
export const frameworkModuleResolver = new FrameworkModuleResolver();
|