@mtkruto/browser 0.119.0 → 0.120.0

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 (128) hide show
  1. package/README.md +1 -1
  2. package/esm/0_errors.d.ts.map +1 -1
  3. package/esm/0_errors.js +9 -31
  4. package/esm/3_errors.js +2 -12
  5. package/esm/4_errors.js +2 -12
  6. package/esm/_dnt.polyfills.d.ts +0 -99
  7. package/esm/_dnt.polyfills.d.ts.map +1 -1
  8. package/esm/_dnt.polyfills.js +1 -127
  9. package/esm/client/0_abortable_loop.js +26 -39
  10. package/esm/client/0_storage_operations.js +179 -218
  11. package/esm/client/1_client_plain.js +4 -22
  12. package/esm/client/2_account_manager.js +140 -149
  13. package/esm/client/2_bot_info_manager.js +26 -38
  14. package/esm/client/2_business_connection_manager.js +10 -23
  15. package/esm/client/2_client_encrypted.js +198 -215
  16. package/esm/client/2_file_manager.js +255 -262
  17. package/esm/client/2_network_statistics_manager.js +31 -44
  18. package/esm/client/2_payment_manager.js +7 -20
  19. package/esm/client/2_reaction_manager.js +7 -20
  20. package/esm/client/2_translations_manager.js +101 -111
  21. package/esm/client/2_update_manager.js +750 -745
  22. package/esm/client/3_client_encrypted_pool.js +10 -26
  23. package/esm/client/3_message_manager.js +503 -508
  24. package/esm/client/3_video_chat_manager.js +57 -68
  25. package/esm/client/4_callback_query_manager.js +18 -30
  26. package/esm/client/4_chat_list_manager.js +140 -146
  27. package/esm/client/4_chat_manager.js +161 -169
  28. package/esm/client/4_checklist_manager.js +26 -39
  29. package/esm/client/4_context.js +244 -259
  30. package/esm/client/4_forum_manager.js +67 -73
  31. package/esm/client/4_gift_manager.js +22 -35
  32. package/esm/client/4_inline_query_manager.js +16 -28
  33. package/esm/client/4_link_preview_manager.js +6 -19
  34. package/esm/client/4_poll_manager.js +44 -57
  35. package/esm/client/4_story_manager.js +41 -53
  36. package/esm/client/5_composer.js +13 -26
  37. package/esm/client/6_client.js +866 -896
  38. package/esm/client/6_client_dispatcher.js +308 -325
  39. package/esm/client/7_client_worker.js +16 -29
  40. package/esm/connection/1_connection_tcp.js +55 -82
  41. package/esm/connection/1_connection_web_socket.js +75 -91
  42. package/esm/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
  43. package/esm/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
  44. package/esm/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
  45. package/esm/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
  46. package/esm/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
  47. package/esm/session/0_session_state.js +12 -38
  48. package/esm/session/1_session.js +49 -72
  49. package/esm/session/2_session_encrypted.js +422 -420
  50. package/esm/storage/2_storage_indexed_db.js +26 -44
  51. package/esm/storage/2_storage_local_storage.js +3 -16
  52. package/esm/storage/2_storage_memory.js +24 -41
  53. package/esm/storage/2_storage_session_storage.js +3 -16
  54. package/esm/tl/1_tl_reader.d.ts +1 -1
  55. package/esm/tl/1_tl_reader.d.ts.map +1 -1
  56. package/esm/tl/1_tl_reader.js +95 -103
  57. package/esm/tl/1_tl_writer.js +169 -178
  58. package/esm/transport/0_transport.js +1 -8
  59. package/esm/transport/1_transport_abridged.js +11 -24
  60. package/esm/transport/1_transport_intermediate.js +10 -23
  61. package/esm/utilities/0_mutex.js +4 -19
  62. package/esm/utilities/0_part_stream.js +11 -25
  63. package/esm/utilities/1_crypto.js +42 -53
  64. package/esm/utilities/2_queue.js +29 -47
  65. package/package.json +1 -1
  66. package/script/0_errors.d.ts.map +1 -1
  67. package/script/0_errors.js +9 -31
  68. package/script/3_errors.js +2 -12
  69. package/script/4_errors.js +2 -12
  70. package/script/_dnt.polyfills.d.ts +0 -99
  71. package/script/_dnt.polyfills.d.ts.map +1 -1
  72. package/script/_dnt.polyfills.js +0 -128
  73. package/script/client/0_abortable_loop.js +27 -40
  74. package/script/client/0_storage_operations.js +179 -218
  75. package/script/client/1_client_plain.js +4 -22
  76. package/script/client/2_account_manager.js +140 -149
  77. package/script/client/2_bot_info_manager.js +26 -38
  78. package/script/client/2_business_connection_manager.js +10 -23
  79. package/script/client/2_client_encrypted.js +199 -216
  80. package/script/client/2_file_manager.js +255 -262
  81. package/script/client/2_network_statistics_manager.js +32 -45
  82. package/script/client/2_payment_manager.js +7 -20
  83. package/script/client/2_reaction_manager.js +7 -20
  84. package/script/client/2_translations_manager.js +102 -112
  85. package/script/client/2_update_manager.js +750 -745
  86. package/script/client/3_client_encrypted_pool.js +10 -26
  87. package/script/client/3_message_manager.js +503 -508
  88. package/script/client/3_video_chat_manager.js +57 -68
  89. package/script/client/4_callback_query_manager.js +18 -30
  90. package/script/client/4_chat_list_manager.js +140 -146
  91. package/script/client/4_chat_manager.js +161 -169
  92. package/script/client/4_checklist_manager.js +26 -39
  93. package/script/client/4_context.js +244 -259
  94. package/script/client/4_forum_manager.js +67 -73
  95. package/script/client/4_gift_manager.js +22 -35
  96. package/script/client/4_inline_query_manager.js +16 -28
  97. package/script/client/4_link_preview_manager.js +6 -19
  98. package/script/client/4_poll_manager.js +44 -57
  99. package/script/client/4_story_manager.js +41 -53
  100. package/script/client/5_composer.js +13 -26
  101. package/script/client/6_client.js +866 -896
  102. package/script/client/6_client_dispatcher.js +308 -325
  103. package/script/client/7_client_worker.js +16 -29
  104. package/script/connection/1_connection_tcp.js +55 -82
  105. package/script/connection/1_connection_web_socket.js +75 -91
  106. package/script/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
  107. package/script/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
  108. package/script/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
  109. package/script/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
  110. package/script/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
  111. package/script/session/0_session_state.js +12 -38
  112. package/script/session/1_session.js +49 -72
  113. package/script/session/2_session_encrypted.js +423 -421
  114. package/script/storage/2_storage_indexed_db.js +26 -44
  115. package/script/storage/2_storage_local_storage.js +3 -16
  116. package/script/storage/2_storage_memory.js +24 -41
  117. package/script/storage/2_storage_session_storage.js +3 -16
  118. package/script/tl/1_tl_reader.d.ts +1 -1
  119. package/script/tl/1_tl_reader.d.ts.map +1 -1
  120. package/script/tl/1_tl_reader.js +96 -104
  121. package/script/tl/1_tl_writer.js +170 -179
  122. package/script/transport/0_transport.js +1 -8
  123. package/script/transport/1_transport_abridged.js +11 -24
  124. package/script/transport/1_transport_intermediate.js +10 -23
  125. package/script/utilities/0_mutex.js +4 -19
  126. package/script/utilities/0_part_stream.js +11 -25
  127. package/script/utilities/1_crypto.js +43 -54
  128. package/script/utilities/2_queue.js +30 -48
@@ -18,18 +18,6 @@
18
18
  * You should have received a copy of the GNU Lesser General Public License
