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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/README.md +24 -9
  2. package/dist/bin/rango.js +157 -63
  3. package/dist/testing/vitest.js +82 -0
  4. package/dist/vite/index.js +1584 -639
  5. package/package.json +60 -11
  6. package/skills/api-client/SKILL.md +211 -0
  7. package/skills/breadcrumbs/SKILL.md +60 -0
  8. package/skills/bundle-analysis/SKILL.md +159 -0
  9. package/skills/cache-guide/SKILL.md +222 -30
  10. package/skills/caching/SKILL.md +263 -8
  11. package/skills/composability/SKILL.md +27 -2
  12. package/skills/css/SKILL.md +76 -0
  13. package/skills/document-cache/SKILL.md +78 -55
  14. package/skills/handler-use/SKILL.md +3 -1
  15. package/skills/hooks/SKILL.md +235 -28
  16. package/skills/host-router/SKILL.md +122 -22
  17. package/skills/intercept/SKILL.md +29 -5
  18. package/skills/layout/SKILL.md +13 -9
  19. package/skills/links/SKILL.md +173 -17
  20. package/skills/loader/SKILL.md +170 -23
  21. package/skills/middleware/SKILL.md +16 -10
  22. package/skills/migrate-nextjs/SKILL.md +38 -16
  23. package/skills/mime-routes/SKILL.md +27 -0
  24. package/skills/observability/SKILL.md +137 -0
  25. package/skills/parallel/SKILL.md +11 -7
  26. package/skills/prerender/SKILL.md +14 -33
  27. package/skills/rango/SKILL.md +250 -26
  28. package/skills/react-compiler/SKILL.md +168 -0
  29. package/skills/response-routes/SKILL.md +114 -47
  30. package/skills/route/SKILL.md +22 -5
  31. package/skills/router-setup/SKILL.md +3 -3
  32. package/skills/server-actions/SKILL.md +78 -42
  33. package/skills/tailwind/SKILL.md +27 -3
  34. package/skills/testing/SKILL.md +129 -0
  35. package/skills/testing/bindings.md +89 -0
  36. package/skills/testing/cache-prerender.md +124 -0
  37. package/skills/testing/client-components.md +122 -0
  38. package/skills/testing/e2e-parity.md +125 -0
  39. package/skills/testing/flight.md +92 -0
  40. package/skills/testing/handles.md +129 -0
  41. package/skills/testing/loader.md +128 -0
  42. package/skills/testing/middleware.md +99 -0
  43. package/skills/testing/render-handler.md +121 -0
  44. package/skills/testing/response-routes.md +95 -0
  45. package/skills/testing/reverse-and-types.md +84 -0
  46. package/skills/testing/server-actions.md +107 -0
  47. package/skills/testing/server-tree.md +128 -0
  48. package/skills/testing/setup.md +120 -0
  49. package/skills/typesafety/SKILL.md +310 -26
  50. package/skills/use-cache/SKILL.md +36 -5
  51. package/skills/vercel/SKILL.md +107 -0
  52. package/skills/view-transitions/SKILL.md +294 -0
  53. package/src/__augment-tests__/augment.ts +81 -0
  54. package/src/__augment-tests__/augmented.check.ts +116 -0
  55. package/src/__internal.ts +0 -65
  56. package/src/browser/action-coordinator.ts +53 -36
  57. package/src/browser/action-fence.ts +47 -0
  58. package/src/browser/app-shell.ts +14 -27
  59. package/src/browser/cookie-name.ts +140 -0
  60. package/src/browser/event-controller.ts +37 -143
  61. package/src/browser/history-state.ts +21 -0
  62. package/src/browser/index.ts +3 -3
  63. package/src/browser/invalidate-client-cache.ts +52 -0
  64. package/src/browser/navigation-bridge.ts +30 -59
  65. package/src/browser/navigation-client.ts +96 -84
  66. package/src/browser/navigation-store-handle.ts +38 -0
  67. package/src/browser/navigation-store.ts +32 -82
  68. package/src/browser/navigation-transaction.ts +9 -59
  69. package/src/browser/partial-update.ts +60 -127
  70. package/src/browser/prefetch/cache.ts +82 -72
  71. package/src/browser/prefetch/fetch.ts +108 -33
  72. package/src/browser/prefetch/queue.ts +6 -3
  73. package/src/browser/rango-state.ts +157 -115
  74. package/src/browser/react/Link.tsx +0 -2
  75. package/src/browser/react/NavigationProvider.tsx +41 -48
  76. package/src/browser/react/ScrollRestoration.tsx +10 -6
  77. package/src/browser/react/filter-segment-order.ts +0 -2
  78. package/src/browser/react/index.ts +0 -48
  79. package/src/browser/react/location-state-shared.ts +166 -8
  80. package/src/browser/react/location-state.ts +39 -14
  81. package/src/browser/react/use-action.ts +6 -15
  82. package/src/browser/react/use-handle.ts +17 -14
  83. package/src/browser/react/use-link-status.ts +0 -4
  84. package/src/browser/react/use-navigation.ts +0 -3
  85. package/src/browser/react/use-params.ts +3 -6
  86. package/src/browser/react/use-reverse.ts +106 -0
  87. package/src/browser/react/use-router.ts +20 -5
  88. package/src/browser/react/use-search-params.ts +0 -5
  89. package/src/browser/react/use-segments.ts +0 -13
  90. package/src/browser/response-adapter.ts +52 -1
  91. package/src/browser/rsc-router.tsx +70 -34
  92. package/src/browser/scroll-restoration.ts +22 -14
  93. package/src/browser/segment-structure-assert.ts +2 -2
  94. package/src/browser/server-action-bridge.ts +168 -44
  95. package/src/browser/types.ts +36 -21
  96. package/src/browser/validate-redirect-origin.ts +43 -16
  97. package/src/build/collect-fallback-refs.ts +107 -0
  98. package/src/build/generate-manifest.ts +60 -35
  99. package/src/build/generate-route-types.ts +3 -0
  100. package/src/build/index.ts +8 -2
  101. package/src/build/prefix-tree-utils.ts +123 -0
  102. package/src/build/route-trie.ts +89 -11
  103. package/src/build/route-types/codegen.ts +4 -4
  104. package/src/build/route-types/include-resolution.ts +1 -1
  105. package/src/build/route-types/param-extraction.ts +6 -3
  106. package/src/build/route-types/per-module-writer.ts +7 -4
  107. package/src/build/route-types/router-processing.ts +122 -22
  108. package/src/build/route-types/scan-filter.ts +1 -1
  109. package/src/build/route-types/source-scan.ts +118 -0
  110. package/src/build/runtime-discovery.ts +9 -20
  111. package/src/cache/cache-error.ts +104 -0
  112. package/src/cache/cache-policy.ts +68 -28
  113. package/src/cache/cache-runtime.ts +134 -32
  114. package/src/cache/cache-scope.ts +100 -74
  115. package/src/cache/cache-tag.ts +98 -0
  116. package/src/cache/cf/cf-cache-store.ts +2255 -238
  117. package/src/cache/cf/index.ts +6 -16
  118. package/src/cache/document-cache.ts +61 -20
  119. package/src/cache/handle-snapshot.ts +63 -0
  120. package/src/cache/index.ts +22 -20
  121. package/src/cache/memory-segment-store.ts +136 -37
  122. package/src/cache/profile-registry.ts +6 -30
  123. package/src/cache/read-through-swr.ts +41 -11
  124. package/src/cache/segment-codec.ts +0 -16
  125. package/src/cache/tag-invalidation.ts +230 -0
  126. package/src/cache/types.ts +33 -100
  127. package/src/cache/vercel/index.ts +11 -0
  128. package/src/cache/vercel/vercel-cache-store.ts +799 -0
  129. package/src/client.rsc.tsx +6 -21
  130. package/src/client.tsx +25 -61
  131. package/src/component-utils.ts +19 -0
  132. package/src/context-var.ts +17 -5
  133. package/src/decode-loader-results.ts +36 -0
  134. package/src/defer.ts +196 -0
  135. package/src/deps/ssr.ts +0 -1
  136. package/src/errors.ts +30 -4
  137. package/src/handle.ts +31 -23
  138. package/src/handles/MetaTags.tsx +0 -14
  139. package/src/handles/breadcrumbs.ts +16 -5
  140. package/src/handles/meta.ts +0 -39
  141. package/src/host/cookie-handler.ts +0 -36
  142. package/src/host/errors.ts +0 -24
  143. package/src/host/index.ts +8 -2
  144. package/src/host/pattern-matcher.ts +7 -50
  145. package/src/host/router.ts +107 -99
  146. package/src/host/testing.ts +40 -27
  147. package/src/host/types.ts +37 -4
  148. package/src/host/utils.ts +1 -1
  149. package/src/href-client.ts +137 -22
  150. package/src/index.rsc.ts +63 -9
  151. package/src/index.ts +64 -9
  152. package/src/internal-debug.ts +2 -4
  153. package/src/loader-store.ts +500 -0
  154. package/src/loader.rsc.ts +20 -13
  155. package/src/loader.ts +12 -11
  156. package/src/missing-id-error.ts +68 -0
  157. package/src/network-error-thrower.tsx +1 -6
  158. package/src/outlet-provider.tsx +1 -5
  159. package/src/prerender/param-hash.ts +10 -11
  160. package/src/prerender/store.ts +32 -37
  161. package/src/prerender.ts +61 -6
  162. package/src/redirect-origin.ts +100 -0
  163. package/src/response-utils.ts +9 -0
  164. package/src/reverse.ts +65 -41
  165. package/src/root-error-boundary.tsx +1 -19
  166. package/src/route-content-wrapper.tsx +7 -72
  167. package/src/route-definition/dsl-helpers.ts +244 -281
  168. package/src/route-definition/helper-factories.ts +29 -139
  169. package/src/route-definition/helpers-types.ts +40 -17
  170. package/src/route-definition/redirect.ts +43 -9
  171. package/src/route-definition/resolve-handler-use.ts +6 -0
  172. package/src/route-definition/use-item-types.ts +32 -0
  173. package/src/route-map-builder.ts +0 -16
  174. package/src/route-types.ts +19 -41
  175. package/src/router/basename.ts +14 -0
  176. package/src/router/content-negotiation.ts +15 -15
  177. package/src/router/error-handling.ts +13 -17
  178. package/src/router/find-match.ts +44 -23
  179. package/src/router/handler-context.ts +4 -42
  180. package/src/router/intercept-resolution.ts +14 -19
  181. package/src/router/lazy-includes.ts +9 -46
  182. package/src/router/loader-resolution.ts +91 -46
  183. package/src/router/logging.ts +0 -6
  184. package/src/router/manifest.ts +18 -29
  185. package/src/router/match-api.ts +0 -20
  186. package/src/router/match-context.ts +0 -22
  187. package/src/router/match-handlers.ts +57 -58
  188. package/src/router/match-middleware/background-revalidation.ts +0 -7
  189. package/src/router/match-middleware/cache-lookup.ts +150 -271
  190. package/src/router/match-middleware/cache-store.ts +3 -33
  191. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  192. package/src/router/match-middleware/segment-resolution.ts +0 -22
  193. package/src/router/match-pipelines.ts +1 -42
  194. package/src/router/match-result.ts +31 -80
  195. package/src/router/metrics.ts +0 -34
  196. package/src/router/middleware-types.ts +0 -116
  197. package/src/router/middleware.ts +118 -133
  198. package/src/router/navigation-snapshot.ts +0 -51
  199. package/src/router/params-util.ts +23 -0
  200. package/src/router/pattern-matching.ts +20 -58
  201. package/src/router/prerender-match.ts +99 -63
  202. package/src/router/preview-match.ts +3 -1
  203. package/src/router/request-classification.ts +28 -62
  204. package/src/router/revalidation.ts +50 -56
  205. package/src/router/route-snapshot.ts +0 -1
  206. package/src/router/router-context.ts +0 -27
  207. package/src/router/router-interfaces.ts +68 -35
  208. package/src/router/router-options.ts +55 -1
  209. package/src/router/router-registry.ts +2 -5
  210. package/src/router/segment-resolution/fresh.ts +44 -63
  211. package/src/router/segment-resolution/helpers.ts +34 -0
  212. package/src/router/segment-resolution/loader-cache.ts +40 -37
  213. package/src/router/segment-resolution/revalidation.ts +203 -285
  214. package/src/router/segment-resolution/static-store.ts +19 -5
  215. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  216. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  217. package/src/router/segment-resolution.ts +4 -1
  218. package/src/router/segment-wrappers.ts +0 -3
  219. package/src/router/state-cookie-name.ts +33 -0
  220. package/src/router/substitute-pattern-params.ts +56 -0
  221. package/src/router/telemetry-otel.ts +0 -20
  222. package/src/router/telemetry.ts +96 -19
  223. package/src/router/timeout.ts +0 -20
  224. package/src/router/trie-matching.ts +87 -47
  225. package/src/router/types.ts +9 -63
  226. package/src/router/url-params.ts +0 -5
  227. package/src/router.ts +80 -41
  228. package/src/rsc/handler-context.ts +3 -2
  229. package/src/rsc/handler.ts +83 -78
  230. package/src/rsc/helpers.ts +93 -5
  231. package/src/rsc/index.ts +1 -1
  232. package/src/rsc/json-route-result.ts +38 -0
  233. package/src/rsc/manifest-init.ts +28 -41
  234. package/src/rsc/origin-guard.ts +39 -25
  235. package/src/rsc/progressive-enhancement.ts +12 -1
  236. package/src/rsc/redirect-guard.ts +99 -0
  237. package/src/rsc/response-error.ts +79 -12
  238. package/src/rsc/response-route-handler.ts +76 -62
  239. package/src/rsc/rsc-rendering.ts +41 -60
  240. package/src/rsc/runtime-warnings.ts +23 -10
  241. package/src/rsc/server-action.ts +62 -67
  242. package/src/rsc/ssr-setup.ts +16 -0
  243. package/src/rsc/types.ts +10 -5
  244. package/src/runtime-env.ts +18 -0
  245. package/src/search-params.ts +4 -20
  246. package/src/segment-loader-promise.ts +14 -2
  247. package/src/segment-system.tsx +199 -142
  248. package/src/serialize.ts +243 -0
  249. package/src/server/context.ts +150 -51
  250. package/src/server/cookie-store.ts +80 -5
  251. package/src/server/handle-store.ts +7 -24
  252. package/src/server/loader-registry.ts +5 -24
  253. package/src/server/request-context.ts +165 -87
  254. package/src/ssr/index.tsx +14 -14
  255. package/src/static-handler.ts +10 -13
  256. package/src/testing/cache-status.ts +162 -0
  257. package/src/testing/collect-handle.ts +40 -0
  258. package/src/testing/dispatch.ts +618 -0
  259. package/src/testing/dom.entry.ts +22 -0
  260. package/src/testing/e2e/fixture.ts +188 -0
  261. package/src/testing/e2e/index.ts +128 -0
  262. package/src/testing/e2e/matchers.ts +35 -0
  263. package/src/testing/e2e/page-helpers.ts +272 -0
  264. package/src/testing/e2e/parity.ts +387 -0
  265. package/src/testing/e2e/server.ts +195 -0
  266. package/src/testing/flight-matchers.ts +97 -0
  267. package/src/testing/flight-normalize.ts +11 -0
  268. package/src/testing/flight-runtime.d.ts +57 -0
  269. package/src/testing/flight-tree.ts +682 -0
  270. package/src/testing/flight.entry.ts +52 -0
  271. package/src/testing/flight.ts +232 -0
  272. package/src/testing/generated-routes.ts +183 -0
  273. package/src/testing/index.ts +99 -0
  274. package/src/testing/internal/context.ts +348 -0
  275. package/src/testing/internal/flight-client-globals.ts +30 -0
  276. package/src/testing/internal/seed-vars.ts +54 -0
  277. package/src/testing/render-handler.ts +330 -0
  278. package/src/testing/render-route.tsx +566 -0
  279. package/src/testing/run-loader.ts +378 -0
  280. package/src/testing/run-middleware.ts +205 -0
  281. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  282. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  283. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  284. package/src/testing/vitest-stubs/version.ts +5 -0
  285. package/src/testing/vitest.ts +305 -0
  286. package/src/theme/ThemeProvider.tsx +0 -52
  287. package/src/theme/ThemeScript.tsx +0 -6
  288. package/src/theme/constants.ts +0 -12
  289. package/src/theme/index.ts +0 -7
  290. package/src/theme/theme-context.ts +1 -5
  291. package/src/theme/theme-script.ts +0 -14
  292. package/src/theme/use-theme.ts +0 -3
  293. package/src/types/boundaries.ts +0 -35
  294. package/src/types/cache-types.ts +13 -4
  295. package/src/types/error-types.ts +30 -90
  296. package/src/types/global-namespace.ts +54 -41
  297. package/src/types/handler-context.ts +97 -22
  298. package/src/types/index.ts +1 -10
  299. package/src/types/loader-types.ts +6 -3
  300. package/src/types/request-scope.ts +0 -19
  301. package/src/types/route-config.ts +6 -50
  302. package/src/types/route-entry.ts +0 -6
  303. package/src/types/segments.ts +18 -14
  304. package/src/urls/include-helper.ts +9 -56
  305. package/src/urls/index.ts +1 -11
  306. package/src/urls/path-helper-types.ts +19 -5
  307. package/src/urls/path-helper.ts +17 -106
  308. package/src/urls/pattern-types.ts +36 -19
  309. package/src/urls/response-types.ts +20 -19
  310. package/src/urls/type-extraction.ts +58 -139
  311. package/src/urls/urls-function.ts +1 -18
  312. package/src/use-loader.tsx +292 -107
  313. package/src/vite/debug.ts +1 -0
  314. package/src/vite/discovery/bundle-postprocess.ts +8 -7
  315. package/src/vite/discovery/discover-routers.ts +95 -82
  316. package/src/vite/discovery/discovery-errors.ts +194 -0
  317. package/src/vite/discovery/prerender-collection.ts +26 -34
  318. package/src/vite/discovery/route-types-writer.ts +40 -84
  319. package/src/vite/discovery/state.ts +39 -1
  320. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  321. package/src/vite/index.ts +4 -0
  322. package/src/vite/plugin-types.ts +185 -10
  323. package/src/vite/plugins/cjs-to-esm.ts +3 -18
  324. package/src/vite/plugins/client-ref-dedup.ts +0 -11
  325. package/src/vite/plugins/client-ref-hashing.ts +12 -11
  326. package/src/vite/plugins/cloudflare-protocol-stub.ts +1 -21
  327. package/src/vite/plugins/expose-action-id.ts +4 -75
  328. package/src/vite/plugins/expose-id-utils.ts +3 -54
  329. package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
  330. package/src/vite/plugins/expose-ids/handler-transform.ts +6 -74
  331. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
  332. package/src/vite/plugins/expose-ids/router-transform.ts +0 -13
  333. package/src/vite/plugins/expose-internal-ids.ts +57 -67
  334. package/src/vite/plugins/performance-tracks.ts +9 -16
  335. package/src/vite/plugins/refresh-cmd.ts +1 -1
  336. package/src/vite/plugins/use-cache-transform.ts +26 -49
  337. package/src/vite/plugins/vercel-output.ts +258 -0
  338. package/src/vite/plugins/version-injector.ts +2 -32
  339. package/src/vite/plugins/version-plugin.ts +32 -23
  340. package/src/vite/plugins/virtual-entries.ts +35 -17
  341. package/src/vite/rango.ts +148 -115
  342. package/src/vite/router-discovery.ts +220 -68
  343. package/src/vite/utils/ast-handler-extract.ts +15 -31
  344. package/src/vite/utils/bundle-analysis.ts +10 -15
  345. package/src/vite/utils/client-chunks.ts +184 -0
  346. package/src/vite/utils/forward-user-plugins.ts +171 -0
  347. package/src/vite/utils/manifest-utils.ts +4 -59
  348. package/src/vite/utils/package-resolution.ts +1 -73
  349. package/src/vite/utils/prerender-utils.ts +0 -35
  350. package/src/vite/utils/shared-utils.ts +95 -43
  351. package/src/browser/action-response-classifier.ts +0 -99
  352. package/src/browser/react/use-client-cache.ts +0 -58
  353. package/src/browser/shallow.ts +0 -40
  354. package/src/handles/index.ts +0 -7
  355. package/src/router/middleware-cookies.ts +0 -55
