chore(core): various improvements
This commit is contained in:
parent
886858d9de
commit
7a0d8ecef2
3 changed files with 189 additions and 187 deletions
|
@ -7,16 +7,15 @@ import { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js'
|
|||
import { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js'
|
||||
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { BaseTelegramClientOptions } from './base-client.types.js'
|
||||
import { ConfigManager } from './network/config-manager.js'
|
||||
import { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js'
|
||||
import { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js'
|
||||
import { PersistentConnectionParams } from './network/persistent-connection.js'
|
||||
import { SessionConnection, TransportFactory } from './network/index.js'
|
||||
import { NetworkManager, RpcCallOptions } from './network/network-manager.js'
|
||||
import { ITelegramStorage } from './storage/index.js'
|
||||
import { MustEqual } from './types/index.js'
|
||||
import {
|
||||
ControllablePromise,
|
||||
createControllablePromise,
|
||||
CryptoProviderFactory,
|
||||
defaultCryptoProviderFactory,
|
||||
defaultProductionDc,
|
||||
defaultProductionIpv6Dc,
|
||||
|
@ -26,176 +25,11 @@ import {
|
|||
ICryptoProvider,
|
||||
LogManager,
|
||||
readStringSession,
|
||||
StringSessionData,
|
||||
toggleChannelIdMark,
|
||||
writeStringSession,
|
||||
} from './utils/index.js'
|
||||
|
||||
/** Options for {@link BaseTelegramClient} */
|
||||
export interface BaseTelegramClientOptions {
|
||||
/**
|
||||
* API ID from my.telegram.org
|
||||
*/
|
||||
apiId: number | string
|
||||
/**
|
||||
* API hash from my.telegram.org
|
||||
*/
|
||||
apiHash: string
|
||||
|
||||
/**
|
||||
* Storage to use for this client.
|
||||
*/
|
||||
storage: ITelegramStorage
|
||||
|
||||
/**
|
||||
* Cryptography provider factory to allow delegating
|
||||
* crypto to native addon, worker, etc.
|
||||
*/
|
||||
crypto?: CryptoProviderFactory
|
||||
|
||||
/**
|
||||
* Whether to use IPv6 datacenters
|
||||
* (IPv6 will be preferred when choosing a DC by id)
|
||||
* (default: false)
|
||||
*/
|
||||
useIpv6?: boolean
|
||||
|
||||
/**
|
||||
* Primary DC to use for initial connection.
|
||||
* This does not mean this will be the only DC used,
|
||||
* nor that this DC will actually be primary, this only
|
||||
* determines the first DC the library will try to connect to.
|
||||
* Can be used to connect to other networks (like test DCs).
|
||||
*
|
||||
* When session already contains primary DC, this parameter is ignored.
|
||||
*
|
||||
* @default Production DC 2.
|
||||
*/
|
||||
defaultDcs?: ITelegramStorage.DcOptions
|
||||
|
||||
/**
|
||||
* Whether to connect to test servers.
|
||||
*
|
||||
* If passed, {@link defaultDc} defaults to Test DC 2.
|
||||
*
|
||||
* **Must** be passed if using test servers, even if
|
||||
* you passed custom {@link defaultDc}
|
||||
*/
|
||||
testMode?: boolean
|
||||
|
||||
/**
|
||||
* Additional options for initConnection call.
|
||||
* `apiId` and `query` are not available and will be ignored.
|
||||
* Omitted values will be filled with defaults
|
||||
*/
|
||||
initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>
|
||||
|
||||
/**
|
||||
* Transport factory to use in the client.
|
||||
*
|
||||
* @default platform-specific transport: WebSocket on the web, TCP in node
|
||||
*/
|
||||
transport?: TransportFactory
|
||||
|
||||
/**
|
||||
* Reconnection strategy.
|
||||
*
|
||||
* @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)
|
||||
*/
|
||||
reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>
|
||||
|
||||
/**
|
||||
* Maximum duration of a flood_wait that will be waited automatically.
|
||||
* Flood waits above this threshold will throw a FloodWaitError.
|
||||
* Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params
|
||||
*
|
||||
* @default 10000
|
||||
*/
|
||||
floodSleepThreshold?: number
|
||||
|
||||
/**
|
||||
* Maximum number of retries when calling RPC methods.
|
||||
* Call is retried when InternalError or FloodWaitError is encountered.
|
||||
* Can be set to Infinity.
|
||||
*
|
||||
* @default 5
|
||||
*/
|
||||
maxRetryCount?: number
|
||||
|
||||
/**
|
||||
* If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,
|
||||
* effectively disabling the server-sent events for the clients.
|
||||
* May be useful in some cases.
|
||||
*
|
||||
* Note that this only wraps calls made with `.call()` within the primary
|
||||
* connection. Additional connections and direct `.sendForResult()` calls
|
||||
* must be wrapped manually.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
disableUpdates?: boolean
|
||||
|
||||
/**
|
||||
* mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s
|
||||
* [error reporting service](https://rpc.pwrtelegram.xyz/).
|
||||
*
|
||||
* This is fully anonymous (except maybe IP) and is only used to improve the library
|
||||
* and developer experience for everyone working with MTProto. This is fully opt-in,
|
||||
* and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enableErrorReporting?: boolean
|
||||
|
||||
/**
|
||||
* If true, RPC errors will have a stack trace of the initial `.call()`
|
||||
* or `.sendForResult()` call position, which drastically improves
|
||||
* debugging experience.<br>
|
||||
* If false, they will have a stack trace of mtcute internals.
|
||||
*
|
||||
* Internally this creates a stack capture before every RPC call
|
||||
* and stores it until the result is received. This might
|
||||
* use a lot more memory than normal, thus can be disabled here.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
niceStacks?: boolean
|
||||
|
||||
/**
|
||||
* Extra parameters for {@link NetworkManager}
|
||||
*/
|
||||
network?: NetworkManagerExtraParams
|
||||
|
||||
/**
|
||||
* Set logging level for the client.
|
||||
*
|
||||
* See static members of {@link LogManager} for possible values.
|
||||
*/
|
||||
logLevel?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY!**
|
||||
*
|
||||
* Override TL layer used for the connection.
|
||||
*
|
||||
* **Does not** change the schema used.
|
||||
*/
|
||||
overrideLayer?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override reader map used for the connection.
|
||||
*/
|
||||
readerMap?: TlReaderMap
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override writer map used for the connection.
|
||||
*/
|
||||
writerMap?: TlWriterMap
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic Telegram client that only implements the bare minimum
|
||||
* to make RPC calls and receive low-level updates.
|
||||
|
@ -248,9 +82,9 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
// not really connected, but rather "connect() was called"
|
||||
private _connected: ControllablePromise<void> | boolean = false
|
||||
|
||||
private _onError?: (err: unknown, connection?: SessionConnection) => void
|
||||
_emitError: (err: unknown, connection?: SessionConnection) => void = console.error.bind(console)
|
||||
|
||||
private _importFrom?: string
|
||||
private _importFrom?: StringSessionData
|
||||
private _importForce?: boolean
|
||||
|
||||
readonly log = new LogManager('client')
|
||||
|
@ -372,7 +206,7 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
const defaultDcAuthKey = await this.storage.getAuthKeyFor(this._defaultDcs.main.id)
|
||||
|
||||
if ((this._importForce || !defaultDcAuthKey) && this._importFrom) {
|
||||
const data = readStringSession(this._readerMap, this._importFrom)
|
||||
const data = this._importFrom
|
||||
|
||||
if (data.testMode !== this._testMode) {
|
||||
throw new Error(
|
||||
|
@ -517,7 +351,7 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
* this was connection-related error.
|
||||
*/
|
||||
onError(handler: (err: unknown, connection?: SessionConnection) => void): void {
|
||||
this._onError = handler
|
||||
this._emitError = handler
|
||||
}
|
||||
|
||||
notifyLoggedIn(auth: tl.auth.RawAuthorization): void {
|
||||
|
@ -525,15 +359,9 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
this.emit('logged_in', auth)
|
||||
}
|
||||
|
||||
_emitError(err: unknown, connection?: SessionConnection): void {
|
||||
if (this._onError) {
|
||||
this._onError(err, connection)
|
||||
} else {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* **ADVANCED**
|
||||
*
|
||||
* Adds all peers from a given object to entity cache in storage.
|
||||
*/
|
||||
async _cachePeersFrom(obj: object): Promise<boolean> {
|
||||
|
@ -634,18 +462,18 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
/**
|
||||
* Request the session to be imported from the given session string.
|
||||
*
|
||||
* Note that the string will not be parsed and imported right away,
|
||||
* instead, it will be imported when `connect()` is called
|
||||
* Note that the session will not be imported right away,
|
||||
* instead, it will be imported once `connect()` is called
|
||||
*
|
||||
* Also note that the session will only be imported in case
|
||||
* the storage is missing authorization (i.e. does not contain
|
||||
* auth key for the primary DC), otherwise it will be ignored (unless `force).
|
||||
* auth key for the primary DC), otherwise it will be ignored (unless `force`).
|
||||
*
|
||||
* @param session Session string to import
|
||||
* @param force Whether to overwrite existing session
|
||||
*/
|
||||
importSession(session: string, force = false): void {
|
||||
this._importFrom = session
|
||||
importSession(session: string | StringSessionData, force = false): void {
|
||||
this._importFrom = typeof session === 'string' ? readStringSession(this._readerMap, session) : session
|
||||
this._importForce = force
|
||||
}
|
||||
}
|
||||
|
|
173
packages/core/src/base-client.types.ts
Normal file
173
packages/core/src/base-client.types.ts
Normal file
|
@ -0,0 +1,173 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'
|
||||
|
||||
import { NetworkManagerExtraParams, ReconnectionStrategy, TransportFactory } from './network/index.js'
|
||||
import { PersistentConnectionParams } from './network/persistent-connection.js'
|
||||
import { ITelegramStorage } from './storage/abstract.js'
|
||||
import { CryptoProviderFactory } from './utils/index.js'
|
||||
|
||||
/** Options for {@link BaseTelegramClient} */
|
||||
export interface BaseTelegramClientOptions {
|
||||
/**
|
||||
* API ID from my.telegram.org
|
||||
*/
|
||||
apiId: number | string
|
||||
/**
|
||||
* API hash from my.telegram.org
|
||||
*/
|
||||
apiHash: string
|
||||
|
||||
/**
|
||||
* Storage to use for this client.
|
||||
*/
|
||||
storage: ITelegramStorage
|
||||
|
||||
/**
|
||||
* Cryptography provider factory to allow delegating
|
||||
* crypto to native addon, worker, etc.
|
||||
*/
|
||||
crypto?: CryptoProviderFactory
|
||||
|
||||
/**
|
||||
* Whether to use IPv6 datacenters
|
||||
* (IPv6 will be preferred when choosing a DC by id)
|
||||
* (default: false)
|
||||
*/
|
||||
useIpv6?: boolean
|
||||
|
||||
/**
|
||||
* Primary DC to use for initial connection.
|
||||
* This does not mean this will be the only DC used,
|
||||
* nor that this DC will actually be primary, this only
|
||||
* determines the first DC the library will try to connect to.
|
||||
* Can be used to connect to other networks (like test DCs).
|
||||
*
|
||||
* When session already contains primary DC, this parameter is ignored.
|
||||
*
|
||||
* @default Production DC 2.
|
||||
*/
|
||||
defaultDcs?: ITelegramStorage.DcOptions
|
||||
|
||||
/**
|
||||
* Whether to connect to test servers.
|
||||
*
|
||||
* If passed, {@link defaultDc} defaults to Test DC 2.
|
||||
*
|
||||
* **Must** be passed if using test servers, even if
|
||||
* you passed custom {@link defaultDc}
|
||||
*/
|
||||
testMode?: boolean
|
||||
|
||||
/**
|
||||
* Additional options for initConnection call.
|
||||
* `apiId` and `query` are not available and will be ignored.
|
||||
* Omitted values will be filled with defaults
|
||||
*/
|
||||
initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>
|
||||
|
||||
/**
|
||||
* Transport factory to use in the client.
|
||||
*
|
||||
* @default platform-specific transport: WebSocket on the web, TCP in node
|
||||
*/
|
||||
transport?: TransportFactory
|
||||
|
||||
/**
|
||||
* Reconnection strategy.
|
||||
*
|
||||
* @default simple reconnection strategy: first 0ms, then up to 5s (increasing by 1s)
|
||||
*/
|
||||
reconnectionStrategy?: ReconnectionStrategy<PersistentConnectionParams>
|
||||
|
||||
/**
|
||||
* Maximum duration of a flood_wait that will be waited automatically.
|
||||
* Flood waits above this threshold will throw a FloodWaitError.
|
||||
* Set to 0 to disable. Can be overridden with `throwFlood` parameter in call() params
|
||||
*
|
||||
* @default 10000
|
||||
*/
|
||||
floodSleepThreshold?: number
|
||||
|
||||
/**
|
||||
* Maximum number of retries when calling RPC methods.
|
||||
* Call is retried when InternalError or FloodWaitError is encountered.
|
||||
* Can be set to Infinity.
|
||||
*
|
||||
* @default 5
|
||||
*/
|
||||
maxRetryCount?: number
|
||||
|
||||
/**
|
||||
* If true, every single API call will be wrapped with `tl.invokeWithoutUpdates`,
|
||||
* effectively disabling the server-sent events for the clients.
|
||||
* May be useful in some cases.
|
||||
*
|
||||
* Note that this only wraps calls made with `.call()` within the primary
|
||||
* connection. Additional connections and direct `.sendForResult()` calls
|
||||
* must be wrapped manually.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
disableUpdates?: boolean
|
||||
|
||||
/**
|
||||
* mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s
|
||||
* [error reporting service](https://rpc.pwrtelegram.xyz/).
|
||||
*
|
||||
* This is fully anonymous (except maybe IP) and is only used to improve the library
|
||||
* and developer experience for everyone working with MTProto. This is fully opt-in,
|
||||
* and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enableErrorReporting?: boolean
|
||||
|
||||
/**
|
||||
* If true, RPC errors will have a stack trace of the initial `.call()`
|
||||
* or `.sendForResult()` call position, which drastically improves
|
||||
* debugging experience.<br>
|
||||
* If false, they will have a stack trace of mtcute internals.
|
||||
*
|
||||
* Internally this creates a stack capture before every RPC call
|
||||
* and stores it until the result is received. This might
|
||||
* use a lot more memory than normal, thus can be disabled here.
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
niceStacks?: boolean
|
||||
|
||||
/**
|
||||
* Extra parameters for {@link NetworkManager}
|
||||
*/
|
||||
network?: NetworkManagerExtraParams
|
||||
|
||||
/**
|
||||
* Set logging level for the client.
|
||||
*
|
||||
* See static members of {@link LogManager} for possible values.
|
||||
*/
|
||||
logLevel?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY!**
|
||||
*
|
||||
* Override TL layer used for the connection.
|
||||
*
|
||||
* **Does not** change the schema used.
|
||||
*/
|
||||
overrideLayer?: number
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override reader map used for the connection.
|
||||
*/
|
||||
readerMap?: TlReaderMap
|
||||
|
||||
/**
|
||||
* **EXPERT USE ONLY**
|
||||
*
|
||||
* Override writer map used for the connection.
|
||||
*/
|
||||
writerMap?: TlWriterMap
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
export * from './base-client.js'
|
||||
export * from './base-client.types.js'
|
||||
export * from './network/index.js'
|
||||
export * from './storage/index.js'
|
||||
export * from './types/index.js'
|
||||
|
|
Loading…
Reference in a new issue