19
19
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20
20
  */
21
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
22
- if (kind === "m") throw new TypeError("Private method is not writable");
23
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
24
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
25
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
26
- };
27
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
28
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
29
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
30
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
31
- };
32
- var _SessionEncrypted_instances, _a, _SessionEncrypted_TGCRYPTO_INITED, _SessionEncrypted_id, _SessionEncrypted_L, _SessionEncrypted_LsendLoop, _SessionEncrypted_LreceiveLoop, _SessionEncrypted_LpingLoop, _SessionEncrypted_authKey, _SessionEncrypted_authKeyId, _SessionEncrypted_sentMessages, _SessionEncrypted_pendingMessages, _SessionEncrypted_containers, _SessionEncrypted_pendingPings, _SessionEncrypted_toAcknowledge, _SessionEncrypted_pendingAcks, _SessionEncrypted_assertNotDisconnected, _SessionEncrypted_invalidateSession, _SessionEncrypted_rejectAllPending, _SessionEncrypted_onMessageFailed, _SessionEncrypted_setServerSalt, _SessionEncrypted_receive, _SessionEncrypted_encryptMessage, _SessionEncrypted_decryptMessage, _SessionEncrypted_awakeSendLoop, _SessionEncrypted_sendLoop, _SessionEncrypted_sendLoopBody, _SessionEncrypted_receiveLoop, _SessionEncrypted_receiveLoopBody, _SessionEncrypted_onMessage, _SessionEncrypted_onRpcResult, _SessionEncrypted_onMsgDetailedInfo, _SessionEncrypted_onMsgNewDetailedInfo, _SessionEncrypted_onBadMsgNotification, _SessionEncrypted_onBadServerSalt, _SessionEncrypted_onPong, _SessionEncrypted_onNewSessionCreated, _SessionEncrypted_onMessageContainer, _SessionEncrypted_pingInterval, _SessionEncrypted_pingLoop, _SessionEncrypted_timeElapsed, _SessionEncrypted_pingLoopBody, _SessionEncrypted_sendPingDelayDisconnect, _SessionEncrypted_resendPendingPing;
33
21
  Object.defineProperty(exports, "__esModule", { value: true });
34
22
  exports.SessionEncrypted = void 0;
35
23
  const _0_deps_js_1 = require("../0_deps.js");
@@ -46,466 +34,480 @@ const GZIP_PACKED = 0x3072CFA1;
46
34
  const RPC_RESULT = 0xF35C6D01;
47
35
  const RPC_ERROR = _2_tl_js_1.Mtproto.schema.definitions["rpc_error"][0];
48
36
  class SessionEncrypted extends _1_session_js_1.Session {
37
+ static #TGCRYPTO_INITED = false;
38
+ #id = (0, _1_utilities_js_1.getRandomId)();
39
+ handlers = {};
40
+ #L;
41
+ #LsendLoop;
42
+ #LreceiveLoop;
43
+ #LpingLoop;
44
+ #authKey = new Uint8Array();
45
+ #authKeyId = 0n;
46
+ #sentMessages = new Set();
47
+ #pendingMessages = new Array();
48
+ #containers = new _0_deps_js_1.LruCache(20_000);
49
+ #pendingPings = new Map();
50
+ #toAcknowledge = new Array();
51
+ #pendingAcks = new _0_deps_js_1.LruCache(100);
49
52
  constructor(dc, params) {
50
53
  super(dc, params);
51
- _SessionEncrypted_instances.add(this);
52
- _SessionEncrypted_id.set(this, (0, _1_utilities_js_1.getRandomId)());
53
- Object.defineProperty(this, "handlers", {
54
- enumerable: true,
55
- configurable: true,
56
- writable: true,
57
- value: {}
58
- });
59
- _SessionEncrypted_L.set(this, void 0);
60
- _SessionEncrypted_LsendLoop.set(this, void 0);
61
- _SessionEncrypted_LreceiveLoop.set(this, void 0);
62
- _SessionEncrypted_LpingLoop.set(this, void 0);
63
- _SessionEncrypted_authKey.set(this, new Uint8Array());
64
- _SessionEncrypted_authKeyId.set(this, 0n);
65
- _SessionEncrypted_sentMessages.set(this, new Set());
66
- _SessionEncrypted_pendingMessages.set(this, new Array());
67
- _SessionEncrypted_containers.set(this, new _0_deps_js_1.LruCache(20_000));
68
- _SessionEncrypted_pendingPings.set(this, new Map());
69
- _SessionEncrypted_toAcknowledge.set(this, new Array());
70
- _SessionEncrypted_pendingAcks.set(this, new _0_deps_js_1.LruCache(100));
71
- //// SEND LOOP ////
72
- _SessionEncrypted_awakeSendLoop.set(this, void 0);
73
- _SessionEncrypted_sendLoop.set(this, new _0_abortable_loop_js_1.AbortableLoop(__classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_sendLoopBody).bind(this), (err) => {
74
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").error("unhandled receive loop error:", err);
75
- }));
76
- //// RECEIVE LOOP ////
77
- _SessionEncrypted_receiveLoop.set(this, new _0_abortable_loop_js_1.AbortableLoop(__classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_receiveLoopBody).bind(this), (err) => {
78
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").error("unhandled receive loop error:", err);
79
- }));
80
- //// PING LOOP ////
81
- _SessionEncrypted_pingInterval.set(this, 56 * _0_deps_js_1.SECOND);
82
- _SessionEncrypted_pingLoop.set(this, new _0_abortable_loop_js_1.AbortableLoop(__classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_pingLoopBody).bind(this), (_, err) => {
83
- __classPrivateFieldGet(this, _SessionEncrypted_LpingLoop, "f").error(err);
84
- }));
85
- _SessionEncrypted_timeElapsed.set(this, 0);
86
- const L = __classPrivateFieldSet(this, _SessionEncrypted_L, (0, _1_utilities_js_1.getLogger)("SessionEncrypted").client(id++), "f");
87
- __classPrivateFieldSet(this, _SessionEncrypted_LsendLoop, L.branch("sendLoop"), "f");
88
- __classPrivateFieldSet(this, _SessionEncrypted_LreceiveLoop, L.branch("receiveLoop"), "f");
89
- __classPrivateFieldSet(this, _SessionEncrypted_LpingLoop, L.branch("pingLoop"), "f");
54
+ const L = this.#L = (0, _1_utilities_js_1.getLogger)("SessionEncrypted").client(id++);
55
+ this.#LsendLoop = L.branch("sendLoop");
56
+ this.#LreceiveLoop = L.branch("receiveLoop");
57
+ this.#LpingLoop = L.branch("pingLoop");
90
58
  }
91
59
  async setAuthKey(key) {
92
60
  const hash = await (0, _1_utilities_js_1.sha1)(key);
93
- __classPrivateFieldSet(this, _SessionEncrypted_authKeyId, (0, _1_utilities_js_1.intFromBytes)(hash.slice(-8)), "f");
94
- __classPrivateFieldSet(this, _SessionEncrypted_authKey, key, "f");
61
+ this.#authKeyId = (0, _1_utilities_js_1.intFromBytes)(hash.slice(-8));
62
+ this.#authKey = key;
95
63
  }
96
64
  get authKey() {
97
- return __classPrivateFieldGet(this, _SessionEncrypted_authKey, "f");
65
+ return this.#authKey;
98
66
  }
99
67
  async connect() {
100
68
  if (!this.isConnected) {
101
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_rejectAllPending).call(this, new _0_errors_js_1.ConnectionError("The connection was closed."));
69
+ this.#rejectAllPending(new _0_errors_js_1.ConnectionError("The connection was closed."));
102
70
  }
103
71
  await super.connect();
