@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.8a4d0430

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 (300) hide show
  1. package/AGENTS.md +5 -0
  2. package/README.md +884 -4
  3. package/dist/bin/rango.js +1601 -0
  4. package/dist/vite/index.js +4474 -867
  5. package/package.json +60 -51
  6. package/skills/breadcrumbs/SKILL.md +250 -0
  7. package/skills/cache-guide/SKILL.md +262 -0
  8. package/skills/caching/SKILL.md +50 -21
  9. package/skills/composability/SKILL.md +172 -0
  10. package/skills/debug-manifest/SKILL.md +12 -8
  11. package/skills/document-cache/SKILL.md +18 -16
  12. package/skills/fonts/SKILL.md +167 -0
  13. package/skills/hooks/SKILL.md +334 -72
  14. package/skills/host-router/SKILL.md +218 -0
  15. package/skills/intercept/SKILL.md +131 -8
  16. package/skills/layout/SKILL.md +100 -3
  17. package/skills/links/SKILL.md +89 -30
  18. package/skills/loader/SKILL.md +388 -38
  19. package/skills/middleware/SKILL.md +171 -34
  20. package/skills/mime-routes/SKILL.md +128 -0
  21. package/skills/parallel/SKILL.md +78 -1
  22. package/skills/prerender/SKILL.md +643 -0
  23. package/skills/rango/SKILL.md +85 -16
  24. package/skills/response-routes/SKILL.md +411 -0
  25. package/skills/route/SKILL.md +226 -14
  26. package/skills/router-setup/SKILL.md +123 -30
  27. package/skills/tailwind/SKILL.md +129 -0
  28. package/skills/theme/SKILL.md +9 -8
  29. package/skills/typesafety/SKILL.md +318 -89
  30. package/skills/use-cache/SKILL.md +324 -0
  31. package/src/__internal.ts +102 -4
  32. package/src/bin/rango.ts +321 -0
  33. package/src/browser/action-coordinator.ts +97 -0
  34. package/src/browser/action-response-classifier.ts +99 -0
  35. package/src/browser/event-controller.ts +87 -64
  36. package/src/browser/history-state.ts +80 -0
  37. package/src/browser/intercept-utils.ts +52 -0
  38. package/src/browser/link-interceptor.ts +24 -4
  39. package/src/browser/logging.ts +55 -0
  40. package/src/browser/merge-segment-loaders.ts +20 -12
  41. package/src/browser/navigation-bridge.ts +285 -553
  42. package/src/browser/navigation-client.ts +124 -71
  43. package/src/browser/navigation-store.ts +33 -50
  44. package/src/browser/navigation-transaction.ts +295 -0
  45. package/src/browser/network-error-handler.ts +61 -0
  46. package/src/browser/partial-update.ts +258 -308
  47. package/src/browser/prefetch/cache.ts +146 -0
  48. package/src/browser/prefetch/fetch.ts +135 -0
  49. package/src/browser/prefetch/observer.ts +65 -0
  50. package/src/browser/prefetch/policy.ts +42 -0
  51. package/src/browser/prefetch/queue.ts +88 -0
  52. package/src/browser/rango-state.ts +112 -0
  53. package/src/browser/react/Link.tsx +185 -73
  54. package/src/browser/react/NavigationProvider.tsx +51 -11
  55. package/src/browser/react/context.ts +6 -0
  56. package/src/browser/react/filter-segment-order.ts +11 -0
  57. package/src/browser/react/index.ts +12 -12
  58. package/src/browser/react/location-state-shared.ts +95 -53
  59. package/src/browser/react/location-state.ts +60 -15
  60. package/src/browser/react/mount-context.ts +6 -1
  61. package/src/browser/react/nonce-context.ts +23 -0
  62. package/src/browser/react/shallow-equal.ts +27 -0
  63. package/src/browser/react/use-action.ts +29 -51
  64. package/src/browser/react/use-client-cache.ts +5 -3
  65. package/src/browser/react/use-handle.ts +32 -79
  66. package/src/browser/react/use-href.tsx +2 -2
  67. package/src/browser/react/use-link-status.ts +6 -5
  68. package/src/browser/react/use-navigation.ts +22 -63
  69. package/src/browser/react/use-params.ts +65 -0
  70. package/src/browser/react/use-pathname.ts +47 -0
  71. package/src/browser/react/use-router.ts +63 -0
  72. package/src/browser/react/use-search-params.ts +56 -0
  73. package/src/browser/react/use-segments.ts +80 -97
  74. package/src/browser/response-adapter.ts +73 -0
  75. package/src/browser/rsc-router.tsx +107 -26
  76. package/src/browser/scroll-restoration.ts +92 -16
  77. package/src/browser/segment-reconciler.ts +216 -0
  78. package/src/browser/segment-structure-assert.ts +16 -0
  79. package/src/browser/server-action-bridge.ts +504 -599
  80. package/src/browser/shallow.ts +6 -1
  81. package/src/browser/types.ts +109 -47
  82. package/src/browser/validate-redirect-origin.ts +29 -0
  83. package/src/build/generate-manifest.ts +235 -24
  84. package/src/build/generate-route-types.ts +36 -0
  85. package/src/build/index.ts +13 -0
  86. package/src/build/route-trie.ts +265 -0
  87. package/src/build/route-types/ast-helpers.ts +25 -0
  88. package/src/build/route-types/ast-route-extraction.ts +98 -0
  89. package/src/build/route-types/codegen.ts +102 -0
  90. package/src/build/route-types/include-resolution.ts +411 -0
  91. package/src/build/route-types/param-extraction.ts +48 -0
  92. package/src/build/route-types/per-module-writer.ts +128 -0
  93. package/src/build/route-types/router-processing.ts +469 -0
  94. package/src/build/route-types/scan-filter.ts +78 -0
  95. package/src/build/runtime-discovery.ts +231 -0
  96. package/src/cache/background-task.ts +34 -0
  97. package/src/cache/cache-key-utils.ts +44 -0
  98. package/src/cache/cache-policy.ts +125 -0
  99. package/src/cache/cache-runtime.ts +338 -0
  100. package/src/cache/cache-scope.ts +120 -303
  101. package/src/cache/cf/cf-cache-store.ts +119 -7
  102. package/src/cache/cf/index.ts +8 -2
  103. package/src/cache/document-cache.ts +101 -72
  104. package/src/cache/handle-capture.ts +81 -0
  105. package/src/cache/handle-snapshot.ts +41 -0
  106. package/src/cache/index.ts +0 -15
  107. package/src/cache/memory-segment-store.ts +191 -13
  108. package/src/cache/profile-registry.ts +73 -0
  109. package/src/cache/read-through-swr.ts +134 -0
  110. package/src/cache/segment-codec.ts +256 -0
  111. package/src/cache/taint.ts +98 -0
  112. package/src/cache/types.ts +72 -122
  113. package/src/client.rsc.tsx +3 -1
  114. package/src/client.tsx +106 -126
  115. package/src/component-utils.ts +4 -4
  116. package/src/components/DefaultDocument.tsx +5 -1
  117. package/src/context-var.ts +86 -0
  118. package/src/debug.ts +17 -7
  119. package/src/errors.ts +108 -2
  120. package/src/handle.ts +15 -29
  121. package/src/handles/MetaTags.tsx +73 -20
  122. package/src/handles/breadcrumbs.ts +66 -0
  123. package/src/handles/index.ts +1 -0
  124. package/src/handles/meta.ts +30 -13
  125. package/src/host/cookie-handler.ts +21 -15
  126. package/src/host/errors.ts +8 -8
  127. package/src/host/index.ts +4 -7
  128. package/src/host/pattern-matcher.ts +27 -27
  129. package/src/host/router.ts +61 -39
  130. package/src/host/testing.ts +8 -8
  131. package/src/host/types.ts +15 -7
  132. package/src/host/utils.ts +1 -1
  133. package/src/href-client.ts +119 -29
  134. package/src/index.rsc.ts +153 -19
  135. package/src/index.ts +211 -30
  136. package/src/internal-debug.ts +11 -0
  137. package/src/loader.rsc.ts +26 -157
  138. package/src/loader.ts +27 -10
  139. package/src/network-error-thrower.tsx +3 -1
  140. package/src/outlet-provider.tsx +45 -0
  141. package/src/prerender/param-hash.ts +37 -0
  142. package/src/prerender/store.ts +185 -0
  143. package/src/prerender.ts +463 -0
  144. package/src/reverse.ts +330 -0
  145. package/src/root-error-boundary.tsx +41 -29
  146. package/src/route-content-wrapper.tsx +7 -4
  147. package/src/route-definition/dsl-helpers.ts +934 -0
  148. package/src/route-definition/helper-factories.ts +200 -0
  149. package/src/route-definition/helpers-types.ts +430 -0
  150. package/src/route-definition/index.ts +52 -0
  151. package/src/route-definition/redirect.ts +93 -0
  152. package/src/route-definition.ts +1 -1428
  153. package/src/route-map-builder.ts +211 -123
  154. package/src/route-name.ts +53 -0
  155. package/src/route-types.ts +59 -8
  156. package/src/router/content-negotiation.ts +116 -0
  157. package/src/router/debug-manifest.ts +72 -0
  158. package/src/router/error-handling.ts +9 -9
  159. package/src/router/find-match.ts +158 -0
  160. package/src/router/handler-context.ts +374 -81
  161. package/src/router/intercept-resolution.ts +395 -0
  162. package/src/router/lazy-includes.ts +234 -0
  163. package/src/router/loader-resolution.ts +215 -122
  164. package/src/router/logging.ts +248 -0
  165. package/src/router/manifest.ts +148 -35
  166. package/src/router/match-api.ts +620 -0
  167. package/src/router/match-context.ts +5 -3
  168. package/src/router/match-handlers.ts +440 -0
  169. package/src/router/match-middleware/background-revalidation.ts +80 -93
  170. package/src/router/match-middleware/cache-lookup.ts +382 -9
  171. package/src/router/match-middleware/cache-store.ts +51 -22
  172. package/src/router/match-middleware/intercept-resolution.ts +55 -17
  173. package/src/router/match-middleware/segment-resolution.ts +24 -6
  174. package/src/router/match-pipelines.ts +10 -45
  175. package/src/router/match-result.ts +34 -28
  176. package/src/router/metrics.ts +235 -15
  177. package/src/router/middleware-cookies.ts +55 -0
  178. package/src/router/middleware-types.ts +222 -0
  179. package/src/router/middleware.ts +324 -367
  180. package/src/router/pattern-matching.ts +211 -43
  181. package/src/router/prerender-match.ts +402 -0
  182. package/src/router/preview-match.ts +170 -0
  183. package/src/router/revalidation.ts +137 -38
  184. package/src/router/router-context.ts +36 -21
  185. package/src/router/router-interfaces.ts +452 -0
  186. package/src/router/router-options.ts +592 -0
  187. package/src/router/router-registry.ts +24 -0
  188. package/src/router/segment-resolution/fresh.ts +570 -0
  189. package/src/router/segment-resolution/helpers.ts +263 -0
  190. package/src/router/segment-resolution/loader-cache.ts +198 -0
  191. package/src/router/segment-resolution/revalidation.ts +1241 -0
  192. package/src/router/segment-resolution/static-store.ts +67 -0
  193. package/src/router/segment-resolution.ts +21 -0
  194. package/src/router/segment-wrappers.ts +289 -0
  195. package/src/router/telemetry-otel.ts +299 -0
  196. package/src/router/telemetry.ts +300 -0
  197. package/src/router/timeout.ts +148 -0
  198. package/src/router/trie-matching.ts +239 -0
  199. package/src/router/types.ts +77 -3
  200. package/src/router.ts +692 -4257
  201. package/src/rsc/handler-context.ts +45 -0
  202. package/src/rsc/handler.ts +764 -754
  203. package/src/rsc/helpers.ts +140 -6
  204. package/src/rsc/index.ts +0 -20
  205. package/src/rsc/loader-fetch.ts +209 -0
  206. package/src/rsc/manifest-init.ts +86 -0
  207. package/src/rsc/nonce.ts +14 -0
  208. package/src/rsc/origin-guard.ts +141 -0
  209. package/src/rsc/progressive-enhancement.ts +379 -0
  210. package/src/rsc/response-error.ts +37 -0
  211. package/src/rsc/response-route-handler.ts +347 -0
  212. package/src/rsc/rsc-rendering.ts +235 -0
  213. package/src/rsc/runtime-warnings.ts +42 -0
  214. package/src/rsc/server-action.ts +348 -0
  215. package/src/rsc/ssr-setup.ts +128 -0
  216. package/src/rsc/types.ts +38 -11
  217. package/src/search-params.ts +230 -0
  218. package/src/segment-system.tsx +25 -13
  219. package/src/server/context.ts +182 -51
  220. package/src/server/cookie-store.ts +190 -0
  221. package/src/server/fetchable-loader-store.ts +37 -0
  222. package/src/server/handle-store.ts +94 -15
  223. package/src/server/loader-registry.ts +15 -56
  224. package/src/server/request-context.ts +430 -70
  225. package/src/server.ts +35 -130
  226. package/src/ssr/index.tsx +100 -31
  227. package/src/static-handler.ts +114 -0
  228. package/src/theme/ThemeProvider.tsx +21 -15
  229. package/src/theme/ThemeScript.tsx +5 -5
  230. package/src/theme/constants.ts +5 -2
  231. package/src/theme/index.ts +4 -14
  232. package/src/theme/theme-context.ts +4 -30
  233. package/src/theme/theme-script.ts +21 -18
  234. package/src/types/boundaries.ts +158 -0
  235. package/src/types/cache-types.ts +198 -0
  236. package/src/types/error-types.ts +192 -0
  237. package/src/types/global-namespace.ts +100 -0
  238. package/src/types/handler-context.ts +687 -0
  239. package/src/types/index.ts +88 -0
  240. package/src/types/loader-types.ts +183 -0
  241. package/src/types/route-config.ts +170 -0
  242. package/src/types/route-entry.ts +102 -0
  243. package/src/types/segments.ts +148 -0
  244. package/src/types.ts +1 -1623
  245. package/src/urls/include-helper.ts +197 -0
  246. package/src/urls/index.ts +53 -0
  247. package/src/urls/path-helper-types.ts +339 -0
  248. package/src/urls/path-helper.ts +329 -0
  249. package/src/urls/pattern-types.ts +95 -0
  250. package/src/urls/response-types.ts +106 -0
  251. package/src/urls/type-extraction.ts +372 -0
  252. package/src/urls/urls-function.ts +98 -0
  253. package/src/urls.ts +1 -802
  254. package/src/use-loader.tsx +85 -77
  255. package/src/vite/discovery/bundle-postprocess.ts +184 -0
  256. package/src/vite/discovery/discover-routers.ts +344 -0
  257. package/src/vite/discovery/prerender-collection.ts +385 -0
  258. package/src/vite/discovery/route-types-writer.ts +258 -0
  259. package/src/vite/discovery/self-gen-tracking.ts +47 -0
  260. package/src/vite/discovery/state.ts +110 -0
  261. package/src/vite/discovery/virtual-module-codegen.ts +203 -0
  262. package/src/vite/index.ts +11 -1133
  263. package/src/vite/plugin-types.ts +131 -0
  264. package/src/vite/plugins/cjs-to-esm.ts +93 -0
  265. package/src/vite/plugins/client-ref-dedup.ts +115 -0
  266. package/src/vite/plugins/client-ref-hashing.ts +105 -0
  267. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -51
  268. package/src/vite/plugins/expose-id-utils.ts +287 -0
  269. package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
  270. package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
  271. package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
  272. package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
  273. package/src/vite/plugins/expose-ids/types.ts +45 -0
  274. package/src/vite/plugins/expose-internal-ids.ts +569 -0
  275. package/src/vite/plugins/refresh-cmd.ts +65 -0
  276. package/src/vite/plugins/use-cache-transform.ts +323 -0
  277. package/src/vite/plugins/version-injector.ts +83 -0
  278. package/src/vite/plugins/version-plugin.ts +254 -0
  279. package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +23 -14
  280. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  281. package/src/vite/rango.ts +510 -0
  282. package/src/vite/router-discovery.ts +785 -0
  283. package/src/vite/utils/ast-handler-extract.ts +517 -0
  284. package/src/vite/utils/banner.ts +36 -0
  285. package/src/vite/utils/bundle-analysis.ts +137 -0
  286. package/src/vite/utils/manifest-utils.ts +70 -0
  287. package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
  288. package/src/vite/utils/prerender-utils.ts +189 -0
  289. package/src/vite/utils/shared-utils.ts +169 -0
  290. package/CLAUDE.md +0 -43
  291. package/src/browser/lru-cache.ts +0 -69
  292. package/src/browser/request-controller.ts +0 -164
  293. package/src/cache/memory-store.ts +0 -253
  294. package/src/href-context.ts +0 -33
  295. package/src/href.ts +0 -255
  296. package/src/server/route-manifest-cache.ts +0 -173
  297. package/src/vite/expose-handle-id.ts +0 -209
  298. package/src/vite/expose-loader-id.ts +0 -426
  299. package/src/vite/expose-location-state-id.ts +0 -177
  300. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import type { GetRegisteredRoutes } from "./types.js";
