vinext 0.1.1 → 0.1.3

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 (266) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/build/prerender.d.ts +9 -1
  5. package/dist/build/prerender.js +41 -12
  6. package/dist/build/run-prerender.d.ts +10 -2
  7. package/dist/build/run-prerender.js +15 -1
  8. package/dist/check.js +4 -3
  9. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  10. package/dist/client/app-nav-failure-handler.js +44 -0
  11. package/dist/client/navigation-runtime.d.ts +3 -2
  12. package/dist/client/vinext-next-data.d.ts +18 -1
  13. package/dist/client/window-next.d.ts +8 -5
  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 -4
  17. package/dist/config/config-matchers.js +88 -16
  18. package/dist/config/next-config.d.ts +59 -4
  19. package/dist/config/next-config.js +149 -48
  20. package/dist/deploy.d.ts +30 -11
  21. package/dist/deploy.js +189 -101
  22. package/dist/entries/app-browser-entry.d.ts +9 -3
  23. package/dist/entries/app-browser-entry.js +21 -3
  24. package/dist/entries/app-rsc-entry.d.ts +2 -0
  25. package/dist/entries/app-rsc-entry.js +71 -6
  26. package/dist/entries/app-rsc-manifest.js +2 -0
  27. package/dist/entries/app-ssr-entry.js +1 -1
  28. package/dist/entries/pages-client-entry.js +54 -9
  29. package/dist/entries/pages-server-entry.js +48 -11
  30. package/dist/index.d.ts +0 -2
  31. package/dist/index.js +285 -139
  32. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  33. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  34. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  35. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  36. package/dist/plugins/og-assets.js +2 -2
  37. package/dist/plugins/optimize-imports.d.ts +10 -5
  38. package/dist/plugins/optimize-imports.js +27 -21
  39. package/dist/plugins/postcss.js +7 -7
  40. package/dist/plugins/sass.d.ts +53 -24
  41. package/dist/plugins/sass.js +249 -1
  42. package/dist/plugins/typeof-window.d.ts +14 -0
  43. package/dist/plugins/typeof-window.js +150 -0
  44. package/dist/plugins/wasm-module-import.d.ts +15 -0
  45. package/dist/plugins/wasm-module-import.js +50 -0
  46. package/dist/routing/app-route-graph.d.ts +25 -2
  47. package/dist/routing/app-route-graph.js +91 -22
  48. package/dist/routing/file-matcher.d.ts +10 -1
  49. package/dist/routing/file-matcher.js +23 -2
  50. package/dist/routing/pages-router.js +3 -3
  51. package/dist/routing/utils.d.ts +35 -6
  52. package/dist/routing/utils.js +59 -7
  53. package/dist/server/api-handler.d.ts +6 -1
  54. package/dist/server/api-handler.js +21 -15
  55. package/dist/server/app-browser-action-result.d.ts +19 -6
  56. package/dist/server/app-browser-action-result.js +19 -10
  57. package/dist/server/app-browser-entry.js +269 -297
  58. package/dist/server/app-browser-error.d.ts +10 -3
  59. package/dist/server/app-browser-error.js +47 -6
  60. package/dist/server/app-browser-history-controller.d.ts +104 -0
  61. package/dist/server/app-browser-history-controller.js +210 -0
  62. package/dist/server/app-browser-hydration.d.ts +2 -0
  63. package/dist/server/app-browser-hydration.js +1 -0
  64. package/dist/server/app-browser-navigation-controller.d.ts +7 -4
  65. package/dist/server/app-browser-navigation-controller.js +33 -9
  66. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  67. package/dist/server/app-browser-rsc-redirect.js +30 -8
  68. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  69. package/dist/server/app-browser-server-action-navigation.js +9 -0
  70. package/dist/server/app-browser-state.js +4 -7
  71. package/dist/server/app-browser-stream.js +86 -43
  72. package/dist/server/app-browser-visible-commit.js +1 -1
  73. package/dist/server/app-elements-wire.d.ts +6 -1
  74. package/dist/server/app-elements-wire.js +14 -4
  75. package/dist/server/app-elements.d.ts +2 -2
  76. package/dist/server/app-elements.js +2 -2
  77. package/dist/server/app-fallback-renderer.d.ts +3 -1
  78. package/dist/server/app-fallback-renderer.js +6 -2
  79. package/dist/server/app-middleware.js +1 -0
  80. package/dist/server/app-optimistic-routing.js +24 -3
  81. package/dist/server/app-page-boundary-render.d.ts +3 -1
  82. package/dist/server/app-page-boundary-render.js +31 -16
  83. package/dist/server/app-page-cache-render.d.ts +53 -0
  84. package/dist/server/app-page-cache-render.js +91 -0
  85. package/dist/server/app-page-cache.d.ts +16 -2
  86. package/dist/server/app-page-cache.js +71 -8
  87. package/dist/server/app-page-dispatch.d.ts +34 -0
  88. package/dist/server/app-page-dispatch.js +167 -97
  89. package/dist/server/app-page-element-builder.d.ts +23 -2
  90. package/dist/server/app-page-element-builder.js +42 -10
  91. package/dist/server/app-page-execution.d.ts +7 -2
  92. package/dist/server/app-page-execution.js +53 -18
  93. package/dist/server/app-page-probe.d.ts +1 -0
  94. package/dist/server/app-page-probe.js +4 -0
  95. package/dist/server/app-page-render-observation.d.ts +3 -1
  96. package/dist/server/app-page-render-observation.js +17 -1
  97. package/dist/server/app-page-render.d.ts +13 -2
  98. package/dist/server/app-page-render.js +48 -17
  99. package/dist/server/app-page-request.d.ts +3 -0
  100. package/dist/server/app-page-request.js +5 -3
  101. package/dist/server/app-page-response.js +1 -1
  102. package/dist/server/app-page-route-wiring.d.ts +5 -1
  103. package/dist/server/app-page-route-wiring.js +21 -11
  104. package/dist/server/app-page-stream.d.ts +16 -9
  105. package/dist/server/app-page-stream.js +12 -9
  106. package/dist/server/app-pages-bridge.d.ts +18 -0
  107. package/dist/server/app-pages-bridge.js +22 -5
  108. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  109. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  110. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  111. package/dist/server/app-ppr-fallback-shell.js +8 -1
  112. package/dist/server/app-route-handler-dispatch.js +9 -2
  113. package/dist/server/app-route-handler-policy.d.ts +1 -0
  114. package/dist/server/app-route-handler-response.js +11 -10
  115. package/dist/server/app-route-handler-runtime.js +12 -1
  116. package/dist/server/app-router-entry.js +5 -0
  117. package/dist/server/app-rsc-cache-busting.js +2 -0
  118. package/dist/server/app-rsc-handler.d.ts +25 -0
  119. package/dist/server/app-rsc-handler.js +153 -53
  120. package/dist/server/app-rsc-response-finalizer.js +1 -1
  121. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  122. package/dist/server/app-rsc-route-matching.js +2 -0
  123. package/dist/server/app-segment-config.d.ts +9 -1
  124. package/dist/server/app-segment-config.js +12 -3
  125. package/dist/server/app-server-action-execution.d.ts +12 -0
  126. package/dist/server/app-server-action-execution.js +47 -15
  127. package/dist/server/app-ssr-entry.d.ts +2 -0
  128. package/dist/server/app-ssr-entry.js +81 -8
  129. package/dist/server/app-ssr-stream.js +9 -1
  130. package/dist/server/cache-control.js +4 -0
  131. package/dist/server/dev-lockfile.js +2 -1
  132. package/dist/server/dev-server.d.ts +2 -2
  133. package/dist/server/dev-server.js +287 -63
  134. package/dist/server/headers.d.ts +8 -1
  135. package/dist/server/headers.js +8 -1
  136. package/dist/server/hybrid-route-priority.d.ts +22 -0
  137. package/dist/server/hybrid-route-priority.js +33 -0
  138. package/dist/server/image-optimization.d.ts +18 -9
  139. package/dist/server/image-optimization.js +37 -23
  140. package/dist/server/implicit-tags.d.ts +2 -1
  141. package/dist/server/implicit-tags.js +4 -1
  142. package/dist/server/instrumentation-runtime.d.ts +6 -0
  143. package/dist/server/instrumentation-runtime.js +8 -0
  144. package/dist/server/isr-decision.d.ts +79 -0
  145. package/dist/server/isr-decision.js +70 -0
  146. package/dist/server/metadata-route-response.js +5 -3
  147. package/dist/server/middleware-runtime.d.ts +13 -0
  148. package/dist/server/middleware-runtime.js +11 -7
  149. package/dist/server/middleware.js +1 -0
  150. package/dist/server/navigation-planner.d.ts +186 -22
  151. package/dist/server/navigation-planner.js +302 -0
  152. package/dist/server/navigation-trace.d.ts +18 -1
  153. package/dist/server/navigation-trace.js +18 -1
  154. package/dist/server/normalize-path.d.ts +0 -8
  155. package/dist/server/normalize-path.js +3 -1
  156. package/dist/server/otel-tracer-extension.d.ts +45 -0
  157. package/dist/server/otel-tracer-extension.js +89 -0
  158. package/dist/server/pages-api-route.d.ts +20 -3
  159. package/dist/server/pages-api-route.js +19 -3
  160. package/dist/server/pages-asset-tags.d.ts +16 -4
  161. package/dist/server/pages-asset-tags.js +22 -12
  162. package/dist/server/pages-data-route.d.ts +8 -1
  163. package/dist/server/pages-data-route.js +16 -3
  164. package/dist/server/pages-get-initial-props.d.ts +54 -4
  165. package/dist/server/pages-get-initial-props.js +43 -1
  166. package/dist/server/pages-node-compat.d.ts +3 -11
  167. package/dist/server/pages-node-compat.js +175 -122
  168. package/dist/server/pages-page-data.d.ts +39 -2
  169. package/dist/server/pages-page-data.js +261 -46
  170. package/dist/server/pages-page-handler.d.ts +5 -2
  171. package/dist/server/pages-page-handler.js +78 -25
  172. package/dist/server/pages-page-response.d.ts +47 -2
  173. package/dist/server/pages-page-response.js +73 -9
  174. package/dist/server/pages-readiness.d.ts +1 -1
  175. package/dist/server/pages-request-pipeline.d.ts +16 -1
  176. package/dist/server/pages-request-pipeline.js +96 -38
  177. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  178. package/dist/server/pregenerated-concrete-paths.js +2 -19
  179. package/dist/server/prerender-manifest.d.ts +33 -0
  180. package/dist/server/prerender-manifest.js +54 -0
  181. package/dist/server/prerender-route-params.d.ts +1 -2
  182. package/dist/server/prod-server.d.ts +39 -1
  183. package/dist/server/prod-server.js +107 -37
  184. package/dist/server/request-pipeline.d.ts +3 -15
  185. package/dist/server/request-pipeline.js +58 -47
  186. package/dist/server/rsc-stream-hints.d.ts +5 -1
  187. package/dist/server/rsc-stream-hints.js +6 -1
  188. package/dist/server/seed-cache.js +10 -18
  189. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  190. package/dist/shims/app-router-scroll-state.js +14 -2
  191. package/dist/shims/app-router-scroll.d.ts +3 -0
  192. package/dist/shims/app-router-scroll.js +28 -18
  193. package/dist/shims/cache-runtime.js +12 -4
  194. package/dist/shims/cache.d.ts +1 -0
  195. package/dist/shims/cache.js +1 -1
  196. package/dist/shims/cdn-cache.d.ts +5 -5
  197. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  198. package/dist/shims/dynamic-preload-chunks.js +79 -0
  199. package/dist/shims/dynamic.d.ts +4 -0
  200. package/dist/shims/dynamic.js +4 -2
  201. package/dist/shims/error-boundary.d.ts +6 -4
  202. package/dist/shims/error-boundary.js +7 -0
  203. package/dist/shims/error.js +38 -11
  204. package/dist/shims/error.react-server.d.ts +9 -0
  205. package/dist/shims/error.react-server.js +6 -0
  206. package/dist/shims/fetch-cache.d.ts +11 -1
  207. package/dist/shims/fetch-cache.js +55 -20
  208. package/dist/shims/hash-scroll.js +6 -1
  209. package/dist/shims/head.js +6 -1
  210. package/dist/shims/headers.d.ts +16 -2
  211. package/dist/shims/headers.js +66 -5
  212. package/dist/shims/image-config.js +7 -1
  213. package/dist/shims/internal/als-registry.js +28 -1
  214. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  215. package/dist/shims/internal/app-route-detection.js +18 -23
  216. package/dist/shims/internal/app-router-context.d.ts +5 -0
  217. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  218. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  219. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  220. package/dist/shims/internal/navigation-untracked.js +55 -0
  221. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  222. package/dist/shims/internal/pages-data-target.js +17 -8
  223. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  224. package/dist/shims/internal/pages-router-accessor.js +13 -0
  225. package/dist/shims/internal/router-context.d.ts +2 -1
  226. package/dist/shims/internal/router-context.js +3 -1
  227. package/dist/shims/link.js +12 -5
  228. package/dist/shims/metadata.d.ts +6 -2
  229. package/dist/shims/metadata.js +32 -14
  230. package/dist/shims/navigation.d.ts +14 -17
  231. package/dist/shims/navigation.js +93 -46
  232. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  233. package/dist/shims/ppr-fallback-shell.js +28 -7
  234. package/dist/shims/router.d.ts +13 -2
  235. package/dist/shims/router.js +434 -116
  236. package/dist/shims/script-nonce-context.d.ts +1 -1
  237. package/dist/shims/script-nonce-context.js +11 -3
  238. package/dist/shims/server.d.ts +33 -2
  239. package/dist/shims/server.js +75 -18
  240. package/dist/shims/slot.js +1 -1
  241. package/dist/shims/unified-request-context.js +2 -0
  242. package/dist/typegen.js +1 -0
  243. package/dist/utils/built-asset-url.d.ts +4 -0
  244. package/dist/utils/built-asset-url.js +11 -0
  245. package/dist/utils/client-build-manifest.js +15 -5
  246. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  247. package/dist/utils/client-runtime-metadata.js +63 -0
  248. package/dist/utils/commonjs-loader.d.ts +16 -0
  249. package/dist/utils/commonjs-loader.js +100 -0
  250. package/dist/utils/deployment-id.d.ts +8 -0
  251. package/dist/utils/deployment-id.js +22 -0
  252. package/dist/utils/hash.d.ts +17 -1
  253. package/dist/utils/hash.js +36 -1
  254. package/dist/utils/html-limited-bots.d.ts +18 -1
  255. package/dist/utils/html-limited-bots.js +23 -1
  256. package/dist/utils/lazy-chunks.d.ts +27 -1
  257. package/dist/utils/lazy-chunks.js +65 -1
  258. package/dist/utils/manifest-paths.d.ts +20 -2
  259. package/dist/utils/manifest-paths.js +38 -3
  260. package/dist/utils/parse-cookie.d.ts +13 -0
  261. package/dist/utils/parse-cookie.js +52 -0
  262. package/dist/utils/path.d.ts +8 -1
  263. package/dist/utils/path.js +13 -1
  264. package/package.json +2 -2
  265. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  266. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -1,5 +1,6 @@