104
- if (!__classPrivateFieldGet(_a, _a, "f", _SessionEncrypted_TGCRYPTO_INITED)) {
72
+ if (!SessionEncrypted.#TGCRYPTO_INITED) {
105
73
  await (0, _0_deps_js_1.initTgCrypto)();
106
- __classPrivateFieldSet(_a, _a, true, "f", _SessionEncrypted_TGCRYPTO_INITED);
74
+ SessionEncrypted.#TGCRYPTO_INITED = true;
107
75
  }
108
- __classPrivateFieldGet(this, _SessionEncrypted_receiveLoop, "f").start();
109
- __classPrivateFieldGet(this, _SessionEncrypted_sendLoop, "f").start();
110
- __classPrivateFieldGet(this, _SessionEncrypted_pingLoop, "f").start();
111
- __classPrivateFieldGet(this, _SessionEncrypted_awakeSendLoop, "f")?.call(this);
76
+ this.#receiveLoop.start();
77
+ this.#sendLoop.start();
78
+ this.#pingLoop.start();
79
+ this.#awakeSendLoop?.();
112
80
  }
113
81
  disconnect() {
114
82
  super.disconnect();
115
83
  this.state.reset();
116
- __classPrivateFieldSet(this, _SessionEncrypted_id, (0, _1_utilities_js_1.getRandomId)(), "f");
117
- __classPrivateFieldGet(this, _SessionEncrypted_pingLoop, "f").abort();
118
- __classPrivateFieldGet(this, _SessionEncrypted_awakeSendLoop, "f")?.call(this);
119
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_rejectAllPending).call(this, new _0_errors_js_1.ConnectionError("The connection was disconnected."));
84
+ this.#id = (0, _1_utilities_js_1.getRandomId)();
85
+ this.#pingLoop.abort();
86
+ this.#awakeSendLoop?.();
87
+ this.#rejectAllPending(new _0_errors_js_1.ConnectionError("The connection was disconnected."));
88
+ }
89
+ #assertNotDisconnected() {
90
+ if (this.isDisconnected) {
91
+ throw new _0_errors_js_1.ConnectionError("The connection was disconnected.");
92
+ }
93
+ }
94
+ async #invalidateSession(reason) {
95
+ this.#L.debug("invalidating session because of", reason);
96
+ this.#id = (0, _1_utilities_js_1.getRandomId)();
97
+ this.state.reset();
98
+ this.disconnect();
99
+ await this.connect();
100
+ this.#rejectAllPending(new _0_session_error_js_1.SessionError("The session was invalidated."));
101
+ }
102
+ #rejectAllPending(reason) {
103
+ for (const id of this.#sentMessages) {
104
+ this.#onMessageFailed(id, reason);
105
+ }
106
+ for (const pendingPing of this.#pendingPings.values()) {
107
+ pendingPing.promiseWithResolvers.reject(reason);
108
+ }
109
+ this.#sentMessages.clear();
110
+ this.#pendingPings.clear();
111
+ this.#containers.clear();
112
+ }
113
+ #onMessageFailed(id, reason) {
114
+ this.#sentMessages.delete(id);
115
+ const pendingContainer = this.#containers.get(id);
116
+ if (pendingContainer) {
117
+ for (const id of pendingContainer) {
118
+ this.#onMessageFailed(id, reason);
119
+ }
120
+ this.#containers.delete(id);
121
+ return;
122
+ }
123
+ const pendingAck = this.#pendingAcks.get(id);
124
+ if (pendingAck) {
125
+ for (const id of pendingAck) {
126
+ this.#toAcknowledge.push(id);
127
+ }
128
+ this.#pendingAcks.delete(id);
129
+ return;
130
+ }
131
+ const pendingPing = this.#pendingPings.get(id);
132
+ if (pendingPing) {
133
+ this.#pendingPings.delete(id);
134
+ if (reason instanceof _0_session_error_js_1.SessionError) {
135
+ (0, _1_utilities_js_1.drop)(this.#resendPendingPing(pendingPing));
136
+ }
137
+ else {
138
+ pendingPing.promiseWithResolvers.reject(reason);
139
+ }
140
+ return;
141
+ }
142
+ // message was not sent by us
143
+ this.handlers.onMessageFailed?.(id, reason);
144
+ }
145
+ #setServerSalt(newServerSalt) {
146
+ this.state.serverSalt = newServerSalt;
147
+ this.handlers.onNewServerSalt?.(newServerSalt);
120
148
  }
121
149
  async send(body) {
122
150
  if (!this.isDisconnected && !this.isConnected) {
123
151
  await super.waitUntilConnected();
124
152
  }
125
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_assertNotDisconnected).call(this);
153
+ this.#assertNotDisconnected();
126
154
  const pendingMessage = { body, promiseWithResolvers: Promise.withResolvers() };
127
- __classPrivateFieldGet(this, _SessionEncrypted_pendingMessages, "f").push(pendingMessage);
128
- __classPrivateFieldGet(this, _SessionEncrypted_awakeSendLoop, "f")?.call(this);
155
+ this.#pendingMessages.push(pendingMessage);
156
+ this.#awakeSendLoop?.();
129
157
  return await pendingMessage.promiseWithResolvers.promise;
130
158
  }
