vinext 1.3.1 → 1.4.0
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 +5 -2
- package/THIRD_PARTY_LICENSES.md +47 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -2
- package/dist/build/prerender.js +1 -1
- package/dist/build/report.d.ts +0 -14
- package/dist/build/report.js +1 -51
- package/dist/check.js +1 -1
- package/dist/cli.js +3 -0
- package/dist/client/dev-error-overlay.js +1 -1
- package/dist/client/navigation-runtime.d.ts +13 -1
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/next-config.d.ts +19 -0
- package/dist/config/next-config.js +64 -1
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
- package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
- package/dist/entries/app-rsc-entry.js +17 -48
- package/dist/entries/app-rsc-manifest.js +3 -4
- package/dist/entries/app-ssr-entry.js +1 -0
- package/dist/entries/pages-server-entry.js +33 -8
- package/dist/index.js +83 -70
- package/dist/init-cloudflare.d.ts +1 -3
- package/dist/init-cloudflare.js +10 -48
- package/dist/init-platform.d.ts +2 -0
- package/dist/init-platform.js +4 -0
- package/dist/plugins/extensionless-dynamic-import.js +6 -2
- package/dist/plugins/next-intl-catalog.d.ts +12 -0
- package/dist/plugins/next-intl-catalog.js +85 -0
- package/dist/plugins/pages-node-externals.d.ts +1 -0
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/use-cache-callable.d.ts +1 -1
- package/dist/plugins/use-cache-callable.js +136 -94
- package/dist/routing/app-route-graph.d.ts +6 -0
- package/dist/routing/app-route-graph.js +9 -1
- package/dist/server/api-handler.js +19 -4
- package/dist/server/app-bfcache-identity.js +1 -1
- package/dist/server/app-browser-entry.js +79 -63
- package/dist/server/app-browser-history-controller.d.ts +5 -4
- package/dist/server/app-browser-history-controller.js +93 -15
- package/dist/server/app-browser-navigation-controller.d.ts +2 -2
- package/dist/server/app-browser-navigation-controller.js +1 -2
- package/dist/server/app-browser-rsc-redirect.js +4 -4
- package/dist/server/app-browser-server-action-client.d.ts +2 -0
- package/dist/server/app-browser-server-action-client.js +4 -3
- package/dist/server/app-browser-state.d.ts +2 -4
- package/dist/server/app-browser-state.js +9 -4
- package/dist/server/app-browser-supplemental-refresh.js +16 -1
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-browser-visible-commit.js +2 -12
- package/dist/server/app-elements-wire.d.ts +6 -38
- package/dist/server/app-elements-wire.js +4 -41
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-history-state.d.ts +2 -2
- package/dist/server/app-history-state.js +5 -2
- package/dist/server/app-mounted-layouts.d.ts +21 -0
- package/dist/server/app-mounted-layouts.js +67 -0
- package/dist/server/app-optimistic-routing.d.ts +19 -1
- package/dist/server/app-optimistic-routing.js +42 -2
- package/dist/server/app-page-boundary-render.js +7 -6
- package/dist/server/app-page-boundary.js +2 -2
- package/dist/server/app-page-cache-finalizer.d.ts +12 -1
- package/dist/server/app-page-cache-finalizer.js +70 -29
- package/dist/server/app-page-cache.d.ts +13 -1
- package/dist/server/app-page-cache.js +31 -9
- package/dist/server/app-page-dispatch.d.ts +5 -10
- package/dist/server/app-page-dispatch.js +84 -154
- package/dist/server/app-page-element-builder.d.ts +2 -2
- package/dist/server/app-page-element-builder.js +10 -9
- package/dist/server/app-page-execution.d.ts +17 -52
- package/dist/server/app-page-execution.js +99 -95
- package/dist/server/app-page-head.d.ts +13 -0
- package/dist/server/app-page-head.js +44 -16
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
- package/dist/server/app-page-layout-gate.d.ts +35 -0
- package/dist/server/app-page-layout-gate.js +50 -0
- package/dist/server/app-page-params.d.ts +0 -1
- package/dist/server/app-page-params.js +1 -14
- package/dist/server/app-page-probe.d.ts +3 -21
- package/dist/server/app-page-probe.js +4 -37
- package/dist/server/app-page-render.d.ts +2 -12
- package/dist/server/app-page-render.js +89 -220
- package/dist/server/app-page-request.d.ts +1 -3
- package/dist/server/app-page-request.js +1 -1
- package/dist/server/app-page-response.js +3 -3
- package/dist/server/app-page-route-wiring.d.ts +13 -6
- package/dist/server/app-page-route-wiring.js +67 -61
- package/dist/server/app-page-rsc-render-status.d.ts +27 -1
- package/dist/server/app-page-rsc-render-status.js +121 -13
- package/dist/server/app-page-stream.d.ts +2 -0
- package/dist/server/app-page-stream.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +4 -0
- package/dist/server/app-pages-bridge.js +7 -3
- package/dist/server/app-render-dependency.d.ts +11 -4
- package/dist/server/app-render-dependency.js +86 -38
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-route-handler-cache.js +2 -2
- package/dist/server/app-route-handler-dispatch.js +14 -9
- package/dist/server/app-route-handler-execution.js +8 -3
- package/dist/server/app-route-handler-policy.d.ts +1 -1
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-handler-runtime.js +17 -4
- package/dist/server/app-rsc-cache-busting.d.ts +2 -2
- package/dist/server/app-rsc-cache-busting.js +4 -4
- package/dist/server/app-rsc-error-handler.d.ts +2 -1
- package/dist/server/app-rsc-error-handler.js +9 -1
- package/dist/server/app-rsc-errors.d.ts +8 -0
- package/dist/server/app-rsc-errors.js +8 -1
- package/dist/server/app-rsc-handler.d.ts +5 -5
- package/dist/server/app-rsc-handler.js +30 -24
- package/dist/server/app-rsc-request-normalization.d.ts +0 -4
- package/dist/server/app-rsc-request-normalization.js +1 -4
- package/dist/server/app-rsc-response-finalizer.js +2 -2
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +7 -4
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +9 -8
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/app-visited-response-cache.d.ts +36 -1
- package/dist/server/app-visited-response-cache.js +46 -5
- package/dist/server/app-worker-stages.d.ts +25 -3
- package/dist/server/app-worker-stages.js +45 -6
- package/dist/server/artifact-compatibility.d.ts +0 -1
- package/dist/server/artifact-compatibility.js +1 -10
- package/dist/server/cache-proof.d.ts +1 -115
- package/dist/server/cache-proof.js +1 -544
- package/dist/server/cacheability-request.js +13 -8
- package/dist/server/dev-server.js +4 -3
- package/dist/server/headers.d.ts +6 -3
- package/dist/server/headers.js +9 -5
- package/dist/server/isr-cache.d.ts +8 -2
- package/dist/server/isr-cache.js +26 -1
- package/dist/server/metadata-route-response.js +32 -15
- package/dist/server/multi-stage.d.ts +52 -11
- package/dist/server/multi-stage.js +13 -1
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/pages-api-route.js +28 -19
- package/dist/server/pages-media-type.d.ts +21 -1
- package/dist/server/pages-media-type.js +69 -5
- package/dist/server/pages-node-compat.js +52 -27
- package/dist/server/pages-page-handler.js +11 -20
- package/dist/server/pages-request-pipeline.d.ts +8 -0
- package/dist/server/pages-request-pipeline.js +2 -2
- package/dist/server/pages-request-stage-entry.js +14 -12
- package/dist/server/pages-response-stage-entry.js +9 -3
- package/dist/server/prod-server.js +5 -1
- package/dist/server/request-pipeline.d.ts +6 -0
- package/dist/server/request-pipeline.js +21 -1
- package/dist/server/shared-cache-identity.d.ts +23 -0
- package/dist/server/shared-cache-identity.js +36 -0
- package/dist/server/worker-stages.d.ts +16 -3
- package/dist/server/worker-stages.js +23 -4
- package/dist/shims/cache-handler.js +2 -2
- package/dist/shims/cache-request-state.d.ts +17 -20
- package/dist/shims/cache-request-state.js +16 -21
- package/dist/shims/cache-runtime.js +27 -11
- package/dist/shims/cache.d.ts +8 -7
- package/dist/shims/cache.js +17 -19
- package/dist/shims/cacheability-classification.d.ts +2 -0
- package/dist/shims/cdn-cache.d.ts +22 -5
- package/dist/shims/client-page-root.js +2 -2
- package/dist/shims/dynamic.js +9 -6
- package/dist/shims/error-boundary.js +2 -2
- package/dist/shims/fetch-cache-state.d.ts +5 -1
- package/dist/shims/fetch-cache-state.js +1 -3
- package/dist/shims/fetch-cache.d.ts +2 -1
- package/dist/shims/fetch-cache.js +34 -24
- package/dist/shims/form.js +2 -2
- package/dist/shims/headers.d.ts +8 -23
- package/dist/shims/headers.js +17 -67
- package/dist/shims/internal/navigation-untracked.js +1 -1
- package/dist/shims/link.js +3 -1
- package/dist/shims/metadata.d.ts +23 -21
- package/dist/shims/metadata.js +62 -24
- package/dist/shims/navigation-server.js +1 -1
- package/dist/shims/navigation.d.ts +74 -7
- package/dist/shims/navigation.js +183 -29
- package/dist/shims/navigation.react-server.js +2 -2
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/slot.d.ts +12 -0
- package/dist/shims/slot.js +37 -9
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -3
- package/dist/utils/cache-control-metadata.d.ts +5 -0
- package/dist/utils/cache-control-metadata.js +9 -1
- package/dist/utils/project.d.ts +2 -2
- package/dist/utils/project.js +3 -16
- package/dist/utils/regex.d.ts +5 -0
- package/dist/utils/regex.js +11 -1
- package/dist/utils/text-stream.d.ts +10 -5
- package/dist/utils/text-stream.js +6 -6
- package/package.json +2 -1
- package/dist/build/layout-classification-types.d.ts +0 -60
- package/dist/build/layout-classification-types.js +0 -1
- package/dist/build/layout-classification.d.ts +0 -62
- package/dist/build/layout-classification.js +0 -98
- package/dist/build/route-classification-injector.d.ts +0 -33
- package/dist/build/route-classification-injector.js +0 -59
- package/dist/build/route-classification-manifest.d.ts +0 -54
- package/dist/build/route-classification-manifest.js +0 -143
- package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
- package/dist/server/app-browser-client-reuse-manifest.js +0 -101
- package/dist/server/app-layout-param-observation.d.ts +0 -42
- package/dist/server/app-layout-param-observation.js +0 -168
- package/dist/server/client-reuse-manifest.d.ts +0 -103
- package/dist/server/client-reuse-manifest.js +0 -209
- package/dist/server/skip-cache-proof.d.ts +0 -60
- package/dist/server/skip-cache-proof.js +0 -168
- package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
- package/dist/server/static-layout-client-reuse-proof.js +0 -33
- package/dist/utils/sorted-array.d.ts +0 -8
- package/dist/utils/sorted-array.js +0 -20
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isPromiseLike } from "../utils/promise.js";
|
|
2
|
-
import { probeAppPageLayouts } from "./app-page-execution.js";
|
|
3
2
|
import { Fragment, isValidElement } from "react";
|
|
4
3
|
//#region src/server/app-page-probe.ts
|
|
5
4
|
const DEFAULT_SUBTREE_PROBE_MAX_DEPTH = 32;
|
|
@@ -63,10 +62,9 @@ async function resolveReactLazyType(lazyType) {
|
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
/**
|
|
66
|
-
* Invokes server
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* failures only make static-layout skip fall back to render-and-send.
|
|
65
|
+
* Invokes the server components a layout renders, so the error-path layout
|
|
66
|
+
* probe sees an HTTP access fallback thrown below the layout's own function
|
|
67
|
+
* body. The real RSC render remains authoritative.
|
|
70
68
|
*/
|
|
71
69
|
async function probeReactServerSubtree(node, options = {}) {
|
|
72
70
|
const maxDepth = options.maxDepth ?? DEFAULT_SUBTREE_PROBE_MAX_DEPTH;
|
|
@@ -118,36 +116,5 @@ async function probeReactServerSubtree(node, options = {}) {
|
|
|
118
116
|
};
|
|
119
117
|
await visit(node, 0);
|
|
120
118
|
}
|
|
121
|
-
async function probeAppPageBeforeRender(options) {
|
|
122
|
-
let layoutFlags = {};
|
|
123
|
-
if (options.skipProbes) return {
|
|
124
|
-
response: null,
|
|
125
|
-
layoutFlags
|
|
126
|
-
};
|
|
127
|
-
if (options.layoutCount > 0) {
|
|
128
|
-
const layoutProbeResult = await probeAppPageLayouts({
|
|
129
|
-
layoutCount: options.layoutCount,
|
|
130
|
-
async onLayoutError(layoutError, layoutIndex) {
|
|
131
|
-
const specialError = options.resolveSpecialError(layoutError);
|
|
132
|
-
if (!specialError) return null;
|
|
133
|
-
return options.renderLayoutSpecialError(specialError, layoutIndex);
|
|
134
|
-
},
|
|
135
|
-
probeLayoutAt: options.probeLayoutAt,
|
|
136
|
-
runWithSuppressedHookWarning(probe) {
|
|
137
|
-
return options.runWithSuppressedHookWarning(probe);
|
|
138
|
-
},
|
|
139
|
-
classification: options.classification
|
|
140
|
-
});
|
|
141
|
-
layoutFlags = layoutProbeResult.layoutFlags;
|
|
142
|
-
if (layoutProbeResult.response) return {
|
|
143
|
-
response: layoutProbeResult.response,
|
|
144
|
-
layoutFlags
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
response: null,
|
|
149
|
-
layoutFlags
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
119
|
//#endregion
|
|
153
|
-
export {
|
|
120
|
+
export { probeReactServerSubtree };
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { ClientReuseManifestParseResult, ClientReuseManifestSkipDisposition } from "./client-reuse-manifest.js";
|
|
2
1
|
import { AppOutgoingElements } from "./app-elements-wire.js";
|
|
3
2
|
import "./app-elements.js";
|
|
4
3
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
5
4
|
import { NavigationContext } from "../shims/navigation-context-state.js";
|
|
6
5
|
import "../shims/navigation.js";
|
|
7
|
-
import { AppPageFontPreload, AppPageSpecialError
|
|
6
|
+
import { AppPageFontPreload, AppPageSpecialError } from "./app-page-execution.js";
|
|
8
7
|
import { AppPageMiddlewareContext } from "./app-page-response.js";
|
|
9
|
-
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
10
8
|
import { RootParams } from "../shims/root-params.js";
|
|
11
9
|
import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
12
10
|
import { AppRenderErrorContextOverrides } from "./app-rsc-error-handler.js";
|
|
@@ -110,7 +108,6 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
110
108
|
isrSet: AppPageCacheSetter;
|
|
111
109
|
interceptionContext?: string | null;
|
|
112
110
|
interceptionId?: string | null;
|
|
113
|
-
layoutCount: number;
|
|
114
111
|
loadSsrHandler: () => Promise<AppPageSsrHandler>;
|
|
115
112
|
middlewareContext: AppPageMiddlewareContext;
|
|
116
113
|
navigationParams: Record<string, unknown>;
|
|
@@ -120,12 +117,10 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
120
117
|
abortPprFallbackShell?: () => void;
|
|
121
118
|
rootParams?: RootParams;
|
|
122
119
|
peekRenderObservationState?: () => AppPageRenderObservationState;
|
|
123
|
-
probeLayoutAt: (layoutIndex: number) => unknown;
|
|
124
120
|
expireSeconds?: number;
|
|
125
121
|
formState?: ReactFormState | null;
|
|
126
122
|
revalidateSeconds: number | null;
|
|
127
123
|
renderErrorBoundaryResponse: (error: unknown, errorOrigin: "rsc" | "ssr") => Promise<Response | null>;
|
|
128
|
-
renderLayoutSpecialError: (specialError: AppPageSpecialError, layoutIndex: number) => Promise<Response>;
|
|
129
124
|
renderPageSpecialError: (specialError: AppPageSpecialError, renderOptions?: AppPageSpecialErrorRenderOptions) => Promise<Response>;
|
|
130
125
|
renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
|
|
131
126
|
onError: AppPageBoundaryOnError;
|
|
@@ -138,16 +133,11 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
138
133
|
prelude: ReadableStream<Uint8Array>;
|
|
139
134
|
}>;
|
|
140
135
|
routePattern: string;
|
|
141
|
-
runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
|
|
142
136
|
scriptNonce?: string;
|
|
143
|
-
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
144
|
-
skipDisposition?: ClientReuseManifestSkipDisposition;
|
|
145
137
|
mountedSlotsHeader?: string | null;
|
|
146
138
|
renderedPathAndSearch?: string | null;
|
|
147
139
|
renderMode?: AppRscRenderMode;
|
|
148
140
|
waitUntil?: (promise: Promise<void>) => void;
|
|
149
|
-
layoutParamAccess?: AppLayoutParamAccessTracker;
|
|
150
|
-
classification?: LayoutClassificationOptions | null;
|
|
151
141
|
};
|
|
152
142
|
type RenderAppPageLifecycleOptions = RenderAppPageLifecycleOptionsBase & ({
|
|
153
143
|
element: AppPageRenderableElement;
|
|
@@ -163,7 +153,7 @@ type RenderAppPageLifecycleOptions = RenderAppPageLifecycleOptionsBase & ({
|
|
|
163
153
|
* its response policy, such as error boundaries and special errors, get the
|
|
164
154
|
* same header as the normal render.
|
|
165
155
|
*/
|
|
166
|
-
export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "dynamicStaleTimeSeconds" | "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce">,
|
|
156
|
+
export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "dynamicStaleTimeSeconds" | "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce">, requestCacheLife?: AppPageRequestCacheLife | null): Response;
|
|
167
157
|
export declare function renderAppPageLifecycle(options: RenderAppPageLifecycleOptions): Promise<Response>;
|
|
168
158
|
//#endregion
|
|
169
159
|
export {};
|
|
@@ -4,36 +4,33 @@ import { bindRequestContext } from "../shims/unified-request-context.js";
|
|
|
4
4
|
import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER } from "./headers.js";
|
|
5
5
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
6
6
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
7
|
-
import {
|
|
7
|
+
import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
|
|
8
|
+
import { getRouteCacheabilityCaptureOptions, isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
|
|
8
9
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, isCdnResponsePolicyHeader } from "./cache-control.js";
|
|
9
10
|
import "./app-rsc-render-mode.js";
|
|
10
11
|
import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
|
|
11
|
-
import { isRenderDynamicLatched
|
|
12
|
-
import { peekDynamicUsage
|
|
12
|
+
import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
|
|
13
|
+
import { peekDynamicUsage } from "../shims/headers.js";
|
|
13
14
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
14
15
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
16
|
+
import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
|
|
17
|
+
import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
|
|
18
|
+
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
15
19
|
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
16
20
|
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
17
21
|
import "./app-elements.js";
|
|
22
|
+
import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
|
|
18
23
|
import { isBailoutToCSRError } from "../shims/navigation-errors.js";
|
|
19
|
-
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
20
24
|
import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
|
|
21
|
-
import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
|
|
22
25
|
import { applyClientStaleTimeHeader, applyEdgeRuntimeHeader, buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy, resolveUncacheableCacheControl } from "./app-page-response.js";
|
|
23
26
|
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageCaughtNotFoundBoundaries, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
24
|
-
import {
|
|
27
|
+
import { getAppPageLayoutGate } from "./app-page-layout-gate.js";
|
|
25
28
|
import { hasDigest } from "./app-rsc-errors.js";
|
|
26
29
|
import { recordAppPageRenderError, traceAppPageRender } from "./app-page-tracing.js";
|
|
27
|
-
import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
|
|
28
|
-
import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRenderObservation, buildRenderRequestApiObservations, createStaticLayoutArtifactReuseDecision } from "./cache-proof.js";
|
|
29
|
-
import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
|
|
30
|
-
import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
|
|
31
30
|
import { buildAppPageHtmlDocumentResponse, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, createAppPageSsrErrorHandler, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
|
|
32
|
-
import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
|
|
33
31
|
import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
34
32
|
import { createAppPageRscRenderStatusResolver } from "./app-page-rsc-render-status.js";
|
|
35
33
|
import { finalizeAppPageCacheabilityEvaluationResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache-finalizer.js";
|
|
36
|
-
import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
|
|
37
34
|
//#region src/server/app-page-render.ts
|
|
38
35
|
function buildResponseTiming(options) {
|
|
39
36
|
if (options.isProduction) return;
|
|
@@ -75,11 +72,11 @@ function applyRequestCacheLife(options) {
|
|
|
75
72
|
* its response policy, such as error boundaries and special errors, get the
|
|
76
73
|
* same header as the normal render.
|
|
77
74
|
*/
|
|
78
|
-
function applyIneligibleRouteCachePolicy(response, options,
|
|
75
|
+
function applyIneligibleRouteCachePolicy(response, options, requestCacheLife = null) {
|
|
79
76
|
const cacheControl = resolveEarlyResponseCacheControl(options);
|
|
80
77
|
const isRscRedirect = options.isRscRequest && response.headers.has("X-Vinext-Rsc-Redirect");
|
|
81
78
|
if (!cacheControl) {
|
|
82
|
-
const staleTimeSeconds = isRscRedirect ? resolveClientStaleTimeSeconds(
|
|
79
|
+
const staleTimeSeconds = isRscRedirect ? resolveClientStaleTimeSeconds(requestCacheLife) : void 0;
|
|
83
80
|
if (staleTimeSeconds === void 0) return response;
|
|
84
81
|
const stamped = cloneForStamping(response);
|
|
85
82
|
applyClientStaleTimeHeader(stamped.headers, staleTimeSeconds);
|
|
@@ -116,18 +113,6 @@ function resolveAppPageCacheWriteRevalidateSeconds(options) {
|
|
|
116
113
|
if (options.revalidateSeconds === null && (options.isForceStatic || options.isDynamicError)) return Infinity;
|
|
117
114
|
return options.revalidateSeconds;
|
|
118
115
|
}
|
|
119
|
-
/**
|
|
120
|
-
* A loading-shell prefetch without a loading boundary that can never be stored
|
|
121
|
-
* renders only the route tree (see buildAppPageElements), so no layout runs and
|
|
122
|
-
* none is probed. Next.js runs no layout for its no-loading prefetch either.
|
|
123
|
-
*/
|
|
124
|
-
function isRouteTreeOnlyLoadingShell(options) {
|
|
125
|
-
if (options.renderMode !== "prefetch-loading-shell") return false;
|
|
126
|
-
if (options.isCacheCandidate === true) return false;
|
|
127
|
-
if (!isAppElementsRecord(options.element)) return false;
|
|
128
|
-
const routeId = options.element[AppElementsWire.keys.route];
|
|
129
|
-
return typeof routeId === "string" && options.element[routeId] === null;
|
|
130
|
-
}
|
|
131
116
|
function readRootBoundaryId(element) {
|
|
132
117
|
const rootLayoutTreePath = element[AppElementsWire.keys.rootLayout];
|
|
133
118
|
return typeof rootLayoutTreePath === "string" ? rootLayoutTreePath : null;
|
|
@@ -144,146 +129,6 @@ function createAppPageArtifactCompatibility(element, routePattern) {
|
|
|
144
129
|
rootBoundaryId
|
|
145
130
|
});
|
|
146
131
|
}
|
|
147
|
-
function readStringMetadata(element, key) {
|
|
148
|
-
const value = element[key];
|
|
149
|
-
return typeof value === "string" ? value : null;
|
|
150
|
-
}
|
|
151
|
-
function createStaticLayoutOutputScope(input) {
|
|
152
|
-
const routeId = readStringMetadata(input.element, AppElementsWire.keys.route);
|
|
153
|
-
if (routeId === null) return null;
|
|
154
|
-
return {
|
|
155
|
-
kind: "layout",
|
|
156
|
-
layoutId: input.layoutId,
|
|
157
|
-
rootBoundaryId: input.artifactCompatibility.rootBoundaryId,
|
|
158
|
-
routeId
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function createRenderAndSendSkipDisposition() {
|
|
162
|
-
return {
|
|
163
|
-
code: "SKIP_MODEL_DISABLED",
|
|
164
|
-
enabled: false,
|
|
165
|
-
mode: "renderAndSend"
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function rejectStaticLayoutObservation(entry, code, fields = {}) {
|
|
169
|
-
return {
|
|
170
|
-
kind: "rejected",
|
|
171
|
-
rejection: {
|
|
172
|
-
code,
|
|
173
|
-
entryId: entry.id,
|
|
174
|
-
fields
|
|
175
|
-
},
|
|
176
|
-
skipDisposition: createRenderAndSendSkipDisposition()
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function rejectUnsafeStaticLayoutObservation(entry, layoutParamAccess) {
|
|
180
|
-
const observation = layoutParamAccess?.getLayoutObservation(entry.id);
|
|
181
|
-
if (!observation) return rejectStaticLayoutObservation(entry, "SKIP_LAYOUT_PARAMS_OBSERVATION_INCOMPLETE");
|
|
182
|
-
const observationRejection = getStaticLayoutObservationSkipRejection(observation);
|
|
183
|
-
if (observationRejection) return rejectStaticLayoutObservation(entry, observationRejection.code, observationRejection.fields);
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
function createRenderLifecycleSkipDisposition(input) {
|
|
187
|
-
if (!input.isRscRequest || input.clientReuseManifest === void 0) return;
|
|
188
|
-
const clientReuseManifest = input.clientReuseManifest;
|
|
189
|
-
if (clientReuseManifest.kind !== "parsed" || clientReuseManifest.manifest.entries.length === 0) return;
|
|
190
|
-
if (!isAppElementsRecord(input.element) || input.artifactCompatibility === void 0) return {
|
|
191
|
-
code: "SKIP_MODEL_DISABLED",
|
|
192
|
-
enabled: false,
|
|
193
|
-
mode: "renderAndSend"
|
|
194
|
-
};
|
|
195
|
-
const element = input.element;
|
|
196
|
-
const artifactCompatibility = input.artifactCompatibility;
|
|
197
|
-
const staticLayoutIds = new Set(Object.entries(input.layoutFlags).filter(([, flag]) => flag === "s").map(([layoutId]) => layoutId));
|
|
198
|
-
return createClientReuseSkipTransportPlan({
|
|
199
|
-
manifest: clientReuseManifest,
|
|
200
|
-
verifyEntry(entry) {
|
|
201
|
-
if (entry.kind !== "layout" || !staticLayoutIds.has(entry.id) || AppElementsWire.parseElementKey(entry.id)?.kind !== "layout") return crossCheckClientReuseManifestEntryWithCache({
|
|
202
|
-
artifact: {
|
|
203
|
-
compatibility: artifactCompatibility,
|
|
204
|
-
invalidation: { kind: "unknown" },
|
|
205
|
-
payloadHash: null
|
|
206
|
-
},
|
|
207
|
-
cacheDecision: null,
|
|
208
|
-
entry
|
|
209
|
-
});
|
|
210
|
-
const currentOutput = createStaticLayoutOutputScope({
|
|
211
|
-
artifactCompatibility,
|
|
212
|
-
element,
|
|
213
|
-
layoutId: entry.id
|
|
214
|
-
});
|
|
215
|
-
if (currentOutput === null) return crossCheckClientReuseManifestEntryWithCache({
|
|
216
|
-
artifact: {
|
|
217
|
-
compatibility: artifactCompatibility,
|
|
218
|
-
invalidation: { kind: "unknown" },
|
|
219
|
-
payloadHash: null
|
|
220
|
-
},
|
|
221
|
-
cacheDecision: null,
|
|
222
|
-
entry
|
|
223
|
-
});
|
|
224
|
-
const observationRejection = rejectUnsafeStaticLayoutObservation(entry, input.layoutParamAccess);
|
|
225
|
-
if (observationRejection) return observationRejection;
|
|
226
|
-
const candidateRouteId = createStaticLayoutClientReuseRouteId(entry.id);
|
|
227
|
-
const candidateOutput = {
|
|
228
|
-
...currentOutput,
|
|
229
|
-
routeId: candidateRouteId
|
|
230
|
-
};
|
|
231
|
-
const candidateVariant = buildCacheVariantWithRouteBudget({
|
|
232
|
-
budget: DEFAULT_CACHE_VARIANT_BUDGET,
|
|
233
|
-
dimensions: [],
|
|
234
|
-
output: candidateOutput,
|
|
235
|
-
routeBudget: {
|
|
236
|
-
routeId: candidateRouteId,
|
|
237
|
-
variantCacheKeys: []
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
const skipArtifactCompatibility = candidateVariant.kind === "variant" ? createStaticLayoutClientReuseArtifactCompatibility({
|
|
241
|
-
artifactCompatibility,
|
|
242
|
-
layoutId: entry.id,
|
|
243
|
-
rootBoundaryId: candidateOutput.rootBoundaryId,
|
|
244
|
-
routeId: candidateOutput.routeId,
|
|
245
|
-
variantCacheKey: candidateVariant.variant.cacheKey
|
|
246
|
-
}) : artifactCompatibility;
|
|
247
|
-
const cacheDecision = createStaticLayoutArtifactReuseDecision({
|
|
248
|
-
candidateArtifactCompatibility: skipArtifactCompatibility,
|
|
249
|
-
candidateObservation: buildRenderObservation({
|
|
250
|
-
boundaryOutcome: { kind: "success" },
|
|
251
|
-
cacheability: "public",
|
|
252
|
-
cacheTags: [],
|
|
253
|
-
completeness: "complete",
|
|
254
|
-
dynamicFetches: [],
|
|
255
|
-
output: candidateOutput,
|
|
256
|
-
pathTags: [input.cleanPathname],
|
|
257
|
-
requestApis: buildRenderRequestApiObservations({
|
|
258
|
-
completeness: "complete",
|
|
259
|
-
observed: []
|
|
260
|
-
})
|
|
261
|
-
}),
|
|
262
|
-
candidateVariant,
|
|
263
|
-
currentArtifactCompatibility: skipArtifactCompatibility,
|
|
264
|
-
currentOutput
|
|
265
|
-
});
|
|
266
|
-
return crossCheckClientReuseManifestEntryWithCache({
|
|
267
|
-
artifact: {
|
|
268
|
-
compatibility: skipArtifactCompatibility,
|
|
269
|
-
invalidation: { kind: "valid" },
|
|
270
|
-
payloadHash: candidateVariant.kind === "variant" ? createStaticLayoutClientReusePayloadHash({
|
|
271
|
-
artifactCompatibility: skipArtifactCompatibility,
|
|
272
|
-
layoutId: entry.id,
|
|
273
|
-
rootBoundaryId: candidateOutput.rootBoundaryId,
|
|
274
|
-
routeId: candidateOutput.routeId,
|
|
275
|
-
variantCacheKey: candidateVariant.variant.cacheKey
|
|
276
|
-
}) : null
|
|
277
|
-
},
|
|
278
|
-
cacheDecision,
|
|
279
|
-
entry
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
}).skipDisposition;
|
|
283
|
-
}
|
|
284
|
-
function isSkipTransportEnabled(skipDisposition) {
|
|
285
|
-
return skipDisposition?.enabled === true;
|
|
286
|
-
}
|
|
287
132
|
/**
|
|
288
133
|
* Wraps an RSC response body to report invalid dynamic usage errors after the
|
|
289
134
|
* stream is fully consumed. In dev mode, errors from cookies()/headers() inside
|
|
@@ -402,27 +247,6 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
402
247
|
}
|
|
403
248
|
return dynamicUsageObserved;
|
|
404
249
|
};
|
|
405
|
-
const probeOutcome = await runWithDetachedDynamicUsage(() => probeAppPageBeforeRender({
|
|
406
|
-
skipProbes: options.pprFallbackShellSignal !== void 0 || isRouteTreeOnlyLoadingShell(options),
|
|
407
|
-
layoutCount: options.layoutCount,
|
|
408
|
-
probeLayoutAt(layoutIndex) {
|
|
409
|
-
return options.probeLayoutAt(layoutIndex);
|
|
410
|
-
},
|
|
411
|
-
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
412
|
-
return options.renderLayoutSpecialError(specialError, layoutIndex);
|
|
413
|
-
},
|
|
414
|
-
resolveSpecialError: resolveAppPageSpecialError,
|
|
415
|
-
runWithSuppressedHookWarning(probe) {
|
|
416
|
-
return options.runWithSuppressedHookWarning(probe);
|
|
417
|
-
},
|
|
418
|
-
classification: options.classification
|
|
419
|
-
}));
|
|
420
|
-
const preRenderResult = probeOutcome.result;
|
|
421
|
-
if (preRenderResult.response) {
|
|
422
|
-
if (probeOutcome.dynamicDetected) markDynamicUsage();
|
|
423
|
-
return applyIneligibleRouteCachePolicy(preRenderResult.response, options, probeOutcome.cacheLife);
|
|
424
|
-
}
|
|
425
|
-
const layoutFlags = preRenderResult.layoutFlags;
|
|
426
250
|
const artifactCompatibility = createAppPageArtifactCompatibility(options.element, options.routePattern);
|
|
427
251
|
const rootBoundaryId = artifactCompatibility?.rootBoundaryId ?? null;
|
|
428
252
|
const renderEpoch = artifactCompatibility?.renderEpoch ?? null;
|
|
@@ -439,23 +263,13 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
439
263
|
rootBoundaryId,
|
|
440
264
|
routePattern: options.routePattern
|
|
441
265
|
});
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
cleanPathname: options.cleanPathname,
|
|
445
|
-
clientReuseManifest: options.clientReuseManifest,
|
|
446
|
-
element: options.element,
|
|
447
|
-
isRscRequest: options.isRscRequest,
|
|
448
|
-
layoutFlags,
|
|
449
|
-
layoutParamAccess: options.layoutParamAccess
|
|
450
|
-
});
|
|
451
|
-
const shouldBypassRscCache = options.isRscRequest && isSkipTransportEnabled(skipDisposition) || options.bypassInterceptionContextCache === true;
|
|
266
|
+
const isPartialPayload = options.isRscRequest && isAppElementsRecord(options.element) && Object.hasOwn(options.element, AppElementsWire.keys.skippedLayoutIds);
|
|
267
|
+
const shouldBypassRscCache = options.bypassInterceptionContextCache === true || isPartialPayload;
|
|
452
268
|
const dynamicStaleTimeSeconds = options.dynamicStaleTimeSeconds ?? resolveConfiguredDynamicStaleTimeSeconds();
|
|
453
269
|
const outgoingElement = AppElementsWire.encodeOutgoingPayload({
|
|
454
270
|
element: options.element,
|
|
455
|
-
layoutFlags,
|
|
456
271
|
...dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic ? { dynamicStaleTimeSeconds } : {},
|
|
457
|
-
...artifactCompatibility ? { artifactCompatibility } : {}
|
|
458
|
-
skipDisposition: options.isRscRequest ? skipDisposition : void 0
|
|
272
|
+
...artifactCompatibility ? { artifactCompatibility } : {}
|
|
459
273
|
});
|
|
460
274
|
const compileEnd = options.isProduction ? void 0 : performance.now();
|
|
461
275
|
const errorContextOverrides = {
|
|
@@ -466,6 +280,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
466
280
|
...options.isPrerender ? { revalidateReason: "stale" } : {}
|
|
467
281
|
};
|
|
468
282
|
const baseOnError = options.createRscOnErrorHandler(options.cleanPathname, options.routePattern, errorContextOverrides);
|
|
283
|
+
const layoutGate = options.isRscRequest && options.isPrerender !== true && options.pprFallbackShellSignal === void 0 ? getAppPageLayoutGate(options.element) : null;
|
|
469
284
|
const rscErrorTracker = createAppPageRscErrorTracker((error, requestInfo, errorContext) => {
|
|
470
285
|
if (renderSpan) recordAppPageRenderError(renderSpan, error);
|
|
471
286
|
return baseOnError(error, requestInfo, errorContext);
|
|
@@ -484,6 +299,24 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
484
299
|
});
|
|
485
300
|
let pprFallbackShellRsc = null;
|
|
486
301
|
if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
|
|
302
|
+
if (layoutGate) {
|
|
303
|
+
const [heldStream, watchedStream] = rscStream.tee();
|
|
304
|
+
rscStream = heldStream;
|
|
305
|
+
const watchedReader = watchedStream.getReader();
|
|
306
|
+
const renderEnded = (async () => {
|
|
307
|
+
while (!(await watchedReader.read()).done);
|
|
308
|
+
})();
|
|
309
|
+
const layoutFailure = await layoutGate.wait((layoutId) => isAppElementsRecord(outgoingElement) && Object.hasOwn(outgoingElement, layoutId), renderEnded);
|
|
310
|
+
watchedReader.cancel().catch(() => {});
|
|
311
|
+
const layoutSpecialError = layoutFailure ? resolveAppPageSpecialError(layoutFailure.error) : null;
|
|
312
|
+
if (layoutFailure && layoutSpecialError) {
|
|
313
|
+
rscStream.cancel().catch(() => {});
|
|
314
|
+
return applyIneligibleRouteCachePolicy(await options.renderPageSpecialError(layoutSpecialError.kind === "http-access-fallback" ? {
|
|
315
|
+
...layoutSpecialError,
|
|
316
|
+
layoutIndex: layoutFailure.layoutIndex
|
|
317
|
+
} : layoutSpecialError), options, options.peekRequestCacheLife?.() ?? options.getRequestCacheLife());
|
|
318
|
+
}
|
|
319
|
+
}
|
|
487
320
|
let revalidateSeconds = options.revalidateSeconds;
|
|
488
321
|
let expireSeconds = options.expireSeconds;
|
|
489
322
|
const shouldWaitForAllReady = options.isPrerender === true && options.isSpeculativePrerender !== true || options.renderWholeDocument === true;
|
|
@@ -501,10 +334,47 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
501
334
|
const rscForResponse = rscCapture.ssrStream;
|
|
502
335
|
const capturedRscDataRef = { value: null };
|
|
503
336
|
if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
|
|
337
|
+
const resolveInitialNavigationCacheMetadata = (dynamicUsed, requestCacheLife) => {
|
|
338
|
+
let kind;
|
|
339
|
+
if (options.isForceStatic) kind = "static";
|
|
340
|
+
else if (options.isForceDynamic || dynamicUsed) kind = "dynamic";
|
|
341
|
+
else {
|
|
342
|
+
const observation = options.peekRenderObservationState?.();
|
|
343
|
+
kind = observation && (observation.dynamicFetches.length > 0 || observation.requestApis.length > 0) ? "dynamic" : "static";
|
|
344
|
+
}
|
|
345
|
+
const staleTimeSeconds = resolveClientStaleTimeSeconds(requestCacheLife);
|
|
346
|
+
return {
|
|
347
|
+
kind,
|
|
348
|
+
...kind === "dynamic" && dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true ? { dynamicStaleTimeSeconds } : {},
|
|
349
|
+
...staleTimeSeconds === void 0 ? {} : { staleTimeSeconds: Math.floor(staleTimeSeconds) }
|
|
350
|
+
};
|
|
351
|
+
};
|
|
504
352
|
if (options.isRscRequest) {
|
|
505
|
-
const
|
|
353
|
+
const capturedRscData = capturedRscDataRef.value;
|
|
354
|
+
const resolvesRscRenderStatus = options.isProduction && shouldCaptureRscForCacheMetadata && capturedRscData !== null && options.isPrerender !== true && options.isRoutePPREnabled !== true;
|
|
355
|
+
const isPageDocumentRender = options.isCacheCandidate === true && !options.scriptNonce && !options.mountedSlotsHeader && !options.interceptionContext && !options.interceptionId && (options.renderMode === void 0 || options.renderMode === "navigation");
|
|
356
|
+
const cdnCacheAdapter = getCdnCacheAdapter();
|
|
357
|
+
const captureAdmittedDocument = resolvesRscRenderStatus && isPageDocumentRender && !cdnCacheAdapter.ownsBackgroundRevalidation ? cdnCacheAdapter.captureAppPageDocument?.() : void 0;
|
|
358
|
+
const rendersDocument = isPageDocumentRender && (cdnCacheAdapter.ownsBackgroundRevalidation || captureAdmittedDocument !== void 0);
|
|
359
|
+
const resolveRscRenderStatus = resolvesRscRenderStatus ? createAppPageRscRenderStatusResolver({
|
|
506
360
|
basePath: options.basePath,
|
|
507
|
-
capturedRscData
|
|
361
|
+
capturedRscData,
|
|
362
|
+
...rendersDocument ? { document: {
|
|
363
|
+
clientTraceMetadata: options.clientTraceMetadata,
|
|
364
|
+
...captureAdmittedDocument ? { deadlineAt: getRouteCacheabilityCaptureOptions()?.captureDeadlineAt } : {},
|
|
365
|
+
getFontData: () => createAppPageFontData({
|
|
366
|
+
getLinks: options.getFontLinks,
|
|
367
|
+
getPreloads: options.getFontPreloads,
|
|
368
|
+
getStyles: options.getFontStyles
|
|
369
|
+
}),
|
|
370
|
+
getInitialNavigationCacheMetadata: () => resolveInitialNavigationCacheMetadata(peekDynamicUsage(), options.peekRequestCacheLife?.()),
|
|
371
|
+
mirrorNextFlight: () => rscErrorTracker.getCapturedSpecialError() !== null,
|
|
372
|
+
onSsrError: createAppPageSsrErrorHandler(options.createRscOnErrorHandler(options.cleanPathname, options.routePattern, {
|
|
373
|
+
...errorContextOverrides,
|
|
374
|
+
renderSource: "server-rendering"
|
|
375
|
+
}), rscErrorTracker.isCapturedError),
|
|
376
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength
|
|
377
|
+
} } : {},
|
|
508
378
|
getCapturedSpecialError: rscErrorTracker.getCapturedSpecialError,
|
|
509
379
|
getCapturedSpecialErrors: rscErrorTracker.getCapturedSpecialErrors,
|
|
510
380
|
isForceStatic: options.isForceStatic,
|
|
@@ -524,7 +394,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
524
394
|
}));
|
|
525
395
|
}
|
|
526
396
|
const dynamicUsedDuringBuild = consumeRenderDynamicUsage();
|
|
527
|
-
const rscResponsePolicy = shouldBypassRscCache ? { cacheControl: NO_STORE_CACHE_CONTROL } : resolveAppPageRscResponsePolicy({
|
|
397
|
+
const rscResponsePolicy = isPartialPayload ? { cacheControl: resolveUncacheableCacheControl(options.isProduction) } : shouldBypassRscCache ? { cacheControl: NO_STORE_CACHE_CONTROL } : resolveAppPageRscResponsePolicy({
|
|
528
398
|
dynamicUsedDuringBuild,
|
|
529
399
|
isDraftMode: options.isDraftMode,
|
|
530
400
|
isDynamicError: options.isDynamicError,
|
|
@@ -535,7 +405,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
535
405
|
expireSeconds,
|
|
536
406
|
revalidateSeconds
|
|
537
407
|
});
|
|
538
|
-
if (shouldBypassRscCache) options.isrDebug?.(
|
|
408
|
+
if (shouldBypassRscCache) options.isrDebug?.(isPartialPayload ? "RSC cache write skipped (partial payload)" : "RSC cache write skipped (unverified interception context)", options.cleanPathname);
|
|
539
409
|
const shouldEmitDynamicStaleTime = dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true && !options.isForceStatic && (dynamicUsedDuringBuild || options.isForceDynamic);
|
|
540
410
|
const staleTimePending = options.isPrerender !== true && mayResolveCacheLifeAfterHeaders && !dynamicUsedDuringBuild;
|
|
541
411
|
const rscResponse = buildAppPageRscResponse(rscForResponse, {
|
|
@@ -575,9 +445,22 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
575
445
|
return finalizeAppPageRscCacheResponse(devRscResponse, {
|
|
576
446
|
capturedRscDataPromise: options.isProduction && shouldCaptureRscForCacheMetadata ? capturedRscDataRef.value : null,
|
|
577
447
|
bypassInterceptionContextCache: options.bypassInterceptionContextCache,
|
|
448
|
+
captureAdmittedDocument,
|
|
578
449
|
cleanPathname: options.cleanPathname,
|
|
579
450
|
consumeDynamicUsage: finalizeRenderDynamicUsage,
|
|
580
451
|
consumeRenderObservationState,
|
|
452
|
+
createHtmlRenderObservation(input) {
|
|
453
|
+
return createAppPageRenderObservation({
|
|
454
|
+
boundaryOutcome: { kind: "success" },
|
|
455
|
+
cacheability: "public",
|
|
456
|
+
cacheTags: input.cacheTags,
|
|
457
|
+
cleanPathname: options.cleanPathname,
|
|
458
|
+
completeness: "complete",
|
|
459
|
+
output: htmlOutputScope,
|
|
460
|
+
params: options.navigationParams,
|
|
461
|
+
state: input.state
|
|
462
|
+
});
|
|
463
|
+
},
|
|
581
464
|
createRscRenderObservation(input) {
|
|
582
465
|
return createAppPageRenderObservation({
|
|
583
466
|
boundaryOutcome: { kind: "success" },
|
|
@@ -598,6 +481,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
598
481
|
return readRequestCacheLifeForCachePolicy(options);
|
|
599
482
|
},
|
|
600
483
|
isrDebug: options.isrDebug,
|
|
484
|
+
isrHtmlKey: options.isrHtmlKey,
|
|
601
485
|
isrRscKey: options.isrRscKey,
|
|
602
486
|
isrSet: options.isrSet,
|
|
603
487
|
interceptionContext: options.interceptionContext,
|
|
@@ -801,22 +685,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
801
685
|
};
|
|
802
686
|
return renderAppPageHtmlStream({
|
|
803
687
|
capturedRscDataRef,
|
|
804
|
-
getInitialNavigationCacheMetadata: () =>
|
|
805
|
-
let kind;
|
|
806
|
-
if (options.isForceStatic) kind = "static";
|
|
807
|
-
else if (options.isForceDynamic || dynamicUsedDuringHtmlRender || peekDynamicUsage()) kind = "dynamic";
|
|
808
|
-
else {
|
|
809
|
-
const observation = options.peekRenderObservationState?.();
|
|
810
|
-
kind = observation && (observation.dynamicFetches.length > 0 || observation.requestApis.length > 0) ? "dynamic" : "static";
|
|
811
|
-
}
|
|
812
|
-
const requestCacheLife = options.isPrerender === true ? requestCacheLifeForPrerender ?? options.peekRequestCacheLife?.() : options.peekRequestCacheLife?.();
|
|
813
|
-
const staleTimeSeconds = resolveClientStaleTimeSeconds(requestCacheLife);
|
|
814
|
-
return {
|
|
815
|
-
kind,
|
|
816
|
-
...kind === "dynamic" && dynamicStaleTimeSeconds !== void 0 && options.isPrerender !== true ? { dynamicStaleTimeSeconds } : {},
|
|
817
|
-
...staleTimeSeconds === void 0 ? {} : { staleTimeSeconds: Math.floor(staleTimeSeconds) }
|
|
818
|
-
};
|
|
819
|
-
},
|
|
688
|
+
getInitialNavigationCacheMetadata: () => resolveInitialNavigationCacheMetadata(dynamicUsedDuringHtmlRender || peekDynamicUsage(), options.isPrerender === true ? requestCacheLifeForPrerender ?? options.peekRequestCacheLife?.() : options.peekRequestCacheLife?.()),
|
|
820
689
|
fontData,
|
|
821
690
|
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
822
691
|
navigationContext: options.getNavigationContext(),
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AppPageSpecialError } from "./app-page-execution.js";
|
|
2
|
-
import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
|
|
3
2
|
//#region src/server/app-page-request.d.ts
|
|
4
3
|
type AppPageParams = Record<string, string | string[]>;
|
|
5
4
|
type GenerateStaticParams = (args: {
|
|
@@ -120,7 +119,7 @@ type ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts> = {
|
|
|
120
119
|
type ResolveAppPageActionRerenderTargetOptions<TRoute, TPage, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetOptions<TRoute, TPage, TInterceptOpts>;
|
|
121
120
|
type ResolveAppPageActionRerenderTargetResult<TRoute, TInterceptOpts> = ResolveAppPageInterceptionRerenderTargetResult<TRoute, TInterceptOpts>;
|
|
122
121
|
type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
123
|
-
buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams,
|
|
122
|
+
buildPageElement: (route: TRoute, params: AppPageParams, interceptOpts: TInterceptOpts | undefined, searchParams: URLSearchParams, buildOptions?: {
|
|
124
123
|
observeMetadataSearchParamsAccess?: boolean;
|
|
125
124
|
observePageSearchParamsAccess?: boolean;
|
|
126
125
|
}) => Promise<TElement>;
|
|
@@ -130,7 +129,6 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
|
|
|
130
129
|
getRouteParamNames: (route: TRoute) => readonly string[];
|
|
131
130
|
getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
|
|
132
131
|
isRscRequest: boolean;
|
|
133
|
-
layoutParamAccess?: AppLayoutParamAccessTracker;
|
|
134
132
|
resolveNavigationParams: (route: TRoute, params: AppPageParams, pathname: string, interceptOpts: TInterceptOpts) => AppPageParams;
|
|
135
133
|
renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
|
|
136
134
|
resolveSearchParams?: (route: TRoute, searchParams: URLSearchParams) => Awaitable<URLSearchParams>;
|
|
@@ -353,7 +353,7 @@ async function resolveAppPageIntercept(options) {
|
|
|
353
353
|
pathname: options.cleanPathname,
|
|
354
354
|
searchParams: renderSearchParams
|
|
355
355
|
});
|
|
356
|
-
const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams
|
|
356
|
+
const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, renderSearchParams);
|
|
357
357
|
return {
|
|
358
358
|
interceptOpts: void 0,
|
|
359
359
|
response: await options.renderInterceptResponse(renderRoute, interceptElement)
|
|
@@ -2,14 +2,14 @@ import { VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-v
|
|
|
2
2
|
import { NEXT_CACHE_TAGS_HEADER, NEXT_ROUTER_STALE_TIME_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_STALE_TIME_PENDING_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
|
|
3
3
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
|
|
4
4
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
5
|
-
import {
|
|
5
|
+
import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
|
|
6
6
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
7
|
+
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
7
8
|
import { applyPrerenderCacheLifeHeader } from "./prerender-cache-life-header.js";
|
|
8
|
-
import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
|
|
9
9
|
//#region src/server/app-page-response.ts
|
|
10
10
|
function applyTimingHeader(headers, timing) {
|
|
11
11
|
if (!timing) return;
|
|
12
|
-
const handlerStart = Math.round(timing.handlerStart);
|
|
12
|
+
const handlerStart = Math.round(Date.now() - (performance.now() - timing.handlerStart));
|
|
13
13
|
const compileMs = timing.compileEnd !== void 0 ? Math.round(timing.compileEnd - timing.handlerStart) : -1;
|
|
14
14
|
const renderMs = timing.responseKind === "html" && timing.renderEnd !== void 0 && timing.compileEnd !== void 0 ? Math.round(timing.renderEnd - timing.compileEnd) : -1;
|
|
15
15
|
headers.set(VINEXT_TIMING_HEADER, `${handlerStart},${compileMs},${renderMs}`);
|