vinext 0.0.45 → 0.0.47
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 +7 -5
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +80 -17
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +1 -1
- package/dist/build/route-classification-injector.d.ts +35 -0
- package/dist/build/route-classification-injector.js +61 -0
- package/dist/build/route-classification-injector.js.map +1 -0
- package/dist/build/route-classification-manifest.d.ts +1 -1
- package/dist/build/standalone.js +4 -3
- package/dist/build/standalone.js.map +1 -1
- package/dist/build/static-export.d.ts +1 -1
- package/dist/check.js +30 -18
- package/dist/check.js.map +1 -1
- package/dist/cli-args.d.ts +31 -0
- package/dist/cli-args.js +104 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli.js +6 -19
- package/dist/cli.js.map +1 -1
- package/dist/cloudflare/kv-cache-handler.js +29 -9
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/config/config-matchers.js +1 -0
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +42 -4
- package/dist/config/next-config.js +27 -0
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +18 -23
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +4 -3
- package/dist/entries/app-rsc-entry.js +435 -2317
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +24 -0
- package/dist/entries/app-rsc-manifest.js +155 -0
- package/dist/entries/app-rsc-manifest.js.map +1 -0
- package/dist/entries/pages-server-entry.js +18 -105
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.js +82 -85
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.js +54 -32
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/rsc-client-shim-excludes.d.ts +6 -0
- package/dist/plugins/rsc-client-shim-excludes.js +28 -0
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +109 -0
- package/dist/routing/app-route-graph.js +819 -0
- package/dist/routing/app-route-graph.js.map +1 -0
- package/dist/routing/app-router.d.ts +2 -79
- package/dist/routing/app-router.js +7 -621
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/route-pattern.d.ts +9 -0
- package/dist/routing/route-pattern.js +90 -0
- package/dist/routing/route-pattern.js.map +1 -0
- package/dist/routing/route-trie.js +10 -11
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/server/app-browser-entry.js +94 -232
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.d.ts +3 -4
- package/dist/server/app-browser-error.js +8 -4
- package/dist/server/app-browser-error.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +73 -0
- package/dist/server/app-browser-navigation-controller.js +282 -0
- package/dist/server/app-browser-navigation-controller.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +1 -1
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-elements.js +1 -5
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +57 -0
- package/dist/server/app-fallback-renderer.js +79 -0
- package/dist/server/app-fallback-renderer.js.map +1 -0
- package/dist/server/app-hook-warning-suppression.d.ts +7 -0
- package/dist/server/app-hook-warning-suppression.js +12 -0
- package/dist/server/app-hook-warning-suppression.js.map +1 -0
- package/dist/server/app-middleware.d.ts +32 -0
- package/dist/server/app-middleware.js +147 -0
- package/dist/server/app-middleware.js.map +1 -0
- package/dist/server/app-mounted-slots-header.d.ts +17 -0
- package/dist/server/app-mounted-slots-header.js +21 -0
- package/dist/server/app-mounted-slots-header.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +4 -2
- package/dist/server/app-page-boundary-render.js +50 -30
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +12 -1
- package/dist/server/app-page-boundary.js +27 -12
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +22 -5
- package/dist/server/app-page-cache.js +90 -11
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +123 -0
- package/dist/server/app-page-dispatch.js +348 -0
- package/dist/server/app-page-dispatch.js.map +1 -0
- package/dist/server/app-page-element-builder.d.ts +61 -0
- package/dist/server/app-page-element-builder.js +139 -0
- package/dist/server/app-page-element-builder.js.map +1 -0
- package/dist/server/app-page-execution.d.ts +4 -3
- package/dist/server/app-page-execution.js +5 -8
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +55 -0
- package/dist/server/app-page-head.js +196 -0
- package/dist/server/app-page-head.js.map +1 -0
- package/dist/server/app-page-method.d.ts +16 -0
- package/dist/server/app-page-method.js +30 -0
- package/dist/server/app-page-method.js.map +1 -0
- package/dist/server/app-page-params.d.ts +8 -0
- package/dist/server/app-page-params.js +28 -0
- package/dist/server/app-page-params.js.map +1 -0
- package/dist/server/app-page-render.d.ts +7 -2
- package/dist/server/app-page-render.js +131 -32
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +23 -8
- package/dist/server/app-page-request.js +51 -6
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +1 -0
- package/dist/server/app-page-response.js +3 -7
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +29 -5
- package/dist/server/app-page-route-wiring.js +30 -8
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +10 -0
- package/dist/server/app-page-stream.js +5 -1
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-post-middleware-context.d.ts +16 -0
- package/dist/server/app-post-middleware-context.js +28 -0
- package/dist/server/app-post-middleware-context.js.map +1 -0
- package/dist/server/app-prerender-endpoints.d.ts +19 -0
- package/dist/server/app-prerender-endpoints.js +96 -0
- package/dist/server/app-prerender-endpoints.js.map +1 -0
- package/dist/server/app-prerender-static-params.d.ts +16 -0
- package/dist/server/app-prerender-static-params.js +14 -0
- package/dist/server/app-prerender-static-params.js.map +1 -0
- package/dist/server/app-request-context.d.ts +22 -0
- package/dist/server/app-request-context.js +30 -0
- package/dist/server/app-request-context.js.map +1 -0
- package/dist/server/app-route-handler-cache.d.ts +4 -0
- package/dist/server/app-route-handler-cache.js +11 -3
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +43 -0
- package/dist/server/app-route-handler-dispatch.js +149 -0
- package/dist/server/app-route-handler-dispatch.js.map +1 -0
- package/dist/server/app-route-handler-execution.d.ts +8 -3
- package/dist/server/app-route-handler-execution.js +25 -4
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.d.ts +6 -3
- package/dist/server/app-route-handler-response.js +52 -11
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +107 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-error-handler.d.ts +21 -0
- package/dist/server/app-rsc-error-handler.js +30 -0
- package/dist/server/app-rsc-error-handler.js.map +1 -0
- package/dist/server/app-rsc-errors.d.ts +27 -0
- package/dist/server/app-rsc-errors.js +42 -0
- package/dist/server/app-rsc-errors.js.map +1 -0
- package/dist/server/app-rsc-handler.d.ts +117 -0
- package/dist/server/app-rsc-handler.js +260 -0
- package/dist/server/app-rsc-handler.js.map +1 -0
- package/dist/server/app-rsc-request-normalization.d.ts +40 -0
- package/dist/server/app-rsc-request-normalization.js +63 -0
- package/dist/server/app-rsc-request-normalization.js.map +1 -0
- package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
- package/dist/server/app-rsc-response-finalizer.js +38 -0
- package/dist/server/app-rsc-response-finalizer.js.map +1 -0
- package/dist/server/app-rsc-route-matching.d.ts +40 -0
- package/dist/server/app-rsc-route-matching.js +66 -0
- package/dist/server/app-rsc-route-matching.js.map +1 -0
- package/dist/server/app-segment-config.d.ts +33 -0
- package/dist/server/app-segment-config.js +86 -0
- package/dist/server/app-segment-config.js.map +1 -0
- package/dist/server/app-server-action-execution.d.ts +88 -1
- package/dist/server/app-server-action-execution.js +257 -5
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +7 -0
- package/dist/server/app-ssr-entry.js +30 -9
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +4 -2
- package/dist/server/app-ssr-stream.js +29 -2
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.d.ts +15 -0
- package/dist/server/app-static-generation.js +20 -0
- package/dist/server/app-static-generation.js.map +1 -0
- package/dist/server/cache-control.d.ts +24 -0
- package/dist/server/cache-control.js +33 -0
- package/dist/server/cache-control.js.map +1 -0
- package/dist/server/dev-error-overlay-store.d.ts +23 -0
- package/dist/server/dev-error-overlay-store.js +67 -0
- package/dist/server/dev-error-overlay-store.js.map +1 -0
- package/dist/server/dev-error-overlay.d.ts +15 -0
- package/dist/server/dev-error-overlay.js +548 -0
- package/dist/server/dev-error-overlay.js.map +1 -0
- package/dist/server/dev-route-files.d.ts +7 -0
- package/dist/server/dev-route-files.js +73 -0
- package/dist/server/dev-route-files.js.map +1 -0
- package/dist/server/dev-server.js +4 -0
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.d.ts +17 -0
- package/dist/server/file-based-metadata.js +356 -0
- package/dist/server/file-based-metadata.js.map +1 -0
- package/dist/server/implicit-tags.d.ts +6 -0
- package/dist/server/implicit-tags.js +42 -0
- package/dist/server/implicit-tags.js.map +1 -0
- package/dist/server/instrumentation-runtime.d.ts +44 -0
- package/dist/server/instrumentation-runtime.js +29 -0
- package/dist/server/instrumentation-runtime.js.map +1 -0
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +16 -3
- package/dist/server/isr-cache.js +56 -8
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-build-data.d.ts +25 -0
- package/dist/server/metadata-route-build-data.js +150 -0
- package/dist/server/metadata-route-build-data.js.map +1 -0
- package/dist/server/metadata-route-response.d.ts +17 -0
- package/dist/server/metadata-route-response.js +187 -0
- package/dist/server/metadata-route-response.js.map +1 -0
- package/dist/server/metadata-routes.d.ts +42 -4
- package/dist/server/metadata-routes.js +127 -11
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.d.ts +15 -0
- package/dist/server/middleware-matcher.js +102 -0
- package/dist/server/middleware-matcher.js.map +1 -0
- package/dist/server/middleware-request-headers.js +2 -1
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +39 -0
- package/dist/server/middleware-runtime.js +159 -0
- package/dist/server/middleware-runtime.js.map +1 -0
- package/dist/server/middleware.d.ts +4 -36
- package/dist/server/middleware.js +18 -228
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +7 -2
- package/dist/server/pages-page-data.js +10 -5
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +2 -1
- package/dist/server/pages-page-response.js +5 -3
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-work-unit-setup.d.ts +7 -0
- package/dist/server/prerender-work-unit-setup.js +30 -0
- package/dist/server/prerender-work-unit-setup.js.map +1 -0
- package/dist/server/prod-server.js +10 -14
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +46 -5
- package/dist/server/request-pipeline.js +84 -5
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.d.ts +7 -0
- package/dist/server/rsc-stream-hints.js +38 -0
- package/dist/server/rsc-stream-hints.js.map +1 -0
- package/dist/server/seed-cache.js +19 -8
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.d.ts +9 -0
- package/dist/server/server-action-not-found.js +40 -0
- package/dist/server/server-action-not-found.js.map +1 -0
- package/dist/shims/cache-runtime.js +28 -11
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +39 -4
- package/dist/shims/cache.js +93 -16
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +66 -5
- package/dist/shims/error-boundary.js +106 -4
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +4 -1
- package/dist/shims/fetch-cache.js +55 -13
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +5 -4
- package/dist/shims/font-google-base.js +61 -13
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/headers.d.ts +14 -2
- package/dist/shims/headers.js +127 -17
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.js +116 -10
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/make-hanging-promise.d.ts +16 -0
- package/dist/shims/internal/make-hanging-promise.js +46 -0
- package/dist/shims/internal/make-hanging-promise.js.map +1 -0
- package/dist/shims/internal/work-unit-async-storage.d.ts +26 -3
- package/dist/shims/internal/work-unit-async-storage.js +6 -3
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/metadata.d.ts +38 -26
- package/dist/shims/metadata.js +75 -45
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +10 -1
- package/dist/shims/navigation.js +18 -1
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +2 -2
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/offline.d.ts +5 -0
- package/dist/shims/offline.js +17 -0
- package/dist/shims/offline.js.map +1 -0
- package/dist/shims/request-state-types.d.ts +3 -2
- package/dist/shims/root-params.d.ts +11 -0
- package/dist/shims/root-params.js +24 -0
- package/dist/shims/root-params.js.map +1 -0
- package/dist/shims/router.js +1 -1
- package/dist/shims/server.d.ts +3 -1
- package/dist/shims/server.js +83 -5
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/thenable-params.d.ts +5 -0
- package/dist/shims/thenable-params.js +37 -0
- package/dist/shims/thenable-params.js.map +1 -0
- package/dist/shims/unified-request-context.d.ts +3 -2
- package/dist/shims/unified-request-context.js +3 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/use-merged-ref.d.ts +7 -0
- package/dist/shims/use-merged-ref.js +40 -0
- package/dist/shims/use-merged-ref.js.map +1 -0
- package/dist/utils/cache-control-metadata.d.ts +6 -0
- package/dist/utils/cache-control-metadata.js +16 -0
- package/dist/utils/cache-control-metadata.js.map +1 -0
- package/package.json +6 -1
- package/dist/server/middleware-codegen.d.ts +0 -54
- package/dist/server/middleware-codegen.js +0 -414
- package/dist/server/middleware-codegen.js.map +0 -1
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getDraftModeCookieHeader, markDynamicUsage, setHeadersContext } from "../shims/headers.js";
|
|
4
|
+
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache.js";
|
|
5
|
+
import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
6
|
+
import { createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
7
|
+
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
8
|
+
import { resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
|
|
9
|
+
import { readAppPageCacheResponse } from "./app-page-cache.js";
|
|
10
|
+
import { buildAppPageSpecialErrorResponse, readAppPageTextStream, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
11
|
+
import { resolveAppPageMethodResponse } from "./app-page-method.js";
|
|
12
|
+
import { buildAppPageElement, resolveAppPageIntercept, validateAppPageDynamicParams } from "./app-page-request.js";
|
|
13
|
+
import { renderAppPageLifecycle } from "./app-page-render.js";
|
|
14
|
+
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
15
|
+
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
16
|
+
//#region src/server/app-page-dispatch.ts
|
|
17
|
+
function shouldReadAppPageCache(options) {
|
|
18
|
+
return options.isProduction && !options.isForceDynamic && (options.isRscRequest || !options.scriptNonce) && (options.revalidateSeconds === null || options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity);
|
|
19
|
+
}
|
|
20
|
+
function buildAppPageTags(cleanPathname, extraTags, routeSegments) {
|
|
21
|
+
return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], "page");
|
|
22
|
+
}
|
|
23
|
+
async function runAppPageRevalidationContext(options, renderFn) {
|
|
24
|
+
return runWithRequestContext(createRequestContext({
|
|
25
|
+
headersContext: createStaticGenerationHeadersContext({
|
|
26
|
+
dynamicConfig: options.dynamicConfig,
|
|
27
|
+
routeKind: "page",
|
|
28
|
+
routePattern: options.routePattern
|
|
29
|
+
}),
|
|
30
|
+
currentFetchCacheMode: options.currentFetchCacheMode ?? null,
|
|
31
|
+
executionContext: getRequestExecutionContext(),
|
|
32
|
+
unstableCacheRevalidation: "foreground"
|
|
33
|
+
}), async () => {
|
|
34
|
+
ensureFetchPatch();
|
|
35
|
+
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
|
|
36
|
+
options.setNavigationContext({
|
|
37
|
+
pathname: options.cleanPathname,
|
|
38
|
+
searchParams: new URLSearchParams(),
|
|
39
|
+
params: options.params
|
|
40
|
+
});
|
|
41
|
+
return renderFn();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function getCapturedRscDataPromise(capturedRscDataPromise) {
|
|
45
|
+
if (!capturedRscDataPromise) throw new Error("[vinext] Expected captured RSC data while regenerating an app page cache entry");
|
|
46
|
+
return capturedRscDataPromise;
|
|
47
|
+
}
|
|
48
|
+
function toInterceptOptions(interceptionContext, intercept) {
|
|
49
|
+
return {
|
|
50
|
+
interceptionContext,
|
|
51
|
+
interceptLayouts: intercept.interceptLayouts,
|
|
52
|
+
interceptPage: intercept.page,
|
|
53
|
+
interceptParams: intercept.matchedParams,
|
|
54
|
+
interceptSlotKey: intercept.slotKey
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function dispatchAppPage(options) {
|
|
58
|
+
const route = options.route;
|
|
59
|
+
const dynamicConfig = options.dynamicConfig;
|
|
60
|
+
const currentRevalidateSeconds = options.revalidateSeconds;
|
|
61
|
+
const isForceStatic = dynamicConfig === "force-static";
|
|
62
|
+
const isDynamicError = dynamicConfig === "error";
|
|
63
|
+
const isForceDynamic = dynamicConfig === "force-dynamic";
|
|
64
|
+
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
|
|
65
|
+
setCurrentFetchCacheMode(options.fetchCache ?? null);
|
|
66
|
+
if (options.hasPageModule && !options.hasPageDefaultExport) {
|
|
67
|
+
options.clearRequestContext();
|
|
68
|
+
return new Response("Page has no default export", { status: 500 });
|
|
69
|
+
}
|
|
70
|
+
const methodResponse = resolveAppPageMethodResponse({
|
|
71
|
+
dynamicConfig,
|
|
72
|
+
hasGenerateStaticParams: options.hasGenerateStaticParams,
|
|
73
|
+
isDynamicRoute: route.isDynamic,
|
|
74
|
+
middlewareHeaders: options.middlewareContext.headers,
|
|
75
|
+
request: options.request,
|
|
76
|
+
revalidateSeconds: currentRevalidateSeconds
|
|
77
|
+
});
|
|
78
|
+
if (methodResponse) {
|
|
79
|
+
options.clearRequestContext();
|
|
80
|
+
return methodResponse;
|
|
81
|
+
}
|
|
82
|
+
if (isForceStatic || isDynamicError) {
|
|
83
|
+
setHeadersContext(createStaticGenerationHeadersContext({
|
|
84
|
+
dynamicConfig,
|
|
85
|
+
routeKind: "page",
|
|
86
|
+
routePattern: route.pattern
|
|
87
|
+
}));
|
|
88
|
+
options.setNavigationContext({
|
|
89
|
+
pathname: options.cleanPathname,
|
|
90
|
+
searchParams: new URLSearchParams(),
|
|
91
|
+
params: options.params
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (shouldReadAppPageCache({
|
|
95
|
+
isForceDynamic,
|
|
96
|
+
isProduction: options.isProduction,
|
|
97
|
+
isRscRequest: options.isRscRequest,
|
|
98
|
+
revalidateSeconds: currentRevalidateSeconds,
|
|
99
|
+
scriptNonce: options.scriptNonce
|
|
100
|
+
})) {
|
|
101
|
+
const cachedPageResponse = await readAppPageCacheResponse({
|
|
102
|
+
cleanPathname: options.cleanPathname,
|
|
103
|
+
clearRequestContext: options.clearRequestContext,
|
|
104
|
+
isRscRequest: options.isRscRequest,
|
|
105
|
+
isrDebug: options.isrDebug,
|
|
106
|
+
isrGet: options.isrGet,
|
|
107
|
+
isrHtmlKey: options.isrHtmlKey,
|
|
108
|
+
isrRscKey: options.isrRscKey,
|
|
109
|
+
isrSet: options.isrSet,
|
|
110
|
+
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
111
|
+
expireSeconds: options.expireSeconds,
|
|
112
|
+
revalidateSeconds: currentRevalidateSeconds ?? 0,
|
|
113
|
+
renderFreshPageForCache: async () => runAppPageRevalidationContext({
|
|
114
|
+
cleanPathname: options.cleanPathname,
|
|
115
|
+
currentFetchCacheMode: options.fetchCache ?? null,
|
|
116
|
+
dynamicConfig,
|
|
117
|
+
params: options.params,
|
|
118
|
+
routePattern: route.pattern,
|
|
119
|
+
routeSegments: route.routeSegments,
|
|
120
|
+
setNavigationContext: options.setNavigationContext
|
|
121
|
+
}, async () => {
|
|
122
|
+
const revalidatedElement = await options.buildPageElement(route, options.params, void 0, new URLSearchParams());
|
|
123
|
+
const revalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, route.pattern);
|
|
124
|
+
const revalidatedRscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(revalidatedElement, { onError: revalidatedOnError }), true);
|
|
125
|
+
const revalidatedSsrEntry = await options.loadSsrHandler();
|
|
126
|
+
const revalidatedCapturedRscRef = { value: null };
|
|
127
|
+
const html = await readAppPageTextStream(await revalidatedSsrEntry.handleSsr(revalidatedRscCapture.ssrStream, options.getNavigationContext(), {
|
|
128
|
+
links: options.getFontLinks(),
|
|
129
|
+
styles: options.getFontStyles(),
|
|
130
|
+
preloads: options.getFontPreloads()
|
|
131
|
+
}, revalidatedRscCapture.sideStream ? {
|
|
132
|
+
sideStream: revalidatedRscCapture.sideStream,
|
|
133
|
+
capturedRscDataRef: revalidatedCapturedRscRef
|
|
134
|
+
} : void 0));
|
|
135
|
+
const rscData = await getCapturedRscDataPromise(revalidatedCapturedRscRef.value);
|
|
136
|
+
const cacheLife = _consumeRequestScopedCacheLife();
|
|
137
|
+
options.clearRequestContext();
|
|
138
|
+
return {
|
|
139
|
+
html,
|
|
140
|
+
rscData,
|
|
141
|
+
tags: buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), route.routeSegments),
|
|
142
|
+
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
143
|
+
revalidate: cacheLife.revalidate,
|
|
144
|
+
expire: cacheLife.expire
|
|
145
|
+
} : void 0
|
|
146
|
+
};
|
|
147
|
+
}),
|
|
148
|
+
scheduleBackgroundRegeneration(key, renderFn) {
|
|
149
|
+
options.scheduleBackgroundRegeneration(key, renderFn, {
|
|
150
|
+
routerKind: "App Router",
|
|
151
|
+
routePath: route.pattern,
|
|
152
|
+
routeType: "render"
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
if (cachedPageResponse) return cachedPageResponse;
|
|
157
|
+
}
|
|
158
|
+
const dynamicParamsResponse = await validateAppPageDynamicParams({
|
|
159
|
+
clearRequestContext: options.clearRequestContext,
|
|
160
|
+
enforceStaticParamsOnly: options.dynamicParamsConfig === false,
|
|
161
|
+
generateStaticParams: options.generateStaticParams,
|
|
162
|
+
isDynamicRoute: route.isDynamic,
|
|
163
|
+
logGenerateStaticParamsError(error) {
|
|
164
|
+
console.error("[vinext] generateStaticParams error:", error);
|
|
165
|
+
},
|
|
166
|
+
params: options.params
|
|
167
|
+
});
|
|
168
|
+
if (dynamicParamsResponse) return dynamicParamsResponse;
|
|
169
|
+
const interceptResult = await resolveAppPageIntercept({
|
|
170
|
+
buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams) {
|
|
171
|
+
setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
|
|
172
|
+
return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams);
|
|
173
|
+
},
|
|
174
|
+
cleanPathname: options.cleanPathname,
|
|
175
|
+
currentRoute: route,
|
|
176
|
+
findIntercept(pathname) {
|
|
177
|
+
return options.findIntercept(pathname);
|
|
178
|
+
},
|
|
179
|
+
getRouteParamNames(sourceRoute) {
|
|
180
|
+
return sourceRoute.params;
|
|
181
|
+
},
|
|
182
|
+
getSourceRoute(sourceRouteIndex) {
|
|
183
|
+
return options.getSourceRoute(sourceRouteIndex);
|
|
184
|
+
},
|
|
185
|
+
isRscRequest: options.isRscRequest,
|
|
186
|
+
renderInterceptResponse(sourceRoute, interceptElement) {
|
|
187
|
+
const interceptOnError = options.createRscOnErrorHandler(options.cleanPathname, sourceRoute.pattern);
|
|
188
|
+
const interceptStream = options.renderToReadableStream(interceptElement, { onError: interceptOnError });
|
|
189
|
+
const interceptHeaders = new Headers({
|
|
190
|
+
"Content-Type": "text/x-component; charset=utf-8",
|
|
191
|
+
Vary: "RSC, Accept"
|
|
192
|
+
});
|
|
193
|
+
mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);
|
|
194
|
+
return new Response(interceptStream, {
|
|
195
|
+
status: options.middlewareContext.status ?? 200,
|
|
196
|
+
headers: interceptHeaders
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
searchParams: options.searchParams,
|
|
200
|
+
setNavigationContext: options.setNavigationContext,
|
|
201
|
+
toInterceptOpts(intercept) {
|
|
202
|
+
return toInterceptOptions(options.interceptionContext, intercept);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
if (interceptResult.response) return interceptResult.response;
|
|
206
|
+
const pageBuildResult = await buildAppPageElement({
|
|
207
|
+
buildPageElement() {
|
|
208
|
+
return options.buildPageElement(route, options.params, interceptResult.interceptOpts, options.searchParams);
|
|
209
|
+
},
|
|
210
|
+
renderErrorBoundaryPage(buildError) {
|
|
211
|
+
return options.renderErrorBoundaryPage(buildError);
|
|
212
|
+
},
|
|
213
|
+
renderSpecialError(specialError) {
|
|
214
|
+
return renderPageSpecialError(options, specialError);
|
|
215
|
+
},
|
|
216
|
+
resolveSpecialError: resolveAppPageSpecialError
|
|
217
|
+
});
|
|
218
|
+
if (pageBuildResult.response) return pageBuildResult.response;
|
|
219
|
+
return renderAppPageLifecycle({
|
|
220
|
+
cleanPathname: options.cleanPathname,
|
|
221
|
+
clearRequestContext: options.clearRequestContext,
|
|
222
|
+
consumeDynamicUsage,
|
|
223
|
+
consumeInvalidDynamicUsageError,
|
|
224
|
+
createRscOnErrorHandler(pathname, routePath) {
|
|
225
|
+
return options.createRscOnErrorHandler(pathname, routePath);
|
|
226
|
+
},
|
|
227
|
+
element: pageBuildResult.element,
|
|
228
|
+
getDraftModeCookieHeader,
|
|
229
|
+
getFontLinks: options.getFontLinks,
|
|
230
|
+
getFontPreloads: options.getFontPreloads,
|
|
231
|
+
getFontStyles: options.getFontStyles,
|
|
232
|
+
getNavigationContext: options.getNavigationContext,
|
|
233
|
+
getPageTags() {
|
|
234
|
+
return buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), route.routeSegments);
|
|
235
|
+
},
|
|
236
|
+
getRequestCacheLife() {
|
|
237
|
+
return _consumeRequestScopedCacheLife();
|
|
238
|
+
},
|
|
239
|
+
peekRequestCacheLife() {
|
|
240
|
+
return _peekRequestScopedCacheLife();
|
|
241
|
+
},
|
|
242
|
+
handlerStart: options.handlerStart,
|
|
243
|
+
hasLoadingBoundary: Boolean(route.loading?.default),
|
|
244
|
+
isDynamicError,
|
|
245
|
+
isForceDynamic,
|
|
246
|
+
isForceStatic,
|
|
247
|
+
isPrerender: process.env.VINEXT_PRERENDER === "1",
|
|
248
|
+
isProduction: options.isProduction,
|
|
249
|
+
isRscRequest: options.isRscRequest,
|
|
250
|
+
isrDebug: options.isrDebug,
|
|
251
|
+
isrHtmlKey: options.isrHtmlKey,
|
|
252
|
+
isrRscKey: options.isrRscKey,
|
|
253
|
+
isrSet: options.isrSet,
|
|
254
|
+
expireSeconds: options.expireSeconds,
|
|
255
|
+
layoutCount: route.layouts.length,
|
|
256
|
+
loadSsrHandler: options.loadSsrHandler,
|
|
257
|
+
middlewareContext: options.middlewareContext,
|
|
258
|
+
params: options.params,
|
|
259
|
+
probeLayoutAt(layoutIndex) {
|
|
260
|
+
return options.probeLayoutAt(layoutIndex);
|
|
261
|
+
},
|
|
262
|
+
probePage() {
|
|
263
|
+
return options.probePage();
|
|
264
|
+
},
|
|
265
|
+
classification: {
|
|
266
|
+
getLayoutId(index) {
|
|
267
|
+
const treePosition = route.layoutTreePositions?.[index] ?? 0;
|
|
268
|
+
return "layout:" + createAppPageTreePath([...route.routeSegments], treePosition);
|
|
269
|
+
},
|
|
270
|
+
buildTimeClassifications: route.__buildTimeClassifications,
|
|
271
|
+
buildTimeReasons: route.__buildTimeReasons,
|
|
272
|
+
debugClassification: options.debugClassification,
|
|
273
|
+
async runWithIsolatedDynamicScope(fn) {
|
|
274
|
+
const priorDynamic = consumeDynamicUsage();
|
|
275
|
+
try {
|
|
276
|
+
return {
|
|
277
|
+
result: await fn(),
|
|
278
|
+
dynamicDetected: consumeDynamicUsage()
|
|
279
|
+
};
|
|
280
|
+
} finally {
|
|
281
|
+
consumeDynamicUsage();
|
|
282
|
+
if (priorDynamic) markDynamicUsage();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
revalidateSeconds: currentRevalidateSeconds,
|
|
287
|
+
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
288
|
+
renderErrorBoundaryResponse(renderError) {
|
|
289
|
+
return options.renderErrorBoundaryPage(renderError);
|
|
290
|
+
},
|
|
291
|
+
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
292
|
+
return renderLayoutSpecialError(options, specialError, layoutIndex);
|
|
293
|
+
},
|
|
294
|
+
renderPageSpecialError(specialError) {
|
|
295
|
+
return renderPageSpecialError(options, specialError);
|
|
296
|
+
},
|
|
297
|
+
renderToReadableStream: options.renderToReadableStream,
|
|
298
|
+
routeHasLocalBoundary: Boolean(route.error?.default || route.errors?.some((errorModule) => errorModule?.default)),
|
|
299
|
+
routePattern: route.pattern,
|
|
300
|
+
runWithSuppressedHookWarning(probe) {
|
|
301
|
+
return options.runWithSuppressedHookWarning(probe);
|
|
302
|
+
},
|
|
303
|
+
scriptNonce: options.scriptNonce,
|
|
304
|
+
waitUntil(cachePromise) {
|
|
305
|
+
getRequestExecutionContext()?.waitUntil(cachePromise);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
async function renderLayoutSpecialError(options, specialError, layoutIndex) {
|
|
310
|
+
return buildAppPageSpecialErrorResponse({
|
|
311
|
+
clearRequestContext: options.clearRequestContext,
|
|
312
|
+
middlewareContext: options.middlewareContext,
|
|
313
|
+
renderFallbackPage(statusCode) {
|
|
314
|
+
const parentBoundary = resolveAppPageParentHttpAccessBoundaryModule({
|
|
315
|
+
layoutIndex,
|
|
316
|
+
rootForbiddenModule: options.rootForbiddenModule,
|
|
317
|
+
rootNotFoundModule: options.rootNotFoundModule,
|
|
318
|
+
rootUnauthorizedModule: options.rootUnauthorizedModule,
|
|
319
|
+
routeForbiddenModules: options.route.forbiddens,
|
|
320
|
+
routeNotFoundModules: options.route.notFounds,
|
|
321
|
+
routeUnauthorizedModules: options.route.unauthorizeds,
|
|
322
|
+
statusCode
|
|
323
|
+
})?.default;
|
|
324
|
+
return options.renderHttpAccessFallbackPage(statusCode, {
|
|
325
|
+
boundaryComponent: parentBoundary,
|
|
326
|
+
layouts: options.route.layouts.slice(0, layoutIndex),
|
|
327
|
+
matchedParams: options.params
|
|
328
|
+
}, null);
|
|
329
|
+
},
|
|
330
|
+
requestUrl: options.request.url,
|
|
331
|
+
specialError
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async function renderPageSpecialError(options, specialError) {
|
|
335
|
+
return buildAppPageSpecialErrorResponse({
|
|
336
|
+
clearRequestContext: options.clearRequestContext,
|
|
337
|
+
middlewareContext: options.middlewareContext,
|
|
338
|
+
renderFallbackPage(statusCode) {
|
|
339
|
+
return options.renderHttpAccessFallbackPage(statusCode, { matchedParams: options.params }, null);
|
|
340
|
+
},
|
|
341
|
+
requestUrl: options.request.url,
|
|
342
|
+
specialError
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
//#endregion
|
|
346
|
+
export { dispatchAppPage };
|
|
347
|
+
|
|
348
|
+
//# sourceMappingURL=app-page-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-page-dispatch.js","names":[],"sources":["../../src/server/app-page-dispatch.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { ClassificationReason } from \"../build/layout-classification-types.js\";\nimport {\n _consumeRequestScopedCacheLife,\n _peekRequestScopedCacheLife,\n type CachedAppPageValue,\n} from \"vinext/shims/cache\";\nimport {\n consumeDynamicUsage,\n consumeInvalidDynamicUsageError,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersContext,\n} from \"vinext/shims/headers\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport {\n ensureFetchPatch,\n type FetchCacheMode,\n getCollectedFetchTags,\n setCurrentFetchCacheMode,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport type { AppOutgoingElements } from \"./app-elements.js\";\nimport { readAppPageCacheResponse } from \"./app-page-cache.js\";\nimport { resolveAppPageParentHttpAccessBoundaryModule } from \"./app-page-boundary.js\";\nimport {\n buildAppPageSpecialErrorResponse,\n readAppPageTextStream,\n resolveAppPageSpecialError,\n teeAppPageRscStreamForCapture,\n type AppPageFontPreload,\n type AppPageSpecialError,\n type LayoutClassificationOptions,\n} from \"./app-page-execution.js\";\nimport { resolveAppPageMethodResponse } from \"./app-page-method.js\";\nimport {\n buildAppPageElement,\n resolveAppPageIntercept,\n validateAppPageDynamicParams,\n type ValidateAppPageDynamicParamsOptions,\n} from \"./app-page-request.js\";\nimport { renderAppPageLifecycle } from \"./app-page-render.js\";\nimport {\n mergeMiddlewareResponseHeaders,\n type AppPageMiddlewareContext,\n} from \"./app-page-response.js\";\nimport { createAppPageTreePath } from \"./app-page-route-wiring.js\";\nimport type { AppPageSsrHandler } from \"./app-page-stream.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\ntype AppPageElement = ReactNode | Readonly<Record<string, ReactNode>>;\ntype AppPageRenderableElement = ReactNode | AppOutgoingElements;\ntype AppPageBoundaryOnError = (\n error: unknown,\n requestInfo: unknown,\n errorContext: unknown,\n) => unknown;\ntype AppPageDebugLogger = (event: string, detail: string) => void;\ntype AppPageCacheSetter = (\n key: string,\n data: CachedAppPageValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppPageCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype AppPageBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\ntype AppPageBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: AppPageBackgroundRegenerationErrorContext,\n) => void;\n\ntype AppPageDispatchIntercept<TPage = unknown> = {\n interceptLayouts?: readonly AppPageModule[] | null;\n matchedParams: AppPageParams;\n page: TPage;\n slotKey: string;\n sourceRouteIndex: number;\n};\n\ntype AppPageDispatchInterceptOptions<TPage = unknown> = {\n interceptionContext: string | null;\n interceptLayouts?: readonly AppPageModule[] | null;\n interceptPage: TPage;\n interceptParams: AppPageParams;\n interceptSlotKey: string;\n};\n\ntype AppPageModule = {\n default?: unknown;\n};\n\ntype AppPageDispatchRoute = {\n __buildTimeClassifications?: LayoutClassificationOptions[\"buildTimeClassifications\"];\n __buildTimeReasons?: LayoutClassificationOptions[\"buildTimeReasons\"];\n error?: AppPageModule | null;\n errors?: readonly (AppPageModule | null | undefined)[];\n forbiddens?: readonly (AppPageModule | null | undefined)[];\n isDynamic: boolean;\n layouts: readonly AppPageModule[];\n layoutTreePositions?: readonly number[];\n loading?: AppPageModule | null;\n notFounds?: readonly (AppPageModule | null | undefined)[];\n params: readonly string[];\n pattern: string;\n routeSegments: readonly string[];\n unauthorizeds?: readonly (AppPageModule | null | undefined)[];\n};\n\ntype DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {\n buildPageElement: (\n route: TRoute,\n params: AppPageParams,\n opts: AppPageDispatchInterceptOptions | undefined,\n searchParams: URLSearchParams,\n ) => Promise<AppPageElement>;\n cleanPathname: string;\n clearRequestContext: () => void;\n createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;\n debugClassification?: (layoutId: string, reason: ClassificationReason) => void;\n dynamicConfig?: string;\n dynamicParamsConfig?: boolean;\n fetchCache?: FetchCacheMode | null;\n findIntercept: (pathname: string) => AppPageDispatchIntercept | null;\n generateStaticParams?: ValidateAppPageDynamicParamsOptions[\"generateStaticParams\"];\n getFontLinks: () => string[];\n getFontPreloads: () => AppPageFontPreload[];\n getFontStyles: () => string[];\n getNavigationContext: () => unknown;\n getSourceRoute: (sourceRouteIndex: number) => TRoute | undefined;\n hasGenerateStaticParams: boolean;\n hasPageDefaultExport: boolean;\n hasPageModule: boolean;\n handlerStart: number;\n interceptionContext: string | null;\n isProduction: boolean;\n isRscRequest: boolean;\n isrDebug?: AppPageDebugLogger;\n isrGet: AppPageCacheGetter;\n isrHtmlKey: (pathname: string) => string;\n isrRscKey: (pathname: string, mountedSlotsHeader?: string | null) => string;\n isrSet: AppPageCacheSetter;\n loadSsrHandler: () => Promise<AppPageSsrHandler>;\n middlewareContext: AppPageMiddlewareContext;\n mountedSlotsHeader?: string | null;\n params: AppPageParams;\n probeLayoutAt: (layoutIndex: number) => unknown;\n probePage: () => unknown;\n expireSeconds?: number;\n renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;\n renderHttpAccessFallbackPage: (\n statusCode: number,\n opts: {\n boundaryComponent?: unknown;\n layouts?: readonly AppPageModule[];\n matchedParams: AppPageParams;\n },\n middlewareContext: AppPageMiddlewareContext | null,\n ) => Promise<Response | null>;\n renderToReadableStream: (\n element: AppPageRenderableElement,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n request: Request;\n revalidateSeconds: number | null;\n resolveRouteFetchCacheMode?: (route: TRoute) => FetchCacheMode | null;\n rootForbiddenModule?: AppPageModule | null;\n rootNotFoundModule?: AppPageModule | null;\n rootUnauthorizedModule?: AppPageModule | null;\n route: TRoute;\n runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;\n scheduleBackgroundRegeneration: AppPageBackgroundRegenerator;\n scriptNonce?: string;\n searchParams: URLSearchParams;\n setNavigationContext: (context: {\n params: AppPageParams;\n pathname: string;\n searchParams: URLSearchParams;\n }) => void;\n};\n\nfunction shouldReadAppPageCache(options: {\n isForceDynamic: boolean;\n isProduction: boolean;\n isRscRequest: boolean;\n revalidateSeconds: number | null;\n scriptNonce?: string;\n}): boolean {\n return (\n options.isProduction &&\n !options.isForceDynamic &&\n (options.isRscRequest || !options.scriptNonce) &&\n (options.revalidateSeconds === null ||\n (options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity))\n );\n}\n\nfunction buildAppPageTags(\n cleanPathname: string,\n extraTags: string[],\n routeSegments: readonly string[],\n): string[] {\n return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], \"page\");\n}\n\nasync function runAppPageRevalidationContext(\n options: {\n cleanPathname: string;\n currentFetchCacheMode?: FetchCacheMode | null;\n dynamicConfig?: string;\n params: AppPageParams;\n routePattern: string;\n routeSegments: readonly string[];\n setNavigationContext: DispatchAppPageOptions<AppPageDispatchRoute>[\"setNavigationContext\"];\n },\n renderFn: () => Promise<{\n html: string;\n rscData: ArrayBuffer;\n tags: string[];\n }>,\n): Promise<{\n html: string;\n rscData: ArrayBuffer;\n tags: string[];\n}> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"page\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n currentFetchCacheMode: options.currentFetchCacheMode ?? null,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n return runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: new URLSearchParams(),\n params: options.params,\n });\n return renderFn();\n });\n}\n\nfunction getCapturedRscDataPromise(\n capturedRscDataPromise: Promise<ArrayBuffer> | null,\n): Promise<ArrayBuffer> {\n if (!capturedRscDataPromise) {\n throw new Error(\n \"[vinext] Expected captured RSC data while regenerating an app page cache entry\",\n );\n }\n\n return capturedRscDataPromise;\n}\n\nfunction toInterceptOptions(\n interceptionContext: string | null,\n intercept: AppPageDispatchIntercept,\n): AppPageDispatchInterceptOptions {\n return {\n interceptionContext,\n interceptLayouts: intercept.interceptLayouts,\n interceptPage: intercept.page,\n interceptParams: intercept.matchedParams,\n interceptSlotKey: intercept.slotKey,\n };\n}\n\nexport async function dispatchAppPage<TRoute extends AppPageDispatchRoute>(\n options: DispatchAppPageOptions<TRoute>,\n): Promise<Response> {\n const route = options.route;\n const dynamicConfig = options.dynamicConfig;\n const currentRevalidateSeconds = options.revalidateSeconds;\n const isForceStatic = dynamicConfig === \"force-static\";\n const isDynamicError = dynamicConfig === \"error\";\n const isForceDynamic = dynamicConfig === \"force-dynamic\";\n\n setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));\n setCurrentFetchCacheMode(options.fetchCache ?? null);\n\n if (options.hasPageModule && !options.hasPageDefaultExport) {\n options.clearRequestContext();\n return new Response(\"Page has no default export\", { status: 500 });\n }\n\n const methodResponse = resolveAppPageMethodResponse({\n dynamicConfig,\n hasGenerateStaticParams: options.hasGenerateStaticParams,\n isDynamicRoute: route.isDynamic,\n middlewareHeaders: options.middlewareContext.headers,\n request: options.request,\n revalidateSeconds: currentRevalidateSeconds,\n });\n if (methodResponse) {\n options.clearRequestContext();\n return methodResponse;\n }\n\n if (isForceStatic || isDynamicError) {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig,\n routeKind: \"page\",\n routePattern: route.pattern,\n }),\n );\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: new URLSearchParams(),\n params: options.params,\n });\n }\n\n if (\n shouldReadAppPageCache({\n isForceDynamic,\n isProduction: options.isProduction,\n isRscRequest: options.isRscRequest,\n revalidateSeconds: currentRevalidateSeconds,\n scriptNonce: options.scriptNonce,\n })\n ) {\n const cachedPageResponse = await readAppPageCacheResponse({\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n isRscRequest: options.isRscRequest,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrHtmlKey: options.isrHtmlKey,\n isrRscKey: options.isrRscKey,\n isrSet: options.isrSet,\n mountedSlotsHeader: options.mountedSlotsHeader,\n expireSeconds: options.expireSeconds,\n // cacheLife-only routes discover their actual revalidate during the\n // fresh render; this seed only gets them into the cache read path.\n revalidateSeconds: currentRevalidateSeconds ?? 0,\n renderFreshPageForCache: async () =>\n runAppPageRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n currentFetchCacheMode: options.fetchCache ?? null,\n dynamicConfig,\n params: options.params,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n setNavigationContext: options.setNavigationContext,\n },\n async () => {\n const revalidatedElement = await options.buildPageElement(\n route,\n options.params,\n undefined,\n new URLSearchParams(),\n );\n const revalidatedOnError = options.createRscOnErrorHandler(\n options.cleanPathname,\n route.pattern,\n );\n const revalidatedRscStream = options.renderToReadableStream(revalidatedElement, {\n onError: revalidatedOnError,\n });\n const revalidatedRscCapture = teeAppPageRscStreamForCapture(revalidatedRscStream, true);\n const revalidatedSsrEntry = await options.loadSsrHandler();\n const revalidatedCapturedRscRef: { value: Promise<ArrayBuffer> | null } = {\n value: null,\n };\n const revalidatedHtmlStream = await revalidatedSsrEntry.handleSsr(\n revalidatedRscCapture.ssrStream,\n options.getNavigationContext(),\n {\n links: options.getFontLinks(),\n styles: options.getFontStyles(),\n preloads: options.getFontPreloads(),\n },\n revalidatedRscCapture.sideStream\n ? {\n sideStream: revalidatedRscCapture.sideStream,\n capturedRscDataRef: revalidatedCapturedRscRef,\n }\n : undefined,\n );\n const html = await readAppPageTextStream(revalidatedHtmlStream);\n const rscData = await getCapturedRscDataPromise(revalidatedCapturedRscRef.value);\n const cacheLife = _consumeRequestScopedCacheLife();\n options.clearRequestContext();\n const tags = buildAppPageTags(\n options.cleanPathname,\n getCollectedFetchTags(),\n route.routeSegments,\n );\n return {\n html,\n rscData,\n tags,\n cacheControl:\n typeof cacheLife?.revalidate === \"number\"\n ? { revalidate: cacheLife.revalidate, expire: cacheLife.expire }\n : undefined,\n };\n },\n ),\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"render\",\n });\n },\n });\n if (cachedPageResponse) {\n return cachedPageResponse;\n }\n }\n\n const dynamicParamsResponse = await validateAppPageDynamicParams({\n clearRequestContext: options.clearRequestContext,\n enforceStaticParamsOnly: options.dynamicParamsConfig === false,\n generateStaticParams: options.generateStaticParams,\n isDynamicRoute: route.isDynamic,\n logGenerateStaticParamsError(error) {\n console.error(\"[vinext] generateStaticParams error:\", error);\n },\n params: options.params,\n });\n if (dynamicParamsResponse) {\n return dynamicParamsResponse;\n }\n\n const interceptResult = await resolveAppPageIntercept<\n TRoute,\n unknown,\n AppPageDispatchInterceptOptions,\n AppPageElement\n >({\n buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams) {\n setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);\n return options.buildPageElement(\n interceptRoute,\n interceptParams,\n interceptOpts,\n interceptSearchParams,\n );\n },\n cleanPathname: options.cleanPathname,\n currentRoute: route,\n findIntercept(pathname) {\n return options.findIntercept(pathname);\n },\n getRouteParamNames(sourceRoute) {\n return sourceRoute.params;\n },\n getSourceRoute(sourceRouteIndex) {\n return options.getSourceRoute(sourceRouteIndex);\n },\n isRscRequest: options.isRscRequest,\n renderInterceptResponse(sourceRoute, interceptElement) {\n const interceptOnError = options.createRscOnErrorHandler(\n options.cleanPathname,\n sourceRoute.pattern,\n );\n const interceptStream = options.renderToReadableStream(interceptElement, {\n onError: interceptOnError,\n });\n const interceptHeaders = new Headers({\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n Vary: \"RSC, Accept\",\n });\n mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);\n return new Response(interceptStream, {\n status: options.middlewareContext.status ?? 200,\n headers: interceptHeaders,\n });\n },\n searchParams: options.searchParams,\n setNavigationContext: options.setNavigationContext,\n toInterceptOpts(intercept) {\n return toInterceptOptions(options.interceptionContext, intercept);\n },\n });\n if (interceptResult.response) {\n return interceptResult.response;\n }\n\n const pageBuildResult = await buildAppPageElement({\n buildPageElement() {\n return options.buildPageElement(\n route,\n options.params,\n interceptResult.interceptOpts,\n options.searchParams,\n );\n },\n renderErrorBoundaryPage(buildError) {\n return options.renderErrorBoundaryPage(buildError);\n },\n renderSpecialError(specialError) {\n return renderPageSpecialError(options, specialError);\n },\n resolveSpecialError: resolveAppPageSpecialError,\n });\n if (pageBuildResult.response) {\n return pageBuildResult.response;\n }\n\n return renderAppPageLifecycle({\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n consumeInvalidDynamicUsageError,\n createRscOnErrorHandler(pathname, routePath) {\n return options.createRscOnErrorHandler(pathname, routePath);\n },\n element: pageBuildResult.element,\n getDraftModeCookieHeader,\n getFontLinks: options.getFontLinks,\n getFontPreloads: options.getFontPreloads,\n getFontStyles: options.getFontStyles,\n getNavigationContext: options.getNavigationContext,\n getPageTags() {\n return buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), route.routeSegments);\n },\n getRequestCacheLife() {\n return _consumeRequestScopedCacheLife();\n },\n peekRequestCacheLife() {\n return _peekRequestScopedCacheLife();\n },\n handlerStart: options.handlerStart,\n hasLoadingBoundary: Boolean(route.loading?.default),\n isDynamicError,\n isForceDynamic,\n isForceStatic,\n isPrerender: process.env.VINEXT_PRERENDER === \"1\",\n isProduction: options.isProduction,\n isRscRequest: options.isRscRequest,\n isrDebug: options.isrDebug,\n isrHtmlKey: options.isrHtmlKey,\n isrRscKey: options.isrRscKey,\n isrSet: options.isrSet,\n expireSeconds: options.expireSeconds,\n layoutCount: route.layouts.length,\n loadSsrHandler: options.loadSsrHandler,\n middlewareContext: options.middlewareContext,\n params: options.params,\n probeLayoutAt(layoutIndex) {\n return options.probeLayoutAt(layoutIndex);\n },\n probePage() {\n return options.probePage();\n },\n classification: {\n getLayoutId(index) {\n const treePosition = route.layoutTreePositions?.[index] ?? 0;\n return \"layout:\" + createAppPageTreePath([...route.routeSegments], treePosition);\n },\n buildTimeClassifications: route.__buildTimeClassifications,\n buildTimeReasons: route.__buildTimeReasons,\n debugClassification: options.debugClassification,\n async runWithIsolatedDynamicScope(fn) {\n const priorDynamic = consumeDynamicUsage();\n try {\n const result = await fn();\n const dynamicDetected = consumeDynamicUsage();\n return { result, dynamicDetected };\n } finally {\n consumeDynamicUsage();\n if (priorDynamic) markDynamicUsage();\n }\n },\n },\n revalidateSeconds: currentRevalidateSeconds,\n mountedSlotsHeader: options.mountedSlotsHeader,\n renderErrorBoundaryResponse(renderError) {\n return options.renderErrorBoundaryPage(renderError);\n },\n renderLayoutSpecialError(specialError, layoutIndex) {\n return renderLayoutSpecialError(options, specialError, layoutIndex);\n },\n renderPageSpecialError(specialError) {\n return renderPageSpecialError(options, specialError);\n },\n renderToReadableStream: options.renderToReadableStream,\n routeHasLocalBoundary: Boolean(\n route.error?.default || route.errors?.some((errorModule) => errorModule?.default),\n ),\n routePattern: route.pattern,\n runWithSuppressedHookWarning(probe) {\n return options.runWithSuppressedHookWarning(probe);\n },\n scriptNonce: options.scriptNonce,\n waitUntil(cachePromise) {\n getRequestExecutionContext()?.waitUntil(cachePromise);\n },\n });\n}\n\nasync function renderLayoutSpecialError<TRoute extends AppPageDispatchRoute>(\n options: DispatchAppPageOptions<TRoute>,\n specialError: AppPageSpecialError,\n layoutIndex: number,\n): Promise<Response> {\n return buildAppPageSpecialErrorResponse({\n clearRequestContext: options.clearRequestContext,\n middlewareContext: options.middlewareContext,\n renderFallbackPage(statusCode) {\n const parentBoundary = resolveAppPageParentHttpAccessBoundaryModule({\n layoutIndex,\n rootForbiddenModule: options.rootForbiddenModule,\n rootNotFoundModule: options.rootNotFoundModule,\n rootUnauthorizedModule: options.rootUnauthorizedModule,\n routeForbiddenModules: options.route.forbiddens,\n routeNotFoundModules: options.route.notFounds,\n routeUnauthorizedModules: options.route.unauthorizeds,\n statusCode,\n })?.default;\n return options.renderHttpAccessFallbackPage(\n statusCode,\n {\n boundaryComponent: parentBoundary,\n layouts: options.route.layouts.slice(0, layoutIndex),\n matchedParams: options.params,\n },\n null,\n );\n },\n requestUrl: options.request.url,\n specialError,\n });\n}\n\nasync function renderPageSpecialError<TRoute extends AppPageDispatchRoute>(\n options: DispatchAppPageOptions<TRoute>,\n specialError: AppPageSpecialError,\n): Promise<Response> {\n return buildAppPageSpecialErrorResponse({\n clearRequestContext: options.clearRequestContext,\n middlewareContext: options.middlewareContext,\n renderFallbackPage(statusCode) {\n return options.renderHttpAccessFallbackPage(\n statusCode,\n { matchedParams: options.params },\n null,\n );\n },\n requestUrl: options.request.url,\n specialError,\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { MetadataFileRoute } from "./metadata-routes.js";
|
|
2
|
+
import { AppElements } from "./app-elements.js";
|
|
3
|
+
import { AppPageParams } from "./app-page-boundary.js";
|
|
4
|
+
import { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute } from "./app-page-route-wiring.js";
|
|
5
|
+
|
|
6
|
+
//#region src/server/app-page-element-builder.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Route shape passed from the generated entry. Extends the wiring route with
|
|
9
|
+
* the page module reference (used to extract the default export for the page
|
|
10
|
+
* element) and the URL pattern (used as the route path in head resolution).
|
|
11
|
+
*/
|
|
12
|
+
type AppPageBuildRoute<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = AppPageRouteWiringRoute<TModule, TErrorModule> & {
|
|
13
|
+
page?: TModule | null;
|
|
14
|
+
pattern: string; /** Param names captured by the route's URL pattern, in order. */
|
|
15
|
+
params?: readonly string[] | null;
|
|
16
|
+
};
|
|
17
|
+
type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
18
|
+
interceptionContext?: string | null;
|
|
19
|
+
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
20
|
+
interceptPage?: TModule | null;
|
|
21
|
+
interceptParams?: AppPageParams | null;
|
|
22
|
+
interceptSlotKey?: string | null;
|
|
23
|
+
};
|
|
24
|
+
type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
|
|
25
|
+
/** Interception context from current-route navigation (null for direct visits). */opts?: AppPageInterceptOptions<TModule> | null; /** URL search params from the incoming request (null when unavailable). */
|
|
26
|
+
searchParams?: URLSearchParams | null; /** Whether the incoming request is an RSC (client-side navigation) request. */
|
|
27
|
+
isRscRequest: boolean; /** The incoming HTTP request (available but unused by this module). */
|
|
28
|
+
request: Request; /** Normalized x-vinext-mounted-slots header value. */
|
|
29
|
+
mountedSlotsHeader: string | null;
|
|
30
|
+
};
|
|
31
|
+
type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
|
|
32
|
+
route: AppPageBuildRoute<TModule, TErrorModule>;
|
|
33
|
+
params: AppPageParams;
|
|
34
|
+
routePath: string;
|
|
35
|
+
pageRequest: AppPagePageRequest<TModule>; /** Root-level global-error.tsx module. Present when the app defines this file. */
|
|
36
|
+
globalErrorModule?: TErrorModule | null; /** Root-level not-found.tsx module. Present when the app defines this file. */
|
|
37
|
+
rootNotFoundModule?: TModule | null; /** Root-level forbidden.tsx module. Present when the app defines this file. */
|
|
38
|
+
rootForbiddenModule?: TModule | null; /** Root-level unauthorized.tsx module. Present when the app defines this file. */
|
|
39
|
+
rootUnauthorizedModule?: TModule | null; /** File-based metadata routes (favicon, manifest, sitemap, etc.). */
|
|
40
|
+
metadataRoutes: readonly MetadataFileRoute[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Build the App Router element tree for a matched route.
|
|
44
|
+
*
|
|
45
|
+
* This is the central element-construction path for the App Router RSC
|
|
46
|
+
* handler. It resolves page head metadata (including parallel route metadata),
|
|
47
|
+
* creates the page React element, and wires it into the nested layout +
|
|
48
|
+
* boundary tree via {@link buildAppPageElements}.
|
|
49
|
+
*
|
|
50
|
+
* The function is extracted from the generated RSC entry template so it can
|
|
51
|
+
* be unit-tested independently of the code-generation machinery.
|
|
52
|
+
*
|
|
53
|
+
* Next.js equivalent: the component tree construction in
|
|
54
|
+
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-component-tree.tsx|create-component-tree.tsx}
|
|
55
|
+
* and the page head resolution in
|
|
56
|
+
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
57
|
+
*/
|
|
58
|
+
declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements };
|
|
61
|
+
//# sourceMappingURL=app-page-element-builder.d.ts.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { markDynamicUsage } from "../shims/headers.js";
|
|
2
|
+
import { APP_INTERCEPTION_CONTEXT_KEY, createAppPayloadRouteId } from "./app-elements.js";
|
|
3
|
+
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
4
|
+
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
5
|
+
import { buildAppPageElements, createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
6
|
+
import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
|
|
7
|
+
import { createElement } from "react";
|
|
8
|
+
//#region src/server/app-page-element-builder.ts
|
|
9
|
+
/**
|
|
10
|
+
* Build the App Router element tree for a matched route.
|
|
11
|
+
*
|
|
12
|
+
* This is the central element-construction path for the App Router RSC
|
|
13
|
+
* handler. It resolves page head metadata (including parallel route metadata),
|
|
14
|
+
* creates the page React element, and wires it into the nested layout +
|
|
15
|
+
* boundary tree via {@link buildAppPageElements}.
|
|
16
|
+
*
|
|
17
|
+
* The function is extracted from the generated RSC entry template so it can
|
|
18
|
+
* be unit-tested independently of the code-generation machinery.
|
|
19
|
+
*
|
|
20
|
+
* Next.js equivalent: the component tree construction in
|
|
21
|
+
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-component-tree.tsx|create-component-tree.tsx}
|
|
22
|
+
* and the page head resolution in
|
|
23
|
+
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
24
|
+
*/
|
|
25
|
+
async function buildPageElements(options) {
|
|
26
|
+
const { route, params, routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
27
|
+
const { opts, searchParams, isRscRequest, mountedSlotsHeader } = pageRequest;
|
|
28
|
+
const pageModule = route.page;
|
|
29
|
+
const PageComponent = pageModule?.default;
|
|
30
|
+
if (!!pageModule && !PageComponent) {
|
|
31
|
+
const interceptionContext = opts?.interceptionContext ?? null;
|
|
32
|
+
const noExportRouteId = createAppPayloadRouteId(routePath, interceptionContext);
|
|
33
|
+
let noExportRootLayout = null;
|
|
34
|
+
if (route.layouts?.length > 0) {
|
|
35
|
+
const treePosition = route.layoutTreePositions?.[0] ?? 0;
|
|
36
|
+
noExportRootLayout = createAppPageTreePath(route.routeSegments, treePosition);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
[APP_INTERCEPTION_CONTEXT_KEY]: interceptionContext,
|
|
40
|
+
__route: noExportRouteId,
|
|
41
|
+
__rootLayout: noExportRootLayout,
|
|
42
|
+
[noExportRouteId]: createElement("div", null, "Page has no default export")
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const { hasSearchParams, metadata: resolvedMetadata, pageSearchParams, viewport: resolvedViewport } = await resolveAppPageHead({
|
|
46
|
+
layoutModules: route.layouts,
|
|
47
|
+
layoutTreePositions: route.layoutTreePositions,
|
|
48
|
+
metadataRoutes,
|
|
49
|
+
pageModule: route.page ?? null,
|
|
50
|
+
parallelRoutes: resolveActiveParallelRouteHeadInputs({
|
|
51
|
+
interceptLayouts: opts?.interceptLayouts ?? null,
|
|
52
|
+
interceptPage: opts?.interceptPage ?? null,
|
|
53
|
+
interceptParams: opts?.interceptParams ?? null,
|
|
54
|
+
interceptSlotKey: opts?.interceptSlotKey ?? null,
|
|
55
|
+
params,
|
|
56
|
+
routeSegments: route.routeSegments ?? [],
|
|
57
|
+
slots: route.slots ?? null
|
|
58
|
+
}),
|
|
59
|
+
params,
|
|
60
|
+
routePath: route.pattern,
|
|
61
|
+
routeSegments: route.routeSegments ?? null,
|
|
62
|
+
searchParams
|
|
63
|
+
});
|
|
64
|
+
const pageProps = { params: makeThenableParams(params) };
|
|
65
|
+
if (searchParams) {
|
|
66
|
+
pageProps.searchParams = makeThenableParams(pageSearchParams);
|
|
67
|
+
if (hasSearchParams) markDynamicUsage();
|
|
68
|
+
}
|
|
69
|
+
const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(" ")) : null;
|
|
70
|
+
const slotOverrides = buildSlotOverrides(route, params, routePath, opts);
|
|
71
|
+
return buildAppPageElements({
|
|
72
|
+
element: PageComponent ? createElement(PageComponent, pageProps) : null,
|
|
73
|
+
globalErrorModule: globalErrorModule ?? null,
|
|
74
|
+
isRscRequest,
|
|
75
|
+
mountedSlotIds,
|
|
76
|
+
makeThenableParams,
|
|
77
|
+
matchedParams: params,
|
|
78
|
+
resolvedMetadata,
|
|
79
|
+
resolvedViewport,
|
|
80
|
+
interceptionContext: opts?.interceptionContext ?? null,
|
|
81
|
+
routePath,
|
|
82
|
+
rootNotFoundModule: rootNotFoundModule ?? null,
|
|
83
|
+
rootForbiddenModule: rootForbiddenModule ?? null,
|
|
84
|
+
rootUnauthorizedModule: rootUnauthorizedModule ?? null,
|
|
85
|
+
route,
|
|
86
|
+
slotOverrides
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build the per-request `slotOverrides` map. Combines:
|
|
91
|
+
* - Interception overrides (existing behavior — swap in the intercepting page
|
|
92
|
+
* and its layouts when the request is intercepted into this slot).
|
|
93
|
+
* - Slot-specific param extraction for inherited slots whose URL pattern
|
|
94
|
+
* has different param names than the route's. The runtime matches the
|
|
95
|
+
* cleaned request path against `slot.slotPatternParts` to produce
|
|
96
|
+
* slot-scoped params, which `app-page-route-wiring` then hands to the
|
|
97
|
+
* slot page instead of the route's matched params.
|
|
98
|
+
*
|
|
99
|
+
* `routePath` is the already-normalized request pathname (basePath stripped,
|
|
100
|
+
* RSC suffix removed). Re-parsing `request.url` here would re-introduce the
|
|
101
|
+
* basePath and silently break the match for any app that configures one.
|
|
102
|
+
*/
|
|
103
|
+
function buildSlotOverrides(route, routeParams, routePath, opts) {
|
|
104
|
+
const overrides = {};
|
|
105
|
+
if (opts && opts.interceptSlotKey && opts.interceptPage) overrides[opts.interceptSlotKey] = {
|
|
106
|
+
layoutModules: opts.interceptLayouts || null,
|
|
107
|
+
pageModule: opts.interceptPage,
|
|
108
|
+
params: opts.interceptParams || routeParams
|
|
109
|
+
};
|
|
110
|
+
const slots = route.slots;
|
|
111
|
+
if (slots) {
|
|
112
|
+
let urlParts = null;
|
|
113
|
+
const routeParamSet = collectParamNameSet(route.params);
|
|
114
|
+
for (const [slotKey, slot] of Object.entries(slots)) {
|
|
115
|
+
const patternParts = slot.slotPatternParts;
|
|
116
|
+
const paramNames = slot.slotParamNames;
|
|
117
|
+
if (!patternParts || patternParts.length === 0) continue;
|
|
118
|
+
if (paramNames && paramNames.every((name) => routeParamSet.has(name))) continue;
|
|
119
|
+
if (urlParts === null) urlParts = routePath.split("/").filter(Boolean);
|
|
120
|
+
const matched = matchRoutePattern(urlParts, patternParts);
|
|
121
|
+
if (!matched) continue;
|
|
122
|
+
const existing = overrides[slotKey];
|
|
123
|
+
overrides[slotKey] = existing ? {
|
|
124
|
+
...existing,
|
|
125
|
+
params: matched
|
|
126
|
+
} : { params: matched };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return Object.keys(overrides).length > 0 ? overrides : null;
|
|
130
|
+
}
|
|
131
|
+
function collectParamNameSet(params) {
|
|
132
|
+
const set = /* @__PURE__ */ new Set();
|
|
133
|
+
if (params) for (const name of params) set.add(name);
|
|
134
|
+
return set;
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { buildPageElements };
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=app-page-element-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-page-element-builder.js","names":[],"sources":["../../src/server/app-page-element-builder.ts"],"sourcesContent":["import { createElement } from \"react\";\nimport { markDynamicUsage } from \"vinext/shims/headers\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from \"./app-page-head.js\";\nimport {\n buildAppPageElements,\n createAppPageTreePath,\n type AppPageErrorModule,\n type AppPageModule,\n type AppPageRouteWiringRoute,\n type AppPageSlotOverride,\n} from \"./app-page-route-wiring.js\";\nimport {\n APP_INTERCEPTION_CONTEXT_KEY,\n createAppPayloadRouteId,\n type AppElements,\n} from \"./app-elements.js\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport { matchRoutePattern } from \"../routing/route-pattern.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\n\nexport type { AppPageErrorModule, AppPageRouteWiringRoute } from \"./app-page-route-wiring.js\";\n\n/**\n * Route shape passed from the generated entry. Extends the wiring route with\n * the page module reference (used to extract the default export for the page\n * element) and the URL pattern (used as the route path in head resolution).\n */\nexport type AppPageBuildRoute<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = AppPageRouteWiringRoute<TModule, TErrorModule> & {\n page?: TModule | null;\n pattern: string;\n /** Param names captured by the route's URL pattern, in order. */\n params?: readonly string[] | null;\n};\n\nexport type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {\n interceptionContext?: string | null;\n interceptLayouts?: readonly (TModule | null | undefined)[] | null;\n interceptPage?: TModule | null;\n interceptParams?: AppPageParams | null;\n interceptSlotKey?: string | null;\n};\n\nexport type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {\n /** Interception context from current-route navigation (null for direct visits). */\n opts?: AppPageInterceptOptions<TModule> | null;\n /** URL search params from the incoming request (null when unavailable). */\n searchParams?: URLSearchParams | null;\n /** Whether the incoming request is an RSC (client-side navigation) request. */\n isRscRequest: boolean;\n /** The incoming HTTP request (available but unused by this module). */\n request: Request;\n /** Normalized x-vinext-mounted-slots header value. */\n mountedSlotsHeader: string | null;\n};\n\nexport type BuildPageElementsOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n route: AppPageBuildRoute<TModule, TErrorModule>;\n params: AppPageParams;\n routePath: string;\n pageRequest: AppPagePageRequest<TModule>;\n /** Root-level global-error.tsx module. Present when the app defines this file. */\n globalErrorModule?: TErrorModule | null;\n /** Root-level not-found.tsx module. Present when the app defines this file. */\n rootNotFoundModule?: TModule | null;\n /** Root-level forbidden.tsx module. Present when the app defines this file. */\n rootForbiddenModule?: TModule | null;\n /** Root-level unauthorized.tsx module. Present when the app defines this file. */\n rootUnauthorizedModule?: TModule | null;\n /** File-based metadata routes (favicon, manifest, sitemap, etc.). */\n metadataRoutes: readonly MetadataFileRoute[];\n};\n\n/**\n * Build the App Router element tree for a matched route.\n *\n * This is the central element-construction path for the App Router RSC\n * handler. It resolves page head metadata (including parallel route metadata),\n * creates the page React element, and wires it into the nested layout +\n * boundary tree via {@link buildAppPageElements}.\n *\n * The function is extracted from the generated RSC entry template so it can\n * be unit-tested independently of the code-generation machinery.\n *\n * Next.js equivalent: the component tree construction in\n * {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-component-tree.tsx|create-component-tree.tsx}\n * and the page head resolution in\n * {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.\n */\nexport async function buildPageElements<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements> {\n const {\n route,\n params,\n routePath,\n pageRequest,\n globalErrorModule,\n rootNotFoundModule,\n rootForbiddenModule,\n rootUnauthorizedModule,\n metadataRoutes,\n } = options;\n const { opts, searchParams, isRscRequest, mountedSlotsHeader } = pageRequest;\n\n const pageModule: AppPageModule | null | undefined = route.page;\n const PageComponent = pageModule?.default;\n const hasPageModule = !!pageModule;\n\n if (hasPageModule && !PageComponent) {\n const interceptionContext = opts?.interceptionContext ?? null;\n const noExportRouteId = createAppPayloadRouteId(routePath, interceptionContext);\n let noExportRootLayout: string | null = null;\n if (route.layouts?.length > 0) {\n const treePosition = route.layoutTreePositions?.[0] ?? 0;\n noExportRootLayout = createAppPageTreePath(route.routeSegments, treePosition);\n }\n return {\n [APP_INTERCEPTION_CONTEXT_KEY]: interceptionContext,\n __route: noExportRouteId,\n __rootLayout: noExportRootLayout,\n [noExportRouteId]: createElement(\"div\", null, \"Page has no default export\"),\n };\n }\n\n const {\n hasSearchParams,\n metadata: resolvedMetadata,\n pageSearchParams,\n viewport: resolvedViewport,\n } = await resolveAppPageHead({\n layoutModules: route.layouts,\n layoutTreePositions: route.layoutTreePositions,\n metadataRoutes,\n pageModule: route.page ?? null,\n parallelRoutes: resolveActiveParallelRouteHeadInputs({\n interceptLayouts: opts?.interceptLayouts ?? null,\n interceptPage: opts?.interceptPage ?? null,\n interceptParams: opts?.interceptParams ?? null,\n interceptSlotKey: opts?.interceptSlotKey ?? null,\n params,\n routeSegments: route.routeSegments ?? [],\n slots: route.slots ?? null,\n }),\n params,\n routePath: route.pattern,\n routeSegments: route.routeSegments ?? null,\n searchParams,\n });\n\n const pageProps: Record<string, unknown> = { params: makeThenableParams(params) };\n if (searchParams) {\n pageProps.searchParams = makeThenableParams(pageSearchParams);\n if (hasSearchParams) markDynamicUsage();\n }\n\n const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(\" \")) : null;\n\n const slotOverrides = buildSlotOverrides(route, params, routePath, opts);\n\n return buildAppPageElements({\n element: PageComponent ? createElement(PageComponent, pageProps) : null,\n globalErrorModule: globalErrorModule ?? null,\n isRscRequest,\n mountedSlotIds,\n makeThenableParams,\n matchedParams: params,\n resolvedMetadata,\n resolvedViewport,\n interceptionContext: opts?.interceptionContext ?? null,\n routePath,\n rootNotFoundModule: rootNotFoundModule ?? null,\n rootForbiddenModule: rootForbiddenModule ?? null,\n rootUnauthorizedModule: rootUnauthorizedModule ?? null,\n route,\n slotOverrides,\n });\n}\n\n/**\n * Build the per-request `slotOverrides` map. Combines:\n * - Interception overrides (existing behavior — swap in the intercepting page\n * and its layouts when the request is intercepted into this slot).\n * - Slot-specific param extraction for inherited slots whose URL pattern\n * has different param names than the route's. The runtime matches the\n * cleaned request path against `slot.slotPatternParts` to produce\n * slot-scoped params, which `app-page-route-wiring` then hands to the\n * slot page instead of the route's matched params.\n *\n * `routePath` is the already-normalized request pathname (basePath stripped,\n * RSC suffix removed). Re-parsing `request.url` here would re-introduce the\n * basePath and silently break the match for any app that configures one.\n */\nfunction buildSlotOverrides<TModule extends AppPageModule, TErrorModule extends AppPageErrorModule>(\n route: AppPageBuildRoute<TModule, TErrorModule>,\n routeParams: AppPageParams,\n routePath: string,\n opts?: AppPageInterceptOptions<TModule> | null,\n): Readonly<Record<string, AppPageSlotOverride<TModule>>> | null {\n const overrides: Record<string, AppPageSlotOverride<TModule>> = {};\n\n if (opts && opts.interceptSlotKey && opts.interceptPage) {\n overrides[opts.interceptSlotKey] = {\n layoutModules: opts.interceptLayouts || null,\n pageModule: opts.interceptPage,\n params: opts.interceptParams || routeParams,\n };\n }\n\n const slots = route.slots;\n if (slots) {\n let urlParts: string[] | null = null;\n const routeParamSet = collectParamNameSet(route.params);\n for (const [slotKey, slot] of Object.entries(slots)) {\n const patternParts = slot.slotPatternParts;\n const paramNames = slot.slotParamNames;\n if (!patternParts || patternParts.length === 0) continue;\n // Skip when every slot param is already a route param — the route's\n // matched params already carry the values the slot page expects.\n // Empty `paramNames` (slot pattern has no dynamic markers) also skips:\n // there's nothing to extract, so the route's matched params suffice.\n if (paramNames && paramNames.every((name) => routeParamSet.has(name))) continue;\n\n if (urlParts === null) {\n urlParts = routePath.split(\"/\").filter(Boolean);\n }\n const matched = matchRoutePattern(urlParts, patternParts);\n if (!matched) continue;\n\n const existing = overrides[slotKey];\n overrides[slotKey] = existing ? { ...existing, params: matched } : { params: matched };\n }\n }\n\n return Object.keys(overrides).length > 0 ? overrides : null;\n}\n\nfunction collectParamNameSet(params: readonly string[] | undefined | null): Set<string> {\n const set = new Set<string>();\n if (params) {\n for (const name of params) set.add(name);\n }\n return set;\n}\n"],"mappings":"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"}
|