vinext 0.0.50 → 0.0.52

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 (462) hide show
  1. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  2. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  3. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  4. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  5. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  6. package/dist/build/precompress.d.ts +13 -2
  7. package/dist/build/precompress.js +23 -13
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +4 -15
  10. package/dist/build/prerender.js +83 -53
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.d.ts +5 -4
  13. package/dist/build/report.js +196 -348
  14. package/dist/build/report.js.map +1 -1
  15. package/dist/check.js +5 -0
  16. package/dist/check.js.map +1 -1
  17. package/dist/cli-args.d.ts +1 -0
  18. package/dist/cli-args.js +5 -0
  19. package/dist/cli-args.js.map +1 -1
  20. package/dist/cli.js +99 -3
  21. package/dist/cli.js.map +1 -1
  22. package/dist/client/navigation-runtime.d.ts +47 -0
  23. package/dist/client/navigation-runtime.js +156 -0
  24. package/dist/client/navigation-runtime.js.map +1 -0
  25. package/dist/client/pages-router-link-navigation.d.ts +26 -0
  26. package/dist/client/pages-router-link-navigation.js +14 -0
  27. package/dist/client/pages-router-link-navigation.js.map +1 -0
  28. package/dist/client/vinext-next-data.d.ts +12 -2
  29. package/dist/client/vinext-next-data.js +50 -1
  30. package/dist/client/vinext-next-data.js.map +1 -0
  31. package/dist/client/window-next.d.ts +3 -1
  32. package/dist/client/window-next.js.map +1 -1
  33. package/dist/cloudflare/kv-cache-handler.js +2 -1
  34. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  35. package/dist/config/config-matchers.d.ts +63 -16
  36. package/dist/config/config-matchers.js +143 -8
  37. package/dist/config/config-matchers.js.map +1 -1
  38. package/dist/config/dotenv.d.ts +11 -1
  39. package/dist/config/dotenv.js.map +1 -1
  40. package/dist/config/next-config.d.ts +107 -5
  41. package/dist/config/next-config.js +233 -7
  42. package/dist/config/next-config.js.map +1 -1
  43. package/dist/config/tsconfig-paths.d.ts +13 -0
  44. package/dist/config/tsconfig-paths.js +117 -0
  45. package/dist/config/tsconfig-paths.js.map +1 -0
  46. package/dist/deploy.js +104 -41
  47. package/dist/deploy.js.map +1 -1
  48. package/dist/entries/app-browser-entry.d.ts +2 -2
  49. package/dist/entries/app-browser-entry.js +34 -3
  50. package/dist/entries/app-browser-entry.js.map +1 -1
  51. package/dist/entries/app-rsc-entry.d.ts +19 -1
  52. package/dist/entries/app-rsc-entry.js +89 -23
  53. package/dist/entries/app-rsc-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  55. package/dist/entries/app-rsc-manifest.js +57 -7
  56. package/dist/entries/app-rsc-manifest.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +3 -3
  58. package/dist/entries/app-ssr-entry.js +4 -4
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.js +21 -7
  61. package/dist/entries/pages-client-entry.js.map +1 -1
  62. package/dist/entries/pages-server-entry.js +77 -9
  63. package/dist/entries/pages-server-entry.js.map +1 -1
  64. package/dist/entries/runtime-entry-module.d.ts +2 -1
  65. package/dist/entries/runtime-entry-module.js +9 -3
  66. package/dist/entries/runtime-entry-module.js.map +1 -1
  67. package/dist/index.js +260 -75
  68. package/dist/index.js.map +1 -1
  69. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  70. package/dist/plugins/client-reference-dedup.js +138 -16
  71. package/dist/plugins/client-reference-dedup.js.map +1 -1
  72. package/dist/plugins/css-data-url.d.ts +7 -0
  73. package/dist/plugins/css-data-url.js +81 -0
  74. package/dist/plugins/css-data-url.js.map +1 -0
  75. package/dist/plugins/fonts.d.ts +2 -2
  76. package/dist/plugins/fonts.js +20 -9
  77. package/dist/plugins/fonts.js.map +1 -1
  78. package/dist/plugins/middleware-server-only.d.ts +54 -0
  79. package/dist/plugins/middleware-server-only.js +91 -0
  80. package/dist/plugins/middleware-server-only.js.map +1 -0
  81. package/dist/plugins/optimize-imports.js +4 -4
  82. package/dist/plugins/optimize-imports.js.map +1 -1
  83. package/dist/plugins/sass.d.ts +34 -0
  84. package/dist/plugins/sass.js +22 -0
  85. package/dist/plugins/sass.js.map +1 -0
  86. package/dist/plugins/strip-server-exports.js +5 -8
  87. package/dist/plugins/strip-server-exports.js.map +1 -1
  88. package/dist/routing/app-route-graph.d.ts +50 -2
  89. package/dist/routing/app-route-graph.js +140 -16
  90. package/dist/routing/app-route-graph.js.map +1 -1
  91. package/dist/routing/app-router.d.ts +2 -2
  92. package/dist/routing/app-router.js +2 -2
  93. package/dist/routing/app-router.js.map +1 -1
  94. package/dist/routing/route-pattern.d.ts +56 -1
  95. package/dist/routing/route-pattern.js +60 -1
  96. package/dist/routing/route-pattern.js.map +1 -1
  97. package/dist/routing/utils.d.ts +2 -1
  98. package/dist/routing/utils.js +4 -1
  99. package/dist/routing/utils.js.map +1 -1
  100. package/dist/server/api-handler.js +139 -37
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-browser-action-result.d.ts +27 -2
  103. package/dist/server/app-browser-action-result.js +63 -2
  104. package/dist/server/app-browser-action-result.js.map +1 -1
  105. package/dist/server/app-browser-entry.js +493 -195
  106. package/dist/server/app-browser-entry.js.map +1 -1
  107. package/dist/server/app-browser-hydration.d.ts +13 -1
  108. package/dist/server/app-browser-hydration.js +9 -1
  109. package/dist/server/app-browser-hydration.js.map +1 -1
  110. package/dist/server/app-browser-interception-context.d.ts +24 -0
  111. package/dist/server/app-browser-interception-context.js +32 -0
  112. package/dist/server/app-browser-interception-context.js.map +1 -0
  113. package/dist/server/app-browser-navigation-controller.d.ts +17 -2
  114. package/dist/server/app-browser-navigation-controller.js +33 -10
  115. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  116. package/dist/server/app-browser-popstate.d.ts +16 -0
  117. package/dist/server/app-browser-popstate.js +17 -0
  118. package/dist/server/app-browser-popstate.js.map +1 -0
  119. package/dist/server/app-browser-rsc-redirect.d.ts +29 -0
  120. package/dist/server/app-browser-rsc-redirect.js +37 -0
  121. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  122. package/dist/server/app-browser-state.d.ts +28 -7
  123. package/dist/server/app-browser-state.js +63 -27
  124. package/dist/server/app-browser-state.js.map +1 -1
  125. package/dist/server/app-browser-stream.d.ts +9 -17
  126. package/dist/server/app-browser-stream.js +18 -13
  127. package/dist/server/app-browser-stream.js.map +1 -1
  128. package/dist/server/app-browser-visible-commit.d.ts +7 -1
  129. package/dist/server/app-browser-visible-commit.js +39 -5
  130. package/dist/server/app-browser-visible-commit.js.map +1 -1
  131. package/dist/server/app-elements-wire.d.ts +43 -6
  132. package/dist/server/app-elements-wire.js +189 -7
  133. package/dist/server/app-elements-wire.js.map +1 -1
  134. package/dist/server/app-elements.d.ts +3 -2
  135. package/dist/server/app-elements.js +3 -2
  136. package/dist/server/app-elements.js.map +1 -1
  137. package/dist/server/app-fallback-renderer.d.ts +10 -1
  138. package/dist/server/app-fallback-renderer.js +41 -3
  139. package/dist/server/app-fallback-renderer.js.map +1 -1
  140. package/dist/server/app-history-state.d.ts +26 -0
  141. package/dist/server/app-history-state.js +53 -0
  142. package/dist/server/app-history-state.js.map +1 -0
  143. package/dist/server/app-middleware.d.ts +13 -0
  144. package/dist/server/app-middleware.js +3 -1
  145. package/dist/server/app-middleware.js.map +1 -1
  146. package/dist/server/app-optimistic-routing.d.ts +54 -0
  147. package/dist/server/app-optimistic-routing.js +200 -0
  148. package/dist/server/app-optimistic-routing.js.map +1 -0
  149. package/dist/server/app-page-boundary-render.d.ts +10 -1
  150. package/dist/server/app-page-boundary-render.js +13 -6
  151. package/dist/server/app-page-boundary-render.js.map +1 -1
  152. package/dist/server/app-page-boundary.js +3 -2
  153. package/dist/server/app-page-boundary.js.map +1 -1
  154. package/dist/server/app-page-cache.d.ts +26 -1
  155. package/dist/server/app-page-cache.js +86 -14
  156. package/dist/server/app-page-cache.js.map +1 -1
  157. package/dist/server/app-page-dispatch.d.ts +7 -0
  158. package/dist/server/app-page-dispatch.js +96 -12
  159. package/dist/server/app-page-dispatch.js.map +1 -1
  160. package/dist/server/app-page-element-builder.d.ts +7 -0
  161. package/dist/server/app-page-element-builder.js +34 -5
  162. package/dist/server/app-page-element-builder.js.map +1 -1
  163. package/dist/server/app-page-execution.d.ts +28 -1
  164. package/dist/server/app-page-execution.js +91 -7
  165. package/dist/server/app-page-execution.js.map +1 -1
  166. package/dist/server/app-page-head.d.ts +7 -0
  167. package/dist/server/app-page-head.js +23 -3
  168. package/dist/server/app-page-head.js.map +1 -1
  169. package/dist/server/app-page-probe.d.ts +23 -1
  170. package/dist/server/app-page-probe.js +29 -1
  171. package/dist/server/app-page-probe.js.map +1 -1
  172. package/dist/server/app-page-render-observation.d.ts +35 -0
  173. package/dist/server/app-page-render-observation.js +68 -0
  174. package/dist/server/app-page-render-observation.js.map +1 -0
  175. package/dist/server/app-page-render.d.ts +7 -1
  176. package/dist/server/app-page-render.js +81 -4
  177. package/dist/server/app-page-render.js.map +1 -1
  178. package/dist/server/app-page-request.d.ts +1 -0
  179. package/dist/server/app-page-request.js.map +1 -1
  180. package/dist/server/app-page-response.js +7 -5
  181. package/dist/server/app-page-response.js.map +1 -1
  182. package/dist/server/app-page-route-wiring.d.ts +3 -1
  183. package/dist/server/app-page-route-wiring.js +59 -24
  184. package/dist/server/app-page-route-wiring.js.map +1 -1
  185. package/dist/server/app-page-stream.d.ts +5 -0
  186. package/dist/server/app-page-stream.js +2 -0
  187. package/dist/server/app-page-stream.js.map +1 -1
  188. package/dist/server/app-prerender-static-params.d.ts +2 -1
  189. package/dist/server/app-prerender-static-params.js +44 -8
  190. package/dist/server/app-prerender-static-params.js.map +1 -1
  191. package/dist/server/app-route-handler-cache.d.ts +2 -2
  192. package/dist/server/app-route-handler-cache.js +3 -2
  193. package/dist/server/app-route-handler-cache.js.map +1 -1
  194. package/dist/server/app-route-handler-dispatch.d.ts +6 -1
  195. package/dist/server/app-route-handler-dispatch.js +1 -1
  196. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  197. package/dist/server/app-route-handler-execution.d.ts +17 -2
  198. package/dist/server/app-route-handler-execution.js.map +1 -1
  199. package/dist/server/app-route-handler-response.js +5 -4
  200. package/dist/server/app-route-handler-response.js.map +1 -1
  201. package/dist/server/app-router-entry.js +7 -15
  202. package/dist/server/app-router-entry.js.map +1 -1
  203. package/dist/server/app-rsc-cache-busting.d.ts +19 -1
  204. package/dist/server/app-rsc-cache-busting.js +36 -1
  205. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  206. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  207. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  208. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  209. package/dist/server/app-rsc-errors.d.ts +4 -1
  210. package/dist/server/app-rsc-errors.js +1 -1
  211. package/dist/server/app-rsc-errors.js.map +1 -1
  212. package/dist/server/app-rsc-handler.d.ts +21 -5
  213. package/dist/server/app-rsc-handler.js +38 -15
  214. package/dist/server/app-rsc-handler.js.map +1 -1
  215. package/dist/server/app-rsc-render-mode.d.ts +4 -3
  216. package/dist/server/app-rsc-render-mode.js +7 -1
  217. package/dist/server/app-rsc-render-mode.js.map +1 -1
  218. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  219. package/dist/server/app-rsc-request-normalization.js +4 -1
  220. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  221. package/dist/server/app-rsc-response-finalizer.d.ts +8 -1
  222. package/dist/server/app-rsc-response-finalizer.js +10 -3
  223. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  224. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  225. package/dist/server/app-rsc-route-matching.js +47 -25
  226. package/dist/server/app-rsc-route-matching.js.map +1 -1
  227. package/dist/server/app-server-action-execution.d.ts +35 -3
  228. package/dist/server/app-server-action-execution.js +87 -33
  229. package/dist/server/app-server-action-execution.js.map +1 -1
  230. package/dist/server/app-ssr-entry.d.ts +3 -0
  231. package/dist/server/app-ssr-entry.js +83 -58
  232. package/dist/server/app-ssr-entry.js.map +1 -1
  233. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  234. package/dist/server/app-ssr-error-meta.js +50 -0
  235. package/dist/server/app-ssr-error-meta.js.map +1 -0
  236. package/dist/server/app-ssr-stream.d.ts +7 -2
  237. package/dist/server/app-ssr-stream.js +26 -15
  238. package/dist/server/app-ssr-stream.js.map +1 -1
  239. package/dist/server/artifact-compatibility.d.ts +13 -3
  240. package/dist/server/artifact-compatibility.js +12 -8
  241. package/dist/server/artifact-compatibility.js.map +1 -1
  242. package/dist/server/cache-headers.d.ts +7 -0
  243. package/dist/server/cache-headers.js +19 -0
  244. package/dist/server/cache-headers.js.map +1 -0
  245. package/dist/server/cache-proof.d.ts +170 -5
  246. package/dist/server/cache-proof.js +472 -18
  247. package/dist/server/cache-proof.js.map +1 -1
  248. package/dist/server/client-reuse-manifest.d.ts +99 -0
  249. package/dist/server/client-reuse-manifest.js +212 -0
  250. package/dist/server/client-reuse-manifest.js.map +1 -0
  251. package/dist/server/default-global-error-module.d.ts +20 -0
  252. package/dist/server/default-global-error-module.js +20 -0
  253. package/dist/server/default-global-error-module.js.map +1 -0
  254. package/dist/server/dev-lockfile.d.ts +110 -0
  255. package/dist/server/dev-lockfile.js +180 -0
  256. package/dist/server/dev-lockfile.js.map +1 -0
  257. package/dist/server/dev-server.d.ts +9 -1
  258. package/dist/server/dev-server.js +76 -19
  259. package/dist/server/dev-server.js.map +1 -1
  260. package/dist/server/edge-api-runtime.d.ts +5 -0
  261. package/dist/server/edge-api-runtime.js +8 -0
  262. package/dist/server/edge-api-runtime.js.map +1 -0
  263. package/dist/server/file-based-metadata.d.ts +13 -0
  264. package/dist/server/file-based-metadata.js +49 -2
  265. package/dist/server/file-based-metadata.js.map +1 -1
  266. package/dist/server/headers.d.ts +20 -1
  267. package/dist/server/headers.js +22 -2
  268. package/dist/server/headers.js.map +1 -1
  269. package/dist/server/html.js +1 -1
  270. package/dist/server/html.js.map +1 -1
  271. package/dist/server/http-error-responses.d.ts +26 -1
  272. package/dist/server/http-error-responses.js +32 -2
  273. package/dist/server/http-error-responses.js.map +1 -1
  274. package/dist/server/isr-cache.d.ts +8 -3
  275. package/dist/server/isr-cache.js +24 -6
  276. package/dist/server/isr-cache.js.map +1 -1
  277. package/dist/server/metadata-route-response.js +22 -5
  278. package/dist/server/metadata-route-response.js.map +1 -1
  279. package/dist/server/metadata-routes.js +27 -8
  280. package/dist/server/metadata-routes.js.map +1 -1
  281. package/dist/server/middleware-runtime.d.ts +15 -0
  282. package/dist/server/middleware-runtime.js +60 -7
  283. package/dist/server/middleware-runtime.js.map +1 -1
  284. package/dist/server/middleware.d.ts +13 -1
  285. package/dist/server/middleware.js +16 -2
  286. package/dist/server/middleware.js.map +1 -1
  287. package/dist/server/navigation-planner.d.ts +26 -6
  288. package/dist/server/navigation-planner.js +358 -24
  289. package/dist/server/navigation-planner.js.map +1 -1
  290. package/dist/server/navigation-trace.d.ts +9 -1
  291. package/dist/server/navigation-trace.js +8 -0
  292. package/dist/server/navigation-trace.js.map +1 -1
  293. package/dist/server/normalize-path.d.ts +2 -1
  294. package/dist/server/normalize-path.js +4 -1
  295. package/dist/server/normalize-path.js.map +1 -1
  296. package/dist/server/pages-api-route.d.ts +27 -1
  297. package/dist/server/pages-api-route.js +25 -3
  298. package/dist/server/pages-api-route.js.map +1 -1
  299. package/dist/server/pages-data-route.d.ts +77 -0
  300. package/dist/server/pages-data-route.js +97 -0
  301. package/dist/server/pages-data-route.js.map +1 -0
  302. package/dist/server/pages-i18n.d.ts +51 -1
  303. package/dist/server/pages-i18n.js +61 -1
  304. package/dist/server/pages-i18n.js.map +1 -1
  305. package/dist/server/pages-page-data.d.ts +32 -4
  306. package/dist/server/pages-page-data.js +52 -19
  307. package/dist/server/pages-page-data.js.map +1 -1
  308. package/dist/server/pages-page-response.d.ts +11 -1
  309. package/dist/server/pages-page-response.js +6 -4
  310. package/dist/server/pages-page-response.js.map +1 -1
  311. package/dist/server/prod-server.d.ts +26 -1
  312. package/dist/server/prod-server.js +150 -44
  313. package/dist/server/prod-server.js.map +1 -1
  314. package/dist/server/request-pipeline.d.ts +11 -2
  315. package/dist/server/request-pipeline.js +28 -11
  316. package/dist/server/request-pipeline.js.map +1 -1
  317. package/dist/server/seed-cache.d.ts +12 -31
  318. package/dist/server/seed-cache.js +22 -35
  319. package/dist/server/seed-cache.js.map +1 -1
  320. package/dist/server/server-action-not-found.d.ts +16 -3
  321. package/dist/server/server-action-not-found.js +27 -4
  322. package/dist/server/server-action-not-found.js.map +1 -1
  323. package/dist/server/server-globals.d.ts +5 -0
  324. package/dist/server/server-globals.js +37 -0
  325. package/dist/server/server-globals.js.map +1 -0
  326. package/dist/server/skip-cache-proof.d.ts +41 -0
  327. package/dist/server/skip-cache-proof.js +101 -0
  328. package/dist/server/skip-cache-proof.js.map +1 -0
  329. package/dist/server/static-file-cache.d.ts +1 -1
  330. package/dist/server/static-file-cache.js +7 -6
  331. package/dist/server/static-file-cache.js.map +1 -1
  332. package/dist/shims/cache-runtime.d.ts +19 -2
  333. package/dist/shims/cache-runtime.js +67 -11
  334. package/dist/shims/cache-runtime.js.map +1 -1
  335. package/dist/shims/cache.d.ts +5 -18
  336. package/dist/shims/cache.js +2 -0
  337. package/dist/shims/cache.js.map +1 -1
  338. package/dist/shims/client-locale.d.ts +15 -0
  339. package/dist/shims/client-locale.js +13 -0
  340. package/dist/shims/client-locale.js.map +1 -0
  341. package/dist/shims/default-global-error.d.ts +32 -0
  342. package/dist/shims/default-global-error.js +181 -0
  343. package/dist/shims/default-global-error.js.map +1 -0
  344. package/dist/shims/document.d.ts +59 -3
  345. package/dist/shims/document.js +36 -5
  346. package/dist/shims/document.js.map +1 -1
  347. package/dist/shims/error-boundary.d.ts +2 -2
  348. package/dist/shims/error-boundary.js +6 -8
  349. package/dist/shims/error-boundary.js.map +1 -1
  350. package/dist/shims/error.d.ts +18 -1
  351. package/dist/shims/error.js +56 -1
  352. package/dist/shims/error.js.map +1 -1
  353. package/dist/shims/fetch-cache.d.ts +4 -1
  354. package/dist/shims/fetch-cache.js +40 -5
  355. package/dist/shims/fetch-cache.js.map +1 -1
  356. package/dist/shims/font-google-base.d.ts +22 -8
  357. package/dist/shims/font-google-base.js +41 -71
  358. package/dist/shims/font-google-base.js.map +1 -1
  359. package/dist/shims/font-local.d.ts +3 -20
  360. package/dist/shims/font-local.js +23 -75
  361. package/dist/shims/font-local.js.map +1 -1
  362. package/dist/shims/font-utils.d.ts +51 -0
  363. package/dist/shims/font-utils.js +97 -0
  364. package/dist/shims/font-utils.js.map +1 -0
  365. package/dist/shims/form.js +13 -6
  366. package/dist/shims/form.js.map +1 -1
  367. package/dist/shims/hash-scroll.d.ts +7 -0
  368. package/dist/shims/hash-scroll.js +30 -0
  369. package/dist/shims/hash-scroll.js.map +1 -0
  370. package/dist/shims/headers.d.ts +8 -11
  371. package/dist/shims/headers.js +22 -2
  372. package/dist/shims/headers.js.map +1 -1
  373. package/dist/shims/image.d.ts +1 -0
  374. package/dist/shims/image.js +144 -78
  375. package/dist/shims/image.js.map +1 -1
  376. package/dist/shims/internal/app-router-context.d.ts +6 -6
  377. package/dist/shims/internal/app-router-context.js +17 -6
  378. package/dist/shims/internal/app-router-context.js.map +1 -1
  379. package/dist/shims/link-prefetch.d.ts +9 -1
  380. package/dist/shims/link-prefetch.js +11 -6
  381. package/dist/shims/link-prefetch.js.map +1 -1
  382. package/dist/shims/link.d.ts +33 -5
  383. package/dist/shims/link.js +205 -50
  384. package/dist/shims/link.js.map +1 -1
  385. package/dist/shims/metadata.d.ts +16 -30
  386. package/dist/shims/metadata.js +91 -32
  387. package/dist/shims/metadata.js.map +1 -1
  388. package/dist/shims/navigation.d.ts +164 -17
  389. package/dist/shims/navigation.js +355 -84
  390. package/dist/shims/navigation.js.map +1 -1
  391. package/dist/shims/navigation.react-server.d.ts +3 -2
  392. package/dist/shims/navigation.react-server.js +5 -2
  393. package/dist/shims/navigation.react-server.js.map +1 -1
  394. package/dist/shims/og.d.ts +18 -2
  395. package/dist/shims/og.js +49 -1
  396. package/dist/shims/og.js.map +1 -0
  397. package/dist/shims/pages-router-runtime.d.ts +7 -0
  398. package/dist/shims/pages-router-runtime.js +16 -0
  399. package/dist/shims/pages-router-runtime.js.map +1 -0
  400. package/dist/shims/request-state-types.d.ts +1 -1
  401. package/dist/shims/root-params.d.ts +3 -1
  402. package/dist/shims/root-params.js +11 -3
  403. package/dist/shims/root-params.js.map +1 -1
  404. package/dist/shims/router-state.d.ts +1 -0
  405. package/dist/shims/router-state.js.map +1 -1
  406. package/dist/shims/router.d.ts +40 -7
  407. package/dist/shims/router.js +355 -250
  408. package/dist/shims/router.js.map +1 -1
  409. package/dist/shims/script.js +110 -32
  410. package/dist/shims/script.js.map +1 -1
  411. package/dist/shims/server.d.ts +21 -4
  412. package/dist/shims/server.js +31 -10
  413. package/dist/shims/server.js.map +1 -1
  414. package/dist/shims/slot.d.ts +1 -0
  415. package/dist/shims/slot.js +45 -1
  416. package/dist/shims/slot.js.map +1 -1
  417. package/dist/shims/unified-request-context.d.ts +1 -1
  418. package/dist/shims/unified-request-context.js +2 -0
  419. package/dist/shims/unified-request-context.js.map +1 -1
  420. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  421. package/dist/shims/unrecognized-action-error.js +41 -0
  422. package/dist/shims/unrecognized-action-error.js.map +1 -0
  423. package/dist/shims/url-safety.d.ts +23 -1
  424. package/dist/shims/url-safety.js +29 -2
  425. package/dist/shims/url-safety.js.map +1 -1
  426. package/dist/shims/url-utils.d.ts +21 -1
  427. package/dist/shims/url-utils.js +67 -3
  428. package/dist/shims/url-utils.js.map +1 -1
  429. package/dist/typegen.d.ts +10 -0
  430. package/dist/typegen.js +242 -0
  431. package/dist/typegen.js.map +1 -0
  432. package/dist/utils/asset-prefix.d.ts +97 -0
  433. package/dist/utils/asset-prefix.js +124 -0
  434. package/dist/utils/asset-prefix.js.map +1 -0
  435. package/dist/utils/base-path.d.ts +7 -1
  436. package/dist/utils/base-path.js +10 -1
  437. package/dist/utils/base-path.js.map +1 -1
  438. package/dist/utils/cache-control-metadata.d.ts +2 -1
  439. package/dist/utils/cache-control-metadata.js +1 -3
  440. package/dist/utils/cache-control-metadata.js.map +1 -1
  441. package/dist/utils/domain-locale.d.ts +2 -1
  442. package/dist/utils/domain-locale.js +9 -1
  443. package/dist/utils/domain-locale.js.map +1 -1
  444. package/dist/utils/lazy-chunks.d.ts +1 -1
  445. package/dist/utils/lazy-chunks.js +1 -1
  446. package/dist/utils/lazy-chunks.js.map +1 -1
  447. package/dist/utils/navigation-signal.d.ts +1 -2
  448. package/dist/utils/navigation-signal.js +1 -1
  449. package/dist/utils/navigation-signal.js.map +1 -1
  450. package/dist/utils/prerender-output-paths.d.ts +15 -0
  451. package/dist/utils/prerender-output-paths.js +24 -0
  452. package/dist/utils/prerender-output-paths.js.map +1 -0
  453. package/dist/utils/query.d.ts +17 -1
  454. package/dist/utils/query.js +36 -1
  455. package/dist/utils/query.js.map +1 -1
  456. package/dist/utils/record.d.ts +5 -0
  457. package/dist/utils/record.js +8 -0
  458. package/dist/utils/record.js.map +1 -0
  459. package/dist/utils/sorted-array.d.ts +9 -0
  460. package/dist/utils/sorted-array.js +22 -0
  461. package/dist/utils/sorted-array.js.map +1 -0
  462. package/package.json +13 -5