18
+ import type { ResponseEnvelope } from "./urls.js";
18
19
 
19
20
  /**
20
21
  * Parse constraint values into a union type for paths
@@ -44,30 +45,34 @@ type ParseConstraintPath<T extends string> =
44
45
  export type PatternToPath<T extends string> =
45
46
  // Optional + constrained param in middle: /:param(a|b)?/rest
46
47
  T extends `${infer Before}:${infer _Name}(${infer Constraint})?/${infer After}`
47
- ? PatternToPath<`${Before}${After}`> | `${Before}${ParseConstraintPath<Constraint>}/${PatternToPath<After>}`
48
- // Optional + constrained param at end: /path/:param(a|b)?
49
- : T extends `${infer Before}:${infer _Name}(${infer Constraint})?`
50
- ? Before | `${Before}${ParseConstraintPath<Constraint>}`
51
- // Constrained param in middle: /:param(a|b)/rest
52
- : T extends `${infer Before}:${infer _Name}(${infer Constraint})/${infer After}`
53
- ? `${Before}${ParseConstraintPath<Constraint>}/${PatternToPath<After>}`
54
- // Constrained param at end: /path/:param(a|b)
55
- : T extends `${infer Before}:${infer _Name}(${infer Constraint})`
56
- ? `${Before}${ParseConstraintPath<Constraint>}`
57
- // Optional param in middle: /:param?/rest
58
- : T extends `${infer Before}:${infer _Param}?/${infer After}`
59
- ? PatternToPath<`${Before}${After}`> | `${Before}${string}/${PatternToPath<After>}`
60
- // Optional param at end: /path/:param?
61
- : T extends `${infer Before}:${infer _Param}?`
62
- ? Before | `${Before}${string}`
63
- // Required param in middle: /:param/rest
64
- : T extends `${infer Before}:${infer _Param}/${infer After}`
65
- ? `${Before}${string}/${PatternToPath<After>}`
66
- // Required param at end: /path/:param
67
- : T extends `${infer Before}:${infer _Param}`
68
- ? `${Before}${string}`
69
- // Static path
70
- : T;
48
+ ?
49
+ | PatternToPath<`${Before}${After}`>
50
+ | `${Before}${ParseConstraintPath<Constraint>}/${PatternToPath<After>}`
51
+ : // Optional + constrained param at end: /path/:param(a|b)?
52
+ T extends `${infer Before}:${infer _Name}(${infer Constraint})?`
53
+ ? Before | `${Before}${ParseConstraintPath<Constraint>}`
54
+ : // Constrained param in middle: /:param(a|b)/rest
55
+ T extends `${infer Before}:${infer _Name}(${infer Constraint})/${infer After}`
56
+ ? `${Before}${ParseConstraintPath<Constraint>}/${PatternToPath<After>}`
57
+ : // Constrained param at end: /path/:param(a|b)
58
+ T extends `${infer Before}:${infer _Name}(${infer Constraint})`
59
+ ? `${Before}${ParseConstraintPath<Constraint>}`
60
+ : // Optional param in middle: /:param?/rest
61
+ T extends `${infer Before}:${infer _Param}?/${infer After}`
62
+ ?
63
+ | PatternToPath<`${Before}${After}`>
64
+ | `${Before}${string}/${PatternToPath<After>}`
65
+ : // Optional param at end: /path/:param?
66
+ T extends `${infer Before}:${infer _Param}?`
67
+ ? Before | `${Before}${string}`
68
+ : // Required param in middle: /:param/rest
69
+ T extends `${infer Before}:${infer _Param}/${infer After}`
70
+ ? `${Before}${string}/${PatternToPath<After>}`
71
+ : // Required param at end: /path/:param
72
+ T extends `${infer Before}:${infer _Param}`
73
+ ? `${Before}${string}`
74
+ : // Static path
75
+ T;
71
76
 
72
77
  /**
73
78
  * Allow optional query string (?...) and/or hash fragment (#...) suffix
@@ -82,10 +87,55 @@ type WithSuffix<T extends string> =
82
87
  | `${T}?${string}#${string}`;
83
88
 
84
89
  /**
85
- * Helper type to get pattern from routes, handling both Record and interface types
90
+ * Helper type to get pattern from routes, handling string values and { path, response } objects
91
+ */
92
+ type RoutePattern<TRoutes, K extends keyof TRoutes> = TRoutes[K] extends string
93
+ ? TRoutes[K]
94
+ : TRoutes[K] extends { readonly path: infer P extends string }
95
+ ? P
96
+ : string;
97
+
98
+ /**
99
+ * Reverse lookup: find route name where the pattern matches TPattern
100
+ */
101
+ type NameForPattern<TPattern extends string, TRoutes = GetRegisteredRoutes> = {
102
+ [K in keyof TRoutes]: RoutePattern<TRoutes, K> extends TPattern ? K : never;
103
+ }[keyof TRoutes];
104
+
105
+ /**
106
+ * Look up the response data type for a route pattern from RegisteredRoutes.
107
+ *
108
+ * Works by reverse-looking up the route name for the given pattern,
109
+ * then extracting the response type from the route entry.
110
+ *
111
+ * For static routes (no params), pattern === path:
112
+ * PathResponse<"/api/health"> → { status: string; timestamp: number }
113
+ *
114
+ * For dynamic routes, use the pattern:
115
+ * PathResponse<"/api/products/:id"> → Product
86
116
  */