1
1
  import { addBasePathToPathname } from "../utils/base-path.js";
2
2
  import { VINEXT_RSC_REDIRECT_HEADER } from "./headers.js";
3
+ import { runWithConnectionProbe } from "../shims/headers.js";
3
4
  import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, createRscRedirectLocation } from "./app-rsc-cache-busting.js";
4
5
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
5
6
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
@@ -180,10 +181,15 @@ async function buildAppPageSpecialErrorResponse(options) {
180
181
  }
181
182
  if (options.renderFallbackPage) {
182
183
  const fallbackResponse = await options.renderFallbackPage(options.specialError.statusCode);
183
- if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(fallbackResponse, options.middlewareContext);
184
+ if (fallbackResponse) return mergeAppPageSpecialErrorHeaders(options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? new Response(fallbackResponse.body, {
185
+ headers: fallbackResponse.headers,
186
+ status: 200,
187
+ statusText: fallbackResponse.statusText
188
+ }) : fallbackResponse, options.middlewareContext);
184
189
  }
185
190
  options.clearRequestContext();
186
- return mergeAppPageSpecialErrorHeaders(new Response(getAppPageStatusText(options.specialError.statusCode), { status: options.specialError.statusCode }), options.middlewareContext);
191
+ const responseStatus = options.specialError.fromMetadata === true && options.serveStreamingMetadata !== false ? 200 : options.specialError.statusCode;
192
+ return mergeAppPageSpecialErrorHeaders(new Response(getAppPageStatusText(options.specialError.statusCode), { status: responseStatus }), options.middlewareContext);
187
193
  }
