@ovencord/discord.js 14.16.3

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 (332) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +148 -0
  3. package/package.json +73 -0
  4. package/src/client/Client.ts +967 -0
  5. package/src/client/actions/Action.ts +141 -0
  6. package/src/client/actions/ActionsManager.ts +138 -0
  7. package/src/client/actions/ChannelCreate.ts +21 -0
  8. package/src/client/actions/ChannelDelete.ts +20 -0
  9. package/src/client/actions/ChannelUpdate.ts +38 -0
  10. package/src/client/actions/GuildChannelsPositionUpdate.ts +17 -0
  11. package/src/client/actions/GuildEmojiCreate.ts +17 -0
  12. package/src/client/actions/GuildEmojiDelete.ts +16 -0
  13. package/src/client/actions/GuildEmojiUpdate.ts +17 -0
  14. package/src/client/actions/GuildEmojisUpdate.ts +30 -0
  15. package/src/client/actions/GuildMemberRemove.ts +29 -0
  16. package/src/client/actions/GuildMemberUpdate.ts +41 -0
  17. package/src/client/actions/GuildRoleCreate.ts +23 -0
  18. package/src/client/actions/GuildRoleDelete.ts +26 -0
  19. package/src/client/actions/GuildRolesPositionUpdate.ts +17 -0
  20. package/src/client/actions/GuildScheduledEventDelete.ts +28 -0
  21. package/src/client/actions/GuildScheduledEventUserAdd.ts +29 -0
  22. package/src/client/actions/GuildScheduledEventUserRemove.ts +29 -0
  23. package/src/client/actions/GuildSoundboardSoundDelete.ts +26 -0
  24. package/src/client/actions/GuildStickerCreate.ts +17 -0
  25. package/src/client/actions/GuildStickerDelete.ts +16 -0
  26. package/src/client/actions/GuildStickerUpdate.ts +17 -0
  27. package/src/client/actions/GuildStickersUpdate.ts +30 -0
  28. package/src/client/actions/GuildUpdate.ts +30 -0
  29. package/src/client/actions/InteractionCreate.ts +104 -0
  30. package/src/client/actions/MessageCreate.ts +38 -0
  31. package/src/client/actions/MessageDelete.ts +29 -0
  32. package/src/client/actions/MessageDeleteBulk.ts +45 -0
  33. package/src/client/actions/MessagePollVoteAdd.ts +37 -0
  34. package/src/client/actions/MessagePollVoteRemove.ts +35 -0
  35. package/src/client/actions/MessageReactionAdd.ts +68 -0
  36. package/src/client/actions/MessageReactionRemove.ts +47 -0
  37. package/src/client/actions/MessageReactionRemoveAll.ts +30 -0
  38. package/src/client/actions/MessageReactionRemoveEmoji.ts +25 -0
  39. package/src/client/actions/MessageUpdate.ts +22 -0
  40. package/src/client/actions/StageInstanceCreate.ts +25 -0
  41. package/src/client/actions/StageInstanceDelete.ts +28 -0
  42. package/src/client/actions/StageInstanceUpdate.ts +27 -0
  43. package/src/client/actions/ThreadCreate.ts +22 -0
  44. package/src/client/actions/ThreadMembersUpdate.ts +45 -0
  45. package/src/client/actions/TypingStart.ts +26 -0
  46. package/src/client/actions/UserUpdate.ts +33 -0
  47. package/src/client/voice/ClientVoiceManager.ts +46 -0
  48. package/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts +19 -0
  49. package/src/client/websocket/handlers/AUTO_MODERATION_ACTION_EXECUTION.ts +17 -0
  50. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_CREATE.ts +18 -0
  51. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_DELETE.ts +21 -0
  52. package/src/client/websocket/handlers/AUTO_MODERATION_RULE_UPDATE.ts +20 -0
  53. package/src/client/websocket/handlers/CHANNEL_CREATE.ts +4 -0
  54. package/src/client/websocket/handlers/CHANNEL_DELETE.ts +4 -0
  55. package/src/client/websocket/handlers/CHANNEL_PINS_UPDATE.ts +22 -0
  56. package/src/client/websocket/handlers/CHANNEL_UPDATE.ts +16 -0
  57. package/src/client/websocket/handlers/ENTITLEMENT_CREATE.ts +14 -0
  58. package/src/client/websocket/handlers/ENTITLEMENT_DELETE.ts +18 -0
  59. package/src/client/websocket/handlers/ENTITLEMENT_UPDATE.ts +16 -0
  60. package/src/client/websocket/handlers/GUILD_AUDIT_LOG_ENTRY_CREATE.ts +19 -0
  61. package/src/client/websocket/handlers/GUILD_BAN_ADD.ts +15 -0
  62. package/src/client/websocket/handlers/GUILD_BAN_REMOVE.ts +20 -0
  63. package/src/client/websocket/handlers/GUILD_CREATE.ts +34 -0
  64. package/src/client/websocket/handlers/GUILD_DELETE.ts +36 -0
  65. package/src/client/websocket/handlers/GUILD_EMOJIS_UPDATE.ts +4 -0
  66. package/src/client/websocket/handlers/GUILD_INTEGRATIONS_UPDATE.ts +15 -0
  67. package/src/client/websocket/handlers/GUILD_MEMBERS_CHUNK.ts +40 -0
  68. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.ts +17 -0
  69. package/src/client/websocket/handlers/GUILD_MEMBER_REMOVE.ts +4 -0
  70. package/src/client/websocket/handlers/GUILD_MEMBER_UPDATE.ts +4 -0
  71. package/src/client/websocket/handlers/GUILD_ROLE_CREATE.ts +4 -0
  72. package/src/client/websocket/handlers/GUILD_ROLE_DELETE.ts +4 -0
  73. package/src/client/websocket/handlers/GUILD_ROLE_UPDATE.ts +21 -0
  74. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.ts +17 -0
  75. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.ts +4 -0
  76. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.ts +19 -0
  77. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_ADD.ts +4 -0
  78. package/src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts +4 -0
  79. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts +24 -0
  80. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.ts +18 -0
  81. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.ts +4 -0
  82. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.ts +20 -0
  83. package/src/client/websocket/handlers/GUILD_STICKERS_UPDATE.ts +4 -0
  84. package/src/client/websocket/handlers/GUILD_UPDATE.ts +4 -0
  85. package/src/client/websocket/handlers/INTERACTION_CREATE.ts +4 -0
  86. package/src/client/websocket/handlers/INVITE_CREATE.ts +20 -0
  87. package/src/client/websocket/handlers/INVITE_DELETE.ts +23 -0
  88. package/src/client/websocket/handlers/MESSAGE_CREATE.ts +4 -0
  89. package/src/client/websocket/handlers/MESSAGE_DELETE.ts +4 -0
  90. package/src/client/websocket/handlers/MESSAGE_DELETE_BULK.ts +4 -0
  91. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.ts +4 -0
  92. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.ts +4 -0
  93. package/src/client/websocket/handlers/MESSAGE_REACTION_ADD.ts +4 -0
  94. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE.ts +4 -0
  95. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_ALL.ts +4 -0
  96. package/src/client/websocket/handlers/MESSAGE_REACTION_REMOVE_EMOJI.ts +4 -0
  97. package/src/client/websocket/handlers/MESSAGE_UPDATE.ts +16 -0
  98. package/src/client/websocket/handlers/PRESENCE_UPDATE.ts +42 -0
  99. package/src/client/websocket/handlers/RATE_LIMITED.ts +23 -0
  100. package/src/client/websocket/handlers/READY.ts +29 -0
  101. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.ts +24 -0
  102. package/src/client/websocket/handlers/STAGE_INSTANCE_CREATE.ts +4 -0
  103. package/src/client/websocket/handlers/STAGE_INSTANCE_DELETE.ts +4 -0
  104. package/src/client/websocket/handlers/STAGE_INSTANCE_UPDATE.ts +4 -0
  105. package/src/client/websocket/handlers/SUBSCRIPTION_CREATE.ts +14 -0
  106. package/src/client/websocket/handlers/SUBSCRIPTION_DELETE.ts +16 -0
  107. package/src/client/websocket/handlers/SUBSCRIPTION_UPDATE.ts +16 -0
  108. package/src/client/websocket/handlers/THREAD_CREATE.ts +4 -0
  109. package/src/client/websocket/handlers/THREAD_DELETE.ts +17 -0
  110. package/src/client/websocket/handlers/THREAD_LIST_SYNC.ts +50 -0
  111. package/src/client/websocket/handlers/THREAD_MEMBERS_UPDATE.ts +4 -0
  112. package/src/client/websocket/handlers/THREAD_MEMBER_UPDATE.ts +25 -0
  113. package/src/client/websocket/handlers/THREAD_UPDATE.ts +16 -0
  114. package/src/client/websocket/handlers/TYPING_START.ts +4 -0
  115. package/src/client/websocket/handlers/USER_UPDATE.ts +4 -0
  116. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.ts +16 -0
  117. package/src/client/websocket/handlers/VOICE_SERVER_UPDATE.ts +5 -0
  118. package/src/client/websocket/handlers/VOICE_STATE_UPDATE.ts +37 -0
  119. package/src/client/websocket/handlers/WEBHOOKS_UPDATE.ts +16 -0
  120. package/src/client/websocket/handlers/index.ts +74 -0
  121. package/src/errors/DJSError.ts +50 -0
  122. package/src/errors/ErrorCodes.ts +277 -0
  123. package/src/errors/Messages.ts +155 -0
  124. package/src/errors/index.ts +6 -0
  125. package/src/index.ts +241 -0
  126. package/src/managers/ApplicationCommandManager.ts +303 -0
  127. package/src/managers/ApplicationCommandPermissionsManager.ts +453 -0
  128. package/src/managers/ApplicationEmojiManager.ts +149 -0
  129. package/src/managers/AutoModerationRuleManager.ts +307 -0
  130. package/src/managers/BaseManager.ts +13 -0
  131. package/src/managers/CachedManager.ts +56 -0
  132. package/src/managers/CategoryChannelChildManager.ts +81 -0
  133. package/src/managers/ChannelManager.ts +194 -0
  134. package/src/managers/DMMessageManager.ts +15 -0
  135. package/src/managers/DataManager.ts +38 -0
  136. package/src/managers/EntitlementManager.ts +182 -0
  137. package/src/managers/GuildApplicationCommandManager.ts +29 -0
  138. package/src/managers/GuildBanManager.ts +221 -0
  139. package/src/managers/GuildChannelManager.ts +552 -0
  140. package/src/managers/GuildEmojiManager.ts +262 -0
  141. package/src/managers/GuildEmojiRoleManager.ts +134 -0
  142. package/src/managers/GuildForumThreadManager.ts +84 -0
  143. package/src/managers/GuildInviteManager.ts +236 -0
  144. package/src/managers/GuildManager.ts +265 -0
  145. package/src/managers/GuildMemberManager.ts +619 -0
  146. package/src/managers/GuildMemberRoleManager.ts +230 -0
  147. package/src/managers/GuildMessageManager.ts +31 -0
  148. package/src/managers/GuildScheduledEventManager.ts +330 -0
  149. package/src/managers/GuildSoundboardSoundManager.ts +157 -0
  150. package/src/managers/GuildStickerManager.ts +192 -0
  151. package/src/managers/GuildTextThreadManager.ts +91 -0
  152. package/src/managers/MessageManager.ts +352 -0
  153. package/src/managers/PartialGroupDMMessageManager.ts +15 -0
  154. package/src/managers/PermissionOverwriteManager.ts +174 -0
  155. package/src/managers/PollAnswerVoterManager.ts +59 -0
  156. package/src/managers/PresenceManager.ts +60 -0
  157. package/src/managers/ReactionManager.ts +72 -0
  158. package/src/managers/ReactionUserManager.ts +82 -0
  159. package/src/managers/RoleManager.ts +432 -0
  160. package/src/managers/StageInstanceManager.ts +166 -0
  161. package/src/managers/SubscriptionManager.ts +83 -0
  162. package/src/managers/ThreadManager.ts +210 -0
  163. package/src/managers/ThreadMemberManager.ts +194 -0
  164. package/src/managers/UserManager.ts +139 -0
  165. package/src/managers/VoiceStateManager.ts +61 -0
  166. package/src/sharding/Shard.ts +513 -0
  167. package/src/sharding/ShardClientUtil.ts +293 -0
  168. package/src/sharding/ShardingManager.ts +374 -0
  169. package/src/structures/ActionRow.ts +31 -0
  170. package/src/structures/AnnouncementChannel.ts +25 -0
  171. package/src/structures/AnonymousGuild.ts +110 -0
  172. package/src/structures/ApplicationCommand.ts +675 -0
  173. package/src/structures/ApplicationEmoji.ts +189 -0
  174. package/src/structures/ApplicationRoleConnectionMetadata.ts +54 -0
  175. package/src/structures/Attachment.ts +189 -0
  176. package/src/structures/AuthorizingIntegrationOwners.ts +63 -0
  177. package/src/structures/AutoModerationActionExecution.ts +138 -0
  178. package/src/structures/AutoModerationRule.ts +325 -0
  179. package/src/structures/AutocompleteInteraction.ts +115 -0
  180. package/src/structures/Base.ts +37 -0
  181. package/src/structures/BaseChannel.ts +188 -0
  182. package/src/structures/BaseGuild.ts +134 -0
  183. package/src/structures/BaseGuildEmoji.ts +113 -0
  184. package/src/structures/BaseGuildTextChannel.ts +230 -0
  185. package/src/structures/BaseGuildVoiceChannel.ts +270 -0
  186. package/src/structures/BaseInteraction.ts +393 -0
  187. package/src/structures/BaseInvite.ts +192 -0
  188. package/src/structures/BaseSelectMenuComponent.ts +58 -0
  189. package/src/structures/ButtonComponent.ts +68 -0
  190. package/src/structures/ButtonInteraction.ts +8 -0
  191. package/src/structures/CategoryChannel.ts +46 -0
  192. package/src/structures/ChannelSelectMenuComponent.ts +18 -0
  193. package/src/structures/ChannelSelectMenuInteraction.ts +34 -0
  194. package/src/structures/ChatInputCommandInteraction.ts +43 -0
  195. package/src/structures/ClientApplication.ts +470 -0
  196. package/src/structures/ClientPresence.ts +87 -0
  197. package/src/structures/ClientUser.ts +219 -0
  198. package/src/structures/CommandInteraction.ts +193 -0
  199. package/src/structures/CommandInteractionOptionResolver.ts +336 -0
  200. package/src/structures/Component.ts +59 -0
  201. package/src/structures/ContainerComponent.ts +63 -0
  202. package/src/structures/ContextMenuCommandInteraction.ts +68 -0
  203. package/src/structures/DMChannel.ts +148 -0
  204. package/src/structures/DirectoryChannel.ts +40 -0
  205. package/src/structures/Embed.ts +251 -0
  206. package/src/structures/Emoji.ts +61 -0
  207. package/src/structures/Entitlement.ts +206 -0
  208. package/src/structures/FileComponent.ts +41 -0
  209. package/src/structures/ForumChannel.ts +31 -0
  210. package/src/structures/GroupDMInvite.ts +34 -0
  211. package/src/structures/Guild.ts +1605 -0
  212. package/src/structures/GuildAuditLogs.ts +99 -0
  213. package/src/structures/GuildAuditLogsEntry.ts +557 -0
  214. package/src/structures/GuildBan.ts +65 -0
  215. package/src/structures/GuildChannel.ts +515 -0
  216. package/src/structures/GuildEmoji.ts +159 -0
  217. package/src/structures/GuildInvite.ts +233 -0
  218. package/src/structures/GuildMember.ts +643 -0
  219. package/src/structures/GuildOnboarding.ts +73 -0
  220. package/src/structures/GuildOnboardingPrompt.ts +93 -0
  221. package/src/structures/GuildOnboardingPromptOption.ts +100 -0
  222. package/src/structures/GuildPreview.ts +218 -0
  223. package/src/structures/GuildPreviewEmoji.ts +28 -0
  224. package/src/structures/GuildScheduledEvent.ts +593 -0
  225. package/src/structures/GuildTemplate.ts +229 -0
  226. package/src/structures/Integration.ts +257 -0
  227. package/src/structures/IntegrationApplication.ts +84 -0
  228. package/src/structures/InteractionCallback.ts +86 -0
  229. package/src/structures/InteractionCallbackResource.ts +57 -0
  230. package/src/structures/InteractionCallbackResponse.ts +35 -0
  231. package/src/structures/InteractionCollector.ts +260 -0
  232. package/src/structures/InteractionWebhook.ts +65 -0
  233. package/src/structures/InviteGuild.ts +22 -0
  234. package/src/structures/LabelComponent.ts +51 -0
  235. package/src/structures/MediaChannel.ts +8 -0
  236. package/src/structures/MediaGalleryComponent.ts +31 -0
  237. package/src/structures/MediaGalleryItem.ts +54 -0
  238. package/src/structures/MentionableSelectMenuComponent.ts +8 -0
  239. package/src/structures/MentionableSelectMenuInteraction.ts +76 -0
  240. package/src/structures/Message.ts +1202 -0
  241. package/src/structures/MessageCollector.ts +155 -0
  242. package/src/structures/MessageComponentInteraction.ts +132 -0
  243. package/src/structures/MessageContextMenuCommandInteraction.ts +18 -0
  244. package/src/structures/MessageMentions.ts +327 -0
  245. package/src/structures/MessagePayload.ts +325 -0
  246. package/src/structures/MessageReaction.ts +219 -0
  247. package/src/structures/ModalComponentResolver.ts +237 -0
  248. package/src/structures/ModalSubmitInteraction.ts +260 -0
  249. package/src/structures/OAuth2Guild.ts +30 -0
  250. package/src/structures/PartialGroupDMChannel.ts +151 -0
  251. package/src/structures/PermissionOverwrites.ts +222 -0
  252. package/src/structures/Poll.ts +195 -0
  253. package/src/structures/PollAnswer.ts +100 -0
  254. package/src/structures/Presence.ts +448 -0
  255. package/src/structures/PrimaryEntryPointCommandInteraction.ts +8 -0
  256. package/src/structures/ReactionCollector.ts +245 -0
  257. package/src/structures/ReactionEmoji.ts +30 -0
  258. package/src/structures/Role.ts +543 -0
  259. package/src/structures/RoleSelectMenuComponent.ts +8 -0
  260. package/src/structures/RoleSelectMenuInteraction.ts +34 -0
  261. package/src/structures/SKU.ts +62 -0
  262. package/src/structures/SectionComponent.ts +44 -0
  263. package/src/structures/SeparatorComponent.ts +29 -0
  264. package/src/structures/SoundboardSound.ts +176 -0
  265. package/src/structures/StageChannel.ts +118 -0
  266. package/src/structures/StageInstance.ts +173 -0
  267. package/src/structures/Sticker.ts +300 -0
  268. package/src/structures/StickerPack.ts +111 -0
  269. package/src/structures/StringSelectMenuComponent.ts +18 -0
  270. package/src/structures/StringSelectMenuInteraction.ts +21 -0
  271. package/src/structures/Subscription.ts +138 -0
  272. package/src/structures/Team.ts +131 -0
  273. package/src/structures/TeamMember.ts +77 -0
  274. package/src/structures/TextChannel.ts +33 -0
  275. package/src/structures/TextDisplayComponent.ts +18 -0
  276. package/src/structures/TextInputComponent.ts +28 -0
  277. package/src/structures/ThreadChannel.ts +680 -0
  278. package/src/structures/ThreadMember.ts +125 -0
  279. package/src/structures/ThreadOnlyChannel.ts +276 -0
  280. package/src/structures/ThumbnailComponent.ts +51 -0
  281. package/src/structures/Typing.ts +81 -0
  282. package/src/structures/UnfurledMediaItem.ts +33 -0
  283. package/src/structures/User.ts +511 -0
  284. package/src/structures/UserContextMenuCommandInteraction.ts +28 -0
  285. package/src/structures/UserSelectMenuComponent.ts +8 -0
  286. package/src/structures/UserSelectMenuInteraction.ts +54 -0
  287. package/src/structures/VoiceChannel.ts +119 -0
  288. package/src/structures/VoiceChannelEffect.ts +92 -0
  289. package/src/structures/VoiceRegion.ts +52 -0
  290. package/src/structures/VoiceState.ts +346 -0
  291. package/src/structures/Webhook.ts +526 -0
  292. package/src/structures/WelcomeChannel.ts +67 -0
  293. package/src/structures/WelcomeScreen.ts +53 -0
  294. package/src/structures/Widget.ts +110 -0
  295. package/src/structures/WidgetMember.ts +124 -0
  296. package/src/structures/interfaces/Application.ts +179 -0
  297. package/src/structures/interfaces/Collector.ts +372 -0
  298. package/src/structures/interfaces/InteractionResponses.ts +384 -0
  299. package/src/structures/interfaces/TextBasedChannel.ts +430 -0
  300. package/src/util/APITypes.ts +690 -0
  301. package/src/util/ActivityFlagsBitField.ts +26 -0
  302. package/src/util/ApplicationFlagsBitField.ts +43 -0
  303. package/src/util/AttachmentFlagsBitField.ts +26 -0
  304. package/src/util/BitField.ts +178 -0
  305. package/src/util/ChannelFlagsBitField.ts +43 -0
  306. package/src/util/Channels.ts +165 -0
  307. package/src/util/Colors.ts +72 -0
  308. package/src/util/Components.ts +285 -0
  309. package/src/util/Constants.ts +251 -0
  310. package/src/util/DataResolver.ts +146 -0
  311. package/src/util/Enums.ts +10 -0
  312. package/src/util/Events.ts +178 -0
  313. package/src/util/GuildMemberFlagsBitField.ts +43 -0
  314. package/src/util/IntentsBitField.ts +35 -0
  315. package/src/util/InviteFlagsBitField.ts +26 -0
  316. package/src/util/Invites.ts +27 -0
  317. package/src/util/LimitedCollection.ts +73 -0
  318. package/src/util/MessageFlagsBitField.ts +43 -0
  319. package/src/util/Options.ts +215 -0
  320. package/src/util/Partials.ts +50 -0
  321. package/src/util/PermissionsBitField.ts +113 -0
  322. package/src/util/RoleFlagsBitField.ts +26 -0
  323. package/src/util/SKUFlagsBitField.ts +26 -0
  324. package/src/util/ShardEvents.ts +26 -0
  325. package/src/util/Status.ts +16 -0
  326. package/src/util/Sweepers.ts +532 -0
  327. package/src/util/Symbols.ts +1 -0
  328. package/src/util/SystemChannelFlagsBitField.ts +45 -0
  329. package/src/util/ThreadMemberFlagsBitField.ts +33 -0
  330. package/src/util/Transformers.ts +123 -0
  331. package/src/util/UserFlagsBitField.ts +33 -0
  332. package/src/util/Util.ts +519 -0
