@rangojs/router 0.18.0 → 0.19.0

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 (244) hide show
  1. package/dist/types/browser/event-controller.d.ts +3 -3
  2. package/dist/types/browser/history-state.d.ts +2 -0
  3. package/dist/types/browser/navigation-transaction.d.ts +20 -2
  4. package/dist/types/browser/partial-update.d.ts +16 -1
  5. package/dist/types/browser/prefetch/cache.d.ts +6 -6
  6. package/dist/types/browser/react/Link.d.ts +19 -9
  7. package/dist/types/browser/react/context.d.ts +2 -2
  8. package/dist/types/browser/react/location-state-shared.d.ts +95 -56
  9. package/dist/types/browser/react/location-state.d.ts +1 -1
  10. package/dist/types/browser/transition-when.d.ts +80 -0
  11. package/dist/types/browser/types.d.ts +104 -9
  12. package/dist/types/build/generate-manifest.d.ts +8 -0
  13. package/dist/types/cache/background-task.d.ts +24 -2
  14. package/dist/types/cache/cache-exec-scope.d.ts +31 -0
  15. package/dist/types/cache/cache-key-utils.d.ts +44 -13
  16. package/dist/types/cache/cache-policy.d.ts +1 -1
  17. package/dist/types/cache/cache-runtime.d.ts +7 -0
  18. package/dist/types/cache/cache-scope.d.ts +117 -35
  19. package/dist/types/cache/cache-tag.d.ts +24 -4
  20. package/dist/types/cache/cf/cf-cache-store.d.ts +55 -44
  21. package/dist/types/cache/cf/cf-shell-frame.d.ts +1 -1
  22. package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +0 -15
  23. package/dist/types/cache/document-cache.d.ts +10 -0
  24. package/dist/types/cache/handle-snapshot.d.ts +40 -8
  25. package/dist/types/cache/invalidation-order.d.ts +23 -0
  26. package/dist/types/cache/request-tag-mask.d.ts +54 -0
  27. package/dist/types/cache/shell-snapshot.d.ts +88 -141
  28. package/dist/types/cache/tag-invalidation.d.ts +38 -14
  29. package/dist/types/cache/types.d.ts +68 -61
  30. package/dist/types/cache/vercel/vercel-cache-store.d.ts +23 -16
  31. package/dist/types/client-urls/navigation.d.ts +28 -2
  32. package/dist/types/client-urls/server-projection.d.ts +5 -2
  33. package/dist/types/client-urls/types.d.ts +5 -5
  34. package/dist/types/client.d.ts +1 -1
  35. package/dist/types/index.d.ts +1 -1
  36. package/dist/types/index.rsc.d.ts +1 -1
  37. package/dist/types/route-definition/helpers-types.d.ts +11 -11
  38. package/dist/types/route-name.d.ts +7 -0
  39. package/dist/types/router/error-handling.d.ts +1 -1
  40. package/dist/types/router/intercept-resolution.d.ts +2 -0
  41. package/dist/types/router/match-context.d.ts +5 -0
  42. package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
  43. package/dist/types/router/router-options.d.ts +4 -1
  44. package/dist/types/router/segment-resolution/loader-cache.d.ts +18 -1
  45. package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
  46. package/dist/types/router/segment-resolution/loader-snapshot.d.ts +14 -40
  47. package/dist/types/router/segment-resolution/mask-nested.d.ts +11 -3
  48. package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
  49. package/dist/types/router/transition-when.d.ts +24 -10
  50. package/dist/types/rsc/attach-transition-when.d.ts +18 -0
  51. package/dist/types/rsc/full-payload.d.ts +14 -7
  52. package/dist/types/rsc/response-cache-serve.d.ts +15 -12
  53. package/dist/types/rsc/shell-build-manifest.d.ts +4 -3
  54. package/dist/types/rsc/shell-capture-constants.d.ts +77 -20
  55. package/dist/types/rsc/shell-capture.d.ts +78 -81
  56. package/dist/types/rsc/shell-serve.d.ts +19 -48
  57. package/dist/types/rsc/types.d.ts +2 -0
  58. package/dist/types/segment-system.d.ts +7 -0
  59. package/dist/types/server/context.d.ts +89 -61
  60. package/dist/types/server/cookie-store.d.ts +30 -18
  61. package/dist/types/server/handle-store.d.ts +52 -1
  62. package/dist/types/server/request-context.d.ts +66 -45
  63. package/dist/types/server/request-headers.d.ts +44 -0
  64. package/dist/types/server.d.ts +1 -0
  65. package/dist/types/testing/e2e/index.d.ts +1 -1
  66. package/dist/types/testing/index.d.ts +3 -2
  67. package/dist/types/testing/internal/action-id.d.ts +7 -0
  68. package/dist/types/testing/location-state-key.d.ts +24 -0
  69. package/dist/types/testing/render-route.d.ts +17 -1
  70. package/dist/types/testing/run-transition-when.d.ts +44 -69
  71. package/dist/types/testing/serve-shell-request.d.ts +7 -6
  72. package/dist/types/testing/shell-status.d.ts +34 -22
  73. package/dist/types/transition-when-ref.d.ts +79 -0
  74. package/dist/types/types/cache-types.d.ts +15 -3
  75. package/dist/types/types/index.d.ts +1 -1
  76. package/dist/types/types/segments.d.ts +86 -71
  77. package/dist/types/urls/path-helper-types.d.ts +3 -4
  78. package/dist/types/urls/pattern-types.d.ts +3 -4
  79. package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
  80. package/dist/vite/index.js +960 -97
  81. package/package.json +1 -1
  82. package/skills/cache-guide/SKILL.md +76 -49
  83. package/skills/caching/SKILL.md +167 -69
  84. package/skills/client-urls/SKILL.md +1 -1
  85. package/skills/comparison/references/framework-comparison.md +8 -5
  86. package/skills/document-cache/SKILL.md +24 -0
  87. package/skills/hooks/SKILL.md +3 -1
  88. package/skills/hooks/navigation.md +23 -2
  89. package/skills/hooks/state.md +98 -6
  90. package/skills/intercept/SKILL.md +29 -12
  91. package/skills/loader/SKILL.md +52 -21
  92. package/skills/middleware/SKILL.md +18 -0
  93. package/skills/migrate-nextjs/SKILL.md +3 -3
  94. package/skills/observability/SKILL.md +6 -5
  95. package/skills/parallel/SKILL.md +1 -1
  96. package/skills/ppr/SKILL.md +129 -77
  97. package/skills/prerender/SKILL.md +3 -3
  98. package/skills/rango/SKILL.md +25 -6
  99. package/skills/route/SKILL.md +2 -0
  100. package/skills/testing/SKILL.md +27 -25
  101. package/skills/testing/cache-prerender.md +9 -9
  102. package/skills/testing/client-components.md +45 -3
  103. package/skills/testing/loader.md +3 -2
  104. package/skills/testing/middleware.md +1 -0
  105. package/skills/testing/predicates.md +49 -49
  106. package/skills/testing/render-handler.md +1 -0
  107. package/skills/testing/serve-shell-request.md +14 -0
  108. package/skills/testing/server-actions.md +9 -3
  109. package/skills/theme/SKILL.md +8 -4
  110. package/skills/typesafety/env-and-bindings.md +8 -0
  111. package/skills/use-cache/SKILL.md +64 -19
  112. package/skills/view-transitions/SKILL.md +150 -29
  113. package/src/__augment-tests__/augmented.check.ts +23 -0
  114. package/src/browser/event-controller.ts +4 -4
  115. package/src/browser/history-state.ts +52 -1
  116. package/src/browser/link-interceptor.ts +4 -0
  117. package/src/browser/navigation-bridge.ts +77 -18
  118. package/src/browser/navigation-client.ts +4 -3
  119. package/src/browser/navigation-store.ts +43 -1
  120. package/src/browser/navigation-transaction.ts +31 -11
  121. package/src/browser/partial-update.ts +146 -35
  122. package/src/browser/prefetch/cache.ts +6 -6
  123. package/src/browser/prefetch/fetch.ts +2 -2
  124. package/src/browser/react/Link.tsx +38 -33
  125. package/src/browser/react/NavigationProvider.tsx +2 -2
  126. package/src/browser/react/context.ts +2 -2
  127. package/src/browser/react/location-state-shared.ts +241 -49
  128. package/src/browser/react/location-state.ts +5 -2
  129. package/src/browser/rsc-router.tsx +4 -0
  130. package/src/browser/server-action-bridge.ts +84 -15
  131. package/src/browser/transition-when.ts +205 -0
  132. package/src/browser/types.ts +124 -10
  133. package/src/build/generate-manifest.ts +77 -1
  134. package/src/cache/background-task.ts +55 -2
  135. package/src/cache/cache-exec-scope.ts +48 -1
  136. package/src/cache/cache-key-utils.ts +56 -16
  137. package/src/cache/cache-policy.ts +9 -4
  138. package/src/cache/cache-runtime.ts +197 -144
  139. package/src/cache/cache-scope.ts +304 -112
  140. package/src/cache/cache-tag.ts +105 -13
  141. package/src/cache/cf/cf-cache-store.ts +152 -76
  142. package/src/cache/cf/cf-shell-frame.ts +2 -2
  143. package/src/cache/cf/cf-tag-marker-memo.ts +11 -100
  144. package/src/cache/document-cache.ts +53 -7
  145. package/src/cache/handle-snapshot.ts +52 -9
  146. package/src/cache/invalidation-order.ts +84 -0
  147. package/src/cache/request-tag-mask.ts +147 -0
  148. package/src/cache/shell-snapshot.ts +130 -348
  149. package/src/cache/tag-invalidation.ts +57 -51
  150. package/src/cache/types.ts +71 -67
  151. package/src/cache/vercel/vercel-cache-store.ts +61 -58
  152. package/src/client-urls/client-root.tsx +8 -4
  153. package/src/client-urls/client-urls.ts +8 -6
  154. package/src/client-urls/navigation.ts +55 -4
  155. package/src/client-urls/server-projection.ts +31 -10
  156. package/src/client-urls/types.ts +12 -5
  157. package/src/client.tsx +2 -0
  158. package/src/host/cookie-handler.ts +2 -1
  159. package/src/index.rsc.ts +3 -0
  160. package/src/index.ts +3 -0
  161. package/src/loader-redirect.tsx +7 -3
  162. package/src/prerender/build-shell-capture.ts +155 -146
  163. package/src/route-definition/dsl-helpers.ts +2 -0
  164. package/src/route-definition/helpers-types.ts +11 -11
  165. package/src/route-name.ts +12 -0
  166. package/src/router/content-negotiation.ts +4 -1
  167. package/src/router/error-handling.ts +5 -2
  168. package/src/router/handler-context.ts +10 -7
  169. package/src/router/intercept-resolution.ts +11 -1
  170. package/src/router/loader-resolution.ts +28 -3
  171. package/src/router/logging.ts +5 -3
  172. package/src/router/match-api.ts +62 -34
  173. package/src/router/match-context.ts +5 -0
  174. package/src/router/match-handlers.ts +9 -29
  175. package/src/router/match-middleware/background-revalidation.ts +3 -5
  176. package/src/router/match-middleware/cache-lookup.ts +35 -19
  177. package/src/router/match-middleware/cache-store.ts +15 -9
  178. package/src/router/match-result.ts +1 -0
  179. package/src/router/middleware.ts +2 -5
  180. package/src/router/navigation-snapshot.ts +6 -5
  181. package/src/router/prerender-match.ts +4 -0
  182. package/src/router/request-classification.ts +7 -4
  183. package/src/router/router-options.ts +4 -1
  184. package/src/router/segment-resolution/fresh.ts +0 -4
  185. package/src/router/segment-resolution/loader-cache.ts +150 -25
  186. package/src/router/segment-resolution/loader-mask.ts +3 -4
  187. package/src/router/segment-resolution/loader-snapshot.ts +15 -78
  188. package/src/router/segment-resolution/mask-nested.ts +47 -22
  189. package/src/router/segment-resolution/revalidation.ts +0 -3
  190. package/src/router/segment-resolution/view-transition-default.ts +6 -21
  191. package/src/router/telemetry.ts +6 -3
  192. package/src/router/transition-when.ts +34 -52
  193. package/src/router.ts +2 -1
  194. package/src/rsc/attach-transition-when.ts +47 -0
  195. package/src/rsc/full-payload.ts +30 -10
  196. package/src/rsc/handler.ts +12 -10
  197. package/src/rsc/loader-fetch.ts +2 -1
  198. package/src/rsc/manifest-init.ts +4 -0
  199. package/src/rsc/origin-guard.ts +8 -5
  200. package/src/rsc/progressive-enhancement.ts +7 -30
  201. package/src/rsc/response-cache-serve.ts +68 -80
  202. package/src/rsc/response-route-handler.ts +2 -2
  203. package/src/rsc/rsc-rendering.ts +206 -252
  204. package/src/rsc/server-action.ts +8 -20
  205. package/src/rsc/shell-build-manifest.ts +22 -20
  206. package/src/rsc/shell-capture-constants.ts +136 -20
  207. package/src/rsc/shell-capture.ts +352 -589
  208. package/src/rsc/shell-serve.ts +73 -109
  209. package/src/rsc/ssr-setup.ts +3 -2
  210. package/src/rsc/types.ts +2 -0
  211. package/src/segment-system.tsx +40 -7
  212. package/src/server/context.ts +189 -124
  213. package/src/server/cookie-store.ts +153 -127
  214. package/src/server/handle-store.ts +245 -27
  215. package/src/server/request-context.ts +123 -84
  216. package/src/server/request-headers.ts +134 -0
  217. package/src/server.ts +4 -0
  218. package/src/testing/dispatch.ts +4 -7
  219. package/src/testing/e2e/index.ts +1 -0
  220. package/src/testing/index.ts +5 -0
  221. package/src/testing/internal/action-id.ts +25 -0
  222. package/src/testing/internal/context.ts +1 -1
  223. package/src/testing/location-state-key.ts +45 -0
  224. package/src/testing/render-handler.ts +1 -1
  225. package/src/testing/render-route.tsx +109 -16
  226. package/src/testing/run-client-revalidate.ts +3 -19
  227. package/src/testing/run-loader.ts +5 -1
  228. package/src/testing/run-transition-when.ts +109 -172
  229. package/src/testing/serve-shell-request.ts +10 -7
  230. package/src/testing/shell-status.ts +60 -56
  231. package/src/transition-when-ref.ts +220 -0
  232. package/src/types/cache-types.ts +15 -3
  233. package/src/types/index.ts +3 -0
  234. package/src/types/segments.ts +94 -91
  235. package/src/urls/path-helper-types.ts +3 -4
  236. package/src/urls/pattern-types.ts +3 -4
  237. package/src/vite/discovery/discover-routers.ts +3 -0
  238. package/src/vite/discovery/shell-prerender-phase.ts +0 -2
  239. package/src/vite/discovery/virtual-module-codegen.ts +16 -6
  240. package/src/vite/plugins/transition-when-hoist.ts +1064 -0
  241. package/src/vite/rango.ts +2 -0
  242. package/src/vite/router-discovery.ts +75 -5
  243. package/dist/types/rsc/transition-gate.d.ts +0 -23
  244. package/src/rsc/transition-gate.ts +0 -86
