vinext 1.0.1 → 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.
Files changed (159) hide show
  1. package/README.md +72 -1
  2. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  3. package/dist/build/app-page-static-eligibility.js +82 -0
  4. package/dist/build/prerender-paths.js +3 -78
  5. package/dist/build/prerender.js +33 -8
  6. package/dist/build/server-manifest.d.ts +7 -0
  7. package/dist/build/server-manifest.js +11 -1
  8. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  9. package/dist/cache/cache-adapters-virtual.js +3 -3
  10. package/dist/client/navigation-runtime.d.ts +11 -0
  11. package/dist/client/navigation-runtime.js +1 -1
  12. package/dist/config/config-matchers.js +3 -1
  13. package/dist/config/next-config.d.ts +7 -0
  14. package/dist/config/next-config.js +18 -3
  15. package/dist/entries/app-rsc-entry.d.ts +2 -0
  16. package/dist/entries/app-rsc-entry.js +64 -43
  17. package/dist/index.d.ts +4 -1
  18. package/dist/index.js +59 -30
  19. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  20. package/dist/plugins/cache-flight-codec.js +68 -0
  21. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  22. package/dist/plugins/commonjs-esm-facade.js +80 -0
  23. package/dist/plugins/fonts.d.ts +8 -11
  24. package/dist/plugins/fonts.js +71 -34
  25. package/dist/routing/file-matcher.d.ts +1 -0
  26. package/dist/routing/file-matcher.js +1 -1
  27. package/dist/server/api-handler.js +17 -7
  28. package/dist/server/app-browser-entry.js +11 -7
  29. package/dist/server/app-browser-history-controller.d.ts +2 -0
  30. package/dist/server/app-browser-history-controller.js +8 -0
  31. package/dist/server/app-browser-interception-context.js +26 -2
  32. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  33. package/dist/server/app-browser-navigation-controller.js +93 -10
  34. package/dist/server/app-fallback-renderer.d.ts +2 -0
  35. package/dist/server/app-fallback-renderer.js +1 -0
  36. package/dist/server/app-history-state.d.ts +3 -0
  37. package/dist/server/app-history-state.js +7 -0
  38. package/dist/server/app-middleware.js +2 -1
  39. package/dist/server/app-optimistic-routing.js +1 -1
  40. package/dist/server/app-page-boundary-render.d.ts +5 -0
  41. package/dist/server/app-page-boundary-render.js +6 -4
  42. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  43. package/dist/server/app-page-cache-finalizer.js +41 -7
  44. package/dist/server/app-page-cache-render.d.ts +18 -0
  45. package/dist/server/app-page-cache-render.js +63 -43
  46. package/dist/server/app-page-cache.d.ts +5 -0
  47. package/dist/server/app-page-cache.js +27 -7
  48. package/dist/server/app-page-dispatch.d.ts +9 -1
  49. package/dist/server/app-page-dispatch.js +47 -30
  50. package/dist/server/app-page-element-builder.d.ts +7 -0
  51. package/dist/server/app-page-element-builder.js +27 -42
  52. package/dist/server/app-page-execution.d.ts +15 -12
  53. package/dist/server/app-page-execution.js +30 -40
  54. package/dist/server/app-page-head.d.ts +5 -0
  55. package/dist/server/app-page-head.js +9 -3
  56. package/dist/server/app-page-probe.d.ts +0 -109
  57. package/dist/server/app-page-probe.js +3 -136
  58. package/dist/server/app-page-render-identity.d.ts +0 -1
  59. package/dist/server/app-page-render-identity.js +1 -1
  60. package/dist/server/app-page-render-observation.js +2 -2
  61. package/dist/server/app-page-render.d.ts +13 -5
  62. package/dist/server/app-page-render.js +219 -119
  63. package/dist/server/app-page-request.d.ts +0 -1
  64. package/dist/server/app-page-request.js +1 -2
  65. package/dist/server/app-page-response.d.ts +4 -3
  66. package/dist/server/app-page-response.js +4 -3
  67. package/dist/server/app-page-route-wiring.d.ts +17 -5
  68. package/dist/server/app-page-route-wiring.js +55 -33
  69. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  70. package/dist/server/app-page-rsc-render-status.js +54 -0
  71. package/dist/server/app-page-stream.d.ts +15 -8
  72. package/dist/server/app-page-stream.js +6 -0
  73. package/dist/server/app-request-stage-dispatch.js +1 -1
  74. package/dist/server/app-request-stage-independent-entry.js +4 -4
  75. package/dist/server/app-response-header-provenance.d.ts +2 -0
  76. package/dist/server/app-response-header-provenance.js +10 -4
  77. package/dist/server/app-route-handler-dispatch.js +1 -1
  78. package/dist/server/app-router-entry.js +3 -3
  79. package/dist/server/app-rsc-handler.d.ts +4 -0
  80. package/dist/server/app-rsc-handler.js +212 -96
  81. package/dist/server/app-rsc-request-normalization.d.ts +3 -1
  82. package/dist/server/app-rsc-request-normalization.js +4 -2
  83. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  84. package/dist/server/app-rsc-response-stage.js +6 -4
  85. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  86. package/dist/server/app-rsc-route-matching.js +36 -19
  87. package/dist/server/app-server-action-execution.js +1 -1
  88. package/dist/server/app-ssr-entry.d.ts +3 -2
  89. package/dist/server/app-ssr-entry.js +6 -4
  90. package/dist/server/app-ssr-stream.d.ts +6 -1
  91. package/dist/server/app-ssr-stream.js +34 -15
  92. package/dist/server/app-worker-stages.d.ts +2 -2
  93. package/dist/server/app-worker-stages.js +3 -3
  94. package/dist/server/cacheability-request.js +9 -5
  95. package/dist/server/config-headers.js +2 -0
  96. package/dist/server/dev-server.js +12 -2
  97. package/dist/server/headers.d.ts +14 -0
  98. package/dist/server/headers.js +15 -1
  99. package/dist/server/image-optimization.d.ts +16 -0
  100. package/dist/server/image-optimization.js +26 -6
  101. package/dist/server/isr-cache.js +2 -2
  102. package/dist/server/middleware-matcher-pattern.js +8 -4
  103. package/dist/server/middleware-response-headers.js +2 -0
  104. package/dist/server/multi-stage.d.ts +8 -0
  105. package/dist/server/navigation-planner.js +1 -1
  106. package/dist/server/node-response-signal.d.ts +16 -0
  107. package/dist/server/node-response-signal.js +26 -0
  108. package/dist/server/open-redirect.d.ts +47 -0
  109. package/dist/server/open-redirect.js +74 -1
  110. package/dist/server/pages-page-handler.js +21 -4
  111. package/dist/server/pages-request-stage-entry.js +8 -4
  112. package/dist/server/prod-server.d.ts +8 -7
  113. package/dist/server/prod-server.js +153 -69
  114. package/dist/server/request-pipeline.d.ts +20 -8
  115. package/dist/server/request-pipeline.js +21 -7
  116. package/dist/server/response-compression.d.ts +43 -0
  117. package/dist/server/response-compression.js +111 -0
  118. package/dist/server/seed-cache.js +10 -7
  119. package/dist/server/socket-error-backstop.d.ts +14 -0
  120. package/dist/server/socket-error-backstop.js +27 -4
  121. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  122. package/dist/shims/cache-adapter-instantiate.js +118 -0
  123. package/dist/shims/cache-callable-runtime.d.ts +2 -40
  124. package/dist/shims/cache-callable-runtime.js +50 -168
  125. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  126. package/dist/shims/cache-flight-arguments.js +56 -0
  127. package/dist/shims/cache-request-state.d.ts +15 -0
  128. package/dist/shims/cache-request-state.js +31 -8
  129. package/dist/shims/cache-runtime.d.ts +6 -19
  130. package/dist/shims/cache-runtime.js +165 -225
  131. package/dist/shims/cache.d.ts +2 -2
  132. package/dist/shims/cache.js +5 -4
  133. package/dist/shims/cacheability-classification.d.ts +7 -0
  134. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  135. package/dist/shims/error-boundary-navigation.js +19 -1
  136. package/dist/shims/error-boundary.d.ts +10 -10
  137. package/dist/shims/error-boundary.js +26 -7
  138. package/dist/shims/fetch-cache.d.ts +6 -0
  139. package/dist/shims/fetch-cache.js +19 -1
  140. package/dist/shims/form.js +1 -1
  141. package/dist/shims/headers.d.ts +13 -0
  142. package/dist/shims/headers.js +47 -4
  143. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  144. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  145. package/dist/shims/internal/headers-state.d.ts +0 -1
  146. package/dist/shims/metadata.js +3 -3
  147. package/dist/shims/navigation-errors.d.ts +6 -0
  148. package/dist/shims/navigation-errors.js +11 -1
  149. package/dist/shims/navigation.d.ts +7 -0
  150. package/dist/shims/navigation.js +14 -4
  151. package/dist/shims/request-context.d.ts +9 -0
  152. package/dist/shims/thenable-params.d.ts +4 -0
  153. package/dist/shims/thenable-params.js +25 -3
  154. package/dist/shims/unified-request-context.js +1 -0
  155. package/dist/utils/mdx-scan.d.ts +5 -0
  156. package/dist/utils/mdx-scan.js +8 -1
  157. package/dist/utils/regex-safety.d.ts +10 -0
  158. package/dist/utils/regex-safety.js +70 -18
  159. package/package.json +3 -3
