@rangojs/router 0.0.0-experimental.1878aa49 → 0.0.0-experimental.190fb30d

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 (443) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +303 -741
  3. package/dist/bin/rango.js +605 -146
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +4117 -1211
  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 +228 -33
  13. package/skills/caching/SKILL.md +336 -19
  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 +247 -17
  37. package/skills/loader/SKILL.md +248 -10
  38. package/skills/middleware/SKILL.md +57 -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 +99 -10
  48. package/skills/ppr/SKILL.md +618 -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 +141 -9
  54. package/skills/router-setup/SKILL.md +44 -9
  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 -626
  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/connection-warmup.ts +134 -0
  91. package/src/browser/cookie-name.ts +140 -0
  92. package/src/browser/event-controller.ts +252 -158
  93. package/src/browser/history-state.ts +21 -0
  94. package/src/browser/index.ts +3 -3
  95. package/src/browser/invalidate-client-cache.ts +52 -0
  96. package/src/browser/logging.ts +28 -0
  97. package/src/browser/merge-segment-loaders.ts +6 -4
  98. package/src/browser/navigation-bridge.ts +115 -27
  99. package/src/browser/navigation-client.ts +163 -70
  100. package/src/browser/navigation-store-handle.ts +38 -0
  101. package/src/browser/navigation-store.ts +161 -73
  102. package/src/browser/navigation-transaction.ts +9 -59
  103. package/src/browser/network-error-handler.ts +34 -7
  104. package/src/browser/partial-update.ts +186 -135
  105. package/src/browser/prefetch/cache.ts +246 -71
  106. package/src/browser/prefetch/fetch.ts +350 -38
  107. package/src/browser/prefetch/queue.ts +61 -12
  108. package/src/browser/rango-state.ts +158 -76
  109. package/src/browser/react/Link.tsx +70 -9
  110. package/src/browser/react/NavigationProvider.tsx +202 -120
  111. package/src/browser/react/ScrollRestoration.tsx +10 -6
  112. package/src/browser/react/filter-segment-order.ts +66 -7
  113. package/src/browser/react/index.ts +0 -48
  114. package/src/browser/react/location-state-shared.ts +178 -8
  115. package/src/browser/react/location-state.ts +39 -14
  116. package/src/browser/react/use-action.ts +6 -15
  117. package/src/browser/react/use-handle.ts +23 -69
  118. package/src/browser/react/use-href.tsx +8 -1
  119. package/src/browser/react/use-link-status.ts +33 -8
  120. package/src/browser/react/use-navigation.ts +32 -7
  121. package/src/browser/react/use-params.ts +20 -10
  122. package/src/browser/react/use-reverse.ts +106 -0
  123. package/src/browser/react/use-router.ts +25 -3
  124. package/src/browser/react/use-search-params.ts +0 -5
  125. package/src/browser/react/use-segments.ts +11 -21
  126. package/src/browser/response-adapter.ts +99 -8
  127. package/src/browser/rsc-router.tsx +145 -28
  128. package/src/browser/scroll-restoration.ts +44 -27
  129. package/src/browser/segment-reconciler.ts +44 -12
  130. package/src/browser/segment-structure-assert.ts +2 -2
  131. package/src/browser/server-action-bridge.ts +236 -65
  132. package/src/browser/types.ts +102 -9
  133. package/src/browser/validate-redirect-origin.ts +43 -16
  134. package/src/build/collect-fallback-refs.ts +107 -0
  135. package/src/build/generate-manifest.ts +205 -159
  136. package/src/build/generate-route-types.ts +3 -1
  137. package/src/build/index.ts +11 -3
  138. package/src/build/prefix-tree-utils.ts +123 -0
  139. package/src/build/route-trie.ts +198 -41
  140. package/src/build/route-types/ast-route-extraction.ts +15 -8
  141. package/src/build/route-types/codegen.ts +16 -5
  142. package/src/build/route-types/include-resolution.ts +456 -62
  143. package/src/build/route-types/param-extraction.ts +6 -3
  144. package/src/build/route-types/per-module-writer.ts +22 -6
  145. package/src/build/route-types/router-processing.ts +128 -51
  146. package/src/build/route-types/scan-filter.ts +9 -2
  147. package/src/build/route-types/source-scan.ts +216 -0
  148. package/src/build/runtime-discovery.ts +13 -21
  149. package/src/cache/cache-error.ts +104 -0
  150. package/src/cache/cache-key-utils.ts +58 -13
  151. package/src/cache/cache-policy.ts +108 -34
  152. package/src/cache/cache-runtime.ts +454 -101
  153. package/src/cache/cache-scope.ts +187 -96
  154. package/src/cache/cache-tag.ts +149 -0
  155. package/src/cache/cf/cf-base64.ts +33 -0
  156. package/src/cache/cf/cf-cache-constants.ts +127 -0
  157. package/src/cache/cf/cf-cache-store.ts +2206 -372
  158. package/src/cache/cf/cf-cache-types.ts +349 -0
  159. package/src/cache/cf/cf-kv-utils.ts +46 -0
  160. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  161. package/src/cache/cf/index.ts +6 -16
  162. package/src/cache/document-cache.ts +126 -41
  163. package/src/cache/handle-snapshot.ts +70 -0
  164. package/src/cache/index.ts +23 -20
  165. package/src/cache/memory-segment-store.ts +243 -37
  166. package/src/cache/profile-registry.ts +46 -31
  167. package/src/cache/read-through-swr.ts +56 -12
  168. package/src/cache/segment-codec.ts +13 -21
  169. package/src/cache/shell-snapshot.ts +417 -0
  170. package/src/cache/tag-invalidation.ts +230 -0
  171. package/src/cache/types.ts +194 -99
  172. package/src/cache/vercel/index.ts +11 -0
  173. package/src/cache/vercel/vercel-cache-store.ts +1132 -0
  174. package/src/client.rsc.tsx +41 -21
  175. package/src/client.tsx +116 -290
  176. package/src/cloudflare/index.ts +11 -0
  177. package/src/cloudflare/tracing.ts +108 -0
  178. package/src/component-utils.ts +19 -0
  179. package/src/components/DefaultDocument.tsx +8 -2
  180. package/src/context-var.ts +18 -6
  181. package/src/decode-loader-results.ts +52 -0
  182. package/src/defer.ts +185 -0
  183. package/src/deps/ssr.ts +0 -1
  184. package/src/encode-kv.ts +49 -0
  185. package/src/errors.ts +30 -4
  186. package/src/escape-script.ts +52 -0
  187. package/src/handle.ts +104 -34
  188. package/src/handles/MetaTags.tsx +24 -53
  189. package/src/handles/Scripts.tsx +183 -0
  190. package/src/handles/breadcrumbs.ts +35 -8
  191. package/src/handles/deferred-resolution.ts +127 -0
  192. package/src/handles/is-thenable.ts +18 -0
  193. package/src/handles/meta.ts +14 -40
  194. package/src/handles/script.ts +244 -0
  195. package/src/host/cookie-handler.ts +9 -60
  196. package/src/host/errors.ts +13 -22
  197. package/src/host/index.ts +9 -2
  198. package/src/host/pattern-matcher.ts +23 -52
  199. package/src/host/router.ts +107 -99
  200. package/src/host/testing.ts +40 -27
  201. package/src/host/types.ts +37 -4
  202. package/src/host/utils.ts +1 -1
  203. package/src/href-client.ts +137 -22
  204. package/src/index.rsc.ts +100 -13
  205. package/src/index.ts +143 -19
  206. package/src/internal-debug.ts +11 -10
  207. package/src/loader-store.ts +500 -0
  208. package/src/loader.rsc.ts +20 -13
  209. package/src/loader.ts +12 -11
  210. package/src/missing-id-error.ts +68 -0
  211. package/src/outlet-context.ts +1 -1
  212. package/src/outlet-provider.tsx +1 -5
  213. package/src/prerender/param-hash.ts +16 -16
  214. package/src/prerender/store.ts +37 -41
  215. package/src/prerender.ts +215 -86
  216. package/src/redirect-origin.ts +114 -0
  217. package/src/regex-escape.ts +8 -0
  218. package/src/render-error-thrower.tsx +20 -0
  219. package/src/response-utils.ts +62 -0
  220. package/src/reverse.ts +65 -15
  221. package/src/root-error-boundary.tsx +1 -19
  222. package/src/route-content-wrapper.tsx +19 -77
  223. package/src/route-definition/dsl-helpers.ts +461 -304
  224. package/src/route-definition/helper-factories.ts +28 -140
  225. package/src/route-definition/helpers-types.ts +147 -72
  226. package/src/route-definition/index.ts +4 -2
  227. package/src/route-definition/redirect.ts +44 -11
  228. package/src/route-definition/resolve-handler-use.ts +160 -0
  229. package/src/route-definition/use-item-types.ts +29 -0
  230. package/src/route-map-builder.ts +41 -20
  231. package/src/route-types.ts +37 -46
  232. package/src/router/basename.ts +14 -0
  233. package/src/router/content-negotiation.ts +164 -17
  234. package/src/router/error-handling.ts +45 -18
  235. package/src/router/find-match.ts +129 -30
  236. package/src/router/handler-context.ts +47 -22
  237. package/src/router/instrument.ts +355 -0
  238. package/src/router/intercept-resolution.ts +39 -20
  239. package/src/router/lazy-includes.ts +85 -62
  240. package/src/router/loader-resolution.ts +277 -54
  241. package/src/router/logging.ts +0 -6
  242. package/src/router/manifest.ts +97 -57
  243. package/src/router/match-api.ts +178 -218
  244. package/src/router/match-context.ts +0 -22
  245. package/src/router/match-handlers.ts +211 -165
  246. package/src/router/match-middleware/background-revalidation.ts +40 -24
  247. package/src/router/match-middleware/cache-lookup.ts +168 -277
  248. package/src/router/match-middleware/cache-store.ts +64 -52
  249. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  250. package/src/router/match-middleware/segment-resolution.ts +45 -14
  251. package/src/router/match-pipelines.ts +1 -42
  252. package/src/router/match-result.ts +113 -45
  253. package/src/router/metrics.ts +0 -34
  254. package/src/router/middleware-types.ts +7 -134
  255. package/src/router/middleware.ts +298 -172
  256. package/src/router/navigation-snapshot.ts +133 -0
  257. package/src/router/params-util.ts +23 -0
  258. package/src/router/parse-pattern.ts +115 -0
  259. package/src/router/pattern-matching.ts +181 -150
  260. package/src/router/prefetch-cache-ttl.ts +51 -0
  261. package/src/router/prefetch-limits.ts +37 -0
  262. package/src/router/prerender-match.ts +201 -56
  263. package/src/router/preview-match.ts +35 -103
  264. package/src/router/request-classification.ts +291 -0
  265. package/src/router/revalidation.ts +123 -73
  266. package/src/router/route-snapshot.ts +256 -0
  267. package/src/router/router-context.ts +6 -29
  268. package/src/router/router-interfaces.ts +125 -35
  269. package/src/router/router-options.ts +166 -5
  270. package/src/router/router-registry.ts +2 -5
  271. package/src/router/segment-resolution/fresh.ts +188 -86
  272. package/src/router/segment-resolution/helpers.ts +86 -6
  273. package/src/router/segment-resolution/loader-cache.ts +155 -39
  274. package/src/router/segment-resolution/loader-mask.ts +67 -0
  275. package/src/router/segment-resolution/loader-snapshot.ts +308 -0
  276. package/src/router/segment-resolution/revalidation.ts +344 -319
  277. package/src/router/segment-resolution/static-store.ts +19 -5
  278. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  279. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  280. package/src/router/segment-resolution.ts +5 -1
  281. package/src/router/segment-wrappers.ts +6 -5
  282. package/src/router/state-cookie-name.ts +33 -0
  283. package/src/router/substitute-pattern-params.ts +75 -0
  284. package/src/router/telemetry-otel.ts +160 -200
  285. package/src/router/telemetry.ts +105 -20
  286. package/src/router/timeout.ts +0 -20
  287. package/src/router/tracing.ts +215 -0
  288. package/src/router/trie-matching.ts +171 -59
  289. package/src/router/types.ts +9 -63
  290. package/src/router/url-params.ts +57 -0
  291. package/src/router.ts +170 -72
  292. package/src/rsc/full-payload.ts +70 -0
  293. package/src/rsc/handler-context.ts +3 -2
  294. package/src/rsc/handler.ts +678 -513
  295. package/src/rsc/helpers.ts +168 -46
  296. package/src/rsc/index.ts +2 -5
  297. package/src/rsc/json-route-result.ts +38 -0
  298. package/src/rsc/loader-fetch.ts +127 -31
  299. package/src/rsc/manifest-init.ts +29 -42
  300. package/src/rsc/nonce.ts +10 -1
  301. package/src/rsc/origin-guard.ts +39 -25
  302. package/src/rsc/progressive-enhancement.ts +134 -15
  303. package/src/rsc/redirect-guard.ts +100 -0
  304. package/src/rsc/response-cache-serve.ts +238 -0
  305. package/src/rsc/response-error.ts +79 -12
  306. package/src/rsc/response-route-handler.ts +99 -189
  307. package/src/rsc/rsc-rendering.ts +497 -77
  308. package/src/rsc/runtime-warnings.ts +23 -10
  309. package/src/rsc/server-action.ts +286 -114
  310. package/src/rsc/shell-capture.ts +1166 -0
  311. package/src/rsc/shell-serve.ts +181 -0
  312. package/src/rsc/ssr-setup.ts +17 -1
  313. package/src/rsc/transition-gate.ts +89 -0
  314. package/src/rsc/types.ts +54 -5
  315. package/src/runtime-env.ts +18 -0
  316. package/src/search-params.ts +35 -30
  317. package/src/segment-content-promise.ts +67 -0
  318. package/src/segment-loader-promise.ts +167 -0
  319. package/src/segment-system.tsx +355 -204
  320. package/src/serialize.ts +243 -0
  321. package/src/server/context.ts +247 -54
  322. package/src/server/cookie-parse.ts +32 -0
  323. package/src/server/cookie-store.ts +152 -5
  324. package/src/server/handle-store.ts +40 -38
  325. package/src/server/loader-registry.ts +33 -42
  326. package/src/server/request-context.ts +502 -161
  327. package/src/ssr/index.tsx +467 -178
  328. package/src/ssr/inject-rsc-eager.ts +167 -0
  329. package/src/ssr/ssr-root.tsx +228 -0
  330. package/src/static-handler.ts +27 -18
  331. package/src/testing/cache-status.ts +162 -0
  332. package/src/testing/collect-handle.ts +46 -0
  333. package/src/testing/dispatch.ts +813 -0
  334. package/src/testing/dom.entry.ts +22 -0
  335. package/src/testing/e2e/fixture.ts +188 -0
  336. package/src/testing/e2e/index.ts +128 -0
  337. package/src/testing/e2e/matchers.ts +35 -0
  338. package/src/testing/e2e/page-helpers.ts +272 -0
  339. package/src/testing/e2e/parity.ts +387 -0
  340. package/src/testing/e2e/server.ts +195 -0
  341. package/src/testing/flight-matchers.ts +97 -0
  342. package/src/testing/flight-normalize.ts +11 -0
  343. package/src/testing/flight-runtime.d.ts +57 -0
  344. package/src/testing/flight-tree.ts +682 -0
  345. package/src/testing/flight.entry.ts +52 -0
  346. package/src/testing/flight.ts +257 -0
  347. package/src/testing/generated-routes.ts +199 -0
  348. package/src/testing/index.ts +105 -0
  349. package/src/testing/internal/context.ts +371 -0
  350. package/src/testing/internal/flight-client-globals.ts +30 -0
  351. package/src/testing/internal/seed-vars.ts +54 -0
  352. package/src/testing/render-handler.ts +357 -0
  353. package/src/testing/render-route.tsx +584 -0
  354. package/src/testing/run-loader.ts +385 -0
  355. package/src/testing/run-middleware.ts +205 -0
  356. package/src/testing/run-transition-when.ts +164 -0
  357. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  358. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  359. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  360. package/src/testing/vitest-stubs/version.ts +5 -0
  361. package/src/testing/vitest.ts +305 -0
  362. package/src/theme/ThemeProvider.tsx +56 -84
  363. package/src/theme/ThemeScript.tsx +7 -9
  364. package/src/theme/constants.ts +52 -13
  365. package/src/theme/index.ts +0 -7
  366. package/src/theme/theme-context.ts +1 -5
  367. package/src/theme/theme-script.ts +22 -21
  368. package/src/theme/use-theme.ts +0 -3
  369. package/src/types/boundaries.ts +0 -35
  370. package/src/types/cache-types.ts +13 -4
  371. package/src/types/error-types.ts +30 -90
  372. package/src/types/global-namespace.ts +54 -41
  373. package/src/types/handler-context.ts +120 -62
  374. package/src/types/index.ts +3 -10
  375. package/src/types/loader-types.ts +40 -10
  376. package/src/types/request-scope.ts +112 -0
  377. package/src/types/route-config.ts +20 -52
  378. package/src/types/route-entry.ts +12 -7
  379. package/src/types/segments.ts +136 -15
  380. package/src/urls/include-helper.ts +40 -75
  381. package/src/urls/include-provider.ts +71 -0
  382. package/src/urls/index.ts +2 -11
  383. package/src/urls/path-helper-types.ts +102 -23
  384. package/src/urls/path-helper.ts +62 -111
  385. package/src/urls/pattern-types.ts +72 -19
  386. package/src/urls/response-types.ts +25 -22
  387. package/src/urls/type-extraction.ts +98 -154
  388. package/src/urls/urls-function.ts +1 -19
  389. package/src/use-loader.tsx +346 -89
  390. package/src/vercel/index.ts +11 -0
  391. package/src/vercel/tracing.ts +88 -0
  392. package/src/vite/debug.ts +185 -0
  393. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  394. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  395. package/src/vite/discovery/discover-routers.ts +127 -86
  396. package/src/vite/discovery/discovery-errors.ts +255 -0
  397. package/src/vite/discovery/gate-state.ts +171 -0
  398. package/src/vite/discovery/prerender-collection.ts +214 -132
  399. package/src/vite/discovery/route-types-writer.ts +40 -84
  400. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  401. package/src/vite/discovery/state.ts +57 -4
  402. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  403. package/src/vite/index.ts +15 -0
  404. package/src/vite/inject-client-debug.ts +88 -0
  405. package/src/vite/plugin-types.ts +261 -6
  406. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  407. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  408. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  409. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  410. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  411. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  412. package/src/vite/plugins/expose-action-id.ts +48 -95
  413. package/src/vite/plugins/expose-id-utils.ts +96 -51
  414. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  415. package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
  416. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  417. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  418. package/src/vite/plugins/expose-internal-ids.ts +553 -317
  419. package/src/vite/plugins/performance-tracks.ts +26 -25
  420. package/src/vite/plugins/refresh-cmd.ts +89 -27
  421. package/src/vite/plugins/use-cache-transform.ts +73 -83
  422. package/src/vite/plugins/vercel-output.ts +384 -0
  423. package/src/vite/plugins/version-injector.ts +40 -29
  424. package/src/vite/plugins/version-plugin.ts +37 -40
  425. package/src/vite/plugins/virtual-entries.ts +138 -27
  426. package/src/vite/rango.ts +238 -139
  427. package/src/vite/router-discovery.ts +1091 -159
  428. package/src/vite/utils/ast-handler-extract.ts +26 -35
  429. package/src/vite/utils/banner.ts +1 -1
  430. package/src/vite/utils/bundle-analysis.ts +10 -15
  431. package/src/vite/utils/client-chunks.ts +184 -0
  432. package/src/vite/utils/directive-prologue.ts +40 -0
  433. package/src/vite/utils/forward-user-plugins.ts +171 -0
  434. package/src/vite/utils/manifest-utils.ts +4 -59
  435. package/src/vite/utils/package-resolution.ts +20 -52
  436. package/src/vite/utils/prerender-utils.ts +98 -38
  437. package/src/vite/utils/shared-utils.ts +142 -43
  438. package/src/browser/action-response-classifier.ts +0 -99
  439. package/src/browser/react/use-client-cache.ts +0 -58
  440. package/src/browser/shallow.ts +0 -40
  441. package/src/handles/index.ts +0 -7
  442. package/src/network-error-thrower.tsx +0 -23
  443. package/src/router/middleware-cookies.ts +0 -55
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Route Snapshot
3
+ *
4
+ * Pure data type representing the fully-resolved state of a single route match.
5
+ * Consolidates the duplicated findMatch + loadManifest + collectRouteMiddleware +
6
+ * cacheScope derivation that previously lived separately in preview-match.ts
7
+ * and match-api.ts.
8
+ *
9
+ * resolveRoute() is the factory: given a pathname and dependencies, it returns
10
+ * a RouteSnapshot (or redirect/null). Consumers (createMatchContextForFull,
11
+ * createMatchContextForPartial, previewMatch) read snapshot fields instead of
12
+ * re-deriving them.
13
+ */
14
+
15
+ import type { CacheScope } from "../cache/cache-scope.js";
16
+ import { createCacheScope } from "../cache/cache-scope.js";
17
+ import type { EntryData, MetricsStore } from "../server/context.js";
18
+ import { loadManifest } from "./manifest.js";
19
+ import { collectRouteMiddleware } from "./middleware.js";
20
+ import type { CollectedMiddleware } from "./middleware-types.js";
21
+ import { traverseBack } from "./pattern-matching.js";
22
+ import type { RouteMatchResult } from "./pattern-matching.js";
23
+
24
+ /**
25
+ * Immutable snapshot of a resolved route match.
26
+ *
27
+ * Contains everything derivable from (pathname, findMatch, loadManifest)
28
+ * without request context, navigation state, or intercept logic.
29
+ */
30
+ export interface RouteSnapshot<TEnv = any> {
31
+ /** Raw match result from the trie/pattern matcher */
32
+ matched: RouteMatchResult<TEnv>;
33
+ /** Resolved manifest entry (with loaded handler, loader, etc.) */
34
+ manifestEntry: EntryData;
35
+ /** All entries in the route chain (from traverseBack) */
36
+ entries: EntryData[];
37
+ /** Canonical route key (e.g. "blog.detail") */
38
+ routeKey: string;
39
+ /** Last segment of a dotted route key (e.g. "detail" from "blog.detail") */
40
+ localRouteName: string;
41
+ /** Extracted route params */
42
+ params: Record<string, string>;
43
+ /** Collected route-level middleware from the entry tree */
44
+ routeMiddleware: CollectedMiddleware[];
45
+ /** Merged cache scope from the entry chain */
46
+ cacheScope: CacheScope | null;
47
+ /** Whether the matched route is a passthrough route */
48
+ isPassthrough: boolean;
49
+ /** Response type for non-RSC routes (e.g. "application/json") */
50
+ responseType?: string;
51
+ /**
52
+ * The isSSR flag the manifest was resolved with. Recorded so consumers can
53
+ * decide whether the snapshot is reusable: a snapshot resolved with isSSR
54
+ * differs (loading({ ssr: false }) entries) and is cached under a different
55
+ * manifest partition, so the full (document) path only reuses an isSSR:true
56
+ * snapshot and the partial path only reuses a non-isSSR one. Undefined on
57
+ * inline snapshots (redirect / not-found) that are never reused.
58
+ */
59
+ isSSR?: boolean;
60
+ }
61
+
62
+ export type ResolveRouteResult<TEnv = any> =
63
+ | { type: "match"; snapshot: RouteSnapshot<TEnv> }
64
+ | { type: "redirect"; redirectTo: string }
65
+ | null;
66
+
67
+ export interface ResolveRouteDeps<TEnv = any> {
68
+ findMatch: (
69
+ pathname: string,
70
+ ) => RouteMatchResult<TEnv> | null | Promise<RouteMatchResult<TEnv> | null>;
71
+ metricsStore?: MetricsStore;
72
+ isSSR?: boolean;
73
+ /**
74
+ * When true, skip entries array and cacheScope chain construction.
75
+ * Used by previewMatch which only needs matched, manifestEntry,
76
+ * routeMiddleware, and responseType — avoids an extra traverseBack
77
+ * allocation and cacheScope composition on the hot classification path.
78
+ */
79
+ lite?: boolean;
80
+ /**
81
+ * When true, skip pushing the "route-matching" metric internally.
82
+ * Used by createMatchContextForPartial on the fresh path (no snapshot
83
+ * reuse) so it can measure current + prev + intercept-source findMatch
84
+ * calls under one combined "route-matching" metric. On the reuse path,
85
+ * the partial path emits "route-matching:nav" for the prev +
86
+ * intercept-source lookups only (current-route resolution was done
87
+ * during classification without metrics).
88
+ */
89
+ skipRouteMatchMetric?: boolean;
90
+ }
91
+
92
+ /**
93
+ * Resolve a pathname into a RouteSnapshot.
94
+ *
95
+ * This is the single source of truth for route derivation. It performs:
96
+ * 1. findMatch(pathname)
97
+ * 2. Redirect check
98
+ * 3. loadManifest
99
+ * 4. Passthrough detection
100
+ * 5. collectRouteMiddleware
101
+ * 6. Cache scope chain
102
+ * 7. responseType + localRouteName extraction
103
+ *
104
+ * Metrics timing is preserved identically to the previous inline code.
105
+ */
106
+ export async function resolveRoute<TEnv = any>(
107
+ pathname: string,
108
+ deps: ResolveRouteDeps<TEnv>,
109
+ ): Promise<ResolveRouteResult<TEnv>> {
110
+ const {
111
+ metricsStore,
112
+ isSSR = false,
113
+ lite = false,
114
+ skipRouteMatchMetric = false,
115
+ } = deps;
116
+
117
+ const routeMatchStart =
118
+ metricsStore && !skipRouteMatchMetric ? performance.now() : 0;
119
+ const matched = await deps.findMatch(pathname);
120
+ if (metricsStore && !skipRouteMatchMetric) {
121
+ metricsStore.metrics.push({
122
+ label: "route-matching",
123
+ duration: performance.now() - routeMatchStart,
124
+ startTime: routeMatchStart - metricsStore.requestStart,
125
+ });
126
+ }
127
+
128
+ if (!matched) {
129
+ return null;
130
+ }
131
+
132
+ if (matched.redirectTo) {
133
+ return { type: "redirect", redirectTo: matched.redirectTo };
134
+ }
135
+
136
+ const manifestStart = metricsStore ? performance.now() : 0;
137
+ const manifestEntry = await loadManifest(
138
+ matched.entry,
139
+ matched.routeKey,
140
+ pathname,
141
+ metricsStore,
142
+ isSSR,
143
+ );
144
+ if (metricsStore) {
145
+ metricsStore.metrics.push({
146
+ label: "manifest-loading",
147
+ duration: performance.now() - manifestStart,
148
+ startTime: manifestStart - metricsStore.requestStart,
149
+ });
150
+ }
151
+
152
+ const isPassthrough =
153
+ manifestEntry.type === "route" && manifestEntry.isPassthrough === true;
154
+
155
+ let entries: EntryData[];
156
+ let cacheScope: CacheScope | null = null;
157
+ if (lite) {
158
+ entries = [];
159
+ } else {
160
+ ({ entries, cacheScope } = buildEntriesAndCacheScope(manifestEntry));
161
+ }
162
+
163
+ const routeMiddleware = collectRouteMiddleware(
164
+ lite ? traverseBack(manifestEntry) : entries,
165
+ matched.params,
166
+ );
167
+
168
+ const responseType =
169
+ matched.responseType ||
170
+ (manifestEntry.type === "route" ? manifestEntry.responseType : undefined);
171
+
172
+ const localRouteName = matched.routeKey.includes(".")
173
+ ? matched.routeKey.split(".").pop()!
174
+ : matched.routeKey;
175
+
176
+ return {
177
+ type: "match",
178
+ snapshot: {
179
+ matched,
180
+ manifestEntry,
181
+ entries,
182
+ routeKey: matched.routeKey,
183
+ localRouteName,
184
+ params: matched.params,
185
+ routeMiddleware,
186
+ cacheScope,
187
+ isPassthrough,
188
+ responseType,
189
+ isSSR,
190
+ },
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Fill in the entries and cacheScope fields on a lite snapshot.
196
+ *
197
+ * When classifyRequest produces a lite snapshot (entries=[], cacheScope=null),
198
+ * this function computes the missing fields from manifestEntry without
199
+ * re-running findMatch, loadManifest, or collectRouteMiddleware.
200
+ *
201
+ * If the snapshot already has entries, returns it as-is.
202
+ */
203
+ export function ensureFullRouteSnapshot<TEnv = any>(
204
+ snapshot: RouteSnapshot<TEnv>,
205
+ ): RouteSnapshot<TEnv> {
206
+ if (snapshot.entries.length > 0) {
207
+ return snapshot;
208
+ }
209
+
210
+ const { entries, cacheScope } = buildEntriesAndCacheScope(
211
+ snapshot.manifestEntry,
212
+ );
213
+ return { ...snapshot, entries, cacheScope };
214
+ }
215
+
216
+ /**
217
+ * Materialize the entry chain and derive the merged cache scope.
218
+ * Shared by resolveRoute (non-lite) and ensureFullRouteSnapshot.
219
+ */
220
+ function buildEntriesAndCacheScope(manifestEntry: EntryData): {
221
+ entries: EntryData[];
222
+ cacheScope: CacheScope | null;
223
+ } {
224
+ const entries = [...traverseBack(manifestEntry)];
225
+ let cacheScope: CacheScope | null = null;
226
+ for (const entry of entries) {
227
+ if (entry.cache) {
228
+ cacheScope = createCacheScope(entry.cache, cacheScope);
229
+ }
230
+ }
231
+ return { entries, cacheScope };
232
+ }
233
+
234
+ /**
235
+ * Test helper: create a RouteSnapshot with sensible defaults and overrides.
236
+ */
237
+ export function createRouteSnapshot<TEnv = any>(
238
+ overrides?: Partial<RouteSnapshot<TEnv>>,
239
+ ): RouteSnapshot<TEnv> {
240
+ return {
241
+ matched: {
242
+ entry: {} as any,
243
+ routeKey: "test",
244
+ params: {},
245
+ } as RouteMatchResult<TEnv>,
246
+ manifestEntry: { type: "route", shortCode: "R0", parent: null } as any,
247
+ entries: [],
248
+ routeKey: "test",
249
+ localRouteName: "test",
250
+ params: {},
251
+ routeMiddleware: [],
252
+ cacheScope: null,
253
+ isPassthrough: false,
254
+ ...overrides,
255
+ };
256
+ }
@@ -19,6 +19,7 @@ import type {
19
19
  } from "../types.js";
20
20
  import type { RouteMatchResult } from "./pattern-matching.js";
21
21
  import type { TelemetrySink } from "./telemetry.js";
22
+ import type { ResolveSegmentOptions } from "./segment-resolution.js";
22
23
 
23
24
  /**
24
25
  * Revalidation context passed to segment resolution
@@ -54,10 +55,10 @@ export interface InterceptResult {
54
55
  * Instead of passing 20+ parameters, middleware calls getRouterContext() to access them.
55
56
  */
56
57
  export interface RouterContext<TEnv = any> {
57
- // Route matching
58
- findMatch: (pathname: string) => RouteMatchResult | null;
58
+ findMatch: (
59
+ pathname: string,
60
+ ) => RouteMatchResult | null | Promise<RouteMatchResult | null>;
59
61
 
60
- // Manifest loading
61
62
  loadManifest: (
62
63
  entry: any,
63
64
  routeKey: string,
@@ -66,10 +67,8 @@ export interface RouterContext<TEnv = any> {
66
67
  isSSR?: boolean,
67
68
  ) => Promise<EntryData>;
68
69
 
69
- // Entry traversal
70
70
  traverseBack: (entry: EntryData) => Generator<EntryData>;
71
71
 
72
- // Handler context creation
73
72
  createHandlerContext: (
74
73
  params: Record<string, string>,
75
74
  request: Request,
@@ -83,7 +82,6 @@ export interface RouterContext<TEnv = any> {
83
82
  isPassthroughRoute?: boolean,
84
83
  ) => HandlerContext<any, TEnv>;
85
84
 
86
- // Loader setup
87
85
  setupLoaderAccess: (
88
86
  ctx: HandlerContext<any, TEnv>,
89
87
  loaderPromises: Map<string, Promise<any>>,
@@ -94,7 +92,6 @@ export interface RouterContext<TEnv = any> {
94
92
  loaderPromises: Map<string, Promise<any>>,
95
93
  ) => void;
96
94
 
97
- // Context access
98
95
  getContext: () => {
99
96
  getOrCreateStore: (key: string) => any;
100
97
  runWithStore: <T>(
@@ -105,16 +102,13 @@ export interface RouterContext<TEnv = any> {
105
102
  ) => T;
106
103
  };
107
104
 
108
- // Metrics
109
105
  getMetricsStore: () => MetricsStore | undefined;
110
106
 
111
- // Cache
112
107
  createCacheScope: (
113
108
  cacheConfig: any,
114
109
  parent: CacheScope | null,
115
110
  ) => CacheScope | null;
116
111
 
117
- // Intercept detection
118
112
  findInterceptForRoute: (
119
113
  routeKey: string,
120
114
  parentEntry: EntryData | null,
@@ -122,7 +116,6 @@ export interface RouterContext<TEnv = any> {
122
116
  isAction: boolean,
123
117
  ) => InterceptResult | null;
124
118
 
125
- // Segment resolution (with revalidation)
126
119
  resolveAllSegmentsWithRevalidation: (
127
120
  entries: EntryData[],
128
121
  routeKey: string,
@@ -133,7 +126,6 @@ export interface RouterContext<TEnv = any> {
133
126
  request: Request,
134
127
  prevUrl: URL,
135
128
  nextUrl: URL,
136
- loaderPromises: Map<string, Promise<any>>,
137
129
  actionContext: any | undefined,
138
130
  interceptResult: InterceptResult | null,
139
131
  localRouteName: string,
@@ -164,14 +156,13 @@ export interface RouterContext<TEnv = any> {
164
156
  handlerContext: HandlerContext<any, TEnv>,
165
157
  belongsToRoute: boolean,
166
158
  revalidationContext?: RevalidationContext,
159
+ options?: { skipMiddleware?: boolean },
167
160
  ) => Promise<ResolvedSegment[]>;
168
161
 
169
- // Collect with markers
170
162
  collectWithMarkers?: <T>(
171
163
  gen: AsyncGenerator<T | { __type: "id"; id: string }>,
172
164
  ) => Promise<{ items: T[]; matchedIds: string[] }>;
173
165
 
174
- // Revalidation evaluation
175
166
  evaluateRevalidation: (params: {
176
167
  segment: ResolvedSegment;
177
168
  prevParams: Record<string, string>;
@@ -195,7 +186,6 @@ export interface RouterContext<TEnv = any> {
195
186
  | "intercept-loader";
196
187
  }) => Promise<boolean>;
197
188
 
198
- // Request context
199
189
  getRequestContext: () =>
200
190
  | {
201
191
  waitUntil: (fn: () => Promise<void>) => void;
@@ -203,17 +193,15 @@ export interface RouterContext<TEnv = any> {
203
193
  }
204
194
  | undefined;
205
195
 
206
- // Simple segment resolution (without revalidation - for full match)
207
196
  resolveAllSegments: (
208
197
  entries: EntryData[],
209
198
  routeKey: string,
210
199
  params: Record<string, string>,
211
200
  handlerContext: HandlerContext<any, TEnv>,
212
201
  loaderPromises: Map<string, Promise<any>>,
213
- options?: { skipLoaders?: boolean },
202
+ options?: ResolveSegmentOptions,
214
203
  ) => Promise<ResolvedSegment[]>;
215
204
 
216
- // Generator-based simple resolution
217
205
  resolveAllSegmentsGenerator?: (
218
206
  entries: EntryData[],
219
207
  routeKey: string,
@@ -222,21 +210,17 @@ export interface RouterContext<TEnv = any> {
222
210
  loaderPromises: Map<string, Promise<any>>,
223
211
  ) => AsyncGenerator<ResolvedSegment | { __type: "id"; id: string }>;
224
212
 
225
- // Collect segments from generator
226
213
  collectSegmentsFromGenerator?: <T>(
227
214
  gen: AsyncGenerator<T | { __type: "id"; id: string }>,
228
215
  ) => Promise<T[]>;
229
216
 
230
- // Handle store
231
217
  createHandleStore: () => any;
232
218
 
233
- // Loaders-only resolution (for full match cache hit - no revalidation)
234
219
  resolveLoadersOnly?: (
235
220
  entries: EntryData[],
236
221
  handlerContext: HandlerContext<any, TEnv>,
237
222
  ) => Promise<ResolvedSegment[]>;
238
223
 
239
- // Loaders-only resolution (for cache hit scenarios)
240
224
  resolveLoadersOnlyWithRevalidation?: (
241
225
  entries: EntryData[],
242
226
  handlerContext: HandlerContext<any, TEnv>,
@@ -258,10 +242,8 @@ export interface RouterContext<TEnv = any> {
258
242
  // Telemetry sink (optional, no-op when undefined)
259
243
  telemetry?: TelemetrySink;
260
244
 
261
- // Request ID for telemetry span correlation (set per-request in match handlers)
262
245
  requestId?: string;
263
246
 
264
- // Intercept loaders only (for cache hit + intercept scenarios)
265
247
  resolveInterceptLoadersOnly?: (
266
248
  intercept: InterceptEntry,
267
249
  entry: EntryData,
@@ -284,7 +266,6 @@ export interface RouterContext<TEnv = any> {
284
266
  } | null>;
285
267
  }
286
268
 
287
- // AsyncLocalStorage instance for router context
288
269
  const routerContext = new AsyncLocalStorage<RouterContext<any>>();
289
270
 
290
271
  /**
@@ -308,10 +289,6 @@ export function getRouterContext<TEnv = any>(): RouterContext<TEnv> {
308
289
  *
309
290
  * All async code within fn() can call getRouterContext() to access router closures.
310
291
  * This works across async boundaries thanks to AsyncLocalStorage.
311
- *
312
- * @param deps Router dependencies to make available
313
- * @param fn Function to run with dependencies available
314
- * @returns Result of fn()
315
292
  */
316
293
  export function runWithRouterContext<T, TEnv = any>(
317
294
  deps: RouterContext<TEnv>,