@rangojs/router 0.0.0-experimental.3 → 0.0.0-experimental.31

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 +883 -4
  3. package/dist/bin/rango.js +1601 -0
  4. package/dist/vite/index.js +4655 -747
  5. package/package.json +78 -50
  6. package/skills/breadcrumbs/SKILL.md +206 -0
  7. package/skills/cache-guide/SKILL.md +262 -0
  8. package/skills/caching/SKILL.md +54 -25
  9. package/skills/composability/SKILL.md +172 -0
  10. package/skills/debug-manifest/SKILL.md +12 -8
  11. package/skills/document-cache/SKILL.md +23 -21
  12. package/skills/fonts/SKILL.md +167 -0
  13. package/skills/hooks/SKILL.md +389 -64
  14. package/skills/host-router/SKILL.md +218 -0
  15. package/skills/intercept/SKILL.md +133 -10
  16. package/skills/layout/SKILL.md +102 -5
  17. package/skills/links/SKILL.md +239 -0
  18. package/skills/loader/SKILL.md +366 -29
  19. package/skills/middleware/SKILL.md +173 -36
  20. package/skills/mime-routes/SKILL.md +128 -0
  21. package/skills/parallel/SKILL.md +80 -3
  22. package/skills/prerender/SKILL.md +643 -0
  23. package/skills/rango/SKILL.md +86 -16
  24. package/skills/response-routes/SKILL.md +411 -0
  25. package/skills/route/SKILL.md +227 -15
  26. package/skills/router-setup/SKILL.md +225 -32
  27. package/skills/tailwind/SKILL.md +129 -0
  28. package/skills/theme/SKILL.md +12 -11
  29. package/skills/typesafety/SKILL.md +415 -87
  30. package/skills/use-cache/SKILL.md +324 -0
  31. package/src/__internal.ts +10 -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 +20 -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 +201 -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 +267 -317
  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 +173 -73
  54. package/src/browser/react/NavigationProvider.tsx +138 -27
  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 +37 -0
  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 +49 -65
  66. package/src/browser/react/use-href.tsx +20 -188
  67. package/src/browser/react/use-link-status.ts +6 -5
  68. package/src/browser/react/use-mount.ts +31 -0
  69. package/src/browser/react/use-navigation.ts +27 -78
  70. package/src/browser/react/use-params.ts +65 -0
  71. package/src/browser/react/use-pathname.ts +47 -0
  72. package/src/browser/react/use-router.ts +63 -0
  73. package/src/browser/react/use-search-params.ts +56 -0
  74. package/src/browser/react/use-segments.ts +80 -97
  75. package/src/browser/response-adapter.ts +73 -0
  76. package/src/browser/rsc-router.tsx +111 -26
  77. package/src/browser/scroll-restoration.ts +92 -16
  78. package/src/browser/segment-reconciler.ts +216 -0
  79. package/src/browser/segment-structure-assert.ts +83 -0
  80. package/src/browser/server-action-bridge.ts +504 -584
  81. package/src/browser/shallow.ts +6 -1
  82. package/src/browser/types.ts +92 -57
  83. package/src/browser/validate-redirect-origin.ts +29 -0
  84. package/src/build/generate-manifest.ts +438 -0
  85. package/src/build/generate-route-types.ts +36 -0
  86. package/src/build/index.ts +35 -0
  87. package/src/build/route-trie.ts +265 -0
  88. package/src/build/route-types/ast-helpers.ts +25 -0
  89. package/src/build/route-types/ast-route-extraction.ts +98 -0
  90. package/src/build/route-types/codegen.ts +102 -0
  91. package/src/build/route-types/include-resolution.ts +411 -0
  92. package/src/build/route-types/param-extraction.ts +48 -0
  93. package/src/build/route-types/per-module-writer.ts +128 -0
  94. package/src/build/route-types/router-processing.ts +469 -0
  95. package/src/build/route-types/scan-filter.ts +78 -0
  96. package/src/build/runtime-discovery.ts +231 -0
  97. package/src/cache/background-task.ts +34 -0
  98. package/src/cache/cache-key-utils.ts +44 -0
  99. package/src/cache/cache-policy.ts +125 -0
  100. package/src/cache/cache-runtime.ts +338 -0
  101. package/src/cache/cache-scope.ts +120 -303
  102. package/src/cache/cf/cf-cache-store.ts +119 -7
  103. package/src/cache/cf/index.ts +8 -2
  104. package/src/cache/document-cache.ts +101 -72
  105. package/src/cache/handle-capture.ts +81 -0
  106. package/src/cache/handle-snapshot.ts +41 -0
  107. package/src/cache/index.ts +0 -15
  108. package/src/cache/memory-segment-store.ts +191 -13
  109. package/src/cache/profile-registry.ts +73 -0
  110. package/src/cache/read-through-swr.ts +134 -0
  111. package/src/cache/segment-codec.ts +256 -0
  112. package/src/cache/taint.ts +98 -0
  113. package/src/cache/types.ts +72 -122
  114. package/src/client.rsc.tsx +12 -15
  115. package/src/client.tsx +115 -135
  116. package/src/component-utils.ts +4 -4
  117. package/src/components/DefaultDocument.tsx +5 -1
  118. package/src/context-var.ts +86 -0
  119. package/src/debug.ts +17 -7
  120. package/src/errors.ts +108 -2
  121. package/src/handle.ts +34 -19
  122. package/src/handles/MetaTags.tsx +73 -20
  123. package/src/handles/breadcrumbs.ts +66 -0
  124. package/src/handles/index.ts +1 -0
  125. package/src/handles/meta.ts +30 -13
  126. package/src/host/cookie-handler.ts +165 -0
  127. package/src/host/errors.ts +97 -0
  128. package/src/host/index.ts +53 -0
  129. package/src/host/pattern-matcher.ts +214 -0
  130. package/src/host/router.ts +352 -0
  131. package/src/host/testing.ts +79 -0
  132. package/src/host/types.ts +146 -0
  133. package/src/host/utils.ts +25 -0
  134. package/src/href-client.ts +135 -49
  135. package/src/index.rsc.ts +183 -17
  136. package/src/index.ts +241 -24
  137. package/src/internal-debug.ts +11 -0
  138. package/src/loader.rsc.ts +27 -142
  139. package/src/loader.ts +27 -10
  140. package/src/network-error-thrower.tsx +3 -1
  141. package/src/outlet-provider.tsx +45 -0
  142. package/src/prerender/param-hash.ts +37 -0
  143. package/src/prerender/store.ts +185 -0
  144. package/src/prerender.ts +463 -0
  145. package/src/reverse.ts +330 -0
  146. package/src/root-error-boundary.tsx +41 -29
  147. package/src/route-content-wrapper.tsx +9 -11
  148. package/src/route-definition/dsl-helpers.ts +934 -0
  149. package/src/route-definition/helper-factories.ts +200 -0
  150. package/src/route-definition/helpers-types.ts +430 -0
  151. package/src/route-definition/index.ts +52 -0
  152. package/src/route-definition/redirect.ts +93 -0
  153. package/src/route-definition.ts +1 -1388
  154. package/src/route-map-builder.ts +241 -112
  155. package/src/route-name.ts +53 -0
  156. package/src/route-types.ts +70 -9
  157. package/src/router/content-negotiation.ts +116 -0
  158. package/src/router/debug-manifest.ts +72 -0
  159. package/src/router/error-handling.ts +9 -9
  160. package/src/router/find-match.ts +158 -0
  161. package/src/router/handler-context.ts +371 -81
  162. package/src/router/intercept-resolution.ts +395 -0
  163. package/src/router/lazy-includes.ts +234 -0
  164. package/src/router/loader-resolution.ts +215 -122
  165. package/src/router/logging.ts +248 -0
  166. package/src/router/manifest.ts +155 -32
  167. package/src/router/match-api.ts +620 -0
  168. package/src/router/match-context.ts +5 -3
  169. package/src/router/match-handlers.ts +440 -0
  170. package/src/router/match-middleware/background-revalidation.ts +80 -93
  171. package/src/router/match-middleware/cache-lookup.ts +382 -9
  172. package/src/router/match-middleware/cache-store.ts +51 -22
  173. package/src/router/match-middleware/intercept-resolution.ts +55 -17
  174. package/src/router/match-middleware/segment-resolution.ts +24 -6
  175. package/src/router/match-pipelines.ts +10 -45
  176. package/src/router/match-result.ts +34 -29
  177. package/src/router/metrics.ts +235 -15
  178. package/src/router/middleware-cookies.ts +55 -0
  179. package/src/router/middleware-types.ts +222 -0
  180. package/src/router/middleware.ts +324 -367
  181. package/src/router/pattern-matching.ts +321 -30
  182. package/src/router/prerender-match.ts +400 -0
  183. package/src/router/preview-match.ts +170 -0
  184. package/src/router/revalidation.ts +137 -38
  185. package/src/router/router-context.ts +36 -21
  186. package/src/router/router-interfaces.ts +452 -0
  187. package/src/router/router-options.ts +592 -0
  188. package/src/router/router-registry.ts +24 -0
  189. package/src/router/segment-resolution/fresh.ts +570 -0
  190. package/src/router/segment-resolution/helpers.ts +263 -0
  191. package/src/router/segment-resolution/loader-cache.ts +198 -0
  192. package/src/router/segment-resolution/revalidation.ts +1241 -0
  193. package/src/router/segment-resolution/static-store.ts +67 -0
  194. package/src/router/segment-resolution.ts +21 -0
  195. package/src/router/segment-wrappers.ts +289 -0
  196. package/src/router/telemetry-otel.ts +299 -0
  197. package/src/router/telemetry.ts +300 -0
  198. package/src/router/timeout.ts +148 -0
  199. package/src/router/trie-matching.ts +239 -0
  200. package/src/router/types.ts +77 -3
  201. package/src/router.ts +688 -3656
  202. package/src/rsc/handler-context.ts +45 -0
  203. package/src/rsc/handler.ts +786 -760
  204. package/src/rsc/helpers.ts +140 -6
  205. package/src/rsc/index.ts +5 -25
  206. package/src/rsc/loader-fetch.ts +209 -0
  207. package/src/rsc/manifest-init.ts +86 -0
  208. package/src/rsc/nonce.ts +14 -0
  209. package/src/rsc/origin-guard.ts +141 -0
  210. package/src/rsc/progressive-enhancement.ts +379 -0
  211. package/src/rsc/response-error.ts +37 -0
  212. package/src/rsc/response-route-handler.ts +347 -0
  213. package/src/rsc/rsc-rendering.ts +235 -0
  214. package/src/rsc/runtime-warnings.ts +42 -0
  215. package/src/rsc/server-action.ts +348 -0
  216. package/src/rsc/ssr-setup.ts +128 -0
  217. package/src/rsc/types.ts +40 -14
  218. package/src/search-params.ts +230 -0
  219. package/src/segment-system.tsx +57 -61
  220. package/src/server/context.ts +202 -51
  221. package/src/server/cookie-store.ts +190 -0
  222. package/src/server/fetchable-loader-store.ts +37 -0
  223. package/src/server/handle-store.ts +94 -15
  224. package/src/server/loader-registry.ts +15 -56
  225. package/src/server/request-context.ts +422 -70
  226. package/src/server.ts +36 -120
  227. package/src/ssr/index.tsx +157 -26
  228. package/src/static-handler.ts +114 -0
  229. package/src/theme/ThemeProvider.tsx +21 -15
  230. package/src/theme/ThemeScript.tsx +5 -5
  231. package/src/theme/constants.ts +5 -2
  232. package/src/theme/index.ts +4 -14
  233. package/src/theme/theme-context.ts +4 -30
  234. package/src/theme/theme-script.ts +21 -18
  235. package/src/types/boundaries.ts +158 -0
  236. package/src/types/cache-types.ts +198 -0
  237. package/src/types/error-types.ts +192 -0
  238. package/src/types/global-namespace.ts +100 -0
  239. package/src/types/handler-context.ts +687 -0
  240. package/src/types/index.ts +88 -0
  241. package/src/types/loader-types.ts +183 -0
  242. package/src/types/route-config.ts +170 -0
  243. package/src/types/route-entry.ts +102 -0
  244. package/src/types/segments.ts +148 -0
  245. package/src/types.ts +1 -1577
  246. package/src/urls/include-helper.ts +197 -0
  247. package/src/urls/index.ts +53 -0
  248. package/src/urls/path-helper-types.ts +339 -0
  249. package/src/urls/path-helper.ts +329 -0
  250. package/src/urls/pattern-types.ts +95 -0
  251. package/src/urls/response-types.ts +106 -0
  252. package/src/urls/type-extraction.ts +372 -0
  253. package/src/urls/urls-function.ts +98 -0
  254. package/src/urls.ts +1 -726
  255. package/src/use-loader.tsx +85 -77
  256. package/src/vite/discovery/bundle-postprocess.ts +184 -0
  257. package/src/vite/discovery/discover-routers.ts +344 -0
  258. package/src/vite/discovery/prerender-collection.ts +385 -0
  259. package/src/vite/discovery/route-types-writer.ts +258 -0
  260. package/src/vite/discovery/self-gen-tracking.ts +47 -0
  261. package/src/vite/discovery/state.ts +110 -0
  262. package/src/vite/discovery/virtual-module-codegen.ts +203 -0
  263. package/src/vite/index.ts +11 -782
  264. package/src/vite/plugin-types.ts +131 -0
  265. package/src/vite/plugins/cjs-to-esm.ts +93 -0
  266. package/src/vite/plugins/client-ref-dedup.ts +115 -0
  267. package/src/vite/plugins/client-ref-hashing.ts +105 -0
  268. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -51
  269. package/src/vite/plugins/expose-id-utils.ts +287 -0
  270. package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
  271. package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
  272. package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
  273. package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
  274. package/src/vite/plugins/expose-ids/types.ts +45 -0
  275. package/src/vite/plugins/expose-internal-ids.ts +569 -0
  276. package/src/vite/plugins/refresh-cmd.ts +65 -0
  277. package/src/vite/plugins/use-cache-transform.ts +323 -0
  278. package/src/vite/plugins/version-injector.ts +83 -0
  279. package/src/vite/plugins/version-plugin.ts +254 -0
  280. package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +29 -15
  281. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  282. package/src/vite/rango.ts +510 -0
  283. package/src/vite/router-discovery.ts +785 -0
  284. package/src/vite/utils/ast-handler-extract.ts +517 -0
  285. package/src/vite/utils/banner.ts +36 -0
  286. package/src/vite/utils/bundle-analysis.ts +137 -0
  287. package/src/vite/utils/manifest-utils.ts +70 -0
  288. package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
  289. package/src/vite/utils/prerender-utils.ts +189 -0
  290. package/src/vite/utils/shared-utils.ts +169 -0
  291. package/CLAUDE.md +0 -3
  292. package/src/browser/lru-cache.ts +0 -69
  293. package/src/browser/request-controller.ts +0 -164
  294. package/src/cache/memory-store.ts +0 -253
  295. package/src/href-context.ts +0 -33
  296. package/src/href.ts +0 -255
  297. package/src/vite/expose-handle-id.ts +0 -209
  298. package/src/vite/expose-loader-id.ts +0 -357
  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,41 +146,77 @@ 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