@@ -0,0 +1,200 @@
1
+ import { decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
2
+ import { stripBasePath } from "../utils/base-path.js";
3
+ import { isUnknownRecord } from "../utils/record.js";
4
+ import { AppElementsWire } from "./app-elements-wire.js";
5
+ import "./app-elements.js";
6
+ import { stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
7
+ import { Suspense, createElement, isValidElement } from "react";
8
+ //#region src/server/app-optimistic-routing.ts
9
+ const routeTrieCache = /* @__PURE__ */ new WeakMap();
10
+ const OPTIMISTIC_ROUTE_SEGMENT_SUSPENSE_TRIGGER = new Promise(() => {});
11
+ function getOptimisticRouteTemplateKey(options) {
12
+ return `${options.routeId}\0${options.interceptionContext ?? ""}\0${options.mountedSlotsHeader ?? ""}`;
13
+ }
14
+ function getOptimisticPrefetchSourceKey(options) {
15
+ return `${options.cacheKey}\0${options.interceptionContext ?? ""}\0${options.mountedSlotsHeader ?? ""}`;
16
+ }
17
+ function createNode() {
18
+ return {
19
+ catchAllChild: null,
20
+ dynamicChild: null,
21
+ optionalCatchAllChild: null,
22
+ route: null,
23
+ staticChildren: /* @__PURE__ */ new Map()
24
+ };
25
+ }
26
+ function buildRouteTrie(routeManifest) {
27
+ const root = createNode();
28
+ for (const route of routeManifest.segmentGraph.routes.values()) {
29
+ let node = root;
30
+ const parts = route.patternParts;
31
+ if (parts.length === 0) {
32
+ node.route ??= route;
33
+ continue;
34
+ }
35
+ for (const [index, part] of parts.entries()) {
36
+ const isTerminal = index === parts.length - 1;
37
+ if (part.startsWith(":") && part.endsWith("+")) {
38
+ if (isTerminal && node.catchAllChild === null) node.catchAllChild = {
39
+ paramName: part.slice(1, -1),
40
+ route
41
+ };
42
+ break;
43
+ }
44
+ if (part.startsWith(":") && part.endsWith("*")) {
45
+ if (isTerminal && node.optionalCatchAllChild === null) node.optionalCatchAllChild = {
46
+ paramName: part.slice(1, -1),
47
+ route
48
+ };
49
+ break;
50
+ }
51
+ if (part.startsWith(":")) {
52
+ const paramName = part.slice(1);
53
+ if (node.dynamicChild === null) node.dynamicChild = {
54
+ node: createNode(),
55
+ paramName
56
+ };
57
+ else if (node.dynamicChild.paramName !== paramName && import.meta.env.DEV) console.warn(`[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${node.dynamicChild.paramName} vs ${part}`);
58
+ node = node.dynamicChild.node;
59
+ if (isTerminal) node.route ??= route;
60
+ continue;
61
+ }
62
+ let staticChild = node.staticChildren.get(part);
63
+ if (staticChild === void 0) {
64
+ staticChild = createNode();
65
+ node.staticChildren.set(part, staticChild);
66
+ }
67
+ node = staticChild;
68
+ if (isTerminal) node.route ??= route;
69
+ }
70
+ }
71
+ return root;
72
+ }
73
+ function getRouteTrie(routeManifest) {
74
+ const existing = routeTrieCache.get(routeManifest);
75
+ if (existing) return existing;
76
+ const trie = buildRouteTrie(routeManifest);
77
+ routeTrieCache.set(routeManifest, trie);
78
+ return trie;
79
+ }
80
+ function matchNode(node, urlParts, index) {
81
+ if (index === urlParts.length) {
82
+ if (node.route !== null) return {
83
+ route: node.route,
84
+ params: Object.create(null)
85
+ };
86
+ if (node.optionalCatchAllChild !== null) return {
87
+ route: node.optionalCatchAllChild.route,
88
+ params: Object.create(null)
89
+ };
90
+ return null;
91
+ }
92
+ const segment = urlParts[index];
93
+ const staticChild = node.staticChildren.get(segment);
94
+ if (staticChild !== void 0) return matchNode(staticChild, urlParts, index + 1);
95
+ if (node.dynamicChild !== null) {
96
+ const match = matchNode(node.dynamicChild.node, urlParts, index + 1);
97
+ if (match === null) return null;
98
+ match.params[node.dynamicChild.paramName] = segment;
99
+ return match;
100
+ }
101
+ if (node.catchAllChild !== null) return {
102
+ route: node.catchAllChild.route,
103
+ params: { [node.catchAllChild.paramName]: urlParts.slice(index) }
104
+ };
105
+ if (node.optionalCatchAllChild !== null) return {
106
+ route: node.optionalCatchAllChild.route,
107
+ params: { [node.optionalCatchAllChild.paramName]: urlParts.slice(index) }
108
+ };
109
+ return null;
110
+ }
111
+ function hrefToRouteParts(href, basePath) {
112
+ let url;
113
+ try {
114
+ url = new URL(href, "https://vinext.local");
115
+ } catch {
116
+ return null;
117
+ }
118
+ stripRscCacheBustingSearchParam(url);
119
+ const appPathname = stripBasePath(stripRscSuffix(url.pathname), basePath);
120
+ return splitPathnameForRouteMatch(appPathname === "" ? "/" : appPathname);
121
+ }
122
+ function matchOptimisticRouteManifestRoute(options) {
123
+ const urlParts = hrefToRouteParts(options.href, options.basePath);
124
+ if (urlParts === null) return null;
125
+ const match = matchNode(getRouteTrie(options.routeManifest), urlParts, 0);
126
+ if (match === null) return null;
127
+ decodeMatchedParams(match.params);
128
+ return match;
129
+ }
130
+ function elementHasSuspenseFallback(value, depth = 0) {
131
+ if (depth > 100) return false;
132
+ if (Array.isArray(value)) return value.some((entry) => elementHasSuspenseFallback(entry, depth + 1));
133
+ if (!isValidElement(value)) return false;
134
+ const props = Reflect.get(value, "props");
135
+ if (value.type === Suspense && isUnknownRecord(props)) {
136
+ const fallback = Reflect.get(props, "fallback");
137
+ if (fallback !== null && fallback !== void 0) return true;
138
+ }
139
+ if (!isUnknownRecord(props)) return false;
140
+ return elementHasSuspenseFallback(Reflect.get(props, "children"), depth + 1);
141
+ }
142
+ function getPageElementIds(elements) {
143
+ return Object.keys(elements).filter((key) => AppElementsWire.parseElementKey(key)?.kind === "page").sort();
144
+ }
145
+ function OptimisticRouteSegment() {
146
+ throw OPTIMISTIC_ROUTE_SEGMENT_SUSPENSE_TRIGGER;
147
+ }
148
+ function createOptimisticRouteTemplate(options) {
149
+ const match = matchOptimisticRouteManifestRoute({
150
+ basePath: options.basePath,
151
+ href: options.href,
152
+ routeManifest: options.routeManifest
153
+ });
154
+ if (match === null || !match.route.isDynamic) return null;
155
+ if (options.interceptionContext !== null) return null;
156
+ const metadata = AppElementsWire.readMetadata(options.elements);
157
+ if (metadata.interception !== null || metadata.interceptionContext !== null) return null;
158
+ const routeElement = options.elements[metadata.routeId];
159
+ if (!options.allowLoadingShell && !elementHasSuspenseFallback(routeElement)) return null;
160
+ if (options.allowLoadingShell && options.elements["__prefetchLoadingShell"] !== "LoadingBoundary") return null;
161
+ if (options.allowLoadingShell && (routeElement === void 0 || routeElement === null)) return null;
162
+ const pageElementIds = getPageElementIds(options.elements);
163
+ if (pageElementIds.length === 0) return null;
164
+ return {
165
+ elements: options.elements,
166
+ mountedSlotsHeader: options.mountedSlotsHeader,
167
+ pageElementIds,
168
+ routeId: match.route.id
169
+ };
170
+ }
171
+ function createOptimisticRouteElements(template) {
172
+ const elements = { ...template.elements };
173
+ for (const pageElementId of template.pageElementIds) elements[pageElementId] = createElement(OptimisticRouteSegment);
174
+ return elements;
175
+ }
176
+ function resolveOptimisticNavigationPayload(options) {
177
+ if (options.interceptionContext !== null) return null;
178
+ const match = matchOptimisticRouteManifestRoute({
179
+ basePath: options.basePath,
180
+ href: options.href,
181
+ routeManifest: options.routeManifest
182
+ });
183
+ if (match === null || !match.route.isDynamic) return null;
184
+ const template = options.templates.get(getOptimisticRouteTemplateKey({
185
+ interceptionContext: options.interceptionContext,
186
+ mountedSlotsHeader: options.mountedSlotsHeader,
187
+ routeId: match.route.id
188
+ }));
189
+ if (template === void 0) return null;
190
+ if (template.mountedSlotsHeader !== options.mountedSlotsHeader) return null;
191
+ return {
192
+ elements: createOptimisticRouteElements(template),
193
+ params: match.params,
194
+ template
195
+ };
196
+ }
197
+ //#endregion
198
+ export { createOptimisticRouteElements, createOptimisticRouteTemplate, getOptimisticPrefetchSourceKey, getOptimisticRouteTemplateKey, matchOptimisticRouteManifestRoute, resolveOptimisticNavigationPayload };
199
+
200
+ //# sourceMappingURL=app-optimistic-routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-optimistic-routing.js","names":[],"sources":["../../src/server/app-optimistic-routing.ts"],"sourcesContent":["import { createElement, isValidElement, Suspense } from \"react\";\nimport { isUnknownRecord } from \"../utils/record.js\";\nimport { stripBasePath } from \"../utils/base-path.js\";\nimport { decodeMatchedParams, splitPathnameForRouteMatch } from \"../routing/utils.js\";\nimport type { RouteManifest, RouteManifestRoute } from \"../routing/app-route-graph.js\";\nimport { stripRscCacheBustingSearchParam, stripRscSuffix } from \"./app-rsc-cache-busting.js\";\nimport {\n AppElementsWire,\n APP_PREFETCH_LOADING_SHELL_MARKER_KEY,\n type AppElementValue,\n type AppElements,\n} from \"./app-elements.js\";\n\ntype OptimisticRouteTrieNode = {\n catchAllChild: { paramName: string; route: RouteManifestRoute } | null;\n dynamicChild: { node: OptimisticRouteTrieNode; paramName: string } | null;\n optionalCatchAllChild: { paramName: string; route: RouteManifestRoute } | null;\n route: RouteManifestRoute | null;\n staticChildren: Map<string, OptimisticRouteTrieNode>;\n};\n\ntype OptimisticRouteMatch = {\n params: Record<string, string | string[]>;\n route: RouteManifestRoute;\n};\n\nexport type OptimisticRouteTemplate = {\n elements: AppElements;\n mountedSlotsHeader: string | null;\n pageElementIds: readonly string[];\n routeId: string;\n};\n\ntype OptimisticNavigationPayload = {\n elements: AppElements;\n params: Record<string, string | string[]>;\n template: OptimisticRouteTemplate;\n};\n\nconst routeTrieCache = new WeakMap<RouteManifest, OptimisticRouteTrieNode>();\n// Shared never-settling thenable used to suspend optimistic page segments until\n// the real RSC payload replaces them.\nconst OPTIMISTIC_ROUTE_SEGMENT_SUSPENSE_TRIGGER = new Promise<never>(() => {});\n\nexport function getOptimisticRouteTemplateKey(options: {\n interceptionContext: string | null;\n mountedSlotsHeader: string | null;\n routeId: string;\n}): string {\n return `${options.routeId}\\0${options.interceptionContext ?? \"\"}\\0${options.mountedSlotsHeader ?? \"\"}`;\n}\n\nexport function getOptimisticPrefetchSourceKey(options: {\n cacheKey: string;\n interceptionContext: string | null;\n mountedSlotsHeader: string | null;\n}): string {\n return `${options.cacheKey}\\0${options.interceptionContext ?? \"\"}\\0${options.mountedSlotsHeader ?? \"\"}`;\n}\n\nfunction createNode(): OptimisticRouteTrieNode {\n return {\n catchAllChild: null,\n dynamicChild: null,\n optionalCatchAllChild: null,\n route: null,\n staticChildren: new Map(),\n };\n}\n\nfunction buildRouteTrie(routeManifest: RouteManifest): OptimisticRouteTrieNode {\n const root = createNode();\n\n for (const route of routeManifest.segmentGraph.routes.values()) {\n let node = root;\n const parts = route.patternParts;\n\n if (parts.length === 0) {\n node.route ??= route;\n continue;\n }\n\n for (const [index, part] of parts.entries()) {\n const isTerminal = index === parts.length - 1;\n if (part.startsWith(\":\") && part.endsWith(\"+\")) {\n if (isTerminal && node.catchAllChild === null) {\n node.catchAllChild = { paramName: part.slice(1, -1), route };\n }\n break;\n }\n\n if (part.startsWith(\":\") && part.endsWith(\"*\")) {\n if (isTerminal && node.optionalCatchAllChild === null) {\n node.optionalCatchAllChild = { paramName: part.slice(1, -1), route };\n }\n break;\n }\n\n if (part.startsWith(\":\")) {\n const paramName = part.slice(1);\n if (node.dynamicChild === null) {\n node.dynamicChild = { node: createNode(), paramName };\n } else if (node.dynamicChild.paramName !== paramName && import.meta.env.DEV) {\n console.warn(\n `[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${node.dynamicChild.paramName} vs ${part}`,\n );\n }\n node = node.dynamicChild.node;\n if (isTerminal) node.route ??= route;\n continue;\n }\n\n let staticChild = node.staticChildren.get(part);\n if (staticChild === undefined) {\n staticChild = createNode();\n node.staticChildren.set(part, staticChild);\n }\n node = staticChild;\n if (isTerminal) node.route ??= route;\n }\n }\n\n return root;\n}\n\nfunction getRouteTrie(routeManifest: RouteManifest): OptimisticRouteTrieNode {\n const existing = routeTrieCache.get(routeManifest);\n if (existing) return existing;\n\n const trie = buildRouteTrie(routeManifest);\n routeTrieCache.set(routeManifest, trie);\n return trie;\n}\n\nfunction matchNode(\n node: OptimisticRouteTrieNode,\n urlParts: readonly string[],\n index: number,\n): OptimisticRouteMatch | null {\n if (index === urlParts.length) {\n if (node.route !== null) {\n return { route: node.route, params: Object.create(null) };\n }\n if (node.optionalCatchAllChild !== null) {\n return {\n route: node.optionalCatchAllChild.route,\n params: Object.create(null),\n };\n }\n return null;\n }\n\n const segment = urlParts[index];\n const staticChild = node.staticChildren.get(segment);\n if (staticChild !== undefined) {\n // Static children are authoritative for optimistic routing. If a known\n // static subtree does not contain the remaining URL, do not fall through to\n // a catch-all sibling and render the wrong loading boundary.\n return matchNode(staticChild, urlParts, index + 1);\n }\n\n if (node.dynamicChild !== null) {\n const match = matchNode(node.dynamicChild.node, urlParts, index + 1);\n if (match === null) return null;\n match.params[node.dynamicChild.paramName] = segment;\n return match;\n }\n\n if (node.catchAllChild !== null) {\n return {\n route: node.catchAllChild.route,\n params: {\n [node.catchAllChild.paramName]: urlParts.slice(index),\n },\n };\n }\n\n if (node.optionalCatchAllChild !== null) {\n return {\n route: node.optionalCatchAllChild.route,\n params: {\n [node.optionalCatchAllChild.paramName]: urlParts.slice(index),\n },\n };\n }\n\n return null;\n}\n\nfunction hrefToRouteParts(href: string, basePath: string): string[] | null {\n let url: URL;\n try {\n url = new URL(href, \"https://vinext.local\");\n } catch {\n return null;\n }\n\n stripRscCacheBustingSearchParam(url);\n const withoutRscSuffix = stripRscSuffix(url.pathname);\n const appPathname = stripBasePath(withoutRscSuffix, basePath);\n return splitPathnameForRouteMatch(appPathname === \"\" ? \"/\" : appPathname);\n}\n\nexport function matchOptimisticRouteManifestRoute(options: {\n basePath: string;\n href: string;\n routeManifest: RouteManifest;\n}): OptimisticRouteMatch | null {\n const urlParts = hrefToRouteParts(options.href, options.basePath);\n if (urlParts === null) return null;\n\n const match = matchNode(getRouteTrie(options.routeManifest), urlParts, 0);\n if (match === null) return null;\n\n decodeMatchedParams(match.params);\n return match;\n}\n\nfunction elementHasSuspenseFallback(value: unknown, depth = 0): boolean {\n if (depth > 100) return false;\n if (Array.isArray(value)) {\n return value.some((entry) => elementHasSuspenseFallback(entry, depth + 1));\n }\n if (!isValidElement(value)) return false;\n\n const props = Reflect.get(value, \"props\");\n if (value.type === Suspense && isUnknownRecord(props)) {\n const fallback = Reflect.get(props, \"fallback\");\n if (fallback !== null && fallback !== undefined) return true;\n }\n\n if (!isUnknownRecord(props)) return false;\n return elementHasSuspenseFallback(Reflect.get(props, \"children\"), depth + 1);\n}\n\nfunction getPageElementIds(elements: AppElements): string[] {\n return Object.keys(elements)\n .filter((key) => AppElementsWire.parseElementKey(key)?.kind === \"page\")\n .sort();\n}\n\nfunction OptimisticRouteSegment(): null {\n throw OPTIMISTIC_ROUTE_SEGMENT_SUSPENSE_TRIGGER;\n}\n\nexport function createOptimisticRouteTemplate(options: {\n allowLoadingShell?: boolean;\n basePath: string;\n elements: AppElements;\n href: string;\n interceptionContext: string | null;\n mountedSlotsHeader: string | null;\n routeManifest: RouteManifest;\n}): OptimisticRouteTemplate | null {\n const match = matchOptimisticRouteManifestRoute({\n basePath: options.basePath,\n href: options.href,\n routeManifest: options.routeManifest,\n });\n if (match === null || !match.route.isDynamic) return null;\n if (options.interceptionContext !== null) return null;\n\n const metadata = AppElementsWire.readMetadata(options.elements);\n if (metadata.interception !== null || metadata.interceptionContext !== null) return null;\n\n const routeElement = options.elements[metadata.routeId];\n // Full-prefetch learning is intentionally heuristic: legacy full prefetches\n // are accepted only when the serialized route subtree still contains a\n // Suspense fallback. Authoritative loading-shell prefetches use the marker\n // check below instead.\n if (!options.allowLoadingShell && !elementHasSuspenseFallback(routeElement)) return null;\n if (\n options.allowLoadingShell &&\n options.elements[APP_PREFETCH_LOADING_SHELL_MARKER_KEY] !== \"LoadingBoundary\"\n ) {\n return null;\n }\n // Shell prefetches must include the eagerly-rendered loading component. A\n // null route element means the server had no route loading boundary.\n if (options.allowLoadingShell && (routeElement === undefined || routeElement === null))\n return null;\n\n const pageElementIds = getPageElementIds(options.elements);\n if (pageElementIds.length === 0) return null;\n\n return {\n elements: options.elements,\n mountedSlotsHeader: options.mountedSlotsHeader,\n pageElementIds,\n routeId: match.route.id,\n };\n}\n\nexport function createOptimisticRouteElements(template: OptimisticRouteTemplate): AppElements {\n const elements: Record<string, AppElementValue> = { ...template.elements };\n for (const pageElementId of template.pageElementIds) {\n elements[pageElementId] = createElement(OptimisticRouteSegment);\n }\n return elements;\n}\n\nexport function resolveOptimisticNavigationPayload(options: {\n basePath: string;\n href: string;\n interceptionContext: string | null;\n mountedSlotsHeader: string | null;\n routeManifest: RouteManifest;\n templates: ReadonlyMap<string, OptimisticRouteTemplate>;\n}): OptimisticNavigationPayload | null {\n if (options.interceptionContext !== null) return null;\n\n const match = matchOptimisticRouteManifestRoute({\n basePath: options.basePath,\n href: options.href,\n routeManifest: options.routeManifest,\n });\n if (match === null || !match.route.isDynamic) return null;\n\n const template = options.templates.get(\n getOptimisticRouteTemplateKey({\n interceptionContext: options.interceptionContext,\n mountedSlotsHeader: options.mountedSlotsHeader,\n routeId: match.route.id,\n }),\n );\n if (template === undefined) return null;\n if (template.mountedSlotsHeader !== options.mountedSlotsHeader) return null;\n\n return {\n elements: createOptimisticRouteElements(template),\n params: match.params,\n template,\n };\n}\n"],"mappings":"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"}
@@ -38,7 +38,8 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
38
38
  loadSsrHandler: () => Promise<AppPageSsrHandler>;
39
39
  makeThenableParams: (params: AppPageParams) => unknown;
40
40
  middlewareContext: AppPageMiddlewareContext;
41
- metadataRoutes: MetadataFileRoute[];
41
+ metadataRoutes: MetadataFileRoute[]; /** Configured next.config `basePath`, threaded into file-based metadata href emission. */
42
+ basePath?: string;
42
43
  renderToReadableStream: (element: ReactNode | AppElements, options: {
43
44
  onError: AppPageBoundaryOnError;
44
45
  }) => ReadableStream<Uint8Array>;
@@ -55,6 +56,14 @@ type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppP
55
56
  rootNotFoundModule?: TModule | null;
56
57
  rootUnauthorizedModule?: TModule | null;
57
58
  route?: AppPageBoundaryRoute<TModule> | null;
59
+ /**
60
+ * When true, the resolved boundary is rendered without wrapping it in the
61
+ * route's layouts. Used by `global-not-found.tsx`, which provides its own
62
+ * `<html>`/`<body>` and intentionally replaces the root layout.
63
+ * Mirrors Next.js's `createNotFoundLoaderTree` behavior for `hasGlobalNotFound`.
64
+ * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/app-render.tsx#L495-L520
65
+ */
66
+ skipLayoutWrapping?: boolean;
58
67
  statusCode: number;
59
68
  } & AppPageBoundaryRenderCommonOptions<TModule>;
60
69
  type RenderAppPageErrorBoundaryOptions<TModule extends AppPageModule = AppPageModule> = {
@@ -129,13 +129,15 @@ async function renderAppPageHttpAccessFallback(options) {
129
129
  });
130
130
  if (!boundaryComponent) return null;
131
131
  const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;
132
+ const pathname = new URL(options.requestUrl).pathname;
132
133
  const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);
