diff --git a/packages/discord.js/src/client/websocket/WebSocketManager.js b/packages/discord.js/src/client/websocket/WebSocketManager.js index 2648cbd76..66bdad65a 100644 --- a/packages/discord.js/src/client/websocket/WebSocketManager.js +++ b/packages/discord.js/src/client/websocket/WebSocketManager.js @@ -9,8 +9,8 @@ const WebSocketShard = require('./WebSocketShard'); const PacketHandlers = require('./handlers'); const { Error, ErrorCodes } = require('../../errors'); const Events = require('../../util/Events'); -const ShardEvents = require('../../util/ShardEvents'); const Status = require('../../util/Status'); +const WebSocketShardEvents = require('../../util/WebSocketShardEvents'); const BeforeReadyWhitelist = [ GatewayDispatchEvents.Ready, @@ -181,7 +181,7 @@ class WebSocketManager extends EventEmitter { this.shardQueue.delete(shard); if (!shard.eventsAttached) { - shard.on(ShardEvents.AllReady, unavailableGuilds => { + shard.on(WebSocketShardEvents.AllReady, unavailableGuilds => { /** * Emitted when a shard turns ready. * @event Client#shardReady @@ -194,7 +194,7 @@ class WebSocketManager extends EventEmitter { this.checkShardsReady(); }); - shard.on(ShardEvents.Close, event => { + shard.on(WebSocketShardEvents.Close, event => { if (event.code === 1_000 ? this.destroyed : event.code in unrecoverableErrorCodeMap) { /** * Emitted when a shard's WebSocket disconnects and will no longer reconnect. @@ -225,11 +225,11 @@ class WebSocketManager extends EventEmitter { this.reconnect(); }); - shard.on(ShardEvents.InvalidSession, () => { + shard.on(WebSocketShardEvents.InvalidSession, () => { this.client.emit(Events.ShardReconnecting, shard.id); }); - shard.on(ShardEvents.Destroyed, () => { + shard.on(WebSocketShardEvents.Destroyed, () => { this.debug('Shard was destroyed but no WebSocket connection was present! Reconnecting...', shard); this.client.emit(Events.ShardReconnecting, shard.id); diff --git a/packages/discord.js/src/client/websocket/WebSocketShard.js b/packages/discord.js/src/client/websocket/WebSocketShard.js index b3dd2c493..541ec0ca3 100644 --- a/packages/discord.js/src/client/websocket/WebSocketShard.js +++ b/packages/discord.js/src/client/websocket/WebSocketShard.js @@ -6,8 +6,8 @@ const { GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes } = require('di const WebSocket = require('../../WebSocket'); const Events = require('../../util/Events'); const IntentsBitField = require('../../util/IntentsBitField'); -const ShardEvents = require('../../util/ShardEvents'); const Status = require('../../util/Status'); +const WebSocketShardEvents = require('../../util/WebSocketShardEvents'); const STATUS_KEYS = Object.keys(Status); const CONNECTION_STATE = Object.keys(WebSocket.WebSocket); @@ -202,11 +202,11 @@ class WebSocketShard extends EventEmitter { return new Promise((resolve, reject) => { const cleanup = () => { - this.removeListener(ShardEvents.Close, onClose); - this.removeListener(ShardEvents.Ready, onReady); - this.removeListener(ShardEvents.Resumed, onResumed); - this.removeListener(ShardEvents.InvalidSession, onInvalidOrDestroyed); - this.removeListener(ShardEvents.Destroyed, onInvalidOrDestroyed); + this.removeListener(WebSocketShardEvents.Close, onClose); + this.removeListener(WebSocketShardEvents.Ready, onReady); + this.removeListener(WebSocketShardEvents.Resumed, onResumed); + this.removeListener(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed); + this.removeListener(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed); }; const onReady = () => { @@ -230,11 +230,11 @@ class WebSocketShard extends EventEmitter { reject(); }; - this.once(ShardEvents.Ready, onReady); - this.once(ShardEvents.Resumed, onResumed); - this.once(ShardEvents.Close, onClose); - this.once(ShardEvents.InvalidSession, onInvalidOrDestroyed); - this.once(ShardEvents.Destroyed, onInvalidOrDestroyed); + this.once(WebSocketShardEvents.Ready, onReady); + this.once(WebSocketShardEvents.Resumed, onResumed); + this.once(WebSocketShardEvents.Close, onClose); + this.once(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed); + this.once(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed); if (this.connection?.readyState === WebSocket.OPEN) { this.debug('An open connection was found, attempting an immediate identify.'); @@ -395,7 +395,7 @@ class WebSocketShard extends EventEmitter { * @event WebSocketShard#close * @param {CloseEvent} event The received event */ - this.emit(ShardEvents.Close, event); + this.emit(WebSocketShardEvents.Close, event); } /** * Called whenever a packet is received. @@ -414,7 +414,7 @@ class WebSocketShard extends EventEmitter { * Emitted when the shard receives the READY payload and is now waiting for guilds * @event WebSocketShard#ready */ - this.emit(ShardEvents.Ready); + this.emit(WebSocketShardEvents.Ready); this.sessionId = packet.d.session_id; this.expectedGuilds = new Set(packet.d.guilds.map(d => d.id)); @@ -428,7 +428,7 @@ class WebSocketShard extends EventEmitter { * Emitted when the shard resumes successfully * @event WebSocketShard#resumed */ - this.emit(ShardEvents.Resumed); + this.emit(WebSocketShardEvents.Resumed); this.status = Status.Ready; const replayed = packet.s - this.closeSequence; @@ -469,7 +469,7 @@ class WebSocketShard extends EventEmitter { * Emitted when the session has been invalidated. * @event WebSocketShard#invalidSession */ - this.emit(ShardEvents.InvalidSession); + this.emit(WebSocketShardEvents.InvalidSession); break; case GatewayOpcodes.HeartbeatAck: this.ackHeartbeat(); @@ -509,7 +509,7 @@ class WebSocketShard extends EventEmitter { * @event WebSocketShard#allReady * @param {?Set} unavailableGuilds Set of unavailable guilds, if any */ - this.emit(ShardEvents.AllReady); + this.emit(WebSocketShardEvents.AllReady); return; } const hasGuildsIntent = new IntentsBitField(this.manager.client.options.intents).has(GatewayIntentBits.Guilds); @@ -533,7 +533,7 @@ class WebSocketShard extends EventEmitter { this.status = Status.Ready; - this.emit(ShardEvents.AllReady, this.expectedGuilds); + this.emit(WebSocketShardEvents.AllReady, this.expectedGuilds); }, hasGuildsIntent ? waitGuildTimeout : 0, ).unref(); @@ -878,7 +878,7 @@ class WebSocketShard extends EventEmitter { * @private * @event WebSocketShard#destroyed */ - this.emit(ShardEvents.Destroyed); + this.emit(WebSocketShardEvents.Destroyed); } } diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index e4befba11..00fae4a3b 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -42,6 +42,7 @@ exports.SystemChannelFlagsBitField = require('./util/SystemChannelFlagsBitField' exports.ThreadMemberFlagsBitField = require('./util/ThreadMemberFlagsBitField'); exports.UserFlagsBitField = require('./util/UserFlagsBitField'); __exportStar(require('./util/Util.js'), exports); +exports.WebSocketShardEvents = require('./util/WebSocketShardEvents'); exports.version = require('../package.json').version; // Managers diff --git a/packages/discord.js/src/sharding/Shard.js b/packages/discord.js/src/sharding/Shard.js index a0833c5fe..c8e279117 100644 --- a/packages/discord.js/src/sharding/Shard.js +++ b/packages/discord.js/src/sharding/Shard.js @@ -6,6 +6,7 @@ const process = require('node:process'); const { setTimeout, clearTimeout } = require('node:timers'); const { setTimeout: sleep } = require('node:timers/promises'); const { Error, ErrorCodes } = require('../errors'); +const ShardEvents = require('../util/ShardEvents'); const { makeError, makePlainError } = require('../util/Util'); let childProcess = null; let Worker = null; @@ -135,7 +136,7 @@ class Shard extends EventEmitter { * @event Shard#spawn * @param {ChildProcess|Worker} process Child process/worker that was created */ - this.emit('spawn', child); + this.emit(ShardEvents.Spawn, child); if (timeout === -1 || timeout === Infinity) return Promise.resolve(child); return new Promise((resolve, reject) => { @@ -327,7 +328,7 @@ class Shard extends EventEmitter { * Emitted upon the shard's {@link Client#event:shardReady} event. * @event Shard#ready */ - this.emit('ready'); + this.emit(ShardEvents.Ready); return; } @@ -338,7 +339,7 @@ class Shard extends EventEmitter { * Emitted upon the shard's {@link Client#event:shardDisconnect} event. * @event Shard#disconnect */ - this.emit('disconnect'); + this.emit(ShardEvents.Disconnect); return; } @@ -349,7 +350,7 @@ class Shard extends EventEmitter { * Emitted upon the shard's {@link Client#event:shardReconnecting} event. * @event Shard#reconnecting */ - this.emit('reconnecting'); + this.emit(ShardEvents.Reconnecting); return; } @@ -388,7 +389,7 @@ class Shard extends EventEmitter { * @event Shard#message * @param {*} message Message that was received */ - this.emit('message', message); + this.emit(ShardEvents.Message, message); } /** @@ -404,7 +405,7 @@ class Shard extends EventEmitter { * @event Shard#death * @param {ChildProcess|Worker} process Child process/worker that exited */ - this.emit('death', this.process ?? this.worker); + this.emit(ShardEvents.Death, this.process ?? this.worker); this.ready = false; this.process = null; @@ -412,7 +413,7 @@ class Shard extends EventEmitter { this._evals.clear(); this._fetches.clear(); - if (respawn) this.spawn(timeout).catch(err => this.emit('error', err)); + if (respawn) this.spawn(timeout).catch(err => this.emit(ShardEvents.Error, err)); } /** diff --git a/packages/discord.js/src/util/ShardEvents.js b/packages/discord.js/src/util/ShardEvents.js index 5f9e3ad61..8da682266 100644 --- a/packages/discord.js/src/util/ShardEvents.js +++ b/packages/discord.js/src/util/ShardEvents.js @@ -2,12 +2,13 @@ /** * @typedef {Object} ShardEvents - * @property {string} Close close - * @property {string} Destroyed destroyed - * @property {string} InvalidSession invalidSession + * @property {string} Death death + * @property {string} Disconnect disconnect + * @property {string} Error error + * @property {string} Message message * @property {string} Ready ready - * @property {string} Resumed resumed - * @property {string} AllReady allReady + * @property {string} Reconnecting reconnecting + * @property {string} Spawn spawn */ // JSDoc for IntelliSense purposes @@ -16,10 +17,11 @@ * @ignore */ module.exports = { - Close: 'close', - Destroyed: 'destroyed', - InvalidSession: 'invalidSession', + Death: 'death', + Disconnect: 'disconnect', + Error: 'error', + Message: 'message', Ready: 'ready', - Resumed: 'resumed', - AllReady: 'allReady', + Reconnecting: 'reconnecting', + Spawn: 'spawn', }; diff --git a/packages/discord.js/src/util/WebSocketShardEvents.js b/packages/discord.js/src/util/WebSocketShardEvents.js new file mode 100644 index 000000000..81e05f2c4 --- /dev/null +++ b/packages/discord.js/src/util/WebSocketShardEvents.js @@ -0,0 +1,25 @@ +'use strict'; + +/** + * @typedef {Object} WebSocketShardEvents + * @property {string} Close close + * @property {string} Destroyed destroyed + * @property {string} InvalidSession invalidSession + * @property {string} Ready ready + * @property {string} Resumed resumed + * @property {string} AllReady allReady + */ + +// JSDoc for IntelliSense purposes +/** + * @type {WebSocketShardEvents} + * @ignore + */ +module.exports = { + Close: 'close', + Destroyed: 'destroyed', + InvalidSession: 'invalidSession', + Ready: 'ready', + Resumed: 'resumed', + AllReady: 'allReady', +}; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index d344e9eee..bb68bdb4d 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -2183,13 +2183,13 @@ export class SelectMenuInteraction extends } export interface ShardEventTypes { - spawn: [process: ChildProcess | Worker]; death: [process: ChildProcess | Worker]; disconnect: []; - ready: []; - reconnecting: []; error: [error: Error]; message: [message: any]; + ready: []; + reconnecting: []; + spawn: [process: ChildProcess | Worker]; } export class Shard extends EventEmitter { @@ -2852,7 +2852,7 @@ export class WebSocketManager extends EventEmitter { private triggerClientReady(): void; } -export interface WebSocketShardEvents { +export interface WebSocketShardEventTypes { ready: []; resumed: []; invalidSession: []; @@ -2913,14 +2913,14 @@ export class WebSocketShard extends EventEmitter { public send(data: unknown, important?: boolean): void; - public on( + public on( event: K, - listener: (...args: WebSocketShardEvents[K]) => Awaitable, + listener: (...args: WebSocketShardEventTypes[K]) => Awaitable, ): this; - public once( + public once( event: K, - listener: (...args: WebSocketShardEvents[K]) => Awaitable, + listener: (...args: WebSocketShardEventTypes[K]) => Awaitable, ): this; } @@ -4344,6 +4344,16 @@ export declare const Events: { }; export enum ShardEvents { + Death = 'death', + Disconnect = 'disconnect', + Error = 'error', + Message = 'message', + Ready = 'ready', + Reconnecting = 'reconnecting', + Spawn = 'spawn', +} + +export enum WebSocketShardEvents { Close = 'close', Destroyed = 'destroyed', InvalidSession = 'invalidSession', diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 385197860..a0e77af9d 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -102,7 +102,7 @@ import { InteractionResponseFields, ThreadChannelType, Events, - ShardEvents, + WebSocketShardEvents, Status, CategoryChannelChildManager, ActionRowData, @@ -129,6 +129,7 @@ import { AnyThreadChannel, ThreadMemberManager, CollectedMessageInteraction, + ShardEvents, } from '.'; import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd'; import { @@ -1099,7 +1100,8 @@ reactionCollector.on('dispose', (...args) => { // Make sure the properties are typed correctly, and that no backwards properties // (K -> V and V -> K) exist: expectAssignable<'messageCreate'>(Events.MessageCreate); -expectAssignable<'close'>(ShardEvents.Close); +expectAssignable<'close'>(WebSocketShardEvents.Close); +expectAssignable<'death'>(ShardEvents.Death); expectAssignable<1>(Status.Connecting); declare const applicationCommandData: ApplicationCommandData;