phial 0.0.1
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/LICENSE +21 -0
- package/README.md +27 -0
- package/bin/phial.mjs +6 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/lib/cli/index.d.ts +5 -0
- package/dist/lib/cli/index.d.ts.map +1 -0
- package/dist/lib/cli/index.js +101 -0
- package/dist/lib/cli/index.js.map +1 -0
- package/dist/lib/generated-routes.d.ts +176 -0
- package/dist/lib/server-routes/errors.js +16 -0
- package/dist/lib/server-routes/errors.js.map +1 -0
- package/dist/lib/vite-plugin/config.d.ts +54 -0
- package/dist/lib/vite-plugin/config.d.ts.map +1 -0
- package/dist/lib/vite-plugin/config.js +54 -0
- package/dist/lib/vite-plugin/config.js.map +1 -0
- package/dist/lib/vite-plugin/generated/client-entry.js +36 -0
- package/dist/lib/vite-plugin/generated/client-entry.js.map +1 -0
- package/dist/lib/vite-plugin/generated/virtual-modules.js +940 -0
- package/dist/lib/vite-plugin/generated/virtual-modules.js.map +1 -0
- package/dist/lib/vite-plugin/host/index.d.ts +4 -0
- package/dist/lib/vite-plugin/host/index.js +5 -0
- package/dist/lib/vite-plugin/host/plugin-build.d.ts +15 -0
- package/dist/lib/vite-plugin/host/plugin-build.d.ts.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-build.js +242 -0
- package/dist/lib/vite-plugin/host/plugin-build.js.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-dev-server.d.ts +19 -0
- package/dist/lib/vite-plugin/host/plugin-dev-server.d.ts.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-dev-server.js +255 -0
- package/dist/lib/vite-plugin/host/plugin-dev-server.js.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-prepare.d.ts +12 -0
- package/dist/lib/vite-plugin/host/plugin-prepare.d.ts.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-prepare.js +29 -0
- package/dist/lib/vite-plugin/host/plugin-prepare.js.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-server.d.ts +19 -0
- package/dist/lib/vite-plugin/host/plugin-server.d.ts.map +1 -0
- package/dist/lib/vite-plugin/host/plugin-server.js +60 -0
- package/dist/lib/vite-plugin/host/plugin-server.js.map +1 -0
- package/dist/lib/vite-plugin/index.d.ts +9 -0
- package/dist/lib/vite-plugin/index.d.ts.map +1 -0
- package/dist/lib/vite-plugin/index.js +261 -0
- package/dist/lib/vite-plugin/index.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/app-pages-scanner.js +162 -0
- package/dist/lib/vite-plugin/scanners/app-pages-scanner.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/app-runtime-scanner.js +39 -0
- package/dist/lib/vite-plugin/scanners/app-runtime-scanner.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/route-manifest.js +60 -0
- package/dist/lib/vite-plugin/scanners/route-manifest.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/routes-scanner.js +72 -0
- package/dist/lib/vite-plugin/scanners/routes-scanner.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/scanner-utils.js +129 -0
- package/dist/lib/vite-plugin/scanners/scanner-utils.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/server-routes-scanner.js +83 -0
- package/dist/lib/vite-plugin/scanners/server-routes-scanner.js.map +1 -0
- package/dist/lib/vite-plugin/scanners/types-generator.d.ts +9 -0
- package/dist/lib/vite-plugin/scanners/types-generator.d.ts.map +1 -0
- package/dist/lib/vite-plugin/scanners/types-generator.js +190 -0
- package/dist/lib/vite-plugin/scanners/types-generator.js.map +1 -0
- package/dist/vite-plugin.d.ts +7 -0
- package/dist/vite-plugin.js +8 -0
- package/package.json +89 -0
|
@@ -0,0 +1,940 @@
|
|
|
1
|
+
//#region src/lib/vite-plugin/generated/virtual-modules.ts
|
|
2
|
+
const VIRTUAL_ROUTES_MANIFEST_ID = "virtual:phial-routes-manifest";
|
|
3
|
+
const VIRTUAL_ROUTES_MODULES_ID = "virtual:phial-routes-modules";
|
|
4
|
+
const VIRTUAL_APP_RUNTIME_ID = "virtual:phial-app-runtime";
|
|
5
|
+
const GENERATED_ROUTES_MANIFEST_ID = "phial/generated-routes-manifest";
|
|
6
|
+
const GENERATED_ROUTES_MODULES_ID = "phial/generated-routes-modules";
|
|
7
|
+
const GENERATED_APP_RUNTIME_ID = "phial/generated-app-runtime";
|
|
8
|
+
const GENERATED_APP_LOADER_ID = "phial/generated-app-loader";
|
|
9
|
+
const GENERATED_APP_MIDDLEWARE_ID = "phial/generated-app-middleware";
|
|
10
|
+
const GENERATED_APP_PLUGIN_ID = "phial/generated-app-plugin";
|
|
11
|
+
const GENERATED_SERVER_ROUTES_ID = "phial/generated-server-routes";
|
|
12
|
+
const GENERATED_SERVER_MIDDLEWARE_ID = "phial/generated-server-middleware";
|
|
13
|
+
const GENERATED_SERVER_PLUGIN_ID = "phial/generated-server-plugin";
|
|
14
|
+
const GENERATED_CONFIG_ID = "phial/generated-config";
|
|
15
|
+
const RESOLVED_VIRTUAL_ROUTES_MANIFEST_ID = `\0${VIRTUAL_ROUTES_MANIFEST_ID}`;
|
|
16
|
+
const RESOLVED_VIRTUAL_ROUTES_MODULES_ID = `\0${VIRTUAL_ROUTES_MODULES_ID}`;
|
|
17
|
+
const RESOLVED_VIRTUAL_APP_RUNTIME_ID = `\0${VIRTUAL_APP_RUNTIME_ID}`;
|
|
18
|
+
const RESOLVED_GENERATED_ROUTES_MANIFEST_ID = `\0${GENERATED_ROUTES_MANIFEST_ID}`;
|
|
19
|
+
const RESOLVED_GENERATED_ROUTES_MODULES_ID = `\0${GENERATED_ROUTES_MODULES_ID}`;
|
|
20
|
+
const RESOLVED_GENERATED_APP_RUNTIME_ID = `\0${GENERATED_APP_RUNTIME_ID}`;
|
|
21
|
+
const RESOLVED_GENERATED_APP_LOADER_ID = `\0${GENERATED_APP_LOADER_ID}`;
|
|
22
|
+
const RESOLVED_GENERATED_APP_MIDDLEWARE_ID = `\0${GENERATED_APP_MIDDLEWARE_ID}`;
|
|
23
|
+
const RESOLVED_GENERATED_APP_PLUGIN_ID = `\0${GENERATED_APP_PLUGIN_ID}`;
|
|
24
|
+
const RESOLVED_GENERATED_SERVER_ROUTES_ID = `\0${GENERATED_SERVER_ROUTES_ID}`;
|
|
25
|
+
const RESOLVED_GENERATED_SERVER_MIDDLEWARE_ID = `\0${GENERATED_SERVER_MIDDLEWARE_ID}`;
|
|
26
|
+
const RESOLVED_GENERATED_SERVER_PLUGIN_ID = `\0${GENERATED_SERVER_PLUGIN_ID}`;
|
|
27
|
+
const RESOLVED_GENERATED_CONFIG_ID = `\0${GENERATED_CONFIG_ID}`;
|
|
28
|
+
function createVirtualRoutesManifestModule(result) {
|
|
29
|
+
return [
|
|
30
|
+
`export const manifest = ${JSON.stringify(result.manifest, null, 2)}`,
|
|
31
|
+
"",
|
|
32
|
+
"export default manifest"
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
35
|
+
function createVirtualRoutesModulesModule(result, options = {}) {
|
|
36
|
+
return options.moduleImportMode === "eager" ? createEagerRouteModulesModule(result) : createDynamicRouteModulesModule(result);
|
|
37
|
+
}
|
|
38
|
+
function createVirtualAppRuntimeModule(result) {
|
|
39
|
+
const importEntries = [
|
|
40
|
+
result.app.app ? {
|
|
41
|
+
importedLocal: "importedAppComponentModule",
|
|
42
|
+
local: "appComponentModule",
|
|
43
|
+
exportName: "appComponent",
|
|
44
|
+
specifier: createImportSpecifier(result.app.app)
|
|
45
|
+
} : null,
|
|
46
|
+
result.app.error ? {
|
|
47
|
+
importedLocal: "importedErrorComponentModule",
|
|
48
|
+
local: "errorComponentModule",
|
|
49
|
+
exportName: "errorComponent",
|
|
50
|
+
specifier: createImportSpecifier(result.app.error)
|
|
51
|
+
} : null,
|
|
52
|
+
result.app.loader ? {
|
|
53
|
+
importedLocal: "importedAppLoaderModule",
|
|
54
|
+
local: "appLoaderModule",
|
|
55
|
+
exportName: "appLoader",
|
|
56
|
+
specifier: createImportSpecifier(result.app.loader)
|
|
57
|
+
} : null,
|
|
58
|
+
result.app.config ? {
|
|
59
|
+
importedLocal: "importedAppConfigModule",
|
|
60
|
+
local: "appConfigModule",
|
|
61
|
+
exportName: "appConfig",
|
|
62
|
+
specifier: createImportSpecifier(result.app.config)
|
|
63
|
+
} : null
|
|
64
|
+
].filter(Boolean);
|
|
65
|
+
const importLines = importEntries.map(({ importedLocal, specifier }) => `import * as ${importedLocal} from ${JSON.stringify(specifier)}`);
|
|
66
|
+
const mutableBindings = importEntries.map(({ importedLocal, local }) => `let ${local} = ${importedLocal}`);
|
|
67
|
+
const exportInitializers = [
|
|
68
|
+
"let appComponent = resolveAppComponent(typeof appComponentModule !== \"undefined\" ? appComponentModule : undefined)",
|
|
69
|
+
"let errorComponent = resolveErrorComponent(typeof errorComponentModule !== \"undefined\" ? errorComponentModule : undefined)",
|
|
70
|
+
"export let appLoader = resolveAppLoader(typeof appLoaderModule !== \"undefined\" ? appLoaderModule : undefined)",
|
|
71
|
+
"let appConfig = resolveAppConfig(typeof appConfigModule !== \"undefined\" ? appConfigModule : undefined)",
|
|
72
|
+
"export let app = createAppModule(appComponent, errorComponent, appLoader)",
|
|
73
|
+
"export let routes = createRouteRecords(manifest, routeModules)",
|
|
74
|
+
"export function createIntegration(runtimeOptions = {}) {",
|
|
75
|
+
" return createRouteRuntimeIntegration({",
|
|
76
|
+
" app,",
|
|
77
|
+
" routes,",
|
|
78
|
+
" ...runtimeOptions",
|
|
79
|
+
" })",
|
|
80
|
+
"}",
|
|
81
|
+
"export let integration = createIntegration()",
|
|
82
|
+
"installRouteModuleHmrBridge()"
|
|
83
|
+
];
|
|
84
|
+
return [
|
|
85
|
+
"import { createRouteRuntimeIntegration } from \"vuepagelet/integration\"",
|
|
86
|
+
`import { manifest } from ${JSON.stringify(GENERATED_ROUTES_MANIFEST_ID)}`,
|
|
87
|
+
`import { routeModules } from ${JSON.stringify(GENERATED_ROUTES_MODULES_ID)}`,
|
|
88
|
+
`import { appMiddlewareRegistry } from ${JSON.stringify(GENERATED_APP_MIDDLEWARE_ID)}`,
|
|
89
|
+
"",
|
|
90
|
+
...importLines,
|
|
91
|
+
...importLines.length > 0 ? [""] : [],
|
|
92
|
+
...mutableBindings,
|
|
93
|
+
...mutableBindings.length > 0 ? [""] : [],
|
|
94
|
+
...exportInitializers,
|
|
95
|
+
"",
|
|
96
|
+
"function resolveAppComponent(module) {",
|
|
97
|
+
" return module?.default",
|
|
98
|
+
"}",
|
|
99
|
+
"",
|
|
100
|
+
"function resolveErrorComponent(module) {",
|
|
101
|
+
" return module?.default",
|
|
102
|
+
"}",
|
|
103
|
+
"",
|
|
104
|
+
"function resolveAppLoader(module) {",
|
|
105
|
+
" const loader = module?.loader ?? module?.default",
|
|
106
|
+
" if (loader !== undefined && typeof loader !== \"function\") {",
|
|
107
|
+
" throw new Error(\"Invalid app loader module. Expected a default export or named \\\"loader\\\" export.\")",
|
|
108
|
+
" }",
|
|
109
|
+
"",
|
|
110
|
+
" return loader",
|
|
111
|
+
"}",
|
|
112
|
+
"",
|
|
113
|
+
"function resolveAppConfig(module) {",
|
|
114
|
+
" return module?.default ?? module?.appConfig ?? {}",
|
|
115
|
+
"}",
|
|
116
|
+
"",
|
|
117
|
+
"function createAppModule(shell, error, loader) {",
|
|
118
|
+
" return { shell, error, loader }",
|
|
119
|
+
"}",
|
|
120
|
+
"",
|
|
121
|
+
"function createRouteRecords(routeManifest, loadedRouteModules) {",
|
|
122
|
+
" const records = routeManifest.map((entry) => ({",
|
|
123
|
+
" id: entry.id,",
|
|
124
|
+
" path: entry.path,",
|
|
125
|
+
" module: createRouteModule(entry, loadedRouteModules[entry.id]),",
|
|
126
|
+
" children: []",
|
|
127
|
+
" }))",
|
|
128
|
+
" const recordMap = new Map(records.map((record) => [record.id, record]))",
|
|
129
|
+
" const roots = []",
|
|
130
|
+
"",
|
|
131
|
+
" for (const entry of routeManifest) {",
|
|
132
|
+
" const record = recordMap.get(entry.id)",
|
|
133
|
+
" if (!record) {",
|
|
134
|
+
" continue",
|
|
135
|
+
" }",
|
|
136
|
+
"",
|
|
137
|
+
" if (entry.parentId) {",
|
|
138
|
+
" const parent = recordMap.get(entry.parentId)",
|
|
139
|
+
" if (parent) {",
|
|
140
|
+
" parent.children.push(record)",
|
|
141
|
+
" continue",
|
|
142
|
+
" }",
|
|
143
|
+
" }",
|
|
144
|
+
"",
|
|
145
|
+
" roots.push(record)",
|
|
146
|
+
" }",
|
|
147
|
+
"",
|
|
148
|
+
" return attachAppMiddleware(roots, resolveGlobalMiddleware(appConfig, appMiddlewareRegistry))",
|
|
149
|
+
"}",
|
|
150
|
+
"",
|
|
151
|
+
"function installRouteModuleHmrBridge() {",
|
|
152
|
+
" if (typeof globalThis === \"undefined\") {",
|
|
153
|
+
" return",
|
|
154
|
+
" }",
|
|
155
|
+
"",
|
|
156
|
+
" globalThis.__ROUTE_MODULE_HMR__ = async () => {",
|
|
157
|
+
" const nextRoutes = createRouteRecords(manifest, routeModules)",
|
|
158
|
+
" syncRouteRecords(routes, nextRoutes)",
|
|
159
|
+
" integration = createIntegration()",
|
|
160
|
+
" await notifyAppRuntimeHotUpdate({",
|
|
161
|
+
" appComponent,",
|
|
162
|
+
" errorComponent,",
|
|
163
|
+
" config: appConfig,",
|
|
164
|
+
" routes,",
|
|
165
|
+
" })",
|
|
166
|
+
" }",
|
|
167
|
+
"}",
|
|
168
|
+
"",
|
|
169
|
+
"async function notifyAppRuntimeHotUpdate(payload) {",
|
|
170
|
+
" if (typeof globalThis === \"undefined\") {",
|
|
171
|
+
" return false",
|
|
172
|
+
" }",
|
|
173
|
+
"",
|
|
174
|
+
" const applyAppRuntimeHotUpdate = globalThis.__APP_RUNTIME_HMR__",
|
|
175
|
+
" if (typeof applyAppRuntimeHotUpdate !== \"function\") {",
|
|
176
|
+
" return false",
|
|
177
|
+
" }",
|
|
178
|
+
"",
|
|
179
|
+
" await applyAppRuntimeHotUpdate(payload)",
|
|
180
|
+
" return true",
|
|
181
|
+
"}",
|
|
182
|
+
"",
|
|
183
|
+
"function syncRouteRecords(targetRoutes, nextRoutes) {",
|
|
184
|
+
" const targetRouteMap = new Map(flattenRoutes(targetRoutes).map((route) => [route.id, route]))",
|
|
185
|
+
"",
|
|
186
|
+
" for (const nextRoute of flattenRoutes(nextRoutes)) {",
|
|
187
|
+
" const targetRoute = targetRouteMap.get(nextRoute.id)",
|
|
188
|
+
" if (!targetRoute) {",
|
|
189
|
+
" continue",
|
|
190
|
+
" }",
|
|
191
|
+
"",
|
|
192
|
+
" targetRoute.path = nextRoute.path",
|
|
193
|
+
" targetRoute.name = nextRoute.name",
|
|
194
|
+
" targetRoute.module = nextRoute.module",
|
|
195
|
+
" }",
|
|
196
|
+
"}",
|
|
197
|
+
"",
|
|
198
|
+
"function flattenRoutes(routes) {",
|
|
199
|
+
" return routes.flatMap((route) => [route, ...flattenRoutes(route.children ?? [])])",
|
|
200
|
+
"}",
|
|
201
|
+
"",
|
|
202
|
+
"function createRouteModule(entry, module) {",
|
|
203
|
+
" const resolvedModule = module ?? {}",
|
|
204
|
+
" const routeModule = entry.kind === \"layout\"",
|
|
205
|
+
" ? { layout: resolveDefaultExport(resolvedModule) }",
|
|
206
|
+
" : { component: resolveDefaultExport(resolvedModule) }",
|
|
207
|
+
" const middleware = resolveMiddlewareReferences([",
|
|
208
|
+
" ...(resolvedModule.directoryMiddleware ?? []),",
|
|
209
|
+
" ...(resolvedModule.middleware ?? []),",
|
|
210
|
+
" ], appMiddlewareRegistry)",
|
|
211
|
+
"",
|
|
212
|
+
" if (resolvedModule.Loading !== undefined) {",
|
|
213
|
+
" routeModule.loading = resolvedModule.Loading",
|
|
214
|
+
" }",
|
|
215
|
+
"",
|
|
216
|
+
" if (resolvedModule.ErrorBoundary !== undefined) {",
|
|
217
|
+
" routeModule.error = resolvedModule.ErrorBoundary",
|
|
218
|
+
" }",
|
|
219
|
+
"",
|
|
220
|
+
" if (resolvedModule.loader !== undefined) {",
|
|
221
|
+
" routeModule.loader = resolvedModule.loader",
|
|
222
|
+
" }",
|
|
223
|
+
"",
|
|
224
|
+
" if (resolvedModule.action !== undefined) {",
|
|
225
|
+
" routeModule.action = resolvedModule.action",
|
|
226
|
+
" }",
|
|
227
|
+
"",
|
|
228
|
+
" if (middleware.length > 0) {",
|
|
229
|
+
" routeModule.middleware = middleware",
|
|
230
|
+
" }",
|
|
231
|
+
"",
|
|
232
|
+
" if (resolvedModule.shouldRevalidate !== undefined) {",
|
|
233
|
+
" routeModule.shouldRevalidate = resolvedModule.shouldRevalidate",
|
|
234
|
+
" }",
|
|
235
|
+
"",
|
|
236
|
+
" return routeModule",
|
|
237
|
+
"}",
|
|
238
|
+
"",
|
|
239
|
+
"function resolveDefaultExport(module) {",
|
|
240
|
+
" return module?.default",
|
|
241
|
+
"}",
|
|
242
|
+
"",
|
|
243
|
+
"function resolveGlobalMiddleware(config, registry) {",
|
|
244
|
+
" return resolveMiddlewareReferences(config?.middleware ?? [], registry)",
|
|
245
|
+
"}",
|
|
246
|
+
"",
|
|
247
|
+
"function resolveMiddlewareReferences(references, registry) {",
|
|
248
|
+
" const entries = Array.isArray(references) ? references : [references]",
|
|
249
|
+
" const middleware = []",
|
|
250
|
+
"",
|
|
251
|
+
" for (const reference of entries) {",
|
|
252
|
+
" if (reference === undefined) {",
|
|
253
|
+
" continue",
|
|
254
|
+
" }",
|
|
255
|
+
"",
|
|
256
|
+
" if (typeof reference === \"function\") {",
|
|
257
|
+
" middleware.push(reference)",
|
|
258
|
+
" continue",
|
|
259
|
+
" }",
|
|
260
|
+
"",
|
|
261
|
+
" const handler = registry[reference]",
|
|
262
|
+
" if (!handler) {",
|
|
263
|
+
" throw new Error(`Unknown middleware reference \"${reference}\".`)",
|
|
264
|
+
" }",
|
|
265
|
+
"",
|
|
266
|
+
" middleware.push(handler)",
|
|
267
|
+
" }",
|
|
268
|
+
"",
|
|
269
|
+
" return middleware",
|
|
270
|
+
"}",
|
|
271
|
+
"",
|
|
272
|
+
"function attachAppMiddleware(routes, middleware) {",
|
|
273
|
+
" if (!Array.isArray(middleware) || middleware.length === 0) {",
|
|
274
|
+
" return routes",
|
|
275
|
+
" }",
|
|
276
|
+
"",
|
|
277
|
+
" return routes.map((route) => ({",
|
|
278
|
+
" ...route,",
|
|
279
|
+
" module: {",
|
|
280
|
+
" ...route.module,",
|
|
281
|
+
" middleware: [...middleware, ...(route.module.middleware ?? [])],",
|
|
282
|
+
" },",
|
|
283
|
+
" }))",
|
|
284
|
+
"}",
|
|
285
|
+
"",
|
|
286
|
+
...importLines.length > 0 ? ["", ...createAppRuntimeHmrBlock(importEntries)] : [],
|
|
287
|
+
"",
|
|
288
|
+
"export default integration"
|
|
289
|
+
].join("\n");
|
|
290
|
+
}
|
|
291
|
+
function createVirtualAppLoaderModule(result) {
|
|
292
|
+
if (!result.app.loader) return [
|
|
293
|
+
"export const appLoader = undefined",
|
|
294
|
+
"",
|
|
295
|
+
"export default appLoader"
|
|
296
|
+
].join("\n");
|
|
297
|
+
return [
|
|
298
|
+
`import * as appLoaderModule from ${JSON.stringify(createImportSpecifier(result.app.loader))}`,
|
|
299
|
+
"",
|
|
300
|
+
"export const appLoader = resolveAppLoader(appLoaderModule)",
|
|
301
|
+
"",
|
|
302
|
+
"function resolveAppLoader(module) {",
|
|
303
|
+
" const loader = module?.loader ?? module?.default",
|
|
304
|
+
" if (typeof loader !== \"function\") {",
|
|
305
|
+
" throw new Error(\"Invalid app loader module. Expected a default export or named \\\"loader\\\" export.\")",
|
|
306
|
+
" }",
|
|
307
|
+
"",
|
|
308
|
+
" return loader",
|
|
309
|
+
"}",
|
|
310
|
+
"",
|
|
311
|
+
"export default appLoader"
|
|
312
|
+
].join("\n");
|
|
313
|
+
}
|
|
314
|
+
function createVirtualAppMiddlewareModule(result) {
|
|
315
|
+
const middlewareEntries = Object.entries(result.app.middleware);
|
|
316
|
+
const importLines = middlewareEntries.map(([, file], index) => `import * as middlewareModule${index} from ${JSON.stringify(createImportSpecifier(file))}`);
|
|
317
|
+
const registryEntries = middlewareEntries.map(([name], index) => [name, `resolveMiddleware(middlewareModule${index}, ${JSON.stringify(name)})`]);
|
|
318
|
+
return [
|
|
319
|
+
...importLines,
|
|
320
|
+
importLines.length > 0 ? "" : "",
|
|
321
|
+
`export const appMiddlewareRegistry = ${serializeObject(registryEntries)}`,
|
|
322
|
+
"",
|
|
323
|
+
"function resolveMiddleware(module, name) {",
|
|
324
|
+
" const middleware = module?.middleware ?? module?.default",
|
|
325
|
+
" if (typeof middleware !== \"function\") {",
|
|
326
|
+
" throw new Error(`Invalid middleware module \"${name}\". Expected a default export or named \"middleware\" export.`)",
|
|
327
|
+
" }",
|
|
328
|
+
"",
|
|
329
|
+
" return middleware",
|
|
330
|
+
"}",
|
|
331
|
+
"",
|
|
332
|
+
"export default appMiddlewareRegistry"
|
|
333
|
+
].join("\n");
|
|
334
|
+
}
|
|
335
|
+
function createVirtualServerRoutesModule(result) {
|
|
336
|
+
const routeEntries = result.server.routes;
|
|
337
|
+
const uniqueFiles = Array.from(new Set(routeEntries.flatMap((route) => [route.file, ...route.directoryMiddleware])));
|
|
338
|
+
const importLines = uniqueFiles.map((specifier, index) => `import * as importedServerFile${index} from ${JSON.stringify(createImportSpecifier(specifier))}`);
|
|
339
|
+
const fileModuleBindings = uniqueFiles.map((_specifier, index) => `const serverFileModule${index} = importedServerFile${index}`);
|
|
340
|
+
const fileIndexMap = serializeObject(uniqueFiles.map((specifier, index) => [specifier, String(index)]));
|
|
341
|
+
return [
|
|
342
|
+
`export { serverMiddlewareRegistry } from ${JSON.stringify(GENERATED_SERVER_MIDDLEWARE_ID)}`,
|
|
343
|
+
"",
|
|
344
|
+
...importLines,
|
|
345
|
+
importLines.length > 0 ? "" : "",
|
|
346
|
+
...fileModuleBindings,
|
|
347
|
+
fileModuleBindings.length > 0 ? "" : "",
|
|
348
|
+
`export const serverRoutes = ${serializeArrayOfObjects(routeEntries.map((route) => [
|
|
349
|
+
["id", JSON.stringify(route.id)],
|
|
350
|
+
["path", JSON.stringify(route.path)],
|
|
351
|
+
["file", JSON.stringify(route.file)],
|
|
352
|
+
["definition", `resolveServerRoute(getLoadedServerModule(${JSON.stringify(route.file)}), ${JSON.stringify(route.file)})`],
|
|
353
|
+
["directoryMiddlewareNames", `resolveDirectoryMiddlewareNames(${serializeArray(route.directoryMiddleware)})`]
|
|
354
|
+
]))}`,
|
|
355
|
+
"",
|
|
356
|
+
"function resolveDirectoryMiddlewareNames(files) {",
|
|
357
|
+
" return files.flatMap((file) => resolveMiddlewareNames(getLoadedServerModule(file), file))",
|
|
358
|
+
"}",
|
|
359
|
+
"",
|
|
360
|
+
"function resolveServerRoute(module, file) {",
|
|
361
|
+
" const route = module?.default ?? module?.route",
|
|
362
|
+
" if (!route || typeof route !== \"object\") {",
|
|
363
|
+
" throw new Error(`Invalid server route module \"${file}\". Expected a default export or named \"route\" export.`)",
|
|
364
|
+
" }",
|
|
365
|
+
"",
|
|
366
|
+
" return {",
|
|
367
|
+
" middlewareNames: normalizeMiddlewareNames(route?.middleware),",
|
|
368
|
+
" meta: route?.meta && typeof route.meta === \"object\" ? route.meta : undefined,",
|
|
369
|
+
" handler: asHandler(route?.handler),",
|
|
370
|
+
" GET: asHandler(route?.GET),",
|
|
371
|
+
" POST: asHandler(route?.POST),",
|
|
372
|
+
" PUT: asHandler(route?.PUT),",
|
|
373
|
+
" PATCH: asHandler(route?.PATCH),",
|
|
374
|
+
" DELETE: asHandler(route?.DELETE),",
|
|
375
|
+
" HEAD: asHandler(route?.HEAD),",
|
|
376
|
+
" OPTIONS: asHandler(route?.OPTIONS),",
|
|
377
|
+
" }",
|
|
378
|
+
"}",
|
|
379
|
+
"",
|
|
380
|
+
"function resolveMiddlewareNames(module, file) {",
|
|
381
|
+
" if (!module) {",
|
|
382
|
+
" return []",
|
|
383
|
+
" }",
|
|
384
|
+
"",
|
|
385
|
+
" const middleware = module?.middleware ?? module?.default",
|
|
386
|
+
" if (middleware === undefined) {",
|
|
387
|
+
" return []",
|
|
388
|
+
" }",
|
|
389
|
+
"",
|
|
390
|
+
" if (!Array.isArray(middleware) || middleware.some((name) => typeof name !== \"string\")) {",
|
|
391
|
+
" throw new Error(`Invalid server route directory middleware \"${file}\". Expected a default export or named \"middleware\" export with a string array.`)",
|
|
392
|
+
" }",
|
|
393
|
+
"",
|
|
394
|
+
" return middleware",
|
|
395
|
+
"}",
|
|
396
|
+
"",
|
|
397
|
+
"function normalizeMiddlewareNames(value) {",
|
|
398
|
+
" if (value === undefined) {",
|
|
399
|
+
" return undefined",
|
|
400
|
+
" }",
|
|
401
|
+
"",
|
|
402
|
+
" if (!Array.isArray(value) || value.some((name) => typeof name !== \"string\")) {",
|
|
403
|
+
" throw new Error('Server route \"middleware\" must be a string array.')",
|
|
404
|
+
" }",
|
|
405
|
+
"",
|
|
406
|
+
" return value",
|
|
407
|
+
"}",
|
|
408
|
+
"",
|
|
409
|
+
"function asHandler(value) {",
|
|
410
|
+
" return typeof value === \"function\" ? value : undefined",
|
|
411
|
+
"}",
|
|
412
|
+
"",
|
|
413
|
+
"function getLoadedServerModule(file) {",
|
|
414
|
+
` const fileIndex = ${fileIndexMap}[file]`,
|
|
415
|
+
" if (fileIndex === undefined) {",
|
|
416
|
+
" return undefined",
|
|
417
|
+
" }",
|
|
418
|
+
"",
|
|
419
|
+
" return [",
|
|
420
|
+
...uniqueFiles.map((_, index) => ` serverFileModule${index}${index < uniqueFiles.length - 1 ? "," : ""}`),
|
|
421
|
+
" ][fileIndex]",
|
|
422
|
+
"}",
|
|
423
|
+
"",
|
|
424
|
+
"export default serverRoutes"
|
|
425
|
+
].join("\n");
|
|
426
|
+
}
|
|
427
|
+
function createVirtualServerMiddlewareModule(result) {
|
|
428
|
+
const middlewareEntries = Object.entries(result.server.middleware);
|
|
429
|
+
const importLines = middlewareEntries.map(([, file], index) => `import * as middlewareModule${index} from ${JSON.stringify(createImportSpecifier(file))}`);
|
|
430
|
+
const registryEntries = middlewareEntries.map(([name], index) => [name, `resolveMiddleware(middlewareModule${index}, ${JSON.stringify(name)})`]);
|
|
431
|
+
return [
|
|
432
|
+
...importLines,
|
|
433
|
+
importLines.length > 0 ? "" : "",
|
|
434
|
+
`export const serverMiddlewareRegistry = ${serializeObject(registryEntries)}`,
|
|
435
|
+
"",
|
|
436
|
+
"function resolveMiddleware(module, name) {",
|
|
437
|
+
" const middleware = module?.middleware ?? module?.default",
|
|
438
|
+
" if (typeof middleware !== \"function\") {",
|
|
439
|
+
" throw new Error(`Invalid server middleware module \"${name}\". Expected a default export or named \"middleware\" export.`)",
|
|
440
|
+
" }",
|
|
441
|
+
"",
|
|
442
|
+
" return middleware",
|
|
443
|
+
"}",
|
|
444
|
+
"",
|
|
445
|
+
"export default serverMiddlewareRegistry"
|
|
446
|
+
].join("\n");
|
|
447
|
+
}
|
|
448
|
+
function createVirtualAppPluginModule() {
|
|
449
|
+
return [
|
|
450
|
+
`import { createIntegration } from ${JSON.stringify(GENERATED_APP_RUNTIME_ID)}`,
|
|
451
|
+
"",
|
|
452
|
+
"function createAppRouteMiddleware(getIntegration) {",
|
|
453
|
+
" return async (request, next) => {",
|
|
454
|
+
" const integration = await getIntegration()",
|
|
455
|
+
" const routeMatch = integration.match(new URL(request.url).pathname)",
|
|
456
|
+
" if (!routeMatch) {",
|
|
457
|
+
" return next(request)",
|
|
458
|
+
" }",
|
|
459
|
+
"",
|
|
460
|
+
" return integration.handleRequest(request)",
|
|
461
|
+
" }",
|
|
462
|
+
"}",
|
|
463
|
+
"",
|
|
464
|
+
"function createAppRouteServerPlugin(options = {}) {",
|
|
465
|
+
" let integrationPromise",
|
|
466
|
+
"",
|
|
467
|
+
" return (server) => {",
|
|
468
|
+
" server.options.middleware.push(",
|
|
469
|
+
" createAppRouteMiddleware(() => {",
|
|
470
|
+
" if (!integrationPromise) {",
|
|
471
|
+
" integrationPromise = Promise.resolve(createIntegration(options))",
|
|
472
|
+
" }",
|
|
473
|
+
"",
|
|
474
|
+
" return integrationPromise",
|
|
475
|
+
" }),",
|
|
476
|
+
" )",
|
|
477
|
+
" }",
|
|
478
|
+
"}",
|
|
479
|
+
"",
|
|
480
|
+
"export function createAppPlugin(options = {}) {",
|
|
481
|
+
" return createAppRouteServerPlugin(options)",
|
|
482
|
+
"}",
|
|
483
|
+
"",
|
|
484
|
+
"export const appPlugin = createAppPlugin()",
|
|
485
|
+
"",
|
|
486
|
+
"export default createAppPlugin"
|
|
487
|
+
].join("\n");
|
|
488
|
+
}
|
|
489
|
+
function createVirtualServerPluginModule() {
|
|
490
|
+
return [
|
|
491
|
+
"import { runMiddleware } from \"@hornjs/fest\"",
|
|
492
|
+
`import { config } from ${JSON.stringify(GENERATED_CONFIG_ID)}`,
|
|
493
|
+
`import { serverMiddlewareRegistry, serverRoutes } from ${JSON.stringify(GENERATED_SERVER_ROUTES_ID)}`,
|
|
494
|
+
"",
|
|
495
|
+
"function createServerRoutesPlugin(options) {",
|
|
496
|
+
" return (server) => {",
|
|
497
|
+
" server.options.middleware.unshift(createServerRoutesMiddleware(options))",
|
|
498
|
+
" }",
|
|
499
|
+
"}",
|
|
500
|
+
"",
|
|
501
|
+
"function createServerRoutesMiddleware(options) {",
|
|
502
|
+
" return async (request, next) => {",
|
|
503
|
+
" const route = findServerRoute(options.routes, new URL(request.url).pathname)",
|
|
504
|
+
" if (!route) {",
|
|
505
|
+
" return next(request)",
|
|
506
|
+
" }",
|
|
507
|
+
"",
|
|
508
|
+
" const handler = getRouteHandler(route, request.method)",
|
|
509
|
+
" if (!handler) {",
|
|
510
|
+
" return new Response(\"Method Not Allowed\", { status: 405 })",
|
|
511
|
+
" }",
|
|
512
|
+
"",
|
|
513
|
+
" const middleware = resolveMiddlewareChain(",
|
|
514
|
+
" route,",
|
|
515
|
+
" options.middlewareRegistry,",
|
|
516
|
+
" options.globalMiddlewareNames,",
|
|
517
|
+
" )",
|
|
518
|
+
" if (middleware.length === 0) {",
|
|
519
|
+
" return handleRoute(request, handler)",
|
|
520
|
+
" }",
|
|
521
|
+
"",
|
|
522
|
+
" return runMiddleware(middleware, request, (nextRequest) => handleRoute(nextRequest, handler))",
|
|
523
|
+
" }",
|
|
524
|
+
"}",
|
|
525
|
+
"",
|
|
526
|
+
"async function handleRoute(request, handler) {",
|
|
527
|
+
" const result = await handler(request)",
|
|
528
|
+
" if (result instanceof Response) {",
|
|
529
|
+
" return result",
|
|
530
|
+
" }",
|
|
531
|
+
"",
|
|
532
|
+
" return Response.json(result)",
|
|
533
|
+
"}",
|
|
534
|
+
"",
|
|
535
|
+
"function resolveMiddlewareChain(route, registry, globalMiddlewareNames = []) {",
|
|
536
|
+
" const names = [",
|
|
537
|
+
" ...globalMiddlewareNames,",
|
|
538
|
+
" ...(route.directoryMiddlewareNames ?? []),",
|
|
539
|
+
" ...(route.definition.middlewareNames ?? []),",
|
|
540
|
+
" ]",
|
|
541
|
+
"",
|
|
542
|
+
" return names.map((name) => {",
|
|
543
|
+
" const middleware = registry[name]",
|
|
544
|
+
" if (!middleware) {",
|
|
545
|
+
" throw new Error(`Unknown server middleware \"${name}\" referenced by route \"${route.id}\".`)",
|
|
546
|
+
" }",
|
|
547
|
+
"",
|
|
548
|
+
" return middleware",
|
|
549
|
+
" })",
|
|
550
|
+
"}",
|
|
551
|
+
"",
|
|
552
|
+
"function findServerRoute(routes, pathname) {",
|
|
553
|
+
" const normalizedPathname = normalizePathname(pathname)",
|
|
554
|
+
" return routes.find((route) => matchesServerRoutePath(route.path, normalizedPathname))",
|
|
555
|
+
"}",
|
|
556
|
+
"",
|
|
557
|
+
"function matchesServerRoutePath(pattern, pathname) {",
|
|
558
|
+
" const normalizedPattern = normalizePathname(pattern)",
|
|
559
|
+
" if (normalizedPattern === pathname) {",
|
|
560
|
+
" return true",
|
|
561
|
+
" }",
|
|
562
|
+
"",
|
|
563
|
+
" const patternSegments = splitPathSegments(normalizedPattern)",
|
|
564
|
+
" const pathnameSegments = splitPathSegments(pathname)",
|
|
565
|
+
" if (patternSegments.length !== pathnameSegments.length) {",
|
|
566
|
+
" return false",
|
|
567
|
+
" }",
|
|
568
|
+
"",
|
|
569
|
+
" for (let index = 0; index < patternSegments.length; index += 1) {",
|
|
570
|
+
" const patternSegment = patternSegments[index]",
|
|
571
|
+
" const pathnameSegment = pathnameSegments[index]",
|
|
572
|
+
"",
|
|
573
|
+
" if (!patternSegment) {",
|
|
574
|
+
" return false",
|
|
575
|
+
" }",
|
|
576
|
+
"",
|
|
577
|
+
" if (patternSegment.startsWith(\":\")) {",
|
|
578
|
+
" continue",
|
|
579
|
+
" }",
|
|
580
|
+
"",
|
|
581
|
+
" if (patternSegment !== pathnameSegment) {",
|
|
582
|
+
" return false",
|
|
583
|
+
" }",
|
|
584
|
+
" }",
|
|
585
|
+
"",
|
|
586
|
+
" return true",
|
|
587
|
+
"}",
|
|
588
|
+
"",
|
|
589
|
+
"function getRouteHandler(route, method) {",
|
|
590
|
+
" const resolvedMethod = method.toUpperCase()",
|
|
591
|
+
" const definition = route.definition",
|
|
592
|
+
"",
|
|
593
|
+
" switch (resolvedMethod) {",
|
|
594
|
+
" case \"GET\":",
|
|
595
|
+
" return definition.GET ?? definition.handler",
|
|
596
|
+
" case \"POST\":",
|
|
597
|
+
" return definition.POST ?? definition.handler",
|
|
598
|
+
" case \"PUT\":",
|
|
599
|
+
" return definition.PUT ?? definition.handler",
|
|
600
|
+
" case \"PATCH\":",
|
|
601
|
+
" return definition.PATCH ?? definition.handler",
|
|
602
|
+
" case \"DELETE\":",
|
|
603
|
+
" return definition.DELETE ?? definition.handler",
|
|
604
|
+
" case \"HEAD\":",
|
|
605
|
+
" return definition.HEAD ?? definition.handler",
|
|
606
|
+
" case \"OPTIONS\":",
|
|
607
|
+
" return definition.OPTIONS ?? definition.handler",
|
|
608
|
+
" default:",
|
|
609
|
+
" return definition.handler",
|
|
610
|
+
" }",
|
|
611
|
+
"}",
|
|
612
|
+
"",
|
|
613
|
+
"function normalizePathname(pathname) {",
|
|
614
|
+
" if (!pathname) {",
|
|
615
|
+
" return \"/\"",
|
|
616
|
+
" }",
|
|
617
|
+
"",
|
|
618
|
+
" if (!pathname.startsWith(\"/\")) {",
|
|
619
|
+
" return `/${pathname}`",
|
|
620
|
+
" }",
|
|
621
|
+
"",
|
|
622
|
+
" if (pathname.length > 1 && pathname.endsWith(\"/\")) {",
|
|
623
|
+
" return pathname.replace(/\\/+$/, \"\")",
|
|
624
|
+
" }",
|
|
625
|
+
"",
|
|
626
|
+
" return pathname",
|
|
627
|
+
"}",
|
|
628
|
+
"",
|
|
629
|
+
"function splitPathSegments(pathname) {",
|
|
630
|
+
" const normalized = normalizePathname(pathname)",
|
|
631
|
+
" if (normalized === \"/\") {",
|
|
632
|
+
" return []",
|
|
633
|
+
" }",
|
|
634
|
+
"",
|
|
635
|
+
" return normalized.replace(/^\\/+|\\/+$/g, \"\").split(\"/\")",
|
|
636
|
+
"}",
|
|
637
|
+
"",
|
|
638
|
+
"export function createServerPlugin() {",
|
|
639
|
+
" return createServerRoutesPlugin({",
|
|
640
|
+
" routes: serverRoutes,",
|
|
641
|
+
" middlewareRegistry: serverMiddlewareRegistry,",
|
|
642
|
+
" globalMiddlewareNames: config.server?.middleware ?? []",
|
|
643
|
+
" })",
|
|
644
|
+
"}",
|
|
645
|
+
"",
|
|
646
|
+
"export const serverPlugin = createServerPlugin()",
|
|
647
|
+
"",
|
|
648
|
+
"export default createServerPlugin"
|
|
649
|
+
].join("\n");
|
|
650
|
+
}
|
|
651
|
+
function resolveVirtualModuleId(id) {
|
|
652
|
+
if (id === "virtual:phial-routes-manifest" || id === RESOLVED_VIRTUAL_ROUTES_MANIFEST_ID) return RESOLVED_VIRTUAL_ROUTES_MANIFEST_ID;
|
|
653
|
+
if (id === "virtual:phial-routes-modules" || id === RESOLVED_VIRTUAL_ROUTES_MODULES_ID) return RESOLVED_VIRTUAL_ROUTES_MODULES_ID;
|
|
654
|
+
if (id === "virtual:phial-app-runtime" || id === RESOLVED_VIRTUAL_APP_RUNTIME_ID) return RESOLVED_VIRTUAL_APP_RUNTIME_ID;
|
|
655
|
+
if (id === "phial/generated-routes-manifest" || id === RESOLVED_GENERATED_ROUTES_MANIFEST_ID) return RESOLVED_GENERATED_ROUTES_MANIFEST_ID;
|
|
656
|
+
if (id === "phial/generated-routes-modules" || id === RESOLVED_GENERATED_ROUTES_MODULES_ID) return RESOLVED_GENERATED_ROUTES_MODULES_ID;
|
|
657
|
+
if (id === "phial/generated-app-runtime" || id === RESOLVED_GENERATED_APP_RUNTIME_ID) return RESOLVED_GENERATED_APP_RUNTIME_ID;
|
|
658
|
+
if (id === "phial/generated-app-loader" || id === RESOLVED_GENERATED_APP_LOADER_ID) return RESOLVED_GENERATED_APP_LOADER_ID;
|
|
659
|
+
if (id === "phial/generated-app-middleware" || id === RESOLVED_GENERATED_APP_MIDDLEWARE_ID) return RESOLVED_GENERATED_APP_MIDDLEWARE_ID;
|
|
660
|
+
if (id === "phial/generated-app-plugin" || id === RESOLVED_GENERATED_APP_PLUGIN_ID) return RESOLVED_GENERATED_APP_PLUGIN_ID;
|
|
661
|
+
if (id === "phial/generated-server-routes" || id === RESOLVED_GENERATED_SERVER_ROUTES_ID) return RESOLVED_GENERATED_SERVER_ROUTES_ID;
|
|
662
|
+
if (id === "phial/generated-server-middleware" || id === RESOLVED_GENERATED_SERVER_MIDDLEWARE_ID) return RESOLVED_GENERATED_SERVER_MIDDLEWARE_ID;
|
|
663
|
+
if (id === "phial/generated-server-plugin" || id === RESOLVED_GENERATED_SERVER_PLUGIN_ID) return RESOLVED_GENERATED_SERVER_PLUGIN_ID;
|
|
664
|
+
if (id === "phial/generated-config" || id === RESOLVED_GENERATED_CONFIG_ID) return RESOLVED_GENERATED_CONFIG_ID;
|
|
665
|
+
return null;
|
|
666
|
+
}
|
|
667
|
+
function createVirtualConfigModule(options) {
|
|
668
|
+
if (!options.hasConfigFile) return [
|
|
669
|
+
"export const hasConfig = false",
|
|
670
|
+
"export const config = {}",
|
|
671
|
+
"",
|
|
672
|
+
"export default config"
|
|
673
|
+
].join("\n");
|
|
674
|
+
return [
|
|
675
|
+
"export const hasConfig = true",
|
|
676
|
+
`export const config = ${JSON.stringify(options.config, null, 2)}`,
|
|
677
|
+
"",
|
|
678
|
+
"export default config"
|
|
679
|
+
].join("\n");
|
|
680
|
+
}
|
|
681
|
+
function createDynamicRouteModulesModule(result) {
|
|
682
|
+
const routeFiles = serializeObject(result.modules.map((module) => [module.id, serializeArray(resolveModuleSpecifiers(module))]));
|
|
683
|
+
const routeModules = serializeObject(result.modules.map((module) => [module.id, `() => loadResolvedRouteModule(${JSON.stringify(module.id)})`]));
|
|
684
|
+
const hmrBlock = createRouteModulesHmrBlock(Array.from(new Set(result.modules.flatMap((module) => resolveModuleSpecifiers(module)))));
|
|
685
|
+
return [
|
|
686
|
+
`export const routeFiles = ${routeFiles}`,
|
|
687
|
+
"",
|
|
688
|
+
`export const routeModules = ${routeModules}`,
|
|
689
|
+
"",
|
|
690
|
+
"export async function loadRouteModule(id) {",
|
|
691
|
+
" const importer = routeModules[id]",
|
|
692
|
+
" return importer ? importer() : undefined",
|
|
693
|
+
"}",
|
|
694
|
+
"",
|
|
695
|
+
"async function loadResolvedRouteModule(id) {",
|
|
696
|
+
` const routeDefinitions = ${serializeObject(result.modules.map((module) => [module.id, createRouteDefinition(module)]))}`,
|
|
697
|
+
" const definition = routeDefinitions[id]",
|
|
698
|
+
" if (!definition) {",
|
|
699
|
+
" return undefined",
|
|
700
|
+
" }",
|
|
701
|
+
"",
|
|
702
|
+
" const loadedModules = await Promise.all(definition.files.map(file => import(file)))",
|
|
703
|
+
" return createPhialRouteModule(definition, loadedModules)",
|
|
704
|
+
"}",
|
|
705
|
+
"",
|
|
706
|
+
...createRouteModuleHelperLines(),
|
|
707
|
+
...hmrBlock.length > 0 ? ["", ...hmrBlock] : [],
|
|
708
|
+
"",
|
|
709
|
+
"export default routeModules"
|
|
710
|
+
].join("\n");
|
|
711
|
+
}
|
|
712
|
+
function createEagerRouteModulesModule(result) {
|
|
713
|
+
const uniqueFiles = Array.from(new Set(result.modules.flatMap((module) => resolveModuleSpecifiers(module))));
|
|
714
|
+
const importLines = uniqueFiles.map((specifier, index) => {
|
|
715
|
+
return `import * as importedRouteFile${index} from ${JSON.stringify(specifier)}`;
|
|
716
|
+
});
|
|
717
|
+
const fileModuleInitializers = uniqueFiles.map((_specifier, index) => {
|
|
718
|
+
return `let routeFileModule${index} = importedRouteFile${index}`;
|
|
719
|
+
});
|
|
720
|
+
const fileSetters = uniqueFiles.map((_specifier, index) => {
|
|
721
|
+
return ` (nextModule) => { if (nextModule) routeFileModule${index} = nextModule }`;
|
|
722
|
+
});
|
|
723
|
+
const routeDefinitions = serializeObject(result.modules.map((module) => [module.id, createRouteDefinition(module)]));
|
|
724
|
+
const routeFiles = serializeObject(result.modules.map((module) => [module.id, serializeArray(resolveModuleSpecifiers(module))]));
|
|
725
|
+
const routeModules = serializeObject(result.modules.map((module) => [module.id, `createResolvedRouteModule(${JSON.stringify(module.id)})`]));
|
|
726
|
+
const hmrBlock = createRouteModulesHmrBlock(uniqueFiles, { applyUpdatedModules: [
|
|
727
|
+
` const applyFileModuleUpdates = [\n${fileSetters.join(",\n")}\n ]`,
|
|
728
|
+
" nextModules.forEach((nextModule, index) => {",
|
|
729
|
+
" const applyUpdate = applyFileModuleUpdates[index]",
|
|
730
|
+
" if (applyUpdate) {",
|
|
731
|
+
" applyUpdate(nextModule)",
|
|
732
|
+
" }",
|
|
733
|
+
" })",
|
|
734
|
+
"",
|
|
735
|
+
` const routeIds = ${JSON.stringify(result.modules.map((module) => module.id))}`,
|
|
736
|
+
" routeIds.forEach((routeId) => {",
|
|
737
|
+
" routeModules[routeId] = createResolvedRouteModule(routeId)",
|
|
738
|
+
" })",
|
|
739
|
+
""
|
|
740
|
+
] });
|
|
741
|
+
return [
|
|
742
|
+
...importLines,
|
|
743
|
+
importLines.length > 0 ? "" : "",
|
|
744
|
+
...fileModuleInitializers,
|
|
745
|
+
fileModuleInitializers.length > 0 ? "" : "",
|
|
746
|
+
`const routeDefinitions = ${routeDefinitions}`,
|
|
747
|
+
"",
|
|
748
|
+
`export const routeFiles = ${routeFiles}`,
|
|
749
|
+
"",
|
|
750
|
+
`export const routeModules = ${routeModules}`,
|
|
751
|
+
"",
|
|
752
|
+
"export function loadRouteModule(id) {",
|
|
753
|
+
" return routeModules[id]",
|
|
754
|
+
"}",
|
|
755
|
+
"",
|
|
756
|
+
"function createResolvedRouteModule(id) {",
|
|
757
|
+
" const definition = routeDefinitions[id]",
|
|
758
|
+
" if (!definition) {",
|
|
759
|
+
" return undefined",
|
|
760
|
+
" }",
|
|
761
|
+
"",
|
|
762
|
+
" const loadedModules = definition.files.map((file) => getLoadedRouteFileModule(file))",
|
|
763
|
+
" return createPhialRouteModule(definition, loadedModules)",
|
|
764
|
+
"}",
|
|
765
|
+
"",
|
|
766
|
+
"function getLoadedRouteFileModule(file) {",
|
|
767
|
+
` const routeFileIndexMap = ${serializeObject(uniqueFiles.map((specifier, index) => [specifier, String(index)]))}`,
|
|
768
|
+
" const fileIndex = routeFileIndexMap[file]",
|
|
769
|
+
" if (fileIndex === undefined) {",
|
|
770
|
+
" return undefined",
|
|
771
|
+
" }",
|
|
772
|
+
"",
|
|
773
|
+
" return [",
|
|
774
|
+
...uniqueFiles.map((_, index) => ` routeFileModule${index}${index < uniqueFiles.length - 1 ? "," : ""}`),
|
|
775
|
+
" ][fileIndex]",
|
|
776
|
+
"}",
|
|
777
|
+
"",
|
|
778
|
+
...createRouteModuleHelperLines(),
|
|
779
|
+
...hmrBlock.length > 0 ? ["", ...hmrBlock] : [],
|
|
780
|
+
"",
|
|
781
|
+
"export default routeModules"
|
|
782
|
+
].join("\n");
|
|
783
|
+
}
|
|
784
|
+
function createRouteModulesHmrBlock(routeImportSpecifiers, options = {}) {
|
|
785
|
+
if (routeImportSpecifiers.length === 0) return [];
|
|
786
|
+
return [
|
|
787
|
+
"if (import.meta.hot) {",
|
|
788
|
+
` import.meta.hot.accept(${JSON.stringify(routeImportSpecifiers)}, async (nextModules) => {`,
|
|
789
|
+
...options.applyUpdatedModules ?? [],
|
|
790
|
+
" if (typeof window !== \"undefined\") {",
|
|
791
|
+
" const runtime = globalThis",
|
|
792
|
+
" const applyRouteModuleHotUpdate = runtime.__ROUTE_MODULE_HMR__",
|
|
793
|
+
"",
|
|
794
|
+
" if (typeof applyRouteModuleHotUpdate === \"function\") {",
|
|
795
|
+
" await applyRouteModuleHotUpdate()",
|
|
796
|
+
" return",
|
|
797
|
+
" }",
|
|
798
|
+
" }",
|
|
799
|
+
"",
|
|
800
|
+
" import.meta.hot.invalidate()",
|
|
801
|
+
" })",
|
|
802
|
+
"}"
|
|
803
|
+
];
|
|
804
|
+
}
|
|
805
|
+
function createAppRuntimeHmrBlock(importEntries) {
|
|
806
|
+
const importSpecifiers = importEntries.map((entry) => entry.specifier);
|
|
807
|
+
const updateBindings = importEntries.flatMap((entry, index) => {
|
|
808
|
+
const resolveExpression = entry.exportName === "appComponent" ? `resolveAppComponent(${entry.local})` : entry.exportName === "errorComponent" ? `resolveErrorComponent(${entry.local})` : entry.exportName === "appLoader" ? `resolveAppLoader(${entry.local})` : `resolveAppConfig(${entry.local})`;
|
|
809
|
+
return [
|
|
810
|
+
` if (nextModules[${index}]) {`,
|
|
811
|
+
` ${entry.local} = nextModules[${index}]`,
|
|
812
|
+
" }",
|
|
813
|
+
` ${entry.exportName} = ${resolveExpression}`
|
|
814
|
+
];
|
|
815
|
+
});
|
|
816
|
+
return [
|
|
817
|
+
"if (import.meta.hot) {",
|
|
818
|
+
` import.meta.hot.accept(${JSON.stringify(importSpecifiers)}, async (nextModules) => {`,
|
|
819
|
+
...updateBindings,
|
|
820
|
+
" app = createAppModule(appComponent, errorComponent, appLoader)",
|
|
821
|
+
" integration = createIntegration()",
|
|
822
|
+
"",
|
|
823
|
+
" if (await notifyAppRuntimeHotUpdate({",
|
|
824
|
+
" appComponent,",
|
|
825
|
+
" errorComponent,",
|
|
826
|
+
" config: appConfig,",
|
|
827
|
+
" routes,",
|
|
828
|
+
" })) {",
|
|
829
|
+
" return",
|
|
830
|
+
" }",
|
|
831
|
+
"",
|
|
832
|
+
" import.meta.hot.invalidate()",
|
|
833
|
+
" })",
|
|
834
|
+
"}"
|
|
835
|
+
];
|
|
836
|
+
}
|
|
837
|
+
function createRouteDefinition(module) {
|
|
838
|
+
const fileEntries = Object.entries(module.files).map(([key, file]) => [key, createImportSpecifier(file)]);
|
|
839
|
+
const directoryMiddlewareFiles = module.directoryMiddleware.map((file) => createImportSpecifier(file));
|
|
840
|
+
const files = Array.from(new Set([...fileEntries.map(([, specifier]) => specifier), ...directoryMiddlewareFiles]));
|
|
841
|
+
return `{
|
|
842
|
+
id: ${JSON.stringify(module.id)},
|
|
843
|
+
kind: ${JSON.stringify(module.kind)},
|
|
844
|
+
files: ${serializeArray(files)},
|
|
845
|
+
entryFiles: ${serializeObject(fileEntries.map(([key, specifier]) => [key, JSON.stringify(specifier)]))},
|
|
846
|
+
directoryMiddlewareFiles: ${serializeArray(directoryMiddlewareFiles)}
|
|
847
|
+
}`;
|
|
848
|
+
}
|
|
849
|
+
function createRouteModuleHelperLines() {
|
|
850
|
+
return [
|
|
851
|
+
"function createPhialRouteModule(definition, loadedModules) {",
|
|
852
|
+
" const modules = Object.fromEntries(definition.files.map((file, index) => [file, loadedModules[index]]))",
|
|
853
|
+
" const primaryModule = resolvePrimaryModule(definition, modules)",
|
|
854
|
+
" const errorModule = resolveEntryModule(definition, modules, \"error\")",
|
|
855
|
+
" const loadingModule = resolveEntryModule(definition, modules, \"loading\")",
|
|
856
|
+
" const loaderModule = resolveEntryModule(definition, modules, \"loader\")",
|
|
857
|
+
" const actionModule = resolveEntryModule(definition, modules, \"action\")",
|
|
858
|
+
" const middlewareModule = resolveEntryModule(definition, modules, \"middleware\")",
|
|
859
|
+
" const directoryMiddlewareModules = definition.directoryMiddlewareFiles.map((file) => modules[file])",
|
|
860
|
+
"",
|
|
861
|
+
" return {",
|
|
862
|
+
" default: resolveDefaultExport(primaryModule),",
|
|
863
|
+
" directoryMiddleware: directoryMiddlewareModules.flatMap((module) => resolveMiddlewareExport(module) ?? []),",
|
|
864
|
+
" loader: resolveHandlerExport(loaderModule, \"loader\") ?? resolveNamedExport(primaryModule, \"loader\"),",
|
|
865
|
+
" action: resolveHandlerExport(actionModule, \"action\") ?? resolveNamedExport(primaryModule, \"action\"),",
|
|
866
|
+
" middleware: resolveMiddlewareExport(middlewareModule) ?? resolveMiddlewareExport(primaryModule, false),",
|
|
867
|
+
" shouldRevalidate: resolveNamedExport(primaryModule, \"shouldRevalidate\"),",
|
|
868
|
+
" meta: resolveNamedExport(primaryModule, \"meta\"),",
|
|
869
|
+
" ErrorBoundary: resolveDefaultExport(errorModule) ?? resolveNamedExport(primaryModule, \"ErrorBoundary\"),",
|
|
870
|
+
" Loading: resolveDefaultExport(loadingModule) ?? resolveNamedExport(primaryModule, \"Loading\"),",
|
|
871
|
+
" onError: resolveHandlerExport(errorModule, \"onError\") ?? resolveNamedExport(primaryModule, \"onError\")",
|
|
872
|
+
" }",
|
|
873
|
+
"}",
|
|
874
|
+
"",
|
|
875
|
+
"function resolvePrimaryModule(definition, modules) {",
|
|
876
|
+
" const primaryFile = definition.entryFiles[definition.kind]",
|
|
877
|
+
" return primaryFile ? modules[primaryFile] : undefined",
|
|
878
|
+
"}",
|
|
879
|
+
"",
|
|
880
|
+
"function resolveEntryModule(definition, modules, key) {",
|
|
881
|
+
" const file = definition.entryFiles[key]",
|
|
882
|
+
" return file ? modules[file] : undefined",
|
|
883
|
+
"}",
|
|
884
|
+
"",
|
|
885
|
+
"function resolveDefaultExport(module) {",
|
|
886
|
+
" return module?.default",
|
|
887
|
+
"}",
|
|
888
|
+
"",
|
|
889
|
+
"function resolveNamedExport(module, name) {",
|
|
890
|
+
" return module?.[name]",
|
|
891
|
+
"}",
|
|
892
|
+
"",
|
|
893
|
+
"function resolveHandlerExport(module, name) {",
|
|
894
|
+
" if (!module) {",
|
|
895
|
+
" return undefined",
|
|
896
|
+
" }",
|
|
897
|
+
"",
|
|
898
|
+
" return module[name] ?? module.default",
|
|
899
|
+
"}",
|
|
900
|
+
"",
|
|
901
|
+
"function resolveMiddlewareExport(module, allowDefault = true) {",
|
|
902
|
+
" if (!module) {",
|
|
903
|
+
" return undefined",
|
|
904
|
+
" }",
|
|
905
|
+
"",
|
|
906
|
+
" const middleware = module.middleware ?? (allowDefault ? module.default : undefined)",
|
|
907
|
+
" if (middleware === undefined) {",
|
|
908
|
+
" return undefined",
|
|
909
|
+
" }",
|
|
910
|
+
"",
|
|
911
|
+
" return Array.isArray(middleware) ? middleware : [middleware]",
|
|
912
|
+
"}"
|
|
913
|
+
];
|
|
914
|
+
}
|
|
915
|
+
function resolveModuleSpecifiers(module) {
|
|
916
|
+
return Array.from(new Set([...Object.values(module.files).map((file) => createImportSpecifier(file)), ...module.directoryMiddleware.map((file) => createImportSpecifier(file))]));
|
|
917
|
+
}
|
|
918
|
+
function serializeObject(entries) {
|
|
919
|
+
if (entries.length === 0) return "{}";
|
|
920
|
+
return `{\n${entries.map(([key, value]) => ` ${JSON.stringify(key)}: ${value}`).join(",\n")}\n}`;
|
|
921
|
+
}
|
|
922
|
+
function serializeArrayOfObjects(entries) {
|
|
923
|
+
if (entries.length === 0) return "[]";
|
|
924
|
+
return `[\n${entries.map((objectEntries) => ` ${serializeInlineObject(objectEntries)}`).join(",\n")}\n]`;
|
|
925
|
+
}
|
|
926
|
+
function serializeInlineObject(entries) {
|
|
927
|
+
if (entries.length === 0) return "{}";
|
|
928
|
+
return `{ ${entries.map(([key, value]) => `${JSON.stringify(key)}: ${value}`).join(", ")} }`;
|
|
929
|
+
}
|
|
930
|
+
function serializeArray(entries) {
|
|
931
|
+
if (entries.length === 0) return "[]";
|
|
932
|
+
return `[\n${entries.map((entry) => ` ${JSON.stringify(entry)}`).join(",\n")}\n]`;
|
|
933
|
+
}
|
|
934
|
+
function createImportSpecifier(file) {
|
|
935
|
+
return file.startsWith("/") ? file : `/${file}`;
|
|
936
|
+
}
|
|
937
|
+
//#endregion
|
|
938
|
+
export { RESOLVED_GENERATED_APP_LOADER_ID, RESOLVED_GENERATED_APP_MIDDLEWARE_ID, RESOLVED_GENERATED_APP_PLUGIN_ID, RESOLVED_GENERATED_APP_RUNTIME_ID, RESOLVED_GENERATED_CONFIG_ID, RESOLVED_GENERATED_ROUTES_MANIFEST_ID, RESOLVED_GENERATED_ROUTES_MODULES_ID, RESOLVED_GENERATED_SERVER_MIDDLEWARE_ID, RESOLVED_GENERATED_SERVER_PLUGIN_ID, RESOLVED_GENERATED_SERVER_ROUTES_ID, RESOLVED_VIRTUAL_APP_RUNTIME_ID, RESOLVED_VIRTUAL_ROUTES_MANIFEST_ID, RESOLVED_VIRTUAL_ROUTES_MODULES_ID, createVirtualAppLoaderModule, createVirtualAppMiddlewareModule, createVirtualAppPluginModule, createVirtualAppRuntimeModule, createVirtualConfigModule, createVirtualRoutesManifestModule, createVirtualRoutesModulesModule, createVirtualServerMiddlewareModule, createVirtualServerPluginModule, createVirtualServerRoutesModule, resolveVirtualModuleId };
|
|
939
|
+
|
|
940
|
+
//# sourceMappingURL=virtual-modules.js.map
|