@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bd6e11bc

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 (285) hide show
  1. package/README.md +196 -43
  2. package/dist/bin/rango.js +277 -99
  3. package/dist/testing/vitest.js +48 -0
  4. package/dist/vite/index.js +2779 -1064
  5. package/dist/vite/index.js.bak +5448 -0
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +57 -11
  8. package/skills/breadcrumbs/SKILL.md +3 -1
  9. package/skills/bundle-analysis/SKILL.md +159 -0
  10. package/skills/cache-guide/SKILL.md +243 -21
  11. package/skills/caching/SKILL.md +155 -6
  12. package/skills/composability/SKILL.md +27 -2
  13. package/skills/document-cache/SKILL.md +78 -55
  14. package/skills/handler-use/SKILL.md +364 -0
  15. package/skills/hooks/SKILL.md +229 -20
  16. package/skills/host-router/SKILL.md +45 -20
  17. package/skills/i18n/SKILL.md +276 -0
  18. package/skills/intercept/SKILL.md +46 -4
  19. package/skills/layout/SKILL.md +28 -7
  20. package/skills/links/SKILL.md +249 -17
  21. package/skills/loader/SKILL.md +273 -53
  22. package/skills/middleware/SKILL.md +49 -12
  23. package/skills/migrate-nextjs/SKILL.md +562 -0
  24. package/skills/migrate-react-router/SKILL.md +769 -0
  25. package/skills/mime-routes/SKILL.md +27 -0
  26. package/skills/observability/SKILL.md +137 -0
  27. package/skills/parallel/SKILL.md +197 -6
  28. package/skills/prerender/SKILL.md +123 -100
  29. package/skills/rango/SKILL.md +242 -22
  30. package/skills/react-compiler/SKILL.md +168 -0
  31. package/skills/response-routes/SKILL.md +66 -9
  32. package/skills/route/SKILL.md +88 -4
  33. package/skills/router-setup/SKILL.md +90 -5
  34. package/skills/server-actions/SKILL.md +751 -0
  35. package/skills/streams-and-websockets/SKILL.md +283 -0
  36. package/skills/testing/SKILL.md +716 -0
  37. package/skills/typesafety/SKILL.md +329 -27
  38. package/skills/use-cache/SKILL.md +34 -5
  39. package/skills/view-transitions/SKILL.md +294 -0
  40. package/src/__augment-tests__/augment.ts +81 -0
  41. package/src/__augment-tests__/augmented.check.ts +117 -0
  42. package/src/__internal.ts +1 -1
  43. package/src/browser/action-coordinator.ts +53 -36
  44. package/src/browser/app-shell.ts +52 -0
  45. package/src/browser/app-version.ts +14 -0
  46. package/src/browser/event-controller.ts +91 -70
  47. package/src/browser/history-state.ts +21 -0
  48. package/src/browser/index.ts +3 -3
  49. package/src/browser/navigation-bridge.ts +102 -16
  50. package/src/browser/navigation-client.ts +164 -59
  51. package/src/browser/navigation-store.ts +75 -17
  52. package/src/browser/navigation-transaction.ts +21 -37
  53. package/src/browser/partial-update.ts +139 -38
  54. package/src/browser/prefetch/cache.ts +175 -15
  55. package/src/browser/prefetch/fetch.ts +180 -33
  56. package/src/browser/prefetch/queue.ts +123 -20
  57. package/src/browser/prefetch/resource-ready.ts +77 -0
  58. package/src/browser/rango-state.ts +53 -13
  59. package/src/browser/react/Link.tsx +81 -9
  60. package/src/browser/react/NavigationProvider.tsx +110 -33
  61. package/src/browser/react/context.ts +7 -2
  62. package/src/browser/react/filter-segment-order.ts +51 -7
  63. package/src/browser/react/index.ts +3 -0
  64. package/src/browser/react/location-state-shared.ts +175 -4
  65. package/src/browser/react/location-state.ts +39 -13
  66. package/src/browser/react/use-handle.ts +23 -64
  67. package/src/browser/react/use-navigation.ts +22 -2
  68. package/src/browser/react/use-params.ts +20 -8
  69. package/src/browser/react/use-reverse.ts +106 -0
  70. package/src/browser/react/use-router.ts +43 -10
  71. package/src/browser/react/use-segments.ts +11 -8
  72. package/src/browser/response-adapter.ts +25 -0
  73. package/src/browser/rsc-router.tsx +191 -74
  74. package/src/browser/scroll-restoration.ts +41 -14
  75. package/src/browser/segment-reconciler.ts +36 -9
  76. package/src/browser/segment-structure-assert.ts +2 -2
  77. package/src/browser/server-action-bridge.ts +31 -36
  78. package/src/browser/types.ts +57 -5
  79. package/src/build/collect-fallback-refs.ts +107 -0
  80. package/src/build/generate-manifest.ts +65 -40
  81. package/src/build/generate-route-types.ts +5 -0
  82. package/src/build/index.ts +2 -0
  83. package/src/build/route-trie.ts +52 -25
  84. package/src/build/route-types/codegen.ts +4 -4
  85. package/src/build/route-types/include-resolution.ts +9 -2
  86. package/src/build/route-types/per-module-writer.ts +7 -4
  87. package/src/build/route-types/router-processing.ts +278 -88
  88. package/src/build/route-types/scan-filter.ts +9 -2
  89. package/src/build/route-types/source-scan.ts +118 -0
  90. package/src/build/runtime-discovery.ts +9 -20
  91. package/src/cache/cache-runtime.ts +15 -11
  92. package/src/cache/cache-scope.ts +76 -49
  93. package/src/cache/cf/cf-cache-store.ts +501 -18
  94. package/src/cache/cf/index.ts +5 -1
  95. package/src/cache/document-cache.ts +17 -7
  96. package/src/cache/index.ts +1 -0
  97. package/src/cache/taint.ts +55 -0
  98. package/src/client.rsc.tsx +3 -0
  99. package/src/client.tsx +94 -238
  100. package/src/context-var.ts +72 -2
  101. package/src/debug.ts +2 -2
  102. package/src/decode-loader-results.ts +36 -0
  103. package/src/errors.ts +30 -1
  104. package/src/handle.ts +65 -12
  105. package/src/host/index.ts +2 -2
  106. package/src/host/router.ts +129 -57
  107. package/src/host/types.ts +31 -2
  108. package/src/host/utils.ts +1 -1
  109. package/src/href-client.ts +140 -20
  110. package/src/index.rsc.ts +12 -5
  111. package/src/index.ts +61 -11
  112. package/src/loader-store.ts +500 -0
  113. package/src/loader.rsc.ts +2 -5
  114. package/src/loader.ts +3 -10
  115. package/src/missing-id-error.ts +68 -0
  116. package/src/outlet-context.ts +1 -1
  117. package/src/prerender/store.ts +5 -4
  118. package/src/prerender.ts +141 -80
  119. package/src/response-utils.ts +37 -0
  120. package/src/reverse.ts +65 -15
  121. package/src/route-content-wrapper.tsx +6 -28
  122. package/src/route-definition/dsl-helpers.ts +435 -260
  123. package/src/route-definition/helper-factories.ts +29 -139
  124. package/src/route-definition/helpers-types.ts +110 -34
  125. package/src/route-definition/index.ts +3 -0
  126. package/src/route-definition/redirect.ts +11 -3
  127. package/src/route-definition/resolve-handler-use.ts +155 -0
  128. package/src/route-definition/use-item-types.ts +32 -0
  129. package/src/route-map-builder.ts +7 -1
  130. package/src/route-types.ts +37 -41
  131. package/src/router/basename.ts +14 -0
  132. package/src/router/content-negotiation.ts +113 -1
  133. package/src/router/error-handling.ts +1 -1
  134. package/src/router/find-match.ts +4 -2
  135. package/src/router/handler-context.ts +77 -38
  136. package/src/router/intercept-resolution.ts +15 -22
  137. package/src/router/lazy-includes.ts +12 -9
  138. package/src/router/loader-resolution.ts +174 -22
  139. package/src/router/logging.ts +5 -2
  140. package/src/router/manifest.ts +31 -16
  141. package/src/router/match-api.ts +128 -192
  142. package/src/router/match-handlers.ts +63 -20
  143. package/src/router/match-middleware/background-revalidation.ts +30 -2
  144. package/src/router/match-middleware/cache-lookup.ts +136 -106
  145. package/src/router/match-middleware/cache-store.ts +54 -10
  146. package/src/router/match-middleware/intercept-resolution.ts +9 -7
  147. package/src/router/match-middleware/segment-resolution.ts +61 -5
  148. package/src/router/match-result.ts +125 -10
  149. package/src/router/metrics.ts +7 -2
  150. package/src/router/middleware-types.ts +21 -34
  151. package/src/router/middleware.ts +103 -90
  152. package/src/router/navigation-snapshot.ts +182 -0
  153. package/src/router/pattern-matching.ts +101 -17
  154. package/src/router/prerender-match.ts +110 -10
  155. package/src/router/preview-match.ts +32 -102
  156. package/src/router/request-classification.ts +286 -0
  157. package/src/router/revalidation.ts +58 -2
  158. package/src/router/route-snapshot.ts +245 -0
  159. package/src/router/router-context.ts +6 -1
  160. package/src/router/router-interfaces.ts +77 -28
  161. package/src/router/router-options.ts +76 -11
  162. package/src/router/router-registry.ts +2 -5
  163. package/src/router/segment-resolution/fresh.ts +223 -24
  164. package/src/router/segment-resolution/helpers.ts +29 -24
  165. package/src/router/segment-resolution/loader-cache.ts +1 -0
  166. package/src/router/segment-resolution/revalidation.ts +466 -285
  167. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  168. package/src/router/segment-wrappers.ts +2 -0
  169. package/src/router/substitute-pattern-params.ts +56 -0
  170. package/src/router/telemetry.ts +99 -0
  171. package/src/router/trie-matching.ts +18 -13
  172. package/src/router/types.ts +9 -0
  173. package/src/router/url-params.ts +49 -0
  174. package/src/router.ts +91 -23
  175. package/src/rsc/handler-context.ts +2 -2
  176. package/src/rsc/handler.ts +440 -381
  177. package/src/rsc/helpers.ts +91 -43
  178. package/src/rsc/index.ts +1 -1
  179. package/src/rsc/loader-fetch.ts +23 -3
  180. package/src/rsc/manifest-init.ts +5 -1
  181. package/src/rsc/origin-guard.ts +28 -10
  182. package/src/rsc/progressive-enhancement.ts +18 -2
  183. package/src/rsc/response-route-handler.ts +46 -53
  184. package/src/rsc/rsc-rendering.ts +41 -48
  185. package/src/rsc/runtime-warnings.ts +9 -10
  186. package/src/rsc/server-action.ts +25 -37
  187. package/src/rsc/ssr-setup.ts +18 -2
  188. package/src/rsc/types.ts +17 -3
  189. package/src/search-params.ts +4 -4
  190. package/src/segment-content-promise.ts +67 -0
  191. package/src/segment-loader-promise.ts +122 -0
  192. package/src/segment-system.tsx +219 -67
  193. package/src/serialize.ts +243 -0
  194. package/src/server/context.ts +277 -61
  195. package/src/server/cookie-store.ts +28 -4
  196. package/src/server/handle-store.ts +19 -0
  197. package/src/server/loader-registry.ts +9 -8
  198. package/src/server/request-context.ts +204 -60
  199. package/src/ssr/index.tsx +9 -1
  200. package/src/static-handler.ts +19 -7
  201. package/src/testing/cache-status.ts +166 -0
  202. package/src/testing/collect-handle.ts +63 -0
  203. package/src/testing/dispatch.ts +440 -0
  204. package/src/testing/dom.entry.ts +22 -0
  205. package/src/testing/e2e/fixture.ts +154 -0
  206. package/src/testing/e2e/index.ts +149 -0
  207. package/src/testing/e2e/matchers.ts +51 -0
  208. package/src/testing/e2e/page-helpers.ts +272 -0
  209. package/src/testing/e2e/parity.ts +306 -0
  210. package/src/testing/e2e/server.ts +183 -0
  211. package/src/testing/flight-matchers.ts +104 -0
  212. package/src/testing/flight-runtime.d.ts +21 -0
  213. package/src/testing/flight.entry.ts +22 -0
  214. package/src/testing/flight.ts +182 -0
  215. package/src/testing/generated-routes.ts +223 -0
  216. package/src/testing/index.ts +106 -0
  217. package/src/testing/internal/context.ts +255 -0
  218. package/src/testing/render-route.tsx +565 -0
  219. package/src/testing/run-loader.ts +296 -0
  220. package/src/testing/run-middleware.ts +179 -0
  221. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  222. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  223. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  224. package/src/testing/vitest-stubs/version.ts +5 -0
  225. package/src/testing/vitest.ts +183 -0
  226. package/src/types/cache-types.ts +4 -4
  227. package/src/types/global-namespace.ts +39 -26
  228. package/src/types/handler-context.ts +194 -72
  229. package/src/types/index.ts +1 -0
  230. package/src/types/loader-types.ts +41 -15
  231. package/src/types/request-scope.ts +126 -0
  232. package/src/types/route-entry.ts +19 -1
  233. package/src/types/segments.ts +37 -1
  234. package/src/urls/include-helper.ts +34 -67
  235. package/src/urls/index.ts +0 -3
  236. package/src/urls/path-helper-types.ts +50 -9
  237. package/src/urls/path-helper.ts +63 -63
  238. package/src/urls/pattern-types.ts +48 -19
  239. package/src/urls/response-types.ts +25 -22
  240. package/src/urls/type-extraction.ts +26 -116
  241. package/src/urls/urls-function.ts +1 -5
  242. package/src/use-loader.tsx +487 -44
  243. package/src/vite/debug.ts +185 -0
  244. package/src/vite/discovery/bundle-postprocess.ts +34 -37
  245. package/src/vite/discovery/discover-routers.ts +105 -51
  246. package/src/vite/discovery/discovery-errors.ts +194 -0
  247. package/src/vite/discovery/gate-state.ts +171 -0
  248. package/src/vite/discovery/prerender-collection.ts +188 -93
  249. package/src/vite/discovery/route-types-writer.ts +40 -84
  250. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  251. package/src/vite/discovery/state.ts +46 -6
  252. package/src/vite/discovery/virtual-module-codegen.ts +13 -23
  253. package/src/vite/index.ts +6 -0
  254. package/src/vite/plugin-types.ts +111 -72
  255. package/src/vite/plugins/cjs-to-esm.ts +8 -7
  256. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  257. package/src/vite/plugins/client-ref-hashing.ts +28 -5
  258. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  259. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  260. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  261. package/src/vite/plugins/expose-action-id.ts +55 -33
  262. package/src/vite/plugins/expose-id-utils.ts +24 -8
  263. package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
  264. package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
  265. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
  266. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  267. package/src/vite/plugins/expose-internal-ids.ts +544 -317
  268. package/src/vite/plugins/performance-tracks.ts +92 -0
  269. package/src/vite/plugins/refresh-cmd.ts +88 -26
  270. package/src/vite/plugins/use-cache-transform.ts +65 -50
  271. package/src/vite/plugins/version-injector.ts +39 -23
  272. package/src/vite/plugins/version-plugin.ts +72 -3
  273. package/src/vite/plugins/virtual-entries.ts +2 -2
  274. package/src/vite/rango.ts +265 -226
  275. package/src/vite/router-discovery.ts +920 -137
  276. package/src/vite/utils/ast-handler-extract.ts +15 -15
  277. package/src/vite/utils/banner.ts +4 -4
  278. package/src/vite/utils/bundle-analysis.ts +4 -2
  279. package/src/vite/utils/client-chunks.ts +190 -0
  280. package/src/vite/utils/forward-user-plugins.ts +193 -0
  281. package/src/vite/utils/manifest-utils.ts +21 -5
  282. package/src/vite/utils/package-resolution.ts +41 -1
  283. package/src/vite/utils/prerender-utils.ts +38 -5
  284. package/src/vite/utils/shared-utils.ts +109 -27
  285. package/src/browser/action-response-classifier.ts +0 -99
