@mtcute/core 0.25.0 → 0.25.2
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/highlevel/methods/misc/normalize-text.cjs +30 -1
- package/highlevel/methods/misc/normalize-text.js +30 -1
- package/highlevel/methods/misc/normalize-text.test.d.cts +1 -0
- package/highlevel/methods/misc/normalize-text.test.d.ts +1 -0
- package/highlevel/updates/manager.cjs +4 -0
- package/highlevel/updates/manager.js +4 -0
- package/highlevel/worker/invoker.cjs +4 -1
- package/highlevel/worker/invoker.d.cts +2 -1
- package/highlevel/worker/invoker.d.ts +2 -1
- package/highlevel/worker/invoker.js +4 -1
- package/highlevel/worker/port.cjs +4 -1
- package/highlevel/worker/port.d.cts +2 -0
- package/highlevel/worker/port.d.ts +2 -0
- package/highlevel/worker/port.js +5 -2
- package/highlevel/worker/protocol.cjs +2 -0
- package/highlevel/worker/protocol.d.cts +10 -0
- package/highlevel/worker/protocol.d.ts +10 -0
- package/highlevel/worker/protocol.js +2 -0
- package/highlevel/worker/worker.cjs +23 -2
- package/highlevel/worker/worker.d.cts +5 -1
- package/highlevel/worker/worker.d.ts +5 -1
- package/highlevel/worker/worker.js +24 -3
- package/network/mtproto-session.cjs +1 -1
- package/network/mtproto-session.js +1 -1
- package/network/network-manager.cjs +23 -18
- package/network/network-manager.js +23 -18
- package/package.json +1 -1
- package/worker.cjs +1 -0
- package/worker.js +2 -1
|
@@ -7,6 +7,19 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
|
|
|
7
7
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
8
|
const resolvePeer = require("../users/resolve-peer.cjs");
|
|
9
9
|
const empty = ["", void 0];
|
|
10
|
+
function adjustOffsets(entities, from, by) {
|
|
11
|
+
for (const ent of entities) {
|
|
12
|
+
if (ent.offset < from) continue;
|
|
13
|
+
if (by >= 0) {
|
|
14
|
+
ent.offset += by;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const adjustTotal = Math.min(ent.offset, Math.abs(by));
|
|
18
|
+
const adjustInternal = Math.max(Math.abs(by) - ent.offset, 0);
|
|
19
|
+
ent.offset -= adjustTotal;
|
|
20
|
+
ent.length -= adjustInternal;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
10
23
|
async function _normalizeInputText(client, input) {
|
|
11
24
|
if (!input) {
|
|
12
25
|
return empty;
|
|
@@ -14,8 +27,10 @@ async function _normalizeInputText(client, input) {
|
|
|
14
27
|
if (typeof input === "string") {
|
|
15
28
|
return [input, void 0];
|
|
16
29
|
}
|
|
17
|
-
|
|
30
|
+
let text = input.text;
|
|
31
|
+
const entities = input.entities;
|
|
18
32
|
if (!entities) return [text, void 0];
|
|
33
|
+
let canTrimStart = true;
|
|
19
34
|
for (const ent of entities) {
|
|
20
35
|
if (ent._ === "messageEntityMentionName") {
|
|
21
36
|
try {
|
|
@@ -27,6 +42,20 @@ async function _normalizeInputText(client, input) {
|
|
|
27
42
|
client.log.warn("Failed to resolve mention entity for %s: %s", ent.userId, e);
|
|
28
43
|
}
|
|
29
44
|
}
|
|
45
|
+
if (ent._ === "messageEntityPre" && ent.offset === 0) {
|
|
46
|
+
canTrimStart = false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (canTrimStart) {
|
|
50
|
+
const resultTrimmed = text.trimStart();
|
|
51
|
+
const numCharsTrimmed = text.length - resultTrimmed.length;
|
|
52
|
+
text = resultTrimmed;
|
|
53
|
+
adjustOffsets(entities, 0, -numCharsTrimmed);
|
|
54
|
+
}
|
|
55
|
+
text = text.trimEnd();
|
|
56
|
+
for (const ent of entities) {
|
|
57
|
+
const end = ent.offset + ent.length;
|
|
58
|
+
if (end > text.length) ent.length = text.length - ent.offset;
|
|
30
59
|
}
|
|
31
60
|
return [text, entities];
|
|
32
61
|
}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { resolveUser } from "../users/resolve-peer.js";
|
|
2
2
|
const empty = ["", void 0];
|
|
3
|
+
function adjustOffsets(entities, from, by) {
|
|
4
|
+
for (const ent of entities) {
|
|
5
|
+
if (ent.offset < from) continue;
|
|
6
|
+
if (by >= 0) {
|
|
7
|
+
ent.offset += by;
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
const adjustTotal = Math.min(ent.offset, Math.abs(by));
|
|
11
|
+
const adjustInternal = Math.max(Math.abs(by) - ent.offset, 0);
|
|
12
|
+
ent.offset -= adjustTotal;
|
|
13
|
+
ent.length -= adjustInternal;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
3
16
|
async function _normalizeInputText(client, input) {
|
|
4
17
|
if (!input) {
|
|
5
18
|
return empty;
|
|
@@ -7,8 +20,10 @@ async function _normalizeInputText(client, input) {
|
|
|
7
20
|
if (typeof input === "string") {
|
|
8
21
|
return [input, void 0];
|
|
9
22
|
}
|
|
10
|
-
|
|
23
|
+
let text = input.text;
|
|
24
|
+
const entities = input.entities;
|
|
11
25
|
if (!entities) return [text, void 0];
|
|
26
|
+
let canTrimStart = true;
|
|
12
27
|
for (const ent of entities) {
|
|
13
28
|
if (ent._ === "messageEntityMentionName") {
|
|
14
29
|
try {
|
|
@@ -20,6 +35,20 @@ async function _normalizeInputText(client, input) {
|
|
|
20
35
|
client.log.warn("Failed to resolve mention entity for %s: %s", ent.userId, e);
|
|
21
36
|
}
|
|
22
37
|
}
|
|
38
|
+
if (ent._ === "messageEntityPre" && ent.offset === 0) {
|
|
39
|
+
canTrimStart = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (canTrimStart) {
|
|
43
|
+
const resultTrimmed = text.trimStart();
|
|
44
|
+
const numCharsTrimmed = text.length - resultTrimmed.length;
|
|
45
|
+
text = resultTrimmed;
|
|
46
|
+
adjustOffsets(entities, 0, -numCharsTrimmed);
|
|
47
|
+
}
|
|
48
|
+
text = text.trimEnd();
|
|
49
|
+
for (const ent of entities) {
|
|
50
|
+
const end = ent.offset + ent.length;
|
|
51
|
+
if (end > text.length) ent.length = text.length - ent.offset;
|
|
23
52
|
}
|
|
24
53
|
return [text, entities];
|
|
25
54
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -97,12 +97,14 @@ class UpdatesManager {
|
|
|
97
97
|
this._onCatchingUp = handler;
|
|
98
98
|
}
|
|
99
99
|
destroy() {
|
|
100
|
+
this.log.debug("destroyed, stopping updates loop");
|
|
100
101
|
this.stopLoop();
|
|
101
102
|
}
|
|
102
103
|
notifyLoggedIn() {
|
|
103
104
|
this.startLoop().catch((err) => this.client.onError.emit(utils.unknownToError(err)));
|
|
104
105
|
}
|
|
105
106
|
notifyLoggedOut() {
|
|
107
|
+
this.log.debug("notifyLoggedOut, stopping updates loop");
|
|
106
108
|
this.stopLoop();
|
|
107
109
|
this.cpts.clear();
|
|
108
110
|
this.cptsMod.clear();
|
|
@@ -316,6 +318,7 @@ class UpdatesManager {
|
|
|
316
318
|
} catch (e) {
|
|
317
319
|
if (tl.tl.RpcError.is(e, "AUTH_KEY_UNREGISTERED")) {
|
|
318
320
|
lock.release();
|
|
321
|
+
this.log.debug("received AUTH_KEY_UNREGISTERED, stopping updates loop");
|
|
319
322
|
this.stopLoop();
|
|
320
323
|
return;
|
|
321
324
|
}
|
|
@@ -812,6 +815,7 @@ class UpdatesManager {
|
|
|
812
815
|
0,
|
|
813
816
|
this._fetchDifference(requestedDiff).catch((err) => {
|
|
814
817
|
if (tl.tl.RpcError.is(err, "AUTH_KEY_UNREGISTERED")) {
|
|
818
|
+
this.log.debug("received AUTH_KEY_UNREGISTERED, stopping updates loop");
|
|
815
819
|
this.stopLoop();
|
|
816
820
|
return;
|
|
817
821
|
}
|
|
@@ -90,12 +90,14 @@ class UpdatesManager {
|
|
|
90
90
|
this._onCatchingUp = handler;
|
|
91
91
|
}
|
|
92
92
|
destroy() {
|
|
93
|
+
this.log.debug("destroyed, stopping updates loop");
|
|
93
94
|
this.stopLoop();
|
|
94
95
|
}
|
|
95
96
|
notifyLoggedIn() {
|
|
96
97
|
this.startLoop().catch((err) => this.client.onError.emit(unknownToError(err)));
|
|
97
98
|
}
|
|
98
99
|
notifyLoggedOut() {
|
|
100
|
+
this.log.debug("notifyLoggedOut, stopping updates loop");
|
|
99
101
|
this.stopLoop();
|
|
100
102
|
this.cpts.clear();
|
|
101
103
|
this.cptsMod.clear();
|
|
@@ -309,6 +311,7 @@ class UpdatesManager {
|
|
|
309
311
|
} catch (e) {
|
|
310
312
|
if (tl.RpcError.is(e, "AUTH_KEY_UNREGISTERED")) {
|
|
311
313
|
lock.release();
|
|
314
|
+
this.log.debug("received AUTH_KEY_UNREGISTERED, stopping updates loop");
|
|
312
315
|
this.stopLoop();
|
|
313
316
|
return;
|
|
314
317
|
}
|
|
@@ -805,6 +808,7 @@ class UpdatesManager {
|
|
|
805
808
|
0,
|
|
806
809
|
this._fetchDifference(requestedDiff).catch((err) => {
|
|
807
810
|
if (tl.RpcError.is(err, "AUTH_KEY_UNREGISTERED")) {
|
|
811
|
+
this.log.debug("received AUTH_KEY_UNREGISTERED, stopping updates loop");
|
|
808
812
|
this.stopLoop();
|
|
809
813
|
return;
|
|
810
814
|
}
|
|
@@ -9,14 +9,16 @@ const utils = require("@fuman/utils");
|
|
|
9
9
|
const errors = require("./errors.cjs");
|
|
10
10
|
const protocol = require("./protocol.cjs");
|
|
11
11
|
class WorkerInvoker {
|
|
12
|
-
constructor(send) {
|
|
12
|
+
constructor(send, workerId) {
|
|
13
13
|
this.send = send;
|
|
14
|
+
this.workerId = workerId;
|
|
14
15
|
}
|
|
15
16
|
_nextId = 0;
|
|
16
17
|
_pending = /* @__PURE__ */ new Map();
|
|
17
18
|
_invoke(target, method, args, isVoid, abortSignal) {
|
|
18
19
|
const id = this._nextId++;
|
|
19
20
|
this.send({
|
|
21
|
+
_mtcuteWorkerId: this.workerId,
|
|
20
22
|
type: "invoke",
|
|
21
23
|
id,
|
|
22
24
|
target,
|
|
@@ -27,6 +29,7 @@ class WorkerInvoker {
|
|
|
27
29
|
});
|
|
28
30
|
abortSignal?.addEventListener("abort", () => {
|
|
29
31
|
this.send({
|
|
32
|
+
_mtcuteWorkerId: this.workerId,
|
|
30
33
|
type: "abort",
|
|
31
34
|
id
|
|
32
35
|
});
|
|
@@ -4,7 +4,8 @@ export type InvokeTarget = Extract<WorkerInboundMessage, {
|
|
|
4
4
|
}>['target'];
|
|
5
5
|
export declare class WorkerInvoker {
|
|
6
6
|
private send;
|
|
7
|
-
|
|
7
|
+
private readonly workerId;
|
|
8
|
+
constructor(send: SendFn, workerId: string);
|
|
8
9
|
private _nextId;
|
|
9
10
|
private _pending;
|
|
10
11
|
private _invoke;
|
|
@@ -4,7 +4,8 @@ export type InvokeTarget = Extract<WorkerInboundMessage, {
|
|
|
4
4
|
}>['target'];
|
|
5
5
|
export declare class WorkerInvoker {
|
|
6
6
|
private send;
|
|
7
|
-
|
|
7
|
+
private readonly workerId;
|
|
8
|
+
constructor(send: SendFn, workerId: string);
|
|
8
9
|
private _nextId;
|
|
9
10
|
private _pending;
|
|
10
11
|
private _invoke;
|
|
@@ -2,14 +2,16 @@ import { Deferred } from "@fuman/utils";
|
|
|
2
2
|
import { deserializeError } from "./errors.js";
|
|
3
3
|
import { serializeResult, deserializeResult } from "./protocol.js";
|
|
4
4
|
class WorkerInvoker {
|
|
5
|
-
constructor(send) {
|
|
5
|
+
constructor(send, workerId) {
|
|
6
6
|
this.send = send;
|
|
7
|
+
this.workerId = workerId;
|
|
7
8
|
}
|
|
8
9
|
_nextId = 0;
|
|
9
10
|
_pending = /* @__PURE__ */ new Map();
|
|
10
11
|
_invoke(target, method, args, isVoid, abortSignal) {
|
|
11
12
|
const id = this._nextId++;
|
|
12
13
|
this.send({
|
|
14
|
+
_mtcuteWorkerId: this.workerId,
|
|
13
15
|
type: "invoke",
|
|
14
16
|
id,
|
|
15
17
|
target,
|
|
@@ -20,6 +22,7 @@ class WorkerInvoker {
|
|
|
20
22
|
});
|
|
21
23
|
abortSignal?.addEventListener("abort", () => {
|
|
22
24
|
this.send({
|
|
25
|
+
_mtcuteWorkerId: this.workerId,
|
|
23
26
|
type: "abort",
|
|
24
27
|
id
|
|
25
28
|
});
|
|
@@ -19,8 +19,9 @@ class TelegramWorkerPort {
|
|
|
19
19
|
this.options = options;
|
|
20
20
|
this.log = new logger.LogManager("worker", options.platform);
|
|
21
21
|
this.platform = options.platform;
|
|
22
|
+
this.workerId = options.workerId ?? protocol.DEFAULT_WORKER_ID;
|
|
22
23
|
this._connection = this.connectToWorker(this.options.worker, this._onMessage);
|
|
23
|
-
this._invoker = new invoker.WorkerInvoker(this._connection[0]);
|
|
24
|
+
this._invoker = new invoker.WorkerInvoker(this._connection[0], this.workerId);
|
|
24
25
|
this.storage = new storage.TelegramStorageProxy(this._invoker);
|
|
25
26
|
this.appConfig = new appConfig.AppConfigManagerProxy(this._invoker);
|
|
26
27
|
const bind = this._invoker.makeBinder("client");
|
|
@@ -82,6 +83,7 @@ class TelegramWorkerPort {
|
|
|
82
83
|
recreateDc;
|
|
83
84
|
_abortController = new AbortController();
|
|
84
85
|
stopSignal = this._abortController.signal;
|
|
86
|
+
workerId;
|
|
85
87
|
call(message, params) {
|
|
86
88
|
if (params?.abortSignal) {
|
|
87
89
|
const { abortSignal, ...rest } = params;
|
|
@@ -94,6 +96,7 @@ class TelegramWorkerPort {
|
|
|
94
96
|
onConnectionState = new utils.Emitter();
|
|
95
97
|
onError = new utils.Emitter();
|
|
96
98
|
_onMessage = (message) => {
|
|
99
|
+
if (message._mtcuteWorkerId !== this.workerId) return;
|
|
97
100
|
switch (message.type) {
|
|
98
101
|
case "log":
|
|
99
102
|
this.log.handler(message.color, message.level, message.tag, message.fmt, message.args);
|
|
@@ -12,6 +12,7 @@ import { AppConfigManagerProxy } from './app-config.js';
|
|
|
12
12
|
import { TelegramStorageProxy } from './storage.js';
|
|
13
13
|
export interface TelegramWorkerPortOptions {
|
|
14
14
|
worker: SomeWorker;
|
|
15
|
+
workerId?: string;
|
|
15
16
|
platform: ICorePlatform;
|
|
16
17
|
}
|
|
17
18
|
export declare abstract class TelegramWorkerPort<Custom extends WorkerCustomMethods> implements ITelegramClient {
|
|
@@ -46,6 +47,7 @@ export declare abstract class TelegramWorkerPort<Custom extends WorkerCustomMeth
|
|
|
46
47
|
readonly recreateDc: ITelegramClient['recreateDc'];
|
|
47
48
|
private _abortController;
|
|
48
49
|
readonly stopSignal: AbortSignal;
|
|
50
|
+
readonly workerId: string;
|
|
49
51
|
constructor(options: TelegramWorkerPortOptions);
|
|
50
52
|
call<T extends tl.RpcMethod>(message: MustEqual<T, tl.RpcMethod>, params?: RpcCallOptions): Promise<tl.RpcCallReturn[T['_']]>;
|
|
51
53
|
abstract connectToWorker(worker: SomeWorker, handler: ClientMessageHandler): [SendFn, () => void];
|
|
@@ -12,6 +12,7 @@ import { AppConfigManagerProxy } from './app-config.js';
|
|
|
12
12
|
import { TelegramStorageProxy } from './storage.js';
|
|
13
13
|
export interface TelegramWorkerPortOptions {
|
|
14
14
|
worker: SomeWorker;
|
|
15
|
+
workerId?: string;
|
|
15
16
|
platform: ICorePlatform;
|
|
16
17
|
}
|
|
17
18
|
export declare abstract class TelegramWorkerPort<Custom extends WorkerCustomMethods> implements ITelegramClient {
|
|
@@ -46,6 +47,7 @@ export declare abstract class TelegramWorkerPort<Custom extends WorkerCustomMeth
|
|
|
46
47
|
readonly recreateDc: ITelegramClient['recreateDc'];
|
|
47
48
|
private _abortController;
|
|
48
49
|
readonly stopSignal: AbortSignal;
|
|
50
|
+
readonly workerId: string;
|
|
49
51
|
constructor(options: TelegramWorkerPortOptions);
|
|
50
52
|
call<T extends tl.RpcMethod>(message: MustEqual<T, tl.RpcMethod>, params?: RpcCallOptions): Promise<tl.RpcCallReturn[T['_']]>;
|
|
51
53
|
abstract connectToWorker(worker: SomeWorker, handler: ClientMessageHandler): [SendFn, () => void];
|
package/highlevel/worker/port.js
CHANGED
|
@@ -5,15 +5,16 @@ import { PeersIndex } from "../types/peers/peers-index.js";
|
|
|
5
5
|
import { AppConfigManagerProxy } from "./app-config.js";
|
|
6
6
|
import { deserializeError } from "./errors.js";
|
|
7
7
|
import { WorkerInvoker } from "./invoker.js";
|
|
8
|
-
import { deserializeResult } from "./protocol.js";
|
|
8
|
+
import { DEFAULT_WORKER_ID, deserializeResult } from "./protocol.js";
|
|
9
9
|
import { TelegramStorageProxy } from "./storage.js";
|
|
10
10
|
class TelegramWorkerPort {
|
|
11
11
|
constructor(options) {
|
|
12
12
|
this.options = options;
|
|
13
13
|
this.log = new LogManager("worker", options.platform);
|
|
14
14
|
this.platform = options.platform;
|
|
15
|
+
this.workerId = options.workerId ?? DEFAULT_WORKER_ID;
|
|
15
16
|
this._connection = this.connectToWorker(this.options.worker, this._onMessage);
|
|
16
|
-
this._invoker = new WorkerInvoker(this._connection[0]);
|
|
17
|
+
this._invoker = new WorkerInvoker(this._connection[0], this.workerId);
|
|
17
18
|
this.storage = new TelegramStorageProxy(this._invoker);
|
|
18
19
|
this.appConfig = new AppConfigManagerProxy(this._invoker);
|
|
19
20
|
const bind = this._invoker.makeBinder("client");
|
|
@@ -75,6 +76,7 @@ class TelegramWorkerPort {
|
|
|
75
76
|
recreateDc;
|
|
76
77
|
_abortController = new AbortController();
|
|
77
78
|
stopSignal = this._abortController.signal;
|
|
79
|
+
workerId;
|
|
78
80
|
call(message, params) {
|
|
79
81
|
if (params?.abortSignal) {
|
|
80
82
|
const { abortSignal, ...rest } = params;
|
|
@@ -87,6 +89,7 @@ class TelegramWorkerPort {
|
|
|
87
89
|
onConnectionState = new Emitter();
|
|
88
90
|
onError = new Emitter();
|
|
89
91
|
_onMessage = (message) => {
|
|
92
|
+
if (message._mtcuteWorkerId !== this.workerId) return;
|
|
90
93
|
switch (message.type) {
|
|
91
94
|
case "log":
|
|
92
95
|
this.log.handler(message.color, message.level, message.tag, message.fmt, message.args);
|
|
@@ -6,6 +6,7 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
|
|
|
6
6
|
"use strict";
|
|
7
7
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
8
|
const Long = require("long");
|
|
9
|
+
const DEFAULT_WORKER_ID = "default";
|
|
9
10
|
function serializeResult(result) {
|
|
10
11
|
if (ArrayBuffer.isView(result)) return result;
|
|
11
12
|
if (Array.isArray(result)) {
|
|
@@ -59,5 +60,6 @@ function deserializeResult(result) {
|
|
|
59
60
|
}
|
|
60
61
|
return result;
|
|
61
62
|
}
|
|
63
|
+
exports.DEFAULT_WORKER_ID = DEFAULT_WORKER_ID;
|
|
62
64
|
exports.deserializeResult = deserializeResult;
|
|
63
65
|
exports.serializeResult = serializeResult;
|
|
@@ -3,6 +3,7 @@ import { Worker as NodeWorker } from 'node:worker_threads';
|
|
|
3
3
|
import { ConnectionState } from '../client.types.js';
|
|
4
4
|
import { SerializedError } from './errors.js';
|
|
5
5
|
export type WorkerInboundMessage = {
|
|
6
|
+
_mtcuteWorkerId: string;
|
|
6
7
|
type: 'invoke';
|
|
7
8
|
id: number;
|
|
8
9
|
target: 'custom' | 'client' | 'storage' | 'storage-self' | 'storage-peers' | 'app-config';
|
|
@@ -11,27 +12,34 @@ export type WorkerInboundMessage = {
|
|
|
11
12
|
void: boolean;
|
|
12
13
|
withAbort: boolean;
|
|
13
14
|
} | {
|
|
15
|
+
_mtcuteWorkerId: string;
|
|
14
16
|
type: 'abort';
|
|
15
17
|
id: number;
|
|
16
18
|
};
|
|
17
19
|
export type WorkerOutboundMessage = {
|
|
20
|
+
_mtcuteWorkerId: string;
|
|
18
21
|
type: 'server_update';
|
|
19
22
|
update: SerializedResult<tl.TypeUpdates>;
|
|
20
23
|
} | {
|
|
24
|
+
_mtcuteWorkerId: string;
|
|
21
25
|
type: 'update';
|
|
22
26
|
update: SerializedResult<tl.TypeUpdate>;
|
|
23
27
|
users: SerializedResult<Map<number, tl.TypeUser>>;
|
|
24
28
|
chats: SerializedResult<Map<number, tl.TypeChat>>;
|
|
25
29
|
hasMin: boolean;
|
|
26
30
|
} | {
|
|
31
|
+
_mtcuteWorkerId: string;
|
|
27
32
|
type: 'error';
|
|
28
33
|
error: SerializedError;
|
|
29
34
|
} | {
|
|
35
|
+
_mtcuteWorkerId: string;
|
|
30
36
|
type: 'stop';
|
|
31
37
|
} | {
|
|
38
|
+
_mtcuteWorkerId: string;
|
|
32
39
|
type: 'conn_state';
|
|
33
40
|
state: ConnectionState;
|
|
34
41
|
} | {
|
|
42
|
+
_mtcuteWorkerId: string;
|
|
35
43
|
type: 'log';
|
|
36
44
|
color: number;
|
|
37
45
|
level: number;
|
|
@@ -39,11 +47,13 @@ export type WorkerOutboundMessage = {
|
|
|
39
47
|
fmt: string;
|
|
40
48
|
args: unknown[];
|
|
41
49
|
} | {
|
|
50
|
+
_mtcuteWorkerId: string;
|
|
42
51
|
type: 'result';
|
|
43
52
|
id: number;
|
|
44
53
|
result?: SerializedResult<unknown>;
|
|
45
54
|
error?: SerializedError;
|
|
46
55
|
};
|
|
56
|
+
export declare const DEFAULT_WORKER_ID = "default";
|
|
47
57
|
export type SomeWorker = NodeWorker | Worker | SharedWorker;
|
|
48
58
|
export type SendFn = (message: WorkerInboundMessage) => void;
|
|
49
59
|
export type ClientMessageHandler = (message: WorkerOutboundMessage) => void;
|
|
@@ -3,6 +3,7 @@ import { Worker as NodeWorker } from 'node:worker_threads';
|
|
|
3
3
|
import { ConnectionState } from '../client.types.js';
|
|
4
4
|
import { SerializedError } from './errors.js';
|
|
5
5
|
export type WorkerInboundMessage = {
|
|
6
|
+
_mtcuteWorkerId: string;
|
|
6
7
|
type: 'invoke';
|
|
7
8
|
id: number;
|
|
8
9
|
target: 'custom' | 'client' | 'storage' | 'storage-self' | 'storage-peers' | 'app-config';
|
|
@@ -11,27 +12,34 @@ export type WorkerInboundMessage = {
|
|
|
11
12
|
void: boolean;
|
|
12
13
|
withAbort: boolean;
|
|
13
14
|
} | {
|
|
15
|
+
_mtcuteWorkerId: string;
|
|
14
16
|
type: 'abort';
|
|
15
17
|
id: number;
|
|
16
18
|
};
|
|
17
19
|
export type WorkerOutboundMessage = {
|
|
20
|
+
_mtcuteWorkerId: string;
|
|
18
21
|
type: 'server_update';
|
|
19
22
|
update: SerializedResult<tl.TypeUpdates>;
|
|
20
23
|
} | {
|
|
24
|
+
_mtcuteWorkerId: string;
|
|
21
25
|
type: 'update';
|
|
22
26
|
update: SerializedResult<tl.TypeUpdate>;
|
|
23
27
|
users: SerializedResult<Map<number, tl.TypeUser>>;
|
|
24
28
|
chats: SerializedResult<Map<number, tl.TypeChat>>;
|
|
25
29
|
hasMin: boolean;
|
|
26
30
|
} | {
|
|
31
|
+
_mtcuteWorkerId: string;
|
|
27
32
|
type: 'error';
|
|
28
33
|
error: SerializedError;
|
|
29
34
|
} | {
|
|
35
|
+
_mtcuteWorkerId: string;
|
|
30
36
|
type: 'stop';
|
|
31
37
|
} | {
|
|
38
|
+
_mtcuteWorkerId: string;
|
|
32
39
|
type: 'conn_state';
|
|
33
40
|
state: ConnectionState;
|
|
34
41
|
} | {
|
|
42
|
+
_mtcuteWorkerId: string;
|
|
35
43
|
type: 'log';
|
|
36
44
|
color: number;
|
|
37
45
|
level: number;
|
|
@@ -39,11 +47,13 @@ export type WorkerOutboundMessage = {
|
|
|
39
47
|
fmt: string;
|
|
40
48
|
args: unknown[];
|
|
41
49
|
} | {
|
|
50
|
+
_mtcuteWorkerId: string;
|
|
42
51
|
type: 'result';
|
|
43
52
|
id: number;
|
|
44
53
|
result?: SerializedResult<unknown>;
|
|
45
54
|
error?: SerializedError;
|
|
46
55
|
};
|
|
56
|
+
export declare const DEFAULT_WORKER_ID = "default";
|
|
47
57
|
export type SomeWorker = NodeWorker | Worker | SharedWorker;
|
|
48
58
|
export type SendFn = (message: WorkerInboundMessage) => void;
|
|
49
59
|
export type ClientMessageHandler = (message: WorkerOutboundMessage) => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Long from "long";
|
|
2
|
+
const DEFAULT_WORKER_ID = "default";
|
|
2
3
|
function serializeResult(result) {
|
|
3
4
|
if (ArrayBuffer.isView(result)) return result;
|
|
4
5
|
if (Array.isArray(result)) {
|
|
@@ -53,6 +54,7 @@ function deserializeResult(result) {
|
|
|
53
54
|
return result;
|
|
54
55
|
}
|
|
55
56
|
export {
|
|
57
|
+
DEFAULT_WORKER_ID,
|
|
56
58
|
deserializeResult,
|
|
57
59
|
serializeResult
|
|
58
60
|
};
|
|
@@ -10,7 +10,9 @@ const protocol = require("./protocol.cjs");
|
|
|
10
10
|
class TelegramWorker {
|
|
11
11
|
constructor(params) {
|
|
12
12
|
this.params = params;
|
|
13
|
-
this.
|
|
13
|
+
this.workerId = params.workerId ?? protocol.DEFAULT_WORKER_ID;
|
|
14
|
+
const [broadcast, cleanup] = this.registerWorker((message, respond) => {
|
|
15
|
+
if (message._mtcuteWorkerId !== this.workerId) return;
|
|
14
16
|
switch (message.type) {
|
|
15
17
|
case "invoke":
|
|
16
18
|
this.onInvoke(message, respond);
|
|
@@ -24,9 +26,12 @@ class TelegramWorker {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
});
|
|
29
|
+
this.broadcast = broadcast;
|
|
30
|
+
this._cleanup = cleanup;
|
|
27
31
|
const client = params.client;
|
|
28
32
|
this.client = client;
|
|
29
33
|
client.log.mgr.handler = (color, level, tag, fmt, args) => this.broadcast({
|
|
34
|
+
_mtcuteWorkerId: this.workerId,
|
|
30
35
|
type: "log",
|
|
31
36
|
color,
|
|
32
37
|
level,
|
|
@@ -36,20 +41,26 @@ class TelegramWorker {
|
|
|
36
41
|
});
|
|
37
42
|
client.onError.add(
|
|
38
43
|
(err) => this.broadcast({
|
|
44
|
+
_mtcuteWorkerId: this.workerId,
|
|
39
45
|
type: "error",
|
|
40
46
|
error: errors.serializeError(err)
|
|
41
47
|
})
|
|
42
48
|
);
|
|
43
49
|
client.onConnectionState.add(
|
|
44
50
|
(state) => this.broadcast({
|
|
51
|
+
_mtcuteWorkerId: this.workerId,
|
|
45
52
|
type: "conn_state",
|
|
46
53
|
state
|
|
47
54
|
})
|
|
48
55
|
);
|
|
49
|
-
client.stopSignal.addEventListener("abort", () => this.broadcast({
|
|
56
|
+
client.stopSignal.addEventListener("abort", () => this.broadcast({
|
|
57
|
+
_mtcuteWorkerId: this.workerId,
|
|
58
|
+
type: "stop"
|
|
59
|
+
}));
|
|
50
60
|
if (client.updates) {
|
|
51
61
|
client.onRawUpdate.add(
|
|
52
62
|
({ update, peers }) => this.broadcast({
|
|
63
|
+
_mtcuteWorkerId: this.workerId,
|
|
53
64
|
type: "update",
|
|
54
65
|
update: protocol.serializeResult(update),
|
|
55
66
|
users: protocol.serializeResult(peers.users),
|
|
@@ -60,6 +71,7 @@ class TelegramWorker {
|
|
|
60
71
|
} else {
|
|
61
72
|
client.onServerUpdate.add(
|
|
62
73
|
(update) => this.broadcast({
|
|
74
|
+
_mtcuteWorkerId: this.workerId,
|
|
63
75
|
type: "server_update",
|
|
64
76
|
update: protocol.serializeResult(update)
|
|
65
77
|
})
|
|
@@ -68,7 +80,9 @@ class TelegramWorker {
|
|
|
68
80
|
}
|
|
69
81
|
client;
|
|
70
82
|
broadcast;
|
|
83
|
+
_cleanup;
|
|
71
84
|
pendingAborts = /* @__PURE__ */ new Map();
|
|
85
|
+
workerId;
|
|
72
86
|
onInvoke(msg, respond) {
|
|
73
87
|
let target;
|
|
74
88
|
switch (msg.target) {
|
|
@@ -92,6 +106,7 @@ class TelegramWorker {
|
|
|
92
106
|
break;
|
|
93
107
|
default: {
|
|
94
108
|
respond({
|
|
109
|
+
_mtcuteWorkerId: this.workerId,
|
|
95
110
|
type: "result",
|
|
96
111
|
id: msg.id,
|
|
97
112
|
error: new Error(`Unknown target ${msg.target}`)
|
|
@@ -102,6 +117,7 @@ class TelegramWorker {
|
|
|
102
117
|
const method = target[msg.method];
|
|
103
118
|
if (!method) {
|
|
104
119
|
respond({
|
|
120
|
+
_mtcuteWorkerId: this.workerId,
|
|
105
121
|
type: "result",
|
|
106
122
|
id: msg.id,
|
|
107
123
|
error: new Error(`Method ${msg.method} not found on ${msg.target}`)
|
|
@@ -128,6 +144,7 @@ class TelegramWorker {
|
|
|
128
144
|
}
|
|
129
145
|
if (msg.void) return;
|
|
130
146
|
respond({
|
|
147
|
+
_mtcuteWorkerId: this.workerId,
|
|
131
148
|
type: "result",
|
|
132
149
|
id: msg.id,
|
|
133
150
|
result: protocol.serializeResult(res)
|
|
@@ -137,11 +154,15 @@ class TelegramWorker {
|
|
|
137
154
|
this.pendingAborts.delete(msg.id);
|
|
138
155
|
}
|
|
139
156
|
respond({
|
|
157
|
+
_mtcuteWorkerId: this.workerId,
|
|
140
158
|
type: "result",
|
|
141
159
|
id: msg.id,
|
|
142
160
|
error: errors.serializeError(err)
|
|
143
161
|
});
|
|
144
162
|
});
|
|
145
163
|
}
|
|
164
|
+
destroy() {
|
|
165
|
+
this._cleanup?.();
|
|
166
|
+
}
|
|
146
167
|
}
|
|
147
168
|
exports.TelegramWorker = TelegramWorker;
|
|
@@ -2,14 +2,18 @@ import { BaseTelegramClient } from '../base.js';
|
|
|
2
2
|
import { RespondFn, WorkerCustomMethods, WorkerMessageHandler } from './protocol.js';
|
|
3
3
|
export interface TelegramWorkerOptions<T extends WorkerCustomMethods> {
|
|
4
4
|
client: BaseTelegramClient;
|
|
5
|
+
workerId?: string;
|
|
5
6
|
customMethods?: T;
|
|
6
7
|
}
|
|
7
8
|
export declare abstract class TelegramWorker<T extends WorkerCustomMethods> {
|
|
8
9
|
readonly params: TelegramWorkerOptions<T>;
|
|
9
10
|
readonly client: BaseTelegramClient;
|
|
10
11
|
readonly broadcast: RespondFn;
|
|
11
|
-
|
|
12
|
+
private _cleanup;
|
|
13
|
+
abstract registerWorker(handler: WorkerMessageHandler): [RespondFn, VoidFunction];
|
|
12
14
|
readonly pendingAborts: Map<number, AbortController>;
|
|
15
|
+
readonly workerId: string;
|
|
13
16
|
constructor(params: TelegramWorkerOptions<T>);
|
|
14
17
|
private onInvoke;
|
|
18
|
+
destroy(): void;
|
|
15
19
|
}
|
|
@@ -2,14 +2,18 @@ import { BaseTelegramClient } from '../base.js';
|
|
|
2
2
|
import { RespondFn, WorkerCustomMethods, WorkerMessageHandler } from './protocol.js';
|
|
3
3
|
export interface TelegramWorkerOptions<T extends WorkerCustomMethods> {
|
|
4
4
|
client: BaseTelegramClient;
|
|
5
|
+
workerId?: string;
|
|
5
6
|
customMethods?: T;
|
|
6
7
|
}
|
|
7
8
|
export declare abstract class TelegramWorker<T extends WorkerCustomMethods> {
|
|
8
9
|
readonly params: TelegramWorkerOptions<T>;
|
|
9
10
|
readonly client: BaseTelegramClient;
|
|
10
11
|
readonly broadcast: RespondFn;
|
|
11
|
-
|
|
12
|
+
private _cleanup;
|
|
13
|
+
abstract registerWorker(handler: WorkerMessageHandler): [RespondFn, VoidFunction];
|
|
12
14
|
readonly pendingAborts: Map<number, AbortController>;
|
|
15
|
+
readonly workerId: string;
|
|
13
16
|
constructor(params: TelegramWorkerOptions<T>);
|
|
14
17
|
private onInvoke;
|
|
18
|
+
destroy(): void;
|
|
15
19
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { serializeError } from "./errors.js";
|
|
2
|
-
import { serializeResult, deserializeResult } from "./protocol.js";
|
|
2
|
+
import { DEFAULT_WORKER_ID, serializeResult, deserializeResult } from "./protocol.js";
|
|
3
3
|
class TelegramWorker {
|
|
4
4
|
constructor(params) {
|
|
5
5
|
this.params = params;
|
|
6
|
-
this.
|
|
6
|
+
this.workerId = params.workerId ?? DEFAULT_WORKER_ID;
|
|
7
|
+
const [broadcast, cleanup] = this.registerWorker((message, respond) => {
|
|
8
|
+
if (message._mtcuteWorkerId !== this.workerId) return;
|
|
7
9
|
switch (message.type) {
|
|
8
10
|
case "invoke":
|
|
9
11
|
this.onInvoke(message, respond);
|
|
@@ -17,9 +19,12 @@ class TelegramWorker {
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
});
|
|
22
|
+
this.broadcast = broadcast;
|
|
23
|
+
this._cleanup = cleanup;
|
|
20
24
|
const client = params.client;
|
|
21
25
|
this.client = client;
|
|
22
26
|
client.log.mgr.handler = (color, level, tag, fmt, args) => this.broadcast({
|
|
27
|
+
_mtcuteWorkerId: this.workerId,
|
|
23
28
|
type: "log",
|
|
24
29
|
color,
|
|
25
30
|
level,
|
|
@@ -29,20 +34,26 @@ class TelegramWorker {
|
|
|
29
34
|
});
|
|
30
35
|
client.onError.add(
|
|
31
36
|
(err) => this.broadcast({
|
|
37
|
+
_mtcuteWorkerId: this.workerId,
|
|
32
38
|
type: "error",
|
|
33
39
|
error: serializeError(err)
|
|
34
40
|
})
|
|
35
41
|
);
|
|
36
42
|
client.onConnectionState.add(
|
|
37
43
|
(state) => this.broadcast({
|
|
44
|
+
_mtcuteWorkerId: this.workerId,
|
|
38
45
|
type: "conn_state",
|
|
39
46
|
state
|
|
40
47
|
})
|
|
41
48
|
);
|
|
42
|
-
client.stopSignal.addEventListener("abort", () => this.broadcast({
|
|
49
|
+
client.stopSignal.addEventListener("abort", () => this.broadcast({
|
|
50
|
+
_mtcuteWorkerId: this.workerId,
|
|
51
|
+
type: "stop"
|
|
52
|
+
}));
|
|
43
53
|
if (client.updates) {
|
|
44
54
|
client.onRawUpdate.add(
|
|
45
55
|
({ update, peers }) => this.broadcast({
|
|
56
|
+
_mtcuteWorkerId: this.workerId,
|
|
46
57
|
type: "update",
|
|
47
58
|
update: serializeResult(update),
|
|
48
59
|
users: serializeResult(peers.users),
|
|
@@ -53,6 +64,7 @@ class TelegramWorker {
|
|
|
53
64
|
} else {
|
|
54
65
|
client.onServerUpdate.add(
|
|
55
66
|
(update) => this.broadcast({
|
|
67
|
+
_mtcuteWorkerId: this.workerId,
|
|
56
68
|
type: "server_update",
|
|
57
69
|
update: serializeResult(update)
|
|
58
70
|
})
|
|
@@ -61,7 +73,9 @@ class TelegramWorker {
|
|
|
61
73
|
}
|
|
62
74
|
client;
|
|
63
75
|
broadcast;
|
|
76
|
+
_cleanup;
|
|
64
77
|
pendingAborts = /* @__PURE__ */ new Map();
|
|
78
|
+
workerId;
|
|
65
79
|
onInvoke(msg, respond) {
|
|
66
80
|
let target;
|
|
67
81
|
switch (msg.target) {
|
|
@@ -85,6 +99,7 @@ class TelegramWorker {
|
|
|
85
99
|
break;
|
|
86
100
|
default: {
|
|
87
101
|
respond({
|
|
102
|
+
_mtcuteWorkerId: this.workerId,
|
|
88
103
|
type: "result",
|
|
89
104
|
id: msg.id,
|
|
90
105
|
error: new Error(`Unknown target ${msg.target}`)
|
|
@@ -95,6 +110,7 @@ class TelegramWorker {
|
|
|
95
110
|
const method = target[msg.method];
|
|
96
111
|
if (!method) {
|
|
97
112
|
respond({
|
|
113
|
+
_mtcuteWorkerId: this.workerId,
|
|
98
114
|
type: "result",
|
|
99
115
|
id: msg.id,
|
|
100
116
|
error: new Error(`Method ${msg.method} not found on ${msg.target}`)
|
|
@@ -121,6 +137,7 @@ class TelegramWorker {
|
|
|
121
137
|
}
|
|
122
138
|
if (msg.void) return;
|
|
123
139
|
respond({
|
|
140
|
+
_mtcuteWorkerId: this.workerId,
|
|
124
141
|
type: "result",
|
|
125
142
|
id: msg.id,
|
|
126
143
|
result: serializeResult(res)
|
|
@@ -130,12 +147,16 @@ class TelegramWorker {
|
|
|
130
147
|
this.pendingAborts.delete(msg.id);
|
|
131
148
|
}
|
|
132
149
|
respond({
|
|
150
|
+
_mtcuteWorkerId: this.workerId,
|
|
133
151
|
type: "result",
|
|
134
152
|
id: msg.id,
|
|
135
153
|
error: serializeError(err)
|
|
136
154
|
});
|
|
137
155
|
});
|
|
138
156
|
}
|
|
157
|
+
destroy() {
|
|
158
|
+
this._cleanup?.();
|
|
159
|
+
}
|
|
139
160
|
}
|
|
140
161
|
export {
|
|
141
162
|
TelegramWorker
|
|
@@ -32,25 +32,27 @@ class DcConnectionManager {
|
|
|
32
32
|
this.isPrimary = isPrimary;
|
|
33
33
|
this._log = this.manager._log.create("dc-manager");
|
|
34
34
|
this._log.prefix = `[DC ${dcId}] `;
|
|
35
|
+
const managerParams = this.manager.params;
|
|
35
36
|
const baseConnectionParams = () => ({
|
|
36
|
-
crypto:
|
|
37
|
+
crypto: managerParams.crypto,
|
|
37
38
|
initConnection: this.manager._initConnectionParams,
|
|
38
39
|
transport: this.manager._transport,
|
|
39
40
|
dc: this._dcs.media,
|
|
40
|
-
testMode:
|
|
41
|
+
testMode: managerParams.testMode,
|
|
41
42
|
reconnectionStrategy: this.manager._reconnectionStrategy,
|
|
42
|
-
layer:
|
|
43
|
-
disableUpdates:
|
|
44
|
-
readerMap:
|
|
45
|
-
writerMap:
|
|
46
|
-
usePfs:
|
|
43
|
+
layer: managerParams.layer,
|
|
44
|
+
disableUpdates: managerParams.disableUpdates,
|
|
45
|
+
readerMap: managerParams.readerMap,
|
|
46
|
+
writerMap: managerParams.writerMap,
|
|
47
|
+
usePfs: managerParams.usePfs,
|
|
47
48
|
isMainConnection: false,
|
|
48
49
|
isMainDcConnection: this.isPrimary,
|
|
49
|
-
inactivityTimeout:
|
|
50
|
-
enableErrorReporting:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
inactivityTimeout: managerParams.inactivityTimeout ?? 6e4,
|
|
51
|
+
enableErrorReporting: managerParams.enableErrorReporting,
|
|
52
|
+
// NB: we need a separate salts manager for each pfs connection, because server salts are auth_key-bound
|
|
53
|
+
salts: managerParams.usePfs ? new serverSalt.ServerSaltManager() : this._salts,
|
|
54
|
+
platform: managerParams.platform,
|
|
55
|
+
pingInterval: managerParams.pingInterval ?? 6e4
|
|
54
56
|
});
|
|
55
57
|
const mainParams = baseConnectionParams();
|
|
56
58
|
mainParams.isMainConnection = true;
|
|
@@ -70,19 +72,19 @@ class DcConnectionManager {
|
|
|
70
72
|
this.main = new multiSessionConnection.MultiSessionConnection(mainParams, mainCount, this._log, "MAIN");
|
|
71
73
|
this.upload = new multiSessionConnection.MultiSessionConnection(
|
|
72
74
|
baseConnectionParams(),
|
|
73
|
-
this.manager._connectionCount("upload", this.dcId,
|
|
75
|
+
this.manager._connectionCount("upload", this.dcId, managerParams.isPremium),
|
|
74
76
|
this._log,
|
|
75
77
|
"UPLOAD"
|
|
76
78
|
);
|
|
77
79
|
this.download = new multiSessionConnection.MultiSessionConnection(
|
|
78
80
|
baseConnectionParams(),
|
|
79
|
-
this.manager._connectionCount("download", this.dcId,
|
|
81
|
+
this.manager._connectionCount("download", this.dcId, managerParams.isPremium),
|
|
80
82
|
this._log,
|
|
81
83
|
"DOWNLOAD"
|
|
82
84
|
);
|
|
83
85
|
this.downloadSmall = new multiSessionConnection.MultiSessionConnection(
|
|
84
86
|
baseConnectionParams(),
|
|
85
|
-
this.manager._connectionCount("downloadSmall", this.dcId,
|
|
87
|
+
this.manager._connectionCount("downloadSmall", this.dcId, managerParams.isPremium),
|
|
86
88
|
this._log,
|
|
87
89
|
"DOWNLOAD_SMALL"
|
|
88
90
|
);
|
|
@@ -135,6 +137,9 @@ class DcConnectionManager {
|
|
|
135
137
|
});
|
|
136
138
|
});
|
|
137
139
|
connection.onFutureSalts.add((salts) => {
|
|
140
|
+
if (this.manager.params.usePfs && kind !== "main") {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
138
143
|
Promise.resolve(this.manager._storage.salts.store(this.dcId, salts)).catch(
|
|
139
144
|
(e) => this.manager.params.emitError(e)
|
|
140
145
|
);
|
|
@@ -220,7 +225,7 @@ class NetworkManager {
|
|
|
220
225
|
_: "initConnection",
|
|
221
226
|
deviceModel,
|
|
222
227
|
systemVersion: "1.0",
|
|
223
|
-
appVersion: "0.25.
|
|
228
|
+
appVersion: "0.25.2",
|
|
224
229
|
systemLangCode: "en",
|
|
225
230
|
langPack: "",
|
|
226
231
|
// "langPacks are for official apps only"
|
|
@@ -296,9 +301,7 @@ class NetworkManager {
|
|
|
296
301
|
async _getOtherDc(dcId) {
|
|
297
302
|
if (!this._dcConnections.has(dcId)) {
|
|
298
303
|
if (this._dcCreationPromise.has(dcId)) {
|
|
299
|
-
this._log.debug("waiting for dc %d to be created", dcId);
|
|
300
304
|
await this._dcCreationPromise.get(dcId);
|
|
301
|
-
this._log.debug("dc %d was created", dcId);
|
|
302
305
|
return utils.asNonNull(this._dcConnections.get(dcId));
|
|
303
306
|
}
|
|
304
307
|
const promise = new utils.Deferred();
|
|
@@ -313,7 +316,9 @@ class NetworkManager {
|
|
|
313
316
|
this._dcConnections.set(dcId, dc);
|
|
314
317
|
promise.resolve();
|
|
315
318
|
this._dcCreationPromise.delete(dcId);
|
|
319
|
+
this._log.debug("dc %d was created", dcId);
|
|
316
320
|
} catch (e) {
|
|
321
|
+
this._log.debug("dc %d was not created: %e", dcId, e);
|
|
317
322
|
promise.reject(e);
|
|
318
323
|
this._dcCreationPromise.delete(dcId);
|
|
319
324
|
return this._getOtherDc(dcId);
|
|
@@ -25,25 +25,27 @@ class DcConnectionManager {
|
|
|
25
25
|
this.isPrimary = isPrimary;
|
|
26
26
|
this._log = this.manager._log.create("dc-manager");
|
|
27
27
|
this._log.prefix = `[DC ${dcId}] `;
|
|
28
|
+
const managerParams = this.manager.params;
|
|
28
29
|
const baseConnectionParams = () => ({
|
|
29
|
-
crypto:
|
|
30
|
+
crypto: managerParams.crypto,
|
|
30
31
|
initConnection: this.manager._initConnectionParams,
|
|
31
32
|
transport: this.manager._transport,
|
|
32
33
|
dc: this._dcs.media,
|
|
33
|
-
testMode:
|
|
34
|
+
testMode: managerParams.testMode,
|
|
34
35
|
reconnectionStrategy: this.manager._reconnectionStrategy,
|
|
35
|
-
layer:
|
|
36
|
-
disableUpdates:
|
|
37
|
-
readerMap:
|
|
38
|
-
writerMap:
|
|
39
|
-
usePfs:
|
|
36
|
+
layer: managerParams.layer,
|
|
37
|
+
disableUpdates: managerParams.disableUpdates,
|
|
38
|
+
readerMap: managerParams.readerMap,
|
|
39
|
+
writerMap: managerParams.writerMap,
|
|
40
|
+
usePfs: managerParams.usePfs,
|
|
40
41
|
isMainConnection: false,
|
|
41
42
|
isMainDcConnection: this.isPrimary,
|
|
42
|
-
inactivityTimeout:
|
|
43
|
-
enableErrorReporting:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
inactivityTimeout: managerParams.inactivityTimeout ?? 6e4,
|
|
44
|
+
enableErrorReporting: managerParams.enableErrorReporting,
|
|
45
|
+
// NB: we need a separate salts manager for each pfs connection, because server salts are auth_key-bound
|
|
46
|
+
salts: managerParams.usePfs ? new ServerSaltManager() : this._salts,
|
|
47
|
+
platform: managerParams.platform,
|
|
48
|
+
pingInterval: managerParams.pingInterval ?? 6e4
|
|
47
49
|
});
|
|
48
50
|
const mainParams = baseConnectionParams();
|
|
49
51
|
mainParams.isMainConnection = true;
|
|
@@ -63,19 +65,19 @@ class DcConnectionManager {
|
|
|
63
65
|
this.main = new MultiSessionConnection(mainParams, mainCount, this._log, "MAIN");
|
|
64
66
|
this.upload = new MultiSessionConnection(
|
|
65
67
|
baseConnectionParams(),
|
|
66
|
-
this.manager._connectionCount("upload", this.dcId,
|
|
68
|
+
this.manager._connectionCount("upload", this.dcId, managerParams.isPremium),
|
|
67
69
|
this._log,
|
|
68
70
|
"UPLOAD"
|
|
69
71
|
);
|
|
70
72
|
this.download = new MultiSessionConnection(
|
|
71
73
|
baseConnectionParams(),
|
|
72
|
-
this.manager._connectionCount("download", this.dcId,
|
|
74
|
+
this.manager._connectionCount("download", this.dcId, managerParams.isPremium),
|
|
73
75
|
this._log,
|
|
74
76
|
"DOWNLOAD"
|
|
75
77
|
);
|
|
76
78
|
this.downloadSmall = new MultiSessionConnection(
|
|
77
79
|
baseConnectionParams(),
|
|
78
|
-
this.manager._connectionCount("downloadSmall", this.dcId,
|
|
80
|
+
this.manager._connectionCount("downloadSmall", this.dcId, managerParams.isPremium),
|
|
79
81
|
this._log,
|
|
80
82
|
"DOWNLOAD_SMALL"
|
|
81
83
|
);
|
|
@@ -128,6 +130,9 @@ class DcConnectionManager {
|
|
|
128
130
|
});
|
|
129
131
|
});
|
|
130
132
|
connection.onFutureSalts.add((salts) => {
|
|
133
|
+
if (this.manager.params.usePfs && kind !== "main") {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
131
136
|
Promise.resolve(this.manager._storage.salts.store(this.dcId, salts)).catch(
|
|
132
137
|
(e) => this.manager.params.emitError(e)
|
|
133
138
|
);
|
|
@@ -213,7 +218,7 @@ class NetworkManager {
|
|
|
213
218
|
_: "initConnection",
|
|
214
219
|
deviceModel,
|
|
215
220
|
systemVersion: "1.0",
|
|
216
|
-
appVersion: "0.25.
|
|
221
|
+
appVersion: "0.25.2",
|
|
217
222
|
systemLangCode: "en",
|
|
218
223
|
langPack: "",
|
|
219
224
|
// "langPacks are for official apps only"
|
|
@@ -289,9 +294,7 @@ class NetworkManager {
|
|
|
289
294
|
async _getOtherDc(dcId) {
|
|
290
295
|
if (!this._dcConnections.has(dcId)) {
|
|
291
296
|
if (this._dcCreationPromise.has(dcId)) {
|
|
292
|
-
this._log.debug("waiting for dc %d to be created", dcId);
|
|
293
297
|
await this._dcCreationPromise.get(dcId);
|
|
294
|
-
this._log.debug("dc %d was created", dcId);
|
|
295
298
|
return asNonNull(this._dcConnections.get(dcId));
|
|
296
299
|
}
|
|
297
300
|
const promise = new Deferred();
|
|
@@ -306,7 +309,9 @@ class NetworkManager {
|
|
|
306
309
|
this._dcConnections.set(dcId, dc);
|
|
307
310
|
promise.resolve();
|
|
308
311
|
this._dcCreationPromise.delete(dcId);
|
|
312
|
+
this._log.debug("dc %d was created", dcId);
|
|
309
313
|
} catch (e) {
|
|
314
|
+
this._log.debug("dc %d was not created: %e", dcId, e);
|
|
310
315
|
promise.reject(e);
|
|
311
316
|
this._dcCreationPromise.delete(dcId);
|
|
312
317
|
return this._getOtherDc(dcId);
|
package/package.json
CHANGED
package/worker.cjs
CHANGED
|
@@ -9,6 +9,7 @@ const port = require("./highlevel/worker/port.cjs");
|
|
|
9
9
|
const protocol = require("./highlevel/worker/protocol.cjs");
|
|
10
10
|
const worker = require("./highlevel/worker/worker.cjs");
|
|
11
11
|
exports.TelegramWorkerPort = port.TelegramWorkerPort;
|
|
12
|
+
exports.DEFAULT_WORKER_ID = protocol.DEFAULT_WORKER_ID;
|
|
12
13
|
exports.deserializeResult = protocol.deserializeResult;
|
|
13
14
|
exports.serializeResult = protocol.serializeResult;
|
|
14
15
|
exports.TelegramWorker = worker.TelegramWorker;
|
package/worker.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { TelegramWorkerPort } from "./highlevel/worker/port.js";
|
|
2
|
-
import { deserializeResult, serializeResult } from "./highlevel/worker/protocol.js";
|
|
2
|
+
import { DEFAULT_WORKER_ID, deserializeResult, serializeResult } from "./highlevel/worker/protocol.js";
|
|
3
3
|
import { TelegramWorker } from "./highlevel/worker/worker.js";
|
|
4
4
|
export {
|
|
5
|
+
DEFAULT_WORKER_ID,
|
|
5
6
|
TelegramWorker,
|
|
6
7
|
TelegramWorkerPort,
|
|
7
8
|
deserializeResult,
|