refactor(ws): event layout (#10376)

* refactor(ws): event layout

BREAKING CHANGE: All events now emit shard id as its own param

* fix: worker event forwarding

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
DD
2024-07-24 21:40:34 +03:00
committed by GitHub
parent fcd35ea2e7
commit bf6761a44a
7 changed files with 137 additions and 134 deletions

View File

@@ -89,87 +89,83 @@ export interface IntrinsicProps {
shardId: number; shardId: number;
} }
export interface WithIntrinsicProps<Data> extends IntrinsicProps { export interface ToEventProps<Data> extends IntrinsicProps {
data: Data; data: Data;
} }
export interface MappedEvents { export interface MappedEvents {
[GatewayDispatchEvents.ApplicationCommandPermissionsUpdate]: [ [GatewayDispatchEvents.ApplicationCommandPermissionsUpdate]: [
WithIntrinsicProps<GatewayApplicationCommandPermissionsUpdateDispatchData>, ToEventProps<GatewayApplicationCommandPermissionsUpdateDispatchData>,
]; ];
[GatewayDispatchEvents.AutoModerationActionExecution]: [ [GatewayDispatchEvents.AutoModerationActionExecution]: [
WithIntrinsicProps<GatewayAutoModerationActionExecutionDispatchData>, ToEventProps<GatewayAutoModerationActionExecutionDispatchData>,
];
[GatewayDispatchEvents.AutoModerationRuleCreate]: [WithIntrinsicProps<GatewayAutoModerationRuleCreateDispatchData>];
[GatewayDispatchEvents.AutoModerationRuleDelete]: [WithIntrinsicProps<GatewayAutoModerationRuleDeleteDispatchData>];
[GatewayDispatchEvents.AutoModerationRuleUpdate]: [WithIntrinsicProps<GatewayAutoModerationRuleUpdateDispatchData>];
[GatewayDispatchEvents.ChannelCreate]: [WithIntrinsicProps<GatewayChannelCreateDispatchData>];
[GatewayDispatchEvents.ChannelDelete]: [WithIntrinsicProps<GatewayChannelDeleteDispatchData>];
[GatewayDispatchEvents.ChannelPinsUpdate]: [WithIntrinsicProps<GatewayChannelPinsUpdateDispatchData>];
[GatewayDispatchEvents.ChannelUpdate]: [WithIntrinsicProps<GatewayChannelUpdateDispatchData>];
[GatewayDispatchEvents.EntitlementCreate]: [WithIntrinsicProps<GatewayEntitlementCreateDispatchData>];
[GatewayDispatchEvents.EntitlementDelete]: [WithIntrinsicProps<GatewayEntitlementDeleteDispatchData>];
[GatewayDispatchEvents.EntitlementUpdate]: [WithIntrinsicProps<GatewayEntitlementUpdateDispatchData>];
[GatewayDispatchEvents.GuildAuditLogEntryCreate]: [WithIntrinsicProps<GatewayGuildAuditLogEntryCreateDispatchData>];
[GatewayDispatchEvents.GuildBanAdd]: [WithIntrinsicProps<GatewayGuildBanAddDispatchData>];
[GatewayDispatchEvents.GuildBanRemove]: [WithIntrinsicProps<GatewayGuildBanRemoveDispatchData>];
[GatewayDispatchEvents.GuildCreate]: [WithIntrinsicProps<GatewayGuildCreateDispatchData>];
[GatewayDispatchEvents.GuildDelete]: [WithIntrinsicProps<GatewayGuildDeleteDispatchData>];
[GatewayDispatchEvents.GuildEmojisUpdate]: [WithIntrinsicProps<GatewayGuildEmojisUpdateDispatchData>];
[GatewayDispatchEvents.GuildIntegrationsUpdate]: [WithIntrinsicProps<GatewayGuildIntegrationsUpdateDispatchData>];
[GatewayDispatchEvents.GuildMemberAdd]: [WithIntrinsicProps<GatewayGuildMemberAddDispatchData>];
[GatewayDispatchEvents.GuildMemberRemove]: [WithIntrinsicProps<GatewayGuildMemberRemoveDispatchData>];
[GatewayDispatchEvents.GuildMemberUpdate]: [WithIntrinsicProps<GatewayGuildMemberUpdateDispatchData>];
[GatewayDispatchEvents.GuildMembersChunk]: [WithIntrinsicProps<GatewayGuildMembersChunkDispatchData>];
[GatewayDispatchEvents.GuildRoleCreate]: [WithIntrinsicProps<GatewayGuildRoleCreateDispatchData>];
[GatewayDispatchEvents.GuildRoleDelete]: [WithIntrinsicProps<GatewayGuildRoleDeleteDispatchData>];
[GatewayDispatchEvents.GuildRoleUpdate]: [WithIntrinsicProps<GatewayGuildRoleUpdateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventCreate]: [WithIntrinsicProps<GatewayGuildScheduledEventCreateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventDelete]: [WithIntrinsicProps<GatewayGuildScheduledEventDeleteDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventUpdate]: [WithIntrinsicProps<GatewayGuildScheduledEventUpdateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventUserAdd]: [
WithIntrinsicProps<GatewayGuildScheduledEventUserAddDispatchData>,
]; ];
[GatewayDispatchEvents.AutoModerationRuleCreate]: [ToEventProps<GatewayAutoModerationRuleCreateDispatchData>];
[GatewayDispatchEvents.AutoModerationRuleDelete]: [ToEventProps<GatewayAutoModerationRuleDeleteDispatchData>];
[GatewayDispatchEvents.AutoModerationRuleUpdate]: [ToEventProps<GatewayAutoModerationRuleUpdateDispatchData>];
[GatewayDispatchEvents.ChannelCreate]: [ToEventProps<GatewayChannelCreateDispatchData>];
[GatewayDispatchEvents.ChannelDelete]: [ToEventProps<GatewayChannelDeleteDispatchData>];
[GatewayDispatchEvents.ChannelPinsUpdate]: [ToEventProps<GatewayChannelPinsUpdateDispatchData>];
[GatewayDispatchEvents.ChannelUpdate]: [ToEventProps<GatewayChannelUpdateDispatchData>];
[GatewayDispatchEvents.EntitlementCreate]: [ToEventProps<GatewayEntitlementCreateDispatchData>];
[GatewayDispatchEvents.EntitlementDelete]: [ToEventProps<GatewayEntitlementDeleteDispatchData>];
[GatewayDispatchEvents.EntitlementUpdate]: [ToEventProps<GatewayEntitlementUpdateDispatchData>];
[GatewayDispatchEvents.GuildAuditLogEntryCreate]: [ToEventProps<GatewayGuildAuditLogEntryCreateDispatchData>];
[GatewayDispatchEvents.GuildBanAdd]: [ToEventProps<GatewayGuildBanAddDispatchData>];
[GatewayDispatchEvents.GuildBanRemove]: [ToEventProps<GatewayGuildBanRemoveDispatchData>];
[GatewayDispatchEvents.GuildCreate]: [ToEventProps<GatewayGuildCreateDispatchData>];
[GatewayDispatchEvents.GuildDelete]: [ToEventProps<GatewayGuildDeleteDispatchData>];
[GatewayDispatchEvents.GuildEmojisUpdate]: [ToEventProps<GatewayGuildEmojisUpdateDispatchData>];
[GatewayDispatchEvents.GuildIntegrationsUpdate]: [ToEventProps<GatewayGuildIntegrationsUpdateDispatchData>];
[GatewayDispatchEvents.GuildMemberAdd]: [ToEventProps<GatewayGuildMemberAddDispatchData>];
[GatewayDispatchEvents.GuildMemberRemove]: [ToEventProps<GatewayGuildMemberRemoveDispatchData>];
[GatewayDispatchEvents.GuildMemberUpdate]: [ToEventProps<GatewayGuildMemberUpdateDispatchData>];
[GatewayDispatchEvents.GuildMembersChunk]: [ToEventProps<GatewayGuildMembersChunkDispatchData>];
[GatewayDispatchEvents.GuildRoleCreate]: [ToEventProps<GatewayGuildRoleCreateDispatchData>];
[GatewayDispatchEvents.GuildRoleDelete]: [ToEventProps<GatewayGuildRoleDeleteDispatchData>];
[GatewayDispatchEvents.GuildRoleUpdate]: [ToEventProps<GatewayGuildRoleUpdateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventCreate]: [ToEventProps<GatewayGuildScheduledEventCreateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventDelete]: [ToEventProps<GatewayGuildScheduledEventDeleteDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventUpdate]: [ToEventProps<GatewayGuildScheduledEventUpdateDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventUserAdd]: [ToEventProps<GatewayGuildScheduledEventUserAddDispatchData>];
[GatewayDispatchEvents.GuildScheduledEventUserRemove]: [ [GatewayDispatchEvents.GuildScheduledEventUserRemove]: [
WithIntrinsicProps<GatewayGuildScheduledEventUserRemoveDispatchData>, ToEventProps<GatewayGuildScheduledEventUserRemoveDispatchData>,
]; ];
[GatewayDispatchEvents.GuildStickersUpdate]: [WithIntrinsicProps<GatewayGuildStickersUpdateDispatchData>]; [GatewayDispatchEvents.GuildStickersUpdate]: [ToEventProps<GatewayGuildStickersUpdateDispatchData>];
[GatewayDispatchEvents.GuildUpdate]: [WithIntrinsicProps<GatewayGuildUpdateDispatchData>]; [GatewayDispatchEvents.GuildUpdate]: [ToEventProps<GatewayGuildUpdateDispatchData>];
[GatewayDispatchEvents.IntegrationCreate]: [WithIntrinsicProps<GatewayIntegrationCreateDispatchData>]; [GatewayDispatchEvents.IntegrationCreate]: [ToEventProps<GatewayIntegrationCreateDispatchData>];
[GatewayDispatchEvents.IntegrationDelete]: [WithIntrinsicProps<GatewayIntegrationDeleteDispatchData>]; [GatewayDispatchEvents.IntegrationDelete]: [ToEventProps<GatewayIntegrationDeleteDispatchData>];
[GatewayDispatchEvents.IntegrationUpdate]: [WithIntrinsicProps<GatewayIntegrationUpdateDispatchData>]; [GatewayDispatchEvents.IntegrationUpdate]: [ToEventProps<GatewayIntegrationUpdateDispatchData>];
[GatewayDispatchEvents.InteractionCreate]: [WithIntrinsicProps<GatewayInteractionCreateDispatchData>]; [GatewayDispatchEvents.InteractionCreate]: [ToEventProps<GatewayInteractionCreateDispatchData>];
[GatewayDispatchEvents.InviteCreate]: [WithIntrinsicProps<GatewayInviteCreateDispatchData>]; [GatewayDispatchEvents.InviteCreate]: [ToEventProps<GatewayInviteCreateDispatchData>];
[GatewayDispatchEvents.InviteDelete]: [WithIntrinsicProps<GatewayInviteDeleteDispatchData>]; [GatewayDispatchEvents.InviteDelete]: [ToEventProps<GatewayInviteDeleteDispatchData>];
[GatewayDispatchEvents.MessageCreate]: [WithIntrinsicProps<GatewayMessageCreateDispatchData>]; [GatewayDispatchEvents.MessageCreate]: [ToEventProps<GatewayMessageCreateDispatchData>];
[GatewayDispatchEvents.MessageDelete]: [WithIntrinsicProps<GatewayMessageDeleteDispatchData>]; [GatewayDispatchEvents.MessageDelete]: [ToEventProps<GatewayMessageDeleteDispatchData>];
[GatewayDispatchEvents.MessageDeleteBulk]: [WithIntrinsicProps<GatewayMessageDeleteBulkDispatchData>]; [GatewayDispatchEvents.MessageDeleteBulk]: [ToEventProps<GatewayMessageDeleteBulkDispatchData>];
[GatewayDispatchEvents.MessagePollVoteAdd]: [WithIntrinsicProps<GatewayMessagePollVoteDispatchData>]; [GatewayDispatchEvents.MessagePollVoteAdd]: [ToEventProps<GatewayMessagePollVoteDispatchData>];
[GatewayDispatchEvents.MessagePollVoteRemove]: [WithIntrinsicProps<GatewayMessagePollVoteDispatchData>]; [GatewayDispatchEvents.MessagePollVoteRemove]: [ToEventProps<GatewayMessagePollVoteDispatchData>];
[GatewayDispatchEvents.MessageReactionAdd]: [WithIntrinsicProps<GatewayMessageReactionAddDispatchData>]; [GatewayDispatchEvents.MessageReactionAdd]: [ToEventProps<GatewayMessageReactionAddDispatchData>];
[GatewayDispatchEvents.MessageReactionRemove]: [WithIntrinsicProps<GatewayMessageReactionRemoveDispatchData>]; [GatewayDispatchEvents.MessageReactionRemove]: [ToEventProps<GatewayMessageReactionRemoveDispatchData>];
[GatewayDispatchEvents.MessageReactionRemoveAll]: [WithIntrinsicProps<GatewayMessageReactionRemoveAllDispatchData>]; [GatewayDispatchEvents.MessageReactionRemoveAll]: [ToEventProps<GatewayMessageReactionRemoveAllDispatchData>];
[GatewayDispatchEvents.MessageReactionRemoveEmoji]: [ [GatewayDispatchEvents.MessageReactionRemoveEmoji]: [ToEventProps<GatewayMessageReactionRemoveEmojiDispatchData>];
WithIntrinsicProps<GatewayMessageReactionRemoveEmojiDispatchData>, [GatewayDispatchEvents.MessageUpdate]: [ToEventProps<GatewayMessageUpdateDispatchData>];
]; [GatewayDispatchEvents.PresenceUpdate]: [ToEventProps<GatewayPresenceUpdateDispatchData>];
[GatewayDispatchEvents.MessageUpdate]: [WithIntrinsicProps<GatewayMessageUpdateDispatchData>]; [GatewayDispatchEvents.Ready]: [ToEventProps<GatewayReadyDispatchData>];
[GatewayDispatchEvents.PresenceUpdate]: [WithIntrinsicProps<GatewayPresenceUpdateDispatchData>]; [GatewayDispatchEvents.Resumed]: [ToEventProps<never>];
[GatewayDispatchEvents.Ready]: [WithIntrinsicProps<GatewayReadyDispatchData>]; [GatewayDispatchEvents.StageInstanceCreate]: [ToEventProps<GatewayStageInstanceCreateDispatchData>];
[GatewayDispatchEvents.Resumed]: [WithIntrinsicProps<never>]; [GatewayDispatchEvents.StageInstanceDelete]: [ToEventProps<GatewayStageInstanceDeleteDispatchData>];
[GatewayDispatchEvents.StageInstanceCreate]: [WithIntrinsicProps<GatewayStageInstanceCreateDispatchData>]; [GatewayDispatchEvents.StageInstanceUpdate]: [ToEventProps<GatewayStageInstanceUpdateDispatchData>];
[GatewayDispatchEvents.StageInstanceDelete]: [WithIntrinsicProps<GatewayStageInstanceDeleteDispatchData>]; [GatewayDispatchEvents.ThreadCreate]: [ToEventProps<GatewayThreadCreateDispatchData>];
[GatewayDispatchEvents.StageInstanceUpdate]: [WithIntrinsicProps<GatewayStageInstanceUpdateDispatchData>]; [GatewayDispatchEvents.ThreadDelete]: [ToEventProps<GatewayThreadDeleteDispatchData>];
[GatewayDispatchEvents.ThreadCreate]: [WithIntrinsicProps<GatewayThreadCreateDispatchData>]; [GatewayDispatchEvents.ThreadListSync]: [ToEventProps<GatewayThreadListSyncDispatchData>];
[GatewayDispatchEvents.ThreadDelete]: [WithIntrinsicProps<GatewayThreadDeleteDispatchData>]; [GatewayDispatchEvents.ThreadMemberUpdate]: [ToEventProps<GatewayThreadMemberUpdateDispatchData>];
[GatewayDispatchEvents.ThreadListSync]: [WithIntrinsicProps<GatewayThreadListSyncDispatchData>]; [GatewayDispatchEvents.ThreadMembersUpdate]: [ToEventProps<GatewayThreadMembersUpdateDispatchData>];
[GatewayDispatchEvents.ThreadMemberUpdate]: [WithIntrinsicProps<GatewayThreadMemberUpdateDispatchData>]; [GatewayDispatchEvents.ThreadUpdate]: [ToEventProps<GatewayThreadUpdateDispatchData>];
[GatewayDispatchEvents.ThreadMembersUpdate]: [WithIntrinsicProps<GatewayThreadMembersUpdateDispatchData>]; [GatewayDispatchEvents.TypingStart]: [ToEventProps<GatewayTypingStartDispatchData>];
[GatewayDispatchEvents.ThreadUpdate]: [WithIntrinsicProps<GatewayThreadUpdateDispatchData>]; [GatewayDispatchEvents.UserUpdate]: [ToEventProps<GatewayUserUpdateDispatchData>];
[GatewayDispatchEvents.TypingStart]: [WithIntrinsicProps<GatewayTypingStartDispatchData>]; [GatewayDispatchEvents.VoiceServerUpdate]: [ToEventProps<GatewayVoiceServerUpdateDispatchData>];
[GatewayDispatchEvents.UserUpdate]: [WithIntrinsicProps<GatewayUserUpdateDispatchData>]; [GatewayDispatchEvents.VoiceStateUpdate]: [ToEventProps<GatewayVoiceStateUpdateDispatchData>];
[GatewayDispatchEvents.VoiceServerUpdate]: [WithIntrinsicProps<GatewayVoiceServerUpdateDispatchData>]; [GatewayDispatchEvents.WebhooksUpdate]: [ToEventProps<GatewayWebhooksUpdateDispatchData>];
[GatewayDispatchEvents.VoiceStateUpdate]: [WithIntrinsicProps<GatewayVoiceStateUpdateDispatchData>];
[GatewayDispatchEvents.WebhooksUpdate]: [WithIntrinsicProps<GatewayWebhooksUpdateDispatchData>];
} }
export interface ManagerShardEventsMap extends MappedEvents {} export interface ManagerShardEventsMap extends MappedEvents {}
@@ -199,12 +195,9 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
this.gateway = gateway; this.gateway = gateway;
this.api = new API(rest); this.api = new API(rest);
this.gateway.on(WebSocketShardEvents.Dispatch, ({ data: dispatch, shardId }) => { this.gateway.on(WebSocketShardEvents.Dispatch, (dispatch, shardId) => {
this.emit( // @ts-expect-error event props can't be resolved properly, but they are correct
dispatch.t, this.emit(dispatch.t, this.toEventProps(dispatch.d, shardId));
// @ts-expect-error event props can't be resolved properly, but they are correct
this.wrapIntrinsicProps(dispatch.d, shardId),
);
}); });
} }
@@ -342,7 +335,7 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
}); });
} }
private wrapIntrinsicProps<ObjectType>(obj: ObjectType, shardId: number): WithIntrinsicProps<ObjectType> { private toEventProps<ObjectType>(obj: ObjectType, shardId: number): ToEventProps<ObjectType> {
return { return {
api: this.api, api: this.api,
shardId, shardId,

View File

@@ -91,7 +91,7 @@ vi.mock('node:worker_threads', async () => {
op: WorkerReceivePayloadOp.Event, op: WorkerReceivePayloadOp.Event,
shardId: message.shardId, shardId: message.shardId,
event: WebSocketShardEvents.Dispatch, event: WebSocketShardEvents.Dispatch,
data: memberChunkData, data: [memberChunkData],
}; };
this.emit('message', response); this.emit('message', response);
@@ -204,10 +204,13 @@ test('spawn, connect, send a message, session info, and destroy', async () => {
}; };
await manager.send(0, payload); await manager.send(0, payload);
expect(mockSend).toHaveBeenCalledWith(0, payload); expect(mockSend).toHaveBeenCalledWith(0, payload);
expect(managerEmitSpy).toHaveBeenCalledWith(WebSocketShardEvents.Dispatch, { expect(managerEmitSpy).toHaveBeenCalledWith(
...memberChunkData, WebSocketShardEvents.Dispatch,
shardId: 0, {
}); ...memberChunkData,
},
0,
);
expect(mockRetrieveSessionInfo).toHaveBeenCalledWith(0); expect(mockRetrieveSessionInfo).toHaveBeenCalledWith(0);
expect(mockUpdateSessionInfo).toHaveBeenCalledWith(0, { ...sessionInfo, sequence: sessionInfo.sequence + 1 }); expect(mockUpdateSessionInfo).toHaveBeenCalledWith(0, { ...sessionInfo, sequence: sessionInfo.sequence + 1 });

View File

@@ -28,8 +28,8 @@ export class SimpleShardingStrategy implements IShardingStrategy {
const strategy = new SimpleContextFetchingStrategy(this.manager, strategyOptions); const strategy = new SimpleContextFetchingStrategy(this.manager, strategyOptions);
const shard = new WebSocketShard(strategy, shardId); const shard = new WebSocketShard(strategy, shardId);
for (const event of Object.values(WebSocketShardEvents)) { for (const event of Object.values(WebSocketShardEvents)) {
// @ts-expect-error: Intentional // @ts-expect-error Event props can't be resolved properly, but they are correct
shard.on(event, (payload) => this.manager.emit(event, { ...payload, shardId })); shard.on(event, (...args) => this.manager.emit(event, ...args, shardId));
} }
this.shards.set(shardId, shard); this.shards.set(shardId, shard);

View File

@@ -48,7 +48,7 @@ export enum WorkerReceivePayloadOp {
export type WorkerReceivePayload = export type WorkerReceivePayload =
// Can't seem to get a type-safe union based off of the event, so I'm sadly leaving data as any for now // Can't seem to get a type-safe union based off of the event, so I'm sadly leaving data as any for now
| { data: any; event: WebSocketShardEvents; op: WorkerReceivePayloadOp.Event; shardId: number } | { data: any[]; event: WebSocketShardEvents; op: WorkerReceivePayloadOp.Event; shardId: number }
| { nonce: number; op: WorkerReceivePayloadOp.CancelIdentify } | { nonce: number; op: WorkerReceivePayloadOp.CancelIdentify }
| { nonce: number; op: WorkerReceivePayloadOp.FetchStatusResponse; status: WebSocketShardStatus } | { nonce: number; op: WorkerReceivePayloadOp.FetchStatusResponse; status: WebSocketShardStatus }
| { nonce: number; op: WorkerReceivePayloadOp.RetrieveSessionInfo; shardId: number } | { nonce: number; op: WorkerReceivePayloadOp.RetrieveSessionInfo; shardId: number }
@@ -293,7 +293,8 @@ export class WorkerShardingStrategy implements IShardingStrategy {
} }
case WorkerReceivePayloadOp.Event: { case WorkerReceivePayloadOp.Event: {
this.manager.emit(payload.event, { ...payload.data, shardId: payload.shardId }); // @ts-expect-error Event props can't be resolved properly, but they are correct
this.manager.emit(payload.event, ...payload.data, payload.shardId);
break; break;
} }

View File

@@ -148,12 +148,11 @@ export class WorkerBootstrapper {
for (const shardId of this.data.shardIds) { for (const shardId of this.data.shardIds) {
const shard = new WebSocketShard(new WorkerContextFetchingStrategy(this.data), shardId); const shard = new WebSocketShard(new WorkerContextFetchingStrategy(this.data), shardId);
for (const event of options.forwardEvents ?? Object.values(WebSocketShardEvents)) { for (const event of options.forwardEvents ?? Object.values(WebSocketShardEvents)) {
// @ts-expect-error: Event types incompatible shard.on(event, (...args) => {
shard.on(event, (data) => {
const payload: WorkerReceivePayload = { const payload: WorkerReceivePayload = {
op: WorkerReceivePayloadOp.Event, op: WorkerReceivePayloadOp.Event,
event, event,
data, data: args,
shardId, shardId,
}; };
parentPort!.postMessage(payload); parentPort!.postMessage(payload);

View File

@@ -197,15 +197,15 @@ export interface CreateWebSocketManagerOptions
RequiredWebSocketManagerOptions {} RequiredWebSocketManagerOptions {}
export interface ManagerShardEventsMap { export interface ManagerShardEventsMap {
[WebSocketShardEvents.Closed]: [{ code: number; shardId: number }]; [WebSocketShardEvents.Closed]: [code: number, shardId: number];
[WebSocketShardEvents.Debug]: [payload: { message: string; shardId: number }]; [WebSocketShardEvents.Debug]: [message: string, shardId: number];
[WebSocketShardEvents.Dispatch]: [payload: { data: GatewayDispatchPayload; shardId: number }]; [WebSocketShardEvents.Dispatch]: [payload: GatewayDispatchPayload, shardId: number];
[WebSocketShardEvents.Error]: [payload: { error: Error; shardId: number }]; [WebSocketShardEvents.Error]: [error: Error, shardId: number];
[WebSocketShardEvents.Hello]: [{ shardId: number }]; [WebSocketShardEvents.Hello]: [shardId: number];
[WebSocketShardEvents.Ready]: [payload: { data: GatewayReadyDispatchData; shardId: number }]; [WebSocketShardEvents.Ready]: [data: GatewayReadyDispatchData, shardId: number];
[WebSocketShardEvents.Resumed]: [{ shardId: number }]; [WebSocketShardEvents.Resumed]: [shardId: number];
[WebSocketShardEvents.HeartbeatComplete]: [ [WebSocketShardEvents.HeartbeatComplete]: [
payload: { ackAt: number; heartbeatAt: number; latency: number; shardId: number }, stats: { ackAt: number; heartbeatAt: number; latency: number; shardId: number },
]; ];
} }

View File

@@ -60,14 +60,14 @@ export enum WebSocketShardDestroyRecovery {
} }
export interface WebSocketShardEventsMap { export interface WebSocketShardEventsMap {
[WebSocketShardEvents.Closed]: [{ code: number }]; [WebSocketShardEvents.Closed]: [code: number];
[WebSocketShardEvents.Debug]: [payload: { message: string }]; [WebSocketShardEvents.Debug]: [message: string];
[WebSocketShardEvents.Dispatch]: [payload: { data: GatewayDispatchPayload }]; [WebSocketShardEvents.Dispatch]: [payload: GatewayDispatchPayload];
[WebSocketShardEvents.Error]: [payload: { error: Error }]; [WebSocketShardEvents.Error]: [error: Error];
[WebSocketShardEvents.Hello]: []; [WebSocketShardEvents.Hello]: [];
[WebSocketShardEvents.Ready]: [payload: { data: GatewayReadyDispatchData }]; [WebSocketShardEvents.Ready]: [payload: GatewayReadyDispatchData];
[WebSocketShardEvents.Resumed]: []; [WebSocketShardEvents.Resumed]: [];
[WebSocketShardEvents.HeartbeatComplete]: [payload: { ackAt: number; heartbeatAt: number; latency: number }]; [WebSocketShardEvents.HeartbeatComplete]: [stats: { ackAt: number; heartbeatAt: number; latency: number }];
} }
export interface WebSocketShardDestroyOptions { export interface WebSocketShardDestroyOptions {
@@ -203,7 +203,7 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
}); });
inflate.on('error', (error) => { inflate.on('error', (error) => {
this.emit(WebSocketShardEvents.Error, { error }); this.emit(WebSocketShardEvents.Error, error);
}); });
this.nativeInflate = inflate; this.nativeInflate = inflate;
@@ -352,7 +352,7 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
this.connection.close(options.code, options.reason); this.connection.close(options.code, options.reason);
await promise; await promise;
this.emit(WebSocketShardEvents.Closed, { code: options.code }); this.emit(WebSocketShardEvents.Closed, options.code);
} }
// Lastly, remove the error event. // Lastly, remove the error event.
@@ -639,11 +639,10 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
this.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH); this.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);
if (this.zLibSyncInflate.err) { if (this.zLibSyncInflate.err) {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error( WebSocketShardEvents.Error,
`${this.zLibSyncInflate.err}${this.zLibSyncInflate.msg ? `: ${this.zLibSyncInflate.msg}` : ''}`, new Error(`${this.zLibSyncInflate.err}${this.zLibSyncInflate.msg ? `: ${this.zLibSyncInflate.msg}` : ''}`),
), );
});
} }
if (!flush) { if (!flush) {
@@ -692,7 +691,7 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
await this.strategy.updateSessionInfo(this.id, session); await this.strategy.updateSessionInfo(this.id, session);
this.emit(WebSocketShardEvents.Ready, { data: payload.d }); this.emit(WebSocketShardEvents.Ready, payload.d);
break; break;
} }
@@ -719,7 +718,7 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
]); ]);
} }
this.emit(WebSocketShardEvents.Dispatch, { data: payload }); this.emit(WebSocketShardEvents.Dispatch, payload);
break; break;
} }
@@ -798,11 +797,11 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
return; return;
} }
this.emit(WebSocketShardEvents.Error, { error }); this.emit(WebSocketShardEvents.Error, error);
} }
private async onClose(code: number) { private async onClose(code: number) {
this.emit(WebSocketShardEvents.Closed, { code }); this.emit(WebSocketShardEvents.Closed, code);
switch (code) { switch (code) {
case CloseCodes.Normal: { case CloseCodes.Normal: {
@@ -838,9 +837,11 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
} }
case GatewayCloseCodes.AuthenticationFailed: { case GatewayCloseCodes.AuthenticationFailed: {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error('Authentication failed'), WebSocketShardEvents.Error,
});
new Error('Authentication failed'),
);
return this.destroy({ code }); return this.destroy({ code });
} }
@@ -865,37 +866,43 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
} }
case GatewayCloseCodes.InvalidShard: { case GatewayCloseCodes.InvalidShard: {
this.emit(WebSocketShardEvents.Error, { this.emit(WebSocketShardEvents.Error, new Error('Invalid shard'));
error: new Error('Invalid shard'),
});
return this.destroy({ code }); return this.destroy({ code });
} }
case GatewayCloseCodes.ShardingRequired: { case GatewayCloseCodes.ShardingRequired: {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error('Sharding is required'), WebSocketShardEvents.Error,
});
new Error('Sharding is required'),
);
return this.destroy({ code }); return this.destroy({ code });
} }
case GatewayCloseCodes.InvalidAPIVersion: { case GatewayCloseCodes.InvalidAPIVersion: {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error('Used an invalid API version'), WebSocketShardEvents.Error,
});
new Error('Used an invalid API version'),
);
return this.destroy({ code }); return this.destroy({ code });
} }
case GatewayCloseCodes.InvalidIntents: { case GatewayCloseCodes.InvalidIntents: {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error('Used invalid intents'), WebSocketShardEvents.Error,
});
new Error('Used invalid intents'),
);
return this.destroy({ code }); return this.destroy({ code });
} }
case GatewayCloseCodes.DisallowedIntents: { case GatewayCloseCodes.DisallowedIntents: {
this.emit(WebSocketShardEvents.Error, { this.emit(
error: new Error('Used disallowed intents'), WebSocketShardEvents.Error,
});
new Error('Used disallowed intents'),
);
return this.destroy({ code }); return this.destroy({ code });
} }
@@ -916,6 +923,6 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
} }
private debug(messages: [string, ...string[]]) { private debug(messages: [string, ...string[]]) {
this.emit(WebSocketShardEvents.Debug, { message: messages.join('\n\t') }); this.emit(WebSocketShardEvents.Debug, messages.join('\n\t'));
} }
} }