@rangojs/router 0.4.0 → 0.4.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 (482) hide show
  1. package/README.md +19 -1
  2. package/dist/types/browser/event-controller.d.ts +4 -0
  3. package/dist/types/browser/link-interceptor.d.ts +17 -7
  4. package/dist/types/browser/navigation-bridge.d.ts +13 -1
  5. package/dist/types/browser/notify-listeners.d.ts +2 -0
  6. package/dist/types/browser/prefetch/cache.d.ts +1 -1
  7. package/dist/types/browser/prefetch/default-strategy.d.ts +12 -3
  8. package/dist/types/browser/prefetch/invalidation.d.ts +6 -0
  9. package/dist/types/browser/prefetch/loader.d.ts +3 -1
  10. package/dist/types/browser/prefetch/observer.d.ts +3 -6
  11. package/dist/types/browser/rango-state.d.ts +4 -0
  12. package/dist/types/browser/react/Link.d.ts +4 -9
  13. package/dist/types/browser/react/context.d.ts +3 -0
  14. package/dist/types/browser/rsc-router.d.ts +7 -2
  15. package/dist/types/browser/types.d.ts +1 -0
  16. package/dist/types/cache/cache-key-utils.d.ts +11 -3
  17. package/dist/types/cache/cache-scope.d.ts +82 -3
  18. package/dist/types/cache/cf/cf-cache-store.d.ts +2 -2
  19. package/dist/types/cache/index.d.ts +3 -1
  20. package/dist/types/cache/search-params-filter.d.ts +64 -0
  21. package/dist/types/cache/shell-snapshot.d.ts +4 -4
  22. package/dist/types/cache/types.d.ts +30 -2
  23. package/dist/types/cache/vercel/vercel-cache-store.d.ts +2 -2
  24. package/dist/types/index.d.ts +1 -0
  25. package/dist/types/index.rsc.d.ts +1 -0
  26. package/dist/types/router/match-middleware/cache-lookup.d.ts +13 -0
  27. package/dist/types/router/navigation-snapshot.d.ts +29 -0
  28. package/dist/types/router/router-options.d.ts +27 -3
  29. package/dist/types/rsc/shell-build-manifest.d.ts +7 -1
  30. package/dist/types/rsc/shell-serve.d.ts +7 -1
  31. package/dist/types/rsc/types.d.ts +17 -0
  32. package/dist/types/server/request-context.d.ts +57 -4
  33. package/dist/types/testing/render-route.d.ts +10 -1
  34. package/dist/types/testing/shell-status.d.ts +6 -3
  35. package/dist/types/vite/plugin-types.d.ts +1 -1
  36. package/dist/vite/index.js +5 -5
  37. package/package.json +23 -22
  38. package/skills/caching/SKILL.md +39 -0
  39. package/skills/comparison/references/framework-comparison.md +7 -1
  40. package/skills/links/SKILL.md +24 -0
  41. package/skills/ppr/SKILL.md +53 -4
  42. package/skills/router-setup/SKILL.md +7 -2
  43. package/skills/testing/client-components.md +15 -14
  44. package/skills/vercel/SKILL.md +1 -1
  45. package/src/browser/event-controller.ts +110 -11
  46. package/src/browser/link-interceptor.ts +469 -20
  47. package/src/browser/navigation-bridge.ts +71 -2
  48. package/src/browser/navigation-store.ts +24 -1
  49. package/src/browser/notify-listeners.ts +22 -0
  50. package/src/browser/prefetch/cache.ts +4 -2
  51. package/src/browser/prefetch/default-strategy.ts +43 -3
  52. package/src/browser/prefetch/invalidation.ts +30 -0
  53. package/src/browser/prefetch/loader.ts +19 -12
  54. package/src/browser/prefetch/observer.ts +50 -22
  55. package/src/browser/rango-state.ts +21 -0
  56. package/src/browser/react/Link.tsx +97 -88
  57. package/src/browser/react/NavigationProvider.tsx +1 -0
  58. package/src/browser/react/context.ts +4 -0
  59. package/src/browser/rsc-router.tsx +22 -9
  60. package/src/browser/types.ts +1 -0
  61. package/src/cache/cache-key-utils.ts +18 -4
  62. package/src/cache/cache-runtime.ts +7 -2
  63. package/src/cache/cache-scope.ts +152 -23
  64. package/src/cache/cf/cf-cache-store.ts +51 -16
  65. package/src/cache/document-cache.ts +7 -1
  66. package/src/cache/index.ts +7 -0
  67. package/src/cache/search-params-filter.ts +118 -0
  68. package/src/cache/shell-snapshot.ts +8 -4
  69. package/src/cache/types.ts +33 -2
  70. package/src/cache/vercel/vercel-cache-store.ts +17 -3
  71. package/src/index.rsc.ts +4 -0
  72. package/src/index.ts +6 -0
  73. package/src/router/match-middleware/cache-lookup.ts +146 -33
  74. package/src/router/match-middleware/cache-store.ts +70 -0
  75. package/src/router/navigation-snapshot.ts +46 -6
  76. package/src/router/router-options.ts +31 -4
  77. package/src/rsc/handler.ts +9 -0
  78. package/src/rsc/response-cache-serve.ts +1 -1
  79. package/src/rsc/rsc-rendering.ts +252 -27
  80. package/src/rsc/shell-build-manifest.ts +8 -1
  81. package/src/rsc/shell-capture.ts +5 -0
  82. package/src/rsc/shell-serve.ts +8 -2
  83. package/src/rsc/types.ts +17 -0
  84. package/src/server/request-context.ts +62 -3
  85. package/src/testing/dispatch.ts +21 -3
  86. package/src/testing/render-route.tsx +86 -17
  87. package/src/testing/shell-status.ts +20 -3
  88. package/src/vite/plugin-types.ts +1 -1
  89. package/src/vite/plugins/vercel-output.ts +2 -2
  90. package/dist/types.backup/__internal.d.ts +0 -127
  91. package/dist/types.backup/bin/rango.d.ts +0 -1
  92. package/dist/types.backup/browser/action-coordinator.d.ts +0 -57
  93. package/dist/types.backup/browser/action-fence.d.ts +0 -33
  94. package/dist/types.backup/browser/app-shell.d.ts +0 -34
  95. package/dist/types.backup/browser/app-version.d.ts +0 -6
  96. package/dist/types.backup/browser/connection-warmup.d.ts +0 -31
  97. package/dist/types.backup/browser/cookie-name.d.ts +0 -66
  98. package/dist/types.backup/browser/event-controller.d.ts +0 -221
  99. package/dist/types.backup/browser/history-state.d.ts +0 -26
  100. package/dist/types.backup/browser/index.d.ts +0 -1
  101. package/dist/types.backup/browser/intercept-utils.d.ts +0 -30
  102. package/dist/types.backup/browser/invalidate-client-cache.d.ts +0 -17
  103. package/dist/types.backup/browser/link-interceptor.d.ts +0 -43
  104. package/dist/types.backup/browser/logging.d.ts +0 -33
  105. package/dist/types.backup/browser/merge-segment-loaders.d.ts +0 -38
  106. package/dist/types.backup/browser/navigation-bridge.d.ts +0 -27
  107. package/dist/types.backup/browser/navigation-client.d.ts +0 -17
  108. package/dist/types.backup/browser/navigation-store-handle.d.ts +0 -25
  109. package/dist/types.backup/browser/navigation-store.d.ts +0 -95
  110. package/dist/types.backup/browser/navigation-transaction.d.ts +0 -75
  111. package/dist/types.backup/browser/network-error-handler.d.ts +0 -35
  112. package/dist/types.backup/browser/partial-update.d.ts +0 -61
  113. package/dist/types.backup/browser/prefetch/cache.d.ts +0 -183
  114. package/dist/types.backup/browser/prefetch/fetch.d.ts +0 -52
  115. package/dist/types.backup/browser/prefetch/observer.d.ts +0 -27
  116. package/dist/types.backup/browser/prefetch/policy.d.ts +0 -13
  117. package/dist/types.backup/browser/prefetch/queue.d.ts +0 -48
  118. package/dist/types.backup/browser/prefetch/resource-ready.d.ts +0 -28
  119. package/dist/types.backup/browser/rango-state.d.ts +0 -52
  120. package/dist/types.backup/browser/react/Link.d.ts +0 -140
  121. package/dist/types.backup/browser/react/NavigationProvider.d.ts +0 -88
  122. package/dist/types.backup/browser/react/ScrollRestoration.d.ts +0 -78
  123. package/dist/types.backup/browser/react/context.d.ts +0 -54
  124. package/dist/types.backup/browser/react/filter-segment-order.d.ts +0 -35
  125. package/dist/types.backup/browser/react/index.d.ts +0 -1
  126. package/dist/types.backup/browser/react/location-state-shared.d.ts +0 -162
  127. package/dist/types.backup/browser/react/location-state.d.ts +0 -29
  128. package/dist/types.backup/browser/react/mount-context.d.ts +0 -23
  129. package/dist/types.backup/browser/react/nonce-context.d.ts +0 -14
  130. package/dist/types.backup/browser/react/shallow-equal.d.ts +0 -5
  131. package/dist/types.backup/browser/react/use-action.d.ts +0 -61
  132. package/dist/types.backup/browser/react/use-handle.d.ts +0 -21
  133. package/dist/types.backup/browser/react/use-href.d.ts +0 -32
  134. package/dist/types.backup/browser/react/use-link-status.d.ts +0 -36
  135. package/dist/types.backup/browser/react/use-mount.d.ts +0 -24
  136. package/dist/types.backup/browser/react/use-navigation.d.ts +0 -15
  137. package/dist/types.backup/browser/react/use-params.d.ts +0 -21
  138. package/dist/types.backup/browser/react/use-pathname.d.ts +0 -13
  139. package/dist/types.backup/browser/react/use-reverse.d.ts +0 -40
  140. package/dist/types.backup/browser/react/use-router.d.ts +0 -23
  141. package/dist/types.backup/browser/react/use-search-params.d.ts +0 -19
  142. package/dist/types.backup/browser/react/use-segments.d.ts +0 -29
  143. package/dist/types.backup/browser/response-adapter.d.ts +0 -58
  144. package/dist/types.backup/browser/rsc-router.d.ts +0 -141
  145. package/dist/types.backup/browser/scroll-restoration.d.ts +0 -103
  146. package/dist/types.backup/browser/segment-reconciler.d.ts +0 -74
  147. package/dist/types.backup/browser/segment-structure-assert.d.ts +0 -16
  148. package/dist/types.backup/browser/server-action-bridge.d.ts +0 -29
  149. package/dist/types.backup/browser/types.d.ts +0 -530
  150. package/dist/types.backup/browser/validate-redirect-origin.d.ts +0 -28
  151. package/dist/types.backup/build/collect-fallback-refs.d.ts +0 -5
  152. package/dist/types.backup/build/generate-manifest.d.ts +0 -100
  153. package/dist/types.backup/build/generate-route-types.d.ts +0 -8
  154. package/dist/types.backup/build/index.d.ts +0 -21
  155. package/dist/types.backup/build/prefix-tree-utils.d.ts +0 -56
  156. package/dist/types.backup/build/route-trie.d.ts +0 -89
  157. package/dist/types.backup/build/route-types/ast-helpers.d.ts +0 -3
  158. package/dist/types.backup/build/route-types/ast-route-extraction.d.ts +0 -13
  159. package/dist/types.backup/build/route-types/codegen.d.ts +0 -16
  160. package/dist/types.backup/build/route-types/include-resolution.d.ts +0 -74
  161. package/dist/types.backup/build/route-types/param-extraction.d.ts +0 -13
  162. package/dist/types.backup/build/route-types/per-module-writer.d.ts +0 -18
  163. package/dist/types.backup/build/route-types/router-processing.d.ts +0 -82
  164. package/dist/types.backup/build/route-types/scan-filter.d.ts +0 -17
  165. package/dist/types.backup/build/route-types/source-scan.d.ts +0 -13
  166. package/dist/types.backup/build/runtime-discovery.d.ts +0 -24
  167. package/dist/types.backup/cache/background-task.d.ts +0 -21
  168. package/dist/types.backup/cache/cache-error.d.ts +0 -71
  169. package/dist/types.backup/cache/cache-key-utils.d.ts +0 -35
  170. package/dist/types.backup/cache/cache-policy.d.ts +0 -59
  171. package/dist/types.backup/cache/cache-runtime.d.ts +0 -51
  172. package/dist/types.backup/cache/cache-scope.d.ts +0 -134
  173. package/dist/types.backup/cache/cache-tag.d.ts +0 -79
  174. package/dist/types.backup/cache/cf/cf-base64.d.ts +0 -4
  175. package/dist/types.backup/cache/cf/cf-cache-constants.d.ts +0 -105
  176. package/dist/types.backup/cache/cf/cf-cache-store.d.ts +0 -481
  177. package/dist/types.backup/cache/cf/cf-cache-types.d.ts +0 -300
  178. package/dist/types.backup/cache/cf/cf-kv-utils.d.ts +0 -22
  179. package/dist/types.backup/cache/cf/cf-tag-marker-memo.d.ts +0 -15
  180. package/dist/types.backup/cache/cf/index.d.ts +0 -3
  181. package/dist/types.backup/cache/document-cache.d.ts +0 -69
  182. package/dist/types.backup/cache/handle-capture.d.ts +0 -23
  183. package/dist/types.backup/cache/handle-snapshot.d.ts +0 -39
  184. package/dist/types.backup/cache/index.d.ts +0 -7
  185. package/dist/types.backup/cache/memory-segment-store.d.ts +0 -163
  186. package/dist/types.backup/cache/profile-registry.d.ts +0 -40
  187. package/dist/types.backup/cache/read-through-swr.d.ts +0 -60
  188. package/dist/types.backup/cache/segment-codec.d.ts +0 -78
  189. package/dist/types.backup/cache/shell-snapshot.d.ts +0 -162
  190. package/dist/types.backup/cache/tag-invalidation.d.ts +0 -74
  191. package/dist/types.backup/cache/taint.d.ts +0 -71
  192. package/dist/types.backup/cache/types.d.ts +0 -407
  193. package/dist/types.backup/cache/vercel/index.d.ts +0 -1
  194. package/dist/types.backup/cache/vercel/vercel-cache-store.d.ts +0 -267
  195. package/dist/types.backup/client.d.ts +0 -184
  196. package/dist/types.backup/client.rsc.d.ts +0 -39
  197. package/dist/types.backup/cloudflare/index.d.ts +0 -7
  198. package/dist/types.backup/cloudflare/tracing.d.ts +0 -53
  199. package/dist/types.backup/component-utils.d.ts +0 -46
  200. package/dist/types.backup/components/DefaultDocument.d.ts +0 -13
  201. package/dist/types.backup/context-var.d.ts +0 -84
  202. package/dist/types.backup/debug.d.ts +0 -57
  203. package/dist/types.backup/decode-loader-results.d.ts +0 -5
  204. package/dist/types.backup/default-error-boundary.d.ts +0 -10
  205. package/dist/types.backup/defer.d.ts +0 -89
  206. package/dist/types.backup/deps/browser.d.ts +0 -1
  207. package/dist/types.backup/deps/html-stream-client.d.ts +0 -1
  208. package/dist/types.backup/deps/html-stream-server.d.ts +0 -1
  209. package/dist/types.backup/deps/rsc.d.ts +0 -1
  210. package/dist/types.backup/deps/ssr.d.ts +0 -1
  211. package/dist/types.backup/encode-kv.d.ts +0 -35
  212. package/dist/types.backup/errors.d.ts +0 -226
  213. package/dist/types.backup/escape-script.d.ts +0 -44
  214. package/dist/types.backup/handle.d.ts +0 -93
  215. package/dist/types.backup/handles/MetaTags.d.ts +0 -17
  216. package/dist/types.backup/handles/Scripts.d.ts +0 -38
  217. package/dist/types.backup/handles/breadcrumbs.d.ts +0 -43
  218. package/dist/types.backup/handles/deferred-resolution.d.ts +0 -53
  219. package/dist/types.backup/handles/is-thenable.d.ts +0 -12
  220. package/dist/types.backup/handles/meta.d.ts +0 -43
  221. package/dist/types.backup/handles/script.d.ts +0 -139
  222. package/dist/types.backup/host/cookie-handler.d.ts +0 -8
  223. package/dist/types.backup/host/errors.d.ts +0 -40
  224. package/dist/types.backup/host/index.d.ts +0 -33
  225. package/dist/types.backup/host/pattern-matcher.d.ts +0 -30
  226. package/dist/types.backup/host/router.d.ts +0 -12
  227. package/dist/types.backup/host/testing.d.ts +0 -41
  228. package/dist/types.backup/host/types.d.ts +0 -148
  229. package/dist/types.backup/host/utils.d.ts +0 -20
  230. package/dist/types.backup/href-client.d.ts +0 -214
  231. package/dist/types.backup/index.d.ts +0 -112
  232. package/dist/types.backup/index.rsc.d.ts +0 -51
  233. package/dist/types.backup/internal-debug.d.ts +0 -1
  234. package/dist/types.backup/loader-store.d.ts +0 -193
  235. package/dist/types.backup/loader.d.ts +0 -18
  236. package/dist/types.backup/loader.rsc.d.ts +0 -18
  237. package/dist/types.backup/missing-id-error.d.ts +0 -1
  238. package/dist/types.backup/outlet-context.d.ts +0 -12
  239. package/dist/types.backup/outlet-provider.d.ts +0 -12
  240. package/dist/types.backup/prerender/build-shell-capture.d.ts +0 -104
  241. package/dist/types.backup/prerender/param-hash.d.ts +0 -6
  242. package/dist/types.backup/prerender/shell-manifest-key.d.ts +0 -18
  243. package/dist/types.backup/prerender/store.d.ts +0 -62
  244. package/dist/types.backup/prerender.d.ts +0 -292
  245. package/dist/types.backup/redirect-origin.d.ts +0 -55
  246. package/dist/types.backup/regex-escape.d.ts +0 -6
  247. package/dist/types.backup/render-error-thrower.d.ts +0 -13
  248. package/dist/types.backup/response-utils.d.ts +0 -35
  249. package/dist/types.backup/reverse.d.ts +0 -206
  250. package/dist/types.backup/root-error-boundary.d.ts +0 -32
  251. package/dist/types.backup/route-content-wrapper.d.ts +0 -40
  252. package/dist/types.backup/route-definition/dsl-helpers.d.ts +0 -130
  253. package/dist/types.backup/route-definition/helper-factories.d.ts +0 -22
  254. package/dist/types.backup/route-definition/helpers-types.d.ts +0 -392
  255. package/dist/types.backup/route-definition/index.d.ts +0 -7
  256. package/dist/types.backup/route-definition/redirect.d.ts +0 -48
  257. package/dist/types.backup/route-definition/resolve-handler-use.d.ts +0 -19
  258. package/dist/types.backup/route-definition/use-item-types.d.ts +0 -1
  259. package/dist/types.backup/route-definition.d.ts +0 -1
  260. package/dist/types.backup/route-map-builder.d.ts +0 -127
  261. package/dist/types.backup/route-name.d.ts +0 -27
  262. package/dist/types.backup/route-types.d.ts +0 -172
  263. package/dist/types.backup/router/basename.d.ts +0 -10
  264. package/dist/types.backup/router/content-negotiation.d.ts +0 -91
  265. package/dist/types.backup/router/debug-manifest.d.ts +0 -7
  266. package/dist/types.backup/router/error-handling.d.ts +0 -76
  267. package/dist/types.backup/router/find-match.d.ts +0 -19
  268. package/dist/types.backup/router/handler-context.d.ts +0 -41
  269. package/dist/types.backup/router/instrument.d.ts +0 -161
  270. package/dist/types.backup/router/intercept-resolution.d.ts +0 -79
  271. package/dist/types.backup/router/lazy-includes.d.ts +0 -26
  272. package/dist/types.backup/router/loader-resolution.d.ts +0 -63
  273. package/dist/types.backup/router/logging.d.ts +0 -41
  274. package/dist/types.backup/router/manifest.d.ts +0 -8
  275. package/dist/types.backup/router/match-api.d.ts +0 -19
  276. package/dist/types.backup/router/match-context.d.ts +0 -184
  277. package/dist/types.backup/router/match-handlers.d.ts +0 -49
  278. package/dist/types.backup/router/match-middleware/background-revalidation.d.ts +0 -113
  279. package/dist/types.backup/router/match-middleware/cache-lookup.d.ts +0 -113
  280. package/dist/types.backup/router/match-middleware/cache-store.d.ts +0 -112
  281. package/dist/types.backup/router/match-middleware/index.d.ts +0 -80
  282. package/dist/types.backup/router/match-middleware/intercept-resolution.d.ts +0 -116
  283. package/dist/types.backup/router/match-middleware/segment-resolution.d.ts +0 -94
  284. package/dist/types.backup/router/match-pipelines.d.ts +0 -103
  285. package/dist/types.backup/router/match-result.d.ts +0 -114
  286. package/dist/types.backup/router/metrics.d.ts +0 -6
  287. package/dist/types.backup/router/middleware-types.d.ts +0 -74
  288. package/dist/types.backup/router/middleware.d.ts +0 -116
  289. package/dist/types.backup/router/navigation-snapshot.d.ts +0 -22
  290. package/dist/types.backup/router/params-util.d.ts +0 -8
  291. package/dist/types.backup/router/parse-pattern.d.ts +0 -38
  292. package/dist/types.backup/router/pattern-matching.d.ts +0 -169
  293. package/dist/types.backup/router/prefetch-cache-ttl.d.ts +0 -27
  294. package/dist/types.backup/router/prefetch-limits.d.ts +0 -20
  295. package/dist/types.backup/router/prerender-match.d.ts +0 -50
  296. package/dist/types.backup/router/preview-match.d.ts +0 -22
  297. package/dist/types.backup/router/request-classification.d.ts +0 -104
  298. package/dist/types.backup/router/revalidation.d.ts +0 -57
  299. package/dist/types.backup/router/route-snapshot.d.ts +0 -112
  300. package/dist/types.backup/router/router-context.d.ts +0 -137
  301. package/dist/types.backup/router/router-interfaces.d.ts +0 -432
  302. package/dist/types.backup/router/router-options.d.ts +0 -738
  303. package/dist/types.backup/router/router-registry.d.ts +0 -15
  304. package/dist/types.backup/router/segment-resolution/fresh.d.ts +0 -55
  305. package/dist/types.backup/router/segment-resolution/helpers.d.ts +0 -93
  306. package/dist/types.backup/router/segment-resolution/loader-cache.d.ts +0 -33
  307. package/dist/types.backup/router/segment-resolution/loader-mask.d.ts +0 -44
  308. package/dist/types.backup/router/segment-resolution/loader-snapshot.d.ts +0 -90
  309. package/dist/types.backup/router/segment-resolution/mask-nested.d.ts +0 -53
  310. package/dist/types.backup/router/segment-resolution/revalidation.d.ts +0 -85
  311. package/dist/types.backup/router/segment-resolution/static-store.d.ts +0 -17
  312. package/dist/types.backup/router/segment-resolution/streamed-handler-telemetry.d.ts +0 -16
  313. package/dist/types.backup/router/segment-resolution/view-transition-default.d.ts +0 -28
  314. package/dist/types.backup/router/segment-resolution.d.ts +0 -3
  315. package/dist/types.backup/router/segment-wrappers.d.ts +0 -53
  316. package/dist/types.backup/router/state-cookie-name.d.ts +0 -1
  317. package/dist/types.backup/router/substitute-pattern-params.d.ts +0 -23
  318. package/dist/types.backup/router/telemetry-otel.d.ts +0 -113
  319. package/dist/types.backup/router/telemetry.d.ts +0 -215
  320. package/dist/types.backup/router/timeout.d.ts +0 -68
  321. package/dist/types.backup/router/tracing.d.ts +0 -125
  322. package/dist/types.backup/router/trie-matching.d.ts +0 -32
  323. package/dist/types.backup/router/types.d.ts +0 -98
  324. package/dist/types.backup/router/url-params.d.ts +0 -26
  325. package/dist/types.backup/router.d.ts +0 -7
  326. package/dist/types.backup/rsc/capture-queue.d.ts +0 -6
  327. package/dist/types.backup/rsc/full-payload.d.ts +0 -22
  328. package/dist/types.backup/rsc/handler-context.d.ts +0 -31
  329. package/dist/types.backup/rsc/handler.d.ts +0 -9
  330. package/dist/types.backup/rsc/helpers.d.ts +0 -213
  331. package/dist/types.backup/rsc/index.d.ts +0 -17
  332. package/dist/types.backup/rsc/json-route-result.d.ts +0 -20
  333. package/dist/types.backup/rsc/loader-fetch.d.ts +0 -14
  334. package/dist/types.backup/rsc/manifest-init.d.ts +0 -18
  335. package/dist/types.backup/rsc/nonce.d.ts +0 -28
  336. package/dist/types.backup/rsc/origin-guard.d.ts +0 -50
  337. package/dist/types.backup/rsc/progressive-enhancement.d.ts +0 -19
  338. package/dist/types.backup/rsc/redirect-guard.d.ts +0 -35
  339. package/dist/types.backup/rsc/response-cache-serve.d.ts +0 -46
  340. package/dist/types.backup/rsc/response-error.d.ts +0 -19
  341. package/dist/types.backup/rsc/response-route-handler.d.ts +0 -29
  342. package/dist/types.backup/rsc/rsc-rendering.d.ts +0 -23
  343. package/dist/types.backup/rsc/runtime-warnings.d.ts +0 -22
  344. package/dist/types.backup/rsc/server-action.d.ts +0 -68
  345. package/dist/types.backup/rsc/shell-build-manifest.d.ts +0 -84
  346. package/dist/types.backup/rsc/shell-capture-constants.d.ts +0 -27
  347. package/dist/types.backup/rsc/shell-capture.d.ts +0 -374
  348. package/dist/types.backup/rsc/shell-serve.d.ts +0 -136
  349. package/dist/types.backup/rsc/ssr-setup.d.ts +0 -48
  350. package/dist/types.backup/rsc/transition-gate.d.ts +0 -27
  351. package/dist/types.backup/rsc/types.d.ts +0 -290
  352. package/dist/types.backup/runtime-env.d.ts +0 -1
  353. package/dist/types.backup/search-params.d.ts +0 -125
  354. package/dist/types.backup/segment-content-promise.d.ts +0 -13
  355. package/dist/types.backup/segment-fragments.d.ts +0 -56
  356. package/dist/types.backup/segment-loader-promise.d.ts +0 -22
  357. package/dist/types.backup/segment-system.d.ts +0 -84
  358. package/dist/types.backup/serialize.d.ts +0 -164
  359. package/dist/types.backup/server/context.d.ts +0 -494
  360. package/dist/types.backup/server/cookie-parse.d.ts +0 -10
  361. package/dist/types.backup/server/cookie-store.d.ts +0 -107
  362. package/dist/types.backup/server/fetchable-loader-store.d.ts +0 -20
  363. package/dist/types.backup/server/handle-store.d.ts +0 -100
  364. package/dist/types.backup/server/loader-registry.d.ts +0 -32
  365. package/dist/types.backup/server/request-context.d.ts +0 -596
  366. package/dist/types.backup/server/root-layout.d.ts +0 -3
  367. package/dist/types.backup/server.d.ts +0 -15
  368. package/dist/types.backup/ssr/index.d.ts +0 -233
  369. package/dist/types.backup/ssr/inject-rsc-eager.d.ts +0 -3
  370. package/dist/types.backup/ssr/preinit-client-references.d.ts +0 -71
  371. package/dist/types.backup/ssr/ssr-root.d.ts +0 -69
  372. package/dist/types.backup/static-handler.d.ts +0 -57
  373. package/dist/types.backup/testing/cache-status.d.ts +0 -63
  374. package/dist/types.backup/testing/collect-handle.d.ts +0 -20
  375. package/dist/types.backup/testing/dispatch.d.ts +0 -123
  376. package/dist/types.backup/testing/dom.entry.d.ts +0 -15
  377. package/dist/types.backup/testing/e2e/fixture.d.ts +0 -37
  378. package/dist/types.backup/testing/e2e/index.d.ts +0 -30
  379. package/dist/types.backup/testing/e2e/matchers.d.ts +0 -17
  380. package/dist/types.backup/testing/e2e/page-helpers.d.ts +0 -62
  381. package/dist/types.backup/testing/e2e/parity.d.ts +0 -111
  382. package/dist/types.backup/testing/e2e/server.d.ts +0 -35
  383. package/dist/types.backup/testing/flight-matchers.d.ts +0 -55
  384. package/dist/types.backup/testing/flight-normalize.d.ts +0 -1
  385. package/dist/types.backup/testing/flight-tree.d.ts +0 -192
  386. package/dist/types.backup/testing/flight.d.ts +0 -115
  387. package/dist/types.backup/testing/flight.entry.d.ts +0 -27
  388. package/dist/types.backup/testing/generated-routes.d.ts +0 -66
  389. package/dist/types.backup/testing/index.d.ts +0 -52
  390. package/dist/types.backup/testing/internal/context.d.ts +0 -225
  391. package/dist/types.backup/testing/internal/flight-client-globals.d.ts +0 -1
  392. package/dist/types.backup/testing/internal/seed-vars.d.ts +0 -30
  393. package/dist/types.backup/testing/render-handler.d.ts +0 -160
  394. package/dist/types.backup/testing/render-route.d.ts +0 -246
  395. package/dist/types.backup/testing/run-loader.d.ts +0 -186
  396. package/dist/types.backup/testing/run-middleware.d.ts +0 -132
  397. package/dist/types.backup/testing/run-transition-when.d.ts +0 -77
  398. package/dist/types.backup/testing/vitest-stubs/cloudflare-email.d.ts +0 -6
  399. package/dist/types.backup/testing/vitest-stubs/cloudflare-workers.d.ts +0 -13
  400. package/dist/types.backup/testing/vitest-stubs/plugin-rsc.d.ts +0 -7
  401. package/dist/types.backup/testing/vitest-stubs/version.d.ts +0 -1
  402. package/dist/types.backup/testing/vitest.d.ts +0 -205
  403. package/dist/types.backup/theme/ThemeProvider.d.ts +0 -13
  404. package/dist/types.backup/theme/ThemeScript.d.ts +0 -45
  405. package/dist/types.backup/theme/constants.d.ts +0 -39
  406. package/dist/types.backup/theme/index.d.ts +0 -29
  407. package/dist/types.backup/theme/theme-context.d.ts +0 -21
  408. package/dist/types.backup/theme/theme-script.d.ts +0 -26
  409. package/dist/types.backup/theme/types.d.ts +0 -162
  410. package/dist/types.backup/theme/use-theme.d.ts +0 -8
  411. package/dist/types.backup/types/boundaries.d.ts +0 -93
  412. package/dist/types.backup/types/cache-types.d.ts +0 -191
  413. package/dist/types.backup/types/error-types.d.ts +0 -114
  414. package/dist/types.backup/types/global-namespace.d.ts +0 -90
  415. package/dist/types.backup/types/handler-context.d.ts +0 -658
  416. package/dist/types.backup/types/index.d.ts +0 -11
  417. package/dist/types.backup/types/loader-types.d.ts +0 -182
  418. package/dist/types.backup/types/request-scope.d.ts +0 -93
  419. package/dist/types.backup/types/route-config.d.ts +0 -105
  420. package/dist/types.backup/types/route-entry.d.ts +0 -95
  421. package/dist/types.backup/types/segments.d.ts +0 -234
  422. package/dist/types.backup/types.d.ts +0 -1
  423. package/dist/types.backup/urls/include-helper.d.ts +0 -17
  424. package/dist/types.backup/urls/include-provider.d.ts +0 -27
  425. package/dist/types.backup/urls/index.d.ts +0 -6
  426. package/dist/types.backup/urls/path-helper-types.d.ts +0 -197
  427. package/dist/types.backup/urls/path-helper.d.ts +0 -12
  428. package/dist/types.backup/urls/pattern-types.d.ts +0 -166
  429. package/dist/types.backup/urls/response-types.d.ts +0 -67
  430. package/dist/types.backup/urls/type-extraction.d.ts +0 -157
  431. package/dist/types.backup/urls/urls-function.d.ts +0 -24
  432. package/dist/types.backup/urls.d.ts +0 -1
  433. package/dist/types.backup/use-loader.d.ts +0 -150
  434. package/dist/types.backup/vercel/index.d.ts +0 -10
  435. package/dist/types.backup/vercel/tracing.d.ts +0 -70
  436. package/dist/types.backup/vite/debug.d.ts +0 -80
  437. package/dist/types.backup/vite/discovery/bundle-postprocess.d.ts +0 -12
  438. package/dist/types.backup/vite/discovery/dev-prerender-cache.d.ts +0 -65
  439. package/dist/types.backup/vite/discovery/discover-routers.d.ts +0 -17
  440. package/dist/types.backup/vite/discovery/discovery-errors.d.ts +0 -113
  441. package/dist/types.backup/vite/discovery/gate-state.d.ts +0 -79
  442. package/dist/types.backup/vite/discovery/prerender-collection.d.ts +0 -24
  443. package/dist/types.backup/vite/discovery/route-types-writer.d.ts +0 -32
  444. package/dist/types.backup/vite/discovery/self-gen-tracking.d.ts +0 -22
  445. package/dist/types.backup/vite/discovery/shell-prerender-phase.d.ts +0 -40
  446. package/dist/types.backup/vite/discovery/state.d.ts +0 -162
  447. package/dist/types.backup/vite/discovery/virtual-module-codegen.d.ts +0 -15
  448. package/dist/types.backup/vite/index.d.ts +0 -11
  449. package/dist/types.backup/vite/inject-client-debug.d.ts +0 -56
  450. package/dist/types.backup/vite/plugin-types.d.ts +0 -298
  451. package/dist/types.backup/vite/plugins/cjs-to-esm.d.ts +0 -6
  452. package/dist/types.backup/vite/plugins/client-ref-dedup.d.ts +0 -40
  453. package/dist/types.backup/vite/plugins/client-ref-hashing.d.ts +0 -35
  454. package/dist/types.backup/vite/plugins/cloudflare-protocol-stub.d.ts +0 -64
  455. package/dist/types.backup/vite/plugins/expose-action-id.d.ts +0 -18
  456. package/dist/types.backup/vite/plugins/expose-id-utils.d.ts +0 -37
  457. package/dist/types.backup/vite/plugins/expose-ids/export-analysis.d.ts +0 -19
  458. package/dist/types.backup/vite/plugins/expose-ids/handler-transform.d.ts +0 -10
  459. package/dist/types.backup/vite/plugins/expose-ids/loader-transform.d.ts +0 -8
  460. package/dist/types.backup/vite/plugins/expose-ids/router-transform.d.ts +0 -13
  461. package/dist/types.backup/vite/plugins/expose-ids/types.d.ts +0 -29
  462. package/dist/types.backup/vite/plugins/expose-internal-ids.d.ts +0 -6
  463. package/dist/types.backup/vite/plugins/performance-tracks.d.ts +0 -25
  464. package/dist/types.backup/vite/plugins/refresh-cmd.d.ts +0 -20
  465. package/dist/types.backup/vite/plugins/use-cache-transform.d.ts +0 -20
  466. package/dist/types.backup/vite/plugins/vercel-output.d.ts +0 -85
  467. package/dist/types.backup/vite/plugins/version-injector.d.ts +0 -21
  468. package/dist/types.backup/vite/plugins/version-plugin.d.ts +0 -19
  469. package/dist/types.backup/vite/plugins/virtual-entries.d.ts +0 -36
  470. package/dist/types.backup/vite/plugins/virtual-stub-plugin.d.ts +0 -7
  471. package/dist/types.backup/vite/rango.d.ts +0 -29
  472. package/dist/types.backup/vite/router-discovery.d.ts +0 -23
  473. package/dist/types.backup/vite/utils/ast-handler-extract.d.ts +0 -64
  474. package/dist/types.backup/vite/utils/banner.d.ts +0 -2
  475. package/dist/types.backup/vite/utils/bundle-analysis.d.ts +0 -28
  476. package/dist/types.backup/vite/utils/client-chunks.d.ts +0 -55
  477. package/dist/types.backup/vite/utils/directive-prologue.d.ts +0 -16
  478. package/dist/types.backup/vite/utils/forward-user-plugins.d.ts +0 -37
  479. package/dist/types.backup/vite/utils/manifest-utils.d.ts +0 -7
  480. package/dist/types.backup/vite/utils/package-resolution.d.ts +0 -6
  481. package/dist/types.backup/vite/utils/prerender-utils.d.ts +0 -32
  482. package/dist/types.backup/vite/utils/shared-utils.d.ts +0 -55
