@rangojs/router 0.4.3 → 0.5.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 (420) hide show
  1. package/dist/types/browser/prefetch/cache.d.ts +31 -2
  2. package/dist/types/cache/cf/cf-cache-store.d.ts +2 -0
  3. package/dist/types/cache/types.d.ts +39 -6
  4. package/dist/types/route-definition/helpers-types.d.ts +5 -4
  5. package/dist/types/rsc/capture-queue.d.ts +19 -3
  6. package/dist/types/rsc/shell-build-manifest.d.ts +2 -2
  7. package/dist/types/rsc/shell-capture.d.ts +22 -2
  8. package/dist/types/rsc/shell-serve.d.ts +18 -12
  9. package/dist/types/static-handler.d.ts +15 -1
  10. package/dist/types/urls/path-helper-types.d.ts +6 -7
  11. package/dist/types.backup/__internal.d.ts +127 -0
  12. package/dist/types.backup/bin/rango.d.ts +1 -0
  13. package/dist/types.backup/browser/action-coordinator.d.ts +57 -0
  14. package/dist/types.backup/browser/action-fence.d.ts +33 -0
  15. package/dist/types.backup/browser/app-shell.d.ts +34 -0
  16. package/dist/types.backup/browser/app-version.d.ts +6 -0
  17. package/dist/types.backup/browser/connection-warmup.d.ts +31 -0
  18. package/dist/types.backup/browser/cookie-name.d.ts +66 -0
  19. package/dist/types.backup/browser/event-controller.d.ts +221 -0
  20. package/dist/types.backup/browser/history-state.d.ts +26 -0
  21. package/dist/types.backup/browser/index.d.ts +1 -0
  22. package/dist/types.backup/browser/intercept-utils.d.ts +30 -0
  23. package/dist/types.backup/browser/invalidate-client-cache.d.ts +17 -0
  24. package/dist/types.backup/browser/link-interceptor.d.ts +43 -0
  25. package/dist/types.backup/browser/logging.d.ts +33 -0
  26. package/dist/types.backup/browser/merge-segment-loaders.d.ts +38 -0
  27. package/dist/types.backup/browser/navigation-bridge.d.ts +27 -0
  28. package/dist/types.backup/browser/navigation-client.d.ts +17 -0
  29. package/dist/types.backup/browser/navigation-store-handle.d.ts +25 -0
  30. package/dist/types.backup/browser/navigation-store.d.ts +95 -0
  31. package/dist/types.backup/browser/navigation-transaction.d.ts +75 -0
  32. package/dist/types.backup/browser/network-error-handler.d.ts +35 -0
  33. package/dist/types.backup/browser/partial-update.d.ts +61 -0
  34. package/dist/types.backup/browser/prefetch/cache.d.ts +183 -0
  35. package/dist/types.backup/browser/prefetch/fetch.d.ts +52 -0
  36. package/dist/types.backup/browser/prefetch/observer.d.ts +27 -0
  37. package/dist/types.backup/browser/prefetch/policy.d.ts +13 -0
  38. package/dist/types.backup/browser/prefetch/queue.d.ts +48 -0
  39. package/dist/types.backup/browser/prefetch/resource-ready.d.ts +28 -0
  40. package/dist/types.backup/browser/rango-state.d.ts +52 -0
  41. package/dist/types.backup/browser/react/Link.d.ts +140 -0
  42. package/dist/types.backup/browser/react/NavigationProvider.d.ts +88 -0
  43. package/dist/types.backup/browser/react/ScrollRestoration.d.ts +78 -0
  44. package/dist/types.backup/browser/react/context.d.ts +54 -0
  45. package/dist/types.backup/browser/react/filter-segment-order.d.ts +35 -0
  46. package/dist/types.backup/browser/react/index.d.ts +1 -0
  47. package/dist/types.backup/browser/react/location-state-shared.d.ts +162 -0
  48. package/dist/types.backup/browser/react/location-state.d.ts +29 -0
  49. package/dist/types.backup/browser/react/mount-context.d.ts +23 -0
  50. package/dist/types.backup/browser/react/nonce-context.d.ts +14 -0
  51. package/dist/types.backup/browser/react/shallow-equal.d.ts +5 -0
  52. package/dist/types.backup/browser/react/use-action.d.ts +61 -0
  53. package/dist/types.backup/browser/react/use-handle.d.ts +21 -0
  54. package/dist/types.backup/browser/react/use-href.d.ts +32 -0
  55. package/dist/types.backup/browser/react/use-link-status.d.ts +36 -0
  56. package/dist/types.backup/browser/react/use-mount.d.ts +24 -0
  57. package/dist/types.backup/browser/react/use-navigation.d.ts +15 -0
  58. package/dist/types.backup/browser/react/use-params.d.ts +21 -0
  59. package/dist/types.backup/browser/react/use-pathname.d.ts +13 -0
  60. package/dist/types.backup/browser/react/use-reverse.d.ts +40 -0
  61. package/dist/types.backup/browser/react/use-router.d.ts +23 -0
  62. package/dist/types.backup/browser/react/use-search-params.d.ts +19 -0
  63. package/dist/types.backup/browser/react/use-segments.d.ts +29 -0
  64. package/dist/types.backup/browser/response-adapter.d.ts +58 -0
  65. package/dist/types.backup/browser/rsc-router.d.ts +141 -0
  66. package/dist/types.backup/browser/scroll-restoration.d.ts +103 -0
  67. package/dist/types.backup/browser/segment-reconciler.d.ts +74 -0
  68. package/dist/types.backup/browser/segment-structure-assert.d.ts +16 -0
  69. package/dist/types.backup/browser/server-action-bridge.d.ts +29 -0
  70. package/dist/types.backup/browser/types.d.ts +530 -0
  71. package/dist/types.backup/browser/validate-redirect-origin.d.ts +28 -0
  72. package/dist/types.backup/build/collect-fallback-refs.d.ts +5 -0
  73. package/dist/types.backup/build/generate-manifest.d.ts +100 -0
  74. package/dist/types.backup/build/generate-route-types.d.ts +8 -0
  75. package/dist/types.backup/build/index.d.ts +21 -0
  76. package/dist/types.backup/build/prefix-tree-utils.d.ts +56 -0
  77. package/dist/types.backup/build/route-trie.d.ts +89 -0
  78. package/dist/types.backup/build/route-types/ast-helpers.d.ts +3 -0
  79. package/dist/types.backup/build/route-types/ast-route-extraction.d.ts +13 -0
  80. package/dist/types.backup/build/route-types/codegen.d.ts +16 -0
  81. package/dist/types.backup/build/route-types/include-resolution.d.ts +74 -0
  82. package/dist/types.backup/build/route-types/param-extraction.d.ts +13 -0
  83. package/dist/types.backup/build/route-types/per-module-writer.d.ts +18 -0
  84. package/dist/types.backup/build/route-types/router-processing.d.ts +82 -0
  85. package/dist/types.backup/build/route-types/scan-filter.d.ts +17 -0
  86. package/dist/types.backup/build/route-types/source-scan.d.ts +13 -0
  87. package/dist/types.backup/build/runtime-discovery.d.ts +24 -0
  88. package/dist/types.backup/cache/background-task.d.ts +21 -0
  89. package/dist/types.backup/cache/cache-error.d.ts +71 -0
  90. package/dist/types.backup/cache/cache-key-utils.d.ts +35 -0
  91. package/dist/types.backup/cache/cache-policy.d.ts +59 -0
  92. package/dist/types.backup/cache/cache-runtime.d.ts +51 -0
  93. package/dist/types.backup/cache/cache-scope.d.ts +134 -0
  94. package/dist/types.backup/cache/cache-tag.d.ts +79 -0
  95. package/dist/types.backup/cache/cf/cf-base64.d.ts +4 -0
  96. package/dist/types.backup/cache/cf/cf-cache-constants.d.ts +105 -0
  97. package/dist/types.backup/cache/cf/cf-cache-store.d.ts +481 -0
  98. package/dist/types.backup/cache/cf/cf-cache-types.d.ts +300 -0
  99. package/dist/types.backup/cache/cf/cf-kv-utils.d.ts +22 -0
  100. package/dist/types.backup/cache/cf/cf-tag-marker-memo.d.ts +15 -0
  101. package/dist/types.backup/cache/cf/index.d.ts +3 -0
  102. package/dist/types.backup/cache/document-cache.d.ts +69 -0
  103. package/dist/types.backup/cache/handle-capture.d.ts +23 -0
  104. package/dist/types.backup/cache/handle-snapshot.d.ts +39 -0
  105. package/dist/types.backup/cache/index.d.ts +7 -0
  106. package/dist/types.backup/cache/memory-segment-store.d.ts +163 -0
  107. package/dist/types.backup/cache/profile-registry.d.ts +40 -0
  108. package/dist/types.backup/cache/read-through-swr.d.ts +60 -0
  109. package/dist/types.backup/cache/segment-codec.d.ts +78 -0
  110. package/dist/types.backup/cache/shell-snapshot.d.ts +162 -0
  111. package/dist/types.backup/cache/tag-invalidation.d.ts +74 -0
  112. package/dist/types.backup/cache/taint.d.ts +71 -0
  113. package/dist/types.backup/cache/types.d.ts +407 -0
  114. package/dist/types.backup/cache/vercel/index.d.ts +1 -0
  115. package/dist/types.backup/cache/vercel/vercel-cache-store.d.ts +267 -0
  116. package/dist/types.backup/client.d.ts +184 -0
  117. package/dist/types.backup/client.rsc.d.ts +39 -0
  118. package/dist/types.backup/cloudflare/index.d.ts +7 -0
  119. package/dist/types.backup/cloudflare/tracing.d.ts +53 -0
  120. package/dist/types.backup/component-utils.d.ts +46 -0
  121. package/dist/types.backup/components/DefaultDocument.d.ts +13 -0
  122. package/dist/types.backup/context-var.d.ts +84 -0
  123. package/dist/types.backup/debug.d.ts +57 -0
  124. package/dist/types.backup/decode-loader-results.d.ts +5 -0
  125. package/dist/types.backup/default-error-boundary.d.ts +10 -0
  126. package/dist/types.backup/defer.d.ts +89 -0
  127. package/dist/types.backup/deps/browser.d.ts +1 -0
  128. package/dist/types.backup/deps/html-stream-client.d.ts +1 -0
  129. package/dist/types.backup/deps/html-stream-server.d.ts +1 -0
  130. package/dist/types.backup/deps/rsc.d.ts +1 -0
  131. package/dist/types.backup/deps/ssr.d.ts +1 -0
  132. package/dist/types.backup/encode-kv.d.ts +35 -0
  133. package/dist/types.backup/errors.d.ts +226 -0
  134. package/dist/types.backup/escape-script.d.ts +44 -0
  135. package/dist/types.backup/handle.d.ts +93 -0
  136. package/dist/types.backup/handles/MetaTags.d.ts +17 -0
  137. package/dist/types.backup/handles/Scripts.d.ts +38 -0
  138. package/dist/types.backup/handles/breadcrumbs.d.ts +43 -0
  139. package/dist/types.backup/handles/deferred-resolution.d.ts +53 -0
  140. package/dist/types.backup/handles/is-thenable.d.ts +12 -0
  141. package/dist/types.backup/handles/meta.d.ts +43 -0
  142. package/dist/types.backup/handles/script.d.ts +139 -0
  143. package/dist/types.backup/host/cookie-handler.d.ts +8 -0
  144. package/dist/types.backup/host/errors.d.ts +40 -0
  145. package/dist/types.backup/host/index.d.ts +33 -0
  146. package/dist/types.backup/host/pattern-matcher.d.ts +30 -0
  147. package/dist/types.backup/host/router.d.ts +12 -0
  148. package/dist/types.backup/host/testing.d.ts +41 -0
  149. package/dist/types.backup/host/types.d.ts +148 -0
  150. package/dist/types.backup/host/utils.d.ts +20 -0
  151. package/dist/types.backup/href-client.d.ts +214 -0
  152. package/dist/types.backup/index.d.ts +112 -0
  153. package/dist/types.backup/index.rsc.d.ts +51 -0
  154. package/dist/types.backup/internal-debug.d.ts +1 -0
  155. package/dist/types.backup/loader-store.d.ts +193 -0
  156. package/dist/types.backup/loader.d.ts +18 -0
  157. package/dist/types.backup/loader.rsc.d.ts +18 -0
  158. package/dist/types.backup/missing-id-error.d.ts +1 -0
  159. package/dist/types.backup/outlet-context.d.ts +12 -0
  160. package/dist/types.backup/outlet-provider.d.ts +12 -0
  161. package/dist/types.backup/prerender/build-shell-capture.d.ts +104 -0
  162. package/dist/types.backup/prerender/param-hash.d.ts +6 -0
  163. package/dist/types.backup/prerender/shell-manifest-key.d.ts +18 -0
  164. package/dist/types.backup/prerender/store.d.ts +62 -0
  165. package/dist/types.backup/prerender.d.ts +292 -0
  166. package/dist/types.backup/redirect-origin.d.ts +55 -0
  167. package/dist/types.backup/regex-escape.d.ts +6 -0
  168. package/dist/types.backup/render-error-thrower.d.ts +13 -0
  169. package/dist/types.backup/response-utils.d.ts +35 -0
  170. package/dist/types.backup/reverse.d.ts +206 -0
  171. package/dist/types.backup/root-error-boundary.d.ts +32 -0
  172. package/dist/types.backup/route-content-wrapper.d.ts +40 -0
  173. package/dist/types.backup/route-definition/dsl-helpers.d.ts +130 -0
  174. package/dist/types.backup/route-definition/helper-factories.d.ts +22 -0
  175. package/dist/types.backup/route-definition/helpers-types.d.ts +392 -0
  176. package/dist/types.backup/route-definition/index.d.ts +7 -0
  177. package/dist/types.backup/route-definition/redirect.d.ts +48 -0
  178. package/dist/types.backup/route-definition/resolve-handler-use.d.ts +19 -0
  179. package/dist/types.backup/route-definition/use-item-types.d.ts +1 -0
  180. package/dist/types.backup/route-definition.d.ts +1 -0
  181. package/dist/types.backup/route-map-builder.d.ts +127 -0
  182. package/dist/types.backup/route-name.d.ts +27 -0
  183. package/dist/types.backup/route-types.d.ts +172 -0
  184. package/dist/types.backup/router/basename.d.ts +10 -0
  185. package/dist/types.backup/router/content-negotiation.d.ts +91 -0
  186. package/dist/types.backup/router/debug-manifest.d.ts +7 -0
  187. package/dist/types.backup/router/error-handling.d.ts +76 -0
  188. package/dist/types.backup/router/find-match.d.ts +19 -0
  189. package/dist/types.backup/router/handler-context.d.ts +41 -0
  190. package/dist/types.backup/router/instrument.d.ts +161 -0
  191. package/dist/types.backup/router/intercept-resolution.d.ts +79 -0
  192. package/dist/types.backup/router/lazy-includes.d.ts +26 -0
  193. package/dist/types.backup/router/loader-resolution.d.ts +63 -0
  194. package/dist/types.backup/router/logging.d.ts +41 -0
  195. package/dist/types.backup/router/manifest.d.ts +8 -0
  196. package/dist/types.backup/router/match-api.d.ts +19 -0
  197. package/dist/types.backup/router/match-context.d.ts +184 -0
  198. package/dist/types.backup/router/match-handlers.d.ts +49 -0
  199. package/dist/types.backup/router/match-middleware/background-revalidation.d.ts +113 -0
  200. package/dist/types.backup/router/match-middleware/cache-lookup.d.ts +113 -0
  201. package/dist/types.backup/router/match-middleware/cache-store.d.ts +112 -0
  202. package/dist/types.backup/router/match-middleware/index.d.ts +80 -0
  203. package/dist/types.backup/router/match-middleware/intercept-resolution.d.ts +116 -0
  204. package/dist/types.backup/router/match-middleware/segment-resolution.d.ts +94 -0
  205. package/dist/types.backup/router/match-pipelines.d.ts +103 -0
  206. package/dist/types.backup/router/match-result.d.ts +114 -0
  207. package/dist/types.backup/router/metrics.d.ts +6 -0
  208. package/dist/types.backup/router/middleware-types.d.ts +74 -0
  209. package/dist/types.backup/router/middleware.d.ts +116 -0
  210. package/dist/types.backup/router/navigation-snapshot.d.ts +22 -0
  211. package/dist/types.backup/router/params-util.d.ts +8 -0
  212. package/dist/types.backup/router/parse-pattern.d.ts +38 -0
  213. package/dist/types.backup/router/pattern-matching.d.ts +169 -0
  214. package/dist/types.backup/router/prefetch-cache-ttl.d.ts +27 -0
  215. package/dist/types.backup/router/prefetch-limits.d.ts +20 -0
  216. package/dist/types.backup/router/prerender-match.d.ts +50 -0
  217. package/dist/types.backup/router/preview-match.d.ts +22 -0
  218. package/dist/types.backup/router/request-classification.d.ts +104 -0
  219. package/dist/types.backup/router/revalidation.d.ts +57 -0
  220. package/dist/types.backup/router/route-snapshot.d.ts +112 -0
  221. package/dist/types.backup/router/router-context.d.ts +137 -0
  222. package/dist/types.backup/router/router-interfaces.d.ts +432 -0
  223. package/dist/types.backup/router/router-options.d.ts +738 -0
  224. package/dist/types.backup/router/router-registry.d.ts +15 -0
  225. package/dist/types.backup/router/segment-resolution/fresh.d.ts +55 -0
  226. package/dist/types.backup/router/segment-resolution/helpers.d.ts +93 -0
  227. package/dist/types.backup/router/segment-resolution/loader-cache.d.ts +33 -0
  228. package/dist/types.backup/router/segment-resolution/loader-mask.d.ts +44 -0
  229. package/dist/types.backup/router/segment-resolution/loader-snapshot.d.ts +90 -0
  230. package/dist/types.backup/router/segment-resolution/mask-nested.d.ts +53 -0
  231. package/dist/types.backup/router/segment-resolution/revalidation.d.ts +85 -0
  232. package/dist/types.backup/router/segment-resolution/static-store.d.ts +17 -0
  233. package/dist/types.backup/router/segment-resolution/streamed-handler-telemetry.d.ts +16 -0
  234. package/dist/types.backup/router/segment-resolution/view-transition-default.d.ts +28 -0
  235. package/dist/types.backup/router/segment-resolution.d.ts +3 -0
  236. package/dist/types.backup/router/segment-wrappers.d.ts +53 -0
  237. package/dist/types.backup/router/state-cookie-name.d.ts +1 -0
  238. package/dist/types.backup/router/substitute-pattern-params.d.ts +23 -0
  239. package/dist/types.backup/router/telemetry-otel.d.ts +113 -0
  240. package/dist/types.backup/router/telemetry.d.ts +215 -0
  241. package/dist/types.backup/router/timeout.d.ts +68 -0
  242. package/dist/types.backup/router/tracing.d.ts +125 -0
  243. package/dist/types.backup/router/trie-matching.d.ts +32 -0
  244. package/dist/types.backup/router/types.d.ts +98 -0
  245. package/dist/types.backup/router/url-params.d.ts +26 -0
  246. package/dist/types.backup/router.d.ts +7 -0
  247. package/dist/types.backup/rsc/capture-queue.d.ts +6 -0
  248. package/dist/types.backup/rsc/full-payload.d.ts +22 -0
  249. package/dist/types.backup/rsc/handler-context.d.ts +31 -0
  250. package/dist/types.backup/rsc/handler.d.ts +9 -0
  251. package/dist/types.backup/rsc/helpers.d.ts +213 -0
  252. package/dist/types.backup/rsc/index.d.ts +17 -0
  253. package/dist/types.backup/rsc/json-route-result.d.ts +20 -0
  254. package/dist/types.backup/rsc/loader-fetch.d.ts +14 -0
  255. package/dist/types.backup/rsc/manifest-init.d.ts +18 -0
  256. package/dist/types.backup/rsc/nonce.d.ts +28 -0
  257. package/dist/types.backup/rsc/origin-guard.d.ts +50 -0
  258. package/dist/types.backup/rsc/progressive-enhancement.d.ts +19 -0
  259. package/dist/types.backup/rsc/redirect-guard.d.ts +35 -0
  260. package/dist/types.backup/rsc/response-cache-serve.d.ts +46 -0
  261. package/dist/types.backup/rsc/response-error.d.ts +19 -0
  262. package/dist/types.backup/rsc/response-route-handler.d.ts +29 -0
  263. package/dist/types.backup/rsc/rsc-rendering.d.ts +23 -0
  264. package/dist/types.backup/rsc/runtime-warnings.d.ts +22 -0
  265. package/dist/types.backup/rsc/server-action.d.ts +68 -0
  266. package/dist/types.backup/rsc/shell-build-manifest.d.ts +84 -0
  267. package/dist/types.backup/rsc/shell-capture-constants.d.ts +27 -0
  268. package/dist/types.backup/rsc/shell-capture.d.ts +374 -0
  269. package/dist/types.backup/rsc/shell-serve.d.ts +136 -0
  270. package/dist/types.backup/rsc/ssr-setup.d.ts +48 -0
  271. package/dist/types.backup/rsc/transition-gate.d.ts +27 -0
  272. package/dist/types.backup/rsc/types.d.ts +290 -0
  273. package/dist/types.backup/runtime-env.d.ts +1 -0
  274. package/dist/types.backup/search-params.d.ts +125 -0
  275. package/dist/types.backup/segment-content-promise.d.ts +13 -0
  276. package/dist/types.backup/segment-fragments.d.ts +56 -0
  277. package/dist/types.backup/segment-loader-promise.d.ts +22 -0
  278. package/dist/types.backup/segment-system.d.ts +84 -0
  279. package/dist/types.backup/serialize.d.ts +164 -0
  280. package/dist/types.backup/server/context.d.ts +494 -0
  281. package/dist/types.backup/server/cookie-parse.d.ts +10 -0
  282. package/dist/types.backup/server/cookie-store.d.ts +107 -0
  283. package/dist/types.backup/server/fetchable-loader-store.d.ts +20 -0
  284. package/dist/types.backup/server/handle-store.d.ts +100 -0
  285. package/dist/types.backup/server/loader-registry.d.ts +32 -0
  286. package/dist/types.backup/server/request-context.d.ts +596 -0
  287. package/dist/types.backup/server/root-layout.d.ts +3 -0
  288. package/dist/types.backup/server.d.ts +15 -0
  289. package/dist/types.backup/ssr/index.d.ts +233 -0
  290. package/dist/types.backup/ssr/inject-rsc-eager.d.ts +3 -0
  291. package/dist/types.backup/ssr/preinit-client-references.d.ts +71 -0
  292. package/dist/types.backup/ssr/ssr-root.d.ts +69 -0
  293. package/dist/types.backup/static-handler.d.ts +57 -0
  294. package/dist/types.backup/testing/cache-status.d.ts +63 -0
  295. package/dist/types.backup/testing/collect-handle.d.ts +20 -0
  296. package/dist/types.backup/testing/dispatch.d.ts +123 -0
  297. package/dist/types.backup/testing/dom.entry.d.ts +15 -0
  298. package/dist/types.backup/testing/e2e/fixture.d.ts +37 -0
  299. package/dist/types.backup/testing/e2e/index.d.ts +30 -0
  300. package/dist/types.backup/testing/e2e/matchers.d.ts +17 -0
  301. package/dist/types.backup/testing/e2e/page-helpers.d.ts +62 -0
  302. package/dist/types.backup/testing/e2e/parity.d.ts +111 -0
  303. package/dist/types.backup/testing/e2e/server.d.ts +35 -0
  304. package/dist/types.backup/testing/flight-matchers.d.ts +55 -0
  305. package/dist/types.backup/testing/flight-normalize.d.ts +1 -0
  306. package/dist/types.backup/testing/flight-tree.d.ts +192 -0
  307. package/dist/types.backup/testing/flight.d.ts +115 -0
  308. package/dist/types.backup/testing/flight.entry.d.ts +27 -0
  309. package/dist/types.backup/testing/generated-routes.d.ts +66 -0
  310. package/dist/types.backup/testing/index.d.ts +52 -0
  311. package/dist/types.backup/testing/internal/context.d.ts +225 -0
  312. package/dist/types.backup/testing/internal/flight-client-globals.d.ts +1 -0
  313. package/dist/types.backup/testing/internal/seed-vars.d.ts +30 -0
  314. package/dist/types.backup/testing/render-handler.d.ts +160 -0
  315. package/dist/types.backup/testing/render-route.d.ts +246 -0
  316. package/dist/types.backup/testing/run-loader.d.ts +186 -0
  317. package/dist/types.backup/testing/run-middleware.d.ts +132 -0
  318. package/dist/types.backup/testing/run-transition-when.d.ts +77 -0
  319. package/dist/types.backup/testing/vitest-stubs/cloudflare-email.d.ts +6 -0
  320. package/dist/types.backup/testing/vitest-stubs/cloudflare-workers.d.ts +13 -0
  321. package/dist/types.backup/testing/vitest-stubs/plugin-rsc.d.ts +7 -0
  322. package/dist/types.backup/testing/vitest-stubs/version.d.ts +1 -0
  323. package/dist/types.backup/testing/vitest.d.ts +205 -0
  324. package/dist/types.backup/theme/ThemeProvider.d.ts +13 -0
  325. package/dist/types.backup/theme/ThemeScript.d.ts +45 -0
  326. package/dist/types.backup/theme/constants.d.ts +39 -0
  327. package/dist/types.backup/theme/index.d.ts +29 -0
  328. package/dist/types.backup/theme/theme-context.d.ts +21 -0
  329. package/dist/types.backup/theme/theme-script.d.ts +26 -0
  330. package/dist/types.backup/theme/types.d.ts +162 -0
  331. package/dist/types.backup/theme/use-theme.d.ts +8 -0
  332. package/dist/types.backup/types/boundaries.d.ts +93 -0
  333. package/dist/types.backup/types/cache-types.d.ts +191 -0
  334. package/dist/types.backup/types/error-types.d.ts +114 -0
  335. package/dist/types.backup/types/global-namespace.d.ts +90 -0
  336. package/dist/types.backup/types/handler-context.d.ts +658 -0
  337. package/dist/types.backup/types/index.d.ts +11 -0
  338. package/dist/types.backup/types/loader-types.d.ts +182 -0
  339. package/dist/types.backup/types/request-scope.d.ts +93 -0
  340. package/dist/types.backup/types/route-config.d.ts +105 -0
  341. package/dist/types.backup/types/route-entry.d.ts +95 -0
  342. package/dist/types.backup/types/segments.d.ts +234 -0
  343. package/dist/types.backup/types.d.ts +1 -0
  344. package/dist/types.backup/urls/include-helper.d.ts +17 -0
  345. package/dist/types.backup/urls/include-provider.d.ts +27 -0
  346. package/dist/types.backup/urls/index.d.ts +6 -0
  347. package/dist/types.backup/urls/path-helper-types.d.ts +197 -0
  348. package/dist/types.backup/urls/path-helper.d.ts +12 -0
  349. package/dist/types.backup/urls/pattern-types.d.ts +166 -0
  350. package/dist/types.backup/urls/response-types.d.ts +67 -0
  351. package/dist/types.backup/urls/type-extraction.d.ts +157 -0
  352. package/dist/types.backup/urls/urls-function.d.ts +24 -0
  353. package/dist/types.backup/urls.d.ts +1 -0
  354. package/dist/types.backup/use-loader.d.ts +150 -0
  355. package/dist/types.backup/vercel/index.d.ts +10 -0
  356. package/dist/types.backup/vercel/tracing.d.ts +70 -0
  357. package/dist/types.backup/vite/debug.d.ts +80 -0
  358. package/dist/types.backup/vite/discovery/bundle-postprocess.d.ts +12 -0
  359. package/dist/types.backup/vite/discovery/dev-prerender-cache.d.ts +65 -0
  360. package/dist/types.backup/vite/discovery/discover-routers.d.ts +17 -0
  361. package/dist/types.backup/vite/discovery/discovery-errors.d.ts +113 -0
  362. package/dist/types.backup/vite/discovery/gate-state.d.ts +79 -0
  363. package/dist/types.backup/vite/discovery/prerender-collection.d.ts +24 -0
  364. package/dist/types.backup/vite/discovery/route-types-writer.d.ts +32 -0
  365. package/dist/types.backup/vite/discovery/self-gen-tracking.d.ts +22 -0
  366. package/dist/types.backup/vite/discovery/shell-prerender-phase.d.ts +40 -0
  367. package/dist/types.backup/vite/discovery/state.d.ts +162 -0
  368. package/dist/types.backup/vite/discovery/virtual-module-codegen.d.ts +15 -0
  369. package/dist/types.backup/vite/index.d.ts +11 -0
  370. package/dist/types.backup/vite/inject-client-debug.d.ts +56 -0
  371. package/dist/types.backup/vite/plugin-types.d.ts +298 -0
  372. package/dist/types.backup/vite/plugins/cjs-to-esm.d.ts +6 -0
  373. package/dist/types.backup/vite/plugins/client-ref-dedup.d.ts +40 -0
  374. package/dist/types.backup/vite/plugins/client-ref-hashing.d.ts +35 -0
  375. package/dist/types.backup/vite/plugins/cloudflare-protocol-stub.d.ts +64 -0
  376. package/dist/types.backup/vite/plugins/expose-action-id.d.ts +18 -0
  377. package/dist/types.backup/vite/plugins/expose-id-utils.d.ts +37 -0
  378. package/dist/types.backup/vite/plugins/expose-ids/export-analysis.d.ts +19 -0
  379. package/dist/types.backup/vite/plugins/expose-ids/handler-transform.d.ts +10 -0
  380. package/dist/types.backup/vite/plugins/expose-ids/loader-transform.d.ts +8 -0
  381. package/dist/types.backup/vite/plugins/expose-ids/router-transform.d.ts +13 -0
  382. package/dist/types.backup/vite/plugins/expose-ids/types.d.ts +29 -0
  383. package/dist/types.backup/vite/plugins/expose-internal-ids.d.ts +6 -0
  384. package/dist/types.backup/vite/plugins/performance-tracks.d.ts +25 -0
  385. package/dist/types.backup/vite/plugins/refresh-cmd.d.ts +20 -0
  386. package/dist/types.backup/vite/plugins/use-cache-transform.d.ts +20 -0
  387. package/dist/types.backup/vite/plugins/vercel-output.d.ts +85 -0
  388. package/dist/types.backup/vite/plugins/version-injector.d.ts +21 -0
  389. package/dist/types.backup/vite/plugins/version-plugin.d.ts +19 -0
  390. package/dist/types.backup/vite/plugins/virtual-entries.d.ts +36 -0
  391. package/dist/types.backup/vite/plugins/virtual-stub-plugin.d.ts +7 -0
  392. package/dist/types.backup/vite/rango.d.ts +29 -0
  393. package/dist/types.backup/vite/router-discovery.d.ts +23 -0
  394. package/dist/types.backup/vite/utils/ast-handler-extract.d.ts +64 -0
  395. package/dist/types.backup/vite/utils/banner.d.ts +2 -0
  396. package/dist/types.backup/vite/utils/bundle-analysis.d.ts +28 -0
  397. package/dist/types.backup/vite/utils/client-chunks.d.ts +55 -0
  398. package/dist/types.backup/vite/utils/directive-prologue.d.ts +16 -0
  399. package/dist/types.backup/vite/utils/forward-user-plugins.d.ts +37 -0
  400. package/dist/types.backup/vite/utils/manifest-utils.d.ts +7 -0
  401. package/dist/types.backup/vite/utils/package-resolution.d.ts +6 -0
  402. package/dist/types.backup/vite/utils/prerender-utils.d.ts +32 -0
  403. package/dist/types.backup/vite/utils/shared-utils.d.ts +55 -0
  404. package/dist/vite/index.js +1 -1
  405. package/package.json +1 -1
  406. package/skills/parallel/SKILL.md +1 -1
  407. package/skills/ppr/SKILL.md +44 -3
  408. package/src/browser/prefetch/cache.ts +53 -9
  409. package/src/browser/prefetch/fetch.ts +83 -2
  410. package/src/cache/cf/cf-cache-store.ts +27 -8
  411. package/src/cache/types.ts +41 -6
  412. package/src/cache/vercel/vercel-cache-store.ts +24 -10
  413. package/src/route-definition/helpers-types.ts +5 -3
  414. package/src/rsc/capture-queue.ts +120 -47
  415. package/src/rsc/rsc-rendering.ts +11 -3
  416. package/src/rsc/shell-build-manifest.ts +20 -7
  417. package/src/rsc/shell-capture.ts +164 -12
  418. package/src/rsc/shell-serve.ts +27 -12
  419. package/src/static-handler.ts +18 -2
  420. package/src/urls/path-helper-types.ts +9 -10