@@ -38,7 +38,7 @@ export type { RunMiddlewareOptions, RunMiddlewareResult, } from "./run-middlewar
38
38
  export { runLoader, runLoaderResult } from "./run-loader.js";
39
39
  export type { RunLoaderOptions, RunLoaderResult, UseResolver, TestLoaderContext, } from "./run-loader.js";
40
40
  export { runTransitionWhen } from "./run-transition-when.js";
41
- export type { RunTransitionWhenOptions, RunTransitionWhenResult, } from "./run-transition-when.js";
41
+ export type { RunTransitionWhenAction, RunTransitionWhenLocation, RunTransitionWhenOptions, RunTransitionWhenResult, } from "./run-transition-when.js";
42
42
  export { runClientRevalidate } from "./run-client-revalidate.js";
43
43
  export type { RunClientRevalidateOptions } from "./run-client-revalidate.js";
44
44
  export { dispatch } from "./dispatch.js";
@@ -47,8 +47,9 @@ export { assertCacheStatus, assertCacheDecision, parseCacheHeader, createCacheSi
47
47
  export type { ExpectedCacheStatus, CacheStatusTarget, CacheSink, } from "./cache-status.js";
48
48
  export type { TelemetryEvent, TelemetrySink, CacheDecisionEvent, CacheSegmentSignal, CacheSegmentStatus, } from "../router/telemetry.js";
49
49
  export { assertPprReplayStatus, assertShellStatus, parsePprReplayStatus, parseShellStatus, PPR_REPLAY_STATUS_HEADER, shellCacheKey, SHELL_STATUS_HEADER, } from "./shell-status.js";
50
- export type { PprReplayBypassReason, PprReplayStatus, ShellStatus, ShellStatusTarget, } from "./shell-status.js";
50
+ export type { PprReplayBypassReason, PprReplayStatus, ShellCachePartition, ShellStatus, ShellStatusTarget, } from "./shell-status.js";
51
51
  export { collectHandle } from "./collect-handle.js";
52
+ export { withLocationStateKey } from "./location-state-key.js";
52
53
  export { diffGeneratedRoutes, assertGeneratedRoutesMatch, } from "./generated-routes.js";
53
54
  export type { GeneratedRoutesDiff, GeneratedRouteMismatch, } from "./generated-routes.js";
54
55
  export { createTestRequestContext, runInRequestContext, toRequest, seedVariables, } from "./internal/context.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The id a testing primitive's `action` option names: a single imported
3
+ * server action (its `$id ?? $$id`, as the action boundary derives it) or a
4
+ * raw actionId string. A function without either id throws, naming the
5
+ * primitive.
6
+ */
7
+ export declare function resolveTestActionId(action: ((...args: never[]) => unknown) | string | undefined, primitive: string): string | undefined;
@@ -0,0 +1,24 @@
1
+ import { type LocationStateDefinition } from "../browser/react/location-state-shared.js";
2
+ /**
3
+ * Assign a location-state key to a `createLocationState()` definition in a unit
4
+ * test that runs without the rango Vite plugin (which injects the key in dev
5
+ * and build). Outside production, a definition without a key throws on first
6
+ * use (`MyState(value)`, `useLocationState(MyState)`, `.read()`).
7
+ *
8
+ * - `withLocationStateKey(GridState, "GridState")` sets `__rsc_ls_GridState`
9
+ * (a name that already starts with `__rsc_ls_` is used as-is).
10
+ * - Without a name, a key already set (by the plugin or an earlier call) is
11
+ * kept; otherwise the definition gets a synthetic `__rsc_ls_test_<n>` key,
12
+ * which then stays on it.
13
+ *
14
+ * Returns the definition.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { withLocationStateKey } from "@rangojs/router/testing";
19
+ * import { GridState } from "../src/location-states";
20
+ *
21
+ * withLocationStateKey(GridState);
22
+ * ```
23
+ */
24
+ export declare function withLocationStateKey<TDefinition extends LocationStateDefinition<any, any>>(definition: TDefinition, name?: string): TDefinition;
@@ -30,6 +30,11 @@
30
30
  * model is the held-navigation useLoader().isLoading: a `transition` spec
31
31
  * plus a pending Promise seeded via navigate(url, { loaders }) commits
32
32
  * through production's commitInTransition (browser/partial-update.ts).
33
+ * - A spec's transition({ when }) decides every commit with production's
34
+ * browser decision: navigate() and useRouter().push model kind "push",
35
+ * useRouter().replace kind "replace", refresh() kind "revalidate".
36
+ * Back/forward, action and optimistic clientUrls() swap decisions are
37
+ * e2e territory.
33
38
  * What it DOES cover: client hooks that read NavigationProvider /
34
39
  * OutletContext — useParams, useReverse, useHref, useMount, useNavigation,
35
40
  * useRouter, usePathname, useSearchParams, Outlet/useOutlet nesting and seeded
@@ -273,8 +278,19 @@ export interface TestRouterHandle {
273
278
  * // reader: isLoading true, old data
274
279
  * await act(async () => resolve({ name: "Product 2" }));
275
280
  * // reader: isLoading false, new data
281
+ *
282
+ * `options.transition: false` is the per-navigation opt-out
283
+ * (`router.push(url, { transition: false })`, `<Link transition={false}>`):
284
+ * the commit is urgent and no transition({ when }) predicate is called.
285
+ */
286
+ navigate(url: string, options?: Pick<RenderRouteOptions, "loaders"> & {
287
+ transition?: boolean;
288
+ }): Promise<void>;
289
+ /**
290
+ * Re-render the current location, as router.refresh() does: a spec's
291
+ * transition({ when }) decides it with kind "revalidate" (`to` is `from`).
276
292
  */
277
- navigate(url: string, options?: Pick<RenderRouteOptions, "loaders">): Promise<void>;
293
+ refresh(): Promise<void>;
278
294
  /** The current committed pathname. */
279
295
  pathname(): string;
280
296
  /** The current committed params. */
@@ -1,78 +1,53 @@
1
1
  /**
2
- * runTransitionWhen — unit-test a transition({ when }) predicate in isolation.
2
+ * runTransitionWhen — unit-test a transition({ when }) browser predicate.
3
3
  *
4
- * Runs the SAME server functions the router uses — the PPR pre-handler evaluator
5
- * when `ppr: true`, applyViewTransitionDefault (which strips the server-only
6
- * function), and gateTransitions. So the
7
- * predicate sees exactly the navigation/action metadata it would at runtime
8
- * (currentUrl/currentParams/fromRouteName, nextUrl/nextParams/toRouteName,
9
- * actionId/actionUrl/actionResult/formData/method, get/env), and `kept` reflects
10
- * whether the transition would apply this request. The result also exposes the
11
- * assembled `whenContext` so tests can assert the exact fields without reaching
12
- * into private request-context state.
4
+ * Builds the context and evaluates the predicate through the SAME browser
5
+ * functions the router uses at navigation time (browser/transition-when.ts):
6
+ * a throw counts as false and is logged. `from`/`to` take a URL string or a
7
+ * partial RouteLocation; a `state` given as location-state entries
8
+ * (`[Def(value)]`, what Link/push take) is stored the way a push stores it,
9
+ * so `Def.read(ctx.to)` reads it back. Accepts the predicate or a whole
10
+ * TransitionConfig.
13
11
  *
14
- * This is the public way to exercise a transition gate: the full
15
- * match -> render pipeline that wires these together only runs under real RSC
16
- * rendering (which the Flight primitives do not drive), so without this primitive
17
- * a consumer could not test their predicate through @rangojs/router/testing.
18
- *
19
- * Synchronous: a transition predicate returns a boolean and the gate has no I/O.
20
- */
21
- import { type RequestContext } from "../server/request-context.js";
22
- import { type VarsInit } from "./internal/context.js";
23
- import type { TransitionConfig, TransitionWhenContext } from "../types/segments.js";
24
- import type { OnErrorCallback } from "../types/error-types.js";
25
- /**
26
- * Options for runTransitionWhen. All navigation/action fields are optional and
27
- * default to "absent", matching what the gate sees for an initial full load with
28
- * no action: omit `currentUrl`/`currentParams`/`fromRouteName` to model the
29
- * navigation source being unavailable, and omit the `action*` fields to model a
30
- * plain (non-action) navigation.
12
+ * Synchronous: a transition predicate returns a boolean and has no I/O.
31
13
  */
32
- export interface RunTransitionWhenOptions<TEnv = any> {
33
- /** The navigation TARGET request (drives `nextUrl`): a Request or URL/path string. Defaults to `http://localhost/`. */
34
- request?: Request | string;
35
- /** Route params for the target (`nextParams`). */
36
- params?: Record<string, string>;
37
- /** Target route name (`toRouteName`). */
38
- toRouteName?: string;
39
- /** Environment bindings surfaced as `env` (and `ctx.env`). */
40
- env?: TEnv;
41
- /** Variables readable via the predicate's `get()`. With `ppr`, these model pre-handler middleware/input state. */
42
- vars?: VarsInit;
43
- /** Navigation SOURCE url (`currentUrl`): a URL or path string. */
44
- currentUrl?: string | URL;
45
- /** Source route params (`currentParams`). */
46
- currentParams?: Record<string, string>;
47
- /** Source route name (`fromRouteName`). */
48
- fromRouteName?: string;
49
- /** Id of the action that triggered a revalidation (`actionId`). */
50
- actionId?: string;
51
- /** Url the action was submitted from (`actionUrl`). */
52
- actionUrl?: string | URL;
53
- /** The action's return value (`actionResult`). */
54
- actionResult?: unknown;
55
- /** FormData from a form action (`formData`). */
14
+ import type { RouteLocation, TransitionConfig, TransitionWhenContext, TransitionWhenFn, TransitionWhenKind } from "../types/segments.js";
15
+ type ImportedAction = (...args: never[]) => unknown;
16
+ /** A navigation side: a URL, or a partial RouteLocation. */
17
+ export type RunTransitionWhenLocation = string | URL | (Partial<Omit<RouteLocation, "url">> & {
18
+ url?: string | URL;
19
+ });
20
+ /** The action fields of a `kind: "action"` context. */
21
+ export interface RunTransitionWhenAction {
22
+ /** The triggering action: an imported server action or its actionId. */
23
+ ref?: ImportedAction | string;
56
24
  formData?: FormData;
57
- /** Receives an error thrown by the predicate (the gate reports to `router.onError`, phase `"rendering"`). */
58
- onError?: OnErrorCallback;
59
- /** Model a route with `ppr`, where the predicate runs before route handlers and cache lookup. */
60
- ppr?: boolean;
25
+ /** The action's return value on success. */
26
+ result?: unknown;
27
+ /** What a failed action threw (the error lane). */
28
+ error?: unknown;
61
29
  }
62
- /**
63
- * Result of runTransitionWhen.
64
- */
65
- export interface RunTransitionWhenResult<TEnv = any> {
66
- /** True if the transition would apply this request (predicate returned non-false, or there is no `when`). */
67
- kept: boolean;
68
- /** Convenience inverse of `kept`. */
69
- dropped: boolean;
30
+ export interface RunTransitionWhenOptions {
31
+ /** Defaults to `"action"` when `action` is given, `"push"` otherwise. */
32
+ kind?: TransitionWhenKind;
33
+ /** The committed location being left. Defaults to `http://localhost/`. */
34
+ from?: RunTransitionWhenLocation;
35
+ /** The destination. Defaults to `from`; always `from` for "action" and "revalidate". */
36
+ to?: RunTransitionWhenLocation;
70
37
  /**
71
- * The production-assembled predicate context. Undefined when the config has
72
- * no `when` predicate.
38
+ * The triggering action (like runClientRevalidate's): an imported server
39
+ * action (id via `$id ?? $$id`), an actionId string, or
40
+ * `{ ref, formData, result, error }`.
73
41
  */
74
- whenContext?: TransitionWhenContext<Record<string, string>, TEnv>;
75
- /** The underlying RequestContext, for additional assertions (`ctx.get(...)`, etc.). */
76
- ctx: RequestContext<TEnv>;
42
+ action?: ImportedAction | string | RunTransitionWhenAction;
43
+ }
44
+ export interface RunTransitionWhenResult {
45
+ /** True when the navigation holds (the predicate did not return false or throw, or there is none). */
46
+ applied: boolean;
47
+ /** Inverse of `applied`. */
48
+ gatedOff: boolean;
49
+ /** The context the predicate received. */
50
+ context: TransitionWhenContext;
77
51
  }
78
- export declare function runTransitionWhen<TEnv = any>(config: TransitionConfig, opts?: RunTransitionWhenOptions<TEnv>): RunTransitionWhenResult<TEnv>;
52
+ export declare function runTransitionWhen(whenOrConfig: TransitionWhenFn | TransitionConfig, opts?: RunTransitionWhenOptions): RunTransitionWhenResult;
53
+ export {};
@@ -100,12 +100,13 @@ export interface ServeShellRequestResult {
100
100
  /**
101
101
  * Reset the per-isolate PPR state requests leave behind, so the next test
102
102
  * starts as a fresh worker would: the capture's stampede guard, its backoff
103
- * (a refused capture backs its URL off for later tests too), the capture's
104
- * and the serve path's once-per-key warnings, the build-shell manifest memo,
105
- * and CFCacheStore's isolate memos (shells, tag markers, tag hints), which
106
- * every CFCacheStore in the process shares by namespace and URL. Call it in
107
- * `beforeEach`, never while a request is in flight. VercelCacheStore's memos
108
- * live on the `cache` handle it is given: a new handle starts empty.
103
+ * (a refused capture backs its URL off for later tests too), the shell path's
104
+ * once-per-key warnings, the build-shell manifest memo, the "use cache"
105
+ * in-flight leaders and warnings, and CFCacheStore's isolate memos (shells,
106
+ * tag markers, tag hints) and warnings, which every CFCacheStore in the
107
+ * process shares by namespace and URL. Call it in `beforeEach`, never while
108
+ * a request is in flight. VercelCacheStore's memos live on the `cache`
109
+ * handle it is given: a new handle starts empty.
109
110
  */
110
111
  export declare function resetShellTestState(): Promise<void>;
111
112
  /**
@@ -31,16 +31,12 @@
31
31
  * Import from `@rangojs/router/testing` (Vitest) or `@rangojs/router/testing/e2e`
32
32
  * (Playwright — same pure helpers, no Vite virtuals).
33
33
  */
34
+ import { PPR_REPLAY_STATUS_HEADER, SHELL_STATUS_HEADER, type PprReplayBypassReason } from "../rsc/shell-capture-constants.js";
34
35
  import { type CacheSearchParams } from "../cache/search-params-filter.js";
35
- /** Production header name (`rsc/shell-serve.ts` `SHELL_STATUS_HEADER`). */
36
- export declare const SHELL_STATUS_HEADER: string;
37
- /** Partial-navigation replay decision header from `rsc/rsc-rendering.ts`. */
38
- export declare const PPR_REPLAY_STATUS_HEADER: string;
36
+ export { PPR_REPLAY_STATUS_HEADER, SHELL_STATUS_HEADER };
37
+ export type { PprReplayBypassReason };
39
38
  /** Values the serve path writes on `x-rango-shell`. */
40
39
  export type ShellStatus = "HIT" | "MISS";
41
- declare const PPR_REPLAY_BYPASS_REASONS: readonly ["method", "dynamic", "nonce", "store-unavailable", "passive-read-unsupported", "no-navigation-context", "prerender-store", "intercept", "cache-disabled", "read-error", "no-entry", "invalid-version", "corrupt-entry", "no-segment-snapshot", "snapshot-miss", "explicit-cache-hit", "stale-build-entry"];
42
- /** Bounded reasons a PPR partial request can fall open to ordinary matching. */
43
- export type PprReplayBypassReason = (typeof PPR_REPLAY_BYPASS_REASONS)[number];
44
40
  /** Parsed `x-rango-ppr-replay` value. */
45
41
  export type PprReplayStatus = {
46
42
  outcome: "HIT";
@@ -54,26 +50,43 @@ export type ShellStatusTarget = Response | {
54
50
  headers: Headers;
55
51
  };
56
52
  /**
57
- * Shell store key for a document URL — same formula as production
58
- * `buildShellKey` in `rsc/shell-serve.ts` (host + pathname + sorted search +
59
- * `:shell`), then the production `partitionShellKey` itself (the leaf
60
- * `rsc/shell-capture-constants.ts`). The base is kept here so the testing
61
- * barrel never imports the shell-serve module (it pulls React). A parity test
62
- * pins the two implementations.
53
+ * What partitions a ppr route's shell, for {@link shellCacheKey}: the
54
+ * request's results of the functions that partition the route's cache()
55
+ * record.
56
+ */
57
+ export interface ShellCachePartition {
58
+ /** The route's cache() `key()` results, outermost first. */
59
+ keys?: readonly string[];
60
+ /**
61
+ * Store `keyGenerator` results, one per store, outermost first: an
62
+ * enclosing cache() on another store's, then the store's of the route's
63
+ * own cache() when it sets no `key()` (with no route cache(), the app
64
+ * store's). When every one returns the default key they partition
65
+ * nothing: leave them out. Otherwise each keeps its position, and one
66
+ * that returns the default key is `""`.
67
+ */
68
+ generated?: readonly string[];
69
+ }
70
+ /**
71
+ * Shell store key for a document URL: the production `buildShellKey` (host +
72
+ * pathname + sorted search + `:shell`) and `partitionShellKey`, both from the
73
+ * React-free leaf `rsc/shell-capture-constants.ts`, so the testing barrel never
74
+ * imports the shell-serve module (it pulls React).
63
75
  *
64
76
  * Accepts a `URL` or an absolute/relative request URL string (relative strings
65
77
  * resolve against `http://localhost`). Pass the router's `cache.searchParams`
66
78
  * config as `searchParams` when the app under test sets one — the production
67
79
  * key applies it, so the expected key must too. When the route's record is
68
- * partitioned by the request — its `cache({ key })`, or the store's
69
- * `keyGenerator` — its shell is too: pass the key that function returns for
70
- * the request as `partition` (appended URI-encoded; a result equal to the
71
- * default key partitions nothing, so pass none). Under nested keyed
72
- * `cache()` scopes, pass their `key()` results as an array, outermost first:
73
- * they compose as the production record key composes them
74
- * (`composeCacheKeys`).
80
+ * partitioned by the request, its shell is too: pass what partitions it as
81
+ * `partition`, composed as production composes it (`composeCacheKeys`,
82
+ * which namespaces each `key()` result):
83
+ * - its `cache({ key })` result, as a string;
84
+ * - nested keyed `cache()` scopes' `key()` results, as an array, outermost
85
+ * first;
86
+ * - store `keyGenerator` results, with or without `key()` results, as
87
+ * `{ keys, generated }` (see {@link ShellCachePartition}).
75
88
  */
76
- export declare function shellCacheKey(url: URL | string, searchParams?: CacheSearchParams, partition?: string | readonly string[]): string;
89
+ export declare function shellCacheKey(url: URL | string, searchParams?: CacheSearchParams, partition?: string | readonly string[] | ShellCachePartition): string;
77
90
  /**
78
91
  * Read `x-rango-shell` from a response. Returns `null` when the header is
79
92
  * absent (axis-1 / non-ppr / ineligible request).
@@ -91,4 +104,3 @@ export declare function assertShellStatus(target: ShellStatusTarget, expected: S
91
104
  export declare function parsePprReplayStatus(target: ShellStatusTarget): PprReplayStatus | null;
92
105
  /** Assert a partial response's PPR replay outcome and freshness/reason. */
93
106
  export declare function assertPprReplayStatus(target: ShellStatusTarget, expected: PprReplayStatus): void;
94
- export {};
@@ -0,0 +1,79 @@
1
+ /**
2
+ * transition({ when }) references: what a route definition may carry as a
3
+ * `when`, how definitions are validated, and how the browser turns the carried
4
+ * value back into a callable predicate.
5
+ *
6
+ * `when` is a BROWSER predicate. The server never calls it; it only carries it
7
+ * to the browser inside the segment's transition config, as one of:
8
+ *
9
+ * - a React client reference: a function exported from a `"use client"`
10
+ * module and imported into a server `urls()` file, or an inline literal the
11
+ * build hoisted into one (vite/plugins/transition-when-hoist.ts). Flight
12
+ * serializes it as a module reference and the browser resolves it to the
13
+ * real function;
14
+ * - a clientUrls() when reference, synthesized by the projection materializer
15
+ * (client-urls/server-projection.ts): the group's definition client
16
+ * reference plus the route id. The browser resolves it to the `when` the
17
+ * route declared in its `"use client"` module.
18
+ *
19
+ * A plain function (a server function) cannot cross Flight, and a
20
+ * non-function is never callable. Both are LOUD errors: route discovery
21
+ * (generateManifestFull `validateTransitionWhen`) fails dev startup, the
22
+ * build and HMR re-discovery, and attachTransitionWhen (rsc/) throws the same
23
+ * error at render time for a route discovery did not see.
24
+ *
25
+ * Telling a client reference apart from a server function needs the
26
+ * react-server module graph, where a `"use client"` import IS a client
27
+ * reference. Outside it (a node/DOM unit-test project that aliases the router
28
+ * entry) the import is the plain function, so strict validation is enabled
29
+ * only by the Vite plugin: discovery passes the option, and the generated
30
+ * routes-manifest module calls enableTransitionWhenValidation() in the app's
31
+ * RSC realm (vite/discovery/virtual-module-codegen.ts).
32
+ */
33
+ import type { TransitionWhenFn } from "./types/segments.js";
34
+ export declare function isClientReference(value: unknown): boolean;
35
+ export declare function createClientUrlsWhenRef(definition: unknown, routeId: string): TransitionWhenFn;
36
+ /**
37
+ * Turn on server-function rejection for this realm. Called by the Vite
38
+ * plugin's generated routes-manifest module, never by tests: see the module
39
+ * comment for why it cannot be on by default.
40
+ */
41
+ export declare function enableTransitionWhenValidation(): void;
42
+ export declare function isTransitionWhenValidationEnabled(): boolean;
43
+ /** @internal Reset for unit tests. */
44
+ export declare function resetTransitionWhenValidation(): void;
45
+ /** Thrown for an invalid transition({ when }); recognized by the dev HMR overlay. */
46
+ export declare class TransitionWhenError extends Error {
47
+ readonly name: string;
48
+ }
49
+ /**
50
+ * The TransitionWhenError in an error's cause chain, matched by name: discovery
51
+ * throws it from the module runner's copy of this module (another class
52
+ * object), and include resolution wraps it (build/generate-manifest.ts).
53
+ */
54
+ export declare function findTransitionWhenError(error: unknown): Error | undefined;
55
+ /** Where an invalid `when` was declared, for the error message. */
56
+ export interface TransitionWhenSite {
57
+ /** The route the entry belongs to (the matched or enumerated route). */
58
+ readonly routeName?: string;
59
+ readonly pattern?: string;
60
+ /** The declaring entry's type when it is not the route itself. */
61
+ readonly entryType?: string;
62
+ }
63
+ /**
64
+ * The problem with a `when` value, or null when it is valid. Non-functions
65
+ * are always invalid; a plain function is invalid only under strict
66
+ * validation (see the module comment).
67
+ */
68
+ export declare function transitionWhenProblem(when: unknown, strict: boolean): "not-a-function" | "server-function" | null;
69
+ export declare function createTransitionWhenError(when: unknown, problem: "not-a-function" | "server-function", site: TransitionWhenSite): TransitionWhenError;
70
+ /**
71
+ * Definition-time shape check (the DSL's transition()). Runs in every
72
+ * environment, so it rejects only what is invalid everywhere: a non-function.
73
+ */
74
+ export declare function assertTransitionWhenShape(when: unknown): void;
75
+ /**
76
+ * Browser: turn a transition config's `when` into the predicate to call.
77
+ * Undefined when there is none (or a clientUrls route no longer declares it).
78
+ */
79
+ export declare function resolveTransitionWhen(when: unknown): TransitionWhenFn | undefined;
@@ -69,7 +69,13 @@ export interface CacheOptions<TEnv = unknown> {
69
69
  /**
70
70
  * Override the cache store for this boundary.
71
71
  * When specified, this boundary and its children use this store
72
- * instead of the app-level store from handler config.
72
+ * instead of the app-level store from handler config. The records of a
73
+ * boundary with a store here are partitioned by the `keyGenerator` of each
74
+ * enclosing cache() without a `key` whose store differs, the app-level
75
+ * store included: under `cache(() => [...])` on an app store with a
76
+ * `keyGenerator`, `cache({ store })` records are split by its result too.
77
+ * Likewise, without a `key` of its own, this store's `keyGenerator`
78
+ * partitions a nested cache() on another store.
73
79
  *
74
80
  * Useful for:
75
81
  * - Different backends per route section (memory vs KV vs Redis)
@@ -104,6 +110,8 @@ export interface CacheOptions<TEnv = unknown> {
104
110
  /**
105
111
  * Conditional cache read function.
106
112
  * Return false to skip cache for this request (always fetch fresh).
113
+ * It gates every cache() nested under this one too: a nested boundary
114
+ * caches only when every enclosing condition allows it.
107
115
  *
108
116
  * Has access to full RequestContext including env, request, params, cookies, etc.
109
117
  * Runs after global and route middleware on RSC routes; on response routes,
@@ -123,7 +131,10 @@ export interface CacheOptions<TEnv = unknown> {
123
131
  condition?: (ctx: import("../server/request-context.js").RequestContext<TEnv>) => boolean;
124
132
  /**
125
133
  * Custom cache key function - FULL OVERRIDE.
126
- * Bypasses default key generation AND store's keyGenerator.
134
+ * Bypasses default key generation AND store's keyGenerator. The result is
135
+ * stored namespaced (`key:` plus its URI encoding), so no value it returns
136
+ * names another route's record; a nested cache() keys its records within
137
+ * this partition.
127
138
  *
128
139
  * Has access to full RequestContext including env, request, params, cookies, etc.
129
140
  * Runs after global and route middleware on RSC routes; on response routes,
@@ -144,7 +155,8 @@ export interface CacheOptions<TEnv = unknown> {
144
155
  key?: (ctx: import("../server/request-context.js").RequestContext<TEnv>) => string | Promise<string>;
145
156
  /**
146
157
  * Tags for cache invalidation.
147
- * Can be a static array or a function that returns tags.
158
+ * Can be a static array or a function that returns tags. They tag the
159
+ * records of every cache() nested under this one too.
148
160
  *
149
161
  * The built-in `MemorySegmentCacheStore`, `CFCacheStore`, and
150
162
  * `VercelCacheStore` index by tag.
@@ -4,7 +4,7 @@ export type { DocumentProps, ExtractParams, TrailingSlashMode, RouteConfig, Rout
4
4
  export type { ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, LoaderDataResult, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, } from "./boundaries.js";
5
5
  export { isLoaderDataResult } from "./boundaries.js";
6
6
  export type { MiddlewareFn, ScopedRouteMap, Handler, HandlerContext, InternalHandlerContext, GenericParams, RevalidateParams, ShouldRevalidateFn, ActionRef, IsActionFn, RouteKeys, ExtractRouteParams, HandlersForRouteMap, Revalidate, Middleware, } from "./handler-context.js";
7
- export type { ViewTransitionClass, TransitionConfig, TransitionWhenFn, TransitionWhenContext, ResolvedSegment, SegmentMetadata, SlotState, RootLayoutProps, MatchResult, } from "./segments.js";
7
+ export type { ViewTransitionClass, TransitionConfig, TransitionWhenFn, TransitionWhenContext, TransitionWhenKind, RouteLocation, ServerRouteLocation, ResolvedSegment, SegmentMetadata, SlotState, RootLayoutProps, MatchResult, } from "./segments.js";
8
8
  export type { LazyIncludeContext, RouteEntry } from "./route-entry.js";
9
9
  export type { LoaderContext, LoaderFn, FetchableLoaderOptions, LoaderOptions, LoadOptions, LoaderDefinition, } from "./loader-types.js";
10
10
  export type { CacheContext, CacheOptions, PartialCacheOptions, EntryCacheConfig, } from "./cache-types.js";