@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327

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 (440) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +301 -797
  3. package/dist/bin/rango.js +603 -145
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +3750 -1160
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +96 -24
  8. package/skills/api-client/SKILL.md +211 -0
  9. package/skills/breadcrumbs/SKILL.md +85 -6
  10. package/skills/bundle-analysis/SKILL.md +159 -0
  11. package/skills/cache-guide/SKILL.md +228 -33
  12. package/skills/caching/SKILL.md +336 -19
  13. package/skills/catalog.json +271 -0
  14. package/skills/comparison/SKILL.md +50 -0
  15. package/skills/comparison/agents/openai.yaml +4 -0
  16. package/skills/comparison/references/framework-comparison.md +837 -0
  17. package/skills/composability/SKILL.md +110 -4
  18. package/skills/css/SKILL.md +76 -0
  19. package/skills/debug-manifest/SKILL.md +5 -3
  20. package/skills/defer-hydration/SKILL.md +235 -0
  21. package/skills/document-cache/SKILL.md +87 -56
  22. package/skills/fonts/SKILL.md +1 -1
  23. package/skills/handler-use/SKILL.md +12 -10
  24. package/skills/hooks/SKILL.md +73 -691
  25. package/skills/hooks/data.md +273 -0
  26. package/skills/hooks/handle-and-actions.md +103 -0
  27. package/skills/hooks/navigation.md +110 -0
  28. package/skills/hooks/outlets.md +41 -0
  29. package/skills/hooks/state.md +228 -0
  30. package/skills/hooks/urls.md +135 -0
  31. package/skills/host-router/SKILL.md +129 -27
  32. package/skills/i18n/SKILL.md +276 -0
  33. package/skills/intercept/SKILL.md +75 -19
  34. package/skills/layout/SKILL.md +40 -19
  35. package/skills/links/SKILL.md +247 -17
  36. package/skills/loader/SKILL.md +248 -10
  37. package/skills/middleware/SKILL.md +25 -13
  38. package/skills/migrate-nextjs/SKILL.md +205 -20
  39. package/skills/migrate-react-router/SKILL.md +59 -670
  40. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  41. package/skills/migrate-react-router/component-migration.md +196 -0
  42. package/skills/migrate-react-router/data-and-actions.md +225 -0
  43. package/skills/migrate-react-router/route-mapping.md +271 -0
  44. package/skills/mime-routes/SKILL.md +29 -2
  45. package/skills/observability/SKILL.md +202 -0
  46. package/skills/parallel/SKILL.md +40 -10
  47. package/skills/ppr/SKILL.md +616 -0
  48. package/skills/prerender/SKILL.md +72 -60
  49. package/skills/rango/SKILL.md +318 -26
  50. package/skills/react-compiler/SKILL.md +168 -0
  51. package/skills/response-routes/SKILL.md +138 -49
  52. package/skills/route/SKILL.md +117 -9
  53. package/skills/router-setup/SKILL.md +44 -9
  54. package/skills/scripts/SKILL.md +179 -0
  55. package/skills/server-actions/SKILL.md +776 -0
  56. package/skills/shell-manifest/SKILL.md +185 -0
  57. package/skills/streams-and-websockets/SKILL.md +283 -0
  58. package/skills/tailwind/SKILL.md +28 -4
  59. package/skills/testing/SKILL.md +130 -0
  60. package/skills/testing/bindings.md +103 -0
  61. package/skills/testing/cache-prerender.md +127 -0
  62. package/skills/testing/client-components.md +124 -0
  63. package/skills/testing/e2e-parity.md +125 -0
  64. package/skills/testing/flight.md +91 -0
  65. package/skills/testing/handles.md +131 -0
  66. package/skills/testing/loader.md +128 -0
  67. package/skills/testing/middleware.md +99 -0
  68. package/skills/testing/render-handler.md +122 -0
  69. package/skills/testing/response-routes.md +95 -0
  70. package/skills/testing/reverse-and-types.md +85 -0
  71. package/skills/testing/server-actions.md +107 -0
  72. package/skills/testing/server-tree.md +128 -0
  73. package/skills/testing/setup.md +123 -0
  74. package/skills/theme/SKILL.md +1 -1
  75. package/skills/typesafety/SKILL.md +45 -626
  76. package/skills/typesafety/env-and-bindings.md +254 -0
  77. package/skills/typesafety/generated-files-and-cli.md +335 -0
  78. package/skills/typesafety/params-and-search.md +153 -0
  79. package/skills/typesafety/route-types.md +209 -0
  80. package/skills/use-cache/SKILL.md +74 -15
  81. package/skills/vercel/SKILL.md +128 -0
  82. package/skills/view-transitions/SKILL.md +337 -0
  83. package/src/__augment-tests__/augment.ts +81 -0
  84. package/src/__augment-tests__/augmented.check.ts +116 -0
  85. package/src/__internal.ts +0 -65
  86. package/src/browser/action-coordinator.ts +53 -36
  87. package/src/browser/action-fence.ts +47 -0
  88. package/src/browser/app-shell.ts +39 -0
  89. package/src/browser/connection-warmup.ts +134 -0
  90. package/src/browser/cookie-name.ts +140 -0
  91. package/src/browser/event-controller.ts +252 -158
  92. package/src/browser/history-state.ts +21 -0
  93. package/src/browser/index.ts +3 -3
  94. package/src/browser/invalidate-client-cache.ts +52 -0
  95. package/src/browser/logging.ts +28 -0
  96. package/src/browser/merge-segment-loaders.ts +6 -4
  97. package/src/browser/navigation-bridge.ts +94 -25
  98. package/src/browser/navigation-client.ts +144 -79
  99. package/src/browser/navigation-store-handle.ts +38 -0
  100. package/src/browser/navigation-store.ts +161 -73
  101. package/src/browser/navigation-transaction.ts +9 -59
  102. package/src/browser/network-error-handler.ts +34 -7
  103. package/src/browser/partial-update.ts +183 -144
  104. package/src/browser/prefetch/cache.ts +242 -77
  105. package/src/browser/prefetch/fetch.ts +325 -69
  106. package/src/browser/prefetch/queue.ts +61 -12
  107. package/src/browser/rango-state.ts +158 -76
  108. package/src/browser/react/Link.tsx +58 -20
  109. package/src/browser/react/NavigationProvider.tsx +202 -120
  110. package/src/browser/react/ScrollRestoration.tsx +10 -6
  111. package/src/browser/react/filter-segment-order.ts +66 -7
  112. package/src/browser/react/index.ts +0 -48
  113. package/src/browser/react/location-state-shared.ts +178 -8
  114. package/src/browser/react/location-state.ts +39 -14
  115. package/src/browser/react/use-action.ts +6 -15
  116. package/src/browser/react/use-handle.ts +17 -14
  117. package/src/browser/react/use-href.tsx +8 -1
  118. package/src/browser/react/use-link-status.ts +33 -8
  119. package/src/browser/react/use-navigation.ts +32 -7
  120. package/src/browser/react/use-params.ts +20 -10
  121. package/src/browser/react/use-reverse.ts +106 -0
  122. package/src/browser/react/use-router.ts +25 -3
  123. package/src/browser/react/use-search-params.ts +0 -5
  124. package/src/browser/react/use-segments.ts +11 -21
  125. package/src/browser/response-adapter.ts +99 -8
  126. package/src/browser/rsc-router.tsx +145 -28
  127. package/src/browser/scroll-restoration.ts +37 -22
  128. package/src/browser/segment-reconciler.ts +31 -21
  129. package/src/browser/segment-structure-assert.ts +2 -2
  130. package/src/browser/server-action-bridge.ts +236 -65
  131. package/src/browser/types.ts +102 -9
  132. package/src/browser/validate-redirect-origin.ts +43 -16
  133. package/src/build/collect-fallback-refs.ts +107 -0
  134. package/src/build/generate-manifest.ts +203 -154
  135. package/src/build/generate-route-types.ts +3 -1
  136. package/src/build/index.ts +11 -3
  137. package/src/build/prefix-tree-utils.ts +123 -0
  138. package/src/build/route-trie.ts +152 -21
  139. package/src/build/route-types/ast-route-extraction.ts +15 -8
  140. package/src/build/route-types/codegen.ts +16 -5
  141. package/src/build/route-types/include-resolution.ts +456 -62
  142. package/src/build/route-types/param-extraction.ts +6 -3
  143. package/src/build/route-types/per-module-writer.ts +22 -6
  144. package/src/build/route-types/router-processing.ts +128 -51
  145. package/src/build/route-types/scan-filter.ts +1 -1
  146. package/src/build/route-types/source-scan.ts +216 -0
  147. package/src/build/runtime-discovery.ts +13 -21
  148. package/src/cache/cache-error.ts +104 -0
  149. package/src/cache/cache-key-utils.ts +58 -13
  150. package/src/cache/cache-policy.ts +108 -34
  151. package/src/cache/cache-runtime.ts +421 -58
  152. package/src/cache/cache-scope.ts +187 -96
  153. package/src/cache/cache-tag.ts +149 -0
  154. package/src/cache/cf/cf-base64.ts +33 -0
  155. package/src/cache/cf/cf-cache-constants.ts +127 -0
  156. package/src/cache/cf/cf-cache-store.ts +2202 -372
  157. package/src/cache/cf/cf-cache-types.ts +349 -0
  158. package/src/cache/cf/cf-kv-utils.ts +46 -0
  159. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  160. package/src/cache/cf/index.ts +6 -16
  161. package/src/cache/document-cache.ts +126 -41
  162. package/src/cache/handle-snapshot.ts +70 -0
  163. package/src/cache/index.ts +23 -20
  164. package/src/cache/memory-segment-store.ts +243 -37
  165. package/src/cache/profile-registry.ts +46 -31
  166. package/src/cache/read-through-swr.ts +56 -12
  167. package/src/cache/segment-codec.ts +13 -21
  168. package/src/cache/shell-snapshot.ts +417 -0
  169. package/src/cache/tag-invalidation.ts +230 -0
  170. package/src/cache/types.ts +180 -99
  171. package/src/cache/vercel/index.ts +11 -0
  172. package/src/cache/vercel/vercel-cache-store.ts +1127 -0
  173. package/src/client.rsc.tsx +41 -21
  174. package/src/client.tsx +33 -61
  175. package/src/cloudflare/index.ts +11 -0
  176. package/src/cloudflare/tracing.ts +108 -0
  177. package/src/component-utils.ts +19 -0
  178. package/src/components/DefaultDocument.tsx +8 -2
  179. package/src/context-var.ts +18 -6
  180. package/src/decode-loader-results.ts +52 -0
  181. package/src/defer.ts +185 -0
  182. package/src/deps/ssr.ts +0 -1
  183. package/src/encode-kv.ts +49 -0
  184. package/src/errors.ts +30 -4
  185. package/src/escape-script.ts +52 -0
  186. package/src/handle.ts +67 -37
  187. package/src/handles/MetaTags.tsx +24 -53
  188. package/src/handles/Scripts.tsx +183 -0
  189. package/src/handles/breadcrumbs.ts +35 -8
  190. package/src/handles/deferred-resolution.ts +127 -0
  191. package/src/handles/is-thenable.ts +18 -0
  192. package/src/handles/meta.ts +14 -40
  193. package/src/handles/script.ts +244 -0
  194. package/src/host/cookie-handler.ts +9 -60
  195. package/src/host/errors.ts +13 -22
  196. package/src/host/index.ts +9 -2
  197. package/src/host/pattern-matcher.ts +23 -52
  198. package/src/host/router.ts +107 -99
  199. package/src/host/testing.ts +40 -27
  200. package/src/host/types.ts +37 -4
  201. package/src/host/utils.ts +1 -1
  202. package/src/href-client.ts +137 -22
  203. package/src/index.rsc.ts +97 -12
  204. package/src/index.ts +98 -14
  205. package/src/internal-debug.ts +11 -10
  206. package/src/loader-store.ts +500 -0
  207. package/src/loader.rsc.ts +20 -13
  208. package/src/loader.ts +12 -11
  209. package/src/missing-id-error.ts +68 -0
  210. package/src/outlet-context.ts +1 -1
  211. package/src/outlet-provider.tsx +1 -5
  212. package/src/prerender/param-hash.ts +16 -16
  213. package/src/prerender/store.ts +32 -37
  214. package/src/prerender.ts +78 -10
  215. package/src/redirect-origin.ts +114 -0
  216. package/src/regex-escape.ts +8 -0
  217. package/src/render-error-thrower.tsx +20 -0
  218. package/src/response-utils.ts +62 -0
  219. package/src/reverse.ts +65 -39
  220. package/src/root-error-boundary.tsx +1 -19
  221. package/src/route-content-wrapper.tsx +19 -77
  222. package/src/route-definition/dsl-helpers.ts +304 -309
  223. package/src/route-definition/helper-factories.ts +28 -140
  224. package/src/route-definition/helpers-types.ts +87 -59
  225. package/src/route-definition/index.ts +1 -2
  226. package/src/route-definition/redirect.ts +44 -11
  227. package/src/route-definition/resolve-handler-use.ts +12 -1
  228. package/src/route-definition/use-item-types.ts +29 -0
  229. package/src/route-map-builder.ts +41 -20
  230. package/src/route-types.ts +19 -46
  231. package/src/router/basename.ts +14 -0
  232. package/src/router/content-negotiation.ts +73 -25
  233. package/src/router/error-handling.ts +45 -18
  234. package/src/router/find-match.ts +129 -30
  235. package/src/router/handler-context.ts +27 -42
  236. package/src/router/instrument.ts +355 -0
  237. package/src/router/intercept-resolution.ts +39 -20
  238. package/src/router/lazy-includes.ts +82 -59
  239. package/src/router/loader-resolution.ts +167 -72
  240. package/src/router/logging.ts +0 -6
  241. package/src/router/manifest.ts +74 -40
  242. package/src/router/match-api.ts +80 -55
  243. package/src/router/match-context.ts +0 -22
  244. package/src/router/match-handlers.ts +211 -165
  245. package/src/router/match-middleware/background-revalidation.ts +40 -24
  246. package/src/router/match-middleware/cache-lookup.ts +159 -285
  247. package/src/router/match-middleware/cache-store.ts +64 -52
  248. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  249. package/src/router/match-middleware/segment-resolution.ts +0 -22
  250. package/src/router/match-pipelines.ts +1 -42
  251. package/src/router/match-result.ts +69 -79
  252. package/src/router/metrics.ts +0 -34
  253. package/src/router/middleware-types.ts +7 -134
  254. package/src/router/middleware.ts +298 -172
  255. package/src/router/navigation-snapshot.ts +7 -56
  256. package/src/router/params-util.ts +23 -0
  257. package/src/router/parse-pattern.ts +115 -0
  258. package/src/router/pattern-matching.ts +181 -150
  259. package/src/router/prefetch-cache-ttl.ts +51 -0
  260. package/src/router/prefetch-limits.ts +37 -0
  261. package/src/router/prerender-match.ts +112 -67
  262. package/src/router/preview-match.ts +6 -2
  263. package/src/router/request-classification.ts +50 -69
  264. package/src/router/revalidation.ts +123 -73
  265. package/src/router/route-snapshot.ts +14 -3
  266. package/src/router/router-context.ts +6 -29
  267. package/src/router/router-interfaces.ts +115 -36
  268. package/src/router/router-options.ts +166 -5
  269. package/src/router/router-registry.ts +2 -5
  270. package/src/router/segment-resolution/fresh.ts +131 -86
  271. package/src/router/segment-resolution/helpers.ts +86 -6
  272. package/src/router/segment-resolution/loader-cache.ts +139 -39
  273. package/src/router/segment-resolution/loader-mask.ts +67 -0
  274. package/src/router/segment-resolution/loader-snapshot.ts +251 -0
  275. package/src/router/segment-resolution/revalidation.ts +272 -320
  276. package/src/router/segment-resolution/static-store.ts +19 -5
  277. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  278. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  279. package/src/router/segment-resolution.ts +5 -1
  280. package/src/router/segment-wrappers.ts +6 -5
  281. package/src/router/state-cookie-name.ts +33 -0
  282. package/src/router/substitute-pattern-params.ts +75 -0
  283. package/src/router/telemetry-otel.ts +160 -200
  284. package/src/router/telemetry.ts +105 -20
  285. package/src/router/timeout.ts +0 -20
  286. package/src/router/tracing.ts +215 -0
  287. package/src/router/trie-matching.ts +171 -59
  288. package/src/router/types.ts +9 -63
  289. package/src/router/url-params.ts +57 -0
  290. package/src/router.ts +157 -71
  291. package/src/rsc/full-payload.ts +70 -0
  292. package/src/rsc/handler-context.ts +3 -2
  293. package/src/rsc/handler.ts +291 -217
  294. package/src/rsc/helpers.ts +168 -46
  295. package/src/rsc/index.ts +2 -5
  296. package/src/rsc/json-route-result.ts +38 -0
  297. package/src/rsc/loader-fetch.ts +114 -38
  298. package/src/rsc/manifest-init.ts +29 -42
  299. package/src/rsc/nonce.ts +10 -1
  300. package/src/rsc/origin-guard.ts +39 -25
  301. package/src/rsc/progressive-enhancement.ts +124 -13
  302. package/src/rsc/redirect-guard.ts +100 -0
  303. package/src/rsc/response-cache-serve.ts +238 -0
  304. package/src/rsc/response-error.ts +79 -12
  305. package/src/rsc/response-route-handler.ts +99 -189
  306. package/src/rsc/rsc-rendering.ts +421 -76
  307. package/src/rsc/runtime-warnings.ts +23 -10
  308. package/src/rsc/server-action.ts +282 -116
  309. package/src/rsc/shell-capture.ts +1158 -0
  310. package/src/rsc/shell-serve.ts +150 -0
  311. package/src/rsc/ssr-setup.ts +16 -0
  312. package/src/rsc/transition-gate.ts +89 -0
  313. package/src/rsc/types.ts +53 -5
  314. package/src/runtime-env.ts +18 -0
  315. package/src/search-params.ts +35 -30
  316. package/src/segment-loader-promise.ts +49 -4
  317. package/src/segment-system.tsx +350 -149
  318. package/src/serialize.ts +243 -0
  319. package/src/server/context.ts +208 -51
  320. package/src/server/cookie-parse.ts +32 -0
  321. package/src/server/cookie-store.ts +152 -5
  322. package/src/server/handle-store.ts +21 -38
  323. package/src/server/loader-registry.ts +33 -42
  324. package/src/server/request-context.ts +395 -176
  325. package/src/ssr/index.tsx +458 -178
  326. package/src/ssr/ssr-root.tsx +228 -0
  327. package/src/static-handler.ts +10 -13
  328. package/src/testing/cache-status.ts +162 -0
  329. package/src/testing/collect-handle.ts +46 -0
  330. package/src/testing/dispatch.ts +813 -0
  331. package/src/testing/dom.entry.ts +22 -0
  332. package/src/testing/e2e/fixture.ts +188 -0
  333. package/src/testing/e2e/index.ts +128 -0
  334. package/src/testing/e2e/matchers.ts +35 -0
  335. package/src/testing/e2e/page-helpers.ts +272 -0
  336. package/src/testing/e2e/parity.ts +387 -0
  337. package/src/testing/e2e/server.ts +195 -0
  338. package/src/testing/flight-matchers.ts +97 -0
  339. package/src/testing/flight-normalize.ts +11 -0
  340. package/src/testing/flight-runtime.d.ts +57 -0
  341. package/src/testing/flight-tree.ts +682 -0
  342. package/src/testing/flight.entry.ts +52 -0
  343. package/src/testing/flight.ts +257 -0
  344. package/src/testing/generated-routes.ts +199 -0
  345. package/src/testing/index.ts +105 -0
  346. package/src/testing/internal/context.ts +371 -0
  347. package/src/testing/internal/flight-client-globals.ts +30 -0
  348. package/src/testing/internal/seed-vars.ts +54 -0
  349. package/src/testing/render-handler.ts +357 -0
  350. package/src/testing/render-route.tsx +584 -0
  351. package/src/testing/run-loader.ts +385 -0
  352. package/src/testing/run-middleware.ts +205 -0
  353. package/src/testing/run-transition-when.ts +164 -0
  354. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  355. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  356. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  357. package/src/testing/vitest-stubs/version.ts +5 -0
  358. package/src/testing/vitest.ts +305 -0
  359. package/src/theme/ThemeProvider.tsx +56 -84
  360. package/src/theme/ThemeScript.tsx +7 -9
  361. package/src/theme/constants.ts +52 -13
  362. package/src/theme/index.ts +0 -7
  363. package/src/theme/theme-context.ts +1 -5
  364. package/src/theme/theme-script.ts +22 -21
  365. package/src/theme/use-theme.ts +0 -3
  366. package/src/types/boundaries.ts +0 -35
  367. package/src/types/cache-types.ts +13 -4
  368. package/src/types/error-types.ts +30 -90
  369. package/src/types/global-namespace.ts +54 -41
  370. package/src/types/handler-context.ts +110 -62
  371. package/src/types/index.ts +3 -10
  372. package/src/types/loader-types.ts +11 -9
  373. package/src/types/request-scope.ts +112 -0
  374. package/src/types/route-config.ts +20 -52
  375. package/src/types/route-entry.ts +0 -6
  376. package/src/types/segments.ts +135 -14
  377. package/src/urls/include-helper.ts +19 -64
  378. package/src/urls/include-provider.ts +71 -0
  379. package/src/urls/index.ts +2 -11
  380. package/src/urls/path-helper-types.ts +63 -17
  381. package/src/urls/path-helper.ts +22 -106
  382. package/src/urls/pattern-types.ts +72 -19
  383. package/src/urls/response-types.ts +22 -29
  384. package/src/urls/type-extraction.ts +98 -154
  385. package/src/urls/urls-function.ts +1 -19
  386. package/src/use-loader.tsx +292 -107
  387. package/src/vercel/index.ts +11 -0
  388. package/src/vercel/tracing.ts +88 -0
  389. package/src/vite/debug.ts +185 -0
  390. package/src/vite/discovery/bundle-postprocess.ts +8 -7
  391. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  392. package/src/vite/discovery/discover-routers.ts +127 -86
  393. package/src/vite/discovery/discovery-errors.ts +255 -0
  394. package/src/vite/discovery/gate-state.ts +171 -0
  395. package/src/vite/discovery/prerender-collection.ts +96 -68
  396. package/src/vite/discovery/route-types-writer.ts +40 -84
  397. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  398. package/src/vite/discovery/state.ts +45 -1
  399. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  400. package/src/vite/index.ts +4 -0
  401. package/src/vite/inject-client-debug.ts +88 -0
  402. package/src/vite/plugin-types.ts +210 -10
  403. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  404. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  405. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  406. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  407. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  408. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  409. package/src/vite/plugins/expose-action-id.ts +48 -95
  410. package/src/vite/plugins/expose-id-utils.ts +88 -55
  411. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  412. package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
  413. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  414. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  415. package/src/vite/plugins/expose-internal-ids.ts +505 -486
  416. package/src/vite/plugins/performance-tracks.ts +26 -25
  417. package/src/vite/plugins/refresh-cmd.ts +1 -1
  418. package/src/vite/plugins/use-cache-transform.ts +73 -83
  419. package/src/vite/plugins/vercel-output.ts +384 -0
  420. package/src/vite/plugins/version-injector.ts +40 -29
  421. package/src/vite/plugins/version-plugin.ts +37 -40
  422. package/src/vite/plugins/virtual-entries.ts +138 -27
  423. package/src/vite/rango.ts +236 -138
  424. package/src/vite/router-discovery.ts +927 -136
  425. package/src/vite/utils/ast-handler-extract.ts +26 -35
  426. package/src/vite/utils/banner.ts +1 -1
  427. package/src/vite/utils/bundle-analysis.ts +10 -15
  428. package/src/vite/utils/client-chunks.ts +184 -0
  429. package/src/vite/utils/directive-prologue.ts +40 -0
  430. package/src/vite/utils/forward-user-plugins.ts +171 -0
  431. package/src/vite/utils/manifest-utils.ts +4 -59
  432. package/src/vite/utils/package-resolution.ts +20 -52
  433. package/src/vite/utils/prerender-utils.ts +71 -43
  434. package/src/vite/utils/shared-utils.ts +142 -43
  435. package/src/browser/action-response-classifier.ts +0 -99
  436. package/src/browser/react/use-client-cache.ts +0 -58
  437. package/src/browser/shallow.ts +0 -40
  438. package/src/handles/index.ts +0 -7
  439. package/src/network-error-thrower.tsx +0 -23
  440. package/src/router/middleware-cookies.ts +0 -55