@@ -19,15 +19,55 @@
19
19
  * is bounded; a capture killed mid-queue by that bound simply recaptures on a
20
20
  * later request (the existing best-effort contract).
21
21
  *
22
- * The chain link resolves in `finally` and the prior link is awaited with a
23
- * swallow, so one rejected capture can never wedge every later one.
22
+ * Document shells outrank queued navigation-only snapshots. Production Link
23
+ * prefetching can enqueue several expensive navigation captures at once; a
24
+ * strict FIFO made the requesting page's document capture wait
25
+ * behind speculative work until its queue budget expired. The active capture
26
+ * is never interrupted, and each priority remains FIFO.
24
27
  */
25
- let captureQueue: Promise<void> = Promise.resolve();
26
28
  let admittedCaptures = 0;
29
+ let captureRunning = false;
30
+
31
+ interface QueuedCapture {
32
+ waitStart: number;
33
+ state: "waiting" | "running" | "settled";
34
+ signalStart: () => void;
35
+ }
36
+
37
+ const documentCaptures: QueuedCapture[] = [];
38
+ const navigationCaptures: QueuedCapture[] = [];
27
39
 
28
40
  /** Bound queued/running capture closures retained by one isolate. */
29
41
  export const MAX_ADMITTED_CAPTURES: number = 32;
