stratal 0.0.21 → 0.0.23

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 (296) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/cloudflare-workers-loader.mjs +80 -7
  3. package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
  4. package/dist/bin/quarry.mjs +84 -160
  5. package/dist/bin/quarry.mjs.map +1 -1
  6. package/dist/cache/index.d.mts +8 -46
  7. package/dist/cache/index.d.mts.map +1 -1
  8. package/dist/cache/index.mjs +134 -97
  9. package/dist/cache/index.mjs.map +1 -1
  10. package/dist/{cache.service-DsnKuNyO.d.mts → cache.service-uElmBtdS.d.mts} +29 -39
  11. package/dist/cache.service-uElmBtdS.d.mts.map +1 -0
  12. package/dist/{command-BgSlsS4M.mjs → command-BvmUAPPQ.mjs} +15 -4
  13. package/dist/command-BvmUAPPQ.mjs.map +1 -0
  14. package/dist/{command-Cmmf0oHX.d.mts → command-CPhFHjG3.d.mts} +3 -2
  15. package/dist/command-CPhFHjG3.d.mts.map +1 -0
  16. package/dist/command-not-found.error-ONAZ2Bpk.mjs +14 -0
  17. package/dist/command-not-found.error-ONAZ2Bpk.mjs.map +1 -0
  18. package/dist/config/index.d.mts +24 -11
  19. package/dist/config/index.d.mts.map +1 -1
  20. package/dist/config/index.mjs +32 -57
  21. package/dist/config/index.mjs.map +1 -1
  22. package/dist/{consumer-registry-B7yUNh0q.d.mts → consumer-registry-D3iMTSdy.d.mts} +54 -22
  23. package/dist/consumer-registry-D3iMTSdy.d.mts.map +1 -0
  24. package/dist/container-storage-BmOJ4_Na.mjs +52 -0
  25. package/dist/container-storage-BmOJ4_Na.mjs.map +1 -0
  26. package/dist/{controller.decorator-B9vwn0zK.mjs → controller.decorator-C5UVeJS3.mjs} +8 -8
  27. package/dist/controller.decorator-C5UVeJS3.mjs.map +1 -0
  28. package/dist/cron/index.d.mts +103 -7
  29. package/dist/cron/index.d.mts.map +1 -1
  30. package/dist/cron/index.mjs +2 -2
  31. package/dist/cron-job-NesZRk8F.d.mts +58 -0
  32. package/dist/cron-job-NesZRk8F.d.mts.map +1 -0
  33. package/dist/{cron-manager-DQSK8uoV.mjs → cron.module-Bgzq5hiT.mjs} +47 -17
  34. package/dist/cron.module-Bgzq5hiT.mjs.map +1 -0
  35. package/dist/decorate-CuAoSZvs.mjs +16 -0
  36. package/dist/deep-merge-ByiAOZ3r.mjs +18 -0
  37. package/dist/deep-merge-ByiAOZ3r.mjs.map +1 -0
  38. package/dist/di/index.d.mts +2 -2
  39. package/dist/di/index.mjs +4 -3
  40. package/dist/di-DseMn-z9.mjs +524 -0
  41. package/dist/di-DseMn-z9.mjs.map +1 -0
  42. package/dist/email/index.d.mts +40 -122
  43. package/dist/email/index.d.mts.map +1 -1
  44. package/dist/email/index.mjs +446 -131
  45. package/dist/email/index.mjs.map +1 -1
  46. package/dist/en-CDZBMcc1.mjs +202 -0
  47. package/dist/en-CDZBMcc1.mjs.map +1 -0
  48. package/dist/{env-D1rcZ8_r.d.mts → env-ug22bJj7.d.mts} +1 -1
  49. package/dist/env-ug22bJj7.d.mts.map +1 -0
  50. package/dist/errors/index.d.mts +2 -2
  51. package/dist/errors/index.mjs +4 -2
  52. package/dist/errors-mXYxG0XB.mjs +333 -0
  53. package/dist/errors-mXYxG0XB.mjs.map +1 -0
  54. package/dist/events/index.d.mts +14 -3
  55. package/dist/events/index.d.mts.map +1 -1
  56. package/dist/events/index.mjs +2 -2
  57. package/dist/{events-CzCV8jI8.mjs → events-BXJGZjpG.mjs} +23 -13
  58. package/dist/events-BXJGZjpG.mjs.map +1 -0
  59. package/dist/exception-context-kEoMFwze.mjs +429 -0
  60. package/dist/exception-context-kEoMFwze.mjs.map +1 -0
  61. package/dist/{gateway-context-CXmXtaUP.mjs → gateway-context-TMu_AlJt.mjs} +38 -31
  62. package/dist/gateway-context-TMu_AlJt.mjs.map +1 -0
  63. package/dist/guards/index.d.mts +3 -3
  64. package/dist/guards/index.d.mts.map +1 -1
  65. package/dist/guards/index.mjs +1 -1
  66. package/dist/{guards-DU1_J9YA.mjs → guards-DALPXy3_.mjs} +6 -5
  67. package/dist/guards-DALPXy3_.mjs.map +1 -0
  68. package/dist/hono-app-CvV3hOfT.mjs +161 -0
  69. package/dist/hono-app-CvV3hOfT.mjs.map +1 -0
  70. package/dist/{http-method.decorator-BrgHMdLQ.mjs → http-method.decorator-ByWZb9DO.mjs} +7 -6
  71. package/dist/http-method.decorator-ByWZb9DO.mjs.map +1 -0
  72. package/dist/i18n/index.d.mts +238 -3
  73. package/dist/i18n/index.d.mts.map +1 -0
  74. package/dist/i18n/index.mjs +39 -3
  75. package/dist/i18n/index.mjs.map +1 -0
  76. package/dist/i18n/messages/en/index.d.mts +2 -2
  77. package/dist/i18n/messages/en/index.mjs +2 -2
  78. package/dist/i18n/utils/index.d.mts +4 -26
  79. package/dist/i18n/utils/index.d.mts.map +1 -1
  80. package/dist/i18n/utils/index.mjs +2 -2
  81. package/dist/i18n/validation/index.d.mts +3 -2
  82. package/dist/i18n/validation/index.mjs +4 -2
  83. package/dist/i18n.module-DRQAZoSZ.mjs +222 -0
  84. package/dist/i18n.module-DRQAZoSZ.mjs.map +1 -0
  85. package/dist/i18n.tokens-CZ_v8oyS.mjs +19 -0
  86. package/dist/i18n.tokens-CZ_v8oyS.mjs.map +1 -0
  87. package/dist/{index-7-hU3GTV.d.mts → index-0ItCjaqw.d.mts} +1 -1
  88. package/dist/index-0ItCjaqw.d.mts.map +1 -0
  89. package/dist/index-B5JBRcWD.d.mts +544 -0
  90. package/dist/index-B5JBRcWD.d.mts.map +1 -0
  91. package/dist/index-BUt92sAE.d.mts +124 -0
  92. package/dist/index-BUt92sAE.d.mts.map +1 -0
  93. package/dist/{index-ByOyTmqf.d.mts → index-B_JoEl3V.d.mts} +751 -2229
  94. package/dist/index-B_JoEl3V.d.mts.map +1 -0
  95. package/dist/index-DtBNIFuP.d.mts +42 -0
  96. package/dist/index-DtBNIFuP.d.mts.map +1 -0
  97. package/dist/{index-C1KvMncZ.d.mts → index-HgOLNruQ.d.mts} +3 -108
  98. package/dist/index-HgOLNruQ.d.mts.map +1 -0
  99. package/dist/index.d.mts +6 -43
  100. package/dist/index.mjs +3 -2
  101. package/dist/{is-command-C6a7WTPw.mjs → is-command-CEPO9n8c.mjs} +2 -2
  102. package/dist/{is-command-C6a7WTPw.mjs.map → is-command-CEPO9n8c.mjs.map} +1 -1
  103. package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-Gvh_AM71.mjs} +1 -1
  104. package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-Gvh_AM71.mjs.map} +1 -1
  105. package/dist/lazy-module-loader-Ib383jH_.d.mts +60 -0
  106. package/dist/lazy-module-loader-Ib383jH_.d.mts.map +1 -0
  107. package/dist/locale-path.service-D-dHiIPc.mjs +165 -0
  108. package/dist/locale-path.service-D-dHiIPc.mjs.map +1 -0
  109. package/dist/locale-url-nZrZxqJP.mjs +44 -0
  110. package/dist/locale-url-nZrZxqJP.mjs.map +1 -0
  111. package/dist/locale-url.service-C2EWmGdq.mjs +41 -0
  112. package/dist/locale-url.service-C2EWmGdq.mjs.map +1 -0
  113. package/dist/logger/index.d.mts +2 -2
  114. package/dist/logger/index.mjs +170 -2
  115. package/dist/logger/index.mjs.map +1 -0
  116. package/dist/macroable/index.d.mts +2 -2
  117. package/dist/macroable/index.mjs +1 -1
  118. package/dist/{macroable-BmufBshB.mjs → macroable-cvDTFZ_A.mjs} +1 -1
  119. package/dist/{macroable-BmufBshB.mjs.map → macroable-cvDTFZ_A.mjs.map} +1 -1
  120. package/dist/metadata-DzzprcID.mjs +39 -0
  121. package/dist/metadata-DzzprcID.mjs.map +1 -0
  122. package/dist/module/index.d.mts +7 -24
  123. package/dist/module/index.d.mts.map +1 -1
  124. package/dist/module/index.mjs +10 -2
  125. package/dist/module/index.mjs.map +1 -0
  126. package/dist/module-registry-Dm-pqHd3.mjs +554 -0
  127. package/dist/module-registry-Dm-pqHd3.mjs.map +1 -0
  128. package/dist/module.decorator-CYHY6pG5.mjs +19 -0
  129. package/dist/module.decorator-CYHY6pG5.mjs.map +1 -0
  130. package/dist/openapi/index.d.mts +44 -8
  131. package/dist/openapi/index.d.mts.map +1 -1
  132. package/dist/openapi/index.mjs +3 -3
  133. package/dist/openapi-CstuTM8S.mjs +309 -0
  134. package/dist/openapi-CstuTM8S.mjs.map +1 -0
  135. package/dist/{openapi-tools.service-Zs-Ewv7F.mjs → openapi-tools.service-BC5EC3R3.mjs} +8 -2
  136. package/dist/openapi-tools.service-BC5EC3R3.mjs.map +1 -0
  137. package/dist/{openapi.service-Bt9bCIrd.d.mts → openapi.service-YhTiJ1bO.d.mts} +3 -3
  138. package/dist/openapi.service-YhTiJ1bO.d.mts.map +1 -0
  139. package/dist/quarry/index.d.mts +14 -163
  140. package/dist/quarry/index.d.mts.map +1 -1
  141. package/dist/quarry/index.mjs +6 -5
  142. package/dist/quarry/runner.d.mts +184 -0
  143. package/dist/quarry/runner.d.mts.map +1 -0
  144. package/dist/quarry/runner.mjs +945 -0
  145. package/dist/quarry/runner.mjs.map +1 -0
  146. package/dist/quarry-registry-CXg0RFXq.d.mts +69 -0
  147. package/dist/quarry-registry-CXg0RFXq.d.mts.map +1 -0
  148. package/dist/quarry.module-BuRPGMDm.mjs +312 -0
  149. package/dist/quarry.module-BuRPGMDm.mjs.map +1 -0
  150. package/dist/queue/index.d.mts +3 -3
  151. package/dist/queue/index.mjs +57 -48
  152. package/dist/queue/index.mjs.map +1 -1
  153. package/dist/queue.module-nddvxzCB.mjs +613 -0
  154. package/dist/queue.module-nddvxzCB.mjs.map +1 -0
  155. package/dist/queue.tokens-DjHnFmre.mjs +11 -0
  156. package/dist/queue.tokens-DjHnFmre.mjs.map +1 -0
  157. package/dist/{r2-storage.provider-DuonKeYm.mjs → r2-storage.provider-DCxQt9dD.mjs} +6 -6
  158. package/dist/r2-storage.provider-DCxQt9dD.mjs.map +1 -0
  159. package/dist/{rate-limit.decorator-6qzNcSOt.mjs → rate-limit.decorator-BPAie_p3.mjs} +6 -11
  160. package/dist/rate-limit.decorator-BPAie_p3.mjs.map +1 -0
  161. package/dist/rate-limiter/index.d.mts +11 -50
  162. package/dist/rate-limiter/index.d.mts.map +1 -1
  163. package/dist/rate-limiter/index.mjs +33 -42
  164. package/dist/rate-limiter/index.mjs.map +1 -1
  165. package/dist/route-name-DGoBOfPg.mjs +171 -0
  166. package/dist/route-name-DGoBOfPg.mjs.map +1 -0
  167. package/dist/route-registration.service-D6vSwiKP.mjs +918 -0
  168. package/dist/route-registration.service-D6vSwiKP.mjs.map +1 -0
  169. package/dist/route-registry-CYqLp2Nj.mjs +123 -0
  170. package/dist/route-registry-CYqLp2Nj.mjs.map +1 -0
  171. package/dist/router/index.d.mts +2 -2
  172. package/dist/router/index.mjs +18 -7
  173. package/dist/router-CWGBD-Bg.mjs +78 -0
  174. package/dist/router-CWGBD-Bg.mjs.map +1 -0
  175. package/dist/router-resolver-D4YlPNlm.mjs +88 -0
  176. package/dist/router-resolver-D4YlPNlm.mjs.map +1 -0
  177. package/dist/seeder/index.d.mts +16 -11
  178. package/dist/seeder/index.d.mts.map +1 -1
  179. package/dist/seeder/index.mjs +5 -3
  180. package/dist/seeder-7ubkms-Y.mjs +81 -0
  181. package/dist/seeder-7ubkms-Y.mjs.map +1 -0
  182. package/dist/seeder-registry-CyUmKsJq.mjs +57 -0
  183. package/dist/seeder-registry-CyUmKsJq.mjs.map +1 -0
  184. package/dist/seeder.module-CYYwk3Qk.mjs +15 -0
  185. package/dist/seeder.module-CYYwk3Qk.mjs.map +1 -0
  186. package/dist/{signed-url-BQPbv2In.mjs → signed-url-DIU0sK_6.mjs} +1 -1
  187. package/dist/{signed-url-BQPbv2In.mjs.map → signed-url-DIU0sK_6.mjs.map} +1 -1
  188. package/dist/storage/index.d.mts +15 -39
  189. package/dist/storage/index.d.mts.map +1 -1
  190. package/dist/storage/index.mjs +3 -3
  191. package/dist/storage/providers/index.d.mts +2 -2
  192. package/dist/storage/providers/index.d.mts.map +1 -1
  193. package/dist/storage/providers/index.mjs +1 -1
  194. package/dist/{storage-D8CBP72Z.mjs → storage-MDZypIE9.mjs} +66 -59
  195. package/dist/storage-MDZypIE9.mjs.map +1 -0
  196. package/dist/{storage-provider.interface-Bd6vA4ak.d.mts → storage-provider.interface-ClUwxz4S.d.mts} +2 -3
  197. package/dist/storage-provider.interface-ClUwxz4S.d.mts.map +1 -0
  198. package/dist/storage.error-Dnib4VHc.mjs +8 -0
  199. package/dist/storage.error-Dnib4VHc.mjs.map +1 -0
  200. package/dist/stratal-DL9M38_s.mjs +383 -0
  201. package/dist/stratal-DL9M38_s.mjs.map +1 -0
  202. package/dist/stratal-DwDJPY9N.d.mts +43 -0
  203. package/dist/stratal-DwDJPY9N.d.mts.map +1 -0
  204. package/dist/tiered-cache.service-Dv3BhxxE.d.mts +79 -0
  205. package/dist/tiered-cache.service-Dv3BhxxE.d.mts.map +1 -0
  206. package/dist/trailing-slash-CFyw8nYu.mjs +34 -0
  207. package/dist/trailing-slash-CFyw8nYu.mjs.map +1 -0
  208. package/dist/{types-cySNS_lp.d.mts → types-CmV_9xBD.d.mts} +1 -1
  209. package/dist/types-CmV_9xBD.d.mts.map +1 -0
  210. package/dist/uri-h7Q8Jug9.mjs +251 -0
  211. package/dist/uri-h7Q8Jug9.mjs.map +1 -0
  212. package/dist/{usage-generator-BUdlhnCK.mjs → usage-generator-DAWYasuP.mjs} +7 -4
  213. package/dist/usage-generator-DAWYasuP.mjs.map +1 -0
  214. package/dist/validation-CpOjviyT.mjs +49 -0
  215. package/dist/validation-CpOjviyT.mjs.map +1 -0
  216. package/dist/validation.context-CRvmrhq7.mjs +117 -0
  217. package/dist/validation.context-CRvmrhq7.mjs.map +1 -0
  218. package/dist/versioning.service-C6aHky8-.mjs +36 -0
  219. package/dist/versioning.service-C6aHky8-.mjs.map +1 -0
  220. package/dist/websocket/index.d.mts +16 -14
  221. package/dist/websocket/index.d.mts.map +1 -1
  222. package/dist/websocket/index.mjs +2 -2
  223. package/dist/workers/index.d.mts +2 -2
  224. package/dist/workers/index.d.mts.map +1 -1
  225. package/dist/workers/index.mjs +3 -2
  226. package/dist/workers/index.mjs.map +1 -1
  227. package/dist/zod-eKqqhZ5_.mjs +72 -0
  228. package/dist/zod-eKqqhZ5_.mjs.map +1 -0
  229. package/dist/{index-Bnpfq6uk.d.mts → zod-wecrEVAs.d.mts} +63 -133
  230. package/dist/zod-wecrEVAs.d.mts.map +1 -0
  231. package/package.json +28 -39
  232. package/dist/base-email.provider-CfQCA08m.mjs +0 -42
  233. package/dist/base-email.provider-CfQCA08m.mjs.map +0 -1
  234. package/dist/cache.service-DsnKuNyO.d.mts.map +0 -1
  235. package/dist/cache.tokens-B7Rw1C9Q.mjs +0 -6
  236. package/dist/cache.tokens-B7Rw1C9Q.mjs.map +0 -1
  237. package/dist/colors-DJaRDXoS.mjs +0 -16
  238. package/dist/colors-DJaRDXoS.mjs.map +0 -1
  239. package/dist/command-BgSlsS4M.mjs.map +0 -1
  240. package/dist/command-Cmmf0oHX.d.mts.map +0 -1
  241. package/dist/consumer-registry-B7yUNh0q.d.mts.map +0 -1
  242. package/dist/controller.decorator-B9vwn0zK.mjs.map +0 -1
  243. package/dist/cron-manager-CmTimEjf.d.mts +0 -131
  244. package/dist/cron-manager-CmTimEjf.d.mts.map +0 -1
  245. package/dist/cron-manager-DQSK8uoV.mjs.map +0 -1
  246. package/dist/en-DSH_bhh6.mjs +0 -308
  247. package/dist/en-DSH_bhh6.mjs.map +0 -1
  248. package/dist/env-D1rcZ8_r.d.mts.map +0 -1
  249. package/dist/errors-COW9-Mar.mjs +0 -1739
  250. package/dist/errors-COW9-Mar.mjs.map +0 -1
  251. package/dist/errors-ORxu1-Bb.mjs +0 -74
  252. package/dist/errors-ORxu1-Bb.mjs.map +0 -1
  253. package/dist/events-CzCV8jI8.mjs.map +0 -1
  254. package/dist/gateway-context-CXmXtaUP.mjs.map +0 -1
  255. package/dist/guards-DU1_J9YA.mjs.map +0 -1
  256. package/dist/http-method.decorator-BrgHMdLQ.mjs.map +0 -1
  257. package/dist/i18n.module-CzXLW9Hy.mjs +0 -2532
  258. package/dist/i18n.module-CzXLW9Hy.mjs.map +0 -1
  259. package/dist/index-7-hU3GTV.d.mts.map +0 -1
  260. package/dist/index-Bnpfq6uk.d.mts.map +0 -1
  261. package/dist/index-ByOyTmqf.d.mts.map +0 -1
  262. package/dist/index-C1KvMncZ.d.mts.map +0 -1
  263. package/dist/index-DBd_2wv8.d.mts +0 -263
  264. package/dist/index-DBd_2wv8.d.mts.map +0 -1
  265. package/dist/index-DUzWs0z7.d.mts +0 -494
  266. package/dist/index-DUzWs0z7.d.mts.map +0 -1
  267. package/dist/index.d.mts.map +0 -1
  268. package/dist/logger-DlV7NtvD.mjs +0 -440
  269. package/dist/logger-DlV7NtvD.mjs.map +0 -1
  270. package/dist/module-BzLg57FK.mjs +0 -866
  271. package/dist/module-BzLg57FK.mjs.map +0 -1
  272. package/dist/openapi-tools.service-Zs-Ewv7F.mjs.map +0 -1
  273. package/dist/openapi.service-Bt9bCIrd.d.mts.map +0 -1
  274. package/dist/quarry-registry-BwY2hOxm.mjs +0 -699
  275. package/dist/quarry-registry-BwY2hOxm.mjs.map +0 -1
  276. package/dist/queue.module-BhCjZp6H.mjs +0 -409
  277. package/dist/queue.module-BhCjZp6H.mjs.map +0 -1
  278. package/dist/r2-storage.provider-DuonKeYm.mjs.map +0 -1
  279. package/dist/rate-limit.decorator-6qzNcSOt.mjs.map +0 -1
  280. package/dist/resend.provider-DB4IlFjG.mjs +0 -68
  281. package/dist/resend.provider-DB4IlFjG.mjs.map +0 -1
  282. package/dist/seeder-zoEfEw9i.mjs +0 -138
  283. package/dist/seeder-zoEfEw9i.mjs.map +0 -1
  284. package/dist/setup-CefZKV_e.mjs +0 -37
  285. package/dist/setup-CefZKV_e.mjs.map +0 -1
  286. package/dist/smtp.provider-B6D7zuWX.mjs +0 -76
  287. package/dist/smtp.provider-B6D7zuWX.mjs.map +0 -1
  288. package/dist/storage-D8CBP72Z.mjs.map +0 -1
  289. package/dist/storage-provider.interface-Bd6vA4ak.d.mts.map +0 -1
  290. package/dist/stratal-CNwpbSZl.mjs +0 -535
  291. package/dist/stratal-CNwpbSZl.mjs.map +0 -1
  292. package/dist/types-cySNS_lp.d.mts.map +0 -1
  293. package/dist/usage-generator-BUdlhnCK.mjs.map +0 -1
  294. package/dist/validation-DtJwAv7O.mjs +0 -248
  295. package/dist/validation-DtJwAv7O.mjs.map +0 -1
  296. /package/dist/{chunk-D1SwGrFN.mjs → chunk-BBjsoOtd.mjs} +0 -0
