@mtkruto/node 0.0.834 → 0.0.900

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 (145) hide show
  1. package/esm/client/client.d.ts +29 -4
  2. package/esm/client/client.js +528 -71
  3. package/esm/client/client_abstract.d.ts +1 -1
  4. package/esm/connection/connection.d.ts +1 -1
  5. package/esm/constants.d.ts +2 -0
  6. package/esm/constants.js +2 -0
  7. package/esm/deps/deno.land/std@0.190.0/encoding/base64.d.ts +11 -0
  8. package/esm/deps/deno.land/std@0.190.0/encoding/base64.js +140 -0
  9. package/esm/deps/deno.land/x/q@v0.0.1/mod.d.ts +6 -0
  10. package/esm/deps/deno.land/x/q@v0.0.1/mod.js +71 -0
  11. package/esm/deps.d.ts +2 -0
  12. package/esm/deps.js +2 -0
  13. package/esm/mod.d.ts +3 -3
  14. package/esm/mod.js +3 -3
  15. package/esm/storage/storage.d.ts +19 -1
  16. package/esm/storage/storage.js +103 -0
  17. package/esm/storage/storage_local_storage.d.ts +1 -1
  18. package/esm/storage/storage_memory.d.ts +1 -1
  19. package/esm/storage/storage_session_storage.d.ts +1 -1
  20. package/esm/tl/1_tl_object.d.ts +0 -1
  21. package/esm/tl/1_tl_object.js +1 -1
  22. package/esm/tl/4_tl_writer.d.ts +5 -0
  23. package/esm/tl/5_rpc_result.d.ts +9 -0
  24. package/esm/tl/6_message.d.ts +10 -0
  25. package/esm/tl/{5_message.js → 6_message.js} +2 -2
  26. package/esm/tl/{6_message_container.d.ts → 7_message_container.d.ts} +1 -1
  27. package/esm/tl/{6_message_container.js → 7_message_container.js} +2 -2
  28. package/esm/transport/transport.d.ts +1 -1
  29. package/esm/types/0_chat_administrator_rights.d.ts +17 -0
  30. package/esm/types/0_chat_administrator_rights.js +38 -0
  31. package/esm/types/0_chat_photo.d.ts +24 -0
  32. package/esm/types/0_chat_photo.js +28 -0
  33. package/esm/types/0_force_reply.d.ts +8 -0
  34. package/esm/types/0_force_reply.js +17 -0
  35. package/esm/types/0_keyboard_button_poll_type.d.ts +3 -0
  36. package/esm/types/0_login_url.d.ts +6 -0
  37. package/esm/types/0_login_url.js +1 -0
  38. package/esm/types/0_message_entity.d.ts +1 -1
  39. package/esm/types/0_message_entity.js +2 -2
  40. package/esm/types/0_reply_keyboard_remove.d.ts +7 -0
  41. package/esm/types/0_reply_keyboard_remove.js +8 -0
  42. package/esm/types/0_web_app_info.d.ts +4 -0
  43. package/esm/types/0_web_app_info.js +3 -0
  44. package/esm/types/1_chat.d.ts +60 -0
  45. package/esm/types/1_chat.js +70 -0
  46. package/esm/types/1_inline_keyboard_button.d.ts +33 -0
  47. package/esm/types/1_inline_keyboard_button.js +63 -0
  48. package/esm/types/1_keyboard_button.d.ts +43 -0
  49. package/esm/types/1_keyboard_button.js +133 -0
  50. package/esm/types/1_user.d.ts +19 -0
  51. package/esm/types/1_user.js +25 -0
  52. package/esm/types/2_inline_keyboard_markup.d.ts +7 -0
  53. package/esm/types/2_inline_keyboard_markup.js +25 -0
  54. package/esm/types/2_reply_keyboard_markup.d.ts +12 -0
  55. package/esm/types/2_reply_keyboard_markup.js +37 -0
  56. package/esm/types/3_message.d.ts +26 -0
  57. package/esm/types/3_message.js +91 -0
  58. package/esm/utilities/0_control.d.ts +1 -0
  59. package/esm/utilities/0_control.js +3 -0
  60. package/esm/utilities/0_object.d.ts +1 -0
  61. package/esm/utilities/0_object.js +14 -0
  62. package/esm/utilities/0_types.js +1 -0
  63. package/esm/utilities/1_message.d.ts +2 -2
  64. package/esm/utilities/1_message.js +3 -3
  65. package/esm/utilities/1_password.js +1 -1
  66. package/package.json +1 -1
  67. package/script/client/client.d.ts +29 -4
  68. package/script/client/client.js +528 -71
  69. package/script/client/client_abstract.d.ts +1 -1
  70. package/script/connection/connection.d.ts +1 -1
  71. package/script/constants.d.ts +2 -0
  72. package/script/constants.js +3 -1
  73. package/script/deps/deno.land/std@0.190.0/encoding/base64.d.ts +11 -0
  74. package/script/deps/deno.land/std@0.190.0/encoding/base64.js +145 -0
  75. package/script/deps/deno.land/x/q@v0.0.1/mod.d.ts +6 -0
  76. package/script/deps/deno.land/x/q@v0.0.1/mod.js +75 -0
  77. package/script/deps.d.ts +2 -0
  78. package/script/deps.js +6 -1
  79. package/script/mod.d.ts +3 -3
  80. package/script/mod.js +3 -3
  81. package/script/storage/storage.d.ts +19 -1
  82. package/script/storage/storage.js +126 -0
  83. package/script/storage/storage_local_storage.d.ts +1 -1
  84. package/script/storage/storage_memory.d.ts +1 -1
  85. package/script/storage/storage_session_storage.d.ts +1 -1
  86. package/script/tl/1_tl_object.d.ts +0 -1
  87. package/script/tl/1_tl_object.js +1 -1
  88. package/script/tl/4_tl_writer.d.ts +5 -0
  89. package/script/tl/5_rpc_result.d.ts +9 -0
  90. package/script/tl/6_message.d.ts +10 -0
  91. package/script/tl/{5_message.js → 6_message.js} +6 -6
  92. package/script/tl/{6_message_container.d.ts → 7_message_container.d.ts} +1 -1
  93. package/script/tl/{6_message_container.js → 7_message_container.js} +4 -4
  94. package/script/transport/transport.d.ts +1 -1
  95. package/script/types/0_chat_administrator_rights.d.ts +17 -0
  96. package/script/types/0_chat_administrator_rights.js +66 -0
  97. package/script/types/0_chat_photo.d.ts +24 -0
  98. package/script/types/0_chat_photo.js +55 -0
  99. package/script/types/0_force_reply.d.ts +8 -0
  100. package/script/types/0_force_reply.js +45 -0
  101. package/script/types/0_keyboard_button_poll_type.d.ts +3 -0
  102. package/script/types/0_login_url.d.ts +6 -0
  103. package/script/types/0_login_url.js +2 -0
  104. package/script/types/0_message_entity.d.ts +1 -1
  105. package/script/types/0_message_entity.js +2 -2
  106. package/script/types/0_reply_keyboard_remove.d.ts +7 -0
  107. package/script/types/0_reply_keyboard_remove.js +36 -0
  108. package/script/types/0_web_app_info.d.ts +4 -0
  109. package/script/types/0_web_app_info.js +7 -0
  110. package/script/types/1_chat.d.ts +60 -0
  111. package/script/types/1_chat.js +97 -0
  112. package/script/types/1_inline_keyboard_button.d.ts +33 -0
  113. package/script/types/1_inline_keyboard_button.js +91 -0
  114. package/script/types/1_keyboard_button.d.ts +43 -0
  115. package/script/types/1_keyboard_button.js +161 -0
  116. package/script/types/1_user.d.ts +19 -0
  117. package/script/types/1_user.js +52 -0
  118. package/script/types/2_inline_keyboard_markup.d.ts +7 -0
  119. package/script/types/2_inline_keyboard_markup.js +53 -0
  120. package/script/types/2_reply_keyboard_markup.d.ts +12 -0
  121. package/script/types/2_reply_keyboard_markup.js +65 -0
  122. package/script/types/3_message.d.ts +26 -0
  123. package/script/types/3_message.js +118 -0
  124. package/script/utilities/0_control.d.ts +1 -0
  125. package/script/utilities/0_control.js +7 -0
  126. package/script/utilities/0_object.d.ts +1 -0
  127. package/script/utilities/0_object.js +18 -0
  128. package/script/utilities/0_types.js +2 -0
  129. package/script/utilities/1_message.d.ts +2 -2
  130. package/script/utilities/1_message.js +9 -9
  131. package/script/utilities/1_password.js +1 -1
  132. package/esm/tl/3_tl_writer.d.ts +0 -5
  133. package/esm/tl/4_rpc_result.d.ts +0 -8
  134. package/esm/tl/5_message.d.ts +0 -11
  135. package/script/tl/3_tl_writer.d.ts +0 -5
  136. package/script/tl/4_rpc_result.d.ts +0 -8
  137. package/script/tl/5_message.d.ts +0 -11
  138. /package/esm/tl/{3_tl_writer.js → 4_tl_writer.js} +0 -0
  139. /package/esm/tl/{4_rpc_result.js → 5_rpc_result.js} +0 -0
  140. /package/esm/{types.js → types/0_keyboard_button_poll_type.js} +0 -0
  141. /package/esm/{types.d.ts → utilities/0_types.d.ts} +0 -0
  142. /package/script/tl/{3_tl_writer.js → 4_tl_writer.js} +0 -0
  143. /package/script/tl/{4_rpc_result.js → 5_rpc_result.js} +0 -0
  144. /package/script/{types.js → types/0_keyboard_button_poll_type.js} +0 -0
  145. /package/script/{types.d.ts → utilities/0_types.d.ts} +0 -0