131
- }
132
- exports.SessionEncrypted = SessionEncrypted;
133
- _a = SessionEncrypted, _SessionEncrypted_id = new WeakMap(), _SessionEncrypted_L = new WeakMap(), _SessionEncrypted_LsendLoop = new WeakMap(), _SessionEncrypted_LreceiveLoop = new WeakMap(), _SessionEncrypted_LpingLoop = new WeakMap(), _SessionEncrypted_authKey = new WeakMap(), _SessionEncrypted_authKeyId = new WeakMap(), _SessionEncrypted_sentMessages = new WeakMap(), _SessionEncrypted_pendingMessages = new WeakMap(), _SessionEncrypted_containers = new WeakMap(), _SessionEncrypted_pendingPings = new WeakMap(), _SessionEncrypted_toAcknowledge = new WeakMap(), _SessionEncrypted_pendingAcks = new WeakMap(), _SessionEncrypted_awakeSendLoop = new WeakMap(), _SessionEncrypted_sendLoop = new WeakMap(), _SessionEncrypted_receiveLoop = new WeakMap(), _SessionEncrypted_pingInterval = new WeakMap(), _SessionEncrypted_pingLoop = new WeakMap(), _SessionEncrypted_timeElapsed = new WeakMap(), _SessionEncrypted_instances = new WeakSet(), _SessionEncrypted_assertNotDisconnected = function _SessionEncrypted_assertNotDisconnected() {
134
- if (this.isDisconnected) {
135
- throw new _0_errors_js_1.ConnectionError("The connection was disconnected.");
136
- }
137
- }, _SessionEncrypted_invalidateSession = async function _SessionEncrypted_invalidateSession(reason) {
138
- __classPrivateFieldGet(this, _SessionEncrypted_L, "f").debug("invalidating session because of", reason);
139
- __classPrivateFieldSet(this, _SessionEncrypted_id, (0, _1_utilities_js_1.getRandomId)(), "f");
140
- this.state.reset();
141
- this.disconnect();
142
- await this.connect();
143
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_rejectAllPending).call(this, new _0_session_error_js_1.SessionError("The session was invalidated."));
144
- }, _SessionEncrypted_rejectAllPending = function _SessionEncrypted_rejectAllPending(reason) {
145
- for (const id of __classPrivateFieldGet(this, _SessionEncrypted_sentMessages, "f")) {
146
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageFailed).call(this, id, reason);
147
- }
148
- for (const pendingPing of __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").values()) {
149
- pendingPing.promiseWithResolvers.reject(reason);
150
- }
151
- __classPrivateFieldGet(this, _SessionEncrypted_sentMessages, "f").clear();
152
- __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").clear();
153
- __classPrivateFieldGet(this, _SessionEncrypted_containers, "f").clear();
154
- }, _SessionEncrypted_onMessageFailed = function _SessionEncrypted_onMessageFailed(id, reason) {
155
- __classPrivateFieldGet(this, _SessionEncrypted_sentMessages, "f").delete(id);
156
- const pendingContainer = __classPrivateFieldGet(this, _SessionEncrypted_containers, "f").get(id);
157
- if (pendingContainer) {
158
- for (const id of pendingContainer) {
159
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageFailed).call(this, id, reason);
160
- }
161
- __classPrivateFieldGet(this, _SessionEncrypted_containers, "f").delete(id);
162
- return;
163
- }
164
- const pendingAck = __classPrivateFieldGet(this, _SessionEncrypted_pendingAcks, "f").get(id);
165
- if (pendingAck) {
166
- for (const id of pendingAck) {
167
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(id);
159
+ async #receive() {
160
+ this.#assertNotDisconnected();
161
+ const buffer = await this.transport.transport.receive();
162
+ if (buffer.length === 4) {
163
+ const int = (0, _1_utilities_js_1.intFromBytes)(buffer);
164
+ throw new _0_errors_js_1.TransportError(Number(int));
168
165
  }
169
- __classPrivateFieldGet(this, _SessionEncrypted_pendingAcks, "f").delete(id);
170
- return;
171
- }
172
- const pendingPing = __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").get(id);
173
- if (pendingPing) {
174
- __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").delete(id);
175
- if (reason instanceof _0_session_error_js_1.SessionError) {
176
- (0, _1_utilities_js_1.drop)(__classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_resendPendingPing).call(this, pendingPing));
166
+ try {
167
+ const decrypted = await this.#decryptMessage(buffer);
168
+ this.#L.in(decrypted);
169
+ return decrypted;
177
170
  }
178
- else {
179
- pendingPing.promiseWithResolvers.reject(reason);
171
+ catch (err) {
172
+ this.#L.error("decryption error:", err);
173
+ await this.#invalidateSession("decryption error");
174
+ throw err;
180
175
  }
181
- return;
182
- }
183
- // message was not sent by us
184
- this.handlers.onMessageFailed?.(id, reason);
185
- }, _SessionEncrypted_setServerSalt = function _SessionEncrypted_setServerSalt(newServerSalt) {
186
- this.state.serverSalt = newServerSalt;
187
- this.handlers.onNewServerSalt?.(newServerSalt);
188
- }, _SessionEncrypted_receive = async function _SessionEncrypted_receive() {
189
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_assertNotDisconnected).call(this);
190
- const buffer = await this.transport.transport.receive();
191
- if (buffer.length === 4) {
192
- const int = (0, _1_utilities_js_1.intFromBytes)(buffer);
193
- throw new _0_errors_js_1.TransportError(Number(int));
194
- }
195
- try {
196
- const decrypted = await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_decryptMessage).call(this, buffer);
197
- __classPrivateFieldGet(this, _SessionEncrypted_L, "f").in(decrypted);
198
- return decrypted;
199
176
  }
