@rangojs/router 0.24.4 → 0.25.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 (267) hide show
  1. package/README.md +1 -0
  2. package/dist/bin/rango.js +363 -39
  3. package/dist/testing/vitest.js +37 -4
  4. package/dist/types/browser/event-controller.d.ts +24 -5
  5. package/dist/types/browser/intercept-utils.d.ts +5 -2
  6. package/dist/types/browser/merge-segment-loaders.d.ts +0 -23
  7. package/dist/types/browser/navigation-transaction.d.ts +5 -5
  8. package/dist/types/browser/partial-update.d.ts +21 -13
  9. package/dist/types/browser/prefetch/cache.d.ts +8 -0
  10. package/dist/types/browser/rango-marker.d.ts +7 -0
  11. package/dist/types/browser/react/filter-segment-order.d.ts +10 -0
  12. package/dist/types/browser/react/use-handle.d.ts +20 -0
  13. package/dist/types/browser/react/use-href.d.ts +6 -0
  14. package/dist/types/browser/react/use-router.d.ts +6 -1
  15. package/dist/types/browser/response-adapter.d.ts +5 -3
  16. package/dist/types/browser/scroll-restoration.d.ts +9 -3
  17. package/dist/types/browser/segment-reconciler.d.ts +10 -13
  18. package/dist/types/browser/types.d.ts +38 -8
  19. package/dist/types/build/route-types/per-module-writer.d.ts +12 -0
  20. package/dist/types/cache/cf/cf-shell-frame.d.ts +2 -0
  21. package/dist/types/cache/types.d.ts +8 -0
  22. package/dist/types/client-urls/client-urls.d.ts +6 -2
  23. package/dist/types/client-urls/revalidate-registry.d.ts +1 -1
  24. package/dist/types/client-urls/server-projection.d.ts +9 -5
  25. package/dist/types/client-urls/types.d.ts +29 -16
  26. package/dist/types/client.d.ts +2 -2
  27. package/dist/types/client.rsc.d.ts +2 -2
  28. package/dist/types/decode-loader-results.d.ts +28 -7
  29. package/dist/types/href-client.d.ts +3 -1
  30. package/dist/types/index.rsc.d.ts +1 -1
  31. package/dist/types/loader-redirect.d.ts +2 -3
  32. package/dist/types/outlet-context.d.ts +7 -6
  33. package/dist/types/prefetch-markers.d.ts +14 -5
  34. package/dist/types/route-content-wrapper.d.ts +17 -14
  35. package/dist/types/route-definition/helpers-types.d.ts +7 -2
  36. package/dist/types/route-definition/resolve-handler-use.d.ts +6 -1
  37. package/dist/types/route-definition/rewrite.d.ts +48 -5
  38. package/dist/types/route-types.d.ts +2 -2
  39. package/dist/types/router/handler-context.d.ts +14 -2
  40. package/dist/types/router/intercept-resolution.d.ts +19 -46
  41. package/dist/types/router/lazy-includes.d.ts +7 -0
  42. package/dist/types/router/match-middleware/intercept-resolution.d.ts +2 -2
  43. package/dist/types/router/middleware.d.ts +0 -16
  44. package/dist/types/router/navigation-snapshot.d.ts +2 -0
  45. package/dist/types/router/prefetch-cache-ttl.d.ts +8 -11
  46. package/dist/types/router/revalidation.d.ts +8 -1
  47. package/dist/types/router/router-context.d.ts +4 -16
  48. package/dist/types/router/router-interfaces.d.ts +0 -6
  49. package/dist/types/router/router-options.d.ts +4 -7
  50. package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +31 -8
  51. package/dist/types/router/segment-resolution/revalidation.d.ts +38 -4
  52. package/dist/types/router/segment-resolution.d.ts +1 -1
  53. package/dist/types/router/segment-wrappers.d.ts +3 -5
  54. package/dist/types/router/substitute-pattern-params.d.ts +3 -2
  55. package/dist/types/router/tracing.d.ts +2 -2
  56. package/dist/types/rsc/full-payload.d.ts +14 -2
  57. package/dist/types/rsc/helpers.d.ts +8 -0
  58. package/dist/types/rsc/manifest-init.d.ts +20 -0
  59. package/dist/types/rsc/prefetch-render-error.d.ts +22 -0
  60. package/dist/types/rsc/progressive-enhancement.d.ts +20 -0
  61. package/dist/types/rsc/rewrite-passes.d.ts +12 -2
  62. package/dist/types/rsc/server-action.d.ts +6 -0
  63. package/dist/types/rsc/shell-capture-constants.d.ts +10 -1
  64. package/dist/types/rsc/shell-capture.d.ts +7 -0
  65. package/dist/types/rsc/types.d.ts +5 -0
  66. package/dist/types/segment-system.d.ts +15 -0
  67. package/dist/types/server/context.d.ts +64 -4
  68. package/dist/types/server/request-context.d.ts +41 -4
  69. package/dist/types/server/request-headers.d.ts +12 -0
  70. package/dist/types/server/rewrite-trail.d.ts +8 -1
  71. package/dist/types/testing/e2e/index.d.ts +1 -1
  72. package/dist/types/testing/flight.entry.d.ts +1 -1
  73. package/dist/types/testing/index.d.ts +1 -1
  74. package/dist/types/testing/internal/client-urls-projection.d.ts +4 -3
  75. package/dist/types/testing/render-route.d.ts +21 -11
  76. package/dist/types/testing/run-loader.d.ts +7 -0
  77. package/dist/types/testing/run-middleware.d.ts +7 -0
  78. package/dist/types/testing/run-revalidate.d.ts +5 -4
  79. package/dist/types/testing/serve-shell-request.d.ts +41 -4
  80. package/dist/types/testing/shell-status.d.ts +17 -0
  81. package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
  82. package/dist/types/testing/vitest.d.ts +10 -1
  83. package/dist/types/thenable-status.d.ts +0 -6
  84. package/dist/types/types/handler-context.d.ts +12 -1
  85. package/dist/types/types/loader-types.d.ts +4 -3
  86. package/dist/types/types/route-entry.d.ts +2 -1
  87. package/dist/types/urls/path-helper-types.d.ts +4 -2
  88. package/dist/types/vite/discovery/client-urls-projection.d.ts +55 -5
  89. package/dist/types/vite/discovery/state.d.ts +20 -0
  90. package/dist/types/vite/plugins/client-urls-revalidate-hoist.d.ts +28 -16
  91. package/dist/types/vite/plugins/hoist/source.d.ts +8 -7
  92. package/dist/types/vite/plugins/virtual-entries.d.ts +6 -0
  93. package/dist/types/vite/utils/prerender-utils.d.ts +7 -0
  94. package/dist/vite/index.js +6816 -6547
  95. package/package.json +1 -1
  96. package/skills/app-structure/SKILL.md +255 -0
  97. package/skills/app-structure/content-site.md +333 -0
  98. package/skills/app-structure/e-commerce.md +435 -0
  99. package/skills/app-structure/large-app.md +885 -0
  100. package/skills/app-structure/multi-app.md +280 -0
  101. package/skills/breadcrumbs/SKILL.md +6 -1
  102. package/skills/caching/SKILL.md +3 -1
  103. package/skills/catalog.json +12 -0
  104. package/skills/client-urls/SKILL.md +185 -32
  105. package/skills/composability/SKILL.md +10 -8
  106. package/skills/handler-use/SKILL.md +48 -9
  107. package/skills/hooks/handle-and-actions.md +104 -0
  108. package/skills/hooks/navigation.md +24 -10
  109. package/skills/hooks/urls.md +1 -1
  110. package/skills/i18n/SKILL.md +2 -1
  111. package/skills/intercept/SKILL.md +60 -29
  112. package/skills/layout/SKILL.md +6 -3
  113. package/skills/links/SKILL.md +151 -17
  114. package/skills/loader/SKILL.md +32 -10
  115. package/skills/middleware/SKILL.md +111 -15
  116. package/skills/observability/SKILL.md +11 -0
  117. package/skills/parallel/SKILL.md +5 -5
  118. package/skills/ppr/SKILL.md +43 -8
  119. package/skills/prerender/SKILL.md +1 -2
  120. package/skills/rango/SKILL.md +3 -0
  121. package/skills/response-routes/SKILL.md +4 -1
  122. package/skills/scripts/SKILL.md +12 -1
  123. package/skills/server-actions/SKILL.md +60 -20
  124. package/skills/testing/SKILL.md +1 -0
  125. package/skills/testing/client-components.md +13 -10
  126. package/skills/testing/loader.md +25 -24
  127. package/skills/testing/middleware.md +11 -11
  128. package/skills/testing/response-routes.md +4 -1
  129. package/skills/testing/serve-shell-request.md +85 -21
  130. package/skills/ux-architecture/SKILL.md +980 -0
  131. package/skills/view-transitions/SKILL.md +43 -10
  132. package/src/__augment-tests__/augmented.check.ts +28 -0
  133. package/src/browser/event-controller.ts +44 -18
  134. package/src/browser/intercept-utils.ts +3 -2
  135. package/src/browser/merge-segment-loaders.ts +0 -85
  136. package/src/browser/navigation-bridge.ts +112 -84
  137. package/src/browser/navigation-client.ts +20 -15
  138. package/src/browser/navigation-store.ts +4 -2
  139. package/src/browser/navigation-transaction.ts +9 -8
  140. package/src/browser/partial-update.ts +90 -32
  141. package/src/browser/prefetch/cache.ts +8 -0
  142. package/src/browser/prefetch/fetch.ts +13 -3
  143. package/src/browser/rango-marker.ts +13 -0
  144. package/src/browser/react/NavigationProvider.tsx +25 -7
  145. package/src/browser/react/filter-segment-order.ts +13 -0
  146. package/src/browser/react/use-action.ts +9 -15
  147. package/src/browser/react/use-handle.ts +63 -71
  148. package/src/browser/react/use-href.tsx +24 -5
  149. package/src/browser/react/use-link-status.ts +1 -1
  150. package/src/browser/react/use-navigation.ts +30 -40
  151. package/src/browser/react/use-router.ts +37 -6
  152. package/src/browser/react/use-segments.ts +8 -12
  153. package/src/browser/response-adapter.ts +11 -5
  154. package/src/browser/rsc-router.tsx +3 -1
  155. package/src/browser/scroll-restoration.ts +34 -20
  156. package/src/browser/segment-reconciler.ts +11 -29
  157. package/src/browser/server-action-bridge.ts +52 -16
  158. package/src/browser/types.ts +40 -8
  159. package/src/build/generate-manifest.ts +12 -1
  160. package/src/build/route-types/codegen.ts +6 -2
  161. package/src/build/route-types/per-module-writer.ts +94 -61
  162. package/src/cache/cache-runtime.ts +9 -0
  163. package/src/cache/cache-scope.ts +2 -1
  164. package/src/cache/cf/cf-cache-store.ts +2 -0
  165. package/src/cache/cf/cf-shell-frame.ts +3 -0
  166. package/src/cache/types.ts +8 -0
  167. package/src/cache/vercel/vercel-cache-store.ts +6 -1
  168. package/src/client-urls/client-urls.ts +202 -153
  169. package/src/client-urls/revalidate-registry.ts +12 -3
  170. package/src/client-urls/server-projection.ts +137 -66
  171. package/src/client-urls/types.ts +30 -15
  172. package/src/client.rsc.tsx +11 -1
  173. package/src/client.tsx +9 -1
  174. package/src/decode-loader-results.ts +64 -31
  175. package/src/href-client.ts +3 -1
  176. package/src/index.rsc.ts +1 -0
  177. package/src/index.ts +12 -4
  178. package/src/loader-redirect.tsx +2 -3
  179. package/src/outlet-context.ts +7 -6
  180. package/src/prefetch-markers.ts +15 -5
  181. package/src/reverse.ts +3 -3
  182. package/src/route-content-wrapper.tsx +19 -17
  183. package/src/route-definition/dsl-helpers.ts +27 -7
  184. package/src/route-definition/helpers-types.ts +7 -2
  185. package/src/route-definition/resolve-handler-use.ts +23 -10
  186. package/src/route-definition/rewrite.ts +86 -19
  187. package/src/route-types.ts +1 -2
  188. package/src/router/find-match.ts +37 -1
  189. package/src/router/handler-context.ts +85 -40
  190. package/src/router/intercept-resolution.ts +161 -307
  191. package/src/router/lazy-includes.ts +43 -27
  192. package/src/router/loader-resolution.ts +21 -1
  193. package/src/router/manifest.ts +6 -8
  194. package/src/router/match-api.ts +11 -1
  195. package/src/router/match-middleware/background-revalidation.ts +2 -4
  196. package/src/router/match-middleware/cache-lookup.ts +16 -20
  197. package/src/router/match-middleware/intercept-resolution.ts +41 -60
  198. package/src/router/match-result.ts +31 -2
  199. package/src/router/middleware.ts +6 -147
  200. package/src/router/navigation-snapshot.ts +38 -2
  201. package/src/router/prefetch-cache-ttl.ts +10 -18
  202. package/src/router/prerender-match.ts +2 -1
  203. package/src/router/revalidation.ts +24 -3
  204. package/src/router/router-context.ts +5 -18
  205. package/src/router/router-interfaces.ts +0 -7
  206. package/src/router/router-options.ts +4 -7
  207. package/src/router/segment-resolution/fresh.ts +6 -2
  208. package/src/router/segment-resolution/helpers.ts +7 -1
  209. package/src/router/segment-resolution/prefetch-deferral.ts +62 -12
  210. package/src/router/segment-resolution/revalidation.ts +75 -35
  211. package/src/router/segment-resolution.ts +0 -1
  212. package/src/router/segment-wrappers.ts +8 -13
  213. package/src/router/substitute-pattern-params.ts +3 -2
  214. package/src/router/tracing.ts +2 -2
  215. package/src/router.ts +2 -9
  216. package/src/rsc/full-payload.ts +26 -4
  217. package/src/rsc/handler.ts +83 -41
  218. package/src/rsc/helpers.ts +13 -0
  219. package/src/rsc/manifest-init.ts +56 -3
  220. package/src/rsc/prefetch-render-error.ts +38 -0
  221. package/src/rsc/progressive-enhancement.ts +161 -211
  222. package/src/rsc/rewrite-passes.ts +56 -9
  223. package/src/rsc/rsc-rendering.ts +79 -23
  224. package/src/rsc/server-action.ts +25 -2
  225. package/src/rsc/shell-capture-constants.ts +22 -0
  226. package/src/rsc/shell-capture.ts +11 -0
  227. package/src/rsc/types.ts +5 -0
  228. package/src/segment-system.tsx +125 -119
  229. package/src/server/context.ts +96 -5
  230. package/src/server/handle-store.ts +3 -2
  231. package/src/server/request-context.ts +42 -3
  232. package/src/server/request-headers.ts +32 -0
  233. package/src/server/rewrite-trail.ts +55 -9
  234. package/src/ssr/ssr-root.tsx +6 -10
  235. package/src/testing/dispatch.ts +4 -5
  236. package/src/testing/e2e/index.ts +1 -0
  237. package/src/testing/flight.entry.ts +1 -0
  238. package/src/testing/index.ts +1 -0
  239. package/src/testing/internal/client-urls-projection.ts +31 -11
  240. package/src/testing/render-route.tsx +83 -40
  241. package/src/testing/run-loader.ts +26 -2
  242. package/src/testing/run-middleware.ts +10 -0
  243. package/src/testing/run-revalidate.ts +13 -6
  244. package/src/testing/serve-shell-request.ts +77 -4
  245. package/src/testing/shell-status.ts +40 -0
  246. package/src/testing/vitest-stubs/version.ts +1 -0
  247. package/src/testing/vitest.ts +74 -7
  248. package/src/thenable-status.ts +0 -11
  249. package/src/types/handler-context.ts +12 -1
  250. package/src/types/loader-types.ts +4 -3
  251. package/src/types/route-entry.ts +2 -1
  252. package/src/urls/include-helper.ts +38 -11
  253. package/src/urls/path-helper-types.ts +4 -2
  254. package/src/vite/discovery/client-urls-projection.ts +205 -16
  255. package/src/vite/discovery/discover-routers.ts +2 -2
  256. package/src/vite/discovery/prerender-collection.ts +2 -6
  257. package/src/vite/discovery/state.ts +26 -0
  258. package/src/vite/plugins/client-urls-revalidate-hoist.ts +190 -77
  259. package/src/vite/plugins/expose-internal-ids.ts +46 -40
  260. package/src/vite/plugins/hoist/source.ts +8 -7
  261. package/src/vite/plugins/transition-when-hoist.ts +1 -0
  262. package/src/vite/plugins/version-plugin.ts +7 -0
  263. package/src/vite/plugins/version.d.ts +7 -0
  264. package/src/vite/plugins/virtual-entries.ts +20 -0
  265. package/src/vite/rango.ts +4 -1
  266. package/src/vite/router-discovery.ts +39 -7
  267. package/src/vite/utils/prerender-utils.ts +17 -0
