@rangojs/router 0.17.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 (293) hide show
  1. package/README.md +3 -2
  2. package/dist/types/browser/cookie-name.d.ts +6 -0
  3. package/dist/types/browser/event-controller.d.ts +3 -3
  4. package/dist/types/browser/history-state.d.ts +18 -0
  5. package/dist/types/browser/navigation-transaction.d.ts +20 -2
  6. package/dist/types/browser/partial-update.d.ts +16 -1
  7. package/dist/types/browser/prefetch/cache.d.ts +6 -6
  8. package/dist/types/browser/react/Link.d.ts +19 -9
  9. package/dist/types/browser/react/context.d.ts +2 -2
  10. package/dist/types/browser/react/location-state-shared.d.ts +95 -56
  11. package/dist/types/browser/react/location-state.d.ts +1 -1
  12. package/dist/types/browser/transition-when.d.ts +80 -0
  13. package/dist/types/browser/types.d.ts +104 -9
  14. package/dist/types/build/generate-manifest.d.ts +8 -0
  15. package/dist/types/cache/background-task.d.ts +24 -2
  16. package/dist/types/cache/cache-exec-scope.d.ts +31 -0
  17. package/dist/types/cache/cache-key-utils.d.ts +48 -2
  18. package/dist/types/cache/cache-policy.d.ts +18 -1
  19. package/dist/types/cache/cache-runtime.d.ts +7 -0
  20. package/dist/types/cache/cache-scope.d.ts +192 -26
  21. package/dist/types/cache/cache-tag.d.ts +116 -11
  22. package/dist/types/cache/cf/cf-base64.d.ts +6 -0
  23. package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
  24. package/dist/types/cache/cf/cf-cache-store.d.ts +224 -72
  25. package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
  26. package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
  27. package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +19 -0
  28. package/dist/types/cache/document-cache.d.ts +10 -0
  29. package/dist/types/cache/handle-snapshot.d.ts +41 -8
  30. package/dist/types/cache/index.d.ts +1 -0
  31. package/dist/types/cache/invalidation-order.d.ts +23 -0
  32. package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
  33. package/dist/types/cache/request-tag-mask.d.ts +54 -0
  34. package/dist/types/cache/shell-memo.d.ts +178 -0
  35. package/dist/types/cache/shell-snapshot.d.ts +141 -105
  36. package/dist/types/cache/tag-invalidation.d.ts +54 -3
  37. package/dist/types/cache/types.d.ts +267 -96
  38. package/dist/types/cache/vercel/vercel-cache-store.d.ts +123 -18
  39. package/dist/types/client-urls/navigation.d.ts +28 -2
  40. package/dist/types/client-urls/server-projection.d.ts +5 -2
  41. package/dist/types/client-urls/types.d.ts +5 -5
  42. package/dist/types/client.d.ts +1 -1
  43. package/dist/types/index.d.ts +1 -1
  44. package/dist/types/index.rsc.d.ts +1 -1
  45. package/dist/types/prerender/build-shell-capture.d.ts +11 -4
  46. package/dist/types/route-definition/helpers-types.d.ts +11 -11
  47. package/dist/types/route-name.d.ts +7 -0
  48. package/dist/types/router/error-handling.d.ts +1 -1
  49. package/dist/types/router/instrument.d.ts +8 -0
  50. package/dist/types/router/intercept-resolution.d.ts +2 -0
  51. package/dist/types/router/match-context.d.ts +5 -0
  52. package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
  53. package/dist/types/router/middleware-types.d.ts +6 -1
  54. package/dist/types/router/router-options.d.ts +4 -1
  55. package/dist/types/router/segment-resolution/loader-cache.d.ts +58 -12
  56. package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
  57. package/dist/types/router/segment-resolution/loader-snapshot.d.ts +33 -48
  58. package/dist/types/router/segment-resolution/mask-nested.d.ts +73 -24
  59. package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
  60. package/dist/types/router/transition-when.d.ts +24 -10
  61. package/dist/types/rsc/attach-transition-when.d.ts +18 -0
  62. package/dist/types/rsc/full-payload.d.ts +21 -0
  63. package/dist/types/rsc/handler.d.ts +1 -1
  64. package/dist/types/rsc/response-cache-serve.d.ts +15 -12
  65. package/dist/types/rsc/shell-build-manifest.d.ts +12 -3
  66. package/dist/types/rsc/shell-capture-constants.d.ts +116 -12
  67. package/dist/types/rsc/shell-capture.d.ts +202 -74
  68. package/dist/types/rsc/shell-serve.d.ts +144 -50
  69. package/dist/types/rsc/types.d.ts +9 -0
  70. package/dist/types/segment-system.d.ts +7 -0
  71. package/dist/types/server/context.d.ts +155 -33
  72. package/dist/types/server/cookie-store.d.ts +33 -0
  73. package/dist/types/server/handle-store.d.ts +52 -1
  74. package/dist/types/server/request-context.d.ts +210 -63
  75. package/dist/types/server/request-headers.d.ts +44 -0
  76. package/dist/types/server.d.ts +1 -0
  77. package/dist/types/ssr/index.d.ts +9 -0
  78. package/dist/types/ssr/ssr-root.d.ts +9 -8
  79. package/dist/types/testing/e2e/index.d.ts +1 -1
  80. package/dist/types/testing/flight.entry.d.ts +7 -0
  81. package/dist/types/testing/index.d.ts +3 -2
  82. package/dist/types/testing/internal/action-id.d.ts +7 -0
  83. package/dist/types/testing/location-state-key.d.ts +24 -0
  84. package/dist/types/testing/render-route.d.ts +17 -1
  85. package/dist/types/testing/run-loader.d.ts +18 -3
  86. package/dist/types/testing/run-transition-when.d.ts +44 -69
  87. package/dist/types/testing/serve-shell-request.d.ts +133 -0
  88. package/dist/types/testing/shell-status.d.ts +44 -19
  89. package/dist/types/transition-when-ref.d.ts +79 -0
  90. package/dist/types/types/cache-types.d.ts +15 -3
  91. package/dist/types/types/handler-context.d.ts +14 -1
  92. package/dist/types/types/index.d.ts +1 -1
  93. package/dist/types/types/segments.d.ts +86 -71
  94. package/dist/types/urls/path-helper-types.d.ts +3 -4
  95. package/dist/types/urls/pattern-types.d.ts +21 -18
  96. package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
  97. package/dist/types/vite/router-discovery.d.ts +29 -2
  98. package/dist/vite/index.js +1005 -105
  99. package/package.json +1 -1
  100. package/skills/breadcrumbs/SKILL.md +17 -7
  101. package/skills/cache-guide/SKILL.md +175 -76
  102. package/skills/caching/SKILL.md +361 -33
  103. package/skills/catalog.json +1 -1
  104. package/skills/client-urls/SKILL.md +12 -7
  105. package/skills/cloudflare/SKILL.md +15 -0
  106. package/skills/comparison/references/framework-comparison.md +52 -37
  107. package/skills/defer-hydration/SKILL.md +50 -30
  108. package/skills/deployment-caching/SKILL.md +5 -2
  109. package/skills/document-cache/SKILL.md +32 -2
  110. package/skills/handler-use/SKILL.md +2 -0
  111. package/skills/hooks/SKILL.md +3 -1
  112. package/skills/hooks/handle-and-actions.md +3 -1
  113. package/skills/hooks/navigation.md +23 -2
  114. package/skills/hooks/state.md +101 -7
  115. package/skills/intercept/SKILL.md +29 -12
  116. package/skills/loader/SKILL.md +197 -44
  117. package/skills/middleware/SKILL.md +34 -9
  118. package/skills/migrate-nextjs/SKILL.md +68 -37
  119. package/skills/migrate-react-router/SKILL.md +2 -1
  120. package/skills/migrate-react-router/component-migration.md +3 -1
  121. package/skills/migrate-react-router/data-and-actions.md +3 -1
  122. package/skills/migrate-react-router/route-mapping.md +7 -4
  123. package/skills/observability/SKILL.md +65 -0
  124. package/skills/parallel/SKILL.md +13 -8
  125. package/skills/ppr/SKILL.md +715 -371
  126. package/skills/prerender/SKILL.md +30 -17
  127. package/skills/rango/SKILL.md +72 -34
  128. package/skills/route/SKILL.md +14 -7
  129. package/skills/router-setup/SKILL.md +4 -2
  130. package/skills/scripts/SKILL.md +8 -1
  131. package/skills/server-actions/SKILL.md +11 -0
  132. package/skills/shell-manifest/SKILL.md +21 -12
  133. package/skills/testing/SKILL.md +49 -43
  134. package/skills/testing/cache-prerender.md +15 -14
  135. package/skills/testing/client-components.md +45 -3
  136. package/skills/testing/loader.md +19 -1
  137. package/skills/testing/middleware.md +1 -0
  138. package/skills/testing/predicates.md +49 -49
  139. package/skills/testing/render-handler.md +1 -0
  140. package/skills/testing/serve-shell-request.md +202 -0
  141. package/skills/testing/server-actions.md +9 -3
  142. package/skills/theme/SKILL.md +56 -4
  143. package/skills/typesafety/env-and-bindings.md +18 -2
  144. package/skills/use-cache/SKILL.md +91 -23
  145. package/skills/vercel/SKILL.md +14 -2
  146. package/skills/view-transitions/SKILL.md +150 -29
  147. package/src/__augment-tests__/augmented.check.ts +23 -0
  148. package/src/browser/cookie-name.ts +23 -0
  149. package/src/browser/event-controller.ts +4 -4
  150. package/src/browser/history-state.ts +75 -1
  151. package/src/browser/link-interceptor.ts +4 -0
  152. package/src/browser/navigation-bridge.ts +77 -18
  153. package/src/browser/navigation-client.ts +4 -3
  154. package/src/browser/navigation-store.ts +43 -1
  155. package/src/browser/navigation-transaction.ts +31 -11
  156. package/src/browser/partial-update.ts +146 -35
  157. package/src/browser/prefetch/cache.ts +6 -6
  158. package/src/browser/prefetch/fetch.ts +2 -2
  159. package/src/browser/react/Link.tsx +38 -33
  160. package/src/browser/react/NavigationProvider.tsx +2 -2
  161. package/src/browser/react/context.ts +2 -2
  162. package/src/browser/react/location-state-shared.ts +241 -49
  163. package/src/browser/react/location-state.ts +5 -2
  164. package/src/browser/rsc-router.tsx +9 -0
  165. package/src/browser/server-action-bridge.ts +84 -15
  166. package/src/browser/transition-when.ts +205 -0
  167. package/src/browser/types.ts +124 -10
  168. package/src/build/generate-manifest.ts +77 -1
  169. package/src/cache/background-task.ts +55 -2
  170. package/src/cache/cache-exec-scope.ts +48 -1
  171. package/src/cache/cache-key-utils.ts +62 -2
  172. package/src/cache/cache-policy.ts +31 -4
  173. package/src/cache/cache-runtime.ts +209 -129
  174. package/src/cache/cache-scope.ts +573 -69
  175. package/src/cache/cache-tag.ts +475 -19
  176. package/src/cache/cf/cf-base64.ts +36 -4
  177. package/src/cache/cf/cf-cache-constants.ts +12 -0
  178. package/src/cache/cf/cf-cache-store.ts +1094 -376
  179. package/src/cache/cf/cf-cache-types.ts +32 -4
  180. package/src/cache/cf/cf-shell-frame.ts +258 -0
  181. package/src/cache/cf/cf-tag-marker-memo.ts +55 -40
  182. package/src/cache/document-cache.ts +53 -7
  183. package/src/cache/handle-snapshot.ts +53 -9
  184. package/src/cache/index.ts +2 -0
  185. package/src/cache/invalidation-order.ts +84 -0
  186. package/src/cache/isolate-tag-memo.ts +308 -0
  187. package/src/cache/request-tag-mask.ts +147 -0
  188. package/src/cache/shell-memo.ts +341 -0
  189. package/src/cache/shell-snapshot.ts +249 -277
  190. package/src/cache/tag-invalidation.ts +109 -18
  191. package/src/cache/types.ts +274 -102
  192. package/src/cache/vercel/vercel-cache-store.ts +561 -74
  193. package/src/client-urls/client-root.tsx +8 -4
  194. package/src/client-urls/client-urls.ts +8 -6
  195. package/src/client-urls/navigation.ts +55 -4
  196. package/src/client-urls/server-projection.ts +31 -10
  197. package/src/client-urls/types.ts +12 -5
  198. package/src/client.tsx +2 -0
  199. package/src/host/cookie-handler.ts +2 -1
  200. package/src/index.rsc.ts +3 -0
  201. package/src/index.ts +3 -0
  202. package/src/loader-redirect.tsx +7 -3
  203. package/src/prerender/build-shell-capture.ts +173 -110
  204. package/src/route-definition/dsl-helpers.ts +6 -3
  205. package/src/route-definition/helpers-types.ts +11 -11
  206. package/src/route-name.ts +12 -0
  207. package/src/router/content-negotiation.ts +4 -1
  208. package/src/router/error-handling.ts +5 -2
  209. package/src/router/handler-context.ts +42 -5
  210. package/src/router/instrument.ts +54 -2
  211. package/src/router/intercept-resolution.ts +30 -8
  212. package/src/router/loader-resolution.ts +89 -33
  213. package/src/router/logging.ts +5 -3
  214. package/src/router/match-api.ts +89 -42
  215. package/src/router/match-context.ts +5 -0
  216. package/src/router/match-handlers.ts +14 -29
  217. package/src/router/match-middleware/background-revalidation.ts +3 -5
  218. package/src/router/match-middleware/cache-lookup.ts +52 -19
  219. package/src/router/match-middleware/cache-store.ts +36 -10
  220. package/src/router/match-result.ts +1 -0
  221. package/src/router/middleware-types.ts +6 -1
  222. package/src/router/middleware.ts +20 -4
  223. package/src/router/navigation-snapshot.ts +6 -5
  224. package/src/router/prerender-match.ts +10 -0
  225. package/src/router/request-classification.ts +7 -4
  226. package/src/router/router-options.ts +4 -1
  227. package/src/router/segment-resolution/fresh.ts +18 -13
  228. package/src/router/segment-resolution/helpers.ts +4 -2
  229. package/src/router/segment-resolution/loader-cache.ts +366 -70
  230. package/src/router/segment-resolution/loader-mask.ts +3 -4
  231. package/src/router/segment-resolution/loader-snapshot.ts +215 -126
  232. package/src/router/segment-resolution/mask-nested.ts +161 -42
  233. package/src/router/segment-resolution/revalidation.ts +27 -13
  234. package/src/router/segment-resolution/view-transition-default.ts +6 -21
  235. package/src/router/telemetry.ts +6 -3
  236. package/src/router/transition-when.ts +34 -52
  237. package/src/router.ts +2 -1
  238. package/src/rsc/attach-transition-when.ts +47 -0
  239. package/src/rsc/full-payload.ts +47 -3
  240. package/src/rsc/handler.ts +24 -10
  241. package/src/rsc/loader-fetch.ts +2 -1
  242. package/src/rsc/manifest-init.ts +4 -0
  243. package/src/rsc/origin-guard.ts +8 -5
  244. package/src/rsc/progressive-enhancement.ts +10 -32
  245. package/src/rsc/response-cache-serve.ts +69 -78
  246. package/src/rsc/response-route-handler.ts +2 -2
  247. package/src/rsc/rsc-rendering.ts +712 -338
  248. package/src/rsc/server-action.ts +8 -20
  249. package/src/rsc/shell-build-manifest.ts +49 -29
  250. package/src/rsc/shell-capture-constants.ts +182 -12
  251. package/src/rsc/shell-capture.ts +1126 -612
  252. package/src/rsc/shell-serve.ts +331 -85
  253. package/src/rsc/ssr-setup.ts +3 -2
  254. package/src/rsc/types.ts +9 -0
  255. package/src/segment-system.tsx +40 -7
  256. package/src/server/context.ts +328 -72
  257. package/src/server/cookie-store.ts +184 -133
  258. package/src/server/handle-store.ts +245 -27
  259. package/src/server/request-context.ts +364 -100
  260. package/src/server/request-headers.ts +134 -0
  261. package/src/server.ts +4 -0
  262. package/src/ssr/index.tsx +96 -37
  263. package/src/ssr/ssr-root.tsx +9 -8
  264. package/src/testing/dispatch.ts +4 -7
  265. package/src/testing/e2e/index.ts +1 -0
  266. package/src/testing/flight.entry.ts +14 -0
  267. package/src/testing/index.ts +5 -0
  268. package/src/testing/internal/action-id.ts +25 -0
  269. package/src/testing/internal/context.ts +1 -1
  270. package/src/testing/location-state-key.ts +45 -0
  271. package/src/testing/render-handler.ts +1 -1
  272. package/src/testing/render-route.tsx +109 -16
  273. package/src/testing/run-client-revalidate.ts +3 -19
  274. package/src/testing/run-loader.ts +67 -5
  275. package/src/testing/run-transition-when.ts +109 -172
  276. package/src/testing/serve-shell-request.ts +381 -0
  277. package/src/testing/shell-status.ts +73 -47
  278. package/src/theme/ThemeProvider.tsx +7 -6
  279. package/src/transition-when-ref.ts +220 -0
  280. package/src/types/cache-types.ts +15 -3
  281. package/src/types/handler-context.ts +14 -1
  282. package/src/types/index.ts +3 -0
  283. package/src/types/segments.ts +94 -91
  284. package/src/urls/path-helper-types.ts +3 -4
  285. package/src/urls/pattern-types.ts +21 -18
  286. package/src/vite/discovery/discover-routers.ts +3 -0
  287. package/src/vite/discovery/shell-prerender-phase.ts +9 -2
  288. package/src/vite/discovery/virtual-module-codegen.ts +16 -6
  289. package/src/vite/plugins/transition-when-hoist.ts +1064 -0
  290. package/src/vite/rango.ts +2 -0
  291. package/src/vite/router-discovery.ts +89 -9
  292. package/dist/types/rsc/transition-gate.d.ts +0 -23
  293. package/src/rsc/transition-gate.ts +0 -86
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { ErrorInfo, NotFoundInfo } from "./boundaries.js";
3
- import type { RevalidateParams, HandlerContext } from "./handler-context.js";
3
+ import type { IsActionFn } from "./handler-context.js";
4
+ import type { DefaultRouteName } from "./global-namespace.js";
4
5
  /**
5
6
  * CSS class(es) for a ViewTransition phase.
6
7
  * Can be a simple string or an object mapping transition types to class names
@@ -8,75 +9,88 @@ import type { RevalidateParams, HandlerContext } from "./handler-context.js";
8
9
  */