200
- catch (err) {
201
- __classPrivateFieldGet(this, _SessionEncrypted_L, "f").error("decryption error:", err);
202
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_invalidateSession).call(this, "decryption error");
203
- throw err;
204
- }
205
- }, _SessionEncrypted_encryptMessage = async function _SessionEncrypted_encryptMessage(message) {
206
- const payloadWriter = new _1_tl_writer_js_1.TLWriter();
207
- payloadWriter.writeInt64(this.state.serverSalt);
208
- payloadWriter.writeInt64(__classPrivateFieldGet(this, _SessionEncrypted_id, "f"));
209
- payloadWriter.write(await (0, _2_tl_js_1.serializeMessage)(message));
210
- payloadWriter.write(new Uint8Array((0, _1_utilities_js_1.mod)(-(payloadWriter.buffer.length + 12), 16) + 12));
211
- const payload = payloadWriter.buffer;
212
- const messageKey = (await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([__classPrivateFieldGet(this, _SessionEncrypted_authKey, "f").subarray(88, 120), payload]))).subarray(8, 24);
213
- const a = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([messageKey, __classPrivateFieldGet(this, _SessionEncrypted_authKey, "f").subarray(0, 36)]));
214
- const b = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([__classPrivateFieldGet(this, _SessionEncrypted_authKey, "f").subarray(40, 76), messageKey]));
215
- const aesKey = (0, _0_deps_js_1.concat)([a.subarray(0, 8), b.subarray(8, 24), a.subarray(24, 32)]);
216
- const aesIV = (0, _0_deps_js_1.concat)([b.subarray(0, 8), a.subarray(8, 24), b.subarray(24, 32)]);
217
- const messageWriter = new _1_tl_writer_js_1.TLWriter();
218
- messageWriter.writeInt64(__classPrivateFieldGet(this, _SessionEncrypted_authKeyId, "f"));
219
- messageWriter.write(messageKey);
220
- messageWriter.write((0, _0_deps_js_1.ige256Encrypt)(payload, aesKey, aesIV));
221
- return messageWriter.buffer;
222
- }, _SessionEncrypted_decryptMessage = async function _SessionEncrypted_decryptMessage(buffer) {
223
- const reader = new _2_tl_js_1.TLReader(buffer);
224
- (0, _0_deps_js_1.assertEquals)(reader.readInt64(), __classPrivateFieldGet(this, _SessionEncrypted_authKeyId, "f"));
225
- const messageKey_ = reader.readInt128();
226
- const messageKey = (0, _1_utilities_js_1.intToBytes)(messageKey_, 16);
227
- const a = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([messageKey, __classPrivateFieldGet(this, _SessionEncrypted_authKey, "f").subarray(8, 44)]));
228
- const b = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([__classPrivateFieldGet(this, _SessionEncrypted_authKey, "f").subarray(48, 84), messageKey]));
229
- const aesKey = (0, _0_deps_js_1.concat)([a.subarray(0, 8), b.subarray(8, 24), a.subarray(24, 32)]);
230
- const aesIv = (0, _0_deps_js_1.concat)([b.subarray(0, 8), a.subarray(8, 24), b.subarray(24, 32)]);
231
- const plaintext = (0, _0_deps_js_1.ige256Decrypt)(reader.buffer, aesKey, aesIv);
232
- (0, _0_deps_js_1.assertEquals)(plaintext.buffer.byteLength % 4, 0);
233
- const plainReader = new _2_tl_js_1.TLReader(plaintext);
234
- const _salt = plainReader.readInt64();
235
- const _sessionId_ = plainReader.readInt64(false);
236
- return (0, _2_tl_js_1.deserializeMessage)(plainReader);
237
- }, _SessionEncrypted_sendLoopBody = async function _SessionEncrypted_sendLoopBody(loop, signal) {
238
- if (!this.isConnected) {
239
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("aborting as not connected");
240
- loop.abort();
241
- return;
242
- }
243
- const pendingMessage = __classPrivateFieldGet(this, _SessionEncrypted_pendingMessages, "f").shift();
244
- if (pendingMessage === undefined) {
245
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("no pending messages");
246
- return await new Promise((resolve) => {
247
- const onAbort = () => {
248
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("got aborted while sleeping");
249
- resolve();
250
- };
251
- signal.addEventListener("abort", onAbort);
252
- __classPrivateFieldSet(this, _SessionEncrypted_awakeSendLoop, () => {
253
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("got awaken");
254
- resolve();
255
- signal.removeEventListener("abort", onAbort);
256
- }, "f");
257
- });
258
- }
259
- const msg_id = this.state.nextMessageId();
260
- const seqno = this.state.nextSeqNo(true);
261
- let message = {
262
- _: "message",
263
- msg_id,
264
- seqno,
265
- body: pendingMessage.body,
266
- };
267
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("msg_id =", msg_id, "seqno =", seqno);
268
- if (__classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").length) {
269
- const msg_ids = __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").splice(0, 8192);
270
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("acknowledging", msg_ids.length, "message(s) while sending this one");
271
- const ack = {
272
- _: "message",
273
- msg_id: this.state.nextMessageId(),
274
- seqno: this.state.nextSeqNo(false),
275
- body: _2_tl_js_1.Mtproto.serializeObject({ _: "msgs_ack", msg_ids }),
276
- };
277
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("msgs_ack msg_id =", ack.msg_id, "seqno =", seqno);
278
- __classPrivateFieldGet(this, _SessionEncrypted_pendingAcks, "f").set(ack.msg_id, msg_ids);
279
- message = {
280
- _: "message",
281
- msg_id: this.state.nextMessageId(),
282
- seqno: this.state.nextSeqNo(false),
283
- body: {
284
- _: "msg_container",
285
- messages: [message, ack],
286
- },
287
- };
288
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("container msg_id =", message.msg_id, "seqno =", message.seqno);
289
- }
290
- try {
291
- const payload = await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_encryptMessage).call(this, message);
292
- await this.transport.transport.send(payload);
293
- pendingMessage.promiseWithResolvers.resolve(msg_id);
294
- }
295
- catch (err) {
296
- pendingMessage.promiseWithResolvers.reject(err);
297
- return;
298
- }
299
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").out(message);
300
- __classPrivateFieldGet(this, _SessionEncrypted_sentMessages, "f").add(msg_id);
301
- if (!(message.body instanceof Uint8Array)) {
302
- const msg_ids = message.body.messages.map((v) => v.msg_id);
303
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("sent container", message.msg_id, "with messages", ...msg_ids);
304
- __classPrivateFieldGet(this, _SessionEncrypted_containers, "f").set(message.msg_id, msg_ids);
305
- }
306
- else {
307
- __classPrivateFieldGet(this, _SessionEncrypted_LsendLoop, "f").debug("sent message", message.msg_id);
308
- }
309
- }, _SessionEncrypted_receiveLoopBody = async function _SessionEncrypted_receiveLoopBody(loop) {
310
- let message;
311
- try {
312
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("receiving");
313
- message = await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_receive).call(this);
314
- }
315
- catch (err) {
316
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").error("failed to receive message:", err);
177
+ async #encryptMessage(message) {
178
+ const payloadWriter = new _1_tl_writer_js_1.TLWriter();
179
+ payloadWriter.writeInt64(this.state.serverSalt);
180
+ payloadWriter.writeInt64(this.#id);
181
+ payloadWriter.write(await (0, _2_tl_js_1.serializeMessage)(message));
182
+ payloadWriter.write(new Uint8Array((0, _1_utilities_js_1.mod)(-(payloadWriter.buffer.length + 12), 16) + 12));
183
+ const payload = payloadWriter.buffer;
184
+ const messageKey = (await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([this.#authKey.subarray(88, 120), payload]))).subarray(8, 24);
185
+ const a = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([messageKey, this.#authKey.subarray(0, 36)]));
186
+ const b = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([this.#authKey.subarray(40, 76), messageKey]));
187
+ const aesKey = (0, _0_deps_js_1.concat)([a.subarray(0, 8), b.subarray(8, 24), a.subarray(24, 32)]);
188
+ const aesIV = (0, _0_deps_js_1.concat)([b.subarray(0, 8), a.subarray(8, 24), b.subarray(24, 32)]);
189
+ const messageWriter = new _1_tl_writer_js_1.TLWriter();
190
+ messageWriter.writeInt64(this.#authKeyId);
191
+ messageWriter.write(messageKey);
192
+ messageWriter.write((0, _0_deps_js_1.ige256Encrypt)(payload, aesKey, aesIV));
193
+ return messageWriter.buffer;
194
+ }
195
+ async #decryptMessage(buffer) {
196
+ const reader = new _2_tl_js_1.TLReader(buffer);
197
+ (0, _0_deps_js_1.assertEquals)(reader.readInt64(), this.#authKeyId);
198
+ const messageKey_ = reader.readInt128();
199
+ const messageKey = (0, _1_utilities_js_1.intToBytes)(messageKey_, 16);
200
+ const a = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([messageKey, this.#authKey.subarray(8, 44)]));
201
+ const b = await (0, _1_utilities_js_1.sha256)((0, _0_deps_js_1.concat)([this.#authKey.subarray(48, 84), messageKey]));
202
+ const aesKey = (0, _0_deps_js_1.concat)([a.subarray(0, 8), b.subarray(8, 24), a.subarray(24, 32)]);
203
+ const aesIv = (0, _0_deps_js_1.concat)([b.subarray(0, 8), a.subarray(8, 24), b.subarray(24, 32)]);
204
+ const plaintext = (0, _0_deps_js_1.ige256Decrypt)(reader.buffer, aesKey, aesIv);
205
+ (0, _0_deps_js_1.assertEquals)(plaintext.buffer.byteLength % 4, 0);
206
+ const plainReader = new _2_tl_js_1.TLReader(plaintext);
207
+ const _salt = plainReader.readInt64();
208
+ const _sessionId_ = plainReader.readInt64(false);
209
+ return (0, _2_tl_js_1.deserializeMessage)(plainReader);
210
+ }
211
+ //// SEND LOOP ////
212
+ #awakeSendLoop;
213
+ #sendLoop = new _0_abortable_loop_js_1.AbortableLoop(this.#sendLoopBody.bind(this), (err) => {
214
+ this.#LsendLoop.error("unhandled receive loop error:", err);
215
+ });
216
+ async #sendLoopBody(loop, signal) {
317
217
  if (!this.isConnected) {
318
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("aborting as not connected");
218
+ this.#LsendLoop.debug("aborting as not connected");
319
219
  loop.abort();
320
220
  return;
321
221
  }
322
- else {
222
+ const pendingMessage = this.#pendingMessages.shift();
223
+ if (pendingMessage === undefined) {
224
+ this.#LsendLoop.debug("no pending messages");
225
+ return await new Promise((resolve) => {
226
+ const onAbort = () => {
227
+ this.#LsendLoop.debug("got aborted while sleeping");
228
+ resolve();
229
+ };
230
+ signal.addEventListener("abort", onAbort);
231
+ this.#awakeSendLoop = () => {
232
+ this.#LsendLoop.debug("got awaken");
233
+ resolve();
234
+ signal.removeEventListener("abort", onAbort);
235
+ };
236
+ });
237
+ }
238
+ const msg_id = this.state.nextMessageId();
239
+ const seqno = this.state.nextSeqNo(true);
240
+ let message = {
241
+ _: "message",
242
+ msg_id,
243
+ seqno,
244
+ body: pendingMessage.body,
245
+ };
246
+ this.#LsendLoop.debug("msg_id =", msg_id, "seqno =", seqno);
247
+ if (this.#toAcknowledge.length) {
248
+ const msg_ids = this.#toAcknowledge.splice(0, 8192);
249
+ this.#LsendLoop.debug("acknowledging", msg_ids.length, "message(s) while sending this one");
250
+ const ack = {
251
+ _: "message",
252
+ msg_id: this.state.nextMessageId(),
253
+ seqno: this.state.nextSeqNo(false),
254
+ body: _2_tl_js_1.Mtproto.serializeObject({ _: "msgs_ack", msg_ids }),
255
+ };
256
+ this.#LsendLoop.debug("msgs_ack msg_id =", ack.msg_id, "seqno =", seqno);
257
+ this.#pendingAcks.set(ack.msg_id, msg_ids);
258
+ message = {
259
+ _: "message",
260
+ msg_id: this.state.nextMessageId(),
261
+ seqno: this.state.nextSeqNo(false),
262
+ body: {
263
+ _: "msg_container",
264
+ messages: [message, ack],
265
+ },
266
+ };
267
+ this.#LsendLoop.debug("container msg_id =", message.msg_id, "seqno =", message.seqno);
268
+ }
269
+ try {
270
+ const payload = await this.#encryptMessage(message);
271
+ await this.transport.transport.send(payload);
272
+ pendingMessage.promiseWithResolvers.resolve(msg_id);
273
+ }
274
+ catch (err) {
275
+ pendingMessage.promiseWithResolvers.reject(err);
323
276
  return;
324
277
  }
325
- }
326
- try {
327
- if (message.body instanceof Uint8Array) {
328
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessage).call(this, message.msg_id, message.body, null);
278
+ this.#LsendLoop.out(message);
279
+ this.#sentMessages.add(msg_id);
280
+ if (!(message.body instanceof Uint8Array)) {
281
+ const msg_ids = message.body.messages.map((v) => v.msg_id);
282
+ this.#LsendLoop.debug("sent container", message.msg_id, "with messages", ...msg_ids);
283
+ this.#containers.set(message.msg_id, msg_ids);
329
284
  }
330
285
  else {
331
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageContainer).call(this, message.msg_id, message.body);
286
+ this.#LsendLoop.debug("sent message", message.msg_id);
332
287
  }
333
288
  }
334
- catch (err) {
335
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").error("failed to handle message:", err);
336
- }
337
- }, _SessionEncrypted_onMessage =
338
- //// RECEIVE LOOP HANDLERS ////
339
- async function _SessionEncrypted_onMessage(msgId, body, containerId) {
340
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("received message with ID", msgId, "and size", body.length, "inside", ...(containerId === null ? ["no container"] : ["container", containerId]));
341
- const logger = __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").branch(msgId + "");
342
- let reader = new _2_tl_js_1.TLReader(body);
343
- let id = reader.readInt32(false);
344
- if (id === GZIP_PACKED) {
345
- logger.debug("unpacking compressed body");
346
- reader = new _2_tl_js_1.TLReader(await (0, _1_utilities_js_1.gunzip)(reader.readBytes()));
347
- id = reader.readInt32(false);
348
- }
349
- if (id === RPC_RESULT) {
350
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onRpcResult).call(this, msgId, reader.buffer, logger);
351
- return;
352
- }
353
- if (!_2_tl_js_1.Mtproto.schema.identifierToName[id]) {
354
- logger.debug("identified body as a non-MTProto constructor");
355
- reader.unreadInt32();
356
- this.handlers.onUpdate?.(reader.buffer);
357
- return;
358
- }
359
- let type;
360
- try {
361
- reader.unreadInt32();
362
- type = await _2_tl_js_1.Mtproto.deserializeType(_2_tl_js_1.X, reader);
363
- }
364
- catch (err) {
365
- logger.error("failed to deserialize MTProto type:", err);
366
- return;
367
- }
368
- logger.debug("received", (0, _2_tl_js_1.repr)(type));
369
- if (_2_tl_js_1.Mtproto.is("new_session_created", type)) {
370
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onNewSessionCreated).call(this, msgId, type);
371
- }
372
- else if (_2_tl_js_1.Mtproto.is("pong", type)) {
373
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onPong).call(this, msgId, type);
374
- }
375
- else if (_2_tl_js_1.Mtproto.is("bad_server_salt", type)) {
376
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onBadServerSalt).call(this, type);
377
- }
378
- else if (_2_tl_js_1.Mtproto.is("bad_msg_notification", type)) {
379
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onBadMsgNotification).call(this, msgId, type, logger);
380
- }
381
- else if (_2_tl_js_1.Mtproto.is("msg_detailed_info", type)) {
382
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMsgDetailedInfo).call(this, type, logger);
383
- }
384
- else if (_2_tl_js_1.Mtproto.is("msg_new_detailed_info", type)) {
385
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMsgNewDetailedInfo).call(this, type, logger);
386
- }
387
- else {
388
- logger.warning(`unhandled MTProto type: ${(0, _2_tl_js_1.repr)(type)}`);
389
- }
390
- }, _SessionEncrypted_onRpcResult = async function _SessionEncrypted_onRpcResult(msgId, body, logger) {
391
- logger.debug("received rpc_result");
392
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(msgId);
393
- let reader = new _2_tl_js_1.TLReader(body);
394
- const reqMsgId = reader.readInt64();
395
- let id = reader.readInt32(false);
396
- if (id === GZIP_PACKED) {
397
- logger.debug("unpacking compressed rpc_result");
398
- reader = new _2_tl_js_1.TLReader(await (0, _1_utilities_js_1.gunzip)(reader.readBytes()));
399
- id = reader.readInt32(false);
400
- reader.unreadInt32();
401
- }
402
- else {
403
- reader.unreadInt32();
404
- }
405
- if (id === RPC_ERROR) {
406
- logger.debug("received rpc_error from message", msgId);
407
- const error = await _2_tl_js_1.Mtproto.deserializeType("rpc_error", reader);
408
- this.handlers.onRpcError?.(reqMsgId, error);
409
- }
410
- else {
411
- this.handlers.onRpcResult?.(reqMsgId, reader.buffer);
412
- }
413
- }, _SessionEncrypted_onMsgDetailedInfo = function _SessionEncrypted_onMsgDetailedInfo(msgDetailedInfo, logger) {
414
- logger.debug("scheduling the acknowledgement of", msgDetailedInfo.answer_msg_id, "because of", msgDetailedInfo._);
415
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(msgDetailedInfo.answer_msg_id);
416
- }, _SessionEncrypted_onMsgNewDetailedInfo = function _SessionEncrypted_onMsgNewDetailedInfo(msgNewDetailedInfo, logger) {
417
- logger.debug("scheduling the acknowledgement of", msgNewDetailedInfo.answer_msg_id, "because of", msgNewDetailedInfo._);
418
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(msgNewDetailedInfo.answer_msg_id);
419
- }, _SessionEncrypted_onBadMsgNotification = async function _SessionEncrypted_onBadMsgNotification(msgId, badMsgNotification, logger) {
420
- let low = false;
421
- switch (badMsgNotification.error_code) {
422
- case 16: // message ID too low
423
- low = true;
424
- /* falls through */
425
- case 17: // message ID too high
426
- this.state.timeDifference = Math.abs((0, _1_utilities_js_1.toUnixTimestamp)(new Date()) - Number(msgId >> 32n));
427
- if (!low) {
428
- this.state.timeDifference = -this.state.timeDifference;
429
- logger.debug("resetting time difference to", -this.state.timeDifference, "because the ID of the message", badMsgNotification.bad_msg_id, "was too high");
430
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_invalidateSession).call(this, "message ID too high");
289
+ //// RECEIVE LOOP ////
290
+ #receiveLoop = new _0_abortable_loop_js_1.AbortableLoop(this.#receiveLoopBody.bind(this), (err) => {
291
+ this.#LreceiveLoop.error("unhandled receive loop error:", err);
292
+ });
293
+ async #receiveLoopBody(loop) {
294
+ let message;
295
+ try {
296
+ this.#LreceiveLoop.debug("receiving");
297
+ message = await this.#receive();
298
+ }
299
+ catch (err) {
300
+ this.#LreceiveLoop.error("failed to receive message:", err);
301
+ if (!this.isConnected) {
302
+ this.#LreceiveLoop.debug("aborting as not connected");
303
+ loop.abort();
431
304
  return;
432
305
  }
433
306
  else {
434
- logger.debug("resending message", badMsgNotification.bad_msg_id, "because its ID was too low");
307
+ return;
435
308
  }
436
- break;
437
- case 48: // bad server salt
438
- // resend
439
- __classPrivateFieldGet(this, _SessionEncrypted_L, "f").debug("resending message that caused bad_server_salt");
440
- break;
441
- default:
442
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_invalidateSession).call(this, "unexpected bad_msg_notification");
443
- return;
444
- }
445
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageFailed).call(this, badMsgNotification.bad_msg_id, new _0_session_error_js_1.SessionError(badMsgNotification._));
446
- }, _SessionEncrypted_onBadServerSalt = function _SessionEncrypted_onBadServerSalt(badServerSalt) {
447
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_setServerSalt).call(this, badServerSalt.new_server_salt);
448
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageFailed).call(this, badServerSalt.bad_msg_id, new _0_session_error_js_1.SessionError(badServerSalt._));
449
- }, _SessionEncrypted_onPong = function _SessionEncrypted_onPong(msgId, pong) {
450
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(msgId);
451
- const pendingPing = __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").get(pong.msg_id);
452
- if (pendingPing) {
453
- pendingPing.promiseWithResolvers.resolve(pong);
454
- __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").delete(pong.msg_id);
455
- }
456
- else {
457
- // pong is not ours
458
- this.handlers.onPong?.(pong);
309
+ }
310
+ try {
311
+ if (message.body instanceof Uint8Array) {
312
+ await this.#onMessage(message.msg_id, message.body, null);
313
+ }
314
+ else {
315
+ await this.#onMessageContainer(message.msg_id, message.body);
316
+ }
317
+ }
318
+ catch (err) {
319
+ this.#LreceiveLoop.error("failed to handle message:", err);
320
+ }
459
321
  }