@@ -1,6 +1,10 @@
1
- import { d as ApplicationError } from "../index-ByOyTmqf.mjs";
2
- import { t as CacheService } from "../cache.service-DsnKuNyO.mjs";
1
+ import { Dr as ApplicationError } from "../index-B_JoEl3V.mjs";
2
+ import { t as CacheService } from "../cache.service-uElmBtdS.mjs";
3
+ import { t as TieredCacheService } from "../tiered-cache.service-Dv3BhxxE.mjs";
3
4
 
5
+ //#region src/cache/cache.error.d.ts
6
+ declare class CacheError extends ApplicationError {}
7
+ //#endregion
4
8
  //#region src/cache/cache.module.d.ts
5
9
  /**
6
10
  * Cache Module
@@ -18,51 +22,9 @@ declare class CacheModule {}
18
22
  //#region src/cache/cache.tokens.d.ts
19
23
  declare const CACHE_TOKENS: {
20
24
  readonly CacheService: symbol;
25
+ readonly TieredCacheService: symbol;
21
26
  };
22
27
  type CacheToken = (typeof CACHE_TOKENS)[keyof typeof CACHE_TOKENS];
23
28
  //#endregion
24
- //#region src/cache/errors/cache-get.error.d.ts
25
- /**
26
- * Error thrown when a cache get operation fails
27
- *
28
- * Raw error details are logged via LoggerService for security.
29
- * Only the key is included in the user-facing error message.
30
- */
31
- declare class CacheGetError extends ApplicationError {
32
- constructor(key: string);
33
- }
34
- //#endregion
35
- //#region src/cache/errors/cache-put.error.d.ts
36
- /**
37
- * Error thrown when a cache put operation fails
38
- *
39
- * Raw error details are logged via LoggerService for security.
40
- * Only the key is included in the user-facing error message.
41
- */
42
- declare class CachePutError extends ApplicationError {
43
- constructor(key: string);
44
- }
45
- //#endregion
46
- //#region src/cache/errors/cache-delete.error.d.ts
47
- /**
48
- * Error thrown when a cache delete operation fails
49
- *
50
- * Raw error details are logged via LoggerService for security.
51
- * Only the key is included in the user-facing error message.
52
- */
53
- declare class CacheDeleteError extends ApplicationError {
54
- constructor(key: string);
55
- }
56
- //#endregion
57
- //#region src/cache/errors/cache-list.error.d.ts
58
- /**
59
- * Error thrown when a cache list operation fails
60
- *
61
- * Raw error details are logged via LoggerService for security.
62
- */
63
- declare class CacheListError extends ApplicationError {
64
- constructor();
65
- }
66
- //#endregion
67
- export { CACHE_TOKENS, CacheDeleteError, CacheGetError, CacheListError, CacheModule, CachePutError, CacheService, CacheToken };
29
+ export { CACHE_TOKENS, CacheError, CacheModule, CacheService, CacheToken, TieredCacheService };
68
30
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/cache/cache.module.ts","../../src/cache/cache.tokens.ts","../../src/cache/errors/cache-get.error.ts","../../src/cache/errors/cache-put.error.ts","../../src/cache/errors/cache-delete.error.ts","../../src/cache/errors/cache-list.error.ts"],"mappings":";;;;;;;;AAgBA;;;;;;;cAMa,WAAA;;;cCtBA,YAAA;EAAA,SAEH,YAAA;AAAA;AAAA,KAEE,UAAA,WAAqB,YAAA,eAA2B,YAAA;;;;;;ADY5D;;;cEPa,aAAA,SAAsB,gBAAA;cACrB,GAAA;AAAA;;;;;;AFMd;;;cGPa,aAAA,SAAsB,gBAAA;cACrB,GAAA;AAAA;;;;;;AHMd;;;cIPa,gBAAA,SAAyB,gBAAA;cACxB,GAAA;AAAA;;;;;;AJMd;;cKRa,cAAA,SAAuB,gBAAA;EAAA,WAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/cache/cache.error.ts","../../src/cache/cache.module.ts","../../src/cache/cache.tokens.ts"],"mappings":";;;;;cAEa,UAAA,SAAmB,gBAAgB;;;;;;;;AAAhD;;;;AAAgD;;cCsBnC,WAAA;;;cCxBA,YAAA;EAAA,SAGH,YAAA;EAAA,SAAA,kBAAA;AAAA;AAAA,KAEE,UAAA,WAAqB,YAAA,eAA2B,YAAY"}
@@ -1,57 +1,17 @@
1
- import { H as ApplicationError, k as ERROR_CODES } from "../errors-COW9-Mar.mjs";
2
- import { a as __decorate, f as DI_TOKENS, o as __decorateParam, p as Transient, s as __decorateMetadata, u as LOGGER_TOKENS } from "../logger-DlV7NtvD.mjs";
3
- import { k as Module } from "../module-BzLg57FK.mjs";
4
- import { t as CACHE_TOKENS } from "../cache.tokens-B7Rw1C9Q.mjs";
5
- import { inject } from "tsyringe";
6
- //#region src/cache/errors/cache-get.error.ts
7
- /**
8
- * Error thrown when a cache get operation fails
9
- *
10
- * Raw error details are logged via LoggerService for security.
11
- * Only the key is included in the user-facing error message.
12
- */
13
- var CacheGetError = class extends ApplicationError {
14
- constructor(key) {
15
- super("errors.cache.getFailed", ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key });
16
- }
17
- };
18
- //#endregion
19
- //#region src/cache/errors/cache-put.error.ts
20
- /**
21
- * Error thrown when a cache put operation fails
22
- *
23
- * Raw error details are logged via LoggerService for security.
24
- * Only the key is included in the user-facing error message.
25
- */
26
- var CachePutError = class extends ApplicationError {
27
- constructor(key) {
28
- super("errors.cache.putFailed", ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key });
29
- }
30
- };
31
- //#endregion
32
- //#region src/cache/errors/cache-delete.error.ts
33
- /**
34
- * Error thrown when a cache delete operation fails
35
- *
36
- * Raw error details are logged via LoggerService for security.
37
- * Only the key is included in the user-facing error message.
38
- */
39
- var CacheDeleteError = class extends ApplicationError {
40
- constructor(key) {
41
- super("errors.cache.deleteFailed", ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key });
42
- }
43
- };
1
+ import { d as inject, r as DI_TOKENS, s as Singleton } from "../di-DseMn-z9.mjs";
2
+ import { a as ApplicationError } from "../container-storage-BmOJ4_Na.mjs";
3
+ import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
4
+ import { LOGGER_TOKENS } from "../logger/index.mjs";
5
+ import "../errors-mXYxG0XB.mjs";
6
+ import { n as Module } from "../module.decorator-CYHY6pG5.mjs";
7
+ import "../module/index.mjs";
8
+ //#region src/cache/cache.error.ts
9
+ var CacheError = class extends ApplicationError {};
44
10
  //#endregion
