seyfert 1.2.0 → 1.2.2

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.
Files changed (59) hide show
  1. package/lib/cache/index.d.ts +1 -5
  2. package/lib/cache/resources/voice-states.d.ts +7 -2
  3. package/lib/cache/resources/voice-states.js +11 -0
  4. package/lib/client/http/adapters/bun.d.ts +14 -0
  5. package/lib/client/http/adapters/bun.js +117 -0
  6. package/lib/client/http/adapters/index.d.ts +15 -0
  7. package/lib/client/http/adapters/index.js +27 -0
  8. package/lib/client/http/adapters/uws.d.ts +17 -0
  9. package/lib/client/http/adapters/uws.js +142 -0
  10. package/lib/client/http/httpclient.d.ts +13 -0
  11. package/lib/client/http/httpclient.js +48 -0
  12. package/lib/client/httpclient.js +31 -29
  13. package/lib/client/oninteractioncreate.js +7 -7
  14. package/lib/client/onmessagecreate.js +12 -3
  15. package/lib/client/workerclient.js +1 -1
  16. package/lib/commands/applications/chat.d.ts +11 -9
  17. package/lib/commands/applications/chat.js +9 -6
  18. package/lib/commands/applications/chatcontext.d.ts +2 -1
  19. package/lib/commands/applications/chatcontext.js +3 -0
  20. package/lib/commands/applications/menu.d.ts +4 -3
  21. package/lib/commands/applications/menu.js +9 -6
  22. package/lib/commands/applications/menucontext.d.ts +5 -2
  23. package/lib/commands/applications/menucontext.js +11 -2
  24. package/lib/commands/basecontex.d.ts +1 -1
  25. package/lib/commands/basecontex.js +5 -11
  26. package/lib/commands/decorators.d.ts +3 -3
  27. package/lib/commands/decorators.js +5 -5
  28. package/lib/commands/handler.js +2 -0
  29. package/lib/common/shorters/channels.d.ts +9 -2
  30. package/lib/common/shorters/channels.js +13 -0
  31. package/lib/common/shorters/members.d.ts +6 -0
  32. package/lib/common/shorters/members.js +6 -0
  33. package/lib/common/shorters/messages.d.ts +2 -2
  34. package/lib/common/shorters/messages.js +7 -3
  35. package/lib/components/componentcontext.d.ts +76 -4
  36. package/lib/components/componentcontext.js +68 -9
  37. package/lib/components/index.d.ts +1 -0
  38. package/lib/components/index.js +1 -0
  39. package/lib/structures/GuildMember.d.ts +1 -5
  40. package/lib/structures/GuildMember.js +2 -2
  41. package/lib/structures/Message.d.ts +1 -1
  42. package/lib/structures/User.js +3 -2
  43. package/lib/structures/VoiceState.d.ts +18 -0
  44. package/lib/structures/VoiceState.js +48 -0
  45. package/lib/structures/channels.d.ts +6 -3
  46. package/lib/structures/channels.js +14 -1
  47. package/lib/structures/extra/Permissions.d.ts +1 -1
  48. package/lib/structures/index.d.ts +1 -0
  49. package/lib/structures/index.js +1 -0
  50. package/lib/websocket/discord/shard.d.ts +4 -4
  51. package/lib/websocket/discord/shard.js +12 -17
  52. package/lib/websocket/discord/sharder.d.ts +1 -1
  53. package/lib/websocket/discord/sharder.js +2 -2
  54. package/lib/websocket/discord/workermanager.js +1 -1
  55. package/lib/websocket/structures/index.d.ts +6 -99
  56. package/lib/websocket/structures/index.js +29 -211
  57. package/lib/websocket/structures/timeout.d.ts +2 -2
  58. package/lib/websocket/structures/timeout.js +4 -4
  59. package/package.json +2 -2
@@ -3,38 +3,82 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ComponentContext = void 0;
4
4
  const v10_1 = require("discord-api-types/v10");
5
5
  const basecontex_1 = require("../commands/basecontex");