460
- }, _SessionEncrypted_onNewSessionCreated = function _SessionEncrypted_onNewSessionCreated(msgId, newSessionCreated) {
461
- __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_setServerSalt).call(this, newSessionCreated.server_salt);
462
- __classPrivateFieldGet(this, _SessionEncrypted_toAcknowledge, "f").push(msgId);
463
- }, _SessionEncrypted_onMessageContainer = async function _SessionEncrypted_onMessageContainer(msgId, msgContainer) {
464
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("received container with ID", msgId, "and", msgContainer.messages.length, "message(s)");
465
- for (const message of msgContainer.messages) {
466
- if (message.body instanceof Uint8Array) {
467
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessage).call(this, message.msg_id, message.body, msgId);
322
+ //// RECEIVE LOOP HANDLERS ////
323
+ async #onMessage(msgId, body, containerId) {
324
+ this.#LreceiveLoop.debug("received message with ID", msgId, "and size", body.length, "inside", ...(containerId === null ? ["no container"] : ["container", containerId]));
325
+ const logger = this.#LreceiveLoop.branch(msgId + "");
326
+ let reader = new _2_tl_js_1.TLReader(body);
327
+ let id = reader.readInt32(false);
328
+ if (id === GZIP_PACKED) {
329
+ logger.debug("unpacking compressed body");
330
+ reader = new _2_tl_js_1.TLReader(await (0, _1_utilities_js_1.gunzip)(reader.readBytes()));
331
+ id = reader.readInt32(false);
332
+ }
333
+ if (id === RPC_RESULT) {
334
+ this.#onRpcResult(msgId, reader.buffer, logger);
335
+ return;
336
+ }
337
+ if (!_2_tl_js_1.Mtproto.schema.identifierToName[id]) {
338
+ logger.debug("identified body as a non-MTProto constructor");
339
+ reader.unreadInt32();
340
+ this.handlers.onUpdate?.(reader.buffer);
341
+ return;
342
+ }
343
+ let type;
344
+ try {
345
+ reader.unreadInt32();
346
+ type = await _2_tl_js_1.Mtproto.deserializeType(_2_tl_js_1.X, reader);
347
+ }
348
+ catch (err) {
349
+ logger.error("failed to deserialize MTProto type:", err);
350
+ return;
351
+ }
352
+ logger.debug("received", (0, _2_tl_js_1.repr)(type));
353
+ if (_2_tl_js_1.Mtproto.is("new_session_created", type)) {
354
+ this.#onNewSessionCreated(msgId, type);
355
+ }
356
+ else if (_2_tl_js_1.Mtproto.is("pong", type)) {
357
+ this.#onPong(msgId, type);
358
+ }
359
+ else if (_2_tl_js_1.Mtproto.is("bad_server_salt", type)) {
360
+ this.#onBadServerSalt(type);
361
+ }
362
+ else if (_2_tl_js_1.Mtproto.is("bad_msg_notification", type)) {
363
+ await this.#onBadMsgNotification(msgId, type, logger);
364
+ }
365
+ else if (_2_tl_js_1.Mtproto.is("msg_detailed_info", type)) {
366
+ this.#onMsgDetailedInfo(type, logger);
367
+ }
368
+ else if (_2_tl_js_1.Mtproto.is("msg_new_detailed_info", type)) {
369
+ this.#onMsgNewDetailedInfo(type, logger);
468
370
  }
469
371
  else {
470
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_onMessageContainer).call(this, msgId, message.body);
372
+ logger.warning(`unhandled MTProto type: ${(0, _2_tl_js_1.repr)(type)}`);
471
373
  }
472
374
  }
