vinext 0.0.50 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
- package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
- package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
- package/dist/build/google-fonts/fallback-metrics.js +46 -0
- package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
- package/dist/build/precompress.d.ts +13 -2
- package/dist/build/precompress.js +12 -3
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +1 -1
- package/dist/build/prerender.js +44 -14
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +5 -4
- package/dist/build/report.js +196 -348
- package/dist/build/report.js.map +1 -1
- package/dist/check.js +1 -0
- package/dist/check.js.map +1 -1
- package/dist/cli.js +60 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/window-next.d.ts +3 -1
- package/dist/client/window-next.js.map +1 -1
- package/dist/config/dotenv.d.ts +11 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +87 -3
- package/dist/config/next-config.js +222 -6
- package/dist/config/next-config.js.map +1 -1
- package/dist/config/tsconfig-paths.d.ts +13 -0
- package/dist/config/tsconfig-paths.js +117 -0
- package/dist/config/tsconfig-paths.js.map +1 -0
- package/dist/deploy.js +3 -2
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +2 -2
- package/dist/entries/app-browser-entry.js +26 -1
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +19 -1
- package/dist/entries/app-rsc-entry.js +38 -12
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +9 -0
- package/dist/entries/app-rsc-manifest.js +4 -1
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.js +3 -5
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +19 -1
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/index.js +130 -37
- package/dist/index.js.map +1 -1
- package/dist/plugins/client-reference-dedup.d.ts +15 -2
- package/dist/plugins/client-reference-dedup.js +138 -16
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fonts.d.ts +2 -2
- package/dist/plugins/fonts.js +15 -6
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/sass.d.ts +34 -0
- package/dist/plugins/sass.js +22 -0
- package/dist/plugins/sass.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +31 -2
- package/dist/routing/app-route-graph.js +82 -10
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/route-pattern.d.ts +56 -1
- package/dist/routing/route-pattern.js +60 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +27 -2
- package/dist/server/app-browser-action-result.js +63 -2
- package/dist/server/app-browser-action-result.js.map +1 -1
- package/dist/server/app-browser-entry.js +262 -108
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +13 -1
- package/dist/server/app-browser-hydration.js +9 -1
- package/dist/server/app-browser-hydration.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +14 -1
- package/dist/server/app-browser-navigation-controller.js +28 -9
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-popstate.d.ts +16 -0
- package/dist/server/app-browser-popstate.js +17 -0
- package/dist/server/app-browser-popstate.js.map +1 -0
- package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
- package/dist/server/app-browser-rsc-redirect.js +37 -0
- package/dist/server/app-browser-rsc-redirect.js.map +1 -0
- package/dist/server/app-browser-state.d.ts +11 -7
- package/dist/server/app-browser-state.js +45 -27
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +5 -4
- package/dist/server/app-browser-stream.js +5 -6
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +5 -0
- package/dist/server/app-browser-visible-commit.js +38 -5
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +38 -6
- package/dist/server/app-elements-wire.js +106 -6
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +10 -1
- package/dist/server/app-fallback-renderer.js +37 -1
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-history-state.d.ts +26 -0
- package/dist/server/app-history-state.js +53 -0
- package/dist/server/app-history-state.js.map +1 -0
- package/dist/server/app-page-boundary-render.d.ts +10 -1
- package/dist/server/app-page-boundary-render.js +13 -6
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.js +3 -2
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +13 -0
- package/dist/server/app-page-cache.js +25 -8
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +5 -0
- package/dist/server/app-page-dispatch.js +68 -11
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +32 -4
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.js +2 -3
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +7 -0
- package/dist/server/app-page-head.js +2 -1
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +23 -1
- package/dist/server/app-page-probe.js +29 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render-observation.d.ts +35 -0
- package/dist/server/app-page-render-observation.js +68 -0
- package/dist/server/app-page-render-observation.js.map +1 -0
- package/dist/server/app-page-render.d.ts +5 -1
- package/dist/server/app-page-render.js +79 -3
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +1 -0
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.js +3 -2
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +42 -14
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +2 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-router-entry.js +1 -13
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +19 -1
- package/dist/server/app-rsc-cache-busting.js +36 -1
- package/dist/server/app-rsc-cache-busting.js.map +1 -1
- package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
- package/dist/server/app-rsc-embedded-chunks.js +34 -0
- package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
- package/dist/server/app-rsc-errors.d.ts +4 -1
- package/dist/server/app-rsc-errors.js +1 -1
- package/dist/server/app-rsc-errors.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +12 -4
- package/dist/server/app-rsc-handler.js +6 -1
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +23 -0
- package/dist/server/app-rsc-route-matching.js +45 -23
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +35 -3
- package/dist/server/app-server-action-execution.js +87 -33
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +1 -0
- package/dist/server/app-ssr-entry.js +37 -13
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.d.ts +14 -0
- package/dist/server/app-ssr-error-meta.js +50 -0
- package/dist/server/app-ssr-error-meta.js.map +1 -0
- package/dist/server/app-ssr-stream.d.ts +1 -1
- package/dist/server/app-ssr-stream.js +9 -12
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/artifact-compatibility.d.ts +12 -2
- package/dist/server/artifact-compatibility.js +12 -8
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-proof.d.ts +124 -5
- package/dist/server/cache-proof.js +416 -18
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/dev-lockfile.d.ts +110 -0
- package/dist/server/dev-lockfile.js +180 -0
- package/dist/server/dev-lockfile.js.map +1 -0
- package/dist/server/dev-server.js +15 -5
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.d.ts +13 -0
- package/dist/server/file-based-metadata.js +49 -2
- package/dist/server/file-based-metadata.js.map +1 -1
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +5 -2
- package/dist/server/headers.js.map +1 -1
- package/dist/server/html.js +1 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.d.ts +10 -0
- package/dist/server/http-error-responses.js +11 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/isr-cache.d.ts +2 -1
- package/dist/server/isr-cache.js +4 -2
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-response.js +22 -5
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.js +27 -8
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-runtime.js +1 -0
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.d.ts +12 -0
- package/dist/server/middleware.js +12 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +19 -5
- package/dist/server/navigation-planner.js +278 -17
- package/dist/server/navigation-planner.js.map +1 -1
- package/dist/server/navigation-trace.d.ts +8 -1
- package/dist/server/navigation-trace.js +7 -0
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/normalize-path.d.ts +2 -1
- package/dist/server/normalize-path.js +4 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-api-route.js +1 -0
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +3 -2
- package/dist/server/pages-page-data.js +22 -3
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/prod-server.d.ts +28 -1
- package/dist/server/prod-server.js +62 -9
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/server-action-not-found.d.ts +16 -3
- package/dist/server/server-action-not-found.js +19 -1
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/server-globals.d.ts +5 -0
- package/dist/server/server-globals.js +37 -0
- package/dist/server/server-globals.js.map +1 -0
- package/dist/server/static-file-cache.js +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/cache-runtime.d.ts +19 -2
- package/dist/shims/cache-runtime.js +67 -11
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +5 -18
- package/dist/shims/cache.js +2 -0
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error-boundary.js +6 -8
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts +18 -1
- package/dist/shims/error.js +56 -1
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +4 -1
- package/dist/shims/fetch-cache.js +40 -5
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +22 -8
- package/dist/shims/font-google-base.js +41 -71
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.d.ts +3 -20
- package/dist/shims/font-local.js +23 -75
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/font-utils.d.ts +51 -0
- package/dist/shims/font-utils.js +97 -0
- package/dist/shims/font-utils.js.map +1 -0
- package/dist/shims/hash-scroll.d.ts +7 -0
- package/dist/shims/hash-scroll.js +30 -0
- package/dist/shims/hash-scroll.js.map +1 -0
- package/dist/shims/headers.d.ts +8 -11
- package/dist/shims/headers.js +22 -2
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts +1 -0
- package/dist/shims/image.js +144 -78
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +6 -6
- package/dist/shims/internal/app-router-context.js +17 -6
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/link-prefetch.d.ts +9 -1
- package/dist/shims/link-prefetch.js +11 -6
- package/dist/shims/link-prefetch.js.map +1 -1
- package/dist/shims/link.d.ts +12 -2
- package/dist/shims/link.js +78 -32
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +16 -30
- package/dist/shims/metadata.js +87 -28
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +158 -17
- package/dist/shims/navigation.js +324 -74
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.d.ts +3 -2
- package/dist/shims/navigation.react-server.js +5 -2
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/pages-router-runtime.d.ts +7 -0
- package/dist/shims/pages-router-runtime.js +16 -0
- package/dist/shims/pages-router-runtime.js.map +1 -0
- package/dist/shims/router.d.ts +32 -6
- package/dist/shims/router.js +197 -242
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.js +110 -32
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +2 -1
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +1 -0
- package/dist/shims/slot.js +41 -1
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/unrecognized-action-error.d.ts +35 -0
- package/dist/shims/unrecognized-action-error.js +41 -0
- package/dist/shims/unrecognized-action-error.js.map +1 -0
- package/dist/shims/url-utils.d.ts +21 -1
- package/dist/shims/url-utils.js +67 -3
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/utils/asset-prefix.d.ts +69 -0
- package/dist/utils/asset-prefix.js +91 -0
- package/dist/utils/asset-prefix.js.map +1 -0
- package/dist/utils/base-path.d.ts +7 -1
- package/dist/utils/base-path.js +10 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +1 -2
- package/dist/utils/navigation-signal.js +1 -1
- package/dist/utils/navigation-signal.js.map +1 -1
- package/dist/utils/sorted-array.d.ts +9 -0
- package/dist/utils/sorted-array.js +22 -0
- package/dist/utils/sorted-array.js.map +1 -0
- package/package.json +3 -3
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
|
-
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, setHeadersContext } from "../shims/headers.js";
|
|
3
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
|
|
4
4
|
import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache.js";
|
|
5
5
|
import { shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
6
|
-
import { ensureFetchPatch, getCollectedFetchTags, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
6
|
+
import { consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
7
7
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
8
8
|
import "./app-elements.js";
|
|
9
|
-
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
|
|
9
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
10
10
|
import { createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
11
|
-
import { readStreamAsText } from "../utils/text-stream.js";
|
|
12
11
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
13
12
|
import { resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
|
|
13
|
+
import { readStreamAsText } from "../utils/text-stream.js";
|
|
14
|
+
import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
14
15
|
import { readAppPageCacheResponse } from "./app-page-cache.js";
|
|
15
16
|
import { buildAppPageSpecialErrorResponse, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
16
17
|
import { resolveAppPageMethodResponse } from "./app-page-method.js";
|
|
@@ -57,7 +58,9 @@ function toInterceptOptions(interceptionContext, intercept) {
|
|
|
57
58
|
interceptLayouts: intercept.interceptLayouts,
|
|
58
59
|
interceptPage: intercept.page,
|
|
59
60
|
interceptParams: intercept.matchedParams,
|
|
60
|
-
|
|
61
|
+
interceptSlotId: intercept.slotId ?? null,
|
|
62
|
+
interceptSlotKey: intercept.slotKey,
|
|
63
|
+
interceptSourceMatchedUrl: interceptionContext
|
|
61
64
|
};
|
|
62
65
|
}
|
|
63
66
|
async function dispatchAppPage(options) {
|
|
@@ -143,17 +146,56 @@ async function dispatchAppPageInner(options) {
|
|
|
143
146
|
links: options.getFontLinks(),
|
|
144
147
|
styles: options.getFontStyles(),
|
|
145
148
|
preloads: options.getFontPreloads()
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
}, {
|
|
150
|
+
basePath: options.basePath,
|
|
151
|
+
...revalidatedRscCapture.sideStream ? {
|
|
152
|
+
sideStream: revalidatedRscCapture.sideStream,
|
|
153
|
+
capturedRscDataRef: revalidatedCapturedRscRef
|
|
154
|
+
} : {}
|
|
155
|
+
}));
|
|
150
156
|
const rscData = await getCapturedRscDataPromise(revalidatedCapturedRscRef.value);
|
|
151
157
|
const cacheLife = _consumeRequestScopedCacheLife();
|
|
152
158
|
options.clearRequestContext();
|
|
159
|
+
const tags = buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), route.routeSegments);
|
|
160
|
+
const observationState = {
|
|
161
|
+
dynamicFetches: consumeDynamicFetchObservations(),
|
|
162
|
+
requestApis: consumeRenderRequestApiUsage()
|
|
163
|
+
};
|
|
153
164
|
return {
|
|
154
165
|
html,
|
|
166
|
+
htmlRenderObservation: createAppPageRenderObservation({
|
|
167
|
+
boundaryOutcome: { kind: "success" },
|
|
168
|
+
cacheability: "public",
|
|
169
|
+
cacheTags: tags,
|
|
170
|
+
cleanPathname: options.cleanPathname,
|
|
171
|
+
completeness: "complete",
|
|
172
|
+
output: createAppPageHtmlOutputScope({
|
|
173
|
+
element: revalidatedElement,
|
|
174
|
+
renderEpoch: null,
|
|
175
|
+
rootBoundaryId: null,
|
|
176
|
+
routePattern: route.pattern
|
|
177
|
+
}),
|
|
178
|
+
params: options.params,
|
|
179
|
+
state: observationState
|
|
180
|
+
}),
|
|
155
181
|
rscData,
|
|
156
|
-
|
|
182
|
+
rscRenderObservation: createAppPageRenderObservation({
|
|
183
|
+
boundaryOutcome: { kind: "success" },
|
|
184
|
+
cacheability: "public",
|
|
185
|
+
cacheTags: tags,
|
|
186
|
+
cleanPathname: options.cleanPathname,
|
|
187
|
+
completeness: "complete",
|
|
188
|
+
output: createAppPageRscOutputScope({
|
|
189
|
+
element: revalidatedElement,
|
|
190
|
+
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
191
|
+
renderEpoch: null,
|
|
192
|
+
rootBoundaryId: null,
|
|
193
|
+
routePattern: route.pattern
|
|
194
|
+
}),
|
|
195
|
+
params: options.params,
|
|
196
|
+
state: observationState
|
|
197
|
+
}),
|
|
198
|
+
tags,
|
|
157
199
|
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
158
200
|
revalidate: cacheLife.revalidate,
|
|
159
201
|
expire: cacheLife.expire
|
|
@@ -199,10 +241,11 @@ async function dispatchAppPageInner(options) {
|
|
|
199
241
|
const interceptOnError = options.createRscOnErrorHandler(options.cleanPathname, sourceRoute.pattern);
|
|
200
242
|
const interceptStream = options.renderToReadableStream(interceptElement, { onError: interceptOnError });
|
|
201
243
|
const interceptHeaders = new Headers({
|
|
202
|
-
"Content-Type":
|
|
244
|
+
"Content-Type": VINEXT_RSC_CONTENT_TYPE,
|
|
203
245
|
Vary: VINEXT_RSC_VARY_HEADER
|
|
204
246
|
});
|
|
205
247
|
mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);
|
|
248
|
+
applyRscCompatibilityIdHeader(interceptHeaders);
|
|
206
249
|
return new Response(interceptStream, {
|
|
207
250
|
status: options.middlewareContext.status ?? 200,
|
|
208
251
|
headers: interceptHeaders
|
|
@@ -217,6 +260,7 @@ async function dispatchAppPageInner(options) {
|
|
|
217
260
|
if (interceptResult.response) return interceptResult.response;
|
|
218
261
|
const pageBuildResult = await buildAppPageElement({
|
|
219
262
|
buildPageElement() {
|
|
263
|
+
if (options.actionFailed) throw options.actionError;
|
|
220
264
|
return options.buildPageElement(route, options.params, interceptResult.interceptOpts, options.searchParams);
|
|
221
265
|
},
|
|
222
266
|
renderErrorBoundaryPage(buildError) {
|
|
@@ -229,10 +273,17 @@ async function dispatchAppPageInner(options) {
|
|
|
229
273
|
});
|
|
230
274
|
if (pageBuildResult.response) return pageBuildResult.response;
|
|
231
275
|
return renderAppPageLifecycle({
|
|
276
|
+
basePath: options.basePath,
|
|
232
277
|
cleanPathname: options.cleanPathname,
|
|
233
278
|
clearRequestContext: options.clearRequestContext,
|
|
234
279
|
consumeDynamicUsage,
|
|
235
280
|
consumeInvalidDynamicUsageError,
|
|
281
|
+
consumeRenderObservationState() {
|
|
282
|
+
return {
|
|
283
|
+
dynamicFetches: consumeDynamicFetchObservations(),
|
|
284
|
+
requestApis: consumeRenderRequestApiUsage()
|
|
285
|
+
};
|
|
286
|
+
},
|
|
236
287
|
createRscOnErrorHandler(pathname, routePath) {
|
|
237
288
|
return options.createRscOnErrorHandler(pathname, routePath);
|
|
238
289
|
},
|
|
@@ -271,6 +322,12 @@ async function dispatchAppPageInner(options) {
|
|
|
271
322
|
loadSsrHandler: options.loadSsrHandler,
|
|
272
323
|
middlewareContext: options.middlewareContext,
|
|
273
324
|
params: options.params,
|
|
325
|
+
peekRenderObservationState() {
|
|
326
|
+
return {
|
|
327
|
+
dynamicFetches: peekDynamicFetchObservations(),
|
|
328
|
+
requestApis: peekRenderRequestApiUsage()
|
|
329
|
+
};
|
|
330
|
+
},
|
|
274
331
|
probeLayoutAt(layoutIndex) {
|
|
275
332
|
return options.probeLayoutAt(layoutIndex);
|
|
276
333
|
},
|
|
@@ -1 +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 { ReactFormState } from \"react-dom/client\";\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 getAndClearPendingCookies,\n getDraftModeCookieHeader,\n isDraftModeRequest,\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 runWithFetchDedupe,\n setCurrentFetchCacheMode,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport { AppElementsWire, type AppOutgoingElements } from \"./app-elements.js\";\nimport { readAppPageCacheResponse } from \"./app-page-cache.js\";\nimport { resolveAppPageParentHttpAccessBoundaryModule } from \"./app-page-boundary.js\";\nimport { readStreamAsText } from \"../utils/text-stream.js\";\nimport {\n buildAppPageSpecialErrorResponse,\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 { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n shouldSuppressLoadingBoundaries,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.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 /** Configured basePath (e.g. \"/blog\"). Used to prefix redirect Locations. */\n basePath?: string;\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 formState?: ReactFormState | 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 isProgressiveActionRender?: boolean;\n isProduction: boolean;\n isRscRequest: boolean;\n isrDebug?: AppPageDebugLogger;\n isrGet: AppPageCacheGetter;\n isrHtmlKey: (pathname: string) => string;\n isrRscKey: (\n pathname: string,\n mountedSlotsHeader?: string | null,\n renderMode?: AppRscRenderMode,\n ) => 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 renderMode?: AppRscRenderMode;\n};\n\nfunction shouldReadAppPageCache(options: {\n isProgressiveActionRender: boolean;\n isDraftMode: boolean;\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.isProgressiveActionRender &&\n !options.isDraftMode &&\n !options.isForceDynamic &&\n (options.isRscRequest || !options.scriptNonce) &&\n (options.revalidateSeconds === null || options.revalidateSeconds > 0)\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 await runWithFetchDedupe(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 return await runWithFetchDedupe(() => dispatchAppPageInner(options));\n}\n\nasync function dispatchAppPageInner<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 const isDraftMode = isDraftModeRequest(options.request);\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) && !isDraftMode) {\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 isDraftMode,\n isForceDynamic,\n isProgressiveActionRender: options.isProgressiveActionRender === true,\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 middlewareHeaders: options.middlewareContext.headers,\n middlewareStatus: options.middlewareContext.status,\n mountedSlotsHeader: options.mountedSlotsHeader,\n renderMode: options.renderMode,\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 // No inner runWithFetchDedupe here: this renderFn is already\n // wrapped in runWithFetchDedupe by runAppPageRevalidationContext.\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 readStreamAsText(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 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 // No inner runWithFetchDedupe here: dispatchAppPage already activated\n // dedupe at line 294, and this callback runs inside dispatchAppPageInner.\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: VINEXT_RSC_VARY_HEADER,\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: shouldSuppressLoadingBoundaries(\n options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION,\n )\n ? false\n : Boolean(route.loading?.default),\n formState: options.formState ?? null,\n isProgressiveActionRender: options.isProgressiveActionRender === true,\n isDynamicError,\n isDraftMode,\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 AppElementsWire.encodeLayoutId(\n createAppPageTreePath([...route.routeSegments], treePosition),\n );\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 renderMode: options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION,\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 basePath: options.basePath,\n clearRequestContext: options.clearRequestContext,\n getAndClearPendingCookies,\n isRscRequest: options.isRscRequest,\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 request: options.request,\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 basePath: options.basePath,\n clearRequestContext: options.clearRequestContext,\n getAndClearPendingCookies,\n isRscRequest: options.isRscRequest,\n middlewareContext: options.middlewareContext,\n renderFallbackPage(statusCode) {\n return options.renderHttpAccessFallbackPage(\n statusCode,\n { matchedParams: options.params },\n null,\n );\n },\n request: options.request,\n specialError,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-page-dispatch.js","names":[],"sources":["../../src/server/app-page-dispatch.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\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 consumeRenderRequestApiUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n isDraftModeRequest,\n markDynamicUsage,\n peekRenderRequestApiUsage,\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 consumeDynamicFetchObservations,\n type FetchCacheMode,\n getCollectedFetchTags,\n peekDynamicFetchObservations,\n runWithFetchDedupe,\n setCurrentFetchCacheMode,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport { AppElementsWire, type AppOutgoingElements } from \"./app-elements.js\";\nimport { readAppPageCacheResponse } from \"./app-page-cache.js\";\nimport { resolveAppPageParentHttpAccessBoundaryModule } from \"./app-page-boundary.js\";\nimport { readStreamAsText } from \"../utils/text-stream.js\";\nimport {\n buildAppPageSpecialErrorResponse,\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 createAppPageHtmlOutputScope,\n createAppPageRenderObservation,\n createAppPageRscOutputScope,\n} from \"./app-page-render-observation.js\";\nimport {\n mergeMiddlewareResponseHeaders,\n type AppPageMiddlewareContext,\n} from \"./app-page-response.js\";\nimport {\n VINEXT_RSC_CONTENT_TYPE,\n VINEXT_RSC_VARY_HEADER,\n applyRscCompatibilityIdHeader,\n} from \"./app-rsc-cache-busting.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n shouldSuppressLoadingBoundaries,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.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 slotId?: string | null;\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 interceptSlotId?: string | null;\n interceptSlotKey: string;\n interceptSourceMatchedUrl?: string | null;\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 /** Configured basePath (e.g. \"/blog\"). Used to prefix redirect Locations. */\n basePath?: string;\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 formState?: ReactFormState | null;\n actionError?: unknown;\n actionFailed?: boolean;\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 isProgressiveActionRender?: boolean;\n isProduction: boolean;\n isRscRequest: boolean;\n isrDebug?: AppPageDebugLogger;\n isrGet: AppPageCacheGetter;\n isrHtmlKey: (pathname: string) => string;\n isrRscKey: (\n pathname: string,\n mountedSlotsHeader?: string | null,\n renderMode?: AppRscRenderMode,\n ) => 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 renderMode?: AppRscRenderMode;\n};\n\nfunction shouldReadAppPageCache(options: {\n isProgressiveActionRender: boolean;\n isDraftMode: boolean;\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.isProgressiveActionRender &&\n !options.isDraftMode &&\n !options.isForceDynamic &&\n (options.isRscRequest || !options.scriptNonce) &&\n (options.revalidateSeconds === null || options.revalidateSeconds > 0)\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 TResult extends {\n html: string;\n rscData: ArrayBuffer;\n tags: string[];\n },\n>(\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<TResult>,\n): Promise<TResult> {\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 await runWithFetchDedupe(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 interceptSlotId: intercept.slotId ?? null,\n interceptSlotKey: intercept.slotKey,\n interceptSourceMatchedUrl: interceptionContext,\n };\n}\n\nexport async function dispatchAppPage<TRoute extends AppPageDispatchRoute>(\n options: DispatchAppPageOptions<TRoute>,\n): Promise<Response> {\n return await runWithFetchDedupe(() => dispatchAppPageInner(options));\n}\n\nasync function dispatchAppPageInner<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 const isDraftMode = isDraftModeRequest(options.request);\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) && !isDraftMode) {\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 isDraftMode,\n isForceDynamic,\n isProgressiveActionRender: options.isProgressiveActionRender === true,\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 middlewareHeaders: options.middlewareContext.headers,\n middlewareStatus: options.middlewareContext.status,\n mountedSlotsHeader: options.mountedSlotsHeader,\n renderMode: options.renderMode,\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 // No inner runWithFetchDedupe here: this renderFn is already\n // wrapped in runWithFetchDedupe by runAppPageRevalidationContext.\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 {\n basePath: options.basePath,\n ...(revalidatedRscCapture.sideStream\n ? {\n sideStream: revalidatedRscCapture.sideStream,\n capturedRscDataRef: revalidatedCapturedRscRef,\n }\n : {}),\n },\n );\n const html = await readStreamAsText(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 // Consume once: HTML and RSC artifacts are produced by the same\n // regeneration render and should carry the same observation set.\n const observationState = {\n dynamicFetches: consumeDynamicFetchObservations(),\n requestApis: consumeRenderRequestApiUsage(),\n };\n return {\n html,\n htmlRenderObservation: createAppPageRenderObservation({\n boundaryOutcome: { kind: \"success\" },\n cacheability: \"public\",\n cacheTags: tags,\n cleanPathname: options.cleanPathname,\n completeness: \"complete\",\n output: createAppPageHtmlOutputScope({\n element: revalidatedElement,\n renderEpoch: null,\n rootBoundaryId: null,\n routePattern: route.pattern,\n }),\n params: options.params,\n state: observationState,\n }),\n rscData,\n rscRenderObservation: createAppPageRenderObservation({\n boundaryOutcome: { kind: \"success\" },\n cacheability: \"public\",\n cacheTags: tags,\n cleanPathname: options.cleanPathname,\n completeness: \"complete\",\n output: createAppPageRscOutputScope({\n element: revalidatedElement,\n mountedSlotsHeader: options.mountedSlotsHeader,\n renderEpoch: null,\n rootBoundaryId: null,\n routePattern: route.pattern,\n }),\n params: options.params,\n state: observationState,\n }),\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 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 // No inner runWithFetchDedupe here: dispatchAppPage already activated\n // dedupe at line 294, and this callback runs inside dispatchAppPageInner.\n const interceptStream = options.renderToReadableStream(interceptElement, {\n onError: interceptOnError,\n });\n const interceptHeaders = new Headers({\n \"Content-Type\": VINEXT_RSC_CONTENT_TYPE,\n Vary: VINEXT_RSC_VARY_HEADER,\n });\n mergeMiddlewareResponseHeaders(interceptHeaders, options.middlewareContext.headers);\n applyRscCompatibilityIdHeader(interceptHeaders);\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 if (options.actionFailed) {\n throw options.actionError;\n }\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 basePath: options.basePath,\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n consumeInvalidDynamicUsageError,\n consumeRenderObservationState() {\n return {\n dynamicFetches: consumeDynamicFetchObservations(),\n requestApis: consumeRenderRequestApiUsage(),\n };\n },\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: shouldSuppressLoadingBoundaries(\n options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION,\n )\n ? false\n : Boolean(route.loading?.default),\n formState: options.formState ?? null,\n isProgressiveActionRender: options.isProgressiveActionRender === true,\n isDynamicError,\n isDraftMode,\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 peekRenderObservationState() {\n return {\n dynamicFetches: peekDynamicFetchObservations(),\n requestApis: peekRenderRequestApiUsage(),\n };\n },\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 AppElementsWire.encodeLayoutId(\n createAppPageTreePath([...route.routeSegments], treePosition),\n );\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 renderMode: options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION,\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 basePath: options.basePath,\n clearRequestContext: options.clearRequestContext,\n getAndClearPendingCookies,\n isRscRequest: options.isRscRequest,\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 request: options.request,\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 basePath: options.basePath,\n clearRequestContext: options.clearRequestContext,\n getAndClearPendingCookies,\n isRscRequest: options.isRscRequest,\n middlewareContext: options.middlewareContext,\n renderFallbackPage(statusCode) {\n return options.renderHttpAccessFallbackPage(\n statusCode,\n { matchedParams: options.params },\n null,\n );\n },\n request: options.request,\n specialError,\n });\n}\n"],"mappings":"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"}
|
|
@@ -20,7 +20,9 @@ type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
|
|
|
20
20
|
interceptLayouts?: readonly (TModule | null | undefined)[] | null;
|
|
21
21
|
interceptPage?: TModule | null;
|
|
22
22
|
interceptParams?: AppPageParams | null;
|
|
23
|
+
interceptSlotId?: string | null;
|
|
23
24
|
interceptSlotKey?: string | null;
|
|
25
|
+
interceptSourceMatchedUrl?: string | null;
|
|
24
26
|
};
|
|
25
27
|
type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
|
|
26
28
|
/** Interception context from current-route navigation (null for direct visits). */opts?: AppPageInterceptOptions<TModule> | null; /** URL search params from the incoming request (null when unavailable). */
|
|
@@ -40,6 +42,11 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
|
|
|
40
42
|
rootForbiddenModule?: TModule | null; /** Root-level unauthorized.tsx module. Present when the app defines this file. */
|
|
41
43
|
rootUnauthorizedModule?: TModule | null; /** File-based metadata routes (favicon, manifest, sitemap, etc.). */
|
|
42
44
|
metadataRoutes: readonly MetadataFileRoute[];
|
|
45
|
+
/**
|
|
46
|
+
* Configured next.config `basePath`. Threaded through `resolveAppPageHead`
|
|
47
|
+
* so file-based metadata route URLs emitted in <head> are prefixed.
|
|
48
|
+
*/
|
|
49
|
+
basePath?: string;
|
|
43
50
|
};
|
|
44
51
|
/**
|
|
45
52
|
* Build the App Router element tree for a matched route.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
|
+
import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
|
|
3
|
+
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
4
|
+
import { markDynamicUsage, markRenderRequestApiUsage } from "../shims/headers.js";
|
|
2
5
|
import { APP_RSC_RENDER_MODE_NAVIGATION } from "./app-rsc-render-mode.js";
|
|
3
6
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
7
|
import "./app-elements.js";
|
|
5
|
-
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
6
8
|
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
7
9
|
import { buildAppPageElements, createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
8
10
|
import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
|
|
@@ -29,7 +31,9 @@ async function buildPageElements(options) {
|
|
|
29
31
|
const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION } = pageRequest;
|
|
30
32
|
const pageModule = route.page;
|
|
31
33
|
const PageComponent = pageModule?.default;
|
|
32
|
-
|
|
34
|
+
const hasPageModule = !!pageModule;
|
|
35
|
+
const interception = createAppPageInterceptionProof(routePath, opts);
|
|
36
|
+
if (hasPageModule && !PageComponent) {
|
|
33
37
|
const interceptionContext = opts?.interceptionContext ?? null;
|
|
34
38
|
const noExportRouteId = AppElementsWire.encodeRouteId(routePath, interceptionContext);
|
|
35
39
|
let noExportRootLayout = null;
|
|
@@ -40,6 +44,7 @@ async function buildPageElements(options) {
|
|
|
40
44
|
}
|
|
41
45
|
return {
|
|
42
46
|
...AppElementsWire.createMetadataEntries({
|
|
47
|
+
interception,
|
|
43
48
|
interceptionContext,
|
|
44
49
|
layoutIds: noExportLayoutIds,
|
|
45
50
|
rootLayoutTreePath: noExportRootLayout,
|
|
@@ -49,6 +54,7 @@ async function buildPageElements(options) {
|
|
|
49
54
|
};
|
|
50
55
|
}
|
|
51
56
|
const { hasSearchParams, metadata: resolvedMetadata, pageSearchParams, viewport: resolvedViewport } = await resolveAppPageHead({
|
|
57
|
+
basePath: options.basePath ?? "",
|
|
52
58
|
layoutModules: route.layouts,
|
|
53
59
|
layoutTreePositions: route.layoutTreePositions,
|
|
54
60
|
metadataRoutes,
|
|
@@ -70,7 +76,10 @@ async function buildPageElements(options) {
|
|
|
70
76
|
const pageProps = { params: makeThenableParams(params) };
|
|
71
77
|
if (searchParams) {
|
|
72
78
|
pageProps.searchParams = makeThenableParams(pageSearchParams);
|
|
73
|
-
if (hasSearchParams)
|
|
79
|
+
if (hasSearchParams) {
|
|
80
|
+
markDynamicUsage();
|
|
81
|
+
markRenderRequestApiUsage("searchParams");
|
|
82
|
+
}
|
|
74
83
|
}
|
|
75
84
|
const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(" ")) : null;
|
|
76
85
|
const slotOverrides = buildSlotOverrides(route, params, routePath, opts);
|
|
@@ -82,8 +91,10 @@ async function buildPageElements(options) {
|
|
|
82
91
|
makeThenableParams,
|
|
83
92
|
matchedParams: params,
|
|
84
93
|
resolvedMetadata,
|
|
94
|
+
resolvedMetadataPathname: routePath,
|
|
85
95
|
resolvedViewport,
|
|
86
96
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
97
|
+
interception,
|
|
87
98
|
routePath,
|
|
88
99
|
rootNotFoundModule: rootNotFoundModule ?? null,
|
|
89
100
|
rootForbiddenModule: rootForbiddenModule ?? null,
|
|
@@ -93,6 +104,23 @@ async function buildPageElements(options) {
|
|
|
93
104
|
renderMode
|
|
94
105
|
});
|
|
95
106
|
}
|
|
107
|
+
function createAppPageInterceptionProof(routePath, opts) {
|
|
108
|
+
const sourceMatchedUrl = normalizeInterceptionProofMatchedUrl(opts?.interceptSourceMatchedUrl ?? null);
|
|
109
|
+
const targetMatchedUrl = normalizeInterceptionProofMatchedUrl(routePath);
|
|
110
|
+
const slotId = opts?.interceptSlotId ?? null;
|
|
111
|
+
if (sourceMatchedUrl === null || targetMatchedUrl === null || slotId === null) return null;
|
|
112
|
+
return {
|
|
113
|
+
sourceMatchedUrl,
|
|
114
|
+
sourceRouteId: AppElementsWire.encodeRouteId(sourceMatchedUrl, null),
|
|
115
|
+
slotId,
|
|
116
|
+
targetMatchedUrl,
|
|
117
|
+
targetRouteId: AppElementsWire.encodeRouteId(targetMatchedUrl, null)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function normalizeInterceptionProofMatchedUrl(value) {
|
|
121
|
+
if (value === null || !isInterceptionMatchedUrlPath(value)) return null;
|
|
122
|
+
return normalizePath(normalizePathnameForRouteMatch(value));
|
|
123
|
+
}
|
|
96
124
|
/**
|
|
97
125
|
* Build the per-request `slotOverrides` map. Combines:
|
|
98
126
|
* - Interception overrides (existing behavior — swap in the intercepting page
|
|
@@ -1 +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 { AppElementsWire, type AppElements } 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\";\nimport { APP_RSC_RENDER_MODE_NAVIGATION, type AppRscRenderMode } from \"./app-rsc-render-mode.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 /** Semantic RSC payload mode for this page render. */\n renderMode?: AppRscRenderMode;\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 {\n opts,\n searchParams,\n isRscRequest,\n mountedSlotsHeader,\n renderMode = APP_RSC_RENDER_MODE_NAVIGATION,\n } = 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 = AppElementsWire.encodeRouteId(routePath, interceptionContext);\n let noExportRootLayout: string | null = null;\n const noExportLayoutIds =\n route.ids?.layouts ??\n route.layouts.map((_, index) =>\n AppElementsWire.encodeLayoutId(\n createAppPageTreePath(route.routeSegments, route.layoutTreePositions?.[index] ?? 0),\n ),\n );\n if (route.layouts?.length > 0) {\n const treePosition = route.layoutTreePositions?.[0] ?? 0;\n noExportRootLayout = createAppPageTreePath(route.routeSegments, treePosition);\n }\n return {\n ...AppElementsWire.createMetadataEntries({\n interceptionContext,\n layoutIds: noExportLayoutIds,\n rootLayoutTreePath: noExportRootLayout,\n routeId: noExportRouteId,\n }),\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 renderMode,\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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"}
|
|
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, markRenderRequestApiUsage } 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 { AppElementsWire, type AppElements, type AppElementsInterception } from \"./app-elements.js\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport { matchRoutePattern } from \"../routing/route-pattern.js\";\nimport { normalizePathnameForRouteMatch } from \"../routing/utils.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\nimport { APP_RSC_RENDER_MODE_NAVIGATION, type AppRscRenderMode } from \"./app-rsc-render-mode.js\";\nimport { isInterceptionMatchedUrlPath, normalizePath } from \"./normalize-path.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 interceptSlotId?: string | null;\n interceptSlotKey?: string | null;\n interceptSourceMatchedUrl?: 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 /** Semantic RSC payload mode for this page render. */\n renderMode?: AppRscRenderMode;\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 * Configured next.config `basePath`. Threaded through `resolveAppPageHead`\n * so file-based metadata route URLs emitted in <head> are prefixed.\n */\n basePath?: string;\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 {\n opts,\n searchParams,\n isRscRequest,\n mountedSlotsHeader,\n renderMode = APP_RSC_RENDER_MODE_NAVIGATION,\n } = pageRequest;\n\n const pageModule: AppPageModule | null | undefined = route.page;\n const PageComponent = pageModule?.default;\n const hasPageModule = !!pageModule;\n const interception = createAppPageInterceptionProof(routePath, opts);\n\n if (hasPageModule && !PageComponent) {\n const interceptionContext = opts?.interceptionContext ?? null;\n const noExportRouteId = AppElementsWire.encodeRouteId(routePath, interceptionContext);\n let noExportRootLayout: string | null = null;\n const noExportLayoutIds =\n route.ids?.layouts ??\n route.layouts.map((_, index) =>\n AppElementsWire.encodeLayoutId(\n createAppPageTreePath(route.routeSegments, route.layoutTreePositions?.[index] ?? 0),\n ),\n );\n if (route.layouts?.length > 0) {\n const treePosition = route.layoutTreePositions?.[0] ?? 0;\n noExportRootLayout = createAppPageTreePath(route.routeSegments, treePosition);\n }\n return {\n ...AppElementsWire.createMetadataEntries({\n interception,\n interceptionContext,\n layoutIds: noExportLayoutIds,\n rootLayoutTreePath: noExportRootLayout,\n routeId: noExportRouteId,\n }),\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 basePath: options.basePath ?? \"\",\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) {\n markDynamicUsage();\n markRenderRequestApiUsage(\"searchParams\");\n }\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 resolvedMetadataPathname: routePath,\n resolvedViewport,\n interceptionContext: opts?.interceptionContext ?? null,\n interception,\n routePath,\n rootNotFoundModule: rootNotFoundModule ?? null,\n rootForbiddenModule: rootForbiddenModule ?? null,\n rootUnauthorizedModule: rootUnauthorizedModule ?? null,\n route,\n slotOverrides,\n renderMode,\n });\n}\n\nfunction createAppPageInterceptionProof<TModule extends AppPageModule>(\n routePath: string,\n opts?: AppPageInterceptOptions<TModule> | null,\n): AppElementsInterception | null {\n const sourceMatchedUrl = normalizeInterceptionProofMatchedUrl(\n opts?.interceptSourceMatchedUrl ?? null,\n );\n const targetMatchedUrl = normalizeInterceptionProofMatchedUrl(routePath);\n const slotId = opts?.interceptSlotId ?? null;\n if (sourceMatchedUrl === null || targetMatchedUrl === null || slotId === null) return null;\n\n return {\n sourceMatchedUrl,\n sourceRouteId: AppElementsWire.encodeRouteId(sourceMatchedUrl, null),\n slotId,\n targetMatchedUrl,\n targetRouteId: AppElementsWire.encodeRouteId(targetMatchedUrl, null),\n };\n}\n\nfunction normalizeInterceptionProofMatchedUrl(value: string | null): string | null {\n if (value === null || !isInterceptionMatchedUrlPath(value)) return null;\n\n return normalizePath(normalizePathnameForRouteMatch(value));\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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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { addBasePathToPathname } from "../utils/base-path.js";
|
|
2
2
|
import { createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
3
3
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
4
4
|
import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
@@ -51,8 +51,7 @@ function applyAppPageRedirectBasePath(location, requestUrl, basePath) {
|
|
|
51
51
|
const resolved = new URL(location, requestUrl);
|
|
52
52
|
const requestOrigin = new URL(requestUrl).origin;
|
|
53
53
|
if (!basePath || resolved.origin !== requestOrigin) return resolved.toString();
|
|
54
|
-
|
|
55
|
-
resolved.pathname = resolved.pathname === "/" ? basePath : `${basePath}${resolved.pathname}`;
|
|
54
|
+
resolved.pathname = addBasePathToPathname(resolved.pathname, basePath);
|
|
56
55
|
return resolved.toString();
|
|
57
56
|
}
|
|
58
57
|
async function buildAppPageSpecialErrorResponse(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-page-execution.js","names":[],"sources":["../../src/server/app-page-execution.ts"],"sourcesContent":["import type { LayoutFlags } from \"./app-elements.js\";\nimport type { ClassificationReason } from \"../build/layout-classification-types.js\";\nimport { createRscRedirectLocation } from \"./app-rsc-cache-busting.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport { parseNextHttpErrorDigest, parseNextRedirectDigest } from \"./next-error-digest.js\";\nimport { hasBasePath } from \"../utils/base-path.js\";\n\nexport type { LayoutFlags };\nexport type { ClassificationReason };\n\nexport type AppPageSpecialError =\n | { kind: \"redirect\"; location: string; statusCode: number }\n | { kind: \"http-access-fallback\"; statusCode: number };\n\nexport type AppPageFontPreload = {\n href: string;\n type: string;\n};\n\ntype AppPageRscStreamCapture = {\n /** Stream for createFromReadableStream (SSR). Always set. */\n ssrStream: ReadableStream<Uint8Array>;\n /** When capturing, the combined embed+capture stream. handleSsr consumes this. */\n sideStream?: ReadableStream<Uint8Array>;\n};\n\ntype BuildAppPageSpecialErrorResponseOptions = {\n /**\n * Optional configured basePath (e.g. \"/blog\"). When set, redirect Locations\n * pointing at app-internal paths get prefixed so callers see e.g.\n * `Location: /blog/about` for `redirect(\"/about\")`. Mirrors Next.js's\n * `addPathPrefix(getURLFromRedirectError(err), basePath)` in app-render.tsx.\n * External URLs (those that resolve to a different origin than the request)\n * are left untouched.\n */\n basePath?: string;\n clearRequestContext: () => void;\n /**\n * Drains and returns Set-Cookie header values that were accumulated during\n * this render via cookies().set() / cookies().delete(). Appended to redirect\n * responses so an auth flow that does `cookies().set(\"session\", \"...\");\n * redirect(\"/\")` preserves the cookie on the 307. Mirrors Next.js's\n * `appendMutableCookies(headers, requestStore.mutableCookies)` in\n * app-render.tsx. Only applied to redirect responses to match Next.js;\n * the http-access-fallback path leaves cookies to the rendered boundary.\n */\n getAndClearPendingCookies?: () => string[];\n isRscRequest: boolean;\n middlewareContext?: { headers: Headers | null };\n renderFallbackPage?: (statusCode: number) => Promise<Response | null>;\n request: Request;\n specialError: AppPageSpecialError;\n};\n\ntype ProbeAppPageLayoutsResult = {\n response: Response | null;\n layoutFlags: LayoutFlags;\n};\n\nexport type LayoutClassificationOptions = {\n /** Build-time classifications from segment config or module graph, keyed by layout index. */\n buildTimeClassifications?: ReadonlyMap<number, \"static\" | \"dynamic\"> | null;\n /**\n * Per-layout classification reasons keyed by layout index. Requires\n * `VINEXT_DEBUG_CLASSIFICATION` at BOTH lifecycle points: at build time so\n * the plugin patches the `__VINEXT_CLASS_REASONS` dispatch stub, and at\n * runtime so the route object actually calls it. Setting the flag only at\n * runtime leaves the stub returning `null`, and every build-time classified\n * layout will fall through to `{ layer: \"no-classifier\" }` in the debug\n * channel. The hot path never reads this and the wire payload is unchanged.\n */\n buildTimeReasons?: ReadonlyMap<number, ClassificationReason> | null;\n /**\n * Emits one log line per layout with the classification reason, keyed by\n * layout ID. Set by the generator when `VINEXT_DEBUG_CLASSIFICATION` is\n * active. When undefined, the probe loop skips debug emission entirely.\n */\n debugClassification?: (layoutId: string, reason: ClassificationReason) => void;\n /** Maps layout index to its layout ID (e.g. \"layout:/blog\"). */\n getLayoutId: (layoutIndex: number) => string;\n /** Runs a function with isolated dynamic usage tracking per layout. */\n runWithIsolatedDynamicScope: <T>(fn: () => T) => Promise<{ result: T; dynamicDetected: boolean }>;\n};\n\ntype ProbeAppPageLayoutsOptions = {\n layoutCount: number;\n onLayoutError: (error: unknown, layoutIndex: number) => Promise<Response | null>;\n probeLayoutAt: (layoutIndex: number) => unknown;\n runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;\n /** When provided, enables per-layout static/dynamic classification. */\n classification?: LayoutClassificationOptions | null;\n};\n\ntype ProbeAppPageComponentOptions = {\n awaitAsyncResult: boolean;\n onError: (error: unknown) => Promise<Response | null>;\n probePage: () => unknown;\n runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;\n};\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"then\" in value &&\n typeof value.then === \"function\",\n );\n}\n\nfunction getAppPageStatusText(statusCode: number): string {\n return statusCode === 403 ? \"Forbidden\" : statusCode === 401 ? \"Unauthorized\" : \"Not Found\";\n}\n\nfunction mergeAppPageSpecialErrorHeaders(\n response: Response,\n middlewareContext: { headers: Headers | null } | undefined,\n): Response {\n const headers = new Headers(response.headers);\n mergeMiddlewareResponseHeaders(headers, middlewareContext?.headers ?? null);\n\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\nexport function resolveAppPageSpecialError(error: unknown): AppPageSpecialError | null {\n if (!(error && typeof error === \"object\" && \"digest\" in error)) {\n return null;\n }\n\n const digest = String(error.digest);\n\n const redirect = parseNextRedirectDigest(digest);\n if (redirect) {\n return {\n kind: \"redirect\",\n location: redirect.url,\n statusCode: redirect.status,\n };\n }\n\n const httpError = parseNextHttpErrorDigest(digest);\n if (httpError) {\n return {\n kind: \"http-access-fallback\",\n statusCode: httpError.status,\n };\n }\n\n return null;\n}\n\n/**\n * Resolves a redirect() target against the request URL and prepends the\n * configured basePath when the target is an app-internal absolute path.\n *\n * Mirrors Next.js's `addPathPrefix(getURLFromRedirectError(err), basePath)`\n * in `app-render.tsx`: a `redirect(\"/about\")` call from a page mounted at\n * `/blog` (basePath) produces `Location: /blog/about`.\n *\n * Skips prefixing when:\n * - basePath is unset / empty\n * - the target is a full URL pointing at a different origin (external redirect)\n * - the target already starts with the basePath (caller did the work themselves)\n */\nfunction applyAppPageRedirectBasePath(\n location: string,\n requestUrl: string,\n basePath: string | undefined,\n): string {\n const resolved = new URL(location, requestUrl);\n const requestOrigin = new URL(requestUrl).origin;\n if (!basePath || resolved.origin !== requestOrigin) {\n return resolved.toString();\n }\n if (hasBasePath(resolved.pathname, basePath)) {\n return resolved.toString();\n }\n resolved.pathname = resolved.pathname === \"/\" ? basePath : `${basePath}${resolved.pathname}`;\n return resolved.toString();\n}\n\nexport async function buildAppPageSpecialErrorResponse(\n options: BuildAppPageSpecialErrorResponseOptions,\n): Promise<Response> {\n if (options.specialError.kind === \"redirect\") {\n options.clearRequestContext();\n // Apply configured basePath first so app-internal targets land at\n // /<basePath>/<target> before the RSC cache-busting transform sees them.\n const prefixedLocation = applyAppPageRedirectBasePath(\n options.specialError.location,\n options.request.url,\n options.basePath,\n );\n const location = options.isRscRequest\n ? await createRscRedirectLocation(prefixedLocation, options.request)\n : prefixedLocation;\n const headers = new Headers({\n Location: location,\n });\n // Middleware may contribute response headers here, but redirect() owns the\n // status. Do not apply middlewareContext.status on special-error responses.\n mergeMiddlewareResponseHeaders(headers, options.middlewareContext?.headers ?? null);\n // Preserve cookies set via cookies().set() / cookies().delete() during the\n // page render — auth flows commonly set a session cookie and immediately\n // redirect, and those Set-Cookie values must ride on the 307.\n const pendingCookies = options.getAndClearPendingCookies?.() ?? [];\n for (const cookie of pendingCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n\n return new Response(null, {\n headers,\n status: options.specialError.statusCode,\n });\n }\n\n if (options.renderFallbackPage) {\n const fallbackResponse = await options.renderFallbackPage(options.specialError.statusCode);\n if (fallbackResponse) {\n return mergeAppPageSpecialErrorHeaders(fallbackResponse, options.middlewareContext);\n }\n }\n\n options.clearRequestContext();\n return mergeAppPageSpecialErrorHeaders(\n new Response(getAppPageStatusText(options.specialError.statusCode), {\n status: options.specialError.statusCode,\n }),\n options.middlewareContext,\n );\n}\n\n/** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */\nexport async function probeAppPageLayouts(\n options: ProbeAppPageLayoutsOptions,\n): Promise<ProbeAppPageLayoutsResult> {\n const layoutFlags: Record<string, \"s\" | \"d\"> = {};\n const cls = options.classification ?? null;\n\n const response = await options.runWithSuppressedHookWarning(async () => {\n for (let layoutIndex = options.layoutCount - 1; layoutIndex >= 0; layoutIndex--) {\n const buildTimeResult = cls?.buildTimeClassifications?.get(layoutIndex);\n\n if (cls && buildTimeResult) {\n // Build-time classified (Layer 1 or Layer 2): skip dynamic isolation,\n // but still probe for special errors (redirects, not-found).\n layoutFlags[cls.getLayoutId(layoutIndex)] = buildTimeResult === \"static\" ? \"s\" : \"d\";\n if (cls.debugClassification) {\n // `no-classifier` is the documented fallback for a layout that was\n // build-time classified but whose reason payload is absent — either\n // because the build was run without `VINEXT_DEBUG_CLASSIFICATION` or\n // because no Layer 1/2 classifier attached a reason. This is the sole\n // producer of the variant; see `layout-classification-types.ts`.\n cls.debugClassification(\n cls.getLayoutId(layoutIndex),\n cls.buildTimeReasons?.get(layoutIndex) ?? { layer: \"no-classifier\" },\n );\n }\n const errorResponse = await probeLayoutForErrors(options, layoutIndex);\n if (errorResponse) return errorResponse;\n continue;\n }\n\n if (cls) {\n // Layer 3: probe with isolated dynamic scope to detect per-layout\n // dynamic API usage (headers(), cookies(), connection(), etc.)\n try {\n const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(() =>\n options.probeLayoutAt(layoutIndex),\n );\n layoutFlags[cls.getLayoutId(layoutIndex)] = dynamicDetected ? \"d\" : \"s\";\n if (cls.debugClassification) {\n cls.debugClassification(cls.getLayoutId(layoutIndex), {\n layer: \"runtime-probe\",\n outcome: dynamicDetected ? \"dynamic\" : \"static\",\n });\n }\n } catch (error) {\n // Probe failed — conservatively treat as dynamic.\n layoutFlags[cls.getLayoutId(layoutIndex)] = \"d\";\n if (cls.debugClassification) {\n cls.debugClassification(cls.getLayoutId(layoutIndex), {\n layer: \"runtime-probe\",\n outcome: \"dynamic\",\n error: error instanceof Error ? error.message : String(error),\n });\n }\n const errorResponse = await options.onLayoutError(error, layoutIndex);\n if (errorResponse) return errorResponse;\n }\n continue;\n }\n\n // No classification options — original behavior\n const errorResponse = await probeLayoutForErrors(options, layoutIndex);\n if (errorResponse) return errorResponse;\n }\n\n return null;\n });\n\n return { response, layoutFlags };\n}\n\nasync function probeLayoutForErrors(\n options: ProbeAppPageLayoutsOptions,\n layoutIndex: number,\n): Promise<Response | null> {\n try {\n const layoutResult = options.probeLayoutAt(layoutIndex);\n if (isPromiseLike(layoutResult)) {\n await layoutResult;\n }\n } catch (error) {\n return options.onLayoutError(error, layoutIndex);\n }\n return null;\n}\n\nexport async function probeAppPageComponent(\n options: ProbeAppPageComponentOptions,\n): Promise<Response | null> {\n return options.runWithSuppressedHookWarning(async () => {\n try {\n const pageResult = options.probePage();\n if (isPromiseLike(pageResult)) {\n if (options.awaitAsyncResult) {\n await pageResult;\n } else {\n void Promise.resolve(pageResult).catch(() => {});\n }\n }\n } catch (error) {\n return options.onError(error);\n }\n\n return null;\n });\n}\n\nexport async function readAppPageBinaryStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<ArrayBuffer> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(value);\n totalLength += value.byteLength;\n }\n\n const buffer = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return buffer.buffer;\n}\n\nexport function teeAppPageRscStreamForCapture(\n stream: ReadableStream<Uint8Array>,\n shouldCapture: boolean,\n): AppPageRscStreamCapture {\n if (!shouldCapture) {\n return {\n ssrStream: stream,\n };\n }\n\n const [ssrStream, sideStream] = stream.tee();\n return {\n ssrStream,\n sideStream,\n };\n}\n\nexport function buildAppPageFontLinkHeader(\n preloads: readonly AppPageFontPreload[] | null | undefined,\n): string {\n if (!preloads || preloads.length === 0) {\n return \"\";\n }\n\n return preloads\n .map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`)\n .join(\", \");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-page-execution.js","names":[],"sources":["../../src/server/app-page-execution.ts"],"sourcesContent":["import type { LayoutFlags } from \"./app-elements.js\";\nimport type { ClassificationReason } from \"../build/layout-classification-types.js\";\nimport { createRscRedirectLocation } from \"./app-rsc-cache-busting.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport { parseNextHttpErrorDigest, parseNextRedirectDigest } from \"./next-error-digest.js\";\nimport { addBasePathToPathname } from \"../utils/base-path.js\";\n\nexport type { LayoutFlags };\nexport type { ClassificationReason };\n\nexport type AppPageSpecialError =\n | { kind: \"redirect\"; location: string; statusCode: number }\n | { kind: \"http-access-fallback\"; statusCode: number };\n\nexport type AppPageFontPreload = {\n href: string;\n type: string;\n};\n\ntype AppPageRscStreamCapture = {\n /** Stream for createFromReadableStream (SSR). Always set. */\n ssrStream: ReadableStream<Uint8Array>;\n /** When capturing, the combined embed+capture stream. handleSsr consumes this. */\n sideStream?: ReadableStream<Uint8Array>;\n};\n\ntype BuildAppPageSpecialErrorResponseOptions = {\n /**\n * Optional configured basePath (e.g. \"/blog\"). When set, redirect Locations\n * pointing at app-internal paths get prefixed so callers see e.g.\n * `Location: /blog/about` for `redirect(\"/about\")`. Mirrors Next.js's\n * `addPathPrefix(getURLFromRedirectError(err), basePath)` in app-render.tsx.\n * External URLs (those that resolve to a different origin than the request)\n * are left untouched.\n */\n basePath?: string;\n clearRequestContext: () => void;\n /**\n * Drains and returns Set-Cookie header values that were accumulated during\n * this render via cookies().set() / cookies().delete(). Appended to redirect\n * responses so an auth flow that does `cookies().set(\"session\", \"...\");\n * redirect(\"/\")` preserves the cookie on the 307. Mirrors Next.js's\n * `appendMutableCookies(headers, requestStore.mutableCookies)` in\n * app-render.tsx. Only applied to redirect responses to match Next.js;\n * the http-access-fallback path leaves cookies to the rendered boundary.\n */\n getAndClearPendingCookies?: () => string[];\n isRscRequest: boolean;\n middlewareContext?: { headers: Headers | null };\n renderFallbackPage?: (statusCode: number) => Promise<Response | null>;\n request: Request;\n specialError: AppPageSpecialError;\n};\n\ntype ProbeAppPageLayoutsResult = {\n response: Response | null;\n layoutFlags: LayoutFlags;\n};\n\nexport type LayoutClassificationOptions = {\n /** Build-time classifications from segment config or module graph, keyed by layout index. */\n buildTimeClassifications?: ReadonlyMap<number, \"static\" | \"dynamic\"> | null;\n /**\n * Per-layout classification reasons keyed by layout index. Requires\n * `VINEXT_DEBUG_CLASSIFICATION` at BOTH lifecycle points: at build time so\n * the plugin patches the `__VINEXT_CLASS_REASONS` dispatch stub, and at\n * runtime so the route object actually calls it. Setting the flag only at\n * runtime leaves the stub returning `null`, and every build-time classified\n * layout will fall through to `{ layer: \"no-classifier\" }` in the debug\n * channel. The hot path never reads this and the wire payload is unchanged.\n */\n buildTimeReasons?: ReadonlyMap<number, ClassificationReason> | null;\n /**\n * Emits one log line per layout with the classification reason, keyed by\n * layout ID. Set by the generator when `VINEXT_DEBUG_CLASSIFICATION` is\n * active. When undefined, the probe loop skips debug emission entirely.\n */\n debugClassification?: (layoutId: string, reason: ClassificationReason) => void;\n /** Maps layout index to its layout ID (e.g. \"layout:/blog\"). */\n getLayoutId: (layoutIndex: number) => string;\n /** Runs a function with isolated dynamic usage tracking per layout. */\n runWithIsolatedDynamicScope: <T>(fn: () => T) => Promise<{ result: T; dynamicDetected: boolean }>;\n};\n\ntype ProbeAppPageLayoutsOptions = {\n layoutCount: number;\n onLayoutError: (error: unknown, layoutIndex: number) => Promise<Response | null>;\n probeLayoutAt: (layoutIndex: number) => unknown;\n runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;\n /** When provided, enables per-layout static/dynamic classification. */\n classification?: LayoutClassificationOptions | null;\n};\n\ntype ProbeAppPageComponentOptions = {\n awaitAsyncResult: boolean;\n onError: (error: unknown) => Promise<Response | null>;\n probePage: () => unknown;\n runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;\n};\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"then\" in value &&\n typeof value.then === \"function\",\n );\n}\n\nfunction getAppPageStatusText(statusCode: number): string {\n return statusCode === 403 ? \"Forbidden\" : statusCode === 401 ? \"Unauthorized\" : \"Not Found\";\n}\n\nfunction mergeAppPageSpecialErrorHeaders(\n response: Response,\n middlewareContext: { headers: Headers | null } | undefined,\n): Response {\n const headers = new Headers(response.headers);\n mergeMiddlewareResponseHeaders(headers, middlewareContext?.headers ?? null);\n\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\nexport function resolveAppPageSpecialError(error: unknown): AppPageSpecialError | null {\n if (!(error && typeof error === \"object\" && \"digest\" in error)) {\n return null;\n }\n\n const digest = String(error.digest);\n\n const redirect = parseNextRedirectDigest(digest);\n if (redirect) {\n return {\n kind: \"redirect\",\n location: redirect.url,\n statusCode: redirect.status,\n };\n }\n\n const httpError = parseNextHttpErrorDigest(digest);\n if (httpError) {\n return {\n kind: \"http-access-fallback\",\n statusCode: httpError.status,\n };\n }\n\n return null;\n}\n\n/**\n * Resolves a redirect() target against the request URL and prepends the\n * configured basePath when the target is an app-internal absolute path.\n *\n * Mirrors Next.js's `addPathPrefix(getURLFromRedirectError(err), basePath)`\n * in `app-render.tsx`: a `redirect(\"/about\")` call from a page mounted at\n * `/blog` (basePath) produces `Location: /blog/about`.\n *\n * Skips prefixing when:\n * - basePath is unset / empty\n * - the target is a full URL pointing at a different origin (external redirect)\n * - the target already starts with the basePath (caller did the work themselves)\n */\nfunction applyAppPageRedirectBasePath(\n location: string,\n requestUrl: string,\n basePath: string | undefined,\n): string {\n const resolved = new URL(location, requestUrl);\n const requestOrigin = new URL(requestUrl).origin;\n if (!basePath || resolved.origin !== requestOrigin) {\n return resolved.toString();\n }\n resolved.pathname = addBasePathToPathname(resolved.pathname, basePath);\n return resolved.toString();\n}\n\nexport async function buildAppPageSpecialErrorResponse(\n options: BuildAppPageSpecialErrorResponseOptions,\n): Promise<Response> {\n if (options.specialError.kind === \"redirect\") {\n options.clearRequestContext();\n // Apply configured basePath first so app-internal targets land at\n // /<basePath>/<target> before the RSC cache-busting transform sees them.\n const prefixedLocation = applyAppPageRedirectBasePath(\n options.specialError.location,\n options.request.url,\n options.basePath,\n );\n const location = options.isRscRequest\n ? await createRscRedirectLocation(prefixedLocation, options.request)\n : prefixedLocation;\n const headers = new Headers({\n Location: location,\n });\n // Middleware may contribute response headers here, but redirect() owns the\n // status. Do not apply middlewareContext.status on special-error responses.\n mergeMiddlewareResponseHeaders(headers, options.middlewareContext?.headers ?? null);\n // Preserve cookies set via cookies().set() / cookies().delete() during the\n // page render — auth flows commonly set a session cookie and immediately\n // redirect, and those Set-Cookie values must ride on the 307.\n const pendingCookies = options.getAndClearPendingCookies?.() ?? [];\n for (const cookie of pendingCookies) {\n headers.append(\"Set-Cookie\", cookie);\n }\n\n return new Response(null, {\n headers,\n status: options.specialError.statusCode,\n });\n }\n\n if (options.renderFallbackPage) {\n const fallbackResponse = await options.renderFallbackPage(options.specialError.statusCode);\n if (fallbackResponse) {\n return mergeAppPageSpecialErrorHeaders(fallbackResponse, options.middlewareContext);\n }\n }\n\n options.clearRequestContext();\n return mergeAppPageSpecialErrorHeaders(\n new Response(getAppPageStatusText(options.specialError.statusCode), {\n status: options.specialError.statusCode,\n }),\n options.middlewareContext,\n );\n}\n\n/** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */\nexport async function probeAppPageLayouts(\n options: ProbeAppPageLayoutsOptions,\n): Promise<ProbeAppPageLayoutsResult> {\n const layoutFlags: Record<string, \"s\" | \"d\"> = {};\n const cls = options.classification ?? null;\n\n const response = await options.runWithSuppressedHookWarning(async () => {\n for (let layoutIndex = options.layoutCount - 1; layoutIndex >= 0; layoutIndex--) {\n const buildTimeResult = cls?.buildTimeClassifications?.get(layoutIndex);\n\n if (cls && buildTimeResult) {\n // Build-time classified (Layer 1 or Layer 2): skip dynamic isolation,\n // but still probe for special errors (redirects, not-found).\n layoutFlags[cls.getLayoutId(layoutIndex)] = buildTimeResult === \"static\" ? \"s\" : \"d\";\n if (cls.debugClassification) {\n // `no-classifier` is the documented fallback for a layout that was\n // build-time classified but whose reason payload is absent — either\n // because the build was run without `VINEXT_DEBUG_CLASSIFICATION` or\n // because no Layer 1/2 classifier attached a reason. This is the sole\n // producer of the variant; see `layout-classification-types.ts`.\n cls.debugClassification(\n cls.getLayoutId(layoutIndex),\n cls.buildTimeReasons?.get(layoutIndex) ?? { layer: \"no-classifier\" },\n );\n }\n const errorResponse = await probeLayoutForErrors(options, layoutIndex);\n if (errorResponse) return errorResponse;\n continue;\n }\n\n if (cls) {\n // Layer 3: probe with isolated dynamic scope to detect per-layout\n // dynamic API usage (headers(), cookies(), connection(), etc.)\n try {\n const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(() =>\n options.probeLayoutAt(layoutIndex),\n );\n layoutFlags[cls.getLayoutId(layoutIndex)] = dynamicDetected ? \"d\" : \"s\";\n if (cls.debugClassification) {\n cls.debugClassification(cls.getLayoutId(layoutIndex), {\n layer: \"runtime-probe\",\n outcome: dynamicDetected ? \"dynamic\" : \"static\",\n });\n }\n } catch (error) {\n // Probe failed — conservatively treat as dynamic.\n layoutFlags[cls.getLayoutId(layoutIndex)] = \"d\";\n if (cls.debugClassification) {\n cls.debugClassification(cls.getLayoutId(layoutIndex), {\n layer: \"runtime-probe\",\n outcome: \"dynamic\",\n error: error instanceof Error ? error.message : String(error),\n });\n }\n const errorResponse = await options.onLayoutError(error, layoutIndex);\n if (errorResponse) return errorResponse;\n }\n continue;\n }\n\n // No classification options — original behavior\n const errorResponse = await probeLayoutForErrors(options, layoutIndex);\n if (errorResponse) return errorResponse;\n }\n\n return null;\n });\n\n return { response, layoutFlags };\n}\n\nasync function probeLayoutForErrors(\n options: ProbeAppPageLayoutsOptions,\n layoutIndex: number,\n): Promise<Response | null> {\n try {\n const layoutResult = options.probeLayoutAt(layoutIndex);\n if (isPromiseLike(layoutResult)) {\n await layoutResult;\n }\n } catch (error) {\n return options.onLayoutError(error, layoutIndex);\n }\n return null;\n}\n\nexport async function probeAppPageComponent(\n options: ProbeAppPageComponentOptions,\n): Promise<Response | null> {\n return options.runWithSuppressedHookWarning(async () => {\n try {\n const pageResult = options.probePage();\n if (isPromiseLike(pageResult)) {\n if (options.awaitAsyncResult) {\n await pageResult;\n } else {\n void Promise.resolve(pageResult).catch(() => {});\n }\n }\n } catch (error) {\n return options.onError(error);\n }\n\n return null;\n });\n}\n\nexport async function readAppPageBinaryStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<ArrayBuffer> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n chunks.push(value);\n totalLength += value.byteLength;\n }\n\n const buffer = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n buffer.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return buffer.buffer;\n}\n\nexport function teeAppPageRscStreamForCapture(\n stream: ReadableStream<Uint8Array>,\n shouldCapture: boolean,\n): AppPageRscStreamCapture {\n if (!shouldCapture) {\n return {\n ssrStream: stream,\n };\n }\n\n const [ssrStream, sideStream] = stream.tee();\n return {\n ssrStream,\n sideStream,\n };\n}\n\nexport function buildAppPageFontLinkHeader(\n preloads: readonly AppPageFontPreload[] | null | undefined,\n): string {\n if (!preloads || preloads.length === 0) {\n return \"\";\n }\n\n return preloads\n .map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`)\n .join(\", \");\n}\n"],"mappings":"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"}
|
|
@@ -26,6 +26,13 @@ type ResolveActiveParallelRouteHeadInputsOptions<TModule extends AppPageHeadModu
|
|
|
26
26
|
slots?: Record<string, AppPageHeadSlot<TModule>> | null;
|
|
27
27
|
};
|
|
28
28
|
type ResolveAppPageHeadOptions<TModule extends AppPageHeadModule = AppPageHeadModule> = {
|
|
29
|
+
/**
|
|
30
|
+
* Configured next.config `basePath`. Threaded into `applyFileBasedMetadata`
|
|
31
|
+
* so file-based metadata route URLs (icon, opengraph-image, manifest, ...)
|
|
32
|
+
* emitted in <head> are prefixed with the basePath. Empty string when no
|
|
33
|
+
* basePath is configured.
|
|
34
|
+
*/
|
|
35
|
+
basePath?: string;
|
|
29
36
|
fallbackOnFileMetadataError?: boolean;
|
|
30
37
|
layoutModules: readonly (TModule | null | undefined)[];
|
|
31
38
|
layoutTreePositions?: readonly number[] | null;
|