@rangojs/router 0.18.0 → 0.19.1

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 +37 -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 +48 -5
  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 +126 -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 +962 -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 +67 -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 +54 -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 +202 -144
  139. package/src/cache/cache-scope.ts +304 -112
  140. package/src/cache/cache-tag.ts +209 -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 +42 -5
  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 +152 -26
  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 +263 -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 +134 -87
  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
@@ -1,7 +1,7 @@
1
+ import type { ServerRouteLocation } from "../types/segments.js";
1
2
  import { AsyncLocalStorage } from "node:async_hooks";
2
3
  import type { ReactNode } from "react";
3
4
  import type { PartialCacheOptions, ErrorBoundaryHandler, Handler, LoaderDefinition, MiddlewareFn, NotFoundBoundaryHandler, ShouldRevalidateFn, TransitionConfig } from "../types";
4
- import type { DefaultRouteName } from "../types/global-namespace.js";
5
5
  import type { ContextVar } from "../context-var.js";
6
6
  /**
7
7
  * Performance metric entry for a single measured operation
@@ -132,20 +132,22 @@ export type InterceptSegmentsState = {
132
132
  * Context passed to intercept selector functions (when())
133
133
  * Contains navigation context to determine if interception should occur.
134
134
  *
135
+ * `from` / `to` have the shape transition({ when }) sees, without `state`:
136
+ * history state never reaches the server.
137
+ *
135
138
  * Note: when() is evaluated during route matching, BEFORE middleware runs.
136
139
  * So ctx.get()/ctx.use() are not available, but env (platform bindings) is.
137
140
  *
138
141
  * @internal This type is an implementation detail and may change without notice.
139
142
  */
140
143
  export type InterceptSelectorContext<TEnv = any> = {
141
- from: URL;
142
- to: URL;
143
- params: Record<string, string>;
144
+ /** Where the navigation comes from: the intercept source while one is open. */
145
+ from: ServerRouteLocation;
146
+ /** The navigation target. */
147
+ to: ServerRouteLocation;
144
148
  request: Request;
145
149
  env: TEnv;
146
150
  segments: InterceptSegmentsState;
147
- fromRouteName?: DefaultRouteName;
148
- toRouteName?: DefaultRouteName;
149
151
  };
150
152
  /**
151
153
  * Selector function for conditional interception
@@ -423,65 +425,82 @@ export declare function track(label: string, depth?: number): () => void;
423
425
  */
424
426
  export declare function isInsideCacheScope(): boolean;
