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,28 +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";
24
+ import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
25
+ import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
21
26
  import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
22
27
  import { renderAppPageLifecycle } from "./app-page-render.js";
23
- import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
24
28
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
25
- import { buildPageCacheTags } from "./implicit-tags.js";
26
29
  import React from "react";
27
30
  //#region src/server/app-page-dispatch.ts
28
31
  function resolveAppPageRouteBoundaryModule(route, statusCode) {
@@ -106,9 +109,6 @@ function shouldReadAppPageCache(options) {
106
109
  function hasSearchParams(searchParams) {
107
110
  return searchParams !== null && searchParams !== void 0 && searchParams.size > 0;
108
111
  }
109
- function buildAppPageTags(cleanPathname, extraTags, routeSegments) {
110
- return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], "page");
111
- }
112
112
  async function runAppPageRevalidationContext(options, renderFn) {
113
113
  return runWithRequestContext(createRequestContext({
114
114
  headersContext: createStaticGenerationHeadersContext({
@@ -118,23 +118,20 @@ async function runAppPageRevalidationContext(options, renderFn) {
118
118
  routePattern: options.routePattern
119
119
  }),
120
120
  currentFetchCacheMode: options.currentFetchCacheMode ?? null,
121
+ currentForceDynamicFetchDefault: options.dynamicConfig === "force-dynamic",
121
122
  executionContext: getRequestExecutionContext(),
122
123
  unstableCacheRevalidation: "foreground"
123
124
  }), async () => {
124
125
  ensureFetchPatch();
125
126
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
126
127
  options.setNavigationContext({
127
- pathname: options.cleanPathname,
128
+ pathname: options.displayPathname ?? options.cleanPathname,
128
129
  searchParams: new URLSearchParams(),
129
130
  params: options.params
130
131
  });
131
132
  return await runWithFetchDedupe(renderFn);
132
133
  });
133
134
  }
134
- function getCapturedRscDataPromise(capturedRscDataPromise) {
135
- if (!capturedRscDataPromise) throw new Error("[vinext] Expected captured RSC data while regenerating an app page cache entry");
136
- return capturedRscDataPromise;
137
- }
138
135
  function toInterceptOptions(interceptionContext, intercept) {
139
136
  return {
140
137
  interceptionContext,
@@ -143,11 +140,77 @@ function toInterceptOptions(interceptionContext, intercept) {
143
140
  interceptParams: intercept.matchedParams,
144
141
  interceptSlotId: intercept.slotId ?? null,
145
142
  interceptSlotKey: intercept.slotKey,
146
- interceptSourceMatchedUrl: interceptionContext
143
+ interceptSourceMatchedUrl: interceptionContext,
144
+ interceptSourcePageSegments: intercept.sourcePageSegments ?? null
147
145
  };
148
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
170
+ };
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
+ }
149
210
  async function dispatchAppPage(options) {
150
- 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);
151
214
  }
152
215
  async function dispatchAppPageInner(options) {
153
216
  const route = options.route;
@@ -160,6 +223,7 @@ async function dispatchAppPageInner(options) {
160
223
  const layoutParamAccess = createAppLayoutParamAccessTracker();
161
224
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
162
225
  setCurrentFetchCacheMode(options.fetchCache ?? null);
226
+ setCurrentForceDynamicFetchDefault(isForceDynamic);
163
227
  if (options.hasPageModule && !options.hasPageDefaultExport) {
164
228
  options.clearRequestContext();
165
229
  return new Response("Page has no default export", { status: 500 });
@@ -183,10 +247,11 @@ async function dispatchAppPageInner(options) {
183
247
  routeKind: "page",
184
248
  routePattern: route.pattern
185
249
  }));
250
+ const staticNavigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, null);
186
251
  options.setNavigationContext({
187
- pathname: options.cleanPathname,
252
+ pathname: options.displayPathname ?? options.cleanPathname,
188
253
  searchParams: new URLSearchParams(),
189
- params: options.params
254
+ params: staticNavigationParams
190
255
  });
191
256
  }
