@rangojs/router 0.0.0-experimental.135c6902 → 0.0.0-experimental.136

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 (404) hide show
  1. package/AGENTS.md +8 -0
  2. package/README.md +245 -49
  3. package/dist/bin/rango.js +440 -133
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +3386 -1111
  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 +78 -25
  9. package/skills/api-client/SKILL.md +211 -0
  10. package/skills/breadcrumbs/SKILL.md +64 -2
  11. package/skills/bundle-analysis/SKILL.md +159 -0
  12. package/skills/cache-guide/SKILL.md +247 -23
  13. package/skills/caching/SKILL.md +281 -11
  14. package/skills/composability/SKILL.md +27 -3
  15. package/skills/css/SKILL.md +76 -0
  16. package/skills/debug-manifest/SKILL.md +4 -2
  17. package/skills/document-cache/SKILL.md +78 -55
  18. package/skills/handler-use/SKILL.md +364 -0
  19. package/skills/hooks/SKILL.md +250 -30
  20. package/skills/host-router/SKILL.md +83 -23
  21. package/skills/i18n/SKILL.md +276 -0
  22. package/skills/intercept/SKILL.md +87 -18
  23. package/skills/layout/SKILL.md +35 -9
  24. package/skills/links/SKILL.md +249 -17
  25. package/skills/loader/SKILL.md +289 -53
  26. package/skills/middleware/SKILL.md +52 -13
  27. package/skills/migrate-nextjs/SKILL.md +584 -0
  28. package/skills/migrate-react-router/SKILL.md +914 -0
  29. package/skills/mime-routes/SKILL.md +28 -1
  30. package/skills/observability/SKILL.md +172 -0
  31. package/skills/parallel/SKILL.md +144 -7
  32. package/skills/prerender/SKILL.md +172 -125
  33. package/skills/rango/SKILL.md +251 -22
  34. package/skills/react-compiler/SKILL.md +168 -0
  35. package/skills/response-routes/SKILL.md +123 -48
  36. package/skills/route/SKILL.md +101 -5
  37. package/skills/router-setup/SKILL.md +117 -10
  38. package/skills/scripts/SKILL.md +179 -0
  39. package/skills/server-actions/SKILL.md +775 -0
  40. package/skills/streams-and-websockets/SKILL.md +283 -0
  41. package/skills/tailwind/SKILL.md +27 -3
  42. package/skills/testing/SKILL.md +130 -0
  43. package/skills/testing/bindings.md +103 -0
  44. package/skills/testing/cache-prerender.md +127 -0
  45. package/skills/testing/client-components.md +124 -0
  46. package/skills/testing/e2e-parity.md +125 -0
  47. package/skills/testing/flight.md +91 -0
  48. package/skills/testing/handles.md +129 -0
  49. package/skills/testing/loader.md +128 -0
  50. package/skills/testing/middleware.md +99 -0
  51. package/skills/testing/render-handler.md +122 -0
  52. package/skills/testing/response-routes.md +95 -0
  53. package/skills/testing/reverse-and-types.md +84 -0
  54. package/skills/testing/server-actions.md +107 -0
  55. package/skills/testing/server-tree.md +128 -0
  56. package/skills/testing/setup.md +123 -0
  57. package/skills/typesafety/SKILL.md +332 -29
  58. package/skills/use-cache/SKILL.md +57 -14
  59. package/skills/view-transitions/SKILL.md +337 -0
  60. package/src/__augment-tests__/augment.ts +81 -0
  61. package/src/__augment-tests__/augmented.check.ts +116 -0
  62. package/src/__internal.ts +1 -66
  63. package/src/browser/action-coordinator.ts +53 -36
  64. package/src/browser/action-fence.ts +47 -0
  65. package/src/browser/app-shell.ts +39 -0
  66. package/src/browser/app-version.ts +14 -0
  67. package/src/browser/connection-warmup.ts +134 -0
  68. package/src/browser/cookie-name.ts +140 -0
  69. package/src/browser/event-controller.ts +192 -150
  70. package/src/browser/history-state.ts +21 -0
  71. package/src/browser/index.ts +3 -3
  72. package/src/browser/invalidate-client-cache.ts +52 -0
  73. package/src/browser/navigation-bridge.ts +131 -30
  74. package/src/browser/navigation-client.ts +199 -86
  75. package/src/browser/navigation-store-handle.ts +38 -0
  76. package/src/browser/navigation-store.ts +157 -74
  77. package/src/browser/navigation-transaction.ts +9 -59
  78. package/src/browser/network-error-handler.ts +34 -7
  79. package/src/browser/partial-update.ts +174 -109
  80. package/src/browser/prefetch/cache.ts +222 -69
  81. package/src/browser/prefetch/fetch.ts +347 -39
  82. package/src/browser/prefetch/queue.ts +113 -32
  83. package/src/browser/prefetch/resource-ready.ts +77 -0
  84. package/src/browser/rango-state.ts +158 -76
  85. package/src/browser/react/Link.tsx +102 -15
  86. package/src/browser/react/NavigationProvider.tsx +300 -122
  87. package/src/browser/react/ScrollRestoration.tsx +10 -6
  88. package/src/browser/react/context.ts +7 -2
  89. package/src/browser/react/deferred-handle-resolution.ts +75 -0
  90. package/src/browser/react/filter-segment-order.ts +66 -7
  91. package/src/browser/react/index.ts +0 -48
  92. package/src/browser/react/location-state-shared.ts +178 -8
  93. package/src/browser/react/location-state.ts +39 -14
  94. package/src/browser/react/use-action.ts +6 -15
  95. package/src/browser/react/use-handle.ts +23 -69
  96. package/src/browser/react/use-href.tsx +8 -1
  97. package/src/browser/react/use-link-status.ts +33 -8
  98. package/src/browser/react/use-navigation.ts +32 -7
  99. package/src/browser/react/use-params.ts +20 -10
  100. package/src/browser/react/use-reverse.ts +106 -0
  101. package/src/browser/react/use-router.ts +46 -11
  102. package/src/browser/react/use-search-params.ts +0 -5
  103. package/src/browser/react/use-segments.ts +11 -21
  104. package/src/browser/response-adapter.ts +99 -8
  105. package/src/browser/rsc-router.tsx +125 -28
  106. package/src/browser/scroll-restoration.ts +37 -22
  107. package/src/browser/segment-reconciler.ts +36 -14
  108. package/src/browser/segment-structure-assert.ts +2 -2
  109. package/src/browser/server-action-bridge.ts +222 -61
  110. package/src/browser/types.ts +115 -12
  111. package/src/browser/validate-redirect-origin.ts +43 -16
  112. package/src/build/collect-fallback-refs.ts +107 -0
  113. package/src/build/generate-manifest.ts +65 -40
  114. package/src/build/generate-route-types.ts +5 -1
  115. package/src/build/index.ts +8 -2
  116. package/src/build/prefix-tree-utils.ts +123 -0
  117. package/src/build/route-trie.ts +165 -36
  118. package/src/build/route-types/ast-route-extraction.ts +15 -8
  119. package/src/build/route-types/codegen.ts +16 -5
  120. package/src/build/route-types/include-resolution.ts +125 -24
  121. package/src/build/route-types/param-extraction.ts +6 -3
  122. package/src/build/route-types/per-module-writer.ts +22 -6
  123. package/src/build/route-types/router-processing.ts +260 -94
  124. package/src/build/route-types/scan-filter.ts +9 -2
  125. package/src/build/route-types/source-scan.ts +216 -0
  126. package/src/build/runtime-discovery.ts +9 -20
  127. package/src/cache/cache-error.ts +104 -0
  128. package/src/cache/cache-key-utils.ts +29 -13
  129. package/src/cache/cache-policy.ts +108 -34
  130. package/src/cache/cache-runtime.ts +239 -52
  131. package/src/cache/cache-scope.ts +234 -87
  132. package/src/cache/cache-tag.ts +103 -0
  133. package/src/cache/cf/cf-base64.ts +33 -0
  134. package/src/cache/cf/cf-cache-constants.ts +127 -0
  135. package/src/cache/cf/cf-cache-store.ts +1989 -378
  136. package/src/cache/cf/cf-cache-types.ts +349 -0
  137. package/src/cache/cf/cf-kv-utils.ts +46 -0
  138. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  139. package/src/cache/cf/index.ts +6 -16
  140. package/src/cache/document-cache.ts +89 -21
  141. package/src/cache/handle-snapshot.ts +70 -0
  142. package/src/cache/index.ts +10 -20
  143. package/src/cache/memory-segment-store.ts +136 -37
  144. package/src/cache/profile-registry.ts +46 -31
  145. package/src/cache/read-through-swr.ts +56 -12
  146. package/src/cache/segment-codec.ts +9 -17
  147. package/src/cache/tag-invalidation.ts +230 -0
  148. package/src/cache/taint.ts +55 -0
  149. package/src/cache/types.ts +37 -100
  150. package/src/client.rsc.tsx +44 -21
  151. package/src/client.tsx +119 -290
  152. package/src/cloudflare/index.ts +11 -0
  153. package/src/cloudflare/tracing.ts +109 -0
  154. package/src/component-utils.ts +19 -0
  155. package/src/components/DefaultDocument.tsx +8 -2
  156. package/src/context-var.ts +84 -2
  157. package/src/decode-loader-results.ts +52 -0
  158. package/src/defer.ts +196 -0
  159. package/src/deps/ssr.ts +0 -1
  160. package/src/encode-kv.ts +49 -0
  161. package/src/errors.ts +30 -4
  162. package/src/escape-script.ts +52 -0
  163. package/src/handle.ts +70 -22
  164. package/src/handles/MetaTags.tsx +62 -19
  165. package/src/handles/Scripts.tsx +183 -0
  166. package/src/handles/breadcrumbs.ts +37 -8
  167. package/src/handles/is-thenable.ts +19 -0
  168. package/src/handles/meta.ts +51 -40
  169. package/src/handles/script.ts +244 -0
  170. package/src/host/cookie-handler.ts +9 -60
  171. package/src/host/errors.ts +0 -24
  172. package/src/host/index.ts +8 -2
  173. package/src/host/pattern-matcher.ts +23 -52
  174. package/src/host/router.ts +107 -99
  175. package/src/host/testing.ts +40 -27
  176. package/src/host/types.ts +37 -4
  177. package/src/host/utils.ts +1 -1
  178. package/src/href-client.ts +137 -22
  179. package/src/index.rsc.ts +99 -13
  180. package/src/index.ts +139 -19
  181. package/src/internal-debug.ts +11 -10
  182. package/src/loader-store.ts +500 -0
  183. package/src/loader.rsc.ts +20 -13
  184. package/src/loader.ts +12 -11
  185. package/src/missing-id-error.ts +68 -0
  186. package/src/outlet-context.ts +1 -1
  187. package/src/outlet-provider.tsx +1 -5
  188. package/src/prerender/param-hash.ts +16 -16
  189. package/src/prerender/store.ts +37 -41
  190. package/src/prerender.ts +198 -82
  191. package/src/redirect-origin.ts +100 -0
  192. package/src/regex-escape.ts +8 -0
  193. package/src/render-error-thrower.tsx +20 -0
  194. package/src/response-utils.ts +62 -0
  195. package/src/reverse.ts +65 -15
  196. package/src/root-error-boundary.tsx +1 -19
  197. package/src/route-content-wrapper.tsx +19 -77
  198. package/src/route-definition/dsl-helpers.ts +461 -304
  199. package/src/route-definition/helper-factories.ts +28 -140
  200. package/src/route-definition/helpers-types.ts +149 -74
  201. package/src/route-definition/index.ts +4 -2
  202. package/src/route-definition/redirect.ts +51 -10
  203. package/src/route-definition/resolve-handler-use.ts +160 -0
  204. package/src/route-definition/use-item-types.ts +29 -0
  205. package/src/route-map-builder.ts +0 -16
  206. package/src/route-types.ts +37 -46
  207. package/src/router/basename.ts +14 -0
  208. package/src/router/content-negotiation.ts +164 -17
  209. package/src/router/error-handling.ts +45 -18
  210. package/src/router/find-match.ts +44 -23
  211. package/src/router/handler-context.ts +83 -39
  212. package/src/router/instrument.ts +350 -0
  213. package/src/router/intercept-resolution.ts +48 -24
  214. package/src/router/lazy-includes.ts +15 -52
  215. package/src/router/loader-resolution.ts +274 -56
  216. package/src/router/logging.ts +0 -6
  217. package/src/router/manifest.ts +40 -42
  218. package/src/router/match-api.ts +124 -204
  219. package/src/router/match-context.ts +0 -22
  220. package/src/router/match-handlers.ts +58 -58
  221. package/src/router/match-middleware/background-revalidation.ts +54 -25
  222. package/src/router/match-middleware/cache-lookup.ts +205 -271
  223. package/src/router/match-middleware/cache-store.ts +81 -50
  224. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  225. package/src/router/match-middleware/segment-resolution.ts +45 -14
  226. package/src/router/match-pipelines.ts +1 -42
  227. package/src/router/match-result.ts +93 -39
  228. package/src/router/metrics.ts +5 -34
  229. package/src/router/middleware-types.ts +13 -142
  230. package/src/router/middleware.ts +268 -171
  231. package/src/router/navigation-snapshot.ts +131 -0
  232. package/src/router/params-util.ts +23 -0
  233. package/src/router/pattern-matching.ts +132 -90
  234. package/src/router/prefetch-cache-ttl.ts +51 -0
  235. package/src/router/prefetch-limits.ts +37 -0
  236. package/src/router/prerender-match.ts +195 -56
  237. package/src/router/preview-match.ts +32 -102
  238. package/src/router/request-classification.ts +276 -0
  239. package/src/router/revalidation.ts +123 -73
  240. package/src/router/route-snapshot.ts +244 -0
  241. package/src/router/router-context.ts +3 -27
  242. package/src/router/router-interfaces.ts +129 -35
  243. package/src/router/router-options.ts +202 -15
  244. package/src/router/router-registry.ts +2 -5
  245. package/src/router/segment-resolution/fresh.ts +197 -92
  246. package/src/router/segment-resolution/helpers.ts +115 -30
  247. package/src/router/segment-resolution/loader-cache.ts +76 -39
  248. package/src/router/segment-resolution/revalidation.ts +392 -338
  249. package/src/router/segment-resolution/static-store.ts +19 -5
  250. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  251. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  252. package/src/router/segment-resolution.ts +5 -1
  253. package/src/router/segment-wrappers.ts +6 -5
  254. package/src/router/state-cookie-name.ts +33 -0
  255. package/src/router/substitute-pattern-params.ts +56 -0
  256. package/src/router/telemetry-otel.ts +161 -199
  257. package/src/router/telemetry.ts +96 -19
  258. package/src/router/timeout.ts +0 -20
  259. package/src/router/tracing.ts +206 -0
  260. package/src/router/trie-matching.ts +163 -59
  261. package/src/router/types.ts +10 -63
  262. package/src/router/url-params.ts +44 -0
  263. package/src/router.ts +174 -54
  264. package/src/rsc/handler-context.ts +3 -2
  265. package/src/rsc/handler.ts +660 -518
  266. package/src/rsc/helpers.ts +168 -46
  267. package/src/rsc/index.ts +2 -5
  268. package/src/rsc/json-route-result.ts +38 -0
  269. package/src/rsc/loader-fetch.ts +127 -31
  270. package/src/rsc/manifest-init.ts +33 -42
  271. package/src/rsc/origin-guard.ts +39 -25
  272. package/src/rsc/progressive-enhancement.ts +133 -13
  273. package/src/rsc/redirect-guard.ts +99 -0
  274. package/src/rsc/response-cache-serve.ts +238 -0
  275. package/src/rsc/response-error.ts +79 -12
  276. package/src/rsc/response-route-handler.ts +99 -189
  277. package/src/rsc/rsc-rendering.ts +115 -73
  278. package/src/rsc/runtime-warnings.ts +23 -10
  279. package/src/rsc/server-action.ts +287 -113
  280. package/src/rsc/ssr-setup.ts +18 -2
  281. package/src/rsc/transition-gate.ts +89 -0
  282. package/src/rsc/types.ts +36 -6
  283. package/src/runtime-env.ts +18 -0
  284. package/src/search-params.ts +35 -30
  285. package/src/segment-content-promise.ts +67 -0
  286. package/src/segment-loader-promise.ts +149 -0
  287. package/src/segment-system.tsx +269 -202
  288. package/src/serialize.ts +243 -0
  289. package/src/server/context.ts +235 -51
  290. package/src/server/cookie-parse.ts +32 -0
  291. package/src/server/cookie-store.ts +80 -5
  292. package/src/server/handle-store.ts +40 -38
  293. package/src/server/loader-registry.ts +38 -46
  294. package/src/server/request-context.ts +442 -173
  295. package/src/ssr/index.tsx +24 -16
  296. package/src/static-handler.ts +27 -18
  297. package/src/testing/cache-status.ts +162 -0
  298. package/src/testing/collect-handle.ts +40 -0
  299. package/src/testing/dispatch.ts +701 -0
  300. package/src/testing/dom.entry.ts +22 -0
  301. package/src/testing/e2e/fixture.ts +188 -0
  302. package/src/testing/e2e/index.ts +128 -0
  303. package/src/testing/e2e/matchers.ts +35 -0
  304. package/src/testing/e2e/page-helpers.ts +272 -0
  305. package/src/testing/e2e/parity.ts +387 -0
  306. package/src/testing/e2e/server.ts +195 -0
  307. package/src/testing/flight-matchers.ts +97 -0
  308. package/src/testing/flight-normalize.ts +11 -0
  309. package/src/testing/flight-runtime.d.ts +57 -0
  310. package/src/testing/flight-tree.ts +682 -0
  311. package/src/testing/flight.entry.ts +52 -0
  312. package/src/testing/flight.ts +257 -0
  313. package/src/testing/generated-routes.ts +183 -0
  314. package/src/testing/index.ts +105 -0
  315. package/src/testing/internal/context.ts +371 -0
  316. package/src/testing/internal/flight-client-globals.ts +30 -0
  317. package/src/testing/internal/seed-vars.ts +54 -0
  318. package/src/testing/render-handler.ts +357 -0
  319. package/src/testing/render-route.tsx +581 -0
  320. package/src/testing/run-loader.ts +385 -0
  321. package/src/testing/run-middleware.ts +205 -0
  322. package/src/testing/run-transition-when.ts +164 -0
  323. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  324. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  325. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  326. package/src/testing/vitest-stubs/version.ts +5 -0
  327. package/src/testing/vitest.ts +305 -0
  328. package/src/theme/ThemeProvider.tsx +20 -58
  329. package/src/theme/ThemeScript.tsx +7 -9
  330. package/src/theme/constants.ts +52 -13
  331. package/src/theme/index.ts +0 -7
  332. package/src/theme/theme-context.ts +1 -5
  333. package/src/theme/theme-script.ts +22 -21
  334. package/src/theme/use-theme.ts +0 -3
  335. package/src/types/boundaries.ts +0 -35
  336. package/src/types/cache-types.ts +17 -8
  337. package/src/types/error-types.ts +30 -90
  338. package/src/types/global-namespace.ts +54 -41
  339. package/src/types/handler-context.ts +234 -82
  340. package/src/types/index.ts +3 -10
  341. package/src/types/loader-types.ts +44 -15
  342. package/src/types/request-scope.ts +112 -0
  343. package/src/types/route-config.ts +6 -50
  344. package/src/types/route-entry.ts +12 -7
  345. package/src/types/segments.ts +136 -15
  346. package/src/urls/include-helper.ts +33 -70
  347. package/src/urls/index.ts +1 -11
  348. package/src/urls/path-helper-types.ts +68 -18
  349. package/src/urls/path-helper.ts +57 -111
  350. package/src/urls/pattern-types.ts +48 -19
  351. package/src/urls/response-types.ts +25 -22
  352. package/src/urls/type-extraction.ts +58 -139
  353. package/src/urls/urls-function.ts +1 -19
  354. package/src/use-loader.tsx +346 -89
  355. package/src/vite/debug.ts +185 -0
  356. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  357. package/src/vite/discovery/discover-routers.ts +130 -85
  358. package/src/vite/discovery/discovery-errors.ts +194 -0
  359. package/src/vite/discovery/gate-state.ts +171 -0
  360. package/src/vite/discovery/prerender-collection.ts +214 -132
  361. package/src/vite/discovery/route-types-writer.ts +40 -84
  362. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  363. package/src/vite/discovery/state.ts +57 -4
  364. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  365. package/src/vite/index.ts +6 -0
  366. package/src/vite/inject-client-debug.ts +36 -0
  367. package/src/vite/plugin-types.ts +178 -5
  368. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  369. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  370. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  371. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  372. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  373. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  374. package/src/vite/plugins/expose-action-id.ts +48 -95
  375. package/src/vite/plugins/expose-id-utils.ts +96 -51
  376. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  377. package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
  378. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  379. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  380. package/src/vite/plugins/expose-internal-ids.ts +553 -317
  381. package/src/vite/plugins/performance-tracks.ts +89 -0
  382. package/src/vite/plugins/refresh-cmd.ts +89 -27
  383. package/src/vite/plugins/use-cache-transform.ts +73 -83
  384. package/src/vite/plugins/version-injector.ts +40 -29
  385. package/src/vite/plugins/version-plugin.ts +37 -40
  386. package/src/vite/plugins/virtual-entries.ts +39 -25
  387. package/src/vite/rango.ts +119 -111
  388. package/src/vite/router-discovery.ts +941 -142
  389. package/src/vite/utils/ast-handler-extract.ts +26 -35
  390. package/src/vite/utils/banner.ts +1 -1
  391. package/src/vite/utils/bundle-analysis.ts +10 -15
  392. package/src/vite/utils/client-chunks.ts +184 -0
  393. package/src/vite/utils/directive-prologue.ts +40 -0
  394. package/src/vite/utils/forward-user-plugins.ts +171 -0
  395. package/src/vite/utils/manifest-utils.ts +4 -59
  396. package/src/vite/utils/package-resolution.ts +20 -52
  397. package/src/vite/utils/prerender-utils.ts +81 -34
  398. package/src/vite/utils/shared-utils.ts +92 -42
  399. package/src/browser/action-response-classifier.ts +0 -99
  400. package/src/browser/react/use-client-cache.ts +0 -58
  401. package/src/browser/shallow.ts +0 -40
  402. package/src/handles/index.ts +0 -7
  403. package/src/network-error-thrower.tsx +0 -23
  404. package/src/router/middleware-cookies.ts +0 -55
