@rangojs/router 0.0.0-experimental.bd6e11bc → 0.0.0-experimental.bdaf10aa

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 (411) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +296 -887
  3. package/dist/bin/rango.js +459 -91
  4. package/dist/testing/vitest.js +36 -2
  5. package/dist/vite/index.js +1708 -414
  6. package/package.json +35 -10
  7. package/skills/api-client/SKILL.md +211 -0
  8. package/skills/breadcrumbs/SKILL.md +82 -5
  9. package/skills/bundle-analysis/SKILL.md +2 -2
  10. package/skills/cache-guide/SKILL.md +14 -9
  11. package/skills/caching/SKILL.md +221 -12
  12. package/skills/catalog.json +271 -0
  13. package/skills/comparison/SKILL.md +50 -0
  14. package/skills/comparison/agents/openai.yaml +4 -0
  15. package/skills/comparison/references/framework-comparison.md +837 -0
  16. package/skills/composability/SKILL.md +83 -2
  17. package/skills/css/SKILL.md +76 -0
  18. package/skills/debug-manifest/SKILL.md +5 -3
  19. package/skills/defer-hydration/SKILL.md +235 -0
  20. package/skills/document-cache/SKILL.md +11 -3
  21. package/skills/fonts/SKILL.md +1 -1
  22. package/skills/handler-use/SKILL.md +9 -9
  23. package/skills/hooks/SKILL.md +73 -900
  24. package/skills/hooks/data.md +273 -0
  25. package/skills/hooks/handle-and-actions.md +103 -0
  26. package/skills/hooks/navigation.md +110 -0
  27. package/skills/hooks/outlets.md +41 -0
  28. package/skills/hooks/state.md +228 -0
  29. package/skills/hooks/urls.md +135 -0
  30. package/skills/host-router/SKILL.md +84 -7
  31. package/skills/i18n/SKILL.md +1 -1
  32. package/skills/intercept/SKILL.md +51 -17
  33. package/skills/layout/SKILL.md +38 -16
  34. package/skills/links/SKILL.md +1 -1
  35. package/skills/loader/SKILL.md +48 -20
  36. package/skills/middleware/SKILL.md +11 -5
  37. package/skills/migrate-nextjs/SKILL.md +203 -20
  38. package/skills/migrate-react-router/SKILL.md +59 -675
  39. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  40. package/skills/migrate-react-router/component-migration.md +196 -0
  41. package/skills/migrate-react-router/data-and-actions.md +225 -0
  42. package/skills/migrate-react-router/route-mapping.md +271 -0
  43. package/skills/mime-routes/SKILL.md +3 -3
  44. package/skills/observability/SKILL.md +70 -5
  45. package/skills/parallel/SKILL.md +32 -8
  46. package/skills/ppr/SKILL.md +622 -0
  47. package/skills/prerender/SKILL.md +59 -28
  48. package/skills/rango/SKILL.md +124 -50
  49. package/skills/response-routes/SKILL.md +78 -46
  50. package/skills/route/SKILL.md +85 -6
  51. package/skills/router-setup/SKILL.md +41 -6
  52. package/skills/scripts/SKILL.md +179 -0
  53. package/skills/server-actions/SKILL.md +28 -3
  54. package/skills/shell-manifest/SKILL.md +185 -0
  55. package/skills/streams-and-websockets/SKILL.md +1 -1
  56. package/skills/tailwind/SKILL.md +28 -4
  57. package/skills/testing/SKILL.md +68 -654
  58. package/skills/testing/bindings.md +103 -0
  59. package/skills/testing/cache-prerender.md +127 -0
  60. package/skills/testing/client-components.md +124 -0
  61. package/skills/testing/e2e-parity.md +125 -0
  62. package/skills/testing/flight.md +91 -0
  63. package/skills/testing/handles.md +131 -0
  64. package/skills/testing/loader.md +128 -0
  65. package/skills/testing/middleware.md +99 -0
  66. package/skills/testing/render-handler.md +122 -0
  67. package/skills/testing/response-routes.md +95 -0
  68. package/skills/testing/reverse-and-types.md +85 -0
  69. package/skills/testing/server-actions.md +107 -0
  70. package/skills/testing/server-tree.md +128 -0
  71. package/skills/testing/setup.md +123 -0
  72. package/skills/theme/SKILL.md +1 -1
  73. package/skills/typesafety/SKILL.md +45 -918
  74. package/skills/typesafety/env-and-bindings.md +254 -0
  75. package/skills/typesafety/generated-files-and-cli.md +335 -0
  76. package/skills/typesafety/params-and-search.md +153 -0
  77. package/skills/typesafety/route-types.md +209 -0
  78. package/skills/use-cache/SKILL.md +47 -17
  79. package/skills/vercel/SKILL.md +128 -0
  80. package/skills/view-transitions/SKILL.md +44 -1
  81. package/src/__augment-tests__/augmented.check.ts +2 -3
  82. package/src/__internal.ts +0 -65
  83. package/src/browser/action-coordinator.ts +1 -1
  84. package/src/browser/action-fence.ts +47 -0
  85. package/src/browser/app-shell.ts +14 -27
  86. package/src/browser/connection-warmup.ts +134 -0
  87. package/src/browser/cookie-name.ts +140 -0
  88. package/src/browser/event-controller.ts +178 -100
  89. package/src/browser/invalidate-client-cache.ts +52 -0
  90. package/src/browser/logging.ts +28 -0
  91. package/src/browser/merge-segment-loaders.ts +6 -4
  92. package/src/browser/navigation-bridge.ts +81 -68
  93. package/src/browser/navigation-client.ts +115 -70
  94. package/src/browser/navigation-store-handle.ts +38 -0
  95. package/src/browser/navigation-store.ts +153 -88
  96. package/src/browser/navigation-transaction.ts +0 -32
  97. package/src/browser/network-error-handler.ts +34 -7
  98. package/src/browser/partial-update.ts +157 -144
  99. package/src/browser/prefetch/cache.ts +148 -81
  100. package/src/browser/prefetch/fetch.ts +231 -51
  101. package/src/browser/prefetch/queue.ts +25 -7
  102. package/src/browser/rango-state.ts +157 -115
  103. package/src/browser/react/Link.tsx +40 -7
  104. package/src/browser/react/NavigationProvider.tsx +140 -99
  105. package/src/browser/react/ScrollRestoration.tsx +10 -6
  106. package/src/browser/react/filter-segment-order.ts +17 -2
  107. package/src/browser/react/index.ts +0 -51
  108. package/src/browser/react/location-state-shared.ts +14 -15
  109. package/src/browser/react/location-state.ts +0 -1
  110. package/src/browser/react/use-action.ts +6 -15
  111. package/src/browser/react/use-handle.ts +0 -5
  112. package/src/browser/react/use-href.tsx +8 -1
  113. package/src/browser/react/use-link-status.ts +33 -8
  114. package/src/browser/react/use-navigation.ts +10 -5
  115. package/src/browser/react/use-params.ts +0 -2
  116. package/src/browser/react/use-router.ts +6 -4
  117. package/src/browser/react/use-search-params.ts +0 -5
  118. package/src/browser/react/use-segments.ts +0 -13
  119. package/src/browser/response-adapter.ts +74 -8
  120. package/src/browser/rsc-router.tsx +97 -22
  121. package/src/browser/scroll-restoration.ts +15 -8
  122. package/src/browser/segment-reconciler.ts +31 -21
  123. package/src/browser/server-action-bridge.ts +216 -38
  124. package/src/browser/types.ts +94 -22
  125. package/src/browser/validate-redirect-origin.ts +43 -16
  126. package/src/build/generate-manifest.ts +155 -131
  127. package/src/build/generate-route-types.ts +1 -1
  128. package/src/build/index.ts +11 -5
  129. package/src/build/prefix-tree-utils.ts +123 -0
  130. package/src/build/route-trie.ts +152 -22
  131. package/src/build/route-types/ast-route-extraction.ts +15 -8
  132. package/src/build/route-types/codegen.ts +12 -1
  133. package/src/build/route-types/include-resolution.ts +455 -61
  134. package/src/build/route-types/param-extraction.ts +6 -3
  135. package/src/build/route-types/per-module-writer.ts +15 -2
  136. package/src/build/route-types/router-processing.ts +77 -41
  137. package/src/build/route-types/source-scan.ts +105 -7
  138. package/src/build/runtime-discovery.ts +4 -1
  139. package/src/cache/cache-error.ts +104 -0
  140. package/src/cache/cache-key-utils.ts +58 -13
  141. package/src/cache/cache-policy.ts +108 -34
  142. package/src/cache/cache-runtime.ts +454 -101
  143. package/src/cache/cache-scope.ts +159 -54
  144. package/src/cache/cache-tag.ts +149 -0
  145. package/src/cache/cf/cf-base64.ts +33 -0
  146. package/src/cache/cf/cf-cache-constants.ts +127 -0
  147. package/src/cache/cf/cf-cache-store.ts +2170 -377
  148. package/src/cache/cf/cf-cache-types.ts +349 -0
  149. package/src/cache/cf/cf-kv-utils.ts +46 -0
  150. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  151. package/src/cache/cf/index.ts +6 -16
  152. package/src/cache/document-cache.ts +126 -41
  153. package/src/cache/handle-snapshot.ts +70 -0
  154. package/src/cache/index.ts +23 -20
  155. package/src/cache/memory-segment-store.ts +243 -37
  156. package/src/cache/profile-registry.ts +46 -31
  157. package/src/cache/read-through-swr.ts +56 -12
  158. package/src/cache/segment-codec.ts +13 -21
  159. package/src/cache/shell-snapshot.ts +417 -0
  160. package/src/cache/tag-invalidation.ts +230 -0
  161. package/src/cache/types.ts +194 -99
  162. package/src/cache/vercel/index.ts +11 -0
  163. package/src/cache/vercel/vercel-cache-store.ts +1132 -0
  164. package/src/client.rsc.tsx +39 -22
  165. package/src/client.tsx +28 -58
  166. package/src/cloudflare/index.ts +11 -0
  167. package/src/cloudflare/tracing.ts +108 -0
  168. package/src/component-utils.ts +19 -0
  169. package/src/components/DefaultDocument.tsx +8 -2
  170. package/src/context-var.ts +13 -1
  171. package/src/decode-loader-results.ts +18 -2
  172. package/src/defer.ts +185 -0
  173. package/src/deps/ssr.ts +0 -1
  174. package/src/encode-kv.ts +49 -0
  175. package/src/errors.ts +0 -3
  176. package/src/escape-script.ts +52 -0
  177. package/src/handle.ts +57 -40
  178. package/src/handles/MetaTags.tsx +24 -53
  179. package/src/handles/Scripts.tsx +183 -0
  180. package/src/handles/breadcrumbs.ts +35 -8
  181. package/src/handles/deferred-resolution.ts +127 -0
  182. package/src/handles/is-thenable.ts +18 -0
  183. package/src/handles/meta.ts +14 -40
  184. package/src/handles/script.ts +244 -0
  185. package/src/host/cookie-handler.ts +9 -60
  186. package/src/host/errors.ts +13 -22
  187. package/src/host/index.ts +7 -0
  188. package/src/host/pattern-matcher.ts +23 -52
  189. package/src/host/router.ts +1 -65
  190. package/src/host/testing.ts +40 -27
  191. package/src/host/types.ts +6 -2
  192. package/src/href-client.ts +7 -12
  193. package/src/index.rsc.ts +88 -8
  194. package/src/index.ts +90 -16
  195. package/src/internal-debug.ts +11 -10
  196. package/src/loader.rsc.ts +19 -9
  197. package/src/loader.ts +12 -4
  198. package/src/outlet-provider.tsx +1 -5
  199. package/src/prerender/param-hash.ts +16 -16
  200. package/src/prerender/store.ts +32 -37
  201. package/src/prerender.ts +75 -7
  202. package/src/redirect-origin.ts +114 -0
  203. package/src/regex-escape.ts +8 -0
  204. package/src/render-error-thrower.tsx +20 -0
  205. package/src/response-utils.ts +25 -0
  206. package/src/root-error-boundary.tsx +1 -19
  207. package/src/route-content-wrapper.tsx +13 -49
  208. package/src/route-definition/dsl-helpers.ts +60 -53
  209. package/src/route-definition/helper-factories.ts +0 -2
  210. package/src/route-definition/helpers-types.ts +46 -46
  211. package/src/route-definition/index.ts +1 -2
  212. package/src/route-definition/redirect.ts +44 -11
  213. package/src/route-definition/resolve-handler-use.ts +6 -1
  214. package/src/route-definition/use-item-types.ts +3 -6
  215. package/src/route-map-builder.ts +41 -20
  216. package/src/route-types.ts +0 -5
  217. package/src/router/content-negotiation.ts +58 -23
  218. package/src/router/error-handling.ts +44 -17
  219. package/src/router/find-match.ts +129 -30
  220. package/src/router/handler-context.ts +6 -1
  221. package/src/router/instrument.ts +355 -0
  222. package/src/router/intercept-resolution.ts +35 -2
  223. package/src/router/lazy-includes.ts +79 -56
  224. package/src/router/loader-resolution.ts +151 -73
  225. package/src/router/logging.ts +0 -6
  226. package/src/router/manifest.ts +74 -40
  227. package/src/router/match-api.ts +76 -52
  228. package/src/router/match-context.ts +0 -22
  229. package/src/router/match-handlers.ts +181 -178
  230. package/src/router/match-middleware/background-revalidation.ts +40 -24
  231. package/src/router/match-middleware/cache-lookup.ts +115 -194
  232. package/src/router/match-middleware/cache-store.ts +61 -50
  233. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  234. package/src/router/match-middleware/segment-resolution.ts +0 -22
  235. package/src/router/match-pipelines.ts +1 -42
  236. package/src/router/match-result.ts +36 -67
  237. package/src/router/metrics.ts +0 -34
  238. package/src/router/middleware-types.ts +0 -116
  239. package/src/router/middleware.ts +231 -120
  240. package/src/router/navigation-snapshot.ts +7 -56
  241. package/src/router/params-util.ts +23 -0
  242. package/src/router/parse-pattern.ts +115 -0
  243. package/src/router/pattern-matching.ts +99 -152
  244. package/src/router/prefetch-cache-ttl.ts +51 -0
  245. package/src/router/prefetch-limits.ts +37 -0
  246. package/src/router/prerender-match.ts +111 -66
  247. package/src/router/preview-match.ts +3 -1
  248. package/src/router/request-classification.ts +47 -42
  249. package/src/router/revalidation.ts +75 -81
  250. package/src/router/route-snapshot.ts +14 -3
  251. package/src/router/router-context.ts +6 -29
  252. package/src/router/router-interfaces.ts +70 -8
  253. package/src/router/router-options.ts +126 -4
  254. package/src/router/segment-resolution/fresh.ts +104 -80
  255. package/src/router/segment-resolution/helpers.ts +86 -6
  256. package/src/router/segment-resolution/loader-cache.ts +155 -39
  257. package/src/router/segment-resolution/loader-mask.ts +60 -0
  258. package/src/router/segment-resolution/loader-snapshot.ts +259 -0
  259. package/src/router/segment-resolution/mask-nested.ts +83 -0
  260. package/src/router/segment-resolution/revalidation.ts +215 -304
  261. package/src/router/segment-resolution/static-store.ts +19 -5
  262. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  263. package/src/router/segment-resolution/view-transition-default.ts +35 -15
  264. package/src/router/segment-resolution.ts +5 -1
  265. package/src/router/segment-wrappers.ts +6 -5
  266. package/src/router/state-cookie-name.ts +33 -0
  267. package/src/router/substitute-pattern-params.ts +54 -35
  268. package/src/router/telemetry-otel.ts +160 -200
  269. package/src/router/telemetry.ts +9 -23
  270. package/src/router/timeout.ts +0 -20
  271. package/src/router/tracing.ts +215 -0
  272. package/src/router/trie-matching.ts +171 -64
  273. package/src/router/types.ts +1 -63
  274. package/src/router/url-params.ts +13 -5
  275. package/src/router.ts +119 -48
  276. package/src/rsc/full-payload.ts +70 -0
  277. package/src/rsc/handler-context.ts +1 -0
  278. package/src/rsc/handler.ts +267 -152
  279. package/src/rsc/helpers.ts +78 -4
  280. package/src/rsc/index.ts +1 -4
  281. package/src/rsc/json-route-result.ts +38 -0
  282. package/src/rsc/loader-fetch.ts +114 -38
  283. package/src/rsc/manifest-init.ts +29 -42
  284. package/src/rsc/nonce.ts +10 -1
  285. package/src/rsc/origin-guard.ts +11 -15
  286. package/src/rsc/progressive-enhancement.ts +120 -13
  287. package/src/rsc/redirect-guard.ts +100 -0
  288. package/src/rsc/response-cache-serve.ts +238 -0
  289. package/src/rsc/response-error.ts +79 -12
  290. package/src/rsc/response-route-handler.ts +58 -141
  291. package/src/rsc/rsc-rendering.ts +492 -49
  292. package/src/rsc/runtime-warnings.ts +14 -0
  293. package/src/rsc/server-action.ts +268 -82
  294. package/src/rsc/shell-capture.ts +1190 -0
  295. package/src/rsc/shell-serve.ts +181 -0
  296. package/src/rsc/transition-gate.ts +89 -0
  297. package/src/rsc/types.ts +45 -3
  298. package/src/runtime-env.ts +18 -0
  299. package/src/search-params.ts +31 -26
  300. package/src/segment-loader-promise.ts +49 -4
  301. package/src/segment-system.tsx +260 -95
  302. package/src/server/context.ts +99 -9
  303. package/src/server/cookie-parse.ts +32 -0
  304. package/src/server/cookie-store.ts +125 -2
  305. package/src/server/handle-store.ts +21 -38
  306. package/src/server/loader-registry.ts +33 -42
  307. package/src/server/request-context.ts +379 -138
  308. package/src/ssr/index.tsx +491 -182
  309. package/src/ssr/inject-rsc-eager.ts +167 -0
  310. package/src/ssr/ssr-root.tsx +228 -0
  311. package/src/static-handler.ts +10 -13
  312. package/src/testing/cache-status.ts +44 -48
  313. package/src/testing/collect-handle.ts +14 -31
  314. package/src/testing/dispatch.ts +533 -160
  315. package/src/testing/e2e/fixture.ts +45 -11
  316. package/src/testing/e2e/index.ts +1 -22
  317. package/src/testing/e2e/matchers.ts +0 -16
  318. package/src/testing/e2e/parity.ts +85 -4
  319. package/src/testing/e2e/server.ts +12 -0
  320. package/src/testing/flight-matchers.ts +7 -14
  321. package/src/testing/flight-normalize.ts +11 -0
  322. package/src/testing/flight-runtime.d.ts +36 -0
  323. package/src/testing/flight-tree.ts +682 -0
  324. package/src/testing/flight.entry.ts +30 -0
  325. package/src/testing/flight.ts +145 -70
  326. package/src/testing/generated-routes.ts +26 -50
  327. package/src/testing/index.ts +18 -19
  328. package/src/testing/internal/context.ts +184 -68
  329. package/src/testing/internal/flight-client-globals.ts +30 -0
  330. package/src/testing/internal/seed-vars.ts +54 -0
  331. package/src/testing/render-handler.ts +357 -0
  332. package/src/testing/render-route.tsx +134 -115
  333. package/src/testing/run-loader.ts +140 -51
  334. package/src/testing/run-middleware.ts +59 -33
  335. package/src/testing/run-transition-when.ts +164 -0
  336. package/src/testing/vitest-stubs/cloudflare-email.ts +1 -1
  337. package/src/testing/vitest-stubs/cloudflare-workers.ts +1 -1
  338. package/src/testing/vitest.ts +138 -16
  339. package/src/theme/ThemeProvider.tsx +56 -84
  340. package/src/theme/ThemeScript.tsx +7 -9
  341. package/src/theme/constants.ts +52 -13
  342. package/src/theme/index.ts +0 -7
  343. package/src/theme/theme-context.ts +1 -5
  344. package/src/theme/theme-script.ts +22 -21
  345. package/src/theme/use-theme.ts +0 -3
  346. package/src/types/boundaries.ts +0 -35
  347. package/src/types/cache-types.ts +13 -4
  348. package/src/types/error-types.ts +30 -90
  349. package/src/types/global-namespace.ts +15 -15
  350. package/src/types/handler-context.ts +45 -15
  351. package/src/types/index.ts +2 -10
  352. package/src/types/loader-types.ts +6 -3
  353. package/src/types/request-scope.ts +8 -22
  354. package/src/types/route-config.ts +20 -52
  355. package/src/types/route-entry.ts +0 -6
  356. package/src/types/segments.ts +100 -13
  357. package/src/urls/include-helper.ts +10 -12
  358. package/src/urls/include-provider.ts +71 -0
  359. package/src/urls/index.ts +2 -8
  360. package/src/urls/path-helper-types.ts +52 -14
  361. package/src/urls/path-helper.ts +5 -54
  362. package/src/urls/pattern-types.ts +36 -0
  363. package/src/urls/type-extraction.ts +76 -42
  364. package/src/urls/urls-function.ts +0 -14
  365. package/src/use-loader.tsx +0 -186
  366. package/src/vercel/index.ts +11 -0
  367. package/src/vercel/tracing.ts +88 -0
  368. package/src/vite/discovery/bundle-postprocess.ts +2 -1
  369. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  370. package/src/vite/discovery/discover-routers.ts +34 -43
  371. package/src/vite/discovery/discovery-errors.ts +61 -0
  372. package/src/vite/discovery/prerender-collection.ts +33 -46
  373. package/src/vite/discovery/state.ts +12 -1
  374. package/src/vite/discovery/virtual-module-codegen.ts +1 -11
  375. package/src/vite/index.ts +9 -0
  376. package/src/vite/inject-client-debug.ts +88 -0
  377. package/src/vite/plugin-types.ts +143 -10
  378. package/src/vite/plugins/cjs-to-esm.ts +8 -12
  379. package/src/vite/plugins/client-ref-dedup.ts +0 -11
  380. package/src/vite/plugins/client-ref-hashing.ts +0 -10
  381. package/src/vite/plugins/cloudflare-protocol-stub.ts +0 -20
  382. package/src/vite/plugins/expose-action-id.ts +2 -73
  383. package/src/vite/plugins/expose-id-utils.ts +85 -56
  384. package/src/vite/plugins/expose-ids/export-analysis.ts +30 -43
  385. package/src/vite/plugins/expose-ids/handler-transform.ts +5 -31
  386. package/src/vite/plugins/expose-ids/loader-transform.ts +12 -20
  387. package/src/vite/plugins/expose-ids/router-transform.ts +98 -26
  388. package/src/vite/plugins/expose-internal-ids.ts +10 -1
  389. package/src/vite/plugins/performance-tracks.ts +0 -3
  390. package/src/vite/plugins/refresh-cmd.ts +1 -1
  391. package/src/vite/plugins/use-cache-transform.ts +21 -46
  392. package/src/vite/plugins/vercel-output.ts +384 -0
  393. package/src/vite/plugins/version-injector.ts +22 -27
  394. package/src/vite/plugins/version-plugin.ts +6 -66
  395. package/src/vite/plugins/virtual-entries.ts +137 -26
  396. package/src/vite/rango.ts +146 -135
  397. package/src/vite/router-discovery.ts +189 -48
  398. package/src/vite/utils/ast-handler-extract.ts +11 -20
  399. package/src/vite/utils/bundle-analysis.ts +6 -13
  400. package/src/vite/utils/client-chunks.ts +0 -6
  401. package/src/vite/utils/directive-prologue.ts +40 -0
  402. package/src/vite/utils/forward-user-plugins.ts +0 -22
  403. package/src/vite/utils/manifest-utils.ts +4 -75
  404. package/src/vite/utils/package-resolution.ts +1 -73
  405. package/src/vite/utils/prerender-utils.ts +71 -44
  406. package/src/vite/utils/shared-utils.ts +55 -37
  407. package/src/browser/react/use-client-cache.ts +0 -58
  408. package/src/browser/shallow.ts +0 -40
  409. package/src/handles/index.ts +0 -7
  410. package/src/network-error-thrower.tsx +0 -23
  411. package/src/router/middleware-cookies.ts +0 -55
