seyfert 2.0.0 → 2.1.1-dev-11310514874.0

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 (265) hide show
  1. package/lib/api/Router.d.ts +2 -2
  2. package/lib/api/Router.js +2 -1
  3. package/lib/api/Routes/applications.d.ts +29 -30
  4. package/lib/api/Routes/cdn.d.ts +6 -1
  5. package/lib/api/Routes/channels.d.ts +44 -45
  6. package/lib/api/Routes/gateway.d.ts +3 -4
  7. package/lib/api/Routes/guilds.d.ts +81 -80
  8. package/lib/api/Routes/index.d.ts +3 -1
  9. package/lib/api/Routes/interactions.d.ts +9 -3
  10. package/lib/api/Routes/invites.d.ts +3 -4
  11. package/lib/api/Routes/skus.d.ts +10 -0
  12. package/lib/api/Routes/skus.js +2 -0
  13. package/lib/api/Routes/soundboard.d.ts +23 -0
  14. package/lib/api/Routes/soundboard.js +2 -0
  15. package/lib/api/Routes/stage-instances.d.ts +5 -6
  16. package/lib/api/Routes/stickers.d.ts +3 -4
  17. package/lib/api/Routes/users.d.ts +11 -12
  18. package/lib/api/Routes/voice.d.ts +2 -3
  19. package/lib/api/Routes/webhooks.d.ts +16 -15
  20. package/lib/api/api.d.ts +17 -11
  21. package/lib/api/api.js +26 -22
  22. package/lib/api/shared.d.ts +2 -2
  23. package/lib/api/utils/constants.d.ts +3 -1
  24. package/lib/api/utils/constants.js +3 -2
  25. package/lib/builders/ActionRow.d.ts +1 -1
  26. package/lib/builders/Attachment.d.ts +3 -3
  27. package/lib/builders/Attachment.js +13 -13
  28. package/lib/builders/Button.d.ts +1 -1
  29. package/lib/builders/Button.js +1 -1
  30. package/lib/builders/Embed.d.ts +1 -1
  31. package/lib/builders/Embed.js +2 -2
  32. package/lib/builders/Modal.d.ts +1 -1
  33. package/lib/builders/Poll.d.ts +1 -1
  34. package/lib/builders/Poll.js +1 -1
  35. package/lib/builders/SelectMenu.d.ts +1 -1
  36. package/lib/builders/SelectMenu.js +1 -1
  37. package/lib/builders/types.d.ts +2 -1
  38. package/lib/cache/adapters/default.js +5 -3
  39. package/lib/cache/adapters/limited.d.ts +1 -2
  40. package/lib/cache/adapters/limited.js +34 -30
  41. package/lib/cache/adapters/workeradapter.js +3 -1
  42. package/lib/cache/index.d.ts +12 -12
  43. package/lib/cache/index.js +48 -39
  44. package/lib/cache/resources/bans.d.ts +2 -2
  45. package/lib/cache/resources/bans.js +1 -1
  46. package/lib/cache/resources/channels.d.ts +1 -1
  47. package/lib/cache/resources/default/guild-related.d.ts +1 -2
  48. package/lib/cache/resources/emojis.d.ts +2 -2
  49. package/lib/cache/resources/emojis.js +1 -1
  50. package/lib/cache/resources/guilds.d.ts +2 -2
  51. package/lib/cache/resources/guilds.js +7 -11
  52. package/lib/cache/resources/members.d.ts +2 -2
  53. package/lib/cache/resources/members.js +1 -1
  54. package/lib/cache/resources/messages.d.ts +2 -2
  55. package/lib/cache/resources/messages.js +3 -3
  56. package/lib/cache/resources/overwrites.d.ts +1 -1
  57. package/lib/cache/resources/roles.d.ts +2 -2
  58. package/lib/cache/resources/roles.js +1 -1
  59. package/lib/cache/resources/stickers.d.ts +2 -2
  60. package/lib/cache/resources/stickers.js +1 -1
  61. package/lib/cache/resources/users.d.ts +2 -2
  62. package/lib/cache/resources/users.js +1 -1
  63. package/lib/cache/resources/voice-states.d.ts +2 -2
  64. package/lib/cache/resources/voice-states.js +1 -1
  65. package/lib/client/base.d.ts +10 -15
  66. package/lib/client/base.js +48 -44
  67. package/lib/client/client.d.ts +4 -4
  68. package/lib/client/client.js +37 -38
  69. package/lib/client/collectors.js +1 -1
  70. package/lib/client/httpclient.d.ts +1 -1
  71. package/lib/client/httpclient.js +2 -2
  72. package/lib/client/transformers.d.ts +37 -34
  73. package/lib/client/transformers.js +66 -63
  74. package/lib/client/workerclient.d.ts +13 -13
  75. package/lib/client/workerclient.js +182 -65
  76. package/lib/collection.d.ts +3 -3
  77. package/lib/commands/applications/chat.d.ts +3 -3
  78. package/lib/commands/applications/chat.js +5 -6
  79. package/lib/commands/applications/chatcontext.d.ts +6 -6
  80. package/lib/commands/applications/chatcontext.js +16 -8
  81. package/lib/commands/applications/entryPoint.d.ts +46 -0
  82. package/lib/commands/applications/entryPoint.js +56 -0
  83. package/lib/commands/applications/entrycontext.d.ts +40 -0
  84. package/lib/commands/applications/entrycontext.js +85 -0
  85. package/lib/commands/applications/menu.d.ts +1 -1
  86. package/lib/commands/applications/menucontext.d.ts +5 -5
  87. package/lib/commands/applications/menucontext.js +6 -6
  88. package/lib/commands/applications/options.d.ts +7 -6
  89. package/lib/commands/applications/shared.d.ts +5 -2
  90. package/lib/commands/basecontext.d.ts +1 -1
  91. package/lib/commands/decorators.d.ts +20 -26
  92. package/lib/commands/decorators.js +8 -4
  93. package/lib/commands/handle.d.ts +13 -12
  94. package/lib/commands/handle.js +133 -65
  95. package/lib/commands/handler.d.ts +9 -7
  96. package/lib/commands/handler.js +27 -18
  97. package/lib/commands/index.d.ts +2 -0
  98. package/lib/commands/index.js +2 -0
  99. package/lib/commands/optionresolver.d.ts +4 -4
  100. package/lib/commands/optionresolver.js +4 -4
  101. package/lib/common/bot/watcher.d.ts +1 -1
  102. package/lib/common/it/formatter.d.ts +21 -21
  103. package/lib/common/it/formatter.js +40 -41
  104. package/lib/common/it/logger.js +1 -1
  105. package/lib/common/it/utils.d.ts +14 -6
  106. package/lib/common/it/utils.js +62 -27
  107. package/lib/common/shorters/application.d.ts +2 -3
  108. package/lib/common/shorters/application.js +3 -3
  109. package/lib/common/shorters/bans.js +1 -1
  110. package/lib/common/shorters/channels.d.ts +3 -3
  111. package/lib/common/shorters/channels.js +3 -3
  112. package/lib/common/shorters/emojis.js +4 -4
  113. package/lib/common/shorters/guilds.d.ts +3 -3
  114. package/lib/common/shorters/guilds.js +5 -9
  115. package/lib/common/shorters/interaction.d.ts +3 -3
  116. package/lib/common/shorters/interaction.js +6 -5
  117. package/lib/common/shorters/members.d.ts +4 -5
  118. package/lib/common/shorters/members.js +6 -7
  119. package/lib/common/shorters/messages.d.ts +1 -1
  120. package/lib/common/shorters/messages.js +4 -4
  121. package/lib/common/shorters/reactions.d.ts +1 -1
  122. package/lib/common/shorters/reactions.js +1 -1
  123. package/lib/common/shorters/roles.js +1 -1
  124. package/lib/common/shorters/templates.js +2 -2
  125. package/lib/common/shorters/threads.d.ts +1 -1
  126. package/lib/common/shorters/threads.js +17 -11
  127. package/lib/common/shorters/webhook.d.ts +1 -1
  128. package/lib/common/shorters/webhook.js +4 -4
  129. package/lib/common/types/options.d.ts +2 -2
  130. package/lib/common/types/resolvables.d.ts +1 -1
  131. package/lib/common/types/util.d.ts +4 -1
  132. package/lib/common/types/write.d.ts +3 -3
  133. package/lib/components/BaseComponent.js +1 -1
  134. package/lib/components/ButtonComponent.d.ts +1 -1
  135. package/lib/components/componentcommand.d.ts +1 -1
  136. package/lib/components/componentcontext.d.ts +4 -4
  137. package/lib/components/componentcontext.js +1 -1
  138. package/lib/components/handler.d.ts +10 -8
  139. package/lib/components/handler.js +16 -13
  140. package/lib/components/index.js +2 -1
  141. package/lib/components/modalcontext.d.ts +2 -2
  142. package/lib/components/modalcontext.js +1 -1
  143. package/lib/deps/mixer.d.ts +1 -1
  144. package/lib/deps/mixer.js +6 -1
  145. package/lib/events/handler.d.ts +5 -5
  146. package/lib/events/handler.js +69 -19
  147. package/lib/events/hooks/application_command.d.ts +1 -1
  148. package/lib/events/hooks/auto_moderation.d.ts +1 -1
  149. package/lib/events/hooks/auto_moderation.js +1 -1
  150. package/lib/events/hooks/channel.d.ts +1 -1
  151. package/lib/events/hooks/custom.d.ts +1 -0
  152. package/lib/events/hooks/custom.js +5 -1
  153. package/lib/events/hooks/dispatch.d.ts +1 -1
  154. package/lib/events/hooks/entitlement.d.ts +4 -5
  155. package/lib/events/hooks/entitlement.js +4 -4
  156. package/lib/events/hooks/guild.d.ts +3 -3
  157. package/lib/events/hooks/guild.js +1 -1
  158. package/lib/events/hooks/index.d.ts +1 -0
  159. package/lib/events/hooks/index.js +1 -0
  160. package/lib/events/hooks/integration.d.ts +1 -1
  161. package/lib/events/hooks/integration.js +1 -1
  162. package/lib/events/hooks/interactions.d.ts +3 -3
  163. package/lib/events/hooks/invite.d.ts +1 -1
  164. package/lib/events/hooks/message.d.ts +3 -3
  165. package/lib/events/hooks/message.js +1 -1
  166. package/lib/events/hooks/presence.d.ts +2 -2
  167. package/lib/events/hooks/soundboard.d.ts +155 -0
  168. package/lib/events/hooks/soundboard.js +28 -0
  169. package/lib/events/hooks/stage.d.ts +2 -2
  170. package/lib/events/hooks/subscriptions.d.ts +35 -0
  171. package/lib/events/hooks/subscriptions.js +16 -0
  172. package/lib/events/hooks/thread.d.ts +2 -2
  173. package/lib/events/hooks/thread.js +2 -2
  174. package/lib/events/hooks/typing.d.ts +1 -1
  175. package/lib/events/hooks/typing.js +1 -1
  176. package/lib/events/hooks/user.d.ts +2 -2
  177. package/lib/events/hooks/voice.d.ts +2 -2
  178. package/lib/events/hooks/voice.js +1 -1
  179. package/lib/events/hooks/webhook.d.ts +1 -1
  180. package/lib/index.d.ts +2 -2
  181. package/lib/index.js +3 -5
  182. package/lib/langs/handler.d.ts +2 -2
  183. package/lib/structures/Guild.d.ts +7 -4
  184. package/lib/structures/Guild.js +1 -1
  185. package/lib/structures/GuildBan.d.ts +1 -1
  186. package/lib/structures/GuildMember.d.ts +7 -5
  187. package/lib/structures/GuildMember.js +5 -3
  188. package/lib/structures/GuildRole.d.ts +1 -1
  189. package/lib/structures/GuildTemplate.d.ts +1 -1
  190. package/lib/structures/Interaction.d.ts +39 -16
  191. package/lib/structures/Interaction.js +82 -26
  192. package/lib/structures/Message.d.ts +4 -10
  193. package/lib/structures/Message.js +5 -8
  194. package/lib/structures/Poll.d.ts +3 -3
  195. package/lib/structures/Sticker.d.ts +2 -2
  196. package/lib/structures/Sticker.js +1 -1
  197. package/lib/structures/VoiceState.d.ts +2 -1
  198. package/lib/structures/VoiceState.js +1 -1
  199. package/lib/structures/Webhook.d.ts +3 -3
  200. package/lib/structures/Webhook.js +1 -1
  201. package/lib/structures/channels.d.ts +4 -4
  202. package/lib/structures/channels.js +8 -7
  203. package/lib/structures/extra/BaseGuild.d.ts +11 -1
  204. package/lib/structures/extra/BaseGuild.js +27 -0
  205. package/lib/structures/extra/BitField.d.ts +3 -3
  206. package/lib/structures/extra/BitField.js +34 -33
  207. package/lib/structures/extra/DiscordBase.js +1 -1
  208. package/lib/structures/extra/Permissions.d.ts +2 -0
  209. package/lib/structures/extra/Permissions.js +21 -0
  210. package/lib/types/gateway.d.ts +71 -6
  211. package/lib/types/payloads/_interactions/_applicationCommands/chatInput.d.ts +6 -1
  212. package/lib/types/payloads/_interactions/applicationCommands.d.ts +41 -6
  213. package/lib/types/payloads/_interactions/applicationCommands.js +28 -1
  214. package/lib/types/payloads/_interactions/base.d.ts +1 -1
  215. package/lib/types/payloads/_interactions/responses.d.ts +74 -2
  216. package/lib/types/payloads/_interactions/responses.js +4 -0
  217. package/lib/types/payloads/channel.d.ts +46 -6
  218. package/lib/types/payloads/channel.js +5 -1
  219. package/lib/types/payloads/guild.d.ts +9 -1
  220. package/lib/types/payloads/guild.js +8 -0
  221. package/lib/types/payloads/index.d.ts +1 -0
  222. package/lib/types/payloads/index.js +1 -0
  223. package/lib/types/payloads/monetization.d.ts +29 -1
  224. package/lib/types/payloads/monetization.js +10 -1
  225. package/lib/types/payloads/soundboard.d.ts +23 -0
  226. package/lib/types/payloads/soundboard.js +5 -0
  227. package/lib/types/payloads/user.js +0 -1
  228. package/lib/types/rest/application.d.ts +3 -3
  229. package/lib/types/rest/auditLog.d.ts +1 -1
  230. package/lib/types/rest/channel.d.ts +5 -18
  231. package/lib/types/rest/guild.d.ts +2 -2
  232. package/lib/types/rest/guildScheduledEvent.d.ts +1 -1
  233. package/lib/types/rest/index.d.ts +1 -0
  234. package/lib/types/rest/index.js +1 -0
  235. package/lib/types/rest/interactions.d.ts +30 -8
  236. package/lib/types/rest/monetization.d.ts +22 -1
  237. package/lib/types/rest/oauth2.d.ts +1 -1
  238. package/lib/types/rest/poll.d.ts +1 -1
  239. package/lib/types/rest/soundboard.d.ts +64 -0
  240. package/lib/types/rest/soundboard.js +2 -0
  241. package/lib/types/rest/stageInstance.d.ts +1 -1
  242. package/lib/types/rest/template.d.ts +1 -1
  243. package/lib/types/rest/user.d.ts +1 -1
  244. package/lib/types/rest/webhook.d.ts +3 -3
  245. package/lib/types/utils/index.d.ts +27 -7
  246. package/lib/types/utils/index.js +25 -6
  247. package/lib/websocket/SharedTypes.d.ts +18 -3
  248. package/lib/websocket/constants/index.d.ts +3 -2
  249. package/lib/websocket/constants/index.js +4 -4
  250. package/lib/websocket/discord/basesocket.d.ts +1 -1
  251. package/lib/websocket/discord/shard.d.ts +4 -3
  252. package/lib/websocket/discord/shard.js +47 -24
  253. package/lib/websocket/discord/sharder.d.ts +9 -6
  254. package/lib/websocket/discord/sharder.js +92 -17
  255. package/lib/websocket/discord/shared.d.ts +12 -3
  256. package/lib/websocket/discord/socket/custom.d.ts +1 -1
  257. package/lib/websocket/discord/socket/custom.js +70 -40
  258. package/lib/websocket/discord/worker.d.ts +9 -2
  259. package/lib/websocket/discord/workermanager.d.ts +42 -16
  260. package/lib/websocket/discord/workermanager.js +170 -46
  261. package/lib/websocket/structures/timeout.d.ts +4 -5
  262. package/lib/websocket/structures/timeout.js +23 -24
  263. package/package.json +72 -65
  264. package/lib/cache/resources/threads.d.ts +0 -14
  265. package/lib/cache/resources/threads.js +0 -32
