@reckona/mreact-router 0.0.82 → 0.0.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +17 -22
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +3 -1
- package/dist/build.js.map +1 -1
- package/dist/client-route-inference.d.ts +2 -0
- package/dist/client-route-inference.d.ts.map +1 -0
- package/dist/client-route-inference.js +2 -0
- package/dist/client-route-inference.js.map +1 -0
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +25 -19
- package/dist/client.js.map +1 -1
- package/dist/layout-composer.d.ts +24 -0
- package/dist/layout-composer.d.ts.map +1 -0
- package/dist/layout-composer.js +83 -0
- package/dist/layout-composer.js.map +1 -0
- package/dist/metadata.d.ts +9 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +419 -0
- package/dist/metadata.js.map +1 -0
- package/dist/middleware.d.ts +22 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +94 -0
- package/dist/middleware.js.map +1 -0
- package/dist/module-runner.d.ts +2 -2
- package/dist/module-runner.d.ts.map +1 -1
- package/dist/module-runner.js +1 -1
- package/dist/module-runner.js.map +1 -1
- package/dist/navigation-runtime.d.ts +2 -0
- package/dist/navigation-runtime.d.ts.map +1 -0
- package/dist/navigation-runtime.js +2 -0
- package/dist/navigation-runtime.js.map +1 -0
- package/dist/preload-policy.d.ts +24 -0
- package/dist/preload-policy.d.ts.map +1 -0
- package/dist/preload-policy.js +45 -0
- package/dist/preload-policy.js.map +1 -0
- package/dist/render.d.ts +1 -3
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +32 -676
- package/dist/render.js.map +1 -1
- package/dist/route-hydration-contract.d.ts +11 -0
- package/dist/route-hydration-contract.d.ts.map +1 -0
- package/dist/route-hydration-contract.js +21 -0
- package/dist/route-hydration-contract.js.map +1 -0
- package/dist/route-module-loader.d.ts +10 -0
- package/dist/route-module-loader.d.ts.map +1 -0
- package/dist/route-module-loader.js +61 -0
- package/dist/route-module-loader.js.map +1 -0
- package/dist/route-source.d.ts.map +1 -1
- package/dist/route-source.js +7 -5
- package/dist/route-source.js.map +1 -1
- package/dist/routes.js +6 -0
- package/dist/routes.js.map +1 -1
- package/dist/serve.d.ts +13 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +63 -28
- package/dist/serve.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +2 -1
- package/dist/vite.js.map +1 -1
- package/package.json +11 -11
- package/src/adapters/aws-lambda.ts +21 -28
- package/src/build.ts +9 -6
- package/src/client-route-inference.ts +18 -0
- package/src/client.ts +32 -20
- package/src/layout-composer.ts +142 -0
- package/src/metadata.ts +578 -0
- package/src/middleware.ts +153 -0
- package/src/module-runner.ts +3 -2
- package/src/navigation-runtime.ts +16 -0
- package/src/preload-policy.ts +89 -0
- package/src/render.ts +75 -986
- package/src/route-hydration-contract.ts +22 -0
- package/src/route-module-loader.ts +95 -0
- package/src/route-source.ts +9 -4
- package/src/routes.ts +8 -0
- package/src/serve.ts +110 -29
- package/src/vite.ts +6 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const routeHydrationContract = {
|
|
2
|
+
clientReferencesScriptPrefix: "mreact-client-references-",
|
|
3
|
+
hydratedAttribute: "data-mreact-hydrated",
|
|
4
|
+
hotRouteHydrateExport: "__mreactHotHydrateRoute",
|
|
5
|
+
propsScriptPrefix: "mreact-props-",
|
|
6
|
+
routeHydrateExport: "__mreactHydrateRoute",
|
|
7
|
+
routeMarkerAttribute: "data-mreact-route-id",
|
|
8
|
+
} as const;
|
|
9
|
+
|
|
10
|
+
export function routeDataScriptIds(routeId: string): [string, string] {
|
|
11
|
+
return [
|
|
12
|
+
`${routeHydrationContract.propsScriptPrefix}${routeId}`,
|
|
13
|
+
`${routeHydrationContract.clientReferencesScriptPrefix}${routeId}`,
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function routeDataScriptSelector(): string {
|
|
18
|
+
return [
|
|
19
|
+
`script[type="application/json"][id^="${routeHydrationContract.propsScriptPrefix}"]`,
|
|
20
|
+
`script[type="application/json"][id^="${routeHydrationContract.clientReferencesScriptPrefix}"]`,
|
|
21
|
+
].join(", ");
|
|
22
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import type { BuiltServerModuleArtifact } from "./build.js";
|
|
3
|
+
import type { AppRouterImportPolicy } from "./import-policy.js";
|
|
4
|
+
|
|
5
|
+
export type BuiltServerModuleOutputLike = NonNullable<BuiltServerModuleArtifact["request"]>;
|
|
6
|
+
|
|
7
|
+
// Per-request hashText (SHA-256) is one of the hot path's dominant
|
|
8
|
+
// costs. Cache hashes for `code` strings we have already seen this
|
|
9
|
+
// process (common case: the prepared code is identical across requests
|
|
10
|
+
// when the source file is unchanged).
|
|
11
|
+
const codeHashCache = new Map<string, string>();
|
|
12
|
+
const MAX_CODE_HASH_ENTRIES = 256;
|
|
13
|
+
|
|
14
|
+
export function memoizedHashText(code: string): string {
|
|
15
|
+
const cached = codeHashCache.get(code);
|
|
16
|
+
if (cached !== undefined) {
|
|
17
|
+
return cached;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const hash = hashText(code);
|
|
21
|
+
if (codeHashCache.size >= MAX_CODE_HASH_ENTRIES) {
|
|
22
|
+
// Simple LRU eviction: drop the oldest entry (Map keeps insertion order).
|
|
23
|
+
const oldestKey = codeHashCache.keys().next().value;
|
|
24
|
+
if (oldestKey !== undefined) {
|
|
25
|
+
codeHashCache.delete(oldestKey);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
codeHashCache.set(code, hash);
|
|
29
|
+
return hash;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function prebuiltRequestModuleArtifact(
|
|
33
|
+
serverModules: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined,
|
|
34
|
+
file: string,
|
|
35
|
+
source: string,
|
|
36
|
+
kind: "request" | "routeMetadata" = "request",
|
|
37
|
+
): BuiltServerModuleOutputLike | undefined {
|
|
38
|
+
const artifact = serverModules?.get(file)?.[kind];
|
|
39
|
+
|
|
40
|
+
return artifact !== undefined && artifact.sourceHash === memoizedHashText(source)
|
|
41
|
+
? artifact
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function prebuiltRouteLoaderModuleArtifact(
|
|
46
|
+
serverModules: ReadonlyMap<string, BuiltServerModuleArtifact> | undefined,
|
|
47
|
+
file: string,
|
|
48
|
+
source: string,
|
|
49
|
+
): BuiltServerModuleOutputLike | undefined {
|
|
50
|
+
const artifact = serverModules?.get(file)?.loader;
|
|
51
|
+
|
|
52
|
+
return artifact !== undefined && artifact.sourceHash === memoizedHashText(source)
|
|
53
|
+
? artifact
|
|
54
|
+
: prebuiltRequestModuleArtifact(serverModules, file, source);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function prebuiltServerComponentModuleCode(
|
|
58
|
+
artifact: BuiltServerModuleArtifact["string"] | BuiltServerModuleArtifact["stream"] | undefined,
|
|
59
|
+
code: string,
|
|
60
|
+
codeHash: string,
|
|
61
|
+
): string | undefined {
|
|
62
|
+
if (artifact === undefined) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!prebuiltServerModuleOutputMatches(artifact, code, codeHash)) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return artifact.bundleCode;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function prebuiltServerModuleOutputMatches(
|
|
74
|
+
artifact: BuiltServerModuleOutputLike,
|
|
75
|
+
code: string,
|
|
76
|
+
codeHash: string,
|
|
77
|
+
): boolean {
|
|
78
|
+
return artifact.sourceHash === codeHash || artifact.code === code;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function importPolicyCacheKey(policy: AppRouterImportPolicy | undefined): string {
|
|
82
|
+
if (policy === undefined) {
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return JSON.stringify({
|
|
87
|
+
allowedPackages: [...(policy.allowedPackages ?? [])].sort(),
|
|
88
|
+
allowedSourceDirs: [...(policy.allowedSourceDirs ?? [])].sort(),
|
|
89
|
+
projectRoot: policy.projectRoot ?? "",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function hashText(text: string): string {
|
|
94
|
+
return createHash("sha256").update(text).digest("hex").slice(0, 16);
|
|
95
|
+
}
|
package/src/route-source.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
hasModuleDirective,
|
|
9
9
|
hasTopLevelExportDeclaration,
|
|
10
10
|
stripTopLevelExportDeclarations,
|
|
11
|
+
stripUnusedStaticValueImports,
|
|
11
12
|
} from "@reckona/mreact-compiler";
|
|
12
13
|
import type { StaticImportReference } from "@reckona/mreact-compiler";
|
|
13
14
|
import { sourceModuleCandidates } from "./source-modules.js";
|
|
@@ -44,10 +45,14 @@ export function stripRouteModuleExports(code: string): string {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export function stripRouteClientOnlyExports(code: string): string {
|
|
47
|
-
return
|
|
48
|
-
code
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
return stripUnusedStaticValueImports({
|
|
49
|
+
code: demoteRouteHelperExports(
|
|
50
|
+
stripTopLevelExportDeclarations({
|
|
51
|
+
code,
|
|
52
|
+
names: routeClientOnlyExportNames,
|
|
53
|
+
}),
|
|
54
|
+
),
|
|
55
|
+
});
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
export function stripRouteClientSource(input: {
|
package/src/routes.ts
CHANGED
|
@@ -239,6 +239,10 @@ async function collectRouteFiles(directory: string, rootDirectory = directory):
|
|
|
239
239
|
const path = join(directory, entry.name);
|
|
240
240
|
|
|
241
241
|
if (entry.isDirectory()) {
|
|
242
|
+
if (shouldSkipRouteScanDirectory(entry.name)) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
242
246
|
files.push(...(await collectRouteFiles(path, rootDirectory)));
|
|
243
247
|
continue;
|
|
244
248
|
}
|
|
@@ -257,6 +261,10 @@ async function collectRouteFiles(directory: string, rootDirectory = directory):
|
|
|
257
261
|
return files;
|
|
258
262
|
}
|
|
259
263
|
|
|
264
|
+
function shouldSkipRouteScanDirectory(name: string): boolean {
|
|
265
|
+
return name === ".vite" || name === "node_modules";
|
|
266
|
+
}
|
|
267
|
+
|
|
260
268
|
function appFileConventionForRelativeFile(
|
|
261
269
|
relativeFile: string,
|
|
262
270
|
): ReturnType<typeof appFileConventionForRootFilename> {
|
package/src/serve.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
BuiltServerModuleArtifact,
|
|
9
9
|
} from "./build.js";
|
|
10
10
|
import type { AppRouterCache } from "./cache.js";
|
|
11
|
-
import type { ClientRouteManifestEntry } from "./client.js";
|
|
11
|
+
import type { ClientRouteManifestEntry } from "./client-route-inference.js";
|
|
12
12
|
import { createRouteMatcher, type AppRoute, type RouteMatcher } from "./routes.js";
|
|
13
13
|
import type { AppRouterServerActionOptions } from "./actions.js";
|
|
14
14
|
import type { AppRouterImportPolicy } from "./import-policy.js";
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
requestLogFields,
|
|
32
32
|
type AppRouterLogger,
|
|
33
33
|
} from "./logger.js";
|
|
34
|
+
import { builtAppRuntimePreloadPlan } from "./preload-policy.js";
|
|
34
35
|
import { routeShellCandidates } from "./route-shells.js";
|
|
35
36
|
import { normalizeRoutePath } from "./route-path.js";
|
|
36
37
|
import type { HttpUpgradeHandler } from "./upgrade.js";
|
|
@@ -116,11 +117,32 @@ export interface RenderBuiltAppRequestOptions {
|
|
|
116
117
|
request: Request;
|
|
117
118
|
routeCache?: AppRouterCache | undefined;
|
|
118
119
|
runtimeDir?: string | undefined;
|
|
120
|
+
immutableRuntime?: boolean | undefined;
|
|
119
121
|
serverActions?: AppRouterServerActionOptions | undefined;
|
|
120
122
|
sinkStrategy?: ResponseSinkStrategy;
|
|
121
123
|
preload?: AppRouterRenderPreload | undefined;
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
export interface BuiltRequestRuntimeOptions {
|
|
127
|
+
immutableRuntime?: boolean | undefined;
|
|
128
|
+
importPolicy?: AppRouterImportPolicy | undefined;
|
|
129
|
+
outDir: string;
|
|
130
|
+
runtimeDir?: string | undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export type BuiltRequestRuntimeRenderOptions = Omit<
|
|
134
|
+
RenderBuiltAppRequestOptions,
|
|
135
|
+
"immutableRuntime" | "outDir" | "request" | "runtimeDir"
|
|
136
|
+
>;
|
|
137
|
+
|
|
138
|
+
export interface BuiltRequestRuntime {
|
|
139
|
+
preload(preload?: BuiltAppRuntimePreloadStrategy | undefined): Promise<void>;
|
|
140
|
+
render(
|
|
141
|
+
request: Request,
|
|
142
|
+
options?: BuiltRequestRuntimeRenderOptions | undefined,
|
|
143
|
+
): Promise<Response>;
|
|
144
|
+
}
|
|
145
|
+
|
|
124
146
|
export type BuiltAppRuntimePreloadMode =
|
|
125
147
|
| "all"
|
|
126
148
|
| "hot-route-requests"
|
|
@@ -201,6 +223,40 @@ export interface AppRouterPrerenderStore {
|
|
|
201
223
|
withLock?<T>(path: string, task: () => Promise<T>): Promise<T>;
|
|
202
224
|
}
|
|
203
225
|
|
|
226
|
+
export async function createBuiltRequestRuntime(
|
|
227
|
+
options: BuiltRequestRuntimeOptions,
|
|
228
|
+
): Promise<BuiltRequestRuntime> {
|
|
229
|
+
const runtime = await readBuiltRuntime({
|
|
230
|
+
immutable: options.immutableRuntime,
|
|
231
|
+
outDir: options.outDir,
|
|
232
|
+
runtimeDir: options.runtimeDir,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
preload(preload) {
|
|
237
|
+
return preloadBuiltAppRuntimeWithRuntime({
|
|
238
|
+
importPolicy: options.importPolicy,
|
|
239
|
+
preload,
|
|
240
|
+
runtime,
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
async render(request, renderOptions = {}) {
|
|
244
|
+
const response = await renderBuiltAppRequestWithRuntime({
|
|
245
|
+
...renderOptions,
|
|
246
|
+
importPolicy: renderOptions.importPolicy ?? options.importPolicy,
|
|
247
|
+
outDir: options.outDir,
|
|
248
|
+
request,
|
|
249
|
+
runtime,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return applyBuiltAppResponseHook(response, {
|
|
253
|
+
onResponse: renderOptions.onResponse,
|
|
254
|
+
request,
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
204
260
|
export async function preloadBuiltAppRuntime(options: {
|
|
205
261
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
206
262
|
outDir: string;
|
|
@@ -211,38 +267,57 @@ export async function preloadBuiltAppRuntime(options: {
|
|
|
211
267
|
outDir: options.outDir,
|
|
212
268
|
runtimeDir: options.runtimeDir,
|
|
213
269
|
});
|
|
214
|
-
|
|
270
|
+
await preloadBuiltAppRuntimeWithRuntime({
|
|
271
|
+
importPolicy: options.importPolicy,
|
|
272
|
+
preload: options.preload,
|
|
273
|
+
runtime,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
215
276
|
|
|
216
|
-
|
|
277
|
+
async function preloadBuiltAppRuntimeWithRuntime(options: {
|
|
278
|
+
importPolicy?: AppRouterImportPolicy | undefined;
|
|
279
|
+
preload?: BuiltAppRuntimePreloadStrategy | undefined;
|
|
280
|
+
runtime: BuiltRuntime;
|
|
281
|
+
}): Promise<void> {
|
|
282
|
+
const plan = builtAppRuntimePreloadPlan(options.preload);
|
|
283
|
+
|
|
284
|
+
if (!plan.shouldPreload) {
|
|
217
285
|
return;
|
|
218
286
|
}
|
|
219
287
|
|
|
220
|
-
const routes = builtRuntimePreloadRoutes(runtime,
|
|
221
|
-
if (
|
|
222
|
-
await loadBuiltServerModuleArtifacts(
|
|
288
|
+
const routes = builtRuntimePreloadRoutes(options.runtime, plan);
|
|
289
|
+
if (plan.loadAllArtifacts) {
|
|
290
|
+
await loadBuiltServerModuleArtifacts(
|
|
291
|
+
options.runtime,
|
|
292
|
+
allBuiltServerModuleFiles(options.runtime),
|
|
293
|
+
"all",
|
|
294
|
+
);
|
|
223
295
|
} else {
|
|
224
|
-
await loadBuiltServerModuleArtifactsForRequest(
|
|
225
|
-
|
|
226
|
-
|
|
296
|
+
await loadBuiltServerModuleArtifactsForRequest(
|
|
297
|
+
options.runtime,
|
|
298
|
+
undefined,
|
|
299
|
+
plan.middlewareArtifacts,
|
|
300
|
+
);
|
|
227
301
|
for (const route of routes) {
|
|
228
|
-
await loadBuiltServerModuleArtifactsForRequest(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
302
|
+
await loadBuiltServerModuleArtifactsForRequest(
|
|
303
|
+
options.runtime,
|
|
304
|
+
route.file,
|
|
305
|
+
plan.routeArtifacts,
|
|
306
|
+
);
|
|
232
307
|
}
|
|
233
308
|
}
|
|
234
309
|
await preloadBuiltRequestModules({
|
|
235
|
-
appDir: runtime.appDir,
|
|
310
|
+
appDir: options.runtime.appDir,
|
|
236
311
|
importPolicy: {
|
|
237
312
|
...options.importPolicy,
|
|
238
|
-
allowedSourceDirs: runtime.allowedSourceDirs,
|
|
239
|
-
projectRoot: runtime.projectRoot,
|
|
313
|
+
allowedSourceDirs: options.runtime.allowedSourceDirs,
|
|
314
|
+
projectRoot: options.runtime.projectRoot,
|
|
240
315
|
},
|
|
241
316
|
routes,
|
|
242
|
-
serverModules: runtime.serverModules,
|
|
243
|
-
serverModuleCacheVersion: runtime.serverModuleCacheVersion,
|
|
244
|
-
serverSourceFiles: runtime.serverSourceFiles,
|
|
245
|
-
includeRenderModules:
|
|
317
|
+
serverModules: options.runtime.serverModules,
|
|
318
|
+
serverModuleCacheVersion: options.runtime.serverModuleCacheVersion,
|
|
319
|
+
serverSourceFiles: options.runtime.serverSourceFiles,
|
|
320
|
+
includeRenderModules: plan.includeRenderModules,
|
|
246
321
|
});
|
|
247
322
|
}
|
|
248
323
|
|
|
@@ -275,6 +350,7 @@ export async function renderBuiltAppRequest(
|
|
|
275
350
|
...options,
|
|
276
351
|
runtime: await readBuiltRuntime({
|
|
277
352
|
outDir: options.outDir,
|
|
353
|
+
immutable: options.immutableRuntime,
|
|
278
354
|
runtimeDir: options.runtimeDir,
|
|
279
355
|
}),
|
|
280
356
|
});
|
|
@@ -470,7 +546,10 @@ export async function startServer(
|
|
|
470
546
|
options: StartServerOptions,
|
|
471
547
|
): Promise<{ close(): Promise<void>; server: Server; url: string }> {
|
|
472
548
|
warnIfImplicitHostTrust(options);
|
|
473
|
-
const runtime = await
|
|
549
|
+
const runtime = await createBuiltRequestRuntime({
|
|
550
|
+
importPolicy: options.importPolicy,
|
|
551
|
+
outDir: options.outDir,
|
|
552
|
+
});
|
|
474
553
|
const server = createServer(async (incoming, outgoing) => {
|
|
475
554
|
const startedAt = logNow();
|
|
476
555
|
const fallbackRequestFields = {
|
|
@@ -494,19 +573,15 @@ export async function startServer(
|
|
|
494
573
|
...logFields,
|
|
495
574
|
type: "router:request:start",
|
|
496
575
|
});
|
|
497
|
-
const response = await
|
|
498
|
-
outDir: options.outDir,
|
|
499
|
-
importPolicy: options.importPolicy,
|
|
576
|
+
const response = await runtime.render(request, {
|
|
500
577
|
instrumentation: options.instrumentation,
|
|
501
578
|
logger: options.logger,
|
|
502
579
|
onResponse: options.onResponse,
|
|
503
580
|
prerenderStore: options.prerenderStore,
|
|
504
|
-
request,
|
|
505
581
|
routeCache: options.routeCache,
|
|
506
|
-
runtime,
|
|
507
582
|
serverActions: options.serverActions,
|
|
508
583
|
...(options.sinkStrategy === undefined ? {} : { sinkStrategy: options.sinkStrategy }),
|
|
509
|
-
})
|
|
584
|
+
});
|
|
510
585
|
emitRouterLog(options.logger, "info", {
|
|
511
586
|
...logFields,
|
|
512
587
|
durationMs: logDurationMs(startedAt),
|
|
@@ -632,17 +707,23 @@ async function readBuiltPublicAsset(
|
|
|
632
707
|
}
|
|
633
708
|
|
|
634
709
|
async function readBuiltRuntime(options: {
|
|
710
|
+
immutable?: boolean | undefined;
|
|
635
711
|
outDir: string;
|
|
636
712
|
runtimeDir?: string | undefined;
|
|
637
713
|
}): Promise<BuiltRuntime> {
|
|
638
714
|
const outDir = options.outDir;
|
|
639
715
|
const runtimeDir = options.runtimeDir ?? join(outDir, "server", "runtime");
|
|
716
|
+
const cacheKey = `${outDir}\0${runtimeDir}`;
|
|
717
|
+
const cached = builtRuntimeCache.get(cacheKey);
|
|
718
|
+
|
|
719
|
+
if (options.immutable === true && cached !== undefined) {
|
|
720
|
+
return cached.runtime;
|
|
721
|
+
}
|
|
722
|
+
|
|
640
723
|
const [serverManifestText, clientManifestText] = await Promise.all([
|
|
641
724
|
readFile(join(outDir, "server", "manifest.json"), "utf8"),
|
|
642
725
|
readFile(join(outDir, "client", "manifest.json"), "utf8"),
|
|
643
726
|
]);
|
|
644
|
-
const cacheKey = `${outDir}\0${runtimeDir}`;
|
|
645
|
-
const cached = builtRuntimeCache.get(cacheKey);
|
|
646
727
|
|
|
647
728
|
if (
|
|
648
729
|
cached !== undefined &&
|
package/src/vite.ts
CHANGED
|
@@ -15,16 +15,18 @@ import {
|
|
|
15
15
|
type ResolvedAppRouterProject,
|
|
16
16
|
} from "./config.js";
|
|
17
17
|
import type { AppRouterImportPolicy } from "./import-policy.js";
|
|
18
|
+
import {
|
|
19
|
+
collectClientRouteReferences,
|
|
20
|
+
detectNavigationRuntimeHint,
|
|
21
|
+
isClientRouteSource,
|
|
22
|
+
} from "./client-route-inference.js";
|
|
18
23
|
import {
|
|
19
24
|
buildNavigationRuntimeBundle,
|
|
20
25
|
buildClientRouteBundle,
|
|
21
26
|
buildClientRouteEntrySource,
|
|
22
27
|
clientScriptForPath,
|
|
23
|
-
collectClientRouteReferences,
|
|
24
|
-
detectNavigationRuntimeHint,
|
|
25
|
-
isClientRouteSource,
|
|
26
28
|
navigationRuntimeScriptForDev,
|
|
27
|
-
} from "./
|
|
29
|
+
} from "./navigation-runtime.js";
|
|
28
30
|
import { nodeRequestToWebRequest, sendResponse } from "./http.js";
|
|
29
31
|
import { renderAppRequest } from "./render.js";
|
|
30
32
|
import { stripRouteClientOnlyExports } from "./route-source.js";
|