@reckona/mreact-router 0.0.11 → 0.0.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 +35 -3
- package/dist/adapters/aws-lambda.d.ts +1 -0
- package/dist/adapters/aws-lambda.d.ts.map +1 -1
- package/dist/adapters/aws-lambda.js +77 -1
- package/dist/adapters/aws-lambda.js.map +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/app-router-globals.d.ts +6 -0
- package/dist/app-router-globals.d.ts.map +1 -1
- package/dist/app-router-globals.js.map +1 -1
- package/dist/build.d.ts +2 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +51 -28
- package/dist/build.js.map +1 -1
- package/dist/cli-options.d.ts +17 -0
- package/dist/cli-options.d.ts.map +1 -0
- package/dist/cli-options.js +97 -0
- package/dist/cli-options.js.map +1 -0
- package/dist/cli.js +53 -27
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +36 -2
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -1
- package/dist/dev-server.d.ts +2 -0
- package/dist/dev-server.d.ts.map +1 -1
- package/dist/dev-server.js +24 -0
- package/dist/dev-server.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/module-runner.d.ts.map +1 -1
- package/dist/module-runner.js +16 -3
- package/dist/module-runner.js.map +1 -1
- package/dist/render.d.ts +8 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +263 -10
- package/dist/render.js.map +1 -1
- package/dist/serve.d.ts +6 -0
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +38 -9
- package/dist/serve.js.map +1 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +20 -1
- package/dist/vite.js.map +1 -1
- package/package.json +8 -8
package/dist/render.js
CHANGED
|
@@ -24,13 +24,60 @@ const nativeEscapeTransform = {
|
|
|
24
24
|
};
|
|
25
25
|
const authRuntimeStateKey = "__mreactAuthRuntimeState";
|
|
26
26
|
const authSessionScriptId = "__mreact_auth_session";
|
|
27
|
+
export async function preloadBuiltRequestModules(options) {
|
|
28
|
+
const tasks = [];
|
|
29
|
+
const middlewareFiles = [
|
|
30
|
+
join(options.appDir, "middleware.ts"),
|
|
31
|
+
join(options.appDir, "middleware.mreact.ts"),
|
|
32
|
+
];
|
|
33
|
+
for (const file of middlewareFiles) {
|
|
34
|
+
if (options.serverSourceFiles.has(file)) {
|
|
35
|
+
tasks.push(loadMiddlewareModule({
|
|
36
|
+
appDir: options.appDir,
|
|
37
|
+
file,
|
|
38
|
+
importPolicy: options.importPolicy,
|
|
39
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
40
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const route of options.routes) {
|
|
45
|
+
const code = await readServerSourceFile(route.file, options.serverModuleCacheVersion, options.serverSourceFiles);
|
|
46
|
+
if (route.kind === "server") {
|
|
47
|
+
tasks.push(loadServerRouteModule({
|
|
48
|
+
file: route.file,
|
|
49
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
50
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
51
|
+
}));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (hasLoaderExport(code)) {
|
|
55
|
+
tasks.push(loadRouteLoaderModule({
|
|
56
|
+
appDir: options.appDir,
|
|
57
|
+
code,
|
|
58
|
+
filename: route.file,
|
|
59
|
+
importPolicy: options.importPolicy,
|
|
60
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
await Promise.all(tasks);
|
|
65
|
+
}
|
|
27
66
|
const serverTransformCache = new Map();
|
|
28
67
|
const serverSourceFileCache = new Map();
|
|
29
68
|
const routeSourceAnalysisCache = new Map();
|
|
69
|
+
const routeOutOfOrderBoundaryAnalysisCache = new Map();
|
|
70
|
+
const routeLoaderModuleCache = new Map();
|
|
71
|
+
const middlewareModuleCache = new Map();
|
|
72
|
+
const serverRouteModuleCache = new Map();
|
|
30
73
|
const composedRouteMetadataCache = new Map();
|
|
31
74
|
const maxServerTransformCacheEntries = 512;
|
|
32
75
|
const maxServerSourceFileCacheEntries = 512;
|
|
33
76
|
const maxRouteSourceAnalysisCacheEntries = 512;
|
|
77
|
+
const maxRouteOutOfOrderBoundaryAnalysisCacheEntries = 512;
|
|
78
|
+
const maxRouteLoaderModuleCacheEntries = 512;
|
|
79
|
+
const maxMiddlewareModuleCacheEntries = 64;
|
|
80
|
+
const maxServerRouteModuleCacheEntries = 512;
|
|
34
81
|
const maxComposedRouteMetadataCacheEntries = 512;
|
|
35
82
|
// Issue 086: per-shell prefix/suffix cache. Pure layouts (whose
|
|
36
83
|
// exported component takes zero arguments and therefore cannot
|
|
@@ -62,6 +109,8 @@ async function renderAppRequestInternal(options) {
|
|
|
62
109
|
appDir: options.appDir,
|
|
63
110
|
importPolicy: options.importPolicy,
|
|
64
111
|
request: options.request,
|
|
112
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
113
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
65
114
|
});
|
|
66
115
|
if (middlewareResponse !== undefined) {
|
|
67
116
|
const location = rewriteLocation(middlewareResponse);
|
|
@@ -113,7 +162,13 @@ async function renderAppRequestInternal(options) {
|
|
|
113
162
|
let routeCacheContext;
|
|
114
163
|
try {
|
|
115
164
|
if (matched.route.kind === "server") {
|
|
116
|
-
return await dispatchServerRoute(
|
|
165
|
+
return await dispatchServerRoute({
|
|
166
|
+
file: matched.route.file,
|
|
167
|
+
params: matched.params,
|
|
168
|
+
request: options.request,
|
|
169
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
170
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
171
|
+
});
|
|
117
172
|
}
|
|
118
173
|
// Issue 080: page routes render HTML for GET / HEAD only. Other
|
|
119
174
|
// methods (PUT, PATCH, DELETE, PROPFIND, ...) get 405 with an
|
|
@@ -142,6 +197,7 @@ async function renderAppRequestInternal(options) {
|
|
|
142
197
|
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
143
198
|
});
|
|
144
199
|
const cachePolicy = originalAnalysis.cachePolicy;
|
|
200
|
+
const navigationScript = options.navigationScripts?.get(matched.route.path);
|
|
145
201
|
const cacheKey = routeCacheKey(options.appDir, matched.route.path, url);
|
|
146
202
|
const mayUseRouteCache = cachePolicy === undefined
|
|
147
203
|
? originalAnalysis.usesRuntimeCacheControl
|
|
@@ -185,6 +241,7 @@ async function renderAppRequestInternal(options) {
|
|
|
185
241
|
appDir: options.appDir,
|
|
186
242
|
filename: matched.route.file,
|
|
187
243
|
importPolicy: options.importPolicy,
|
|
244
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
188
245
|
})
|
|
189
246
|
: undefined;
|
|
190
247
|
recoveryRoute = {
|
|
@@ -206,7 +263,13 @@ async function renderAppRequestInternal(options) {
|
|
|
206
263
|
"content-type": "text/html; charset=utf-8",
|
|
207
264
|
"x-mreact-stream": "1",
|
|
208
265
|
};
|
|
209
|
-
|
|
266
|
+
const mayRenderOutOfOrder = await mayRenderOutOfOrderBoundaryDeep({
|
|
267
|
+
code: routeCode,
|
|
268
|
+
filename: matched.route.file,
|
|
269
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
270
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
271
|
+
});
|
|
272
|
+
if (loadingFile === undefined && !mayRenderOutOfOrder) {
|
|
210
273
|
const stringOutput = transformServerModule({
|
|
211
274
|
code: routeCode,
|
|
212
275
|
clientBoundaryImports: clientInference.clientBoundaryImports,
|
|
@@ -282,6 +345,7 @@ async function renderAppRequestInternal(options) {
|
|
|
282
345
|
return withOptionalActionCookie(htmlResponse(`<!DOCTYPE html>${clientNavigationHeadTags({
|
|
283
346
|
assetBaseUrl: options.assetBaseUrl,
|
|
284
347
|
currentScript: clientRoute ? clientScript : undefined,
|
|
348
|
+
currentNavigationScript: clientRoute ? undefined : navigationScript,
|
|
285
349
|
routeScripts: options.clientScripts,
|
|
286
350
|
})}${html}`, { headers }), preparedActions.csrfToken, preparedActions.csrfTokenIsNew === true);
|
|
287
351
|
}
|
|
@@ -429,6 +493,7 @@ async function renderAppRequestInternal(options) {
|
|
|
429
493
|
const response = withOptionalActionCookie(htmlResponse(`<!DOCTYPE html>${clientNavigationHeadTags({
|
|
430
494
|
assetBaseUrl: options.assetBaseUrl,
|
|
431
495
|
currentScript: clientRoute ? clientScript : undefined,
|
|
496
|
+
currentNavigationScript: clientRoute ? undefined : navigationScript,
|
|
432
497
|
routeScripts: options.clientScripts,
|
|
433
498
|
})}${html}`, {
|
|
434
499
|
headers: responseHeadersForMetadata(metadata),
|
|
@@ -519,9 +584,15 @@ function modulePreloadTags(script, assetBaseUrl) {
|
|
|
519
584
|
function clientNavigationHeadTags(options) {
|
|
520
585
|
return [
|
|
521
586
|
modulePreloadTags(options.currentScript, options.assetBaseUrl),
|
|
587
|
+
navigationRuntimeScriptTag(options.currentNavigationScript, options.assetBaseUrl),
|
|
522
588
|
routePrefetchManifestScript(options.routeScripts, options.assetBaseUrl),
|
|
523
589
|
].join("");
|
|
524
590
|
}
|
|
591
|
+
function navigationRuntimeScriptTag(script, assetBaseUrl) {
|
|
592
|
+
return script === undefined
|
|
593
|
+
? ""
|
|
594
|
+
: `<script type="module" src="${escapeHtmlAttribute(assetPath(script, assetBaseUrl ?? "/_mreact/client/"))}"></script>`;
|
|
595
|
+
}
|
|
525
596
|
function routePrefetchManifestScript(routeScripts, assetBaseUrl) {
|
|
526
597
|
if (routeScripts === undefined || routeScripts.size === 0) {
|
|
527
598
|
return "";
|
|
@@ -665,15 +736,15 @@ function normalizeErrorForProps(error) {
|
|
|
665
736
|
}
|
|
666
737
|
return { message: String(error) };
|
|
667
738
|
}
|
|
668
|
-
async function dispatchServerRoute(
|
|
669
|
-
const module = await
|
|
670
|
-
const handler = module[request.method] ?? module.ALL ?? module.default;
|
|
739
|
+
async function dispatchServerRoute(options) {
|
|
740
|
+
const module = await loadServerRouteModule(options);
|
|
741
|
+
const handler = module[options.request.method] ?? module.ALL ?? module.default;
|
|
671
742
|
if (typeof handler !== "function") {
|
|
672
743
|
return new Response("Method Not Allowed", { status: 405 });
|
|
673
744
|
}
|
|
674
745
|
let response;
|
|
675
746
|
try {
|
|
676
|
-
response = await handler(request, { params });
|
|
747
|
+
response = await handler(options.request, { params: options.params });
|
|
677
748
|
}
|
|
678
749
|
catch (error) {
|
|
679
750
|
if (error instanceof Response) {
|
|
@@ -685,6 +756,29 @@ async function dispatchServerRoute(file, request, params) {
|
|
|
685
756
|
? response
|
|
686
757
|
: new Response("Invalid route response", { status: 500 });
|
|
687
758
|
}
|
|
759
|
+
async function loadServerRouteModule(options) {
|
|
760
|
+
if (options.serverModuleCacheVersion === undefined) {
|
|
761
|
+
return await importAppRouterFileModule(options.file);
|
|
762
|
+
}
|
|
763
|
+
const code = await readServerSourceFile(options.file, options.serverModuleCacheVersion, options.serverSourceFiles);
|
|
764
|
+
const cacheKey = `server-route\0${options.file}\0${options.serverModuleCacheVersion}\0${memoizedHashText(code)}`;
|
|
765
|
+
const cached = serverRouteModuleCache.get(cacheKey);
|
|
766
|
+
if (cached !== undefined) {
|
|
767
|
+
return cached;
|
|
768
|
+
}
|
|
769
|
+
const loaded = importAppRouterSourceModule({
|
|
770
|
+
cacheKey,
|
|
771
|
+
code,
|
|
772
|
+
label: `server-route:${options.file}`,
|
|
773
|
+
resolveDir: dirname(options.file),
|
|
774
|
+
sourcefile: options.file,
|
|
775
|
+
}).catch((error) => {
|
|
776
|
+
serverRouteModuleCache.delete(cacheKey);
|
|
777
|
+
throw error;
|
|
778
|
+
});
|
|
779
|
+
setBoundedCacheEntry(serverRouteModuleCache, cacheKey, loaded, maxServerRouteModuleCacheEntries);
|
|
780
|
+
return loaded;
|
|
781
|
+
}
|
|
688
782
|
async function runMiddleware(options) {
|
|
689
783
|
const candidates = [
|
|
690
784
|
join(options.appDir, "middleware.ts"),
|
|
@@ -701,6 +795,8 @@ async function runMiddleware(options) {
|
|
|
701
795
|
appDir: options.appDir,
|
|
702
796
|
file,
|
|
703
797
|
importPolicy: options.importPolicy,
|
|
798
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
799
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
704
800
|
});
|
|
705
801
|
if (!middlewareMatches(module.config, new URL(options.request.url).pathname)) {
|
|
706
802
|
return undefined;
|
|
@@ -729,7 +825,34 @@ async function runMiddleware(options) {
|
|
|
729
825
|
return undefined;
|
|
730
826
|
}
|
|
731
827
|
async function loadMiddlewareModule(options) {
|
|
732
|
-
const code = await
|
|
828
|
+
const code = await readServerSourceFile(options.file, options.serverModuleCacheVersion, options.serverSourceFiles);
|
|
829
|
+
const cacheKey = options.serverModuleCacheVersion === undefined
|
|
830
|
+
? undefined
|
|
831
|
+
: `middleware\0${options.appDir}\0${options.file}\0${options.serverModuleCacheVersion}\0${memoizedHashText(code)}\0${importPolicyCacheKey(options.importPolicy)}`;
|
|
832
|
+
if (cacheKey !== undefined) {
|
|
833
|
+
const cached = middlewareModuleCache.get(cacheKey);
|
|
834
|
+
if (cached !== undefined) {
|
|
835
|
+
return cached;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
const loaded = bundleMiddlewareModule({
|
|
839
|
+
appDir: options.appDir,
|
|
840
|
+
code,
|
|
841
|
+
file: options.file,
|
|
842
|
+
importPolicy: options.importPolicy,
|
|
843
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
844
|
+
}).catch((error) => {
|
|
845
|
+
if (cacheKey !== undefined) {
|
|
846
|
+
middlewareModuleCache.delete(cacheKey);
|
|
847
|
+
}
|
|
848
|
+
throw error;
|
|
849
|
+
});
|
|
850
|
+
if (cacheKey !== undefined) {
|
|
851
|
+
setBoundedCacheEntry(middlewareModuleCache, cacheKey, loaded, maxMiddlewareModuleCacheEntries);
|
|
852
|
+
}
|
|
853
|
+
return loaded;
|
|
854
|
+
}
|
|
855
|
+
async function bundleMiddlewareModule(options) {
|
|
733
856
|
const output = await bundle({
|
|
734
857
|
bundle: true,
|
|
735
858
|
format: "esm",
|
|
@@ -747,7 +870,7 @@ async function loadMiddlewareModule(options) {
|
|
|
747
870
|
jsxFactory: "__mreact_jsx",
|
|
748
871
|
jsxFragment: "__mreact_fragment",
|
|
749
872
|
stdin: {
|
|
750
|
-
contents: code,
|
|
873
|
+
contents: options.code,
|
|
751
874
|
loader: "ts",
|
|
752
875
|
resolveDir: dirname(options.file),
|
|
753
876
|
sourcefile: options.file,
|
|
@@ -758,6 +881,11 @@ async function loadMiddlewareModule(options) {
|
|
|
758
881
|
throw new Error(`Failed to compile middleware for ${options.file}.`);
|
|
759
882
|
}
|
|
760
883
|
return importAppRouterSourceModule({
|
|
884
|
+
...(options.serverModuleCacheVersion === undefined
|
|
885
|
+
? {}
|
|
886
|
+
: {
|
|
887
|
+
cacheKey: `middleware:${options.file}:${options.serverModuleCacheVersion}:${memoizedHashText(compiled)}`,
|
|
888
|
+
}),
|
|
761
889
|
code: compiled,
|
|
762
890
|
label: `middleware:${options.file}`,
|
|
763
891
|
});
|
|
@@ -987,6 +1115,92 @@ function hasOutOfOrderBoundary(code) {
|
|
|
987
1115
|
function mayRenderOutOfOrderBoundary(code) {
|
|
988
1116
|
return (code.includes("<Await") || code.includes("Await(") || code.includes("renderOutOfOrderBoundary"));
|
|
989
1117
|
}
|
|
1118
|
+
async function mayRenderOutOfOrderBoundaryDeep(options) {
|
|
1119
|
+
const seen = new Set();
|
|
1120
|
+
return await mayRenderOutOfOrderBoundaryDeepInner(options, seen);
|
|
1121
|
+
}
|
|
1122
|
+
async function mayRenderOutOfOrderBoundaryDeepInner(options, seen) {
|
|
1123
|
+
if (mayRenderOutOfOrderBoundary(options.code)) {
|
|
1124
|
+
return true;
|
|
1125
|
+
}
|
|
1126
|
+
if (seen.has(options.filename)) {
|
|
1127
|
+
return false;
|
|
1128
|
+
}
|
|
1129
|
+
seen.add(options.filename);
|
|
1130
|
+
const sourceHash = memoizedHashText(options.code);
|
|
1131
|
+
const cacheKey = `${options.serverModuleCacheVersion ?? "dev"}\0${options.filename}\0${sourceHash}`;
|
|
1132
|
+
const cached = routeOutOfOrderBoundaryAnalysisCache.get(cacheKey);
|
|
1133
|
+
if (cached !== undefined) {
|
|
1134
|
+
return cached;
|
|
1135
|
+
}
|
|
1136
|
+
const pending = mayRenderImportedOutOfOrderBoundary(options, seen).catch((error) => {
|
|
1137
|
+
routeOutOfOrderBoundaryAnalysisCache.delete(cacheKey);
|
|
1138
|
+
throw error;
|
|
1139
|
+
});
|
|
1140
|
+
setBoundedCacheEntry(routeOutOfOrderBoundaryAnalysisCache, cacheKey, pending, maxRouteOutOfOrderBoundaryAnalysisCacheEntries);
|
|
1141
|
+
return pending;
|
|
1142
|
+
}
|
|
1143
|
+
async function mayRenderImportedOutOfOrderBoundary(options, seen) {
|
|
1144
|
+
for (const specifier of localModuleSpecifiers(options.code)) {
|
|
1145
|
+
const file = await resolveLocalServerSourceImport(options.filename, specifier);
|
|
1146
|
+
if (file === undefined) {
|
|
1147
|
+
continue;
|
|
1148
|
+
}
|
|
1149
|
+
const code = await readServerSourceFile(file, options.serverModuleCacheVersion, options.serverSourceFiles);
|
|
1150
|
+
if (await mayRenderOutOfOrderBoundaryDeepInner({
|
|
1151
|
+
code,
|
|
1152
|
+
filename: file,
|
|
1153
|
+
serverModuleCacheVersion: options.serverModuleCacheVersion,
|
|
1154
|
+
serverSourceFiles: options.serverSourceFiles,
|
|
1155
|
+
}, seen)) {
|
|
1156
|
+
return true;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1161
|
+
function localModuleSpecifiers(code) {
|
|
1162
|
+
const specifiers = new Set();
|
|
1163
|
+
const importPattern = /\b(?:import|export)\s+(?:type\s+)?(?:[^"']*?\s+from\s*)?["'](?<source>\.{1,2}\/[^"']+)["']/g;
|
|
1164
|
+
for (const match of code.matchAll(importPattern)) {
|
|
1165
|
+
const source = match.groups?.source;
|
|
1166
|
+
if (source !== undefined) {
|
|
1167
|
+
specifiers.add(source);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return Array.from(specifiers);
|
|
1171
|
+
}
|
|
1172
|
+
async function resolveLocalServerSourceImport(fromFile, specifier) {
|
|
1173
|
+
const base = join(dirname(fromFile), specifier);
|
|
1174
|
+
const candidates = localServerSourceImportCandidates(base);
|
|
1175
|
+
for (const candidate of candidates) {
|
|
1176
|
+
try {
|
|
1177
|
+
await access(candidate);
|
|
1178
|
+
return candidate;
|
|
1179
|
+
}
|
|
1180
|
+
catch {
|
|
1181
|
+
// Try the next TypeScript route/source extension.
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return undefined;
|
|
1185
|
+
}
|
|
1186
|
+
function localServerSourceImportCandidates(base) {
|
|
1187
|
+
const candidates = [base];
|
|
1188
|
+
if (base.endsWith(".js")) {
|
|
1189
|
+
const withoutJs = base.slice(0, -".js".length);
|
|
1190
|
+
candidates.push(`${withoutJs}.ts`, `${withoutJs}.tsx`, `${withoutJs}.mreact.tsx`);
|
|
1191
|
+
}
|
|
1192
|
+
else if (base.endsWith(".jsx")) {
|
|
1193
|
+
const withoutJsx = base.slice(0, -".jsx".length);
|
|
1194
|
+
candidates.push(`${withoutJsx}.tsx`, `${withoutJsx}.mreact.tsx`);
|
|
1195
|
+
}
|
|
1196
|
+
else if (base.endsWith(".mreact")) {
|
|
1197
|
+
candidates.push(`${base}.tsx`);
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
candidates.push(`${base}.ts`, `${base}.tsx`, `${base}.mreact.tsx`, join(base, "index.ts"), join(base, "index.tsx"), join(base, "index.mreact.tsx"));
|
|
1201
|
+
}
|
|
1202
|
+
return candidates;
|
|
1203
|
+
}
|
|
990
1204
|
async function runServerStreamModuleWithLoading(code, options) {
|
|
991
1205
|
const loadingProps = {
|
|
992
1206
|
data: undefined,
|
|
@@ -1338,6 +1552,31 @@ async function loadRouteData(options) {
|
|
|
1338
1552
|
if (!hasLoaderExport(options.code)) {
|
|
1339
1553
|
return undefined;
|
|
1340
1554
|
}
|
|
1555
|
+
const module = await loadRouteLoaderModule(options);
|
|
1556
|
+
return module.loader === undefined ? undefined : await module.loader(options.context);
|
|
1557
|
+
}
|
|
1558
|
+
async function loadRouteLoaderModule(options) {
|
|
1559
|
+
const cacheKey = options.serverModuleCacheVersion === undefined
|
|
1560
|
+
? undefined
|
|
1561
|
+
: `${options.appDir}\0${options.filename}\0${options.serverModuleCacheVersion}\0${memoizedHashText(options.code)}\0${importPolicyCacheKey(options.importPolicy)}`;
|
|
1562
|
+
if (cacheKey !== undefined) {
|
|
1563
|
+
const cached = routeLoaderModuleCache.get(cacheKey);
|
|
1564
|
+
if (cached !== undefined) {
|
|
1565
|
+
return cached;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
const loaded = bundleRouteLoaderModule(options).catch((error) => {
|
|
1569
|
+
if (cacheKey !== undefined) {
|
|
1570
|
+
routeLoaderModuleCache.delete(cacheKey);
|
|
1571
|
+
}
|
|
1572
|
+
throw error;
|
|
1573
|
+
});
|
|
1574
|
+
if (cacheKey !== undefined) {
|
|
1575
|
+
setBoundedCacheEntry(routeLoaderModuleCache, cacheKey, loaded, maxRouteLoaderModuleCacheEntries);
|
|
1576
|
+
}
|
|
1577
|
+
return loaded;
|
|
1578
|
+
}
|
|
1579
|
+
async function bundleRouteLoaderModule(options) {
|
|
1341
1580
|
const output = await bundle({
|
|
1342
1581
|
bundle: true,
|
|
1343
1582
|
format: "esm",
|
|
@@ -1365,11 +1604,25 @@ async function loadRouteData(options) {
|
|
|
1365
1604
|
if (code === undefined) {
|
|
1366
1605
|
throw new Error(`Failed to compile loader for ${options.filename}.`);
|
|
1367
1606
|
}
|
|
1368
|
-
|
|
1607
|
+
return await importAppRouterSourceModule({
|
|
1608
|
+
...(options.serverModuleCacheVersion === undefined
|
|
1609
|
+
? {}
|
|
1610
|
+
: {
|
|
1611
|
+
cacheKey: `loader:${options.filename}:${options.serverModuleCacheVersion}:${memoizedHashText(code)}`,
|
|
1612
|
+
}),
|
|
1369
1613
|
code,
|
|
1370
1614
|
label: `loader:${options.filename}`,
|
|
1371
1615
|
});
|
|
1372
|
-
|
|
1616
|
+
}
|
|
1617
|
+
function importPolicyCacheKey(policy) {
|
|
1618
|
+
if (policy === undefined) {
|
|
1619
|
+
return "";
|
|
1620
|
+
}
|
|
1621
|
+
return JSON.stringify({
|
|
1622
|
+
allowedPackages: [...(policy.allowedPackages ?? [])].sort(),
|
|
1623
|
+
allowedSourceDirs: [...(policy.allowedSourceDirs ?? [])].sort(),
|
|
1624
|
+
projectRoot: policy.projectRoot ?? "",
|
|
1625
|
+
});
|
|
1373
1626
|
}
|
|
1374
1627
|
async function loadRouteMetadata(options) {
|
|
1375
1628
|
if (!hasMetadataExport(options.code)) {
|