133
134
  const { metadata, viewport } = await resolveAppPageHead({
135
+ basePath: options.basePath ?? "",
134
136
  layoutModules,
135
137
  layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(options.route, layoutModules),
136
138
  metadataRoutes: options.metadataRoutes,
137
139
  params: options.matchedParams,
138
- routePath: options.route?.pattern ?? new URL(options.requestUrl).pathname,
140
+ routePath: options.route?.pattern ?? pathname,
139
141
  routeSegments
140
142
  });
141
143
  const headElements = [createElement("meta", {
@@ -148,12 +150,14 @@ async function renderAppPageHttpAccessFallback(options) {
148
150
  })];
149
151
  if (metadata) headElements.push(createElement(MetadataHead, {
150
152
  key: "metadata",
151
- metadata
153
+ metadata,
154
+ pathname
152
155
  }));
153
156
  headElements.push(createElement(ViewportHead, {
154
157
  key: "viewport",
155
158
  viewport
156
159
  }));
160
+ const skipLayoutWrapping = options.skipLayoutWrapping ?? false;
157
161
  const element = wrapRenderedBoundaryElement({
158
162
  element: createElement(Fragment, null, ...headElements, createElement(boundaryComponent)),
159
163
  globalErrorModule: options.globalErrorModule,
@@ -164,13 +168,14 @@ async function renderAppPageHttpAccessFallback(options) {
164
168
  makeThenableParams: options.makeThenableParams,
165
169
  matchedParams: options.matchedParams,
166
170
  resolveChildSegments: options.resolveChildSegments,
167
- routeSegments: options.route?.routeSegments
171
+ routeSegments: options.route?.routeSegments,
172
+ skipLayoutWrapping
168
173
  });
169
174
  return renderAppPageBoundaryElementResponse({
170
175
  ...options,
171
176
  element,
172
- layoutModules,
173
- route: options.route,
177
+ layoutModules: skipLayoutWrapping ? [] : layoutModules,
178
+ route: skipLayoutWrapping ? null : options.route,
174
179
  routePattern: options.route?.pattern,
175
180
  status: options.statusCode
176
181
  });
@@ -196,6 +201,7 @@ async function renderAppPageErrorBoundary(options) {
196
201
  })];
