@snail-js/api 0.1.27 → 1.0.0

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 (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -605
  3. package/dist/adapter/plain.d.ts +12 -0
  4. package/dist/adapter/plain.d.ts.map +1 -0
  5. package/dist/adapter/react.d.ts +14 -0
  6. package/dist/adapter/react.d.ts.map +1 -0
  7. package/dist/adapter/registry.d.ts +16 -0
  8. package/dist/adapter/registry.d.ts.map +1 -0
  9. package/dist/adapter/vue.d.ts +15 -0
  10. package/dist/adapter/vue.d.ts.map +1 -0
  11. package/dist/chunks/custom-UchOSg_s.js +466 -0
  12. package/dist/chunks/custom-UchOSg_s.js.map +1 -0
  13. package/dist/chunks/download-lBC7oOTT.js +160 -0
  14. package/dist/chunks/download-lBC7oOTT.js.map +1 -0
  15. package/dist/chunks/object-Ct0w-h4i.js +74 -0
  16. package/dist/chunks/object-Ct0w-h4i.js.map +1 -0
  17. package/dist/chunks/plugin-D3RDffDG.js +742 -0
  18. package/dist/chunks/plugin-D3RDffDG.js.map +1 -0
  19. package/dist/chunks/react-C1em-gxy.js +62 -0
  20. package/dist/chunks/react-C1em-gxy.js.map +1 -0
  21. package/dist/chunks/request-qeRhihEF.js +40 -0
  22. package/dist/chunks/request-qeRhihEF.js.map +1 -0
  23. package/dist/chunks/response-D-ubkAFl.js +127 -0
  24. package/dist/chunks/response-D-ubkAFl.js.map +1 -0
  25. package/dist/chunks/use-download-FAjtdJ58.js +1816 -0
  26. package/dist/chunks/use-download-FAjtdJ58.js.map +1 -0
  27. package/dist/chunks/vue-Dd9EhkQ3.js +34 -0
  28. package/dist/chunks/vue-Dd9EhkQ3.js.map +1 -0
  29. package/dist/core/args.d.ts +54 -0
  30. package/dist/core/args.d.ts.map +1 -0
  31. package/dist/core/connection.d.ts +15 -0
  32. package/dist/core/connection.d.ts.map +1 -0
  33. package/dist/core/context.d.ts +124 -0
  34. package/dist/core/context.d.ts.map +1 -0
  35. package/dist/core/http-stream.d.ts +28 -0
  36. package/dist/core/http-stream.d.ts.map +1 -0
  37. package/dist/core/logger.d.ts +22 -0
  38. package/dist/core/logger.d.ts.map +1 -0
  39. package/dist/core/metadata.d.ts +92 -0
  40. package/dist/core/metadata.d.ts.map +1 -0
  41. package/dist/core/metadata.keys.d.ts +41 -0
  42. package/dist/core/metadata.keys.d.ts.map +1 -0
  43. package/dist/core/method.d.ts +177 -0
  44. package/dist/core/method.d.ts.map +1 -0
  45. package/dist/core/plugin-manager.d.ts +106 -0
  46. package/dist/core/plugin-manager.d.ts.map +1 -0
  47. package/dist/core/plugin.d.ts +113 -0
  48. package/dist/core/plugin.d.ts.map +1 -0
  49. package/dist/core/reconnect.d.ts +22 -0
  50. package/dist/core/reconnect.d.ts.map +1 -0
  51. package/dist/core/resolve-stream.d.ts +45 -0
  52. package/dist/core/resolve-stream.d.ts.map +1 -0
  53. package/dist/core/resolve.d.ts +50 -0
  54. package/dist/core/resolve.d.ts.map +1 -0
  55. package/dist/core/response.d.ts +60 -0
  56. package/dist/core/response.d.ts.map +1 -0
  57. package/dist/core/server.d.ts +132 -0
  58. package/dist/core/server.d.ts.map +1 -0
  59. package/dist/core/sse.d.ts +27 -0
  60. package/dist/core/sse.d.ts.map +1 -0
  61. package/dist/core/state-bag.d.ts +36 -0
  62. package/dist/core/state-bag.d.ts.map +1 -0
  63. package/dist/core/websocket.d.ts +29 -0
  64. package/dist/core/websocket.d.ts.map +1 -0
  65. package/dist/decorators/api.d.ts +24 -4
  66. package/dist/decorators/api.d.ts.map +1 -0
  67. package/dist/decorators/args.d.ts +77 -14
  68. package/dist/decorators/args.d.ts.map +1 -0
  69. package/dist/decorators/custom.d.ts +81 -0
  70. package/dist/decorators/custom.d.ts.map +1 -0
  71. package/dist/decorators/header.d.ts +22 -0
  72. package/dist/decorators/header.d.ts.map +1 -0
  73. package/dist/decorators/index.d.ts +17 -0
  74. package/dist/decorators/index.d.ts.map +1 -0
  75. package/dist/decorators/methods.d.ts +33 -0
  76. package/dist/decorators/methods.d.ts.map +1 -0
  77. package/dist/decorators/progress.d.ts +24 -6
  78. package/dist/decorators/progress.d.ts.map +1 -0
  79. package/dist/decorators/server.d.ts +28 -7
  80. package/dist/decorators/server.d.ts.map +1 -0
  81. package/dist/decorators/stream.d.ts +113 -0
  82. package/dist/decorators/stream.d.ts.map +1 -0
  83. package/dist/default/options.d.ts +19 -0
  84. package/dist/default/options.d.ts.map +1 -0
  85. package/dist/error/base.d.ts +20 -0
  86. package/dist/error/base.d.ts.map +1 -0
  87. package/dist/error/decorator.d.ts +14 -0
  88. package/dist/error/decorator.d.ts.map +1 -0
  89. package/dist/error/hook.d.ts +14 -0
  90. package/dist/error/hook.d.ts.map +1 -0
  91. package/dist/error/index.d.ts +8 -0
  92. package/dist/error/index.d.ts.map +1 -0
  93. package/dist/error/options.d.ts +12 -0
  94. package/dist/error/options.d.ts.map +1 -0
  95. package/dist/error/plugin.d.ts +11 -0
  96. package/dist/error/plugin.d.ts.map +1 -0
  97. package/dist/error/request.d.ts +29 -0
  98. package/dist/error/request.d.ts.map +1 -0
  99. package/dist/error/response.d.ts +36 -0
  100. package/dist/error/response.d.ts.map +1 -0
  101. package/dist/index.d.ts +56 -11
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +2034 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/locale/en.d.ts +5 -0
  106. package/dist/locale/en.d.ts.map +1 -0
  107. package/dist/locale/index.d.ts +57 -0
  108. package/dist/locale/index.d.ts.map +1 -0
  109. package/dist/locale/types.d.ts +11 -0
  110. package/dist/locale/types.d.ts.map +1 -0
  111. package/dist/locale/zh.d.ts +5 -0
  112. package/dist/locale/zh.d.ts.map +1 -0
  113. package/dist/plugins/cache/adapters/indexeddb.d.ts +52 -0
  114. package/dist/plugins/cache/adapters/indexeddb.d.ts.map +1 -0
  115. package/dist/plugins/cache/adapters/memory.d.ts +60 -0
  116. package/dist/plugins/cache/adapters/memory.d.ts.map +1 -0
  117. package/dist/plugins/cache/adapters/web-storage.d.ts +43 -0
  118. package/dist/plugins/cache/adapters/web-storage.d.ts.map +1 -0
  119. package/dist/plugins/cache/decorators.d.ts +62 -0
  120. package/dist/plugins/cache/decorators.d.ts.map +1 -0
  121. package/dist/plugins/cache/index.d.ts +41 -0
  122. package/dist/plugins/cache/index.d.ts.map +1 -0
  123. package/dist/plugins/cache/key.d.ts +48 -0
  124. package/dist/plugins/cache/key.d.ts.map +1 -0
  125. package/dist/plugins/cache/manager.d.ts +124 -0
  126. package/dist/plugins/cache/manager.d.ts.map +1 -0
  127. package/dist/plugins/cache/plugin.d.ts +64 -0
  128. package/dist/plugins/cache/plugin.d.ts.map +1 -0
  129. package/dist/plugins/cache/type.d.ts +116 -0
  130. package/dist/plugins/cache/type.d.ts.map +1 -0
  131. package/dist/plugins/index.d.ts +75 -0
  132. package/dist/plugins/index.d.ts.map +1 -0
  133. package/dist/plugins/index.js +2265 -0
  134. package/dist/plugins/index.js.map +1 -0
  135. package/dist/plugins/interceptor/decorators.d.ts +44 -0
  136. package/dist/plugins/interceptor/decorators.d.ts.map +1 -0
  137. package/dist/plugins/interceptor/index.d.ts +31 -0
  138. package/dist/plugins/interceptor/index.d.ts.map +1 -0
  139. package/dist/plugins/interceptor/manager.d.ts +27 -0
  140. package/dist/plugins/interceptor/manager.d.ts.map +1 -0
  141. package/dist/plugins/interceptor/plugin.d.ts +65 -0
  142. package/dist/plugins/interceptor/plugin.d.ts.map +1 -0
  143. package/dist/plugins/interceptor/type.d.ts +45 -0
  144. package/dist/plugins/interceptor/type.d.ts.map +1 -0
  145. package/dist/plugins/pool/index.d.ts +26 -0
  146. package/dist/plugins/pool/index.d.ts.map +1 -0
  147. package/dist/plugins/pool/plugin.d.ts +83 -0
  148. package/dist/plugins/pool/plugin.d.ts.map +1 -0
  149. package/dist/plugins/pool/scheduler.d.ts +153 -0
  150. package/dist/plugins/pool/scheduler.d.ts.map +1 -0
  151. package/dist/plugins/pool/type.d.ts +38 -0
  152. package/dist/plugins/pool/type.d.ts.map +1 -0
  153. package/dist/plugins/react/index.d.ts +20 -0
  154. package/dist/plugins/react/index.d.ts.map +1 -0
  155. package/dist/plugins/react/index.js +145 -0
  156. package/dist/plugins/react/index.js.map +1 -0
  157. package/dist/plugins/react/plugin.d.ts +33 -0
  158. package/dist/plugins/react/plugin.d.ts.map +1 -0
  159. package/dist/plugins/react/type.d.ts +32 -0
  160. package/dist/plugins/react/type.d.ts.map +1 -0
  161. package/dist/plugins/transform/decorators.d.ts +54 -0
  162. package/dist/plugins/transform/decorators.d.ts.map +1 -0
  163. package/dist/plugins/transform/hydrate.d.ts +47 -0
  164. package/dist/plugins/transform/hydrate.d.ts.map +1 -0
  165. package/dist/plugins/transform/index.d.ts +41 -0
  166. package/dist/plugins/transform/index.d.ts.map +1 -0
  167. package/dist/plugins/transform/plugin.d.ts +20 -0
  168. package/dist/plugins/transform/plugin.d.ts.map +1 -0
  169. package/dist/plugins/transform/type.d.ts +67 -0
  170. package/dist/plugins/transform/type.d.ts.map +1 -0
  171. package/dist/plugins/validate/decorators.d.ts +24 -0
  172. package/dist/plugins/validate/decorators.d.ts.map +1 -0
  173. package/dist/plugins/validate/index.d.ts +40 -0
  174. package/dist/plugins/validate/index.d.ts.map +1 -0
  175. package/dist/plugins/validate/plugin.d.ts +13 -0
  176. package/dist/plugins/validate/plugin.d.ts.map +1 -0
  177. package/dist/plugins/validate/type.d.ts +54 -0
  178. package/dist/plugins/validate/type.d.ts.map +1 -0
  179. package/dist/plugins/version/decorators.d.ts +22 -0
  180. package/dist/plugins/version/decorators.d.ts.map +1 -0
  181. package/dist/plugins/version/index.d.ts +23 -0
  182. package/dist/plugins/version/index.d.ts.map +1 -0
  183. package/dist/plugins/version/plugin.d.ts +13 -0
  184. package/dist/plugins/version/plugin.d.ts.map +1 -0
  185. package/dist/plugins/version/type.d.ts +47 -0
  186. package/dist/plugins/version/type.d.ts.map +1 -0
  187. package/dist/plugins/vue/index.d.ts +21 -0
  188. package/dist/plugins/vue/index.d.ts.map +1 -0
  189. package/dist/plugins/vue/index.js +114 -0
  190. package/dist/plugins/vue/index.js.map +1 -0
  191. package/dist/plugins/vue/plugin.d.ts +15 -0
  192. package/dist/plugins/vue/plugin.d.ts.map +1 -0
  193. package/dist/plugins/vue/type.d.ts +34 -0
  194. package/dist/plugins/vue/type.d.ts.map +1 -0
  195. package/dist/strategies/index.d.ts +2 -0
  196. package/dist/strategies/index.d.ts.map +1 -0
  197. package/dist/strategies/index.js +29 -0
  198. package/dist/strategies/index.js.map +1 -0
  199. package/dist/strategies/plain.d.ts +2 -0
  200. package/dist/strategies/plain.d.ts.map +1 -0
  201. package/dist/strategies/plain.js +23 -0
  202. package/dist/strategies/plain.js.map +1 -0
  203. package/dist/strategies/react.d.ts +2 -0
  204. package/dist/strategies/react.d.ts.map +1 -0
  205. package/dist/strategies/react.js +30 -0
  206. package/dist/strategies/react.js.map +1 -0
  207. package/dist/strategies/shared/adapter.d.ts +23 -0
  208. package/dist/strategies/shared/adapter.d.ts.map +1 -0
  209. package/dist/strategies/shared/dom.d.ts +53 -0
  210. package/dist/strategies/shared/dom.d.ts.map +1 -0
  211. package/dist/strategies/shared/error.d.ts +30 -0
  212. package/dist/strategies/shared/error.d.ts.map +1 -0
  213. package/dist/strategies/shared/method.d.ts +51 -0
  214. package/dist/strategies/shared/method.d.ts.map +1 -0
  215. package/dist/strategies/shared/public.d.ts +33 -0
  216. package/dist/strategies/shared/public.d.ts.map +1 -0
  217. package/dist/strategies/shared/queue.d.ts +30 -0
  218. package/dist/strategies/shared/queue.d.ts.map +1 -0
  219. package/dist/strategies/shared/retry.d.ts +51 -0
  220. package/dist/strategies/shared/retry.d.ts.map +1 -0
  221. package/dist/strategies/shared/state.d.ts +117 -0
  222. package/dist/strategies/shared/state.d.ts.map +1 -0
  223. package/dist/strategies/shared/timing.d.ts +53 -0
  224. package/dist/strategies/shared/timing.d.ts.map +1 -0
  225. package/dist/strategies/shared/watcher.d.ts +37 -0
  226. package/dist/strategies/shared/watcher.d.ts.map +1 -0
  227. package/dist/strategies/use-auto-request.d.ts +77 -0
  228. package/dist/strategies/use-auto-request.d.ts.map +1 -0
  229. package/dist/strategies/use-download.d.ts +103 -0
  230. package/dist/strategies/use-download.d.ts.map +1 -0
  231. package/dist/strategies/use-fetcher.d.ts +52 -0
  232. package/dist/strategies/use-fetcher.d.ts.map +1 -0
  233. package/dist/strategies/use-pagination.d.ts +101 -0
  234. package/dist/strategies/use-pagination.d.ts.map +1 -0
  235. package/dist/strategies/use-request.d.ts +50 -0
  236. package/dist/strategies/use-request.d.ts.map +1 -0
  237. package/dist/strategies/use-retriable-request.d.ts +46 -0
  238. package/dist/strategies/use-retriable-request.d.ts.map +1 -0
  239. package/dist/strategies/use-sse.d.ts +103 -0
  240. package/dist/strategies/use-sse.d.ts.map +1 -0
  241. package/dist/strategies/use-token-auth.d.ts +88 -0
  242. package/dist/strategies/use-token-auth.d.ts.map +1 -0
  243. package/dist/strategies/use-uploader.d.ts +88 -0
  244. package/dist/strategies/use-uploader.d.ts.map +1 -0
  245. package/dist/strategies/use-watcher.d.ts +69 -0
  246. package/dist/strategies/use-watcher.d.ts.map +1 -0
  247. package/dist/typings/adapter.d.ts +61 -0
  248. package/dist/typings/adapter.d.ts.map +1 -0
  249. package/dist/typings/api.d.ts +122 -0
  250. package/dist/typings/api.d.ts.map +1 -0
  251. package/dist/typings/args.d.ts +51 -0
  252. package/dist/typings/args.d.ts.map +1 -0
  253. package/dist/typings/index.d.ts +8 -12
  254. package/dist/typings/index.d.ts.map +1 -0
  255. package/dist/typings/meta.d.ts +44 -0
  256. package/dist/typings/meta.d.ts.map +1 -0
  257. package/dist/typings/plugin.d.ts +114 -0
  258. package/dist/typings/plugin.d.ts.map +1 -0
  259. package/dist/typings/response.d.ts +118 -0
  260. package/dist/typings/response.d.ts.map +1 -0
  261. package/dist/typings/server.d.ts +83 -0
  262. package/dist/typings/server.d.ts.map +1 -0
  263. package/dist/typings/stream.d.ts +150 -0
  264. package/dist/typings/stream.d.ts.map +1 -0
  265. package/dist/utils/download.d.ts +97 -0
  266. package/dist/utils/download.d.ts.map +1 -0
  267. package/dist/utils/emitter.d.ts +36 -0
  268. package/dist/utils/emitter.d.ts.map +1 -0
  269. package/dist/utils/index.d.ts +6 -1
  270. package/dist/utils/index.d.ts.map +1 -0
  271. package/dist/utils/is.d.ts +22 -0
  272. package/dist/utils/is.d.ts.map +1 -0
  273. package/dist/utils/object.d.ts +44 -0
  274. package/dist/utils/object.d.ts.map +1 -0
  275. package/dist/utils/url.d.ts +44 -0
  276. package/dist/utils/url.d.ts.map +1 -0
  277. package/package.json +90 -27
  278. package/README_EN.md +0 -607
  279. package/dist/cache/index.d.ts +0 -9
  280. package/dist/cache/indexDBCache.d.ts +0 -13
  281. package/dist/cache/localstorageCache.d.ts +0 -10
  282. package/dist/cache/memoryCache.d.ts +0 -11
  283. package/dist/core/index.d.ts +0 -4
  284. package/dist/core/snailApi.d.ts +0 -22
  285. package/dist/core/snailMethod.d.ts +0 -49
  286. package/dist/core/snailServer.d.ts +0 -35
  287. package/dist/core/snailSse.d.ts +0 -20
  288. package/dist/decorators/cache.d.ts +0 -15
  289. package/dist/decorators/method.d.ts +0 -38
  290. package/dist/decorators/sse.d.ts +0 -30
  291. package/dist/decorators/strategy.d.ts +0 -10
  292. package/dist/decorators/versioning.d.ts +0 -16
  293. package/dist/eventEmmit/index.d.ts +0 -1
  294. package/dist/eventEmmit/snail.event.d.ts +0 -10
  295. package/dist/snail-api.js +0 -4868
  296. package/dist/snail-api.umd.cjs +0 -4872
  297. package/dist/strategies/jwtStrategy.d.ts +0 -4
  298. package/dist/typings/api.option.d.ts +0 -10
  299. package/dist/typings/apiProxy.d.ts +0 -8
  300. package/dist/typings/cache.management.option.d.ts +0 -25
  301. package/dist/typings/cache.type.d.ts +0 -23
  302. package/dist/typings/content.type.d.ts +0 -5
  303. package/dist/typings/request.body.d.ts +0 -3
  304. package/dist/typings/response.data.d.ts +0 -13
  305. package/dist/typings/snail.event.d.ts +0 -6
  306. package/dist/typings/snail.method.d.ts +0 -14
  307. package/dist/typings/snail.option.d.ts +0 -16
  308. package/dist/typings/sse.d.ts +0 -15
  309. package/dist/typings/strategy.d.ts +0 -5
  310. package/dist/typings/versioning.option.d.ts +0 -30
  311. package/dist/utils/function.d.ts +0 -31
  312. package/dist/versioning/index.d.ts +0 -1
  313. package/dist/versioning/versioning.d.ts +0 -12
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-storage.d.ts","sourceRoot":"","sources":["../../../../src/plugins/cache/adapters/web-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS5C,0DAA0D;AAC1D,MAAM,WAAW,6BAA6B;IAC5C,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAuB,YAAW,YAAY;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YACE,cAAc,EAAE,MAAM,OAAO,GAAG,SAAS,EACzC,OAAO,GAAE,6BAAkC,EAK5C;IAED,4EAA4E;IAC5E,IAAI,SAAS,IAAI,OAAO,CAEvB;IAEK,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAqB1D;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxE;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvC;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3B;IAEK,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAK9B;IAED,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,GAAG;IAIX,4DAA4D;IAC5D,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,KAAK;CAUd"}
@@ -0,0 +1,62 @@
1
+ import type { CacheableOptions } from "./type.js";
2
+ type DualDecorator = ClassDecorator & MethodDecorator;
3
+ /**
4
+ * Mark this method — or every method of this class — as cacheable.
5
+ *
6
+ * Passing the decorator is an explicit opt-in: it caches even a verb that
7
+ * `CacheOptions.cacheFor` does not list. Without it, `cacheFor` decides, and the
8
+ * reason is that "cache every POST of this class" is far too easy to write by
9
+ * accident when the intent was only to attach tags.
10
+ *
11
+ * ```ts
12
+ * @Api("/user")
13
+ * @Cacheable({ tags: ["users"] })
14
+ * class UserApi {
15
+ * @Get("/") list(): Promise<User[]> { return null!; }
16
+ *
17
+ * @Get("/stats")
18
+ * @Cacheable({ ttl: 5 })
19
+ * stats(): Promise<Stats> { return null!; }
20
+ * }
21
+ * ```
22
+ */
23
+ export declare function Cacheable(options?: CacheableOptions): DualDecorator;
24
+ /**
25
+ * Opt this method — or this entire class — out of caching.
26
+ *
27
+ * A method-level `@NoCache()` beats a class-level `@Cacheable()`, and a
28
+ * class-level `@NoCache()` beats the `cacheFor` default. Opting out is the one
29
+ * decision that may never be overridden by a broader rule, because the cost of
30
+ * being wrong is serving stale data.
31
+ */
32
+ export declare function NoCache(): DualDecorator;
33
+ /**
34
+ * Purge every cached entry carrying any of `tags` once this request succeeds.
35
+ *
36
+ * "Succeeds" means the HTTP round-trip did: the hook lives on the response path,
37
+ * so a failed or cancelled request invalidates nothing. A method may invalidate a
38
+ * tag it also stores under — the plugin purges before it stores, so the fresh
39
+ * entry survives its own invalidation.
40
+ */
41
+ export declare function Invalidates(...tags: string[]): DualDecorator;
42
+ /**
43
+ * Legacy-compatible alias of {@link Invalidates} for a single source name.
44
+ *
45
+ * The pre-rewrite decorator was named after the *source* of a change rather than
46
+ * the entries it purges; application code written against it keeps working, and
47
+ * new code should prefer `@Invalidates`.
48
+ */
49
+ export declare function HitSource(name: string): DualDecorator;
50
+ /**
51
+ * Read `@Cacheable(...)` from a method (when `methodName` is given) or a class.
52
+ *
53
+ * `undefined` means "not marked", which is different from `{}` ("marked, with no
54
+ * overrides") — the plugin treats the two differently.
55
+ */
56
+ export declare function readCacheable(target: unknown, methodName?: string): CacheableOptions | undefined;
57
+ /** `true` when `@NoCache()` was applied to this method or class. */
58
+ export declare function readNoCache(target: unknown, methodName?: string): boolean;
59
+ /** Tags listed by `@Invalidates(...)` / `@HitSource(...)`, in application order. */
60
+ export declare function readInvalidates(target: unknown, methodName?: string): string[];
61
+ export {};
62
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/decorators.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAuB/C,KAAK,aAAa,GAAG,cAAc,GAAG,eAAe,CAAC;AAgDtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,aAAa,CAUvE;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAEvC;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAkB5D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAErD;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAIhG;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9E"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Cache plugin.
3
+ *
4
+ * ```ts
5
+ * import { Cache, Cacheable, Invalidates, NoCache } from "@snail-js/api/plugins";
6
+ *
7
+ * Service.use(Cache({ ttl: 30, l2: "localStorage" }));
8
+ *
9
+ * @Api("/user")
10
+ * class UserApi {
11
+ * @Get("/")
12
+ * @Cacheable({ tags: ["users"] })
13
+ * list(): Promise<User[]> { return null!; }
14
+ *
15
+ * @Post("/")
16
+ * @Invalidates("users")
17
+ * create(@Data() body: NewUser): Promise<User> { return null!; }
18
+ * }
19
+ * ```
20
+ *
21
+ * `priority: -100` is the reserved cache band: last in forward order, so the key
22
+ * is hashed from the final url/params/body, and first in unwind order, so the raw
23
+ * envelope is stored before validation and transformation touch it.
24
+ *
25
+ * @packageDocumentation
26
+ */
27
+ export { IndexedDBCacheAdapter } from "./adapters/indexeddb.js";
28
+ export type { IndexedDBCacheAdapterOptions } from "./adapters/indexeddb.js";
29
+ export { DEFAULT_L1_MAX_SIZE, MemoryCacheAdapter } from "./adapters/memory.js";
30
+ export type { MemoryCacheAdapterOptions } from "./adapters/memory.js";
31
+ export { WebStorageCacheAdapter } from "./adapters/web-storage.js";
32
+ export type { WebStorageCacheAdapterOptions } from "./adapters/web-storage.js";
33
+ export { Cacheable, HitSource, Invalidates, NoCache, readCacheable, readInvalidates, readNoCache } from "./decorators.js";
34
+ export { buildCacheKey } from "./key.js";
35
+ export type { CacheKeyInput } from "./key.js";
36
+ export { CacheManager } from "./manager.js";
37
+ export type { CacheManagerOptions, ResolvedCacheOptions } from "./manager.js";
38
+ export { CACHE_PLUGIN_NAME, CACHE_PRIORITY, Cache, makeCachedResponse } from "./plugin.js";
39
+ export type { CachePlugin } from "./plugin.js";
40
+ export type { CacheableOptions, CacheAdapter, CacheLookup, CacheOptions } from "./type.js";
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,YAAY,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACxF,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,YAAY,EACb,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { InternalAxiosRequestConfig } from "axios";
2
+ import type { SnailMethodType } from "../../typings/api.js";
3
+ /**
4
+ * Cache-key construction.
5
+ *
6
+ * ## Why the whole request identity is hashed
7
+ *
8
+ * A key has to answer one question: "would this request produce the same
9
+ * response as the one I already stored?". That depends on the verb, the final
10
+ * url, the query params and the body — and on nothing else. Headers are
11
+ * deliberately excluded: an `Authorization` header changes *who* asks, not what
12
+ * is asked, and including it would turn every token refresh into a cache flush.
13
+ *
14
+ * ## Why `stableStringify`
15
+ *
16
+ * `{ a: 1, b: 2 }` and `{ b: 2, a: 1 }` are the same query. Serialising them
17
+ * with `JSON.stringify` produces two different strings and therefore two cache
18
+ * entries for one logical request; `stableStringify` sorts object keys, so the
19
+ * hash — and the key — is order-independent.
20
+ *
21
+ * ## Why the url is final here
22
+ *
23
+ * The cache plugin runs at `priority: -100` — last in forward order — precisely
24
+ * so the interceptor plugin (`100`) and the argument decorators have already
25
+ * rewritten `ctx.request.url` and filled in `:placeholders`. Hashing an earlier
26
+ * stage of the url would key `/user/:id` and `/user/42` differently, or worse,
27
+ * identically.
28
+ */
29
+ /** Everything needed to identify one cacheable request. */
30
+ export interface CacheKeyInput {
31
+ /** Namespace, so two servers on one origin never share entries. */
32
+ prefix: string;
33
+ /** The live axios config — url, params and body must already be final. */
34
+ request: InternalAxiosRequestConfig;
35
+ /** Fallback verb when the config carries none. */
36
+ methodType: SnailMethodType;
37
+ /** `@Cacheable({ key })`: use this verbatim instead of the request identity. */
38
+ explicitKey?: string;
39
+ }
40
+ /**
41
+ * Build the key used for one request.
42
+ *
43
+ * The readable part (`prefix:VERB`) is kept outside the hash so a misbehaving
44
+ * cache can be diagnosed from a key alone; only the volatile signature is hashed,
45
+ * which keeps keys short enough for `localStorage`.
46
+ */
47
+ export declare function buildCacheKey(input: CacheKeyInput): string;
48
+ //# sourceMappingURL=key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IAEf,0EAA0E;IAC1E,OAAO,EAAE,0BAA0B,CAAC;IAEpC,kDAAkD;IAClD,UAAU,EAAE,eAAe,CAAC;IAE5B,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAmB1D"}
@@ -0,0 +1,124 @@
1
+ import type { SnailLogger } from "../../core/logger.js";
2
+ import type { SnailMethodType } from "../../typings/api.js";
3
+ import type { CacheAdapter, CacheLookup, CacheOptions } from "./type.js";
4
+ export interface CacheManagerOptions extends CacheOptions {
5
+ /**
6
+ * Logger for L2 failures.
7
+ *
8
+ * The manager runs outside any request, so it has no `ctx.logger`; the plugin
9
+ * injects one built from `@Server({ logLevel })`. Defaults to silent, because a
10
+ * cache must not make an application noisy by itself.
11
+ */
12
+ logger?: SnailLogger;
13
+ }
14
+ /** `CacheOptions` with every default applied — the manager's public state. */
15
+ export interface ResolvedCacheOptions {
16
+ ttl: number;
17
+ maxSize: number;
18
+ l1: boolean;
19
+ l2: CacheAdapter | undefined;
20
+ cacheFor: "all" | readonly SnailMethodType[];
21
+ prefix: string;
22
+ staleWhileRevalidate: boolean;
23
+ dedupe: boolean;
24
+ }
25
+ /**
26
+ * Storage engine behind the cache plugin.
27
+ *
28
+ * ## Layers
29
+ *
30
+ * - **L1** is a {@link MemoryCacheAdapter}: always present unless `l1: false`,
31
+ * bounded by `maxSize`, and the only place an L2 hit is promoted into.
32
+ * - **L2** is any {@link CacheAdapter}, usually a persistent store.
33
+ *
34
+ * ## What the manager owns that the adapters do not
35
+ *
36
+ * TTL, LRU and tags are policy, not storage. Keeping them here means a custom L2
37
+ * adapter only has to answer "get/set/delete" and never has to know what a tag
38
+ * is — which is what makes the adapter interface small enough to implement over
39
+ * anything (IndexedDB, `localStorage`, an HTTP cache).
40
+ *
41
+ * ## Freshness vs. `staleWhileRevalidate`
42
+ *
43
+ * Freshness is always decided by this class, using the `expiresAt` it records on
44
+ * `set`. In stale-while-revalidate mode L1 is told "never expire" so the stale
45
+ * copy survives to be served while the plugin refreshes it; otherwise L1 is
46
+ * given the real TTL and sweeps the entry itself. L2 always receives the real TTL
47
+ * so a second tab (which has no shared in-memory index) never reads a stale one.
48
+ */
49
+ export declare class CacheManager {
50
+ /** Fully resolved options, exposed so the plugin can apply the same policy. */
51
+ readonly options: ResolvedCacheOptions;
52
+ private readonly l1;
53
+ private readonly logger;
54
+ /** key → absolute expiry timestamp in ms; `0` means "never expires". */
55
+ private readonly expiry;
56
+ /** tag → every key carrying it. */
57
+ private readonly tagIndex;
58
+ /** key → every tag it carries, so a delete can unindex it in O(tags). */
59
+ private readonly keyTags;
60
+ /** Cache key → the promise of the request currently being sent for it. */
61
+ private readonly flight;
62
+ constructor(options?: CacheManagerOptions);
63
+ /** Number of live **L1** entries. L2 is not enumerated, by design. */
64
+ get size(): number;
65
+ /**
66
+ * Read a fresh value.
67
+ *
68
+ * A stale entry (kept alive only for stale-while-revalidate) is *not* returned:
69
+ * callers that must serve staleness ask {@link lookup} explicitly, so the
70
+ * common path cannot accidentally serve expired data.
71
+ */
72
+ get<T = unknown>(key: string): Promise<T | undefined>;
73
+ /** `true` when a fresh value is stored under `key`. */
74
+ has(key: string): Promise<boolean>;
75
+ /**
76
+ * Read a value together with its freshness.
77
+ *
78
+ * `allowStale` is the plugin's `staleWhileRevalidate` switch: when the entry is
79
+ * past its TTL but still resident, it is returned with `stale: true` so the
80
+ * caller can serve it now and refresh afterwards.
81
+ */
82
+ lookup<T = unknown>(key: string, allowStale?: boolean): Promise<CacheLookup<T> | undefined>;
83
+ /**
84
+ * Store a value in L1 and L2.
85
+ *
86
+ * `ttlSeconds` defaults to the configured TTL and `tags` may be empty; a tag
87
+ * written here is what `@Invalidates("tag")` later purges.
88
+ */
89
+ set(key: string, value: unknown, ttlSeconds?: number, tags?: readonly string[]): Promise<void>;
90
+ /** Remove one entry from every layer. */
91
+ delete(key: string): Promise<void>;
92
+ /** Remove every entry this manager can see. */
93
+ clear(): Promise<void>;
94
+ /**
95
+ * Purge every entry carrying any of `tags`.
96
+ *
97
+ * Used by `@Invalidates(...)` / `@HitSource(...)` after a successful request.
98
+ * Keys are collected first because deleting mutates the tags they came from.
99
+ */
100
+ invalidateTags(tags: readonly string[]): Promise<void>;
101
+ /** Alias of {@link clear}, spelled the way `@Invalidates("*")`-style callers expect. */
102
+ invalidateAll(): Promise<void>;
103
+ /** The promise of the request currently being sent for `key`, if any. */
104
+ getInFlight(key: string): Promise<unknown> | undefined;
105
+ /**
106
+ * Publish the promise of the request being sent for `key`.
107
+ *
108
+ * The entry removes itself when the promise settles, so a rejected shared
109
+ * promise cannot be picked up by a later, unrelated request. The rejection is
110
+ * also marked as observed: a leader that fails with no follower waiting would
111
+ * otherwise surface as an unhandled rejection in Node.
112
+ */
113
+ setInFlight(key: string, promise: Promise<unknown>): void;
114
+ private readL1;
115
+ private readL2;
116
+ private writeL1;
117
+ private writeL2;
118
+ private markExpiry;
119
+ private isStale;
120
+ private rememberTags;
121
+ private forgetKey;
122
+ private warnL2;
123
+ }
124
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { AxiosResponse, InternalAxiosRequestConfig } from "axios";
2
+ import type { SnailPluginObject } from "../../typings/plugin.js";
3
+ import { CacheManager } from "./manager.js";
4
+ import type { CacheOptions } from "./type.js";
5
+ /**
6
+ * The cache plugin.
7
+ *
8
+ * ## Where it sits in the pipeline
9
+ *
10
+ * `priority: -100` is the reserved cache band, which buys two things the contract
11
+ * spells out in `docs/guide/plugin-lifecycle.md` §2.2:
12
+ *
13
+ * - **last in forward order** — the interceptor (`100`) and every argument
14
+ * decorator have already run, so `ctx.request` holds the final url, params and
15
+ * body when the key is built. Hashing an earlier shape would key two different
16
+ * requests identically (or one request twice).
17
+ * - **first in unwind order** — the raw envelope is stored before the validation
18
+ * and transformation plugins touch it, so a hit replays exactly what the server
19
+ * sent rather than a processed derivative.
20
+ *
21
+ * ## Stores what the server sent
22
+ *
23
+ * The entry holds `ctx.response.data`, not the `SnailResult`. The result is a
24
+ * projection of the envelope onto the caller's envelope schema; caching it would
25
+ * freeze one server's key names into another's cache.
26
+ */
27
+ /** Plugin name; also the identity used by `Service.use()` / `Service.remove()`. */
28
+ export declare const CACHE_PLUGIN_NAME = "cache";
29
+ /** The reserved cache priority band (see `docs/guide/plugin-lifecycle.md` §2.1). */
30
+ export declare const CACHE_PRIORITY = -100;
31
+ /** The plugin object plus the manager behind it. */
32
+ export interface CachePlugin extends SnailPluginObject<CacheOptions> {
33
+ /**
34
+ * The storage engine, available once the plugin has been installed by
35
+ * `Service.use(...)` — `install` is where the server name (the default key
36
+ * prefix) and the resolved log level become known.
37
+ */
38
+ readonly manager: CacheManager | undefined;
39
+ }
40
+ /**
41
+ * Create the cache plugin.
42
+ *
43
+ * ```ts
44
+ * const cache = Cache({ ttl: 30, l2: "localStorage" });
45
+ * Service.use(cache);
46
+ * await cache.manager?.invalidateAll();
47
+ * ```
48
+ */
49
+ export declare function Cache(options?: CacheOptions): CachePlugin;
50
+ /**
51
+ * Wrap a cached body into the axios response a plugin must hand back.
52
+ *
53
+ * `headers` is empty on purpose: the stored entry is only the body, and inventing
54
+ * headers would make downstream plugins react to values the server never sent.
55
+ * `config` is the live request, so anything reading `response.config` sees the
56
+ * request that produced the hit.
57
+ *
58
+ * The body is **copied**. Without that, the object handed to the caller would be
59
+ * the very object the cache holds, so one `result.data.name = "x"` would silently
60
+ * rewrite the cache entry — and, worse, a response transformer that hydrates the
61
+ * payload in place would corrupt the stored value for every later hit.
62
+ */
63
+ export declare function makeCachedResponse<T>(body: T, config: InternalAxiosRequestConfig): AxiosResponse<T>;
64
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAOvE,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIzE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,oFAAoF;AACpF,eAAO,MAAM,cAAc,OAAO,CAAC;AAoBnC,oDAAoD;AACpD,MAAM,WAAW,WAAY,SAAQ,iBAAiB,CAAC,YAAY,CAAC;IAClE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CA4CzD;AA4LD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,0BAA0B,GACjC,aAAa,CAAC,CAAC,CAAC,CAQlB"}
@@ -0,0 +1,116 @@
1
+ import type { SnailMethodType } from "../../typings/api.js";
2
+ /**
3
+ * Shared shapes of the cache plugin.
4
+ *
5
+ * The design splits into three layers, each with one job:
6
+ *
7
+ * - a **decorator** says what to do (`@Cacheable`, `@NoCache`, `@Invalidates`),
8
+ * - the **plugin** turns that metadata plus the cache options into a per-request
9
+ * plan, and
10
+ * - a **`CacheManager`** owns storage: L1, optional L2, TTL, LRU and tag index.
11
+ */
12
+ /**
13
+ * A persistent (or at least outliving) cache store — "L2".
14
+ *
15
+ * Every method is asynchronous on purpose. `localStorage` is synchronous and
16
+ * IndexedDB is not; forcing the synchronous one to pretend does not cost
17
+ * anything, while letting an async store pretend to be synchronous is impossible.
18
+ * IndexedDB therefore needs no special case anywhere in the plugin.
19
+ *
20
+ * An implementation must never throw for a missing environment — the built-in
21
+ * IndexedDB and Web Storage adapters degrade to no-ops — but the manager guards
22
+ * the calls anyway, because a quota error (`QuotaExceededError`) is a normal
23
+ * outcome that must not fail the request.
24
+ */
25
+ export interface CacheAdapter {
26
+ /** Read a value. `undefined` means "not stored" or "expired". */
27
+ get<T = unknown>(key: string): Promise<T | undefined>;
28
+ /** Store a value. `ttlSeconds <= 0` means "no expiry". */
29
+ set(key: string, value: unknown, ttlSeconds: number): Promise<void>;
30
+ /** Remove one key. Removing an absent key is not an error. */
31
+ delete(key: string): Promise<void>;
32
+ /** Remove everything this adapter owns. */
33
+ clear(): Promise<void>;
34
+ /**
35
+ * Every key currently stored, when the backend can enumerate them.
36
+ *
37
+ * Optional because a custom adapter may front a store that cannot list keys
38
+ * (an HTTP cache, for example). The plugin never requires it; it exists for
39
+ * maintenance tooling and for tests.
40
+ */
41
+ keys?(): Promise<string[]>;
42
+ }
43
+ /** Options accepted by `Cache(...)`. */
44
+ export interface CacheOptions {
45
+ /**
46
+ * Entry lifetime in seconds. Default 60.
47
+ *
48
+ * Must be positive; a zero, negative or non-finite value falls back to the
49
+ * default rather than silently storing an entry that never expires.
50
+ */
51
+ ttl?: number;
52
+ /**
53
+ * L1 LRU capacity. Default 100.
54
+ *
55
+ * A non-positive value also means 100 — an unbounded in-memory cache is a leak
56
+ * with extra steps, so it is not reachable by accident.
57
+ */
58
+ maxSize?: number;
59
+ /** L1 on/off. Default true. */
60
+ l1?: boolean;
61
+ /**
62
+ * L2 store.
63
+ *
64
+ * A string selects a built-in adapter and resolves its global lazily; an
65
+ * object is used as-is. When the selected environment global is missing
66
+ * (Node has neither `localStorage` nor `indexedDB`), the plugin warns once and
67
+ * continues with L1 only instead of throwing.
68
+ */
69
+ l2?: "localStorage" | "sessionStorage" | "indexedDB" | CacheAdapter;
70
+ /** Which verbs are cacheable. Default `["GET"]`. Accepts `"all"`. */
71
+ cacheFor?: "all" | SnailMethodType | SnailMethodType[];
72
+ /** Key prefix, defaults to the server name. */
73
+ prefix?: string;
74
+ /** Serve a stale entry immediately and refresh in the background. Default false. */
75
+ staleWhileRevalidate?: boolean;
76
+ /** Collapse concurrent identical requests into one. Default true. */
77
+ dedupe?: boolean;
78
+ }
79
+ /**
80
+ * Options accepted by `@Cacheable(...)`.
81
+ *
82
+ * Passing this decorator is an explicit opt-in: a method (or every method of a
83
+ * class) marked with it is cached even for a verb that `cacheFor` does not list.
84
+ * Without it, `cacheFor` decides.
85
+ */
86
+ export interface CacheableOptions {
87
+ /**
88
+ * Entry lifetime in seconds for this target, overriding `CacheOptions.ttl`.
89
+ *
90
+ * Per-target rather than per-call because the decorator is static metadata: a
91
+ * method that needs a different lifetime for different arguments wants two
92
+ * methods.
93
+ */
94
+ ttl?: number;
95
+ /**
96
+ * Tags attached to the stored entry, so `@Invalidates("tag")` can purge it
97
+ * without knowing its key.
98
+ */
99
+ tags?: readonly string[];
100
+ /**
101
+ * Explicit cache key, bypassing the method/url/params/body hash.
102
+ *
103
+ * Every call of that method then shares one entry. Reach for it when the
104
+ * request has volatile parts that must not take part in the identity — a
105
+ * nonce, a timestamp — and accept that those parts are ignored.
106
+ */
107
+ key?: string;
108
+ }
109
+ /** One cached value plus its freshness, as returned by `CacheManager.lookup`. */
110
+ export interface CacheLookup<T = unknown> {
111
+ /** The stored body. */
112
+ value: T;
113
+ /** `true` when the entry is past its TTL but was kept for `staleWhileRevalidate`. */
114
+ stale: boolean;
115
+ }
116
+ //# sourceMappingURL=type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache/type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;;;GASG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEtD,0DAA0D;IAC1D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE,8DAA8D;IAC9D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,2CAA2C;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC5B;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,+BAA+B;IAC/B,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb;;;;;;;OAOG;IACH,EAAE,CAAC,EAAE,cAAc,GAAG,gBAAgB,GAAG,WAAW,GAAG,YAAY,CAAC;IAEpE,qEAAqE;IACrE,QAAQ,CAAC,EAAE,KAAK,GAAG,eAAe,GAAG,eAAe,EAAE,CAAC;IAEvD,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oFAAoF;IACpF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEzB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,iFAAiF;AACjF,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,uBAAuB;IACvB,KAAK,EAAE,CAAC,CAAC;IAET,qFAAqF;IACrF,KAAK,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `@snail-js/api/plugins` — the built-in optional plugins.
3
+ *
4
+ * ```ts
5
+ * import {
6
+ * Cache,
7
+ * Cacheable,
8
+ * Invalidates,
9
+ * Interceptor,
10
+ * BeforeRequest,
11
+ * Versioning,
12
+ * Version,
13
+ * Validate,
14
+ * Transform
15
+ * } from "@snail-js/api/plugins";
16
+ *
17
+ * Service
18
+ * .use(Interceptor())
19
+ * .use(Versioning({ type: "header", defaultVersion: "1.0.0" }))
20
+ * .use(Validate())
21
+ * .use(Transform())
22
+ * .use(Cache({ ttl: 60, l2: "localStorage" }));
23
+ * ```
24
+ *
25
+ * ## Why this is a separate entry point
26
+ *
27
+ * Nothing here is in the core. Keeping the plugins behind `@snail-js/api/plugins`
28
+ * means an application that imports only the root entry pays for none of it — no
29
+ * cache, no validation and no JSON→class hydration. Each plugin lives in its own
30
+ * directory with its own barrel, so a bundler can drop the ones a given app never
31
+ * calls.
32
+ *
33
+ * ## The framework adapters are *not* here
34
+ *
35
+ * `VueAdapter` and `ReactAdapter` live behind their own subpaths:
36
+ *
37
+ * ```ts
38
+ * import { VueAdapter } from "@snail-js/api/plugins/vue";
39
+ * import { ReactAdapter } from "@snail-js/api/plugins/react";
40
+ * ```
41
+ *
42
+ * They are kept out of this barrel deliberately. A re-export would make this
43
+ * module statically import both `vue` and `react`, so a React application that
44
+ * only wanted `Cache` would fail to resolve `vue` at all — and a framework-free
45
+ * one would pull both frameworks into its bundle. Separate subpaths keep the
46
+ * optional peers genuinely optional.
47
+ *
48
+ * ## Registration order does not matter
49
+ *
50
+ * Plugins are ordered by `priority`, not by the order `use()` was called in:
51
+ *
52
+ * | Priority | Plugin |
53
+ * | --- | --- |
54
+ * | `100` | interceptor |
55
+ * | `50` | versioning |
56
+ * | `0` | framework adapter, transform |
57
+ * | `-50` | validate |
58
+ * | `-100` | cache |
59
+ * | `-150` | request pool |
60
+ *
61
+ * Forward hooks run highest-priority first, so the interceptor sees the request
62
+ * before the cache hashes it and the pool — dead last — only ever gates requests
63
+ * the cache could not answer. Unwind hooks run in the opposite direction, so the
64
+ * cache stores the raw envelope before validation and transformation touch it.
65
+ * See `docs/guide/plugin-lifecycle.md` §2.1 for the reasoning.
66
+ *
67
+ * @packageDocumentation
68
+ */
69
+ export * from "./cache/index.js";
70
+ export * from "./interceptor/index.js";
71
+ export * from "./pool/index.js";
72
+ export * from "./transform/index.js";
73
+ export * from "./validate/index.js";
74
+ export * from "./version/index.js";
75
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}