@mtcute/dispatcher 0.16.0 → 0.16.9

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 (239) hide show
  1. package/README.md +2 -2
  2. package/callback-data-builder.test.d.ts +1 -0
  3. package/{esm/context → context}/business-message.d.ts +17 -17
  4. package/{esm/context → context}/callback-query.d.ts +4 -4
  5. package/{cjs/context → context}/chat-join-request.d.ts +1 -1
  6. package/{esm/context → context}/chosen-inline-result.d.ts +1 -1
  7. package/{esm/context → context}/inline-query.d.ts +2 -2
  8. package/{cjs/context → context}/message.d.ts +3 -3
  9. package/context/parse.d.ts +13 -0
  10. package/{esm/context → context}/pre-checkout-query.d.ts +1 -1
  11. package/{cjs/dispatcher.d.ts → dispatcher.d.ts} +2 -2
  12. package/{cjs/filters → filters}/bots.d.ts +13 -23
  13. package/filters/bots.test.d.ts +1 -0
  14. package/{esm/filters → filters}/chat.d.ts +2 -2
  15. package/filters/logic.test.d.ts +1 -0
  16. package/filters/message.d.ts +214 -0
  17. package/{cjs/filters → filters}/state.d.ts +1 -1
  18. package/{esm/filters → filters}/text.d.ts +5 -5
  19. package/{esm/filters → filters}/user.d.ts +1 -1
  20. package/{esm/handler.d.ts → handler.d.ts} +1 -1
  21. package/index.cjs +2510 -0
  22. package/index.d.ts +8 -1
  23. package/index.js +2505 -1
  24. package/package.json +28 -24
  25. package/{esm/state → state}/repository.d.ts +6 -6
  26. package/{esm/state → state}/service.d.ts +3 -2
  27. package/{cjs/state → state}/update-state.d.ts +1 -1
  28. package/{esm/wizard.d.ts → wizard.d.ts} +4 -4
  29. package/cjs/callback-data-builder.js +0 -139
  30. package/cjs/callback-data-builder.js.map +0 -1
  31. package/cjs/context/base.js +0 -3
  32. package/cjs/context/base.js.map +0 -1
  33. package/cjs/context/business-message.d.ts +0 -60
  34. package/cjs/context/business-message.js +0 -146
  35. package/cjs/context/business-message.js.map +0 -1
  36. package/cjs/context/callback-query.d.ts +0 -62
  37. package/cjs/context/callback-query.js +0 -109
  38. package/cjs/context/callback-query.js.map +0 -1
  39. package/cjs/context/chat-join-request.js +0 -35
  40. package/cjs/context/chat-join-request.js.map +0 -1
  41. package/cjs/context/chosen-inline-result.d.ts +0 -22
  42. package/cjs/context/chosen-inline-result.js +0 -36
  43. package/cjs/context/chosen-inline-result.js.map +0 -1
  44. package/cjs/context/index.js +0 -25
  45. package/cjs/context/index.js.map +0 -1
  46. package/cjs/context/inline-query.d.ts +0 -15
  47. package/cjs/context/inline-query.js +0 -23
  48. package/cjs/context/inline-query.js.map +0 -1
  49. package/cjs/context/message.js +0 -171
  50. package/cjs/context/message.js.map +0 -1
  51. package/cjs/context/parse.d.ts +0 -13
  52. package/cjs/context/parse.js +0 -43
  53. package/cjs/context/parse.js.map +0 -1
  54. package/cjs/context/pre-checkout-query.d.ts +0 -17
  55. package/cjs/context/pre-checkout-query.js +0 -27
  56. package/cjs/context/pre-checkout-query.js.map +0 -1
  57. package/cjs/context/scene-transition.js +0 -52
  58. package/cjs/context/scene-transition.js.map +0 -1
  59. package/cjs/dispatcher.js +0 -905
  60. package/cjs/dispatcher.js.map +0 -1
  61. package/cjs/filters/bots.js +0 -133
  62. package/cjs/filters/bots.js.map +0 -1
  63. package/cjs/filters/bundle.js +0 -27
  64. package/cjs/filters/bundle.js.map +0 -1
  65. package/cjs/filters/chat.d.ts +0 -27
  66. package/cjs/filters/chat.js +0 -55
  67. package/cjs/filters/chat.js.map +0 -1
  68. package/cjs/filters/group.js +0 -72
  69. package/cjs/filters/group.js.map +0 -1
  70. package/cjs/filters/index.js +0 -29
  71. package/cjs/filters/index.js.map +0 -1
  72. package/cjs/filters/logic.js +0 -114
  73. package/cjs/filters/logic.js.map +0 -1
  74. package/cjs/filters/message.d.ts +0 -332
  75. package/cjs/filters/message.js +0 -179
  76. package/cjs/filters/message.js.map +0 -1
  77. package/cjs/filters/state.js +0 -32
  78. package/cjs/filters/state.js.map +0 -1
  79. package/cjs/filters/text.d.ts +0 -64
  80. package/cjs/filters/text.js +0 -135
  81. package/cjs/filters/text.js.map +0 -1
  82. package/cjs/filters/types.js +0 -6
  83. package/cjs/filters/types.js.map +0 -1
  84. package/cjs/filters/updates.js +0 -40
  85. package/cjs/filters/updates.js.map +0 -1
  86. package/cjs/filters/user.d.ts +0 -24
  87. package/cjs/filters/user.js +0 -78
  88. package/cjs/filters/user.js.map +0 -1
  89. package/cjs/handler.d.ts +0 -41
  90. package/cjs/handler.js +0 -4
  91. package/cjs/handler.js.map +0 -1
  92. package/cjs/index.js +0 -31
  93. package/cjs/index.js.map +0 -1
  94. package/cjs/package.json +0 -3
  95. package/cjs/propagation.js +0 -27
  96. package/cjs/propagation.js.map +0 -1
  97. package/cjs/state/index.js +0 -22
  98. package/cjs/state/index.js.map +0 -1
  99. package/cjs/state/key.js +0 -43
  100. package/cjs/state/key.js.map +0 -1
  101. package/cjs/state/provider.js +0 -3
  102. package/cjs/state/provider.js.map +0 -1
  103. package/cjs/state/providers/index.js +0 -19
  104. package/cjs/state/providers/index.js.map +0 -1
  105. package/cjs/state/providers/memory.js +0 -81
  106. package/cjs/state/providers/memory.js.map +0 -1
  107. package/cjs/state/providers/sqlite.js +0 -100
  108. package/cjs/state/providers/sqlite.js.map +0 -1
  109. package/cjs/state/repository.d.ts +0 -62
  110. package/cjs/state/repository.js +0 -3
  111. package/cjs/state/repository.js.map +0 -1
  112. package/cjs/state/service.d.ts +0 -19
  113. package/cjs/state/service.js +0 -70
  114. package/cjs/state/service.js.map +0 -1
  115. package/cjs/state/update-state.js +0 -220
  116. package/cjs/state/update-state.js.map +0 -1
  117. package/cjs/wizard.d.ts +0 -64
  118. package/cjs/wizard.js +0 -103
  119. package/cjs/wizard.js.map +0 -1
  120. package/esm/callback-data-builder.d.ts +0 -49
  121. package/esm/callback-data-builder.js +0 -135
  122. package/esm/callback-data-builder.js.map +0 -1
  123. package/esm/context/base.d.ts +0 -9
  124. package/esm/context/base.js +0 -2
  125. package/esm/context/base.js.map +0 -1
  126. package/esm/context/business-message.js +0 -142
  127. package/esm/context/business-message.js.map +0 -1
  128. package/esm/context/callback-query.js +0 -103
  129. package/esm/context/callback-query.js.map +0 -1
  130. package/esm/context/chat-join-request.d.ts +0 -17
  131. package/esm/context/chat-join-request.js +0 -31
  132. package/esm/context/chat-join-request.js.map +0 -1
  133. package/esm/context/chosen-inline-result.js +0 -32
  134. package/esm/context/chosen-inline-result.js.map +0 -1
  135. package/esm/context/index.d.ts +0 -9
  136. package/esm/context/index.js +0 -9
  137. package/esm/context/index.js.map +0 -1
  138. package/esm/context/inline-query.js +0 -19
  139. package/esm/context/inline-query.js.map +0 -1
  140. package/esm/context/message.d.ts +0 -76
  141. package/esm/context/message.js +0 -167
  142. package/esm/context/message.js.map +0 -1
  143. package/esm/context/parse.d.ts +0 -13
  144. package/esm/context/parse.js +0 -39
  145. package/esm/context/parse.js.map +0 -1
  146. package/esm/context/pre-checkout-query.js +0 -23
  147. package/esm/context/pre-checkout-query.js.map +0 -1
  148. package/esm/context/scene-transition.d.ts +0 -24
  149. package/esm/context/scene-transition.js +0 -48
  150. package/esm/context/scene-transition.js.map +0 -1
  151. package/esm/dispatcher.d.ts +0 -880
  152. package/esm/dispatcher.js +0 -901
  153. package/esm/dispatcher.js.map +0 -1
  154. package/esm/filters/bots.d.ts +0 -74
  155. package/esm/filters/bots.js +0 -129
  156. package/esm/filters/bots.js.map +0 -1
  157. package/esm/filters/bundle.d.ts +0 -10
  158. package/esm/filters/bundle.js +0 -11
  159. package/esm/filters/bundle.js.map +0 -1
  160. package/esm/filters/chat.js +0 -50
  161. package/esm/filters/chat.js.map +0 -1
  162. package/esm/filters/group.d.ts +0 -26
  163. package/esm/filters/group.js +0 -67
  164. package/esm/filters/group.js.map +0 -1
  165. package/esm/filters/index.d.ts +0 -4
  166. package/esm/filters/index.js +0 -3
  167. package/esm/filters/index.js.map +0 -1
  168. package/esm/filters/logic.d.ts +0 -29
  169. package/esm/filters/logic.js +0 -107
  170. package/esm/filters/logic.js.map +0 -1
  171. package/esm/filters/message.d.ts +0 -332
  172. package/esm/filters/message.js +0 -156
  173. package/esm/filters/message.js.map +0 -1
  174. package/esm/filters/state.d.ts +0 -15
  175. package/esm/filters/state.js +0 -27
  176. package/esm/filters/state.js.map +0 -1
  177. package/esm/filters/text.js +0 -127
  178. package/esm/filters/text.js.map +0 -1
  179. package/esm/filters/types.d.ts +0 -91
  180. package/esm/filters/types.js +0 -5
  181. package/esm/filters/types.js.map +0 -1
  182. package/esm/filters/updates.d.ts +0 -39
  183. package/esm/filters/updates.js +0 -34
  184. package/esm/filters/updates.js.map +0 -1
  185. package/esm/filters/user.js +0 -72
  186. package/esm/filters/user.js.map +0 -1
  187. package/esm/handler.js +0 -3
  188. package/esm/handler.js.map +0 -1
  189. package/esm/index.d.ts +0 -8
  190. package/esm/index.js +0 -9
  191. package/esm/index.js.map +0 -1
  192. package/esm/propagation.d.ts +0 -22
  193. package/esm/propagation.js +0 -24
  194. package/esm/propagation.js.map +0 -1
  195. package/esm/state/index.d.ts +0 -5
  196. package/esm/state/index.js +0 -6
  197. package/esm/state/index.js.map +0 -1
  198. package/esm/state/key.d.ts +0 -24
  199. package/esm/state/key.js +0 -39
  200. package/esm/state/key.js.map +0 -1
  201. package/esm/state/provider.d.ts +0 -5
  202. package/esm/state/provider.js +0 -2
  203. package/esm/state/provider.js.map +0 -1
  204. package/esm/state/providers/index.d.ts +0 -2
  205. package/esm/state/providers/index.js +0 -3
  206. package/esm/state/providers/index.js.map +0 -1
  207. package/esm/state/providers/memory.d.ts +0 -29
  208. package/esm/state/providers/memory.js +0 -77
  209. package/esm/state/providers/memory.js.map +0 -1
  210. package/esm/state/providers/sqlite.d.ts +0 -28
  211. package/esm/state/providers/sqlite.js +0 -96
  212. package/esm/state/providers/sqlite.js.map +0 -1
  213. package/esm/state/repository.js +0 -2
  214. package/esm/state/repository.js.map +0 -1
  215. package/esm/state/service.js +0 -66
  216. package/esm/state/service.js.map +0 -1
  217. package/esm/state/update-state.d.ts +0 -151
  218. package/esm/state/update-state.js +0 -215
  219. package/esm/state/update-state.js.map +0 -1
  220. package/esm/wizard.js +0 -99
  221. package/esm/wizard.js.map +0 -1
  222. /package/{cjs/callback-data-builder.d.ts → callback-data-builder.d.ts} +0 -0
  223. /package/{cjs/context → context}/base.d.ts +0 -0
  224. /package/{cjs/context → context}/index.d.ts +0 -0
  225. /package/{cjs/context → context}/scene-transition.d.ts +0 -0
  226. /package/{cjs/filters → filters}/bundle.d.ts +0 -0
  227. /package/{cjs/filters → filters}/group.d.ts +0 -0
  228. /package/{cjs/filters → filters}/index.d.ts +0 -0
  229. /package/{cjs/filters → filters}/logic.d.ts +0 -0
  230. /package/{cjs/filters → filters}/types.d.ts +0 -0
  231. /package/{cjs/filters → filters}/updates.d.ts +0 -0
  232. /package/{cjs/index.d.ts → index.d.cts} +0 -0
  233. /package/{cjs/propagation.d.ts → propagation.d.ts} +0 -0
  234. /package/{cjs/state → state}/index.d.ts +0 -0
  235. /package/{cjs/state → state}/key.d.ts +0 -0
  236. /package/{cjs/state → state}/provider.d.ts +0 -0
  237. /package/{cjs/state → state}/providers/index.d.ts +0 -0
  238. /package/{cjs/state → state}/providers/memory.d.ts +0 -0
  239. /package/{cjs/state → state}/providers/sqlite.d.ts +0 -0
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./key.js"), exports);
18
- __exportStar(require("./provider.js"), exports);
19
- __exportStar(require("./providers/index.js"), exports);
20
- __exportStar(require("./repository.js"), exports);
21
- __exportStar(require("./update-state.js"), exports);
22
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAwB;AACxB,gDAA6B;AAC7B,uDAAoC;AACpC,kDAA+B;AAC/B,oDAAiC","sourcesContent":["export * from './key.js'\nexport * from './provider.js'\nexport * from './providers/index.js'\nexport * from './repository.js'\nexport * from './update-state.js'\n"]}
package/cjs/state/key.js DELETED
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultStateKeyDelegate = void 0;
4
- const core_1 = require("@mtcute/core");
5
- /**
6
- * Default state key delegate.
7
- *
8
- * Derives key as follows:
9
- * - If private chat, `msg.chat.id`
10
- * - If group chat, `msg.chat.id + '_' + msg.sender.id`
11
- * - If channel, `msg.chat.id`
12
- * - If non-inline callback query:
13
- * - If in private chat (i.e. `upd.chatType === 'user'`), `upd.user.id`
14
- * - If in group/channel/supergroup (i.e. `upd.chatType !== 'user'`), `upd.chatId + '_' + upd.user.id`
15
- */
16
- const defaultStateKeyDelegate = (upd) => {
17
- if ('type' in upd) {
18
- // User | Chat
19
- return String(upd.id);
20
- }
21
- if (upd._name === 'new_message' || upd._name === 'new_business_message') {
22
- switch (upd.chat.chatType) {
23
- case 'private':
24
- case 'bot':
25
- case 'channel':
26
- return String(upd.chat.id);
27
- case 'group':
28
- case 'supergroup':
29
- case 'gigagroup':
30
- return `${upd.chat.id}_${upd.sender.id}`;
31
- default:
32
- (0, core_1.assertNever)(upd.chat.chatType);
33
- }
34
- }
35
- if (upd._name === 'callback_query') {
36
- if (upd.chat.chatType === 'private')
37
- return `${upd.user.id}`;
38
- return `${upd.chat.id}_${upd.user.id}`;
39
- }
40
- return null;
41
- };
42
- exports.defaultStateKeyDelegate = defaultStateKeyDelegate;
43
- //# sourceMappingURL=key.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"key.js","sourceRoot":"","sources":["../../../src/state/key.ts"],"names":[],"mappings":";;;AAAA,uCAA8D;AAiB9D;;;;;;;;;;GAUG;AACI,MAAM,uBAAuB,GAAqB,CAAC,GAAG,EAAiB,EAAE;IAC5E,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,cAAc;QACd,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,IAAI,GAAG,CAAC,KAAK,KAAK,aAAa,IAAI,GAAG,CAAC,KAAK,KAAK,sBAAsB,EAAE,CAAC;QACtE,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACxB,KAAK,SAAS,CAAC;YACf,KAAK,KAAK,CAAC;YACX,KAAK,SAAS;gBACV,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAC9B,KAAK,OAAO,CAAC;YACb,KAAK,YAAY,CAAC;YAClB,KAAK,WAAW;gBACZ,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAA;YAC5C;gBACI,IAAA,kBAAW,EAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,KAAK,KAAK,gBAAgB,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;YAAE,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;QAE5D,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;IAC1C,CAAC;IAED,OAAO,IAAI,CAAA;AACf,CAAC,CAAA;AA5BY,QAAA,uBAAuB,2BA4BnC","sourcesContent":["import { assertNever, MaybePromise, Peer } from '@mtcute/core'\n\nimport { BusinessMessageContext } from '../context/business-message.js'\nimport { CallbackQueryContext, MessageContext } from '../context/index.js'\n\n/**\n * Function that determines how the state key is derived.\n *\n * The key is additionally prefixed with current scene, if any.\n *\n * @param msg Message or callback from which to derive the key\n * @param scene Current scene UID, or `null` if none\n */\nexport type StateKeyDelegate = (\n upd: MessageContext | BusinessMessageContext | CallbackQueryContext | Peer,\n) => MaybePromise<string | null>\n\n/**\n * Default state key delegate.\n *\n * Derives key as follows:\n * - If private chat, `msg.chat.id`\n * - If group chat, `msg.chat.id + '_' + msg.sender.id`\n * - If channel, `msg.chat.id`\n * - If non-inline callback query:\n * - If in private chat (i.e. `upd.chatType === 'user'`), `upd.user.id`\n * - If in group/channel/supergroup (i.e. `upd.chatType !== 'user'`), `upd.chatId + '_' + upd.user.id`\n */\nexport const defaultStateKeyDelegate: StateKeyDelegate = (upd): string | null => {\n if ('type' in upd) {\n // User | Chat\n return String(upd.id)\n }\n\n if (upd._name === 'new_message' || upd._name === 'new_business_message') {\n switch (upd.chat.chatType) {\n case 'private':\n case 'bot':\n case 'channel':\n return String(upd.chat.id)\n case 'group':\n case 'supergroup':\n case 'gigagroup':\n return `${upd.chat.id}_${upd.sender.id}`\n default:\n assertNever(upd.chat.chatType)\n }\n }\n\n if (upd._name === 'callback_query') {\n if (upd.chat.chatType === 'private') return `${upd.user.id}`\n\n return `${upd.chat.id}_${upd.user.id}`\n }\n\n return null\n}\n"]}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/state/provider.ts"],"names":[],"mappings":"","sourcesContent":["import { IStorageProvider } from '@mtcute/core'\n\nimport { IStateRepository } from './repository.js'\n\nexport type IStateStorageProvider = IStorageProvider<{\n state: IStateRepository\n}>\n"]}
@@ -1,19 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./memory.js"), exports);
18
- __exportStar(require("./sqlite.js"), exports);
19
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/state/providers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B;AAC3B,8CAA2B","sourcesContent":["export * from './memory.js'\nexport * from './sqlite.js'\n"]}
@@ -1,81 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MemoryStateStorage = void 0;
4
- const core_1 = require("@mtcute/core");
5
- class MemoryStateRepository {
6
- _driver;
7
- state;
8
- rl;
9
- constructor(_driver) {
10
- this._driver = _driver;
11
- this.state = this._driver.getState('dispatcher_fsm', () => new Map());
12
- this.rl = this._driver.getState('rl', () => new Map());
13
- }
14
- setState(key, state, ttl) {
15
- this.state.set(key, {
16
- value: state,
17
- expiresAt: ttl ? Date.now() + ttl * 1000 : undefined,
18
- });
19
- }
20
- getState(key, now) {
21
- const state = this.state.get(key);
22
- if (!state)
23
- return null;
24
- if (state.expiresAt && state.expiresAt < now) {
25
- this.state.delete(key);
26
- return null;
27
- }
28
- return state.value;
29
- }
30
- deleteState(key) {
31
- this.state.delete(key);
32
- }
33
- vacuum(now) {
34
- for (const [key, state] of this.state.entries()) {
35
- if (state.expiresAt && state.expiresAt < now) {
36
- this.state.delete(key);
37
- }
38
- }
39
- for (const [key, state] of this.rl.entries()) {
40
- if (state.reset < now) {
41
- this.rl.delete(key);
42
- }
43
- }
44
- }
45
- getRateLimit(key, now, limit, window) {
46
- // leaky bucket
47
- const item = this.rl.get(key);
48
- if (!item) {
49
- const state = {
50
- reset: now + window * 1000,
51
- remaining: limit,
52
- };
53
- this.rl.set(key, state);
54
- return [state.remaining, state.reset];
55
- }
56
- if (item.reset < now) {
57
- // expired
58
- const state = {
59
- reset: now + window * 1000,
60
- remaining: limit,
61
- };
62
- this.rl.set(key, state);
63
- return [state.remaining, state.reset];
64
- }
65
- item.remaining = item.remaining > 0 ? item.remaining - 1 : 0;
66
- return [item.remaining, item.reset];
67
- }
68
- resetRateLimit(key) {
69
- this.rl.delete(key);
70
- }
71
- }
72
- class MemoryStateStorage {
73
- driver;
74
- state;
75
- constructor(driver = new core_1.MemoryStorageDriver()) {
76
- this.driver = driver;
77
- this.state = new MemoryStateRepository(this.driver);
78
- }
79
- }
80
- exports.MemoryStateStorage = MemoryStateStorage;
81
- //# sourceMappingURL=memory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../../src/state/providers/memory.ts"],"names":[],"mappings":"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","sourcesContent":["import { MaybePromise, MemoryStorageDriver } from '@mtcute/core'\n\nimport { IStateStorageProvider } from '../provider.js'\nimport { IStateRepository } from '../repository.js'\n\ninterface StateDto {\n value: string\n expiresAt?: number\n}\n\ninterface RateLimitDto {\n reset: number\n remaining: number\n}\n\nclass MemoryStateRepository implements IStateRepository {\n readonly state\n readonly rl\n constructor(readonly _driver: MemoryStorageDriver) {\n this.state = this._driver.getState<Map<string, StateDto>>('dispatcher_fsm', () => new Map())\n this.rl = this._driver.getState<Map<string, RateLimitDto>>('rl', () => new Map())\n }\n\n setState(key: string, state: string, ttl?: number | undefined): void {\n this.state.set(key, {\n value: state,\n expiresAt: ttl ? Date.now() + ttl * 1000 : undefined,\n })\n }\n\n getState(key: string, now: number): string | null {\n const state = this.state.get(key)\n if (!state) return null\n\n if (state.expiresAt && state.expiresAt < now) {\n this.state.delete(key)\n\n return null\n }\n\n return state.value\n }\n\n deleteState(key: string): void {\n this.state.delete(key)\n }\n\n vacuum(now: number): void {\n for (const [key, state] of this.state.entries()) {\n if (state.expiresAt && state.expiresAt < now) {\n this.state.delete(key)\n }\n }\n\n for (const [key, state] of this.rl.entries()) {\n if (state.reset < now) {\n this.rl.delete(key)\n }\n }\n }\n\n getRateLimit(key: string, now: number, limit: number, window: number): [number, number] {\n // leaky bucket\n const item = this.rl.get(key)\n\n if (!item) {\n const state: RateLimitDto = {\n reset: now + window * 1000,\n remaining: limit,\n }\n\n this.rl.set(key, state)\n\n return [state.remaining, state.reset]\n }\n\n if (item.reset < now) {\n // expired\n\n const state: RateLimitDto = {\n reset: now + window * 1000,\n remaining: limit,\n }\n\n this.rl.set(key, state)\n\n return [state.remaining, state.reset]\n }\n\n item.remaining = item.remaining > 0 ? item.remaining - 1 : 0\n\n return [item.remaining, item.reset]\n }\n\n resetRateLimit(key: string): MaybePromise<void> {\n this.rl.delete(key)\n }\n}\n\nexport class MemoryStateStorage implements IStateStorageProvider {\n readonly state\n\n constructor(readonly driver: MemoryStorageDriver = new MemoryStorageDriver()) {\n this.state = new MemoryStateRepository(this.driver)\n }\n}\n"]}
@@ -1,100 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SqliteStateStorage = void 0;
4
- class SqliteStateRepository {
5
- _driver;
6
- constructor(_driver) {
7
- this._driver = _driver;
8
- _driver.registerMigration('state', 1, (db) => {
9
- db.exec(`
10
- create table fsm_state (
11
- key text primary key,
12
- value text not null,
13
- expires_at integer
14
- );
15
- create table rl_state (
16
- key text primary key,
17
- reset integer not null,
18
- remaining integer not null
19
- );
20
- `);
21
- });
22
- _driver.onLoad(() => {
23
- this._setState = _driver.db.prepare('insert or replace into fsm_state (key, value, expires_at) values (?, ?, ?)');
24
- this._getState = _driver.db.prepare('select value, expires_at from fsm_state where key = ?');
25
- this._deleteState = _driver.db.prepare('delete from fsm_state where key = ?');
26
- this._deleteOldState = _driver.db.prepare('delete from fsm_state where expires_at < ?');
27
- this._setRl = _driver.db.prepare('insert or replace into rl_state (key, reset, remaining) values (?, ?, ?)');
28
- this._getRl = _driver.db.prepare('select reset, remaining from rl_state where key = ?');
29
- this._deleteRl = _driver.db.prepare('delete from rl_state where key = ?');
30
- this._deleteOldRl = _driver.db.prepare('delete from rl_state where reset < ?');
31
- });
32
- _driver.registerLegacyMigration('state', (db) => {
33
- // not too important information, just drop the table
34
- db.exec('drop table state');
35
- });
36
- }
37
- _setState;
38
- setState(key, state, ttl) {
39
- this._setState.run(key, state, ttl ? Date.now() + ttl * 1000 : undefined);
40
- }
41
- _getState;
42
- getState(key, now) {
43
- const res_ = this._getState.get(key);
44
- if (!res_)
45
- return null;
46
- const res = res_;
47
- if (res.expires_at && res.expires_at < now) {
48
- this._deleteState.run(key);
49
- return null;
50
- }
51
- return res.value;
52
- }
53
- _deleteState;
54
- deleteState(key) {
55
- this._deleteState.run(key);
56
- }
57
- _deleteOldState;
58
- _deleteOldRl;
59
- vacuum(now) {
60
- this._deleteOldState.run(now);
61
- this._deleteOldRl.run(now);
62
- }
63
- _setRl;
64
- _getRl;
65
- _deleteRl;
66
- getRateLimit(key, now, limit, window) {
67
- const val = this._getRl.get(key);
68
- // hot path. rate limit fsm entries always have an expiration date
69
- if (!val || val.reset < now) {
70
- // expired or does not exist
71
- const item = {
72
- reset: now + window * 1000,
73
- remaining: limit,
74
- };
75
- this._setRl.run(key, item.reset, item.remaining);
76
- return [item.remaining, item.reset];
77
- }
78
- if (val.remaining > 0) {
79
- val.remaining -= 1;
80
- this._setRl.run(key, val.reset, val.remaining);
81
- }
82
- return [val.remaining, val.reset];
83
- }
84
- resetRateLimit(key) {
85
- this._deleteRl.run(key);
86
- }
87
- }
88
- class SqliteStateStorage {
89
- driver;
90
- state;
91
- constructor(driver) {
92
- this.driver = driver;
93
- this.state = new SqliteStateRepository(driver);
94
- }
95
- static from(provider) {
96
- return new SqliteStateStorage(provider.driver);
97
- }
98
- }
99
- exports.SqliteStateStorage = SqliteStateStorage;
100
- //# sourceMappingURL=sqlite.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../../src/state/providers/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseSqliteStorage, BaseSqliteStorageDriver, ISqliteStatement, MaybePromise } from '@mtcute/core'\n\nimport { IStateStorageProvider } from '../provider.js'\nimport { IStateRepository } from '../repository.js'\n\ninterface StateDto {\n value: string\n expires_at: number | null\n}\n\ninterface RateLimitDto {\n reset: number\n remaining: number\n}\n\nclass SqliteStateRepository implements IStateRepository {\n constructor(readonly _driver: BaseSqliteStorageDriver) {\n _driver.registerMigration('state', 1, (db) => {\n db.exec(`\n create table fsm_state (\n key text primary key,\n value text not null,\n expires_at integer\n );\n create table rl_state (\n key text primary key,\n reset integer not null,\n remaining integer not null\n );\n `)\n })\n _driver.onLoad(() => {\n this._setState = _driver.db.prepare(\n 'insert or replace into fsm_state (key, value, expires_at) values (?, ?, ?)',\n )\n this._getState = _driver.db.prepare('select value, expires_at from fsm_state where key = ?')\n this._deleteState = _driver.db.prepare('delete from fsm_state where key = ?')\n this._deleteOldState = _driver.db.prepare('delete from fsm_state where expires_at < ?')\n\n this._setRl = _driver.db.prepare('insert or replace into rl_state (key, reset, remaining) values (?, ?, ?)')\n this._getRl = _driver.db.prepare('select reset, remaining from rl_state where key = ?')\n this._deleteRl = _driver.db.prepare('delete from rl_state where key = ?')\n this._deleteOldRl = _driver.db.prepare('delete from rl_state where reset < ?')\n })\n _driver.registerLegacyMigration('state', (db) => {\n // not too important information, just drop the table\n db.exec('drop table state')\n })\n }\n\n private _setState!: ISqliteStatement\n setState(key: string, state: string, ttl?: number | undefined): MaybePromise<void> {\n this._setState.run(key, state, ttl ? Date.now() + ttl * 1000 : undefined)\n }\n\n private _getState!: ISqliteStatement\n getState(key: string, now: number): MaybePromise<string | null> {\n const res_ = this._getState.get(key)\n if (!res_) return null\n const res = res_ as StateDto\n\n if (res.expires_at && res.expires_at < now) {\n this._deleteState.run(key)\n\n return null\n }\n\n return res.value\n }\n\n private _deleteState!: ISqliteStatement\n deleteState(key: string): MaybePromise<void> {\n this._deleteState.run(key)\n }\n\n private _deleteOldState!: ISqliteStatement\n private _deleteOldRl!: ISqliteStatement\n vacuum(now: number): MaybePromise<void> {\n this._deleteOldState.run(now)\n this._deleteOldRl.run(now)\n }\n\n private _setRl!: ISqliteStatement\n private _getRl!: ISqliteStatement\n private _deleteRl!: ISqliteStatement\n\n getRateLimit(key: string, now: number, limit: number, window: number): [number, number] {\n const val = this._getRl.get(key) as RateLimitDto | undefined\n\n // hot path. rate limit fsm entries always have an expiration date\n\n if (!val || val.reset < now) {\n // expired or does not exist\n const item: RateLimitDto = {\n reset: now + window * 1000,\n remaining: limit,\n }\n\n this._setRl.run(key, item.reset, item.remaining)\n\n return [item.remaining, item.reset]\n }\n\n if (val.remaining > 0) {\n val.remaining -= 1\n\n this._setRl.run(key, val.reset, val.remaining)\n }\n\n return [val.remaining, val.reset]\n }\n\n resetRateLimit(key: string): MaybePromise<void> {\n this._deleteRl.run(key)\n }\n}\n\nexport class SqliteStateStorage implements IStateStorageProvider {\n readonly state\n constructor(readonly driver: BaseSqliteStorageDriver) {\n this.state = new SqliteStateRepository(driver)\n }\n\n static from(provider: BaseSqliteStorage) {\n return new SqliteStateStorage(provider.driver)\n }\n}\n"]}
@@ -1,62 +0,0 @@
1
- import { MaybePromise } from '@mtcute/core';
2
- /**
3
- * Interface for FSM storage for the dispatcher.
4
- *
5
- * All of the officially supported storages already implement
6
- * this interface, so you can just re-use it.
7
- *
8
- * Current scene is a special case of a `string` state,
9
- * Most of the time you can just store it the same way
10
- * as normal state, prefixing with something like `$current_state_`
11
- * (scene name can't start with `$`).
12
- * Alternatively, you can store them as simple strings
13
- */
14
- export interface IStateRepository {
15
- /**
16
- * Retrieve state from the storage
17
- * If state is not found or has expired, return `null`
18
- *
19
- * @param key Key of the state, as defined by {@link StateKeyDelegate}
20
- */
21
- getState(key: string, now: number): MaybePromise<string | null>;
22
- /**
23
- * Save state to the storage
24
- *
25
- * @param key Key of the state, as defined by {@link StateKeyDelegate}
26
- * @param state String representing the state
27
- * @param ttl TTL for the state, in seconds
28
- */
29
- setState(key: string, state: string, ttl?: number): MaybePromise<void>;
30
- /**
31
- * Delete state from the storage
32
- *
33
- * @param key Key of the state, as defined by {@link StateKeyDelegate}
34
- */
35
- deleteState(key: string): MaybePromise<void>;
36
- /**
37
- * Clean up expired states and rate limits.
38
- *
39
- * @param now Current unix time in ms
40
- */
41
- vacuum(now: number): MaybePromise<void>;
42
- /**
43
- * Get information about a rate limit.
44
- *
45
- * It is recommended that you use sliding window or leaky bucket
46
- * to implement rate limiting ([learn more](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm/)),
47
- *
48
- * @param key Key of the rate limit
49
- * @param now Current unix time in ms
50
- * @param limit Maximum number of requests in `window`
51
- * @param window Window size in seconds
52
- * @returns Tuple containing the number of remaining and
53
- * unix time in ms when the user can try again
54
- */
55
- getRateLimit(key: string, now: number, limit: number, window: number): MaybePromise<[number, number]>;
56
- /**
57
- * Reset a rate limit.
58
- *
59
- * @param key Key of the rate limit
60
- */
61
- resetRateLimit(key: string): MaybePromise<void>;
62
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=repository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/state/repository.ts"],"names":[],"mappings":"","sourcesContent":["import { MaybePromise } from '@mtcute/core'\n\n/**\n * Interface for FSM storage for the dispatcher.\n *\n * All of the officially supported storages already implement\n * this interface, so you can just re-use it.\n *\n * Current scene is a special case of a `string` state,\n * Most of the time you can just store it the same way\n * as normal state, prefixing with something like `$current_state_`\n * (scene name can't start with `$`).\n * Alternatively, you can store them as simple strings\n */\nexport interface IStateRepository {\n /**\n * Retrieve state from the storage\n * If state is not found or has expired, return `null`\n *\n * @param key Key of the state, as defined by {@link StateKeyDelegate}\n */\n getState(key: string, now: number): MaybePromise<string | null>\n\n /**\n * Save state to the storage\n *\n * @param key Key of the state, as defined by {@link StateKeyDelegate}\n * @param state String representing the state\n * @param ttl TTL for the state, in seconds\n */\n setState(key: string, state: string, ttl?: number): MaybePromise<void>\n\n /**\n * Delete state from the storage\n *\n * @param key Key of the state, as defined by {@link StateKeyDelegate}\n */\n deleteState(key: string): MaybePromise<void>\n\n /**\n * Clean up expired states and rate limits.\n *\n * @param now Current unix time in ms\n */\n vacuum(now: number): MaybePromise<void>\n\n /**\n * Get information about a rate limit.\n *\n * It is recommended that you use sliding window or leaky bucket\n * to implement rate limiting ([learn more](https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm/)),\n *\n * @param key Key of the rate limit\n * @param now Current unix time in ms\n * @param limit Maximum number of requests in `window`\n * @param window Window size in seconds\n * @returns Tuple containing the number of remaining and\n * unix time in ms when the user can try again\n */\n getRateLimit(key: string, now: number, limit: number, window: number): MaybePromise<[number, number]>\n\n /**\n * Reset a rate limit.\n *\n * @param key Key of the rate limit\n */\n resetRateLimit(key: string): MaybePromise<void>\n}\n"]}
@@ -1,19 +0,0 @@
1
- import { IStateStorageProvider } from './provider.js';
2
- export declare class StateService {
3
- readonly provider: IStateStorageProvider;
4
- constructor(provider: IStateStorageProvider);
5
- private _cache;
6
- private _vacuumTimer?;
7
- private _loaded;
8
- private _load;
9
- load(): Promise<void>;
10
- destroy(): Promise<void>;
11
- getState<T>(key: string): Promise<T | null>;
12
- setState<T>(key: string, state: T, ttl?: number): Promise<void>;
13
- deleteState(key: string): Promise<void>;
14
- getCurrentScene(key: string): Promise<string | null>;
15
- setCurrentScene(key: string, scene: string, ttl?: number): Promise<void>;
16
- deleteCurrentScene(key: string): Promise<void>;
17
- getRateLimit(key: string, limit: number, window: number): import("@mtcute/core").MaybePromise<[number, number]>;
18
- resetRateLimit(key: string): import("@mtcute/core").MaybePromise<void>;
19
- }
@@ -1,70 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StateService = void 0;
4
- const utils_js_1 = require("@mtcute/core/utils.js");
5
- const makeCurrentSceneKey = (key) => `$current_scene_${key}`;
6
- class StateService {
7
- provider;
8
- constructor(provider) {
9
- this.provider = provider;
10
- }
11
- _cache = new utils_js_1.LruMap(100);
12
- _vacuumTimer;
13
- _loaded = false;
14
- _load = (0, utils_js_1.asyncResettable)(async () => {
15
- await this.provider.driver.load?.();
16
- this._loaded = true;
17
- });
18
- async load() {
19
- await this._load.run();
20
- this._vacuumTimer = setInterval(() => {
21
- Promise.resolve(this.provider.state.vacuum(Date.now())).catch(() => { });
22
- }, 300_000);
23
- }
24
- async destroy() {
25
- await this.provider.driver.save?.();
26
- await this.provider.driver.destroy?.();
27
- clearInterval(this._vacuumTimer);
28
- this._loaded = false;
29
- }
30
- async getState(key) {
31
- if (!this._loaded)
32
- await this.load();
33
- const cached = this._cache.get(key);
34
- if (cached)
35
- return cached;
36
- const state = await this.provider.state.getState(key, Date.now());
37
- if (!state)
38
- return null;
39
- return JSON.parse(state);
40
- }
41
- async setState(key, state, ttl) {
42
- if (!this._loaded)
43
- await this.load();
44
- this._cache.set(key, state);
45
- await this.provider.state.setState(key, JSON.stringify(state), ttl);
46
- }
47
- async deleteState(key) {
48
- if (!this._loaded)
49
- await this.load();
50
- this._cache.delete(key);
51
- await this.provider.state.deleteState(key);
52
- }
53
- getCurrentScene(key) {
54
- return this.getState(makeCurrentSceneKey(key));
55
- }
56
- setCurrentScene(key, scene, ttl) {
57
- return this.setState(makeCurrentSceneKey(key), scene, ttl);
58
- }
59
- deleteCurrentScene(key) {
60
- return this.deleteState(makeCurrentSceneKey(key));
61
- }
62
- getRateLimit(key, limit, window) {
63
- return this.provider.state.getRateLimit(key, Date.now(), limit, window);
64
- }
65
- resetRateLimit(key) {
66
- return this.provider.state.resetRateLimit(key);
67
- }
68
- }
69
- exports.StateService = StateService;
70
- //# sourceMappingURL=service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/state/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { asyncResettable, LruMap } from '@mtcute/core/utils.js'\n\nimport { IStateStorageProvider } from './provider.js'\n\nconst makeCurrentSceneKey = (key: string) => `$current_scene_${key}`\n\nexport class StateService {\n constructor(readonly provider: IStateStorageProvider) {}\n\n private _cache: LruMap<string, unknown> = new LruMap(100)\n private _vacuumTimer?: NodeJS.Timeout\n\n private _loaded = false\n private _load = asyncResettable(async () => {\n await this.provider.driver.load?.()\n this._loaded = true\n })\n async load() {\n await this._load.run()\n this._vacuumTimer = setInterval(() => {\n Promise.resolve(this.provider.state.vacuum(Date.now())).catch(() => {})\n }, 300_000)\n }\n\n async destroy() {\n await this.provider.driver.save?.()\n await this.provider.driver.destroy?.()\n clearInterval(this._vacuumTimer)\n this._loaded = false\n }\n\n async getState<T>(key: string): Promise<T | null> {\n if (!this._loaded) await this.load()\n\n const cached = this._cache.get(key)\n if (cached) return cached as T\n\n const state = await this.provider.state.getState(key, Date.now())\n if (!state) return null\n\n return JSON.parse(state) as T\n }\n\n async setState<T>(key: string, state: T, ttl?: number): Promise<void> {\n if (!this._loaded) await this.load()\n\n this._cache.set(key, state)\n await this.provider.state.setState(key, JSON.stringify(state), ttl)\n }\n\n async deleteState(key: string): Promise<void> {\n if (!this._loaded) await this.load()\n\n this._cache.delete(key)\n await this.provider.state.deleteState(key)\n }\n\n getCurrentScene(key: string): Promise<string | null> {\n return this.getState(makeCurrentSceneKey(key))\n }\n\n setCurrentScene(key: string, scene: string, ttl?: number): Promise<void> {\n return this.setState(makeCurrentSceneKey(key), scene, ttl)\n }\n\n deleteCurrentScene(key: string): Promise<void> {\n return this.deleteState(makeCurrentSceneKey(key))\n }\n\n getRateLimit(key: string, limit: number, window: number) {\n return this.provider.state.getRateLimit(key, Date.now(), limit, window)\n }\n\n resetRateLimit(key: string) {\n return this.provider.state.resetRateLimit(key)\n }\n}\n"]}