vinext 0.0.49 → 0.0.51

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 (506) hide show
  1. package/dist/build/client-build-config.js.map +1 -1
  2. package/dist/build/google-fonts/build-url.js.map +1 -1
  3. package/dist/build/google-fonts/fallback-metrics-data.js +14031 -0
  4. package/dist/build/google-fonts/fallback-metrics-data.js.map +1 -0
  5. package/dist/build/google-fonts/fallback-metrics.d.ts +13 -0
  6. package/dist/build/google-fonts/fallback-metrics.js +46 -0
  7. package/dist/build/google-fonts/fallback-metrics.js.map +1 -0
  8. package/dist/build/google-fonts/get-axes.js.map +1 -1
  9. package/dist/build/google-fonts/sort-variants.js.map +1 -1
  10. package/dist/build/google-fonts/validate.js.map +1 -1
  11. package/dist/build/layout-classification.js.map +1 -1
  12. package/dist/build/nitro-route-rules.js.map +1 -1
  13. package/dist/build/precompress.d.ts +13 -2
  14. package/dist/build/precompress.js +12 -3
  15. package/dist/build/precompress.js.map +1 -1
  16. package/dist/build/prerender.d.ts +17 -1
  17. package/dist/build/prerender.js +114 -23
  18. package/dist/build/prerender.js.map +1 -1
  19. package/dist/build/report.d.ts +5 -4
  20. package/dist/build/report.js +196 -348
  21. package/dist/build/report.js.map +1 -1
  22. package/dist/build/route-classification-injector.js.map +1 -1
  23. package/dist/build/route-classification-manifest.js.map +1 -1
  24. package/dist/build/run-prerender.js.map +1 -1
  25. package/dist/build/server-manifest.js.map +1 -1
  26. package/dist/build/ssr-manifest.js.map +1 -1
  27. package/dist/build/standalone.js.map +1 -1
  28. package/dist/build/static-export.js.map +1 -1
  29. package/dist/check.js +2 -1
  30. package/dist/check.js.map +1 -1
  31. package/dist/cli-args.js.map +1 -1
  32. package/dist/cli.js +68 -7
  33. package/dist/cli.js.map +1 -1
  34. package/dist/client/instrumentation-client-state.js.map +1 -1
  35. package/dist/client/validate-module-path.js.map +1 -1
  36. package/dist/client/vinext-next-data.d.ts +5 -1
  37. package/dist/client/window-next.d.ts +151 -0
  38. package/dist/client/window-next.js +48 -0
  39. package/dist/client/window-next.js.map +1 -0
  40. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  41. package/dist/cloudflare/tpr.js +2 -1
  42. package/dist/cloudflare/tpr.js.map +1 -1
  43. package/dist/config/config-matchers.d.ts +3 -1
  44. package/dist/config/config-matchers.js +5 -4
  45. package/dist/config/config-matchers.js.map +1 -1
  46. package/dist/config/dotenv.d.ts +11 -1
  47. package/dist/config/dotenv.js.map +1 -1
  48. package/dist/config/next-config.d.ts +93 -6
  49. package/dist/config/next-config.js +233 -6
  50. package/dist/config/next-config.js.map +1 -1
  51. package/dist/config/tsconfig-paths.d.ts +13 -0
  52. package/dist/config/tsconfig-paths.js +117 -0
  53. package/dist/config/tsconfig-paths.js.map +1 -0
  54. package/dist/deploy.js +16 -7
  55. package/dist/deploy.js.map +1 -1
  56. package/dist/entries/app-browser-entry.d.ts +3 -1
  57. package/dist/entries/app-browser-entry.js +36 -2
  58. package/dist/entries/app-browser-entry.js.map +1 -1
  59. package/dist/entries/app-rsc-entry.d.ts +19 -1
  60. package/dist/entries/app-rsc-entry.js +49 -12
  61. package/dist/entries/app-rsc-entry.js.map +1 -1
  62. package/dist/entries/app-rsc-manifest.d.ts +9 -0
  63. package/dist/entries/app-rsc-manifest.js +8 -1
  64. package/dist/entries/app-rsc-manifest.js.map +1 -1
  65. package/dist/entries/app-ssr-entry.js.map +1 -1
  66. package/dist/entries/pages-client-entry.js +3 -5
  67. package/dist/entries/pages-client-entry.js.map +1 -1
  68. package/dist/entries/pages-entry-helpers.js.map +1 -1
  69. package/dist/entries/pages-server-entry.js +34 -1
  70. package/dist/entries/pages-server-entry.js.map +1 -1
  71. package/dist/entries/runtime-entry-module.js.map +1 -1
  72. package/dist/index.js +204 -53
  73. package/dist/index.js.map +1 -1
  74. package/dist/init.js.map +1 -1
  75. package/dist/plugins/async-hooks-stub.js.map +1 -1
  76. package/dist/plugins/client-reference-dedup.d.ts +15 -2
  77. package/dist/plugins/client-reference-dedup.js +138 -16
  78. package/dist/plugins/client-reference-dedup.js.map +1 -1
  79. package/dist/plugins/fonts.d.ts +2 -2
  80. package/dist/plugins/fonts.js +15 -6
  81. package/dist/plugins/fonts.js.map +1 -1
  82. package/dist/plugins/instrumentation-client.js.map +1 -1
  83. package/dist/plugins/og-assets.js.map +1 -1
  84. package/dist/plugins/optimize-imports.js.map +1 -1
  85. package/dist/plugins/postcss.js.map +1 -1
  86. package/dist/plugins/rsc-client-reference-loaders.d.ts +7 -0
  87. package/dist/plugins/rsc-client-reference-loaders.js +48 -0
  88. package/dist/plugins/rsc-client-reference-loaders.js.map +1 -0
  89. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
  90. package/dist/plugins/sass.d.ts +34 -0
  91. package/dist/plugins/sass.js +22 -0
  92. package/dist/plugins/sass.js.map +1 -0
  93. package/dist/plugins/server-externals-manifest.js.map +1 -1
  94. package/dist/plugins/strip-server-exports.js.map +1 -1
  95. package/dist/routing/app-route-graph.d.ts +78 -6
  96. package/dist/routing/app-route-graph.js +241 -25
  97. package/dist/routing/app-route-graph.js.map +1 -1
  98. package/dist/routing/app-router.js.map +1 -1
  99. package/dist/routing/file-matcher.js.map +1 -1
  100. package/dist/routing/pages-router.js.map +1 -1
  101. package/dist/routing/route-matching.js.map +1 -1
  102. package/dist/routing/route-pattern.d.ts +56 -1
  103. package/dist/routing/route-pattern.js +60 -1
  104. package/dist/routing/route-pattern.js.map +1 -1
  105. package/dist/routing/route-trie.js.map +1 -1
  106. package/dist/routing/route-validation.js.map +1 -1
  107. package/dist/routing/utils.js.map +1 -1
  108. package/dist/server/api-handler.js.map +1 -1
  109. package/dist/server/app-browser-action-result.d.ts +44 -0
  110. package/dist/server/app-browser-action-result.js +79 -0
  111. package/dist/server/app-browser-action-result.js.map +1 -0
  112. package/dist/server/app-browser-entry.js +330 -133
  113. package/dist/server/app-browser-entry.js.map +1 -1
  114. package/dist/server/app-browser-error.js.map +1 -1
  115. package/dist/server/app-browser-hydration.d.ts +31 -0
  116. package/dist/server/app-browser-hydration.js +30 -0
  117. package/dist/server/app-browser-hydration.js.map +1 -0
  118. package/dist/server/app-browser-navigation-controller.d.ts +20 -4
  119. package/dist/server/app-browser-navigation-controller.js +90 -23
  120. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  121. package/dist/server/app-browser-popstate.d.ts +16 -0
  122. package/dist/server/app-browser-popstate.js +17 -0
  123. package/dist/server/app-browser-popstate.js.map +1 -0
  124. package/dist/server/app-browser-rsc-redirect.d.ts +28 -0
  125. package/dist/server/app-browser-rsc-redirect.js +37 -0
  126. package/dist/server/app-browser-rsc-redirect.js.map +1 -0
  127. package/dist/server/app-browser-state.d.ts +27 -23
  128. package/dist/server/app-browser-state.js +158 -54
  129. package/dist/server/app-browser-state.js.map +1 -1
  130. package/dist/server/app-browser-stream.d.ts +9 -4
  131. package/dist/server/app-browser-stream.js +29 -8
  132. package/dist/server/app-browser-stream.js.map +1 -1
  133. package/dist/server/app-browser-visible-commit.d.ts +11 -1
  134. package/dist/server/app-browser-visible-commit.js +69 -21
  135. package/dist/server/app-browser-visible-commit.js.map +1 -1
  136. package/dist/server/app-client-reference-preloader.js.map +1 -1
  137. package/dist/server/app-elements-wire.d.ts +43 -6
  138. package/dist/server/app-elements-wire.js +121 -5
  139. package/dist/server/app-elements-wire.js.map +1 -1
  140. package/dist/server/app-elements.d.ts +2 -2
  141. package/dist/server/app-elements.js +2 -2
  142. package/dist/server/app-elements.js.map +1 -1
  143. package/dist/server/app-fallback-renderer.d.ts +10 -1
  144. package/dist/server/app-fallback-renderer.js +37 -1
  145. package/dist/server/app-fallback-renderer.js.map +1 -1
  146. package/dist/server/app-history-state.d.ts +26 -0
  147. package/dist/server/app-history-state.js +53 -0
  148. package/dist/server/app-history-state.js.map +1 -0
  149. package/dist/server/app-hook-warning-suppression.js.map +1 -1
  150. package/dist/server/app-middleware.d.ts +1 -1
  151. package/dist/server/app-middleware.js +4 -9
  152. package/dist/server/app-middleware.js.map +1 -1
  153. package/dist/server/app-mounted-slots-header.js.map +1 -1
  154. package/dist/server/app-page-boundary-render.d.ts +11 -1
  155. package/dist/server/app-page-boundary-render.js +27 -19
  156. package/dist/server/app-page-boundary-render.js.map +1 -1
  157. package/dist/server/app-page-boundary.d.ts +1 -0
  158. package/dist/server/app-page-boundary.js +10 -7
  159. package/dist/server/app-page-boundary.js.map +1 -1
  160. package/dist/server/app-page-cache.d.ts +23 -3
  161. package/dist/server/app-page-cache.js +63 -27
  162. package/dist/server/app-page-cache.js.map +1 -1
  163. package/dist/server/app-page-dispatch.d.ts +11 -1
  164. package/dist/server/app-page-dispatch.js +85 -14
  165. package/dist/server/app-page-dispatch.js.map +1 -1
  166. package/dist/server/app-page-element-builder.d.ts +10 -1
  167. package/dist/server/app-page-element-builder.js +38 -6
  168. package/dist/server/app-page-element-builder.js.map +1 -1
  169. package/dist/server/app-page-execution.js +2 -3
  170. package/dist/server/app-page-execution.js.map +1 -1
  171. package/dist/server/app-page-head.d.ts +7 -0
  172. package/dist/server/app-page-head.js +6 -1
  173. package/dist/server/app-page-head.js.map +1 -1
  174. package/dist/server/app-page-method.js.map +1 -1
  175. package/dist/server/app-page-params.js.map +1 -1
  176. package/dist/server/app-page-probe.d.ts +23 -1
  177. package/dist/server/app-page-probe.js +29 -1
  178. package/dist/server/app-page-probe.js.map +1 -1
  179. package/dist/server/app-page-render-observation.d.ts +35 -0
  180. package/dist/server/app-page-render-observation.js +68 -0
  181. package/dist/server/app-page-render-observation.js.map +1 -0
  182. package/dist/server/app-page-render.d.ts +12 -2
  183. package/dist/server/app-page-render.js +90 -7
  184. package/dist/server/app-page-render.js.map +1 -1
  185. package/dist/server/app-page-request.d.ts +1 -0
  186. package/dist/server/app-page-request.js +2 -1
  187. package/dist/server/app-page-request.js.map +1 -1
  188. package/dist/server/app-page-response.d.ts +2 -0
  189. package/dist/server/app-page-response.js +18 -7
  190. package/dist/server/app-page-response.js.map +1 -1
  191. package/dist/server/app-page-route-wiring.d.ts +9 -3
  192. package/dist/server/app-page-route-wiring.js +91 -62
  193. package/dist/server/app-page-route-wiring.js.map +1 -1
  194. package/dist/server/app-page-segment-state.d.ts +10 -0
  195. package/dist/server/app-page-segment-state.js +87 -0
  196. package/dist/server/app-page-segment-state.js.map +1 -0
  197. package/dist/server/app-page-stream.d.ts +9 -2
  198. package/dist/server/app-page-stream.js +4 -1
  199. package/dist/server/app-page-stream.js.map +1 -1
  200. package/dist/server/app-post-middleware-context.js.map +1 -1
  201. package/dist/server/app-prerender-endpoints.js.map +1 -1
  202. package/dist/server/app-prerender-static-params.js.map +1 -1
  203. package/dist/server/app-render-dependency.js.map +1 -1
  204. package/dist/server/app-request-context.js.map +1 -1
  205. package/dist/server/app-route-handler-cache.js.map +1 -1
  206. package/dist/server/app-route-handler-dispatch.js +3 -1
  207. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  208. package/dist/server/app-route-handler-execution.js.map +1 -1
  209. package/dist/server/app-route-handler-policy.js +1 -0
  210. package/dist/server/app-route-handler-policy.js.map +1 -1
  211. package/dist/server/app-route-handler-response.js +4 -3
  212. package/dist/server/app-route-handler-response.js.map +1 -1
  213. package/dist/server/app-route-handler-runtime.js.map +1 -1
  214. package/dist/server/app-router-entry.js +7 -15
  215. package/dist/server/app-router-entry.js.map +1 -1
  216. package/dist/server/app-rsc-cache-busting.d.ts +23 -2
  217. package/dist/server/app-rsc-cache-busting.js +75 -19
  218. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  219. package/dist/server/app-rsc-embedded-chunks.d.ts +9 -0
  220. package/dist/server/app-rsc-embedded-chunks.js +34 -0
  221. package/dist/server/app-rsc-embedded-chunks.js.map +1 -0
  222. package/dist/server/app-rsc-error-handler.js.map +1 -1
  223. package/dist/server/app-rsc-errors.d.ts +4 -1
  224. package/dist/server/app-rsc-errors.js +1 -1
  225. package/dist/server/app-rsc-errors.js.map +1 -1
  226. package/dist/server/app-rsc-handler.d.ts +18 -1
  227. package/dist/server/app-rsc-handler.js +55 -16
  228. package/dist/server/app-rsc-handler.js.map +1 -1
  229. package/dist/server/app-rsc-render-mode.d.ts +11 -0
  230. package/dist/server/app-rsc-render-mode.js +21 -0
  231. package/dist/server/app-rsc-render-mode.js.map +1 -0
  232. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  233. package/dist/server/app-rsc-request-normalization.js +7 -2
  234. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  235. package/dist/server/app-rsc-response-finalizer.d.ts +2 -1
  236. package/dist/server/app-rsc-response-finalizer.js +6 -1
  237. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  238. package/dist/server/app-rsc-route-matching.d.ts +23 -0
  239. package/dist/server/app-rsc-route-matching.js +45 -23
  240. package/dist/server/app-rsc-route-matching.js.map +1 -1
  241. package/dist/server/app-segment-config.js.map +1 -1
  242. package/dist/server/app-server-action-execution.d.ts +51 -5
  243. package/dist/server/app-server-action-execution.js +161 -51
  244. package/dist/server/app-server-action-execution.js.map +1 -1
  245. package/dist/server/app-ssr-entry.d.ts +7 -0
  246. package/dist/server/app-ssr-entry.js +44 -14
  247. package/dist/server/app-ssr-entry.js.map +1 -1
  248. package/dist/server/app-ssr-error-meta.d.ts +14 -0
  249. package/dist/server/app-ssr-error-meta.js +50 -0
  250. package/dist/server/app-ssr-error-meta.js.map +1 -0
  251. package/dist/server/app-ssr-stream.d.ts +1 -1
  252. package/dist/server/app-ssr-stream.js +9 -12
  253. package/dist/server/app-ssr-stream.js.map +1 -1
  254. package/dist/server/app-static-generation.js.map +1 -1
  255. package/dist/server/artifact-compatibility.d.ts +12 -2
  256. package/dist/server/artifact-compatibility.js +12 -8
  257. package/dist/server/artifact-compatibility.js.map +1 -1
  258. package/dist/server/cache-control.js +1 -0
  259. package/dist/server/cache-control.js.map +1 -1
  260. package/dist/server/cache-proof.d.ts +124 -5
  261. package/dist/server/cache-proof.js +416 -18
  262. package/dist/server/cache-proof.js.map +1 -1
  263. package/dist/server/csp.js.map +1 -1
  264. package/dist/server/dev-error-overlay-store.js.map +1 -1
  265. package/dist/server/dev-error-overlay.js +5 -0
  266. package/dist/server/dev-error-overlay.js.map +1 -1
  267. package/dist/server/dev-lockfile.d.ts +110 -0
  268. package/dist/server/dev-lockfile.js +180 -0
  269. package/dist/server/dev-lockfile.js.map +1 -0
  270. package/dist/server/dev-module-runner.js.map +1 -1
  271. package/dist/server/dev-origin-check.js.map +1 -1
  272. package/dist/server/dev-route-files.js.map +1 -1
  273. package/dist/server/dev-server.js +23 -10
  274. package/dist/server/dev-server.js.map +1 -1
  275. package/dist/server/file-based-metadata.d.ts +13 -0
  276. package/dist/server/file-based-metadata.js +49 -2
  277. package/dist/server/file-based-metadata.js.map +1 -1
  278. package/dist/server/headers.d.ts +81 -0
  279. package/dist/server/headers.js +104 -0
  280. package/dist/server/headers.js.map +1 -0
  281. package/dist/server/html.js +1 -1
  282. package/dist/server/html.js.map +1 -1
  283. package/dist/server/http-error-responses.d.ts +10 -0
  284. package/dist/server/http-error-responses.js +11 -1
  285. package/dist/server/http-error-responses.js.map +1 -1
  286. package/dist/server/image-optimization.d.ts +11 -1
  287. package/dist/server/image-optimization.js.map +1 -1
  288. package/dist/server/implicit-tags.js +2 -1
  289. package/dist/server/implicit-tags.js.map +1 -1
  290. package/dist/server/instrumentation-runtime.js.map +1 -1
  291. package/dist/server/instrumentation.js.map +1 -1
  292. package/dist/server/isr-cache.d.ts +12 -2
  293. package/dist/server/isr-cache.js +16 -5
  294. package/dist/server/isr-cache.js.map +1 -1
  295. package/dist/server/metadata-route-build-data.js.map +1 -1
  296. package/dist/server/metadata-route-response.js +22 -5
  297. package/dist/server/metadata-route-response.js.map +1 -1
  298. package/dist/server/metadata-routes.js +27 -8
  299. package/dist/server/metadata-routes.js.map +1 -1
  300. package/dist/server/middleware-matcher.js.map +1 -1
  301. package/dist/server/middleware-request-headers.d.ts +4 -1
  302. package/dist/server/middleware-request-headers.js +15 -8
  303. package/dist/server/middleware-request-headers.js.map +1 -1
  304. package/dist/server/middleware-response-headers.d.ts +2 -1
  305. package/dist/server/middleware-response-headers.js +1 -1
  306. package/dist/server/middleware-response-headers.js.map +1 -1
  307. package/dist/server/middleware-runtime.d.ts +1 -0
  308. package/dist/server/middleware-runtime.js +7 -3
  309. package/dist/server/middleware-runtime.js.map +1 -1
  310. package/dist/server/middleware.d.ts +12 -0
  311. package/dist/server/middleware.js +12 -0
  312. package/dist/server/middleware.js.map +1 -1
  313. package/dist/server/navigation-planner.d.ts +133 -0
  314. package/dist/server/navigation-planner.js +432 -0
  315. package/dist/server/navigation-planner.js.map +1 -0
  316. package/dist/server/navigation-trace.d.ts +19 -2
  317. package/dist/server/navigation-trace.js +20 -1
  318. package/dist/server/navigation-trace.js.map +1 -1
  319. package/dist/server/next-error-digest.d.ts +3 -2
  320. package/dist/server/next-error-digest.js +4 -2
  321. package/dist/server/next-error-digest.js.map +1 -1
  322. package/dist/server/normalize-path.d.ts +2 -1
  323. package/dist/server/normalize-path.js +4 -1
  324. package/dist/server/normalize-path.js.map +1 -1
  325. package/dist/server/pages-api-route.js +1 -0
  326. package/dist/server/pages-api-route.js.map +1 -1
  327. package/dist/server/pages-i18n.js.map +1 -1
  328. package/dist/server/pages-media-type.js.map +1 -1
  329. package/dist/server/pages-node-compat.js.map +1 -1
  330. package/dist/server/pages-page-data.d.ts +3 -2
  331. package/dist/server/pages-page-data.js +27 -5
  332. package/dist/server/pages-page-data.js.map +1 -1
  333. package/dist/server/pages-page-response.js +2 -1
  334. package/dist/server/pages-page-response.js.map +1 -1
  335. package/dist/server/prerender-work-unit-setup.js +1 -1
  336. package/dist/server/prerender-work-unit-setup.js.map +1 -1
  337. package/dist/server/prod-server.d.ts +28 -1
  338. package/dist/server/prod-server.js +97 -22
  339. package/dist/server/prod-server.js.map +1 -1
  340. package/dist/server/request-log.js.map +1 -1
  341. package/dist/server/request-pipeline.d.ts +1 -13
  342. package/dist/server/request-pipeline.js +3 -25
  343. package/dist/server/request-pipeline.js.map +1 -1
  344. package/dist/server/rsc-stream-hints.js.map +1 -1
  345. package/dist/server/seed-cache.js.map +1 -1
  346. package/dist/server/server-action-not-found.d.ts +16 -3
  347. package/dist/server/server-action-not-found.js +22 -4
  348. package/dist/server/server-action-not-found.js.map +1 -1
  349. package/dist/server/server-globals.d.ts +5 -0
  350. package/dist/server/server-globals.js +37 -0
  351. package/dist/server/server-globals.js.map +1 -0
  352. package/dist/server/socket-error-backstop.js.map +1 -1
  353. package/dist/server/static-file-cache.js +1 -1
  354. package/dist/server/static-file-cache.js.map +1 -1
  355. package/dist/server/worker-utils.d.ts +0 -7
  356. package/dist/server/worker-utils.js +3 -2
  357. package/dist/server/worker-utils.js.map +1 -1
  358. package/dist/shims/amp.js.map +1 -1
  359. package/dist/shims/app.d.ts +37 -4
  360. package/dist/shims/app.js +50 -1
  361. package/dist/shims/app.js.map +1 -0
  362. package/dist/shims/cache-for-request.js.map +1 -1
  363. package/dist/shims/cache-runtime.d.ts +19 -2
  364. package/dist/shims/cache-runtime.js +87 -19
  365. package/dist/shims/cache-runtime.js.map +1 -1
  366. package/dist/shims/cache.d.ts +20 -21
  367. package/dist/shims/cache.js +101 -15
  368. package/dist/shims/cache.js.map +1 -1
  369. package/dist/shims/client-hook-error.js.map +1 -1
  370. package/dist/shims/compat-router.js.map +1 -1
  371. package/dist/shims/config.js.map +1 -1
  372. package/dist/shims/constants.js.map +1 -1
  373. package/dist/shims/document.js.map +1 -1
  374. package/dist/shims/dynamic.d.ts +18 -10
  375. package/dist/shims/dynamic.js +107 -51
  376. package/dist/shims/dynamic.js.map +1 -1
  377. package/dist/shims/error-boundary.d.ts +35 -6
  378. package/dist/shims/error-boundary.js +116 -33
  379. package/dist/shims/error-boundary.js.map +1 -1
  380. package/dist/shims/error.d.ts +18 -1
  381. package/dist/shims/error.js +56 -1
  382. package/dist/shims/error.js.map +1 -1
  383. package/dist/shims/fetch-cache.d.ts +25 -1
  384. package/dist/shims/fetch-cache.js +159 -13
  385. package/dist/shims/fetch-cache.js.map +1 -1
  386. package/dist/shims/font-google-base.d.ts +22 -8
  387. package/dist/shims/font-google-base.js +41 -71
  388. package/dist/shims/font-google-base.js.map +1 -1
  389. package/dist/shims/font-local.d.ts +3 -20
  390. package/dist/shims/font-local.js +23 -75
  391. package/dist/shims/font-local.js.map +1 -1
  392. package/dist/shims/font-utils.d.ts +51 -0
  393. package/dist/shims/font-utils.js +97 -0
  394. package/dist/shims/font-utils.js.map +1 -0
  395. package/dist/shims/form.js +3 -1
  396. package/dist/shims/form.js.map +1 -1
  397. package/dist/shims/hash-scroll.d.ts +7 -0
  398. package/dist/shims/hash-scroll.js +30 -0
  399. package/dist/shims/hash-scroll.js.map +1 -0
  400. package/dist/shims/head-state.js.map +1 -1
  401. package/dist/shims/head.d.ts +3 -1
  402. package/dist/shims/head.js +28 -16
  403. package/dist/shims/head.js.map +1 -1
  404. package/dist/shims/headers.d.ts +11 -12
  405. package/dist/shims/headers.js +45 -8
  406. package/dist/shims/headers.js.map +1 -1
  407. package/dist/shims/i18n-context.js.map +1 -1
  408. package/dist/shims/i18n-state.js.map +1 -1
  409. package/dist/shims/image-config.d.ts +14 -1
  410. package/dist/shims/image-config.js +24 -1
  411. package/dist/shims/image-config.js.map +1 -1
  412. package/dist/shims/image.d.ts +1 -0
  413. package/dist/shims/image.js +159 -80
  414. package/dist/shims/image.js.map +1 -1
  415. package/dist/shims/internal/als-registry.js.map +1 -1
  416. package/dist/shims/internal/app-router-context.d.ts +7 -6
  417. package/dist/shims/internal/app-router-context.js +17 -6
  418. package/dist/shims/internal/app-router-context.js.map +1 -1
  419. package/dist/shims/internal/cookie-serialize.js.map +1 -1
  420. package/dist/shims/internal/make-hanging-promise.d.ts +1 -1
  421. package/dist/shims/internal/make-hanging-promise.js +1 -1
  422. package/dist/shims/internal/make-hanging-promise.js.map +1 -1
  423. package/dist/shims/internal/parse-cookie-header.js.map +1 -1
  424. package/dist/shims/internal/utils.js.map +1 -1
  425. package/dist/shims/internal/work-unit-async-storage.js +2 -2
  426. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  427. package/dist/shims/layout-segment-context.js.map +1 -1
  428. package/dist/shims/legacy-image.js.map +1 -1
  429. package/dist/shims/link-prefetch.d.ts +42 -0
  430. package/dist/shims/link-prefetch.js +45 -0
  431. package/dist/shims/link-prefetch.js.map +1 -0
  432. package/dist/shims/link.d.ts +37 -4
  433. package/dist/shims/link.js +156 -46
  434. package/dist/shims/link.js.map +1 -1
  435. package/dist/shims/metadata.d.ts +16 -30
  436. package/dist/shims/metadata.js +87 -28
  437. package/dist/shims/metadata.js.map +1 -1
  438. package/dist/shims/navigation-state.js.map +1 -1
  439. package/dist/shims/navigation.d.ts +172 -10
  440. package/dist/shims/navigation.js +335 -70
  441. package/dist/shims/navigation.js.map +1 -1
  442. package/dist/shims/navigation.react-server.d.ts +3 -2
  443. package/dist/shims/navigation.react-server.js +5 -2
  444. package/dist/shims/navigation.react-server.js.map +1 -1
  445. package/dist/shims/offline.js.map +1 -1
  446. package/dist/shims/pages-router-runtime.d.ts +7 -0
  447. package/dist/shims/pages-router-runtime.js +16 -0
  448. package/dist/shims/pages-router-runtime.js.map +1 -0
  449. package/dist/shims/readonly-url-search-params.js.map +1 -1
  450. package/dist/shims/request-context.js.map +1 -1
  451. package/dist/shims/root-params.js.map +1 -1
  452. package/dist/shims/router-state.js.map +1 -1
  453. package/dist/shims/router.d.ts +69 -7
  454. package/dist/shims/router.js +232 -249
  455. package/dist/shims/router.js.map +1 -1
  456. package/dist/shims/script-nonce-context.js.map +1 -1
  457. package/dist/shims/script.js +110 -32
  458. package/dist/shims/script.js.map +1 -1
  459. package/dist/shims/server.js +12 -15
  460. package/dist/shims/server.js.map +1 -1
  461. package/dist/shims/slot.d.ts +7 -1
  462. package/dist/shims/slot.js +60 -7
  463. package/dist/shims/slot.js.map +1 -1
  464. package/dist/shims/thenable-params.js.map +1 -1
  465. package/dist/shims/unified-request-context.js +5 -0
  466. package/dist/shims/unified-request-context.js.map +1 -1
  467. package/dist/shims/unrecognized-action-error.d.ts +35 -0
  468. package/dist/shims/unrecognized-action-error.js +41 -0
  469. package/dist/shims/unrecognized-action-error.js.map +1 -0
  470. package/dist/shims/url-safety.js.map +1 -1
  471. package/dist/shims/url-utils.d.ts +22 -1
  472. package/dist/shims/url-utils.js +76 -3
  473. package/dist/shims/url-utils.js.map +1 -1
  474. package/dist/shims/use-merged-ref.js.map +1 -1
  475. package/dist/shims/web-vitals.d.ts +4 -21
  476. package/dist/shims/web-vitals.js +19 -6
  477. package/dist/shims/web-vitals.js.map +1 -1
  478. package/dist/utils/asset-prefix.d.ts +69 -0
  479. package/dist/utils/asset-prefix.js +91 -0
  480. package/dist/utils/asset-prefix.js.map +1 -0
  481. package/dist/utils/base-path.d.ts +7 -1
  482. package/dist/utils/base-path.js +10 -1
  483. package/dist/utils/base-path.js.map +1 -1
  484. package/dist/utils/cache-control-metadata.js.map +1 -1
  485. package/dist/utils/domain-locale.js.map +1 -1
  486. package/dist/utils/encode-cache-tag.d.ts +31 -0
  487. package/dist/utils/encode-cache-tag.js +38 -0
  488. package/dist/utils/encode-cache-tag.js.map +1 -0
  489. package/dist/utils/error-cause.js.map +1 -1
  490. package/dist/utils/hash.js.map +1 -1
  491. package/dist/utils/lazy-chunks.js.map +1 -1
  492. package/dist/utils/manifest-paths.js.map +1 -1
  493. package/dist/utils/mdx-scan.js.map +1 -1
  494. package/dist/utils/navigation-signal.d.ts +5 -0
  495. package/dist/utils/navigation-signal.js +14 -0
  496. package/dist/utils/navigation-signal.js.map +1 -0
  497. package/dist/utils/project.js.map +1 -1
  498. package/dist/utils/public-routes.js.map +1 -1
  499. package/dist/utils/query.js.map +1 -1
  500. package/dist/utils/safe-json-file.js.map +1 -1
  501. package/dist/utils/sorted-array.d.ts +9 -0
  502. package/dist/utils/sorted-array.js +22 -0
  503. package/dist/utils/sorted-array.js.map +1 -0
  504. package/dist/utils/text-stream.js.map +1 -1
  505. package/dist/utils/vinext-root.js.map +1 -1
  506. package/package.json +8 -6