@@ -23,10 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.Client = exports.ParseMode = exports.restartAuth = void 0;
26
+ exports.Client = exports.ParseMode = exports.restartAuth = exports.getEntity = void 0;
27
27
  const deps_js_1 = require("../deps.js");
28
28
  const constants_js_1 = require("../constants.js");
29
29
  const _0_bigint_js_1 = require("../utilities/0_bigint.js");
30
+ const _0_control_js_1 = require("../utilities/0_control.js");
31
+ const _0_hash_js_1 = require("../utilities/0_hash.js");
30
32
  const _0_html_js_1 = require("../utilities/0_html.js");
31
33
  const _1_message_js_1 = require("../utilities/1_message.js");
32
34
  const _1_password_js_1 = require("../utilities/1_password.js");
@@ -34,15 +36,23 @@ const _1_tl_object_js_1 = require("../tl/1_tl_object.js");
34
36
  const types = __importStar(require("../tl/2_types.js"));
35
37
  const functions = __importStar(require("../tl/3_functions.js"));
36
38
  const _3_tl_reader_js_1 = require("../tl/3_tl_reader.js");
37
- const _4_rpc_result_js_1 = require("../tl/4_rpc_result.js");
38
- const _5_message_js_1 = require("../tl/5_message.js");
39
- const _6_message_container_js_1 = require("../tl/6_message_container.js");
39
+ const _5_rpc_result_js_1 = require("../tl/5_rpc_result.js");
40
+ const _6_message_js_1 = require("../tl/6_message.js"); // MTProto API message
41
+ const _7_message_container_js_1 = require("../tl/7_message_container.js");
40
42
  const client_abstract_js_1 = require("./client_abstract.js");
41
43
  const client_plain_js_1 = require("./client_plain.js");
42
44
  const storage_memory_js_1 = require("../storage/storage_memory.js");