87
- type RoutePattern<TRoutes, K extends keyof TRoutes> =
88
- TRoutes[K] extends string ? TRoutes[K] : string;
117
+ export type PathResponse<
118
+ TPattern extends string,
119
+ TRoutes = GetRegisteredRoutes,
120
+ > = ResponseEnvelope<
121
+ {
122
+ [K in keyof TRoutes]: RoutePattern<TRoutes, K> extends TPattern
123
+ ? TRoutes[K] extends { readonly response: infer R }
124
+ ? Exclude<R, Response>
125
+ : never
126
+ : never;
127
+ }[keyof TRoutes]
128
+ >;
129
+
130
+ /**
131
+ * Strip trailing slash from a path (e.g., "/blog/" -> "/blog" | "/blog/")
132
+ * Allows navigation to include() prefixes without requiring trailing slash
133
+ */
134
+ type OptionalTrailingSlash<T extends string> = T extends `${infer Base}/`
135
+ ? Base extends ""
136
+ ? T
137
+ : Base | T
138
+ : T;
89
139
 
90
140
  /**
91
141
  * Union of all valid paths from registered routes
@@ -96,7 +146,13 @@ type RoutePattern<TRoutes, K extends keyof TRoutes> =
96
146
  export type ValidPaths<TRoutes = GetRegisteredRoutes> =
97
147
  keyof TRoutes extends never
98
148
  ? `/${string}` // Fallback when no routes are registered
99
- : WithSuffix<PatternToPath<RoutePattern<TRoutes, keyof TRoutes>>>;
149
+ : WithSuffix<
150
+ {
151
+ [K in keyof TRoutes]: OptionalTrailingSlash<
152
+ PatternToPath<RoutePattern<TRoutes, K>>
153
+ >;
154
+ }[keyof TRoutes]
155
+ >;
100
156
 
101
157
  /**
102
158
  * Type-safe href function for client-side use
@@ -126,7 +182,41 @@ export type ValidPaths<TRoutes = GetRegisteredRoutes> =
126
182
  */