@@ -44,18 +44,15 @@ function wrapRenderedBoundaryElement(options) {
44
44
  skipLayoutWrapping: options.skipLayoutWrapping
45
45
  });
46
46
  }
47
- function resolveAppPageBoundaryRootLayoutTreePath(route) {
48
- if (route?.layouts) {
49
- const rootLayoutEntry = createAppPageLayoutEntries({
50
- errors: route.errors,
51
- layoutTreePositions: route.layoutTreePositions,
52
- layouts: route.layouts,
53
- notFounds: null,
54
- routeSegments: route.routeSegments
55
- })[0];
56
- if (rootLayoutEntry) return rootLayoutEntry.treePath;
57
- }
58
- return null;
47
+ function createAppPageBoundaryLayoutEntries(route, layoutModules) {
48
+ if (!route || layoutModules.length === 0) return [];
49
+ return createAppPageLayoutEntries({
50
+ errors: route.errors,
51
+ layoutTreePositions: route.layoutTreePositions,
52
+ layouts: layoutModules,
53
+ notFounds: null,
54
+ routeSegments: route.routeSegments
55
+ });
59
56
  }
60
57
  function resolveHttpAccessFallbackHeadRouteSegments(route, layoutModules) {
61
58
  if (!route?.routeSegments) return;
@@ -71,10 +68,12 @@ function resolveHttpAccessFallbackHeadLayoutTreePositions(route, layoutModules)
71
68
  }
72
69
  function createAppPageBoundaryRscPayload(options) {
73
70
  const routeId = AppElementsWire.encodeRouteId(options.pathname, null);
71
+ const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);
74
72
  return {
75
73
  ...AppElementsWire.createMetadataEntries({
76
74
  interceptionContext: null,
77
- rootLayoutTreePath: resolveAppPageBoundaryRootLayoutTreePath(options.route),
75
+ layoutIds: layoutEntries.map((entry) => entry.id),
76
+ rootLayoutTreePath: layoutEntries[0]?.treePath ?? null,
78
77
  routeId
79
78
  }),
80
79
  [routeId]: options.element
@@ -107,6 +106,7 @@ async function renderAppPageBoundaryElementResponse(options) {
107
106
  },
108
107
  element: createAppPageBoundaryRscPayload({
109
108
  element: options.element,
109
+ layoutModules: options.layoutModules,
110
110
  pathname,
111
111
  route: options.route
112
112
  }),
@@ -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
  });