@@ -53,10 +53,10 @@ class ShardManager extends Map {
53
53
  return acc / this.size;
54
54
  }
55
55
  calculateShardId(guildId) {
56
- return Number((BigInt(guildId) >> 22n) % BigInt(this.options.info.shards ?? 1));
56
+ return (0, common_1.calculateShardId)(guildId, this.totalShards);
57
57
  }
58
- spawn(shardId) {
59
- this.debugger?.info(`Spawn shard ${shardId}`);
58
+ create(shardId) {
59
+ this.debugger?.info(`Creating shard ${shardId}`);
60
60
  let shard = this.get(shardId);
61
61
  shard ??= new shard_1.Shard(shardId, {
62
62
  token: this.options.token,
@@ -73,7 +73,7 @@ class ShardManager extends Map {
73
73
  }
74
74
  async spawnShards() {
75
75
  const buckets = this.spawnBuckets();
76
- this.debugger?.info('Spawn shards');
76
+ this.debugger?.info('Spawning shards');
77
77
  for (const bucket of buckets) {
78
78
  for (const shard of bucket) {
79
79
  if (!shard) {
@@ -83,6 +83,81 @@ class ShardManager extends Map {
83
83
  this.connectQueue.push(shard.connect.bind(shard));
84
84
  }
85
85
  }
86
+ await this.startResharder();
87
+ }
88
+ async startResharder() {
89
+ if (this.options.resharding.interval <= 0)
90
+ return;
91
+ if (this.shardStart !== 0 || this.shardEnd !== this.totalShards)
92
+ return this.debugger?.debug('Cannot start resharder');
93
+ this.debugger?.debug('Resharder enabled');
94
+ setInterval(async () => {
95
+ this.debugger?.debug('Checking if reshard is needed');
96
+ const info = await this.options.resharding.getInfo();
97
+ if (info.shards <= this.totalShards)
98
+ return this.debugger?.debug('Resharding not needed');
99
+ //https://github.com/discordeno/discordeno/blob/6a5f446c0651b9fad9f1550ff1857fe7a026426b/packages/gateway/src/manager.ts#L106C8-L106C94
100
+ const percentage = (info.shards / ((this.totalShards * 2500) / 1000)) * 100;
101
+ if (percentage < this.options.resharding.percentage)
102
+ return this.debugger?.debug(`Percentage is not enough to reshard ${percentage}/${this.options.resharding.percentage}`);
103
+ this.debugger?.info('Starting resharding process');
104
+ this.connectQueue.concurrency = info.session_start_limit.max_concurrency;
105
+ this.options.info.session_start_limit.max_concurrency = info.session_start_limit.max_concurrency;
106
+ //waiting for all shards to connect
107
+ let shardsConnected = 0;
108
+ const handleGuilds = new Set();
109
+ let handlePayload = async (sharder, _, packet) => {
110
+ if (packet.t === 'GUILD_CREATE' || packet.t === 'GUILD_DELETE') {
111
+ handleGuilds.delete(packet.d.id);
112
+ if (shardsConnected === info.shards && !handleGuilds.size) {
113
+ return cleanProcess(sharder);
114
+ }
115
+ }
116
+ if (packet.t !== 'READY')
117
+ return;
118
+ for (const guild of packet.d.guilds) {
119
+ handleGuilds.add(guild.id);
120
+ }
121
+ if (++shardsConnected < info.shards || handleGuilds.size)
122
+ return;
123
+ cleanProcess(sharder);
124
+ // dont listen more events when all shards are ready
125
+ };
126
+ const cleanProcess = (sharder) => {
127
+ handlePayload = async () => {
128
+ //
129
+ };
130
+ this.disconnectAll();
131
+ this.clear();
132
+ this.options.totalShards = this.options.shardEnd = info.shards;
133
+ for (const [id, shard] of sharder) {
134
+ shard.options.handlePayload = (shardId, packet) => {
135
+ return this.options.handlePayload(shardId, packet);
136
+ };
137
+ this.set(id, shard);
138
+ }
139
+ sharder.clear();
140
+ };
141
+ const options = (0, common_1.MergeOptions)(this.options, {
142
+ totalShards: info.shards,
143
+ shardEnd: info.shards,
144
+ });
145
+ const resharder = new ShardManager({
146
+ ...options,
147
+ resharding: {
148
+ // getInfo mock, we don't need it
149
+ getInfo: () => ({}),
150
+ interval: 0,
151
+ percentage: 0,
152
+ },
153
+ handlePayload: (shardId, packet) => {
154
+ return handlePayload(resharder, shardId, packet);
155
+ },
156
+ });
157
+ // share ratelimit
158
+ resharder.connectQueue = this.connectQueue;
159
+ await resharder.spawnShards();
160
+ }, this.options.resharding.interval);
86
161
  }
87
162
  /*
88
163
  * spawns buckets in order
@@ -94,7 +169,7 @@ class ShardManager extends Map {
94
169
  chunks.forEach((arr, index) => {
95
170
  for (let i = 0; i < arr.length; i++) {
96
171
  const id = i + (index > 0 ? index * this.concurrency : 0) + this.shardStart;
97
- chunks[index][i] = this.spawn(id);
172
+ chunks[index][i] = this.create(id);
98
173
  }
99
174
  });
100
175
  this.debugger?.info(`${chunks.length} buckets created`);
@@ -102,7 +177,7 @@ class ShardManager extends Map {
102
177
  }
103
178
  forceIdentify(shardId) {
104
179
  this.debugger?.info(`Shard #${shardId} force identify`);
105
- return this.spawn(shardId).identify();
180
+ return this.create(shardId).identify();
106
181
  }
107
182
  disconnect(shardId) {
108
183
  this.debugger?.info(`Shard #${shardId} force disconnect`);
@@ -110,10 +185,7 @@ class ShardManager extends Map {
110
185
  }
111
186
  disconnectAll() {
112
187
  this.debugger?.info('Disconnect all shards');
113
- return new Promise(resolve => {
114
- this.forEach(shard => shard.disconnect());
115
- resolve(null);
116
- });
188
+ this.forEach(shard => shard.disconnect());
117
189
  }
118
190
  setShardPresence(shardId, payload) {
119
191
  this.debugger?.info(`Shard #${shardId} update presence`);
@@ -123,12 +195,9 @@ class ShardManager extends Map {
123
195
  });
124
196
  }
125
197
  setPresence(payload) {
126
- return new Promise(resolve => {
127
- this.forEach(shard => {
128
- this.setShardPresence(shard.id, payload);
129
- }, this);
130
- resolve();
131
- });
198
+ this.forEach(shard => {
199
+ this.setShardPresence(shard.id, payload);
200
+ }, this);
132
201
  }
133
202
  joinVoice(guild_id, channel_id, options) {
134
203
  const shardId = this.calculateShardId(guild_id);
@@ -144,7 +213,6 @@ class ShardManager extends Map {
144
213
  }
145
214
  leaveVoice(guild_id) {
146
215
  const shardId = this.calculateShardId(guild_id);
147
- this.debugger?.info(`Shard #${shardId} leave voice in ${guild_id}`);
148
216
  return this.send(shardId, {
149
217
  op: types_1.GatewayOpcodes.VoiceStateUpdate,
150
218
  d: {
@@ -165,5 +233,12 @@ class ShardManager extends Map {
165
233
  }
166
234
  this.get(shardId)?.send(false, payload);
167
235
  }
236
+ resume(shardId, shardData) {
237
+ if (this.has(shardId))
238
+ throw new Error('Cannot override existing shard');
239
+ const shard = this.create(shardId);
240
+ shard.data = shardData;
241
+ return this.connectQueue.push(shard.connect.bind(shard));
242
+ }
168
243
  }
169
244
  exports.ShardManager = ShardManager;
@@ -1,5 +1,5 @@
1
- import type { APIGatewayBotInfo, GatewayDispatchPayload, GatewayIntentBits, GatewayPresenceUpdateData } from '../../types';
2
1
  import type { Awaitable, DeepPartial, Logger } from '../../common';
2
+ import type { APIGatewayBotInfo, GatewayDispatchPayload, GatewayIntentBits, GatewayPresenceUpdateData } from '../../types';
3
3
  import type { IdentifyProperties } from '../constants';
4
4
  export interface ShardManagerOptions extends ShardDetails {
5
5
  /** Important data which is used by the manager to connect shards to the gateway. */
@@ -29,6 +29,14 @@ export interface ShardManagerOptions extends ShardDetails {
29
29
  */
30
30
  presence?: (shardId: number, workerId: number) => GatewayPresenceUpdateData;
31
31
  compress?: boolean;
32
+ resharding?: {
33
+ /**
34
+ * @returns the gateway connection info
35
+ */
36
+ getInfo(): Promise<APIGatewayBotInfo>;
37
+ interval: number;
38
+ percentage: number;
39
+ };
32
40
  }
33
41
  export interface CustomManagerAdapter {
34
42
  postMessage(workerId: number, body: unknown): Awaitable<unknown>;
@@ -39,12 +47,12 @@ export interface WorkerManagerOptions extends Omit<ShardManagerOptions, 'handleP
39
47
  adapter?: CustomManagerAdapter;
40
48
  workers?: number;
41
49
  /**
42
- * @default 32
50
+ * @default 16
43
51
  */
44
52
  shardsPerWorker?: number;
45
53
  workerProxy?: boolean;
46
54
  path: string;
47
- handlePayload(shardId: number, workerId: number, packet: GatewayDispatchPayload): unknown;
55
+ handlePayload?(shardId: number, workerId: number, packet: GatewayDispatchPayload): any;
48
56
  properties?: DeepPartial<NonNullable<ShardManagerOptions['properties']>>;
49
57
  }
50
58
  export interface ShardData {
@@ -109,4 +117,5 @@ export interface WorkerData {
109
117
  debug: boolean;
110
118
  workerProxy: boolean;
111
119
  __USING_WATCHER__?: boolean;
120
+ resharding: boolean;
112
121
  }
@@ -19,7 +19,7 @@ export declare class SeyfertWebSocket {
19
19
  private connect;
20
20
  handleReadable(): void;
21
21
  handleEvent(body: Buffer, opcode: number): void;
22
- handleClose(): void;
22
+ handleClose(): Promise<void>;
23
23
  send(data: string): void;
24
24
  private _write;
25
25
  onping(_data: string): void;
@@ -18,38 +18,51 @@ class SeyfertWebSocket {
18
18
  this.path = `${urlParts.pathname}${urlParts.search || ''}`;
19
19
  this.connect();
20
20
  }
21
- connect() {
22
- const key = (0, node_crypto_1.randomBytes)(16).toString('base64');
23
- const req = (0, node_https_1.request)({
24
- //discord gateway hostname
25
- hostname: this.hostname,
26
- path: this.path,
27
- headers: {
28
- Connection: 'Upgrade',
29
- Upgrade: 'websocket',
30
- 'Sec-WebSocket-Key': key,
31
- 'Sec-WebSocket-Version': '13',
32
- },
33
- });
34
- req.on('upgrade', (res, socket) => {
35
- const hash = (0, node_crypto_1.createHash)('sha1').update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest('base64');
36
- const accept = res.headers['sec-websocket-accept'];
37
- if (accept !== hash) {
38
- socket.end(() => {
39
- this.onerror(new Error('Invalid sec-websocket-accept header'));
40
- });
41
- return;
42
- }
43
- this.socket = socket;
44
- socket.on('readable', this.handleReadable.bind(this));
45
- socket.on('close', this.handleClose.bind(this));
46
- socket.on('error', err => this.onerror(err));
47
- this.onopen();
48
- });
49
- req.on('close', () => {
50
- req.removeAllListeners();
21
+ connect(retries = 0) {
22
+ return new Promise((resolve, rej) => {
23
+ const key = (0, node_crypto_1.randomBytes)(16).toString('base64');
24
+ const req = (0, node_https_1.request)({
25
+ //discord gateway hostname
26
+ hostname: this.hostname,
27
+ path: this.path,
28
+ headers: {
29
+ Connection: 'Upgrade',
30
+ Upgrade: 'websocket',
31
+ 'Sec-WebSocket-Key': key,
32
+ 'Sec-WebSocket-Version': '13',
33
+ },
34
+ });
35
+ req.on('upgrade', (res, socket) => {
36
+ const hash = (0, node_crypto_1.createHash)('sha1').update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest('base64');
37
+ const accept = res.headers['sec-websocket-accept'];
38
+ if (accept !== hash) {
39
+ socket.end(() => {
40
+ rej(new Error('Invalid sec-websocket-accept header'));
41
+ });
42
+ return;
43
+ }
44
+ this.socket = socket;
45
+ socket.on('readable', this.handleReadable.bind(this));
46
+ socket.on('close', this.handleClose.bind(this));
47
+ socket.on('error', err => this.onerror(err));
48
+ resolve();
49
+ this.onopen();
50
+ });
51
+ req.on('close', () => {
52
+ req.removeAllListeners();
53
+ });
54
+ req.on('error', e => {
55
+ if (retries < 5) {
56
+ setTimeout(() => {
57
+ resolve(this.connect(retries + 1));
58
+ }, 500);
59
+ }
60
+ else {
61
+ rej(e);
62
+ }
63
+ });
64
+ req.end();
51
65
  });
52
- req.end();
53
66
  }
54
67
  handleReadable() {
55
68
  // Keep reading until no data, this is useful when two payloads merges.
@@ -66,9 +79,11 @@ class SeyfertWebSocket {
66
79
  // Equivalent to readUint32BE
67
80
  length = this.readBytes(2, slice - 2);
68
81
  }
82
+ const payloadLength = slice + length;
69
83
  // Read the frame, ignore data next to it, leave it to next `while` cycle
70
- const frame = this.socket.read(slice + length);
71
- if (!frame)
84
+ const frame = this.socket.read(payloadLength);
85
+ // unfinished object when socket closes while reading the data
86
+ if (!frame || frame.length !== payloadLength)
72
87
  return;
73
88
  // Get fin (0 | 1)
74
89
  const fin = frame[0] >> 7;
@@ -131,7 +146,7 @@ class SeyfertWebSocket {
131
146
  break;
132
147
  }
133
148
  }
134
- handleClose() {
149
+ async handleClose() {
135
150
  this.socket?.removeAllListeners();
136
151
  this.socket?.destroy();
137
152
  this.socket = undefined;
@@ -146,6 +161,8 @@ class SeyfertWebSocket {
146
161
  this._write(Buffer.from(data), 1);
147
162
  }
148
163
  _write(buffer, opcode) {
164
+ if (!this.socket?.writable)
165
+ return;
149
166
  const length = buffer.length;
150
167
  let frame;
151
168
  // Kinda same logic as above, but client-side
@@ -169,12 +186,24 @@ class SeyfertWebSocket {
169
186
  frame.set(buffer, frame.length - length);
170
187
  this.socket?.write(frame);
171
188
  }
172
- onping(_data) { }
173
- onpong(_data) { }
174
- onopen() { }
175
- onmessage(_payload) { }
176
- onclose(_close) { }
177
- onerror(_err) { }
189
+ onping(_data) {
190
+ //
191
+ }
192
+ onpong(_data) {
193
+ //
194
+ }
195
+ onopen() {
196
+ //
197
+ }
198
+ onmessage(_payload) {
199
+ //
200
+ }
201
+ onclose(_close) {
202
+ //
203
+ }
204
+ onerror(_err) {
205
+ //
206
+ }
178
207
  close(code, reason) {
179
208
  this.__closeCalled = true;
180
209
  // alloc payload length
@@ -186,6 +215,7 @@ class SeyfertWebSocket {
186
215
  // message, close opcode
187
216
  this._write(buffer, 0x8);
188
217
  this.socket?.end();
218
+ this.onclose({ code, reason });
189
219
  }
190
220
  pong(data) {
191
221
  //send pong opcode (10)
@@ -9,13 +9,16 @@ export interface WorkerShardInfo {
9
9
  export type WorkerInfo = {
10
10
  shards: WorkerShardInfo[];
11
11
  };
12
- type CreateWorkerMessage<T extends string, D extends object = {}> = {
12
+ type CreateWorkerMessage<T extends string, D extends object = object> = {
13
13
  type: T;
14
14
  workerId: number;
15
15
  } & D;
16
16
  export type WorkerRequestConnect = CreateWorkerMessage<'CONNECT_QUEUE', {
17
17
  shardId: number;
18
18
  }>;
19
+ export type WorkerRequestConnectResharding = CreateWorkerMessage<'CONNECT_QUEUE_RESHARDING', {
20
+ shardId: number;
21
+ }>;
19
22
  export type WorkerReceivePayload = CreateWorkerMessage<'RECEIVE_PAYLOAD', {
20
23
  shardId: number;
21
24
  payload: GatewayDispatchPayload;
@@ -35,7 +38,11 @@ export type WorkerSendInfo = CreateWorkerMessage<'WORKER_INFO', WorkerInfo & {
35
38
  nonce: string;
36
39
  }>;
37
40
  export type WorkerReady = CreateWorkerMessage<'WORKER_READY'>;
41
+ export type WorkerReadyResharding = CreateWorkerMessage<'WORKER_READY_RESHARDING'>;
42
+ export type WorkerShardsConnected = CreateWorkerMessage<'WORKER_SHARDS_CONNECTED'>;
38
43
  export type WorkerStart = CreateWorkerMessage<'WORKER_START'>;
44
+ export type WorkerStartResharding = CreateWorkerMessage<'WORKER_START_RESHARDING'>;
45
+ export type WorkerDisconnectedAllShardsResharding = CreateWorkerMessage<'DISCONNECTED_ALL_SHARDS_RESHARDING'>;
39
46
  export type WorkerSendApiRequest = CreateWorkerMessage<'WORKER_API_REQUEST', {
40
47
  method: HttpMethods;
41
48
  url: `/${string}`;
@@ -51,5 +58,5 @@ export type WorkerSendEval = CreateWorkerMessage<'EVAL', {
51
58
  nonce: string;
52
59
  toWorkerId: number;
53
60
  }>;
54
- export type WorkerMessage = WorkerRequestConnect | WorkerReceivePayload | WorkerSendResultPayload | WorkerSendCacheRequest | WorkerSendShardInfo | WorkerSendInfo | WorkerReady | WorkerSendApiRequest | WorkerSendEvalResponse | WorkerSendEval | WorkerStart;
61
+ export type WorkerMessage = WorkerRequestConnect | WorkerReceivePayload | WorkerSendResultPayload | WorkerSendCacheRequest | WorkerSendShardInfo | WorkerSendInfo | WorkerReady | WorkerShardsConnected | WorkerSendApiRequest | WorkerSendEvalResponse | WorkerSendEval | WorkerStart | WorkerStartResharding | WorkerRequestConnectResharding | WorkerReadyResharding | WorkerDisconnectedAllShardsResharding;
55
62
  export {};
@@ -1,26 +1,38 @@
1
- import type { GatewayPresenceUpdateData, GatewaySendPayload } from '../../types';
2
1
  import { type Worker as ClusterWorker } from 'node:cluster';
3
2
  import { ApiHandler, Logger } from '../..';
4
3
  import { type Adapter } from '../../cache';
5
4
  import { type MakePartial } from '../../common';
5
+ import type { GatewayPresenceUpdateData, GatewaySendPayload } from '../../types';
6
6
  import { ConnectQueue } from '../structures/timeout';
7
7
  import type { ShardOptions, WorkerData, WorkerManagerOptions } from './shared';
8
8
  import type { WorkerInfo, WorkerMessage, WorkerShardInfo } from './worker';
9
9
  export declare class WorkerManager extends Map<number, (ClusterWorker | import('node:worker_threads').Worker | {
10
- ready: boolean;
10
+ ready?: boolean;
11
11
  }) & {
12
12
  ready?: boolean;
13
+ disconnected?: boolean;
14
+ resharded?: boolean;
13
15
  }> {
16
+ static prepareSpaces(options: {
17
+ shardStart: number;
18
+ shardEnd: number;
19
+ shardsPerWorker: number;
20
+ }, logger?: Logger): number[][];
14
21
  options: MakePartial<Required<WorkerManagerOptions>, 'adapter'>;
15
22
  debugger?: Logger;
16
23
  connectQueue: ConnectQueue;
24
+ workerQueue: (() => void)[];
17
25
  cacheAdapter: Adapter;
18
26
  promises: Map<string, {
19
27
  resolve: (value: any) => void;
20
28
  timeout: NodeJS.Timeout;
21
29
  }>;
22
30
  rest: ApiHandler;
23
- constructor(options: MakePartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload'>);
31
+ reshardingWorkerQueue: (() => void)[];
32
+ private _info?;
33
+ constructor(options: Omit<MakePartial<WorkerManagerOptions, 'token' | 'intents' | 'info' | 'handlePayload'>, 'resharding'> & {
34
+ resharding?: MakePartial<NonNullable<WorkerManagerOptions['resharding']>, 'getInfo'>;
35
+ });
24
36
  setCache(adapter: Adapter): void;
25
37
  setRest(rest: ApiHandler): void;
26
38
  get remaining(): number;
@@ -30,20 +42,25 @@ export declare class WorkerManager extends Map<number, (ClusterWorker | import('
30
42
  get shardStart(): number;
31
43
  get shardEnd(): number;
32
44
  get shardsPerWorker(): number;
33
- get workers(): number;
34
- syncLatency({ shardId, workerId }: {
35
- shardId?: number;
45
+ syncLatency({ shardId, workerId, }: {
46
+ shardId: number;
36
47
  workerId?: number;
37
- }): Promise<number | undefined>;
48
+ } | {
49
+ shardId?: number;
50
+ workerId: number;
51
+ }): Promise<number>;
38
52
  calculateShardId(guildId: string): number;
39
53
  calculateWorkerId(shardId: number): number;
40
- prepareSpaces(): number[][];
41
- postMessage(id: number, body: any): void;
42
- prepareWorkers(shards: number[][]): Promise<void>;
43
- createWorker(workerData: WorkerData): ClusterWorker | import("worker_threads").Worker | {
44
- ready: boolean;
45
- };
46
- spawn(workerId: number, shardId: number): void;
54
+ postMessage(id: number, body: ManagerMessages): void;
55
+ prepareWorkers(shards: number[][], resharding?: boolean): Promise<void>;
56
+ createWorker(workerData: WorkerData): ClusterWorker | import("worker_threads").Worker | ({
57
+ ready?: boolean;
58
+ } & {
59
+ ready?: boolean;
60
+ disconnected?: boolean;
61
+ resharded?: boolean;
62
+ });
63
+ spawn(workerId: number, shardId: number, resharding?: boolean): void;
47
64
  handleWorkerMessage(message: WorkerMessage): Promise<void>;
48
65
  private generateNonce;
49
66
  private generateSendPromise;
@@ -51,15 +68,24 @@ export declare class WorkerManager extends Map<number, (ClusterWorker | import('
51
68
  getShardInfo(shardId: number): Promise<WorkerShardInfo>;
52
69
  getWorkerInfo(workerId: number): Promise<WorkerInfo>;
53
70
  start(): Promise<void>;
71
+ startResharding(): Promise<void>;
54
72
  }
55
- type CreateManagerMessage<T extends string, D extends object = {}> = {
73
+ type CreateManagerMessage<T extends string, D extends object = object> = {
56
74
  type: T;
57
75
  } & D;
58
76
  export type ManagerAllowConnect = CreateManagerMessage<'ALLOW_CONNECT', {
59
77
  shardId: number;
60
78
  presence: GatewayPresenceUpdateData;
61
79
  }>;
80
+ export type ManagerAllowConnectResharding = CreateManagerMessage<'ALLOW_CONNECT_RESHARDING', {
81
+ shardId: number;
82
+ presence: GatewayPresenceUpdateData;
83
+ }>;
84
+ export type ManagerWorkerAlreadyExistsResharding = CreateManagerMessage<'WORKER_ALREADY_EXISTS_RESHARDING'>;
62
85
  export type ManagerSpawnShards = CreateManagerMessage<'SPAWN_SHARDS', Pick<ShardOptions, 'info' | 'properties' | 'compress'>>;
86
+ export type ManagerSpawnShardsResharding = CreateManagerMessage<'SPAWN_SHARDS_RESHARDING', Pick<ShardOptions, 'info' | 'properties' | 'compress'>>;
87
+ export type DisconnectAllShardsResharding = CreateManagerMessage<'DISCONNECT_ALL_SHARDS_RESHARDING'>;
88
+ export type ConnnectAllShardsResharding = CreateManagerMessage<'CONNECT_ALL_SHARDS_RESHARDING'>;
63
89
  export type ManagerSendPayload = CreateManagerMessage<'SEND_PAYLOAD', GatewaySendPayload & {
64
90
  shardId: number;
65
91
  nonce: string;
@@ -90,5 +116,5 @@ export type ManagerSendEvalResponse = CreateManagerMessage<'EVAL_RESPONSE', {
90
116
  response: any;
91
117
  nonce: string;
92
118
  }>;
93
- export type ManagerMessages = ManagerAllowConnect | ManagerSpawnShards | ManagerSendPayload | ManagerRequestShardInfo | ManagerRequestWorkerInfo | ManagerSendCacheResult | ManagerSendBotReady | ManagerSendApiResponse | ManagerSendEvalResponse | ManagerExecuteEval;
119
+ export type ManagerMessages = ManagerAllowConnect | ManagerSpawnShards | ManagerSendPayload | ManagerRequestShardInfo | ManagerRequestWorkerInfo | ManagerSendCacheResult | ManagerSendBotReady | ManagerSendApiResponse | ManagerSendEvalResponse | ManagerExecuteEval | ManagerWorkerAlreadyExistsResharding | ManagerSpawnShardsResharding | ManagerAllowConnectResharding | DisconnectAllShardsResharding | ConnnectAllShardsResharding;
94
120
  export {};