6
+ /**
7
+ * Represents a context for interacting with components in a Discord bot.
8
+ * @template Type - The type of component interaction.
9
+ */
6
10
  class ComponentContext extends basecontex_1.BaseContext {
7
11
  client;
8
12
  interaction;
13
+ /**
14
+ * Creates a new instance of the ComponentContext class.
15
+ * @param client - The UsingClient instance.
16
+ * @param interaction - The component interaction object.
17
+ */
9
18
  constructor(client, interaction) {
10
19
  super(client);
11
20
  this.client = client;
12
21
  this.interaction = interaction;
13
22
  }
23
+ /**
24
+ * Gets the proxy object.
25
+ */
14
26
  get proxy() {
15
27
  return this.client.proxy;
16
28
  }
29
+ /**
30
+ * Gets the language object for the interaction's locale.
31
+ */
17
32
  get t() {
18
33
  return this.client.langs.get(this.interaction?.locale ?? this.client.langs?.defaultLang ?? 'en-US');
19
34
  }
35
+ /**
36
+ * Gets the custom ID of the interaction.
37
+ */
20
38
  get customId() {
21
39
  return this.interaction.customId;
22
40
  }
23
- get write() {
24
- return this.interaction.write;
25
- }
41
+ /**
42
+ * Writes a response to the interaction.
43
+ * @param body - The body of the response.
44
+ * @param fetchReply - Whether to fetch the reply or not.
45
+ */
46
+ write(body, fetchReply) {
47
+ return this.interaction.write(body, fetchReply);
48
+ }
49
+ /**
50
+ * Defers the reply to the interaction.
51
+ * @param ephemeral - Whether the reply should be ephemeral or not.
52
+ */
26
53
  deferReply(ephemeral = false) {
27
54
  return this.interaction.deferReply(ephemeral ? v10_1.MessageFlags.Ephemeral : undefined);
28
55
  }
29
- get editResponse() {
30
- return this.interaction.editResponse;
31
- }
32
- get update() {
33
- return this.interaction.update;
34
- }
56
+ /**
57
+ * Edits the response of the interaction.
58
+ * @param body - The updated body of the response.
59
+ */
60
+ editResponse(body) {
61
+ return this.interaction.editResponse(body);
62
+ }
63
+ /**
64
+ * Updates the interaction with new data.
65
+ * @param body - The updated body of the interaction.
66
+ */
67
+ update(body) {
68
+ return this.interaction.update(body);
69
+ }
70
+ /**
71
+ * Edits the response or replies to the interaction.
72
+ * @param body - The body of the response or updated body of the interaction.
73
+ * @param fetchReply - Whether to fetch the reply or not.
74
+ */
35
75
  editOrReply(body, fetchReply) {
36
76
  return this.interaction.editOrReply(body, fetchReply);
37
77
  }
78
+ /**
79
+ * Deletes the response of the interaction.
80
+ * @returns A promise that resolves when the response is deleted.
81
+ */
38
82
  deleteResponse() {
39
83
  return this.interaction.deleteResponse();
40
84
  }
@@ -63,17 +107,32 @@ class ComponentContext extends basecontex_1.BaseContext {
63
107
  return this.client.guilds.fetch(this.guildId, mode === 'rest');
64
108
  }
65
109
  }
110
+ /**
111
+ * Gets the ID of the guild of the interaction.
112
+ */
66
113
  get guildId() {
67
114
  return this.interaction.guildId;
68
115
  }
116
+ /**
117
+ * Gets the ID of the channel of the interaction.
118
+ */
69
119
  get channelId() {
70
120
  return this.interaction.channelId;
71
121
  }
122
+ /**
123
+ * Gets the author of the interaction.
124
+ */
72
125
  get author() {
73
126
  return this.interaction.user;
74
127
  }
128
+ /**
129
+ * Gets the member of the interaction.
130
+ */
75
131
  get member() {
76
132
  return this.interaction.member;
77
133
  }
134
+ isComponent() {
135
+ return true;
136
+ }
78
137
  }
79
138
  exports.ComponentContext = ComponentContext;
@@ -10,6 +10,7 @@ import { UserSelectMenuComponent } from './UserSelectMenuComponent';
10
10
  export type MessageComponents = ButtonComponent | LinkButtonComponent | RoleSelectMenuComponent | UserSelectMenuComponent | StringSelectMenuComponent | ChannelSelectMenuComponent | MentionableSelectMenuComponent | TextInputComponent;
11
11
  export type ActionRowMessageComponents = Exclude<MessageComponents, TextInputComponent>;
12
12
  export * from './command';