188
194
  /** See `LayoutFlags` type docblock in app-elements.ts for lifecycle. */
189
195
  async function probeAppPageLayouts(options) {
@@ -210,7 +216,10 @@ async function probeAppPageLayouts(options) {
210
216
  if (cls) {
211
217
  const layoutId = cls.getLayoutId(layoutIndex);
212
218
  try {
213
- const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(() => options.probeLayoutAt(layoutIndex));
219
+ const { dynamicDetected } = await cls.runWithIsolatedDynamicScope(async () => {
220
+ const outcome = await runWithConnectionProbe(() => options.probeLayoutAt(layoutIndex));
221
+ return outcome.completed ? outcome.result : null;
222
+ });
214
223
  const observationDynamic = cls.isLayoutObservationDynamic?.(layoutId) === true;
215
224
  const layoutDynamic = dynamicDetected || observationDynamic;
216
225
  layoutFlags[layoutId] = layoutDynamic ? "d" : "s";
@@ -239,25 +248,51 @@ async function probeAppPageLayouts(options) {
239
248
  };
240
249
  }
241
250
  async function probeLayoutForErrors(options, layoutIndex) {
242
- try {
243
- const layoutResult = options.probeLayoutAt(layoutIndex);
244
- if (isPromiseLike(layoutResult)) await layoutResult;
245
- } catch (error) {
246
- return options.onLayoutError(error, layoutIndex);
247
- }
248
- return null;
249
- }
250
- async function probeAppPageComponent(options) {
251
- return options.runWithSuppressedHookWarning(async () => {
251
+ const outcome = await runWithConnectionProbe(async () => {
252
252
  try {
253
- const pageResult = options.probePage();
254
- if (isPromiseLike(pageResult)) if (options.awaitAsyncResult) await pageResult;
255
- else Promise.resolve(pageResult).catch(() => {});
253
+ const layoutResult = options.probeLayoutAt(layoutIndex);
254
+ if (isPromiseLike(layoutResult)) await layoutResult;
256
255
  } catch (error) {
257
- return options.onError(error);
256
+ return options.onLayoutError(error, layoutIndex);
258
257
  }
259
258
  return null;
260
259
  });
260
+ return outcome.completed ? outcome.result : null;
261
+ }
262
+ async function probeAppPageComponent(options) {
263
+ return options.runWithSuppressedHookWarning(async () => {
264
+ const outcome = await runWithConnectionProbe(async () => {
265
+ try {
266
+ const pageResult = options.probePage();
267
+ if (isPromiseLike(pageResult)) if (options.awaitAsyncResult) await pageResult;
268
+ else Promise.resolve(pageResult).catch(() => {});
269
+ } catch (error) {
270
+ return options.onError(error);
271
+ }
272
+ return null;
273
+ });
274
+ return outcome.completed ? outcome.result : null;
275
+ });
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
+ });
261
296
  }
262
297
  async function readAppPageBinaryStream(stream) {
263
298
  const reader = stream.getReader();
@@ -290,4 +325,4 @@ function buildAppPageFontLinkHeader(preloads) {
290
325
  return preloads.map((preload) => `<${preload.href}>; rel=preload; as=font; type=${preload.type}; crossorigin`).join(", ");
291
326
  }
292
327
  //#endregion
293
- 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;
@@ -68,7 +69,11 @@ type RenderAppPageLifecycleOptions = {
68
69
  layoutCount: number;
69
70
  loadSsrHandler: () => Promise<AppPageSsrHandler>;
70
71
  middlewareContext: AppPageMiddlewareContext;
72
+ navigationParams: Record<string, unknown>;
71
73
  params: Record<string, unknown>;
74
+ pprFallbackShellSignal?: AbortSignal;
75
+ pprFallbackShellReactSignal?: AbortSignal;
76
+ abortPprFallbackShell?: () => void;
72
77
  rootParams?: RootParams;
73
78
  peekRenderObservationState?: () => AppPageRenderObservationState;
74
79
  probeLayoutAt: (layoutIndex: number) => unknown;
@@ -81,8 +86,14 @@ type RenderAppPageLifecycleOptions = {
81
86
  renderPageSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
82
87
  renderToReadableStream: (element: ReactNode | AppOutgoingElements, options: {
83
88
  onError: AppPageBoundaryOnError;
89
+ signal?: AbortSignal;
84
90
  }) => ReadableStream<Uint8Array>;
85
- routeHasLocalBoundary: boolean;
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;
@@ -1,8 +1,8 @@
1
+ import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
1
2
  import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVersion } from "./artifact-compatibility.js";
2
3
  import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
3
4
  import "./app-elements.js";
4
5
  import { runWithFetchDedupe } from "../shims/fetch-cache.js";
5
- import { NO_STORE_CACHE_CONTROL } from "./cache-control.js";
6
6
  import { buildAppPageHtmlResponse, buildAppPageRscResponse, resolveAppPageHtmlResponsePolicy, resolveAppPageRscResponsePolicy } from "./app-page-response.js";
7
7
  import { buildAppPageFontLinkHeader, readAppPageBinaryStream, resolveAppPageSpecialError, teeAppPageRscStreamForCapture } from "./app-page-execution.js";
8
8
  import { probeAppPageBeforeRender } from "./app-page-probe.js";
@@ -10,7 +10,7 @@ import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRe
10
10
  import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
11
11
  import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache.js";
12
12
  import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
13
- import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery, shouldRerenderAppPageWithGlobalError } from "./app-page-stream.js";
13
+ import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
14
14
  import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
15
15
  import { hasDigest } from "./app-rsc-errors.js";
16
16
  import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
@@ -249,6 +249,7 @@ function wrapRscResponseForDevErrorReporting(response, consumeInvalidDynamicUsag
249
249
  async function renderAppPageLifecycle(options) {
250
250
  const preRenderResult = await probeAppPageBeforeRender({
251
251
  hasLoadingBoundary: options.hasLoadingBoundary,
252
+ skipProbes: options.pprFallbackShellSignal !== void 0,
252
253
  layoutCount: options.layoutCount,
253
254
  probeLayoutAt(layoutIndex) {
254
255
  return options.probeLayoutAt(layoutIndex);
@@ -293,7 +294,7 @@ async function renderAppPageLifecycle(options) {
293
294
  cleanPathname: options.cleanPathname,
294
295
  completeness: "partial",
295
296
  output: rscOutputScope,
296
- params: options.params,
297
+ params: options.navigationParams,
297
298
  state: options.peekRenderObservationState?.() ?? createEmptyAppPageRenderObservationState()
298
299
  });
299
300
  const skipDisposition = options.skipDisposition ?? createRenderLifecycleSkipDisposition({
@@ -315,11 +316,31 @@ async function renderAppPageLifecycle(options) {
315
316
  });
316
317
  const compileEnd = options.isProduction ? void 0 : performance.now();
317
318
  const rscErrorTracker = createAppPageRscErrorTracker(options.createRscOnErrorHandler(options.cleanPathname, options.routePattern));
318
- const rscStream = runWithFetchDedupe(() => options.renderToReadableStream(outgoingElement, { onError: rscErrorTracker.onRenderError }));
319
+ let rscStream = await runWithFetchDedupe(async () => {
320
+ if (options.pprFallbackShellSignal && options.prerenderToReadableStream) {
321
+ const reactSignal = options.pprFallbackShellReactSignal ?? options.pprFallbackShellSignal;
322
+ const pendingResult = options.prerenderToReadableStream(outgoingElement, {
323
+ onError: rscErrorTracker.onRenderError,
324
+ signal: reactSignal
325
+ });
326
+ if (options.abortPprFallbackShell) setTimeout(options.abortPprFallbackShell, 0);
327
+ return (await pendingResult).prelude;
328
+ }
329
+ return options.renderToReadableStream(outgoingElement, { onError: rscErrorTracker.onRenderError });
330
+ });
331
+ let pprFallbackShellRsc = null;
332
+ if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
319
333
  let revalidateSeconds = options.revalidateSeconds;
320
334
  let expireSeconds = options.expireSeconds;
321
335
  const shouldCaptureRscForCacheMetadata = options.isProgressiveActionRender !== true && (options.isProduction || options.isPrerender === true) && (revalidateSeconds === null || revalidateSeconds > 0 && revalidateSeconds !== Infinity) && !options.isDraftMode && !options.isForceDynamic && !shouldBypassRscCacheForSkipTransport;
322
- const rscCapture = teeAppPageRscStreamForCapture(rscStream, shouldCaptureRscForCacheMetadata);
336
+ const createBufferedRscStream = (close) => new ReadableStream({ start(controller) {
337
+ if (pprFallbackShellRsc) controller.enqueue(pprFallbackShellRsc);
338
+ if (close) controller.close();
339
+ } });
340
+ const rscCapture = pprFallbackShellRsc ? {
341
+ ssrStream: createBufferedRscStream(false),
342
+ ...shouldCaptureRscForCacheMetadata ? { sideStream: createBufferedRscStream(true) } : {}
343
+ } : teeAppPageRscStreamForCapture(rscStream, shouldCaptureRscForCacheMetadata);
323
344
  const rscForResponse = rscCapture.ssrStream;
324
345
  const capturedRscDataRef = { value: null };
325
346
  if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
@@ -349,7 +370,7 @@ async function renderAppPageLifecycle(options) {
349
370
  isEdgeRuntime: options.isEdgeRuntime,
350
371
  middlewareContext: options.middlewareContext,
351
372
  mountedSlotsHeader: options.mountedSlotsHeader,
352
- params: options.params,
373
+ params: options.navigationParams,
353
374
  policy: rscResponsePolicy,
354
375
  timing: buildResponseTiming({
355
376
  compileEnd,
@@ -371,7 +392,7 @@ async function renderAppPageLifecycle(options) {
371
392
  cleanPathname: options.cleanPathname,
372
393
  completeness: "complete",
373
394
  output: rscOutputScope,
374
- params: options.params,
395
+ params: options.navigationParams,
375
396
  state: input.state
376
397
  });
377
398
  },
@@ -415,17 +436,19 @@ async function renderAppPageLifecycle(options) {
415
436
  return renderAppPageHtmlStream({
416
437
  capturedRscDataRef,
417
438
  fontData,
439
+ hasCustomGlobalError: options.hasCustomGlobalError,
418
440
  navigationContext: options.getNavigationContext(),
419
441
  basePath: options.basePath,
420
442
  clientTraceMetadata: options.clientTraceMetadata,
421
443
  reactMaxHeadersLength: options.reactMaxHeadersLength,
422
444
  rootParams: options.rootParams,
445
+ pprFallbackShellSignal: options.pprFallbackShellSignal,
423
446
  formState: options.formState ?? null,
424
447
  rscStream: rscForResponse,
425
448
  scriptNonce: options.scriptNonce,
426
449
  sideStream: rscCapture.sideStream,
427
450
  ssrHandler,
428
- waitForAllReady: options.isPrerender
451
+ waitForAllReady: options.isPrerender === true
429
452
  });
430
453
  },
431
454
  renderSpecialErrorResponse(specialError) {
@@ -448,13 +471,6 @@ async function renderAppPageLifecycle(options) {
448
471
  }
449
472
  }
450
473
  }
451
- if (shouldRerenderAppPageWithGlobalError({
452
- capturedError: rscErrorTracker.getCapturedError(),
453
- hasLocalBoundary: options.routeHasLocalBoundary
454
- })) {
455
- const cleanResponse = await options.renderErrorBoundaryResponse(rscErrorTracker.getCapturedError());
456
- if (cleanResponse) return cleanResponse;
457
- }
458
474
  if (options.isPrerender === true) {
459
475
  await settleCapturedRscRenderForCacheMetadata(htmlRender.capturedRscData);
460
476
  ({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
@@ -489,6 +505,21 @@ async function renderAppPageLifecycle(options) {
489
505
  renderEnd,
490
506
  responseKind: "html"
491
507
  });
508
+ if (htmlRender.shellErrorRecovered) {
509
+ const response = buildAppPageHtmlResponse(safeHtmlStream, {
510
+ draftCookie,
511
+ linkHeader,
512
+ isEdgeRuntime: options.isEdgeRuntime,
513
+ middlewareContext: {
514
+ headers: options.middlewareContext.headers,
515
+ status: 500
516
+ },
517
+ policy: { cacheControl: NEVER_CACHE_CONTROL },
518
+ timing: htmlResponseTiming
519
+ });
520
+ applyCdnResponseHeaders(response.headers, { cacheControl: NEVER_CACHE_CONTROL });
521
+ return response;
522
+ }
492
523
  const shouldSpeculativelyWriteCache = options.isProduction && shouldCaptureRscForCacheMetadata && revalidateSeconds === null && !options.isDynamicError && !options.isForceStatic && !options.scriptNonce && options.isProgressiveActionRender !== true && !dynamicUsedDuringRender;
493
524
  if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
494
525
  const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
@@ -516,7 +547,7 @@ async function renderAppPageLifecycle(options) {
516
547
  cleanPathname: options.cleanPathname,
517
548
  completeness: "complete",
518
549
  output: htmlOutputScope,
519
- params: options.params,
550
+ params: options.navigationParams,
520
551
  state: input.state
521
552
  });
522
553
  },
@@ -528,7 +559,7 @@ async function renderAppPageLifecycle(options) {
528
559
  cleanPathname: options.cleanPathname,
529
560
  completeness: "complete",
530
561
  output: rscOutputScope,
531
- params: options.params,
562
+ params: options.navigationParams,
532
563
  state: input.state
533
564
  });
534
565
  },
@@ -29,6 +29,7 @@ type ResolveAppPageGenerateStaticParamsSourcesOptions = {
29
29
  };
30
30
  type BuildAppPageElementOptions<TElement> = {
31
31
  buildPageElement: () => Promise<TElement>;
32
+ probePageSpecialError?: () => Promise<AppPageSpecialError | null>;
32
33
  renderErrorBoundaryPage: (error: unknown) => Promise<Response | null>;
33
34
  renderSpecialError: (specialError: AppPageSpecialError) => Promise<Response>;
34
35
  resolveSpecialError: (error: unknown) => AppPageSpecialError | null;
@@ -44,6 +45,7 @@ type AppPageInterceptMatch<TPage = unknown> = {
44
45
  slotId?: string | null;
45
46
  slotKey: string;
46
47
  sourceRouteIndex: number;
48
+ sourcePageSegments?: readonly string[] | null;
47
49
  };
48
50
  type ResolveAppPageInterceptMatchOptions<TRoute, TPage, TInterceptOpts> = {
49
51
  cleanPathname: string;
@@ -87,6 +89,7 @@ type ResolveAppPageInterceptOptions<TRoute, TPage, TInterceptOpts, TElement> = {
87
89
  getSourceRoute: (sourceRouteIndex: number) => Awaitable<TRoute | undefined>;
88
90
  isRscRequest: boolean;
89
91
  layoutParamAccess?: AppLayoutParamAccessTracker;
92
+ resolveNavigationParams: (route: TRoute, params: AppPageParams, pathname: string, interceptOpts: TInterceptOpts) => AppPageParams;
90
93
  renderInterceptResponse: (route: TRoute, element: TElement) => Promise<Response> | Response;
91
94
  searchParams: URLSearchParams;
92
95
  setNavigationContext: (context: {
@@ -155,13 +155,14 @@ async function resolveAppPageIntercept(options) {
155
155
  });
156
156
  if (interceptState.kind === "source-route") {
157
157
  const renderRoute = interceptState.sourceRoute;
158
+ const interceptOpts = options.toInterceptOpts(interceptState.intercept);
158
159
  const renderParams = pickRouteParams(interceptState.intercept.matchedParams, options.getRouteParamNames(interceptState.sourceRoute));
159
160
  options.setNavigationContext({
160
- params: interceptState.intercept.matchedParams,
161
+ params: options.resolveNavigationParams(renderRoute, interceptState.intercept.matchedParams, options.cleanPathname, interceptOpts),
161
162
  pathname: options.cleanPathname,
162
163
  searchParams: options.searchParams
163
164
  });
164
- const interceptElement = await options.buildPageElement(renderRoute, renderParams, options.toInterceptOpts(interceptState.intercept), options.searchParams, options.layoutParamAccess);
165
+ const interceptElement = await options.buildPageElement(renderRoute, renderParams, interceptOpts, options.searchParams, options.layoutParamAccess);
165
166
  return {
166
167
  interceptOpts: void 0,
167
168
  response: await options.renderInterceptResponse(renderRoute, interceptElement)
@@ -179,7 +180,8 @@ async function buildAppPageElement(options) {
179
180
  response: null
180
181
  };
181
182
  } catch (error) {
182
- const specialError = options.resolveSpecialError(error);
183
+ const buildSpecialError = options.resolveSpecialError(error);
184
+ const specialError = (buildSpecialError ? await options.probePageSpecialError?.() : null) ?? buildSpecialError;
183
185
  if (specialError) return {
184
186
  element: null,
185
187
  response: await options.renderSpecialError(specialError)
@@ -1,7 +1,7 @@
1
1
  import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
2
2
  import { setCacheStateHeaders } from "./cache-headers.js";
3
- import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
4
3
  import { NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
4
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
5
5
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
6
6
  //#region src/server/app-page-response.ts
7
7
  function applyTimingHeader(headers, timing) {
@@ -113,6 +113,7 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
113
113
  resolvedMetadata: Metadata | null;
114
114
  resolvedMetadataPathname?: string;
115
115
  resolvedViewport: Viewport;
116
+ trailingSlash?: boolean;
116
117
  rootForbiddenModule?: TModule | null;
117
118
  rootNotFoundModule?: TModule | null;
118
119
  rootUnauthorizedModule?: TModule | null;
@@ -129,6 +130,7 @@ type BuildAppPageElementsOptions<TModule extends AppPageModule = AppPageModule,
129
130
  renderIdentity?: AppPageRenderIdentity;
130
131
  renderMode?: AppRscRenderMode;
131
132
  routePath: string;
133
+ sourcePageSegments?: readonly string[] | null;
132
134
  };
133
135
  declare function createAppPageTreePath(routeSegments: readonly string[] | null | undefined, treePosition: number): string;
134
136
  declare function probeAppPageLayoutWithTracking<TModule extends AppPageModule>(options: {
@@ -142,6 +144,8 @@ declare function createAppPageLayoutEntries<TModule extends AppPageModule, TErro
142
144
  forbiddens?: readonly (TModule | null | undefined)[] | null;
143
145
  unauthorizeds?: readonly (TModule | null | undefined)[] | null;
144
146
  }): AppPageLayoutEntry<TModule, TErrorModule>[];
147
+ declare function createAppPageSourcePage(routeSegments: readonly string[] | null | undefined): string;
148
+ declare function createAppPageRouteBodyMetadata(metadata: Metadata | null, pathname: string, metadataPlacement: "body" | "head", trailingSlash?: boolean): ReactNode;
145
149
  declare function buildAppPageElements<TModule extends AppPageModule, TErrorModule extends AppPageErrorModule>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements;
146
150
  //#endregion
147
- export { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute, AppPageSlotOverride, buildAppPageElements, createAppPageLayoutEntries, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
151
+ export { AppPageErrorModule, AppPageModule, AppPageRouteWiringRoute, AppPageSlotOverride, buildAppPageElements, createAppPageLayoutEntries, createAppPageRouteBodyMetadata, createAppPageSourcePage, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
@@ -2,7 +2,8 @@ import { createAppRenderDependency, registerAppElementRenderDependencies, render
2
2
  import { APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
3
3
  import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, shouldSuppressLoadingBoundaries } from "./app-rsc-render-mode.js";
4
4
  import { APP_PREFETCH_LOADING_SHELL_MARKER_KEY } from "./app-elements.js";
5
- import { ErrorBoundary, ForbiddenBoundary, NotFoundBoundary, RedirectBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
5
+ import DefaultGlobalError from "../shims/default-global-error.js";
6
+ import { ErrorBoundary, ForbiddenBoundary, GlobalErrorBoundary, NotFoundBoundary, RedirectBoundary, UnauthorizedBoundary } from "../shims/error-boundary.js";
6
7
  import { AppRouterScrollTarget } from "../shims/app-router-scroll.js";
7
8
  import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
8
9
  import { MetadataHead, ViewportHead, renderMetadataToHtml } from "../shims/metadata.js";
@@ -14,6 +15,7 @@ import { Fragment, Suspense } from "react";
14
15
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
15
16
  //#region src/server/app-page-route-wiring.tsx
16
17
  const APP_PAGE_LAYOUT_PROBE_CHILD = /* @__PURE__ */ jsx(Fragment, {});
18
+ const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
17
19
  function getDefaultExport(module) {
18
20
  return module?.default ?? null;
19
21
  }
@@ -85,6 +87,9 @@ function createAppPageTemplateEntries(route) {
85
87
  };
86
88
  });
87
89
  }
90
+ function createAppPageSourcePage(routeSegments) {
91
+ return `/${[...routeSegments ?? [], "page"].join("/")}`;
92
+ }
88
93
  function createAppPageErrorEntries(route) {
89
94
  return (route.errorPaths ?? route.errors ?? []).flatMap((errorModule, index) => {
90
95
  if (!errorModule) return [];
@@ -139,21 +144,22 @@ function createAppPageSlotBindings(route, layoutEntries, resolveSlotOverride, op
139
144
  }
140
145
  return normalizeAppElementsSlotBindings(bindings, { layoutIds: layoutEntries.map((entry) => entry.id) });
141
146
  }
142
- function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement) {
147
+ function createAppPageRouteHead(metadata, viewport, pathname, metadataPlacement, trailingSlash) {
143
148
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
144
149
  /* @__PURE__ */ jsx("meta", { charSet: "utf-8" }),
145
150
  metadata && metadataPlacement === "head" ? /* @__PURE__ */ jsx(MetadataHead, {
146
151
  metadata,
147
- pathname
152
+ pathname,
153
+ trailingSlash
148
154
  }) : null,
149
155
  /* @__PURE__ */ jsx(ViewportHead, { viewport })
150
156
  ] });
151
157
  }
152
- function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement) {
158
+ function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, trailingSlash) {
153
159
  if (!metadata || metadataPlacement !== "body") return null;
154
160
  return /* @__PURE__ */ jsx("div", {
155
161
  hidden: true,
156
- dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname) }
162
+ dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname, { trailingSlash }) }
157
163
  });
158
164
  }
159
165
  function buildAppPageElements(options) {
@@ -205,6 +211,7 @@ function buildAppPageElements(options) {
205
211
  layoutIds: options.route.ids?.layouts ?? layoutEntries.map((entry) => entry.id),
206
212
  rootLayoutTreePath,
207
213
  routeId,
214
+ sourcePage: createAppPageSourcePage(options.sourcePageSegments ?? routeSegments),
208
215
  slotBindings: createAppPageSlotBindings(options.route, layoutEntries, resolveSlotOverride, {
209
216
  interception: renderIdentity?.interception ?? options.interception ?? null,
210
217
  interceptionContext,
@@ -426,17 +433,20 @@ function buildAppPageElements(options) {
426
433
  });
427
434
  }
428
435
  const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);
429
- if (globalErrorComponent) routeChildren = /* @__PURE__ */ jsx(ErrorBoundary, {
430
- fallback: globalErrorComponent,
431
- children: routeChildren
436
+ routeChildren = /* @__PURE__ */ jsx(GlobalErrorBoundary, {
437
+ fallback: DEFAULT_GLOBAL_ERROR_COMPONENT,
438
+ children: globalErrorComponent ? /* @__PURE__ */ jsx(ErrorBoundary, {
439
+ fallback: globalErrorComponent,
440
+ children: routeChildren
441
+ }) : routeChildren
432
442
  });
433
443
  elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
434
- createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement),
444
+ createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
435
445
  routeChildren,
436
- createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement)
446
+ createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash)
437
447
  ] });
438
448
  registerAppElementRenderDependencies(elements, renderDependenciesByElementId);
439
449
  return elements;
440
450
  }
441
451
  //#endregion
442
- export { buildAppPageElements, createAppPageLayoutEntries, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
452
+ export { buildAppPageElements, createAppPageLayoutEntries, createAppPageRouteBodyMetadata, createAppPageSourcePage, createAppPageTreePath, probeAppPageLayoutWithTracking, resolveAppPageChildSegments };
@@ -18,6 +18,7 @@ type AppSsrRenderResult = {
18
18
  htmlStream: ReadableStream<Uint8Array>;
19
19
  metadataReady: Promise<void>;
20
20
  capturedRscData: Promise<ArrayBuffer> | null;
21
+ shellErrorRecovered?: boolean;
21
22
  /**
22
23
  * Preload `Link` header value emitted by React during SSR (via `onHeaders`),
23
24
  * already capped to `reactMaxHeadersLength`. Empty/undefined when React
@@ -62,9 +63,14 @@ type AppPageSsrHandler = {
62
63
  sideStream?: ReadableStream<Uint8Array>;
63
64
  capturedRscDataRef?: {
64
65
  value: Promise<ArrayBuffer> | null;
65
- }; /** When true, wait for the full React tree before emitting bytes. */
66
+ }; /** Abort signal for a build-time PPR fallback-shell static render. */
67
+ pprFallbackShellSignal?: AbortSignal; /** When true, wait for the full React tree before emitting bytes. */
66
68
  waitForAllReady?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
67
69
  initialDevServerError?: unknown;
70
+ /** When true, an SSR-phase-only shell render error resolves to the
71
+ * default `__next_error__` error-document shell (with the original
72
+ * flight payload and bootstrap) instead of rejecting. See handleSsr. */
73
+ fallbackToErrorDocumentOnShellError?: boolean;
68
74
  }) => Promise<ReadableStream<Uint8Array> | AppSsrRenderResult>;
69
75
  };
70
76
  type RenderAppPageHtmlStreamOptions = {
@@ -93,9 +99,14 @@ type RenderAppPageHtmlStreamOptions = {
93
99
  sideStream?: ReadableStream<Uint8Array>; /** Out-parameter filled with accumulated raw RSC bytes after stream consumption. */
94
100
  capturedRscDataRef?: {
95
101
  value: Promise<ArrayBuffer> | null;
96
- }; /** When true, wait for the full React tree before emitting bytes. */
102
+ }; /** Abort signal for a build-time PPR fallback-shell static render. */
103
+ pprFallbackShellSignal?: AbortSignal; /** When true, wait for the full React tree before emitting bytes. */
97
104
  waitForAllReady?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
98
105
  initialDevServerError?: unknown;
106
+ /** True when the app supplies a custom global-error.tsx. Disables the
107
+ * default error-document shell fallback so SSR shell errors keep driving
108
+ * the server-rendered global-error boundary re-render. */
109
+ hasCustomGlobalError?: boolean;
99
110
  };
100
111
  type RenderAppPageHtmlResponseOptions = {
101
112
  clearRequestContext: () => void;
@@ -108,7 +119,8 @@ type AppPageHtmlStreamRecoveryResult = {
108
119
  htmlStream: ReadableStream<Uint8Array> | null;
109
120
  response: Response | null;
110
121
  metadataReady: Promise<void>;
111
- capturedRscData: Promise<ArrayBuffer> | null; /** React-emitted preload `Link` header (already capped). */
122
+ capturedRscData: Promise<ArrayBuffer> | null;
123
+ shellErrorRecovered: boolean; /** React-emitted preload `Link` header (already capped). */
112
124
  linkHeader?: string;
113
125
  };
114
126
  type RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError> = {
@@ -129,10 +141,6 @@ type AppPageRscErrorTracker = {
129
141
  getCapturedSpecialError: () => unknown;
130
142
  onRenderError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown;
131
143
  };
132
- type ShouldRerenderAppPageWithGlobalErrorOptions = {
133
- capturedError: unknown;
134
- hasLocalBoundary: boolean;
135
- };
136
144
  declare function createAppPageFontData(options: CreateAppPageFontDataOptions): AppPageFontData;
137
145
  declare function renderAppPageHtmlStream(options: RenderAppPageHtmlStreamOptions): Promise<AppSsrRenderResult>;
138
146
  /**
@@ -146,6 +154,5 @@ declare function deferUntilStreamConsumed(stream: ReadableStream<Uint8Array>, on
146
154
  declare function renderAppPageHtmlResponse(options: RenderAppPageHtmlResponseOptions): Promise<Response>;
147
155
  declare function renderAppPageHtmlStreamWithRecovery<TSpecialError>(options: RenderAppPageHtmlStreamWithRecoveryOptions<TSpecialError>): Promise<AppPageHtmlStreamRecoveryResult>;
148
156
  declare function createAppPageRscErrorTracker(baseOnError: (error: unknown, requestInfo: unknown, errorContext: unknown) => unknown): AppPageRscErrorTracker;
149
- declare function shouldRerenderAppPageWithGlobalError(options: ShouldRerenderAppPageWithGlobalErrorOptions): boolean;
150
157
  //#endregion
151
- export { AppPageFontData, AppPageSsrHandler, AppSsrRenderResult, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery, shouldRerenderAppPageWithGlobalError };
158
+ export { AppPageFontData, AppPageSsrHandler, AppSsrRenderResult, buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, deferUntilStreamConsumed, isAppSsrRenderResult, renderAppPageHtmlResponse, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery };