@rangojs/router 0.0.0-experimental.12 → 0.0.0-experimental.121

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 (1150) hide show
  1. package/AGENTS.md +9 -0
  2. package/README.md +1037 -4
  3. package/dist/__internal.d.ts +83 -0
  4. package/dist/__internal.d.ts.map +1 -0
  5. package/dist/__internal.js +19 -0
  6. package/dist/__internal.js.map +1 -0
  7. package/dist/__mocks__/version.d.ts +7 -0
  8. package/dist/__mocks__/version.d.ts.map +1 -0
  9. package/dist/__mocks__/version.js +7 -0
  10. package/dist/__mocks__/version.js.map +1 -0
  11. package/dist/__tests__/client-href.test.d.ts +2 -0
  12. package/dist/__tests__/client-href.test.d.ts.map +1 -0
  13. package/dist/__tests__/client-href.test.js +74 -0
  14. package/dist/__tests__/client-href.test.js.map +1 -0
  15. package/dist/__tests__/component-utils.test.d.ts +2 -0
  16. package/dist/__tests__/component-utils.test.d.ts.map +1 -0
  17. package/dist/__tests__/component-utils.test.js +51 -0
  18. package/dist/__tests__/component-utils.test.js.map +1 -0
  19. package/dist/__tests__/event-controller.test.d.ts +2 -0
  20. package/dist/__tests__/event-controller.test.d.ts.map +1 -0
  21. package/dist/__tests__/event-controller.test.js +538 -0
  22. package/dist/__tests__/event-controller.test.js.map +1 -0
  23. package/dist/__tests__/helpers/route-tree.d.ts +118 -0
  24. package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
  25. package/dist/__tests__/helpers/route-tree.js +374 -0
  26. package/dist/__tests__/helpers/route-tree.js.map +1 -0
  27. package/dist/__tests__/match-result.test.d.ts +2 -0
  28. package/dist/__tests__/match-result.test.d.ts.map +1 -0
  29. package/dist/__tests__/match-result.test.js +154 -0
  30. package/dist/__tests__/match-result.test.js.map +1 -0
  31. package/dist/__tests__/navigation-store.test.d.ts +2 -0
  32. package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
  33. package/dist/__tests__/navigation-store.test.js +440 -0
  34. package/dist/__tests__/navigation-store.test.js.map +1 -0
  35. package/dist/__tests__/partial-update.test.d.ts +2 -0
  36. package/dist/__tests__/partial-update.test.d.ts.map +1 -0
  37. package/dist/__tests__/partial-update.test.js +1009 -0
  38. package/dist/__tests__/partial-update.test.js.map +1 -0
  39. package/dist/__tests__/reverse-types.test.d.ts +8 -0
  40. package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
  41. package/dist/__tests__/reverse-types.test.js +656 -0
  42. package/dist/__tests__/reverse-types.test.js.map +1 -0
  43. package/dist/__tests__/route-definition.test.d.ts +2 -0
  44. package/dist/__tests__/route-definition.test.d.ts.map +1 -0
  45. package/dist/__tests__/route-definition.test.js +55 -0
  46. package/dist/__tests__/route-definition.test.js.map +1 -0
  47. package/dist/__tests__/router-helpers.test.d.ts +2 -0
  48. package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
  49. package/dist/__tests__/router-helpers.test.js +377 -0
  50. package/dist/__tests__/router-helpers.test.js.map +1 -0
  51. package/dist/__tests__/router-integration-2.test.d.ts +2 -0
  52. package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
  53. package/dist/__tests__/router-integration-2.test.js +426 -0
  54. package/dist/__tests__/router-integration-2.test.js.map +1 -0
  55. package/dist/__tests__/router-integration.test.d.ts +2 -0
  56. package/dist/__tests__/router-integration.test.d.ts.map +1 -0
  57. package/dist/__tests__/router-integration.test.js +1051 -0
  58. package/dist/__tests__/router-integration.test.js.map +1 -0
  59. package/dist/__tests__/search-params.test.d.ts +5 -0
  60. package/dist/__tests__/search-params.test.d.ts.map +1 -0
  61. package/dist/__tests__/search-params.test.js +306 -0
  62. package/dist/__tests__/search-params.test.js.map +1 -0
  63. package/dist/__tests__/segment-system.test.d.ts +2 -0
  64. package/dist/__tests__/segment-system.test.d.ts.map +1 -0
  65. package/dist/__tests__/segment-system.test.js +627 -0
  66. package/dist/__tests__/segment-system.test.js.map +1 -0
  67. package/dist/__tests__/static-handler-types.test.d.ts +8 -0
  68. package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
  69. package/dist/__tests__/static-handler-types.test.js +63 -0
  70. package/dist/__tests__/static-handler-types.test.js.map +1 -0
  71. package/dist/__tests__/urls.test.d.ts +2 -0
  72. package/dist/__tests__/urls.test.d.ts.map +1 -0
  73. package/dist/__tests__/urls.test.js +421 -0
  74. package/dist/__tests__/urls.test.js.map +1 -0
  75. package/dist/__tests__/use-mount.test.d.ts +2 -0
  76. package/dist/__tests__/use-mount.test.d.ts.map +1 -0
  77. package/dist/__tests__/use-mount.test.js +35 -0
  78. package/dist/__tests__/use-mount.test.js.map +1 -0
  79. package/dist/bin/rango.d.ts +2 -0
  80. package/dist/bin/rango.d.ts.map +1 -0
  81. package/dist/bin/rango.js +1704 -212
  82. package/dist/bin/rango.js.map +1 -0
  83. package/dist/browser/event-controller.d.ts +191 -0
  84. package/dist/browser/event-controller.d.ts.map +1 -0
  85. package/dist/browser/event-controller.js +559 -0
  86. package/dist/browser/event-controller.js.map +1 -0
  87. package/dist/browser/index.d.ts +2 -0
  88. package/dist/browser/index.d.ts.map +1 -0
  89. package/dist/browser/index.js +14 -0
  90. package/dist/browser/index.js.map +1 -0
  91. package/dist/browser/link-interceptor.d.ts +38 -0
  92. package/dist/browser/link-interceptor.d.ts.map +1 -0
  93. package/dist/browser/link-interceptor.js +99 -0
  94. package/dist/browser/link-interceptor.js.map +1 -0
  95. package/dist/browser/logging.d.ts +10 -0
  96. package/dist/browser/logging.d.ts.map +1 -0
  97. package/dist/browser/logging.js +29 -0
  98. package/dist/browser/logging.js.map +1 -0
  99. package/dist/browser/lru-cache.d.ts +17 -0
  100. package/dist/browser/lru-cache.d.ts.map +1 -0
  101. package/dist/browser/lru-cache.js +50 -0
  102. package/dist/browser/lru-cache.js.map +1 -0
  103. package/dist/browser/merge-segment-loaders.d.ts +39 -0
  104. package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
  105. package/dist/browser/merge-segment-loaders.js +102 -0
  106. package/dist/browser/merge-segment-loaders.js.map +1 -0
  107. package/dist/browser/navigation-bridge.d.ts +102 -0
  108. package/dist/browser/navigation-bridge.d.ts.map +1 -0
  109. package/dist/browser/navigation-bridge.js +708 -0
  110. package/dist/browser/navigation-bridge.js.map +1 -0
  111. package/dist/browser/navigation-client.d.ts +25 -0
  112. package/dist/browser/navigation-client.d.ts.map +1 -0
  113. package/dist/browser/navigation-client.js +157 -0
  114. package/dist/browser/navigation-client.js.map +1 -0
  115. package/dist/browser/navigation-store.d.ts +101 -0
  116. package/dist/browser/navigation-store.d.ts.map +1 -0
  117. package/dist/browser/navigation-store.js +625 -0
  118. package/dist/browser/navigation-store.js.map +1 -0
  119. package/dist/browser/partial-update.d.ts +75 -0
  120. package/dist/browser/partial-update.d.ts.map +1 -0
  121. package/dist/browser/partial-update.js +426 -0
  122. package/dist/browser/partial-update.js.map +1 -0
  123. package/dist/browser/react/Link.d.ts +86 -0
  124. package/dist/browser/react/Link.d.ts.map +1 -0
  125. package/dist/browser/react/Link.js +128 -0
  126. package/dist/browser/react/Link.js.map +1 -0
  127. package/dist/browser/react/NavigationProvider.d.ts +63 -0
  128. package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
  129. package/dist/browser/react/NavigationProvider.js +216 -0
  130. package/dist/browser/react/NavigationProvider.js.map +1 -0
  131. package/dist/browser/react/ScrollRestoration.d.ts +75 -0
  132. package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
  133. package/dist/browser/react/ScrollRestoration.js +57 -0
  134. package/dist/browser/react/ScrollRestoration.js.map +1 -0
  135. package/dist/browser/react/context.d.ts +46 -0
  136. package/dist/browser/react/context.d.ts.map +1 -0
  137. package/dist/browser/react/context.js +10 -0
  138. package/dist/browser/react/context.js.map +1 -0
  139. package/dist/browser/react/index.d.ts +11 -0
  140. package/dist/browser/react/index.d.ts.map +1 -0
  141. package/dist/browser/react/index.js +22 -0
  142. package/dist/browser/react/index.js.map +1 -0
  143. package/dist/browser/react/location-state-shared.d.ts +63 -0
  144. package/dist/browser/react/location-state-shared.d.ts.map +1 -0
  145. package/dist/browser/react/location-state-shared.js +81 -0
  146. package/dist/browser/react/location-state-shared.js.map +1 -0
  147. package/dist/browser/react/location-state.d.ts +23 -0
  148. package/dist/browser/react/location-state.d.ts.map +1 -0
  149. package/dist/browser/react/location-state.js +29 -0
  150. package/dist/browser/react/location-state.js.map +1 -0
  151. package/dist/browser/react/mount-context.d.ts +24 -0
  152. package/dist/browser/react/mount-context.d.ts.map +1 -0
  153. package/dist/browser/react/mount-context.js +24 -0
  154. package/dist/browser/react/mount-context.js.map +1 -0
  155. package/dist/browser/react/use-action.d.ts +64 -0
  156. package/dist/browser/react/use-action.d.ts.map +1 -0
  157. package/dist/browser/react/use-action.js +134 -0
  158. package/dist/browser/react/use-action.js.map +1 -0
  159. package/dist/browser/react/use-client-cache.d.ts +41 -0
  160. package/dist/browser/react/use-client-cache.d.ts.map +1 -0
  161. package/dist/browser/react/use-client-cache.js +39 -0
  162. package/dist/browser/react/use-client-cache.js.map +1 -0
  163. package/dist/browser/react/use-handle.d.ts +31 -0
  164. package/dist/browser/react/use-handle.d.ts.map +1 -0
  165. package/dist/browser/react/use-handle.js +144 -0
  166. package/dist/browser/react/use-handle.js.map +1 -0
  167. package/dist/browser/react/use-href.d.ts +33 -0
  168. package/dist/browser/react/use-href.d.ts.map +1 -0
  169. package/dist/browser/react/use-href.js +39 -0
  170. package/dist/browser/react/use-href.js.map +1 -0
  171. package/dist/browser/react/use-link-status.d.ts +37 -0
  172. package/dist/browser/react/use-link-status.d.ts.map +1 -0
  173. package/dist/browser/react/use-link-status.js +99 -0
  174. package/dist/browser/react/use-link-status.js.map +1 -0
  175. package/dist/browser/react/use-mount.d.ts +25 -0
  176. package/dist/browser/react/use-mount.d.ts.map +1 -0
  177. package/dist/browser/react/use-mount.js +30 -0
  178. package/dist/browser/react/use-mount.js.map +1 -0
  179. package/dist/browser/react/use-navigation.d.ts +27 -0
  180. package/dist/browser/react/use-navigation.d.ts.map +1 -0
  181. package/dist/browser/react/use-navigation.js +87 -0
  182. package/dist/browser/react/use-navigation.js.map +1 -0
  183. package/dist/browser/react/use-segments.d.ts +38 -0
  184. package/dist/browser/react/use-segments.d.ts.map +1 -0
  185. package/dist/browser/react/use-segments.js +130 -0
  186. package/dist/browser/react/use-segments.js.map +1 -0
  187. package/dist/browser/request-controller.d.ts +26 -0
  188. package/dist/browser/request-controller.d.ts.map +1 -0
  189. package/dist/browser/request-controller.js +147 -0
  190. package/dist/browser/request-controller.js.map +1 -0
  191. package/dist/browser/rsc-router.d.ts +129 -0
  192. package/dist/browser/rsc-router.d.ts.map +1 -0
  193. package/dist/browser/rsc-router.js +195 -0
  194. package/dist/browser/rsc-router.js.map +1 -0
  195. package/dist/browser/scroll-restoration.d.ts +93 -0
  196. package/dist/browser/scroll-restoration.d.ts.map +1 -0
  197. package/dist/browser/scroll-restoration.js +321 -0
  198. package/dist/browser/scroll-restoration.js.map +1 -0
  199. package/dist/browser/segment-structure-assert.d.ts +17 -0
  200. package/dist/browser/segment-structure-assert.d.ts.map +1 -0
  201. package/dist/browser/segment-structure-assert.js +59 -0
  202. package/dist/browser/segment-structure-assert.js.map +1 -0
  203. package/dist/browser/server-action-bridge.d.ts +26 -0
  204. package/dist/browser/server-action-bridge.d.ts.map +1 -0
  205. package/dist/browser/server-action-bridge.js +668 -0
  206. package/dist/browser/server-action-bridge.js.map +1 -0
  207. package/dist/browser/shallow.d.ts +12 -0
  208. package/dist/browser/shallow.d.ts.map +1 -0
  209. package/dist/browser/shallow.js +34 -0
  210. package/dist/browser/shallow.js.map +1 -0
  211. package/dist/browser/types.d.ts +369 -0
  212. package/dist/browser/types.d.ts.map +1 -0
  213. package/dist/browser/types.js +2 -0
  214. package/dist/browser/types.js.map +1 -0
  215. package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
  216. package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
  217. package/dist/build/__tests__/generate-cli.test.js +237 -0
  218. package/dist/build/__tests__/generate-cli.test.js.map +1 -0
  219. package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
  220. package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
  221. package/dist/build/__tests__/generate-manifest.test.js +119 -0
  222. package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
  223. package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
  224. package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
  225. package/dist/build/__tests__/generate-route-types.test.js +620 -0
  226. package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
  227. package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
  228. package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
  229. package/dist/build/__tests__/per-router-manifest.test.js +308 -0
  230. package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
  231. package/dist/build/generate-manifest.d.ts +81 -0
  232. package/dist/build/generate-manifest.d.ts.map +1 -0
  233. package/dist/build/generate-manifest.js +276 -0
  234. package/dist/build/generate-manifest.js.map +1 -0
  235. package/dist/build/generate-route-types.d.ts +115 -0
  236. package/dist/build/generate-route-types.d.ts.map +1 -0
  237. package/dist/build/generate-route-types.js +740 -0
  238. package/dist/build/generate-route-types.js.map +1 -0
  239. package/dist/build/index.d.ts +21 -0
  240. package/dist/build/index.d.ts.map +1 -0
  241. package/dist/build/index.js +21 -0
  242. package/dist/build/index.js.map +1 -0
  243. package/dist/build/route-trie.d.ts +71 -0
  244. package/dist/build/route-trie.d.ts.map +1 -0
  245. package/dist/build/route-trie.js +175 -0
  246. package/dist/build/route-trie.js.map +1 -0
  247. package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
  248. package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
  249. package/dist/cache/__tests__/cache-scope.test.js +208 -0
  250. package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
  251. package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
  252. package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
  253. package/dist/cache/__tests__/document-cache.test.js +345 -0
  254. package/dist/cache/__tests__/document-cache.test.js.map +1 -0
  255. package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
  256. package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
  257. package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
  258. package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
  259. package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
  260. package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
  261. package/dist/cache/__tests__/memory-store.test.js +367 -0
  262. package/dist/cache/__tests__/memory-store.test.js.map +1 -0
  263. package/dist/cache/cache-scope.d.ts +102 -0
  264. package/dist/cache/cache-scope.d.ts.map +1 -0
  265. package/dist/cache/cache-scope.js +440 -0
  266. package/dist/cache/cache-scope.js.map +1 -0
  267. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
  268. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
  269. package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
  270. package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
  271. package/dist/cache/cf/cf-cache-store.d.ts +165 -0
  272. package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
  273. package/dist/cache/cf/cf-cache-store.js +242 -0
  274. package/dist/cache/cf/cf-cache-store.js.map +1 -0
  275. package/dist/cache/cf/index.d.ts +14 -0
  276. package/dist/cache/cf/index.d.ts.map +1 -0
  277. package/dist/cache/cf/index.js +17 -0
  278. package/dist/cache/cf/index.js.map +1 -0
  279. package/dist/cache/document-cache.d.ts +64 -0
  280. package/dist/cache/document-cache.d.ts.map +1 -0
  281. package/dist/cache/document-cache.js +228 -0
  282. package/dist/cache/document-cache.js.map +1 -0
  283. package/dist/cache/index.d.ts +19 -0
  284. package/dist/cache/index.d.ts.map +1 -0
  285. package/dist/cache/index.js +21 -0
  286. package/dist/cache/index.js.map +1 -0
  287. package/dist/cache/memory-segment-store.d.ts +110 -0
  288. package/dist/cache/memory-segment-store.d.ts.map +1 -0
  289. package/dist/cache/memory-segment-store.js +117 -0
  290. package/dist/cache/memory-segment-store.js.map +1 -0
  291. package/dist/cache/memory-store.d.ts +41 -0
  292. package/dist/cache/memory-store.d.ts.map +1 -0
  293. package/dist/cache/memory-store.js +191 -0
  294. package/dist/cache/memory-store.js.map +1 -0
  295. package/dist/cache/types.d.ts +317 -0
  296. package/dist/cache/types.d.ts.map +1 -0
  297. package/dist/cache/types.js +12 -0
  298. package/dist/cache/types.js.map +1 -0
  299. package/dist/client.d.ts +248 -0
  300. package/dist/client.d.ts.map +1 -0
  301. package/dist/client.js +367 -0
  302. package/dist/client.js.map +1 -0
  303. package/dist/client.rsc.d.ts +26 -0
  304. package/dist/client.rsc.d.ts.map +1 -0
  305. package/dist/client.rsc.js +46 -0
  306. package/dist/client.rsc.js.map +1 -0
  307. package/dist/component-utils.d.ts +36 -0
  308. package/dist/component-utils.d.ts.map +1 -0
  309. package/dist/component-utils.js +61 -0
  310. package/dist/component-utils.js.map +1 -0
  311. package/dist/components/DefaultDocument.d.ts +13 -0
  312. package/dist/components/DefaultDocument.d.ts.map +1 -0
  313. package/dist/components/DefaultDocument.js +15 -0
  314. package/dist/components/DefaultDocument.js.map +1 -0
  315. package/dist/debug.d.ts +58 -0
  316. package/dist/debug.d.ts.map +1 -0
  317. package/dist/debug.js +157 -0
  318. package/dist/debug.js.map +1 -0
  319. package/dist/default-error-boundary.d.ts +11 -0
  320. package/dist/default-error-boundary.d.ts.map +1 -0
  321. package/dist/default-error-boundary.js +45 -0
  322. package/dist/default-error-boundary.js.map +1 -0
  323. package/dist/deps/browser.d.ts +2 -0
  324. package/dist/deps/browser.d.ts.map +1 -0
  325. package/dist/deps/browser.js +3 -0
  326. package/dist/deps/browser.js.map +1 -0
  327. package/dist/deps/html-stream-client.d.ts +2 -0
  328. package/dist/deps/html-stream-client.d.ts.map +1 -0
  329. package/dist/deps/html-stream-client.js +3 -0
  330. package/dist/deps/html-stream-client.js.map +1 -0
  331. package/dist/deps/html-stream-server.d.ts +2 -0
  332. package/dist/deps/html-stream-server.d.ts.map +1 -0
  333. package/dist/deps/html-stream-server.js +3 -0
  334. package/dist/deps/html-stream-server.js.map +1 -0
  335. package/dist/deps/rsc.d.ts +2 -0
  336. package/dist/deps/rsc.d.ts.map +1 -0
  337. package/dist/deps/rsc.js +4 -0
  338. package/dist/deps/rsc.js.map +1 -0
  339. package/dist/deps/ssr.d.ts +2 -0
  340. package/dist/deps/ssr.d.ts.map +1 -0
  341. package/dist/deps/ssr.js +3 -0
  342. package/dist/deps/ssr.js.map +1 -0
  343. package/dist/errors.d.ts +174 -0
  344. package/dist/errors.d.ts.map +1 -0
  345. package/dist/errors.js +241 -0
  346. package/dist/errors.js.map +1 -0
  347. package/dist/handle.d.ts +78 -0
  348. package/dist/handle.d.ts.map +1 -0
  349. package/dist/handle.js +82 -0
  350. package/dist/handle.js.map +1 -0
  351. package/dist/handles/MetaTags.d.ts +14 -0
  352. package/dist/handles/MetaTags.d.ts.map +1 -0
  353. package/dist/handles/MetaTags.js +136 -0
  354. package/dist/handles/MetaTags.js.map +1 -0
  355. package/dist/handles/index.d.ts +6 -0
  356. package/dist/handles/index.d.ts.map +1 -0
  357. package/dist/handles/index.js +6 -0
  358. package/dist/handles/index.js.map +1 -0
  359. package/dist/handles/meta.d.ts +39 -0
  360. package/dist/handles/meta.d.ts.map +1 -0
  361. package/dist/handles/meta.js +202 -0
  362. package/dist/handles/meta.js.map +1 -0
  363. package/dist/host/__tests__/errors.test.d.ts +2 -0
  364. package/dist/host/__tests__/errors.test.d.ts.map +1 -0
  365. package/dist/host/__tests__/errors.test.js +76 -0
  366. package/dist/host/__tests__/errors.test.js.map +1 -0
  367. package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
  368. package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
  369. package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
  370. package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
  371. package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
  372. package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
  373. package/dist/host/__tests__/pattern-matcher.test.js +251 -0
  374. package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
  375. package/dist/host/__tests__/router.test.d.ts +2 -0
  376. package/dist/host/__tests__/router.test.d.ts.map +1 -0
  377. package/dist/host/__tests__/router.test.js +241 -0
  378. package/dist/host/__tests__/router.test.js.map +1 -0
  379. package/dist/host/__tests__/testing.test.d.ts +2 -0
  380. package/dist/host/__tests__/testing.test.d.ts.map +1 -0
  381. package/dist/host/__tests__/testing.test.js +64 -0
  382. package/dist/host/__tests__/testing.test.js.map +1 -0
  383. package/dist/host/__tests__/utils.test.d.ts +2 -0
  384. package/dist/host/__tests__/utils.test.d.ts.map +1 -0
  385. package/dist/host/__tests__/utils.test.js +29 -0
  386. package/dist/host/__tests__/utils.test.js.map +1 -0
  387. package/dist/host/cookie-handler.d.ts +34 -0
  388. package/dist/host/cookie-handler.d.ts.map +1 -0
  389. package/dist/host/cookie-handler.js +124 -0
  390. package/dist/host/cookie-handler.js.map +1 -0
  391. package/dist/host/errors.d.ts +56 -0
  392. package/dist/host/errors.d.ts.map +1 -0
  393. package/dist/host/errors.js +79 -0
  394. package/dist/host/errors.js.map +1 -0
  395. package/dist/host/index.d.ts +29 -0
  396. package/dist/host/index.d.ts.map +1 -0
  397. package/dist/host/index.js +32 -0
  398. package/dist/host/index.js.map +1 -0
  399. package/dist/host/pattern-matcher.d.ts +36 -0
  400. package/dist/host/pattern-matcher.d.ts.map +1 -0
  401. package/dist/host/pattern-matcher.js +172 -0
  402. package/dist/host/pattern-matcher.js.map +1 -0
  403. package/dist/host/router.d.ts +26 -0
  404. package/dist/host/router.d.ts.map +1 -0
  405. package/dist/host/router.js +218 -0
  406. package/dist/host/router.js.map +1 -0
  407. package/dist/host/testing.d.ts +36 -0
  408. package/dist/host/testing.d.ts.map +1 -0
  409. package/dist/host/testing.js +55 -0
  410. package/dist/host/testing.js.map +1 -0
  411. package/dist/host/types.d.ts +115 -0
  412. package/dist/host/types.d.ts.map +1 -0
  413. package/dist/host/types.js +7 -0
  414. package/dist/host/types.js.map +1 -0
  415. package/dist/host/utils.d.ts +21 -0
  416. package/dist/host/utils.d.ts.map +1 -0
  417. package/dist/host/utils.js +23 -0
  418. package/dist/host/utils.js.map +1 -0
  419. package/dist/href-client.d.ts +131 -0
  420. package/dist/href-client.d.ts.map +1 -0
  421. package/dist/href-client.js +64 -0
  422. package/dist/href-client.js.map +1 -0
  423. package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
  424. package/dist/href-context.d.ts.map +1 -0
  425. package/dist/href-context.js +21 -0
  426. package/dist/href-context.js.map +1 -0
  427. package/dist/index.d.ts +73 -0
  428. package/dist/index.d.ts.map +1 -0
  429. package/dist/index.js +91 -0
  430. package/dist/index.js.map +1 -0
  431. package/dist/index.rsc.d.ts +32 -0
  432. package/dist/index.rsc.d.ts.map +1 -0
  433. package/dist/index.rsc.js +40 -0
  434. package/dist/index.rsc.js.map +1 -0
  435. package/dist/internal-debug.d.ts +2 -0
  436. package/dist/internal-debug.d.ts.map +1 -0
  437. package/dist/internal-debug.js +5 -0
  438. package/dist/internal-debug.js.map +1 -0
  439. package/dist/loader.d.ts +14 -0
  440. package/dist/loader.d.ts.map +1 -0
  441. package/dist/loader.js +20 -0
  442. package/dist/loader.js.map +1 -0
  443. package/dist/loader.rsc.d.ts +19 -0
  444. package/dist/loader.rsc.d.ts.map +1 -0
  445. package/dist/loader.rsc.js +99 -0
  446. package/dist/loader.rsc.js.map +1 -0
  447. package/dist/network-error-thrower.d.ts +17 -0
  448. package/dist/network-error-thrower.d.ts.map +1 -0
  449. package/dist/network-error-thrower.js +14 -0
  450. package/dist/network-error-thrower.js.map +1 -0
  451. package/dist/outlet-context.d.ts +13 -0
  452. package/dist/outlet-context.d.ts.map +1 -0
  453. package/dist/outlet-context.js +3 -0
  454. package/dist/outlet-context.js.map +1 -0
  455. package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
  456. package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
  457. package/dist/prerender/__tests__/param-hash.test.js +148 -0
  458. package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
  459. package/dist/prerender/param-hash.d.ts +16 -0
  460. package/dist/prerender/param-hash.d.ts.map +1 -0
  461. package/dist/prerender/param-hash.js +36 -0
  462. package/dist/prerender/param-hash.js.map +1 -0
  463. package/dist/prerender/store.d.ts +38 -0
  464. package/dist/prerender/store.d.ts.map +1 -0
  465. package/dist/prerender/store.js +61 -0
  466. package/dist/prerender/store.js.map +1 -0
  467. package/dist/prerender.d.ts +66 -0
  468. package/dist/prerender.d.ts.map +1 -0
  469. package/dist/prerender.js +57 -0
  470. package/dist/prerender.js.map +1 -0
  471. package/dist/reverse.d.ts +196 -0
  472. package/dist/reverse.d.ts.map +1 -0
  473. package/dist/reverse.js +78 -0
  474. package/dist/reverse.js.map +1 -0
  475. package/dist/root-error-boundary.d.ts +33 -0
  476. package/dist/root-error-boundary.d.ts.map +1 -0
  477. package/dist/root-error-boundary.js +165 -0
  478. package/dist/root-error-boundary.js.map +1 -0
  479. package/dist/route-content-wrapper.d.ts +46 -0
  480. package/dist/route-content-wrapper.d.ts.map +1 -0
  481. package/dist/route-content-wrapper.js +77 -0
  482. package/dist/route-content-wrapper.js.map +1 -0
  483. package/dist/route-definition.d.ts +421 -0
  484. package/dist/route-definition.d.ts.map +1 -0
  485. package/dist/route-definition.js +868 -0
  486. package/dist/route-definition.js.map +1 -0
  487. package/dist/route-map-builder.d.ts +155 -0
  488. package/dist/route-map-builder.d.ts.map +1 -0
  489. package/dist/route-map-builder.js +237 -0
  490. package/dist/route-map-builder.js.map +1 -0
  491. package/dist/route-types.d.ts +165 -0
  492. package/dist/route-types.d.ts.map +1 -0
  493. package/dist/route-types.js +7 -0
  494. package/dist/route-types.js.map +1 -0
  495. package/dist/router/__tests__/handler-context.test.d.ts +2 -0
  496. package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
  497. package/dist/router/__tests__/handler-context.test.js +65 -0
  498. package/dist/router/__tests__/handler-context.test.js.map +1 -0
  499. package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
  500. package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
  501. package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
  502. package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
  503. package/dist/router/__tests__/match-context.test.d.ts +2 -0
  504. package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
  505. package/dist/router/__tests__/match-context.test.js +92 -0
  506. package/dist/router/__tests__/match-context.test.js.map +1 -0
  507. package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
  508. package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
  509. package/dist/router/__tests__/match-pipelines.test.js +417 -0
  510. package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
  511. package/dist/router/__tests__/match-result.test.d.ts +2 -0
  512. package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
  513. package/dist/router/__tests__/match-result.test.js +457 -0
  514. package/dist/router/__tests__/match-result.test.js.map +1 -0
  515. package/dist/router/__tests__/on-error.test.d.ts +2 -0
  516. package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
  517. package/dist/router/__tests__/on-error.test.js +678 -0
  518. package/dist/router/__tests__/on-error.test.js.map +1 -0
  519. package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
  520. package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
  521. package/dist/router/__tests__/pattern-matching.test.js +629 -0
  522. package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
  523. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
  524. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
  525. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
  526. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
  527. package/dist/router/error-handling.d.ts +77 -0
  528. package/dist/router/error-handling.d.ts.map +1 -0
  529. package/dist/router/error-handling.js +202 -0
  530. package/dist/router/error-handling.js.map +1 -0
  531. package/dist/router/handler-context.d.ts +20 -0
  532. package/dist/router/handler-context.d.ts.map +1 -0
  533. package/dist/router/handler-context.js +198 -0
  534. package/dist/router/handler-context.js.map +1 -0
  535. package/dist/router/intercept-resolution.d.ts +66 -0
  536. package/dist/router/intercept-resolution.d.ts.map +1 -0
  537. package/dist/router/intercept-resolution.js +246 -0
  538. package/dist/router/intercept-resolution.js.map +1 -0
  539. package/dist/router/loader-resolution.d.ts +64 -0
  540. package/dist/router/loader-resolution.d.ts.map +1 -0
  541. package/dist/router/loader-resolution.js +284 -0
  542. package/dist/router/loader-resolution.js.map +1 -0
  543. package/dist/router/logging.d.ts +15 -0
  544. package/dist/router/logging.d.ts.map +1 -0
  545. package/dist/router/logging.js +99 -0
  546. package/dist/router/logging.js.map +1 -0
  547. package/dist/router/manifest.d.ts +22 -0
  548. package/dist/router/manifest.d.ts.map +1 -0
  549. package/dist/router/manifest.js +181 -0
  550. package/dist/router/manifest.js.map +1 -0
  551. package/dist/router/match-api.d.ts +35 -0
  552. package/dist/router/match-api.d.ts.map +1 -0
  553. package/dist/router/match-api.js +406 -0
  554. package/dist/router/match-api.js.map +1 -0
  555. package/dist/router/match-context.d.ts +206 -0
  556. package/dist/router/match-context.d.ts.map +1 -0
  557. package/dist/router/match-context.js +17 -0
  558. package/dist/router/match-context.js.map +1 -0
  559. package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
  560. package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
  561. package/dist/router/match-middleware/background-revalidation.js +75 -0
  562. package/dist/router/match-middleware/background-revalidation.js.map +1 -0
  563. package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
  564. package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
  565. package/dist/router/match-middleware/cache-lookup.js +257 -0
  566. package/dist/router/match-middleware/cache-lookup.js.map +1 -0
  567. package/dist/router/match-middleware/cache-store.d.ts +113 -0
  568. package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
  569. package/dist/router/match-middleware/cache-store.js +108 -0
  570. package/dist/router/match-middleware/cache-store.js.map +1 -0
  571. package/dist/router/match-middleware/index.d.ts +81 -0
  572. package/dist/router/match-middleware/index.d.ts.map +1 -0
  573. package/dist/router/match-middleware/index.js +80 -0
  574. package/dist/router/match-middleware/index.js.map +1 -0
  575. package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
  576. package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
  577. package/dist/router/match-middleware/intercept-resolution.js +134 -0
  578. package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
  579. package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
  580. package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
  581. package/dist/router/match-middleware/segment-resolution.js +53 -0
  582. package/dist/router/match-middleware/segment-resolution.js.map +1 -0
  583. package/dist/router/match-pipelines.d.ts +147 -0
  584. package/dist/router/match-pipelines.d.ts.map +1 -0
  585. package/dist/router/match-pipelines.js +82 -0
  586. package/dist/router/match-pipelines.js.map +1 -0
  587. package/dist/router/match-result.d.ts +126 -0
  588. package/dist/router/match-result.d.ts.map +1 -0
  589. package/dist/router/match-result.js +93 -0
  590. package/dist/router/match-result.js.map +1 -0
  591. package/dist/router/metrics.d.ts +20 -0
  592. package/dist/router/metrics.d.ts.map +1 -0
  593. package/dist/router/metrics.js +47 -0
  594. package/dist/router/metrics.js.map +1 -0
  595. package/dist/router/middleware.d.ts +249 -0
  596. package/dist/router/middleware.d.ts.map +1 -0
  597. package/dist/router/middleware.js +434 -0
  598. package/dist/router/middleware.js.map +1 -0
  599. package/dist/router/middleware.test.d.ts +2 -0
  600. package/dist/router/middleware.test.d.ts.map +1 -0
  601. package/dist/router/middleware.test.js +816 -0
  602. package/dist/router/middleware.test.js.map +1 -0
  603. package/dist/router/pattern-matching.d.ts +149 -0
  604. package/dist/router/pattern-matching.d.ts.map +1 -0
  605. package/dist/router/pattern-matching.js +349 -0
  606. package/dist/router/pattern-matching.js.map +1 -0
  607. package/dist/router/revalidation.d.ts +44 -0
  608. package/dist/router/revalidation.d.ts.map +1 -0
  609. package/dist/router/revalidation.js +147 -0
  610. package/dist/router/revalidation.js.map +1 -0
  611. package/dist/router/router-context.d.ts +135 -0
  612. package/dist/router/router-context.d.ts.map +1 -0
  613. package/dist/router/router-context.js +36 -0
  614. package/dist/router/router-context.js.map +1 -0
  615. package/dist/router/segment-resolution.d.ts +127 -0
  616. package/dist/router/segment-resolution.d.ts.map +1 -0
  617. package/dist/router/segment-resolution.js +919 -0
  618. package/dist/router/segment-resolution.js.map +1 -0
  619. package/dist/router/trie-matching.d.ts +40 -0
  620. package/dist/router/trie-matching.d.ts.map +1 -0
  621. package/dist/router/trie-matching.js +127 -0
  622. package/dist/router/trie-matching.js.map +1 -0
  623. package/dist/router/types.d.ts +136 -0
  624. package/dist/router/types.d.ts.map +1 -0
  625. package/dist/router/types.js +7 -0
  626. package/dist/router/types.js.map +1 -0
  627. package/dist/router.d.ts +753 -0
  628. package/dist/router.d.ts.map +1 -0
  629. package/dist/router.gen.d.ts +6 -0
  630. package/dist/router.gen.d.ts.map +1 -0
  631. package/dist/router.gen.js +6 -0
  632. package/dist/router.gen.js.map +1 -0
  633. package/dist/router.js +1304 -0
  634. package/dist/router.js.map +1 -0
  635. package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
  636. package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
  637. package/dist/rsc/__tests__/helpers.test.js +140 -0
  638. package/dist/rsc/__tests__/helpers.test.js.map +1 -0
  639. package/dist/rsc/handler.d.ts +45 -0
  640. package/dist/rsc/handler.d.ts.map +1 -0
  641. package/dist/rsc/handler.js +1172 -0
  642. package/dist/rsc/handler.js.map +1 -0
  643. package/dist/rsc/helpers.d.ts +16 -0
  644. package/dist/rsc/helpers.d.ts.map +1 -0
  645. package/dist/rsc/helpers.js +55 -0
  646. package/dist/rsc/helpers.js.map +1 -0
  647. package/dist/rsc/index.d.ts +22 -0
  648. package/dist/rsc/index.d.ts.map +1 -0
  649. package/dist/rsc/index.js +23 -0
  650. package/dist/rsc/index.js.map +1 -0
  651. package/dist/rsc/nonce.d.ts +9 -0
  652. package/dist/rsc/nonce.d.ts.map +1 -0
  653. package/dist/rsc/nonce.js +18 -0
  654. package/dist/rsc/nonce.js.map +1 -0
  655. package/dist/rsc/types.d.ts +206 -0
  656. package/dist/rsc/types.d.ts.map +1 -0
  657. package/dist/rsc/types.js +8 -0
  658. package/dist/rsc/types.js.map +1 -0
  659. package/dist/search-params.d.ts +103 -0
  660. package/dist/search-params.d.ts.map +1 -0
  661. package/dist/search-params.js +74 -0
  662. package/dist/search-params.js.map +1 -0
  663. package/dist/segment-system.d.ts +75 -0
  664. package/dist/segment-system.d.ts.map +1 -0
  665. package/dist/segment-system.js +336 -0
  666. package/dist/segment-system.js.map +1 -0
  667. package/dist/server/context.d.ts +245 -0
  668. package/dist/server/context.d.ts.map +1 -0
  669. package/dist/server/context.js +197 -0
  670. package/dist/server/context.js.map +1 -0
  671. package/dist/server/fetchable-loader-store.d.ts +18 -0
  672. package/dist/server/fetchable-loader-store.d.ts.map +1 -0
  673. package/dist/server/fetchable-loader-store.js +18 -0
  674. package/dist/server/fetchable-loader-store.js.map +1 -0
  675. package/dist/server/handle-store.d.ts +85 -0
  676. package/dist/server/handle-store.d.ts.map +1 -0
  677. package/dist/server/handle-store.js +142 -0
  678. package/dist/server/handle-store.js.map +1 -0
  679. package/dist/server/loader-registry.d.ts +55 -0
  680. package/dist/server/loader-registry.d.ts.map +1 -0
  681. package/dist/server/loader-registry.js +132 -0
  682. package/dist/server/loader-registry.js.map +1 -0
  683. package/dist/server/request-context.d.ts +226 -0
  684. package/dist/server/request-context.d.ts.map +1 -0
  685. package/dist/server/request-context.js +290 -0
  686. package/dist/server/request-context.js.map +1 -0
  687. package/dist/server/root-layout.d.ts +4 -0
  688. package/dist/server/root-layout.d.ts.map +1 -0
  689. package/dist/server/root-layout.js +5 -0
  690. package/dist/server/root-layout.js.map +1 -0
  691. package/dist/server.d.ts +15 -0
  692. package/dist/server.d.ts.map +1 -0
  693. package/dist/server.js +20 -0
  694. package/dist/server.js.map +1 -0
  695. package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
  696. package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
  697. package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
  698. package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
  699. package/dist/ssr/index.d.ts +98 -0
  700. package/dist/ssr/index.d.ts.map +1 -0
  701. package/dist/ssr/index.js +158 -0
  702. package/dist/ssr/index.js.map +1 -0
  703. package/dist/static-handler.d.ts +50 -0
  704. package/dist/static-handler.d.ts.map +1 -0
  705. package/dist/static-handler.gen.d.ts +5 -0
  706. package/dist/static-handler.gen.d.ts.map +1 -0
  707. package/dist/static-handler.gen.js +5 -0
  708. package/dist/static-handler.gen.js.map +1 -0
  709. package/dist/static-handler.js +29 -0
  710. package/dist/static-handler.js.map +1 -0
  711. package/dist/testing/vitest.js +82 -0
  712. package/dist/theme/ThemeProvider.d.ts +20 -0
  713. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  714. package/dist/theme/ThemeProvider.js +240 -0
  715. package/dist/theme/ThemeProvider.js.map +1 -0
  716. package/dist/theme/ThemeScript.d.ts +48 -0
  717. package/dist/theme/ThemeScript.d.ts.map +1 -0
  718. package/dist/theme/ThemeScript.js +13 -0
  719. package/dist/theme/ThemeScript.js.map +1 -0
  720. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  721. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  722. package/dist/theme/__tests__/theme.test.js +103 -0
  723. package/dist/theme/__tests__/theme.test.js.map +1 -0
  724. package/dist/theme/constants.d.ts +29 -0
  725. package/dist/theme/constants.d.ts.map +1 -0
  726. package/dist/theme/constants.js +48 -0
  727. package/dist/theme/constants.js.map +1 -0
  728. package/dist/theme/index.d.ts +31 -0
  729. package/dist/theme/index.d.ts.map +1 -0
  730. package/dist/theme/index.js +36 -0
  731. package/dist/theme/index.js.map +1 -0
  732. package/dist/theme/theme-context.d.ts +40 -0
  733. package/dist/theme/theme-context.d.ts.map +1 -0
  734. package/dist/theme/theme-context.js +60 -0
  735. package/dist/theme/theme-context.js.map +1 -0
  736. package/dist/theme/theme-script.d.ts +27 -0
  737. package/dist/theme/theme-script.d.ts.map +1 -0
  738. package/dist/theme/theme-script.js +147 -0
  739. package/dist/theme/theme-script.js.map +1 -0
  740. package/dist/theme/types.d.ts +163 -0
  741. package/dist/theme/types.d.ts.map +1 -0
  742. package/dist/theme/types.js +11 -0
  743. package/dist/theme/types.js.map +1 -0
  744. package/dist/theme/use-theme.d.ts +12 -0
  745. package/dist/theme/use-theme.d.ts.map +1 -0
  746. package/dist/theme/use-theme.js +40 -0
  747. package/dist/theme/use-theme.js.map +1 -0
  748. package/dist/types.d.ts +1479 -0
  749. package/dist/types.d.ts.map +1 -0
  750. package/dist/types.js +10 -0
  751. package/dist/types.js.map +1 -0
  752. package/dist/urls.d.ts +441 -0
  753. package/dist/urls.d.ts.map +1 -0
  754. package/dist/urls.gen.d.ts +8 -0
  755. package/dist/urls.gen.d.ts.map +1 -0
  756. package/dist/urls.gen.js +8 -0
  757. package/dist/urls.gen.js.map +1 -0
  758. package/dist/urls.js +443 -0
  759. package/dist/urls.js.map +1 -0
  760. package/dist/use-loader.d.ts +127 -0
  761. package/dist/use-loader.d.ts.map +1 -0
  762. package/dist/use-loader.js +237 -0
  763. package/dist/use-loader.js.map +1 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  766. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  767. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  770. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  771. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  774. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  775. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  776. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  777. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  778. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  779. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  780. package/dist/vite/ast-handler-extract.d.ts +49 -0
  781. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  782. package/dist/vite/ast-handler-extract.js +249 -0
  783. package/dist/vite/ast-handler-extract.js.map +1 -0
  784. package/dist/vite/expose-action-id.d.ts +19 -0
  785. package/dist/vite/expose-action-id.d.ts.map +1 -0
  786. package/dist/vite/expose-action-id.js +250 -0
  787. package/dist/vite/expose-action-id.js.map +1 -0
  788. package/dist/vite/expose-id-utils.d.ts +69 -0
  789. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  790. package/dist/vite/expose-id-utils.js +289 -0
  791. package/dist/vite/expose-id-utils.js.map +1 -0
  792. package/dist/vite/expose-internal-ids.d.ts +22 -0
  793. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  794. package/dist/vite/expose-internal-ids.js +886 -0
  795. package/dist/vite/expose-internal-ids.js.map +1 -0
  796. package/dist/vite/index.d.ts +149 -0
  797. package/dist/vite/index.d.ts.map +1 -0
  798. package/dist/vite/index.js +5994 -2763
  799. package/dist/vite/index.js.bak +5448 -0
  800. package/dist/vite/index.js.map +1 -0
  801. package/dist/vite/index.named-routes.gen.ts +103 -0
  802. package/dist/vite/package-resolution.d.ts +43 -0
  803. package/dist/vite/package-resolution.d.ts.map +1 -0
  804. package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
  805. package/dist/vite/package-resolution.js.map +1 -0
  806. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  807. package/dist/vite/virtual-entries.d.ts +25 -0
  808. package/dist/vite/virtual-entries.d.ts.map +1 -0
  809. package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
  810. package/dist/vite/virtual-entries.js.map +1 -0
  811. package/package.json +64 -54
  812. package/skills/api-client/SKILL.md +211 -0
  813. package/skills/breadcrumbs/SKILL.md +252 -0
  814. package/skills/bundle-analysis/SKILL.md +159 -0
  815. package/skills/cache-guide/SKILL.md +484 -0
  816. package/skills/caching/SKILL.md +202 -24
  817. package/skills/composability/SKILL.md +197 -0
  818. package/skills/css/SKILL.md +76 -0
  819. package/skills/debug-manifest/SKILL.md +12 -8
  820. package/skills/document-cache/SKILL.md +87 -62
  821. package/skills/fonts/SKILL.md +6 -4
  822. package/skills/handler-use/SKILL.md +364 -0
  823. package/skills/hooks/SKILL.md +537 -70
  824. package/skills/host-router/SKILL.md +264 -0
  825. package/skills/i18n/SKILL.md +276 -0
  826. package/skills/intercept/SKILL.md +173 -8
  827. package/skills/layout/SKILL.md +123 -5
  828. package/skills/links/SKILL.md +304 -25
  829. package/skills/loader/SKILL.md +600 -54
  830. package/skills/middleware/SKILL.md +211 -37
  831. package/skills/migrate-nextjs/SKILL.md +562 -0
  832. package/skills/migrate-react-router/SKILL.md +769 -0
  833. package/skills/mime-routes/SKILL.md +41 -10
  834. package/skills/observability/SKILL.md +137 -0
  835. package/skills/parallel/SKILL.md +271 -3
  836. package/skills/prerender/SKILL.md +413 -52
  837. package/skills/rango/SKILL.md +301 -21
  838. package/skills/react-compiler/SKILL.md +168 -0
  839. package/skills/response-routes/SKILL.md +248 -120
  840. package/skills/route/SKILL.md +279 -21
  841. package/skills/router-setup/SKILL.md +211 -33
  842. package/skills/server-actions/SKILL.md +751 -0
  843. package/skills/streams-and-websockets/SKILL.md +283 -0
  844. package/skills/tailwind/SKILL.md +27 -3
  845. package/skills/theme/SKILL.md +9 -8
  846. package/skills/typesafety/SKILL.md +547 -107
  847. package/skills/use-cache/SKILL.md +353 -0
  848. package/skills/view-transitions/SKILL.md +294 -0
  849. package/src/__augment-tests__/augment.ts +81 -0
  850. package/src/__augment-tests__/augmented.check.ts +116 -0
  851. package/src/__internal.ts +102 -4
  852. package/src/bin/rango.ts +312 -15
  853. package/src/browser/action-coordinator.ts +114 -0
  854. package/src/browser/app-shell.ts +39 -0
  855. package/src/browser/app-version.ts +14 -0
  856. package/src/browser/event-controller.ts +172 -128
  857. package/src/browser/history-state.ts +101 -0
  858. package/src/browser/index.ts +3 -3
  859. package/src/browser/intercept-utils.ts +52 -0
  860. package/src/browser/link-interceptor.ts +24 -4
  861. package/src/browser/logging.ts +11 -0
  862. package/src/browser/merge-segment-loaders.ts +20 -12
  863. package/src/browser/navigation-bridge.ts +309 -562
  864. package/src/browser/navigation-client.ts +206 -75
  865. package/src/browser/navigation-store.ts +80 -63
  866. package/src/browser/navigation-transaction.ts +279 -0
  867. package/src/browser/network-error-handler.ts +61 -0
  868. package/src/browser/partial-update.ts +355 -314
  869. package/src/browser/prefetch/cache.ts +363 -0
  870. package/src/browser/prefetch/fetch.ts +350 -0
  871. package/src/browser/prefetch/observer.ts +65 -0
  872. package/src/browser/prefetch/policy.ts +48 -0
  873. package/src/browser/prefetch/queue.ts +191 -0
  874. package/src/browser/prefetch/resource-ready.ts +77 -0
  875. package/src/browser/rango-state.ts +136 -0
  876. package/src/browser/react/Link.tsx +255 -71
  877. package/src/browser/react/NavigationProvider.tsx +153 -33
  878. package/src/browser/react/context.ts +11 -0
  879. package/src/browser/react/filter-segment-order.ts +55 -0
  880. package/src/browser/react/index.ts +15 -12
  881. package/src/browser/react/location-state-shared.ts +269 -56
  882. package/src/browser/react/location-state.ts +90 -19
  883. package/src/browser/react/mount-context.ts +6 -1
  884. package/src/browser/react/nonce-context.ts +23 -0
  885. package/src/browser/react/shallow-equal.ts +27 -0
  886. package/src/browser/react/use-action.ts +29 -51
  887. package/src/browser/react/use-client-cache.ts +5 -3
  888. package/src/browser/react/use-handle.ts +41 -123
  889. package/src/browser/react/use-link-status.ts +6 -5
  890. package/src/browser/react/use-navigation.ts +44 -65
  891. package/src/browser/react/use-params.ts +77 -0
  892. package/src/browser/react/use-pathname.ts +47 -0
  893. package/src/browser/react/use-reverse.ts +106 -0
  894. package/src/browser/react/use-router.ts +97 -0
  895. package/src/browser/react/use-search-params.ts +56 -0
  896. package/src/browser/react/use-segments.ts +85 -99
  897. package/src/browser/response-adapter.ts +124 -0
  898. package/src/browser/rsc-router.tsx +275 -72
  899. package/src/browser/scroll-restoration.ts +132 -49
  900. package/src/browser/segment-reconciler.ts +243 -0
  901. package/src/browser/segment-structure-assert.ts +17 -1
  902. package/src/browser/server-action-bridge.ts +508 -610
  903. package/src/browser/shallow.ts +6 -1
  904. package/src/browser/types.ts +149 -48
  905. package/src/browser/validate-redirect-origin.ts +29 -0
  906. package/src/build/collect-fallback-refs.ts +107 -0
  907. package/src/build/generate-manifest.ts +123 -56
  908. package/src/build/generate-route-types.ts +41 -1029
  909. package/src/build/index.ts +4 -0
  910. package/src/build/prefix-tree-utils.ts +123 -0
  911. package/src/build/route-trie.ts +127 -31
  912. package/src/build/route-types/ast-helpers.ts +25 -0
  913. package/src/build/route-types/ast-route-extraction.ts +98 -0
  914. package/src/build/route-types/codegen.ts +102 -0
  915. package/src/build/route-types/include-resolution.ts +418 -0
  916. package/src/build/route-types/param-extraction.ts +48 -0
  917. package/src/build/route-types/per-module-writer.ts +131 -0
  918. package/src/build/route-types/router-processing.ts +659 -0
  919. package/src/build/route-types/scan-filter.ts +85 -0
  920. package/src/build/route-types/source-scan.ts +118 -0
  921. package/src/build/runtime-discovery.ts +220 -0
  922. package/src/cache/background-task.ts +34 -0
  923. package/src/cache/cache-key-utils.ts +44 -0
  924. package/src/cache/cache-policy.ts +125 -0
  925. package/src/cache/cache-runtime.ts +354 -0
  926. package/src/cache/cache-scope.ts +170 -308
  927. package/src/cache/cf/cf-cache-store.ts +716 -30
  928. package/src/cache/cf/index.ts +13 -3
  929. package/src/cache/document-cache.ts +116 -77
  930. package/src/cache/handle-capture.ts +81 -0
  931. package/src/cache/handle-snapshot.ts +144 -0
  932. package/src/cache/index.ts +1 -15
  933. package/src/cache/memory-segment-store.ts +192 -13
  934. package/src/cache/profile-registry.ts +73 -0
  935. package/src/cache/read-through-swr.ts +134 -0
  936. package/src/cache/segment-codec.ts +256 -0
  937. package/src/cache/taint.ts +153 -0
  938. package/src/cache/types.ts +78 -124
  939. package/src/client.rsc.tsx +6 -1
  940. package/src/client.tsx +117 -322
  941. package/src/component-utils.ts +4 -4
  942. package/src/components/DefaultDocument.tsx +5 -1
  943. package/src/context-var.ts +156 -0
  944. package/src/debug.ts +19 -9
  945. package/src/decode-loader-results.ts +36 -0
  946. package/src/errors.ts +106 -10
  947. package/src/handle.ts +54 -11
  948. package/src/handles/MetaTags.tsx +73 -20
  949. package/src/handles/breadcrumbs.ts +66 -0
  950. package/src/handles/index.ts +1 -0
  951. package/src/handles/meta.ts +30 -13
  952. package/src/host/cookie-handler.ts +21 -15
  953. package/src/host/errors.ts +8 -8
  954. package/src/host/index.ts +6 -9
  955. package/src/host/pattern-matcher.ts +27 -27
  956. package/src/host/router.ts +176 -82
  957. package/src/host/testing.ts +8 -8
  958. package/src/host/types.ts +46 -9
  959. package/src/host/utils.ts +2 -2
  960. package/src/href-client.ts +196 -57
  961. package/src/index.rsc.ts +112 -42
  962. package/src/index.ts +178 -74
  963. package/src/internal-debug.ts +9 -3
  964. package/src/loader-store.ts +500 -0
  965. package/src/loader.rsc.ts +15 -93
  966. package/src/loader.ts +20 -10
  967. package/src/missing-id-error.ts +68 -0
  968. package/src/network-error-thrower.tsx +3 -1
  969. package/src/outlet-context.ts +1 -1
  970. package/src/outlet-provider.tsx +45 -0
  971. package/src/prerender/param-hash.ts +4 -2
  972. package/src/prerender/store.ts +125 -18
  973. package/src/prerender.ts +389 -23
  974. package/src/response-utils.ts +37 -0
  975. package/src/reverse.ts +198 -128
  976. package/src/root-error-boundary.tsx +41 -29
  977. package/src/route-content-wrapper.tsx +13 -32
  978. package/src/route-definition/dsl-helpers.ts +1109 -0
  979. package/src/route-definition/helper-factories.ts +90 -0
  980. package/src/route-definition/helpers-types.ts +506 -0
  981. package/src/route-definition/index.ts +55 -0
  982. package/src/route-definition/redirect.ts +101 -0
  983. package/src/route-definition/resolve-handler-use.ts +155 -0
  984. package/src/route-definition/use-item-types.ts +32 -0
  985. package/src/route-definition.ts +1 -1450
  986. package/src/route-map-builder.ts +87 -133
  987. package/src/route-name.ts +53 -0
  988. package/src/route-types.ts +72 -41
  989. package/src/router/content-negotiation.ts +228 -0
  990. package/src/router/debug-manifest.ts +72 -0
  991. package/src/router/error-handling.ts +10 -10
  992. package/src/router/find-match.ts +208 -0
  993. package/src/router/handler-context.ts +372 -125
  994. package/src/router/intercept-resolution.ts +24 -26
  995. package/src/router/lazy-includes.ts +256 -0
  996. package/src/router/loader-resolution.ts +367 -140
  997. package/src/router/logging.ts +112 -6
  998. package/src/router/manifest.ts +89 -28
  999. package/src/router/match-api.ts +175 -238
  1000. package/src/router/match-context.ts +4 -2
  1001. package/src/router/match-handlers.ts +441 -0
  1002. package/src/router/match-middleware/background-revalidation.ts +97 -89
  1003. package/src/router/match-middleware/cache-lookup.ts +289 -54
  1004. package/src/router/match-middleware/cache-store.ts +78 -17
  1005. package/src/router/match-middleware/intercept-resolution.ts +45 -22
  1006. package/src/router/match-middleware/segment-resolution.ts +73 -9
  1007. package/src/router/match-pipelines.ts +10 -45
  1008. package/src/router/match-result.ts +146 -24
  1009. package/src/router/metrics.ts +241 -16
  1010. package/src/router/middleware-cookies.ts +55 -0
  1011. package/src/router/middleware-types.ts +209 -0
  1012. package/src/router/middleware.ts +354 -384
  1013. package/src/router/navigation-snapshot.ts +182 -0
  1014. package/src/router/pattern-matching.ts +279 -44
  1015. package/src/router/prerender-match.ts +527 -0
  1016. package/src/router/preview-match.ts +100 -0
  1017. package/src/router/request-classification.ts +313 -0
  1018. package/src/router/revalidation.ts +163 -16
  1019. package/src/router/route-snapshot.ts +245 -0
  1020. package/src/router/router-context.ts +41 -21
  1021. package/src/router/router-interfaces.ts +500 -0
  1022. package/src/router/router-options.ts +642 -0
  1023. package/src/router/router-registry.ts +21 -0
  1024. package/src/router/segment-resolution/fresh.ts +769 -0
  1025. package/src/router/segment-resolution/helpers.ts +268 -0
  1026. package/src/router/segment-resolution/loader-cache.ts +199 -0
  1027. package/src/router/segment-resolution/revalidation.ts +1420 -0
  1028. package/src/router/segment-resolution/static-store.ts +81 -0
  1029. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  1030. package/src/router/segment-resolution.ts +21 -1354
  1031. package/src/router/segment-wrappers.ts +291 -0
  1032. package/src/router/substitute-pattern-params.ts +56 -0
  1033. package/src/router/telemetry-otel.ts +299 -0
  1034. package/src/router/telemetry.ts +300 -0
  1035. package/src/router/timeout.ts +148 -0
  1036. package/src/router/trie-matching.ts +133 -42
  1037. package/src/router/types.ts +24 -9
  1038. package/src/router/url-params.ts +49 -0
  1039. package/src/router.ts +710 -2373
  1040. package/src/rsc/handler-context.ts +45 -0
  1041. package/src/rsc/handler.ts +821 -1128
  1042. package/src/rsc/helpers.ts +182 -19
  1043. package/src/rsc/index.ts +1 -21
  1044. package/src/rsc/loader-fetch.ts +229 -0
  1045. package/src/rsc/manifest-init.ts +77 -0
  1046. package/src/rsc/nonce.ts +14 -0
  1047. package/src/rsc/origin-guard.ts +161 -0
  1048. package/src/rsc/progressive-enhancement.ts +395 -0
  1049. package/src/rsc/response-error.ts +104 -0
  1050. package/src/rsc/response-route-handler.ts +362 -0
  1051. package/src/rsc/rsc-rendering.ts +240 -0
  1052. package/src/rsc/runtime-warnings.ts +41 -0
  1053. package/src/rsc/server-action.ts +350 -0
  1054. package/src/rsc/ssr-setup.ts +144 -0
  1055. package/src/rsc/types.ts +52 -11
  1056. package/src/search-params.ts +70 -58
  1057. package/src/segment-content-promise.ts +67 -0
  1058. package/src/segment-loader-promise.ts +122 -0
  1059. package/src/segment-system.tsx +237 -73
  1060. package/src/serialize.ts +243 -0
  1061. package/src/server/context.ts +439 -85
  1062. package/src/server/cookie-store.ts +214 -0
  1063. package/src/server/fetchable-loader-store.ts +11 -6
  1064. package/src/server/handle-store.ts +113 -15
  1065. package/src/server/loader-registry.ts +24 -64
  1066. package/src/server/request-context.ts +640 -107
  1067. package/src/server.ts +26 -164
  1068. package/src/ssr/index.tsx +107 -30
  1069. package/src/static-handler.ts +39 -9
  1070. package/src/theme/ThemeProvider.tsx +21 -15
  1071. package/src/theme/ThemeScript.tsx +5 -5
  1072. package/src/theme/constants.ts +5 -2
  1073. package/src/theme/index.ts +4 -14
  1074. package/src/theme/theme-context.ts +4 -30
  1075. package/src/theme/theme-script.ts +21 -18
  1076. package/src/types/boundaries.ts +158 -0
  1077. package/src/types/cache-types.ts +198 -0
  1078. package/src/types/error-types.ts +192 -0
  1079. package/src/types/global-namespace.ts +113 -0
  1080. package/src/types/handler-context.ts +809 -0
  1081. package/src/types/index.ts +89 -0
  1082. package/src/types/loader-types.ts +212 -0
  1083. package/src/types/request-scope.ts +126 -0
  1084. package/src/types/route-config.ts +170 -0
  1085. package/src/types/route-entry.ts +120 -0
  1086. package/src/types/segments.ts +184 -0
  1087. package/src/types.ts +1 -1795
  1088. package/src/urls/include-helper.ts +164 -0
  1089. package/src/urls/index.ts +49 -0
  1090. package/src/urls/path-helper-types.ts +386 -0
  1091. package/src/urls/path-helper.ts +329 -0
  1092. package/src/urls/pattern-types.ts +124 -0
  1093. package/src/urls/response-types.ts +109 -0
  1094. package/src/urls/type-extraction.ts +291 -0
  1095. package/src/urls/urls-function.ts +94 -0
  1096. package/src/urls.ts +1 -1323
  1097. package/src/use-loader.tsx +559 -108
  1098. package/src/vite/debug.ts +185 -0
  1099. package/src/vite/discovery/bundle-postprocess.ts +181 -0
  1100. package/src/vite/discovery/discover-routers.ts +379 -0
  1101. package/src/vite/discovery/discovery-errors.ts +194 -0
  1102. package/src/vite/discovery/gate-state.ts +171 -0
  1103. package/src/vite/discovery/prerender-collection.ts +480 -0
  1104. package/src/vite/discovery/route-types-writer.ts +214 -0
  1105. package/src/vite/discovery/self-gen-tracking.ts +73 -0
  1106. package/src/vite/discovery/state.ts +150 -0
  1107. package/src/vite/discovery/virtual-module-codegen.ts +193 -0
  1108. package/src/vite/index.ts +17 -2261
  1109. package/src/vite/plugin-types.ts +170 -0
  1110. package/src/vite/plugins/cjs-to-esm.ts +94 -0
  1111. package/src/vite/plugins/client-ref-dedup.ts +131 -0
  1112. package/src/vite/plugins/client-ref-hashing.ts +128 -0
  1113. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  1114. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  1115. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  1116. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +109 -60
  1117. package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +32 -51
  1118. package/src/vite/plugins/expose-ids/export-analysis.ts +376 -0
  1119. package/src/vite/plugins/expose-ids/handler-transform.ts +156 -0
  1120. package/src/vite/plugins/expose-ids/loader-transform.ts +72 -0
  1121. package/src/vite/plugins/expose-ids/router-transform.ts +127 -0
  1122. package/src/vite/plugins/expose-ids/types.ts +45 -0
  1123. package/src/vite/plugins/expose-internal-ids.ts +796 -0
  1124. package/src/vite/plugins/performance-tracks.ts +92 -0
  1125. package/src/vite/plugins/refresh-cmd.ts +127 -0
  1126. package/src/vite/plugins/use-cache-transform.ts +338 -0
  1127. package/src/vite/plugins/version-injector.ts +99 -0
  1128. package/src/vite/plugins/version-plugin.ts +323 -0
  1129. package/src/vite/plugins/virtual-entries.ts +123 -0
  1130. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  1131. package/src/vite/rango.ts +549 -0
  1132. package/src/vite/router-discovery.ts +1567 -0
  1133. package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +194 -22
  1134. package/src/vite/utils/banner.ts +36 -0
  1135. package/src/vite/utils/bundle-analysis.ts +139 -0
  1136. package/src/vite/utils/client-chunks.ts +190 -0
  1137. package/src/vite/utils/forward-user-plugins.ts +193 -0
  1138. package/src/vite/utils/manifest-utils.ts +19 -0
  1139. package/src/vite/utils/package-resolution.ts +161 -0
  1140. package/src/vite/utils/prerender-utils.ts +222 -0
  1141. package/src/vite/utils/shared-utils.ts +251 -0
  1142. package/CLAUDE.md +0 -43
  1143. package/src/browser/lru-cache.ts +0 -69
  1144. package/src/browser/request-controller.ts +0 -164
  1145. package/src/cache/memory-store.ts +0 -253
  1146. package/src/router.gen.ts +0 -6
  1147. package/src/static-handler.gen.ts +0 -5
  1148. package/src/urls.gen.ts +0 -8
  1149. package/src/vite/expose-internal-ids.ts +0 -1167
  1150. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- /// <reference path="../../vite/version.d.ts" />
1
+ /// <reference path="../../vite/plugins/version.d.ts" />
2
2
 
3
3
  // Extend CacheStorage with Cloudflare's default cache property
4
4
  declare global {
@@ -10,14 +10,21 @@ declare global {
10
10
  /**
11
11
  * Cloudflare Edge Cache Store
12
12
  *
13
- * Production cache store using Cloudflare's Cache API.
14
- * Handles SWR atomically - get() checks staleness and marks REVALIDATING in one operation.
13
+ * Production cache store using Cloudflare's Cache API (L1) with optional
14
+ * KV persistence (L2).
15
+ *
16
+ * L1 (Cache API): Per-colo, fast, ephemeral. Handles SWR atomically.
17
+ * L2 (KV): Global, persistent, ~50ms reads. Auto-warms cold colos.
18
+ *
19
+ * Read flow: L1 hit → serve | L1 miss → L2 hit → serve + promote to L1 | both miss → render
20
+ * Write flow: L1 write + L2 write (both via waitUntil)
15
21
  *
16
22
  * Features:
17
23
  * - Extended TTL for SWR window (max-age = ttl + swr)
18
24
  * - Staleness via x-edge-cache-stale-at header
19
- * - Atomic REVALIDATING status for thundering herd prevention
25
+ * - Atomic REVALIDATING status for thundering herd prevention (L1 only)
20
26
  * - Non-blocking writes via waitUntil
27
+ * - KV L2 for cross-colo cache persistence
21
28
  */
22
29
 
23
30
  import type {
@@ -25,12 +32,19 @@ import type {
25
32
  CachedEntryData,
26
33
  CacheDefaults,
27
34
  CacheGetResult,
35
+ CacheItemResult,
36
+ CacheItemOptions,
28
37
  } from "../types.js";
29
38
  import {
30
- getRequestContext,
39
+ _getRequestContext,
31
40
  type RequestContext,
32
41
  } from "../../server/request-context.js";
33
42
  import { VERSION } from "@rangojs/router:version";
43
+ import {
44
+ resolveTtl,
45
+ resolveSwrWindow,
46
+ DEFAULT_FUNCTION_TTL,
47
+ } from "../cache-policy.js";
34
48
 
35
49
  // ============================================================================
36
50
  // Constants
@@ -42,6 +56,15 @@ export const CACHE_STALE_AT_HEADER = "x-edge-cache-stale-at";
42
56
  /** Header storing cache status: HIT | REVALIDATING */
43
57
  export const CACHE_STATUS_HEADER = "x-edge-cache-status";
44
58
 
59
+ /**
60
+ * Header stashing the route author's original Cache-Control on L1 document
61
+ * entries. putResponse/promoteResponseToL1 overwrite Cache-Control with a long
62
+ * `max-age` so the CF Cache API retains the entry across the whole SWR window;
63
+ * getResponse restores this original value before serving so the client and any
64
+ * upstream CDN see the author's intended directive, not the internal edge TTL.
65
+ */
66
+ const CACHE_ORIG_CC_HEADER = "x-edge-cache-orig-cc";
67
+
45
68
  /**
46
69
  * Maximum age in seconds for REVALIDATING status before allowing new revalidation.
47
70
  * After this period, a stale entry in REVALIDATING status will trigger revalidation again.
@@ -49,16 +72,87 @@ export const CACHE_STATUS_HEADER = "x-edge-cache-status";
49
72
  */
50
73
  export const MAX_REVALIDATION_INTERVAL = 30;
51
74
 
75
+ /**
76
+ * Maximum time (ms) to wait for an L1 edge cache (CF Cache API) read before
77
+ * giving up and treating it as a miss. The Cache API is normally sub-millisecond
78
+ * per-colo, so a slow `match` signals a degraded colo; we don't want it adding
79
+ * latency to the request. On timeout the lookup is abandoned, a warning is
80
+ * logged, and the read falls through to its normal miss path (L2/KV or render).
81
+ *
82
+ * This is the default; override per store via
83
+ * `CFCacheStoreOptions.edgeLookupTimeoutMs` (<= 0 disables the budget).
84
+ */
85
+ export const EDGE_LOOKUP_TIMEOUT_MS = 10;
86
+
52
87
  // ============================================================================
53
88
  // Types
54
89
  // ============================================================================
55
90
 
91
+ // Re-exported from the canonical home so cf-cache-store consumers keep
92
+ // importing `ExecutionContext` from this module without a second interface
93
+ // drifting over time.
94
+ export type { ExecutionContext } from "../../types/request-scope.js";
95
+ import type { ExecutionContext } from "../../types/request-scope.js";
96
+
97
+ /**
98
+ * Minimal Cloudflare KV Namespace interface.
99
+ * Avoids hard dependency on @cloudflare/workers-types.
100
+ */
101
+ export interface KVNamespace {
102
+ get(key: string, options?: { type?: string }): Promise<any>;
103
+ put(
104
+ key: string,
105
+ value: string,
106
+ options?: { expirationTtl?: number },
107
+ ): Promise<void>;
108
+ delete(key: string): Promise<void>;
109
+ }
110
+
111
+ /**
112
+ * KV envelope for segment cache entries.
113
+ * @internal
114
+ */
115
+ interface KVSegmentEnvelope {
116
+ /** Cached segment data */
117
+ d: CachedEntryData;
118
+ /** When entry becomes stale (ms epoch) */
119
+ s: number;
120
+ /** When entry hard-expires (ms epoch) */
121
+ e: number;
122
+ }
123
+
56
124
  /**
57
- * Cloudflare Workers ExecutionContext (subset we need)
125
+ * KV envelope for function cache entries ("use cache").
126
+ * @internal
58
127
  */
59
- export interface ExecutionContext {
60
- waitUntil(promise: Promise<any>): void;
61
- passThroughOnException(): void;
128
+ interface KVItemEnvelope {
129
+ /** RSC-serialized return value */
130
+ v: string;
131
+ /** RSC-encoded handle data (see handle-snapshot.ts encodeHandles) */
132
+ h?: string;
133
+ /** When entry becomes stale (ms epoch) */
134
+ s: number;
135
+ /** When entry hard-expires (ms epoch) */
136
+ e: number;
137
+ }
138
+
139
+ /**
140
+ * KV envelope for document cache entries.
141
+ * @internal
142
+ */
143
+ interface KVResponseEnvelope {
144
+ /** Response body as base64-encoded string (safe for binary payloads) */
145
+ b: string;
146
+ /** HTTP status code */
147
+ st: number;
148
+ /** HTTP status text */
149
+ stx: string;
150
+ /** Serialized headers as key-value pairs */
151
+ hd: [string, string][];
152
+ /** When entry becomes stale (ms epoch) */
153
+ s: number;
154
+ /** When entry hard-expires (ms epoch) */
155
+ e: number;
62
156
  }
63
157
 
64
158
  export interface CFCacheStoreOptions<TEnv = unknown> {
@@ -91,15 +185,40 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
91
185
  */
92
186
  ctx: ExecutionContext;
93
187
 
188
+ /**
189
+ * Optional KV namespace for L2 cache persistence.
190
+ *
191
+ * When provided, KV acts as a global fallback behind the per-colo Cache API.
192
+ * On L1 miss, KV is checked and hits are promoted back to L1.
193
+ * On writes, data is persisted to both L1 and KV.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * new CFCacheStore({ ctx: env.ctx, kv: env.CACHE_KV })
198
+ * ```
199
+ */
200
+ kv?: KVNamespace;
201
+
94
202
  /**
95
203
  * Cache version string override. When this changes, all cached entries are
96
204
  * effectively invalidated (new keys won't match old entries).
97
205
  *
98
- * Defaults to the auto-generated VERSION from `rsc-router:version` virtual module.
206
+ * Defaults to the auto-generated VERSION from the `@rangojs/router:version` virtual module.
99
207
  * Only set this if you need a custom versioning strategy.
100
208
  */
101
209
  version?: string;
102
210
 
211
+ /**
212
+ * Latency budget (ms) for an L1 edge cache (CF Cache API) read. A `match`
213
+ * slower than this is abandoned and treated as a miss, so a degraded colo
214
+ * cannot stall the request; the read then falls through to its normal miss
215
+ * path (L2/KV or render).
216
+ *
217
+ * Defaults to {@link EDGE_LOOKUP_TIMEOUT_MS} (10). Set to 0 (or any value
218
+ * <= 0) to disable the budget and always await `match`.
219
+ */
220
+ edgeLookupTimeoutMs?: number;
221
+
103
222
  /**
104
223
  * Custom key generator applied to all cache operations.
105
224
  * Receives the full RequestContext (including env) and the default-generated key.
@@ -124,7 +243,7 @@ export interface CFCacheStoreOptions<TEnv = unknown> {
124
243
  * @example Using cookies for locale-aware caching
125
244
  * ```typescript
126
245
  * keyGenerator: (ctx, defaultKey) => {
127
- * const locale = ctx.cookie('locale') || 'en';
246
+ * const locale = cookies().get('locale')?.value || 'en';
128
247
  * return `${locale}:${defaultKey}`;
129
248
  * }
130
249
  * ```
@@ -153,9 +272,11 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
153
272
  ) => string | Promise<string>;
154
273
 
155
274
  private readonly namespace?: string;
156
- private readonly baseUrl: string;
275
+ private readonly explicitBaseUrl?: string;
157
276
  private readonly waitUntil?: (fn: () => Promise<void>) => void;
158
277
  private readonly version?: string;
278
+ private readonly edgeLookupTimeoutMs: number;
279
+ private readonly kv?: KVNamespace;
159
280
 
160
281
  constructor(options: CFCacheStoreOptions<TEnv>) {
161
282
  if (!options.ctx) {
@@ -167,22 +288,43 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
167
288
  }
168
289
 
169
290
  this.namespace = options.namespace;
170
- this.baseUrl = options.baseUrl ?? this.deriveBaseUrl();
291
+ // Base URL is resolved lazily per cache operation (see resolveBaseUrl).
292
+ // The store is constructed before the per-request context ALS is entered
293
+ // (the cache factory runs ahead of runWithRequestContext in the handler),
294
+ // so deriving the host here would always miss the request and fall back to
295
+ // the internal host. Only the explicit override can be captured eagerly.
296
+ this.explicitBaseUrl = options.baseUrl;
171
297
  this.defaults = options.defaults;
172
298
  this.version = options.version ?? VERSION;
299
+ this.edgeLookupTimeoutMs =
300
+ options.edgeLookupTimeoutMs ?? EDGE_LOOKUP_TIMEOUT_MS;
173
301
  this.keyGenerator = options.keyGenerator;
174
302
  this.waitUntil = (fn) => options.ctx.waitUntil(fn());
303
+ this.kv = options.kv;
304
+ }
305
+
306
+ /**
307
+ * Resolve the cache-key base URL for the current cache operation.
308
+ * Prefers an explicit `baseUrl` option; otherwise derives it from the live
309
+ * request. Called per operation (from keyToRequest), which runs inside the
310
+ * request-context ALS, so deriveBaseUrl sees the request and can use the
311
+ * production host instead of the internal fallback.
312
+ * @internal
313
+ */
314
+ private resolveBaseUrl(): string {
315
+ return this.explicitBaseUrl ?? this.deriveBaseUrl();
175
316
  }
176
317
 
177
318
  /**
178
319
  * Derive base URL from request hostname via requestContext.
179
- * Uses internal fallback for dev/preview environments.
320
+ * Uses internal fallback for dev/preview environments and untrusted hostnames.
321
+ * Must run inside the request context (invoked lazily via resolveBaseUrl).
180
322
  * @internal
181
323
  */
182
324
  private deriveBaseUrl(): string {
183
- const fallback = "https://rsc-cache.internal.com/";
325
+ const fallback = "https://rsc-dummy-host-1.com/";
184
326
 
185
- const ctx = getRequestContext();
327
+ const ctx = _getRequestContext();
186
328
  if (!ctx?.request) {
187
329
  return fallback;
188
330
  }
@@ -201,6 +343,12 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
201
343
  return fallback;
202
344
  }
203
345
 
346
+ // Validate hostname: must be a valid domain (alphanumeric, hyphens, dots)
347
+ // to prevent host header injection into cache keys
348
+ if (!/^[a-zA-Z0-9.-]+$/.test(hostname) || hostname.length > 253) {
349
+ return fallback;
350
+ }
351
+
204
352
  // Use actual hostname for production
205
353
  return `https://${hostname}/`;
206
354
  } catch {
@@ -219,6 +367,57 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
219
367
  return caches.default;
220
368
  }
221
369
 
370
+ /**
371
+ * Read from the L1 edge cache with a latency budget. A `match` that takes
372
+ * longer than the configured budget (edgeLookupTimeoutMs, default
373
+ * EDGE_LOOKUP_TIMEOUT_MS) is abandoned and reported as a miss (undefined) so a
374
+ * degraded colo cannot stall the request; callers then fall through to their
375
+ * normal miss path (L2/KV or render). The slow `match` is left to settle in
376
+ * the background (errors swallowed) rather than aborted, since the Cache API
377
+ * exposes no cancellation. A budget <= 0 disables the timeout entirely and
378
+ * awaits `match` directly.
379
+ * @internal
380
+ */
381
+ private async matchWithTimeout(
382
+ cache: Cache,
383
+ request: Request,
384
+ ): Promise<Response | undefined> {
385
+ const budget = this.edgeLookupTimeoutMs;
386
+ if (budget <= 0) {
387
+ return cache.match(request);
388
+ }
389
+ let timer: ReturnType<typeof setTimeout> | undefined;
390
+ const timeout = new Promise<{ timedOut: true }>((resolve) => {
391
+ timer = setTimeout(() => resolve({ timedOut: true }), budget);
392
+ });
393
+ try {
394
+ const matchPromise = cache.match(request);
395
+ // The losing branch keeps running; ensure a late rejection can't surface
396
+ // as an unhandled rejection once we've stopped awaiting it.
397
+ matchPromise.catch(() => {});
398
+ const result = await Promise.race([
399
+ matchPromise.then((response) => ({
400
+ timedOut: false as const,
401
+ response,
402
+ })),
403
+ timeout,
404
+ ]);
405
+ if (result.timedOut) {
406
+ console.warn(
407
+ `[CFCacheStore] edge cache lookup exceeded ${budget}ms; treating as miss`,
408
+ );
409
+ return undefined;
410
+ }
411
+ return result.response;
412
+ } finally {
413
+ if (timer) clearTimeout(timer);
414
+ }
415
+ }
416
+
417
+ // ============================================================================
418
+ // Segment Cache Methods
419
+ // ============================================================================
420
+
222
421
  /**
223
422
  * Get cached entry data by key.
224
423
  *
@@ -227,16 +426,17 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
227
426
  * - If already REVALIDATING (and recent), returns shouldRevalidate: false
228
427
  * - If fresh, returns shouldRevalidate: false
229
428
  *
230
- * The atomic mark prevents thundering herd - only first request triggers revalidation.
429
+ * On L1 miss, falls back to KV (L2) if configured.
430
+ * KV hits are promoted to L1 in the background.
231
431
  */
232
432
  async get(key: string): Promise<CacheGetResult | null> {
233
433
  try {
234
434
  const cache = await this.getCache();
235
435
  const request = this.keyToRequest(key);
236
- const response = await cache.match(request);
436
+ const response = await this.matchWithTimeout(cache, request);
237
437
 
238
438
  if (!response) {
239
- return null;
439
+ return this.kvGetSegment(key);
240
440
  }
241
441
 
242
442
  // Read status headers
@@ -279,6 +479,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
279
479
  /**
280
480
  * Store entry data with TTL and optional SWR window.
281
481
  * Uses waitUntil for non-blocking write when available.
482
+ * When KV is configured, also persists to L2.
282
483
  */
283
484
  async set(
284
485
  key: string,
@@ -291,11 +492,12 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
291
492
  const request = this.keyToRequest(key);
292
493
 
293
494
  // Extended TTL covers SWR window
294
- const swrWindow = swr ?? this.defaults?.swr ?? 0;
495
+ const swrWindow = resolveSwrWindow(swr, this.defaults);
295
496
  const totalTtl = ttl + swrWindow;
296
497
  const staleAt = Date.now() + ttl * 1000;
297
498
 
298
- const response = new Response(JSON.stringify(data), {
499
+ const body = JSON.stringify(data);
500
+ const response = new Response(body, {
299
501
  headers: {
300
502
  "Content-Type": "application/json",
301
503
  "Cache-Control": `public, max-age=${totalTtl}`,
@@ -315,18 +517,35 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
315
517
  // Blocking fallback
316
518
  await putPromise;
317
519
  }
520
+
521
+ // L2: persist to KV
522
+ this.kvSetSegment(key, data, staleAt, totalTtl, swrWindow);
318
523
  } catch (error) {
319
524
  console.error("[CFCacheStore] set failed:", error);
320
525
  }
321
526
  }
322
527
 
323
528
  /**
324
- * Delete a cached entry
529
+ * Delete a cached entry from L1 and L2.
325
530
  */
326
531
  async delete(key: string): Promise<boolean> {
327
532
  try {
328
533
  const cache = await this.getCache();
329
- return await cache.delete(this.keyToRequest(key));
534
+ const result = await cache.delete(this.keyToRequest(key));
535
+
536
+ // L2: delete from KV
537
+ if (this.kv && this.waitUntil) {
538
+ const kvKey = this.toKVKey(key);
539
+ this.waitUntil(async () => {
540
+ try {
541
+ await this.kv!.delete(kvKey);
542
+ } catch {
543
+ // KV delete failures are non-critical
544
+ }
545
+ });
546
+ }
547
+
548
+ return result;
330
549
  } catch (error) {
331
550
  console.error("[CFCacheStore] delete failed:", error);
332
551
  return false;
@@ -340,6 +559,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
340
559
  /**
341
560
  * Get a cached Response by key (for document-level caching).
342
561
  * Returns the response and whether it should be revalidated (SWR).
562
+ * Falls back to KV (L2) on L1 miss.
343
563
  */
344
564
  async getResponse(
345
565
  key: string,
@@ -347,10 +567,10 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
347
567
  try {
348
568
  const cache = await this.getCache();
349
569
  const request = this.keyToRequest(`doc:${key}`);
350
- const response = await cache.match(request);
570
+ const response = await this.matchWithTimeout(cache, request);
351
571
 
352
572
  if (!response || response.status !== 200) {
353
- return null;
573
+ return this.kvGetResponse(key);
354
574
  }
355
575
 
356
576
  // Check staleness
@@ -358,7 +578,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
358
578
  const isStale = staleAt > 0 && Date.now() > staleAt;
359
579
 
360
580
  return {
361
- response,
581
+ response: this.toClientResponse(response),
362
582
  shouldRevalidate: isStale,
363
583
  };
364
584
  } catch (error) {
@@ -367,8 +587,33 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
367
587
  }
368
588
  }
369
589
 
590
+ /**
591
+ * Strip internal edge headers and restore the author's Cache-Control before a
592
+ * cached document Response is served to a client. L1 entries carry the
593
+ * internal staleness/status headers and a rewritten Cache-Control; none of
594
+ * those should reach the browser or an upstream CDN.
595
+ */
596
+ private toClientResponse(response: Response): Response {
597
+ const headers = new Headers(response.headers);
598
+ const originalCacheControl = headers.get(CACHE_ORIG_CC_HEADER);
599
+ if (originalCacheControl !== null) {
600
+ headers.set("Cache-Control", originalCacheControl);
601
+ } else {
602
+ headers.delete("Cache-Control");
603
+ }
604
+ headers.delete(CACHE_ORIG_CC_HEADER);
605
+ headers.delete(CACHE_STALE_AT_HEADER);
606
+ headers.delete(CACHE_STATUS_HEADER);
607
+ return new Response(response.body, {
608
+ status: response.status,
609
+ statusText: response.statusText,
610
+ headers,
611
+ });
612
+ }
613
+
370
614
  /**
371
615
  * Store a Response with TTL and optional SWR window (for document-level caching).
616
+ * When KV is configured, also persists to L2.
372
617
  */
373
618
  async putResponse(
374
619
  key: string,
@@ -381,16 +626,29 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
381
626
  const request = this.keyToRequest(`doc:${key}`);
382
627
 
383
628
  // Extended TTL covers SWR window
384
- const swrWindow = swr ?? this.defaults?.swr ?? 0;
629
+ const swrWindow = resolveSwrWindow(swr, this.defaults);
385
630
  const totalTtl = ttl + swrWindow;
386
631
  const staleAt = Date.now() + ttl * 1000;
387
632
 
388
- // Clone and add cache headers
633
+ // Clone body for potential KV write before consuming it for L1
634
+ const [l1Body, kvBody] = this.kv
635
+ ? response.body
636
+ ? response.body.tee()
637
+ : [null, null]
638
+ : [response.body, null];
639
+
640
+ // Clone and add cache headers. The author's Cache-Control is stashed and
641
+ // replaced with a long max-age so the CF Cache API holds the entry across
642
+ // the SWR window; getResponse restores the original before serving.
389
643
  const headers = new Headers(response.headers);
644
+ const originalCacheControl = response.headers.get("Cache-Control");
645
+ if (originalCacheControl !== null) {
646
+ headers.set(CACHE_ORIG_CC_HEADER, originalCacheControl);
647
+ }
390
648
  headers.set("Cache-Control", `public, max-age=${totalTtl}`);
391
649
  headers.set(CACHE_STALE_AT_HEADER, String(staleAt));
392
650
 
393
- const toCache = new Response(response.body, {
651
+ const toCache = new Response(l1Body, {
394
652
  status: response.status,
395
653
  statusText: response.statusText,
396
654
  headers,
@@ -407,11 +665,166 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
407
665
  // Blocking fallback
408
666
  await putPromise;
409
667
  }
668
+
669
+ // L2: persist to KV (KV requires expirationTtl >= 60s)
670
+ if (this.kv && this.waitUntil && totalTtl >= 60) {
671
+ const kvKey = this.toKVKey(`doc:${key}`);
672
+ const headersArray: [string, string][] = [];
673
+ response.headers.forEach((v, k) => headersArray.push([k, v]));
674
+ // Read body as ArrayBuffer and encode to base64 to preserve binary payloads
675
+ const bodyBuf = kvBody
676
+ ? await new Response(kvBody).arrayBuffer()
677
+ : new ArrayBuffer(0);
678
+ const bodyBase64 = bufferToBase64(bodyBuf);
679
+
680
+ this.waitUntil(async () => {
681
+ try {
682
+ const envelope: KVResponseEnvelope = {
683
+ b: bodyBase64,
684
+ st: response.status,
685
+ stx: response.statusText,
686
+ hd: headersArray,
687
+ s: staleAt,
688
+ e: staleAt + swrWindow * 1000,
689
+ };
690
+ await this.kv!.put(kvKey, JSON.stringify(envelope), {
691
+ expirationTtl: totalTtl,
692
+ });
693
+ } catch (error) {
694
+ console.error("[CFCacheStore] KV putResponse failed:", error);
695
+ }
696
+ });
697
+ }
410
698
  } catch (error) {
411
699
  console.error("[CFCacheStore] putResponse failed:", error);
412
700
  }
413
701
  }
414
702
 
703
+ // ============================================================================
704
+ // Function Cache Methods (for "use cache" directive)
705
+ // ============================================================================
706
+
707
+ /**
708
+ * Get a cached function result by key.
709
+ * Follows the same SWR pattern as get() for segment caching.
710
+ * Falls back to KV (L2) on L1 miss.
711
+ */
712
+ async getItem(key: string): Promise<CacheItemResult | null> {
713
+ try {
714
+ const cache = await this.getCache();
715
+ const request = this.keyToRequest(`fn:${key}`);
716
+ const response = await this.matchWithTimeout(cache, request);
717
+
718
+ if (!response) return this.kvGetItem(key);
719
+
720
+ const staleAt = Number(
721
+ response.headers.get(CACHE_STALE_AT_HEADER) ?? "0",
722
+ );
723
+ const status = response.headers.get(CACHE_STATUS_HEADER);
724
+ const age = Number(response.headers.get("age") ?? "0");
725
+
726
+ const isStale = staleAt > 0 && Date.now() > staleAt;
727
+ const isRevalidating =
728
+ status === "REVALIDATING" && age < MAX_REVALIDATION_INTERVAL;
729
+
730
+ const data = (await response.json()) as {
731
+ value: string;
732
+ handles?: string;
733
+ };
734
+
735
+ if (!isStale || isRevalidating) {
736
+ return {
737
+ value: data.value,
738
+ handles: data.handles,
739
+ shouldRevalidate: false,
740
+ };
741
+ }
742
+
743
+ // Stale and needs revalidation — mark REVALIDATING atomically
744
+ const headers = new Headers(response.headers);
745
+ headers.set(CACHE_STATUS_HEADER, "REVALIDATING");
746
+ await cache.put(
747
+ request,
748
+ new Response(JSON.stringify(data), { status: 200, headers }),
749
+ );
750
+
751
+ return {
752
+ value: data.value,
753
+ handles: data.handles,
754
+ shouldRevalidate: true,
755
+ };
756
+ } catch (error) {
757
+ console.error("[CFCacheStore] getItem failed:", error);
758
+ return null;
759
+ }
760
+ }
761
+
762
+ /**
763
+ * Store a function result with TTL and optional SWR window.
764
+ * When KV is configured, also persists to L2.
765
+ */
766
+ async setItem(
767
+ key: string,
768
+ value: string,
769
+ options?: CacheItemOptions,
770
+ ): Promise<void> {
771
+ try {
772
+ const cache = await this.getCache();
773
+ const request = this.keyToRequest(`fn:${key}`);
774
+
775
+ const ttl = resolveTtl(options?.ttl, this.defaults, DEFAULT_FUNCTION_TTL);
776
+ const swrWindow = resolveSwrWindow(options?.swr, this.defaults);
777
+ const totalTtl = ttl + swrWindow;
778
+ const staleAt = Date.now() + ttl * 1000;
779
+
780
+ const body = JSON.stringify({ value, handles: options?.handles });
781
+ const response = new Response(body, {
782
+ headers: {
783
+ "Content-Type": "application/json",
784
+ "Cache-Control": `public, max-age=${totalTtl}`,
785
+ [CACHE_STALE_AT_HEADER]: String(staleAt),
786
+ [CACHE_STATUS_HEADER]: "HIT",
787
+ },
788
+ });
789
+
790
+ const putPromise = cache.put(request, response);
791
+
792
+ if (this.waitUntil) {
793
+ this.waitUntil(async () => {
794
+ await putPromise;
795
+ });
796
+ } else {
797
+ await putPromise;
798
+ }
799
+
800
+ // L2: persist to KV (KV requires expirationTtl >= 60s)
801
+ if (this.kv && this.waitUntil && totalTtl >= 60) {
802
+ const kvKey = this.toKVKey(`fn:${key}`);
803
+ this.waitUntil(async () => {
804
+ try {
805
+ const envelope: KVItemEnvelope = {
806
+ v: value,
807
+ h: options?.handles,
808
+ s: staleAt,
809
+ e: staleAt + swrWindow * 1000,
810
+ };
811
+ await this.kv!.put(kvKey, JSON.stringify(envelope), {
812
+ expirationTtl: totalTtl,
813
+ });
814
+ } catch (error) {
815
+ console.error("[CFCacheStore] KV setItem failed:", error);
816
+ }
817
+ });
818
+ }
819
+ } catch (error) {
820
+ console.error("[CFCacheStore] setItem failed:", error);
821
+ }
822
+ }
823
+
824
+ // ============================================================================
825
+ // Key Helpers
826
+ // ============================================================================
827
+
415
828
  /**
416
829
  * Convert string key to Request object for CF Cache API.
417
830
  * Includes version in URL if specified (for cache invalidation on code changes).
@@ -421,8 +834,281 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
421
834
  const encodedKey = encodeURIComponent(key);
422
835
  // Include version in URL path to invalidate cache when version changes
423
836
  const versionPath = this.version ? `v/${this.version}/` : "";
424
- return new Request(`${this.baseUrl}${versionPath}${encodedKey}`, {
837
+ return new Request(`${this.resolveBaseUrl()}${versionPath}${encodedKey}`, {
425
838
  method: "GET",
426
839
  });
427
840
  }
841
+
842
+ /**
843
+ * Convert string key to KV key string.
844
+ * Uses same version prefix as Cache API for consistent invalidation.
845
+ * @internal
846
+ */
847
+ private toKVKey(key: string): string {
848
+ const versionPath = this.version ? `v/${this.version}/` : "";
849
+ return `${versionPath}${key}`;
850
+ }
851
+
852
+ // ============================================================================
853
+ // KV L2 Helpers
854
+ // ============================================================================
855
+
856
+ /**
857
+ * KV fallback for segment cache reads.
858
+ * Returns null if KV is not configured, entry is missing, or expired.
859
+ * Promotes hits to L1 via waitUntil.
860
+ * @internal
861
+ */
862
+ private async kvGetSegment(key: string): Promise<CacheGetResult | null> {
863
+ if (!this.kv) return null;
864
+
865
+ try {
866
+ const kvKey = this.toKVKey(key);
867
+ const raw = await this.kv.get(kvKey, { type: "json" });
868
+ if (!raw) return null;
869
+
870
+ const envelope = raw as KVSegmentEnvelope;
871
+ const now = Date.now();
872
+
873
+ // Hard-expired — treat as miss
874
+ if (now > envelope.e) return null;
875
+
876
+ const shouldRevalidate = now > envelope.s;
877
+
878
+ // Promote to L1 in background
879
+ this.promoteSegmentToL1(key, envelope);
880
+
881
+ return { data: envelope.d, shouldRevalidate };
882
+ } catch (error) {
883
+ console.error("[CFCacheStore] KV get failed:", error);
884
+ return null;
885
+ }
886
+ }
887
+
888
+ /**
889
+ * Write segment data to KV.
890
+ * @internal
891
+ */
892
+ private kvSetSegment(
893
+ key: string,
894
+ data: CachedEntryData,
895
+ staleAt: number,
896
+ totalTtl: number,
897
+ swrWindow: number,
898
+ ): void {
899
+ // KV requires expirationTtl >= 60s. Skip write for short-lived entries.
900
+ if (!this.kv || !this.waitUntil || totalTtl < 60) return;
901
+
902
+ const kvKey = this.toKVKey(key);
903
+ const expiresAt = staleAt + swrWindow * 1000;
904
+
905
+ this.waitUntil(async () => {
906
+ try {
907
+ const envelope: KVSegmentEnvelope = {
908
+ d: data,
909
+ s: staleAt,
910
+ e: expiresAt,
911
+ };
912
+ await this.kv!.put(kvKey, JSON.stringify(envelope), {
913
+ expirationTtl: totalTtl,
914
+ });
915
+ } catch (error) {
916
+ console.error("[CFCacheStore] KV set failed:", error);
917
+ }
918
+ });
919
+ }
920
+
921
+ /**
922
+ * Promote segment data from KV to L1 Cache API.
923
+ * @internal
924
+ */
925
+ private promoteSegmentToL1(key: string, envelope: KVSegmentEnvelope): void {
926
+ if (!this.waitUntil) return;
927
+
928
+ this.waitUntil(async () => {
929
+ try {
930
+ const now = Date.now();
931
+ const remainingTtl = Math.max(1, Math.floor((envelope.e - now) / 1000));
932
+ const cache = await this.getCache();
933
+ const request = this.keyToRequest(key);
934
+
935
+ const response = new Response(JSON.stringify(envelope.d), {
936
+ headers: {
937
+ "Content-Type": "application/json",
938
+ "Cache-Control": `public, max-age=${remainingTtl}`,
939
+ [CACHE_STALE_AT_HEADER]: String(envelope.s),
940
+ [CACHE_STATUS_HEADER]: "HIT",
941
+ },
942
+ });
943
+
944
+ await cache.put(request, response);
945
+ } catch (error) {
946
+ console.error("[CFCacheStore] L1 promote failed:", error);
947
+ }
948
+ });
949
+ }
950
+
951
+ /**
952
+ * KV fallback for function cache reads.
953
+ * @internal
954
+ */
955
+ private async kvGetItem(key: string): Promise<CacheItemResult | null> {
956
+ if (!this.kv) return null;
957
+
958
+ try {
959
+ const kvKey = this.toKVKey(`fn:${key}`);
960
+ const raw = await this.kv.get(kvKey, { type: "json" });
961
+ if (!raw) return null;
962
+
963
+ const envelope = raw as KVItemEnvelope;
964
+ const now = Date.now();
965
+
966
+ if (now > envelope.e) return null;
967
+
968
+ const shouldRevalidate = now > envelope.s;
969
+
970
+ // Promote to L1
971
+ this.promoteItemToL1(key, envelope);
972
+
973
+ return {
974
+ value: envelope.v,
975
+ handles: envelope.h,
976
+ shouldRevalidate,
977
+ };
978
+ } catch (error) {
979
+ console.error("[CFCacheStore] KV getItem failed:", error);
980
+ return null;
981
+ }
982
+ }
983
+
984
+ /**
985
+ * Promote function cache data from KV to L1.
986
+ * @internal
987
+ */
988
+ private promoteItemToL1(key: string, envelope: KVItemEnvelope): void {
989
+ if (!this.waitUntil) return;
990
+
991
+ this.waitUntil(async () => {
992
+ try {
993
+ const now = Date.now();
994
+ const remainingTtl = Math.max(1, Math.floor((envelope.e - now) / 1000));
995
+ const cache = await this.getCache();
996
+ const request = this.keyToRequest(`fn:${key}`);
997
+
998
+ const body = JSON.stringify({ value: envelope.v, handles: envelope.h });
999
+ const response = new Response(body, {
1000
+ headers: {
1001
+ "Content-Type": "application/json",
1002
+ "Cache-Control": `public, max-age=${remainingTtl}`,
1003
+ [CACHE_STALE_AT_HEADER]: String(envelope.s),
1004
+ [CACHE_STATUS_HEADER]: "HIT",
1005
+ },
1006
+ });
1007
+
1008
+ await cache.put(request, response);
1009
+ } catch (error) {
1010
+ console.error("[CFCacheStore] L1 item promote failed:", error);
1011
+ }
1012
+ });
1013
+ }
1014
+
1015
+ /**
1016
+ * KV fallback for document cache reads.
1017
+ * @internal
1018
+ */
1019
+ private async kvGetResponse(
1020
+ key: string,
1021
+ ): Promise<{ response: Response; shouldRevalidate: boolean } | null> {
1022
+ if (!this.kv) return null;
1023
+
1024
+ try {
1025
+ const kvKey = this.toKVKey(`doc:${key}`);
1026
+ const raw = await this.kv.get(kvKey, { type: "json" });
1027
+ if (!raw) return null;
1028
+
1029
+ const envelope = raw as KVResponseEnvelope;
1030
+ const now = Date.now();
1031
+
1032
+ if (now > envelope.e) return null;
1033
+
1034
+ const shouldRevalidate = now > envelope.s;
1035
+
1036
+ // Reconstruct Response (decode base64 → binary)
1037
+ const headers = new Headers(envelope.hd);
1038
+ const bodyBuffer = base64ToBuffer(envelope.b);
1039
+ const response = new Response(bodyBuffer, {
1040
+ status: envelope.st,
1041
+ statusText: envelope.stx,
1042
+ headers,
1043
+ });
1044
+
1045
+ // Promote to L1
1046
+ this.promoteResponseToL1(key, envelope);
1047
+
1048
+ return { response, shouldRevalidate };
1049
+ } catch (error) {
1050
+ console.error("[CFCacheStore] KV getResponse failed:", error);
1051
+ return null;
1052
+ }
1053
+ }
1054
+
1055
+ /**
1056
+ * Promote document cache data from KV to L1.
1057
+ * @internal
1058
+ */
1059
+ private promoteResponseToL1(key: string, envelope: KVResponseEnvelope): void {
1060
+ if (!this.waitUntil) return;
1061
+
1062
+ this.waitUntil(async () => {
1063
+ try {
1064
+ const now = Date.now();
1065
+ const remainingTtl = Math.max(1, Math.floor((envelope.e - now) / 1000));
1066
+ const cache = await this.getCache();
1067
+ const request = this.keyToRequest(`doc:${key}`);
1068
+
1069
+ const headers = new Headers(envelope.hd);
1070
+ const originalCacheControl = headers.get("Cache-Control");
1071
+ if (originalCacheControl !== null) {
1072
+ headers.set(CACHE_ORIG_CC_HEADER, originalCacheControl);
1073
+ }
1074
+ headers.set("Cache-Control", `public, max-age=${remainingTtl}`);
1075
+ headers.set(CACHE_STALE_AT_HEADER, String(envelope.s));
1076
+
1077
+ const bodyBuffer = base64ToBuffer(envelope.b);
1078
+ const response = new Response(bodyBuffer, {
1079
+ status: envelope.st,
1080
+ statusText: envelope.stx,
1081
+ headers,
1082
+ });
1083
+
1084
+ await cache.put(request, response);
1085
+ } catch (error) {
1086
+ console.error("[CFCacheStore] L1 response promote failed:", error);
1087
+ }
1088
+ });
1089
+ }
1090
+ }
1091
+
1092
+ // ============================================================================
1093
+ // Base64 Helpers (binary-safe response body encoding for KV)
1094
+ // ============================================================================
1095
+
1096
+ /** Encode ArrayBuffer to base64 string. */
1097
+ function bufferToBase64(buffer: ArrayBuffer): string {
1098
+ const bytes = new Uint8Array(buffer);
1099
+ let binary = "";
1100
+ for (let i = 0; i < bytes.length; i++) {
1101
+ binary += String.fromCharCode(bytes[i]!);
1102
+ }
1103
+ return btoa(binary);
1104
+ }
1105
+
1106
+ /** Decode base64 string to ArrayBuffer. */
1107
+ function base64ToBuffer(base64: string): ArrayBuffer {
1108
+ const binary = atob(base64);
1109
+ const bytes = new Uint8Array(binary.length);
1110
+ for (let i = 0; i < binary.length; i++) {
1111
+ bytes[i] = binary.charCodeAt(i);
1112
+ }
1113
+ return bytes.buffer;
428
1114
  }