9
10
  export type ViewTransitionClass = Record<string, string> | string;
10
11
  /**
11
- * The context a transition({ when }) predicate receives.
12
- *
13
- * It mirrors the {@link ShouldRevalidateFn} args a `revalidate()` predicate
14
- * gets — the same navigation/action metadata — so the two read the same shape,
15
- * plus `get`/`env` for request-context reads. There is no full `HandlerContext`
16
- * here: the gate runs at the RSC-payload layer with the request context, not a
17
- * handler context, so handler-only sugar (`search`/`build`/`dev`/`headers`) is
18
- * absent by design. On ordinary routes, `get` can read what handlers or
19
- * middleware set via `ctx.set(...)`. On `ppr` routes the gate runs before route
20
- * handlers, so only middleware-established values are available.
21
- *
22
- * Field availability (all source fields are optional — never fabricated):
23
- * - `currentUrl` / `currentParams` / `fromRouteName` (the navigation SOURCE) are
24
- * populated on soft navigations and action-success revalidations. They are
25
- * undefined on an initial full document load and on action-error / no-JS error
26
- * paths that skip the navigation snapshot — there is no prior page to name.
27
- * - `nextUrl` / `nextParams` / `get` / `env` / `method` are always present;
28
- * `toRouteName` is present only when the target route is named (undefined for
29
- * unnamed/auto-generated routes, like `fromRouteName`).
30
- * - `actionId` / `actionUrl` / `actionResult` / `formData` are populated only
31
- * when a server action triggered the render; `method` is "POST" then, "GET"
32
- * otherwise. On no-JS (progressive-enhancement) action paths `actionId` may be
33
- * undefined when React cannot surface the action's stable id: the success
34
- * re-render still sets `actionUrl`/`formData` for a recognized action, but the
35
- * error-boundary re-render exposes `actionUrl` only when `actionId` resolved.
36
- * Malformed form bodies that fail before action detection expose no action
37
- * fields. Treat `actionId` as "the action, if known", not as "was this an
38
- * action".
39
- *
40
- * PREFETCH / CACHE CAVEAT (read this before gating on the source): the gate runs
41
- * server-side during resolution. A PREFETCHED navigation renders at prefetch
42
- * time, so `currentUrl`/`currentParams`/`fromRouteName` reflect the page the
43
- * prefetch fired from, NOT necessarily the page the user actually navigates from
44
- * — the decision is baked into the stored Flight payload and replayed verbatim.
45
- * A non-PPR `cache()`/prerender hit replays the stored transition with the
46
- * predicate NOT re-run. A `ppr` route instead evaluates the predicate before
47
- * handlers on every match, including cache, prerender, and PPR replay. Prefetch
48
- * still freezes the server decision into its Flight payload. If the gate must
49
- * reflect the exact click-time source, source-scope the prefetch
50
- * (`<Link prefetchKey=":source">`).
12
+ * One side of a navigation as the browser knows it when a
13
+ * `transition({ when })` predicate runs.
51
14
  */
