vinext 0.1.0 → 0.1.2
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 +2 -5
- package/dist/build/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/client-build-config.d.ts +33 -1
- package/dist/build/client-build-config.js +66 -1
- package/dist/check.js +4 -3
- package/dist/cli.js +2 -0
- package/dist/client/navigation-runtime.d.ts +11 -2
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/window-next.d.ts +6 -4
- package/dist/config/config-matchers.d.ts +31 -5
- package/dist/config/config-matchers.js +50 -3
- package/dist/config/next-config.d.ts +29 -3
- package/dist/config/next-config.js +32 -2
- package/dist/deploy.js +47 -304
- package/dist/entries/app-rsc-entry.d.ts +8 -2
- package/dist/entries/app-rsc-entry.js +61 -5
- package/dist/entries/app-rsc-manifest.js +20 -2
- package/dist/entries/pages-client-entry.js +1 -1
- package/dist/entries/pages-server-entry.js +16 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +233 -280
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +8 -4
- package/dist/plugins/optimize-imports.js +16 -12
- package/dist/plugins/postcss.js +18 -14
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +184 -0
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +35 -2
- package/dist/routing/app-route-graph.js +179 -8
- package/dist/routing/file-matcher.js +1 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +16 -1
- package/dist/server/api-handler.js +4 -0
- package/dist/server/app-browser-entry.js +155 -215
- package/dist/server/app-browser-error.d.ts +4 -1
- package/dist/server/app-browser-error.js +7 -1
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-interception-context.d.ts +2 -1
- package/dist/server/app-browser-interception-context.js +15 -2
- package/dist/server/app-browser-navigation-controller.d.ts +13 -2
- package/dist/server/app-browser-navigation-controller.js +83 -4
- package/dist/server/app-browser-popstate.d.ts +12 -3
- package/dist/server/app-browser-popstate.js +19 -4
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-state.d.ts +3 -0
- package/dist/server/app-browser-state.js +10 -10
- package/dist/server/app-browser-visible-commit.js +10 -8
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-history-state.d.ts +45 -1
- package/dist/server/app-history-state.js +109 -1
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +22 -1
- package/dist/server/app-page-boundary-render.d.ts +2 -1
- package/dist/server/app-page-boundary-render.js +45 -21
- package/dist/server/app-page-cache.js +9 -7
- package/dist/server/app-page-dispatch.d.ts +14 -0
- package/dist/server/app-page-dispatch.js +21 -6
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +58 -17
- package/dist/server/app-page-execution.d.ts +1 -1
- package/dist/server/app-page-execution.js +32 -17
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -16
- package/dist/server/app-page-request.d.ts +9 -6
- package/dist/server/app-page-request.js +14 -10
- package/dist/server/app-page-response.d.ts +2 -2
- package/dist/server/app-page-response.js +2 -2
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +10 -8
- package/dist/server/app-page-stream.d.ts +37 -7
- package/dist/server/app-page-stream.js +36 -6
- package/dist/server/app-pages-bridge.d.ts +16 -0
- package/dist/server/app-pages-bridge.js +23 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +2 -0
- 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-response.js +11 -10
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +15 -3
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +5 -4
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +20 -1
- package/dist/server/app-rsc-route-matching.js +29 -4
- package/dist/server/app-server-action-execution.d.ts +22 -1
- package/dist/server/app-server-action-execution.js +73 -12
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +19 -3
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +97 -43
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-cache.d.ts +37 -1
- package/dist/server/isr-cache.js +85 -1
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +62 -1
- package/dist/server/navigation-planner.js +193 -3
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +11 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +14 -3
- package/dist/server/pages-api-route.js +6 -1
- package/dist/server/pages-asset-tags.d.ts +15 -4
- package/dist/server/pages-asset-tags.js +18 -12
- package/dist/server/pages-data-route.js +5 -1
- package/dist/server/pages-node-compat.d.ts +5 -11
- package/dist/server/pages-node-compat.js +175 -118
- package/dist/server/pages-page-data.d.ts +38 -7
- package/dist/server/pages-page-data.js +64 -18
- package/dist/server/pages-page-handler.d.ts +10 -2
- package/dist/server/pages-page-handler.js +49 -20
- package/dist/server/pages-page-response.d.ts +55 -2
- package/dist/server/pages-page-response.js +74 -6
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +113 -0
- package/dist/server/pages-request-pipeline.js +230 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/prod-server.d.ts +45 -3
- package/dist/server/prod-server.js +182 -234
- package/dist/server/socket-error-backstop.d.ts +19 -1
- package/dist/server/socket-error-backstop.js +77 -4
- package/dist/shims/app-router-scroll.js +22 -4
- package/dist/shims/cache-runtime.js +39 -2
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +77 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +17 -7
- package/dist/shims/error-boundary.js +8 -1
- package/dist/shims/error.js +37 -11
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +28 -1
- package/dist/shims/hash-scroll.d.ts +1 -0
- package/dist/shims/hash-scroll.js +3 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +37 -1
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +10 -6
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/utils.d.ts +1 -0
- package/dist/shims/link.js +20 -6
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +9 -18
- package/dist/shims/navigation.js +96 -23
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +2 -0
- package/dist/shims/router.d.ts +6 -3
- package/dist/shims/router.js +156 -22
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +17 -1
- package/dist/shims/server.js +31 -6
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/client-build-manifest.d.ts +8 -1
- package/dist/utils/client-build-manifest.js +41 -6
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +5 -1
- package/package.json +6 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
|
|
2
2
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
3
3
|
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
4
|
+
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
5
|
+
import { decideIsr } from "./isr-decision.js";
|
|
4
6
|
import { buildAppPageCacheValue } from "./isr-cache.js";
|
|
5
7
|
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
6
8
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
7
|
-
import { applyCdnResponseHeaders, buildCachedRevalidateCacheControl } from "./cache-control.js";
|
|
8
9
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
9
10
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
10
11
|
import { hasCompleteNegativeRequestApiProof } from "./cache-proof.js";
|
|
@@ -52,9 +53,6 @@ function buildAppPageCacheTags(pathname, extraTags) {
|
|
|
52
53
|
for (const tag of extraTags) if (!tags.includes(tag)) tags.push(tag);
|
|
53
54
|
return tags.map(encodeCacheTag);
|
|
54
55
|
}
|
|
55
|
-
function buildAppPageCacheControl(cacheState, revalidateSeconds, expireSeconds) {
|
|
56
|
-
return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);
|
|
57
|
-
}
|
|
58
56
|
function buildAppPageCachedHeaders(options) {
|
|
59
57
|
const headers = new Headers({
|
|
60
58
|
"Content-Type": options.contentType,
|
|
@@ -87,9 +85,13 @@ function resolveAppPageCacheWritePolicy(options) {
|
|
|
87
85
|
}
|
|
88
86
|
function buildAppPageCachedResponse(cachedValue, options) {
|
|
89
87
|
const status = options.middlewareStatus ?? (cachedValue.status || 200);
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
const { cacheControl } = decideIsr({
|
|
89
|
+
cacheState: options.cacheState,
|
|
90
|
+
kind: "app-page",
|
|
91
|
+
revalidateSeconds: options.revalidateSeconds,
|
|
92
|
+
expireSeconds: options.expireSeconds,
|
|
93
|
+
cacheControlMeta: options.cacheControl
|
|
94
|
+
});
|
|
93
95
|
if (options.isRscRequest) {
|
|
94
96
|
if (!cachedValue.rscData) return null;
|
|
95
97
|
const rscHeaders = buildAppPageCachedHeaders({
|
|
@@ -51,6 +51,12 @@ type AppPageModule = {
|
|
|
51
51
|
dynamic?: unknown;
|
|
52
52
|
revalidate?: unknown;
|
|
53
53
|
};
|
|
54
|
+
type AppPageDispatchSlot = {
|
|
55
|
+
default?: AppPageModule | null;
|
|
56
|
+
page?: AppPageModule | null;
|
|
57
|
+
slotPatternParts?: readonly string[] | null;
|
|
58
|
+
slotParamNames?: readonly string[] | null;
|
|
59
|
+
};
|
|
54
60
|
type AppPageDispatchRoute = {
|
|
55
61
|
__buildTimeClassifications?: LayoutClassificationOptions["buildTimeClassifications"];
|
|
56
62
|
__buildTimeReasons?: LayoutClassificationOptions["buildTimeReasons"];
|
|
@@ -67,6 +73,7 @@ type AppPageDispatchRoute = {
|
|
|
67
73
|
params: readonly string[];
|
|
68
74
|
pattern: string;
|
|
69
75
|
routeSegments: readonly string[];
|
|
76
|
+
slots?: Readonly<Record<string, AppPageDispatchSlot>>;
|
|
70
77
|
unauthorized?: AppPageModule | null;
|
|
71
78
|
unauthorizeds?: readonly (AppPageModule | null | undefined)[];
|
|
72
79
|
};
|
|
@@ -78,9 +85,16 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
78
85
|
* SSR head. Undefined or empty disables emission entirely.
|
|
79
86
|
*/
|
|
80
87
|
clientTraceMetadata?: readonly string[];
|
|
88
|
+
/**
|
|
89
|
+
* Maximum total length (in characters) of the preload `Link` header emitted
|
|
90
|
+
* during SSR. `0` disables emission. From `reactMaxHeadersLength` in
|
|
91
|
+
* `next.config`. Undefined falls back to the React default downstream.
|
|
92
|
+
*/
|
|
93
|
+
reactMaxHeadersLength?: number;
|
|
81
94
|
buildPageElement: (route: TRoute, params: AppPageParams, opts: AppPageDispatchInterceptOptions | undefined, searchParams: URLSearchParams, layoutParamAccess?: AppLayoutParamAccessTracker) => Promise<AppPageElement>;
|
|
82
95
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
83
96
|
cleanPathname: string;
|
|
97
|
+
displayPathname?: string;
|
|
84
98
|
clearRequestContext: () => void;
|
|
85
99
|
createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;
|
|
86
100
|
debugClassification?: (layoutId: string, reason: ClassificationReason) => void;
|
|
@@ -18,9 +18,10 @@ import { resolveAppPageParentHttpAccessBoundary, resolveAppPageParentHttpAccessB
|
|
|
18
18
|
import { isAppSsrRenderResult } from "./app-page-stream.js";
|
|
19
19
|
import { createAppLayoutParamAccessTracker, isAppLayoutObservationUnsafeForStaticReuse } from "./app-layout-param-observation.js";
|
|
20
20
|
import { resolveAppPageMethodResponse } from "./app-page-method.js";
|
|
21
|
+
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
22
|
+
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
21
23
|
import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
|
|
22
24
|
import { renderAppPageLifecycle } from "./app-page-render.js";
|
|
23
|
-
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
24
25
|
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
25
26
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
26
27
|
import React from "react";
|
|
@@ -124,7 +125,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
124
125
|
ensureFetchPatch();
|
|
125
126
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
|
|
126
127
|
options.setNavigationContext({
|
|
127
|
-
pathname: options.cleanPathname,
|
|
128
|
+
pathname: options.displayPathname ?? options.cleanPathname,
|
|
128
129
|
searchParams: new URLSearchParams(),
|
|
129
130
|
params: options.params
|
|
130
131
|
});
|
|
@@ -183,10 +184,11 @@ async function dispatchAppPageInner(options) {
|
|
|
183
184
|
routeKind: "page",
|
|
184
185
|
routePattern: route.pattern
|
|
185
186
|
}));
|
|
187
|
+
const staticNavigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, null);
|
|
186
188
|
options.setNavigationContext({
|
|
187
|
-
pathname: options.cleanPathname,
|
|
189
|
+
pathname: options.displayPathname ?? options.cleanPathname,
|
|
188
190
|
searchParams: new URLSearchParams(),
|
|
189
|
-
params:
|
|
191
|
+
params: staticNavigationParams
|
|
190
192
|
});
|
|
191
193
|
}
|
|
192
194
|
if (shouldReadAppPageCache({
|
|
@@ -217,7 +219,7 @@ async function dispatchAppPageInner(options) {
|
|
|
217
219
|
expireSeconds: options.expireSeconds,
|
|
218
220
|
revalidateSeconds: currentRevalidateSeconds ?? 0,
|
|
219
221
|
renderFreshPageForCache: async () => {
|
|
220
|
-
const revalidationTarget = resolveAppPageInterceptionRerenderTarget({
|
|
222
|
+
const revalidationTarget = await resolveAppPageInterceptionRerenderTarget({
|
|
221
223
|
cleanPathname: options.cleanPathname,
|
|
222
224
|
currentParams: options.params,
|
|
223
225
|
currentRoute: route,
|
|
@@ -233,9 +235,11 @@ async function dispatchAppPageInner(options) {
|
|
|
233
235
|
return toInterceptOptions(options.interceptionContext, intercept);
|
|
234
236
|
}
|
|
235
237
|
});
|
|
238
|
+
revalidationTarget.navigationParams = resolveAppPageNavigationParams(revalidationTarget.route, revalidationTarget.navigationParams, options.cleanPathname, revalidationTarget.interceptOpts);
|
|
236
239
|
await options.ensureRouteLoaded?.(revalidationTarget.route);
|
|
237
240
|
return runAppPageRevalidationContext({
|
|
238
241
|
cleanPathname: options.cleanPathname,
|
|
242
|
+
displayPathname: options.displayPathname,
|
|
239
243
|
currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
|
|
240
244
|
draftModeSecret: options.draftModeSecret,
|
|
241
245
|
dynamicConfig,
|
|
@@ -256,6 +260,7 @@ async function dispatchAppPageInner(options) {
|
|
|
256
260
|
}, {
|
|
257
261
|
basePath: options.basePath,
|
|
258
262
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
263
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
259
264
|
rootParams: options.rootParams,
|
|
260
265
|
waitForAllReady: true,
|
|
261
266
|
...revalidatedRscCapture.sideStream ? {
|
|
@@ -351,6 +356,9 @@ async function dispatchAppPageInner(options) {
|
|
|
351
356
|
},
|
|
352
357
|
isRscRequest: options.isRscRequest,
|
|
353
358
|
layoutParamAccess,
|
|
359
|
+
resolveNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts) {
|
|
360
|
+
return resolveAppPageNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts);
|
|
361
|
+
},
|
|
354
362
|
renderInterceptResponse(sourceRoute, interceptElement) {
|
|
355
363
|
const interceptOnError = options.createRscOnErrorHandler(options.cleanPathname, sourceRoute.pattern);
|
|
356
364
|
const interceptStream = options.renderToReadableStream(interceptElement, { onError: interceptOnError });
|
|
@@ -386,10 +394,17 @@ async function dispatchAppPageInner(options) {
|
|
|
386
394
|
resolveSpecialError: resolveAppPageSpecialError
|
|
387
395
|
});
|
|
388
396
|
if (pageBuildResult.response) return pageBuildResult.response;
|
|
397
|
+
const navigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, interceptResult.interceptOpts);
|
|
398
|
+
options.setNavigationContext({
|
|
399
|
+
pathname: options.displayPathname ?? options.cleanPathname,
|
|
400
|
+
searchParams: options.searchParams,
|
|
401
|
+
params: navigationParams
|
|
402
|
+
});
|
|
389
403
|
const layoutClassifications = getEffectiveLayoutClassifications(route, options.debugClassification);
|
|
390
404
|
return renderAppPageLifecycle({
|
|
391
405
|
basePath: options.basePath,
|
|
392
406
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
407
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
393
408
|
cleanPathname: options.cleanPathname,
|
|
394
409
|
clearRequestContext: options.clearRequestContext,
|
|
395
410
|
consumeDynamicUsage,
|
|
@@ -440,6 +455,7 @@ async function dispatchAppPageInner(options) {
|
|
|
440
455
|
layoutCount: route.layouts.length,
|
|
441
456
|
loadSsrHandler: options.loadSsrHandler,
|
|
442
457
|
middlewareContext: options.middlewareContext,
|
|
458
|
+
navigationParams,
|
|
443
459
|
params: options.params,
|
|
444
460
|
layoutParamAccess,
|
|
445
461
|
rootParams: options.rootParams,
|
|
@@ -493,7 +509,6 @@ async function dispatchAppPageInner(options) {
|
|
|
493
509
|
return renderPageSpecialError(options, specialError);
|
|
494
510
|
},
|
|
495
511
|
renderToReadableStream: options.renderToReadableStream,
|
|
496
|
-
routeHasLocalBoundary: Boolean(route.error?.default || route.errors?.some((errorModule) => errorModule?.default)),
|
|
497
512
|
routePattern: route.pattern,
|
|
498
513
|
runWithSuppressedHookWarning(probe) {
|
|
499
514
|
return options.runWithSuppressedHookWarning(probe);
|
|
@@ -37,6 +37,7 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
|
|
|
37
37
|
route: AppPageBuildRoute<TModule, TErrorModule>;
|
|
38
38
|
params: AppPageParams;
|
|
39
39
|
routePath: string;
|
|
40
|
+
displayPathname?: string;
|
|
40
41
|
pageRequest: AppPagePageRequest<TModule>; /** Root-level global-error.tsx module. Present when the app defines this file. */
|
|
41
42
|
globalErrorModule?: TErrorModule | null; /** Root-level not-found.tsx module. Present when the app defines this file. */
|
|
42
43
|
rootNotFoundModule?: TModule | null; /** Root-level forbidden.tsx module. Present when the app defines this file. */
|
|
@@ -48,9 +49,28 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
|
|
|
48
49
|
* Configured next.config `basePath`. Threaded through `resolveAppPageHead`
|
|
49
50
|
* so file-based metadata route URLs emitted in <head> are prefixed.
|
|
50
51
|
*/
|
|
51
|
-
basePath?: string; /**
|
|
52
|
+
basePath?: string; /** Configured next.config `trailingSlash`, threaded into canonical URL rendering. */
|
|
53
|
+
trailingSlash?: boolean; /** Serialized next.config `htmlLimitedBots` regexp source. */
|
|
52
54
|
htmlLimitedBots?: string;
|
|
53
55
|
};
|
|
56
|
+
type AppPageNavigationParamModule = {
|
|
57
|
+
default?: unknown;
|
|
58
|
+
};
|
|
59
|
+
type AppPageNavigationParamSlot = {
|
|
60
|
+
default?: AppPageNavigationParamModule | null;
|
|
61
|
+
page?: AppPageNavigationParamModule | null;
|
|
62
|
+
slotPatternParts?: readonly string[] | null;
|
|
63
|
+
slotParamNames?: readonly string[] | null;
|
|
64
|
+
};
|
|
65
|
+
type AppPageNavigationParamRoute = {
|
|
66
|
+
params?: readonly string[] | null;
|
|
67
|
+
slots?: Readonly<Record<string, AppPageNavigationParamSlot>> | null;
|
|
68
|
+
};
|
|
69
|
+
type AppPageNavigationParamInterceptOptions = {
|
|
70
|
+
interceptPage?: unknown;
|
|
71
|
+
interceptParams?: AppPageParams | null;
|
|
72
|
+
interceptSlotKey?: string | null;
|
|
73
|
+
};
|
|
54
74
|
/**
|
|
55
75
|
* Build the App Router element tree for a matched route.
|
|
56
76
|
*
|
|
@@ -68,5 +88,6 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
|
|
|
68
88
|
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
69
89
|
*/
|
|
70
90
|
declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
|
|
91
|
+
declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
|
|
71
92
|
//#endregion
|
|
72
|
-
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements };
|
|
93
|
+
export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams };
|
|
@@ -8,6 +8,7 @@ import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-
|
|
|
8
8
|
import { makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
|
|
9
9
|
import { buildAppPageElements, createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
10
10
|
import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
|
|
11
|
+
import "./app-rsc-route-matching.js";
|
|
11
12
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
12
13
|
import { createElement } from "react";
|
|
13
14
|
//#region src/server/app-page-element-builder.ts
|
|
@@ -28,18 +29,21 @@ import { createElement } from "react";
|
|
|
28
29
|
* {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
|
|
29
30
|
*/
|
|
30
31
|
async function buildPageElements(options) {
|
|
31
|
-
const { route, params, routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
32
|
+
const { route, params, routePath, displayPathname = routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
|
|
32
33
|
const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION } = pageRequest;
|
|
33
34
|
const pageModule = route.page;
|
|
34
|
-
const
|
|
35
|
+
const isSiblingIntercept = opts?.interceptSlotKey === "__vinext_page_intercept" && !!opts?.interceptPage;
|
|
36
|
+
const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
|
|
37
|
+
const EffectivePageComponent = effectivePageModule?.default;
|
|
38
|
+
const effectiveParams = isSiblingIntercept ? opts.interceptParams ?? params : params;
|
|
35
39
|
const hasPageModule = !!pageModule;
|
|
36
40
|
const renderIdentity = createAppPageRenderIdentity({
|
|
37
|
-
displayPathname
|
|
41
|
+
displayPathname,
|
|
38
42
|
interceptionContext: opts?.interceptionContext ?? null,
|
|
39
43
|
interceptSourceMatchedUrl: opts?.interceptSourceMatchedUrl ?? null,
|
|
40
|
-
interceptSlotId: opts?.interceptSlotId ?? null
|
|
44
|
+
interceptSlotId: isSiblingIntercept ? null : opts?.interceptSlotId ?? null
|
|
41
45
|
});
|
|
42
|
-
if (hasPageModule && !
|
|
46
|
+
if ((hasPageModule || isSiblingIntercept) && !EffectivePageComponent) {
|
|
43
47
|
let noExportRootLayout = null;
|
|
44
48
|
const noExportLayoutIds = route.ids?.layouts ?? route.layouts.map((_, index) => AppElementsWire.encodeLayoutId(createAppPageTreePath(route.routeSegments, route.layoutTreePositions?.[index] ?? 0)));
|
|
45
49
|
if (route.layouts?.length > 0) {
|
|
@@ -62,7 +66,7 @@ async function buildPageElements(options) {
|
|
|
62
66
|
layoutModules: route.layouts,
|
|
63
67
|
layoutTreePositions: route.layoutTreePositions,
|
|
64
68
|
metadataRoutes,
|
|
65
|
-
pageModule:
|
|
69
|
+
pageModule: effectivePageModule ?? null,
|
|
66
70
|
parallelRoutes: resolveActiveParallelRouteHeadInputs({
|
|
67
71
|
interceptLayouts: opts?.interceptLayouts ?? null,
|
|
68
72
|
interceptPage: opts?.interceptPage ?? null,
|
|
@@ -72,12 +76,12 @@ async function buildPageElements(options) {
|
|
|
72
76
|
routeSegments: route.routeSegments ?? [],
|
|
73
77
|
slots: route.slots ?? null
|
|
74
78
|
}),
|
|
75
|
-
params,
|
|
79
|
+
params: effectiveParams,
|
|
76
80
|
routePath: route.pattern,
|
|
77
81
|
routeSegments: route.routeSegments ?? null,
|
|
78
82
|
searchParams
|
|
79
83
|
});
|
|
80
|
-
const pageProps = { params: makeThenableParams(
|
|
84
|
+
const pageProps = { params: makeThenableParams(effectiveParams) };
|
|
81
85
|
let pageSearchParamsThenable;
|
|
82
86
|
if (searchParams) {
|
|
83
87
|
pageSearchParamsThenable = !shouldSuppressLoadingBoundaries(renderMode) && Boolean(route.loading?.default) ? makeObservedAppPageSearchParamsThenable(pageSearchParams) : makeThenableParams(pageSearchParams);
|
|
@@ -86,8 +90,16 @@ async function buildPageElements(options) {
|
|
|
86
90
|
const mountedSlotIds = mountedSlotsHeader ? new Set(mountedSlotsHeader.split(" ")) : null;
|
|
87
91
|
const slotOverrides = buildSlotOverrides(route, params, routePath, opts);
|
|
88
92
|
const metadataPlacement = hasDynamicMetadata && shouldServeStreamingMetadata(pageRequest.request.headers.get("user-agent") ?? "", options.htmlLimitedBots) ? "body" : "head";
|
|
93
|
+
let siblingInterceptElement = isSiblingIntercept && EffectivePageComponent ? createElement(EffectivePageComponent, pageProps) : null;
|
|
94
|
+
if (isSiblingIntercept && siblingInterceptElement !== null && opts?.interceptLayouts?.length) {
|
|
95
|
+
const siblingThenableParams = makeThenableParams(effectiveParams);
|
|
96
|
+
for (let i = opts.interceptLayouts.length - 1; i >= 0; i--) {
|
|
97
|
+
const LayoutComponent = opts.interceptLayouts[i]?.default;
|
|
98
|
+
if (LayoutComponent) siblingInterceptElement = createElement(LayoutComponent, { params: siblingThenableParams }, siblingInterceptElement);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
return buildAppPageElements({
|
|
90
|
-
element:
|
|
102
|
+
element: isSiblingIntercept ? siblingInterceptElement : EffectivePageComponent ? createElement(EffectivePageComponent, pageProps) : null,
|
|
91
103
|
globalErrorModule: globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE,
|
|
92
104
|
isRscRequest,
|
|
93
105
|
layoutParamAccess: options.layoutParamAccess,
|
|
@@ -106,7 +118,8 @@ async function buildPageElements(options) {
|
|
|
106
118
|
route,
|
|
107
119
|
searchParams: pageSearchParamsThenable,
|
|
108
120
|
slotOverrides,
|
|
109
|
-
renderMode
|
|
121
|
+
renderMode,
|
|
122
|
+
trailingSlash: options.trailingSlash
|
|
110
123
|
});
|
|
111
124
|
}
|
|
112
125
|
/**
|
|
@@ -125,11 +138,23 @@ async function buildPageElements(options) {
|
|
|
125
138
|
*/
|
|
126
139
|
function buildSlotOverrides(route, routeParams, routePath, opts) {
|
|
127
140
|
const overrides = {};
|
|
128
|
-
if (opts && opts.interceptSlotKey && opts.interceptPage) overrides[opts.interceptSlotKey] = {
|
|
141
|
+
if (opts && opts.interceptSlotKey && opts.interceptPage && opts.interceptSlotKey !== "__vinext_page_intercept") overrides[opts.interceptSlotKey] = {
|
|
129
142
|
layoutModules: opts.interceptLayouts || null,
|
|
130
143
|
pageModule: opts.interceptPage,
|
|
131
144
|
params: opts.interceptParams || routeParams
|
|
132
145
|
};
|
|
146
|
+
const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
|
|
147
|
+
for (const [slotKey, params] of Object.entries(slotParamOverrides ?? {})) {
|
|
148
|
+
const existing = overrides[slotKey];
|
|
149
|
+
overrides[slotKey] = existing ? {
|
|
150
|
+
...existing,
|
|
151
|
+
params
|
|
152
|
+
} : { params };
|
|
153
|
+
}
|
|
154
|
+
return Object.keys(overrides).length > 0 ? overrides : null;
|
|
155
|
+
}
|
|
156
|
+
function resolveSlotParamOverrides(route, routePath) {
|
|
157
|
+
const overrides = {};
|
|
133
158
|
const slots = route.slots;
|
|
134
159
|
if (slots) {
|
|
135
160
|
let urlParts = null;
|
|
@@ -142,19 +167,35 @@ function buildSlotOverrides(route, routeParams, routePath, opts) {
|
|
|
142
167
|
if (urlParts === null) urlParts = routePath.split("/").filter(Boolean);
|
|
143
168
|
const matched = matchRoutePattern(urlParts, patternParts);
|
|
144
169
|
if (!matched) continue;
|
|
145
|
-
|
|
146
|
-
overrides[slotKey] = existing ? {
|
|
147
|
-
...existing,
|
|
148
|
-
params: matched
|
|
149
|
-
} : { params: matched };
|
|
170
|
+
overrides[slotKey] = matched;
|
|
150
171
|
}
|
|
151
172
|
}
|
|
152
173
|
return Object.keys(overrides).length > 0 ? overrides : null;
|
|
153
174
|
}
|
|
175
|
+
function mergeAppPageParams(target, source) {
|
|
176
|
+
for (const [key, value] of Object.entries(source)) target[key] = value;
|
|
177
|
+
}
|
|
178
|
+
function isDefaultExportModule(module) {
|
|
179
|
+
return typeof module === "object" && module !== null;
|
|
180
|
+
}
|
|
181
|
+
function hasDefaultExport(module) {
|
|
182
|
+
if (!isDefaultExportModule(module)) return false;
|
|
183
|
+
return module?.default !== null && module?.default !== void 0;
|
|
184
|
+
}
|
|
185
|
+
function resolveAppPageNavigationParams(route, routeParams, routePath, opts) {
|
|
186
|
+
const navigationParams = { ...routeParams };
|
|
187
|
+
const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
|
|
188
|
+
for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
|
|
189
|
+
const isInterceptedSlot = opts?.interceptSlotKey === slotKey && opts.interceptSlotKey !== "__vinext_page_intercept" && hasDefaultExport(opts.interceptPage);
|
|
190
|
+
if (!isInterceptedSlot && !hasDefaultExport(slot.page) && !hasDefaultExport(slot.default)) continue;
|
|
191
|
+
mergeAppPageParams(navigationParams, isInterceptedSlot ? opts?.interceptParams ?? routeParams : slotParamOverrides?.[slotKey] ?? routeParams);
|
|
192
|
+
}
|
|
193
|
+
return navigationParams;
|
|
194
|
+
}
|
|
154
195
|
function collectParamNameSet(params) {
|
|
155
196
|
const set = /* @__PURE__ */ new Set();
|
|
156
197
|
if (params) for (const name of params) set.add(name);
|
|
157
198
|
return set;
|
|
158
199
|
}
|
|
159
200
|
//#endregion
|
|
160
|
-
export { buildPageElements };
|
|
201
|
+
export { buildPageElements, resolveAppPageNavigationParams };
|
|
@@ -103,7 +103,7 @@ type LayoutClassificationOptions = {
|
|
|
103
103
|
* unsafe even if the older dynamic scope did not report dynamic usage.
|
|
104
104
|
*/
|
|
105
105
|
isLayoutObservationDynamic?: (layoutId: string) => boolean; /** Runs a function with isolated dynamic usage tracking per layout. */
|
|
106
|
-
runWithIsolatedDynamicScope: <T>(fn: () => T) => Promise<{
|
|
106
|
+
runWithIsolatedDynamicScope: <T>(fn: () => T | Promise<T>) => Promise<{
|
|
107
107
|
result: T;
|
|
108
108
|
dynamicDetected: boolean;
|
|
109
109
|
}>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { addBasePathToPathname } from "../utils/base-path.js";
|
|
2
2
|
import { VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
|
|
3
|
+
import { runWithConnectionProbe } from "../shims/headers.js";
|
|
3
4
|
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
|
|
4
5
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
5
6
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
@@ -180,10 +181,15 @@ async function buildAppPageSpecialErrorResponse(options) {
|
|
|
180
181
|
}
|
|
181
182
|
if (options.renderFallbackPage) {
|
|
182
183
|
const fallbackResponse = await options.renderFallbackPage(options.specialError.statusCode);
|
|
183
|
-
if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(fallbackResponse,
|
|
184
|
+
if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? new Response(fallbackResponse.body, {
|
|
185
|
+
headers: fallbackResponse.headers,
|
|
186
|
+
status: 200,
|
|
187
|
+
statusText: fallbackResponse.statusText
|
|
188
|
+
}) : fallbackResponse, options.middlewareContext);
|
|
184
189
|
}
|
|
185
190
|
options.clearRequestContext();
|
|
186
|
-
|
|
191
|
+
const responseStatus = options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? 200 : options.specialError.statusCode;
|
|
192
|
+
return mergeAppPageSpecialErrorHeaders(new Response(getAppPageStatusText(options.specialError.statusCode), { status: responseStatus }), options.middlewareContext);
|
|
187
193
|
}
|
|
188
194
|
/** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */
|
|
189
195
|
async function probeAppPageLayouts(options) {
|
|
@@ -210,7 +216,10 @@ async function probeAppPageLayouts(options) {
|
|
|
210
216
|
if (cls) {
|
|
211
217
|
const layoutId = cls.getLayoutId(layoutIndex);
|
|
212
218
|
try {
|
|
213
|
-
const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(() =>
|
|
219
|
+
const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(async () => {
|
|
220
|
+
const outcome = await runWithConnectionProbe(() => options.probeLayoutAt(layoutIndex));
|
|
221
|
+
return outcome.completed ? outcome.result : null;
|
|
222
|
+
});
|
|
214
223
|
const observationDynamic = cls.isLayoutObservationDynamic?.(layoutId) === true;
|
|
215
224
|
const layoutDynamic = dynamicDetected || observationDynamic;
|
|
216
225
|
layoutFlags[layoutId] = layoutDynamic ? "d" : "s";
|
|
@@ -239,25 +248,31 @@ async function probeAppPageLayouts(options) {
|
|
|
239
248
|
};
|
|
240
249
|
}
|
|
241
250
|
async function probeLayoutForErrors(options, layoutIndex) {
|
|
242
|
-
|
|
243
|
-
const layoutResult = options.probeLayoutAt(layoutIndex);
|
|
244
|
-
if (isPromiseLike(layoutResult)) await layoutResult;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
return options.onLayoutError(error, layoutIndex);
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
async function probeAppPageComponent(options) {
|
|
251
|
-
return options.runWithSuppressedHookWarning(async () => {
|
|
251
|
+
const outcome = await runWithConnectionProbe(async () => {
|
|
252
252
|
try {
|
|
253
|
-
const
|
|
254
|
-
if (isPromiseLike(
|
|
255
|
-
else Promise.resolve(pageResult).catch(() => {});
|
|
253
|
+
const layoutResult = options.probeLayoutAt(layoutIndex);
|
|
254
|
+
if (isPromiseLike(layoutResult)) await layoutResult;
|
|
256
255
|
} catch (error) {
|
|
257
|
-
return options.
|
|
256
|
+
return options.onLayoutError(error, layoutIndex);
|
|
258
257
|
}
|
|
259
258
|
return null;
|
|
260
259
|
});
|
|
260
|
+
return outcome.completed ? outcome.result : null;
|
|
261
|
+
}
|
|
262
|
+
async function probeAppPageComponent(options) {
|
|
263
|
+
return options.runWithSuppressedHookWarning(async () => {
|
|
264
|
+
const outcome = await runWithConnectionProbe(async () => {
|
|
265
|
+
try {
|
|
266
|
+
const pageResult = options.probePage();
|
|
267
|
+
if (isPromiseLike(pageResult)) if (options.awaitAsyncResult) await pageResult;
|
|
268
|
+
else Promise.resolve(pageResult).catch(() => {});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
return options.onError(error);
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
});
|
|
274
|
+
return outcome.completed ? outcome.result : null;
|
|
275
|
+
});
|
|
261
276
|
}
|
|
262
277
|
async function readAppPageBinaryStream(stream) {
|
|
263
278
|
const reader = stream.getReader();
|
|
@@ -28,6 +28,12 @@ type RenderAppPageLifecycleOptions = {
|
|
|
28
28
|
* Undefined or empty disables emission.
|
|
29
29
|
*/
|
|
30
30
|
clientTraceMetadata?: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Maximum total length (in characters) of the preload `Link` header emitted
|
|
33
|
+
* during SSR. `0` disables emission. From `reactMaxHeadersLength` in
|
|
34
|
+
* `next.config`.
|
|
35
|
+
*/
|
|
36
|
+
reactMaxHeadersLength?: number;
|
|
31
37
|
cleanPathname: string;
|
|
32
38
|
clearRequestContext: () => void;
|
|
33
39
|
consumeDynamicUsage: () => boolean;
|
|
@@ -62,6 +68,7 @@ type RenderAppPageLifecycleOptions = {
|
|
|
62
68
|
layoutCount: number;
|
|
63
69
|
loadSsrHandler: () => Promise<AppPageSsrHandler>;
|
|
64
70
|
middlewareContext: AppPageMiddlewareContext;
|
|
71
|
+
navigationParams: Record<string, unknown>;
|
|
65
72
|
params: Record<string, unknown>;
|
|
66
73
|
rootParams?: RootParams;
|
|
67
74
|
peekRenderObservationState?: () => AppPageRenderObservationState;
|
|
@@ -76,7 +83,6 @@ type RenderAppPageLifecycleOptions = {
|
|
|
76
83
|
renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
|
|
77
84
|
onError: AppPageBoundaryOnError;
|
|
78
85
|
}) => ReadableStream<Uint8Array>;
|
|
79
|
-
routeHasLocalBoundary: boolean;
|
|
80
86
|
routePattern: string;
|
|
81
87
|
runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
|
|
82
88
|
scriptNonce?: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { NO_STORE_CACHE_CONTROL } from "./cache-control.js";
|
|
1
2
|
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
2
3
|
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
3
4
|
import "./app-elements.js";
|
|
4
5
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
5
|
-
import { NO_STORE_CACHE_CONTROL } from "./cache-control.js";
|
|
6
6
|
import { buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy } from "./app-page-response.js";
|
|
7
7
|
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
8
8
|
import { probeAppPageBeforeRender } from "./app-page-probe.js";
|
|
@@ -10,7 +10,7 @@ import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRe
|
|
|
10
10
|
import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
|
|
11
11
|
import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache.js";
|
|
12
12
|
import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
|
|
13
|
-
import { createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery
|
|
13
|
+
import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
|
|
14
14
|
import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
|
|
15
15
|
import { hasDigest } from "./app-rsc-errors.js";
|
|
16
16
|
import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
|
|
@@ -293,7 +293,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
293
293
|
cleanPathname: options.cleanPathname,
|
|
294
294
|
completeness: "partial",
|
|
295
295
|
output: rscOutputScope,
|
|
296
|
-
params: options.
|
|
296
|
+
params: options.navigationParams,
|
|
297
297
|
state: options.peekRenderObservationState?.() ?? createEmptyAppPageRenderObservationState()
|
|
298
298
|
});
|
|
299
299
|
const skipDisposition = options.skipDisposition ?? createRenderLifecycleSkipDisposition({
|
|
@@ -349,7 +349,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
349
349
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
350
350
|
middlewareContext: options.middlewareContext,
|
|
351
351
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
352
|
-
params: options.
|
|
352
|
+
params: options.navigationParams,
|
|
353
353
|
policy: rscResponsePolicy,
|
|
354
354
|
timing: buildResponseTiming({
|
|
355
355
|
compileEnd,
|
|
@@ -371,7 +371,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
371
371
|
cleanPathname: options.cleanPathname,
|
|
372
372
|
completeness: "complete",
|
|
373
373
|
output: rscOutputScope,
|
|
374
|
-
params: options.
|
|
374
|
+
params: options.navigationParams,
|
|
375
375
|
state: input.state
|
|
376
376
|
});
|
|
377
377
|
},
|
|
@@ -418,6 +418,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
418
418
|
navigationContext: options.getNavigationContext(),
|
|
419
419
|
basePath: options.basePath,
|
|
420
420
|
clientTraceMetadata: options.clientTraceMetadata,
|
|
421
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
421
422
|
rootParams: options.rootParams,
|
|
422
423
|
formState: options.formState ?? null,
|
|
423
424
|
rscStream: rscForResponse,
|
|
@@ -435,6 +436,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
435
436
|
if (htmlRender.response) return htmlRender.response;
|
|
436
437
|
let htmlStream = htmlRender.htmlStream;
|
|
437
438
|
if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
|
|
439
|
+
const linkHeader = buildAppPageLinkHeader(htmlRender.linkHeader, fontLinkHeader, options.reactMaxHeadersLength);
|
|
438
440
|
if (options.isPrerender === true) await htmlRender.metadataReady;
|
|
439
441
|
if (options.hasLoadingBoundary) {
|
|
440
442
|
const captured = rscErrorTracker.getCapturedSpecialError();
|
|
@@ -446,13 +448,6 @@ async function renderAppPageLifecycle(options) {
|
|
|
446
448
|
}
|
|
447
449
|
}
|
|
448
450
|
}
|
|
449
|
-
if (shouldRerenderAppPageWithGlobalError({
|
|
450
|
-
capturedError: rscErrorTracker.getCapturedError(),
|
|
451
|
-
hasLocalBoundary: options.routeHasLocalBoundary
|
|
452
|
-
})) {
|
|
453
|
-
const cleanResponse = await options.renderErrorBoundaryResponse(rscErrorTracker.getCapturedError());
|
|
454
|
-
if (cleanResponse) return cleanResponse;
|
|
455
|
-
}
|
|
456
451
|
if (options.isPrerender === true) {
|
|
457
452
|
await settleCapturedRscRenderForCacheMetadata(htmlRender.capturedRscData);
|
|
458
453
|
({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
|
|
@@ -491,7 +486,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
491
486
|
if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
|
|
492
487
|
const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
493
488
|
draftCookie,
|
|
494
|
-
|
|
489
|
+
linkHeader,
|
|
495
490
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
496
491
|
middlewareContext: options.middlewareContext,
|
|
497
492
|
policy: htmlResponsePolicy,
|
|
@@ -514,7 +509,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
514
509
|
cleanPathname: options.cleanPathname,
|
|
515
510
|
completeness: "complete",
|
|
516
511
|
output: htmlOutputScope,
|
|
517
|
-
params: options.
|
|
512
|
+
params: options.navigationParams,
|
|
518
513
|
state: input.state
|
|
519
514
|
});
|
|
520
515
|
},
|
|
@@ -526,7 +521,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
526
521
|
cleanPathname: options.cleanPathname,
|
|
527
522
|
completeness: "complete",
|
|
528
523
|
output: rscOutputScope,
|
|
529
|
-
params: options.
|
|
524
|
+
params: options.navigationParams,
|
|
530
525
|
state: input.state
|
|
531
526
|
});
|
|
532
527
|
},
|
|
@@ -551,7 +546,7 @@ async function renderAppPageLifecycle(options) {
|
|
|
551
546
|
}
|
|
552
547
|
return buildAppPageHtmlResponse(safeHtmlStream, {
|
|
553
548
|
draftCookie,
|
|
554
|
-
|
|
549
|
+
linkHeader,
|
|
555
550
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
556
551
|
middlewareContext: options.middlewareContext,
|
|
557
552
|
policy: htmlResponsePolicy,
|