13
+ export * from './componentcontext';
13
14
  /**
14
15
  * Return a new component instance based on the component type.
15
16
  *
@@ -24,6 +24,7 @@ const RoleSelectMenuComponent_1 = require("./RoleSelectMenuComponent");
24
24
  const StringSelectMenuComponent_1 = require("./StringSelectMenuComponent");
25
25
  const UserSelectMenuComponent_1 = require("./UserSelectMenuComponent");
26
26
  __exportStar(require("./command"), exports);
27
+ __exportStar(require("./componentcontext"), exports);
27
28
  /**
28
29
  * Return a new component instance based on the component type.
29
30
  *
@@ -31,11 +31,7 @@ export declare class BaseGuildMember extends DiscordBase {
31
31
  } & {
32
32
  guild_id: string;
33
33
  }) | undefined>;
34
- voice(): import("..").ReturnCache<(Omit<import("discord-api-types/v10").GatewayVoiceState, "member"> & {
35
- guild_id: string;
36
- } & {
37
- guild_id: string;
38
- }) | undefined>;
34
+ voice(): import("..").ReturnCache<import("./VoiceState").VoiceState | undefined>;
39
35
  toString(): string;
40
36
  private patch;
41
37
  get roles(): {
@@ -34,10 +34,10 @@ class BaseGuildMember extends DiscordBase_1.DiscordBase {
34
34
  return this.client.members.edit(this.guildId, this.id, body, reason);
35
35
  }
36
36
  presence() {
37
- return this.cache.presences?.get(this.id);
37
+ return this.client.members.presence(this.id);
38
38
  }
39
39
  voice() {
40
- return this.cache.voiceStates?.get(this.id, this.guildId);
40
+ return this.client.members.voice(this.guildId, this.id);
41
41
  }
42
42
  toString() {
43
43
  return `<@${this.id}>`;
@@ -44,7 +44,7 @@ export declare class Message extends BaseMessage {
44
44
  reply(body: Omit<MessageCreateBodyRequest, 'message_reference'>, fail?: boolean): Promise<Message>;
45
45
  edit(body: MessageUpdateBodyRequest): Promise<Message>;
46
46
  write(body: MessageCreateBodyRequest): Promise<Message>;
47
- delete(reason?: string): Promise<void | undefined>;
47
+ delete(reason?: string): Promise<void>;
48
48
  crosspost(reason?: string): Promise<Message>;
49
49
  }
50
50
  export type EditMessageWebhook = Omit<MessageWebhookMethodEditParams, 'messageId'>;
@@ -26,7 +26,8 @@ class User extends DiscordBase_1.DiscordBase {
26
26
  }
27
27
  avatarURL(options) {
28
28
  if (!this.avatar) {
29
- return this.rest.cdn.defaultAvatar(Number(this.discriminator));
29
+ const avatarIndex = this.discriminator === '0' ? Number(BigInt(this.id) >> 22n) % 6 : Number.parseInt(this.discriminator) % 5;
30
+ return this.rest.cdn.defaultAvatar(avatarIndex);
30
31
  }
31
32
  return this.rest.cdn.avatar(this.id, this.avatar, options);
32
33
  }
@@ -36,7 +37,7 @@ class User extends DiscordBase_1.DiscordBase {
36
37
  return this.rest.cdn.banner(this.id, this.banner, options);
37
38
  }
38
39
  presence() {
39
- return this.cache.presences?.get(this.id);
40
+ return this.client.members.presence(this.id);
40
41
  }
41
42
  toString() {
42
43
  return `<@${this.id}>`;
@@ -0,0 +1,18 @@
1
+ import type { GuildMember, UsingClient } from '../';
2
+ import type { VoiceStateResource } from '../cache/resources/voice-states';
3
+ import type { ObjectToLower } from '../common';
4
+ import { Base } from './extra/Base';
5
+ export interface VoiceState extends Base, ObjectToLower<VoiceStateResource> {
6
+ }
7
+ export declare class VoiceState extends Base {
8
+ private withMember?;
9
+ constructor(client: UsingClient, data: VoiceStateResource, withMember?: GuildMember | undefined);
10
+ isMuted(): boolean;
11
+ member(force?: boolean): Promise<GuildMember>;
12
+ user(force?: boolean): Promise<import("./User").User>;
13
+ channel(force?: boolean): Promise<import("./channels").BaseChannel<import("discord-api-types/v10").ChannelType> | import("./channels").DMChannel | import("./channels").CategoryChannel | undefined>;
14
+ setMute(mute?: boolean, reason?: string): Promise<GuildMember>;
15
+ setDeaf(deaf?: boolean, reason?: string): Promise<GuildMember>;
16
+ disconnect(reason?: string): Promise<GuildMember>;
17
+ setChannel(channel_id: null | string, reason?: string): Promise<GuildMember>;
18
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VoiceState = void 0;
4
+ const Base_1 = require("./extra/Base");
5
+ class VoiceState extends Base_1.Base {
6
+ withMember;
7
+ constructor(client, data, withMember) {
8
+ super(client);
9
+ this.withMember = withMember;
10
+ this.__patchThis(data);
11
+ }
12
+ isMuted() {
13
+ return this.mute || this.selfMute;
14
+ }
15
+ async member(force) {
16
+ return (this.withMember ??= await this.client.members.fetch(this.guildId, this.userId, force));
17
+ }
18
+ async user(force) {
19
+ return this.client.users.fetch(this.userId, force);
20
+ }
21
+ async channel(force) {
22
+ if (!this.channelId)
23
+ return;
24
+ return this.client.channels.fetch(this.channelId, force);
25
+ }
26
+ async setMute(mute = !this.mute, reason) {
27
+ return this.client.members.edit(this.guildId, this.userId, { mute }, reason).then(member => {
28
+ this.mute = mute;
29
+ return member;
30
+ });
31
+ }
32
+ async setDeaf(deaf = !this.deaf, reason) {
33
+ return this.client.members.edit(this.guildId, this.userId, { deaf }, reason).then(member => {
34
+ this.deaf = deaf;
35
+ return member;
36
+ });
37
+ }
38
+ async disconnect(reason) {
39
+ return this.setChannel(null, reason);
40
+ }
41
+ async setChannel(channel_id, reason) {
42
+ return this.client.members.edit(this.guildId, this.userId, { channel_id }, reason).then(member => {
43
+ this.channelId = channel_id;
44
+ return member;
45
+ });
46
+ }
47
+ }
48
+ exports.VoiceState = VoiceState;
@@ -1,4 +1,4 @@
1
- import { type APIChannelBase, type APIGuildChannel, type APIGuildForumDefaultReactionEmoji, type APIGuildForumTag, ChannelType, type RESTGetAPIChannelMessageReactionUsersQuery, type RESTPatchAPIChannelJSONBody, type RESTPatchAPIGuildChannelPositionsJSONBody, type RESTPostAPIChannelWebhookJSONBody, type RESTPostAPIGuildChannelJSONBody, type SortOrderType, VideoQualityMode, type APIDMChannel, type APIGuildCategoryChannel, type APIGuildForumChannel, type APIGuildMediaChannel, type APIGuildStageVoiceChannel, type APIGuildVoiceChannel, type APINewsChannel, type APITextChannel, type APIThreadChannel, type ThreadAutoArchiveDuration } from 'discord-api-types/v10';
1
+ import { ChannelType, VideoQualityMode, type APIChannelBase, type APIDMChannel, type APIGuildCategoryChannel, type APIGuildChannel, type APIGuildForumChannel, type APIGuildForumDefaultReactionEmoji, type APIGuildForumTag, type APIGuildMediaChannel, type APIGuildStageVoiceChannel, type APIGuildVoiceChannel, type APINewsChannel, type APITextChannel, type APIThreadChannel, type RESTGetAPIChannelMessageReactionUsersQuery, type RESTPatchAPIChannelJSONBody, type RESTPatchAPIGuildChannelPositionsJSONBody, type RESTPostAPIChannelWebhookJSONBody, type RESTPostAPIGuildChannelJSONBody, type RESTPostAPIGuildForumThreadsJSONBody, type SortOrderType, type ThreadAutoArchiveDuration } from 'discord-api-types/v10';
2
2
  import type { UsingClient } from '../commands';
3
3
  import type { EmojiResolvable, MessageCreateBodyRequest, MessageUpdateBodyRequest, MethodContext, ObjectToLower, StringToNumber, ToClass } from '../common';
4
4
  import type { GuildMember } from './GuildMember';
@@ -108,7 +108,7 @@ export declare class MessagesMethods extends DiscordBase {
108
108
  write: (body: MessageCreateBodyRequest) => Promise<import("./Message").Message>;
109
109
  edit: (messageId: string, body: MessageUpdateBodyRequest) => Promise<import("./Message").Message>;
110
110
  crosspost: (messageId: string, reason?: string) => Promise<import("./Message").Message>;
111
- delete: (messageId: string, reason?: string) => Promise<void | undefined>;
111
+ delete: (messageId: string, reason?: string) => Promise<void>;
112
112
  fetch: (messageId: string) => Promise<import("./Message").Message>;
113
113
  purge: (messages: string[], reason?: string) => Promise<never>;
114
114
  };
@@ -129,7 +129,7 @@ export declare class MessagesMethods extends DiscordBase {
129
129
  write: (body: MessageCreateBodyRequest) => Promise<import("./Message").Message>;
130
130
  edit: (messageId: string, body: MessageUpdateBodyRequest) => Promise<import("./Message").Message>;
131
131
  crosspost: (messageId: string, reason?: string) => Promise<import("./Message").Message>;
132
- delete: (messageId: string, reason?: string) => Promise<void | undefined>;
132
+ delete: (messageId: string, reason?: string) => Promise<void>;
133
133
  fetch: (messageId: string) => Promise<import("./Message").Message>;
134
134
  purge: (messages: string[], reason?: string) => Promise<never>;
135
135
  };
@@ -168,14 +168,17 @@ export declare class ThreadOnlyMethods extends DiscordBase {
168
168
  setReactionEmoji(emoji: APIGuildForumDefaultReactionEmoji, reason?: string): Promise<AllChannels>;
169
169
  setSortOrder(sort: SortOrderType, reason?: string): Promise<AllChannels>;
170
170
  setThreadRateLimit(rate: number, reason?: string): Promise<AllChannels>;
171
+ thread(body: RESTPostAPIGuildForumThreadsJSONBody, reason?: string): Promise<ThreadChannel>;
171
172
  }
172
173
  export interface VoiceChannelMethods extends BaseChannel<ChannelType> {
173
174
  }
174
175
  export declare class VoiceChannelMethods extends DiscordBase {
176
+ guildId?: string;
175
177
  setBitrate(bitrate: number | null, reason?: string): Promise<AllChannels>;
176
178
  setUserLimit(user_limit: number | null, reason?: string): Promise<AllChannels>;
177
179
  setRTC(rtc_region: string | null, reason?: string): Promise<AllChannels>;
178
180
  setVideoQuality(quality: keyof typeof VideoQualityMode, reason?: string): Promise<AllChannels>;
181
+ states(): Promise<import("./VoiceState").VoiceState[]>;
179
182
  }
180
183
  export declare class WebhookGuildMethods extends DiscordBase {
181
184
  webhooks: {
@@ -229,12 +229,16 @@ let ThreadOnlyMethods = class ThreadOnlyMethods extends DiscordBase_1.DiscordBas
229
229
  setThreadRateLimit(rate, reason) {
230
230
  return this.edit({ default_thread_rate_limit_per_user: rate }, reason);
231
231
  }
232
+ async thread(body, reason) {
233
+ return this.client.channels.thread(this.id, body, reason);
234
+ }
232
235
  };
233
236
  exports.ThreadOnlyMethods = ThreadOnlyMethods;
234
237
  exports.ThreadOnlyMethods = ThreadOnlyMethods = __decorate([
235
238
  (0, ts_mixer_1.mix)(TopicableGuildChannel)
236
239
  ], ThreadOnlyMethods);
237
240
  class VoiceChannelMethods extends DiscordBase_1.DiscordBase {
241
+ guildId;
238
242
  setBitrate(bitrate, reason) {
239
243
  return this.edit({ bitrate }, reason);
240
244
  }
@@ -247,13 +251,22 @@ class VoiceChannelMethods extends DiscordBase_1.DiscordBase {
247
251
  setVideoQuality(quality, reason) {
248
252
  return this.edit({ video_quality_mode: v10_1.VideoQualityMode[quality] }, reason);
249
253
  }
254
+ async states() {
255
+ if (!this.guildId)
256
+ return [];
257
+ const states = await this.cache.voiceStates?.values(this.guildId);
258
+ if (!states?.length)
259
+ return [];
260
+ const filter = states.filter(state => state.channelId === this.id);
261
+ return filter;
262
+ }
250
263
  }
251
264
  exports.VoiceChannelMethods = VoiceChannelMethods;
252
265
  class WebhookGuildMethods extends DiscordBase_1.DiscordBase {
253
266
  webhooks = WebhookGuildMethods.guild({ client: this.client, guildId: this.id });
254
267
  static guild(ctx) {
255
268
  return {
256
- list: () => ctx.client.webhooks.listFromChannel(ctx.guildId),
269
+ list: () => ctx.client.webhooks.listFromGuild(ctx.guildId),
257
270
  };
258
271
  }
259
272
  }
@@ -53,7 +53,7 @@ export declare class PermissionsBitField extends BitField<typeof PermissionFlags
53
53
  readonly SendVoiceMessages: bigint;
54
54
  };
55
55
  static All: bigint;
56
- keys: (bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) => PermissionStrings;
56
+ keys: (bits?: BitFieldResolvable<typeof PermissionFlagsBits>[]) => PermissionStrings;
57
57
  has(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]): boolean;
58
58
  strictHas(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]): boolean;
59
59
  }
@@ -11,5 +11,6 @@ export * from './Interaction';
11
11
  export * from './Message';
12
12
  export * from './Sticker';
13
13
  export * from './User';
14
+ export * from './VoiceState';
14
15
  export * from './Webhook';
15
16
  export * from './channels';
@@ -27,5 +27,6 @@ __exportStar(require("./Interaction"), exports);
27
27
  __exportStar(require("./Message"), exports);
28
28
  __exportStar(require("./Sticker"), exports);
29
29
  __exportStar(require("./User"), exports);
30
+ __exportStar(require("./VoiceState"), exports);
30
31
  __exportStar(require("./Webhook"), exports);
31
32
  __exportStar(require("./channels"), exports);
@@ -3,7 +3,7 @@ import type { GatewayReceivePayload, GatewaySendPayload } from 'discord-api-type
3
3
  import type WS from 'ws';
4
4
  import { type CloseEvent } from 'ws';
5
5
  import type { Logger } from '../../common';
6
- import { DynamicBucket, PriorityQueue } from '../structures';
6
+ import { DynamicBucket } from '../structures';
7
7
  import { ConnectTimeout } from '../structures/timeout';
8
8
  import { BaseSocket } from './basesocket';
9
9
  import type { ShardData, ShardOptions } from './shared';
@@ -23,7 +23,7 @@ export declare class Shard {
23
23
  connectTimeout: ConnectTimeout;
24
24
  heart: ShardHeart;
25
25
  bucket: DynamicBucket;
26
- offlineSendQueue: PriorityQueue<(_?: unknown) => void>;
26
+ offlineSendQueue: ((_?: unknown) => void)[];
27
27
  constructor(id: number, options: ShardOptions);
28
28
  get latency(): number;
29
29
  get isOpen(): boolean;
@@ -31,7 +31,7 @@ export declare class Shard {
31
31
  get resumeGatewayURL(): string | undefined;
32
32
  get currentGatewayURL(): string;
33
33
  connect(): Promise<void>;
34
- send<T extends GatewaySendPayload = GatewaySendPayload>(priority: number, message: T): Promise<void>;
34
+ send<T extends GatewaySendPayload = GatewaySendPayload>(force: boolean, message: T): Promise<void>;
35
35
  identify(): Promise<void>;
36
36
  get resumable(): boolean;
37
37
  resume(): Promise<void>;
@@ -42,6 +42,6 @@ export declare class Shard {
42
42
  protected handleClosed(close: CloseEvent): Promise<void>;
43
43
  close(code: number, reason: string): Promise<void>;
44
44
  protected handleMessage({ data }: WS.MessageEvent): Promise<void>;
45
- checkOffline(priority: number): Promise<unknown>;
45
+ checkOffline(force: boolean): Promise<unknown>;
46
46
  calculateSafeRequests(): number;
47
47
  }
@@ -23,7 +23,7 @@ class Shard {
23
23
  ack: true,
24
24
  };
25
25
  bucket;
26
- offlineSendQueue = new structures_1.PriorityQueue();
26
+ offlineSendQueue = [];
27
27
  constructor(id, options) {
28
28
  this.id = id;
29
29
  this.options = options;
@@ -34,12 +34,7 @@ class Shard {
34
34
  if (options.debugger)
35
35
  this.debugger = options.debugger;
36
36
  const safe = this.calculateSafeRequests();
37
- this.bucket = new structures_1.DynamicBucket({
38
- limit: safe,
39
- refillAmount: safe,
40
- refillInterval: 6e4,
41
- debugger: this.debugger,
42
- });
37
+ this.bucket = new structures_1.DynamicBucket({ refillInterval: 6e4, limit: safe, debugger: options.debugger });
43
38
  }
44
39
  get latency() {
45
40
  return this.heart.lastAck && this.heart.lastBeat
@@ -76,7 +71,7 @@ class Shard {
76
71
  this.heart.ack = true;
77
72
  };
78
73
  }
79
- async send(priority, message) {
74
+ async send(force, message) {
80
75
  this.debugger?.info(`[Shard #${this.id}] Sending: ${v10_1.GatewayOpcodes[message.op]} ${JSON.stringify(message.d, (_, value) => {
81
76
  if (typeof value === 'string')
82
77
  return value.replace(this.options.token, v => {
@@ -85,13 +80,13 @@ class Shard {
85
80
  });
86
81
  return value;
87
82
  }, 1)}`);
88
- await this.checkOffline(priority);
89
- await this.bucket.acquire(priority);
90
- await this.checkOffline(priority);
83
+ await this.checkOffline(force);
84
+ await this.bucket.acquire(force);
85
+ await this.checkOffline(force);
91
86
  this.websocket?.send(JSON.stringify(message));
92
87
  }
93
88
  async identify() {
94
- await this.send(0, {
89
+ await this.send(true, {
95
90
  op: v10_1.GatewayOpcodes.Identify,
96
91
  d: {
97
92
  token: `Bot ${this.options.token}`,
@@ -107,7 +102,7 @@ class Shard {
107
102
  return !!(this.data.resume_gateway_url && this.data.session_id && this.data.resumeSeq !== null);
108
103
  }
109
104
  async resume() {
110
- await this.send(0, {
105
+ await this.send(true, {
111
106
  op: v10_1.GatewayOpcodes.Resume,
112
107
  d: {
113
108
  seq: this.data.resumeSeq,
@@ -185,13 +180,13 @@ class Shard {
185
180
  {
186
181
  switch (packet.t) {
187
182
  case v10_1.GatewayDispatchEvents.Resumed:
188
- this.offlineSendQueue.toArray().map((resolve) => resolve());
183
+ this.offlineSendQueue.map((resolve) => resolve());
189
184
  this.options.handlePayload(this.id, packet);
190
185
  break;
191
186
  case v10_1.GatewayDispatchEvents.Ready: {
192
187
  this.data.resume_gateway_url = packet.d.resume_gateway_url;
193
188
  this.data.session_id = packet.d.session_id;
194
- this.offlineSendQueue.toArray().map((resolve) => resolve());
189
+ this.offlineSendQueue.map((resolve) => resolve());
195
190
  this.options.handlePayload(this.id, packet);
196
191
  break;
197
192
  }
@@ -251,9 +246,9 @@ class Shard {
251
246
  }
252
247
  return this.onpacket(JSON.parse(data));
253
248
  }
254
- checkOffline(priority) {
249
+ checkOffline(force) {
255
250
  if (!this.isOpen) {
256
- return new Promise(resolve => this.offlineSendQueue.push(resolve, priority));
251
+ return new Promise(resolve => this.offlineSendQueue[force ? 'unshift' : 'push'](resolve));
257
252
  }
258
253
  return Promise.resolve();
259
254
  }
@@ -22,7 +22,7 @@ export declare class ShardManager extends Map<number, Shard> {
22
22
  disconnect(shardId: number): Promise<void> | undefined;
23
23
  disconnectAll(): Promise<unknown>;
24
24
  setShardPresence(shardId: number, payload: GatewayUpdatePresence['d']): void;
25
- setPresence(payload: GatewayUpdatePresence['d']): Promise<void> | undefined;
25
+ setPresence(payload: GatewayUpdatePresence['d']): Promise<void>;
26
26
  joinVoice(guild_id: string, channel_id: string, options: ObjectToLower<Pick<GatewayVoiceStateUpdate['d'], 'self_deaf' | 'self_mute'>>): void;
27
27
  leaveVoice(guild_id: string): void;
28
28
  send<T extends GatewaySendPayload>(shardId: number, payload: T): void;
@@ -82,7 +82,7 @@ class ShardManager extends Map {
82
82
  */