30
42
 
43
+ /** Point-in-time queue occupancy, for capture-scheduling telemetry. */
44
+ export interface CaptureQueueDepths {
45
+ /** A capture is currently executing (never preempted). */
46
+ running: boolean;
47
+ /** Waiting document-priority captures (run before every navigation capture). */
48
+ document: number;
49
+ /** Waiting navigation-priority captures. */
50
+ navigation: number;
51
+ }
52
+
53
+ /**
54
+ * Snapshot the queue's waiting/running state. Wait-timed-out entries still
55
+ * sitting in the arrays (pruned lazily by takeNextCapture) are excluded — they
56
+ * will never run, so counting them would overstate the backlog.
57
+ */
58
+ export function captureQueueDepths(): CaptureQueueDepths {
59
+ const waiting = (queue: QueuedCapture[]): number => {
60
+ let count = 0;
61
+ for (const queued of queue) if (queued.state === "waiting") count++;
62
+ return count;
63
+ };
64
+ return {
65
+ running: captureRunning,
66
+ document: waiting(documentCaptures),
67
+ navigation: waiting(navigationCaptures),
68
+ };
69
+ }
70
+
31
71
  /** The caller may drop this best-effort capture and retry on a later request. */
32
72
  export class CaptureQueueFullError extends Error {
33
73
  constructor() {
@@ -65,7 +105,7 @@ export class CaptureQueueWaitTimeoutError extends Error {
65
105
  }
66
106
 
67
107
  /**
68
- * Upper bound on how long one queue link may hold the queue. A capture task
108
+ * Upper bound on how long one running capture may hold the queue. A capture task
69
109
  * normally settles well inside this (attempt + in-place retry + writes), but
70
110
  * a task wedged on never-settling I/O — a workerd waitUntil fetch that pends
71
111
  * instead of rejecting (seen on GH runners with the dev prerender store
@@ -76,70 +116,103 @@ export class CaptureQueueWaitTimeoutError extends Error {
76
116
  const QUEUE_LINK_CAP_MS = 60_000;
77
117
 
78
118
  /**
79
- * Run `task` after every previously enqueued capture has settled. Returns a
80
- * promise for THIS task's completion (rejections propagate to the caller —
81
- * the queue itself is insulated).
119
+ * Run `task` after the active capture and every higher/equal-priority capture
120
+ * ahead of it have settled. Returns a promise for THIS task's completion
121
+ * (rejections propagate to the caller — the queue itself is insulated).
82
122
  */
83
123
  export function enqueueSerializedCapture(
84
124
  task: () => Promise<void>,
85
- opts?: { maxQueueWaitMs?: number },
125
+ opts?: {
126
+ maxQueueWaitMs?: number;
127
+ priority?: "document" | "navigation";
128
+ },
86
129
  ): Promise<void> {
87
130
  if (admittedCaptures >= MAX_ADMITTED_CAPTURES) {
88
131
  return Promise.reject(new CaptureQueueFullError());
89
132
  }
90
133
  admittedCaptures++;
91
- const prior = captureQueue;
92
- let releaseQueue!: () => void;
93
- captureQueue = new Promise<void>((resolve) => {
94
- releaseQueue = resolve;
134
+
135
+ let signalStart!: () => void;
136
+ const startGate = new Promise<void>((resolve) => {
137
+ signalStart = resolve;
95
138
  });
96
- return (async () => {
97
- const waitStart = performance.now();
139
+ const queued: QueuedCapture = {
140
+ waitStart: performance.now(),
141
+ state: "waiting",
142
+ signalStart,
143
+ };
144
+
145
+ const completion = (async () => {
98
146
  const budget = opts?.maxQueueWaitMs ?? CAPTURE_QUEUE_WAIT_BUDGET_MS;
99
- // The wait itself is budget-raced: the drop fires AT the budget, not once
100
- // the predecessor eventually settles — a waiter parked behind a wedged
101
- // link must not stay pending until that link's 60s cap just to learn it
102
- // was already over budget.
103
147
  let waitTimer: ReturnType<typeof setTimeout> | undefined;
104
148
  const waitTimedOut = await Promise.race([
105
- prior.catch(() => {}).then(() => false),
149
+ startGate.then(() => false),
106
150
  new Promise<boolean>((resolve) => {
107
- waitTimer = setTimeout(() => resolve(true), budget);
151
+ waitTimer = setTimeout(() => {
152
+ if (queued.state !== "waiting") return;
153
+ queued.state = "settled";
154
+ admittedCaptures--;
155
+ resolve(true);
156
+ }, budget);
108
157
  (waitTimer as { unref?: () => void }).unref?.();
109
158
  }),
110
159
  ]);
111
160
  if (waitTimer) clearTimeout(waitTimer);
112
161
  if (waitTimedOut) {
113
- // Never started: hand the admission slot back here (the taskPromise
114
- // finally below does it for tasks that ran). Serialization stays
115
- // intact: THIS link releases only once the predecessor settles —
116
- // releasing now would let a successor run concurrently with it.
117
- admittedCaptures--;
118
- prior.catch(() => {}).then(releaseQueue, releaseQueue);
119
- throw new CaptureQueueWaitTimeoutError(performance.now() - waitStart);
162
+ throw new CaptureQueueWaitTimeoutError(
163
+ performance.now() - queued.waitStart,
164
+ );
120
165
  }
166
+
167
+ let capTimer: ReturnType<typeof setTimeout> | undefined;
168
+ const taskPromise = Promise.resolve()
169
+ .then(task)
170
+ .finally(() => {
171
+ // A capped capture releases serialization, but its detached task still
172
+ // counts against admission until it actually settles.
173
+ admittedCaptures--;
174
+ });
175
+ const cap = new Promise<void>((resolve) => {
176
+ capTimer = setTimeout(resolve, QUEUE_LINK_CAP_MS);
177
+ (capTimer as { unref?: () => void }).unref?.();
178
+ });
179
+
121
180
  try {
122
- let capTimer: ReturnType<typeof setTimeout> | undefined;
123
- const taskPromise = Promise.resolve()
124
- .then(task)
125
- .finally(() => {
126
- // A timed-out link releases serialization, but its detached task still
127
- // counts against admission until it actually settles.
128
- admittedCaptures--;
129
- });
130
- try {
131
- await Promise.race([
132
- taskPromise,
133
- new Promise<void>((resolve) => {
134
- capTimer = setTimeout(resolve, QUEUE_LINK_CAP_MS);
135
- (capTimer as { unref?: () => void }).unref?.();
136
- }),
137
- ]);
138
- } finally {
139
- if (capTimer) clearTimeout(capTimer);
140
- }
181
+ await Promise.race([taskPromise, cap]);
141
182
  } finally {
142
- releaseQueue();
183
+ if (capTimer) clearTimeout(capTimer);
184
+ queued.state = "settled";
185
+ captureRunning = false;
186
+ // Handoff must happen before this caller's waitUntil promise settles.
187
+ // Resolving first lets workerd terminate the context with the queue lock
188
+ // still held, permanently parking later captures in the isolate.
189
+ startNextCapture();
143
190
  }
144
191
  })();
192
+
193
+ const queue =
194
+ opts?.priority === "document" ? documentCaptures : navigationCaptures;
195
+ queue.push(queued);
196
+ startNextCapture();
197
+ return completion;
198
+ }
199
+
200
+ function takeNextCapture(): QueuedCapture | undefined {
201
+ for (const queue of [documentCaptures, navigationCaptures]) {
202
+ let queued: QueuedCapture | undefined;
203
+ while ((queued = queue.shift())) {
204
+ if (queued.state === "waiting") return queued;
205
+ }
206
+ }
207
+ return undefined;
208
+ }
209
+
210
+ function startNextCapture(): void {
211
+ if (captureRunning) return;
212
+ const queued = takeNextCapture();
213
+ if (!queued) return;
214
+
215
+ captureRunning = true;
216
+ queued.state = "running";
217
+ queued.signalStart();
145
218
  }
@@ -79,6 +79,7 @@ import { reportCacheError } from "../cache/cache-error.js";
79
79
  import type { SearchParamsFilter } from "../cache/search-params-filter.js";
80
80
  import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
81
81
  import type {
82
+ DocumentShellCacheEntry,
82
83
  SegmentCacheStore,
83
84
  ShellCacheEntry,
84
85
  ShellSnapshotRecord,
@@ -212,7 +213,14 @@ function replayableShellSnapshot(
212
213
  if (!isValidShellHit(entry, buildVersion)) {
213
214
  return { reason: "invalid-version" };
214
215
  }
215
- if (!hasIntactShellPayload(entry)) return { reason: "corrupt-entry" };
216
+ // navigationOnly entries store no document half (prelude/postponed absent),
217
+ // so the payload gate applies to document-snapshot entries alone. Replay
218
+ // consumes only the snapshot; fragment corruption inside it is caught by the
219
+ // consumer-side Flight decoders (SegmentFragmentDecodeError →
220
+ // segmentReplayCorrupt → healing capture at the document key).
221
+ if (!entry.navigationOnly && !hasIntactShellPayload(entry)) {
222
+ return { reason: "corrupt-entry" };
223
+ }
216
224
  if (entry.handlerLiveHoles) return { reason: "handler-live-holes" };
217
225
  if (entry.transitionWhen) return { reason: "transition-when" };
218
226
  // Eligibility requires the CANONICAL doc segment record (`docKey`), not just
@@ -386,7 +394,7 @@ async function handleRscRenderingInner<TEnv>(
386
394
  // build-manifest hit further down): schedule the background
387
395
  // recapture when asked, then commit the composed response.
388
396
  const serveHit = (
389
- entry: ShellCacheEntry,
397
+ entry: DocumentShellCacheEntry,
390
398
  revalidate: boolean | undefined,
391
399
  ): Response => {
392
400
  if (revalidate) {
@@ -1159,7 +1167,7 @@ function serveShellHit(
1159
1167
  reqCtx: RequestContext<any>,
1160
1168
  handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
1161
1169
  ssrModule: SSRModule,
1162
- entry: ShellCacheEntry,
1170
+ entry: DocumentShellCacheEntry,
1163
1171
  descriptor: ShellCaptureDescriptor,
1164
1172
  ): Response {
1165
1173
  const preludeBytes = base64ToBytes(entry.prelude);
@@ -25,7 +25,11 @@
25
25
  * markers say whether it is still current.
26
26
  */
27
27
 
28
- import type { SegmentCacheStore, ShellCacheEntry } from "../cache/types.js";
28
+ import type {
29
+ DocumentShellCacheEntry,
30
+ SegmentCacheStore,
31
+ ShellCacheEntry,
32
+ } from "../cache/types.js";
29
33
  import { sortedSearchString } from "../cache/cache-key-utils.js";
30
34
  import type { SearchParamsFilter } from "../cache/search-params-filter.js";
31
35
  import {
@@ -88,20 +92,29 @@ function loadManifest(): Promise<ShellManifestModule | null> {
88
92
  * Spec-only keying is sound because buildVersion is process-constant on the
89
93
  * manifest path (folded into the shipped worker; dev never loads a manifest).
90
94
  */
91
- const validatedSpecs = new Map<string, BuildShellEntry | null>();
95
+ const validatedSpecs = new Map<string, ValidatedBuildShellEntry | null>();
96
+
97
+ /**
98
+ * A manifest record whose document half passed hasIntactShellPayload — the
99
+ * casts below sit directly on that runtime gate (build entries are always
100
+ * document-shaped; the predicate narrows entry, not the record around it).
101
+ */
102
+ type ValidatedBuildShellEntry = BuildShellEntry & {
103
+ entry: DocumentShellCacheEntry;
104
+ };
92
105
 
93
106
  async function validatedManifestRecord(
94
107
  mod: ShellManifestModule,
95
108
  spec: string,
96
109
  buildVersion: string,
97
- ): Promise<BuildShellEntry | undefined> {
110
+ ): Promise<ValidatedBuildShellEntry | undefined> {
98
111
  let verdict = validatedSpecs.get(spec);
99
112
  if (verdict === undefined) {
100
113
  const record = (await mod.loadShellAsset(spec)).default;
101
114
  verdict =
102
115
  isValidShellHit(record.entry, buildVersion) &&
103
116
  hasIntactShellPayload(record.entry)
104
- ? record
117
+ ? (record as ValidatedBuildShellEntry)
105
118
  : null;
106
119
  validatedSpecs.set(spec, verdict);
107
120
  }
@@ -118,7 +131,7 @@ export function resetBuildShellManifestForTests(): void {
118
131
  const warnedTagCheckUnsupported = new Set<string>();
119
132
 
120
133
  export interface BuildShellHit {
121
- entry: ShellCacheEntry;
134
+ entry: DocumentShellCacheEntry;
122
135
  /** Past createdAt + ttl: serve, but schedule the runtime recapture. */
123
136
  stale: boolean;
124
137
  }
@@ -273,7 +286,7 @@ export async function lookupBuildShell(
273
286
  const hasManifest = globalThis.__loadShellManifestModule !== undefined;
274
287
  if (!hasManifest && !dev) return null;
275
288
  if (sortedSearchString(url.searchParams, filter) !== "") return null;
276
- let record: BuildShellEntry | undefined;
289
+ let record: ValidatedBuildShellEntry | undefined;
277
290
  if (hasManifest) {
278
291
  const mod = await loadManifest();
279
292
  if (!mod) return null;
@@ -286,7 +299,7 @@ export async function lookupBuildShell(
286
299
  fetched !== undefined &&
287
300
  isValidShellHit(fetched.entry, buildVersion) &&
288
301
  hasIntactShellPayload(fetched.entry)
289
- ? fetched
302
+ ? (fetched as ValidatedBuildShellEntry)
290
303
  : undefined;
291
304
  }
292
305
  if (!record) return null;
@@ -23,6 +23,7 @@ import { runBackground } from "../cache/background-task.js";
23
23
  import {
24
24
  CaptureQueueFullError,
25
25
  CaptureQueueWaitTimeoutError,
26
+ captureQueueDepths,
26
27
  enqueueSerializedCapture,
27
28
  } from "./capture-queue.js";
28
29
  import { SHELL_CAPTURE_MAX_WAIT_MS } from "./shell-capture-constants.js";
@@ -397,6 +398,43 @@ function warnSnapshotOverCapOnce(
397
398
  );
398
399
  }
399
400
 
401
+ /**
402
+ * Dev warning threshold (ms) for the slowest bake-source settlement wait. Bake
403
+ * time is by-design shell latency (top-level pushed handle promises and
404
+ * bake-lane loader containers settle before the freeze), but it recurs on
405
+ * EVERY capture of the route and occupies the per-isolate serialized capture
406
+ * queue — silently: the served response's own timing never shows it (a route
407
+ * can read 13ms TTFB while each of its captures holds the queue for seconds).
408
+ * Past this threshold the source gets named once per key with the remedy
409
+ * ladder.
410
+ */
411
+ const SHELL_CAPTURE_BAKE_WARN_MS = 2_000;
412
+
413
+ /** Keys already warned about an expensive bake source (once per key). */
414
+ const warnedBakeCosts = new Set<string>();
415
+
416
+ /**
417
+ * Dev-only, once per key: name the slowest bake source and the three remedies
418
+ * in preference order. The doctrine ("nesting = liveness") makes the cost
419
+ * legitimate, so this is a cost report with an exit, not a deprecation.
420
+ */
421
+ function warnBakeCostOnce(key: string, source: string, ms: number): void {
422
+ if (warnedBakeCosts.has(key)) return;
423
+ warnedBakeCosts.add(key);
424
+ console.warn(
425
+ `[rango] Shell capture for "${key}" waited ${ms}ms for ${source} to ` +
426
+ "settle before the shell could freeze. This cost recurs on every capture " +
427
+ "of the route and occupies the per-isolate capture queue; the served " +
428
+ "response never shows it. Top-level promises BAKE by design (the " +
429
+ "container settles; nested promises stay live). To make the value " +
430
+ "per-request instead, nest it ({ data: promise }) and read it with use() " +
431
+ "under Suspense; to keep it baked but cheap, wrap the work in cache() " +
432
+ "(the capture replays the cached value); for a segment loader, add a " +
433
+ "loading() boundary to its entry (live lane, masked at capture). See the " +
434
+ "/ppr skill (node_modules/@rangojs/router/skills/ppr/SKILL.md).",
435
+ );
436
+ }
437
+
400
438
  /**
401
439
  * One structured event from the background capture pipeline, mirroring the
402
440
  * CFCacheReadDebugEvent pattern (cache/cf/cf-cache-types.ts): typed fields an
@@ -418,6 +456,10 @@ export interface ShellCaptureDebugEvent {
418
456
  * - skip-backoff: the key is inside its refused-capture backoff window and
419
457
  * the capture was not attempted
420
458
  * - skip-capacity: the isolate capture queue is full; a later request may retry
459
+ * - skip-inert-store: the resolved store's shell family is missing or
460
+ * declared inert (SegmentCacheStore.shellFamilyInert — a CFCacheStore
461
+ * without a KV namespace); nothing could store the result, so the
462
+ * background render was not scheduled at all
421
463
  * - skip-queue-timeout: the capture waited past CAPTURE_QUEUE_WAIT_BUDGET_MS
422
464
  * behind other captures and was dropped unrun (no backoff — the route is
423
465
  * not doomed, the isolate was busy; a later request re-probes). Carries
@@ -434,6 +476,7 @@ export interface ShellCaptureDebugEvent {
434
476
  | "skip-in-flight"
435
477
  | "skip-backoff"
436
478
  | "skip-capacity"
479
+ | "skip-inert-store"
437
480
  | "skip-queue-timeout"
438
481
  | "backoff";
439
482
  /** Attempt number (1 = first, 2 = in-place retry). Absent on skips. */
@@ -466,6 +509,22 @@ export interface ShellCaptureDebugEvent {
466
509
  backoffRemainingMs?: number;
467
510
  /** Ms the capture waited in the serialized queue (skip-queue-timeout). */
468
511
  queueWaitMs?: number;
512
+ /** Queue priority class at enqueue: document outranks queued navigation. */
513
+ queuePriority?: "document" | "navigation";
514
+ /**
515
+ * Captures ahead at enqueue: the active one plus every waiting capture of
516
+ * same-or-higher priority. 0 = this capture starts immediately.
517
+ */
518
+ queueAhead?: number;
519
+ /**
520
+ * Ms the capture gate was HELD waiting for the slowest bake source — a
521
+ * top-level pushed handle promise or a bake-lane loader container — to
522
+ * settle, measured from capture start. Bake time is by-design shell latency
523
+ * (the hole doctrine: top-level promises bake), but it recurs on EVERY
524
+ * capture of the route and occupies the serialized queue; this field makes
525
+ * it attributable. Absent when nothing held the gate.
526
+ */
527
+ bakeWaitMs?: number;
469
528
  }
470
529
 
471
530
  /**
@@ -515,6 +574,15 @@ export function describeShellCaptureEvent(
515
574
  if (event.queueWaitMs !== undefined) {
516
575
  parts.push(`queue-wait=${event.queueWaitMs}ms`);
517
576
  }
577
+ if (event.queuePriority !== undefined) {
578
+ parts.push(`queue-priority=${event.queuePriority}`);
579
+ }
580
+ if (event.queueAhead !== undefined) {
581
+ parts.push(`queue-ahead=${event.queueAhead}`);
582
+ }
583
+ if (event.bakeWaitMs !== undefined) {
584
+ parts.push(`bake=${event.bakeWaitMs}ms`);
585
+ }
518
586
  return parts.join(" ");
519
587
  }
520
588
 
@@ -864,6 +932,16 @@ export function scheduleShellCapture(
864
932
  });
865
933
  return;
866
934
  }
935
+ // A capture whose write can only no-op is dead work that still occupies the
936
+ // serialized queue (a promise-heavy route bakes for seconds per MISS),
937
+ // starving captures that CAN store. Skip scheduling entirely when the
938
+ // resolved store (same defaulting as captureAndStoreShell) has no shell
939
+ // family or declared it inert (CFCacheStore without a KV namespace).
940
+ const scheduledStore = descriptor.store ?? reqCtx._cacheStore;
941
+ if (!scheduledStore?.putShell || scheduledStore.shellFamilyInert) {
942
+ publishCaptureDebugEvent(descriptor, { key, outcome: "skip-inert-store" });
943
+ return;
944
+ }
867
945
  inFlightCaptures.add(key);
868
946
  const captureTask = async (span: TraceSpan) => {
869
947
  try {
@@ -941,15 +1019,34 @@ export function scheduleShellCapture(
941
1019
  const serializedTask = async () => {
942
1020
  await observePhase(PHASES.background("shell-capture"), async (span) => {
943
1021
  span.setAttribute("rango.shell_key", key);
1022
+ // A production page can enqueue several navigation-only captures through
1023
+ // viewport prefetching. Let a later document MISS overtake that queued
1024
+ // speculative work so it can become a shell HIT before the 15s queue
1025
+ // budget expires. Never preempts the active capture. Priority and the
1026
+ // backlog ahead at enqueue ride the span (and the skip event below), so
1027
+ // a skip-queue-timeout diagnoses itself instead of needing a trace dive.
1028
+ const queuePriority = descriptor.navigationOnly
1029
+ ? ("navigation" as const)
1030
+ : ("document" as const);
1031
+ const depths = captureQueueDepths();
1032
+ const queueAhead =
1033
+ (depths.running ? 1 : 0) +
1034
+ depths.document +
1035
+ (queuePriority === "navigation" ? depths.navigation : 0);
1036
+ span.setAttribute("rango.background.queue_priority", queuePriority);
1037
+ span.setAttribute("rango.background.queue_ahead", queueAhead);
944
1038
  const queueStart = performance.now();
945
1039
  try {
946
- await enqueueSerializedCapture(() => {
947
- span.setAttribute(
948
- "rango.background.queue_wait_ms",
949
- Math.round(performance.now() - queueStart),
950
- );
951
- return captureTask(span);
952
- });
1040
+ await enqueueSerializedCapture(
1041
+ () => {
1042
+ span.setAttribute(
1043
+ "rango.background.queue_wait_ms",
1044
+ Math.round(performance.now() - queueStart),
1045
+ );
1046
+ return captureTask(span);
1047
+ },
1048
+ { priority: queuePriority },
1049
+ );
953
1050
  } catch (error) {
954
1051
  if (error instanceof CaptureQueueFullError) {
955
1052
  inFlightCaptures.delete(key);
@@ -974,6 +1071,8 @@ export function scheduleShellCapture(
974
1071
  key,
975
1072
  outcome: "skip-queue-timeout",
976
1073
  queueWaitMs: Math.round(error.waitedMs),
1074
+ queuePriority,
1075
+ queueAhead,
977
1076
  });
978
1077
  return;
979
1078
  }
@@ -1035,6 +1134,7 @@ type CaptureAttemptStats = Pick<
1035
1134
  | "snapshotSkipped"
1036
1135
  | "untaggedBake"
1037
1136
  | "storeWrite"
1137
+ | "bakeWaitMs"
1038
1138
  >;
1039
1139
 
1040
1140
  /**
@@ -1511,6 +1611,29 @@ async function captureAndStoreShell(
1511
1611
  loaderRecordsForHold && loaderRecordsForHold.size > 0
1512
1612
  ? Promise.allSettled([handlesBaked, ...loaderRecordsForHold.values()])
1513
1613
  : handlesBaked;
1614
+ // Bake-cost attribution: record how long each bake source held the gate,
1615
+ // measured from capture start. Side-channel observers only — holdUntil and
1616
+ // its consumers are untouched, and a rejected source is recorded the same
1617
+ // (allSettled swallows it; the drain below owns the refusal). Folded into
1618
+ // stats.bakeWaitMs (+ a once-per-key dev warning) after a successful
1619
+ // capture; on a refusal the other warnings own the story.
1620
+ const bakeStart = performance.now();
1621
+ const bakeWaits: { source: string; ms: number }[] = [];
1622
+ const observeBake = (source: string, promise: Promise<unknown>): void => {
1623
+ const record = (): void => {
1624
+ bakeWaits.push({
1625
+ source,
1626
+ ms: Math.round(performance.now() - bakeStart),
1627
+ });
1628
+ };
1629
+ promise.then(record, record);
1630
+ };
1631
+ observeBake("top-level pushed handle promises", handlesBaked);
1632
+ if (loaderRecordsForHold) {
1633
+ for (const [loaderId, promise] of loaderRecordsForHold) {
1634
+ observeBake(`bake-lane segment loader "${loaderId}"`, promise);
1635
+ }
1636
+ }
1514
1637
  const gate = gateFlightForCapture(rscStream, undefined, holdUntil);
1515
1638
  // Quiesce = handles settled AND the Flight shell rows went task-quiet. Either
1516
1639
  // half stalling is bounded by captureShellHTML's maxWaitMs.
@@ -1590,6 +1713,23 @@ async function captureAndStoreShell(
1590
1713
  }
1591
1714
  if (stats) stats.preludeBytes = result.prelude.length;
1592
1715
 
1716
+ // Every bake source has settled by here (quiesce gates on holdUntil).
1717
+ // Surface the slowest one: sub-ms settles are noise, threshold-crossers
1718
+ // get the dev warning with the remedy ladder.
1719
+ let slowestBake: { source: string; ms: number } | undefined;
1720
+ for (const wait of bakeWaits) {
1721
+ if (!slowestBake || wait.ms > slowestBake.ms) slowestBake = wait;
1722
+ }
1723
+ if (slowestBake && slowestBake.ms > 0) {
1724
+ if (stats) stats.bakeWaitMs = slowestBake.ms;
1725
+ if (
1726
+ process.env.NODE_ENV !== "production" &&
1727
+ slowestBake.ms >= SHELL_CAPTURE_BAKE_WARN_MS
1728
+ ) {
1729
+ warnBakeCostOnce(capture.key, slowestBake.source, slowestBake.ms);
1730
+ }
1731
+ }
1732
+
1593
1733
  // Store per the flag's key/ttl/swr/tags, into the flag's store: the middleware
1594
1734
  // threads the SAME store it resolved for its getShell read (options.store ??
1595
1735
  // _cacheStore), so a store-attached middleware writes captures where it reads
@@ -1746,11 +1886,23 @@ async function captureAndStoreShell(
1746
1886
  if (store?.putShell) {
1747
1887
  try {
1748
1888
  const entry: ShellCacheEntry = {
1749
- // slice() copies just this view's bytes into a fresh ArrayBuffer, so a
1750
- // prelude that is a subarray of a larger backing buffer encodes only its
1751
- // own region bufferToBase64 reads the whole ArrayBuffer it is handed.
1752
- prelude: bufferToBase64(result.prelude.slice().buffer as ArrayBuffer),
1753
- postponed: result.postponed,
1889
+ // Document half only for document captures. A navigationOnly entry's
1890
+ // HTML is never served (document reads skip the flag; partial replay
1891
+ // consumes only snapshot/docKey), so storing it would ride every KV
1892
+ // write/read as dead weight — the prerender still ran above as the
1893
+ // completeness arbiter and sanity gate, its output is dropped here.
1894
+ ...(capture.navigationOnly
1895
+ ? {}
1896
+ : {
1897
+ // slice() copies just this view's bytes into a fresh
1898
+ // ArrayBuffer, so a prelude that is a subarray of a larger
1899
+ // backing buffer encodes only its own region — bufferToBase64
1900
+ // reads the whole ArrayBuffer it is handed.
1901
+ prelude: bufferToBase64(
1902
+ result.prelude.slice().buffer as ArrayBuffer,
1903
+ ),
1904
+ postponed: result.postponed,
1905
+ }),
1754
1906
  reactVersion: React.version,
1755
1907
  buildVersion: capture.buildVersion,
1756
1908
  // The theme this capture's payload was built with (buildFullPayload
@@ -20,7 +20,11 @@ import React from "react";
20
20
  import { isPprEntry, type EntryData } from "../server/context.js";
21
21
  import { sortedSearchString } from "../cache/cache-key-utils.js";
22
22
  import type { SearchParamsFilter } from "../cache/search-params-filter.js";
23
- import type { ShellCacheEntry, SegmentCacheStore } from "../cache/types.js";
23
+ import type {
24
+ DocumentShellCacheEntry,
25
+ ShellCacheEntry,
26
+ SegmentCacheStore,
27
+ } from "../cache/types.js";
24
28
  import { SHELL_CAPTURE_MAX_WAIT_MS } from "./shell-capture-constants.js";
25
29
 
26
30
  /** Debug/status header the browser (and e2e assertions) can read: HIT | MISS. */
@@ -150,18 +154,29 @@ export function isValidShellHit(
150
154
  }
151
155
 
152
156
  /**
153
- * Payload integrity gate, run BEFORE the HIT response commits: a stored entry
154
- * whose prelude is not decodable base64 or whose postponed blob is not
155
- * parseable JSON would otherwise throw AFTER the 200 + full static prelude
156
- * flushed (`serveShellHit` decodes at stream construction, `resumeShellHTML`
157
- * parses in the tail) — the client gets a visually complete page that never
158
- * hydrates, re-served on every request until the entry ages out (no eviction
159
- * path exists; failure schedules no recapture by itself). Checking here turns
160
- * a corrupt entry (store-layer fault) into a plain MISS the recapture
161
- * overwrites. Cost: one duplicate decode/parse per HIT, sub-ms against a
162
- * prelude flush that dominates the path.
157
+ * DOCUMENT-half integrity gate and type narrowing, run BEFORE the HIT response
158
+ * commits: a stored entry whose prelude is not decodable base64 or whose
159
+ * postponed blob is not parseable JSON would otherwise throw AFTER the 200 +
160
+ * full static prelude flushed (`serveShellHit` decodes at stream construction,
161
+ * `resumeShellHTML` parses in the tail) — the client gets a visually complete
162
+ * page that never hydrates, re-served on every request until the entry ages
163
+ * out (no eviction path exists; failure schedules no recapture by itself).
164
+ * Checking here turns a corrupt entry (store-layer fault) into a plain MISS
165
+ * the recapture overwrites. Cost: one duplicate decode/parse per HIT, sub-ms
166
+ * against a prelude flush that dominates the path.
167
+ *
168
+ * navigationOnly entries store no document half (prelude/postponed absent) and
169
+ * therefore never pass. The partial-replay path skips this gate for them
170
+ * (replayableShellSnapshot) — snapshot fragment corruption is caught by the
171
+ * consumer-side Flight decoders instead (SegmentFragmentDecodeError → healing
172
+ * capture).
163
173
  */
164
- export function hasIntactShellPayload(entry: ShellCacheEntry): boolean {
174
+ export function hasIntactShellPayload(
175
+ entry: ShellCacheEntry,
176
+ ): entry is DocumentShellCacheEntry {
177
+ if (typeof entry.prelude !== "string" || entry.postponed === undefined) {
178
+ return false;
179
+ }
165
180
  try {
166
181
  base64ToBytes(entry.prelude);
167
182
  if (entry.postponed !== null) JSON.parse(entry.postponed);