473
- }, _SessionEncrypted_pingLoopBody = async function _SessionEncrypted_pingLoopBody(_loop, signal) {
474
- const ms = Math.max(0, __classPrivateFieldGet(this, _SessionEncrypted_pingInterval, "f") - __classPrivateFieldGet(this, _SessionEncrypted_timeElapsed, "f"));
475
- if (ms) {
476
- __classPrivateFieldGet(this, _SessionEncrypted_LpingLoop, "f").debug(`sending ping in ${ms}ms`);
477
- await (0, _0_deps_js_1.delay)(ms, { signal });
478
- }
479
- else {
480
- __classPrivateFieldGet(this, _SessionEncrypted_LpingLoop, "f").debug("sending ping now");
375
+ async #onRpcResult(msgId, body, logger) {
376
+ logger.debug("received rpc_result");
377
+ this.#toAcknowledge.push(msgId);
378
+ let reader = new _2_tl_js_1.TLReader(body);
379
+ const reqMsgId = reader.readInt64();
380
+ let id = reader.readInt32(false);
381
+ if (id === GZIP_PACKED) {
382
+ logger.debug("unpacking compressed rpc_result");
383
+ reader = new _2_tl_js_1.TLReader(await (0, _1_utilities_js_1.gunzip)(reader.readBytes()));
384
+ id = reader.readInt32(false);
385
+ reader.unreadInt32();
386
+ }
387
+ else {
388
+ reader.unreadInt32();
389
+ }
390
+ if (id === RPC_ERROR) {
391
+ logger.debug("received rpc_error from message", msgId);
392
+ const error = await _2_tl_js_1.Mtproto.deserializeType("rpc_error", reader);
393
+ this.handlers.onRpcError?.(reqMsgId, error);
394
+ }
395
+ else {
396
+ this.handlers.onRpcResult?.(reqMsgId, reader.buffer);
397
+ }
481
398
  }
482
- signal.throwIfAborted();
483
- const then = Date.now();
484
- try {
485
- await __classPrivateFieldGet(this, _SessionEncrypted_instances, "m", _SessionEncrypted_sendPingDelayDisconnect).call(this, __classPrivateFieldGet(this, _SessionEncrypted_pingInterval, "f") / _0_deps_js_1.SECOND + 15);
486
- __classPrivateFieldGet(this, _SessionEncrypted_LpingLoop, "f").debug("received pong");
399
+ #onMsgDetailedInfo(msgDetailedInfo, logger) {
400
+ logger.debug("scheduling the acknowledgement of", msgDetailedInfo.answer_msg_id, "because of", msgDetailedInfo._);
401
+ this.#toAcknowledge.push(msgDetailedInfo.answer_msg_id);
402
+ }
403
+ #onMsgNewDetailedInfo(msgNewDetailedInfo, logger) {
404
+ logger.debug("scheduling the acknowledgement of", msgNewDetailedInfo.answer_msg_id, "because of", msgNewDetailedInfo._);
405
+ this.#toAcknowledge.push(msgNewDetailedInfo.answer_msg_id);
406
+ }
407
+ async #onBadMsgNotification(msgId, badMsgNotification, logger) {
408
+ let low = false;
409
+ switch (badMsgNotification.error_code) {
410
+ case 16: // message ID too low
411
+ low = true;
412
+ /* falls through */
413
+ case 17: // message ID too high
414
+ this.state.timeDifference = Math.abs((0, _1_utilities_js_1.toUnixTimestamp)(new Date()) - Number(msgId >> 32n));
415
+ if (!low) {
416
+ this.state.timeDifference = -this.state.timeDifference;
417
+ logger.debug("resetting time difference to", -this.state.timeDifference, "because the ID of the message", badMsgNotification.bad_msg_id, "was too high");
418
+ await this.#invalidateSession("message ID too high");
419
+ return;
420
+ }
421
+ else {
422
+ logger.debug("resending message", badMsgNotification.bad_msg_id, "because its ID was too low");
423
+ }
424
+ break;
425
+ case 48: // bad server salt
426
+ // resend
427
+ this.#L.debug("resending message that caused bad_server_salt");
428
+ break;
429
+ default:
430
+ await this.#invalidateSession("unexpected bad_msg_notification");
431
+ return;
432
+ }
433
+ this.#onMessageFailed(badMsgNotification.bad_msg_id, new _0_session_error_js_1.SessionError(badMsgNotification._));
434
+ }
435
+ #onBadServerSalt(badServerSalt) {
436
+ this.#setServerSalt(badServerSalt.new_server_salt);
437
+ this.#onMessageFailed(badServerSalt.bad_msg_id, new _0_session_error_js_1.SessionError(badServerSalt._));
438
+ }
439
+ #onPong(msgId, pong) {
440
+ this.#toAcknowledge.push(msgId);
441
+ const pendingPing = this.#pendingPings.get(pong.msg_id);
442
+ if (pendingPing) {
443
+ pendingPing.promiseWithResolvers.resolve(pong);
444
+ this.#pendingPings.delete(pong.msg_id);
445
+ }
446
+ else {
447
+ // pong is not ours
448
+ this.handlers.onPong?.(pong);
449
+ }
487
450
  }