45
- //#region src/cache/errors/cache-list.error.ts
46
- /**
47
- * Error thrown when a cache list operation fails
48
- *
49
- * Raw error details are logged via LoggerService for security.
50
- */
51
- var CacheListError = class extends ApplicationError {
52
- constructor() {
53
- super("errors.cache.listFailed", ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, {});
54
- }
11
+ //#region src/cache/cache.tokens.ts
12
+ const CACHE_TOKENS = {
13
+ CacheService: Symbol.for("stratal:cache:service"),
14
+ TieredCacheService: Symbol.for("stratal:cache:tiered-service")
55
15
  };
56
16
  //#endregion
57
17
  //#region src/cache/services/cache.service.ts
@@ -65,47 +25,34 @@ let CacheService = _CacheService = class CacheService {
65
25
  this.logger = logger;
66
26
  this.kv = env.CACHE;
67
27
  }
68
- /**
69
- * Set the KV namespace binding
70
- *
71
- * Used internally by `withBinding()` to configure different KV instances.
72
- *
73
- * @param kv - KV namespace to use
74
- */
75
- setKV(kv) {
76
- this.kv = kv;
28
+ /** The KV namespace this instance is bound to. */
29
+ get namespace() {
30
+ return this.kv;
77
31
  }
78
32
  /**
79
- * Create a new CacheService instance with a different KV binding
80
- *
81
- * **Pattern:** Returns a new instance (immutable)
82
- *
83
- * **Best Practice:** Initialize specialized caches as class properties in constructor
84
- *
85
- * @example
86
- * ```typescript
87
- * class MyService {
88
- * private readonly uploadsCache: CacheService
89
- * private readonly systemCache: CacheService
90
- *
91
- * constructor(
92
- * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,
93
- * @inject(DI_TOKENS.CloudflareEnv) private readonly env: Env
94
- * ) {
95
- * this.uploadsCache = this.cache.withBinding(this.env.UPLOADS_CACHE)
96
- * this.systemCache = this.cache.withBinding(this.env.SYSTEM_CONFIG_KV)
97
- * }
98
- * }
99
- * ```
33
+ * Create a new CacheService instance bound to a different KV namespace.
100
34
  *
101
35
  * @param kv - KV namespace to use
102
- * @returns New CacheService instance with the specified binding
36
+ * @returns A new CacheService for the given binding
103
37
  */
104
38
  withBinding(kv) {
105
39
  const instance = new _CacheService(this.env, this.logger);
106
- instance.setKV(kv);
40
+ instance.kv = kv;
107
41
  return instance;
108
42
  }
43
+ /**
44
+ * Create a new CacheService instance bound to a KV namespace by its binding
45
+ * name, resolved from the environment.
46
+ *
47
+ * @param name - KV namespace binding name (e.g. `'UPLOADS_CACHE'`)
48
+ * @returns A new CacheService for the given binding
49
+ * @throws {CacheError} If no binding with that name exists in the environment
50
+ */
51
+ binding(name) {
52
+ const kv = this.env[name];
53
+ if (!kv) throw new CacheError(`KV binding "${name}" was not found in the environment`);
54
+ return this.withBinding(kv);
55
+ }
109
56
  async get(key, typeOrOptions) {
110
57
  try {
111
58
  if (typeof typeOrOptions === "string") return await this.kv.get(key, typeOrOptions);
@@ -116,7 +63,7 @@ let CacheService = _CacheService = class CacheService {
116
63
  key,
117
64
  error
118
65
  });
119
- throw new CacheGetError(key);
66
+ throw new CacheError(`Failed to get cache key "${key}"`);
120
67
  }
121
68
  }
122
69
  async getWithMetadata(key, typeOrOptions) {
@@ -129,7 +76,7 @@ let CacheService = _CacheService = class CacheService {
129
76
  key,
130
77
  error
131
78
  });
132
- throw new CacheGetError(key);
79
+ throw new CacheError(`Failed to get cache key "${key}"`);
133
80
  }
