vinext 0.1.2 → 0.1.4

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 (243) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/prerender.d.ts +9 -1
  4. package/dist/build/prerender.js +42 -12
  5. package/dist/build/run-prerender.d.ts +10 -2
  6. package/dist/build/run-prerender.js +15 -1
  7. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  8. package/dist/client/app-nav-failure-handler.js +44 -0
  9. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  10. package/dist/client/pages-router-link-navigation.js +32 -2
  11. package/dist/client/vinext-next-data.d.ts +18 -1
  12. package/dist/client/vinext-next-data.js +2 -0
  13. package/dist/client/window-next.d.ts +2 -1
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -1
  17. package/dist/config/config-matchers.js +87 -16
  18. package/dist/config/next-config.d.ts +46 -4
  19. package/dist/config/next-config.js +147 -48
  20. package/dist/config/tsconfig-paths.js +14 -1
  21. package/dist/deploy.d.ts +30 -11
  22. package/dist/deploy.js +200 -112
  23. package/dist/entries/app-browser-entry.d.ts +9 -3
  24. package/dist/entries/app-browser-entry.js +21 -3
  25. package/dist/entries/app-rsc-entry.d.ts +2 -0
  26. package/dist/entries/app-rsc-entry.js +65 -5
  27. package/dist/entries/app-rsc-manifest.js +2 -0
  28. package/dist/entries/app-ssr-entry.js +1 -1
  29. package/dist/entries/pages-client-entry.js +66 -20
  30. package/dist/entries/pages-server-entry.js +47 -31
  31. package/dist/index.js +417 -102
  32. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  33. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  34. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  35. package/dist/plugins/fonts.js +5 -4
  36. package/dist/plugins/optimize-imports.d.ts +2 -1
  37. package/dist/plugins/optimize-imports.js +11 -9
  38. package/dist/plugins/postcss.js +7 -7
  39. package/dist/plugins/strip-server-exports.d.ts +9 -7
  40. package/dist/plugins/strip-server-exports.js +493 -46
  41. package/dist/plugins/typeof-window.d.ts +14 -0
  42. package/dist/plugins/typeof-window.js +150 -0
  43. package/dist/routing/app-route-graph.d.ts +2 -1
  44. package/dist/routing/app-route-graph.js +46 -16
  45. package/dist/routing/file-matcher.d.ts +10 -1
  46. package/dist/routing/file-matcher.js +22 -1
  47. package/dist/routing/pages-router.js +3 -3
  48. package/dist/routing/utils.d.ts +35 -6
  49. package/dist/routing/utils.js +59 -7
  50. package/dist/server/api-handler.d.ts +6 -1
  51. package/dist/server/api-handler.js +21 -15
  52. package/dist/server/app-browser-action-result.d.ts +19 -6
  53. package/dist/server/app-browser-action-result.js +20 -11
  54. package/dist/server/app-browser-entry.js +175 -91
  55. package/dist/server/app-browser-error.d.ts +10 -6
  56. package/dist/server/app-browser-error.js +43 -8
  57. package/dist/server/app-browser-hydration.d.ts +2 -0
  58. package/dist/server/app-browser-hydration.js +1 -0
  59. package/dist/server/app-browser-navigation-controller.d.ts +5 -3
  60. package/dist/server/app-browser-navigation-controller.js +23 -2
  61. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  62. package/dist/server/app-browser-server-action-navigation.js +9 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js +19 -11
  65. package/dist/server/app-browser-stream.js +86 -43
  66. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  67. package/dist/server/app-elements-wire.d.ts +6 -1
  68. package/dist/server/app-elements-wire.js +14 -4
  69. package/dist/server/app-elements.d.ts +2 -2
  70. package/dist/server/app-elements.js +2 -2
  71. package/dist/server/app-fallback-renderer.d.ts +1 -0
  72. package/dist/server/app-fallback-renderer.js +3 -1
  73. package/dist/server/app-optimistic-routing.js +2 -2
  74. package/dist/server/app-page-boundary-render.d.ts +1 -0
  75. package/dist/server/app-page-boundary-render.js +27 -14
  76. package/dist/server/app-page-cache-render.d.ts +53 -0
  77. package/dist/server/app-page-cache-render.js +91 -0
  78. package/dist/server/app-page-cache.d.ts +16 -2
  79. package/dist/server/app-page-cache.js +62 -1
  80. package/dist/server/app-page-dispatch.d.ts +26 -0
  81. package/dist/server/app-page-dispatch.js +149 -92
  82. package/dist/server/app-page-element-builder.d.ts +1 -0
  83. package/dist/server/app-page-element-builder.js +5 -2
  84. package/dist/server/app-page-execution.d.ts +6 -1
  85. package/dist/server/app-page-execution.js +21 -1
  86. package/dist/server/app-page-probe.d.ts +1 -0
  87. package/dist/server/app-page-probe.js +4 -0
  88. package/dist/server/app-page-render-observation.d.ts +3 -1
  89. package/dist/server/app-page-render-observation.js +17 -1
  90. package/dist/server/app-page-render.d.ts +12 -1
  91. package/dist/server/app-page-render.js +42 -4
  92. package/dist/server/app-page-request.d.ts +2 -0
  93. package/dist/server/app-page-request.js +2 -1
  94. package/dist/server/app-page-route-wiring.d.ts +3 -1
  95. package/dist/server/app-page-route-wiring.js +14 -5
  96. package/dist/server/app-page-stream.d.ts +15 -3
  97. package/dist/server/app-page-stream.js +11 -5
  98. package/dist/server/app-pages-bridge.d.ts +23 -1
  99. package/dist/server/app-pages-bridge.js +26 -17
  100. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  101. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  102. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  103. package/dist/server/app-ppr-fallback-shell.js +8 -1
  104. package/dist/server/app-route-handler-dispatch.js +9 -2
  105. package/dist/server/app-route-handler-policy.d.ts +1 -0
  106. package/dist/server/app-router-entry.js +5 -0
  107. package/dist/server/app-rsc-cache-busting.js +2 -0
  108. package/dist/server/app-rsc-handler.d.ts +28 -0
  109. package/dist/server/app-rsc-handler.js +195 -59
  110. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  111. package/dist/server/app-rsc-route-matching.js +8 -2
  112. package/dist/server/app-segment-config.d.ts +9 -1
  113. package/dist/server/app-segment-config.js +12 -3
  114. package/dist/server/app-server-action-execution.d.ts +1 -0
  115. package/dist/server/app-server-action-execution.js +47 -15
  116. package/dist/server/app-ssr-entry.d.ts +2 -0
  117. package/dist/server/app-ssr-entry.js +84 -39
  118. package/dist/server/before-interactive-head.d.ts +17 -0
  119. package/dist/server/before-interactive-head.js +35 -0
  120. package/dist/server/cache-control.js +4 -0
  121. package/dist/server/csp.js +1 -4
  122. package/dist/server/dev-server.d.ts +2 -2
  123. package/dist/server/dev-server.js +321 -83
  124. package/dist/server/hybrid-route-priority.d.ts +22 -0
  125. package/dist/server/hybrid-route-priority.js +33 -0
  126. package/dist/server/image-optimization.d.ts +18 -9
  127. package/dist/server/image-optimization.js +37 -23
  128. package/dist/server/implicit-tags.d.ts +2 -1
  129. package/dist/server/implicit-tags.js +4 -1
  130. package/dist/server/middleware-matcher.js +12 -3
  131. package/dist/server/middleware-runtime.d.ts +3 -4
  132. package/dist/server/middleware-runtime.js +2 -0
  133. package/dist/server/navigation-planner.d.ts +135 -41
  134. package/dist/server/navigation-planner.js +138 -0
  135. package/dist/server/navigation-trace.d.ts +9 -1
  136. package/dist/server/navigation-trace.js +9 -1
  137. package/dist/server/operation-token.d.ts +40 -0
  138. package/dist/server/operation-token.js +85 -0
  139. package/dist/server/pages-api-route.d.ts +6 -0
  140. package/dist/server/pages-api-route.js +13 -2
  141. package/dist/server/pages-asset-tags.d.ts +2 -1
  142. package/dist/server/pages-asset-tags.js +6 -2
  143. package/dist/server/pages-data-route.d.ts +9 -2
  144. package/dist/server/pages-data-route.js +18 -6
  145. package/dist/server/pages-dev-module-url.d.ts +4 -0
  146. package/dist/server/pages-dev-module-url.js +15 -0
  147. package/dist/server/pages-document-initial-props.d.ts +4 -15
  148. package/dist/server/pages-document-initial-props.js +27 -56
  149. package/dist/server/pages-get-initial-props.d.ts +54 -4
  150. package/dist/server/pages-get-initial-props.js +43 -1
  151. package/dist/server/pages-i18n.js +2 -2
  152. package/dist/server/pages-node-compat.js +2 -2
  153. package/dist/server/pages-page-data.d.ts +11 -2
  154. package/dist/server/pages-page-data.js +207 -34
  155. package/dist/server/pages-page-handler.d.ts +4 -2
  156. package/dist/server/pages-page-handler.js +62 -23
  157. package/dist/server/pages-page-response.d.ts +4 -1
  158. package/dist/server/pages-page-response.js +11 -8
  159. package/dist/server/pages-readiness.js +1 -1
  160. package/dist/server/pages-request-pipeline.d.ts +8 -7
  161. package/dist/server/pages-request-pipeline.js +126 -47
  162. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  163. package/dist/server/pregenerated-concrete-paths.js +2 -19
  164. package/dist/server/prerender-manifest.d.ts +33 -0
  165. package/dist/server/prerender-manifest.js +54 -0
  166. package/dist/server/prerender-route-params.d.ts +1 -2
  167. package/dist/server/prod-server.d.ts +3 -1
  168. package/dist/server/prod-server.js +50 -13
  169. package/dist/server/request-pipeline.d.ts +3 -15
  170. package/dist/server/request-pipeline.js +58 -47
  171. package/dist/server/rsc-stream-hints.d.ts +5 -1
  172. package/dist/server/rsc-stream-hints.js +6 -1
  173. package/dist/server/seed-cache.js +10 -18
  174. package/dist/server/static-file-cache.js +16 -4
  175. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  176. package/dist/shims/app-router-scroll-state.js +14 -2
  177. package/dist/shims/app-router-scroll.d.ts +3 -0
  178. package/dist/shims/app-router-scroll.js +28 -18
  179. package/dist/shims/before-interactive-context.d.ts +14 -3
  180. package/dist/shims/cache-runtime.js +3 -2
  181. package/dist/shims/cache.d.ts +1 -0
  182. package/dist/shims/cache.js +1 -1
  183. package/dist/shims/cdn-cache.d.ts +5 -5
  184. package/dist/shims/document.d.ts +15 -20
  185. package/dist/shims/document.js +5 -8
  186. package/dist/shims/dynamic-preload-chunks.js +6 -4
  187. package/dist/shims/error-boundary.d.ts +2 -0
  188. package/dist/shims/error-boundary.js +7 -0
  189. package/dist/shims/error.js +3 -2
  190. package/dist/shims/error.react-server.d.ts +9 -0
  191. package/dist/shims/error.react-server.js +6 -0
  192. package/dist/shims/fetch-cache.d.ts +3 -1
  193. package/dist/shims/fetch-cache.js +45 -20
  194. package/dist/shims/hash-scroll.js +6 -1
  195. package/dist/shims/headers.js +29 -4
  196. package/dist/shims/image.js +9 -2
  197. package/dist/shims/internal/als-registry.js +28 -1
  198. package/dist/shims/internal/app-route-detection.js +8 -17
  199. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  201. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  202. package/dist/shims/internal/navigation-untracked.js +55 -0
  203. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  204. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  205. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  206. package/dist/shims/internal/pages-data-target.js +17 -8
  207. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  208. package/dist/shims/internal/pages-router-accessor.js +13 -0
  209. package/dist/shims/internal/router-context.d.ts +2 -1
  210. package/dist/shims/internal/router-context.js +3 -1
  211. package/dist/shims/link.js +47 -19
  212. package/dist/shims/metadata.js +4 -4
  213. package/dist/shims/navigation.d.ts +8 -2
  214. package/dist/shims/navigation.js +63 -31
  215. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  216. package/dist/shims/ppr-fallback-shell.js +28 -7
  217. package/dist/shims/router.d.ts +18 -3
  218. package/dist/shims/router.js +512 -142
  219. package/dist/shims/script.js +8 -4
  220. package/dist/shims/server.d.ts +16 -1
  221. package/dist/shims/server.js +44 -12
  222. package/dist/shims/unified-request-context.js +1 -0
  223. package/dist/utils/built-asset-url.d.ts +4 -0
  224. package/dist/utils/built-asset-url.js +11 -0
  225. package/dist/utils/commonjs-loader.d.ts +16 -0
  226. package/dist/utils/commonjs-loader.js +100 -0
  227. package/dist/utils/deployment-id.d.ts +8 -0
  228. package/dist/utils/deployment-id.js +22 -0
  229. package/dist/utils/has-trailing-comma.d.ts +24 -0
  230. package/dist/utils/has-trailing-comma.js +62 -0
  231. package/dist/utils/html-limited-bots.d.ts +18 -1
  232. package/dist/utils/html-limited-bots.js +23 -1
  233. package/dist/utils/parse-cookie.d.ts +13 -0
  234. package/dist/utils/parse-cookie.js +52 -0
  235. package/dist/utils/path.d.ts +7 -1
  236. package/dist/utils/path.js +9 -1
  237. package/dist/utils/text-stream.d.ts +1 -1
  238. package/dist/utils/text-stream.js +2 -2
  239. package/dist/utils/vite-version.d.ts +12 -1
  240. package/dist/utils/vite-version.js +9 -1
  241. package/package.json +2 -2
  242. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  243. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -1,29 +1,31 @@