197
202
  if (!errorBoundary.isGlobalError) try {
198
203
  const { metadata, viewport } = await resolveAppPageHead({
204
+ basePath: options.basePath ?? "",
199
205
  fallbackOnFileMetadataError: true,
200
206
  layoutModules,
201
207
  layoutTreePositions: options.route?.layoutTreePositions,
@@ -206,7 +212,8 @@ async function renderAppPageErrorBoundary(options) {
206
212
  });
207
213
  if (metadata) headElements.push(createElement(MetadataHead, {
208
214
  key: "metadata",
209
- metadata
215
+ metadata,
216
+ pathname
210
217
  }));
211
218
  headElements.push(createElement(ViewportHead, {
212
219
  key: "viewport",
@@ -1 +1 @@
1
- {"version":3,"file":"app-page-boundary-render.js","names":[],"sources":["../../src/server/app-page-boundary-render.ts"],"sourcesContent":["import { Fragment, createElement, type ComponentType, type ReactNode } from \"react\";\nimport { buildClientHookErrorMessage } from \"vinext/shims/client-hook-error\";\nimport { ErrorBoundary } from \"vinext/shims/error-boundary\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport { MetadataHead, ViewportHead } from \"vinext/shims/metadata\";\nimport type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { AppPageMiddlewareContext } from \"./app-page-response.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\nimport { resolveAppPageHead } from \"./app-page-head.js\";\nimport {\n renderAppPageBoundaryResponse,\n resolveAppPageErrorBoundary,\n resolveAppPageHttpAccessBoundaryComponent,\n wrapAppPageBoundaryElement,\n type AppPageParams,\n} from \"./app-page-boundary.js\";\nimport {\n createAppPageFontData,\n renderAppPageHtmlResponse,\n type AppPageSsrHandler,\n} from \"./app-page-stream.js\";\nimport { AppElementsWire, type AppElements } from \"./app-elements.js\";\nimport { createAppPageLayoutEntries } from \"./app-page-route-wiring.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AppPageComponent = ComponentType<any>;\ntype AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\ntype AppPageBoundaryOnError = (\n error: unknown,\n requestInfo: unknown,\n errorContext: unknown,\n) => unknown;\n\ntype AppPageBoundaryRscPayloadOptions<TModule extends AppPageModule = AppPageModule> = {\n element: ReactNode;\n layoutModules: readonly (TModule | null | undefined)[];\n pathname: string;\n route?: AppPageBoundaryRoute<TModule> | null;\n};\n\ntype AppPageBoundaryLayoutEntry = {\n id: string;\n treePath: string;\n};\n\nexport type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {\n error?: TModule | null;\n errorPaths?: readonly TModule[] | null;\n errors?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n layoutTreePositions?: readonly number[] | null;\n layouts?: readonly (TModule | null | undefined)[];\n notFound?: TModule | null;\n params?: AppPageParams;\n pattern?: string;\n routeSegments?: readonly string[];\n unauthorized?: TModule | null;\n};\n\ntype AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {\n buildFontLinkHeader: (preloads: readonly AppPageFontPreload[] | null | undefined) => string;\n clearRequestContext: () => void;\n createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;\n getFontLinks: () => string[];\n getFontPreloads: () => AppPageFontPreload[];\n getFontStyles: () => string[];\n getNavigationContext: () => unknown;\n globalErrorModule?: TModule | null;\n isRscRequest: boolean;\n loadSsrHandler: () => Promise<AppPageSsrHandler>;\n makeThenableParams: (params: AppPageParams) => unknown;\n middlewareContext: AppPageMiddlewareContext;\n metadataRoutes: MetadataFileRoute[];\n renderToReadableStream: (\n element: ReactNode | AppElements,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n requestUrl: string;\n resolveChildSegments: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => string[];\n rootLayouts: readonly (TModule | null | undefined)[];\n scriptNonce?: string;\n};\n\ntype RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {\n boundaryComponent?: AppPageComponent | null;\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n matchedParams: AppPageParams;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route?: AppPageBoundaryRoute<TModule> | null;\n statusCode: number;\n} & AppPageBoundaryRenderCommonOptions<TModule>;\n\ntype RenderAppPageErrorBoundaryOptions<TModule extends AppPageModule = AppPageModule> = {\n error: unknown;\n matchedParams?: AppPageParams | null;\n route?: AppPageBoundaryRoute<TModule> | null;\n sanitizeErrorForClient: (error: Error) => Error;\n} & AppPageBoundaryRenderCommonOptions<TModule>;\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction wrapRenderedBoundaryElement<TModule extends AppPageModule>(\n options: Pick<\n AppPageBoundaryRenderCommonOptions<TModule>,\n \"globalErrorModule\" | \"isRscRequest\" | \"makeThenableParams\" | \"resolveChildSegments\"\n > & {\n element: ReactNode;\n includeGlobalErrorBoundary: boolean;\n layoutModules: readonly (TModule | null | undefined)[];\n layoutTreePositions?: readonly number[] | null;\n matchedParams: AppPageParams;\n routeSegments?: readonly string[];\n skipLayoutWrapping?: boolean;\n },\n): ReactNode {\n return wrapAppPageBoundaryElement({\n element: options.element,\n getDefaultExport,\n globalErrorComponent: getDefaultExport(options.globalErrorModule),\n includeGlobalErrorBoundary: options.includeGlobalErrorBoundary,\n isRscRequest: options.isRscRequest,\n layoutModules: options.layoutModules,\n layoutTreePositions: options.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams: options.matchedParams,\n renderErrorBoundary(GlobalErrorComponent, children) {\n return createElement(ErrorBoundary, {\n fallback: GlobalErrorComponent,\n // oxlint-disable-next-line react/no-children-prop\n children,\n });\n },\n renderLayout(LayoutComponent, children, asyncParams) {\n return createElement(LayoutComponent as AppPageComponent, {\n // oxlint-disable-next-line react/no-children-prop\n children,\n params: asyncParams,\n });\n },\n renderLayoutSegmentProvider(segmentMap, children) {\n return createElement(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n LayoutSegmentProvider as ComponentType<any>,\n { segmentMap },\n children,\n );\n },\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.routeSegments ?? [],\n skipLayoutWrapping: options.skipLayoutWrapping,\n });\n}\n\nfunction createAppPageBoundaryLayoutEntries<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly AppPageBoundaryLayoutEntry[] {\n if (!route || layoutModules.length === 0) return [];\n\n return createAppPageLayoutEntries({\n errors: route.errors,\n layoutTreePositions: route.layoutTreePositions,\n layouts: layoutModules,\n notFounds: null,\n routeSegments: route.routeSegments,\n });\n}\n\nfunction resolveHttpAccessFallbackHeadRouteSegments<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly string[] | undefined {\n if (!route?.routeSegments) {\n return undefined;\n }\n\n if (!route.layouts || layoutModules.length >= route.layouts.length) {\n return route.routeSegments;\n }\n\n const lastIncludedLayoutIndex = layoutModules.length - 1;\n if (lastIncludedLayoutIndex < 0) {\n return [];\n }\n\n const segmentCount = route.layoutTreePositions?.[lastIncludedLayoutIndex] ?? 0;\n return route.routeSegments.slice(0, segmentCount);\n}\n\nfunction resolveHttpAccessFallbackHeadLayoutTreePositions<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly number[] | null | undefined {\n if (!route?.layouts || layoutModules.length >= route.layouts.length) {\n return route?.layoutTreePositions;\n }\n\n return route.layoutTreePositions?.slice(0, layoutModules.length);\n}\n\nfunction createAppPageBoundaryRscPayload<TModule extends AppPageModule>(\n options: AppPageBoundaryRscPayloadOptions<TModule>,\n): AppElements {\n const routeId = AppElementsWire.encodeRouteId(options.pathname, null);\n const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);\n\n return {\n ...AppElementsWire.createMetadataEntries({\n interceptionContext: null,\n layoutIds: layoutEntries.map((entry) => entry.id),\n rootLayoutTreePath: layoutEntries[0]?.treePath ?? null,\n routeId,\n }),\n [routeId]: options.element,\n };\n}\n\nasync function renderAppPageBoundaryElementResponse<TModule extends AppPageModule>(\n options: AppPageBoundaryRenderCommonOptions<TModule> & {\n element: ReactNode;\n layoutModules: readonly (TModule | null | undefined)[];\n route?: AppPageBoundaryRoute<TModule> | null;\n routePattern?: string;\n status: number;\n },\n): Promise<Response> {\n const pathname = new URL(options.requestUrl).pathname;\n const payload = createAppPageBoundaryRscPayload({\n element: options.element,\n layoutModules: options.layoutModules,\n pathname,\n route: options.route,\n });\n\n return renderAppPageBoundaryResponse({\n async createHtmlResponse(rscStream, responseStatus) {\n const fontData = createAppPageFontData({\n getLinks: options.getFontLinks,\n getPreloads: options.getFontPreloads,\n getStyles: options.getFontStyles,\n });\n const ssrHandler = await options.loadSsrHandler();\n return renderAppPageHtmlResponse({\n clearRequestContext: options.clearRequestContext,\n fontData,\n fontLinkHeader: options.buildFontLinkHeader(fontData.preloads),\n middlewareHeaders: options.middlewareContext.headers,\n navigationContext: options.getNavigationContext(),\n rscStream,\n scriptNonce: options.scriptNonce,\n ssrHandler,\n status: responseStatus,\n });\n },\n createRscOnErrorHandler() {\n return options.createRscOnErrorHandler(pathname, options.routePattern ?? pathname);\n },\n element: payload,\n isRscRequest: options.isRscRequest,\n middlewareHeaders: options.middlewareContext.headers,\n renderToReadableStream: options.renderToReadableStream,\n status: options.status,\n });\n}\n\nexport async function renderAppPageHttpAccessFallback<TModule extends AppPageModule>(\n options: RenderAppPageHttpAccessFallbackOptions<TModule>,\n): Promise<Response | null> {\n const boundaryComponent =\n options.boundaryComponent ??\n resolveAppPageHttpAccessBoundaryComponent({\n getDefaultExport,\n rootForbiddenModule: options.rootForbiddenModule,\n rootNotFoundModule: options.rootNotFoundModule,\n rootUnauthorizedModule: options.rootUnauthorizedModule,\n routeForbiddenModule: options.route?.forbidden,\n routeNotFoundModule: options.route?.notFound,\n routeUnauthorizedModule: options.route?.unauthorized,\n statusCode: options.statusCode,\n });\n if (!boundaryComponent) {\n return null;\n }\n\n const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;\n const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);\n const { metadata, viewport } = await resolveAppPageHead({\n layoutModules,\n layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(\n options.route,\n layoutModules,\n ),\n metadataRoutes: options.metadataRoutes,\n params: options.matchedParams,\n routePath: options.route?.pattern ?? new URL(options.requestUrl).pathname,\n routeSegments,\n });\n\n const headElements: ReactNode[] = [\n createElement(\"meta\", { charSet: \"utf-8\", key: \"charset\" }),\n createElement(\"meta\", { content: \"noindex\", key: \"robots\", name: \"robots\" }),\n ];\n if (metadata) {\n headElements.push(createElement(MetadataHead, { key: \"metadata\", metadata }));\n }\n headElements.push(createElement(ViewportHead, { key: \"viewport\", viewport }));\n\n const element = wrapRenderedBoundaryElement({\n element: createElement(Fragment, null, ...headElements, createElement(boundaryComponent)),\n globalErrorModule: options.globalErrorModule,\n includeGlobalErrorBoundary: true,\n isRscRequest: options.isRscRequest,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams: options.matchedParams,\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.route?.routeSegments,\n });\n\n return renderAppPageBoundaryElementResponse({\n ...options,\n element,\n layoutModules,\n route: options.route,\n routePattern: options.route?.pattern,\n status: options.statusCode,\n });\n}\n\nexport async function renderAppPageErrorBoundary<TModule extends AppPageModule>(\n options: RenderAppPageErrorBoundaryOptions<TModule>,\n): Promise<Response | null> {\n const errorBoundary = resolveAppPageErrorBoundary({\n getDefaultExport,\n errorModules: options.route?.errorPaths,\n globalErrorModule: options.globalErrorModule,\n layoutErrorModules: options.route?.errors,\n pageErrorModule: options.route?.error,\n });\n if (!errorBoundary.component) {\n return null;\n }\n\n const rawError =\n options.error instanceof Error ? options.error : new Error(String(options.error));\n rewriteClientHookError(rawError);\n const errorObject = options.sanitizeErrorForClient(rawError);\n const matchedParams = options.matchedParams ?? options.route?.params ?? {};\n const layoutModules = options.route?.layouts ?? options.rootLayouts;\n const pathname = new URL(options.requestUrl).pathname;\n\n const headElements: ReactNode[] = [createElement(\"meta\", { charSet: \"utf-8\", key: \"charset\" })];\n if (!errorBoundary.isGlobalError) {\n try {\n const { metadata, viewport } = await resolveAppPageHead({\n fallbackOnFileMetadataError: true,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n metadataRoutes: options.metadataRoutes,\n params: matchedParams,\n routePath: options.route?.pattern ?? pathname,\n routeSegments: options.route?.routeSegments,\n });\n if (metadata) {\n headElements.push(createElement(MetadataHead, { key: \"metadata\", metadata }));\n }\n headElements.push(createElement(ViewportHead, { key: \"viewport\", viewport }));\n } catch (error) {\n console.error(\n `[vinext] App page error boundary head resolution failed for ${options.route?.pattern ?? pathname}:`,\n error,\n );\n }\n }\n\n const element = wrapRenderedBoundaryElement({\n element: createElement(\n Fragment,\n null,\n ...headElements,\n createElement(errorBoundary.component, {\n error: errorObject,\n }),\n ),\n globalErrorModule: options.globalErrorModule,\n includeGlobalErrorBoundary: !errorBoundary.isGlobalError,\n isRscRequest: options.isRscRequest,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams,\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.route?.routeSegments,\n skipLayoutWrapping: errorBoundary.isGlobalError,\n });\n\n return renderAppPageBoundaryElementResponse({\n ...options,\n element,\n layoutModules,\n route: options.route,\n routePattern: options.route?.pattern,\n status: 200,\n });\n}\n\n// React client-only hooks that are absent from the `react-server` export\n// condition. When called in a Server Component they produce a TypeError like\n// \"useState is not a function\". Rewrite into an actionable message matching\n// the format used by the next/navigation shims (see client-hook-error.ts).\nconst _clientHookPattern =\n /\\b(useState|useEffect|useReducer|useRef|useContext|useLayoutEffect|useInsertionEffect|useSyncExternalStore|useTransition|useImperativeHandle|useDeferredValue|useActionState|useOptimistic|useEffectEvent)\\b.*is not a function/;\n\nfunction rewriteClientHookError(error: Error): void {\n const match = error.message.match(_clientHookPattern);\n if (match) {\n error.message = buildClientHookErrorMessage(`${match[1]}()`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-page-boundary-render.js","names":[],"sources":["../../src/server/app-page-boundary-render.ts"],"sourcesContent":["import { Fragment, createElement, type ComponentType, type ReactNode } from \"react\";\nimport { buildClientHookErrorMessage } from \"vinext/shims/client-hook-error\";\nimport { ErrorBoundary } from \"vinext/shims/error-boundary\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport { MetadataHead, ViewportHead } from \"vinext/shims/metadata\";\nimport type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { AppPageMiddlewareContext } from \"./app-page-response.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\nimport { resolveAppPageHead } from \"./app-page-head.js\";\nimport {\n renderAppPageBoundaryResponse,\n resolveAppPageErrorBoundary,\n resolveAppPageHttpAccessBoundaryComponent,\n wrapAppPageBoundaryElement,\n type AppPageParams,\n} from \"./app-page-boundary.js\";\nimport {\n createAppPageFontData,\n renderAppPageHtmlResponse,\n type AppPageSsrHandler,\n} from \"./app-page-stream.js\";\nimport { AppElementsWire, type AppElements } from \"./app-elements.js\";\nimport { createAppPageLayoutEntries } from \"./app-page-route-wiring.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AppPageComponent = ComponentType<any>;\ntype AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\ntype AppPageBoundaryOnError = (\n error: unknown,\n requestInfo: unknown,\n errorContext: unknown,\n) => unknown;\n\ntype AppPageBoundaryRscPayloadOptions<TModule extends AppPageModule = AppPageModule> = {\n element: ReactNode;\n layoutModules: readonly (TModule | null | undefined)[];\n pathname: string;\n route?: AppPageBoundaryRoute<TModule> | null;\n};\n\ntype AppPageBoundaryLayoutEntry = {\n id: string;\n treePath: string;\n};\n\nexport type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {\n error?: TModule | null;\n errorPaths?: readonly TModule[] | null;\n errors?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n layoutTreePositions?: readonly number[] | null;\n layouts?: readonly (TModule | null | undefined)[];\n notFound?: TModule | null;\n params?: AppPageParams;\n pattern?: string;\n routeSegments?: readonly string[];\n unauthorized?: TModule | null;\n};\n\ntype AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageModule> = {\n buildFontLinkHeader: (preloads: readonly AppPageFontPreload[] | null | undefined) => string;\n clearRequestContext: () => void;\n createRscOnErrorHandler: (pathname: string, routePath: string) => AppPageBoundaryOnError;\n getFontLinks: () => string[];\n getFontPreloads: () => AppPageFontPreload[];\n getFontStyles: () => string[];\n getNavigationContext: () => unknown;\n globalErrorModule?: TModule | null;\n isRscRequest: boolean;\n loadSsrHandler: () => Promise<AppPageSsrHandler>;\n makeThenableParams: (params: AppPageParams) => unknown;\n middlewareContext: AppPageMiddlewareContext;\n metadataRoutes: MetadataFileRoute[];\n /** Configured next.config `basePath`, threaded into file-based metadata href emission. */\n basePath?: string;\n renderToReadableStream: (\n element: ReactNode | AppElements,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n requestUrl: string;\n resolveChildSegments: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => string[];\n rootLayouts: readonly (TModule | null | undefined)[];\n scriptNonce?: string;\n};\n\ntype RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {\n boundaryComponent?: AppPageComponent | null;\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n matchedParams: AppPageParams;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route?: AppPageBoundaryRoute<TModule> | null;\n /**\n * When true, the resolved boundary is rendered without wrapping it in the\n * route's layouts. Used by `global-not-found.tsx`, which provides its own\n * `<html>`/`<body>` and intentionally replaces the root layout.\n * Mirrors Next.js's `createNotFoundLoaderTree` behavior for `hasGlobalNotFound`.\n * @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/app-render.tsx#L495-L520\n */\n skipLayoutWrapping?: boolean;\n statusCode: number;\n} & AppPageBoundaryRenderCommonOptions<TModule>;\n\ntype RenderAppPageErrorBoundaryOptions<TModule extends AppPageModule = AppPageModule> = {\n error: unknown;\n matchedParams?: AppPageParams | null;\n route?: AppPageBoundaryRoute<TModule> | null;\n sanitizeErrorForClient: (error: Error) => Error;\n} & AppPageBoundaryRenderCommonOptions<TModule>;\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction wrapRenderedBoundaryElement<TModule extends AppPageModule>(\n options: Pick<\n AppPageBoundaryRenderCommonOptions<TModule>,\n \"globalErrorModule\" | \"isRscRequest\" | \"makeThenableParams\" | \"resolveChildSegments\"\n > & {\n element: ReactNode;\n includeGlobalErrorBoundary: boolean;\n layoutModules: readonly (TModule | null | undefined)[];\n layoutTreePositions?: readonly number[] | null;\n matchedParams: AppPageParams;\n routeSegments?: readonly string[];\n skipLayoutWrapping?: boolean;\n },\n): ReactNode {\n return wrapAppPageBoundaryElement({\n element: options.element,\n getDefaultExport,\n globalErrorComponent: getDefaultExport(options.globalErrorModule),\n includeGlobalErrorBoundary: options.includeGlobalErrorBoundary,\n isRscRequest: options.isRscRequest,\n layoutModules: options.layoutModules,\n layoutTreePositions: options.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams: options.matchedParams,\n renderErrorBoundary(GlobalErrorComponent, children) {\n return createElement(ErrorBoundary, {\n fallback: GlobalErrorComponent,\n // oxlint-disable-next-line react/no-children-prop\n children,\n });\n },\n renderLayout(LayoutComponent, children, asyncParams) {\n return createElement(LayoutComponent as AppPageComponent, {\n // oxlint-disable-next-line react/no-children-prop\n children,\n params: asyncParams,\n });\n },\n renderLayoutSegmentProvider(segmentMap, children) {\n return createElement(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n LayoutSegmentProvider as ComponentType<any>,\n { segmentMap },\n children,\n );\n },\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.routeSegments ?? [],\n skipLayoutWrapping: options.skipLayoutWrapping,\n });\n}\n\nfunction createAppPageBoundaryLayoutEntries<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly AppPageBoundaryLayoutEntry[] {\n if (!route || layoutModules.length === 0) return [];\n\n return createAppPageLayoutEntries({\n errors: route.errors,\n layoutTreePositions: route.layoutTreePositions,\n layouts: layoutModules,\n notFounds: null,\n routeSegments: route.routeSegments,\n });\n}\n\nfunction resolveHttpAccessFallbackHeadRouteSegments<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly string[] | undefined {\n if (!route?.routeSegments) {\n return undefined;\n }\n\n if (!route.layouts || layoutModules.length >= route.layouts.length) {\n return route.routeSegments;\n }\n\n const lastIncludedLayoutIndex = layoutModules.length - 1;\n if (lastIncludedLayoutIndex < 0) {\n return [];\n }\n\n const segmentCount = route.layoutTreePositions?.[lastIncludedLayoutIndex] ?? 0;\n return route.routeSegments.slice(0, segmentCount);\n}\n\nfunction resolveHttpAccessFallbackHeadLayoutTreePositions<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n layoutModules: readonly (TModule | null | undefined)[],\n): readonly number[] | null | undefined {\n if (!route?.layouts || layoutModules.length >= route.layouts.length) {\n return route?.layoutTreePositions;\n }\n\n return route.layoutTreePositions?.slice(0, layoutModules.length);\n}\n\nfunction createAppPageBoundaryRscPayload<TModule extends AppPageModule>(\n options: AppPageBoundaryRscPayloadOptions<TModule>,\n): AppElements {\n const routeId = AppElementsWire.encodeRouteId(options.pathname, null);\n const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);\n\n return {\n ...AppElementsWire.createMetadataEntries({\n interceptionContext: null,\n layoutIds: layoutEntries.map((entry) => entry.id),\n rootLayoutTreePath: layoutEntries[0]?.treePath ?? null,\n routeId,\n }),\n [routeId]: options.element,\n };\n}\n\nasync function renderAppPageBoundaryElementResponse<TModule extends AppPageModule>(\n options: AppPageBoundaryRenderCommonOptions<TModule> & {\n element: ReactNode;\n layoutModules: readonly (TModule | null | undefined)[];\n route?: AppPageBoundaryRoute<TModule> | null;\n routePattern?: string;\n status: number;\n },\n): Promise<Response> {\n const pathname = new URL(options.requestUrl).pathname;\n const payload = createAppPageBoundaryRscPayload({\n element: options.element,\n layoutModules: options.layoutModules,\n pathname,\n route: options.route,\n });\n\n return renderAppPageBoundaryResponse({\n async createHtmlResponse(rscStream, responseStatus) {\n const fontData = createAppPageFontData({\n getLinks: options.getFontLinks,\n getPreloads: options.getFontPreloads,\n getStyles: options.getFontStyles,\n });\n const ssrHandler = await options.loadSsrHandler();\n return renderAppPageHtmlResponse({\n clearRequestContext: options.clearRequestContext,\n fontData,\n fontLinkHeader: options.buildFontLinkHeader(fontData.preloads),\n middlewareHeaders: options.middlewareContext.headers,\n navigationContext: options.getNavigationContext(),\n rscStream,\n scriptNonce: options.scriptNonce,\n ssrHandler,\n status: responseStatus,\n });\n },\n createRscOnErrorHandler() {\n return options.createRscOnErrorHandler(pathname, options.routePattern ?? pathname);\n },\n element: payload,\n isRscRequest: options.isRscRequest,\n middlewareHeaders: options.middlewareContext.headers,\n renderToReadableStream: options.renderToReadableStream,\n status: options.status,\n });\n}\n\nexport async function renderAppPageHttpAccessFallback<TModule extends AppPageModule>(\n options: RenderAppPageHttpAccessFallbackOptions<TModule>,\n): Promise<Response | null> {\n const boundaryComponent =\n options.boundaryComponent ??\n resolveAppPageHttpAccessBoundaryComponent({\n getDefaultExport,\n rootForbiddenModule: options.rootForbiddenModule,\n rootNotFoundModule: options.rootNotFoundModule,\n rootUnauthorizedModule: options.rootUnauthorizedModule,\n routeForbiddenModule: options.route?.forbidden,\n routeNotFoundModule: options.route?.notFound,\n routeUnauthorizedModule: options.route?.unauthorized,\n statusCode: options.statusCode,\n });\n if (!boundaryComponent) {\n return null;\n }\n\n const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;\n const pathname = new URL(options.requestUrl).pathname;\n const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);\n const { metadata, viewport } = await resolveAppPageHead({\n basePath: options.basePath ?? \"\",\n layoutModules,\n layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(\n options.route,\n layoutModules,\n ),\n metadataRoutes: options.metadataRoutes,\n params: options.matchedParams,\n routePath: options.route?.pattern ?? pathname,\n routeSegments,\n });\n\n const headElements: ReactNode[] = [\n createElement(\"meta\", { charSet: \"utf-8\", key: \"charset\" }),\n createElement(\"meta\", { content: \"noindex\", key: \"robots\", name: \"robots\" }),\n ];\n if (metadata) {\n headElements.push(createElement(MetadataHead, { key: \"metadata\", metadata, pathname }));\n }\n headElements.push(createElement(ViewportHead, { key: \"viewport\", viewport }));\n\n const skipLayoutWrapping = options.skipLayoutWrapping ?? false;\n const element = wrapRenderedBoundaryElement({\n element: createElement(Fragment, null, ...headElements, createElement(boundaryComponent)),\n globalErrorModule: options.globalErrorModule,\n includeGlobalErrorBoundary: true,\n isRscRequest: options.isRscRequest,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams: options.matchedParams,\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.route?.routeSegments,\n skipLayoutWrapping,\n });\n\n return renderAppPageBoundaryElementResponse({\n ...options,\n // When global-not-found owns the document, no layouts should contribute to\n // the RSC payload's layout entries either — otherwise the SSR pipeline\n // would expect a root-layout tree path that doesn't exist in the markup.\n element,\n layoutModules: skipLayoutWrapping ? [] : layoutModules,\n route: skipLayoutWrapping ? null : options.route,\n routePattern: options.route?.pattern,\n status: options.statusCode,\n });\n}\n\nexport async function renderAppPageErrorBoundary<TModule extends AppPageModule>(\n options: RenderAppPageErrorBoundaryOptions<TModule>,\n): Promise<Response | null> {\n const errorBoundary = resolveAppPageErrorBoundary({\n getDefaultExport,\n errorModules: options.route?.errorPaths,\n globalErrorModule: options.globalErrorModule,\n layoutErrorModules: options.route?.errors,\n pageErrorModule: options.route?.error,\n });\n if (!errorBoundary.component) {\n return null;\n }\n\n const rawError =\n options.error instanceof Error ? options.error : new Error(String(options.error));\n rewriteClientHookError(rawError);\n const errorObject = options.sanitizeErrorForClient(rawError);\n const matchedParams = options.matchedParams ?? options.route?.params ?? {};\n const layoutModules = options.route?.layouts ?? options.rootLayouts;\n const pathname = new URL(options.requestUrl).pathname;\n\n const headElements: ReactNode[] = [createElement(\"meta\", { charSet: \"utf-8\", key: \"charset\" })];\n if (!errorBoundary.isGlobalError) {\n try {\n const { metadata, viewport } = await resolveAppPageHead({\n basePath: options.basePath ?? \"\",\n fallbackOnFileMetadataError: true,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n metadataRoutes: options.metadataRoutes,\n params: matchedParams,\n routePath: options.route?.pattern ?? pathname,\n routeSegments: options.route?.routeSegments,\n });\n if (metadata) {\n headElements.push(createElement(MetadataHead, { key: \"metadata\", metadata, pathname }));\n }\n headElements.push(createElement(ViewportHead, { key: \"viewport\", viewport }));\n } catch (error) {\n console.error(\n `[vinext] App page error boundary head resolution failed for ${options.route?.pattern ?? pathname}:`,\n error,\n );\n }\n }\n\n const element = wrapRenderedBoundaryElement({\n element: createElement(\n Fragment,\n null,\n ...headElements,\n createElement(errorBoundary.component, {\n error: errorObject,\n }),\n ),\n globalErrorModule: options.globalErrorModule,\n includeGlobalErrorBoundary: !errorBoundary.isGlobalError,\n isRscRequest: options.isRscRequest,\n layoutModules,\n layoutTreePositions: options.route?.layoutTreePositions,\n makeThenableParams: options.makeThenableParams,\n matchedParams,\n resolveChildSegments: options.resolveChildSegments,\n routeSegments: options.route?.routeSegments,\n skipLayoutWrapping: errorBoundary.isGlobalError,\n });\n\n return renderAppPageBoundaryElementResponse({\n ...options,\n element,\n layoutModules,\n route: options.route,\n routePattern: options.route?.pattern,\n status: 200,\n });\n}\n\n// React client-only hooks that are absent from the `react-server` export\n// condition. When called in a Server Component they produce a TypeError like\n// \"useState is not a function\". Rewrite into an actionable message matching\n// the format used by the next/navigation shims (see client-hook-error.ts).\nconst _clientHookPattern =\n /\\b(useState|useEffect|useReducer|useRef|useContext|useLayoutEffect|useInsertionEffect|useSyncExternalStore|useTransition|useImperativeHandle|useDeferredValue|useActionState|useOptimistic|useEffectEvent)\\b.*is not a function/;\n\nfunction rewriteClientHookError(error: Error): void {\n const match = error.message.match(_clientHookPattern);\n if (match) {\n error.message = buildClientHookErrorMessage(`${match[1]}()`);\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { runWithFetchDedupe } from "../shims/fetch-cache.js";
2
- import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
2
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
3
3
  import { resolveAppPageSegmentParams } from "./app-page-params.js";
4
4
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
5
5
  //#region src/server/app-page-boundary.ts
@@ -66,10 +66,11 @@ async function renderAppPageBoundaryResponse(options) {
66
66
  const rscStream = runWithFetchDedupe(() => options.renderToReadableStream(options.element, { onError: options.createRscOnErrorHandler() }));
67
67
  if (options.isRscRequest) {
68
68
  const headers = new Headers({
69
- "Content-Type": "text/x-component; charset=utf-8",
69
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
70
70
  Vary: VINEXT_RSC_VARY_HEADER
71
71
  });
72
72
  mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
73
+ applyRscCompatibilityIdHeader(headers);
73
74
  return new Response(rscStream, {
74
75
  status: options.status,
75
76
  headers
@@ -1 +1 @@
1
- {"version":3,"file":"app-page-boundary.js","names":[],"sources":["../../src/server/app-page-boundary.ts"],"sourcesContent":["import { runWithFetchDedupe } from \"vinext/shims/fetch-cache\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport { VINEXT_RSC_VARY_HEADER } from \"./app-rsc-cache-busting.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\n\nexport type AppPageParams = Record<string, string | string[]>;\n\ntype ResolveAppPageHttpAccessBoundaryComponentOptions<TModule, TComponent> = {\n getDefaultExport: (module: TModule | null | undefined) => TComponent | null | undefined;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n routeForbiddenModule?: TModule | null;\n routeNotFoundModule?: TModule | null;\n routeUnauthorizedModule?: TModule | null;\n statusCode: number;\n};\n\ntype ResolveAppPageParentHttpAccessBoundaryModuleOptions<TModule> = {\n layoutIndex: number;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n routeForbiddenModules?: readonly (TModule | null | undefined)[] | null;\n routeNotFoundModules?: readonly (TModule | null | undefined)[] | null;\n routeUnauthorizedModules?: readonly (TModule | null | undefined)[] | null;\n statusCode: number;\n};\n\ntype ResolveAppPageErrorBoundaryOptions<TModule, TComponent> = {\n getDefaultExport: (module: TModule | null | undefined) => TComponent | null | undefined;\n globalErrorModule?: TModule | null;\n errorModules?: readonly (TModule | null | undefined)[] | null;\n layoutErrorModules?: readonly (TModule | null | undefined)[] | null;\n pageErrorModule?: TModule | null;\n};\n\ntype ResolveAppPageErrorBoundaryResult<TComponent> = {\n component: TComponent | null;\n isGlobalError: boolean;\n};\n\ntype WrapAppPageBoundaryElementOptions<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent,\n> = {\n element: TElement;\n getDefaultExport: (\n module: TLayoutModule | null | undefined,\n ) => TLayoutComponent | null | undefined;\n globalErrorComponent?: TGlobalErrorComponent | null;\n includeGlobalErrorBoundary: boolean;\n isRscRequest: boolean;\n layoutModules: readonly (TLayoutModule | null | undefined)[];\n layoutTreePositions?: readonly number[] | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n renderErrorBoundary: (component: TGlobalErrorComponent, children: TElement) => TElement;\n renderLayout: (component: TLayoutComponent, children: TElement, params: unknown) => TElement;\n renderLayoutSegmentProvider?: (\n segmentMap: { children: TChildSegments },\n children: TElement,\n ) => TElement;\n resolveChildSegments?: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => TChildSegments;\n routeSegments?: readonly string[];\n skipLayoutWrapping?: boolean;\n};\n\ntype AppPageBoundaryOnError = (\n error: unknown,\n requestInfo: unknown,\n errorContext: unknown,\n) => unknown;\n\ntype RenderAppPageBoundaryResponseOptions<TElement> = {\n createHtmlResponse: (rscStream: ReadableStream<Uint8Array>, status: number) => Promise<Response>;\n createRscOnErrorHandler: () => AppPageBoundaryOnError;\n element: TElement;\n isRscRequest: boolean;\n middlewareHeaders?: Headers | null;\n renderToReadableStream: (\n element: TElement,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n status: number;\n};\n\nexport function resolveAppPageHttpAccessBoundaryComponent<TModule, TComponent>(\n options: ResolveAppPageHttpAccessBoundaryComponentOptions<TModule, TComponent>,\n): TComponent | null {\n let boundaryModule: TModule | null | undefined;\n\n if (options.statusCode === 403) {\n boundaryModule = options.routeForbiddenModule ?? options.rootForbiddenModule;\n } else if (options.statusCode === 401) {\n boundaryModule = options.routeUnauthorizedModule ?? options.rootUnauthorizedModule;\n } else {\n boundaryModule = options.routeNotFoundModule ?? options.rootNotFoundModule;\n }\n\n return options.getDefaultExport(boundaryModule) ?? null;\n}\n\nexport function resolveAppPageParentHttpAccessBoundaryModule<TModule>(\n options: ResolveAppPageParentHttpAccessBoundaryModuleOptions<TModule>,\n): TModule | null {\n let routeModules = options.routeNotFoundModules;\n let rootModule = options.rootNotFoundModule;\n\n if (options.statusCode === 403) {\n routeModules = options.routeForbiddenModules;\n rootModule = options.rootForbiddenModule;\n } else if (options.statusCode === 401) {\n routeModules = options.routeUnauthorizedModules;\n rootModule = options.rootUnauthorizedModule;\n }\n\n if (routeModules) {\n for (let index = options.layoutIndex - 1; index >= 0; index--) {\n const module = routeModules[index];\n if (module) {\n return module;\n }\n }\n }\n\n return rootModule ?? null;\n}\n\nexport function resolveAppPageErrorBoundary<TModule, TComponent>(\n options: ResolveAppPageErrorBoundaryOptions<TModule, TComponent>,\n): ResolveAppPageErrorBoundaryResult<TComponent> {\n const pageErrorComponent = options.getDefaultExport(options.pageErrorModule);\n if (pageErrorComponent) {\n return {\n component: pageErrorComponent,\n isGlobalError: false,\n };\n }\n\n const segmentErrorModules = options.errorModules ?? options.layoutErrorModules;\n if (segmentErrorModules) {\n for (let index = segmentErrorModules.length - 1; index >= 0; index--) {\n const segmentErrorComponent = options.getDefaultExport(segmentErrorModules[index]);\n if (segmentErrorComponent) {\n return {\n component: segmentErrorComponent,\n isGlobalError: false,\n };\n }\n }\n }\n\n const globalErrorComponent = options.getDefaultExport(options.globalErrorModule);\n return {\n component: globalErrorComponent ?? null,\n isGlobalError: Boolean(globalErrorComponent),\n };\n}\n\nexport function wrapAppPageBoundaryElement<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent,\n>(\n options: WrapAppPageBoundaryElementOptions<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent\n >,\n): TElement {\n let element = options.element;\n\n if (!options.skipLayoutWrapping) {\n for (let index = options.layoutModules.length - 1; index >= 0; index--) {\n const layoutComponent = options.getDefaultExport(options.layoutModules[index]);\n if (!layoutComponent) {\n continue;\n }\n\n const treePosition = options.layoutTreePositions ? options.layoutTreePositions[index] : 0;\n const asyncParams = options.makeThenableParams(\n resolveAppPageSegmentParams(options.routeSegments, treePosition, options.matchedParams),\n );\n element = options.renderLayout(layoutComponent, element, asyncParams);\n\n if (\n options.isRscRequest &&\n options.renderLayoutSegmentProvider &&\n options.resolveChildSegments\n ) {\n const childSegments = options.resolveChildSegments(\n options.routeSegments ?? [],\n treePosition,\n options.matchedParams,\n );\n element = options.renderLayoutSegmentProvider({ children: childSegments }, element);\n }\n }\n }\n\n if (options.isRscRequest && options.includeGlobalErrorBoundary && options.globalErrorComponent) {\n element = options.renderErrorBoundary(options.globalErrorComponent, element);\n }\n\n return element;\n}\n\nexport async function renderAppPageBoundaryResponse<TElement>(\n options: RenderAppPageBoundaryResponseOptions<TElement>,\n): Promise<Response> {\n // Defensive wrap for standalone callers; idempotent under dispatchAppPage.\n // The async stream consumption that follows relies on the surrounding\n // runWithRequestContext to keep ALS state alive after this synchronous call\n // returns. See app-page-render.ts for the same pattern.\n const rscStream = runWithFetchDedupe(() =>\n options.renderToReadableStream(options.element, {\n onError: options.createRscOnErrorHandler(),\n }),\n );\n\n if (options.isRscRequest) {\n // Do NOT clear request-scoped context here. RSC responses are consumed lazily\n // by the client, so headers()/cookies() and async server components still need\n // their ALS-backed state while the stream is being read.\n const headers = new Headers({\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n Vary: VINEXT_RSC_VARY_HEADER,\n });\n mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);\n\n return new Response(rscStream, {\n status: options.status,\n headers,\n });\n }\n\n return options.createHtmlResponse(rscStream, options.status);\n}\n"],"mappings":";;;;;AA8FA,SAAgB,0CACd,SACmB;CACnB,IAAI;CAEJ,IAAI,QAAQ,eAAe,KACzB,iBAAiB,QAAQ,wBAAwB,QAAQ;MACpD,IAAI,QAAQ,eAAe,KAChC,iBAAiB,QAAQ,2BAA2B,QAAQ;MAE5D,iBAAiB,QAAQ,uBAAuB,QAAQ;CAG1D,OAAO,QAAQ,iBAAiB,eAAe,IAAI;;AAGrD,SAAgB,6CACd,SACgB;CAChB,IAAI,eAAe,QAAQ;CAC3B,IAAI,aAAa,QAAQ;CAEzB,IAAI,QAAQ,eAAe,KAAK;EAC9B,eAAe,QAAQ;EACvB,aAAa,QAAQ;QAChB,IAAI,QAAQ,eAAe,KAAK;EACrC,eAAe,QAAQ;EACvB,aAAa,QAAQ;;CAGvB,IAAI,cACF,KAAK,IAAI,QAAQ,QAAQ,cAAc,GAAG,SAAS,GAAG,SAAS;EAC7D,MAAM,SAAS,aAAa;EAC5B,IAAI,QACF,OAAO;;CAKb,OAAO,cAAc;;AAGvB,SAAgB,4BACd,SAC+C;CAC/C,MAAM,qBAAqB,QAAQ,iBAAiB,QAAQ,gBAAgB;CAC5E,IAAI,oBACF,OAAO;EACL,WAAW;EACX,eAAe;EAChB;CAGH,MAAM,sBAAsB,QAAQ,gBAAgB,QAAQ;CAC5D,IAAI,qBACF,KAAK,IAAI,QAAQ,oBAAoB,SAAS,GAAG,SAAS,GAAG,SAAS;EACpE,MAAM,wBAAwB,QAAQ,iBAAiB,oBAAoB,OAAO;EAClF,IAAI,uBACF,OAAO;GACL,WAAW;GACX,eAAe;GAChB;;CAKP,MAAM,uBAAuB,QAAQ,iBAAiB,QAAQ,kBAAkB;CAChF,OAAO;EACL,WAAW,wBAAwB;EACnC,eAAe,QAAQ,qBAAqB;EAC7C;;AAGH,SAAgB,2BAOd,SAOU;CACV,IAAI,UAAU,QAAQ;CAEtB,IAAI,CAAC,QAAQ,oBACX,KAAK,IAAI,QAAQ,QAAQ,cAAc,SAAS,GAAG,SAAS,GAAG,SAAS;EACtE,MAAM,kBAAkB,QAAQ,iBAAiB,QAAQ,cAAc,OAAO;EAC9E,IAAI,CAAC,iBACH;EAGF,MAAM,eAAe,QAAQ,sBAAsB,QAAQ,oBAAoB,SAAS;EACxF,MAAM,cAAc,QAAQ,mBAC1B,4BAA4B,QAAQ,eAAe,cAAc,QAAQ,cAAc,CACxF;EACD,UAAU,QAAQ,aAAa,iBAAiB,SAAS,YAAY;EAErE,IACE,QAAQ,gBACR,QAAQ,+BACR,QAAQ,sBACR;GACA,MAAM,gBAAgB,QAAQ,qBAC5B,QAAQ,iBAAiB,EAAE,EAC3B,cACA,QAAQ,cACT;GACD,UAAU,QAAQ,4BAA4B,EAAE,UAAU,eAAe,EAAE,QAAQ;;;CAKzF,IAAI,QAAQ,gBAAgB,QAAQ,8BAA8B,QAAQ,sBACxE,UAAU,QAAQ,oBAAoB,QAAQ,sBAAsB,QAAQ;CAG9E,OAAO;;AAGT,eAAsB,8BACpB,SACmB;CAKnB,MAAM,YAAY,yBAChB,QAAQ,uBAAuB,QAAQ,SAAS,EAC9C,SAAS,QAAQ,yBAAyB,EAC3C,CAAC,CACH;CAED,IAAI,QAAQ,cAAc;EAIxB,MAAM,UAAU,IAAI,QAAQ;GAC1B,gBAAgB;GAChB,MAAM;GACP,CAAC;EACF,+BAA+B,SAAS,QAAQ,qBAAqB,KAAK;EAE1E,OAAO,IAAI,SAAS,WAAW;GAC7B,QAAQ,QAAQ;GAChB;GACD,CAAC;;CAGJ,OAAO,QAAQ,mBAAmB,WAAW,QAAQ,OAAO"}
1
+ {"version":3,"file":"app-page-boundary.js","names":[],"sources":["../../src/server/app-page-boundary.ts"],"sourcesContent":["import { runWithFetchDedupe } from \"vinext/shims/fetch-cache\";\nimport { mergeMiddlewareResponseHeaders } from \"./middleware-response-headers.js\";\nimport {\n VINEXT_RSC_CONTENT_TYPE,\n VINEXT_RSC_VARY_HEADER,\n applyRscCompatibilityIdHeader,\n} from \"./app-rsc-cache-busting.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\n\nexport type AppPageParams = Record<string, string | string[]>;\n\ntype ResolveAppPageHttpAccessBoundaryComponentOptions<TModule, TComponent> = {\n getDefaultExport: (module: TModule | null | undefined) => TComponent | null | undefined;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n routeForbiddenModule?: TModule | null;\n routeNotFoundModule?: TModule | null;\n routeUnauthorizedModule?: TModule | null;\n statusCode: number;\n};\n\ntype ResolveAppPageParentHttpAccessBoundaryModuleOptions<TModule> = {\n layoutIndex: number;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n routeForbiddenModules?: readonly (TModule | null | undefined)[] | null;\n routeNotFoundModules?: readonly (TModule | null | undefined)[] | null;\n routeUnauthorizedModules?: readonly (TModule | null | undefined)[] | null;\n statusCode: number;\n};\n\ntype ResolveAppPageErrorBoundaryOptions<TModule, TComponent> = {\n getDefaultExport: (module: TModule | null | undefined) => TComponent | null | undefined;\n globalErrorModule?: TModule | null;\n errorModules?: readonly (TModule | null | undefined)[] | null;\n layoutErrorModules?: readonly (TModule | null | undefined)[] | null;\n pageErrorModule?: TModule | null;\n};\n\ntype ResolveAppPageErrorBoundaryResult<TComponent> = {\n component: TComponent | null;\n isGlobalError: boolean;\n};\n\ntype WrapAppPageBoundaryElementOptions<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent,\n> = {\n element: TElement;\n getDefaultExport: (\n module: TLayoutModule | null | undefined,\n ) => TLayoutComponent | null | undefined;\n globalErrorComponent?: TGlobalErrorComponent | null;\n includeGlobalErrorBoundary: boolean;\n isRscRequest: boolean;\n layoutModules: readonly (TLayoutModule | null | undefined)[];\n layoutTreePositions?: readonly number[] | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n renderErrorBoundary: (component: TGlobalErrorComponent, children: TElement) => TElement;\n renderLayout: (component: TLayoutComponent, children: TElement, params: unknown) => TElement;\n renderLayoutSegmentProvider?: (\n segmentMap: { children: TChildSegments },\n children: TElement,\n ) => TElement;\n resolveChildSegments?: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => TChildSegments;\n routeSegments?: readonly string[];\n skipLayoutWrapping?: boolean;\n};\n\ntype AppPageBoundaryOnError = (\n error: unknown,\n requestInfo: unknown,\n errorContext: unknown,\n) => unknown;\n\ntype RenderAppPageBoundaryResponseOptions<TElement> = {\n createHtmlResponse: (rscStream: ReadableStream<Uint8Array>, status: number) => Promise<Response>;\n createRscOnErrorHandler: () => AppPageBoundaryOnError;\n element: TElement;\n isRscRequest: boolean;\n middlewareHeaders?: Headers | null;\n renderToReadableStream: (\n element: TElement,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n status: number;\n};\n\nexport function resolveAppPageHttpAccessBoundaryComponent<TModule, TComponent>(\n options: ResolveAppPageHttpAccessBoundaryComponentOptions<TModule, TComponent>,\n): TComponent | null {\n let boundaryModule: TModule | null | undefined;\n\n if (options.statusCode === 403) {\n boundaryModule = options.routeForbiddenModule ?? options.rootForbiddenModule;\n } else if (options.statusCode === 401) {\n boundaryModule = options.routeUnauthorizedModule ?? options.rootUnauthorizedModule;\n } else {\n boundaryModule = options.routeNotFoundModule ?? options.rootNotFoundModule;\n }\n\n return options.getDefaultExport(boundaryModule) ?? null;\n}\n\nexport function resolveAppPageParentHttpAccessBoundaryModule<TModule>(\n options: ResolveAppPageParentHttpAccessBoundaryModuleOptions<TModule>,\n): TModule | null {\n let routeModules = options.routeNotFoundModules;\n let rootModule = options.rootNotFoundModule;\n\n if (options.statusCode === 403) {\n routeModules = options.routeForbiddenModules;\n rootModule = options.rootForbiddenModule;\n } else if (options.statusCode === 401) {\n routeModules = options.routeUnauthorizedModules;\n rootModule = options.rootUnauthorizedModule;\n }\n\n if (routeModules) {\n for (let index = options.layoutIndex - 1; index >= 0; index--) {\n const module = routeModules[index];\n if (module) {\n return module;\n }\n }\n }\n\n return rootModule ?? null;\n}\n\nexport function resolveAppPageErrorBoundary<TModule, TComponent>(\n options: ResolveAppPageErrorBoundaryOptions<TModule, TComponent>,\n): ResolveAppPageErrorBoundaryResult<TComponent> {\n const pageErrorComponent = options.getDefaultExport(options.pageErrorModule);\n if (pageErrorComponent) {\n return {\n component: pageErrorComponent,\n isGlobalError: false,\n };\n }\n\n const segmentErrorModules = options.errorModules ?? options.layoutErrorModules;\n if (segmentErrorModules) {\n for (let index = segmentErrorModules.length - 1; index >= 0; index--) {\n const segmentErrorComponent = options.getDefaultExport(segmentErrorModules[index]);\n if (segmentErrorComponent) {\n return {\n component: segmentErrorComponent,\n isGlobalError: false,\n };\n }\n }\n }\n\n const globalErrorComponent = options.getDefaultExport(options.globalErrorModule);\n return {\n component: globalErrorComponent ?? null,\n isGlobalError: Boolean(globalErrorComponent),\n };\n}\n\nexport function wrapAppPageBoundaryElement<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent,\n>(\n options: WrapAppPageBoundaryElementOptions<\n TElement,\n TLayoutModule,\n TLayoutComponent,\n TChildSegments,\n TGlobalErrorComponent\n >,\n): TElement {\n let element = options.element;\n\n if (!options.skipLayoutWrapping) {\n for (let index = options.layoutModules.length - 1; index >= 0; index--) {\n const layoutComponent = options.getDefaultExport(options.layoutModules[index]);\n if (!layoutComponent) {\n continue;\n }\n\n const treePosition = options.layoutTreePositions ? options.layoutTreePositions[index] : 0;\n const asyncParams = options.makeThenableParams(\n resolveAppPageSegmentParams(options.routeSegments, treePosition, options.matchedParams),\n );\n element = options.renderLayout(layoutComponent, element, asyncParams);\n\n if (\n options.isRscRequest &&\n options.renderLayoutSegmentProvider &&\n options.resolveChildSegments\n ) {\n const childSegments = options.resolveChildSegments(\n options.routeSegments ?? [],\n treePosition,\n options.matchedParams,\n );\n element = options.renderLayoutSegmentProvider({ children: childSegments }, element);\n }\n }\n }\n\n if (options.isRscRequest && options.includeGlobalErrorBoundary && options.globalErrorComponent) {\n element = options.renderErrorBoundary(options.globalErrorComponent, element);\n }\n\n return element;\n}\n\nexport async function renderAppPageBoundaryResponse<TElement>(\n options: RenderAppPageBoundaryResponseOptions<TElement>,\n): Promise<Response> {\n // Defensive wrap for standalone callers; idempotent under dispatchAppPage.\n // The async stream consumption that follows relies on the surrounding\n // runWithRequestContext to keep ALS state alive after this synchronous call\n // returns. See app-page-render.ts for the same pattern.\n const rscStream = runWithFetchDedupe(() =>\n options.renderToReadableStream(options.element, {\n onError: options.createRscOnErrorHandler(),\n }),\n );\n\n if (options.isRscRequest) {\n // Do NOT clear request-scoped context here. RSC responses are consumed lazily\n // by the client, so headers()/cookies() and async server components still need\n // their ALS-backed state while the stream is being read.\n const headers = new Headers({\n \"Content-Type\": VINEXT_RSC_CONTENT_TYPE,\n Vary: VINEXT_RSC_VARY_HEADER,\n });\n mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);\n applyRscCompatibilityIdHeader(headers);\n\n return new Response(rscStream, {\n status: options.status,\n headers,\n });\n }\n\n return options.createHtmlResponse(rscStream, options.status);\n}\n"],"mappings":";;;;;AAkGA,SAAgB,0CACd,SACmB;CACnB,IAAI;CAEJ,IAAI,QAAQ,eAAe,KACzB,iBAAiB,QAAQ,wBAAwB,QAAQ;MACpD,IAAI,QAAQ,eAAe,KAChC,iBAAiB,QAAQ,2BAA2B,QAAQ;MAE5D,iBAAiB,QAAQ,uBAAuB,QAAQ;CAG1D,OAAO,QAAQ,iBAAiB,eAAe,IAAI;;AAGrD,SAAgB,6CACd,SACgB;CAChB,IAAI,eAAe,QAAQ;CAC3B,IAAI,aAAa,QAAQ;CAEzB,IAAI,QAAQ,eAAe,KAAK;EAC9B,eAAe,QAAQ;EACvB,aAAa,QAAQ;QAChB,IAAI,QAAQ,eAAe,KAAK;EACrC,eAAe,QAAQ;EACvB,aAAa,QAAQ;;CAGvB,IAAI,cACF,KAAK,IAAI,QAAQ,QAAQ,cAAc,GAAG,SAAS,GAAG,SAAS;EAC7D,MAAM,SAAS,aAAa;EAC5B,IAAI,QACF,OAAO;;CAKb,OAAO,cAAc;;AAGvB,SAAgB,4BACd,SAC+C;CAC/C,MAAM,qBAAqB,QAAQ,iBAAiB,QAAQ,gBAAgB;CAC5E,IAAI,oBACF,OAAO;EACL,WAAW;EACX,eAAe;EAChB;CAGH,MAAM,sBAAsB,QAAQ,gBAAgB,QAAQ;CAC5D,IAAI,qBACF,KAAK,IAAI,QAAQ,oBAAoB,SAAS,GAAG,SAAS,GAAG,SAAS;EACpE,MAAM,wBAAwB,QAAQ,iBAAiB,oBAAoB,OAAO;EAClF,IAAI,uBACF,OAAO;GACL,WAAW;GACX,eAAe;GAChB;;CAKP,MAAM,uBAAuB,QAAQ,iBAAiB,QAAQ,kBAAkB;CAChF,OAAO;EACL,WAAW,wBAAwB;EACnC,eAAe,QAAQ,qBAAqB;EAC7C;;AAGH,SAAgB,2BAOd,SAOU;CACV,IAAI,UAAU,QAAQ;CAEtB,IAAI,CAAC,QAAQ,oBACX,KAAK,IAAI,QAAQ,QAAQ,cAAc,SAAS,GAAG,SAAS,GAAG,SAAS;EACtE,MAAM,kBAAkB,QAAQ,iBAAiB,QAAQ,cAAc,OAAO;EAC9E,IAAI,CAAC,iBACH;EAGF,MAAM,eAAe,QAAQ,sBAAsB,QAAQ,oBAAoB,SAAS;EACxF,MAAM,cAAc,QAAQ,mBAC1B,4BAA4B,QAAQ,eAAe,cAAc,QAAQ,cAAc,CACxF;EACD,UAAU,QAAQ,aAAa,iBAAiB,SAAS,YAAY;EAErE,IACE,QAAQ,gBACR,QAAQ,+BACR,QAAQ,sBACR;GACA,MAAM,gBAAgB,QAAQ,qBAC5B,QAAQ,iBAAiB,EAAE,EAC3B,cACA,QAAQ,cACT;GACD,UAAU,QAAQ,4BAA4B,EAAE,UAAU,eAAe,EAAE,QAAQ;;;CAKzF,IAAI,QAAQ,gBAAgB,QAAQ,8BAA8B,QAAQ,sBACxE,UAAU,QAAQ,oBAAoB,QAAQ,sBAAsB,QAAQ;CAG9E,OAAO;;AAGT,eAAsB,8BACpB,SACmB;CAKnB,MAAM,YAAY,yBAChB,QAAQ,uBAAuB,QAAQ,SAAS,EAC9C,SAAS,QAAQ,yBAAyB,EAC3C,CAAC,CACH;CAED,IAAI,QAAQ,cAAc;EAIxB,MAAM,UAAU,IAAI,QAAQ;GAC1B,gBAAgB;GAChB,MAAM;GACP,CAAC;EACF,+BAA+B,SAAS,QAAQ,qBAAqB,KAAK;EAC1E,8BAA8B,QAAQ;EAEtC,OAAO,IAAI,SAAS,WAAW;GAC7B,QAAQ,QAAQ;GAChB;GACD,CAAC;;CAGJ,OAAO,QAAQ,mBAAmB,WAAW,QAAQ,OAAO"}
@@ -1,6 +1,8 @@
1
+ import { RenderObservation } from "./cache-proof.js";
1
2
  import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache.js";
2
3
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
3
4
  import { ISRCacheEntry } from "./isr-cache.js";
5
+ import { AppPageRenderObservationState } from "./app-page-render-observation.js";
4
6
 
5
7
  //#region src/server/app-page-cache.d.ts
6
8
  type AppPageDebugLogger = (event: string, detail: string) => void;
@@ -11,10 +13,27 @@ type AppPageRequestCacheLife = {
11
13
  revalidate?: number;
12
14
  expire?: number;
13
15
  };
16
+ type AppPageCacheOutcomeMetric = Readonly<{
17
+ artifact: "html" | "rsc";
18
+ /**
19
+ * Internal cache lookup key for debugging and tests. Runtime telemetry sinks should hash or
20
+ * redact this value before export to avoid high-cardinality or user-derived labels.
21
+ */
22
+ cacheKey: string;
23
+ outcome: "hit" | "miss" | "stale";
24
+ reason: "empty-entry" | "no-entry" | "non-app-page-entry" | "read-error" | "served" | "stale-empty-entry";
25
+ }>;
26
+ type AppPageCacheOutcomeRecorder = (metric: AppPageCacheOutcomeMetric) => void;
27
+ type BuildAppPageCacheRenderObservation = (input: {
28
+ cacheTags: readonly string[];
29
+ state: AppPageRenderObservationState;
30
+ }) => RenderObservation;
14
31
  type AppPageCacheRenderResult = {
15
32
  cacheControl?: CacheControlMetadata;
16
33
  html: string;
34
+ htmlRenderObservation?: RenderObservation;
17
35
  rscData: ArrayBuffer;
36
+ rscRenderObservation?: RenderObservation;
18
37
  tags: string[];
19
38
  };
20
39
  type BuildAppPageCachedResponseOptions = {
@@ -39,6 +58,7 @@ type ReadAppPageCacheResponseOptions = {
39
58
  middlewareHeaders?: Headers | null;
40
59
  middlewareStatus?: number | null;
41
60
  mountedSlotsHeader?: string | null;
61
+ recordCacheOutcome?: AppPageCacheOutcomeRecorder;
42
62
  renderMode?: AppRscRenderMode;
43
63
  expireSeconds?: number;
44
64
  revalidateSeconds: number;
@@ -50,6 +70,9 @@ type FinalizeAppPageHtmlCacheResponseOptions = {
50
70
  capturedRscDataPromise: Promise<ArrayBuffer> | null;
51
71
  cleanPathname: string;
52
72
  consumeDynamicUsage: () => boolean;
73
+ consumeRenderObservationState?: () => AppPageRenderObservationState;
74
+ createHtmlRenderObservation?: BuildAppPageCacheRenderObservation;
75
+ createRscRenderObservation?: BuildAppPageCacheRenderObservation;
53
76
  getPageTags: () => string[];
54
77
  getRequestCacheLife?: () => AppPageRequestCacheLife | null;
55
78
  isrDebug?: AppPageDebugLogger;
@@ -65,6 +88,8 @@ type ScheduleAppPageRscCacheWriteOptions = {
65
88
  capturedRscDataPromise: Promise<ArrayBuffer> | null;
66
89
  cleanPathname: string;
67
90
  consumeDynamicUsage: () => boolean;
91
+ consumeRenderObservationState?: () => AppPageRenderObservationState;
92
+ createRscRenderObservation?: BuildAppPageCacheRenderObservation;
68
93
  dynamicUsedDuringBuild: boolean;
69
94
  getPageTags: () => string[];
70
95
  getRequestCacheLife?: () => AppPageRequestCacheLife | null;
@@ -85,5 +110,5 @@ declare function finalizeAppPageHtmlCacheResponse(response: Response, options: F
85
110
  declare function finalizeAppPageRscCacheResponse(response: Response, options: ScheduleAppPageRscCacheWriteOptions): Response;
86
111
  declare function scheduleAppPageRscCacheWrite(options: ScheduleAppPageRscCacheWriteOptions): boolean;
87
112
  //#endregion
88
- export { buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, scheduleAppPageRscCacheWrite };
113
+ export { AppPageCacheOutcomeMetric, buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, scheduleAppPageRscCacheWrite };
89
114
  //# sourceMappingURL=app-page-cache.d.ts.map