@mtcute/core 0.1.2 → 0.2.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/cjs/base-client.d.ts +3 -6
- package/cjs/base-client.js +12 -20
- package/cjs/base-client.js.map +1 -1
- package/cjs/network/index.d.ts +1 -1
- package/cjs/network/index.js.map +1 -1
- package/cjs/network/multi-session-connection.js +17 -4
- package/cjs/network/multi-session-connection.js.map +1 -1
- package/cjs/network/network-manager.d.ts +1 -1
- package/cjs/network/network-manager.js +12 -5
- package/cjs/network/network-manager.js.map +1 -1
- package/cjs/network/transports/intermediate.test.js +1 -3
- package/cjs/network/transports/intermediate.test.js.map +1 -1
- package/cjs/network/transports/tcp.test.js +96 -90
- package/cjs/network/transports/tcp.test.js.map +1 -1
- package/cjs/storage/abstract.d.ts +18 -0
- package/cjs/storage/abstract.js.map +1 -1
- package/cjs/storage/idb.d.ts +101 -0
- package/cjs/storage/idb.js +458 -0
- package/cjs/storage/idb.js.map +1 -0
- package/cjs/storage/idb.test.d.ts +1 -0
- package/cjs/storage/idb.test.js +21 -0
- package/cjs/storage/idb.test.js.map +1 -0
- package/cjs/storage/index.d.ts +0 -4
- package/cjs/storage/index.js +0 -4
- package/cjs/storage/index.js.map +1 -1
- package/cjs/storage/json-file.d.ts +12 -0
- package/cjs/storage/json-file.js +12 -0
- package/cjs/storage/json-file.js.map +1 -1
- package/cjs/storage/json.js +3 -2
- package/cjs/storage/json.js.map +1 -1
- package/cjs/storage/json.test.js +4 -5
- package/cjs/storage/json.test.js.map +1 -1
- package/cjs/storage/localstorage.d.ts +12 -0
- package/cjs/storage/localstorage.js +12 -0
- package/cjs/storage/localstorage.js.map +1 -1
- package/cjs/storage/memory.d.ts +12 -1
- package/cjs/storage/memory.js +65 -3
- package/cjs/storage/memory.js.map +1 -1
- package/cjs/storage/memory.test.js +2 -1
- package/cjs/storage/memory.test.js.map +1 -1
- package/cjs/utils/controllable-promise.d.ts +0 -5
- package/cjs/utils/controllable-promise.js +1 -7
- package/cjs/utils/controllable-promise.js.map +1 -1
- package/cjs/utils/crypto/mtproto.test.js +26 -23
- package/cjs/utils/crypto/mtproto.test.js.map +1 -1
- package/cjs/utils/crypto/node.test.js +9 -8
- package/cjs/utils/crypto/node.test.js.map +1 -1
- package/cjs/utils/crypto/utils.test.js +4 -4
- package/cjs/utils/crypto/utils.test.js.map +1 -1
- package/cjs/utils/logger.test.js +10 -8
- package/cjs/utils/logger.test.js.map +1 -1
- package/cjs/utils/peer-utils.js +3 -1
- package/cjs/utils/peer-utils.js.map +1 -1
- package/esm/base-client.d.ts +3 -6
- package/esm/base-client.js +2 -10
- package/esm/base-client.js.map +1 -1
- package/esm/network/index.d.ts +1 -1
- package/esm/network/index.js.map +1 -1
- package/esm/network/multi-session-connection.js +17 -4
- package/esm/network/multi-session-connection.js.map +1 -1
- package/esm/network/network-manager.d.ts +1 -1
- package/esm/network/network-manager.js +12 -5
- package/esm/network/network-manager.js.map +1 -1
- package/esm/network/transports/intermediate.test.js +1 -3
- package/esm/network/transports/intermediate.test.js.map +1 -1
- package/esm/network/transports/tcp.test.js +96 -90
- package/esm/network/transports/tcp.test.js.map +1 -1
- package/esm/storage/abstract.d.ts +18 -0
- package/esm/storage/abstract.js.map +1 -1
- package/esm/storage/idb.d.ts +101 -0
- package/esm/storage/idb.js +454 -0
- package/esm/storage/idb.js.map +1 -0
- package/esm/storage/idb.test.d.ts +1 -0
- package/esm/storage/idb.test.js +19 -0
- package/esm/storage/idb.test.js.map +1 -0
- package/esm/storage/index.d.ts +0 -4
- package/esm/storage/index.js +0 -4
- package/esm/storage/index.js.map +1 -1
- package/esm/storage/json-file.d.ts +12 -0
- package/esm/storage/json-file.js +12 -0
- package/esm/storage/json-file.js.map +1 -1
- package/esm/storage/json.js +3 -2
- package/esm/storage/json.js.map +1 -1
- package/esm/storage/json.test.js +4 -5
- package/esm/storage/json.test.js.map +1 -1
- package/esm/storage/localstorage.d.ts +12 -0
- package/esm/storage/localstorage.js +12 -0
- package/esm/storage/localstorage.js.map +1 -1
- package/esm/storage/memory.d.ts +12 -1
- package/esm/storage/memory.js +65 -3
- package/esm/storage/memory.js.map +1 -1
- package/esm/storage/memory.test.js +2 -1
- package/esm/storage/memory.test.js.map +1 -1
- package/esm/utils/controllable-promise.d.ts +0 -5
- package/esm/utils/controllable-promise.js +0 -5
- package/esm/utils/controllable-promise.js.map +1 -1
- package/esm/utils/crypto/mtproto.test.js +27 -24
- package/esm/utils/crypto/mtproto.test.js.map +1 -1
- package/esm/utils/crypto/node.test.js +9 -8
- package/esm/utils/crypto/node.test.js.map +1 -1
- package/esm/utils/crypto/utils.test.js +4 -4
- package/esm/utils/crypto/utils.test.js.map +1 -1
- package/esm/utils/logger.test.js +10 -8
- package/esm/utils/logger.test.js.map +1 -1
- package/esm/utils/peer-utils.js +3 -1
- package/esm/utils/peer-utils.js.map +1 -1
- package/package.json +20 -16
package/cjs/base-client.d.ts
CHANGED
|
@@ -20,10 +20,9 @@ export interface BaseTelegramClientOptions {
|
|
|
20
20
|
*/
|
|
21
21
|
apiHash: string;
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
* If omitted, {@link MemoryStorage} is used
|
|
23
|
+
* Storage to use for this client.
|
|
25
24
|
*/
|
|
26
|
-
storage
|
|
25
|
+
storage: ITelegramStorage;
|
|
27
26
|
/**
|
|
28
27
|
* Cryptography provider factory to allow delegating
|
|
29
28
|
* crypto to native addon, worker, etc.
|
|
@@ -260,10 +259,8 @@ export declare class BaseTelegramClient extends EventEmitter {
|
|
|
260
259
|
_emitError(err: unknown, connection?: SessionConnection): void;
|
|
261
260
|
/**
|
|
262
261
|
* Adds all peers from a given object to entity cache in storage.
|
|
263
|
-
*
|
|
264
|
-
* @returns `true` if there were any `min` peers
|
|
265
262
|
*/
|
|
266
|
-
_cachePeersFrom(obj: object): Promise<
|
|
263
|
+
_cachePeersFrom(obj: object): Promise<void>;
|
|
267
264
|
/**
|
|
268
265
|
* Export current session to a single *LONG* string, containing
|
|
269
266
|
* all the needed information.
|
package/cjs/base-client.js
CHANGED
|
@@ -12,8 +12,7 @@ const reader_js_1 = require("@mtcute/tl/binary/reader.js");
|
|
|
12
12
|
const writer_js_1 = require("@mtcute/tl/binary/writer.js");
|
|
13
13
|
const config_manager_js_1 = require("./network/config-manager.js");
|
|
14
14
|
const network_manager_js_1 = require("./network/network-manager.js");
|
|
15
|
-
const index_js_1 = require("./
|
|
16
|
-
const index_js_2 = require("./utils/index.js");
|
|
15
|
+
const index_js_1 = require("./utils/index.js");
|
|
17
16
|
/**
|
|
18
17
|
* Basic Telegram client that only implements the bare minimum
|
|
19
18
|
* to make RPC calls and receive low-level updates.
|
|
@@ -26,7 +25,7 @@ class BaseTelegramClient extends events_1.default {
|
|
|
26
25
|
this._config = new config_manager_js_1.ConfigManager(() => this.call({ _: 'help.getConfig' }));
|
|
27
26
|
// not really connected, but rather "connect() was called"
|
|
28
27
|
this._connected = false;
|
|
29
|
-
this.log = new
|
|
28
|
+
this.log = new index_js_1.LogManager('client');
|
|
30
29
|
this._beforeStorageSave = [];
|
|
31
30
|
const apiId = typeof opts.apiId === 'string' ? parseInt(opts.apiId) : opts.apiId;
|
|
32
31
|
if (isNaN(apiId)) {
|
|
@@ -35,18 +34,18 @@ class BaseTelegramClient extends events_1.default {
|
|
|
35
34
|
if (opts.logLevel !== undefined) {
|
|
36
35
|
this.log.level = opts.logLevel;
|
|
37
36
|
}
|
|
38
|
-
this.crypto = (opts.crypto ??
|
|
39
|
-
this.storage = opts.storage
|
|
37
|
+
this.crypto = (opts.crypto ?? index_js_1.defaultCryptoProviderFactory)();
|
|
38
|
+
this.storage = opts.storage;
|
|
40
39
|
this._apiHash = opts.apiHash;
|
|
41
40
|
this._useIpv6 = Boolean(opts.useIpv6);
|
|
42
41
|
this._testMode = Boolean(opts.testMode);
|
|
43
42
|
let dc = opts.defaultDcs;
|
|
44
43
|
if (!dc) {
|
|
45
44
|
if (this._testMode) {
|
|
46
|
-
dc = this._useIpv6 ?
|
|
45
|
+
dc = this._useIpv6 ? index_js_1.defaultTestIpv6Dc : index_js_1.defaultTestDc;
|
|
47
46
|
}
|
|
48
47
|
else {
|
|
49
|
-
dc = this._useIpv6 ?
|
|
48
|
+
dc = this._useIpv6 ? index_js_1.defaultProductionIpv6Dc : index_js_1.defaultProductionDc;
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
this._defaultDcs = dc;
|
|
@@ -109,7 +108,7 @@ class BaseTelegramClient extends events_1.default {
|
|
|
109
108
|
await this._connected;
|
|
110
109
|
return;
|
|
111
110
|
}
|
|
112
|
-
const promise = (this._connected = (0,
|
|
111
|
+
const promise = (this._connected = (0, index_js_1.createControllablePromise)());
|
|
113
112
|
await this.crypto.initialize?.();
|
|
114
113
|
await this._loadStorage();
|
|
115
114
|
const primaryDc = await this.storage.getDefaultDcs();
|
|
@@ -117,7 +116,7 @@ class BaseTelegramClient extends events_1.default {
|
|
|
117
116
|
this._defaultDcs = primaryDc;
|
|
118
117
|
const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id);
|
|
119
118
|
if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {
|
|
120
|
-
const data = (0,
|
|
119
|
+
const data = (0, index_js_1.readStringSession)(this._readerMap, this._importFrom);
|
|
121
120
|
if (data.testMode !== this._testMode) {
|
|
122
121
|
throw new Error('This session string is not for the current backend. ' +
|
|
123
122
|
`Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${this._testMode ? 'test' : 'prod'}`);
|
|
@@ -213,19 +212,13 @@ class BaseTelegramClient extends events_1.default {
|
|
|
213
212
|
}
|
|
214
213
|
/**
|
|
215
214
|
* Adds all peers from a given object to entity cache in storage.
|
|
216
|
-
*
|
|
217
|
-
* @returns `true` if there were any `min` peers
|
|
218
215
|
*/
|
|
219
216
|
async _cachePeersFrom(obj) {
|
|
220
217
|
const parsedPeers = [];
|
|
221
|
-
let hadMin = false;
|
|
222
218
|
let count = 0;
|
|
223
|
-
for (const peer of (0,
|
|
219
|
+
for (const peer of (0, index_js_1.getAllPeersFrom)(obj)) {
|
|
224
220
|
if (peer.min) {
|
|
225
|
-
//
|
|
226
|
-
// see this thread: https://t.me/tdlibchat/15084
|
|
227
|
-
hadMin = true;
|
|
228
|
-
this.log.debug('received min peer: %j', peer);
|
|
221
|
+
// no point in caching min peers as we can't use them
|
|
229
222
|
continue;
|
|
230
223
|
}
|
|
231
224
|
count += 1;
|
|
@@ -260,7 +253,7 @@ class BaseTelegramClient extends events_1.default {
|
|
|
260
253
|
continue;
|
|
261
254
|
}
|
|
262
255
|
parsedPeers.push({
|
|
263
|
-
id: (0,
|
|
256
|
+
id: (0, index_js_1.toggleChannelIdMark)(peer.id),
|
|
264
257
|
accessHash: peer.accessHash,
|
|
265
258
|
username: peer._ === 'channel' ? peer.username?.toLowerCase() : undefined,
|
|
266
259
|
type: 'channel',
|
|
@@ -273,7 +266,6 @@ class BaseTelegramClient extends events_1.default {
|
|
|
273
266
|
await this.storage.updatePeers(parsedPeers);
|
|
274
267
|
this.log.debug('cached %d peers', count);
|
|
275
268
|
}
|
|
276
|
-
return hadMin;
|
|
277
269
|
}
|
|
278
270
|
/**
|
|
279
271
|
* Export current session to a single *LONG* string, containing
|
|
@@ -297,7 +289,7 @@ class BaseTelegramClient extends events_1.default {
|
|
|
297
289
|
const authKey = await this.storage.getAuthKeyFor(primaryDcs.main.id);
|
|
298
290
|
if (!authKey)
|
|
299
291
|
throw new Error('Auth key is not ready yet');
|
|
300
|
-
return (0,
|
|
292
|
+
return (0, index_js_1.writeStringSession)(this._writerMap, {
|
|
301
293
|
version: 2,
|
|
302
294
|
self: await this.storage.getSelf(),
|
|
303
295
|
testMode: this._testMode,
|
package/cjs/base-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-client.js","sourceRoot":"","sources":["../../src/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport EventEmitter from 'events'\nimport Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'\nimport { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { ConfigManager } from './network/config-manager.js'\nimport { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js'\nimport { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js'\nimport { PersistentConnectionParams } from './network/persistent-connection.js'\nimport { ITelegramStorage, MemoryStorage } from './storage/index.js'\nimport { MustEqual } from './types/index.js'\nimport {\n ControllablePromise,\n createControllablePromise,\n CryptoProviderFactory,\n defaultCryptoProviderFactory,\n defaultProductionDc,\n defaultProductionIpv6Dc,\n defaultTestDc,\n defaultTestIpv6Dc,\n getAllPeersFrom,\n ICryptoProvider,\n LogManager,\n readStringSession,\n toggleChannelIdMark,\n writeStringSession,\n} from './utils/index.js'\n\n/** Options for {@link BaseTelegramClient} */\nexport interface BaseTelegramClientOptions {\n /**\n * API ID from my.telegram.org\n */\n apiId: number | string\n /**\n * API hash from my.telegram.org\n */\n apiHash: string\n\n /**\n * Telegram storage to use.\n * If omitted, {@link MemoryStorage} is used\n */\n storage?: ITelegramStorage\n\n /**\n * Cryptography provider factory to allow delegating\n * crypto to native addon, worker, etc.\n */\n crypto?: CryptoProviderFactory\n\n /**\n * Whether to use IPv6 datacenters\n * (IPv6 will be preferred when choosing a DC by id)\n * (default: false)\n */\n useIpv6?: boolean\n\n /**\n * Primary DC to use for initial connection.\n * This does not mean this will be the only DC used,\n * nor that this DC will actually be primary, this only\n * determines the first DC the library will try to connect to.\n * Can be used to connect to other networks (like test DCs).\n *\n * When session already contains primary DC, this parameter is ignored.\n *\n * @default Production DC 2.\n */\n defaultDcs?: ITelegramStorage.DcOptions\n\n /**\n * Whether to connect to test servers.\n *\n * If passed, {@link defaultDc} defaults to Test DC 2.\n *\n * **Must** be passed if using test servers, even if\n * you passed custom {@link defaultDc}\n */\n testMode?: boolean\n\n /**\n * Additional options for initConnection call.\n * `apiId` and `query` are not available and will be ignored.\n * Omitted values will be filled with defaults\n */\n initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>\n\n /**\n * Transport factory to use in the client.\n *\n * @default platform-specific transport: WebSocket on the web, TCP in node\n */\n transport?: TransportFactory\n\n /**\n * Reconnection strategy.\n *\n * @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)\n */\n reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>\n\n /**\n * Maximum duration of a flood_wait that will be waited automatically.\n * Flood waits above this threshold will throw a FloodWaitError.\n * Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params\n *\n * @default 10000\n */\n floodSleepThreshold?: number\n\n /**\n * Maximum number of retries when calling RPC methods.\n * Call is retried when InternalError or FloodWaitError is encountered.\n * Can be set to Infinity.\n *\n * @default 5\n */\n maxRetryCount?: number\n\n /**\n * If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,\n * effectively disabling the server-sent events for the clients.\n * May be useful in some cases.\n *\n * Note that this only wraps calls made with `.call()` within the primary\n * connection. Additional connections and direct `.sendForResult()` calls\n * must be wrapped manually.\n *\n * @default false\n */\n disableUpdates?: boolean\n\n /**\n * mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s\n * [error reporting service](https://rpc.pwrtelegram.xyz/).\n *\n * This is fully anonymous (except maybe IP) and is only used to improve the library\n * and developer experience for everyone working with MTProto. This is fully opt-in,\n * and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.\n *\n * @default false\n */\n enableErrorReporting?: boolean\n\n /**\n * If true, RPC errors will have a stack trace of the initial `.call()`\n * or `.sendForResult()` call position, which drastically improves\n * debugging experience.<br>\n * If false, they will have a stack trace of mtcute internals.\n *\n * Internally this creates a stack capture before every RPC call\n * and stores it until the result is received. This might\n * use a lot more memory than normal, thus can be disabled here.\n *\n * @default true\n */\n niceStacks?: boolean\n\n /**\n * Extra parameters for {@link NetworkManager}\n */\n network?: NetworkManagerExtraParams\n\n /**\n * Set logging level for the client.\n *\n * See static members of {@link LogManager} for possible values.\n */\n logLevel?: number\n\n /**\n * **EXPERT USE ONLY!**\n *\n * Override TL layer used for the connection.\n *\n * **Does not** change the schema used.\n */\n overrideLayer?: number\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override reader map used for the connection.\n */\n readerMap?: TlReaderMap\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override writer map used for the connection.\n */\n writerMap?: TlWriterMap\n}\n\n/**\n * Basic Telegram client that only implements the bare minimum\n * to make RPC calls and receive low-level updates.\n */\nexport class BaseTelegramClient extends EventEmitter {\n /**\n * Crypto provider taken from {@link BaseTelegramClientOptions.crypto}\n */\n readonly crypto: ICryptoProvider\n\n /**\n * Telegram storage taken from {@link BaseTelegramClientOptions.storage}\n */\n readonly storage: ITelegramStorage\n\n /**\n * API hash taken from {@link BaseTelegramClientOptions.apiHash}\n */\n protected readonly _apiHash: string\n\n /**\n * \"Use IPv6\" taken from {@link BaseTelegramClientOptions.useIpv6}\n */\n protected readonly _useIpv6: boolean\n\n /**\n * \"Test mode\" taken from {@link BaseTelegramClientOptions.testMode}\n */\n protected readonly _testMode: boolean\n\n /**\n * Primary DCs taken from {@link BaseTelegramClientOptions.defaultDcs},\n * loaded from session or changed by other means (like redirecting).\n */\n protected _defaultDcs: ITelegramStorage.DcOptions\n\n private _niceStacks: boolean\n /** TL layer used by the client */\n readonly _layer: number\n /** TL readers map used by the client */\n readonly _readerMap: TlReaderMap\n /** TL writers map used by the client */\n readonly _writerMap: TlWriterMap\n\n /** Unix timestamp when the last update was received */\n protected _lastUpdateTime = 0\n\n readonly _config = new ConfigManager(() => this.call({ _: 'help.getConfig' }))\n\n // not really connected, but rather \"connect() was called\"\n private _connected: ControllablePromise<void> | boolean = false\n\n private _onError?: (err: unknown, connection?: SessionConnection) => void\n\n private _importFrom?: string\n private _importForce?: boolean\n\n readonly log = new LogManager('client')\n readonly network: NetworkManager\n\n constructor(opts: BaseTelegramClientOptions) {\n super()\n\n const apiId = typeof opts.apiId === 'string' ? parseInt(opts.apiId) : opts.apiId\n\n if (isNaN(apiId)) {\n throw new Error('apiId must be a number or a numeric string!')\n }\n\n if (opts.logLevel !== undefined) {\n this.log.level = opts.logLevel\n }\n\n this.crypto = (opts.crypto ?? defaultCryptoProviderFactory)()\n this.storage = opts.storage ?? new MemoryStorage()\n this._apiHash = opts.apiHash\n this._useIpv6 = Boolean(opts.useIpv6)\n this._testMode = Boolean(opts.testMode)\n\n let dc = opts.defaultDcs\n\n if (!dc) {\n if (this._testMode) {\n dc = this._useIpv6 ? defaultTestIpv6Dc : defaultTestDc\n } else {\n dc = this._useIpv6 ? defaultProductionIpv6Dc : defaultProductionDc\n }\n }\n\n this._defaultDcs = dc\n this._niceStacks = opts.niceStacks ?? true\n\n this._layer = opts.overrideLayer ?? tl.LAYER\n this._readerMap = opts.readerMap ?? defaultReaderMap\n this._writerMap = opts.writerMap ?? defaultWriterMap\n\n this.network = new NetworkManager(\n {\n apiId,\n crypto: this.crypto,\n disableUpdates: opts.disableUpdates ?? false,\n initConnectionOptions: opts.initConnectionOptions,\n layer: this._layer,\n log: this.log,\n readerMap: this._readerMap,\n writerMap: this._writerMap,\n reconnectionStrategy: opts.reconnectionStrategy,\n storage: this.storage,\n testMode: this._testMode,\n transport: opts.transport,\n _emitError: this._emitError.bind(this),\n floodSleepThreshold: opts.floodSleepThreshold ?? 10000,\n maxRetryCount: opts.maxRetryCount ?? 5,\n isPremium: false,\n useIpv6: Boolean(opts.useIpv6),\n keepAliveAction: this._keepAliveAction.bind(this),\n enableErrorReporting: opts.enableErrorReporting ?? false,\n onUsable: () => this.emit('usable'),\n ...(opts.network ?? {}),\n },\n this._config,\n )\n\n this.storage.setup?.(this.log, this._readerMap, this._writerMap)\n }\n\n protected _keepAliveAction(): void {\n this.emit('keep_alive')\n }\n\n protected async _loadStorage(): Promise<void> {\n await this.storage.load?.()\n }\n\n _beforeStorageSave: (() => Promise<void>)[] = []\n\n beforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave.push(cb)\n }\n\n offBeforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave = this._beforeStorageSave.filter((x) => x !== cb)\n }\n\n async saveStorage(): Promise<void> {\n for (const cb of this._beforeStorageSave) {\n await cb()\n }\n await this.storage.save?.()\n }\n\n /**\n * Initialize the connection to the primary DC.\n *\n * You shouldn't usually call this method directly as it is called\n * implicitly the first time you call {@link call}.\n */\n async connect(): Promise<void> {\n if (this._connected) {\n // avoid double-connect\n await this._connected\n\n return\n }\n\n const promise = (this._connected = createControllablePromise())\n\n await this.crypto.initialize?.()\n await this._loadStorage()\n const primaryDc = await this.storage.getDefaultDcs()\n if (primaryDc !== null) this._defaultDcs = primaryDc\n\n const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id)\n\n if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {\n const data = readStringSession(this._readerMap, this._importFrom)\n\n if (data.testMode !== this._testMode) {\n throw new Error(\n 'This session string is not for the current backend. ' +\n `Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${\n this._testMode ? 'test' : 'prod'\n }`,\n )\n }\n\n this._defaultDcs = data.primaryDcs\n await this.storage.setDefaultDcs(data.primaryDcs)\n\n if (data.self) {\n await this.storage.setSelf(data.self)\n }\n\n // await this.primaryConnection.setupKeys(data.authKey)\n await this.storage.setAuthKeyFor(data.primaryDcs.main.id, data.authKey)\n\n await this.saveStorage()\n }\n\n this.emit('before_connect')\n\n this.network\n .connect(this._defaultDcs)\n .then(() => {\n promise.resolve()\n this._connected = true\n })\n .catch((err: Error) => this._emitError(err))\n }\n\n /**\n * Close all connections and finalize the client.\n */\n async close(): Promise<void> {\n this.emit('before_close')\n\n this._config.destroy()\n this.network.destroy()\n\n await this.saveStorage()\n await this.storage.destroy?.()\n\n this.emit('closed')\n }\n\n /**\n * Make an RPC call to the primary DC.\n * This method handles DC migration, flood waits and retries automatically.\n *\n * If you want more low-level control, use\n * `primaryConnection.sendForResult()` (which is what this method wraps)\n *\n * This method is still quite low-level and you shouldn't use this\n * when using high-level API provided by `@mtcute/client`.\n *\n * @param message RPC method to call\n * @param params Additional call parameters\n */\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._connected !== true) {\n await this.connect()\n }\n\n const stack = this._niceStacks ? new Error().stack : undefined\n\n const res = await this.network.call(message, params, stack)\n await this._cachePeersFrom(res)\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return res\n }\n\n /**\n * Change transport for the client.\n *\n * Can be used, for example, to change proxy at runtime\n *\n * This effectively calls `changeTransport()` on\n * `primaryConnection` and all additional connections.\n *\n * @param factory New transport factory\n */\n changeTransport(factory: TransportFactory): void {\n this.network.changeTransport(factory)\n }\n\n /**\n * Register an error handler for the client\n *\n * @param handler\n * Error handler. Called with one or two parameters.\n * The first one is always the error, and the second is\n * the connection in which the error has occurred, in case\n * this was connection-related error.\n */\n onError(handler: (err: unknown, connection?: SessionConnection) => void): void {\n this._onError = handler\n }\n\n notifyLoggedIn(auth: tl.auth.RawAuthorization): void {\n this.network.notifyLoggedIn(auth)\n this.emit('logged_in', auth)\n }\n\n _emitError(err: unknown, connection?: SessionConnection): void {\n if (this._onError) {\n this._onError(err, connection)\n } else {\n console.error(err)\n }\n }\n\n /**\n * Adds all peers from a given object to entity cache in storage.\n *\n * @returns `true` if there were any `min` peers\n */\n async _cachePeersFrom(obj: object): Promise<boolean> {\n const parsedPeers: ITelegramStorage.PeerInfo[] = []\n\n let hadMin = false\n let count = 0\n\n for (const peer of getAllPeersFrom(obj as tl.TlObject)) {\n if ((peer as any).min) {\n // absolutely incredible min peer handling, courtesy of levlam.\n // see this thread: https://t.me/tdlibchat/15084\n hadMin = true\n this.log.debug('received min peer: %j', peer)\n continue\n }\n\n count += 1\n\n switch (peer._) {\n case 'user':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n\n parsedPeers.push({\n id: peer.id,\n accessHash: peer.accessHash,\n username: peer.username?.toLowerCase(),\n phone: peer.phone,\n type: 'user',\n full: peer,\n })\n break\n case 'chat':\n case 'chatForbidden':\n parsedPeers.push({\n id: -peer.id,\n accessHash: Long.ZERO,\n type: 'chat',\n full: peer,\n })\n break\n case 'channel':\n case 'channelForbidden':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n parsedPeers.push({\n id: toggleChannelIdMark(peer.id),\n accessHash: peer.accessHash,\n username: peer._ === 'channel' ? peer.username?.toLowerCase() : undefined,\n type: 'channel',\n full: peer,\n })\n break\n }\n }\n\n if (count > 0) {\n await this.storage.updatePeers(parsedPeers)\n this.log.debug('cached %d peers', count)\n }\n\n return hadMin\n }\n\n /**\n * Export current session to a single *LONG* string, containing\n * all the needed information.\n *\n * > **Warning!** Anyone with this string will be able\n * > to authorize as you and do anything. Treat this\n * > as your password, and never give it away!\n * >\n * > In case you have accidentally leaked this string,\n * > make sure to revoke this session in account settings:\n * > \"Privacy & Security\" > \"Active sessions\" >\n * > find the one containing `mtcute` > Revoke,\n * > or, in case this is a bot, revoke bot token\n * > with [@BotFather](//t.me/botfather)\n */\n async exportSession(): Promise<string> {\n const primaryDcs = await this.storage.getDefaultDcs()\n if (!primaryDcs) throw new Error('No default DC set')\n\n const authKey = await this.storage.getAuthKeyFor(primaryDcs.main.id)\n if (!authKey) throw new Error('Auth key is not ready yet')\n\n return writeStringSession(this._writerMap, {\n version: 2,\n self: await this.storage.getSelf(),\n testMode: this._testMode,\n primaryDcs,\n authKey,\n })\n }\n\n /**\n * Request the session to be imported from the given session string.\n *\n * Note that the string will not be parsed and imported right away,\n * instead, it will be imported when `connect()` is called\n *\n * Also note that the session will only be imported in case\n * the storage is missing authorization (i.e. does not contain\n * auth key for the primary DC), otherwise it will be ignored (unless `force).\n *\n * @param session Session string to import\n * @param force Whether to overwrite existing session\n */\n importSession(session: string, force = false): void {\n this._importFrom = session\n this._importForce = force\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"base-client.js","sourceRoot":"","sources":["../../src/base-client.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport EventEmitter from 'events'\nimport Long from 'long'\n\nimport { tl } from '@mtcute/tl'\nimport { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'\nimport { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { ConfigManager } from './network/config-manager.js'\nimport { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js'\nimport { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js'\nimport { PersistentConnectionParams } from './network/persistent-connection.js'\nimport { ITelegramStorage } from './storage/index.js'\nimport { MustEqual } from './types/index.js'\nimport {\n ControllablePromise,\n createControllablePromise,\n CryptoProviderFactory,\n defaultCryptoProviderFactory,\n defaultProductionDc,\n defaultProductionIpv6Dc,\n defaultTestDc,\n defaultTestIpv6Dc,\n getAllPeersFrom,\n ICryptoProvider,\n LogManager,\n readStringSession,\n toggleChannelIdMark,\n writeStringSession,\n} from './utils/index.js'\n\n/** Options for {@link BaseTelegramClient} */\nexport interface BaseTelegramClientOptions {\n /**\n * API ID from my.telegram.org\n */\n apiId: number | string\n /**\n * API hash from my.telegram.org\n */\n apiHash: string\n\n /**\n * Storage to use for this client.\n */\n storage: ITelegramStorage\n\n /**\n * Cryptography provider factory to allow delegating\n * crypto to native addon, worker, etc.\n */\n crypto?: CryptoProviderFactory\n\n /**\n * Whether to use IPv6 datacenters\n * (IPv6 will be preferred when choosing a DC by id)\n * (default: false)\n */\n useIpv6?: boolean\n\n /**\n * Primary DC to use for initial connection.\n * This does not mean this will be the only DC used,\n * nor that this DC will actually be primary, this only\n * determines the first DC the library will try to connect to.\n * Can be used to connect to other networks (like test DCs).\n *\n * When session already contains primary DC, this parameter is ignored.\n *\n * @default Production DC 2.\n */\n defaultDcs?: ITelegramStorage.DcOptions\n\n /**\n * Whether to connect to test servers.\n *\n * If passed, {@link defaultDc} defaults to Test DC 2.\n *\n * **Must** be passed if using test servers, even if\n * you passed custom {@link defaultDc}\n */\n testMode?: boolean\n\n /**\n * Additional options for initConnection call.\n * `apiId` and `query` are not available and will be ignored.\n * Omitted values will be filled with defaults\n */\n initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>\n\n /**\n * Transport factory to use in the client.\n *\n * @default platform-specific transport: WebSocket on the web, TCP in node\n */\n transport?: TransportFactory\n\n /**\n * Reconnection strategy.\n *\n * @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)\n */\n reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>\n\n /**\n * Maximum duration of a flood_wait that will be waited automatically.\n * Flood waits above this threshold will throw a FloodWaitError.\n * Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params\n *\n * @default 10000\n */\n floodSleepThreshold?: number\n\n /**\n * Maximum number of retries when calling RPC methods.\n * Call is retried when InternalError or FloodWaitError is encountered.\n * Can be set to Infinity.\n *\n * @default 5\n */\n maxRetryCount?: number\n\n /**\n * If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,\n * effectively disabling the server-sent events for the clients.\n * May be useful in some cases.\n *\n * Note that this only wraps calls made with `.call()` within the primary\n * connection. Additional connections and direct `.sendForResult()` calls\n * must be wrapped manually.\n *\n * @default false\n */\n disableUpdates?: boolean\n\n /**\n * mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s\n * [error reporting service](https://rpc.pwrtelegram.xyz/).\n *\n * This is fully anonymous (except maybe IP) and is only used to improve the library\n * and developer experience for everyone working with MTProto. This is fully opt-in,\n * and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.\n *\n * @default false\n */\n enableErrorReporting?: boolean\n\n /**\n * If true, RPC errors will have a stack trace of the initial `.call()`\n * or `.sendForResult()` call position, which drastically improves\n * debugging experience.<br>\n * If false, they will have a stack trace of mtcute internals.\n *\n * Internally this creates a stack capture before every RPC call\n * and stores it until the result is received. This might\n * use a lot more memory than normal, thus can be disabled here.\n *\n * @default true\n */\n niceStacks?: boolean\n\n /**\n * Extra parameters for {@link NetworkManager}\n */\n network?: NetworkManagerExtraParams\n\n /**\n * Set logging level for the client.\n *\n * See static members of {@link LogManager} for possible values.\n */\n logLevel?: number\n\n /**\n * **EXPERT USE ONLY!**\n *\n * Override TL layer used for the connection.\n *\n * **Does not** change the schema used.\n */\n overrideLayer?: number\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override reader map used for the connection.\n */\n readerMap?: TlReaderMap\n\n /**\n * **EXPERT USE ONLY**\n *\n * Override writer map used for the connection.\n */\n writerMap?: TlWriterMap\n}\n\n/**\n * Basic Telegram client that only implements the bare minimum\n * to make RPC calls and receive low-level updates.\n */\nexport class BaseTelegramClient extends EventEmitter {\n /**\n * Crypto provider taken from {@link BaseTelegramClientOptions.crypto}\n */\n readonly crypto: ICryptoProvider\n\n /**\n * Telegram storage taken from {@link BaseTelegramClientOptions.storage}\n */\n readonly storage: ITelegramStorage\n\n /**\n * API hash taken from {@link BaseTelegramClientOptions.apiHash}\n */\n protected readonly _apiHash: string\n\n /**\n * \"Use IPv6\" taken from {@link BaseTelegramClientOptions.useIpv6}\n */\n protected readonly _useIpv6: boolean\n\n /**\n * \"Test mode\" taken from {@link BaseTelegramClientOptions.testMode}\n */\n protected readonly _testMode: boolean\n\n /**\n * Primary DCs taken from {@link BaseTelegramClientOptions.defaultDcs},\n * loaded from session or changed by other means (like redirecting).\n */\n protected _defaultDcs: ITelegramStorage.DcOptions\n\n private _niceStacks: boolean\n /** TL layer used by the client */\n readonly _layer: number\n /** TL readers map used by the client */\n readonly _readerMap: TlReaderMap\n /** TL writers map used by the client */\n readonly _writerMap: TlWriterMap\n\n /** Unix timestamp when the last update was received */\n protected _lastUpdateTime = 0\n\n readonly _config = new ConfigManager(() => this.call({ _: 'help.getConfig' }))\n\n // not really connected, but rather \"connect() was called\"\n private _connected: ControllablePromise<void> | boolean = false\n\n private _onError?: (err: unknown, connection?: SessionConnection) => void\n\n private _importFrom?: string\n private _importForce?: boolean\n\n readonly log = new LogManager('client')\n readonly network: NetworkManager\n\n constructor(opts: BaseTelegramClientOptions) {\n super()\n\n const apiId = typeof opts.apiId === 'string' ? parseInt(opts.apiId) : opts.apiId\n\n if (isNaN(apiId)) {\n throw new Error('apiId must be a number or a numeric string!')\n }\n\n if (opts.logLevel !== undefined) {\n this.log.level = opts.logLevel\n }\n\n this.crypto = (opts.crypto ?? defaultCryptoProviderFactory)()\n\n this.storage = opts.storage\n this._apiHash = opts.apiHash\n this._useIpv6 = Boolean(opts.useIpv6)\n this._testMode = Boolean(opts.testMode)\n\n let dc = opts.defaultDcs\n\n if (!dc) {\n if (this._testMode) {\n dc = this._useIpv6 ? defaultTestIpv6Dc : defaultTestDc\n } else {\n dc = this._useIpv6 ? defaultProductionIpv6Dc : defaultProductionDc\n }\n }\n\n this._defaultDcs = dc\n this._niceStacks = opts.niceStacks ?? true\n\n this._layer = opts.overrideLayer ?? tl.LAYER\n this._readerMap = opts.readerMap ?? defaultReaderMap\n this._writerMap = opts.writerMap ?? defaultWriterMap\n\n this.network = new NetworkManager(\n {\n apiId,\n crypto: this.crypto,\n disableUpdates: opts.disableUpdates ?? false,\n initConnectionOptions: opts.initConnectionOptions,\n layer: this._layer,\n log: this.log,\n readerMap: this._readerMap,\n writerMap: this._writerMap,\n reconnectionStrategy: opts.reconnectionStrategy,\n storage: this.storage,\n testMode: this._testMode,\n transport: opts.transport,\n _emitError: this._emitError.bind(this),\n floodSleepThreshold: opts.floodSleepThreshold ?? 10000,\n maxRetryCount: opts.maxRetryCount ?? 5,\n isPremium: false,\n useIpv6: Boolean(opts.useIpv6),\n keepAliveAction: this._keepAliveAction.bind(this),\n enableErrorReporting: opts.enableErrorReporting ?? false,\n onUsable: () => this.emit('usable'),\n ...(opts.network ?? {}),\n },\n this._config,\n )\n\n this.storage.setup?.(this.log, this._readerMap, this._writerMap)\n }\n\n protected _keepAliveAction(): void {\n this.emit('keep_alive')\n }\n\n protected async _loadStorage(): Promise<void> {\n await this.storage.load?.()\n }\n\n _beforeStorageSave: (() => Promise<void>)[] = []\n\n beforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave.push(cb)\n }\n\n offBeforeStorageSave(cb: () => Promise<void>): void {\n this._beforeStorageSave = this._beforeStorageSave.filter((x) => x !== cb)\n }\n\n async saveStorage(): Promise<void> {\n for (const cb of this._beforeStorageSave) {\n await cb()\n }\n await this.storage.save?.()\n }\n\n /**\n * Initialize the connection to the primary DC.\n *\n * You shouldn't usually call this method directly as it is called\n * implicitly the first time you call {@link call}.\n */\n async connect(): Promise<void> {\n if (this._connected) {\n // avoid double-connect\n await this._connected\n\n return\n }\n\n const promise = (this._connected = createControllablePromise())\n\n await this.crypto.initialize?.()\n await this._loadStorage()\n const primaryDc = await this.storage.getDefaultDcs()\n if (primaryDc !== null) this._defaultDcs = primaryDc\n\n const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id)\n\n if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {\n const data = readStringSession(this._readerMap, this._importFrom)\n\n if (data.testMode !== this._testMode) {\n throw new Error(\n 'This session string is not for the current backend. ' +\n `Session is ${data.testMode ? 'test' : 'prod'}, but the client is ${\n this._testMode ? 'test' : 'prod'\n }`,\n )\n }\n\n this._defaultDcs = data.primaryDcs\n await this.storage.setDefaultDcs(data.primaryDcs)\n\n if (data.self) {\n await this.storage.setSelf(data.self)\n }\n\n // await this.primaryConnection.setupKeys(data.authKey)\n await this.storage.setAuthKeyFor(data.primaryDcs.main.id, data.authKey)\n\n await this.saveStorage()\n }\n\n this.emit('before_connect')\n\n this.network\n .connect(this._defaultDcs)\n .then(() => {\n promise.resolve()\n this._connected = true\n })\n .catch((err: Error) => this._emitError(err))\n }\n\n /**\n * Close all connections and finalize the client.\n */\n async close(): Promise<void> {\n this.emit('before_close')\n\n this._config.destroy()\n this.network.destroy()\n\n await this.saveStorage()\n await this.storage.destroy?.()\n\n this.emit('closed')\n }\n\n /**\n * Make an RPC call to the primary DC.\n * This method handles DC migration, flood waits and retries automatically.\n *\n * If you want more low-level control, use\n * `primaryConnection.sendForResult()` (which is what this method wraps)\n *\n * This method is still quite low-level and you shouldn't use this\n * when using high-level API provided by `@mtcute/client`.\n *\n * @param message RPC method to call\n * @param params Additional call parameters\n */\n async call<T extends tl.RpcMethod>(\n message: MustEqual<T, tl.RpcMethod>,\n params?: RpcCallOptions,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n if (this._connected !== true) {\n await this.connect()\n }\n\n const stack = this._niceStacks ? new Error().stack : undefined\n\n const res = await this.network.call(message, params, stack)\n await this._cachePeersFrom(res)\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return res\n }\n\n /**\n * Change transport for the client.\n *\n * Can be used, for example, to change proxy at runtime\n *\n * This effectively calls `changeTransport()` on\n * `primaryConnection` and all additional connections.\n *\n * @param factory New transport factory\n */\n changeTransport(factory: TransportFactory): void {\n this.network.changeTransport(factory)\n }\n\n /**\n * Register an error handler for the client\n *\n * @param handler\n * Error handler. Called with one or two parameters.\n * The first one is always the error, and the second is\n * the connection in which the error has occurred, in case\n * this was connection-related error.\n */\n onError(handler: (err: unknown, connection?: SessionConnection) => void): void {\n this._onError = handler\n }\n\n notifyLoggedIn(auth: tl.auth.RawAuthorization): void {\n this.network.notifyLoggedIn(auth)\n this.emit('logged_in', auth)\n }\n\n _emitError(err: unknown, connection?: SessionConnection): void {\n if (this._onError) {\n this._onError(err, connection)\n } else {\n console.error(err)\n }\n }\n\n /**\n * Adds all peers from a given object to entity cache in storage.\n */\n async _cachePeersFrom(obj: object): Promise<void> {\n const parsedPeers: ITelegramStorage.PeerInfo[] = []\n\n let count = 0\n\n for (const peer of getAllPeersFrom(obj as tl.TlObject)) {\n if ((peer as any).min) {\n // no point in caching min peers as we can't use them\n continue\n }\n\n count += 1\n\n switch (peer._) {\n case 'user':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n\n parsedPeers.push({\n id: peer.id,\n accessHash: peer.accessHash,\n username: peer.username?.toLowerCase(),\n phone: peer.phone,\n type: 'user',\n full: peer,\n })\n break\n case 'chat':\n case 'chatForbidden':\n parsedPeers.push({\n id: -peer.id,\n accessHash: Long.ZERO,\n type: 'chat',\n full: peer,\n })\n break\n case 'channel':\n case 'channelForbidden':\n if (!peer.accessHash) {\n this.log.warn('received user without access hash: %j', peer)\n continue\n }\n parsedPeers.push({\n id: toggleChannelIdMark(peer.id),\n accessHash: peer.accessHash,\n username: peer._ === 'channel' ? peer.username?.toLowerCase() : undefined,\n type: 'channel',\n full: peer,\n })\n break\n }\n }\n\n if (count > 0) {\n await this.storage.updatePeers(parsedPeers)\n this.log.debug('cached %d peers', count)\n }\n }\n\n /**\n * Export current session to a single *LONG* string, containing\n * all the needed information.\n *\n * > **Warning!** Anyone with this string will be able\n * > to authorize as you and do anything. Treat this\n * > as your password, and never give it away!\n * >\n * > In case you have accidentally leaked this string,\n * > make sure to revoke this session in account settings:\n * > \"Privacy & Security\" > \"Active sessions\" >\n * > find the one containing `mtcute` > Revoke,\n * > or, in case this is a bot, revoke bot token\n * > with [@BotFather](//t.me/botfather)\n */\n async exportSession(): Promise<string> {\n const primaryDcs = await this.storage.getDefaultDcs()\n if (!primaryDcs) throw new Error('No default DC set')\n\n const authKey = await this.storage.getAuthKeyFor(primaryDcs.main.id)\n if (!authKey) throw new Error('Auth key is not ready yet')\n\n return writeStringSession(this._writerMap, {\n version: 2,\n self: await this.storage.getSelf(),\n testMode: this._testMode,\n primaryDcs,\n authKey,\n })\n }\n\n /**\n * Request the session to be imported from the given session string.\n *\n * Note that the string will not be parsed and imported right away,\n * instead, it will be imported when `connect()` is called\n *\n * Also note that the session will only be imported in case\n * the storage is missing authorization (i.e. does not contain\n * auth key for the primary DC), otherwise it will be ignored (unless `force).\n *\n * @param session Session string to import\n * @param force Whether to overwrite existing session\n */\n importSession(session: string, force = false): void {\n this._importFrom = session\n this._importForce = force\n }\n}\n"]}
|
package/cjs/network/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js';
|
|
1
|
+
export type { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js';
|
|
2
2
|
export * from './reconnection.js';
|
|
3
3
|
export * from './session-connection.js';
|
|
4
4
|
export * from './transports/index.js';
|
package/cjs/network/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,oDAAiC;AACjC,0DAAuC;AACvC,wDAAqC","sourcesContent":["export { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js'\nexport * from './reconnection.js'\nexport * from './session-connection.js'\nexport * from './transports/index.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,oDAAiC;AACjC,0DAAuC;AACvC,wDAAqC","sourcesContent":["export type { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js'\nexport * from './reconnection.js'\nexport * from './session-connection.js'\nexport * from './transports/index.js'\n"]}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.MultiSessionConnection = void 0;
|
|
7
7
|
const events_1 = __importDefault(require("events"));
|
|
8
|
+
const index_js_1 = require("../utils/index.js");
|
|
8
9
|
const mtproto_session_js_1 = require("./mtproto-session.js");
|
|
9
10
|
const session_connection_js_1 = require("./session-connection.js");
|
|
10
11
|
class MultiSessionConnection extends events_1.default {
|
|
@@ -98,8 +99,19 @@ class MultiSessionConnection extends events_1.default {
|
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
if (enforcePfsChanged) {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
// we need to fetch new auth keys first
|
|
103
|
+
const promise = (0, index_js_1.createControllablePromise)();
|
|
104
|
+
this.emit('request-keys', promise);
|
|
105
|
+
promise
|
|
106
|
+
.then(() => {
|
|
107
|
+
this._connections.forEach((conn) => {
|
|
108
|
+
conn.setUsePfs(this.params.usePfs || this._enforcePfs);
|
|
109
|
+
if (connect)
|
|
110
|
+
conn.connect();
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
.catch((err) => {
|
|
114
|
+
this.emit('error', err);
|
|
103
115
|
});
|
|
104
116
|
}
|
|
105
117
|
// create new connections
|
|
@@ -112,7 +124,7 @@ class MultiSessionConnection extends events_1.default {
|
|
|
112
124
|
isMainConnection: this.params.isMainConnection && i === 0,
|
|
113
125
|
withUpdates: this.params.isMainConnection && this.params.isMainDcConnection && !this.params.disableUpdates,
|
|
114
126
|
}, session);
|
|
115
|
-
if (this.params.isMainConnection) {
|
|
127
|
+
if (this.params.isMainConnection && this.params.isMainDcConnection) {
|
|
116
128
|
conn.on('update', (update) => this.emit('update', update));
|
|
117
129
|
}
|
|
118
130
|
conn.on('error', (err) => this.emit('error', err, conn));
|
|
@@ -143,7 +155,8 @@ class MultiSessionConnection extends events_1.default {
|
|
|
143
155
|
this._connections.forEach((it) => it.flushWhenIdle());
|
|
144
156
|
});
|
|
145
157
|
this._connections.push(conn);
|
|
146
|
-
if
|
|
158
|
+
// if enforcePfsChanged, we need to connect after setting the new auth key
|
|
159
|
+
if (connect && !enforcePfsChanged)
|
|
147
160
|
conn.connect();
|
|
148
161
|
}
|
|
149
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-session-connection.js","sourceRoot":"","sources":["../../../src/network/multi-session-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events'\n\nimport { tl } from '@mtcute/tl'\n\nimport { Logger } from '../utils/index.js'\nimport { MtprotoSession } from './mtproto-session.js'\nimport { SessionConnection, SessionConnectionParams } from './session-connection.js'\nimport { TransportFactory } from './transports/index.js'\n\nexport class MultiSessionConnection extends EventEmitter {\n private _log: Logger\n readonly _sessions: MtprotoSession[]\n private _enforcePfs = false\n\n constructor(\n readonly params: SessionConnectionParams,\n private _count: number,\n log: Logger,\n logPrefix = '',\n ) {\n super()\n this._log = log.create('multi')\n if (logPrefix) this._log.prefix = `[${logPrefix}] `\n this._enforcePfs = _count > 1 && params.isMainConnection\n\n this._sessions = []\n this._updateConnections()\n }\n\n protected _connections: SessionConnection[] = []\n\n setCount(count: number, connect = this.params.isMainConnection): void {\n this._count = count\n\n this._updateConnections(connect)\n }\n\n private _updateSessions(): void {\n // there are two cases\n // 1. this msc is main, in which case every connection should have its own session\n // 2. this msc is not main, in which case all connections should share the same session\n // if (!this.params.isMainConnection) {\n // // case 2\n // this._log.debug(\n // 'updating sessions count: %d -> 1',\n // this._sessions.length,\n // )\n //\n // if (this._sessions.length === 0) {\n // this._sessions.push(\n // new MtprotoSession(\n // this.params.crypto,\n // this._log.create('session'),\n // this.params.readerMap,\n // this.params.writerMap,\n // ),\n // )\n // }\n //\n // // shouldn't happen, but just in case\n // while (this._sessions.length > 1) {\n // this._sessions.pop()!.reset()\n // }\n //\n // return\n // }\n\n this._log.debug('updating sessions count: %d -> %d', this._sessions.length, this._count)\n\n // case 1\n if (this._sessions.length === this._count) return\n\n if (this._sessions.length > this._count) {\n // destroy extra sessions\n for (let i = this._sessions.length - 1; i >= this._count; i--) {\n this._sessions[i].reset()\n }\n\n this._sessions.splice(this._count)\n\n return\n }\n\n while (this._sessions.length < this._count) {\n const idx = this._sessions.length\n const session = new MtprotoSession(\n this.params.crypto,\n this._log.create('session'),\n this.params.readerMap,\n this.params.writerMap,\n )\n\n // brvh\n if (idx !== 0) session._authKey = this._sessions[0]._authKey\n\n this._sessions.push(session)\n }\n }\n\n private _updateConnections(connect = false): void {\n this._updateSessions()\n if (this._connections.length === this._count) return\n\n this._log.debug('updating connections count: %d -> %d', this._connections.length, this._count)\n\n const newEnforcePfs = this._count > 1 && this.params.isMainConnection\n const enforcePfsChanged = newEnforcePfs !== this._enforcePfs\n\n if (enforcePfsChanged) {\n this._log.debug('enforcePfs changed: %s -> %s', this._enforcePfs, newEnforcePfs)\n this._enforcePfs = newEnforcePfs\n }\n\n if (this._connections.length > this._count) {\n // destroy extra connections\n for (let i = this._connections.length - 1; i >= this._count; i--) {\n this._connections[i].removeAllListeners()\n this._connections[i].destroy()\n }\n\n this._connections.splice(this._count)\n\n return\n }\n\n if (enforcePfsChanged) {\n this._connections.forEach((conn) => {\n conn.setUsePfs(this.params.usePfs || this._enforcePfs)\n })\n }\n\n // create new connections\n for (let i = this._connections.length; i < this._count; i++) {\n const session = this._sessions[i] // this.params.isMainConnection ? // :\n // this._sessions[0]\n const conn = new SessionConnection(\n {\n ...this.params,\n usePfs: this.params.usePfs || this._enforcePfs,\n isMainConnection: this.params.isMainConnection && i === 0,\n withUpdates:\n this.params.isMainConnection && this.params.isMainDcConnection && !this.params.disableUpdates,\n },\n session,\n )\n\n if (this.params.isMainConnection) {\n conn.on('update', (update) => this.emit('update', update))\n }\n conn.on('error', (err) => this.emit('error', err, conn))\n conn.on('key-change', (key) => {\n this.emit('key-change', i, key)\n\n // notify other connections\n for (const conn_ of this._connections) {\n if (conn_ === conn) continue\n conn_.onConnected()\n }\n })\n conn.on('tmp-key-change', (key, expires) => this.emit('tmp-key-change', i, key, expires))\n conn.on('auth-begin', () => {\n this._log.debug('received auth-begin from connection %d', i)\n this.emit('auth-begin', i)\n\n // we need to reset temp auth keys if there are any left\n\n this._connections.forEach((conn_) => {\n conn_._session._authKeyTemp.reset()\n if (conn_ !== conn) conn_.reconnect()\n })\n })\n conn.on('usable', () => this.emit('usable', i))\n conn.on('request-auth', () => this.emit('request-auth', i))\n conn.on('flood-done', () => {\n this._log.debug('received flood-done from connection %d', i)\n\n this._connections.forEach((it) => it.flushWhenIdle())\n })\n\n this._connections.push(conn)\n if (connect) conn.connect()\n }\n }\n\n _destroyed = false\n destroy(): void {\n this._connections.forEach((conn) => conn.destroy())\n this._sessions.forEach((sess) => sess.reset())\n this.removeAllListeners()\n\n this._destroyed = true\n }\n\n private _nextConnection = 0\n\n sendRpc<T extends tl.RpcMethod>(\n request: T,\n stack?: string,\n timeout?: number,\n abortSignal?: AbortSignal,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n // if (this.params.isMainConnection) {\n // find the least loaded connection\n let min = Infinity\n let minIdx = 0\n\n for (let i = 0; i < this._connections.length; i++) {\n const conn = this._connections[i]\n const total = conn._session.queuedRpc.length + conn._session.pendingMessages.size()\n\n if (total < min) {\n min = total\n minIdx = i\n }\n }\n\n return this._connections[minIdx].sendRpc(request, stack, timeout, abortSignal)\n // }\n\n // round-robin connections\n // since they all share the same session, it doesn't matter which one we use\n // the connection chosen here will only affect the first attempt at sending\n // return this._connections[\n // this._nextConnection++ % this._connections.length\n // ].sendRpc(request, stack, timeout)\n }\n\n connect(): void {\n for (const conn of this._connections) {\n conn.connect()\n }\n }\n\n ensureConnected(): void {\n if (this._connections[0].isConnected) return\n\n this.connect()\n }\n\n setAuthKey(authKey: Uint8Array | null, temp = false, idx = 0): void {\n const session = this._sessions[idx]\n const key = temp ? session._authKeyTemp : session._authKey\n key.setup(authKey)\n }\n\n resetAuthKeys(): void {\n for (const session of this._sessions) {\n session.reset(true)\n }\n this.notifyKeyChange()\n }\n\n setInactivityTimeout(timeout?: number): void {\n this._log.debug('setting inactivity timeout to %s', timeout)\n\n // for future connections (if any)\n this.params.inactivityTimeout = timeout\n\n // for current connections\n for (const conn of this._connections) {\n conn.setInactivityTimeout(timeout)\n }\n }\n\n notifyKeyChange(): void {\n // only expected to be called on non-main connections\n const session = this._sessions[0]\n\n if (this.params.usePfs && !session._authKeyTemp.ready) {\n this._log.debug('temp auth key needed but not ready, ignoring key change')\n\n return\n }\n\n if (this._sessions[0].queuedRpc.length) {\n // there are pending requests, we need to reconnect.\n this._log.debug('notifying key change on the connection due to queued rpc')\n this._connections[0].onConnected()\n }\n\n // connection is idle, we don't need to notify it\n }\n\n requestAuth(): void {\n this._connections[0]._authorize()\n }\n\n resetSessions(): void {\n if (this.params.isMainConnection) {\n for (const conn of this._connections) {\n conn._resetSession()\n }\n } else {\n this._connections[0]._resetSession()\n }\n }\n\n changeTransport(factory: TransportFactory): void {\n this._connections.forEach((conn) => conn.changeTransport(factory))\n }\n\n getPoolSize(): number {\n return this._connections.length\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"multi-session-connection.js","sourceRoot":"","sources":["../../../src/network/multi-session-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from 'events'\n\nimport { tl } from '@mtcute/tl'\n\nimport { createControllablePromise, Logger } from '../utils/index.js'\nimport { MtprotoSession } from './mtproto-session.js'\nimport { SessionConnection, SessionConnectionParams } from './session-connection.js'\nimport { TransportFactory } from './transports/index.js'\n\nexport class MultiSessionConnection extends EventEmitter {\n private _log: Logger\n readonly _sessions: MtprotoSession[]\n private _enforcePfs = false\n\n constructor(\n readonly params: SessionConnectionParams,\n private _count: number,\n log: Logger,\n logPrefix = '',\n ) {\n super()\n this._log = log.create('multi')\n if (logPrefix) this._log.prefix = `[${logPrefix}] `\n this._enforcePfs = _count > 1 && params.isMainConnection\n\n this._sessions = []\n this._updateConnections()\n }\n\n protected _connections: SessionConnection[] = []\n\n setCount(count: number, connect = this.params.isMainConnection): void {\n this._count = count\n\n this._updateConnections(connect)\n }\n\n private _updateSessions(): void {\n // there are two cases\n // 1. this msc is main, in which case every connection should have its own session\n // 2. this msc is not main, in which case all connections should share the same session\n // if (!this.params.isMainConnection) {\n // // case 2\n // this._log.debug(\n // 'updating sessions count: %d -> 1',\n // this._sessions.length,\n // )\n //\n // if (this._sessions.length === 0) {\n // this._sessions.push(\n // new MtprotoSession(\n // this.params.crypto,\n // this._log.create('session'),\n // this.params.readerMap,\n // this.params.writerMap,\n // ),\n // )\n // }\n //\n // // shouldn't happen, but just in case\n // while (this._sessions.length > 1) {\n // this._sessions.pop()!.reset()\n // }\n //\n // return\n // }\n\n this._log.debug('updating sessions count: %d -> %d', this._sessions.length, this._count)\n\n // case 1\n if (this._sessions.length === this._count) return\n\n if (this._sessions.length > this._count) {\n // destroy extra sessions\n for (let i = this._sessions.length - 1; i >= this._count; i--) {\n this._sessions[i].reset()\n }\n\n this._sessions.splice(this._count)\n\n return\n }\n\n while (this._sessions.length < this._count) {\n const idx = this._sessions.length\n const session = new MtprotoSession(\n this.params.crypto,\n this._log.create('session'),\n this.params.readerMap,\n this.params.writerMap,\n )\n\n // brvh\n if (idx !== 0) session._authKey = this._sessions[0]._authKey\n\n this._sessions.push(session)\n }\n }\n\n private _updateConnections(connect = false): void {\n this._updateSessions()\n if (this._connections.length === this._count) return\n\n this._log.debug('updating connections count: %d -> %d', this._connections.length, this._count)\n\n const newEnforcePfs = this._count > 1 && this.params.isMainConnection\n const enforcePfsChanged = newEnforcePfs !== this._enforcePfs\n\n if (enforcePfsChanged) {\n this._log.debug('enforcePfs changed: %s -> %s', this._enforcePfs, newEnforcePfs)\n this._enforcePfs = newEnforcePfs\n }\n\n if (this._connections.length > this._count) {\n // destroy extra connections\n for (let i = this._connections.length - 1; i >= this._count; i--) {\n this._connections[i].removeAllListeners()\n this._connections[i].destroy()\n }\n\n this._connections.splice(this._count)\n\n return\n }\n\n if (enforcePfsChanged) {\n // we need to fetch new auth keys first\n const promise = createControllablePromise<void>()\n this.emit('request-keys', promise)\n\n promise\n .then(() => {\n this._connections.forEach((conn) => {\n conn.setUsePfs(this.params.usePfs || this._enforcePfs)\n\n if (connect) conn.connect()\n })\n })\n .catch((err) => {\n this.emit('error', err)\n })\n }\n\n // create new connections\n for (let i = this._connections.length; i < this._count; i++) {\n const session = this._sessions[i] // this.params.isMainConnection ? // :\n // this._sessions[0]\n const conn = new SessionConnection(\n {\n ...this.params,\n usePfs: this.params.usePfs || this._enforcePfs,\n isMainConnection: this.params.isMainConnection && i === 0,\n withUpdates:\n this.params.isMainConnection && this.params.isMainDcConnection && !this.params.disableUpdates,\n },\n session,\n )\n\n if (this.params.isMainConnection && this.params.isMainDcConnection) {\n conn.on('update', (update) => this.emit('update', update))\n }\n conn.on('error', (err) => this.emit('error', err, conn))\n conn.on('key-change', (key) => {\n this.emit('key-change', i, key)\n\n // notify other connections\n for (const conn_ of this._connections) {\n if (conn_ === conn) continue\n conn_.onConnected()\n }\n })\n conn.on('tmp-key-change', (key, expires) => this.emit('tmp-key-change', i, key, expires))\n conn.on('auth-begin', () => {\n this._log.debug('received auth-begin from connection %d', i)\n this.emit('auth-begin', i)\n\n // we need to reset temp auth keys if there are any left\n\n this._connections.forEach((conn_) => {\n conn_._session._authKeyTemp.reset()\n if (conn_ !== conn) conn_.reconnect()\n })\n })\n conn.on('usable', () => this.emit('usable', i))\n conn.on('request-auth', () => this.emit('request-auth', i))\n conn.on('flood-done', () => {\n this._log.debug('received flood-done from connection %d', i)\n\n this._connections.forEach((it) => it.flushWhenIdle())\n })\n\n this._connections.push(conn)\n // if enforcePfsChanged, we need to connect after setting the new auth key\n if (connect && !enforcePfsChanged) conn.connect()\n }\n }\n\n _destroyed = false\n destroy(): void {\n this._connections.forEach((conn) => conn.destroy())\n this._sessions.forEach((sess) => sess.reset())\n this.removeAllListeners()\n\n this._destroyed = true\n }\n\n private _nextConnection = 0\n\n sendRpc<T extends tl.RpcMethod>(\n request: T,\n stack?: string,\n timeout?: number,\n abortSignal?: AbortSignal,\n ): Promise<tl.RpcCallReturn[T['_']]> {\n // if (this.params.isMainConnection) {\n // find the least loaded connection\n let min = Infinity\n let minIdx = 0\n\n for (let i = 0; i < this._connections.length; i++) {\n const conn = this._connections[i]\n const total = conn._session.queuedRpc.length + conn._session.pendingMessages.size()\n\n if (total < min) {\n min = total\n minIdx = i\n }\n }\n\n return this._connections[minIdx].sendRpc(request, stack, timeout, abortSignal)\n // }\n\n // round-robin connections\n // since they all share the same session, it doesn't matter which one we use\n // the connection chosen here will only affect the first attempt at sending\n // return this._connections[\n // this._nextConnection++ % this._connections.length\n // ].sendRpc(request, stack, timeout)\n }\n\n connect(): void {\n for (const conn of this._connections) {\n conn.connect()\n }\n }\n\n ensureConnected(): void {\n if (this._connections[0].isConnected) return\n\n this.connect()\n }\n\n setAuthKey(authKey: Uint8Array | null, temp = false, idx = 0): void {\n const session = this._sessions[idx]\n const key = temp ? session._authKeyTemp : session._authKey\n key.setup(authKey)\n }\n\n resetAuthKeys(): void {\n for (const session of this._sessions) {\n session.reset(true)\n }\n this.notifyKeyChange()\n }\n\n setInactivityTimeout(timeout?: number): void {\n this._log.debug('setting inactivity timeout to %s', timeout)\n\n // for future connections (if any)\n this.params.inactivityTimeout = timeout\n\n // for current connections\n for (const conn of this._connections) {\n conn.setInactivityTimeout(timeout)\n }\n }\n\n notifyKeyChange(): void {\n // only expected to be called on non-main connections\n const session = this._sessions[0]\n\n if (this.params.usePfs && !session._authKeyTemp.ready) {\n this._log.debug('temp auth key needed but not ready, ignoring key change')\n\n return\n }\n\n if (this._sessions[0].queuedRpc.length) {\n // there are pending requests, we need to reconnect.\n this._log.debug('notifying key change on the connection due to queued rpc')\n this._connections[0].onConnected()\n }\n\n // connection is idle, we don't need to notify it\n }\n\n requestAuth(): void {\n this._connections[0]._authorize()\n }\n\n resetSessions(): void {\n if (this.params.isMainConnection) {\n for (const conn of this._connections) {\n conn._resetSession()\n }\n } else {\n this._connections[0]._resetSession()\n }\n }\n\n changeTransport(factory: TransportFactory): void {\n this._connections.forEach((conn) => conn.changeTransport(factory))\n }\n\n getPoolSize(): number {\n return this._connections.length\n }\n}\n"]}
|
|
@@ -143,7 +143,7 @@ export declare class DcConnectionManager {
|
|
|
143
143
|
private _setupMulti;
|
|
144
144
|
setIsPrimary(isPrimary: boolean): void;
|
|
145
145
|
setIsPremium(isPremium: boolean): void;
|
|
146
|
-
loadKeys(): Promise<boolean>;
|
|
146
|
+
loadKeys(forcePfs?: boolean): Promise<boolean>;
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Class that manages all connections to Telegram servers.
|
|
@@ -144,6 +144,12 @@ class DcConnectionManager {
|
|
|
144
144
|
connection.on('request-auth', () => {
|
|
145
145
|
this.main.requestAuth();
|
|
146
146
|
});
|
|
147
|
+
// fucking awesome architecture, but whatever
|
|
148
|
+
connection.on('request-keys', (promise) => {
|
|
149
|
+
this.loadKeys(true)
|
|
150
|
+
.then(() => promise.resolve())
|
|
151
|
+
.catch((e) => promise.reject(e));
|
|
152
|
+
});
|
|
147
153
|
connection.on('error', (err, conn) => {
|
|
148
154
|
this.manager.params._emitError(err, conn);
|
|
149
155
|
});
|
|
@@ -152,6 +158,7 @@ class DcConnectionManager {
|
|
|
152
158
|
if (this.isPrimary === isPrimary)
|
|
153
159
|
return;
|
|
154
160
|
this.isPrimary = isPrimary;
|
|
161
|
+
this.main.params.isMainDcConnection = isPrimary;
|
|
155
162
|
if (isPrimary) {
|
|
156
163
|
this.main.setInactivityTimeout(undefined);
|
|
157
164
|
}
|
|
@@ -164,7 +171,7 @@ class DcConnectionManager {
|
|
|
164
171
|
this.download.setCount(this.manager._connectionCount('download', this.dcId, isPremium));
|
|
165
172
|
this.downloadSmall.setCount(this.manager._connectionCount('downloadSmall', this.dcId, isPremium));
|
|
166
173
|
}
|
|
167
|
-
async loadKeys() {
|
|
174
|
+
async loadKeys(forcePfs = false) {
|
|
168
175
|
const permanent = await this.manager._storage.getAuthKeyFor(this.dcId);
|
|
169
176
|
this.main.setAuthKey(permanent);
|
|
170
177
|
this.upload.setAuthKey(permanent);
|
|
@@ -173,7 +180,7 @@ class DcConnectionManager {
|
|
|
173
180
|
if (!permanent) {
|
|
174
181
|
return false;
|
|
175
182
|
}
|
|
176
|
-
if (this.manager.params.usePfs) {
|
|
183
|
+
if (this.manager.params.usePfs || forcePfs) {
|
|
177
184
|
await Promise.all(this.main._sessions.map(async (_, i) => {
|
|
178
185
|
const temp = await this.manager._storage.getAuthKeyFor(this.dcId, i);
|
|
179
186
|
this.main.setAuthKey(temp, true, i);
|
|
@@ -219,7 +226,7 @@ class NetworkManager {
|
|
|
219
226
|
_: 'initConnection',
|
|
220
227
|
deviceModel,
|
|
221
228
|
systemVersion: '1.0',
|
|
222
|
-
appVersion: '0.
|
|
229
|
+
appVersion: '0.2.0',
|
|
223
230
|
systemLangCode: 'en',
|
|
224
231
|
langPack: '',
|
|
225
232
|
langCode: 'en',
|
|
@@ -327,7 +334,7 @@ class NetworkManager {
|
|
|
327
334
|
// shouldn't happen
|
|
328
335
|
throw new index_js_1.MtArgumentError('DC manager already exists');
|
|
329
336
|
}
|
|
330
|
-
const dc = new DcConnectionManager(this, defaultDcs.main.id, defaultDcs);
|
|
337
|
+
const dc = new DcConnectionManager(this, defaultDcs.main.id, defaultDcs, true);
|
|
331
338
|
this._dcConnections.set(defaultDcs.main.id, dc);
|
|
332
339
|
await this._switchPrimaryDc(dc);
|
|
333
340
|
}
|
|
@@ -394,7 +401,7 @@ class NetworkManager {
|
|
|
394
401
|
return;
|
|
395
402
|
const options = await this._findDcOptions(newDc);
|
|
396
403
|
if (!this._dcConnections.has(newDc)) {
|
|
397
|
-
this._dcConnections.set(newDc, new DcConnectionManager(this, newDc, options));
|
|
404
|
+
this._dcConnections.set(newDc, new DcConnectionManager(this, newDc, options, true));
|
|
398
405
|
}
|
|
399
406
|
await this._storage.setDefaultDcs(options);
|
|
400
407
|
await this._switchPrimaryDc(this._dcConnections.get(newDc));
|