103
159
  *
104
- * This is an identity function - it returns the path unchanged.
105
- * The value is in TypeScript validation: invalid paths cause compile errors.
106
- *
107
- * Works with:
108
- * - Static paths: href("/about")
109
- * - Dynamic segments: href("/blog/my-post")
110
- * - Multiple segments: href("/shop/product/widget/reviews/123")
111
- *
112
- * Does NOT validate:
113
- * - Query strings (passed through as-is)
114
- * - Hash fragments (passed through as-is)
160
+ * Without mount: identity function, validates absolute paths at compile time.
161
+ * With mount: prepends mount path, for use with useMount() inside include() scopes.
115
162
  *
116
163
  * @param path - A valid path matching one of the registered route patterns
117
- * @returns The path unchanged
164
+ * @param mount - Optional mount prefix from useMount() for include-scoped paths
165
+ * @returns The resolved path
118
166
  *
119
167
  * @example
120
168
  * ```typescript
121
- * // Valid paths (compile)
122
- * href("/blog/hello"); // matches /blog/:slug
123
- * href("/shop/product/widget"); // matches /shop/product/:slug
124
- * href("/shop/product/widget/reviews"); // matches /shop/product/:slug/reviews
169
+ * // Absolute paths (type-safe)
170
+ * href("/blog/hello"); // "/blog/hello"
171
+ * href("/shop/product/widget"); // "/shop/product/widget"
125
172
  *
126
- * // Query strings and hashes pass through (not validated)
173
+ * // With mount (inside an include)
174
+ * const mount = useMount(); // "/articles"
175
+ * href("/", mount); // "/articles/"
176
+ * href("/my-post", mount); // "/articles/my-post"
177
+ *
178
+ * // Query strings and hashes pass through
127
179
  * href("/blog/hello?page=1");
128
180
  * href("/about#contact");
129
- *
130
- * // Invalid paths (TypeScript error)
131
- * href("/nonexistent"); // Error: not assignable to ValidPaths
132
181
  * ```