@@ -1,633 +1,52 @@
1
1
  ---
2
2
  name: typesafety
3
- description: Set up type-safe routes, params, and environment types in @rangojs/router
3
+ description: Set up type-safe routes, params, and environment types in @rangojs/router. Use when route or search params aren't typed, TypeScript can't infer a loader's return type, or wiring up typed environment bindings.
4
4
  argument-hint: [setup]
5
5
  ---
6
6
 
7
7
  # Type Safety Setup
8
8
 
9
- @rangojs/router provides end-to-end type safety for routes, parameters, and environment.
10
-
11
- ## Router Setup
12
-
13
- ```typescript
14
- // router.tsx
15
- import { createRouter } from "@rangojs/router";
16
- import { urlpatterns } from "./urls";
17
-
18
- const router = createRouter<AppBindings>({
19
- document: Document,
20
- }).routes(urlpatterns);
21
-
22
- // Server-side named-route reverse (type-safe via routeMap)
23
- export const reverse = router.reverse;
24
-
25
- export default router;
26
- ```
27
-
28
- ### Which global type should I use?
29
-
30
- Use the generated route map by default. Manual `RegisteredRoutes` augmentation
31
- is only needed when you want the richer `typeof router.routeMap` shape
32
- available globally.
33
-
34
- - `GeneratedRouteMap` auto-registered by `router.named-routes.gen.ts`
35
- Use for `Handler<"name">`, `Prerender<"name">`, server `ctx.reverse()`,
36
- and named-route param/search inference.
37
- - `typeof router.routeMap`the real merged route map from your router
38
- instance, including response-route metadata such as `{ path, response }`.
39
- - `RegisteredRoutes` manual global hook for exposing `typeof router.routeMap`
40
- to utilities like `href()`, `ValidPaths`, and `PathResponse`.
41
-
42
- Recommended setup:
43
-
44
- ```typescript
45
- // router.tsx
46
- import { createRouter } from "@rangojs/router";
47
- import { urlpatterns } from "./urls";
48
- import type { AppBindings, AppVars } from "./env";
49
-
50
- export const router = createRouter<AppBindings>({}).routes(urlpatterns);
51
-
52
- declare global {
53
- namespace RSCRouter {
54
- interface Env extends AppBindings {}
55
- interface Vars extends AppVars {}
56
- interface RegisteredRoutes extends typeof router.routeMap {}
57
- }
58
- }
59
- ```
60
-
61
- ## Route Definition with Type-Safe Names
62
-
63
- ```typescript
64
- // urls.tsx
65
- import { urls } from "@rangojs/router";
66
-
67
- export const urlpatterns = urls(({ path, layout }) => [
68
- path("/", HomePage, { name: "home" }),
69
- path("/products", ProductsPage, { name: "products" }),
70
- path("/product/:slug", ProductPage, { name: "product" }),
71
- path("/cart", CartPage, { name: "cart" }),
72
- path("/checkout/:step?", CheckoutPage, { name: "checkout" }),
73
- ]);
74
-
75
- // Route names are inferred from the { name } option
76
- ```
77
-
78
- ## Type-Safe href()
79
-
80
- ### Server: ctx.reverse with route names
81
-
82
- In route handlers, `ctx.reverse()` uses two namespaces:
83
-
84
- - **`.name`** — local route, resolved within the current `include()` scope
85
- - **`name`** — global route, from the named-routes definition
86
-
87
- ```typescript
88
- import type { Handler } from "@rangojs/router";
89
-
90
- export const ProductHandler: Handler<"shop.product"> = (ctx) => {
91
- ctx.reverse(".cart"); // Local: /shop/cart
92
- ctx.reverse(".product", { slug: "widget" }); // Local: /shop/product/widget
93
- ctx.reverse("blog.post", { slug: "1" }); // Global: /blog/1
94
- };
95
- ```
96
-
97
- For type-safe local names, generate a route types file with `npx rango generate urls/shop.tsx`
98
- and pass it as the second generic to `Handler` or `Prerender`:
99
-
100
- ```typescript
101
- import type { Handler } from "@rangojs/router";
102
- import type { routes } from "./shop.gen.js";
103
-
104
- export const ProductHandler: Handler<"shop.product", routes> = (ctx) => {
105
- ctx.reverse(".cart"); // Type-safe local name
106
- ctx.reverse(".product", { slug: "widget" }); // Type-safe local with params
107
- ctx.reverse("blog.post", { slug: "hi" }); // Type-safe global name
108
- };
109
- ```
110
-
111
- ### Client: href + useHref
112
-
113
- On the client, `href()` validates paths against registered route patterns at compile time:
114
-
115
- ```typescript
116
- "use client";
117
- import { href, useHref, Link } from "@rangojs/router/client";
118
-
119
- // href() validates absolute paths via PatternToPath types
120
- href("/about"); // Valid path
121
- href("/blog/hello"); // Matches /blog/:slug
122
-
123
- // useHref() auto-prefixes with include() mount
124
- function ShopNav() {
125
- const href = useHref();
126
- return <Link to={href("/cart")}>Cart</Link>; // "/shop/cart"
127
- }
128
- ```
129
-
130
- `href()` and path-based response utilities read from `RegisteredRoutes`, so if
131
- you want them typed globally you should augment:
132
-
133
- ```typescript
134
- declare global {
135
- namespace RSCRouter {
136
- interface RegisteredRoutes extends typeof router.routeMap {}
137
- }
138
- }
139
- ```
140
-
141
- See `/links` for full URL generation guide.
142
-
143
- ## Environment Type Setup
144
-
145
- Define your app's environment for type-safe bindings and variables:
146
-
147
- ```typescript
148
- // env.ts
149
-
150
- // Cloudflare bindings — passed as TEnv to createRouter<TEnv>()
151
- export interface AppBindings {
152
- DB: D1Database;
153
- KV: KVNamespace;
154
- CACHE: KVNamespace;
155
- AI: Ai;
156
- }
157
-
158
- // Variables set by middleware — declared via module augmentation
159
- export interface AppVariables {
160
- user?: { id: string; email: string; role: string };
161
- requestId?: string;
162
- permissions?: string[];
163
- }
164
- ```
165
-
166
- ### Using Environment Types
167
-
168
- ```typescript
169
- // router.tsx
170
- import type { AppBindings, AppVariables } from "./env";
171
-
172
- const router = createRouter<AppBindings>({
173
- document: Document,
174
- }).routes(urlpatterns);
175
-
176
- // Register bindings and variables globally for implicit typing
177
- declare global {
178
- namespace RSCRouter {
179
- interface Env extends AppBindings {}
180
- interface Vars extends AppVariables {}
181
- }
182
- }
183
-
184
- // middleware - typed via ctx.set / ctx.get
185
- import type { Middleware } from "@rangojs/router";
186
-
187
- export const authMiddleware: Middleware = async (ctx, next) => {
188
- ctx.set("user", {
189
- id: "123",
190
- email: "user@example.com",
191
- role: "admin",
192
- });
193
- await next();
194
- };
195
-
196
- // loaders - typed context
197
- export const UserLoader = createLoader(async (ctx) => {
198
- const db = ctx.env.DB; // D1Database (plain bindings)
199
- const userId = ctx.get("user")?.id; // from RSCRouter.Vars
200
- return db.prepare("SELECT * FROM users WHERE id = ?").bind(userId).first();
201
- });
202
- ```
203
-
204
- ## Global Environment Registration
205
-
206
- Register environment types globally for implicit typing:
207
-
208
- ```typescript
209
- // router.tsx
210
- declare global {
211
- namespace RSCRouter {
212
- interface Env extends AppBindings {}
213
- interface Vars extends AppVariables {}
214
- }
215
- }
216
- ```
217
-
218
- Now handlers have typed context without explicit imports:
219
-
220
- ```typescript
221
- // In loaders
222
- export const DashboardLoader = createLoader(async (ctx) => {
223
- // ctx.env.DB is typed from global RSCRouter.Env
224
- // ctx.get("user") is typed from global RSCRouter.Vars
225
- const user = ctx.get("user");
226
- return { user };
227
- });
228
- ```
229
-
230
- ## Typed Search Params
231
-
232
- Add a `search` schema to `path()` options for type-safe query parameters:
233
-
234
- ```typescript
235
- // Route definition with search schema
236
- path("/search", SearchPage, {
237
- name: "search",
238
- search: { q: "string", page: "number?", sort: "string?" },
239
- });
240
- ```
241
-
242
- ### Handler with typed search params
243
-
244
- `Handler<"name">` automatically resolves route params and search params from the
245
- global `GeneratedRouteMap` (the gen file). No explicit route map import needed:
246
-
247
- ```typescript
248
- // pages/search.tsx
249
- import type { Handler } from "@rangojs/router";
250
-
251
- export const SearchPage: Handler<"search"> = (ctx) => {
252
- // ctx.search is typed: { q: string; page?: number; sort?: string }
253
- const { q, page, sort } = ctx.search;
254
- return <SearchResults q={q} page={page} sort={sort} />;
255
- };
256
- ```
257
-
258
- This avoids circular references because `Handler` defaults to `GeneratedRouteMap`
259
- (from `router.named-routes.gen.ts`) instead of `RegisteredRoutes` (which depends on `router.tsx`).
260
-
261
- You can also pass an explicit route map for per-module isolation (opt-in,
262
- after running `npx rango generate`):
263
-
264
- ```typescript
265
- import type { Handler } from "@rangojs/router";
266
- import type { routes } from "./urls.gen.js";
267
-
268
- export const SearchPage: Handler<"search", routes> = (ctx) => { ... };
269
- ```
270
-
271
- Supported types: `"string"`, `"number"`, `"boolean"`, with `?` suffix for optional.
272
- Values are automatically coerced from query string (e.g., `"2"` becomes `2` for numbers).
273
- Routes without a `search` schema keep the standard `URLSearchParams` behavior.
274
-
275
- ### RouteSearchParams and RouteParams utility types
276
-
277
- Extract typed params by route name for use in component props, return types, or anywhere:
278
-
279
- ```typescript
280
- import type { RouteSearchParams, RouteParams } from "@rangojs/router";
281
-
282
- // RouteSearchParams<"name"> resolves the search schema to a typed object
283
- type SP = RouteSearchParams<"search">;
284
- // { q: string | undefined; page?: number; sort?: string }
285
-
286
- // RouteParams<"name"> resolves URL params from the route pattern
287
- type P = RouteParams<"blogPost">;
288
- // { slug: string }
289
-
290
- // Use in component props
291
- interface SearchResultsProps {
292
- params: RouteSearchParams<"search">;
293
- }
294
- ```
295
-
296
- Both default to the global route map (`RegisteredRoutes` or `GeneratedRouteMap`).
297
- Pass an explicit route map as the second type argument when needed:
298
-
299
- ```typescript
300
- import type { routes } from "./urls.gen.js";
301
-
302
- type SP = RouteSearchParams<"search", routes>;
303
- type P = RouteParams<"blogPost", routes>;
304
- ```
305
-
306
- ### Generated route types
307
-
308
- In the generated `router.named-routes.gen.ts`, routes with search schemas
309
- use `{ path, search }` objects:
310
-
311
- ```typescript
312
- // router.named-routes.gen.ts (auto-generated)
313
- export const NamedRoutes = {
314
- "search.index": {
315
- path: "/search",
316
- search: { q: "string", page: "number?", sort: "string?" },
317
- },
318
- "home.index": "/", // No search schema -> plain string
319
- } as const;
320
- ```
321
-
322
- ## Loader Type Safety
323
-
324
- Loaders have typed return values:
325
-
326
- ```typescript
327
- // loaders/product.ts
328
- export const ProductLoader = createLoader(async (ctx) => {
329
- return {
330
- id: ctx.params.slug,
331
- name: "Widget",
332
- price: 99,
333
- };
334
- });
335
-
336
- // In server component - type is inferred
337
- import { useLoader } from "@rangojs/router/client";
338
-
339
- async function ProductPage() {
340
- const product = await useLoader(ProductLoader);
341
- // product: { id: string; name: string; price: number }
342
- return <h1>{product.name}</h1>;
343
- }
344
-
345
- // In client component - same type
346
- "use client";
347
- import { useLoader } from "@rangojs/router/client";
348
-
349
- function ProductPrice() {
350
- const { data } = useLoader(ProductLoader);
351
- // data: { id: string; name: string; price: number }
352
- const product = data;
353
- return <span>${product.price}</span>;
354
- }
355
- ```
356
-
357
- ## Typed Context Variables
358
-
359
- `createVar<T>()` creates a typed token for `ctx.set()`/`ctx.get()`, making
360
- handler-to-layout data contracts explicit and compile-time verified:
361
-
362
- ```typescript
363
- import { createVar } from "@rangojs/router";
364
-
365
- // Define a typed token (shared between producer and consumer)
366
- interface PaginationData {
367
- current: number;
368
- total: number;
369
- perPage: number;
370
- }
371
- export const Pagination = createVar<PaginationData>();
372
-
373
- // Non-cacheable var — reading inside cache() or "use cache" throws at runtime
374
- const Session = createVar<SessionData>({ cache: false });
375
- ```
376
-
377
- `createVar` accepts an optional options object. The `cache` option (default
378
- `true`) controls whether the var's values can be read inside cache scopes.
379
- Write-level escalation is also supported: `ctx.set(Var, value, { cache: false })`
380
- marks a specific write as non-cacheable even if the var itself is cacheable.
381
- "Least cacheable wins" — if either says `cache: false`, the value throws on
382
- read inside `cache()` or `"use cache"`.
383
-
384
- ### Producer (handler or middleware)
385
-
386
- ```typescript
387
- import { Pagination } from "../vars/pagination.js";
388
-
389
- const ArticleList: Handler<"articles.list"> = async (ctx) => {
390
- ctx.set(Pagination, { // type-checked
391
- current: 1,
392
- total: 10,
393
- perPage: 5,
394
- });
395
- return <Articles />;
396
- };
397
- ```
398
-
399
- ### Consumer (layout, parallel, or any context with get)
400
-
401
- ```typescript
402
- import { Pagination } from "../vars/pagination.js";
403
-
404
- export function PaginationLayout(ctx: any) {
405
- const pagination = ctx.get(Pagination); // typed as PaginationData | undefined
406
- if (!pagination) return <Outlet />;
407
- return <nav>Page {pagination.current} of {pagination.total}</nav>;
408
- }
409
- ```
410
-
411
- ### Why not just use RSCRouter.Vars?
412
-
413
- `RSCRouter.Vars` (via module augmentation) provides app-global typing for
414
- `ctx.get("key")` / `ctx.set("key", value)`. It works for middleware state
415
- shared app-wide. `createVar<T>()` is for route-local or feature-scoped
416
- context -- the producer and consumer import the same token, creating a
417
- scoped contract without polluting global types.
418
-
419
- Both approaches coexist: `ctx.get("user")` (global via Vars) and
420
- `ctx.get(Pagination)` (scoped via createVar) work side by side.
421
-
422
- ## Handle Type Safety
423
-
424
- Handles have typed data:
425
-
426
- ```typescript
427
- // Built-in Breadcrumbs handle — import from "@rangojs/router"
428
- import { Breadcrumbs } from "@rangojs/router";
429
- // Type: Handle<BreadcrumbItem, BreadcrumbItem[]>
430
- // BreadcrumbItem: { label: string; href: string; content?: ReactNode | Promise<ReactNode> }
431
-
432
- // In route handler — push is fully typed
433
- path("/shop/product/:slug", (ctx) => {
434
- const breadcrumb = ctx.use(Breadcrumbs);
435
- breadcrumb({ label: "Products", href: "/shop/products" });
436
- return <ProductPage />;
437
- }, { name: "product" });
438
-
439
- // In client — typed array
440
- import { useHandle, Breadcrumbs } from "@rangojs/router/client";
441
- function BreadcrumbNav() {
442
- const crumbs = useHandle(Breadcrumbs);
443
- // crumbs: BreadcrumbItem[]
444
- }
445
-
446
- // Custom handles also work the same way
447
- import { createHandle } from "@rangojs/router";
448
- export const PageTitle = createHandle<string, string>(
449
- (segments) => segments.flat().at(-1) ?? "Default Title"
450
- );
451
- ```
452
-
453
- ## Ref Prop Type Safety (Loaders & Handles)
454
-
455
- Loaders and handles can be passed as props from server to client components.
456
- Use `typeof` to get the full typed definition without manually specifying generics:
457
-
458
- ```typescript
459
- // loaders.ts
460
- export const ProductLoader = createLoader(async (ctx) => {
461
- return { product: await fetchProduct(ctx.params.slug) };
462
- });
463
-
464
- // Built-in Breadcrumbs — or any custom handle created with createHandle()
465
-
466
- // Client component — typeof infers all generics
467
- ("use client");
468
- import { useLoader, useHandle, type Breadcrumbs } from "@rangojs/router/client";
469
- import type { ProductLoader } from "../loaders";
470
-
471
- function MyComponent({
472
- loader,
473
- handle,
474
- }: {
475
- loader: typeof ProductLoader; // LoaderDefinition<{ product: Product }>
476
- handle: typeof Breadcrumbs; // Handle<{ label: string; href: string }>
477
- }) {
478
- const { data } = useLoader(loader); // data is typed
479
- const crumbs = useHandle(handle); // crumbs is typed array
480
- // ...
481
- }
482
- ```
483
-
484
- RSC Flight serialization calls `toJSON()` on both loaders and handles,
485
- sending only `{ __brand, $$id }` to the client. The hooks recover the
486
- full functionality from module-level registries.
487
-
488
- ## Location State Type Safety
489
-
490
- ```typescript
491
- // location-states.ts
492
- import { createLocationState } from "@rangojs/router";
493
-
494
- // All export patterns work: export const, const + export { X }, export { X as Y }
495
- export const ProductPreview = createLocationState<{
496
- name: string;
497
- price: number;
498
- image: string;
499
- }>();
500
-
501
- // Passing state through Link
502
- <Link
503
- to={href("product", { slug: "widget" })}
504
- state={[ProductPreview({ name: "Widget", price: 99, image: "/img.jpg" })]}
505
- >
506
- View Product
507
- </Link>
508
-
509
- // Reading state in component
510
- function ProductHeader() {
511
- const preview = useLocationState(ProductPreview);
512
- // preview: { name: string; price: number; image: string } | undefined
513
-
514
- if (preview) {
515
- return <h1>{preview.name} - ${preview.price}</h1>;
516
- }
517
- return <h1>Loading...</h1>;
518
- }
519
- ```
520
-
521
- ## Multi-Project tsconfig Setup
522
-
523
- For monorepos or multi-app setups, use a shared base tsconfig. Each app only needs
524
- to extend the base and add its `router.tsx` to `files` so TypeScript picks up the
525
- global type declarations (like `RSCRouter.Env`).
526
-
527
- ```jsonc
528
- // tsconfig.base.json (root)
529
- {
530
- "compilerOptions": {
531
- "target": "ES2022",
532
- "module": "ESNext",
533
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
534
- "jsx": "react-jsx",
535
- "moduleResolution": "bundler",
536
- "strict": true,
537
- "noEmit": true,
538
- "skipLibCheck": true,
539
- "isolatedModules": true,
540
- "esModuleInterop": true,
541
- "resolveJsonModule": true,
542
- },
543
- }
544
- ```
545
-
546
- ```jsonc
547
- // apps/shop/tsconfig.json
548
- {
549
- "extends": "../../tsconfig.base.json",
550
- "include": ["src"],
551
- "files": ["src/router.tsx"],
552
- }
553
- ```
554
-
555
- ```jsonc
556
- // apps/blog/tsconfig.json
557
- {
558
- "extends": "../../tsconfig.base.json",
559
- "include": ["src"],
560
- "files": ["src/router.tsx"],
561
- }
562
- ```
563
-
564
- The `files` array ensures `router.tsx` (which contains `declare global { namespace RSCRouter { interface Env; interface Vars } }`)
565
- is always included in the compilation even if nothing directly imports it. Route types come from the
566
- auto-generated `*.named-routes.gen.ts` file (via `rango generate`), not from manual declaration.
567
- Each app gets its own typed environment without interfering with other apps.
568
-
569
- ## Complete Type-Safe Setup
570
-
571
- ```typescript
572
- // 1. env.ts - Environment types
573
- export interface AppBindings {
574
- DB: D1Database;
575
- KV: KVNamespace;
576
- }
577
-
578
- export interface AppVariables {
579
- user?: { id: string; email: string; role: string };
580
- }
581
-
582
- // 2. urls.tsx - Route definitions with names
583
- import { urls } from "@rangojs/router";
584
-
585
- export const urlpatterns = urls(({ path, layout, loader }) => [
586
- path("/", HomePage, { name: "home" }),
587
-
588
- layout(<ShopLayout />, () => [
589
- path("/shop", ShopIndex, { name: "shop" }),
590
- path("/shop/product/:slug", ProductPage, { name: "product" }, () => [
591
- loader(ProductLoader),
592
- ]),
593
- ]),
594
- ]);
595
-
596
- // 3. router.tsx - Create router and export reverse
597
- const router = createRouter<AppBindings>({
598
- document: Document,
599
- }).routes(urlpatterns);
600
-
601
- // Register bindings and variables globally for implicit typing
602
- declare global {
603
- namespace RSCRouter {
604
- interface Env extends AppBindings {}
605
- interface Vars extends AppVariables {}
606
- }
607
- }
608
-
609
- export const reverse = router.reverse;
610
- export default router;
611
-
612
- // 4. Run `npx rango generate src/router.tsx` to generate
613
- // router.named-routes.gen.ts (auto-registers GeneratedRouteMap globally).
614
- // No manual RegisteredRoutes declaration needed.
615
-
616
- // 5. loaders/*.ts - Type-safe loaders
617
- export const ProductLoader = createLoader(async (ctx) => {
618
- // ctx.params: { slug: string }
619
- // ctx.get("user"): User | undefined (from RSCRouter.Vars)
620
- // ctx.env.DB: D1Database (plain bindings from RSCRouter.Env)
621
- return { product: await fetchProduct(ctx.params.slug) };
622
- });
623
-
624
- // 6. Server: ctx.reverse for named routes
625
- path("/product/:slug", (ctx) => {
626
- return <Link to={ctx.reverse("shop")}>Back to Shop</Link>;
627
- }, { name: "product" })
628
-
629
- // 7. Client: useHref for mounted paths, href for absolute
630
- "use client";
631
- import { useHref, href, Link } from "@rangojs/router/client";
632
- <Link to={href("/shop/product/widget")}>Widget</Link>
633
- ```
9
+ @rangojs/router provides end-to-end type safety for routes, parameters, and
10
+ environment. Without it: `ctx.reverse()`/`href()` accept any string (typos
11
+ 404 at runtime, not compile time), `ctx.search`/`ctx.params` fall back to
12
+ loose `Record<string, string>`, and `ctx.env`/`ctx.get()` are untyped so a
13
+ missing binding surfaces as `undefined` in production instead of a build
14
+ error.
15
+
16
+ Each topic's full setup, code, and caveats live in a companion file linked
17
+ below. Read the one for your case.
18
+
19
+ ## Routing table
20
+
21
+ | I need... | Topic | File |
22
+ | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------------------------------- |
23
+ | Named routes, `.gen.ts` surfaces, `RegisteredRoutes` vs `GeneratedRouteMap`, tsconfig checklist | Router setup & generated route types | [`./generated-files-and-cli.md`](./generated-files-and-cli.md) |
24
+ | Type-safe `path()` names, `ctx.reverse()`, `href()`/`useHref()`, `Rango.PathResponse`, stable `path#export` identity | Route & href typing | [`./route-types.md`](./route-types.md) |
25
+ | Typed `search` schemas, `RouteSearchParams`/`RouteParams`, loader return types | Search params & loader typing | [`./params-and-search.md`](./params-and-search.md) |
26
+ | Typed `env`/bindings, `Rango.Vars`, `createVar()`, handle typing, loader/handle ref props, location state typing | Environment, context, and state typing | [`./env-and-bindings.md`](./env-and-bindings.md) |
27
+ | Multi-app / multi-router tsconfig setup, avoiding `GeneratedRouteMap` collisions | Multi-project setup & full walkthrough | [`./generated-files-and-cli.md`](./generated-files-and-cli.md) |
28
+ | Slow typecheck with many `include()` modules (instantiation blowup), wide `UrlPatterns<any>` annotations | Typecheck cost at route scale | [`./generated-files-and-cli.md`](./generated-files-and-cli.md) |
29
+
30
+ ## Companion files
31
+
32
+ - [`./generated-files-and-cli.md`](./generated-files-and-cli.md) — Router
33
+ setup, the three route-typing surfaces (`GeneratedRouteMap` /
34
+ per-module `routes` / `RegisteredRoutes`), the single-app setup checklist,
35
+ `$$routeNames` vs `router.routeMap`, multi-project tsconfig setup, and the
36
+ complete end-to-end setup walkthrough.
37
+ - [`./route-types.md`](./route-types.md)Type-safe route names, server
38
+ `ctx.reverse()`, client `href()`/`useHref()`, `Rango.Path`,
39
+ `Rango.PathResponse` (incl. overriding JSON/Flight serialization), and the
40
+ `path#export` stable identity scheme shared by loaders/handles/cached
41
+ functions/actions.
42
+ - [`./params-and-search.md`](./params-and-search.md) — Typed `search`
43
+ schemas on `path()`, `Handler<"name">` param/search inference,
44
+ `RouteSearchParams`/`RouteParams` utility types, and loader return-type
45
+ inference.
46
+ - [`./env-and-bindings.md`](./env-and-bindings.md) Environment bindings
47
+ (`TEnv`) and `Rango.Env`/`Rango.Vars` registration, `createVar<T>()`
48
+ scoped context tokens, handle typing, passing loaders/handles as typed
49
+ props, and location state typing.
50
+
51
+ See `/links` for the full URL generation guide (per-module `*.gen.ts`,
52
+ `useReverse`).