@discordeno/gateway 19.0.0-next.f8afb94 → 19.0.0-next.f98bb9b

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 CHANGED
@@ -1,8 +1,7 @@
1
- import type { AtLeastOne, BigString, Camelize, DiscordGatewayPayload, DiscordMember, RequestGuildMembers } from '@discordeno/types';
2
- import { Collection, LeakyBucket } from '@discordeno/utils';
3
- import WebSocket from 'ws';
4
- import type { RequestMemberRequest } from './manager.js';
5
- import type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js';
1
+ import type { DiscordGatewayPayload } from '@discordeno/types';
2
+ import { LeakyBucket } from '@discordeno/utils';
3
+ import NodeWebSocket from 'ws';
4
+ import type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest } from './types.js';
6
5
  import { ShardState } from './types.js';
7
6
  export declare class DiscordenoShard {
8
7
  /** The id of the shard */
@@ -20,7 +19,7 @@ export declare class DiscordenoShard {
20
19
  /** Current session id of the shard if present. */
21
20
  sessionId?: string;
22
21
  /** This contains the WebSocket connection to Discord, if currently connected. */
23
- socket?: WebSocket;
22
+ socket?: NodeWebSocket;
24
23
  /** Current internal state of the this. */
25
24
  state: ShardState;
26
25
  /** The url provided by discord to use when resuming a connection for this this. */
@@ -33,22 +32,10 @@ export declare class DiscordenoShard {
33
32
  resolves: Map<"READY" | "RESUMED" | "INVALID_SESSION", (payload: DiscordGatewayPayload) => void>;
34
33
  /** Shard bucket. Only access this if you know what you are doing. Bucket for handling shard request rate limits. */
35
34
  bucket: LeakyBucket;
36
- /** This managers cache related settings. */
37
- cache: {
38
- requestMembers: {
39
- /**
40
- * Whether or not request member requests should be cached.
41
- * @default false
42
- */
43
- enabled: boolean;
44
- /** The pending requests. */
45
- pending: Collection<string, RequestMemberRequest>;
46
- };
47
- };
48
35
  constructor(options: ShardCreateOptions);
49
36
  /** The gateway configuration which is used to connect to Discord. */
50
37
  get gatewayConfig(): ShardGatewayConfig;
51
- /** 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. */
38
+ /** The url to connect to. Initially this is the discord gateway url, and then is switched to resume gateway url once a READY is received. */
52
39
  get connectionUrl(): string;
53
40
  /** 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. */
54
41
  calculateSafeRequests(): number;
@@ -70,12 +57,12 @@ export declare class DiscordenoShard {
70
57
  /** Shutdown the this. Forcefully disconnect the shard from Discord. The shard may not attempt to reconnect with Discord. */
71
58
  shutdown(): Promise<void>;
72
59
  /** Handle a gateway connection close. */
73
- handleClose(close: WebSocket.CloseEvent): Promise<void>;
60
+ handleClose(close: NodeWebSocket.CloseEvent): Promise<void>;
74
61
  /** Handles a incoming gateway packet. */
75
62
  handleDiscordPacket(packet: DiscordGatewayPayload): Promise<void>;
76
63
  forwardToBot(packet: DiscordGatewayPayload): void;
77
64
  /** Handle an incoming gateway message. */
78
- handleMessage(message: WebSocket.MessageEvent): Promise<void>;
65
+ handleMessage(message: NodeWebSocket.MessageEvent): Promise<void>;
79
66
  /**
80
67
  * Override in order to make the shards presence.
81
68
  * async in case devs create the presence based on eg. database values.
@@ -90,74 +77,6 @@ export declare class DiscordenoShard {
90
77
  startHeartbeating(interval: number): void;
91
78
  /** Stop the heartbeating process with discord. */
92
79
  stopHeartbeating(): void;
93
- /**
94
- * Connects the bot user to a voice or stage channel.
95
- *
96
- * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.
97
- *
98
- * @param guildId - The ID of the guild the voice channel to leave is in.
99
- * @param channelId - The ID of the channel you want to join.
100
- *
101
- * @remarks
102
- * Requires the `CONNECT` permission.
103
- *
104
- * Fires a _Voice State Update_ gateway event.
105
- *
106
- * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}
107
- */
108
- joinVoiceChannel(guildId: BigString, channelId: BigString, options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>): Promise<void>;
109
- /**
110
- * Edits the bot status in all shards that this gateway manages.
111
- *
112
- * @param data The status data to set the bots status to.
113
- * @returns Promise<void>
114
- */
115
- editBotStatus(data: StatusUpdate): Promise<void>;
116
- /**
117
- * Edits the bot's status on one shard.
118
- *
119
- * @param shardId The shard id to edit the status for.
120
- * @param data The status data to set the bots status to.
121
- * @returns Promise<void>
122
- */
123
- editShardStatus(data: StatusUpdate): Promise<void>;
124
- /**
125
- * Fetches the list of members for a guild over the gateway.
126
- *
127
- * @param guildId - The ID of the guild to get the list of members for.
128
- * @param options - The parameters for the fetching of the members.
129
- *
130
- * @remarks
131
- * If requesting the entire member list:
132
- * - Requires the `GUILD_MEMBERS` intent.
133
- *
134
- * If requesting presences ({@link RequestGuildMembers.presences | presences} set to `true`):
135
- * - Requires the `GUILD_PRESENCES` intent.
136
- *
137
- * If requesting a prefix ({@link RequestGuildMembers.query | query} non-`undefined`):
138
- * - Returns a maximum of 100 members.
139
- *
140
- * If requesting a users by ID ({@link RequestGuildMembers.userIds | userIds} non-`undefined`):
141
- * - Returns a maximum of 100 members.
142
- *
143
- * Fires a _Guild Members Chunk_ gateway event for every 1000 members fetched.
144
- *
145
- * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members}
146
- */
147
- requestMembers(guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>): Promise<Camelize<DiscordMember[]>>;
148
- /**
149
- * Leaves the voice channel the bot user is currently in.
150
- *
151
- * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.
152
- *
153
- * @param guildId - The ID of the guild the voice channel to leave is in.
154
- *
155
- * @remarks
156
- * Fires a _Voice State Update_ gateway event.
157
- *
158
- * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}
159
- */
160
- leaveVoiceChannel(guildId: BigString): Promise<void>;
161
80
  }
162
81
  export interface ShardCreateOptions {
163
82
  /** The shard id */
@@ -1 +1 @@
1
- {"version":3,"file":"Shard.d.ts","sourceRoot":"","sources":["../src/Shard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Shard.d.ts","sourceRoot":"","sources":["../src/Shard.ts"],"names":[],"mappings":"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"}
package/dist/Shard.js CHANGED
@@ -1,7 +1,7 @@
1
- /* eslint-disable @typescript-eslint/no-confusing-void-expression */ import { GatewayCloseEventCodes, GatewayIntents, GatewayOpcodes } from '@discordeno/types';
2
- import { Collection, LeakyBucket, camelize, delay, logger } from '@discordeno/utils';
1
+ /* eslint-disable @typescript-eslint/no-confusing-void-expression */ import { GatewayCloseEventCodes, GatewayOpcodes } from '@discordeno/types';
2
+ import { camelize, delay, LeakyBucket, logger } from '@discordeno/utils';
3
3
  import { inflateSync } from 'node:zlib';
4
- import WebSocket from 'ws';
4
+ import NodeWebSocket from 'ws';
5
5
  import { ShardSocketCloseCodes, ShardState } from './types.js';
6
6
  export class DiscordenoShard {
7
7
  constructor(options){
@@ -13,15 +13,6 @@ export class DiscordenoShard {
13
13
  /** The shard related event handlers. */ this.events = {};
14
14
  /** Cache for pending gateway requests which should have been send while the gateway went offline. */ this.offlineSendQueue = [];
15
15
  /** Resolve internal waiting states. Mapped by SelectedEvents => ResolveFunction */ this.resolves = new Map();
16
- /** This managers cache related settings. */ this.cache = {
17
- requestMembers: {
18
- /**
19
- * Whether or not request member requests should be cached.
20
- * @default false
21
- */ enabled: false,
22
- /** The pending requests. */ pending: new Collection()
23
- }
24
- };
25
16
  this.id = options.id;
26
17
  this.connection = options.connection;
27
18
  this.events = options.events;
@@ -40,7 +31,7 @@ export class DiscordenoShard {
40
31
  /** The gateway configuration which is used to connect to Discord. */ get gatewayConfig() {
41
32
  return this.connection;
42
33
  }
43
- /** 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. */ get connectionUrl() {
34
+ /** The url to connect to. Initially this is the discord gateway url, and then is switched to resume gateway url once a READY is received. */ get connectionUrl() {
44
35
  // Use || and not ?? here. ?? will cause a bug.
45
36
  return this.resumeGatewayUrl || this.gatewayConfig.url;
46
37
  }
@@ -59,7 +50,7 @@ export class DiscordenoShard {
59
50
  }
60
51
  }
61
52
  /** Close the socket connection to discord if present. */ close(code, reason) {
62
- if (this.socket?.readyState !== WebSocket.OPEN) return;
53
+ if (this.socket?.readyState !== NodeWebSocket.OPEN) return;
63
54
  this.socket?.close(code, reason);
64
55
  }
65
56
  /** Connect the shard with the gateway and start heartbeating. This will not identify the shard to the gateway. */ async connect() {
@@ -75,7 +66,8 @@ export class DiscordenoShard {
75
66
  const url = new URL(this.connectionUrl);
76
67
  url.searchParams.set('v', this.gatewayConfig.version.toString());
77
68
  url.searchParams.set('encoding', 'json');
78
- const socket = new WebSocket(url.toString());
69
+ const socket = // @ts-expect-error Deno
70
+ globalThis.Deno !== undefined && Reflect.has(globalThis, 'Deno') ? new WebSocket(url.toString()) : new NodeWebSocket(url.toString());
79
71
  this.socket = socket;
80
72
  // TODO: proper event handling
81
73
  socket.onerror = (event)=>console.log({
@@ -145,13 +137,14 @@ export class DiscordenoShard {
145
137
  });
146
138
  }
147
139
  /** Check whether the connection to Discord is currently open. */ isOpen() {
148
- return this.socket?.readyState === WebSocket.OPEN;
140
+ return this.socket?.readyState === NodeWebSocket.OPEN;
149
141
  }
150
142
  /** Attempt to resume the previous shards session with the gateway. */ async resume() {
151
143
  logger.debug(`[Gateway] Resuming Shard #${this.id}`);
152
144
  // It has been requested to resume the Shards session.
153
145
  // It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.
154
146
  if (this.isOpen()) {
147
+ logger.debug(`[Gateway] Resuming Shard #${this.id} in isOpen`);
155
148
  this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.');
156
149
  }
157
150
  // Shard has never identified, so we cannot resume.
@@ -160,8 +153,11 @@ export class DiscordenoShard {
160
153
  return await this.identify();
161
154
  }
162
155
  this.state = ShardState.Resuming;
156
+ logger.debug(`[Gateway] Resuming Shard #${this.id}, before connecting`);
163
157
  // Before we can resume, we need to create a new connection with Discord's gateway.
164
158
  await this.connect();
159
+ logger.debug(// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
160
+ `[Gateway] Resuming Shard #${this.id}, after connecting. ${this.gatewayConfig.token} | ${this.sessionId} | ${this.previousSequenceNumber}`);
165
161
  this.send({
166
162
  op: GatewayOpcodes.Resume,
167
163
  d: {
@@ -170,6 +166,7 @@ export class DiscordenoShard {
170
166
  seq: this.previousSequenceNumber ?? 0
171
167
  }
172
168
  }, true);
169
+ logger.debug(`[Gateway] Resuming Shard #${this.id} after send resumg`);
173
170
  return await new Promise((resolve)=>{
174
171
  this.resolves.set('RESUMED', ()=>resolve());
175
172
  // If it is attempted to resume with an invalid session id,
@@ -249,6 +246,7 @@ export class DiscordenoShard {
249
246
  case GatewayCloseEventCodes.AlreadyAuthenticated:
250
247
  default:
251
248
  {
249
+ logger.info(`[Shard] closed shard #${this.id}. Resuming...`);
252
250
  this.state = ShardState.Resuming;
253
251
  this.events.disconnected?.(this);
254
252
  return await this.resume();
@@ -282,6 +280,7 @@ export class DiscordenoShard {
282
280
  case GatewayOpcodes.Hello:
283
281
  {
284
282
  const interval = packet.d.heartbeat_interval;
283
+ logger.debug(`[Gateway] Hello on Shard #${this.id}`);
285
284
  this.startHeartbeating(interval);
286
285
  if (this.state !== ShardState.Resuming) {
287
286
  const currentQueue = [
@@ -333,25 +332,33 @@ export class DiscordenoShard {
333
332
  break;
334
333
  }
335
334
  }
336
- if (packet.t === 'RESUMED') {
337
- // gateway.debug("GW RESUMED", { shardId });
338
- this.state = ShardState.Connected;
339
- this.events.resumed?.(this);
340
- // Continue the requests which have been queued since the shard went offline.
341
- this.offlineSendQueue.map((resolve)=>resolve());
342
- this.resolves.get('RESUMED')?.(packet);
343
- this.resolves.delete('RESUMED');
344
- } else if (packet.t === 'READY') {
345
- // Important for future resumes.
346
- const payload = packet.d;
347
- this.resumeGatewayUrl = payload.resume_gateway_url;
348
- this.sessionId = payload.session_id;
349
- this.state = ShardState.Connected;
350
- // Continue the requests which have been queued since the shard went offline.
351
- // Important when this is a re-identify
352
- this.offlineSendQueue.map((resolve)=>resolve());
353
- this.resolves.get('READY')?.(packet);
354
- this.resolves.delete('READY');
335
+ switch(packet.t){
336
+ case 'RESUMED':
337
+ this.state = ShardState.Connected;
338
+ this.events.resumed?.(this);
339
+ // Continue the requests which have been queued since the shard went offline.
340
+ this.offlineSendQueue.map((resolve)=>resolve());
341
+ this.resolves.get('RESUMED')?.(packet);
342
+ this.resolves.delete('RESUMED');
343
+ break;
344
+ case 'READY':
345
+ {
346
+ // Important for future resumes.
347
+ const payload = packet.d;
348
+ this.resumeGatewayUrl = payload.resume_gateway_url;
349
+ this.sessionId = payload.session_id;
350
+ this.state = ShardState.Connected;
351
+ // Continue the requests which have been queued since the shard went offline.
352
+ // Important when this is a re-identify
353
+ this.offlineSendQueue.map((resolve)=>resolve());
354
+ this.resolves.get('READY')?.(packet);
355
+ this.resolves.delete('READY');
356
+ break;
357
+ }
358
+ case 'GUILD_MEMBERS_CHUNK':
359
+ {
360
+ this.events.guildMemberChunk?.(packet.d);
361
+ }
355
362
  }
356
363
  // Update the sequence number if it is present
357
364
  // `s` can be either `null` or a `number`.
@@ -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);
@@ -446,153 +462,6 @@ export class DiscordenoShard {
446
462
  // To go safe we should clear the related timeout too.
447
463
  clearTimeout(this.heart.timeoutId);
448
464
  }
449
- /**
450
- * Connects the bot user to a voice or stage channel.
451
- *
452
- * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.
453
- *
454
- * @param guildId - The ID of the guild the voice channel to leave is in.
455
- * @param channelId - The ID of the channel you want to join.
456
- *
457
- * @remarks
458
- * Requires the `CONNECT` permission.
459
- *
460
- * Fires a _Voice State Update_ gateway event.
461
- *
462
- * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}
463
- */ async joinVoiceChannel(guildId, channelId, options) {
464
- logger.debug(`[Shard] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`);
465
- await this.send({
466
- op: GatewayOpcodes.VoiceStateUpdate,
467
- d: {
468
- guild_id: guildId.toString(),
469
- channel_id: channelId.toString(),
470
- self_mute: Boolean(options?.selfMute),
471
- self_deaf: options?.selfDeaf ?? true
472
- }
473
- });
474
- }
475
- /**
476
- * Edits the bot status in all shards that this gateway manages.
477
- *
478
- * @param data The status data to set the bots status to.
479
- * @returns Promise<void>
480
- */ async editBotStatus(data) {
481
- logger.debug(`[Shard] editBotStatus data: ${JSON.stringify(data)}`);
482
- await this.editShardStatus(data);
483
- }
484
- /**
485
- * Edits the bot's status on one shard.
486
- *
487
- * @param shardId The shard id to edit the status for.
488
- * @param data The status data to set the bots status to.
489
- * @returns Promise<void>
490
- */ async editShardStatus(data) {
491
- logger.debug(`[Shard] editShardStatus shardId: ${this.id} -> data: ${JSON.stringify(data)}`);
492
- await this.send({
493
- op: GatewayOpcodes.PresenceUpdate,
494
- d: {
495
- since: null,
496
- afk: false,
497
- activities: data.activities,
498
- status: data.status
499
- }
500
- });
501
- }
502
- /**
503
- * Fetches the list of members for a guild over the gateway.
504
- *
505
- * @param guildId - The ID of the guild to get the list of members for.
506
- * @param options - The parameters for the fetching of the members.
507
- *
508
- * @remarks
509
- * If requesting the entire member list:
510
- * - Requires the `GUILD_MEMBERS` intent.
511
- *
512
- * If requesting presences ({@link RequestGuildMembers.presences | presences} set to `true`):
513
- * - Requires the `GUILD_PRESENCES` intent.
514
- *
515
- * If requesting a prefix ({@link RequestGuildMembers.query | query} non-`undefined`):
516
- * - Returns a maximum of 100 members.
517
- *
518
- * If requesting a users by ID ({@link RequestGuildMembers.userIds | userIds} non-`undefined`):
519
- * - Returns a maximum of 100 members.
520
- *
521
- * Fires a _Guild Members Chunk_ gateway event for every 1000 members fetched.
522
- *
523
- * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members}
524
- */ async requestMembers(guildId, options) {
525
- // You can request 1 member without the intent
526
- // Check if intents is not 0 as proxy ws won't set intents in other instances
527
- if (this.connection.intents && (!options?.limit || options.limit > 1) && !(this.connection.intents & GatewayIntents.GuildMembers)) {
528
- throw new Error('MISSING_INTENT_GUILD_MEMBERS');
529
- }
530
- if (options?.userIds?.length) {
531
- logger.debug(`[Shard] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`);
532
- options.limit = options.userIds.length;
533
- }
534
- const nonce = `${guildId}-${Date.now()}`;
535
- // Gateway does not require caching these requests so directly send and return
536
- if (!this.cache.requestMembers?.enabled) {
537
- logger.debug(`[Shard] requestMembers guildId: ${guildId} -> skipping cache -> options ${JSON.stringify(options)}`);
538
- await this.send({
539
- op: GatewayOpcodes.RequestGuildMembers,
540
- d: {
541
- guild_id: guildId.toString(),
542
- // If a query is provided use it, OR if a limit is NOT provided use ""
543
- query: options?.query ?? (options?.limit ? undefined : ''),
544
- limit: options?.limit ?? 0,
545
- presences: options?.presences ?? false,
546
- user_ids: options?.userIds?.map((id)=>id.toString()),
547
- nonce
548
- }
549
- });
550
- return [];
551
- }
552
- return await new Promise((resolve)=>{
553
- this.cache.requestMembers?.pending.set(nonce, {
554
- nonce,
555
- resolve,
556
- members: []
557
- });
558
- logger.debug(`[Shard] requestMembers guildId: ${guildId} -> requesting members -> data: ${JSON.stringify(options)}`);
559
- this.send({
560
- op: GatewayOpcodes.RequestGuildMembers,
561
- d: {
562
- guild_id: guildId.toString(),
563
- // If a query is provided use it, OR if a limit is NOT provided use ""
564
- query: options?.query ?? (options?.limit ? undefined : ''),
565
- limit: options?.limit ?? 0,
566
- presences: options?.presences ?? false,
567
- user_ids: options?.userIds?.map((id)=>id.toString()),
568
- nonce
569
- }
570
- });
571
- });
572
- }
573
- /**
574
- * Leaves the voice channel the bot user is currently in.
575
- *
576
- * This function sends the _Update Voice State_ gateway command over the gateway behind the scenes.
577
- *
578
- * @param guildId - The ID of the guild the voice channel to leave is in.
579
- *
580
- * @remarks
581
- * Fires a _Voice State Update_ gateway event.
582
- *
583
- * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state}
584
- */ async leaveVoiceChannel(guildId) {
585
- logger.debug(`[Shard] leaveVoiceChannel guildId: ${guildId} Shard ${this.id}`);
586
- await this.send({
587
- op: GatewayOpcodes.VoiceStateUpdate,
588
- d: {
589
- guild_id: guildId.toString(),
590
- channel_id: null,
591
- self_mute: false,
592
- self_deaf: false
593
- }
594
- });
595
- }
596
465
  }
597
466
  export default DiscordenoShard;
598
467
 
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":"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"}
1
+ {"version":3,"sources":["../src/Shard.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-confusing-void-expression */\nimport type { DiscordGatewayPayload, DiscordGuildMembersChunk, DiscordHello, DiscordReady } from '@discordeno/types'\nimport { GatewayCloseEventCodes, GatewayOpcodes } from '@discordeno/types'\nimport { camelize, delay, LeakyBucket, logger } from '@discordeno/utils'\nimport { inflateSync } from 'node:zlib'\nimport NodeWebSocket from 'ws'\nimport type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest } from './types.js'\nimport { ShardSocketCloseCodes, ShardState } from './types.js'\n\ndeclare let WebSocket: any\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?: NodeWebSocket\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 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. Initially 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 !== NodeWebSocket.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: NodeWebSocket =\n // @ts-expect-error Deno\n globalThis.Deno !== undefined && Reflect.has(globalThis, 'Deno') ? new WebSocket(url.toString()) : new NodeWebSocket(url.toString())\n this.socket = socket\n\n // TODO: proper event handling\n socket.onerror = (event: NodeWebSocket.ErrorEvent) => console.log({ error: event, shardId: this.id })\n socket.onclose = async (event: NodeWebSocket.CloseEvent) => await this.handleClose(event)\n socket.onmessage = async (message: NodeWebSocket.MessageEvent) => 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 === NodeWebSocket.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: boolean = 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: NodeWebSocket.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 switch (packet.t) {\n case 'RESUMED':\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 break\n case 'READY': {\n // Important for future resumes.\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 break\n }\n case 'GUILD_MEMBERS_CHUNK': {\n this.events.guildMemberChunk?.(packet.d as DiscordGuildMembersChunk)\n }\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: NodeWebSocket.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\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","GatewayOpcodes","camelize","delay","LeakyBucket","logger","inflateSync","NodeWebSocket","ShardSocketCloseCodes","ShardState","DiscordenoShard","constructor","options","maxRequestsPerRateLimitTick","previousSequenceNumber","rateLimitResetInterval","state","Offline","resumeGatewayUrl","events","offlineSendQueue","resolves","Map","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","globalThis","Deno","undefined","Reflect","has","WebSocket","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","guildMemberChunk","s","forwardToBot","preProcessMessage","data","Blob","arrayBuffer","parse","intervalId","clearInterval","timeoutId","clearTimeout","jitter","setTimeout","setInterval"],"mappings":"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"}
package/dist/manager.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { AtLeastOne, BigString, Camelize, DiscordGetGatewayBot, DiscordMember, RequestGuildMembers } from '@discordeno/types';
1
+ import { type AtLeastOne, type BigString, type Camelize, type DiscordGetGatewayBot, type DiscordMember, type DiscordMemberWithUser, type RequestGuildMembers } from '@discordeno/types';
2
2
  import { Collection } from '@discordeno/utils';
3
3
  import Shard from './Shard.js';
4
- import type { ShardEvents, StatusUpdate, UpdateVoiceState } from './types.js';
4
+ import type { ShardEvents, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js';
5
5
  export declare function createGatewayManager(options: CreateGatewayManagerOptions): GatewayManager;
6
6
  export interface CreateGatewayManagerOptions {
7
7
  /**
@@ -118,6 +118,7 @@ export interface GatewayManager extends Required<CreateGatewayManagerOptions> {
118
118
  spawnShards: () => Promise<void>;
119
119
  /** Shutdown all shards. */
120
120
  shutdown: (code: number, reason: string) => Promise<void>;
121
+ sendPayload: (shardId: number, payload: ShardSocketRequest) => Promise<void>;
121
122
  /** Allows users to hook in and change to communicate to different workers across different servers or anything they like. For example using redis pubsub to talk to other servers. */
122
123
  tellWorkerToIdentify: (workerId: number, shardId: number, bucketId: number) => Promise<void>;
123
124
  /** Tell the manager to identify a Shard. If this Shard is not already managed this will also add the Shard to the manager. */
@@ -203,6 +204,6 @@ export interface RequestMemberRequest {
203
204
  /** The resolver handler to run when all members arrive. */
204
205
  resolve: (value: Camelize<DiscordMember[]> | PromiseLike<Camelize<DiscordMember[]>>) => void;
205
206
  /** The members that have already arrived for this request. */
206
- members: Camelize<DiscordMember[]>;
207
+ members: DiscordMemberWithUser[];
207
208
  }
208
209
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"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"}
package/dist/manager.js CHANGED
@@ -1,18 +1,33 @@
1
- /* eslint-disable @typescript-eslint/no-confusing-void-expression */ import { Collection, delay, logger } from '@discordeno/utils';
1
+ /* eslint-disable @typescript-eslint/no-confusing-void-expression */ import { GatewayIntents, GatewayOpcodes } from '@discordeno/types';
2
+ import { camelize, Collection, delay, logger } from '@discordeno/utils';
2
3
  import Shard from './Shard.js';
3
4
  export function createGatewayManager(options) {
4
- if (!options.connection) {
5
- options.connection = {
6
- url: 'wss://gateway.discord.gg',
7
- shards: 1,
8
- sessionStartLimit: {
9
- maxConcurrency: 1,
10
- remaining: 1000,
11
- total: 1000,
12
- resetAfter: 1000 * 60 * 60 * 24
13
- }
14
- };
15
- }
5
+ const connectionOptions = options.connection ?? {
6
+ url: 'wss://gateway.discord.gg',
7
+ shards: 1,
8
+ sessionStartLimit: {
9
+ maxConcurrency: 1,
10
+ remaining: 1000,
11
+ total: 1000,
12
+ resetAfter: 1000 * 60 * 60 * 24
13
+ }
14
+ };
15
+ options.events.guildMemberChunk ??= (payload)=>{
16
+ // If it's not enabled skip checks.
17
+ if (!gateway.cache.requestMembers?.enabled) return;
18
+ // If this request has no nonce, skip checks.
19
+ if (!payload.nonce) return;
20
+ const pending = gateway.cache.requestMembers.pending.get(payload.nonce);
21
+ if (!pending) return;
22
+ if (payload.chunk_count === 1) pending.members = payload.members;
23
+ else pending.members.push(...payload.members);
24
+ // If this is not the final chunk, just save to cache.
25
+ if (payload.chunk_index + 1 < payload.chunk_count) return;
26
+ // Resolve the promise that all requests are done.
27
+ pending.resolve(camelize(pending.members));
28
+ // Delete the cache to clean up once its done.
29
+ gateway.cache.requestMembers.pending.delete(payload.nonce);
30
+ };
16
31
  const gateway = {
17
32
  events: options.events,
18
33
  compress: options.compress ?? false,
@@ -23,16 +38,16 @@ export function createGatewayManager(options) {
23
38
  device: options.properties?.device ?? 'Discordeno'
24
39
  },
25
40
  token: options.token,
26
- url: options.url ?? options.connection.url ?? 'wss://gateway.discord.gg',
41
+ url: options.url ?? connectionOptions.url ?? 'wss://gateway.discord.gg',
27
42
  version: options.version ?? 10,
28
- connection: options.connection,
29
- totalShards: options.totalShards ?? options.connection.shards ?? 1,
30
- lastShardId: options.lastShardId ?? 0,
43
+ connection: connectionOptions,
44
+ totalShards: options.totalShards ?? connectionOptions.shards ?? 1,
45
+ lastShardId: options.lastShardId ?? (options.totalShards ? options.totalShards - 1 : connectionOptions ? connectionOptions.shards - 1 : 0),
31
46
  firstShardId: options.firstShardId ?? 0,
32
47
  totalWorkers: options.totalWorkers ?? 4,
33
48
  shardsPerWorker: options.shardsPerWorker ?? 25,
34
49
  spawnShardDelay: options.spawnShardDelay ?? 5300,
35
- preferSnakeCase: false,
50
+ preferSnakeCase: options.preferSnakeCase ?? false,
36
51
  shards: new Map(),
37
52
  buckets: new Map(),
38
53
  cache: {
@@ -53,7 +68,7 @@ export function createGatewayManager(options) {
53
68
  (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency)) * gateway.connection.sessionStartLimit.maxConcurrency;
54
69
  },
55
70
  calculateWorkerId (shardId) {
56
- const workerId = shardId % gateway.shardsPerWorker;
71
+ const workerId = Math.min(shardId % gateway.shardsPerWorker, gateway.totalWorkers - 1);
57
72
  logger.debug(`[Gateway] Calculating workerId: Shard: ${shardId} -> Worker: ${workerId} -> Per Worker: ${gateway.shardsPerWorker} -> Total: ${gateway.totalWorkers}`);
58
73
  return workerId;
59
74
  },
@@ -117,6 +132,13 @@ export function createGatewayManager(options) {
117
132
  gateway.shards.forEach((shard)=>shard.close(code, reason));
118
133
  await delay(5000);
119
134
  },
135
+ async sendPayload (shardId, payload) {
136
+ const shard = gateway.shards.get(shardId);
137
+ if (!shard) {
138
+ throw new Error(`Shard (id: ${shardId} not found`);
139
+ }
140
+ await shard.send(payload);
141
+ },
120
142
  async tellWorkerToIdentify (workerId, shardId, bucketId) {
121
143
  logger.debug(`[Gateway] tell worker to identify (${workerId}, ${shardId}, ${bucketId})`);
122
144
  await gateway.identify(shardId);
@@ -195,12 +217,16 @@ export function createGatewayManager(options) {
195
217
  },
196
218
  async joinVoiceChannel (guildId, channelId, options) {
197
219
  const shardId = gateway.calculateShardId(guildId);
198
- const shard = gateway.shards.get(shardId);
199
- if (!shard) {
200
- throw new Error(`Shard (id: ${shardId} not found`);
201
- }
202
220
  logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`);
203
- shard.joinVoiceChannel(guildId, channelId, options);
221
+ await gateway.sendPayload(shardId, {
222
+ op: GatewayOpcodes.VoiceStateUpdate,
223
+ d: {
224
+ guild_id: guildId.toString(),
225
+ channel_id: channelId.toString(),
226
+ self_mute: options?.selfMute ?? false,
227
+ self_deaf: options?.selfDeaf ?? true
228
+ }
229
+ });
204
230
  },
205
231
  async editBotStatus (data) {
206
232
  logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data)}`);
@@ -211,30 +237,63 @@ export function createGatewayManager(options) {
211
237
  }));
212
238
  },
213
239
  async editShardStatus (shardId, data) {
214
- const shard = gateway.shards.get(shardId);
215
- if (!shard) {
216
- throw new Error(`Shard (id: ${shardId}) not found.`);
217
- }
218
240
  logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`);
219
- await shard.editShardStatus(data);
241
+ await gateway.sendPayload(shardId, {
242
+ op: GatewayOpcodes.PresenceUpdate,
243
+ d: {
244
+ since: null,
245
+ afk: false,
246
+ activities: data.activities,
247
+ status: data.status
248
+ }
249
+ });
220
250
  },
221
251
  async requestMembers (guildId, options) {
222
252
  const shardId = gateway.calculateShardId(guildId);
223
- const shard = gateway.shards.get(shardId);
224
- if (!shard) {
225
- throw new Error(`Shard (id: ${shardId}) not found.`);
253
+ if (gateway.intents && (!options?.limit || options.limit > 1) && !(gateway.intents & GatewayIntents.GuildMembers)) throw new Error('Cannot fetch more then 1 member without the GUILD_MEMBERS intent');
254
+ logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> data: ${JSON.stringify(options)}`);
255
+ if (options?.userIds?.length) {
256
+ logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`);
257
+ options.limit = options.userIds.length;
226
258
  }
227
- logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> options ${JSON.stringify(options)}`);
228
- return await shard.requestMembers(guildId, options);
259
+ const members = !gateway.cache.requestMembers?.enabled || !options?.nonce ? [] : new Promise((resolve, reject)=>{
260
+ // Should never happen.
261
+ if (!gateway.cache.requestMembers?.enabled || !options?.nonce) {
262
+ reject(new Error("Can't request the members without the nonce or with the feature disabled."));
263
+ return;
264
+ }
265
+ gateway.cache.requestMembers.pending.set(options.nonce, {
266
+ nonce: options.nonce,
267
+ resolve,
268
+ members: []
269
+ });
270
+ });
271
+ await gateway.sendPayload(shardId, {
272
+ op: GatewayOpcodes.RequestGuildMembers,
273
+ d: {
274
+ guild_id: guildId.toString(),
275
+ // If a query is provided use it, OR if a limit is NOT provided use ""
276
+ query: options?.query ?? (options?.limit ? undefined : ''),
277
+ limit: options?.limit ?? 0,
278
+ presences: options?.presences ?? false,
279
+ user_ids: options?.userIds?.map((id)=>id.toString()),
280
+ nonce: options?.nonce
281
+ }
282
+ });
283
+ return await members;
229
284
  },
230
285
  async leaveVoiceChannel (guildId) {
231
286
  const shardId = gateway.calculateShardId(guildId);
232
- const shard = gateway.shards.get(shardId);
233
- if (!shard) {
234
- throw new Error(`Shard (id: ${shardId} not found`);
235
- }
236
287
  logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`);
237
- await shard.leaveVoiceChannel(guildId);
288
+ await gateway.sendPayload(shardId, {
289
+ op: GatewayOpcodes.VoiceStateUpdate,
290
+ d: {
291
+ guild_id: guildId.toString(),
292
+ channel_id: null,
293
+ self_mute: false,
294
+ self_deaf: false
295
+ }
296
+ });
238
297
  }
239
298
  };
240
299
  return gateway;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/manager.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-confusing-void-expression */\nimport type { AtLeastOne, BigString, Camelize, DiscordGetGatewayBot, DiscordMember, RequestGuildMembers } from '@discordeno/types'\nimport { Collection, delay, logger } from '@discordeno/utils'\nimport Shard from './Shard.js'\nimport type { ShardEvents, StatusUpdate, UpdateVoiceState } from './types.js'\n\nexport function createGatewayManager(options: CreateGatewayManagerOptions): GatewayManager {\n if (!options.connection) {\n options.connection = {\n url: 'wss://gateway.discord.gg',\n shards: 1,\n sessionStartLimit: {\n maxConcurrency: 1,\n remaining: 1000,\n total: 1000,\n resetAfter: 1000 * 60 * 60 * 24,\n },\n }\n }\n\n const gateway: GatewayManager = {\n events: options.events,\n compress: options.compress ?? false,\n intents: options.intents ?? 0,\n properties: {\n os: options.properties?.os ?? process.platform,\n browser: options.properties?.browser ?? 'Discordeno',\n device: options.properties?.device ?? 'Discordeno',\n },\n token: options.token,\n url: options.url ?? options.connection.url ?? 'wss://gateway.discord.gg',\n version: options.version ?? 10,\n connection: options.connection,\n totalShards: options.totalShards ?? options.connection.shards ?? 1,\n lastShardId: options.lastShardId ?? 0,\n firstShardId: options.firstShardId ?? 0,\n totalWorkers: options.totalWorkers ?? 4,\n shardsPerWorker: options.shardsPerWorker ?? 25,\n spawnShardDelay: options.spawnShardDelay ?? 5300,\n preferSnakeCase: false,\n shards: new Map(),\n buckets: new Map(),\n cache: {\n requestMembers: {\n enabled: options.cache?.requestMembers?.enabled ?? false,\n pending: new Collection(),\n },\n },\n\n calculateTotalShards() {\n // Bots under 100k servers do not have access to total shards.\n if (gateway.totalShards < 100) {\n logger.debug(`[Gateway] Calculating total shards: ${gateway.totalShards}`)\n return gateway.totalShards\n }\n\n logger.debug(`[Gateway] Calculating total shards`, gateway.totalShards, gateway.connection.sessionStartLimit.maxConcurrency)\n // Calculate a multiple of `maxConcurrency` which can be used to connect to the gateway.\n return (\n Math.ceil(\n gateway.totalShards /\n // If `maxConcurrency` is 1 we can safely use 16.\n (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency),\n ) * gateway.connection.sessionStartLimit.maxConcurrency\n )\n },\n calculateWorkerId(shardId) {\n const workerId = shardId % gateway.shardsPerWorker\n logger.debug(\n `[Gateway] Calculating workerId: Shard: ${shardId} -> Worker: ${workerId} -> Per Worker: ${gateway.shardsPerWorker} -> Total: ${gateway.totalWorkers}`,\n )\n return workerId\n },\n prepareBuckets() {\n for (let i = 0; i < gateway.connection.sessionStartLimit.maxConcurrency; ++i) {\n logger.debug(`[Gateway] Preparing buckets for concurrency: ${i}`)\n gateway.buckets.set(i, {\n workers: [],\n identifyRequests: [],\n })\n }\n\n // ORGANIZE ALL SHARDS INTO THEIR OWN BUCKETS\n for (let shardId = gateway.firstShardId; shardId <= gateway.lastShardId; ++shardId) {\n logger.debug(`[Gateway] Preparing buckets for shard: ${shardId}`)\n if (shardId >= gateway.totalShards) {\n throw new Error(`Shard (id: ${shardId}) is bigger or equal to the used amount of used shards which is ${gateway.totalShards}`)\n }\n\n const bucketId = shardId % gateway.connection.sessionStartLimit.maxConcurrency\n const bucket = gateway.buckets.get(bucketId)\n if (!bucket) {\n throw new Error(\n `Shard (id: ${shardId}) got assigned to an illegal bucket id: ${bucketId}, expected a bucket id between 0 and ${\n gateway.connection.sessionStartLimit.maxConcurrency - 1\n }`,\n )\n }\n\n // FIND A QUEUE IN THIS BUCKET THAT HAS SPACE\n // const worker = bucket.workers.find((w) => w.queue.length < gateway.shardsPerWorker);\n const workerId = gateway.calculateWorkerId(shardId)\n const worker = bucket.workers.find((w) => w.id === workerId)\n if (worker) {\n // IF THE QUEUE HAS SPACE JUST ADD IT TO THIS QUEUE\n worker.queue.push(shardId)\n } else {\n bucket.workers.push({ id: workerId, queue: [shardId] })\n }\n }\n\n for (const bucket of gateway.buckets.values()) {\n for (const worker of bucket.workers.values()) {\n // eslint-disable-next-line @typescript-eslint/require-array-sort-compare\n worker.queue = worker.queue.sort((a, b) => a - b)\n }\n }\n },\n async spawnShards() {\n // PREPARES ALL SHARDS IN SPECIFIC BUCKETS\n gateway.prepareBuckets()\n\n // Prefer concurrency of forEach instead of forof\n await Promise.all(\n [...gateway.buckets.entries()].map(async ([bucketId, bucket]) => {\n for (const worker of bucket.workers) {\n for (const shardId of worker.queue) {\n await gateway.tellWorkerToIdentify(worker.id, shardId, bucketId)\n }\n }\n }),\n )\n },\n async shutdown(code, reason) {\n gateway.shards.forEach((shard) => shard.close(code, reason))\n\n await delay(5000)\n },\n async tellWorkerToIdentify(workerId, shardId, bucketId) {\n logger.debug(`[Gateway] tell worker to identify (${workerId}, ${shardId}, ${bucketId})`)\n await gateway.identify(shardId)\n },\n async identify(shardId: number) {\n let shard = this.shards.get(shardId)\n logger.debug(`[Gateway] identifying ${shard ? 'existing' : 'new'} shard (${shardId})`)\n\n if (!shard) {\n shard = new Shard({\n id: shardId,\n connection: {\n compress: this.compress,\n intents: this.intents,\n properties: this.properties,\n token: this.token,\n totalShards: this.totalShards,\n url: this.url,\n version: this.version,\n },\n events: options.events,\n requestIdentify: async () => {\n await gateway.identify(shardId)\n },\n shardIsReady: async () => {\n logger.debug(`[Shard] Shard #${shardId} is ready`)\n await delay(gateway.spawnShardDelay)\n logger.debug(`[Shard] Resolving shard identify request`)\n gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)!.identifyRequests.shift()?.()\n },\n })\n\n if (this.preferSnakeCase) {\n shard.forwardToBot = async (payload) => {\n options.events.message?.(shard!, payload)\n }\n }\n\n this.shards.set(shardId, shard)\n }\n\n const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)\n if (!bucket) return\n\n return await new Promise((resolve) => {\n // Mark that we are making an identify request so another is not made.\n bucket.identifyRequests.push(resolve)\n logger.debug(`[Gateway] identifying shard #(${shardId}).`)\n // This will trigger identify and when READY is received it will resolve the above request.\n shard?.identify()\n })\n },\n async kill(shardId: number) {\n const shard = this.shards.get(shardId)\n if (!shard) {\n return logger.debug(`[Gateway] kill shard but not found (${shardId})`)\n }\n\n logger.debug(`[Gateway] kill shard (${shardId})`)\n this.shards.delete(shardId)\n await shard.shutdown()\n },\n\n async requestIdentify(shardId: number) {\n logger.debug(`[Gateway] requesting identify`)\n // const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)\n // if (!bucket) return\n\n // return await new Promise((resolve) => {\n // bucket.identifyRequests.push(resolve)\n // })\n },\n\n // Helpers methods below this\n\n calculateShardId(guildId, totalShards) {\n // If none is provided, use the total shards number from gateway object.\n if (!totalShards) totalShards = gateway.totalShards\n // If it is only 1 shard, it will always be shard id 0\n if (totalShards === 1) {\n logger.debug(`[Gateway] calculateShardId (1 shard)`)\n return 0\n }\n\n logger.debug(`[Gateway] calculateShardId (guildId: ${guildId}, totalShards: ${totalShards})`)\n return Number((BigInt(guildId) >> 22n) % BigInt(totalShards))\n },\n\n async joinVoiceChannel(guildId, channelId, options) {\n const shardId = gateway.calculateShardId(guildId)\n const shard = gateway.shards.get(shardId)\n if (!shard) {\n throw new Error(`Shard (id: ${shardId} not found`)\n }\n\n logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`)\n shard.joinVoiceChannel(guildId, channelId, options)\n },\n\n async editBotStatus(data) {\n logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data)}`)\n await Promise.all(\n [...gateway.shards.values()].map(async (shard) => {\n gateway.editShardStatus(shard.id, data)\n }),\n )\n },\n\n async editShardStatus(shardId, data) {\n const shard = gateway.shards.get(shardId)\n if (!shard) {\n throw new Error(`Shard (id: ${shardId}) not found.`)\n }\n\n logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`)\n await shard.editShardStatus(data)\n },\n\n async requestMembers(guildId, options) {\n const shardId = gateway.calculateShardId(guildId)\n const shard = gateway.shards.get(shardId)\n if (!shard) {\n throw new Error(`Shard (id: ${shardId}) not found.`)\n }\n\n logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> options ${JSON.stringify(options)}`)\n return await shard.requestMembers(guildId, options)\n },\n\n async leaveVoiceChannel(guildId) {\n const shardId = gateway.calculateShardId(guildId)\n const shard = gateway.shards.get(shardId)\n if (!shard) {\n throw new Error(`Shard (id: ${shardId} not found`)\n }\n\n logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`)\n await shard.leaveVoiceChannel(guildId)\n },\n }\n\n return gateway\n}\n\nexport interface CreateGatewayManagerOptions {\n /**\n * Id of the first Shard which should get controlled by this manager.\n * @default 0\n */\n firstShardId?: number\n /**\n * Id of the last Shard which should get controlled by this manager.\n * @default 0\n */\n lastShardId?: number\n /**\n * Delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 5100. YOU DON'T WANT TO HIT THE RATE LIMIT!!!\n * @default 5300\n */\n spawnShardDelay?: number\n /**\n * Whether to send the discord packets in snake case form.\n * @default false\n */\n preferSnakeCase?: boolean\n /**\n * Total amount of shards your bot uses. Useful for zero-downtime updates or resharding.\n * @default 1\n */\n totalShards?: number\n /**\n * The amount of shards to load per worker.\n * @default 25\n */\n shardsPerWorker?: number\n /**\n * The total amount of workers to use for your bot.\n * @default 4\n */\n totalWorkers?: number\n /** Important data which is used by the manager to connect shards to the gateway. */\n connection?: Camelize<DiscordGetGatewayBot>\n /** Whether incoming payloads are compressed using zlib.\n *\n * @default false\n */\n compress?: boolean\n /** The calculated intent value of the events which the shard should receive.\n *\n * @default 0\n */\n intents?: number\n /** Identify properties to use */\n properties?: {\n /** Operating system the shard runs on.\n *\n * @default \"darwin\" | \"linux\" | \"windows\"\n */\n os: string\n /** The \"browser\" where this shard is running on.\n *\n * @default \"Discordeno\"\n */\n browser: string\n /** The device on which the shard is running.\n *\n * @default \"Discordeno\"\n */\n device: string\n }\n /** Bot token which is used to connect to Discord */\n token: string\n /** The URL of the gateway which should be connected to.\n *\n * @default \"wss://gateway.discord.gg\"\n */\n url?: string\n /** The gateway version which should be used.\n *\n * @default 10\n */\n version?: number\n /** The events handlers */\n events: ShardEvents\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?: boolean\n /** The pending requests. */\n pending: Collection<string, RequestMemberRequest>\n }\n }\n}\n\nexport interface GatewayManager extends Required<CreateGatewayManagerOptions> {\n /** The max concurrency buckets. Those will be created when the `spawnShards` (which calls `prepareBuckets` under the hood) function gets called. */\n buckets: Map<\n number,\n {\n workers: Array<{ id: number; queue: number[] }>\n /** Requests to identify shards are made based on whether it is available to be made. */\n identifyRequests: Array<(value: void | PromiseLike<void>) => void>\n }\n >\n /** The shards that are created. */\n shards: Map<number, Shard>\n /** Determine max number of shards to use based upon the max concurrency. */\n calculateTotalShards: () => number\n /** Determine the id of the worker which is handling a shard. */\n calculateWorkerId: (shardId: number) => number\n /** Prepares all the buckets that are available for identifying the shards. */\n prepareBuckets: () => void\n /** Start identifying all the shards. */\n spawnShards: () => Promise<void>\n /** Shutdown all shards. */\n shutdown: (code: number, reason: string) => Promise<void>\n /** Allows users to hook in and change to communicate to different workers across different servers or anything they like. For example using redis pubsub to talk to other servers. */\n tellWorkerToIdentify: (workerId: number, shardId: number, bucketId: number) => Promise<void>\n /** Tell the manager to identify a Shard. If this Shard is not already managed this will also add the Shard to the manager. */\n identify: (shardId: number) => Promise<void>\n /** Kill a shard. Close a shards connection to Discord's gateway (if any) and remove it from the manager. */\n kill: (shardId: number) => Promise<void>\n /** This function makes sure that the bucket is allowed to make the next identify request. */\n requestIdentify: (shardId: number) => Promise<void>\n /** Calculates the number of shards based on the guild id and total shards. */\n calculateShardId: (guildId: BigString, totalShards?: number) => number\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 joinVoiceChannel: (guildId: BigString, channelId: BigString, options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>) => Promise<void>\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 editBotStatus: (data: StatusUpdate) => Promise<void>\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 editShardStatus: (shardId: number, data: StatusUpdate) => Promise<void>\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 requestMembers: (guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>) => Promise<Camelize<DiscordMember[]>>\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 leaveVoiceChannel: (guildId: BigString) => Promise<void>\n}\n\nexport interface RequestMemberRequest {\n /** The unique nonce for this request. */\n nonce: string\n /** The resolver handler to run when all members arrive. */\n resolve: (value: Camelize<DiscordMember[]> | PromiseLike<Camelize<DiscordMember[]>>) => void\n /** The members that have already arrived for this request. */\n members: Camelize<DiscordMember[]>\n}\n"],"names":["Collection","delay","logger","Shard","createGatewayManager","options","connection","url","shards","sessionStartLimit","maxConcurrency","remaining","total","resetAfter","gateway","events","compress","intents","properties","os","process","platform","browser","device","token","version","totalShards","lastShardId","firstShardId","totalWorkers","shardsPerWorker","spawnShardDelay","preferSnakeCase","Map","buckets","cache","requestMembers","enabled","pending","calculateTotalShards","debug","Math","ceil","calculateWorkerId","shardId","workerId","prepareBuckets","i","set","workers","identifyRequests","Error","bucketId","bucket","get","worker","find","w","id","queue","push","values","sort","a","b","spawnShards","Promise","all","entries","map","tellWorkerToIdentify","shutdown","code","reason","forEach","shard","close","identify","requestIdentify","shardIsReady","shift","forwardToBot","payload","message","resolve","kill","delete","calculateShardId","guildId","Number","BigInt","joinVoiceChannel","channelId","editBotStatus","data","JSON","stringify","editShardStatus","leaveVoiceChannel"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/manager.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-confusing-void-expression */\nimport {\n GatewayIntents,\n GatewayOpcodes,\n type AtLeastOne,\n type BigString,\n type Camelize,\n type DiscordGetGatewayBot,\n type DiscordMember,\n type DiscordMemberWithUser,\n type RequestGuildMembers,\n} from '@discordeno/types'\nimport { camelize, Collection, delay, logger } from '@discordeno/utils'\nimport Shard from './Shard.js'\nimport type { ShardEvents, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js'\n\nexport function createGatewayManager(options: CreateGatewayManagerOptions): GatewayManager {\n const connectionOptions = options.connection ?? {\n url: 'wss://gateway.discord.gg',\n shards: 1,\n sessionStartLimit: {\n maxConcurrency: 1,\n remaining: 1000,\n total: 1000,\n resetAfter: 1000 * 60 * 60 * 24,\n },\n }\n\n options.events.guildMemberChunk ??= (payload) => {\n // If it's not enabled skip checks.\n if (!gateway.cache.requestMembers?.enabled) return\n\n // If this request has no nonce, skip checks.\n if (!payload.nonce) return\n\n const pending = gateway.cache.requestMembers.pending.get(payload.nonce)\n if (!pending) return\n\n if (payload.chunk_count === 1) pending.members = payload.members\n else pending.members.push(...payload.members)\n\n // If this is not the final chunk, just save to cache.\n if (payload.chunk_index + 1 < payload.chunk_count) return\n\n // Resolve the promise that all requests are done.\n pending.resolve(camelize(pending.members))\n\n // Delete the cache to clean up once its done.\n gateway.cache.requestMembers.pending.delete(payload.nonce)\n }\n\n const gateway: GatewayManager = {\n events: options.events,\n compress: options.compress ?? false,\n intents: options.intents ?? 0,\n properties: {\n os: options.properties?.os ?? process.platform,\n browser: options.properties?.browser ?? 'Discordeno',\n device: options.properties?.device ?? 'Discordeno',\n },\n token: options.token,\n url: options.url ?? connectionOptions.url ?? 'wss://gateway.discord.gg',\n version: options.version ?? 10,\n connection: connectionOptions,\n totalShards: options.totalShards ?? connectionOptions.shards ?? 1,\n lastShardId: options.lastShardId ?? (options.totalShards ? options.totalShards - 1 : connectionOptions ? connectionOptions.shards - 1 : 0),\n firstShardId: options.firstShardId ?? 0,\n totalWorkers: options.totalWorkers ?? 4,\n shardsPerWorker: options.shardsPerWorker ?? 25,\n spawnShardDelay: options.spawnShardDelay ?? 5300,\n preferSnakeCase: options.preferSnakeCase ?? false,\n shards: new Map(),\n buckets: new Map(),\n cache: {\n requestMembers: {\n enabled: options.cache?.requestMembers?.enabled ?? false,\n pending: new Collection(),\n },\n },\n\n calculateTotalShards() {\n // Bots under 100k servers do not have access to total shards.\n if (gateway.totalShards < 100) {\n logger.debug(`[Gateway] Calculating total shards: ${gateway.totalShards}`)\n return gateway.totalShards\n }\n\n logger.debug(`[Gateway] Calculating total shards`, gateway.totalShards, gateway.connection.sessionStartLimit.maxConcurrency)\n // Calculate a multiple of `maxConcurrency` which can be used to connect to the gateway.\n return (\n Math.ceil(\n gateway.totalShards /\n // If `maxConcurrency` is 1 we can safely use 16.\n (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency),\n ) * gateway.connection.sessionStartLimit.maxConcurrency\n )\n },\n calculateWorkerId(shardId) {\n const workerId = Math.min(shardId % gateway.shardsPerWorker, gateway.totalWorkers - 1)\n logger.debug(\n `[Gateway] Calculating workerId: Shard: ${shardId} -> Worker: ${workerId} -> Per Worker: ${gateway.shardsPerWorker} -> Total: ${gateway.totalWorkers}`,\n )\n return workerId\n },\n prepareBuckets() {\n for (let i = 0; i < gateway.connection.sessionStartLimit.maxConcurrency; ++i) {\n logger.debug(`[Gateway] Preparing buckets for concurrency: ${i}`)\n gateway.buckets.set(i, {\n workers: [],\n identifyRequests: [],\n })\n }\n\n // ORGANIZE ALL SHARDS INTO THEIR OWN BUCKETS\n for (let shardId = gateway.firstShardId; shardId <= gateway.lastShardId; ++shardId) {\n logger.debug(`[Gateway] Preparing buckets for shard: ${shardId}`)\n if (shardId >= gateway.totalShards) {\n throw new Error(`Shard (id: ${shardId}) is bigger or equal to the used amount of used shards which is ${gateway.totalShards}`)\n }\n\n const bucketId = shardId % gateway.connection.sessionStartLimit.maxConcurrency\n const bucket = gateway.buckets.get(bucketId)\n if (!bucket) {\n throw new Error(\n `Shard (id: ${shardId}) got assigned to an illegal bucket id: ${bucketId}, expected a bucket id between 0 and ${\n gateway.connection.sessionStartLimit.maxConcurrency - 1\n }`,\n )\n }\n\n // FIND A QUEUE IN THIS BUCKET THAT HAS SPACE\n // const worker = bucket.workers.find((w) => w.queue.length < gateway.shardsPerWorker);\n const workerId = gateway.calculateWorkerId(shardId)\n const worker = bucket.workers.find((w) => w.id === workerId)\n if (worker) {\n // IF THE QUEUE HAS SPACE JUST ADD IT TO THIS QUEUE\n worker.queue.push(shardId)\n } else {\n bucket.workers.push({ id: workerId, queue: [shardId] })\n }\n }\n\n for (const bucket of gateway.buckets.values()) {\n for (const worker of bucket.workers.values()) {\n // eslint-disable-next-line @typescript-eslint/require-array-sort-compare\n worker.queue = worker.queue.sort((a, b) => a - b)\n }\n }\n },\n async spawnShards() {\n // PREPARES ALL SHARDS IN SPECIFIC BUCKETS\n gateway.prepareBuckets()\n\n // Prefer concurrency of forEach instead of forof\n await Promise.all(\n [...gateway.buckets.entries()].map(async ([bucketId, bucket]) => {\n for (const worker of bucket.workers) {\n for (const shardId of worker.queue) {\n await gateway.tellWorkerToIdentify(worker.id, shardId, bucketId)\n }\n }\n }),\n )\n },\n async shutdown(code, reason) {\n gateway.shards.forEach((shard) => shard.close(code, reason))\n\n await delay(5000)\n },\n async sendPayload(shardId, payload) {\n const shard = gateway.shards.get(shardId)\n\n if (!shard) {\n throw new Error(`Shard (id: ${shardId} not found`)\n }\n\n await shard.send(payload)\n },\n async tellWorkerToIdentify(workerId, shardId, bucketId) {\n logger.debug(`[Gateway] tell worker to identify (${workerId}, ${shardId}, ${bucketId})`)\n await gateway.identify(shardId)\n },\n async identify(shardId: number) {\n let shard = this.shards.get(shardId)\n logger.debug(`[Gateway] identifying ${shard ? 'existing' : 'new'} shard (${shardId})`)\n\n if (!shard) {\n shard = new Shard({\n id: shardId,\n connection: {\n compress: this.compress,\n intents: this.intents,\n properties: this.properties,\n token: this.token,\n totalShards: this.totalShards,\n url: this.url,\n version: this.version,\n },\n events: options.events,\n requestIdentify: async () => {\n await gateway.identify(shardId)\n },\n shardIsReady: async () => {\n logger.debug(`[Shard] Shard #${shardId} is ready`)\n await delay(gateway.spawnShardDelay)\n logger.debug(`[Shard] Resolving shard identify request`)\n gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)!.identifyRequests.shift()?.()\n },\n })\n\n if (this.preferSnakeCase) {\n shard.forwardToBot = async (payload) => {\n options.events.message?.(shard!, payload)\n }\n }\n\n this.shards.set(shardId, shard)\n }\n\n const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)\n if (!bucket) return\n\n return await new Promise((resolve) => {\n // Mark that we are making an identify request so another is not made.\n bucket.identifyRequests.push(resolve)\n logger.debug(`[Gateway] identifying shard #(${shardId}).`)\n // This will trigger identify and when READY is received it will resolve the above request.\n shard?.identify()\n })\n },\n async kill(shardId: number) {\n const shard = this.shards.get(shardId)\n if (!shard) {\n return logger.debug(`[Gateway] kill shard but not found (${shardId})`)\n }\n\n logger.debug(`[Gateway] kill shard (${shardId})`)\n this.shards.delete(shardId)\n await shard.shutdown()\n },\n async requestIdentify(shardId: number) {\n logger.debug(`[Gateway] requesting identify`)\n // const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)\n // if (!bucket) return\n\n // return await new Promise((resolve) => {\n // bucket.identifyRequests.push(resolve)\n // })\n },\n\n // Helpers methods below this\n\n calculateShardId(guildId, totalShards) {\n // If none is provided, use the total shards number from gateway object.\n if (!totalShards) totalShards = gateway.totalShards\n // If it is only 1 shard, it will always be shard id 0\n if (totalShards === 1) {\n logger.debug(`[Gateway] calculateShardId (1 shard)`)\n return 0\n }\n\n logger.debug(`[Gateway] calculateShardId (guildId: ${guildId}, totalShards: ${totalShards})`)\n return Number((BigInt(guildId) >> 22n) % BigInt(totalShards))\n },\n\n async joinVoiceChannel(guildId, channelId, options) {\n const shardId = gateway.calculateShardId(guildId)\n\n logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`)\n\n await gateway.sendPayload(shardId, {\n op: GatewayOpcodes.VoiceStateUpdate,\n d: {\n guild_id: guildId.toString(),\n channel_id: channelId.toString(),\n self_mute: options?.selfMute ?? false,\n self_deaf: options?.selfDeaf ?? true,\n },\n })\n },\n\n async editBotStatus(data) {\n logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data)}`)\n\n await Promise.all(\n [...gateway.shards.values()].map(async (shard) => {\n gateway.editShardStatus(shard.id, data)\n }),\n )\n },\n\n async editShardStatus(shardId, data) {\n logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`)\n\n await gateway.sendPayload(shardId, {\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 async requestMembers(guildId, options) {\n const shardId = gateway.calculateShardId(guildId)\n\n if (gateway.intents && (!options?.limit || options.limit > 1) && !(gateway.intents & GatewayIntents.GuildMembers))\n throw new Error('Cannot fetch more then 1 member without the GUILD_MEMBERS intent')\n\n logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> data: ${JSON.stringify(options)}`)\n\n if (options?.userIds?.length) {\n logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`)\n\n options.limit = options.userIds.length\n }\n\n const members =\n !gateway.cache.requestMembers?.enabled || !options?.nonce\n ? []\n : new Promise<Camelize<DiscordMember[]>>((resolve, reject) => {\n // Should never happen.\n if (!gateway.cache.requestMembers?.enabled || !options?.nonce) {\n reject(new Error(\"Can't request the members without the nonce or with the feature disabled.\"))\n return\n }\n\n gateway.cache.requestMembers.pending.set(options.nonce, {\n nonce: options.nonce,\n resolve,\n members: [],\n })\n })\n\n await gateway.sendPayload(shardId, {\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: options?.nonce,\n },\n })\n\n return await members\n },\n\n async leaveVoiceChannel(guildId) {\n const shardId = gateway.calculateShardId(guildId)\n\n logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`)\n\n await gateway.sendPayload(shardId, {\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\n return gateway\n}\n\nexport interface CreateGatewayManagerOptions {\n /**\n * Id of the first Shard which should get controlled by this manager.\n * @default 0\n */\n firstShardId?: number\n /**\n * Id of the last Shard which should get controlled by this manager.\n * @default 0\n */\n lastShardId?: number\n /**\n * Delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 5100. YOU DON'T WANT TO HIT THE RATE LIMIT!!!\n * @default 5300\n */\n spawnShardDelay?: number\n /**\n * Whether to send the discord packets in snake case form.\n * @default false\n */\n preferSnakeCase?: boolean\n /**\n * Total amount of shards your bot uses. Useful for zero-downtime updates or resharding.\n * @default 1\n */\n totalShards?: number\n /**\n * The amount of shards to load per worker.\n * @default 25\n */\n shardsPerWorker?: number\n /**\n * The total amount of workers to use for your bot.\n * @default 4\n */\n totalWorkers?: number\n /** Important data which is used by the manager to connect shards to the gateway. */\n connection?: Camelize<DiscordGetGatewayBot>\n /** Whether incoming payloads are compressed using zlib.\n *\n * @default false\n */\n compress?: boolean\n /** The calculated intent value of the events which the shard should receive.\n *\n * @default 0\n */\n intents?: number\n /** Identify properties to use */\n properties?: {\n /** Operating system the shard runs on.\n *\n * @default \"darwin\" | \"linux\" | \"windows\"\n */\n os: string\n /** The \"browser\" where this shard is running on.\n *\n * @default \"Discordeno\"\n */\n browser: string\n /** The device on which the shard is running.\n *\n * @default \"Discordeno\"\n */\n device: string\n }\n /** Bot token which is used to connect to Discord */\n token: string\n /** The URL of the gateway which should be connected to.\n *\n * @default \"wss://gateway.discord.gg\"\n */\n url?: string\n /** The gateway version which should be used.\n *\n * @default 10\n */\n version?: number\n /** The events handlers */\n events: ShardEvents\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?: boolean\n /** The pending requests. */\n pending: Collection<string, RequestMemberRequest>\n }\n }\n}\n\nexport interface GatewayManager extends Required<CreateGatewayManagerOptions> {\n /** The max concurrency buckets. Those will be created when the `spawnShards` (which calls `prepareBuckets` under the hood) function gets called. */\n buckets: Map<\n number,\n {\n workers: Array<{ id: number; queue: number[] }>\n /** Requests to identify shards are made based on whether it is available to be made. */\n identifyRequests: Array<(value: void | PromiseLike<void>) => void>\n }\n >\n /** The shards that are created. */\n shards: Map<number, Shard>\n /** Determine max number of shards to use based upon the max concurrency. */\n calculateTotalShards: () => number\n /** Determine the id of the worker which is handling a shard. */\n calculateWorkerId: (shardId: number) => number\n /** Prepares all the buckets that are available for identifying the shards. */\n prepareBuckets: () => void\n /** Start identifying all the shards. */\n spawnShards: () => Promise<void>\n /** Shutdown all shards. */\n shutdown: (code: number, reason: string) => Promise<void>\n sendPayload: (shardId: number, payload: ShardSocketRequest) => Promise<void>\n /** Allows users to hook in and change to communicate to different workers across different servers or anything they like. For example using redis pubsub to talk to other servers. */\n tellWorkerToIdentify: (workerId: number, shardId: number, bucketId: number) => Promise<void>\n /** Tell the manager to identify a Shard. If this Shard is not already managed this will also add the Shard to the manager. */\n identify: (shardId: number) => Promise<void>\n /** Kill a shard. Close a shards connection to Discord's gateway (if any) and remove it from the manager. */\n kill: (shardId: number) => Promise<void>\n /** This function makes sure that the bucket is allowed to make the next identify request. */\n requestIdentify: (shardId: number) => Promise<void>\n /** Calculates the number of shards based on the guild id and total shards. */\n calculateShardId: (guildId: BigString, totalShards?: number) => number\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 joinVoiceChannel: (guildId: BigString, channelId: BigString, options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>) => Promise<void>\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 editBotStatus: (data: StatusUpdate) => Promise<void>\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 editShardStatus: (shardId: number, data: StatusUpdate) => Promise<void>\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 requestMembers: (guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>) => Promise<Camelize<DiscordMember[]>>\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 leaveVoiceChannel: (guildId: BigString) => Promise<void>\n}\n\nexport interface RequestMemberRequest {\n /** The unique nonce for this request. */\n nonce: string\n /** The resolver handler to run when all members arrive. */\n resolve: (value: Camelize<DiscordMember[]> | PromiseLike<Camelize<DiscordMember[]>>) => void\n /** The members that have already arrived for this request. */\n members: DiscordMemberWithUser[]\n}\n"],"names":["GatewayIntents","GatewayOpcodes","camelize","Collection","delay","logger","Shard","createGatewayManager","options","connectionOptions","connection","url","shards","sessionStartLimit","maxConcurrency","remaining","total","resetAfter","events","guildMemberChunk","payload","gateway","cache","requestMembers","enabled","nonce","pending","get","chunk_count","members","push","chunk_index","resolve","delete","compress","intents","properties","os","process","platform","browser","device","token","version","totalShards","lastShardId","firstShardId","totalWorkers","shardsPerWorker","spawnShardDelay","preferSnakeCase","Map","buckets","calculateTotalShards","debug","Math","ceil","calculateWorkerId","shardId","workerId","min","prepareBuckets","i","set","workers","identifyRequests","Error","bucketId","bucket","worker","find","w","id","queue","values","sort","a","b","spawnShards","Promise","all","entries","map","tellWorkerToIdentify","shutdown","code","reason","forEach","shard","close","sendPayload","send","identify","requestIdentify","shardIsReady","shift","forwardToBot","message","kill","calculateShardId","guildId","Number","BigInt","joinVoiceChannel","channelId","op","VoiceStateUpdate","d","guild_id","toString","channel_id","self_mute","selfMute","self_deaf","selfDeaf","editBotStatus","data","JSON","stringify","editShardStatus","PresenceUpdate","since","afk","activities","status","limit","GuildMembers","userIds","length","reject","RequestGuildMembers","query","undefined","presences","user_ids","leaveVoiceChannel"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import type { ActivityTypes, Camelize, DiscordActivity, DiscordGatewayPayload, GatewayOpcodes, PresenceStatus } from '@discordeno/types';
2
+ import type { ActivityTypes, Camelize, DiscordActivity, DiscordGatewayPayload, DiscordGuildMembersChunk, GatewayOpcodes, PresenceStatus } from '@discordeno/types';
3
3
  import type Shard from './Shard.js';
4
4
  export declare enum ShardState {
5
5
  /** Shard is fully connected to the gateway and receiving events from Discord. */
@@ -110,6 +110,7 @@ export interface ShardEvents {
110
110
  identified?: (shard: Shard) => unknown;
111
111
  /** The shard has received a message from Discord. */
112
112
  message?: (shard: Shard, payload: Camelize<DiscordGatewayPayload>) => unknown;
113
+ guildMemberChunk?: (payload: DiscordGuildMembersChunk) => unknown;
113
114
  }
114
115
  export declare enum ShardSocketCloseCodes {
115
116
  /** A regular Shard shutdown. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { ActivityTypes, Camelize, DiscordActivity, DiscordGatewayPayload, GatewayOpcodes, PresenceStatus } from '@discordeno/types'\nimport type Shard from './Shard.js'\n\nexport enum ShardState {\n /** Shard is fully connected to the gateway and receiving events from Discord. */\n Connected = 0,\n /** Shard started to connect to the gateway. This is only used if the shard is not currently trying to identify or resume. */\n Connecting = 1,\n /** Shard got disconnected and reconnection actions have been started. */\n Disconnected = 2,\n /** The shard is connected to the gateway but only heartbeating. At this state the shard has not been identified with discord. */\n Unidentified = 3,\n /** Shard is trying to identify with the gateway to create a new session. */\n Identifying = 4,\n /** Shard is trying to resume a session with the gateway. */\n Resuming = 5,\n /** Shard got shut down studied or due to a not (self) fixable error and may not attempt to reconnect on its own. */\n Offline = 6,\n}\n\nexport interface ShardGatewayConfig {\n /** Whether incoming payloads are compressed using zlib.\n *\n * @default false\n */\n compress: boolean\n /** The calculated intent value of the events which the shard should receive.\n *\n * @default 0\n */\n intents: number\n /** Identify properties to use */\n properties: {\n /** Operating system the shard runs on.\n *\n * @default \"darwin\" | \"linux\" | \"windows\"\n */\n os: string\n /** The \"browser\" where this shard is running on.\n *\n * @default \"Discordeno\"\n */\n browser: string\n /** The device on which the shard is running.\n *\n * @default \"Discordeno\"\n */\n device: string\n }\n /** Bot token which is used to connect to Discord */\n token: string\n /** The URL of the gateway which should be connected to.\n *\n * @default \"wss://gateway.discord.gg\"\n */\n url: string\n /** The gateway version which should be used.\n *\n * @default 10\n */\n version: number\n /**\n * The total number of shards to connect to across the entire bot.\n * @default 1\n */\n totalShards: number\n}\n\nexport interface ShardHeart {\n /** Whether or not the heartbeat was acknowledged by Discord in time. */\n acknowledged: boolean\n /** Interval between heartbeats requested by Discord. */\n interval: number\n /** Id of the interval, which is used for sending the heartbeats. */\n intervalId?: NodeJS.Timer\n /** Unix (in milliseconds) timestamp when the last heartbeat ACK was received from Discord. */\n lastAck?: number\n /** Unix timestamp (in milliseconds) when the last heartbeat was sent. */\n lastBeat?: number\n /** Round trip time (in milliseconds) from Shard to Discord and back.\n * Calculated using the heartbeat system.\n * Note: this value is undefined until the first heartbeat to Discord has happened.\n */\n rtt?: number\n /** Id of the timeout which is used for sending the first heartbeat to Discord since it's \"special\". */\n timeoutId?: NodeJS.Timeout\n}\n\nexport interface ShardEvents {\n /** A heartbeat has been send. */\n heartbeat?: (shard: Shard) => unknown\n /** A heartbeat ACK was received. */\n heartbeatAck?: (shard: Shard) => unknown\n /** Shard has received a Hello payload. */\n hello?: (shard: Shard) => unknown\n /** The Shards session has been invalidated. */\n invalidSession?: (shard: Shard, resumable: boolean) => unknown\n /** The shard has started a resume action. */\n resuming?: (shard: Shard) => unknown\n /** The shard has successfully resumed an old session. */\n resumed?: (shard: Shard) => unknown\n /** Discord has requested the Shard to reconnect. */\n requestedReconnect?: (shard: Shard) => unknown\n /** The shard started to connect to Discord's gateway. */\n connecting?: (shard: Shard) => unknown\n /** The shard is connected with Discord's gateway. */\n connected?: (shard: Shard) => unknown\n /** The shard has been disconnected from Discord's gateway. */\n disconnected?: (shard: Shard) => unknown\n /** The shard has started to identify itself to Discord. */\n identifying?: (shard: Shard) => unknown\n /** The shard has successfully been identified itself with Discord. */\n identified?: (shard: Shard) => unknown\n /** The shard has received a message from Discord. */\n message?: (shard: Shard, payload: Camelize<DiscordGatewayPayload>) => unknown\n}\n\nexport enum ShardSocketCloseCodes {\n /** A regular Shard shutdown. */\n Shutdown = 3000,\n /** A resume has been requested and therefore the old connection needs to be closed. */\n ResumeClosingOldConnection = 3024,\n /** Did not receive a heartbeat ACK in time.\n * Closing the shard and creating a new session.\n */\n ZombiedConnection = 3010,\n /** Discordeno's gateway tests hae been finished, therefore the Shard can be turned off. */\n TestingFinished = 3064,\n /** Special close code reserved for Discordeno's zero-downtime resharding system. */\n Resharded = 3065,\n /** Shard is re-identifying therefore the old connection needs to be closed. */\n ReIdentifying = 3066,\n}\n\nexport interface ShardSocketRequest {\n /** The OP-Code for the payload to send. */\n op: GatewayOpcodes\n /** Payload data. */\n d: unknown\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#update-presence */\nexport interface BotStatusUpdate {\n // /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */\n since: number | null\n /** The user's activities */\n activities: BotActivity[]\n /** The user's new status */\n status: keyof typeof PresenceStatus\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#activity-object */\nexport interface BotActivity {\n name: string\n type: ActivityTypes\n url?: string\n}\n\n/** https://discord.com/developers/docs/topics/gateway#update-voice-state */\nexport interface UpdateVoiceState {\n /** id of the guild */\n guildId: string\n /** id of the voice channel client wants to join (null if disconnecting) */\n channelId: string | null\n /** Is the client muted */\n selfMute: boolean\n /** Is the client deafened */\n selfDeaf: boolean\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#update-presence */\nexport interface StatusUpdate {\n // /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */\n // since: number | null;\n /** The user's activities */\n activities?: Camelize<Array<Omit<DiscordActivity, 'created_at'>>>\n /** The user's new status */\n status: keyof typeof PresenceStatus\n // /** Whether or not the client is afk */\n // afk: boolean;\n}\n"],"names":["ShardState","Connected","Connecting","Disconnected","Unidentified","Identifying","Resuming","Offline","ShardSocketCloseCodes","Shutdown","ResumeClosingOldConnection","ZombiedConnection","TestingFinished","Resharded","ReIdentifying"],"mappings":"WAGO;UAAKA,UAAU;IAAVA,WAAAA,WACV,+EAA+E,GAC/EC,eAAY,KAAZA;IAFUD,WAAAA,WAGV,2HAA2H,GAC3HE,gBAAa,KAAbA;IAJUF,WAAAA,WAKV,uEAAuE,GACvEG,kBAAe,KAAfA;IANUH,WAAAA,WAOV,+HAA+H,GAC/HI,kBAAe,KAAfA;IARUJ,WAAAA,WASV,0EAA0E,GAC1EK,iBAAc,KAAdA;IAVUL,WAAAA,WAWV,0DAA0D,GAC1DM,cAAW,KAAXA;IAZUN,WAAAA,WAaV,kHAAkH,GAClHO,aAAU,KAAVA;GAdUP,eAAAA;WAkHL;UAAKQ,qBAAqB;IAArBA,sBAAAA,sBACV,8BAA8B,GAC9BC,cAAW,QAAXA;IAFUD,sBAAAA,sBAGV,qFAAqF,GACrFE,gCAA6B,QAA7BA;IAJUF,sBAAAA,sBAKV;;GAEC,GACDG,uBAAoB,QAApBA;IARUH,sBAAAA,sBASV,yFAAyF,GACzFI,qBAAkB,QAAlBA;IAVUJ,sBAAAA,sBAWV,kFAAkF,GAClFK,eAAY,QAAZA;IAZUL,sBAAAA,sBAaV,6EAA6E,GAC7EM,mBAAgB,QAAhBA;GAdUN,0BAAAA"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n ActivityTypes,\n Camelize,\n DiscordActivity,\n DiscordGatewayPayload,\n DiscordGuildMembersChunk,\n GatewayOpcodes,\n PresenceStatus,\n} from '@discordeno/types'\nimport type Shard from './Shard.js'\n\nexport enum ShardState {\n /** Shard is fully connected to the gateway and receiving events from Discord. */\n Connected = 0,\n /** Shard started to connect to the gateway. This is only used if the shard is not currently trying to identify or resume. */\n Connecting = 1,\n /** Shard got disconnected and reconnection actions have been started. */\n Disconnected = 2,\n /** The shard is connected to the gateway but only heartbeating. At this state the shard has not been identified with discord. */\n Unidentified = 3,\n /** Shard is trying to identify with the gateway to create a new session. */\n Identifying = 4,\n /** Shard is trying to resume a session with the gateway. */\n Resuming = 5,\n /** Shard got shut down studied or due to a not (self) fixable error and may not attempt to reconnect on its own. */\n Offline = 6,\n}\n\nexport interface ShardGatewayConfig {\n /** Whether incoming payloads are compressed using zlib.\n *\n * @default false\n */\n compress: boolean\n /** The calculated intent value of the events which the shard should receive.\n *\n * @default 0\n */\n intents: number\n /** Identify properties to use */\n properties: {\n /** Operating system the shard runs on.\n *\n * @default \"darwin\" | \"linux\" | \"windows\"\n */\n os: string\n /** The \"browser\" where this shard is running on.\n *\n * @default \"Discordeno\"\n */\n browser: string\n /** The device on which the shard is running.\n *\n * @default \"Discordeno\"\n */\n device: string\n }\n /** Bot token which is used to connect to Discord */\n token: string\n /** The URL of the gateway which should be connected to.\n *\n * @default \"wss://gateway.discord.gg\"\n */\n url: string\n /** The gateway version which should be used.\n *\n * @default 10\n */\n version: number\n /**\n * The total number of shards to connect to across the entire bot.\n * @default 1\n */\n totalShards: number\n}\n\nexport interface ShardHeart {\n /** Whether or not the heartbeat was acknowledged by Discord in time. */\n acknowledged: boolean\n /** Interval between heartbeats requested by Discord. */\n interval: number\n /** Id of the interval, which is used for sending the heartbeats. */\n intervalId?: NodeJS.Timer\n /** Unix (in milliseconds) timestamp when the last heartbeat ACK was received from Discord. */\n lastAck?: number\n /** Unix timestamp (in milliseconds) when the last heartbeat was sent. */\n lastBeat?: number\n /** Round trip time (in milliseconds) from Shard to Discord and back.\n * Calculated using the heartbeat system.\n * Note: this value is undefined until the first heartbeat to Discord has happened.\n */\n rtt?: number\n /** Id of the timeout which is used for sending the first heartbeat to Discord since it's \"special\". */\n timeoutId?: NodeJS.Timeout\n}\n\nexport interface ShardEvents {\n /** A heartbeat has been send. */\n heartbeat?: (shard: Shard) => unknown\n /** A heartbeat ACK was received. */\n heartbeatAck?: (shard: Shard) => unknown\n /** Shard has received a Hello payload. */\n hello?: (shard: Shard) => unknown\n /** The Shards session has been invalidated. */\n invalidSession?: (shard: Shard, resumable: boolean) => unknown\n /** The shard has started a resume action. */\n resuming?: (shard: Shard) => unknown\n /** The shard has successfully resumed an old session. */\n resumed?: (shard: Shard) => unknown\n /** Discord has requested the Shard to reconnect. */\n requestedReconnect?: (shard: Shard) => unknown\n /** The shard started to connect to Discord's gateway. */\n connecting?: (shard: Shard) => unknown\n /** The shard is connected with Discord's gateway. */\n connected?: (shard: Shard) => unknown\n /** The shard has been disconnected from Discord's gateway. */\n disconnected?: (shard: Shard) => unknown\n /** The shard has started to identify itself to Discord. */\n identifying?: (shard: Shard) => unknown\n /** The shard has successfully been identified itself with Discord. */\n identified?: (shard: Shard) => unknown\n /** The shard has received a message from Discord. */\n message?: (shard: Shard, payload: Camelize<DiscordGatewayPayload>) => unknown\n /* The shard has received a GUILD_MEMBER_CHUNK from Discord and should be handled accordingly */\n guildMemberChunk?: (payload: DiscordGuildMembersChunk) => unknown\n}\n\nexport enum ShardSocketCloseCodes {\n /** A regular Shard shutdown. */\n Shutdown = 3000,\n /** A resume has been requested and therefore the old connection needs to be closed. */\n ResumeClosingOldConnection = 3024,\n /** Did not receive a heartbeat ACK in time.\n * Closing the shard and creating a new session.\n */\n ZombiedConnection = 3010,\n /** Discordeno's gateway tests hae been finished, therefore the Shard can be turned off. */\n TestingFinished = 3064,\n /** Special close code reserved for Discordeno's zero-downtime resharding system. */\n Resharded = 3065,\n /** Shard is re-identifying therefore the old connection needs to be closed. */\n ReIdentifying = 3066,\n}\n\nexport interface ShardSocketRequest {\n /** The OP-Code for the payload to send. */\n op: GatewayOpcodes\n /** Payload data. */\n d: unknown\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#update-presence */\nexport interface BotStatusUpdate {\n // /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */\n since: number | null\n /** The user's activities */\n activities: BotActivity[]\n /** The user's new status */\n status: keyof typeof PresenceStatus\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#activity-object */\nexport interface BotActivity {\n name: string\n type: ActivityTypes\n url?: string\n}\n\n/** https://discord.com/developers/docs/topics/gateway#update-voice-state */\nexport interface UpdateVoiceState {\n /** id of the guild */\n guildId: string\n /** id of the voice channel client wants to join (null if disconnecting) */\n channelId: string | null\n /** Is the client muted */\n selfMute: boolean\n /** Is the client deafened */\n selfDeaf: boolean\n}\n\n/** https://discord.com/developers/docs/topics/gateway-events#update-presence */\nexport interface StatusUpdate {\n // /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */\n // since: number | null;\n /** The user's activities */\n activities?: Camelize<Array<Omit<DiscordActivity, 'created_at'>>>\n /** The user's new status */\n status: keyof typeof PresenceStatus\n // /** Whether or not the client is afk */\n // afk: boolean;\n}\n"],"names":["ShardState","Connected","Connecting","Disconnected","Unidentified","Identifying","Resuming","Offline","ShardSocketCloseCodes","Shutdown","ResumeClosingOldConnection","ZombiedConnection","TestingFinished","Resharded","ReIdentifying"],"mappings":"WAWO;UAAKA,UAAU;IAAVA,WAAAA,WACV,+EAA+E,GAC/EC,eAAY,KAAZA;IAFUD,WAAAA,WAGV,2HAA2H,GAC3HE,gBAAa,KAAbA;IAJUF,WAAAA,WAKV,uEAAuE,GACvEG,kBAAe,KAAfA;IANUH,WAAAA,WAOV,+HAA+H,GAC/HI,kBAAe,KAAfA;IARUJ,WAAAA,WASV,0EAA0E,GAC1EK,iBAAc,KAAdA;IAVUL,WAAAA,WAWV,0DAA0D,GAC1DM,cAAW,KAAXA;IAZUN,WAAAA,WAaV,kHAAkH,GAClHO,aAAU,KAAVA;GAdUP,eAAAA;WAoHL;UAAKQ,qBAAqB;IAArBA,sBAAAA,sBACV,8BAA8B,GAC9BC,cAAW,QAAXA;IAFUD,sBAAAA,sBAGV,qFAAqF,GACrFE,gCAA6B,QAA7BA;IAJUF,sBAAAA,sBAKV;;GAEC,GACDG,uBAAoB,QAApBA;IARUH,sBAAAA,sBASV,yFAAyF,GACzFI,qBAAkB,QAAlBA;IAVUJ,sBAAAA,sBAWV,kFAAkF,GAClFK,eAAY,QAAZA;IAZUL,sBAAAA,sBAaV,6EAA6E,GAC7EM,mBAAgB,QAAhBA;GAdUN,0BAAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@discordeno/gateway",
3
- "version": "19.0.0-next.f8afb94",
3
+ "version": "19.0.0-next.f98bb9b",
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.f8afb94",
28
- "@discordeno/utils": "19.0.0-next.f8afb94",
27
+ "@discordeno/types": "19.0.0-next.f98bb9b",
28
+ "@discordeno/utils": "19.0.0-next.f98bb9b",
29
29
  "ws": "^8.13.0"
30
30
  },
31
31
  "devDependencies": {