@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,114 @@
1
+ import { n as createPlugin } from "../../chunks/plugin-D3RDffDG.js";
2
+ import { t as SnailCancelledError } from "../../chunks/request-qeRhihEF.js";
3
+ import { a as readKey, o as unwrapEnvelope } from "../../chunks/response-D-ubkAFl.js";
4
+ import { t as vueStateAdapter } from "../../chunks/vue-Dd9EhkQ3.js";
5
+ //#region src/plugins/vue/plugin.ts
6
+ /**
7
+ * Vue adapter plugin.
8
+ *
9
+ * Mirrors every request's state onto `ctx.meta` as Vue refs, so a component can
10
+ * render `method.meta.data` / `loading` / `error` without writing a single
11
+ * `ref()` or `watch()` itself.
12
+ *
13
+ * ## Why `initMeta` and not `beforeRequest`
14
+ *
15
+ * `initMeta` runs **once**, when the `SnailMethod` is built; `beforeCreate` runs
16
+ * per `send()`. Creating the refs in the per-send hook is the classic bug where a
17
+ * list keeps rendering the first page forever: the UI captured ref #1 while the
18
+ * second send wrote into ref #2. The handles are created here and only ever
19
+ * *written* afterwards, so the object the caller holds stays live for the whole
20
+ * life of the method.
21
+ *
22
+ * ## Why the work is split across four hooks
23
+ *
24
+ * `ctx.meta` is caller-visible, so each handle is written at the moment its value
25
+ * becomes true: the payload after the response arrives (before the `success`
26
+ * event, so a handler that reads `meta.data` sees fresh data), the error before
27
+ * the `error`/`codeError` event, and `loading` in `afterRequest` — which runs in a
28
+ * `finally`, for success, failure and cancellation alike.
29
+ */
30
+ /** Key of the `loading` handle. Fixed, and not part of the envelope. */
31
+ var LOADING_KEY = "loading";
32
+ /** Key of the `error` handle. Fixed, and not part of the envelope. */
33
+ var ERROR_KEY = "error";
34
+ /**
35
+ * Create one handle unless the caller already holds one for that key.
36
+ *
37
+ * The guard matters because `send()` re-runs `initMeta` when the context was built
38
+ * before the plugin was installed; recreating refs there would silently detach
39
+ * whatever the UI is rendering.
40
+ */
41
+ function ensureHandle(ctx, key, initial) {
42
+ if (vueStateAdapter.isState?.(ctx.meta[key])) return;
43
+ ctx.meta[key] = vueStateAdapter.create(initial);
44
+ }
45
+ /** Create the five handles. Runs once per `SnailMethod`. */
46
+ function createHandles(ctx) {
47
+ const { dataKey, codeKey, messageKey } = ctx.serverOptions;
48
+ ensureHandle(ctx, dataKey, void 0);
49
+ ensureHandle(ctx, codeKey, void 0);
50
+ ensureHandle(ctx, messageKey, void 0);
51
+ ensureHandle(ctx, LOADING_KEY, false);
52
+ ensureHandle(ctx, ERROR_KEY, void 0);
53
+ }
54
+ /**
55
+ * Write one handle, ignoring a key this plugin never created.
56
+ *
57
+ * A missing handle means the caller removed it or another adapter owns the key;
58
+ * skipping is better than creating a ref nobody holds a reference to.
59
+ */
60
+ function writeHandle(ctx, key, value) {
61
+ const handle = ctx.meta[key];
62
+ if (handle) vueStateAdapter.write(handle, value);
63
+ }
64
+ /** Copy the envelope of the current response into the caller's refs. */
65
+ function captureResponse(ctx) {
66
+ const response = ctx.getResponse();
67
+ if (!response) return;
68
+ const { dataKey, codeKey, messageKey } = ctx.serverOptions;
69
+ writeHandle(ctx, dataKey, unwrapEnvelope(response.data, dataKey));
70
+ writeHandle(ctx, codeKey, readKey(response.data, codeKey));
71
+ writeHandle(ctx, messageKey, readKey(response.data, messageKey));
72
+ }
73
+ /**
74
+ * Create the Vue adapter plugin.
75
+ *
76
+ * ```ts
77
+ * Service.use(VueAdapter());
78
+ *
79
+ * const user = Service.createApi(UserApi).getUser("1");
80
+ * // renders immediately: `user.meta.loading.value === false`
81
+ * await user.send();
82
+ * user.meta.data.value; // the unwrapped payload
83
+ * ```
84
+ */
85
+ var VueAdapter = createPlugin({
86
+ name: "vue-adapter",
87
+ priority: 0,
88
+ setup() {
89
+ return {
90
+ initMeta(ctx) {
91
+ createHandles(ctx);
92
+ },
93
+ beforeCreate(ctx) {
94
+ writeHandle(ctx, LOADING_KEY, true);
95
+ writeHandle(ctx, ERROR_KEY, void 0);
96
+ },
97
+ afterResponse(ctx, next) {
98
+ captureResponse(ctx);
99
+ return next();
100
+ },
101
+ onError(ctx, error) {
102
+ if (error instanceof SnailCancelledError) return;
103
+ writeHandle(ctx, ERROR_KEY, error);
104
+ },
105
+ afterRequest(ctx) {
106
+ writeHandle(ctx, LOADING_KEY, false);
107
+ }
108
+ };
109
+ }
110
+ });
111
+ //#endregion
112
+ export { VueAdapter };
113
+
114
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/plugins/vue/plugin.ts"],"sourcesContent":["import { vueStateAdapter } from \"../../adapter/vue\";\nimport { createPlugin } from \"../../core/plugin\";\nimport { readKey, unwrapEnvelope } from \"../../core/response\";\nimport { SnailCancelledError } from \"../../error/request\";\nimport type { SnailContext } from \"../../core/context\";\nimport type { SnailStateRef } from \"../../typings/adapter\";\nimport type { VueAdapterOptions } from \"./type\";\n\n/**\n * Vue adapter plugin.\n *\n * Mirrors every request's state onto `ctx.meta` as Vue refs, so a component can\n * render `method.meta.data` / `loading` / `error` without writing a single\n * `ref()` or `watch()` itself.\n *\n * ## Why `initMeta` and not `beforeRequest`\n *\n * `initMeta` runs **once**, when the `SnailMethod` is built; `beforeCreate` runs\n * per `send()`. Creating the refs in the per-send hook is the classic bug where a\n * list keeps rendering the first page forever: the UI captured ref #1 while the\n * second send wrote into ref #2. The handles are created here and only ever\n * *written* afterwards, so the object the caller holds stays live for the whole\n * life of the method.\n *\n * ## Why the work is split across four hooks\n *\n * `ctx.meta` is caller-visible, so each handle is written at the moment its value\n * becomes true: the payload after the response arrives (before the `success`\n * event, so a handler that reads `meta.data` sees fresh data), the error before\n * the `error`/`codeError` event, and `loading` in `afterRequest` — which runs in a\n * `finally`, for success, failure and cancellation alike.\n */\n\n/** Key of the `loading` handle. Fixed, and not part of the envelope. */\nconst LOADING_KEY = \"loading\";\n\n/** Key of the `error` handle. Fixed, and not part of the envelope. */\nconst ERROR_KEY = \"error\";\n\n/**\n * Create one handle unless the caller already holds one for that key.\n *\n * The guard matters because `send()` re-runs `initMeta` when the context was built\n * before the plugin was installed; recreating refs there would silently detach\n * whatever the UI is rendering.\n */\nfunction ensureHandle(ctx: SnailContext, key: string, initial: unknown): void {\n if (vueStateAdapter.isState?.(ctx.meta[key])) return;\n ctx.meta[key] = vueStateAdapter.create(initial);\n}\n\n/** Create the five handles. Runs once per `SnailMethod`. */\nfunction createHandles(ctx: SnailContext): void {\n const { dataKey, codeKey, messageKey } = ctx.serverOptions;\n ensureHandle(ctx, dataKey, undefined);\n ensureHandle(ctx, codeKey, undefined);\n ensureHandle(ctx, messageKey, undefined);\n ensureHandle(ctx, LOADING_KEY, false);\n ensureHandle(ctx, ERROR_KEY, undefined);\n}\n\n/**\n * Write one handle, ignoring a key this plugin never created.\n *\n * A missing handle means the caller removed it or another adapter owns the key;\n * skipping is better than creating a ref nobody holds a reference to.\n */\nfunction writeHandle(ctx: SnailContext, key: string, value: unknown): void {\n const handle = ctx.meta[key];\n if (handle) vueStateAdapter.write(handle as SnailStateRef, value);\n}\n\n/** Copy the envelope of the current response into the caller's refs. */\nfunction captureResponse(ctx: SnailContext): void {\n const response = ctx.getResponse();\n if (!response) return;\n\n const { dataKey, codeKey, messageKey } = ctx.serverOptions;\n writeHandle(ctx, dataKey, unwrapEnvelope(response.data, dataKey));\n writeHandle(ctx, codeKey, readKey(response.data, codeKey));\n writeHandle(ctx, messageKey, readKey(response.data, messageKey));\n}\n\n/**\n * Create the Vue adapter plugin.\n *\n * ```ts\n * Service.use(VueAdapter());\n *\n * const user = Service.createApi(UserApi).getUser(\"1\");\n * // renders immediately: `user.meta.loading.value === false`\n * await user.send();\n * user.meta.data.value; // the unwrapped payload\n * ```\n */\nexport const VueAdapter = createPlugin<VueAdapterOptions>({\n name: \"vue-adapter\",\n priority: 0,\n\n setup() {\n return {\n initMeta(ctx) {\n createHandles(ctx);\n },\n\n beforeCreate(ctx) {\n writeHandle(ctx, LOADING_KEY, true);\n // A new attempt clears the previous failure; otherwise a stale error would\n // keep rendering next to data that has just loaded successfully.\n writeHandle(ctx, ERROR_KEY, undefined);\n },\n\n afterResponse(ctx, next) {\n captureResponse(ctx);\n return next();\n },\n\n onError(ctx, error) {\n // Cancellation is expected control flow, not a failure: writing it would\n // flash an error state every time a component unmounts mid-request.\n if (error instanceof SnailCancelledError) return;\n writeHandle(ctx, ERROR_KEY, error);\n },\n\n afterRequest(ctx) {\n writeHandle(ctx, LOADING_KEY, false);\n }\n };\n }\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,IAAM,cAAc;;AAGpB,IAAM,YAAY;;;;;;;;AASlB,SAAS,aAAa,KAAmB,KAAa,SAAwB;CAC5E,IAAI,gBAAgB,UAAU,IAAI,KAAK,IAAI,GAAG;CAC9C,IAAI,KAAK,OAAO,gBAAgB,OAAO,OAAO;AAChD;;AAGA,SAAS,cAAc,KAAyB;CAC9C,MAAM,EAAE,SAAS,SAAS,eAAe,IAAI;CAC7C,aAAa,KAAK,SAAS,KAAA,CAAS;CACpC,aAAa,KAAK,SAAS,KAAA,CAAS;CACpC,aAAa,KAAK,YAAY,KAAA,CAAS;CACvC,aAAa,KAAK,aAAa,KAAK;CACpC,aAAa,KAAK,WAAW,KAAA,CAAS;AACxC;;;;;;;AAQA,SAAS,YAAY,KAAmB,KAAa,OAAsB;CACzE,MAAM,SAAS,IAAI,KAAK;CACxB,IAAI,QAAQ,gBAAgB,MAAM,QAAyB,KAAK;AAClE;;AAGA,SAAS,gBAAgB,KAAyB;CAChD,MAAM,WAAW,IAAI,YAAY;CACjC,IAAI,CAAC,UAAU;CAEf,MAAM,EAAE,SAAS,SAAS,eAAe,IAAI;CAC7C,YAAY,KAAK,SAAS,eAAe,SAAS,MAAM,OAAO,CAAC;CAChE,YAAY,KAAK,SAAS,QAAQ,SAAS,MAAM,OAAO,CAAC;CACzD,YAAY,KAAK,YAAY,QAAQ,SAAS,MAAM,UAAU,CAAC;AACjE;;;;;;;;;;;;;AAcA,IAAa,aAAa,aAAgC;CACxD,MAAM;CACN,UAAU;CAEV,QAAQ;EACN,OAAO;GACL,SAAS,KAAK;IACZ,cAAc,GAAG;GACnB;GAEA,aAAa,KAAK;IAChB,YAAY,KAAK,aAAa,IAAI;IAGlC,YAAY,KAAK,WAAW,KAAA,CAAS;GACvC;GAEA,cAAc,KAAK,MAAM;IACvB,gBAAgB,GAAG;IACnB,OAAO,KAAK;GACd;GAEA,QAAQ,KAAK,OAAO;IAGlB,IAAI,iBAAiB,qBAAqB;IAC1C,YAAY,KAAK,WAAW,KAAK;GACnC;GAEA,aAAa,KAAK;IAChB,YAAY,KAAK,aAAa,KAAK;GACrC;EACF;CACF;AACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { VueAdapterOptions } from "./type.js";
2
+ /**
3
+ * Create the Vue adapter plugin.
4
+ *
5
+ * ```ts
6
+ * Service.use(VueAdapter());
7
+ *
8
+ * const user = Service.createApi(UserApi).getUser("1");
9
+ * // renders immediately: `user.meta.loading.value === false`
10
+ * await user.send();
11
+ * user.meta.data.value; // the unwrapped payload
12
+ * ```
13
+ */
14
+ export declare const VueAdapter: import("../../index.js").SnailPlugin<VueAdapterOptions>;
15
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/vue/plugin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AA6EhD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,gDAkCrB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Options accepted by the Vue adapter plugin.
3
+ *
4
+ * Deliberately empty: the adapter mirrors the envelope keys the server already
5
+ * declares (`dataKey` / `codeKey` / `messageKey`) and adds the two fixed handles
6
+ * `loading` and `error`, so there is nothing left to configure. A per-plugin key
7
+ * option was avoided on purpose — two sources of truth for the same key is how a
8
+ * UI ends up rendering `undefined` while the payload sits one key away.
9
+ *
10
+ * The parameter is part of the factory signature anyway, so a future option can
11
+ * be added without breaking every `VueAdapter()` call site.
12
+ *
13
+ * ## Typing the handles
14
+ *
15
+ * `method.meta.loading` and `.error` are already typed as `Ref<boolean>` /
16
+ * `Ref<unknown>` through the `SnailMeta` interface. The envelope handles are named
17
+ * after the server's configured keys, which a static interface cannot know, so
18
+ * declare them yourself with your real payload type:
19
+ *
20
+ * ```ts
21
+ * import type { Ref } from "vue";
22
+ *
23
+ * declare module "@snail-js/api" {
24
+ * interface SnailMeta {
25
+ * data: Ref<User>;
26
+ * code: Ref<number>;
27
+ * message: Ref<string>;
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ export interface VueAdapterOptions {
33
+ }
34
+ //# sourceMappingURL=type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/plugins/vue/type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,iBAAiB;CAAG"}
@@ -0,0 +1,2 @@
1
+ export * from "./shared/public.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategies/index.ts"],"names":[],"mappings":"AA0BA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { t as vueStateAdapter } from "../chunks/vue-Dd9EhkQ3.js";
2
+ import { a as useRetriableRequest, c as useFetcher, d as createStrategyState, f as setStateAdapter, i as useUploader, l as useWatcher, n as useSSE, o as useAutoRequest, r as useTokenAuth, s as usePagination, t as useDownload, u as useRequest } from "../chunks/use-download-FAjtdJ58.js";
3
+ //#region src/strategies/index.ts
4
+ /**
5
+ * `@snail-js/api/strategies` — the default entry point, wired for Vue.
6
+ *
7
+ * ```ts
8
+ * import { useRequest, usePagination } from "@snail-js/api/strategies";
9
+ *
10
+ * const user = useRequest(userApi.getUser);
11
+ * ```
12
+ *
13
+ * ## Why the adapter is installed here and nowhere else
14
+ *
15
+ * A strategy hands the caller state handles; only the framework knows what a
16
+ * handle is. Importing this module is therefore the *only* thing that makes Vue's
17
+ * `ref()` the state primitive, and it is what pulls `vue` into a bundle. An
18
+ * application that never imports this entry (or the Vue adapter plugin) never
19
+ * ships Vue — which is why this file and `react.ts` are the only modules in the
20
+ * strategy layer allowed to import a framework.
21
+ *
22
+ * The assignment runs before the re-export below, so a hook created immediately
23
+ * after the import already sees the Vue adapter.
24
+ */
25
+ setStateAdapter(vueStateAdapter);
26
+ //#endregion
27
+ export { createStrategyState, useAutoRequest, useDownload, useFetcher, usePagination, useRequest, useRetriableRequest, useSSE, useTokenAuth, useUploader, useWatcher };
28
+
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/strategies/index.ts"],"sourcesContent":["/**\n * `@snail-js/api/strategies` — the default entry point, wired for Vue.\n *\n * ```ts\n * import { useRequest, usePagination } from \"@snail-js/api/strategies\";\n *\n * const user = useRequest(userApi.getUser);\n * ```\n *\n * ## Why the adapter is installed here and nowhere else\n *\n * A strategy hands the caller state handles; only the framework knows what a\n * handle is. Importing this module is therefore the *only* thing that makes Vue's\n * `ref()` the state primitive, and it is what pulls `vue` into a bundle. An\n * application that never imports this entry (or the Vue adapter plugin) never\n * ships Vue — which is why this file and `react.ts` are the only modules in the\n * strategy layer allowed to import a framework.\n *\n * The assignment runs before the re-export below, so a hook created immediately\n * after the import already sees the Vue adapter.\n */\nimport { vueStateAdapter } from \"../adapter/vue\";\nimport { setStateAdapter } from \"../adapter/registry\";\n\nsetStateAdapter(vueStateAdapter);\n\nexport * from \"./shared/public\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,gBAAgB,eAAe"}
@@ -0,0 +1,2 @@
1
+ export * from "./shared/public.js";
2
+ //# sourceMappingURL=plain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plain.d.ts","sourceRoot":"","sources":["../../src/strategies/plain.ts"],"names":[],"mappings":"AAuBA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { a as useRetriableRequest, c as useFetcher, d as createStrategyState, f as setStateAdapter, i as useUploader, l as useWatcher, n as useSSE, o as useAutoRequest, p as plainStateAdapter, r as useTokenAuth, s as usePagination, t as useDownload, u as useRequest } from "../chunks/use-download-FAjtdJ58.js";
2
+ //#region src/strategies/plain.ts
3
+ /**
4
+ * `@snail-js/api/strategies/plain` — the framework-free entry point.
5
+ *
6
+ * ```ts
7
+ * import { useRequest } from "@snail-js/api/strategies/plain";
8
+ *
9
+ * const user = useRequest(userApi.getUser);
10
+ * await user.send("1");
11
+ * user.data.value; // values update, nothing re-renders
12
+ * ```
13
+ *
14
+ * State handles are plain mutable boxes. Everything works — reads, writes,
15
+ * `bind()`, events — it just does not *trigger* a render, which is exactly right
16
+ * for a script, a server-side pass or a test. This entry is also what the strategy
17
+ * test suite imports, so the whole layer is exercised without a UI framework.
18
+ */
19
+ setStateAdapter(plainStateAdapter);
20
+ //#endregion
21
+ export { createStrategyState, useAutoRequest, useDownload, useFetcher, usePagination, useRequest, useRetriableRequest, useSSE, useTokenAuth, useUploader, useWatcher };
22
+
23
+ //# sourceMappingURL=plain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plain.js","names":[],"sources":["../../src/strategies/plain.ts"],"sourcesContent":["/**\n * `@snail-js/api/strategies/plain` — the framework-free entry point.\n *\n * ```ts\n * import { useRequest } from \"@snail-js/api/strategies/plain\";\n *\n * const user = useRequest(userApi.getUser);\n * await user.send(\"1\");\n * user.data.value; // values update, nothing re-renders\n * ```\n *\n * State handles are plain mutable boxes. Everything works — reads, writes,\n * `bind()`, events — it just does not *trigger* a render, which is exactly right\n * for a script, a server-side pass or a test. This entry is also what the strategy\n * test suite imports, so the whole layer is exercised without a UI framework.\n */\nimport { plainStateAdapter } from \"../adapter/plain\";\nimport { setStateAdapter } from \"../adapter/registry\";\n\n// The registry already defaults to this adapter; setting it explicitly keeps the\n// three entries symmetric and makes the choice visible at the import site.\nsetStateAdapter(plainStateAdapter);\n\nexport * from \"./shared/public\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,gBAAgB,iBAAiB"}
@@ -0,0 +1,2 @@
1
+ export * from "./shared/public.js";
2
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/strategies/react.ts"],"names":[],"mappings":"AA2BA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { t as reactStateAdapter } from "../chunks/react-C1em-gxy.js";
2
+ import { a as useRetriableRequest, c as useFetcher, d as createStrategyState, f as setStateAdapter, i as useUploader, l as useWatcher, n as useSSE, o as useAutoRequest, r as useTokenAuth, s as usePagination, t as useDownload, u as useRequest } from "../chunks/use-download-FAjtdJ58.js";
3
+ //#region src/strategies/react.ts
4
+ /**
5
+ * `@snail-js/api/strategies/react` — the React entry point.
6
+ *
7
+ * ```ts
8
+ * import { useRequest } from "@snail-js/api/strategies/react";
9
+ *
10
+ * const user = useRequest(userApi.getUser);
11
+ * const { data, loading } = user.bind(); // subscribes this component
12
+ * ```
13
+ *
14
+ * ## Why React needs its own entry
15
+ *
16
+ * Vue's `ref()` is tracked by the render effect that reads `.value`, so Vue needs
17
+ * nothing from the strategy layer. React has no such tracking: a component only
18
+ * re-renders when something explicitly tells it to. The React adapter therefore
19
+ * allocates subscribable boxes and implements `useBind` with
20
+ * `useSyncExternalStore`, and it is what `bind()` calls during render.
21
+ *
22
+ * Importing this module is what puts React's adapter in place — and the module is
23
+ * the only place in the strategy layer that imports `react`, so an application
24
+ * built on Vue never pulls it in.
25
+ */
26
+ setStateAdapter(reactStateAdapter);
27
+ //#endregion
28
+ export { createStrategyState, useAutoRequest, useDownload, useFetcher, usePagination, useRequest, useRetriableRequest, useSSE, useTokenAuth, useUploader, useWatcher };
29
+
30
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","names":[],"sources":["../../src/strategies/react.ts"],"sourcesContent":["/**\n * `@snail-js/api/strategies/react` — the React entry point.\n *\n * ```ts\n * import { useRequest } from \"@snail-js/api/strategies/react\";\n *\n * const user = useRequest(userApi.getUser);\n * const { data, loading } = user.bind(); // subscribes this component\n * ```\n *\n * ## Why React needs its own entry\n *\n * Vue's `ref()` is tracked by the render effect that reads `.value`, so Vue needs\n * nothing from the strategy layer. React has no such tracking: a component only\n * re-renders when something explicitly tells it to. The React adapter therefore\n * allocates subscribable boxes and implements `useBind` with\n * `useSyncExternalStore`, and it is what `bind()` calls during render.\n *\n * Importing this module is what puts React's adapter in place — and the module is\n * the only place in the strategy layer that imports `react`, so an application\n * built on Vue never pulls it in.\n */\nimport { reactStateAdapter } from \"../adapter/react\";\nimport { setStateAdapter } from \"../adapter/registry\";\n\nsetStateAdapter(reactStateAdapter);\n\nexport * from \"./shared/public\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,gBAAgB,iBAAiB"}
@@ -0,0 +1,23 @@
1
+ import type { SnailStateAdapter, SnailStateRef } from "../../typings/adapter.js";
2
+ /**
3
+ * Resolve the state adapter one strategy instance should use.
4
+ *
5
+ * The adapter is resolved **once per hook** rather than per read. A hook that
6
+ * asked the registry on every write could observe two different adapters if an
7
+ * application called `setStateAdapter()` between two requests, and would then mix
8
+ * Vue refs with plain boxes in one set of handles.
9
+ */
10
+ export declare function resolveStateAdapter(options?: {
11
+ adapter?: SnailStateAdapter;
12
+ }): SnailStateAdapter;
13
+ /**
14
+ * Read a handle for the current render.
15
+ *
16
+ * `useBind` exists for frameworks that only re-render on an explicit
17
+ * subscription (React's `useSyncExternalStore`); Vue tracks the `.value` access
18
+ * itself, so its adapter omits the method and the read is the whole story. The
19
+ * `??` fallback — rather than a truthiness check — keeps a legitimate `false`,
20
+ * `0` or `""` from being replaced by a second read.
21
+ */
22
+ export declare function bindRef<T>(adapter: SnailStateAdapter, ref: SnailStateRef<T>): T;
23
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAAO,GAAG,iBAAiB,CAEpG;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAE/E"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Guarded access to the browser globals a strategy listens to.
3
+ *
4
+ * The tests for this layer run in Node, where `window` and `document` do not
5
+ * exist at all. Reading them lazily — inside a function, never at module scope —
6
+ * is what lets the same module be imported in both environments, and it is the
7
+ * only reason `useAutoRequest` can be created in a server-side render without
8
+ * throwing.
9
+ */
10
+ /**
11
+ * The subset of `EventTarget` this layer uses.
12
+ *
13
+ * `(...args: any[]) => void` rather than `() => void` on purpose: `window`'s own
14
+ * `addEventListener` expects an `EventListener`, and a zero-argument listener type
15
+ * would make the real object structurally incompatible.
16
+ */
17
+ export interface DomEventTargetLike {
18
+ addEventListener(type: string, listener: (...args: any[]) => void, options?: unknown): void;
19
+ removeEventListener(type: string, listener: (...args: any[]) => void, options?: unknown): void;
20
+ }
21
+ /** The global `window`, or `undefined` outside a DOM environment. */
22
+ export declare function getWindowTarget(): DomEventTargetLike | undefined;
23
+ /** The global `document`, or `undefined` outside a DOM environment. */
24
+ export declare function getDocumentTarget(): DomEventTargetLike | undefined;
25
+ /**
26
+ * `true` when the page is on screen.
27
+ *
28
+ * Node reports `true` so a `visibilitychange`-driven strategy still works in a
29
+ * script; there is no hidden page to miss.
30
+ */
31
+ export declare function isDocumentVisible(): boolean;
32
+ /** A collection of registered listeners that can be removed as one unit. */
33
+ export interface ListenerScope {
34
+ /**
35
+ * Register `listener`. Returns `false` when the target does not exist — the
36
+ * Node case — so the caller can tell "not attached" from "attached".
37
+ */
38
+ add(target: DomEventTargetLike | undefined, type: string, listener: (...args: any[]) => void): boolean;
39
+ /** Remove every listener registered through this scope. Safe to call twice. */
40
+ removeAll(): void;
41
+ /** Number of listeners currently attached. */
42
+ readonly size: number;
43
+ }
44
+ /**
45
+ * Create a listener bookkeeping scope.
46
+ *
47
+ * `stop()` and `dispose()` are called from event handlers, from `finally` blocks
48
+ * and sometimes twice; without one central registry it is far too easy to remove a
49
+ * listener with a *different* function reference than the one added, which leaks
50
+ * silently and keeps the component from being collected.
51
+ */
52
+ export declare function createListenerScope(): ListenerScope;
53
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5F,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAChG;AAED,qEAAqE;AACrE,wBAAgB,eAAe,IAAI,kBAAkB,GAAG,SAAS,CAGhE;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,IAAI,kBAAkB,GAAG,SAAS,CAGlE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,CACD,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GACjC,OAAO,CAAC;IAEX,+EAA+E;IAC/E,SAAS,IAAI,IAAI,CAAC;IAElB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CA8BnD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `true` when an error means "this request was deliberately stopped".
3
+ *
4
+ * Cancellation is **expected control flow**, not a failure: `method.abort()` and
5
+ * a strategy discarding a stale response both produce it. Every strategy must ask
6
+ * this question before writing `error` state or firing `onError`, otherwise a
7
+ * user aborting a request would see a spurious error toast.
8
+ *
9
+ * The duck-typed `code` check is what catches an `AbortError` produced by a
10
+ * caller-supplied `AbortSignal`, which axios does not always wrap in its own
11
+ * cancel class.
12
+ */
13
+ export declare function isCancellation(error: unknown): boolean;
14
+ /**
15
+ * Best-effort business/HTTP code of a failure, for the `code` state handle.
16
+ *
17
+ * Reading it from the error rather than from a response keeps `code` meaningful
18
+ * on the failure path too — a `401` should be visible to the UI even though no
19
+ * envelope ever passed validation.
20
+ */
21
+ export declare function readErrorCode(error: unknown): number | string | undefined;
22
+ /**
23
+ * Best-effort human readable message of a failure, for the `message` handle.
24
+ *
25
+ * The backend envelope is preferred over the `Error.message` because an axios
26
+ * transport message ("Request failed with status code 401") is useless to show a
27
+ * user while `{ message: "token expired" }` is not.
28
+ */
29
+ export declare function readErrorMessage(error: unknown): string | undefined;
30
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/error.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKtD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAUzE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQnE"}
@@ -0,0 +1,51 @@
1
+ import type { AxiosProgressEvent } from "axios";
2
+ import type { SnailMethod } from "../../core/method.js";
3
+ /**
4
+ * A proxied api method — exactly what `Service.createApi(UserApi).getUser` is.
5
+ *
6
+ * Calling it **builds** a request (no network); `send()` performs it. A strategy
7
+ * needs the callable rather than an already-built `SnailMethod` because it must
8
+ * be able to re-send with different arguments, and because a strategy that
9
+ * forwards the argument tuple keeps the api class's own signature intact.
10
+ */
11
+ export type StrategyMethod<TArgs extends readonly unknown[] = readonly unknown[], TData = unknown> = (...args: TArgs) => SnailMethod<any, TData, any, any, any>;
12
+ /** The `SnailMethod` a strategy drives, with its payload type narrowed. */
13
+ export type SnailRequest<TData = unknown> = SnailMethod<any, TData, any, any, any>;
14
+ /**
15
+ * Holds the single `SnailMethod` a hook reuses across sends.
16
+ *
17
+ * `docs/guide/plugin-lifecycle.md` §4.3 is explicit that `initMeta` runs once per method, not
18
+ * once per send, so the reactive handles a UI captured stay identical across
19
+ * re-sends. Calling `method(...args)` again would build a *second* context with a
20
+ * second set of refs — the UI would keep rendering the first, frozen one. This
21
+ * holder is what makes "one instance, many sends" the default instead of a rule
22
+ * every hook author has to remember.
23
+ */
24
+ export interface MethodHolder<TData = unknown> {
25
+ /** The instance driving every send, or `undefined` before the first one. */
26
+ readonly instance: SnailRequest<TData> | undefined;
27
+ /** `true` while this holder's method has a request in flight. */
28
+ readonly pending: boolean;
29
+ /** Get-or-create the instance. Only the first call's arguments are captured. */
30
+ resolve(args: readonly unknown[]): SnailRequest<TData>;
31
+ /** Cancel the in-flight request, if any. A no-op before the first send. */
32
+ abort(): void;
33
+ }
34
+ /** Create a {@link MethodHolder} around a proxied api method. */
35
+ export declare function createMethodHolder<TArgs extends readonly unknown[], TData>(method: StrategyMethod<TArgs, TData>): MethodHolder<TData>;
36
+ /**
37
+ * Attach a per-request upload progress callback.
38
+ *
39
+ * The core resolves `onUploadProgress` from `@UploadProgress(...)` metadata when
40
+ * the `SnailMethod` is built, which is once per method — not once per file. To
41
+ * vary it per request this writes onto the **live** axios config instead.
42
+ *
43
+ * The timing is load-bearing: `send()` calls `begin()` synchronously before its
44
+ * first `await`, so the config read here is the one axios will send. Calling this
45
+ * before `send()` would be silently overwritten by `begin()`, and calling it
46
+ * after an `await` would be too late.
47
+ *
48
+ * @returns `false` when there was no live config to attach to.
49
+ */
50
+ export declare function attachUploadProgress<TData>(snail: SnailRequest<TData>, listener: (event: AxiosProgressEvent) => void): boolean;
51
+ //# sourceMappingURL=method.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/method.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,CACxB,KAAK,SAAS,SAAS,OAAO,EAAE,GAAG,SAAS,OAAO,EAAE,EACrD,KAAK,GAAG,OAAO,IACb,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE/D,2EAA2E;AAC3E,MAAM,MAAM,YAAY,CAAC,KAAK,GAAG,OAAO,IAAI,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAEnF;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY,CAAC,KAAK,GAAG,OAAO;IAC3C,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IAEnD,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEvD,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;CACf;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAChC,KAAK,SAAS,SAAS,OAAO,EAAE,EAChC,KAAK,EACL,MAAM,EAAE,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAoB3D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EACxC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAC5C,OAAO,CAYT"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The public surface of `@snail-js/api/strategies`.
3
+ *
4
+ * The three entry points (`index.ts` for Vue, `react.ts` for React and `plain.ts`
5
+ * for everything else) differ in exactly one statement — which state adapter they
6
+ * install — and then re-export this module. Keeping the export list in one place
7
+ * is what stops the three entries from drifting apart; a hook added here appears
8
+ * in all three, and none of them re-implements anything.
9
+ */
10
+ export { createStrategyState } from "./state.js";
11
+ export type { StrategyBoundState, StrategyState, StrategyStateController, StrategyStateOptions, StrategyStatePatch } from "./state.js";
12
+ export type { MethodHolder, SnailRequest, StrategyMethod } from "./method.js";
13
+ export { useRequest } from "../use-request.js";
14
+ export type { UseRequestOptions, UseRequestResult } from "../use-request.js";
15
+ export { useWatcher } from "../use-watcher.js";
16
+ export type { UseWatcherOptions, UseWatcherResult } from "../use-watcher.js";
17
+ export { useFetcher } from "../use-fetcher.js";
18
+ export type { UseFetcherCore, UseFetcherOptions, UseFetcherResult, UseFetcherStateOptions } from "../use-fetcher.js";
19
+ export { usePagination } from "../use-pagination.js";
20
+ export type { PageRequest, UsePaginationOptions, UsePaginationResult } from "../use-pagination.js";
21
+ export { useAutoRequest } from "../use-auto-request.js";
22
+ export type { UseAutoRequestOptions, UseAutoRequestResult } from "../use-auto-request.js";
23
+ export { useRetriableRequest } from "../use-retriable-request.js";
24
+ export type { UseRetriableRequestOptions, UseRetriableRequestResult } from "../use-retriable-request.js";
25
+ export { useUploader } from "../use-uploader.js";
26
+ export type { UploaderProgress, UploadFileState, UploadFileStatus, UseUploaderOptions, UseUploaderResult } from "../use-uploader.js";
27
+ export { useTokenAuth } from "../use-token-auth.js";
28
+ export type { TokenAuthHandle, TokenAuthOptions } from "../use-token-auth.js";
29
+ export { useSSE } from "../use-sse.js";
30
+ export type { SseConnectionTap, SseEndpoint, UseSseOptions, UseSseResult } from "../use-sse.js";
31
+ export { useDownload } from "../use-download.js";
32
+ export type { DownloadDescriptor, UseDownloadOptions, UseDownloadResult } from "../use-download.js";
33
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/public.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI3E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE7F,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A bounded-concurrency queue of asynchronous tasks.
3
+ *
4
+ * `useUploader` needs this for one reason: a user dropping 200 files must not open
5
+ * 200 sockets. The queue also owns the "is everything finished?" question, so
6
+ * `upload()` can hand back a promise that resolves when the batch drains instead
7
+ * of making the caller poll the file list.
8
+ */
9
+ export interface TaskQueue {
10
+ /** Enqueue a task; it starts as soon as a slot is free. */
11
+ add(task: () => Promise<void>): void;
12
+ /** Resolves once nothing is running and nothing is waiting. */
13
+ drain(): Promise<void>;
14
+ /** Drop every task that has not started yet. Running tasks are untouched. */
15
+ clear(): void;
16
+ /** Number of tasks currently running. */
17
+ readonly active: number;
18
+ /** Number of tasks waiting for a slot. */
19
+ readonly pending: number;
20
+ }
21
+ /**
22
+ * Create a queue that runs at most `concurrency` tasks at a time.
23
+ *
24
+ * A task that rejects is swallowed rather than failing the queue: one broken
25
+ * upload must not stall the remaining ones, and the caller observes the failure
26
+ * through per-file state anyway. `concurrency` is clamped to at least 1, because a
27
+ * queue with zero slots would never drain and `drain()` would never resolve.
28
+ */
29
+ export declare function createTaskQueue(concurrency?: number): TaskQueue;
30
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/queue.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,GAAG,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAErC,+DAA+D;IAC/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,6EAA6E;IAC7E,KAAK,IAAI,IAAI,CAAC;IAEd,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,WAAW,SAAI,GAAG,SAAS,CA0D1D"}
@@ -0,0 +1,51 @@
1
+ /** Retry knobs shared by `useRetriableRequest` and the reconnect transports. */
2
+ export interface RetryOptions {
3
+ /** Extra attempts after the first failure. Defaults to `3`. */
4
+ retries?: number;
5
+ /** First delay in milliseconds. Defaults to `1000`. */
6
+ delayMs?: number;
7
+ /** Upper bound for one delay. Defaults to `30000`. */
8
+ maxDelayMs?: number;
9
+ /** Multiplier applied after each failure. Defaults to `2`. */
10
+ factor?: number;
11
+ /** Randomise the delay to avoid a thundering herd. Defaults to `true`. */
12
+ jitter?: boolean;
13
+ }
14
+ /** Fully defaulted retry configuration. */
15
+ export interface RetryPolicy {
16
+ retries: number;
17
+ delayMs: number;
18
+ maxDelayMs: number;
19
+ factor: number;
20
+ jitter: boolean;
21
+ }
22
+ /** Decides whether one failed attempt deserves another. */
23
+ export type RetryPredicate = (error: unknown, attempt: number) => boolean;
24
+ /** Defaults are deliberately conservative: three tries, exponential, jittered. */
25
+ export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
26
+ /**
27
+ * Fill in the retry defaults.
28
+ *
29
+ * `retries` is floored and clamped to `>= 0`: a negative value would make the
30
+ * attempt loop run zero times and resolve without ever sending, which is a
31
+ * silent no-op rather than a validation error the caller can see.
32
+ */
33
+ export declare function resolveRetryPolicy(options?: RetryOptions): RetryPolicy;
34
+ /**
35
+ * Delay before attempt `attempt` (1-based), with exponential growth and an
36
+ * optional jitter.
37
+ *
38
+ * Jitter is *half* the computed delay plus a random share, not a fresh random
39
+ * pick: full jitter can produce a near-zero delay that turns a retry storm into a
40
+ * hammering loop, while half jitter still spreads a fleet of clients out.
41
+ */
42
+ export declare function computeBackoffDelay(attempt: number, policy: RetryPolicy): number;
43
+ /**
44
+ * The default {@link RetryPredicate}: retry everything except a cancellation.
45
+ *
46
+ * Retrying a cancellation is the one case that is always wrong — the caller asked
47
+ * for the request to stop, so a retry ignores an explicit instruction and keeps
48
+ * the socket busy.
49
+ */
50
+ export declare const defaultRetryPredicate: RetryPredicate;
51
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/strategies/shared/retry.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;AAE1E,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,YAAiB,GAAG,WAAW,CAiB1E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAKhF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,cACZ,CAAC"}