127
183
  export function href<T extends ValidPaths>(path: T, mount?: string): string {
128
184
  if (mount && mount !== "/") {
129
- return mount + path;
185
+ // Strip trailing slash from mount to avoid double-slash when joining
186
+ const normalizedMount = mount.endsWith("/") ? mount.slice(0, -1) : mount;
187
+ return normalizedMount + path;
130
188
  }
131
189
  return path;
132
190
  }
191
+
192
+ /**
193
+ * Props shape returned by href.json() etc. for spreading on <Link>.
194
+ * Sets data-external to trigger hard navigation (skips RSC fetch).
195
+ */
196
+ export interface ResponseHrefProps {
197
+ to: string;
198
+ "data-external": "";
199
+ }
200
+
201
+ type ResponseHrefFn = <T extends ValidPaths>(
202
+ path: T,
203
+ mount?: string,
204
+ ) => ResponseHrefProps;
205
+
206
+ function createResponseHrefTag(): ResponseHrefFn {
207
+ return (path, mount) => ({
208
+ to: href(path, mount),
209
+ "data-external": "" as const,
210
+ });
211
+ }
212
+
213
+ export namespace href {
214
+ export const json: ResponseHrefFn = createResponseHrefTag();
215
+ export const text: ResponseHrefFn = createResponseHrefTag();
216
+ export const html: ResponseHrefFn = createResponseHrefTag();
217
+ export const xml: ResponseHrefFn = createResponseHrefTag();
218
+ export const md: ResponseHrefFn = createResponseHrefTag();
219
+ export const image: ResponseHrefFn = createResponseHrefTag();
220
+ export const stream: ResponseHrefFn = createResponseHrefTag();
221
+ export const any: ResponseHrefFn = createResponseHrefTag();
222
+ }
package/src/index.rsc.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
- * rsc-router (react-server environment)
2
+ * @rangojs/router (react-server environment)
3
3
  *