@@ -178,6 +183,7 @@ async function renderAppPageHttpAccessFallback(options) {
178
183
  async function renderAppPageErrorBoundary(options) {
179
184
  const errorBoundary = resolveAppPageErrorBoundary({
180
185
  getDefaultExport,
186
+ errorModules: options.route?.errorPaths,
181
187
  globalErrorModule: options.globalErrorModule,
182
188
  layoutErrorModules: options.route?.errors,
183
189
  pageErrorModule: options.route?.error
@@ -195,6 +201,7 @@ async function renderAppPageErrorBoundary(options) {
195
201
  })];
196
202
  if (!errorBoundary.isGlobalError) try {
197
203
  const { metadata, viewport } = await resolveAppPageHead({
204
+ basePath: options.basePath ?? "",
198
205
  fallbackOnFileMetadataError: true,
199
206
  layoutModules,
200
207
  layoutTreePositions: options.route?.layoutTreePositions,
@@ -205,7 +212,8 @@ async function renderAppPageErrorBoundary(options) {
205
212
  });
206
213
  if (metadata) headElements.push(createElement(MetadataHead, {
207
214
  key: "metadata",
208
- metadata
215
+ metadata,
216
+ pathname
209
217
  }));
210
218
  headElements.push(createElement(ViewportHead, {
211
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 pathname: string;\n route?: AppPageBoundaryRoute<TModule> | null;\n};\n\nexport type AppPageBoundaryRoute<TModule extends AppPageModule = AppPageModule> = {\n error?: 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 resolveAppPageBoundaryRootLayoutTreePath<TModule extends AppPageModule>(\n route: AppPageBoundaryRoute<TModule> | null | undefined,\n): string | null {\n if (route?.layouts) {\n const rootLayoutEntry = createAppPageLayoutEntries({\n errors: route.errors,\n layoutTreePositions: route.layoutTreePositions,\n layouts: route.layouts,\n notFounds: null,\n routeSegments: route.routeSegments,\n })[0];\n\n if (rootLayoutEntry) {\n return rootLayoutEntry.treePath;\n }\n }\n\n // Without route tree metadata we cannot derive a canonical root layout tree path.\n // Returning null keeps boundary payloads soft-navigation compatible.\n return null;\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\n return {\n ...AppElementsWire.createMetadataEntries({\n interceptionContext: null,\n rootLayoutTreePath: resolveAppPageBoundaryRootLayoutTreePath(options.route),\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 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 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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"}
@@ -23,6 +23,7 @@ type ResolveAppPageParentHttpAccessBoundaryModuleOptions<TModule> = {
23
23
  type ResolveAppPageErrorBoundaryOptions<TModule, TComponent> = {
24
24
  getDefaultExport: (module: TModule | null | undefined) => TComponent | null | undefined;
25
25
  globalErrorModule?: TModule | null;
26
+ errorModules?: readonly (TModule | null | undefined)[] | null;
26
27
  layoutErrorModules?: readonly (TModule | null | undefined)[] | null;
27
28
  pageErrorModule?: TModule | null;
28
29
  };
@@ -1,4 +1,5 @@
1
- import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
1
+ import { runWithFetchDedupe } from "../shims/fetch-cache.js";
2
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
2
3
  import { resolveAppPageSegmentParams } from "./app-page-params.js";
3
4
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
4
5
  //#region src/server/app-page-boundary.ts
@@ -31,10 +32,11 @@ function resolveAppPageErrorBoundary(options) {
31
32
  component: pageErrorComponent,
32
33
  isGlobalError: false
33
34
  };
34
- if (options.layoutErrorModules) for (let index = options.layoutErrorModules.length - 1; index >= 0; index--) {
35
- const layoutErrorComponent = options.getDefaultExport(options.layoutErrorModules[index]);
36
- if (layoutErrorComponent) return {
37
- component: layoutErrorComponent,
35
+ const segmentErrorModules = options.errorModules ?? options.layoutErrorModules;
36
+ if (segmentErrorModules) for (let index = segmentErrorModules.length - 1; index >= 0; index--) {
37
+ const segmentErrorComponent = options.getDefaultExport(segmentErrorModules[index]);
38
+ if (segmentErrorComponent) return {
39
+ component: segmentErrorComponent,
38
40
  isGlobalError: false
39
41
  };
40
42
  }
@@ -61,13 +63,14 @@ function wrapAppPageBoundaryElement(options) {
61
63
  return element;
62
64
  }
63
65
  async function renderAppPageBoundaryResponse(options) {
64
- const rscStream = options.renderToReadableStream(options.element, { onError: options.createRscOnErrorHandler() });
66
+ const rscStream = runWithFetchDedupe(() => options.renderToReadableStream(options.element, { onError: options.createRscOnErrorHandler() }));
65
67
  if (options.isRscRequest) {
66
68
  const headers = new Headers({
67
- "Content-Type": "text/x-component; charset=utf-8",
69
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
68
70
  Vary: VINEXT_RSC_VARY_HEADER
69
71
  });
70
72
  mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
73
+ applyRscCompatibilityIdHeader(headers);
71
74
  return new Response(rscStream, {
72
75
  status: options.status,
73
76
  headers
@@ -1 +1 @@
1
- {"version":3,"file":"app-page-boundary.js","names":[],"sources":["../../src/server/app-page-boundary.ts"],"sourcesContent":["import { 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 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 if (options.layoutErrorModules) {\n for (let index = options.layoutErrorModules.length - 1; index >= 0; index--) {\n const layoutErrorComponent = options.getDefaultExport(options.layoutErrorModules[index]);\n if (layoutErrorComponent) {\n return {\n component: layoutErrorComponent,\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 const rscStream = options.renderToReadableStream(options.element, {\n onError: options.createRscOnErrorHandler(),\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":";;;;AA4FA,SAAgB,0CACd,SACmB;CACnB,IAAI;AAEJ,KAAI,QAAQ,eAAe,IACzB,kBAAiB,QAAQ,wBAAwB,QAAQ;UAChD,QAAQ,eAAe,IAChC,kBAAiB,QAAQ,2BAA2B,QAAQ;KAE5D,kBAAiB,QAAQ,uBAAuB,QAAQ;AAG1D,QAAO,QAAQ,iBAAiB,eAAe,IAAI;;AAGrD,SAAgB,6CACd,SACgB;CAChB,IAAI,eAAe,QAAQ;CAC3B,IAAI,aAAa,QAAQ;AAEzB,KAAI,QAAQ,eAAe,KAAK;AAC9B,iBAAe,QAAQ;AACvB,eAAa,QAAQ;YACZ,QAAQ,eAAe,KAAK;AACrC,iBAAe,QAAQ;AACvB,eAAa,QAAQ;;AAGvB,KAAI,aACF,MAAK,IAAI,QAAQ,QAAQ,cAAc,GAAG,SAAS,GAAG,SAAS;EAC7D,MAAM,SAAS,aAAa;AAC5B,MAAI,OACF,QAAO;;AAKb,QAAO,cAAc;;AAGvB,SAAgB,4BACd,SAC+C;CAC/C,MAAM,qBAAqB,QAAQ,iBAAiB,QAAQ,gBAAgB;AAC5E,KAAI,mBACF,QAAO;EACL,WAAW;EACX,eAAe;EAChB;AAGH,KAAI,QAAQ,mBACV,MAAK,IAAI,QAAQ,QAAQ,mBAAmB,SAAS,GAAG,SAAS,GAAG,SAAS;EAC3E,MAAM,uBAAuB,QAAQ,iBAAiB,QAAQ,mBAAmB,OAAO;AACxF,MAAI,qBACF,QAAO;GACL,WAAW;GACX,eAAe;GAChB;;CAKP,MAAM,uBAAuB,QAAQ,iBAAiB,QAAQ,kBAAkB;AAChF,QAAO;EACL,WAAW,wBAAwB;EACnC,eAAe,QAAQ,qBAAqB;EAC7C;;AAGH,SAAgB,2BAOd,SAOU;CACV,IAAI,UAAU,QAAQ;AAEtB,KAAI,CAAC,QAAQ,mBACX,MAAK,IAAI,QAAQ,QAAQ,cAAc,SAAS,GAAG,SAAS,GAAG,SAAS;EACtE,MAAM,kBAAkB,QAAQ,iBAAiB,QAAQ,cAAc,OAAO;AAC9E,MAAI,CAAC,gBACH;EAGF,MAAM,eAAe,QAAQ,sBAAsB,QAAQ,oBAAoB,SAAS;EACxF,MAAM,cAAc,QAAQ,mBAC1B,4BAA4B,QAAQ,eAAe,cAAc,QAAQ,cAAc,CACxF;AACD,YAAU,QAAQ,aAAa,iBAAiB,SAAS,YAAY;AAErE,MACE,QAAQ,gBACR,QAAQ,+BACR,QAAQ,sBACR;GACA,MAAM,gBAAgB,QAAQ,qBAC5B,QAAQ,iBAAiB,EAAE,EAC3B,cACA,QAAQ,cACT;AACD,aAAU,QAAQ,4BAA4B,EAAE,UAAU,eAAe,EAAE,QAAQ;;;AAKzF,KAAI,QAAQ,gBAAgB,QAAQ,8BAA8B,QAAQ,qBACxE,WAAU,QAAQ,oBAAoB,QAAQ,sBAAsB,QAAQ;AAG9E,QAAO;;AAGT,eAAsB,8BACpB,SACmB;CACnB,MAAM,YAAY,QAAQ,uBAAuB,QAAQ,SAAS,EAChE,SAAS,QAAQ,yBAAyB,EAC3C,CAAC;AAEF,KAAI,QAAQ,cAAc;EAIxB,MAAM,UAAU,IAAI,QAAQ;GAC1B,gBAAgB;GAChB,MAAM;GACP,CAAC;AACF,iCAA+B,SAAS,QAAQ,qBAAqB,KAAK;AAE1E,SAAO,IAAI,SAAS,WAAW;GAC7B,QAAQ,QAAQ;GAChB;GACD,CAAC;;AAGJ,QAAO,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,5 +1,8 @@
1
+ import { RenderObservation } from "./cache-proof.js";
1
2
  import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache.js";
3
+ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
2
4
  import { ISRCacheEntry } from "./isr-cache.js";
5
+ import { AppPageRenderObservationState } from "./app-page-render-observation.js";
3
6
 
4
7
  //#region src/server/app-page-cache.d.ts
5
8
  type AppPageDebugLogger = (event: string, detail: string) => void;
@@ -10,10 +13,16 @@ type AppPageRequestCacheLife = {
10
13
  revalidate?: number;
11
14
  expire?: number;
12
15
  };
16
+ type BuildAppPageCacheRenderObservation = (input: {
17
+ cacheTags: readonly string[];
18
+ state: AppPageRenderObservationState;
19
+ }) => RenderObservation;
13
20
  type AppPageCacheRenderResult = {
14
21
  cacheControl?: CacheControlMetadata;
15
22
  html: string;
23
+ htmlRenderObservation?: RenderObservation;
16
24
  rscData: ArrayBuffer;
25
+ rscRenderObservation?: RenderObservation;
17
26
  tags: string[];
18
27
  };
19
28
  type BuildAppPageCachedResponseOptions = {
@@ -21,6 +30,8 @@ type BuildAppPageCachedResponseOptions = {
21
30
  cacheState: "HIT" | "STALE";
22
31
  expireSeconds?: number;
23
32
  isRscRequest: boolean;
33
+ middlewareHeaders?: Headers | null;
34
+ middlewareStatus?: number | null;
24
35
  mountedSlotsHeader?: string | null;
25
36
  revalidateSeconds: number;
26
37
  };
@@ -31,9 +42,12 @@ type ReadAppPageCacheResponseOptions = {
31
42
  isrDebug?: AppPageDebugLogger;
32
43
  isrGet: AppPageCacheGetter;
33
44
  isrHtmlKey: (pathname: string) => string;
34
- isrRscKey: (pathname: string, mountedSlotsHeader?: string | null) => string;
45
+ isrRscKey: (pathname: string, mountedSlotsHeader?: string | null, renderMode?: AppRscRenderMode) => string;
35
46
  isrSet: AppPageCacheSetter;
47
+ middlewareHeaders?: Headers | null;
48
+ middlewareStatus?: number | null;
36
49
  mountedSlotsHeader?: string | null;
50
+ renderMode?: AppRscRenderMode;
37
51
  expireSeconds?: number;
38
52
  revalidateSeconds: number;
39
53
  renderFreshPageForCache: () => Promise<AppPageCacheRenderResult>;
@@ -44,11 +58,14 @@ type FinalizeAppPageHtmlCacheResponseOptions = {
44
58
  capturedRscDataPromise: Promise<ArrayBuffer> | null;
45
59
  cleanPathname: string;
46
60
  consumeDynamicUsage: () => boolean;
61
+ consumeRenderObservationState?: () => AppPageRenderObservationState;
62
+ createHtmlRenderObservation?: BuildAppPageCacheRenderObservation;
63
+ createRscRenderObservation?: BuildAppPageCacheRenderObservation;
47
64
  getPageTags: () => string[];
48
65
  getRequestCacheLife?: () => AppPageRequestCacheLife | null;
49
66
  isrDebug?: AppPageDebugLogger;
50
67
  isrHtmlKey: (pathname: string) => string;
51
- isrRscKey: (pathname: string, mountedSlotsHeader?: string | null) => string;
68
+ isrRscKey: (pathname: string, mountedSlotsHeader?: string | null, renderMode?: AppRscRenderMode) => string;
52
69
  isrSet: AppPageCacheSetter;
53
70
  preserveClientResponseHeaders?: boolean;
54
71
  expireSeconds?: number;
@@ -59,13 +76,16 @@ type ScheduleAppPageRscCacheWriteOptions = {
59
76
  capturedRscDataPromise: Promise<ArrayBuffer> | null;
60
77
  cleanPathname: string;
61
78
  consumeDynamicUsage: () => boolean;
79
+ consumeRenderObservationState?: () => AppPageRenderObservationState;
80
+ createRscRenderObservation?: BuildAppPageCacheRenderObservation;
62
81
  dynamicUsedDuringBuild: boolean;
63
82
  getPageTags: () => string[];
64
83
  getRequestCacheLife?: () => AppPageRequestCacheLife | null;
65
84
  isrDebug?: AppPageDebugLogger;
66
- isrRscKey: (pathname: string, mountedSlotsHeader?: string | null) => string;
85
+ isrRscKey: (pathname: string, mountedSlotsHeader?: string | null, renderMode?: AppRscRenderMode) => string;
67
86
  isrSet: AppPageCacheSetter;
68
87
  mountedSlotsHeader?: string | null;
88
+ renderMode?: AppRscRenderMode;
69
89
  preserveClientResponseHeaders?: boolean;
70
90
  expireSeconds?: number;
71
91
  revalidateSeconds: number | null;
@@ -1,7 +1,11 @@
1
+ import { VINEXT_CACHE_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
2
+ import { encodeCacheTag } from "../utils/encode-cache-tag.js";
1
3
  import { buildAppPageCacheValue } from "./isr-cache.js";
2
- import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
4
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
5
+ import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
3
6
  import { buildCachedRevalidateCacheControl } from "./cache-control.js";
4
7
  import { readStreamAsText } from "../utils/text-stream.js";
8
+ import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
5
9
  //#region src/server/app-page-cache.ts
6
10
  const NO_STORE_CACHE_CONTROL = "no-store, must-revalidate";
7
11
  function buildAppPageCacheTags(pathname, extraTags) {
@@ -21,11 +25,22 @@ function buildAppPageCacheTags(pathname, extraTags) {
21
25
  }
22
26
  tags.push(`_N_T_${built}/page`);
23
27
  for (const tag of extraTags) if (!tags.includes(tag)) tags.push(tag);
24
- return tags;
28
+ return tags.map(encodeCacheTag);
25
29
  }
26
30
  function buildAppPageCacheControl(cacheState, revalidateSeconds, expireSeconds) {
27
31
  return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);
28
32
  }
33
+ function buildAppPageCachedHeaders(options) {
34
+ const headers = new Headers({
35
+ "Cache-Control": options.cacheControl,
36
+ "Content-Type": options.contentType,
37
+ Vary: VINEXT_RSC_VARY_HEADER,
38
+ [VINEXT_CACHE_HEADER]: options.cacheState
39
+ });
40
+ if (options.mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
41
+ mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
42
+ return headers;
43
+ }
29
44
  function getCachedAppPageValue(entry) {
30
45
  return entry?.value.value && entry.value.value.kind === "APP_PAGE" ? entry.value.value : null;
31
46
  }
@@ -42,37 +57,39 @@ function resolveAppPageCacheWritePolicy(options) {
42
57
  };
43
58
  }
44
59
  function buildAppPageCachedResponse(cachedValue, options) {
45
- const status = cachedValue.status || 200;
60
+ const status = options.middlewareStatus ?? (cachedValue.status || 200);
46
61
  const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;
47
62
  const expireSeconds = options.cacheControl === void 0 ? void 0 : options.cacheControl.expire ?? options.expireSeconds;
48
- const headers = {
49
- "Cache-Control": buildAppPageCacheControl(options.cacheState, revalidateSeconds, expireSeconds),
50
- Vary: VINEXT_RSC_VARY_HEADER,
51
- "X-Vinext-Cache": options.cacheState
52
- };
63
+ const cacheControl = buildAppPageCacheControl(options.cacheState, revalidateSeconds, expireSeconds);
53
64
  if (options.isRscRequest) {
54
65
  if (!cachedValue.rscData) return null;
55
- const rscHeaders = {
56
- "Content-Type": "text/x-component; charset=utf-8",
57
- ...headers
58
- };
59
- if (options.mountedSlotsHeader) rscHeaders["X-Vinext-Mounted-Slots"] = options.mountedSlotsHeader;
66
+ const rscHeaders = buildAppPageCachedHeaders({
67
+ cacheControl,
68
+ cacheState: options.cacheState,
69
+ contentType: VINEXT_RSC_CONTENT_TYPE,
70
+ middlewareHeaders: options.middlewareHeaders,
71
+ mountedSlotsHeader: options.mountedSlotsHeader
72
+ });
73
+ applyRscCompatibilityIdHeader(rscHeaders);
60
74
  return new Response(cachedValue.rscData, {
61
75
  status,
62
76
  headers: rscHeaders
63
77
  });
64
78
  }
65
79
  if (typeof cachedValue.html !== "string" || cachedValue.html.length === 0) return null;
80
+ const htmlHeaders = buildAppPageCachedHeaders({
81
+ cacheControl,
82
+ cacheState: options.cacheState,
83
+ contentType: "text/html; charset=utf-8",
84
+ middlewareHeaders: options.middlewareHeaders
85
+ });
66
86
  return new Response(cachedValue.html, {
67
87
  status,
68
- headers: {
69
- "Content-Type": "text/html; charset=utf-8",
70
- ...headers
71
- }
88
+ headers: htmlHeaders
72
89
  });
73
90
  }
74
91
  async function readAppPageCacheResponse(options) {
75
- const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader) : options.isrHtmlKey(options.cleanPathname);
92
+ const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode) : options.isrHtmlKey(options.cleanPathname);
76
93
  try {
77
94
  const cached = await options.isrGet(isrKey);
78
95
  const cachedValue = getCachedAppPageValue(cached);
@@ -82,6 +99,8 @@ async function readAppPageCacheResponse(options) {
82
99
  cacheControl: cached?.value.cacheControl,
83
100
  expireSeconds: options.expireSeconds,
84
101
  isRscRequest: options.isRscRequest,
102
+ middlewareHeaders: options.middlewareHeaders,
103
+ middlewareStatus: options.middlewareStatus,
85
104
  mountedSlotsHeader: options.mountedSlotsHeader,
86
105
  revalidateSeconds: options.revalidateSeconds
87
106
  });
@@ -93,13 +112,13 @@ async function readAppPageCacheResponse(options) {
93
112
  options.isrDebug?.("MISS (empty cached entry)", options.cleanPathname);
94
113
  }
95
114
  if (cached?.isStale && cachedValue) {
96
- const regenerationKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader) : options.isrHtmlKey(options.cleanPathname);
115
+ const regenerationKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode) : options.isrHtmlKey(options.cleanPathname);
97
116
  options.scheduleBackgroundRegeneration(regenerationKey, async () => {
98
117
  const revalidatedPage = await options.renderFreshPageForCache();
99
118
  const revalidateSeconds = revalidatedPage.cacheControl?.revalidate ?? options.revalidateSeconds;
100
119
  const expireSeconds = revalidatedPage.cacheControl?.expire ?? options.expireSeconds;
101
- const writes = [options.isrSet(options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader), buildAppPageCacheValue("", revalidatedPage.rscData, 200), revalidateSeconds, revalidatedPage.tags, expireSeconds)];
102
- if (!options.isRscRequest) writes.push(options.isrSet(options.isrHtmlKey(options.cleanPathname), buildAppPageCacheValue(revalidatedPage.html, void 0, 200), revalidateSeconds, revalidatedPage.tags, expireSeconds));
120
+ const writes = [options.isrSet(options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode), buildAppPageCacheValue("", revalidatedPage.rscData, 200, revalidatedPage.rscRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds)];
121
+ if (!options.isRscRequest) writes.push(options.isrSet(options.isrHtmlKey(options.cleanPathname), buildAppPageCacheValue(revalidatedPage.html, void 0, 200, revalidatedPage.htmlRenderObservation), revalidateSeconds, revalidatedPage.tags, expireSeconds));
103
122
  await Promise.all(writes);
104
123
  options.isrDebug?.("regen complete", options.cleanPathname);
105
124
  });
@@ -108,6 +127,8 @@ async function readAppPageCacheResponse(options) {
108
127
  cacheControl: cached.value.cacheControl,
109
128
  expireSeconds: options.expireSeconds,
110
129
  isRscRequest: options.isRscRequest,
130
+ middlewareHeaders: options.middlewareHeaders,
131
+ middlewareStatus: options.middlewareStatus,
111
132
  mountedSlotsHeader: options.mountedSlotsHeader,
112
133
  revalidateSeconds: options.revalidateSeconds
113
134
  });
@@ -132,7 +153,7 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
132
153
  const clientHeaders = new Headers(response.headers);
133
154
  if (options.preserveClientResponseHeaders !== true) {
134
155
  clientHeaders.set("Cache-Control", NO_STORE_CACHE_CONTROL);
135
- clientHeaders.set("X-Vinext-Cache", "MISS");
156
+ clientHeaders.set(VINEXT_CACHE_HEADER, "MISS");
136
157
  }
137
158
  const cachePromise = (async () => {
138
159
  try {
@@ -151,8 +172,17 @@ function finalizeAppPageHtmlCacheResponse(response, options) {
151
172
  return;
152
173
  }
153
174
  const pageTags = options.getPageTags();
154
- const writes = [options.isrSet(htmlKey, buildAppPageCacheValue(cachedHtml, void 0, 200), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)];
155
- if (options.capturedRscDataPromise) writes.push(options.capturedRscDataPromise.then((rscData) => options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)));
175
+ const observationState = options.consumeRenderObservationState?.() ?? createEmptyAppPageRenderObservationState();
176
+ const htmlRenderObservation = options.createHtmlRenderObservation?.({
177
+ cacheTags: pageTags,
178
+ state: observationState
179
+ });
180
+ const rscRenderObservation = options.createRscRenderObservation?.({
181
+ cacheTags: pageTags,
182
+ state: observationState
183
+ });
184
+ const writes = [options.isrSet(htmlKey, buildAppPageCacheValue(cachedHtml, void 0, 200, htmlRenderObservation), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)];
185
+ if (options.capturedRscDataPromise) writes.push(options.capturedRscDataPromise.then((rscData) => options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200, rscRenderObservation), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)));
156
186
  await Promise.all(writes);
157
187
  options.isrDebug?.("HTML cache written", htmlKey);
158
188
  } catch (cacheError) {
@@ -171,7 +201,7 @@ function finalizeAppPageRscCacheResponse(response, options) {
171
201
  if (options.preserveClientResponseHeaders === true) return response;
172
202
  const clientHeaders = new Headers(response.headers);
173
203
  clientHeaders.set("Cache-Control", NO_STORE_CACHE_CONTROL);
174
- clientHeaders.set("X-Vinext-Cache", "MISS");
204
+ clientHeaders.set(VINEXT_CACHE_HEADER, "MISS");
175
205
  return new Response(response.body, {
176
206
  status: response.status,
177
207
  statusText: response.statusText,
@@ -181,7 +211,7 @@ function finalizeAppPageRscCacheResponse(response, options) {
181
211
  function scheduleAppPageRscCacheWrite(options) {
182
212
  const capturedRscDataPromise = options.capturedRscDataPromise;
183
213
  if (!capturedRscDataPromise || options.dynamicUsedDuringBuild) return false;
184
- const rscKey = options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader);
214
+ const rscKey = options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode);
185
215
  const cachePromise = (async () => {
186
216
  try {
187
217
  const rscData = await capturedRscDataPromise;
@@ -198,7 +228,13 @@ function scheduleAppPageRscCacheWrite(options) {
198
228
  options.isrDebug?.("RSC cache write skipped (no cache policy)", rscKey);
199
229
  return;
200
230
  }
201
- await options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200), cachePolicy.revalidateSeconds, options.getPageTags(), cachePolicy.expireSeconds);
231
+ const pageTags = options.getPageTags();
232
+ const observationState = options.consumeRenderObservationState?.() ?? createEmptyAppPageRenderObservationState();
233
+ const rscRenderObservation = options.createRscRenderObservation?.({
234
+ cacheTags: pageTags,
235
+ state: observationState
236
+ });
237
+ await options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200, rscRenderObservation), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds);
202
238
  options.isrDebug?.("RSC cache written", rscKey);
203
239
  } catch (cacheError) {
204
240
  console.error("[vinext] ISR RSC cache write error:", cacheError);