@discordeno/gateway 19.0.0-next.e19eca5 → 19.0.0-next.e2d86ea
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Shard.d.ts.map +1 -1
- package/dist/Shard.js +16 -0
- package/dist/Shard.js.map +1 -1
- package/package.json +3 -3
package/dist/Shard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Shard.d.ts","sourceRoot":"","sources":["../src/Shard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,QAAQ,EACR,qBAAqB,EAErB,aAAa,EAEb,mBAAmB,EACpB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAA2B,MAAM,mBAAmB,CAAA;AAEpF,OAAO,SAAS,MAAM,IAAI,CAAA;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAClJ,OAAO,EAAyB,UAAU,EAAE,MAAM,YAAY,CAAA;AAE9D,qBAAa,eAAe;IAC1B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,qFAAqF;IACrF,UAAU,EAAE,kBAAkB,CAAA;IAC9B,kDAAkD;IAClD,KAAK,EAAE,UAAU,CAAA;IACjB,4HAA4H;IAC5H,2BAA2B,EAAE,MAAM,CAAM;IACzC,4CAA4C;IAC5C,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAO;IAC5C,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAQ;IACtC,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,0CAA0C;IAC1C,KAAK,aAAqB;IAC1B,mFAAmF;IACnF,gBAAgB,EAAE,MAAM,CAAK;IAC7B,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAK;IACxB,qGAAqG;IACrG,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,CAAK;IACnD,mFAAmF;IACnF,QAAQ,yDAA8D,qBAAqB,KAAK,IAAI,EAAG;IACvG,oHAAoH;IACpH,MAAM,EAAE,WAAW,CAAA;IAEnB,4CAA4C;IAC5C,KAAK;;YAED;;;eAGG;;YAEH,4BAA4B;;;MAG/B;gBAEW,OAAO,EAAE,kBAAkB;IAoBvC,qEAAqE;IACrE,IAAI,aAAa,IAAI,kBAAkB,CAEtC;IAED,4IAA4I;IAC5I,IAAI,aAAa,IAAI,MAAM,CAG1B;IAED,6JAA6J;IAC7J,qBAAqB,IAAI,MAAM;IAOzB,YAAY,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxD,yDAAyD;IACzD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAMzC,kHAAkH;IAC5G,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;IAkCzC,4GAA4G;IACtG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD/B,iEAAiE;IACjE,MAAM,IAAI,OAAO;IAIjB,sEAAsE;IAChE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"Shard.d.ts","sourceRoot":"","sources":["../src/Shard.ts"],"names":[],"mappings":"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"}
|
package/dist/Shard.js
CHANGED
|
@@ -152,6 +152,7 @@ export class DiscordenoShard {
|
|
|
152
152
|
// It has been requested to resume the Shards session.
|
|
153
153
|
// It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.
|
|
154
154
|
if (this.isOpen()) {
|
|
155
|
+
logger.debug(`[Gateway] Resuming Shard #${this.id} in isOpen`);
|
|
155
156
|
this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.');
|
|
156
157
|
}
|
|
157
158
|
// Shard has never identified, so we cannot resume.
|
|
@@ -160,8 +161,11 @@ export class DiscordenoShard {
|
|
|
160
161
|
return await this.identify();
|
|
161
162
|
}
|
|
162
163
|
this.state = ShardState.Resuming;
|
|
164
|
+
logger.debug(`[Gateway] Resuming Shard #${this.id}, before connecting`);
|
|
163
165
|
// Before we can resume, we need to create a new connection with Discord's gateway.
|
|
164
166
|
await this.connect();
|
|
167
|
+
logger.debug(// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
168
|
+
`[Gateway] Resuming Shard #${this.id}, after connecting. ${this.gatewayConfig.token} | ${this.sessionId} | ${this.previousSequenceNumber}`);
|
|
165
169
|
this.send({
|
|
166
170
|
op: GatewayOpcodes.Resume,
|
|
167
171
|
d: {
|
|
@@ -170,6 +174,7 @@ export class DiscordenoShard {
|
|
|
170
174
|
seq: this.previousSequenceNumber ?? 0
|
|
171
175
|
}
|
|
172
176
|
}, true);
|
|
177
|
+
logger.debug(`[Gateway] Resuming Shard #${this.id} after send resumg`);
|
|
173
178
|
return await new Promise((resolve)=>{
|
|
174
179
|
this.resolves.set('RESUMED', ()=>resolve());
|
|
175
180
|
// If it is attempted to resume with an invalid session id,
|
|
@@ -249,6 +254,7 @@ export class DiscordenoShard {
|
|
|
249
254
|
case GatewayCloseEventCodes.AlreadyAuthenticated:
|
|
250
255
|
default:
|
|
251
256
|
{
|
|
257
|
+
logger.info(`[Shard] closed shard #${this.id}. Resuming...`);
|
|
252
258
|
this.state = ShardState.Resuming;
|
|
253
259
|
this.events.disconnected?.(this);
|
|
254
260
|
return await this.resume();
|
|
@@ -282,6 +288,7 @@ export class DiscordenoShard {
|
|
|
282
288
|
case GatewayOpcodes.Hello:
|
|
283
289
|
{
|
|
284
290
|
const interval = packet.d.heartbeat_interval;
|
|
291
|
+
logger.debug(`[Gateway] Hello on Shard #${this.id}`);
|
|
285
292
|
this.startHeartbeating(interval);
|
|
286
293
|
if (this.state !== ShardState.Resuming) {
|
|
287
294
|
const currentQueue = [
|
|
@@ -388,6 +395,7 @@ export class DiscordenoShard {
|
|
|
388
395
|
/** This function communicates with the management process, in order to know whether its free to identify. When this function resolves, this means that the shard is allowed to send an identify payload to discord. */ async requestIdentify() {}
|
|
389
396
|
/** This function communicates with the management process, in order to tell it can identify the next shard. */ async shardIsReady() {}
|
|
390
397
|
/** Start sending heartbeat payloads to Discord in the provided interval. */ startHeartbeating(interval) {
|
|
398
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id}`);
|
|
391
399
|
// If old heartbeast exist like after resume, clear the old ones.
|
|
392
400
|
if (this.heart.intervalId) clearInterval(this.heart.intervalId);
|
|
393
401
|
if (this.heart.timeoutId) clearTimeout(this.heart.timeoutId);
|
|
@@ -398,6 +406,7 @@ export class DiscordenoShard {
|
|
|
398
406
|
ShardState.Disconnected,
|
|
399
407
|
ShardState.Offline
|
|
400
408
|
].includes(this.state)) {
|
|
409
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} a`);
|
|
401
410
|
this.state = ShardState.Unidentified;
|
|
402
411
|
}
|
|
403
412
|
// The first heartbeat needs to be send with a random delay between `0` and `interval`
|
|
@@ -406,17 +415,22 @@ export class DiscordenoShard {
|
|
|
406
415
|
// Reference: https://discord.com/developers/docs/topics/gateway#heartbeating
|
|
407
416
|
const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5));
|
|
408
417
|
this.heart.timeoutId = setTimeout(()=>{
|
|
418
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} b`);
|
|
409
419
|
if (!this.isOpen()) return;
|
|
420
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} c ${this.previousSequenceNumber}`);
|
|
410
421
|
// Using a direct socket.send call here because heartbeat requests are reserved by us.
|
|
411
422
|
this.socket?.send(JSON.stringify({
|
|
412
423
|
op: GatewayOpcodes.Heartbeat,
|
|
413
424
|
d: this.previousSequenceNumber
|
|
414
425
|
}));
|
|
426
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} d`);
|
|
415
427
|
this.heart.lastBeat = Date.now();
|
|
416
428
|
this.heart.acknowledged = false;
|
|
417
429
|
// After the random heartbeat jitter we can start a normal interval.
|
|
418
430
|
this.heart.intervalId = setInterval(async ()=>{
|
|
431
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} e`);
|
|
419
432
|
if (!this.isOpen()) return;
|
|
433
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} f`);
|
|
420
434
|
// gateway.debug("GW DEBUG", `Running setInterval in heartbeat file. Shard: ${shardId}`);
|
|
421
435
|
// gateway.debug("GW HEARTBEATING", { shardId, shard: currentShard });
|
|
422
436
|
// The Shard did not receive a heartbeat ACK from Discord in time,
|
|
@@ -429,11 +443,13 @@ export class DiscordenoShard {
|
|
|
429
443
|
return await this.identify();
|
|
430
444
|
}
|
|
431
445
|
this.heart.acknowledged = false;
|
|
446
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} g`);
|
|
432
447
|
// Using a direct socket.send call here because heartbeat requests are reserved by us.
|
|
433
448
|
this.socket?.send(JSON.stringify({
|
|
434
449
|
op: GatewayOpcodes.Heartbeat,
|
|
435
450
|
d: this.previousSequenceNumber
|
|
436
451
|
}));
|
|
452
|
+
logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} h`);
|
|
437
453
|
this.heart.lastBeat = Date.now();
|
|
438
454
|
this.events.heartbeat?.(this);
|
|
439
455
|
}, this.heart.interval);
|
package/dist/Shard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Shard.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-confusing-void-expression */\nimport type {\n AtLeastOne,\n BigString,\n Camelize,\n DiscordGatewayPayload,\n DiscordHello,\n DiscordMember,\n DiscordReady,\n RequestGuildMembers,\n} from '@discordeno/types'\nimport { GatewayCloseEventCodes, GatewayIntents, GatewayOpcodes } from '@discordeno/types'\nimport { Collection, LeakyBucket, camelize, delay, logger } from '@discordeno/utils'\nimport { inflateSync } from 'node:zlib'\nimport WebSocket from 'ws'\nimport type { RequestMemberRequest } from './manager.js'\nimport type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js'\nimport { ShardSocketCloseCodes, ShardState } from './types.js'\n\nexport class DiscordenoShard {\n /** The id of the shard */\n id: number\n /** The connection config details that this shard will used to connect to discord. */\n connection: ShardGatewayConfig\n /** This contains all the heartbeat information */\n heart: ShardHeart\n /** The maximum of requests which can be send to discord per rate limit tick. Typically this value should not be changed. */\n maxRequestsPerRateLimitTick: number = 120\n /** The previous payload sequence number. */\n previousSequenceNumber: number | null = null\n /** In which interval (in milliseconds) the gateway resets it's rate limit. */\n rateLimitResetInterval: number = 60000\n /** Current session id of the shard if present. */\n sessionId?: string\n /** This contains the WebSocket connection to Discord, if currently connected. */\n socket?: WebSocket\n /** Current internal state of the this. */\n state = ShardState.Offline\n /** The url provided by discord to use when resuming a connection for this this. */\n resumeGatewayUrl: string = ''\n /** The shard related event handlers. */\n events: ShardEvents = {}\n /** Cache for pending gateway requests which should have been send while the gateway went offline. */\n offlineSendQueue: Array<(_?: unknown) => void> = []\n /** Resolve internal waiting states. Mapped by SelectedEvents => ResolveFunction */\n resolves = new Map<'READY' | 'RESUMED' | 'INVALID_SESSION', (payload: DiscordGatewayPayload) => void>()\n /** Shard bucket. Only access this if you know what you are doing. Bucket for handling shard request rate limits. */\n bucket: LeakyBucket\n\n /** This managers cache related settings. */\n cache = {\n requestMembers: {\n /**\n * Whether or not request member requests should be cached.\n * @default false\n */\n enabled: false,\n /** The pending requests. */\n pending: new Collection<string, RequestMemberRequest>(),\n },\n }\n\n constructor(options: ShardCreateOptions) {\n this.id = options.id\n this.connection = options.connection\n this.events = options.events\n\n this.heart = {\n acknowledged: false,\n interval: 45000,\n }\n\n if (options.requestIdentify) this.requestIdentify = options.requestIdentify\n if (options.shardIsReady) this.shardIsReady = options.shardIsReady\n\n this.bucket = new LeakyBucket({\n max: this.calculateSafeRequests(),\n refillAmount: this.calculateSafeRequests(),\n refillInterval: 60000,\n })\n }\n\n /** The gateway configuration which is used to connect to Discord. */\n get gatewayConfig(): ShardGatewayConfig {\n return this.connection\n }\n\n /** The url to connect to. Intially this is the discord gateway url, and then is switched to resume gateway url once a READY is received. */\n get connectionUrl(): string {\n // Use || and not ?? here. ?? will cause a bug.\n return this.resumeGatewayUrl || this.gatewayConfig.url\n }\n\n /** Calculate the amount of requests which can safely be made per rate limit interval, before the gateway gets disconnected due to an exceeded rate limit. */\n calculateSafeRequests(): number {\n // * 2 adds extra safety layer for discords OP 1 requests that we need to respond to\n const safeRequests = this.maxRequestsPerRateLimitTick - Math.ceil(this.rateLimitResetInterval / this.heart.interval) * 2\n\n return safeRequests < 0 ? 0 : safeRequests\n }\n\n async checkOffline(highPriority: boolean): Promise<void> {\n if (!this.isOpen()) {\n await new Promise((resolve) => {\n // Higher priority requests get added at the beginning of the array.\n if (highPriority) this.offlineSendQueue.unshift(resolve)\n else this.offlineSendQueue.push(resolve)\n })\n }\n }\n\n /** Close the socket connection to discord if present. */\n close(code: number, reason: string): void {\n if (this.socket?.readyState !== WebSocket.OPEN) return\n\n this.socket?.close(code, reason)\n }\n\n /** Connect the shard with the gateway and start heartbeating. This will not identify the shard to the gateway. */\n async connect(): Promise<DiscordenoShard> {\n // Only set the shard to `Connecting` state,\n // if the connection request does not come from an identify or resume action.\n if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) {\n this.state = ShardState.Connecting\n }\n this.events.connecting?.(this)\n\n const url = new URL(this.connectionUrl)\n url.searchParams.set('v', this.gatewayConfig.version.toString())\n url.searchParams.set('encoding', 'json')\n\n const socket = new WebSocket(url.toString())\n this.socket = socket\n\n // TODO: proper event handling\n socket.onerror = (event) => console.log({ error: event, shardId: this.id })\n socket.onclose = async (event) => await this.handleClose(event)\n socket.onmessage = async (message) => await this.handleMessage(message)\n\n return await new Promise((resolve) => {\n socket.onopen = () => {\n // Only set the shard to `Unidentified` state,\n // if the connection request does not come from an identify or resume action.\n if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) {\n this.state = ShardState.Unidentified\n }\n this.events.connected?.(this)\n\n resolve(this)\n }\n })\n }\n\n /** Identify the shard to the gateway. If not connected, this will also connect the shard to the gateway. */\n async identify(): Promise<void> {\n // A new identify has been requested even though there is already a connection open.\n // Therefore we need to close the old connection and heartbeating before creating a new one.\n if (this.isOpen()) {\n logger.debug(`CLOSING EXISTING SHARD: #${this.id}`)\n this.close(ShardSocketCloseCodes.ReIdentifying, 'Re-identifying closure of old connection.')\n }\n\n this.state = ShardState.Identifying\n this.events.identifying?.(this)\n\n // It is possible that the shard is in Heartbeating state but not identified,\n // so check whether there is already a gateway connection existing.\n // If not we need to create one before we identify.\n if (!this.isOpen()) {\n await this.connect()\n }\n\n this.send(\n {\n op: GatewayOpcodes.Identify,\n d: {\n token: `Bot ${this.gatewayConfig.token}`,\n compress: this.gatewayConfig.compress,\n properties: this.gatewayConfig.properties,\n intents: this.gatewayConfig.intents,\n shard: [this.id, this.gatewayConfig.totalShards],\n presence: await this.makePresence?.(),\n },\n },\n true,\n )\n\n return await new Promise((resolve) => {\n this.resolves.set('READY', () => {\n this.events.identified?.(this)\n // Tells the manager that this shard is ready\n this.shardIsReady()\n resolve()\n })\n // When identifying too fast,\n // Discord sends an invalid session payload.\n // This can safely be ignored though and the shard starts a new identify action.\n this.resolves.set('INVALID_SESSION', () => {\n this.resolves.delete('READY')\n resolve()\n })\n })\n }\n\n /** Check whether the connection to Discord is currently open. */\n isOpen(): boolean {\n return this.socket?.readyState === WebSocket.OPEN\n }\n\n /** Attempt to resume the previous shards session with the gateway. */\n async resume(): Promise<void> {\n logger.debug(`[Gateway] Resuming Shard #${this.id}`)\n // It has been requested to resume the Shards session.\n // It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.\n if (this.isOpen()) {\n this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.')\n }\n\n // Shard has never identified, so we cannot resume.\n if (!this.sessionId) {\n logger.debug(`[Shard] Trying to resume a shard #${this.id} that was NOT first identified. (No session id found)`)\n\n return await this.identify()\n }\n\n this.state = ShardState.Resuming\n\n // Before we can resume, we need to create a new connection with Discord's gateway.\n await this.connect()\n\n this.send(\n {\n op: GatewayOpcodes.Resume,\n d: {\n token: `Bot ${this.gatewayConfig.token}`,\n session_id: this.sessionId,\n seq: this.previousSequenceNumber ?? 0,\n },\n },\n true,\n )\n\n return await new Promise((resolve) => {\n this.resolves.set('RESUMED', () => resolve())\n // If it is attempted to resume with an invalid session id,\n // Discord sends an invalid session payload\n // Not erroring here since it is easy that this happens, also it would be not catchable\n this.resolves.set('INVALID_SESSION', () => {\n this.resolves.delete('RESUMED')\n resolve()\n })\n })\n }\n\n /** Send a message to Discord.\n * @param {boolean} [highPriority=false] - Whether this message should be send asap.\n */\n async send(message: ShardSocketRequest, highPriority = false): Promise<void> {\n // Before acquiring a token from the bucket, check whether the shard is currently offline or not.\n // Else bucket and token wait time just get wasted.\n await this.checkOffline(highPriority)\n\n await this.bucket.acquire(highPriority)\n\n // It's possible, that the shard went offline after a token has been acquired from the bucket.\n await this.checkOffline(highPriority)\n\n this.socket?.send(JSON.stringify(message))\n }\n\n /** Shutdown the this. Forcefully disconnect the shard from Discord. The shard may not attempt to reconnect with Discord. */\n async shutdown(): Promise<void> {\n this.close(ShardSocketCloseCodes.Shutdown, 'Shard shutting down.')\n this.state = ShardState.Offline\n }\n\n /** Handle a gateway connection close. */\n async handleClose(close: WebSocket.CloseEvent): Promise<void> {\n // gateway.debug(\"GW CLOSED\", { shardId, payload: event });\n\n this.stopHeartbeating()\n\n switch (close.code) {\n case ShardSocketCloseCodes.TestingFinished: {\n this.state = ShardState.Offline\n this.events.disconnected?.(this)\n\n return\n }\n // On these codes a manual start will be done.\n case ShardSocketCloseCodes.Shutdown:\n case ShardSocketCloseCodes.ReIdentifying:\n case ShardSocketCloseCodes.Resharded:\n case ShardSocketCloseCodes.ResumeClosingOldConnection:\n case ShardSocketCloseCodes.ZombiedConnection: {\n this.state = ShardState.Disconnected\n this.events.disconnected?.(this)\n\n // gateway.debug(\"GW CLOSED_RECONNECT\", { shardId, payload: event });\n return\n }\n // Gateway connection closes which require a new identify.\n case GatewayCloseEventCodes.UnknownOpcode:\n case GatewayCloseEventCodes.NotAuthenticated:\n case GatewayCloseEventCodes.InvalidSeq:\n case GatewayCloseEventCodes.RateLimited:\n case GatewayCloseEventCodes.SessionTimedOut: {\n logger.debug(`[Shard] Gateway connection closing requiring re-identify. Code: ${close.code}`)\n this.state = ShardState.Identifying\n this.events.disconnected?.(this)\n\n return await this.identify()\n }\n // When these codes are received something went really wrong.\n // On those we cannot start a reconnect attempt.\n case GatewayCloseEventCodes.AuthenticationFailed:\n case GatewayCloseEventCodes.InvalidShard:\n case GatewayCloseEventCodes.ShardingRequired:\n case GatewayCloseEventCodes.InvalidApiVersion:\n case GatewayCloseEventCodes.InvalidIntents:\n case GatewayCloseEventCodes.DisallowedIntents: {\n this.state = ShardState.Offline\n this.events.disconnected?.(this)\n\n throw new Error(close.reason || 'Discord gave no reason! GG! You broke Discord!')\n }\n // Gateway connection closes on which a resume is allowed.\n case GatewayCloseEventCodes.UnknownError:\n case GatewayCloseEventCodes.DecodeError:\n case GatewayCloseEventCodes.AlreadyAuthenticated:\n default: {\n this.state = ShardState.Resuming\n this.events.disconnected?.(this)\n\n return await this.resume()\n }\n }\n }\n\n /** Handles a incoming gateway packet. */\n async handleDiscordPacket(packet: DiscordGatewayPayload): Promise<void> {\n // Edge case start: https://github.com/discordeno/discordeno/issues/2311\n this.heart.lastAck = Date.now()\n // Manually calculating the round trip time for users who need it.\n if (this.heart.lastBeat && !this.heart.acknowledged) {\n this.heart.rtt = this.heart.lastAck - this.heart.lastBeat\n }\n this.heart.acknowledged = true\n // Edge case end!\n\n switch (packet.op) {\n case GatewayOpcodes.Heartbeat: {\n // TODO: can this actually happen\n if (!this.isOpen()) return\n\n this.heart.lastBeat = Date.now()\n // Discord randomly sends this requiring an immediate heartbeat back.\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n this.events.heartbeat?.(this)\n\n break\n }\n case GatewayOpcodes.Hello: {\n const interval = (packet.d as DiscordHello).heartbeat_interval\n\n this.startHeartbeating(interval)\n\n if (this.state !== ShardState.Resuming) {\n const currentQueue = [...this.bucket.queue]\n // HELLO has been send on a non resume action.\n // This means that the shard starts a new session,\n // therefore the rate limit interval has been reset too.\n this.bucket = new LeakyBucket({\n max: this.calculateSafeRequests(),\n refillInterval: 60000,\n refillAmount: this.calculateSafeRequests(),\n })\n\n // Queue should not be lost on a re-identify.\n this.bucket.queue.unshift(...currentQueue)\n }\n\n this.events.hello?.(this)\n\n break\n }\n case GatewayOpcodes.HeartbeatACK: {\n this.events.heartbeatAck?.(this)\n\n break\n }\n case GatewayOpcodes.Reconnect: {\n // gateway.debug(\"GW RECONNECT\", { shardId });\n\n this.events.requestedReconnect?.(this)\n\n await this.resume()\n\n break\n }\n case GatewayOpcodes.InvalidSession: {\n const resumable = packet.d as boolean\n logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with resumeable as ${resumable.toString()}`)\n\n this.events.invalidSession?.(this, resumable)\n\n // We need to wait for a random amount of time between 1 and 5\n // Reference: https://discord.com/developers/docs/topics/gateway#resuming\n await delay(Math.floor((Math.random() * 4 + 1) * 1000))\n\n this.resolves.get('INVALID_SESSION')?.(packet)\n this.resolves.delete('INVALID_SESSION')\n\n // When resumable is false we need to re-identify\n if (!resumable) {\n await this.requestIdentify()\n\n break\n }\n\n // The session is invalid but apparently it is resumable\n await this.resume()\n\n break\n }\n }\n\n if (packet.t === 'RESUMED') {\n // gateway.debug(\"GW RESUMED\", { shardId });\n\n this.state = ShardState.Connected\n this.events.resumed?.(this)\n\n // Continue the requests which have been queued since the shard went offline.\n this.offlineSendQueue.map((resolve) => resolve())\n\n this.resolves.get('RESUMED')?.(packet)\n this.resolves.delete('RESUMED')\n } else if (packet.t === 'READY') {\n // Important for future resumes.\n\n const payload = packet.d as DiscordReady\n\n this.resumeGatewayUrl = payload.resume_gateway_url\n\n this.sessionId = payload.session_id\n this.state = ShardState.Connected\n\n // Continue the requests which have been queued since the shard went offline.\n // Important when this is a re-identify\n this.offlineSendQueue.map((resolve) => resolve())\n\n this.resolves.get('READY')?.(packet)\n this.resolves.delete('READY')\n }\n\n // Update the sequence number if it is present\n // `s` can be either `null` or a `number`.\n // In order to prevent update misses when `s` is `0` we check against null.\n if (packet.s !== null) {\n this.previousSequenceNumber = packet.s\n }\n\n this.forwardToBot(packet)\n }\n\n forwardToBot(packet: DiscordGatewayPayload): void {\n // The necessary handling required for the Shards connection has been finished.\n // Now the event can be safely forwarded.\n this.events.message?.(this, camelize(packet))\n }\n\n /** Handle an incoming gateway message. */\n async handleMessage(message: WebSocket.MessageEvent): Promise<void> {\n let preProcessMessage = message.data\n\n // If message compression is enabled,\n // Discord might send zlib compressed payloads.\n if (this.gatewayConfig.compress && preProcessMessage instanceof Blob) {\n preProcessMessage = inflateSync(await preProcessMessage.arrayBuffer()).toString()\n }\n\n // Safeguard incase decompression failed to make a string.\n if (typeof preProcessMessage !== 'string') return\n\n return await this.handleDiscordPacket(JSON.parse(preProcessMessage) as DiscordGatewayPayload)\n }\n\n /**\n * Override in order to make the shards presence.\n * async in case devs create the presence based on eg. database values.\n * Passing the shard's id there to make it easier for the dev to use this function.\n */\n async makePresence(): Promise<BotStatusUpdate | undefined> {\n // eslint-disable-next-line no-useless-return\n return\n }\n\n /** This function communicates with the management process, in order to know whether its free to identify. When this function resolves, this means that the shard is allowed to send an identify payload to discord. */\n async requestIdentify(): Promise<void> {}\n\n /** This function communicates with the management process, in order to tell it can identify the next shard. */\n async shardIsReady(): Promise<void> {}\n\n /** Start sending heartbeat payloads to Discord in the provided interval. */\n startHeartbeating(interval: number): void {\n // If old heartbeast exist like after resume, clear the old ones.\n if (this.heart.intervalId) clearInterval(this.heart.intervalId)\n if (this.heart.timeoutId) clearTimeout(this.heart.timeoutId)\n\n this.heart.interval = interval\n\n // Only set the shard's state to `Unidentified`\n // if heartbeating has not been started due to an identify or resume action.\n if ([ShardState.Disconnected, ShardState.Offline].includes(this.state)) {\n this.state = ShardState.Unidentified\n }\n\n // The first heartbeat needs to be send with a random delay between `0` and `interval`\n // Using a `setTimeout(_, jitter)` here to accomplish that.\n // `Math.random()` can be `0` so we use `0.5` if this happens\n // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating\n const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5))\n this.heart.timeoutId = setTimeout(() => {\n if (!this.isOpen()) return\n\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n\n this.heart.lastBeat = Date.now()\n this.heart.acknowledged = false\n\n // After the random heartbeat jitter we can start a normal interval.\n this.heart.intervalId = setInterval(async () => {\n if (!this.isOpen()) return\n // gateway.debug(\"GW DEBUG\", `Running setInterval in heartbeat file. Shard: ${shardId}`);\n\n // gateway.debug(\"GW HEARTBEATING\", { shardId, shard: currentShard });\n\n // The Shard did not receive a heartbeat ACK from Discord in time,\n // therefore we have to assume that the connection has failed or got \"zombied\".\n // The Shard needs to start a re-identify action accordingly.\n // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack\n if (!this.heart.acknowledged) {\n logger.debug(`[Shard] Heartbeat not acknowledged for shard #${this.id}.`)\n this.close(ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection, did not receive an heartbeat ACK in time.')\n\n return await this.identify()\n }\n\n this.heart.acknowledged = false\n\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n\n this.heart.lastBeat = Date.now()\n\n this.events.heartbeat?.(this)\n }, this.heart.interval)\n }, jitter)\n }\n\n /** Stop the heartbeating process with discord. */\n stopHeartbeating(): void {\n // Clear the regular heartbeat interval.\n clearInterval(this.heart.intervalId)\n // It's possible that the Shard got closed before the first jittered heartbeat.\n // To go safe we should clear the related timeout too.\n clearTimeout(this.heart.timeoutId)\n }\n\n /**\n * Connects the bot user to a voice or stage channel.\n *\n * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.\n *\n * @param guildId - The ID of the guild the voice channel to leave is in.\n * @param channelId - The ID of the channel you want to join.\n *\n * @remarks\n * Requires the `CONNECT` permission.\n *\n * Fires a _Voice State Update_ gateway event.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}\n */\n async joinVoiceChannel(\n guildId: BigString,\n channelId: BigString,\n options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>,\n ): Promise<void> {\n logger.debug(`[Shard] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`)\n await this.send({\n op: GatewayOpcodes.VoiceStateUpdate,\n d: {\n guild_id: guildId.toString(),\n channel_id: channelId.toString(),\n self_mute: Boolean(options?.selfMute),\n self_deaf: options?.selfDeaf ?? true,\n },\n })\n }\n\n /**\n * Edits the bot status in all shards that this gateway manages.\n *\n * @param data The status data to set the bots status to.\n * @returns Promise<void>\n */\n async editBotStatus(data: StatusUpdate): Promise<void> {\n logger.debug(`[Shard] editBotStatus data: ${JSON.stringify(data)}`)\n await this.editShardStatus(data)\n }\n\n /**\n * Edits the bot's status on one shard.\n *\n * @param shardId The shard id to edit the status for.\n * @param data The status data to set the bots status to.\n * @returns Promise<void>\n */\n async editShardStatus(data: StatusUpdate): Promise<void> {\n logger.debug(`[Shard] editShardStatus shardId: ${this.id} -> data: ${JSON.stringify(data)}`)\n await this.send({\n op: GatewayOpcodes.PresenceUpdate,\n d: {\n since: null,\n afk: false,\n activities: data.activities,\n status: data.status,\n },\n })\n }\n\n /**\n * Fetches the list of members for a guild over the gateway.\n *\n * @param guildId - The ID of the guild to get the list of members for.\n * @param options - The parameters for the fetching of the members.\n *\n * @remarks\n * If requesting the entire member list:\n * - Requires the `GUILD_MEMBERS` intent.\n *\n * If requesting presences ({@link RequestGuildMembers.presences | presences} set to `true`):\n * - Requires the `GUILD_PRESENCES` intent.\n *\n * If requesting a prefix ({@link RequestGuildMembers.query | query} non-`undefined`):\n * - Returns a maximum of 100 members.\n *\n * If requesting a users by ID ({@link RequestGuildMembers.userIds | userIds} non-`undefined`):\n * - Returns a maximum of 100 members.\n *\n * Fires a _Guild Members Chunk_ gateway event for every 1000 members fetched.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members}\n */\n async requestMembers(guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>): Promise<Camelize<DiscordMember[]>> {\n // You can request 1 member without the intent\n // Check if intents is not 0 as proxy ws won't set intents in other instances\n if (this.connection.intents && (!options?.limit || options.limit > 1) && !(this.connection.intents & GatewayIntents.GuildMembers)) {\n throw new Error('MISSING_INTENT_GUILD_MEMBERS')\n }\n\n if (options?.userIds?.length) {\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`)\n options.limit = options.userIds.length\n }\n\n const nonce = `${guildId}-${Date.now()}`\n\n // Gateway does not require caching these requests so directly send and return\n if (!this.cache.requestMembers?.enabled) {\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> skipping cache -> options ${JSON.stringify(options)}`)\n await this.send({\n op: GatewayOpcodes.RequestGuildMembers,\n d: {\n guild_id: guildId.toString(),\n // If a query is provided use it, OR if a limit is NOT provided use \"\"\n query: options?.query ?? (options?.limit ? undefined : ''),\n limit: options?.limit ?? 0,\n presences: options?.presences ?? false,\n user_ids: options?.userIds?.map((id) => id.toString()),\n nonce,\n },\n })\n return []\n }\n\n return await new Promise((resolve) => {\n this.cache.requestMembers?.pending.set(nonce, { nonce, resolve, members: [] })\n\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> requesting members -> data: ${JSON.stringify(options)}`)\n this.send({\n op: GatewayOpcodes.RequestGuildMembers,\n d: {\n guild_id: guildId.toString(),\n // If a query is provided use it, OR if a limit is NOT provided use \"\"\n query: options?.query ?? (options?.limit ? undefined : ''),\n limit: options?.limit ?? 0,\n presences: options?.presences ?? false,\n user_ids: options?.userIds?.map((id) => id.toString()),\n nonce,\n },\n })\n })\n }\n\n /**\n * Leaves the voice channel the bot user is currently in.\n *\n * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.\n *\n * @param guildId - The ID of the guild the voice channel to leave is in.\n *\n * @remarks\n * Fires a _Voice State Update_ gateway event.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}\n */\n async leaveVoiceChannel(guildId: BigString): Promise<void> {\n logger.debug(`[Shard] leaveVoiceChannel guildId: ${guildId} Shard ${this.id}`)\n await this.send({\n op: GatewayOpcodes.VoiceStateUpdate,\n d: {\n guild_id: guildId.toString(),\n channel_id: null,\n self_mute: false,\n self_deaf: false,\n },\n })\n }\n}\n\nexport interface ShardCreateOptions {\n /** The shard id */\n id: number\n /** The connection details */\n connection: ShardGatewayConfig\n /** The event handlers for events on the shard. */\n events: ShardEvents\n /** The handler to request a space to make an identify request. */\n requestIdentify?: () => Promise<void>\n /** The handler to alert the gateway manager that this shard has received a READY event. */\n shardIsReady?: () => Promise<void>\n}\n\nexport default DiscordenoShard\n"],"names":["GatewayCloseEventCodes","GatewayIntents","GatewayOpcodes","Collection","LeakyBucket","camelize","delay","logger","inflateSync","WebSocket","ShardSocketCloseCodes","ShardState","DiscordenoShard","constructor","options","maxRequestsPerRateLimitTick","previousSequenceNumber","rateLimitResetInterval","state","Offline","resumeGatewayUrl","events","offlineSendQueue","resolves","Map","cache","requestMembers","enabled","pending","id","connection","heart","acknowledged","interval","requestIdentify","shardIsReady","bucket","max","calculateSafeRequests","refillAmount","refillInterval","gatewayConfig","connectionUrl","url","safeRequests","Math","ceil","checkOffline","highPriority","isOpen","Promise","resolve","unshift","push","close","code","reason","socket","readyState","OPEN","connect","Identifying","Resuming","includes","Connecting","connecting","URL","searchParams","set","version","toString","onerror","event","console","log","error","shardId","onclose","handleClose","onmessage","message","handleMessage","onopen","Unidentified","connected","identify","debug","ReIdentifying","identifying","send","op","Identify","d","token","compress","properties","intents","shard","totalShards","presence","makePresence","identified","delete","resume","ResumeClosingOldConnection","sessionId","Resume","session_id","seq","acquire","JSON","stringify","shutdown","Shutdown","stopHeartbeating","TestingFinished","disconnected","Resharded","ZombiedConnection","Disconnected","UnknownOpcode","NotAuthenticated","InvalidSeq","RateLimited","SessionTimedOut","AuthenticationFailed","InvalidShard","ShardingRequired","InvalidApiVersion","InvalidIntents","DisallowedIntents","Error","UnknownError","DecodeError","AlreadyAuthenticated","handleDiscordPacket","packet","lastAck","Date","now","lastBeat","rtt","Heartbeat","heartbeat","Hello","heartbeat_interval","startHeartbeating","currentQueue","queue","hello","HeartbeatACK","heartbeatAck","Reconnect","requestedReconnect","InvalidSession","resumable","invalidSession","floor","random","get","t","Connected","resumed","map","payload","resume_gateway_url","s","forwardToBot","preProcessMessage","data","Blob","arrayBuffer","parse","intervalId","clearInterval","timeoutId","clearTimeout","jitter","setTimeout","setInterval","joinVoiceChannel","guildId","channelId","VoiceStateUpdate","guild_id","channel_id","self_mute","Boolean","selfMute","self_deaf","selfDeaf","editBotStatus","editShardStatus","PresenceUpdate","since","afk","activities","status","limit","GuildMembers","userIds","length","nonce","RequestGuildMembers","query","undefined","presences","user_ids","members","leaveVoiceChannel"],"mappings":"AAAA,kEAAkE,GAWlE,SAASA,sBAAsB,EAAEC,cAAc,EAAEC,cAAc,QAAQ,oBAAmB;AAC1F,SAASC,UAAU,EAAEC,WAAW,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,QAAQ,oBAAmB;AACpF,SAASC,WAAW,QAAQ,YAAW;AACvC,OAAOC,eAAe,KAAI;AAG1B,SAASC,qBAAqB,EAAEC,UAAU,QAAQ,aAAY;AAE9D,OAAO,MAAMC;IA2CXC,YAAYC,OAA2B,CAAE;QApCzC,0HAA0H,QAC1HC,8BAAsC;QACtC,0CAA0C,QAC1CC,yBAAwC,IAAI;QAC5C,4EAA4E,QAC5EC,yBAAiC;QAKjC,wCAAwC,QACxCC,QAAQP,WAAWQ,OAAO;QAC1B,iFAAiF,QACjFC,mBAA2B;QAC3B,sCAAsC,QACtCC,SAAsB,CAAC;QACvB,mGAAmG,QACnGC,mBAAiD,EAAE;QACnD,iFAAiF,QACjFC,WAAW,IAAIC;QAIf,0CAA0C,QAC1CC,QAAQ;YACNC,gBAAgB;gBACd;;;OAGC,GACDC,SAAS,KAAK;gBACd,0BAA0B,GAC1BC,SAAS,IAAIzB;YACf;QACF;QAGE,IAAI,CAAC0B,EAAE,GAAGf,QAAQe,EAAE;QACpB,IAAI,CAACC,UAAU,GAAGhB,QAAQgB,UAAU;QACpC,IAAI,CAACT,MAAM,GAAGP,QAAQO,MAAM;QAE5B,IAAI,CAACU,KAAK,GAAG;YACXC,cAAc,KAAK;YACnBC,UAAU;QACZ;QAEA,IAAInB,QAAQoB,eAAe,EAAE,IAAI,CAACA,eAAe,GAAGpB,QAAQoB,eAAe;QAC3E,IAAIpB,QAAQqB,YAAY,EAAE,IAAI,CAACA,YAAY,GAAGrB,QAAQqB,YAAY;QAElE,IAAI,CAACC,MAAM,GAAG,IAAIhC,YAAY;YAC5BiC,KAAK,IAAI,CAACC,qBAAqB;YAC/BC,cAAc,IAAI,CAACD,qBAAqB;YACxCE,gBAAgB;QAClB;IACF;IAEA,mEAAmE,GACnE,IAAIC,gBAAoC;QACtC,OAAO,IAAI,CAACX,UAAU;IACxB;IAEA,0IAA0I,GAC1I,IAAIY,gBAAwB;QAC1B,+CAA+C;QAC/C,OAAO,IAAI,CAACtB,gBAAgB,IAAI,IAAI,CAACqB,aAAa,CAACE,GAAG;IACxD;IAEA,2JAA2J,GAC3JL,wBAAgC;QAC9B,oFAAoF;QACpF,MAAMM,eAAe,IAAI,CAAC7B,2BAA2B,GAAG8B,KAAKC,IAAI,CAAC,IAAI,CAAC7B,sBAAsB,GAAG,IAAI,CAACc,KAAK,CAACE,QAAQ,IAAI;QAEvH,OAAOW,eAAe,IAAI,IAAIA,YAAY;IAC5C;IAEA,MAAMG,aAAaC,YAAqB,EAAiB;QACvD,IAAI,CAAC,IAAI,CAACC,MAAM,IAAI;YAClB,MAAM,IAAIC,QAAQ,CAACC,UAAY;gBAC7B,oEAAoE;gBACpE,IAAIH,cAAc,IAAI,CAAC1B,gBAAgB,CAAC8B,OAAO,CAACD;qBAC3C,IAAI,CAAC7B,gBAAgB,CAAC+B,IAAI,CAACF;YAClC;QACF,CAAC;IACH;IAEA,uDAAuD,GACvDG,MAAMC,IAAY,EAAEC,MAAc,EAAQ;QACxC,IAAI,IAAI,CAACC,MAAM,EAAEC,eAAejD,UAAUkD,IAAI,EAAE;QAEhD,IAAI,CAACF,MAAM,EAAEH,MAAMC,MAAMC;IAC3B;IAEA,gHAAgH,GAChH,MAAMI,UAAoC;QACxC,4CAA4C;QAC5C,6EAA6E;QAC7E,IAAI,CAAC;YAACjD,WAAWkD,WAAW;YAAElD,WAAWmD,QAAQ;SAAC,CAACC,QAAQ,CAAC,IAAI,CAAC7C,KAAK,GAAG;YACvE,IAAI,CAACA,KAAK,GAAGP,WAAWqD,UAAU;QACpC,CAAC;QACD,IAAI,CAAC3C,MAAM,CAAC4C,UAAU,GAAG,IAAI;QAE7B,MAAMtB,MAAM,IAAIuB,IAAI,IAAI,CAACxB,aAAa;QACtCC,IAAIwB,YAAY,CAACC,GAAG,CAAC,KAAK,IAAI,CAAC3B,aAAa,CAAC4B,OAAO,CAACC,QAAQ;QAC7D3B,IAAIwB,YAAY,CAACC,GAAG,CAAC,YAAY;QAEjC,MAAMX,SAAS,IAAIhD,UAAUkC,IAAI2B,QAAQ;QACzC,IAAI,CAACb,MAAM,GAAGA;QAEd,8BAA8B;QAC9BA,OAAOc,OAAO,GAAG,CAACC,QAAUC,QAAQC,GAAG,CAAC;gBAAEC,OAAOH;gBAAOI,SAAS,IAAI,CAAC/C,EAAE;YAAC;QACzE4B,OAAOoB,OAAO,GAAG,OAAOL,QAAU,MAAM,IAAI,CAACM,WAAW,CAACN;QACzDf,OAAOsB,SAAS,GAAG,OAAOC,UAAY,MAAM,IAAI,CAACC,aAAa,CAACD;QAE/D,OAAO,MAAM,IAAI9B,QAAQ,CAACC,UAAY;YACpCM,OAAOyB,MAAM,GAAG,IAAM;gBACpB,8CAA8C;gBAC9C,6EAA6E;gBAC7E,IAAI,CAAC;oBAACvE,WAAWkD,WAAW;oBAAElD,WAAWmD,QAAQ;iBAAC,CAACC,QAAQ,CAAC,IAAI,CAAC7C,KAAK,GAAG;oBACvE,IAAI,CAACA,KAAK,GAAGP,WAAWwE,YAAY;gBACtC,CAAC;gBACD,IAAI,CAAC9D,MAAM,CAAC+D,SAAS,GAAG,IAAI;gBAE5BjC,QAAQ,IAAI;YACd;QACF;IACF;IAEA,0GAA0G,GAC1G,MAAMkC,WAA0B;QAC9B,oFAAoF;QACpF,4FAA4F;QAC5F,IAAI,IAAI,CAACpC,MAAM,IAAI;YACjB1C,OAAO+E,KAAK,CAAC,CAAC,yBAAyB,EAAE,IAAI,CAACzD,EAAE,CAAC,CAAC;YAClD,IAAI,CAACyB,KAAK,CAAC5C,sBAAsB6E,aAAa,EAAE;QAClD,CAAC;QAED,IAAI,CAACrE,KAAK,GAAGP,WAAWkD,WAAW;QACnC,IAAI,CAACxC,MAAM,CAACmE,WAAW,GAAG,IAAI;QAE9B,6EAA6E;QAC7E,mEAAmE;QACnE,mDAAmD;QACnD,IAAI,CAAC,IAAI,CAACvC,MAAM,IAAI;YAClB,MAAM,IAAI,CAACW,OAAO;QACpB,CAAC;QAED,IAAI,CAAC6B,IAAI,CACP;YACEC,IAAIxF,eAAeyF,QAAQ;YAC3BC,GAAG;gBACDC,OAAO,CAAC,IAAI,EAAE,IAAI,CAACpD,aAAa,CAACoD,KAAK,CAAC,CAAC;gBACxCC,UAAU,IAAI,CAACrD,aAAa,CAACqD,QAAQ;gBACrCC,YAAY,IAAI,CAACtD,aAAa,CAACsD,UAAU;gBACzCC,SAAS,IAAI,CAACvD,aAAa,CAACuD,OAAO;gBACnCC,OAAO;oBAAC,IAAI,CAACpE,EAAE;oBAAE,IAAI,CAACY,aAAa,CAACyD,WAAW;iBAAC;gBAChDC,UAAU,MAAM,IAAI,CAACC,YAAY;YACnC;QACF,GACA,IAAI;QAGN,OAAO,MAAM,IAAIlD,QAAQ,CAACC,UAAY;YACpC,IAAI,CAAC5B,QAAQ,CAAC6C,GAAG,CAAC,SAAS,IAAM;gBAC/B,IAAI,CAAC/C,MAAM,CAACgF,UAAU,GAAG,IAAI;gBAC7B,6CAA6C;gBAC7C,IAAI,CAAClE,YAAY;gBACjBgB;YACF;YACA,6BAA6B;YAC7B,4CAA4C;YAC5C,gFAAgF;YAChF,IAAI,CAAC5B,QAAQ,CAAC6C,GAAG,CAAC,mBAAmB,IAAM;gBACzC,IAAI,CAAC7C,QAAQ,CAAC+E,MAAM,CAAC;gBACrBnD;YACF;QACF;IACF;IAEA,+DAA+D,GAC/DF,SAAkB;QAChB,OAAO,IAAI,CAACQ,MAAM,EAAEC,eAAejD,UAAUkD,IAAI;IACnD;IAEA,oEAAoE,GACpE,MAAM4C,SAAwB;QAC5BhG,OAAO+E,KAAK,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAACzD,EAAE,CAAC,CAAC;QACnD,sDAAsD;QACtD,mHAAmH;QACnH,IAAI,IAAI,CAACoB,MAAM,IAAI;YACjB,IAAI,CAACK,KAAK,CAAC5C,sBAAsB8F,0BAA0B,EAAE;QAC/D,CAAC;QAED,mDAAmD;QACnD,IAAI,CAAC,IAAI,CAACC,SAAS,EAAE;YACnBlG,OAAO+E,KAAK,CAAC,CAAC,kCAAkC,EAAE,IAAI,CAACzD,EAAE,CAAC,qDAAqD,CAAC;YAEhH,OAAO,MAAM,IAAI,CAACwD,QAAQ;QAC5B,CAAC;QAED,IAAI,CAACnE,KAAK,GAAGP,WAAWmD,QAAQ;QAEhC,mFAAmF;QACnF,MAAM,IAAI,CAACF,OAAO;QAElB,IAAI,CAAC6B,IAAI,CACP;YACEC,IAAIxF,eAAewG,MAAM;YACzBd,GAAG;gBACDC,OAAO,CAAC,IAAI,EAAE,IAAI,CAACpD,aAAa,CAACoD,KAAK,CAAC,CAAC;gBACxCc,YAAY,IAAI,CAACF,SAAS;gBAC1BG,KAAK,IAAI,CAAC5F,sBAAsB,IAAI;YACtC;QACF,GACA,IAAI;QAGN,OAAO,MAAM,IAAIkC,QAAQ,CAACC,UAAY;YACpC,IAAI,CAAC5B,QAAQ,CAAC6C,GAAG,CAAC,WAAW,IAAMjB;YACnC,2DAA2D;YAC3D,2CAA2C;YAC3C,uFAAuF;YACvF,IAAI,CAAC5B,QAAQ,CAAC6C,GAAG,CAAC,mBAAmB,IAAM;gBACzC,IAAI,CAAC7C,QAAQ,CAAC+E,MAAM,CAAC;gBACrBnD;YACF;QACF;IACF;IAEA;;GAEC,GACD,MAAMsC,KAAKT,OAA2B,EAAEhC,eAAe,KAAK,EAAiB;QAC3E,iGAAiG;QACjG,mDAAmD;QACnD,MAAM,IAAI,CAACD,YAAY,CAACC;QAExB,MAAM,IAAI,CAACZ,MAAM,CAACyE,OAAO,CAAC7D;QAE1B,8FAA8F;QAC9F,MAAM,IAAI,CAACD,YAAY,CAACC;QAExB,IAAI,CAACS,MAAM,EAAEgC,KAAKqB,KAAKC,SAAS,CAAC/B;IACnC;IAEA,0HAA0H,GAC1H,MAAMgC,WAA0B;QAC9B,IAAI,CAAC1D,KAAK,CAAC5C,sBAAsBuG,QAAQ,EAAE;QAC3C,IAAI,CAAC/F,KAAK,GAAGP,WAAWQ,OAAO;IACjC;IAEA,uCAAuC,GACvC,MAAM2D,YAAYxB,KAA2B,EAAiB;QAC5D,6DAA6D;QAE7D,IAAI,CAAC4D,gBAAgB;QAErB,OAAQ5D,MAAMC,IAAI;YAChB,KAAK7C,sBAAsByG,eAAe;gBAAE;oBAC1C,IAAI,CAACjG,KAAK,GAAGP,WAAWQ,OAAO;oBAC/B,IAAI,CAACE,MAAM,CAAC+F,YAAY,GAAG,IAAI;oBAE/B;gBACF;YACA,8CAA8C;YAC9C,KAAK1G,sBAAsBuG,QAAQ;YACnC,KAAKvG,sBAAsB6E,aAAa;YACxC,KAAK7E,sBAAsB2G,SAAS;YACpC,KAAK3G,sBAAsB8F,0BAA0B;YACrD,KAAK9F,sBAAsB4G,iBAAiB;gBAAE;oBAC5C,IAAI,CAACpG,KAAK,GAAGP,WAAW4G,YAAY;oBACpC,IAAI,CAAClG,MAAM,CAAC+F,YAAY,GAAG,IAAI;oBAE/B,qEAAqE;oBACrE;gBACF;YACA,0DAA0D;YAC1D,KAAKpH,uBAAuBwH,aAAa;YACzC,KAAKxH,uBAAuByH,gBAAgB;YAC5C,KAAKzH,uBAAuB0H,UAAU;YACtC,KAAK1H,uBAAuB2H,WAAW;YACvC,KAAK3H,uBAAuB4H,eAAe;gBAAE;oBAC3CrH,OAAO+E,KAAK,CAAC,CAAC,gEAAgE,EAAEhC,MAAMC,IAAI,CAAC,CAAC;oBAC5F,IAAI,CAACrC,KAAK,GAAGP,WAAWkD,WAAW;oBACnC,IAAI,CAACxC,MAAM,CAAC+F,YAAY,GAAG,IAAI;oBAE/B,OAAO,MAAM,IAAI,CAAC/B,QAAQ;gBAC5B;YACA,6DAA6D;YAC7D,gDAAgD;YAChD,KAAKrF,uBAAuB6H,oBAAoB;YAChD,KAAK7H,uBAAuB8H,YAAY;YACxC,KAAK9H,uBAAuB+H,gBAAgB;YAC5C,KAAK/H,uBAAuBgI,iBAAiB;YAC7C,KAAKhI,uBAAuBiI,cAAc;YAC1C,KAAKjI,uBAAuBkI,iBAAiB;gBAAE;oBAC7C,IAAI,CAAChH,KAAK,GAAGP,WAAWQ,OAAO;oBAC/B,IAAI,CAACE,MAAM,CAAC+F,YAAY,GAAG,IAAI;oBAE/B,MAAM,IAAIe,MAAM7E,MAAME,MAAM,IAAI,kDAAiD;gBACnF;YACA,0DAA0D;YAC1D,KAAKxD,uBAAuBoI,YAAY;YACxC,KAAKpI,uBAAuBqI,WAAW;YACvC,KAAKrI,uBAAuBsI,oBAAoB;YAChD;gBAAS;oBACP,IAAI,CAACpH,KAAK,GAAGP,WAAWmD,QAAQ;oBAChC,IAAI,CAACzC,MAAM,CAAC+F,YAAY,GAAG,IAAI;oBAE/B,OAAO,MAAM,IAAI,CAACb,MAAM;gBAC1B;QACF;IACF;IAEA,uCAAuC,GACvC,MAAMgC,oBAAoBC,MAA6B,EAAiB;QACtE,wEAAwE;QACxE,IAAI,CAACzG,KAAK,CAAC0G,OAAO,GAAGC,KAAKC,GAAG;QAC7B,kEAAkE;QAClE,IAAI,IAAI,CAAC5G,KAAK,CAAC6G,QAAQ,IAAI,CAAC,IAAI,CAAC7G,KAAK,CAACC,YAAY,EAAE;YACnD,IAAI,CAACD,KAAK,CAAC8G,GAAG,GAAG,IAAI,CAAC9G,KAAK,CAAC0G,OAAO,GAAG,IAAI,CAAC1G,KAAK,CAAC6G,QAAQ;QAC3D,CAAC;QACD,IAAI,CAAC7G,KAAK,CAACC,YAAY,GAAG,IAAI;QAC9B,iBAAiB;QAEjB,OAAQwG,OAAO9C,EAAE;YACf,KAAKxF,eAAe4I,SAAS;gBAAE;oBAC7B,iCAAiC;oBACjC,IAAI,CAAC,IAAI,CAAC7F,MAAM,IAAI;oBAEpB,IAAI,CAAClB,KAAK,CAAC6G,QAAQ,GAAGF,KAAKC,GAAG;oBAC9B,qEAAqE;oBACrE,sFAAsF;oBACtF,IAAI,CAAClF,MAAM,EAAEgC,KACXqB,KAAKC,SAAS,CAAC;wBACbrB,IAAIxF,eAAe4I,SAAS;wBAC5BlD,GAAG,IAAI,CAAC5E,sBAAsB;oBAChC;oBAEF,IAAI,CAACK,MAAM,CAAC0H,SAAS,GAAG,IAAI;oBAE5B,KAAK;gBACP;YACA,KAAK7I,eAAe8I,KAAK;gBAAE;oBACzB,MAAM/G,WAAW,AAACuG,OAAO5C,CAAC,CAAkBqD,kBAAkB;oBAE9D,IAAI,CAACC,iBAAiB,CAACjH;oBAEvB,IAAI,IAAI,CAACf,KAAK,KAAKP,WAAWmD,QAAQ,EAAE;wBACtC,MAAMqF,eAAe;+BAAI,IAAI,CAAC/G,MAAM,CAACgH,KAAK;yBAAC;wBAC3C,8CAA8C;wBAC9C,kDAAkD;wBAClD,wDAAwD;wBACxD,IAAI,CAAChH,MAAM,GAAG,IAAIhC,YAAY;4BAC5BiC,KAAK,IAAI,CAACC,qBAAqB;4BAC/BE,gBAAgB;4BAChBD,cAAc,IAAI,CAACD,qBAAqB;wBAC1C;wBAEA,6CAA6C;wBAC7C,IAAI,CAACF,MAAM,CAACgH,KAAK,CAAChG,OAAO,IAAI+F;oBAC/B,CAAC;oBAED,IAAI,CAAC9H,MAAM,CAACgI,KAAK,GAAG,IAAI;oBAExB,KAAK;gBACP;YACA,KAAKnJ,eAAeoJ,YAAY;gBAAE;oBAChC,IAAI,CAACjI,MAAM,CAACkI,YAAY,GAAG,IAAI;oBAE/B,KAAK;gBACP;YACA,KAAKrJ,eAAesJ,SAAS;gBAAE;oBAC7B,gDAAgD;oBAEhD,IAAI,CAACnI,MAAM,CAACoI,kBAAkB,GAAG,IAAI;oBAErC,MAAM,IAAI,CAAClD,MAAM;oBAEjB,KAAK;gBACP;YACA,KAAKrG,eAAewJ,cAAc;gBAAE;oBAClC,MAAMC,YAAYnB,OAAO5C,CAAC;oBAC1BrF,OAAO+E,KAAK,CAAC,CAAC,4CAA4C,EAAE,IAAI,CAACzD,EAAE,CAAC,oBAAoB,EAAE8H,UAAUrF,QAAQ,GAAG,CAAC;oBAEhH,IAAI,CAACjD,MAAM,CAACuI,cAAc,GAAG,IAAI,EAAED;oBAEnC,8DAA8D;oBAC9D,yEAAyE;oBACzE,MAAMrJ,MAAMuC,KAAKgH,KAAK,CAAC,AAAChH,CAAAA,KAAKiH,MAAM,KAAK,IAAI,CAAA,IAAK;oBAEjD,IAAI,CAACvI,QAAQ,CAACwI,GAAG,CAAC,qBAAqBvB;oBACvC,IAAI,CAACjH,QAAQ,CAAC+E,MAAM,CAAC;oBAErB,iDAAiD;oBACjD,IAAI,CAACqD,WAAW;wBACd,MAAM,IAAI,CAACzH,eAAe;wBAE1B,KAAK;oBACP,CAAC;oBAED,wDAAwD;oBACxD,MAAM,IAAI,CAACqE,MAAM;oBAEjB,KAAK;gBACP;QACF;QAEA,IAAIiC,OAAOwB,CAAC,KAAK,WAAW;YAC1B,4CAA4C;YAE5C,IAAI,CAAC9I,KAAK,GAAGP,WAAWsJ,SAAS;YACjC,IAAI,CAAC5I,MAAM,CAAC6I,OAAO,GAAG,IAAI;YAE1B,6EAA6E;YAC7E,IAAI,CAAC5I,gBAAgB,CAAC6I,GAAG,CAAC,CAAChH,UAAYA;YAEvC,IAAI,CAAC5B,QAAQ,CAACwI,GAAG,CAAC,aAAavB;YAC/B,IAAI,CAACjH,QAAQ,CAAC+E,MAAM,CAAC;QACvB,OAAO,IAAIkC,OAAOwB,CAAC,KAAK,SAAS;YAC/B,gCAAgC;YAEhC,MAAMI,UAAU5B,OAAO5C,CAAC;YAExB,IAAI,CAACxE,gBAAgB,GAAGgJ,QAAQC,kBAAkB;YAElD,IAAI,CAAC5D,SAAS,GAAG2D,QAAQzD,UAAU;YACnC,IAAI,CAACzF,KAAK,GAAGP,WAAWsJ,SAAS;YAEjC,6EAA6E;YAC7E,uCAAuC;YACvC,IAAI,CAAC3I,gBAAgB,CAAC6I,GAAG,CAAC,CAAChH,UAAYA;YAEvC,IAAI,CAAC5B,QAAQ,CAACwI,GAAG,CAAC,WAAWvB;YAC7B,IAAI,CAACjH,QAAQ,CAAC+E,MAAM,CAAC;QACvB,CAAC;QAED,8CAA8C;QAC9C,0CAA0C;QAC1C,2EAA2E;QAC3E,IAAIkC,OAAO8B,CAAC,KAAK,IAAI,EAAE;YACrB,IAAI,CAACtJ,sBAAsB,GAAGwH,OAAO8B,CAAC;QACxC,CAAC;QAED,IAAI,CAACC,YAAY,CAAC/B;IACpB;IAEA+B,aAAa/B,MAA6B,EAAQ;QAChD,+EAA+E;QAC/E,yCAAyC;QACzC,IAAI,CAACnH,MAAM,CAAC2D,OAAO,GAAG,IAAI,EAAE3E,SAASmI;IACvC;IAEA,wCAAwC,GACxC,MAAMvD,cAAcD,OAA+B,EAAiB;QAClE,IAAIwF,oBAAoBxF,QAAQyF,IAAI;QAEpC,qCAAqC;QACrC,+CAA+C;QAC/C,IAAI,IAAI,CAAChI,aAAa,CAACqD,QAAQ,IAAI0E,6BAA6BE,MAAM;YACpEF,oBAAoBhK,YAAY,MAAMgK,kBAAkBG,WAAW,IAAIrG,QAAQ;QACjF,CAAC;QAED,0DAA0D;QAC1D,IAAI,OAAOkG,sBAAsB,UAAU;QAE3C,OAAO,MAAM,IAAI,CAACjC,mBAAmB,CAACzB,KAAK8D,KAAK,CAACJ;IACnD;IAEA;;;;GAIC,GACD,MAAMpE,eAAqD;QACzD,6CAA6C;QAC7C;IACF;IAEA,qNAAqN,GACrN,MAAMlE,kBAAiC,CAAC;IAExC,6GAA6G,GAC7G,MAAMC,eAA8B,CAAC;IAErC,0EAA0E,GAC1E+G,kBAAkBjH,QAAgB,EAAQ;QACxC,iEAAiE;QACjE,IAAI,IAAI,CAACF,KAAK,CAAC8I,UAAU,EAAEC,cAAc,IAAI,CAAC/I,KAAK,CAAC8I,UAAU;QAC9D,IAAI,IAAI,CAAC9I,KAAK,CAACgJ,SAAS,EAAEC,aAAa,IAAI,CAACjJ,KAAK,CAACgJ,SAAS;QAE3D,IAAI,CAAChJ,KAAK,CAACE,QAAQ,GAAGA;QAEtB,+CAA+C;QAC/C,4EAA4E;QAC5E,IAAI;YAACtB,WAAW4G,YAAY;YAAE5G,WAAWQ,OAAO;SAAC,CAAC4C,QAAQ,CAAC,IAAI,CAAC7C,KAAK,GAAG;YACtE,IAAI,CAACA,KAAK,GAAGP,WAAWwE,YAAY;QACtC,CAAC;QAED,sFAAsF;QACtF,2DAA2D;QAC3D,6DAA6D;QAC7D,6EAA6E;QAC7E,MAAM8F,SAASpI,KAAKC,IAAI,CAAC,IAAI,CAACf,KAAK,CAACE,QAAQ,GAAIY,CAAAA,KAAKiH,MAAM,MAAM,GAAE;QACnE,IAAI,CAAC/H,KAAK,CAACgJ,SAAS,GAAGG,WAAW,IAAM;YACtC,IAAI,CAAC,IAAI,CAACjI,MAAM,IAAI;YAEpB,sFAAsF;YACtF,IAAI,CAACQ,MAAM,EAAEgC,KACXqB,KAAKC,SAAS,CAAC;gBACbrB,IAAIxF,eAAe4I,SAAS;gBAC5BlD,GAAG,IAAI,CAAC5E,sBAAsB;YAChC;YAGF,IAAI,CAACe,KAAK,CAAC6G,QAAQ,GAAGF,KAAKC,GAAG;YAC9B,IAAI,CAAC5G,KAAK,CAACC,YAAY,GAAG,KAAK;YAE/B,oEAAoE;YACpE,IAAI,CAACD,KAAK,CAAC8I,UAAU,GAAGM,YAAY,UAAY;gBAC9C,IAAI,CAAC,IAAI,CAAClI,MAAM,IAAI;gBACpB,yFAAyF;gBAEzF,sEAAsE;gBAEtE,kEAAkE;gBAClE,+EAA+E;gBAC/E,6DAA6D;gBAC7D,2GAA2G;gBAC3G,IAAI,CAAC,IAAI,CAAClB,KAAK,CAACC,YAAY,EAAE;oBAC5BzB,OAAO+E,KAAK,CAAC,CAAC,8CAA8C,EAAE,IAAI,CAACzD,EAAE,CAAC,CAAC,CAAC;oBACxE,IAAI,CAACyB,KAAK,CAAC5C,sBAAsB4G,iBAAiB,EAAE;oBAEpD,OAAO,MAAM,IAAI,CAACjC,QAAQ;gBAC5B,CAAC;gBAED,IAAI,CAACtD,KAAK,CAACC,YAAY,GAAG,KAAK;gBAE/B,sFAAsF;gBACtF,IAAI,CAACyB,MAAM,EAAEgC,KACXqB,KAAKC,SAAS,CAAC;oBACbrB,IAAIxF,eAAe4I,SAAS;oBAC5BlD,GAAG,IAAI,CAAC5E,sBAAsB;gBAChC;gBAGF,IAAI,CAACe,KAAK,CAAC6G,QAAQ,GAAGF,KAAKC,GAAG;gBAE9B,IAAI,CAACtH,MAAM,CAAC0H,SAAS,GAAG,IAAI;YAC9B,GAAG,IAAI,CAAChH,KAAK,CAACE,QAAQ;QACxB,GAAGgJ;IACL;IAEA,gDAAgD,GAChD/D,mBAAyB;QACvB,wCAAwC;QACxC4D,cAAc,IAAI,CAAC/I,KAAK,CAAC8I,UAAU;QACnC,+EAA+E;QAC/E,sDAAsD;QACtDG,aAAa,IAAI,CAACjJ,KAAK,CAACgJ,SAAS;IACnC;IAEA;;;;;;;;;;;;;;GAcC,GACD,MAAMK,iBACJC,OAAkB,EAClBC,SAAoB,EACpBxK,OAAqE,EACtD;QACfP,OAAO+E,KAAK,CAAC,CAAC,kCAAkC,EAAE+F,QAAQ,YAAY,EAAEC,UAAU,CAAC;QACnF,MAAM,IAAI,CAAC7F,IAAI,CAAC;YACdC,IAAIxF,eAAeqL,gBAAgB;YACnC3F,GAAG;gBACD4F,UAAUH,QAAQ/G,QAAQ;gBAC1BmH,YAAYH,UAAUhH,QAAQ;gBAC9BoH,WAAWC,QAAQ7K,SAAS8K;gBAC5BC,WAAW/K,SAASgL,YAAY,IAAI;YACtC;QACF;IACF;IAEA;;;;;GAKC,GACD,MAAMC,cAActB,IAAkB,EAAiB;QACrDlK,OAAO+E,KAAK,CAAC,CAAC,4BAA4B,EAAEwB,KAAKC,SAAS,CAAC0D,MAAM,CAAC;QAClE,MAAM,IAAI,CAACuB,eAAe,CAACvB;IAC7B;IAEA;;;;;;GAMC,GACD,MAAMuB,gBAAgBvB,IAAkB,EAAiB;QACvDlK,OAAO+E,KAAK,CAAC,CAAC,iCAAiC,EAAE,IAAI,CAACzD,EAAE,CAAC,UAAU,EAAEiF,KAAKC,SAAS,CAAC0D,MAAM,CAAC;QAC3F,MAAM,IAAI,CAAChF,IAAI,CAAC;YACdC,IAAIxF,eAAe+L,cAAc;YACjCrG,GAAG;gBACDsG,OAAO,IAAI;gBACXC,KAAK,KAAK;gBACVC,YAAY3B,KAAK2B,UAAU;gBAC3BC,QAAQ5B,KAAK4B,MAAM;YACrB;QACF;IACF;IAEA;;;;;;;;;;;;;;;;;;;;;;GAsBC,GACD,MAAM3K,eAAe2J,OAAkB,EAAEvK,OAA8C,EAAsC;QAC3H,8CAA8C;QAC9C,6EAA6E;QAC7E,IAAI,IAAI,CAACgB,UAAU,CAACkE,OAAO,IAAK,CAAA,CAAClF,SAASwL,SAASxL,QAAQwL,KAAK,GAAG,CAAA,KAAM,CAAE,CAAA,IAAI,CAACxK,UAAU,CAACkE,OAAO,GAAG/F,eAAesM,YAAY,AAAD,GAAI;YACjI,MAAM,IAAIpE,MAAM,gCAA+B;QACjD,CAAC;QAED,IAAIrH,SAAS0L,SAASC,QAAQ;YAC5BlM,OAAO+E,KAAK,CAAC,CAAC,gCAAgC,EAAE+F,QAAQ,gDAAgD,EAAEvK,QAAQ0L,OAAO,CAACC,MAAM,CAAC,CAAC;YAClI3L,QAAQwL,KAAK,GAAGxL,QAAQ0L,OAAO,CAACC,MAAM;QACxC,CAAC;QAED,MAAMC,QAAQ,CAAC,EAAErB,QAAQ,CAAC,EAAE3C,KAAKC,GAAG,GAAG,CAAC;QAExC,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAClH,KAAK,CAACC,cAAc,EAAEC,SAAS;YACvCpB,OAAO+E,KAAK,CAAC,CAAC,gCAAgC,EAAE+F,QAAQ,8BAA8B,EAAEvE,KAAKC,SAAS,CAACjG,SAAS,CAAC;YACjH,MAAM,IAAI,CAAC2E,IAAI,CAAC;gBACdC,IAAIxF,eAAeyM,mBAAmB;gBACtC/G,GAAG;oBACD4F,UAAUH,QAAQ/G,QAAQ;oBAC1B,sEAAsE;oBACtEsI,OAAO9L,SAAS8L,SAAU9L,CAAAA,SAASwL,QAAQO,YAAY,EAAE,AAAD;oBACxDP,OAAOxL,SAASwL,SAAS;oBACzBQ,WAAWhM,SAASgM,aAAa,KAAK;oBACtCC,UAAUjM,SAAS0L,SAASrC,IAAI,CAACtI,KAAOA,GAAGyC,QAAQ;oBACnDoI;gBACF;YACF;YACA,OAAO,EAAE;QACX,CAAC;QAED,OAAO,MAAM,IAAIxJ,QAAQ,CAACC,UAAY;YACpC,IAAI,CAAC1B,KAAK,CAACC,cAAc,EAAEE,QAAQwC,GAAG,CAACsI,OAAO;gBAAEA;gBAAOvJ;gBAAS6J,SAAS,EAAE;YAAC;YAE5EzM,OAAO+E,KAAK,CAAC,CAAC,gCAAgC,EAAE+F,QAAQ,gCAAgC,EAAEvE,KAAKC,SAAS,CAACjG,SAAS,CAAC;YACnH,IAAI,CAAC2E,IAAI,CAAC;gBACRC,IAAIxF,eAAeyM,mBAAmB;gBACtC/G,GAAG;oBACD4F,UAAUH,QAAQ/G,QAAQ;oBAC1B,sEAAsE;oBACtEsI,OAAO9L,SAAS8L,SAAU9L,CAAAA,SAASwL,QAAQO,YAAY,EAAE,AAAD;oBACxDP,OAAOxL,SAASwL,SAAS;oBACzBQ,WAAWhM,SAASgM,aAAa,KAAK;oBACtCC,UAAUjM,SAAS0L,SAASrC,IAAI,CAACtI,KAAOA,GAAGyC,QAAQ;oBACnDoI;gBACF;YACF;QACF;IACF;IAEA;;;;;;;;;;;GAWC,GACD,MAAMO,kBAAkB5B,OAAkB,EAAiB;QACzD9K,OAAO+E,KAAK,CAAC,CAAC,mCAAmC,EAAE+F,QAAQ,OAAO,EAAE,IAAI,CAACxJ,EAAE,CAAC,CAAC;QAC7E,MAAM,IAAI,CAAC4D,IAAI,CAAC;YACdC,IAAIxF,eAAeqL,gBAAgB;YACnC3F,GAAG;gBACD4F,UAAUH,QAAQ/G,QAAQ;gBAC1BmH,YAAY,IAAI;gBAChBC,WAAW,KAAK;gBAChBG,WAAW,KAAK;YAClB;QACF;IACF;AACF,CAAC;AAeD,eAAejL,gBAAe"}
|
|
1
|
+
{"version":3,"sources":["../src/Shard.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-confusing-void-expression */\nimport type {\n AtLeastOne,\n BigString,\n Camelize,\n DiscordGatewayPayload,\n DiscordHello,\n DiscordMember,\n DiscordReady,\n RequestGuildMembers,\n} from '@discordeno/types'\nimport { GatewayCloseEventCodes, GatewayIntents, GatewayOpcodes } from '@discordeno/types'\nimport { Collection, LeakyBucket, camelize, delay, logger } from '@discordeno/utils'\nimport { inflateSync } from 'node:zlib'\nimport WebSocket from 'ws'\nimport type { RequestMemberRequest } from './manager.js'\nimport type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js'\nimport { ShardSocketCloseCodes, ShardState } from './types.js'\n\nexport class DiscordenoShard {\n /** The id of the shard */\n id: number\n /** The connection config details that this shard will used to connect to discord. */\n connection: ShardGatewayConfig\n /** This contains all the heartbeat information */\n heart: ShardHeart\n /** The maximum of requests which can be send to discord per rate limit tick. Typically this value should not be changed. */\n maxRequestsPerRateLimitTick: number = 120\n /** The previous payload sequence number. */\n previousSequenceNumber: number | null = null\n /** In which interval (in milliseconds) the gateway resets it's rate limit. */\n rateLimitResetInterval: number = 60000\n /** Current session id of the shard if present. */\n sessionId?: string\n /** This contains the WebSocket connection to Discord, if currently connected. */\n socket?: WebSocket\n /** Current internal state of the this. */\n state = ShardState.Offline\n /** The url provided by discord to use when resuming a connection for this this. */\n resumeGatewayUrl: string = ''\n /** The shard related event handlers. */\n events: ShardEvents = {}\n /** Cache for pending gateway requests which should have been send while the gateway went offline. */\n offlineSendQueue: Array<(_?: unknown) => void> = []\n /** Resolve internal waiting states. Mapped by SelectedEvents => ResolveFunction */\n resolves = new Map<'READY' | 'RESUMED' | 'INVALID_SESSION', (payload: DiscordGatewayPayload) => void>()\n /** Shard bucket. Only access this if you know what you are doing. Bucket for handling shard request rate limits. */\n bucket: LeakyBucket\n\n /** This managers cache related settings. */\n cache = {\n requestMembers: {\n /**\n * Whether or not request member requests should be cached.\n * @default false\n */\n enabled: false,\n /** The pending requests. */\n pending: new Collection<string, RequestMemberRequest>(),\n },\n }\n\n constructor(options: ShardCreateOptions) {\n this.id = options.id\n this.connection = options.connection\n this.events = options.events\n\n this.heart = {\n acknowledged: false,\n interval: 45000,\n }\n\n if (options.requestIdentify) this.requestIdentify = options.requestIdentify\n if (options.shardIsReady) this.shardIsReady = options.shardIsReady\n\n this.bucket = new LeakyBucket({\n max: this.calculateSafeRequests(),\n refillAmount: this.calculateSafeRequests(),\n refillInterval: 60000,\n })\n }\n\n /** The gateway configuration which is used to connect to Discord. */\n get gatewayConfig(): ShardGatewayConfig {\n return this.connection\n }\n\n /** The url to connect to. Intially this is the discord gateway url, and then is switched to resume gateway url once a READY is received. */\n get connectionUrl(): string {\n // Use || and not ?? here. ?? will cause a bug.\n return this.resumeGatewayUrl || this.gatewayConfig.url\n }\n\n /** Calculate the amount of requests which can safely be made per rate limit interval, before the gateway gets disconnected due to an exceeded rate limit. */\n calculateSafeRequests(): number {\n // * 2 adds extra safety layer for discords OP 1 requests that we need to respond to\n const safeRequests = this.maxRequestsPerRateLimitTick - Math.ceil(this.rateLimitResetInterval / this.heart.interval) * 2\n\n return safeRequests < 0 ? 0 : safeRequests\n }\n\n async checkOffline(highPriority: boolean): Promise<void> {\n if (!this.isOpen()) {\n await new Promise((resolve) => {\n // Higher priority requests get added at the beginning of the array.\n if (highPriority) this.offlineSendQueue.unshift(resolve)\n else this.offlineSendQueue.push(resolve)\n })\n }\n }\n\n /** Close the socket connection to discord if present. */\n close(code: number, reason: string): void {\n if (this.socket?.readyState !== WebSocket.OPEN) return\n\n this.socket?.close(code, reason)\n }\n\n /** Connect the shard with the gateway and start heartbeating. This will not identify the shard to the gateway. */\n async connect(): Promise<DiscordenoShard> {\n // Only set the shard to `Connecting` state,\n // if the connection request does not come from an identify or resume action.\n if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) {\n this.state = ShardState.Connecting\n }\n this.events.connecting?.(this)\n\n const url = new URL(this.connectionUrl)\n url.searchParams.set('v', this.gatewayConfig.version.toString())\n url.searchParams.set('encoding', 'json')\n\n const socket = new WebSocket(url.toString())\n this.socket = socket\n\n // TODO: proper event handling\n socket.onerror = (event) => console.log({ error: event, shardId: this.id })\n socket.onclose = async (event) => await this.handleClose(event)\n socket.onmessage = async (message) => await this.handleMessage(message)\n\n return await new Promise((resolve) => {\n socket.onopen = () => {\n // Only set the shard to `Unidentified` state,\n // if the connection request does not come from an identify or resume action.\n if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) {\n this.state = ShardState.Unidentified\n }\n this.events.connected?.(this)\n\n resolve(this)\n }\n })\n }\n\n /** Identify the shard to the gateway. If not connected, this will also connect the shard to the gateway. */\n async identify(): Promise<void> {\n // A new identify has been requested even though there is already a connection open.\n // Therefore we need to close the old connection and heartbeating before creating a new one.\n if (this.isOpen()) {\n logger.debug(`CLOSING EXISTING SHARD: #${this.id}`)\n this.close(ShardSocketCloseCodes.ReIdentifying, 'Re-identifying closure of old connection.')\n }\n\n this.state = ShardState.Identifying\n this.events.identifying?.(this)\n\n // It is possible that the shard is in Heartbeating state but not identified,\n // so check whether there is already a gateway connection existing.\n // If not we need to create one before we identify.\n if (!this.isOpen()) {\n await this.connect()\n }\n\n this.send(\n {\n op: GatewayOpcodes.Identify,\n d: {\n token: `Bot ${this.gatewayConfig.token}`,\n compress: this.gatewayConfig.compress,\n properties: this.gatewayConfig.properties,\n intents: this.gatewayConfig.intents,\n shard: [this.id, this.gatewayConfig.totalShards],\n presence: await this.makePresence?.(),\n },\n },\n true,\n )\n\n return await new Promise((resolve) => {\n this.resolves.set('READY', () => {\n this.events.identified?.(this)\n // Tells the manager that this shard is ready\n this.shardIsReady()\n resolve()\n })\n // When identifying too fast,\n // Discord sends an invalid session payload.\n // This can safely be ignored though and the shard starts a new identify action.\n this.resolves.set('INVALID_SESSION', () => {\n this.resolves.delete('READY')\n resolve()\n })\n })\n }\n\n /** Check whether the connection to Discord is currently open. */\n isOpen(): boolean {\n return this.socket?.readyState === WebSocket.OPEN\n }\n\n /** Attempt to resume the previous shards session with the gateway. */\n async resume(): Promise<void> {\n logger.debug(`[Gateway] Resuming Shard #${this.id}`)\n // It has been requested to resume the Shards session.\n // It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.\n if (this.isOpen()) {\n logger.debug(`[Gateway] Resuming Shard #${this.id} in isOpen`)\n this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.')\n }\n\n // Shard has never identified, so we cannot resume.\n if (!this.sessionId) {\n logger.debug(`[Shard] Trying to resume a shard #${this.id} that was NOT first identified. (No session id found)`)\n\n return await this.identify()\n }\n\n this.state = ShardState.Resuming\n\n logger.debug(`[Gateway] Resuming Shard #${this.id}, before connecting`)\n // Before we can resume, we need to create a new connection with Discord's gateway.\n await this.connect()\n logger.debug(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `[Gateway] Resuming Shard #${this.id}, after connecting. ${this.gatewayConfig.token} | ${this.sessionId} | ${this.previousSequenceNumber}`,\n )\n\n this.send(\n {\n op: GatewayOpcodes.Resume,\n d: {\n token: `Bot ${this.gatewayConfig.token}`,\n session_id: this.sessionId,\n seq: this.previousSequenceNumber ?? 0,\n },\n },\n true,\n )\n logger.debug(`[Gateway] Resuming Shard #${this.id} after send resumg`)\n\n return await new Promise((resolve) => {\n this.resolves.set('RESUMED', () => resolve())\n // If it is attempted to resume with an invalid session id,\n // Discord sends an invalid session payload\n // Not erroring here since it is easy that this happens, also it would be not catchable\n this.resolves.set('INVALID_SESSION', () => {\n this.resolves.delete('RESUMED')\n resolve()\n })\n })\n }\n\n /** Send a message to Discord.\n * @param {boolean} [highPriority=false] - Whether this message should be send asap.\n */\n async send(message: ShardSocketRequest, highPriority = false): Promise<void> {\n // Before acquiring a token from the bucket, check whether the shard is currently offline or not.\n // Else bucket and token wait time just get wasted.\n await this.checkOffline(highPriority)\n\n await this.bucket.acquire(highPriority)\n\n // It's possible, that the shard went offline after a token has been acquired from the bucket.\n await this.checkOffline(highPriority)\n\n this.socket?.send(JSON.stringify(message))\n }\n\n /** Shutdown the this. Forcefully disconnect the shard from Discord. The shard may not attempt to reconnect with Discord. */\n async shutdown(): Promise<void> {\n this.close(ShardSocketCloseCodes.Shutdown, 'Shard shutting down.')\n this.state = ShardState.Offline\n }\n\n /** Handle a gateway connection close. */\n async handleClose(close: WebSocket.CloseEvent): Promise<void> {\n // gateway.debug(\"GW CLOSED\", { shardId, payload: event });\n\n this.stopHeartbeating()\n\n switch (close.code) {\n case ShardSocketCloseCodes.TestingFinished: {\n this.state = ShardState.Offline\n this.events.disconnected?.(this)\n\n return\n }\n // On these codes a manual start will be done.\n case ShardSocketCloseCodes.Shutdown:\n case ShardSocketCloseCodes.ReIdentifying:\n case ShardSocketCloseCodes.Resharded:\n case ShardSocketCloseCodes.ResumeClosingOldConnection:\n case ShardSocketCloseCodes.ZombiedConnection: {\n this.state = ShardState.Disconnected\n this.events.disconnected?.(this)\n\n // gateway.debug(\"GW CLOSED_RECONNECT\", { shardId, payload: event });\n return\n }\n // Gateway connection closes which require a new identify.\n case GatewayCloseEventCodes.UnknownOpcode:\n case GatewayCloseEventCodes.NotAuthenticated:\n case GatewayCloseEventCodes.InvalidSeq:\n case GatewayCloseEventCodes.RateLimited:\n case GatewayCloseEventCodes.SessionTimedOut: {\n logger.debug(`[Shard] Gateway connection closing requiring re-identify. Code: ${close.code}`)\n this.state = ShardState.Identifying\n this.events.disconnected?.(this)\n\n return await this.identify()\n }\n // When these codes are received something went really wrong.\n // On those we cannot start a reconnect attempt.\n case GatewayCloseEventCodes.AuthenticationFailed:\n case GatewayCloseEventCodes.InvalidShard:\n case GatewayCloseEventCodes.ShardingRequired:\n case GatewayCloseEventCodes.InvalidApiVersion:\n case GatewayCloseEventCodes.InvalidIntents:\n case GatewayCloseEventCodes.DisallowedIntents: {\n this.state = ShardState.Offline\n this.events.disconnected?.(this)\n\n throw new Error(close.reason || 'Discord gave no reason! GG! You broke Discord!')\n }\n // Gateway connection closes on which a resume is allowed.\n case GatewayCloseEventCodes.UnknownError:\n case GatewayCloseEventCodes.DecodeError:\n case GatewayCloseEventCodes.AlreadyAuthenticated:\n default: {\n logger.info(`[Shard] closed shard #${this.id}. Resuming...`)\n this.state = ShardState.Resuming\n this.events.disconnected?.(this)\n\n return await this.resume()\n }\n }\n }\n\n /** Handles a incoming gateway packet. */\n async handleDiscordPacket(packet: DiscordGatewayPayload): Promise<void> {\n // Edge case start: https://github.com/discordeno/discordeno/issues/2311\n this.heart.lastAck = Date.now()\n // Manually calculating the round trip time for users who need it.\n if (this.heart.lastBeat && !this.heart.acknowledged) {\n this.heart.rtt = this.heart.lastAck - this.heart.lastBeat\n }\n this.heart.acknowledged = true\n // Edge case end!\n\n switch (packet.op) {\n case GatewayOpcodes.Heartbeat: {\n // TODO: can this actually happen\n if (!this.isOpen()) return\n\n this.heart.lastBeat = Date.now()\n // Discord randomly sends this requiring an immediate heartbeat back.\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n this.events.heartbeat?.(this)\n\n break\n }\n case GatewayOpcodes.Hello: {\n const interval = (packet.d as DiscordHello).heartbeat_interval\n logger.debug(`[Gateway] Hello on Shard #${this.id}`)\n this.startHeartbeating(interval)\n\n if (this.state !== ShardState.Resuming) {\n const currentQueue = [...this.bucket.queue]\n // HELLO has been send on a non resume action.\n // This means that the shard starts a new session,\n // therefore the rate limit interval has been reset too.\n this.bucket = new LeakyBucket({\n max: this.calculateSafeRequests(),\n refillInterval: 60000,\n refillAmount: this.calculateSafeRequests(),\n })\n\n // Queue should not be lost on a re-identify.\n this.bucket.queue.unshift(...currentQueue)\n }\n\n this.events.hello?.(this)\n\n break\n }\n case GatewayOpcodes.HeartbeatACK: {\n this.events.heartbeatAck?.(this)\n\n break\n }\n case GatewayOpcodes.Reconnect: {\n // gateway.debug(\"GW RECONNECT\", { shardId });\n\n this.events.requestedReconnect?.(this)\n\n await this.resume()\n\n break\n }\n case GatewayOpcodes.InvalidSession: {\n const resumable = packet.d as boolean\n logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with resumeable as ${resumable.toString()}`)\n\n this.events.invalidSession?.(this, resumable)\n\n // We need to wait for a random amount of time between 1 and 5\n // Reference: https://discord.com/developers/docs/topics/gateway#resuming\n await delay(Math.floor((Math.random() * 4 + 1) * 1000))\n\n this.resolves.get('INVALID_SESSION')?.(packet)\n this.resolves.delete('INVALID_SESSION')\n\n // When resumable is false we need to re-identify\n if (!resumable) {\n await this.requestIdentify()\n\n break\n }\n\n // The session is invalid but apparently it is resumable\n await this.resume()\n\n break\n }\n }\n\n if (packet.t === 'RESUMED') {\n // gateway.debug(\"GW RESUMED\", { shardId });\n\n this.state = ShardState.Connected\n this.events.resumed?.(this)\n\n // Continue the requests which have been queued since the shard went offline.\n this.offlineSendQueue.map((resolve) => resolve())\n\n this.resolves.get('RESUMED')?.(packet)\n this.resolves.delete('RESUMED')\n } else if (packet.t === 'READY') {\n // Important for future resumes.\n\n const payload = packet.d as DiscordReady\n\n this.resumeGatewayUrl = payload.resume_gateway_url\n\n this.sessionId = payload.session_id\n this.state = ShardState.Connected\n\n // Continue the requests which have been queued since the shard went offline.\n // Important when this is a re-identify\n this.offlineSendQueue.map((resolve) => resolve())\n\n this.resolves.get('READY')?.(packet)\n this.resolves.delete('READY')\n }\n\n // Update the sequence number if it is present\n // `s` can be either `null` or a `number`.\n // In order to prevent update misses when `s` is `0` we check against null.\n if (packet.s !== null) {\n this.previousSequenceNumber = packet.s\n }\n\n this.forwardToBot(packet)\n }\n\n forwardToBot(packet: DiscordGatewayPayload): void {\n // The necessary handling required for the Shards connection has been finished.\n // Now the event can be safely forwarded.\n this.events.message?.(this, camelize(packet))\n }\n\n /** Handle an incoming gateway message. */\n async handleMessage(message: WebSocket.MessageEvent): Promise<void> {\n let preProcessMessage = message.data\n\n // If message compression is enabled,\n // Discord might send zlib compressed payloads.\n if (this.gatewayConfig.compress && preProcessMessage instanceof Blob) {\n preProcessMessage = inflateSync(await preProcessMessage.arrayBuffer()).toString()\n }\n\n // Safeguard incase decompression failed to make a string.\n if (typeof preProcessMessage !== 'string') return\n\n return await this.handleDiscordPacket(JSON.parse(preProcessMessage) as DiscordGatewayPayload)\n }\n\n /**\n * Override in order to make the shards presence.\n * async in case devs create the presence based on eg. database values.\n * Passing the shard's id there to make it easier for the dev to use this function.\n */\n async makePresence(): Promise<BotStatusUpdate | undefined> {\n // eslint-disable-next-line no-useless-return\n return\n }\n\n /** This function communicates with the management process, in order to know whether its free to identify. When this function resolves, this means that the shard is allowed to send an identify payload to discord. */\n async requestIdentify(): Promise<void> {}\n\n /** This function communicates with the management process, in order to tell it can identify the next shard. */\n async shardIsReady(): Promise<void> {}\n\n /** Start sending heartbeat payloads to Discord in the provided interval. */\n startHeartbeating(interval: number): void {\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id}`)\n // If old heartbeast exist like after resume, clear the old ones.\n if (this.heart.intervalId) clearInterval(this.heart.intervalId)\n if (this.heart.timeoutId) clearTimeout(this.heart.timeoutId)\n\n this.heart.interval = interval\n\n // Only set the shard's state to `Unidentified`\n // if heartbeating has not been started due to an identify or resume action.\n if ([ShardState.Disconnected, ShardState.Offline].includes(this.state)) {\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} a`)\n this.state = ShardState.Unidentified\n }\n\n // The first heartbeat needs to be send with a random delay between `0` and `interval`\n // Using a `setTimeout(_, jitter)` here to accomplish that.\n // `Math.random()` can be `0` so we use `0.5` if this happens\n // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating\n const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5))\n this.heart.timeoutId = setTimeout(() => {\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} b`)\n if (!this.isOpen()) return\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} c ${this.previousSequenceNumber!}`)\n\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} d`)\n this.heart.lastBeat = Date.now()\n this.heart.acknowledged = false\n\n // After the random heartbeat jitter we can start a normal interval.\n this.heart.intervalId = setInterval(async () => {\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} e`)\n if (!this.isOpen()) return\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} f`)\n // gateway.debug(\"GW DEBUG\", `Running setInterval in heartbeat file. Shard: ${shardId}`);\n\n // gateway.debug(\"GW HEARTBEATING\", { shardId, shard: currentShard });\n\n // The Shard did not receive a heartbeat ACK from Discord in time,\n // therefore we have to assume that the connection has failed or got \"zombied\".\n // The Shard needs to start a re-identify action accordingly.\n // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack\n if (!this.heart.acknowledged) {\n logger.debug(`[Shard] Heartbeat not acknowledged for shard #${this.id}.`)\n this.close(ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection, did not receive an heartbeat ACK in time.')\n\n return await this.identify()\n }\n\n this.heart.acknowledged = false\n\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} g`)\n // Using a direct socket.send call here because heartbeat requests are reserved by us.\n this.socket?.send(\n JSON.stringify({\n op: GatewayOpcodes.Heartbeat,\n d: this.previousSequenceNumber,\n }),\n )\n logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} h`)\n\n this.heart.lastBeat = Date.now()\n\n this.events.heartbeat?.(this)\n }, this.heart.interval)\n }, jitter)\n }\n\n /** Stop the heartbeating process with discord. */\n stopHeartbeating(): void {\n // Clear the regular heartbeat interval.\n clearInterval(this.heart.intervalId)\n // It's possible that the Shard got closed before the first jittered heartbeat.\n // To go safe we should clear the related timeout too.\n clearTimeout(this.heart.timeoutId)\n }\n\n /**\n * Connects the bot user to a voice or stage channel.\n *\n * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.\n *\n * @param guildId - The ID of the guild the voice channel to leave is in.\n * @param channelId - The ID of the channel you want to join.\n *\n * @remarks\n * Requires the `CONNECT` permission.\n *\n * Fires a _Voice State Update_ gateway event.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}\n */\n async joinVoiceChannel(\n guildId: BigString,\n channelId: BigString,\n options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>,\n ): Promise<void> {\n logger.debug(`[Shard] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`)\n await this.send({\n op: GatewayOpcodes.VoiceStateUpdate,\n d: {\n guild_id: guildId.toString(),\n channel_id: channelId.toString(),\n self_mute: Boolean(options?.selfMute),\n self_deaf: options?.selfDeaf ?? true,\n },\n })\n }\n\n /**\n * Edits the bot status in all shards that this gateway manages.\n *\n * @param data The status data to set the bots status to.\n * @returns Promise<void>\n */\n async editBotStatus(data: StatusUpdate): Promise<void> {\n logger.debug(`[Shard] editBotStatus data: ${JSON.stringify(data)}`)\n await this.editShardStatus(data)\n }\n\n /**\n * Edits the bot's status on one shard.\n *\n * @param shardId The shard id to edit the status for.\n * @param data The status data to set the bots status to.\n * @returns Promise<void>\n */\n async editShardStatus(data: StatusUpdate): Promise<void> {\n logger.debug(`[Shard] editShardStatus shardId: ${this.id} -> data: ${JSON.stringify(data)}`)\n await this.send({\n op: GatewayOpcodes.PresenceUpdate,\n d: {\n since: null,\n afk: false,\n activities: data.activities,\n status: data.status,\n },\n })\n }\n\n /**\n * Fetches the list of members for a guild over the gateway.\n *\n * @param guildId - The ID of the guild to get the list of members for.\n * @param options - The parameters for the fetching of the members.\n *\n * @remarks\n * If requesting the entire member list:\n * - Requires the `GUILD_MEMBERS` intent.\n *\n * If requesting presences ({@link RequestGuildMembers.presences | presences} set to `true`):\n * - Requires the `GUILD_PRESENCES` intent.\n *\n * If requesting a prefix ({@link RequestGuildMembers.query | query} non-`undefined`):\n * - Returns a maximum of 100 members.\n *\n * If requesting a users by ID ({@link RequestGuildMembers.userIds | userIds} non-`undefined`):\n * - Returns a maximum of 100 members.\n *\n * Fires a _Guild Members Chunk_ gateway event for every 1000 members fetched.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members}\n */\n async requestMembers(guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>): Promise<Camelize<DiscordMember[]>> {\n // You can request 1 member without the intent\n // Check if intents is not 0 as proxy ws won't set intents in other instances\n if (this.connection.intents && (!options?.limit || options.limit > 1) && !(this.connection.intents & GatewayIntents.GuildMembers)) {\n throw new Error('MISSING_INTENT_GUILD_MEMBERS')\n }\n\n if (options?.userIds?.length) {\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`)\n options.limit = options.userIds.length\n }\n\n const nonce = `${guildId}-${Date.now()}`\n\n // Gateway does not require caching these requests so directly send and return\n if (!this.cache.requestMembers?.enabled) {\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> skipping cache -> options ${JSON.stringify(options)}`)\n await this.send({\n op: GatewayOpcodes.RequestGuildMembers,\n d: {\n guild_id: guildId.toString(),\n // If a query is provided use it, OR if a limit is NOT provided use \"\"\n query: options?.query ?? (options?.limit ? undefined : ''),\n limit: options?.limit ?? 0,\n presences: options?.presences ?? false,\n user_ids: options?.userIds?.map((id) => id.toString()),\n nonce,\n },\n })\n return []\n }\n\n return await new Promise((resolve) => {\n this.cache.requestMembers?.pending.set(nonce, { nonce, resolve, members: [] })\n\n logger.debug(`[Shard] requestMembers guildId: ${guildId} -> requesting members -> data: ${JSON.stringify(options)}`)\n this.send({\n op: GatewayOpcodes.RequestGuildMembers,\n d: {\n guild_id: guildId.toString(),\n // If a query is provided use it, OR if a limit is NOT provided use \"\"\n query: options?.query ?? (options?.limit ? undefined : ''),\n limit: options?.limit ?? 0,\n presences: options?.presences ?? false,\n user_ids: options?.userIds?.map((id) => id.toString()),\n nonce,\n },\n })\n })\n }\n\n /**\n * Leaves the voice channel the bot user is currently in.\n *\n * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.\n *\n * @param guildId - The ID of the guild the voice channel to leave is in.\n *\n * @remarks\n * Fires a _Voice State Update_ gateway event.\n *\n * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}\n */\n async leaveVoiceChannel(guildId: BigString): Promise<void> {\n logger.debug(`[Shard] leaveVoiceChannel guildId: ${guildId} Shard ${this.id}`)\n await this.send({\n op: GatewayOpcodes.VoiceStateUpdate,\n d: {\n guild_id: guildId.toString(),\n channel_id: null,\n self_mute: false,\n self_deaf: false,\n },\n })\n }\n}\n\nexport interface ShardCreateOptions {\n /** The shard id */\n id: number\n /** The connection details */\n connection: ShardGatewayConfig\n /** The event handlers for events on the shard. */\n events: ShardEvents\n /** The handler to request a space to make an identify request. */\n requestIdentify?: () => Promise<void>\n /** The handler to alert the gateway manager that this shard has received a READY event. */\n shardIsReady?: () => Promise<void>\n}\n\nexport default DiscordenoShard\n"],"names":["GatewayCloseEventCodes","GatewayIntents","GatewayOpcodes","Collection","LeakyBucket","camelize","delay","logger","inflateSync","WebSocket","ShardSocketCloseCodes","ShardState","DiscordenoShard","constructor","options","maxRequestsPerRateLimitTick","previousSequenceNumber","rateLimitResetInterval","state","Offline","resumeGatewayUrl","events","offlineSendQueue","resolves","Map","cache","requestMembers","enabled","pending","id","connection","heart","acknowledged","interval","requestIdentify","shardIsReady","bucket","max","calculateSafeRequests","refillAmount","refillInterval","gatewayConfig","connectionUrl","url","safeRequests","Math","ceil","checkOffline","highPriority","isOpen","Promise","resolve","unshift","push","close","code","reason","socket","readyState","OPEN","connect","Identifying","Resuming","includes","Connecting","connecting","URL","searchParams","set","version","toString","onerror","event","console","log","error","shardId","onclose","handleClose","onmessage","message","handleMessage","onopen","Unidentified","connected","identify","debug","ReIdentifying","identifying","send","op","Identify","d","token","compress","properties","intents","shard","totalShards","presence","makePresence","identified","delete","resume","ResumeClosingOldConnection","sessionId","Resume","session_id","seq","acquire","JSON","stringify","shutdown","Shutdown","stopHeartbeating","TestingFinished","disconnected","Resharded","ZombiedConnection","Disconnected","UnknownOpcode","NotAuthenticated","InvalidSeq","RateLimited","SessionTimedOut","AuthenticationFailed","InvalidShard","ShardingRequired","InvalidApiVersion","InvalidIntents","DisallowedIntents","Error","UnknownError","DecodeError","AlreadyAuthenticated","info","handleDiscordPacket","packet","lastAck","Date","now","lastBeat","rtt","Heartbeat","heartbeat","Hello","heartbeat_interval","startHeartbeating","currentQueue","queue","hello","HeartbeatACK","heartbeatAck","Reconnect","requestedReconnect","InvalidSession","resumable","invalidSession","floor","random","get","t","Connected","resumed","map","payload","resume_gateway_url","s","forwardToBot","preProcessMessage","data","Blob","arrayBuffer","parse","intervalId","clearInterval","timeoutId","clearTimeout","jitter","setTimeout","setInterval","joinVoiceChannel","guildId","channelId","VoiceStateUpdate","guild_id","channel_id","self_mute","Boolean","selfMute","self_deaf","selfDeaf","editBotStatus","editShardStatus","PresenceUpdate","since","afk","activities","status","limit","GuildMembers","userIds","length","nonce","RequestGuildMembers","query","undefined","presences","user_ids","members","leaveVoiceChannel"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discordeno/gateway",
|
|
3
|
-
"version": "19.0.0-next.
|
|
3
|
+
"version": "19.0.0-next.e2d86ea",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"test:test-type": "tsc --project tsconfig.test.json"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@discordeno/types": "19.0.0-next.
|
|
28
|
-
"@discordeno/utils": "19.0.0-next.
|
|
27
|
+
"@discordeno/types": "19.0.0-next.e2d86ea",
|
|
28
|
+
"@discordeno/utils": "19.0.0-next.e2d86ea",
|
|
29
29
|
"ws": "^8.13.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|