@discordjs/ws 3.0.0-pr-11006.1765452229-e636950b2 → 3.0.0-pr-10758.1765463096-d081e1706

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/WorkerBootstrapper.ts","../src/strategies/context/WorkerContextFetchingStrategy.ts","../src/strategies/sharding/WorkerShardingStrategy.ts","../src/strategies/context/IContextFetchingStrategy.ts","../src/ws/WebSocketShard.ts","../src/utils/constants.ts","../src/strategies/sharding/SimpleShardingStrategy.ts","../src/strategies/context/SimpleContextFetchingStrategy.ts","../src/throttling/SimpleIdentifyThrottler.ts","../src/strategies/sharding/defaultWorker.ts"],"sourcesContent":["import { isMainThread, parentPort, workerData } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { Awaitable } from '@discordjs/util';\nimport { WorkerContextFetchingStrategy } from '../strategies/context/WorkerContextFetchingStrategy.js';\nimport {\n\tWorkerReceivePayloadOp,\n\tWorkerSendPayloadOp,\n\ttype WorkerData,\n\ttype WorkerReceivePayload,\n\ttype WorkerSendPayload,\n} from '../strategies/sharding/WorkerShardingStrategy.js';\nimport type { WebSocketShardDestroyOptions } from '../ws/WebSocketShard.js';\nimport { WebSocketShardEvents, WebSocketShard } from '../ws/WebSocketShard.js';\n\n/**\n * Options for bootstrapping the worker\n */\nexport interface BootstrapOptions {\n\t/**\n\t * Shard events to just arbitrarily forward to the parent thread for the manager to emit\n\t * Note: By default, this will include ALL events\n\t * you most likely want to handle dispatch within the worker itself\n\t */\n\tforwardEvents?: WebSocketShardEvents[];\n\t/**\n\t * Function to call when a shard is created for additional setup\n\t */\n\tshardCallback?(shard: WebSocketShard): Awaitable<void>;\n}\n\n/**\n * Utility class for bootstrapping a worker thread to be used for sharding\n */\nexport class WorkerBootstrapper {\n\t/**\n\t * The data passed to the worker thread\n\t */\n\tprotected readonly data = workerData as WorkerData;\n\n\t/**\n\t * The shards that are managed by this worker\n\t */\n\tprotected readonly shards = new Collection<number, WebSocketShard>();\n\n\tpublic constructor() {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Expected WorkerBootstrap to not be used within the main thread');\n\t\t}\n\t}\n\n\t/**\n\t * Helper method to initiate a shard's connection process\n\t */\n\tprotected async connect(shardId: number): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.connect();\n\t}\n\n\t/**\n\t * Helper method to destroy a shard\n\t */\n\tprotected async destroy(shardId: number, options?: WebSocketShardDestroyOptions): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.destroy(options);\n\t}\n\n\t/**\n\t * Helper method to attach event listeners to the parentPort\n\t */\n\tprotected setupThreadEvents(): void {\n\t\tparentPort!\n\t\t\t.on('messageerror', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('message', async (payload: WorkerSendPayload) => {\n\t\t\t\tswitch (payload.op) {\n\t\t\t\t\tcase WorkerSendPayloadOp.Connect: {\n\t\t\t\t\t\tawait this.connect(payload.shardId);\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.Connected,\n\t\t\t\t\t\t\tshardId: payload.shardId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.Destroy: {\n\t\t\t\t\t\tawait this.destroy(payload.shardId, payload.options);\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.Destroyed,\n\t\t\t\t\t\t\tshardId: payload.shardId,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.Send: {\n\t\t\t\t\t\tconst shard = this.shards.get(payload.shardId);\n\t\t\t\t\t\tif (!shard) {\n\t\t\t\t\t\t\tthrow new RangeError(`Shard ${payload.shardId} does not exist`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait shard.send(payload.payload);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.SessionInfoResponse: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.ShardIdentifyResponse: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.FetchStatus: {\n\t\t\t\t\t\tconst shard = this.shards.get(payload.shardId);\n\t\t\t\t\t\tif (!shard) {\n\t\t\t\t\t\t\tthrow new Error(`Shard ${payload.shardId} does not exist`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.FetchStatusResponse,\n\t\t\t\t\t\t\tstatus: shard.status,\n\t\t\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Bootstraps the worker thread with the provided options\n\t */\n\tpublic async bootstrap(options: Readonly<BootstrapOptions> = {}): Promise<void> {\n\t\t// Start by initializing the shards\n\t\tfor (const shardId of this.data.shardIds) {\n\t\t\tconst shard = new WebSocketShard(new WorkerContextFetchingStrategy(this.data), shardId);\n\t\t\tfor (const event of options.forwardEvents ?? Object.values(WebSocketShardEvents)) {\n\t\t\t\tshard.on(event, (...args: unknown[]) => {\n\t\t\t\t\tconst payload: WorkerReceivePayload = {\n\t\t\t\t\t\top: WorkerReceivePayloadOp.Event,\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tdata: args,\n\t\t\t\t\t\tshardId,\n\t\t\t\t\t};\n\n\t\t\t\t\tparentPort!.postMessage(payload);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Any additional setup the user might want to do\n\t\t\tawait options.shardCallback?.(shard);\n\t\t\tthis.shards.set(shardId, shard);\n\t\t}\n\n\t\t// Lastly, start listening to messages from the parent thread\n\t\tthis.setupThreadEvents();\n\n\t\tconst message: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.WorkerReady,\n\t\t};\n\t\tparentPort!.postMessage(message);\n\t}\n}\n","import { isMainThread, parentPort } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { SessionInfo } from '../../ws/WebSocketManager.js';\nimport {\n\tWorkerReceivePayloadOp,\n\tWorkerSendPayloadOp,\n\ttype WorkerReceivePayload,\n\ttype WorkerSendPayload,\n} from '../sharding/WorkerShardingStrategy.js';\nimport type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';\n\nexport class WorkerContextFetchingStrategy implements IContextFetchingStrategy {\n\tprivate readonly sessionPromises = new Collection<number, (session: SessionInfo | null) => void>();\n\n\tprivate readonly waitForIdentifyPromises = new Collection<\n\t\tnumber,\n\t\t{ reject(error: unknown): void; resolve(): void; signal: AbortSignal }\n\t>();\n\n\tpublic constructor(public readonly options: FetchingStrategyOptions) {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Cannot instantiate WorkerContextFetchingStrategy on the main thread');\n\t\t}\n\n\t\tparentPort!.on('message', (payload: WorkerSendPayload) => {\n\t\t\tif (payload.op === WorkerSendPayloadOp.SessionInfoResponse) {\n\t\t\t\tthis.sessionPromises.get(payload.nonce)?.(payload.session);\n\t\t\t\tthis.sessionPromises.delete(payload.nonce);\n\t\t\t}\n\n\t\t\tif (payload.op === WorkerSendPayloadOp.ShardIdentifyResponse) {\n\t\t\t\tconst promise = this.waitForIdentifyPromises.get(payload.nonce);\n\t\t\t\tif (payload.ok) {\n\t\t\t\t\tpromise?.resolve();\n\t\t\t\t} else {\n\t\t\t\t\t// We need to make sure we reject with an abort error\n\t\t\t\t\tpromise?.reject(promise.signal.reason);\n\t\t\t\t}\n\n\t\t\t\tthis.waitForIdentifyPromises.delete(payload.nonce);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async retrieveSessionInfo(shardId: number): Promise<SessionInfo | null> {\n\t\tconst nonce = Math.random();\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.RetrieveSessionInfo,\n\t\t\tshardId,\n\t\t\tnonce,\n\t\t};\n\t\t// eslint-disable-next-line no-promise-executor-return\n\t\tconst promise = new Promise<SessionInfo | null>((resolve) => this.sessionPromises.set(nonce, resolve));\n\t\tparentPort!.postMessage(payload);\n\t\treturn promise;\n\t}\n\n\tpublic updateSessionInfo(shardId: number, sessionInfo: SessionInfo | null) {\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.UpdateSessionInfo,\n\t\t\tshardId,\n\t\t\tsession: sessionInfo,\n\t\t};\n\t\tparentPort!.postMessage(payload);\n\t}\n\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst nonce = Math.random();\n\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.WaitForIdentify,\n\t\t\tnonce,\n\t\t\tshardId,\n\t\t};\n\t\tconst promise = new Promise<void>((resolve, reject) =>\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tthis.waitForIdentifyPromises.set(nonce, { signal, resolve, reject }),\n\t\t);\n\n\t\tparentPort!.postMessage(payload);\n\n\t\tconst listener = () => {\n\t\t\tconst payload: WorkerReceivePayload = {\n\t\t\t\top: WorkerReceivePayloadOp.CancelIdentify,\n\t\t\t\tnonce,\n\t\t\t};\n\n\t\t\tparentPort!.postMessage(payload);\n\t\t};\n\n\t\tsignal.addEventListener('abort', listener);\n\n\t\ttry {\n\t\t\tawait promise;\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', listener);\n\t\t}\n\t}\n}\n","import { once } from 'node:events';\nimport { join, isAbsolute, resolve } from 'node:path';\nimport { Worker } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { GatewaySendPayload } from 'discord-api-types/v10';\nimport type { IIdentifyThrottler } from '../../throttling/IIdentifyThrottler.js';\nimport type { SessionInfo, WebSocketManager } from '../../ws/WebSocketManager.js';\nimport type {\n\tWebSocketShardDestroyOptions,\n\tWebSocketShardEvents,\n\tWebSocketShardStatus,\n} from '../../ws/WebSocketShard.js';\nimport { managerToFetchingStrategyOptions, type FetchingStrategyOptions } from '../context/IContextFetchingStrategy.js';\nimport type { IShardingStrategy } from './IShardingStrategy.js';\n\nexport interface WorkerData extends FetchingStrategyOptions {\n\tshardIds: number[];\n}\n\nexport enum WorkerSendPayloadOp {\n\tConnect,\n\tDestroy,\n\tSend,\n\tSessionInfoResponse,\n\tShardIdentifyResponse,\n\tFetchStatus,\n}\n\nexport type WorkerSendPayload =\n\t| { nonce: number; ok: boolean; op: WorkerSendPayloadOp.ShardIdentifyResponse }\n\t| { nonce: number; op: WorkerSendPayloadOp.FetchStatus; shardId: number }\n\t| { nonce: number; op: WorkerSendPayloadOp.SessionInfoResponse; session: SessionInfo | null }\n\t| { op: WorkerSendPayloadOp.Connect; shardId: number }\n\t| { op: WorkerSendPayloadOp.Destroy; options?: WebSocketShardDestroyOptions; shardId: number }\n\t| { op: WorkerSendPayloadOp.Send; payload: GatewaySendPayload; shardId: number };\n\nexport enum WorkerReceivePayloadOp {\n\tConnected,\n\tDestroyed,\n\tEvent,\n\tRetrieveSessionInfo,\n\tUpdateSessionInfo,\n\tWaitForIdentify,\n\tFetchStatusResponse,\n\tWorkerReady,\n\tCancelIdentify,\n}\n\nexport type WorkerReceivePayload =\n\t// Can't seem to get a type-safe union based off of the event, so I'm sadly leaving data as any for now\n\t| { data: any[]; event: WebSocketShardEvents; op: WorkerReceivePayloadOp.Event; shardId: number }\n\t| { nonce: number; op: WorkerReceivePayloadOp.CancelIdentify }\n\t| { nonce: number; op: WorkerReceivePayloadOp.FetchStatusResponse; status: WebSocketShardStatus }\n\t| { nonce: number; op: WorkerReceivePayloadOp.RetrieveSessionInfo; shardId: number }\n\t| { nonce: number; op: WorkerReceivePayloadOp.WaitForIdentify; shardId: number }\n\t| { op: WorkerReceivePayloadOp.Connected; shardId: number }\n\t| { op: WorkerReceivePayloadOp.Destroyed; shardId: number }\n\t| { op: WorkerReceivePayloadOp.UpdateSessionInfo; session: SessionInfo | null; shardId: number }\n\t| { op: WorkerReceivePayloadOp.WorkerReady };\n\n/**\n * Options for a {@link WorkerShardingStrategy}\n */\nexport interface WorkerShardingStrategyOptions {\n\t/**\n\t * Dictates how many shards should be spawned per worker thread.\n\t */\n\tshardsPerWorker: number | 'all';\n\t/**\n\t * Handles a payload not recognized by the handler.\n\t */\n\tunknownPayloadHandler?(payload: any): unknown;\n\t/**\n\t * Path to the worker file to use. The worker requires quite a bit of setup, it is recommended you leverage the {@link WorkerBootstrapper} class.\n\t */\n\tworkerPath?: string;\n}\n\n/**\n * Strategy used to spawn threads in worker_threads\n */\nexport class WorkerShardingStrategy implements IShardingStrategy {\n\tprivate readonly manager: WebSocketManager;\n\n\tprivate readonly options: WorkerShardingStrategyOptions;\n\n\t#workers: Worker[] = [];\n\n\treadonly #workerByShardId = new Collection<number, Worker>();\n\n\tprivate readonly connectPromises = new Collection<number, () => void>();\n\n\tprivate readonly destroyPromises = new Collection<number, () => void>();\n\n\tprivate readonly fetchStatusPromises = new Collection<number, (status: WebSocketShardStatus) => void>();\n\n\tprivate readonly waitForIdentifyControllers = new Collection<number, AbortController>();\n\n\tprivate throttler?: IIdentifyThrottler;\n\n\tpublic constructor(manager: WebSocketManager, options: WorkerShardingStrategyOptions) {\n\t\tthis.manager = manager;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.spawn}\n\t */\n\tpublic async spawn(shardIds: number[]) {\n\t\tconst shardsPerWorker = this.options.shardsPerWorker === 'all' ? shardIds.length : this.options.shardsPerWorker;\n\t\tconst strategyOptions = await managerToFetchingStrategyOptions(this.manager);\n\n\t\tconst loops = Math.ceil(shardIds.length / shardsPerWorker);\n\t\tconst promises: Promise<void>[] = [];\n\n\t\tfor (let idx = 0; idx < loops; idx++) {\n\t\t\tconst slice = shardIds.slice(idx * shardsPerWorker, (idx + 1) * shardsPerWorker);\n\t\t\tconst workerData: WorkerData = {\n\t\t\t\t...strategyOptions,\n\t\t\t\tshardIds: slice,\n\t\t\t};\n\n\t\t\tpromises.push(this.setupWorker(workerData));\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.connect}\n\t */\n\tpublic async connect() {\n\t\tconst promises = [];\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.Connect,\n\t\t\t\tshardId,\n\t\t\t};\n\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tconst promise = new Promise<void>((resolve) => this.connectPromises.set(shardId, resolve));\n\t\t\tworker.postMessage(payload);\n\t\t\tpromises.push(promise);\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.destroy}\n\t */\n\tpublic async destroy(options: Omit<WebSocketShardDestroyOptions, 'recover'> = {}) {\n\t\tconst promises = [];\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.Destroy,\n\t\t\t\tshardId,\n\t\t\t\toptions,\n\t\t\t};\n\n\t\t\tpromises.push(\n\t\t\t\t// eslint-disable-next-line no-promise-executor-return, promise/prefer-await-to-then\n\t\t\t\tnew Promise<void>((resolve) => this.destroyPromises.set(shardId, resolve)).then(async () => worker.terminate()),\n\t\t\t);\n\t\t\tworker.postMessage(payload);\n\t\t}\n\n\t\tthis.#workers = [];\n\t\tthis.#workerByShardId.clear();\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic send(shardId: number, data: GatewaySendPayload) {\n\t\tconst worker = this.#workerByShardId.get(shardId);\n\t\tif (!worker) {\n\t\t\tthrow new Error(`No worker found for shard ${shardId}`);\n\t\t}\n\n\t\tconst payload: WorkerSendPayload = {\n\t\t\top: WorkerSendPayloadOp.Send,\n\t\t\tshardId,\n\t\t\tpayload: data,\n\t\t};\n\t\tworker.postMessage(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\tconst statuses = new Collection<number, WebSocketShardStatus>();\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst nonce = Math.random();\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.FetchStatus,\n\t\t\t\tshardId,\n\t\t\t\tnonce,\n\t\t\t};\n\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tconst promise = new Promise<WebSocketShardStatus>((resolve) => this.fetchStatusPromises.set(nonce, resolve));\n\t\t\tworker.postMessage(payload);\n\n\t\t\tconst status = await promise;\n\t\t\tstatuses.set(shardId, status);\n\t\t}\n\n\t\treturn statuses;\n\t}\n\n\tprivate async setupWorker(workerData: WorkerData) {\n\t\tconst worker = new Worker(this.resolveWorkerPath(), { workerData });\n\n\t\tawait once(worker, 'online');\n\t\t// We do this in case the user has any potentially long running code in their worker\n\t\tawait this.waitForWorkerReady(worker);\n\n\t\tworker\n\t\t\t.on('error', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('messageerror', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('message', async (payload: any) => {\n\t\t\t\tif ('op' in payload) {\n\t\t\t\t\tawait this.onMessage(worker, payload);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.options.unknownPayloadHandler?.(payload);\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.#workers.push(worker);\n\t\tfor (const shardId of workerData.shardIds) {\n\t\t\tthis.#workerByShardId.set(shardId, worker);\n\t\t}\n\t}\n\n\tprivate resolveWorkerPath(): string {\n\t\tconst path = this.options.workerPath;\n\n\t\tif (!path) {\n\t\t\treturn join(__dirname, 'defaultWorker.js');\n\t\t}\n\n\t\tif (isAbsolute(path)) {\n\t\t\treturn path;\n\t\t}\n\n\t\tif (/^\\.\\.?[/\\\\]/.test(path)) {\n\t\t\treturn resolve(path);\n\t\t}\n\n\t\ttry {\n\t\t\treturn require.resolve(path);\n\t\t} catch {\n\t\t\treturn resolve(path);\n\t\t}\n\t}\n\n\tprivate async waitForWorkerReady(worker: Worker): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst handler = (payload: WorkerReceivePayload) => {\n\t\t\t\tif (payload.op === WorkerReceivePayloadOp.WorkerReady) {\n\t\t\t\t\tresolve();\n\t\t\t\t\tworker.off('message', handler);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tworker.on('message', handler);\n\t\t});\n\t}\n\n\tprivate async onMessage(worker: Worker, payload: WorkerReceivePayload) {\n\t\tswitch (payload.op) {\n\t\t\tcase WorkerReceivePayloadOp.Connected: {\n\t\t\t\tthis.connectPromises.get(payload.shardId)?.();\n\t\t\t\tthis.connectPromises.delete(payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.Destroyed: {\n\t\t\t\tthis.destroyPromises.get(payload.shardId)?.();\n\t\t\t\tthis.destroyPromises.delete(payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.Event: {\n\t\t\t\t// @ts-expect-error Event props can't be resolved properly, but they are correct\n\t\t\t\tthis.manager.emit(payload.event, ...payload.data, payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.RetrieveSessionInfo: {\n\t\t\t\tconst session = await this.manager.options.retrieveSessionInfo(payload.shardId);\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.SessionInfoResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tsession,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.UpdateSessionInfo: {\n\t\t\t\tawait this.manager.options.updateSessionInfo(payload.shardId, payload.session);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.WaitForIdentify: {\n\t\t\t\tconst throttler = await this.ensureThrottler();\n\n\t\t\t\t// If this rejects it means we aborted, in which case we reply elsewhere.\n\t\t\t\ttry {\n\t\t\t\t\tconst controller = new AbortController();\n\t\t\t\t\tthis.waitForIdentifyControllers.set(payload.nonce, controller);\n\t\t\t\t\tawait throttler.waitForIdentify(payload.shardId, controller.signal);\n\t\t\t\t} catch {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.ShardIdentifyResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tok: true,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.FetchStatusResponse: {\n\t\t\t\tthis.fetchStatusPromises.get(payload.nonce)?.(payload.status);\n\t\t\t\tthis.fetchStatusPromises.delete(payload.nonce);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.WorkerReady: {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.CancelIdentify: {\n\t\t\t\tthis.waitForIdentifyControllers.get(payload.nonce)?.abort();\n\t\t\t\tthis.waitForIdentifyControllers.delete(payload.nonce);\n\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.ShardIdentifyResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tok: false,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tawait this.options.unknownPayloadHandler?.(payload);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async ensureThrottler(): Promise<IIdentifyThrottler> {\n\t\tthis.throttler ??= await this.manager.options.buildIdentifyThrottler(this.manager);\n\t\treturn this.throttler;\n\t}\n}\n","import type { Awaitable } from '@discordjs/util';\nimport type { APIGatewayBotInfo } from 'discord-api-types/v10';\nimport type { SessionInfo, WebSocketManager, WebSocketManagerOptions } from '../../ws/WebSocketManager.js';\n\nexport interface FetchingStrategyOptions extends Pick<\n\tWebSocketManagerOptions,\n\t| 'compression'\n\t| 'encoding'\n\t| 'handshakeTimeout'\n\t| 'helloTimeout'\n\t| 'identifyProperties'\n\t| 'initialPresence'\n\t| 'intents'\n\t| 'largeThreshold'\n\t| 'readyTimeout'\n\t| 'token'\n\t| 'useIdentifyCompression'\n\t| 'version'\n> {\n\treadonly gatewayInformation: APIGatewayBotInfo;\n\treadonly shardCount: number;\n}\n\n/**\n * Strategies responsible solely for making manager information accessible\n */\nexport interface IContextFetchingStrategy {\n\treadonly options: FetchingStrategyOptions;\n\tretrieveSessionInfo(shardId: number): Awaitable<SessionInfo | null>;\n\tupdateSessionInfo(shardId: number, sessionInfo: SessionInfo | null): Awaitable<void>;\n\t/**\n\t * Resolves once the given shard should be allowed to identify\n\t * This should correctly handle the signal and reject with an abort error if the operation is aborted.\n\t * Other errors will cause the shard to reconnect.\n\t */\n\twaitForIdentify(shardId: number, signal: AbortSignal): Promise<void>;\n}\n\nexport async function managerToFetchingStrategyOptions(manager: WebSocketManager): Promise<FetchingStrategyOptions> {\n\treturn {\n\t\tcompression: manager.options.compression,\n\t\tencoding: manager.options.encoding,\n\t\thandshakeTimeout: manager.options.handshakeTimeout,\n\t\thelloTimeout: manager.options.helloTimeout,\n\t\tidentifyProperties: manager.options.identifyProperties,\n\t\tinitialPresence: manager.options.initialPresence,\n\t\tintents: manager.options.intents,\n\t\tlargeThreshold: manager.options.largeThreshold,\n\t\treadyTimeout: manager.options.readyTimeout,\n\t\ttoken: manager.token,\n\t\tuseIdentifyCompression: manager.options.useIdentifyCompression,\n\t\tversion: manager.options.version,\n\n\t\tgatewayInformation: await manager.fetchGatewayInformation(),\n\t\tshardCount: await manager.getShardCount(),\n\t};\n}\n","import { Buffer } from 'node:buffer';\nimport { once } from 'node:events';\nimport { setTimeout as sleep } from 'node:timers/promises';\nimport type * as nativeZlib from 'node:zlib';\nimport { Collection } from '@discordjs/collection';\nimport { lazy, shouldUseGlobalFetchAndWebSocket } from '@discordjs/util';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';\nimport {\n\tGatewayCloseCodes,\n\tGatewayDispatchEvents,\n\tGatewayOpcodes,\n\ttype GatewayDispatchPayload,\n\ttype GatewayIdentifyData,\n\ttype GatewayReadyDispatchData,\n\ttype GatewayReceivePayload,\n\ttype GatewaySendPayload,\n} from 'discord-api-types/v10';\nimport { WebSocket, type Data } from 'ws';\nimport type * as ZlibSync from 'zlib-sync';\nimport type { IContextFetchingStrategy } from '../strategies/context/IContextFetchingStrategy';\nimport {\n\tCompressionMethod,\n\tCompressionParameterMap,\n\tImportantGatewayOpcodes,\n\tgetInitialSendRateLimitState,\n} from '../utils/constants.js';\nimport type { SessionInfo } from './WebSocketManager.js';\n\n/* eslint-disable promise/prefer-await-to-then */\nconst getZlibSync = lazy(async () => import('zlib-sync').then((mod) => mod.default).catch(() => null));\nconst getNativeZlib = lazy(async () => import('node:zlib').then((mod) => mod).catch(() => null));\n/* eslint-enable promise/prefer-await-to-then */\n\nexport enum WebSocketShardEvents {\n\tClosed = 'closed',\n\tDebug = 'debug',\n\tDispatch = 'dispatch',\n\tError = 'error',\n\tHeartbeatComplete = 'heartbeat',\n\tHello = 'hello',\n\tReady = 'ready',\n\tResumed = 'resumed',\n\tSocketError = 'socketError',\n}\n\nexport enum WebSocketShardStatus {\n\tIdle,\n\tConnecting,\n\tResuming,\n\tReady,\n}\n\nexport enum WebSocketShardDestroyRecovery {\n\tReconnect,\n\tResume,\n}\n\nexport interface WebSocketShardEventsMap {\n\t[WebSocketShardEvents.Closed]: [code: number];\n\t[WebSocketShardEvents.Debug]: [message: string];\n\t[WebSocketShardEvents.Dispatch]: [payload: GatewayDispatchPayload];\n\t[WebSocketShardEvents.Error]: [error: Error];\n\t[WebSocketShardEvents.Hello]: [];\n\t[WebSocketShardEvents.Ready]: [payload: GatewayReadyDispatchData];\n\t[WebSocketShardEvents.Resumed]: [];\n\t[WebSocketShardEvents.HeartbeatComplete]: [stats: { ackAt: number; heartbeatAt: number; latency: number }];\n\t[WebSocketShardEvents.SocketError]: [error: Error];\n}\n\nexport interface WebSocketShardDestroyOptions {\n\tcode?: number;\n\treason?: string;\n\trecover?: WebSocketShardDestroyRecovery;\n}\n\nexport enum CloseCodes {\n\tNormal = 1_000,\n\tResuming = 4_200,\n}\n\nexport interface SendRateLimitState {\n\tresetAt: number;\n\tsent: number;\n}\n\nconst WebSocketConstructor: typeof WebSocket = shouldUseGlobalFetchAndWebSocket()\n\t? (globalThis as any).WebSocket\n\t: WebSocket;\n\nexport class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {\n\tprivate connection: WebSocket | null = null;\n\n\tprivate nativeInflate: nativeZlib.Inflate | null = null;\n\n\tprivate zLibSyncInflate: ZlibSync.Inflate | null = null;\n\n\t/**\n\t * @privateRemarks\n\t *\n\t * Used only for native zlib inflate, zlib-sync buffering is handled by the library itself.\n\t */\n\tprivate inflateBuffer: Buffer[] = [];\n\n\tprivate readonly textDecoder = new TextDecoder();\n\n\tprivate replayedEvents = 0;\n\n\tprivate isAck = true;\n\n\tprivate sendRateLimitState: SendRateLimitState = getInitialSendRateLimitState();\n\n\tprivate initialHeartbeatTimeoutController: AbortController | null = null;\n\n\tprivate heartbeatInterval: NodeJS.Timeout | null = null;\n\n\tprivate lastHeartbeatAt = -1;\n\n\t// Indicates whether the shard has already resolved its original connect() call\n\tprivate initialConnectResolved = false;\n\n\t// Indicates if we failed to connect to the ws url\n\tprivate failedToConnectDueToNetworkError = false;\n\n\tprivate readonly sendQueue = new AsyncQueue();\n\n\tprivate readonly timeoutAbortControllers = new Collection<WebSocketShardEvents, AbortController>();\n\n\tprivate readonly strategy: IContextFetchingStrategy;\n\n\tpublic readonly id: number;\n\n\t#status: WebSocketShardStatus = WebSocketShardStatus.Idle;\n\n\tprivate identifyCompressionEnabled = false;\n\n\t/**\n\t * @privateRemarks\n\t *\n\t * This is needed because `this.strategy.options.compression` is not an actual reflection of the compression method\n\t * used, but rather the compression method that the user wants to use. This is because the libraries could just be missing.\n\t */\n\tprivate get transportCompressionEnabled() {\n\t\treturn this.strategy.options.compression !== null && (this.nativeInflate ?? this.zLibSyncInflate) !== null;\n\t}\n\n\tpublic get status(): WebSocketShardStatus {\n\t\treturn this.#status;\n\t}\n\n\tpublic constructor(strategy: IContextFetchingStrategy, id: number) {\n\t\tsuper();\n\t\tthis.strategy = strategy;\n\t\tthis.id = id;\n\t}\n\n\tpublic async connect() {\n\t\tconst controller = new AbortController();\n\t\tlet promise;\n\n\t\tif (!this.initialConnectResolved) {\n\t\t\t// Sleep for the remaining time, but if the connection closes in the meantime, we shouldn't wait the remainder to avoid blocking the new conn\n\t\t\tpromise = Promise.race([\n\t\t\t\tonce(this, WebSocketShardEvents.Ready, { signal: controller.signal }),\n\t\t\t\tonce(this, WebSocketShardEvents.Resumed, { signal: controller.signal }),\n\t\t\t]);\n\t\t}\n\n\t\tvoid this.internalConnect();\n\n\t\ttry {\n\t\t\tawait promise;\n\t\t} finally {\n\t\t\t// cleanup hanging listeners\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.initialConnectResolved = true;\n\t}\n\n\tprivate async internalConnect() {\n\t\tif (this.#status !== WebSocketShardStatus.Idle) {\n\t\t\tthrow new Error(\"Tried to connect a shard that wasn't idle\");\n\t\t}\n\n\t\tconst { version, encoding, compression, useIdentifyCompression } = this.strategy.options;\n\t\tthis.identifyCompressionEnabled = useIdentifyCompression;\n\n\t\t// eslint-disable-next-line id-length\n\t\tconst params = new URLSearchParams({ v: version, encoding });\n\t\tif (compression !== null) {\n\t\t\tif (useIdentifyCompression) {\n\t\t\t\tconsole.warn('WebSocketShard: transport compression is enabled, disabling identify compression');\n\t\t\t\tthis.identifyCompressionEnabled = false;\n\t\t\t}\n\n\t\t\tparams.append('compress', CompressionParameterMap[compression]);\n\n\t\t\tswitch (compression) {\n\t\t\t\tcase CompressionMethod.ZlibNative: {\n\t\t\t\t\tconst zlib = await getNativeZlib();\n\t\t\t\t\tif (zlib) {\n\t\t\t\t\t\tthis.inflateBuffer = [];\n\n\t\t\t\t\t\tconst inflate = zlib.createInflate({\n\t\t\t\t\t\t\tchunkSize: 65_535,\n\t\t\t\t\t\t\tflush: zlib.constants.Z_SYNC_FLUSH,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tinflate.on('data', (chunk) => {\n\t\t\t\t\t\t\tthis.inflateBuffer.push(chunk);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tinflate.on('error', (error) => {\n\t\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis.nativeInflate = inflate;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn('WebSocketShard: Compression is set to native but node:zlib is not available.');\n\t\t\t\t\t\tparams.delete('compress');\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase CompressionMethod.ZlibSync: {\n\t\t\t\t\tconst zlib = await getZlibSync();\n\t\t\t\t\tif (zlib) {\n\t\t\t\t\t\tthis.zLibSyncInflate = new zlib.Inflate({\n\t\t\t\t\t\t\tchunkSize: 65_535,\n\t\t\t\t\t\t\tto: 'string',\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn('WebSocketShard: Compression is set to zlib-sync, but it is not installed.');\n\t\t\t\t\t\tparams.delete('compress');\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.identifyCompressionEnabled) {\n\t\t\tconst zlib = await getNativeZlib();\n\t\t\tif (!zlib) {\n\t\t\t\tconsole.warn('WebSocketShard: Identify compression is enabled, but node:zlib is not available.');\n\t\t\t\tthis.identifyCompressionEnabled = false;\n\t\t\t}\n\t\t}\n\n\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\n\t\tconst url = `${session?.resumeURL ?? this.strategy.options.gatewayInformation.url}?${params.toString()}`;\n\n\t\tthis.debug([`Connecting to ${url}`]);\n\n\t\tconst connection = new WebSocketConstructor(url, [], {\n\t\t\thandshakeTimeout: this.strategy.options.handshakeTimeout ?? undefined,\n\t\t});\n\n\t\tconnection.binaryType = 'arraybuffer';\n\n\t\tconnection.onmessage = (event) => {\n\t\t\tvoid this.onMessage(event.data, event.data instanceof ArrayBuffer);\n\t\t};\n\n\t\tconnection.onerror = (event) => {\n\t\t\tthis.onError(event.error);\n\t\t};\n\n\t\tconnection.onclose = (event) => {\n\t\t\tvoid this.onClose(event.code);\n\t\t};\n\n\t\tconnection.onopen = () => {\n\t\t\tthis.sendRateLimitState = getInitialSendRateLimitState();\n\t\t};\n\n\t\tthis.connection = connection;\n\n\t\tthis.#status = WebSocketShardStatus.Connecting;\n\n\t\tconst { ok } = await this.waitForEvent(WebSocketShardEvents.Hello, this.strategy.options.helloTimeout);\n\t\tif (!ok) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (session?.shardCount === this.strategy.options.shardCount) {\n\t\t\tawait this.resume(session);\n\t\t} else {\n\t\t\tawait this.identify();\n\t\t}\n\t}\n\n\tpublic async destroy(options: WebSocketShardDestroyOptions = {}) {\n\t\tif (this.#status === WebSocketShardStatus.Idle) {\n\t\t\tthis.debug(['Tried to destroy a shard that was idle']);\n\t\t\treturn;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\tif (!options.code) {\n\t\t\toptions.code = options.recover === WebSocketShardDestroyRecovery.Resume ? CloseCodes.Resuming : CloseCodes.Normal;\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Destroying shard',\n\t\t\t`Reason: ${options.reason ?? 'none'}`,\n\t\t\t`Code: ${options.code}`,\n\t\t\t`Recover: ${options.recover === undefined ? 'none' : WebSocketShardDestroyRecovery[options.recover]!}`,\n\t\t]);\n\n\t\t// Reset state\n\t\tthis.isAck = true;\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t}\n\n\t\tif (this.initialHeartbeatTimeoutController) {\n\t\t\tthis.initialHeartbeatTimeoutController.abort();\n\t\t\tthis.initialHeartbeatTimeoutController = null;\n\t\t}\n\n\t\tthis.lastHeartbeatAt = -1;\n\n\t\tfor (const controller of this.timeoutAbortControllers.values()) {\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.timeoutAbortControllers.clear();\n\n\t\tthis.failedToConnectDueToNetworkError = false;\n\n\t\t// Clear session state if applicable\n\t\tif (options.recover !== WebSocketShardDestroyRecovery.Resume) {\n\t\t\tawait this.strategy.updateSessionInfo(this.id, null);\n\t\t}\n\n\t\tif (this.connection) {\n\t\t\t// No longer need to listen to messages\n\t\t\tthis.connection.onmessage = null;\n\t\t\t// Prevent a reconnection loop by unbinding the main close event\n\t\t\tthis.connection.onclose = null;\n\n\t\t\tconst shouldClose = this.connection.readyState === WebSocket.OPEN;\n\n\t\t\tthis.debug([\n\t\t\t\t'Connection status during destroy',\n\t\t\t\t`Needs closing: ${shouldClose}`,\n\t\t\t\t`Ready state: ${this.connection.readyState}`,\n\t\t\t]);\n\n\t\t\tif (shouldClose) {\n\t\t\t\tlet outerResolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\t\t\touterResolve = resolve;\n\t\t\t\t});\n\n\t\t\t\tthis.connection.onclose = outerResolve!;\n\n\t\t\t\tthis.connection.close(options.code, options.reason);\n\n\t\t\t\tawait promise;\n\t\t\t\tthis.emit(WebSocketShardEvents.Closed, options.code);\n\t\t\t}\n\n\t\t\t// Lastly, remove the error event.\n\t\t\t// Doing this earlier would cause a hard crash in case an error event fired on our `close` call\n\t\t\tthis.connection.onerror = null;\n\t\t} else {\n\t\t\tthis.debug(['Destroying a shard that has no connection; please open an issue on GitHub']);\n\t\t}\n\n\t\tthis.#status = WebSocketShardStatus.Idle;\n\n\t\tif (options.recover !== undefined) {\n\t\t\t// There's cases (like no internet connection) where we immediately fail to connect,\n\t\t\t// causing a very fast and draining reconnection loop.\n\t\t\tawait sleep(500);\n\t\t\treturn this.internalConnect();\n\t\t}\n\t}\n\n\tprivate async waitForEvent(event: WebSocketShardEvents, timeoutDuration?: number | null): Promise<{ ok: boolean }> {\n\t\tthis.debug([`Waiting for event ${event} ${timeoutDuration ? `for ${timeoutDuration}ms` : 'indefinitely'}`]);\n\t\tconst timeoutController = new AbortController();\n\t\tconst timeout = timeoutDuration ? setTimeout(() => timeoutController.abort(), timeoutDuration).unref() : null;\n\n\t\tthis.timeoutAbortControllers.set(event, timeoutController);\n\n\t\tconst closeController = new AbortController();\n\n\t\ttry {\n\t\t\t// If the first promise resolves, all is well. If the 2nd promise resolves,\n\t\t\t// the shard has meanwhile closed. In that case, a destroy is already ongoing, so we just need to\n\t\t\t// return false. Meanwhile, if something rejects (error event) or the first controller is aborted,\n\t\t\t// we enter the catch block and trigger a destroy there.\n\t\t\tconst closed = await Promise.race<boolean>([\n\t\t\t\tonce(this, event, { signal: timeoutController.signal }).then(() => false),\n\t\t\t\tonce(this, WebSocketShardEvents.Closed, { signal: closeController.signal }).then(() => true),\n\t\t\t]);\n\n\t\t\treturn { ok: !closed };\n\t\t} catch {\n\t\t\t// If we're here because of other reasons, we need to destroy the shard\n\t\t\tvoid this.destroy({\n\t\t\t\tcode: CloseCodes.Normal,\n\t\t\t\treason: 'Something timed out or went wrong while waiting for an event',\n\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t});\n\n\t\t\treturn { ok: false };\n\t\t} finally {\n\t\t\tif (timeout) {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t}\n\n\t\t\tthis.timeoutAbortControllers.delete(event);\n\n\t\t\t// Clean up the close listener to not leak memory\n\t\t\tif (!closeController.signal.aborted) {\n\t\t\t\tcloseController.abort();\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async send(payload: GatewaySendPayload): Promise<void> {\n\t\tif (!this.connection) {\n\t\t\tthrow new Error(\"WebSocketShard wasn't connected\");\n\t\t}\n\n\t\t// Generally, the way we treat payloads is 115/60 seconds. The actual limit is 120/60, so we have a bit of leeway.\n\t\t// We use that leeway for those special payloads that we just fire with no checking, since there's no shot we ever\n\t\t// send more than 5 of those in a 60 second interval. This way we can avoid more complex queueing logic.\n\n\t\tif (ImportantGatewayOpcodes.has(payload.op)) {\n\t\t\tthis.connection.send(JSON.stringify(payload));\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#status !== WebSocketShardStatus.Ready && !ImportantGatewayOpcodes.has(payload.op)) {\n\t\t\tthis.debug(['Tried to send a non-crucial payload before the shard was ready, waiting']);\n\t\t\t// This will throw if the shard throws an error event in the meantime, just requeue the payload\n\t\t\ttry {\n\t\t\t\tawait once(this, WebSocketShardEvents.Ready);\n\t\t\t} catch {\n\t\t\t\treturn this.send(payload);\n\t\t\t}\n\t\t}\n\n\t\tawait this.sendQueue.wait();\n\n\t\tconst now = Date.now();\n\t\tif (now >= this.sendRateLimitState.resetAt) {\n\t\t\tthis.sendRateLimitState = getInitialSendRateLimitState();\n\t\t}\n\n\t\tif (this.sendRateLimitState.sent + 1 >= 115) {\n\t\t\t// Sprinkle in a little randomness just in case.\n\t\t\tconst sleepFor = this.sendRateLimitState.resetAt - now + Math.random() * 1_500;\n\n\t\t\tthis.debug([`Was about to hit the send rate limit, sleeping for ${sleepFor}ms`]);\n\t\t\tconst controller = new AbortController();\n\n\t\t\t// Sleep for the remaining time, but if the connection closes in the meantime, we shouldn't wait the remainder to avoid blocking the new conn\n\t\t\tconst interrupted = await Promise.race([\n\t\t\t\tsleep(sleepFor).then(() => false),\n\t\t\t\tonce(this, WebSocketShardEvents.Closed, { signal: controller.signal }).then(() => true),\n\t\t\t]);\n\n\t\t\tif (interrupted) {\n\t\t\t\tthis.debug(['Connection closed while waiting for the send rate limit to reset, re-queueing payload']);\n\t\t\t\tthis.sendQueue.shift();\n\t\t\t\treturn this.send(payload);\n\t\t\t}\n\n\t\t\t// This is so the listener from the `once` call is removed\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.sendRateLimitState.sent++;\n\n\t\tthis.sendQueue.shift();\n\t\tthis.connection.send(JSON.stringify(payload));\n\t}\n\n\tprivate async identify() {\n\t\tthis.debug(['Waiting for identify throttle']);\n\n\t\tconst controller = new AbortController();\n\t\tconst closeHandler = () => {\n\t\t\tcontroller.abort();\n\t\t};\n\n\t\tthis.on(WebSocketShardEvents.Closed, closeHandler);\n\n\t\ttry {\n\t\t\tawait this.strategy.waitForIdentify(this.id, controller.signal);\n\t\t} catch {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthis.debug(['Was waiting for an identify, but the shard closed in the meantime']);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.debug([\n\t\t\t\t'IContextFetchingStrategy#waitForIdentify threw an unknown error.',\n\t\t\t\t\"If you're using a custom strategy, this is probably nothing to worry about.\",\n\t\t\t\t\"If you're not, please open an issue on GitHub.\",\n\t\t\t]);\n\n\t\t\tawait this.destroy({\n\t\t\t\treason: 'Identify throttling logic failed',\n\t\t\t\trecover: WebSocketShardDestroyRecovery.Resume,\n\t\t\t});\n\t\t} finally {\n\t\t\tthis.off(WebSocketShardEvents.Closed, closeHandler);\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Identifying',\n\t\t\t`shard id: ${this.id.toString()}`,\n\t\t\t`shard count: ${this.strategy.options.shardCount}`,\n\t\t\t`intents: ${this.strategy.options.intents}`,\n\t\t\t`compression: ${this.transportCompressionEnabled ? CompressionParameterMap[this.strategy.options.compression!] : this.identifyCompressionEnabled ? 'identify' : 'none'}`,\n\t\t]);\n\n\t\tconst data: GatewayIdentifyData = {\n\t\t\ttoken: this.strategy.options.token,\n\t\t\tproperties: this.strategy.options.identifyProperties,\n\t\t\tintents: this.strategy.options.intents,\n\t\t\tcompress: this.identifyCompressionEnabled,\n\t\t\tshard: [this.id, this.strategy.options.shardCount],\n\t\t};\n\n\t\tif (this.strategy.options.largeThreshold) {\n\t\t\tdata.large_threshold = this.strategy.options.largeThreshold;\n\t\t}\n\n\t\tif (this.strategy.options.initialPresence) {\n\t\t\tdata.presence = this.strategy.options.initialPresence;\n\t\t}\n\n\t\tawait this.send({\n\t\t\top: GatewayOpcodes.Identify,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: data,\n\t\t});\n\n\t\tawait this.waitForEvent(WebSocketShardEvents.Ready, this.strategy.options.readyTimeout);\n\t}\n\n\tprivate async resume(session: SessionInfo) {\n\t\tthis.debug([\n\t\t\t'Resuming session',\n\t\t\t`resume url: ${session.resumeURL}`,\n\t\t\t`sequence: ${session.sequence}`,\n\t\t\t`shard id: ${this.id.toString()}`,\n\t\t]);\n\n\t\tthis.#status = WebSocketShardStatus.Resuming;\n\t\tthis.replayedEvents = 0;\n\t\treturn this.send({\n\t\t\top: GatewayOpcodes.Resume,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: {\n\t\t\t\ttoken: this.strategy.options.token,\n\t\t\t\tseq: session.sequence,\n\t\t\t\tsession_id: session.sessionId,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async heartbeat(requested = false) {\n\t\tif (!this.isAck && !requested) {\n\t\t\treturn this.destroy({ reason: 'Zombie connection', recover: WebSocketShardDestroyRecovery.Resume });\n\t\t}\n\n\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\n\t\tawait this.send({\n\t\t\top: GatewayOpcodes.Heartbeat,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: session?.sequence ?? null,\n\t\t});\n\n\t\tthis.lastHeartbeatAt = Date.now();\n\t\tthis.isAck = false;\n\t}\n\n\tprivate parseInflateResult(result: any): GatewayReceivePayload | null {\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn JSON.parse(typeof result === 'string' ? result : this.textDecoder.decode(result)) as GatewayReceivePayload;\n\t}\n\n\tprivate async unpackMessage(data: Data, isBinary: boolean): Promise<GatewayReceivePayload | null> {\n\t\t// Deal with no compression\n\t\tif (!isBinary) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(data as string) as GatewayReceivePayload;\n\t\t\t} catch {\n\t\t\t\t// This is a non-JSON payload / (at the time of writing this comment) emitted by bun wrongly interpreting custom close codes https://github.com/oven-sh/bun/issues/3392\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tconst decompressable = new Uint8Array(data as ArrayBuffer);\n\n\t\t// Deal with identify compress\n\t\tif (this.identifyCompressionEnabled) {\n\t\t\t// eslint-disable-next-line no-async-promise-executor\n\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\tconst zlib = (await getNativeZlib())!;\n\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-callbacks\n\t\t\t\tzlib.inflate(decompressable, { chunkSize: 65_535 }, (err, result) => {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve(JSON.parse(this.textDecoder.decode(result)) as GatewayReceivePayload);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\t// Deal with transport compression\n\t\tif (this.transportCompressionEnabled) {\n\t\t\tconst flush =\n\t\t\t\tdecompressable.length >= 4 &&\n\t\t\t\tdecompressable.at(-4) === 0x00 &&\n\t\t\t\tdecompressable.at(-3) === 0x00 &&\n\t\t\t\tdecompressable.at(-2) === 0xff &&\n\t\t\t\tdecompressable.at(-1) === 0xff;\n\n\t\t\tif (this.nativeInflate) {\n\t\t\t\tconst doneWriting = new Promise<void>((resolve) => {\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-callbacks\n\t\t\t\t\tthis.nativeInflate!.write(decompressable, 'binary', (error) => {\n\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tif (!flush) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// This way we're ensuring the latest write has flushed and our buffer is ready\n\t\t\t\tawait doneWriting;\n\n\t\t\t\tconst result = this.parseInflateResult(Buffer.concat(this.inflateBuffer));\n\t\t\t\tthis.inflateBuffer = [];\n\n\t\t\t\treturn result;\n\t\t\t} else if (this.zLibSyncInflate) {\n\t\t\t\tconst zLibSync = (await getZlibSync())!;\n\t\t\t\tthis.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);\n\n\t\t\t\tif (this.zLibSyncInflate.err) {\n\t\t\t\t\t// Must be here because zlib-sync is lazily loaded\n\t\t\t\t\tconst ZlibErrorCodes = {\n\t\t\t\t\t\t[zLibSync.Z_NEED_DICT]: 'Z_NEED_DICT',\n\t\t\t\t\t\t[zLibSync.Z_STREAM_END]: 'Z_STREAM_END',\n\t\t\t\t\t\t[zLibSync.Z_ERRNO]: 'Z_ERRNO',\n\t\t\t\t\t\t[zLibSync.Z_STREAM_ERROR]: 'Z_STREAM_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_DATA_ERROR]: 'Z_DATA_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_MEM_ERROR]: 'Z_MEM_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_BUF_ERROR]: 'Z_BUF_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_VERSION_ERROR]: 'Z_VERSION_ERROR',\n\t\t\t\t\t} as const satisfies Record<number, string>;\n\n\t\t\t\t\t// Try to match nodejs zlib errors as much as possible\n\t\t\t\t\tconst error: NodeJS.ErrnoException = new Error(this.zLibSyncInflate.msg ?? undefined);\n\t\t\t\t\terror.errno = this.zLibSyncInflate.err;\n\t\t\t\t\terror.code = ZlibErrorCodes[this.zLibSyncInflate.err];\n\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t}\n\n\t\t\t\tif (!flush) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst { result } = this.zLibSyncInflate;\n\t\t\t\treturn this.parseInflateResult(result);\n\t\t\t}\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Received a message we were unable to decompress',\n\t\t\t`isBinary: ${isBinary.toString()}`,\n\t\t\t`identifyCompressionEnabled: ${this.identifyCompressionEnabled.toString()}`,\n\t\t\t`inflate: ${this.transportCompressionEnabled ? CompressionMethod[this.strategy.options.compression!] : 'none'}`,\n\t\t]);\n\n\t\treturn null;\n\t}\n\n\tprivate async onMessage(data: Data, isBinary: boolean) {\n\t\tconst payload = await this.unpackMessage(data, isBinary);\n\t\tif (!payload) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch (payload.op) {\n\t\t\tcase GatewayOpcodes.Dispatch: {\n\t\t\t\tif (this.#status === WebSocketShardStatus.Resuming) {\n\t\t\t\t\tthis.replayedEvents++;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line sonarjs/no-nested-switch, @typescript-eslint/switch-exhaustiveness-check\n\t\t\t\tswitch (payload.t) {\n\t\t\t\t\tcase GatewayDispatchEvents.Ready: {\n\t\t\t\t\t\tthis.#status = WebSocketShardStatus.Ready;\n\n\t\t\t\t\t\tconst session = {\n\t\t\t\t\t\t\tsequence: payload.s,\n\t\t\t\t\t\t\tsessionId: payload.d.session_id,\n\t\t\t\t\t\t\tshardId: this.id,\n\t\t\t\t\t\t\tshardCount: this.strategy.options.shardCount,\n\t\t\t\t\t\t\tresumeURL: payload.d.resume_gateway_url,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tawait this.strategy.updateSessionInfo(this.id, session);\n\n\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Ready, payload.d);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase GatewayDispatchEvents.Resumed: {\n\t\t\t\t\t\tthis.#status = WebSocketShardStatus.Ready;\n\t\t\t\t\t\tthis.debug([`Resumed and replayed ${this.replayedEvents} events`]);\n\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Resumed);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\t\t\t\tif (session) {\n\t\t\t\t\tif (payload.s > session.sequence) {\n\t\t\t\t\t\tawait this.strategy.updateSessionInfo(this.id, { ...session, sequence: payload.s });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.debug([\n\t\t\t\t\t\t`Received a ${payload.t} event but no session is available. Session information cannot be re-constructed in this state without a full reconnect`,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\tthis.emit(WebSocketShardEvents.Dispatch, payload);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Heartbeat: {\n\t\t\t\tawait this.heartbeat(true);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Reconnect: {\n\t\t\t\tawait this.destroy({\n\t\t\t\t\treason: 'Told to reconnect by Discord',\n\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Resume,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.InvalidSession: {\n\t\t\t\tthis.debug([`Invalid session; will attempt to resume: ${payload.d.toString()}`]);\n\t\t\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\t\t\t\tif (payload.d && session) {\n\t\t\t\t\tawait this.resume(session);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.destroy({\n\t\t\t\t\t\treason: 'Invalid session',\n\t\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Hello: {\n\t\t\t\tthis.emit(WebSocketShardEvents.Hello);\n\t\t\t\tconst jitter = Math.random();\n\t\t\t\tconst firstWait = Math.floor(payload.d.heartbeat_interval * jitter);\n\t\t\t\tthis.debug([`Preparing first heartbeat of the connection with a jitter of ${jitter}; waiting ${firstWait}ms`]);\n\n\t\t\t\ttry {\n\t\t\t\t\tconst controller = new AbortController();\n\t\t\t\t\tthis.initialHeartbeatTimeoutController = controller;\n\t\t\t\t\tawait sleep(firstWait, undefined, { signal: controller.signal });\n\t\t\t\t} catch {\n\t\t\t\t\tthis.debug(['Cancelled initial heartbeat due to #destroy being called']);\n\t\t\t\t\treturn;\n\t\t\t\t} finally {\n\t\t\t\t\tthis.initialHeartbeatTimeoutController = null;\n\t\t\t\t}\n\n\t\t\t\tawait this.heartbeat();\n\n\t\t\t\tthis.debug([`First heartbeat sent, starting to beat every ${payload.d.heartbeat_interval}ms`]);\n\t\t\t\tthis.heartbeatInterval = setInterval(() => void this.heartbeat(), payload.d.heartbeat_interval);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.HeartbeatAck: {\n\t\t\t\tthis.isAck = true;\n\n\t\t\t\tconst ackAt = Date.now();\n\t\t\t\tthis.emit(WebSocketShardEvents.HeartbeatComplete, {\n\t\t\t\t\tackAt,\n\t\t\t\t\theartbeatAt: this.lastHeartbeatAt,\n\t\t\t\t\tlatency: ackAt - this.lastHeartbeatAt,\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onError(error: Error) {\n\t\tthis.emit(WebSocketShardEvents.SocketError, error);\n\t\tthis.failedToConnectDueToNetworkError = true;\n\t}\n\n\tprivate async onClose(code: number) {\n\t\tthis.emit(WebSocketShardEvents.Closed, code);\n\n\t\tswitch (code) {\n\t\t\tcase CloseCodes.Normal: {\n\t\t\t\treturn this.destroy({\n\t\t\t\t\tcode,\n\t\t\t\t\treason: 'Got disconnected by Discord',\n\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcase CloseCodes.Resuming: {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.UnknownError: {\n\t\t\t\tthis.debug([`An unknown error occurred: ${code}`]);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.UnknownOpcode: {\n\t\t\t\tthis.debug(['An invalid opcode was sent to Discord.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.DecodeError: {\n\t\t\t\tthis.debug(['An invalid payload was sent to Discord.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.NotAuthenticated: {\n\t\t\t\tthis.debug(['A request was somehow sent before the identify/resume payload.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.AuthenticationFailed: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Authentication failed'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.AlreadyAuthenticated: {\n\t\t\t\tthis.debug(['More than one auth payload was sent.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidSeq: {\n\t\t\t\tthis.debug(['An invalid sequence was sent.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.RateLimited: {\n\t\t\t\tthis.debug(['The WebSocket rate limit has been hit, this should never happen']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.SessionTimedOut: {\n\t\t\t\tthis.debug(['Session timed out.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidShard: {\n\t\t\t\tthis.emit(WebSocketShardEvents.Error, new Error('Invalid shard'));\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.ShardingRequired: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Sharding is required'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidAPIVersion: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used an invalid API version'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidIntents: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used invalid intents'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.DisallowedIntents: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used disallowed intents'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis.debug([\n\t\t\t\t\t`The gateway closed with an unexpected code ${code}, attempting to ${\n\t\t\t\t\t\tthis.failedToConnectDueToNetworkError ? 'reconnect' : 'resume'\n\t\t\t\t\t}.`,\n\t\t\t\t]);\n\t\t\t\treturn this.destroy({\n\t\t\t\t\tcode,\n\t\t\t\t\trecover: this.failedToConnectDueToNetworkError\n\t\t\t\t\t\t? WebSocketShardDestroyRecovery.Reconnect\n\t\t\t\t\t\t: WebSocketShardDestroyRecovery.Resume,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate debug(messages: [string, ...string[]]) {\n\t\tthis.emit(WebSocketShardEvents.Debug, messages.join('\\n\\t'));\n\t}\n}\n","import process from 'node:process';\nimport { Collection } from '@discordjs/collection';\nimport { lazy } from '@discordjs/util';\nimport { APIVersion, GatewayOpcodes } from 'discord-api-types/v10';\nimport { SimpleShardingStrategy } from '../strategies/sharding/SimpleShardingStrategy.js';\nimport { SimpleIdentifyThrottler } from '../throttling/SimpleIdentifyThrottler.js';\nimport type { SessionInfo, OptionalWebSocketManagerOptions, WebSocketManager } from '../ws/WebSocketManager.js';\nimport type { SendRateLimitState } from '../ws/WebSocketShard.js';\n\n/**\n * Valid encoding types\n */\nexport enum Encoding {\n\tJSON = 'json',\n}\n\n/**\n * Valid compression methods\n */\nexport enum CompressionMethod {\n\tZlibNative,\n\tZlibSync,\n}\n\nexport const DefaultDeviceProperty = `@discordjs/ws [VI]{{inject}}[/VI]` as `@discordjs/ws ${string}`;\n\nconst getDefaultSessionStore = lazy(() => new Collection<number, SessionInfo | null>());\n\nexport const CompressionParameterMap = {\n\t[CompressionMethod.ZlibNative]: 'zlib-stream',\n\t[CompressionMethod.ZlibSync]: 'zlib-stream',\n} as const satisfies Record<CompressionMethod, string>;\n\n/**\n * Default options used by the manager\n */\nexport const DefaultWebSocketManagerOptions = {\n\tasync buildIdentifyThrottler(manager: WebSocketManager) {\n\t\tconst info = await manager.fetchGatewayInformation();\n\t\treturn new SimpleIdentifyThrottler(info.session_start_limit.max_concurrency);\n\t},\n\tbuildStrategy: (manager) => new SimpleShardingStrategy(manager),\n\tshardCount: null,\n\tshardIds: null,\n\tlargeThreshold: null,\n\tinitialPresence: null,\n\tidentifyProperties: {\n\t\tbrowser: DefaultDeviceProperty,\n\t\tdevice: DefaultDeviceProperty,\n\t\tos: process.platform,\n\t},\n\tversion: APIVersion,\n\tencoding: Encoding.JSON,\n\tcompression: null,\n\tuseIdentifyCompression: false,\n\tretrieveSessionInfo(shardId) {\n\t\tconst store = getDefaultSessionStore();\n\t\treturn store.get(shardId) ?? null;\n\t},\n\tupdateSessionInfo(shardId: number, info: SessionInfo | null) {\n\t\tconst store = getDefaultSessionStore();\n\t\tif (info) {\n\t\t\tstore.set(shardId, info);\n\t\t} else {\n\t\t\tstore.delete(shardId);\n\t\t}\n\t},\n\thandshakeTimeout: 30_000,\n\thelloTimeout: 60_000,\n\treadyTimeout: 15_000,\n} as const satisfies Omit<OptionalWebSocketManagerOptions, 'fetchGatewayInformation' | 'token'>;\n\nexport const ImportantGatewayOpcodes = new Set([\n\tGatewayOpcodes.Heartbeat,\n\tGatewayOpcodes.Identify,\n\tGatewayOpcodes.Resume,\n]);\n\nexport function getInitialSendRateLimitState(): SendRateLimitState {\n\treturn {\n\t\tsent: 0,\n\t\tresetAt: Date.now() + 60_000,\n\t};\n}\n","import { Collection } from '@discordjs/collection';\nimport type { GatewaySendPayload } from 'discord-api-types/v10';\nimport type { WebSocketManager } from '../../ws/WebSocketManager.js';\nimport { WebSocketShard, WebSocketShardEvents, type WebSocketShardDestroyOptions } from '../../ws/WebSocketShard.js';\nimport { managerToFetchingStrategyOptions } from '../context/IContextFetchingStrategy.js';\nimport { SimpleContextFetchingStrategy } from '../context/SimpleContextFetchingStrategy.js';\nimport type { IShardingStrategy } from './IShardingStrategy.js';\n\n/**\n * Simple strategy that just spawns shards in the current process\n */\nexport class SimpleShardingStrategy implements IShardingStrategy {\n\tprivate readonly manager: WebSocketManager;\n\n\tprivate readonly shards = new Collection<number, WebSocketShard>();\n\n\tpublic constructor(manager: WebSocketManager) {\n\t\tthis.manager = manager;\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.spawn}\n\t */\n\tpublic async spawn(shardIds: number[]) {\n\t\tconst strategyOptions = await managerToFetchingStrategyOptions(this.manager);\n\n\t\tfor (const shardId of shardIds) {\n\t\t\tconst strategy = new SimpleContextFetchingStrategy(this.manager, strategyOptions);\n\t\t\tconst shard = new WebSocketShard(strategy, shardId);\n\n\t\t\tfor (const event of Object.values(WebSocketShardEvents)) {\n\t\t\t\t// @ts-expect-error Ugly casts are needed because when we try to collect all args, TS doesn't handle that nicely due to the strictness + lack of context\n\t\t\t\tshard.on(event, (...args) => this.manager.emit(event, ...args, shardId));\n\t\t\t}\n\n\t\t\tthis.shards.set(shardId, shard);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.connect}\n\t */\n\tpublic async connect() {\n\t\tconst promises = [];\n\n\t\tfor (const shard of this.shards.values()) {\n\t\t\tpromises.push(shard.connect());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.destroy}\n\t */\n\tpublic async destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {\n\t\tconst promises = [];\n\n\t\tfor (const shard of this.shards.values()) {\n\t\t\tpromises.push(shard.destroy(options));\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t\tthis.shards.clear();\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic async send(shardId: number, payload: GatewaySendPayload) {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} not found`);\n\t\t}\n\n\t\treturn shard.send(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\treturn this.shards.mapValues((shard) => shard.status);\n\t}\n}\n","import type { Awaitable } from '@discordjs/util';\nimport type { IIdentifyThrottler } from '../../throttling/IIdentifyThrottler.js';\nimport type { SessionInfo, WebSocketManager } from '../../ws/WebSocketManager.js';\nimport type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';\n\nexport class SimpleContextFetchingStrategy implements IContextFetchingStrategy {\n\t// This strategy assumes every shard is running under the same process - therefore we need a single\n\t// IdentifyThrottler per manager.\n\tprivate static throttlerCache = new WeakMap<WebSocketManager, IIdentifyThrottler>();\n\n\tprivate static async ensureThrottler(manager: WebSocketManager): Promise<IIdentifyThrottler> {\n\t\tconst throttler = SimpleContextFetchingStrategy.throttlerCache.get(manager);\n\t\tif (throttler) {\n\t\t\treturn throttler;\n\t\t}\n\n\t\tconst newThrottler = await manager.options.buildIdentifyThrottler(manager);\n\t\tSimpleContextFetchingStrategy.throttlerCache.set(manager, newThrottler);\n\n\t\treturn newThrottler;\n\t}\n\n\tpublic constructor(\n\t\tprivate readonly manager: WebSocketManager,\n\t\tpublic readonly options: FetchingStrategyOptions,\n\t) {}\n\n\tpublic async retrieveSessionInfo(shardId: number): Promise<SessionInfo | null> {\n\t\treturn this.manager.options.retrieveSessionInfo(shardId);\n\t}\n\n\tpublic updateSessionInfo(shardId: number, sessionInfo: SessionInfo | null): Awaitable<void> {\n\t\treturn this.manager.options.updateSessionInfo(shardId, sessionInfo);\n\t}\n\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst throttler = await SimpleContextFetchingStrategy.ensureThrottler(this.manager);\n\t\tawait throttler.waitForIdentify(shardId, signal);\n\t}\n}\n","import { setTimeout as sleep } from 'node:timers/promises';\nimport { Collection } from '@discordjs/collection';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport type { IIdentifyThrottler } from './IIdentifyThrottler.js';\n\n/**\n * The state of a rate limit key's identify queue.\n */\nexport interface IdentifyState {\n\tqueue: AsyncQueue;\n\tresetsAt: number;\n}\n\n/**\n * Local, in-memory identify throttler.\n */\nexport class SimpleIdentifyThrottler implements IIdentifyThrottler {\n\tprivate readonly states = new Collection<number, IdentifyState>();\n\n\tpublic constructor(private readonly maxConcurrency: number) {}\n\n\t/**\n\t * {@inheritDoc IIdentifyThrottler.waitForIdentify}\n\t */\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst key = shardId % this.maxConcurrency;\n\n\t\tconst state = this.states.ensure(key, () => ({\n\t\t\tqueue: new AsyncQueue(),\n\t\t\tresetsAt: Number.POSITIVE_INFINITY,\n\t\t}));\n\n\t\tawait state.queue.wait({ signal });\n\n\t\ttry {\n\t\t\tconst diff = state.resetsAt - Date.now();\n\t\t\tif (diff > 0 && diff <= 5_000) {\n\t\t\t\t// To account for the latency the IDENTIFY payload goes through, we add a bit more wait time\n\t\t\t\tconst time = diff + Math.random() * 1_500;\n\t\t\t\tawait sleep(time);\n\t\t\t}\n\n\t\t\tstate.resetsAt = Date.now() + 5_000;\n\t\t} finally {\n\t\t\tstate.queue.shift();\n\t\t}\n\t}\n}\n","import { WorkerBootstrapper } from '../../utils/WorkerBootstrapper.js';\n\nconst bootstrapper = new WorkerBootstrapper();\nvoid bootstrapper.bootstrap();\n"],"mappings":"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","names":["isMainThread","parentPort","Collection","Collection","Collection","resolve","payload","Buffer","once","sleep","Collection","lazy","AsyncQueue","GatewayOpcodes","Collection","Collection","Collection","Collection","Collection","CompressionMethod","Collection","lazy","WebSocketShardEvents","WebSocketShardDestroyRecovery","AsyncQueue","Collection","once","resolve","sleep","GatewayOpcodes","Buffer","session","Collection","isMainThread","parentPort"]}
1
+ {"version":3,"sources":["../src/utils/WorkerBootstrapper.ts","../src/strategies/context/WorkerContextFetchingStrategy.ts","../src/strategies/sharding/WorkerShardingStrategy.ts","../src/strategies/context/IContextFetchingStrategy.ts","../src/ws/WebSocketShard.ts","../src/utils/constants.ts","../src/strategies/sharding/SimpleShardingStrategy.ts","../src/strategies/context/SimpleContextFetchingStrategy.ts","../src/throttling/SimpleIdentifyThrottler.ts","../src/strategies/sharding/defaultWorker.ts"],"sourcesContent":["import { isMainThread, parentPort, workerData } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { Awaitable } from '@discordjs/util';\nimport { WorkerContextFetchingStrategy } from '../strategies/context/WorkerContextFetchingStrategy.js';\nimport {\n\tWorkerReceivePayloadOp,\n\tWorkerSendPayloadOp,\n\ttype WorkerData,\n\ttype WorkerReceivePayload,\n\ttype WorkerSendPayload,\n} from '../strategies/sharding/WorkerShardingStrategy.js';\nimport type { WebSocketShardDestroyOptions } from '../ws/WebSocketShard.js';\nimport { WebSocketShardEvents, WebSocketShard } from '../ws/WebSocketShard.js';\n\n/**\n * Options for bootstrapping the worker\n */\nexport interface BootstrapOptions {\n\t/**\n\t * Shard events to just arbitrarily forward to the parent thread for the manager to emit\n\t * Note: By default, this will include ALL events\n\t * you most likely want to handle dispatch within the worker itself\n\t */\n\tforwardEvents?: WebSocketShardEvents[];\n\t/**\n\t * Function to call when a shard is created for additional setup\n\t */\n\tshardCallback?(shard: WebSocketShard): Awaitable<void>;\n}\n\n/**\n * Utility class for bootstrapping a worker thread to be used for sharding\n */\nexport class WorkerBootstrapper {\n\t/**\n\t * The data passed to the worker thread\n\t */\n\tprotected readonly data = workerData as WorkerData;\n\n\t/**\n\t * The shards that are managed by this worker\n\t */\n\tprotected readonly shards = new Collection<number, WebSocketShard>();\n\n\tpublic constructor() {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Expected WorkerBootstrap to not be used within the main thread');\n\t\t}\n\t}\n\n\t/**\n\t * Helper method to initiate a shard's connection process\n\t */\n\tprotected async connect(shardId: number): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.connect();\n\t}\n\n\t/**\n\t * Helper method to destroy a shard\n\t */\n\tprotected async destroy(shardId: number, options?: WebSocketShardDestroyOptions): Promise<void> {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} does not exist`);\n\t\t}\n\n\t\tawait shard.destroy(options);\n\t}\n\n\t/**\n\t * Helper method to attach event listeners to the parentPort\n\t */\n\tprotected setupThreadEvents(): void {\n\t\tparentPort!\n\t\t\t.on('messageerror', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('message', async (payload: WorkerSendPayload) => {\n\t\t\t\tswitch (payload.op) {\n\t\t\t\t\tcase WorkerSendPayloadOp.Connect: {\n\t\t\t\t\t\tawait this.connect(payload.shardId);\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.Connected,\n\t\t\t\t\t\t\tshardId: payload.shardId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.Destroy: {\n\t\t\t\t\t\tawait this.destroy(payload.shardId, payload.options);\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.Destroyed,\n\t\t\t\t\t\t\tshardId: payload.shardId,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.Send: {\n\t\t\t\t\t\tconst shard = this.shards.get(payload.shardId);\n\t\t\t\t\t\tif (!shard) {\n\t\t\t\t\t\t\tthrow new RangeError(`Shard ${payload.shardId} does not exist`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait shard.send(payload.payload);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.SessionInfoResponse: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.ShardIdentifyResponse: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase WorkerSendPayloadOp.FetchStatus: {\n\t\t\t\t\t\tconst shard = this.shards.get(payload.shardId);\n\t\t\t\t\t\tif (!shard) {\n\t\t\t\t\t\t\tthrow new Error(`Shard ${payload.shardId} does not exist`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst response: WorkerReceivePayload = {\n\t\t\t\t\t\t\top: WorkerReceivePayloadOp.FetchStatusResponse,\n\t\t\t\t\t\t\tstatus: shard.status,\n\t\t\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tparentPort!.postMessage(response);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t/**\n\t * Bootstraps the worker thread with the provided options\n\t */\n\tpublic async bootstrap(options: Readonly<BootstrapOptions> = {}): Promise<void> {\n\t\t// Start by initializing the shards\n\t\tfor (const shardId of this.data.shardIds) {\n\t\t\tconst shard = new WebSocketShard(new WorkerContextFetchingStrategy(this.data), shardId);\n\t\t\tfor (const event of options.forwardEvents ?? Object.values(WebSocketShardEvents)) {\n\t\t\t\tshard.on(event, (...args: unknown[]) => {\n\t\t\t\t\tconst payload: WorkerReceivePayload = {\n\t\t\t\t\t\top: WorkerReceivePayloadOp.Event,\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tdata: args,\n\t\t\t\t\t\tshardId,\n\t\t\t\t\t};\n\n\t\t\t\t\tparentPort!.postMessage(payload);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Any additional setup the user might want to do\n\t\t\tawait options.shardCallback?.(shard);\n\t\t\tthis.shards.set(shardId, shard);\n\t\t}\n\n\t\t// Lastly, start listening to messages from the parent thread\n\t\tthis.setupThreadEvents();\n\n\t\tconst message: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.WorkerReady,\n\t\t};\n\t\tparentPort!.postMessage(message);\n\t}\n}\n","import { isMainThread, parentPort } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { SessionInfo } from '../../ws/WebSocketManager.js';\nimport {\n\tWorkerReceivePayloadOp,\n\tWorkerSendPayloadOp,\n\ttype WorkerReceivePayload,\n\ttype WorkerSendPayload,\n} from '../sharding/WorkerShardingStrategy.js';\nimport type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';\n\nexport class WorkerContextFetchingStrategy implements IContextFetchingStrategy {\n\tprivate readonly sessionPromises = new Collection<number, (session: SessionInfo | null) => void>();\n\n\tprivate readonly waitForIdentifyPromises = new Collection<\n\t\tnumber,\n\t\t{ reject(error: unknown): void; resolve(): void; signal: AbortSignal }\n\t>();\n\n\tpublic constructor(public readonly options: FetchingStrategyOptions) {\n\t\tif (isMainThread) {\n\t\t\tthrow new Error('Cannot instantiate WorkerContextFetchingStrategy on the main thread');\n\t\t}\n\n\t\tparentPort!.on('message', (payload: WorkerSendPayload) => {\n\t\t\tif (payload.op === WorkerSendPayloadOp.SessionInfoResponse) {\n\t\t\t\tthis.sessionPromises.get(payload.nonce)?.(payload.session);\n\t\t\t\tthis.sessionPromises.delete(payload.nonce);\n\t\t\t}\n\n\t\t\tif (payload.op === WorkerSendPayloadOp.ShardIdentifyResponse) {\n\t\t\t\tconst promise = this.waitForIdentifyPromises.get(payload.nonce);\n\t\t\t\tif (payload.ok) {\n\t\t\t\t\tpromise?.resolve();\n\t\t\t\t} else {\n\t\t\t\t\t// We need to make sure we reject with an abort error\n\t\t\t\t\tpromise?.reject(promise.signal.reason);\n\t\t\t\t}\n\n\t\t\t\tthis.waitForIdentifyPromises.delete(payload.nonce);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic async retrieveSessionInfo(shardId: number): Promise<SessionInfo | null> {\n\t\tconst nonce = Math.random();\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.RetrieveSessionInfo,\n\t\t\tshardId,\n\t\t\tnonce,\n\t\t};\n\t\t// eslint-disable-next-line no-promise-executor-return\n\t\tconst promise = new Promise<SessionInfo | null>((resolve) => this.sessionPromises.set(nonce, resolve));\n\t\tparentPort!.postMessage(payload);\n\t\treturn promise;\n\t}\n\n\tpublic updateSessionInfo(shardId: number, sessionInfo: SessionInfo | null) {\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.UpdateSessionInfo,\n\t\t\tshardId,\n\t\t\tsession: sessionInfo,\n\t\t};\n\t\tparentPort!.postMessage(payload);\n\t}\n\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst nonce = Math.random();\n\n\t\tconst payload: WorkerReceivePayload = {\n\t\t\top: WorkerReceivePayloadOp.WaitForIdentify,\n\t\t\tnonce,\n\t\t\tshardId,\n\t\t};\n\t\tconst promise = new Promise<void>((resolve, reject) =>\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tthis.waitForIdentifyPromises.set(nonce, { signal, resolve, reject }),\n\t\t);\n\n\t\tparentPort!.postMessage(payload);\n\n\t\tconst listener = () => {\n\t\t\tconst payload: WorkerReceivePayload = {\n\t\t\t\top: WorkerReceivePayloadOp.CancelIdentify,\n\t\t\t\tnonce,\n\t\t\t};\n\n\t\t\tparentPort!.postMessage(payload);\n\t\t};\n\n\t\tsignal.addEventListener('abort', listener);\n\n\t\ttry {\n\t\t\tawait promise;\n\t\t} finally {\n\t\t\tsignal.removeEventListener('abort', listener);\n\t\t}\n\t}\n}\n","import { once } from 'node:events';\nimport { join, isAbsolute, resolve } from 'node:path';\nimport { Worker } from 'node:worker_threads';\nimport { Collection } from '@discordjs/collection';\nimport type { GatewaySendPayload } from 'discord-api-types/v10';\nimport type { IIdentifyThrottler } from '../../throttling/IIdentifyThrottler.js';\nimport type { SessionInfo, WebSocketManager } from '../../ws/WebSocketManager.js';\nimport type {\n\tWebSocketShardDestroyOptions,\n\tWebSocketShardEvents,\n\tWebSocketShardStatus,\n} from '../../ws/WebSocketShard.js';\nimport { managerToFetchingStrategyOptions, type FetchingStrategyOptions } from '../context/IContextFetchingStrategy.js';\nimport type { IShardingStrategy } from './IShardingStrategy.js';\n\nexport interface WorkerData extends FetchingStrategyOptions {\n\tshardIds: number[];\n}\n\nexport enum WorkerSendPayloadOp {\n\tConnect,\n\tDestroy,\n\tSend,\n\tSessionInfoResponse,\n\tShardIdentifyResponse,\n\tFetchStatus,\n}\n\nexport type WorkerSendPayload =\n\t| { nonce: number; ok: boolean; op: WorkerSendPayloadOp.ShardIdentifyResponse }\n\t| { nonce: number; op: WorkerSendPayloadOp.FetchStatus; shardId: number }\n\t| { nonce: number; op: WorkerSendPayloadOp.SessionInfoResponse; session: SessionInfo | null }\n\t| { op: WorkerSendPayloadOp.Connect; shardId: number }\n\t| { op: WorkerSendPayloadOp.Destroy; options?: WebSocketShardDestroyOptions; shardId: number }\n\t| { op: WorkerSendPayloadOp.Send; payload: GatewaySendPayload; shardId: number };\n\nexport enum WorkerReceivePayloadOp {\n\tConnected,\n\tDestroyed,\n\tEvent,\n\tRetrieveSessionInfo,\n\tUpdateSessionInfo,\n\tWaitForIdentify,\n\tFetchStatusResponse,\n\tWorkerReady,\n\tCancelIdentify,\n}\n\nexport type WorkerReceivePayload =\n\t// Can't seem to get a type-safe union based off of the event, so I'm sadly leaving data as any for now\n\t| { data: any[]; event: WebSocketShardEvents; op: WorkerReceivePayloadOp.Event; shardId: number }\n\t| { nonce: number; op: WorkerReceivePayloadOp.CancelIdentify }\n\t| { nonce: number; op: WorkerReceivePayloadOp.FetchStatusResponse; status: WebSocketShardStatus }\n\t| { nonce: number; op: WorkerReceivePayloadOp.RetrieveSessionInfo; shardId: number }\n\t| { nonce: number; op: WorkerReceivePayloadOp.WaitForIdentify; shardId: number }\n\t| { op: WorkerReceivePayloadOp.Connected; shardId: number }\n\t| { op: WorkerReceivePayloadOp.Destroyed; shardId: number }\n\t| { op: WorkerReceivePayloadOp.UpdateSessionInfo; session: SessionInfo | null; shardId: number }\n\t| { op: WorkerReceivePayloadOp.WorkerReady };\n\n/**\n * Options for a {@link WorkerShardingStrategy}\n */\nexport interface WorkerShardingStrategyOptions {\n\t/**\n\t * Dictates how many shards should be spawned per worker thread.\n\t */\n\tshardsPerWorker: number | 'all';\n\t/**\n\t * Handles a payload not recognized by the handler.\n\t */\n\tunknownPayloadHandler?(payload: any): unknown;\n\t/**\n\t * Path to the worker file to use. The worker requires quite a bit of setup, it is recommended you leverage the {@link WorkerBootstrapper} class.\n\t */\n\tworkerPath?: string;\n}\n\n/**\n * Strategy used to spawn threads in worker_threads\n */\nexport class WorkerShardingStrategy implements IShardingStrategy {\n\tprivate readonly manager: WebSocketManager;\n\n\tprivate readonly options: WorkerShardingStrategyOptions;\n\n\t#workers: Worker[] = [];\n\n\treadonly #workerByShardId = new Collection<number, Worker>();\n\n\tprivate readonly connectPromises = new Collection<number, () => void>();\n\n\tprivate readonly destroyPromises = new Collection<number, () => void>();\n\n\tprivate readonly fetchStatusPromises = new Collection<number, (status: WebSocketShardStatus) => void>();\n\n\tprivate readonly waitForIdentifyControllers = new Collection<number, AbortController>();\n\n\tprivate throttler?: IIdentifyThrottler;\n\n\tpublic constructor(manager: WebSocketManager, options: WorkerShardingStrategyOptions) {\n\t\tthis.manager = manager;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.spawn}\n\t */\n\tpublic async spawn(shardIds: number[]) {\n\t\tconst shardsPerWorker = this.options.shardsPerWorker === 'all' ? shardIds.length : this.options.shardsPerWorker;\n\t\tconst strategyOptions = await managerToFetchingStrategyOptions(this.manager);\n\n\t\tconst loops = Math.ceil(shardIds.length / shardsPerWorker);\n\t\tconst promises: Promise<void>[] = [];\n\n\t\tfor (let idx = 0; idx < loops; idx++) {\n\t\t\tconst slice = shardIds.slice(idx * shardsPerWorker, (idx + 1) * shardsPerWorker);\n\t\t\tconst workerData: WorkerData = {\n\t\t\t\t...strategyOptions,\n\t\t\t\tshardIds: slice,\n\t\t\t};\n\n\t\t\tpromises.push(this.setupWorker(workerData));\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.connect}\n\t */\n\tpublic async connect() {\n\t\tconst promises = [];\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.Connect,\n\t\t\t\tshardId,\n\t\t\t};\n\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tconst promise = new Promise<void>((resolve) => this.connectPromises.set(shardId, resolve));\n\t\t\tworker.postMessage(payload);\n\t\t\tpromises.push(promise);\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.destroy}\n\t */\n\tpublic async destroy(options: Omit<WebSocketShardDestroyOptions, 'recover'> = {}) {\n\t\tconst promises = [];\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.Destroy,\n\t\t\t\tshardId,\n\t\t\t\toptions,\n\t\t\t};\n\n\t\t\tpromises.push(\n\t\t\t\t// eslint-disable-next-line no-promise-executor-return, promise/prefer-await-to-then\n\t\t\t\tnew Promise<void>((resolve) => this.destroyPromises.set(shardId, resolve)).then(async () => worker.terminate()),\n\t\t\t);\n\t\t\tworker.postMessage(payload);\n\t\t}\n\n\t\tthis.#workers = [];\n\t\tthis.#workerByShardId.clear();\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic send(shardId: number, data: GatewaySendPayload) {\n\t\tconst worker = this.#workerByShardId.get(shardId);\n\t\tif (!worker) {\n\t\t\tthrow new Error(`No worker found for shard ${shardId}`);\n\t\t}\n\n\t\tconst payload: WorkerSendPayload = {\n\t\t\top: WorkerSendPayloadOp.Send,\n\t\t\tshardId,\n\t\t\tpayload: data,\n\t\t};\n\t\tworker.postMessage(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\tconst statuses = new Collection<number, WebSocketShardStatus>();\n\n\t\tfor (const [shardId, worker] of this.#workerByShardId.entries()) {\n\t\t\tconst nonce = Math.random();\n\t\t\tconst payload: WorkerSendPayload = {\n\t\t\t\top: WorkerSendPayloadOp.FetchStatus,\n\t\t\t\tshardId,\n\t\t\t\tnonce,\n\t\t\t};\n\n\t\t\t// eslint-disable-next-line no-promise-executor-return\n\t\t\tconst promise = new Promise<WebSocketShardStatus>((resolve) => this.fetchStatusPromises.set(nonce, resolve));\n\t\t\tworker.postMessage(payload);\n\n\t\t\tconst status = await promise;\n\t\t\tstatuses.set(shardId, status);\n\t\t}\n\n\t\treturn statuses;\n\t}\n\n\tprivate async setupWorker(workerData: WorkerData) {\n\t\tconst worker = new Worker(this.resolveWorkerPath(), { workerData });\n\n\t\tawait once(worker, 'online');\n\t\t// We do this in case the user has any potentially long running code in their worker\n\t\tawait this.waitForWorkerReady(worker);\n\n\t\tworker\n\t\t\t.on('error', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('messageerror', (err) => {\n\t\t\t\tthrow err;\n\t\t\t})\n\t\t\t.on('message', async (payload: any) => {\n\t\t\t\tif ('op' in payload) {\n\t\t\t\t\tawait this.onMessage(worker, payload);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.options.unknownPayloadHandler?.(payload);\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.#workers.push(worker);\n\t\tfor (const shardId of workerData.shardIds) {\n\t\t\tthis.#workerByShardId.set(shardId, worker);\n\t\t}\n\t}\n\n\tprivate resolveWorkerPath(): string {\n\t\tconst path = this.options.workerPath;\n\n\t\tif (!path) {\n\t\t\treturn join(__dirname, 'defaultWorker.js');\n\t\t}\n\n\t\tif (isAbsolute(path)) {\n\t\t\treturn path;\n\t\t}\n\n\t\tif (/^\\.\\.?[/\\\\]/.test(path)) {\n\t\t\treturn resolve(path);\n\t\t}\n\n\t\ttry {\n\t\t\treturn require.resolve(path);\n\t\t} catch {\n\t\t\treturn resolve(path);\n\t\t}\n\t}\n\n\tprivate async waitForWorkerReady(worker: Worker): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst handler = (payload: WorkerReceivePayload) => {\n\t\t\t\tif (payload.op === WorkerReceivePayloadOp.WorkerReady) {\n\t\t\t\t\tresolve();\n\t\t\t\t\tworker.off('message', handler);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tworker.on('message', handler);\n\t\t});\n\t}\n\n\tprivate async onMessage(worker: Worker, payload: WorkerReceivePayload) {\n\t\tswitch (payload.op) {\n\t\t\tcase WorkerReceivePayloadOp.Connected: {\n\t\t\t\tthis.connectPromises.get(payload.shardId)?.();\n\t\t\t\tthis.connectPromises.delete(payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.Destroyed: {\n\t\t\t\tthis.destroyPromises.get(payload.shardId)?.();\n\t\t\t\tthis.destroyPromises.delete(payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.Event: {\n\t\t\t\t// @ts-expect-error Event props can't be resolved properly, but they are correct\n\t\t\t\tthis.manager.emit(payload.event, ...payload.data, payload.shardId);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.RetrieveSessionInfo: {\n\t\t\t\tconst session = await this.manager.options.retrieveSessionInfo(payload.shardId);\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.SessionInfoResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tsession,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.UpdateSessionInfo: {\n\t\t\t\tawait this.manager.options.updateSessionInfo(payload.shardId, payload.session);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.WaitForIdentify: {\n\t\t\t\tconst throttler = await this.ensureThrottler();\n\n\t\t\t\t// If this rejects it means we aborted, in which case we reply elsewhere.\n\t\t\t\ttry {\n\t\t\t\t\tconst controller = new AbortController();\n\t\t\t\t\tthis.waitForIdentifyControllers.set(payload.nonce, controller);\n\t\t\t\t\tawait throttler.waitForIdentify(payload.shardId, controller.signal);\n\t\t\t\t} catch {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.ShardIdentifyResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tok: true,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.FetchStatusResponse: {\n\t\t\t\tthis.fetchStatusPromises.get(payload.nonce)?.(payload.status);\n\t\t\t\tthis.fetchStatusPromises.delete(payload.nonce);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.WorkerReady: {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase WorkerReceivePayloadOp.CancelIdentify: {\n\t\t\t\tthis.waitForIdentifyControllers.get(payload.nonce)?.abort();\n\t\t\t\tthis.waitForIdentifyControllers.delete(payload.nonce);\n\n\t\t\t\tconst response: WorkerSendPayload = {\n\t\t\t\t\top: WorkerSendPayloadOp.ShardIdentifyResponse,\n\t\t\t\t\tnonce: payload.nonce,\n\t\t\t\t\tok: false,\n\t\t\t\t};\n\t\t\t\tworker.postMessage(response);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tawait this.options.unknownPayloadHandler?.(payload);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async ensureThrottler(): Promise<IIdentifyThrottler> {\n\t\tthis.throttler ??= await this.manager.options.buildIdentifyThrottler(this.manager);\n\t\treturn this.throttler;\n\t}\n}\n","import type { Awaitable } from '@discordjs/util';\nimport type { APIGatewayBotInfo } from 'discord-api-types/v10';\nimport type { SessionInfo, WebSocketManager, WebSocketManagerOptions } from '../../ws/WebSocketManager.js';\n\nexport interface FetchingStrategyOptions extends Pick<\n\tWebSocketManagerOptions,\n\t| 'compression'\n\t| 'encoding'\n\t| 'handshakeTimeout'\n\t| 'helloTimeout'\n\t| 'identifyProperties'\n\t| 'initialPresence'\n\t| 'intents'\n\t| 'largeThreshold'\n\t| 'readyTimeout'\n\t| 'token'\n\t| 'useIdentifyCompression'\n\t| 'version'\n> {\n\treadonly gatewayInformation: APIGatewayBotInfo;\n\treadonly shardCount: number;\n}\n\n/**\n * Strategies responsible solely for making manager information accessible\n */\nexport interface IContextFetchingStrategy {\n\treadonly options: FetchingStrategyOptions;\n\tretrieveSessionInfo(shardId: number): Awaitable<SessionInfo | null>;\n\tupdateSessionInfo(shardId: number, sessionInfo: SessionInfo | null): Awaitable<void>;\n\t/**\n\t * Resolves once the given shard should be allowed to identify\n\t * This should correctly handle the signal and reject with an abort error if the operation is aborted.\n\t * Other errors will cause the shard to reconnect.\n\t */\n\twaitForIdentify(shardId: number, signal: AbortSignal): Promise<void>;\n}\n\nexport async function managerToFetchingStrategyOptions(manager: WebSocketManager): Promise<FetchingStrategyOptions> {\n\treturn {\n\t\tcompression: manager.options.compression,\n\t\tencoding: manager.options.encoding,\n\t\thandshakeTimeout: manager.options.handshakeTimeout,\n\t\thelloTimeout: manager.options.helloTimeout,\n\t\tidentifyProperties: manager.options.identifyProperties,\n\t\tinitialPresence: manager.options.initialPresence,\n\t\tintents: manager.options.intents,\n\t\tlargeThreshold: manager.options.largeThreshold,\n\t\treadyTimeout: manager.options.readyTimeout,\n\t\ttoken: manager.token,\n\t\tuseIdentifyCompression: manager.options.useIdentifyCompression,\n\t\tversion: manager.options.version,\n\n\t\tgatewayInformation: await manager.fetchGatewayInformation(),\n\t\tshardCount: await manager.getShardCount(),\n\t};\n}\n","import { Buffer } from 'node:buffer';\nimport { once } from 'node:events';\nimport { setTimeout as sleep } from 'node:timers/promises';\nimport type * as nativeZlib from 'node:zlib';\nimport { Collection } from '@discordjs/collection';\nimport { lazy, shouldUseGlobalFetchAndWebSocket } from '@discordjs/util';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';\nimport {\n\tGatewayCloseCodes,\n\tGatewayDispatchEvents,\n\tGatewayOpcodes,\n\ttype GatewayDispatchPayload,\n\ttype GatewayIdentifyData,\n\ttype GatewayReadyDispatchData,\n\ttype GatewayReceivePayload,\n\ttype GatewaySendPayload,\n} from 'discord-api-types/v10';\nimport { WebSocket, type Data } from 'ws';\nimport type * as ZlibSync from 'zlib-sync';\nimport type { IContextFetchingStrategy } from '../strategies/context/IContextFetchingStrategy';\nimport {\n\tCompressionMethod,\n\tCompressionParameterMap,\n\tImportantGatewayOpcodes,\n\tgetInitialSendRateLimitState,\n} from '../utils/constants.js';\nimport type { SessionInfo } from './WebSocketManager.js';\n\n/* eslint-disable promise/prefer-await-to-then */\nconst getZlibSync = lazy(async () => import('zlib-sync').then((mod) => mod.default).catch(() => null));\nconst getNativeZlib = lazy(async () => import('node:zlib').then((mod) => mod).catch(() => null));\n/* eslint-enable promise/prefer-await-to-then */\n\nexport enum WebSocketShardEvents {\n\tClosed = 'closed',\n\tDebug = 'debug',\n\tDispatch = 'dispatch',\n\tError = 'error',\n\tHeartbeatComplete = 'heartbeat',\n\tHello = 'hello',\n\tReady = 'ready',\n\tResumed = 'resumed',\n\tSocketError = 'socketError',\n}\n\nexport enum WebSocketShardStatus {\n\tIdle,\n\tConnecting,\n\tResuming,\n\tReady,\n}\n\nexport enum WebSocketShardDestroyRecovery {\n\tReconnect,\n\tResume,\n}\n\nexport interface WebSocketShardEventsMap {\n\t[WebSocketShardEvents.Closed]: [code: number];\n\t[WebSocketShardEvents.Debug]: [message: string];\n\t[WebSocketShardEvents.Dispatch]: [payload: GatewayDispatchPayload];\n\t[WebSocketShardEvents.Error]: [error: Error];\n\t[WebSocketShardEvents.Hello]: [];\n\t[WebSocketShardEvents.Ready]: [payload: GatewayReadyDispatchData];\n\t[WebSocketShardEvents.Resumed]: [];\n\t[WebSocketShardEvents.HeartbeatComplete]: [stats: { ackAt: number; heartbeatAt: number; latency: number }];\n\t[WebSocketShardEvents.SocketError]: [error: Error];\n}\n\nexport interface WebSocketShardDestroyOptions {\n\tcode?: number;\n\treason?: string;\n\trecover?: WebSocketShardDestroyRecovery;\n}\n\nexport enum CloseCodes {\n\tNormal = 1_000,\n\tResuming = 4_200,\n}\n\nexport interface SendRateLimitState {\n\tresetAt: number;\n\tsent: number;\n}\n\nconst WebSocketConstructor: typeof WebSocket = shouldUseGlobalFetchAndWebSocket()\n\t? (globalThis as any).WebSocket\n\t: WebSocket;\n\nexport class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {\n\tprivate connection: WebSocket | null = null;\n\n\tprivate nativeInflate: nativeZlib.Inflate | null = null;\n\n\tprivate zLibSyncInflate: ZlibSync.Inflate | null = null;\n\n\t/**\n\t * @privateRemarks\n\t *\n\t * Used only for native zlib inflate, zlib-sync buffering is handled by the library itself.\n\t */\n\tprivate inflateBuffer: Buffer[] = [];\n\n\tprivate readonly textDecoder = new TextDecoder();\n\n\tprivate replayedEvents = 0;\n\n\tprivate isAck = true;\n\n\tprivate sendRateLimitState: SendRateLimitState = getInitialSendRateLimitState();\n\n\tprivate initialHeartbeatTimeoutController: AbortController | null = null;\n\n\tprivate heartbeatInterval: NodeJS.Timeout | null = null;\n\n\tprivate lastHeartbeatAt = -1;\n\n\t// Indicates whether the shard has already resolved its original connect() call\n\tprivate initialConnectResolved = false;\n\n\t// Indicates if we failed to connect to the ws url\n\tprivate failedToConnectDueToNetworkError = false;\n\n\tprivate readonly sendQueue = new AsyncQueue();\n\n\tprivate readonly timeoutAbortControllers = new Collection<WebSocketShardEvents, AbortController>();\n\n\tprivate readonly strategy: IContextFetchingStrategy;\n\n\tpublic readonly id: number;\n\n\t#status: WebSocketShardStatus = WebSocketShardStatus.Idle;\n\n\tprivate identifyCompressionEnabled = false;\n\n\t/**\n\t * @privateRemarks\n\t *\n\t * This is needed because `this.strategy.options.compression` is not an actual reflection of the compression method\n\t * used, but rather the compression method that the user wants to use. This is because the libraries could just be missing.\n\t */\n\tprivate get transportCompressionEnabled() {\n\t\treturn this.strategy.options.compression !== null && (this.nativeInflate ?? this.zLibSyncInflate) !== null;\n\t}\n\n\tpublic get status(): WebSocketShardStatus {\n\t\treturn this.#status;\n\t}\n\n\tpublic constructor(strategy: IContextFetchingStrategy, id: number) {\n\t\tsuper();\n\t\tthis.strategy = strategy;\n\t\tthis.id = id;\n\t}\n\n\tpublic async connect() {\n\t\tconst controller = new AbortController();\n\t\tlet promise;\n\n\t\tif (!this.initialConnectResolved) {\n\t\t\t// Sleep for the remaining time, but if the connection closes in the meantime, we shouldn't wait the remainder to avoid blocking the new conn\n\t\t\tpromise = Promise.race([\n\t\t\t\tonce(this, WebSocketShardEvents.Ready, { signal: controller.signal }),\n\t\t\t\tonce(this, WebSocketShardEvents.Resumed, { signal: controller.signal }),\n\t\t\t]);\n\t\t}\n\n\t\tvoid this.internalConnect();\n\n\t\ttry {\n\t\t\tawait promise;\n\t\t} finally {\n\t\t\t// cleanup hanging listeners\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.initialConnectResolved = true;\n\t}\n\n\tprivate async internalConnect() {\n\t\tif (this.#status !== WebSocketShardStatus.Idle) {\n\t\t\tthrow new Error(\"Tried to connect a shard that wasn't idle\");\n\t\t}\n\n\t\tconst { version, encoding, compression, useIdentifyCompression } = this.strategy.options;\n\t\tthis.identifyCompressionEnabled = useIdentifyCompression;\n\n\t\t// eslint-disable-next-line id-length\n\t\tconst params = new URLSearchParams({ v: version, encoding });\n\t\tif (compression !== null) {\n\t\t\tif (useIdentifyCompression) {\n\t\t\t\tconsole.warn('WebSocketShard: transport compression is enabled, disabling identify compression');\n\t\t\t\tthis.identifyCompressionEnabled = false;\n\t\t\t}\n\n\t\t\tparams.append('compress', CompressionParameterMap[compression]);\n\n\t\t\tswitch (compression) {\n\t\t\t\tcase CompressionMethod.ZlibNative: {\n\t\t\t\t\tconst zlib = await getNativeZlib();\n\t\t\t\t\tif (zlib) {\n\t\t\t\t\t\tthis.inflateBuffer = [];\n\n\t\t\t\t\t\tconst inflate = zlib.createInflate({\n\t\t\t\t\t\t\tchunkSize: 65_535,\n\t\t\t\t\t\t\tflush: zlib.constants.Z_SYNC_FLUSH,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tinflate.on('data', (chunk) => {\n\t\t\t\t\t\t\tthis.inflateBuffer.push(chunk);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tinflate.on('error', (error) => {\n\t\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis.nativeInflate = inflate;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn('WebSocketShard: Compression is set to native zlib but node:zlib is not available.');\n\t\t\t\t\t\tparams.delete('compress');\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase CompressionMethod.ZlibSync: {\n\t\t\t\t\tconst zlib = await getZlibSync();\n\t\t\t\t\tif (zlib) {\n\t\t\t\t\t\tthis.zLibSyncInflate = new zlib.Inflate({\n\t\t\t\t\t\t\tchunkSize: 65_535,\n\t\t\t\t\t\t\tto: 'string',\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn('WebSocketShard: Compression is set to zlib-sync, but it is not installed.');\n\t\t\t\t\t\tparams.delete('compress');\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase CompressionMethod.ZstdNative: {\n\t\t\t\t\tconst zlib = await getNativeZlib();\n\t\t\t\t\tif (zlib && 'createZstdDecompress' in zlib) {\n\t\t\t\t\t\tthis.inflateBuffer = [];\n\n\t\t\t\t\t\tconst inflate = zlib.createZstdDecompress({\n\t\t\t\t\t\t\tchunkSize: 65_535,\n\t\t\t\t\t\t}) as nativeZlib.Inflate;\n\n\t\t\t\t\t\tinflate.on('data', (chunk) => {\n\t\t\t\t\t\t\tthis.inflateBuffer.push(chunk);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tinflate.on('error', (error) => {\n\t\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis.nativeInflate = inflate;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t'WebSocketShard: Compression is set to native zstd but node:zlib is not available or your node version does not support zstd decompression.',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tparams.delete('compress');\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.identifyCompressionEnabled) {\n\t\t\tconst zlib = await getNativeZlib();\n\t\t\tif (!zlib) {\n\t\t\t\tconsole.warn('WebSocketShard: Identify compression is enabled, but node:zlib is not available.');\n\t\t\t\tthis.identifyCompressionEnabled = false;\n\t\t\t}\n\t\t}\n\n\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\n\t\tconst url = `${session?.resumeURL ?? this.strategy.options.gatewayInformation.url}?${params.toString()}`;\n\n\t\tthis.debug([`Connecting to ${url}`]);\n\n\t\tconst connection = new WebSocketConstructor(url, [], {\n\t\t\thandshakeTimeout: this.strategy.options.handshakeTimeout ?? undefined,\n\t\t});\n\n\t\tconnection.binaryType = 'arraybuffer';\n\n\t\tconnection.onmessage = (event) => {\n\t\t\tvoid this.onMessage(event.data, event.data instanceof ArrayBuffer);\n\t\t};\n\n\t\tconnection.onerror = (event) => {\n\t\t\tthis.onError(event.error);\n\t\t};\n\n\t\tconnection.onclose = (event) => {\n\t\t\tvoid this.onClose(event.code);\n\t\t};\n\n\t\tconnection.onopen = () => {\n\t\t\tthis.sendRateLimitState = getInitialSendRateLimitState();\n\t\t};\n\n\t\tthis.connection = connection;\n\n\t\tthis.#status = WebSocketShardStatus.Connecting;\n\n\t\tconst { ok } = await this.waitForEvent(WebSocketShardEvents.Hello, this.strategy.options.helloTimeout);\n\t\tif (!ok) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (session?.shardCount === this.strategy.options.shardCount) {\n\t\t\tawait this.resume(session);\n\t\t} else {\n\t\t\tawait this.identify();\n\t\t}\n\t}\n\n\tpublic async destroy(options: WebSocketShardDestroyOptions = {}) {\n\t\tif (this.#status === WebSocketShardStatus.Idle) {\n\t\t\tthis.debug(['Tried to destroy a shard that was idle']);\n\t\t\treturn;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\tif (!options.code) {\n\t\t\toptions.code = options.recover === WebSocketShardDestroyRecovery.Resume ? CloseCodes.Resuming : CloseCodes.Normal;\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Destroying shard',\n\t\t\t`Reason: ${options.reason ?? 'none'}`,\n\t\t\t`Code: ${options.code}`,\n\t\t\t`Recover: ${options.recover === undefined ? 'none' : WebSocketShardDestroyRecovery[options.recover]!}`,\n\t\t]);\n\n\t\t// Reset state\n\t\tthis.isAck = true;\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t}\n\n\t\tif (this.initialHeartbeatTimeoutController) {\n\t\t\tthis.initialHeartbeatTimeoutController.abort();\n\t\t\tthis.initialHeartbeatTimeoutController = null;\n\t\t}\n\n\t\tthis.lastHeartbeatAt = -1;\n\n\t\tfor (const controller of this.timeoutAbortControllers.values()) {\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.timeoutAbortControllers.clear();\n\n\t\tthis.failedToConnectDueToNetworkError = false;\n\n\t\t// Clear session state if applicable\n\t\tif (options.recover !== WebSocketShardDestroyRecovery.Resume) {\n\t\t\tawait this.strategy.updateSessionInfo(this.id, null);\n\t\t}\n\n\t\tif (this.connection) {\n\t\t\t// No longer need to listen to messages\n\t\t\tthis.connection.onmessage = null;\n\t\t\t// Prevent a reconnection loop by unbinding the main close event\n\t\t\tthis.connection.onclose = null;\n\n\t\t\tconst shouldClose = this.connection.readyState === WebSocket.OPEN;\n\n\t\t\tthis.debug([\n\t\t\t\t'Connection status during destroy',\n\t\t\t\t`Needs closing: ${shouldClose}`,\n\t\t\t\t`Ready state: ${this.connection.readyState}`,\n\t\t\t]);\n\n\t\t\tif (shouldClose) {\n\t\t\t\tlet outerResolve: () => void;\n\t\t\t\tconst promise = new Promise<void>((resolve) => {\n\t\t\t\t\touterResolve = resolve;\n\t\t\t\t});\n\n\t\t\t\tthis.connection.onclose = outerResolve!;\n\n\t\t\t\tthis.connection.close(options.code, options.reason);\n\n\t\t\t\tawait promise;\n\t\t\t\tthis.emit(WebSocketShardEvents.Closed, options.code);\n\t\t\t}\n\n\t\t\t// Lastly, remove the error event.\n\t\t\t// Doing this earlier would cause a hard crash in case an error event fired on our `close` call\n\t\t\tthis.connection.onerror = null;\n\t\t} else {\n\t\t\tthis.debug(['Destroying a shard that has no connection; please open an issue on GitHub']);\n\t\t}\n\n\t\tthis.#status = WebSocketShardStatus.Idle;\n\n\t\tif (options.recover !== undefined) {\n\t\t\t// There's cases (like no internet connection) where we immediately fail to connect,\n\t\t\t// causing a very fast and draining reconnection loop.\n\t\t\tawait sleep(500);\n\t\t\treturn this.internalConnect();\n\t\t}\n\t}\n\n\tprivate async waitForEvent(event: WebSocketShardEvents, timeoutDuration?: number | null): Promise<{ ok: boolean }> {\n\t\tthis.debug([`Waiting for event ${event} ${timeoutDuration ? `for ${timeoutDuration}ms` : 'indefinitely'}`]);\n\t\tconst timeoutController = new AbortController();\n\t\tconst timeout = timeoutDuration ? setTimeout(() => timeoutController.abort(), timeoutDuration).unref() : null;\n\n\t\tthis.timeoutAbortControllers.set(event, timeoutController);\n\n\t\tconst closeController = new AbortController();\n\n\t\ttry {\n\t\t\t// If the first promise resolves, all is well. If the 2nd promise resolves,\n\t\t\t// the shard has meanwhile closed. In that case, a destroy is already ongoing, so we just need to\n\t\t\t// return false. Meanwhile, if something rejects (error event) or the first controller is aborted,\n\t\t\t// we enter the catch block and trigger a destroy there.\n\t\t\tconst closed = await Promise.race<boolean>([\n\t\t\t\tonce(this, event, { signal: timeoutController.signal }).then(() => false),\n\t\t\t\tonce(this, WebSocketShardEvents.Closed, { signal: closeController.signal }).then(() => true),\n\t\t\t]);\n\n\t\t\treturn { ok: !closed };\n\t\t} catch {\n\t\t\t// If we're here because of other reasons, we need to destroy the shard\n\t\t\tvoid this.destroy({\n\t\t\t\tcode: CloseCodes.Normal,\n\t\t\t\treason: 'Something timed out or went wrong while waiting for an event',\n\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t});\n\n\t\t\treturn { ok: false };\n\t\t} finally {\n\t\t\tif (timeout) {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t}\n\n\t\t\tthis.timeoutAbortControllers.delete(event);\n\n\t\t\t// Clean up the close listener to not leak memory\n\t\t\tif (!closeController.signal.aborted) {\n\t\t\t\tcloseController.abort();\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async send(payload: GatewaySendPayload): Promise<void> {\n\t\tif (!this.connection) {\n\t\t\tthrow new Error(\"WebSocketShard wasn't connected\");\n\t\t}\n\n\t\t// Generally, the way we treat payloads is 115/60 seconds. The actual limit is 120/60, so we have a bit of leeway.\n\t\t// We use that leeway for those special payloads that we just fire with no checking, since there's no shot we ever\n\t\t// send more than 5 of those in a 60 second interval. This way we can avoid more complex queueing logic.\n\n\t\tif (ImportantGatewayOpcodes.has(payload.op)) {\n\t\t\tthis.connection.send(JSON.stringify(payload));\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#status !== WebSocketShardStatus.Ready && !ImportantGatewayOpcodes.has(payload.op)) {\n\t\t\tthis.debug(['Tried to send a non-crucial payload before the shard was ready, waiting']);\n\t\t\t// This will throw if the shard throws an error event in the meantime, just requeue the payload\n\t\t\ttry {\n\t\t\t\tawait once(this, WebSocketShardEvents.Ready);\n\t\t\t} catch {\n\t\t\t\treturn this.send(payload);\n\t\t\t}\n\t\t}\n\n\t\tawait this.sendQueue.wait();\n\n\t\tconst now = Date.now();\n\t\tif (now >= this.sendRateLimitState.resetAt) {\n\t\t\tthis.sendRateLimitState = getInitialSendRateLimitState();\n\t\t}\n\n\t\tif (this.sendRateLimitState.sent + 1 >= 115) {\n\t\t\t// Sprinkle in a little randomness just in case.\n\t\t\tconst sleepFor = this.sendRateLimitState.resetAt - now + Math.random() * 1_500;\n\n\t\t\tthis.debug([`Was about to hit the send rate limit, sleeping for ${sleepFor}ms`]);\n\t\t\tconst controller = new AbortController();\n\n\t\t\t// Sleep for the remaining time, but if the connection closes in the meantime, we shouldn't wait the remainder to avoid blocking the new conn\n\t\t\tconst interrupted = await Promise.race([\n\t\t\t\tsleep(sleepFor).then(() => false),\n\t\t\t\tonce(this, WebSocketShardEvents.Closed, { signal: controller.signal }).then(() => true),\n\t\t\t]);\n\n\t\t\tif (interrupted) {\n\t\t\t\tthis.debug(['Connection closed while waiting for the send rate limit to reset, re-queueing payload']);\n\t\t\t\tthis.sendQueue.shift();\n\t\t\t\treturn this.send(payload);\n\t\t\t}\n\n\t\t\t// This is so the listener from the `once` call is removed\n\t\t\tcontroller.abort();\n\t\t}\n\n\t\tthis.sendRateLimitState.sent++;\n\n\t\tthis.sendQueue.shift();\n\t\tthis.connection.send(JSON.stringify(payload));\n\t}\n\n\tprivate async identify() {\n\t\tthis.debug(['Waiting for identify throttle']);\n\n\t\tconst controller = new AbortController();\n\t\tconst closeHandler = () => {\n\t\t\tcontroller.abort();\n\t\t};\n\n\t\tthis.on(WebSocketShardEvents.Closed, closeHandler);\n\n\t\ttry {\n\t\t\tawait this.strategy.waitForIdentify(this.id, controller.signal);\n\t\t} catch {\n\t\t\tif (controller.signal.aborted) {\n\t\t\t\tthis.debug(['Was waiting for an identify, but the shard closed in the meantime']);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.debug([\n\t\t\t\t'IContextFetchingStrategy#waitForIdentify threw an unknown error.',\n\t\t\t\t\"If you're using a custom strategy, this is probably nothing to worry about.\",\n\t\t\t\t\"If you're not, please open an issue on GitHub.\",\n\t\t\t]);\n\n\t\t\tawait this.destroy({\n\t\t\t\treason: 'Identify throttling logic failed',\n\t\t\t\trecover: WebSocketShardDestroyRecovery.Resume,\n\t\t\t});\n\t\t} finally {\n\t\t\tthis.off(WebSocketShardEvents.Closed, closeHandler);\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Identifying',\n\t\t\t`shard id: ${this.id.toString()}`,\n\t\t\t`shard count: ${this.strategy.options.shardCount}`,\n\t\t\t`intents: ${this.strategy.options.intents}`,\n\t\t\t`compression: ${this.transportCompressionEnabled ? CompressionParameterMap[this.strategy.options.compression!] : this.identifyCompressionEnabled ? 'identify' : 'none'}`,\n\t\t]);\n\n\t\tconst data: GatewayIdentifyData = {\n\t\t\ttoken: this.strategy.options.token,\n\t\t\tproperties: this.strategy.options.identifyProperties,\n\t\t\tintents: this.strategy.options.intents,\n\t\t\tcompress: this.identifyCompressionEnabled,\n\t\t\tshard: [this.id, this.strategy.options.shardCount],\n\t\t};\n\n\t\tif (this.strategy.options.largeThreshold) {\n\t\t\tdata.large_threshold = this.strategy.options.largeThreshold;\n\t\t}\n\n\t\tif (this.strategy.options.initialPresence) {\n\t\t\tdata.presence = this.strategy.options.initialPresence;\n\t\t}\n\n\t\tawait this.send({\n\t\t\top: GatewayOpcodes.Identify,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: data,\n\t\t});\n\n\t\tawait this.waitForEvent(WebSocketShardEvents.Ready, this.strategy.options.readyTimeout);\n\t}\n\n\tprivate async resume(session: SessionInfo) {\n\t\tthis.debug([\n\t\t\t'Resuming session',\n\t\t\t`resume url: ${session.resumeURL}`,\n\t\t\t`sequence: ${session.sequence}`,\n\t\t\t`shard id: ${this.id.toString()}`,\n\t\t]);\n\n\t\tthis.#status = WebSocketShardStatus.Resuming;\n\t\tthis.replayedEvents = 0;\n\t\treturn this.send({\n\t\t\top: GatewayOpcodes.Resume,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: {\n\t\t\t\ttoken: this.strategy.options.token,\n\t\t\t\tseq: session.sequence,\n\t\t\t\tsession_id: session.sessionId,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async heartbeat(requested = false) {\n\t\tif (!this.isAck && !requested) {\n\t\t\treturn this.destroy({ reason: 'Zombie connection', recover: WebSocketShardDestroyRecovery.Resume });\n\t\t}\n\n\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\n\t\tawait this.send({\n\t\t\top: GatewayOpcodes.Heartbeat,\n\t\t\t// eslint-disable-next-line id-length\n\t\t\td: session?.sequence ?? null,\n\t\t});\n\n\t\tthis.lastHeartbeatAt = Date.now();\n\t\tthis.isAck = false;\n\t}\n\n\tprivate parseInflateResult(result: any): GatewayReceivePayload | null {\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn JSON.parse(typeof result === 'string' ? result : this.textDecoder.decode(result)) as GatewayReceivePayload;\n\t}\n\n\tprivate async unpackMessage(data: Data, isBinary: boolean): Promise<GatewayReceivePayload | null> {\n\t\t// Deal with no compression\n\t\tif (!isBinary) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(data as string) as GatewayReceivePayload;\n\t\t\t} catch {\n\t\t\t\t// This is a non-JSON payload / (at the time of writing this comment) emitted by bun wrongly interpreting custom close codes https://github.com/oven-sh/bun/issues/3392\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tconst decompressable = new Uint8Array(data as ArrayBuffer);\n\n\t\t// Deal with identify compress\n\t\tif (this.identifyCompressionEnabled) {\n\t\t\t// eslint-disable-next-line no-async-promise-executor\n\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\tconst zlib = (await getNativeZlib())!;\n\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-callbacks\n\t\t\t\tzlib.inflate(decompressable, { chunkSize: 65_535 }, (err, result) => {\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\treject(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve(JSON.parse(this.textDecoder.decode(result)) as GatewayReceivePayload);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\t// Deal with transport compression\n\t\tif (this.transportCompressionEnabled) {\n\t\t\t// Each WS message received is a full gateway message for zstd streaming, but for zlib it's chunked\n\t\t\tconst flush =\n\t\t\t\tthis.strategy.options.compression === CompressionMethod.ZstdNative ||\n\t\t\t\t(decompressable.length >= 4 &&\n\t\t\t\t\tdecompressable.at(-4) === 0x00 &&\n\t\t\t\t\tdecompressable.at(-3) === 0x00 &&\n\t\t\t\t\tdecompressable.at(-2) === 0xff &&\n\t\t\t\t\tdecompressable.at(-1) === 0xff);\n\n\t\t\tif (this.nativeInflate) {\n\t\t\t\tconst doneWriting = new Promise<void>((resolve) => {\n\t\t\t\t\t// eslint-disable-next-line promise/prefer-await-to-callbacks\n\t\t\t\t\tthis.nativeInflate!.write(decompressable, 'binary', (error) => {\n\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tif (!flush) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// This way we're ensuring the latest write has flushed and our buffer is ready\n\t\t\t\tawait doneWriting;\n\n\t\t\t\tconst result = this.parseInflateResult(Buffer.concat(this.inflateBuffer));\n\t\t\t\tthis.inflateBuffer = [];\n\n\t\t\t\treturn result;\n\t\t\t} else if (this.zLibSyncInflate) {\n\t\t\t\tconst zLibSync = (await getZlibSync())!;\n\t\t\t\tthis.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);\n\n\t\t\t\tif (this.zLibSyncInflate.err) {\n\t\t\t\t\t// Must be here because zlib-sync is lazily loaded\n\t\t\t\t\tconst ZlibErrorCodes = {\n\t\t\t\t\t\t[zLibSync.Z_NEED_DICT]: 'Z_NEED_DICT',\n\t\t\t\t\t\t[zLibSync.Z_STREAM_END]: 'Z_STREAM_END',\n\t\t\t\t\t\t[zLibSync.Z_ERRNO]: 'Z_ERRNO',\n\t\t\t\t\t\t[zLibSync.Z_STREAM_ERROR]: 'Z_STREAM_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_DATA_ERROR]: 'Z_DATA_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_MEM_ERROR]: 'Z_MEM_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_BUF_ERROR]: 'Z_BUF_ERROR',\n\t\t\t\t\t\t[zLibSync.Z_VERSION_ERROR]: 'Z_VERSION_ERROR',\n\t\t\t\t\t} as const satisfies Record<number, string>;\n\n\t\t\t\t\t// Try to match nodejs zlib errors as much as possible\n\t\t\t\t\tconst error: NodeJS.ErrnoException = new Error(this.zLibSyncInflate.msg ?? undefined);\n\t\t\t\t\terror.errno = this.zLibSyncInflate.err;\n\t\t\t\t\terror.code = ZlibErrorCodes[this.zLibSyncInflate.err];\n\t\t\t\t\tthis.emit(WebSocketShardEvents.Error, error);\n\t\t\t\t}\n\n\t\t\t\tif (!flush) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst { result } = this.zLibSyncInflate;\n\t\t\t\treturn this.parseInflateResult(result);\n\t\t\t}\n\t\t}\n\n\t\tthis.debug([\n\t\t\t'Received a message we were unable to decompress',\n\t\t\t`isBinary: ${isBinary.toString()}`,\n\t\t\t`identifyCompressionEnabled: ${this.identifyCompressionEnabled.toString()}`,\n\t\t\t`inflate: ${this.transportCompressionEnabled ? CompressionMethod[this.strategy.options.compression!] : 'none'}`,\n\t\t]);\n\n\t\treturn null;\n\t}\n\n\tprivate async onMessage(data: Data, isBinary: boolean) {\n\t\tconst payload = await this.unpackMessage(data, isBinary);\n\t\tif (!payload) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch (payload.op) {\n\t\t\tcase GatewayOpcodes.Dispatch: {\n\t\t\t\tif (this.#status === WebSocketShardStatus.Resuming) {\n\t\t\t\t\tthis.replayedEvents++;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line sonarjs/no-nested-switch, @typescript-eslint/switch-exhaustiveness-check\n\t\t\t\tswitch (payload.t) {\n\t\t\t\t\tcase GatewayDispatchEvents.Ready: {\n\t\t\t\t\t\tthis.#status = WebSocketShardStatus.Ready;\n\n\t\t\t\t\t\tconst session = {\n\t\t\t\t\t\t\tsequence: payload.s,\n\t\t\t\t\t\t\tsessionId: payload.d.session_id,\n\t\t\t\t\t\t\tshardId: this.id,\n\t\t\t\t\t\t\tshardCount: this.strategy.options.shardCount,\n\t\t\t\t\t\t\tresumeURL: payload.d.resume_gateway_url,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tawait this.strategy.updateSessionInfo(this.id, session);\n\n\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Ready, payload.d);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase GatewayDispatchEvents.Resumed: {\n\t\t\t\t\t\tthis.#status = WebSocketShardStatus.Ready;\n\t\t\t\t\t\tthis.debug([`Resumed and replayed ${this.replayedEvents} events`]);\n\t\t\t\t\t\tthis.emit(WebSocketShardEvents.Resumed);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\t\t\t\tif (session) {\n\t\t\t\t\tif (payload.s > session.sequence) {\n\t\t\t\t\t\tawait this.strategy.updateSessionInfo(this.id, { ...session, sequence: payload.s });\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.debug([\n\t\t\t\t\t\t`Received a ${payload.t} event but no session is available. Session information cannot be re-constructed in this state without a full reconnect`,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\tthis.emit(WebSocketShardEvents.Dispatch, payload);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Heartbeat: {\n\t\t\t\tawait this.heartbeat(true);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Reconnect: {\n\t\t\t\tawait this.destroy({\n\t\t\t\t\treason: 'Told to reconnect by Discord',\n\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Resume,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.InvalidSession: {\n\t\t\t\tthis.debug([`Invalid session; will attempt to resume: ${payload.d.toString()}`]);\n\t\t\t\tconst session = await this.strategy.retrieveSessionInfo(this.id);\n\t\t\t\tif (payload.d && session) {\n\t\t\t\t\tawait this.resume(session);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.destroy({\n\t\t\t\t\t\treason: 'Invalid session',\n\t\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.Hello: {\n\t\t\t\tthis.emit(WebSocketShardEvents.Hello);\n\t\t\t\tconst jitter = Math.random();\n\t\t\t\tconst firstWait = Math.floor(payload.d.heartbeat_interval * jitter);\n\t\t\t\tthis.debug([`Preparing first heartbeat of the connection with a jitter of ${jitter}; waiting ${firstWait}ms`]);\n\n\t\t\t\ttry {\n\t\t\t\t\tconst controller = new AbortController();\n\t\t\t\t\tthis.initialHeartbeatTimeoutController = controller;\n\t\t\t\t\tawait sleep(firstWait, undefined, { signal: controller.signal });\n\t\t\t\t} catch {\n\t\t\t\t\tthis.debug(['Cancelled initial heartbeat due to #destroy being called']);\n\t\t\t\t\treturn;\n\t\t\t\t} finally {\n\t\t\t\t\tthis.initialHeartbeatTimeoutController = null;\n\t\t\t\t}\n\n\t\t\t\tawait this.heartbeat();\n\n\t\t\t\tthis.debug([`First heartbeat sent, starting to beat every ${payload.d.heartbeat_interval}ms`]);\n\t\t\t\tthis.heartbeatInterval = setInterval(() => void this.heartbeat(), payload.d.heartbeat_interval);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayOpcodes.HeartbeatAck: {\n\t\t\t\tthis.isAck = true;\n\n\t\t\t\tconst ackAt = Date.now();\n\t\t\t\tthis.emit(WebSocketShardEvents.HeartbeatComplete, {\n\t\t\t\t\tackAt,\n\t\t\t\t\theartbeatAt: this.lastHeartbeatAt,\n\t\t\t\t\tlatency: ackAt - this.lastHeartbeatAt,\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onError(error: Error) {\n\t\tthis.emit(WebSocketShardEvents.SocketError, error);\n\t\tthis.failedToConnectDueToNetworkError = true;\n\t}\n\n\tprivate async onClose(code: number) {\n\t\tthis.emit(WebSocketShardEvents.Closed, code);\n\n\t\tswitch (code) {\n\t\t\tcase CloseCodes.Normal: {\n\t\t\t\treturn this.destroy({\n\t\t\t\t\tcode,\n\t\t\t\t\treason: 'Got disconnected by Discord',\n\t\t\t\t\trecover: WebSocketShardDestroyRecovery.Reconnect,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcase CloseCodes.Resuming: {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.UnknownError: {\n\t\t\t\tthis.debug([`An unknown error occurred: ${code}`]);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.UnknownOpcode: {\n\t\t\t\tthis.debug(['An invalid opcode was sent to Discord.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.DecodeError: {\n\t\t\t\tthis.debug(['An invalid payload was sent to Discord.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.NotAuthenticated: {\n\t\t\t\tthis.debug(['A request was somehow sent before the identify/resume payload.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.AuthenticationFailed: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Authentication failed'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.AlreadyAuthenticated: {\n\t\t\t\tthis.debug(['More than one auth payload was sent.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidSeq: {\n\t\t\t\tthis.debug(['An invalid sequence was sent.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.RateLimited: {\n\t\t\t\tthis.debug(['The WebSocket rate limit has been hit, this should never happen']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Reconnect });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.SessionTimedOut: {\n\t\t\t\tthis.debug(['Session timed out.']);\n\t\t\t\treturn this.destroy({ code, recover: WebSocketShardDestroyRecovery.Resume });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidShard: {\n\t\t\t\tthis.emit(WebSocketShardEvents.Error, new Error('Invalid shard'));\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.ShardingRequired: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Sharding is required'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidAPIVersion: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used an invalid API version'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.InvalidIntents: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used invalid intents'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tcase GatewayCloseCodes.DisallowedIntents: {\n\t\t\t\tthis.emit(\n\t\t\t\t\tWebSocketShardEvents.Error,\n\n\t\t\t\t\tnew Error('Used disallowed intents'),\n\t\t\t\t);\n\t\t\t\treturn this.destroy({ code });\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tthis.debug([\n\t\t\t\t\t`The gateway closed with an unexpected code ${code}, attempting to ${\n\t\t\t\t\t\tthis.failedToConnectDueToNetworkError ? 'reconnect' : 'resume'\n\t\t\t\t\t}.`,\n\t\t\t\t]);\n\t\t\t\treturn this.destroy({\n\t\t\t\t\tcode,\n\t\t\t\t\trecover: this.failedToConnectDueToNetworkError\n\t\t\t\t\t\t? WebSocketShardDestroyRecovery.Reconnect\n\t\t\t\t\t\t: WebSocketShardDestroyRecovery.Resume,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate debug(messages: [string, ...string[]]) {\n\t\tthis.emit(WebSocketShardEvents.Debug, messages.join('\\n\\t'));\n\t}\n}\n","import process from 'node:process';\nimport { Collection } from '@discordjs/collection';\nimport { lazy } from '@discordjs/util';\nimport { APIVersion, GatewayOpcodes } from 'discord-api-types/v10';\nimport { SimpleShardingStrategy } from '../strategies/sharding/SimpleShardingStrategy.js';\nimport { SimpleIdentifyThrottler } from '../throttling/SimpleIdentifyThrottler.js';\nimport type { SessionInfo, OptionalWebSocketManagerOptions, WebSocketManager } from '../ws/WebSocketManager.js';\nimport type { SendRateLimitState } from '../ws/WebSocketShard.js';\n\n/**\n * Valid encoding types\n */\nexport enum Encoding {\n\tJSON = 'json',\n}\n\n/**\n * Valid compression methods\n */\nexport enum CompressionMethod {\n\tZlibNative,\n\tZlibSync,\n\tZstdNative,\n}\n\nexport const DefaultDeviceProperty = `@discordjs/ws [VI]{{inject}}[/VI]` as `@discordjs/ws ${string}`;\n\nconst getDefaultSessionStore = lazy(() => new Collection<number, SessionInfo | null>());\n\nexport const CompressionParameterMap = {\n\t[CompressionMethod.ZlibNative]: 'zlib-stream',\n\t[CompressionMethod.ZlibSync]: 'zlib-stream',\n\t[CompressionMethod.ZstdNative]: 'zstd-stream',\n} as const satisfies Record<CompressionMethod, string>;\n\n/**\n * Default options used by the manager\n */\nexport const DefaultWebSocketManagerOptions = {\n\tasync buildIdentifyThrottler(manager: WebSocketManager) {\n\t\tconst info = await manager.fetchGatewayInformation();\n\t\treturn new SimpleIdentifyThrottler(info.session_start_limit.max_concurrency);\n\t},\n\tbuildStrategy: (manager) => new SimpleShardingStrategy(manager),\n\tshardCount: null,\n\tshardIds: null,\n\tlargeThreshold: null,\n\tinitialPresence: null,\n\tidentifyProperties: {\n\t\tbrowser: DefaultDeviceProperty,\n\t\tdevice: DefaultDeviceProperty,\n\t\tos: process.platform,\n\t},\n\tversion: APIVersion,\n\tencoding: Encoding.JSON,\n\tcompression: null,\n\tuseIdentifyCompression: false,\n\tretrieveSessionInfo(shardId) {\n\t\tconst store = getDefaultSessionStore();\n\t\treturn store.get(shardId) ?? null;\n\t},\n\tupdateSessionInfo(shardId: number, info: SessionInfo | null) {\n\t\tconst store = getDefaultSessionStore();\n\t\tif (info) {\n\t\t\tstore.set(shardId, info);\n\t\t} else {\n\t\t\tstore.delete(shardId);\n\t\t}\n\t},\n\thandshakeTimeout: 30_000,\n\thelloTimeout: 60_000,\n\treadyTimeout: 15_000,\n} as const satisfies Omit<OptionalWebSocketManagerOptions, 'fetchGatewayInformation' | 'token'>;\n\nexport const ImportantGatewayOpcodes = new Set([\n\tGatewayOpcodes.Heartbeat,\n\tGatewayOpcodes.Identify,\n\tGatewayOpcodes.Resume,\n]);\n\nexport function getInitialSendRateLimitState(): SendRateLimitState {\n\treturn {\n\t\tsent: 0,\n\t\tresetAt: Date.now() + 60_000,\n\t};\n}\n","import { Collection } from '@discordjs/collection';\nimport type { GatewaySendPayload } from 'discord-api-types/v10';\nimport type { WebSocketManager } from '../../ws/WebSocketManager.js';\nimport { WebSocketShard, WebSocketShardEvents, type WebSocketShardDestroyOptions } from '../../ws/WebSocketShard.js';\nimport { managerToFetchingStrategyOptions } from '../context/IContextFetchingStrategy.js';\nimport { SimpleContextFetchingStrategy } from '../context/SimpleContextFetchingStrategy.js';\nimport type { IShardingStrategy } from './IShardingStrategy.js';\n\n/**\n * Simple strategy that just spawns shards in the current process\n */\nexport class SimpleShardingStrategy implements IShardingStrategy {\n\tprivate readonly manager: WebSocketManager;\n\n\tprivate readonly shards = new Collection<number, WebSocketShard>();\n\n\tpublic constructor(manager: WebSocketManager) {\n\t\tthis.manager = manager;\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.spawn}\n\t */\n\tpublic async spawn(shardIds: number[]) {\n\t\tconst strategyOptions = await managerToFetchingStrategyOptions(this.manager);\n\n\t\tfor (const shardId of shardIds) {\n\t\t\tconst strategy = new SimpleContextFetchingStrategy(this.manager, strategyOptions);\n\t\t\tconst shard = new WebSocketShard(strategy, shardId);\n\n\t\t\tfor (const event of Object.values(WebSocketShardEvents)) {\n\t\t\t\t// @ts-expect-error Ugly casts are needed because when we try to collect all args, TS doesn't handle that nicely due to the strictness + lack of context\n\t\t\t\tshard.on(event, (...args) => this.manager.emit(event, ...args, shardId));\n\t\t\t}\n\n\t\t\tthis.shards.set(shardId, shard);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.connect}\n\t */\n\tpublic async connect() {\n\t\tconst promises = [];\n\n\t\tfor (const shard of this.shards.values()) {\n\t\t\tpromises.push(shard.connect());\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.destroy}\n\t */\n\tpublic async destroy(options?: Omit<WebSocketShardDestroyOptions, 'recover'>) {\n\t\tconst promises = [];\n\n\t\tfor (const shard of this.shards.values()) {\n\t\t\tpromises.push(shard.destroy(options));\n\t\t}\n\n\t\tawait Promise.all(promises);\n\t\tthis.shards.clear();\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.send}\n\t */\n\tpublic async send(shardId: number, payload: GatewaySendPayload) {\n\t\tconst shard = this.shards.get(shardId);\n\t\tif (!shard) {\n\t\t\tthrow new RangeError(`Shard ${shardId} not found`);\n\t\t}\n\n\t\treturn shard.send(payload);\n\t}\n\n\t/**\n\t * {@inheritDoc IShardingStrategy.fetchStatus}\n\t */\n\tpublic async fetchStatus() {\n\t\treturn this.shards.mapValues((shard) => shard.status);\n\t}\n}\n","import type { Awaitable } from '@discordjs/util';\nimport type { IIdentifyThrottler } from '../../throttling/IIdentifyThrottler.js';\nimport type { SessionInfo, WebSocketManager } from '../../ws/WebSocketManager.js';\nimport type { FetchingStrategyOptions, IContextFetchingStrategy } from './IContextFetchingStrategy.js';\n\nexport class SimpleContextFetchingStrategy implements IContextFetchingStrategy {\n\t// This strategy assumes every shard is running under the same process - therefore we need a single\n\t// IdentifyThrottler per manager.\n\tprivate static throttlerCache = new WeakMap<WebSocketManager, IIdentifyThrottler>();\n\n\tprivate static async ensureThrottler(manager: WebSocketManager): Promise<IIdentifyThrottler> {\n\t\tconst throttler = SimpleContextFetchingStrategy.throttlerCache.get(manager);\n\t\tif (throttler) {\n\t\t\treturn throttler;\n\t\t}\n\n\t\tconst newThrottler = await manager.options.buildIdentifyThrottler(manager);\n\t\tSimpleContextFetchingStrategy.throttlerCache.set(manager, newThrottler);\n\n\t\treturn newThrottler;\n\t}\n\n\tpublic constructor(\n\t\tprivate readonly manager: WebSocketManager,\n\t\tpublic readonly options: FetchingStrategyOptions,\n\t) {}\n\n\tpublic async retrieveSessionInfo(shardId: number): Promise<SessionInfo | null> {\n\t\treturn this.manager.options.retrieveSessionInfo(shardId);\n\t}\n\n\tpublic updateSessionInfo(shardId: number, sessionInfo: SessionInfo | null): Awaitable<void> {\n\t\treturn this.manager.options.updateSessionInfo(shardId, sessionInfo);\n\t}\n\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst throttler = await SimpleContextFetchingStrategy.ensureThrottler(this.manager);\n\t\tawait throttler.waitForIdentify(shardId, signal);\n\t}\n}\n","import { setTimeout as sleep } from 'node:timers/promises';\nimport { Collection } from '@discordjs/collection';\nimport { AsyncQueue } from '@sapphire/async-queue';\nimport type { IIdentifyThrottler } from './IIdentifyThrottler.js';\n\n/**\n * The state of a rate limit key's identify queue.\n */\nexport interface IdentifyState {\n\tqueue: AsyncQueue;\n\tresetsAt: number;\n}\n\n/**\n * Local, in-memory identify throttler.\n */\nexport class SimpleIdentifyThrottler implements IIdentifyThrottler {\n\tprivate readonly states = new Collection<number, IdentifyState>();\n\n\tpublic constructor(private readonly maxConcurrency: number) {}\n\n\t/**\n\t * {@inheritDoc IIdentifyThrottler.waitForIdentify}\n\t */\n\tpublic async waitForIdentify(shardId: number, signal: AbortSignal): Promise<void> {\n\t\tconst key = shardId % this.maxConcurrency;\n\n\t\tconst state = this.states.ensure(key, () => ({\n\t\t\tqueue: new AsyncQueue(),\n\t\t\tresetsAt: Number.POSITIVE_INFINITY,\n\t\t}));\n\n\t\tawait state.queue.wait({ signal });\n\n\t\ttry {\n\t\t\tconst diff = state.resetsAt - Date.now();\n\t\t\tif (diff > 0 && diff <= 5_000) {\n\t\t\t\t// To account for the latency the IDENTIFY payload goes through, we add a bit more wait time\n\t\t\t\tconst time = diff + Math.random() * 1_500;\n\t\t\t\tawait sleep(time);\n\t\t\t}\n\n\t\t\tstate.resetsAt = Date.now() + 5_000;\n\t\t} finally {\n\t\t\tstate.queue.shift();\n\t\t}\n\t}\n}\n","import { WorkerBootstrapper } from '../../utils/WorkerBootstrapper.js';\n\nconst bootstrapper = new WorkerBootstrapper();\nvoid bootstrapper.bootstrap();\n"],"mappings":"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","names":["isMainThread","parentPort","Collection","Collection","Collection","resolve","payload","Buffer","once","sleep","Collection","lazy","AsyncQueue","GatewayOpcodes","Collection","Collection","Collection","Collection","Collection","CompressionMethod","Collection","lazy","WebSocketShardEvents","WebSocketShardDestroyRecovery","AsyncQueue","Collection","once","resolve","sleep","GatewayOpcodes","Buffer","session","Collection","isMainThread","parentPort"]}
package/dist/index.d.mts CHANGED
@@ -201,12 +201,14 @@ declare enum Encoding {
201
201
  */
202
202
  declare enum CompressionMethod {
203
203
  ZlibNative = 0,
204
- ZlibSync = 1
204
+ ZlibSync = 1,
205
+ ZstdNative = 2
205
206
  }
206
207
  declare const DefaultDeviceProperty: `@discordjs/ws ${string}`;
207
208
  declare const CompressionParameterMap: {
208
209
  readonly 0: "zlib-stream";
209
210
  readonly 1: "zlib-stream";
211
+ readonly 2: "zstd-stream";
210
212
  };
211
213
  /**
212
214
  * Default options used by the manager
package/dist/index.d.ts CHANGED
@@ -201,12 +201,14 @@ declare enum Encoding {
201
201
  */
202
202
  declare enum CompressionMethod {
203
203
  ZlibNative = 0,
204
- ZlibSync = 1
204
+ ZlibSync = 1,
205
+ ZstdNative = 2
205
206
  }
206
207
  declare const DefaultDeviceProperty: `@discordjs/ws ${string}`;
207
208
  declare const CompressionParameterMap: {
208
209
  readonly 0: "zlib-stream";
209
210
  readonly 1: "zlib-stream";
211
+ readonly 2: "zstd-stream";
210
212
  };
211
213
  /**
212
214
  * Default options used by the manager
package/dist/index.js CHANGED
@@ -513,13 +513,15 @@ var Encoding = /* @__PURE__ */ ((Encoding2) => {
513
513
  var CompressionMethod = /* @__PURE__ */ ((CompressionMethod2) => {
514
514
  CompressionMethod2[CompressionMethod2["ZlibNative"] = 0] = "ZlibNative";
515
515
  CompressionMethod2[CompressionMethod2["ZlibSync"] = 1] = "ZlibSync";
516
+ CompressionMethod2[CompressionMethod2["ZstdNative"] = 2] = "ZstdNative";
516
517
  return CompressionMethod2;
517
518
  })(CompressionMethod || {});
518
- var DefaultDeviceProperty = `@discordjs/ws 3.0.0-pr-11006.1765452229-e636950b2`;
519
+ var DefaultDeviceProperty = `@discordjs/ws 3.0.0-pr-10758.1765463096-d081e1706`;
519
520
  var getDefaultSessionStore = (0, import_util.lazy)(() => new import_collection4.Collection());
520
521
  var CompressionParameterMap = {
521
522
  [0 /* ZlibNative */]: "zlib-stream",
522
- [1 /* ZlibSync */]: "zlib-stream"
523
+ [1 /* ZlibSync */]: "zlib-stream",
524
+ [2 /* ZstdNative */]: "zstd-stream"
523
525
  };
524
526
  var DefaultWebSocketManagerOptions = {
525
527
  async buildIdentifyThrottler(manager) {
@@ -696,7 +698,7 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
696
698
  });
697
699
  this.nativeInflate = inflate;
698
700
  } else {
699
- console.warn("WebSocketShard: Compression is set to native but node:zlib is not available.");
701
+ console.warn("WebSocketShard: Compression is set to native zlib but node:zlib is not available.");
700
702
  params.delete("compress");
701
703
  }
702
704
  break;
@@ -714,6 +716,28 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
714
716
  }
715
717
  break;
716
718
  }
719
+ case 2 /* ZstdNative */: {
720
+ const zlib = await getNativeZlib();
721
+ if (zlib && "createZstdDecompress" in zlib) {
722
+ this.inflateBuffer = [];
723
+ const inflate = zlib.createZstdDecompress({
724
+ chunkSize: 65535
725
+ });
726
+ inflate.on("data", (chunk) => {
727
+ this.inflateBuffer.push(chunk);
728
+ });
729
+ inflate.on("error", (error) => {
730
+ this.emit("error" /* Error */, error);
731
+ });
732
+ this.nativeInflate = inflate;
733
+ } else {
734
+ console.warn(
735
+ "WebSocketShard: Compression is set to native zstd but node:zlib is not available or your node version does not support zstd decompression."
736
+ );
737
+ params.delete("compress");
738
+ }
739
+ break;
740
+ }
717
741
  }
718
742
  }
719
743
  if (this.identifyCompressionEnabled) {
@@ -996,7 +1020,7 @@ var WebSocketShard = class extends import_async_event_emitter.AsyncEventEmitter
996
1020
  });
997
1021
  }
998
1022
  if (this.transportCompressionEnabled) {
999
- const flush = decompressable.length >= 4 && decompressable.at(-4) === 0 && decompressable.at(-3) === 0 && decompressable.at(-2) === 255 && decompressable.at(-1) === 255;
1023
+ const flush = this.strategy.options.compression === 2 /* ZstdNative */ || decompressable.length >= 4 && decompressable.at(-4) === 0 && decompressable.at(-3) === 0 && decompressable.at(-2) === 255 && decompressable.at(-1) === 255;
1000
1024
  if (this.nativeInflate) {
1001
1025
  const doneWriting = new Promise((resolve2) => {
1002
1026
  this.nativeInflate.write(decompressable, "binary", (error) => {
@@ -1484,7 +1508,6 @@ var WebSocketManager = class extends import_async_event_emitter2.AsyncEventEmitt
1484
1508
  if (typeof options.fetchGatewayInformation !== "function") {
1485
1509
  throw new TypeError("fetchGatewayInformation is required");
1486
1510
  }
1487
- console.log("woah. new. NEW! NEW!!!!!!! \u203C\uFE0F \u{1F5E3}\uFE0F \u{1F525}");
1488
1511
  super();
1489
1512
  this.options = {
1490
1513
  ...DefaultWebSocketManagerOptions,
@@ -1587,7 +1610,7 @@ var WebSocketManager = class extends import_async_event_emitter2.AsyncEventEmitt
1587
1610
  };
1588
1611
 
1589
1612
  // src/index.ts
1590
- var version = "3.0.0-pr-11006.1765452229-e636950b2";
1613
+ var version = "3.0.0-pr-10758.1765463096-d081e1706";
1591
1614
  // Annotate the CommonJS export names for ESM import in node:
1592
1615
  0 && (module.exports = {
1593
1616
  CloseCodes,