@mtkruto/node 0.0.910 → 0.0.921

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 (51) hide show
  1. package/esm/client/1_client_abstract.d.ts +2 -1
  2. package/esm/client/1_client_abstract.js +9 -3
  3. package/esm/client/3_client.d.ts +4 -2
  4. package/esm/client/3_client.js +150 -76
  5. package/esm/constants.d.ts +1 -1
  6. package/esm/constants.js +1 -1
  7. package/esm/deps.d.ts +1 -2
  8. package/esm/deps.js +0 -1
  9. package/esm/types/!0_file_id.d.ts +6 -6
  10. package/esm/types/!0_file_id.js +11 -58
  11. package/esm/types/0_chat_photo.d.ts +1 -0
  12. package/esm/types/0_chat_photo.js +4 -2
  13. package/esm/types/0_thumbnail.d.ts +9 -0
  14. package/esm/types/0_thumbnail.js +9 -0
  15. package/esm/types/1_photo.d.ts +11 -0
  16. package/esm/types/1_photo.js +49 -0
  17. package/esm/types/3_message.d.ts +2 -0
  18. package/esm/types/3_message.js +8 -3
  19. package/esm/utilities/0_base64.d.ts +2 -0
  20. package/esm/utilities/0_base64.js +9 -0
  21. package/esm/utilities/0_rle.d.ts +2 -0
  22. package/esm/utilities/0_rle.js +49 -0
  23. package/esm/utilities/0_rle_test.d.ts +1 -0
  24. package/package.json +1 -1
  25. package/script/client/1_client_abstract.d.ts +2 -1
  26. package/script/client/1_client_abstract.js +9 -3
  27. package/script/client/3_client.d.ts +4 -2
  28. package/script/client/3_client.js +149 -75
  29. package/script/constants.d.ts +1 -1
  30. package/script/constants.js +1 -1
  31. package/script/deps.d.ts +1 -2
  32. package/script/deps.js +1 -3
  33. package/script/types/!0_file_id.d.ts +6 -6
  34. package/script/types/!0_file_id.js +11 -58
  35. package/script/types/0_chat_photo.d.ts +1 -0
  36. package/script/types/0_chat_photo.js +4 -2
  37. package/script/types/0_thumbnail.d.ts +9 -0
  38. package/script/types/0_thumbnail.js +13 -0
  39. package/script/types/1_photo.d.ts +11 -0
  40. package/script/types/1_photo.js +76 -0
  41. package/script/types/3_message.d.ts +2 -0
  42. package/script/types/3_message.js +8 -3
  43. package/script/utilities/0_base64.d.ts +2 -0
  44. package/script/utilities/0_base64.js +14 -0
  45. package/script/utilities/0_rle.d.ts +2 -0
  46. package/script/utilities/0_rle.js +54 -0
  47. package/script/utilities/0_rle_test.d.ts +1 -0
  48. package/esm/deps/deno.land/x/q@v0.0.1/mod.d.ts +0 -6
  49. package/esm/deps/deno.land/x/q@v0.0.1/mod.js +0 -71
  50. package/script/deps/deno.land/x/q@v0.0.1/mod.d.ts +0 -6
  51. package/script/deps/deno.land/x/q@v0.0.1/mod.js +0 -75
