vinext 1.0.1 → 1.2.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 +93 -10
- package/dist/build/app-page-static-eligibility.d.ts +15 -0
- package/dist/build/app-page-static-eligibility.js +82 -0
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +8 -81
- package/dist/build/prerender.js +33 -8
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/server-manifest.d.ts +7 -0
- package/dist/build/server-manifest.js +11 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.js +7 -6
- package/dist/cli.js +2 -1
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/client/navigation-runtime.d.ts +11 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +81 -82
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +14 -0
- package/dist/config/next-config.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +6 -0
- package/dist/entries/app-rsc-entry.js +84 -49
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +7 -2
- package/dist/index.js +193 -73
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +1 -0
- package/dist/init.js +67 -3
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/cache-flight-codec.d.ts +19 -0
- package/dist/plugins/cache-flight-codec.js +68 -0
- package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
- package/dist/plugins/commonjs-esm-facade.js +80 -0
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +9 -8
- package/dist/plugins/fonts.d.ts +8 -11
- package/dist/plugins/fonts.js +71 -34
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +3 -4
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +262 -98
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.js +8 -2
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +129 -0
- package/dist/routing/file-matcher.d.ts +1 -0
- package/dist/routing/file-matcher.js +1 -1
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +19 -8
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-entry.js +11 -7
- package/dist/server/app-browser-history-controller.d.ts +2 -0
- package/dist/server/app-browser-history-controller.js +8 -0
- package/dist/server/app-browser-interception-context.js +26 -2
- package/dist/server/app-browser-navigation-controller.d.ts +7 -1
- package/dist/server/app-browser-navigation-controller.js +94 -11
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-fallback-renderer.d.ts +2 -0
- package/dist/server/app-fallback-renderer.js +1 -0
- package/dist/server/app-history-state.d.ts +3 -0
- package/dist/server/app-history-state.js +7 -0
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +19 -3
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +5 -0
- package/dist/server/app-page-boundary-render.js +6 -4
- package/dist/server/app-page-cache-finalizer.d.ts +11 -0
- package/dist/server/app-page-cache-finalizer.js +41 -7
- package/dist/server/app-page-cache-render.d.ts +18 -0
- package/dist/server/app-page-cache-render.js +63 -43
- package/dist/server/app-page-cache.d.ts +6 -1
- package/dist/server/app-page-cache.js +28 -8
- package/dist/server/app-page-dispatch.d.ts +12 -2
- package/dist/server/app-page-dispatch.js +51 -33
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +27 -42
- package/dist/server/app-page-execution.d.ts +15 -12
- package/dist/server/app-page-execution.js +30 -40
- package/dist/server/app-page-head.d.ts +5 -0
- package/dist/server/app-page-head.js +9 -3
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-probe.d.ts +0 -109
- package/dist/server/app-page-probe.js +3 -136
- package/dist/server/app-page-render-identity.d.ts +0 -1
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render-observation.js +3 -3
- package/dist/server/app-page-render.d.ts +13 -5
- package/dist/server/app-page-render.js +219 -119
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +54 -17
- package/dist/server/app-page-response.d.ts +4 -3
- package/dist/server/app-page-response.js +4 -3
- package/dist/server/app-page-route-wiring.d.ts +17 -5
- package/dist/server/app-page-route-wiring.js +57 -35
- package/dist/server/app-page-rsc-render-status.d.ts +48 -0
- package/dist/server/app-page-rsc-render-status.js +54 -0
- package/dist/server/app-page-stream.d.ts +15 -8
- package/dist/server/app-page-stream.js +6 -0
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -3
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-request-stage-dispatch.js +7 -3
- package/dist/server/app-request-stage-independent-entry.js +29 -9
- package/dist/server/app-response-header-provenance.d.ts +2 -0
- package/dist/server/app-response-header-provenance.js +10 -4
- package/dist/server/app-response-stage-entry.js +10 -2
- 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 +6 -3
- 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-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +45 -24
- package/dist/server/app-router-entry.js +27 -8
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +11 -0
- package/dist/server/app-rsc-handler.js +291 -125
- package/dist/server/app-rsc-request-normalization.d.ts +3 -1
- package/dist/server/app-rsc-request-normalization.js +4 -2
- package/dist/server/app-rsc-response-stage.d.ts +1 -1
- package/dist/server/app-rsc-response-stage.js +10 -6
- package/dist/server/app-rsc-route-matching.d.ts +9 -1
- package/dist/server/app-rsc-route-matching.js +36 -19
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +62 -23
- package/dist/server/app-ssr-entry.d.ts +3 -2
- package/dist/server/app-ssr-entry.js +8 -5
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +34 -15
- package/dist/server/app-worker-stages.d.ts +7 -2
- package/dist/server/app-worker-stages.js +4 -4
- package/dist/server/cacheability-request.js +11 -7
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/config-headers.js +2 -0
- package/dist/server/dev-server.js +50 -29
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +18 -1
- package/dist/server/headers.js +19 -2
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +54 -0
- package/dist/server/image-optimization.js +118 -9
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +43 -8
- package/dist/server/metadata-route-response.js +9 -8
- package/dist/server/middleware-matcher-pattern.js +8 -4
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-response-headers.js +2 -0
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +33 -20
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +19 -0
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/node-response-signal.d.ts +16 -0
- package/dist/server/node-response-signal.js +26 -0
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/open-redirect.d.ts +47 -0
- package/dist/server/open-redirect.js +74 -1
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +4 -3
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +19 -2
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +50 -120
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +209 -130
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +41 -34
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +37 -18
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +79 -16
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/pages-router-entry.js +4 -3
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +20 -7
- package/dist/server/prod-server.js +343 -129
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +24 -9
- package/dist/server/request-pipeline.js +24 -9
- package/dist/server/response-compression.d.ts +43 -0
- package/dist/server/response-compression.js +111 -0
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.js +31 -2
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +15 -11
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +23 -1
- package/dist/server/socket-error-backstop.js +69 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +86 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
- package/dist/shims/cache-adapter-instantiate.js +118 -0
- package/dist/shims/cache-callable-runtime.d.ts +6 -42
- package/dist/shims/cache-callable-runtime.js +65 -174
- package/dist/shims/cache-flight-arguments.d.ts +22 -0
- package/dist/shims/cache-flight-arguments.js +56 -0
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-request-state.d.ts +15 -0
- package/dist/shims/cache-request-state.js +31 -8
- package/dist/shims/cache-runtime.d.ts +12 -20
- package/dist/shims/cache-runtime.js +166 -225
- package/dist/shims/cache.d.ts +4 -4
- package/dist/shims/cache.js +44 -16
- package/dist/shims/cacheability-classification.d.ts +7 -0
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +19 -1
- package/dist/shims/error-boundary.d.ts +10 -10
- package/dist/shims/error-boundary.js +26 -7
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -61
- package/dist/shims/fetch-cache.js +161 -108
- package/dist/shims/form.js +1 -1
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +15 -13
- package/dist/shims/headers.d.ts +13 -0
- package/dist/shims/headers.js +47 -4
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
- package/dist/shims/internal/app-page-props-cache-key.js +24 -15
- package/dist/shims/internal/headers-state.d.ts +0 -1
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/metadata.js +3 -3
- package/dist/shims/navigation-errors.d.ts +6 -0
- package/dist/shims/navigation-errors.js +11 -1
- package/dist/shims/navigation.d.ts +7 -0
- package/dist/shims/navigation.js +45 -9
- package/dist/shims/request-context.d.ts +11 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +12 -20
- package/dist/shims/server.d.ts +16 -0
- package/dist/shims/server.js +24 -4
- package/dist/shims/thenable-params.d.ts +4 -0
- package/dist/shims/thenable-params.js +25 -3
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/shims/url-utils.d.ts +2 -0
- package/dist/shims/url-utils.js +3 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/mdx-scan.d.ts +5 -0
- package/dist/utils/mdx-scan.js +8 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +4 -0
- package/dist/utils/plugin-rsc-version.js +15 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +3 -0
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/regex-safety.d.ts +10 -0
- package/dist/utils/regex-safety.js +70 -18
- package/package.json +9 -5
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
2
1
|
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
3
|
-
import {
|
|
4
|
-
import "./app-elements.js";
|
|
2
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
5
3
|
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage } from "../shims/headers.js";
|
|
6
4
|
import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
7
5
|
import { consumeDynamicFetchObservations } from "../shims/fetch-cache.js";
|
|
6
|
+
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
7
|
+
import "./app-elements.js";
|
|
8
8
|
import { buildRenderObservation, buildRenderRequestApiObservations } from "./cache-proof.js";
|
|
9
9
|
//#region src/server/app-page-render-observation.ts
|
|
10
10
|
function readRootBoundaryId(element) {
|
|
@@ -23,6 +23,13 @@ type AppPageRequestCacheLife = {
|
|
|
23
23
|
stale?: number;
|
|
24
24
|
};
|
|
25
25
|
type AppPageRenderableElement = ReactNode | Readonly<Record<string, ReactNode>>;
|
|
26
|
+
type AppPageSpecialErrorRenderOptions = {
|
|
27
|
+
/**
|
|
28
|
+
* The document may be stored in place of the page's, so like a cache
|
|
29
|
+
* candidate's render it must not carry the request's query.
|
|
30
|
+
*/
|
|
31
|
+
isCacheCandidate?: boolean;
|
|
32
|
+
};
|
|
26
33
|
type PreparedAppPageElement = {
|
|
27
34
|
element: AppPageRenderableElement;
|
|
28
35
|
response?: never;
|
|
@@ -63,7 +70,6 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
63
70
|
getDraftModeCookieHeader: () => string | null | undefined;
|
|
64
71
|
handlerStart: number;
|
|
65
72
|
hasCustomGlobalError?: boolean;
|
|
66
|
-
hasLoadingBoundary: boolean;
|
|
67
73
|
dynamicStaleTimeSeconds?: number;
|
|
68
74
|
isDynamicError: boolean;
|
|
69
75
|
isDraftMode: boolean;
|
|
@@ -83,9 +89,12 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
83
89
|
isCacheCandidate?: boolean;
|
|
84
90
|
isProgressiveActionRender?: boolean;
|
|
85
91
|
isPrerender?: boolean;
|
|
92
|
+
/** PPR routes send every RSC response as a 200. */
|
|
93
|
+
isRoutePPREnabled?: boolean;
|
|
86
94
|
isSpeculativePrerender?: boolean;
|
|
95
|
+
/** Wait for the whole document before its first byte, as a prerender does. */
|
|
96
|
+
renderWholeDocument?: boolean;
|
|
87
97
|
isProduction: boolean;
|
|
88
|
-
probePageBeforeRender?: boolean;
|
|
89
98
|
omitPendingDynamicCacheState?: boolean;
|
|
90
99
|
isRscRequest: boolean;
|
|
91
100
|
traceOperation?: "prerender" | "render";
|
|
@@ -107,13 +116,12 @@ type RenderAppPageLifecycleOptionsBase = {
|
|
|
107
116
|
rootParams?: RootParams;
|
|
108
117
|
peekRenderObservationState?: () => AppPageRenderObservationState;
|
|
109
118
|
probeLayoutAt: (layoutIndex: number) => unknown;
|
|
110
|
-
probePage: () => unknown;
|
|
111
119
|
expireSeconds?: number;
|
|
112
120
|
formState?: ReactFormState | null;
|
|
113
121
|
revalidateSeconds: number | null;
|
|
114
122
|
renderErrorBoundaryResponse: (error: unknown, errorOrigin: "rsc" | "ssr") => Promise<Response | null>;
|
|
115
123
|
renderLayoutSpecialError: (specialError: AppPageSpecialError, layoutIndex: number) => Promise<Response>;
|
|
116
|
-
renderPageSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
|
|
124
|
+
renderPageSpecialError: (specialError: AppPageSpecialError, renderOptions?: AppPageSpecialErrorRenderOptions) => Promise<Response>;
|
|
117
125
|
renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
|
|
118
126
|
onError: AppPageBoundaryOnError;
|
|
119
127
|
signal?: AbortSignal;
|
|
@@ -150,6 +158,6 @@ type RenderAppPageLifecycleOptions = RenderAppPageLifecycleOptionsBase & ({
|
|
|
150
158
|
* its response policy, such as error boundaries and special errors, get the
|
|
151
159
|
* same header as the normal render.
|
|
152
160
|
*/
|
|
153
|
-
export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce"
|
|
161
|
+
export declare function applyIneligibleRouteCachePolicy(response: Response, options: Pick<RenderAppPageLifecycleOptions, "dynamicStaleTimeSeconds" | "isDraftMode" | "isDynamicError" | "isForceDynamic" | "isForceStatic" | "isProduction" | "isProgressiveActionRender" | "isRscRequest" | "isStaticEligible" | "middlewareContext" | "peekDynamicUsage" | "revalidateSeconds" | "scriptNonce">, probeCacheLife?: AppPageRequestCacheLife | null): Response;
|
|
154
162
|
export declare function renderAppPageLifecycle(options: RenderAppPageLifecycleOptions): Promise<Response>;
|
|
155
163
|
//#endregion
|
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
|
|
2
2
|
import { bindRequestContext } from "../shims/unified-request-context.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
|
+
import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER } from "./headers.js";
|
|
4
5
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
5
6
|
import { isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
|
|
6
7
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, isCdnResponsePolicyHeader } from "./cache-control.js";
|
|
7
|
-
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
8
|
-
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
9
|
-
import "./app-elements.js";
|
|
10
8
|
import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
|
|
11
|
-
import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
|
|
12
|
-
import { peekDynamicUsage } from "../shims/headers.js";
|
|
9
|
+
import { isRenderDynamicLatched, markDynamicUsage } from "../shims/internal/headers-state.js";
|
|
10
|
+
import { peekDynamicUsage, runWithDetachedDynamicUsage } from "../shims/headers.js";
|
|
13
11
|
import { runWithFetchDedupe } from "../shims/fetch-cache.js";
|
|
12
|
+
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
14
13
|
import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
|
|
14
|
+
import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
|
|
15
|
+
import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
|
|
16
|
+
import "./app-elements.js";
|
|
15
17
|
import { isBailoutToCSRError } from "../shims/navigation-errors.js";
|
|
16
18
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
19
|
+
import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
|
|
20
|
+
import { copyLinkHeaderProvenance, getFrameworkLinkHeader } from "./app-response-header-provenance.js";
|
|
21
|
+
import { applyClientStaleTimeHeader, applyEdgeRuntimeHeader, buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy, resolveUncacheableCacheControl } from "./app-page-response.js";
|
|
22
|
+
import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
|
|
20
23
|
import { probeAppPageBeforeRender } from "./app-page-probe.js";
|
|
21
24
|
import { hasDigest } from "./app-rsc-errors.js";
|
|
22
25
|
import { recordAppPageRenderError, traceAppPageRender } from "./app-page-tracing.js";
|
|
23
26
|
import { traceResponseStartWithCompletion } from "./response-start-tracing.js";
|
|
24
27
|
import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRenderObservation, buildRenderRequestApiObservations, createStaticLayoutArtifactReuseDecision } from "./cache-proof.js";
|
|
25
28
|
import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
|
|
29
|
+
import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, createAppPageSsrErrorHandler, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
|
|
30
|
+
import { createAppPageRscRenderStatusResolver } from "./app-page-rsc-render-status.js";
|
|
26
31
|
import { finalizeAppPageCacheabilityEvaluationResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache-finalizer.js";
|
|
27
32
|
import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
|
|
28
33
|
import { appendRscCompletionMetadata } from "./rsc-completion-metadata.js";
|
|
29
|
-
import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, createAppPageSsrErrorHandler, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
|
|
30
34
|
import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
|
|
31
35
|
import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
|
|
32
36
|
//#region src/server/app-page-render.ts
|
|
@@ -70,15 +74,32 @@ function applyRequestCacheLife(options) {
|
|
|
70
74
|
* its response policy, such as error boundaries and special errors, get the
|
|
71
75
|
* same header as the normal render.
|
|
72
76
|
*/
|
|
73
|
-
function applyIneligibleRouteCachePolicy(response, options) {
|
|
77
|
+
function applyIneligibleRouteCachePolicy(response, options, probeCacheLife = null) {
|
|
74
78
|
const cacheControl = resolveEarlyResponseCacheControl(options);
|
|
75
|
-
|
|
79
|
+
const isRscRedirect = options.isRscRequest && response.headers.has("X-Vinext-Rsc-Redirect");
|
|
80
|
+
if (!cacheControl) {
|
|
81
|
+
const staleTimeSeconds = isRscRedirect ? resolveClientStaleTimeSeconds(probeCacheLife) : void 0;
|
|
82
|
+
if (staleTimeSeconds === void 0) return response;
|
|
83
|
+
const stamped = cloneForStamping(response);
|
|
84
|
+
applyClientStaleTimeHeader(stamped.headers, staleTimeSeconds);
|
|
85
|
+
return stamped;
|
|
86
|
+
}
|
|
87
|
+
const dynamicStaleTimeSeconds = isRscRedirect ? options.dynamicStaleTimeSeconds ?? resolveConfiguredDynamicStaleTimeSeconds() : void 0;
|
|
76
88
|
const middlewarePolicy = [...options.middlewareContext.headers ?? []].filter(([name, value]) => isCdnResponsePolicyHeader(name) && response.headers.get(name) === value);
|
|
77
|
-
|
|
89
|
+
const keepsMiddlewareCacheControl = middlewarePolicy.some(([name]) => name === "cache-control");
|
|
90
|
+
if (keepsMiddlewareCacheControl && dynamicStaleTimeSeconds === void 0) return response;
|
|
91
|
+
const stamped = cloneForStamping(response);
|
|
92
|
+
if (!keepsMiddlewareCacheControl) {
|
|
93
|
+
applyCdnResponseHeaders(stamped.headers, { cacheControl });
|
|
94
|
+
for (const [name, value] of middlewarePolicy) stamped.headers.set(name, value);
|
|
95
|
+
}
|
|
96
|
+
if (dynamicStaleTimeSeconds !== void 0) stamped.headers.set(VINEXT_DYNAMIC_STALE_TIME_HEADER, String(dynamicStaleTimeSeconds));
|
|
97
|
+
return stamped;
|
|
98
|
+
}
|
|
99
|
+
/** Some early responses have immutable headers, so stamp a copy. */
|
|
100
|
+
function cloneForStamping(response) {
|
|
78
101
|
const stamped = preserveFullyBufferedBodyMetadata(response, new Response(response.body, response));
|
|
79
102
|
copyLinkHeaderProvenance(response.headers, stamped.headers);
|
|
80
|
-
applyCdnResponseHeaders(stamped.headers, { cacheControl });
|
|
81
|
-
for (const [name, value] of middlewarePolicy) stamped.headers.set(name, value);
|
|
82
103
|
return stamped;
|
|
83
104
|
}
|
|
84
105
|
/** The known-dynamic branches of the RSC and HTML response policies, in their order. */
|
|
@@ -368,32 +389,26 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
368
389
|
}
|
|
369
390
|
return dynamicUsageObserved;
|
|
370
391
|
};
|
|
371
|
-
const
|
|
372
|
-
const probePageBeforeRender = options.isRscRequest || configuredProbePageBeforeRender && !(options.peekDynamicUsage?.() ?? false);
|
|
373
|
-
const preRenderResult = await probeAppPageBeforeRender({
|
|
374
|
-
hasLoadingBoundary: options.hasLoadingBoundary,
|
|
375
|
-
probePageBeforeRender,
|
|
392
|
+
const probeOutcome = await runWithDetachedDynamicUsage(() => probeAppPageBeforeRender({
|
|
376
393
|
skipProbes: options.pprFallbackShellSignal !== void 0,
|
|
377
394
|
layoutCount: options.layoutCount,
|
|
378
395
|
probeLayoutAt(layoutIndex) {
|
|
379
396
|
return options.probeLayoutAt(layoutIndex);
|
|
380
397
|
},
|
|
381
|
-
probePage() {
|
|
382
|
-
return options.probePage();
|
|
383
|
-
},
|
|
384
398
|
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
385
399
|
return options.renderLayoutSpecialError(specialError, layoutIndex);
|
|
386
400
|
},
|
|
387
|
-
renderPageSpecialError(specialError) {
|
|
388
|
-
return options.renderPageSpecialError(specialError);
|
|
389
|
-
},
|
|
390
401
|
resolveSpecialError: resolveAppPageSpecialError,
|
|
391
402
|
runWithSuppressedHookWarning(probe) {
|
|
392
403
|
return options.runWithSuppressedHookWarning(probe);
|
|
393
404
|
},
|
|
394
405
|
classification: options.classification
|
|
395
|
-
});
|
|
396
|
-
|
|
406
|
+
}));
|
|
407
|
+
const preRenderResult = probeOutcome.result;
|
|
408
|
+
if (preRenderResult.response) {
|
|
409
|
+
if (probeOutcome.dynamicDetected) markDynamicUsage();
|
|
410
|
+
return applyIneligibleRouteCachePolicy(preRenderResult.response, options, probeOutcome.cacheLife);
|
|
411
|
+
}
|
|
397
412
|
const layoutFlags = preRenderResult.layoutFlags;
|
|
398
413
|
const artifactCompatibility = createAppPageArtifactCompatibility(options.element, options.routePattern);
|
|
399
414
|
const rootBoundaryId = artifactCompatibility?.rootBoundaryId ?? null;
|
|
@@ -458,7 +473,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
458
473
|
if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
|
|
459
474
|
let revalidateSeconds = options.revalidateSeconds;
|
|
460
475
|
let expireSeconds = options.expireSeconds;
|
|
461
|
-
const shouldWaitForAllReady = options.isPrerender === true && options.isSpeculativePrerender !== true;
|
|
476
|
+
const shouldWaitForAllReady = options.isPrerender === true && options.isSpeculativePrerender !== true || options.renderWholeDocument === true;
|
|
462
477
|
const shouldReadRequestCacheLifeForPrerender = options.isPrerender === true;
|
|
463
478
|
const mayResolveCacheLifeAfterHeaders = options.isProgressiveActionRender !== true && (revalidateSeconds === null || revalidateSeconds > 0) && !options.isDraftMode && !options.isForceDynamic && !shouldBypassRscCache;
|
|
464
479
|
const shouldCaptureRscForCacheMetadata = (options.isProduction || options.isPrerender === true) && mayResolveCacheLifeAfterHeaders && options.isStaticEligible;
|
|
@@ -474,6 +489,16 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
474
489
|
const capturedRscDataRef = { value: null };
|
|
475
490
|
if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
|
|
476
491
|
if (options.isRscRequest) {
|
|
492
|
+
const resolveRscRenderStatus = options.isProduction && shouldCaptureRscForCacheMetadata && capturedRscDataRef.value !== null && options.isPrerender !== true && options.isRoutePPREnabled !== true ? createAppPageRscRenderStatusResolver({
|
|
493
|
+
basePath: options.basePath,
|
|
494
|
+
capturedRscData: capturedRscDataRef.value,
|
|
495
|
+
getCapturedSpecialError: rscErrorTracker.getCapturedSpecialError,
|
|
496
|
+
getCapturedSpecialErrors: rscErrorTracker.getCapturedSpecialErrors,
|
|
497
|
+
isForceStatic: options.isForceStatic,
|
|
498
|
+
loadSsrHandler: options.loadSsrHandler,
|
|
499
|
+
navigationContext: options.getNavigationContext(),
|
|
500
|
+
rootParams: options.rootParams
|
|
501
|
+
}) : void 0;
|
|
477
502
|
let requestCacheLifeForPrerender = null;
|
|
478
503
|
if (shouldWaitForAllReady) await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value);
|
|
479
504
|
if (shouldReadRequestCacheLifeForPrerender) {
|
|
@@ -566,6 +591,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
566
591
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
567
592
|
omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
|
|
568
593
|
renderMode: options.renderMode,
|
|
594
|
+
resolveRscRenderStatus,
|
|
569
595
|
preserveClientResponseHeaders: rscResponsePolicy.cacheState !== "MISS",
|
|
570
596
|
expireSeconds,
|
|
571
597
|
isStaticEligible: options.isStaticEligible,
|
|
@@ -591,6 +617,145 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
591
617
|
let requestCacheLifeForPrerender = null;
|
|
592
618
|
let dynamicUsedDuringHtmlRender = false;
|
|
593
619
|
let renderEnd;
|
|
620
|
+
let shellSpecialError = null;
|
|
621
|
+
const resolveHtmlCacheWrite = (dynamicUsedDuringRender) => {
|
|
622
|
+
const htmlResponsePolicy = resolveAppPageHtmlResponsePolicy({
|
|
623
|
+
dynamicUsedDuringRender,
|
|
624
|
+
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
625
|
+
hasScriptNonce: Boolean(options.scriptNonce),
|
|
626
|
+
isDraftMode: options.isDraftMode,
|
|
627
|
+
isDynamicError: options.isDynamicError,
|
|
628
|
+
isForceDynamic: options.isForceDynamic,
|
|
629
|
+
isForceStatic: options.isForceStatic,
|
|
630
|
+
isProduction: options.isProduction,
|
|
631
|
+
isStaticEligible: options.isStaticEligible,
|
|
632
|
+
expireSeconds,
|
|
633
|
+
revalidateSeconds
|
|
634
|
+
});
|
|
635
|
+
const shouldSpeculativelyWriteCache = options.isProduction && shouldCaptureRscForCacheMetadata && !options.isEdgeRuntime && revalidateSeconds === null && !options.isDynamicError && !options.isForceStatic && !options.scriptNonce && options.isProgressiveActionRender !== true && !dynamicUsedDuringRender;
|
|
636
|
+
return {
|
|
637
|
+
htmlResponsePolicy,
|
|
638
|
+
shouldWriteHtmlCache: htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache
|
|
639
|
+
};
|
|
640
|
+
};
|
|
641
|
+
const finalizeHtmlCacheWrite = (response, write) => finalizeAppPageHtmlCacheResponse(response, {
|
|
642
|
+
bypassInterceptionContextCache: options.bypassInterceptionContextCache,
|
|
643
|
+
capturedDynamicUsageBeforeContextCleanup: write.capturedDynamicUsageBeforeContextCleanup,
|
|
644
|
+
capturedRscDataPromise: capturedRscDataRef.value,
|
|
645
|
+
cleanPathname: options.cleanPathname,
|
|
646
|
+
clientTraceMetadataMarker,
|
|
647
|
+
consumeDynamicUsage: consumeRenderDynamicUsage,
|
|
648
|
+
consumeRenderObservationState,
|
|
649
|
+
createHtmlRenderObservation(input) {
|
|
650
|
+
return createAppPageRenderObservation({
|
|
651
|
+
boundaryOutcome: { kind: "success" },
|
|
652
|
+
cacheability: "public",
|
|
653
|
+
cacheTags: input.cacheTags,
|
|
654
|
+
cleanPathname: options.cleanPathname,
|
|
655
|
+
completeness: "complete",
|
|
656
|
+
output: htmlOutputScope,
|
|
657
|
+
params: options.navigationParams,
|
|
658
|
+
state: input.state
|
|
659
|
+
});
|
|
660
|
+
},
|
|
661
|
+
createRscRenderObservation(input) {
|
|
662
|
+
return createAppPageRenderObservation({
|
|
663
|
+
boundaryOutcome: { kind: "success" },
|
|
664
|
+
cacheability: "public",
|
|
665
|
+
cacheTags: input.cacheTags,
|
|
666
|
+
cleanPathname: options.cleanPathname,
|
|
667
|
+
completeness: "complete",
|
|
668
|
+
output: rscOutputScope,
|
|
669
|
+
params: options.navigationParams,
|
|
670
|
+
state: input.state
|
|
671
|
+
});
|
|
672
|
+
},
|
|
673
|
+
getPageTags() {
|
|
674
|
+
return options.getPageTags();
|
|
675
|
+
},
|
|
676
|
+
getRequestCacheLife() {
|
|
677
|
+
return readRequestCacheLifeForCachePolicy(options);
|
|
678
|
+
},
|
|
679
|
+
headers: write.headers,
|
|
680
|
+
isrDebug: options.isrDebug,
|
|
681
|
+
isrHtmlKey: options.isrHtmlKey,
|
|
682
|
+
isrRscKey: options.isrRscKey,
|
|
683
|
+
isrSet: options.isrSet,
|
|
684
|
+
interceptionContext: options.interceptionContext,
|
|
685
|
+
interceptionId: options.interceptionId,
|
|
686
|
+
omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
|
|
687
|
+
preserveClientResponseHeaders: !write.htmlResponsePolicy.shouldWriteToCache,
|
|
688
|
+
expireSeconds,
|
|
689
|
+
isStaticEligible: options.isStaticEligible,
|
|
690
|
+
revalidateSeconds: resolveAppPageCacheWriteRevalidateSeconds({
|
|
691
|
+
isDynamicError: options.isDynamicError,
|
|
692
|
+
isForceStatic: options.isForceStatic,
|
|
693
|
+
isStaticEligible: options.isStaticEligible,
|
|
694
|
+
revalidateSeconds
|
|
695
|
+
}),
|
|
696
|
+
linkHeader: write.linkHeader,
|
|
697
|
+
status: write.status,
|
|
698
|
+
waitUntil(cachePromise) {
|
|
699
|
+
options.waitUntil?.(cachePromise);
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
const mayStoreShellSpecialError = () => options.isProduction && shouldCaptureRscForCacheMetadata && options.isPrerender !== true && capturedRscDataRef.value !== null && resolveEarlyResponseCacheControl(options) === null;
|
|
703
|
+
const mayPrerenderShellSpecialError = () => options.isPrerender === true && options.isSpeculativePrerender !== true && options.pprFallbackShellSignal === void 0 && shouldCaptureRscForCacheMetadata && capturedRscDataRef.value !== null && resolveEarlyResponseCacheControl(options) === null;
|
|
704
|
+
const readPrerenderCacheMetadata = () => ({
|
|
705
|
+
cacheTags: options.getPageTags(),
|
|
706
|
+
requestCacheLife: readRequestCacheLifeForPrerender(options)
|
|
707
|
+
});
|
|
708
|
+
let prerenderedSpecialError = null;
|
|
709
|
+
const finalizePrerenderedShellSpecialErrorResponse = async (response, specialError, prerendered) => {
|
|
710
|
+
if (response.status !== specialError.statusCode) return applyIneligibleRouteCachePolicy(response, options);
|
|
711
|
+
const body = await response.arrayBuffer();
|
|
712
|
+
const { cacheTags, requestCacheLife } = prerendered.redirectMetadata ?? readPrerenderCacheMetadata();
|
|
713
|
+
({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
|
|
714
|
+
expireSeconds,
|
|
715
|
+
requestCacheLife,
|
|
716
|
+
revalidateSeconds
|
|
717
|
+
}));
|
|
718
|
+
const { htmlResponsePolicy } = resolveHtmlCacheWrite(prerendered.dynamicUsed || consumeRenderDynamicUsage());
|
|
719
|
+
const headers = new Headers(response.headers);
|
|
720
|
+
if (htmlResponsePolicy.cacheControl && !headers.has("cache-control")) headers.set("Cache-Control", htmlResponsePolicy.cacheControl);
|
|
721
|
+
applyPrerenderCacheLifeHeader(headers, requestCacheLife);
|
|
722
|
+
applyPrerenderCacheTagsHeader(headers, cacheTags);
|
|
723
|
+
getRequestExecutionContext()?.recordPrerenderSpecialError?.({
|
|
724
|
+
headers: resolveAppPageSpecialErrorStoredHeaders(specialError, options.basePath) ?? {},
|
|
725
|
+
status: response.status
|
|
726
|
+
});
|
|
727
|
+
const prerenderResponse = new Response(body, {
|
|
728
|
+
headers,
|
|
729
|
+
status: response.status,
|
|
730
|
+
statusText: response.statusText
|
|
731
|
+
});
|
|
732
|
+
copyLinkHeaderProvenance(response.headers, prerenderResponse.headers);
|
|
733
|
+
return prerenderResponse;
|
|
734
|
+
};
|
|
735
|
+
const finalizeShellSpecialErrorResponse = (response, specialError) => {
|
|
736
|
+
if (response.status !== specialError.statusCode) return applyIneligibleRouteCachePolicy(response, options);
|
|
737
|
+
const dynamicUsedDuringRender = consumeRenderDynamicUsage();
|
|
738
|
+
const { htmlResponsePolicy, shouldWriteHtmlCache } = resolveHtmlCacheWrite(dynamicUsedDuringRender);
|
|
739
|
+
const headers = new Headers(response.headers);
|
|
740
|
+
if (htmlResponsePolicy.cacheControl && !headers.has("cache-control")) headers.set("Cache-Control", htmlResponsePolicy.cacheControl);
|
|
741
|
+
if (htmlResponsePolicy.cacheState) setCacheStateHeaders(headers, htmlResponsePolicy.cacheState);
|
|
742
|
+
const policyResponse = new Response(response.body, {
|
|
743
|
+
headers,
|
|
744
|
+
status: response.status,
|
|
745
|
+
statusText: response.statusText
|
|
746
|
+
});
|
|
747
|
+
copyLinkHeaderProvenance(response.headers, policyResponse.headers);
|
|
748
|
+
if (!shouldWriteHtmlCache) return policyResponse;
|
|
749
|
+
const clientResponse = finalizeHtmlCacheWrite(policyResponse, {
|
|
750
|
+
capturedDynamicUsageBeforeContextCleanup: () => dynamicUsedDuringRender,
|
|
751
|
+
headers: resolveAppPageSpecialErrorStoredHeaders(specialError, options.basePath),
|
|
752
|
+
htmlResponsePolicy,
|
|
753
|
+
linkHeader: getFrameworkLinkHeader(response.headers),
|
|
754
|
+
status: response.status
|
|
755
|
+
});
|
|
756
|
+
copyLinkHeaderProvenance(response.headers, clientResponse.headers);
|
|
757
|
+
return clientResponse;
|
|
758
|
+
};
|
|
594
759
|
const htmlRender = await renderAppPageHtmlStreamWithRecovery({
|
|
595
760
|
onShellRendered() {
|
|
596
761
|
if (!options.isProduction) renderEnd = performance.now();
|
|
@@ -657,30 +822,34 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
657
822
|
isStaticGeneration: options.isPrerender === true,
|
|
658
823
|
isForceStatic: options.isForceStatic,
|
|
659
824
|
isCacheCandidate: isCacheCandidateHtmlRender,
|
|
660
|
-
onSsrError: createAppPageSsrErrorHandler(onSsrError, rscErrorTracker.isCapturedError)
|
|
825
|
+
onSsrError: createAppPageSsrErrorHandler(onSsrError, rscErrorTracker.isCapturedError),
|
|
826
|
+
mirrorNextFlight: () => rscErrorTracker.getCapturedSpecialError() !== null
|
|
661
827
|
});
|
|
662
828
|
},
|
|
663
|
-
renderSpecialErrorResponse(specialError) {
|
|
664
|
-
|
|
829
|
+
async renderSpecialErrorResponse(specialError) {
|
|
830
|
+
shellSpecialError = specialError;
|
|
831
|
+
const mayPrerender = mayPrerenderShellSpecialError();
|
|
832
|
+
if (mayStoreShellSpecialError() || mayPrerender) await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value, peekRenderDynamicUsage);
|
|
833
|
+
if (mayPrerender) prerenderedSpecialError = {
|
|
834
|
+
dynamicUsed: consumeRenderDynamicUsage(),
|
|
835
|
+
redirectMetadata: specialError.kind === "redirect" ? readPrerenderCacheMetadata() : null
|
|
836
|
+
};
|
|
837
|
+
return options.renderPageSpecialError(specialError, { isCacheCandidate: isCacheCandidateHtmlRender });
|
|
665
838
|
},
|
|
666
|
-
resolveSpecialError
|
|
839
|
+
resolveSpecialError(error) {
|
|
840
|
+
return resolveAppPageShellSpecialError(error, rscErrorTracker.getCapturedSpecialErrors(error));
|
|
841
|
+
}
|
|
667
842
|
});
|
|
668
843
|
options.onRenderComplete?.(htmlRender.renderComplete);
|
|
669
|
-
if (htmlRender.response)
|
|
844
|
+
if (htmlRender.response) {
|
|
845
|
+
if (shellSpecialError && options.isProduction && options.isPrerender !== true && resolveEarlyResponseCacheControl(options) === null) return finalizeShellSpecialErrorResponse(htmlRender.response, shellSpecialError);
|
|
846
|
+
if (shellSpecialError && prerenderedSpecialError) return finalizePrerenderedShellSpecialErrorResponse(htmlRender.response, shellSpecialError, prerenderedSpecialError);
|
|
847
|
+
return applyIneligibleRouteCachePolicy(htmlRender.response, options);
|
|
848
|
+
}
|
|
670
849
|
let htmlStream = htmlRender.htmlStream;
|
|
671
850
|
if (!htmlStream) throw new Error("[vinext] Expected an HTML stream when no fallback response was returned");
|
|
672
851
|
const linkHeader = buildAppPageLinkHeader(htmlRender.linkHeader, fontLinkHeader, options.reactMaxHeadersLength);
|
|
673
852
|
if (options.isPrerender === true) await htmlRender.metadataReady;
|
|
674
|
-
if (options.hasLoadingBoundary || !probePageBeforeRender) {
|
|
675
|
-
const captured = rscErrorTracker.getCapturedSpecialError();
|
|
676
|
-
if (captured) {
|
|
677
|
-
const specialError = resolveAppPageSpecialError(captured);
|
|
678
|
-
if (specialError) {
|
|
679
|
-
htmlStream.cancel().catch(() => {});
|
|
680
|
-
return applyIneligibleRouteCachePolicy(await options.renderPageSpecialError(specialError), options);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
853
|
let dynamicUsedDuringRender = consumeRenderDynamicUsage();
|
|
685
854
|
dynamicUsedDuringHtmlRender = dynamicUsedDuringRender;
|
|
686
855
|
const stopSpeculativeMetadataWaitOnDynamicUsage = options.isSpeculativePrerender === true && shouldReadRequestCacheLifeForPrerender ? () => {
|
|
@@ -710,19 +879,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
710
879
|
dynamicUsedDuringHtmlRender = dynamicUsedBeforeContextCleanup;
|
|
711
880
|
options.clearRequestContext();
|
|
712
881
|
});
|
|
713
|
-
const htmlResponsePolicy =
|
|
714
|
-
dynamicUsedDuringRender,
|
|
715
|
-
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
716
|
-
hasScriptNonce: Boolean(options.scriptNonce),
|
|
717
|
-
isDraftMode: options.isDraftMode,
|
|
718
|
-
isDynamicError: options.isDynamicError,
|
|
719
|
-
isForceDynamic: options.isForceDynamic,
|
|
720
|
-
isForceStatic: options.isForceStatic,
|
|
721
|
-
isProduction: options.isProduction,
|
|
722
|
-
isStaticEligible: options.isStaticEligible,
|
|
723
|
-
expireSeconds,
|
|
724
|
-
revalidateSeconds
|
|
725
|
-
});
|
|
882
|
+
const { htmlResponsePolicy, shouldWriteHtmlCache } = resolveHtmlCacheWrite(dynamicUsedDuringRender);
|
|
726
883
|
const htmlResponseTiming = buildResponseTiming({
|
|
727
884
|
compileEnd,
|
|
728
885
|
handlerStart: options.handlerStart,
|
|
@@ -747,8 +904,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
747
904
|
applyCdnResponseHeaders(response.headers, { cacheControl: NEVER_CACHE_CONTROL });
|
|
748
905
|
return response;
|
|
749
906
|
}
|
|
750
|
-
|
|
751
|
-
if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
|
|
907
|
+
if (shouldWriteHtmlCache) {
|
|
752
908
|
const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
753
909
|
cacheTags: options.isPrerender === true ? options.getPageTags() : void 0,
|
|
754
910
|
draftCookie,
|
|
@@ -760,66 +916,10 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
760
916
|
timing: htmlResponseTiming
|
|
761
917
|
});
|
|
762
918
|
if (options.isPrerender === true) return isrResponse;
|
|
763
|
-
return
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
},
|
|
768
|
-
capturedRscDataPromise: capturedRscDataRef.value,
|
|
769
|
-
cleanPathname: options.cleanPathname,
|
|
770
|
-
clientTraceMetadataMarker,
|
|
771
|
-
consumeDynamicUsage: consumeRenderDynamicUsage,
|
|
772
|
-
consumeRenderObservationState,
|
|
773
|
-
createHtmlRenderObservation(input) {
|
|
774
|
-
return createAppPageRenderObservation({
|
|
775
|
-
boundaryOutcome: { kind: "success" },
|
|
776
|
-
cacheability: "public",
|
|
777
|
-
cacheTags: input.cacheTags,
|
|
778
|
-
cleanPathname: options.cleanPathname,
|
|
779
|
-
completeness: "complete",
|
|
780
|
-
output: htmlOutputScope,
|
|
781
|
-
params: options.navigationParams,
|
|
782
|
-
state: input.state
|
|
783
|
-
});
|
|
784
|
-
},
|
|
785
|
-
createRscRenderObservation(input) {
|
|
786
|
-
return createAppPageRenderObservation({
|
|
787
|
-
boundaryOutcome: { kind: "success" },
|
|
788
|
-
cacheability: "public",
|
|
789
|
-
cacheTags: input.cacheTags,
|
|
790
|
-
cleanPathname: options.cleanPathname,
|
|
791
|
-
completeness: "complete",
|
|
792
|
-
output: rscOutputScope,
|
|
793
|
-
params: options.navigationParams,
|
|
794
|
-
state: input.state
|
|
795
|
-
});
|
|
796
|
-
},
|
|
797
|
-
getPageTags() {
|
|
798
|
-
return options.getPageTags();
|
|
799
|
-
},
|
|
800
|
-
getRequestCacheLife() {
|
|
801
|
-
return readRequestCacheLifeForCachePolicy(options);
|
|
802
|
-
},
|
|
803
|
-
isrDebug: options.isrDebug,
|
|
804
|
-
isrHtmlKey: options.isrHtmlKey,
|
|
805
|
-
isrRscKey: options.isrRscKey,
|
|
806
|
-
isrSet: options.isrSet,
|
|
807
|
-
interceptionContext: options.interceptionContext,
|
|
808
|
-
interceptionId: options.interceptionId,
|
|
809
|
-
omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
|
|
810
|
-
preserveClientResponseHeaders: !htmlResponsePolicy.shouldWriteToCache,
|
|
811
|
-
expireSeconds,
|
|
812
|
-
isStaticEligible: options.isStaticEligible,
|
|
813
|
-
revalidateSeconds: resolveAppPageCacheWriteRevalidateSeconds({
|
|
814
|
-
isDynamicError: options.isDynamicError,
|
|
815
|
-
isForceStatic: options.isForceStatic,
|
|
816
|
-
isStaticEligible: options.isStaticEligible,
|
|
817
|
-
revalidateSeconds
|
|
818
|
-
}),
|
|
819
|
-
linkHeader: linkHeader ?? null,
|
|
820
|
-
waitUntil(cachePromise) {
|
|
821
|
-
options.waitUntil?.(cachePromise);
|
|
822
|
-
}
|
|
919
|
+
return finalizeHtmlCacheWrite(isrResponse, {
|
|
920
|
+
capturedDynamicUsageBeforeContextCleanup: () => dynamicUsedBeforeContextCleanup,
|
|
921
|
+
htmlResponsePolicy,
|
|
922
|
+
linkHeader: linkHeader ?? null
|
|
823
923
|
});
|
|
824
924
|
}
|
|
825
925
|
const response = buildAppPageHtmlResponse(safeHtmlStream, {
|
|
@@ -49,7 +49,6 @@ type ResolveAppPageGenerateStaticParamsSourcesOptions = {
|
|
|
49
49
|
};
|
|
50
50
|
type BuildAppPageElementOptions<TElement> = {
|
|
51
51
|
buildPageElement: () => Promise<TElement>;
|
|
52
|
-
probePageSpecialError?: () => Promise<AppPageSpecialError | null>;
|
|
53
52
|
renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
|
|
54
53
|
renderSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
|
|
55
54
|
resolveSpecialError: (error: unknown) => AppPageSpecialError | null;
|
|
@@ -183,24 +183,62 @@ async function generateIndependentStaticParams(sources, primaryParams, requestPa
|
|
|
183
183
|
validated
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
function isStaticParamsRowConsistentWithRequest(row, requestParams) {
|
|
187
|
+
const sharedKeys = Object.keys(row).filter((key) => requestParams[key] !== void 0);
|
|
188
|
+
return areStaticParamsAllowed(requestParams, [row], false, sharedKeys);
|
|
189
|
+
}
|
|
190
|
+
function rewritesParentParams(parentParams, item) {
|
|
191
|
+
return Object.keys(item).some((key) => Object.hasOwn(parentParams, key) && JSON.stringify(item[key]) !== JSON.stringify(parentParams[key]));
|
|
192
|
+
}
|
|
193
|
+
async function generateChainedStaticParams(sources, requestParams, results = /* @__PURE__ */ new Map()) {
|
|
194
|
+
let generatedRows = [];
|
|
195
|
+
let skippedParents = false;
|
|
196
|
+
let needsEveryCombination = false;
|
|
188
197
|
for (const source of sources) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
let sourceResults = results.get(source);
|
|
199
|
+
if (!sourceResults) {
|
|
200
|
+
sourceResults = /* @__PURE__ */ new Map();
|
|
201
|
+
results.set(source, sourceResults);
|
|
202
|
+
}
|
|
203
|
+
const hasParentParams = generatedRows.length > 0;
|
|
204
|
+
let parents = hasParentParams ? generatedRows : [{
|
|
205
|
+
params: {},
|
|
206
|
+
lineage: ""
|
|
207
|
+
}];
|
|
208
|
+
const nextRows = [];
|
|
209
|
+
if (requestParams) {
|
|
210
|
+
const consistent = parents.filter((row) => isStaticParamsRowConsistentWithRequest(row.params, requestParams));
|
|
211
|
+
parents = consistent.length > 0 ? consistent : parents.slice(0, 1);
|
|
212
|
+
}
|
|
213
|
+
if (hasParentParams && parents.length < generatedRows.length) skippedParents = true;
|
|
214
|
+
for (const parent of parents) {
|
|
215
|
+
let result = sourceResults.get(parent.lineage);
|
|
216
|
+
if (!sourceResults.has(parent.lineage)) {
|
|
217
|
+
result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parent.params }));
|
|
218
|
+
sourceResults.set(parent.lineage, result);
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(result) && result.length > 0) result.forEach((item, index) => {
|
|
221
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) return;
|
|
222
|
+
const row = item;
|
|
223
|
+
if (skippedParents && rewritesParentParams(parent.params, row)) needsEveryCombination = true;
|
|
224
|
+
nextRows.push({
|
|
225
|
+
params: {
|
|
226
|
+
...parent.params,
|
|
227
|
+
...row
|
|
228
|
+
},
|
|
229
|
+
lineage: `${parent.lineage}/${index}`
|
|
198
230
|
});
|
|
199
|
-
}
|
|
231
|
+
});
|
|
232
|
+
else if (hasParentParams) nextRows.push({
|
|
233
|
+
params: parent.params,
|
|
234
|
+
lineage: `${parent.lineage}/-`
|
|
235
|
+
});
|
|
200
236
|
}
|
|
201
|
-
|
|
237
|
+
if (skippedParents && nextRows.length === 0) needsEveryCombination = true;
|
|
238
|
+
generatedRows = nextRows;
|
|
202
239
|
}
|
|
203
|
-
return
|
|
240
|
+
if (needsEveryCombination) return generateChainedStaticParams(sources, null, results);
|
|
241
|
+
return generatedRows.map((row) => row.params);
|
|
204
242
|
}
|
|
205
243
|
function normalizeGenerateStaticParams(generateStaticParams) {
|
|
206
244
|
return (Array.isArray(generateStaticParams) ? generateStaticParams : [generateStaticParams]).flatMap((source) => {
|
|
@@ -218,7 +256,7 @@ async function validateAppPageDynamicParams(options) {
|
|
|
218
256
|
if (generateStaticParamsSources.length === 0) return notFoundResponse();
|
|
219
257
|
const chainedSources = generateStaticParamsSources.filter((source) => source.chained);
|
|
220
258
|
let chainedStaticParams = null;
|
|
221
|
-
if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources);
|
|
259
|
+
if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources, generateStaticParamsSources.some((source) => !source.chained) ? null : options.params);
|
|
222
260
|
const independentChains = /* @__PURE__ */ new Map();
|
|
223
261
|
for (const source of generateStaticParamsSources.filter((source) => !source.chained)) {
|
|
224
262
|
const chain = independentChains.get(source.independentChain ?? source) ?? [];
|
|
@@ -333,8 +371,7 @@ async function buildAppPageElement(options) {
|
|
|
333
371
|
response: null
|
|
334
372
|
};
|
|
335
373
|
} catch (error) {
|
|
336
|
-
const
|
|
337
|
-
const specialError = (buildSpecialError ? await options.probePageSpecialError?.() : null) ?? buildSpecialError;
|
|
374
|
+
const specialError = options.resolveSpecialError(error);
|
|
338
375
|
if (specialError) return {
|
|
339
376
|
element: null,
|
|
340
377
|
response: await options.renderSpecialError(specialError)
|
|
@@ -71,9 +71,10 @@ type BuildAppPageHtmlResponseOptions = {
|
|
|
71
71
|
timing?: AppPageResponseTiming;
|
|
72
72
|
};
|
|
73
73
|
/**
|
|
74
|
-
* Only ever set from a *completed* render's cacheLife (cache replay
|
|
75
|
-
* prerender seed) — `use cache` scopes
|
|
76
|
-
* so a streaming response can never
|
|
74
|
+
* Only ever set from a *completed* render's cacheLife (cache replay,
|
|
75
|
+
* prerender seed, or a layout probe's early redirect) — `use cache` scopes
|
|
76
|
+
* keep resolving after headers commit, so a streaming response can never
|
|
77
|
+
* carry it.
|
|
77
78
|
*/
|
|
78
79
|
export declare function applyClientStaleTimeHeader(headers: Headers, staleTimeSeconds: number | undefined): void;
|
|
79
80
|
/**
|