@ovencord/discord.js 14.16.14 → 14.16.15-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -11
- package/src/client/Client.ts +102 -114
- package/src/client/actions/Action.ts +27 -23
- package/src/client/actions/ChannelCreate.ts +2 -2
- package/src/client/actions/ChannelDelete.ts +1 -1
- package/src/client/actions/ChannelUpdate.ts +2 -2
- package/src/client/actions/GuildChannelsPositionUpdate.ts +1 -1
- package/src/client/actions/GuildEmojiCreate.ts +1 -1
- package/src/client/actions/GuildEmojiDelete.ts +1 -1
- package/src/client/actions/GuildEmojiUpdate.ts +1 -1
- package/src/client/actions/GuildEmojisUpdate.ts +1 -1
- package/src/client/actions/GuildMemberRemove.ts +1 -1
- package/src/client/actions/GuildMemberUpdate.ts +1 -1
- package/src/client/actions/GuildRoleCreate.ts +1 -1
- package/src/client/actions/GuildRoleDelete.ts +1 -1
- package/src/client/actions/GuildRolesPositionUpdate.ts +1 -1
- package/src/client/actions/GuildScheduledEventDelete.ts +1 -1
- package/src/client/actions/GuildScheduledEventUserAdd.ts +1 -1
- package/src/client/actions/GuildScheduledEventUserRemove.ts +1 -1
- package/src/client/actions/GuildSoundboardSoundDelete.ts +1 -1
- package/src/client/actions/GuildStickerCreate.ts +1 -1
- package/src/client/actions/GuildStickerDelete.ts +1 -1
- package/src/client/actions/GuildStickerUpdate.ts +1 -1
- package/src/client/actions/GuildStickersUpdate.ts +1 -1
- package/src/client/actions/GuildUpdate.ts +1 -1
- package/src/client/actions/InteractionCreate.ts +1 -1
- package/src/client/actions/MessageCreate.ts +2 -2
- package/src/client/actions/MessageDelete.ts +2 -2
- package/src/client/actions/MessageDeleteBulk.ts +1 -1
- package/src/client/actions/MessagePollVoteAdd.ts +2 -2
- package/src/client/actions/MessagePollVoteRemove.ts +2 -2
- package/src/client/actions/MessageReactionAdd.ts +2 -2
- package/src/client/actions/MessageReactionRemove.ts +2 -2
- package/src/client/actions/MessageReactionRemoveAll.ts +1 -1
- package/src/client/actions/MessageReactionRemoveEmoji.ts +1 -1
- package/src/client/actions/MessageUpdate.ts +1 -1
- package/src/client/actions/StageInstanceCreate.ts +1 -1
- package/src/client/actions/StageInstanceDelete.ts +1 -1
- package/src/client/actions/StageInstanceUpdate.ts +1 -1
- package/src/client/actions/ThreadCreate.ts +1 -1
- package/src/client/actions/ThreadMembersUpdate.ts +1 -1
- package/src/client/actions/TypingStart.ts +1 -1
- package/src/client/actions/UserUpdate.ts +1 -1
- package/src/client/websocket/handlers/RATE_LIMITED.ts +1 -1
- package/src/managers/ApplicationEmojiManager.ts +11 -11
- package/src/managers/PresenceManager.ts +0 -1
- package/src/managers/UserManager.ts +0 -1
- package/src/sharding/Shard.ts +38 -37
- package/src/sharding/ShardClientUtil.ts +18 -19
- package/src/sharding/ShardingManager.ts +7 -7
- package/src/structures/AnonymousGuild.ts +0 -1
- package/src/structures/BaseGuild.ts +0 -1
- package/src/structures/Guild.ts +0 -1
- package/src/structures/interfaces/Collector.ts +1 -1
- package/src/util/AsyncEventEmitter.ts +150 -0
- package/src/util/Partials.ts +1 -1
- package/src/util/Status.ts +5 -15
package/src/sharding/Shard.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/* eslint-disable no-use-before-define */
|
|
2
2
|
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import process from 'node:process';
|
|
5
|
-
import { setTimeout, clearTimeout } from 'node:timers';
|
|
6
|
-
import { setTimeout as sleep } from 'node:timers/promises';
|
|
7
4
|
import { SHARE_ENV } from 'node:worker_threads';
|
|
8
|
-
import { AsyncEventEmitter } from '
|
|
5
|
+
import { AsyncEventEmitter } from '../util/AsyncEventEmitter.js';
|
|
9
6
|
import { DiscordjsError, ErrorCodes } from '../errors/index.js';
|
|
10
7
|
import { ShardEvents } from '../util/ShardEvents.js';
|
|
11
8
|
import { makeError, makePlainError } from '../util/Util.js';
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import type { ChildProcess } from 'node:child_process';
|
|
11
|
+
import type { Worker as WorkerThread } from 'node:worker_threads';
|
|
12
|
+
|
|
13
|
+
let childProcess: typeof import('node:child_process') | null = null;
|
|
14
|
+
let Worker: typeof WorkerThread | null = null;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* A self-contained shard created by the {@link ShardingManager}. Each one has a {@link ChildProcess} that contains
|
|
@@ -27,11 +27,13 @@ export class Shard extends AsyncEventEmitter {
|
|
|
27
27
|
public args: any;
|
|
28
28
|
public execArgv: any;
|
|
29
29
|
public env: any;
|
|
30
|
-
public worker:
|
|
30
|
+
public worker: WorkerThread | null = null;
|
|
31
|
+
public process: ChildProcess | null = null;
|
|
32
|
+
public ready: boolean = false;
|
|
31
33
|
public _evals: any;
|
|
32
34
|
public _fetches: any;
|
|
33
35
|
public _exitListener: any;
|
|
34
|
-
constructor(manager, id) {
|
|
36
|
+
constructor(manager: any, id: any) {
|
|
35
37
|
super();
|
|
36
38
|
|
|
37
39
|
switch (manager.mode) {
|
|
@@ -155,14 +157,13 @@ export class Shard extends AsyncEventEmitter {
|
|
|
155
157
|
|
|
156
158
|
switch (this.manager.mode) {
|
|
157
159
|
case 'process':
|
|
158
|
-
this.process = childProcess
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
.on('exit', this._exitListener);
|
|
160
|
+
this.process = childProcess.fork(path.resolve(this.manager.file), this.args, {
|
|
161
|
+
env: this.env,
|
|
162
|
+
execArgv: this.execArgv,
|
|
163
|
+
silent: this.silent,
|
|
164
|
+
});
|
|
165
|
+
(this.process as any).on('message', this._handleMessage.bind(this));
|
|
166
|
+
(this.process as any).on('exit', this._exitListener);
|
|
166
167
|
break;
|
|
167
168
|
case 'worker':
|
|
168
169
|
this.worker = new Worker(path.resolve(this.manager.file), {
|
|
@@ -170,9 +171,9 @@ export class Shard extends AsyncEventEmitter {
|
|
|
170
171
|
env: SHARE_ENV,
|
|
171
172
|
execArgv: this.execArgv,
|
|
172
173
|
argv: this.args,
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
});
|
|
175
|
+
(this.worker as any).on('message', this._handleMessage.bind(this));
|
|
176
|
+
(this.worker as any).on('exit', this._exitListener);
|
|
176
177
|
break;
|
|
177
178
|
default:
|
|
178
179
|
break;
|
|
@@ -232,11 +233,11 @@ export class Shard extends AsyncEventEmitter {
|
|
|
232
233
|
*/
|
|
233
234
|
kill() {
|
|
234
235
|
if (this.process) {
|
|
235
|
-
this.process.removeListener('exit', this._exitListener);
|
|
236
|
+
(this.process as any).removeListener('exit', this._exitListener);
|
|
236
237
|
this.process.kill();
|
|
237
238
|
} else {
|
|
238
|
-
this.worker.removeListener('exit', this._exitListener);
|
|
239
|
-
this.worker.terminate();
|
|
239
|
+
(this.worker as any).removeListener('exit', this._exitListener);
|
|
240
|
+
(this.worker as any).terminate();
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
this._handleExit(false);
|
|
@@ -260,7 +261,7 @@ export class Shard extends AsyncEventEmitter {
|
|
|
260
261
|
*/
|
|
261
262
|
async respawn({ delay = 500, timeout = 30_000 } = {}) {
|
|
262
263
|
this.kill();
|
|
263
|
-
if (delay > 0) await sleep(delay);
|
|
264
|
+
if (delay > 0) await Bun.sleep(delay);
|
|
264
265
|
return this.spawn(timeout);
|
|
265
266
|
}
|
|
266
267
|
|
|
@@ -270,15 +271,15 @@ export class Shard extends AsyncEventEmitter {
|
|
|
270
271
|
* @param {*} message Message to send to the shard
|
|
271
272
|
* @returns {Promise<Shard>}
|
|
272
273
|
*/
|
|
273
|
-
async send(message) {
|
|
274
|
+
async send(message: any): Promise<Shard> {
|
|
274
275
|
return new Promise((resolve, reject) => {
|
|
275
276
|
if (this.process) {
|
|
276
|
-
this.process.send(message, err => {
|
|
277
|
+
(this.process as any).send(message, (err: Error | null) => {
|
|
277
278
|
if (err) reject(err);
|
|
278
279
|
else resolve(this);
|
|
279
280
|
});
|
|
280
281
|
} else {
|
|
281
|
-
this.worker.postMessage(message);
|
|
282
|
+
(this.worker as any).postMessage(message);
|
|
282
283
|
resolve(this);
|
|
283
284
|
}
|
|
284
285
|
});
|
|
@@ -294,7 +295,7 @@ export class Shard extends AsyncEventEmitter {
|
|
|
294
295
|
* .then(count => console.log(`${count} guilds in shard ${shard.id}`))
|
|
295
296
|
* .catch(console.error);
|
|
296
297
|
*/
|
|
297
|
-
async fetchClientValue(prop) {
|
|
298
|
+
async fetchClientValue(prop: any): Promise<any> {
|
|
298
299
|
// Shard is dead (maybe respawning), don't cache anything and error immediately
|
|
299
300
|
if (!this.process && !this.worker) {
|
|
300
301
|
throw new DiscordjsError(ErrorCodes.ShardingNoChildExists, this.id);
|
|
@@ -306,9 +307,9 @@ export class Shard extends AsyncEventEmitter {
|
|
|
306
307
|
const promise = new Promise((resolve, reject) => {
|
|
307
308
|
const child = this.process ?? this.worker;
|
|
308
309
|
|
|
309
|
-
const listener = message => {
|
|
310
|
+
const listener = (message: any) => {
|
|
310
311
|
if (message?._fetchProp !== prop) return;
|
|
311
|
-
child.removeListener('message', listener);
|
|
312
|
+
(child as any).removeListener('message', listener);
|
|
312
313
|
this.decrementMaxListeners(child);
|
|
313
314
|
this._fetches.delete(prop);
|
|
314
315
|
if (message._error) reject(makeError(message._error));
|
|
@@ -316,10 +317,10 @@ export class Shard extends AsyncEventEmitter {
|
|
|
316
317
|
};
|
|
317
318
|
|
|
318
319
|
this.incrementMaxListeners(child);
|
|
319
|
-
child.on('message', listener);
|
|
320
|
+
(child as any).on('message', listener);
|
|
320
321
|
|
|
321
322
|
this.send({ _fetchProp: prop }).catch(error => {
|
|
322
|
-
child.removeListener('message', listener);
|
|
323
|
+
(child as any).removeListener('message', listener);
|
|
323
324
|
this.decrementMaxListeners(child);
|
|
324
325
|
this._fetches.delete(prop);
|
|
325
326
|
reject(error);
|
|
@@ -337,7 +338,7 @@ export class Shard extends AsyncEventEmitter {
|
|
|
337
338
|
* @param {*} [context] The context for the eval
|
|
338
339
|
* @returns {Promise<*>} Result of the script execution
|
|
339
340
|
*/
|
|
340
|
-
async eval(script, context) {
|
|
341
|
+
async eval(script: any, context?: any): Promise<any> {
|
|
341
342
|
// Stringify the script if it's a Function
|
|
342
343
|
const _eval = typeof script === 'function' ? `(${script})(this, ${JSON.stringify(context)})` : script;
|
|
343
344
|
|
|
@@ -352,9 +353,9 @@ export class Shard extends AsyncEventEmitter {
|
|
|
352
353
|
const promise = new Promise((resolve, reject) => {
|
|
353
354
|
const child = this.process ?? this.worker;
|
|
354
355
|
|
|
355
|
-
const listener = message => {
|
|
356
|
+
const listener = (message: any) => {
|
|
356
357
|
if (message?._eval !== _eval) return;
|
|
357
|
-
child.removeListener('message', listener);
|
|
358
|
+
(child as any).removeListener('message', listener);
|
|
358
359
|
this.decrementMaxListeners(child);
|
|
359
360
|
this._evals.delete(_eval);
|
|
360
361
|
if (message._error) reject(makeError(message._error));
|
|
@@ -362,10 +363,10 @@ export class Shard extends AsyncEventEmitter {
|
|
|
362
363
|
};
|
|
363
364
|
|
|
364
365
|
this.incrementMaxListeners(child);
|
|
365
|
-
child.on('message', listener);
|
|
366
|
+
(child as any).on('message', listener);
|
|
366
367
|
|
|
367
368
|
this.send({ _eval }).catch(error => {
|
|
368
|
-
child.removeListener('message', listener);
|
|
369
|
+
(child as any).removeListener('message', listener);
|
|
369
370
|
this.decrementMaxListeners(child);
|
|
370
371
|
this._evals.delete(_eval);
|
|
371
372
|
reject(error);
|
|
@@ -382,7 +383,7 @@ export class Shard extends AsyncEventEmitter {
|
|
|
382
383
|
* @param {*} message Message received
|
|
383
384
|
* @private
|
|
384
385
|
*/
|
|
385
|
-
_handleMessage(message) {
|
|
386
|
+
_handleMessage(message: any): void {
|
|
386
387
|
if (message) {
|
|
387
388
|
// Shard is ready
|
|
388
389
|
if (message._ready) {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
|
|
3
|
-
import process from 'node:process';
|
|
4
2
|
import { calculateShardId } from '@ovencord/util';
|
|
5
3
|
import { WebSocketShardEvents } from '@ovencord/ws';
|
|
6
4
|
import { DiscordjsError, DiscordjsTypeError, ErrorCodes } from '../errors/index.js';
|
|
@@ -15,8 +13,9 @@ export class ShardClientUtil {
|
|
|
15
13
|
public client: any;
|
|
16
14
|
public mode: any;
|
|
17
15
|
public parentPort: any;
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
private static _singleton: ShardClientUtil | null = null;
|
|
17
|
+
|
|
18
|
+
constructor(client: any, mode: any) {
|
|
20
19
|
/**
|
|
21
20
|
* Client for the shard
|
|
22
21
|
*
|
|
@@ -76,18 +75,18 @@ export class ShardClientUtil {
|
|
|
76
75
|
* @returns {Promise<void>}
|
|
77
76
|
* @emits Shard#message
|
|
78
77
|
*/
|
|
79
|
-
async send(message) {
|
|
78
|
+
async send(message: any): Promise<void> {
|
|
80
79
|
return new Promise((resolve, reject) => {
|
|
81
80
|
switch (this.mode) {
|
|
82
81
|
case 'process':
|
|
83
|
-
process.send(message, err => {
|
|
82
|
+
process.send!(message, (err: Error | null) => {
|
|
84
83
|
if (err) reject(err);
|
|
85
|
-
else resolve();
|
|
84
|
+
else resolve(undefined);
|
|
86
85
|
});
|
|
87
86
|
break;
|
|
88
87
|
case 'worker':
|
|
89
88
|
this.parentPort.postMessage(message);
|
|
90
|
-
resolve();
|
|
89
|
+
resolve(undefined);
|
|
91
90
|
break;
|
|
92
91
|
default:
|
|
93
92
|
break;
|
|
@@ -107,11 +106,11 @@ export class ShardClientUtil {
|
|
|
107
106
|
* .catch(console.error);
|
|
108
107
|
* @see {@link ShardingManager#fetchClientValues}
|
|
109
108
|
*/
|
|
110
|
-
async fetchClientValues(prop, shard) {
|
|
109
|
+
async fetchClientValues(prop: any, shard: any): Promise<any> {
|
|
111
110
|
return new Promise((resolve, reject) => {
|
|
112
111
|
const parent = this.parentPort ?? process;
|
|
113
112
|
|
|
114
|
-
const listener = message => {
|
|
113
|
+
const listener = (message: any) => {
|
|
115
114
|
if (message?._sFetchProp !== prop || message._sFetchPropShard !== shard) return;
|
|
116
115
|
parent.removeListener('message', listener);
|
|
117
116
|
this.decrementMaxListeners(parent);
|
|
@@ -142,7 +141,7 @@ export class ShardClientUtil {
|
|
|
142
141
|
* .catch(console.error);
|
|
143
142
|
* @see {@link ShardingManager#broadcastEval}
|
|
144
143
|
*/
|
|
145
|
-
async broadcastEval(script, options = {}) {
|
|
144
|
+
async broadcastEval(script: any, options: any = {}): Promise<any> {
|
|
146
145
|
return new Promise((resolve, reject) => {
|
|
147
146
|
const parent = this.parentPort ?? process;
|
|
148
147
|
if (typeof script !== 'function') {
|
|
@@ -152,7 +151,7 @@ export class ShardClientUtil {
|
|
|
152
151
|
|
|
153
152
|
const evalScript = `(${script})(this, ${JSON.stringify(options.context)})`;
|
|
154
153
|
|
|
155
|
-
const listener = message => {
|
|
154
|
+
const listener = (message: any) => {
|
|
156
155
|
if (message?._sEval !== evalScript || message._sEvalShard !== options.shard) return;
|
|
157
156
|
parent.removeListener('message', listener);
|
|
158
157
|
this.decrementMaxListeners(parent);
|
|
@@ -177,7 +176,7 @@ export class ShardClientUtil {
|
|
|
177
176
|
* @returns {Promise<void>} Resolves upon the message being sent
|
|
178
177
|
* @see {@link ShardingManager#respawnAll}
|
|
179
178
|
*/
|
|
180
|
-
async respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}) {
|
|
179
|
+
async respawnAll({ shardDelay = 5_000, respawnDelay = 500, timeout = 30_000 } = {}): Promise<void> {
|
|
181
180
|
return this.send({ _sRespawnAll: { shardDelay, respawnDelay, timeout } });
|
|
182
181
|
}
|
|
183
182
|
|
|
@@ -187,7 +186,7 @@ export class ShardClientUtil {
|
|
|
187
186
|
* @param {*} message Message received
|
|
188
187
|
* @private
|
|
189
188
|
*/
|
|
190
|
-
async _handleMessage(message) {
|
|
189
|
+
async _handleMessage(message: any): Promise<void> {
|
|
191
190
|
if (!message) return;
|
|
192
191
|
if (message._fetchProp) {
|
|
193
192
|
try {
|
|
@@ -214,7 +213,7 @@ export class ShardClientUtil {
|
|
|
214
213
|
* @param {*} message Message to send
|
|
215
214
|
* @private
|
|
216
215
|
*/
|
|
217
|
-
_respond(type, message) {
|
|
216
|
+
_respond(type: string, message: any): void {
|
|
218
217
|
this.send(message).catch(error_ => {
|
|
219
218
|
const error = new Error(`Error when sending ${type} response to master process: ${error_.message}`);
|
|
220
219
|
error.stack = error_.stack;
|
|
@@ -239,7 +238,7 @@ export class ShardClientUtil {
|
|
|
239
238
|
* @param {ShardingManagerMode} mode Mode the shard was spawned with
|
|
240
239
|
* @returns {ShardClientUtil}
|
|
241
240
|
*/
|
|
242
|
-
static singleton(client, mode) {
|
|
241
|
+
static singleton(client: any, mode: any): ShardClientUtil {
|
|
243
242
|
if (this._singleton) {
|
|
244
243
|
client.emit(
|
|
245
244
|
Events.Warn,
|
|
@@ -259,7 +258,7 @@ export class ShardClientUtil {
|
|
|
259
258
|
* @param {number} shardCount Number of shards
|
|
260
259
|
* @returns {number}
|
|
261
260
|
*/
|
|
262
|
-
static shardIdForGuildId(guildId, shardCount) {
|
|
261
|
+
static shardIdForGuildId(guildId: string, shardCount: number): number {
|
|
263
262
|
const shard = calculateShardId(guildId, shardCount);
|
|
264
263
|
if (shard < 0) throw new DiscordjsError(ErrorCodes.ShardingShardMiscalculation, shard, guildId, shardCount);
|
|
265
264
|
return shard;
|
|
@@ -271,7 +270,7 @@ export class ShardClientUtil {
|
|
|
271
270
|
* @param {Worker|ChildProcess} emitter The emitter that emits the events.
|
|
272
271
|
* @private
|
|
273
272
|
*/
|
|
274
|
-
incrementMaxListeners(emitter) {
|
|
273
|
+
incrementMaxListeners(emitter: any): void {
|
|
275
274
|
const maxListeners = emitter.getMaxListeners();
|
|
276
275
|
if (maxListeners !== 0) {
|
|
277
276
|
emitter.setMaxListeners(maxListeners + 1);
|
|
@@ -284,7 +283,7 @@ export class ShardClientUtil {
|
|
|
284
283
|
* @param {Worker|ChildProcess} emitter The emitter that emits the events.
|
|
285
284
|
* @private
|
|
286
285
|
*/
|
|
287
|
-
decrementMaxListeners(emitter) {
|
|
286
|
+
decrementMaxListeners(emitter: any): void {
|
|
288
287
|
const maxListeners = emitter.getMaxListeners();
|
|
289
288
|
if (maxListeners !== 0) {
|
|
290
289
|
emitter.setMaxListeners(maxListeners - 1);
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import process from 'node:process';
|
|
4
|
-
import { setTimeout as sleep } from 'node:timers/promises';
|
|
5
3
|
import { Collection } from '@ovencord/collection';
|
|
6
4
|
import { range } from '@ovencord/util';
|
|
7
|
-
import { AsyncEventEmitter } from '
|
|
5
|
+
import { AsyncEventEmitter } from '../util/AsyncEventEmitter.js';
|
|
8
6
|
import { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } from '../errors/index.js';
|
|
9
7
|
import { fetchRecommendedShardCount } from '../util/Util.js';
|
|
10
8
|
import { Shard } from './Shard.js';
|
|
@@ -24,10 +22,12 @@ export class ShardingManager extends AsyncEventEmitter {
|
|
|
24
22
|
public shardList: any;
|
|
25
23
|
public totalShards: any;
|
|
26
24
|
public mode: any;
|
|
25
|
+
public respawn: boolean;
|
|
27
26
|
public silent: any;
|
|
28
27
|
public shardArgs: any;
|
|
29
28
|
public execArgv: any;
|
|
30
29
|
public token: any;
|
|
30
|
+
public shards: any;
|
|
31
31
|
/**
|
|
32
32
|
* The mode to spawn shards with for a {@link ShardingManager}. Can be either one of:
|
|
33
33
|
* - 'process' to use child processes
|
|
@@ -55,7 +55,7 @@ export class ShardingManager extends AsyncEventEmitter {
|
|
|
55
55
|
* @param {string} file Path to your shard script file
|
|
56
56
|
* @param {ShardingManagerOptions} [options] Options for the sharding manager
|
|
57
57
|
*/
|
|
58
|
-
constructor(file, options) {
|
|
58
|
+
constructor(file: any, options?: any) {
|
|
59
59
|
super();
|
|
60
60
|
const _options = {
|
|
61
61
|
totalShards: 'auto',
|
|
@@ -261,7 +261,7 @@ export class ShardingManager extends AsyncEventEmitter {
|
|
|
261
261
|
const promises = [];
|
|
262
262
|
const shard = this.createShard(shardId);
|
|
263
263
|
promises.push(shard.spawn(timeout));
|
|
264
|
-
if (delay > 0 && this.shards.size !== this.shardList.length) promises.push(sleep(delay));
|
|
264
|
+
if (delay > 0 && this.shards.size !== this.shardList.length) promises.push(Bun.sleep(delay));
|
|
265
265
|
await Promise.all(promises);
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -295,7 +295,7 @@ export class ShardingManager extends AsyncEventEmitter {
|
|
|
295
295
|
* @param {BroadcastEvalOptions} [options={}] The options for the broadcast
|
|
296
296
|
* @returns {Promise<*|Array<*>>} Results of the script execution
|
|
297
297
|
*/
|
|
298
|
-
async broadcastEval(script, options = {}) {
|
|
298
|
+
async broadcastEval(script: any, options: any = {}): Promise<any> {
|
|
299
299
|
if (typeof script !== 'function') {
|
|
300
300
|
throw new DiscordjsTypeError(ErrorCodes.ShardingInvalidEvalBroadcast);
|
|
301
301
|
}
|
|
@@ -365,7 +365,7 @@ export class ShardingManager extends AsyncEventEmitter {
|
|
|
365
365
|
let shardCounter = 0;
|
|
366
366
|
for (const shard of this.shards.values()) {
|
|
367
367
|
const promises = [shard.respawn({ delay: respawnDelay, timeout })];
|
|
368
|
-
if (++shardCounter < this.shards.size && shardDelay > 0) promises.push(sleep(shardDelay));
|
|
368
|
+
if (++shardCounter < this.shards.size && shardDelay > 0) promises.push(Bun.sleep(shardDelay));
|
|
369
369
|
await Promise.all(promises);
|
|
370
370
|
}
|
|
371
371
|
|
package/src/structures/Guild.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setTimeout, clearTimeout } from 'node:timers';
|
|
2
2
|
import { Collection } from '@ovencord/collection';
|
|
3
|
-
import { AsyncEventEmitter } from '
|
|
3
|
+
import { AsyncEventEmitter } from '../../util/AsyncEventEmitter.js';
|
|
4
4
|
import { DiscordjsTypeError, ErrorCodes } from '../../errors/index.js';
|
|
5
5
|
import { flatten } from '../../util/Util.js';
|
|
6
6
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export type EventMap = Record<string | symbol, any[]>;
|
|
2
|
+
|
|
3
|
+
export class AsyncEventEmitter<Events extends EventMap = EventMap> {
|
|
4
|
+
private _listeners = new Map<keyof Events | string | symbol, Set<Function>>();
|
|
5
|
+
private _maxListeners = 10;
|
|
6
|
+
|
|
7
|
+
public on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => void | Promise<void>): this;
|
|
8
|
+
public on<K extends string | symbol>(event: K, listener: (...args: any[]) => void | Promise<void>): this;
|
|
9
|
+
public on(event: string | symbol, listener: Function): this {
|
|
10
|
+
if (!this._listeners.has(event)) {
|
|
11
|
+
this._listeners.set(event, new Set());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const listeners = this._listeners.get(event)!;
|
|
15
|
+
listeners.add(listener);
|
|
16
|
+
|
|
17
|
+
if (listeners.size > this._maxListeners) {
|
|
18
|
+
console.warn(
|
|
19
|
+
`Possible AsyncEventEmitter memory leak detected. ` +
|
|
20
|
+
`${listeners.size} ${String(event)} listeners added. ` +
|
|
21
|
+
`Use emitter.setMaxListeners() to increase limit`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => void | Promise<void>): this;
|
|
29
|
+
public once<K extends string | symbol>(event: K, listener: (...args: any[]) => void | Promise<void>): this;
|
|
30
|
+
public once(event: string | symbol, listener: Function): this {
|
|
31
|
+
const wrapper = async (...args: any[]) => {
|
|
32
|
+
this.off(event, wrapper);
|
|
33
|
+
await listener(...args);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Object.defineProperty(wrapper, '_originalListener', {
|
|
37
|
+
value: listener,
|
|
38
|
+
writable: false,
|
|
39
|
+
enumerable: false,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return this.on(event, wrapper);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public off<K extends keyof Events>(event: K, listener: (...args: Events[K]) => void | Promise<void>): this;
|
|
46
|
+
public off<K extends string | symbol>(event: K, listener: (...args: any[]) => void | Promise<void>): this;
|
|
47
|
+
public off(event: string | symbol, listener: Function): this {
|
|
48
|
+
const listeners = this._listeners.get(event);
|
|
49
|
+
if (!listeners) return this;
|
|
50
|
+
|
|
51
|
+
for (const fn of listeners) {
|
|
52
|
+
if (fn === listener || (fn as any)._originalListener === listener) {
|
|
53
|
+
listeners.delete(fn);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (listeners.size === 0) {
|
|
58
|
+
this._listeners.delete(event);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public async emit<K extends keyof Events>(event: K, ...args: Events[K]): Promise<boolean>;
|
|
65
|
+
public async emit<K extends string | symbol>(event: K, ...args: any[]): Promise<boolean>;
|
|
66
|
+
public async emit(event: string | symbol, ...args: any[]): Promise<boolean> {
|
|
67
|
+
const listeners = this._listeners.get(event);
|
|
68
|
+
if (!listeners?.size) return false;
|
|
69
|
+
|
|
70
|
+
// We copy the listeners to ensure that if a listener is removed during execution,
|
|
71
|
+
// the loop still iterates over the snapshot of listeners at the time of emission.
|
|
72
|
+
// However, for strict sequential execution where one might remove another,
|
|
73
|
+
// iterating over the live Set or a copy is a design choice.
|
|
74
|
+
// Discord.js usually handles this by copying or iterating safe.
|
|
75
|
+
// The user's snippet iterates directly over the listeners collection from .get().
|
|
76
|
+
// If we use 'for of' on a Set, it handles deletions gracefully (the deleted item won't be visited if not reached yet),
|
|
77
|
+
// but additions might be visited.
|
|
78
|
+
// For now, adhering to user's "for (const listener of listeners)" pattern.
|
|
79
|
+
|
|
80
|
+
// NOTE: Iterating over the Set directly allows listeners to remove themselves safely.
|
|
81
|
+
for (const listener of listeners) {
|
|
82
|
+
try {
|
|
83
|
+
await listener(...args);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (event === 'error') {
|
|
86
|
+
console.error('Error in error handler:', error);
|
|
87
|
+
} else if (this.listenerCount('error') > 0) {
|
|
88
|
+
await this.emit('error', error);
|
|
89
|
+
} else {
|
|
90
|
+
console.error(`Unhandled error in ${String(event)} event:`, error);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public removeAllListeners(event?: keyof Events | string | symbol): this {
|
|
100
|
+
if (event !== undefined) {
|
|
101
|
+
this._listeners.delete(event);
|
|
102
|
+
} else {
|
|
103
|
+
this._listeners.clear();
|
|
104
|
+
}
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public setMaxListeners(n: number): this {
|
|
109
|
+
this._maxListeners = n;
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public getMaxListeners(): number {
|
|
114
|
+
return this._maxListeners;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public listenerCount(event: keyof Events | string | symbol): number {
|
|
118
|
+
return this._listeners.get(event)?.size ?? 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public eventNames(): Array<keyof Events | string | symbol> {
|
|
122
|
+
return Array.from(this._listeners.keys());
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public rawListeners(event: keyof Events | string | symbol): Function[] {
|
|
126
|
+
return Array.from(this._listeners.get(event) ?? []);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public waitFor<K extends keyof Events>(event: K, timeout?: number): Promise<Events[K]>;
|
|
130
|
+
public waitFor<K extends string | symbol>(event: K, timeout?: number): Promise<any[]>;
|
|
131
|
+
public waitFor(event: string | symbol, timeout?: number): Promise<any[]> {
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
let timeoutId: Timer | undefined;
|
|
134
|
+
|
|
135
|
+
const listener = (...args: any[]) => {
|
|
136
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
137
|
+
resolve(args);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
this.once(event, listener);
|
|
141
|
+
|
|
142
|
+
if (timeout) {
|
|
143
|
+
timeoutId = setTimeout(() => {
|
|
144
|
+
this.off(event, listener);
|
|
145
|
+
reject(new Error(`Timeout waiting for ${String(event)}`));
|
|
146
|
+
}, timeout);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
package/src/util/Partials.ts
CHANGED
package/src/util/Status.ts
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @property {number} Idle idle
|
|
8
|
-
* @property {number} WaitingForGuilds waiting for guilds
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// JSDoc for IntelliSense purposes
|
|
12
|
-
/**
|
|
13
|
-
* @type {Status}
|
|
14
|
-
* @ignore
|
|
15
|
-
*/
|
|
16
|
-
export const Status = createEnum(['Ready', 'Idle', 'WaitingForGuilds']);
|
|
2
|
+
export enum Status {
|
|
3
|
+
Ready,
|
|
4
|
+
Idle,
|
|
5
|
+
WaitingForGuilds,
|
|
6
|
+
}
|