@rangojs/router 0.0.0-experimental.97 → 0.0.0-experimental.98914650

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 (356) hide show
  1. package/README.md +24 -9
  2. package/dist/bin/rango.js +157 -63
  3. package/dist/testing/vitest.js +82 -0
  4. package/dist/vite/index.js +1584 -639
  5. package/package.json +71 -21
  6. package/skills/api-client/SKILL.md +211 -0
  7. package/skills/breadcrumbs/SKILL.md +60 -0
  8. package/skills/bundle-analysis/SKILL.md +159 -0
  9. package/skills/cache-guide/SKILL.md +222 -30
  10. package/skills/caching/SKILL.md +263 -8
  11. package/skills/composability/SKILL.md +27 -2
  12. package/skills/css/SKILL.md +76 -0
  13. package/skills/document-cache/SKILL.md +78 -55
  14. package/skills/handler-use/SKILL.md +3 -1
  15. package/skills/hooks/SKILL.md +235 -28
  16. package/skills/host-router/SKILL.md +122 -22
  17. package/skills/i18n/SKILL.md +276 -0
  18. package/skills/intercept/SKILL.md +29 -5
  19. package/skills/layout/SKILL.md +13 -9
  20. package/skills/links/SKILL.md +173 -17
  21. package/skills/loader/SKILL.md +170 -23
  22. package/skills/middleware/SKILL.md +16 -10
  23. package/skills/migrate-nextjs/SKILL.md +38 -16
  24. package/skills/mime-routes/SKILL.md +27 -0
  25. package/skills/observability/SKILL.md +137 -0
  26. package/skills/parallel/SKILL.md +11 -7
  27. package/skills/prerender/SKILL.md +14 -33
  28. package/skills/rango/SKILL.md +250 -25
  29. package/skills/react-compiler/SKILL.md +168 -0
  30. package/skills/response-routes/SKILL.md +114 -47
  31. package/skills/route/SKILL.md +42 -5
  32. package/skills/router-setup/SKILL.md +3 -3
  33. package/skills/server-actions/SKILL.md +78 -42
  34. package/skills/tailwind/SKILL.md +27 -3
  35. package/skills/testing/SKILL.md +129 -0
  36. package/skills/testing/bindings.md +89 -0
  37. package/skills/testing/cache-prerender.md +124 -0
  38. package/skills/testing/client-components.md +122 -0
  39. package/skills/testing/e2e-parity.md +125 -0
  40. package/skills/testing/flight.md +92 -0
  41. package/skills/testing/handles.md +129 -0
  42. package/skills/testing/loader.md +128 -0
  43. package/skills/testing/middleware.md +99 -0
  44. package/skills/testing/render-handler.md +121 -0
  45. package/skills/testing/response-routes.md +95 -0
  46. package/skills/testing/reverse-and-types.md +84 -0
  47. package/skills/testing/server-actions.md +107 -0
  48. package/skills/testing/server-tree.md +128 -0
  49. package/skills/testing/setup.md +120 -0
  50. package/skills/typesafety/SKILL.md +316 -26
  51. package/skills/use-cache/SKILL.md +36 -5
  52. package/skills/vercel/SKILL.md +107 -0
  53. package/skills/view-transitions/SKILL.md +294 -0
  54. package/src/__augment-tests__/augment.ts +81 -0
  55. package/src/__augment-tests__/augmented.check.ts +116 -0
  56. package/src/__internal.ts +0 -65
  57. package/src/browser/action-coordinator.ts +53 -36
  58. package/src/browser/action-fence.ts +47 -0
  59. package/src/browser/app-shell.ts +14 -27
  60. package/src/browser/cookie-name.ts +140 -0
  61. package/src/browser/event-controller.ts +37 -143
  62. package/src/browser/history-state.ts +21 -0
  63. package/src/browser/index.ts +3 -3
  64. package/src/browser/invalidate-client-cache.ts +52 -0
  65. package/src/browser/navigation-bridge.ts +30 -59
  66. package/src/browser/navigation-client.ts +96 -84
  67. package/src/browser/navigation-store-handle.ts +38 -0
  68. package/src/browser/navigation-store.ts +32 -82
  69. package/src/browser/navigation-transaction.ts +9 -59
  70. package/src/browser/partial-update.ts +60 -127
  71. package/src/browser/prefetch/cache.ts +82 -72
  72. package/src/browser/prefetch/fetch.ts +108 -33
  73. package/src/browser/prefetch/queue.ts +6 -3
  74. package/src/browser/rango-state.ts +157 -115
  75. package/src/browser/react/Link.tsx +0 -2
  76. package/src/browser/react/NavigationProvider.tsx +41 -48
  77. package/src/browser/react/ScrollRestoration.tsx +10 -6
  78. package/src/browser/react/filter-segment-order.ts +0 -2
  79. package/src/browser/react/index.ts +0 -48
  80. package/src/browser/react/location-state-shared.ts +166 -8
  81. package/src/browser/react/location-state.ts +39 -14
  82. package/src/browser/react/use-action.ts +6 -15
  83. package/src/browser/react/use-handle.ts +17 -14
  84. package/src/browser/react/use-link-status.ts +0 -4
  85. package/src/browser/react/use-navigation.ts +0 -3
  86. package/src/browser/react/use-params.ts +11 -11
  87. package/src/browser/react/use-reverse.ts +106 -0
  88. package/src/browser/react/use-router.ts +20 -5
  89. package/src/browser/react/use-search-params.ts +0 -5
  90. package/src/browser/react/use-segments.ts +0 -13
  91. package/src/browser/response-adapter.ts +52 -1
  92. package/src/browser/rsc-router.tsx +70 -34
  93. package/src/browser/scroll-restoration.ts +22 -14
  94. package/src/browser/segment-structure-assert.ts +2 -2
  95. package/src/browser/server-action-bridge.ts +168 -44
  96. package/src/browser/types.ts +36 -21
  97. package/src/browser/validate-redirect-origin.ts +43 -16
  98. package/src/build/collect-fallback-refs.ts +107 -0
  99. package/src/build/generate-manifest.ts +60 -35
  100. package/src/build/generate-route-types.ts +3 -0
  101. package/src/build/index.ts +8 -2
  102. package/src/build/prefix-tree-utils.ts +123 -0
  103. package/src/build/route-trie.ts +89 -10
  104. package/src/build/route-types/codegen.ts +4 -4
  105. package/src/build/route-types/include-resolution.ts +1 -1
  106. package/src/build/route-types/param-extraction.ts +6 -3
  107. package/src/build/route-types/per-module-writer.ts +7 -4
  108. package/src/build/route-types/router-processing.ts +122 -22
  109. package/src/build/route-types/scan-filter.ts +1 -1
  110. package/src/build/route-types/source-scan.ts +118 -0
  111. package/src/build/runtime-discovery.ts +9 -20
  112. package/src/cache/cache-error.ts +104 -0
  113. package/src/cache/cache-policy.ts +68 -28
  114. package/src/cache/cache-runtime.ts +134 -32
  115. package/src/cache/cache-scope.ts +100 -74
  116. package/src/cache/cache-tag.ts +98 -0
  117. package/src/cache/cf/cf-cache-store.ts +2255 -238
  118. package/src/cache/cf/index.ts +6 -16
  119. package/src/cache/document-cache.ts +61 -20
  120. package/src/cache/handle-snapshot.ts +63 -0
  121. package/src/cache/index.ts +22 -20
  122. package/src/cache/memory-segment-store.ts +136 -37
  123. package/src/cache/profile-registry.ts +6 -30
  124. package/src/cache/read-through-swr.ts +41 -11
  125. package/src/cache/segment-codec.ts +0 -16
  126. package/src/cache/tag-invalidation.ts +230 -0
  127. package/src/cache/types.ts +33 -100
  128. package/src/cache/vercel/index.ts +11 -0
  129. package/src/cache/vercel/vercel-cache-store.ts +799 -0
  130. package/src/client.rsc.tsx +6 -21
  131. package/src/client.tsx +25 -61
  132. package/src/component-utils.ts +19 -0
  133. package/src/context-var.ts +17 -5
  134. package/src/decode-loader-results.ts +36 -0
  135. package/src/defer.ts +196 -0
  136. package/src/deps/ssr.ts +0 -1
  137. package/src/errors.ts +30 -4
  138. package/src/handle.ts +31 -23
  139. package/src/handles/MetaTags.tsx +0 -14
  140. package/src/handles/breadcrumbs.ts +16 -5
  141. package/src/handles/meta.ts +0 -39
  142. package/src/host/cookie-handler.ts +0 -36
  143. package/src/host/errors.ts +0 -24
  144. package/src/host/index.ts +8 -2
  145. package/src/host/pattern-matcher.ts +7 -50
  146. package/src/host/router.ts +107 -99
  147. package/src/host/testing.ts +40 -27
  148. package/src/host/types.ts +37 -4
  149. package/src/host/utils.ts +1 -1
  150. package/src/href-client.ts +137 -22
  151. package/src/index.rsc.ts +63 -9
  152. package/src/index.ts +64 -9
  153. package/src/internal-debug.ts +2 -4
  154. package/src/loader-store.ts +500 -0
  155. package/src/loader.rsc.ts +20 -13
  156. package/src/loader.ts +12 -11
  157. package/src/missing-id-error.ts +68 -0
  158. package/src/network-error-thrower.tsx +1 -6
  159. package/src/outlet-provider.tsx +1 -5
  160. package/src/prerender/param-hash.ts +10 -11
  161. package/src/prerender/store.ts +32 -37
  162. package/src/prerender.ts +61 -6
  163. package/src/redirect-origin.ts +100 -0
  164. package/src/response-utils.ts +9 -0
  165. package/src/reverse.ts +65 -40
  166. package/src/root-error-boundary.tsx +1 -19
  167. package/src/route-content-wrapper.tsx +7 -72
  168. package/src/route-definition/dsl-helpers.ts +244 -281
  169. package/src/route-definition/helper-factories.ts +29 -139
  170. package/src/route-definition/helpers-types.ts +40 -17
  171. package/src/route-definition/redirect.ts +43 -9
  172. package/src/route-definition/resolve-handler-use.ts +6 -0
  173. package/src/route-definition/use-item-types.ts +32 -0
  174. package/src/route-map-builder.ts +0 -16
  175. package/src/route-types.ts +19 -41
  176. package/src/router/basename.ts +14 -0
  177. package/src/router/content-negotiation.ts +15 -15
  178. package/src/router/error-handling.ts +13 -17
  179. package/src/router/find-match.ts +44 -23
  180. package/src/router/handler-context.ts +4 -41
  181. package/src/router/intercept-resolution.ts +14 -19
  182. package/src/router/lazy-includes.ts +9 -46
  183. package/src/router/loader-resolution.ts +91 -46
  184. package/src/router/logging.ts +0 -6
  185. package/src/router/manifest.ts +18 -29
  186. package/src/router/match-api.ts +0 -20
  187. package/src/router/match-context.ts +0 -22
  188. package/src/router/match-handlers.ts +57 -58
  189. package/src/router/match-middleware/background-revalidation.ts +0 -7
  190. package/src/router/match-middleware/cache-lookup.ts +150 -271
  191. package/src/router/match-middleware/cache-store.ts +3 -33
  192. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  193. package/src/router/match-middleware/segment-resolution.ts +0 -22
  194. package/src/router/match-pipelines.ts +1 -42
  195. package/src/router/match-result.ts +31 -80
  196. package/src/router/metrics.ts +0 -34
  197. package/src/router/middleware-types.ts +5 -112
  198. package/src/router/middleware.ts +118 -133
  199. package/src/router/navigation-snapshot.ts +0 -51
  200. package/src/router/params-util.ts +23 -0
  201. package/src/router/pattern-matching.ts +62 -67
  202. package/src/router/prerender-match.ts +99 -63
  203. package/src/router/preview-match.ts +3 -1
  204. package/src/router/request-classification.ts +28 -62
  205. package/src/router/revalidation.ts +50 -56
  206. package/src/router/route-snapshot.ts +0 -1
  207. package/src/router/router-context.ts +0 -27
  208. package/src/router/router-interfaces.ts +68 -35
  209. package/src/router/router-options.ts +55 -1
  210. package/src/router/router-registry.ts +2 -5
  211. package/src/router/segment-resolution/fresh.ts +44 -63
  212. package/src/router/segment-resolution/helpers.ts +34 -0
  213. package/src/router/segment-resolution/loader-cache.ts +40 -37
  214. package/src/router/segment-resolution/revalidation.ts +203 -285
  215. package/src/router/segment-resolution/static-store.ts +19 -5
  216. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  217. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  218. package/src/router/segment-resolution.ts +4 -1
  219. package/src/router/segment-wrappers.ts +0 -3
  220. package/src/router/state-cookie-name.ts +33 -0
  221. package/src/router/substitute-pattern-params.ts +56 -0
  222. package/src/router/telemetry-otel.ts +0 -20
  223. package/src/router/telemetry.ts +96 -19
  224. package/src/router/timeout.ts +0 -20
  225. package/src/router/trie-matching.ts +87 -48
  226. package/src/router/types.ts +9 -63
  227. package/src/router/url-params.ts +0 -5
  228. package/src/router.ts +80 -41
  229. package/src/rsc/handler-context.ts +3 -2
  230. package/src/rsc/handler.ts +83 -78
  231. package/src/rsc/helpers.ts +93 -5
  232. package/src/rsc/index.ts +1 -1
  233. package/src/rsc/json-route-result.ts +38 -0
  234. package/src/rsc/manifest-init.ts +28 -41
  235. package/src/rsc/origin-guard.ts +39 -25
  236. package/src/rsc/progressive-enhancement.ts +12 -1
  237. package/src/rsc/redirect-guard.ts +99 -0
  238. package/src/rsc/response-error.ts +79 -12
  239. package/src/rsc/response-route-handler.ts +76 -62
  240. package/src/rsc/rsc-rendering.ts +41 -60
  241. package/src/rsc/runtime-warnings.ts +23 -10
  242. package/src/rsc/server-action.ts +62 -67
  243. package/src/rsc/ssr-setup.ts +16 -0
  244. package/src/rsc/types.ts +10 -5
  245. package/src/runtime-env.ts +18 -0
  246. package/src/search-params.ts +4 -20
  247. package/src/segment-loader-promise.ts +14 -2
  248. package/src/segment-system.tsx +199 -142
  249. package/src/serialize.ts +243 -0
  250. package/src/server/context.ts +150 -51
  251. package/src/server/cookie-store.ts +80 -5
  252. package/src/server/handle-store.ts +7 -24
  253. package/src/server/loader-registry.ts +5 -24
  254. package/src/server/request-context.ts +165 -87
  255. package/src/ssr/index.tsx +14 -14
  256. package/src/static-handler.ts +10 -13
  257. package/src/testing/cache-status.ts +162 -0
  258. package/src/testing/collect-handle.ts +40 -0
  259. package/src/testing/dispatch.ts +618 -0
  260. package/src/testing/dom.entry.ts +22 -0
  261. package/src/testing/e2e/fixture.ts +188 -0
  262. package/src/testing/e2e/index.ts +128 -0
  263. package/src/testing/e2e/matchers.ts +35 -0
  264. package/src/testing/e2e/page-helpers.ts +272 -0
  265. package/src/testing/e2e/parity.ts +387 -0
  266. package/src/testing/e2e/server.ts +195 -0
  267. package/src/testing/flight-matchers.ts +97 -0
  268. package/src/testing/flight-normalize.ts +11 -0
  269. package/src/testing/flight-runtime.d.ts +57 -0
  270. package/src/testing/flight-tree.ts +682 -0
  271. package/src/testing/flight.entry.ts +52 -0
  272. package/src/testing/flight.ts +232 -0
  273. package/src/testing/generated-routes.ts +183 -0
  274. package/src/testing/index.ts +99 -0
  275. package/src/testing/internal/context.ts +348 -0
  276. package/src/testing/internal/flight-client-globals.ts +30 -0
  277. package/src/testing/internal/seed-vars.ts +54 -0
  278. package/src/testing/render-handler.ts +330 -0
  279. package/src/testing/render-route.tsx +566 -0
  280. package/src/testing/run-loader.ts +378 -0
  281. package/src/testing/run-middleware.ts +205 -0
  282. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  283. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  284. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  285. package/src/testing/vitest-stubs/version.ts +5 -0
  286. package/src/testing/vitest.ts +305 -0
  287. package/src/theme/ThemeProvider.tsx +0 -52
  288. package/src/theme/ThemeScript.tsx +0 -6
  289. package/src/theme/constants.ts +0 -12
  290. package/src/theme/index.ts +0 -7
  291. package/src/theme/theme-context.ts +1 -5
  292. package/src/theme/theme-script.ts +0 -14
  293. package/src/theme/use-theme.ts +0 -3
  294. package/src/types/boundaries.ts +0 -35
  295. package/src/types/cache-types.ts +13 -4
  296. package/src/types/error-types.ts +30 -90
  297. package/src/types/global-namespace.ts +54 -41
  298. package/src/types/handler-context.ts +97 -22
  299. package/src/types/index.ts +1 -10
  300. package/src/types/loader-types.ts +6 -3
  301. package/src/types/request-scope.ts +0 -19
  302. package/src/types/route-config.ts +6 -50
  303. package/src/types/route-entry.ts +0 -6
  304. package/src/types/segments.ts +18 -14
  305. package/src/urls/include-helper.ts +9 -56
  306. package/src/urls/index.ts +1 -11
  307. package/src/urls/path-helper-types.ts +19 -5
  308. package/src/urls/path-helper.ts +17 -106
  309. package/src/urls/pattern-types.ts +36 -19
  310. package/src/urls/response-types.ts +20 -19
  311. package/src/urls/type-extraction.ts +58 -139
  312. package/src/urls/urls-function.ts +1 -18
  313. package/src/use-loader.tsx +292 -107
  314. package/src/vite/debug.ts +1 -0
  315. package/src/vite/discovery/bundle-postprocess.ts +8 -7
  316. package/src/vite/discovery/discover-routers.ts +95 -82
  317. package/src/vite/discovery/discovery-errors.ts +194 -0
  318. package/src/vite/discovery/prerender-collection.ts +26 -34
  319. package/src/vite/discovery/route-types-writer.ts +40 -84
  320. package/src/vite/discovery/state.ts +39 -1
  321. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  322. package/src/vite/index.ts +4 -0
  323. package/src/vite/plugin-types.ts +185 -10
  324. package/src/vite/plugins/cjs-to-esm.ts +3 -18
  325. package/src/vite/plugins/client-ref-dedup.ts +0 -11
  326. package/src/vite/plugins/client-ref-hashing.ts +12 -11
  327. package/src/vite/plugins/cloudflare-protocol-stub.ts +1 -21
  328. package/src/vite/plugins/expose-action-id.ts +4 -75
  329. package/src/vite/plugins/expose-id-utils.ts +3 -54
  330. package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
  331. package/src/vite/plugins/expose-ids/handler-transform.ts +6 -74
  332. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
  333. package/src/vite/plugins/expose-ids/router-transform.ts +0 -13
  334. package/src/vite/plugins/expose-internal-ids.ts +57 -67
  335. package/src/vite/plugins/performance-tracks.ts +9 -16
  336. package/src/vite/plugins/refresh-cmd.ts +1 -1
  337. package/src/vite/plugins/use-cache-transform.ts +26 -49
  338. package/src/vite/plugins/vercel-output.ts +258 -0
  339. package/src/vite/plugins/version-injector.ts +2 -32
  340. package/src/vite/plugins/version-plugin.ts +32 -23
  341. package/src/vite/plugins/virtual-entries.ts +35 -17
  342. package/src/vite/rango.ts +148 -115
  343. package/src/vite/router-discovery.ts +220 -68
  344. package/src/vite/utils/ast-handler-extract.ts +15 -31
  345. package/src/vite/utils/bundle-analysis.ts +10 -15
  346. package/src/vite/utils/client-chunks.ts +184 -0
  347. package/src/vite/utils/forward-user-plugins.ts +171 -0
  348. package/src/vite/utils/manifest-utils.ts +4 -59
  349. package/src/vite/utils/package-resolution.ts +1 -73
  350. package/src/vite/utils/prerender-utils.ts +0 -34
  351. package/src/vite/utils/shared-utils.ts +95 -43
  352. package/src/browser/action-response-classifier.ts +0 -99
  353. package/src/browser/react/use-client-cache.ts +0 -58
  354. package/src/browser/shallow.ts +0 -40
  355. package/src/handles/index.ts +0 -7
  356. package/src/router/middleware-cookies.ts +0 -55