43
- const _0_hash_js_1 = require("../utilities/0_hash.js");
44
45
  const _0_message_entity_js_1 = require("../types/0_message_entity.js");
46
+ const _0_reply_keyboard_remove_js_1 = require("../types/0_reply_keyboard_remove.js");
47
+ const _0_force_reply_js_1 = require("../types/0_force_reply.js");
48
+ const _2_reply_keyboard_markup_js_1 = require("../types/2_reply_keyboard_markup.js");
49
+ const _2_inline_keyboard_markup_js_1 = require("../types/2_inline_keyboard_markup.js");
50
+ const _3_message_js_1 = require("../types/3_message.js"); // high-level wrapper for Telegram API's message
45
51
  const d = (0, deps_js_1.debug)("client");
52
+ const dRecoverUpdateGap = (0, deps_js_1.debug)("client_recoverUpdateGap");
53
+ const dRecoverChannelUpdateGap = (0, deps_js_1.debug)("client_recoverChannelUpdateGap");
54
+ const UPDATE_GAP = Symbol();
55
+ exports.getEntity = Symbol();
46
56
  exports.restartAuth = Symbol();
47
57
  var ParseMode;
48
58
  (function (ParseMode) {
@@ -108,7 +118,13 @@ class Client extends client_abstract_js_1.ClientAbstract {
108
118
  writable: true,
109
119
  value: new Set()
110
120
  });
111
- Object.defineProperty(this, "updatesHandler", {
121
+ Object.defineProperty(this, "updateState", {
122
+ enumerable: true,
123
+ configurable: true,
124
+ writable: true,
125
+ value: void 0
126
+ });
127
+ Object.defineProperty(this, "updateHandler", {
112
128
  enumerable: true,
113
129
  configurable: true,
114
130
  writable: true,
@@ -162,6 +178,79 @@ class Client extends client_abstract_js_1.ClientAbstract {
162
178
  writable: true,
163
179
  value: false
164
180
  });
181
+ Object.defineProperty(this, "messageProcessQueue", {
182
+ enumerable: true,
183
+ configurable: true,
184
+ writable: true,
185
+ value: (0, deps_js_1.queue)(async (message) => {
186
+ let body = message.body;
187
+ if (body instanceof types.GZIPPacked) {
188
+ body = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(body.packedData)).readObject();
189
+ }
190
+ d("received %s", body.constructor.name);
191
+ if (body instanceof types.Updates || body instanceof types.TypeUpdate) {
192
+ await this.processUpdates(body);
193
+ }
194
+ else if (message.body instanceof _5_rpc_result_js_1.RPCResult) {
195
+ let result = message.body.result;
196
+ if (result instanceof types.GZIPPacked) {
197
+ result = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(result.packedData)).readObject();
198
+ }
199
+ if (result instanceof types.RPCError) {
200
+ d("RPCResult: %d %s", result.errorCode, result.errorMessage);
201
+ }
202
+ else {
203
+ d("RPCResult: %s", result.constructor.name);
204
+ }
205
+ if (result instanceof types.Updates || result instanceof types.TypeUpdate) {
206
+ await this.processUpdates(result);
207
+ }
208
+ else {
209
+ await this.processResult(result);
210
+ }
211
+ const promise = this.promises.get(message.body.messageId);
212
+ if (promise) {
213
+ if (result instanceof types.RPCError) {
214
+ promise.reject(result);
215
+ }
216
+ else {
217
+ promise.resolve(result);
218
+ }
219
+ this.promises.delete(message.body.messageId);
220
+ }
221
+ }
222
+ else if (message.body instanceof types.Pong) {
223
+ const promise = this.promises.get(message.body.msgId);
224
+ if (promise) {
225
+ promise.resolve(message.body);
226
+ this.promises.delete(message.body.msgId);
227
+ }
228
+ }
229
+ else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
230
+ if (message.body instanceof types.BadServerSalt) {
231
+ this.state.salt = message.body.newServerSalt;
232
+ }
233
+ const promise = this.promises.get(message.body.badMsgId);
234
+ if (promise) {
235
+ promise.resolve(message.body);
236
+ this.promises.delete(message.body.badMsgId);
237
+ }
238
+ }
239
+ this.toAcknowledge.add(message.id);
240
+ }, 2)
241
+ });
242
+ Object.defineProperty(this, "updateApplicationMutex", {
243
+ enumerable: true,
244
+ configurable: true,
245
+ writable: true,
246
+ value: new deps_js_1.Mutex()
247
+ });
248
+ Object.defineProperty(this, "updateGapRecoveryMutex", {
249
+ enumerable: true,
250
+ configurable: true,
251
+ writable: true,
252
+ value: new deps_js_1.Mutex()
253
+ });
165
254
  this.parseMode = params?.parseMode ?? ParseMode.None;
166
255
  this.appVersion = params?.appVersion ?? constants_js_1.DEFAULT_APP_VERSION;
167
256
  this.deviceModel = params?.deviceModel ?? constants_js_1.DEFAULT_DEVICE_MODEL;
@@ -231,6 +320,11 @@ class Client extends client_abstract_js_1.ClientAbstract {
231
320
  this.receiveLoop();
232
321
  this.pingLoop();
233
322
  }
323
+ async fetchState(source) {
324
+ const state = await this.invoke(new functions.UpdatesGetState());
325
+ this.updateState = state;
326
+ d("state fetched [%s]", source);
327
+ }
234
328
  /**
235
329
  * Calls [initConnection](1) and authorizes the client with one of the following:
236
330
  *
@@ -280,6 +374,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
280
374
  const password = typeof params.password === "string" ? params.password : await params.password();
281
375
  const input = await (0, _1_password_js_1.checkPassword)(password, ap);
282
376
  await this.invoke(new functions.AuthCheckPassword({ password: input }));
377
+ await this.storage.setAccountType("user");
283
378
  d("authorized as user");
284
379
  break;
285
380
  }
@@ -302,7 +397,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
302
397
  }
303
398
  };
304
399
  try {
305
- await this.invoke(new functions.UpdatesGetState());
400
+ await this.fetchState("authorize");
306
401
  d("already authorized");
307
402
  return;
308
403
  }
@@ -343,6 +438,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
343
438
  }
344
439
  else {
345
440
  signedIn = true;
441
+ await this.storage.setAccountType("user");
346
442
  d("authorized as user");
347
443
  break;
348
444
  }
@@ -377,6 +473,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
377
473
  }
378
474
  else {
379
475
  await this.invoke(new functions.AuthImportBotAuthorization({ apiId: this.apiId, apiHash: this.apiHash, botAuthToken: params, flags: 0 }));
476
+ await this.storage.setAccountType("bot");
380
477
  d("authorized as bot");
381
478
  }
382
479
  }
@@ -404,6 +501,14 @@ class Client extends client_abstract_js_1.ClientAbstract {
404
501
  throw err;
405
502
  }
406
503
  }
504
+ finally {
505
+ try {
506
+ await this.fetchState("authorize");
507
+ }
508
+ catch (_err) {
509
+ //
510
+ }
511
+ }
407
512
  }
408
513
  async receiveLoop() {
409
514
  if (!this.auth) {
@@ -434,60 +539,9 @@ class Client extends client_abstract_js_1.ClientAbstract {
434
539
  d("failed to decrypt message: %o", err);
435
540
  continue;
436
541
  }
437
- const messages = decrypted instanceof _6_message_container_js_1.MessageContainer ? decrypted.messages : [decrypted];
542
+ const messages = decrypted instanceof _7_message_container_js_1.MessageContainer ? decrypted.messages : [decrypted];
438
543
  for (const message of messages) {
439
- let body = message.body;
440
- if (body instanceof types.GZIPPacked) {
441
- body = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(body.packedData)).readObject();
442
- }
443
- d("received %s", body.constructor.name);
444
- if (body instanceof types.Updates) {
445
- this.processUpdates(body);
446
- }
447
- else if (message.body instanceof _4_rpc_result_js_1.RPCResult) {
448
- let result = message.body.result;
449
- if (result instanceof types.GZIPPacked) {
450
- result = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(result.packedData)).readObject();
451
- }
452
- if (result instanceof types.RPCError) {
453
- d("RPCResult: %d %s", result.errorCode, result.errorMessage);
454
- }
455
- else {
456
- d("RPCResult: %s", result.constructor.name);
457
- }
458
- const promise = this.promises.get(message.body.messageId);
459
- if (promise) {
460
- if (result instanceof types.RPCError) {
461
- promise.reject(result);
462
- }
463
- else {
464
- if (result instanceof types.Updates) {
465
- await this.processChats(result.chats);
466
- await this.processUsers(result.users);
467
- }
468
- promise.resolve(result);
469
- }
470
- this.promises.delete(message.body.messageId);
471
- }
472
- }
473
- else if (message.body instanceof types.Pong) {
474
- const promise = this.promises.get(message.body.msgId);
475
- if (promise) {
476
- promise.resolve(message.body);
477
- this.promises.delete(message.body.msgId);
478
- }
479
- }
480
- else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
481
- if (message.body instanceof types.BadServerSalt) {
482
- this.state.salt = message.body.newServerSalt;
483
- }
484
- const promise = this.promises.get(message.body.badMsgId);
485
- if (promise) {
486
- promise.resolve(message.body);
487
- this.promises.delete(message.body.badMsgId);
488
- }
489
- }
490
- this.toAcknowledge.add(message.id);
544
+ this.messageProcessQueue.push(message);
491
545
  }
492
546
  }
493
547
  }
@@ -511,7 +565,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
511
565
  seqNo++;
512
566
  this.state.seqNo++;
513
567
  }
514
- const message = new _5_message_js_1.Message((0, _1_message_js_1.getMessageId)(), seqNo, function_);
568
+ const message = new _6_message_js_1.Message((0, _1_message_js_1.getMessageId)(), seqNo, function_);
515
569
  await this.transport.send(await (0, _1_message_js_1.encryptMessage)(message, this.auth.key, this.auth.id, this.state.salt, this.sessionId));
516
570
  d("invoked %s", function_.constructor.name);
517
571
  if (noWait) {
@@ -536,6 +590,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
536
590
  async processChats(chats) {
537
591
  for (const chat of chats) {
538
592
  if (chat instanceof types.Channel && chat.accessHash) {
593
+ await this.storage.setEntity(chat);
539
594
  await this.storage.setChannelAccessHash(chat.id, chat.accessHash);
540
595
  if (chat.username) {
541
596
  await this.storage.updateUsernames("channel", chat.id, [chat.username]);
@@ -544,11 +599,15 @@ class Client extends client_abstract_js_1.ClientAbstract {
544
599
  await this.storage.updateUsernames("channel", chat.id, chat.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
545
600
  }
546
601
  }
602
+ else if (chat instanceof types.Chat) {
603
+ await this.storage.setEntity(chat);
604
+ }
547
605
  }
548
606
  }
549
607
  async processUsers(users) {
550
608
  for (const user of users) {
551
609
  if (user instanceof types.User && user.accessHash) {
610
+ await this.storage.setEntity(user);
552
611
  await this.storage.setUserAccessHash(user.id, user.accessHash);
553
612
  if (user.username) {
554
613
  await this.storage.updateUsernames("user", user.id, [user.username]);
@@ -559,19 +618,310 @@ class Client extends client_abstract_js_1.ClientAbstract {
559
618
  }
560
619
  }
561
620
  }
621
+ async applyUpdateNoGap(update, usePts = true) {
622
+ const release = await this.updateApplicationMutex.acquire();
623
+ try {
624
+ if ((update instanceof types.UpdateNewMessage) ||
625
+ (update instanceof types.UpdateDeleteMessages) ||
626
+ (update instanceof types.UpdateReadHistoryInbox) ||
627
+ (update instanceof types.UpdateReadHistoryOutbox) ||
628
+ (update instanceof types.UpdateWebPage) ||
629
+ (update instanceof types.UpdateReadMessagesContents) ||
630
+ (update instanceof types.UpdateEditMessage) ||
631
+ (update instanceof types.UpdateFolderPeers) ||
632
+ (update instanceof types.UpdatePinnedMessages) ||
633
+ (update instanceof types.UpdatePinnedChannelMessages) ||
634
+ (update instanceof types.UpdateShortMessage) ||
635
+ (update instanceof types.UpdateShortChatMessage) ||
636
+ (update instanceof types.UpdateShortSentMessage)) {
637
+ const localState = await this.getLocalState();
638
+ if (localState.pts + update.ptsCount > update.pts) {
639
+ // the update is already applied
640
+ return;
641
+ }
642
+ else if (localState.pts + update.ptsCount < update.pts) {
643
+ // there is an update gap that needs to be filled
644
+ throw UPDATE_GAP;
645
+ }
646
+ localState.pts = update.pts;
647
+ d("applied update with pts %d", update.pts);
648
+ await this.storage.setState(localState);
649
+ }
650
+ else if (usePts &&
651
+ ((update instanceof types.UpdateNewChannelMessage) ||
652
+ (update instanceof types.UpdateDeleteChannelMessages) ||
653
+ (update instanceof types.UpdateEditChannelMessage) ||
654
+ (update instanceof types.UpdateChannelWebPage))) {
655
+ const channelId = update instanceof types.UpdateNewChannelMessage || update instanceof types.UpdateEditChannelMessage ? update.message[_1_tl_object_js_1.as](types.Message).peerId[_1_tl_object_js_1.as](types.PeerChannel).channelId : update.channelId;
656
+ let localPts = await this.storage.getChannelPts(channelId);
657
+ if (!localPts) {
658
+ localPts = update.pts - update.ptsCount;
659
+ }
660
+ if (localPts + update.ptsCount > update.pts) {
661
+ // already applied
662
+ return;
663
+ }
664
+ else if (localPts + update.ptsCount < update.pts) {
665
+ // should call channelGetDifference
666
+ throw UPDATE_GAP;
667
+ }
668
+ d("applied update with pts %d", update.pts);
669
+ await this.storage.setChannelPts(channelId, update.pts);
670
+ }
671
+ // apply update (call listeners)
672
+ this.updateHandler?.(this, update);
673
+ }
674
+ finally {
675
+ release();
676
+ }
677
+ }
678
+ async applyUpdate(update) {
679
+ if (update instanceof types.TypeUpdates &&
680
+ !(update instanceof types.UpdateShortMessage) &&
681
+ !(update instanceof types.UpdateShortChatMessage) &&
682
+ !(update instanceof types.UpdateShortSentMessage)) {
683
+ // other constructors inheriting Updates are not applicable
684
+ (0, _0_control_js_1.UNREACHABLE)();
685
+ }
686
+ if (update instanceof types.TypeUpdate && update instanceof types.UpdateChannelTooLong) {
687
+ // updateChannelTooLong is not applicable
688
+ (0, _0_control_js_1.UNREACHABLE)();
689
+ }
690
+ // can't apply updates when filling gap
691
+ const release = await this.updateGapRecoveryMutex.acquire();
692
+ try {
693
+ await this.applyUpdateNoGap(update);
694
+ release();
695
+ }
696
+ catch (err) {
697
+ release();
698
+ if (err == UPDATE_GAP) {
699
+ if ((update instanceof types.UpdateNewChannelMessage) ||
700
+ (update instanceof types.UpdateDeleteChannelMessages) ||
701
+ (update instanceof types.UpdateEditChannelMessage) ||
702
+ (update instanceof types.UpdateChannelWebPage)) {
703
+ const channelId = update instanceof types.UpdateNewChannelMessage || update instanceof types.UpdateEditChannelMessage ? update.message[_1_tl_object_js_1.as](types.Message).peerId[_1_tl_object_js_1.as](types.PeerChannel).channelId : update.channelId;
704
+ await this.recoverChannelUpdateGap(channelId, "applyUpdate");
705
+ }
706
+ else if ((update instanceof types.UpdateNewMessage) ||
707
+ (update instanceof types.UpdateDeleteMessages) ||
708
+ (update instanceof types.UpdateReadHistoryInbox) ||
709
+ (update instanceof types.UpdateReadHistoryOutbox) ||
710
+ (update instanceof types.UpdateWebPage) ||
711
+ (update instanceof types.UpdateReadMessagesContents) ||
712
+ (update instanceof types.UpdateEditMessage) ||
713
+ (update instanceof types.UpdateFolderPeers) ||
714
+ (update instanceof types.UpdatePinnedMessages) ||
715
+ (update instanceof types.UpdatePinnedChannelMessages) ||
716
+ (update instanceof types.UpdateShortMessage) ||
717
+ (update instanceof types.UpdateShortChatMessage) ||
718
+ (update instanceof types.UpdateShortSentMessage)) {
719
+ await this.recoverUpdateGap("applyUpdate");
720
+ }
721
+ else {
722
+ // can't detect update gap from other types of updates
723
+ (0, _0_control_js_1.UNREACHABLE)();
724
+ }
725
+ // just for integrity
726
+ const release = await this.updateGapRecoveryMutex.acquire();
727
+ try {
728
+ await this.applyUpdateNoGap(update);
729
+ }
730
+ catch (err) {
731
+ if (err == UPDATE_GAP) {
732
+ // the gap must have been filled until now
733
+ (0, _0_control_js_1.UNREACHABLE)();
734
+ }
735
+ else {
736
+ throw err;
737
+ }
738
+ }
739
+ finally {
740
+ release();
741
+ }
742
+ }
743
+ else {
744
+ throw err;
745
+ }
746
+ }
747
+ }
562
748
  async processUpdates(updates) {
563
749
  try {
564
- await this.processChats(updates.chats);
565
- await this.processUsers(updates.users);
566
- for (const update of updates.updates) {
567
- if (update instanceof types.UpdateUserName) {
568
- await this.storage.updateUsernames("user", update.userId, update.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
750
+ if (updates instanceof types.TypeUpdates) {
751
+ if (updates instanceof types.Updates) {
752
+ await this.processChats(updates.chats);
753
+ await this.processUsers(updates.users);
754
+ await this.setUpdateStateDate(updates.date);
755
+ for (const update of updates.updates) {
756
+ await this.processUpdates(update);
757
+ }
758
+ }
759
+ else if (updates instanceof types.UpdateShortMessage ||
760
+ updates instanceof types.UpdateShortChatMessage ||
761
+ updates instanceof types.UpdateShortSentMessage) {
762
+ await this.setUpdateStateDate(updates.date);
763
+ await this.applyUpdate(updates);
764
+ }
765
+ else if (updates instanceof types.UpdatesTooLong) {
766
+ await this.recoverUpdateGap("updatesTooLong");
767
+ }
768
+ else if (updates instanceof types.UpdatesCombined) {
769
+ await this.setUpdateStateDate(updates.date);
770
+ await this.processChats(updates.chats);
771
+ await this.processUsers(updates.users);
772
+ for (const update of updates.updates) {
773
+ await this.processUpdates(update);
774
+ }
569
775
  }
570
776
  }
571
- await this.updatesHandler?.(this, updates);
777
+ else if (updates instanceof types.TypeUpdate && updates instanceof types.UpdateChannelTooLong) {
778
+ if (updates.pts != undefined) {
779
+ await this.storage.setChannelPts(updates.channelId, updates.pts);
780
+ }
781
+ await this.recoverChannelUpdateGap(updates.channelId, "updateChannelTooLong");
782
+ }
783
+ else {
784
+ if (updates instanceof types.UpdateUserName) {
785
+ await this.storage.updateUsernames("user", updates.userId, updates.usernames.map((v) => v[_1_tl_object_js_1.as](types.Username)).map((v) => v.username));
786
+ }
787
+ else if (updates instanceof types.UpdatePtsChanged) {
788
+ await this.fetchState("updatePtsChanged");
789
+ if (this.updateState) {
790
+ await this.storage.setState(this.updateState);
791
+ }
792
+ else {
793
+ (0, _0_control_js_1.UNREACHABLE)();
794
+ }
795
+ }
796
+ await this.applyUpdate(updates);
797
+ }
572
798
  }
573
799
  catch (err) {
574
- console.error("Error processing updates:", err);
800
+ d("error processing updates: %O", err);
801
+ }
802
+ }
803
+ async setUpdateStateDate(date) {
804
+ const release = await this.updateApplicationMutex.acquire();
805
+ try {
806
+ const localState = await this.getLocalState();
807
+ localState.date = date;
808
+ await this.storage.setState(localState);
809
+ }
810
+ finally {
811
+ release();
812
+ }
813
+ }
814
+ async getLocalState() {
815
+ let localState = await this.storage.getState();
816
+ if (!localState) {
817
+ if (this.updateState) {
818
+ localState = this.updateState;
819
+ await this.storage.setState(localState);
820
+ }
821
+ else {
822
+ (0, _0_control_js_1.UNREACHABLE)();
823
+ }
824
+ }
825
+ return localState;
826
+ }
827
+ async recoverUpdateGap(source) {
828
+ dRecoverUpdateGap("recovering from update gap [%s]", source);
829
+ const release = await this.updateGapRecoveryMutex.acquire();
830
+ try {
831
+ let state = await this.getLocalState();
832
+ while (true) {
833
+ const difference = await this.invoke(new functions.UpdatesGetDifference({ pts: state.pts, date: state.date, qts: state.qts }));
834
+ if (difference instanceof types.UpdatesDifference || difference instanceof types.UpdatesDifferenceSlice) {
835
+ await this.processChats(difference.chats);
836
+ await this.processUsers(difference.users);
837
+ for (const message of difference.newMessages) {
838
+ await this.applyUpdateNoGap(new types.UpdateNewMessage({ message, pts: 0, ptsCount: 0 }));
839
+ }
840
+ for (const update of difference.otherUpdates) {
841
+ await this.applyUpdateNoGap(update);
842
+ }
843
+ if (difference instanceof types.UpdatesDifference) {
844
+ dRecoverUpdateGap("recovered from update gap");
845
+ break;
846
+ }
847
+ else if (difference instanceof types.UpdatesDifferenceSlice) {
848
+ state = difference.intermediateState[_1_tl_object_js_1.as](types.UpdatesState);
849
+ }
850
+ else {
851
+ (0, _0_control_js_1.UNREACHABLE)();
852
+ }
853
+ }
854
+ else if (difference instanceof types.UpdatesDifferenceTooLong) {
855
+ // stored messages should be invalidated in case we store messages in the future
856
+ state.pts = difference.pts;
857
+ dRecoverUpdateGap("received differenceTooLong");
858
+ }
859
+ else if (difference instanceof types.UpdatesDifferenceEmpty) {
860
+ await this.setUpdateStateDate(difference.date);
861
+ dRecoverUpdateGap("there was no update gap");
862
+ break;
863
+ }
864
+ else {
865
+ (0, _0_control_js_1.UNREACHABLE)();
866
+ }
867
+ }
868
+ }
869
+ finally {
870
+ release();
871
+ }
872
+ }
873
+ async recoverChannelUpdateGap(channelId, source) {
874
+ dRecoverChannelUpdateGap("recovering channel update gap [%o, %s]", channelId, source);
875
+ const release = await this.updateGapRecoveryMutex.acquire();
876
+ try {
877
+ const pts_ = await this.storage.getChannelPts(channelId);
878
+ let pts = pts_ == null ? 1 : pts_;
879
+ while (true) {
880
+ const { accessHash } = await this.getInputPeer(constants_js_1.ZERO_CHANNEL_ID + -Number(channelId)).then((v) => v[_1_tl_object_js_1.as](types.InputPeerChannel));
881
+ const difference = await this.invoke(new functions.UpdatesGetChannelDifference({
882
+ pts,
883
+ channel: new types.InputChannel({ channelId, accessHash: accessHash }),
884
+ filter: new types.ChannelMessagesFilterEmpty(),
885
+ limit: await this.storage.getAccountType() == "user" ? constants_js_1.CHANNEL_DIFFERENCE_LIMIT_USER : constants_js_1.CHANNEL_DIFFERENCE_LIMIT_BOT,
886
+ }));
887
+ if (difference instanceof types.UpdatesChannelDifference) {
888
+ await this.processChats(difference.chats);
889
+ await this.processUsers(difference.users);
890
+ for (const message of difference.newMessages) {
891
+ await this.applyUpdateNoGap(new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), false);
892
+ }
893
+ for (const update of difference.otherUpdates) {
894
+ await this.applyUpdateNoGap(update, false);
895
+ }
896
+ await this.storage.setChannelPts(channelId, difference.pts);
897
+ dRecoverChannelUpdateGap("recovered from update gap");
898
+ break;
899
+ }
900
+ else if (difference instanceof types.UpdatesChannelDifferenceTooLong) {
901
+ // invalidate messages
902
+ dRecoverChannelUpdateGap("received channelDifferenceTooLong");
903
+ await this.processChats(difference.chats);
904
+ await this.processUsers(difference.users);
905
+ for (const message of difference.messages) {
906
+ await this.applyUpdateNoGap(new types.UpdateNewChannelMessage({ message, pts: 0, ptsCount: 0 }), false);
907
+ }
908
+ const pts_ = difference.dialog[_1_tl_object_js_1.as](types.Dialog).pts;
909
+ if (pts_ != undefined) {
910
+ pts = pts_;
911
+ }
912
+ else {
913
+ (0, _0_control_js_1.UNREACHABLE)();
914
+ }
915
+ dRecoverChannelUpdateGap("processed channelDifferenceTooLong");
916
+ }
917
+ else if (difference instanceof types.UpdatesChannelDifferenceEmpty) {
918
+ dRecoverChannelUpdateGap("there was no update gap");
919
+ break;
920
+ }
921
+ }
922
+ }
923
+ finally {
924
+ release();
575
925
  }
576
926
  }
577
927
  async getInputPeer(id) {
@@ -607,7 +957,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
607
957
  channelId = resolved.peer.channelId;
608
958
  }
609
959
  else {
610
- throw new Error("Unreachable");
960
+ (0, _0_control_js_1.UNREACHABLE)();
611
961
  }
612
962
  }
613
963
  if (userId) {
@@ -619,7 +969,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
619
969
  return new types.InputPeerChannel({ channelId, accessHash: accessHash ?? 0n });
620
970
  }
621
971
  else {
622
- throw new Error("Unreachable");
972
+ (0, _0_control_js_1.UNREACHABLE)();
623
973
  }
624
974
  }
625
975
  }
@@ -640,6 +990,50 @@ class Client extends client_abstract_js_1.ClientAbstract {
640
990
  throw new Error("ID format unknown or not implemented");
641
991
  }
642
992
  }
993
+ [exports.getEntity](peer) {
994
+ const type = peer instanceof types.PeerUser ? "user" : peer instanceof types.PeerChat ? "chat" : peer instanceof types.PeerChannel ? "channel" : (0, _0_control_js_1.UNREACHABLE)();
995
+ const id = peer instanceof types.PeerUser ? peer.userId : peer instanceof types.PeerChat ? peer.chatId : peer instanceof types.PeerChannel ? peer.channelId : (0, _0_control_js_1.UNREACHABLE)();
996
+ return this.storage.getEntity(type, id);
997
+ }
998
+ async processResult(result) {
999
+ if (result instanceof types.MessagesDialogs ||
1000
+ result instanceof types.MessagesDialogsSlice ||
1001
+ result instanceof types.MessagesMessages ||
1002
+ result instanceof types.MessagesMessagesSlice ||
1003
+ result instanceof types.MessagesChannelMessages ||
1004
+ result instanceof types.MessagesChatFull ||
1005
+ result instanceof types.ContactsFound ||
1006
+ result instanceof types.AccountPrivacyRules ||
1007
+ result instanceof types.ContactsResolvedPeer ||
1008
+ result instanceof types.ChannelsChannelParticipants ||
1009
+ result instanceof types.ChannelsChannelParticipant ||
1010
+ result instanceof types.MessagesPeerDialogs ||
1011
+ result instanceof types.ContactsTopPeers ||
1012
+ result instanceof types.ChannelsAdminLogResults ||
1013
+ result instanceof types.HelpRecentMeURLs ||
1014
+ result instanceof types.MessagesInactiveChats ||
1015
+ result instanceof types.HelpPromoData ||
1016
+ result instanceof types.MessagesMessageViews ||
1017
+ result instanceof types.MessagesDiscussionMessage ||
1018
+ result instanceof types.PhoneGroupCall ||
1019
+ result instanceof types.PhoneGroupParticipants ||
1020
+ result instanceof types.PhoneJoinAsPeers ||
1021
+ result instanceof types.MessagesSponsoredMessages ||
1022
+ result instanceof types.MessagesSearchResultsCalendar ||
1023
+ result instanceof types.ChannelsSendAsPeers ||
1024
+ result instanceof types.UsersUserFull ||
1025
+ result instanceof types.MessagesPeerSettings ||
1026
+ result instanceof types.MessagesMessageReactionsList ||
1027
+ result instanceof types.MessagesForumTopics ||
1028
+ result instanceof types.AccountAutoSaveSettings ||
1029
+ result instanceof types.ChatlistsExportedInvites ||
1030
+ result instanceof types.ChatlistsChatlistInviteAlready ||
1031
+ result instanceof types.ChatlistsChatlistInvite ||
1032
+ result instanceof types.ChatlistsChatlistUpdates) {
1033
+ await this.processChats(result.chats);
1034
+ await this.processUsers(result.users);
1035
+ }
1036
+ }
643
1037
  async sendMessage(chatId, text, params) {
644
1038
  const entities_ = params?.entities ?? [];
645
1039
  const parseMode = params?.parseMode ?? this.parseMode;
@@ -654,6 +1048,27 @@ class Client extends client_abstract_js_1.ClientAbstract {
654
1048
  }
655
1049
  }
656
1050
  }
1051
+ let replyMarkup = undefined;
1052
+ if (params?.replyMarkup) {
1053
+ if ("inlineKeyboard" in params.replyMarkup) {
1054
+ replyMarkup = await (0, _2_inline_keyboard_markup_js_1.inlineKeyboardMarkupToTlObject)(params.replyMarkup, async (v) => {
1055
+ const inputPeer = await this.getInputPeer(v).then((v) => v[_1_tl_object_js_1.as](types.InputPeerUser));
1056
+ return new types.InputUser({ userId: inputPeer.userId, accessHash: inputPeer.accessHash });
1057
+ });
1058
+ }
1059
+ else if ("keyboard" in params.replyMarkup) {
1060
+ replyMarkup = (0, _2_reply_keyboard_markup_js_1.replyKeyboardMarkupToTlObject)(params.replyMarkup);
1061
+ }
1062
+ else if ("removeKeyboard" in params.replyMarkup) {
1063
+ replyMarkup = (0, _0_reply_keyboard_remove_js_1.replyKeyboardRemoveToTlObject)(params.replyMarkup);
1064
+ }
1065
+ else if ("forceReply" in params.replyMarkup) {
1066
+ replyMarkup = (0, _0_force_reply_js_1.forceReplyToTlObject)(params.replyMarkup);
1067
+ }
1068
+ else {
1069
+ throw new Error("The replyMarkup parameter has an unexpected type");
1070
+ }
1071
+ }
657
1072
  const peer = await this.getInputPeer(chatId);
658
1073
  const randomId = (0, _0_bigint_js_1.getRandomId)();
659
1074
  const message = text;
@@ -664,7 +1079,7 @@ class Client extends client_abstract_js_1.ClientAbstract {
664
1079
  const topMsgId = params?.messageThreadId;
665
1080
  const sendAs = params?.sendAs ? await this.getInputPeer(params.sendAs) : undefined;
666
1081
  const entities = entities_?.length > 0 ? entities_.map((v) => (0, _0_message_entity_js_1.messageEntityToTlObject)(v)) : undefined;
667
- return await this.invoke(new functions.MessagesSendMessage({
1082
+ const result = await this.invoke(new functions.MessagesSendMessage({
668
1083
  peer,
669
1084
  randomId,
670
1085
  message,
@@ -675,7 +1090,49 @@ class Client extends client_abstract_js_1.ClientAbstract {
675
1090
  topMsgId,
676
1091
  sendAs,
677
1092
  entities,
1093
+ replyMarkup,
678
1094
  }));
1095
+ if (result instanceof types.Updates) {
1096
+ for (const update of result.updates) {
1097
+ if (update instanceof types.UpdateNewMessage) {
1098
+ return (0, _3_message_js_1.constructMessage)(update.message[_1_tl_object_js_1.as](types.Message), this[exports.getEntity].bind(this));
1099
+ }
1100
+ else if (update instanceof types.UpdateNewChannelMessage) {
1101
+ return (0, _3_message_js_1.constructMessage)(update.message[_1_tl_object_js_1.as](types.Message), this[exports.getEntity].bind(this));
1102
+ }
1103
+ }
1104
+ }
1105
+ else if (result instanceof types.UpdateShortSentMessage || result instanceof types.UpdateShortSentMessage) {
1106
+ const message = await this.getMessage(chatId, result.id);
1107
+ if (message != null) {
1108
+ return message;
1109
+ }
1110
+ }
1111
+ (0, _0_control_js_1.UNREACHABLE)();
1112
+ }
1113
+ async getMessages(chatId, messageIds) {
1114
+ const peer = await this.getInputPeer(chatId);
1115
+ let messages_;
1116
+ if (peer instanceof types.InputPeerChannel) {
1117
+ messages_ = await this.invoke(new functions.ChannelsGetMessages({
1118
+ channel: new types.InputChannel({ channelId: peer.channelId, accessHash: peer.accessHash }),
1119
+ id: messageIds.map((v) => new types.InputMessageID({ id: v })),
1120
+ })).then((v) => v[_1_tl_object_js_1.as](types.MessagesMessages));
1121
+ }
1122
+ else {
1123
+ messages_ = await this.invoke(new functions.MessagesGetMessages({
1124
+ id: messageIds.map((v) => new types.InputMessageID({ id: v })),
1125
+ })).then((v) => v[_1_tl_object_js_1.as](types.MessagesMessages));
1126
+ }
1127
+ const messages = new Array();
1128
+ for (const message_ of messages_.messages) {
1129
+ messages.push(await (0, _3_message_js_1.constructMessage)(message_[_1_tl_object_js_1.as](types.Message), this[exports.getEntity].bind(this)));
1130
+ }
1131
+ return messages;
1132
+ }
1133
+ async getMessage(chatId, messageId) {
1134
+ const messages = await this.getMessages(chatId, [messageId]);
1135
+ return messages[0] ?? null;
679
1136
  }
680
1137
  }
681
1138
  exports.Client = Client;