134
81
  }
135
82
  /**
@@ -138,7 +85,7 @@ let CacheService = _CacheService = class CacheService {
138
85
  * @param key - Cache key
139
86
  * @param value - Value to store (string, ArrayBuffer, ArrayBufferView, or ReadableStream)
140
87
  * @param options - Put options (expiration, expirationTtl, metadata)
141
- * @throws {CachePutError} If operation fails
88
+ * @throws {CacheError} If operation fails
142
89
  *
143
90
  * @example
144
91
  * ```typescript
@@ -160,14 +107,14 @@ let CacheService = _CacheService = class CacheService {
160
107
  key,
161
108
  error
162
109
  });
163
- throw new CachePutError(key);
110
+ throw new CacheError(`Failed to store cache key "${key}"`);
164
111
  }
165
112
  }
166
113
  /**
167
114
  * Delete a value from cache
168
115
  *
169
116
  * @param key - Cache key to delete
170
- * @throws {CacheDeleteError} If operation fails
117
+ * @throws {CacheError} If operation fails
171
118
  */
172
119
  async delete(key) {
173
120
  try {
@@ -177,7 +124,7 @@ let CacheService = _CacheService = class CacheService {
177
124
  key,
178
125
  error
179
126
  });
180
- throw new CacheDeleteError(key);
127
+ throw new CacheError(`Failed to delete cache key "${key}"`);
181
128
  }
182
129
  }
183
130
  /**
@@ -185,7 +132,7 @@ let CacheService = _CacheService = class CacheService {
185
132
  *
186
133
  * @param options - List options (limit, prefix, cursor)
187
134
  * @returns List result with keys and pagination info
188
- * @throws {CacheListError} If operation fails
135
+ * @throws {CacheError} If operation fails
189
136
  *
190
137
  * @example
191
138
  * ```typescript
@@ -210,17 +157,104 @@ let CacheService = _CacheService = class CacheService {
210
157
  options,
211
158
  error
212
159
  });
213
- throw new CacheListError();
160
+ throw new CacheError("Failed to list cache keys");
214
161
  }
215
162
  }
216
163
  };
217
164
  CacheService = _CacheService = __decorate([
218
- Transient(CACHE_TOKENS.CacheService),
165
+ Singleton(CACHE_TOKENS.CacheService),
219
166
  __decorateParam(0, inject(DI_TOKENS.CloudflareEnv)),
220
- __decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
221
- __decorateMetadata("design:paramtypes", [Object, Object])
167
+ __decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
222
168
  ], CacheService);
223
169
  //#endregion
170
+ //#region src/cache/services/tiered-cache.service.ts
171
+ var _TieredCacheService;
172
+ /**
173
+ * Max entries kept in the isolate-local L1 before the oldest is evicted (FIFO).
174
+ * Bounds memory per isolate; KV remains the unbounded source of truth.
175
+ */
176
+ const L1_MAX_ENTRIES = 1e3;
177
+ let TieredCacheService = _TieredCacheService = class TieredCacheService {
178
+ cache;
179
+ /** Isolate-local L1 tier. Per-instance, so each binding has its own. */
180
+ l1 = /* @__PURE__ */ new Map();
181
+ /** Memoized tiered instances per binding name (each with its own L1). */
182
+ children = /* @__PURE__ */ new Map();
183
+ constructor(cache) {
184
+ this.cache = cache;
185
+ }
186
+ /**
187
+ * Get the tiered cache bound to a KV namespace by its binding name. Memoized:
188
+ * repeated calls with the same name return the same instance, preserving its
189
+ * isolate-local L1 across requests/messages.
190
+ *
191
+ * @param name - KV namespace binding name (e.g. `'UPLOADS_CACHE'`)
192
+ * @throws {CacheError} If no binding with that name exists in the environment
193
+ */
194
+ binding(name) {
195
+ let child = this.children.get(name);
196
+ if (child === void 0) {
197
+ child = new _TieredCacheService(this.cache.binding(name));
198
+ this.children.set(name, child);
199
+ }
200
+ return child;
201
+ }
202
+ async get(key, typeOrOptions) {
203
+ const type = typeof typeOrOptions === "string" ? typeOrOptions : typeOrOptions?.type ?? "text";
204
+ if (type === "text" || type === "json") {
205
+ const cached = this.l1Read(key);
206
+ if (cached !== null) return type === "json" ? JSON.parse(cached) : cached;
207
+ }
208
+ const value = await this.cache.get(key, typeOrOptions);
209
+ if (type === "text" && typeof value === "string") this.l1Write(key, value, null);
210
+ return value;
211
+ }
212
+ async getWithMetadata(key, typeOrOptions) {
213
+ return this.cache.getWithMetadata(key, typeOrOptions);
214
+ }
215
+ async put(key, value, options) {
216
+ await this.cache.put(key, value, options);
217
+ if (typeof value === "string") this.l1Write(key, value, this.l1ExpiresAt(options));
218
+ else this.l1.delete(key);
219
+ }
220
+ async delete(key) {
221
+ await this.cache.delete(key);
222
+ this.l1.delete(key);
223
+ }
224
+ async list(options) {
225
+ return this.cache.list(options);
226
+ }
227
+ /** Read a fresh L1 entry, evicting it if expired. Returns `null` on miss. */
228
+ l1Read(key) {
229
+ const entry = this.l1.get(key);
230
+ if (entry === void 0) return null;
231
+ if (entry.expiresAt !== null && Date.now() >= entry.expiresAt) {
232
+ this.l1.delete(key);
233
+ return null;
234
+ }
235
+ return entry.value;
236
+ }
237
+ /** Write an L1 entry, refreshing its recency and evicting the oldest at cap. */
238
+ l1Write(key, value, expiresAt) {
239
+ this.l1.delete(key);
240
+ if (this.l1.size >= L1_MAX_ENTRIES) {
241
+ const oldest = this.l1.keys().next().value;
242
+ if (oldest !== void 0) this.l1.delete(oldest);
243
+ }
244
+ this.l1.set(key, {
245
+ value,
246
+ expiresAt
247
+ });
248
+ }
249
+ /** Compute an absolute L1 expiry (epoch ms) from KV put options. */
250
+ l1ExpiresAt(options) {
251
+ if (options?.expiration !== void 0) return options.expiration * 1e3;
252
+ if (options?.expirationTtl !== void 0) return Date.now() + options.expirationTtl * 1e3;
253
+ return null;
254
+ }
255
+ };
256
+ TieredCacheService = _TieredCacheService = __decorate([Singleton(CACHE_TOKENS.TieredCacheService), __decorateParam(0, inject(CACHE_TOKENS.CacheService))], TieredCacheService);
257
+ //#endregion
224
258
  //#region src/cache/cache.module.ts