@@ -4,7 +4,7 @@
4
4
  * Evaluates whether segments should revalidate based on params, actions, and custom functions.
5
5
  */
6
6
 
7
- import type { ResolvedSegment, HandlerContext } from "../types";
7
+ import type { ResolvedSegment, HandlerContext, ActionRef } from "../types";
8
8
  import type { ActionContext } from "./types";
9
9
  import {
10
10
  debugLog,
@@ -14,21 +14,52 @@ import {
14
14
  import type { RevalidationTraceEntry } from "./logging.js";
15
15
  import { _getRequestContext } from "../server/request-context.js";
16
16
  import { isAutoGeneratedRouteName } from "../route-name.js";
17
+ import { paramsEqual } from "./params-util.js";
17
18
 
18
- function paramsEqual(
19
- a: Record<string, string>,
20
- b: Record<string, string>,
21
- ): boolean {
22
- if (a === b) return true;
23
-
24
- const keysA = Object.keys(a);
25
- if (keysA.length !== Object.keys(b).length) return false;
26
-
27
- for (const key of keysA) {
28
- if (a[key] !== b[key]) return false;
29
- }
19
+ /**
20
+ * Resolve a server-action reference's stable id, mirroring how the action
21
+ * boundary derives `actionContext.actionId` in `rsc/server-action.ts`
22
+ * (`$id ?? $$id`): the file-path `$id` set by the expose-action-id plugin in a
23
+ * production RSC build when present, otherwise React's `$$id`. Resolving both
24
+ * the incoming `actionId` and the reference with the same precedence makes
25
+ * `isAction()` form-agnostic across dev and production.
26
+ */
27
+ function resolveActionRefId(ref: unknown): string | undefined {
28
+ if (ref == null) return undefined;
29
+ const r = ref as { $id?: unknown; $$id?: unknown };
30
+ if (typeof r.$id === "string") return r.$id;
31
+ if (typeof r.$$id === "string") return r.$$id;
32
+ return undefined;
33
+ }
30
34
 
31
- return true;
35
+ /**
36
+ * Build the `isAction()` helper bound to the current action's id. Called with no
37
+ * arguments it answers "is this request an action at all?" (any action) — `true`
38
+ * during action handling, `false` on plain navigation. Called with one or more
39
+ * action references it narrows to those: a single imported action, several
40
+ * (variadic), or any export of a namespace import (`import * as Mod`). Returns
41
+ * `false` when there is no action (plain navigation) or nothing matches.
42
+ */
43
+ function makeIsAction(
44
+ currentActionId: string | undefined,
45
+ ): (...actions: ActionRef[]) => boolean {
46
+ return (...actions: ActionRef[]): boolean => {
47
+ if (!currentActionId) return false;
48
+ // Bare isAction(): an action is in flight (currentActionId is set) and the
49
+ // caller did not narrow to a specific action, so this is "any action".
50
+ if (actions.length === 0) return true;
51
+ for (const action of actions) {
52
+ if (typeof action === "function") {
53
+ if (resolveActionRefId(action) === currentActionId) return true;
54
+ } else if (action && typeof action === "object") {
55
+ // Namespace import: match any export of the module.
56
+ for (const value of Object.values(action)) {
57
+ if (resolveActionRefId(value) === currentActionId) return true;
58
+ }
59
+ }
60
+ }
61
+ return false;
62
+ };
32
63
  }
33
64
 
34
65
  /**
@@ -95,8 +126,6 @@ export async function evaluateRevalidation<TEnv>(
95
126
  const paramsChanged = !paramsEqual(nextParams, prevParams);
96
127
  const searchChanged = prevUrl.search !== nextUrl.search;
97
128
 
98
- // Trace helper: push a structured entry to the request-scoped trace buffer.
99
- // Guarded by isTraceActive() so object construction is skipped in production.
100
129
  function pushTrace(
101
130
  defaultVal: boolean,
102
131
  finalVal: boolean,
@@ -115,43 +144,28 @@ export async function evaluateRevalidation<TEnv>(
115
144
  });
116
145
  }
117
146
 
118
- // Calculate default revalidation based on segment type and request method
119
147
  let defaultShouldRevalidate: boolean;
120
148
  let defaultReason: string;
121
149
 
122
150
  if (defaultOverride) {
123
- // Caller injected the seed (e.g. parallel slot not in clientSegmentIds).
124
- // Skip the type-derived heuristic — caller knows better in this context.
125
151
  defaultShouldRevalidate = defaultOverride.value;
126
152
  defaultReason = defaultOverride.reason;
127
153
  } else if (request.method === "POST") {
128
- // Actions: revalidate segments that belong to the route, skip parent chain
129
154
  if (segment.type === "route") {
130
- // Route segment always revalidates on actions
131
155
  defaultShouldRevalidate = true;
132
156
  defaultReason = "action:route-segment";
133
157
  } else if (segment.type === "loader") {
134
- // Loaders always revalidate on actions - they often contain action-sensitive data
135
- // (e.g., cart count after add-to-cart action)
136
158
  defaultShouldRevalidate = true;
137
159
  defaultReason = "action:loader-segment";
138
160
  } else if (segment.belongsToRoute) {
139
- // Segment belongs to route (orphan layouts/parallels) - revalidate
140
161
  defaultShouldRevalidate = true;
141
162
  defaultReason = "action:belongs-to-route";
142
163
  } else {
143
- // Parent chain segment (shared layouts/parallels) - don't revalidate
144
164
  defaultShouldRevalidate = false;
145
165
  defaultReason = "action:parent-chain-skip";
146
166
  }
147
167
  } else {
148
- // Navigation (GET): Conservative defaults to minimize unnecessary revalidations
149
- // Only the route segment revalidates by default - all others require explicit opt-in
150
-
151
168
  if (segment.type === "route") {
152
- // Route segments revalidate when path params OR search params change.
153
- // Search params (e.g., ?page=2&sort=price) are server-parsed via ctx.search,
154
- // so the handler must re-execute to produce updated content.
155
169
  const routeChanged = paramsChanged || searchChanged;
156
170
  defaultShouldRevalidate = routeChanged;
157
171
  defaultReason = paramsChanged
@@ -167,8 +181,6 @@ export async function evaluateRevalidation<TEnv>(
167
181
  });
168
182
  }
169
183
  } else if (segment.belongsToRoute && (paramsChanged || searchChanged)) {
170
- // Children of the route path (loaders, orphan layouts/parallels)
171
- // revalidate when path params or search params change
172
184
  defaultShouldRevalidate = true;
173
185
  defaultReason = paramsChanged
174
186
  ? "nav:route-child-params-changed"
@@ -180,9 +192,6 @@ export async function evaluateRevalidation<TEnv>(
180
192
  searchChanged,
181
193
  });
182
194
  } else {
183
- // Parent layouts and parallels default to no revalidation
184
- // Cannot assume these segments depend on params without explicit declaration
185
- // Use custom revalidation functions to opt-in when needed
186
195
  defaultShouldRevalidate = false;
187
196
  defaultReason = "nav:non-route-skip";
188
197
  debugLog("revalidation", "non-route segment skipped by default", {
@@ -192,7 +201,6 @@ export async function evaluateRevalidation<TEnv>(
192
201
  }
193
202
  }
194
203
 
195
- // No custom revalidations defined - return default behavior without prev segment
196
204
  if (revalidations.length === 0) {
197
205
  if (defaultShouldRevalidate) {
198
206
  debugLog("revalidation", "default revalidate=true", {
@@ -209,14 +217,10 @@ export async function evaluateRevalidation<TEnv>(
209
217
  return defaultShouldRevalidate;
210
218
  }
211
219
 
212
- // Custom revalidations exist - may need full prev segment
213
- // Lazy load prev segment only if getPrevSegment provided
214
220
  const prevSegment = getPrevSegment ? await getPrevSegment() : null;
215
221
 
216
- // Execute revalidation functions with soft/hard decision pattern
217
222
  let currentSuggestion = defaultShouldRevalidate;
218
223
 
219
- // Compute public route names (filtered: undefined for auto-generated routes)
220
224
  const toRouteName =
221
225
  routeKey && !isAutoGeneratedRouteName(routeKey) ? routeKey : undefined;
222
226
  const reqCtx = _getRequestContext();
@@ -240,23 +244,18 @@ export async function evaluateRevalidation<TEnv>(
240
244
  slotName: segment.slot,
241
245
  // Action context (only populated when triggered by server action)
242
246
  actionId: actionContext?.actionId,
247
+ isAction: makeIsAction(actionContext?.actionId),
243
248
  actionUrl: actionContext?.actionUrl,
244
249
  actionResult: actionContext?.actionResult,
245
250
  formData: actionContext?.formData,
246
- method: request.method, // GET for navigation, POST for actions
247
- routeName: toRouteName, // Navigation target route name (filtered)
248
- fromRouteName, // Navigation source route name (filtered)
249
- toRouteName, // Navigation target route name (filtered)
250
- // Stale cache context (only true for background revalidation after stale cache render)
251
+ method: request.method,
252
+ routeName: toRouteName,
253
+ fromRouteName,
254
+ toRouteName,
251
255
  stale,
252
256
  });
253
257
 
254
- // Check return type:
255
- // - boolean: hard decision, short-circuit immediately
256
- // - { defaultShouldRevalidate: boolean }: soft decision, update suggestion and continue
257
- // - null/undefined: use default behavior (equivalent to returning { defaultShouldRevalidate })
258
258
  if (typeof result === "boolean") {
259
- // Hard decision - short-circuit
260
259
  debugLog("revalidation", "hard decision", {
261
260
  segmentId: segment.id,
262
261
  revalidator: name,
@@ -269,7 +268,6 @@ export async function evaluateRevalidation<TEnv>(
269
268
  typeof result === "object" &&
270
269
  "defaultShouldRevalidate" in result
271
270
  ) {
272
- // Soft decision - update suggestion and continue
273
271
  currentSuggestion = result.defaultShouldRevalidate;
274
272
  debugLog("revalidation", "soft decision", {
275
273
  segmentId: segment.id,
@@ -277,18 +275,14 @@ export async function evaluateRevalidation<TEnv>(
277
275
  revalidate: currentSuggestion,
278
276
  });
279
277
  } else if (result === null || result === undefined) {
280
- // Defer to default - equivalent to { defaultShouldRevalidate: currentSuggestion }
281
- // This means "I don't care, use whatever the default is"
282
278
  debugLog("revalidation", "deferred to current default", {
283
279
  segmentId: segment.id,
284
280
  revalidator: name,
285
281
  revalidate: currentSuggestion,
286
282
  });
287
- // currentSuggestion stays the same, continue to next function
288
283
  }
289
284
  }
290
285
 
291
- // All revalidators completed - use final suggestion
292
286
  debugLog("revalidation", "final decision", {
293
287
  segmentId: segment.id,
294
288
  revalidate: currentSuggestion,
@@ -230,7 +230,6 @@ export function createRouteSnapshot<TEnv = any>(
230
230
  entry: {} as any,
231
231
  routeKey: "test",
232
232
  params: {},
233
- optionalParams: new Set(),
234
233
  } as RouteMatchResult<TEnv>,
235
234
  manifestEntry: { type: "route", shortCode: "R0", parent: null } as any,
236
235
  entries: [],
@@ -54,10 +54,8 @@ export interface InterceptResult {
54
54
  * Instead of passing 20+ parameters, middleware calls getRouterContext() to access them.
55
55
  */
56
56
  export interface RouterContext<TEnv = any> {
57
- // Route matching
58
57
  findMatch: (pathname: string) => RouteMatchResult | null;
59
58
 
60
- // Manifest loading
61
59
  loadManifest: (
62
60
  entry: any,
63
61
  routeKey: string,
@@ -66,10 +64,8 @@ export interface RouterContext<TEnv = any> {
66
64
  isSSR?: boolean,
67
65
  ) => Promise<EntryData>;
68
66
 
69
- // Entry traversal
70
67
  traverseBack: (entry: EntryData) => Generator<EntryData>;
71
68
 
72
- // Handler context creation
73
69
  createHandlerContext: (
74
70
  params: Record<string, string>,
75
71
  request: Request,
@@ -83,7 +79,6 @@ export interface RouterContext<TEnv = any> {
83
79
  isPassthroughRoute?: boolean,
84
80
  ) => HandlerContext<any, TEnv>;
85
81
 
86
- // Loader setup
87
82
  setupLoaderAccess: (
88
83
  ctx: HandlerContext<any, TEnv>,
89
84
  loaderPromises: Map<string, Promise<any>>,
@@ -94,7 +89,6 @@ export interface RouterContext<TEnv = any> {
94
89
  loaderPromises: Map<string, Promise<any>>,
95
90
  ) => void;
96
91
 
97
- // Context access
98
92
  getContext: () => {
99
93
  getOrCreateStore: (key: string) => any;
100
94
  runWithStore: <T>(
@@ -105,16 +99,13 @@ export interface RouterContext<TEnv = any> {
105
99
  ) => T;
106
100
  };
107
101
 
108
- // Metrics
109
102
  getMetricsStore: () => MetricsStore | undefined;
110
103
 
111
- // Cache
112
104
  createCacheScope: (
113
105
  cacheConfig: any,
114
106
  parent: CacheScope | null,
115
107
  ) => CacheScope | null;
116
108
 
117
- // Intercept detection
118
109
  findInterceptForRoute: (
119
110
  routeKey: string,
120
111
  parentEntry: EntryData | null,
@@ -122,7 +113,6 @@ export interface RouterContext<TEnv = any> {
122
113
  isAction: boolean,
123
114
  ) => InterceptResult | null;
124
115
 
125
- // Segment resolution (with revalidation)
126
116
  resolveAllSegmentsWithRevalidation: (
127
117
  entries: EntryData[],
128
118
  routeKey: string,
@@ -133,7 +123,6 @@ export interface RouterContext<TEnv = any> {
133
123
  request: Request,
134
124
  prevUrl: URL,
135
125
  nextUrl: URL,
136
- loaderPromises: Map<string, Promise<any>>,
137
126
  actionContext: any | undefined,
138
127
  interceptResult: InterceptResult | null,
139
128
  localRouteName: string,
@@ -166,12 +155,10 @@ export interface RouterContext<TEnv = any> {
166
155
  revalidationContext?: RevalidationContext,
167
156
  ) => Promise<ResolvedSegment[]>;
168
157
 
169
- // Collect with markers
170
158
  collectWithMarkers?: <T>(
171
159
  gen: AsyncGenerator<T | { __type: "id"; id: string }>,
172
160
  ) => Promise<{ items: T[]; matchedIds: string[] }>;
173
161
 
174
- // Revalidation evaluation
175
162
  evaluateRevalidation: (params: {
176
163
  segment: ResolvedSegment;
177
164
  prevParams: Record<string, string>;
@@ -195,7 +182,6 @@ export interface RouterContext<TEnv = any> {
195
182
  | "intercept-loader";
196
183
  }) => Promise<boolean>;
197
184
 
198
- // Request context
199
185
  getRequestContext: () =>
200
186
  | {
201
187
  waitUntil: (fn: () => Promise<void>) => void;
@@ -203,7 +189,6 @@ export interface RouterContext<TEnv = any> {
203
189
  }
204
190
  | undefined;
205
191
 
206
- // Simple segment resolution (without revalidation - for full match)
207
192
  resolveAllSegments: (
208
193
  entries: EntryData[],
209
194
  routeKey: string,
@@ -213,7 +198,6 @@ export interface RouterContext<TEnv = any> {
213
198
  options?: { skipLoaders?: boolean },
214
199
  ) => Promise<ResolvedSegment[]>;
215
200
 
216
- // Generator-based simple resolution
217
201
  resolveAllSegmentsGenerator?: (
218
202
  entries: EntryData[],
219
203
  routeKey: string,
@@ -222,21 +206,17 @@ export interface RouterContext<TEnv = any> {
222
206
  loaderPromises: Map<string, Promise<any>>,
223
207
  ) => AsyncGenerator<ResolvedSegment | { __type: "id"; id: string }>;
224
208
 
225
- // Collect segments from generator
226
209
  collectSegmentsFromGenerator?: <T>(
227
210
  gen: AsyncGenerator<T | { __type: "id"; id: string }>,
228
211
  ) => Promise<T[]>;
229
212
 
230
- // Handle store
231
213
  createHandleStore: () => any;
232
214
 
233
- // Loaders-only resolution (for full match cache hit - no revalidation)
234
215
  resolveLoadersOnly?: (
235
216
  entries: EntryData[],
236
217
  handlerContext: HandlerContext<any, TEnv>,
237
218
  ) => Promise<ResolvedSegment[]>;
238
219
 
239
- // Loaders-only resolution (for cache hit scenarios)
240
220
  resolveLoadersOnlyWithRevalidation?: (
241
221
  entries: EntryData[],
242
222
  handlerContext: HandlerContext<any, TEnv>,
@@ -258,10 +238,8 @@ export interface RouterContext<TEnv = any> {
258
238
  // Telemetry sink (optional, no-op when undefined)
259
239
  telemetry?: TelemetrySink;
260
240
 
261
- // Request ID for telemetry span correlation (set per-request in match handlers)
262
241
  requestId?: string;
263
242
 
264
- // Intercept loaders only (for cache hit + intercept scenarios)
265
243
  resolveInterceptLoadersOnly?: (
266
244
  intercept: InterceptEntry,
267
245
  entry: EntryData,
@@ -284,7 +262,6 @@ export interface RouterContext<TEnv = any> {
284
262
  } | null>;
285
263
  }
286
264
 
287
- // AsyncLocalStorage instance for router context
288
265
  const routerContext = new AsyncLocalStorage<RouterContext<any>>();
289
266
 
290
267
  /**
@@ -308,10 +285,6 @@ export function getRouterContext<TEnv = any>(): RouterContext<TEnv> {
308
285
  *
309
286
  * All async code within fn() can call getRouterContext() to access router closures.
310
287
  * This works across async boundaries thanks to AsyncLocalStorage.
311
- *
312
- * @param deps Router dependencies to make available
313
- * @param fn Function to run with dependencies available
314
- * @returns Result of fn()
315
288
  */
316
289
  export function runWithRouterContext<T, TEnv = any>(
317
290
  deps: RouterContext<TEnv>,
@@ -2,18 +2,16 @@ import type { ComponentType, ReactNode } from "react";
2
2
  import type { SerializedManifest } from "../debug.js";
3
3
  import type { ReverseFunction } from "../reverse.js";
4
4
  import type { UrlPatterns } from "../urls.js";
5
- import type { UrlBuilder } from "../urls/pattern-types.js";
5
+ import type { UrlBuilder, EnvCompatible } from "../urls/pattern-types.js";
6
6
  import type { EntryData } from "../server/context";
7
7
  import type { ErrorInfo, MatchResult } from "../types";
8
8
  import type { NonceProvider } from "../rsc/types.js";
9
9
  import type { ExecutionContext } from "../server/request-context.js";
10
- import type {
11
- SerializedSegmentData,
12
- SegmentHandleData,
13
- } from "../cache/types.js";
10
+ import type { SerializedSegmentData } from "../cache/types.js";
14
11
  import type { MiddlewareEntry, MiddlewareFn } from "./middleware.js";
12
+ import type { ExtractParams } from "../types/route-config.js";
15
13
  import { RSC_ROUTER_BRAND } from "./router-registry.js";
16
- import type { RSCRouterOptions, RootLayoutProps } from "./router-options.js";
14
+ import type { RangoOptions, RootLayoutProps } from "./router-options.js";
17
15
  import type { DefaultVars } from "../types/global-namespace.js";
18
16
  import type { ResolvedTimeouts, OnTimeoutCallback } from "./timeout.js";
19
17
 
@@ -49,16 +47,16 @@ type MergeRoutesWithResponses<
49
47
  };
50
48
 
51
49
  /**
52
- * Public RSC Router interface — the user-facing API surface.
50
+ * Public Rango router interface — the user-facing API surface.
53
51
  *
54
52
  * Users interact with this type when building and using routers.
55
- * Internal framework code uses RSCRouterInternal (via toInternal()) to access
53
+ * Internal framework code uses RangoInternal (via toInternal()) to access
56
54
  * matching, build-time, and configuration members that are not part of the
57
55
  * public contract.
58
56
  *
59
57
  * TRoutes accumulates all registered route types through the builder chain.
60
58
  */
61
- export interface RSCRouter<
59
+ export interface Rango<
62
60
  TEnv = any,
63
61
  TRoutes extends Record<string, unknown> = Record<string, string>,
64
62
  > {
@@ -89,16 +87,16 @@ export interface RSCRouter<
89
87
  * ])
90
88
  * ```
91
89
  */
92
- routes<T extends UrlPatterns<TEnv, any>>(
93
- patterns: T,
94
- ): RSCRouter<
90
+ routes<T extends UrlPatterns<any, any, any>>(
91
+ patterns: T & EnvCompatible<T, TEnv>,
92
+ ): Rango<
95
93
  TEnv,
96
94
  TRoutes &
97
95
  (NonNullable<T["_routes"]> extends Record<string, unknown>
98
96
  ? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]>
99
97
  : Record<string, string>)
100
98
  >;
101
- routes(builder: UrlBuilder<TEnv>): RSCRouter<TEnv, TRoutes>;
99
+ routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
102
100
 
103
101
  /**
104
102
  * Add global middleware that runs on all routes
@@ -108,13 +106,18 @@ export interface RSCRouter<
108
106
  * createRouter({ document: RootLayout })
109
107
  * .use(loggerMiddleware) // All routes
110
108
  * .use("/api/*", rateLimiter) // Pattern match
109
+ * .use("/users/:id", (ctx) => {}) // ctx.params.id is typed
111
110
  * .routes(urlpatterns)
112
111
  * ```
113
112
  */
113
+ use<Pattern extends string>(
114
+ pattern: Pattern,
115
+ middleware: MiddlewareFn<TEnv, ExtractParams<Pattern>>,
116
+ ): Rango<TEnv, TRoutes>;
114
117
  use(
115
118
  patternOrMiddleware: string | MiddlewareFn<TEnv>,
116
119
  middleware?: MiddlewareFn<TEnv>,
117
- ): RSCRouter<TEnv, TRoutes>;
120
+ ): Rango<TEnv, TRoutes>;
118
121
 
119
122
  /**
120
123
  * Type-safe URL builder for registered routes
@@ -141,7 +144,7 @@ export interface RSCRouter<
141
144
  * type AppRoutes = typeof _router.routeMap;
142
145
  *
143
146
  * declare global {
144
- * namespace RSCRouter {
147
+ * namespace Rango {
145
148
  * interface RegisteredRoutes extends AppRoutes {}
146
149
  * }
147
150
  * }
@@ -177,16 +180,16 @@ export interface RSCRouter<
177
180
  }
178
181
 
179
182
  /**
180
- * Internal RSC Router interface — the full framework-facing API.
183
+ * Internal Rango router interface — the full framework-facing API.
181
184
  *
182
185
  * This type includes all members used by the Vite plugin, RSC handler,
183
186
  * pre-rendering pipeline, and other framework internals. It is NOT exported
184
187
  * from the public package API.
185
188
  *
186
- * Use toInternal(router) to assert a public RSCRouter into this type
189
+ * Use toInternal(router) to assert a public Rango into this type
187
190
  * at the boundary where framework code receives a user-provided router.
188
191
  */
189
- export interface RSCRouterInternal<
192
+ export interface RangoInternal<
190
193
  TEnv = any,
191
194
  TRoutes extends Record<string, unknown> = Record<string, string>,
192
195
  > {
@@ -206,26 +209,36 @@ export interface RSCRouterInternal<
206
209
  readonly basename: string | undefined;
207
210
 
208
211
  /**
209
- * Register routes using URL patterns from urls() or a builder function
210
- */
211
- routes<T extends UrlPatterns<TEnv, any>>(
212
- patterns: T,
213
- ): RSCRouter<
212
+ * Register routes using URL patterns from urls() or a builder function.
213
+ *
214
+ * Env compatibility is checked by EnvCompatible: an env-agnostic urls() block
215
+ * (its env is `unknown` — e.g. a shared module, or an app that does not augment
216
+ * `Rango.Env`) attaches to any router, while a urls<TEnv>() block carrying a
217
+ * concrete env is accepted only when this router's `TEnv` satisfies it. So a
218
+ * `urls<{ DB }>()` cannot be mounted on a `createRouter<{}>()`.
219
+ */
220
+ routes<T extends UrlPatterns<any, any, any>>(
221
+ patterns: T & EnvCompatible<T, TEnv>,
222
+ ): Rango<
214
223
  TEnv,
215
224
  TRoutes &
216
225
  (NonNullable<T["_routes"]> extends Record<string, unknown>
217
226
  ? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]>
218
227
  : Record<string, string>)
219
228
  >;
220
- routes(builder: UrlBuilder<TEnv>): RSCRouter<TEnv, TRoutes>;
229
+ routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
221
230
 
222
231
  /**
223
232
  * Add global middleware that runs on all routes
224
233
  */
234
+ use<Pattern extends string>(
235
+ pattern: Pattern,
236
+ middleware: MiddlewareFn<TEnv, ExtractParams<Pattern>>,
237
+ ): Rango<TEnv, TRoutes>;
225
238
  use(
226
239
  patternOrMiddleware: string | MiddlewareFn<TEnv>,
227
240
  middleware?: MiddlewareFn<TEnv>,
228
- ): RSCRouter<TEnv, TRoutes>;
241
+ ): Rango<TEnv, TRoutes>;
229
242
 
230
243
  /**
231
244
  * Type-safe URL builder for registered routes
@@ -247,17 +260,17 @@ export interface RSCRouterInternal<
247
260
  * Error callback for monitoring/alerting
248
261
  * Called when errors occur in loaders, actions, or routes
249
262
  */
250
- readonly onError?: RSCRouterOptions<TEnv>["onError"];
263
+ readonly onError?: RangoOptions<TEnv>["onError"];
251
264
 
252
265
  /**
253
266
  * Cache configuration
254
267
  */
255
- readonly cache?: RSCRouterOptions<TEnv>["cache"];
268
+ readonly cache?: RangoOptions<TEnv>["cache"];
256
269
 
257
270
  /**
258
271
  * Not found component to render when no route matches
259
272
  */
260
- readonly notFound?: RSCRouterOptions<TEnv>["notFound"];
273
+ readonly notFound?: RangoOptions<TEnv>["notFound"];
261
274
 
262
275
  /**
263
276
  * Resolved theme configuration (null if theme not enabled)
@@ -287,6 +300,13 @@ export interface RSCRouterInternal<
287
300
  */
288
301
  readonly prefetchCacheTTL: number;
289
302
 
303
+ /**
304
+ * Resolved rango state cookie name (`{prefix}_{routerId}`), composed once at
305
+ * router init and shipped to the client in payload metadata. The server-side
306
+ * cookie writer reads it from here; the client reads it from metadata.
307
+ */
308
+ readonly resolvedStateCookieName: string;
309
+
290
310
  /**
291
311
  * Whether connection warmup is enabled.
292
312
  * When true, the client sends HEAD /?_rsc_warmup after idle periods
@@ -359,6 +379,17 @@ export interface RSCRouterInternal<
359
379
  /** @internal basename for runtime manifest generation */
360
380
  readonly __basename?: string;
361
381
 
382
+ /**
383
+ * @internal Router-level error/notFound fallbacks (`createRouter` options),
384
+ * exposed for the build-time clientChunks discovery so a `"use client"`
385
+ * default boundary is routed into the dedicated `app-fallback` chunk. Unlike
386
+ * the route-tree `errorBoundary()`/`notFoundBoundary()` helpers these never
387
+ * land in `EntryData`, so they are read directly off the router instance.
388
+ */
389
+ readonly __defaultErrorBoundary?: RangoOptions<TEnv>["defaultErrorBoundary"];
390
+ readonly __defaultNotFoundBoundary?: RangoOptions<TEnv>["defaultNotFoundBoundary"];
391
+ readonly __notFound?: RangoOptions<TEnv>["notFound"];
392
+
362
393
  match(
363
394
  request: Request,
364
395
  input?: RouterRequestInput<TEnv>,
@@ -378,11 +409,13 @@ export interface RSCRouterInternal<
378
409
  devMode?: boolean,
379
410
  ): Promise<{
380
411
  segments: SerializedSegmentData[];
381
- handles: Record<string, SegmentHandleData>;
412
+ /** RSC-encoded handle map ("" when none) — see handle-snapshot.ts. */
413
+ handles: string;
382
414
  routeName: string;
383
415
  params: Record<string, string>;
384
416
  interceptSegments?: SerializedSegmentData[];
385
- interceptHandles?: Record<string, SegmentHandleData>;
417
+ /** RSC-encoded MERGED (main + intercept) handle map for the intercept artifact. */
418
+ interceptHandles?: string;
386
419
  passthrough?: true;
387
420
  } | null>;
388
421
 
@@ -396,7 +429,7 @@ export interface RSCRouterInternal<
396
429
  routeName?: string,
397
430
  buildEnv?: any,
398
431
  devMode?: boolean,
399
- ): Promise<{ encoded: string; handles: Record<string, unknown[]> } | null>;
432
+ ): Promise<{ encoded: string; handles: string } | null>;
400
433
 
401
434
  /**
402
435
  * Preview match - returns route middleware without segment resolution.
@@ -469,16 +502,16 @@ export interface RSCRouterInternal<
469
502
  }
470
503
 
471
504
  /**
472
- * Assert a public RSCRouter into the internal type.
505
+ * Assert a public Rango into the internal type.
473
506
  *
474
507
  * Use this at the boundary where framework code receives a user-provided
475
508
  * router and needs access to internal members (match, config, build-time).
476
509
  * The cast is safe because createRouter() always produces an object that
477
- * satisfies RSCRouterInternal; the public type is just a narrower view.
510
+ * satisfies RangoInternal; the public type is just a narrower view.
478
511
  */
479
512
  export function toInternal<
480
513
  TEnv = any,
481
514
  TRoutes extends Record<string, unknown> = Record<string, string>,
482
- >(router: RSCRouter<TEnv, TRoutes>): RSCRouterInternal<TEnv, TRoutes> {
483
- return router as RSCRouterInternal<TEnv, TRoutes>;
515
+ >(router: Rango<TEnv, TRoutes>): RangoInternal<TEnv, TRoutes> {
516
+ return router as RangoInternal<TEnv, TRoutes>;
484
517
  }