52
- export type TransitionWhenContext<TParams = Record<string, string>, TEnv = unknown> = Partial<Pick<RevalidateParams<TParams, TEnv>, "currentUrl" | "currentParams" | "fromRouteName">> & Pick<RevalidateParams<TParams, TEnv>, "nextUrl" | "nextParams" | "toRouteName" | "actionId" | "actionUrl" | "actionResult" | "formData" | "method"> & Pick<HandlerContext<any, TEnv>, "get" | "env">;
15
+ export interface RouteLocation {
16
+ readonly url: URL;
17
+ /** Merged route params of the location. */
18
+ readonly params: Readonly<Record<string, string>>;
19
+ /**
20
+ * The matched route's name (include prefixes applied), typed from the
21
+ * generated route map; undefined for an unnamed route or when unknown.
22
+ * Internal names never appear here.
23
+ */
24
+ readonly routeName: DefaultRouteName | undefined;
25
+ /**
26
+ * `history.state` of this entry at decision time. Read a typed slot with
27
+ * `Def.read(location)` (a `createLocationState()` definition).
28
+ */
29
+ readonly state: unknown;
30
+ }
53
31
  /**
54
- * Predicate that gates whether a transition() applies for the current request.
32
+ * A navigation side as the server sees it, for intercept's `when` selector:
33
+ * a {@link RouteLocation} without `state` (history state never reaches the
34
+ * server).
35
+ */
36
+ export type ServerRouteLocation = Omit<RouteLocation, "state">;
37
+ /**
38
+ * How the navigation being decided was started.
55
39
  *
56
- * Evaluated server-side outside any cache scope. On ordinary routes it runs
57
- * AFTER the route's handler, so `get(...)` can read handler/middleware state. A
58
- * route with `ppr` automatically hoists it before route handlers and reevaluates
59
- * it on every cache/prerender/PPR replay; there `get(...)` can read middleware
60
- * state, but not values set by route handlers. Return false to drop this
61
- * segment's transition for the request; return true to apply it. The
62
- * context ({@link TransitionWhenContext}) carries the same navigation/action
63
- * metadata a `revalidate()` predicate sees plus `get`/`env`. If it throws, the
64
- * error is reported to the router's onError (phase "rendering") and the
65
- * transition is dropped (the navigation does not hold).
40
+ * - `"push"` / `"replace"`: a Link click, `router.push()` / `router.replace()`
41
+ * or `navigate()`.
42
+ * - `"pop"`: browser back/forward (restored from the history cache or
43
+ * refetched).
44
+ * - `"action"`: the commit that applies a server action's revalidation,
45
+ * including the error-boundary commit of a failed action.
46
+ * - `"revalidate"`: a re-render of the current URL: `router.refresh()`,
47
+ * cross-tab invalidation, or the background revalidation of a stale entry.
48
+ */
49
+ export type TransitionWhenKind = "push" | "replace" | "pop" | "action" | "revalidate";
50
+ /**
51
+ * The context a `transition({ when })` predicate receives. The predicate runs
52
+ * in the BROWSER, once per navigation, at the first commit that presents the
53
+ * destination. The server never calls it.
66
54
  *
67
- * Distinct from intercept()'s `when` config selector, which runs at MATCH time
68
- * over `{ from, to, params, segments, … }`.
55
+ * - `from`: the committed location being left.
56
+ * - `to`: the destination. The same object as `from` for `"action"` and
57
+ * `"revalidate"`.
58
+ * - `isAction`: the matcher `revalidate()` predicates get; `false` off an
59
+ * action.
60
+ * - `action`: present only for `kind: "action"`.
61
+ */
62
+ export interface TransitionWhenContext {
63
+ readonly kind: TransitionWhenKind;
64
+ readonly from: RouteLocation;
65
+ readonly to: RouteLocation;
66
+ readonly isAction: IsActionFn;
67
+ /** Present only for `kind: "action"`. */
68
+ readonly action?: {
69
+ /** The action's hashed `$$id` in the browser; match with `isAction(fn)` instead. */
70
+ readonly id: string | undefined;
71
+ /** The FormData argument the action received (the 2nd argument under `useActionState`). */
72
+ readonly formData: FormData | undefined;
73
+ /** The action's return value on success. */
74
+ readonly result: unknown;
75
+ /** What a failed action threw (its error-boundary commit); `result` is undefined then. */
76
+ readonly error: unknown;
77
+ };
78
+ }
79
+ /**
80
+ * Browser-run predicate that gates whether a navigation holds and animates.
69
81
  *
70
- * Scope: dropping a transition removes only THIS segment's contribution to the
71
- * navigation's hold. The startTransition hold is navigation-wide — it engages if
72
- * any matched segment still has a transition — so `when: false` makes the
73
- * navigation stream its loading fallback only when no other matched segment
74
- * keeps a transition (the common case: a single transition on the route).
82
+ * In `urls()` write it inline (`transition({ when: (ctx) => ... })`, which
83
+ * the build hoists into a client module; it may reference only its own
84
+ * bindings, globals and client-safe imports) or export it from a
85
+ * `"use client"` module and import it; in `clientUrls()` it is an inline
86
+ * function. Anything else (a server function, a non-function) fails route
87
+ * discovery.
75
88
  *
76
- * On non-PPR routes it runs only during fresh resolution. On PPR routes it runs
77
- * before handlers for every match, including runtime cache, build-time
78
- * prerender, and PPR segment replay. A prefetched navigation still freezes the
79
- * result to prefetch time; see {@link TransitionWhenContext}.
89
+ * `false` makes the navigation an urgent commit: no hold, no view transition,
90
+ * and a same-route navigation streams its `loading()` fallback. The segment
91
+ * keeps its key and its `<ViewTransition>` element (every class "none"), so
92
+ * nothing remounts. One predicate returning false decides for the whole
93
+ * navigation. A throw is logged with `console.error` and counts as `false`.
80
94
  */