425
427
  /**
426
- * Throw if called during the ACTIVE background shell-capture render
427
- * (`_shellCaptureRun` true on the derived request context built by
428
- * shell-capture.ts). The captured shell is shared across every user hitting
429
- * the URL, so a request-scoped read here would bake one user's cookies,
430
- * headers, or per-request variables into markup served to others — same
431
- * hazard as the cache scopes above, at the document tier. DSL segment loaders
432
- * need no exemption: the live lane is masked (never executed) during capture,
433
- * and the bake lane is exactly what this guard exists for.
434
- *
435
- * It covers everything the capture waits for, not only synchronous handler
436
- * code: a promise the handler passes or pushes, an async server component,
437
- * and a loader the handler awaits (`await ctx.use(Loader)`) all run under the
438
- * capture context and all bake. The last one used to be exempt (the
439
- * consumption-lane rule, #672/#674): while a HIT re-ran handlers, a slot
440
- * handler's `ctx.use` of an identity loader rendered per visitor on the HIT.
441
- * Now every HIT replays the capture's copy, so the exemption would bake the
442
- * capturing request's identity into every visitor's page. The cache()
443
- * guards above keep it (a cache() HIT is a separate tier).
444
- *
445
- * Keys off `_shellCaptureRun`, NOT the `_shellCapture` descriptor: the descriptor
446
- * is also present during the FOREGROUND render (it means "a capture is wanted"),
447
- * and the foreground must read cookies/headers normally to serve the real user.
448
- * Only the derived capture context sets `_shellCaptureRun`.
428
+ * What a refused identity read says (guardIdentityRead): its `verb`, and per
429
+ * refusing scope the text after "<surface> cannot be <verb> ...": why the
430
+ * value must not reach that scope, and what to do instead. `fix.warning` is
431
+ * the fix the capture's refusal warning gives (shell-capture.ts
432
+ * refuseOnCaptureGuard).
433
+ */
434
+ export interface IdentityReadWording {
435
+ /** "called" for a function (cookies(), ctx.get()), "read" for a property (the theme getters). */
436
+ verb: LoaderIdentityReadVerb;
437
+ fix: {
438
+ useCache: string;
439
+ cacheScope: string;
440
+ capture: string;
441
+ warning: string;
442
+ };
443
+ /**
444
+ * False when the read is recorded later, by the returned view's read
445
+ * methods (cookies(), headers()): a view taken outside a loader and read
446
+ * inside one still counts, and a cookie write alone is not a read.
447
+ */
448
+ record?: false;
449
+ }
450
+ /**
451
+ * The one guard every request-identity read goes through: cookies(),
452
+ * headers(), the theme reads (cookie-store.ts readGuardedTheme), a
453
+ * non-cacheable ctx.get() (assertNonCacheableReadAllowed), and the raw reads
454
+ * `ctx.request.headers` and `getRequestContext().cookie()` / `.cookies()`
455
+ * (cookie-store.ts guardRequestHeaders, guardRawCookieRead; #976). Each surface keeps
456
+ * its own wording; the ladder and its exemptions are shared, so the surfaces
457
+ * refuse in exactly the same places:
449
458
  *
450
- * Applies only to the READ surfaces (cookies(), headers(), a { cache: false }
451
- * variable, and the theme reads through tripShellCaptureGuard) whose values
452
- * become markup. Response directives
453
- * (invalidateClientCache(), keepClientCache()) stay callable: during capture
454
- * they are header effects on a discarded response, and on the live HIT path
455
- * the full pipeline runs so their headers flow to the client normally.
459
+ * 0. A cache's own key(), store keyGenerator, condition() and tags(), and
460
+ * onError, read freely and record nothing (runIdentityExempt,
461
+ * cache/cache-exec-scope.ts): the value picks or labels the entry, or is
462
+ * only observed; it is never rendered. A cached body, loader body or
463
+ * funnel they start is guarded again.
464
+ * 1. A PPR shell capture (`ctx` is the capture's derived context,
465
+ * `_shellCaptureRun`) trips first: the capture context is flagged (so a
466
+ * caught throw still refuses the capture) and the read throws. The shell is
467
+ * shared per host+URL, and every HIT replays what the capture read. There
468
+ * is no loader-body exemption here: a bake-lane loader and a loader a
469
+ * handler awaits both bake.
470
+ * 2. A "use cache" body throws: the key does not include the value, so the
471
+ * first caller's would be stored and served to later callers. That holds
472
+ * for a loader body entered inside the cached function too (`await
473
+ * ctx.use(Loader)` there): its value is part of what the function returns.
474
+ * Before, a non-cacheable ctx.get() there was exempt while cookies() threw,
475
+ * and the entry stored the first request's value.
476
+ * 3. A cache() boundary throws, except inside a loader body
477
+ * (isInsideCacheScope): a route cache() never stores loader values.
478
+ * 4. The read is allowed, and recorded on the current loader execution for a
479
+ * loader cache() fill without key() (#972, recordLoaderIdentityRead)
480
+ * unless `wording.record` defers it to the returned view.
456
481
  *
457
- * The throw can be caught by the code that made the read, so the guard also
458
- * flags the capture context; the capture refuses on the flag
459
- * (shell-capture.ts refuseOnCaptureGuard), nothing is stored, and every
460
- * request keeps getting the normal axis-1 render.
482
+ * Outside these scopes every read is allowed, a live loader's included. The
483
+ * response directives (invalidateClientCache(), keepClientCache()) record
484
+ * nothing and are not captured reads: they take refuseInCacheScope alone.
485
+ */
486
+ export declare function guardIdentityRead(ctx: unknown, surface: string, wording: IdentityReadWording): void;
487
+ /**
488
+ * Steps 2 and 3 of guardIdentityRead: throw when a "use cache" body or a
489
+ * cache() boundary would store what `surface` produces.
461
490
  */
462
- export declare function assertNotInsideShellCapture(ctx: unknown, fnName: string): void;
491
+ export declare function refuseInCacheScope(surface: string, { verb, fix }: IdentityReadWording): void;
463
492
  /**
464
- * True when `ctx` is the active capture render (assertNotInsideShellCapture
465
- * above). On true the capture context is flagged with the read (`surface`,
466
- * e.g. "cookies()", "ctx.theme") and the fix the refusal warning gives, plus
467
- * the loader body (if any) that made the read, and the caller throws.
493
+ * The capture refusal for a request-scoped read (cookies(), headers(), a
494
+ * { cache: false } variable): the message after the surface, and the fix the
495
+ * refusal warning gives. `what` names the data that would leak.
468
496
  */