@@ -27,9 +27,6 @@ import type { UseThemeReturn } from "./types.js";
27
27
  *
28
28
  * Must be used within a ThemeProvider (which is automatically included
29
29
  * in NavigationProvider when theme is enabled in router config).
30
- *
31
- * @returns Theme state and methods
32
- * @throws Error if used outside ThemeProvider
33
30
  */
34
31
  export function useTheme(): UseThemeReturn {
35
32
  const ctx = requireThemeContext();
@@ -1,22 +1,12 @@
1
1
  import type { ReactNode } from "react";
2
2
 
3
- /**
4
- * Error information passed to error boundary fallback components
5
- */
6
3
  export interface ErrorInfo {
7
- /** Error message (always available) */
8
4
  message: string;
9
- /** Error name/type (e.g., "RouteNotFoundError", "MiddlewareError") */
10
5
  name: string;
11
- /** Optional error code for programmatic handling */
12
6
  code?: string;
13
- /** Stack trace (only in development) */
14
7
  stack?: string;
15
- /** Original error cause if available */
16
8
  cause?: unknown;
17
- /** Segment ID where the error occurred */
18
9
  segmentId: string;
19
- /** Segment type where the error occurred */
20
10
  segmentType:
21
11
  | "layout"
22
12
  | "route"
@@ -46,13 +36,9 @@ export interface ErrorInfo {
46
36
  * ```
47
37
  */
48
38
  export interface ErrorBoundaryFallbackProps {
49
- /** Error information */
50
39
  error: ErrorInfo;
51
40
  }
52
41
 
53
- /**
54
- * Error boundary handler - receives error info and returns fallback UI
55
- */
56
42
  export type ErrorBoundaryHandler = (
57
43
  props: ErrorBoundaryFallbackProps,
58
44
  ) => ReactNode;
@@ -77,17 +63,10 @@ export type ErrorBoundaryHandler = (
77
63
  * ```
78
64
  */
79
65
  export interface ClientErrorBoundaryFallbackProps {
80
- /** Error information */
81
66
  error: ErrorInfo;
82
- /** Function to reset error state and retry rendering */
83
67
  reset: () => void;
84
68
  }
85
69
 
86
- /**
87
- * Wrapped loader data result for deferred resolution with error handling.
88
- * When loaders are deferred to client-side resolution, errors need to be
89
- * wrapped so the client can handle them appropriately.
90
- */
91
70
  export type LoaderDataResult<T = unknown> =
92
71
  | { __loaderResult: true; ok: true; data: T }
93
72
  | {
@@ -97,9 +76,6 @@ export type LoaderDataResult<T = unknown> =
97
76
  fallback: ReactNode | null;
98
77
  };
99
78
 
100
- /**
101
- * Type guard to check if a value is a wrapped loader result
102
- */
103
79
  export function isLoaderDataResult(value: unknown): value is LoaderDataResult {
104
80
  return (
105
81
  typeof value === "object" &&
@@ -109,15 +85,9 @@ export function isLoaderDataResult(value: unknown): value is LoaderDataResult {
109
85
  );
110
86
  }
111
87
 
112
- /**
113
- * Not found information passed to notFound boundary fallback components
114
- */
115
88
  export interface NotFoundInfo {
116
- /** Not found message */
117
89
  message: string;
118
- /** Segment ID where notFound was thrown */
119
90
  segmentId: string;
120
- /** Segment type where notFound was thrown */
121
91
  segmentType:
122
92
  | "layout"
123
93
  | "route"
@@ -125,7 +95,6 @@ export interface NotFoundInfo {
125
95
  | "loader"
126
96
  | "middleware"
127
97
  | "cache";
128
- /** The pathname that triggered the not found */
129
98
  pathname?: string;
130
99
  }
131
100
 
@@ -146,13 +115,9 @@ export interface NotFoundInfo {
146
115
  * ```
147
116
  */
148
117
  export interface NotFoundBoundaryFallbackProps {
149
- /** Not found information */
150
118
  notFound: NotFoundInfo;
151
119
  }
152
120
 
153
- /**
154
- * NotFound boundary handler - receives not found info and returns fallback UI
155
- */
156
121
  export type NotFoundBoundaryHandler = (
157
122
  props: NotFoundBoundaryFallbackProps,
158
123
  ) => ReactNode;
@@ -78,6 +78,14 @@ export interface CacheOptions<TEnv = unknown> {
78
78
  * - Loader-specific caching strategies
79
79
  * - Hot data in fast cache, cold data in larger/slower cache
80
80
  *
81
+ * Tag invalidation caveat: a per-boundary store becomes reachable by
82
+ * `updateTag()` / `revalidateTag()` once this boundary is resolved in the
83
+ * current process. If the store is *durable* (shared across processes) and the
84
+ * very first request to a fresh worker is an `updateTag`/`revalidateTag` for a
85
+ * tag held only in this store - before this boundary is matched - that
86
+ * invalidation can miss it. For data you invalidate by tag, prefer the
87
+ * app-level store (always reachable), or ensure the boundary is warmed.
88
+ *
81
89
  * @example
82
90
  * ```typescript
83
91
  * const kvStore = new CloudflareKVStore(env.CACHE_KV);
@@ -145,10 +153,11 @@ export interface CacheOptions<TEnv = unknown> {
145
153
  * Tags for cache invalidation.
146
154
  * Can be a static array or a function that returns tags.
147
155
  *
148
- * Note: Tags are passed through to the store but built-in stores
149
- * (MemorySegmentCacheStore, CFCacheStore) do not yet index or
150
- * invalidate by tag. Effective tag-based invalidation requires a
151
- * custom store implementation with secondary indices.
156
+ * The built-in `MemorySegmentCacheStore` and `CFCacheStore` index by tag.
157
+ * Invalidate on demand with `updateTag(...tags)` (awaitable, read-your-own-writes;
158
+ * for server actions) or `revalidateTag(...tags)` (background hard-purge, not
159
+ * awaited; for route handlers / webhooks). For `CFCacheStore`, distributed
160
+ * invalidation requires a `kv` namespace (markers live in that same namespace).
152
161
  *
153
162
  * @example
154
163
  * ```typescript
@@ -14,19 +14,19 @@
14
14
  * - "unknown": Fallback for unclassified errors (not currently invoked)
15
15
  */
16
16
  export type ErrorPhase =
17
- | "routing" // During route matching
18
- | "manifest" // During manifest loading (reserved, not currently invoked)
19
- | "middleware" // During middleware execution (errors propagate to handler phase)
20
- | "loader" // During loader execution
21
- | "handler" // During route/layout handler execution
22
- | "rendering" // During RSC/SSR rendering (SSR handler uses separate callback)
23
- | "action" // During server action execution
24
- | "revalidation" // During revalidation evaluation
25
- | "cache" // During "use cache" background operations (stale revalidation, async cache writes)
26
- | "prerender" // During build-time pre-rendering (Vite closeBundle)
27
- | "static" // During build-time static handler rendering (Vite closeBundle)
28
- | "origin" // During cross-origin request validation (CSRF protection)
29
- | "unknown"; // Fallback for unclassified errors
17
+ | "routing"
18
+ | "manifest"
19
+ | "middleware"
20
+ | "loader"
21
+ | "handler"
22
+ | "rendering"
23
+ | "action"
24
+ | "revalidation"
25
+ | "cache"
26
+ | "prerender"
27
+ | "static"
28
+ | "origin"
29
+ | "unknown";
30
30
 
31
31
  /**
32
32
  * Comprehensive context passed to onError callback
@@ -59,103 +59,43 @@ export type ErrorPhase =
59
59
  * ```
60
60
  */
61
61
  export interface OnErrorContext<TEnv = any> {
62
- /**
63
- * The error that occurred
64
- */
65
62
  error: Error;
66
-
67
- /**
68
- * Phase where the error occurred
69
- */
70
63
  phase: ErrorPhase;
71
-
72
- /**
73
- * The original request
74
- */
75
64
  request: Request;
76
-
77
- /**
78
- * Parsed URL from the request
79
- */
80
65
  url: URL;
81
-
82
- /**
83
- * Request pathname
84
- */
85
66
  pathname: string;
86
-
87
- /**
88
- * HTTP method
89
- */
90
67
  method: string;
91
-
92
- /**
93
- * Matched route key (if available)
94
- * e.g., "shop.products.detail"
95
- */
68
+ /** Matched route key (if available) e.g., "shop.products.detail" */
96
69
  routeKey?: string;
97
-
98
- /**
99
- * Route params (if available)
100
- * e.g., { slug: "headphones" }
101
- */
70
+ /** Route params (if available) e.g., { slug: "headphones" } */
102
71
  params?: Record<string, string>;
103
-
104
- /**
105
- * Segment ID where error occurred (if available)
106
- * e.g., "M1L0" for a layout, "M1R0" for a route
107
- */
72
+ /** Segment ID where error occurred (if available) e.g., "M1L0" for a layout, "M1R0" for a route */
108
73
  segmentId?: string;
109
-
110
- /**
111
- * Segment type where error occurred (if available)
112
- */
74
+ /** Segment type where error occurred (if available) */
113
75
  segmentType?: "layout" | "route" | "parallel" | "loader" | "middleware";
114
-
115
- /**
116
- * Loader name (if error occurred in a loader)
117
- */
76
+ /** Loader name (if error occurred in a loader) */
118
77
  loaderName?: string;
119
-
120
- /**
121
- * Middleware name/id (if error occurred in middleware)
122
- */
78
+ /** Middleware name/id (if error occurred in middleware) */
123
79
  middlewareId?: string;
124
-
125
- /**
126
- * Action ID (if error occurred during server action)
127
- * e.g., "src/actions.ts#addToCart"
128
- */
80
+ /** Action ID (if error occurred during server action) e.g., "src/actions.ts#addToCart" */
129
81
  actionId?: string;
130
-
131
- /**
132
- * Environment/bindings (platform context)
133
- */
82
+ /** Environment/bindings (platform context) */
134
83
  env?: TEnv;
135
-
136
- /**
137
- * Duration from request start to error (milliseconds)
138
- */
84
+ /** Duration from request start to error (milliseconds) */
139
85
  duration?: number;
140
-
141
- /**
142
- * Whether this is a partial/navigation request
143
- */
86
+ /** Whether this is a partial/navigation request */
144
87
  isPartial?: boolean;
145
-
146
- /**
147
- * Whether an error boundary caught the error
148
- * If true, the error was handled and a fallback UI was rendered
149
- */
88
+ /** Whether an error boundary caught the error */
150
89
  handledByBoundary?: boolean;
151
-
152
- /**
153
- * Stack trace (if available)
154
- */
90
+ /** Stack trace (if available) */
155
91
  stack?: string;
156
92
 
157
93
  /**
158
- * Additional metadata specific to the error phase
94
+ * Additional metadata specific to the error phase. For the `cache` phase,
95
+ * `metadata.category` is a `CacheErrorCategory` (exported from
96
+ * `@rangojs/router/cache`) identifying the failure kind, e.g. `cache-read`
97
+ * (transient outage, degraded to a miss) vs `cache-corrupt` (faulty entry
98
+ * self-healed) vs `cache-invalidate` (a failed background revalidateTag).
159
99
  */
160
100
  metadata?: Record<string, unknown>;
161
101
  }
@@ -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,39 +18,41 @@
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
- interface Env {
24
- // Empty by default - users augment with their bindings (e.g., { DB: D1Database })
25
- }
23
+ interface Env {}
26
24
 
27
25
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
28
- interface Vars {
29
- // Empty by default - users augment with their variables (e.g., { user?: User })
30
- }
26
+ interface Vars {}
31
27
 
32
28
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
33
- interface RegisteredRoutes {
34
- // Empty by default - users augment with their merged route maps for type-safe href()
35
- // Values are string (pattern) for RSC routes, or { path: string; response: T } for response routes
36
- }
29
+ interface RegisteredRoutes {}
37
30
 
38
31
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
39
- interface GeneratedRouteMap {
40
- // Empty by default - populated by generated named-routes.gen.ts
41
- // Maps route names to URL pattern strings for Handler<"routeName"> support
42
- }
32
+ interface GeneratedRouteMap {}
43
33
  }
44
34
  }
45
35
 
46
36
  /**
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)
37
+ * Route map for path-validation surfaces (`href`, `ValidPaths`, `PathResponse`).
38
+ *
39
+ * Resolution order:
40
+ * 1. `RegisteredRoutes` — manual `extends typeof router.routeMap`; richest map,
41
+ * the only one carrying response-route payload metadata.
42
+ * 2. `GeneratedRouteMap` — auto-wired by `router.named-routes.gen.ts`; path +
43
+ * search only. Lets `rango generate` alone enable `href()`/`ValidPaths` path
44
+ * checking without a manual `RegisteredRoutes` declaration.
45
+ * 3. `Record<string, string>` — permissive fallback when nothing is registered.
46
+ *
47
+ * Referencing `GeneratedRouteMap` here is cycle-safe: it is declared in the
48
+ * standalone gen file with no imports, unlike `RegisteredRoutes extends typeof
49
+ * router.routeMap`.
50
50
  */
51
- export type GetRegisteredRoutes = keyof RSCRouter.RegisteredRoutes extends never
52
- ? Record<string, string>
53
- : RSCRouter.RegisteredRoutes;
51
+ export type GetRegisteredRoutes = keyof Rango.RegisteredRoutes extends never
52
+ ? keyof Rango.GeneratedRouteMap extends never
53
+ ? Record<string, string>
54
+ : Rango.GeneratedRouteMap
55
+ : Rango.RegisteredRoutes;
54
56
 
55
57
  /**
56
58
  * Default route map for reverse() surfaces.
@@ -58,12 +60,11 @@ export type GetRegisteredRoutes = keyof RSCRouter.RegisteredRoutes extends never
58
60
  * cycles, but falls back to RegisteredRoutes for manual augmentation and then to
59
61
  * a permissive record when no route types are available.
60
62
  */
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;
63
+ export type DefaultReverseRouteMap = keyof Rango.GeneratedRouteMap extends never
64
+ ? keyof Rango.RegisteredRoutes extends never
65
+ ? Record<string, string>
66
+ : Rango.RegisteredRoutes
67
+ : Rango.GeneratedRouteMap;
67
68
 
68
69
  /**
69
70
  * Default route map for Handler type.
@@ -71,30 +72,42 @@ export type DefaultReverseRouteMap =
71
72
  * circular dependencies: router.tsx -> urls.tsx -> handler.tsx -> RegisteredRoutes -> router.tsx.
72
73
  * GeneratedRouteMap is declared in a standalone gen file with no imports.
73
74
  */
74
- export type DefaultHandlerRouteMap =
75
- keyof RSCRouter.GeneratedRouteMap extends never
76
- ? {}
77
- : RSCRouter.GeneratedRouteMap;
75
+ export type DefaultHandlerRouteMap = keyof Rango.GeneratedRouteMap extends never
76
+ ? {}
77
+ : Rango.GeneratedRouteMap;
78
78
 
79
79
  /**
80
- * Default environment type - uses global augmentation if available, any otherwise
80
+ * Default environment type - uses global augmentation if available.
81
+ *
82
+ * Falls back to `unknown` (not `any`) when `Rango.Env` is not augmented, so
83
+ * an app that forgets to register its bindings gets a compile error on
84
+ * `ctx.env.SOMETHING` instead of silently losing all env type-checking. Augment
85
+ * `Rango.Env` to type `ctx.env`.
81
86
  */
82
- export type DefaultEnv = keyof RSCRouter.Env extends never
83
- ? any
84
- : RSCRouter.Env;
87
+ export type DefaultEnv = keyof Rango.Env extends never ? unknown : Rango.Env;
85
88
 
86
89
  /**
87
- * Default variables type - uses global augmentation if available, Record<string, any> otherwise
90
+ * Variables type backing the string-key `ctx.get` / `ctx.set` overloads.
91
+ *
92
+ * Uses `Rango.Vars` augmentation when present; otherwise falls back to
93
+ * `Record<string, any>` so an un-augmented app can use string-key vars with
94
+ * zero config -- at the cost of a typo'd key being silently `any`.
95
+ *
96
+ * This `any` fallback is deliberate (see #561) and is an intentional asymmetry
97
+ * with `DefaultEnv` above, which falls back to `unknown`: env bindings are
98
+ * platform-critical and should be registered, so a forgotten binding is made a
99
+ * compile error; vars are ad-hoc and middleware-set, so the zero-config path
100
+ * wins. Augment `Rango.Vars` for type-safe keys.
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;
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { Handle } from "../handle.js";
3
+ import type { HandlePush } from "../defer.js";
3
4
  import type { ContextVar } from "../context-var.js";
4
5
  import type { MiddlewareFn } from "../router/middleware.js";
5
6
  import type { Theme } from "../theme/types.js";
@@ -43,7 +44,7 @@ export type { MiddlewareFn } from "../router/middleware.js";
43
44
  */
44
45
  export type ScopedRouteMap<
45
46
  TPrefix extends string,
46
- TMap = RSCRouter.GeneratedRouteMap,
47
+ TMap = Rango.GeneratedRouteMap,
47
48
  > = {
48
49
  [K in keyof TMap as K extends `${TPrefix}.${infer Rest}`
49
50
  ? Rest
@@ -107,14 +108,6 @@ type StrictLocalParamsWithExtras<TEntry> =
107
108
  ? Record<string, string>
108
109
  : ExtractParamsFromEntry<TEntry, {}> & Record<string, string>;
109
110
 
110
- // HandlerContext.reverse is the only reverse surface with runtime param autofill
111
- // from the current matched request. Middleware/loaders/request context do not
112
- // have the same local-route guarantees, so they keep plain ScopedReverseFunction.
113
- //
114
- // When a handler has an explicit local route map, enforce that local route
115
- // params declared by that map are present while still allowing extra mount
116
- // params to be passed through. Global names remain autofill-friendly because
117
- // parent include() params are often unknown at the module definition site.
118
111
  type StrictLocalAutofillGlobalReverseFunction<TLocalRoutes, TGlobalRoutes> =
119
112
  ScopedReverseFunction<TLocalRoutes, TGlobalRoutes> & {
120
113
  <TName extends keyof TGlobalRoutes & string>(
@@ -282,6 +275,8 @@ export type HandlerContext<
282
275
  * For handles: Returns a push function to add data for this segment.
283
276
  * Handle data accumulates across all matched route segments.
284
277
  * Push accepts: direct value, Promise, or async callback (executed immediately).
278
+ * Or call `.defer()` to reserve the slot now and resolve it later (e.g. from a
279
+ * deep async component), with a timeout safety net — see {@link HandlePush}.
285
280
  *
286
281
  * @example
287
282
  * ```typescript
@@ -315,6 +310,13 @@ export type HandlerContext<
315
310
  * });
316
311
  * return <ProductPage />;
317
312
  * });
313
+ *
314
+ * // Handle usage - deferred (reserve the slot now, resolve from a deep component)
315
+ * route("product", (ctx) => {
316
+ * const resolve = ctx.use(Breadcrumbs).defer({ timeoutMs: 5000, else: null });
317
+ * loadCrumb(ctx.params.id).then(resolve); // resolver is push-equal
318
+ * return <ProductPage />; // auto-resolves to `else` on timeout
319
+ * });
318
320
  * ```
319
321
  */
320
322
  use: {
@@ -323,7 +325,7 @@ export type HandlerContext<
323
325
  ): Promise<T>;
324
326
  <TData, TAccumulated = TData[]>(
325
327
  handle: Handle<TData, TAccumulated>,
326
- ): (data: TData | Promise<TData> | (() => Promise<TData>)) => void;
328
+ ): HandlePush<TData>;
327
329
  };
328
330
  /**
329
331
  * Current theme (from cookie or default).
@@ -430,6 +432,18 @@ export type InternalHandlerContext<
430
432
  _responseType?: string;
431
433
  /** Route name for cache key scoping (prevents cross-route collisions). */
432
434
  _routeName?: string;
435
+ /**
436
+ * @internal Loader-cache override table: loaderId -> memoized data promise.
437
+ * A single stable ctx.use interceptor consults this instead of chaining one
438
+ * wrapper per cached loader (avoids O(N) dispatch). See loader-cache.ts.
439
+ */
440
+ _loaderCacheOverrides?: Map<string, Promise<any>>;
441
+ /**
442
+ * @internal ctx.use captured before the loader-cache interceptor was installed.
443
+ * The cache-miss execute runs the loader through this, bypassing the override
444
+ * table (so a loader cannot await its own in-flight memoized promise).
445
+ */
446
+ _loaderCacheOriginalUse?: (item: any) => any;
433
447
  };
434
448
 
435
449
  /**
@@ -513,6 +527,19 @@ export type RevalidateParams<TParams = GenericParams, TEnv = any> = Parameters<
513
527
  * })
514
528
  * ```
515
529
  */
530
+ /**
531
+ * A reference to a server action, used by `isAction()` in a revalidate predicate.
532
+ *
533
+ * Either a directly imported action (`import { addToCart }`) or a namespace
534
+ * import of an action module (`import * as CartActions`). Matching resolves the
535
+ * action's build-injected id (`path#export`) — the same identity the router uses
536
+ * for `actionId` — so a renamed or moved action breaks at compile time instead
537
+ * of silently failing to match.
538
+ */
539
+ export type ActionRef =
540
+ | ((...args: never[]) => unknown)
541
+ | Record<string, unknown>;
542
+
516
543
  /**
517
544
  * Revalidation function called during client-side navigation to decide whether
518
545
  * a segment (layout, route, parallel slot, or loader) should be re-rendered.
@@ -522,12 +549,24 @@ export type RevalidateParams<TParams = GenericParams, TEnv = any> = Parameters<
522
549
  * downstream revalidators, or nothing (`void` / `null` / `undefined`) to defer
523
550
  * to the current suggestion without changing it.
524
551
  *
552
+ * Two idioms cover almost every case; they differ only in what an _unrelated_
553
+ * action does. Match actions by reference with `ctx.isAction()` (rename-safe)
554
+ * rather than `actionId?.includes("...")` (a renamed or moved action silently
555
+ * stops matching). Because `isAction` returns a raw boolean, combine it with
556
+ * `|| undefined` to defer or leave it bare to suppress.
557
+ *
525
558
  * @example
526
559
  * ```ts
527
- * // Re-render only when a cart action happened or browser signals staleness
528
- * revalidate(({ actionId, stale }) =>
529
- * actionId?.includes("cart") || stale || false
530
- * )
560
+ * import * as CartActions from "./actions/cart";
561
+ *
562
+ * // Idiom A — "mine, else defer": re-render on my actions, otherwise return
563
+ * // undefined so the segment's default decision still applies (and downstream
564
+ * // revalidators get a say).
565
+ * revalidate((ctx) => ctx.isAction(CartActions) || undefined)
566
+ *
567
+ * // Idiom B — "mine only": re-render on my actions and suppress everything
568
+ * // else (isAction returns a raw boolean, so an unrelated action yields false).
569
+ * revalidate((ctx) => ctx.isAction(CartActions))
531
570
  *
532
571
  * // Always re-render when params change (default behavior made explicit)
533
572
  * revalidate(({ defaultShouldRevalidate }) => defaultShouldRevalidate)
@@ -553,8 +592,11 @@ export type ShouldRevalidateFn<TParams = GenericParams, TEnv = any> = (args: {
553
592
 
554
593
  // ── Segment metadata (which segment is being evaluated) ──────────────
555
594
 
556
- /** The type of segment being revalidated. */
557
- segmentType: "layout" | "route" | "parallel";
595
+ /**
596
+ * The type of segment being revalidated. `"loader"` is passed to revalidate
597
+ * functions attached to a `loader(Fn, () => [revalidate(...)])` registration.
598
+ */
599
+ segmentType: "layout" | "route" | "parallel" | "loader";
558
600
  /** Layout name (e.g., `"root"`, `"shop"`, `"auth"`). Only set for layout segments. */
559
601
  layoutName?: string;
560
602
  /** Slot name (e.g., `"@sidebar"`, `"@modal"`). Only set for parallel segments. */
@@ -570,21 +612,54 @@ export type ShouldRevalidateFn<TParams = GenericParams, TEnv = any> = (args: {
570
612
  * relative to the project root, followed by `#` and the exported function name.
571
613
  *
572
614
  * This is stable and can be used for path-based matching to revalidate
573
- * when any action in a module or directory fires:
615
+ * when any action in a module or directory fires. Prefer `|| undefined`
616
+ * (defer to the segment default / downstream revalidators) over `?? false`
617
+ * (hard short-circuit that suppresses the default and ends the chain):
574
618
  *
575
619
  * @example
576
620
  * ```ts
577
621
  * // Match a specific action
578
- * revalidate(({ actionId }) => actionId === "src/actions/cart.ts#addToCart")
622
+ * revalidate(({ actionId }) => actionId === "src/actions/cart.ts#addToCart" || undefined)
579
623
  *
580
624
  * // Match any action in the cart module
581
- * revalidate(({ actionId }) => actionId?.includes("cart") ?? false)
625
+ * revalidate(({ actionId }) => actionId?.includes("cart") || undefined)
582
626
  *
583
627
  * // Match any action under src/apps/store/actions/
584
- * revalidate(({ actionId }) => actionId?.startsWith("src/apps/store/actions/") ?? false)
628
+ * revalidate(({ actionId }) => actionId?.startsWith("src/apps/store/actions/") || undefined)
585
629
  * ```
586
630
  */
587
631
  actionId?: string;
632
+ /**
633
+ * Typed, rename-safe action matching. Returns `true` when the action that
634
+ * triggered this revalidation is one of the given references — or, for a
635
+ * namespace import (`import * as CartActions`), any export of that module —
636
+ * and `false` otherwise (including plain navigation with no action).
637
+ *
638
+ * Called with NO arguments it answers "is this request an action at all?":
639
+ * `true` for any action, `false` on plain navigation. Use the bare form when
640
+ * you want to revalidate on every action regardless of which one fired.
641
+ *
642
+ * Prefer this over hand-written `actionId` substring matches: it resolves the
643
+ * action's stable `path#export` id from the imported reference, so a rename is
644
+ * a type error in one place instead of silent drift across consumers. It
645
+ * resolves the reference the same way the action boundary derives `actionId`
646
+ * (`$id ?? $$id`), so it matches in both dev and production.
647
+ *
648
+ * Returns a raw boolean, so for the common "revalidate on match, else defer"
649
+ * intent combine with `|| undefined`:
650
+ *
651
+ * @example
652
+ * ```ts
653
+ * import { addToCart, removeFromCart } from "./actions/cart";
654
+ * import * as CartActions from "./actions/cart";
655
+ *
656
+ * revalidate((ctx) => ctx.isAction() || undefined); // any action
657
+ * revalidate((ctx) => ctx.isAction(addToCart) || undefined); // one action
658
+ * revalidate((ctx) => ctx.isAction(addToCart, removeFromCart) || undefined); // several
659
+ * revalidate((ctx) => ctx.isAction(CartActions) || undefined); // any in the module
660
+ * ```
661
+ */
662
+ isAction: (...actions: ActionRef[]) => boolean;
588
663
  /** URL where the action was executed (the page the user was on when they triggered the action). */
589
664
  actionUrl?: URL;
590
665
  /** Return value from the action execution. Can be used to conditionally revalidate based on the action's outcome. */
@@ -725,7 +800,7 @@ export type Revalidate<
725
800
  * Middleware function with typed params and environment
726
801
  *
727
802
  * @template TParams - Params object (defaults to generic)
728
- * @template TEnv - Environment type (defaults to global RSCRouter.Env)
803
+ * @template TEnv - Environment type (defaults to global Rango.Env)
729
804
  *
730
805
  * Note: Middleware cannot directly use route names for params typing because
731
806
  * middleware is defined during router setup, before RegisteredRoutes is populated.
@@ -733,7 +808,7 @@ export type Revalidate<
733
808
  *
734
809
  * @example
735
810
  * ```typescript
736
- * // Basic middleware (uses global RSCRouter.Env via module augmentation)
811
+ * // Basic middleware (uses global Rango.Env via module augmentation)
737
812
  * const middleware: Middleware = async (ctx, next) => {
738
813
  * ctx.set("user", { id: "123" }); // Type-safe!
739
814
  * await next();