@@ -68,8 +68,11 @@ export interface InitBrowserAppOptions {
68
68
 
69
69
  /**
70
70
  * Enable global link interception for SPA navigation.
71
- * When enabled, clicks on same-origin anchor elements are intercepted
72
- * and handled via client-side navigation instead of full page loads.
71
+ * When enabled, clicks on eligible same-origin HTML anchor elements are intercepted
72
+ * and handled via client-side navigation instead of full page loads. Plain
73
+ * anchors inside the router basename also follow its default prefetch strategy
74
+ * after hydration. `data-prefetch="false"`/`"none"` opts out; `"true"` allows
75
+ * an application route with a common static-resource suffix.
73
76
  *
74
77
  * Links rendered with the Link component handle their own navigation
75
78
  * regardless of this setting.
@@ -124,6 +127,8 @@ export interface BrowserAppContext {
124
127
  warmupEnabled?: boolean;
125
128
  /** Whether the hydrated tree should be wrapped in React.StrictMode */
126
129
  strictMode?: boolean;
130
+ /** Whether plain-anchor click interception and delegated prefetch are enabled */
131
+ linkInterceptionEnabled?: boolean;
127
132
  /** App version for prefetch version mismatch detection */
128
133
  version?: string;
129
134
  /**
@@ -196,6 +201,12 @@ export async function initBrowserApp(
196
201
  }
197
202
  const initialHistoryKey = generateHistoryKey(window.location.href);
198
203
 
204
+ // Resolve the state namespace before the store installs its BroadcastChannel
205
+ // listener. A streaming handle payload can delay hydration below; leaving the
206
+ // default name active during that wait would discard this router's messages.
207
+ const version = initialPayload.metadata?.version;
208
+ initRangoState(version ?? "0", initialPayload.metadata?.stateCookieName);
209
+
199
210
  // Create navigation store with history-based caching
200
211
  const store = createNavigationStore({
201
212
  initialLocation: window.location,
@@ -271,7 +282,6 @@ export async function initBrowserApp(
271
282
  // It is set once from the initial payload and not swapped within a session:
272
283
  // a cross-app navigation is a full document load (X-RSC-Reload), so the
273
284
  // target app establishes its own shell on load.
274
- const version = initialPayload.metadata?.version;
275
285
  const appShellRef = createAppShellRef({
276
286
  routerId: initialPayload.metadata?.routerId,
277
287
  rootLayout: initialPayload.metadata?.rootLayout,
@@ -279,11 +289,6 @@ export async function initBrowserApp(
279
289
  version,
280
290
  });
281
291
 
282
- // Initialize the rango state cookie for cache invalidation. The build version
283
- // busts cached prefetches on deploy; the server-resolved cookie name
284
- // namespaces the cookie so sibling apps on the same origin don't collide
285
- // (falls back to the bare default prefix if metadata lacks the name).
286
- initRangoState(version ?? "0", initialPayload.metadata?.stateCookieName);
287
292
  setAppVersion(version);
288
293
 
289
294
  // Initialize the in-memory prefetch cache (TTL + max size) and the prefetch
@@ -359,6 +364,8 @@ export async function initBrowserApp(
359
364
  onUpdate: (update) => store.emitUpdate(update),
360
365
  renderSegments,
361
366
  version: version,
367
+ defaultPrefetch,
368
+ basename: initialPayload.metadata?.basename,
362
369
  });
363
370
 
364
371
  // Connect action redirect → navigation bridge (now that both are initialized)
@@ -541,6 +548,7 @@ export async function initBrowserApp(
541
548
  initialTheme: effectiveInitialTheme,
542
549
  warmupEnabled: initialPayload.metadata?.warmupEnabled ?? true,
543
550
  strictMode: initialPayload.metadata?.strictMode ?? true,
551
+ linkInterceptionEnabled: linkInterception,
544
552
  version,
545
553
  appShellRef,
546
554
  };
@@ -614,6 +622,7 @@ export function Rango(_props: RangoProps): React.ReactElement {
614
622
  warmupEnabled,
615
623
  version,
616
624
  appShellRef,
625
+ linkInterceptionEnabled,
617
626
  } = getBrowserAppContext();
618
627
 
619
628
  // Signal that the React tree has hydrated. useEffect only fires after
@@ -621,11 +630,15 @@ export function Rango(_props: RangoProps): React.ReactElement {
621
630
  // that does not depend on React internals like __reactFiber.
622
631
  React.useEffect(() => {
623
632
  document.documentElement.dataset.hydrated = "";
633
+ const cleanupPrefetch = linkInterceptionEnabled
634
+ ? bridge.registerDelegatedPrefetch()
635
+ : undefined;
624
636
  if (IS_BROWSER_DEBUG && !hydrationCommitLogged) {
625
637
  hydrationCommitLogged = true;
626
638
  bootLog("hydration commit (root effect flushed)");
627
639
  }
628
- }, []);
640
+ return cleanupPrefetch;
641
+ }, [bridge, linkInterceptionEnabled]);
629
642
 
630
643
  return (
631
644
  <NavigationProvider
@@ -613,6 +613,7 @@ export interface NavigationBridge {
613
613
  refresh(): Promise<void>;
614
614
  handlePopstate(): Promise<void>;
615
615
  registerLinkInterception(): () => void;
616
+ registerDelegatedPrefetch(): () => void;
616
617
  /** Current RSC version (live, reflects the latest updateVersion). */
617
618
  getVersion(): string | undefined;
618
619
  /** Update the RSC version (e.g. after HMR). Clears prefetch cache. */
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { encodeKV } from "../encode-kv.js";
10
+ import type { SearchParamsFilter } from "./search-params-filter.js";
10
11
 
11
12
  /**
12
13
  * Reserved URL query params that the router owns and must never key the cache
@@ -34,12 +35,22 @@ function isReservedSearchParam(key: string): boolean {
34
35
  * Build a sorted, deterministic query string from URLSearchParams,
35
36
  * excluding the router's reserved params (see isReservedSearchParam).
36
37
  *
37
- * Returns empty string when no user-facing params exist.
38
+ * `filter` is the compiled `cache.searchParams` config (search-params-filter.ts),
39
+ * applied AFTER the reserved-param exclusion and BEFORE the sort, so reserved
40
+ * params can never be re-included (`include: ["__no_cache"]` is a no-op) and
41
+ * surviving params stay order-insensitive. `undefined` means no filtering --
42
+ * that path must stay byte-identical to the pre-filter format (cacheKeyBase
43
+ * output is byte-stable by contract).
44
+ *
45
+ * Returns empty string when no user-facing params survive.
38
46
  */
39
- export function sortedSearchString(searchParams: URLSearchParams): string {
47
+ export function sortedSearchString(
48
+ searchParams: URLSearchParams,
49
+ filter?: SearchParamsFilter,
50
+ ): string {
40
51
  const pairs: [string, string][] = [];
41
52
  for (const [k, v] of searchParams) {
42
- if (!isReservedSearchParam(k)) {
53
+ if (!isReservedSearchParam(k) && (filter === undefined || filter(k))) {
43
54
  pairs.push([k, v]);
44
55
  }
45
56
  }
@@ -77,9 +88,12 @@ export function cacheKeyBase(
77
88
  pathname: string,
78
89
  searchParams?: URLSearchParams,
79
90
  params?: Record<string, string>,
91
+ filter?: SearchParamsFilter,
80
92
  ): string {
81
93
  const paramStr = sortedRouteParams(params);
82
- const searchStr = searchParams ? sortedSearchString(searchParams) : "";
94
+ const searchStr = searchParams
95
+ ? sortedSearchString(searchParams, filter)
96
+ : "";
83
97
 
84
98
  let key = `${host}${pathname}`;
85
99
  if (paramStr) key += `:${paramStr}`;
@@ -302,9 +302,14 @@ export function registerCachedFunction<T extends (...args: any[]) => any>(
302
302
  if (ctx._responseType) {
303
303
  keyArgs.push(ctx._responseType);
304
304
  }
305
- // Include user-facing search params (exclude internal _rsc*/__ params)
305
+ // Include user-facing search params (exclude internal _rsc*/__
306
+ // params, plus the request's cache.searchParams filter -- same
307
+ // normalization as the URL-keyed tiers).
306
308
  if (ctx.searchParams instanceof URLSearchParams) {
307
- const normalized = sortedSearchString(ctx.searchParams);
309
+ const normalized = sortedSearchString(
310
+ ctx.searchParams,
311
+ requestCtx?._searchParamsFilter,
312
+ );
308
313
  if (normalized) {
309
314
  keyArgs.push(normalized);
310
315
  }
@@ -11,6 +11,7 @@
11
11
  import type { PartialCacheOptions } from "../types.js";
12
12
  import type { ResolvedSegment } from "../types.js";
13
13
  import type { SegmentCacheStore, CachedEntryData } from "./types.js";
14
+ import { CACHE_READ_ERROR } from "./types.js";
14
15
  import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
15
16
  import {
16
17
  getRequestContext,
@@ -101,7 +102,7 @@ function getDefaultRouteCacheKey(
101
102
  ? "intercept"
102
103
  : (prefixOverride ?? (isPartial ? "partial" : "doc"));
103
104
 
104
- return `${prefix}:${cacheKeyBase(host, pathname, searchParams, params)}`;
105
+ return `${prefix}:${cacheKeyBase(host, pathname, searchParams, params, ctx?._searchParamsFilter)}`;
105
106
  }
106
107
 
107
108
  // ============================================================================
@@ -110,6 +111,17 @@ function getDefaultRouteCacheKey(
110
111
 
111
112
  const CACHE_HIT_OBSERVERS = new WeakMap<CacheScope, () => void>();
112
113
 
114
+ /**
115
+ * Discriminated outcome of a route cache lookup — see
116
+ * {@link CacheScope.lookupRouteDetailed} for what each status licenses.
117
+ */
118
+ export type CacheRouteLookupOutcome =
119
+ | {
120
+ status: "hit";
121
+ result: { segments: ResolvedSegment[]; shouldRevalidate: boolean };
122
+ }
123
+ | { status: "miss" | "bypass" | "error" };
124
+
113
125
  /**
114
126
  * CacheScope represents a cache boundary in the route tree.
115
127
  *
@@ -225,30 +237,76 @@ export class CacheScope {
225
237
  return resolveCacheKey(keyFn, this.getStore(), defaultKey, "CacheScope");
226
238
  }
227
239
 
240
+ /**
241
+ * @internal Whether a cache read/write is allowed for the current request:
242
+ * the scope is enabled AND its `condition` (if any) returns true. "read"
243
+ * is consulted by the PPR navigation-replay gate BEFORE any shell-store
244
+ * read so a cache(false)/condition-false route reports `cache-disabled`
245
+ * without spending getShell I/O; "write" gates the capture's snapshot-only
246
+ * doc record (cache-store middleware) under the same semantics as the
247
+ * scope's own store write. Consumer opt-outs are absolute — the seeded
248
+ * fallback must never serve where the consumer refused cached serves.
249
+ */
250
+ allowsCache(op: "read" | "write"): boolean {
251
+ return this.enabled && this.conditionAllows(op);
252
+ }
253
+
254
+ /**
255
+ * @internal True for scopes minted from the `_shellImplicitCache` marker
256
+ * (createShellImplicitDocScope) — the only construction path that passes
257
+ * the `doc` defaultKeyPrefix; route-derived scopes (createCacheScope) never
258
+ * do. withCacheLookup/withCacheStore use this to tell the implicit doc
259
+ * scope from a route-derived scope: the two compose on the replay serve
260
+ * path and only the route-derived kind gets the seeded fallback /
261
+ * doc-record treatment.
262
+ */
263
+ get isShellImplicitDocScope(): boolean {
264
+ return this.defaultKeyPrefix === "doc";
265
+ }
266
+
228
267
  /**
229
268
  * Evaluate the cache `condition` predicate. Returns false (skip the cache
230
269
  * operation) when the predicate returns false or throws; returns true when
231
270
  * there is no condition or no request context to evaluate it against.
232
271
  */
272
+ /**
273
+ * One WRITE decision per (scope, request), memoized on the request context.
274
+ * A capture render has TWO writers consulting the same predicate — the
275
+ * explicit tier's cacheRoute and the snapshot-only doc record gate
276
+ * (recordShellCaptureDocRecord) — and a true→false flap between the two
277
+ * evaluations recorded a REPLAYABLE canonical snapshot for a render whose
278
+ * real write was refused. The first evaluation pins the answer for the
279
+ * whole render (the capture's derived context during captures). READ
280
+ * decisions stay per-lookup by design: pre-deciding a flappable predicate
281
+ * at the replay gate was the round-2 regression.
282
+ */
283
+ private readonly writeConditionMemo = new WeakMap<RequestContext, boolean>();
284
+
233
285
  private conditionAllows(op: "read" | "write"): boolean {
234
286
  if (this.config === false || !this.config.condition) return true;
235
287
  const requestCtx = getRequestContext();
236
288
  if (!requestCtx) return true;
289
+ if (op === "write") {
290
+ const memoized = this.writeConditionMemo.get(requestCtx);
291
+ if (memoized !== undefined) return memoized;
292
+ }
293
+ let allowed: boolean;
237
294
  try {
238
- if (!this.config.condition(requestCtx)) {
295
+ allowed = !!this.config.condition(requestCtx);
296
+ if (!allowed) {
239
297
  debugCacheLog(
240
298
  `[CacheScope] condition returned false, skipping cache ${op}`,
241
299
  );
242
- return false;
243
300
  }
244
- return true;
245
301
  } catch (error) {
246
302
  console.error(
247
303
  `[CacheScope] condition function threw, skipping cache ${op}:`,
248
304
  error,
249
305
  );
250
- return false;
306
+ allowed = false;
251
307
  }
308
+ if (op === "write") this.writeConditionMemo.set(requestCtx, allowed);
309
+ return allowed;
252
310
  }
253
311
 
254
312
  /**
@@ -267,11 +325,42 @@ export class CacheScope {
267
325
  segments: ResolvedSegment[];
268
326
  shouldRevalidate: boolean;
269
327
  } | null> {
270
- if (!this.enabled) return null;
271
- if (!this.conditionAllows("read")) return null;
328
+ const outcome = await this.lookupRouteDetailed(
329
+ pathname,
330
+ params,
331
+ isIntercept,
332
+ );
333
+ return outcome.status === "hit" ? outcome.result : null;
334
+ }
335
+
336
+ /**
337
+ * @internal lookupRoute with a discriminated outcome. The PPR replay
338
+ * composition (withCacheLookup) may substitute the seeded doc record ONLY on
339
+ * a true `miss` — the other non-hit outcomes must not be papered over:
340
+ *
341
+ * - `bypass`: the scope refused the read — cache(false), a false
342
+ * `condition()`, or no resolvable store. Consumer opt-outs are absolute;
343
+ * a fallback here would serve cached segments to a request the consumer
344
+ * said must render fresh.
345
+ * - `error`: a throwing consumer key()/store keyGenerator/store.get. The
346
+ * contract on that failure is "render uncached" (see the catch below) —
347
+ * falling back would serve the canonical doc record across a broken key
348
+ * partition, exactly the collision resolveCacheKey's no-default-fallback
349
+ * rule exists to prevent.
350
+ *
351
+ * A corrupt entry that was evicted reads as `miss`: the store was consulted
352
+ * and holds nothing servable, which is the post-eviction truth.
353
+ */
354
+ async lookupRouteDetailed(
355
+ pathname: string,
356
+ params: Record<string, string>,
357
+ isIntercept?: boolean,
358
+ ): Promise<CacheRouteLookupOutcome> {
359
+ if (!this.enabled) return { status: "bypass" };
360
+ if (!this.conditionAllows("read")) return { status: "bypass" };
272
361
 
273
362
  const store = this.getStore();
274
- if (!store) return null;
363
+ if (!store) return { status: "bypass" };
275
364
 
276
365
  // Resolve cache key INSIDE the try so a throwing consumer key() (or a
277
366
  // store.keyGenerator) degrades to a cache miss (return null -> render
@@ -285,9 +374,17 @@ export class CacheScope {
285
374
 
286
375
  const result = await store.get(key);
287
376
 
377
+ // Built-in stores swallow backend read failures internally and signal
378
+ // them with CACHE_READ_ERROR — classify as `error`, not `miss`, so the
379
+ // replay composition renders uncached instead of substituting the
380
+ // seeded doc record for a tier whose backend never answered.
381
+ if (result === CACHE_READ_ERROR) {
382
+ return { status: "error" };
383
+ }
384
+
288
385
  if (!result) {
289
386
  debugCacheLog(`[CacheScope] MISS: ${key}`);
290
- return null;
387
+ return { status: "miss" };
291
388
  }
292
389
 
293
390
  const { data: cached, shouldRevalidate } = result;
@@ -320,7 +417,7 @@ export class CacheScope {
320
417
  .catch((e) =>
321
418
  reportCacheError(e, "cache-delete", `[CacheScope] ${key}: evict`),
322
419
  );
323
- return null;
420
+ return { status: "miss" };
324
421
  }
325
422
 
326
423
  // A hit serves content that was tagged at write time, so the document
@@ -351,16 +448,18 @@ export class CacheScope {
351
448
  }
352
449
 
353
450
  CACHE_HIT_OBSERVERS.get(this)?.();
354
- return { segments, shouldRevalidate };
451
+ return { status: "hit", result: { segments, shouldRevalidate } };
355
452
  } catch (error) {
356
453
  // Covers a store.get() failure AND a throwing consumer key()/keyGenerator
357
- // (resolveKey). Either way degrade to a cache miss so the render proceeds.
454
+ // (resolveKey). Either way degrade to an uncached render reported as
455
+ // `error`, not `miss`, so the replay composition cannot substitute the
456
+ // seeded doc record for a lookup that never resolved its key partition.
358
457
  reportCacheError(
359
458
  error,
360
459
  "cache-read",
361
460
  `[CacheScope] lookup ${key ?? "(key resolution failed)"}`,
362
461
  );
363
- return null;
462
+ return { status: "error" };
364
463
  }
365
464
  }
366
465
 
@@ -422,6 +521,15 @@ export class CacheScope {
422
521
  // Resolve cache key early (while request context is available)
423
522
  const key = await this.resolveKey(pathname, params, isIntercept);
424
523
 
524
+ // Doc-namespaced scopes (the shell implicit scope and the capture's
525
+ // composed doc scope) publish the canonical document segment key so
526
+ // captureAndStoreShell can stamp it onto the shell entry (`docKey`).
527
+ // Replay eligibility then requires this exact record — "any segment
528
+ // record" previously counted unusable explicit-tier-keyed records too.
529
+ if (this.defaultKeyPrefix === "doc" && requestCtx._shellImplicitCache) {
530
+ requestCtx._shellImplicitCache.docKey = key;
531
+ }
532
+
425
533
  // Resolve tags early (while request context is available, before waitUntil)
426
534
  const tags = resolveCacheTags(this.config, requestCtx);
427
535
  recordRequestTags(tags, requestCtx);
@@ -538,6 +646,31 @@ export function createCacheScope(
538
646
  return new CacheScope(config.options, parent);
539
647
  }
540
648
 
649
+ type ShellImplicitCacheMarker = NonNullable<
650
+ RequestContext["_shellImplicitCache"]
651
+ >;
652
+
653
+ /**
654
+ * Mint the implicit doc-level scope for a `_shellImplicitCache` marker: key
655
+ * resolution under the marker's `doc` namespace against the marker's store,
656
+ * with the marker's onHit wired as the hit observer. Shared by
657
+ * {@link resolveShellImplicitCacheScope} (routes that derived no scope) and
658
+ * the explicit-scope composition sites (capture doc record in the cache-store
659
+ * middleware, seeded replay fallback in withCacheLookup) so both ends of the
660
+ * shell contract resolve the SAME canonical document key.
661
+ */
662
+ export function createShellImplicitDocScope(
663
+ marker: ShellImplicitCacheMarker,
664
+ ): CacheScope {
665
+ const implicitScope = new CacheScope(
666
+ { ttl: marker.ttl, swr: marker.swr, store: marker.store },
667
+ null,
668
+ marker.keyPrefix,
669
+ );
670
+ if (marker.onHit) CACHE_HIT_OBSERVERS.set(implicitScope, marker.onHit);
671
+ return implicitScope;
672
+ }
673
+
541
674
  /**
542
675
  * Shell fast path: when the route tree derived NO cache scope and the current
543
676
  * request context carries the `_shellImplicitCache` marker (a shell capture,
@@ -548,9 +681,11 @@ export function createCacheScope(
548
681
  * (resolveFreshLoadersAndYield).
549
682
  *
550
683
  * An existing scope — including an explicit cache(false) opt-out — always
551
- * wins: the consumer's cache() semantics (their ttl/swr/store/condition) are
552
- * never overridden, and cache(false) keeps the tail on the full handler
553
- * re-run path.
684
+ * wins HERE: the consumer's cache() semantics (their ttl/swr/store/condition)
685
+ * are never overridden, and cache(false) keeps the tail on the full handler
686
+ * re-run path. On the navigation-replay serve path the marker still composes
687
+ * with an explicit scope downstream (withCacheLookup's seeded fallback after
688
+ * an explicit-tier miss) — see `onExplicitHit` on `_shellImplicitCache`.
554
689
  */
555
690
  export function resolveShellImplicitCacheScope(
556
691
  scope: CacheScope | null,
@@ -558,11 +693,5 @@ export function resolveShellImplicitCacheScope(
558
693
  if (scope) return scope;
559
694
  const marker = getRequestContext()?._shellImplicitCache;
560
695
  if (!marker) return null;
561
- const implicitScope = new CacheScope(
562
- { ttl: marker.ttl, swr: marker.swr, store: marker.store },
563
- null,
564
- marker.keyPrefix,
565
- );
566
- if (marker.onHit) CACHE_HIT_OBSERVERS.set(implicitScope, marker.onHit);
567
- return implicitScope;
696
+ return createShellImplicitDocScope(marker);
568
697
  }
@@ -35,7 +35,9 @@ import type {
35
35
  CacheItemResult,
36
36
  CacheItemOptions,
37
37
  ShellCacheEntry,
38
+ CacheReadError,
38
39
  } from "../types.js";
40
+ import { CACHE_READ_ERROR } from "../types.js";
39
41
  import {
40
42
  _getRequestContext,
41
43
  type RequestContext,
@@ -286,6 +288,14 @@ interface KVShellEnvelope {
286
288
  i?: string;
287
289
  /** Capture data snapshot: recorded cache-store hits/writes for HIT parity */
288
290
  sn?: import("../types.js").ShellSnapshotRecord[];
291
+ /**
292
+ * ShellCacheEntry.docKey. Must round-trip: navigation-replay eligibility
293
+ * requires the exact canonical doc segment record named here — dropping the
294
+ * field reads back as "no consumable record" and every partial navigation
295
+ * reports `no-segment-snapshot` after a KV round trip (the memory store
296
+ * passes the entry by reference, so only envelope stores can lose it).
297
+ */
298
+ dk?: string;
289
299
  /**
290
300
  * ShellCacheEntry.handlerLiveHoles. Must round-trip: the serve side arms the
291
301
  * handler-free fast path on `!entry.handlerLiveHoles`, so dropping the flag
@@ -883,7 +893,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
883
893
  * On L1 miss, falls back to KV (L2) if configured.
884
894
  * KV hits are promoted to L1 in the background.
885
895
  */
886
- async get(key: string): Promise<CacheGetResult | null> {
896
+ async get(key: string): Promise<CacheGetResult | null | CacheReadError> {
887
897
  if (this.isReservedSegmentKey(key, "cache-read")) return null;
888
898
  try {
889
899
  const cache = await this.getCache();
@@ -897,27 +907,40 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
897
907
  const matchMs = Date.now() - matchStart;
898
908
 
899
909
  if (!response) {
900
- // A transient L1 match error (matchError set) is reported as cache-read
901
- // but, like a genuine miss or an abandoned slow match (timedOut), still
902
- // degrades to L2/KV rather than failing the read.
903
- if (matchError)
910
+ if (matchError) {
911
+ // A match REJECTION is reported as cache-read and still degrades to
912
+ // L2/KV -- a real KV value (or KV's own CACHE_READ_ERROR) stands on
913
+ // its own. But a null KV result (unconfigured namespace, kv-miss,
914
+ // kv-timeout) is NOT proof of absence under a rejected L1 match:
915
+ // the only real signal this read produced is the failure, so
916
+ // surface CACHE_READ_ERROR instead of a replayable miss (the PPR
917
+ // seeded fallback must render uncached, not substitute the doc
918
+ // record for a partition the store could not actually read).
904
919
  reportCacheError(
905
920
  matchError,
906
921
  "cache-read",
907
922
  "[CFCacheStore] get L1 match",
908
923
  );
924
+ if (this.debug)
925
+ this.emitDebug({
926
+ op: "get",
927
+ key,
928
+ // Distinct from a genuine absence: surface it as match-error so
929
+ // debug agrees with the cache-read already routed to onError,
930
+ // instead of masquerading as l1-miss.
931
+ outcome: "match-error",
932
+ matchMs,
933
+ });
934
+ const kvResult = await this.kvGetSegment(key);
935
+ return kvResult ?? CACHE_READ_ERROR;
936
+ }
937
+ // An abandoned slow match (timedOut) keeps the fail-open latency-budget
938
+ // policy: degrade to L2/KV, and a KV null stays a miss.
909
939
  if (this.debug)
910
940
  this.emitDebug({
911
941
  op: "get",
912
942
  key,
913
- // A match REJECTION (matchError) is distinct from a genuine absence:
914
- // surface it as match-error so debug agrees with the cache-read
915
- // already routed to onError, instead of masquerading as l1-miss.
916
- outcome: matchError
917
- ? "match-error"
918
- : timedOut
919
- ? "match-timeout"
920
- : "l1-miss",
943
+ outcome: timedOut ? "match-timeout" : "l1-miss",
921
944
  matchMs,
922
945
  });
923
946
  return this.kvGetSegment(key);
@@ -1098,7 +1121,9 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
1098
1121
  // emit is the separate wrangler-tail signal. Keep both observability paths.
1099
1122
  reportCacheError(error, "cache-read", "[CFCacheStore] get");
1100
1123
  if (this.debug) this.emitDebug({ op: "get", key, outcome: "error" });
1101
- return null;
1124
+ // Distinct from a miss so the PPR replay composition renders uncached
1125
+ // instead of substituting the seeded doc record (CACHE_READ_ERROR).
1126
+ return CACHE_READ_ERROR;
1102
1127
  }
1103
1128
  }
1104
1129
 
@@ -1819,6 +1844,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
1819
1844
  buildVersion: envelope.bv,
1820
1845
  initialTheme: envelope.i,
1821
1846
  snapshot: envelope.sn,
1847
+ docKey: envelope.dk,
1822
1848
  handlerLiveHoles: envelope.lh,
1823
1849
  transitionWhen: envelope.tw,
1824
1850
  navigationOnly: envelope.no,
@@ -1908,6 +1934,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
1908
1934
  ta: taggedAt,
1909
1935
  i: entry.initialTheme,
1910
1936
  sn: entry.snapshot,
1937
+ dk: entry.docKey,
1911
1938
  lh: entry.handlerLiveHoles,
1912
1939
  tw: entry.transitionWhen,
1913
1940
  no: entry.navigationOnly,
@@ -2817,7 +2844,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
2817
2844
  private async kvGetSegment(
2818
2845
  key: string,
2819
2846
  opts?: { suppressRevalidate?: boolean },
2820
- ): Promise<CacheGetResult | null> {
2847
+ ): Promise<CacheGetResult | null | CacheReadError> {
2821
2848
  if (!this.kv) return null;
2822
2849
 
2823
2850
  try {
@@ -2886,7 +2913,15 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
2886
2913
  } catch (error) {
2887
2914
  reportCacheError(error, "cache-read", "[CFCacheStore] kvGetSegment");
2888
2915
  if (this.debug) this.emitDebug({ op: "get", key, outcome: "error" });
2889
- return null;
2916
+ // A KV failure is NOT proof of absence: returning null classified it a
2917
+ // real miss and let the PPR seeded fallback substitute the doc record
2918
+ // for a key partition the store could not actually read. Same sentinel
2919
+ // as get()'s own catch — lookupRouteDetailed classifies it `error` and
2920
+ // the render stays uncached. (A kvGetOrEvict TIMEOUT above stays null
2921
+ // by design: it is a bounded-latency degrade of a likely-healthy read,
2922
+ // and serving the equivalent seeded record there is the fallback
2923
+ // working as intended, not a masked failure.)
2924
+ return CACHE_READ_ERROR;
2890
2925
  }
2891
2926
  }
2892
2927
 
@@ -327,7 +327,13 @@ export function createDocumentCacheMiddleware<TEnv = any>(
327
327
  // existing keys and double any host they already include).
328
328
  const cacheKey = keyGenerator
329
329
  ? keyGenerator(url) + segmentHash + typeSuffix
330
- : cacheKeyBase(url.host, url.pathname, url.searchParams) +
330
+ : cacheKeyBase(
331
+ url.host,
332
+ url.pathname,
333
+ url.searchParams,
334
+ undefined,
335
+ requestCtx?._searchParamsFilter,
336
+ ) +
331
337
  segmentHash +
332
338
  typeSuffix;
333
339
  // 1. Check cache
@@ -7,7 +7,9 @@ export type {
7
7
  ShellCacheEntry,
8
8
  SerializedSegmentData,
9
9
  SegmentHandleData,
10
+ CacheReadError,
10
11
  } from "./types.js";
12
+ export { CACHE_READ_ERROR } from "./types.js";
11
13
 
12
14
  export { MemorySegmentCacheStore } from "./memory-segment-store.js";
13
15
 
@@ -39,6 +41,11 @@ export {
39
41
  VERCEL_MAX_TAG_BYTES,
40
42
  } from "./vercel/index.js";
41
43
 
44
+ export {
45
+ TRACKING_SEARCH_PARAMS,
46
+ type CacheSearchParams,
47
+ } from "./search-params-filter.js";
48
+
42
49
  export { CacheScope, createCacheScope } from "./cache-scope.js";
43
50
 
44
51
  export {