@@ -0,0 +1,11 @@
1
+ import * as types from "../tl/2_types.js";
2
+ import { Thumbnail } from "./0_thumbnail.js";
3
+ export interface Photo {
4
+ fileId: string;
5
+ fileUniqueId: string;
6
+ width: number;
7
+ height: number;
8
+ fileSize: number;
9
+ thumbnails: Thumbnail[];
10
+ }
11
+ export declare function constructPhoto(photo: types.Photo): Photo;
@@ -0,0 +1,49 @@
1
+ import { as } from "../tl/1_tl_object.js";
2
+ import * as types from "../tl/2_types.js";
3
+ import { FileID, FileType, FileUniqueID, FileUniqueType, ThumbnailSource } from "./!0_file_id.js";
4
+ import { constructThumbnail } from "./0_thumbnail.js";
5
+ export function constructPhoto(photo) {
6
+ const sizes = photo.sizes
7
+ .map((v) => {
8
+ if (v instanceof types.PhotoSizeProgressive) {
9
+ return new types.PhotoSize({ type: v.type, w: v.w, h: v.h, size: Math.max(...v.sizes) });
10
+ }
11
+ else {
12
+ return v;
13
+ }
14
+ })
15
+ .map((v) => v[as](types.PhotoSize))
16
+ .sort((a, b) => a.size - b.size);
17
+ const largest = sizes.slice(-1)[0];
18
+ const { dcId, id: mediaId, accessHash, fileReference } = photo;
19
+ const fileUniqueId = new FileUniqueID(FileUniqueType.Document, { mediaId: photo.id }).encode();
20
+ return {
21
+ fileId: new FileID(null, null, FileType.Photo, dcId, {
22
+ mediaId,
23
+ accessHash,
24
+ fileReference,
25
+ thumbnailSource: ThumbnailSource.Thumbnail,
26
+ thumbnailFileType: FileType.Photo,
27
+ thumbnailSize: largest.type,
28
+ volumeId: 0n,
29
+ localId: 0,
30
+ }).encode(),
31
+ fileUniqueId,
32
+ width: largest.w,
33
+ height: largest.h,
34
+ fileSize: largest.size,
35
+ thumbnails: sizes.slice(0, -1).map((v) => {
36
+ const fileId = new FileID(null, null, FileType.Photo, dcId, {
37
+ mediaId,
38
+ accessHash,
39
+ fileReference,
40
+ thumbnailSource: ThumbnailSource.Thumbnail,
41
+ thumbnailFileType: FileType.Photo,
42
+ thumbnailSize: v.type,
43
+ volumeId: 0n,
44
+ localId: 0,
45
+ }).encode();
46
+ return constructThumbnail(v, fileId, fileUniqueId);
47
+ }),
48
+ };
49
+ }
@@ -7,6 +7,7 @@ import { Chat } from "./1_chat.js";
7
7
  import { User } from "./1_user.js";
8
8
  import { InlineKeyboardMarkup } from "./2_inline_keyboard_markup.js";
9
9
  import { ReplyKeyboardMarkup } from "./2_reply_keyboard_markup.js";