192
257
  if (shouldReadAppPageCache({
@@ -233,12 +298,14 @@ async function dispatchAppPageInner(options) {
233
298
  return toInterceptOptions(options.interceptionContext, intercept);
234
299
  }
235
300
  });
301
+ revalidationTarget.navigationParams = resolveAppPageNavigationParams(revalidationTarget.route, revalidationTarget.navigationParams, options.cleanPathname, revalidationTarget.interceptOpts);
236
302
  await options.ensureRouteLoaded?.(revalidationTarget.route);
237
303
  return runAppPageRevalidationContext({
238
304
  cleanPathname: options.cleanPathname,
305
+ displayPathname: options.displayPathname,
239
306
  currentFetchCacheMode: options.resolveRouteFetchCacheMode?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? options.fetchCache ?? null : null),
240
307
  draftModeSecret: options.draftModeSecret,
241
- dynamicConfig,
308
+ dynamicConfig: options.resolveRouteDynamicConfig?.(revalidationTarget.route) ?? (revalidationTarget.route === route ? dynamicConfig : void 0),
242
309
  params: revalidationTarget.navigationParams,
243
310
  routePattern: revalidationTarget.route.pattern,
244
311
  routeSegments: revalidationTarget.route.routeSegments,
@@ -246,72 +313,34 @@ async function dispatchAppPageInner(options) {
246
313
  }, async () => {
247
314
  const revalidatedElement = await options.buildPageElement(revalidationTarget.route, revalidationTarget.params, revalidationTarget.interceptOpts, new URLSearchParams());
248
315
  const revalidatedOnError = options.createRscOnErrorHandler(options.cleanPathname, revalidationTarget.route.pattern);
249
- const revalidatedRscCapture = teeAppPageRscStreamForCapture(options.renderToReadableStream(revalidatedElement, { onError: revalidatedOnError }), true);
250
- const revalidatedSsrEntry = await options.loadSsrHandler();
251
- const revalidatedCapturedRscRef = { value: null };
252
- const revalidatedHtmlResult = await revalidatedSsrEntry.handleSsr(revalidatedRscCapture.ssrStream, options.getNavigationContext(), {
253
- links: options.getFontLinks(),
254
- styles: options.getFontStyles(),
255
- preloads: options.getFontPreloads()
256
- }, {
316
+ const rendered = await renderAppPageCacheArtifacts({
257
317
  basePath: options.basePath,
318
+ captureRscData: true,
319
+ cleanPathname: options.cleanPathname,
258
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,
259
330
  reactMaxHeadersLength: options.reactMaxHeadersLength,
331
+ renderToReadableStream: options.renderToReadableStream,
260
332
  rootParams: options.rootParams,
261
- waitForAllReady: true,
262
- ...revalidatedRscCapture.sideStream ? {
263
- sideStream: revalidatedRscCapture.sideStream,
264
- capturedRscDataRef: revalidatedCapturedRscRef
265
- } : {}
333
+ route: revalidationTarget.route,
334
+ waitForAllReady: true
266
335
  });
267
- const html = await readStreamAsText(isAppSsrRenderResult(revalidatedHtmlResult) ? revalidatedHtmlResult.htmlStream : revalidatedHtmlResult);
268
- const rscData = await getCapturedRscDataPromise(revalidatedCapturedRscRef.value);
269
- const cacheLife = _consumeRequestScopedCacheLife();
270
336
  options.clearRequestContext();
271
- const tags = buildAppPageTags(options.cleanPathname, getCollectedFetchTags(), revalidationTarget.route.routeSegments);
272
- const observationState = {
273
- dynamicFetches: consumeDynamicFetchObservations(),
274
- requestApis: consumeRenderRequestApiUsage()
275
- };
276
337
  return {
277
- html,
278
- htmlRenderObservation: createAppPageRenderObservation({
279
- boundaryOutcome: { kind: "success" },
280
- cacheability: "public",
281
- cacheTags: tags,
282
- cleanPathname: options.cleanPathname,
283
- completeness: "complete",
284
- output: createAppPageHtmlOutputScope({
285
- element: revalidatedElement,
286
- renderEpoch: null,
287
- rootBoundaryId: null,
288
- routePattern: revalidationTarget.route.pattern
289
- }),
290
- params: revalidationTarget.navigationParams,
291
- state: observationState
292
- }),
293
- rscData,
294
- rscRenderObservation: createAppPageRenderObservation({
295
- boundaryOutcome: { kind: "success" },
296
- cacheability: "public",
297
- cacheTags: tags,
298
- cleanPathname: options.cleanPathname,
299
- completeness: "complete",
300
- output: createAppPageRscOutputScope({
301
- element: revalidatedElement,
302
- mountedSlotsHeader: options.mountedSlotsHeader,
303
- renderEpoch: null,
304
- rootBoundaryId: null,
305
- routePattern: revalidationTarget.route.pattern
306
- }),
307
- params: revalidationTarget.navigationParams,
308
- state: observationState
309
- }),
310
- tags,
311
- cacheControl: typeof cacheLife?.revalidate === "number" ? {
312
- revalidate: cacheLife.revalidate,
313
- expire: cacheLife.expire
314
- } : 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
315
344
  };
316
345
  });
317
346
  },
@@ -325,18 +354,23 @@ async function dispatchAppPageInner(options) {
325
354
  });
326
355
  if (cachedPageResponse) return cachedPageResponse;
327
356
  }