@@ -0,0 +1,44 @@
1
+ /**
2
+ * URL param encode/decode at the route boundary.
3
+ *
4
+ * Extraction (decode): regex/trie matchers keep param values URL-encoded;
5
+ * `safeDecodeURIComponent` turns them back into raw strings so `ctx.params`
6
+ * matches the contract apps expect (Express/React Router/Fastify/Koa) and
7
+ * round-trips through reverse stay stable. Malformed %-encoding is
8
+ * preserved as-is so a broken URL doesn't crash matching.
9
+ *
10
+ * Reversal (encode): `encodePathSegment` escapes only what RFC 3986
11
+ * requires for a path segment — `/`, `?`, `#`, space, control chars,
12
+ * non-ASCII — and leaves pchar sub-delims (`@ : $ & + , ; =` and friends)
13
+ * readable. `encodeURIComponent` over-encodes for path segments, which
14
+ * makes generated URLs harder for humans to read in the address bar
15
+ * (e.g. mailbox IDs like `ivo@example.com` would become
16
+ * `ivo%40example.com` even though `@` is path-legal).
17
+ */
18
+
19
+ export function safeDecodeURIComponent(raw: string): string {
20
+ if (raw === "" || raw.indexOf("%") === -1) return raw;
21
+ try {
22
+ return decodeURIComponent(raw);
23
+ } catch {
24
+ return raw;
25
+ }
26
+ }
27
+
28
+ const PATH_SAFE_ESCAPES: Record<string, string> = {
29
+ "%3A": ":",
30
+ "%40": "@",
31
+ "%24": "$",
32
+ "%26": "&",
33
+ "%2B": "+",
34
+ "%2C": ",",
35
+ "%3B": ";",
36
+ "%3D": "=",
37
+ };
38
+
39
+ export function encodePathSegment(value: string): string {
40
+ return encodeURIComponent(value).replace(
41
+ /%(?:3A|40|24|26|2B|2C|3B|3D)/gi,
42
+ (match) => PATH_SAFE_ESCAPES[match.toUpperCase()] ?? match,
43
+ );
44
+ }
package/src/router.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { createCacheScope } from "./cache/cache-scope.js";
3
- import {
4
- setCacheProfiles,
5
- resolveCacheProfiles,
6
- } from "./cache/profile-registry.js";
3
+ import { resolveCacheProfiles } from "./cache/profile-registry.js";
7
4
  import { isCachedFunction } from "./cache/taint.js";
