vinext 0.0.52 → 0.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/build/clean-output.d.ts +14 -0
- package/dist/build/clean-output.js +36 -0
- package/dist/build/clean-output.js.map +1 -0
- package/dist/build/inline-css.d.ts +7 -0
- package/dist/build/inline-css.js +50 -0
- package/dist/build/inline-css.js.map +1 -0
- package/dist/build/prerender.d.ts +6 -2
- package/dist/build/prerender.js +51 -12
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/static-export.d.ts +5 -0
- package/dist/build/static-export.js +8 -3
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.js +4 -0
- package/dist/check.js.map +1 -1
- package/dist/cli.js +19 -4
- package/dist/cli.js.map +1 -1
- package/dist/client/instrumentation-client-inject.d.ts +34 -0
- package/dist/client/instrumentation-client-inject.js +57 -0
- package/dist/client/instrumentation-client-inject.js.map +1 -0
- package/dist/client/navigation-runtime.d.ts +16 -2
- package/dist/client/navigation-runtime.js +16 -1
- package/dist/client/navigation-runtime.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/vinext-next-data.js.map +1 -1
- package/dist/client/window-next.d.ts +17 -2
- package/dist/client/window-next.js.map +1 -1
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.js +2 -1
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/next-config.d.ts +95 -4
- package/dist/config/next-config.js +173 -14
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +42 -7
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +11 -1
- package/dist/entries/app-browser-entry.js +16 -6
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +12 -3
- package/dist/entries/app-rsc-entry.js +41 -8
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +21 -1
- package/dist/entries/app-rsc-manifest.js +6 -4
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.d.ts +4 -1
- package/dist/entries/pages-client-entry.js +40 -3
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +292 -34
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +1 -10
- package/dist/entries/runtime-entry-module.js +2 -12
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +91 -10
- package/dist/index.js.map +1 -1
- package/dist/plugins/fonts.js +25 -2
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/remove-console.d.ts +16 -0
- package/dist/plugins/remove-console.js +176 -0
- package/dist/plugins/remove-console.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +24 -1
- package/dist/routing/app-route-graph.js +52 -4
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -2
- package/dist/routing/app-router.js +2 -2
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +21 -1
- package/dist/routing/file-matcher.js +39 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +1 -1
- package/dist/routing/pages-router.js +10 -3
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-trie.js +13 -18
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/utils.d.ts +11 -1
- package/dist/routing/utils.js +15 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js +19 -10
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +16 -1
- package/dist/server/app-browser-action-result.js +15 -1
- package/dist/server/app-browser-action-result.js.map +1 -1
- package/dist/server/app-browser-entry.js +47 -28
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +4 -0
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +13 -4
- package/dist/server/app-elements-wire.js +10 -1
- 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 +27 -8
- package/dist/server/app-fallback-renderer.js +19 -8
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-history-state.js +6 -2
- package/dist/server/app-history-state.js.map +1 -1
- package/dist/server/app-inline-css-client.d.ts +7 -0
- package/dist/server/app-inline-css-client.js +37 -0
- package/dist/server/app-inline-css-client.js.map +1 -0
- package/dist/server/app-interception-context-header.d.ts +33 -0
- package/dist/server/app-interception-context-header.js +44 -0
- package/dist/server/app-interception-context-header.js.map +1 -0
- package/dist/server/app-mounted-slots-header.d.ts +19 -0
- package/dist/server/app-mounted-slots-header.js +40 -1
- package/dist/server/app-mounted-slots-header.js.map +1 -1
- package/dist/server/app-optimistic-routing.js +26 -18
- package/dist/server/app-optimistic-routing.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +2 -0
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +22 -1
- package/dist/server/app-page-boundary.js +30 -3
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +9 -3
- package/dist/server/app-page-cache.js +14 -8
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +13 -1
- package/dist/server/app-page-dispatch.js +136 -82
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +17 -30
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +1 -0
- package/dist/server/app-page-execution.js +2 -0
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.d.ts +1 -0
- package/dist/server/app-page-head.js +8 -0
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-render-identity.d.ts +22 -0
- package/dist/server/app-page-render-identity.js +42 -0
- package/dist/server/app-page-render-identity.js.map +1 -0
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-render.d.ts +9 -1
- package/dist/server/app-page-render.js +8 -2
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +6 -3
- package/dist/server/app-page-request.js +5 -2
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +11 -1
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +16 -0
- package/dist/server/app-page-route-wiring.js +25 -10
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +12 -0
- package/dist/server/app-page-stream.js +3 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +3 -0
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-response.js +38 -6
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +16 -3
- package/dist/server/app-rsc-handler.js +60 -11
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +2 -1
- package/dist/server/app-rsc-request-normalization.js +6 -4
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-segment-config.d.ts +4 -1
- package/dist/server/app-segment-config.js +6 -1
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +22 -3
- package/dist/server/app-server-action-execution.js +46 -7
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +57 -6
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.js +3 -3
- package/dist/server/app-ssr-error-meta.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +25 -1
- package/dist/server/app-ssr-stream.js +237 -19
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +2 -1
- package/dist/server/app-static-generation.js.map +1 -1
- package/dist/server/client-trace-metadata.d.ts +31 -0
- package/dist/server/client-trace-metadata.js +83 -0
- package/dist/server/client-trace-metadata.js.map +1 -0
- package/dist/server/cookie-utils.d.ts +13 -0
- package/dist/server/cookie-utils.js +20 -0
- package/dist/server/cookie-utils.js.map +1 -0
- package/dist/server/default-not-found-module.d.ts +20 -0
- package/dist/server/default-not-found-module.js +20 -0
- package/dist/server/default-not-found-module.js.map +1 -0
- package/dist/server/dev-server.d.ts +8 -1
- package/dist/server/dev-server.js +56 -11
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/headers.d.ts +5 -1
- package/dist/server/headers.js +5 -1
- package/dist/server/headers.js.map +1 -1
- package/dist/server/html.d.ts +2 -1
- package/dist/server/html.js +6 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/image-optimization.d.ts +13 -4
- package/dist/server/image-optimization.js +15 -4
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/isr-cache.d.ts +7 -5
- package/dist/server/isr-cache.js +17 -6
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/middleware-runtime.js +1 -2
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.js +1 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +18 -0
- package/dist/server/pages-api-route.js +3 -1
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-body-parser-config.d.ts +60 -0
- package/dist/server/pages-body-parser-config.js +79 -0
- package/dist/server/pages-body-parser-config.js.map +1 -0
- package/dist/server/pages-data-route.js +1 -0
- package/dist/server/pages-data-route.js.map +1 -1
- package/dist/server/pages-default-404.d.ts +31 -0
- package/dist/server/pages-default-404.js +40 -0
- package/dist/server/pages-default-404.js.map +1 -0
- package/dist/server/pages-document-initial-props.d.ts +7 -0
- package/dist/server/pages-document-initial-props.js +14 -0
- package/dist/server/pages-document-initial-props.js.map +1 -0
- package/dist/server/pages-node-compat.d.ts +10 -0
- package/dist/server/pages-node-compat.js +12 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.d.ts +40 -0
- package/dist/server/pages-page-data.js +19 -14
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-method.d.ts +48 -0
- package/dist/server/pages-page-method.js +19 -0
- package/dist/server/pages-page-method.js.map +1 -0
- package/dist/server/pages-page-response.d.ts +8 -0
- package/dist/server/pages-page-response.js +21 -11
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/pages-serializable-props.d.ts +25 -0
- package/dist/server/pages-serializable-props.js +69 -0
- package/dist/server/pages-serializable-props.js.map +1 -0
- package/dist/server/prerender-route-params.d.ts +14 -0
- package/dist/server/prerender-route-params.js +94 -0
- package/dist/server/prerender-route-params.js.map +1 -0
- package/dist/server/prod-server.d.ts +3 -23
- package/dist/server/prod-server.js +43 -57
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/proxy-trust.d.ts +41 -0
- package/dist/server/proxy-trust.js +70 -0
- package/dist/server/proxy-trust.js.map +1 -0
- package/dist/server/request-pipeline.d.ts +3 -3
- package/dist/server/request-pipeline.js +5 -4
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/seed-cache.js +12 -6
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +3 -2
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/static-file-cache.js +2 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/server/streaming-metadata.d.ts +5 -0
- package/dist/server/streaming-metadata.js +10 -0
- package/dist/server/streaming-metadata.js.map +1 -0
- package/dist/shims/app-router-scroll-state.d.ts +14 -0
- package/dist/shims/app-router-scroll-state.js +51 -0
- package/dist/shims/app-router-scroll-state.js.map +1 -0
- package/dist/shims/app-router-scroll.d.ts +28 -0
- package/dist/shims/app-router-scroll.js +115 -0
- package/dist/shims/app-router-scroll.js.map +1 -0
- package/dist/shims/before-interactive-context.d.ts +30 -0
- package/dist/shims/before-interactive-context.js +10 -0
- package/dist/shims/before-interactive-context.js.map +1 -0
- package/dist/shims/cache-runtime.d.ts +1 -1
- package/dist/shims/cache-runtime.js +14 -1
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +6 -0
- package/dist/shims/cache.js +7 -0
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/default-not-found.d.ts +12 -0
- package/dist/shims/default-not-found.js +61 -0
- package/dist/shims/default-not-found.js.map +1 -0
- package/dist/shims/error.js +3 -0
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/font-local.d.ts +5 -0
- package/dist/shims/font-local.js +6 -2
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/head.js +4 -4
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +13 -2
- package/dist/shims/headers.js +73 -22
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/image.d.ts +1 -1
- package/dist/shims/image.js +4 -4
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/app-route-detection.d.ts +37 -0
- package/dist/shims/internal/app-route-detection.js +69 -0
- package/dist/shims/internal/app-route-detection.js.map +1 -0
- package/dist/shims/internal/pages-data-target.d.ts +58 -0
- package/dist/shims/internal/pages-data-target.js +91 -0
- package/dist/shims/internal/pages-data-target.js.map +1 -0
- package/dist/shims/internal/pages-data-url.d.ts +42 -0
- package/dist/shims/internal/pages-data-url.js +73 -0
- package/dist/shims/internal/pages-data-url.js.map +1 -0
- package/dist/shims/link.d.ts +18 -2
- package/dist/shims/link.js +129 -15
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +9 -7
- package/dist/shims/metadata.js +70 -7
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +1 -2
- package/dist/shims/navigation.js +94 -20
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/router.d.ts +5 -0
- package/dist/shims/router.js +389 -80
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts +11 -1
- package/dist/shims/script.js +158 -15
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +1 -0
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/url-utils.d.ts +2 -1
- package/dist/shims/url-utils.js +15 -4
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/utils/html-limited-bots.d.ts +5 -0
- package/dist/utils/html-limited-bots.js +15 -0
- package/dist/utils/html-limited-bots.js.map +1 -0
- package/dist/utils/path.d.ts +13 -0
- package/dist/utils/path.js +16 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/query.d.ts +6 -0
- package/dist/utils/query.js +10 -1
- package/dist/utils/query.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
1
2
|
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
|
|
2
|
-
import { AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
3
3
|
import { APP_PREFETCH_LOADING_SHELL_MARKER_KEY } from "./app-elements.js";
|
|
4
4
|
import { ErrorBoundary, ForbiddenBoundary, NotFoundBoundary, RedirectBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
|
|
5
|
+
import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
|
|
5
6
|
import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
|
|
6
|
-
import { MetadataHead, ViewportHead } from "../shims/metadata.js";
|
|
7
|
+
import { MetadataHead, ViewportHead, renderMetadataToHtml } from "../shims/metadata.js";
|
|
7
8
|
import { Children as Children$1, ParallelSlot, Slot } from "../shims/slot.js";
|
|
8
9
|
import { createAppRenderDependency, renderAfterAppDependencies, renderWithAppDependencyBarrier } from "./app-render-dependency.js";
|
|
9
10
|
import { resolveAppPageSegmentParams } from "./app-page-params.js";
|
|
@@ -100,26 +101,35 @@ function createAppPageSlotBindings(route, layoutEntries, resolveSlotOverride) {
|
|
|
100
101
|
}
|
|
101
102
|
return normalizeAppElementsSlotBindings(bindings, { layoutIds: layoutEntries.map((entry) => entry.id) });
|
|
102
103
|
}
|
|
103
|
-
function createAppPageRouteHead(metadata, viewport, pathname) {
|
|
104
|
+
function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement) {
|
|
104
105
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
105
106
|
/* @__PURE__ */ jsx("meta", { charSet: "utf-8" }),
|
|
106
|
-
metadata ? /* @__PURE__ */ jsx(MetadataHead, {
|
|
107
|
+
metadata && metadataPlacement === "head" ? /* @__PURE__ */ jsx(MetadataHead, {
|
|
107
108
|
metadata,
|
|
108
109
|
pathname
|
|
109
110
|
}) : null,
|
|
110
111
|
/* @__PURE__ */ jsx(ViewportHead, { viewport })
|
|
111
112
|
] });
|
|
112
113
|
}
|
|
114
|
+
function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement) {
|
|
115
|
+
if (!metadata || metadataPlacement !== "body") return null;
|
|
116
|
+
return /* @__PURE__ */ jsx("div", {
|
|
117
|
+
hidden: true,
|
|
118
|
+
dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname) }
|
|
119
|
+
});
|
|
120
|
+
}
|
|
113
121
|
function buildAppPageElements(options) {
|
|
114
|
-
const
|
|
122
|
+
const renderIdentity = options.renderIdentity;
|
|
123
|
+
const interceptionContext = renderIdentity?.interceptionContext ?? options.interceptionContext ?? null;
|
|
115
124
|
const renderMode = options.renderMode ?? "navigation";
|
|
116
125
|
const routeSegments = options.route.routeSegments ?? [];
|
|
117
126
|
const routeResetKey = resolveAppPageRouteStateKey(routeSegments, options.matchedParams);
|
|
118
|
-
const routeId = AppElementsWire.encodeRouteId(options.routePath, interceptionContext);
|
|
119
|
-
const pageId = AppElementsWire.encodePageId(options.routePath, interceptionContext);
|
|
127
|
+
const routeId = renderIdentity?.routeId ?? AppElementsWire.encodeRouteId(options.routePath, interceptionContext);
|
|
128
|
+
const pageId = renderIdentity?.pageId ?? AppElementsWire.encodePageId(options.routePath, interceptionContext);
|
|
120
129
|
const layoutEntries = createAppPageLayoutEntries(options.route);
|
|
121
130
|
const templateEntries = createAppPageTemplateEntries(options.route);
|
|
122
131
|
const errorEntries = createAppPageErrorEntries(options.route);
|
|
132
|
+
const metadataPlacement = options.metadataPlacement ?? "head";
|
|
123
133
|
const layoutEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
124
134
|
const templateEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
125
135
|
const errorEntriesByTreePosition = /* @__PURE__ */ new Map();
|
|
@@ -151,13 +161,14 @@ function buildAppPageElements(options) {
|
|
|
151
161
|
if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) return options.slotOverrides?.[slotName];
|
|
152
162
|
};
|
|
153
163
|
const elements = { ...AppElementsWire.createMetadataEntries({
|
|
154
|
-
interception: options.interception ?? null,
|
|
164
|
+
interception: renderIdentity?.interception ?? options.interception ?? null,
|
|
155
165
|
interceptionContext,
|
|
156
166
|
layoutIds: options.route.ids?.layouts ?? layoutEntries.map((entry) => entry.id),
|
|
157
167
|
rootLayoutTreePath,
|
|
158
168
|
routeId,
|
|
159
169
|
slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride)
|
|
160
170
|
}) };
|
|
171
|
+
if (options.route.staticSiblings && options.route.staticSiblings.length > 0) elements[APP_STATIC_SIBLINGS_KEY] = options.route.staticSiblings;
|
|
161
172
|
const getEffectiveSlotParams = (slotKey, slotName) => resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;
|
|
162
173
|
for (const treePosition of orderedTreePositions) {
|
|
163
174
|
const layoutIndex = layoutIndicesByTreePosition.get(treePosition);
|
|
@@ -265,7 +276,7 @@ function buildAppPageElements(options) {
|
|
|
265
276
|
}
|
|
266
277
|
let routeChildren = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
267
278
|
segmentMap: { children: [] },
|
|
268
|
-
children: /* @__PURE__ */ jsx(Slot, { id: pageId })
|
|
279
|
+
children: /* @__PURE__ */ jsx(AppRouterScrollTarget, { children: /* @__PURE__ */ jsx(Slot, { id: pageId }) })
|
|
269
280
|
});
|
|
270
281
|
if (isPrefetchLoadingShell) if (routeLoadingComponent === null) routeChildren = null;
|
|
271
282
|
else routeChildren = /* @__PURE__ */ jsx(routeLoadingComponent, {});
|
|
@@ -365,7 +376,11 @@ function buildAppPageElements(options) {
|
|
|
365
376
|
fallback: globalErrorComponent,
|
|
366
377
|
children: routeChildren
|
|
367
378
|
});
|
|
368
|
-
elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
379
|
+
elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
380
|
+
createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement),
|
|
381
|
+
routeChildren,
|
|
382
|
+
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement)
|
|
383
|
+
] });
|
|
369
384
|
return elements;
|
|
370
385
|
}
|
|
371
386
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-page-route-wiring.js","names":["Children","SlotComponent","InterceptLayoutComponent","SlotLayoutComponent","SlotLoadingComponent","RouteLoadingComponent","NotFoundComponent","ForbiddenComponent","UnauthorizedComponent","LayoutNotFoundComponent","LayoutForbiddenComponent","LayoutUnauthorizedComponent"],"sources":["../../src/server/app-page-route-wiring.tsx"],"sourcesContent":["import { Suspense, type ComponentType, type ReactNode } from \"react\";\nimport {\n AppElementsWire,\n APP_PREFETCH_LOADING_SHELL_MARKER_KEY,\n normalizeAppElementsSlotBindings,\n type AppElements,\n type AppElementsInterception,\n type AppElementsSlotBinding,\n} from \"./app-elements.js\";\nimport {\n ErrorBoundary,\n ForbiddenBoundary,\n NotFoundBoundary,\n RedirectBoundary,\n UnauthorizedBoundary,\n} from \"vinext/shims/error-boundary\";\nimport type { AppRouteSemanticIds } from \"../routing/app-route-graph.js\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport { MetadataHead, ViewportHead, type Metadata, type Viewport } from \"vinext/shims/metadata\";\nimport { Children, ParallelSlot, Slot } from \"vinext/shims/slot\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n createAppRenderDependency,\n renderAfterAppDependencies,\n renderWithAppDependencyBarrier,\n type AppRenderDependency,\n} from \"./app-render-dependency.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL,\n shouldSuppressLoadingBoundaries,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.js\";\nimport {\n resolveAppPageChildSegments,\n resolveAppPageRouteStateKey,\n resolveAppPageSegmentStateKey,\n} from \"./app-page-segment-state.js\";\n\nexport { resolveAppPageChildSegments } from \"./app-page-segment-state.js\";\n\ntype AppPageComponentProps = {\n children?: ReactNode;\n error?: unknown;\n params?: unknown;\n reset?: () => void;\n} & Record<string, unknown>;\n\ntype AppPageComponent = ComponentType<AppPageComponentProps>;\ntype AppPageErrorComponent = ComponentType<{ error: unknown; reset: () => void }>;\n\nexport type AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\n\nexport type AppPageErrorModule = Record<string, unknown> & {\n default?: AppPageErrorComponent | null | undefined;\n};\n\ntype AppPageRouteWiringSlot<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n /** Graph-owned semantic slot identity. */\n id?: string | null;\n /** Slot prop name passed to the owning layout (e.g. \"modal\" from @modal). */\n name: string;\n default?: TModule | null;\n error?: TErrorModule | null;\n layout?: TModule | null;\n layoutIndex: number;\n loading?: TModule | null;\n page?: TModule | null;\n routeSegments?: readonly string[] | null;\n /**\n * Full URL pattern parts for the slot's mirrored sub-page. Set when the\n * slot's params may differ from the route's (e.g. inherited slot whose\n * dynamic markers have different names than the route's). The runtime\n * matches the request URL against these parts to extract slot params.\n */\n slotPatternParts?: readonly string[] | null;\n /** Param names captured by `slotPatternParts`, in order. */\n slotParamNames?: readonly string[] | null;\n};\n\nexport type AppPageRouteWiringRoute<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n ids?: AppRouteSemanticIds | null;\n error?: TErrorModule | null;\n errorPaths?: readonly TErrorModule[] | null;\n errors?: readonly (TErrorModule | null | undefined)[] | null;\n errorTreePositions?: readonly number[] | null;\n layoutTreePositions?: readonly number[] | null;\n layouts: readonly (TModule | null | undefined)[];\n loading?: TModule | null;\n notFound?: TModule | null;\n notFounds?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorized?: TModule | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n routeSegments?: readonly string[];\n /**\n * Keyed by stable slot id (name + owner path), not necessarily the slot prop name.\n */\n slots?: Readonly<Record<string, AppPageRouteWiringSlot<TModule, TErrorModule>>> | null;\n templateTreePositions?: readonly number[] | null;\n templates?: readonly (TModule | null | undefined)[] | null;\n};\n\nexport type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n /**\n * The page module to render for this slot. Optional — when omitted, the\n * slot's existing `page` is used (e.g. when the override only changes the\n * slot's `params` for an inherited mirror with distinct param names).\n */\n pageModule?: TModule | null;\n params?: AppPageParams;\n props?: Readonly<Record<string, unknown>>;\n};\n\ntype AppPageLayoutEntry<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n errorModule?: TErrorModule | null | undefined;\n forbiddenModule?: TModule | null | undefined;\n id: string;\n layoutModule?: TModule | null | undefined;\n notFoundModule?: TModule | null | undefined;\n unauthorizedModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype BuildAppPageRouteElementOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n element: ReactNode;\n globalErrorModule?: TErrorModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n resolvedMetadata: Metadata | null;\n resolvedMetadataPathname?: string;\n resolvedViewport: Viewport;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route: AppPageRouteWiringRoute<TModule, TErrorModule>;\n slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;\n};\n\ntype BuildAppPageElementsOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = BuildAppPageRouteElementOptions<TModule, TErrorModule> & {\n interception?: AppElementsInterception | null;\n interceptionContext?: string | null;\n isRscRequest?: boolean;\n mountedSlotIds?: ReadonlySet<string> | null;\n renderMode?: AppRscRenderMode;\n routePath: string;\n};\n\ntype AppPageTemplateEntry<TModule extends AppPageModule = AppPageModule> = {\n id: string;\n templateModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype AppPageErrorEntry<TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {\n errorModule?: TErrorModule | null | undefined;\n treePosition: number;\n};\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction getErrorBoundaryExport<TModule extends AppPageErrorModule>(\n module: TModule | null | undefined,\n): AppPageErrorComponent | null {\n return module?.default ?? null;\n}\n\nexport function createAppPageTreePath(\n routeSegments: readonly string[] | null | undefined,\n treePosition: number,\n): string {\n const treePathSegments = routeSegments?.slice(0, treePosition) ?? [];\n if (treePathSegments.length === 0) {\n return \"/\";\n }\n return `/${treePathSegments.join(\"/\")}`;\n}\n\nexport function createAppPageLayoutEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: Pick<\n AppPageRouteWiringRoute<TModule, TErrorModule>,\n | \"errors\"\n | \"errorTreePositions\"\n | \"layoutTreePositions\"\n | \"layouts\"\n | \"notFounds\"\n | \"routeSegments\"\n > & {\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n },\n): AppPageLayoutEntry<TModule, TErrorModule>[] {\n return route.layouts.map((layoutModule, index) => {\n const treePosition = route.layoutTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n errorModule: route.errorTreePositions ? null : (route.errors?.[index] ?? null),\n forbiddenModule: route.forbiddens?.[index] ?? null,\n id: AppElementsWire.encodeLayoutId(treePath),\n layoutModule,\n notFoundModule: route.notFounds?.[index] ?? null,\n unauthorizedModule: route.unauthorizeds?.[index] ?? null,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageTemplateEntries<TModule extends AppPageModule>(\n route: Pick<\n AppPageRouteWiringRoute<TModule>,\n \"routeSegments\" | \"templateTreePositions\" | \"templates\"\n >,\n): AppPageTemplateEntry<TModule>[] {\n return (route.templates ?? []).map((templateModule, index) => {\n const treePosition = route.templateTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n id: AppElementsWire.encodeTemplateId(treePath),\n templateModule,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageErrorEntries<TErrorModule extends AppPageErrorModule>(\n route: Pick<\n AppPageRouteWiringRoute<AppPageModule, TErrorModule>,\n \"errorPaths\" | \"errors\" | \"errorTreePositions\"\n >,\n): AppPageErrorEntry<TErrorModule>[] {\n return (route.errorPaths ?? route.errors ?? []).flatMap((errorModule, index) => {\n if (!errorModule) return [];\n const treePosition = route.errorTreePositions?.[index];\n if (treePosition === undefined) return [];\n return [{ errorModule, treePosition }];\n });\n}\n\nfunction createAppPageParallelSlotEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n layoutIndex: number,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n getEffectiveSlotParams: (slotKey: string, slotName: string) => AppPageParams,\n): Readonly<Record<string, ReactNode>> | undefined {\n const parallelSlots: Record<string, ReactNode> = {};\n\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n\n const layoutEntry = layoutEntries[targetIndex];\n const treePath = layoutEntry?.treePath ?? \"/\";\n const slotId = resolveAppPageSlotId(slot, treePath);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotSegments = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n parallelSlots[slotName] = (\n <LayoutSegmentProvider segmentMap={{ children: slotSegments }}>\n <Slot id={slotId} />\n </LayoutSegmentProvider>\n );\n }\n\n return Object.keys(parallelSlots).length > 0 ? parallelSlots : undefined;\n}\n\nfunction resolveAppPageSlotId(slot: AppPageRouteWiringSlot, treePath: string): string {\n const slotId = AppElementsWire.encodeSlotId(slot.name, treePath);\n if (slot.id && slot.id !== slotId) {\n throw new Error(\n `[vinext] App Router slot id mismatch for @${slot.name}: graph id ${slot.id} does not match wire id ${slotId}`,\n );\n }\n return slotId;\n}\n\nfunction resolveAppPageSlotBindingState(\n slot: AppPageRouteWiringSlot,\n override: AppPageSlotOverride | undefined,\n): AppElementsSlotBinding[\"state\"] {\n const pageComponent = getDefaultExport(override?.pageModule) ?? getDefaultExport(slot.page);\n if (pageComponent) return \"active\";\n if (getDefaultExport(slot.default)) return \"default\";\n return \"unmatched\";\n}\n\nfunction createAppPageSlotBindings<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n resolveSlotOverride: (\n slotKey: string,\n slotName: string,\n ) => AppPageSlotOverride<TModule> | undefined,\n): readonly AppElementsSlotBinding[] {\n const bindings: AppElementsSlotBinding[] = [];\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const layoutEntry = layoutEntries[targetIndex] ?? null;\n const ownerLayoutId = layoutEntry?.id ?? null;\n const override = resolveSlotOverride(slotKey, slot.name);\n bindings.push({\n ownerLayoutId,\n slotId: resolveAppPageSlotId(slot, layoutEntry?.treePath ?? \"/\"),\n state: resolveAppPageSlotBindingState(slot, override),\n });\n }\n return normalizeAppElementsSlotBindings(bindings, {\n layoutIds: layoutEntries.map((entry) => entry.id),\n });\n}\n\nfunction createAppPageRouteHead(\n metadata: Metadata | null,\n viewport: Viewport,\n pathname: string,\n): ReactNode {\n return (\n <>\n <meta charSet=\"utf-8\" />\n {metadata ? <MetadataHead metadata={metadata} pathname={pathname} /> : null}\n <ViewportHead viewport={viewport} />\n </>\n );\n}\n\nexport function buildAppPageElements<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements {\n const interceptionContext = options.interceptionContext ?? null;\n const renderMode = options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION;\n const routeSegments = options.route.routeSegments ?? [];\n const routeResetKey = resolveAppPageRouteStateKey(routeSegments, options.matchedParams);\n const routeId = AppElementsWire.encodeRouteId(options.routePath, interceptionContext);\n const pageId = AppElementsWire.encodePageId(options.routePath, interceptionContext);\n const layoutEntries = createAppPageLayoutEntries(options.route);\n const templateEntries = createAppPageTemplateEntries(options.route);\n const errorEntries = createAppPageErrorEntries(options.route);\n const layoutEntriesByTreePosition = new Map<number, AppPageLayoutEntry<TModule, TErrorModule>>();\n const templateEntriesByTreePosition = new Map<number, AppPageTemplateEntry<TModule>>();\n const errorEntriesByTreePosition = new Map<number, AppPageErrorEntry<TErrorModule>>();\n for (const layoutEntry of layoutEntries) {\n layoutEntriesByTreePosition.set(layoutEntry.treePosition, layoutEntry);\n }\n for (const templateEntry of templateEntries) {\n templateEntriesByTreePosition.set(templateEntry.treePosition, templateEntry);\n }\n for (const errorEntry of errorEntries) {\n errorEntriesByTreePosition.set(errorEntry.treePosition, errorEntry);\n }\n const layoutIndicesByTreePosition = new Map<number, number>();\n for (let index = 0; index < layoutEntries.length; index++) {\n layoutIndicesByTreePosition.set(layoutEntries[index].treePosition, index);\n }\n const layoutDependenciesByIndex = new Map<number, AppRenderDependency>();\n const layoutDependenciesBefore: AppRenderDependency[][] = [];\n const slotDependenciesByLayoutIndex: AppRenderDependency[][] = [];\n const templateDependenciesById = new Map<string, AppRenderDependency>();\n const templateDependenciesBeforeById = new Map<string, AppRenderDependency[]>();\n const pageDependencies: AppRenderDependency[] = [];\n const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;\n const slotNameCounts = new Map<string, number>();\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);\n }\n const orderedTreePositions = Array.from(\n new Set<number>([\n ...layoutEntries.map((entry) => entry.treePosition),\n ...templateEntries.map((entry) => entry.treePosition),\n ...errorEntries.map((entry) => entry.treePosition),\n ]),\n ).sort((left, right) => left - right);\n const resolveSlotOverride = (slotKey: string, slotName: string) => {\n const overrideByKey = options.slotOverrides?.[slotKey];\n if (overrideByKey) {\n return overrideByKey;\n }\n\n // Legacy callers may still provide overrides by slot prop name.\n // Only allow that fallback when it is unambiguous.\n if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) {\n return options.slotOverrides?.[slotName];\n }\n\n return undefined;\n };\n const elements: Record<\n string,\n ReactNode | string | null | AppElementsInterception | readonly AppElementsSlotBinding[]\n > = {\n ...AppElementsWire.createMetadataEntries({\n interception: options.interception ?? null,\n interceptionContext,\n layoutIds: options.route.ids?.layouts ?? layoutEntries.map((entry) => entry.id),\n rootLayoutTreePath,\n routeId,\n slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride),\n }),\n };\n const getEffectiveSlotParams = (slotKey: string, slotName: string): AppPageParams =>\n resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;\n\n for (const treePosition of orderedTreePositions) {\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition);\n if (layoutIndex !== undefined) {\n const layoutEntry = layoutEntries[layoutIndex];\n layoutDependenciesBefore[layoutIndex] = [...pageDependencies];\n if (getDefaultExport(layoutEntry.layoutModule)) {\n const layoutDependency = createAppRenderDependency();\n layoutDependenciesByIndex.set(layoutIndex, layoutDependency);\n pageDependencies.push(layoutDependency);\n }\n slotDependenciesByLayoutIndex[layoutIndex] = [...pageDependencies];\n }\n\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n if (!templateEntry || !getDefaultExport(templateEntry.templateModule)) {\n continue;\n }\n\n const templateDependency = createAppRenderDependency();\n templateDependenciesById.set(templateEntry.id, templateDependency);\n templateDependenciesBeforeById.set(templateEntry.id, [...pageDependencies]);\n pageDependencies.push(templateDependency);\n }\n\n const routeLoadingComponent = getDefaultExport(options.route.loading);\n const isPrefetchLoadingShell = renderMode === APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL;\n const shouldRenderPrefetchLoadingShell = isPrefetchLoadingShell && routeLoadingComponent !== null;\n if (shouldRenderPrefetchLoadingShell) {\n // Client loading components serialize as module references in Flight. Keep\n // a durable marker in the shell payload so external router tests and\n // diagnostics can recognize this as a loading-boundary response without\n // requiring source text to appear in client component references.\n elements[APP_PREFETCH_LOADING_SHELL_MARKER_KEY] = \"LoadingBoundary\";\n }\n\n elements[pageId] = isPrefetchLoadingShell\n ? null\n : renderAfterAppDependencies(options.element, pageDependencies);\n\n for (const templateEntry of templateEntries) {\n const templateComponent = getDefaultExport(templateEntry.templateModule);\n if (!templateComponent) {\n continue;\n }\n const TemplateComponent = templateComponent;\n const templateDependency = templateDependenciesById.get(templateEntry.id);\n const templateElement = templateDependency ? (\n renderWithAppDependencyBarrier(\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>,\n templateDependency,\n )\n ) : (\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>\n );\n elements[templateEntry.id] = renderAfterAppDependencies(\n templateElement,\n templateDependenciesBeforeById.get(templateEntry.id) ?? [],\n );\n }\n\n for (let index = 0; index < layoutEntries.length; index++) {\n const layoutEntry = layoutEntries[index];\n const layoutComponent = getDefaultExport(layoutEntry.layoutModule);\n if (!layoutComponent) {\n continue;\n }\n\n const layoutProps: Record<string, unknown> = {\n params: options.makeThenableParams(\n resolveAppPageSegmentParams(\n options.route.routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n ),\n };\n\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== index) {\n continue;\n }\n layoutProps[slotName] = <ParallelSlot name={slotName} />;\n }\n\n const LayoutComponent = layoutComponent;\n const layoutDependency = layoutDependenciesByIndex.get(index);\n const layoutElement = layoutDependency ? (\n renderWithAppDependencyBarrier(\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>,\n layoutDependency,\n )\n ) : (\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>\n );\n elements[layoutEntry.id] = renderAfterAppDependencies(\n layoutElement,\n layoutDependenciesBefore[index] ?? [],\n );\n }\n\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const treePath = layoutEntries[targetIndex]?.treePath ?? \"/\";\n const slotId = resolveAppPageSlotId(slot, treePath);\n const slotOverride = resolveSlotOverride(slotKey, slotName);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotRouteSegments = slot.routeSegments ?? [];\n const slotResetKey = resolveAppPageRouteStateKey(slotRouteSegments, slotParams);\n const overrideOrPageComponent =\n getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);\n const defaultComponent = getDefaultExport(slot.default);\n\n // On soft nav (RSC): omit key when only default.tsx exists and the slot is\n // already mounted on the client. Absent key means the browser retains prior\n // slot content rather than replacing it. When the slot is not yet mounted\n // (first entry into this layout), include the key so default.tsx renders.\n if (\n !overrideOrPageComponent &&\n defaultComponent &&\n options.isRscRequest &&\n options.mountedSlotIds?.has(slotId)\n ) {\n continue;\n }\n\n const slotComponent = overrideOrPageComponent ?? defaultComponent;\n\n if (!slotComponent) {\n elements[slotId] = AppElementsWire.unmatchedSlotValue;\n continue;\n }\n\n const slotThenableParams = options.makeThenableParams(slotParams);\n const slotProps: Record<string, unknown> = {\n params: slotThenableParams,\n };\n if (slotOverride?.props) {\n Object.assign(slotProps, slotOverride.props);\n }\n\n const SlotComponent = slotComponent;\n let slotElement: ReactNode = <SlotComponent {...slotProps} />;\n const interceptLayouts = slotOverride?.layoutModules ?? [];\n\n for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {\n const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);\n if (!interceptLayoutComponent) {\n continue;\n }\n const InterceptLayoutComponent = interceptLayoutComponent;\n slotElement = (\n <InterceptLayoutComponent params={slotThenableParams}>\n {slotElement}\n </InterceptLayoutComponent>\n );\n }\n\n const slotLayoutComponent = getDefaultExport(slot.layout);\n if (slotLayoutComponent) {\n const SlotLayoutComponent = slotLayoutComponent;\n slotElement = (\n <SlotLayoutComponent params={slotThenableParams}>{slotElement}</SlotLayoutComponent>\n );\n }\n\n const slotLoadingComponent = getDefaultExport(slot.loading);\n if (slotLoadingComponent && !shouldSuppressLoadingBoundaries(renderMode)) {\n const SlotLoadingComponent = slotLoadingComponent;\n slotElement = (\n <Suspense key={slotResetKey} fallback={<SlotLoadingComponent />}>\n {slotElement}\n </Suspense>\n );\n }\n\n const slotErrorComponent = getErrorBoundaryExport(slot.error);\n if (slotErrorComponent) {\n slotElement = (\n <ErrorBoundary resetKey={slotResetKey} fallback={slotErrorComponent}>\n {slotElement}\n </ErrorBoundary>\n );\n }\n\n elements[slotId] = renderAfterAppDependencies(\n slotElement,\n targetIndex >= 0 ? (slotDependenciesByLayoutIndex[targetIndex] ?? []) : [],\n );\n }\n\n let routeChildren: ReactNode = (\n <LayoutSegmentProvider segmentMap={{ children: [] }}>\n <Slot id={pageId} />\n </LayoutSegmentProvider>\n );\n\n if (isPrefetchLoadingShell) {\n if (routeLoadingComponent === null) {\n routeChildren = null;\n } else {\n const RouteLoadingComponent = routeLoadingComponent;\n routeChildren = <RouteLoadingComponent />;\n }\n } else {\n // Wrap the page slot in a per-segment RedirectBoundary so that a\n // redirect() thrown from a server component (or a client component\n // within the page subtree) is caught here — below the route's layouts —\n // rather than at the top-level boundary in app-browser-entry. Catching\n // at the top level unmounts the entire route tree including layouts,\n // which destroys client-side state in layout-hosted components\n // (counters, theme toggles, form drafts). Here, only the page subtree\n // is unmounted; the surrounding layouts stay mounted across the\n // boundary's null-render → router.replace transition, and segment\n // reuse keeps their React state intact.\n //\n // Placed inside the Suspense (loading) boundary to match Next.js nesting\n // for the redirect boundary specifically:\n // Error > AccessFallback > Loading (Suspense) > Redirect > content\n // (Note: Next.js places AccessFallback inside Loading, not outside — that\n // is a pre-existing nesting divergence tracked separately.)\n // This keeps the loading fallback visible during redirect-driven\n // transitions rather than unmounting it.\n routeChildren = <RedirectBoundary>{routeChildren}</RedirectBoundary>;\n\n if (routeLoadingComponent && !shouldSuppressLoadingBoundaries(renderMode)) {\n const RouteLoadingComponent = routeLoadingComponent;\n // Route-level wrappers cover the full page branch in vinext's flat element\n // transport, so their reset key includes the visible segment-state path.\n // Dynamic param changes reset the pending boundary, while search-only changes\n // preserve it.\n routeChildren = (\n <Suspense key={routeResetKey} fallback={<RouteLoadingComponent />}>\n {routeChildren}\n </Suspense>\n );\n }\n }\n\n const lastLayoutErrorModule =\n errorEntries.length > 0 ? errorEntries[errorEntries.length - 1].errorModule : null;\n // Next.js nesting (outer to inner): Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap first, then Forbidden, Unauthorized, Error.\n const notFoundComponent =\n getDefaultExport(options.route.notFound) ?? getDefaultExport(options.rootNotFoundModule);\n if (notFoundComponent) {\n const NotFoundComponent = notFoundComponent;\n routeChildren = (\n <NotFoundBoundary resetKey={routeResetKey} fallback={<NotFoundComponent />}>\n {routeChildren}\n </NotFoundBoundary>\n );\n }\n\n const forbiddenComponent =\n getDefaultExport(options.route.forbidden) ?? getDefaultExport(options.rootForbiddenModule);\n if (forbiddenComponent) {\n const ForbiddenComponent = forbiddenComponent;\n routeChildren = (\n <ForbiddenBoundary resetKey={routeResetKey} fallback={<ForbiddenComponent />}>\n {routeChildren}\n </ForbiddenBoundary>\n );\n }\n\n const unauthorizedComponent =\n getDefaultExport(options.route.unauthorized) ??\n getDefaultExport(options.rootUnauthorizedModule);\n if (unauthorizedComponent) {\n const UnauthorizedComponent = unauthorizedComponent;\n routeChildren = (\n <UnauthorizedBoundary resetKey={routeResetKey} fallback={<UnauthorizedComponent />}>\n {routeChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const pageErrorComponent = getErrorBoundaryExport(options.route.error);\n if (pageErrorComponent && options.route.error !== lastLayoutErrorModule) {\n routeChildren = (\n <ErrorBoundary resetKey={routeResetKey} fallback={pageErrorComponent}>\n {routeChildren}\n </ErrorBoundary>\n );\n }\n\n for (let index = orderedTreePositions.length - 1; index >= 0; index--) {\n const treePosition = orderedTreePositions[index];\n const segmentResetKey = resolveAppPageSegmentStateKey(\n routeSegments,\n treePosition,\n options.matchedParams,\n );\n let segmentChildren: ReactNode = routeChildren;\n const layoutEntry = layoutEntriesByTreePosition.get(treePosition);\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n const errorEntry = errorEntriesByTreePosition.get(treePosition);\n\n // Next.js nesting per segment (outer to inner): Layout > Template > Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap the leaf subtree first,\n // then ErrorBoundary, then Template, with the Layout slot outermost.\n if (layoutEntry) {\n const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule);\n if (layoutNotFoundComponent) {\n const LayoutNotFoundComponent = layoutNotFoundComponent;\n segmentChildren = (\n <NotFoundBoundary resetKey={segmentResetKey} fallback={<LayoutNotFoundComponent />}>\n {segmentChildren}\n </NotFoundBoundary>\n );\n }\n\n const layoutForbiddenComponent = getDefaultExport(layoutEntry.forbiddenModule);\n if (layoutForbiddenComponent) {\n const LayoutForbiddenComponent = layoutForbiddenComponent;\n segmentChildren = (\n <ForbiddenBoundary resetKey={segmentResetKey} fallback={<LayoutForbiddenComponent />}>\n {segmentChildren}\n </ForbiddenBoundary>\n );\n }\n\n const layoutUnauthorizedComponent = getDefaultExport(layoutEntry.unauthorizedModule);\n if (layoutUnauthorizedComponent) {\n const LayoutUnauthorizedComponent = layoutUnauthorizedComponent;\n segmentChildren = (\n <UnauthorizedBoundary\n resetKey={segmentResetKey}\n fallback={<LayoutUnauthorizedComponent />}\n >\n {segmentChildren}\n </UnauthorizedBoundary>\n );\n }\n }\n\n const segmentErrorComponent = getErrorBoundaryExport(\n errorEntry?.errorModule ?? layoutEntry?.errorModule,\n );\n if (segmentErrorComponent) {\n segmentChildren = (\n <ErrorBoundary resetKey={segmentResetKey} fallback={segmentErrorComponent}>\n {segmentChildren}\n </ErrorBoundary>\n );\n }\n\n if (templateEntry && getDefaultExport(templateEntry.templateModule)) {\n segmentChildren = (\n <Slot id={templateEntry.id} key={segmentResetKey}>\n {segmentChildren}\n </Slot>\n );\n }\n\n if (!layoutEntry) {\n routeChildren = segmentChildren;\n continue;\n }\n const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;\n const segmentMap: { children: string[] } & Record<string, string[]> = {\n children: resolveAppPageChildSegments(\n routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n };\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n segmentMap[slotName] = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n }\n\n routeChildren = (\n <LayoutSegmentProvider segmentMap={segmentMap}>\n {layoutHasElement ? (\n <Slot\n id={layoutEntry.id}\n parallelSlots={createAppPageParallelSlotEntries(\n layoutIndex,\n layoutEntries,\n options.route,\n getEffectiveSlotParams,\n )}\n >\n {segmentChildren}\n </Slot>\n ) : (\n segmentChildren\n )}\n </LayoutSegmentProvider>\n );\n }\n\n const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);\n if (globalErrorComponent) {\n routeChildren = <ErrorBoundary fallback={globalErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n elements[routeId] = (\n <>\n {createAppPageRouteHead(\n options.resolvedMetadata,\n options.resolvedViewport,\n options.resolvedMetadataPathname ?? options.routePath,\n )}\n {routeChildren}\n </>\n );\n\n return elements;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-page-route-wiring.js","names":["Children","SlotComponent","InterceptLayoutComponent","SlotLayoutComponent","SlotLoadingComponent","RouteLoadingComponent","NotFoundComponent","ForbiddenComponent","UnauthorizedComponent","LayoutNotFoundComponent","LayoutForbiddenComponent","LayoutUnauthorizedComponent"],"sources":["../../src/server/app-page-route-wiring.tsx"],"sourcesContent":["import { Suspense, type ComponentType, type ReactNode } from \"react\";\nimport {\n AppElementsWire,\n APP_PREFETCH_LOADING_SHELL_MARKER_KEY,\n APP_STATIC_SIBLINGS_KEY,\n normalizeAppElementsSlotBindings,\n type AppElements,\n type AppElementsInterception,\n type AppElementsSlotBinding,\n} from \"./app-elements.js\";\nimport {\n ErrorBoundary,\n ForbiddenBoundary,\n NotFoundBoundary,\n RedirectBoundary,\n UnauthorizedBoundary,\n} from \"vinext/shims/error-boundary\";\nimport { AppRouterScrollTarget } from \"vinext/shims/app-router-scroll\";\nimport type { AppRouteSemanticIds } from \"../routing/app-route-graph.js\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport {\n MetadataHead,\n ViewportHead,\n renderMetadataToHtml,\n type Metadata,\n type Viewport,\n} from \"vinext/shims/metadata\";\nimport { Children, ParallelSlot, Slot } from \"vinext/shims/slot\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n createAppRenderDependency,\n renderAfterAppDependencies,\n renderWithAppDependencyBarrier,\n type AppRenderDependency,\n} from \"./app-render-dependency.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\nimport {\n APP_RSC_RENDER_MODE_NAVIGATION,\n APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL,\n shouldSuppressLoadingBoundaries,\n type AppRscRenderMode,\n} from \"./app-rsc-render-mode.js\";\nimport {\n resolveAppPageChildSegments,\n resolveAppPageRouteStateKey,\n resolveAppPageSegmentStateKey,\n} from \"./app-page-segment-state.js\";\nimport type { AppPageRenderIdentity } from \"./app-page-render-identity.js\";\n\nexport { resolveAppPageChildSegments } from \"./app-page-segment-state.js\";\n\ntype AppPageComponentProps = {\n children?: ReactNode;\n error?: unknown;\n params?: unknown;\n reset?: () => void;\n} & Record<string, unknown>;\n\ntype AppPageComponent = ComponentType<AppPageComponentProps>;\ntype AppPageErrorComponent = ComponentType<{ error: unknown; reset: () => void }>;\n\nexport type AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\n\nexport type AppPageErrorModule = Record<string, unknown> & {\n default?: AppPageErrorComponent | null | undefined;\n};\n\ntype AppPageRouteWiringSlot<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n /** Graph-owned semantic slot identity. */\n id?: string | null;\n /** Slot prop name passed to the owning layout (e.g. \"modal\" from @modal). */\n name: string;\n default?: TModule | null;\n error?: TErrorModule | null;\n layout?: TModule | null;\n layoutIndex: number;\n loading?: TModule | null;\n page?: TModule | null;\n routeSegments?: readonly string[] | null;\n /**\n * Full URL pattern parts for the slot's mirrored sub-page. Set when the\n * slot's params may differ from the route's (e.g. inherited slot whose\n * dynamic markers have different names than the route's). The runtime\n * matches the request URL against these parts to extract slot params.\n */\n slotPatternParts?: readonly string[] | null;\n /** Param names captured by `slotPatternParts`, in order. */\n slotParamNames?: readonly string[] | null;\n};\n\nexport type AppPageRouteWiringRoute<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n ids?: AppRouteSemanticIds | null;\n error?: TErrorModule | null;\n errorPaths?: readonly TErrorModule[] | null;\n errors?: readonly (TErrorModule | null | undefined)[] | null;\n errorTreePositions?: readonly number[] | null;\n layoutTreePositions?: readonly number[] | null;\n layouts: readonly (TModule | null | undefined)[];\n loading?: TModule | null;\n notFound?: TModule | null;\n notFounds?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorized?: TModule | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n routeSegments?: readonly string[];\n /**\n * Keyed by stable slot id (name + owner path), not necessarily the slot prop name.\n */\n slots?: Readonly<Record<string, AppPageRouteWiringSlot<TModule, TErrorModule>>> | null;\n /**\n * Static sibling segment names at each dynamic URL level for this route. Used\n * by the client router to determine if a cached prefetch of the dynamic\n * route can be reused when navigating to a static sibling URL.\n *\n * Mirrors Next.js's `staticSiblings` tuple element on the loader-tree\n * dynamic segments — see `.nextjs-ref/packages/next/src/shared/lib/app-router-types.ts`\n * (DynamicSegmentTuple) and the loader emit in\n * `packages/next/src/build/webpack/loaders/next-app-loader/index.ts`.\n *\n * Issue: https://github.com/cloudflare/vinext/issues/1525\n */\n staticSiblings?: readonly string[] | null;\n templateTreePositions?: readonly number[] | null;\n templates?: readonly (TModule | null | undefined)[] | null;\n};\n\nexport type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n /**\n * The page module to render for this slot. Optional — when omitted, the\n * slot's existing `page` is used (e.g. when the override only changes the\n * slot's `params` for an inherited mirror with distinct param names).\n */\n pageModule?: TModule | null;\n params?: AppPageParams;\n props?: Readonly<Record<string, unknown>>;\n};\n\ntype AppPageLayoutEntry<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n errorModule?: TErrorModule | null | undefined;\n forbiddenModule?: TModule | null | undefined;\n id: string;\n layoutModule?: TModule | null | undefined;\n notFoundModule?: TModule | null | undefined;\n unauthorizedModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype BuildAppPageRouteElementOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n element: ReactNode;\n globalErrorModule?: TErrorModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n metadataPlacement?: \"body\" | \"head\";\n resolvedMetadata: Metadata | null;\n resolvedMetadataPathname?: string;\n resolvedViewport: Viewport;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route: AppPageRouteWiringRoute<TModule, TErrorModule>;\n slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;\n};\n\ntype BuildAppPageElementsOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = BuildAppPageRouteElementOptions<TModule, TErrorModule> & {\n interception?: AppElementsInterception | null;\n interceptionContext?: string | null;\n isRscRequest?: boolean;\n mountedSlotIds?: ReadonlySet<string> | null;\n renderIdentity?: AppPageRenderIdentity;\n renderMode?: AppRscRenderMode;\n routePath: string;\n};\n\ntype AppPageTemplateEntry<TModule extends AppPageModule = AppPageModule> = {\n id: string;\n templateModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype AppPageErrorEntry<TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {\n errorModule?: TErrorModule | null | undefined;\n treePosition: number;\n};\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction getErrorBoundaryExport<TModule extends AppPageErrorModule>(\n module: TModule | null | undefined,\n): AppPageErrorComponent | null {\n return module?.default ?? null;\n}\n\nexport function createAppPageTreePath(\n routeSegments: readonly string[] | null | undefined,\n treePosition: number,\n): string {\n const treePathSegments = routeSegments?.slice(0, treePosition) ?? [];\n if (treePathSegments.length === 0) {\n return \"/\";\n }\n return `/${treePathSegments.join(\"/\")}`;\n}\n\nexport function createAppPageLayoutEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: Pick<\n AppPageRouteWiringRoute<TModule, TErrorModule>,\n | \"errors\"\n | \"errorTreePositions\"\n | \"layoutTreePositions\"\n | \"layouts\"\n | \"notFounds\"\n | \"routeSegments\"\n > & {\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n },\n): AppPageLayoutEntry<TModule, TErrorModule>[] {\n return route.layouts.map((layoutModule, index) => {\n const treePosition = route.layoutTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n errorModule: route.errorTreePositions ? null : (route.errors?.[index] ?? null),\n forbiddenModule: route.forbiddens?.[index] ?? null,\n id: AppElementsWire.encodeLayoutId(treePath),\n layoutModule,\n notFoundModule: route.notFounds?.[index] ?? null,\n unauthorizedModule: route.unauthorizeds?.[index] ?? null,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageTemplateEntries<TModule extends AppPageModule>(\n route: Pick<\n AppPageRouteWiringRoute<TModule>,\n \"routeSegments\" | \"templateTreePositions\" | \"templates\"\n >,\n): AppPageTemplateEntry<TModule>[] {\n return (route.templates ?? []).map((templateModule, index) => {\n const treePosition = route.templateTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n id: AppElementsWire.encodeTemplateId(treePath),\n templateModule,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageErrorEntries<TErrorModule extends AppPageErrorModule>(\n route: Pick<\n AppPageRouteWiringRoute<AppPageModule, TErrorModule>,\n \"errorPaths\" | \"errors\" | \"errorTreePositions\"\n >,\n): AppPageErrorEntry<TErrorModule>[] {\n return (route.errorPaths ?? route.errors ?? []).flatMap((errorModule, index) => {\n if (!errorModule) return [];\n const treePosition = route.errorTreePositions?.[index];\n if (treePosition === undefined) return [];\n return [{ errorModule, treePosition }];\n });\n}\n\nfunction createAppPageParallelSlotEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n layoutIndex: number,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n getEffectiveSlotParams: (slotKey: string, slotName: string) => AppPageParams,\n): Readonly<Record<string, ReactNode>> | undefined {\n const parallelSlots: Record<string, ReactNode> = {};\n\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n\n const layoutEntry = layoutEntries[targetIndex];\n const treePath = layoutEntry?.treePath ?? \"/\";\n const slotId = resolveAppPageSlotId(slot, treePath);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotSegments = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n parallelSlots[slotName] = (\n <LayoutSegmentProvider segmentMap={{ children: slotSegments }}>\n <Slot id={slotId} />\n </LayoutSegmentProvider>\n );\n }\n\n return Object.keys(parallelSlots).length > 0 ? parallelSlots : undefined;\n}\n\nfunction resolveAppPageSlotId(slot: AppPageRouteWiringSlot, treePath: string): string {\n const slotId = AppElementsWire.encodeSlotId(slot.name, treePath);\n if (slot.id && slot.id !== slotId) {\n throw new Error(\n `[vinext] App Router slot id mismatch for @${slot.name}: graph id ${slot.id} does not match wire id ${slotId}`,\n );\n }\n return slotId;\n}\n\nfunction resolveAppPageSlotBindingState(\n slot: AppPageRouteWiringSlot,\n override: AppPageSlotOverride | undefined,\n): AppElementsSlotBinding[\"state\"] {\n const pageComponent = getDefaultExport(override?.pageModule) ?? getDefaultExport(slot.page);\n if (pageComponent) return \"active\";\n if (getDefaultExport(slot.default)) return \"default\";\n return \"unmatched\";\n}\n\nfunction createAppPageSlotBindings<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n resolveSlotOverride: (\n slotKey: string,\n slotName: string,\n ) => AppPageSlotOverride<TModule> | undefined,\n): readonly AppElementsSlotBinding[] {\n const bindings: AppElementsSlotBinding[] = [];\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const layoutEntry = layoutEntries[targetIndex] ?? null;\n const ownerLayoutId = layoutEntry?.id ?? null;\n const override = resolveSlotOverride(slotKey, slot.name);\n bindings.push({\n ownerLayoutId,\n slotId: resolveAppPageSlotId(slot, layoutEntry?.treePath ?? \"/\"),\n state: resolveAppPageSlotBindingState(slot, override),\n });\n }\n return normalizeAppElementsSlotBindings(bindings, {\n layoutIds: layoutEntries.map((entry) => entry.id),\n });\n}\n\nfunction createAppPageRouteHead(\n metadata: Metadata | null,\n viewport: Viewport,\n pathname: string,\n metadataPlacement: \"body\" | \"head\",\n): ReactNode {\n return (\n <>\n <meta charSet=\"utf-8\" />\n {metadata && metadataPlacement === \"head\" ? (\n <MetadataHead metadata={metadata} pathname={pathname} />\n ) : null}\n <ViewportHead viewport={viewport} />\n </>\n );\n}\n\nfunction createAppPageRouteBodyMetadata(\n metadata: Metadata | null,\n pathname: string,\n metadataPlacement: \"body\" | \"head\",\n): ReactNode {\n if (!metadata || metadataPlacement !== \"body\") return null;\n return (\n <div hidden dangerouslySetInnerHTML={{ __html: renderMetadataToHtml(metadata, pathname) }} />\n );\n}\n\nexport function buildAppPageElements<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements {\n const renderIdentity = options.renderIdentity;\n const interceptionContext =\n renderIdentity?.interceptionContext ?? options.interceptionContext ?? null;\n const renderMode = options.renderMode ?? APP_RSC_RENDER_MODE_NAVIGATION;\n const routeSegments = options.route.routeSegments ?? [];\n const routeResetKey = resolveAppPageRouteStateKey(routeSegments, options.matchedParams);\n const routeId =\n renderIdentity?.routeId ??\n AppElementsWire.encodeRouteId(options.routePath, interceptionContext);\n const pageId =\n renderIdentity?.pageId ?? AppElementsWire.encodePageId(options.routePath, interceptionContext);\n const layoutEntries = createAppPageLayoutEntries(options.route);\n const templateEntries = createAppPageTemplateEntries(options.route);\n const errorEntries = createAppPageErrorEntries(options.route);\n const metadataPlacement = options.metadataPlacement ?? \"head\";\n const layoutEntriesByTreePosition = new Map<number, AppPageLayoutEntry<TModule, TErrorModule>>();\n const templateEntriesByTreePosition = new Map<number, AppPageTemplateEntry<TModule>>();\n const errorEntriesByTreePosition = new Map<number, AppPageErrorEntry<TErrorModule>>();\n for (const layoutEntry of layoutEntries) {\n layoutEntriesByTreePosition.set(layoutEntry.treePosition, layoutEntry);\n }\n for (const templateEntry of templateEntries) {\n templateEntriesByTreePosition.set(templateEntry.treePosition, templateEntry);\n }\n for (const errorEntry of errorEntries) {\n errorEntriesByTreePosition.set(errorEntry.treePosition, errorEntry);\n }\n const layoutIndicesByTreePosition = new Map<number, number>();\n for (let index = 0; index < layoutEntries.length; index++) {\n layoutIndicesByTreePosition.set(layoutEntries[index].treePosition, index);\n }\n const layoutDependenciesByIndex = new Map<number, AppRenderDependency>();\n const layoutDependenciesBefore: AppRenderDependency[][] = [];\n const slotDependenciesByLayoutIndex: AppRenderDependency[][] = [];\n const templateDependenciesById = new Map<string, AppRenderDependency>();\n const templateDependenciesBeforeById = new Map<string, AppRenderDependency[]>();\n const pageDependencies: AppRenderDependency[] = [];\n const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;\n const slotNameCounts = new Map<string, number>();\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);\n }\n const orderedTreePositions = Array.from(\n new Set<number>([\n ...layoutEntries.map((entry) => entry.treePosition),\n ...templateEntries.map((entry) => entry.treePosition),\n ...errorEntries.map((entry) => entry.treePosition),\n ]),\n ).sort((left, right) => left - right);\n const resolveSlotOverride = (slotKey: string, slotName: string) => {\n const overrideByKey = options.slotOverrides?.[slotKey];\n if (overrideByKey) {\n return overrideByKey;\n }\n\n // Legacy callers may still provide overrides by slot prop name.\n // Only allow that fallback when it is unambiguous.\n if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) {\n return options.slotOverrides?.[slotName];\n }\n\n return undefined;\n };\n const elements: Record<\n string,\n | ReactNode\n | string\n | null\n | AppElementsInterception\n | readonly AppElementsSlotBinding[]\n | readonly string[]\n > = {\n ...AppElementsWire.createMetadataEntries({\n interception: renderIdentity?.interception ?? options.interception ?? null,\n interceptionContext,\n layoutIds: options.route.ids?.layouts ?? layoutEntries.map((entry) => entry.id),\n rootLayoutTreePath,\n routeId,\n slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride),\n }),\n };\n // Surface static-sibling info on the wire so the client router can decide\n // whether a cached dynamic-route prefetch can be reused when navigating to a\n // static sibling URL. Mirrors Next.js's loader-tree `staticSiblings` tuple\n // element (issue cloudflare/vinext#1525). Only included when the route has\n // dynamic segments with static siblings — keeps the payload lean for\n // fully-static routes.\n if (options.route.staticSiblings && options.route.staticSiblings.length > 0) {\n elements[APP_STATIC_SIBLINGS_KEY] = options.route.staticSiblings;\n }\n const getEffectiveSlotParams = (slotKey: string, slotName: string): AppPageParams =>\n resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;\n\n for (const treePosition of orderedTreePositions) {\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition);\n if (layoutIndex !== undefined) {\n const layoutEntry = layoutEntries[layoutIndex];\n layoutDependenciesBefore[layoutIndex] = [...pageDependencies];\n if (getDefaultExport(layoutEntry.layoutModule)) {\n const layoutDependency = createAppRenderDependency();\n layoutDependenciesByIndex.set(layoutIndex, layoutDependency);\n pageDependencies.push(layoutDependency);\n }\n slotDependenciesByLayoutIndex[layoutIndex] = [...pageDependencies];\n }\n\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n if (!templateEntry || !getDefaultExport(templateEntry.templateModule)) {\n continue;\n }\n\n const templateDependency = createAppRenderDependency();\n templateDependenciesById.set(templateEntry.id, templateDependency);\n templateDependenciesBeforeById.set(templateEntry.id, [...pageDependencies]);\n pageDependencies.push(templateDependency);\n }\n\n const routeLoadingComponent = getDefaultExport(options.route.loading);\n const isPrefetchLoadingShell = renderMode === APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL;\n const shouldRenderPrefetchLoadingShell = isPrefetchLoadingShell && routeLoadingComponent !== null;\n if (shouldRenderPrefetchLoadingShell) {\n // Client loading components serialize as module references in Flight. Keep\n // a durable marker in the shell payload so external router tests and\n // diagnostics can recognize this as a loading-boundary response without\n // requiring source text to appear in client component references.\n elements[APP_PREFETCH_LOADING_SHELL_MARKER_KEY] = \"LoadingBoundary\";\n }\n\n elements[pageId] = isPrefetchLoadingShell\n ? null\n : renderAfterAppDependencies(options.element, pageDependencies);\n\n for (const templateEntry of templateEntries) {\n const templateComponent = getDefaultExport(templateEntry.templateModule);\n if (!templateComponent) {\n continue;\n }\n const TemplateComponent = templateComponent;\n const templateDependency = templateDependenciesById.get(templateEntry.id);\n const templateElement = templateDependency ? (\n renderWithAppDependencyBarrier(\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>,\n templateDependency,\n )\n ) : (\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>\n );\n elements[templateEntry.id] = renderAfterAppDependencies(\n templateElement,\n templateDependenciesBeforeById.get(templateEntry.id) ?? [],\n );\n }\n\n for (let index = 0; index < layoutEntries.length; index++) {\n const layoutEntry = layoutEntries[index];\n const layoutComponent = getDefaultExport(layoutEntry.layoutModule);\n if (!layoutComponent) {\n continue;\n }\n\n const layoutProps: Record<string, unknown> = {\n params: options.makeThenableParams(\n resolveAppPageSegmentParams(\n options.route.routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n ),\n };\n\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== index) {\n continue;\n }\n layoutProps[slotName] = <ParallelSlot name={slotName} />;\n }\n\n const LayoutComponent = layoutComponent;\n const layoutDependency = layoutDependenciesByIndex.get(index);\n const layoutElement = layoutDependency ? (\n renderWithAppDependencyBarrier(\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>,\n layoutDependency,\n )\n ) : (\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>\n );\n elements[layoutEntry.id] = renderAfterAppDependencies(\n layoutElement,\n layoutDependenciesBefore[index] ?? [],\n );\n }\n\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const treePath = layoutEntries[targetIndex]?.treePath ?? \"/\";\n const slotId = resolveAppPageSlotId(slot, treePath);\n const slotOverride = resolveSlotOverride(slotKey, slotName);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotRouteSegments = slot.routeSegments ?? [];\n const slotResetKey = resolveAppPageRouteStateKey(slotRouteSegments, slotParams);\n const overrideOrPageComponent =\n getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);\n const defaultComponent = getDefaultExport(slot.default);\n\n // On soft nav (RSC): omit key when only default.tsx exists and the slot is\n // already mounted on the client. Absent key means the browser retains prior\n // slot content rather than replacing it. When the slot is not yet mounted\n // (first entry into this layout), include the key so default.tsx renders.\n if (\n !overrideOrPageComponent &&\n defaultComponent &&\n options.isRscRequest &&\n options.mountedSlotIds?.has(slotId)\n ) {\n continue;\n }\n\n const slotComponent = overrideOrPageComponent ?? defaultComponent;\n\n if (!slotComponent) {\n elements[slotId] = AppElementsWire.unmatchedSlotValue;\n continue;\n }\n\n const slotThenableParams = options.makeThenableParams(slotParams);\n const slotProps: Record<string, unknown> = {\n params: slotThenableParams,\n };\n if (slotOverride?.props) {\n Object.assign(slotProps, slotOverride.props);\n }\n\n const SlotComponent = slotComponent;\n let slotElement: ReactNode = <SlotComponent {...slotProps} />;\n const interceptLayouts = slotOverride?.layoutModules ?? [];\n\n for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {\n const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);\n if (!interceptLayoutComponent) {\n continue;\n }\n const InterceptLayoutComponent = interceptLayoutComponent;\n slotElement = (\n <InterceptLayoutComponent params={slotThenableParams}>\n {slotElement}\n </InterceptLayoutComponent>\n );\n }\n\n const slotLayoutComponent = getDefaultExport(slot.layout);\n if (slotLayoutComponent) {\n const SlotLayoutComponent = slotLayoutComponent;\n slotElement = (\n <SlotLayoutComponent params={slotThenableParams}>{slotElement}</SlotLayoutComponent>\n );\n }\n\n const slotLoadingComponent = getDefaultExport(slot.loading);\n if (slotLoadingComponent && !shouldSuppressLoadingBoundaries(renderMode)) {\n const SlotLoadingComponent = slotLoadingComponent;\n slotElement = (\n <Suspense key={slotResetKey} fallback={<SlotLoadingComponent />}>\n {slotElement}\n </Suspense>\n );\n }\n\n const slotErrorComponent = getErrorBoundaryExport(slot.error);\n if (slotErrorComponent) {\n slotElement = (\n <ErrorBoundary resetKey={slotResetKey} fallback={slotErrorComponent}>\n {slotElement}\n </ErrorBoundary>\n );\n }\n\n elements[slotId] = renderAfterAppDependencies(\n slotElement,\n targetIndex >= 0 ? (slotDependenciesByLayoutIndex[targetIndex] ?? []) : [],\n );\n }\n\n let routeChildren: ReactNode = (\n <LayoutSegmentProvider segmentMap={{ children: [] }}>\n <AppRouterScrollTarget>\n <Slot id={pageId} />\n </AppRouterScrollTarget>\n </LayoutSegmentProvider>\n );\n\n if (isPrefetchLoadingShell) {\n if (routeLoadingComponent === null) {\n routeChildren = null;\n } else {\n const RouteLoadingComponent = routeLoadingComponent;\n routeChildren = <RouteLoadingComponent />;\n }\n } else {\n // Wrap the page slot in a per-segment RedirectBoundary so that a\n // redirect() thrown from a server component (or a client component\n // within the page subtree) is caught here — below the route's layouts —\n // rather than at the top-level boundary in app-browser-entry. Catching\n // at the top level unmounts the entire route tree including layouts,\n // which destroys client-side state in layout-hosted components\n // (counters, theme toggles, form drafts). Here, only the page subtree\n // is unmounted; the surrounding layouts stay mounted across the\n // boundary's null-render → router.replace transition, and segment\n // reuse keeps their React state intact.\n //\n // Placed inside the Suspense (loading) boundary to match Next.js nesting\n // for the redirect boundary specifically:\n // Error > AccessFallback > Loading (Suspense) > Redirect > content\n // (Note: Next.js places AccessFallback inside Loading, not outside — that\n // is a pre-existing nesting divergence tracked separately.)\n // This keeps the loading fallback visible during redirect-driven\n // transitions rather than unmounting it.\n routeChildren = <RedirectBoundary>{routeChildren}</RedirectBoundary>;\n\n if (routeLoadingComponent && !shouldSuppressLoadingBoundaries(renderMode)) {\n const RouteLoadingComponent = routeLoadingComponent;\n // Route-level wrappers cover the full page branch in vinext's flat element\n // transport, so their reset key includes the visible segment-state path.\n // Dynamic param changes reset the pending boundary, while search-only changes\n // preserve it.\n routeChildren = (\n <Suspense key={routeResetKey} fallback={<RouteLoadingComponent />}>\n {routeChildren}\n </Suspense>\n );\n }\n }\n\n const lastLayoutErrorModule =\n errorEntries.length > 0 ? errorEntries[errorEntries.length - 1].errorModule : null;\n // Next.js nesting (outer to inner): Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap first, then Forbidden, Unauthorized, Error.\n const notFoundComponent =\n getDefaultExport(options.route.notFound) ?? getDefaultExport(options.rootNotFoundModule);\n if (notFoundComponent) {\n const NotFoundComponent = notFoundComponent;\n routeChildren = (\n <NotFoundBoundary resetKey={routeResetKey} fallback={<NotFoundComponent />}>\n {routeChildren}\n </NotFoundBoundary>\n );\n }\n\n const forbiddenComponent =\n getDefaultExport(options.route.forbidden) ?? getDefaultExport(options.rootForbiddenModule);\n if (forbiddenComponent) {\n const ForbiddenComponent = forbiddenComponent;\n routeChildren = (\n <ForbiddenBoundary resetKey={routeResetKey} fallback={<ForbiddenComponent />}>\n {routeChildren}\n </ForbiddenBoundary>\n );\n }\n\n const unauthorizedComponent =\n getDefaultExport(options.route.unauthorized) ??\n getDefaultExport(options.rootUnauthorizedModule);\n if (unauthorizedComponent) {\n const UnauthorizedComponent = unauthorizedComponent;\n routeChildren = (\n <UnauthorizedBoundary resetKey={routeResetKey} fallback={<UnauthorizedComponent />}>\n {routeChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const pageErrorComponent = getErrorBoundaryExport(options.route.error);\n if (pageErrorComponent && options.route.error !== lastLayoutErrorModule) {\n routeChildren = (\n <ErrorBoundary resetKey={routeResetKey} fallback={pageErrorComponent}>\n {routeChildren}\n </ErrorBoundary>\n );\n }\n\n for (let index = orderedTreePositions.length - 1; index >= 0; index--) {\n const treePosition = orderedTreePositions[index];\n const segmentResetKey = resolveAppPageSegmentStateKey(\n routeSegments,\n treePosition,\n options.matchedParams,\n );\n let segmentChildren: ReactNode = routeChildren;\n const layoutEntry = layoutEntriesByTreePosition.get(treePosition);\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n const errorEntry = errorEntriesByTreePosition.get(treePosition);\n\n // Next.js nesting per segment (outer to inner): Layout > Template > Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap the leaf subtree first,\n // then ErrorBoundary, then Template, with the Layout slot outermost.\n if (layoutEntry) {\n const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule);\n if (layoutNotFoundComponent) {\n const LayoutNotFoundComponent = layoutNotFoundComponent;\n segmentChildren = (\n <NotFoundBoundary resetKey={segmentResetKey} fallback={<LayoutNotFoundComponent />}>\n {segmentChildren}\n </NotFoundBoundary>\n );\n }\n\n const layoutForbiddenComponent = getDefaultExport(layoutEntry.forbiddenModule);\n if (layoutForbiddenComponent) {\n const LayoutForbiddenComponent = layoutForbiddenComponent;\n segmentChildren = (\n <ForbiddenBoundary resetKey={segmentResetKey} fallback={<LayoutForbiddenComponent />}>\n {segmentChildren}\n </ForbiddenBoundary>\n );\n }\n\n const layoutUnauthorizedComponent = getDefaultExport(layoutEntry.unauthorizedModule);\n if (layoutUnauthorizedComponent) {\n const LayoutUnauthorizedComponent = layoutUnauthorizedComponent;\n segmentChildren = (\n <UnauthorizedBoundary\n resetKey={segmentResetKey}\n fallback={<LayoutUnauthorizedComponent />}\n >\n {segmentChildren}\n </UnauthorizedBoundary>\n );\n }\n }\n\n const segmentErrorComponent = getErrorBoundaryExport(\n errorEntry?.errorModule ?? layoutEntry?.errorModule,\n );\n if (segmentErrorComponent) {\n segmentChildren = (\n <ErrorBoundary resetKey={segmentResetKey} fallback={segmentErrorComponent}>\n {segmentChildren}\n </ErrorBoundary>\n );\n }\n\n if (templateEntry && getDefaultExport(templateEntry.templateModule)) {\n segmentChildren = (\n <Slot id={templateEntry.id} key={segmentResetKey}>\n {segmentChildren}\n </Slot>\n );\n }\n\n if (!layoutEntry) {\n routeChildren = segmentChildren;\n continue;\n }\n const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;\n const segmentMap: { children: string[] } & Record<string, string[]> = {\n children: resolveAppPageChildSegments(\n routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n };\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n segmentMap[slotName] = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n }\n\n routeChildren = (\n <LayoutSegmentProvider segmentMap={segmentMap}>\n {layoutHasElement ? (\n <Slot\n id={layoutEntry.id}\n parallelSlots={createAppPageParallelSlotEntries(\n layoutIndex,\n layoutEntries,\n options.route,\n getEffectiveSlotParams,\n )}\n >\n {segmentChildren}\n </Slot>\n ) : (\n segmentChildren\n )}\n </LayoutSegmentProvider>\n );\n }\n\n const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);\n if (globalErrorComponent) {\n routeChildren = <ErrorBoundary fallback={globalErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n elements[routeId] = (\n <>\n {createAppPageRouteHead(\n options.resolvedMetadata,\n options.resolvedViewport,\n options.resolvedMetadataPathname ?? options.routePath,\n metadataPlacement,\n )}\n {routeChildren}\n {createAppPageRouteBodyMetadata(\n options.resolvedMetadata,\n options.resolvedMetadataPathname ?? options.routePath,\n metadataPlacement,\n )}\n </>\n );\n\n return elements;\n}\n"],"mappings":"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"}
|
|
@@ -18,6 +18,11 @@ type AppPageSsrHandler = {
|
|
|
18
18
|
formState?: ReactFormState | null;
|
|
19
19
|
scriptNonce?: string;
|
|
20
20
|
basePath?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Allow-list of OpenTelemetry propagation keys to emit as `<meta>` tags
|
|
23
|
+
* in the SSR head. Sourced from `experimental.clientTraceMetadata`.
|
|
24
|
+
*/
|
|
25
|
+
clientTraceMetadata?: readonly string[];
|
|
21
26
|
rootParams?: RootParams;
|
|
22
27
|
sideStream?: ReadableStream<Uint8Array>;
|
|
23
28
|
capturedRscDataRef?: {
|
|
@@ -33,6 +38,12 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
33
38
|
rscStream: ReadableStream<Uint8Array>;
|
|
34
39
|
scriptNonce?: string;
|
|
35
40
|
basePath?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Allow-list of OpenTelemetry propagation keys (from
|
|
43
|
+
* `experimental.clientTraceMetadata`) to surface as `<meta>` tags in
|
|
44
|
+
* the SSR head. Undefined or empty disables emission.
|
|
45
|
+
*/
|
|
46
|
+
clientTraceMetadata?: readonly string[];
|
|
36
47
|
rootParams?: RootParams;
|
|
37
48
|
ssrHandler: AppPageSsrHandler;
|
|
38
49
|
/** Pre-split side stream for fused embed+capture (#981). When set,
|
|
@@ -46,6 +57,7 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
46
57
|
type RenderAppPageHtmlResponseOptions = {
|
|
47
58
|
clearRequestContext: () => void;
|
|
48
59
|
fontLinkHeader?: string;
|
|
60
|
+
isEdgeRuntime?: boolean;
|
|
49
61
|
middlewareHeaders?: Headers | null;
|
|
50
62
|
status: number;
|
|
51
63
|
} & RenderAppPageHtmlStreamOptions;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
|
|
2
2
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
3
|
+
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
3
4
|
//#region src/server/app-page-stream.ts
|
|
4
5
|
function createAppPageFontData(options) {
|
|
5
6
|
return {
|
|
@@ -13,6 +14,7 @@ async function renderAppPageHtmlStream(options) {
|
|
|
13
14
|
formState: options.formState ?? null,
|
|
14
15
|
scriptNonce: options.scriptNonce,
|
|
15
16
|
basePath: options.basePath,
|
|
17
|
+
clientTraceMetadata: options.clientTraceMetadata,
|
|
16
18
|
rootParams: options.rootParams,
|
|
17
19
|
sideStream: options.sideStream,
|
|
18
20
|
capturedRscDataRef: options.capturedRscDataRef,
|
|
@@ -63,6 +65,7 @@ async function renderAppPageHtmlResponse(options) {
|
|
|
63
65
|
"Content-Type": "text/html; charset=utf-8",
|
|
64
66
|
Vary: VINEXT_RSC_VARY_HEADER
|
|
65
67
|
});
|
|
68
|
+
applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);
|
|
66
69
|
if (options.fontLinkHeader) headers.set("Link", options.fontLinkHeader);
|
|
67
70
|
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
|
|
68
71
|
return new Response(safeStream, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-page-stream.js","names":[],"sources":["../../src/server/app-page-stream.ts"],"sourcesContent":["import type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport type { RootParams } from \"vinext/shims/root-params\";\n\nexport type AppPageFontData = {\n links: string[];\n preloads: readonly AppPageFontPreload[];\n styles: string[];\n};\n\ntype CreateAppPageFontDataOptions = {\n getLinks: () => string[];\n getPreloads: () => AppPageFontPreload[];\n getStyles: () => string[];\n};\n\nexport type AppPageSsrHandler = {\n handleSsr: (\n rscStream: ReadableStream<Uint8Array>,\n navigationContext: unknown,\n fontData: AppPageFontData,\n options?: {\n formState?: ReactFormState | null;\n scriptNonce?: string;\n basePath?: string;\n rootParams?: RootParams;\n sideStream?: ReadableStream<Uint8Array>;\n capturedRscDataRef?: { value: Promise<ArrayBuffer> | null };\n /** When true, wait for the full React tree before emitting bytes. */\n waitForAllReady?: boolean;\n },\n ) => Promise<ReadableStream<Uint8Array>>;\n};\n\ntype RenderAppPageHtmlStreamOptions = {\n fontData: AppPageFontData;\n formState?: ReactFormState | null;\n navigationContext: unknown;\n rscStream: ReadableStream<Uint8Array>;\n scriptNonce?: string;\n basePath?: string;\n rootParams?: RootParams;\n ssrHandler: AppPageSsrHandler;\n /** Pre-split side stream for fused embed+capture (#981). When set,\n * handleSsr skips its internal tee and accumulates raw RSC bytes. */\n sideStream?: ReadableStream<Uint8Array>;\n /** Out-parameter filled with accumulated raw RSC bytes after stream consumption. */\n capturedRscDataRef?: { value: Promise<ArrayBuffer> | null };\n /** When true, wait for the full React tree before emitting bytes. */\n waitForAllReady?: boolean;\n};\n\ntype RenderAppPageHtmlResponseOptions = {\n clearRequestContext: () => void;\n fontLinkHeader?: string;\n middlewareHeaders?: Headers | null;\n status: number;\n} & RenderAppPageHtmlStreamOptions;\n\ntype AppPageHtmlStreamRecoveryResult = {\n htmlStream: ReadableStream<Uint8Array> | null;\n response: Response | null;\n};\n\ntype RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError> = {\n onShellRendered?: () => void;\n renderErrorBoundaryResponse: (error: unknown) => Promise<Response | null>;\n renderHtmlStream: () => Promise<ReadableStream<Uint8Array>>;\n renderSpecialErrorResponse: (specialError: TSpecialError) => Promise<Response>;\n resolveSpecialError: (error: unknown) => TSpecialError | null;\n};\n\ntype AppPageRscErrorTracker = {\n getCapturedError: () => unknown;\n /**\n * Returns a NEXT_REDIRECT or NEXT_HTTP_ERROR_FALLBACK error captured during\n * the RSC render. Read after the SSR shell promise resolves to swap a\n * 307/404 in place of the streamed body when redirect()/notFound() throws\n * synchronously inside a route-level Suspense boundary (loading.tsx).\n */\n getCapturedSpecialError: () => unknown;\n onRenderError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;\n};\n\ntype ShouldRerenderAppPageWithGlobalErrorOptions = {\n capturedError: unknown;\n hasLocalBoundary: boolean;\n};\n\nexport function createAppPageFontData(options: CreateAppPageFontDataOptions): AppPageFontData {\n return {\n links: options.getLinks(),\n preloads: options.getPreloads(),\n styles: options.getStyles(),\n };\n}\n\nexport async function renderAppPageHtmlStream(\n options: RenderAppPageHtmlStreamOptions,\n): Promise<ReadableStream<Uint8Array>> {\n const ssrOptions = {\n formState: options.formState ?? null,\n scriptNonce: options.scriptNonce,\n basePath: options.basePath,\n rootParams: options.rootParams,\n sideStream: options.sideStream,\n capturedRscDataRef: options.capturedRscDataRef,\n waitForAllReady: options.waitForAllReady,\n };\n\n return options.ssrHandler.handleSsr(\n options.rscStream,\n options.navigationContext,\n options.fontData,\n ssrOptions,\n );\n}\n\n/**\n * Wraps a stream so that `onFlush` is called when the last byte has been read\n * by the downstream consumer (i.e. when the HTTP layer finishes draining the\n * response body). This is the correct place to clear per-request context,\n * because the RSC/SSR pipeline is lazy — components execute while the stream\n * is being consumed, not when the stream handle is first obtained.\n */\nexport function deferUntilStreamConsumed(\n stream: ReadableStream<Uint8Array>,\n onFlush: () => void,\n): ReadableStream<Uint8Array> {\n let called = false;\n const once = () => {\n if (!called) {\n called = true;\n onFlush();\n }\n };\n\n const cleanup = new TransformStream<Uint8Array, Uint8Array>({\n flush() {\n once();\n },\n });\n\n const piped = stream.pipeThrough(cleanup);\n\n // Wrap with a ReadableStream so we can intercept cancel() — the TransformStream\n // Transformer interface does not expose a cancel hook in the Web Streams spec.\n const reader = piped.getReader();\n return new ReadableStream<Uint8Array>({\n pull(controller) {\n return reader.read().then(\n ({ done, value }) => {\n if (done) {\n controller.close();\n } else {\n controller.enqueue(value);\n }\n },\n (error) => {\n once();\n controller.error(error);\n },\n );\n },\n cancel(reason) {\n // Stream cancelled before fully consumed (e.g. client disconnected).\n // Still clear per-request context to avoid leaks.\n once();\n return reader.cancel(reason);\n },\n });\n}\n\nexport async function renderAppPageHtmlResponse(\n options: RenderAppPageHtmlResponseOptions,\n): Promise<Response> {\n const htmlStream = await renderAppPageHtmlStream(options);\n\n // Defer clearRequestContext() until the stream is fully consumed by the HTTP\n // layer. Calling it synchronously here would race the lazy RSC/SSR pipeline:\n // components execute while the stream is being pulled, not when the handle\n // is first returned. See: https://github.com/cloudflare/vinext/issues/660\n const safeStream = deferUntilStreamConsumed(htmlStream, () => {\n options.clearRequestContext();\n });\n\n const headers = new Headers({\n \"Content-Type\": \"text/html; charset=utf-8\",\n Vary: VINEXT_RSC_VARY_HEADER,\n });\n\n if (options.fontLinkHeader) {\n headers.set(\"Link\", options.fontLinkHeader);\n }\n\n mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);\n\n return new Response(safeStream, {\n status: options.status,\n headers,\n });\n}\n\nexport async function renderAppPageHtmlStreamWithRecovery<TSpecialError>(\n options: RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError>,\n): Promise<AppPageHtmlStreamRecoveryResult> {\n try {\n const htmlStream = await options.renderHtmlStream();\n options.onShellRendered?.();\n return {\n htmlStream,\n response: null,\n };\n } catch (error) {\n const specialError = options.resolveSpecialError(error);\n if (specialError) {\n return {\n htmlStream: null,\n response: await options.renderSpecialErrorResponse(specialError),\n };\n }\n\n const boundaryResponse = await options.renderErrorBoundaryResponse(error);\n if (boundaryResponse) {\n return {\n htmlStream: null,\n response: boundaryResponse,\n };\n }\n\n throw error;\n }\n}\n\nexport function createAppPageRscErrorTracker(\n baseOnError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown,\n): AppPageRscErrorTracker {\n let capturedError: unknown = null;\n let capturedSpecialError: unknown = null;\n\n return {\n getCapturedError() {\n return capturedError;\n },\n getCapturedSpecialError() {\n return capturedSpecialError;\n },\n onRenderError(error, requestInfo, errorContext) {\n if (error && typeof error === \"object\" && \"digest\" in error) {\n // Errors with a digest are signal throws (NEXT_REDIRECT,\n // NEXT_NOT_FOUND, NEXT_HTTP_ERROR_FALLBACK). They're not real\n // failures — keep the first one so the lifecycle can swap a\n // 307/404 in place of a streamed \"Switched to client rendering\"\n // body for routes with a route-level Suspense boundary.\n if (capturedSpecialError === null) {\n capturedSpecialError = error;\n }\n } else {\n capturedError = error;\n }\n return baseOnError(error, requestInfo, errorContext);\n },\n };\n}\n\nexport function shouldRerenderAppPageWithGlobalError(\n options: ShouldRerenderAppPageWithGlobalErrorOptions,\n): boolean {\n return Boolean(options.capturedError) && !options.hasLocalBoundary;\n}\n"],"mappings":";;;AA2FA,SAAgB,sBAAsB,SAAwD;CAC5F,OAAO;EACL,OAAO,QAAQ,UAAU;EACzB,UAAU,QAAQ,aAAa;EAC/B,QAAQ,QAAQ,WAAW;EAC5B;;AAGH,eAAsB,wBACpB,SACqC;CACrC,MAAM,aAAa;EACjB,WAAW,QAAQ,aAAa;EAChC,aAAa,QAAQ;EACrB,UAAU,QAAQ;EAClB,YAAY,QAAQ;EACpB,YAAY,QAAQ;EACpB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EAC1B;CAED,OAAO,QAAQ,WAAW,UACxB,QAAQ,WACR,QAAQ,mBACR,QAAQ,UACR,WACD;;;;;;;;;AAUH,SAAgB,yBACd,QACA,SAC4B;CAC5B,IAAI,SAAS;CACb,MAAM,aAAa;EACjB,IAAI,CAAC,QAAQ;GACX,SAAS;GACT,SAAS;;;CAIb,MAAM,UAAU,IAAI,gBAAwC,EAC1D,QAAQ;EACN,MAAM;IAET,CAAC;CAMF,MAAM,SAJQ,OAAO,YAAY,QAIb,CAAC,WAAW;CAChC,OAAO,IAAI,eAA2B;EACpC,KAAK,YAAY;GACf,OAAO,OAAO,MAAM,CAAC,MAClB,EAAE,MAAM,YAAY;IACnB,IAAI,MACF,WAAW,OAAO;SAElB,WAAW,QAAQ,MAAM;OAG5B,UAAU;IACT,MAAM;IACN,WAAW,MAAM,MAAM;KAE1B;;EAEH,OAAO,QAAQ;GAGb,MAAM;GACN,OAAO,OAAO,OAAO,OAAO;;EAE/B,CAAC;;AAGJ,eAAsB,0BACpB,SACmB;CAOnB,MAAM,aAAa,yBAAyB,MANnB,wBAAwB,QAAQ,QAMK;EAC5D,QAAQ,qBAAqB;GAC7B;CAEF,MAAM,UAAU,IAAI,QAAQ;EAC1B,gBAAgB;EAChB,MAAM;EACP,CAAC;CAEF,IAAI,QAAQ,gBACV,QAAQ,IAAI,QAAQ,QAAQ,eAAe;CAG7C,+BAA+B,SAAS,QAAQ,qBAAqB,KAAK;CAE1E,OAAO,IAAI,SAAS,YAAY;EAC9B,QAAQ,QAAQ;EAChB;EACD,CAAC;;AAGJ,eAAsB,oCACpB,SAC0C;CAC1C,IAAI;EACF,MAAM,aAAa,MAAM,QAAQ,kBAAkB;EACnD,QAAQ,mBAAmB;EAC3B,OAAO;GACL;GACA,UAAU;GACX;UACM,OAAO;EACd,MAAM,eAAe,QAAQ,oBAAoB,MAAM;EACvD,IAAI,cACF,OAAO;GACL,YAAY;GACZ,UAAU,MAAM,QAAQ,2BAA2B,aAAa;GACjE;EAGH,MAAM,mBAAmB,MAAM,QAAQ,4BAA4B,MAAM;EACzE,IAAI,kBACF,OAAO;GACL,YAAY;GACZ,UAAU;GACX;EAGH,MAAM;;;AAIV,SAAgB,6BACd,aACwB;CACxB,IAAI,gBAAyB;CAC7B,IAAI,uBAAgC;CAEpC,OAAO;EACL,mBAAmB;GACjB,OAAO;;EAET,0BAA0B;GACxB,OAAO;;EAET,cAAc,OAAO,aAAa,cAAc;GAC9C,IAAI,SAAS,OAAO,UAAU,YAAY,YAAY;QAMhD,yBAAyB,MAC3B,uBAAuB;UAGzB,gBAAgB;GAElB,OAAO,YAAY,OAAO,aAAa,aAAa;;EAEvD;;AAGH,SAAgB,qCACd,SACS;CACT,OAAO,QAAQ,QAAQ,cAAc,IAAI,CAAC,QAAQ"}
|
|
1
|
+
{"version":3,"file":"app-page-stream.js","names":[],"sources":["../../src/server/app-page-stream.ts"],"sourcesContent":["import type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport { applyEdgeRuntimeHeader } from \"./app-page-response.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport type { RootParams } from \"vinext/shims/root-params\";\n\nexport type AppPageFontData = {\n links: string[];\n preloads: readonly AppPageFontPreload[];\n styles: string[];\n};\n\ntype CreateAppPageFontDataOptions = {\n getLinks: () => string[];\n getPreloads: () => AppPageFontPreload[];\n getStyles: () => string[];\n};\n\nexport type AppPageSsrHandler = {\n handleSsr: (\n rscStream: ReadableStream<Uint8Array>,\n navigationContext: unknown,\n fontData: AppPageFontData,\n options?: {\n formState?: ReactFormState | null;\n scriptNonce?: string;\n basePath?: string;\n /**\n * Allow-list of OpenTelemetry propagation keys to emit as `<meta>` tags\n * in the SSR head. Sourced from `experimental.clientTraceMetadata`.\n */\n clientTraceMetadata?: readonly string[];\n rootParams?: RootParams;\n sideStream?: ReadableStream<Uint8Array>;\n capturedRscDataRef?: { value: Promise<ArrayBuffer> | null };\n /** When true, wait for the full React tree before emitting bytes. */\n waitForAllReady?: boolean;\n },\n ) => Promise<ReadableStream<Uint8Array>>;\n};\n\ntype RenderAppPageHtmlStreamOptions = {\n fontData: AppPageFontData;\n formState?: ReactFormState | null;\n navigationContext: unknown;\n rscStream: ReadableStream<Uint8Array>;\n scriptNonce?: string;\n basePath?: string;\n /**\n * Allow-list of OpenTelemetry propagation keys (from\n * `experimental.clientTraceMetadata`) to surface as `<meta>` tags in\n * the SSR head. Undefined or empty disables emission.\n */\n clientTraceMetadata?: readonly string[];\n rootParams?: RootParams;\n ssrHandler: AppPageSsrHandler;\n /** Pre-split side stream for fused embed+capture (#981). When set,\n * handleSsr skips its internal tee and accumulates raw RSC bytes. */\n sideStream?: ReadableStream<Uint8Array>;\n /** Out-parameter filled with accumulated raw RSC bytes after stream consumption. */\n capturedRscDataRef?: { value: Promise<ArrayBuffer> | null };\n /** When true, wait for the full React tree before emitting bytes. */\n waitForAllReady?: boolean;\n};\n\ntype RenderAppPageHtmlResponseOptions = {\n clearRequestContext: () => void;\n fontLinkHeader?: string;\n isEdgeRuntime?: boolean;\n middlewareHeaders?: Headers | null;\n status: number;\n} & RenderAppPageHtmlStreamOptions;\n\ntype AppPageHtmlStreamRecoveryResult = {\n htmlStream: ReadableStream<Uint8Array> | null;\n response: Response | null;\n};\n\ntype RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError> = {\n onShellRendered?: () => void;\n renderErrorBoundaryResponse: (error: unknown) => Promise<Response | null>;\n renderHtmlStream: () => Promise<ReadableStream<Uint8Array>>;\n renderSpecialErrorResponse: (specialError: TSpecialError) => Promise<Response>;\n resolveSpecialError: (error: unknown) => TSpecialError | null;\n};\n\ntype AppPageRscErrorTracker = {\n getCapturedError: () => unknown;\n /**\n * Returns a NEXT_REDIRECT or NEXT_HTTP_ERROR_FALLBACK error captured during\n * the RSC render. Read after the SSR shell promise resolves to swap a\n * 307/404 in place of the streamed body when redirect()/notFound() throws\n * synchronously inside a route-level Suspense boundary (loading.tsx).\n */\n getCapturedSpecialError: () => unknown;\n onRenderError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;\n};\n\ntype ShouldRerenderAppPageWithGlobalErrorOptions = {\n capturedError: unknown;\n hasLocalBoundary: boolean;\n};\n\nexport function createAppPageFontData(options: CreateAppPageFontDataOptions): AppPageFontData {\n return {\n links: options.getLinks(),\n preloads: options.getPreloads(),\n styles: options.getStyles(),\n };\n}\n\nexport async function renderAppPageHtmlStream(\n options: RenderAppPageHtmlStreamOptions,\n): Promise<ReadableStream<Uint8Array>> {\n const ssrOptions = {\n formState: options.formState ?? null,\n scriptNonce: options.scriptNonce,\n basePath: options.basePath,\n clientTraceMetadata: options.clientTraceMetadata,\n rootParams: options.rootParams,\n sideStream: options.sideStream,\n capturedRscDataRef: options.capturedRscDataRef,\n waitForAllReady: options.waitForAllReady,\n };\n\n return options.ssrHandler.handleSsr(\n options.rscStream,\n options.navigationContext,\n options.fontData,\n ssrOptions,\n );\n}\n\n/**\n * Wraps a stream so that `onFlush` is called when the last byte has been read\n * by the downstream consumer (i.e. when the HTTP layer finishes draining the\n * response body). This is the correct place to clear per-request context,\n * because the RSC/SSR pipeline is lazy — components execute while the stream\n * is being consumed, not when the stream handle is first obtained.\n */\nexport function deferUntilStreamConsumed(\n stream: ReadableStream<Uint8Array>,\n onFlush: () => void,\n): ReadableStream<Uint8Array> {\n let called = false;\n const once = () => {\n if (!called) {\n called = true;\n onFlush();\n }\n };\n\n const cleanup = new TransformStream<Uint8Array, Uint8Array>({\n flush() {\n once();\n },\n });\n\n const piped = stream.pipeThrough(cleanup);\n\n // Wrap with a ReadableStream so we can intercept cancel() — the TransformStream\n // Transformer interface does not expose a cancel hook in the Web Streams spec.\n const reader = piped.getReader();\n return new ReadableStream<Uint8Array>({\n pull(controller) {\n return reader.read().then(\n ({ done, value }) => {\n if (done) {\n controller.close();\n } else {\n controller.enqueue(value);\n }\n },\n (error) => {\n once();\n controller.error(error);\n },\n );\n },\n cancel(reason) {\n // Stream cancelled before fully consumed (e.g. client disconnected).\n // Still clear per-request context to avoid leaks.\n once();\n return reader.cancel(reason);\n },\n });\n}\n\nexport async function renderAppPageHtmlResponse(\n options: RenderAppPageHtmlResponseOptions,\n): Promise<Response> {\n const htmlStream = await renderAppPageHtmlStream(options);\n\n // Defer clearRequestContext() until the stream is fully consumed by the HTTP\n // layer. Calling it synchronously here would race the lazy RSC/SSR pipeline:\n // components execute while the stream is being pulled, not when the handle\n // is first returned. See: https://github.com/cloudflare/vinext/issues/660\n const safeStream = deferUntilStreamConsumed(htmlStream, () => {\n options.clearRequestContext();\n });\n\n const headers = new Headers({\n \"Content-Type\": \"text/html; charset=utf-8\",\n Vary: VINEXT_RSC_VARY_HEADER,\n });\n\n applyEdgeRuntimeHeader(headers, options.isEdgeRuntime);\n\n if (options.fontLinkHeader) {\n headers.set(\"Link\", options.fontLinkHeader);\n }\n\n mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);\n\n return new Response(safeStream, {\n status: options.status,\n headers,\n });\n}\n\nexport async function renderAppPageHtmlStreamWithRecovery<TSpecialError>(\n options: RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError>,\n): Promise<AppPageHtmlStreamRecoveryResult> {\n try {\n const htmlStream = await options.renderHtmlStream();\n options.onShellRendered?.();\n return {\n htmlStream,\n response: null,\n };\n } catch (error) {\n const specialError = options.resolveSpecialError(error);\n if (specialError) {\n return {\n htmlStream: null,\n response: await options.renderSpecialErrorResponse(specialError),\n };\n }\n\n const boundaryResponse = await options.renderErrorBoundaryResponse(error);\n if (boundaryResponse) {\n return {\n htmlStream: null,\n response: boundaryResponse,\n };\n }\n\n throw error;\n }\n}\n\nexport function createAppPageRscErrorTracker(\n baseOnError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown,\n): AppPageRscErrorTracker {\n let capturedError: unknown = null;\n let capturedSpecialError: unknown = null;\n\n return {\n getCapturedError() {\n return capturedError;\n },\n getCapturedSpecialError() {\n return capturedSpecialError;\n },\n onRenderError(error, requestInfo, errorContext) {\n if (error && typeof error === \"object\" && \"digest\" in error) {\n // Errors with a digest are signal throws (NEXT_REDIRECT,\n // NEXT_NOT_FOUND, NEXT_HTTP_ERROR_FALLBACK). They're not real\n // failures — keep the first one so the lifecycle can swap a\n // 307/404 in place of a streamed \"Switched to client rendering\"\n // body for routes with a route-level Suspense boundary.\n if (capturedSpecialError === null) {\n capturedSpecialError = error;\n }\n } else {\n capturedError = error;\n }\n return baseOnError(error, requestInfo, errorContext);\n },\n };\n}\n\nexport function shouldRerenderAppPageWithGlobalError(\n options: ShouldRerenderAppPageWithGlobalErrorOptions,\n): boolean {\n return Boolean(options.capturedError) && !options.hasLocalBoundary;\n}\n"],"mappings":";;;;AAwGA,SAAgB,sBAAsB,SAAwD;CAC5F,OAAO;EACL,OAAO,QAAQ,UAAU;EACzB,UAAU,QAAQ,aAAa;EAC/B,QAAQ,QAAQ,WAAW;EAC5B;;AAGH,eAAsB,wBACpB,SACqC;CACrC,MAAM,aAAa;EACjB,WAAW,QAAQ,aAAa;EAChC,aAAa,QAAQ;EACrB,UAAU,QAAQ;EAClB,qBAAqB,QAAQ;EAC7B,YAAY,QAAQ;EACpB,YAAY,QAAQ;EACpB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EAC1B;CAED,OAAO,QAAQ,WAAW,UACxB,QAAQ,WACR,QAAQ,mBACR,QAAQ,UACR,WACD;;;;;;;;;AAUH,SAAgB,yBACd,QACA,SAC4B;CAC5B,IAAI,SAAS;CACb,MAAM,aAAa;EACjB,IAAI,CAAC,QAAQ;GACX,SAAS;GACT,SAAS;;;CAIb,MAAM,UAAU,IAAI,gBAAwC,EAC1D,QAAQ;EACN,MAAM;IAET,CAAC;CAMF,MAAM,SAJQ,OAAO,YAAY,QAIb,CAAC,WAAW;CAChC,OAAO,IAAI,eAA2B;EACpC,KAAK,YAAY;GACf,OAAO,OAAO,MAAM,CAAC,MAClB,EAAE,MAAM,YAAY;IACnB,IAAI,MACF,WAAW,OAAO;SAElB,WAAW,QAAQ,MAAM;OAG5B,UAAU;IACT,MAAM;IACN,WAAW,MAAM,MAAM;KAE1B;;EAEH,OAAO,QAAQ;GAGb,MAAM;GACN,OAAO,OAAO,OAAO,OAAO;;EAE/B,CAAC;;AAGJ,eAAsB,0BACpB,SACmB;CAOnB,MAAM,aAAa,yBAAyB,MANnB,wBAAwB,QAAQ,QAMK;EAC5D,QAAQ,qBAAqB;GAC7B;CAEF,MAAM,UAAU,IAAI,QAAQ;EAC1B,gBAAgB;EAChB,MAAM;EACP,CAAC;CAEF,uBAAuB,SAAS,QAAQ,cAAc;CAEtD,IAAI,QAAQ,gBACV,QAAQ,IAAI,QAAQ,QAAQ,eAAe;CAG7C,+BAA+B,SAAS,QAAQ,qBAAqB,KAAK;CAE1E,OAAO,IAAI,SAAS,YAAY;EAC9B,QAAQ,QAAQ;EAChB;EACD,CAAC;;AAGJ,eAAsB,oCACpB,SAC0C;CAC1C,IAAI;EACF,MAAM,aAAa,MAAM,QAAQ,kBAAkB;EACnD,QAAQ,mBAAmB;EAC3B,OAAO;GACL;GACA,UAAU;GACX;UACM,OAAO;EACd,MAAM,eAAe,QAAQ,oBAAoB,MAAM;EACvD,IAAI,cACF,OAAO;GACL,YAAY;GACZ,UAAU,MAAM,QAAQ,2BAA2B,aAAa;GACjE;EAGH,MAAM,mBAAmB,MAAM,QAAQ,4BAA4B,MAAM;EACzE,IAAI,kBACF,OAAO;GACL,YAAY;GACZ,UAAU;GACX;EAGH,MAAM;;;AAIV,SAAgB,6BACd,aACwB;CACxB,IAAI,gBAAyB;CAC7B,IAAI,uBAAgC;CAEpC,OAAO;EACL,mBAAmB;GACjB,OAAO;;EAET,0BAA0B;GACxB,OAAO;;EAET,cAAc,OAAO,aAAa,cAAc;GAC9C,IAAI,SAAS,OAAO,UAAU,YAAY,YAAY;QAMhD,yBAAyB,MAC3B,uBAAuB;UAGzB,gBAAgB;GAElB,OAAO,YAAY,OAAO,aAAa,aAAa;;EAEvD;;AAGH,SAAgB,qCACd,SACS;CACT,OAAO,QAAQ,QAAQ,cAAc,IAAI,CAAC,QAAQ"}
|
|
@@ -22,6 +22,7 @@ function buildRouteHandlerPageCacheTags(pathname, extraTags, routeSegments) {
|
|
|
22
22
|
async function runInRouteHandlerRevalidationContext(options, renderFn) {
|
|
23
23
|
await runWithRequestContext(createRequestContext({
|
|
24
24
|
headersContext: createStaticGenerationHeadersContext({
|
|
25
|
+
draftModeSecret: options.draftModeSecret,
|
|
25
26
|
dynamicConfig: options.dynamicConfig,
|
|
26
27
|
routeKind: "route",
|
|
27
28
|
routePattern: options.routePattern
|
|
@@ -92,6 +93,7 @@ async function dispatchAppRouteHandler(options) {
|
|
|
92
93
|
runInRevalidationContext(renderFn) {
|
|
93
94
|
return runInRouteHandlerRevalidationContext({
|
|
94
95
|
cleanPathname: options.cleanPathname,
|
|
96
|
+
draftModeSecret: options.draftModeSecret,
|
|
95
97
|
dynamicConfig: handler.dynamic,
|
|
96
98
|
routePattern: route.pattern,
|
|
97
99
|
routeSegments: route.routeSegments
|
|
@@ -117,6 +119,7 @@ async function dispatchAppRouteHandler(options) {
|
|
|
117
119
|
cleanPathname: options.cleanPathname,
|
|
118
120
|
clearRequestContext: options.clearRequestContext,
|
|
119
121
|
consumeDynamicUsage,
|
|
122
|
+
draftModeSecret: options.draftModeSecret,
|
|
120
123
|
executionContext: getRequestExecutionContext(),
|
|
121
124
|
getAndClearPendingCookies,
|
|
122
125
|
getCollectedFetchTags,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute, isValidHTTPMethod } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n expireSeconds?: number;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes, matching Next.js semantics. The dispatch\n * layer threads this through to the handler context unchanged so user code\n * (`params ? await params : null`) resolves to `null`.\n */\n params: AppRouteParams | null;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n // Reject non-standard HTTP methods before any auto-OPTIONS/405 logic.\n // Next.js returns 400 for invalid methods; vinext mirrors that behavior.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/app-route/module.ts#L390-L392\n if (!isValidHTTPMethod(method)) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 400 }),\n options.middlewareContext,\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: options.params === null ? null : makeThenableParams(options.params),\n reportRequestError(error, request, context) {\n void reportRequestError(error, request, context);\n },\n request: options.request,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute, isValidHTTPMethod } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { makeThenableParams } from \"vinext/shims/thenable-params\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n draftModeSecret: string;\n expireSeconds?: number;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes, matching Next.js semantics. The dispatch\n * layer threads this through to the handler context unchanged so user code\n * (`params ? await params : null`) resolves to `null`.\n */\n params: AppRouteParams | null;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n draftModeSecret: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n draftModeSecret: options.draftModeSecret,\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n // Reject non-standard HTTP methods before any auto-OPTIONS/405 logic.\n // Next.js returns 400 for invalid methods; vinext mirrors that behavior.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/app-route/module.ts#L390-L392\n if (!isValidHTTPMethod(method)) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 400 }),\n options.middlewareContext,\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n draftModeSecret: options.draftModeSecret,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n draftModeSecret: options.draftModeSecret,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: options.params === null ? null : makeThenableParams(options.params),\n reportRequestError(error, request, context) {\n void reportRequestError(error, request, context);\n },\n request: options.request,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
|
|
@@ -38,6 +38,7 @@ type AppRouteDebugLogger = (event: string, detail: string) => void;
|
|
|
38
38
|
type RunAppRouteHandlerOptions = {
|
|
39
39
|
basePath?: string;
|
|
40
40
|
consumeDynamicUsage: AppRouteDynamicUsageFn;
|
|
41
|
+
draftModeSecret?: string;
|
|
41
42
|
dynamicConfig?: string;
|
|
42
43
|
handlerFn: AppRouteHandlerFunction;
|
|
43
44
|
i18n?: NextI18nConfig | null;
|
|
@@ -7,6 +7,7 @@ import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader,
|
|
|
7
7
|
function configureAppRouteStaticGenerationContext(options) {
|
|
8
8
|
if (options.dynamicConfig === "force-static" || options.dynamicConfig === "error") {
|
|
9
9
|
setHeadersContext(createStaticGenerationHeadersContext({
|
|
10
|
+
draftModeSecret: options.draftModeSecret,
|
|
10
11
|
dynamicConfig: options.dynamicConfig,
|
|
11
12
|
routeKind: "route",
|
|
12
13
|
routePattern: options.routePattern
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\n/**\n * Route handler context.\n *\n * `params` is `null` for non-dynamic routes (no `[param]` segments) so that\n * user code like `params ? await params : null` resolves to `null`, matching\n * Next.js behavior. For dynamic routes it's a thenable that resolves to the\n * matched params object.\n *\n * See: test/e2e/app-dir/app-routes/app-custom-routes.test.ts in Next.js for\n * the authoritative assertion (`expect(meta.params).toEqual(null)`).\n */\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams | null },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes. Passed through to the handler context\n * unchanged — callers are expected to compute this from `route.isDynamic`.\n */\n params: AppRouteParams | null;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n expireSeconds?: number;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\n/**\n * Route handler context.\n *\n * `params` is `null` for non-dynamic routes (no `[param]` segments) so that\n * user code like `params ? await params : null` resolves to `null`, matching\n * Next.js behavior. For dynamic routes it's a thenable that resolves to the\n * matched params object.\n *\n * See: test/e2e/app-dir/app-routes/app-custom-routes.test.ts in Next.js for\n * the authoritative assertion (`expect(meta.params).toEqual(null)`).\n */\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams | null },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n draftModeSecret?: string;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n /**\n * `null` for non-dynamic routes. Passed through to the handler context\n * unchanged — callers are expected to compute this from `route.isDynamic`.\n */\n params: AppRouteParams | null;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n expireSeconds?: number;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n draftModeSecret: options.draftModeSecret,\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":"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"}
|