@rangojs/router 0.0.0-experimental.a769fbe7 → 0.0.0-experimental.ac99d918

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 (374) hide show
  1. package/README.md +211 -43
  2. package/dist/bin/rango.js +279 -102
  3. package/dist/testing/vitest.js +82 -0
  4. package/dist/vite/index.js +3313 -1160
  5. package/dist/vite/index.js.bak +5448 -0
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +62 -11
  8. package/skills/api-client/SKILL.md +211 -0
  9. package/skills/breadcrumbs/SKILL.md +63 -1
  10. package/skills/bundle-analysis/SKILL.md +159 -0
  11. package/skills/cache-guide/SKILL.md +222 -30
  12. package/skills/caching/SKILL.md +263 -8
  13. package/skills/composability/SKILL.md +27 -2
  14. package/skills/css/SKILL.md +76 -0
  15. package/skills/document-cache/SKILL.md +78 -55
  16. package/skills/handler-use/SKILL.md +364 -0
  17. package/skills/hooks/SKILL.md +250 -30
  18. package/skills/host-router/SKILL.md +124 -22
  19. package/skills/i18n/SKILL.md +276 -0
  20. package/skills/intercept/SKILL.md +49 -5
  21. package/skills/layout/SKILL.md +35 -9
  22. package/skills/links/SKILL.md +249 -17
  23. package/skills/loader/SKILL.md +223 -9
  24. package/skills/middleware/SKILL.md +52 -13
  25. package/skills/migrate-nextjs/SKILL.md +584 -0
  26. package/skills/migrate-react-router/SKILL.md +769 -0
  27. package/skills/mime-routes/SKILL.md +27 -0
  28. package/skills/observability/SKILL.md +137 -0
  29. package/skills/parallel/SKILL.md +77 -7
  30. package/skills/prerender/SKILL.md +123 -100
  31. package/skills/rango/SKILL.md +250 -22
  32. package/skills/react-compiler/SKILL.md +168 -0
  33. package/skills/response-routes/SKILL.md +122 -47
  34. package/skills/route/SKILL.md +66 -5
  35. package/skills/router-setup/SKILL.md +38 -3
  36. package/skills/server-actions/SKILL.md +775 -0
  37. package/skills/streams-and-websockets/SKILL.md +283 -0
  38. package/skills/tailwind/SKILL.md +27 -3
  39. package/skills/testing/SKILL.md +129 -0
  40. package/skills/testing/bindings.md +89 -0
  41. package/skills/testing/cache-prerender.md +124 -0
  42. package/skills/testing/client-components.md +122 -0
  43. package/skills/testing/e2e-parity.md +125 -0
  44. package/skills/testing/flight.md +92 -0
  45. package/skills/testing/handles.md +129 -0
  46. package/skills/testing/loader.md +128 -0
  47. package/skills/testing/middleware.md +99 -0
  48. package/skills/testing/render-handler.md +121 -0
  49. package/skills/testing/response-routes.md +95 -0
  50. package/skills/testing/reverse-and-types.md +84 -0
  51. package/skills/testing/server-actions.md +107 -0
  52. package/skills/testing/server-tree.md +128 -0
  53. package/skills/testing/setup.md +120 -0
  54. package/skills/typesafety/SKILL.md +319 -27
  55. package/skills/use-cache/SKILL.md +36 -5
  56. package/skills/vercel/SKILL.md +107 -0
  57. package/skills/view-transitions/SKILL.md +294 -0
  58. package/src/__augment-tests__/augment.ts +81 -0
  59. package/src/__augment-tests__/augmented.check.ts +116 -0
  60. package/src/__internal.ts +1 -66
  61. package/src/browser/action-coordinator.ts +53 -36
  62. package/src/browser/action-fence.ts +47 -0
  63. package/src/browser/app-shell.ts +39 -0
  64. package/src/browser/app-version.ts +14 -0
  65. package/src/browser/cookie-name.ts +140 -0
  66. package/src/browser/event-controller.ts +81 -147
  67. package/src/browser/history-state.ts +21 -0
  68. package/src/browser/index.ts +3 -3
  69. package/src/browser/invalidate-client-cache.ts +52 -0
  70. package/src/browser/navigation-bridge.ts +66 -14
  71. package/src/browser/navigation-client.ts +172 -109
  72. package/src/browser/navigation-store-handle.ts +38 -0
  73. package/src/browser/navigation-store.ts +76 -67
  74. package/src/browser/navigation-transaction.ts +9 -59
  75. package/src/browser/partial-update.ts +79 -93
  76. package/src/browser/prefetch/cache.ts +180 -62
  77. package/src/browser/prefetch/fetch.ts +252 -39
  78. package/src/browser/prefetch/queue.ts +42 -8
  79. package/src/browser/rango-state.ts +158 -76
  80. package/src/browser/react/Link.tsx +72 -10
  81. package/src/browser/react/NavigationProvider.tsx +83 -31
  82. package/src/browser/react/ScrollRestoration.tsx +10 -6
  83. package/src/browser/react/context.ts +7 -2
  84. package/src/browser/react/filter-segment-order.ts +49 -7
  85. package/src/browser/react/index.ts +0 -48
  86. package/src/browser/react/location-state-shared.ts +166 -8
  87. package/src/browser/react/location-state.ts +39 -14
  88. package/src/browser/react/use-action.ts +6 -15
  89. package/src/browser/react/use-handle.ts +23 -69
  90. package/src/browser/react/use-link-status.ts +0 -4
  91. package/src/browser/react/use-navigation.ts +22 -5
  92. package/src/browser/react/use-params.ts +20 -10
  93. package/src/browser/react/use-reverse.ts +106 -0
  94. package/src/browser/react/use-router.ts +46 -11
  95. package/src/browser/react/use-search-params.ts +0 -5
  96. package/src/browser/react/use-segments.ts +11 -21
  97. package/src/browser/response-adapter.ts +52 -1
  98. package/src/browser/rsc-router.tsx +111 -24
  99. package/src/browser/scroll-restoration.ts +29 -19
  100. package/src/browser/segment-reconciler.ts +36 -14
  101. package/src/browser/segment-structure-assert.ts +2 -2
  102. package/src/browser/server-action-bridge.ts +176 -62
  103. package/src/browser/types.ts +60 -11
  104. package/src/browser/validate-redirect-origin.ts +43 -16
  105. package/src/build/collect-fallback-refs.ts +107 -0
  106. package/src/build/generate-manifest.ts +65 -40
  107. package/src/build/generate-route-types.ts +6 -0
  108. package/src/build/index.ts +8 -2
  109. package/src/build/prefix-tree-utils.ts +123 -0
  110. package/src/build/route-trie.ts +137 -32
  111. package/src/build/route-types/codegen.ts +4 -4
  112. package/src/build/route-types/include-resolution.ts +9 -2
  113. package/src/build/route-types/param-extraction.ts +6 -3
  114. package/src/build/route-types/per-module-writer.ts +7 -4
  115. package/src/build/route-types/router-processing.ts +333 -94
  116. package/src/build/route-types/scan-filter.ts +9 -2
  117. package/src/build/route-types/source-scan.ts +118 -0
  118. package/src/build/runtime-discovery.ts +9 -20
  119. package/src/cache/cache-error.ts +104 -0
  120. package/src/cache/cache-policy.ts +68 -28
  121. package/src/cache/cache-runtime.ts +134 -32
  122. package/src/cache/cache-scope.ts +100 -74
  123. package/src/cache/cache-tag.ts +98 -0
  124. package/src/cache/cf/cf-cache-store.ts +2256 -241
  125. package/src/cache/cf/index.ts +6 -16
  126. package/src/cache/document-cache.ts +61 -20
  127. package/src/cache/handle-snapshot.ts +63 -0
  128. package/src/cache/index.ts +22 -20
  129. package/src/cache/memory-segment-store.ts +136 -37
  130. package/src/cache/profile-registry.ts +6 -30
  131. package/src/cache/read-through-swr.ts +41 -11
  132. package/src/cache/segment-codec.ts +0 -16
  133. package/src/cache/tag-invalidation.ts +230 -0
  134. package/src/cache/types.ts +33 -100
  135. package/src/cache/vercel/index.ts +11 -0
  136. package/src/cache/vercel/vercel-cache-store.ts +799 -0
  137. package/src/client.rsc.tsx +6 -21
  138. package/src/client.tsx +108 -290
  139. package/src/component-utils.ts +19 -0
  140. package/src/context-var.ts +17 -5
  141. package/src/decode-loader-results.ts +36 -0
  142. package/src/defer.ts +196 -0
  143. package/src/deps/browser.ts +0 -1
  144. package/src/deps/ssr.ts +0 -1
  145. package/src/errors.ts +30 -4
  146. package/src/handle.ts +70 -22
  147. package/src/handles/MetaTags.tsx +0 -14
  148. package/src/handles/breadcrumbs.ts +16 -5
  149. package/src/handles/meta.ts +0 -39
  150. package/src/host/cookie-handler.ts +0 -36
  151. package/src/host/errors.ts +0 -24
  152. package/src/host/index.ts +8 -2
  153. package/src/host/pattern-matcher.ts +7 -50
  154. package/src/host/router.ts +107 -99
  155. package/src/host/testing.ts +40 -27
  156. package/src/host/types.ts +37 -4
  157. package/src/host/utils.ts +1 -1
  158. package/src/href-client.ts +137 -22
  159. package/src/index.rsc.ts +69 -10
  160. package/src/index.ts +112 -14
  161. package/src/internal-debug.ts +2 -4
  162. package/src/loader-store.ts +500 -0
  163. package/src/loader.rsc.ts +20 -13
  164. package/src/loader.ts +12 -11
  165. package/src/missing-id-error.ts +68 -0
  166. package/src/network-error-thrower.tsx +1 -6
  167. package/src/outlet-context.ts +1 -1
  168. package/src/outlet-provider.tsx +1 -5
  169. package/src/prerender/param-hash.ts +10 -11
  170. package/src/prerender/store.ts +37 -41
  171. package/src/prerender.ts +198 -82
  172. package/src/redirect-origin.ts +100 -0
  173. package/src/response-utils.ts +37 -0
  174. package/src/reverse.ts +65 -15
  175. package/src/root-error-boundary.tsx +1 -19
  176. package/src/route-content-wrapper.tsx +7 -72
  177. package/src/route-definition/dsl-helpers.ts +413 -275
  178. package/src/route-definition/helper-factories.ts +29 -139
  179. package/src/route-definition/helpers-types.ts +107 -32
  180. package/src/route-definition/index.ts +3 -0
  181. package/src/route-definition/redirect.ts +50 -8
  182. package/src/route-definition/resolve-handler-use.ts +161 -0
  183. package/src/route-definition/use-item-types.ts +32 -0
  184. package/src/route-map-builder.ts +0 -16
  185. package/src/route-types.ts +37 -41
  186. package/src/router/basename.ts +14 -0
  187. package/src/router/content-negotiation.ts +108 -9
  188. package/src/router/error-handling.ts +13 -17
  189. package/src/router/find-match.ts +44 -23
  190. package/src/router/handler-context.ts +46 -30
  191. package/src/router/intercept-resolution.ts +23 -23
  192. package/src/router/lazy-includes.ts +15 -52
  193. package/src/router/loader-resolution.ts +207 -30
  194. package/src/router/logging.ts +0 -6
  195. package/src/router/manifest.ts +40 -42
  196. package/src/router/match-api.ts +120 -204
  197. package/src/router/match-context.ts +0 -22
  198. package/src/router/match-handlers.ts +58 -58
  199. package/src/router/match-middleware/background-revalidation.ts +0 -7
  200. package/src/router/match-middleware/cache-lookup.ts +161 -262
  201. package/src/router/match-middleware/cache-store.ts +3 -33
  202. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  203. package/src/router/match-middleware/segment-resolution.ts +45 -14
  204. package/src/router/match-pipelines.ts +1 -42
  205. package/src/router/match-result.ts +87 -39
  206. package/src/router/metrics.ts +0 -34
  207. package/src/router/middleware-types.ts +7 -140
  208. package/src/router/middleware.ts +169 -140
  209. package/src/router/navigation-snapshot.ts +131 -0
  210. package/src/router/params-util.ts +23 -0
  211. package/src/router/pattern-matching.ts +109 -63
  212. package/src/router/prerender-match.ts +190 -54
  213. package/src/router/preview-match.ts +32 -102
  214. package/src/router/request-classification.ts +276 -0
  215. package/src/router/revalidation.ts +63 -55
  216. package/src/router/route-snapshot.ts +244 -0
  217. package/src/router/router-context.ts +0 -27
  218. package/src/router/router-interfaces.ts +100 -35
  219. package/src/router/router-options.ts +91 -11
  220. package/src/router/router-registry.ts +2 -5
  221. package/src/router/segment-resolution/fresh.ts +119 -65
  222. package/src/router/segment-resolution/helpers.ts +34 -0
  223. package/src/router/segment-resolution/loader-cache.ts +40 -37
  224. package/src/router/segment-resolution/revalidation.ts +329 -305
  225. package/src/router/segment-resolution/static-store.ts +19 -5
  226. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  227. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  228. package/src/router/segment-resolution.ts +4 -1
  229. package/src/router/segment-wrappers.ts +0 -3
  230. package/src/router/state-cookie-name.ts +33 -0
  231. package/src/router/substitute-pattern-params.ts +56 -0
  232. package/src/router/telemetry-otel.ts +0 -20
  233. package/src/router/telemetry.ts +96 -19
  234. package/src/router/timeout.ts +0 -20
  235. package/src/router/trie-matching.ts +91 -46
  236. package/src/router/types.ts +9 -63
  237. package/src/router/url-params.ts +44 -0
  238. package/src/router.ts +128 -42
  239. package/src/rsc/handler-context.ts +3 -2
  240. package/src/rsc/handler.ts +492 -409
  241. package/src/rsc/helpers.ts +162 -46
  242. package/src/rsc/index.ts +1 -1
  243. package/src/rsc/json-route-result.ts +38 -0
  244. package/src/rsc/loader-fetch.ts +18 -3
  245. package/src/rsc/manifest-init.ts +33 -42
  246. package/src/rsc/origin-guard.ts +39 -25
  247. package/src/rsc/progressive-enhancement.ts +28 -4
  248. package/src/rsc/redirect-guard.ts +99 -0
  249. package/src/rsc/response-error.ts +79 -12
  250. package/src/rsc/response-route-handler.ts +90 -63
  251. package/src/rsc/rsc-rendering.ts +53 -56
  252. package/src/rsc/runtime-warnings.ts +23 -10
  253. package/src/rsc/server-action.ts +74 -69
  254. package/src/rsc/ssr-setup.ts +18 -2
  255. package/src/rsc/types.ts +22 -9
  256. package/src/runtime-env.ts +18 -0
  257. package/src/search-params.ts +4 -20
  258. package/src/segment-content-promise.ts +67 -0
  259. package/src/segment-loader-promise.ts +134 -0
  260. package/src/segment-system.tsx +208 -201
  261. package/src/serialize.ts +243 -0
  262. package/src/server/context.ts +211 -52
  263. package/src/server/cookie-store.ts +80 -5
  264. package/src/server/handle-store.ts +26 -24
  265. package/src/server/loader-registry.ts +10 -28
  266. package/src/server/request-context.ts +289 -124
  267. package/src/ssr/index.tsx +22 -15
  268. package/src/static-handler.ts +27 -18
  269. package/src/testing/cache-status.ts +162 -0
  270. package/src/testing/collect-handle.ts +40 -0
  271. package/src/testing/dispatch.ts +618 -0
  272. package/src/testing/dom.entry.ts +22 -0
  273. package/src/testing/e2e/fixture.ts +188 -0
  274. package/src/testing/e2e/index.ts +128 -0
  275. package/src/testing/e2e/matchers.ts +35 -0
  276. package/src/testing/e2e/page-helpers.ts +272 -0
  277. package/src/testing/e2e/parity.ts +387 -0
  278. package/src/testing/e2e/server.ts +195 -0
  279. package/src/testing/flight-matchers.ts +97 -0
  280. package/src/testing/flight-normalize.ts +11 -0
  281. package/src/testing/flight-runtime.d.ts +57 -0
  282. package/src/testing/flight-tree.ts +682 -0
  283. package/src/testing/flight.entry.ts +52 -0
  284. package/src/testing/flight.ts +232 -0
  285. package/src/testing/generated-routes.ts +183 -0
  286. package/src/testing/index.ts +99 -0
  287. package/src/testing/internal/context.ts +348 -0
  288. package/src/testing/internal/flight-client-globals.ts +30 -0
  289. package/src/testing/internal/seed-vars.ts +54 -0
  290. package/src/testing/render-handler.ts +330 -0
  291. package/src/testing/render-route.tsx +566 -0
  292. package/src/testing/run-loader.ts +378 -0
  293. package/src/testing/run-middleware.ts +205 -0
  294. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  295. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  296. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  297. package/src/testing/vitest-stubs/version.ts +5 -0
  298. package/src/testing/vitest.ts +305 -0
  299. package/src/theme/ThemeProvider.tsx +0 -52
  300. package/src/theme/ThemeScript.tsx +0 -6
  301. package/src/theme/constants.ts +0 -12
  302. package/src/theme/index.ts +0 -7
  303. package/src/theme/theme-context.ts +1 -5
  304. package/src/theme/theme-script.ts +0 -14
  305. package/src/theme/use-theme.ts +0 -3
  306. package/src/types/boundaries.ts +0 -35
  307. package/src/types/cache-types.ts +17 -8
  308. package/src/types/error-types.ts +30 -90
  309. package/src/types/global-namespace.ts +54 -41
  310. package/src/types/handler-context.ts +124 -70
  311. package/src/types/index.ts +1 -10
  312. package/src/types/loader-types.ts +40 -11
  313. package/src/types/request-scope.ts +107 -0
  314. package/src/types/route-config.ts +6 -50
  315. package/src/types/route-entry.ts +12 -7
  316. package/src/types/segments.ts +36 -15
  317. package/src/urls/include-helper.ts +33 -70
  318. package/src/urls/index.ts +1 -11
  319. package/src/urls/path-helper-types.ts +58 -11
  320. package/src/urls/path-helper.ts +57 -111
  321. package/src/urls/pattern-types.ts +48 -19
  322. package/src/urls/response-types.ts +25 -22
  323. package/src/urls/type-extraction.ts +58 -139
  324. package/src/urls/urls-function.ts +1 -18
  325. package/src/use-loader.tsx +346 -89
  326. package/src/vite/debug.ts +185 -0
  327. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  328. package/src/vite/discovery/discover-routers.ts +130 -85
  329. package/src/vite/discovery/discovery-errors.ts +194 -0
  330. package/src/vite/discovery/gate-state.ts +171 -0
  331. package/src/vite/discovery/prerender-collection.ts +192 -99
  332. package/src/vite/discovery/route-types-writer.ts +40 -84
  333. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  334. package/src/vite/discovery/state.ts +51 -4
  335. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  336. package/src/vite/index.ts +8 -0
  337. package/src/vite/plugin-types.ts +236 -6
  338. package/src/vite/plugins/cjs-to-esm.ts +8 -18
  339. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  340. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  341. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  342. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  343. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  344. package/src/vite/plugins/expose-action-id.ts +48 -95
  345. package/src/vite/plugins/expose-id-utils.ts +11 -50
  346. package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
  347. package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
  348. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
  349. package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
  350. package/src/vite/plugins/expose-internal-ids.ts +554 -317
  351. package/src/vite/plugins/performance-tracks.ts +65 -207
  352. package/src/vite/plugins/refresh-cmd.ts +89 -27
  353. package/src/vite/plugins/use-cache-transform.ts +73 -83
  354. package/src/vite/plugins/vercel-output.ts +258 -0
  355. package/src/vite/plugins/version-injector.ts +21 -25
  356. package/src/vite/plugins/version-plugin.ts +32 -23
  357. package/src/vite/plugins/virtual-entries.ts +46 -17
  358. package/src/vite/rango.ts +207 -125
  359. package/src/vite/router-discovery.ts +931 -133
  360. package/src/vite/utils/ast-handler-extract.ts +15 -31
  361. package/src/vite/utils/banner.ts +1 -1
  362. package/src/vite/utils/bundle-analysis.ts +10 -15
  363. package/src/vite/utils/client-chunks.ts +184 -0
  364. package/src/vite/utils/forward-user-plugins.ts +171 -0
  365. package/src/vite/utils/manifest-utils.ts +4 -59
  366. package/src/vite/utils/package-resolution.ts +20 -52
  367. package/src/vite/utils/prerender-utils.ts +27 -29
  368. package/src/vite/utils/shared-utils.ts +97 -44
  369. package/src/browser/action-response-classifier.ts +0 -99
  370. package/src/browser/debug-channel.ts +0 -93
  371. package/src/browser/react/use-client-cache.ts +0 -58
  372. package/src/browser/shallow.ts +0 -40
  373. package/src/handles/index.ts +0 -7
  374. package/src/router/middleware-cookies.ts +0 -55
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,
@@ -69,6 +69,7 @@ import {
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";
@@ -89,13 +90,10 @@ import {
89
90
  RouterRegistry,
90
91
  nextRouterAutoId,
91
92
  } from "./router/router-registry.js";
93
+ import type { RangoOptions, RootLayoutProps } from "./router/router-options.js";
92
94
  import type {
93
- RSCRouterOptions,
94
- RootLayoutProps,
95
- } from "./router/router-options.js";
96
- import type {
97
- RSCRouter,
98
- RSCRouterInternal,
95
+ Rango,
96
+ RangoInternal,
99
97
  RouterRequestInput,
100
98
  } from "./router/router-interfaces.js";
101
99
 
@@ -110,29 +108,31 @@ import {
110
108
  matchForPrerender as _matchForPrerender,
111
109
  renderStaticSegment as _renderStaticSegment,
112
110
  } from "./router/prerender-match.js";
111
+ import { resolveStateCookieName } from "./router/state-cookie-name.js";
113
112
 
114
113
  // Re-export public types and values from extracted modules
115
114
  export { RSC_ROUTER_BRAND, RouterRegistry } from "./router/router-registry.js";
116
115
  export type {
117
- RSCRouterOptions,
116
+ RangoOptions,
118
117
  RootLayoutProps,
119
118
  SSRStreamMode,
120
119
  SSROptions,
121
120
  ResolveStreamingContext,
122
121
  } from "./router/router-options.js";
123
122
  export type {
124
- RSCRouter,
125
- RSCRouterInternal,
123
+ Rango,
124
+ RangoInternal,
126
125
  RouterRequestInput,
127
126
  } from "./router/router-interfaces.js";
128
127
  export { toInternal } from "./router/router-interfaces.js";
129
128
 
130
129
  export function createRouter<TEnv = any>(
131
- options: RSCRouterOptions<TEnv> = {},
132
- ): RSCRouter<TEnv, {}> {
130
+ options: RangoOptions<TEnv> = {},
131
+ ): Rango<TEnv, {}> {
133
132
  const {
134
133
  id: userProvidedId,
135
134
  $$id: injectedId,
135
+ basename: basenameOption,
136
136
  debugPerformance = false,
137
137
  document: documentOption,
138
138
  defaultErrorBoundary,
@@ -148,6 +148,7 @@ export function createRouter<TEnv = any>(
148
148
  nonce,
149
149
  version,
150
150
  prefetchCacheTTL: prefetchCacheTTLOption,
151
+ stateCookiePrefix: stateCookiePrefixOption,
151
152
  warmup: warmupOption,
152
153
  allowDebugManifest: allowDebugManifestOption = false,
153
154
  telemetry: telemetrySink,
@@ -156,16 +157,31 @@ export function createRouter<TEnv = any>(
156
157
  timeouts: timeoutsOption,
157
158
  onTimeout,
158
159
  originCheck: originCheckOption,
160
+ viewTransition: viewTransitionOption = "auto",
161
+ debugCacheSignal: debugCacheSignalOption = false,
159
162
  } = options;
160
163
 
164
+ // Debug cache signal gate (DEVELOPMENT/TEST ONLY). Enabled by the
165
+ // debugCacheSignal option OR the RANGO_TEST_SIGNALS=1 env flag. When off,
166
+ // no X-Rango-Cache header is emitted and output is byte-identical.
167
+ const cacheSignalEnabled =
168
+ debugCacheSignalOption ||
169
+ (typeof process !== "undefined" &&
170
+ (process as { env?: Record<string, string | undefined> }).env
171
+ ?.RANGO_TEST_SIGNALS === "1");
172
+
173
+ // Normalize basename: ensure leading slash, strip trailing slash.
174
+ // A bare "/" is equivalent to no basename. Shared with the testing
175
+ // primitives via normalizeBasename so they can never drift.
176
+ const basename = normalizeBasename(basenameOption);
177
+
161
178
  // Resolve telemetry sink (no-op when not configured)
162
179
  const telemetry = resolveSink(telemetrySink);
163
180
 
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")).
181
+ // Resolve cache profiles: merge user config with the guaranteed default
182
+ // profile. This resolved map is threaded onto each request context; the
183
+ // "use cache: <profile>" runtime path reads it request-scoped.
167
184
  const resolvedCacheProfiles = resolveCacheProfiles(cacheProfilesOption);
168
- setCacheProfiles(resolvedCacheProfiles);
169
185
 
170
186
  // Source file: prefer Vite-injected path (zero cost), fall back to
171
187
  // stack trace parsing for non-Vite environments (e.g. tests).
@@ -200,6 +216,14 @@ export function createRouter<TEnv = any>(
200
216
  const routerId =
201
217
  userProvidedId ?? injectedId ?? `router_${nextRouterAutoId()}`;
202
218
 
219
+ // Resolve the rango state cookie name once, here, so the two cookie writers
220
+ // (the client document.cookie writer and the server Set-Cookie writer)
221
+ // consume one pre-composed name and cannot drift.
222
+ const resolvedStateCookieName = resolveStateCookieName(
223
+ stateCookiePrefixOption,
224
+ routerId,
225
+ );
226
+
203
227
  // Resolve prefetch cache TTL (default: 300 seconds / 5 minutes)
204
228
  // Clamp to a non-negative integer for valid Cache-Control max-age.
205
229
  const rawTTL =
@@ -246,9 +270,14 @@ export function createRouter<TEnv = any>(
246
270
  invokeOnError(onError, error, phase, context, "Router");
247
271
  }
248
272
 
249
- // Validate document is a client component
273
+ // Validate document is a client component. Under a test runner the "use
274
+ // client" transform has not run, so a real exported document has no marker;
275
+ // allowServerInTest lets the router construct in a bare unit test (for
276
+ // dispatch / assertGeneratedRoutesMatch) while a real build still throws.
250
277
  if (documentOption !== undefined) {
251
- assertClientComponent(documentOption, "document");
278
+ assertClientComponent(documentOption, "document", {
279
+ allowServerInTest: true,
280
+ });
252
281
  }
253
282
 
254
283
  // Use default document if none provided (keeps internal name as rootLayout)
@@ -322,7 +351,6 @@ export function createRouter<TEnv = any>(
322
351
  regex,
323
352
  paramNames,
324
353
  handler,
325
- mountPrefix,
326
354
  });
327
355
  }
328
356
 
@@ -356,9 +384,11 @@ export function createRouter<TEnv = any>(
356
384
  getRouterPrecomputedEntries(routerId) ?? getPrecomputedEntries();
357
385
  if (current !== precomputedSource) {
358
386
  precomputedSource = current;
359
- precomputedByPrefix = current
360
- ? new Map(current.map((e) => [e.staticPrefix, e.routes]))
361
- : null;
387
+ // buildPrecomputedByPrefix drops any staticPrefix owned by more than one
388
+ // leaf include instead of collapsing it last-wins (which would mis-assign
389
+ // one include's routes to another's entry and 500 a valid sibling route).
390
+ // Such shared-prefix includes resolve via the handler path instead.
391
+ precomputedByPrefix = current ? buildPrecomputedByPrefix(current) : null;
362
392
  }
363
393
  return precomputedByPrefix;
364
394
  }
@@ -528,6 +558,7 @@ export function createRouter<TEnv = any>(
528
558
  findNearestNotFoundBoundary,
529
559
  notFoundComponent: notFound,
530
560
  callOnError,
561
+ viewTransitionDefault: viewTransitionOption,
531
562
  };
532
563
 
533
564
  // Match API dependencies
@@ -615,6 +646,8 @@ export function createRouter<TEnv = any>(
615
646
  params: Record<string, string>,
616
647
  buildVars?: Record<string, any>,
617
648
  isPassthroughRoute?: boolean,
649
+ buildEnv?: TEnv,
650
+ devMode?: boolean,
618
651
  ) {
619
652
  return _matchForPrerender(
620
653
  pathname,
@@ -622,6 +655,8 @@ export function createRouter<TEnv = any>(
622
655
  prerenderDeps,
623
656
  buildVars,
624
657
  isPassthroughRoute,
658
+ buildEnv,
659
+ devMode,
625
660
  );
626
661
  }
627
662
 
@@ -629,12 +664,16 @@ export function createRouter<TEnv = any>(
629
664
  handler: Function,
630
665
  handlerId: string,
631
666
  routeName?: string,
667
+ buildEnv?: TEnv,
668
+ devMode?: boolean,
632
669
  ) {
633
670
  return _renderStaticSegment<TEnv>(
634
671
  handler,
635
672
  handlerId,
636
673
  mergedRouteMap,
637
674
  routeName,
675
+ buildEnv,
676
+ devMode,
638
677
  );
639
678
  }
640
679
 
@@ -647,6 +686,7 @@ export function createRouter<TEnv = any>(
647
686
  findMatch,
648
687
  findInterceptForRoute,
649
688
  telemetry: telemetrySink,
689
+ cacheSignalEnabled,
650
690
  });
651
691
 
652
692
  const { match, matchPartial, matchError, previewMatch } = matchHandlers;
@@ -656,11 +696,18 @@ export function createRouter<TEnv = any>(
656
696
  * The type system tracks accumulated routes through the builder chain
657
697
  * Initial TRoutes is {} (empty) to avoid poisoning accumulated types with Record<string, string>
658
698
  */
659
- const router: RSCRouterInternal<TEnv, {}> = {
699
+ const router: RangoInternal<TEnv, {}> = {
660
700
  __brand: RSC_ROUTER_BRAND,
661
701
  id: routerId,
702
+ basename,
703
+
704
+ routes(patternsOrBuilder: UrlPatterns<TEnv> | UrlBuilder<TEnv>): any {
705
+ // Wrap builder functions in urls() automatically
706
+ const urlPatterns: UrlPatterns<TEnv> =
707
+ typeof patternsOrBuilder === "function"
708
+ ? (urls(patternsOrBuilder) as UrlPatterns<TEnv>)
709
+ : patternsOrBuilder;
662
710
 
663
- routes(urlPatterns: UrlPatterns<TEnv>): any {
664
711
  // Store reference for runtime manifest generation
665
712
  storedUrlPatterns = urlPatterns;
666
713
  const currentMountIndex = mountIndex++;
@@ -697,7 +744,7 @@ export function createRouter<TEnv = any>(
697
744
  };
698
745
 
699
746
  let handlerResult: AllUseItems[] = [];
700
- RSCRouterContext.run(
747
+ RangoContext.run(
701
748
  {
702
749
  manifest,
703
750
  patterns: routePatterns,
@@ -708,6 +755,10 @@ export function createRouter<TEnv = any>(
708
755
  counters: {},
709
756
  mountIndex: currentMountIndex,
710
757
  cacheProfiles: resolvedCacheProfiles,
758
+ // basename sets the initial URL prefix so all path() patterns
759
+ // are registered with the prefix (e.g. "/admin" + "/users" = "/admin/users").
760
+ // No namePrefix — route names stay unprefixed.
761
+ ...(basename ? { urlPrefix: basename } : {}),
711
762
  },
712
763
  () => {
713
764
  handlerResult = urlPatterns.handler() as AllUseItems[];
@@ -727,7 +778,7 @@ export function createRouter<TEnv = any>(
727
778
  if (entry.type === "route" && entry.isPrerender) {
728
779
  if (!prerenderRouteKeys) prerenderRouteKeys = new Set();
729
780
  prerenderRouteKeys.add(name);
730
- if (entry.prerenderDef?.options?.passthrough === true) {
781
+ if (entry.isPassthrough === true) {
731
782
  if (!passthroughRouteKeys) passthroughRouteKeys = new Set();
732
783
  passthroughRouteKeys.add(name);
733
784
  }
@@ -805,10 +856,13 @@ export function createRouter<TEnv = any>(
805
856
 
806
857
  // Create placeholder RouteEntry for each lazy include
807
858
  for (const lazyInclude of lazyIncludes) {
808
- // Compute the full URL prefix (combining parent prefix if any)
809
- const fullPrefix = lazyInclude.context.urlPrefix
810
- ? lazyInclude.context.urlPrefix + lazyInclude.prefix
811
- : lazyInclude.prefix;
859
+ // Compute the full URL prefix (combining parent prefix if any). Use the
860
+ // slash-collapsing join so a trailing-slash parent prefix does not
861
+ // produce a double-slash staticPrefix the trie's sp can never match.
862
+ const fullPrefix = joinPrefix(
863
+ lazyInclude.context.urlPrefix,
864
+ lazyInclude.prefix,
865
+ );
812
866
 
813
867
  const lazyEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
814
868
  prefix: "",
@@ -856,8 +910,18 @@ export function createRouter<TEnv = any>(
856
910
  patternOrMiddleware: string | MiddlewareFn<TEnv>,
857
911
  middleware?: MiddlewareFn<TEnv>,
858
912
  ): any {
859
- // Global middleware - no mount prefix
860
- addMiddleware(patternOrMiddleware, middleware, null);
913
+ // Auto-prefix pattern with basename so router-level middleware
914
+ // patterns are router-relative (e.g. "/users/*" matches "/app/users/*").
915
+ if (basename && typeof patternOrMiddleware === "string") {
916
+ const pattern = patternOrMiddleware;
917
+ const prefixed =
918
+ pattern === "/*" || pattern === "*"
919
+ ? `${basename}/*`
920
+ : `${basename}${pattern}`;
921
+ addMiddleware(prefixed, middleware, null);
922
+ } else {
923
+ addMiddleware(patternOrMiddleware, middleware, null);
924
+ }
861
925
  return router;
862
926
  },
863
927
 
@@ -894,6 +958,10 @@ export function createRouter<TEnv = any>(
894
958
  prefetchCacheControl,
895
959
  prefetchCacheTTL,
896
960
 
961
+ // Expose the resolved rango state cookie name for the server-side writer
962
+ // (invalidateClientCache) and for shipping to the client in metadata.
963
+ resolvedStateCookieName,
964
+
897
965
  // Expose warmup enabled flag for handler and client
898
966
  warmupEnabled,
899
967
 
@@ -958,6 +1026,16 @@ export function createRouter<TEnv = any>(
958
1026
  // Expose source file for per-router type generation
959
1027
  __sourceFile,
960
1028
 
1029
+ // Expose basename for runtime manifest generation
1030
+ __basename: basename,
1031
+
1032
+ // Expose router-level boundary defaults for build-time clientChunks
1033
+ // discovery (so a "use client" default boundary lands in app-fallback).
1034
+ // These are createRouter options, never pushed onto EntryData.
1035
+ __defaultErrorBoundary: defaultErrorBoundary,
1036
+ __defaultNotFoundBoundary: defaultNotFoundBoundary,
1037
+ __notFound: notFound,
1038
+
961
1039
  // RSC request handler (lazily created on first call)
962
1040
  fetch: (() => {
963
1041
  // Handler is created on first call and reused
@@ -975,8 +1053,10 @@ export function createRouter<TEnv = any>(
975
1053
  if (!handler) {
976
1054
  // Lazy import deferred to first request to avoid dev mode issues
977
1055
  const { createRSCHandler } = await import("./rsc/handler.js");
978
- // Cast: handler.ts still accepts (request, env) will be updated
979
- // separately to accept RouterRequestInput.
1056
+ // Cast: createRSCHandler receives `router as any`, which erases TEnv
1057
+ // and infers its handler as RouterRequestInput<unknown>. Re-narrow the
1058
+ // returned handler to RouterRequestInput<TEnv> so the call below stays
1059
+ // typed. (The handler already accepts (request, RouterRequestInput).)
980
1060
  handler = createRSCHandler({
981
1061
  router: router as any,
982
1062
  cache,
@@ -991,6 +1071,10 @@ export function createRouter<TEnv = any>(
991
1071
  };
992
1072
  })(),
993
1073
 
1074
+ // Low-level route matching for request classification
1075
+ findMatch: (pathname: string, metricsStore?: any) =>
1076
+ findMatch(pathname, metricsStore),
1077
+
994
1078
  // Debug utility for manifest inspection
995
1079
  debugManifest: () => buildDebugManifest<TEnv>(routesEntries),
996
1080
  };
@@ -999,8 +1083,10 @@ export function createRouter<TEnv = any>(
999
1083
  RouterRegistry.set(routerId, router);
1000
1084
 
1001
1085
  // If urls option was provided, auto-register them
1002
- if (urlsOption) {
1003
- return router.routes(urlsOption) as RSCRouter<TEnv, {}>;
1086
+ if (typeof urlsOption === "function") {
1087
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1088
+ } else if (urlsOption) {
1089
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1004
1090
  }
1005
1091
 
1006
1092
  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
  /**