1
1
  import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
3
- import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
3
+ import { beginPprFallbackShellFinalRender, createPprFallbackShellState, getPprFallbackShellState, runWithPprFallbackShellState } from "../shims/ppr-fallback-shell.js";
4
+ import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
4
5
  import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache.js";
5
6
  import { AppElementsWire } from "./app-elements-wire.js";
6
7
  import { shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
7
8
  import "./app-elements.js";
8
- import { consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
9
+ import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
9
10
  import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
10
- import { readStreamAsText } from "../utils/text-stream.js";
11
11
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
12
12
  import "./app-page-response.js";
13
- import { buildAppPageSpecialErrorResponse, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
13
+ import { buildAppPageSpecialErrorResponse, probeAppPageThrownError, resolveAppPageSpecialError } from "./app-page-execution.js";
14
14
  import { createAppPageTreePath } from "./app-page-route-wiring.js";
15
- import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope } from "./app-page-render-observation.js";
16
- import { readAppPageCacheResponse } from "./app-page-cache.js";
15
+ import { consumeAppPageRenderObservationState, discardAppPageRenderState } from "./app-page-render-observation.js";
16
+ import { rewriteAppPprFallbackShellHtmlNavigation } from "./app-ppr-fallback-shell.js";
17
+ import { readAppPageCacheResponse, readAppPageFallbackShellCacheResponse } from "./app-page-cache.js";
17
18
  import { resolveAppPageParentHttpAccessBoundary, resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
18
- import { isAppSsrRenderResult } from "./app-page-stream.js";
19
19
  import { createAppLayoutParamAccessTracker, isAppLayoutObservationUnsafeForStaticReuse } from "./app-layout-param-observation.js";
20
+ import { buildAppPageTags } from "./implicit-tags.js";
21
+ import { renderAppPageCacheArtifacts } from "./app-page-cache-render.js";
22
+ import { warmPprFallbackShellCaches } from "./app-ppr-fallback-shell-render.js";
20
23
  import { resolveAppPageMethodResponse } from "./app-page-method.js";
21
24
  import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
22
25
  import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
23
26
  import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
24
27
  import { renderAppPageLifecycle } from "./app-page-render.js";
25
28
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
26
- import { buildPageCacheTags } from "./implicit-tags.js";
27
29
  import React from "react";
28
30
  //#region src/server/app-page-dispatch.ts
29
31
  function resolveAppPageRouteBoundaryModule(route, statusCode) {
@@ -107,9 +109,6 @@ function shouldReadAppPageCache(options) {
107
109
  function hasSearchParams(searchParams) {
108
110
  return searchParams !== null && searchParams !== void 0 && searchParams.size > 0;
109
111
  }
110
- function buildAppPageTags(cleanPathname, extraTags, routeSegments) {
111
- return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], "page");
112
- }
113
112
  async function runAppPageRevalidationContext(options, renderFn) {
114
113
  return runWithRequestContext(createRequestContext({
115
114
  headersContext: createStaticGenerationHeadersContext({
@@ -119,6 +118,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
119
118
  routePattern: options.routePattern
120
119
  }),
121
120
  currentFetchCacheMode: options.currentFetchCacheMode ?? null,
121
+ currentForceDynamicFetchDefault: options.dynamicConfig === "force-dynamic",
122
122
  executionContext: getRequestExecutionContext(),
123
123
  unstableCacheRevalidation: "foreground"
124
124
  }), async () => {
@@ -132,10 +132,6 @@ async function runAppPageRevalidationContext(options, renderFn) {
132
132
  return await runWithFetchDedupe(renderFn);
133
133
  });
134
134
  }
135
- function getCapturedRscDataPromise(capturedRscDataPromise) {
136
- if (!capturedRscDataPromise) throw new Error("[vinext] Expected captured RSC data while regenerating an app page cache entry");
137
- return capturedRscDataPromise;
138
- }
139
135
  function toInterceptOptions(interceptionContext, intercept) {
140
136
  return {
141
137
  interceptionContext,
@@ -144,11 +140,77 @@ function toInterceptOptions(interceptionContext, intercept) {
144
140
  interceptParams: intercept.matchedParams,
145
141
  interceptSlotId: intercept.slotId ?? null,
146
142
  interceptSlotKey: intercept.slotKey,
147
- interceptSourceMatchedUrl: interceptionContext
143
+ interceptSourceMatchedUrl: interceptionContext,
144
+ interceptSourcePageSegments: intercept.sourcePageSegments ?? null
145
+ };
146
+ }
147
+ /**
148
+ * Request-phase fallback-shell gate. Callers must run the exact cache read and
149
+ * static-param validation before this classification step.
150
+ */
151
+ function classifyPprFallbackShellEligibility(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) {
152
+ if (options.renderedConcreteUrlPaths?.has(options.cleanPathname) === true) return { kind: "skip-known-pregenerated-route" };
153
+ const fallbackShells = options.pprFallbackCacheShells;
154
+ if (!fallbackShells || fallbackShells.length === 0) return { kind: "skip-no-fallback-shells" };
155
+ if (options.isRscRequest) return { kind: "skip-rsc-request" };
156
+ if (options.request.method !== "GET") return { kind: "skip-non-get" };
157
+ if (!isForceStatic && hasSearchParams(options.searchParams)) return { kind: "skip-search-params" };
158
+ if (!shouldReadAppPageCache({
159
+ isDraftMode,
160
+ isForceDynamic,
161
+ isProgressiveActionRender: options.isProgressiveActionRender === true,
162
+ isProduction: options.isProduction,
163
+ isRscRequest: false,
164
+ revalidateSeconds: currentRevalidateSeconds,
165
+ scriptNonce: options.scriptNonce
166
+ })) return { kind: "skip-cache-disabled" };
167
+ return {
168
+ kind: "probe-fallback-shells",
169
+ fallbackShells
148
170
  };
149
171
  }
172
+ async function probePprFallbackShellCache(options, route, fallbackShells, currentRevalidateSeconds) {
173
+ for (const fallbackShell of fallbackShells) {
174
+ const fallbackShellResponse = await readAppPageFallbackShellCacheResponse({
175
+ clearRequestContext: options.clearRequestContext,
176
+ expireSeconds: options.expireSeconds,
177
+ fallbackPathname: fallbackShell.pathname,
178
+ isEdgeRuntime: options.isEdgeRuntime,
179
+ isrDebug: options.isrDebug,
180
+ isrGet: options.isrGet,
181
+ isrHtmlKey: options.isrHtmlKey,
182
+ middlewareHeaders: options.middlewareContext.headers,
183
+ middlewareStatus: options.middlewareContext.status,
184
+ revalidateSeconds: currentRevalidateSeconds ?? 0,
185
+ rewriteHtml(html) {
186
+ return rewriteAppPprFallbackShellHtmlNavigation({
187
+ html,
188
+ params: options.params,
189
+ pathname: options.cleanPathname,
190
+ searchParams: options.searchParams
191
+ });
192
+ }
193
+ });
194
+ if (fallbackShellResponse) return fallbackShellResponse;
195
+ }
196
+ return null;
197
+ }
198
+ async function tryServePprFallbackShell(options, route, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic) {
199
+ const decision = classifyPprFallbackShellEligibility(options, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic);
200
+ switch (decision.kind) {
201
+ case "skip-known-pregenerated-route":
202
+ case "skip-no-fallback-shells":
203
+ case "skip-rsc-request":
204
+ case "skip-non-get":
205
+ case "skip-search-params":
206
+ case "skip-cache-disabled": return null;
207
+ case "probe-fallback-shells": return await probePprFallbackShellCache(options, route, decision.fallbackShells, currentRevalidateSeconds);
208
+ }
209
+ }
150
210
  async function dispatchAppPage(options) {
151
- return await runWithFetchDedupe(() => dispatchAppPageInner(options));
211
+ const dispatch = () => runWithFetchDedupe(() => dispatchAppPageInner(options));
212
+ if (!options.pprFallbackShell) return await dispatch();
213
+ return await runWithPprFallbackShellState(createPprFallbackShellState(options.pprFallbackShell), dispatch);
152
214
  }
153
215
  async function dispatchAppPageInner(options) {
154
216
  const route = options.route;
@@ -161,6 +223,7 @@ async function dispatchAppPageInner(options) {
161
223
  const layoutParamAccess = createAppLayoutParamAccessTracker();
162
224
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
163
225
  setCurrentFetchCacheMode(options.fetchCache ?? null);
226
+ setCurrentForceDynamicFetchDefault(isForceDynamic);
164
227
  if (options.hasPageModule && !options.hasPageDefaultExport) {
165
228
  options.clearRequestContext();
166
229
  return new Response("Page has no default export", { status: 500 });
@@ -242,7 +305,7 @@ async function dispatchAppPageInner(options) {
242
305
  displayPathname: options.displayPathname,
243
306
  currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
244
307
  draftModeSecret: options.draftModeSecret,
245
- dynamicConfig,
308
+ dynamicConfig: options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0),
246
309
  params: revalidationTarget.navigationParams,
247
310
  routePattern: revalidationTarget.route.pattern,
248
311
  routeSegments: revalidationTarget.route.routeSegments,
@@ -250,72 +313,34 @@ async function dispatchAppPageInner(options) {
250
313
  }, async () => {
251
314
  const revalidatedElement = await options.buildPageElement(revalidationTarget.route, revalidationTarget.params, revalidationTarget.interceptOpts, new URLSearchParams());
252
315
  const revalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern);
253
- const revalidatedRscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(revalidatedElement, { onError: revalidatedOnError }), true);
254
- const revalidatedSsrEntry = await options.loadSsrHandler();
255
- const revalidatedCapturedRscRef = { value: null };
256
- const revalidatedHtmlResult = await revalidatedSsrEntry.handleSsr(revalidatedRscCapture.ssrStream, options.getNavigationContext(), {
257
- links: options.getFontLinks(),
258
- styles: options.getFontStyles(),
259
- preloads: options.getFontPreloads()
260
- }, {
316
+ const rendered = await renderAppPageCacheArtifacts({
261
317
  basePath: options.basePath,
318
+ captureRscData: true,
319
+ cleanPathname: options.cleanPathname,
262
320
  clientTraceMetadata: options.clientTraceMetadata,
321
+ element: revalidatedElement,
322
+ getFontLinks: options.getFontLinks,
323
+ getFontPreloads: options.getFontPreloads,
324
+ getFontStyles: options.getFontStyles,
325
+ getNavigationContext: options.getNavigationContext,
326
+ loadSsrHandler: options.loadSsrHandler,
327
+ mountedSlotsHeader: options.mountedSlotsHeader,
328
+ navigationParams: revalidationTarget.navigationParams,
329
+ onError: revalidatedOnError,
263
330
  reactMaxHeadersLength: options.reactMaxHeadersLength,
331
+ renderToReadableStream: options.renderToReadableStream,
264
332
  rootParams: options.rootParams,
265
- waitForAllReady: true,
266
- ...revalidatedRscCapture.sideStream ? {
267
- sideStream: revalidatedRscCapture.sideStream,
268
- capturedRscDataRef: revalidatedCapturedRscRef
269
- } : {}
333
+ route: revalidationTarget.route,
334
+ waitForAllReady: true
270
335
  });
271
- const html = await readStreamAsText(isAppSsrRenderResult(revalidatedHtmlResult) ? revalidatedHtmlResult.htmlStream : revalidatedHtmlResult);
272
- const rscData = await getCapturedRscDataPromise(revalidatedCapturedRscRef.value);
273
- const cacheLife = _consumeRequestScopedCacheLife();
274
336
  options.clearRequestContext();
275
- const tags = buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), revalidationTarget.route.routeSegments);
276
- const observationState = {
277
- dynamicFetches: consumeDynamicFetchObservations(),
278
- requestApis: consumeRenderRequestApiUsage()
279
- };
280
337
  return {
281
- html,
282
- htmlRenderObservation: createAppPageRenderObservation({
283
- boundaryOutcome: { kind: "success" },
284
- cacheability: "public",
285
- cacheTags: tags,
286
- cleanPathname: options.cleanPathname,
287
- completeness: "complete",
288
- output: createAppPageHtmlOutputScope({
289
- element: revalidatedElement,
290
- renderEpoch: null,
291
- rootBoundaryId: null,
292
- routePattern: revalidationTarget.route.pattern
293
- }),
294
- params: revalidationTarget.navigationParams,
295
- state: observationState
296
- }),
297
- rscData,
298
- rscRenderObservation: createAppPageRenderObservation({
299
- boundaryOutcome: { kind: "success" },
300
- cacheability: "public",
301
- cacheTags: tags,
302
- cleanPathname: options.cleanPathname,
303
- completeness: "complete",
304
- output: createAppPageRscOutputScope({
305
- element: revalidatedElement,
306
- mountedSlotsHeader: options.mountedSlotsHeader,
307
- renderEpoch: null,
308
- rootBoundaryId: null,
309
- routePattern: revalidationTarget.route.pattern
310
- }),
311
- params: revalidationTarget.navigationParams,
312
- state: observationState
313
- }),
314
- tags,
315
- cacheControl: typeof cacheLife?.revalidate === "number" ? {
316
- revalidate: cacheLife.revalidate,
317
- expire: cacheLife.expire
318
- } : void 0
338
+ html: rendered.html,
339
+ htmlRenderObservation: rendered.htmlRenderObservation,
340
+ rscData: rendered.rscData,
341
+ rscRenderObservation: rendered.rscRenderObservation,
342
+ tags: rendered.tags,
343
+ cacheControl: rendered.cacheControl
319
344
  };
320
345
  });
321
346
  },
@@ -329,18 +354,23 @@ async function dispatchAppPageInner(options) {
329
354
  });
330
355
  if (cachedPageResponse) return cachedPageResponse;
331
356
  }
332
- const dynamicParamsResponse = await validateAppPageDynamicParams({
333
- clearRequestContext: options.clearRequestContext,
334
- enforceStaticParamsOnly: options.dynamicParamsConfig === false,
335
- generateStaticParams: options.generateStaticParams,
336
- isDynamicRoute: route.isDynamic,
337
- params: options.staticParamsValidationParams ?? options.params
338
- });
339
- if (dynamicParamsResponse) return dynamicParamsResponse;
357
+ if (options.skipStaticParamsValidation !== true) {
358
+ const dynamicParamsResponse = await validateAppPageDynamicParams({
359
+ clearRequestContext: options.clearRequestContext,
360
+ enforceStaticParamsOnly: options.dynamicParamsConfig === false,
361
+ generateStaticParams: options.generateStaticParams,
362
+ isDynamicRoute: route.isDynamic,
363
+ params: options.staticParamsValidationParams ?? options.params
364
+ });
365
+ if (dynamicParamsResponse) return dynamicParamsResponse;
366
+ }
367
+ const fallbackShellResponse = await tryServePprFallbackShell(options, route, currentRevalidateSeconds, isDraftMode, isForceStatic, isForceDynamic);
368
+ if (fallbackShellResponse) return fallbackShellResponse;
340
369
  const interceptResult = await resolveAppPageIntercept({
341
370
  async buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess) {
342
371
  await options.ensureRouteLoaded?.(interceptRoute);
343
372
  setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
373
+ setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(interceptRoute) === "force-dynamic");
344
374
  return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess);
345
375
  },
346
376
  cleanPathname: options.cleanPathname,
@@ -380,11 +410,20 @@ async function dispatchAppPageInner(options) {
380
410
  }
381
411
  });
