@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.
- package/README.md +1 -1
- package/esm/0_errors.d.ts.map +1 -1
- package/esm/0_errors.js +9 -31
- package/esm/3_errors.js +2 -12
- package/esm/4_errors.js +2 -12
- package/esm/_dnt.polyfills.d.ts +0 -99
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +1 -127
- package/esm/client/0_abortable_loop.js +26 -39
- package/esm/client/0_storage_operations.js +179 -218
- package/esm/client/1_client_plain.js +4 -22
- package/esm/client/2_account_manager.js +140 -149
- package/esm/client/2_bot_info_manager.js +26 -38
- package/esm/client/2_business_connection_manager.js +10 -23
- package/esm/client/2_client_encrypted.js +198 -215
- package/esm/client/2_file_manager.js +255 -262
- package/esm/client/2_network_statistics_manager.js +31 -44
- package/esm/client/2_payment_manager.js +7 -20
- package/esm/client/2_reaction_manager.js +7 -20
- package/esm/client/2_translations_manager.js +101 -111
- package/esm/client/2_update_manager.js +750 -745
- package/esm/client/3_client_encrypted_pool.js +10 -26
- package/esm/client/3_message_manager.js +503 -508
- package/esm/client/3_video_chat_manager.js +57 -68
- package/esm/client/4_callback_query_manager.js +18 -30
- package/esm/client/4_chat_list_manager.js +140 -146
- package/esm/client/4_chat_manager.js +161 -169
- package/esm/client/4_checklist_manager.js +26 -39
- package/esm/client/4_context.js +244 -259
- package/esm/client/4_forum_manager.js +67 -73
- package/esm/client/4_gift_manager.js +22 -35
- package/esm/client/4_inline_query_manager.js +16 -28
- package/esm/client/4_link_preview_manager.js +6 -19
- package/esm/client/4_poll_manager.js +44 -57
- package/esm/client/4_story_manager.js +41 -53
- package/esm/client/5_composer.js +13 -26
- package/esm/client/6_client.js +866 -896
- package/esm/client/6_client_dispatcher.js +308 -325
- package/esm/client/7_client_worker.js +16 -29
- package/esm/connection/1_connection_tcp.js +55 -82
- package/esm/connection/1_connection_web_socket.js +75 -91
- package/esm/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/esm/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/esm/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/esm/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/esm/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/esm/session/0_session_state.js +12 -38
- package/esm/session/1_session.js +49 -72
- package/esm/session/2_session_encrypted.js +422 -420
- package/esm/storage/2_storage_indexed_db.js +26 -44
- package/esm/storage/2_storage_local_storage.js +3 -16
- package/esm/storage/2_storage_memory.js +24 -41
- package/esm/storage/2_storage_session_storage.js +3 -16
- package/esm/tl/1_tl_reader.d.ts +1 -1
- package/esm/tl/1_tl_reader.d.ts.map +1 -1
- package/esm/tl/1_tl_reader.js +95 -103
- package/esm/tl/1_tl_writer.js +169 -178
- package/esm/transport/0_transport.js +1 -8
- package/esm/transport/1_transport_abridged.js +11 -24
- package/esm/transport/1_transport_intermediate.js +10 -23
- package/esm/utilities/0_mutex.js +4 -19
- package/esm/utilities/0_part_stream.js +11 -25
- package/esm/utilities/1_crypto.js +42 -53
- package/esm/utilities/2_queue.js +29 -47
- package/package.json +1 -1
- package/script/0_errors.d.ts.map +1 -1
- package/script/0_errors.js +9 -31
- package/script/3_errors.js +2 -12
- package/script/4_errors.js +2 -12
- package/script/_dnt.polyfills.d.ts +0 -99
- package/script/_dnt.polyfills.d.ts.map +1 -1
- package/script/_dnt.polyfills.js +0 -128
- package/script/client/0_abortable_loop.js +27 -40
- package/script/client/0_storage_operations.js +179 -218
- package/script/client/1_client_plain.js +4 -22
- package/script/client/2_account_manager.js +140 -149
- package/script/client/2_bot_info_manager.js +26 -38
- package/script/client/2_business_connection_manager.js +10 -23
- package/script/client/2_client_encrypted.js +199 -216
- package/script/client/2_file_manager.js +255 -262
- package/script/client/2_network_statistics_manager.js +32 -45
- package/script/client/2_payment_manager.js +7 -20
- package/script/client/2_reaction_manager.js +7 -20
- package/script/client/2_translations_manager.js +102 -112
- package/script/client/2_update_manager.js +750 -745
- package/script/client/3_client_encrypted_pool.js +10 -26
- package/script/client/3_message_manager.js +503 -508
- package/script/client/3_video_chat_manager.js +57 -68
- package/script/client/4_callback_query_manager.js +18 -30
- package/script/client/4_chat_list_manager.js +140 -146
- package/script/client/4_chat_manager.js +161 -169
- package/script/client/4_checklist_manager.js +26 -39
- package/script/client/4_context.js +244 -259
- package/script/client/4_forum_manager.js +67 -73
- package/script/client/4_gift_manager.js +22 -35
- package/script/client/4_inline_query_manager.js +16 -28
- package/script/client/4_link_preview_manager.js +6 -19
- package/script/client/4_poll_manager.js +44 -57
- package/script/client/4_story_manager.js +41 -53
- package/script/client/5_composer.js +13 -26
- package/script/client/6_client.js +866 -896
- package/script/client/6_client_dispatcher.js +308 -325
- package/script/client/7_client_worker.js +16 -29
- package/script/connection/1_connection_tcp.js +55 -82
- package/script/connection/1_connection_web_socket.js +75 -91
- package/script/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/script/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/script/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/script/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/script/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/script/session/0_session_state.js +12 -38
- package/script/session/1_session.js +49 -72
- package/script/session/2_session_encrypted.js +423 -421
- package/script/storage/2_storage_indexed_db.js +26 -44
- package/script/storage/2_storage_local_storage.js +3 -16
- package/script/storage/2_storage_memory.js +24 -41
- package/script/storage/2_storage_session_storage.js +3 -16
- package/script/tl/1_tl_reader.d.ts +1 -1
- package/script/tl/1_tl_reader.d.ts.map +1 -1
- package/script/tl/1_tl_reader.js +96 -104
- package/script/tl/1_tl_writer.js +170 -179
- package/script/transport/0_transport.js +1 -8
- package/script/transport/1_transport_abridged.js +11 -24
- package/script/transport/1_transport_intermediate.js +10 -23
- package/script/utilities/0_mutex.js +4 -19
- package/script/utilities/0_part_stream.js +11 -25
- package/script/utilities/1_crypto.js +43 -54
- package/script/utilities/2_queue.js +30 -48
|
@@ -17,18 +17,7 @@
|
|
|
17
17
|
* You should have received a copy of the GNU Lesser General Public License
|
|
18
18
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
|
-
var
|
|
21
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
22
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
23
|
-
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");
|
|
24
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
25
|
-
};
|
|
26
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
27
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
28
|
-
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");
|
|
29
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
30
|
-
};
|
|
31
|
-
var _UpdateManager_instances, _a, _UpdateManager_c, _UpdateManager_updateState, _UpdateManager_updateHandler, _UpdateManager_LrecoverUpdateGap, _UpdateManager_LrecoverChannelUpdateGap, _UpdateManager_L$handleUpdate, _UpdateManager_L$processUpdates, _UpdateManager_LfetchState, _UpdateManager_LopenChat, _UpdateManager_defaultDropPendingUpdates, _UpdateManager_mustDropPendingUpdates, _UpdateManager_state, _UpdateManager_getState, _UpdateManager_setState, _UpdateManager_extractMessages, _UpdateManager_extractMinPeerReferences, _UpdateManager_handleUpdateQueues, _UpdateManager_nonFirst, _UpdateManager_getChannelPtsWithDropPendingUpdatesCheck, _UpdateManager_checkGap, _UpdateManager_checkGapQts, _UpdateManager_checkChannelGap, _UpdateManager_channelUpdateQueues, _UpdateManager_processChannelPtsUpdateInner, _UpdateManager_queueUpdate, _UpdateManager_processChannelPtsUpdate, _UpdateManager_processPtsUpdateInner, _UpdateManager_ptsUpdateQueue, _UpdateManager_processPtsUpdate, _UpdateManager_processQtsUpdateInner, _UpdateManager_qtsUpdateQueue, _UpdateManager_processQtsUpdate, _UpdateManager_processUpdatesQueue, _UpdateManager_processUpdates, _UpdateManager_setUpdateStateDate, _UpdateManager_setUpdatePts, _UpdateManager_setUpdateQts, _UpdateManager_getLocalState, _UpdateManager_recoveringUpdateGap, _UpdateManager_recoverUpdateGapMutex, _UpdateManager_recoverChannelUpdateGap, _UpdateManager_handleUpdatesSet, _UpdateManager_handleStoredUpdates, _UpdateManager_handleUpdate, _UpdateManager_needsGetDifference, _UpdateManager_collectChatIds, _UpdateManager_collectChatIdsFromEntities, _UpdateManager_openChats;
|
|
20
|
+
var _a;
|
|
32
21
|
import { delay, SECOND, unreachable } from "../0_deps.js";
|
|
33
22
|
import { InputError } from "../0_errors.js";
|
|
34
23
|
import { getLogger, Mutex, Queue, ZERO_CHANNEL_ID } from "../1_utilities.js";
|
|
@@ -37,37 +26,26 @@ import { PersistentTimestampInvalid } from "../3_errors.js";
|
|
|
37
26
|
import { CHANNEL_DIFFERENCE_LIMIT_BOT, CHANNEL_DIFFERENCE_LIMIT_USER } from "../4_constants.js";
|
|
38
27
|
import { peerToChatId } from "../tl/2_telegram.js";
|
|
39
28
|
export class UpdateManager {
|
|
29
|
+
static QTS_COUNT = 1;
|
|
30
|
+
static MAIN_BOX_ID = 0n;
|
|
31
|
+
#c;
|
|
32
|
+
#updateState;
|
|
33
|
+
#updateHandler;
|
|
34
|
+
#LrecoverUpdateGap;
|
|
35
|
+
#LrecoverChannelUpdateGap;
|
|
36
|
+
#L$handleUpdate;
|
|
37
|
+
#L$processUpdates;
|
|
38
|
+
#LfetchState;
|
|
39
|
+
#LopenChat;
|
|
40
40
|
constructor(c) {
|
|
41
|
-
|
|
42
|
-
_UpdateManager_c.set(this, void 0);
|
|
43
|
-
_UpdateManager_updateState.set(this, void 0);
|
|
44
|
-
_UpdateManager_updateHandler.set(this, void 0);
|
|
45
|
-
_UpdateManager_LrecoverUpdateGap.set(this, void 0);
|
|
46
|
-
_UpdateManager_LrecoverChannelUpdateGap.set(this, void 0);
|
|
47
|
-
_UpdateManager_L$handleUpdate.set(this, void 0);
|
|
48
|
-
_UpdateManager_L$processUpdates.set(this, void 0);
|
|
49
|
-
_UpdateManager_LfetchState.set(this, void 0);
|
|
50
|
-
_UpdateManager_LopenChat.set(this, void 0);
|
|
51
|
-
_UpdateManager_defaultDropPendingUpdates.set(this, null);
|
|
52
|
-
_UpdateManager_state.set(this, null);
|
|
53
|
-
_UpdateManager_handleUpdateQueues.set(this, new Map());
|
|
54
|
-
_UpdateManager_nonFirst.set(this, new Set());
|
|
55
|
-
_UpdateManager_channelUpdateQueues.set(this, new Map());
|
|
56
|
-
_UpdateManager_ptsUpdateQueue.set(this, new Queue("ptsUpdate"));
|
|
57
|
-
_UpdateManager_qtsUpdateQueue.set(this, new Queue("qtsUpdate"));
|
|
58
|
-
_UpdateManager_processUpdatesQueue.set(this, new Queue("UpdateManager/processUpdates"));
|
|
59
|
-
_UpdateManager_recoveringUpdateGap.set(this, false);
|
|
60
|
-
_UpdateManager_recoverUpdateGapMutex.set(this, new Mutex());
|
|
61
|
-
_UpdateManager_handleUpdatesSet.set(this, new Set());
|
|
62
|
-
_UpdateManager_openChats.set(this, new Map());
|
|
63
|
-
__classPrivateFieldSet(this, _UpdateManager_c, c, "f");
|
|
41
|
+
this.#c = c;
|
|
64
42
|
const L = getLogger("UpdateManager").client(c.id);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
43
|
+
this.#LrecoverUpdateGap = L.branch("recoverUpdateGap");
|
|
44
|
+
this.#LrecoverChannelUpdateGap = L.branch("recoverChannelUpdateGap");
|
|
45
|
+
this.#L$handleUpdate = L.branch("#handleUpdate");
|
|
46
|
+
this.#L$processUpdates = L.branch("#processUpdates");
|
|
47
|
+
this.#LfetchState = L.branch("fetchState");
|
|
48
|
+
this.#LopenChat = L.branch("openChat");
|
|
71
49
|
}
|
|
72
50
|
static isPtsUpdate(v) {
|
|
73
51
|
return Api.isOneOf(["updateNewMessage", "updateDeleteMessages", "updateReadHistoryInbox", "updateReadHistoryOutbox", "updatePinnedChannelMessages", "updatePinnedMessages", "updateFolderPeers", "updateChannelWebPage", "updateEditMessage", "updateReadMessagesContents", "updateWebPage"], v);
|
|
@@ -83,21 +61,94 @@ export class UpdateManager {
|
|
|
83
61
|
"updateChannelTooLong",
|
|
84
62
|
], v);
|
|
85
63
|
}
|
|
64
|
+
#defaultDropPendingUpdates = null;
|
|
65
|
+
#mustDropPendingUpdates() {
|
|
66
|
+
if (typeof this.#c.dropPendingUpdates === "boolean") {
|
|
67
|
+
return this.#c.dropPendingUpdates;
|
|
68
|
+
}
|
|
69
|
+
if (this.#defaultDropPendingUpdates === null) {
|
|
70
|
+
this.#defaultDropPendingUpdates = this.#c.storage.isBot;
|
|
71
|
+
}
|
|
72
|
+
return this.#defaultDropPendingUpdates;
|
|
73
|
+
}
|
|
74
|
+
#state = null;
|
|
75
|
+
async #getState() {
|
|
76
|
+
if (this.#mustDropPendingUpdates()) {
|
|
77
|
+
return this.#state ?? null;
|
|
78
|
+
}
|
|
79
|
+
if (this.#state !== null) {
|
|
80
|
+
return this.#state;
|
|
81
|
+
}
|
|
82
|
+
const state = await this.#c.storage.getState();
|
|
83
|
+
return this.#state = state;
|
|
84
|
+
}
|
|
85
|
+
async #setState(state) {
|
|
86
|
+
this.#state = state;
|
|
87
|
+
if (!this.#mustDropPendingUpdates()) {
|
|
88
|
+
await this.#c.storage.setState(state);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
86
91
|
async fetchState(source) {
|
|
87
|
-
let state = await
|
|
88
|
-
const difference = await
|
|
92
|
+
let state = await this.#c.invoke({ _: "updates.getState" });
|
|
93
|
+
const difference = await this.#c.invoke({ ...state, _: "updates.getDifference" });
|
|
89
94
|
if (Api.is("updates.difference", difference)) {
|
|
90
95
|
state = difference.state;
|
|
91
96
|
}
|
|
92
97
|
else if (Api.is("updates.differenceSlice", difference)) {
|
|
93
98
|
state = difference.intermediate_state;
|
|
94
99
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
await
|
|
100
|
+
this.#updateState = state;
|
|
101
|
+
this.#LfetchState.debug(`state fetched [${source}]`);
|
|
102
|
+
if (this.#mustDropPendingUpdates()) {
|
|
103
|
+
await this.#setState(state);
|
|
99
104
|
}
|
|
100
105
|
}
|
|
106
|
+
#extractMessages(context) {
|
|
107
|
+
const messages = new Array();
|
|
108
|
+
if (Array.isArray(context)) {
|
|
109
|
+
for (const item of context) {
|
|
110
|
+
messages.push(...this.#extractMessages(item));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (Api.isOneOf(["updates", "updatesCombined"], context)) {
|
|
114
|
+
messages.push(...this.#extractMessages(context.updates));
|
|
115
|
+
}
|
|
116
|
+
else if (Api.isOneOf(["updates.difference", "updates.differenceSlice", "updates.channelDifference"], context)) {
|
|
117
|
+
for (const message of context.new_messages) {
|
|
118
|
+
if (Api.is("message", message)) {
|
|
119
|
+
messages.push(message);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
messages.push(...this.#extractMessages(context.other_updates));
|
|
123
|
+
}
|
|
124
|
+
else if (Api.isOneOf(["updateNewMessage", "updateNewChannelMessage", "updateEditMessage", "updateEditChannelMessage", "updateBotNewBusinessMessage", "updateBotNewBusinessMessage"], context)) {
|
|
125
|
+
if (Api.is("message", context.message)) {
|
|
126
|
+
messages.push(context.message);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else if (Api.is("message", context)) {
|
|
130
|
+
messages.push(context);
|
|
131
|
+
}
|
|
132
|
+
else if (context !== null && typeof context === "object" && "messages" in context && Array.isArray(context.messages)) {
|
|
133
|
+
for (const message of context.messages) {
|
|
134
|
+
if (Api.is("message", message)) {
|
|
135
|
+
messages.push(message);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return messages;
|
|
140
|
+
}
|
|
141
|
+
#extractMinPeerReferences(context) {
|
|
142
|
+
const minPeerReferences = new Array();
|
|
143
|
+
const messages = this.#extractMessages(context);
|
|
144
|
+
for (const message of messages) {
|
|
145
|
+
if (!message.from_id) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
minPeerReferences.push({ chatId: Api.peerToChatId(message.peer_id), senderId: Api.peerToChatId(message.from_id), messageId: message.id });
|
|
149
|
+
}
|
|
150
|
+
return minPeerReferences;
|
|
151
|
+
}
|
|
101
152
|
processChats(chats, _context) {
|
|
102
153
|
for (const chat of chats) {
|
|
103
154
|
this.processChat(chat);
|
|
@@ -110,14 +161,14 @@ export class UpdateManager {
|
|
|
110
161
|
if (Api.is("channel", chat) && chat.min) {
|
|
111
162
|
return; // TODO
|
|
112
163
|
}
|
|
113
|
-
|
|
164
|
+
this.#c.messageStorage.setPeer(chat);
|
|
114
165
|
if ("username" in chat && chat.username) {
|
|
115
|
-
|
|
166
|
+
this.#c.messageStorage.usernames.set([chat.username], [Api.peerToChatId(chat), new Date()]);
|
|
116
167
|
}
|
|
117
168
|
if ("usernames" in chat && chat.usernames) {
|
|
118
169
|
const value = [Api.peerToChatId(chat), new Date()];
|
|
119
170
|
for (const username of chat.usernames) {
|
|
120
|
-
|
|
171
|
+
this.#c.messageStorage.usernames.set([username.username], value);
|
|
121
172
|
}
|
|
122
173
|
}
|
|
123
174
|
}
|
|
@@ -157,7 +208,7 @@ export class UpdateManager {
|
|
|
157
208
|
if ("messages" in result && Array.isArray(result.messages)) {
|
|
158
209
|
for (const message of result.messages) {
|
|
159
210
|
if (Api.is("message", message) || Api.is("messageService", message)) {
|
|
160
|
-
await
|
|
211
|
+
await this.#c.messageStorage.setMessage(Api.peerToChatId(message.peer_id), message.id, message);
|
|
161
212
|
}
|
|
162
213
|
}
|
|
163
214
|
}
|
|
@@ -165,7 +216,7 @@ export class UpdateManager {
|
|
|
165
216
|
if (Api.is("messages.messages", result)) {
|
|
166
217
|
for (const message of result.messages) {
|
|
167
218
|
if (Api.is("message", message) || Api.is("messageService", message)) {
|
|
168
|
-
await
|
|
219
|
+
await this.#c.messageStorage.setMessage(Api.peerToChatId(message.peer_id), message.id, message);
|
|
169
220
|
}
|
|
170
221
|
}
|
|
171
222
|
}
|
|
@@ -182,19 +233,20 @@ export class UpdateManager {
|
|
|
182
233
|
if (user.min) {
|
|
183
234
|
return; // TODO
|
|
184
235
|
}
|
|
185
|
-
|
|
236
|
+
this.#c.messageStorage.setPeer(user);
|
|
186
237
|
if (user.username) {
|
|
187
|
-
|
|
238
|
+
this.#c.messageStorage.usernames.set([user.username], [Api.peerToChatId(user), new Date()]);
|
|
188
239
|
}
|
|
189
240
|
if (user.usernames) {
|
|
190
241
|
const value = [Api.peerToChatId(user), new Date()];
|
|
191
242
|
for (const username of user.usernames) {
|
|
192
|
-
|
|
243
|
+
this.#c.messageStorage.usernames.set([username.username], value);
|
|
193
244
|
}
|
|
194
245
|
}
|
|
195
246
|
}
|
|
247
|
+
#handleUpdateQueues = new Map();
|
|
196
248
|
getHandleUpdateQueue(boxId) {
|
|
197
|
-
let queue =
|
|
249
|
+
let queue = this.#handleUpdateQueues.get(boxId);
|
|
198
250
|
if (queue !== undefined) {
|
|
199
251
|
return queue;
|
|
200
252
|
}
|
|
@@ -203,27 +255,365 @@ export class UpdateManager {
|
|
|
203
255
|
return queue;
|
|
204
256
|
}
|
|
205
257
|
}
|
|
258
|
+
#nonFirst = new Set();
|
|
259
|
+
async #getChannelPtsWithDropPendingUpdatesCheck(channelId) {
|
|
260
|
+
if (!(this.#mustDropPendingUpdates())) {
|
|
261
|
+
return await this.#c.storage.channelPts.get([channelId]);
|
|
262
|
+
}
|
|
263
|
+
const first = !this.#nonFirst.has(channelId);
|
|
264
|
+
if (first) {
|
|
265
|
+
this.#nonFirst.add(channelId);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
return await this.#c.storage.channelPts.get([channelId]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async #checkGap(pts, ptsCount) {
|
|
273
|
+
const localState = await this.#getLocalState();
|
|
274
|
+
if (localState.pts + ptsCount < pts) {
|
|
275
|
+
await this.recoverUpdateGap("processUpdates[pts]");
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async #checkGapQts(qts) {
|
|
279
|
+
const localState = await this.#getLocalState();
|
|
280
|
+
if (localState.qts + _a.QTS_COUNT < qts) {
|
|
281
|
+
await this.recoverUpdateGap("processUpdates[qts]");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async #checkChannelGap(channelId, pts, ptsCount) {
|
|
285
|
+
let localPts = await this.#getChannelPtsWithDropPendingUpdatesCheck(channelId);
|
|
286
|
+
if (!localPts) {
|
|
287
|
+
localPts = pts - ptsCount;
|
|
288
|
+
}
|
|
289
|
+
if (localPts + ptsCount < pts) {
|
|
290
|
+
await this.#recoverChannelUpdateGap(channelId, "processUpdates");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
#channelUpdateQueues = new Map();
|
|
294
|
+
async #processChannelPtsUpdateInner(update, checkGap) {
|
|
295
|
+
const channelId = Api.is("updateNewChannelMessage", update) || Api.is("updateEditChannelMessage", update) ? Api.as("peerChannel", update.message.peer_id).channel_id : update.channel_id;
|
|
296
|
+
if (Api.is("updateChannelTooLong", update)) {
|
|
297
|
+
if (update.pts !== undefined) {
|
|
298
|
+
this.#c.storage.channelPts.set([channelId], update.pts);
|
|
299
|
+
}
|
|
300
|
+
await this.#recoverChannelUpdateGap(channelId, "updateChannelTooLong");
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (update.pts !== 0) {
|
|
304
|
+
const ptsCount = update.pts_count;
|
|
305
|
+
if (checkGap) {
|
|
306
|
+
await this.#checkChannelGap(channelId, update.pts, ptsCount);
|
|
307
|
+
}
|
|
308
|
+
let currentPts = await this.#getChannelPtsWithDropPendingUpdatesCheck(channelId);
|
|
309
|
+
currentPts ??= update.pts - ptsCount;
|
|
310
|
+
if (currentPts + ptsCount > update.pts) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (this.#c.guaranteeUpdateDelivery) {
|
|
315
|
+
await this.#c.storage.setUpdate(channelId, update);
|
|
316
|
+
}
|
|
317
|
+
if (update.pts !== 0) {
|
|
318
|
+
this.#c.storage.channelPts.set([channelId], update.pts);
|
|
319
|
+
}
|
|
320
|
+
this.#queueUpdate(update, channelId, true);
|
|
321
|
+
}
|
|
322
|
+
#queueUpdate(update, boxId, pts) {
|
|
323
|
+
this.getHandleUpdateQueue(boxId).add(async () => {
|
|
324
|
+
if (this.#c.guaranteeUpdateDelivery && pts) {
|
|
325
|
+
await this.#handleStoredUpdates(boxId);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
await (await this.#handleUpdate(update))();
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
#processChannelPtsUpdate(update, checkGap) {
|
|
333
|
+
const channelId = Api.is("updateNewChannelMessage", update) || Api.is("updateEditChannelMessage", update) ? Api.as("peerChannel", update.message.peer_id).channel_id : update.channel_id;
|
|
334
|
+
let queue = this.#channelUpdateQueues.get(channelId);
|
|
335
|
+
if (queue === undefined) {
|
|
336
|
+
queue = new Queue(`channelUpdates-${channelId}`);
|
|
337
|
+
this.#channelUpdateQueues.set(channelId, queue);
|
|
338
|
+
}
|
|
339
|
+
queue.add(async () => {
|
|
340
|
+
await this.#processChannelPtsUpdateInner(update, checkGap);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
async #processPtsUpdateInner(update, checkGap) {
|
|
344
|
+
if (update.pts !== 0 && checkGap) {
|
|
345
|
+
await this.#checkGap(update.pts, update.pts_count);
|
|
346
|
+
if (await this.#needsGetDifference(update)) {
|
|
347
|
+
await this.recoverUpdateGap("needsGetDifference");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const localState = await this.#getLocalState();
|
|
351
|
+
if (update.pts !== 0 && localState.pts + update.pts_count > update.pts) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (this.#c.guaranteeUpdateDelivery) {
|
|
355
|
+
await this.#c.storage.setUpdate(_a.MAIN_BOX_ID, update);
|
|
356
|
+
}
|
|
357
|
+
if (update.pts !== 0) {
|
|
358
|
+
await this.#setUpdatePts(update.pts);
|
|
359
|
+
}
|
|
360
|
+
this.#queueUpdate(update, 1n, false);
|
|
361
|
+
}
|
|
362
|
+
#ptsUpdateQueue = new Queue("ptsUpdate");
|
|
363
|
+
#processPtsUpdate(update, checkGap) {
|
|
364
|
+
this.#ptsUpdateQueue.add(async () => {
|
|
365
|
+
await this.#processPtsUpdateInner(update, checkGap);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async #processQtsUpdateInner(update, checkGap) {
|
|
369
|
+
const localState = await this.#getLocalState();
|
|
370
|
+
if (update.qts !== 0) {
|
|
371
|
+
if (checkGap) {
|
|
372
|
+
await this.#checkGapQts(update.qts);
|
|
373
|
+
}
|
|
374
|
+
if (localState.qts + _a.QTS_COUNT > update.qts) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
if (this.#c.guaranteeUpdateDelivery) {
|
|
379
|
+
await this.#c.storage.setUpdate(_a.MAIN_BOX_ID, update);
|
|
380
|
+
}
|
|
381
|
+
if (update.qts !== 0) {
|
|
382
|
+
await this.#setUpdateQts(update.qts);
|
|
383
|
+
}
|
|
384
|
+
this.#queueUpdate(update, 0n, true);
|
|
385
|
+
}
|
|
386
|
+
#qtsUpdateQueue = new Queue("qtsUpdate");
|
|
387
|
+
#processQtsUpdate(update, checkGap) {
|
|
388
|
+
this.#qtsUpdateQueue.add(async () => {
|
|
389
|
+
await this.#processQtsUpdateInner(update, checkGap);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
#processUpdatesQueue = new Queue("UpdateManager/processUpdates");
|
|
206
393
|
processUpdates(updates, checkGap, call = null, callback) {
|
|
207
|
-
|
|
394
|
+
this.#processUpdatesQueue.add(() => this.#processUpdates(updates, checkGap, call).finally(callback));
|
|
395
|
+
}
|
|
396
|
+
async #processUpdates(updates_, checkGap, call = null) {
|
|
397
|
+
/// First, individual updates (Update[1]) are extracted from Updates.[2]
|
|
398
|
+
///
|
|
399
|
+
/// If an updatesTooLong[3] was received, an update gap recovery is initiated and no further action will be taken.
|
|
400
|
+
///
|
|
401
|
+
/// [1]: https://core.telegram.org/type/Update
|
|
402
|
+
/// [2]: https://core.telegram.org/type/Updates
|
|
403
|
+
/// [3]: https://core.telegram.org/constructor/updatesTooLong
|
|
404
|
+
let updates;
|
|
405
|
+
if (Api.is("updatesCombined", updates_) || Api.is("updates", updates_)) {
|
|
406
|
+
updates = updates_.updates;
|
|
407
|
+
const seq = updates_.seq;
|
|
408
|
+
const seqStart = "seq_start" in updates_ ? updates_.seq_start : updates_.seq;
|
|
409
|
+
if (checkGap) {
|
|
410
|
+
if (seqStart === 0) {
|
|
411
|
+
checkGap = false;
|
|
412
|
+
this.#L$processUpdates.debug("seqStart=0");
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
const localState = await this.#getLocalState();
|
|
416
|
+
const localSeq = localState.seq;
|
|
417
|
+
if (localSeq + 1 === seqStart) {
|
|
418
|
+
// The update sequence can be applied.
|
|
419
|
+
localState.seq = seq;
|
|
420
|
+
localState.date = updates_.date;
|
|
421
|
+
await this.#setUpdateStateDate(updates_.date);
|
|
422
|
+
await this.#setState(localState);
|
|
423
|
+
}
|
|
424
|
+
else if (localSeq + 1 > seqStart) {
|
|
425
|
+
// The update sequence was already applied, and must be ignored.
|
|
426
|
+
this.#L$processUpdates.debug("localSeq + 1 > seqStart");
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
else if (localSeq + 1 < seqStart) {
|
|
430
|
+
// There's an updates gap that must be filled.
|
|
431
|
+
await this.recoverUpdateGap("localSeq + 1 < seqStart");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
else if (Api.is("updateShort", updates_)) {
|
|
437
|
+
updates = [updates_.update];
|
|
438
|
+
}
|
|
439
|
+
else if (Api.is("updateShortMessage", updates_)) {
|
|
440
|
+
updates = [
|
|
441
|
+
{
|
|
442
|
+
_: "updateNewMessage",
|
|
443
|
+
message: {
|
|
444
|
+
_: "message",
|
|
445
|
+
out: updates_.out,
|
|
446
|
+
mentioned: updates_.mentioned,
|
|
447
|
+
media_unread: updates_.media_unread,
|
|
448
|
+
silent: updates_.silent,
|
|
449
|
+
id: updates_.id,
|
|
450
|
+
from_id: updates_.out ? ({ _: "peerUser", user_id: BigInt(await this.#c.getSelfId()) }) : ({ _: "peerUser", user_id: updates_.user_id }),
|
|
451
|
+
peer_id: { _: "peerUser", user_id: updates_.user_id },
|
|
452
|
+
message: updates_.message,
|
|
453
|
+
date: updates_.date,
|
|
454
|
+
fwd_from: updates_.fwd_from,
|
|
455
|
+
via_bot_id: updates_.via_bot_id,
|
|
456
|
+
reply_to: updates_.reply_to,
|
|
457
|
+
entities: updates_.entities,
|
|
458
|
+
ttl_period: updates_.ttl_period,
|
|
459
|
+
},
|
|
460
|
+
pts: updates_.pts,
|
|
461
|
+
pts_count: updates_.pts_count,
|
|
462
|
+
},
|
|
463
|
+
];
|
|
464
|
+
}
|
|
465
|
+
else if (Api.is("updateShortChatMessage", updates_)) {
|
|
466
|
+
updates = [
|
|
467
|
+
{
|
|
468
|
+
_: "updateNewMessage",
|
|
469
|
+
message: {
|
|
470
|
+
_: "message",
|
|
471
|
+
mentioned: updates_.mentioned,
|
|
472
|
+
media_unread: updates_.media_unread,
|
|
473
|
+
silent: updates_.silent,
|
|
474
|
+
id: updates_.id,
|
|
475
|
+
from_id: { _: "peerUser", user_id: updates_.from_id },
|
|
476
|
+
peer_id: { _: "peerChat", chat_id: updates_.chat_id },
|
|
477
|
+
fwd_from: updates_.fwd_from,
|
|
478
|
+
via_bot_id: updates_.via_bot_id,
|
|
479
|
+
reply_to: updates_.reply_to,
|
|
480
|
+
date: updates_.date,
|
|
481
|
+
message: updates_.message,
|
|
482
|
+
entities: updates_.entities,
|
|
483
|
+
ttl_period: updates_.ttl_period,
|
|
484
|
+
},
|
|
485
|
+
pts: updates_.pts,
|
|
486
|
+
pts_count: updates_.pts_count,
|
|
487
|
+
},
|
|
488
|
+
];
|
|
489
|
+
}
|
|
490
|
+
else if (Api.is("updateShortSentMessage", updates_)) {
|
|
491
|
+
if (!Api.is("messages.sendMessage", call)) {
|
|
492
|
+
unreachable();
|
|
493
|
+
}
|
|
494
|
+
updates = [{
|
|
495
|
+
_: "updateNewMessage",
|
|
496
|
+
message: {
|
|
497
|
+
_: "message",
|
|
498
|
+
out: updates_.out,
|
|
499
|
+
silent: call.silent,
|
|
500
|
+
id: updates_.id,
|
|
501
|
+
from_id: { _: "peerUser", user_id: BigInt(await this.#c.getSelfId()) },
|
|
502
|
+
peer_id: Api.inputPeerToPeer(call.peer),
|
|
503
|
+
message: call.message,
|
|
504
|
+
media: updates_.media,
|
|
505
|
+
date: updates_.date,
|
|
506
|
+
// reply_to: call.reply_to, // TODO?
|
|
507
|
+
entities: updates_.entities,
|
|
508
|
+
ttl_period: updates_.ttl_period,
|
|
509
|
+
},
|
|
510
|
+
pts: updates_.pts,
|
|
511
|
+
pts_count: updates_.pts_count,
|
|
512
|
+
}];
|
|
513
|
+
}
|
|
514
|
+
else if (Api.is("updatesTooLong", updates_)) {
|
|
515
|
+
await this.recoverUpdateGap("updatesTooLong");
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
else if (Api.isOfEnum("Update", updates_)) {
|
|
519
|
+
updates = [updates_];
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
unreachable();
|
|
523
|
+
}
|
|
524
|
+
/// We process the updates when we are sure there is no gap.
|
|
525
|
+
if (Api.is("updates", updates_) || Api.is("updatesCombined", updates_)) {
|
|
526
|
+
this.processChats(updates_.chats, updates_);
|
|
527
|
+
this.processUsers(updates_.users, updates_);
|
|
528
|
+
this.#setUpdateStateDate(updates_.date);
|
|
529
|
+
}
|
|
530
|
+
else if (Api.isOneOf([
|
|
531
|
+
"updateShort",
|
|
532
|
+
"updateShortMessage",
|
|
533
|
+
"updateShortChatMessage",
|
|
534
|
+
"updateShortSentMessage",
|
|
535
|
+
], updates_)) {
|
|
536
|
+
await this.#setUpdateStateDate(updates_.date);
|
|
537
|
+
}
|
|
538
|
+
for (const update of updates) {
|
|
539
|
+
if (Api.is("updatePtsChanged", update)) {
|
|
540
|
+
await this.fetchState("updatePtsChanged");
|
|
541
|
+
if (this.#updateState) {
|
|
542
|
+
await this.#setState(this.#updateState);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
unreachable();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
else if (_a.isPtsUpdate(update)) {
|
|
549
|
+
this.#processPtsUpdate(update, checkGap);
|
|
550
|
+
}
|
|
551
|
+
else if (_a.isChannelPtsUpdate(update)) {
|
|
552
|
+
this.#processChannelPtsUpdate(update, checkGap);
|
|
553
|
+
}
|
|
554
|
+
else if (_a.isQtsUpdate(update)) {
|
|
555
|
+
this.#processQtsUpdate(update, checkGap);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
this.#queueUpdate(update, 0n, false);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async #setUpdateStateDate(date) {
|
|
563
|
+
const localState = await this.#getLocalState();
|
|
564
|
+
localState.date = date;
|
|
565
|
+
await this.#setState(localState);
|
|
566
|
+
}
|
|
567
|
+
async #setUpdatePts(pts) {
|
|
568
|
+
const localState = await this.#getLocalState();
|
|
569
|
+
localState.pts = pts;
|
|
570
|
+
await this.#setState(localState);
|
|
571
|
+
}
|
|
572
|
+
async #setUpdateQts(qts) {
|
|
573
|
+
const localState = await this.#getLocalState();
|
|
574
|
+
localState.qts = qts;
|
|
575
|
+
await this.#setState(localState);
|
|
576
|
+
}
|
|
577
|
+
async #getLocalState() {
|
|
578
|
+
let localState = await this.#getState();
|
|
579
|
+
if (!localState) {
|
|
580
|
+
if (this.#updateState) {
|
|
581
|
+
localState = this.#updateState;
|
|
582
|
+
await this.#setState(localState);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
await this.fetchState("getLocalState");
|
|
586
|
+
if (this.#updateState) {
|
|
587
|
+
localState = this.#updateState;
|
|
588
|
+
await this.#setState(localState);
|
|
589
|
+
}
|
|
590
|
+
else {
|
|
591
|
+
unreachable();
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return localState;
|
|
208
596
|
}
|
|
597
|
+
#recoveringUpdateGap = false;
|
|
598
|
+
#recoverUpdateGapMutex = new Mutex();
|
|
209
599
|
async recoverUpdateGap(source) {
|
|
210
|
-
const wasRecoveringUpdateGap =
|
|
211
|
-
const unlock = await
|
|
600
|
+
const wasRecoveringUpdateGap = this.#recoveringUpdateGap;
|
|
601
|
+
const unlock = await this.#recoverUpdateGapMutex.lock();
|
|
212
602
|
if (wasRecoveringUpdateGap) {
|
|
213
|
-
|
|
603
|
+
this.#LrecoverUpdateGap.debug(`update gap was just recovered [${source}]`);
|
|
214
604
|
unlock();
|
|
215
605
|
return;
|
|
216
606
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
607
|
+
this.#recoveringUpdateGap = true;
|
|
608
|
+
this.#LrecoverUpdateGap.debug(`recovering from update gap [${source}]`);
|
|
609
|
+
this.#c.setConnectionState("updating");
|
|
220
610
|
try {
|
|
221
611
|
let retryIn = 5;
|
|
222
|
-
let state = await
|
|
612
|
+
let state = await this.#getLocalState();
|
|
223
613
|
while (true) {
|
|
224
614
|
let difference;
|
|
225
615
|
try {
|
|
226
|
-
difference = await
|
|
616
|
+
difference = await this.#c.invoke({ _: "updates.getDifference", pts: state.pts, date: state.date, qts: state.qts ?? 0 });
|
|
227
617
|
}
|
|
228
618
|
catch (err) {
|
|
229
619
|
if (err instanceof PersistentTimestampInvalid) {
|
|
@@ -242,32 +632,32 @@ export class UpdateManager {
|
|
|
242
632
|
this.processChats(difference.chats, difference);
|
|
243
633
|
this.processUsers(difference.users, difference);
|
|
244
634
|
for (const message of difference.new_messages) {
|
|
245
|
-
await
|
|
635
|
+
await this.#processUpdates({ _: "updateNewMessage", message, pts: 0, pts_count: 0 }, false);
|
|
246
636
|
}
|
|
247
637
|
for (const update of difference.other_updates) {
|
|
248
|
-
await
|
|
638
|
+
await this.#processUpdates(update, false);
|
|
249
639
|
}
|
|
250
640
|
if (Api.is("updates.difference", difference)) {
|
|
251
|
-
await
|
|
252
|
-
|
|
641
|
+
await this.#setState(difference.state);
|
|
642
|
+
this.#LrecoverUpdateGap.debug("recovered from update gap");
|
|
253
643
|
break;
|
|
254
644
|
}
|
|
255
645
|
else if (Api.is("updates.differenceSlice", difference)) {
|
|
256
646
|
state = difference.intermediate_state;
|
|
257
|
-
await
|
|
647
|
+
await this.#setState(state);
|
|
258
648
|
}
|
|
259
649
|
else {
|
|
260
650
|
unreachable();
|
|
261
651
|
}
|
|
262
652
|
}
|
|
263
653
|
else if (Api.is("updates.differenceTooLong", difference)) {
|
|
264
|
-
await
|
|
654
|
+
await this.#c.messageStorage.deleteMessages();
|
|
265
655
|
state.pts = difference.pts;
|
|
266
|
-
|
|
656
|
+
this.#LrecoverUpdateGap.debug("received differenceTooLong");
|
|
267
657
|
}
|
|
268
658
|
else if (Api.is("updates.differenceEmpty", difference)) {
|
|
269
|
-
await
|
|
270
|
-
|
|
659
|
+
await this.#setUpdateStateDate(difference.date);
|
|
660
|
+
this.#LrecoverUpdateGap.debug("there was no update gap");
|
|
271
661
|
break;
|
|
272
662
|
}
|
|
273
663
|
else {
|
|
@@ -276,43 +666,309 @@ export class UpdateManager {
|
|
|
276
666
|
}
|
|
277
667
|
}
|
|
278
668
|
catch (err) {
|
|
279
|
-
|
|
669
|
+
this.#LrecoverUpdateGap.error(err);
|
|
280
670
|
}
|
|
281
671
|
finally {
|
|
282
672
|
unlock();
|
|
283
|
-
|
|
284
|
-
|
|
673
|
+
this.#c.resetConnectionState();
|
|
674
|
+
this.#recoveringUpdateGap = false;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
async #recoverChannelUpdateGap(channelId, source) {
|
|
678
|
+
let lastTimeout = 10;
|
|
679
|
+
this.#LrecoverChannelUpdateGap.debug(`recovering channel update gap [${channelId}, ${source}]`);
|
|
680
|
+
const pts_ = await this.#c.storage.channelPts.get([channelId]);
|
|
681
|
+
let pts = pts_ === null ? 1 : pts_;
|
|
682
|
+
let retryIn = 5;
|
|
683
|
+
while (true) {
|
|
684
|
+
const { access_hash } = await this.#c.getInputPeer(ZERO_CHANNEL_ID + -Number(channelId)).then((v) => Api.as("inputPeerChannel", v));
|
|
685
|
+
let difference;
|
|
686
|
+
try {
|
|
687
|
+
difference = await this.#c.invoke({
|
|
688
|
+
_: "updates.getChannelDifference",
|
|
689
|
+
pts,
|
|
690
|
+
channel: { _: "inputChannel", channel_id: channelId, access_hash },
|
|
691
|
+
filter: { _: "channelMessagesFilterEmpty" },
|
|
692
|
+
limit: this.#c.storage.isBot ? CHANNEL_DIFFERENCE_LIMIT_BOT : CHANNEL_DIFFERENCE_LIMIT_USER,
|
|
693
|
+
});
|
|
694
|
+
lastTimeout = difference.timeout ?? lastTimeout;
|
|
695
|
+
}
|
|
696
|
+
catch (err) {
|
|
697
|
+
if (err instanceof PersistentTimestampInvalid) {
|
|
698
|
+
await delay(retryIn * SECOND);
|
|
699
|
+
retryIn += 5;
|
|
700
|
+
if (retryIn > 60) {
|
|
701
|
+
retryIn = 60;
|
|
702
|
+
}
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
throw err;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (Api.is("updates.channelDifference", difference)) {
|
|
710
|
+
this.processChats(difference.chats, difference);
|
|
711
|
+
this.processUsers(difference.users, difference);
|
|
712
|
+
for (const message of difference.new_messages) {
|
|
713
|
+
await this.#processUpdates({ _: "updateNewChannelMessage", message, pts: 0, pts_count: 0 }, false);
|
|
714
|
+
}
|
|
715
|
+
for (const update of difference.other_updates) {
|
|
716
|
+
await this.#processUpdates(update, false);
|
|
717
|
+
}
|
|
718
|
+
this.#c.storage.channelPts.set([channelId], difference.pts);
|
|
719
|
+
this.#LrecoverChannelUpdateGap.debug(`recovered from update gap [${channelId}, ${source}]`, channelId, source);
|
|
720
|
+
break;
|
|
721
|
+
}
|
|
722
|
+
else if (Api.is("updates.channelDifferenceTooLong", difference)) {
|
|
723
|
+
// TODO: invalidate messages
|
|
724
|
+
this.#LrecoverChannelUpdateGap.debug("received channelDifferenceTooLong");
|
|
725
|
+
this.processChats(difference.chats, difference);
|
|
726
|
+
this.processUsers(difference.users, difference);
|
|
727
|
+
for (const message of difference.messages) {
|
|
728
|
+
await this.#processUpdates({ _: "updateNewChannelMessage", message, pts: 0, pts_count: 0 }, false);
|
|
729
|
+
}
|
|
730
|
+
const pts_ = Api.as("dialog", difference.dialog).pts;
|
|
731
|
+
if (pts_ !== undefined) {
|
|
732
|
+
pts = pts_;
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
unreachable();
|
|
736
|
+
}
|
|
737
|
+
this.#LrecoverChannelUpdateGap.debug("processed channelDifferenceTooLong");
|
|
738
|
+
}
|
|
739
|
+
else if (Api.is("updates.channelDifferenceEmpty", difference)) {
|
|
740
|
+
this.#LrecoverChannelUpdateGap.debug("there was no update gap");
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return lastTimeout;
|
|
745
|
+
}
|
|
746
|
+
#handleUpdatesSet = new Set();
|
|
747
|
+
async #handleStoredUpdates(boxId) {
|
|
748
|
+
if (this.#handleUpdatesSet.has(boxId)) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
this.#handleUpdatesSet.add(boxId);
|
|
752
|
+
do {
|
|
753
|
+
const maybeUpdate = await this.#c.storage.getFirstUpdate(boxId);
|
|
754
|
+
if (maybeUpdate === null) {
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
const [key, update] = maybeUpdate;
|
|
758
|
+
for (let i = 0; i < 100; ++i) {
|
|
759
|
+
try {
|
|
760
|
+
const handle = await this.#handleUpdate(update);
|
|
761
|
+
handle: for (let i = 0; i < 2; ++i) {
|
|
762
|
+
try {
|
|
763
|
+
await handle();
|
|
764
|
+
break handle;
|
|
765
|
+
}
|
|
766
|
+
catch {
|
|
767
|
+
continue handle;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
}
|
|
772
|
+
catch (err) {
|
|
773
|
+
this.#L$handleUpdate.error(err);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
await this.#c.storage.set(key, null);
|
|
777
|
+
} while (true);
|
|
778
|
+
this.#handleUpdatesSet.delete(boxId);
|
|
779
|
+
}
|
|
780
|
+
#handleUpdate(update) {
|
|
781
|
+
const handler = this.#updateHandler;
|
|
782
|
+
if (handler) {
|
|
783
|
+
return handler(update);
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
return Promise.resolve(() => Promise.resolve());
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
async #needsGetDifference(update) {
|
|
790
|
+
const chatIds = this.#collectChatIds(update);
|
|
791
|
+
if (!chatIds.size) {
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
return (await Promise.all(chatIds.values().map((v) => this.#c.messageStorage.peers.get([v])))).some((v) => !v);
|
|
795
|
+
}
|
|
796
|
+
#collectChatIds(object) {
|
|
797
|
+
const chatIds = new Set();
|
|
798
|
+
if (Api.is("messageFwdHeader", object)) {
|
|
799
|
+
if (object.from_id) {
|
|
800
|
+
chatIds.add(peerToChatId(object.from_id));
|
|
801
|
+
}
|
|
802
|
+
if (object.saved_from_peer) {
|
|
803
|
+
chatIds.add(peerToChatId(object.saved_from_peer));
|
|
804
|
+
}
|
|
805
|
+
return chatIds;
|
|
806
|
+
}
|
|
807
|
+
if (Api.isOfEnum("MessageMedia", object)) {
|
|
808
|
+
switch (object._) {
|
|
809
|
+
case "messageMediaContact":
|
|
810
|
+
if (object.user_id) {
|
|
811
|
+
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.user_id }));
|
|
812
|
+
}
|
|
813
|
+
break;
|
|
814
|
+
case "messageMediaStory":
|
|
815
|
+
chatIds.add(peerToChatId(object.peer));
|
|
816
|
+
break;
|
|
817
|
+
case "messageMediaGiveaway":
|
|
818
|
+
for (const chatId of object.channels.map((v) => peerToChatId({ _: "peerChannel", channel_id: v }))) {
|
|
819
|
+
chatIds.add(chatId);
|
|
820
|
+
}
|
|
821
|
+
break;
|
|
822
|
+
case "messageMediaGiveawayResults":
|
|
823
|
+
chatIds.add(peerToChatId({ _: "peerChannel", channel_id: object.channel_id }));
|
|
824
|
+
for (const chatId of object.winners.map((user_id) => peerToChatId({ _: "peerUser", user_id }))) {
|
|
825
|
+
chatIds.add(chatId);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
return chatIds;
|
|
829
|
+
}
|
|
830
|
+
// messsages
|
|
831
|
+
if (!("message" in object)) {
|
|
832
|
+
return chatIds;
|
|
833
|
+
}
|
|
834
|
+
if (Api.is("messageEmpty", object.message)) {
|
|
835
|
+
return chatIds;
|
|
836
|
+
}
|
|
837
|
+
chatIds.add(peerToChatId(object.message.peer_id));
|
|
838
|
+
if (object.message.from_id) {
|
|
839
|
+
chatIds.add(peerToChatId(object.message.from_id));
|
|
840
|
+
}
|
|
841
|
+
if (Api.is("messageService", object.message)) {
|
|
842
|
+
switch (object.message.action._) {
|
|
843
|
+
case "messageActionChatCreate":
|
|
844
|
+
case "messageActionChatAddUser":
|
|
845
|
+
case "messageActionInviteToGroupCall":
|
|
846
|
+
for (const user_id of object.message.action.users) {
|
|
847
|
+
chatIds.add(peerToChatId({ _: "peerUser", user_id }));
|
|
848
|
+
}
|
|
849
|
+
break;
|
|
850
|
+
case "messageActionChatDeleteUser":
|
|
851
|
+
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.action.user_id }));
|
|
852
|
+
break;
|
|
853
|
+
case "messageActionChatMigrateTo":
|
|
854
|
+
chatIds.add(peerToChatId({ _: "peerChannel", channel_id: object.message.action.channel_id }));
|
|
855
|
+
break;
|
|
856
|
+
case "messageActionChannelMigrateFrom":
|
|
857
|
+
chatIds.add(peerToChatId({ _: "peerChat", chat_id: object.message.action.chat_id }));
|
|
858
|
+
break;
|
|
859
|
+
case "messageActionConferenceCall":
|
|
860
|
+
if (object.message.action.other_participants) {
|
|
861
|
+
for (const participant of object.message.action.other_participants) {
|
|
862
|
+
chatIds.add(peerToChatId(participant));
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
break;
|
|
866
|
+
case "messageActionPaymentRefunded":
|
|
867
|
+
chatIds.add(peerToChatId(object.message.action.peer));
|
|
868
|
+
break;
|
|
869
|
+
case "messageActionGiftCode":
|
|
870
|
+
if (object.message.action.boost_peer) {
|
|
871
|
+
chatIds.add(peerToChatId(object.message.action.boost_peer));
|
|
872
|
+
}
|
|
873
|
+
break;
|
|
874
|
+
case "messageActionRequestedPeer":
|
|
875
|
+
if (!this.#c.storage.isBot) {
|
|
876
|
+
for (const peer of object.message.action.peers) {
|
|
877
|
+
chatIds.add(peerToChatId(peer));
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
break;
|
|
881
|
+
case "messageActionSetMessagesTTL":
|
|
882
|
+
if (object.message.action.auto_setting_from) {
|
|
883
|
+
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.action.auto_setting_from }));
|
|
884
|
+
}
|
|
885
|
+
}
|
|
285
886
|
}
|
|
887
|
+
else {
|
|
888
|
+
if (object.message.reply_to) {
|
|
889
|
+
switch (object.message.reply_to._) {
|
|
890
|
+
case "messageReplyHeader":
|
|
891
|
+
if (object.message.reply_to.reply_to_peer_id) {
|
|
892
|
+
chatIds.add(peerToChatId(object.message.reply_to.reply_to_peer_id));
|
|
893
|
+
}
|
|
894
|
+
if (object.message.reply_to.reply_from) {
|
|
895
|
+
for (const chatId of this.#collectChatIds(object.message.reply_to.reply_from)) {
|
|
896
|
+
chatIds.add(chatId);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
if (object.message.reply_to.quote_entities) {
|
|
900
|
+
for (const chatId of this.#collectChatIdsFromEntities(object.message.reply_to.quote_entities)) {
|
|
901
|
+
chatIds.add(chatId);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (object.message.reply_to.reply_media) {
|
|
905
|
+
for (const chatId of this.#collectChatIds(object.message.reply_to.reply_media)) {
|
|
906
|
+
chatIds.add(chatId);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
break;
|
|
910
|
+
case "messageReplyStoryHeader":
|
|
911
|
+
chatIds.add(peerToChatId(object.message.reply_to.peer));
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
if (object.message.fwd_from) {
|
|
915
|
+
for (const chatId of this.#collectChatIds(object.message.fwd_from)) {
|
|
916
|
+
chatIds.add(chatId);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (object.message.via_bot_id) {
|
|
920
|
+
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.via_bot_id }));
|
|
921
|
+
}
|
|
922
|
+
if (object.message.entities) {
|
|
923
|
+
for (const chatId of this.#collectChatIdsFromEntities(object.message.entities)) {
|
|
924
|
+
chatIds.add(chatId);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
if (object.message.media) {
|
|
928
|
+
for (const chatId of this.#collectChatIds(object.message.media)) {
|
|
929
|
+
chatIds.add(chatId);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return chatIds;
|
|
934
|
+
}
|
|
935
|
+
#collectChatIdsFromEntities(entities) {
|
|
936
|
+
const chatIds = new Array();
|
|
937
|
+
for (const user_id of entities.filter((v) => Api.is("messageEntityMentionName", v)).map((v) => v.user_id)) {
|
|
938
|
+
chatIds.push(peerToChatId({ _: "peerUser", user_id }));
|
|
939
|
+
}
|
|
940
|
+
return chatIds;
|
|
286
941
|
}
|
|
287
942
|
setUpdateHandler(handler) {
|
|
288
|
-
|
|
943
|
+
this.#updateHandler = handler;
|
|
289
944
|
}
|
|
945
|
+
#openChats = new Map();
|
|
290
946
|
async openChat(chatId, params) {
|
|
291
947
|
if (params?.timeout !== undefined && (params.timeout < 0 || params?.timeout === 0)) {
|
|
292
948
|
throw new InputError("An invalid timeout was specified.");
|
|
293
949
|
}
|
|
294
|
-
const channel = await
|
|
950
|
+
const channel = await this.#c.getInputChannel(chatId);
|
|
295
951
|
const channelId = channel.channel_id;
|
|
296
|
-
if (
|
|
952
|
+
if (this.#openChats.has(channelId)) {
|
|
297
953
|
return;
|
|
298
954
|
}
|
|
299
955
|
const controller = new AbortController();
|
|
300
956
|
const promise = Promise.resolve().then(async () => {
|
|
301
|
-
const logger =
|
|
957
|
+
const logger = this.#LopenChat.branch(Api.peerToChatId(channel) + "");
|
|
302
958
|
while (true) {
|
|
303
|
-
if (
|
|
959
|
+
if (this.#c.isDisconnected()) {
|
|
304
960
|
logger.debug("disconnected, stopping the loop");
|
|
305
|
-
|
|
961
|
+
this.#openChats.delete(channelId);
|
|
306
962
|
break;
|
|
307
963
|
}
|
|
308
|
-
if (!
|
|
964
|
+
if (!this.#openChats.has(channelId)) {
|
|
309
965
|
const aborted = controller.signal.aborted;
|
|
310
966
|
logger.debug(`closed${(aborted ? " (aborted)" : "")}, stopping the loop`);
|
|
311
967
|
break;
|
|
312
968
|
}
|
|
313
969
|
try {
|
|
314
970
|
const Ti = Date.now();
|
|
315
|
-
const otherTimeout = await
|
|
971
|
+
const otherTimeout = await this.#recoverChannelUpdateGap(channelId, "openChat");
|
|
316
972
|
const timeout = params?.timeout ?? otherTimeout;
|
|
317
973
|
const dT = Date.now() - Ti;
|
|
318
974
|
const delayMs = Math.max(timeout * SECOND - dT, 0);
|
|
@@ -322,20 +978,20 @@ export class UpdateManager {
|
|
|
322
978
|
}
|
|
323
979
|
}
|
|
324
980
|
catch (err) {
|
|
325
|
-
if (
|
|
981
|
+
if (this.#c.isDisconnected()) {
|
|
326
982
|
continue; // breaks the loop
|
|
327
983
|
}
|
|
328
|
-
|
|
984
|
+
this.#LopenChat.error("an unexpected error occurred:", err);
|
|
329
985
|
}
|
|
330
986
|
}
|
|
331
987
|
});
|
|
332
|
-
|
|
988
|
+
this.#openChats.set(channelId, { controller, promise });
|
|
333
989
|
}
|
|
334
990
|
async closeChat(chatId) {
|
|
335
|
-
const { channel_id } = await
|
|
336
|
-
const openChat =
|
|
991
|
+
const { channel_id } = await this.#c.getInputChannel(chatId);
|
|
992
|
+
const openChat = this.#openChats.get(channel_id);
|
|
337
993
|
if (openChat) {
|
|
338
|
-
|
|
994
|
+
this.#openChats.delete(channel_id);
|
|
339
995
|
openChat.controller.abort();
|
|
340
996
|
}
|
|
341
997
|
else {
|
|
@@ -343,661 +999,10 @@ export class UpdateManager {
|
|
|
343
999
|
}
|
|
344
1000
|
}
|
|
345
1001
|
closeAllChats() {
|
|
346
|
-
for (const [channelId, openChat] of
|
|
347
|
-
|
|
1002
|
+
for (const [channelId, openChat] of this.#openChats.entries()) {
|
|
1003
|
+
this.#openChats.delete(channelId);
|
|
348
1004
|
openChat.controller.abort();
|
|
349
1005
|
}
|
|
350
1006
|
}
|
|
351
1007
|
}
|
|
352
|
-
_a = UpdateManager
|
|
353
|
-
if (typeof __classPrivateFieldGet(this, _UpdateManager_c, "f").dropPendingUpdates === "boolean") {
|
|
354
|
-
return __classPrivateFieldGet(this, _UpdateManager_c, "f").dropPendingUpdates;
|
|
355
|
-
}
|
|
356
|
-
if (__classPrivateFieldGet(this, _UpdateManager_defaultDropPendingUpdates, "f") === null) {
|
|
357
|
-
__classPrivateFieldSet(this, _UpdateManager_defaultDropPendingUpdates, __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.isBot, "f");
|
|
358
|
-
}
|
|
359
|
-
return __classPrivateFieldGet(this, _UpdateManager_defaultDropPendingUpdates, "f");
|
|
360
|
-
}, _UpdateManager_getState = async function _UpdateManager_getState() {
|
|
361
|
-
if (__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_mustDropPendingUpdates).call(this)) {
|
|
362
|
-
return __classPrivateFieldGet(this, _UpdateManager_state, "f") ?? null;
|
|
363
|
-
}
|
|
364
|
-
if (__classPrivateFieldGet(this, _UpdateManager_state, "f") !== null) {
|
|
365
|
-
return __classPrivateFieldGet(this, _UpdateManager_state, "f");
|
|
366
|
-
}
|
|
367
|
-
const state = await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.getState();
|
|
368
|
-
return __classPrivateFieldSet(this, _UpdateManager_state, state, "f");
|
|
369
|
-
}, _UpdateManager_setState = async function _UpdateManager_setState(state) {
|
|
370
|
-
__classPrivateFieldSet(this, _UpdateManager_state, state, "f");
|
|
371
|
-
if (!__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_mustDropPendingUpdates).call(this)) {
|
|
372
|
-
await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.setState(state);
|
|
373
|
-
}
|
|
374
|
-
}, _UpdateManager_extractMessages = function _UpdateManager_extractMessages(context) {
|
|
375
|
-
const messages = new Array();
|
|
376
|
-
if (Array.isArray(context)) {
|
|
377
|
-
for (const item of context) {
|
|
378
|
-
messages.push(...__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_extractMessages).call(this, item));
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
else if (Api.isOneOf(["updates", "updatesCombined"], context)) {
|
|
382
|
-
messages.push(...__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_extractMessages).call(this, context.updates));
|
|
383
|
-
}
|
|
384
|
-
else if (Api.isOneOf(["updates.difference", "updates.differenceSlice", "updates.channelDifference"], context)) {
|
|
385
|
-
for (const message of context.new_messages) {
|
|
386
|
-
if (Api.is("message", message)) {
|
|
387
|
-
messages.push(message);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
messages.push(...__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_extractMessages).call(this, context.other_updates));
|
|
391
|
-
}
|
|
392
|
-
else if (Api.isOneOf(["updateNewMessage", "updateNewChannelMessage", "updateEditMessage", "updateEditChannelMessage", "updateBotNewBusinessMessage", "updateBotNewBusinessMessage"], context)) {
|
|
393
|
-
if (Api.is("message", context.message)) {
|
|
394
|
-
messages.push(context.message);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
else if (Api.is("message", context)) {
|
|
398
|
-
messages.push(context);
|
|
399
|
-
}
|
|
400
|
-
else if (context !== null && typeof context === "object" && "messages" in context && Array.isArray(context.messages)) {
|
|
401
|
-
for (const message of context.messages) {
|
|
402
|
-
if (Api.is("message", message)) {
|
|
403
|
-
messages.push(message);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return messages;
|
|
408
|
-
}, _UpdateManager_extractMinPeerReferences = function _UpdateManager_extractMinPeerReferences(context) {
|
|
409
|
-
const minPeerReferences = new Array();
|
|
410
|
-
const messages = __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_extractMessages).call(this, context);
|
|
411
|
-
for (const message of messages) {
|
|
412
|
-
if (!message.from_id) {
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
minPeerReferences.push({ chatId: Api.peerToChatId(message.peer_id), senderId: Api.peerToChatId(message.from_id), messageId: message.id });
|
|
416
|
-
}
|
|
417
|
-
return minPeerReferences;
|
|
418
|
-
}, _UpdateManager_getChannelPtsWithDropPendingUpdatesCheck = async function _UpdateManager_getChannelPtsWithDropPendingUpdatesCheck(channelId) {
|
|
419
|
-
if (!(__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_mustDropPendingUpdates).call(this))) {
|
|
420
|
-
return await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.get([channelId]);
|
|
421
|
-
}
|
|
422
|
-
const first = !__classPrivateFieldGet(this, _UpdateManager_nonFirst, "f").has(channelId);
|
|
423
|
-
if (first) {
|
|
424
|
-
__classPrivateFieldGet(this, _UpdateManager_nonFirst, "f").add(channelId);
|
|
425
|
-
return null;
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
return await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.get([channelId]);
|
|
429
|
-
}
|
|
430
|
-
}, _UpdateManager_checkGap = async function _UpdateManager_checkGap(pts, ptsCount) {
|
|
431
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
432
|
-
if (localState.pts + ptsCount < pts) {
|
|
433
|
-
await this.recoverUpdateGap("processUpdates[pts]");
|
|
434
|
-
}
|
|
435
|
-
}, _UpdateManager_checkGapQts = async function _UpdateManager_checkGapQts(qts) {
|
|
436
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
437
|
-
if (localState.qts + _a.QTS_COUNT < qts) {
|
|
438
|
-
await this.recoverUpdateGap("processUpdates[qts]");
|
|
439
|
-
}
|
|
440
|
-
}, _UpdateManager_checkChannelGap = async function _UpdateManager_checkChannelGap(channelId, pts, ptsCount) {
|
|
441
|
-
let localPts = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getChannelPtsWithDropPendingUpdatesCheck).call(this, channelId);
|
|
442
|
-
if (!localPts) {
|
|
443
|
-
localPts = pts - ptsCount;
|
|
444
|
-
}
|
|
445
|
-
if (localPts + ptsCount < pts) {
|
|
446
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_recoverChannelUpdateGap).call(this, channelId, "processUpdates");
|
|
447
|
-
}
|
|
448
|
-
}, _UpdateManager_processChannelPtsUpdateInner = async function _UpdateManager_processChannelPtsUpdateInner(update, checkGap) {
|
|
449
|
-
const channelId = Api.is("updateNewChannelMessage", update) || Api.is("updateEditChannelMessage", update) ? Api.as("peerChannel", update.message.peer_id).channel_id : update.channel_id;
|
|
450
|
-
if (Api.is("updateChannelTooLong", update)) {
|
|
451
|
-
if (update.pts !== undefined) {
|
|
452
|
-
__classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.set([channelId], update.pts);
|
|
453
|
-
}
|
|
454
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_recoverChannelUpdateGap).call(this, channelId, "updateChannelTooLong");
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
if (update.pts !== 0) {
|
|
458
|
-
const ptsCount = update.pts_count;
|
|
459
|
-
if (checkGap) {
|
|
460
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_checkChannelGap).call(this, channelId, update.pts, ptsCount);
|
|
461
|
-
}
|
|
462
|
-
let currentPts = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getChannelPtsWithDropPendingUpdatesCheck).call(this, channelId);
|
|
463
|
-
currentPts ??= update.pts - ptsCount;
|
|
464
|
-
if (currentPts + ptsCount > update.pts) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (__classPrivateFieldGet(this, _UpdateManager_c, "f").guaranteeUpdateDelivery) {
|
|
469
|
-
await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.setUpdate(channelId, update);
|
|
470
|
-
}
|
|
471
|
-
if (update.pts !== 0) {
|
|
472
|
-
__classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.set([channelId], update.pts);
|
|
473
|
-
}
|
|
474
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_queueUpdate).call(this, update, channelId, true);
|
|
475
|
-
}, _UpdateManager_queueUpdate = function _UpdateManager_queueUpdate(update, boxId, pts) {
|
|
476
|
-
this.getHandleUpdateQueue(boxId).add(async () => {
|
|
477
|
-
if (__classPrivateFieldGet(this, _UpdateManager_c, "f").guaranteeUpdateDelivery && pts) {
|
|
478
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_handleStoredUpdates).call(this, boxId);
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
await (await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_handleUpdate).call(this, update))();
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
}, _UpdateManager_processChannelPtsUpdate = function _UpdateManager_processChannelPtsUpdate(update, checkGap) {
|
|
485
|
-
const channelId = Api.is("updateNewChannelMessage", update) || Api.is("updateEditChannelMessage", update) ? Api.as("peerChannel", update.message.peer_id).channel_id : update.channel_id;
|
|
486
|
-
let queue = __classPrivateFieldGet(this, _UpdateManager_channelUpdateQueues, "f").get(channelId);
|
|
487
|
-
if (queue === undefined) {
|
|
488
|
-
queue = new Queue(`channelUpdates-${channelId}`);
|
|
489
|
-
__classPrivateFieldGet(this, _UpdateManager_channelUpdateQueues, "f").set(channelId, queue);
|
|
490
|
-
}
|
|
491
|
-
queue.add(async () => {
|
|
492
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processChannelPtsUpdateInner).call(this, update, checkGap);
|
|
493
|
-
});
|
|
494
|
-
}, _UpdateManager_processPtsUpdateInner = async function _UpdateManager_processPtsUpdateInner(update, checkGap) {
|
|
495
|
-
if (update.pts !== 0 && checkGap) {
|
|
496
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_checkGap).call(this, update.pts, update.pts_count);
|
|
497
|
-
if (await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_needsGetDifference).call(this, update)) {
|
|
498
|
-
await this.recoverUpdateGap("needsGetDifference");
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
502
|
-
if (update.pts !== 0 && localState.pts + update.pts_count > update.pts) {
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
if (__classPrivateFieldGet(this, _UpdateManager_c, "f").guaranteeUpdateDelivery) {
|
|
506
|
-
await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.setUpdate(_a.MAIN_BOX_ID, update);
|
|
507
|
-
}
|
|
508
|
-
if (update.pts !== 0) {
|
|
509
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setUpdatePts).call(this, update.pts);
|
|
510
|
-
}
|
|
511
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_queueUpdate).call(this, update, 1n, false);
|
|
512
|
-
}, _UpdateManager_processPtsUpdate = function _UpdateManager_processPtsUpdate(update, checkGap) {
|
|
513
|
-
__classPrivateFieldGet(this, _UpdateManager_ptsUpdateQueue, "f").add(async () => {
|
|
514
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processPtsUpdateInner).call(this, update, checkGap);
|
|
515
|
-
});
|
|
516
|
-
}, _UpdateManager_processQtsUpdateInner = async function _UpdateManager_processQtsUpdateInner(update, checkGap) {
|
|
517
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
518
|
-
if (update.qts !== 0) {
|
|
519
|
-
if (checkGap) {
|
|
520
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_checkGapQts).call(this, update.qts);
|
|
521
|
-
}
|
|
522
|
-
if (localState.qts + _a.QTS_COUNT > update.qts) {
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
if (__classPrivateFieldGet(this, _UpdateManager_c, "f").guaranteeUpdateDelivery) {
|
|
527
|
-
await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.setUpdate(_a.MAIN_BOX_ID, update);
|
|
528
|
-
}
|
|
529
|
-
if (update.qts !== 0) {
|
|
530
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setUpdateQts).call(this, update.qts);
|
|
531
|
-
}
|
|
532
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_queueUpdate).call(this, update, 0n, true);
|
|
533
|
-
}, _UpdateManager_processQtsUpdate = function _UpdateManager_processQtsUpdate(update, checkGap) {
|
|
534
|
-
__classPrivateFieldGet(this, _UpdateManager_qtsUpdateQueue, "f").add(async () => {
|
|
535
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processQtsUpdateInner).call(this, update, checkGap);
|
|
536
|
-
});
|
|
537
|
-
}, _UpdateManager_processUpdates = async function _UpdateManager_processUpdates(updates_, checkGap, call = null) {
|
|
538
|
-
/// First, individual updates (Update[1]) are extracted from Updates.[2]
|
|
539
|
-
///
|
|
540
|
-
/// If an updatesTooLong[3] was received, an update gap recovery is initiated and no further action will be taken.
|
|
541
|
-
///
|
|
542
|
-
/// [1]: https://core.telegram.org/type/Update
|
|
543
|
-
/// [2]: https://core.telegram.org/type/Updates
|
|
544
|
-
/// [3]: https://core.telegram.org/constructor/updatesTooLong
|
|
545
|
-
let updates;
|
|
546
|
-
if (Api.is("updatesCombined", updates_) || Api.is("updates", updates_)) {
|
|
547
|
-
updates = updates_.updates;
|
|
548
|
-
const seq = updates_.seq;
|
|
549
|
-
const seqStart = "seq_start" in updates_ ? updates_.seq_start : updates_.seq;
|
|
550
|
-
if (checkGap) {
|
|
551
|
-
if (seqStart === 0) {
|
|
552
|
-
checkGap = false;
|
|
553
|
-
__classPrivateFieldGet(this, _UpdateManager_L$processUpdates, "f").debug("seqStart=0");
|
|
554
|
-
}
|
|
555
|
-
else {
|
|
556
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
557
|
-
const localSeq = localState.seq;
|
|
558
|
-
if (localSeq + 1 === seqStart) {
|
|
559
|
-
// The update sequence can be applied.
|
|
560
|
-
localState.seq = seq;
|
|
561
|
-
localState.date = updates_.date;
|
|
562
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setUpdateStateDate).call(this, updates_.date);
|
|
563
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
564
|
-
}
|
|
565
|
-
else if (localSeq + 1 > seqStart) {
|
|
566
|
-
// The update sequence was already applied, and must be ignored.
|
|
567
|
-
__classPrivateFieldGet(this, _UpdateManager_L$processUpdates, "f").debug("localSeq + 1 > seqStart");
|
|
568
|
-
return;
|
|
569
|
-
}
|
|
570
|
-
else if (localSeq + 1 < seqStart) {
|
|
571
|
-
// There's an updates gap that must be filled.
|
|
572
|
-
await this.recoverUpdateGap("localSeq + 1 < seqStart");
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
else if (Api.is("updateShort", updates_)) {
|
|
578
|
-
updates = [updates_.update];
|
|
579
|
-
}
|
|
580
|
-
else if (Api.is("updateShortMessage", updates_)) {
|
|
581
|
-
updates = [
|
|
582
|
-
{
|
|
583
|
-
_: "updateNewMessage",
|
|
584
|
-
message: {
|
|
585
|
-
_: "message",
|
|
586
|
-
out: updates_.out,
|
|
587
|
-
mentioned: updates_.mentioned,
|
|
588
|
-
media_unread: updates_.media_unread,
|
|
589
|
-
silent: updates_.silent,
|
|
590
|
-
id: updates_.id,
|
|
591
|
-
from_id: updates_.out ? ({ _: "peerUser", user_id: BigInt(await __classPrivateFieldGet(this, _UpdateManager_c, "f").getSelfId()) }) : ({ _: "peerUser", user_id: updates_.user_id }),
|
|
592
|
-
peer_id: { _: "peerUser", user_id: updates_.user_id },
|
|
593
|
-
message: updates_.message,
|
|
594
|
-
date: updates_.date,
|
|
595
|
-
fwd_from: updates_.fwd_from,
|
|
596
|
-
via_bot_id: updates_.via_bot_id,
|
|
597
|
-
reply_to: updates_.reply_to,
|
|
598
|
-
entities: updates_.entities,
|
|
599
|
-
ttl_period: updates_.ttl_period,
|
|
600
|
-
},
|
|
601
|
-
pts: updates_.pts,
|
|
602
|
-
pts_count: updates_.pts_count,
|
|
603
|
-
},
|
|
604
|
-
];
|
|
605
|
-
}
|
|
606
|
-
else if (Api.is("updateShortChatMessage", updates_)) {
|
|
607
|
-
updates = [
|
|
608
|
-
{
|
|
609
|
-
_: "updateNewMessage",
|
|
610
|
-
message: {
|
|
611
|
-
_: "message",
|
|
612
|
-
mentioned: updates_.mentioned,
|
|
613
|
-
media_unread: updates_.media_unread,
|
|
614
|
-
silent: updates_.silent,
|
|
615
|
-
id: updates_.id,
|
|
616
|
-
from_id: { _: "peerUser", user_id: updates_.from_id },
|
|
617
|
-
peer_id: { _: "peerChat", chat_id: updates_.chat_id },
|
|
618
|
-
fwd_from: updates_.fwd_from,
|
|
619
|
-
via_bot_id: updates_.via_bot_id,
|
|
620
|
-
reply_to: updates_.reply_to,
|
|
621
|
-
date: updates_.date,
|
|
622
|
-
message: updates_.message,
|
|
623
|
-
entities: updates_.entities,
|
|
624
|
-
ttl_period: updates_.ttl_period,
|
|
625
|
-
},
|
|
626
|
-
pts: updates_.pts,
|
|
627
|
-
pts_count: updates_.pts_count,
|
|
628
|
-
},
|
|
629
|
-
];
|
|
630
|
-
}
|
|
631
|
-
else if (Api.is("updateShortSentMessage", updates_)) {
|
|
632
|
-
if (!Api.is("messages.sendMessage", call)) {
|
|
633
|
-
unreachable();
|
|
634
|
-
}
|
|
635
|
-
updates = [{
|
|
636
|
-
_: "updateNewMessage",
|
|
637
|
-
message: {
|
|
638
|
-
_: "message",
|
|
639
|
-
out: updates_.out,
|
|
640
|
-
silent: call.silent,
|
|
641
|
-
id: updates_.id,
|
|
642
|
-
from_id: { _: "peerUser", user_id: BigInt(await __classPrivateFieldGet(this, _UpdateManager_c, "f").getSelfId()) },
|
|
643
|
-
peer_id: Api.inputPeerToPeer(call.peer),
|
|
644
|
-
message: call.message,
|
|
645
|
-
media: updates_.media,
|
|
646
|
-
date: updates_.date,
|
|
647
|
-
// reply_to: call.reply_to, // TODO?
|
|
648
|
-
entities: updates_.entities,
|
|
649
|
-
ttl_period: updates_.ttl_period,
|
|
650
|
-
},
|
|
651
|
-
pts: updates_.pts,
|
|
652
|
-
pts_count: updates_.pts_count,
|
|
653
|
-
}];
|
|
654
|
-
}
|
|
655
|
-
else if (Api.is("updatesTooLong", updates_)) {
|
|
656
|
-
await this.recoverUpdateGap("updatesTooLong");
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
else if (Api.isOfEnum("Update", updates_)) {
|
|
660
|
-
updates = [updates_];
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
unreachable();
|
|
664
|
-
}
|
|
665
|
-
/// We process the updates when we are sure there is no gap.
|
|
666
|
-
if (Api.is("updates", updates_) || Api.is("updatesCombined", updates_)) {
|
|
667
|
-
this.processChats(updates_.chats, updates_);
|
|
668
|
-
this.processUsers(updates_.users, updates_);
|
|
669
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setUpdateStateDate).call(this, updates_.date);
|
|
670
|
-
}
|
|
671
|
-
else if (Api.isOneOf([
|
|
672
|
-
"updateShort",
|
|
673
|
-
"updateShortMessage",
|
|
674
|
-
"updateShortChatMessage",
|
|
675
|
-
"updateShortSentMessage",
|
|
676
|
-
], updates_)) {
|
|
677
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setUpdateStateDate).call(this, updates_.date);
|
|
678
|
-
}
|
|
679
|
-
for (const update of updates) {
|
|
680
|
-
if (Api.is("updatePtsChanged", update)) {
|
|
681
|
-
await this.fetchState("updatePtsChanged");
|
|
682
|
-
if (__classPrivateFieldGet(this, _UpdateManager_updateState, "f")) {
|
|
683
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, __classPrivateFieldGet(this, _UpdateManager_updateState, "f"));
|
|
684
|
-
}
|
|
685
|
-
else {
|
|
686
|
-
unreachable();
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
else if (_a.isPtsUpdate(update)) {
|
|
690
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processPtsUpdate).call(this, update, checkGap);
|
|
691
|
-
}
|
|
692
|
-
else if (_a.isChannelPtsUpdate(update)) {
|
|
693
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processChannelPtsUpdate).call(this, update, checkGap);
|
|
694
|
-
}
|
|
695
|
-
else if (_a.isQtsUpdate(update)) {
|
|
696
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processQtsUpdate).call(this, update, checkGap);
|
|
697
|
-
}
|
|
698
|
-
else {
|
|
699
|
-
__classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_queueUpdate).call(this, update, 0n, false);
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
}, _UpdateManager_setUpdateStateDate = async function _UpdateManager_setUpdateStateDate(date) {
|
|
703
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
704
|
-
localState.date = date;
|
|
705
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
706
|
-
}, _UpdateManager_setUpdatePts = async function _UpdateManager_setUpdatePts(pts) {
|
|
707
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
708
|
-
localState.pts = pts;
|
|
709
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
710
|
-
}, _UpdateManager_setUpdateQts = async function _UpdateManager_setUpdateQts(qts) {
|
|
711
|
-
const localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getLocalState).call(this);
|
|
712
|
-
localState.qts = qts;
|
|
713
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
714
|
-
}, _UpdateManager_getLocalState = async function _UpdateManager_getLocalState() {
|
|
715
|
-
let localState = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_getState).call(this);
|
|
716
|
-
if (!localState) {
|
|
717
|
-
if (__classPrivateFieldGet(this, _UpdateManager_updateState, "f")) {
|
|
718
|
-
localState = __classPrivateFieldGet(this, _UpdateManager_updateState, "f");
|
|
719
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
720
|
-
}
|
|
721
|
-
else {
|
|
722
|
-
await this.fetchState("getLocalState");
|
|
723
|
-
if (__classPrivateFieldGet(this, _UpdateManager_updateState, "f")) {
|
|
724
|
-
localState = __classPrivateFieldGet(this, _UpdateManager_updateState, "f");
|
|
725
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_setState).call(this, localState);
|
|
726
|
-
}
|
|
727
|
-
else {
|
|
728
|
-
unreachable();
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
return localState;
|
|
733
|
-
}, _UpdateManager_recoverChannelUpdateGap = async function _UpdateManager_recoverChannelUpdateGap(channelId, source) {
|
|
734
|
-
let lastTimeout = 10;
|
|
735
|
-
__classPrivateFieldGet(this, _UpdateManager_LrecoverChannelUpdateGap, "f").debug(`recovering channel update gap [${channelId}, ${source}]`);
|
|
736
|
-
const pts_ = await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.get([channelId]);
|
|
737
|
-
let pts = pts_ === null ? 1 : pts_;
|
|
738
|
-
let retryIn = 5;
|
|
739
|
-
while (true) {
|
|
740
|
-
const { access_hash } = await __classPrivateFieldGet(this, _UpdateManager_c, "f").getInputPeer(ZERO_CHANNEL_ID + -Number(channelId)).then((v) => Api.as("inputPeerChannel", v));
|
|
741
|
-
let difference;
|
|
742
|
-
try {
|
|
743
|
-
difference = await __classPrivateFieldGet(this, _UpdateManager_c, "f").invoke({
|
|
744
|
-
_: "updates.getChannelDifference",
|
|
745
|
-
pts,
|
|
746
|
-
channel: { _: "inputChannel", channel_id: channelId, access_hash },
|
|
747
|
-
filter: { _: "channelMessagesFilterEmpty" },
|
|
748
|
-
limit: __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.isBot ? CHANNEL_DIFFERENCE_LIMIT_BOT : CHANNEL_DIFFERENCE_LIMIT_USER,
|
|
749
|
-
});
|
|
750
|
-
lastTimeout = difference.timeout ?? lastTimeout;
|
|
751
|
-
}
|
|
752
|
-
catch (err) {
|
|
753
|
-
if (err instanceof PersistentTimestampInvalid) {
|
|
754
|
-
await delay(retryIn * SECOND);
|
|
755
|
-
retryIn += 5;
|
|
756
|
-
if (retryIn > 60) {
|
|
757
|
-
retryIn = 60;
|
|
758
|
-
}
|
|
759
|
-
continue;
|
|
760
|
-
}
|
|
761
|
-
else {
|
|
762
|
-
throw err;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
if (Api.is("updates.channelDifference", difference)) {
|
|
766
|
-
this.processChats(difference.chats, difference);
|
|
767
|
-
this.processUsers(difference.users, difference);
|
|
768
|
-
for (const message of difference.new_messages) {
|
|
769
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processUpdates).call(this, { _: "updateNewChannelMessage", message, pts: 0, pts_count: 0 }, false);
|
|
770
|
-
}
|
|
771
|
-
for (const update of difference.other_updates) {
|
|
772
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processUpdates).call(this, update, false);
|
|
773
|
-
}
|
|
774
|
-
__classPrivateFieldGet(this, _UpdateManager_c, "f").storage.channelPts.set([channelId], difference.pts);
|
|
775
|
-
__classPrivateFieldGet(this, _UpdateManager_LrecoverChannelUpdateGap, "f").debug(`recovered from update gap [${channelId}, ${source}]`, channelId, source);
|
|
776
|
-
break;
|
|
777
|
-
}
|
|
778
|
-
else if (Api.is("updates.channelDifferenceTooLong", difference)) {
|
|
779
|
-
// TODO: invalidate messages
|
|
780
|
-
__classPrivateFieldGet(this, _UpdateManager_LrecoverChannelUpdateGap, "f").debug("received channelDifferenceTooLong");
|
|
781
|
-
this.processChats(difference.chats, difference);
|
|
782
|
-
this.processUsers(difference.users, difference);
|
|
783
|
-
for (const message of difference.messages) {
|
|
784
|
-
await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_processUpdates).call(this, { _: "updateNewChannelMessage", message, pts: 0, pts_count: 0 }, false);
|
|
785
|
-
}
|
|
786
|
-
const pts_ = Api.as("dialog", difference.dialog).pts;
|
|
787
|
-
if (pts_ !== undefined) {
|
|
788
|
-
pts = pts_;
|
|
789
|
-
}
|
|
790
|
-
else {
|
|
791
|
-
unreachable();
|
|
792
|
-
}
|
|
793
|
-
__classPrivateFieldGet(this, _UpdateManager_LrecoverChannelUpdateGap, "f").debug("processed channelDifferenceTooLong");
|
|
794
|
-
}
|
|
795
|
-
else if (Api.is("updates.channelDifferenceEmpty", difference)) {
|
|
796
|
-
__classPrivateFieldGet(this, _UpdateManager_LrecoverChannelUpdateGap, "f").debug("there was no update gap");
|
|
797
|
-
break;
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
return lastTimeout;
|
|
801
|
-
}, _UpdateManager_handleStoredUpdates = async function _UpdateManager_handleStoredUpdates(boxId) {
|
|
802
|
-
if (__classPrivateFieldGet(this, _UpdateManager_handleUpdatesSet, "f").has(boxId)) {
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
805
|
-
__classPrivateFieldGet(this, _UpdateManager_handleUpdatesSet, "f").add(boxId);
|
|
806
|
-
do {
|
|
807
|
-
const maybeUpdate = await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.getFirstUpdate(boxId);
|
|
808
|
-
if (maybeUpdate === null) {
|
|
809
|
-
break;
|
|
810
|
-
}
|
|
811
|
-
const [key, update] = maybeUpdate;
|
|
812
|
-
for (let i = 0; i < 100; ++i) {
|
|
813
|
-
try {
|
|
814
|
-
const handle = await __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_handleUpdate).call(this, update);
|
|
815
|
-
handle: for (let i = 0; i < 2; ++i) {
|
|
816
|
-
try {
|
|
817
|
-
await handle();
|
|
818
|
-
break handle;
|
|
819
|
-
}
|
|
820
|
-
catch {
|
|
821
|
-
continue handle;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
break;
|
|
825
|
-
}
|
|
826
|
-
catch (err) {
|
|
827
|
-
__classPrivateFieldGet(this, _UpdateManager_L$handleUpdate, "f").error(err);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
await __classPrivateFieldGet(this, _UpdateManager_c, "f").storage.set(key, null);
|
|
831
|
-
} while (true);
|
|
832
|
-
__classPrivateFieldGet(this, _UpdateManager_handleUpdatesSet, "f").delete(boxId);
|
|
833
|
-
}, _UpdateManager_handleUpdate = function _UpdateManager_handleUpdate(update) {
|
|
834
|
-
const handler = __classPrivateFieldGet(this, _UpdateManager_updateHandler, "f");
|
|
835
|
-
if (handler) {
|
|
836
|
-
return handler(update);
|
|
837
|
-
}
|
|
838
|
-
else {
|
|
839
|
-
return Promise.resolve(() => Promise.resolve());
|
|
840
|
-
}
|
|
841
|
-
}, _UpdateManager_needsGetDifference = async function _UpdateManager_needsGetDifference(update) {
|
|
842
|
-
const chatIds = __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIds).call(this, update);
|
|
843
|
-
if (!chatIds.size) {
|
|
844
|
-
return false;
|
|
845
|
-
}
|
|
846
|
-
return (await Promise.all(chatIds.values().map((v) => __classPrivateFieldGet(this, _UpdateManager_c, "f").messageStorage.peers.get([v])))).some((v) => !v);
|
|
847
|
-
}, _UpdateManager_collectChatIds = function _UpdateManager_collectChatIds(object) {
|
|
848
|
-
const chatIds = new Set();
|
|
849
|
-
if (Api.is("messageFwdHeader", object)) {
|
|
850
|
-
if (object.from_id) {
|
|
851
|
-
chatIds.add(peerToChatId(object.from_id));
|
|
852
|
-
}
|
|
853
|
-
if (object.saved_from_peer) {
|
|
854
|
-
chatIds.add(peerToChatId(object.saved_from_peer));
|
|
855
|
-
}
|
|
856
|
-
return chatIds;
|
|
857
|
-
}
|
|
858
|
-
if (Api.isOfEnum("MessageMedia", object)) {
|
|
859
|
-
switch (object._) {
|
|
860
|
-
case "messageMediaContact":
|
|
861
|
-
if (object.user_id) {
|
|
862
|
-
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.user_id }));
|
|
863
|
-
}
|
|
864
|
-
break;
|
|
865
|
-
case "messageMediaStory":
|
|
866
|
-
chatIds.add(peerToChatId(object.peer));
|
|
867
|
-
break;
|
|
868
|
-
case "messageMediaGiveaway":
|
|
869
|
-
for (const chatId of object.channels.map((v) => peerToChatId({ _: "peerChannel", channel_id: v }))) {
|
|
870
|
-
chatIds.add(chatId);
|
|
871
|
-
}
|
|
872
|
-
break;
|
|
873
|
-
case "messageMediaGiveawayResults":
|
|
874
|
-
chatIds.add(peerToChatId({ _: "peerChannel", channel_id: object.channel_id }));
|
|
875
|
-
for (const chatId of object.winners.map((user_id) => peerToChatId({ _: "peerUser", user_id }))) {
|
|
876
|
-
chatIds.add(chatId);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
return chatIds;
|
|
880
|
-
}
|
|
881
|
-
// messsages
|
|
882
|
-
if (!("message" in object)) {
|
|
883
|
-
return chatIds;
|
|
884
|
-
}
|
|
885
|
-
if (Api.is("messageEmpty", object.message)) {
|
|
886
|
-
return chatIds;
|
|
887
|
-
}
|
|
888
|
-
chatIds.add(peerToChatId(object.message.peer_id));
|
|
889
|
-
if (object.message.from_id) {
|
|
890
|
-
chatIds.add(peerToChatId(object.message.from_id));
|
|
891
|
-
}
|
|
892
|
-
if (Api.is("messageService", object.message)) {
|
|
893
|
-
switch (object.message.action._) {
|
|
894
|
-
case "messageActionChatCreate":
|
|
895
|
-
case "messageActionChatAddUser":
|
|
896
|
-
case "messageActionInviteToGroupCall":
|
|
897
|
-
for (const user_id of object.message.action.users) {
|
|
898
|
-
chatIds.add(peerToChatId({ _: "peerUser", user_id }));
|
|
899
|
-
}
|
|
900
|
-
break;
|
|
901
|
-
case "messageActionChatDeleteUser":
|
|
902
|
-
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.action.user_id }));
|
|
903
|
-
break;
|
|
904
|
-
case "messageActionChatMigrateTo":
|
|
905
|
-
chatIds.add(peerToChatId({ _: "peerChannel", channel_id: object.message.action.channel_id }));
|
|
906
|
-
break;
|
|
907
|
-
case "messageActionChannelMigrateFrom":
|
|
908
|
-
chatIds.add(peerToChatId({ _: "peerChat", chat_id: object.message.action.chat_id }));
|
|
909
|
-
break;
|
|
910
|
-
case "messageActionConferenceCall":
|
|
911
|
-
if (object.message.action.other_participants) {
|
|
912
|
-
for (const participant of object.message.action.other_participants) {
|
|
913
|
-
chatIds.add(peerToChatId(participant));
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
break;
|
|
917
|
-
case "messageActionPaymentRefunded":
|
|
918
|
-
chatIds.add(peerToChatId(object.message.action.peer));
|
|
919
|
-
break;
|
|
920
|
-
case "messageActionGiftCode":
|
|
921
|
-
if (object.message.action.boost_peer) {
|
|
922
|
-
chatIds.add(peerToChatId(object.message.action.boost_peer));
|
|
923
|
-
}
|
|
924
|
-
break;
|
|
925
|
-
case "messageActionRequestedPeer":
|
|
926
|
-
if (!__classPrivateFieldGet(this, _UpdateManager_c, "f").storage.isBot) {
|
|
927
|
-
for (const peer of object.message.action.peers) {
|
|
928
|
-
chatIds.add(peerToChatId(peer));
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
break;
|
|
932
|
-
case "messageActionSetMessagesTTL":
|
|
933
|
-
if (object.message.action.auto_setting_from) {
|
|
934
|
-
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.action.auto_setting_from }));
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
else {
|
|
939
|
-
if (object.message.reply_to) {
|
|
940
|
-
switch (object.message.reply_to._) {
|
|
941
|
-
case "messageReplyHeader":
|
|
942
|
-
if (object.message.reply_to.reply_to_peer_id) {
|
|
943
|
-
chatIds.add(peerToChatId(object.message.reply_to.reply_to_peer_id));
|
|
944
|
-
}
|
|
945
|
-
if (object.message.reply_to.reply_from) {
|
|
946
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIds).call(this, object.message.reply_to.reply_from)) {
|
|
947
|
-
chatIds.add(chatId);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
if (object.message.reply_to.quote_entities) {
|
|
951
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIdsFromEntities).call(this, object.message.reply_to.quote_entities)) {
|
|
952
|
-
chatIds.add(chatId);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
if (object.message.reply_to.reply_media) {
|
|
956
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIds).call(this, object.message.reply_to.reply_media)) {
|
|
957
|
-
chatIds.add(chatId);
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
break;
|
|
961
|
-
case "messageReplyStoryHeader":
|
|
962
|
-
chatIds.add(peerToChatId(object.message.reply_to.peer));
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
if (object.message.fwd_from) {
|
|
966
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIds).call(this, object.message.fwd_from)) {
|
|
967
|
-
chatIds.add(chatId);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
if (object.message.via_bot_id) {
|
|
971
|
-
chatIds.add(peerToChatId({ _: "peerUser", user_id: object.message.via_bot_id }));
|
|
972
|
-
}
|
|
973
|
-
if (object.message.entities) {
|
|
974
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIdsFromEntities).call(this, object.message.entities)) {
|
|
975
|
-
chatIds.add(chatId);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
if (object.message.media) {
|
|
979
|
-
for (const chatId of __classPrivateFieldGet(this, _UpdateManager_instances, "m", _UpdateManager_collectChatIds).call(this, object.message.media)) {
|
|
980
|
-
chatIds.add(chatId);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
return chatIds;
|
|
985
|
-
}, _UpdateManager_collectChatIdsFromEntities = function _UpdateManager_collectChatIdsFromEntities(entities) {
|
|
986
|
-
const chatIds = new Array();
|
|
987
|
-
for (const user_id of entities.filter((v) => Api.is("messageEntityMentionName", v)).map((v) => v.user_id)) {
|
|
988
|
-
chatIds.push(peerToChatId({ _: "peerUser", user_id }));
|
|
989
|
-
}
|
|
990
|
-
return chatIds;
|
|
991
|
-
};
|
|
992
|
-
Object.defineProperty(UpdateManager, "QTS_COUNT", {
|
|
993
|
-
enumerable: true,
|
|
994
|
-
configurable: true,
|
|
995
|
-
writable: true,
|
|
996
|
-
value: 1
|
|
997
|
-
});
|
|
998
|
-
Object.defineProperty(UpdateManager, "MAIN_BOX_ID", {
|
|
999
|
-
enumerable: true,
|
|
1000
|
-
configurable: true,
|
|
1001
|
-
writable: true,
|
|
1002
|
-
value: 0n
|
|
1003
|
-
});
|
|
1008
|
+
_a = UpdateManager;
|