328
- const dynamicParamsResponse = await validateAppPageDynamicParams({
329
- clearRequestContext: options.clearRequestContext,
330
- enforceStaticParamsOnly: options.dynamicParamsConfig === false,
331
- generateStaticParams: options.generateStaticParams,
332
- isDynamicRoute: route.isDynamic,
333
- params: options.staticParamsValidationParams ?? options.params
334
- });
335
- 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;
336
369
  const interceptResult = await resolveAppPageIntercept({
337
370
  async buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess) {
338
371
  await options.ensureRouteLoaded?.(interceptRoute);
339
372
  setCurrentFetchCacheMode(options.resolveRouteFetchCacheMode?.(interceptRoute) ?? null);
373
+ setCurrentForceDynamicFetchDefault(options.resolveRouteDynamicConfig?.(interceptRoute) === "force-dynamic");
340
374
  return options.buildPageElement(interceptRoute, interceptParams, interceptOpts, interceptSearchParams, interceptLayoutParamAccess);
341
375
  },
342
376
  cleanPathname: options.cleanPathname,
@@ -352,6 +386,9 @@ async function dispatchAppPageInner(options) {
352
386
  },
353
387
  isRscRequest: options.isRscRequest,
354
388
  layoutParamAccess,
389
+ resolveNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts) {
390
+ return resolveAppPageNavigationParams(sourceRoute, navigationParams, pathname, interceptOpts);
391
+ },
355
392
  renderInterceptResponse(sourceRoute, interceptElement) {
356
393
  const interceptOnError = options.createRscOnErrorHandler(options.cleanPathname, sourceRoute.pattern);
357
394
  const interceptStream = options.renderToReadableStream(interceptElement, { onError: interceptOnError });
@@ -373,11 +410,20 @@ async function dispatchAppPageInner(options) {
373
410
  }
374
411
  });
375
412
  if (interceptResult.response) return interceptResult.response;
