@mtcute/dispatcher 0.16.7 → 0.16.13

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 (237) hide show
  1. package/{cjs/callback-data-builder.d.ts → callback-data-builder.d.ts} +2 -2
  2. package/callback-data-builder.test.d.ts +1 -0
  3. package/{esm/context → context}/base.d.ts +2 -2
  4. package/{esm/context → context}/business-message.d.ts +5 -6
  5. package/{esm/context → context}/callback-query.d.ts +6 -7
  6. package/{cjs/context → context}/chat-join-request.d.ts +3 -3
  7. package/{esm/context → context}/chosen-inline-result.d.ts +3 -3
  8. package/{esm/context → context}/inline-query.d.ts +4 -5
  9. package/{cjs/context → context}/message.d.ts +11 -6
  10. package/{cjs/context → context}/parse.d.ts +3 -3
  11. package/{esm/context → context}/pre-checkout-query.d.ts +3 -3
  12. package/{esm/context → context}/scene-transition.d.ts +1 -1
  13. package/{cjs/dispatcher.d.ts → dispatcher.d.ts} +9 -10
  14. package/{cjs/filters → filters}/bots.d.ts +4 -4
  15. package/filters/bots.test.d.ts +1 -0
  16. package/{cjs/filters → filters}/chat.d.ts +3 -3
  17. package/{esm/filters → filters}/group.d.ts +4 -4
  18. package/{cjs/filters → filters}/logic.d.ts +1 -1
  19. package/filters/logic.test.d.ts +1 -0
  20. package/{esm/filters → filters}/message.d.ts +9 -5
  21. package/{cjs/filters → filters}/state.d.ts +2 -2
  22. package/{esm/filters → filters}/text.d.ts +3 -3
  23. package/{cjs/filters → filters}/types.d.ts +2 -2
  24. package/{cjs/filters → filters}/updates.d.ts +2 -2
  25. package/{cjs/filters → filters}/user.d.ts +3 -4
  26. package/{cjs/handler.d.ts → handler.d.ts} +5 -5
  27. package/index.cjs +2534 -0
  28. package/index.d.ts +8 -1
  29. package/index.js +2529 -1
  30. package/package.json +28 -24
  31. package/{cjs/state → state}/key.d.ts +3 -3
  32. package/state/provider.d.ts +5 -0
  33. package/{cjs/state → state}/providers/memory.d.ts +3 -4
  34. package/{esm/state → state}/providers/sqlite.d.ts +3 -3
  35. package/{cjs/state → state}/repository.d.ts +1 -1
  36. package/{esm/state → state}/service.d.ts +2 -2
  37. package/{cjs/state → state}/update-state.d.ts +2 -2
  38. package/{esm/wizard.d.ts → wizard.d.ts} +5 -6
  39. package/cjs/callback-data-builder.js +0 -141
  40. package/cjs/callback-data-builder.js.map +0 -1
  41. package/cjs/context/base.d.ts +0 -9
  42. package/cjs/context/base.js +0 -3
  43. package/cjs/context/base.js.map +0 -1
  44. package/cjs/context/business-message.d.ts +0 -61
  45. package/cjs/context/business-message.js +0 -146
  46. package/cjs/context/business-message.js.map +0 -1
  47. package/cjs/context/callback-query.d.ts +0 -63
  48. package/cjs/context/callback-query.js +0 -109
  49. package/cjs/context/callback-query.js.map +0 -1
  50. package/cjs/context/chat-join-request.js +0 -35
  51. package/cjs/context/chat-join-request.js.map +0 -1
  52. package/cjs/context/chosen-inline-result.d.ts +0 -22
  53. package/cjs/context/chosen-inline-result.js +0 -36
  54. package/cjs/context/chosen-inline-result.js.map +0 -1
  55. package/cjs/context/index.js +0 -25
  56. package/cjs/context/index.js.map +0 -1
  57. package/cjs/context/inline-query.d.ts +0 -16
  58. package/cjs/context/inline-query.js +0 -23
  59. package/cjs/context/inline-query.js.map +0 -1
  60. package/cjs/context/message.js +0 -171
  61. package/cjs/context/message.js.map +0 -1
  62. package/cjs/context/parse.js +0 -42
  63. package/cjs/context/parse.js.map +0 -1
  64. package/cjs/context/pre-checkout-query.d.ts +0 -17
  65. package/cjs/context/pre-checkout-query.js +0 -27
  66. package/cjs/context/pre-checkout-query.js.map +0 -1
  67. package/cjs/context/scene-transition.d.ts +0 -24
  68. package/cjs/context/scene-transition.js +0 -52
  69. package/cjs/context/scene-transition.js.map +0 -1
  70. package/cjs/dispatcher.js +0 -908
  71. package/cjs/dispatcher.js.map +0 -1
  72. package/cjs/filters/bots.js +0 -135
  73. package/cjs/filters/bots.js.map +0 -1
  74. package/cjs/filters/bundle.js +0 -27
  75. package/cjs/filters/bundle.js.map +0 -1
  76. package/cjs/filters/chat.js +0 -56
  77. package/cjs/filters/chat.js.map +0 -1
  78. package/cjs/filters/group.d.ts +0 -26
  79. package/cjs/filters/group.js +0 -69
  80. package/cjs/filters/group.js.map +0 -1
  81. package/cjs/filters/index.js +0 -29
  82. package/cjs/filters/index.js.map +0 -1
  83. package/cjs/filters/logic.js +0 -112
  84. package/cjs/filters/logic.js.map +0 -1
  85. package/cjs/filters/message.d.ts +0 -215
  86. package/cjs/filters/message.js +0 -191
  87. package/cjs/filters/message.js.map +0 -1
  88. package/cjs/filters/state.js +0 -33
  89. package/cjs/filters/state.js.map +0 -1
  90. package/cjs/filters/text.d.ts +0 -64
  91. package/cjs/filters/text.js +0 -136
  92. package/cjs/filters/text.js.map +0 -1
  93. package/cjs/filters/types.js +0 -3
  94. package/cjs/filters/types.js.map +0 -1
  95. package/cjs/filters/updates.js +0 -40
  96. package/cjs/filters/updates.js.map +0 -1
  97. package/cjs/filters/user.js +0 -77
  98. package/cjs/filters/user.js.map +0 -1
  99. package/cjs/handler.js +0 -4
  100. package/cjs/handler.js.map +0 -1
  101. package/cjs/index.js +0 -31
  102. package/cjs/index.js.map +0 -1
  103. package/cjs/package.json +0 -3
  104. package/cjs/propagation.js +0 -27
  105. package/cjs/propagation.js.map +0 -1
  106. package/cjs/state/index.js +0 -22
  107. package/cjs/state/index.js.map +0 -1
  108. package/cjs/state/key.js +0 -43
  109. package/cjs/state/key.js.map +0 -1
  110. package/cjs/state/provider.d.ts +0 -5
  111. package/cjs/state/provider.js +0 -3
  112. package/cjs/state/provider.js.map +0 -1
  113. package/cjs/state/providers/index.js +0 -19
  114. package/cjs/state/providers/index.js.map +0 -1
  115. package/cjs/state/providers/memory.js +0 -81
  116. package/cjs/state/providers/memory.js.map +0 -1
  117. package/cjs/state/providers/sqlite.d.ts +0 -28
  118. package/cjs/state/providers/sqlite.js +0 -100
  119. package/cjs/state/providers/sqlite.js.map +0 -1
  120. package/cjs/state/repository.js +0 -3
  121. package/cjs/state/repository.js.map +0 -1
  122. package/cjs/state/service.d.ts +0 -20
  123. package/cjs/state/service.js +0 -70
  124. package/cjs/state/service.js.map +0 -1
  125. package/cjs/state/update-state.js +0 -219
  126. package/cjs/state/update-state.js.map +0 -1
  127. package/cjs/wizard.d.ts +0 -65
  128. package/cjs/wizard.js +0 -105
  129. package/cjs/wizard.js.map +0 -1
  130. package/esm/callback-data-builder.d.ts +0 -49
  131. package/esm/callback-data-builder.js +0 -137
  132. package/esm/callback-data-builder.js.map +0 -1
  133. package/esm/context/base.js +0 -2
  134. package/esm/context/base.js.map +0 -1
  135. package/esm/context/business-message.js +0 -142
  136. package/esm/context/business-message.js.map +0 -1
  137. package/esm/context/callback-query.js +0 -103
  138. package/esm/context/callback-query.js.map +0 -1
  139. package/esm/context/chat-join-request.d.ts +0 -17
  140. package/esm/context/chat-join-request.js +0 -31
  141. package/esm/context/chat-join-request.js.map +0 -1
  142. package/esm/context/chosen-inline-result.js +0 -32
  143. package/esm/context/chosen-inline-result.js.map +0 -1
  144. package/esm/context/index.d.ts +0 -9
  145. package/esm/context/index.js +0 -9
  146. package/esm/context/index.js.map +0 -1
  147. package/esm/context/inline-query.js +0 -19
  148. package/esm/context/inline-query.js.map +0 -1
  149. package/esm/context/message.d.ts +0 -77
  150. package/esm/context/message.js +0 -167
  151. package/esm/context/message.js.map +0 -1
  152. package/esm/context/parse.d.ts +0 -13
  153. package/esm/context/parse.js +0 -39
  154. package/esm/context/parse.js.map +0 -1
  155. package/esm/context/pre-checkout-query.js +0 -23
  156. package/esm/context/pre-checkout-query.js.map +0 -1
  157. package/esm/context/scene-transition.js +0 -48
  158. package/esm/context/scene-transition.js.map +0 -1
  159. package/esm/dispatcher.d.ts +0 -881
  160. package/esm/dispatcher.js +0 -904
  161. package/esm/dispatcher.js.map +0 -1
  162. package/esm/filters/bots.d.ts +0 -64
  163. package/esm/filters/bots.js +0 -131
  164. package/esm/filters/bots.js.map +0 -1
  165. package/esm/filters/bundle.d.ts +0 -10
  166. package/esm/filters/bundle.js +0 -11
  167. package/esm/filters/bundle.js.map +0 -1
  168. package/esm/filters/chat.d.ts +0 -27
  169. package/esm/filters/chat.js +0 -51
  170. package/esm/filters/chat.js.map +0 -1
  171. package/esm/filters/group.js +0 -65
  172. package/esm/filters/group.js.map +0 -1
  173. package/esm/filters/index.d.ts +0 -4
  174. package/esm/filters/index.js +0 -3
  175. package/esm/filters/index.js.map +0 -1
  176. package/esm/filters/logic.d.ts +0 -29
  177. package/esm/filters/logic.js +0 -105
  178. package/esm/filters/logic.js.map +0 -1
  179. package/esm/filters/message.js +0 -168
  180. package/esm/filters/message.js.map +0 -1
  181. package/esm/filters/state.d.ts +0 -15
  182. package/esm/filters/state.js +0 -28
  183. package/esm/filters/state.js.map +0 -1
  184. package/esm/filters/text.js +0 -129
  185. package/esm/filters/text.js.map +0 -1
  186. package/esm/filters/types.d.ts +0 -91
  187. package/esm/filters/types.js +0 -2
  188. package/esm/filters/types.js.map +0 -1
  189. package/esm/filters/updates.d.ts +0 -39
  190. package/esm/filters/updates.js +0 -34
  191. package/esm/filters/updates.js.map +0 -1
  192. package/esm/filters/user.d.ts +0 -25
  193. package/esm/filters/user.js +0 -71
  194. package/esm/filters/user.js.map +0 -1
  195. package/esm/handler.d.ts +0 -41
  196. package/esm/handler.js +0 -3
  197. package/esm/handler.js.map +0 -1
  198. package/esm/index.d.ts +0 -8
  199. package/esm/index.js +0 -9
  200. package/esm/index.js.map +0 -1
  201. package/esm/propagation.d.ts +0 -22
  202. package/esm/propagation.js +0 -24
  203. package/esm/propagation.js.map +0 -1
  204. package/esm/state/index.d.ts +0 -5
  205. package/esm/state/index.js +0 -6
  206. package/esm/state/index.js.map +0 -1
  207. package/esm/state/key.d.ts +0 -24
  208. package/esm/state/key.js +0 -39
  209. package/esm/state/key.js.map +0 -1
  210. package/esm/state/provider.d.ts +0 -5
  211. package/esm/state/provider.js +0 -2
  212. package/esm/state/provider.js.map +0 -1
  213. package/esm/state/providers/index.d.ts +0 -2
  214. package/esm/state/providers/index.js +0 -3
  215. package/esm/state/providers/index.js.map +0 -1
  216. package/esm/state/providers/memory.d.ts +0 -30
  217. package/esm/state/providers/memory.js +0 -77
  218. package/esm/state/providers/memory.js.map +0 -1
  219. package/esm/state/providers/sqlite.js +0 -96
  220. package/esm/state/providers/sqlite.js.map +0 -1
  221. package/esm/state/repository.d.ts +0 -62
  222. package/esm/state/repository.js +0 -2
  223. package/esm/state/repository.js.map +0 -1
  224. package/esm/state/service.js +0 -66
  225. package/esm/state/service.js.map +0 -1
  226. package/esm/state/update-state.d.ts +0 -151
  227. package/esm/state/update-state.js +0 -214
  228. package/esm/state/update-state.js.map +0 -1
  229. package/esm/wizard.js +0 -101
  230. package/esm/wizard.js.map +0 -1
  231. /package/{cjs/context → context}/index.d.ts +0 -0
  232. /package/{cjs/filters → filters}/bundle.d.ts +0 -0
  233. /package/{cjs/filters → filters}/index.d.ts +0 -0
  234. /package/{cjs/index.d.ts → index.d.cts} +0 -0
  235. /package/{cjs/propagation.d.ts → propagation.d.ts} +0 -0
  236. /package/{cjs/state → state}/index.d.ts +0 -0
  237. /package/{cjs/state → state}/providers/index.d.ts +0 -0
