vinext 0.0.49 → 0.0.50

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 (390) 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/get-axes.js.map +1 -1
  4. package/dist/build/google-fonts/sort-variants.js.map +1 -1
  5. package/dist/build/google-fonts/validate.js.map +1 -1
  6. package/dist/build/layout-classification.js.map +1 -1
  7. package/dist/build/nitro-route-rules.js.map +1 -1
  8. package/dist/build/precompress.js.map +1 -1
  9. package/dist/build/prerender.d.ts +17 -1
  10. package/dist/build/prerender.js +77 -16
  11. package/dist/build/prerender.js.map +1 -1
  12. package/dist/build/report.js.map +1 -1
  13. package/dist/build/route-classification-injector.js.map +1 -1
  14. package/dist/build/route-classification-manifest.js.map +1 -1
  15. package/dist/build/run-prerender.js.map +1 -1
  16. package/dist/build/server-manifest.js.map +1 -1
  17. package/dist/build/ssr-manifest.js.map +1 -1
  18. package/dist/build/standalone.js.map +1 -1
  19. package/dist/build/static-export.js.map +1 -1
  20. package/dist/check.js +1 -1
  21. package/dist/check.js.map +1 -1
  22. package/dist/cli-args.js.map +1 -1
  23. package/dist/cli.js +8 -4
  24. package/dist/cli.js.map +1 -1
  25. package/dist/client/instrumentation-client-state.js.map +1 -1
  26. package/dist/client/validate-module-path.js.map +1 -1
  27. package/dist/client/vinext-next-data.d.ts +5 -1
  28. package/dist/client/window-next.d.ts +149 -0
  29. package/dist/client/window-next.js +48 -0
  30. package/dist/client/window-next.js.map +1 -0
  31. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  32. package/dist/cloudflare/tpr.js +2 -1
  33. package/dist/cloudflare/tpr.js.map +1 -1
  34. package/dist/config/config-matchers.d.ts +3 -1
  35. package/dist/config/config-matchers.js +5 -4
  36. package/dist/config/config-matchers.js.map +1 -1
  37. package/dist/config/dotenv.js.map +1 -1
  38. package/dist/config/next-config.d.ts +6 -3
  39. package/dist/config/next-config.js +13 -2
  40. package/dist/config/next-config.js.map +1 -1
  41. package/dist/deploy.js +13 -5
  42. package/dist/deploy.js.map +1 -1
  43. package/dist/entries/app-browser-entry.d.ts +3 -1
  44. package/dist/entries/app-browser-entry.js +11 -2
  45. package/dist/entries/app-browser-entry.js.map +1 -1
  46. package/dist/entries/app-rsc-entry.js +11 -0
  47. package/dist/entries/app-rsc-entry.js.map +1 -1
  48. package/dist/entries/app-rsc-manifest.js +4 -0
  49. package/dist/entries/app-rsc-manifest.js.map +1 -1
  50. package/dist/entries/app-ssr-entry.js.map +1 -1
  51. package/dist/entries/pages-client-entry.js.map +1 -1
  52. package/dist/entries/pages-entry-helpers.js.map +1 -1
  53. package/dist/entries/pages-server-entry.js +15 -0
  54. package/dist/entries/pages-server-entry.js.map +1 -1
  55. package/dist/entries/runtime-entry-module.js.map +1 -1
  56. package/dist/index.js +76 -18
  57. package/dist/index.js.map +1 -1
  58. package/dist/init.js.map +1 -1
  59. package/dist/plugins/async-hooks-stub.js.map +1 -1
  60. package/dist/plugins/client-reference-dedup.js.map +1 -1
  61. package/dist/plugins/fonts.js.map +1 -1
  62. package/dist/plugins/instrumentation-client.js.map +1 -1
  63. package/dist/plugins/og-assets.js.map +1 -1
  64. package/dist/plugins/optimize-imports.js.map +1 -1
  65. package/dist/plugins/postcss.js.map +1 -1
  66. package/dist/plugins/rsc-client-reference-loaders.d.ts +7 -0
  67. package/dist/plugins/rsc-client-reference-loaders.js +48 -0
  68. package/dist/plugins/rsc-client-reference-loaders.js.map +1 -0
  69. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
  70. package/dist/plugins/server-externals-manifest.js.map +1 -1
  71. package/dist/plugins/strip-server-exports.js.map +1 -1
  72. package/dist/routing/app-route-graph.d.ts +48 -5
  73. package/dist/routing/app-route-graph.js +159 -15
  74. package/dist/routing/app-route-graph.js.map +1 -1
  75. package/dist/routing/app-router.js.map +1 -1
  76. package/dist/routing/file-matcher.js.map +1 -1
  77. package/dist/routing/pages-router.js.map +1 -1
  78. package/dist/routing/route-matching.js.map +1 -1
  79. package/dist/routing/route-pattern.js.map +1 -1
  80. package/dist/routing/route-trie.js.map +1 -1
  81. package/dist/routing/route-validation.js.map +1 -1
  82. package/dist/routing/utils.js.map +1 -1
  83. package/dist/server/api-handler.js.map +1 -1
  84. package/dist/server/app-browser-action-result.d.ts +19 -0
  85. package/dist/server/app-browser-action-result.js +18 -0
  86. package/dist/server/app-browser-action-result.js.map +1 -0
  87. package/dist/server/app-browser-entry.js +91 -48
  88. package/dist/server/app-browser-entry.js.map +1 -1
  89. package/dist/server/app-browser-error.js.map +1 -1
  90. package/dist/server/app-browser-hydration.d.ts +19 -0
  91. package/dist/server/app-browser-hydration.js +22 -0
  92. package/dist/server/app-browser-hydration.js.map +1 -0
  93. package/dist/server/app-browser-navigation-controller.d.ts +6 -3
  94. package/dist/server/app-browser-navigation-controller.js +67 -19
  95. package/dist/server/app-browser-navigation-controller.js.map +1 -1
  96. package/dist/server/app-browser-state.d.ts +17 -17
  97. package/dist/server/app-browser-state.js +122 -36
  98. package/dist/server/app-browser-state.js.map +1 -1
  99. package/dist/server/app-browser-stream.d.ts +4 -0
  100. package/dist/server/app-browser-stream.js +24 -2
  101. package/dist/server/app-browser-stream.js.map +1 -1
  102. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  103. package/dist/server/app-browser-visible-commit.js +34 -19
  104. package/dist/server/app-browser-visible-commit.js.map +1 -1
  105. package/dist/server/app-client-reference-preloader.js.map +1 -1
  106. package/dist/server/app-elements-wire.d.ts +6 -1
  107. package/dist/server/app-elements-wire.js +17 -1
  108. package/dist/server/app-elements-wire.js.map +1 -1
  109. package/dist/server/app-elements.d.ts +2 -2
  110. package/dist/server/app-elements.js +2 -2
  111. package/dist/server/app-elements.js.map +1 -1
  112. package/dist/server/app-fallback-renderer.js.map +1 -1
  113. package/dist/server/app-hook-warning-suppression.js.map +1 -1
  114. package/dist/server/app-middleware.d.ts +1 -1
  115. package/dist/server/app-middleware.js +4 -9
  116. package/dist/server/app-middleware.js.map +1 -1
  117. package/dist/server/app-mounted-slots-header.js.map +1 -1
  118. package/dist/server/app-page-boundary-render.d.ts +1 -0
  119. package/dist/server/app-page-boundary-render.js +14 -13
  120. package/dist/server/app-page-boundary-render.js.map +1 -1
  121. package/dist/server/app-page-boundary.d.ts +1 -0
  122. package/dist/server/app-page-boundary.js +7 -5
  123. package/dist/server/app-page-boundary.js.map +1 -1
  124. package/dist/server/app-page-cache.d.ts +10 -3
  125. package/dist/server/app-page-cache.js +42 -23
  126. package/dist/server/app-page-cache.js.map +1 -1
  127. package/dist/server/app-page-dispatch.d.ts +6 -1
  128. package/dist/server/app-page-dispatch.js +21 -7
  129. package/dist/server/app-page-dispatch.js.map +1 -1
  130. package/dist/server/app-page-element-builder.d.ts +3 -1
  131. package/dist/server/app-page-element-builder.js +6 -2
  132. package/dist/server/app-page-element-builder.js.map +1 -1
  133. package/dist/server/app-page-execution.js.map +1 -1
  134. package/dist/server/app-page-head.js +4 -0
  135. package/dist/server/app-page-head.js.map +1 -1
  136. package/dist/server/app-page-method.js.map +1 -1
  137. package/dist/server/app-page-params.js.map +1 -1
  138. package/dist/server/app-page-probe.js.map +1 -1
  139. package/dist/server/app-page-render.d.ts +7 -1
  140. package/dist/server/app-page-render.js +11 -4
  141. package/dist/server/app-page-render.js.map +1 -1
  142. package/dist/server/app-page-request.js +2 -1
  143. package/dist/server/app-page-request.js.map +1 -1
  144. package/dist/server/app-page-response.d.ts +2 -0
  145. package/dist/server/app-page-response.js +15 -5
  146. package/dist/server/app-page-response.js.map +1 -1
  147. package/dist/server/app-page-route-wiring.d.ts +6 -2
  148. package/dist/server/app-page-route-wiring.js +50 -49
  149. package/dist/server/app-page-route-wiring.js.map +1 -1
  150. package/dist/server/app-page-segment-state.d.ts +10 -0
  151. package/dist/server/app-page-segment-state.js +87 -0
  152. package/dist/server/app-page-segment-state.js.map +1 -0
  153. package/dist/server/app-page-stream.d.ts +7 -2
  154. package/dist/server/app-page-stream.js +3 -1
  155. package/dist/server/app-page-stream.js.map +1 -1
  156. package/dist/server/app-post-middleware-context.js.map +1 -1
  157. package/dist/server/app-prerender-endpoints.js.map +1 -1
  158. package/dist/server/app-prerender-static-params.js.map +1 -1
  159. package/dist/server/app-render-dependency.js.map +1 -1
  160. package/dist/server/app-request-context.js.map +1 -1
  161. package/dist/server/app-route-handler-cache.js.map +1 -1
  162. package/dist/server/app-route-handler-dispatch.js +3 -1
  163. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  164. package/dist/server/app-route-handler-execution.js.map +1 -1
  165. package/dist/server/app-route-handler-policy.js +1 -0
  166. package/dist/server/app-route-handler-policy.js.map +1 -1
  167. package/dist/server/app-route-handler-response.js +4 -3
  168. package/dist/server/app-route-handler-response.js.map +1 -1
  169. package/dist/server/app-route-handler-runtime.js.map +1 -1
  170. package/dist/server/app-router-entry.js +6 -2
  171. package/dist/server/app-router-entry.js.map +1 -1
  172. package/dist/server/app-rsc-cache-busting.d.ts +5 -2
  173. package/dist/server/app-rsc-cache-busting.js +40 -19
  174. package/dist/server/app-rsc-cache-busting.js.map +1 -1
  175. package/dist/server/app-rsc-error-handler.js.map +1 -1
  176. package/dist/server/app-rsc-errors.js.map +1 -1
  177. package/dist/server/app-rsc-handler.d.ts +10 -1
  178. package/dist/server/app-rsc-handler.js +51 -17
  179. package/dist/server/app-rsc-handler.js.map +1 -1
  180. package/dist/server/app-rsc-render-mode.d.ts +11 -0
  181. package/dist/server/app-rsc-render-mode.js +21 -0
  182. package/dist/server/app-rsc-render-mode.js.map +1 -0
  183. package/dist/server/app-rsc-request-normalization.d.ts +4 -1
  184. package/dist/server/app-rsc-request-normalization.js +7 -2
  185. package/dist/server/app-rsc-request-normalization.js.map +1 -1
  186. package/dist/server/app-rsc-response-finalizer.d.ts +2 -1
  187. package/dist/server/app-rsc-response-finalizer.js +6 -1
  188. package/dist/server/app-rsc-response-finalizer.js.map +1 -1
  189. package/dist/server/app-rsc-route-matching.js.map +1 -1
  190. package/dist/server/app-segment-config.js.map +1 -1
  191. package/dist/server/app-server-action-execution.d.ts +16 -2
  192. package/dist/server/app-server-action-execution.js +79 -23
  193. package/dist/server/app-server-action-execution.js.map +1 -1
  194. package/dist/server/app-ssr-entry.d.ts +6 -0
  195. package/dist/server/app-ssr-entry.js +10 -4
  196. package/dist/server/app-ssr-entry.js.map +1 -1
  197. package/dist/server/app-ssr-stream.js.map +1 -1
  198. package/dist/server/app-static-generation.js.map +1 -1
  199. package/dist/server/artifact-compatibility.js.map +1 -1
  200. package/dist/server/cache-control.js +1 -0
  201. package/dist/server/cache-control.js.map +1 -1
  202. package/dist/server/cache-proof.js.map +1 -1
  203. package/dist/server/csp.js.map +1 -1
  204. package/dist/server/dev-error-overlay-store.js.map +1 -1
  205. package/dist/server/dev-error-overlay.js +5 -0
  206. package/dist/server/dev-error-overlay.js.map +1 -1
  207. package/dist/server/dev-module-runner.js.map +1 -1
  208. package/dist/server/dev-origin-check.js.map +1 -1
  209. package/dist/server/dev-route-files.js.map +1 -1
  210. package/dist/server/dev-server.js +8 -5
  211. package/dist/server/dev-server.js.map +1 -1
  212. package/dist/server/file-based-metadata.js.map +1 -1
  213. package/dist/server/headers.d.ts +79 -0
  214. package/dist/server/headers.js +101 -0
  215. package/dist/server/headers.js.map +1 -0
  216. package/dist/server/html.js.map +1 -1
  217. package/dist/server/http-error-responses.js.map +1 -1
  218. package/dist/server/image-optimization.d.ts +11 -1
  219. package/dist/server/image-optimization.js.map +1 -1
  220. package/dist/server/implicit-tags.js +2 -1
  221. package/dist/server/implicit-tags.js.map +1 -1
  222. package/dist/server/instrumentation-runtime.js.map +1 -1
  223. package/dist/server/instrumentation.js.map +1 -1
  224. package/dist/server/isr-cache.d.ts +10 -1
  225. package/dist/server/isr-cache.js +12 -3
  226. package/dist/server/isr-cache.js.map +1 -1
  227. package/dist/server/metadata-route-build-data.js.map +1 -1
  228. package/dist/server/metadata-route-response.js.map +1 -1
  229. package/dist/server/metadata-routes.js.map +1 -1
  230. package/dist/server/middleware-matcher.js.map +1 -1
  231. package/dist/server/middleware-request-headers.d.ts +4 -1
  232. package/dist/server/middleware-request-headers.js +15 -8
  233. package/dist/server/middleware-request-headers.js.map +1 -1
  234. package/dist/server/middleware-response-headers.d.ts +2 -1
  235. package/dist/server/middleware-response-headers.js +1 -1
  236. package/dist/server/middleware-response-headers.js.map +1 -1
  237. package/dist/server/middleware-runtime.d.ts +1 -0
  238. package/dist/server/middleware-runtime.js +6 -3
  239. package/dist/server/middleware-runtime.js.map +1 -1
  240. package/dist/server/middleware.js.map +1 -1
  241. package/dist/server/navigation-planner.d.ts +119 -0
  242. package/dist/server/navigation-planner.js +171 -0
  243. package/dist/server/navigation-planner.js.map +1 -0
  244. package/dist/server/navigation-trace.d.ts +12 -2
  245. package/dist/server/navigation-trace.js +13 -1
  246. package/dist/server/navigation-trace.js.map +1 -1
  247. package/dist/server/next-error-digest.d.ts +3 -2
  248. package/dist/server/next-error-digest.js +4 -2
  249. package/dist/server/next-error-digest.js.map +1 -1
  250. package/dist/server/normalize-path.js.map +1 -1
  251. package/dist/server/pages-api-route.js.map +1 -1
  252. package/dist/server/pages-i18n.js.map +1 -1
  253. package/dist/server/pages-media-type.js.map +1 -1
  254. package/dist/server/pages-node-compat.js.map +1 -1
  255. package/dist/server/pages-page-data.js +5 -2
  256. package/dist/server/pages-page-data.js.map +1 -1
  257. package/dist/server/pages-page-response.js +3 -2
  258. package/dist/server/pages-page-response.js.map +1 -1
  259. package/dist/server/prerender-work-unit-setup.js +1 -1
  260. package/dist/server/prerender-work-unit-setup.js.map +1 -1
  261. package/dist/server/prod-server.js +35 -13
  262. package/dist/server/prod-server.js.map +1 -1
  263. package/dist/server/request-log.js.map +1 -1
  264. package/dist/server/request-pipeline.d.ts +1 -13
  265. package/dist/server/request-pipeline.js +3 -25
  266. package/dist/server/request-pipeline.js.map +1 -1
  267. package/dist/server/rsc-stream-hints.js.map +1 -1
  268. package/dist/server/seed-cache.js.map +1 -1
  269. package/dist/server/server-action-not-found.js +3 -3
  270. package/dist/server/server-action-not-found.js.map +1 -1
  271. package/dist/server/socket-error-backstop.js.map +1 -1
  272. package/dist/server/static-file-cache.js.map +1 -1
  273. package/dist/server/worker-utils.d.ts +0 -7
  274. package/dist/server/worker-utils.js +3 -2
  275. package/dist/server/worker-utils.js.map +1 -1
  276. package/dist/shims/amp.js.map +1 -1
  277. package/dist/shims/app.d.ts +37 -4
  278. package/dist/shims/app.js +50 -1
  279. package/dist/shims/app.js.map +1 -0
  280. package/dist/shims/cache-for-request.js.map +1 -1
  281. package/dist/shims/cache-runtime.js +20 -8
  282. package/dist/shims/cache-runtime.js.map +1 -1
  283. package/dist/shims/cache.d.ts +15 -3
  284. package/dist/shims/cache.js +99 -15
  285. package/dist/shims/cache.js.map +1 -1
  286. package/dist/shims/client-hook-error.js.map +1 -1
  287. package/dist/shims/compat-router.js.map +1 -1
  288. package/dist/shims/config.js.map +1 -1
  289. package/dist/shims/constants.js.map +1 -1
  290. package/dist/shims/document.js.map +1 -1
  291. package/dist/shims/dynamic.d.ts +18 -10
  292. package/dist/shims/dynamic.js +107 -51
  293. package/dist/shims/dynamic.js.map +1 -1
  294. package/dist/shims/error-boundary.d.ts +35 -6
  295. package/dist/shims/error-boundary.js +118 -33
  296. package/dist/shims/error-boundary.js.map +1 -1
  297. package/dist/shims/error.js.map +1 -1
  298. package/dist/shims/fetch-cache.d.ts +22 -1
  299. package/dist/shims/fetch-cache.js +124 -13
  300. package/dist/shims/fetch-cache.js.map +1 -1
  301. package/dist/shims/font-google-base.js.map +1 -1
  302. package/dist/shims/font-local.js.map +1 -1
  303. package/dist/shims/form.js +3 -1
  304. package/dist/shims/form.js.map +1 -1
  305. package/dist/shims/head-state.js.map +1 -1
  306. package/dist/shims/head.d.ts +3 -1
  307. package/dist/shims/head.js +28 -16
  308. package/dist/shims/head.js.map +1 -1
  309. package/dist/shims/headers.d.ts +4 -2
  310. package/dist/shims/headers.js +24 -7
  311. package/dist/shims/headers.js.map +1 -1
  312. package/dist/shims/i18n-context.js.map +1 -1
  313. package/dist/shims/i18n-state.js.map +1 -1
  314. package/dist/shims/image-config.d.ts +14 -1
  315. package/dist/shims/image-config.js +24 -1
  316. package/dist/shims/image-config.js.map +1 -1
  317. package/dist/shims/image.js +15 -2
  318. package/dist/shims/image.js.map +1 -1
  319. package/dist/shims/internal/als-registry.js.map +1 -1
  320. package/dist/shims/internal/app-router-context.d.ts +1 -0
  321. package/dist/shims/internal/app-router-context.js.map +1 -1
  322. package/dist/shims/internal/cookie-serialize.js.map +1 -1
  323. package/dist/shims/internal/make-hanging-promise.d.ts +1 -1
  324. package/dist/shims/internal/make-hanging-promise.js +1 -1
  325. package/dist/shims/internal/make-hanging-promise.js.map +1 -1
  326. package/dist/shims/internal/parse-cookie-header.js.map +1 -1
  327. package/dist/shims/internal/utils.js.map +1 -1
  328. package/dist/shims/internal/work-unit-async-storage.js +2 -2
  329. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  330. package/dist/shims/layout-segment-context.js.map +1 -1
  331. package/dist/shims/legacy-image.js.map +1 -1
  332. package/dist/shims/link-prefetch.d.ts +34 -0
  333. package/dist/shims/link-prefetch.js +40 -0
  334. package/dist/shims/link-prefetch.js.map +1 -0
  335. package/dist/shims/link.d.ts +27 -4
  336. package/dist/shims/link.js +91 -27
  337. package/dist/shims/link.js.map +1 -1
  338. package/dist/shims/metadata.js.map +1 -1
  339. package/dist/shims/navigation-state.js.map +1 -1
  340. package/dist/shims/navigation.d.ts +22 -1
  341. package/dist/shims/navigation.js +30 -15
  342. package/dist/shims/navigation.js.map +1 -1
  343. package/dist/shims/navigation.react-server.js.map +1 -1
  344. package/dist/shims/offline.js.map +1 -1
  345. package/dist/shims/readonly-url-search-params.js.map +1 -1
  346. package/dist/shims/request-context.js.map +1 -1
  347. package/dist/shims/root-params.js.map +1 -1
  348. package/dist/shims/router-state.js.map +1 -1
  349. package/dist/shims/router.d.ts +38 -2
  350. package/dist/shims/router.js +45 -17
  351. package/dist/shims/router.js.map +1 -1
  352. package/dist/shims/script-nonce-context.js.map +1 -1
  353. package/dist/shims/script.js.map +1 -1
  354. package/dist/shims/server.js +10 -14
  355. package/dist/shims/server.js.map +1 -1
  356. package/dist/shims/slot.d.ts +6 -1
  357. package/dist/shims/slot.js +20 -7
  358. package/dist/shims/slot.js.map +1 -1
  359. package/dist/shims/thenable-params.js.map +1 -1
  360. package/dist/shims/unified-request-context.js +3 -0
  361. package/dist/shims/unified-request-context.js.map +1 -1
  362. package/dist/shims/url-safety.js.map +1 -1
  363. package/dist/shims/url-utils.d.ts +2 -1
  364. package/dist/shims/url-utils.js +10 -1
  365. package/dist/shims/url-utils.js.map +1 -1
  366. package/dist/shims/use-merged-ref.js.map +1 -1
  367. package/dist/shims/web-vitals.d.ts +4 -21
  368. package/dist/shims/web-vitals.js +19 -6
  369. package/dist/shims/web-vitals.js.map +1 -1
  370. package/dist/utils/base-path.js.map +1 -1
  371. package/dist/utils/cache-control-metadata.js.map +1 -1
  372. package/dist/utils/domain-locale.js.map +1 -1
  373. package/dist/utils/encode-cache-tag.d.ts +31 -0
  374. package/dist/utils/encode-cache-tag.js +38 -0
  375. package/dist/utils/encode-cache-tag.js.map +1 -0
  376. package/dist/utils/error-cause.js.map +1 -1
  377. package/dist/utils/hash.js.map +1 -1
  378. package/dist/utils/lazy-chunks.js.map +1 -1
  379. package/dist/utils/manifest-paths.js.map +1 -1
  380. package/dist/utils/mdx-scan.js.map +1 -1
  381. package/dist/utils/navigation-signal.d.ts +6 -0
  382. package/dist/utils/navigation-signal.js +14 -0
  383. package/dist/utils/navigation-signal.js.map +1 -0
  384. package/dist/utils/project.js.map +1 -1
  385. package/dist/utils/public-routes.js.map +1 -1
  386. package/dist/utils/query.js.map +1 -1
  387. package/dist/utils/safe-json-file.js.map +1 -1
  388. package/dist/utils/text-stream.js.map +1 -1
  389. package/dist/utils/vinext-root.js.map +1 -1
  390. package/package.json +6 -4