376
- const pageBuildResult = await buildAppPageElement({
413
+ const buildCurrentPageElement = () => buildAppPageElement({
377
414
  buildPageElement() {
378
415
  if (options.actionFailed) throw options.actionError;
379
416
  return options.buildPageElement(route, options.params, interceptResult.interceptOpts, options.searchParams, layoutParamAccess);
380
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
+ },
381
427
  renderErrorBoundaryPage(buildError) {
382
428
  return options.renderErrorBoundaryPage(buildError);
383
429
  },
@@ -386,8 +432,30 @@ async function dispatchAppPageInner(options) {
386
432
  },
387
433
  resolveSpecialError: resolveAppPageSpecialError
388
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();
389
448
  if (pageBuildResult.response) return pageBuildResult.response;
449
+ const navigationParams = resolveAppPageNavigationParams(route, options.params, options.cleanPathname, interceptResult.interceptOpts);
450
+ options.setNavigationContext({
451
+ pathname: options.displayPathname ?? options.cleanPathname,
452
+ searchParams: options.searchParams,
453
+ params: navigationParams
454
+ });
390
455
  const layoutClassifications = getEffectiveLayoutClassifications(route, options.debugClassification);
456
+ const activeFallbackShellState = getPprFallbackShellState();
457
+ const pprFallbackShellSignal = activeFallbackShellState?.abortController.signal;
458
+ const pprFallbackShellReactSignal = activeFallbackShellState?.reactAbortController.signal;
391
459
  return renderAppPageLifecycle({
392
460
  basePath: options.basePath,
393
461
  clientTraceMetadata: options.clientTraceMetadata,
@@ -396,12 +464,7 @@ async function dispatchAppPageInner(options) {
396
464
  clearRequestContext: options.clearRequestContext,
397
465
  consumeDynamicUsage,
398
466
  consumeInvalidDynamicUsageError,
399
- consumeRenderObservationState() {
400
- return {
401
- dynamicFetches: consumeDynamicFetchObservations(),
402
- requestApis: consumeRenderRequestApiUsage()
403
- };
404
- },
467
+ consumeRenderObservationState: consumeAppPageRenderObservationState,
405
468
  createRscOnErrorHandler(pathname, routePath) {
406
469
  return options.createRscOnErrorHandler(pathname, routePath);
407
470
  },
@@ -442,7 +505,13 @@ async function dispatchAppPageInner(options) {
442
505
  layoutCount: route.layouts.length,
443
506
  loadSsrHandler: options.loadSsrHandler,
444
507
  middlewareContext: options.middlewareContext,
508
+ navigationParams,
445
509
  params: options.params,
510
+ pprFallbackShellSignal,
511
+ pprFallbackShellReactSignal,
512
+ abortPprFallbackShell: activeFallbackShellState ? () => {
513
+ beginPprFallbackShellFinalRender(activeFallbackShellState);
514
+ } : void 0,
446
515
  layoutParamAccess,
447
516
  rootParams: options.rootParams,
448
517
  peekRenderObservationState() {
@@ -495,7 +564,8 @@ async function dispatchAppPageInner(options) {
495
564
  return renderPageSpecialError(options, specialError);
496
565
  },
497
566
  renderToReadableStream: options.renderToReadableStream,
498
- routeHasLocalBoundary: Boolean(route.error?.default || route.errors?.some((errorModule) => errorModule?.default)),
567
+ hasCustomGlobalError: options.hasCustomGlobalError,
568
+ prerenderToReadableStream: options.prerenderToReadableStream,
499
569
  routePattern: route.pattern,
500
570
  runWithSuppressedHookWarning(probe) {
501
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). */
@@ -49,9 +50,28 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
49
50
  * Configured next.config `basePath`. Threaded through `resolveAppPageHead`
50
51
  * so file-based metadata route URLs emitted in <head> are prefixed.
51
52
  */
52
- basePath?: string; /** Serialized next.config `htmlLimitedBots` regexp source. */
53
+ basePath?: string; /** Configured next.config `trailingSlash`, threaded into canonical URL rendering. */
54
+ trailingSlash?: boolean; /** Serialized next.config `htmlLimitedBots` regexp source. */
53
55
  htmlLimitedBots?: string;
54
56
  };
57
+ type AppPageNavigationParamModule = {
58
+ default?: unknown;
59
+ };
60
+ type AppPageNavigationParamSlot = {
61
+ default?: AppPageNavigationParamModule | null;
62
+ page?: AppPageNavigationParamModule | null;
63
+ slotPatternParts?: readonly string[] | null;
64
+ slotParamNames?: readonly string[] | null;
65
+ };
66
+ type AppPageNavigationParamRoute = {
67
+ params?: readonly string[] | null;
68
+ slots?: Readonly<Record<string, AppPageNavigationParamSlot>> | null;
69
+ };
70
+ type AppPageNavigationParamInterceptOptions = {
71
+ interceptPage?: unknown;
72
+ interceptParams?: AppPageParams | null;
73
+ interceptSlotKey?: string | null;
74
+ };
55
75
  /**
56
76
  * Build the App Router element tree for a matched route.
57
77
  *
@@ -69,5 +89,6 @@ type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TEr
69
89
  * {@link https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/create-metadata.tsx|create-metadata.tsx}.
70
90
  */
71
91
  declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
92
+ declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
72
93
  //#endregion
73
- export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements };
94
+ export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams };
@@ -6,10 +6,10 @@ 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
- import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
12
11
  import "./app-rsc-route-matching.js";
12
+ import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
13
13
  import { createElement } from "react";
14
14
  //#region src/server/app-page-element-builder.ts
15
15
  /**
@@ -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,13 +114,15 @@ 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,
118
121
  route,
119
122
  searchParams: pageSearchParamsThenable,
120
123
  slotOverrides,
121
- renderMode
124
+ renderMode,
125
+ trailingSlash: options.trailingSlash
122
126
  });
123
127
  }
124
128
  /**
@@ -142,6 +146,18 @@ function buildSlotOverrides(route, routeParams, routePath, opts) {
142
146
  pageModule: opts.interceptPage,
143
147
  params: opts.interceptParams || routeParams
144
148
  };
149
+ const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
150
+ for (const [slotKey, params] of Object.entries(slotParamOverrides ?? {})) {
151
+ const existing = overrides[slotKey];
152
+ overrides[slotKey] = existing ? {
153
+ ...existing,
154
+ params
155
+ } : { params };
156
+ }
157
+ return Object.keys(overrides).length > 0 ? overrides : null;
158
+ }
159
+ function resolveSlotParamOverrides(route, routePath) {
160
+ const overrides = {};
145
161
  const slots = route.slots;
146
162
  if (slots) {
147
163
  let urlParts = null;
@@ -154,19 +170,35 @@ function buildSlotOverrides(route, routeParams, routePath, opts) {
154
170
  if (urlParts === null) urlParts = routePath.split("/").filter(Boolean);
155
171
  const matched = matchRoutePattern(urlParts, patternParts);
156
172
  if (!matched) continue;
157
- const existing = overrides[slotKey];
158
- overrides[slotKey] = existing ? {
159
- ...existing,
160
- params: matched
161
- } : { params: matched };
173
+ overrides[slotKey] = matched;
162
174
  }
163
175
  }
164
176
  return Object.keys(overrides).length > 0 ? overrides : null;
165
177
  }
178
+ function mergeAppPageParams(target, source) {
179
+ for (const [key, value] of Object.entries(source)) target[key] = value;
180
+ }
181
+ function isDefaultExportModule(module) {
182
+ return typeof module === "object" && module !== null;
183
+ }
184
+ function hasDefaultExport(module) {
185
+ if (!isDefaultExportModule(module)) return false;
186
+ return module?.default !== null && module?.default !== void 0;
187
+ }
188
+ function resolveAppPageNavigationParams(route, routeParams, routePath, opts) {
189
+ const navigationParams = { ...routeParams };
190
+ const slotParamOverrides = resolveSlotParamOverrides(route, routePath);
191
+ for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {
192
+ const isInterceptedSlot = opts?.interceptSlotKey === slotKey && opts.interceptSlotKey !== "__vinext_page_intercept" && hasDefaultExport(opts.interceptPage);
193
+ if (!isInterceptedSlot && !hasDefaultExport(slot.page) && !hasDefaultExport(slot.default)) continue;
194
+ mergeAppPageParams(navigationParams, isInterceptedSlot ? opts?.interceptParams ?? routeParams : slotParamOverrides?.[slotKey] ?? routeParams);
195
+ }
196
+ return navigationParams;
197
+ }
166
198
  function collectParamNameSet(params) {
167
199
  const set = /* @__PURE__ */ new Set();
168
200
  if (params) for (const name of params) set.add(name);
169
201
  return set;
170
202
  }
171
203
  //#endregion
172
- export { buildPageElements };
204
+ export { buildPageElements, resolveAppPageNavigationParams };
@@ -103,7 +103,7 @@ type LayoutClassificationOptions = {
103
103
  * unsafe even if the older dynamic scope did not report dynamic usage.
104
104
  */
105
105
  isLayoutObservationDynamic?: (layoutId: string) => boolean; /** Runs a function with isolated dynamic usage tracking per layout. */
106
- runWithIsolatedDynamicScope: <T>(fn: () => T) => Promise<{
106
+ runWithIsolatedDynamicScope: <T>(fn: () => T | Promise<T>) => Promise<{
107
107
  result: T;
108
108
  dynamicDetected: boolean;
109
109
  }>;
@@ -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 };