469
- export declare function tripShellCaptureGuard(ctx: unknown, surface: string, fix: string): boolean;
497
+ export declare function requestReadCaptureFix(what: string): Pick<IdentityReadWording["fix"], "capture" | "warning">;
470
498
  /**
471
499
  * Read guard for a non-cacheable variable (`createVar({ cache: false })` or a
472
- * `ctx.set(..., { cache: false })` write). Callers check isNonCacheable() first
473
- * so ordinary reads never reach the scope lookups.
474
- *
475
- * Throws during a PPR shell capture (`requestCtx` is the ambient request
476
- * context; assertNotInsideShellCapture): the shell is shared per host+URL.
477
- *
478
- * Throws inside a "use cache" body: the key does not include the value, so the
479
- * first caller's value would be stored and served to later callers (#925). A
480
- * loader body entered INSIDE the cached function is exempt, the same baked-copy
481
- * trade isInsideCacheScope() makes for cache(). A cached function called FROM a
482
- * loader is not: the loader re-runs, the cached body does not. The body scope
483
- * records the exec scope it was entered in, so the exemption holds only while
484
- * that is still the innermost one.
500
+ * `ctx.set(..., { cache: false })` write), through guardIdentityRead.
501
+ * Callers check isNonCacheable() first so ordinary reads never reach the
502
+ * scope lookups. `requestCtx` is the ambient request context, whose capture
503
+ * flag the guard reads.
485
504
  */
486
505
  export declare function assertNonCacheableReadAllowed(keyOrVar: string | ContextVar<unknown>, requestCtx?: unknown): void;
487
506
  /** How the identity error words a read: a function call or a property read. */