@@ -0,0 +1,293 @@
1
+ /* eslint-disable */
2
+
3
+ import process from 'node:process';
4
+ import { calculateShardId } from '@ovencord/util';
5
+ import { WebSocketShardEvents } from '@ovencord/ws';
6
+ import { DiscordjsError, DiscordjsTypeError, ErrorCodes } from '../errors/index.js';
7
+ import { Events } from '../util/Events.js';
8
+ import { makeError, makePlainError } from '../util/Util.js';
9
+
10
+ /**
11
+ * Helper class for sharded clients spawned as a child process/worker, such as from a {@link ShardingManager}.
12
+ * Utilizes IPC to send and receive data to/from the master process and other shards.
13
+ */
14
+ export class ShardClientUtil {
15
+ public client: any;
16
+ public mode: any;
17
+ public parentPort: any;
18
+ public _singleton: any;
19
+ constructor(client, mode) {
20
+ /**
21
+ * Client for the shard
22
+ *
23
+ * @type {Client}
24
+ */
25
+ this.client = client;
26
+
27
+ /**
28
+ * Mode the shard was spawned with
29
+ *
30
+ * @type {ShardingManagerMode}
31
+ */
32
+ this.mode = mode;
33
+
34
+ /**
35
+ * Message port for the master process (only when {@link ShardClientUtil#mode} is `worker`)
36
+ *
37
+ * @type {?MessagePort}
38
+ */
39
+ this.parentPort = null;
40
+
41
+ switch (mode) {
42
+ case 'process':
43
+ process.on('message', this._handleMessage.bind(this));
44
+ client.on(Events.ClientReady, () => {
45
+ process.send({ _ready: true });
46
+ });
47
+ client.ws.on(WebSocketShardEvents.Closed, () => {
48
+ process.send({ _disconnect: true });
49
+ });
50
+ client.ws.on(WebSocketShardEvents.Resumed, () => {
51
+ process.send({ _resume: true });
52
+ });
53
+ break;
54
+ case 'worker':
55
+ this.parentPort = require('node:worker_threads').parentPort;
56
+ this.parentPort.on('message', this._handleMessage.bind(this));
57
+ client.on(Events.ClientReady, () => {
58
+ this.parentPort.postMessage({ _ready: true });
59
+ });
60
+ client.ws.on(WebSocketShardEvents.Closed, () => {
61
+ this.parentPort.postMessage({ _disconnect: true });
62
+ });
63
+ client.ws.on(WebSocketShardEvents.Resumed, () => {
64
+ this.parentPort.postMessage({ _resume: true });
65
+ });
66
+ break;
67
+ default:
68
+ break;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Sends a message to the master process.
74
+ *
75
+ * @param {*} message Message to send
76
+ * @returns {Promise<void>}
77
+ * @emits Shard#message
78
+ */
79
+ async send(message) {
80
+ return new Promise((resolve, reject) => {
81
+ switch (this.mode) {
82
+ case 'process':
83
+ process.send(message, err => {
84
+ if (err) reject(err);
85
+ else resolve();
86
+ });
87
+ break;
88
+ case 'worker':
89
+ this.parentPort.postMessage(message);
90
+ resolve();
91
+ break;
92
+ default:
93
+ break;
94
+ }
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Fetches a client property value of each shard, or a given shard.
100
+ *
101
+ * @param {string} prop Name of the client property to get, using periods for nesting
102
+ * @param {number} [shard] Shard to fetch property from, all if undefined
103
+ * @returns {Promise<*|Array<*>>}
104
+ * @example
105
+ * client.shard.fetchClientValues('guilds.cache.size')
106
+ * .then(results => console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`))
107
+ * .catch(console.error);
108
+ * @see {@link ShardingManager#fetchClientValues}
109
+ */
110
+ async fetchClientValues(prop, shard) {
111
+ return new Promise((resolve, reject) => {
112
+ const parent = this.parentPort ?? process;
113
+
114
+ const listener = message => {
115
+ if (message?._sFetchProp !== prop || message._sFetchPropShard !== shard) return;
116
+ parent.removeListener('message', listener);
117
+ this.decrementMaxListeners(parent);
118
+ if (message._error) reject(makeError(message._error));
119
+ else resolve(message._result);
120
+ };
121
+
122
+ this.incrementMaxListeners(parent);
123
+ parent.on('message', listener);
124
+
125
+ this.send({ _sFetchProp: prop, _sFetchPropShard: shard }).catch(error => {
126
+ parent.removeListener('message', listener);
127
+ this.decrementMaxListeners(parent);
128
+ reject(error);
129
+ });
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Evaluates a script or function on all shards, or a given shard, in the context of the {@link Client}s.
135
+ *
136
+ * @param {Function} script JavaScript to run on each shard
137
+ * @param {BroadcastEvalOptions} [options={}] The options for the broadcast
138
+ * @returns {Promise<*|Array<*>>} Results of the script execution
139
+ * @example
140
+ * client.shard.broadcastEval(client => client.guilds.cache.size)
141
+ * .then(results => console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`))
142
+ * .catch(console.error);
143
+ * @see {@link ShardingManager#broadcastEval}
144
+ */
145
+ async broadcastEval(script, options = {}) {
146
+ return new Promise((resolve, reject) => {
147
+ const parent = this.parentPort ?? process;
148
+ if (typeof script !== 'function') {
149
+ reject(new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast));
150
+ return;
151
+ }
152
+
153
+ const evalScript = `(${script})(this, ${JSON.stringify(options.context)})`;
154
+
155
+ const listener = message => {
156
+ if (message?._sEval !== evalScript || message._sEvalShard !== options.shard) return;
157
+ parent.removeListener('message', listener);
158
+ this.decrementMaxListeners(parent);
159
+ if (message._error) reject(makeError(message._error));
160
+ else resolve(message._result);
161
+ };
162
+
163
+ this.incrementMaxListeners(parent);
164
+ parent.on('message', listener);
165
+ this.send({ _sEval: evalScript, _sEvalShard: options.shard }).catch(error => {
166
+ parent.removeListener('message', listener);
167
+ this.decrementMaxListeners(parent);
168
+ reject(error);
169
+ });
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Requests a respawn of all shards.
175
+ *
176
+ * @param {MultipleShardRespawnOptions} [options] Options for respawning shards
177
+ * @returns {Promise<void>} Resolves upon the message being sent
178
+ * @see {@link ShardingManager#respawnAll}
179
+ */
180
+ async respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}) {
181
+ return this.send({ _sRespawnAll: { shardDelay, respawnDelay, timeout } });
182
+ }
183
+
184
+ /**
185
+ * Handles an IPC message.
186
+ *
187
+ * @param {*} message Message received
188
+ * @private
189
+ */
190
+ async _handleMessage(message) {
191
+ if (!message) return;
192
+ if (message._fetchProp) {
193
+ try {
194
+ const props = message._fetchProp.split('.');
195
+ let value = this.client;
196
+ for (const prop of props) value = value[prop];
197
+ this._respond('fetchProp', { _fetchProp: message._fetchProp, _result: value });
198
+ } catch (error) {
199
+ this._respond('fetchProp', { _fetchProp: message._fetchProp, _error: makePlainError(error) });
200
+ }
201
+ } else if (message._eval) {
202
+ try {
203
+ this._respond('eval', { _eval: message._eval, _result: await this.client._eval(message._eval) });
204
+ } catch (error) {
205
+ this._respond('eval', { _eval: message._eval, _error: makePlainError(error) });
206
+ }
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Sends a message to the master process, emitting an error from the client upon failure.
212
+ *
213
+ * @param {string} type Type of response to send
214
+ * @param {*} message Message to send
215
+ * @private
216
+ */
217
+ _respond(type, message) {
218
+ this.send(message).catch(error_ => {
219
+ const error = new Error(`Error when sending ${type} response to master process: ${error_.message}`);
220
+ error.stack = error_.stack;
221
+ /**
222
+ * Emitted when the client encounters an error.
223
+ * <warn>Errors thrown within this event do not have a catch handler, it is
224
+ * recommended to not use async functions as `error` event handlers. See the
225
+ * {@link https://nodejs.org/api/events.html#capture-rejections-of-promises Node.js documentation}
226
+ * for details.)</warn>
227
+ *
228
+ * @event Client#error
229
+ * @param {Error} error The error encountered
230
+ */
231
+ this.client.emit(Events.Error, error);
232
+ });
233
+ }
234
+
235
+ /**
236
+ * Creates/gets the singleton of this class.
237
+ *
238
+ * @param {Client} client The client to use
239
+ * @param {ShardingManagerMode} mode Mode the shard was spawned with
240
+ * @returns {ShardClientUtil}
241
+ */
242
+ static singleton(client, mode) {
243
+ if (this._singleton) {
244
+ client.emit(
245
+ Events.Warn,
246
+ 'Multiple clients created in child process/worker; only the first will handle sharding helpers.',
247
+ );
248
+ } else {
249
+ this._singleton = new this(client, mode);
250
+ }
251
+
252
+ return this._singleton;
253
+ }
254
+
255
+ /**
256
+ * Get the shard id for a given guild id.
257
+ *
258
+ * @param {Snowflake} guildId Snowflake guild id to get shard id for
259
+ * @param {number} shardCount Number of shards
260
+ * @returns {number}
261
+ */
262
+ static shardIdForGuildId(guildId, shardCount) {
263
+ const shard = calculateShardId(guildId, shardCount);
264
+ if (shard < 0) throw new DiscordjsError(ErrorCodes.ShardingShardMiscalculation, shard, guildId, shardCount);
265
+ return shard;
266
+ }
267
+
268
+ /**
269
+ * Increments max listeners by one for a given emitter, if they are not zero.
270
+ *
271
+ * @param {Worker|ChildProcess} emitter The emitter that emits the events.
272
+ * @private
273
+ */
274
+ incrementMaxListeners(emitter) {
275
+ const maxListeners = emitter.getMaxListeners();
276
+ if (maxListeners !== 0) {
277
+ emitter.setMaxListeners(maxListeners + 1);
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Decrements max listeners by one for a given emitter, if they are not zero.
283
+ *
284
+ * @param {Worker|ChildProcess} emitter The emitter that emits the events.
285
+ * @private
286
+ */
287
+ decrementMaxListeners(emitter) {
288
+ const maxListeners = emitter.getMaxListeners();
289
+ if (maxListeners !== 0) {
290
+ emitter.setMaxListeners(maxListeners - 1);
291
+ }
292
+ }
293
+ }
@@ -0,0 +1,374 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import process from 'node:process';
4
+ import { setTimeout as sleep } from 'node:timers/promises';
5
+ import { Collection } from '@ovencord/collection';
6
+ import { range } from '@ovencord/util';
7
+ import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
8
+ import { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } from '../errors/index.js';
9
+ import { fetchRecommendedShardCount } from '../util/Util.js';
10
+ import { Shard } from './Shard.js';
11
+
12
+ /**
13
+ * This is a utility class that makes multi-process sharding of a bot an easy and painless experience.
14
+ * It works by spawning a self-contained {@link ChildProcess} or {@link Worker} for each individual shard, each
15
+ * containing its own instance of your bot's {@link Client}. They all have a line of communication with the master
16
+ * process, and there are several useful methods that utilize it in order to simplify tasks that are normally difficult
17
+ * with sharding. It can spawn a specific number of shards or the amount that Discord suggests for the bot, and takes a
18
+ * path to your main bot script to launch for each one.
19
+ *
20
+ * @extends {AsyncEventEmitter}
21
+ */
22
+ export class ShardingManager extends AsyncEventEmitter {
23
+ public file: any;
24
+ public shardList: any;
25
+ public totalShards: any;
26
+ public mode: any;
27
+ public silent: any;
28
+ public shardArgs: any;
29
+ public execArgv: any;
30
+ public token: any;
31
+ /**
32
+ * The mode to spawn shards with for a {@link ShardingManager}. Can be either one of:
33
+ * - 'process' to use child processes
34
+ * - 'worker' to use {@link Worker} threads
35
+ *
36
+ * @typedef {string} ShardingManagerMode
37
+ */
38
+
39
+ /**
40
+ * The options to spawn shards with for a {@link ShardingManager}.
41
+ *
42
+ * @typedef {Object} ShardingManagerOptions
43
+ * @property {string|number} [totalShards='auto'] Number of total shards of all shard managers or "auto"
44
+ * @property {string|number[]} [shardList='auto'] List of shards to spawn or "auto"
45
+ * @property {ShardingManagerMode} [mode='process'] Which mode to use for shards
46
+ * @property {boolean} [respawn=true] Whether shards should automatically respawn upon exiting
47
+ * @property {boolean} [silent=false] Whether to pass the silent flag to child process
48
+ * (only available when mode is set to 'process')
49
+ * @property {string[]} [shardArgs=[]] Arguments to pass to the shard script when spawning
50
+ * @property {string[]} [execArgv=[]] Arguments to pass to the shard script executable when spawning
51
+ * @property {string} [token] Token to use for automatic shard count and passing to shards
52
+ */
53
+
54
+ /**
55
+ * @param {string} file Path to your shard script file
56
+ * @param {ShardingManagerOptions} [options] Options for the sharding manager
57
+ */
58
+ constructor(file, options) {
59
+ super();
60
+ const _options = {
61
+ totalShards: 'auto',
62
+ mode: 'process',
63
+ respawn: true,
64
+ silent: false,
65
+ shardArgs: [],
66
+ execArgv: [],
67
+ token: process.env.DISCORD_TOKEN,
68
+ ...options,
69
+ };
70
+
71
+ /**
72
+ * Path to the shard script file
73
+ *
74
+ * @type {string}
75
+ */
76
+ this.file = file;
77
+ if (!file) throw new DiscordjsError(ErrorCodes.ClientInvalidOption, 'File', 'specified.');
78
+ if (!path.isAbsolute(file)) this.file = path.resolve(process.cwd(), file);
79
+ // eslint-disable-next-line
80
+ const stats = fs.statSync(this.file);
81
+ if (!stats.isFile()) throw new DiscordjsError(ErrorCodes.ClientInvalidOption, 'File', 'a file');
82
+
83
+ /**
84
+ * List of shards this sharding manager spawns
85
+ *
86
+ * @type {string|number[]}
87
+ */
88
+ this.shardList = _options.shardList ?? 'auto';
89
+ if (this.shardList !== 'auto') {
90
+ if (!Array.isArray(this.shardList)) {
91
+ throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array.');
92
+ }
93
+
94
+ this.shardList = [...new Set(this.shardList)];
95
+ if (this.shardList.length < 1) {
96
+ throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'shardList', 'at least 1 id.');
97
+ }
98
+
99
+ if (
100
+ this.shardList.some(
101
+ shardId => typeof shardId !== 'number' || Number.isNaN(shardId) || !Number.isInteger(shardId) || shardId < 0,
102
+ )
103
+ ) {
104
+ throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'shardList', 'an array of positive integers.');
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Amount of shards that all sharding managers spawn in total
110
+ *
111
+ * @type {number}
112
+ */
113
+ this.totalShards = _options.totalShards || 'auto';
114
+ if (this.totalShards !== 'auto') {
115
+ if (typeof this.totalShards !== 'number' || Number.isNaN(this.totalShards)) {
116
+ throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
117
+ }
118
+
119
+ if (this.totalShards < 1) {
120
+ throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'at least 1.');
121
+ }
122
+
123
+ if (!Number.isInteger(this.totalShards)) {
124
+ throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'an integer.');
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Mode for shards to spawn with
130
+ *
131
+ * @type {ShardingManagerMode}
132
+ */
133
+ this.mode = _options.mode;
134
+ if (this.mode !== 'process' && this.mode !== 'worker') {
135
+ throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Sharding mode', '"process" or "worker"');
136
+ }
137
+
138
+ /**
139
+ * Whether shards should automatically respawn upon exiting
140
+ *
141
+ * @type {boolean}
142
+ */
143
+ this.respawn = _options.respawn;
144
+
145
+ /**
146
+ * Whether to pass the silent flag to child process (only when {@link ShardingManager#mode} is `process`)
147
+ *
148
+ * @type {boolean}
149
+ */
150
+ this.silent = _options.silent;
151
+
152
+ /**
153
+ * An array of arguments to pass to shards (only when {@link ShardingManager#mode} is `process`)
154
+ *
155
+ * @type {string[]}
156
+ */
157
+ this.shardArgs = _options.shardArgs;
158
+
159
+ /**
160
+ * An array of arguments to pass to the executable (only when {@link ShardingManager#mode} is `process`)
161
+ *
162
+ * @type {string[]}
163
+ */
164
+ this.execArgv = _options.execArgv;
165
+
166
+ /**
167
+ * Token to use for obtaining the automatic shard count, and passing to shards
168
+ *
169
+ * @type {?string}
170
+ */
171
+ this.token = _options.token?.replace(/^bot\s*/i, '') ?? null;
172
+
173
+ /**
174
+ * A collection of shards that this manager has spawned
175
+ *
176
+ * @type {Collection<number, Shard>}
177
+ */
178
+ this.shards = new Collection();
179
+
180
+ process.env.SHARDING_MANAGER = true;
181
+ process.env.SHARDING_MANAGER_MODE = this.mode;
182
+ process.env.DISCORD_TOKEN = this.token;
183
+ }
184
+
185
+ /**
186
+ * Creates a single shard.
187
+ * <warn>Using this method is usually not necessary if you use the spawn method.</warn>
188
+ *
189
+ * @param {number} [id=this.shards.size] Id of the shard to create
190
+ * <info>This is usually not necessary to manually specify.</info>
191
+ * @returns {Shard} Note that the created shard needs to be explicitly spawned using its spawn method.
192
+ */
193
+ createShard(id = this.shards.size) {
194
+ const shard = new Shard(this, id);
195
+ this.shards.set(id, shard);
196
+ /**
197
+ * Emitted upon creating a shard.
198
+ *
199
+ * @event ShardingManager#shardCreate
200
+ * @param {Shard} shard Shard that was created
201
+ */
202
+ this.emit('shardCreate', shard);
203
+ return shard;
204
+ }
205
+
206
+ /**
207
+ * Options used to spawn multiple shards.
208
+ *
209
+ * @typedef {Object} MultipleShardSpawnOptions
210
+ * @property {number|string} [amount=this.totalShards] Number of shards to spawn
211
+ * @property {number} [delay=5500] How long to wait in between spawning each shard (in milliseconds)
212
+ * @property {number} [timeout=30000] The amount in milliseconds to wait until the {@link Client} has become ready
213
+ */
214
+
215
+ /**
216
+ * Spawns multiple shards.
217
+ *
218
+ * @param {MultipleShardSpawnOptions} [options] Options for spawning shards
219
+ * @returns {Promise<Collection<number, Shard>>}
220
+ */
221
+ async spawn({ amount = this.totalShards, delay = 5_500, timeout = 30_000 } = {}) {
222
+ // Obtain/verify the number of shards to spawn
223
+ let shardAmount = amount;
224
+ if (shardAmount === 'auto') {
225
+ // eslint-disable-next-line require-atomic-updates
226
+ shardAmount = await fetchRecommendedShardCount(this.token);
227
+ } else {
228
+ if (typeof shardAmount !== 'number' || Number.isNaN(shardAmount)) {
229
+ throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'a number.');
230
+ }
231
+
232
+ if (shardAmount < 1) {
233
+ throw new DiscordjsRangeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'at least 1.');
234
+ }
235
+
236
+ if (!Number.isInteger(shardAmount)) {
237
+ throw new DiscordjsTypeError(ErrorCodes.ClientInvalidOption, 'Amount of shards', 'an integer.');
238
+ }
239
+ }
240
+
241
+ // Make sure this many shards haven't already been spawned
242
+ if (this.shards.size >= shardAmount) throw new DiscordjsError(ErrorCodes.ShardingAlreadySpawned, this.shards.size);
243
+ if (this.shardList === 'auto' || this.totalShards === 'auto' || this.totalShards !== shardAmount) {
244
+ this.shardList = [...range(shardAmount)];
245
+ }
246
+
247
+ if (this.totalShards === 'auto' || this.totalShards !== shardAmount) {
248
+ this.totalShards = shardAmount;
249
+ }
250
+
251
+ if (this.shardList.some(shardId => shardId >= shardAmount)) {
252
+ throw new DiscordjsRangeError(
253
+ ErrorCodes.ClientInvalidOption,
254
+ 'Amount of shards',
255
+ 'bigger than the highest shardId in the shardList option.',
256
+ );
257
+ }
258
+
259
+ // Spawn the shards
260
+ for (const shardId of this.shardList) {
261
+ const promises = [];
262
+ const shard = this.createShard(shardId);
263
+ promises.push(shard.spawn(timeout));
264
+ if (delay > 0 && this.shards.size !== this.shardList.length) promises.push(sleep(delay));
265
+ await Promise.all(promises);
266
+ }
267
+
268
+ return this.shards;
269
+ }
270
+
271
+ /**
272
+ * Sends a message to all shards.
273
+ *
274
+ * @param {*} message Message to be sent to the shards
275
+ * @returns {Promise<Shard[]>}
276
+ */
277
+ async broadcast(message) {
278
+ const promises = [];
279
+ for (const shard of this.shards.values()) promises.push(shard.send(message));
280
+ return Promise.all(promises);
281
+ }
282
+
283
+ /**
284
+ * Options for {@link ShardingManager#broadcastEval} and {@link ShardClientUtil#broadcastEval}.
285
+ *
286
+ * @typedef {Object} BroadcastEvalOptions
287
+ * @property {number} [shard] Shard to run script on, all if undefined
288
+ * @property {*} [context] The JSON-serializable values to call the script with
289
+ */
290
+
291
+ /**
292
+ * Evaluates a script on all shards, or a given shard, in the context of the {@link Client}s.
293
+ *
294
+ * @param {Function} script JavaScript to run on each shard
295
+ * @param {BroadcastEvalOptions} [options={}] The options for the broadcast
296
+ * @returns {Promise<*|Array<*>>} Results of the script execution
297
+ */
298
+ async broadcastEval(script, options = {}) {
299
+ if (typeof script !== 'function') {
300
+ throw new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast);
301
+ }
302
+
303
+ return this._performOnShards('eval', [`(${script})(this, ${JSON.stringify(options.context)})`], options.shard);
304
+ }
305
+
306
+ /**
307
+ * Fetches a client property value of each shard, or a given shard.
308
+ *
309
+ * @param {string} prop Name of the client property to get, using periods for nesting
310
+ * @param {number} [shard] Shard to fetch property from, all if undefined
311
+ * @returns {Promise<*|Array<*>>}
312
+ * @example
313
+ * manager.fetchClientValues('guilds.cache.size')
314
+ * .then(results => console.log(`${results.reduce((prev, val) => prev + val, 0)} total guilds`))
315
+ * .catch(console.error);
316
+ */
317
+ async fetchClientValues(prop, shard) {
318
+ return this._performOnShards('fetchClientValue', [prop], shard);
319
+ }
320
+
321
+ /**
322
+ * Runs a method with given arguments on all shards, or a given shard.
323
+ *
324
+ * @param {string} method Method name to run on each shard
325
+ * @param {Array<*>} args Arguments to pass through to the method call
326
+ * @param {number} [shard] Shard to run on, all if undefined
327
+ * @returns {Promise<*|Array<*>>} Results of the method execution
328
+ * @private
329
+ */
330
+ async _performOnShards(method, args, shard) {
331
+ if (this.shards.size === 0) throw new DiscordjsError(ErrorCodes.ShardingNoShards);
332
+
333
+ if (typeof shard === 'number') {
334
+ if (this.shards.has(shard)) return this.shards.get(shard)[method](...args);
335
+ throw new DiscordjsError(ErrorCodes.ShardingShardNotFound, shard);
336
+ }
337
+
338
+ if (this.shards.size !== this.shardList.length) {
339
+ throw new DiscordjsError(ErrorCodes.ShardingInProcess);
340
+ }
341
+
342
+ const promises = [];
343
+ for (const sh of this.shards.values()) promises.push(sh[method](...args));
344
+ return Promise.all(promises);
345
+ }
346
+
347
+ /**
348
+ * Options used to respawn all shards.
349
+ *
350
+ * @typedef {Object} MultipleShardRespawnOptions
351
+ * @property {number} [shardDelay=5000] How long to wait between shards (in milliseconds)
352
+ * @property {number} [respawnDelay=500] How long to wait between killing a shard's process and restarting it
353
+ * (in milliseconds)
354
+ * @property {number} [timeout=30000] The amount in milliseconds to wait for a shard to become ready before
355
+ * continuing to another (`-1` or `Infinity` for no wait)
356
+ */
357
+
358
+ /**
359
+ * Kills all running shards and respawns them.
360
+ *
361
+ * @param {MultipleShardRespawnOptions} [options] Options for respawning shards
362
+ * @returns {Promise<Collection<number, Shard>>}
363
+ */
364
+ async respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}) {
365
+ let shardCounter = 0;
366
+ for (const shard of this.shards.values()) {
367
+ const promises = [shard.respawn({ delay: respawnDelay, timeout })];
368
+ if (++shardCounter < this.shards.size && shardDelay > 0) promises.push(sleep(shardDelay));
369
+ await Promise.all(promises);
370
+ }
371
+
372
+ return this.shards;
373
+ }
374
+ }
@@ -0,0 +1,31 @@
1
+ import { createComponent } from '../util/Components.js';
2
+ import { Component } from './Component.js';
3
+
4
+ /**
5
+ * Represents an action row
6
+ *
7
+ * @extends {Component}
8
+ */
9
+ export class ActionRow extends Component {
10
+ public components: any;
11
+ constructor({ components, ...data }) {
12
+ super(data);
13
+
14
+ /**
15
+ * The components in this action row
16
+ *
17
+ * @type {Component[]}
18
+ * @readonly
19
+ */
20
+ this.components = components.map(component => createComponent(component));
21
+ }
22
+
23
+ /**
24
+ * Returns the API-compatible JSON for this component
25
+ *
26
+ * @returns {APIActionRowComponent}
27
+ */
28
+ toJSON() {
29
+ return { ...this.data, components: this.components.map(component => component.toJSON()) };
30
+ }
31
+ }