133
182
  */
134
- export function href<T extends ValidPaths>(path: T): T {
183
+ export function href<T extends ValidPaths>(path: T, mount?: string): string {
184
+ if (mount && mount !== "/") {
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;
188
+ }
135
189
  return path;
136
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.
@@ -24,17 +24,23 @@ export {
24
24
  NetworkError,
25
25
  isNetworkError,
26
26
  sanitizeError,
27
+ RouterError,
28
+ Skip,
29
+ isSkip,
27
30
  } from "./index.js";
28
31
 
29
32
  // Re-export all types from types.ts (user-facing types only)
30
33
  export type {
31
34
  // Configuration types
32
35
  DocumentProps,
33
- RouterEnv,
34
36
  DefaultEnv,
35
37
  RouteDefinition,
38
+ RouteConfig,
39
+ RouteDefinitionOptions,
40
+ TrailingSlashMode,
36
41
  // Handler types
37
42
  Handler,
43
+ ScopedRouteMap,
38
44
  HandlerContext,
39
45
  ExtractParams,
40
46
  GenericParams,
@@ -50,9 +56,6 @@ export type {
50
56
  LoaderContext,
51
57
  FetchableLoaderOptions,
52
58
  LoadOptions,
53
- LoaderActionContext,
54
- LoaderAction,
55
- LoaderMiddlewareFn,
56
59
  // Error boundary types
57
60
  ErrorInfo,
58
61
  ErrorBoundaryFallbackProps,
@@ -62,23 +65,97 @@ export type {
62
65
  NotFoundInfo,
63
66
  NotFoundBoundaryFallbackProps,
64
67
  NotFoundBoundaryHandler,
68
+ // Error handling callback types
69
+ ErrorPhase,
70
+ OnErrorContext,
71
+ OnErrorCallback,
65
72
  } from "./types.js";
66
73
 
67
74
  // Router options type (server-only, so import directly)
68
- export type { RSCRouterOptions } from "./router.js";
75
+ export type {
76
+ RSCRouterOptions,
77
+ SSRStreamMode,
78
+ SSROptions,
79
+ ResolveStreamingContext,
80
+ } from "./router.js";
81
+
82
+ // Server-side createLoader and redirect
83
+ export {
84
+ createLoader,
85
+ redirect,
86
+ type RouteHelpers,
87
+ type RouteHandlers,
88
+ // Globally importable route helpers for composition
89
+ layout,
90
+ cache,
91
+ middleware,
92
+ revalidate,
93
+ loader,
94
+ loading,
95
+ parallel,
96
+ intercept,
97
+ when,
98
+ errorBoundary,
99
+ notFoundBoundary,
100
+ transition,
101
+ } from "./route-definition.js";
102
+
103
+ // Composition types for reusable callback factories
104
+ export type {
105
+ RouteUseItem,
106
+ LayoutUseItem,
107
+ AllUseItems,
108
+ UseItems,
109
+ } from "./route-types.js";
110
+
111
+ // Handle API
112
+ export { createHandle, isHandle, type Handle } from "./handle.js";
113
+
114
+ // Context variable API (typed ctx.set/ctx.get tokens)
115
+ export { createVar, type ContextVar } from "./context-var.js";
69
116
 
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";
117
+ // CSP nonce token (use with ctx.get(nonce) in middleware/handlers)
118
+ export { nonce } from "./rsc/nonce.js";
119
+
120
+ // Pre-render handler API
121
+ export {
122
+ Prerender,
123
+ isPrerenderHandler,
124
+ type PrerenderHandlerDefinition,
125
+ type PrerenderPassthroughContext,
126
+ type PrerenderOptions,
127
+ type BuildContext,
128
+ type StaticBuildContext,
129
+ type GetParamsContext,
130
+ } from "./prerender.js";
131
+
132
+ // Static handler API
133
+ export {
134
+ Static,
135
+ isStaticHandler,
136
+ type StaticHandlerDefinition,
137
+ } from "./static-handler.js";
73
138
 
74
139
  // Django-style URL patterns (RSC/server context)
75
140
  export {
76
141
  urls,
142
+ RESPONSE_TYPE,
77
143
  type PathHelpers,
78
144
  type PathOptions,
79
145
  type UrlPatterns,
80
146
  type IncludeOptions,
81
147
  type IncludeItem,
148
+ type RouteResponse,
149
+ type ResponseError,
150
+ type ResponseEnvelope,
151
+ type ResponseHandler,
152
+ type ResponseHandlerContext,
153
+ type JsonResponseHandler,
154
+ type TextResponseHandler,
155
+ type JsonValue,
156
+ type ResponsePathFn,
157
+ type JsonResponsePathFn,
158
+ type TextResponsePathFn,
82
159
  } from "./urls.js";
83
160
 
84
161
  // Core router (server-side)
@@ -86,15 +163,104 @@ export {
86
163
  createRouter,
87
164
  type RSCRouter,
88
165
  type RootLayoutProps,
166
+ type RouterRequestInput,
89
167
  } from "./router.js";
90
168
 
91
- // RSC handler (server-side)
92
- export { createRSCHandler } from "./rsc/handler.js";
93
- export type { CreateRSCHandlerOptions, HandlerCacheConfig } from "./rsc/types.js";
169
+ // RSC handler types (server-side)
170
+ export type { HandlerCacheConfig } from "./rsc/types.js";
94
171
 
95
172
  // Built-in handles (server-side)
96
173
  export { Meta } from "./handles/meta.js";
174
+ export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
175
+
176
+ // Request context (for accessing request data in server actions/components).
177
+ // Re-exported with a narrowed return type so that public consumers only see
178
+ // public members. Internal code imports from "./server/request-context.js"
179
+ // directly and gets the full type.
180
+ import { getRequestContext as _getRequestContextInternal } from "./server/request-context.js";
181
+ export type { PublicRequestContext as RequestContext } from "./server/request-context.js";
182
+ import type { PublicRequestContext } from "./server/request-context.js";
183
+ import type { DefaultEnv } from "./types/global-namespace.js";
184
+
185
+ export const getRequestContext: <
186
+ TEnv = DefaultEnv,
187
+ >() => PublicRequestContext<TEnv> = _getRequestContextInternal;
188
+
189
+ // Request-scoped shorthands
190
+ export {
191
+ cookies,
192
+ headers,
193
+ type CookieStore,
194
+ type Cookie,
195
+ type ReadonlyHeaders,
196
+ } from "./server/cookie-store.js";
197
+
198
+ // Meta types
199
+ export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
200
+
201
+ // Middleware context types
202
+ export type { MiddlewareContext, CookieOptions } from "./router/middleware.js";
203
+
204
+ // Reverse type utilities for type-safe URL generation (Django-style URL reversal)
205
+ export type {
206
+ ScopedReverseFunction,
207
+ ReverseFunction,
208
+ ExtractLocalRoutes,
209
+ ParamsFor,
210
+ SanitizePrefix,
211
+ MergeRoutes,
212
+ } from "./reverse.js";
213
+ export { scopedReverse, createReverse } from "./reverse.js";
214
+
215
+ // Search params schema types
216
+ export type {
217
+ SearchSchema,
218
+ SearchSchemaValue,
219
+ ResolveSearchSchema,
220
+ RouteSearchParams,
221
+ RouteParams,
222
+ } from "./search-params.js";
97
223
 
98
- // Href type utilities for type-safe URL generation
99
- export type { ScopedHrefFunction, HrefFunction, ExtractLocalRoutes } from "./href.js";
100
- export { scopedHref } from "./href.js";
224
+ // Debug utilities for route matching (development only)
225
+ export {
226
+ enableMatchDebug,
227
+ getMatchDebugStats,
228
+ } from "./router/pattern-matching.js";
229
+
230
+ // Location state (universal)
231
+ export {
232
+ createLocationState,
233
+ type LocationStateDefinition,
234
+ type LocationStateEntry,
235
+ type LocationStateOptions,
236
+ } from "./browser/react/location-state-shared.js";
237
+
238
+ // Path-based response type lookup from RegisteredRoutes
239
+ export type { PathResponse } from "./href-client.js";
240
+
241
+ // Telemetry sink
242
+ export { createConsoleSink } from "./router/telemetry.js";
243
+ export { createOTelSink } from "./router/telemetry-otel.js";
244
+ export type { OTelTracer, OTelSpan } from "./router/telemetry-otel.js";
245
+ export type {
246
+ TelemetrySink,
247
+ TelemetryEvent,
248
+ RequestStartEvent,
249
+ RequestEndEvent,
250
+ RequestErrorEvent,
251
+ RequestTimeoutEvent,
252
+ LoaderStartEvent,
253
+ LoaderEndEvent,
254
+ LoaderErrorEvent,
255
+ HandlerErrorEvent,
256
+ CacheDecisionEvent,
257
+ RevalidationDecisionEvent,
258
+ } from "./router/telemetry.js";
259
+
260
+ // Timeout types and error class
261
+ export { RouterTimeoutError } from "./router/timeout.js";
262
+ export type {
263
+ RouterTimeouts,
264
+ TimeoutPhase,
265
+ TimeoutContext,
266
+ } from "./router/timeout.js";