@@ -520,8 +539,44 @@ export interface LoaderIdentityRead {
520
539
  * (cache-tag.ts recordedIdentityRead), so both orders fail the same way.
521
540
  * Response directives do not record: a key cannot make a skipped body's side
522
541
  * effect reach a HIT.
542
+ *
543
+ * The read also lands on the execution's LoaderRunIdentity (#1011), which
544
+ * every execution has, from either loader runner (runInsideLoaderRun).
523
545
  */
524
546
  export declare function recordLoaderIdentityRead(surface: string, verb?: LoaderIdentityReadVerb): void;
547
+ /**
548
+ * One loader execution's request-identity record (#1011): the first identity
549
+ * read its body made, and the executions whose values it read with
550
+ * ctx.use(Loader). Every execution has one; the recorded-tag sets that carry
551
+ * the same reads for a loader cache() fill (cache-tag.ts) exist only in a
552
+ * request that binds one.
553
+ *
554
+ * A "use cache" function that reads a loader's value through the request
555
+ * memo (a handler, the route's loader() binding or a parent layout's started
556
+ * it first) does not run the body, so guardIdentityRead never sees the read.
557
+ * Scar: the entry, keyed without the cookie, stored the first visitor's value
558
+ * and served it to the next. cache-tag.ts readStartedLoaderValue refuses such
559
+ * a value through this record.
560
+ */
561
+ export interface LoaderRunIdentity {
562
+ readonly loaderId: string;
563
+ read?: LoaderIdentityRead;
564
+ reads?: Set<LoaderRunIdentity>;
565
+ }
566
+ /**
567
+ * Run a loader body with `run` as its identity record: both loader runners
568
+ * (loader-resolution.ts createLoaderExecutor, request-context.ts
569
+ * createUseFunction) enter it around the loader function.
570
+ */
571
+ export declare function runInsideLoaderRun<T>(run: LoaderRunIdentity, fn: () => T): T;
572
+ /** The innermost loader execution's identity record (runInsideLoaderRun). */
573
+ export declare function getLoaderRunIdentity(): LoaderRunIdentity | undefined;
574
+ /**
575
+ * The error a "use cache" function's read of a loader value fails with when
576
+ * the loader's execution, or one whose value it read, made `read` (#1011).
577
+ * Worded like guardIdentityRead's "use cache" refusal, naming the loaders.
578
+ */
579
+ export declare function useCacheLoaderIdentityError(read: LoaderIdentityRead, loaderId: string): Error;
525
580
  /** The error a loader cache() fill with no declared key fails with (#972). */
526
581
  export declare function loaderCacheIdentityError(read: LoaderIdentityRead, cachedLoaderId: string): Error;
527
582
  /**
@@ -608,10 +663,13 @@ export declare function assertCachedHeaderWriteAllowed(surface: string, surfaceP
608
663
  export declare function runInsideLoaderScope<T>(fn: () => T): T;
609
664
  /**
610
665
  * Run `fn` inside a loader BODY scope. Marks loader-function execution for the
611
- * cache-purity guard only (isInsideCacheScope), WITHOUT affecting
666
+ * cache() purity guard only (isInsideCacheScope), WITHOUT affecting
612
667
  * isInsideLoaderScope()/rendered() gating. Applied to every loader body (DSL
613
668
  * and handler-invoked via ctx.use) so request-scoped reads inside a loader
614
- * never trip the cache-scope guards — loaders always run fresh.
669
+ * never trip the cache() guard — a route cache() never stores loader values.
670
+ * A "use cache" body the loader was entered in still refuses them
671
+ * (guardIdentityRead); one that reads the value later refuses what the run
672
+ * recorded (runInsideLoaderRun, cache-tag.ts readStartedLoaderValue).
615
673
  */
616
674
  export declare function runInsideLoaderBodyScope<T>(fn: () => T, loaderId?: string, tags?: Set<string>): T;
617
675
  /** The innermost loader body's execution tag set (runInsideLoaderBodyScope). */
@@ -619,12 +677,19 @@ export declare function getLoaderBodyTags(): Set<string> | undefined;
619
677
  /**
620
678
  * The $$id of the loader whose body is currently executing, or undefined
621
679
  * outside any loader body. Used by the shell-capture identity guard
622
- * (assertNotInsideShellCapture) so its refusal warning can name the loader that read
680
+ * (guardIdentityRead) so its refusal warning can name the loader that read
623
681
  * cookies()/headers() instead of blaming a lane it cannot see — the old
624
682
  * hardcoded "bake-lane loader" text misled a live-lane debugging session
625
683
  * (issue #672, secondary).
626
684
  */
627
685
  export declare function getCurrentLoaderBodyId(): string | undefined;
686
+ /**
687
+ * The innermost loader body running here, or around it through the
688
+ * ctx.use(Loader) chain, whose id `match` accepts (HandleStore.push, the
689
+ * shell capture's push funnel). A body `stop` accepts, and `match` does not,
690
+ * ends the walk: nothing around it is returned.
691
+ */
692
+ export declare function findEnclosingLoaderBody(match: (loaderId: string) => boolean, stop?: (loaderId: string) => boolean): string | undefined;
628
693
  /**
629
694
  * True while `loaderId`'s body, or a loader it awaits via ctx.use at any
630
695
  * depth, is executing. The loader-level cache records these pushes
@@ -7,6 +7,8 @@
7
7
  * Writes append Set-Cookie to the response stub.
8
8
  */
9
9
  import type { CookieOptions } from "../router/middleware-types.js";
10
+ import type { Theme } from "../theme/types.js";
11
+ import { type RequestContext } from "./request-context.js";
10
12
  /**
11
13
  * A single cookie entry returned by get() and getAll().
12
14
  */
@@ -63,27 +65,37 @@ export interface ReadonlyHeaders {
63
65
  [Symbol.iterator](): HeadersIterator<[string, string]>;
64
66
  }
65
67
  type HeadersIterator<T> = IterableIterator<T>;
66
- /** The public reads of the visitor's theme cookie that assertThemeReadAllowed guards. */
68
+ /**
69
+ * Run the identity guard for a raw cookie read on `ctx`
70
+ * (request-context.ts `cookie()` / `cookies()`). Before #976 they were plain
71
+ * reads of the Cookie header that no shared scope refused. The guard reads
72
+ * the ambient context, as cookies() does, and falls back to `ctx`.
73
+ */
74
+ export declare function guardRawCookieRead(ctx: RequestContext<any>, surface: "getRequestContext().cookie()" | "getRequestContext().cookies()"): void;
75
+ /**
76
+ * Guard `request.headers` like headers() (#976): the request every ctx
77
+ * exposes (request context, handler, middleware and loader `ctx.request`)
78
+ * gets an own getter that runs guardIdentityRead against the ambient request
79
+ * context, so a read inside a ppr capture, a cache() boundary, a "use cache"
80
+ * body or an unkeyed loader cache() fill refuses as cookies() does. A Request
81
+ * argument keys a "use cache" entry by its URL only (cache-runtime.ts), so a
82
+ * header read there baked the first caller's value into the shared entry.
83
+ * The router's own reads go through requestHeaders() (request-headers.ts).
84
+ * Idempotent; returns `request`.
85
+ */
86
+ export declare function guardRequestHeaders(request: Request): Request;
87
+ /** The public reads of the visitor's theme cookie that readGuardedTheme guards. */
67
88
  export type ThemeReadSurface = "ctx.theme" | "getRequestContext().theme";
68
89
  /**
69
- * Guard for a read of the visitor's theme: the handler and middleware
70
- * `ctx.theme` (handler-context.ts, middleware.ts) and `getRequestContext().theme`
71
- * (request-context.ts). The theme is the visitor's theme cookie, so it is an
72
- * identity read like cookies(): it refuses in the same scopes, in the same
73
- * order (refusingCacheScope, then tripShellCaptureGuard in context.ts), with
74
- * the same exemption (a loader body under cache(); at capture there is none).
75
- * Before #971 each read was a plain cookie read, so a ppr shell, a cache()
76
- * entry or a "use cache" entry stored the first visitor's theme and served it
77
- * to every later visitor.
78
- *
79
- * A read the guards allow is recorded on the current loader execution, as a
80
- * cookies() read method records it (#972, recordLoaderIdentityRead).
81
- *
82
- * `ctx` is the request context at read time, as cookies() reads it. The
83
- * router's own payload read (payloadInitialTheme, rsc/full-payload.ts) goes
84
- * through the unguarded `_readTheme()`.
90
+ * `ctx`'s theme through guardIdentityRead: the one body of every public theme
91
+ * read (the handler and middleware `ctx.theme`, handler-context.ts and
92
+ * middleware.ts, and `getRequestContext().theme`, request-context.ts). The
93
+ * guard reads the ambient context, as cookies() does, and falls back to
94
+ * `ctx`; the value is `ctx`'s unguarded `_readTheme()`, which the router's
95
+ * own payload read (payloadInitialTheme, rsc/full-payload.ts) calls directly.
96
+ * Undefined without a theme config.
85
97
  */
86
- export declare function assertThemeReadAllowed(ctx: unknown, surface: ThemeReadSurface): void;
98
+ export declare function readGuardedTheme(ctx: RequestContext<any> | undefined, surface: ThemeReadSurface): Theme | undefined;
87
99
  /**
88
100
  * Get the original request headers (read-only).
89
101
  *
@@ -85,9 +85,60 @@ export interface HandleStore {
85
85
  * body (loader-cache.ts replayLoaderHandles). If that loader then runs live
86
86
  * in this request, its first push removes every value replayed for it and
87
87
  * takes the first one's position (later live pushes follow it), so the
88
- * handle output stays live without a duplicate.
88
+ * handle output stays live without a duplicate. A push counts as that
89
+ * loader's when it is made in its body, or in a body it entered that has
90
+ * no replayed values of its own (the capture credits a dependency's push
91
+ * under a live-lane loader to that loader); a hole's run that ends without
92
+ * one drops them (settleLoaderRun).
89
93
  */
90
94
  pushReplayed(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
95
+ /**
96
+ * push() a document HIT's copy of `loaderId`'s settled push, restored from
97
+ * the shell's doc record (handle-snapshot.ts restoreHandles). The record is
98
+ * authoritative for that loader's settled pushes: the prelude was rendered
99
+ * from it, and a run of the loader on the HIT reads the store, not the
100
+ * capture's values. So from then on this request drops every settled,
101
+ * thenable-free push the loader makes (live, or replayed from a cache
102
+ * entry, anywhere inside its body), and keeps the ones holding a thenable
103
+ * (holdsThenable: what the record could not keep, `runs`), placed among the
104
+ * restored copies in the loader's push order. Only bake-lane owners are
105
+ * restored this way (withCacheLookup): a live-lane loader is a hole.
106
+ */
107
+ pushRestored(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
108
+ /**
109
+ * The loaders the route runs on the live lane (liveLaneLoaderIds), from a
110
+ * PPR shell record's restore (handle-snapshot.ts restoreHandles): the
111
+ * holes. A push counts for a restored loader when that loader is the
112
+ * replayed one or the innermost enclosing loader body that restored
113
+ * copies; the walk out through enclosing bodies stops at a hole's body,
114
+ * and a replay of a hole's push counts for none. So a restored loader
115
+ * never takes a push made inside a hole it awaited, while a body inside the
116
+ * hole that restored copies of its own (a dependency the capture ran under
117
+ * a bake-lane loader) still takes its pushes.
118
+ */
119
+ markLiveLane(loaderIds: ReadonlySet<string>): void;
120
+ /**
121
+ * `loaderId`'s run in this request settled (resolved or rejected), its
122
+ * pushes made (loader-resolution.ts createLoaderExecutor). When the loader
123
+ * is a hole (markLiveLane), values replayed for it that no push of the run
124
+ * replaced are dropped: the run's output decides, so a hole that throws or
125
+ * skips its push shows none rather than the capture's. Any other loader's
126
+ * replayed values stay: a bake-lane loader's record is authoritative for
127
+ * its settled pushes, as its pin is for its data. Restored copies are not
128
+ * replays and stand.
129
+ */
130
+ settleLoaderRun(loaderId: string): void;
131
+ /**
132
+ * A hole's own cache() HIT (loader-cache.ts replayLoaderHandles, once it
133
+ * claims the hole): the values replayed for hole `loaderId` before (its
134
+ * shell copies, which restoreHandles leaves unclaimed, those of the
135
+ * dependencies credited to it included) give way to the pushes the entry
136
+ * recorded, none when it recorded none, so they match the entry's data.
137
+ * `deliver` makes the pushReplayed calls, which take the removed values'
138
+ * place in each array. Any other loader, or a hole with nothing replayed,
139
+ * delivers as a plain replay.
140
+ */
141
+ redeliverReplays(loaderId: string, deliver: () => void): void;
91
142
  /**
92
143
  * Get all collected handle data after all handlers have settled.
93
144
  * Waits for `settled` (handler lane), then returns the data at that point.
@@ -22,11 +22,12 @@ import { type MetricsStore } from "./context.js";
22
22
  import type { SegmentCacheStore } from "../cache/types.js";
23
23
  import type { Theme, ResolvedThemeConfig } from "../theme/types.js";
24
24
  import type { ExecutionContext, RequestScope } from "../types/request-scope.js";
25
- import type { TransitionWhenFn } from "../types/segments.js";
25
+ import type { TransitionWhenRecord } from "../router/transition-when.js";
26
26
  import type { ResolvedTracing } from "../router/tracing.js";
27
27
  import type { RenderMode, RenderPhase } from "../router/timeout.js";
28
28
  import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
29
29
  import type { RoutineTrace } from "../rsc/routine-plan.js";
30
+ import { type ExecutionStart } from "../cache/invalidation-order.js";
30
31
  export interface RenderForegroundCursor {
31
32
  mode: RenderMode;
32
33
  phase: RenderPhase;
@@ -86,10 +87,24 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
86
87
  dynamic(): void;
87
88
  /** @internal Request-local PPR opt-out marker set by ctx.dynamic(). */
88
89
  _dynamic?: boolean;
89
- /** @internal Get a cookie value (effective: request + response mutations). Use cookies().get() instead. */
90
+ /**
91
+ * @internal Get a cookie value (effective: request + response mutations).
92
+ * Use cookies().get() instead. Guarded like cookies() (#976).
93
+ */
90
94
  cookie(name: string): string | undefined;
91
- /** @internal Get all cookies (effective merged view). Use cookies().getAll() instead. */
95
+ /**
96
+ * @internal Get all cookies (effective merged view). Use
97
+ * cookies().getAll() instead. Guarded like cookies() (#976).
98
+ */
92
99
  cookies(): Record<string, string>;
100
+ /**
101
+ * @internal `cookie()` without the identity guard: the read behind the
102
+ * cookies() store, which guards at its own call and records per read
103
+ * method. Non-enumerable, like `_readTheme`.
104
+ */
105
+ _readCookie(name: string): string | undefined;
106
+ /** @internal `cookies()` without the identity guard (see `_readCookie`). */
107
+ _readCookies(): Record<string, string>;
93
108
  /** @internal Set a cookie on the response. Use cookies().set() instead. */
94
109
  setCookie(name: string, value: string, options?: CookieOptions): void;
95
110
  /** @internal Delete a cookie. Use cookies().delete() instead. */
@@ -119,19 +134,18 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
119
134
  /**
120
135
  * @internal The context createRequestContext() returned. A context derived
121
136
  * from it with Object.create (a PPR HIT tail, a shell capture, a background
122
- * revalidation render) inherits it, so per-request invalidation state
123
- * (tag-invalidation.ts, the stores' masks) is keyed by the request, not by
124
- * whichever derived object called or read (#973).
137
+ * revalidation render) inherits it, so per-request invalidation state (the
138
+ * stores' masks) is keyed by the request, not by whichever derived object
139
+ * called or read (#973).
125
140
  */
126
141
  _requestRoot?: RequestContext<any, any>;
127
142
  /**
128
- * @internal The tags this request invalidated with
129
- * updateTag()/revalidateTag(), each with its position in the invalidation
130
- * order (tag-invalidation.ts currentCacheSeq). Kept on _requestRoot. A
131
- * "use cache" execution that started before one of its own tags was
132
- * invalidated is neither joined nor written (cache-runtime.ts, #973).
143
+ * @internal Where the request started in the isolate's invalidation order
144
+ * (cache/invalidation-order.ts), taken when createRequestContext() ran. The
145
+ * document cache gates its write on it (#977): a middleware ahead of the
146
+ * document cache can read tagged data the document bakes.
133
147
  */
134
- _tagInvalidations?: Map<string, number>;
148
+ _requestStart?: ExecutionStart;
135
149
  /**
136
150
  * @internal The handler has handed the response to the host (rsc/handler.ts
137
151
  * `rango.response`): header and cookie writes after this are lost, as from
@@ -171,18 +185,13 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
171
185
  */
172
186
  readonly _handleStore: HandleStore;
173
187
  /**
174
- * @internal transition({ when }) predicates for segments matched this request,
175
- * keyed by segment id. Collected during resolution (the function is stripped
176
- * from the serialized segment config), then evaluated post-handler in
177
- * rsc-rendering — outside any cache scope — to drop the transition of any
178
- * segment whose predicate returns false.
188
+ * @internal transition({ when }) client references of the matched entry
189
+ * chain, keyed by segment id. Recorded at match time from the static route
190
+ * definition (router/transition-when.ts) and attached to the payload's
191
+ * segments right before Flight (rsc/attach-transition-when.ts). The server
192
+ * never calls them, and no cache or snapshot stores them.
179
193
  */
180
- _transitionWhen?: Array<{
181
- id: string;
182
- when: TransitionWhenFn;
183
- }>;
184
- /** @internal PPR transition decisions evaluated before cache lookup/handlers. */
185
- _pprTransitionDecisions?: Map<string, boolean>;
194
+ _transitionWhenRefs?: ReadonlyMap<string, TransitionWhenRecord>;
186
195
  /**
187
196
  * @internal Post-match serve-source truth for the PPR replay reporter.
188
197
  * Stamped from the match context as `intercept`, then overwritten as
@@ -206,8 +215,8 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
206
215
  * capture task's derived request context (built by shell-capture.ts). This is
207
216
  * the switch every capture-specific behavior reads: loader masking
208
217
  * (loader-mask.ts isShellCaptureActive / fresh.ts emitStreaming) and the
209
- * cookies()/headers() capture guard (cookie-store.ts
210
- * assertNotInsideShellCapture). The foreground render never sets it, so the
218
+ * identity-read capture guard (server/context.ts guardIdentityRead). The
219
+ * foreground render never sets it, so the
211
220
  * served response is byte-identical to axis 1. The capture descriptor itself
212
221
  * (key/ttl/swr/tags/store) is NOT threaded through the request context — the
213
222
  * integrated PPR serve path (rsc/shell-serve.ts + rsc-rendering.ts) builds it
@@ -232,6 +241,15 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
232
241
  * `runs: 1`, so a HIT still runs their bodies for those pushes.
233
242
  */
234
243
  _shellCaptureUnrecordedLoaderPush?: true;
244
+ /**
245
+ * @internal The lane of each loader the capture's matched route registers
246
+ * (loader-cache.ts routeLoaderLanes), set by createMatchContextForFull
247
+ * before any loader runs. The capture's push funnel credits a push made
248
+ * under a live-lane loader's body, at any depth, to that loader
249
+ * (shell-capture.ts deriveShellCaptureContext). Own property of the
250
+ * capture's derived context only.
251
+ */
252
+ _shellCaptureLoaderLanes?: ReadonlyMap<string, "live" | "bake">;
235
253
  /**
236
254
  * @internal Record keys resolved for this request (CacheScope
237
255
  * resolveKeyFrom): by the scope's `key()` (one result) or its store's
@@ -330,7 +348,9 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
330
348
  * scope replaces any route-derived cache() scope for the tail's match
331
349
  * (resolveShellImplicitCacheScope), and a lookup that does not hit throws
332
350
  * ShellRecordUnavailableError instead of resolving segments
333
- * (withCacheLookup): a HIT never runs a handler.
351
+ * (withCacheLookup): a HIT never runs a handler. The record's
352
+ * loader-owned handle pushes restore as authoritative
353
+ * (HandleStore.pushRestored): the prelude rendered them.
334
354
  */
335
355
  docTail?: true;
336
356
  /**
@@ -382,8 +402,9 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
382
402
  _shellFragmentPayload?: boolean;
383
403
  /**
384
404
  * @internal Set by the capture guard (server/context.ts
385
- * tripShellCaptureGuard) when it throws DURING a capture render: the read
386
- * ("cookies()", "headers()", "ctx.get()", "ctx.theme") and the fix the
405
+ * guardIdentityRead) when it throws DURING a capture render: the read
406
+ * ("cookies()", "headers()", `ctx.get() for a non-cacheable variable`,
407
+ * "ctx.theme") and the fix the
387
408
  * refusal warning gives for it. Load-bearing for the
388
409
  * bake lane: a guard throw inside an executing loader is swallowed by
389
410
  * wrapLoaderPromise into per-loader error UI, which would otherwise bake
@@ -512,11 +533,24 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
512
533
  /**
513
534
  * @internal The theme cookie (or the default) read with no identity guard.
514
535
  * The guarded reads (`theme` here, the handler and middleware `ctx.theme`)
515
- * call it after assertThemeReadAllowed; the router's own payload read goes
516
- * through payloadInitialTheme (rsc/full-payload.ts). Undefined without
536
+ * call it after guardIdentityRead (readGuardedTheme); the router's own payload read goes
537
+ * through payloadInitialTheme (rsc/full-payload.ts), except the unmatched
538
+ * route's 404 (rsc/handler.ts), which is never stored. Undefined without
517
539
  * theme config.
518
540
  */
519
541
  _readTheme(): Theme | undefined;
542
+ /**
543
+ * @internal Set by the document-cache middleware (cache/document-cache.ts)
544
+ * before it runs a render whose response it may store: the MISS and the
545
+ * stale refresh. payloadInitialTheme reads it (#978).
546
+ */
547
+ _documentCacheRender?: boolean;
548
+ /**
549
+ * @internal Set by payloadInitialTheme when the document payload carries
550
+ * the visitor's theme and it differs from the no-cookie default. The
551
+ * document cache does not store that response (#978).
552
+ */
553
+ _payloadVisitorTheme?: boolean;
520
554
  /**
521
555
  * Attach location state entries to the current response.
522
556
  *
@@ -551,19 +585,6 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
551
585
  _routeName?: string;
552
586
  /** @internal Previous route key (from the navigation source), used for revalidation */
553
587
  _prevRouteKey?: string;
554
- /**
555
- * @internal Navigation/action source data the transition({ when }) gate reads
556
- * to build its ShouldRevalidateFn-shaped predicate context. currentUrl/Params
557
- * come from the navigation snapshot (set at match time); action* are stashed
558
- * at the action-bearing gate call sites. All undefined when there is no source
559
- * (initial full load) or no action (plain navigation).
560
- */
561
- _gateCurrentUrl?: URL;
562
- _gateCurrentParams?: Record<string, string>;
563
- _gateActionId?: string;
564
- _gateActionUrl?: URL;
565
- _gateActionResult?: unknown;
566
- _gateFormData?: FormData;
567
588
  /**
568
589
  * @internal True while the post-action revalidation render is running (set by
569
590
  * revalidateAfterAction). The "use cache" runtime reads this to prefer
@@ -727,7 +748,7 @@ export interface RouteRecordWindow {
727
748
  * This is the type exported to library consumers. Internal code should
728
749
  * use the full RequestContext interface directly.
729
750
  */
730
- export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhen" | "_pprTransitionDecisions" | "_pprReplayPostMatchReason" | "_cacheStore" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_locationState" | "_routeName" | "_prevRouteKey" | "_gateCurrentUrl" | "_gateCurrentParams" | "_gateActionId" | "_gateActionUrl" | "_gateActionResult" | "_gateFormData" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_tagInvalidations" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
751
+ export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureUnrecordedLoaderPush" | "_shellCaptureLoaderLanes" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_routeRecordWindow" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_locationState" | "_routeName" | "_prevRouteKey" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
731
752
  /**
732
753
  * Marker for a waitUntil-scheduled fn whose task promise must NOT enter
733
754
  * _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
@@ -762,7 +783,7 @@ export declare function setRequestContextParams(params: Record<string, string>,
762
783
  * route key available for revalidation and intercept evaluation.
763
784
  * @internal
764
785
  */
765
- export declare function setRequestContextPrevRouteKey(prevRouteKey: string | undefined, currentUrl?: URL, currentParams?: Record<string, string>): void;
786
+ export declare function setRequestContextPrevRouteKey(prevRouteKey: string | undefined): void;
766
787
  /**
767
788
  * Get accumulated location state entries from the current request context.
768
789
  * Returns undefined if no state has been set.