@@ -13,7 +13,7 @@ import { parseCookiesFromHeader } from "./cookie-parse.js";
13
13
  import type { CacheErrorCategory } from "../cache/cache-error.js";
14
14
  import type { CookieOptions } from "../router/middleware.js";
15
15
  import type { LoaderDefinition } from "../types.js";
16
- import type { ScopedReverseFunction } from "../reverse.js";
16
+ import type { AutofillAwareReverseFunction } from "../types/handler-context.js";
17
17
  import type { DefaultEnv, DefaultReverseRouteMap, DefaultRouteName } from "../types/global-namespace.js";
18
18
  import type { Handle } from "../handle.js";
19
19
  import { type ContextVar } from "../context-var.js";
@@ -28,6 +28,8 @@ import type { ResolvedTracing } from "../router/tracing.js";
28
28
  import type { RenderMode, RenderPhase } from "../router/timeout.js";
29
29
  import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
30
30
  import type { RoutineTrace } from "../rsc/routine-plan.js";
31
+ import type { ActionContinuation } from "../rsc/server-action.js";
32
+ import type { FormActionOutcome } from "../rsc/progressive-enhancement.js";
31
33
  import { type ExecutionStart } from "../cache/invalidation-order.js";
32
34
  export interface RenderForegroundCursor {
33
35
  mode: RenderMode;
@@ -243,6 +245,12 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
243
245
  * locally and passes it to scheduleShellCapture directly.
244
246
  */
245
247
  _shellCaptureRun?: boolean;
248
+ /**
249
+ * @internal Set beside `_shellCaptureRun` when the shell is keyed by the
250
+ * visitor's URL (`rewrite(...).shell("visitor")`): the capture renders the
251
+ * visitor's location and `ctx.rewrittenFrom`; the theme stays the default.
252
+ */
253
+ _shellCaptureForVisitor?: boolean;
246
254
  /**
247
255
  * @internal Bake-lane loader containers collected DURING a shell capture:
248
256
  * segment-key -> the loader's (pre-wrap) result promise. Populated by
@@ -635,12 +643,25 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
635
643
  * Generate URLs from route names.
636
644
  * Uses the global route map. After route matching, scoped (`.name`) resolution
637
645
  * works within the matched include() scope.
638
- */
639
- reverse: ScopedReverseFunction<Record<string, string>, DefaultReverseRouteMap>;
646
+ *
647
+ * Params are optional in the type because the fill depends on the phase.
648
+ * After the route match (route middleware, handlers, loaders, server actions)
649
+ * missing params come from the matched route's params; explicit params win.
650
+ * In global middleware before `next()` nothing is matched and the fill is
651
+ * empty, so a route with a required param throws `Missing param "<name>" for
652
+ * route "<route>"` at runtime (a param-less route still resolves).
653
+ */
654
+ reverse: AutofillAwareReverseFunction<Record<string, string>, DefaultReverseRouteMap>;
640
655
  /** @internal Route name from route matching, used for scoped reverse resolution */
641
656
  _routeName?: string;
642
657
  /** @internal Previous route key (from the navigation source), used for revalidation */
643
658
  _prevRouteKey?: string;
659
+ /**
660
+ * @internal Leaving a rewritten page, the visitor's URL moved
661
+ * (router/match-api.ts): the default revalidation counts it as a search
662
+ * change, since the render may read `ctx.rewrittenFrom`.
663
+ */
664
+ _visitorMoved?: boolean;
644
665
  /**
645
666
  * @internal True while the post-action revalidation render is running (set by
646
667
  * revalidateAfterAction). The "use cache" runtime reads this to prefer
@@ -650,6 +671,22 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
650
671
  * revalidating in the background. A plain navigation (flag unset) keeps SWR.
651
672
  */
652
673
  _inActionRevalidation?: boolean;
674
+ /**
675
+ * @internal The outcome of the action this request ran (a JS server
676
+ * action's continuation, a no-JS form post's form state), set before route
677
+ * middleware wraps the re-render. While it is unset, applyRewrite
678
+ * (rsc/rewrite-passes.ts) moves a mutation with its body, so the action
679
+ * runs on the target's pass, or refuses it (`disallowMutations()`, or a
680
+ * body middleware read); once set, the request moves to the target, whose
681
+ * pass re-renders from it instead of running the action again (#1145).
682
+ */
683
+ _actionRan?: {
684
+ kind: "action";
685
+ continuation: ActionContinuation;
686
+ } | {
687
+ kind: "form";
688
+ outcome: FormActionOutcome;
689
+ };
653
690
  /**
654
691
  * @internal Render barrier for experimental `rendered()` API.
655
692
  * Resolves when all non-loader segments have settled and handle data
@@ -823,7 +860,7 @@ export interface RouteRecordWindow {
823
860
  * This is the type exported to library consumers. Internal code should
824
861
  * use the full RequestContext interface directly.
825
862
  */
826
- export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_routeName" | "_prevRouteKey" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
863
+ export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellCaptureForVisitor" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_routeName" | "_prevRouteKey" | "_visitorMoved" | "_inActionRevalidation" | "_actionRan" | "_reportedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
827
864
  /**
828
865
  * Marker for a waitUntil-scheduled fn whose task promise must NOT enter
829
866
  * _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
@@ -18,6 +18,18 @@
18
18
  * fill); the rest follow the rule so a new call site cannot drift into one.
19
19
  */
20
20
  export declare function requestHeaders(request: Request): Headers;
21
+ /**
22
+ * A copy of `request`'s headers for a bodyless mirror of it (the PE
23
+ * re-render, route middleware around it, a rewrite pass after an action),
24
+ * without the body-framing ones and `content-type`, so a body check gated on
25
+ * the content-type passes over a request that has no body.
26
+ */
27
+ export declare function bodylessHeaders(request: Request): Headers;
28
+ /**
29
+ * A bodyless mirror of `request` at `url`: `method`, its
30
+ * {@link bodylessHeaders}, the signal and workerd's `cf`.
31
+ */
32
+ export declare function bodylessRequest(url: string | URL, request: Request, method: string): Request;
21
33
  /**
22
34
  * Shadow `request.headers` with an own, non-enumerable getter that calls
23
35
  * `beforeRead` and returns the request's own Headers (stable per request, so
@@ -7,10 +7,13 @@
7
7
  * visitor's URL is its first entry (`ctx.rewrittenFrom`); the hops are its
8
8
  * length minus one.
9
9
  */
10
+ import type { RewriteShell } from "../route-definition/rewrite.js";
10
11
  import type { RequestContext } from "./request-context.js";
11
12
  /** Most rewrites one request may take; the next one is a RewriteLoopError. */
12
13
  export declare const MAX_REWRITE_HOPS = 5;
13
14
  type TrailContext = Pick<RequestContext<any>, "_variables">;
15
+ /** A URL's path and search: what a rewrite hop, a target and a visitor's move compare. */
16
+ export declare function pathKey(url: URL): string;
14
17
  /** The trail of a rewritten request; undefined when nothing rewrote. */
15
18
  export declare function rewriteTrail(reqCtx: TrailContext | undefined): readonly string[] | undefined;
16
19
  /**
@@ -19,11 +22,15 @@ export declare function rewriteTrail(reqCtx: TrailContext | undefined): readonly
19
22
  * URL the request is on (pathname and search).
20
23
  */
21
24
  export declare function recordRewriteHop(reqCtx: TrailContext, from: URL, to: URL): number;
25
+ export declare function recordRewriteShell(reqCtx: TrailContext, audience: RewriteShell | undefined): void;
26
+ /** The last hop's `rewrite(...).shell()` choice; undefined: none. */
27
+ export declare function rewriteShellAudience(reqCtx: TrailContext | undefined): RewriteShell | undefined;
22
28
  type AudienceContext = Pick<RequestContext<any>, "_shellCaptureRun" | "_documentCacheRender" | "res">;
23
29
  /**
24
30
  * A render other visitors may be served: a PPR shell capture, or a render
25
31
  * the document cache stores (its response opted in before next()). It shows
26
- * what a direct visit to its URL shows: no visitor theme, no visitor URL.
32
+ * no visitor theme, and no visitor URL unless it is a visitor-keyed shell
33
+ * capture (`_shellCaptureForVisitor`).
27
34
  */
28
35
  export declare function rendersForSharedAudience(reqCtx: AudienceContext): boolean;
29
36
  /**
@@ -4,7 +4,7 @@ import { blockPrefetch, unblockPrefetch, createPageHelpers, createStopwatch, get
4
4
  import { createParity, type ExpectParityOptions, type Parity, type ParityDescribeOptions, type ParityIntent } from "./parity.js";
5
5
  import { createRangoMatchers, type RangoMatchers } from "./matchers.js";
6
6
  export { assertCacheStatus, assertCacheDecision, parseCacheHeader, createCacheSink, filterCacheDecisions, type CacheSink, type ExpectedCacheStatus, type CacheStatusTarget, } from "../cache-status.js";
7
- export { assertPprReplayStatus, assertShellStatus, parsePprReplayStatus, parseShellStatus, PPR_REPLAY_STATUS_HEADER, shellCacheKey, SHELL_STATUS_HEADER, type PprReplayBypassReason, type PprReplayStatus, type ShellCachePartition, type ShellStatus, type ShellStatusTarget, } from "../shell-status.js";
7
+ export { assertPprReplayStatus, assertShellStatus, parsePprReplayStatus, parseShellStatus, PPR_REPLAY_STATUS_HEADER, shellCacheKey, SHELL_STATUS_HEADER, visitorShellCacheKey, type PprReplayBypassReason, type PprReplayStatus, type ShellCachePartition, type ShellStatus, type ShellStatusTarget, } from "../shell-status.js";
8
8
  export { testId, waitForHydration, waitForNavigation, goBack, goForward, getHistoryState, waitForElement, isVisibleInViewport, isPrefetchRequest, blockPrefetch, unblockPrefetch, parseNumber, getNumericContent, createStopwatch, measureTime, createPageHelpers, createUseFixture, createParity, createRangoMatchers, };
9
9
  export type { Fixture, FixtureOptions, PageHelpers, Stopwatch, Parity, ParityIntent, ParityDescribeOptions, ExpectParityOptions, RangoMatchers, };
10
10
  export interface RangoE2E extends PageHelpers, Parity {
@@ -33,4 +33,4 @@ export type { TestableHandler, RenderHandlerOptions, RenderHandlerResult, StateC
33
33
  export { createActionForm } from "./action-form.js";
34
34
  export type { CreateActionFormOptions } from "./action-form.js";
35
35
  export { serveShellRequest, resetShellTestState, } from "./serve-shell-request.js";
36
- export type { ServeShellRequestAction, ServeShellRequestOptions, ServeShellRequestResult, ShellRequestHandles, } from "./serve-shell-request.js";
36
+ export type { ServeShellRequestAction, ServeShellRequestOptions, ServeShellRequestResult, ShellRequestAction, ShellRequestHandles, } from "./serve-shell-request.js";
@@ -50,7 +50,7 @@ export type { PrerenderConfig, PrerenderResult, PrerenderWarmCaches, } from "../
50
50
  export { assertCacheStatus, assertCacheDecision, parseCacheHeader, createCacheSink, filterCacheDecisions, } from "./cache-status.js";
51
51
  export type { ExpectedCacheStatus, CacheStatusTarget, CacheSink, } from "./cache-status.js";
52
52
  export type { TelemetryEvent, TelemetrySink, CacheDecisionEvent, CacheSegmentSignal, CacheSegmentStatus, } from "../router/telemetry.js";
53
- export { assertPprReplayStatus, assertShellStatus, parsePprReplayStatus, parseShellStatus, PPR_REPLAY_STATUS_HEADER, shellCacheKey, SHELL_STATUS_HEADER, } from "./shell-status.js";
53
+ export { assertPprReplayStatus, assertShellStatus, parsePprReplayStatus, parseShellStatus, PPR_REPLAY_STATUS_HEADER, shellCacheKey, SHELL_STATUS_HEADER, visitorShellCacheKey, } from "./shell-status.js";
54
54
  export type { PprReplayBypassReason, PprReplayStatus, ShellCachePartition, ShellStatus, ShellStatusTarget, } from "./shell-status.js";
55
55
  export { setBuildVersions } from "./build-versions.js";
56
56
  export type { BuildVersions, RouterVersions } from "./build-versions.js";
@@ -9,8 +9,9 @@
9
9
  *
10
10
  * A Vitest project runs no hoist plugin, so the source's revalidate()
11
11
  * predicates are plain functions. Each is registered under a key named for
12
- * its reference, route and loader, as the plugin's generated module registers
13
- * its own, and the projection carries the keys: materialization attaches them
14
- * and the server runs them, as in an app.
12
+ * its reference, route or intercept, and loader, as the plugin's generated
13
+ * module registers its own, and the projection carries the keys:
14
+ * materialization attaches them and the server runs them, as in an app. A
15
+ * boolean rides in the projection as itself, as the plugin leaves a literal.
15
16
  */
16
17
  export declare function installClientUrlsProjection(referenceId: string, source: Readonly<Record<string, unknown>>): void;
@@ -23,13 +23,16 @@
23
23
  * SEEDED directly into client context (see the `loaders` / `locationState` /
24
24
  * `handles` / `outletPending` options) — nothing is executed on the server.
25
25
  * This exercises the context read path, not the run path.
26
- * - navigate() does NOT drive the navigation lifecycle: useNavigation().state,
27
- * useLinkStatus().pending, and useAction().state stay "idle". Assert
28
- * pending/loading/submitting transition states with renderServerTree / e2e
29
- * instead (navigate() warns once if used). The one pending state it does
30
- * model is the held-navigation useLoader().isLoading: a `transition` spec
31
- * plus a pending Promise seeded via navigate(url, { loaders }) commits
32
- * through production's commitInTransition (browser/partial-update.ts).
26
+ * - navigate() drives the navigation lifecycle as a click does:
27
+ * useNavigation() reads loading from the call and idle with the commit,
28
+ * and useLinkStatus().pending is true for a link to the destination until
29
+ * the commit is handed to React. A `transition` spec plus a pending
30
+ * Promise seeded via navigate(url, { loaders }) commits through
31
+ * production's commitInTransition (browser/partial-update.ts), which React
32
+ * holds: useNavigation() stays loading and the held reader's
33
+ * useLoader().isLoading reads true until the data lands. Without
34
+ * `transition` the commit is urgent (production's same-structure hold is
35
+ * not modeled). useAction().state stays idle: no action runs.
33
36
  * - A spec's transition({ when }) decides every commit with production's
34
37
  * browser decision: navigate() and useRouter().push model kind "push",
35
38
  * useRouter().replace kind "replace", refresh() kind "revalidate".
@@ -324,9 +327,10 @@ export interface TestRouterHandle {
324
327
  * pending Promise suspends the read like a streaming Flight chunk. When a
325
328
  * spec in the chain has `transition`, the commit goes through production's
326
329
  * commitInTransition: the reader stays on screen with
327
- * `useLoader().isLoading === true` until the promise settles. Settle it
328
- * inside RTL's `act()` to flush the commit. Without `transition` the commit
329
- * is urgent and the read suspends to the nearest Suspense boundary.
330
+ * `useLoader().isLoading === true`, and `useNavigation().state` reads
331
+ * "loading", until the promise settles. Settle it inside RTL's `act()` to
332
+ * flush the commit. Without `transition` the commit is urgent and the read
333
+ * suspends to the nearest Suspense boundary.
330
334
  *
331
335
  * @example
332
336
  * await router.navigate("/products/2", { loaders: [[ProductLoader, next]] });
@@ -346,8 +350,14 @@ export interface TestRouterHandle {
346
350
  * location state as a production replace does). With neither, history is
347
351
  * left alone and readers keep the state they have: `navigate(url)` and
348
352
  * `navigate(url, { replace: false })` are the same call.
353
+ *
354
+ * `options.handles` are the destination's handle pushes (`[handle,
355
+ * values]`, attached to its leaf route as in `renderRoute`'s own
356
+ * `handles`). They arrive on the response's handle stream, so `useHandle`
357
+ * readers take them with the page's commit: while React holds the page,
358
+ * readers keep the values of the page being left.
349
359
  */
350
- navigate(url: string, options?: Pick<RenderRouteOptions, "loaders"> & Pick<NavigateOptions, "state" | "replace" | "transition">): Promise<void>;
360
+ navigate(url: string, options?: Pick<RenderRouteOptions, "loaders" | "handles"> & Pick<NavigateOptions, "state" | "replace" | "transition">): Promise<void>;
351
361
  /**
352
362
  * Re-render the current location, as router.refresh() does: a spec's
353
363
  * transition({ when }) decides it with kind "revalidate" (`to` is `from`).
@@ -100,6 +100,13 @@ export interface RunLoaderOptions<TEnv = any> {
100
100
  routeMap?: Record<string, string>;
101
101
  /** Matched route name for scoped `.name` reverse resolution. */
102
102
  routeName?: string;
103
+ /**
104
+ * Include name prefix of the module whose `layout()` / `parallel()` /
105
+ * `cache()` declares the loader (`"account"`, or `""` for the root module).
106
+ * `ctx.reverse(".name")` then resolves in that module, as such a loader's
107
+ * does in production, instead of from `routeName`.
108
+ */
109
+ declaredIn?: string;
103
110
  /** HTTP method surfaced as `ctx.method`. Defaults to "GET". */
104
111
  method?: string;
105
112
  /** Request body surfaced as `ctx.body`. */
@@ -88,6 +88,13 @@ export interface RunMiddlewareRewrite {
88
88
  pathname: string;
89
89
  search: string;
90
90
  routeName?: string;
91
+ /**
92
+ * Present, `true`, only when the rewrite was thrown with
93
+ * `.disallowMutations()`: production refuses it for a non-GET, non-HEAD
94
+ * request in global middleware, before the action runs, instead of moving
95
+ * the mutation to the target.
96
+ */
97
+ mutationsDisallowed?: true;
91
98
  }
92
99
  /**
93
100
  * Result of runMiddleware.
@@ -66,9 +66,10 @@ export interface RunRevalidateOptions<TEnv = any> {
66
66
  context?: RevalidateArgs["context"];
67
67
  }
68
68
  /**
69
- * Run one revalidate() predicate, or a chain in declaration order, the way
70
- * the router does for a request. Resolves to the final decision: true
71
- * re-runs the segment, false keeps the client's copy.
69
+ * Run one revalidate() argument, or a chain in declaration order, the way
70
+ * the router does for a request: a predicate, or `true` / `false` as
71
+ * `revalidate()` takes them. Resolves to the final decision: true re-runs
72
+ * the segment, false keeps the client's copy.
72
73
  */
73
- export declare function runRevalidate<TEnv = any>(fn: ShouldRevalidateFn<any, TEnv> | readonly ShouldRevalidateFn<any, TEnv>[], opts?: RunRevalidateOptions<TEnv>): Promise<boolean>;
74
+ export declare function runRevalidate<TEnv = any>(fn: ShouldRevalidateFn<any, TEnv> | boolean | readonly (ShouldRevalidateFn<any, TEnv> | boolean)[], opts?: RunRevalidateOptions<TEnv>): Promise<boolean>;
74
75
  export {};
@@ -70,13 +70,20 @@ export interface ServeShellRequestOptions<TEnv = any> {
70
70
  * entries are deferred: `result.readDeferred()` lists them. `fill: true`
71
71
  * sends the request the browser follows an adopted prefetch with
72
72
  * (`_rsc_fill`): pass the ids the prefetch delivered, without the deferred
73
- * ones, as `segments`, and the same URL as `from`.
73
+ * ones, as `segments`, and the same URL as `from`. `interceptSource` sends
74
+ * the intercept source (`X-RSC-Router-Intercept-Source`) the browser sends
75
+ * from an open modal and with the fill of an intercept, whose `from` is
76
+ * that source. `rewriteTarget` sends the `metadata.rewriteTarget` the page at
77
+ * `from` carried when middleware rewrote it (`_rsc_rt`), as the browser
78
+ * does: the server then diffs against the route that rendered that page.
74
79
  */
75
80
  partial?: true | {
76
81
  from?: string;
82
+ rewriteTarget?: string;
77
83
  segments?: readonly string[];
78
84
  prefetch?: boolean;
79
85
  fill?: boolean;
86
+ interceptSource?: string;
80
87
  };
81
88
  /**
82
89
  * POST this form as a submit before hydration: the no-JS request the
@@ -109,6 +116,8 @@ export interface ServeShellRequestAction {
109
116
  args?: readonly unknown[];
110
117
  /** The segment ids the page holds (`_rsc_segments`). */
111
118
  segments?: readonly string[];
119
+ /** The page's payload `metadata.rewriteTarget`, as for `partial`. */
120
+ rewriteTarget?: string;
112
121
  }
113
122
  /** A response's handle data, as the browser consumes it. */
114
123
  export interface ShellRequestHandles {
@@ -125,6 +134,24 @@ export interface ShellRequestHandles {
125
134
  */
126
135
  late: HandleData[];
127
136
  }
137
+ /**
138
+ * An `action` request's answer, as browser/server-action-bridge.ts reads it.
139
+ */
140
+ export interface ShellRequestAction {
141
+ /** False when the action threw: the call rejects with `result`. */
142
+ ok: boolean;
143
+ /** What the call resolves (or rejects) with. */
144
+ result: unknown;
145
+ /**
146
+ * The error of the first loader that threw while it re-ran in the action's
147
+ * revalidation, the value `useAction(action).revalidationError` reports.
148
+ * That loader throws at its `useLoader` read, where the nearest boundary
149
+ * catches it, and the call still resolves. `null` when every loader
150
+ * answered (a `notFound()` or `redirect()` is not an error), or `ok` is
151
+ * false, as `useAction` reports it.
152
+ */
153
+ revalidationError: Error | null;
154
+ }
128
155
  /** Result of {@link serveShellRequest}. */
129
156
  export interface ServeShellRequestResult {
130
157
  /** The handler's Response. Its body is already read: see `body`. */
@@ -150,9 +177,12 @@ export interface ServeShellRequestResult {
150
177
  * The shell key production resolved for this request: for a document the
151
178
  * serve path read and captured (a MISS or a HIT), the key it used, request
152
179
  * partition included (a route partitioned by `cache({ key })` or the
153
- * store's `keyGenerator`). Otherwise (a route without `ppr`, a request
154
- * passed to axis 1 before its key was resolved, a partial request) the
155
- * document URL's key without a partition, as `shellCacheKey` builds it.
180
+ * store's `keyGenerator`), and for a request middleware rewrote with
181
+ * `rewrite(...).shell("visitor")` the visitor's key, as
182
+ * `visitorShellCacheKey` builds it. Otherwise (a route without `ppr`, a
183
+ * request passed to axis 1 before its key was resolved, a rewritten
184
+ * request whose rewrite chose no shell, a partial request) the document
185
+ * URL's key without a partition, as `shellCacheKey` builds it.
156
186
  */
157
187
  key: string;
158
188
  /**
@@ -185,6 +215,13 @@ export interface ServeShellRequestResult {
185
215
  * hydrates without it.
186
216
  */
187
217
  readPayloadFormState(): Promise<unknown>;
218
+ /**
219
+ * For an `action` request, the call's answer as the browser reads it: its
220
+ * result and the `revalidationError` its loaders' reruns report.
221
+ * Undefined when no Flight was rendered or the payload carries no action
222
+ * result.
223
+ */
224
+ readAction(): Promise<ShellRequestAction | undefined>;
188
225
  }
189
226
  /**
190
227
  * Reset the per-isolate PPR state requests leave behind, so the next test
@@ -95,6 +95,23 @@ export interface ShellCachePartition {
95
95
  export declare function shellCacheKey(router: {
96
96
  readonly id: string;
97
97
  }, url: URL | string, searchParams?: CacheSearchParams, partition?: string | readonly string[] | ShellCachePartition): string;
98
+ /**
99
+ * Shell store key of a request middleware rewrote with
100
+ * `throw rewrite(...).shell("visitor")`: the visitor's `url`, partitioned by
101
+ * the rewrite's `target` (its path and search), as production builds it
102
+ * (`visitorShellKey`, `rsc/shell-capture-constants.ts`). `searchParams` is
103
+ * the target route's `cache.searchParams` config, applied to the visitor's
104
+ * search; `partition` is the target route's own, as for
105
+ * {@link shellCacheKey}, composed after the target's.
106
+ *
107
+ * ```ts
108
+ * const hit = await serveShellRequest(router, "/summer", { cacheStore });
109
+ * expect(hit.key).toBe(visitorShellCacheKey(router, "/summer", "/item/1"));
110
+ * ```
111
+ */
112
+ export declare function visitorShellCacheKey(router: {
113
+ readonly id: string;
114
+ }, url: URL | string, target: URL | string, searchParams?: CacheSearchParams, partition?: string | readonly string[] | ShellCachePartition): string;
98
115
  /**
99
116
  * Read `x-rango-shell` from a response. Returns `null` when the header is
100
117
  * absent (axis-1 / non-ppr / ineligible request).
@@ -1,2 +1,3 @@
1
1
  export declare const VERSION = "";
2
2
  export declare const ROUTER_VERSIONS: undefined;
3
+ export declare const PACKAGE_VERSION = "0.0.0-test";
@@ -144,11 +144,20 @@ export interface RangoTestConfig {
144
144
  */
145
145
  export declare function rangoTestConfig(opts?: RangoTestAliasOptions): RangoTestConfig;
146
146
  /** A minimal Vite plugin shape (avoids a hard dependency on Vite's types). */
147
+ /** The part of a Vite plugin context {@link rangoUseClientTransform} resolves with. */
148
+ interface SourceResolveContext {
149
+ resolve(source: string, importer?: string, options?: {
150
+ skipSelf?: boolean;
151
+ }): Promise<{
152
+ id: string;
153
+ external?: boolean | string;
154
+ } | null>;
155
+ }
147
156
  interface FlightTransformPlugin {
148
157
  name: string;
149
158
  resolveId: {
150
159
  order: "pre";
151
- handler(source: string, importer: string | undefined): string | undefined;
160
+ handler(this: SourceResolveContext, source: string, importer: string | undefined): Promise<string | undefined>;
152
161
  };
153
162
  transform(code: string, id: string): Promise<{
154
163
  code: string;
@@ -13,9 +13,3 @@ export declare function unwrapsSynchronously(stream: Promise<unknown>): boolean;
13
13
  * listing a 0 ms promise on every reader that calls it.
14
14
  */
15
15
  export declare const SETTLED_THENABLE: Promise<undefined>;
16
- /**
17
- * The value React reads from `value` without suspending: `value` itself when
18
- * it is not a promise, a promise's `value` once it carries React's or Flight's
19
- * `status: "fulfilled"`. Undefined while it is pending or rejected.
20
- */
21
- export declare function settledValue<T>(value: T | Promise<T>): T | undefined;
@@ -53,7 +53,13 @@ type AutofillParamsFromEntry<TEntry> = TEntry extends string ? string extends TE
53
53
  type AutofillSearchFromEntry<TMap, TKey> = TKey extends keyof TMap ? TMap[TKey] extends {
54
54
  readonly search: infer S extends SearchSchema;
55
55
  } ? ResolveSearchSchema<S> : Record<string, unknown> : Record<string, unknown>;
56
- type AutofillAwareReverseFunction<TLocalRoutes, TGlobalRoutes> = ScopedReverseFunction<TLocalRoutes, TGlobalRoutes> & {
56
+ /**
57
+ * `ScopedReverseFunction` whose global-name params are optional: the runtime
58
+ * fills missing ones from the matched route's params (`createReverseFunction`
59
+ * in `router/handler-context.ts`, explicit params win). Shared by handler,
60
+ * loader and request-context `reverse`.
61
+ */
62
+ export type AutofillAwareReverseFunction<TLocalRoutes, TGlobalRoutes> = ScopedReverseFunction<TLocalRoutes, TGlobalRoutes> & {
57
63
  <TName extends keyof TGlobalRoutes & string>(name: TName, params?: AutofillParamsFromEntry<TGlobalRoutes[TName]>, search?: AutofillSearchFromEntry<TGlobalRoutes, TName>): string;
58
64
  <TName extends keyof TLocalRoutes & string>(name: `.${TName}`, params?: AutofillParamsFromEntry<TLocalRoutes[TName]>, search?: AutofillSearchFromEntry<TLocalRoutes, TName>): string;
59
65
  };
@@ -329,6 +335,11 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
329
335
  _responseType?: string;
330
336
  /** Route name for cache key scoping (prevents cross-route collisions). */
331
337
  _routeName?: string;
338
+ /**
339
+ * The segment's ReverseScope on a layout's / parallel's ctx and its
340
+ * loaders' (withReverseScope): keys a "use cache" call taking the ctx.
341
+ */
342
+ _reverseScope?: import("../server/context.js").ReverseScope;
332
343
  /**
333
344
  * @internal The on-demand overlay holds a "removed" marker for this request
334
345
  * (tryPrerenderLookup, cache-lookup.ts); gateOnDemandProducer reads it. On
@@ -2,7 +2,7 @@ import type { ContextVar } from "../context-var.js";
2
2
  import type { Handle } from "../handle.js";
3
3
  import type { HandlePush } from "../defer.js";
4
4
  import type { MiddlewareFn } from "../router/middleware.js";
5
- import type { ScopedReverseFunction } from "../reverse.js";
5
+ import type { AutofillAwareReverseFunction } from "./handler-context.js";
6
6
  import type { SearchSchema, ResolveSearchSchema } from "../search-params.js";
7
7
  import type { UseItems, LoaderUseItem } from "../route-types.js";
8
8
  import type { DefaultEnv, DefaultReverseRouteMap, DefaultVars } from "./global-namespace.js";
@@ -118,9 +118,10 @@ export type LoaderContext<TParams = Record<string, string | undefined>, TEnv = D
118
118
  /**
119
119
  * Generate URLs from route names.
120
120
  * Same scoped reverse as route handlers — `.name` resolves within the
121
- * current include() scope, `name` resolves globally.
121
+ * current include() scope, `name` resolves globally, and params the matched
122
+ * route already carries (e.g. include() mount params) are filled in.
122
123
  */
123
- reverse: ScopedReverseFunction<Record<string, string>, DefaultReverseRouteMap>;
124
+ reverse: AutofillAwareReverseFunction<Record<string, string>, DefaultReverseRouteMap>;
124
125
  };
125
126
  /**
126
127
  * Loader function signature
@@ -1,6 +1,7 @@
1
1
  import type { AllUseItems } from "../route-types.js";
2
+ import type { IncludeScopePosition } from "../server/context.js";
2
3
  import type { TrailingSlashMode, ResolvedRouteMap } from "./route-config.js";
3
- export interface LazyIncludeContext {
4
+ export interface LazyIncludeContext extends IncludeScopePosition {
4
5
  urlPrefix: string;
5
6
  namePrefix: string | undefined;
6
7
  parent: unknown;
@@ -144,9 +144,11 @@ export type PathHelpers<TEnv> = {
144
144
  (fns: MiddlewareFn<TEnv>[], children: () => UseItems<LayoutUseItem>): MiddlewareItem;
145
145
  };
146
146
  /**
147
- * Control when a segment should revalidate during navigation
147
+ * Control when a segment should revalidate during navigation.
148
+ * `revalidate(true)` / `revalidate(false)` are shorthand for
149
+ * `revalidate(() => true)` / `revalidate(() => false)`.
148
150
  */
149
- revalidate: (fn: ShouldRevalidateFn<any, TEnv>) => RevalidateItem;
151
+ revalidate: (fn: ShouldRevalidateFn<any, TEnv> | boolean) => RevalidateItem;
150
152
  /**
151
153
  * Attach a data loader to the current route/layout.
152
154
  *
@@ -1,3 +1,4 @@
1
+ import { type EnvironmentModuleNode } from "vite";
1
2
  import { type ClientUrlProjection } from "../../client-urls/server-projection.js";
2
3
  import type { DiscoveryState } from "./state.js";
3
4
  interface ClientUrlSsrEnvironment {
@@ -9,7 +10,40 @@ interface ClientUrlProjectionServerModule {
9
10
  clearClientUrlProjections(): void;
10
11
  setClientUrlProjection(referenceId: string, projection: ClientUrlProjection): void;
11
12
  }
13
+ /** The RSC environment whose realm `ClientUrlProjectionServerModule` is. */
14
+ interface ClientUrlRscEnvironment {
15
+ readonly runner: {
16
+ import(id: string): Promise<unknown>;
17
+ };
18
+ readonly moduleGraph?: {
19
+ getModuleById(id: string): EnvironmentModuleNode | undefined;
20
+ invalidateModule(mod: EnvironmentModuleNode): void;
21
+ };
22
+ }
23
+ export declare const CLIENT_URLS_REVALIDATE_QUERY = "rango-revalidate";
24
+ /** The id of the module registering `file`'s hoisted revalidate() predicates. */
25
+ export declare function hoistedRevalidateId(file: string): string;
12
26
  export declare function recordClientUrlsModule(state: DiscoveryState, code: string, id: string): void;
27
+ /** A module that imports the router's client entry (a cheap pre-filter). */
28
+ export declare const CLIENT_IMPORT_RE: RegExp;
29
+ /**
30
+ * Whether an edited module can carry a clientUrls() component's own items: it
31
+ * imports "@rangojs/router/client" and assigns a `.use` in code (not in a
32
+ * comment or string). Such a module changes its groups' projections and
33
+ * hoisted revalidate() registrations like a group edit, with or without
34
+ * "use client".
35
+ */
36
+ export declare function isClientUrlsComponentUseSource(source: string): boolean;
37
+ /**
38
+ * A hash of the text of every `X.use = ...` assignment of a component-use
39
+ * module (isClientUrlsComponentUseSource), or undefined for any other module.
40
+ * Equal before and after a save, the edit (markup, hooks) left what its
41
+ * groups read unchanged: the dev watcher skips re-discovery and the client
42
+ * keeps Fast Refresh. An edit outside the assignments that changes what one
43
+ * means (a helper it calls, an import's source) is not seen. A module that
44
+ * does not parse hashes whole.
45
+ */
46
+ export declare function componentUseSignature(source: string, file: string): string | undefined;
13
47
  export declare function resolveClientUrlsSource(state: DiscoveryState, referenceId: string): string | undefined;
14
48
  /**
15
49
  * Deterministic filesystem discovery of clientUrls modules. Transform-based
@@ -33,11 +67,13 @@ export declare function scanForClientUrlModules(state: DiscoveryState): void;
33
67
  * import, so `.routes(reference)` materialized the previous pass's projection.
34
68
  *
35
69
  * Errors are deliberately swallowed per source (a module mid-edit keeps its
36
- * last-known projection); the strict discoverClientUrlProjections() pass still
37
- * surfaces real failures afterwards. No-ops on cold start (nothing recorded
38
- * yet) and when the SSR runner is unavailable.
70
+ * last-known projection), and all refreshed projections keep their
71
+ * last-known state when any registration fails to load; the strict
72
+ * discoverClientUrlProjections() pass still surfaces real failures afterwards.
73
+ * No-ops on cold start (nothing recorded yet) and when the SSR runner is
74
+ * unavailable.
39
75
  */
40
- export declare function refreshRecordedClientUrlProjections(state: DiscoveryState, ssrEnv: ClientUrlSsrEnvironment | undefined, serverMod: ClientUrlProjectionServerModule): Promise<void>;
76
+ export declare function refreshRecordedClientUrlProjections(state: DiscoveryState, ssrEnv: ClientUrlSsrEnvironment | undefined, serverMod: ClientUrlProjectionServerModule, rscEnv: ClientUrlRscEnvironment): Promise<void>;
41
77
  /**
42
78
  * Strict projection discovery over every RECORDED clientUrls module. Recorded
43
79
  * modules — not router references — are the source of truth: include() mounts
@@ -49,5 +85,19 @@ export declare function refreshRecordedClientUrlProjections(state: DiscoveryStat
49
85
  * (recordClientUrlsModule never un-records, so deletions must self-heal here).
50
86
  * A present-but-broken module is a hard error: it is part of the app graph.
51
87
  */
52
- export declare function discoverClientUrlProjections(state: DiscoveryState, ssrEnv: ClientUrlSsrEnvironment | undefined, serverMod: ClientUrlProjectionServerModule): Promise<void>;
88
+ export declare function discoverClientUrlProjections(state: DiscoveryState, ssrEnv: ClientUrlSsrEnvironment | undefined, serverMod: ClientUrlProjectionServerModule, rscEnv: ClientUrlRscEnvironment): Promise<void>;
89
+ /**
90
+ * Assign each group of `projections` the other files holding the predicates
91
+ * it reads (each key's file, as the hoist transform recorded it: a key with
92
+ * none stays unregistered, and materialization names it), after loading their
93
+ * registrations into `rscEnv`. The group's own registrations load with its
94
+ * proxy, and its `?rango-revalidate` module imports the assigned files'
95
+ * (plugins/client-urls-revalidate-hoist.ts). When a group's files change, that
96
+ * module is invalidated, so a later evaluation (a reload, a request realm)
97
+ * imports the current ones. Another realm (workerd, a production bundle)
98
+ * loads a group only after discovery: its entry imports the routes-manifest
99
+ * module first, whose load waits for discovery (RSC_ENTRY_BOOTSTRAP_IMPORTS),
100
+ * and a build discovers in buildStart.
101
+ */
102
+ export declare function assignClientUrlRevalidateFiles(state: Pick<DiscoveryState, "clientUrlRevalidate" | "clientUrlSourceByReferenceId">, rscEnv: ClientUrlRscEnvironment, projections: ReadonlyMap<string, ClientUrlProjection>): Promise<void>;
53
103
  export {};