10
+ import { Photo } from "./1_photo.js";
10
11
  export interface Message {
11
12
  id: number;
12
13
  threadId?: number;
@@ -35,6 +36,7 @@ export interface Message {
35
36
  hasMediaSpoiler?: boolean;
36
37
  views?: number;
37
38
  replyMarkup?: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply;
39
+ photo?: Photo;
38
40
  }
39
41
  export declare function constructMessage(message_: types.Message, getEntity: {
40
42
  (peer: types.PeerUser): MaybePromise<types.User | null>;
@@ -9,6 +9,7 @@ import { constructChat } from "./1_chat.js";
9
9
  import { constructUser } from "./1_user.js";
10
10
  import { constructInlineKeyboardMarkup } from "./2_inline_keyboard_markup.js";
11
11
  import { constructReplyKeyboardMarkup } from "./2_reply_keyboard_markup.js";
12
+ import { constructPhoto } from "./1_photo.js";
12
13
  const d = debug("types/Message");
13
14
  export async function constructMessage(message_, getEntity, getMessage) {
14
15
  let chat_ = null;
@@ -73,9 +74,6 @@ export async function constructMessage(message_, getEntity, getMessage) {
73
74
  UNREACHABLE();
74
75
  }
75
76
  }
76
- else {
77
- UNREACHABLE();
78
- }
79
77
  if (message_.message) {
80
78
  if (message_.media == undefined) {
81
79
  message.text = message_.message;
@@ -176,5 +174,12 @@ export async function constructMessage(message_, getEntity, getMessage) {
176
174
  UNREACHABLE();
177
175
  }
178
176
  }
177
+ if (message_.media) {
178
+ if (message_.media instanceof types.MessageMediaPhoto) {
179
+ if (message_.media.photo instanceof types.Photo) {
180
+ message.photo = constructPhoto(message_.media.photo);
181
+ }
182
+ }
183
+ }
179
184
  return cleanObject(message);
180
185
  }
@@ -0,0 +1,2 @@
1
+ export declare function base64EncodeUrlSafe(data: ArrayBuffer | string): string;
2
+ export declare function base64DecodeUrlSafe(data: string): Uint8Array;
@@ -0,0 +1,9 @@
1
+ import { base64Decode, base64Encode } from "../deps.js";
2
+ // TODO: test
3
+ export function base64EncodeUrlSafe(data) {
4
+ return base64Encode(data).replace(/=*$/, "").replaceAll("+", "-").replaceAll("/", "_");
5
+ }
6
+ export function base64DecodeUrlSafe(data) {
7
+ data = data.replaceAll("_", "/").replaceAll("-", "+");
8
+ return base64Decode(data + "=".repeat(data.length % 4));
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare function rleEncode(s: Uint8Array): Uint8Array;
2
+ export declare function rleDecode(s: Uint8Array): Uint8Array;
@@ -0,0 +1,49 @@
1
+ export function rleEncode(s) {
2
+ const r = new Array();
3
+ let n = 0;
4
+ for (const b of s) {
5
+ if (!b) {
6
+ if (n == 255) {
7
+ r.push(0);
8
+ r.push(n);
9
+ n = 1;
10
+ }
11
+ else {
12
+ n++;
13
+ }
14
+ }
15
+ else {
16
+ if (n) {
17
+ r.push(0);
18
+ r.push(n);
19
+ n = 0;
20
+ }
21
+ r.push(b);
22
+ }
23
+ }
24
+ if (n) {
25
+ r.push(0);
26
+ r.push(n);
27
+ }
28
+ return new Uint8Array(r);
29
+ }
30
+ export function rleDecode(s) {
31
+ const r = new Array();
32
+ let z = false;
33
+ for (const b of s) {
34
+ if (!b) {
35
+ z = true;
36
+ continue;
37
+ }
38
+ if (z) {
39
+ for (let i = 0; i < b; i++) {
40
+ r.push(0);
41
+ }
42
+ z = false;
43
+ }
44
+ else {
45
+ r.push(b);
46
+ }
47
+ }
48
+ return new Uint8Array(r);
49
+ }
@@ -0,0 +1 @@
1
+ export {};
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.910",
5
+ "version": "0.0.921",
6
6
  "description": "MTKruto for Node.js",
7
7
  "author": "Roj <rojvv@icloud.com>",
8
8
  "license": "LGPL-3.0-or-later",
@@ -4,12 +4,13 @@ import { Transport } from "../transport/0_transport.js";
4
4
  import { DC } from "../transport/2_transport_provider.js";
5
5
  export declare abstract class ClientAbstract {
6
6
  protected transportProvider: import("../transport/2_transport_provider.js").TransportProvider;
7
+ protected readonly cdn: boolean;
7
8
  protected connection: Connection;
8
9
  protected transport: Transport;
9
10
  private _dcId;
10
11
  private _initialDc;
11
12
  get initialDc(): DC;
12
- constructor(transportProvider?: import("../transport/2_transport_provider.js").TransportProvider);
13
+ constructor(transportProvider?: import("../transport/2_transport_provider.js").TransportProvider, cdn?: boolean);
13
14
  get dcId(): number;
14
15
  setDc(dc: DC): MaybePromise<void>;
15
16
  get connected(): boolean;
@@ -8,13 +8,19 @@ class ClientAbstract {
8
8
  get initialDc() {
9
9
  return this._initialDc;
10
10
  }
11
- constructor(transportProvider = (0, _2_transport_provider_js_1.defaultTransportProvider)({ initialDc: constants_js_1.DEFAULT_INITIAL_DC })) {
11
+ constructor(transportProvider = (0, _2_transport_provider_js_1.defaultTransportProvider)({ initialDc: constants_js_1.DEFAULT_INITIAL_DC }), cdn = false) {
12
12
  Object.defineProperty(this, "transportProvider", {
13
13
  enumerable: true,
14
14
  configurable: true,
15
15
  writable: true,
16
16
  value: transportProvider
17
17
  });
18
+ Object.defineProperty(this, "cdn", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: cdn
23
+ });
18
24
  Object.defineProperty(this, "connection", {
19
25
  enumerable: true,
20
26
  configurable: true,
@@ -41,7 +47,7 @@ class ClientAbstract {
41
47
  });
42
48
  const { initialDc, createTransport } = transportProvider;
43
49
  this._initialDc = initialDc;
44
- const { connection, transport, dcId } = createTransport({ cdn: false });
50
+ const { connection, transport, dcId } = createTransport({ cdn: this.cdn });
45
51
  this.connection = connection;
46
52
  this.transport = transport;
47
53
  this._dcId = dcId;
@@ -51,7 +57,7 @@ class ClientAbstract {
51
57
  }
52
58
  // MaybePromise since `Client` has to deal with `Storage.set()`
53
59
  setDc(dc) {
54
- const { connection, transport, dcId } = this.transportProvider.createTransport({ dc, cdn: false });
60
+ const { connection, transport, dcId } = this.transportProvider.createTransport({ dc, cdn: this.cdn });
55
61
  this.connection = connection;
56
62
  this.transport = transport;
57
63
  this._dcId = dcId;
@@ -83,7 +83,7 @@ export declare class Client extends ClientAbstract {
83
83
  * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
84
84
  * @param params Other parameters.
85
85
  */
86
- constructor(storage?: Storage, apiId?: number, apiHash?: string, params?: ClientParams);
86
+ constructor(storage?: Storage, apiId?: number, apiHash?: string, params?: ClientParams, cdn?: boolean);
87
87
  private storageInited;
88
88
  /**
89
89
  * Sets the DC and resets the auth key stored in the session provider
@@ -118,7 +118,6 @@ export declare class Client extends ClientAbstract {
118
118
  * [2]: https://core.telegram.org/method/updates.getState
119
119
  */
120
120
  authorize(params: string | types.AuthExportedAuthorization | AuthorizeUserParams): Promise<void>;
121
- private messageProcessQueue;
122
121
  private receiveLoop;
123
122
  private pingLoop;
124
123
  /**
@@ -138,6 +137,7 @@ export declare class Client extends ClientAbstract {
138
137
  private updateApplicationMutex;
139
138
  private applyUpdateNoGap;
140
139
  private applyUpdate;
140
+ private updateProcessLock;
141
141
  private processUpdates;
142
142
  private setUpdateStateDate;
143
143
  private getLocalState;
@@ -162,4 +162,6 @@ export declare class Client extends ClientAbstract {
162
162
  }): Promise<Omit<Message, "replyToMessage">>;
163
163
  getMessages(chatId: number | string, messageIds: number[]): Promise<Omit<Message, "replyToMessage">[]>;
164
164
  getMessage(chatId: number | string, messageId: number): Promise<Omit<Message, "replyToMessage"> | null>;
165
+ private downloadInner;
166
+ download(fileId_: string): Promise<AsyncGenerator<Uint8Array, void, unknown>>;
165
167
  }
@@ -37,6 +37,7 @@ const _5_rpc_result_js_1 = require("../tl/5_rpc_result.js");
37
37
  const _6_message_js_1 = require("../tl/6_message.js"); // MTProto API message
38
38
  const _7_message_container_js_1 = require("../tl/7_message_container.js");
39
39
  const _1_storage_memory_js_1 = require("../storage/1_storage_memory.js");
40
+ const _0_file_id_js_1 = require("../types/!0_file_id.js");
40
41
  const _0_message_entity_js_1 = require("../types/0_message_entity.js");
41
42
  const _0_reply_keyboard_remove_js_1 = require("../types/0_reply_keyboard_remove.js");
42
43
  const _0_force_reply_js_1 = require("../types/0_force_reply.js");
@@ -70,8 +71,8 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
70
71
  * @param apiHash App's API hash from [my.telegram.org/apps](https://my.telegram.org/apps). Default to empty string (unset).
71
72
  * @param params Other parameters.
72
73
  */
73
- constructor(storage = new _1_storage_memory_js_1.StorageMemory(), apiId = 0, apiHash = "", params) {
74
- super(params?.transportProvider);
74
+ constructor(storage = new _1_storage_memory_js_1.StorageMemory(), apiId = 0, apiHash = "", params, cdn = false) {
75
+ super(params?.transportProvider, cdn);
75
76
  Object.defineProperty(this, "storage", {
76
77
  enumerable: true,
77
78
  configurable: true,
@@ -180,68 +181,13 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
180
181
  writable: true,
181
182
  value: false
182
183
  });
183
- Object.defineProperty(this, "messageProcessQueue", {
184
+ Object.defineProperty(this, "updateApplicationMutex", {
184
185
  enumerable: true,
185
186
  configurable: true,
186
187
  writable: true,
187
- value: (0, deps_js_1.queue)(async (message) => {
188
- let body = message.body;
189
- if (body instanceof types.GZIPPacked) {
190
- body = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(body.packedData)).readObject();
191
- }
192
- dRecv("received %s", body.constructor.name);
193
- if (body instanceof types.Updates || body instanceof types.TypeUpdate) {
194
- await this.processUpdates(body);
195
- }
196
- else if (message.body instanceof _5_rpc_result_js_1.RPCResult) {
197
- let result = message.body.result;
198
- if (result instanceof types.GZIPPacked) {
199
- result = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(result.packedData)).readObject();
200
- }
201
- if (result instanceof types.RPCError) {
202
- dRecv("RPCResult: %d %s", result.errorCode, result.errorMessage);
203
- }
204
- else {
205
- dRecv("RPCResult: %s", result.constructor.name);
206
- }
207
- if (result instanceof types.Updates || result instanceof types.TypeUpdate) {
208
- await this.processUpdates(result);
209
- }
210
- else {
211
- await this.processResult(result);
212
- }
213
- const promise = this.promises.get(message.body.messageId);
214
- if (promise) {
215
- if (result instanceof types.RPCError) {
216
- promise.reject(result);
217
- }
218
- else {
219
- promise.resolve(result);
220
- }
221
- this.promises.delete(message.body.messageId);
222
- }
223
- }
224
- else if (message.body instanceof types.Pong) {
225
- const promise = this.promises.get(message.body.msgId);
226
- if (promise) {
227
- promise.resolve(message.body);
228
- this.promises.delete(message.body.msgId);
229
- }
230
- }
231
- else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
232
- if (message.body instanceof types.BadServerSalt) {
233
- this.state.salt = message.body.newServerSalt;
234
- }
235
- const promise = this.promises.get(message.body.badMsgId);
236
- if (promise) {
237
- promise.resolve(message.body);
238
- this.promises.delete(message.body.badMsgId);
239
- }
240
- }
241
- this.toAcknowledge.add(message.id);
242
- }, 2)
188
+ value: new deps_js_1.Mutex()
243
189
  });
244
- Object.defineProperty(this, "updateApplicationMutex", {
190
+ Object.defineProperty(this, "updateProcessLock", {
245
191
  enumerable: true,
246
192
  configurable: true,
247
193
  writable: true,
@@ -544,7 +490,64 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
544
490
  }
545
491
  const messages = decrypted instanceof _7_message_container_js_1.MessageContainer ? decrypted.messages : [decrypted];
546
492
  for (const message of messages) {
547
- this.messageProcessQueue.push(message);
493
+ let body = message.body;
494
+ if (body instanceof types.GZIPPacked) {
495
+ body = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(body.packedData)).readObject();
496
+ }
497
+ dRecv("received %s", body.constructor.name);
498
+ if (body instanceof types.Updates || body instanceof types.TypeUpdate) {
499
+ this.processUpdates(body);
500
+ }
501
+ else if (message.body instanceof _5_rpc_result_js_1.RPCResult) {
502
+ let result = message.body.result;
503
+ if (result instanceof types.GZIPPacked) {
504
+ result = new _3_tl_reader_js_1.TLReader((0, deps_js_1.gunzip)(result.packedData)).readObject();
505
+ }
506
+ if (result instanceof types.RPCError) {
507
+ dRecv("RPCResult: %d %s", result.errorCode, result.errorMessage);
508
+ }
509
+ else {
510
+ dRecv("RPCResult: %s", result.constructor.name);
511
+ }
512
+ const messageId = message.body.messageId;
513
+ const resolvePromise = () => {
514
+ const promise = this.promises.get(messageId);
515
+ if (promise) {
516
+ if (result instanceof types.RPCError) {
517
+ promise.reject(result);
518
+ }
519
+ else {
520
+ promise.resolve(result);
521
+ }
522
+ this.promises.delete(messageId);
523
+ }
524
+ };
525
+ if (result instanceof types.Updates || result instanceof types.TypeUpdate) {
526
+ this.processUpdates(result).then(resolvePromise);
527
+ }
528
+ else {
529
+ await this.processResult(result);
530
+ resolvePromise();
531
+ }
532
+ }
533
+ else if (message.body instanceof types.Pong) {
534
+ const promise = this.promises.get(message.body.msgId);
535
+ if (promise) {
536
+ promise.resolve(message.body);
537
+ this.promises.delete(message.body.msgId);
538
+ }
539
+ }
540
+ else if (message.body instanceof types.BadMsgNotification || message.body instanceof types.BadServerSalt) {
541
+ if (message.body instanceof types.BadServerSalt) {
542
+ this.state.salt = message.body.newServerSalt;
543
+ }
544
+ const promise = this.promises.get(message.body.badMsgId);
545
+ if (promise) {
546
+ promise.resolve(message.body);
547
+ this.promises.delete(message.body.badMsgId);
548
+ }
549
+ }
550
+ this.toAcknowledge.add(message.id);
548
551
  }
549
552
  }
550
553
  }
@@ -637,18 +640,20 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
637
640
  (update instanceof types.UpdateShortMessage) ||
638
641
  (update instanceof types.UpdateShortChatMessage) ||
639
642
  (update instanceof types.UpdateShortSentMessage)) {
640
- const localState = await this.getLocalState();
641
- if (localState.pts + update.ptsCount > update.pts) {
642
- // the update is already applied
643
- return;
644
- }
645
- else if (localState.pts + update.ptsCount < update.pts) {
646
- // there is an update gap that needs to be filled
647
- throw UPDATE_GAP;
643
+ if (update.pts != 0 && update.ptsCount != 0) {
644
+ const localState = await this.getLocalState();
645
+ if (localState.pts + update.ptsCount > update.pts) {
646
+ // the update is already applied
647
+ return;
648
+ }
649
+ else if (localState.pts + update.ptsCount < update.pts) {
650
+ // there is an update gap that needs to be filled
651
+ throw UPDATE_GAP;
652
+ }
653
+ localState.pts = update.pts;
654
+ d("applied update with pts %d", update.pts);
655
+ await this.storage.setState(localState);
648
656
  }
649
- localState.pts = update.pts;
650
- d("applied update with pts %d", update.pts);
651
- await this.storage.setState(localState);
652
657
  }
653
658
  else if (usePts &&
654
659
  ((update instanceof types.UpdateNewChannelMessage) ||
@@ -748,7 +753,8 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
748
753
  }
749
754
  }
750
755
  }
751
- async processUpdates(updates) {
756
+ async processUpdates(updates, release) {
757
+ release ??= await this.updateProcessLock.acquire();
752
758
  try {
753
759
  if (updates instanceof types.TypeUpdates) {
754
760
  if (updates instanceof types.Updates) {
@@ -756,7 +762,7 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
756
762
  await this.processUsers(updates.users);
757
763
  await this.setUpdateStateDate(updates.date);
758
764
  for (const update of updates.updates) {
759
- await this.processUpdates(update);
765
+ await this.processUpdates(update, release);
760
766
  }
761
767
  }
762
768
  else if (updates instanceof types.UpdateShortMessage ||
@@ -773,7 +779,7 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
773
779
  await this.processChats(updates.chats);
774
780
  await this.processUsers(updates.users);
775
781
  for (const update of updates.updates) {
776
- await this.processUpdates(update);
782
+ await this.processUpdates(update, release);
777
783
  }
778
784
  }
779
785
  }
@@ -802,6 +808,9 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
802
808
  catch (err) {
803
809
  d("error processing updates: %O", err);
804
810
  }
811
+ finally {
812
+ release();
813
+ }
805
814
  }
806
815
  async setUpdateStateDate(date) {
807
816
  const release = await this.updateApplicationMutex.acquire();
@@ -844,6 +853,7 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
844
853
  await this.applyUpdateNoGap(update);
845
854
  }
846
855
  if (difference instanceof types.UpdatesDifference) {
856
+ await this.storage.setState(difference.state[_1_tl_object_js_1.as](types.UpdatesState));
847
857
  dGap("recovered from update gap");
848
858
  break;
849
859
  }
@@ -1137,5 +1147,69 @@ class Client extends _1_client_abstract_js_1.ClientAbstract {
1137
1147
  const messages = await this.getMessages(chatId, [messageId]);
1138
1148
  return messages[0] ?? null;
1139
1149
  }
1150
+ async *downloadInner(location, dcId) {
1151
+ let client = null;
1152
+ if (dcId != undefined && dcId != this.dcId) {
1153
+ const exportedAuth = await this.invoke(new functions.AuthExportAuthorization({ dcId }));
1154
+ client = new Client(new _1_storage_memory_js_1.StorageMemory(), this.apiId, this.apiHash, {
1155
+ transportProvider: this.transportProvider,
1156
+ appVersion: this.appVersion,
1157
+ deviceModel: this.deviceModel,
1158
+ langCode: this.langCode,
1159
+ langPack: this.langPack,
1160
+ systemLangCode: this.systemLangCode,
1161
+ systemVersion: this.systemVersion,
1162
+ }, true);
1163
+ let dc = String(dcId);
1164
+ if (this.dcId < 0) {
1165
+ dc += "-test";
1166
+ }
1167
+ await client.setDc(dc);
1168
+ await client.connect();
1169
+ await client.authorize(exportedAuth);
1170
+ }
1171
+ const limit = 1024 * 1024;
1172
+ let offset = 0n;
1173
+ while (true) {
1174
+ const file = await (client ?? this).invoke(new functions.UploadGetFile({ location, offset, limit }));
1175
+ if (file instanceof types.UploadFile) {
1176
+ yield file.bytes;
1177
+ if (file.bytes.length < limit) {
1178
+ break;
1179
+ }
1180
+ else {
1181
+ offset += BigInt(file.bytes.length);
1182
+ }
1183
+ }
1184
+ else {
1185
+ (0, _0_control_js_1.UNREACHABLE)();
1186
+ }
1187
+ }
1188
+ }
1189
+ async download(fileId_) {
1190
+ const fileId = _0_file_id_js_1.FileID.decode(fileId_);
1191
+ switch (fileId.fileType) {
1192
+ case _0_file_id_js_1.FileType.ChatPhoto: {
1193
+ const big = fileId.params.thumbnailSource == _0_file_id_js_1.ThumbnailSource.ChatPhotoBig;
1194
+ const peer = await this.getInputPeer(fileId.params.chatId);
1195
+ const location = new types.InputPeerPhotoFileLocation({ big: big ? true : undefined, peer, photoId: fileId.params.mediaId });
1196
+ return this.downloadInner(location);
1197
+ }
1198
+ case _0_file_id_js_1.FileType.Photo: {
1199
+ if (fileId.params.mediaId == undefined || fileId.params.accessHash == undefined || fileId.params.fileReference == undefined || fileId.params.thumbnailSize == undefined) {
1200
+ (0, _0_control_js_1.UNREACHABLE)();
1201
+ }
1202
+ const location = new types.InputPhotoFileLocation({
1203
+ id: fileId.params.mediaId,
1204
+ accessHash: fileId.params.accessHash,
1205
+ fileReference: fileId.params.fileReference,
1206
+ thumbSize: fileId.params.thumbnailSize,
1207
+ });
1208
+ return this.downloadInner(location);
1209
+ }
1210
+ default:
1211
+ (0, _0_control_js_1.UNREACHABLE)();
1212
+ }
1213
+ }
1140
1214
  }
1141
1215
  exports.Client = Client;
@@ -4,7 +4,7 @@ export declare const publicKeys: Map<bigint, [bigint, bigint]>;
4
4
  export declare const VECTOR_CONSTRUCTOR = 481674261;
5
5
  export declare const DEFAULT_INITIAL_DC: DC;
6
6
  export declare const LAYER = 158;
7
- export declare const DEFAULT_APP_VERSION = "MTKruto 0.0.910";
7
+ export declare const DEFAULT_APP_VERSION = "MTKruto 0.0.921";
8
8
  export declare const DEFAULT_DEVICE_MODEL: string;
9
9
  export declare const DEFAULT_LANG_CODE: string;
10
10
  export declare const DEFAULT_LANG_PACK = "";
@@ -88,7 +88,7 @@ exports.publicKeys = new Map([
88
88
  exports.VECTOR_CONSTRUCTOR = 0x1CB5C415;
89
89
  exports.DEFAULT_INITIAL_DC = "2-test";
90
90
  exports.LAYER = 158;
91
- exports.DEFAULT_APP_VERSION = "MTKruto 0.0.910";
91
+ exports.DEFAULT_APP_VERSION = "MTKruto 0.0.921";
92
92
  // @ts-ignore: lib
93
93
  exports.DEFAULT_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;
94
94
  exports.DEFAULT_LANG_CODE = typeof navigator === "undefined" ? "en" : navigator.language.split("-")[0];
package/script/deps.d.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  export * from "./deps/deno.land/std@0.190.0/testing/asserts.js";
2
2
  export { ctr256Decrypt, ctr256Encrypt, factorize, ige256Decrypt, ige256Encrypt, init as initTgCrypto } from "./deps/deno.land/x/tgcrypto@0.1.3/mod.js";
3
3
  export { gunzip, gzip } from "./deps/raw.githubusercontent.com/MTKruto/compress/master/gzip/gzip.js";
4
- export { Mutex } from "async-mutex";
4
+ export { Mutex, type MutexInterface } from "async-mutex";
5
5
  export { Parser } from "./deps/deno.land/x/html_parser@v0.1.3/src/mod.js";
6
6
  import { debug as debug_ } from "./deps/raw.githubusercontent.com/MTKruto/debug/master/mod.js";
7
7
  export declare const debug: typeof debug_;
8
- export { queue } from "./deps/deno.land/x/q@v0.0.1/mod.js";
9
8
  export { decode as base64Decode, encode as base64Encode } from "./deps/deno.land/std@0.190.0/encoding/base64.js";
package/script/deps.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.base64Encode = exports.base64Decode = exports.queue = exports.debug = exports.Parser = exports.Mutex = exports.gzip = exports.gunzip = exports.initTgCrypto = exports.ige256Encrypt = exports.ige256Decrypt = exports.factorize = exports.ctr256Encrypt = exports.ctr256Decrypt = void 0;
17
+ exports.base64Encode = exports.base64Decode = exports.debug = exports.Parser = exports.Mutex = exports.gzip = exports.gunzip = exports.initTgCrypto = exports.ige256Encrypt = exports.ige256Decrypt = exports.factorize = exports.ctr256Encrypt = exports.ctr256Decrypt = void 0;
18
18
  __exportStar(require("./deps/deno.land/std@0.190.0/testing/asserts.js"), exports);
19
19
  var mod_js_1 = require("./deps/deno.land/x/tgcrypto@0.1.3/mod.js");
20
20
  Object.defineProperty(exports, "ctr256Decrypt", { enumerable: true, get: function () { return mod_js_1.ctr256Decrypt; } });
@@ -33,8 +33,6 @@ Object.defineProperty(exports, "Parser", { enumerable: true, get: function () {
33
33
  const mod_js_3 = require("./deps/raw.githubusercontent.com/MTKruto/debug/master/mod.js");
34
34
  const debug = (v) => (0, mod_js_3.debug)(`mtkruto/${v}`);
35
35
  exports.debug = debug;
36
- var mod_js_4 = require("./deps/deno.land/x/q@v0.0.1/mod.js");
37
- Object.defineProperty(exports, "queue", { enumerable: true, get: function () { return mod_js_4.queue; } });
38
36
  var base64_js_1 = require("./deps/deno.land/std@0.190.0/encoding/base64.js");
39
37
  Object.defineProperty(exports, "base64Decode", { enumerable: true, get: function () { return base64_js_1.decode; } });
40
38
  Object.defineProperty(exports, "base64Encode", { enumerable: true, get: function () { return base64_js_1.encode; } });
@@ -36,19 +36,19 @@ interface FileIDParams {
36
36
  thumbnailSize?: string;
37
37
  secret?: bigint;
38
38
  localId?: number;
39
- chatId?: bigint;
39
+ chatId?: number;
40
40
  chatAccessHash?: bigint;
41
41
  stickerSetId?: bigint;
42
42
  stickerSetAccessHash?: bigint;
43
43
  }
44
44
  export declare class FileID {
45
- private readonly fileType;
46
- private readonly dcId;
47
- private readonly params;
45
+ readonly fileType: FileType;
46
+ readonly dcId: number;
47
+ readonly params: FileIDParams;
48
48
  static MAJOR: number;
49
49
  static MINOR: number;
50
- private readonly major;
51
- private readonly minor;
50
+ readonly major: number;
51
+ readonly minor: number;
52
52
  constructor(major: number | null | undefined, minor: number | null | undefined, fileType: FileType, dcId: number, params: FileIDParams);
53
53
  static decode(fileId: string): FileID;
54
54
  encode(major?: number, minor?: number): string;