@snail-js/api 0.1.28 → 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 -4871
  296. package/dist/snail-api.umd.cjs +0 -4875
  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,28 @@
1
+ import type { SnailHttpStreamConnection, SnailHttpStreamOptions } from "../typings/stream.js";
2
+ import type { SnailLogger } from "./logger.js";
3
+ /** Everything the HTTP streaming transport needs. */
4
+ export interface HttpStreamInit {
5
+ /** Fully qualified url. */
6
+ url: string;
7
+ /** Options from `@HttpStream(path, options)` with its request method. */
8
+ options: SnailHttpStreamOptions & {
9
+ method?: string;
10
+ };
11
+ /** Request payload. */
12
+ body: unknown;
13
+ /** Name used in log lines. */
14
+ name: string;
15
+ /** Extra headers (server-level, auth, …). */
16
+ headers?: Record<string, string>;
17
+ /** Logger. */
18
+ logger: SnailLogger;
19
+ }
20
+ /**
21
+ * Streaming HTTP response.
22
+ *
23
+ * Uses `fetch` so the response body arrives as a `ReadableStream`, which works
24
+ * in browsers, Node 18+ and workers alike. The connection object is itself
25
+ * async-iterable, so callers write `for await (const chunk of stream)`.
26
+ */
27
+ export declare function createHttpStream(init: HttpStreamInit): SnailHttpStreamConnection;
28
+ //# sourceMappingURL=http-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-stream.d.ts","sourceRoot":"","sources":["../../src/core/http-stream.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,OAAO,EAAE,sBAAsB,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,uBAAuB;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc;IACd,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,yBAAyB,CAwJhF"}
@@ -0,0 +1,22 @@
1
+ import type { SnailLogLevel } from "../typings/server.js";
2
+ /**
3
+ * Level-gated logger.
4
+ *
5
+ * The pre-rewrite code called bare `console.log` from the middle of the request
6
+ * pipeline, which made a request library noisy by default and impossible to
7
+ * silence. Every diagnostic now goes through a logger whose level comes from
8
+ * `@Server({ logLevel })`, and the default level is `"silent"`.
9
+ */
10
+ export interface SnailLogger {
11
+ /** Active level. */
12
+ readonly level: SnailLogLevel;
13
+ /** `true` when a message at `level` would be printed. */
14
+ enabled(level: Exclude<SnailLogLevel, "silent">): boolean;
15
+ error(message: string, ...rest: unknown[]): void;
16
+ warn(message: string, ...rest: unknown[]): void;
17
+ info(message: string, ...rest: unknown[]): void;
18
+ debug(message: string, ...rest: unknown[]): void;
19
+ }
20
+ /** Create a logger honouring `@Server({ logLevel })`. */
21
+ export declare function createLogger(level?: SnailLogLevel): SnailLogger;
22
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,yDAAyD;IACzD,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC;IAC1D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,KAAK,GAAE,aAAwB,GAAG,WAAW,CAqBzE"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * A dependency-free replacement for `reflect-metadata`.
3
+ *
4
+ * ## Why not `reflect-metadata`?
5
+ *
6
+ * TypeScript 7 dropped the ability to emit `design:*` metadata: enabling
7
+ * `emitDecoratorMetadata` is accepted but silently emits nothing (verified
8
+ * against `tsc` 7.0.2 — the `__metadata` helper is emitted, the calls are not).
9
+ * That removes the only capability `reflect-metadata` ever provided to this
10
+ * library: we have never needed inferred constructor parameter types, only the
11
+ * metadata our *own* decorators write.
12
+ *
13
+ * Dropping it buys three things:
14
+ * 1. no runtime polyfill to install or import at the app entry point;
15
+ * 2. one fewer entry in `dependencies` — axios stays the only one;
16
+ * 3. deterministic behaviour on every runtime (browser, Node, worker, edge)
17
+ * because the polyfill's `Reflect.defineMetadata` is not involved at all.
18
+ *
19
+ * Legacy decorators (`experimentalDecorators: true`) and parameter decorators
20
+ * remain fully supported by TypeScript 7.
21
+ *
22
+ * ## Storage model
23
+ *
24
+ * ```text
25
+ * WeakMap<owner, Map<slot, Map<key, value>>>
26
+ * │ └── the decorator's symbol key
27
+ * └── CLASS_SLOT for class metadata, else the method name
28
+ * ```
29
+ *
30
+ * `owner` is always a *class* (constructor function). A decorator applied to a
31
+ * method or parameter receives the prototype, so {@link resolveOwner} maps it
32
+ * back to the class.
33
+ *
34
+ * ## Decorator application order (important)
35
+ *
36
+ * For `@Api("/u") class U { @Get() list(@Query("a") a: string) {} }` the
37
+ * runtime order is:
38
+ *
39
+ * ```text
40
+ * 1. parameter decorators (reverse index order)
41
+ * 2. method decorators
42
+ * 3. class decorators
43
+ * ```
44
+ *
45
+ * Every writer below therefore *merges*; none of them may clobber an existing
46
+ * value. Array-shaped metadata is appended, never replaced.
47
+ */
48
+ /**
49
+ * Normalise whatever a decorator receives into the class that owns the metadata.
50
+ *
51
+ * - class decorator → the constructor itself
52
+ * - method / parameter decorator → `prototype.constructor`
53
+ * - a bare prototype passed by hand → `prototype.constructor`
54
+ */
55
+ export declare function resolveOwner(target: unknown): object;
56
+ /**
57
+ * Write metadata, replacing any value previously written for the same
58
+ * (owner, slot, key) triple.
59
+ */
60
+ export declare function defineMetadata(key: symbol, value: unknown, target: unknown, propertyKey?: PropertyKey): void;
61
+ /** Read metadata from exactly this owner, ignoring the prototype chain. */
62
+ export declare function getOwnMetadata<T = unknown>(key: symbol, target: unknown, propertyKey?: PropertyKey): T | undefined;
63
+ /**
64
+ * Read metadata, walking the class prototype chain so a base api class or a base
65
+ * server class can supply defaults to its subclasses.
66
+ */
67
+ export declare function getMetadata<T = unknown>(key: symbol, target: unknown, propertyKey?: PropertyKey): T | undefined;
68
+ /** `true` when {@link getMetadata} would find something. */
69
+ export declare function hasMetadata(key: symbol, target: unknown, propertyKey?: PropertyKey): boolean;
70
+ /**
71
+ * Append to array-shaped metadata, always creating a fresh array.
72
+ *
73
+ * Copy-on-write matters: several decorators legitimately contribute to one key
74
+ * (four `@Query()` parameters, a class-level `@Header()` plus a method-level
75
+ * one) and the array must never be shared with a base class.
76
+ */
77
+ export declare function appendMetadata<T>(key: symbol, value: T, target: unknown, propertyKey?: PropertyKey): void;
78
+ /** Merge a record into record-shaped metadata (class-level `@Header` and friends). */
79
+ export declare function mergeMetadata<T extends object>(key: symbol, value: T, target: unknown, propertyKey?: PropertyKey): void;
80
+ /** Delete metadata from exactly this owner. Returns whether anything was removed. */
81
+ export declare function deleteMetadata(key: symbol, target: unknown, propertyKey?: PropertyKey): boolean;
82
+ /**
83
+ * Collect every method name that carries metadata for `key`, walking the class
84
+ * prototype chain from base to derived so subclasses may override.
85
+ */
86
+ export declare function collectMethodKeys(key: symbol, target: unknown): string[];
87
+ /**
88
+ * Test-only escape hatch: swap the registry for a fresh `WeakMap`. Existing
89
+ * owners become unreachable and are garbage collected.
90
+ */
91
+ export declare function clearMetadataRegistry(): void;
92
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/core/metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AASH;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CASpD;AAwBD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,IAAI,CAEN;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EACxC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,CAAC,GAAG,SAAS,CAEf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,CAAC,GAAG,SAAS,CAUf;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,IAAI,CAGN;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC5C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,CAAC,EACR,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,IAAI,CAGN;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,CAsBxE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Metadata keys used by every `@snail-js/api` decorator.
3
+ *
4
+ * `Symbol.for` is used instead of plain `Symbol()` on purpose: a monorepo can
5
+ * easily end up with two copies of this package (one hoisted for the app, one
6
+ * nested under a dependency). Global symbol registration keeps both copies
7
+ * reading and writing the *same* metadata slots.
8
+ */
9
+ /** `@Server(...)` options, stored on the server class. */
10
+ export declare const SNAIL_SERVER_OPTIONS: unique symbol;
11
+ /** `@Api(...)` options, stored on the api class. */
12
+ export declare const SNAIL_API_OPTIONS: unique symbol;
13
+ /** `@Get(...)` / `@Post(...)` / … options, stored per method. */
14
+ export declare const SNAIL_REQUEST_METHOD: unique symbol;
15
+ /** `@Params()` / `@Query()` / `@Data()` parameter descriptors, stored per method. */
16
+ export declare const SNAIL_PARAMS: unique symbol;
17
+ /** `@Header(...)` records, stored on the api class and per method. */
18
+ export declare const SNAIL_HEADERS: unique symbol;
19
+ /** `@UploadProgress(...)` callback, stored per method. */
20
+ export declare const SNAIL_UPLOAD_PROGRESS: unique symbol;
21
+ /** `@DownloadProgress(...)` callback, stored per method. */
22
+ export declare const SNAIL_DOWNLOAD_PROGRESS: unique symbol;
23
+ /** `@Sse(...)` options, stored on the stream class. */
24
+ export declare const SNAIL_SSE_OPTIONS: unique symbol;
25
+ /** `@SseEvent(...)` / `@OnSseOpen()` / `@OnSseError()` handlers, stored on the stream class. */
26
+ export declare const SNAIL_SSE_HANDLERS: unique symbol;
27
+ /** `@WebSocket(...)` options, stored on the stream class. */
28
+ export declare const SNAIL_WS_OPTIONS: unique symbol;
29
+ /** `@OnWsOpen()` / `@OnWsMessage()` / … handlers, stored on the stream class. */
30
+ export declare const SNAIL_WS_HANDLERS: unique symbol;
31
+ /** `@HttpStream(...)` options, stored per method. */
32
+ export declare const SNAIL_HTTP_STREAM: unique symbol;
33
+ /**
34
+ * Prefix reserved for third-party decorators built with
35
+ * {@link createParamDecorator} and friends.
36
+ *
37
+ * Plugin authors should namespace their key, e.g.
38
+ * `Symbol.for("@acme/snail-plugin:tenant")`, so two plugins can never collide.
39
+ */
40
+ export declare const SNAIL_CUSTOM_KEY_PREFIX = "@snail-js/api:custom:";
41
+ //# sourceMappingURL=metadata.keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.keys.d.ts","sourceRoot":"","sources":["../../src/core/metadata.keys.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,eAA6C,CAAC;AAE/E,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,eAA0C,CAAC;AAEzE,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,eAA6C,CAAC;AAE/E,qFAAqF;AACrF,eAAO,MAAM,YAAY,eAAqC,CAAC;AAE/D,sEAAsE;AACtE,eAAO,MAAM,aAAa,eAAsC,CAAC;AAEjE,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,eAA8C,CAAC;AAEjF,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,eAAgD,CAAC;AAErF,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,eAA0C,CAAC;AAEzE,gGAAgG;AAChG,eAAO,MAAM,kBAAkB,eAA2C,CAAC;AAE3E,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,eAAyC,CAAC;AAEvE,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,eAA0C,CAAC;AAEzE,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,eAA0C,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,0BAA0B,CAAC"}
@@ -0,0 +1,177 @@
1
+ import { AxiosHeaders } from "axios";
2
+ import type { AxiosInstance, InternalAxiosRequestConfig } from "axios";
3
+ import type { SnailApiOptions, SnailMethodOptions, SnailMethodType } from "../typings/api.js";
4
+ import type { SnailParamDescriptor } from "../typings/args.js";
5
+ import type { SnailMeta } from "../typings/meta.js";
6
+ import type { SnailResult } from "../typings/response.js";
7
+ import type { ResolvedServerOptions } from "../typings/server.js";
8
+ import { SnailContext } from "./context.js";
9
+ import type { SnailLogger } from "./logger.js";
10
+ import type { PluginManager } from "./plugin-manager.js";
11
+ import type { SnailServer } from "./server.js";
12
+ /** Payload of the `codeError` event. */
13
+ export interface SnailCodeErrorEvent {
14
+ /** Business status code the backend returned. */
15
+ code: number | string | undefined;
16
+ /** Full parsed envelope. */
17
+ payload: unknown;
18
+ /** The `SnailResponseError` that will be thrown. */
19
+ error: unknown;
20
+ }
21
+ /** Events emitted by a {@link SnailMethod}. */
22
+ export interface SnailMethodEventMap<S, T, D extends string, C extends string, M extends string> {
23
+ success: SnailResult<S, T, D, C, M>;
24
+ error: unknown;
25
+ codeError: SnailCodeErrorEvent;
26
+ finish: undefined;
27
+ cache: undefined;
28
+ }
29
+ /** Everything `SnailMethod` needs, assembled by the proxy in `SnailServer`. */
30
+ export interface SnailMethodInit {
31
+ server: SnailServer<any, any, any, any>;
32
+ pluginManager: PluginManager;
33
+ axios: AxiosInstance;
34
+ apiClass: new () => unknown;
35
+ api: unknown;
36
+ apiName: string;
37
+ apiOptions: Required<SnailApiOptions>;
38
+ serverOptions: ResolvedServerOptions;
39
+ methodName: string;
40
+ methodType: SnailMethodType;
41
+ route: string;
42
+ methodOptions: SnailMethodOptions & {
43
+ url: string;
44
+ };
45
+ descriptors: readonly SnailParamDescriptor[];
46
+ headers: AxiosHeaders;
47
+ logger: SnailLogger;
48
+ /**
49
+ * Builds a fresh axios config for this method.
50
+ *
51
+ * A factory rather than a value: every `send()` must start from a clean config
52
+ * so mutations a plugin made during the previous send do not leak forward.
53
+ */
54
+ requestConfig: () => InternalAxiosRequestConfig;
55
+ }
56
+ /**
57
+ * One pending request.
58
+ *
59
+ * Created by calling a proxied api method — `userApi.getUser("1")` — and sent by
60
+ * calling {@link SnailMethod.send}. Nothing hits the network until `send()`.
61
+ *
62
+ * ## Why the context is built once and reset
63
+ *
64
+ * Framework adapters create the caller's reactive handles in their `initMeta`
65
+ * hook. Those handles must survive every re-send, so the context is constructed
66
+ * once and {@link SnailContext.reset} clears only the per-request fields. Calling
67
+ * `userApi.getUser()` twice would produce two independent sets of refs, which is
68
+ * exactly the bug the old `request()`-returns-fresh-state design had.
69
+ */
70
+ export declare class SnailMethod<S = unknown, T = unknown, D extends string = "data", C extends string = "code", M extends string = "message"> {
71
+ /** `server.api.method`. */
72
+ readonly name: string;
73
+ /** Decorated method name. */
74
+ readonly methodName: string;
75
+ /** Request verb. */
76
+ readonly methodType: SnailMethodType;
77
+ /** Url template before `:placeholder` substitution. */
78
+ readonly route: string;
79
+ /** Arguments this instance was created with. `send(...args)` may override them. */
80
+ readonly args: readonly unknown[];
81
+ /**
82
+ * Caller-visible reactive values created by framework adapters.
83
+ *
84
+ * A live view of `context.meta`, so the handles an adapter created in
85
+ * `initMeta` stay stable across every re-send. Empty when no adapter plugin is
86
+ * installed.
87
+ *
88
+ * `loading` and `error` are typed by the {@link SnailMeta} interface; the
89
+ * envelope handles are named after the server's configured keys, so augment
90
+ * `SnailMeta` to type them.
91
+ */
92
+ get meta(): SnailMeta & Record<string, unknown>;
93
+ /** The live request context. */
94
+ readonly context: SnailContext;
95
+ private readonly init;
96
+ private readonly emitter;
97
+ private controller;
98
+ private inFlight;
99
+ constructor(init: SnailMethodInit, args?: readonly unknown[]);
100
+ /** `true` while a request is in flight. */
101
+ get pending(): boolean;
102
+ /** Result of the most recent successful request. */
103
+ get result(): SnailResult<S, T, D, C, M> | undefined;
104
+ /** Error from the most recent failed request. */
105
+ get error(): unknown;
106
+ /** The final axios config of the most recent request. */
107
+ get request(): InternalAxiosRequestConfig;
108
+ /**
109
+ * Send the request.
110
+ *
111
+ * Any arguments given here replace the ones captured when the method was
112
+ * proxied, which is what lets a strategy own one instance and vary the
113
+ * arguments per call.
114
+ *
115
+ * ## One request in flight at a time
116
+ *
117
+ * A `SnailMethod` owns exactly one context, and that context is what holds the
118
+ * caller's reactive handles. Two overlapping `send()` calls would therefore
119
+ * race over the same `ctx.response`, and the slower response could land in the
120
+ * state the faster one already reported.
121
+ *
122
+ * Starting a second send therefore **aborts the first**, so the previous call
123
+ * rejects with a `SnailCancelledError` and "latest wins" holds. Callers that
124
+ * genuinely want two parallel requests should create two instances —
125
+ * `userApi.getUser("1")` and `userApi.getUser("2")` — which is also what makes
126
+ * the argument types line up.
127
+ */
128
+ send(...args: unknown[]): Promise<SnailResult<S, T, D, C, M>>;
129
+ /**
130
+ * Cancel the in-flight request.
131
+ *
132
+ * `send()` rejects with a {@link SnailCancelledError}, which strategies treat
133
+ * as expected control flow rather than a failure.
134
+ */
135
+ abort(reason?: unknown): void;
136
+ /** Subscribe to a successful request. Returns an unsubscribe function. */
137
+ onSuccess(listener: (result: SnailResult<S, T, D, C, M>) => void): () => void;
138
+ /** Subscribe to a failed request. */
139
+ onError(listener: (error: unknown) => void): () => void;
140
+ /**
141
+ * Subscribe to a rejected business code.
142
+ *
143
+ * Observation only: the request still rejects with a `SnailResponseError`, so
144
+ * this is the right place to raise a toast, not to recover.
145
+ */
146
+ onCodeError(listener: (event: SnailCodeErrorEvent) => void): () => void;
147
+ /** Subscribe to settlement, successful or not. */
148
+ onFinish(listener: () => void): () => void;
149
+ /** Subscribe to a response served from a cache. */
150
+ onHitCache(listener: () => void): () => void;
151
+ /** Reset the context for a fresh send, superseding any request already in flight. */
152
+ private begin;
153
+ /**
154
+ * The transport step.
155
+ *
156
+ * Runs only when every `beforeRequest` hook called `next()`, i.e. only when the
157
+ * response has to come from the network. The `afterResponse` chain is *not* here
158
+ * — see {@link SnailMethod.send} for why it has to run on a cache hit too.
159
+ */
160
+ private dispatch;
161
+ /** Validate the envelope and assemble the caller-facing result. */
162
+ private finalize;
163
+ /** Report a failure through the plugin hooks and the events, then rethrow it. */
164
+ private fail;
165
+ /**
166
+ * Turn axios' error vocabulary into ours.
167
+ *
168
+ * The rule is: **if the server answered, hand back axios' error unchanged** —
169
+ * it carries `response.status` and `response.data`, which applications and the
170
+ * auth strategies both branch on. Only when no response exists at all (DNS
171
+ * failure, offline, CORS rejection) is there nothing useful to preserve, so
172
+ * that case becomes a typed {@link SnailHttpError} with the axios error as its
173
+ * `cause`.
174
+ */
175
+ private normalizeTransportError;
176
+ }
177
+ //# sourceMappingURL=method.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method.d.ts","sourceRoot":"","sources":["../../src/core/method.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import type { SnailPluginObject } from "../typings/plugin.js";
2
+ import type { ResolvedServerOptions } from "../typings/server.js";
3
+ import { type BoundHook } from "./plugin.js";
4
+ /** A plugin registered on one server. */
5
+ export interface RegisteredPlugin {
6
+ /** Plugin name. */
7
+ readonly name: string;
8
+ /** Chain ordering weight; higher runs first in the forward phase. */
9
+ readonly priority: number;
10
+ /** Registration sequence, used as a stable tie-breaker. */
11
+ readonly index: number;
12
+ /** The plugin object itself. */
13
+ readonly instance: SnailPluginObject<any>;
14
+ }
15
+ /**
16
+ * Per-server plugin registry.
17
+ *
18
+ * ## Why this is not a singleton
19
+ *
20
+ * The pre-rewrite implementation kept one global manager plus a mutable
21
+ * `_server` pointer that every caller had to set with `switchServer()` before
22
+ * `getHooks()`. Any two servers in flight — or simply two interleaved `await`s —
23
+ * silently read the *wrong* server's plugins. Each `SnailServer` now owns its
24
+ * own manager and passes its name in the constructor, so that class of bug is
25
+ * unrepresentable.
26
+ *
27
+ * ## Ordering
28
+ *
29
+ * Plugins sort by `priority` descending, ties broken by registration order.
30
+ *
31
+ * - **Forward hooks** run highest-priority first, so an interceptor (`100`)
32
+ * installs before the cache (`-100`).
33
+ * - **Unwind hooks** run in the opposite direction, closing the onion: the
34
+ * plugin closest to the network reacts to the response first.
35
+ *
36
+ * ## Sync registration, async install
37
+ *
38
+ * `register()` is synchronous and returns immediately, so `Service.use(A).use(B)`
39
+ * chains naturally while a `dependsOn` mistake still throws on the spot. The
40
+ * `install` hooks themselves may be async; {@link PluginManager.ready} is awaited
41
+ * once per request, before any plugin hook runs.
42
+ */
43
+ export declare class PluginManager {
44
+ private readonly serverName;
45
+ private readonly serverOptions;
46
+ private readonly registry;
47
+ private readonly order;
48
+ private readonly installTasks;
49
+ private sequence;
50
+ constructor(serverName: string, serverOptions: ResolvedServerOptions);
51
+ /** Number of registered plugins. */
52
+ get size(): number;
53
+ /** Resolves once every `install` hook has settled. */
54
+ get ready(): Promise<void>;
55
+ /** `true` when a plugin with this name is registered. */
56
+ has(name: string): boolean;
57
+ /** Read one registered plugin. */
58
+ get(name: string): RegisteredPlugin | undefined;
59
+ /** Registered plugin names in chain order (forward phase). */
60
+ names(): string[];
61
+ /** All registered plugins in chain order (forward phase). */
62
+ list(): RegisteredPlugin[];
63
+ /**
64
+ * Validate and register a plugin. Synchronous by design.
65
+ *
66
+ * Throws {@link SnailPluginError} for a nameless plugin, a duplicate name or
67
+ * an unsatisfied `dependsOn` — all before anything is mutated.
68
+ */
69
+ register(plugin: SnailPluginObject<any>): void;
70
+ /** Unregister a plugin, running its `uninstall` hook first. */
71
+ remove(name: string): Promise<void>;
72
+ /** Remove every plugin, unwinding in reverse registration order. */
73
+ clear(): Promise<void>;
74
+ /**
75
+ * Sorted plugin list.
76
+ *
77
+ * `"forward"` → priority descending (highest first).
78
+ * `"unwind"` → priority ascending (highest last).
79
+ */
80
+ sorted(direction: "forward" | "unwind"): RegisteredPlugin[];
81
+ /** Hooks of one name, in the direction that hook traverses. */
82
+ hooks(hookName: string): BoundHook[];
83
+ /** `true` when at least one plugin implements `hookName`. */
84
+ hasHook(hookName: string): boolean;
85
+ /**
86
+ * Run a chain hook over every plugin, then `downstream`.
87
+ *
88
+ * A plugin that never calls `next()` stops the chain: `downstream` (for
89
+ * `beforeRequest`, the HTTP request itself) never runs. That is the mechanism
90
+ * behind a cache hit.
91
+ */
92
+ runChain(hookName: string, ctx: unknown, downstream?: () => Promise<void> | void): Promise<void>;
93
+ /** Run a non-chain hook over every plugin, sequentially and awaited. */
94
+ runEffects(hookName: string, ...args: unknown[]): Promise<void>;
95
+ /** Run a non-chain hook synchronously — for constructor-time hooks. */
96
+ runEffectsSync(hookName: string, ...args: unknown[]): void;
97
+ /**
98
+ * Fold a value through every plugin's hook.
99
+ *
100
+ * Used by `requestInterceptor` / `responseInterceptor`, where each plugin may
101
+ * return a replacement for the value it received. Returning `undefined` keeps
102
+ * the previous value.
103
+ */
104
+ reduce<T>(hookName: string, initial: T, ...args: unknown[]): T;
105
+ }
106
+ //# sourceMappingURL=plugin-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-manager.d.ts","sourceRoot":"","sources":["../../src/core/plugin-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA6B,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAqBxD,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAPhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA4B;IACzD,OAAO,CAAC,QAAQ,CAAK;IAErB,YACmB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,qBAAqB,EACnD;IAEJ,oCAAoC;IACpC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,sDAAsD;IACtD,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzB;IAED,yDAAyD;IACzD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzB;IAED,kCAAkC;IAClC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAE9C;IAED,8DAA8D;IAC9D,KAAK,IAAI,MAAM,EAAE,CAEhB;IAED,6DAA6D;IAC7D,IAAI,IAAI,gBAAgB,EAAE,CAEzB;IAED;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,GAAG,IAAI,CAuE7C;IAED,+DAA+D;IACzD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBxC;IAED,oEAAoE;IAC9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAI3B;IAED;;;;;OAKG;IACH,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,gBAAgB,EAAE,CAU1D;IAED,+DAA+D;IAC/D,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAgBnC;IAED,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQjC;IAED;;;;;;OAMG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,OAAO,EACZ,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC,CAOf;IAED,wEAAwE;IAClE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE;IAED,uEAAuE;IACvE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAIzD;IAED;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAO7D;CACF"}
@@ -0,0 +1,113 @@
1
+ import type { SnailMessages } from "../locale/types.js";
2
+ import type { SnailParamResolver } from "../typings/args.js";
3
+ import type { SnailPlugin, SnailPluginObject } from "../typings/plugin.js";
4
+ import type { ResolvedServerOptions } from "../typings/server.js";
5
+ /**
6
+ * Plugin machinery.
7
+ *
8
+ * ## Everything is a plugin
9
+ *
10
+ * The core ships *no* optional behaviour: caching, versioning, interceptors,
11
+ * validation, transformation and framework adapters are all plugins. Core owns
12
+ * exactly three things — the metadata written by decorators, the request
13
+ * pipeline, and this plugin lifecycle.
14
+ *
15
+ * ## Two kinds of hook
16
+ *
17
+ * - **Chain hooks** (`beforeRequest`, `afterResponse`) are Koa-style middleware:
18
+ * a hook receives `next`, may `await` it, and may decline to call it to stop
19
+ * the request. This is what makes cross-cutting concerns composable.
20
+ * - **Effect hooks** (`initMeta`, `beforeCreate`, `onError`, `afterRequest`) run
21
+ * sequentially and cannot influence control flow.
22
+ */
23
+ /** Identity helper that preserves the option type of a plugin factory. */
24
+ export declare function definePlugin<O = unknown>(factory: SnailPlugin<O>): SnailPlugin<O>;
25
+ /** Building blocks handed to a plugin's `setup` function. */
26
+ export interface PluginSetupApi {
27
+ /** Name of the server this plugin was installed on. */
28
+ readonly serverName: string;
29
+ /** Fully resolved server options. */
30
+ readonly serverOptions: ResolvedServerOptions;
31
+ /** Names of the plugins registered before this one. */
32
+ readonly installedPlugins: readonly string[];
33
+ /**
34
+ * Register a custom parameter source usable as `@Source("key")`.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * api.defineParamSource("tenant", ({ ctx, value }) => {
39
+ * ctx.request.headers.set("x-tenant", String(value));
40
+ * });
41
+ * ```
42
+ */
43
+ defineParamSource(source: string, resolver: SnailParamResolver): void;
44
+ /** Contribute translated messages for this plugin's own error output. */
45
+ addMessages(messages: SnailMessages): void;
46
+ /** Register cleanup to run when the plugin is uninstalled. */
47
+ onDispose(dispose: () => void | Promise<void>): void;
48
+ }
49
+ /** Declarative description accepted by {@link createPlugin}. */
50
+ export interface PluginDefinition<O, Hooks extends object> {
51
+ /** Unique plugin name. */
52
+ readonly name: string;
53
+ /** Execution order inside a chain; higher runs first. Defaults to `0`. */
54
+ readonly priority?: number;
55
+ /** Plugin names that must be registered first. */
56
+ readonly dependsOn?: readonly string[];
57
+ /**
58
+ * Runs once per server, at install time.
59
+ *
60
+ * Use it to register parameter sources, add messages, seed state or capture
61
+ * options in a closure. Return the lifecycle hooks.
62
+ */
63
+ readonly setup?: (options: O, api: PluginSetupApi) => Hooks | void;
64
+ }
65
+ /** The lifecycle hooks a plugin may return, excluding registration plumbing. */
66
+ export type PluginHooks = Omit<SnailPluginObject, "name" | "priority" | "dependsOn" | "install" | "uninstall">;
67
+ /**
68
+ * Create a third-party plugin.
69
+ *
70
+ * This is the supported entry point for plugin authors. It validates the name,
71
+ * wires `install`/`uninstall`, exposes a scoped {@link PluginSetupApi} and keeps
72
+ * the hook object fully typed.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * interface TraceOptions { header?: string }
77
+ *
78
+ * export const Trace = createPlugin<TraceOptions, { onSend?: (url: string) => void }>({
79
+ * name: "trace",
80
+ * priority: 20,
81
+ * setup(options, api) {
82
+ * const header = options?.header ?? "x-trace-id";
83
+ * api.addMessages({ "trace.missing": "trace header %s is missing" });
84
+ * return {
85
+ * beforeRequest(ctx) {
86
+ * ctx.request.headers.set(header, crypto.randomUUID());
87
+ * }
88
+ * };
89
+ * }
90
+ * });
91
+ *
92
+ * Service.use(Trace({ header: "x-trace-id" }));
93
+ * ```
94
+ */
95
+ export declare function createPlugin<O = void, Hooks extends object = PluginHooks>(definition: PluginDefinition<O, Hooks>): SnailPlugin<O>;
96
+ /** One hook bound to the plugin that owns it. */
97
+ export interface BoundHook {
98
+ readonly pluginName: string;
99
+ readonly hook: (...args: any[]) => any;
100
+ }
101
+ /**
102
+ * Compose chain hooks into a single Koa-style function.
103
+ *
104
+ * The returned function runs `entries[0]` first (they are pre-sorted by the
105
+ * manager), handing each hook a `next` that advances the chain. When the chain
106
+ * is exhausted, `downstream` runs — that is where the manager splices in the
107
+ * actual HTTP request between `beforeRequest` and `afterResponse`.
108
+ *
109
+ * Calling `next()` twice from one hook throws {@link SnailHookError}; without
110
+ * that guard the second call silently re-runs the rest of the chain.
111
+ */
112
+ export declare function composeChain(hookName: string, entries: readonly BoundHook[]): (ctx: unknown, downstream?: () => Promise<void> | void) => Promise<void>;
113
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/core/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAEV,WAAW,EAEX,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAK/D;;;;;;;;;;;;;;;;;GAiBG;AAEH,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAEjF;AAED,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,qCAAqC;IACrC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAE9C,uDAAuD;IACvD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAE7C;;;;;;;;;OASG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAEtE,yEAAyE;IACzE,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAE3C,8DAA8D;IAC9D,SAAS,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD;AAED,gEAAgE;AAChE,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM;IACvD,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,kDAAkD;IAClD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEvC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,cAAc,KAAK,KAAK,GAAG,IAAI,CAAC;CACpE;AAED,gFAAgF;AAChF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC;AAE/G;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,SAAS,MAAM,GAAG,WAAW,EACvE,UAAU,EAAE,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC,GACrC,WAAW,CAAC,CAAC,CAAC,CA6ChB;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;CACxC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,SAAS,SAAS,EAAE,GAC5B,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAqC1E"}
@@ -0,0 +1,22 @@
1
+ import type { SnailReconnectPolicy } from "../typings/stream.js";
2
+ /** A reconnect policy with every default applied. */
3
+ export type ResolvedReconnectPolicy = Required<SnailReconnectPolicy>;
4
+ /** Defaults used when a transport enables reconnecting without a policy. */
5
+ export declare const DEFAULT_RECONNECT_POLICY: ResolvedReconnectPolicy;
6
+ /**
7
+ * Normalise the `reconnect` option.
8
+ *
9
+ * Returns `undefined` when reconnecting is switched off, so callers can branch on
10
+ * a single falsy check instead of handling `false | undefined | policy`.
11
+ */
12
+ export declare function resolveReconnectPolicy(policy: false | SnailReconnectPolicy | undefined): ResolvedReconnectPolicy | undefined;
13
+ /**
14
+ * Exponential backoff with optional full jitter.
15
+ *
16
+ * `attempt` is 1-based: `attempt: 1` returns the first delay. The result is
17
+ * always capped by `maxDelayMs`, so a long outage cannot push a retry hours out.
18
+ */
19
+ export declare function backoffDelay(attempt: number, policy: ResolvedReconnectPolicy): number;
20
+ /** `true` when another attempt is allowed. */
21
+ export declare function canRetry(attempt: number, policy: ResolvedReconnectPolicy): boolean;
22
+ //# sourceMappingURL=reconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/core/reconnect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,qDAAqD;AACrD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AAErE,4EAA4E;AAC5E,eAAO,MAAM,wBAAwB,EAAE,uBAMtC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,KAAK,GAAG,oBAAoB,GAAG,SAAS,GAC/C,uBAAuB,GAAG,SAAS,CAIrC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,uBAAuB,GAC9B,MAAM,CAOR;AAED,8CAA8C;AAC9C,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAElF"}