81
95
  export type TransitionWhenFn = (ctx: TransitionWhenContext) => boolean;
82
96
  /**
@@ -108,13 +122,8 @@ export interface TransitionConfig {
108
122
  */
109
123
  viewTransition?: "auto" | false;
110
124
  /**
111
- * Optional server-side predicate that gates this transition per request. When
112
- * present and it returns false, the router drops this segment's transition for
113
- * the request, so the navigation streams its loading fallback instead of
114
- * holding. PPR routes evaluate it before route handlers and on every replay;
115
- * other routes evaluate it after handlers on fresh resolution. The predicate
116
- * is server-only and never serialized to the client; only its resolved effect
117
- * crosses. See {@link TransitionWhenFn}.
125
+ * Optional browser-run predicate that gates this transition per
126
+ * navigation. See {@link TransitionWhenFn}.
118
127
  */
119
128
  when?: TransitionWhenFn;
120
129
  }
@@ -248,6 +257,12 @@ export interface MatchResult {
248
257
  * decline its optimistic presentation for targets an intercept would claim.
249
258
  */
250
259
  interceptTargets?: string[];
260
+ /**
261
+ * Set on a partial match when an intercept targets the matched route,
262
+ * whether or not it applied from this source. The response depends on the
263
+ * source, so the RSC handler scopes its prefetch entry to it (#1007).
264
+ */
265
+ interceptTargeted?: true;
251
266
  /**
252
267
  * Redirect URL for trailing slash normalization.
253
268
  * When set, the RSC handler should return a 308 redirect to this URL
@@ -194,10 +194,9 @@ export type PathHelpers<TEnv> = {
194
194
  * transition cannot fire without a startTransition. See
195
195
  * skills/view-transitions for the startTransition x ViewTransition matrix.
196
196
  *
197
- * Pass `when: (ctx) => boolean` to gate the transition per request. It normally
198
- * runs after the route handler; `ppr` routes automatically run it before route
199
- * handlers and on every replay, where `ctx.get(...)` sees middleware state but
200
- * not handler-set values.
197
+ * Pass `when` (inline, hoisted into a client module by the build, or a
198
+ * "use client" export) to gate the navigation's hold and view transition in
199
+ * the browser (never on the server); see TransitionWhenFn.
201
200
  */
202
201
  transition: {
203
202
  (): TransitionItem;
@@ -53,30 +53,33 @@ export interface PartialPrerenderProps {
53
53
  /**
54
54
  * Operational tags attached to the captured shell entry for
55
55
  * `updateTag()`/`revalidateTag()`-driven eviction. UNIONED with the tags the
56
- * capture render auto-collects (the shell's own non-loader request tags).
56
+ * capture collects: its doc record's tags (what the handler layer and the
57
+ * server components it rendered recorded) and its bake-lane loaders'.
57
58
  */
58
59
  tags?: string[];
59
60
  /**
60
- * Upper bound (serialized UTF-8 bytes) on the capture data snapshot riding
61
- * inside the shell entry. The snapshot duplicates every cache-store value
62
- * the capture pinned, so a page over a large cache() segment can push the
63
- * entry toward store value limits (Cloudflare KV caps a value at 25 MiB).
64
- * Over the cap the snapshot is skipped: the shell is still stored and
65
- * served, but pinned reads fall back to the live store, so drifted cached
66
- * content can hydration-mismatch and be repaired client-side (the
67
- * pre-snapshot behavior). Reported once per key. Defaults to 8 MiB.
61
+ * Upper bound (serialized UTF-8 bytes) on the loader pins in the capture
62
+ * data snapshot: the bake-lane loader records. The doc record (the handler
63
+ * layer every HIT replays) is exempt. Over the cap the pins are dropped: the
64
+ * shell is still stored and every HIT still replays the handler layer, but the
65
+ * pinned loaders read the live store, so drifted cached content can
66
+ * hydration-mismatch and be repaired client-side. Reported once per key.
67
+ * Defaults to 8 MiB. The whole entry is bounded separately by the store's
68
+ * value limit (Cloudflare KV: 25 MiB); an entry over it is refused.
68
69
  */
69
70
  maxSnapshotBytes?: number;
70
71
  /**
71
- * Capture settle budget in MILLISECONDS (default 15000). Bounds the whole
72
- * background capture: the wait for deferred shell material — top-level
73
- * pushed handle promises (`ctx.use(Meta)(promise.then(...))` and friends)
74
- * are AWAITED and their settled values baked into the stored shell — AND
75
- * the fizz prerender deadline. Declare it to tighten the budget below the
76
- * default or when a route's shell material takes longer than 15s to
77
- * settle. A budget that expires with pushes still pending REFUSES the
78
- * capture (the route stays MISS with the once-per-key warning) — a shell
79
- * with missing head material is never stored. Capture is background work
72
+ * Capture settle budget in MILLISECONDS (default 15000). One deadline for
73
+ * the whole background capture: the match (the handlers, and the loaders
74
+ * they await), the wait for handler output (handle pushes and the promises
75
+ * nested in them, bake-lane loaders, and the doc record's encode, which
76
+ * awaits handler promises and async server components), AND the fizz
77
+ * prerender. Everything a handler produces is
78
+ * awaited and baked into the stored shell. Declare it to tighten the
79
+ * budget below the default or when a route's shell material takes longer
80
+ * than 15s to settle. A budget that expires before the doc record is
81
+ * written REFUSES the capture (the route stays MISS with the once-per-key
82
+ * warning): a shell with missing handler output is never stored. Capture is background work
80
83
  * (waitUntil), so a longer budget costs latency-to-HIT only, never a served
81
84
  * response; the platform waitUntil lifetime (workerd: ~30s past response
82
85
  * completion) is the physical ceiling — the default's derivation lives in
@@ -0,0 +1,45 @@
1
+ import type { Plugin } from "vite";
2
+ import MagicString from "magic-string";
3
+ /** Specifiers that can never load in the browser. */
4
+ export declare function isServerOnlySpecifier(source: string): boolean;
5
+ export interface HoistTransitionWhenDeps {
6
+ /**
7
+ * Whether an import the literal re-emits is server-only beyond its
8
+ * specifier (the plugin resolves it and looks for `import "server-only"`).
9
+ */
10
+ isServerOnlyImport?(source: string): Promise<boolean> | boolean;
11
+ }
12
+ export interface HoistTransitionWhenResult {
13
+ readonly code: string;
14
+ readonly map: ReturnType<MagicString["generateMap"]>;
15
+ /** Virtual module source per hoisted literal, by index. */
16
+ readonly modules: readonly string[];
17
+ }
18
+ /**
19
+ * Hoist every inline `transition({ when: <function literal> })` of a urls
20
+ * module. Returns null when there is nothing to hoist. Throws a
21
+ * TransitionWhenError for a capture, a server-only import or module-loading
22
+ * expression, an accessor `when`, or a local identifier value.
23
+ */
24
+ export declare function hoistTransitionWhens(code: string, id: string, deps?: HoistTransitionWhenDeps): Promise<HoistTransitionWhenResult | null>;
25
+ /** The hoisted module index a `?rango-when=N` id names, or null. */
26
+ export declare function parseHoistedWhenId(id: string): {
27
+ file: string;
28
+ index: number;
29
+ } | null;
30
+ /**
31
+ * The plugin: hoists in the RSC environment (where urls() modules are
32
+ * evaluated) and serves the `?rango-when=N` modules in every environment
33
+ * (RSC, SSR and client all load them).
34
+ *
35
+ * `load` serves the modules the transform emitted, not a re-hoist of the file
36
+ * on disk: the transform hoists the pipeline code, which an earlier plugin
37
+ * may have changed, so re-hoisting the disk source can number the literals
38
+ * differently and serve the wrong one for index N. The disk source is the
39
+ * fallback only when the transform has not seen the current file: an
40
+ * environment loading before the RSC transform ran (the order environments
41
+ * ask in is not fixed), or an edit the RSC environment has not re-transformed
42
+ * yet (serving the last transform would then be stale). The map is per
43
+ * plugin instance, so every environment of one dev server or build shares it.
44
+ */
45
+ export declare function transitionWhenHoistPlugin(): Plugin;
@@ -5,9 +5,36 @@
5
5
  * environment. Delegates to extracted modules for discovery, route types
6
6
  * generation, virtual module codegen, and bundle post-processing.
7
7
  */
8
- import type { Plugin } from "vite";
9
- import { VIRTUAL_ROUTES_MANIFEST_ID, type PluginOptions } from "./discovery/state.js";
8
+ import type { Plugin, ViteDevServer } from "vite";
9
+ import { VIRTUAL_ROUTES_MANIFEST_ID, type DiscoveryState, type PluginOptions } from "./discovery/state.js";
10
10
  export { VIRTUAL_ROUTES_MANIFEST_ID };
11
+ /**
12
+ * Create a minimal Vite server for router discovery.
13
+ *
14
+ * Both dev-mode prerender and build-mode discovery need a temp RSC server
15
+ * to import user router files via module runner. This factory centralizes
16
+ * the shared config and the mode-specific differences:
17
+ * - Dev: path-based IDs (no forceBuild), separate cacheDir
18
+ * - Build: hashed IDs (forceBuild), hashClientRefs for production bundles
19
+ *
20
+ * Returns the ViteDevServer instance. Callers access .environments.rsc as needed.
21
+ * @internal Exported for tests.
22
+ */
23
+ export declare function createTempRscServer(state: DiscoveryState, options?: {
24
+ forceBuild?: boolean;
25
+ cacheDir?: string;
26
+ /**
27
+ * Serve the REAL rango SSR entry (getVirtualEntrySSR) for
28
+ * "virtual:entry-ssr" instead of the discovery stub, so the dev
29
+ * /__rsc_shell endpoint can drive captureShellHTML in this server's SSR
30
+ * realm. Dev-correct by construction: the entry's bootstrap resolves to
31
+ * plugin-rsc's stable virtual browser-entry URL, which the MAIN dev
32
+ * server serves to the browser. Loaded lazily — discovery never imports
33
+ * the SSR entry, so the temp server stays as light as before until a
34
+ * shell capture actually runs.
35
+ */
36
+ realSsrEntry?: boolean;
37
+ }): Promise<ViteDevServer>;
11
38
  /**
12
39
  * Plugin that discovers router instances at dev/build time via the RSC environment.
13
40
  *