382
412
  if (interceptResult.response) return interceptResult.response;
383
- const pageBuildResult = await buildAppPageElement({
413
+ const buildCurrentPageElement = () => buildAppPageElement({
384
414
  buildPageElement() {
385
415
  if (options.actionFailed) throw options.actionError;
386
416
  return options.buildPageElement(route, options.params, interceptResult.interceptOpts, options.searchParams, layoutParamAccess);
387
417
  },
418
+ async probePageSpecialError() {
419
+ if (!shouldSuppressLoadingBoundaries(options.renderMode ?? "navigation") && route.loading?.default) return null;
420
+ return resolveAppPageSpecialError(await probeAppPageThrownError({
421
+ probePage: options.probePage,
422
+ runWithSuppressedHookWarning(probe) {
423
+ return options.runWithSuppressedHookWarning(probe);
424
+ }
425
+ }));
426
+ },
388
427
  renderErrorBoundaryPage(buildError) {
389
428
  return options.renderErrorBoundaryPage(buildError);
390
429
  },
@@ -393,6 +432,19 @@ async function dispatchAppPageInner(options) {
393
432
  },
394
433
  resolveSpecialError: resolveAppPageSpecialError
395
434
  });
435
+ const fallbackShellState = getPprFallbackShellState();
436
+ if (fallbackShellState && process.env.VINEXT_PRERENDER === "1" && !options.isRscRequest) {
437
+ const warmupBuildResult = await buildCurrentPageElement();
438
+ if (warmupBuildResult.response) return warmupBuildResult.response;
439
+ await warmPprFallbackShellCaches({
440
+ element: warmupBuildResult.element,
441
+ onError: options.createRscOnErrorHandler(options.cleanPathname, route.pattern),
442
+ renderToReadableStream: options.renderToReadableStream,
443
+ state: fallbackShellState
444
+ });
445
+ discardAppPageRenderState();
446
+ }
447
+ const pageBuildResult = await buildCurrentPageElement();
396
448
  if (pageBuildResult.response) return pageBuildResult.response;
397
449
  const navigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, interceptResult.interceptOpts);
398
450
  options.setNavigationContext({
@@ -401,6 +453,9 @@ async function dispatchAppPageInner(options) {
401
453
  params: navigationParams
402
454
  });
403
455
  const layoutClassifications = getEffectiveLayoutClassifications(route, options.debugClassification);
456
+ const activeFallbackShellState = getPprFallbackShellState();
457
+ const pprFallbackShellSignal = activeFallbackShellState?.abortController.signal;
458
+ const pprFallbackShellReactSignal = activeFallbackShellState?.reactAbortController.signal;
404
459
  return renderAppPageLifecycle({
405
460
  basePath: options.basePath,
406
461
  clientTraceMetadata: options.clientTraceMetadata,
@@ -409,12 +464,7 @@ async function dispatchAppPageInner(options) {
409
464
  clearRequestContext: options.clearRequestContext,
410
465
  consumeDynamicUsage,
411
466
  consumeInvalidDynamicUsageError,
412
- consumeRenderObservationState() {
413
- return {
414
- dynamicFetches: consumeDynamicFetchObservations(),
415
- requestApis: consumeRenderRequestApiUsage()
416
- };
417
- },
467
+ consumeRenderObservationState: consumeAppPageRenderObservationState,
418
468
  createRscOnErrorHandler(pathname, routePath) {
419
469
  return options.createRscOnErrorHandler(pathname, routePath);
420
470
  },
@@ -457,6 +507,11 @@ async function dispatchAppPageInner(options) {
457
507
  middlewareContext: options.middlewareContext,
458
508
  navigationParams,
459
509
  params: options.params,
510
+ pprFallbackShellSignal,
511
+ pprFallbackShellReactSignal,
512
+ abortPprFallbackShell: activeFallbackShellState ? () => {
513
+ beginPprFallbackShellFinalRender(activeFallbackShellState);
514
+ } : void 0,
460
515
  layoutParamAccess,
461
516
  rootParams: options.rootParams,
462
517
  peekRenderObservationState() {
@@ -509,6 +564,8 @@ async function dispatchAppPageInner(options) {
509
564
  return renderPageSpecialError(options, specialError);
510
565
  },
511
566
  renderToReadableStream: options.renderToReadableStream,
567
+ hasCustomGlobalError: options.hasCustomGlobalError,
568
+ prerenderToReadableStream: options.prerenderToReadableStream,
512
569
  routePattern: route.pattern,
513
570
  runWithSuppressedHookWarning(probe) {
514
571
  return options.runWithSuppressedHookWarning(probe);
@@ -24,6 +24,7 @@ type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
24
24
  interceptSlotId?: string | null;
25
25
  interceptSlotKey?: string | null;
26
26
  interceptSourceMatchedUrl?: string | null;
27
+ interceptSourcePageSegments?: readonly string[] | null;
27
28
  };
28
29
  type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
29
30
  /** Interception context from current-route navigation (null for direct visits). */opts?: AppPageInterceptOptions<TModule> | null; /** URL search params from the incoming request (null when unavailable). */
@@ -6,7 +6,7 @@ import { createAppPageRenderIdentity } from "./app-page-render-identity.js";
6
6
  import { makeThenableParams } from "../shims/thenable-params.js";
7
7
  import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
8
8
  import { makeObservedAppPageSearchParamsThenable } from "./app-page-search-params-observation.js";
9
- import { buildAppPageElements, createAppPageTreePath } from "./app-page-route-wiring.js";
9
+ import { buildAppPageElements, createAppPageSourcePage, createAppPageTreePath } from "./app-page-route-wiring.js";
10
10
  import { DEFAULT_GLOBAL_ERROR_MODULE } from "./default-global-error-module.js";
11
11
  import "./app-rsc-route-matching.js";
12
12
  import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
@@ -36,6 +36,7 @@ async function buildPageElements(options) {
36
36
  const effectivePageModule = isSiblingIntercept ? opts.interceptPage : pageModule;
37
37
  const EffectivePageComponent = effectivePageModule?.default;
38
38
  const effectiveParams = isSiblingIntercept ? opts.interceptParams ?? params : params;
39
+ const sourcePageSegments = isSiblingIntercept ? opts?.interceptSourcePageSegments : route.routeSegments;
39
40
  const hasPageModule = !!pageModule;
40
41
  const renderIdentity = createAppPageRenderIdentity({
41
42
  displayPathname,
@@ -56,7 +57,8 @@ async function buildPageElements(options) {
56
57
  interceptionContext: renderIdentity.interceptionContext,
57
58
  layoutIds: noExportLayoutIds,
58
59
  rootLayoutTreePath: noExportRootLayout,
59
- routeId: renderIdentity.routeId
60
+ routeId: renderIdentity.routeId,
61
+ sourcePage: createAppPageSourcePage(sourcePageSegments)
60
62
  }),
61
63
  [renderIdentity.routeId]: createElement("div", null, "Page has no default export")
62
64
  };
@@ -112,6 +114,7 @@ async function buildPageElements(options) {
112
114
  resolvedViewport,
113
115
  renderIdentity,
114
116
  routePath,
117
+ sourcePageSegments,
115
118
  rootNotFoundModule: rootNotFoundModule ?? null,
116
119
  rootForbiddenModule: rootForbiddenModule ?? null,
117
120
  rootUnauthorizedModule: rootUnauthorizedModule ?? null,
@@ -121,13 +121,18 @@ type ProbeAppPageComponentOptions = {
121
121
  probePage: () => unknown;
122
122
  runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
123
123
  };
124
+ type ProbeAppPageThrownErrorOptions = {
125
+ probePage: () => unknown;
126
+ runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
127
+ };
124
128
  declare function resolveAppPageSpecialError(error: unknown): AppPageSpecialError | null;
125
129
  declare function buildAppPageSpecialErrorResponse(options: BuildAppPageSpecialErrorResponseOptions): Promise<Response>;
126
130
  /** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */
127
131
  declare function probeAppPageLayouts(options: ProbeAppPageLayoutsOptions): Promise<ProbeAppPageLayoutsResult>;
128
132
  declare function probeAppPageComponent(options: ProbeAppPageComponentOptions): Promise<Response | null>;
133
+ declare function probeAppPageThrownError(options: ProbeAppPageThrownErrorOptions): Promise<unknown>;
129
134
  declare function readAppPageBinaryStream(stream: ReadableStream<Uint8Array>): Promise<ArrayBuffer>;
130
135
  declare function teeAppPageRscStreamForCapture(stream: ReadableStream<Uint8Array>, shouldCapture: boolean): AppPageRscStreamCapture;
131
136
  declare function buildAppPageFontLinkHeader(preloads: readonly AppPageFontPreload[] | null | undefined): string;
132
137
  //#endregion
133
- export { AppPageFontPreload, AppPageSpecialError, LayoutClassificationOptions, type LayoutFlags, buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
138
+ export { AppPageFontPreload, AppPageSpecialError, LayoutClassificationOptions, type LayoutFlags, buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, probeAppPageThrownError, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
@@ -274,6 +274,26 @@ async function probeAppPageComponent(options) {
274
274
  return outcome.completed ? outcome.result : null;
275
275
  });
276
276
  }
277
+ async function probeAppPageThrownError(options) {
278
+ return options.runWithSuppressedHookWarning(async () => {
279
+ const outcome = await runWithConnectionProbe(async () => {
280
+ try {
281
+ const pageResult = options.probePage();
282
+ if (isPromiseLike(pageResult)) await pageResult;
283
+ } catch (error) {
284
+ return {
285
+ error,
286
+ thrown: true
287
+ };
288
+ }
289
+ return {
290
+ error: null,
291
+ thrown: false
292
+ };
293
+ });
294
+ return outcome.completed && outcome.result.thrown ? outcome.result.error : null;
295
+ });
296
+ }
277
297
  async function readAppPageBinaryStream(stream) {
278
298
  const reader = stream.getReader();
279
299
  const chunks = [];
@@ -305,4 +325,4 @@ function buildAppPageFontLinkHeader(preloads) {
305
325
  return preloads.map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`).join(", ");
306
326
  }
307
327
  //#endregion
308
- export { buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
328
+ export { buildAppPageFontLinkHeader, buildAppPageSpecialErrorResponse, probeAppPageComponent, probeAppPageLayouts, probeAppPageThrownError, readAppPageBinaryStream, resolveAppPageSpecialError, tagAppPageMetadataError, teeAppPageRscStreamForCapture };
@@ -119,6 +119,7 @@ type ProbeAppPageBeforeRenderResult = {
119
119
  };
120
120
  type ProbeAppPageBeforeRenderOptions = {
121
121
  hasLoadingBoundary: boolean;
122
+ skipProbes?: boolean;
122
123
  layoutCount: number;
123
124
  probeLayoutAt: (layoutIndex: number) => unknown;
124
125
  probePage: () => unknown;
@@ -227,6 +227,10 @@ function buildAppPageProbes(options) {
227
227
  }
228
228
  async function probeAppPageBeforeRender(options) {
229
229
  let layoutFlags = {};
230
+ if (options.skipProbes) return {
231
+ response: null,
232
+ layoutFlags
233
+ };
230
234
  if (options.layoutCount > 0) {
231
235
  const layoutProbeResult = await probeAppPageLayouts({
232
236
  layoutCount: options.layoutCount,
@@ -7,6 +7,8 @@ type AppPageRenderObservationState = Readonly<{
7
7
  requestApis: readonly RenderRequestApiKind[];
8
8
  }>;
9
9
  declare function createEmptyAppPageRenderObservationState(): AppPageRenderObservationState;
10
+ declare function consumeAppPageRenderObservationState(): AppPageRenderObservationState;
11
+ declare function discardAppPageRenderState(): void;
10
12
  declare function createAppPageRenderObservation(options: {
11
13
  boundaryOutcome: BoundaryOutcome;
12
14
  cacheTags: readonly string[];
@@ -31,4 +33,4 @@ declare function createAppPageHtmlOutputScope(options: {
31
33
  routePattern: string;
32
34
  }): CacheProofOutputScope;
33
35
  //#endregion
34
- export { AppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState };
36
+ export { AppPageRenderObservationState, consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState, discardAppPageRenderState };
@@ -1,7 +1,10 @@
1
+ import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage } from "../shims/headers.js";
1
2
  import { fnv1a64 } from "../utils/hash.js";
3
+ import { _consumeRequestScopedCacheLife } from "../shims/cache.js";
2
4
  import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
3
5
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
4
6
  import "./app-elements.js";
7
+ import { consumeDynamicFetchObservations } from "../shims/fetch-cache.js";
5
8
  import { buildRenderObservation, buildRenderRequestApiObservations } from "./cache-proof.js";
6
9
  //#region src/server/app-page-render-observation.ts
7
10
  function readRootBoundaryId(element) {
@@ -30,6 +33,19 @@ function createEmptyAppPageRenderObservationState() {
30
33
  requestApis: []
31
34
  };
32
35
  }
36
+ function consumeAppPageRenderObservationState() {
37
+ return {
38
+ dynamicFetches: consumeDynamicFetchObservations(),
39
+ requestApis: consumeRenderRequestApiUsage()
40
+ };
41
+ }
42
+ function discardAppPageRenderState() {
43
+ _consumeRequestScopedCacheLife();
44
+ consumeDynamicFetchObservations();
45
+ consumeRenderRequestApiUsage();
46
+ consumeInvalidDynamicUsageError();
47
+ consumeDynamicUsage();
48
+ }
33
49
  function createAppPageRenderObservation(options) {
34
50
  return buildRenderObservation({
35
51
  boundaryOutcome: options.boundaryOutcome,
@@ -63,4 +79,4 @@ function createAppPageHtmlOutputScope(options) {
63
79
  };
64
80
  }
65
81
  //#endregion
66
- export { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState };
82
+ export { consumeAppPageRenderObservationState, createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState, discardAppPageRenderState };
@@ -7,8 +7,8 @@ import { AppPageMiddlewareContext } from "./app-page-response.js";
7
7
  import { RootParams } from "../shims/root-params.js";
8
8
  import { AppPageSsrHandler } from "./app-page-stream.js";
9
9
  import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
10
- import { AppRscRenderMode } from "./app-rsc-render-mode.js";
11
10
  import { AppPageRenderObservationState } from "./app-page-render-observation.js";
11
+ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
12
12
  import { ReactNode } from "react";
13
13
  import { ReactFormState } from "react-dom/client";
14
14
 
@@ -49,6 +49,7 @@ type RenderAppPageLifecycleOptions = {
49
49
  peekRequestCacheLife?: () => AppPageRequestCacheLife | null;
50
50
  getDraftModeCookieHeader: () => string | null | undefined;
51
51
  handlerStart: number;
52
+ hasCustomGlobalError?: boolean;
52
53
  hasLoadingBoundary: boolean;
53
54
  dynamicStaleTimeSeconds?: number;
54
55
  isDynamicError: boolean;
@@ -70,6 +71,9 @@ type RenderAppPageLifecycleOptions = {
70
71
  middlewareContext: AppPageMiddlewareContext;
71
72
  navigationParams: Record<string, unknown>;
72
73
  params: Record<string, unknown>;
74
+ pprFallbackShellSignal?: AbortSignal;
75
+ pprFallbackShellReactSignal?: AbortSignal;
76
+ abortPprFallbackShell?: () => void;
73
77
  rootParams?: RootParams;
74
78
  peekRenderObservationState?: () => AppPageRenderObservationState;
75
79
  probeLayoutAt: (layoutIndex: number) => unknown;
@@ -82,7 +86,14 @@ type RenderAppPageLifecycleOptions = {
82
86
  renderPageSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
83
87
  renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
84
88
  onError: AppPageBoundaryOnError;
89
+ signal?: AbortSignal;
85
90
  }) => ReadableStream<Uint8Array>;
91
+ prerenderToReadableStream?: (element: ReactNode | AppOutgoingElements, options: {
92
+ onError: AppPageBoundaryOnError;
93
+ signal?: AbortSignal;
94
+ }) => Promise<{
95
+ prelude: ReadableStream<Uint8Array>;
96
+ }>;
86
97
  routePattern: string;
87
98
  runWithSuppressedHookWarning<T>(probe: () => Promise<T>): Promise<T>;
88
99
  scriptNonce?: string;