@@ -5,7 +5,7 @@ import { createPendingNavigationCommit, resolvePendingNavigationCommitDispositio
5
5
  const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
6
6
  function applyApprovedVisibleCommit(state, commit) {
7
7
  assertApprovedVisibleCommit(commit);
8
- return reduceApprovedVisibleCommitState(state, commit.action);
8
+ return reduceApprovedVisibleCommitState(state, commit);
9
9
  }
10
10
  function assertApprovedVisibleCommit(commit) {
11
11
  if (commit[approvedVisibleCommitBrand] !== true) throw new Error("[vinext] Visible router state mutation requires ApprovedVisibleCommit");
@@ -27,16 +27,19 @@ function commitVisibleRouterState(state, nextState, operation) {
27
27
  visibleCommitVersion
28
28
  };
29
29
  }
30
- function reduceApprovedVisibleCommitState(state, action) {
30
+ function reduceApprovedVisibleCommitState(state, commit) {
31
+ const { action } = commit;
31
32
  switch (action.type) {
32
33
  case "traverse":
33
34
  case "navigate": return commitVisibleRouterState(state, {
34
- elements: mergeElements(state.elements, action.elements, action.type === "traverse"),
35
+ elements: mergeElements(state.elements, action.elements, {
36
+ clearAbsentSlots: action.type === "traverse",
37
+ preserveAbsentSlots: commit.decision.preserveAbsentSlots,
38
+ preserveElementIds: commit.decision.preserveElementIds
39
+ }),
35
40
  interceptionContext: action.interceptionContext,
36
- layoutFlags: {
37
- ...state.layoutFlags,
38
- ...action.layoutFlags
39
- },
41
+ layoutFlags: mergeLayoutFlags(state.layoutFlags, action.layoutFlags, commit.decision.preserveElementIds),
42
+ layoutIds: action.layoutIds,
40
43
  navigationSnapshot: action.navigationSnapshot,
41
44
  previousNextUrl: action.previousNextUrl,
42
45
  renderId: action.renderId,
@@ -47,6 +50,7 @@ function reduceApprovedVisibleCommitState(state, action) {
47
50
  elements: action.elements,
48
51
  interceptionContext: action.interceptionContext,
49
52
  layoutFlags: action.layoutFlags,
53
+ layoutIds: action.layoutIds,
50
54
  navigationSnapshot: action.navigationSnapshot,
51
55
  previousNextUrl: action.previousNextUrl,
52
56
  renderId: action.renderId,
@@ -60,26 +64,37 @@ function reduceApprovedVisibleCommitState(state, action) {
60
64
  }
61
65
  }
62
66
  function resolvePendingNavigationCommitDecision(options) {
63
- const { disposition, trace } = resolvePendingNavigationCommitDispositionDecision(options);
64
- switch (disposition) {
67
+ const decision = resolvePendingNavigationCommitDispositionDecision(options);
68
+ switch (decision.disposition) {
65
69
  case "skip": return {
66
70
  disposition: "no-commit",
67
- trace
71
+ trace: decision.trace
68
72
  };
69
73
  case "hard-navigate": return {
70
74
  disposition: "hard-navigate",
71
- trace
75
+ trace: decision.trace
72
76
  };
73
- case "dispatch": return createVisibleCommitDecision(trace);
74
- default: throw new Error("[vinext] Unknown navigation commit disposition: " + String(disposition));
77
+ case "dispatch": return createVisibleCommitDecision(decision.trace, decision.preserveElementIds, decision.preserveAbsentSlots);
78
+ default: throw new Error("[vinext] Unknown navigation commit disposition: " + String(decision));
75
79
  }
76
80
  }
77
- function createVisibleCommitDecision(trace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent)) {
81
+ function createVisibleCommitDecision(trace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent), preserveElementIds = [], preserveAbsentSlots = false) {
78
82
  return {
79
83
  disposition: "commit",
84
+ preserveAbsentSlots,
85
+ preserveElementIds: [...preserveElementIds],
80
86
  trace
81
87
  };
82
88
  }
89
+ function mergeLayoutFlags(previousFlags, nextFlags, preserveElementIds) {
90
+ const merged = { ...nextFlags };
91
+ for (const id of preserveElementIds) {
92
+ if (Object.hasOwn(merged, id)) continue;
93
+ const value = previousFlags[id];
94
+ if (value) merged[id] = value;
95
+ }
96
+ return merged;
97
+ }
83
98
  function createApprovedVisibleCommit(options) {
84
99
  return {
85
100
  [approvedVisibleCommitBrand]: true,
@@ -130,11 +145,10 @@ function approveHmrVisibleCommit(pending) {
130
145
  function approvePendingNavigationCommit(options) {
131
146
  const decision = addCommitTransactionTrace(resolvePendingNavigationCommitDecision({
132
147
  activeNavigationId: options.activeNavigationId,
133
- currentVisibleCommitVersion: options.currentState.visibleCommitVersion,
134
- currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,
135
- nextRootLayoutTreePath: options.pending.rootLayoutTreePath,
148
+ currentState: options.currentState,
149
+ pending: options.pending,
136
150
  startedNavigationId: options.startedNavigationId,
137
- startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion
151
+ targetHref: options.targetHref
138
152
  }), options.pending);
139
153
  switch (decision.disposition) {
140
154
  case "commit": return {
@@ -167,7 +181,8 @@ async function resolveAndClassifyNavigationCommit(options) {
167
181
  activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,
168
182
  currentState: approvalState,
169
183
  pending,
170
- startedNavigationId: options.startedNavigationId
184
+ startedNavigationId: options.startedNavigationId,
185
+ targetHref: options.targetHref
171
186
  });
172
187
  return {
173
188
  approvedCommit: approval.approvedCommit,
@@ -1 +1 @@
1
- {"version":3,"file":"app-browser-visible-commit.js","names":[],"sources":["../../src/server/app-browser-visible-commit.ts"],"sourcesContent":["import type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport { mergeElements } from \"vinext/shims/slot\";\nimport type { AppElements } from \"./app-elements.js\";\nimport {\n createPendingNavigationCommit,\n resolvePendingNavigationCommitDispositionDecision,\n type AppRouterAction,\n type AppRouterState,\n type CommittedOperationRecord,\n type OperationLane,\n type PendingNavigationCommit,\n type PendingOperationRecord,\n} from \"./app-browser-state.js\";\nimport {\n NavigationTraceReasonCodes,\n NavigationTraceTransactionCodes,\n createNavigationTrace,\n prependNavigationTraceEntry,\n type NavigationTrace,\n type NavigationTraceFields,\n type NavigationTraceTransactionCode,\n} from \"./navigation-trace.js\";\n\ntype VisibleCommitDecision = {\n disposition: \"commit\";\n trace: NavigationTrace;\n};\ntype HardNavigateCommitDecision = {\n disposition: \"hard-navigate\";\n trace: NavigationTrace;\n};\ntype NoCommitDecision = {\n disposition: \"no-commit\";\n trace: NavigationTrace;\n};\ntype CommitDecision = VisibleCommitDecision | HardNavigateCommitDecision | NoCommitDecision;\nconst approvedVisibleCommitBrand: unique symbol = Symbol(\"ApprovedVisibleCommit\");\nexport type ApprovedVisibleCommit = {\n readonly [approvedVisibleCommitBrand]: true;\n readonly action: AppRouterAction;\n readonly decision: VisibleCommitDecision;\n readonly interceptionContext: string | null;\n readonly previousNextUrl: string | null;\n readonly rootLayoutTreePath: string | null;\n readonly routeId: string;\n};\ntype VisibleCommitApproval = {\n approvedCommit: ApprovedVisibleCommit;\n decision: VisibleCommitDecision;\n};\ntype NonVisibleCommitApproval = {\n approvedCommit: null;\n decision: HardNavigateCommitDecision | NoCommitDecision;\n};\ntype CommitApproval = VisibleCommitApproval | NonVisibleCommitApproval;\ntype ClassifiedPendingNavigationCommit = {\n approvedCommit: ApprovedVisibleCommit | null;\n decision: CommitDecision;\n pending: PendingNavigationCommit;\n trace: NavigationTrace;\n};\n\nexport function applyApprovedVisibleCommit(\n state: AppRouterState,\n commit: ApprovedVisibleCommit,\n): AppRouterState {\n assertApprovedVisibleCommit(commit);\n return reduceApprovedVisibleCommitState(state, commit.action);\n}\n\nfunction assertApprovedVisibleCommit(commit: ApprovedVisibleCommit): void {\n if (commit[approvedVisibleCommitBrand] !== true) {\n throw new Error(\"[vinext] Visible router state mutation requires ApprovedVisibleCommit\");\n }\n}\n\nfunction commitOperationRecord(\n operation: PendingOperationRecord,\n visibleCommitVersion: number,\n): CommittedOperationRecord {\n return {\n id: operation.id,\n lane: operation.lane,\n startedVisibleCommitVersion: operation.startedVisibleCommitVersion,\n state: \"committed\",\n visibleCommitVersion,\n };\n}\n\nfunction commitVisibleRouterState(\n state: AppRouterState,\n nextState: Omit<AppRouterState, \"activeOperation\" | \"visibleCommitVersion\">,\n operation: PendingOperationRecord,\n): AppRouterState {\n // Single owner for visibleCommitVersion: only an ApprovedVisibleCommit may\n // advance it, and every accepted visible mutation advances it exactly once.\n const visibleCommitVersion = state.visibleCommitVersion + 1;\n return {\n ...nextState,\n activeOperation: commitOperationRecord(operation, visibleCommitVersion),\n visibleCommitVersion,\n };\n}\n\nfunction reduceApprovedVisibleCommitState(\n state: AppRouterState,\n action: AppRouterAction,\n): AppRouterState {\n switch (action.type) {\n case \"traverse\":\n case \"navigate\":\n return commitVisibleRouterState(\n state,\n {\n elements: mergeElements(state.elements, action.elements, action.type === \"traverse\"),\n interceptionContext: action.interceptionContext,\n layoutFlags: { ...state.layoutFlags, ...action.layoutFlags },\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n case \"replace\":\n return commitVisibleRouterState(\n state,\n {\n elements: action.elements,\n interceptionContext: action.interceptionContext,\n layoutFlags: action.layoutFlags,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n default: {\n const _exhaustive: never = action.type;\n throw new Error(\"[vinext] Unknown router action: \" + String(_exhaustive));\n }\n }\n}\n\nfunction resolvePendingNavigationCommitDecision(options: {\n activeNavigationId: number;\n currentVisibleCommitVersion: number;\n currentRootLayoutTreePath: string | null;\n nextRootLayoutTreePath: string | null;\n startedNavigationId: number;\n startedVisibleCommitVersion: number;\n}): CommitDecision {\n const { disposition, trace } = resolvePendingNavigationCommitDispositionDecision(options);\n\n switch (disposition) {\n case \"skip\":\n return { disposition: \"no-commit\", trace };\n case \"hard-navigate\":\n return { disposition: \"hard-navigate\", trace };\n case \"dispatch\":\n return createVisibleCommitDecision(trace);\n default: {\n const _exhaustive: never = disposition;\n throw new Error(\"[vinext] Unknown navigation commit disposition: \" + String(_exhaustive));\n }\n }\n}\n\nfunction createVisibleCommitDecision(\n trace: NavigationTrace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent),\n): VisibleCommitDecision {\n return { disposition: \"commit\", trace };\n}\n\nfunction createApprovedVisibleCommit(options: {\n decision: VisibleCommitDecision;\n pending: PendingNavigationCommit;\n}): ApprovedVisibleCommit {\n return {\n [approvedVisibleCommitBrand]: true,\n action: options.pending.action,\n decision: options.decision,\n interceptionContext: options.pending.interceptionContext,\n previousNextUrl: options.pending.previousNextUrl,\n rootLayoutTreePath: options.pending.rootLayoutTreePath,\n routeId: options.pending.routeId,\n };\n}\n\nfunction createCommitTransactionFields(pending: PendingNavigationCommit): NavigationTraceFields {\n return {\n operationLane: pending.action.operation.lane,\n pendingOperationId: pending.action.operation.id,\n startedVisibleCommitVersion: pending.action.operation.startedVisibleCommitVersion,\n };\n}\n\nfunction prependCommitTransactionTrace(\n trace: NavigationTrace,\n code: NavigationTraceTransactionCode,\n pending: PendingNavigationCommit,\n): NavigationTrace {\n return prependNavigationTraceEntry(trace, code, createCommitTransactionFields(pending));\n}\n\nfunction addCommitTransactionTrace(\n decision: CommitDecision,\n pending: PendingNavigationCommit,\n): CommitDecision {\n switch (decision.disposition) {\n case \"commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.visibleCommit,\n pending,\n ),\n };\n case \"hard-navigate\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.hardNavigate,\n pending,\n ),\n };\n case \"no-commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.noCommit,\n pending,\n ),\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport function approveHmrVisibleCommit(pending: PendingNavigationCommit): ApprovedVisibleCommit {\n if (pending.action.operation.lane !== \"hmr\") {\n throw new Error(\"[vinext] HMR visible commit approval requires an HMR pending operation\");\n }\n\n const decision = addCommitTransactionTrace(createVisibleCommitDecision(), pending);\n // This guard is a type narrowing assertion: createVisibleCommitDecision()\n // structurally produces a commit decision, and addCommitTransactionTrace()\n // must preserve that disposition while adding operator trace context.\n if (decision.disposition !== \"commit\") {\n throw new Error(\"[vinext] HMR visible commit approval did not produce a commit decision\");\n }\n\n return createApprovedVisibleCommit({\n decision,\n pending,\n });\n}\n\nexport function approvePendingNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n}): CommitApproval {\n const decision = addCommitTransactionTrace(\n resolvePendingNavigationCommitDecision({\n activeNavigationId: options.activeNavigationId,\n currentVisibleCommitVersion: options.currentState.visibleCommitVersion,\n currentRootLayoutTreePath: options.currentState.rootLayoutTreePath,\n nextRootLayoutTreePath: options.pending.rootLayoutTreePath,\n startedNavigationId: options.startedNavigationId,\n startedVisibleCommitVersion: options.pending.action.operation.startedVisibleCommitVersion,\n }),\n options.pending,\n );\n\n switch (decision.disposition) {\n case \"commit\":\n return {\n approvedCommit: createApprovedVisibleCommit({\n decision,\n pending: options.pending,\n }),\n decision,\n };\n case \"hard-navigate\":\n case \"no-commit\":\n return {\n approvedCommit: null,\n decision,\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function resolveAndClassifyNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n // When provided, these getters are called after awaiting nextElements so\n // approval uses the latest lifecycle authority instead of the call snapshot.\n getActiveNavigationId?: () => number;\n getCurrentStateForApproval?: () => AppRouterState;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n previousNextUrl?: string | null;\n renderId: number;\n startedNavigationId: number;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<ClassifiedPendingNavigationCommit> {\n const pending = await createPendingNavigationCommit({\n currentState: options.currentState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n operationLane: options.operationLane,\n previousNextUrl: options.previousNextUrl,\n renderId: options.renderId,\n type: options.type,\n });\n\n const approvalState = options.getCurrentStateForApproval?.() ?? options.currentState;\n const approval = approvePendingNavigationCommit({\n activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,\n currentState: approvalState,\n pending,\n startedNavigationId: options.startedNavigationId,\n });\n\n return {\n approvedCommit: approval.approvedCommit,\n decision: approval.decision,\n pending,\n trace: approval.decision.trace,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-browser-visible-commit.js","names":["_exhaustive"],"sources":["../../src/server/app-browser-visible-commit.ts"],"sourcesContent":["import type { ClientNavigationRenderSnapshot } from \"vinext/shims/navigation\";\nimport { mergeElements } from \"vinext/shims/slot\";\nimport type { AppElements } from \"./app-elements.js\";\nimport {\n createPendingNavigationCommit,\n resolvePendingNavigationCommitDispositionDecision,\n type AppRouterAction,\n type AppRouterState,\n type CommittedOperationRecord,\n type OperationLane,\n type PendingNavigationCommit,\n type PendingOperationRecord,\n} from \"./app-browser-state.js\";\nimport {\n NavigationTraceReasonCodes,\n NavigationTraceTransactionCodes,\n createNavigationTrace,\n prependNavigationTraceEntry,\n type NavigationTrace,\n type NavigationTraceFields,\n type NavigationTraceTransactionCode,\n} from \"./navigation-trace.js\";\n\ntype VisibleCommitDecision = {\n disposition: \"commit\";\n preserveAbsentSlots: boolean;\n preserveElementIds: readonly string[];\n trace: NavigationTrace;\n};\ntype HardNavigateCommitDecision = {\n disposition: \"hard-navigate\";\n trace: NavigationTrace;\n};\ntype NoCommitDecision = {\n disposition: \"no-commit\";\n trace: NavigationTrace;\n};\ntype CommitDecision = VisibleCommitDecision | HardNavigateCommitDecision | NoCommitDecision;\nconst approvedVisibleCommitBrand: unique symbol = Symbol(\"ApprovedVisibleCommit\");\nexport type ApprovedVisibleCommit = {\n readonly [approvedVisibleCommitBrand]: true;\n readonly action: AppRouterAction;\n readonly decision: VisibleCommitDecision;\n readonly interceptionContext: string | null;\n readonly previousNextUrl: string | null;\n readonly rootLayoutTreePath: string | null;\n readonly routeId: string;\n};\ntype VisibleCommitApproval = {\n approvedCommit: ApprovedVisibleCommit;\n decision: VisibleCommitDecision;\n};\ntype NonVisibleCommitApproval = {\n approvedCommit: null;\n decision: HardNavigateCommitDecision | NoCommitDecision;\n};\ntype CommitApproval = VisibleCommitApproval | NonVisibleCommitApproval;\ntype ClassifiedPendingNavigationCommit = {\n approvedCommit: ApprovedVisibleCommit | null;\n decision: CommitDecision;\n pending: PendingNavigationCommit;\n trace: NavigationTrace;\n};\n\nexport function applyApprovedVisibleCommit(\n state: AppRouterState,\n commit: ApprovedVisibleCommit,\n): AppRouterState {\n assertApprovedVisibleCommit(commit);\n return reduceApprovedVisibleCommitState(state, commit);\n}\n\nfunction assertApprovedVisibleCommit(commit: ApprovedVisibleCommit): void {\n if (commit[approvedVisibleCommitBrand] !== true) {\n throw new Error(\"[vinext] Visible router state mutation requires ApprovedVisibleCommit\");\n }\n}\n\nfunction commitOperationRecord(\n operation: PendingOperationRecord,\n visibleCommitVersion: number,\n): CommittedOperationRecord {\n return {\n id: operation.id,\n lane: operation.lane,\n startedVisibleCommitVersion: operation.startedVisibleCommitVersion,\n state: \"committed\",\n visibleCommitVersion,\n };\n}\n\nfunction commitVisibleRouterState(\n state: AppRouterState,\n nextState: Omit<AppRouterState, \"activeOperation\" | \"visibleCommitVersion\">,\n operation: PendingOperationRecord,\n): AppRouterState {\n // Single owner for visibleCommitVersion: only an ApprovedVisibleCommit may\n // advance it, and every accepted visible mutation advances it exactly once.\n const visibleCommitVersion = state.visibleCommitVersion + 1;\n return {\n ...nextState,\n activeOperation: commitOperationRecord(operation, visibleCommitVersion),\n visibleCommitVersion,\n };\n}\n\nfunction reduceApprovedVisibleCommitState(\n state: AppRouterState,\n commit: ApprovedVisibleCommit,\n): AppRouterState {\n const { action } = commit;\n switch (action.type) {\n case \"traverse\":\n case \"navigate\":\n return commitVisibleRouterState(\n state,\n {\n elements: mergeElements(state.elements, action.elements, {\n clearAbsentSlots: action.type === \"traverse\",\n preserveAbsentSlots: commit.decision.preserveAbsentSlots,\n preserveElementIds: commit.decision.preserveElementIds,\n }),\n interceptionContext: action.interceptionContext,\n layoutFlags: mergeLayoutFlags(\n state.layoutFlags,\n action.layoutFlags,\n commit.decision.preserveElementIds,\n ),\n layoutIds: action.layoutIds,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n case \"replace\":\n return commitVisibleRouterState(\n state,\n {\n elements: action.elements,\n interceptionContext: action.interceptionContext,\n layoutFlags: action.layoutFlags,\n layoutIds: action.layoutIds,\n navigationSnapshot: action.navigationSnapshot,\n previousNextUrl: action.previousNextUrl,\n renderId: action.renderId,\n rootLayoutTreePath: action.rootLayoutTreePath,\n routeId: action.routeId,\n },\n action.operation,\n );\n default: {\n const _exhaustive: never = action.type;\n throw new Error(\"[vinext] Unknown router action: \" + String(_exhaustive));\n }\n }\n}\n\nfunction resolvePendingNavigationCommitDecision(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n targetHref: string;\n}): CommitDecision {\n const decision = resolvePendingNavigationCommitDispositionDecision(options);\n\n switch (decision.disposition) {\n case \"skip\":\n return { disposition: \"no-commit\", trace: decision.trace };\n case \"hard-navigate\":\n return { disposition: \"hard-navigate\", trace: decision.trace };\n case \"dispatch\":\n return createVisibleCommitDecision(\n decision.trace,\n decision.preserveElementIds,\n decision.preserveAbsentSlots,\n );\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown navigation commit disposition: \" + String(_exhaustive));\n }\n }\n}\n\nfunction createVisibleCommitDecision(\n trace: NavigationTrace = createNavigationTrace(NavigationTraceReasonCodes.commitCurrent),\n preserveElementIds: readonly string[] = [],\n preserveAbsentSlots: boolean = false,\n): VisibleCommitDecision {\n return {\n disposition: \"commit\",\n preserveAbsentSlots,\n preserveElementIds: [...preserveElementIds],\n trace,\n };\n}\n\nfunction mergeLayoutFlags(\n previousFlags: AppRouterState[\"layoutFlags\"],\n nextFlags: AppRouterState[\"layoutFlags\"],\n preserveElementIds: readonly string[],\n): AppRouterState[\"layoutFlags\"] {\n const merged: Record<string, \"s\" | \"d\"> = { ...nextFlags };\n for (const id of preserveElementIds) {\n if (Object.hasOwn(merged, id)) continue;\n const value = previousFlags[id];\n if (value) merged[id] = value;\n }\n return merged;\n}\n\nfunction createApprovedVisibleCommit(options: {\n decision: VisibleCommitDecision;\n pending: PendingNavigationCommit;\n}): ApprovedVisibleCommit {\n return {\n [approvedVisibleCommitBrand]: true,\n action: options.pending.action,\n decision: options.decision,\n interceptionContext: options.pending.interceptionContext,\n previousNextUrl: options.pending.previousNextUrl,\n rootLayoutTreePath: options.pending.rootLayoutTreePath,\n routeId: options.pending.routeId,\n };\n}\n\nfunction createCommitTransactionFields(pending: PendingNavigationCommit): NavigationTraceFields {\n return {\n operationLane: pending.action.operation.lane,\n pendingOperationId: pending.action.operation.id,\n startedVisibleCommitVersion: pending.action.operation.startedVisibleCommitVersion,\n };\n}\n\nfunction prependCommitTransactionTrace(\n trace: NavigationTrace,\n code: NavigationTraceTransactionCode,\n pending: PendingNavigationCommit,\n): NavigationTrace {\n return prependNavigationTraceEntry(trace, code, createCommitTransactionFields(pending));\n}\n\nfunction addCommitTransactionTrace(\n decision: CommitDecision,\n pending: PendingNavigationCommit,\n): CommitDecision {\n switch (decision.disposition) {\n case \"commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.visibleCommit,\n pending,\n ),\n };\n case \"hard-navigate\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.hardNavigate,\n pending,\n ),\n };\n case \"no-commit\":\n return {\n ...decision,\n trace: prependCommitTransactionTrace(\n decision.trace,\n NavigationTraceTransactionCodes.noCommit,\n pending,\n ),\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport function approveHmrVisibleCommit(pending: PendingNavigationCommit): ApprovedVisibleCommit {\n if (pending.action.operation.lane !== \"hmr\") {\n throw new Error(\"[vinext] HMR visible commit approval requires an HMR pending operation\");\n }\n\n const decision = addCommitTransactionTrace(createVisibleCommitDecision(), pending);\n // This guard is a type narrowing assertion: createVisibleCommitDecision()\n // structurally produces a commit decision, and addCommitTransactionTrace()\n // must preserve that disposition while adding operator trace context.\n if (decision.disposition !== \"commit\") {\n throw new Error(\"[vinext] HMR visible commit approval did not produce a commit decision\");\n }\n\n return createApprovedVisibleCommit({\n decision,\n pending,\n });\n}\n\nexport function approvePendingNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n pending: PendingNavigationCommit;\n startedNavigationId: number;\n targetHref: string;\n}): CommitApproval {\n const decision = addCommitTransactionTrace(\n resolvePendingNavigationCommitDecision({\n activeNavigationId: options.activeNavigationId,\n currentState: options.currentState,\n pending: options.pending,\n startedNavigationId: options.startedNavigationId,\n targetHref: options.targetHref,\n }),\n options.pending,\n );\n\n switch (decision.disposition) {\n case \"commit\":\n return {\n approvedCommit: createApprovedVisibleCommit({\n decision,\n pending: options.pending,\n }),\n decision,\n };\n case \"hard-navigate\":\n case \"no-commit\":\n return {\n approvedCommit: null,\n decision,\n };\n default: {\n const _exhaustive: never = decision;\n throw new Error(\"[vinext] Unknown commit decision: \" + String(_exhaustive));\n }\n }\n}\n\nexport async function resolveAndClassifyNavigationCommit(options: {\n activeNavigationId: number;\n currentState: AppRouterState;\n // When provided, these getters are called after awaiting nextElements so\n // approval uses the latest lifecycle authority instead of the call snapshot.\n getActiveNavigationId?: () => number;\n getCurrentStateForApproval?: () => AppRouterState;\n navigationSnapshot: ClientNavigationRenderSnapshot;\n nextElements: Promise<AppElements>;\n operationLane: OperationLane;\n previousNextUrl?: string | null;\n renderId: number;\n startedNavigationId: number;\n targetHref: string;\n type: \"navigate\" | \"replace\" | \"traverse\";\n}): Promise<ClassifiedPendingNavigationCommit> {\n const pending = await createPendingNavigationCommit({\n currentState: options.currentState,\n nextElements: options.nextElements,\n navigationSnapshot: options.navigationSnapshot,\n operationLane: options.operationLane,\n previousNextUrl: options.previousNextUrl,\n renderId: options.renderId,\n type: options.type,\n });\n\n const approvalState = options.getCurrentStateForApproval?.() ?? options.currentState;\n const approval = approvePendingNavigationCommit({\n activeNavigationId: options.getActiveNavigationId?.() ?? options.activeNavigationId,\n currentState: approvalState,\n pending,\n startedNavigationId: options.startedNavigationId,\n targetHref: options.targetHref,\n });\n\n return {\n approvedCommit: approval.approvedCommit,\n decision: approval.decision,\n pending,\n trace: approval.decision.trace,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-client-reference-preloader.js","names":[],"sources":["../../src/server/app-client-reference-preloader.ts"],"sourcesContent":["type ClientReferenceRequire = (id: string) => Promise<unknown>;\n\ntype ClientReferenceMap = Readonly<Record<string, unknown>>;\n\ntype ClientReferencePreloaderOptions = {\n getReferences: () => ClientReferenceMap | undefined;\n getClientRequire: () => ClientReferenceRequire | undefined;\n onPreloadError?: (id: string, error: unknown) => void;\n};\n\ntype ClientReferencePreloader = {\n preload: (referenceIds?: Iterable<string>) => Promise<void>;\n};\n\nconst resolvedPreload = Promise.resolve();\n\nexport function createClientReferencePreloader(\n options: ClientReferencePreloaderOptions,\n): ClientReferencePreloader {\n let allReferencesPreloaded = false;\n let allReferencesPreloadPromise: Promise<void> | null = null;\n const preloadedReferences = new Set<string>();\n const referencePreloadPromises = new Map<string, Promise<void>>();\n\n function preloadReference(id: string, clientRequire: ClientReferenceRequire): Promise<void> {\n if (preloadedReferences.has(id)) {\n return resolvedPreload;\n }\n\n const existing = referencePreloadPromises.get(id);\n if (existing) {\n return existing;\n }\n\n const preloadPromise = clientRequire(id)\n .catch((error) => {\n options.onPreloadError?.(id, error);\n })\n .then(() => {\n preloadedReferences.add(id);\n })\n .finally(() => {\n referencePreloadPromises.delete(id);\n });\n\n referencePreloadPromises.set(id, preloadPromise);\n return preloadPromise;\n }\n\n function preloadReferenceSet(\n referenceIds: Iterable<string>,\n refs: ClientReferenceMap,\n clientRequire: ClientReferenceRequire,\n ): Promise<void> {\n const pending: Promise<void>[] = [];\n\n for (const id of referenceIds) {\n if (Object.hasOwn(refs, id)) {\n pending.push(preloadReference(id, clientRequire));\n }\n }\n\n if (pending.length === 0) {\n return resolvedPreload;\n }\n\n return Promise.all(pending).then(() => {});\n }\n\n return {\n preload(referenceIds) {\n const refs = options.getReferences();\n const clientRequire = options.getClientRequire();\n if (!refs || !clientRequire) {\n return resolvedPreload;\n }\n\n if (referenceIds) {\n return preloadReferenceSet(referenceIds, refs, clientRequire);\n }\n\n if (allReferencesPreloaded) {\n return resolvedPreload;\n }\n if (allReferencesPreloadPromise) {\n return allReferencesPreloadPromise;\n }\n\n allReferencesPreloadPromise = preloadReferenceSet(Object.keys(refs), refs, clientRequire)\n .then(() => {\n allReferencesPreloaded = true;\n })\n .finally(() => {\n allReferencesPreloadPromise = null;\n });\n\n return allReferencesPreloadPromise;\n },\n };\n}\n"],"mappings":";AAcA,MAAM,kBAAkB,QAAQ,SAAS;AAEzC,SAAgB,+BACd,SAC0B;CAC1B,IAAI,yBAAyB;CAC7B,IAAI,8BAAoD;CACxD,MAAM,sCAAsB,IAAI,KAAa;CAC7C,MAAM,2CAA2B,IAAI,KAA4B;CAEjE,SAAS,iBAAiB,IAAY,eAAsD;AAC1F,MAAI,oBAAoB,IAAI,GAAG,CAC7B,QAAO;EAGT,MAAM,WAAW,yBAAyB,IAAI,GAAG;AACjD,MAAI,SACF,QAAO;EAGT,MAAM,iBAAiB,cAAc,GAAG,CACrC,OAAO,UAAU;AAChB,WAAQ,iBAAiB,IAAI,MAAM;IACnC,CACD,WAAW;AACV,uBAAoB,IAAI,GAAG;IAC3B,CACD,cAAc;AACb,4BAAyB,OAAO,GAAG;IACnC;AAEJ,2BAAyB,IAAI,IAAI,eAAe;AAChD,SAAO;;CAGT,SAAS,oBACP,cACA,MACA,eACe;EACf,MAAM,UAA2B,EAAE;AAEnC,OAAK,MAAM,MAAM,aACf,KAAI,OAAO,OAAO,MAAM,GAAG,CACzB,SAAQ,KAAK,iBAAiB,IAAI,cAAc,CAAC;AAIrD,MAAI,QAAQ,WAAW,EACrB,QAAO;AAGT,SAAO,QAAQ,IAAI,QAAQ,CAAC,WAAW,GAAG;;AAG5C,QAAO,EACL,QAAQ,cAAc;EACpB,MAAM,OAAO,QAAQ,eAAe;EACpC,MAAM,gBAAgB,QAAQ,kBAAkB;AAChD,MAAI,CAAC,QAAQ,CAAC,cACZ,QAAO;AAGT,MAAI,aACF,QAAO,oBAAoB,cAAc,MAAM,cAAc;AAG/D,MAAI,uBACF,QAAO;AAET,MAAI,4BACF,QAAO;AAGT,gCAA8B,oBAAoB,OAAO,KAAK,KAAK,EAAE,MAAM,cAAc,CACtF,WAAW;AACV,4BAAyB;IACzB,CACD,cAAc;AACb,iCAA8B;IAC9B;AAEJ,SAAO;IAEV"}
1
+ {"version":3,"file":"app-client-reference-preloader.js","names":[],"sources":["../../src/server/app-client-reference-preloader.ts"],"sourcesContent":["type ClientReferenceRequire = (id: string) => Promise<unknown>;\n\ntype ClientReferenceMap = Readonly<Record<string, unknown>>;\n\ntype ClientReferencePreloaderOptions = {\n getReferences: () => ClientReferenceMap | undefined;\n getClientRequire: () => ClientReferenceRequire | undefined;\n onPreloadError?: (id: string, error: unknown) => void;\n};\n\ntype ClientReferencePreloader = {\n preload: (referenceIds?: Iterable<string>) => Promise<void>;\n};\n\nconst resolvedPreload = Promise.resolve();\n\nexport function createClientReferencePreloader(\n options: ClientReferencePreloaderOptions,\n): ClientReferencePreloader {\n let allReferencesPreloaded = false;\n let allReferencesPreloadPromise: Promise<void> | null = null;\n const preloadedReferences = new Set<string>();\n const referencePreloadPromises = new Map<string, Promise<void>>();\n\n function preloadReference(id: string, clientRequire: ClientReferenceRequire): Promise<void> {\n if (preloadedReferences.has(id)) {\n return resolvedPreload;\n }\n\n const existing = referencePreloadPromises.get(id);\n if (existing) {\n return existing;\n }\n\n const preloadPromise = clientRequire(id)\n .catch((error) => {\n options.onPreloadError?.(id, error);\n })\n .then(() => {\n preloadedReferences.add(id);\n })\n .finally(() => {\n referencePreloadPromises.delete(id);\n });\n\n referencePreloadPromises.set(id, preloadPromise);\n return preloadPromise;\n }\n\n function preloadReferenceSet(\n referenceIds: Iterable<string>,\n refs: ClientReferenceMap,\n clientRequire: ClientReferenceRequire,\n ): Promise<void> {\n const pending: Promise<void>[] = [];\n\n for (const id of referenceIds) {\n if (Object.hasOwn(refs, id)) {\n pending.push(preloadReference(id, clientRequire));\n }\n }\n\n if (pending.length === 0) {\n return resolvedPreload;\n }\n\n return Promise.all(pending).then(() => {});\n }\n\n return {\n preload(referenceIds) {\n const refs = options.getReferences();\n const clientRequire = options.getClientRequire();\n if (!refs || !clientRequire) {\n return resolvedPreload;\n }\n\n if (referenceIds) {\n return preloadReferenceSet(referenceIds, refs, clientRequire);\n }\n\n if (allReferencesPreloaded) {\n return resolvedPreload;\n }\n if (allReferencesPreloadPromise) {\n return allReferencesPreloadPromise;\n }\n\n allReferencesPreloadPromise = preloadReferenceSet(Object.keys(refs), refs, clientRequire)\n .then(() => {\n allReferencesPreloaded = true;\n })\n .finally(() => {\n allReferencesPreloadPromise = null;\n });\n\n return allReferencesPreloadPromise;\n },\n };\n}\n"],"mappings":";AAcA,MAAM,kBAAkB,QAAQ,SAAS;AAEzC,SAAgB,+BACd,SAC0B;CAC1B,IAAI,yBAAyB;CAC7B,IAAI,8BAAoD;CACxD,MAAM,sCAAsB,IAAI,KAAa;CAC7C,MAAM,2CAA2B,IAAI,KAA4B;CAEjE,SAAS,iBAAiB,IAAY,eAAsD;EAC1F,IAAI,oBAAoB,IAAI,GAAG,EAC7B,OAAO;EAGT,MAAM,WAAW,yBAAyB,IAAI,GAAG;EACjD,IAAI,UACF,OAAO;EAGT,MAAM,iBAAiB,cAAc,GAAG,CACrC,OAAO,UAAU;GAChB,QAAQ,iBAAiB,IAAI,MAAM;IACnC,CACD,WAAW;GACV,oBAAoB,IAAI,GAAG;IAC3B,CACD,cAAc;GACb,yBAAyB,OAAO,GAAG;IACnC;EAEJ,yBAAyB,IAAI,IAAI,eAAe;EAChD,OAAO;;CAGT,SAAS,oBACP,cACA,MACA,eACe;EACf,MAAM,UAA2B,EAAE;EAEnC,KAAK,MAAM,MAAM,cACf,IAAI,OAAO,OAAO,MAAM,GAAG,EACzB,QAAQ,KAAK,iBAAiB,IAAI,cAAc,CAAC;EAIrD,IAAI,QAAQ,WAAW,GACrB,OAAO;EAGT,OAAO,QAAQ,IAAI,QAAQ,CAAC,WAAW,GAAG;;CAG5C,OAAO,EACL,QAAQ,cAAc;EACpB,MAAM,OAAO,QAAQ,eAAe;EACpC,MAAM,gBAAgB,QAAQ,kBAAkB;EAChD,IAAI,CAAC,QAAQ,CAAC,eACZ,OAAO;EAGT,IAAI,cACF,OAAO,oBAAoB,cAAc,MAAM,cAAc;EAG/D,IAAI,wBACF,OAAO;EAET,IAAI,6BACF,OAAO;EAGT,8BAA8B,oBAAoB,OAAO,KAAK,KAAK,EAAE,MAAM,cAAc,CACtF,WAAW;GACV,yBAAyB;IACzB,CACD,cAAc;GACb,8BAA8B;IAC9B;EAEJ,OAAO;IAEV"}
@@ -4,6 +4,7 @@ import { ReactNode } from "react";
4
4
  //#region src/server/app-elements-wire.d.ts
5
5
  declare const APP_ARTIFACT_COMPATIBILITY_KEY = "__artifactCompatibility";
6
6
  declare const APP_INTERCEPTION_CONTEXT_KEY = "__interceptionContext";
7
+ declare const APP_LAYOUT_IDS_KEY = "__layoutIds";
7
8
  declare const APP_LAYOUT_FLAGS_KEY = "__layoutFlags";
8
9
  declare const APP_ROUTE_KEY = "__route";
9
10
  declare const APP_ROOT_LAYOUT_KEY = "__rootLayout";
@@ -34,6 +35,7 @@ type LayoutFlags = Readonly<Record<string, "s" | "d">>;
34
35
  type AppElementsMetadata = {
35
36
  artifactCompatibility: ArtifactCompatibilityEnvelope;
36
37
  interceptionContext: string | null;
38
+ layoutIds: readonly string[];
37
39
  layoutFlags: LayoutFlags;
38
40
  routeId: string;
39
41
  rootLayoutTreePath: string | null;
@@ -59,12 +61,14 @@ type AppElementsWireElementKey = {
59
61
  };
60
62
  type AppElementsWireMetadataInput = {
61
63
  interceptionContext: string | null;
64
+ layoutIds?: readonly string[];
62
65
  routeId: string;
63
66
  rootLayoutTreePath: string | null;
64
67
  };
65
68
  type AppElementsWireMetadataEntries = Readonly<{
66
69
  [APP_ROUTE_KEY]: string;
67
70
  [APP_INTERCEPTION_CONTEXT_KEY]: string | null;
71
+ [APP_LAYOUT_IDS_KEY]: readonly string[];
68
72
  [APP_ROOT_LAYOUT_KEY]: string | null;
69
73
  }>;
70
74
  /**
@@ -77,6 +81,7 @@ type AppOutgoingElements = Readonly<Record<string, ReactNode | LayoutFlags | Art
77
81
  type AppElementsWireKeys = {
78
82
  readonly artifactCompatibility: typeof APP_ARTIFACT_COMPATIBILITY_KEY;
79
83
  readonly interceptionContext: typeof APP_INTERCEPTION_CONTEXT_KEY;
84
+ readonly layoutIds: typeof APP_LAYOUT_IDS_KEY;
80
85
  readonly layoutFlags: typeof APP_LAYOUT_FLAGS_KEY;
81
86
  readonly rootLayout: typeof APP_ROOT_LAYOUT_KEY;
82
87
  readonly route: typeof APP_ROUTE_KEY;
@@ -126,5 +131,5 @@ declare function buildOutgoingAppPayload(input: {
126
131
  declare function readAppElementsMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;
127
132
  declare const AppElementsWire: AppElementsWireCodec;
128
133
  //#endregion
129
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags };
134
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags };
130
135
  //# sourceMappingURL=app-elements-wire.d.ts.map
@@ -4,6 +4,7 @@ import { isValidElement } from "react";
4
4
  const APP_INTERCEPTION_SEPARATOR = "\0";
5
5
  const APP_ARTIFACT_COMPATIBILITY_KEY = "__artifactCompatibility";
6
6
  const APP_INTERCEPTION_CONTEXT_KEY = "__interceptionContext";
7
+ const APP_LAYOUT_IDS_KEY = "__layoutIds";
7
8
  const APP_LAYOUT_FLAGS_KEY = "__layoutFlags";
8
9
  const APP_ROUTE_KEY = "__route";
9
10
  const APP_ROOT_LAYOUT_KEY = "__rootLayout";
@@ -103,6 +104,7 @@ function createAppElementsWireMetadataEntries(input) {
103
104
  return {
104
105
  [APP_ROUTE_KEY]: input.routeId,
105
106
  [APP_INTERCEPTION_CONTEXT_KEY]: input.interceptionContext,
107
+ [APP_LAYOUT_IDS_KEY]: [...input.layoutIds ?? []],
106
108
  [APP_ROOT_LAYOUT_KEY]: input.rootLayoutTreePath
107
109
  };
108
110
  }
@@ -126,6 +128,17 @@ function parseLayoutFlags(value) {
126
128
  if (isLayoutFlagsRecord(value)) return value;
127
129
  return {};
128
130
  }
131
+ function parseLayoutIds(value) {
132
+ if (value === void 0) return [];
133
+ if (!Array.isArray(value)) throw new Error("[vinext] Invalid __layoutIds in App Router payload: expected layout id string[]");
134
+ const layoutIds = [];
135
+ for (const entry of value) {
136
+ if (typeof entry !== "string") throw new Error("[vinext] Invalid __layoutIds in App Router payload: expected layout id string[]");
137
+ if (parseAppElementsWireElementKey(entry)?.kind !== "layout") throw new Error("[vinext] Invalid __layoutIds in App Router payload: expected layout ids");
138
+ layoutIds.push(entry);
139
+ }
140
+ return layoutIds;
141
+ }
129
142
  /**
130
143
  * Type predicate for a plain (non-null, non-array) record of app payload values.
131
144
  * Used to distinguish the App Router payload object from bare React elements at
@@ -168,9 +181,11 @@ function readAppElementsMetadata(elements) {
168
181
  if (rootLayoutTreePath === void 0) throw new Error("[vinext] Missing __rootLayout key in App Router payload");
169
182
  if (rootLayoutTreePath !== null && typeof rootLayoutTreePath !== "string") throw new Error("[vinext] Invalid __rootLayout in App Router payload: expected string or null");
170
183
  const layoutFlags = parseLayoutFlags(elements[APP_LAYOUT_FLAGS_KEY]);
184
+ const layoutIds = parseLayoutIds(elements[APP_LAYOUT_IDS_KEY]);
171
185
  return {
172
186
  artifactCompatibility: readArtifactCompatibilityMetadata(elements[APP_ARTIFACT_COMPATIBILITY_KEY]),
173
187
  interceptionContext: interceptionContext ?? null,
188
+ layoutIds,
174
189
  layoutFlags,
175
190
  routeId,
176
191
  rootLayoutTreePath
@@ -180,6 +195,7 @@ const AppElementsWire = {
180
195
  keys: {
181
196
  artifactCompatibility: APP_ARTIFACT_COMPATIBILITY_KEY,
182
197
  interceptionContext: APP_INTERCEPTION_CONTEXT_KEY,
198
+ layoutIds: APP_LAYOUT_IDS_KEY,
183
199
  layoutFlags: APP_LAYOUT_FLAGS_KEY,
184
200
  rootLayout: APP_ROOT_LAYOUT_KEY,
185
201
  route: APP_ROUTE_KEY
@@ -200,6 +216,6 @@ const AppElementsWire = {
200
216
  withLayoutFlags
201
217
  };
202
218
  //#endregion
203
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags };
219
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags };
204
220
 
205
221
  //# sourceMappingURL=app-elements-wire.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-elements-wire.js","names":[],"sources":["../../src/server/app-elements-wire.ts"],"sourcesContent":["import { isValidElement, type ReactNode } from \"react\";\nimport {\n createArtifactCompatibilityEnvelope,\n parseArtifactCompatibilityEnvelope,\n type ArtifactCompatibilityEnvelope,\n} from \"./artifact-compatibility.js\";\n\nconst APP_INTERCEPTION_SEPARATOR = \"\\0\";\n\nexport const APP_ARTIFACT_COMPATIBILITY_KEY = \"__artifactCompatibility\";\nexport const APP_INTERCEPTION_CONTEXT_KEY = \"__interceptionContext\";\nexport const APP_LAYOUT_FLAGS_KEY = \"__layoutFlags\";\nexport const APP_ROUTE_KEY = \"__route\";\nexport const APP_ROOT_LAYOUT_KEY = \"__rootLayout\";\nexport const APP_UNMATCHED_SLOT_WIRE_VALUE = \"__VINEXT_UNMATCHED_SLOT__\";\n\nexport const UNMATCHED_SLOT = Symbol.for(\"vinext.unmatchedSlot\");\n\nexport type AppElementValue = ReactNode | typeof UNMATCHED_SLOT | string | null;\ntype AppWireElementValue = ReactNode | string | null;\n\nexport type AppElements = Readonly<Record<string, AppElementValue>>;\nexport type AppWireElements = Readonly<Record<string, AppWireElementValue>>;\n\n/**\n * Per-layout static/dynamic flags. `\"s\"` = static (skippable on next nav);\n * `\"d\"` = dynamic (must always render).\n *\n * Lifecycle (partial — later PRs extend this):\n *\n * 1. PROBE — probeAppPageLayouts (server/app-page-execution.ts) returns\n * LayoutFlags for every layout in the route at render time.\n *\n * 2. ATTACH — AppElementsWire.encodeOutgoingPayload writes `__layoutFlags`\n * into the outgoing App Router payload record.\n *\n * 3. WIRE — renderToReadableStream serializes the record as RSC row 0.\n *\n * 4. PARSE — AppElementsWire.readMetadata extracts layoutFlags from the\n * wire payload on the client side.\n */\nexport type LayoutFlags = Readonly<Record<string, \"s\" | \"d\">>;\n\ntype AppElementsMetadata = {\n artifactCompatibility: ArtifactCompatibilityEnvelope;\n interceptionContext: string | null;\n layoutFlags: LayoutFlags;\n routeId: string;\n rootLayoutTreePath: string | null;\n};\n\ntype AppElementsWireElementKey =\n | { kind: \"layout\"; treePath: string }\n | { interceptionContext: string | null; kind: \"page\"; path: string }\n | { interceptionContext: string | null; kind: \"route\"; path: string }\n | { kind: \"slot\"; name: string; treePath: string }\n | { kind: \"template\"; treePath: string };\n\ntype AppElementsWireMetadataInput = {\n interceptionContext: string | null;\n routeId: string;\n rootLayoutTreePath: string | null;\n};\n\ntype AppElementsWireMetadataEntries = Readonly<{\n [APP_ROUTE_KEY]: string;\n [APP_INTERCEPTION_CONTEXT_KEY]: string | null;\n [APP_ROOT_LAYOUT_KEY]: string | null;\n}>;\n\n/**\n * The outgoing wire payload shape. Includes ReactNode values for the\n * rendered tree plus metadata values like LayoutFlags attached under\n * known keys (e.g. __layoutFlags). Distinct from AppElements / AppWireElements\n * which only carry render-time values.\n */\nexport type AppOutgoingElements = Readonly<\n Record<string, ReactNode | LayoutFlags | ArtifactCompatibilityEnvelope>\n>;\n\ntype AppElementsWireKeys = {\n readonly artifactCompatibility: typeof APP_ARTIFACT_COMPATIBILITY_KEY;\n readonly interceptionContext: typeof APP_INTERCEPTION_CONTEXT_KEY;\n readonly layoutFlags: typeof APP_LAYOUT_FLAGS_KEY;\n readonly rootLayout: typeof APP_ROOT_LAYOUT_KEY;\n readonly route: typeof APP_ROUTE_KEY;\n};\n\ntype AppElementsWireCodec = {\n readonly keys: AppElementsWireKeys;\n readonly unmatchedSlotValue: typeof APP_UNMATCHED_SLOT_WIRE_VALUE;\n createMetadataEntries(input: AppElementsWireMetadataInput): AppElementsWireMetadataEntries;\n decode(elements: AppWireElements): AppElements;\n encodeCacheKey(rscUrl: string, interceptionContext: string | null): string;\n encodeLayoutId(treePath: string): string;\n encodeOutgoingPayload(input: {\n element: ReactNode | Readonly<Record<string, ReactNode>>;\n artifactCompatibility?: ArtifactCompatibilityEnvelope;\n layoutFlags: LayoutFlags;\n }): ReactNode | AppOutgoingElements;\n encodePageId(routePath: string, interceptionContext: string | null): string;\n encodeRouteId(routePath: string, interceptionContext: string | null): string;\n encodeSlotId(slotName: string, treePath: string): string;\n encodeTemplateId(treePath: string): string;\n isSlotId(key: string): boolean;\n parseElementKey(key: string): AppElementsWireElementKey | null;\n readMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;\n withLayoutFlags<T extends Record<string, unknown>>(\n elements: T,\n layoutFlags: LayoutFlags,\n ): T & { [APP_LAYOUT_FLAGS_KEY]: LayoutFlags };\n};\n\nfunction appendInterceptionContext(identity: string, interceptionContext: string | null): string {\n return interceptionContext === null\n ? identity\n : `${identity}${APP_INTERCEPTION_SEPARATOR}${interceptionContext}`;\n}\n\nfunction createAppPayloadRouteId(routePath: string, interceptionContext: string | null): string {\n return appendInterceptionContext(`route:${routePath}`, interceptionContext);\n}\n\nfunction createAppPayloadPageId(routePath: string, interceptionContext: string | null): string {\n return appendInterceptionContext(`page:${routePath}`, interceptionContext);\n}\n\nfunction createAppPayloadLayoutId(treePath: string): string {\n return `layout:${treePath}`;\n}\n\nfunction createAppPayloadTemplateId(treePath: string): string {\n return `template:${treePath}`;\n}\n\nfunction createAppPayloadSlotId(slotName: string, treePath: string): string {\n return `slot:${slotName}:${treePath}`;\n}\n\nfunction createAppPayloadCacheKey(rscUrl: string, interceptionContext: string | null): string {\n return appendInterceptionContext(rscUrl, interceptionContext);\n}\n\nfunction parsePathWithInterception(input: string): {\n interceptionContext: string | null;\n path: string;\n} | null {\n const separatorIndex = input.indexOf(APP_INTERCEPTION_SEPARATOR);\n const path = separatorIndex === -1 ? input : input.slice(0, separatorIndex);\n if (!path.startsWith(\"/\")) return null;\n\n return {\n interceptionContext: separatorIndex === -1 ? null : input.slice(separatorIndex + 1),\n path,\n };\n}\n\n/**\n * AppElements tree paths are absolute route-tree paths on the wire.\n * Bare segment names are not valid layout/template/slot tree identities.\n */\nfunction parseTreePath(input: string): string | null {\n return input.startsWith(\"/\") ? input : null;\n}\n\nfunction parseAppElementsWireElementKey(key: string): AppElementsWireElementKey | null {\n if (key.startsWith(\"route:\")) {\n const parsed = parsePathWithInterception(key.slice(\"route:\".length));\n if (!parsed) return null;\n return { interceptionContext: parsed.interceptionContext, kind: \"route\", path: parsed.path };\n }\n\n if (key.startsWith(\"page:\")) {\n const parsed = parsePathWithInterception(key.slice(\"page:\".length));\n if (!parsed) return null;\n return { interceptionContext: parsed.interceptionContext, kind: \"page\", path: parsed.path };\n }\n\n if (key.startsWith(\"layout:\")) {\n const treePath = parseTreePath(key.slice(\"layout:\".length));\n return treePath ? { kind: \"layout\", treePath } : null;\n }\n\n if (key.startsWith(\"template:\")) {\n const treePath = parseTreePath(key.slice(\"template:\".length));\n return treePath ? { kind: \"template\", treePath } : null;\n }\n\n if (key.startsWith(\"slot:\")) {\n const body = key.slice(\"slot:\".length);\n const separatorIndex = body.indexOf(\":\");\n if (separatorIndex <= 0) return null;\n const name = body.slice(0, separatorIndex);\n const treePath = parseTreePath(body.slice(separatorIndex + 1));\n return treePath ? { kind: \"slot\", name, treePath } : null;\n }\n\n return null;\n}\n\nfunction isAppElementsWireSlotId(key: string): boolean {\n if (!key.startsWith(\"slot:\")) return false;\n const body = key.slice(\"slot:\".length);\n const separatorIndex = body.indexOf(\":\");\n return separatorIndex > 0 && body.charCodeAt(separatorIndex + 1) === 0x2f;\n}\n\nfunction createAppElementsWireMetadataEntries(\n input: AppElementsWireMetadataInput,\n): AppElementsWireMetadataEntries {\n return {\n [APP_ROUTE_KEY]: input.routeId,\n [APP_INTERCEPTION_CONTEXT_KEY]: input.interceptionContext,\n [APP_ROOT_LAYOUT_KEY]: input.rootLayoutTreePath,\n };\n}\n\nexport function normalizeAppElements(elements: AppWireElements): AppElements {\n let needsNormalization = false;\n for (const [key, value] of Object.entries(elements)) {\n if (isAppElementsWireSlotId(key) && value === APP_UNMATCHED_SLOT_WIRE_VALUE) {\n needsNormalization = true;\n break;\n }\n }\n\n if (!needsNormalization) {\n return elements;\n }\n\n const normalized: Record<string, AppElementValue> = {};\n for (const [key, value] of Object.entries(elements)) {\n normalized[key] =\n isAppElementsWireSlotId(key) && value === APP_UNMATCHED_SLOT_WIRE_VALUE\n ? UNMATCHED_SLOT\n : value;\n }\n\n return normalized;\n}\n\nfunction isLayoutFlagsRecord(value: unknown): value is LayoutFlags {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n for (const v of Object.values(value)) {\n if (v !== \"s\" && v !== \"d\") return false;\n }\n return true;\n}\n\nfunction parseLayoutFlags(value: unknown): LayoutFlags {\n if (isLayoutFlagsRecord(value)) return value;\n return {};\n}\n\n/**\n * Type predicate for a plain (non-null, non-array) record of app payload values.\n * Used to distinguish the App Router payload object from bare React elements at\n * the render boundary. Narrows to `Readonly<Record<string, unknown>>` because\n * the outgoing payload carries heterogeneous values (ReactNodes for the rendered\n * tree, plus metadata like `__layoutFlags` which is a plain object). Delegates\n * to React's canonical `isValidElement` so we don't depend on React's internal\n * `$$typeof` marker scheme.\n */\nexport function isAppElementsRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== \"object\" || value === null) return false;\n if (Array.isArray(value)) return false;\n if (isValidElement(value)) return false;\n return true;\n}\n\nexport function withLayoutFlags<T extends Record<string, unknown>>(\n elements: T,\n layoutFlags: LayoutFlags,\n): T & { [APP_LAYOUT_FLAGS_KEY]: LayoutFlags } {\n return { ...elements, [APP_LAYOUT_FLAGS_KEY]: layoutFlags };\n}\n\nexport function buildOutgoingAppPayload(input: {\n element: ReactNode | Readonly<Record<string, ReactNode>>;\n artifactCompatibility?: ArtifactCompatibilityEnvelope;\n layoutFlags: LayoutFlags;\n}): ReactNode | AppOutgoingElements {\n if (!isAppElementsRecord(input.element)) {\n return input.element;\n }\n return {\n ...input.element,\n [APP_LAYOUT_FLAGS_KEY]: input.layoutFlags,\n [APP_ARTIFACT_COMPATIBILITY_KEY]:\n input.artifactCompatibility ?? createArtifactCompatibilityEnvelope(),\n };\n}\n\nfunction readArtifactCompatibilityMetadata(value: unknown): ArtifactCompatibilityEnvelope {\n if (value === undefined) return createArtifactCompatibilityEnvelope();\n\n const artifactCompatibility = parseArtifactCompatibilityEnvelope(value);\n // TODO(#726-COMPAT-04): hard-fail malformed compatibility metadata once\n // cache/skip consumers depend on this proof. During Wave01 the field is\n // emitted as scaffolding, so bad or future-version values degrade like\n // missing __layoutFlags instead of crashing render paths that do not read it.\n return artifactCompatibility ?? createArtifactCompatibilityEnvelope();\n}\n\nexport function readAppElementsMetadata(\n elements: Readonly<Record<string, unknown>>,\n): AppElementsMetadata {\n const routeId = elements[APP_ROUTE_KEY];\n if (typeof routeId !== \"string\") {\n throw new Error(\"[vinext] Missing __route string in App Router payload\");\n }\n\n const interceptionContext = elements[APP_INTERCEPTION_CONTEXT_KEY];\n if (\n interceptionContext !== undefined &&\n interceptionContext !== null &&\n typeof interceptionContext !== \"string\"\n ) {\n throw new Error(\"[vinext] Invalid __interceptionContext in App Router payload\");\n }\n\n const rootLayoutTreePath = elements[APP_ROOT_LAYOUT_KEY];\n if (rootLayoutTreePath === undefined) {\n throw new Error(\"[vinext] Missing __rootLayout key in App Router payload\");\n }\n if (rootLayoutTreePath !== null && typeof rootLayoutTreePath !== \"string\") {\n throw new Error(\"[vinext] Invalid __rootLayout in App Router payload: expected string or null\");\n }\n\n const layoutFlags = parseLayoutFlags(elements[APP_LAYOUT_FLAGS_KEY]);\n const artifactCompatibility = readArtifactCompatibilityMetadata(\n elements[APP_ARTIFACT_COMPATIBILITY_KEY],\n );\n\n return {\n artifactCompatibility,\n interceptionContext: interceptionContext ?? null,\n layoutFlags,\n routeId,\n rootLayoutTreePath,\n };\n}\n\nexport const AppElementsWire: AppElementsWireCodec = {\n // WIRE follow-ups use these stable key names when moving payload readers and writers\n // behind the codec boundary.\n keys: {\n artifactCompatibility: APP_ARTIFACT_COMPATIBILITY_KEY,\n interceptionContext: APP_INTERCEPTION_CONTEXT_KEY,\n layoutFlags: APP_LAYOUT_FLAGS_KEY,\n rootLayout: APP_ROOT_LAYOUT_KEY,\n route: APP_ROUTE_KEY,\n },\n unmatchedSlotValue: APP_UNMATCHED_SLOT_WIRE_VALUE,\n createMetadataEntries: createAppElementsWireMetadataEntries,\n decode: normalizeAppElements,\n encodeCacheKey: createAppPayloadCacheKey,\n encodeLayoutId: createAppPayloadLayoutId,\n encodeOutgoingPayload: buildOutgoingAppPayload,\n encodePageId: createAppPayloadPageId,\n encodeRouteId: createAppPayloadRouteId,\n encodeSlotId: createAppPayloadSlotId,\n encodeTemplateId: createAppPayloadTemplateId,\n isSlotId: isAppElementsWireSlotId,\n parseElementKey: parseAppElementsWireElementKey,\n readMetadata: readAppElementsMetadata,\n withLayoutFlags,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-elements-wire.js","names":[],"sources":["../../src/server/app-elements-wire.ts"],"sourcesContent":["import { isValidElement, type ReactNode } from \"react\";\nimport {\n createArtifactCompatibilityEnvelope,\n parseArtifactCompatibilityEnvelope,\n type ArtifactCompatibilityEnvelope,\n} from \"./artifact-compatibility.js\";\n\nconst APP_INTERCEPTION_SEPARATOR = \"\\0\";\n\nexport const APP_ARTIFACT_COMPATIBILITY_KEY = \"__artifactCompatibility\";\nexport const APP_INTERCEPTION_CONTEXT_KEY = \"__interceptionContext\";\nexport const APP_LAYOUT_IDS_KEY = \"__layoutIds\";\nexport const APP_LAYOUT_FLAGS_KEY = \"__layoutFlags\";\nexport const APP_ROUTE_KEY = \"__route\";\nexport const APP_ROOT_LAYOUT_KEY = \"__rootLayout\";\nexport const APP_UNMATCHED_SLOT_WIRE_VALUE = \"__VINEXT_UNMATCHED_SLOT__\";\n\nexport const UNMATCHED_SLOT = Symbol.for(\"vinext.unmatchedSlot\");\n\nexport type AppElementValue = ReactNode | typeof UNMATCHED_SLOT | string | null;\ntype AppWireElementValue = ReactNode | string | null;\n\nexport type AppElements = Readonly<Record<string, AppElementValue>>;\nexport type AppWireElements = Readonly<Record<string, AppWireElementValue>>;\n\n/**\n * Per-layout static/dynamic flags. `\"s\"` = static (skippable on next nav);\n * `\"d\"` = dynamic (must always render).\n *\n * Lifecycle (partial — later PRs extend this):\n *\n * 1. PROBE — probeAppPageLayouts (server/app-page-execution.ts) returns\n * LayoutFlags for every layout in the route at render time.\n *\n * 2. ATTACH — AppElementsWire.encodeOutgoingPayload writes `__layoutFlags`\n * into the outgoing App Router payload record.\n *\n * 3. WIRE — renderToReadableStream serializes the record as RSC row 0.\n *\n * 4. PARSE — AppElementsWire.readMetadata extracts layoutFlags from the\n * wire payload on the client side.\n */\nexport type LayoutFlags = Readonly<Record<string, \"s\" | \"d\">>;\n\ntype AppElementsMetadata = {\n artifactCompatibility: ArtifactCompatibilityEnvelope;\n interceptionContext: string | null;\n layoutIds: readonly string[];\n layoutFlags: LayoutFlags;\n routeId: string;\n rootLayoutTreePath: string | null;\n};\n\ntype AppElementsWireElementKey =\n | { kind: \"layout\"; treePath: string }\n | { interceptionContext: string | null; kind: \"page\"; path: string }\n | { interceptionContext: string | null; kind: \"route\"; path: string }\n | { kind: \"slot\"; name: string; treePath: string }\n | { kind: \"template\"; treePath: string };\n\ntype AppElementsWireMetadataInput = {\n interceptionContext: string | null;\n layoutIds?: readonly string[];\n routeId: string;\n rootLayoutTreePath: string | null;\n};\n\ntype AppElementsWireMetadataEntries = Readonly<{\n [APP_ROUTE_KEY]: string;\n [APP_INTERCEPTION_CONTEXT_KEY]: string | null;\n [APP_LAYOUT_IDS_KEY]: readonly string[];\n [APP_ROOT_LAYOUT_KEY]: string | null;\n}>;\n\n/**\n * The outgoing wire payload shape. Includes ReactNode values for the\n * rendered tree plus metadata values like LayoutFlags attached under\n * known keys (e.g. __layoutFlags). Distinct from AppElements / AppWireElements\n * which only carry render-time values.\n */\nexport type AppOutgoingElements = Readonly<\n Record<string, ReactNode | LayoutFlags | ArtifactCompatibilityEnvelope>\n>;\n\ntype AppElementsWireKeys = {\n readonly artifactCompatibility: typeof APP_ARTIFACT_COMPATIBILITY_KEY;\n readonly interceptionContext: typeof APP_INTERCEPTION_CONTEXT_KEY;\n readonly layoutIds: typeof APP_LAYOUT_IDS_KEY;\n readonly layoutFlags: typeof APP_LAYOUT_FLAGS_KEY;\n readonly rootLayout: typeof APP_ROOT_LAYOUT_KEY;\n readonly route: typeof APP_ROUTE_KEY;\n};\n\ntype AppElementsWireCodec = {\n readonly keys: AppElementsWireKeys;\n readonly unmatchedSlotValue: typeof APP_UNMATCHED_SLOT_WIRE_VALUE;\n createMetadataEntries(input: AppElementsWireMetadataInput): AppElementsWireMetadataEntries;\n decode(elements: AppWireElements): AppElements;\n encodeCacheKey(rscUrl: string, interceptionContext: string | null): string;\n encodeLayoutId(treePath: string): string;\n encodeOutgoingPayload(input: {\n element: ReactNode | Readonly<Record<string, ReactNode>>;\n artifactCompatibility?: ArtifactCompatibilityEnvelope;\n layoutFlags: LayoutFlags;\n }): ReactNode | AppOutgoingElements;\n encodePageId(routePath: string, interceptionContext: string | null): string;\n encodeRouteId(routePath: string, interceptionContext: string | null): string;\n encodeSlotId(slotName: string, treePath: string): string;\n encodeTemplateId(treePath: string): string;\n isSlotId(key: string): boolean;\n parseElementKey(key: string): AppElementsWireElementKey | null;\n readMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;\n withLayoutFlags<T extends Record<string, unknown>>(\n elements: T,\n layoutFlags: LayoutFlags,\n ): T & { [APP_LAYOUT_FLAGS_KEY]: LayoutFlags };\n};\n\nfunction appendInterceptionContext(identity: string, interceptionContext: string | null): string {\n return interceptionContext === null\n ? identity\n : `${identity}${APP_INTERCEPTION_SEPARATOR}${interceptionContext}`;\n}\n\nfunction createAppPayloadRouteId(routePath: string, interceptionContext: string | null): string {\n return appendInterceptionContext(`route:${routePath}`, interceptionContext);\n}\n\nfunction createAppPayloadPageId(routePath: string, interceptionContext: string | null): string {\n return appendInterceptionContext(`page:${routePath}`, interceptionContext);\n}\n\nfunction createAppPayloadLayoutId(treePath: string): string {\n return `layout:${treePath}`;\n}\n\nfunction createAppPayloadTemplateId(treePath: string): string {\n return `template:${treePath}`;\n}\n\nfunction createAppPayloadSlotId(slotName: string, treePath: string): string {\n return `slot:${slotName}:${treePath}`;\n}\n\nfunction createAppPayloadCacheKey(rscUrl: string, interceptionContext: string | null): string {\n return appendInterceptionContext(rscUrl, interceptionContext);\n}\n\nfunction parsePathWithInterception(input: string): {\n interceptionContext: string | null;\n path: string;\n} | null {\n const separatorIndex = input.indexOf(APP_INTERCEPTION_SEPARATOR);\n const path = separatorIndex === -1 ? input : input.slice(0, separatorIndex);\n if (!path.startsWith(\"/\")) return null;\n\n return {\n interceptionContext: separatorIndex === -1 ? null : input.slice(separatorIndex + 1),\n path,\n };\n}\n\n/**\n * AppElements tree paths are absolute route-tree paths on the wire.\n * Bare segment names are not valid layout/template/slot tree identities.\n */\nfunction parseTreePath(input: string): string | null {\n return input.startsWith(\"/\") ? input : null;\n}\n\nfunction parseAppElementsWireElementKey(key: string): AppElementsWireElementKey | null {\n if (key.startsWith(\"route:\")) {\n const parsed = parsePathWithInterception(key.slice(\"route:\".length));\n if (!parsed) return null;\n return { interceptionContext: parsed.interceptionContext, kind: \"route\", path: parsed.path };\n }\n\n if (key.startsWith(\"page:\")) {\n const parsed = parsePathWithInterception(key.slice(\"page:\".length));\n if (!parsed) return null;\n return { interceptionContext: parsed.interceptionContext, kind: \"page\", path: parsed.path };\n }\n\n if (key.startsWith(\"layout:\")) {\n const treePath = parseTreePath(key.slice(\"layout:\".length));\n return treePath ? { kind: \"layout\", treePath } : null;\n }\n\n if (key.startsWith(\"template:\")) {\n const treePath = parseTreePath(key.slice(\"template:\".length));\n return treePath ? { kind: \"template\", treePath } : null;\n }\n\n if (key.startsWith(\"slot:\")) {\n const body = key.slice(\"slot:\".length);\n const separatorIndex = body.indexOf(\":\");\n if (separatorIndex <= 0) return null;\n const name = body.slice(0, separatorIndex);\n const treePath = parseTreePath(body.slice(separatorIndex + 1));\n return treePath ? { kind: \"slot\", name, treePath } : null;\n }\n\n return null;\n}\n\nfunction isAppElementsWireSlotId(key: string): boolean {\n if (!key.startsWith(\"slot:\")) return false;\n const body = key.slice(\"slot:\".length);\n const separatorIndex = body.indexOf(\":\");\n return separatorIndex > 0 && body.charCodeAt(separatorIndex + 1) === 0x2f;\n}\n\nfunction createAppElementsWireMetadataEntries(\n input: AppElementsWireMetadataInput,\n): AppElementsWireMetadataEntries {\n return {\n [APP_ROUTE_KEY]: input.routeId,\n [APP_INTERCEPTION_CONTEXT_KEY]: input.interceptionContext,\n [APP_LAYOUT_IDS_KEY]: [...(input.layoutIds ?? [])],\n [APP_ROOT_LAYOUT_KEY]: input.rootLayoutTreePath,\n };\n}\n\nexport function normalizeAppElements(elements: AppWireElements): AppElements {\n let needsNormalization = false;\n for (const [key, value] of Object.entries(elements)) {\n if (isAppElementsWireSlotId(key) && value === APP_UNMATCHED_SLOT_WIRE_VALUE) {\n needsNormalization = true;\n break;\n }\n }\n\n if (!needsNormalization) {\n return elements;\n }\n\n const normalized: Record<string, AppElementValue> = {};\n for (const [key, value] of Object.entries(elements)) {\n normalized[key] =\n isAppElementsWireSlotId(key) && value === APP_UNMATCHED_SLOT_WIRE_VALUE\n ? UNMATCHED_SLOT\n : value;\n }\n\n return normalized;\n}\n\nfunction isLayoutFlagsRecord(value: unknown): value is LayoutFlags {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n for (const v of Object.values(value)) {\n if (v !== \"s\" && v !== \"d\") return false;\n }\n return true;\n}\n\nfunction parseLayoutFlags(value: unknown): LayoutFlags {\n if (isLayoutFlagsRecord(value)) return value;\n return {};\n}\n\nfunction parseLayoutIds(value: unknown): readonly string[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) {\n throw new Error(\n \"[vinext] Invalid __layoutIds in App Router payload: expected layout id string[]\",\n );\n }\n\n const layoutIds: string[] = [];\n for (const entry of value) {\n if (typeof entry !== \"string\") {\n throw new Error(\n \"[vinext] Invalid __layoutIds in App Router payload: expected layout id string[]\",\n );\n }\n\n const parsed = parseAppElementsWireElementKey(entry);\n if (parsed?.kind !== \"layout\") {\n throw new Error(\"[vinext] Invalid __layoutIds in App Router payload: expected layout ids\");\n }\n\n layoutIds.push(entry);\n }\n return layoutIds;\n}\n\n/**\n * Type predicate for a plain (non-null, non-array) record of app payload values.\n * Used to distinguish the App Router payload object from bare React elements at\n * the render boundary. Narrows to `Readonly<Record<string, unknown>>` because\n * the outgoing payload carries heterogeneous values (ReactNodes for the rendered\n * tree, plus metadata like `__layoutFlags` which is a plain object). Delegates\n * to React's canonical `isValidElement` so we don't depend on React's internal\n * `$$typeof` marker scheme.\n */\nexport function isAppElementsRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== \"object\" || value === null) return false;\n if (Array.isArray(value)) return false;\n if (isValidElement(value)) return false;\n return true;\n}\n\nexport function withLayoutFlags<T extends Record<string, unknown>>(\n elements: T,\n layoutFlags: LayoutFlags,\n): T & { [APP_LAYOUT_FLAGS_KEY]: LayoutFlags } {\n return { ...elements, [APP_LAYOUT_FLAGS_KEY]: layoutFlags };\n}\n\nexport function buildOutgoingAppPayload(input: {\n element: ReactNode | Readonly<Record<string, ReactNode>>;\n artifactCompatibility?: ArtifactCompatibilityEnvelope;\n layoutFlags: LayoutFlags;\n}): ReactNode | AppOutgoingElements {\n if (!isAppElementsRecord(input.element)) {\n return input.element;\n }\n return {\n ...input.element,\n [APP_LAYOUT_FLAGS_KEY]: input.layoutFlags,\n [APP_ARTIFACT_COMPATIBILITY_KEY]:\n input.artifactCompatibility ?? createArtifactCompatibilityEnvelope(),\n };\n}\n\nfunction readArtifactCompatibilityMetadata(value: unknown): ArtifactCompatibilityEnvelope {\n if (value === undefined) return createArtifactCompatibilityEnvelope();\n\n const artifactCompatibility = parseArtifactCompatibilityEnvelope(value);\n // TODO(#726-COMPAT-04): hard-fail malformed compatibility metadata once\n // cache/skip consumers depend on this proof. During Wave01 the field is\n // emitted as scaffolding, so bad or future-version values degrade like\n // missing __layoutFlags instead of crashing render paths that do not read it.\n return artifactCompatibility ?? createArtifactCompatibilityEnvelope();\n}\n\nexport function readAppElementsMetadata(\n elements: Readonly<Record<string, unknown>>,\n): AppElementsMetadata {\n const routeId = elements[APP_ROUTE_KEY];\n if (typeof routeId !== \"string\") {\n throw new Error(\"[vinext] Missing __route string in App Router payload\");\n }\n\n const interceptionContext = elements[APP_INTERCEPTION_CONTEXT_KEY];\n if (\n interceptionContext !== undefined &&\n interceptionContext !== null &&\n typeof interceptionContext !== \"string\"\n ) {\n throw new Error(\"[vinext] Invalid __interceptionContext in App Router payload\");\n }\n\n const rootLayoutTreePath = elements[APP_ROOT_LAYOUT_KEY];\n if (rootLayoutTreePath === undefined) {\n throw new Error(\"[vinext] Missing __rootLayout key in App Router payload\");\n }\n if (rootLayoutTreePath !== null && typeof rootLayoutTreePath !== \"string\") {\n throw new Error(\"[vinext] Invalid __rootLayout in App Router payload: expected string or null\");\n }\n\n const layoutFlags = parseLayoutFlags(elements[APP_LAYOUT_FLAGS_KEY]);\n const layoutIds = parseLayoutIds(elements[APP_LAYOUT_IDS_KEY]);\n const artifactCompatibility = readArtifactCompatibilityMetadata(\n elements[APP_ARTIFACT_COMPATIBILITY_KEY],\n );\n\n return {\n artifactCompatibility,\n interceptionContext: interceptionContext ?? null,\n layoutIds,\n layoutFlags,\n routeId,\n rootLayoutTreePath,\n };\n}\n\nexport const AppElementsWire: AppElementsWireCodec = {\n // WIRE follow-ups use these stable key names when moving payload readers and writers\n // behind the codec boundary.\n keys: {\n artifactCompatibility: APP_ARTIFACT_COMPATIBILITY_KEY,\n interceptionContext: APP_INTERCEPTION_CONTEXT_KEY,\n layoutIds: APP_LAYOUT_IDS_KEY,\n layoutFlags: APP_LAYOUT_FLAGS_KEY,\n rootLayout: APP_ROOT_LAYOUT_KEY,\n route: APP_ROUTE_KEY,\n },\n unmatchedSlotValue: APP_UNMATCHED_SLOT_WIRE_VALUE,\n createMetadataEntries: createAppElementsWireMetadataEntries,\n decode: normalizeAppElements,\n encodeCacheKey: createAppPayloadCacheKey,\n encodeLayoutId: createAppPayloadLayoutId,\n encodeOutgoingPayload: buildOutgoingAppPayload,\n encodePageId: createAppPayloadPageId,\n encodeRouteId: createAppPayloadRouteId,\n encodeSlotId: createAppPayloadSlotId,\n encodeTemplateId: createAppPayloadTemplateId,\n isSlotId: isAppElementsWireSlotId,\n parseElementKey: parseAppElementsWireElementKey,\n readMetadata: readAppElementsMetadata,\n withLayoutFlags,\n};\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
1
+ import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
2
2
 
3
3
  //#region src/server/app-elements.d.ts
4
4
  declare function getMountedSlotIds(elements: AppElements): string[];
5
5
  declare function getMountedSlotIdsHeader(elements: AppElements): string | null;
6
6
  declare function resolveVisitedResponseInterceptionContext(requestInterceptionContext: string | null, payloadInterceptionContext: string | null): string | null;
7
7
  //#endregion
8
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, type AppElementValue, type AppElements, AppElementsWire, type AppOutgoingElements, type AppWireElements, type LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
8
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, type AppElementValue, type AppElements, AppElementsWire, type AppOutgoingElements, type AppWireElements, type LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
9
9
  //# sourceMappingURL=app-elements.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
2
- import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
2
+ import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
3
3
  //#region src/server/app-elements.ts
4
4
  function getMountedSlotIds(elements) {
5
5
  return Object.keys(elements).filter((key) => {
@@ -14,6 +14,6 @@ function resolveVisitedResponseInterceptionContext(requestInterceptionContext, p
14
14
  return payloadInterceptionContext ?? requestInterceptionContext;
15
15
  }
16
16
  //#endregion
17
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
17
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
18
18
 
19
19
  //# sourceMappingURL=app-elements.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-elements.js","names":[],"sources":["../../src/server/app-elements.ts"],"sourcesContent":["import { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\nimport { AppElementsWire, UNMATCHED_SLOT, type AppElements } from \"./app-elements-wire.js\";\n\nexport {\n AppElementsWire,\n APP_ARTIFACT_COMPATIBILITY_KEY,\n APP_INTERCEPTION_CONTEXT_KEY,\n APP_LAYOUT_FLAGS_KEY,\n APP_ROOT_LAYOUT_KEY,\n APP_ROUTE_KEY,\n APP_UNMATCHED_SLOT_WIRE_VALUE,\n UNMATCHED_SLOT,\n buildOutgoingAppPayload,\n isAppElementsRecord,\n normalizeAppElements,\n readAppElementsMetadata,\n withLayoutFlags,\n type AppElementValue,\n type AppElements,\n type AppOutgoingElements,\n type AppWireElements,\n type LayoutFlags,\n} from \"./app-elements-wire.js\";\n\n// Raw constructor helpers stay private because callers use AppElementsWire codecs.\n\nexport function getMountedSlotIds(elements: AppElements): string[] {\n return Object.keys(elements)\n .filter((key) => {\n const value = elements[key];\n return (\n AppElementsWire.isSlotId(key) &&\n value !== null &&\n value !== undefined &&\n value !== UNMATCHED_SLOT\n );\n })\n .sort();\n}\n\nexport function getMountedSlotIdsHeader(elements: AppElements): string | null {\n return normalizeMountedSlotsHeader(getMountedSlotIds(elements).join(\" \"));\n}\n\nexport function resolveVisitedResponseInterceptionContext(\n requestInterceptionContext: string | null,\n payloadInterceptionContext: string | null,\n): string | null {\n return payloadInterceptionContext ?? requestInterceptionContext;\n}\n"],"mappings":";;;AA0BA,SAAgB,kBAAkB,UAAiC;AACjE,QAAO,OAAO,KAAK,SAAS,CACzB,QAAQ,QAAQ;EACf,MAAM,QAAQ,SAAS;AACvB,SACE,gBAAgB,SAAS,IAAI,IAC7B,UAAU,QACV,UAAU,KAAA,KACV,UAAU;GAEZ,CACD,MAAM;;AAGX,SAAgB,wBAAwB,UAAsC;AAC5E,QAAO,4BAA4B,kBAAkB,SAAS,CAAC,KAAK,IAAI,CAAC;;AAG3E,SAAgB,0CACd,4BACA,4BACe;AACf,QAAO,8BAA8B"}
1
+ {"version":3,"file":"app-elements.js","names":[],"sources":["../../src/server/app-elements.ts"],"sourcesContent":["import { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\nimport { AppElementsWire, UNMATCHED_SLOT, type AppElements } from \"./app-elements-wire.js\";\n\nexport {\n AppElementsWire,\n APP_ARTIFACT_COMPATIBILITY_KEY,\n APP_INTERCEPTION_CONTEXT_KEY,\n APP_LAYOUT_IDS_KEY,\n APP_LAYOUT_FLAGS_KEY,\n APP_ROOT_LAYOUT_KEY,\n APP_ROUTE_KEY,\n APP_UNMATCHED_SLOT_WIRE_VALUE,\n UNMATCHED_SLOT,\n buildOutgoingAppPayload,\n isAppElementsRecord,\n normalizeAppElements,\n readAppElementsMetadata,\n withLayoutFlags,\n type AppElementValue,\n type AppElements,\n type AppOutgoingElements,\n type AppWireElements,\n type LayoutFlags,\n} from \"./app-elements-wire.js\";\n\n// Raw constructor helpers stay private because callers use AppElementsWire codecs.\n\nexport function getMountedSlotIds(elements: AppElements): string[] {\n return Object.keys(elements)\n .filter((key) => {\n const value = elements[key];\n return (\n AppElementsWire.isSlotId(key) &&\n value !== null &&\n value !== undefined &&\n value !== UNMATCHED_SLOT\n );\n })\n .sort();\n}\n\nexport function getMountedSlotIdsHeader(elements: AppElements): string | null {\n return normalizeMountedSlotsHeader(getMountedSlotIds(elements).join(\" \"));\n}\n\nexport function resolveVisitedResponseInterceptionContext(\n requestInterceptionContext: string | null,\n payloadInterceptionContext: string | null,\n): string | null {\n return payloadInterceptionContext ?? requestInterceptionContext;\n}\n"],"mappings":";;;AA2BA,SAAgB,kBAAkB,UAAiC;CACjE,OAAO,OAAO,KAAK,SAAS,CACzB,QAAQ,QAAQ;EACf,MAAM,QAAQ,SAAS;EACvB,OACE,gBAAgB,SAAS,IAAI,IAC7B,UAAU,QACV,UAAU,KAAA,KACV,UAAU;GAEZ,CACD,MAAM;;AAGX,SAAgB,wBAAwB,UAAsC;CAC5E,OAAO,4BAA4B,kBAAkB,SAAS,CAAC,KAAK,IAAI,CAAC;;AAG3E,SAAgB,0CACd,4BACA,4BACe;CACf,OAAO,8BAA8B"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-fallback-renderer.js","names":[],"sources":["../../src/server/app-fallback-renderer.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n renderAppPageErrorBoundary,\n renderAppPageHttpAccessFallback,\n type AppPageBoundaryRoute,\n} from \"./app-page-boundary-render.js\";\nimport type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { AppPageMiddlewareContext } from \"./app-page-response.js\";\nimport type { AppPageSsrHandler } from \"./app-page-stream.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\nimport type { AppElements } from \"./app-elements.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AppPageComponent = import(\"react\").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 AppFallbackRendererRootBoundaries<TModule extends AppPageModule = AppPageModule> = {\n rootForbiddenModule?: TModule | null;\n rootLayouts: readonly (TModule | null | undefined)[];\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n};\n\ntype AppFallbackRendererFontProviders = {\n buildFontLinkHeader: (preloads: readonly AppPageFontPreload[] | null | undefined) => string;\n getFontLinks: () => string[];\n getFontPreloads: () => AppPageFontPreload[];\n getFontStyles: () => string[];\n};\n\ntype AppFallbackRendererOptions<TModule extends AppPageModule = AppPageModule> = {\n clearRequestContext: () => void;\n createRscOnErrorHandler: (\n request: Request,\n pathname: string,\n routePath: string,\n ) => AppPageBoundaryOnError;\n fontProviders: AppFallbackRendererFontProviders;\n getNavigationContext: () => unknown;\n globalErrorModule?: TModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n metadataRoutes: MetadataFileRoute[];\n resolveChildSegments: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => string[];\n rootBoundaries: AppFallbackRendererRootBoundaries<TModule>;\n rscRenderer: (\n element: ReactNode | AppElements,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n sanitizer: (error: Error) => Error;\n ssrLoader: () => Promise<AppPageSsrHandler>;\n};\n\ntype AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {\n renderErrorBoundary: (\n route: AppPageBoundaryRoute<TModule> | null,\n error: unknown,\n isRscRequest: boolean,\n request: Request,\n matchedParams: AppPageParams | undefined,\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n renderHttpAccessFallback: (\n route: AppPageBoundaryRoute<TModule> | null,\n statusCode: number,\n isRscRequest: boolean,\n request: Request,\n opts: {\n boundaryComponent?: AppPageComponent | null;\n layouts?: readonly (TModule | null | undefined)[] | null;\n matchedParams?: AppPageParams;\n },\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n renderNotFound: (\n route: AppPageBoundaryRoute<TModule> | null,\n isRscRequest: boolean,\n request: Request,\n matchedParams: AppPageParams | undefined,\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n};\n\nconst EMPTY_MW_CTX: AppPageMiddlewareContext = { headers: null, status: null };\n\nexport function createAppFallbackRenderer<TModule extends AppPageModule>(\n options: AppFallbackRendererOptions<TModule>,\n): AppFallbackRenderer<TModule> {\n const {\n clearRequestContext,\n createRscOnErrorHandler: buildRscOnErrorHandler,\n fontProviders,\n getNavigationContext,\n globalErrorModule,\n makeThenableParams,\n metadataRoutes,\n resolveChildSegments,\n rootBoundaries,\n rscRenderer,\n sanitizer,\n ssrLoader,\n } = options;\n\n const { rootForbiddenModule, rootLayouts, rootNotFoundModule, rootUnauthorizedModule } =\n rootBoundaries;\n\n return {\n renderHttpAccessFallback(\n route,\n statusCode,\n isRscRequest,\n request,\n opts,\n scriptNonce,\n middlewareContext,\n ) {\n return renderAppPageHttpAccessFallback({\n boundaryComponent: opts?.boundaryComponent ?? null,\n buildFontLinkHeader: fontProviders.buildFontLinkHeader,\n clearRequestContext,\n createRscOnErrorHandler(pathname, routePath) {\n return buildRscOnErrorHandler(request, pathname, routePath);\n },\n getFontLinks: fontProviders.getFontLinks,\n getFontPreloads: fontProviders.getFontPreloads,\n getFontStyles: fontProviders.getFontStyles,\n getNavigationContext,\n globalErrorModule,\n isRscRequest,\n layoutModules: opts?.layouts ?? null,\n loadSsrHandler: ssrLoader,\n makeThenableParams,\n matchedParams: opts?.matchedParams ?? route?.params ?? {},\n middlewareContext: middlewareContext ?? EMPTY_MW_CTX,\n metadataRoutes,\n requestUrl: request.url,\n resolveChildSegments,\n rootForbiddenModule,\n rootLayouts,\n rootNotFoundModule,\n rootUnauthorizedModule,\n route,\n renderToReadableStream: rscRenderer,\n scriptNonce,\n statusCode,\n });\n },\n\n renderNotFound(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext) {\n return this.renderHttpAccessFallback(\n route,\n 404,\n isRscRequest,\n request,\n { matchedParams },\n scriptNonce,\n middlewareContext,\n );\n },\n\n renderErrorBoundary(\n route,\n error,\n isRscRequest,\n request,\n matchedParams,\n scriptNonce,\n middlewareContext,\n ) {\n return renderAppPageErrorBoundary({\n buildFontLinkHeader: fontProviders.buildFontLinkHeader,\n clearRequestContext,\n createRscOnErrorHandler(pathname, routePath) {\n return buildRscOnErrorHandler(request, pathname, routePath);\n },\n error,\n getFontLinks: fontProviders.getFontLinks,\n getFontPreloads: fontProviders.getFontPreloads,\n getFontStyles: fontProviders.getFontStyles,\n getNavigationContext,\n globalErrorModule,\n isRscRequest,\n loadSsrHandler: ssrLoader,\n makeThenableParams,\n matchedParams: matchedParams ?? route?.params ?? {},\n middlewareContext: middlewareContext ?? EMPTY_MW_CTX,\n metadataRoutes,\n requestUrl: request.url,\n resolveChildSegments,\n rootLayouts,\n route,\n renderToReadableStream: rscRenderer,\n sanitizeErrorForClient: sanitizer,\n scriptNonce,\n });\n },\n };\n}\n"],"mappings":";;AAiGA,MAAM,eAAyC;CAAE,SAAS;CAAM,QAAQ;CAAM;AAE9E,SAAgB,0BACd,SAC8B;CAC9B,MAAM,EACJ,qBACA,yBAAyB,wBACzB,eACA,sBACA,mBACA,oBACA,gBACA,sBACA,gBACA,aACA,WACA,cACE;CAEJ,MAAM,EAAE,qBAAqB,aAAa,oBAAoB,2BAC5D;AAEF,QAAO;EACL,yBACE,OACA,YACA,cACA,SACA,MACA,aACA,mBACA;AACA,UAAO,gCAAgC;IACrC,mBAAmB,MAAM,qBAAqB;IAC9C,qBAAqB,cAAc;IACnC;IACA,wBAAwB,UAAU,WAAW;AAC3C,YAAO,uBAAuB,SAAS,UAAU,UAAU;;IAE7D,cAAc,cAAc;IAC5B,iBAAiB,cAAc;IAC/B,eAAe,cAAc;IAC7B;IACA;IACA;IACA,eAAe,MAAM,WAAW;IAChC,gBAAgB;IAChB;IACA,eAAe,MAAM,iBAAiB,OAAO,UAAU,EAAE;IACzD,mBAAmB,qBAAqB;IACxC;IACA,YAAY,QAAQ;IACpB;IACA;IACA;IACA;IACA;IACA;IACA,wBAAwB;IACxB;IACA;IACD,CAAC;;EAGJ,eAAe,OAAO,cAAc,SAAS,eAAe,aAAa,mBAAmB;AAC1F,UAAO,KAAK,yBACV,OACA,KACA,cACA,SACA,EAAE,eAAe,EACjB,aACA,kBACD;;EAGH,oBACE,OACA,OACA,cACA,SACA,eACA,aACA,mBACA;AACA,UAAO,2BAA2B;IAChC,qBAAqB,cAAc;IACnC;IACA,wBAAwB,UAAU,WAAW;AAC3C,YAAO,uBAAuB,SAAS,UAAU,UAAU;;IAE7D;IACA,cAAc,cAAc;IAC5B,iBAAiB,cAAc;IAC/B,eAAe,cAAc;IAC7B;IACA;IACA;IACA,gBAAgB;IAChB;IACA,eAAe,iBAAiB,OAAO,UAAU,EAAE;IACnD,mBAAmB,qBAAqB;IACxC;IACA,YAAY,QAAQ;IACpB;IACA;IACA;IACA,wBAAwB;IACxB,wBAAwB;IACxB;IACD,CAAC;;EAEL"}
1
+ {"version":3,"file":"app-fallback-renderer.js","names":[],"sources":["../../src/server/app-fallback-renderer.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n renderAppPageErrorBoundary,\n renderAppPageHttpAccessFallback,\n type AppPageBoundaryRoute,\n} from \"./app-page-boundary-render.js\";\nimport type { AppPageFontPreload } from \"./app-page-execution.js\";\nimport type { AppPageMiddlewareContext } from \"./app-page-response.js\";\nimport type { AppPageSsrHandler } from \"./app-page-stream.js\";\nimport type { MetadataFileRoute } from \"./metadata-routes.js\";\nimport type { AppElements } from \"./app-elements.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AppPageComponent = import(\"react\").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 AppFallbackRendererRootBoundaries<TModule extends AppPageModule = AppPageModule> = {\n rootForbiddenModule?: TModule | null;\n rootLayouts: readonly (TModule | null | undefined)[];\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n};\n\ntype AppFallbackRendererFontProviders = {\n buildFontLinkHeader: (preloads: readonly AppPageFontPreload[] | null | undefined) => string;\n getFontLinks: () => string[];\n getFontPreloads: () => AppPageFontPreload[];\n getFontStyles: () => string[];\n};\n\ntype AppFallbackRendererOptions<TModule extends AppPageModule = AppPageModule> = {\n clearRequestContext: () => void;\n createRscOnErrorHandler: (\n request: Request,\n pathname: string,\n routePath: string,\n ) => AppPageBoundaryOnError;\n fontProviders: AppFallbackRendererFontProviders;\n getNavigationContext: () => unknown;\n globalErrorModule?: TModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n metadataRoutes: MetadataFileRoute[];\n resolveChildSegments: (\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n ) => string[];\n rootBoundaries: AppFallbackRendererRootBoundaries<TModule>;\n rscRenderer: (\n element: ReactNode | AppElements,\n options: { onError: AppPageBoundaryOnError },\n ) => ReadableStream<Uint8Array>;\n sanitizer: (error: Error) => Error;\n ssrLoader: () => Promise<AppPageSsrHandler>;\n};\n\ntype AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {\n renderErrorBoundary: (\n route: AppPageBoundaryRoute<TModule> | null,\n error: unknown,\n isRscRequest: boolean,\n request: Request,\n matchedParams: AppPageParams | undefined,\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n renderHttpAccessFallback: (\n route: AppPageBoundaryRoute<TModule> | null,\n statusCode: number,\n isRscRequest: boolean,\n request: Request,\n opts: {\n boundaryComponent?: AppPageComponent | null;\n layouts?: readonly (TModule | null | undefined)[] | null;\n matchedParams?: AppPageParams;\n },\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n renderNotFound: (\n route: AppPageBoundaryRoute<TModule> | null,\n isRscRequest: boolean,\n request: Request,\n matchedParams: AppPageParams | undefined,\n scriptNonce: string | undefined,\n middlewareContext: AppPageMiddlewareContext,\n ) => Promise<Response | null>;\n};\n\nconst EMPTY_MW_CTX: AppPageMiddlewareContext = { headers: null, status: null };\n\nexport function createAppFallbackRenderer<TModule extends AppPageModule>(\n options: AppFallbackRendererOptions<TModule>,\n): AppFallbackRenderer<TModule> {\n const {\n clearRequestContext,\n createRscOnErrorHandler: buildRscOnErrorHandler,\n fontProviders,\n getNavigationContext,\n globalErrorModule,\n makeThenableParams,\n metadataRoutes,\n resolveChildSegments,\n rootBoundaries,\n rscRenderer,\n sanitizer,\n ssrLoader,\n } = options;\n\n const { rootForbiddenModule, rootLayouts, rootNotFoundModule, rootUnauthorizedModule } =\n rootBoundaries;\n\n return {\n renderHttpAccessFallback(\n route,\n statusCode,\n isRscRequest,\n request,\n opts,\n scriptNonce,\n middlewareContext,\n ) {\n return renderAppPageHttpAccessFallback({\n boundaryComponent: opts?.boundaryComponent ?? null,\n buildFontLinkHeader: fontProviders.buildFontLinkHeader,\n clearRequestContext,\n createRscOnErrorHandler(pathname, routePath) {\n return buildRscOnErrorHandler(request, pathname, routePath);\n },\n getFontLinks: fontProviders.getFontLinks,\n getFontPreloads: fontProviders.getFontPreloads,\n getFontStyles: fontProviders.getFontStyles,\n getNavigationContext,\n globalErrorModule,\n isRscRequest,\n layoutModules: opts?.layouts ?? null,\n loadSsrHandler: ssrLoader,\n makeThenableParams,\n matchedParams: opts?.matchedParams ?? route?.params ?? {},\n middlewareContext: middlewareContext ?? EMPTY_MW_CTX,\n metadataRoutes,\n requestUrl: request.url,\n resolveChildSegments,\n rootForbiddenModule,\n rootLayouts,\n rootNotFoundModule,\n rootUnauthorizedModule,\n route,\n renderToReadableStream: rscRenderer,\n scriptNonce,\n statusCode,\n });\n },\n\n renderNotFound(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext) {\n return this.renderHttpAccessFallback(\n route,\n 404,\n isRscRequest,\n request,\n { matchedParams },\n scriptNonce,\n middlewareContext,\n );\n },\n\n renderErrorBoundary(\n route,\n error,\n isRscRequest,\n request,\n matchedParams,\n scriptNonce,\n middlewareContext,\n ) {\n return renderAppPageErrorBoundary({\n buildFontLinkHeader: fontProviders.buildFontLinkHeader,\n clearRequestContext,\n createRscOnErrorHandler(pathname, routePath) {\n return buildRscOnErrorHandler(request, pathname, routePath);\n },\n error,\n getFontLinks: fontProviders.getFontLinks,\n getFontPreloads: fontProviders.getFontPreloads,\n getFontStyles: fontProviders.getFontStyles,\n getNavigationContext,\n globalErrorModule,\n isRscRequest,\n loadSsrHandler: ssrLoader,\n makeThenableParams,\n matchedParams: matchedParams ?? route?.params ?? {},\n middlewareContext: middlewareContext ?? EMPTY_MW_CTX,\n metadataRoutes,\n requestUrl: request.url,\n resolveChildSegments,\n rootLayouts,\n route,\n renderToReadableStream: rscRenderer,\n sanitizeErrorForClient: sanitizer,\n scriptNonce,\n });\n },\n };\n}\n"],"mappings":";;AAiGA,MAAM,eAAyC;CAAE,SAAS;CAAM,QAAQ;CAAM;AAE9E,SAAgB,0BACd,SAC8B;CAC9B,MAAM,EACJ,qBACA,yBAAyB,wBACzB,eACA,sBACA,mBACA,oBACA,gBACA,sBACA,gBACA,aACA,WACA,cACE;CAEJ,MAAM,EAAE,qBAAqB,aAAa,oBAAoB,2BAC5D;CAEF,OAAO;EACL,yBACE,OACA,YACA,cACA,SACA,MACA,aACA,mBACA;GACA,OAAO,gCAAgC;IACrC,mBAAmB,MAAM,qBAAqB;IAC9C,qBAAqB,cAAc;IACnC;IACA,wBAAwB,UAAU,WAAW;KAC3C,OAAO,uBAAuB,SAAS,UAAU,UAAU;;IAE7D,cAAc,cAAc;IAC5B,iBAAiB,cAAc;IAC/B,eAAe,cAAc;IAC7B;IACA;IACA;IACA,eAAe,MAAM,WAAW;IAChC,gBAAgB;IAChB;IACA,eAAe,MAAM,iBAAiB,OAAO,UAAU,EAAE;IACzD,mBAAmB,qBAAqB;IACxC;IACA,YAAY,QAAQ;IACpB;IACA;IACA;IACA;IACA;IACA;IACA,wBAAwB;IACxB;IACA;IACD,CAAC;;EAGJ,eAAe,OAAO,cAAc,SAAS,eAAe,aAAa,mBAAmB;GAC1F,OAAO,KAAK,yBACV,OACA,KACA,cACA,SACA,EAAE,eAAe,EACjB,aACA,kBACD;;EAGH,oBACE,OACA,OACA,cACA,SACA,eACA,aACA,mBACA;GACA,OAAO,2BAA2B;IAChC,qBAAqB,cAAc;IACnC;IACA,wBAAwB,UAAU,WAAW;KAC3C,OAAO,uBAAuB,SAAS,UAAU,UAAU;;IAE7D;IACA,cAAc,cAAc;IAC5B,iBAAiB,cAAc;IAC/B,eAAe,cAAc;IAC7B;IACA;IACA;IACA,gBAAgB;IAChB;IACA,eAAe,iBAAiB,OAAO,UAAU,EAAE;IACnD,mBAAmB,qBAAqB;IACxC;IACA,YAAY,QAAQ;IACpB;IACA;IACA;IACA,wBAAwB;IACxB,wBAAwB;IACxB;IACD,CAAC;;EAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-hook-warning-suppression.js","names":[],"sources":["../../src/server/app-hook-warning-suppression.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport const suppressHookWarningAls = new AsyncLocalStorage<boolean>();\n\nconst _origConsoleError = console.error;\nconsole.error = (...args: unknown[]) => {\n if (\n suppressHookWarningAls.getStore() === true &&\n typeof args[0] === \"string\" &&\n args[0].includes(\"Invalid hook call\")\n )\n return;\n _origConsoleError.apply(console, args);\n};\n"],"mappings":";;AAEA,MAAa,yBAAyB,IAAI,mBAA4B;AAEtE,MAAM,oBAAoB,QAAQ;AAClC,QAAQ,SAAS,GAAG,SAAoB;AACtC,KACE,uBAAuB,UAAU,KAAK,QACtC,OAAO,KAAK,OAAO,YACnB,KAAK,GAAG,SAAS,oBAAoB,CAErC;AACF,mBAAkB,MAAM,SAAS,KAAK"}
1
+ {"version":3,"file":"app-hook-warning-suppression.js","names":[],"sources":["../../src/server/app-hook-warning-suppression.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport const suppressHookWarningAls = new AsyncLocalStorage<boolean>();\n\nconst _origConsoleError = console.error;\nconsole.error = (...args: unknown[]) => {\n if (\n suppressHookWarningAls.getStore() === true &&\n typeof args[0] === \"string\" &&\n args[0].includes(\"Invalid hook call\")\n )\n return;\n _origConsoleError.apply(console, args);\n};\n"],"mappings":";;AAEA,MAAa,yBAAyB,IAAI,mBAA4B;AAEtE,MAAM,oBAAoB,QAAQ;AAClC,QAAQ,SAAS,GAAG,SAAoB;CACtC,IACE,uBAAuB,UAAU,KAAK,QACtC,OAAO,KAAK,OAAO,YACnB,KAAK,GAAG,SAAS,oBAAoB,EAErC;CACF,kBAAkB,MAAM,SAAS,KAAK"}
@@ -1,5 +1,6 @@
1
1
  import { NextI18nConfig } from "../config/next-config.js";
2
2
  import { MiddlewareModule } from "./middleware-runtime.js";
3
+ import { FLIGHT_HEADERS } from "./headers.js";
3
4
 
4
5
  //#region src/server/app-middleware.d.ts
5
6
  type AppMiddlewareContext = {
@@ -24,7 +25,6 @@ type ApplyAppMiddlewareResult = {
24
25
  kind: "response";
25
26
  response: Response;
26
27
  };
27
- declare const FLIGHT_HEADERS: readonly string[];
28
28
  declare function isExternalMiddlewareRewrite(rewriteUrl: string, request: Request): boolean;
29
29
  declare function proxyExternalMiddlewareRewrite(request: Request, rewriteUrl: string, context: AppMiddlewareContext): Promise<Response>;
30
30
  declare function applyAppMiddleware(options: ApplyAppMiddlewareOptions): Promise<ApplyAppMiddlewareResult>;
@@ -1,3 +1,4 @@
1
+ import { FLIGHT_HEADERS, VINEXT_MW_CTX_HEADER } from "./headers.js";
1
2
  import { buildRequestHeadersFromMiddlewareResponse } from "./middleware-request-headers.js";
2
3
  import { isExternalUrl, proxyExternalRequest } from "../config/config-matchers.js";
3
4
  import { internalServerErrorResponse } from "./http-error-responses.js";
@@ -7,13 +8,6 @@ import { applyMiddlewareRequestHeaders, setHeadersContext } from "../shims/heade
7
8
  import { setNavigationContext } from "../shims/navigation.js";
8
9
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
9
10
  //#region src/server/app-middleware.ts
10
- const FLIGHT_HEADERS = [
11
- "rsc",
12
- "next-router-state-tree",
13
- "next-router-prefetch",
14
- "next-hmr-refresh",
15
- "next-router-segment-prefetch"
16
- ];
17
11
  const FLIGHT_HEADER_SET = new Set(FLIGHT_HEADERS);
18
12
  function isForwardedMiddlewareContext(value) {
19
13
  return !!value && typeof value === "object";
@@ -45,7 +39,7 @@ function isExternalMiddlewareRewrite(rewriteUrl, request) {
45
39
  return new URL(rewriteUrl, request.url).origin !== new URL(request.url).origin;
46
40
  }
47
41
  function requestWithMiddlewareRequestHeaders(request, middlewareHeaders) {
48
- const nextHeaders = middlewareHeaders ? buildRequestHeadersFromMiddlewareResponse(request.headers, middlewareHeaders) : null;
42
+ const nextHeaders = middlewareHeaders ? buildRequestHeadersFromMiddlewareResponse(request.headers, middlewareHeaders, { preserveCredentialHeaders: true }) : null;
49
43
  if (!nextHeaders) return request;
50
44
  const init = {
51
45
  method: request.method,
@@ -81,7 +75,7 @@ async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
81
75
  }
82
76
  function applyForwardedMiddlewareContext(request, context) {
83
77
  if (process.env.NODE_ENV === "production") return { applied: false };
84
- const header = request.headers.get("x-vinext-mw-ctx");
78
+ const header = request.headers.get(VINEXT_MW_CTX_HEADER);
85
79
  if (!header) return { applied: false };
86
80
  try {
87
81
  const data = JSON.parse(header);
@@ -142,6 +136,7 @@ async function applyAppMiddleware(options) {
142
136
  };
143
137
  }
144
138
  if (result.responseHeaders) options.context.headers = new Headers(result.responseHeaders);
139
+ if (result.status !== void 0) options.context.status = result.status;
145
140
  if (result.rewriteUrl) {
146
141
  if (result.rewriteStatus !== void 0) options.context.status = result.rewriteStatus;
147
142
  if (isExternalUrl(result.rewriteUrl)) return {