225
259
  /**
226
260
  * Cache Module
@@ -237,8 +271,11 @@ let CacheModule = class CacheModule {};
237
271
  CacheModule = __decorate([Module({ providers: [{
238
272
  provide: CACHE_TOKENS.CacheService,
239
273
  useClass: CacheService
274
+ }, {
275
+ provide: CACHE_TOKENS.TieredCacheService,
276
+ useClass: TieredCacheService
240
277
  }] })], CacheModule);
241
278
  //#endregion
242
- export { CACHE_TOKENS, CacheDeleteError, CacheGetError, CacheListError, CacheModule, CachePutError, CacheService };
279
+ export { CACHE_TOKENS, CacheError, CacheModule, CacheService, TieredCacheService };
243
280
 
244
281
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cache/errors/cache-get.error.ts","../../src/cache/errors/cache-put.error.ts","../../src/cache/errors/cache-delete.error.ts","../../src/cache/errors/cache-list.error.ts","../../src/cache/services/cache.service.ts","../../src/cache/cache.module.ts"],"sourcesContent":["import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * Error thrown when a cache get operation fails\n *\n * Raw error details are logged via LoggerService for security.\n * Only the key is included in the user-facing error message.\n */\nexport class CacheGetError extends ApplicationError {\n constructor(key: string) {\n super('errors.cache.getFailed', ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key })\n }\n}\n","import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * Error thrown when a cache put operation fails\n *\n * Raw error details are logged via LoggerService for security.\n * Only the key is included in the user-facing error message.\n */\nexport class CachePutError extends ApplicationError {\n constructor(key: string) {\n super('errors.cache.putFailed', ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key })\n }\n}\n","import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * Error thrown when a cache delete operation fails\n *\n * Raw error details are logged via LoggerService for security.\n * Only the key is included in the user-facing error message.\n */\nexport class CacheDeleteError extends ApplicationError {\n constructor(key: string) {\n super('errors.cache.deleteFailed', ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, { key })\n }\n}\n","import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * Error thrown when a cache list operation fails\n *\n * Raw error details are logged via LoggerService for security.\n */\nexport class CacheListError extends ApplicationError {\n constructor() {\n super('errors.cache.listFailed', ERROR_CODES.SYSTEM.INFRASTRUCTURE_ERROR, {})\n }\n}\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { type StratalEnv } from '../../env'\nimport { LOGGER_TOKENS, type LoggerService } from '../../logger'\nimport { CACHE_TOKENS } from '../cache.tokens'\nimport {\n CacheDeleteError,\n CacheGetError,\n CacheListError,\n CachePutError,\n} from '../errors'\n\n/**\n * Cache Service\n *\n * Type-safe wrapper around Cloudflare KV namespaces for caching operations.\n *\n * **Features:**\n * - Mirrors all KVNamespace methods with full type safety\n * - Supports multiple KV bindings via `withBinding()`\n * - Automatic error handling with logging\n * - Security: Raw errors are logged, not exposed to users\n *\n * **Usage:**\n * ```typescript\n * class MyService {\n * private readonly uploadsCache: CacheService\n *\n * constructor(\n * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,\n * @inject(DI_TOKENS.CloudflareEnv) private readonly env: Env\n * ) {\n * // Initialize specialized caches in constructor\n * this.uploadsCache = this.cache.withBinding(this.env.UPLOADS_CACHE)\n * }\n *\n * async cacheData(key: string, value: string) {\n * await this.cache.put(key, value, { expirationTtl: 3600 })\n * await this.uploadsCache.put(`upload:${key}`, value)\n * }\n * }\n * ```\n *\n * @see https://developers.cloudflare.com/kv/api/\n */\n@Transient(CACHE_TOKENS.CacheService)\nexport class CacheService {\n private kv: KVNamespace\n\n constructor(\n @inject(DI_TOKENS.CloudflareEnv) private readonly env: StratalEnv,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService\n ) {\n this.kv = env.CACHE\n }\n\n /**\n * Set the KV namespace binding\n *\n * Used internally by `withBinding()` to configure different KV instances.\n *\n * @param kv - KV namespace to use\n */\n setKV(kv: KVNamespace): void {\n this.kv = kv\n }\n\n /**\n * Create a new CacheService instance with a different KV binding\n *\n * **Pattern:** Returns a new instance (immutable)\n *\n * **Best Practice:** Initialize specialized caches as class properties in constructor\n *\n * @example\n * ```typescript\n * class MyService {\n * private readonly uploadsCache: CacheService\n * private readonly systemCache: CacheService\n *\n * constructor(\n * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,\n * @inject(DI_TOKENS.CloudflareEnv) private readonly env: Env\n * ) {\n * this.uploadsCache = this.cache.withBinding(this.env.UPLOADS_CACHE)\n * this.systemCache = this.cache.withBinding(this.env.SYSTEM_CONFIG_KV)\n * }\n * }\n * ```\n *\n * @param kv - KV namespace to use\n * @returns New CacheService instance with the specified binding\n */\n withBinding(kv: KVNamespace): CacheService {\n const instance = new CacheService(this.env, this.logger)\n instance.setKV(kv)\n return instance\n }\n\n // ==================== GET METHODS ====================\n\n /**\n * Get a value from cache\n *\n * @param key - Cache key\n * @param typeOrOptions - Type string or options object (defaults to 'text')\n * @returns Value in specified type, or null if not found\n * @throws {CacheGetError} If operation fails\n */\n async get(key: string, typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>): Promise<string | null>\n async get<ExpectedValue = unknown>(key: string, typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>): Promise<ExpectedValue | null>\n async get(key: string, typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>): Promise<ArrayBuffer | null>\n async get(key: string, typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>): Promise<ReadableStream | null>\n\n async get<ExpectedValue = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<string | ExpectedValue | ArrayBuffer | ReadableStream | null> {\n try {\n if (typeof typeOrOptions === 'string') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.get(key, typeOrOptions as any)\n }\n\n if (typeOrOptions) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.get(key, typeOrOptions as any)\n }\n\n return await this.kv.get(key)\n } catch (error) {\n this.logger.error('Cache get operation failed', { key, error })\n throw new CacheGetError(key)\n }\n }\n\n // ==================== GET WITH METADATA METHODS ====================\n\n /**\n * Get a value with metadata from cache\n *\n * @param key - Cache key\n * @param typeOrOptions - Type string or options object (defaults to 'text')\n * @returns Object with value, metadata, and cacheStatus\n * @throws {CacheGetError} If operation fails\n */\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>\n ): Promise<KVNamespaceGetWithMetadataResult<string, Metadata>>\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>\n ): Promise<KVNamespaceGetWithMetadataResult<ExpectedValue, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>\n ): Promise<KVNamespaceGetWithMetadataResult<ArrayBuffer, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>\n ): Promise<KVNamespaceGetWithMetadataResult<ReadableStream, Metadata>>\n\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<\n KVNamespaceGetWithMetadataResult<\n string | ExpectedValue | ArrayBuffer | ReadableStream,\n Metadata\n >\n > {\n try {\n if (typeof typeOrOptions === 'string') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.getWithMetadata(key, typeOrOptions as any)\n }\n\n if (typeOrOptions) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.getWithMetadata(key, typeOrOptions as any)\n }\n\n return await this.kv.getWithMetadata(key)\n } catch (error) {\n this.logger.error('Cache getWithMetadata operation failed', { key, error })\n throw new CacheGetError(key)\n }\n }\n\n // ==================== PUT METHOD ====================\n\n /**\n * Store a value in cache\n *\n * @param key - Cache key\n * @param value - Value to store (string, ArrayBuffer, ArrayBufferView, or ReadableStream)\n * @param options - Put options (expiration, expirationTtl, metadata)\n * @throws {CachePutError} If operation fails\n *\n * @example\n * ```typescript\n * // Simple put\n * await cache.put('key', 'value')\n *\n * // With TTL\n * await cache.put('key', 'value', { expirationTtl: 3600 })\n *\n * // With metadata\n * await cache.put('key', 'value', { metadata: { created: Date.now() } })\n * ```\n */\n async put(\n key: string,\n value: string | ArrayBuffer | ArrayBufferView | ReadableStream,\n options?: KVNamespacePutOptions\n ): Promise<void> {\n try {\n await this.kv.put(key, value as string, options)\n } catch (error) {\n this.logger.error('Cache put operation failed', { key, error })\n throw new CachePutError(key)\n }\n }\n\n // ==================== DELETE METHODS ====================\n\n /**\n * Delete a value from cache\n *\n * @param key - Cache key to delete\n * @throws {CacheDeleteError} If operation fails\n */\n async delete(key: string): Promise<void> {\n try {\n await this.kv.delete(key)\n } catch (error) {\n this.logger.error('Cache delete operation failed', { key, error })\n throw new CacheDeleteError(key)\n }\n }\n\n\n // ==================== LIST METHOD ====================\n\n /**\n * List keys in cache\n *\n * @param options - List options (limit, prefix, cursor)\n * @returns List result with keys and pagination info\n * @throws {CacheListError} If operation fails\n *\n * @example\n * ```typescript\n * // List all keys\n * const result = await cache.list()\n *\n * // List with prefix\n * const result = await cache.list({ prefix: 'user:' })\n *\n * // Paginated list\n * const result = await cache.list({ limit: 100 })\n * if (!result.list_complete) {\n * const nextPage = await cache.list({ cursor: result.cursor })\n * }\n * ```\n */\n async list<Metadata = unknown>(\n options?: KVNamespaceListOptions\n ): Promise<KVNamespaceListResult<Metadata>> {\n try {\n return await this.kv.list<Metadata>(options)\n } catch (error) {\n this.logger.error('Cache list operation failed', { options, error })\n throw new CacheListError()\n }\n }\n}\n","/**\n * Cache Module\n *\n * Provides key-value caching capabilities using Cloudflare KV namespaces.\n *\n * **Features:**\n * - Type-safe KV wrapper with full method coverage\n * - Multiple KV binding support via `withBinding()`\n * - Automatic error handling with security-focused logging\n * - Singleton service for optimal performance\n */\n\nimport { Module } from '../module'\nimport { CACHE_TOKENS } from './cache.tokens'\nimport { CacheService } from './services'\n\n@Module({\n providers: [\n // Singleton - CacheService has no request dependencies\n { provide: CACHE_TOKENS.CacheService, useClass: CacheService },\n ],\n})\nexport class CacheModule {}\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,gBAAb,cAAmC,iBAAiB;CAClD,YAAY,KAAa;EACvB,MAAM,0BAA0B,YAAY,OAAO,sBAAsB,EAAE,KAAK,CAAC;;;;;;;;;;;ACFrF,IAAa,gBAAb,cAAmC,iBAAiB;CAClD,YAAY,KAAa;EACvB,MAAM,0BAA0B,YAAY,OAAO,sBAAsB,EAAE,KAAK,CAAC;;;;;;;;;;;ACFrF,IAAa,mBAAb,cAAsC,iBAAiB;CACrD,YAAY,KAAa;EACvB,MAAM,6BAA6B,YAAY,OAAO,sBAAsB,EAAE,KAAK,CAAC;;;;;;;;;;ACHxF,IAAa,iBAAb,cAAoC,iBAAiB;CACnD,cAAc;EACZ,MAAM,2BAA2B,YAAY,OAAO,sBAAsB,EAAE,CAAC;;;;;;ACqC1E,IAAA,eAAA,gBAAA,MAAM,aAAa;CAI4B;CACI;CAJxD;CAEA,YACE,KACA,QACA;EAFkD,KAAA,MAAA;EACI,KAAA,SAAA;EAEtD,KAAK,KAAK,IAAI;;;;;;;;;CAUhB,MAAM,IAAuB;EAC3B,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BZ,YAAY,IAA+B;EACzC,MAAM,WAAW,IAAA,cAAiB,KAAK,KAAK,KAAK,OAAO;EACxD,SAAS,MAAM,GAAG;EAClB,OAAO;;CAkBT,MAAM,IACJ,KACA,eACuE;EACvE,IAAI;GACF,IAAI,OAAO,kBAAkB,UAE3B,OAAO,MAAM,KAAK,GAAG,IAAI,KAAK,cAAqB;GAGrD,IAAI,eAEF,OAAO,MAAM,KAAK,GAAG,IAAI,KAAK,cAAqB;GAGrD,OAAO,MAAM,KAAK,GAAG,IAAI,IAAI;WACtB,OAAO;GACd,KAAK,OAAO,MAAM,8BAA8B;IAAE;IAAK;IAAO,CAAC;GAC/D,MAAM,IAAI,cAAc,IAAI;;;CA+BhC,MAAM,gBACJ,KACA,eAMA;EACA,IAAI;GACF,IAAI,OAAO,kBAAkB,UAE3B,OAAO,MAAM,KAAK,GAAG,gBAAgB,KAAK,cAAqB;GAGjE,IAAI,eAEF,OAAO,MAAM,KAAK,GAAG,gBAAgB,KAAK,cAAqB;GAGjE,OAAO,MAAM,KAAK,GAAG,gBAAgB,IAAI;WAClC,OAAO;GACd,KAAK,OAAO,MAAM,0CAA0C;IAAE;IAAK;IAAO,CAAC;GAC3E,MAAM,IAAI,cAAc,IAAI;;;;;;;;;;;;;;;;;;;;;;;CA0BhC,MAAM,IACJ,KACA,OACA,SACe;EACf,IAAI;GACF,MAAM,KAAK,GAAG,IAAI,KAAK,OAAiB,QAAQ;WACzC,OAAO;GACd,KAAK,OAAO,MAAM,8BAA8B;IAAE;IAAK;IAAO,CAAC;GAC/D,MAAM,IAAI,cAAc,IAAI;;;;;;;;;CAYhC,MAAM,OAAO,KAA4B;EACvC,IAAI;GACF,MAAM,KAAK,GAAG,OAAO,IAAI;WAClB,OAAO;GACd,KAAK,OAAO,MAAM,iCAAiC;IAAE;IAAK;IAAO,CAAC;GAClE,MAAM,IAAI,iBAAiB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;CA6BnC,MAAM,KACJ,SAC0C;EAC1C,IAAI;GACF,OAAO,MAAM,KAAK,GAAG,KAAe,QAAQ;WACrC,OAAO;GACd,KAAK,OAAO,MAAM,+BAA+B;IAAE;IAAS;IAAO,CAAC;GACpE,MAAM,IAAI,gBAAgB;;;;;CArO/B,UAAU,aAAa,aAAa;oBAKhC,OAAO,UAAU,cAAc,CAAA;oBAC/B,OAAO,cAAc,cAAc,CAAA;;;;;;;;;;;;;;;;AC9BjC,IAAA,cAAA,MAAM,YAAY;0BANxB,OAAO,EACN,WAAW,CAET;CAAE,SAAS,aAAa;CAAc,UAAU;CAAc,CAC/D,EACF,CAAC,CAAA,EAAA,YAAA"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/cache/cache.error.ts","../../src/cache/cache.tokens.ts","../../src/cache/services/cache.service.ts","../../src/cache/services/tiered-cache.service.ts","../../src/cache/cache.module.ts"],"sourcesContent":["import { ApplicationError } from '../errors'\n\nexport class CacheError extends ApplicationError {}\n","export const CACHE_TOKENS = {\n CacheService: Symbol.for('stratal:cache:service'),\n TieredCacheService: Symbol.for('stratal:cache:tiered-service'),\n} as const\n\nexport type CacheToken = (typeof CACHE_TOKENS)[keyof typeof CACHE_TOKENS]\n","import { inject } from '../../di'\nimport { Singleton } from '../../di/decorators'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { type StratalEnv } from '../../env'\nimport { LOGGER_TOKENS, type LoggerService } from '../../logger'\nimport { CACHE_TOKENS } from '../cache.tokens'\nimport { CacheError } from '../cache.error'\n\n/**\n * Cache Service\n *\n * Type-safe wrapper around Cloudflare KV namespaces for caching operations.\n *\n * Reads are eventually consistent — KV may serve an edge-cached value for up to\n * ~60s after a write. When you need isolate-local read-after-write coherence\n * (e.g. set-once markers like queue idempotency keys), opt into\n * {@link TieredCacheService}, which layers an isolate-local L1 over this\n * service. Do **not** use the L1 tier for read-modify-write counters that need\n * cross-edge freshness (e.g. rate limiting) — plain KV is the correct primitive\n * there.\n *\n * **Features:**\n * - Mirrors all KVNamespace methods with full type safety\n * - Supports multiple KV bindings via `withBinding()` / `binding(name)`\n * - Automatic error handling with logging\n * - Security: Raw errors are logged, not exposed to users\n *\n * **Usage:**\n * ```typescript\n * class MyService {\n * private readonly uploadsCache: CacheService\n *\n * constructor(\n * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,\n * ) {\n * // Initialize specialized caches in constructor\n * this.uploadsCache = this.cache.binding('UPLOADS_CACHE')\n * }\n *\n * async cacheData(key: string, value: string) {\n * await this.cache.put(key, value, { expirationTtl: 3600 })\n * await this.uploadsCache.put(`upload:${key}`, value)\n * }\n * }\n * ```\n *\n * @see https://developers.cloudflare.com/kv/api/\n */\n@Singleton(CACHE_TOKENS.CacheService)\nexport class CacheService {\n private kv: KVNamespace\n\n constructor(\n @inject(DI_TOKENS.CloudflareEnv) private readonly env: StratalEnv,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService\n ) {\n this.kv = env.CACHE\n }\n\n /** The KV namespace this instance is bound to. */\n get namespace(): KVNamespace {\n return this.kv\n }\n\n /**\n * Create a new CacheService instance bound to a different KV namespace.\n *\n * @param kv - KV namespace to use\n * @returns A new CacheService for the given binding\n */\n withBinding(kv: KVNamespace): CacheService {\n const instance = new CacheService(this.env, this.logger)\n instance.kv = kv\n return instance\n }\n\n /**\n * Create a new CacheService instance bound to a KV namespace by its binding\n * name, resolved from the environment.\n *\n * @param name - KV namespace binding name (e.g. `'UPLOADS_CACHE'`)\n * @returns A new CacheService for the given binding\n * @throws {CacheError} If no binding with that name exists in the environment\n */\n binding(name: string): CacheService {\n const kv = (this.env as unknown as Record<string, unknown>)[name] as KVNamespace | undefined\n if (!kv) {\n throw new CacheError(`KV binding \"${name}\" was not found in the environment`)\n }\n return this.withBinding(kv)\n }\n\n // ==================== GET METHODS ====================\n\n /**\n * Get a value from cache\n *\n * @param key - Cache key\n * @param typeOrOptions - Type string or options object (defaults to 'text')\n * @returns Value in specified type, or null if not found\n * @throws {CacheError} If operation fails\n */\n async get(key: string, typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>): Promise<string | null>\n async get<ExpectedValue = unknown>(key: string, typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>): Promise<ExpectedValue | null>\n async get(key: string, typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>): Promise<ArrayBuffer | null>\n async get(key: string, typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>): Promise<ReadableStream | null>\n\n async get<ExpectedValue = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<string | ExpectedValue | ArrayBuffer | ReadableStream | null> {\n try {\n if (typeof typeOrOptions === 'string') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.get(key, typeOrOptions as any)\n }\n\n if (typeOrOptions) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.get(key, typeOrOptions as any)\n }\n\n return await this.kv.get(key)\n } catch (error) {\n this.logger.error('Cache get operation failed', { key, error })\n throw new CacheError(`Failed to get cache key \"${key}\"`)\n }\n }\n\n // ==================== GET WITH METADATA METHODS ====================\n\n /**\n * Get a value with metadata from cache\n *\n * @param key - Cache key\n * @param typeOrOptions - Type string or options object (defaults to 'text')\n * @returns Object with value, metadata, and cacheStatus\n * @throws {CacheError} If operation fails\n */\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>\n ): Promise<KVNamespaceGetWithMetadataResult<string, Metadata>>\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>\n ): Promise<KVNamespaceGetWithMetadataResult<ExpectedValue, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>\n ): Promise<KVNamespaceGetWithMetadataResult<ArrayBuffer, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>\n ): Promise<KVNamespaceGetWithMetadataResult<ReadableStream, Metadata>>\n\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<\n KVNamespaceGetWithMetadataResult<\n string | ExpectedValue | ArrayBuffer | ReadableStream,\n Metadata\n >\n > {\n try {\n if (typeof typeOrOptions === 'string') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.getWithMetadata(key, typeOrOptions as any)\n }\n\n if (typeOrOptions) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging KV overloaded API\n return await this.kv.getWithMetadata(key, typeOrOptions as any)\n }\n\n return await this.kv.getWithMetadata(key)\n } catch (error) {\n this.logger.error('Cache getWithMetadata operation failed', { key, error })\n throw new CacheError(`Failed to get cache key \"${key}\"`)\n }\n }\n\n // ==================== PUT METHOD ====================\n\n /**\n * Store a value in cache\n *\n * @param key - Cache key\n * @param value - Value to store (string, ArrayBuffer, ArrayBufferView, or ReadableStream)\n * @param options - Put options (expiration, expirationTtl, metadata)\n * @throws {CacheError} If operation fails\n *\n * @example\n * ```typescript\n * // Simple put\n * await cache.put('key', 'value')\n *\n * // With TTL\n * await cache.put('key', 'value', { expirationTtl: 3600 })\n *\n * // With metadata\n * await cache.put('key', 'value', { metadata: { created: Date.now() } })\n * ```\n */\n async put(\n key: string,\n value: string | ArrayBuffer | ArrayBufferView | ReadableStream,\n options?: KVNamespacePutOptions\n ): Promise<void> {\n try {\n await this.kv.put(key, value as string, options)\n } catch (error) {\n this.logger.error('Cache put operation failed', { key, error })\n throw new CacheError(`Failed to store cache key \"${key}\"`)\n }\n }\n\n // ==================== DELETE METHODS ====================\n\n /**\n * Delete a value from cache\n *\n * @param key - Cache key to delete\n * @throws {CacheError} If operation fails\n */\n async delete(key: string): Promise<void> {\n try {\n await this.kv.delete(key)\n } catch (error) {\n this.logger.error('Cache delete operation failed', { key, error })\n throw new CacheError(`Failed to delete cache key \"${key}\"`)\n }\n }\n\n\n // ==================== LIST METHOD ====================\n\n /**\n * List keys in cache\n *\n * @param options - List options (limit, prefix, cursor)\n * @returns List result with keys and pagination info\n * @throws {CacheError} If operation fails\n *\n * @example\n * ```typescript\n * // List all keys\n * const result = await cache.list()\n *\n * // List with prefix\n * const result = await cache.list({ prefix: 'user:' })\n *\n * // Paginated list\n * const result = await cache.list({ limit: 100 })\n * if (!result.list_complete) {\n * const nextPage = await cache.list({ cursor: result.cursor })\n * }\n * ```\n */\n async list<Metadata = unknown>(\n options?: KVNamespaceListOptions\n ): Promise<KVNamespaceListResult<Metadata>> {\n try {\n return await this.kv.list<Metadata>(options)\n } catch (error) {\n this.logger.error('Cache list operation failed', { options, error })\n throw new CacheError('Failed to list cache keys')\n }\n }\n}\n","import { inject } from '../../di'\nimport { Singleton } from '../../di/decorators'\nimport { CACHE_TOKENS } from '../cache.tokens'\nimport type { CacheService } from './cache.service'\n\n/** A value held in the isolate-local L1 tier. */\ninterface L1Entry {\n /** The raw string value, exactly as it is (or would be) stored in KV. */\n value: string\n /** Absolute expiry in epoch milliseconds, or `null` for no expiry. */\n expiresAt: number | null\n}\n\n/**\n * Max entries kept in the isolate-local L1 before the oldest is evicted (FIFO).\n * Bounds memory per isolate; KV remains the unbounded source of truth.\n */\nconst L1_MAX_ENTRIES = 1000\n\n/**\n * Tiered Cache Service\n *\n * Layers an **isolate-local in-memory L1** over {@link CacheService} (KV, the\n * L2). Opt-in — inject `CACHE_TOKENS.TieredCacheService` instead of\n * `CACHE_TOKENS.CacheService` when you want it.\n *\n * **Why:** KV reads are eventually consistent (a `get` can return an\n * edge-cached value for up to ~60s after a `put`). The L1 makes writes made\n * through *this isolate* immediately and consistently visible to subsequent\n * reads on the same isolate — closing the read-after-write gap KV alone cannot.\n * This is what makes set-once patterns (e.g. queue idempotency markers) reliable\n * within an isolate, even inside KV's consistency window.\n *\n * **Use it for:** set-once / read-mostly values (idempotency claims, immutable\n * lookups). **Do not use it for** read-modify-write counters that need\n * cross-edge freshness (e.g. rate limiting): an isolate that wrote a key reads\n * its own value until the L1 entry expires, so concurrent increments from other\n * isolates are missed and overwritten. Use plain {@link CacheService} (KV) or a\n * Durable-Object store for those.\n *\n * **Semantics:**\n * - L1 caches string-backed values only (`text`/`json`). `arrayBuffer`/`stream`\n * reads and non-string writes bypass and invalidate L1.\n * - `put`/`delete` are write-through: KV and L1 update in lock-step, honoring\n * `expirationTtl`/`expiration` for the L1 entry's own expiry.\n * - `get` populates L1 from `text` reads (the only path that yields the raw\n * string). `json` reads are served from L1 when the string was cached by a\n * prior `put`/`text` read, otherwise they go straight to KV.\n * - `getWithMetadata` and `list` always read KV directly (metadata is not held\n * in L1).\n *\n * **Cross-isolate caveat:** the L1 only observes writes made through its own\n * isolate. A value mutated by another isolate is not seen until the local entry\n * expires or is invalidated by a local write/delete.\n *\n * **Bindings:** `binding(name)` returns a memoized tiered instance per binding,\n * so each KV namespace has its own stable, isolate-lifetime L1.\n */\n@Singleton(CACHE_TOKENS.TieredCacheService)\nexport class TieredCacheService {\n /** Isolate-local L1 tier. Per-instance, so each binding has its own. */\n private readonly l1 = new Map<string, L1Entry>()\n /** Memoized tiered instances per binding name (each with its own L1). */\n private readonly children = new Map<string, TieredCacheService>()\n\n constructor(\n @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService\n ) {}\n\n /**\n * Get the tiered cache bound to a KV namespace by its binding name. Memoized:\n * repeated calls with the same name return the same instance, preserving its\n * isolate-local L1 across requests/messages.\n *\n * @param name - KV namespace binding name (e.g. `'UPLOADS_CACHE'`)\n * @throws {CacheError} If no binding with that name exists in the environment\n */\n binding(name: string): TieredCacheService {\n let child = this.children.get(name)\n if (child === undefined) {\n child = new TieredCacheService(this.cache.binding(name))\n this.children.set(name, child)\n }\n return child\n }\n\n // ==================== GET ====================\n\n async get(key: string, typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>): Promise<string | null>\n async get<ExpectedValue = unknown>(key: string, typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>): Promise<ExpectedValue | null>\n async get(key: string, typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>): Promise<ArrayBuffer | null>\n async get(key: string, typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>): Promise<ReadableStream | null>\n\n async get<ExpectedValue = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<string | ExpectedValue | ArrayBuffer | ReadableStream | null> {\n const type = typeof typeOrOptions === 'string'\n ? typeOrOptions\n : typeOrOptions?.type ?? 'text'\n\n // L1 holds string-backed values only. Serve text/json from it when present.\n if (type === 'text' || type === 'json') {\n const cached = this.l1Read(key)\n if (cached !== null) {\n return type === 'json' ? (JSON.parse(cached) as ExpectedValue) : cached\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging the typed CacheService.get overloads\n const value = await this.cache.get<ExpectedValue>(key, typeOrOptions as any)\n\n // Only `text` reads yield the raw string we can cache; back-populate L1.\n if (type === 'text' && typeof value === 'string') {\n this.l1Write(key, value, null)\n }\n\n return value\n }\n\n // ==================== GET WITH METADATA (KV-direct) ====================\n\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>\n ): Promise<KVNamespaceGetWithMetadataResult<string, Metadata>>\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>\n ): Promise<KVNamespaceGetWithMetadataResult<ExpectedValue, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'arrayBuffer' | KVNamespaceGetOptions<'arrayBuffer'>\n ): Promise<KVNamespaceGetWithMetadataResult<ArrayBuffer, Metadata>>\n async getWithMetadata<Metadata = unknown>(\n key: string,\n typeOrOptions: 'stream' | KVNamespaceGetOptions<'stream'>\n ): Promise<KVNamespaceGetWithMetadataResult<ReadableStream, Metadata>>\n\n async getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(\n key: string,\n typeOrOptions?: string | KVNamespaceGetOptions<'text' | 'json' | 'arrayBuffer' | 'stream'>\n ): Promise<\n KVNamespaceGetWithMetadataResult<\n string | ExpectedValue | ArrayBuffer | ReadableStream,\n Metadata\n >\n > {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any -- bridging the typed CacheService.getWithMetadata overloads\n return this.cache.getWithMetadata<ExpectedValue, Metadata>(key, typeOrOptions as any)\n }\n\n // ==================== PUT (write-through) ====================\n\n async put(\n key: string,\n value: string | ArrayBuffer | ArrayBufferView | ReadableStream,\n options?: KVNamespacePutOptions\n ): Promise<void> {\n await this.cache.put(key, value, options)\n // Write-through: cache strings in L1; invalidate for binary values, which\n // L1 does not hold.\n if (typeof value === 'string') {\n this.l1Write(key, value, this.l1ExpiresAt(options))\n } else {\n this.l1.delete(key)\n }\n }\n\n // ==================== DELETE (write-through) ====================\n\n async delete(key: string): Promise<void> {\n await this.cache.delete(key)\n this.l1.delete(key)\n }\n\n // ==================== LIST (KV-direct) ====================\n\n async list<Metadata = unknown>(\n options?: KVNamespaceListOptions\n ): Promise<KVNamespaceListResult<Metadata>> {\n return this.cache.list<Metadata>(options)\n }\n\n // ==================== L1 TIER ====================\n\n /** Read a fresh L1 entry, evicting it if expired. Returns `null` on miss. */\n private l1Read(key: string): string | null {\n const entry = this.l1.get(key)\n if (entry === undefined) return null\n if (entry.expiresAt !== null && Date.now() >= entry.expiresAt) {\n this.l1.delete(key)\n return null\n }\n return entry.value\n }\n\n /** Write an L1 entry, refreshing its recency and evicting the oldest at cap. */\n private l1Write(key: string, value: string, expiresAt: number | null): void {\n // Re-insert so the most recently written key is youngest in iteration order.\n this.l1.delete(key)\n if (this.l1.size >= L1_MAX_ENTRIES) {\n const oldest = this.l1.keys().next().value\n if (oldest !== undefined) this.l1.delete(oldest)\n }\n this.l1.set(key, { value, expiresAt })\n }\n\n /** Compute an absolute L1 expiry (epoch ms) from KV put options. */\n private l1ExpiresAt(options?: KVNamespacePutOptions): number | null {\n if (options?.expiration !== undefined) return options.expiration * 1000\n if (options?.expirationTtl !== undefined) return Date.now() + options.expirationTtl * 1000\n return null\n }\n}\n","/**\n * Cache Module\n *\n * Provides key-value caching capabilities using Cloudflare KV namespaces.\n *\n * **Features:**\n * - Type-safe KV wrapper with full method coverage\n * - Multiple KV binding support via `withBinding()`\n * - Automatic error handling with security-focused logging\n * - Singleton service for optimal performance\n */\n\nimport { Module } from '../module'\nimport { CACHE_TOKENS } from './cache.tokens'\nimport { CacheService, TieredCacheService } from './services'\n\n@Module({\n providers: [\n // Singleton - CacheService has no request dependencies\n { provide: CACHE_TOKENS.CacheService, useClass: CacheService },\n // Opt-in isolate-local L1 over CacheService (for set-once/read-mostly keys)\n { provide: CACHE_TOKENS.TieredCacheService, useClass: TieredCacheService },\n ],\n})\nexport class CacheModule {}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { t as StratalEnv } from "./env-D1rcZ8_r.mjs";
2
- import { i as LoggerService } from "./index-DBd_2wv8.mjs";
1
+ import { t as StratalEnv } from "./env-ug22bJj7.mjs";
2
+ import { r as LoggerService } from "./index-BUt92sAE.mjs";
3
3
 
4
4
  //#region src/cache/services/cache.service.d.ts
5
5
  /**
@@ -7,9 +7,17 @@ import { i as LoggerService } from "./index-DBd_2wv8.mjs";
7
7
  *
8
8
  * Type-safe wrapper around Cloudflare KV namespaces for caching operations.
9
9
  *
10
+ * Reads are eventually consistent — KV may serve an edge-cached value for up to
11
+ * ~60s after a write. When you need isolate-local read-after-write coherence
12
+ * (e.g. set-once markers like queue idempotency keys), opt into
13
+ * {@link TieredCacheService}, which layers an isolate-local L1 over this
14
+ * service. Do **not** use the L1 tier for read-modify-write counters that need
15
+ * cross-edge freshness (e.g. rate limiting) — plain KV is the correct primitive
16
+ * there.
17
+ *
10
18
  * **Features:**
11
19
  * - Mirrors all KVNamespace methods with full type safety
12
- * - Supports multiple KV bindings via `withBinding()`
20
+ * - Supports multiple KV bindings via `withBinding()` / `binding(name)`
13
21
  * - Automatic error handling with logging
14
22
  * - Security: Raw errors are logged, not exposed to users
15
23
  *
@@ -20,10 +28,9 @@ import { i as LoggerService } from "./index-DBd_2wv8.mjs";
20
28
  *
21
29
  * constructor(
22
30
  * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,
23
- * @inject(DI_TOKENS.CloudflareEnv) private readonly env: Env
24
31
  * ) {
25
32
  * // Initialize specialized caches in constructor
26
- * this.uploadsCache = this.cache.withBinding(this.env.UPLOADS_CACHE)
33
+ * this.uploadsCache = this.cache.binding('UPLOADS_CACHE')
27
34
  * }
28
35
  *
29
36
  * async cacheData(key: string, value: string) {
@@ -40,48 +47,31 @@ declare class CacheService {
40
47
  private readonly logger;
41
48
  private kv;
42
49
  constructor(env: StratalEnv, logger: LoggerService);
50
+ /** The KV namespace this instance is bound to. */
51
+ get namespace(): KVNamespace;
43
52
  /**
44
- * Set the KV namespace binding
45
- *
46
- * Used internally by `withBinding()` to configure different KV instances.
53
+ * Create a new CacheService instance bound to a different KV namespace.
47
54
  *
48
55
  * @param kv - KV namespace to use
56
+ * @returns A new CacheService for the given binding
49
57
  */
50
- setKV(kv: KVNamespace): void;
58
+ withBinding(kv: KVNamespace): CacheService;
51
59
  /**
52
- * Create a new CacheService instance with a different KV binding
53
- *
54
- * **Pattern:** Returns a new instance (immutable)
60
+ * Create a new CacheService instance bound to a KV namespace by its binding
61
+ * name, resolved from the environment.
55
62
  *
56
- * **Best Practice:** Initialize specialized caches as class properties in constructor
57
- *
58
- * @example
59
- * ```typescript
60
- * class MyService {
61
- * private readonly uploadsCache: CacheService
62
- * private readonly systemCache: CacheService
63
- *
64
- * constructor(
65
- * @inject(CACHE_TOKENS.CacheService) private readonly cache: CacheService,
66
- * @inject(DI_TOKENS.CloudflareEnv) private readonly env: Env
67
- * ) {
68
- * this.uploadsCache = this.cache.withBinding(this.env.UPLOADS_CACHE)
69
- * this.systemCache = this.cache.withBinding(this.env.SYSTEM_CONFIG_KV)
70
- * }
71
- * }
72
- * ```
73
- *
74
- * @param kv - KV namespace to use
75
- * @returns New CacheService instance with the specified binding
63
+ * @param name - KV namespace binding name (e.g. `'UPLOADS_CACHE'`)
64
+ * @returns A new CacheService for the given binding
65
+ * @throws {CacheError} If no binding with that name exists in the environment
76
66
  */
77
- withBinding(kv: KVNamespace): CacheService;
67
+ binding(name: string): CacheService;
78
68
  /**
79
69
  * Get a value from cache
80
70
  *
81
71
  * @param key - Cache key
82
72
  * @param typeOrOptions - Type string or options object (defaults to 'text')
83
73
  * @returns Value in specified type, or null if not found
84
- * @throws {CacheGetError} If operation fails
74
+ * @throws {CacheError} If operation fails
85
75
  */
86
76
  get(key: string, typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>): Promise<string | null>;
87
77
  get<ExpectedValue = unknown>(key: string, typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>): Promise<ExpectedValue | null>;
@@ -93,7 +83,7 @@ declare class CacheService {
93
83
  * @param key - Cache key
94
84
  * @param typeOrOptions - Type string or options object (defaults to 'text')
95
85
  * @returns Object with value, metadata, and cacheStatus
96
- * @throws {CacheGetError} If operation fails
86
+ * @throws {CacheError} If operation fails
97
87
  */
98
88
  getWithMetadata<Metadata = unknown>(key: string, typeOrOptions?: 'text' | KVNamespaceGetOptions<'text'>): Promise<KVNamespaceGetWithMetadataResult<string, Metadata>>;
99
89
  getWithMetadata<ExpectedValue = unknown, Metadata = unknown>(key: string, typeOrOptions: 'json' | KVNamespaceGetOptions<'json'>): Promise<KVNamespaceGetWithMetadataResult<ExpectedValue, Metadata>>;
@@ -105,7 +95,7 @@ declare class CacheService {
105
95
  * @param key - Cache key
106
96
  * @param value - Value to store (string, ArrayBuffer, ArrayBufferView, or ReadableStream)
107
97
  * @param options - Put options (expiration, expirationTtl, metadata)
108
- * @throws {CachePutError} If operation fails
98
+ * @throws {CacheError} If operation fails
109
99
  *
110
100
  * @example
111
101
  * ```typescript
@@ -124,7 +114,7 @@ declare class CacheService {
124
114
  * Delete a value from cache
125
115
  *
126
116
  * @param key - Cache key to delete
127
- * @throws {CacheDeleteError} If operation fails
117
+ * @throws {CacheError} If operation fails
128
118
  */
129
119
  delete(key: string): Promise<void>;
130
120
  /**
@@ -132,7 +122,7 @@ declare class CacheService {
132
122
  *
133
123
  * @param options - List options (limit, prefix, cursor)
134
124
  * @returns List result with keys and pagination info
135
- * @throws {CacheListError} If operation fails
125
+ * @throws {CacheError} If operation fails
136
126
  *
137
127
  * @example
138
128
  * ```typescript
@@ -153,4 +143,4 @@ declare class CacheService {
153
143
  }
154
144
  //#endregion
155
145
  export { CacheService as t };
156
- //# sourceMappingURL=cache.service-DsnKuNyO.d.mts.map
146
+ //# sourceMappingURL=cache.service-uElmBtdS.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.service-uElmBtdS.d.mts","names":[],"sources":["../src/cache/services/cache.service.ts"],"mappings":";;;;;;AAgDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cACa,YAAA;EAAA,iBAIyC,GAAA;EAAA,iBACI,MAAA;EAAA,QAJhD,EAAA;cAG4C,GAAA,EAAK,UAAA,EACD,MAAA,EAAQ,aAAA;EA2J7D;EAAA,IArJC,SAAA,IAAa,WAAA;EAyML;;;;;;EA/LZ,WAAA,CAAY,EAAA,EAAI,WAAA,GAAc,YAAA;EAhB0B;;;;;;;;EA8BxD,OAAA,CAAQ,IAAA,WAAe,YAAA;EAdvB;;;;;;;;EAgCM,GAAA,CAAI,GAAA,UAAa,aAAA,YAAyB,qBAAA,WAAgC,OAAA;EAC1E,GAAA,0BAA6B,GAAA,UAAa,aAAA,WAAwB,qBAAA,WAAgC,OAAA,CAAQ,aAAA;EAC1G,GAAA,CAAI,GAAA,UAAa,aAAA,kBAA+B,qBAAA,kBAAuC,OAAA,CAAQ,WAAA;EAC/F,GAAA,CAAI,GAAA,UAAa,aAAA,aAA0B,qBAAA,aAAkC,OAAA,CAAQ,cAAA;EAFrF;;;;;;;;EAoCA,eAAA,qBACJ,GAAA,UACA,aAAA,YAAyB,qBAAA,WACxB,OAAA,CAAQ,gCAAA,SAAyC,QAAA;EAC9C,eAAA,8CACJ,GAAA,UACA,aAAA,WAAwB,qBAAA,WACvB,OAAA,CAAQ,gCAAA,CAAiC,aAAA,EAAe,QAAA;EACrD,eAAA,qBACJ,GAAA,UACA,aAAA,kBAA+B,qBAAA,kBAC9B,OAAA,CAAQ,gCAAA,CAAiC,WAAA,EAAa,QAAA;EACnD,eAAA,qBACJ,GAAA,UACA,aAAA,aAA0B,qBAAA,aACzB,OAAA,CAAQ,gCAAA,CAAiC,cAAA,EAAgB,QAAA;EAlDyC;;;;;;;;;;;;;;;;;;;;EAqG/F,GAAA,CACJ,GAAA,UACA,KAAA,WAAgB,WAAA,GAAc,eAAA,GAAkB,cAAA,EAChD,OAAA,GAAU,qBAAA,GACT,OAAA;EA/DA;;;;;;EAgFG,MAAA,CAAO,GAAA,WAAc,OAAA;EA7EM;;;;;;;;;;;;;;;;;;;;;;EA+G3B,IAAA,qBACJ,OAAA,GAAU,sBAAA,GACT,OAAA,CAAQ,qBAAA,CAAsB,QAAA;AAAA"}
@@ -1,5 +1,16 @@
1
- import { a as green, n as cyan, o as red, r as dim, s as yellow, t as bold } from "./colors-DJaRDXoS.mjs";
2
- import "reflect-metadata";
1
+ //#region src/quarry/colors.ts
2
+ /** Minimal ANSI color helpers that respect the `NO_COLOR` convention. */
3
+ const isEnabled = () => typeof process !== "undefined" ? !process.env.NO_COLOR : true;
4
+ /** Create an ANSI formatter that wraps text with the given open/close SGR codes. */
5
+ const code = (open, close) => (s) => isEnabled() ? `\x1b[${open}m${s}\x1b[${close}m` : s;
6
+ const bold = code(1, 22);
7
+ const dim = code(2, 22);
8
+ const cyan = code(36, 39);
9
+ const green = code(32, 39);
10
+ const red = code(31, 39);
11
+ const yellow = code(33, 39);
12
+ const dimWhite = (s) => isEnabled() ? `\x1b[2;37m${s}\x1b[22;39m` : s;
13
+ //#endregion
3
14
  //#region src/quarry/constants.ts
4
15
  /**
5
16
  * Symbol key for storing internal mutable state on Command instances.
@@ -191,6 +202,6 @@ var Command = class {
191
202
  }
192
203
  };
193
204
  //#endregion
194
- export { CommandError as n, COMMAND_INTERNALS as r, Command as t };
205
+ export { cyan as a, green as c, bold as i, red as l, CommandError as n, dim as o, COMMAND_INTERNALS as r, dimWhite as s, Command as t, yellow as u };
195
206
 
196
- //# sourceMappingURL=command-BgSlsS4M.mjs.map
207
+ //# sourceMappingURL=command-BvmUAPPQ.mjs.map