package/cjs/dispatcher.js DELETED
@@ -1,908 +0,0 @@
1
- "use strict";
2
- /* eslint-disable ts/no-unsafe-assignment */
3
- /* eslint-disable ts/no-unsafe-argument */
4
- /* eslint-disable ts/no-empty-object-type */
5
- // ^^ will be looked into in MTQ-29
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Dispatcher = void 0;
8
- const core_1 = require("@mtcute/core");
9
- const parse_js_1 = require("./context/parse.js");
10
- const scene_transition_js_1 = require("./context/scene-transition.js");
11
- const index_js_1 = require("./state/index.js");
12
- const service_js_1 = require("./state/service.js");
13
- /**
14
- * Updates dispatcher
15
- */
16
- class Dispatcher {
17
- _groups = new Map();
18
- _groupsOrder = [];
19
- _client;
20
- _parent;
21
- _children = [];
22
- _scenes;
23
- _scene;
24
- _sceneScoped;
25
- _storage;
26
- _stateKeyDelegate;
27
- _customStateKeyDelegate;
28
- _customStorage;
29
- _deps = {};
30
- _errorHandler;
31
- _preUpdateHandler;
32
- _postUpdateHandler;
33
- _sceneTransitionHandler;
34
- constructor(client, params) {
35
- this.dispatchRawUpdate = this.dispatchRawUpdate.bind(this);
36
- this.dispatchUpdate = this.dispatchUpdate.bind(this);
37
- // eslint-disable-next-line prefer-const
38
- let { storage, key, sceneName } = params ?? {};
39
- if (client) {
40
- this.bindToClient(client);
41
- if (storage) {
42
- this._storage = new service_js_1.StateService(storage);
43
- this._stateKeyDelegate = key ?? index_js_1.defaultStateKeyDelegate;
44
- }
45
- }
46
- else {
47
- // child dispatcher without client
48
- if (storage) {
49
- this._customStorage = new service_js_1.StateService(storage);
50
- }
51
- if (key) {
52
- this._customStateKeyDelegate = key;
53
- }
54
- if (sceneName) {
55
- if (sceneName[0] === '$') {
56
- throw new core_1.MtArgumentError('Scene name cannot start with $');
57
- }
58
- this._scene = sceneName;
59
- }
60
- }
61
- }
62
- static for(client, params) {
63
- return new Dispatcher(client, params);
64
- }
65
- /**
66
- * Create a new child dispatcher.
67
- */
68
- static child(params) {
69
- return new Dispatcher(undefined, params);
70
- }
71
- /**
72
- * Create a new scene dispatcher
73
- */
74
- static scene(name, params) {
75
- return new Dispatcher(undefined, { sceneName: name, ...params });
76
- }
77
- /** For scene dispatchers, name of the scene */
78
- get sceneName() {
79
- return this._scene;
80
- }
81
- inject(name, value) {
82
- if (this._parent) {
83
- throw new core_1.MtArgumentError('Cannot inject dependencies to child dispatchers');
84
- }
85
- if (typeof name === 'object') {
86
- for (const [k, v] of Object.entries(name)) {
87
- this._deps[k] = v;
88
- }
89
- }
90
- else {
91
- this._deps[name] = value;
92
- }
93
- }
94
- /**
95
- * Get the dependencies injected into this dispatcher.
96
- */
97
- get deps() {
98
- return this._deps;
99
- }
100
- /**
101
- * Bind the dispatcher to the client.
102
- * Called by the constructor automatically if
103
- * `client` was passed.
104
- *
105
- * Dispatcher also uses bound client to throw errors
106
- */
107
- bindToClient(client) {
108
- client.on('update', this.dispatchUpdate);
109
- client.on('raw_update', this.dispatchRawUpdate);
110
- this._client = client;
111
- }
112
- /**
113
- * Unbind a dispatcher from the client.
114
- */
115
- unbind() {
116
- if (this._client) {
117
- this._client.off('update', this.dispatchUpdate);
118
- this._client.off('raw_update', this.dispatchRawUpdate);
119
- this._client = undefined;
120
- }
121
- }
122
- /**
123
- * Destroy the dispatcher and all its children.
124
- *
125
- * When destroying, all the registered handlers are removed,
126
- * and the underlying storage is freed.
127
- */
128
- async destroy() {
129
- if (this._parent && this._customStorage) {
130
- await this._customStorage.destroy();
131
- }
132
- else if (!this._parent && this._storage) {
133
- await this._storage.destroy();
134
- }
135
- this.removeUpdateHandler('all');
136
- for (const child of this._children) {
137
- await child.destroy();
138
- }
139
- for (const scene of this._scenes?.values() ?? []) {
140
- await scene.destroy();
141
- }
142
- }
143
- /**
144
- * Process a raw update with this dispatcher.
145
- * Calling this method without bound client will not work.
146
- *
147
- * Under the hood asynchronously calls {@link dispatchRawUpdateNow}
148
- * with error handler set to client's one.
149
- *
150
- * @param update Update to process
151
- * @param peers Peers index
152
- */
153
- dispatchRawUpdate(update, peers) {
154
- if (!this._client)
155
- return;
156
- // order does not matter in the dispatcher,
157
- // so we can handle each update in its own task
158
- this.dispatchRawUpdateNow(update, peers).catch(err => this._client.emitError(err));
159
- }
160
- /**
161
- * Process a raw update right now in the current stack.
162
- *
163
- * Unlike {@link dispatchRawUpdate}, this does not schedule
164
- * the update to be dispatched, but dispatches it immediately,
165
- * and after `await`ing this method you can be certain that the update
166
- * was fully processed by all the registered handlers, including children.
167
- *
168
- * @param update Update to process
169
- * @param peers Peers map
170
- * @returns Whether the update was handled
171
- */
172
- async dispatchRawUpdateNow(update, peers) {
173
- if (!this._client)
174
- return false;
175
- let handled = false;
176
- outer: for (const grp of this._groupsOrder) {
177
- const group = this._groups.get(grp);
178
- if (group.has('raw')) {
179
- const handlers = group.get('raw');
180
- for (const h of handlers) {
181
- let result;
182
- if (!h.check || (await h.check(this._client, update, peers))) {
183
- result = await h.callback(this._client, update, peers);
184
- handled = true;
185
- }
186
- else {
187
- continue;
188
- }
189
- switch (result) {
190
- case 'continue':
191
- continue;
192
- case 'stop':
193
- break outer;
194
- case 'stop-children':
195
- return handled;
196
- }
197
- break;
198
- }
199
- }
200
- }
201
- for (const child of this._children) {
202
- const childHandled = await child.dispatchRawUpdateNow(update, peers);
203
- handled ||= childHandled;
204
- }
205
- return handled;
206
- }
207
- /**
208
- * Process an update with this dispatcher.
209
- * Calling this method without bound client will not work.
210
- *
211
- * Under the hood asynchronously calls {@link dispatchUpdateNow}
212
- * with error handler set to client's one.
213
- *
214
- * @param update Update to process
215
- */
216
- dispatchUpdate(update) {
217
- if (!this._client)
218
- return;
219
- // order does not matter in the dispatcher,
220
- // so we can handle each update in its own task
221
- this.dispatchUpdateNow(update).catch(err => this._client.emitError(err));
222
- }
223
- /**
224
- * Process an update right now in the current stack.
225
- *
226
- * Unlike {@link dispatchUpdate}, this does not schedule
227
- * the update to be dispatched, but dispatches it immediately,
228
- * and after `await`ing this method you can be certain that the update
229
- * was fully processed by all the registered handlers, including children.
230
- *
231
- * @param update Update to process
232
- * @returns Whether the update was handled
233
- */
234
- async dispatchUpdateNow(update) {
235
- return this._dispatchUpdateNowImpl(update);
236
- }
237
- async _dispatchUpdateNowImpl(update,
238
- // this is getting a bit crazy lol
239
- parsedState, parsedScene, forceScene, parsedContext) {
240
- if (!this._client)
241
- return false;
242
- if (parsedScene === undefined) {
243
- if (this._storage
244
- && this._scenes
245
- && (update.name === 'new_message'
246
- || update.name === 'edit_message'
247
- || update.name === 'callback_query'
248
- || update.name === 'message_group'
249
- || update.name === 'new_business_message'
250
- || update.name === 'edit_business_message'
251
- || update.name === 'business_message_group')) {
252
- // no need to fetch scene if there are no registered scenes
253
- if (!parsedContext)
254
- parsedContext = (0, parse_js_1._parsedUpdateToContext)(this._client, update);
255
- const key = await this._stateKeyDelegate(parsedContext);
256
- if (key) {
257
- parsedScene = await this._storage.getCurrentScene(key);
258
- }
259
- else {
260
- parsedScene = null;
261
- }
262
- }
263
- else {
264
- parsedScene = null;
265
- }
266
- }
267
- if (!forceScene && parsedScene !== null) {
268
- if (this._scene) {
269
- if (this._scene !== parsedScene) {
270
- // should not happen, but just in case
271
- return false;
272
- }
273
- }
274
- else {
275
- if (!this._scenes || !this._scenes.has(parsedScene)) {
276
- // not registered scene
277
- return false;
278
- }
279
- return this._scenes.get(parsedScene)._dispatchUpdateNowImpl(update, parsedState, parsedScene, true);
280
- }
281
- }
282
- if (parsedState === undefined) {
283
- if (this._storage
284
- && (update.name === 'new_message'
285
- || update.name === 'edit_message'
286
- || update.name === 'callback_query'
287
- || update.name === 'message_group'
288
- || update.name === 'new_business_message'
289
- || update.name === 'edit_business_message'
290
- || update.name === 'business_message_group')) {
291
- if (!parsedContext)
292
- parsedContext = (0, parse_js_1._parsedUpdateToContext)(this._client, update);
293
- const key = await this._stateKeyDelegate(parsedContext);
294
- if (key) {
295
- let customKey;
296
- if (!this._customStateKeyDelegate
297
- || (customKey = await this._customStateKeyDelegate(parsedContext))) {
298
- parsedState = new index_js_1.UpdateState(this._storage, key, this._scene ?? null, this._sceneScoped, this._customStorage, customKey);
299
- }
300
- }
301
- else {
302
- parsedState = null;
303
- }
304
- }
305
- else {
306
- parsedState = null;
307
- }
308
- }
309
- let shouldDispatch = true;
310
- let shouldDispatchChildren = true;
311
- let handled = false;
312
- switch (await this._preUpdateHandler?.(update, parsedState)) {
313
- case 'stop':
314
- shouldDispatch = false;
315
- break;
316
- case 'stop-children':
317
- return false;
318
- }
319
- if (shouldDispatch) {
320
- outer: for (const grp of this._groupsOrder) {
321
- const group = this._groups.get(grp);
322
- if (group.has(update.name)) {
323
- // raw is not handled here, so we can safely assume this
324
- const handlers = group.get(update.name);
325
- try {
326
- for (const h of handlers) {
327
- let result;
328
- if (!parsedContext)
329
- parsedContext = (0, parse_js_1._parsedUpdateToContext)(this._client, update);
330
- if (!h.check || (await h.check(parsedContext, parsedState))) {
331
- result = await h.callback(parsedContext, parsedState);
332
- handled = true;
333
- }
334
- else {
335
- continue;
336
- }
337
- if (parsedState && this._scenes) {
338
- // check if scene transition was made
339
- const newScene = parsedState.scene;
340
- if (parsedScene !== newScene) {
341
- const nextDp = newScene ? this._scenes.get(newScene) : this._parent;
342
- if (!nextDp) {
343
- throw new core_1.MtArgumentError(`Scene ${newScene} not found`);
344
- }
345
- if (nextDp._sceneTransitionHandler) {
346
- const transition = new scene_transition_js_1.SceneTransitionContext(parsedScene, parsedContext);
347
- const transitionResult = await nextDp._sceneTransitionHandler?.(transition, parsedState);
348
- switch (transitionResult) {
349
- case 'stop':
350
- return true;
351
- case 'continue':
352
- continue;
353
- case 'scene': {
354
- const scene = parsedState.scene;
355
- const dp = scene ? nextDp._scenes.get(scene) : nextDp._parent;
356
- // eslint-disable-next-line ts/return-await
357
- return dp._dispatchUpdateNowImpl(update, undefined, scene, true);
358
- }
359
- }
360
- }
361
- }
362
- }
363
- switch (result) {
364
- case 'continue':
365
- continue;
366
- case 'stop':
367
- break outer;
368
- case 'stop-children':
369
- shouldDispatchChildren = false;
370
- break outer;
371
- case 'scene': {
372
- if (!parsedState) {
373
- throw new core_1.MtArgumentError('Cannot use ToScene without state');
374
- }
375
- const scene = parsedState.scene;
376
- const dp = scene ? this._scenes.get(scene) : this._parent;
377
- // eslint-disable-next-line ts/return-await
378
- return dp._dispatchUpdateNowImpl(update, undefined, scene, true);
379
- }
380
- }
381
- break;
382
- }
383
- }
384
- catch (e) {
385
- if (this._errorHandler) {
386
- const handled = await this._errorHandler(e, update, parsedState);
387
- if (!handled)
388
- throw e;
389
- }
390
- else {
391
- throw e;
392
- }
393
- }
394
- }
395
- }
396
- }
397
- if (shouldDispatchChildren) {
398
- for (const child of this._children) {
399
- const childHandled = await child._dispatchUpdateNowImpl(update);
400
- handled ||= childHandled;
401
- }
402
- }
403
- await this._postUpdateHandler?.(handled, update, parsedState);
404
- return handled;
405
- }
406
- /**
407
- * Add an update handler to a given handlers group
408
- *
409
- * @param handler Update handler
410
- * @param group Handler group index
411
- */
412
- addUpdateHandler(handler, group = 0) {
413
- if (!this._groups.has(group)) {
414
- this._groups.set(group, new Map());
415
- this._groupsOrder.push(group);
416
- this._groupsOrder.sort((a, b) => a - b);
417
- }
418
- if (!this._groups.get(group).has(handler.name)) {
419
- this._groups.get(group).set(handler.name, []);
420
- }
421
- this._groups.get(group).get(handler.name).push(handler);
422
- }
423
- /**
424
- * Remove an update handler (or handlers) from a given
425
- * handler group.
426
- *
427
- * @param handler Update handler to remove, its name or `'all'` to remove all
428
- * @param group Handler group index (null to affect all groups)
429
- */
430
- removeUpdateHandler(handler, group = 0) {
431
- if (group !== null && !this._groups.has(group)) {
432
- return;
433
- }
434
- if (typeof handler === 'string') {
435
- if (handler === 'all') {
436
- if (group === null) {
437
- this._groups = new Map();
438
- }
439
- else {
440
- this._groups.delete(group);
441
- }
442
- }
443
- else if (group !== null) {
444
- this._groups.get(group).delete(handler);
445
- }
446
- return;
447
- }
448
- if (group === null)
449
- return;
450
- if (!this._groups.get(group).has(handler.name)) {
451
- return;
452
- }
453
- const idx = this._groups.get(group).get(handler.name).indexOf(handler);
454
- if (idx > -1) {
455
- this._groups.get(group).get(handler.name).splice(idx, 1);
456
- }
457
- }
458
- /**
459
- * Register an error handler.
460
- *
461
- * This is used locally within this dispatcher
462
- * (does not affect children/parent) whenever
463
- * an error is thrown inside an update handler.
464
- * Not used for raw update handlers
465
- *
466
- * When an error is thrown, but there is no error
467
- * handler, it is propagated to `TelegramClient`.
468
- *
469
- * There can be at most one error handler.
470
- * Pass `null` to remove it.
471
- *
472
- * @param handler Error handler
473
- */
474
- onError(handler) {
475
- if (handler)
476
- this._errorHandler = handler;
477
- else
478
- this._errorHandler = undefined;
479
- }
480
- /**
481
- * Register pre-update middleware.
482
- *
483
- * This is used locally within this dispatcher
484
- * (does not affect children/parent) before processing
485
- * an update, and can be used to skip this update.
486
- *
487
- * There can be at most one pre-update middleware.
488
- * Pass `null` to remove it.
489
- *
490
- * @param handler Pre-update middleware
491
- */
492
- onPreUpdate(handler) {
493
- if (handler)
494
- this._preUpdateHandler = handler;
495
- else
496
- this._preUpdateHandler = undefined;
497
- }
498
- /**
499
- * Register post-update middleware.
500
- *
501
- * This is used locally within this dispatcher
502
- * (does not affect children/parent) after successfully
503
- * processing an update, and can be used for stats.
504
- *
505
- * There can be at most one post-update middleware.
506
- * Pass `null` to remove it.
507
- *
508
- * @param handler Pre-update middleware
509
- */
510
- onPostUpdate(handler) {
511
- if (handler)
512
- this._postUpdateHandler = handler;
513
- else
514
- this._postUpdateHandler = undefined;
515
- }
516
- /**
517
- * Set error handler that will propagate
518
- * the error to the parent dispatcher
519
- */
520
- propagateErrorToParent(err, update, state) {
521
- if (!this.parent) {
522
- throw new core_1.MtArgumentError('This dispatcher is not a child');
523
- }
524
- if (this.parent._errorHandler) {
525
- return this.parent._errorHandler(err, update, state);
526
- }
527
- throw err;
528
- }
529
- // children //
530
- /**
531
- * Get parent dispatcher if current dispatcher is a child.
532
- * Otherwise, return `null`
533
- */
534
- get parent() {
535
- return this._parent ?? null;
536
- }
537
- _prepareChild(child) {
538
- if (child._client) {
539
- throw new core_1.MtArgumentError(`Provided dispatcher is ${child._parent
540
- ? 'already a child. Use parent.removeChild() before calling addChild()'
541
- : 'already bound to a client. Use unbind() before calling addChild()'}`);
542
- }
543
- child._parent = this;
544
- child._client = this._client;
545
- child._storage = this._storage;
546
- child._deps = this._deps;
547
- child._scenes = this._scenes;
548
- child._stateKeyDelegate = this._stateKeyDelegate;
549
- child._customStorage ??= this._customStorage;
550
- child._customStateKeyDelegate ??= this._customStateKeyDelegate;
551
- }
552
- /**
553
- * Add a child dispatcher.
554
- *
555
- * Child dispatchers are called when dispatching updates
556
- * just like normal, except they can be controlled
557
- * externally. Additionally, child dispatcher have their own
558
- * independent handler grouping that does not interfere with parent's,
559
- * including `StopPropagation` (i.e. returning `StopPropagation` will
560
- * still call children. To entirely stop, use `StopChildrenPropagation`)
561
- *
562
- * Note that child dispatchers share the same TelegramClient and
563
- * storage binding as the parent, don't bind them manually.
564
- *
565
- * @param child Other dispatcher
566
- */
567
- addChild(child) {
568
- if (this._children.includes(child))
569
- return;
570
- this._prepareChild(child);
571
- this._children.push(child);
572
- }
573
- addScene(scene, scoped = true) {
574
- if (!this._scenes)
575
- this._scenes = new Map();
576
- if (!scene._scene) {
577
- throw new core_1.MtArgumentError('Non-scene dispatcher passed to addScene. Use `Dispatcher.scene()` to create one.');
578
- }
579
- if (this._scenes.has(scene._scene)) {
580
- throw new core_1.MtArgumentError(`Scene with name ${scene._scene} is already registered!`);
581
- }
582
- this._prepareChild(scene);
583
- scene._sceneScoped = scoped;
584
- this._scenes.set(scene._scene, scene);
585
- }
586
- /**
587
- * Remove a child dispatcher.
588
- *
589
- * Removing child dispatcher will also remove
590
- * child dispatcher's client binding.
591
- *
592
- * If the provided dispatcher is not a child of current,
593
- * this function will silently fail.
594
- *
595
- * @param child Other dispatcher
596
- */
597
- removeChild(child) {
598
- const idx = this._children.indexOf(child);
599
- if (idx > -1) {
600
- child._unparent();
601
- this._children.splice(idx, 1);
602
- }
603
- }
604
- _unparent() {
605
- this._parent = this._client = undefined;
606
- this._deps = {}; // to avoid dangling references
607
- this._stateKeyDelegate = undefined;
608
- this._storage = undefined;
609
- }
610
- /**
611
- * Extend current dispatcher by copying other dispatcher's
612
- * handlers and children to the current.
613
- *
614
- * This might be more efficient for simple cases, but do note that the handler
615
- * groups, children and scenes will get merged (unlike {@link addChild},
616
- * where they are independent). Also note that unlike with children,
617
- * when adding handlers to `other` *after* you extended
618
- * the current dispatcher, changes will not be applied.
619
- *
620
- * @param other Other dispatcher
621
- */
622
- extend(other) {
623
- if (other._customStorage || other._customStateKeyDelegate) {
624
- throw new core_1.MtArgumentError('Provided dispatcher has custom storage and cannot be extended from.');
625
- }
626
- other._groupsOrder.forEach((group) => {
627
- if (!this._groups.has(group)) {
628
- this._groups.set(group, other._groups.get(group));
629
- this._groupsOrder.push(group);
630
- }
631
- else {
632
- const otherGrp = other._groups.get(group);
633
- const selfGrp = this._groups.get(group);
634
- for (const typ of otherGrp.keys()) {
635
- if (!selfGrp.has(typ)) {
636
- selfGrp.set(typ, otherGrp.get(typ));
637
- }
638
- else {
639
- // selfGrp[typ].push(...otherGrp[typ])
640
- selfGrp.get(typ).push(...otherGrp.get(typ));
641
- }
642
- }
643
- }
644
- });
645
- other._children.forEach((it) => {
646
- it._unparent();
647
- this.addChild(it);
648
- });
649
- if (other._scenes) {
650
- const otherScenes = other._scenes;
651
- if (!this._scenes)
652
- this._scenes = new Map();
653
- const myScenes = this._scenes;
654
- for (const key of otherScenes.keys()) {
655
- otherScenes.get(key)._unparent();
656
- if (myScenes.has(key)) {
657
- // will be overwritten
658
- myScenes.delete(key);
659
- }
660
- this.addScene(otherScenes.get(key), otherScenes.get(key)._sceneScoped);
661
- }
662
- }
663
- this._groupsOrder.sort((a, b) => a - b);
664
- }
665
- /**
666
- * Create a clone of this dispatcher, that has the same handlers,
667
- * but is not bound to a client or to a parent dispatcher.
668
- *
669
- * Custom Storage and key delegate are copied too.
670
- *
671
- * By default, child dispatchers (and scenes) are ignored, since
672
- * that requires cloning every single one of them recursively
673
- * and then binding them back.
674
- *
675
- * @param children Whether to also clone children and scenes
676
- */
677
- clone(children = false) {
678
- const dp = new Dispatcher();
679
- // copy handlers.
680
- for (const key of this._groups.keys()) {
681
- const idx = key;
682
- dp._groups.set(idx, new Map());
683
- for (const type of this._groups.get(idx).keys()) {
684
- // dp._groups.get(idx)!.set(type, [...this._groups.get(idx)!].get(type)!])
685
- dp._groups.get(idx).set(type, [...this._groups.get(idx).get(type)]);
686
- }
687
- }
688
- dp._groupsOrder = [...this._groupsOrder];
689
- dp._errorHandler = this._errorHandler;
690
- dp._customStateKeyDelegate = this._customStateKeyDelegate;
691
- dp._customStorage = this._customStorage;
692
- if (children) {
693
- this._children.forEach((it) => {
694
- const child = it.clone(true);
695
- dp.addChild(child);
696
- });
697
- if (this._scenes) {
698
- for (const key of this._scenes.keys()) {
699
- const scene = this._scenes.get(key).clone(true);
700
- dp.addScene(scene, this._scenes.get(key)._sceneScoped);
701
- }
702
- }
703
- }
704
- return dp;
705
- }
706
- getState(object) {
707
- if (!this._storage) {
708
- throw new core_1.MtArgumentError('Cannot use getUpdateState() filter without state storage');
709
- }
710
- if (typeof object === 'string') {
711
- return new index_js_1.UpdateState(this._storage, object, this._scene ?? null, this._sceneScoped, this._customStorage);
712
- }
713
- return Promise.resolve(this._stateKeyDelegate(object)).then((key) => {
714
- if (!key) {
715
- throw new core_1.MtArgumentError('Cannot derive key from given object');
716
- }
717
- if (!this._customStateKeyDelegate) {
718
- return new index_js_1.UpdateState(this._storage, key, this._scene ?? null, this._sceneScoped, this._customStorage);
719
- }
720
- return Promise.resolve(this._customStateKeyDelegate(object)).then((customKey) => {
721
- if (!customKey) {
722
- throw new core_1.MtArgumentError('Cannot derive custom key from given object');
723
- }
724
- return new index_js_1.UpdateState(this._storage, key, this._scene ?? null, this._sceneScoped, this._customStorage, customKey);
725
- });
726
- });
727
- }
728
- /**
729
- * Get global state.
730
- *
731
- * This will load the state for the given object
732
- * ignoring local custom storage, key delegate and scene scope.
733
- */
734
- getGlobalState(object) {
735
- if (!this._parent) {
736
- throw new core_1.MtArgumentError('This dispatcher does not have a parent');
737
- }
738
- return Promise.resolve(this._stateKeyDelegate(object)).then((key) => {
739
- if (!key) {
740
- throw new core_1.MtArgumentError('Cannot derive key from given object');
741
- }
742
- return new index_js_1.UpdateState(this._storage, key, this._scene ?? null, false);
743
- });
744
- }
745
- // addUpdateHandler convenience wrappers //
746
- _addKnownHandler(name, filter, handler, group) {
747
- if (typeof handler === 'number' || typeof handler === 'undefined') {
748
- this.addUpdateHandler({
749
- name,
750
- callback: filter,
751
- }, handler);
752
- }
753
- else {
754
- this.addUpdateHandler({
755
- name,
756
- callback: handler,
757
- check: filter,
758
- }, group);
759
- }
760
- }
761
- /** @internal */
762
- onRawUpdate(filter, handler, group) {
763
- this._addKnownHandler('raw', filter, handler, group);
764
- }
765
- /**
766
- * Register a scene transition handler
767
- *
768
- * This handler is called whenever a scene transition occurs
769
- * in the context of the scene that is being entered,
770
- * and before any of the its own handlers are called,
771
- * and can be used to customize the transition behavior:
772
- * - `Stop` to prevent dispatching the update any further **even if ToScene/ToRoot was used**
773
- * - `Continue` same as Stop, but still dispatch the update to children
774
- * - `ToScene` to prevent the transition and dispatch the update to the scene entered in the transition handler
775
- *
776
- * > **Note**: if multiple `state.enter()` calls were made within the same update,
777
- * > this handler will only be called for the last one.
778
- *
779
- * @param handler Raw update handler
780
- * @param group Handler group index
781
- */
782
- onSceneTransition(handler) {
783
- if (handler)
784
- this._sceneTransitionHandler = handler;
785
- else
786
- this._sceneTransitionHandler = undefined;
787
- }
788
- /** @internal */
789
- onAnyCallbackQuery(filter, handler, group) {
790
- this._addKnownHandler('callback_query', filter, handler, group);
791
- this._addKnownHandler('inline_callback_query', filter, handler, group);
792
- this._addKnownHandler('business_callback_query', filter, handler, group);
793
- }
794
- /** @internal */
795
- onNewMessage(filter, handler, group) {
796
- this._addKnownHandler('new_message', filter, handler, group);
797
- }
798
- /** @internal */
799
- onEditMessage(filter, handler, group) {
800
- this._addKnownHandler('edit_message', filter, handler, group);
801
- }
802
- /** @internal */
803
- onMessageGroup(filter, handler, group) {
804
- this._addKnownHandler('message_group', filter, handler, group);
805
- }
806
- /** @internal */
807
- onDeleteMessage(filter, handler, group) {
808
- this._addKnownHandler('delete_message', filter, handler, group);
809
- }
810
- /** @internal */
811
- onChatMemberUpdate(filter, handler, group) {
812
- this._addKnownHandler('chat_member', filter, handler, group);
813
- }
814
- /** @internal */
815
- onInlineQuery(filter, handler, group) {
816
- this._addKnownHandler('inline_query', filter, handler, group);
817
- }
818
- /** @internal */
819
- onChosenInlineResult(filter, handler, group) {
820
- this._addKnownHandler('chosen_inline_result', filter, handler, group);
821
- }
822
- /** @internal */
823
- onCallbackQuery(filter, handler, group) {
824
- this._addKnownHandler('callback_query', filter, handler, group);
825
- }
826
- /** @internal */
827
- onInlineCallbackQuery(filter, handler, group) {
828
- this._addKnownHandler('inline_callback_query', filter, handler, group);
829
- }
830
- /** @internal */
831
- onBusinessCallbackQuery(filter, handler, group) {
832
- this._addKnownHandler('business_callback_query', filter, handler, group);
833
- }
834
- /** @internal */
835
- onPollUpdate(filter, handler, group) {
836
- this._addKnownHandler('poll', filter, handler, group);
837
- }
838
- /** @internal */
839
- onPollVote(filter, handler, group) {
840
- this._addKnownHandler('poll_vote', filter, handler, group);
841
- }
842
- /** @internal */
843
- onUserStatusUpdate(filter, handler, group) {
844
- this._addKnownHandler('user_status', filter, handler, group);
845
- }
846
- /** @internal */
847
- onUserTyping(filter, handler, group) {
848
- this._addKnownHandler('user_typing', filter, handler, group);
849
- }
850
- /** @internal */
851
- onHistoryRead(filter, handler, group) {
852
- this._addKnownHandler('history_read', filter, handler, group);
853
- }
854
- /** @internal */
855
- onBotStopped(filter, handler, group) {
856
- this._addKnownHandler('bot_stopped', filter, handler, group);
857
- }
858
- /** @internal */
859
- onBotChatJoinRequest(filter, handler, group) {
860
- this._addKnownHandler('bot_chat_join_request', filter, handler, group);
861
- }
862
- /** @internal */
863
- onChatJoinRequest(filter, handler, group) {
864
- this._addKnownHandler('chat_join_request', filter, handler, group);
865
- }
866
- /** @internal */
867
- onPreCheckoutQuery(filter, handler, group) {
868
- this._addKnownHandler('pre_checkout_query', filter, handler, group);
869
- }
870
- /** @internal */
871
- onStoryUpdate(filter, handler, group) {
872
- this._addKnownHandler('story', filter, handler, group);
873
- }
874
- /** @internal */
875
- onDeleteStory(filter, handler, group) {
876
- this._addKnownHandler('delete_story', filter, handler, group);
877
- }
878
- /** @internal */
879
- onBotReactionUpdate(filter, handler, group) {
880
- this._addKnownHandler('bot_reaction', filter, handler, group);
881
- }
882
- /** @internal */
883
- onBotReactionCountUpdate(filter, handler, group) {
884
- this._addKnownHandler('bot_reaction_count', filter, handler, group);
885
- }
886
- /** @internal */
887
- onBusinessConnectionUpdate(filter, handler, group) {
888
- this._addKnownHandler('business_connection', filter, handler, group);
889
- }
890
- /** @internal */
891
- onNewBusinessMessage(filter, handler, group) {
892
- this._addKnownHandler('new_business_message', filter, handler, group);
893
- }
894
- /** @internal */
895
- onEditBusinessMessage(filter, handler, group) {
896
- this._addKnownHandler('edit_business_message', filter, handler, group);
897
- }
898
- /** @internal */
899
- onBusinessMessageGroup(filter, handler, group) {
900
- this._addKnownHandler('business_message_group', filter, handler, group);
901
- }
902
- /** @internal */
903
- onDeleteBusinessMessage(filter, handler, group) {
904
- this._addKnownHandler('delete_business_message', filter, handler, group);
905
- }
906
- }
907
- exports.Dispatcher = Dispatcher;
908
- //# sourceMappingURL=dispatcher.js.map