@rangojs/router 0.0.0-experimental.eb0645d3 → 0.0.0-experimental.f1468e3c

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 (392) hide show
  1. package/AGENTS.md +8 -0
  2. package/README.md +126 -16
  3. package/dist/bin/rango.js +319 -95
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +2724 -1053
  6. package/package.json +68 -14
  7. package/skills/api-client/SKILL.md +211 -0
  8. package/skills/breadcrumbs/SKILL.md +64 -2
  9. package/skills/bundle-analysis/SKILL.md +159 -0
  10. package/skills/cache-guide/SKILL.md +224 -32
  11. package/skills/caching/SKILL.md +279 -17
  12. package/skills/composability/SKILL.md +27 -3
  13. package/skills/css/SKILL.md +76 -0
  14. package/skills/debug-manifest/SKILL.md +4 -2
  15. package/skills/document-cache/SKILL.md +78 -55
  16. package/skills/handler-use/SKILL.md +11 -9
  17. package/skills/hooks/SKILL.md +243 -29
  18. package/skills/host-router/SKILL.md +83 -23
  19. package/skills/i18n/SKILL.md +276 -0
  20. package/skills/intercept/SKILL.md +68 -19
  21. package/skills/layout/SKILL.md +13 -9
  22. package/skills/links/SKILL.md +190 -23
  23. package/skills/loader/SKILL.md +235 -9
  24. package/skills/middleware/SKILL.md +18 -10
  25. package/skills/migrate-nextjs/SKILL.md +43 -19
  26. package/skills/migrate-react-router/SKILL.md +8 -2
  27. package/skills/mime-routes/SKILL.md +28 -1
  28. package/skills/observability/SKILL.md +172 -0
  29. package/skills/parallel/SKILL.md +18 -7
  30. package/skills/prerender/SKILL.md +65 -60
  31. package/skills/rango/SKILL.md +251 -24
  32. package/skills/react-compiler/SKILL.md +168 -0
  33. package/skills/response-routes/SKILL.md +115 -48
  34. package/skills/route/SKILL.md +46 -5
  35. package/skills/router-setup/SKILL.md +30 -8
  36. package/skills/scripts/SKILL.md +179 -0
  37. package/skills/server-actions/SKILL.md +775 -0
  38. package/skills/tailwind/SKILL.md +27 -3
  39. package/skills/testing/SKILL.md +130 -0
  40. package/skills/testing/bindings.md +103 -0
  41. package/skills/testing/cache-prerender.md +127 -0
  42. package/skills/testing/client-components.md +124 -0
  43. package/skills/testing/e2e-parity.md +125 -0
  44. package/skills/testing/flight.md +91 -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 +122 -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 +123 -0
  54. package/skills/typesafety/SKILL.md +322 -29
  55. package/skills/use-cache/SKILL.md +57 -14
  56. package/skills/view-transitions/SKILL.md +337 -0
  57. package/src/__augment-tests__/augment.ts +81 -0
  58. package/src/__augment-tests__/augmented.check.ts +116 -0
  59. package/src/__internal.ts +0 -65
  60. package/src/browser/action-coordinator.ts +53 -36
  61. package/src/browser/action-fence.ts +47 -0
  62. package/src/browser/app-shell.ts +39 -0
  63. package/src/browser/connection-warmup.ts +134 -0
  64. package/src/browser/cookie-name.ts +140 -0
  65. package/src/browser/event-controller.ts +192 -150
  66. package/src/browser/history-state.ts +21 -0
  67. package/src/browser/index.ts +3 -3
  68. package/src/browser/invalidate-client-cache.ts +52 -0
  69. package/src/browser/navigation-bridge.ts +94 -25
  70. package/src/browser/navigation-client.ts +121 -84
  71. package/src/browser/navigation-store-handle.ts +38 -0
  72. package/src/browser/navigation-store.ts +115 -67
  73. package/src/browser/navigation-transaction.ts +9 -59
  74. package/src/browser/network-error-handler.ts +34 -7
  75. package/src/browser/partial-update.ts +147 -128
  76. package/src/browser/prefetch/cache.ts +107 -56
  77. package/src/browser/prefetch/fetch.ts +204 -34
  78. package/src/browser/prefetch/queue.ts +6 -3
  79. package/src/browser/rango-state.ts +158 -76
  80. package/src/browser/react/Link.tsx +30 -7
  81. package/src/browser/react/NavigationProvider.tsx +283 -118
  82. package/src/browser/react/ScrollRestoration.tsx +10 -6
  83. package/src/browser/react/deferred-handle-resolution.ts +75 -0
  84. package/src/browser/react/filter-segment-order.ts +66 -7
  85. package/src/browser/react/index.ts +0 -48
  86. package/src/browser/react/location-state-shared.ts +178 -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 +17 -14
  90. package/src/browser/react/use-href.tsx +8 -1
  91. package/src/browser/react/use-link-status.ts +33 -8
  92. package/src/browser/react/use-navigation.ts +10 -5
  93. package/src/browser/react/use-params.ts +11 -11
  94. package/src/browser/react/use-reverse.ts +106 -0
  95. package/src/browser/react/use-router.ts +25 -3
  96. package/src/browser/react/use-search-params.ts +0 -5
  97. package/src/browser/react/use-segments.ts +11 -21
  98. package/src/browser/response-adapter.ts +99 -8
  99. package/src/browser/rsc-router.tsx +91 -24
  100. package/src/browser/scroll-restoration.ts +30 -17
  101. package/src/browser/segment-structure-assert.ts +2 -2
  102. package/src/browser/server-action-bridge.ts +214 -55
  103. package/src/browser/types.ts +80 -9
  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 +60 -35
  107. package/src/build/generate-route-types.ts +2 -1
  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 +117 -14
  111. package/src/build/route-types/ast-route-extraction.ts +15 -8
  112. package/src/build/route-types/codegen.ts +16 -5
  113. package/src/build/route-types/include-resolution.ts +117 -23
  114. package/src/build/route-types/param-extraction.ts +6 -3
  115. package/src/build/route-types/per-module-writer.ts +22 -6
  116. package/src/build/route-types/router-processing.ts +55 -28
  117. package/src/build/route-types/scan-filter.ts +1 -1
  118. package/src/build/route-types/source-scan.ts +216 -0
  119. package/src/build/runtime-discovery.ts +9 -20
  120. package/src/cache/cache-error.ts +104 -0
  121. package/src/cache/cache-key-utils.ts +29 -13
  122. package/src/cache/cache-policy.ts +108 -34
  123. package/src/cache/cache-runtime.ts +224 -41
  124. package/src/cache/cache-scope.ts +188 -82
  125. package/src/cache/cache-tag.ts +103 -0
  126. package/src/cache/cf/cf-base64.ts +33 -0
  127. package/src/cache/cf/cf-cache-constants.ts +127 -0
  128. package/src/cache/cf/cf-cache-store.ts +1989 -378
  129. package/src/cache/cf/cf-cache-types.ts +349 -0
  130. package/src/cache/cf/cf-kv-utils.ts +46 -0
  131. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  132. package/src/cache/cf/index.ts +6 -16
  133. package/src/cache/document-cache.ts +89 -21
  134. package/src/cache/handle-snapshot.ts +70 -0
  135. package/src/cache/index.ts +10 -20
  136. package/src/cache/memory-segment-store.ts +136 -37
  137. package/src/cache/profile-registry.ts +46 -31
  138. package/src/cache/read-through-swr.ts +56 -12
  139. package/src/cache/segment-codec.ts +9 -17
  140. package/src/cache/tag-invalidation.ts +230 -0
  141. package/src/cache/types.ts +37 -100
  142. package/src/client.rsc.tsx +44 -21
  143. package/src/client.tsx +36 -61
  144. package/src/cloudflare/index.ts +11 -0
  145. package/src/cloudflare/tracing.ts +109 -0
  146. package/src/component-utils.ts +19 -0
  147. package/src/components/DefaultDocument.tsx +8 -2
  148. package/src/context-var.ts +18 -6
  149. package/src/decode-loader-results.ts +52 -0
  150. package/src/defer.ts +196 -0
  151. package/src/deps/ssr.ts +0 -1
  152. package/src/encode-kv.ts +49 -0
  153. package/src/errors.ts +30 -4
  154. package/src/escape-script.ts +52 -0
  155. package/src/handle.ts +31 -23
  156. package/src/handles/MetaTags.tsx +62 -19
  157. package/src/handles/Scripts.tsx +183 -0
  158. package/src/handles/breadcrumbs.ts +37 -8
  159. package/src/handles/is-thenable.ts +19 -0
  160. package/src/handles/meta.ts +51 -40
  161. package/src/handles/script.ts +244 -0
  162. package/src/host/cookie-handler.ts +9 -60
  163. package/src/host/errors.ts +0 -24
  164. package/src/host/index.ts +8 -2
  165. package/src/host/pattern-matcher.ts +23 -52
  166. package/src/host/router.ts +107 -99
  167. package/src/host/testing.ts +40 -27
  168. package/src/host/types.ts +37 -4
  169. package/src/host/utils.ts +1 -1
  170. package/src/href-client.ts +137 -22
  171. package/src/index.rsc.ts +96 -12
  172. package/src/index.ts +94 -14
  173. package/src/internal-debug.ts +11 -10
  174. package/src/loader-store.ts +500 -0
  175. package/src/loader.rsc.ts +20 -13
  176. package/src/loader.ts +12 -11
  177. package/src/missing-id-error.ts +68 -0
  178. package/src/outlet-context.ts +1 -1
  179. package/src/outlet-provider.tsx +1 -5
  180. package/src/prerender/param-hash.ts +16 -16
  181. package/src/prerender/store.ts +32 -37
  182. package/src/prerender.ts +61 -6
  183. package/src/redirect-origin.ts +100 -0
  184. package/src/regex-escape.ts +8 -0
  185. package/src/render-error-thrower.tsx +20 -0
  186. package/src/response-utils.ts +34 -0
  187. package/src/reverse.ts +65 -40
  188. package/src/root-error-boundary.tsx +1 -19
  189. package/src/route-content-wrapper.tsx +19 -77
  190. package/src/route-definition/dsl-helpers.ts +304 -309
  191. package/src/route-definition/helper-factories.ts +28 -140
  192. package/src/route-definition/helpers-types.ts +82 -55
  193. package/src/route-definition/index.ts +1 -2
  194. package/src/route-definition/redirect.ts +44 -11
  195. package/src/route-definition/resolve-handler-use.ts +12 -1
  196. package/src/route-definition/use-item-types.ts +29 -0
  197. package/src/route-map-builder.ts +0 -16
  198. package/src/route-types.ts +19 -46
  199. package/src/router/basename.ts +14 -0
  200. package/src/router/content-negotiation.ts +73 -25
  201. package/src/router/error-handling.ts +45 -18
  202. package/src/router/find-match.ts +44 -23
  203. package/src/router/handler-context.ts +27 -43
  204. package/src/router/instrument.ts +350 -0
  205. package/src/router/intercept-resolution.ts +39 -20
  206. package/src/router/lazy-includes.ts +10 -47
  207. package/src/router/loader-resolution.ts +155 -72
  208. package/src/router/logging.ts +0 -6
  209. package/src/router/manifest.ts +18 -29
  210. package/src/router/match-api.ts +9 -24
  211. package/src/router/match-context.ts +0 -22
  212. package/src/router/match-handlers.ts +58 -58
  213. package/src/router/match-middleware/background-revalidation.ts +40 -24
  214. package/src/router/match-middleware/cache-lookup.ts +159 -285
  215. package/src/router/match-middleware/cache-store.ts +64 -52
  216. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  217. package/src/router/match-middleware/segment-resolution.ts +0 -22
  218. package/src/router/match-pipelines.ts +1 -42
  219. package/src/router/match-result.ts +44 -74
  220. package/src/router/metrics.ts +0 -34
  221. package/src/router/middleware-types.ts +7 -134
  222. package/src/router/middleware.ts +247 -166
  223. package/src/router/navigation-snapshot.ts +0 -51
  224. package/src/router/params-util.ts +23 -0
  225. package/src/router/pattern-matching.ts +85 -94
  226. package/src/router/prefetch-cache-ttl.ts +51 -0
  227. package/src/router/prerender-match.ts +104 -65
  228. package/src/router/preview-match.ts +3 -1
  229. package/src/router/request-classification.ts +28 -62
  230. package/src/router/revalidation.ts +123 -73
  231. package/src/router/route-snapshot.ts +0 -1
  232. package/src/router/router-context.ts +3 -28
  233. package/src/router/router-interfaces.ts +83 -35
  234. package/src/router/router-options.ts +136 -5
  235. package/src/router/router-registry.ts +2 -5
  236. package/src/router/segment-resolution/fresh.ts +97 -84
  237. package/src/router/segment-resolution/helpers.ts +86 -6
  238. package/src/router/segment-resolution/loader-cache.ts +76 -39
  239. package/src/router/segment-resolution/revalidation.ts +272 -320
  240. package/src/router/segment-resolution/static-store.ts +19 -5
  241. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  242. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  243. package/src/router/segment-resolution.ts +5 -1
  244. package/src/router/segment-wrappers.ts +6 -5
  245. package/src/router/state-cookie-name.ts +33 -0
  246. package/src/router/substitute-pattern-params.ts +56 -0
  247. package/src/router/telemetry-otel.ts +161 -199
  248. package/src/router/telemetry.ts +96 -19
  249. package/src/router/timeout.ts +0 -20
  250. package/src/router/tracing.ts +206 -0
  251. package/src/router/trie-matching.ts +162 -64
  252. package/src/router/types.ts +9 -63
  253. package/src/router/url-params.ts +0 -5
  254. package/src/router.ts +110 -55
  255. package/src/rsc/handler-context.ts +3 -2
  256. package/src/rsc/handler.ts +264 -220
  257. package/src/rsc/helpers.ts +100 -6
  258. package/src/rsc/index.ts +2 -5
  259. package/src/rsc/json-route-result.ts +38 -0
  260. package/src/rsc/loader-fetch.ts +114 -38
  261. package/src/rsc/manifest-init.ts +28 -41
  262. package/src/rsc/origin-guard.ts +39 -25
  263. package/src/rsc/progressive-enhancement.ts +117 -11
  264. package/src/rsc/redirect-guard.ts +99 -0
  265. package/src/rsc/response-cache-serve.ts +238 -0
  266. package/src/rsc/response-error.ts +79 -12
  267. package/src/rsc/response-route-handler.ts +88 -188
  268. package/src/rsc/rsc-rendering.ts +98 -76
  269. package/src/rsc/runtime-warnings.ts +23 -10
  270. package/src/rsc/server-action.ts +281 -117
  271. package/src/rsc/ssr-setup.ts +16 -0
  272. package/src/rsc/transition-gate.ts +89 -0
  273. package/src/rsc/types.ts +23 -5
  274. package/src/runtime-env.ts +18 -0
  275. package/src/search-params.ts +35 -30
  276. package/src/segment-loader-promise.ts +31 -4
  277. package/src/segment-system.tsx +254 -143
  278. package/src/serialize.ts +243 -0
  279. package/src/server/context.ts +163 -51
  280. package/src/server/cookie-parse.ts +32 -0
  281. package/src/server/cookie-store.ts +80 -5
  282. package/src/server/handle-store.ts +21 -38
  283. package/src/server/loader-registry.ts +33 -42
  284. package/src/server/request-context.ts +287 -178
  285. package/src/ssr/index.tsx +21 -16
  286. package/src/static-handler.ts +10 -13
  287. package/src/testing/cache-status.ts +162 -0
  288. package/src/testing/collect-handle.ts +40 -0
  289. package/src/testing/dispatch.ts +701 -0
  290. package/src/testing/dom.entry.ts +22 -0
  291. package/src/testing/e2e/fixture.ts +188 -0
  292. package/src/testing/e2e/index.ts +128 -0
  293. package/src/testing/e2e/matchers.ts +35 -0
  294. package/src/testing/e2e/page-helpers.ts +272 -0
  295. package/src/testing/e2e/parity.ts +387 -0
  296. package/src/testing/e2e/server.ts +195 -0
  297. package/src/testing/flight-matchers.ts +97 -0
  298. package/src/testing/flight-normalize.ts +11 -0
  299. package/src/testing/flight-runtime.d.ts +57 -0
  300. package/src/testing/flight-tree.ts +682 -0
  301. package/src/testing/flight.entry.ts +52 -0
  302. package/src/testing/flight.ts +257 -0
  303. package/src/testing/generated-routes.ts +183 -0
  304. package/src/testing/index.ts +105 -0
  305. package/src/testing/internal/context.ts +371 -0
  306. package/src/testing/internal/flight-client-globals.ts +30 -0
  307. package/src/testing/internal/seed-vars.ts +54 -0
  308. package/src/testing/render-handler.ts +357 -0
  309. package/src/testing/render-route.tsx +581 -0
  310. package/src/testing/run-loader.ts +385 -0
  311. package/src/testing/run-middleware.ts +205 -0
  312. package/src/testing/run-transition-when.ts +164 -0
  313. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  314. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  315. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  316. package/src/testing/vitest-stubs/version.ts +5 -0
  317. package/src/testing/vitest.ts +305 -0
  318. package/src/theme/ThemeProvider.tsx +20 -58
  319. package/src/theme/ThemeScript.tsx +7 -9
  320. package/src/theme/constants.ts +52 -13
  321. package/src/theme/index.ts +0 -7
  322. package/src/theme/theme-context.ts +1 -5
  323. package/src/theme/theme-script.ts +22 -21
  324. package/src/theme/use-theme.ts +0 -3
  325. package/src/types/boundaries.ts +0 -35
  326. package/src/types/cache-types.ts +13 -4
  327. package/src/types/error-types.ts +30 -90
  328. package/src/types/global-namespace.ts +54 -41
  329. package/src/types/handler-context.ts +110 -62
  330. package/src/types/index.ts +3 -10
  331. package/src/types/loader-types.ts +11 -9
  332. package/src/types/request-scope.ts +112 -0
  333. package/src/types/route-config.ts +6 -50
  334. package/src/types/route-entry.ts +0 -6
  335. package/src/types/segments.ts +135 -14
  336. package/src/urls/include-helper.ts +9 -56
  337. package/src/urls/index.ts +1 -11
  338. package/src/urls/path-helper-types.ts +29 -12
  339. package/src/urls/path-helper.ts +17 -106
  340. package/src/urls/pattern-types.ts +36 -19
  341. package/src/urls/response-types.ts +22 -29
  342. package/src/urls/type-extraction.ts +58 -139
  343. package/src/urls/urls-function.ts +1 -19
  344. package/src/use-loader.tsx +292 -107
  345. package/src/vite/debug.ts +185 -0
  346. package/src/vite/discovery/bundle-postprocess.ts +8 -7
  347. package/src/vite/discovery/discover-routers.ts +126 -85
  348. package/src/vite/discovery/discovery-errors.ts +194 -0
  349. package/src/vite/discovery/gate-state.ts +171 -0
  350. package/src/vite/discovery/prerender-collection.ts +96 -68
  351. package/src/vite/discovery/route-types-writer.ts +40 -84
  352. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  353. package/src/vite/discovery/state.ts +44 -0
  354. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  355. package/src/vite/index.ts +2 -0
  356. package/src/vite/inject-client-debug.ts +36 -0
  357. package/src/vite/plugin-types.ts +126 -8
  358. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  359. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  360. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  361. package/src/vite/plugins/cloudflare-protocol-stub.ts +1 -21
  362. package/src/vite/plugins/expose-action-id.ts +48 -95
  363. package/src/vite/plugins/expose-id-utils.ts +88 -55
  364. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  365. package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
  366. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  367. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  368. package/src/vite/plugins/expose-internal-ids.ts +505 -486
  369. package/src/vite/plugins/performance-tracks.ts +26 -25
  370. package/src/vite/plugins/refresh-cmd.ts +1 -1
  371. package/src/vite/plugins/use-cache-transform.ts +73 -83
  372. package/src/vite/plugins/version-injector.ts +40 -29
  373. package/src/vite/plugins/version-plugin.ts +37 -40
  374. package/src/vite/plugins/virtual-entries.ts +39 -25
  375. package/src/vite/rango.ts +109 -118
  376. package/src/vite/router-discovery.ts +718 -119
  377. package/src/vite/utils/ast-handler-extract.ts +26 -35
  378. package/src/vite/utils/banner.ts +1 -1
  379. package/src/vite/utils/bundle-analysis.ts +10 -15
  380. package/src/vite/utils/client-chunks.ts +184 -0
  381. package/src/vite/utils/directive-prologue.ts +40 -0
  382. package/src/vite/utils/forward-user-plugins.ts +171 -0
  383. package/src/vite/utils/manifest-utils.ts +4 -59
  384. package/src/vite/utils/package-resolution.ts +20 -52
  385. package/src/vite/utils/prerender-utils.ts +54 -39
  386. package/src/vite/utils/shared-utils.ts +90 -41
  387. package/src/browser/action-response-classifier.ts +0 -99
  388. package/src/browser/react/use-client-cache.ts +0 -58
  389. package/src/browser/shallow.ts +0 -40
  390. package/src/handles/index.ts +0 -7
  391. package/src/network-error-thrower.tsx +0 -23
  392. 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";