83
83
  spawnBuckets() {
84
84
  this.debugger?.info('#0 Preparing buckets');
85
- const chunks = structures_1.SequentialBucket.chunk(new Array(this.shardEnd - this.shardStart), this.concurrency);
85
+ const chunks = structures_1.DynamicBucket.chunk(new Array(this.shardEnd - this.shardStart), this.concurrency);
86
86
  chunks.forEach((arr, index) => {
87
87
  for (let i = 0; i < arr.length; i++) {
88
88
  const id = i + (index > 0 ? index * this.concurrency : 0) + this.shardStart;
@@ -155,7 +155,7 @@ class ShardManager extends Map {
155
155
  payload,
156
156
  });
157
157
  }
158
- this.get(shardId)?.send(1, payload);
158
+ this.get(shardId)?.send(false, payload);
159
159
  }
160
160
  }
161
161
  exports.ShardManager = ShardManager;
@@ -83,7 +83,7 @@ class WorkerManager extends Map {
83
83
  }
84
84
  prepareSpaces() {
85
85
  this.debugger?.info('Preparing buckets');
86
- const chunks = structures_1.SequentialBucket.chunk(new Array(this.shardEnd - this.shardStart), this.options.shardsPerWorker);
86
+ const chunks = structures_1.DynamicBucket.chunk(new Array(this.shardEnd - this.shardStart), this.options.shardsPerWorker);
87
87
  chunks.forEach((shards, index) => {
88
88
  for (let i = 0; i < shards.length; i++) {
89
89
  const id = i + (index > 0 ? index * this.options.shardsPerWorker : 0) + this.shardStart;
@@ -1,117 +1,24 @@
1
1
  /// <reference types="node" />
2
- import type { Logger } from '../../common';
3
- /**
4
- * just any kind of request to queue and resolve later
5
- */
6
- export type QueuedRequest = (value: void | Promise<void>) => Promise<unknown> | any;
2
+ import { type Logger } from '../../common';
7
3
  /**
8
4
  * options of the dynamic bucket
9
5
  */
10
6
  export interface DynamicBucketOptions {
11
7
  limit: number;
12
8
  refillInterval: number;
13
- refillAmount: number;
14
9
  debugger?: Logger;
15
10
  }
16
- /**
17
- * generally useless for interaction based bots
18
- * ideally this would only be triggered on certain paths
19
- * example: a huge amount of messages being spammed
20
- *
21
- * a dynamic bucket is just a priority queue implemented using linked lists
22
- * we create an empty bucket for every path
23
- * dynamically allocating memory improves the final memory footprint
24
- */
25
11
  export declare class DynamicBucket {
26
- limit: number;
27
- refillInterval: number;
28
- refillAmount: number;
29
- /** The queue of requests to acquire an available request. Mapped by <shardId, resolve()> */
30
- queue: PriorityQueue<QueuedRequest>;
31
- /** The amount of requests that have been used up already. */
12
+ options: DynamicBucketOptions;
13
+ queue: ((value?: unknown) => any)[];
32
14
  used: number;
33
- /** Whether or not the queue is already processing. */
34
- processing: boolean;
35
- /** The timeout id for the timer to reduce the used amount by the refill amount. */
36
- timeoutId?: NodeJS.Timeout;
37
- /** The timestamp in milliseconds when the next refill is scheduled. */
15
+ processing?: boolean;
38
16
  refillsAt?: number;
39
- debugger?: Logger;
17
+ timeoutId?: NodeJS.Timeout;
40
18
  constructor(options: DynamicBucketOptions);
41
19
  get remaining(): number;
42
20
  refill(): void;
43
- /** Begin processing the queue. */
44
21
  processQueue(): Promise<void>;
45
- /** Pauses the execution until the request is available to be made. */
46
- acquire(priority: number): Promise<void>;
47
- toString(): string;
48
- }
49
- /**
50
- * abstract node lol
51
- */
52
- export interface AbstractNode<T> {
53
- data: T;
54
- next: this | null;
55
- }
56
- export interface QueuePusher<T> {
57
- push(data: T): NonNullable<TNode<T>>;
58
- }
59
- export interface QueuePusherWithPriority<T> {
60
- push(data: T, priority: number): NonNullable<PNode<T>>;
61
- }
62
- export declare class TNode<T> implements AbstractNode<T> {
63
- data: T;
64
- next: this | null;
65
- constructor(data: T);
66
- static null<T>(list: AbstractNode<T> | null): list is null;
67
- }
68
- export declare class PNode<T> extends TNode<T> {
69
- priority: number;
70
- constructor(data: T, priority: number);
71
- }
72
- export declare abstract class Queue<T> {
73
- protected abstract head: AbstractNode<T> | null;
74
- /**
75
- * O(1)
76
- */
77
- pop(): AbstractNode<T> | null;
78
- /**
79
- * O(1)
80
- */
81
- peek(): T;
82
- /**
83
- * O(n)
84
- */
85
- size(): number;
86
- /**
87
- * O(1)
88
- */
89
- isEmpty(): boolean;
90
- [Symbol.iterator](): IterableIterator<T>;
91
- toArray(): T[];
92
- toString(): string;
93
- }
94
- export declare class LinkedList<T> extends Queue<T> implements QueuePusher<T> {
95
- protected head: TNode<T> | null;
96
- /**
97
- * O(1)
98
- */
99
- push(data: T): NonNullable<TNode<T>>;
100
- }
101
- export declare class PriorityQueue<T> extends Queue<T> implements QueuePusherWithPriority<T> {
102
- protected head: PNode<T> | null;
103
- /**
104
- * O(#priorities)
105
- */
106
- push(data: T, priority: number): NonNullable<PNode<T>>;
107
- }
108
- export declare class SequentialBucket {
109
- private connections;
110
- private capacity;
111
- private spawnTimeout;
112
- constructor(maxCapacity: number);
113
- destroy(): Promise<void>;
114
- push(promise: QueuedRequest): Promise<void>;
115
- acquire(promises?: LinkedList<QueuedRequest>): Promise<boolean>;
22
+ acquire(force?: boolean): Promise<unknown>;
116
23
  static chunk<T>(array: T[], chunks: number): T[][];
117
24
  }