@rangojs/router 0.0.0-experimental.b9cb8739 → 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 (449) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +303 -741
  3. package/dist/bin/rango.js +730 -184
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +4344 -1335
  6. package/dist/vite/index.js.bak +5448 -0
  7. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  8. package/package.json +86 -15
  9. package/skills/api-client/SKILL.md +211 -0
  10. package/skills/breadcrumbs/SKILL.md +85 -6
  11. package/skills/bundle-analysis/SKILL.md +159 -0
  12. package/skills/cache-guide/SKILL.md +251 -24
  13. package/skills/caching/SKILL.md +375 -17
  14. package/skills/catalog.json +271 -0
  15. package/skills/comparison/SKILL.md +50 -0
  16. package/skills/comparison/agents/openai.yaml +4 -0
  17. package/skills/comparison/references/framework-comparison.md +837 -0
  18. package/skills/composability/SKILL.md +110 -4
  19. package/skills/css/SKILL.md +76 -0
  20. package/skills/debug-manifest/SKILL.md +5 -3
  21. package/skills/defer-hydration/SKILL.md +235 -0
  22. package/skills/document-cache/SKILL.md +87 -56
  23. package/skills/fonts/SKILL.md +1 -1
  24. package/skills/handler-use/SKILL.md +364 -0
  25. package/skills/hooks/SKILL.md +73 -691
  26. package/skills/hooks/data.md +273 -0
  27. package/skills/hooks/handle-and-actions.md +103 -0
  28. package/skills/hooks/navigation.md +110 -0
  29. package/skills/hooks/outlets.md +41 -0
  30. package/skills/hooks/state.md +228 -0
  31. package/skills/hooks/urls.md +135 -0
  32. package/skills/host-router/SKILL.md +129 -27
  33. package/skills/i18n/SKILL.md +276 -0
  34. package/skills/intercept/SKILL.md +94 -18
  35. package/skills/layout/SKILL.md +62 -19
  36. package/skills/links/SKILL.md +249 -17
  37. package/skills/loader/SKILL.md +302 -54
  38. package/skills/middleware/SKILL.md +59 -16
  39. package/skills/migrate-nextjs/SKILL.md +745 -0
  40. package/skills/migrate-react-router/SKILL.md +153 -0
  41. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  42. package/skills/migrate-react-router/component-migration.md +196 -0
  43. package/skills/migrate-react-router/data-and-actions.md +225 -0
  44. package/skills/migrate-react-router/route-mapping.md +271 -0
  45. package/skills/mime-routes/SKILL.md +29 -2
  46. package/skills/observability/SKILL.md +202 -0
  47. package/skills/parallel/SKILL.md +225 -10
  48. package/skills/ppr/SKILL.md +622 -0
  49. package/skills/prerender/SKILL.md +178 -124
  50. package/skills/rango/SKILL.md +318 -24
  51. package/skills/react-compiler/SKILL.md +168 -0
  52. package/skills/response-routes/SKILL.md +138 -49
  53. package/skills/route/SKILL.md +172 -9
  54. package/skills/router-setup/SKILL.md +131 -11
  55. package/skills/scripts/SKILL.md +179 -0
  56. package/skills/server-actions/SKILL.md +776 -0
  57. package/skills/shell-manifest/SKILL.md +185 -0
  58. package/skills/streams-and-websockets/SKILL.md +283 -0
  59. package/skills/tailwind/SKILL.md +28 -4
  60. package/skills/testing/SKILL.md +130 -0
  61. package/skills/testing/bindings.md +103 -0
  62. package/skills/testing/cache-prerender.md +127 -0
  63. package/skills/testing/client-components.md +124 -0
  64. package/skills/testing/e2e-parity.md +125 -0
  65. package/skills/testing/flight.md +91 -0
  66. package/skills/testing/handles.md +131 -0
  67. package/skills/testing/loader.md +128 -0
  68. package/skills/testing/middleware.md +99 -0
  69. package/skills/testing/render-handler.md +122 -0
  70. package/skills/testing/response-routes.md +95 -0
  71. package/skills/testing/reverse-and-types.md +85 -0
  72. package/skills/testing/server-actions.md +107 -0
  73. package/skills/testing/server-tree.md +128 -0
  74. package/skills/testing/setup.md +123 -0
  75. package/skills/theme/SKILL.md +1 -1
  76. package/skills/typesafety/SKILL.md +45 -616
  77. package/skills/typesafety/env-and-bindings.md +254 -0
  78. package/skills/typesafety/generated-files-and-cli.md +335 -0
  79. package/skills/typesafety/params-and-search.md +153 -0
  80. package/skills/typesafety/route-types.md +209 -0
  81. package/skills/use-cache/SKILL.md +74 -15
  82. package/skills/vercel/SKILL.md +128 -0
  83. package/skills/view-transitions/SKILL.md +337 -0
  84. package/src/__augment-tests__/augment.ts +81 -0
  85. package/src/__augment-tests__/augmented.check.ts +116 -0
  86. package/src/__internal.ts +1 -66
  87. package/src/browser/action-coordinator.ts +53 -36
  88. package/src/browser/action-fence.ts +47 -0
  89. package/src/browser/app-shell.ts +39 -0
  90. package/src/browser/app-version.ts +14 -0
  91. package/src/browser/connection-warmup.ts +134 -0
  92. package/src/browser/cookie-name.ts +140 -0
  93. package/src/browser/event-controller.ts +257 -158
  94. package/src/browser/history-state.ts +21 -0
  95. package/src/browser/index.ts +3 -3
  96. package/src/browser/invalidate-client-cache.ts +52 -0
  97. package/src/browser/logging.ts +28 -0
  98. package/src/browser/merge-segment-loaders.ts +6 -4
  99. package/src/browser/navigation-bridge.ts +132 -33
  100. package/src/browser/navigation-client.ts +218 -68
  101. package/src/browser/navigation-store-handle.ts +38 -0
  102. package/src/browser/navigation-store.ts +203 -80
  103. package/src/browser/navigation-transaction.ts +18 -66
  104. package/src/browser/network-error-handler.ts +34 -7
  105. package/src/browser/partial-update.ts +241 -127
  106. package/src/browser/prefetch/cache.ts +271 -44
  107. package/src/browser/prefetch/fetch.ts +367 -40
  108. package/src/browser/prefetch/queue.ts +144 -23
  109. package/src/browser/prefetch/resource-ready.ts +77 -0
  110. package/src/browser/rango-state.ts +158 -76
  111. package/src/browser/react/Link.tsx +121 -16
  112. package/src/browser/react/NavigationProvider.tsx +240 -122
  113. package/src/browser/react/ScrollRestoration.tsx +10 -6
  114. package/src/browser/react/context.ts +7 -2
  115. package/src/browser/react/filter-segment-order.ts +66 -7
  116. package/src/browser/react/index.ts +0 -48
  117. package/src/browser/react/location-state-shared.ts +178 -8
  118. package/src/browser/react/location-state.ts +39 -14
  119. package/src/browser/react/use-action.ts +6 -15
  120. package/src/browser/react/use-handle.ts +23 -69
  121. package/src/browser/react/use-href.tsx +8 -1
  122. package/src/browser/react/use-link-status.ts +33 -8
  123. package/src/browser/react/use-navigation.ts +32 -7
  124. package/src/browser/react/use-params.ts +20 -10
  125. package/src/browser/react/use-reverse.ts +106 -0
  126. package/src/browser/react/use-router.ts +46 -11
  127. package/src/browser/react/use-search-params.ts +0 -5
  128. package/src/browser/react/use-segments.ts +11 -21
  129. package/src/browser/response-adapter.ts +99 -8
  130. package/src/browser/rsc-router.tsx +272 -80
  131. package/src/browser/scroll-restoration.ts +56 -22
  132. package/src/browser/segment-reconciler.ts +44 -7
  133. package/src/browser/segment-structure-assert.ts +2 -2
  134. package/src/browser/server-action-bridge.ts +244 -71
  135. package/src/browser/types.ts +136 -12
  136. package/src/browser/validate-redirect-origin.ts +43 -16
  137. package/src/build/collect-fallback-refs.ts +107 -0
  138. package/src/build/generate-manifest.ts +207 -158
  139. package/src/build/generate-route-types.ts +6 -1
  140. package/src/build/index.ts +11 -3
  141. package/src/build/prefix-tree-utils.ts +123 -0
  142. package/src/build/route-trie.ts +198 -41
  143. package/src/build/route-types/ast-route-extraction.ts +15 -8
  144. package/src/build/route-types/codegen.ts +16 -5
  145. package/src/build/route-types/include-resolution.ts +464 -63
  146. package/src/build/route-types/param-extraction.ts +6 -3
  147. package/src/build/route-types/per-module-writer.ts +22 -6
  148. package/src/build/route-types/router-processing.ts +336 -110
  149. package/src/build/route-types/scan-filter.ts +9 -2
  150. package/src/build/route-types/source-scan.ts +216 -0
  151. package/src/build/runtime-discovery.ts +13 -21
  152. package/src/cache/cache-error.ts +104 -0
  153. package/src/cache/cache-key-utils.ts +58 -13
  154. package/src/cache/cache-policy.ts +108 -34
  155. package/src/cache/cache-runtime.ts +454 -97
  156. package/src/cache/cache-scope.ts +235 -103
  157. package/src/cache/cache-tag.ts +149 -0
  158. package/src/cache/cf/cf-base64.ts +33 -0
  159. package/src/cache/cf/cf-cache-constants.ts +127 -0
  160. package/src/cache/cf/cf-cache-store.ts +2446 -170
  161. package/src/cache/cf/cf-cache-types.ts +349 -0
  162. package/src/cache/cf/cf-kv-utils.ts +46 -0
  163. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  164. package/src/cache/cf/index.ts +11 -17
  165. package/src/cache/document-cache.ts +144 -49
  166. package/src/cache/handle-snapshot.ts +70 -0
  167. package/src/cache/index.ts +24 -20
  168. package/src/cache/memory-segment-store.ts +243 -37
  169. package/src/cache/profile-registry.ts +46 -31
  170. package/src/cache/read-through-swr.ts +56 -12
  171. package/src/cache/segment-codec.ts +13 -21
  172. package/src/cache/shell-snapshot.ts +417 -0
  173. package/src/cache/tag-invalidation.ts +230 -0
  174. package/src/cache/taint.ts +55 -0
  175. package/src/cache/types.ts +194 -99
  176. package/src/cache/vercel/index.ts +11 -0
  177. package/src/cache/vercel/vercel-cache-store.ts +1132 -0
  178. package/src/client.rsc.tsx +41 -21
  179. package/src/client.tsx +116 -290
  180. package/src/cloudflare/index.ts +11 -0
  181. package/src/cloudflare/tracing.ts +108 -0
  182. package/src/component-utils.ts +19 -0
  183. package/src/components/DefaultDocument.tsx +8 -2
  184. package/src/context-var.ts +84 -2
  185. package/src/debug.ts +2 -2
  186. package/src/decode-loader-results.ts +52 -0
  187. package/src/defer.ts +185 -0
  188. package/src/deps/ssr.ts +0 -1
  189. package/src/encode-kv.ts +49 -0
  190. package/src/errors.ts +30 -4
  191. package/src/escape-script.ts +52 -0
  192. package/src/handle.ts +104 -34
  193. package/src/handles/MetaTags.tsx +24 -53
  194. package/src/handles/Scripts.tsx +183 -0
  195. package/src/handles/breadcrumbs.ts +35 -8
  196. package/src/handles/deferred-resolution.ts +127 -0
  197. package/src/handles/is-thenable.ts +18 -0
  198. package/src/handles/meta.ts +14 -40
  199. package/src/handles/script.ts +244 -0
  200. package/src/host/cookie-handler.ts +9 -60
  201. package/src/host/errors.ts +13 -22
  202. package/src/host/index.ts +9 -2
  203. package/src/host/pattern-matcher.ts +23 -52
  204. package/src/host/router.ts +107 -99
  205. package/src/host/testing.ts +40 -27
  206. package/src/host/types.ts +37 -4
  207. package/src/host/utils.ts +1 -1
  208. package/src/href-client.ts +137 -22
  209. package/src/index.rsc.ts +100 -13
  210. package/src/index.ts +143 -19
  211. package/src/internal-debug.ts +11 -10
  212. package/src/loader-store.ts +500 -0
  213. package/src/loader.rsc.ts +20 -13
  214. package/src/loader.ts +12 -11
  215. package/src/missing-id-error.ts +68 -0
  216. package/src/outlet-context.ts +1 -1
  217. package/src/outlet-provider.tsx +1 -5
  218. package/src/prerender/param-hash.ts +16 -16
  219. package/src/prerender/store.ts +37 -41
  220. package/src/prerender.ts +215 -86
  221. package/src/redirect-origin.ts +114 -0
  222. package/src/regex-escape.ts +8 -0
  223. package/src/render-error-thrower.tsx +20 -0
  224. package/src/response-utils.ts +62 -0
  225. package/src/reverse.ts +65 -15
  226. package/src/root-error-boundary.tsx +1 -19
  227. package/src/route-content-wrapper.tsx +19 -77
  228. package/src/route-definition/dsl-helpers.ts +485 -303
  229. package/src/route-definition/helper-factories.ts +28 -140
  230. package/src/route-definition/helpers-types.ts +153 -77
  231. package/src/route-definition/index.ts +4 -2
  232. package/src/route-definition/redirect.ts +53 -12
  233. package/src/route-definition/resolve-handler-use.ts +160 -0
  234. package/src/route-definition/use-item-types.ts +29 -0
  235. package/src/route-map-builder.ts +48 -21
  236. package/src/route-types.ts +37 -46
  237. package/src/router/basename.ts +14 -0
  238. package/src/router/content-negotiation.ts +164 -17
  239. package/src/router/error-handling.ts +45 -18
  240. package/src/router/find-match.ts +130 -29
  241. package/src/router/handler-context.ts +83 -39
  242. package/src/router/instrument.ts +355 -0
  243. package/src/router/intercept-resolution.ts +50 -24
  244. package/src/router/lazy-includes.ts +89 -63
  245. package/src/router/loader-resolution.ts +286 -56
  246. package/src/router/logging.ts +5 -8
  247. package/src/router/manifest.ts +105 -56
  248. package/src/router/match-api.ts +178 -218
  249. package/src/router/match-context.ts +0 -22
  250. package/src/router/match-handlers.ts +211 -165
  251. package/src/router/match-middleware/background-revalidation.ts +66 -22
  252. package/src/router/match-middleware/cache-lookup.ts +214 -263
  253. package/src/router/match-middleware/cache-store.ts +105 -50
  254. package/src/router/match-middleware/intercept-resolution.ts +8 -28
  255. package/src/router/match-middleware/segment-resolution.ts +52 -18
  256. package/src/router/match-pipelines.ts +1 -42
  257. package/src/router/match-result.ts +128 -44
  258. package/src/router/metrics.ts +5 -34
  259. package/src/router/middleware-types.ts +13 -142
  260. package/src/router/middleware.ts +301 -177
  261. package/src/router/navigation-snapshot.ts +133 -0
  262. package/src/router/params-util.ts +23 -0
  263. package/src/router/parse-pattern.ts +115 -0
  264. package/src/router/pattern-matching.ts +181 -150
  265. package/src/router/prefetch-cache-ttl.ts +51 -0
  266. package/src/router/prefetch-limits.ts +37 -0
  267. package/src/router/prerender-match.ts +203 -58
  268. package/src/router/preview-match.ts +35 -103
  269. package/src/router/request-classification.ts +291 -0
  270. package/src/router/revalidation.ts +123 -73
  271. package/src/router/route-snapshot.ts +256 -0
  272. package/src/router/router-context.ts +11 -29
  273. package/src/router/router-interfaces.ts +146 -35
  274. package/src/router/router-options.ts +202 -15
  275. package/src/router/router-registry.ts +2 -5
  276. package/src/router/segment-resolution/fresh.ts +301 -78
  277. package/src/router/segment-resolution/helpers.ts +115 -30
  278. package/src/router/segment-resolution/loader-cache.ts +156 -39
  279. package/src/router/segment-resolution/loader-mask.ts +60 -0
  280. package/src/router/segment-resolution/loader-snapshot.ts +259 -0
  281. package/src/router/segment-resolution/mask-nested.ts +83 -0
  282. package/src/router/segment-resolution/revalidation.ts +477 -385
  283. package/src/router/segment-resolution/static-store.ts +19 -5
  284. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  285. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  286. package/src/router/segment-resolution.ts +5 -1
  287. package/src/router/segment-wrappers.ts +8 -5
  288. package/src/router/state-cookie-name.ts +33 -0
  289. package/src/router/substitute-pattern-params.ts +75 -0
  290. package/src/router/telemetry-otel.ts +160 -200
  291. package/src/router/telemetry.ts +105 -20
  292. package/src/router/timeout.ts +0 -20
  293. package/src/router/tracing.ts +215 -0
  294. package/src/router/trie-matching.ts +171 -59
  295. package/src/router/types.ts +10 -63
  296. package/src/router/url-params.ts +57 -0
  297. package/src/router.ts +210 -71
  298. package/src/rsc/full-payload.ts +70 -0
  299. package/src/rsc/handler-context.ts +3 -2
  300. package/src/rsc/handler.ts +682 -508
  301. package/src/rsc/helpers.ts +168 -46
  302. package/src/rsc/index.ts +2 -5
  303. package/src/rsc/json-route-result.ts +38 -0
  304. package/src/rsc/loader-fetch.ts +127 -31
  305. package/src/rsc/manifest-init.ts +33 -42
  306. package/src/rsc/nonce.ts +10 -1
  307. package/src/rsc/origin-guard.ts +39 -25
  308. package/src/rsc/progressive-enhancement.ts +138 -15
  309. package/src/rsc/redirect-guard.ts +100 -0
  310. package/src/rsc/response-cache-serve.ts +238 -0
  311. package/src/rsc/response-error.ts +79 -12
  312. package/src/rsc/response-route-handler.ts +99 -189
  313. package/src/rsc/rsc-rendering.ts +509 -73
  314. package/src/rsc/runtime-warnings.ts +23 -10
  315. package/src/rsc/server-action.ts +287 -113
  316. package/src/rsc/shell-capture.ts +1190 -0
  317. package/src/rsc/shell-serve.ts +181 -0
  318. package/src/rsc/ssr-setup.ts +18 -2
  319. package/src/rsc/transition-gate.ts +89 -0
  320. package/src/rsc/types.ts +62 -6
  321. package/src/runtime-env.ts +18 -0
  322. package/src/search-params.ts +35 -30
  323. package/src/segment-content-promise.ts +67 -0
  324. package/src/segment-loader-promise.ts +167 -0
  325. package/src/segment-system.tsx +449 -132
  326. package/src/serialize.ts +243 -0
  327. package/src/server/context.ts +367 -61
  328. package/src/server/cookie-parse.ts +32 -0
  329. package/src/server/cookie-store.ts +152 -5
  330. package/src/server/handle-store.ts +40 -38
  331. package/src/server/loader-registry.ts +38 -46
  332. package/src/server/request-context.ts +558 -173
  333. package/src/ssr/index.tsx +491 -174
  334. package/src/ssr/inject-rsc-eager.ts +167 -0
  335. package/src/ssr/ssr-root.tsx +228 -0
  336. package/src/static-handler.ts +27 -18
  337. package/src/testing/cache-status.ts +162 -0
  338. package/src/testing/collect-handle.ts +46 -0
  339. package/src/testing/dispatch.ts +813 -0
  340. package/src/testing/dom.entry.ts +22 -0
  341. package/src/testing/e2e/fixture.ts +188 -0
  342. package/src/testing/e2e/index.ts +128 -0
  343. package/src/testing/e2e/matchers.ts +35 -0
  344. package/src/testing/e2e/page-helpers.ts +272 -0
  345. package/src/testing/e2e/parity.ts +387 -0
  346. package/src/testing/e2e/server.ts +195 -0
  347. package/src/testing/flight-matchers.ts +97 -0
  348. package/src/testing/flight-normalize.ts +11 -0
  349. package/src/testing/flight-runtime.d.ts +57 -0
  350. package/src/testing/flight-tree.ts +682 -0
  351. package/src/testing/flight.entry.ts +52 -0
  352. package/src/testing/flight.ts +257 -0
  353. package/src/testing/generated-routes.ts +199 -0
  354. package/src/testing/index.ts +105 -0
  355. package/src/testing/internal/context.ts +371 -0
  356. package/src/testing/internal/flight-client-globals.ts +30 -0
  357. package/src/testing/internal/seed-vars.ts +54 -0
  358. package/src/testing/render-handler.ts +357 -0
  359. package/src/testing/render-route.tsx +584 -0
  360. package/src/testing/run-loader.ts +385 -0
  361. package/src/testing/run-middleware.ts +205 -0
  362. package/src/testing/run-transition-when.ts +164 -0
  363. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  364. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  365. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  366. package/src/testing/vitest-stubs/version.ts +5 -0
  367. package/src/testing/vitest.ts +305 -0
  368. package/src/theme/ThemeProvider.tsx +56 -84
  369. package/src/theme/ThemeScript.tsx +7 -9
  370. package/src/theme/constants.ts +52 -13
  371. package/src/theme/index.ts +0 -7
  372. package/src/theme/theme-context.ts +1 -5
  373. package/src/theme/theme-script.ts +22 -21
  374. package/src/theme/use-theme.ts +0 -3
  375. package/src/types/boundaries.ts +0 -35
  376. package/src/types/cache-types.ts +17 -8
  377. package/src/types/error-types.ts +30 -90
  378. package/src/types/global-namespace.ts +54 -41
  379. package/src/types/handler-context.ts +234 -82
  380. package/src/types/index.ts +3 -10
  381. package/src/types/loader-types.ts +44 -15
  382. package/src/types/request-scope.ts +112 -0
  383. package/src/types/route-config.ts +20 -52
  384. package/src/types/route-entry.ts +19 -7
  385. package/src/types/segments.ts +137 -14
  386. package/src/urls/include-helper.ts +40 -75
  387. package/src/urls/include-provider.ts +71 -0
  388. package/src/urls/index.ts +2 -11
  389. package/src/urls/path-helper-types.ts +102 -23
  390. package/src/urls/path-helper.ts +62 -111
  391. package/src/urls/pattern-types.ts +84 -19
  392. package/src/urls/response-types.ts +25 -22
  393. package/src/urls/type-extraction.ts +98 -154
  394. package/src/urls/urls-function.ts +1 -19
  395. package/src/use-loader.tsx +346 -89
  396. package/src/vercel/index.ts +11 -0
  397. package/src/vercel/tracing.ts +88 -0
  398. package/src/vite/debug.ts +185 -0
  399. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  400. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  401. package/src/vite/discovery/discover-routers.ts +130 -85
  402. package/src/vite/discovery/discovery-errors.ts +255 -0
  403. package/src/vite/discovery/gate-state.ts +171 -0
  404. package/src/vite/discovery/prerender-collection.ts +214 -132
  405. package/src/vite/discovery/route-types-writer.ts +40 -84
  406. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  407. package/src/vite/discovery/state.ts +57 -6
  408. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  409. package/src/vite/index.ts +15 -0
  410. package/src/vite/inject-client-debug.ts +88 -0
  411. package/src/vite/plugin-types.ts +234 -62
  412. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  413. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  414. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  415. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  416. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  417. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  418. package/src/vite/plugins/expose-action-id.ts +49 -98
  419. package/src/vite/plugins/expose-id-utils.ts +96 -51
  420. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  421. package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
  422. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  423. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  424. package/src/vite/plugins/expose-internal-ids.ts +553 -317
  425. package/src/vite/plugins/performance-tracks.ts +89 -0
  426. package/src/vite/plugins/refresh-cmd.ts +89 -27
  427. package/src/vite/plugins/use-cache-transform.ts +73 -83
  428. package/src/vite/plugins/vercel-output.ts +384 -0
  429. package/src/vite/plugins/version-injector.ts +40 -29
  430. package/src/vite/plugins/version-plugin.ts +46 -37
  431. package/src/vite/plugins/virtual-entries.ts +138 -27
  432. package/src/vite/rango.ts +353 -303
  433. package/src/vite/router-discovery.ts +1090 -166
  434. package/src/vite/utils/ast-handler-extract.ts +26 -35
  435. package/src/vite/utils/banner.ts +4 -4
  436. package/src/vite/utils/bundle-analysis.ts +10 -15
  437. package/src/vite/utils/client-chunks.ts +184 -0
  438. package/src/vite/utils/directive-prologue.ts +40 -0
  439. package/src/vite/utils/forward-user-plugins.ts +171 -0
  440. package/src/vite/utils/manifest-utils.ts +4 -59
  441. package/src/vite/utils/package-resolution.ts +20 -52
  442. package/src/vite/utils/prerender-utils.ts +98 -38
  443. package/src/vite/utils/shared-utils.ts +144 -44
  444. package/src/browser/action-response-classifier.ts +0 -99
  445. package/src/browser/react/use-client-cache.ts +0 -58
  446. package/src/browser/shallow.ts +0 -40
  447. package/src/handles/index.ts +0 -7
  448. package/src/network-error-thrower.tsx +0 -23
  449. package/src/router/middleware-cookies.ts +0 -55
