vinext 1.0.0 → 1.1.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 +72 -1
- package/THIRD_PARTY_LICENSES.md +26 -0
- package/dist/build/app-page-static-eligibility.d.ts +15 -0
- package/dist/build/app-page-static-eligibility.js +82 -0
- package/dist/build/lifecycle.js +10 -10
- package/dist/build/pages-client-assets-module.js +6 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.js +6 -85
- package/dist/build/prerender.d.ts +8 -1
- package/dist/build/prerender.js +167 -46
- package/dist/build/run-prerender.js +4 -3
- package/dist/build/server-entry.d.ts +2 -0
- package/dist/build/server-entry.js +7 -1
- package/dist/build/server-manifest.d.ts +7 -0
- package/dist/build/server-manifest.js +11 -1
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/client/browser-globals.d.ts +4 -0
- package/dist/client/browser-globals.js +5 -0
- package/dist/client/navigation-runtime.d.ts +11 -1
- package/dist/client/navigation-runtime.js +3 -3
- package/dist/config/config-matchers.js +3 -1
- package/dist/config/dotenv.js +14 -3
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +18 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +67 -45
- package/dist/index.d.ts +4 -1
- package/dist/index.js +200 -100
- package/dist/init-cloudflare.d.ts +1 -1
- package/dist/init-cloudflare.js +6 -6
- package/dist/init-platform.js +1 -1
- package/dist/init.js +4 -2
- 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/commonjs-syntax.d.ts +16 -0
- package/dist/plugins/commonjs-syntax.js +22 -0
- package/dist/plugins/fonts.d.ts +8 -11
- package/dist/plugins/fonts.js +71 -34
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +54 -3
- package/dist/plugins/import-meta-url.js +6 -6
- package/dist/plugins/og-asset-ownership.d.ts +2 -0
- package/dist/plugins/og-asset-ownership.js +24 -13
- package/dist/plugins/og-assets.d.ts +18 -0
- package/dist/plugins/og-assets.js +50 -8
- package/dist/plugins/og-harfbuzz.js +38 -27
- package/dist/plugins/optimize-imports.js +2 -1
- package/dist/plugins/require-context.d.ts +1 -0
- package/dist/plugins/require-context.js +28 -1
- package/dist/plugins/scan-build-css.d.ts +12 -0
- package/dist/plugins/scan-build-css.js +39 -0
- package/dist/plugins/strip-server-exports.d.ts +2 -0
- package/dist/plugins/strip-server-exports.js +3 -1
- package/dist/plugins/transform-result.d.ts +18 -0
- package/dist/plugins/transform-result.js +23 -2
- package/dist/plugins/typeof-window.d.ts +10 -0
- package/dist/plugins/typeof-window.js +33 -9
- package/dist/routing/app-route-graph.d.ts +0 -1
- package/dist/routing/app-route-graph.js +2 -4
- package/dist/routing/app-route-ids.d.ts +3 -0
- package/dist/routing/app-route-ids.js +6 -0
- package/dist/routing/file-matcher.d.ts +1 -0
- package/dist/routing/file-matcher.js +1 -1
- package/dist/server/api-handler.js +17 -7
- package/dist/server/app-bfcache-id.d.ts +1 -0
- package/dist/server/app-bfcache-id.js +7 -1
- package/dist/server/app-bfcache-identity.js +1 -2
- package/dist/server/app-browser-entry.js +15 -9
- 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-hydration.d.ts +1 -1
- package/dist/server/app-browser-hydration.js +2 -2
- 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-state.js +1 -1
- package/dist/server/app-browser-stream.d.ts +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 -1
- package/dist/server/app-history-state.js +9 -5
- package/dist/server/app-middleware.js +2 -1
- 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 +65 -44
- package/dist/server/app-page-cache.d.ts +5 -0
- package/dist/server/app-page-cache.js +27 -7
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +47 -30
- 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-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 +2 -2
- package/dist/server/app-page-render.d.ts +13 -5
- package/dist/server/app-page-render.js +219 -118
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +1 -2
- 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 +55 -33
- 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-search-params-observation.js +1 -1
- package/dist/server/app-page-stream.d.ts +15 -8
- package/dist/server/app-page-stream.js +7 -1
- package/dist/server/app-page-tracing.js +2 -1
- package/dist/server/app-pages-bridge.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +3 -0
- package/dist/server/app-render-abort-error.js +8 -0
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +8 -11
- 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-route-handler-cache.d.ts +2 -1
- package/dist/server/app-route-handler-cache.js +11 -7
- package/dist/server/app-route-handler-dispatch.js +11 -4
- package/dist/server/app-route-handler-execution.d.ts +9 -1
- package/dist/server/app-route-handler-execution.js +28 -13
- package/dist/server/app-route-handler-policy.js +2 -2
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-handler-response.js +14 -5
- package/dist/server/app-router-entry.d.ts +2 -1
- package/dist/server/app-router-entry.js +8 -12
- package/dist/server/app-rsc-errors.d.ts +0 -1
- package/dist/server/app-rsc-errors.js +2 -6
- package/dist/server/app-rsc-handler.d.ts +5 -0
- package/dist/server/app-rsc-handler.js +229 -102
- package/dist/server/app-rsc-request-normalization.d.ts +4 -2
- package/dist/server/app-rsc-request-normalization.js +7 -4
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.d.ts +1 -1
- package/dist/server/app-rsc-response-stage.js +6 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -1
- package/dist/server/app-rsc-route-matching.js +37 -20
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.d.ts +3 -2
- package/dist/server/app-ssr-entry.js +9 -7
- package/dist/server/app-ssr-search-params-gate.js +1 -1
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +35 -16
- package/dist/server/app-worker-stages.d.ts +2 -2
- package/dist/server/app-worker-stages.js +3 -3
- package/dist/server/cache-control.js +3 -11
- package/dist/server/cacheability-request.js +56 -52
- package/dist/server/config-headers.js +3 -1
- package/dist/server/dev-server.js +23 -5
- package/dist/server/headers.d.ts +16 -0
- package/dist/server/headers.js +19 -1
- package/dist/server/http-error-responses.js +1 -0
- package/dist/server/image-optimization.d.ts +16 -0
- package/dist/server/image-optimization.js +26 -6
- package/dist/server/isr-cache.d.ts +2 -0
- package/dist/server/isr-cache.js +8 -3
- package/dist/server/metadata-route-response.js +94 -37
- package/dist/server/middleware-matcher-pattern.js +8 -4
- package/dist/server/middleware-response-headers.js +2 -0
- package/dist/server/multi-stage.d.ts +8 -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/open-redirect.d.ts +47 -0
- package/dist/server/open-redirect.js +74 -1
- package/dist/server/pages-api-route.js +8 -2
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +73 -22
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-page-data.d.ts +6 -1
- package/dist/server/pages-page-data.js +71 -65
- package/dist/server/pages-page-handler.js +50 -15
- package/dist/server/pages-page-response.js +3 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -1
- package/dist/server/pages-request-pipeline.js +20 -5
- package/dist/server/pages-request-stage-entry.js +14 -8
- package/dist/server/prerender-manifest.d.ts +6 -0
- package/dist/server/prerender-manifest.js +1 -1
- package/dist/server/prod-server.d.ts +8 -7
- package/dist/server/prod-server.js +152 -78
- package/dist/server/request-pipeline.d.ts +20 -8
- package/dist/server/request-pipeline.js +21 -7
- package/dist/server/response-compression.d.ts +43 -0
- package/dist/server/response-compression.js +111 -0
- package/dist/server/response-stage-cacheability.js +1 -1
- package/dist/server/seed-cache.js +10 -7
- package/dist/server/socket-error-backstop.d.ts +14 -0
- package/dist/server/socket-error-backstop.js +27 -4
- package/dist/server/worker-revalidation-context.d.ts +2 -1
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +48 -8
- 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 +2 -40
- package/dist/shims/cache-callable-runtime.js +50 -168
- package/dist/shims/cache-flight-arguments.d.ts +22 -0
- package/dist/shims/cache-flight-arguments.js +56 -0
- package/dist/shims/cache-request-state.d.ts +18 -14
- package/dist/shims/cache-request-state.js +33 -21
- package/dist/shims/cache-runtime.d.ts +6 -19
- package/dist/shims/cache-runtime.js +168 -226
- package/dist/shims/cache.d.ts +3 -2
- package/dist/shims/cache.js +8 -5
- package/dist/shims/cacheability-classification.d.ts +8 -1
- package/dist/shims/cacheability-classification.js +2 -2
- package/dist/shims/cdn-cache.d.ts +10 -1
- package/dist/shims/cdn-cache.js +16 -9
- 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/error.d.ts +4 -18
- package/dist/shims/error.js +17 -10
- package/dist/shims/error.react-server.d.ts +4 -6
- package/dist/shims/error.react-server.js +4 -1
- package/dist/shims/fetch-cache.d.ts +6 -0
- package/dist/shims/fetch-cache.js +23 -4
- package/dist/shims/form.js +1 -1
- package/dist/shims/headers.d.ts +19 -69
- package/dist/shims/headers.js +82 -183
- 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/cache-context-accessor.d.ts +16 -0
- package/dist/shims/internal/cache-context-accessor.js +15 -0
- package/dist/shims/internal/headers-state.d.ts +73 -0
- package/dist/shims/internal/headers-state.js +157 -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 +16 -6
- package/dist/shims/request-context.d.ts +9 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.js +1 -1
- package/dist/shims/server.js +52 -2
- 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/utils/encode-cache-tag.d.ts +1 -0
- package/dist/utils/encode-cache-tag.js +11 -1
- package/dist/utils/mdx-scan.d.ts +5 -0
- package/dist/utils/mdx-scan.js +8 -1
- package/dist/utils/regex-safety.d.ts +10 -0
- package/dist/utils/regex-safety.js +70 -18
- package/dist/utils/vite-cli-invocation.js +8 -1
- package/package.json +8 -4
- package/dist/server/metadata-route-cache-policy.d.ts +0 -5
- package/dist/server/metadata-route-cache-policy.js +0 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
|
|
2
|
+
import { consumeDynamicUsage, consumeInvalidDynamicUsageError } from "../shims/headers.js";
|
|
2
3
|
import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
3
4
|
import { getCollectedFetchTags } from "../shims/fetch-cache.js";
|
|
4
5
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
@@ -25,34 +26,49 @@ async function renderAppPageCacheArtifactsImpl(options, renderSpan) {
|
|
|
25
26
|
const rscCapture = teeAppPageRscStreamForCapture(rscStream, options.captureRscData);
|
|
26
27
|
const capturedRscDataRef = { value: null };
|
|
27
28
|
const fontPreloads = options.getFontPreloads();
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
29
|
+
const ssrHandler = await options.loadSsrHandler();
|
|
30
|
+
let htmlResult = null;
|
|
31
|
+
let specialErrorDocument = null;
|
|
32
|
+
try {
|
|
33
|
+
htmlResult = await ssrHandler.handleSsr(rscCapture.ssrStream, options.getNavigationContext(), {
|
|
34
|
+
links: options.getFontLinks(),
|
|
35
|
+
styles: options.getFontStyles(),
|
|
36
|
+
preloads: fontPreloads
|
|
37
|
+
}, {
|
|
38
|
+
basePath: options.basePath,
|
|
39
|
+
clientTraceMetadata: options.clientTraceMetadata,
|
|
40
|
+
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
41
|
+
rootParams: options.rootParams,
|
|
42
|
+
waitForAllReady: options.waitForAllReady,
|
|
43
|
+
mirrorNextFlight: options.mirrorNextFlight,
|
|
44
|
+
isStaticGeneration: true,
|
|
45
|
+
isForceStatic: options.isForceStatic,
|
|
46
|
+
onSsrError: options.onSsrError && options.isCapturedRscError ? createAppPageSsrErrorHandler((error) => {
|
|
47
|
+
recordAppPageRenderError(renderSpan, error);
|
|
48
|
+
return options.onSsrError?.(error);
|
|
49
|
+
}, options.isCapturedRscError) : options.onSsrError ? (error) => {
|
|
50
|
+
recordAppPageRenderError(renderSpan, error);
|
|
51
|
+
return options.onSsrError?.(error);
|
|
52
|
+
} : void 0,
|
|
53
|
+
...rscCapture.sideStream ? {
|
|
54
|
+
sideStream: rscCapture.sideStream,
|
|
55
|
+
capturedRscDataRef
|
|
56
|
+
} : {}
|
|
57
|
+
});
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (!options.renderShellSpecialError) throw error;
|
|
60
|
+
await capturedRscDataRef.value?.catch(() => {});
|
|
61
|
+
specialErrorDocument = await options.renderShellSpecialError(error);
|
|
62
|
+
if (!specialErrorDocument) throw error;
|
|
63
|
+
}
|
|
64
|
+
let html = specialErrorDocument?.html ?? "";
|
|
65
|
+
let linkHeader = specialErrorDocument?.linkHeader;
|
|
66
|
+
if (htmlResult) {
|
|
67
|
+
const htmlStream = isAppSsrRenderResult(htmlResult) ? htmlResult.htmlStream : htmlResult;
|
|
68
|
+
const reactLinkHeader = isAppSsrRenderResult(htmlResult) ? htmlResult.linkHeader : void 0;
|
|
69
|
+
linkHeader = buildAppPageLinkHeader(reactLinkHeader, buildAppPageFontLinkHeader(fontPreloads), options.reactMaxHeadersLength);
|
|
70
|
+
html = await readStreamAsText(htmlStream);
|
|
71
|
+
}
|
|
56
72
|
let rscData;
|
|
57
73
|
if (options.captureRscData) {
|
|
58
74
|
const capturedPromise = capturedRscDataRef.value;
|
|
@@ -64,24 +80,29 @@ async function renderAppPageCacheArtifactsImpl(options, renderSpan) {
|
|
|
64
80
|
const observationState = consumeAppPageRenderObservationState();
|
|
65
81
|
consumeInvalidDynamicUsageError();
|
|
66
82
|
const usedDynamicApi = consumeDynamicUsage() || isRenderDynamicLatched();
|
|
83
|
+
const htmlRenderObservation = createAppPageRenderObservation({
|
|
84
|
+
boundaryOutcome: { kind: "success" },
|
|
85
|
+
cacheability: "public",
|
|
86
|
+
cacheTags: tags,
|
|
87
|
+
cleanPathname: options.cleanPathname,
|
|
88
|
+
completeness: "complete",
|
|
89
|
+
output: createAppPageHtmlOutputScope({
|
|
90
|
+
element: options.element,
|
|
91
|
+
renderEpoch: null,
|
|
92
|
+
rootBoundaryId: null,
|
|
93
|
+
routePattern: options.route.pattern
|
|
94
|
+
}),
|
|
95
|
+
params: options.navigationParams,
|
|
96
|
+
state: observationState
|
|
97
|
+
});
|
|
67
98
|
const result = {
|
|
68
99
|
html,
|
|
69
|
-
htmlRenderObservation
|
|
70
|
-
boundaryOutcome: { kind: "success" },
|
|
71
|
-
cacheability: "public",
|
|
72
|
-
cacheTags: tags,
|
|
73
|
-
cleanPathname: options.cleanPathname,
|
|
74
|
-
completeness: "complete",
|
|
75
|
-
output: createAppPageHtmlOutputScope({
|
|
76
|
-
element: options.element,
|
|
77
|
-
renderEpoch: null,
|
|
78
|
-
rootBoundaryId: null,
|
|
79
|
-
routePattern: options.route.pattern
|
|
80
|
-
}),
|
|
81
|
-
params: options.navigationParams,
|
|
82
|
-
state: observationState
|
|
83
|
-
}),
|
|
100
|
+
htmlRenderObservation,
|
|
84
101
|
...linkHeader ? { linkHeader } : {},
|
|
102
|
+
...specialErrorDocument ? {
|
|
103
|
+
headers: specialErrorDocument.headers,
|
|
104
|
+
status: specialErrorDocument.status
|
|
105
|
+
} : {},
|
|
85
106
|
tags,
|
|
86
107
|
usedDynamicApi,
|
|
87
108
|
cacheControl: typeof cacheLife?.revalidate === "number" ? {
|
|
@@ -21,11 +21,15 @@ export type AppPageCacheOutcomeMetric = Readonly<{
|
|
|
21
21
|
type AppPageCacheOutcomeRecorder = (metric: AppPageCacheOutcomeMetric) => void;
|
|
22
22
|
type AppPageCacheRenderResult = {
|
|
23
23
|
cacheControl?: CacheControlMetadata;
|
|
24
|
+
/** Response headers stored with both entries, such as a redirect's `location`. */
|
|
25
|
+
headers?: Record<string, string>;
|
|
24
26
|
html: string;
|
|
25
27
|
htmlRenderObservation: RenderObservation;
|
|
26
28
|
linkHeader?: string;
|
|
27
29
|
rscData: ArrayBuffer;
|
|
28
30
|
rscRenderObservation: RenderObservation;
|
|
31
|
+
/** The status of a render whose shell ended in a special error. */
|
|
32
|
+
status?: number;
|
|
29
33
|
/**
|
|
30
34
|
* The route-level revalidate of the route this render regenerated, or null
|
|
31
35
|
* when it has none and the render's cacheLife sets it. Undefined keeps the
|
|
@@ -40,6 +44,7 @@ type BuildAppPageCachedResponseOptions = {
|
|
|
40
44
|
cacheState: "HIT" | "STALE";
|
|
41
45
|
expireSeconds?: number;
|
|
42
46
|
isEdgeRuntime?: boolean;
|
|
47
|
+
isRoutePPREnabled?: boolean;
|
|
43
48
|
isRscRequest: boolean;
|
|
44
49
|
middlewareHeaders?: Headers | null;
|
|
45
50
|
middlewareStatus?: number | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
2
|
-
import { VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER } from "./headers.js";
|
|
2
|
+
import { VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
|
|
3
3
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
4
4
|
import { decideIsr } from "./isr-decision.js";
|
|
5
5
|
import { buildAppPageCacheValue, isrCacheControl, resolveRouteExpireSeconds } from "./isr-cache.js";
|
|
@@ -53,6 +53,10 @@ function buildAppPageCachedHeaders(options) {
|
|
|
53
53
|
if (options.params && Object.keys(options.params).length > 0) headers.set(VINEXT_PARAMS_HEADER, encodeURIComponent(JSON.stringify(options.params)));
|
|
54
54
|
if (options.mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
|
|
55
55
|
applyClientStaleTimeHeader(headers, options.staleTimeSeconds);
|
|
56
|
+
for (const [name, value] of Object.entries(options.storedHeaders ?? {})) {
|
|
57
|
+
if (name.toLowerCase() === "link") continue;
|
|
58
|
+
for (const item of Array.isArray(value) ? value : [value]) headers.append(name, item);
|
|
59
|
+
}
|
|
56
60
|
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
|
|
57
61
|
if (options.linkHeader) {
|
|
58
62
|
if (Array.isArray(options.linkHeader)) for (const value of options.linkHeader) headers.append("Link", value);
|
|
@@ -88,8 +92,15 @@ function resolveRegenerationFailureCacheControl(previous) {
|
|
|
88
92
|
...previous.stale === void 0 ? {} : { stale: previous.stale }
|
|
89
93
|
};
|
|
90
94
|
}
|
|
95
|
+
function isRedirectStatus(status) {
|
|
96
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
97
|
+
}
|
|
91
98
|
function buildAppPageCachedResponse(cachedValue, options) {
|
|
92
|
-
const
|
|
99
|
+
const storedStatus = cachedValue.status || 200;
|
|
100
|
+
const isRedirect = isRedirectStatus(storedStatus);
|
|
101
|
+
const isHttpErrorFallbackStatus = storedStatus === 401 || storedStatus === 403 || storedStatus === 404;
|
|
102
|
+
const replayStatus = options.isRscRequest && (isRedirect || options.isRoutePPREnabled === true) ? 200 : storedStatus;
|
|
103
|
+
const status = isRedirect || isHttpErrorFallbackStatus ? replayStatus : options.middlewareStatus ?? replayStatus;
|
|
93
104
|
const { cacheControl } = decideIsr({
|
|
94
105
|
cacheState: options.cacheState,
|
|
95
106
|
kind: "app-page",
|
|
@@ -108,17 +119,19 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
108
119
|
middlewareHeaders: options.middlewareHeaders,
|
|
109
120
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
110
121
|
params: options.params,
|
|
111
|
-
staleTimeSeconds
|
|
122
|
+
staleTimeSeconds,
|
|
123
|
+
storedHeaders: cachedValue.headers
|
|
112
124
|
});
|
|
113
125
|
if (options.renderedPathAndSearch) rscHeaders.set(VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, encodeURIComponent(options.renderedPathAndSearch));
|
|
114
126
|
applyRscCompatibilityIdHeader(rscHeaders);
|
|
115
127
|
applyRscDeploymentIdHeader(rscHeaders);
|
|
128
|
+
if (isHttpErrorFallbackStatus && status === storedStatus) rscHeaders.set(VINEXT_SPECIAL_ERROR_STATUS_HEADER, String(storedStatus));
|
|
116
129
|
return new Response(cachedValue.rscData, {
|
|
117
130
|
status,
|
|
118
131
|
headers: rscHeaders
|
|
119
132
|
});
|
|
120
133
|
}
|
|
121
|
-
if (typeof cachedValue.html !== "string" || cachedValue.html.length === 0) return null;
|
|
134
|
+
if (typeof cachedValue.html !== "string" || cachedValue.html.length === 0 && !isRedirect) return null;
|
|
122
135
|
const htmlHeaders = buildAppPageCachedHeaders({
|
|
123
136
|
cacheControl,
|
|
124
137
|
cacheState: options.cacheState,
|
|
@@ -126,7 +139,8 @@ function buildAppPageCachedResponse(cachedValue, options) {
|
|
|
126
139
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
127
140
|
linkHeader: cachedValue.headers?.link,
|
|
128
141
|
middlewareHeaders: options.middlewareHeaders,
|
|
129
|
-
staleTimeSeconds
|
|
142
|
+
staleTimeSeconds,
|
|
143
|
+
storedHeaders: cachedValue.headers
|
|
130
144
|
});
|
|
131
145
|
const response = new Response(cachedValue.html, {
|
|
132
146
|
status,
|
|
@@ -218,6 +232,7 @@ async function readAppPageCacheResponse(options) {
|
|
|
218
232
|
cacheControl: cached?.value.cacheControl,
|
|
219
233
|
expireSeconds: options.expireSeconds,
|
|
220
234
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
235
|
+
isRoutePPREnabled: options.isRoutePPREnabled,
|
|
221
236
|
isRscRequest: options.isRscRequest,
|
|
222
237
|
middlewareHeaders: options.middlewareHeaders,
|
|
223
238
|
middlewareStatus: options.middlewareStatus,
|
|
@@ -287,9 +302,13 @@ see more here https://nextjs.org/docs/messages/app-static-to-dynamic-error`);
|
|
|
287
302
|
return false;
|
|
288
303
|
}
|
|
289
304
|
};
|
|
290
|
-
|
|
305
|
+
const status = revalidatedPage.status ?? 200;
|
|
306
|
+
if (!await store(rscKey, buildAppPageCacheValue("", revalidatedPage.rscData, status, revalidatedPage.rscRenderObservation, revalidatedPage.headers))) return;
|
|
291
307
|
if (!options.isRscRequest) {
|
|
292
|
-
if (!await store(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0,
|
|
308
|
+
if (!await store(isrKey, buildAppPageCacheValue(revalidatedPage.html, void 0, status, revalidatedPage.htmlRenderObservation, revalidatedPage.linkHeader ? {
|
|
309
|
+
...revalidatedPage.headers,
|
|
310
|
+
link: revalidatedPage.linkHeader
|
|
311
|
+
} : revalidatedPage.headers))) return;
|
|
293
312
|
}
|
|
294
313
|
options.isrDebug?.("regen complete", options.cleanPathname);
|
|
295
314
|
};
|
|
@@ -306,6 +325,7 @@ see more here https://nextjs.org/docs/messages/app-static-to-dynamic-error`);
|
|
|
306
325
|
cacheControl: cached.value.cacheControl,
|
|
307
326
|
expireSeconds: options.expireSeconds,
|
|
308
327
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
328
|
+
isRoutePPREnabled: options.isRoutePPREnabled,
|
|
309
329
|
isRscRequest: options.isRscRequest,
|
|
310
330
|
middlewareHeaders: options.middlewareHeaders,
|
|
311
331
|
middlewareStatus: options.middlewareStatus,
|
|
@@ -142,6 +142,7 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
142
142
|
observeMetadataSearchParamsAccess?: boolean;
|
|
143
143
|
observePageSearchParamsAccess?: boolean;
|
|
144
144
|
serveStreamingMetadata?: boolean;
|
|
145
|
+
placeStreamedMetadataInHead?: boolean;
|
|
145
146
|
}) => Promise<AppPageElement>;
|
|
146
147
|
clientReuseManifest?: ClientReuseManifestParseResult;
|
|
147
148
|
cleanPathname: string;
|
|
@@ -221,13 +222,14 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
221
222
|
staticParamsValidationParams?: AppPageParams;
|
|
222
223
|
rootParams?: RootParams;
|
|
223
224
|
probeLayoutAt: (layoutIndex: number, layoutParamAccess?: AppLayoutParamAccessTracker) => unknown;
|
|
224
|
-
probePage: (searchParams?: URLSearchParams) => unknown;
|
|
225
225
|
expireSeconds?: number;
|
|
226
226
|
renderErrorBoundaryPage: (error: unknown, errorOrigin?: "rsc" | "ssr") => Promise<Response | null>;
|
|
227
227
|
renderHttpAccessFallbackPage: (statusCode: number, opts: {
|
|
228
228
|
boundaryComponent?: unknown;
|
|
229
229
|
boundaryModule?: AppPageModule | null;
|
|
230
230
|
intercept?: AppPageDispatchInterceptOptions | null;
|
|
231
|
+
/** The document may be stored, so it must not carry the request's query. */
|
|
232
|
+
isCacheCandidate?: boolean;
|
|
231
233
|
layouts?: readonly AppPageModule[];
|
|
232
234
|
matchedParams: AppPageParams;
|
|
233
235
|
}, middlewareContext: AppPageMiddlewareContext | null) => Promise<Response | null>;
|
|
@@ -268,6 +270,12 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
268
270
|
searchParams: URLSearchParams;
|
|
269
271
|
}) => void;
|
|
270
272
|
renderMode?: AppRscRenderMode;
|
|
273
|
+
/**
|
|
274
|
+
* Render the document whole before its first byte, with streamed metadata in
|
|
275
|
+
* `<head>`, as a background regeneration does. The adapter sets this for a
|
|
276
|
+
* render no client is waiting on, such as its regeneration or a warm-up.
|
|
277
|
+
*/
|
|
278
|
+
renderWholeDocument?: boolean;
|
|
271
279
|
};
|
|
272
280
|
export declare function shouldReadAppPageCache(options: {
|
|
273
281
|
isProgressiveActionRender: boolean;
|
|
@@ -5,27 +5,28 @@ import { VINEXT_INTERCEPTION_ID_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc
|
|
|
5
5
|
import "./headers.js";
|
|
6
6
|
import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
|
|
7
7
|
import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
|
|
8
|
-
import { AppElementsWire } from "./app-elements-wire.js";
|
|
9
|
-
import "./app-elements.js";
|
|
10
8
|
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, peekDynamicUsage, peekRenderRequestApiUsage, runWithIsolatedDynamicUsage, setHeadersContext } from "../shims/headers.js";
|
|
11
9
|
import { _captureRequestScopedCacheLifeAccessors } from "../shims/cache-request-state.js";
|
|
12
10
|
import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchRevalidate, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground } from "../shims/fetch-cache.js";
|
|
13
11
|
import { cacheabilityManifestPageState } from "./cacheability-manifest.js";
|
|
12
|
+
import { isAppPageStaticEligible } from "./app-segment-config.js";
|
|
13
|
+
import { AppElementsWire } from "./app-elements-wire.js";
|
|
14
|
+
import "./app-elements.js";
|
|
14
15
|
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
|
|
15
16
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
17
|
+
import { getFrameworkLinkHeader } from "./app-response-header-provenance.js";
|
|
16
18
|
import { resolveUncacheableCacheControl } from "./app-page-response.js";
|
|
17
19
|
import { buildRscRedirectFlightStream } from "./app-rsc-redirect-flight.js";
|
|
18
|
-
import { buildAppPageSpecialErrorResponse,
|
|
20
|
+
import { buildAppPageSpecialErrorResponse, resolveAppPageShellSpecialError, resolveAppPageSpecialError, resolveAppPageSpecialErrorStoredHeaders } from "./app-page-execution.js";
|
|
19
21
|
import { resolveAppPageTraceOperation } from "./app-page-tracing.js";
|
|
20
22
|
import { createAppPageTreePath } from "./app-page-route-wiring.js";
|
|
21
23
|
import { traceResponseStart } from "./response-start-tracing.js";
|
|
22
24
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
23
25
|
import { consumeAppPageRenderObservationState, discardAppPageRenderState } from "./app-page-render-observation.js";
|
|
24
|
-
import {
|
|
26
|
+
import { createAppPageRscErrorTracker } from "./app-page-stream.js";
|
|
25
27
|
import { resolveAppPageParentHttpAccessBoundary, resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
|
|
26
28
|
import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
|
|
27
29
|
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
28
|
-
import { createAppPageRscErrorTracker } from "./app-page-stream.js";
|
|
29
30
|
import { createAppLayoutParamAccessTracker, isAppLayoutObservationUnsafeForStaticReuse } from "./app-layout-param-observation.js";
|
|
30
31
|
import { resolveAppPageMethodResponse } from "./app-page-method.js";
|
|
31
32
|
import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
|
|
@@ -255,7 +256,6 @@ async function dispatchAppPageInner(options) {
|
|
|
255
256
|
const pageSearchParams = shouldUseEmptySearchParams ? new URLSearchParams() : options.searchParams;
|
|
256
257
|
const layoutParamAccess = createAppLayoutParamAccessTracker();
|
|
257
258
|
const activeLoadingTreePositions = getActiveLoadingTreePositions(route);
|
|
258
|
-
const hasActiveLoadingBoundary = activeLoadingTreePositions.length > 0;
|
|
259
259
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
|
|
260
260
|
setCurrentFetchCacheMode(options.fetchCache ?? null);
|
|
261
261
|
setCurrentFetchRevalidate(currentRevalidateSeconds);
|
|
@@ -396,14 +396,16 @@ async function dispatchAppPageInner(options) {
|
|
|
396
396
|
isForceStatic: revalidationDynamicConfig === "force-static",
|
|
397
397
|
observeMetadataSearchParamsAccess: revalidationDynamicConfig !== "force-static",
|
|
398
398
|
observePageSearchParamsAccess: revalidationDynamicConfig !== "force-static",
|
|
399
|
-
serveStreamingMetadata:
|
|
399
|
+
serveStreamingMetadata: placeGeneratedMetadataInBody,
|
|
400
|
+
placeStreamedMetadataInHead: true
|
|
400
401
|
});
|
|
401
402
|
const baseRevalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern, { revalidateReason: "stale" });
|
|
402
403
|
const baseRevalidatedOnSsrError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern, {
|
|
403
404
|
renderSource: "server-rendering",
|
|
404
405
|
revalidateReason: "stale"
|
|
405
406
|
});
|
|
406
|
-
|
|
407
|
+
const rscErrorTracker = createAppPageRscErrorTracker(baseRevalidatedOnError);
|
|
408
|
+
revalidationRscErrorTracker = rscErrorTracker;
|
|
407
409
|
const rendered = await renderAppPageCacheArtifacts({
|
|
408
410
|
basePath: options.basePath,
|
|
409
411
|
captureRscData: true,
|
|
@@ -416,14 +418,36 @@ async function dispatchAppPageInner(options) {
|
|
|
416
418
|
getNavigationContext: options.getNavigationContext,
|
|
417
419
|
loadSsrHandler: options.loadSsrHandler,
|
|
418
420
|
mountedSlotsHeader: options.mountedSlotsHeader,
|
|
421
|
+
mirrorNextFlight: () => rscErrorTracker.getCapturedSpecialError() !== null,
|
|
419
422
|
navigationParams: revalidationTarget.navigationParams,
|
|
420
|
-
isCapturedRscError:
|
|
421
|
-
onError:
|
|
423
|
+
isCapturedRscError: rscErrorTracker.isCapturedError,
|
|
424
|
+
onError: rscErrorTracker.onRenderError,
|
|
422
425
|
onSsrError(error) {
|
|
423
426
|
reportedSsrRevalidationErrors.add(error);
|
|
424
427
|
return baseRevalidatedOnSsrError(error, void 0, void 0);
|
|
425
428
|
},
|
|
426
429
|
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
430
|
+
async renderShellSpecialError(error) {
|
|
431
|
+
const specialError = resolveAppPageShellSpecialError(error, rscErrorTracker.getCapturedSpecialErrors(error));
|
|
432
|
+
if (!specialError) return null;
|
|
433
|
+
if (options.isRscRequest) {
|
|
434
|
+
if (specialError.fromMetadata === true) return null;
|
|
435
|
+
return {
|
|
436
|
+
headers: resolveAppPageSpecialErrorStoredHeaders(specialError, options.basePath),
|
|
437
|
+
html: "",
|
|
438
|
+
status: specialError.statusCode
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
if (revalidationTarget.route !== route) return null;
|
|
442
|
+
const document = await renderPageSpecialError(options, specialError, false, revalidationTarget.interceptOpts, true);
|
|
443
|
+
if (document.status !== specialError.statusCode) return null;
|
|
444
|
+
return {
|
|
445
|
+
headers: resolveAppPageSpecialErrorStoredHeaders(specialError, options.basePath),
|
|
446
|
+
html: await document.text(),
|
|
447
|
+
linkHeader: getFrameworkLinkHeader(document.headers) ?? void 0,
|
|
448
|
+
status: specialError.statusCode
|
|
449
|
+
};
|
|
450
|
+
},
|
|
427
451
|
renderToReadableStream: options.renderToReadableStream,
|
|
428
452
|
rootParams: options.rootParams,
|
|
429
453
|
route: revalidationTarget.route,
|
|
@@ -432,6 +456,7 @@ async function dispatchAppPageInner(options) {
|
|
|
432
456
|
});
|
|
433
457
|
options.clearRequestContext();
|
|
434
458
|
return {
|
|
459
|
+
headers: rendered.headers,
|
|
435
460
|
html: rendered.html,
|
|
436
461
|
htmlRenderObservation: rendered.htmlRenderObservation,
|
|
437
462
|
linkHeader: rendered.linkHeader,
|
|
@@ -440,6 +465,7 @@ async function dispatchAppPageInner(options) {
|
|
|
440
465
|
tags: rendered.tags,
|
|
441
466
|
cacheControl: rendered.cacheControl,
|
|
442
467
|
revalidateSeconds: revalidationRouteRevalidateSeconds,
|
|
468
|
+
status: rendered.status,
|
|
443
469
|
usedDynamicApi: rendered.usedDynamicApi
|
|
444
470
|
};
|
|
445
471
|
});
|
|
@@ -465,6 +491,7 @@ async function dispatchAppPageInner(options) {
|
|
|
465
491
|
if (dynamicParamsResponse) {
|
|
466
492
|
const renderedNotFound = await options.renderHttpAccessFallbackPage(404, { matchedParams: options.params }, options.middlewareContext);
|
|
467
493
|
const cachePolicy = {
|
|
494
|
+
dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds,
|
|
468
495
|
isDraftMode,
|
|
469
496
|
isDynamicError,
|
|
470
497
|
isForceDynamic,
|
|
@@ -510,7 +537,8 @@ async function dispatchAppPageInner(options) {
|
|
|
510
537
|
isForceStatic: sourceDynamicConfig === "force-static",
|
|
511
538
|
observeMetadataSearchParamsAccess: sourceDynamicConfig !== "force-static",
|
|
512
539
|
observePageSearchParamsAccess: sourceDynamicConfig !== "force-static",
|
|
513
|
-
serveStreamingMetadata: placeGeneratedMetadataInBody
|
|
540
|
+
serveStreamingMetadata: placeGeneratedMetadataInBody,
|
|
541
|
+
placeStreamedMetadataInHead: options.renderWholeDocument === true
|
|
514
542
|
});
|
|
515
543
|
},
|
|
516
544
|
cleanPathname: options.cleanPathname,
|
|
@@ -565,19 +593,10 @@ async function dispatchAppPageInner(options) {
|
|
|
565
593
|
isForceStatic,
|
|
566
594
|
observeMetadataSearchParamsAccess: !isForceStatic,
|
|
567
595
|
observePageSearchParamsAccess: !isForceStatic,
|
|
568
|
-
serveStreamingMetadata: placeGeneratedMetadataInBody
|
|
596
|
+
serveStreamingMetadata: placeGeneratedMetadataInBody,
|
|
597
|
+
placeStreamedMetadataInHead: options.renderWholeDocument === true
|
|
569
598
|
});
|
|
570
599
|
},
|
|
571
|
-
async probePageSpecialError() {
|
|
572
|
-
if (hasActiveLoadingBoundary) return null;
|
|
573
|
-
const pageError = await probeAppPageThrownError({
|
|
574
|
-
probePage: () => options.probePage(pageSearchParams),
|
|
575
|
-
runWithSuppressedHookWarning(probe) {
|
|
576
|
-
return options.runWithSuppressedHookWarning(probe);
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
return resolveAppPageSpecialError(pageError);
|
|
580
|
-
},
|
|
581
600
|
renderErrorBoundaryPage(buildError) {
|
|
582
601
|
return options.renderErrorBoundaryPage(buildError);
|
|
583
602
|
},
|
|
@@ -645,7 +664,6 @@ async function dispatchAppPageInner(options) {
|
|
|
645
664
|
return requestCacheLife.peek();
|
|
646
665
|
},
|
|
647
666
|
handlerStart: options.handlerStart,
|
|
648
|
-
hasLoadingBoundary: hasActiveLoadingBoundary,
|
|
649
667
|
omitPendingDynamicCacheState: hasRequestSearchParams && !(isCacheCandidate && !options.isRscRequest),
|
|
650
668
|
formState: options.formState ?? null,
|
|
651
669
|
isProgressiveActionRender: options.isProgressiveActionRender === true,
|
|
@@ -657,7 +675,9 @@ async function dispatchAppPageInner(options) {
|
|
|
657
675
|
isStaticEligible,
|
|
658
676
|
isCacheCandidate,
|
|
659
677
|
isPrerender,
|
|
678
|
+
isRoutePPREnabled: options.pprRuntime !== void 0,
|
|
660
679
|
isSpeculativePrerender,
|
|
680
|
+
renderWholeDocument: options.renderWholeDocument === true && !options.isRscRequest,
|
|
661
681
|
isProduction: options.isProduction,
|
|
662
682
|
isRscRequest: options.isRscRequest,
|
|
663
683
|
traceOperation,
|
|
@@ -690,10 +710,6 @@ async function dispatchAppPageInner(options) {
|
|
|
690
710
|
probeLayoutAt(layoutIndex) {
|
|
691
711
|
return options.probeLayoutAt(layoutIndex, layoutParamAccess);
|
|
692
712
|
},
|
|
693
|
-
probePage() {
|
|
694
|
-
return options.probePage(pageSearchParams);
|
|
695
|
-
},
|
|
696
|
-
probePageBeforeRender: options.isRscRequest,
|
|
697
713
|
classification: {
|
|
698
714
|
getLayoutId(index) {
|
|
699
715
|
const treePosition = route.layoutTreePositions?.[index] ?? 0;
|
|
@@ -719,8 +735,8 @@ async function dispatchAppPageInner(options) {
|
|
|
719
735
|
renderLayoutSpecialError(specialError, layoutIndex) {
|
|
720
736
|
return renderLayoutSpecialError(options, specialError, layoutIndex, serveStreamingMetadata);
|
|
721
737
|
},
|
|
722
|
-
renderPageSpecialError(specialError) {
|
|
723
|
-
return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts);
|
|
738
|
+
renderPageSpecialError(specialError, renderOptions) {
|
|
739
|
+
return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts, renderOptions?.isCacheCandidate === true);
|
|
724
740
|
},
|
|
725
741
|
renderToReadableStream: options.renderToReadableStream,
|
|
726
742
|
hasCustomGlobalError: options.hasCustomGlobalError,
|
|
@@ -773,7 +789,7 @@ async function renderLayoutSpecialError(options, specialError, layoutIndex, serv
|
|
|
773
789
|
specialError
|
|
774
790
|
});
|
|
775
791
|
}
|
|
776
|
-
async function renderPageSpecialError(options, specialError, serveStreamingMetadata, intercept) {
|
|
792
|
+
async function renderPageSpecialError(options, specialError, serveStreamingMetadata, intercept, isCacheCandidate = false) {
|
|
777
793
|
return buildAppPageSpecialErrorResponse({
|
|
778
794
|
basePath: options.basePath,
|
|
779
795
|
buildRscRedirectFlightStream: (rscOptions) => buildRscRedirectFlightStream({
|
|
@@ -802,6 +818,7 @@ async function renderPageSpecialError(options, specialError, serveStreamingMetad
|
|
|
802
818
|
const useLayoutAlignedBoundary = boundaryLayoutIndex !== null && (routeBoundaryModule === null || routeBoundaryModule === parentBoundaryModule);
|
|
803
819
|
const fallbackOptions = {
|
|
804
820
|
intercept,
|
|
821
|
+
...isCacheCandidate ? { isCacheCandidate } : {},
|
|
805
822
|
matchedParams: options.params
|
|
806
823
|
};
|
|
807
824
|
if (useLayoutAlignedBoundary && boundaryLayoutIndex !== null) {
|
|
@@ -61,6 +61,13 @@ export type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> =
|
|
|
61
61
|
observeMetadataSearchParamsAccess?: boolean;
|
|
62
62
|
/** Whether generated metadata may stream into the response body. */
|
|
63
63
|
serveStreamingMetadata?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Wait for streamed metadata in `<head>`, for a document rendered whole
|
|
66
|
+
* before it's written, such as a background regeneration. Next.js does this
|
|
67
|
+
* for every static or ISR render. Its errors still reach the route's
|
|
68
|
+
* boundaries through the outlet.
|
|
69
|
+
*/
|
|
70
|
+
placeStreamedMetadataInHead?: boolean;
|
|
64
71
|
/** Whether streamed render errors must be sanitized for client transport. */
|
|
65
72
|
isProduction?: boolean;
|
|
66
73
|
};
|