8
5
  import { assertClientComponent } from "./component-utils.js";
9
6
  import { DefaultDocument } from "./components/DefaultDocument.js";
@@ -19,11 +16,13 @@ import {
19
16
  import MapRootLayout from "./server/root-layout.js";
20
17
  import type { AllUseItems } from "./route-types.js";
21
18
  import type { UrlPatterns } from "./urls.js";
19
+ import type { UrlBuilder } from "./urls/pattern-types.js";
20
+ import { urls } from "./urls.js";
21
+ import { buildPrecomputedByPrefix } from "./build/prefix-tree-utils.js";
22
22
  import {
23
- EntryData,
24
- InterceptSelectorContext,
23
+ type EntryData,
25
24
  getContext,
26
- RSCRouterContext,
25
+ RangoContext,
27
26
  type MetricsStore,
28
27
  } from "./server/context";
29
28
  import { createHandleStore, type HandleStore } from "./server/handle-store.js";
@@ -55,6 +54,7 @@ import { buildDebugManifest } from "./router/debug-manifest.js";
55
54
 
56
55
  import type { SegmentResolutionDeps, MatchApiDeps } from "./router/types.js";
57
56
  import { createHandlerContext } from "./router/handler-context.js";
57
+ import { normalizeBasename } from "./router/basename.js";
58
58
  import {
59
59
  setupLoaderAccess,
60
60
  setupLoaderAccessSilent,
@@ -63,15 +63,17 @@ import {
63
63
  import { loadManifest } from "./router/manifest.js";
64
64
  import { createMetricsStore } from "./router/metrics.js";
65
65
  import {
66
- parsePattern,
66
+ compileMiddlewarePattern,
67
67
  type MiddlewareEntry,
68
68
  type MiddlewareFn,
69
69
  } from "./router/middleware.js";
70
70
  import {
71
71
  extractStaticPrefix,
72
+ joinPrefix,
72
73
  traverseBack,
73
74
  } from "./router/pattern-matching.js";
74
75
  import { resolveSink, safeEmit, getRequestId } from "./router/telemetry.js";
76
+ import { resolveTracing } from "./router/tracing.js";
75
77
  import { evaluateRevalidation } from "./router/revalidation.js";
76
78
  import {
77
79
  type RouterContext,
@@ -89,13 +91,10 @@ import {
89
91
  RouterRegistry,
90
92
  nextRouterAutoId,
91
93
  } from "./router/router-registry.js";
94
+ import type { RangoOptions, RootLayoutProps } from "./router/router-options.js";
92
95
  import type {
93
- RSCRouterOptions,
94
- RootLayoutProps,
95
- } from "./router/router-options.js";
96
- import type {
97
- RSCRouter,
98
- RSCRouterInternal,
96
+ Rango,
97
+ RangoInternal,
99
98
  RouterRequestInput,
100
99
  } from "./router/router-interfaces.js";
101
100
 
@@ -110,29 +109,36 @@ import {
110
109
  matchForPrerender as _matchForPrerender,
111
110
  renderStaticSegment as _renderStaticSegment,
112
111
  } from "./router/prerender-match.js";
112
+ import { resolveStateCookieName } from "./router/state-cookie-name.js";
113
+ import { resolvePrefetchCacheTTL } from "./router/prefetch-cache-ttl.js";
114
+ import {
115
+ resolvePrefetchCacheSize,
116
+ resolvePrefetchConcurrency,
117
+ } from "./router/prefetch-limits.js";
113
118
 
114
119
  // Re-export public types and values from extracted modules
115
120
  export { RSC_ROUTER_BRAND, RouterRegistry } from "./router/router-registry.js";
116
121
  export type {
117
- RSCRouterOptions,
122
+ RangoOptions,
118
123
  RootLayoutProps,
119
124
  SSRStreamMode,
120
125
  SSROptions,
121
126
  ResolveStreamingContext,
122
127
  } from "./router/router-options.js";
123
128
  export type {
124
- RSCRouter,
125
- RSCRouterInternal,
129
+ Rango,
130
+ RangoInternal,
126
131
  RouterRequestInput,
127
132
  } from "./router/router-interfaces.js";
128
133
  export { toInternal } from "./router/router-interfaces.js";
129
134
 
130
135
  export function createRouter<TEnv = any>(
131
- options: RSCRouterOptions<TEnv> = {},
132
- ): RSCRouter<TEnv, {}> {
136
+ options: RangoOptions<TEnv> = {},
137
+ ): Rango<TEnv, {}> {
133
138
  const {
134
139
  id: userProvidedId,
135
140
  $$id: injectedId,
141
+ basename: basenameOption,
136
142
  debugPerformance = false,
137
143
  document: documentOption,
138
144
  defaultErrorBoundary,
@@ -148,24 +154,48 @@ export function createRouter<TEnv = any>(
148
154
  nonce,
149
155
  version,
150
156
  prefetchCacheTTL: prefetchCacheTTLOption,
157
+ prefetchCacheSize: prefetchCacheSizeOption,
158
+ prefetchConcurrency: prefetchConcurrencyOption,
159
+ stateCookiePrefix: stateCookiePrefixOption,
151
160
  warmup: warmupOption,
152
161
  allowDebugManifest: allowDebugManifestOption = false,
153
162
  telemetry: telemetrySink,
163
+ tracing: tracingOption,
154
164
  ssr: ssrOption,
155
165
  timeout: timeoutShorthand,
156
166
  timeouts: timeoutsOption,
157
167
  onTimeout,
158
168
  originCheck: originCheckOption,
169
+ viewTransition: viewTransitionOption = "auto",
170
+ debugCacheSignal: debugCacheSignalOption = false,
171
+ strictMode: strictModeOption = true,
159
172
  } = options;
160
173
 
174
+ // Debug cache signal gate (DEVELOPMENT/TEST ONLY). Enabled by the
175
+ // debugCacheSignal option OR the RANGO_TEST_SIGNALS=1 env flag. When off,
176
+ // no X-Rango-Cache header is emitted and output is byte-identical.
177
+ const cacheSignalEnabled =
178
+ debugCacheSignalOption ||
179
+ (typeof process !== "undefined" &&
180
+ (process as { env?: Record<string, string | undefined> }).env
181
+ ?.RANGO_TEST_SIGNALS === "1");
182
+
183
+ // Normalize basename: ensure leading slash, strip trailing slash.
184
+ // A bare "/" is equivalent to no basename. Shared with the testing
185
+ // primitives via normalizeBasename so they can never drift.
186
+ const basename = normalizeBasename(basenameOption);
187
+
161
188
  // Resolve telemetry sink (no-op when not configured)
162
189
  const telemetry = resolveSink(telemetrySink);
163
190
 
164
- // Resolve cache profiles: merge user config with guaranteed default profile.
165
- // This resolved map is both stored on the router (for per-request context)
166
- // and written to the global registry (for DSL-time cache("profileName")).
191
+ // Resolve span tracing (undefined when not configured; every traceSpan() call
192
+ // is then a direct pass-through with zero behavior change).
193
+ const resolvedTracing = resolveTracing(tracingOption);
194
+
195
+ // Resolve cache profiles: merge user config with the guaranteed default
196
+ // profile. This resolved map is threaded onto each request context; the
197
+ // "use cache: <profile>" runtime path reads it request-scoped.
167
198
  const resolvedCacheProfiles = resolveCacheProfiles(cacheProfilesOption);
168
- setCacheProfiles(resolvedCacheProfiles);
169
199
 
170
200
  // Source file: prefer Vite-injected path (zero cost), fall back to
171
201
  // stack trace parsing for non-Vite environments (e.g. tests).
@@ -200,21 +230,40 @@ export function createRouter<TEnv = any>(
200
230
  const routerId =
201
231
  userProvidedId ?? injectedId ?? `router_${nextRouterAutoId()}`;
202
232
 
203
- // Resolve prefetch cache TTL (default: 300 seconds / 5 minutes)
204
- // Clamp to a non-negative integer for valid Cache-Control max-age.
205
- const rawTTL =
206
- prefetchCacheTTLOption !== undefined ? prefetchCacheTTLOption : 300;
207
- const prefetchCacheTTLSeconds =
208
- rawTTL === false ? 0 : Math.max(0, Math.floor(rawTTL));
209
- const prefetchCacheTTL = prefetchCacheTTLSeconds * 1000;
233
+ // Resolve the rango state cookie name once, here, so the two cookie writers
234
+ // (the client document.cookie writer and the server Set-Cookie writer)
235
+ // consume one pre-composed name and cannot drift.
236
+ const resolvedStateCookieName = resolveStateCookieName(
237
+ stateCookiePrefixOption,
238
+ routerId,
239
+ );
240
+
241
+ // Resolve prefetch cache TTL (default: 300 seconds / 5 minutes). Clamps to a
242
+ // non-negative integer and guards non-finite (NaN/Infinity) inputs so a
243
+ // malformed `Cache-Control: max-age=NaN` can never reach the wire.
244
+ const resolvedPrefetchCacheTTL = resolvePrefetchCacheTTL(
245
+ prefetchCacheTTLOption,
246
+ );
247
+ const prefetchCacheTTL = resolvedPrefetchCacheTTL.ms;
210
248
  const prefetchCacheControl: string | false =
211
- prefetchCacheTTLSeconds === 0
212
- ? false
213
- : `private, max-age=${prefetchCacheTTLSeconds}`;
249
+ resolvedPrefetchCacheTTL.cacheControl;
250
+
251
+ // Resolve client-side prefetch limits (in-memory cache size and queue
252
+ // concurrency). Both are positive-integer counts; sub-1/non-finite inputs
253
+ // fall back to the defaults. Shipped to the client in payload metadata.
254
+ const prefetchCacheSize = resolvePrefetchCacheSize(prefetchCacheSizeOption);
255
+ const prefetchConcurrency = resolvePrefetchConcurrency(
256
+ prefetchConcurrencyOption,
257
+ );
214
258
 
215
259
  // Resolve warmup enabled flag (default: true)
216
260
  const warmupEnabled = warmupOption !== false;
217
261
 
262
+ // Resolve StrictMode flag (default: true). Shipped to the client in payload
263
+ // metadata; the browser entry reads it once to decide whether to wrap the
264
+ // hydrated tree in React.StrictMode.
265
+ const strictMode = strictModeOption !== false;
266
+
218
267
  // Resolve theme config (null if theme not enabled)
219
268
  const resolvedThemeConfig = themeOption
220
269
  ? resolveThemeConfig(themeOption)
@@ -246,9 +295,14 @@ export function createRouter<TEnv = any>(
246
295
  invokeOnError(onError, error, phase, context, "Router");
247
296
  }
248
297
 
249
- // Validate document is a client component
298
+ // Validate document is a client component. Under a test runner the "use
299
+ // client" transform has not run, so a real exported document has no marker;
300
+ // allowServerInTest lets the router construct in a bare unit test (for
301
+ // dispatch / assertGeneratedRoutesMatch) while a real build still throws.
250
302
  if (documentOption !== undefined) {
251
- assertClientComponent(documentOption, "document");
303
+ assertClientComponent(documentOption, "document", {
304
+ allowServerInTest: true,
305
+ });
252
306
  }
253
307
 
254
308
  // Use default document if none provided (keeps internal name as rootLayout)
@@ -312,7 +366,7 @@ export function createRouter<TEnv = any>(
312
366
  let regex: RegExp | null = null;
313
367
  let paramNames: string[] = [];
314
368
  if (fullPattern) {
315
- const parsed = parsePattern(fullPattern);
369
+ const parsed = compileMiddlewarePattern(fullPattern);
316
370
  regex = parsed.regex;
317
371
  paramNames = parsed.paramNames;
318
372
  }
@@ -322,7 +376,6 @@ export function createRouter<TEnv = any>(
322
376
  regex,
323
377
  paramNames,
324
378
  handler,
325
- mountPrefix,
326
379
  });
327
380
  }
328
381
 
@@ -356,9 +409,11 @@ export function createRouter<TEnv = any>(
356
409
  getRouterPrecomputedEntries(routerId) ?? getPrecomputedEntries();
357
410
  if (current !== precomputedSource) {
358
411
  precomputedSource = current;
359
- precomputedByPrefix = current
360
- ? new Map(current.map((e) => [e.staticPrefix, e.routes]))
361
- : null;
412
+ // buildPrecomputedByPrefix drops any staticPrefix owned by more than one
413
+ // leaf include instead of collapsing it last-wins (which would mis-assign
414
+ // one include's routes to another's entry and 500 a valid sibling route).
415
+ // Such shared-prefix includes resolve via the handler path instead.
416
+ precomputedByPrefix = current ? buildPrecomputedByPrefix(current) : null;
362
417
  }
363
418
  return precomputedByPrefix;
364
419
  }
@@ -526,7 +581,9 @@ export function createRouter<TEnv = any>(
526
581
  trackHandler,
527
582
  findNearestErrorBoundary,
528
583
  findNearestNotFoundBoundary,
584
+ notFoundComponent: notFound,
529
585
  callOnError,
586
+ viewTransitionDefault: viewTransitionOption,
530
587
  };
531
588
 
532
589
  // Match API dependencies
@@ -614,6 +671,8 @@ export function createRouter<TEnv = any>(
614
671
  params: Record<string, string>,
615
672
  buildVars?: Record<string, any>,
616
673
  isPassthroughRoute?: boolean,
674
+ buildEnv?: TEnv,
675
+ devMode?: boolean,
617
676
  ) {
618
677
  return _matchForPrerender(
619
678
  pathname,
@@ -621,6 +680,8 @@ export function createRouter<TEnv = any>(
621
680
  prerenderDeps,
622
681
  buildVars,
623
682
  isPassthroughRoute,
683
+ buildEnv,
684
+ devMode,
624
685
  );
625
686
  }
626
687
 
@@ -628,12 +689,16 @@ export function createRouter<TEnv = any>(
628
689
  handler: Function,
629
690
  handlerId: string,
630
691
  routeName?: string,
692
+ buildEnv?: TEnv,
693
+ devMode?: boolean,
631
694
  ) {
632
695
  return _renderStaticSegment<TEnv>(
633
696
  handler,
634
697
  handlerId,
635
698
  mergedRouteMap,
636
699
  routeName,
700
+ buildEnv,
701
+ devMode,
637
702
  );
638
703
  }
639
704
 
@@ -646,6 +711,7 @@ export function createRouter<TEnv = any>(
646
711
  findMatch,
647
712
  findInterceptForRoute,
648
713
  telemetry: telemetrySink,
714
+ cacheSignalEnabled,
649
715
  });
650
716
 
651
717
  const { match, matchPartial, matchError, previewMatch } = matchHandlers;
@@ -655,11 +721,18 @@ export function createRouter<TEnv = any>(
655
721
  * The type system tracks accumulated routes through the builder chain
656
722
  * Initial TRoutes is {} (empty) to avoid poisoning accumulated types with Record<string, string>
657
723
  */
658
- const router: RSCRouterInternal<TEnv, {}> = {
724
+ const router: RangoInternal<TEnv, {}> = {
659
725
  __brand: RSC_ROUTER_BRAND,
660
726
  id: routerId,
727
+ basename,
728
+
729
+ routes(patternsOrBuilder: UrlPatterns<TEnv> | UrlBuilder<TEnv>): any {
730
+ // Wrap builder functions in urls() automatically
731
+ const urlPatterns: UrlPatterns<TEnv> =
732
+ typeof patternsOrBuilder === "function"
733
+ ? (urls(patternsOrBuilder) as UrlPatterns<TEnv>)
734
+ : patternsOrBuilder;
661
735
 
662
- routes(urlPatterns: UrlPatterns<TEnv>): any {
663
736
  // Store reference for runtime manifest generation
664
737
  storedUrlPatterns = urlPatterns;
665
738
  const currentMountIndex = mountIndex++;
@@ -696,7 +769,7 @@ export function createRouter<TEnv = any>(
696
769
  };
697
770
 
698
771
  let handlerResult: AllUseItems[] = [];
699
- RSCRouterContext.run(
772
+ RangoContext.run(
700
773
  {
701
774
  manifest,
702
775
  patterns: routePatterns,
@@ -707,6 +780,10 @@ export function createRouter<TEnv = any>(
707
780
  counters: {},
708
781
  mountIndex: currentMountIndex,
709
782
  cacheProfiles: resolvedCacheProfiles,
783
+ // basename sets the initial URL prefix so all path() patterns
784
+ // are registered with the prefix (e.g. "/admin" + "/users" = "/admin/users").
785
+ // No namePrefix — route names stay unprefixed.
786
+ ...(basename ? { urlPrefix: basename } : {}),
710
787
  },
711
788
  () => {
712
789
  handlerResult = urlPatterns.handler() as AllUseItems[];
@@ -726,7 +803,7 @@ export function createRouter<TEnv = any>(
726
803
  if (entry.type === "route" && entry.isPrerender) {
727
804
  if (!prerenderRouteKeys) prerenderRouteKeys = new Set();
728
805
  prerenderRouteKeys.add(name);
729
- if (entry.prerenderDef?.options?.passthrough === true) {
806
+ if (entry.isPassthrough === true) {
730
807
  if (!passthroughRouteKeys) passthroughRouteKeys = new Set();
731
808
  passthroughRouteKeys.add(name);
732
809
  }
@@ -804,10 +881,13 @@ export function createRouter<TEnv = any>(
804
881
 
805
882
  // Create placeholder RouteEntry for each lazy include
806
883
  for (const lazyInclude of lazyIncludes) {
807
- // Compute the full URL prefix (combining parent prefix if any)
808
- const fullPrefix = lazyInclude.context.urlPrefix
809
- ? lazyInclude.context.urlPrefix + lazyInclude.prefix
810
- : lazyInclude.prefix;
884
+ // Compute the full URL prefix (combining parent prefix if any). Use the
885
+ // slash-collapsing join so a trailing-slash parent prefix does not
886
+ // produce a double-slash staticPrefix the trie's sp can never match.
887
+ const fullPrefix = joinPrefix(
888
+ lazyInclude.context.urlPrefix,
889
+ lazyInclude.prefix,
890
+ );
811
891
 
812
892
  const lazyEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
813
893
  prefix: "",
@@ -855,8 +935,18 @@ export function createRouter<TEnv = any>(
855
935
  patternOrMiddleware: string | MiddlewareFn<TEnv>,
856
936
  middleware?: MiddlewareFn<TEnv>,
857
937
  ): any {
858
- // Global middleware - no mount prefix
859
- addMiddleware(patternOrMiddleware, middleware, null);
938
+ // Auto-prefix pattern with basename so router-level middleware
939
+ // patterns are router-relative (e.g. "/users/*" matches "/app/users/*").
940
+ if (basename && typeof patternOrMiddleware === "string") {
941
+ const pattern = patternOrMiddleware;
942
+ const prefixed =
943
+ pattern === "/*" || pattern === "*"
944
+ ? `${basename}/*`
945
+ : `${basename}${pattern}`;
946
+ addMiddleware(prefixed, middleware, null);
947
+ } else {
948
+ addMiddleware(patternOrMiddleware, middleware, null);
949
+ }
860
950
  return router;
861
951
  },
862
952
 
@@ -892,13 +982,25 @@ export function createRouter<TEnv = any>(
892
982
  // Expose prefetch cache settings
893
983
  prefetchCacheControl,
894
984
  prefetchCacheTTL,
985
+ prefetchCacheSize,
986
+ prefetchConcurrency,
987
+
988
+ // Expose the resolved rango state cookie name for the server-side writer
989
+ // (invalidateClientCache) and for shipping to the client in metadata.
990
+ resolvedStateCookieName,
895
991
 
896
992
  // Expose warmup enabled flag for handler and client
897
993
  warmupEnabled,
898
994
 
995
+ // Expose StrictMode flag for the initial-render payload metadata
996
+ strictMode,
997
+
899
998
  // Expose router-wide performance debugging for request-level metrics setup
900
999
  debugPerformance,
901
1000
 
1001
+ // Expose resolved span tracing for the handler (Cloudflare custom spans)
1002
+ tracing: resolvedTracing,
1003
+
902
1004
  // Expose debug manifest flag for handler
903
1005
  allowDebugManifest: allowDebugManifestOption,
904
1006
 
@@ -957,6 +1059,16 @@ export function createRouter<TEnv = any>(
957
1059
  // Expose source file for per-router type generation
958
1060
  __sourceFile,
959
1061
 
1062
+ // Expose basename for runtime manifest generation
1063
+ __basename: basename,
1064
+
1065
+ // Expose router-level boundary defaults for build-time clientChunks
1066
+ // discovery (so a "use client" default boundary lands in app-fallback).
1067
+ // These are createRouter options, never pushed onto EntryData.
1068
+ __defaultErrorBoundary: defaultErrorBoundary,
1069
+ __defaultNotFoundBoundary: defaultNotFoundBoundary,
1070
+ __notFound: notFound,
1071
+
960
1072
  // RSC request handler (lazily created on first call)
961
1073
  fetch: (() => {
962
1074
  // Handler is created on first call and reused
@@ -974,8 +1086,10 @@ export function createRouter<TEnv = any>(
974
1086
  if (!handler) {
975
1087
  // Lazy import deferred to first request to avoid dev mode issues
976
1088
  const { createRSCHandler } = await import("./rsc/handler.js");
977
- // Cast: handler.ts still accepts (request, env) — will be updated
978
- // separately to accept RouterRequestInput.
1089
+ // Cast: createRSCHandler receives `router as any`, which erases TEnv
1090
+ // and infers its handler as RouterRequestInput<unknown>. Re-narrow the
1091
+ // returned handler to RouterRequestInput<TEnv> so the call below stays
1092
+ // typed. (The handler already accepts (request, RouterRequestInput).)
979
1093
  handler = createRSCHandler({
980
1094
  router: router as any,
981
1095
  cache,
@@ -990,6 +1104,10 @@ export function createRouter<TEnv = any>(
990
1104
  };
991
1105
  })(),
992
1106
 
1107
+ // Low-level route matching for request classification
1108
+ findMatch: (pathname: string, metricsStore?: any) =>
1109
+ findMatch(pathname, metricsStore),
1110
+
993
1111
  // Debug utility for manifest inspection
994
1112
  debugManifest: () => buildDebugManifest<TEnv>(routesEntries),
995
1113
  };
@@ -998,8 +1116,10 @@ export function createRouter<TEnv = any>(
998
1116
  RouterRegistry.set(routerId, router);
999
1117
 
1000
1118
  // If urls option was provided, auto-register them
1001
- if (urlsOption) {
1002
- return router.routes(urlsOption) as RSCRouter<TEnv, {}>;
1119
+ if (typeof urlsOption === "function") {
1120
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1121
+ } else if (urlsOption) {
1122
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1003
1123
  }
1004
1124
 
1005
1125
  return router;
@@ -6,14 +6,14 @@
6
6
  * RSC rendering) so they can be standalone modules without closure coupling.
7
7
  */
8
8
 
9
- import type { RSCRouterInternal } from "../router/router-interfaces.js";
9
+ import type { RangoInternal } from "../router/router-interfaces.js";
10
10
  import type { ErrorPhase } from "../types.js";
11
11
  import type { InvokeOnErrorContext } from "../router/error-handling.js";
12
12
  import type { RSCDependencies, LoadSSRModule } from "./types.js";
13
13
  import type { SSRStreamMode } from "../router/router-options.js";
14
14
 
15
15
  export interface HandlerContext<TEnv = unknown> {
16
- router: RSCRouterInternal<TEnv, any>;
16
+ router: RangoInternal<TEnv, any>;
17
17
  version: string;
18
18
  renderToReadableStream: RSCDependencies["renderToReadableStream"];
19
19
  decodeReply: RSCDependencies["decodeReply"];
@@ -31,6 +31,7 @@ export interface HandlerContext<TEnv = unknown> {
31
31
  createRedirectFlightResponse: (
32
32
  redirectUrl: string,
33
33
  locationState?: Record<string, unknown>,
34
+ external?: boolean,
34
35
  ) => Response;
35
36
 
36
37
  /**