@@ -1,10 +1,3 @@
1
- /**
2
- * Match API
3
- *
4
- * Extracted from createRouter closure. Contains match context creation functions
5
- * and the matchError function for error boundary resolution.
6
- */
7
-
8
1
  import { CacheScope, createCacheScope } from "../cache/cache-scope.js";
9
2
  import { RouteNotFoundError } from "../errors";
10
3
  import {
@@ -22,10 +15,10 @@ import { collectRouteMiddleware } from "./middleware.js";
22
15
  import { traverseBack } from "./pattern-matching.js";
23
16
  import { DefaultErrorFallback } from "../default-error-boundary.js";
24
17
  import {
25
- EntryData,
26
- LoaderEntry,
18
+ type EntryData,
19
+ type LoaderEntry,
27
20
  getContext,
28
- InterceptSelectorContext,
21
+ type InterceptSelectorContext,
29
22
  } from "../server/context";
30
23
  import type { ErrorBoundaryHandler, ErrorInfo, MatchResult } from "../types";
31
24
  import type { ReactNode } from "react";
@@ -33,10 +26,18 @@ import type { MatchContext } from "./match-context.js";
33
26
  import type { MatchApiDeps, ActionContext } from "./types.js";
34
27
  import {
35
28
  getRequestContext,
29
+ _getRequestContext,
36
30
  setRequestContextPrevRouteKey,
37
31
  } from "../server/request-context.js";
38
32
  import { isAutoGeneratedRouteName } from "../route-name.js";
33
+ import type { DefaultRouteName } from "../types/global-namespace.js";
39
34
  import { debugLog, debugWarn } from "./logging.js";
35
+ import {
36
+ resolveRoute,
37
+ ensureFullRouteSnapshot,
38
+ type RouteSnapshot,
39
+ } from "./route-snapshot.js";
40
+ import { resolveNavigation } from "./navigation-snapshot.js";
40
41
 
41
42
  /**
42
43
  * Create match context for full requests (document/SSR).
@@ -47,64 +48,73 @@ export async function createMatchContextForFull<TEnv>(
47
48
  deps: MatchApiDeps<TEnv>,
48
49
  findInterceptForRoute: MatchApiDeps<TEnv>["findInterceptForRoute"],
49
50
  ): Promise<MatchContext<TEnv> | { type: "redirect"; redirectUrl: string }> {
50
- const url = new URL(request.url);
51
- const pathname = url.pathname;
51
+ const reqCtx = _getRequestContext();
52
+ const cleanUrl = reqCtx?.url ?? stripInternalParams(new URL(request.url));
53
+ const pathname = cleanUrl.pathname;
52
54
 
53
55
  const metricsStore = deps.getMetricsStore();
54
56
 
55
- const routeMatchStart = metricsStore ? performance.now() : 0;
56
- const matched = deps.findMatch(pathname, metricsStore);
57
- if (metricsStore) {
58
- metricsStore.metrics.push({
59
- label: "route-matching",
60
- duration: performance.now() - routeMatchStart,
61
- startTime: routeMatchStart - metricsStore.requestStart,
62
- });
57
+ const isHmr = !!request.headers.get("X-RSC-HMR");
58
+ // HMR: clear the manifest cache so stale handler references are discarded.
59
+ if (isHmr) {
60
+ clearManifestCache();
63
61
  }
64
62
 
65
- if (!matched) {
66
- throw new RouteNotFoundError(`No route matched for ${pathname}`, {
67
- cause: { pathname, method: request.method },
63
+ // Reuse the snapshot classifyRequest already resolved when it is a full-render
64
+ // snapshot (isSSR:true) and HMR has not invalidated it — mirrors the partial
65
+ // path. A partial-mode snapshot (isSSR:false) carries the wrong loading()
66
+ // entries and lives in a different manifest partition, so it is NOT reusable.
67
+ const classified = reqCtx?._classifiedRoute;
68
+ const classifiedRoute =
69
+ !isHmr && classified?.isSSR === true ? classified : undefined;
70
+
71
+ // On the reuse path, findMatch + manifest-loading already ran during
72
+ // classifyRequest (which carries no metricsStore), so only the cheap
73
+ // entries/cacheScope materialization is timed here under a distinct label. On
74
+ // the fresh path, resolveRoute emits route-matching + manifest-loading as usual.
75
+ const routeMatchStart = metricsStore ? performance.now() : 0;
76
+
77
+ let snapshot: RouteSnapshot<TEnv>;
78
+ if (classifiedRoute && classifiedRoute.manifestEntry) {
79
+ snapshot = ensureFullRouteSnapshot(classifiedRoute);
80
+ if (metricsStore) {
81
+ metricsStore.metrics.push({
82
+ label: "route-matching:reuse",
83
+ duration: performance.now() - routeMatchStart,
84
+ startTime: routeMatchStart - metricsStore.requestStart,
85
+ });
86
+ }
87
+ } else {
88
+ const result = await resolveRoute<TEnv>(pathname, {
89
+ findMatch: (p) => deps.findMatch(p, metricsStore),
90
+ metricsStore,
91
+ isSSR: true,
68
92
  });
69
- }
70
93
 
71
- if (matched.redirectTo) {
72
- return {
73
- type: "redirect",
74
- redirectUrl: matched.redirectTo + url.search,
75
- };
76
- }
94
+ if (!result) {
95
+ throw new RouteNotFoundError(`No route matched for ${pathname}`, {
96
+ cause: { pathname, method: request.method },
97
+ });
98
+ }
77
99
 
78
- const manifestStart = metricsStore ? performance.now() : 0;
79
- const manifestEntry = await loadManifest(
80
- matched.entry,
81
- matched.routeKey,
82
- pathname,
83
- metricsStore,
84
- true,
85
- );
86
- if (metricsStore) {
87
- metricsStore.metrics.push({
88
- label: "manifest-loading",
89
- duration: performance.now() - manifestStart,
90
- startTime: manifestStart - metricsStore.requestStart,
91
- });
92
- }
100
+ if (result.type === "redirect") {
101
+ // Preserve the raw query string (including internal _rsc* params) on the
102
+ // redirect target, matching the pre-reuse behavior of `url.search`.
103
+ const rawSearch = (reqCtx?.originalUrl ?? new URL(request.url)).search;
104
+ return {
105
+ type: "redirect",
106
+ redirectUrl: result.redirectTo + rawSearch,
107
+ };
108
+ }
93
109
 
94
- if (
95
- manifestEntry.type === "route" &&
96
- manifestEntry.prerenderDef?.options?.passthrough === true
97
- ) {
98
- matched.pt = true;
110
+ snapshot = result.snapshot;
99
111
  }
100
112
 
101
- const routeMiddleware = collectRouteMiddleware(
102
- traverseBack(manifestEntry),
103
- matched.params,
104
- );
113
+ const { matched } = snapshot;
105
114
 
106
- // Clean URL without internal _rsc* params for userland access
107
- const cleanUrl = stripInternalParams(url);
115
+ if (snapshot.isPassthrough) {
116
+ matched.pt = true;
117
+ }
108
118
 
109
119
  const handlerContext = createHandlerContext(
110
120
  matched.params,
@@ -134,14 +144,6 @@ export async function createMatchContextForFull<TEnv>(
134
144
  Store.metrics = metricsStore;
135
145
  }
136
146
 
137
- const entries = [...traverseBack(manifestEntry)];
138
- let cacheScope: CacheScope | null = null;
139
- for (const entry of entries) {
140
- if (entry.cache) {
141
- cacheScope = createCacheScope(entry.cache, cacheScope);
142
- }
143
- }
144
-
145
147
  return {
146
148
  request,
147
149
  url: cleanUrl,
@@ -154,12 +156,10 @@ export async function createMatchContextForFull<TEnv>(
154
156
  prevParams: {},
155
157
  prevMatch: null,
156
158
  matched,
157
- manifestEntry,
158
- entries,
159
+ manifestEntry: snapshot.manifestEntry,
160
+ entries: snapshot.entries,
159
161
  routeKey: matched.routeKey,
160
- localRouteName: matched.routeKey.includes(".")
161
- ? matched.routeKey.split(".").pop()!
162
- : matched.routeKey,
162
+ localRouteName: snapshot.localRouteName,
163
163
  handlerContext,
164
164
  loaderPromises,
165
165
  routeMap: deps.getRouteMap(),
@@ -175,16 +175,16 @@ export async function createMatchContextForFull<TEnv>(
175
175
  segments: { path: [], ids: [] },
176
176
  toRouteName:
177
177
  matched.routeKey && !isAutoGeneratedRouteName(matched.routeKey)
178
- ? matched.routeKey
178
+ ? (matched.routeKey as DefaultRouteName)
179
179
  : undefined,
180
180
  },
181
181
  isSameRouteNavigation: false,
182
182
  interceptResult: null,
183
- cacheScope,
183
+ cacheScope: snapshot.cacheScope,
184
184
  isIntercept: false,
185
185
  actionContext: undefined,
186
186
  isAction: false,
187
- routeMiddleware,
187
+ routeMiddleware: snapshot.routeMiddleware,
188
188
  isFullMatch: true,
189
189
  };
190
190
  }
@@ -199,111 +199,92 @@ export async function createMatchContextForPartial<TEnv>(
199
199
  findInterceptForRoute: MatchApiDeps<TEnv>["findInterceptForRoute"],
200
200
  actionContext?: ActionContext,
201
201
  ): Promise<MatchContext<TEnv> | null> {
202
- const url = new URL(request.url);
203
- const pathname = url.pathname;
202
+ const reqCtx = _getRequestContext();
203
+ // resolveNavigation needs the raw URL (reads internal _rsc_segments /
204
+ // _rsc_stale params that stripInternalParams removes); the clean URL feeds the
205
+ // handler context. Both come off the request context when present.
206
+ const rawUrl = reqCtx?.originalUrl ?? new URL(request.url);
207
+ const cleanUrl = reqCtx?.url ?? stripInternalParams(rawUrl);
208
+ const pathname = cleanUrl.pathname;
204
209
 
205
210
  const metricsStore = deps.getMetricsStore();
206
211
 
207
- const clientSegmentIds =
208
- url.searchParams.get("_rsc_segments")?.split(",").filter(Boolean) || [];
209
- const stale = url.searchParams.get("_rsc_stale") === "true";
210
- const previousUrl =
211
- request.headers.get("X-RSC-Router-Client-Path") ||
212
- request.headers.get("Referer");
213
- const interceptSourceUrl = request.headers.get(
214
- "X-RSC-Router-Intercept-Source",
215
- );
212
+ const isHmr = !!request.headers.get("X-RSC-HMR");
216
213
 
217
214
  // HMR: clear manifest cache so stale handler references are discarded
218
- if (request.headers.get("X-RSC-HMR")) {
215
+ if (isHmr) {
219
216
  clearManifestCache();
220
217
  }
221
218
 
222
- if (!previousUrl) {
223
- return null;
224
- }
225
-
226
- let prevUrl: URL;
227
- try {
228
- prevUrl = new URL(previousUrl, url.origin);
229
- } catch {
230
- return null;
231
- }
219
+ // Reuse the classified snapshot when available and not invalidated by HMR.
220
+ // classifyRequest resolves a partial request with isSSR=false, matching this
221
+ // path. Never reuse an isSSR:true (full-render) snapshot — its loading()
222
+ // entries and manifest partition are wrong here. On HMR, discard to pick up
223
+ // manifest changes.
224
+ const classified = reqCtx?._classifiedRoute;
225
+ const classifiedRoute =
226
+ !isHmr && classified?.isSSR !== true ? classified : undefined;
227
+
228
+ // Time route matching. On the reuse path, only nav findMatch calls are new
229
+ // (current-route findMatch and manifest-loading were already timed during
230
+ // classifyRequest via its metricsStore). On the fresh path, all findMatch
231
+ // calls are measured together.
232
+ const routeMatchStart = metricsStore ? performance.now() : 0;
232
233
 
233
- let interceptContextUrl: URL;
234
- try {
235
- interceptContextUrl = interceptSourceUrl
236
- ? new URL(interceptSourceUrl, url.origin)
237
- : prevUrl;
238
- } catch {
239
- interceptContextUrl = prevUrl;
240
- }
234
+ let snapshot: RouteSnapshot<TEnv>;
235
+ if (classifiedRoute && classifiedRoute.manifestEntry) {
236
+ snapshot = ensureFullRouteSnapshot(classifiedRoute);
237
+ } else {
238
+ const result = await resolveRoute<TEnv>(pathname, {
239
+ findMatch: (p) => deps.findMatch(p, metricsStore),
240
+ metricsStore,
241
+ isSSR: false,
242
+ skipRouteMatchMetric: true,
243
+ });
241
244
 
242
- const routeMatchStart = metricsStore ? performance.now() : 0;
243
- const prevMatch = deps.findMatch(prevUrl.pathname);
244
- const prevParams = prevMatch?.params || {};
245
- const interceptContextMatch = interceptSourceUrl
246
- ? deps.findMatch(interceptContextUrl.pathname)
247
- : prevMatch;
245
+ if (!result) {
246
+ throw new RouteNotFoundError(`No route matched for ${pathname}`, {
247
+ cause: { pathname, method: request.method },
248
+ });
249
+ }
248
250
 
249
- const matched = deps.findMatch(pathname, metricsStore);
251
+ if (result.type === "redirect") {
252
+ return null;
253
+ }
250
254
 
251
- if (metricsStore) {
252
- metricsStore.metrics.push({
253
- label: "route-matching",
254
- duration: performance.now() - routeMatchStart,
255
- startTime: routeMatchStart - metricsStore.requestStart,
256
- });
255
+ snapshot = result.snapshot;
257
256
  }
258
257
 
259
- if (!matched) {
260
- throw new RouteNotFoundError(`No route matched for ${pathname}`, {
261
- cause: { pathname, method: request.method, previousUrl },
262
- });
263
- }
258
+ const { matched } = snapshot;
264
259
 
265
- if (matched.redirectTo) {
266
- return null;
260
+ // Backward compat: downstream middleware reads matched.pt
261
+ if (snapshot.isPassthrough) {
262
+ matched.pt = true;
267
263
  }
268
264
 
269
- if (prevMatch && prevMatch.entry !== matched.entry && !matched.pr) {
270
- debugLog("matchPartial", "route group changed", {
271
- from: prevMatch.routeKey,
272
- to: matched.routeKey,
273
- });
265
+ const nav = await resolveNavigation(request, rawUrl, matched.routeKey, {
266
+ findMatch: deps.findMatch,
267
+ });
268
+ if (!nav) {
269
+ return null;
274
270
  }
275
271
 
276
- const manifestStart = metricsStore ? performance.now() : 0;
277
- const manifestEntry = await loadManifest(
278
- matched.entry,
279
- matched.routeKey,
280
- pathname,
281
- metricsStore,
282
- false,
283
- );
284
272
  if (metricsStore) {
273
+ const isReuse = !!classifiedRoute;
285
274
  metricsStore.metrics.push({
286
- label: "manifest-loading",
287
- duration: performance.now() - manifestStart,
288
- startTime: manifestStart - metricsStore.requestStart,
275
+ label: isReuse ? "route-matching:nav" : "route-matching",
276
+ duration: performance.now() - routeMatchStart,
277
+ startTime: routeMatchStart - metricsStore.requestStart,
289
278
  });
290
279
  }
291
280
 
292
- if (
293
- manifestEntry.type === "route" &&
294
- manifestEntry.prerenderDef?.options?.passthrough === true
295
- ) {
296
- matched.pt = true;
281
+ if (nav.prevMatch && nav.prevMatch.entry !== matched.entry && !matched.pr) {
282
+ debugLog("matchPartial", "route group changed", {
283
+ from: nav.prevMatch.routeKey,
284
+ to: matched.routeKey,
285
+ });
297
286
  }
298
287
 
299
- const routeMiddleware = collectRouteMiddleware(
300
- traverseBack(manifestEntry),
301
- matched.params,
302
- );
303
-
304
- // Clean URL without internal _rsc* params for userland access
305
- const cleanUrl = stripInternalParams(url);
306
-
307
288
  const handlerContext = createHandlerContext(
308
289
  matched.params,
309
290
  request,
@@ -317,9 +298,8 @@ export async function createMatchContextForPartial<TEnv>(
317
298
  matched.pt === true,
318
299
  );
319
300
 
320
- const clientSegmentSet = new Set(clientSegmentIds);
321
301
  debugLog("matchPartial", "client segments", {
322
- segments: Array.from(clientSegmentSet),
302
+ segments: Array.from(nav.clientSegmentSet),
323
303
  });
324
304
 
325
305
  const loaderPromises = new Map<string, Promise<any>>();
@@ -337,100 +317,79 @@ export async function createMatchContextForPartial<TEnv>(
337
317
  Store.metrics = metricsStore;
338
318
  }
339
319
 
340
- const isSameRouteNavigation = !!(
341
- interceptContextMatch && interceptContextMatch.routeKey === matched.routeKey
342
- );
343
-
344
- if (interceptSourceUrl) {
320
+ if (nav.hasInterceptSource) {
345
321
  debugLog("matchPartial.intercept", "intercept context detected", {
346
322
  currentUrl: pathname,
347
- interceptSource: interceptSourceUrl,
348
- contextRoute: interceptContextMatch?.routeKey,
323
+ interceptSource: nav.interceptContextUrl.href,
324
+ contextRoute: nav.interceptContextMatch?.routeKey,
349
325
  currentRoute: matched.routeKey,
350
- sameRouteNavigation: isSameRouteNavigation,
326
+ sameRouteNavigation: nav.isSameRouteNavigation,
351
327
  });
352
328
  }
353
329
 
354
- const localRouteName = matched.routeKey.includes(".")
355
- ? matched.routeKey.split(".").pop()!
356
- : matched.routeKey;
357
-
358
- const filteredSegmentIds = clientSegmentIds.filter((id) => {
359
- if (id.includes(".@")) return false;
360
- if (/D\d+\./.test(id)) return false;
361
- return true;
362
- });
363
- const effectiveFromUrl = interceptSourceUrl ? interceptContextUrl : prevUrl;
364
- const effectiveFromMatch = interceptSourceUrl
365
- ? interceptContextMatch
366
- : prevMatch;
367
-
368
- // Store previous route key on the request context for revalidation
369
- // fromRouteName. Uses effectiveFromMatch so intercept-source navigations
370
- // see the intercept origin route, not the plain previous URL route.
371
- setRequestContextPrevRouteKey(effectiveFromMatch?.routeKey);
330
+ setRequestContextPrevRouteKey(
331
+ nav.effectiveFromMatch?.routeKey,
332
+ nav.effectiveFromUrl,
333
+ nav.effectiveFromMatch?.params ?? nav.prevParams,
334
+ );
372
335
 
373
336
  const interceptSelectorContext: InterceptSelectorContext = {
374
- from: effectiveFromUrl,
337
+ from: nav.effectiveFromUrl,
375
338
  to: cleanUrl,
376
339
  params: matched.params,
377
340
  request,
378
341
  env,
379
342
  segments: {
380
- path: effectiveFromUrl.pathname.split("/").filter(Boolean),
381
- ids: filteredSegmentIds,
343
+ path: nav.effectiveFromUrl.pathname.split("/").filter(Boolean),
344
+ ids: nav.filteredSegmentIds,
382
345
  },
383
346
  fromRouteName:
384
- effectiveFromMatch?.routeKey &&
385
- !isAutoGeneratedRouteName(effectiveFromMatch.routeKey)
386
- ? effectiveFromMatch.routeKey
347
+ nav.effectiveFromMatch?.routeKey &&
348
+ !isAutoGeneratedRouteName(nav.effectiveFromMatch.routeKey)
349
+ ? (nav.effectiveFromMatch.routeKey as DefaultRouteName)
387
350
  : undefined,
388
351
  toRouteName:
389
352
  matched.routeKey && !isAutoGeneratedRouteName(matched.routeKey)
390
- ? matched.routeKey
353
+ ? (matched.routeKey as DefaultRouteName)
391
354
  : undefined,
392
355
  };
393
356
  const isAction = !!actionContext;
394
357
 
395
- const clientHasInterceptSegments = [...clientSegmentSet].some((id) =>
358
+ const clientHasInterceptSegments = [...nav.clientSegmentSet].some((id) =>
396
359
  id.includes(".@"),
397
360
  );
398
361
  const skipInterceptForAction = isAction && !clientHasInterceptSegments;
399
362
  const interceptResult =
400
- isSameRouteNavigation || skipInterceptForAction
363
+ nav.isSameRouteNavigation || skipInterceptForAction
401
364
  ? null
402
365
  : findInterceptForRoute(
403
366
  matched.routeKey,
404
- manifestEntry.parent,
367
+ snapshot.manifestEntry.parent,
405
368
  interceptSelectorContext,
406
369
  isAction,
407
370
  ) ||
408
- (localRouteName !== matched.routeKey
371
+ (snapshot.localRouteName !== matched.routeKey
409
372
  ? findInterceptForRoute(
410
- localRouteName,
411
- manifestEntry.parent,
373
+ snapshot.localRouteName,
374
+ snapshot.manifestEntry.parent,
412
375
  interceptSelectorContext,
413
376
  isAction,
414
377
  )
415
378
  : null);
416
379
 
380
+ // Make a mutable copy of clientSegmentSet so we can delete entries
381
+ // for same-route navigation forcing
382
+ const clientSegmentSet = new Set(nav.clientSegmentSet);
383
+
417
384
  if (
418
- isSameRouteNavigation &&
419
- manifestEntry.type === "route" &&
420
- interceptSourceUrl
385
+ nav.isSameRouteNavigation &&
386
+ snapshot.manifestEntry.type === "route" &&
387
+ nav.hasInterceptSource
421
388
  ) {
422
389
  debugLog("matchPartial.intercept", "forcing route segment render", {
423
- segmentId: manifestEntry.shortCode,
390
+ segmentId: snapshot.manifestEntry.shortCode,
424
391
  });
425
- clientSegmentSet.delete(manifestEntry.shortCode);
426
- }
427
-
428
- const entries = [...traverseBack(manifestEntry)];
429
- let cacheScope: CacheScope | null = null;
430
- for (const entry of entries) {
431
- if (entry.cache) {
432
- cacheScope = createCacheScope(entry.cache, cacheScope);
433
- }
392
+ clientSegmentSet.delete(snapshot.manifestEntry.shortCode);
434
393
  }
435
394
 
436
395
  const isIntercept = !!interceptResult;
@@ -440,31 +399,31 @@ export async function createMatchContextForPartial<TEnv>(
440
399
  url: cleanUrl,
441
400
  pathname,
442
401
  env,
443
- clientSegmentIds,
402
+ clientSegmentIds: nav.clientSegmentIds,
444
403
  clientSegmentSet,
445
- stale,
446
- prevUrl,
447
- prevParams,
448
- prevMatch,
404
+ stale: nav.stale,
405
+ prevUrl: nav.prevUrl,
406
+ prevParams: nav.prevParams,
407
+ prevMatch: nav.prevMatch,
449
408
  matched,
450
- manifestEntry,
451
- entries,
409
+ manifestEntry: snapshot.manifestEntry,
410
+ entries: snapshot.entries,
452
411
  routeKey: matched.routeKey,
453
- localRouteName,
412
+ localRouteName: snapshot.localRouteName,
454
413
  handlerContext,
455
414
  loaderPromises,
456
415
  routeMap: deps.getRouteMap(),
457
416
  metricsStore,
458
417
  Store,
459
- interceptContextMatch,
418
+ interceptContextMatch: nav.interceptContextMatch,
460
419
  interceptSelectorContext,
461
- isSameRouteNavigation,
420
+ isSameRouteNavigation: nav.isSameRouteNavigation,
462
421
  interceptResult,
463
- cacheScope,
422
+ cacheScope: snapshot.cacheScope,
464
423
  isIntercept,
465
424
  actionContext,
466
425
  isAction,
467
- routeMiddleware,
426
+ routeMiddleware: snapshot.routeMiddleware,
468
427
  isFullMatch: false,
469
428
  };
470
429
  }
@@ -485,7 +444,7 @@ export async function matchError<TEnv>(
485
444
 
486
445
  debugLog("matchError", "matching error", { pathname });
487
446
 
488
- const matched = deps.findMatch(pathname);
447
+ const matched = await deps.findMatch(pathname);
489
448
  if (!matched) {
490
449
  debugWarn("matchError", "no route matched", { pathname });
491
450
  return null;
@@ -615,6 +574,7 @@ export async function matchError<TEnv>(
615
574
  segments: [errorSegment],
616
575
  matched: matchedIds,
617
576
  diff: [errorSegment.id],
577
+ resolvedIds: [errorSegment.id],
618
578
  params: matched.params,
619
579
  };
620
580
  }
@@ -242,25 +242,3 @@ export function createPipelineState(): MatchPipelineState {
242
242
  slots: {},
243
243
  };
244
244
  }
245
-
246
- /**
247
- * Input parameters for createMatchContext
248
- */
249
- export interface CreateMatchContextInput<TEnv = any> {
250
- request: Request;
251
- env: TEnv;
252
- actionContext?: ActionContext;
253
- }
254
-
255
- /**
256
- * Result from createMatchContext - either a context or null (fall back to full match)
257
- */
258
- export type CreateMatchContextResult<TEnv = any> =
259
- | { type: "context"; ctx: MatchContext<TEnv> }
260
- | { type: "fallback"; reason: string }
261
- | { type: "error"; error: Error };
262
-
263
- // Note: createMatchContext() will be implemented in Step J10 when we wire everything together.
264
- // It requires access to RouterContext (findMatch, loadManifest, etc.) which are closure
265
- // functions from createRouter(). The implementation will live in router.ts initially
266
- // and call getRouterContext() to access these dependencies.