refactor: make ShardEvents the events of Shard (#8185)

This commit is contained in:
Almeida
2022-07-03 17:04:19 +01:00
committed by GitHub
parent 31d5930464
commit c5750d59f5
8 changed files with 91 additions and 50 deletions

View File

@@ -9,8 +9,8 @@ const WebSocketShard = require('./WebSocketShard');
const PacketHandlers = require('./handlers'); const PacketHandlers = require('./handlers');
const { Error, ErrorCodes } = require('../../errors'); const { Error, ErrorCodes } = require('../../errors');
const Events = require('../../util/Events'); const Events = require('../../util/Events');
const ShardEvents = require('../../util/ShardEvents');
const Status = require('../../util/Status'); const Status = require('../../util/Status');
const WebSocketShardEvents = require('../../util/WebSocketShardEvents');
const BeforeReadyWhitelist = [ const BeforeReadyWhitelist = [
GatewayDispatchEvents.Ready, GatewayDispatchEvents.Ready,
@@ -181,7 +181,7 @@ class WebSocketManager extends EventEmitter {
this.shardQueue.delete(shard); this.shardQueue.delete(shard);
if (!shard.eventsAttached) { if (!shard.eventsAttached) {
shard.on(ShardEvents.AllReady, unavailableGuilds => { shard.on(WebSocketShardEvents.AllReady, unavailableGuilds => {
/** /**
* Emitted when a shard turns ready. * Emitted when a shard turns ready.
* @event Client#shardReady * @event Client#shardReady
@@ -194,7 +194,7 @@ class WebSocketManager extends EventEmitter {
this.checkShardsReady(); this.checkShardsReady();
}); });
shard.on(ShardEvents.Close, event => { shard.on(WebSocketShardEvents.Close, event => {
if (event.code === 1_000 ? this.destroyed : event.code in unrecoverableErrorCodeMap) { if (event.code === 1_000 ? this.destroyed : event.code in unrecoverableErrorCodeMap) {
/** /**
* Emitted when a shard's WebSocket disconnects and will no longer reconnect. * Emitted when a shard's WebSocket disconnects and will no longer reconnect.
@@ -225,11 +225,11 @@ class WebSocketManager extends EventEmitter {
this.reconnect(); this.reconnect();
}); });
shard.on(ShardEvents.InvalidSession, () => { shard.on(WebSocketShardEvents.InvalidSession, () => {
this.client.emit(Events.ShardReconnecting, shard.id); 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.debug('Shard was destroyed but no WebSocket connection was present! Reconnecting...', shard);
this.client.emit(Events.ShardReconnecting, shard.id); this.client.emit(Events.ShardReconnecting, shard.id);

View File

@@ -6,8 +6,8 @@ const { GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes } = require('di
const WebSocket = require('../../WebSocket'); const WebSocket = require('../../WebSocket');
const Events = require('../../util/Events'); const Events = require('../../util/Events');
const IntentsBitField = require('../../util/IntentsBitField'); const IntentsBitField = require('../../util/IntentsBitField');
const ShardEvents = require('../../util/ShardEvents');
const Status = require('../../util/Status'); const Status = require('../../util/Status');
const WebSocketShardEvents = require('../../util/WebSocketShardEvents');
const STATUS_KEYS = Object.keys(Status); const STATUS_KEYS = Object.keys(Status);
const CONNECTION_STATE = Object.keys(WebSocket.WebSocket); const CONNECTION_STATE = Object.keys(WebSocket.WebSocket);
@@ -202,11 +202,11 @@ class WebSocketShard extends EventEmitter {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const cleanup = () => { const cleanup = () => {
this.removeListener(ShardEvents.Close, onClose); this.removeListener(WebSocketShardEvents.Close, onClose);
this.removeListener(ShardEvents.Ready, onReady); this.removeListener(WebSocketShardEvents.Ready, onReady);
this.removeListener(ShardEvents.Resumed, onResumed); this.removeListener(WebSocketShardEvents.Resumed, onResumed);
this.removeListener(ShardEvents.InvalidSession, onInvalidOrDestroyed); this.removeListener(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed);
this.removeListener(ShardEvents.Destroyed, onInvalidOrDestroyed); this.removeListener(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed);
}; };
const onReady = () => { const onReady = () => {
@@ -230,11 +230,11 @@ class WebSocketShard extends EventEmitter {
reject(); reject();
}; };
this.once(ShardEvents.Ready, onReady); this.once(WebSocketShardEvents.Ready, onReady);
this.once(ShardEvents.Resumed, onResumed); this.once(WebSocketShardEvents.Resumed, onResumed);
this.once(ShardEvents.Close, onClose); this.once(WebSocketShardEvents.Close, onClose);
this.once(ShardEvents.InvalidSession, onInvalidOrDestroyed); this.once(WebSocketShardEvents.InvalidSession, onInvalidOrDestroyed);
this.once(ShardEvents.Destroyed, onInvalidOrDestroyed); this.once(WebSocketShardEvents.Destroyed, onInvalidOrDestroyed);
if (this.connection?.readyState === WebSocket.OPEN) { if (this.connection?.readyState === WebSocket.OPEN) {
this.debug('An open connection was found, attempting an immediate identify.'); this.debug('An open connection was found, attempting an immediate identify.');
@@ -395,7 +395,7 @@ class WebSocketShard extends EventEmitter {
* @event WebSocketShard#close * @event WebSocketShard#close
* @param {CloseEvent} event The received event * @param {CloseEvent} event The received event
*/ */
this.emit(ShardEvents.Close, event); this.emit(WebSocketShardEvents.Close, event);
} }
/** /**
* Called whenever a packet is received. * 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 * Emitted when the shard receives the READY payload and is now waiting for guilds
* @event WebSocketShard#ready * @event WebSocketShard#ready
*/ */
this.emit(ShardEvents.Ready); this.emit(WebSocketShardEvents.Ready);
this.sessionId = packet.d.session_id; this.sessionId = packet.d.session_id;
this.expectedGuilds = new Set(packet.d.guilds.map(d => d.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 * Emitted when the shard resumes successfully
* @event WebSocketShard#resumed * @event WebSocketShard#resumed
*/ */
this.emit(ShardEvents.Resumed); this.emit(WebSocketShardEvents.Resumed);
this.status = Status.Ready; this.status = Status.Ready;
const replayed = packet.s - this.closeSequence; const replayed = packet.s - this.closeSequence;
@@ -469,7 +469,7 @@ class WebSocketShard extends EventEmitter {
* Emitted when the session has been invalidated. * Emitted when the session has been invalidated.
* @event WebSocketShard#invalidSession * @event WebSocketShard#invalidSession
*/ */
this.emit(ShardEvents.InvalidSession); this.emit(WebSocketShardEvents.InvalidSession);
break; break;
case GatewayOpcodes.HeartbeatAck: case GatewayOpcodes.HeartbeatAck:
this.ackHeartbeat(); this.ackHeartbeat();
@@ -509,7 +509,7 @@ class WebSocketShard extends EventEmitter {
* @event WebSocketShard#allReady * @event WebSocketShard#allReady
* @param {?Set<string>} unavailableGuilds Set of unavailable guilds, if any * @param {?Set<string>} unavailableGuilds Set of unavailable guilds, if any
*/ */
this.emit(ShardEvents.AllReady); this.emit(WebSocketShardEvents.AllReady);
return; return;
} }
const hasGuildsIntent = new IntentsBitField(this.manager.client.options.intents).has(GatewayIntentBits.Guilds); 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.status = Status.Ready;
this.emit(ShardEvents.AllReady, this.expectedGuilds); this.emit(WebSocketShardEvents.AllReady, this.expectedGuilds);
}, },
hasGuildsIntent ? waitGuildTimeout : 0, hasGuildsIntent ? waitGuildTimeout : 0,
).unref(); ).unref();
@@ -878,7 +878,7 @@ class WebSocketShard extends EventEmitter {
* @private * @private
* @event WebSocketShard#destroyed * @event WebSocketShard#destroyed
*/ */
this.emit(ShardEvents.Destroyed); this.emit(WebSocketShardEvents.Destroyed);
} }
} }

View File

@@ -42,6 +42,7 @@ exports.SystemChannelFlagsBitField = require('./util/SystemChannelFlagsBitField'
exports.ThreadMemberFlagsBitField = require('./util/ThreadMemberFlagsBitField'); exports.ThreadMemberFlagsBitField = require('./util/ThreadMemberFlagsBitField');
exports.UserFlagsBitField = require('./util/UserFlagsBitField'); exports.UserFlagsBitField = require('./util/UserFlagsBitField');
__exportStar(require('./util/Util.js'), exports); __exportStar(require('./util/Util.js'), exports);
exports.WebSocketShardEvents = require('./util/WebSocketShardEvents');
exports.version = require('../package.json').version; exports.version = require('../package.json').version;
// Managers // Managers

View File

@@ -6,6 +6,7 @@ const process = require('node:process');
const { setTimeout, clearTimeout } = require('node:timers'); const { setTimeout, clearTimeout } = require('node:timers');
const { setTimeout: sleep } = require('node:timers/promises'); const { setTimeout: sleep } = require('node:timers/promises');
const { Error, ErrorCodes } = require('../errors'); const { Error, ErrorCodes } = require('../errors');
const ShardEvents = require('../util/ShardEvents');
const { makeError, makePlainError } = require('../util/Util'); const { makeError, makePlainError } = require('../util/Util');
let childProcess = null; let childProcess = null;
let Worker = null; let Worker = null;
@@ -135,7 +136,7 @@ class Shard extends EventEmitter {
* @event Shard#spawn * @event Shard#spawn
* @param {ChildProcess|Worker} process Child process/worker that was created * @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); if (timeout === -1 || timeout === Infinity) return Promise.resolve(child);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -327,7 +328,7 @@ class Shard extends EventEmitter {
* Emitted upon the shard's {@link Client#event:shardReady} event. * Emitted upon the shard's {@link Client#event:shardReady} event.
* @event Shard#ready * @event Shard#ready
*/ */
this.emit('ready'); this.emit(ShardEvents.Ready);
return; return;
} }
@@ -338,7 +339,7 @@ class Shard extends EventEmitter {
* Emitted upon the shard's {@link Client#event:shardDisconnect} event. * Emitted upon the shard's {@link Client#event:shardDisconnect} event.
* @event Shard#disconnect * @event Shard#disconnect
*/ */
this.emit('disconnect'); this.emit(ShardEvents.Disconnect);
return; return;
} }
@@ -349,7 +350,7 @@ class Shard extends EventEmitter {
* Emitted upon the shard's {@link Client#event:shardReconnecting} event. * Emitted upon the shard's {@link Client#event:shardReconnecting} event.
* @event Shard#reconnecting * @event Shard#reconnecting
*/ */
this.emit('reconnecting'); this.emit(ShardEvents.Reconnecting);
return; return;
} }
@@ -388,7 +389,7 @@ class Shard extends EventEmitter {
* @event Shard#message * @event Shard#message
* @param {*} message Message that was received * @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 * @event Shard#death
* @param {ChildProcess|Worker} process Child process/worker that exited * @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.ready = false;
this.process = null; this.process = null;
@@ -412,7 +413,7 @@ class Shard extends EventEmitter {
this._evals.clear(); this._evals.clear();
this._fetches.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));
} }
/** /**

View File

@@ -2,12 +2,13 @@
/** /**
* @typedef {Object} ShardEvents * @typedef {Object} ShardEvents
* @property {string} Close close * @property {string} Death death
* @property {string} Destroyed destroyed * @property {string} Disconnect disconnect
* @property {string} InvalidSession invalidSession * @property {string} Error error
* @property {string} Message message
* @property {string} Ready ready * @property {string} Ready ready
* @property {string} Resumed resumed * @property {string} Reconnecting reconnecting
* @property {string} AllReady allReady * @property {string} Spawn spawn
*/ */
// JSDoc for IntelliSense purposes // JSDoc for IntelliSense purposes
@@ -16,10 +17,11 @@
* @ignore * @ignore
*/ */
module.exports = { module.exports = {
Close: 'close', Death: 'death',
Destroyed: 'destroyed', Disconnect: 'disconnect',
InvalidSession: 'invalidSession', Error: 'error',
Message: 'message',
Ready: 'ready', Ready: 'ready',
Resumed: 'resumed', Reconnecting: 'reconnecting',
AllReady: 'allReady', Spawn: 'spawn',
}; };

View File

@@ -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',
};

View File

@@ -2183,13 +2183,13 @@ export class SelectMenuInteraction<Cached extends CacheType = CacheType> extends
} }
export interface ShardEventTypes { export interface ShardEventTypes {
spawn: [process: ChildProcess | Worker];
death: [process: ChildProcess | Worker]; death: [process: ChildProcess | Worker];
disconnect: []; disconnect: [];
ready: [];
reconnecting: [];
error: [error: Error]; error: [error: Error];
message: [message: any]; message: [message: any];
ready: [];
reconnecting: [];
spawn: [process: ChildProcess | Worker];
} }
export class Shard extends EventEmitter { export class Shard extends EventEmitter {
@@ -2852,7 +2852,7 @@ export class WebSocketManager extends EventEmitter {
private triggerClientReady(): void; private triggerClientReady(): void;
} }
export interface WebSocketShardEvents { export interface WebSocketShardEventTypes {
ready: []; ready: [];
resumed: []; resumed: [];
invalidSession: []; invalidSession: [];
@@ -2913,14 +2913,14 @@ export class WebSocketShard extends EventEmitter {
public send(data: unknown, important?: boolean): void; public send(data: unknown, important?: boolean): void;
public on<K extends keyof WebSocketShardEvents>( public on<K extends keyof WebSocketShardEventTypes>(
event: K, event: K,
listener: (...args: WebSocketShardEvents[K]) => Awaitable<void>, listener: (...args: WebSocketShardEventTypes[K]) => Awaitable<void>,
): this; ): this;
public once<K extends keyof WebSocketShardEvents>( public once<K extends keyof WebSocketShardEventTypes>(
event: K, event: K,
listener: (...args: WebSocketShardEvents[K]) => Awaitable<void>, listener: (...args: WebSocketShardEventTypes[K]) => Awaitable<void>,
): this; ): this;
} }
@@ -4344,6 +4344,16 @@ export declare const Events: {
}; };
export enum ShardEvents { export enum ShardEvents {
Death = 'death',
Disconnect = 'disconnect',
Error = 'error',
Message = 'message',
Ready = 'ready',
Reconnecting = 'reconnecting',
Spawn = 'spawn',
}
export enum WebSocketShardEvents {
Close = 'close', Close = 'close',
Destroyed = 'destroyed', Destroyed = 'destroyed',
InvalidSession = 'invalidSession', InvalidSession = 'invalidSession',

View File

@@ -102,7 +102,7 @@ import {
InteractionResponseFields, InteractionResponseFields,
ThreadChannelType, ThreadChannelType,
Events, Events,
ShardEvents, WebSocketShardEvents,
Status, Status,
CategoryChannelChildManager, CategoryChannelChildManager,
ActionRowData, ActionRowData,
@@ -129,6 +129,7 @@ import {
AnyThreadChannel, AnyThreadChannel,
ThreadMemberManager, ThreadMemberManager,
CollectedMessageInteraction, CollectedMessageInteraction,
ShardEvents,
} from '.'; } from '.';
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd'; import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
import { import {
@@ -1099,7 +1100,8 @@ reactionCollector.on('dispose', (...args) => {
// Make sure the properties are typed correctly, and that no backwards properties // Make sure the properties are typed correctly, and that no backwards properties
// (K -> V and V -> K) exist: // (K -> V and V -> K) exist:
expectAssignable<'messageCreate'>(Events.MessageCreate); expectAssignable<'messageCreate'>(Events.MessageCreate);
expectAssignable<'close'>(ShardEvents.Close); expectAssignable<'close'>(WebSocketShardEvents.Close);
expectAssignable<'death'>(ShardEvents.Death);
expectAssignable<1>(Status.Connecting); expectAssignable<1>(Status.Connecting);
declare const applicationCommandData: ApplicationCommandData; declare const applicationCommandData: ApplicationCommandData;