488
- finally {
489
- __classPrivateFieldSet(this, _SessionEncrypted_timeElapsed, Date.now() - then, "f");
490
- __classPrivateFieldGet(this, _SessionEncrypted_LpingLoop, "f").debug(`took ${__classPrivateFieldGet(this, _SessionEncrypted_timeElapsed, "f")}`);
451
+ #onNewSessionCreated(msgId, newSessionCreated) {
452
+ this.#setServerSalt(newSessionCreated.server_salt);
453
+ this.#toAcknowledge.push(msgId);
491
454
  }
492
- signal.throwIfAborted();
493
- }, _SessionEncrypted_sendPingDelayDisconnect = async function _SessionEncrypted_sendPingDelayDisconnect(disconnect_delay) {
494
- const ping_id = (0, _1_utilities_js_1.getRandomId)();
495
- const call = { _: "ping_delay_disconnect", ping_id, disconnect_delay };
496
- const messageId = await this.send(_2_tl_js_1.Mtproto.serializeObject(call));
497
- const promiseWithResolvers = Promise.withResolvers();
498
- __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").set(messageId, { call, promiseWithResolvers });
499
- await promiseWithResolvers.promise;
500
- }, _SessionEncrypted_resendPendingPing = async function _SessionEncrypted_resendPendingPing(pendingPing) {
501
- try {
502
- const messageId = await this.send(_2_tl_js_1.Mtproto.serializeObject(pendingPing.call));
503
- __classPrivateFieldGet(this, _SessionEncrypted_pendingPings, "f").set(messageId, pendingPing);
504
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("ping resent");
455
+ async #onMessageContainer(msgId, msgContainer) {
456
+ this.#LreceiveLoop.debug("received container with ID", msgId, "and", msgContainer.messages.length, "message(s)");
457
+ for (const message of msgContainer.messages) {
458
+ if (message.body instanceof Uint8Array) {
459
+ await this.#onMessage(message.msg_id, message.body, msgId);
460
+ }
461
+ else {
462
+ await this.#onMessageContainer(msgId, message.body);
463
+ }
464
+ }
505
465
  }
506
- catch (err) {
507
- __classPrivateFieldGet(this, _SessionEncrypted_LreceiveLoop, "f").debug("rejecting ping because of failed resend:", err);
508
- pendingPing.promiseWithResolvers.reject(err);
466
+ //// PING LOOP ////
467
+ #pingInterval = 56 * _0_deps_js_1.SECOND;
468
+ #pingLoop = new _0_abortable_loop_js_1.AbortableLoop(this.#pingLoopBody.bind(this), (_, err) => {
469
+ this.#LpingLoop.error(err);
470
+ });
471
+ #timeElapsed = 0;
472
+ async #pingLoopBody(_loop, signal) {
473
+ const ms = Math.max(0, this.#pingInterval - this.#timeElapsed);
474
+ if (ms) {
475
+ this.#LpingLoop.debug(`sending ping in ${ms}ms`);
476
+ await (0, _0_deps_js_1.delay)(ms, { signal });
477
+ }
478
+ else {
479
+ this.#LpingLoop.debug("sending ping now");
480
+ }
481
+ signal.throwIfAborted();
482
+ const then = Date.now();
483
+ try {
484
+ await this.#sendPingDelayDisconnect(this.#pingInterval / _0_deps_js_1.SECOND + 15);
485
+ this.#LpingLoop.debug("received pong");
486
+ }
487
+ finally {
488
+ this.#timeElapsed = Date.now() - then;
489
+ this.#LpingLoop.debug(`took ${this.#timeElapsed}`);
490
+ }
491
+ signal.throwIfAborted();
492
+ }
493
+ async #sendPingDelayDisconnect(disconnect_delay) {
494
+ const ping_id = (0, _1_utilities_js_1.getRandomId)();
495
+ const call = { _: "ping_delay_disconnect", ping_id, disconnect_delay };
496
+ const messageId = await this.send(_2_tl_js_1.Mtproto.serializeObject(call));
497
+ const promiseWithResolvers = Promise.withResolvers();
498
+ this.#pendingPings.set(messageId, { call, promiseWithResolvers });
499
+ await promiseWithResolvers.promise;
500
+ }
501
+ async #resendPendingPing(pendingPing) {
502
+ try {
503
+ const messageId = await this.send(_2_tl_js_1.Mtproto.serializeObject(pendingPing.call));
504
+ this.#pendingPings.set(messageId, pendingPing);
505
+ this.#LreceiveLoop.debug("ping resent");
506
+ }
507
+ catch (err) {
508
+ this.#LreceiveLoop.debug("rejecting ping because of failed resend:", err);
509
+ pendingPing.promiseWithResolvers.reject(err);
510
+ }
509
511
  }
510
- };
511
- _SessionEncrypted_TGCRYPTO_INITED = { value: false };
512
+ }
513
+ exports.SessionEncrypted = SessionEncrypted;