@@ -0,0 +1,183 @@
1
+ /**
2
+ * @rangojs/router/testing/vitest
3
+ *
4
+ * Vitest setup helper for the UNIT + INTEGRATION + DOM test project of a
5
+ * @rangojs/router consumer app. It returns the `resolve.alias` entries that make
6
+ * a real app's router / loaders / middleware importable in a bare Vitest process.
7
+ *
8
+ * Why this is needed (the documented "vi.mock(plugin-rsc) + import router"
9
+ * recipe is not sufficient for a real app):
10
+ *
11
+ * - `@rangojs/router` resolves to SERVER-ONLY STUBS outside the `react-server`
12
+ * condition — `urls()`, `createRouter()`, `cookies()`, `getRequestContext()`
13
+ * throw "only available in a react-server environment". Importing the app's own
14
+ * router/loaders/middleware then fails immediately. Vitest does NOT apply the
15
+ * `react-server` condition to bare-package exports resolution, and enabling it
16
+ * globally flips React to its server build (no `createContext`), crashing the
17
+ * router's client-boundary imports. The surgical fix is to alias ONLY the bare
18
+ * `@rangojs/router` specifier to its react-server entry (real impls) while
19
+ * leaving React as the client build — which is exactly what this helper does.
20
+ * - The build-only `@rangojs/router:version` virtual and `@vitejs/plugin-rsc/rsc`
21
+ * (whose real body imports unresolvable Vite virtuals) are stubbed.
22
+ * - Cloudflare apps additionally import the `cloudflare:workers` /
23
+ * `cloudflare:email` runtime virtuals; pass `{ cloudflare: true }` to stub them.
24
+ *
25
+ * Usage (recommended one-call form — see {@link rangoTestConfig}):
26
+ *
27
+ * ```ts
28
+ * // vitest.config.ts
29
+ * import { defineConfig } from "vitest/config";
30
+ * import { rangoTestConfig } from "@rangojs/router/testing/vitest";
31
+ *
32
+ * export default defineConfig({
33
+ * test: {
34
+ * globals: true,
35
+ * include: ["test/**\/*.test.{ts,tsx}"],
36
+ * environment: "node",
37
+ * ...rangoTestConfig({ cloudflare: true }),
38
+ * },
39
+ * });
40
+ * ```
41
+ *
42
+ * `rangoTestConfig` bundles the resolve aliases ({@link rangoTestAliases}) with
43
+ * the `server.deps.inline` contract ({@link rangoInlineDeps}) an installed
44
+ * consumer needs — @rangojs/router ships as TS source, and without `deps.inline`
45
+ * Vitest hands those `.ts` files to Node, which on Node >= 23 throws
46
+ * `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`. Use the lower-level
47
+ * `rangoTestAliases` directly only if you wire `deps.inline` yourself.
48
+ *
49
+ * Notes:
50
+ * - This is for the node/DOM project. The Flight project (real RSC rendering via
51
+ * `@rangojs/router/testing/flight`) uses the `react-server` condition and pure
52
+ * leaf server components — it does NOT use this alias (which would crash under
53
+ * the server React build). See the testing guide for the Flight config.
54
+ * - `renderRoute` (`@rangojs/router/testing/dom`) tests run in this same project
55
+ * under a DOM environment (`happy-dom`/`jsdom`); the alias does not affect them.
56
+ * - LIMITATION: the FULL app router still cannot be imported if it uses
57
+ * `Prerender()` / `createLoader()` (their build-time-injected `$$id` is absent
58
+ * in a bare test). Build a router from an importable, Prerender-free include for
59
+ * `dispatch`, or assert whole-router behavior with e2e.
60
+ */
61
+
62
+ import { fileURLToPath } from "node:url";
63
+
64
+ /** A single Vite/Vitest resolve alias entry. Structurally a Vite `Alias`. */
65
+ export interface TestAlias {
66
+ find: string | RegExp;
67
+ replacement: string;
68
+ }
69
+
70
+ /** Options for {@link rangoTestAliases}. */
71
+ export interface RangoTestAliasOptions {
72
+ /**
73
+ * Stub the Cloudflare Workers runtime virtuals (`cloudflare:workers` /
74
+ * `cloudflare:email`). Enable for a Cloudflare app whose route tree imports
75
+ * them. Default: false.
76
+ */
77
+ cloudflare?: boolean;
78
+ }
79
+
80
+ /**
81
+ * Resolve a path relative to this module. Anchored at the PACKAGE ROOT
82
+ * (`../../` from both `src/testing/vitest.ts` and the shipped
83
+ * `dist/testing/vitest.js` — each is two levels below the root), so the alias
84
+ * targets always point at the `src/*.ts` files Vite transpiles at test time,
85
+ * regardless of whether this helper is loaded as source (in-repo) or as the
86
+ * compiled `dist` entry (an installed consumer).
87
+ */
88
+ function here(relativeFromRoot: string): string {
89
+ return fileURLToPath(new URL(`../../${relativeFromRoot}`, import.meta.url));
90
+ }
91
+
92
+ /**
93
+ * Build the `resolve.alias` entries a consumer's node/DOM Vitest project needs to
94
+ * import a real @rangojs/router app's router/loaders/middleware. Spread into a
95
+ * Vitest config: `resolve: { alias: rangoTestAliases(...) }` (concat your own
96
+ * aliases as needed).
97
+ */
98
+ export function rangoTestAliases(
99
+ opts: RangoTestAliasOptions = {},
100
+ ): TestAlias[] {
101
+ const aliases: TestAlias[] = [
102
+ // Real impls (index.rsc.ts) for the bare specifier ONLY — exact regex so
103
+ // subpaths (/testing, /client, /cache, ...) are untouched. React stays the
104
+ // client build, so createContext and "use client" modules work.
105
+ { find: /^@rangojs\/router$/, replacement: here("src/index.rsc.ts") },
106
+ {
107
+ find: "@rangojs/router:version",
108
+ replacement: here("src/testing/vitest-stubs/version.ts"),
109
+ },
110
+ {
111
+ find: /^@vitejs\/plugin-rsc\/rsc$/,
112
+ replacement: here("src/testing/vitest-stubs/plugin-rsc.ts"),
113
+ },
114
+ ];
115
+
116
+ if (opts.cloudflare) {
117
+ aliases.push(
118
+ {
119
+ find: "cloudflare:workers",
120
+ replacement: here("src/testing/vitest-stubs/cloudflare-workers.ts"),
121
+ },
122
+ {
123
+ find: "cloudflare:email",
124
+ replacement: here("src/testing/vitest-stubs/cloudflare-email.ts"),
125
+ },
126
+ );
127
+ }
128
+
129
+ return aliases;
130
+ }
131
+
132
+ /**
133
+ * Vitest `server.deps.inline` patterns that force Vite (not Node) to transpile
134
+ * @rangojs/router's TypeScript source under test.
135
+ *
136
+ * REQUIRED for an installed (node_modules) consumer: @rangojs/router ships as TS
137
+ * source, and Vitest externalizes node_modules by default — so without this Node
138
+ * loads the `.ts` files directly and, on Node >= 23, throws
139
+ * `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`. In this monorepo it is a no-op
140
+ * (the workspace symlink resolves to a realpath outside node_modules, which Vite
141
+ * already transpiles), which is precisely why an in-repo dogfood never surfaces
142
+ * the need and the contract has to be shipped explicitly.
143
+ */
144
+ export const rangoInlineDeps: RegExp[] = [/@rangojs[/\\]router/];
145
+
146
+ /** The Vitest `test`-block fragment {@link rangoTestConfig} returns. */
147
+ export interface RangoTestConfig {
148
+ alias: TestAlias[];
149
+ server: { deps: { inline: RegExp[] } };
150
+ }
151
+
152
+ /**
153
+ * The complete Vitest `test`-block fragment a consumer needs: the resolve
154
+ * aliases ({@link rangoTestAliases}) AND the `server.deps.inline` contract
155
+ * ({@link rangoInlineDeps}). Spread it into your `test` block so both land in
156
+ * one place and a consumer cannot forget the `deps.inline` half (omitting it
157
+ * loads rango's TS source through Node and breaks on Node >= 23):
158
+ *
159
+ * ```ts
160
+ * // vitest.config.ts
161
+ * import { defineConfig } from "vitest/config";
162
+ * import { rangoTestConfig } from "@rangojs/router/testing/vitest";
163
+ *
164
+ * export default defineConfig({
165
+ * test: {
166
+ * globals: true,
167
+ * include: ["test/**\/*.test.{ts,tsx}"],
168
+ * environment: "node",
169
+ * ...rangoTestConfig({ cloudflare: true }),
170
+ * },
171
+ * });
172
+ * ```
173
+ */
174
+ export function rangoTestConfig(
175
+ opts: RangoTestAliasOptions = {},
176
+ ): RangoTestConfig {
177
+ return {
178
+ alias: rangoTestAliases(opts),
179
+ // fresh copy so the shared rangoInlineDeps const is never aliased into (or
180
+ // mutated through) a consumer's resolved config
181
+ server: { deps: { inline: [...rangoInlineDeps] } },
182
+ };
183
+ }
@@ -5,8 +5,8 @@
5
5
  * during cache key generation (before middleware runs).