@@ -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 status = options.middlewareStatus ?? (cachedValue.status || 200);
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
- if (!await store(rscKey, buildAppPageCacheValue("", revalidatedPage.rscData, 200, revalidatedPage.rscRenderObservation))) return;
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, 200, revalidatedPage.htmlRenderObservation, revalidatedPage.linkHeader ? { link: revalidatedPage.linkHeader } : void 0))) return;
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, probeAppPageThrownError, resolveAppPageSpecialError } from "./app-page-execution.js";
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 { isAppPageStaticEligible } from "./app-segment-config.js";
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: false
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
- revalidationRscErrorTracker = createAppPageRscErrorTracker(baseRevalidatedOnError);
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: revalidationRscErrorTracker.isCapturedError,
421
- onError: revalidationRscErrorTracker.onRenderError,
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
  };
@@ -1,27 +1,27 @@
1
1
  import { isPromiseLike } from "../utils/promise.js";
2
2
  import { APP_RSC_RENDER_MODE_NAVIGATION } from "./app-rsc-render-mode.js";
3
+ import { matchRoutePattern } from "../routing/route-pattern.js";
3
4
  import { createAppPageRenderDependency, invokeAppComponent, isAppClientReference, isAppRenderSuspension, isReactOwnedAppComponent, renderAfterAppDependencies } from "./app-render-dependency.js";