@@ -21,11 +18,11 @@ import type { AllUseItems } from "./route-types.js";
21
18
  import type { UrlPatterns } from "./urls.js";
22
19
  import type { UrlBuilder } from "./urls/pattern-types.js";
23
20
  import { urls } from "./urls.js";
21
+ import { buildPrecomputedByPrefix } from "./build/prefix-tree-utils.js";
24
22
  import {
25
- EntryData,
26
- InterceptSelectorContext,
23
+ type EntryData,
27
24
  getContext,
28
- RSCRouterContext,
25
+ RangoContext,
29
26
  type MetricsStore,
30
27
  } from "./server/context";
31
28
  import { createHandleStore, type HandleStore } from "./server/handle-store.js";
@@ -57,6 +54,7 @@ import { buildDebugManifest } from "./router/debug-manifest.js";
57
54
 
58
55
  import type { SegmentResolutionDeps, MatchApiDeps } from "./router/types.js";
59
56
  import { createHandlerContext } from "./router/handler-context.js";
57
+ import { normalizeBasename } from "./router/basename.js";
60
58
  import {
61
59
  setupLoaderAccess,
62
60
  setupLoaderAccessSilent,
@@ -65,15 +63,17 @@ import {
65
63
  import { loadManifest } from "./router/manifest.js";
66
64
  import { createMetricsStore } from "./router/metrics.js";
67
65
  import {
68
- parsePattern,
66
+ compileMiddlewarePattern,
69
67
  type MiddlewareEntry,
70
68
  type MiddlewareFn,
71
69
  } from "./router/middleware.js";
72
70
  import {
73
71
  extractStaticPrefix,
72
+ joinPrefix,
74
73
  traverseBack,
75
74
  } from "./router/pattern-matching.js";
76
75
  import { resolveSink, safeEmit, getRequestId } from "./router/telemetry.js";
76
+ import { resolveTracing } from "./router/tracing.js";
77
77
  import { evaluateRevalidation } from "./router/revalidation.js";
78
78
  import {
79
79
  type RouterContext,
@@ -91,13 +91,10 @@ import {
91
91
  RouterRegistry,
92
92
  nextRouterAutoId,
93
93
  } from "./router/router-registry.js";
94
+ import type { RangoOptions, RootLayoutProps } from "./router/router-options.js";
94
95
  import type {
95
- RSCRouterOptions,
96
- RootLayoutProps,
97
- } from "./router/router-options.js";
98
- import type {
99
- RSCRouter,
100
- RSCRouterInternal,
96
+ Rango,
97
+ RangoInternal,
101
98
  RouterRequestInput,
102
99
  } from "./router/router-interfaces.js";
103
100
 
@@ -112,26 +109,28 @@ import {
112
109
  matchForPrerender as _matchForPrerender,
113
110
  renderStaticSegment as _renderStaticSegment,
114
111
  } from "./router/prerender-match.js";
112
+ import { resolveStateCookieName } from "./router/state-cookie-name.js";
113
+ import { resolvePrefetchCacheTTL } from "./router/prefetch-cache-ttl.js";
115
114
 
116
115
  // Re-export public types and values from extracted modules
117
116
  export { RSC_ROUTER_BRAND, RouterRegistry } from "./router/router-registry.js";
118
117
  export type {
119
- RSCRouterOptions,
118
+ RangoOptions,
120
119
  RootLayoutProps,
121
120
  SSRStreamMode,
122
121
  SSROptions,
123
122
  ResolveStreamingContext,
124
123
  } from "./router/router-options.js";
125
124
  export type {
126
- RSCRouter,
127
- RSCRouterInternal,
125
+ Rango,
126
+ RangoInternal,
128
127
  RouterRequestInput,
129
128
  } from "./router/router-interfaces.js";
130
129
  export { toInternal } from "./router/router-interfaces.js";
131
130
 
132
131
  export function createRouter<TEnv = any>(
133
- options: RSCRouterOptions<TEnv> = {},
134
- ): RSCRouter<TEnv, {}> {
132
+ options: RangoOptions<TEnv> = {},
133
+ ): Rango<TEnv, {}> {
135
134
  const {
136
135
  id: userProvidedId,
137
136
  $$id: injectedId,
@@ -151,31 +150,46 @@ export function createRouter<TEnv = any>(
151
150
  nonce,
152
151
  version,
153
152
  prefetchCacheTTL: prefetchCacheTTLOption,
153
+ stateCookiePrefix: stateCookiePrefixOption,
154
154
  warmup: warmupOption,
155
155
  allowDebugManifest: allowDebugManifestOption = false,
156
156
  telemetry: telemetrySink,
157
+ tracing: tracingOption,
157
158
  ssr: ssrOption,
158
159
  timeout: timeoutShorthand,
159
160
  timeouts: timeoutsOption,
160
161
  onTimeout,
161
162
  originCheck: originCheckOption,
163
+ viewTransition: viewTransitionOption = "auto",
164
+ debugCacheSignal: debugCacheSignalOption = false,
165
+ strictMode: strictModeOption = true,
162
166
  } = options;
163
167
 
168
+ // Debug cache signal gate (DEVELOPMENT/TEST ONLY). Enabled by the
169
+ // debugCacheSignal option OR the RANGO_TEST_SIGNALS=1 env flag. When off,
170
+ // no X-Rango-Cache header is emitted and output is byte-identical.
171
+ const cacheSignalEnabled =
172
+ debugCacheSignalOption ||
173
+ (typeof process !== "undefined" &&
174
+ (process as { env?: Record<string, string | undefined> }).env
175
+ ?.RANGO_TEST_SIGNALS === "1");
176
+
164
177
  // Normalize basename: ensure leading slash, strip trailing slash.
165
- // A bare "/" is equivalent to no basename.
166
- const basename =
167
- basenameOption && basenameOption.replace(/^\/+|\/+$/g, "")
168
- ? "/" + basenameOption.replace(/^\/+|\/+$/g, "")
169
- : undefined;
178
+ // A bare "/" is equivalent to no basename. Shared with the testing
179
+ // primitives via normalizeBasename so they can never drift.
180
+ const basename = normalizeBasename(basenameOption);
170
181
 
171
182
  // Resolve telemetry sink (no-op when not configured)
172
183
  const telemetry = resolveSink(telemetrySink);
173
184
 
174
- // Resolve cache profiles: merge user config with guaranteed default profile.
175
- // This resolved map is both stored on the router (for per-request context)
176
- // and written to the global registry (for DSL-time cache("profileName")).
185
+ // Resolve span tracing (undefined when not configured; every traceSpan() call
186
+ // is then a direct pass-through with zero behavior change).
187
+ const resolvedTracing = resolveTracing(tracingOption);
188
+
189
+ // Resolve cache profiles: merge user config with the guaranteed default
190
+ // profile. This resolved map is threaded onto each request context; the
191
+ // "use cache: <profile>" runtime path reads it request-scoped.
177
192
  const resolvedCacheProfiles = resolveCacheProfiles(cacheProfilesOption);
178
- setCacheProfiles(resolvedCacheProfiles);
179
193
 
180
194
  // Source file: prefer Vite-injected path (zero cost), fall back to
181
195
  // stack trace parsing for non-Vite environments (e.g. tests).
@@ -210,21 +224,32 @@ export function createRouter<TEnv = any>(
210
224
  const routerId =
211
225
  userProvidedId ?? injectedId ?? `router_${nextRouterAutoId()}`;
212
226
 
213
- // Resolve prefetch cache TTL (default: 300 seconds / 5 minutes)
214
- // Clamp to a non-negative integer for valid Cache-Control max-age.
215
- const rawTTL =
216
- prefetchCacheTTLOption !== undefined ? prefetchCacheTTLOption : 300;
217
- const prefetchCacheTTLSeconds =
218
- rawTTL === false ? 0 : Math.max(0, Math.floor(rawTTL));
219
- const prefetchCacheTTL = prefetchCacheTTLSeconds * 1000;
227
+ // Resolve the rango state cookie name once, here, so the two cookie writers
228
+ // (the client document.cookie writer and the server Set-Cookie writer)
229
+ // consume one pre-composed name and cannot drift.
230
+ const resolvedStateCookieName = resolveStateCookieName(
231
+ stateCookiePrefixOption,
232
+ routerId,
233
+ );
234
+
235
+ // Resolve prefetch cache TTL (default: 300 seconds / 5 minutes). Clamps to a
236
+ // non-negative integer and guards non-finite (NaN/Infinity) inputs so a
237
+ // malformed `Cache-Control: max-age=NaN` can never reach the wire.
238
+ const resolvedPrefetchCacheTTL = resolvePrefetchCacheTTL(
239
+ prefetchCacheTTLOption,
240
+ );
241
+ const prefetchCacheTTL = resolvedPrefetchCacheTTL.ms;
220
242
  const prefetchCacheControl: string | false =
221
- prefetchCacheTTLSeconds === 0
222
- ? false
223
- : `private, max-age=${prefetchCacheTTLSeconds}`;
243
+ resolvedPrefetchCacheTTL.cacheControl;
224
244
 
225
245
  // Resolve warmup enabled flag (default: true)
226
246
  const warmupEnabled = warmupOption !== false;
227
247
 
248
+ // Resolve StrictMode flag (default: true). Shipped to the client in payload
249
+ // metadata; the browser entry reads it once to decide whether to wrap the
250
+ // hydrated tree in React.StrictMode.
251
+ const strictMode = strictModeOption !== false;
252
+
228
253
  // Resolve theme config (null if theme not enabled)
229
254
  const resolvedThemeConfig = themeOption
230
255
  ? resolveThemeConfig(themeOption)
@@ -256,9 +281,14 @@ export function createRouter<TEnv = any>(
256
281
  invokeOnError(onError, error, phase, context, "Router");
257
282
  }
258
283
 
259
- // Validate document is a client component
284
+ // Validate document is a client component. Under a test runner the "use
285
+ // client" transform has not run, so a real exported document has no marker;
286
+ // allowServerInTest lets the router construct in a bare unit test (for
287
+ // dispatch / assertGeneratedRoutesMatch) while a real build still throws.
260
288
  if (documentOption !== undefined) {
261
- assertClientComponent(documentOption, "document");
289
+ assertClientComponent(documentOption, "document", {
290
+ allowServerInTest: true,
291
+ });
262
292
  }
263
293
 
264
294
  // Use default document if none provided (keeps internal name as rootLayout)
@@ -322,7 +352,7 @@ export function createRouter<TEnv = any>(
322
352
  let regex: RegExp | null = null;
323
353
  let paramNames: string[] = [];
324
354
  if (fullPattern) {
325
- const parsed = parsePattern(fullPattern);
355
+ const parsed = compileMiddlewarePattern(fullPattern);
326
356
  regex = parsed.regex;
327
357
  paramNames = parsed.paramNames;
328
358
  }
@@ -332,7 +362,6 @@ export function createRouter<TEnv = any>(
332
362
  regex,
333
363
  paramNames,
334
364
  handler,
335
- mountPrefix,
336
365
  });
337
366
  }
338
367
 
@@ -366,9 +395,11 @@ export function createRouter<TEnv = any>(
366
395
  getRouterPrecomputedEntries(routerId) ?? getPrecomputedEntries();
367
396
  if (current !== precomputedSource) {
368
397
  precomputedSource = current;
369
- precomputedByPrefix = current
370
- ? new Map(current.map((e) => [e.staticPrefix, e.routes]))
371
- : null;
398
+ // buildPrecomputedByPrefix drops any staticPrefix owned by more than one
399
+ // leaf include instead of collapsing it last-wins (which would mis-assign
400
+ // one include's routes to another's entry and 500 a valid sibling route).
401
+ // Such shared-prefix includes resolve via the handler path instead.
402
+ precomputedByPrefix = current ? buildPrecomputedByPrefix(current) : null;
372
403
  }
373
404
  return precomputedByPrefix;
374
405
  }
@@ -538,6 +569,7 @@ export function createRouter<TEnv = any>(
538
569
  findNearestNotFoundBoundary,
539
570
  notFoundComponent: notFound,
540
571
  callOnError,
572
+ viewTransitionDefault: viewTransitionOption,
541
573
  };
542
574
 
543
575
  // Match API dependencies
@@ -665,6 +697,7 @@ export function createRouter<TEnv = any>(
665
697
  findMatch,
666
698
  findInterceptForRoute,
667
699
  telemetry: telemetrySink,
700
+ cacheSignalEnabled,
668
701
  });
669
702
 
670
703
  const { match, matchPartial, matchError, previewMatch } = matchHandlers;
@@ -674,7 +707,7 @@ export function createRouter<TEnv = any>(
674
707
  * The type system tracks accumulated routes through the builder chain
675
708
  * Initial TRoutes is {} (empty) to avoid poisoning accumulated types with Record<string, string>
676
709
  */
677
- const router: RSCRouterInternal<TEnv, {}> = {
710
+ const router: RangoInternal<TEnv, {}> = {
678
711
  __brand: RSC_ROUTER_BRAND,
679
712
  id: routerId,
680
713
  basename,
@@ -722,7 +755,7 @@ export function createRouter<TEnv = any>(
722
755
  };
723
756
 
724
757
  let handlerResult: AllUseItems[] = [];
725
- RSCRouterContext.run(
758
+ RangoContext.run(
726
759
  {
727
760
  manifest,
728
761
  patterns: routePatterns,
@@ -834,10 +867,13 @@ export function createRouter<TEnv = any>(
834
867
 
835
868
  // Create placeholder RouteEntry for each lazy include
836
869
  for (const lazyInclude of lazyIncludes) {
837
- // Compute the full URL prefix (combining parent prefix if any)
838
- const fullPrefix = lazyInclude.context.urlPrefix
839
- ? lazyInclude.context.urlPrefix + lazyInclude.prefix
840
- : lazyInclude.prefix;
870
+ // Compute the full URL prefix (combining parent prefix if any). Use the
871
+ // slash-collapsing join so a trailing-slash parent prefix does not
872
+ // produce a double-slash staticPrefix the trie's sp can never match.
873
+ const fullPrefix = joinPrefix(
874
+ lazyInclude.context.urlPrefix,
875
+ lazyInclude.prefix,
876
+ );
841
877
 
842
878
  const lazyEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
843
879
  prefix: "",
@@ -933,12 +969,22 @@ export function createRouter<TEnv = any>(
933
969
  prefetchCacheControl,
934
970
  prefetchCacheTTL,
935
971
 
972
+ // Expose the resolved rango state cookie name for the server-side writer
973
+ // (invalidateClientCache) and for shipping to the client in metadata.
974
+ resolvedStateCookieName,
975
+
936
976
  // Expose warmup enabled flag for handler and client
937
977
  warmupEnabled,
938
978
 
979
+ // Expose StrictMode flag for the initial-render payload metadata
980
+ strictMode,
981
+
939
982
  // Expose router-wide performance debugging for request-level metrics setup
940
983
  debugPerformance,
941
984
 
985
+ // Expose resolved span tracing for the handler (Cloudflare custom spans)
986
+ tracing: resolvedTracing,
987
+
942
988
  // Expose debug manifest flag for handler
943
989
  allowDebugManifest: allowDebugManifestOption,
944
990
 
@@ -1000,6 +1046,13 @@ export function createRouter<TEnv = any>(
1000
1046
  // Expose basename for runtime manifest generation
1001
1047
  __basename: basename,
1002
1048
 
1049
+ // Expose router-level boundary defaults for build-time clientChunks
1050
+ // discovery (so a "use client" default boundary lands in app-fallback).
1051
+ // These are createRouter options, never pushed onto EntryData.
1052
+ __defaultErrorBoundary: defaultErrorBoundary,
1053
+ __defaultNotFoundBoundary: defaultNotFoundBoundary,
1054
+ __notFound: notFound,
1055
+
1003
1056
  // RSC request handler (lazily created on first call)
1004
1057
  fetch: (() => {
1005
1058
  // Handler is created on first call and reused
@@ -1017,8 +1070,10 @@ export function createRouter<TEnv = any>(
1017
1070
  if (!handler) {
1018
1071
  // Lazy import deferred to first request to avoid dev mode issues
1019
1072
  const { createRSCHandler } = await import("./rsc/handler.js");
1020
- // Cast: handler.ts still accepts (request, env) will be updated
1021
- // separately to accept RouterRequestInput.
1073
+ // Cast: createRSCHandler receives `router as any`, which erases TEnv
1074
+ // and infers its handler as RouterRequestInput<unknown>. Re-narrow the
1075
+ // returned handler to RouterRequestInput<TEnv> so the call below stays
1076
+ // typed. (The handler already accepts (request, RouterRequestInput).)
1022
1077
  handler = createRSCHandler({
1023
1078
  router: router as any,
1024
1079
  cache,
@@ -1046,9 +1101,9 @@ export function createRouter<TEnv = any>(
1046
1101
 
1047
1102
  // If urls option was provided, auto-register them
1048
1103
  if (typeof urlsOption === "function") {
1049
- return router.routes(urlsOption) as RSCRouter<TEnv, {}>;
1104
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1050
1105
  } else if (urlsOption) {
1051
- return router.routes(urlsOption) as RSCRouter<TEnv, {}>;
1106
+ return router.routes(urlsOption) as Rango<TEnv, {}>;
1052
1107
  }
1053
1108
 
1054
1109
  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
  /**