6
6
  *
7
7
  * Note: While the full RequestContext is passed, middleware-set variables
8
- * (ctx.var, ctx.get()) may not be populated yet since cache lookup
9
- * happens before middleware execution.
8
+ * read via `ctx.get()` may not be populated yet since cache lookup happens
9
+ * before middleware execution.
10
10
  */
11
11
  export type { RequestContext as CacheContext } from "../server/request-context.js";
12
12
 
@@ -101,7 +101,7 @@ export interface CacheOptions<TEnv = unknown> {
101
101
  * Return false to skip cache for this request (always fetch fresh).
102
102
  *
103
103
  * Has access to full RequestContext including env, request, params, cookies, etc.
104
- * Note: Middleware-set variables (ctx.var) may not be populated yet.
104
+ * Note: Middleware-set variables read via `ctx.get()` may not be populated yet.
105
105
  *
106
106
  * @example
107
107
  * ```typescript
@@ -123,7 +123,7 @@ export interface CacheOptions<TEnv = unknown> {
123
123
  * Bypasses default key generation AND store's keyGenerator.
124
124
  *
125
125
  * Has access to full RequestContext including env, request, params, cookies, etc.
126
- * Note: Middleware-set variables (ctx.var) may not be populated yet.
126
+ * Note: Middleware-set variables read via `ctx.get()` may not be populated yet.
127
127
  *
128
128
  * @example
129
129
  * ```typescript
@@ -7,7 +7,7 @@
7
7
  * ```typescript
8
8
  * // In env.ts or env.d.ts
9
9
  * declare global {
10
- * namespace RSCRouter {
10
+ * namespace Rango {
11
11
  * interface Env extends AppBindings {}
12
12
  * interface Vars extends AppVariables {}
13
13
  * }
@@ -18,7 +18,7 @@
18
18
  * ```
19
19
  */
20
20
  declare global {
21
- namespace RSCRouter {
21
+ namespace Rango {
22
22
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
23
23
  interface Env {
24
24
  // Empty by default - users augment with their bindings (e.g., { DB: D1Database })
@@ -44,13 +44,25 @@ declare global {
44
44
  }
45
45
 
46
46
  /**
47
- * Get registered routes or fallback to generic Record<string, string>
48
- * When RSCRouter.RegisteredRoutes is augmented, provides autocomplete for route names
49
- * When not augmented, allows any string (no autocomplete)
47
+ * Route map for path-validation surfaces (`href`, `ValidPaths`, `PathResponse`).
48
+ *
49
+ * Resolution order:
50
+ * 1. `RegisteredRoutes` — manual `extends typeof router.routeMap`; richest map,
51
+ * the only one carrying response-route payload metadata.
52
+ * 2. `GeneratedRouteMap` — auto-wired by `router.named-routes.gen.ts`; path +
53
+ * search only. Lets `rango generate` alone enable `href()`/`ValidPaths` path
54
+ * checking without a manual `RegisteredRoutes` declaration.
55
+ * 3. `Record<string, string>` — permissive fallback when nothing is registered.
56
+ *
57
+ * Referencing `GeneratedRouteMap` here is cycle-safe: it is declared in the
58
+ * standalone gen file with no imports, unlike `RegisteredRoutes extends typeof
59
+ * router.routeMap`.
50
60
  */
51
- export type GetRegisteredRoutes = keyof RSCRouter.RegisteredRoutes extends never
52
- ? Record<string, string>
53
- : RSCRouter.RegisteredRoutes;
61
+ export type GetRegisteredRoutes = keyof Rango.RegisteredRoutes extends never
62
+ ? keyof Rango.GeneratedRouteMap extends never
63
+ ? Record<string, string>
64
+ : Rango.GeneratedRouteMap
65
+ : Rango.RegisteredRoutes;
54
66
 
55
67
  /**
56
68
  * Default route map for reverse() surfaces.
@@ -58,12 +70,11 @@ export type GetRegisteredRoutes = keyof RSCRouter.RegisteredRoutes extends never
58
70
  * cycles, but falls back to RegisteredRoutes for manual augmentation and then to
59
71
  * a permissive record when no route types are available.
60
72
  */
61
- export type DefaultReverseRouteMap =
62
- keyof RSCRouter.GeneratedRouteMap extends never
63
- ? keyof RSCRouter.RegisteredRoutes extends never
64
- ? Record<string, string>
65
- : RSCRouter.RegisteredRoutes
66
- : RSCRouter.GeneratedRouteMap;
73
+ export type DefaultReverseRouteMap = keyof Rango.GeneratedRouteMap extends never
74
+ ? keyof Rango.RegisteredRoutes extends never
75
+ ? Record<string, string>
76
+ : Rango.RegisteredRoutes
77
+ : Rango.GeneratedRouteMap;
67
78
 
68
79
  /**
69
80
  * Default route map for Handler type.
@@ -71,30 +82,32 @@ export type DefaultReverseRouteMap =
71
82
  * circular dependencies: router.tsx -> urls.tsx -> handler.tsx -> RegisteredRoutes -> router.tsx.
72
83
  * GeneratedRouteMap is declared in a standalone gen file with no imports.
73
84
  */
74
- export type DefaultHandlerRouteMap =
75
- keyof RSCRouter.GeneratedRouteMap extends never
76
- ? {}
77
- : RSCRouter.GeneratedRouteMap;
85
+ export type DefaultHandlerRouteMap = keyof Rango.GeneratedRouteMap extends never
86
+ ? {}
87
+ : Rango.GeneratedRouteMap;
78
88
 
79
89
  /**
80
- * Default environment type - uses global augmentation if available, any otherwise
90
+ * Default environment type - uses global augmentation if available.
91
+ *
92
+ * Falls back to `unknown` (not `any`) when `Rango.Env` is not augmented, so
93
+ * an app that forgets to register its bindings gets a compile error on
94
+ * `ctx.env.SOMETHING` instead of silently losing all env type-checking. Augment
95
+ * `Rango.Env` to type `ctx.env`.
81
96
  */
82
- export type DefaultEnv = keyof RSCRouter.Env extends never
83
- ? any
84
- : RSCRouter.Env;
97
+ export type DefaultEnv = keyof Rango.Env extends never ? unknown : Rango.Env;
85
98
 
86
99
  /**
87
100
  * Default variables type - uses global augmentation if available, Record<string, any> otherwise
88
101
  */
89
- export type DefaultVars = keyof RSCRouter.Vars extends never
102
+ export type DefaultVars = keyof Rango.Vars extends never
90
103
  ? Record<string, any>
91
- : RSCRouter.Vars;
104
+ : Rango.Vars;
92
105
 
93
106
  /**
94
107
  * Default route name type for public `routeName` on contexts.
95
108
  * When GeneratedRouteMap is augmented, narrows to the known route names.
96
109
  * Otherwise falls back to `string` for untyped usage.
97
110
  */
98
- export type DefaultRouteName = keyof RSCRouter.GeneratedRouteMap extends never
111
+ export type DefaultRouteName = keyof Rango.GeneratedRouteMap extends never
99
112
  ? string
100
- : keyof RSCRouter.GeneratedRouteMap & string;
113
+ : keyof Rango.GeneratedRouteMap & string;