@mtkruto/node 0.0.987 → 0.0.989

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.
@@ -1,11 +1,17 @@
1
1
  import { MaybePromise } from "../utilities/0_types.js";
2
2
  import { DC, TransportProvider } from "../transport/2_transport_provider.js";
3
3
  export interface ClientAbstractParams {
4
+ /**
5
+ * The first DC to connect to. This is commonly used to decide whether to connect to test or production servers. It is not necessarily the DC that the client will directly connect to or is currently connected to. Defaults to the default initial DC.
6
+ */
4
7
  initialDc?: DC;
5
8
  /**
6
9
  * The transport provider to use. Defaults to `webSocketTransportProvider` with its default options.
7
10
  */
8
11
  transportProvider?: TransportProvider;
12
+ /**
13
+ * Whether the connection is with a CDN server. Defaults to false.
14
+ */
9
15
  cdn?: boolean;
10
16
  }
11
17
  export declare abstract class ClientAbstract {
@@ -3,7 +3,7 @@ import { Function } from "../tl/3_functions.js";
3
3
  import { ClientAbstract, ClientAbstractParams } from "./1_client_abstract.js";
4
4
  export interface ClientPlainParams extends ClientAbstractParams {
5
5
  /**
6
- * MTProto public keys to use in the `[keyId, [key, exponent]][]` format. Don't set this unless you know what you are doing.
6
+ * MTProto public keys to use in the `[keyId, [key, exponent]][]` format. Don't set this unless you know what you are doing. Defaults to Telegram servers' public keys.
7
7
  */
8
8
  publicKeys?: PublicKeys;
9
9
  }
@@ -1,17 +1,17 @@
1
1
  import { MaybePromise } from "../utilities/0_types.js";
2
+ import { DC } from "../transport/2_transport_provider.js";
2
3
  import * as types from "../tl/2_types.js";
3
- import * as functions from "../tl/3_functions.js";
4
4
  import { ReadObject } from "../tl/3_tl_reader.js";
5
- import { Storage } from "../storage/0_storage.js";
6
- import { DC } from "../transport/2_transport_provider.js";
7
- import { MessageEntity } from "../types/0_message_entity.js";
5
+ import * as functions from "../tl/3_functions.js";
8
6
  import { ReplyKeyboardRemove } from "../types/0_reply_keyboard_remove.js";
7
+ import { MessageEntity } from "../types/0_message_entity.js";
9
8
  import { ForceReply } from "../types/0_force_reply.js";
10
- import { ReplyKeyboardMarkup } from "../types/2_reply_keyboard_markup.js";
11
9
  import { InlineKeyboardMarkup } from "../types/2_inline_keyboard_markup.js";
10
+ import { ReplyKeyboardMarkup } from "../types/2_reply_keyboard_markup.js";
12
11
  import { Message } from "../types/3_message.js";
13
- import { ClientAbstract } from "./1_client_abstract.js";
12
+ import { Storage } from "../storage/0_storage.js";
14
13
  import { ClientPlainParams } from "./2_client_plain.js";
14
+ import { ClientAbstract } from "./1_client_abstract.js";
15
15
  export declare const getEntity: unique symbol;
16
16
  export declare const getStickerSetName: unique symbol;
17
17
  export declare const handleMigrationError: unique symbol;
@@ -27,35 +27,35 @@ export interface AuthorizeUserParams<S = string> {
27
27
  }
28
28
  export interface ClientParams extends ClientPlainParams {
29
29
  /**
30
- * Default parse mode. Defauls to `ParseMode.None`.
30
+ * A parse mode to use when the `parseMode` parameter is not specified when sending or editing messages. Defauls to `ParseMode.None`.
31
31
  */
32
32
  parseMode?: ParseMode;
33
33
  /**
34
- * The app_version parameter to be passed to initConnection when calling `authorize`.
34
+ * The app_version parameter to be passed to initConnection when calling `authorize`. It is recommended that this parameter is changed if users are authorized. Defaults to "MTKruto" followed by this version of MTKruto.
35
35
  */
36
36
  appVersion?: string;
37
37
  /**
38
- * The device_version parameter to be passed to initConnection when calling `authorize`.
38
+ * The device_version parameter to be passed to initConnection when calling `authorize`. The default varies by the current runtime.
39
39
  */
40
40
  deviceModel?: string;
41
41
  /**
42
- * The lang_code parameter to be passed to initConnection when calling `authorize`.
42
+ * The lang_code parameter to be passed to initConnection when calling `authorize`. Defaults to the runtime's language or `"en"`.
43
43
  */
44
44
  langCode?: string;
45
45
  /**
46
- * The lang_pack parameter to be passed to initConnection when calling `authorize`.
46
+ * The lang_pack parameter to be passed to initConnection when calling `authorize`. Defaults to an empty string.
47
47
  */
48
48
  langPack?: string;
49
49
  /**
50
- * The system_lang_cde parameter to be passed to initConnection when calling `authorize`.
50
+ * The system_lang_cde parameter to be passed to initConnection when calling `authorize`. Defaults to the runtime's language or `"en"`.
51
51
  */
52
52
  systemLangCode?: string;
53
53
  /**
54
- * The system_version parameter to be passed to initConnection when calling `authorize`.
54
+ * The system_version parameter to be passed to initConnection when calling `authorize`. The default varies by the current runtime.
55
55
  */
56
56
  systemVersion?: string;
57
57
  /**
58
- * Whether to automatically call `start` with no parameters in the first `invoke` call.
58
+ * Whether to automatically call `start` with no parameters in the first `invoke` call. Defaults to `true`.
59
59
  */
60
60
  autoStart?: boolean;
61
61
  }
@@ -171,6 +171,7 @@ export declare class Client extends ClientAbstract {
171
171
  */
172
172
  constructor(storage?: Storage, apiId?: number | null, apiHash?: string | null, params?: ClientParams);
173
173
  private propagateConnectionState;
174
+ private lastPropagatedConnectionState;
174
175
  protected stateChangeHandler: (connected: boolean) => void;
175
176
  private storageInited;
176
177
  /**
@@ -308,18 +309,17 @@ export declare class Client extends ClientAbstract {
308
309
  private handleUpdate;
309
310
  handler: Handler;
310
311
  use(middleware: Handler): void;
311
- on<U extends keyof Update, K extends null | keyof Update[U] = null>(filter: Update[U] extends string ? U : U | [U, K, ...K[]], handler: Handler<Pick<Update, U> & {
312
- [P in U]: K extends keyof Update[U] ? With<Update[U], K> : Update[U];
313
- }>): void;
312
+ on<U extends keyof Update, K extends keyof Update[U]>(filter: Update[U] extends string ? U : Update[U] extends Array<any> ? U : U | [U, ...K[]], handler: Handler<Pick<{
313
+ [P in U]: With<Update[U], K>;
314
+ }, U>>): void;
314
315
  }
315
- type With<T, K extends keyof T> = T & Required<{
316
- [P in K]: T[P];
317
- }>;
316
+ type With<T, K extends keyof T> = T & Required<Pick<T, K>>;
318
317
  export type ConnectionState = "not-connected" | "updating" | "ready";
319
318
  export interface Update {
320
319
  message: Message;
321
320
  editedMessage: Message;
322
321
  connectionState: ConnectionState;
322
+ deletedMessages: [Message, ...Message[]];
323
323
  }
324
324
  export interface Handler<U extends Partial<Update> = Partial<Update>> {
325
325
  (update: U, next: () => Promise<void>): MaybePromise<void>;
@@ -1,33 +1,33 @@
1
1
  import { debug, gunzip, Mutex } from "../deps.js";
2
2
  import { ACK_THRESHOLD, APP_VERSION, CHANNEL_DIFFERENCE_LIMIT_BOT, CHANNEL_DIFFERENCE_LIMIT_USER, DEVICE_MODEL, LANG_CODE, LANG_PACK, LAYER, MAX_CHANNEL_ID, MAX_CHAT_ID, STICKER_SET_NAME_TTL, SYSTEM_LANG_CODE, SYSTEM_VERSION, USERNAME_TTL, ZERO_CHANNEL_ID } from "../constants.js";
3
+ import { drop, mustPrompt, mustPromptOneOf } from "../utilities/1_misc.js";
3
4
  import { bigIntFromBuffer, getRandomBigInt, getRandomId } from "../utilities/0_bigint.js";
5
+ import { getChannelChatId, hasChannelPts, hasPts, peerToChatId } from "./0_utilities.js";
4
6
  import { UNREACHABLE } from "../utilities/0_control.js";
7
+ import { Queue } from "../utilities/0_queue.js";
5
8
  import { sha1 } from "../utilities/0_hash.js";
9
+ import { TLError } from "../tl/0_tl_raw_reader.js";
6
10
  import { as } from "../tl/1_tl_object.js";
7
11
  import * as types from "../tl/2_types.js";
8
- import * as functions from "../tl/3_functions.js";
9
12
  import { TLReader } from "../tl/3_tl_reader.js";
13
+ import * as functions from "../tl/3_functions.js";
10
14
  import { RPCResult } from "../tl/5_rpc_result.js";
11
15
  import { Message as Message_ } from "../tl/6_message.js"; // MTProto API message
12
16
  import { MessageContainer } from "../tl/7_message_container.js";
13
- import { StorageMemory } from "../storage/1_storage_memory.js";
14
17
  import { FileID, FileType, ThumbnailSource } from "../types/!0_file_id.js";
15
- import { messageEntityToTlObject } from "../types/0_message_entity.js";
16
18
  import { replyKeyboardRemoveToTlObject } from "../types/0_reply_keyboard_remove.js";
19
+ import { messageEntityToTlObject } from "../types/0_message_entity.js";
17
20
  import { forceReplyToTlObject } from "../types/0_force_reply.js";
18
- import { replyKeyboardMarkupToTlObject } from "../types/2_reply_keyboard_markup.js";
21
+ import { constructUser } from "../types/1_user.js";
19
22
  import { inlineKeyboardMarkupToTlObject } from "../types/2_inline_keyboard_markup.js";
23
+ import { replyKeyboardMarkupToTlObject } from "../types/2_reply_keyboard_markup.js";
20
24
  import { constructMessage } from "../types/3_message.js"; // high-level wrapper for Telegram API's message
25
+ import { StorageMemory } from "../storage/1_storage_memory.js";
21
26
  import { decryptMessage, encryptMessage, getMessageId } from "./0_message.js";
22
- import { parseHtml } from "./0_html.js";
23
27
  import { checkPassword } from "./0_password.js";
24
- import { ClientAbstract } from "./1_client_abstract.js";
28
+ import { parseHtml } from "./0_html.js";
25
29
  import { ClientPlain } from "./2_client_plain.js";
26
- import { drop, mustPrompt, mustPromptOneOf } from "../utilities/1_misc.js";
27
- import { getChannelChatId, hasChannelPts, hasPts, peerToChatId } from "./0_utilities.js";
28
- import { constructUser } from "../types/1_user.js";
29
- import { TLError } from "../tl/0_tl_raw_reader.js";
30
- import { Queue } from "../utilities/0_queue.js";
30
+ import { ClientAbstract } from "./1_client_abstract.js";
31
31
  const d = debug("Client");
32
32
  const dGap = debug("Client/recoverUpdateGap");
33
33
  const dGapC = debug("Client/recoverChannelUpdateGap");
@@ -161,12 +161,29 @@ export class Client extends ClientAbstract {
161
161
  writable: true,
162
162
  value: void 0
163
163
  });
164
+ Object.defineProperty(this, "lastPropagatedConnectionState", {
165
+ enumerable: true,
166
+ configurable: true,
167
+ writable: true,
168
+ value: null
169
+ });
164
170
  Object.defineProperty(this, "stateChangeHandler", {
165
171
  enumerable: true,
166
172
  configurable: true,
167
173
  writable: true,
168
174
  value: ((connected) => {
169
- this.propagateConnectionState(connected ? "ready" : "not-connected");
175
+ this.connectMutex.acquire().then(async (release) => {
176
+ try {
177
+ const connectionState = connected ? "ready" : "not-connected";
178
+ if (this.connected == connected && this.lastPropagatedConnectionState != connectionState) {
179
+ await this.propagateConnectionState(connectionState);
180
+ this.lastPropagatedConnectionState = connectionState;
181
+ }
182
+ }
183
+ finally {
184
+ release();
185
+ }
186
+ });
170
187
  }).bind(this)
171
188
  });
172
189
  Object.defineProperty(this, "storageInited", {
@@ -802,7 +819,7 @@ export class Client extends ClientAbstract {
802
819
  if (currentPts === undefined) {
803
820
  currentPts = await this.storage.getChannelPts(channelId);
804
821
  }
805
- currentPts ??= update.pts;
822
+ currentPts ??= update.pts - ptsCount;
806
823
  if (currentPts + ptsCount > update.pts) {
807
824
  updates = updates.filter((v) => v != update);
808
825
  }
@@ -1411,25 +1428,13 @@ export class Client extends ClientAbstract {
1411
1428
  }
1412
1429
  return constructUser(users[0][as](types.User));
1413
1430
  }
1431
+ // TODO: log errors
1414
1432
  async handleUpdate(update) {
1415
1433
  if (update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewChannelMessage || update instanceof types.UpdateNewChannelMessage) {
1416
1434
  if (update.message instanceof types.Message || update.message instanceof types.MessageService) {
1417
1435
  await this.storage.setMessage(peerToChatId(update.message.peerId), update.message.id, update.message);
1418
1436
  }
1419
1437
  }
1420
- else if (update instanceof types.UpdateDeleteChannelMessages) {
1421
- for (const message of update.messages) {
1422
- await this.storage.setMessage(getChannelChatId(update.channelId), message, null);
1423
- }
1424
- }
1425
- else if (update instanceof types.UpdateDeleteMessages) {
1426
- for (const message of update.messages) {
1427
- const chatId = await this.storage.getMessageChat(message);
1428
- if (chatId) {
1429
- await this.storage.setMessage(chatId, message, null);
1430
- }
1431
- }
1432
- }
1433
1438
  if (update instanceof types.UpdateNewMessage ||
1434
1439
  update instanceof types.UpdateNewChannelMessage ||
1435
1440
  update instanceof types.UpdateEditMessage ||
@@ -1438,20 +1443,52 @@ export class Client extends ClientAbstract {
1438
1443
  const message = await constructMessage(update.message, this[getEntity].bind(this), this.getMessage.bind(this), this[getStickerSetName].bind(this));
1439
1444
  await this.handler({ [key]: message }, resolve);
1440
1445
  }
1446
+ if (update instanceof types.UpdateDeleteMessages) {
1447
+ const deletedMessages = new Array();
1448
+ for (const messageId of update.messages) {
1449
+ const chatId = await this.storage.getMessageChat(messageId);
1450
+ if (chatId) {
1451
+ const message = await this.storage.getMessage(chatId, messageId);
1452
+ if (message != null) {
1453
+ deletedMessages.push(await constructMessage(message, this[getEntity].bind(this), this.getMessage.bind(this), this[getStickerSetName].bind(this)));
1454
+ }
1455
+ await this.storage.setMessage(chatId, messageId, null);
1456
+ }
1457
+ }
1458
+ if (deletedMessages.length > 0) {
1459
+ await this.handler({ deletedMessages: deletedMessages }, resolve);
1460
+ }
1461
+ }
1462
+ else if (update instanceof types.UpdateDeleteChannelMessages) {
1463
+ const chatId = getChannelChatId(update.channelId);
1464
+ const deletedMessages = new Array();
1465
+ for (const messageId of update.messages) {
1466
+ const message = await this.storage.getMessage(chatId, messageId);
1467
+ if (message) {
1468
+ deletedMessages.push(await constructMessage(message, this[getEntity].bind(this), this.getMessage.bind(this), this[getStickerSetName].bind(this)));
1469
+ }
1470
+ await this.storage.setMessage(chatId, messageId, null);
1471
+ }
1472
+ if (deletedMessages.length > 0) {
1473
+ await this.handler({ deletedMessages: deletedMessages }, resolve);
1474
+ }
1475
+ }
1441
1476
  }
1442
1477
  use(middleware) {
1443
1478
  const handler = this.handler;
1444
1479
  this.handler = async (upd, next) => {
1445
1480
  let called = false;
1446
- await middleware(upd, async () => {
1481
+ await handler(upd, async () => {
1447
1482
  if (called)
1448
1483
  return;
1449
1484
  called = true;
1450
- await handler(upd, next);
1485
+ await middleware(upd, next);
1451
1486
  });
1452
1487
  };
1453
1488
  }
1454
- on(filter, handler) {
1489
+ on(
1490
+ // deno-lint-ignore no-explicit-any
1491
+ filter, handler) {
1455
1492
  const type = typeof filter === "string" ? filter : filter[0];
1456
1493
  const keys = Array.isArray(filter) ? filter.slice(1) : [];
1457
1494
  this.use((update, next) => {
@@ -5,7 +5,7 @@ export declare const PUBLIC_KEYS: PublicKeys;
5
5
  export declare const VECTOR_CONSTRUCTOR = 481674261;
6
6
  export declare const INITIAL_DC: DC;
7
7
  export declare const LAYER = 161;
8
- export declare const APP_VERSION = "MTKruto 0.0.987";
8
+ export declare const APP_VERSION = "MTKruto 0.0.989";
9
9
  export declare const DEVICE_MODEL: string;
10
10
  export declare const LANG_CODE: string;
11
11
  export declare const LANG_PACK = "";
package/esm/constants.js CHANGED
@@ -54,7 +54,7 @@ export const PUBLIC_KEYS = Object.freeze([
54
54
  export const VECTOR_CONSTRUCTOR = 0x1CB5C415;
55
55
  export const INITIAL_DC = "2-test";
56
56
  export const LAYER = 161;
57
- export const APP_VERSION = "MTKruto 0.0.987";
57
+ export const APP_VERSION = "MTKruto 0.0.989";
58
58
  // @ts-ignore: lib
59
59
  export const DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
60
60
  export const LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "module": "./esm/mod.js",
3
3
  "main": "./script/mod.js",
4
4
  "name": "@mtkruto/node",
5
- "version": "0.0.987",
5
+ "version": "0.0.989",
6
6
  "description": "MTKruto for Node.js",
7
7
  "author": "Roj <rojvv@icloud.com>",
8
8
  "license": "LGPL-3.0-or-later",
@@ -1,11 +1,17 @@
1
1
  import { MaybePromise } from "../utilities/0_types.js";
2
2
  import { DC, TransportProvider } from "../transport/2_transport_provider.js";
3
3
  export interface ClientAbstractParams {
4
+ /**
5
+ * The first DC to connect to. This is commonly used to decide whether to connect to test or production servers. It is not necessarily the DC that the client will directly connect to or is currently connected to. Defaults to the default initial DC.
6
+ */
4
7
  initialDc?: DC;
5
8
  /**
6
9
  * The transport provider to use. Defaults to `webSocketTransportProvider` with its default options.
7
10
  */
8
11
  transportProvider?: TransportProvider;
12
+ /**
13
+ * Whether the connection is with a CDN server. Defaults to false.
14
+ */
9
15
  cdn?: boolean;
10
16
  }
11
17
  export declare abstract class ClientAbstract {
@@ -3,7 +3,7 @@ import { Function } from "../tl/3_functions.js";
3
3
  import { ClientAbstract, ClientAbstractParams } from "./1_client_abstract.js";
4
4
  export interface ClientPlainParams extends ClientAbstractParams {
5
5
  /**
6
- * MTProto public keys to use in the `[keyId, [key, exponent]][]` format. Don't set this unless you know what you are doing.
6
+ * MTProto public keys to use in the `[keyId, [key, exponent]][]` format. Don't set this unless you know what you are doing. Defaults to Telegram servers' public keys.
7
7
  */
8
8
  publicKeys?: PublicKeys;
9
9
  }
@@ -1,17 +1,17 @@
1
1
  import { MaybePromise } from "../utilities/0_types.js";
2
+ import { DC } from "../transport/2_transport_provider.js";
2
3
  import * as types from "../tl/2_types.js";
3
- import * as functions from "../tl/3_functions.js";
4
4
  import { ReadObject } from "../tl/3_tl_reader.js";
5
- import { Storage } from "../storage/0_storage.js";
6
- import { DC } from "../transport/2_transport_provider.js";
7
- import { MessageEntity } from "../types/0_message_entity.js";
5
+ import * as functions from "../tl/3_functions.js";
8
6
  import { ReplyKeyboardRemove } from "../types/0_reply_keyboard_remove.js";
7
+ import { MessageEntity } from "../types/0_message_entity.js";
9
8
  import { ForceReply } from "../types/0_force_reply.js";
10
- import { ReplyKeyboardMarkup } from "../types/2_reply_keyboard_markup.js";
11
9
  import { InlineKeyboardMarkup } from "../types/2_inline_keyboard_markup.js";
10
+ import { ReplyKeyboardMarkup } from "../types/2_reply_keyboard_markup.js";
12
11
  import { Message } from "../types/3_message.js";
13
- import { ClientAbstract } from "./1_client_abstract.js";
12
+ import { Storage } from "../storage/0_storage.js";
14
13
  import { ClientPlainParams } from "./2_client_plain.js";
14
+ import { ClientAbstract } from "./1_client_abstract.js";
15
15
  export declare const getEntity: unique symbol;
16
16
  export declare const getStickerSetName: unique symbol;
17
17
  export declare const handleMigrationError: unique symbol;
@@ -27,35 +27,35 @@ export interface AuthorizeUserParams<S = string> {
27
27
  }
28
28
  export interface ClientParams extends ClientPlainParams {
29
29
  /**
30
- * Default parse mode. Defauls to `ParseMode.None`.
30
+ * A parse mode to use when the `parseMode` parameter is not specified when sending or editing messages. Defauls to `ParseMode.None`.
31
31
  */
32
32
  parseMode?: ParseMode;
33
33
  /**
34
- * The app_version parameter to be passed to initConnection when calling `authorize`.
34
+ * The app_version parameter to be passed to initConnection when calling `authorize`. It is recommended that this parameter is changed if users are authorized. Defaults to "MTKruto" followed by this version of MTKruto.
35
35
  */
36
36
  appVersion?: string;
37
37
  /**
38
- * The device_version parameter to be passed to initConnection when calling `authorize`.
38
+ * The device_version parameter to be passed to initConnection when calling `authorize`. The default varies by the current runtime.
39
39
  */
40
40
  deviceModel?: string;
41
41
  /**
42
- * The lang_code parameter to be passed to initConnection when calling `authorize`.
42
+ * The lang_code parameter to be passed to initConnection when calling `authorize`. Defaults to the runtime's language or `"en"`.
43
43
  */
44
44
  langCode?: string;
45
45
  /**
46
- * The lang_pack parameter to be passed to initConnection when calling `authorize`.
46
+ * The lang_pack parameter to be passed to initConnection when calling `authorize`. Defaults to an empty string.
47
47
  */
48
48
  langPack?: string;
49
49
  /**
50
- * The system_lang_cde parameter to be passed to initConnection when calling `authorize`.
50
+ * The system_lang_cde parameter to be passed to initConnection when calling `authorize`. Defaults to the runtime's language or `"en"`.
51
51
  */
52
52
  systemLangCode?: string;
53
53
  /**
54
- * The system_version parameter to be passed to initConnection when calling `authorize`.
54
+ * The system_version parameter to be passed to initConnection when calling `authorize`. The default varies by the current runtime.
55
55
  */
56
56
  systemVersion?: string;
57
57
  /**
58
- * Whether to automatically call `start` with no parameters in the first `invoke` call.
58
+ * Whether to automatically call `start` with no parameters in the first `invoke` call. Defaults to `true`.
59
59
  */
60
60
  autoStart?: boolean;
61
61
  }
@@ -171,6 +171,7 @@ export declare class Client extends ClientAbstract {
171
171
  */
172
172
  constructor(storage?: Storage, apiId?: number | null, apiHash?: string | null, params?: ClientParams);
173
173
  private propagateConnectionState;
174
+ private lastPropagatedConnectionState;
174
175
  protected stateChangeHandler: (connected: boolean) => void;
175
176
  private storageInited;
176
177
  /**
@@ -308,18 +309,17 @@ export declare class Client extends ClientAbstract {
308
309
  private handleUpdate;
309
310
  handler: Handler;
310
311
  use(middleware: Handler): void;
311
- on<U extends keyof Update, K extends null | keyof Update[U] = null>(filter: Update[U] extends string ? U : U | [U, K, ...K[]], handler: Handler<Pick<Update, U> & {
312
- [P in U]: K extends keyof Update[U] ? With<Update[U], K> : Update[U];
313
- }>): void;
312
+ on<U extends keyof Update, K extends keyof Update[U]>(filter: Update[U] extends string ? U : Update[U] extends Array<any> ? U : U | [U, ...K[]], handler: Handler<Pick<{
313
+ [P in U]: With<Update[U], K>;
314
+ }, U>>): void;
314
315
  }
315
- type With<T, K extends keyof T> = T & Required<{
316
- [P in K]: T[P];
317
- }>;
316
+ type With<T, K extends keyof T> = T & Required<Pick<T, K>>;
318
317
  export type ConnectionState = "not-connected" | "updating" | "ready";
319
318
  export interface Update {
320
319
  message: Message;
321
320
  editedMessage: Message;
322
321
  connectionState: ConnectionState;
322
+ deletedMessages: [Message, ...Message[]];
323
323
  }
324
324
  export interface Handler<U extends Partial<Update> = Partial<Update>> {
325
325
  (update: U, next: () => Promise<void>): MaybePromise<void>;
@@ -26,34 +26,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Client = exports.ParseMode = exports.restartAuth = exports.handleMigrationError = exports.getStickerSetName = exports.getEntity = void 0;
27
27
  const deps_js_1 = require("../deps.js");
28
28
  const constants_js_1 = require("../constants.js");
29
+ const _1_misc_js_1 = require("../utilities/1_misc.js");
29
30
  const _0_bigint_js_1 = require("../utilities/0_bigint.js");
31
+ const _0_utilities_js_1 = require("./0_utilities.js");
30
32
  const _0_control_js_1 = require("../utilities/0_control.js");
33
+ const _0_queue_js_1 = require("../utilities/0_queue.js");
31
34
  const _0_hash_js_1 = require("../utilities/0_hash.js");
35
+ const _0_tl_raw_reader_js_1 = require("../tl/0_tl_raw_reader.js");
32
36
  const _1_tl_object_js_1 = require("../tl/1_tl_object.js");
33
37
  const types = __importStar(require("../tl/2_types.js"));
34
- const functions = __importStar(require("../tl/3_functions.js"));
35
38
  const _3_tl_reader_js_1 = require("../tl/3_tl_reader.js");
39
+ const functions = __importStar(require("../tl/3_functions.js"));
36
40
  const _5_rpc_result_js_1 = require("../tl/5_rpc_result.js");
37
41
  const _6_message_js_1 = require("../tl/6_message.js"); // MTProto API message
38
42
  const _7_message_container_js_1 = require("../tl/7_message_container.js");
39
- const _1_storage_memory_js_1 = require("../storage/1_storage_memory.js");
40
43
  const _0_file_id_js_1 = require("../types/!0_file_id.js");
41
- const _0_message_entity_js_1 = require("../types/0_message_entity.js");
42
44
  const _0_reply_keyboard_remove_js_1 = require("../types/0_reply_keyboard_remove.js");
45
+ const _0_message_entity_js_1 = require("../types/0_message_entity.js");
43
46
  const _0_force_reply_js_1 = require("../types/0_force_reply.js");
44
- const _2_reply_keyboard_markup_js_1 = require("../types/2_reply_keyboard_markup.js");
47
+ const _1_user_js_1 = require("../types/1_user.js");
45
48
  const _2_inline_keyboard_markup_js_1 = require("../types/2_inline_keyboard_markup.js");
49
+ const _2_reply_keyboard_markup_js_1 = require("../types/2_reply_keyboard_markup.js");
46
50
  const _3_message_js_1 = require("../types/3_message.js"); // high-level wrapper for Telegram API's message
51
+ const _1_storage_memory_js_1 = require("../storage/1_storage_memory.js");
47
52
  const _0_message_js_1 = require("./0_message.js");
48
- const _0_html_js_1 = require("./0_html.js");
49
53
  const _0_password_js_1 = require("./0_password.js");
50
- const _1_client_abstract_js_1 = require("./1_client_abstract.js");
54
+ const _0_html_js_1 = require("./0_html.js");
51
55
  const _2_client_plain_js_1 = require("./2_client_plain.js");
52
- const _1_misc_js_1 = require("../utilities/1_misc.js");
53
- const _0_utilities_js_1 = require("./0_utilities.js");
54
- const _1_user_js_1 = require("../types/1_user.js");
55
- const _0_tl_raw_reader_js_1 = require("../tl/0_tl_raw_reader.js");
56
- const _0_queue_js_1 = require("../utilities/0_queue.js");
56
+ const _1_client_abstract_js_1 = require("./1_client_abstract.js");
57
57
  const d = (0, deps_js_1.debug)("Client");
58
58
  const dGap = (0, deps_js_1.debug)("Client/recoverUpdateGap");
59
59
  const dGapC = (0, deps_js_1.debug)("Client/recoverChannelUpdateGap");
@@ -187,12 +187,29 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
187
187
  writable: true,
188
188
  value: void 0
189
189
  });
190
+ Object.defineProperty(this, "lastPropagatedConnectionState", {
191
+ enumerable: true,
192
+ configurable: true,
193
+ writable: true,
194
+ value: null
195
+ });
190
196
  Object.defineProperty(this, "stateChangeHandler", {
191
197
  enumerable: true,
192
198
  configurable: true,
193
199
  writable: true,
194
200
  value: ((connected) => {
195
- this.propagateConnectionState(connected ? "ready" : "not-connected");
201
+ this.connectMutex.acquire().then(async (release) => {
202
+ try {
203
+ const connectionState = connected ? "ready" : "not-connected";
204
+ if (this.connected == connected && this.lastPropagatedConnectionState != connectionState) {
205
+ await this.propagateConnectionState(connectionState);
206
+ this.lastPropagatedConnectionState = connectionState;
207
+ }
208
+ }
209
+ finally {
210
+ release();
211
+ }
212
+ });
196
213
  }).bind(this)
197
214
  });
198
215
  Object.defineProperty(this, "storageInited", {
@@ -828,7 +845,7 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
828
845
  if (currentPts === undefined) {
829
846
  currentPts = await this.storage.getChannelPts(channelId);
830
847
  }
831
- currentPts ??= update.pts;
848
+ currentPts ??= update.pts - ptsCount;
832
849
  if (currentPts + ptsCount > update.pts) {
833
850
  updates = updates.filter((v) => v != update);
834
851
  }
@@ -1437,25 +1454,13 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
1437
1454
  }
1438
1455
  return (0, _1_user_js_1.constructUser)(users[0][_1_tl_object_js_1.as](types.User));
1439
1456
  }
1457
+ // TODO: log errors
1440
1458
  async handleUpdate(update) {
1441
1459
  if (update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewChannelMessage || update instanceof types.UpdateNewChannelMessage) {
1442
1460
  if (update.message instanceof types.Message || update.message instanceof types.MessageService) {
1443
1461
  await this.storage.setMessage((0, _0_utilities_js_1.peerToChatId)(update.message.peerId), update.message.id, update.message);
1444
1462
  }
1445
1463
  }
1446
- else if (update instanceof types.UpdateDeleteChannelMessages) {
1447
- for (const message of update.messages) {
1448
- await this.storage.setMessage((0, _0_utilities_js_1.getChannelChatId)(update.channelId), message, null);
1449
- }
1450
- }
1451
- else if (update instanceof types.UpdateDeleteMessages) {
1452
- for (const message of update.messages) {
1453
- const chatId = await this.storage.getMessageChat(message);
1454
- if (chatId) {
1455
- await this.storage.setMessage(chatId, message, null);
1456
- }
1457
- }
1458
- }
1459
1464
  if (update instanceof types.UpdateNewMessage ||
1460
1465
  update instanceof types.UpdateNewChannelMessage ||
1461
1466
  update instanceof types.UpdateEditMessage ||
@@ -1464,20 +1469,52 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
1464
1469
  const message = await (0, _3_message_js_1.constructMessage)(update.message, this[exports.getEntity].bind(this), this.getMessage.bind(this), this[exports.getStickerSetName].bind(this));
1465
1470
  await this.handler({ [key]: message }, resolve);
1466
1471
  }
1472
+ if (update instanceof types.UpdateDeleteMessages) {
1473
+ const deletedMessages = new Array();
1474
+ for (const messageId of update.messages) {
1475
+ const chatId = await this.storage.getMessageChat(messageId);
1476
+ if (chatId) {
1477
+ const message = await this.storage.getMessage(chatId, messageId);
1478
+ if (message != null) {
1479
+ deletedMessages.push(await (0, _3_message_js_1.constructMessage)(message, this[exports.getEntity].bind(this), this.getMessage.bind(this), this[exports.getStickerSetName].bind(this)));
1480
+ }
1481
+ await this.storage.setMessage(chatId, messageId, null);
1482
+ }
1483
+ }
1484
+ if (deletedMessages.length > 0) {
1485
+ await this.handler({ deletedMessages: deletedMessages }, resolve);
1486
+ }
1487
+ }
1488
+ else if (update instanceof types.UpdateDeleteChannelMessages) {
1489
+ const chatId = (0, _0_utilities_js_1.getChannelChatId)(update.channelId);
1490
+ const deletedMessages = new Array();
1491
+ for (const messageId of update.messages) {
1492
+ const message = await this.storage.getMessage(chatId, messageId);
1493
+ if (message) {
1494
+ deletedMessages.push(await (0, _3_message_js_1.constructMessage)(message, this[exports.getEntity].bind(this), this.getMessage.bind(this), this[exports.getStickerSetName].bind(this)));
1495
+ }
1496
+ await this.storage.setMessage(chatId, messageId, null);
1497
+ }
1498
+ if (deletedMessages.length > 0) {
1499
+ await this.handler({ deletedMessages: deletedMessages }, resolve);
1500
+ }
1501
+ }
1467
1502
  }
1468
1503
  use(middleware) {
1469
1504
  const handler = this.handler;
1470
1505
  this.handler = async (upd, next) => {
1471
1506
  let called = false;
1472
- await middleware(upd, async () => {
1507
+ await handler(upd, async () => {
1473
1508
  if (called)
1474
1509
  return;
1475
1510
  called = true;
1476
- await handler(upd, next);
1511
+ await middleware(upd, next);
1477
1512
  });
1478
1513
  };
1479
1514
  }
1480
- on(filter, handler) {
1515
+ on(
1516
+ // deno-lint-ignore no-explicit-any
1517
+ filter, handler) {
1481
1518
  const type = typeof filter === "string" ? filter : filter[0];
1482
1519
  const keys = Array.isArray(filter) ? filter.slice(1) : [];
1483
1520
  this.use((update, next) => {
@@ -5,7 +5,7 @@ export declare const PUBLIC_KEYS: PublicKeys;
5
5
  export declare const VECTOR_CONSTRUCTOR = 481674261;
6
6
  export declare const INITIAL_DC: DC;
7
7
  export declare const LAYER = 161;
8
- export declare const APP_VERSION = "MTKruto 0.0.987";
8
+ export declare const APP_VERSION = "MTKruto 0.0.989";
9
9
  export declare const DEVICE_MODEL: string;
10
10
  export declare const LANG_CODE: string;
11
11
  export declare const LANG_PACK = "";
@@ -80,7 +80,7 @@ exports.PUBLIC_KEYS = Object.freeze([
80
80
  exports.VECTOR_CONSTRUCTOR = 0x1CB5C415;
81
81
  exports.INITIAL_DC = "2-test";
82
82
  exports.LAYER = 161;
83
- exports.APP_VERSION = "MTKruto 0.0.987";
83
+ exports.APP_VERSION = "MTKruto 0.0.989";
84
84
  // @ts-ignore: lib
85
85
  exports.DEVICE_MODEL = typeof dntShim.Deno === "undefined" ? typeof navigator === "undefined" ? typeof process === "undefined" ? "Unknown" : process.platform + "-" + process.arch : navigator.userAgent.split(" ")[0] : dntShim.Deno.build.os + "-" + dntShim.Deno.build.arch;
86
86
  exports.LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];