@@ -14,6 +14,7 @@ import {
14
14
  getParallelEntries,
15
15
  getParallelSlotEntries,
16
16
  type EntryData,
17
+ type ParallelEntryData,
17
18
  } from "../../server/context";
18
19
  import type {
19
20
  HandlerContext,
@@ -34,62 +35,23 @@ import {
34
35
  import { resolveLoaderData } from "./loader-cache.js";
35
36
  import {
36
37
  handleHandlerResult,
38
+ warnOnStreamedResponse,
37
39
  tryStaticHandler,
38
40
  tryStaticSlot,
39
41
  resolveLayoutComponent,
40
42
  resolveWithErrorBoundary,
43
+ buildLoaderErrorContext,
41
44
  } from "./helpers.js";
42
45
  import { applyViewTransitionDefault } from "./view-transition-default.js";
43
46
  import { getRouterContext } from "../router-context.js";
44
- import { resolveSink, safeEmit } from "../telemetry.js";
47
+ import { observeEvent, observeHandler } from "../instrument.js";
48
+ import { observeStreamedHandler } from "./streamed-handler-telemetry.js";
45
49
  import {
46
50
  track,
47
51
  RangoContext,
48
52
  runInsideLoaderScope,
49
53
  } from "../../server/context.js";
50
54
 
51
- // ---------------------------------------------------------------------------
52
- // Telemetry helpers
53
- // ---------------------------------------------------------------------------
54
-
55
- /**
56
- * Attach a fire-and-forget rejection observer to a streamed handler promise.
57
- * Silently no-ops when called outside RouterContext (e.g. in unit tests).
58
- */
59
- function observeStreamedHandler(
60
- promise: Promise<ReactNode>,
61
- segmentId: string,
62
- segmentType: string,
63
- pathname?: string,
64
- routeKey?: string,
65
- params?: Record<string, string>,
66
- ): void {
67
- let routerCtx;
68
- try {
69
- routerCtx = getRouterContext();
70
- } catch {
71
- return;
72
- }
73
- if (!routerCtx?.telemetry) return;
74
- const sink = resolveSink(routerCtx.telemetry);
75
- const reqId = routerCtx.requestId;
76
- promise.catch((err: unknown) => {
77
- const errorObj = err instanceof Error ? err : new Error(String(err));
78
- safeEmit(sink, {
79
- type: "handler.error",
80
- timestamp: performance.now(),
81
- requestId: reqId,
82
- segmentId,
83
- segmentType,
84
- error: errorObj,
85
- handledByBoundary: true,
86
- pathname,
87
- routeKey,
88
- params,
89
- });
90
- });
91
- }
92
-
93
55
  /**
94
56
  * Trace a parallel slot that's being force-rendered on a full refetch (client
95
57
  * has no cached state). User revalidate fns are bypassed in this case — see
@@ -126,23 +88,14 @@ function emitRevalidationDecision(
126
88
  routeKey: string,
127
89
  shouldRevalidate: boolean,
128
90
  ): void {
129
- let routerCtx;
130
- try {
131
- routerCtx = getRouterContext();
132
- } catch {
133
- return;
134
- }
135
- if (routerCtx?.telemetry) {
136
- safeEmit(resolveSink(routerCtx.telemetry), {
137
- type: "revalidation.decision",
138
- timestamp: performance.now(),
139
- requestId: routerCtx.requestId,
140
- segmentId,
141
- pathname,
142
- routeKey,
143
- shouldRevalidate,
144
- });
145
- }
91
+ observeEvent({
92
+ type: "revalidation.decision",
93
+ timestamp: performance.now(),
94
+ segmentId,
95
+ pathname,
96
+ routeKey,
97
+ shouldRevalidate,
98
+ });
146
99
  }
147
100
 
148
101
  // ---------------------------------------------------------------------------
@@ -247,6 +200,10 @@ export async function resolveLoadersWithRevalidation<TEnv>(
247
200
  ),
248
201
  );
249
202
 
203
+ // Partial (revalidation) render path: a throwing DSL loader must still fire
204
+ // onError/loader.error. isPartial flags the reporting phase accordingly.
205
+ const errorContext = { ...buildLoaderErrorContext(ctx), isPartial: true };
206
+
250
207
  const loadersToRun = revalidationChecks.filter((c) => c.shouldRun);
251
208
  const segments: ResolvedSegment[] = loadersToRun.map(
252
209
  ({ loaderEntry, loader, segmentId, index }) => ({
@@ -264,6 +221,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
264
221
  entry,
265
222
  segmentId,
266
223
  ctx.pathname,
224
+ errorContext,
267
225
  ),
268
226
  belongsToRoute,
269
227
  }),
@@ -426,6 +384,97 @@ export function buildEntryRevalidateMap(
426
384
  return map;
427
385
  }
428
386
 
387
+ /**
388
+ * Resolve the component for a single parallel slot on the revalidation path.
389
+ * Pure component resolution shared verbatim by
390
+ * resolveParallelSegmentsWithRevalidation and the orphan-inlined loop in
391
+ * resolveOrphanLayoutWithRevalidation: try the static slot cache, else run the
392
+ * slot handler (pinning _currentSegmentId to the slot id so handle pushes land
393
+ * in the slot's own bucket, and wrapping a streamed handler). Returns the
394
+ * resolved component and whether the handler actually ran. Does NOT touch the
395
+ * revalidate-default policy (the caller decides shouldResolve, including the
396
+ * orphan-vs-main defaultOverride divergence) or loader-resolution ordering.
397
+ */
398
+ async function resolveParallelSlotComponent<TEnv>(args: {
399
+ shouldResolve: boolean;
400
+ parallelEntry: ParallelEntryData;
401
+ slot: string;
402
+ parallelId: string;
403
+ handler:
404
+ | ((ctx: HandlerContext<any, TEnv>) => ReactNode | Promise<ReactNode>)
405
+ | ReactNode
406
+ | undefined;
407
+ context: HandlerContext<any, TEnv>;
408
+ deps: SegmentResolutionDeps<TEnv>;
409
+ routeKey: string;
410
+ params: Record<string, string>;
411
+ }): Promise<{ component: ReactNode | undefined; handlerRan: boolean }> {
412
+ const {
413
+ shouldResolve,
414
+ parallelEntry,
415
+ slot,
416
+ parallelId,
417
+ handler,
418
+ context,
419
+ deps,
420
+ routeKey,
421
+ params,
422
+ } = args;
423
+
424
+ let component: ReactNode | undefined;
425
+ let handlerRan = false;
426
+ if (shouldResolve) {
427
+ component = await tryStaticSlot(parallelEntry, slot, parallelId);
428
+ // tryStaticSlot returning a value means the static cache supplied the
429
+ // component — handler did NOT run. handlerRan stays false.
430
+ }
431
+ if (component === undefined) {
432
+ const hasLoadingFallback =
433
+ parallelEntry.loading !== undefined && parallelEntry.loading !== false;
434
+ if (!shouldResolve) {
435
+ component = null;
436
+ } else if (handler === undefined) {
437
+ // Handler evicted (production static slot) but static lookup missed.
438
+ // Nothing to render — use null so the client keeps its cached version.
439
+ component = null;
440
+ } else {
441
+ // Slot-keyed pushes — slot owns its own bucket, parent layout owns its
442
+ // own. On slot-only revalidations the partial merge updates only the
443
+ // slot's bucket; the parent's bucket stays intact.
444
+ (context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
445
+ parallelId;
446
+ handlerRan = true;
447
+ if (hasLoadingFallback) {
448
+ const result =
449
+ typeof handler === "function" ? handler(context) : handler;
450
+ if (result instanceof Promise) {
451
+ warnOnStreamedResponse(result, parallelId);
452
+ const tracked = deps.trackHandler(result, {
453
+ segmentId: parallelId,
454
+ segmentType: "parallel",
455
+ });
456
+ observeStreamedHandler(
457
+ tracked,
458
+ parallelId,
459
+ "parallel",
460
+ context.pathname,
461
+ routeKey,
462
+ params,
463
+ );
464
+ component = tracked as ReactNode;
465
+ } else {
466
+ component = result as ReactNode;
467
+ }
468
+ } else {
469
+ component =
470
+ typeof handler === "function" ? await handler(context) : handler;
471
+ }
472
+ }
473
+ }
474
+
475
+ return { component, handlerRan };
476
+ }
477
+
429
478
  /**
430
479
  * Resolve parallel segments with revalidation.
431
480
  */
@@ -443,9 +492,30 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
443
492
  deps: SegmentResolutionDeps<TEnv>,
444
493
  actionContext?: ActionContext,
445
494
  stale?: boolean,
495
+ options?: {
496
+ /**
497
+ * Seed for an unknown parent-chain slot (slot not in clientSegmentIds) when
498
+ * there are no deciding revalidate fns. "type-derived" (default, main path):
499
+ * `belongsToRoute || isNewParent`. "force-render" (orphan path): always
500
+ * `true` — orphan parallels always belong to the route and must render
501
+ * unless the user opts out via revalidate(); the #482 blank-parent-chain-
502
+ * slot guard.
503
+ */
504
+ parentChainDefault?: "type-derived" | "force-render";
505
+ /**
506
+ * When a slot's loaders are resolved relative to the slot segment push.
507
+ * "after" (default, main path) pushes the slot segment first; "before"
508
+ * (orphan path) resolves loaders first. This only changes the
509
+ * segments/matchedIds emission ORDER (the client reconciler is insensitive
510
+ * to it: loader sub-ids are filtered out and slots are re-grouped by parent).
511
+ */
512
+ loaderOrder?: "after" | "before";
513
+ },
446
514
  ): Promise<SegmentRevalidationResult> {
447
515
  const segments: ResolvedSegment[] = [];
448
516
  const matchedIds: string[] = [];
517
+ const parentChainDefault = options?.parentChainDefault ?? "type-derived";
518
+ const loaderOrder = options?.loaderOrder ?? "after";
449
519
 
450
520
  const resolvedParallelEntries = new Set<string>();
451
521
  for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
@@ -470,6 +540,34 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
470
540
 
471
541
  const isFullRefetch = clientSegmentIds.size === 0;
472
542
  const isNewParent = !clientSegmentIds.has(entry.shortCode);
543
+
544
+ // A slot's loaders (never cached) are deduped per parallel entry and
545
+ // emitted either before or after the slot segment per loaderOrder.
546
+ const resolveSlotLoaders = async () => {
547
+ if (resolvedParallelEntries.has(parallelEntry.id)) return;
548
+ const loaderResult = await resolveLoadersWithRevalidation(
549
+ parallelEntry,
550
+ context,
551
+ belongsToRoute,
552
+ clientSegmentIds,
553
+ prevParams,
554
+ request,
555
+ prevUrl,
556
+ nextUrl,
557
+ routeKey,
558
+ deps,
559
+ actionContext,
560
+ entry.shortCode,
561
+ stale,
562
+ );
563
+ segments.push(...loaderResult.segments);
564
+ matchedIds.push(...loaderResult.matchedIds);
565
+ resolvedParallelEntries.add(parallelEntry.id);
566
+ };
567
+
568
+ if (loaderOrder === "before") {
569
+ await resolveSlotLoaders();
570
+ }
473
571
  // Always announce the slot in matchedIds — it's unconditionally appended
474
572
  // to `segments` below, and a segment present in segments but missing from
475
573
  // matched lets the client prune it (then it's missing from clientSegmentIds
@@ -489,7 +587,10 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
489
587
  // soft chain seeds with the right "new segment" / "parent-chain" value.
490
588
  let defaultOverride: { value: boolean; reason: string } | undefined;
491
589
  if (!clientSegmentIds.has(parallelId)) {
492
- const value = belongsToRoute || isNewParent;
590
+ const value =
591
+ parentChainDefault === "force-render"
592
+ ? true
593
+ : belongsToRoute || isNewParent;
493
594
  defaultOverride = {
494
595
  value,
495
596
  reason: value ? "new-segment" : "skip-parent-chain",
@@ -537,55 +638,17 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
537
638
  shouldResolve,
538
639
  );
539
640
 
540
- let component: ReactNode | undefined;
541
- let handlerRan = false;
542
- if (shouldResolve) {
543
- component = await tryStaticSlot(parallelEntry, slot, parallelId);
544
- // tryStaticSlot returning a value means the static cache supplied the
545
- // component — handler did NOT run. handlerRan stays false.
546
- }
547
- if (component === undefined) {
548
- const hasLoadingFallback =
549
- parallelEntry.loading !== undefined && parallelEntry.loading !== false;
550
- if (!shouldResolve) {
551
- component = null;
552
- } else if (handler === undefined) {
553
- // Handler evicted (production static slot) but static lookup missed.
554
- // Nothing to render — use null so the client keeps its cached version.
555
- component = null;
556
- } else {
557
- // Slot-keyed pushes — slot owns its own bucket, parent layout owns
558
- // its own. On slot-only revalidations the partial merge updates only
559
- // the slot's bucket; the parent's bucket stays intact.
560
- (context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
561
- parallelId;
562
- handlerRan = true;
563
- if (hasLoadingFallback) {
564
- const result =
565
- typeof handler === "function" ? handler(context) : handler;
566
- if (result instanceof Promise) {
567
- const tracked = deps.trackHandler(result, {
568
- segmentId: parallelId,
569
- segmentType: "parallel",
570
- });
571
- observeStreamedHandler(
572
- tracked,
573
- parallelId,
574
- "parallel",
575
- context.pathname,
576
- routeKey,
577
- params,
578
- );
579
- component = tracked as ReactNode;
580
- } else {
581
- component = result as ReactNode;
582
- }
583
- } else {
584
- component =
585
- typeof handler === "function" ? await handler(context) : handler;
586
- }
587
- }
588
- }
641
+ const { component, handlerRan } = await resolveParallelSlotComponent({
642
+ shouldResolve,
643
+ parallelEntry,
644
+ slot,
645
+ parallelId,
646
+ handler,
647
+ context,
648
+ deps,
649
+ routeKey,
650
+ params,
651
+ });
589
652
 
590
653
  segments.push({
591
654
  id: parallelId,
@@ -597,6 +660,7 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
597
660
  transition: applyViewTransitionDefault(
598
661
  parallelEntry.transition,
599
662
  deps.viewTransitionDefault,
663
+ parallelId,
600
664
  ),
601
665
  params,
602
666
  slot,
@@ -608,28 +672,9 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
608
672
  : {}),
609
673
  });
610
674
 
611
- if (resolvedParallelEntries.has(parallelEntry.id)) {
612
- continue;
675
+ if (loaderOrder === "after") {
676
+ await resolveSlotLoaders();
613
677
  }
614
-
615
- const loaderResult = await resolveLoadersWithRevalidation(
616
- parallelEntry,
617
- context,
618
- belongsToRoute,
619
- clientSegmentIds,
620
- prevParams,
621
- request,
622
- prevUrl,
623
- nextUrl,
624
- routeKey,
625
- deps,
626
- actionContext,
627
- entry.shortCode,
628
- stale,
629
- );
630
- segments.push(...loaderResult.segments);
631
- matchedIds.push(...loaderResult.matchedIds);
632
- resolvedParallelEntries.add(parallelEntry.id);
633
678
  }
634
679
 
635
680
  return { segments, matchedIds };
@@ -755,13 +800,18 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
755
800
  ? routeEntry.liveHandler
756
801
  : routeEntry.handler;
757
802
  if (!routeEntry.loading) {
758
- const result = handleHandlerResult(await handler(context));
803
+ const result = handleHandlerResult(
804
+ await observeHandler(entry.id, handler, context),
805
+ );
759
806
  doneHandler();
760
807
  return result;
761
808
  }
762
809
  if (!actionContext) {
763
- const result = handleHandlerResult(handler(context));
810
+ const result = handleHandlerResult(
811
+ observeHandler(entry.id, handler, context),
812
+ );
764
813
  if (result instanceof Promise) {
814
+ warnOnStreamedResponse(result, routeEntry.id);
765
815
  result.finally(doneHandler).catch(() => {});
766
816
  const tracked = deps.trackHandler(result, {
767
817
  segmentId: entry.shortCode,
@@ -783,7 +833,9 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
783
833
  debugLog("segment.action", "resolving action route with awaited value", {
784
834
  entryId: entry.id,
785
835
  });
786
- const actionResult = handleHandlerResult(await handler(context));
836
+ const actionResult = handleHandlerResult(
837
+ await observeHandler(entry.id, handler, context),
838
+ );
787
839
  doneHandler();
788
840
  return {
789
841
  content: Promise.resolve(actionResult),
@@ -810,6 +862,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
810
862
  transition: applyViewTransitionDefault(
811
863
  entry.transition,
812
864
  deps.viewTransitionDefault,
865
+ entry.shortCode,
813
866
  ),
814
867
  params,
815
868
  belongsToRoute,
@@ -836,7 +889,6 @@ export async function resolveSegmentWithRevalidation<TEnv>(
836
889
  request: Request,
837
890
  prevUrl: URL,
838
891
  nextUrl: URL,
839
- loaderPromises: Map<string, Promise<any>>,
840
892
  deps: SegmentResolutionDeps<TEnv>,
841
893
  actionContext?: ActionContext,
842
894
  stale?: boolean,
@@ -1147,177 +1199,38 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
1147
1199
  transition: applyViewTransitionDefault(
1148
1200
  orphan.transition,
1149
1201
  deps.viewTransitionDefault,
1202
+ orphan.shortCode,
1150
1203
  ),
1151
1204
  ...(orphan.mountPath ? { mountPath: orphan.mountPath } : {}),
1152
1205
  });
1153
1206
 
1154
- const resolvedParallelEntries = new Set<string>();
1155
- for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
1156
- orphan.parallel,
1157
- )) {
1158
- invariant(
1159
- parallelEntry.type === "parallel",
1160
- `Expected parallel entry, got: ${parallelEntry.type}`,
1161
- );
1162
-
1163
- if (!resolvedParallelEntries.has(parallelEntry.id)) {
1164
- // shortCodeOverride must match the parent layout, not the parallel entry.
1165
- const loaderResult = await resolveLoadersWithRevalidation(
1166
- parallelEntry,
1167
- context,
1168
- belongsToRoute,
1169
- clientSegmentIds,
1170
- prevParams,
1171
- request,
1172
- prevUrl,
1173
- nextUrl,
1174
- routeKey,
1175
- deps,
1176
- actionContext,
1177
- orphan.shortCode,
1178
- stale,
1179
- );
1180
- segments.push(...loaderResult.segments);
1181
- matchedIds.push(...loaderResult.matchedIds);
1182
- resolvedParallelEntries.add(parallelEntry.id);
1183
- }
1184
-
1185
- const slots = parallelEntry.handler as Record<
1186
- `@${string}`,
1187
- | ((ctx: HandlerContext<any, TEnv>) => ReactNode | Promise<ReactNode>)
1188
- | ReactNode
1189
- >;
1190
- // Handler may be undefined in production after static handler eviction.
1191
- const handler = slots[slot];
1192
-
1193
- // Use orphan.shortCode (the parent layout) to match the SSR path
1194
- // (resolveParallelEntry receives parentShortCode = orphan.shortCode).
1195
- // Using parallelEntry.shortCode would generate IDs the client doesn't know about.
1196
- const parallelId = `${orphan.shortCode}.${slot}`;
1197
- matchedIds.push(parallelId);
1198
-
1199
- const isFullRefetch = clientSegmentIds.size === 0;
1200
- let shouldResolve: boolean;
1201
- if (isFullRefetch) {
1202
- // Same load-bearing rationale as the main parallel path: full refetch
1203
- // means the client has nothing to fall back to, so the slot must render.
1204
- traceFullRefetchedParallelSlot(parallelId, belongsToRoute);
1205
- shouldResolve = true;
1206
- } else {
1207
- // When slot is unknown to the client, seed the soft chain with `true`
1208
- // (orphan parallels always belong to the route — we want them rendered
1209
- // unless the user explicitly opts out via revalidate()).
1210
- const defaultOverride = clientSegmentIds.has(parallelId)
1211
- ? undefined
1212
- : { value: true, reason: "new-segment" };
1213
-
1214
- const dummySegment: ResolvedSegment = {
1215
- id: parallelId,
1216
- namespace: parallelEntry.id,
1217
- type: "parallel",
1218
- index: 0,
1219
- component: null as any,
1220
- params,
1221
- slot,
1222
- belongsToRoute,
1223
- parallelName: `${parallelEntry.id}.${slot}`,
1224
- ...(parallelEntry.mountPath
1225
- ? { mountPath: parallelEntry.mountPath }
1226
- : {}),
1227
- };
1228
-
1229
- shouldResolve = await evaluateRevalidation({
1230
- segment: dummySegment,
1231
- prevParams,
1232
- getPrevSegment: null,
1233
- request,
1234
- prevUrl,
1235
- nextUrl,
1236
- revalidations: parallelEntry.revalidate.map((fn, i) => ({
1237
- name: `revalidate${i}`,
1238
- fn,
1239
- })),
1240
- routeKey,
1241
- context,
1242
- actionContext,
1243
- stale,
1244
- traceSource: "parallel",
1245
- defaultOverride,
1246
- });
1247
- }
1248
- emitRevalidationDecision(
1249
- parallelId,
1250
- context.pathname,
1251
- routeKey,
1252
- shouldResolve,
1253
- );
1254
-
1255
- let component: ReactNode | undefined;
1256
- let handlerRan = false;
1257
- if (shouldResolve) {
1258
- component = await tryStaticSlot(parallelEntry, slot, parallelId);
1259
- }
1260
- if (component === undefined) {
1261
- const hasLoadingFallback =
1262
- parallelEntry.loading !== undefined && parallelEntry.loading !== false;
1263
- if (!shouldResolve) {
1264
- component = null;
1265
- } else if (handler === undefined) {
1266
- // Handler evicted (production static slot) but static lookup missed.
1267
- component = null;
1268
- } else {
1269
- // Slot-keyed pushes — see resolveParallelSegmentsWithRevalidation.
1270
- (context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
1271
- parallelId;
1272
- handlerRan = true;
1273
- if (hasLoadingFallback) {
1274
- const result =
1275
- typeof handler === "function" ? handler(context) : handler;
1276
- if (result instanceof Promise) {
1277
- const tracked = deps.trackHandler(result, {
1278
- segmentId: parallelId,
1279
- segmentType: "parallel",
1280
- });
1281
- observeStreamedHandler(
1282
- tracked,
1283
- parallelId,
1284
- "parallel",
1285
- context.pathname,
1286
- routeKey,
1287
- params,
1288
- );
1289
- component = tracked as ReactNode;
1290
- } else {
1291
- component = result as ReactNode;
1292
- }
1293
- } else {
1294
- component =
1295
- typeof handler === "function" ? await handler(context) : handler;
1296
- }
1297
- }
1298
- }
1299
-
1300
- segments.push({
1301
- id: parallelId,
1302
- namespace: parallelEntry.id,
1303
- type: "parallel",
1304
- index: 0,
1305
- component,
1306
- loading: parallelEntry.loading === false ? null : parallelEntry.loading,
1307
- transition: applyViewTransitionDefault(
1308
- parallelEntry.transition,
1309
- deps.viewTransitionDefault,
1310
- ),
1311
- params,
1312
- slot,
1313
- _handlerRan: handlerRan,
1314
- belongsToRoute,
1315
- parallelName: `${parallelEntry.id}.${slot}`,
1316
- ...(parallelEntry.mountPath
1317
- ? { mountPath: parallelEntry.mountPath }
1318
- : {}),
1319
- });
1320
- }
1207
+ // Resolve the orphan layout's parallel slots through the shared main-path
1208
+ // helper. The orphan policy is carried by explicit args, byte-for-byte:
1209
+ // - parentChainDefault "force-render": an unknown parent-chain slot seeds
1210
+ // `true` (orphan parallels always belong to the route — the #482 guard),
1211
+ // where the main path would seed `belongsToRoute || isNewParent`.
1212
+ // - loaderOrder "before": a slot's loaders are emitted before the slot
1213
+ // segment, matching the prior inlined order.
1214
+ // `entry.shortCode` inside the helper is `orphan.shortCode` (orphan is passed
1215
+ // as `entry`), so the parallel ids + loader shortCodeOverride are unchanged.
1216
+ const parallelResult = await resolveParallelSegmentsWithRevalidation(
1217
+ orphan,
1218
+ params,
1219
+ context,
1220
+ belongsToRoute,
1221
+ clientSegmentIds,
1222
+ prevParams,
1223
+ request,
1224
+ prevUrl,
1225
+ nextUrl,
1226
+ routeKey,
1227
+ deps,
1228
+ actionContext,
1229
+ stale,
1230
+ { parentChainDefault: "force-render", loaderOrder: "before" },
1231
+ );
1232
+ segments.push(...parallelResult.segments);
1233
+ matchedIds.push(...parallelResult.matchedIds);
1321
1234
 
1322
1235
  return { segments, matchedIds };
1323
1236
  }
@@ -1335,7 +1248,6 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
1335
1248
  request: Request,
1336
1249
  prevUrl: URL,
1337
1250
  nextUrl: URL,
1338
- loaderPromises: Map<string, Promise<any>>,
1339
1251
  actionContext: ActionContext | undefined,
1340
1252
  interceptResult: { intercept: any; entry: EntryData } | null,
1341
1253
  localRouteName: string,
@@ -1387,7 +1299,6 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
1387
1299
  request,
1388
1300
  prevUrl,
1389
1301
  nextUrl,
1390
- loaderPromises,
1391
1302
  deps,
1392
1303
  actionContext,
1393
1304
  stale,