4
5
  import { AppElementsWire } from "./app-elements-wire.js";
5
6
  import "./app-elements.js";
6
- import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
7
- import { matchRoutePattern } from "../routing/route-pattern.js";
7
+ import { withUseCacheLayoutMarker, withUseCachePageMarker } from "../shims/internal/app-page-props-cache-key.js";
8
8
  import { makeThenableParams } from "../shims/thenable-params.js";
9
- import { withUseCachePageMarker } from "../shims/internal/app-page-props-cache-key.js";
10
9
  import { resolveAppPageBranchParams, resolveAppPageSegmentParams } from "./app-page-params.js";
11
10
  import { resolveAppPageSpecialError } from "./app-page-execution.js";
12
- import { prepareAppPageHead, resolveActiveParallelRouteHeadInputs } from "./app-page-head.js";
13
- import { createAppPageSearchParamsObserver, makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
14
11
  import { APP_PAGE_SEGMENT_KEY, isAppPageRouteGroupSegment, resolveAppPagePatternStateKey, resolveAppPageRouteStateKey } from "./app-page-segment-state.js";
15
12
  import { sanitizeErrorForClient } from "./app-rsc-errors.js";
16
13
  import { resolveAppPageModuleTraceSegment, traceCreateComponentTree, traceGetLayoutOrPageModule } from "./app-page-tracing.js";
17
14
  import { buildAppPageElements, createAppPageSourcePage, createAppPageTreePath, resolveAppPageLoadingModuleAtOrAbove } from "./app-page-route-wiring.js";
15
+ import { collectAppPageSearchParams, hasAppPageDynamicMetadata, prepareAppPageHead, resolveActiveParallelRouteHeadInputs } from "./app-page-head.js";
18
16
  import { resolveHttpAccessFallbackMetadata, resolveHttpAccessFallbackViewport } from "./app-page-http-access-fallback-metadata.js";
19
17
  import { ClientPageRoot } from "../shims/client-page-root.js";
20
18
  import "./app-rsc-route-matching.js";
21
19
  import { resolveAppPageParentHttpAccessBoundary } from "./app-page-boundary.js";
22
20
  import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
21
+ import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
22
+ import { createAppPageSearchParamsObserver, makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
23
23
  import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
24
- import { Suspense, createElement } from "react";
24
+ import { Suspense, cache, createElement } from "react";
25
25
  //#region src/server/app-page-element-builder.ts
26
26
  function resolveInterceptLayoutParams(branchSegments, layoutSegments, params) {
27
27
  return resolveAppPageBranchParams(branchSegments, layoutSegments.length, params, layoutSegments);
@@ -60,7 +60,7 @@ function traceAppPageInterceptLayoutModules(modules, branchSegments, layoutSegme
60
60
  async function buildPageElements(options) {
61
61
  const { route, params, routePath, displayPathname = routePath, pageRequest, globalErrorModule, rootNotFoundModule, rootForbiddenModule, rootUnauthorizedModule, metadataRoutes } = options;
62
62
  const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
63
- const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION, observeMetadataSearchParamsAccess = false, observePageSearchParamsAccess = false, isForceStatic = false, serveStreamingMetadata, isProduction = process.env.NODE_ENV === "production" } = pageRequest;
63
+ const { opts, searchParams, isRscRequest, mountedSlotsHeader, renderMode = APP_RSC_RENDER_MODE_NAVIGATION, observeMetadataSearchParamsAccess = false, observePageSearchParamsAccess = false, isForceStatic = false, serveStreamingMetadata, placeStreamedMetadataInHead = false, isProduction = process.env.NODE_ENV === "production" } = pageRequest;
64
64
  const pageModule = route.page;
65
65
  const isSiblingIntercept = opts?.interceptSlotKey === "__vinext_page_intercept" && !!opts?.interceptPage;
66
66
  const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
@@ -140,7 +140,7 @@ async function buildPageElements(options) {
140
140
  } : null;
141
141
  const parallelRoutes = [...primaryParallelRouteHeadInput ? [primaryParallelRouteHeadInput.head] : [], ...activeParallelRouteHeadInputs.map((input) => input.head)];
142
142
  const metadataSearchParamsObserver = observeMetadataSearchParamsAccess ? createAppPageSearchParamsObserver() : void 0;
143
- const preparedHead = prepareAppPageHead({
143
+ const headOptions = {
144
144
  applyFileBasedMetadata: options.applyFileBasedMetadata,
145
145
  basePath: options.basePath ?? "",
146
146
  layoutModules: route.layouts,
@@ -153,15 +153,11 @@ async function buildPageElements(options) {
153
153
  routeSegments: route.routeSegments ?? null,
154
154
  searchParams,
155
155
  searchParamsObserver: metadataSearchParamsObserver
156
- });
157
- const { hasDynamicMetadata, pageSearchParams } = preparedHead;
156
+ };
157
+ const hasDynamicMetadata = hasAppPageDynamicMetadata(headOptions);
158
+ const { pageSearchParams } = collectAppPageSearchParams(searchParams);
158
159
  const streamGeneratedHead = serveStreamingMetadata ?? shouldServeStreamingMetadata(pageRequest.request.headers.get("user-agent") ?? "", options.htmlLimitedBots);
159
- const metadataPlacement = hasDynamicMetadata && streamGeneratedHead ? "body" : "head";
160
- const shouldDeferMetadata = metadataPlacement === "body";
161
- const streamingMetadata = shouldDeferMetadata ? isProduction ? preparedHead.metadata.catch((error) => {
162
- throw sanitizeErrorForClient(error, "production");
163
- }) : preparedHead.metadata : null;
164
- streamingMetadata?.catch(() => null);
160
+ const metadataPlacement = hasDynamicMetadata && streamGeneratedHead && !placeStreamedMetadataInHead ? "body" : "head";
165
161
  const resolveNotFoundFallbackPlanOptions = () => {
166
162
  const routeBoundaryModule = route.notFound;
167
163
  const parentBoundary = resolveAppPageParentHttpAccessBoundary({
@@ -189,8 +185,6 @@ async function buildPageElements(options) {
189
185
  routeSegments: route.routeSegments ?? null
190
186
  };
191
187
  };
192
- let viewportErrorOutlet = null;
193
- let metadataErrorOutlet = null;
194
188
  const resolveMetadataErrorTags = async (error) => {
195
189
  if (resolveAppPageSpecialError(error)?.kind !== "http-access-fallback") return null;
196
190
  return resolveHttpAccessFallbackMetadata({
@@ -201,24 +195,19 @@ async function buildPageElements(options) {
201
195
  routePath: route.pattern
202
196
  }).catch(() => null);
203
197
  };
204
- const [resolvedMetadata, resolvedViewport] = await Promise.all([shouldDeferMetadata ? Promise.resolve(null) : preparedHead.metadata.catch((error) => {
205
- metadataErrorOutlet = Promise.reject(isProduction ? sanitizeErrorForClient(error, "production") : error);
206
- metadataErrorOutlet.catch(() => null);
207
- return resolveMetadataErrorTags(error);
208
- }), preparedHead.viewport.catch(async (error) => {
209
- const specialError = resolveAppPageSpecialError(error);
210
- viewportErrorOutlet = Promise.reject(isProduction ? sanitizeErrorForClient(error, "production") : error);
211
- viewportErrorOutlet.catch(() => null);
212
- return specialError?.kind === "http-access-fallback" ? resolveHttpAccessFallbackViewport(resolveNotFoundFallbackPlanOptions()).catch(() => ({})) : {};
213
- })]);
214
- const streamingMetadataTags = shouldDeferMetadata ? preparedHead.metadata.catch(resolveMetadataErrorTags) : null;
215
- const streamingMetadataOutletInputs = [
216
- streamingMetadata,
217
- metadataErrorOutlet,
218
- viewportErrorOutlet
219
- ].filter((promise) => promise !== null).map((promise) => Promise.resolve(promise));
220
- const streamingMetadataOutlet = streamingMetadataOutletInputs.length > 0 ? Promise.all(streamingMetadataOutletInputs).then(() => null) : null;
221
- streamingMetadataOutlet?.catch(() => null);
198
+ const toClientError = (error) => isProduction ? sanitizeErrorForClient(error, "production") : error;
199
+ const resolveHead = cache(() => {
200
+ const preparedHead = prepareAppPageHead(headOptions);
201
+ const outlet = Promise.all([preparedHead.metadata, preparedHead.viewport]).then(() => null, (error) => {
202
+ throw toClientError(error);
203
+ });
204
+ outlet.catch(() => null);
205
+ return {
206
+ metadata: preparedHead.metadata.catch(resolveMetadataErrorTags),
207
+ outlet,
208
+ viewport: preparedHead.viewport.catch((error) => resolveAppPageSpecialError(error)?.kind === "http-access-fallback" ? resolveHttpAccessFallbackViewport(resolveNotFoundFallbackPlanOptions()).catch(() => ({})) : {})
209
+ };
210
+ });
222
211
  const pageProps = { params: makeThenableParams(effectiveParams) };
223
212
  const pageTreePosition = (sourcePageSegments ?? route.routeSegments ?? []).length;
224
213
  const hasPageLoadingBoundary = resolveAppPageLoadingModuleAtOrAbove(route, pageTreePosition) !== null || isSiblingIntercept && resolveAppPageLoadingModuleAtOrAbove({
@@ -299,7 +288,7 @@ async function buildPageElements(options) {
299
288
  const LayoutComponent = traceGetLayoutOrPageModule(resolveInterceptLayoutTraceSegment(opts?.interceptBranchSegments, interceptLayoutSegments), () => layoutModule.default);
300
289
  if (!LayoutComponent) continue;
301
290
  const interceptLayoutParams = resolveInterceptLayoutParams(opts?.interceptBranchSegments ?? interceptLayoutSegments, interceptLayoutSegments, effectiveParams);
302
- element = createElement(LayoutComponent, { params: makeThenableParams(interceptLayoutParams) }, element);
291
+ element = createElement(LayoutComponent, withUseCacheLayoutMarker(LayoutComponent, { params: makeThenableParams(interceptLayoutParams) }), element);
303
292
  }
304
293
  }
305
294
  return element;
@@ -319,14 +308,10 @@ async function buildPageElements(options) {
319
308
  matchedParams: params,
320
309
  pageRenderDependency,
321
310
  metadataPlacement,
322
- resolvedMetadata,
311
+ resolveHead,
323
312
  resolvedMetadataPathname: routePath,
324
- resolvedViewport,
325
313
  scriptNonce: options.scriptNonce,
326
- streamingMetadata,
327
- streamingMetadataOutlet,
328
314
  streamingMetadataOutletSuspended: streamGeneratedHead,
329
- streamingMetadataTags,
330
315
  renderIdentity,
331
316
  routePath,
332
317
  semanticPageIdentity,
@@ -123,22 +123,25 @@ type ProbeAppPageLayoutsOptions = {
123
123
  /** When provided, enables per-layout static/dynamic classification. */
124
124
  classification?: LayoutClassificationOptions | null;
125
125
  };
126
- type ProbeAppPageComponentOptions = {
127
- awaitAsyncResult: boolean;
128
- onError: (error: unknown) => Promise<Response | null>;
129
- probePage: () => unknown;
130
- runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
131
- };
132
- type ProbeAppPageThrownErrorOptions = {
133
- probePage: () => unknown;
134
- runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
135
- };
136
126
  export declare function resolveAppPageSpecialError(error: unknown): AppPageSpecialError | null;
127
+ /**
128
+ * Resolve the special error that rejected an SSR shell. An error from the RSC
129
+ * render reaches the shell decoded from its Flight digest, so whether
130
+ * generateMetadata() threw it comes from the errors the RSC render threw with
131
+ * that digest. When the page threw one too, the page's decides. An error a
132
+ * client component threw during SSR is the page's, since generateMetadata()
133
+ * runs only in the RSC render.
134
+ */
135
+ export declare function resolveAppPageShellSpecialError(error: unknown, renderedSpecialErrors: readonly unknown[]): AppPageSpecialError | null;
136
+ /**
137
+ * The response headers stored with a page's special-error entries: a
138
+ * redirect's own `location`, not the response's, which middleware may have
139
+ * replaced for this request.
140
+ */
141
+ export declare function resolveAppPageSpecialErrorStoredHeaders(specialError: AppPageSpecialError, basePath: string | undefined): Record<string, string> | undefined;
137
142
  export declare function buildAppPageSpecialErrorResponse(options: BuildAppPageSpecialErrorResponseOptions): Promise<Response>;
138
143
  /** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */
139
144
  export declare function probeAppPageLayouts(options: ProbeAppPageLayoutsOptions): Promise<ProbeAppPageLayoutsResult>;
140
- export declare function probeAppPageComponent(options: ProbeAppPageComponentOptions): Promise<Response | null>;
141
- export declare function probeAppPageThrownError(options: ProbeAppPageThrownErrorOptions): Promise<unknown>;
142
145
  export declare function readAppPageBinaryStream(stream: ReadableStream<Uint8Array>): Promise<ArrayBuffer>;
143
146
  export declare function bufferAppPageBinaryStream(stream: ReadableStream<Uint8Array>): Promise<ReadableStream<Uint8Array>>;
144
147
  export declare function teeAppPageRscStreamForCapture(stream: ReadableStream<Uint8Array>, shouldCapture: boolean): AppPageRscStreamCapture;