4
- * This file is used when importing "rsc-router" from RSC (server components).
4
+ * This file is used when importing "@rangojs/router" from RSC (server components).
5
5
  * It re-exports everything from the universal index.ts plus adds server-side
6
- * createLoader that includes the actual loader function.
6
+ * implementations that replace the client-side error stubs.
7
7
  *
8
8
  * The bundler uses the "react-server" export condition to select this file
9
9
  * in RSC context, while the regular index.ts is used in client components.
@@ -11,8 +11,6 @@
11
11
 
12
12
  // Re-export all universal exports from index.ts
13
13
  export {
14
- // Universal rendering utilities
15
- renderSegments,
16
14
  // Error classes
17
15
  RouteNotFoundError,
18
16
  DataNotFoundError,
@@ -21,18 +19,20 @@ export {
21
19
  HandlerError,
22
20
  BuildError,
23
21
  InvalidHandlerError,
24
- NetworkError,
25
- isNetworkError,
26
- sanitizeError,
22
+ RouterError,
23
+ Skip,
24
+ isSkip,
27
25
  } from "./index.js";
28
26
 
29
27
  // Re-export all types from types.ts (user-facing types only)
30
28
  export type {
31
29
  // Configuration types
32
30
  DocumentProps,
33
- RouterEnv,
34
31
  DefaultEnv,
35
32
  RouteDefinition,
33
+ RouteConfig,
34
+ RouteDefinitionOptions,
35
+ TrailingSlashMode,
36
36
  // Handler types
37
37
  Handler,
38
38
  HandlerContext,
@@ -50,9 +50,6 @@ export type {
50
50
  LoaderContext,
51
51
  FetchableLoaderOptions,
52
52
  LoadOptions,
53
- LoaderActionContext,
54
- LoaderAction,
55
- LoaderMiddlewareFn,
56
53
  // Error boundary types
57
54
  ErrorInfo,
58
55
  ErrorBoundaryFallbackProps,
@@ -62,14 +59,71 @@ export type {
62
59
  NotFoundInfo,
63
60
  NotFoundBoundaryFallbackProps,
64
61
  NotFoundBoundaryHandler,
62
+ // Error handling callback types
63
+ ErrorPhase,
64
+ OnErrorContext,
65
+ OnErrorCallback,
65
66
  } from "./types.js";
66
67
 
67
68
  // Router options type (server-only, so import directly)
68
- export type { RSCRouterOptions } from "./router.js";
69
+ export type {
70
+ RSCRouterOptions,
71
+ SSRStreamMode,
72
+ SSROptions,
73
+ ResolveStreamingContext,
74
+ } from "./router.js";
75
+
76
+ // Server-side createLoader and redirect
77
+ export {
78
+ createLoader,
79
+ redirect,
80
+ type RouteHelpers,
81
+ type RouteHandlers,
82
+ // Globally importable route helpers for composition
83
+ layout,
84
+ cache,
85
+ middleware,
86
+ revalidate,
87
+ loader,
88
+ loading,
89
+ parallel,
90
+ intercept,
91
+ when,
92
+ errorBoundary,
93
+ notFoundBoundary,
94
+ transition,
95
+ } from "./route-definition.js";
96
+
97
+ // Composition types for reusable callback factories
98
+ export type {
99
+ RouteUseItem,
100
+ LayoutUseItem,
101
+ AllUseItems,
102
+ UseItems,
103
+ } from "./route-types.js";
104
+
105
+ // Handle API
106
+ export { createHandle, isHandle, type Handle } from "./handle.js";
69
107
 
70
- // Server-side createLoader - includes the actual loader function
71
- // This is the key addition for RSC context
72
- export { createLoader } from "./route-definition.js";
108
+ // Context variable API (typed ctx.set/ctx.get tokens)
109
+ export { createVar, type ContextVar } from "./context-var.js";
110
+
111
+ // CSP nonce token (use with ctx.get(nonce) in middleware/handlers)
112
+ export { nonce } from "./rsc/nonce.js";
113
+
114
+ // Pre-render handler API
115
+ export {
116
+ Prerender,
117
+ type PrerenderHandlerDefinition,
118
+ type PrerenderPassthroughContext,
119
+ type PrerenderOptions,
120
+ type BuildContext,
121
+ type StaticBuildContext,
122
+ type GetParamsContext,
123
+ } from "./prerender.js";
124
+
125
+ // Static handler API
126
+ export { Static, type StaticHandlerDefinition } from "./static-handler.js";
73
127
 
74
128
  // Django-style URL patterns (RSC/server context)
75
129
  export {
@@ -79,6 +133,17 @@ export {
79
133
  type UrlPatterns,
80
134
  type IncludeOptions,
81
135
  type IncludeItem,
136
+ type RouteResponse,
137
+ type ResponseError,
138
+ type ResponseEnvelope,
139
+ type ResponseHandler,
140
+ type ResponseHandlerContext,
141
+ type JsonResponseHandler,
142
+ type TextResponseHandler,
143
+ type JsonValue,
144
+ type ResponsePathFn,
145
+ type JsonResponsePathFn,
146
+ type TextResponsePathFn,
82
147
  } from "./urls.js";
83
148
 
84
149
  // Core router (server-side)
@@ -86,6 +151,7 @@ export {
86
151
  createRouter,
87
152
  type RSCRouter,
88
153
  type RootLayoutProps,
154
+ type RouterRequestInput,
89
155
  } from "./router.js";
90
156
 
91
157
  // RSC handler types (server-side)
@@ -93,7 +159,75 @@ export type { HandlerCacheConfig } from "./rsc/types.js";
93
159
 
94
160
  // Built-in handles (server-side)
95
161
  export { Meta } from "./handles/meta.js";
162
+ export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
163
+
164
+ // Request context (for accessing request data in server actions/components).
165
+ // Re-exported with a narrowed return type so that public consumers only see
166
+ // public members. Internal code imports from "./server/request-context.js"
167
+ // directly and gets the full type.
168
+ import { getRequestContext as _getRequestContextInternal } from "./server/request-context.js";
169
+ export type { PublicRequestContext as RequestContext } from "./server/request-context.js";
170
+ import type { PublicRequestContext } from "./server/request-context.js";
171
+ import type { DefaultEnv } from "./types/global-namespace.js";
172
+
173
+ export const getRequestContext: <
174
+ TEnv = DefaultEnv,
175
+ >() => PublicRequestContext<TEnv> = _getRequestContextInternal;
96
176
 
97
- // Href type utilities for type-safe URL generation
98
- export type { ScopedHrefFunction, HrefFunction, ExtractLocalRoutes } from "./href.js";
99
- export { scopedHref } from "./href.js";
177
+ // Request-scoped shorthands
178
+ export {
179
+ cookies,
180
+ headers,
181
+ type CookieStore,
182
+ type Cookie,
183
+ type ReadonlyHeaders,
184
+ } from "./server/cookie-store.js";
185
+
186
+ // Meta types
187
+ export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
188
+
189
+ // Middleware context types
190
+ export type { MiddlewareContext, CookieOptions } from "./router/middleware.js";
191
+
192
+ // Reverse type utilities for type-safe URL generation (Django-style URL reversal)
193
+ export type {
194
+ ScopedReverseFunction,
195
+ ReverseFunction,
196
+ ExtractLocalRoutes,
197
+ ParamsFor,
198
+ } from "./reverse.js";
199
+ export { scopedReverse, createReverse } from "./reverse.js";
200
+
201
+ // Search params schema types
202
+ export type {
203
+ SearchSchema,
204
+ SearchSchemaValue,
205
+ ResolveSearchSchema,
206
+ RouteSearchParams,
207
+ RouteParams,
208
+ } from "./search-params.js";
209
+
210
+ // Location state (universal)
211
+ export {
212
+ createLocationState,
213
+ type LocationStateDefinition,
214
+ type LocationStateEntry,
215
+ type LocationStateOptions,
216
+ } from "./browser/react/location-state-shared.js";
217
+
218
+ // Path-based response type lookup from RegisteredRoutes
219
+ export type { PathResponse } from "./href-client.js";
220
+
221
+ // Telemetry sink
222
+ export { createConsoleSink } from "./router/telemetry.js";
223
+ export { createOTelSink } from "./router/telemetry-otel.js";
224
+ export type { OTelTracer, OTelSpan } from "./router/telemetry-otel.js";
225
+ export type { TelemetrySink, TelemetryEvent } from "./router/telemetry.js";
226
+
227
+ // Timeout types and error class
228
+ export { RouterTimeoutError } from "./router/timeout.js";
229
+ export type {
230
+ RouterTimeouts,
231
+ TimeoutPhase,
232
+ TimeoutContext,
233
+ } from "./router/timeout.js";