chore: use target=es2022 with useDefineForClassFields=true

This commit is contained in:
alina 🌸 2024-04-02 04:37:33 +03:00
parent 9491b2b1e6
commit c5d115f088
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
18 changed files with 206 additions and 144 deletions

View file

@ -33,7 +33,18 @@ export class BaseTelegramClient implements ITelegramClient {
private _serverUpdatesHandler: (updates: tl.TypeUpdates) => void = () => {}
private _connectionStateHandler: (state: ConnectionState) => void = () => {}
readonly log
readonly mt
readonly crypto
readonly storage
constructor(readonly params: BaseTelegramClientOptions) {
this.log = this.params.logger ?? new LogManager('client')
this.mt = new MtClient({
...this.params,
logger: this.log.create('mtproto'),
})
if (!params.disableUpdates && params.updates !== false) {
this.updates = new UpdatesManager(this, params.updates)
this._serverUpdatesHandler = this.updates.handleUpdate.bind(this.updates)
@ -56,18 +67,13 @@ export class BaseTelegramClient implements ITelegramClient {
this._connectionStateHandler('offline')
}
})
}
readonly log = this.params.logger ?? new LogManager('client')
readonly mt = new MtClient({
...this.params,
logger: this.log.create('mtproto'),
})
readonly crypto = this.mt.crypto
readonly storage = new TelegramStorageManager(this.mt.storage, {
this.crypto = this.mt.crypto
this.storage = new TelegramStorageManager(this.mt.storage, {
provider: this.params.storage,
...this.params.storageOptions,
})
}
readonly appConfig = new AppConfigManager(this)
private _prepare = asyncResettable(async () => {

View file

@ -1,3 +1,4 @@
import { ServiceOptions } from '../../storage/service/base.js'
import { StorageManager } from '../../storage/storage.js'
import { PublicPart } from '../../types/utils.js'
import { ITelegramStorageProvider } from './provider.js'
@ -17,26 +18,40 @@ export interface TelegramStorageManagerExtraOptions {
}
export class TelegramStorageManager {
private provider
readonly updates
readonly self: PublicPart<CurrentUserService>
readonly refMsgs
readonly peers: PublicPart<PeersService>
constructor(
private mt: StorageManager,
private options: TelegramStorageManagerOptions & TelegramStorageManagerExtraOptions,
) {}
) {
this.provider = this.options.provider
private provider = this.options.provider
const serviceOptions: ServiceOptions = {
driver: this.mt.driver,
readerMap: this.mt.options.readerMap,
writerMap: this.mt.options.writerMap,
log: this.mt.log,
}
readonly updates = new UpdatesStateService(this.provider.kv, this.mt._serviceOptions)
readonly self: PublicPart<CurrentUserService> = new CurrentUserService(this.provider.kv, this.mt._serviceOptions)
readonly refMsgs = new RefMessagesService(
this.updates = new UpdatesStateService(this.provider.kv, serviceOptions)
this.self = new CurrentUserService(this.provider.kv, serviceOptions)
this.refMsgs = new RefMessagesService(
this.options.refMessages ?? {},
this.provider.refMessages,
this.mt._serviceOptions,
serviceOptions,
)
readonly peers: PublicPart<PeersService> = new PeersService(
this.peers = new PeersService(
this.options.peers ?? {},
this.provider.peers,
this.refMsgs,
this.mt._serviceOptions,
serviceOptions,
)
}
async clear(withAuthKeys = false) {
await this.provider.peers.deleteAll()

View file

@ -100,7 +100,7 @@ export class UpdatesManager {
pendingQtsUpdatesPostponed = new SortedLinkedList<PendingUpdate>((a, b) => a.qtsBefore! - b.qtsBefore!)
pendingUnorderedUpdates = new Deque<PendingUpdate>()
noDispatchEnabled = !this.params.disableNoDispatch
noDispatchEnabled
// channel id or 0 => msg id
noDispatchMsg = new Map<number, Set<number>>()
// channel id or 0 => pts
@ -128,14 +128,14 @@ export class UpdatesManager {
// whether to catch up channels from the locally stored pts
catchingUp = false
catchUpOnStart = this.params.catchUp ?? false
catchUpOnStart
cpts = new Map<number, number>()
cptsMod = new Map<number, number>()
channelDiffTimeouts = new Map<number, NodeJS.Timeout>()
channelsOpened = new Map<number, number>()
log = this.client.log.create('updates')
log
private _handler: RawUpdateHandler = () => {}
private _onCatchingUp: (catchingUp: boolean) => void = () => {}
@ -157,6 +157,9 @@ export class UpdatesManager {
this.hasTimedoutPostponed = true
this.updatesLoopCv.notify()
})
this.log = client.log.create('updates')
this.catchUpOnStart = params.catchUp ?? false
this.noDispatchEnabled = !params.disableNoDispatch
}
setHandler(handler: RawUpdateHandler): void {

View file

@ -91,9 +91,9 @@ export type PendingMessage =
export class MtprotoSession {
_sessionId = randomLong()
_authKey = new AuthKey(this._crypto, this.log, this._readerMap)
_authKeyTemp = new AuthKey(this._crypto, this.log, this._readerMap)
_authKeyTempSecondary = new AuthKey(this._crypto, this.log, this._readerMap)
_authKey: AuthKey
_authKeyTemp: AuthKey
_authKeyTempSecondary: AuthKey
_timeOffset = 0
_lastMessageId = Long.ZERO
@ -139,6 +139,10 @@ export class MtprotoSession {
readonly _salts: ServerSaltManager,
) {
this.log.prefix = `[SESSION ${this._sessionId.toString(16)}] `
this._authKey = new AuthKey(_crypto, log, _readerMap)
this._authKeyTemp = new AuthKey(_crypto, log, _readerMap)
this._authKeyTempSecondary = new AuthKey(_crypto, log, _readerMap)
}
get hasPendingMessages(): boolean {

View file

@ -188,7 +188,37 @@ export interface RpcCallOptions {
*/
export class DcConnectionManager {
private _salts = new ServerSaltManager()
private __baseConnectionParams = (): SessionConnectionParams => ({
private _log
/** Main connection pool */
main: MultiSessionConnection
/** Upload connection pool */
upload: MultiSessionConnection
/** Download connection pool */
download: MultiSessionConnection
/** Download connection pool (for small files) */
downloadSmall: MultiSessionConnection
private get _mainConnectionCount() {
if (!this.isPrimary) return 1
return this.manager.config.getNow()?.tmpSessions ?? 1
}
constructor(
/** Network manager instance */
readonly manager: NetworkManager,
/** DC ID */
readonly dcId: number,
/** DC options to use */
readonly _dcs: DcOptions,
/** Whether this DC is the primary one */
public isPrimary = false,
) {
this._log = this.manager._log.create('dc-manager')
this._log.prefix = `[DC ${dcId}] `
const baseConnectionParams = (): SessionConnectionParams => ({
crypto: this.manager.params.crypto,
initConnection: this.manager._initConnectionParams,
transportFactory: this.manager._transportFactory,
@ -207,54 +237,7 @@ export class DcConnectionManager {
salts: this._salts,
})
private _log = this.manager._log.create('dc-manager')
/** Main connection pool */
main: MultiSessionConnection
/** Upload connection pool */
upload = new MultiSessionConnection(
this.__baseConnectionParams(),
this.manager._connectionCount('upload', this.dcId, this.manager.params.isPremium),
this._log,
'UPLOAD',
)
/** Download connection pool */
download = new MultiSessionConnection(
this.__baseConnectionParams(),
this.manager._connectionCount('download', this.dcId, this.manager.params.isPremium),
this._log,
'DOWNLOAD',
)
/** Download connection pool (for small files) */
downloadSmall = new MultiSessionConnection(
this.__baseConnectionParams(),
this.manager._connectionCount('downloadSmall', this.dcId, this.manager.params.isPremium),
this._log,
'DOWNLOAD_SMALL',
)
private get _mainConnectionCount() {
if (!this.isPrimary) return 1
return this.manager.config.getNow()?.tmpSessions ?? 1
}
constructor(
/** Network manager instance */
readonly manager: NetworkManager,
/** DC ID */
readonly dcId: number,
/** DC options to use */
readonly _dcs: DcOptions,
/** Whether this DC is the primary one */
public isPrimary = false,
) {
this._log.prefix = `[DC ${dcId}] `
const mainParams = this.__baseConnectionParams()
const mainParams = baseConnectionParams()
mainParams.isMainConnection = true
mainParams.dc = _dcs.main
@ -263,6 +246,24 @@ export class DcConnectionManager {
}
this.main = new MultiSessionConnection(mainParams, this._mainConnectionCount, this._log, 'MAIN')
this.upload = new MultiSessionConnection(
baseConnectionParams(),
this.manager._connectionCount('upload', this.dcId, this.manager.params.isPremium),
this._log,
'UPLOAD',
)
this.download = new MultiSessionConnection(
baseConnectionParams(),
this.manager._connectionCount('download', this.dcId, this.manager.params.isPremium),
this._log,
'DOWNLOAD',
)
this.downloadSmall = new MultiSessionConnection(
baseConnectionParams(),
this.manager._connectionCount('downloadSmall', this.dcId, this.manager.params.isPremium),
this._log,
'DOWNLOAD_SMALL',
)
this._setupMulti('main')
this._setupMulti('upload')
@ -425,8 +426,8 @@ export class DcConnectionManager {
* Class that manages all connections to Telegram servers.
*/
export class NetworkManager {
readonly _log = this.params.log.create('network')
readonly _storage = this.params.storage
readonly _log
readonly _storage
readonly _initConnectionParams: tl.RawInitConnectionRequest
readonly _transportFactory: TransportFactory
@ -465,6 +466,9 @@ export class NetworkManager {
this._onConfigChanged = this._onConfigChanged.bind(this)
config.onReload(this._onConfigChanged)
this._log = params.log.create('network')
this._storage = params.storage
}
private async _findDcOptions(dcId: number): Promise<DcOptions> {

View file

@ -70,7 +70,7 @@ function makeNiceStack(error: tl.RpcError, stack: string, method?: string) {
* A connection to a single DC.
*/
export class SessionConnection extends PersistentConnection {
readonly params!: SessionConnectionParams
declare readonly params: SessionConnectionParams
private _flushTimer = new EarlyTimer()
private _queuedDestroySession: Long[] = []
@ -78,7 +78,7 @@ export class SessionConnection extends PersistentConnection {
// waitForMessage
private _pendingWaitForUnencrypted: [ControllablePromise<Uint8Array>, NodeJS.Timeout][] = []
private _usePfs = this.params.usePfs ?? false
private _usePfs
private _isPfsBindingPending = false
private _isPfsBindingPendingInBackground = false
private _pfsUpdateTimeout?: NodeJS.Timeout
@ -102,9 +102,12 @@ export class SessionConnection extends PersistentConnection {
this._crypto = params.crypto
this._salts = params.salts
this._handleRawMessage = this._handleRawMessage.bind(this)
this._usePfs = this.params.usePfs ?? false
this._online = getPlatform().isOnline?.() ?? true
}
private _online = getPlatform().isOnline?.() ?? true
private _online
getAuthKey(temp = false): Uint8Array | null {
const key = temp ? this._session._authKeyTemp : this._session._authKey

View file

@ -8,13 +8,14 @@ interface AuthKeysState {
}
export class MemoryAuthKeysRepository implements IAuthKeysRepository {
constructor(readonly _driver: MemoryStorageDriver) {}
readonly state = this._driver.getState<AuthKeysState>('authKeys', () => ({
readonly state
constructor(readonly _driver: MemoryStorageDriver) {
this.state = this._driver.getState<AuthKeysState>('authKeys', () => ({
authKeys: new Map(),
authKeysTemp: new Map(),
authKeysTempExpiry: new Map(),
}))
}
set(dc: number, key: Uint8Array | null): void {
if (key) {

View file

@ -2,9 +2,10 @@ import { IKeyValueRepository } from '../../repository/key-value.js'
import { MemoryStorageDriver } from '../driver.js'
export class MemoryKeyValueRepository implements IKeyValueRepository {
constructor(readonly _driver: MemoryStorageDriver) {}
readonly state = this._driver.getState<Map<string, Uint8Array>>('kv', () => new Map())
readonly state
constructor(readonly _driver: MemoryStorageDriver) {
this.state = this._driver.getState<Map<string, Uint8Array>>('kv', () => new Map())
}
set(key: string, value: Uint8Array): void {
this.state.set(key, value)

View file

@ -8,13 +8,14 @@ interface PeersState {
}
export class MemoryPeersRepository implements IPeersRepository {
constructor(readonly _driver: MemoryStorageDriver) {}
readonly state = this._driver.getState<PeersState>('peers', () => ({
readonly state
constructor(readonly _driver: MemoryStorageDriver) {
this.state = this._driver.getState<PeersState>('peers', () => ({
entities: new Map(),
usernameIndex: new Map(),
phoneIndex: new Map(),
}))
}
store(peer: IPeersRepository.PeerInfo): void {
const old = this.state.entities.get(peer.id)

View file

@ -6,11 +6,12 @@ interface RefMessagesState {
}
export class MemoryRefMessagesRepository implements IReferenceMessagesRepository {
constructor(readonly _driver: MemoryStorageDriver) {}
readonly state = this._driver.getState<RefMessagesState>('refMessages', () => ({
readonly state
constructor(readonly _driver: MemoryStorageDriver) {
this.state = this._driver.getState<RefMessagesState>('refMessages', () => ({
refs: new Map(),
}))
}
store(peerId: number, chatId: number, msgId: number): void {
if (!this.state.refs.has(peerId)) {

View file

@ -10,10 +10,15 @@ export { BaseSqliteStorageDriver }
export * from './types.js'
export class BaseSqliteStorage implements IMtStorageProvider, ITelegramStorageProvider {
constructor(readonly driver: BaseSqliteStorageDriver) {}
readonly authKeys
readonly kv
readonly refMessages
readonly peers
readonly authKeys = new SqliteAuthKeysRepository(this.driver)
readonly kv = new SqliteKeyValueRepository(this.driver)
readonly refMessages = new SqliteRefMessagesRepository(this.driver)
readonly peers = new SqlitePeersRepository(this.driver)
constructor(readonly driver: BaseSqliteStorageDriver) {
this.authKeys = new SqliteAuthKeysRepository(this.driver)
this.kv = new SqliteKeyValueRepository(this.driver)
this.refMessages = new SqliteRefMessagesRepository(this.driver)
this.peers = new SqlitePeersRepository(this.driver)
}
}

View file

@ -40,22 +40,29 @@ export interface StorageManagerExtraOptions {
}
export class StorageManager {
constructor(readonly options: StorageManagerOptions & StorageManagerExtraOptions) {}
readonly provider
readonly driver
readonly log
readonly dcs
readonly salts
readonly keys
readonly provider = this.options.provider
readonly driver = this.provider.driver
readonly log = this.options.log.create('storage')
constructor(readonly options: StorageManagerOptions & StorageManagerExtraOptions) {
this.provider = this.options.provider
this.driver = this.provider.driver
this.log = this.options.log.create('storage')
readonly _serviceOptions: ServiceOptions = {
const serviceOptions: ServiceOptions = {
driver: this.driver,
readerMap: this.options.readerMap,
writerMap: this.options.writerMap,
log: this.log,
}
readonly dcs = new DefaultDcsService(this.provider.kv, this._serviceOptions)
readonly salts = new FutureSaltsService(this.provider.kv, this._serviceOptions)
readonly keys = new AuthKeysService(this.provider.authKeys, this.salts, this._serviceOptions)
this.dcs = new DefaultDcsService(this.provider.kv, serviceOptions)
this.salts = new FutureSaltsService(this.provider.kv, serviceOptions)
this.keys = new AuthKeysService(this.provider.authKeys, this.salts, serviceOptions)
}
private _cleanupRestore?: () => void

View file

@ -142,21 +142,24 @@ export class LogManager extends Logger {
static DEBUG = 4
static VERBOSE = 5
readonly platform
level: number
handler
constructor(tag = 'base') {
// workaround because we cant pass this to super
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-argument
super(null as any, tag)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(this as any).mgr = this
this.platform = getPlatform()
this.level = this.platform.getDefaultLogLevel() ?? DEFAULT_LOG_LEVEL
this.handler = this.platform.log.bind(this.platform)
}
private _filter: (tag: string) => boolean = defaultFilter
readonly platform = getPlatform()
level = this.platform.getDefaultLogLevel() ?? DEFAULT_LOG_LEVEL
handler = this.platform.log.bind(this.platform)
/**
* Create a {@link Logger} with the given tag
*

View file

@ -165,7 +165,7 @@ class TlsHelloWriter implements TlsOperationHandler {
pos = 0
private _domain: Buffer
private _grease = initGrease(this.crypto, 7)
private _grease
private _scopes: number[] = []
constructor(
@ -175,6 +175,7 @@ class TlsHelloWriter implements TlsOperationHandler {
) {
this._domain = domain
this.buf = Buffer.allocUnsafe(size)
this._grease = initGrease(this.crypto, 7)
}
string(buf: Buffer) {

View file

@ -12,9 +12,9 @@ const toBuffer = (buf: Uint8Array): Buffer => Buffer.from(buf.buffer, buf.byteOf
export class NodePlatform implements ICorePlatform {
// ICorePlatform
log!: typeof defaultLoggingHandler
beforeExit!: typeof beforeExit
normalizeFile!: typeof normalizeFile
declare log: typeof defaultLoggingHandler
declare beforeExit: typeof beforeExit
declare normalizeFile: typeof normalizeFile
getDeviceModel(): string {
return `${os.type()} ${os.arch()} ${os.release()}`

View file

@ -15,11 +15,17 @@ export { IdbStorageDriver } from './driver.js'
* recommended over local storage based one.
*/
export class IdbStorage implements IMtStorageProvider {
constructor(readonly dbName: string) {}
readonly driver
readonly kv
readonly authKeys
readonly peers
readonly refMessages
readonly driver = new IdbStorageDriver(this.dbName)
readonly kv = new IdbKvRepository(this.driver)
readonly authKeys = new IdbAuthKeysRepository(this.driver)
readonly peers = new IdbPeersRepository(this.driver)
readonly refMessages = new IdbRefMsgRepository(this.driver)
constructor(readonly dbName: string) {
this.driver = new IdbStorageDriver(this.dbName)
this.kv = new IdbKvRepository(this.driver)
this.authKeys = new IdbAuthKeysRepository(this.driver)
this.peers = new IdbPeersRepository(this.driver)
this.refMessages = new IdbRefMsgRepository(this.driver)
}
}

View file

@ -8,8 +8,8 @@ import { defaultLoggingHandler } from './logging.js'
export class WebPlatform implements ICorePlatform {
// ICorePlatform
log!: typeof defaultLoggingHandler
beforeExit!: typeof beforeExit
declare log: typeof defaultLoggingHandler
declare beforeExit: typeof beforeExit
getDeviceModel(): string {
if (typeof navigator === 'undefined') return 'Browser'
@ -47,14 +47,14 @@ export class WebPlatform implements ICorePlatform {
}
// ITlPlatform
utf8ByteLength!: typeof utf8ByteLength
utf8Encode!: typeof utf8Encode
utf8Decode!: typeof utf8Decode
hexEncode!: typeof hexEncode
hexDecode!: typeof hexDecode
declare utf8ByteLength: typeof utf8ByteLength
declare utf8Encode: typeof utf8Encode
declare utf8Decode: typeof utf8Decode
declare hexEncode: typeof hexEncode
declare hexDecode: typeof hexDecode
base64Encode!: typeof base64Encode
base64Decode!: typeof base64Decode
declare base64Encode: typeof base64Encode
declare base64Decode: typeof base64Decode
}
WebPlatform.prototype.log = defaultLoggingHandler

View file

@ -3,7 +3,7 @@
"outDir": "./dist",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "es2020",
"target": "es2022",
"allowJs": true,
"sourceMap": true,
"inlineSources": true,
@ -29,6 +29,7 @@
],
"resolveJsonModule": true,
"isolatedModules": true,
"useDefineForClassFields": true,
},
"ts-node": {
"esm": true,