@bakit/gateway 3.0.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +24 -9
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +22 -8
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,8 @@ var child_process = require('child_process');
|
|
|
10
10
|
var path = require('path');
|
|
11
11
|
var url = require('url');
|
|
12
12
|
var utils = require('@bakit/utils');
|
|
13
|
+
var collection = require('@discordjs/collection');
|
|
14
|
+
var PQueue = require('p-queue');
|
|
13
15
|
var rest = require('@bakit/rest');
|
|
14
16
|
|
|
15
17
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -17,6 +19,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
17
19
|
|
|
18
20
|
var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
|
|
19
21
|
var WebSocket__default = /*#__PURE__*/_interopDefault(WebSocket);
|
|
22
|
+
var PQueue__default = /*#__PURE__*/_interopDefault(PQueue);
|
|
20
23
|
|
|
21
24
|
// src/lib/Shard.ts
|
|
22
25
|
var MIN_HEARTBEAT_INTERVAL = 1e3, MAX_HEARTBEAT_INTERVAL = 6e4, SAFE_HEARTBEAT_INTERVAL = 45e3, ShardState = /* @__PURE__ */ ((ShardState2) => (ShardState2[ShardState2.Idle = 0] = "Idle", ShardState2[ShardState2.Connecting = 1] = "Connecting", ShardState2[ShardState2.Ready = 2] = "Ready", ShardState2[ShardState2.Resuming = 3] = "Resuming", ShardState2[ShardState2.Disconnecting = 4] = "Disconnecting", ShardState2[ShardState2.Disconnected = 5] = "Disconnected", ShardState2))(ShardState || {}), ShardStrategy = /* @__PURE__ */ ((ShardStrategy2) => (ShardStrategy2[ShardStrategy2.Resume = 0] = "Resume", ShardStrategy2[ShardStrategy2.Reconnect = 1] = "Reconnect", ShardStrategy2[ShardStrategy2.Shutdown = 2] = "Shutdown", ShardStrategy2))(ShardStrategy || {}), Shard = class extends EventEmitter__default.default {
|
|
@@ -283,6 +286,10 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter__default.default
|
|
|
283
286
|
}
|
|
284
287
|
process;
|
|
285
288
|
#pendingEvals = /* @__PURE__ */ new Map();
|
|
289
|
+
#shards = /* @__PURE__ */ new Set();
|
|
290
|
+
get shards() {
|
|
291
|
+
return new Set(this.#shards);
|
|
292
|
+
}
|
|
286
293
|
get killed() {
|
|
287
294
|
return this.process.killed || !this.process.connected;
|
|
288
295
|
}
|
|
@@ -351,7 +358,7 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter__default.default
|
|
|
351
358
|
#handleIPC(message) {
|
|
352
359
|
if (this.#isValidPayload(message)) {
|
|
353
360
|
if (isDispatchPayload(message)) {
|
|
354
|
-
this
|
|
361
|
+
this.#handleDispatchPayload(message);
|
|
355
362
|
return;
|
|
356
363
|
}
|
|
357
364
|
if (isEvalResponsePayload(message)) {
|
|
@@ -360,6 +367,9 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter__default.default
|
|
|
360
367
|
}
|
|
361
368
|
}
|
|
362
369
|
}
|
|
370
|
+
#handleDispatchPayload(payload) {
|
|
371
|
+
payload.t === "shardAdd" && this.#shards.add(payload.d[0]), this.emit(payload.t, ...payload.d);
|
|
372
|
+
}
|
|
363
373
|
#handleEvalResponse(payload) {
|
|
364
374
|
let pending = this.#pendingEvals.get(payload.d.nonce);
|
|
365
375
|
if (!pending) {
|
|
@@ -452,7 +462,7 @@ var Cluster = class extends EventEmitter__default.default {
|
|
|
452
462
|
this.id = id;
|
|
453
463
|
this.options = options;
|
|
454
464
|
}
|
|
455
|
-
shards = new
|
|
465
|
+
shards = new collection.Collection();
|
|
456
466
|
#readyCount = 0;
|
|
457
467
|
#starting = false;
|
|
458
468
|
get size() {
|
|
@@ -515,7 +525,7 @@ var Cluster = class extends EventEmitter__default.default {
|
|
|
515
525
|
}
|
|
516
526
|
};
|
|
517
527
|
var ShardingManager = class extends EventEmitter__default.default {
|
|
518
|
-
clusters = new
|
|
528
|
+
clusters = new collection.Collection();
|
|
519
529
|
options;
|
|
520
530
|
rest;
|
|
521
531
|
#gatewayInfo;
|
|
@@ -537,22 +547,21 @@ var ShardingManager = class extends EventEmitter__default.default {
|
|
|
537
547
|
return this.#totalShards;
|
|
538
548
|
}
|
|
539
549
|
get ready() {
|
|
540
|
-
return this.#readyCount === this.totalClusters;
|
|
550
|
+
return this.totalClusters > 0 && this.#readyCount === this.totalClusters;
|
|
541
551
|
}
|
|
542
552
|
async spawn() {
|
|
543
553
|
this.#gatewayInfo = await this.rest.get("/gateway/bot");
|
|
544
554
|
let { session_start_limit: limit } = this.#gatewayInfo;
|
|
545
|
-
this.#totalShards = typeof this.options.totalShards == "number" ? this.options.totalShards : this.#gatewayInfo.shards, this.#identifyQueue = new
|
|
555
|
+
this.#totalShards = typeof this.options.totalShards == "number" ? this.options.totalShards : this.#gatewayInfo.shards, this.#identifyQueue = new PQueue__default.default({
|
|
546
556
|
concurrency: limit.max_concurrency,
|
|
547
557
|
intervalCap: limit.max_concurrency,
|
|
548
558
|
interval: 5e3
|
|
549
559
|
});
|
|
550
560
|
let { totalShards, totalClusters } = this;
|
|
551
561
|
this.emit("debug", `Spawning ${totalClusters} clusters (${totalShards} total shards)...`);
|
|
552
|
-
let promises = [];
|
|
553
562
|
for (let i = 0; i < totalClusters; i++)
|
|
554
|
-
|
|
555
|
-
|
|
563
|
+
this.#spawnCluster(i);
|
|
564
|
+
this.emit("debug", "All clusters spawned");
|
|
556
565
|
}
|
|
557
566
|
async kill(signal = "SIGTERM") {
|
|
558
567
|
this.emit("debug", "Shutting down all clusters...");
|
|
@@ -573,6 +582,12 @@ var ShardingManager = class extends EventEmitter__default.default {
|
|
|
573
582
|
let promises = this.clusters.map((cluster) => cluster.eval(fn));
|
|
574
583
|
return Promise.all(promises);
|
|
575
584
|
}
|
|
585
|
+
send(shardId, payload) {
|
|
586
|
+
let cluster = this.clusters.find((cluster2) => cluster2.shards.has(shardId));
|
|
587
|
+
if (!cluster)
|
|
588
|
+
throw new Error(`Shard ${shardId} not found`);
|
|
589
|
+
cluster.send(payload);
|
|
590
|
+
}
|
|
576
591
|
requestIdentify(cluster, shardId) {
|
|
577
592
|
this.#identifyQueue?.add(() => cluster.identifyShard(shardId));
|
|
578
593
|
}
|
|
@@ -580,7 +595,7 @@ var ShardingManager = class extends EventEmitter__default.default {
|
|
|
580
595
|
let start = clusterId * this.options.shardsPerCluster, end = Math.min(start + this.options.shardsPerCluster, this.totalShards);
|
|
581
596
|
return Array.from({ length: end - start }, (_, i) => start + i);
|
|
582
597
|
}
|
|
583
|
-
|
|
598
|
+
#spawnCluster(id) {
|
|
584
599
|
let shardIds = this.#getShardIdsForCluster(id), firstShardId = shardIds[0], lastShardId = shardIds[shardIds.length - 1];
|
|
585
600
|
this.emit("debug", `Spawning cluster ${id} (shards ${firstShardId}-${lastShardId})`);
|
|
586
601
|
let env = {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import EventEmitter from 'node:events';
|
|
2
2
|
import { GatewayReadyDispatchData, GatewayReceivePayload, GatewayDispatchPayload, GatewaySendPayload } from 'discord-api-types/v10';
|
|
3
3
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
-
import { Collection } from '@
|
|
5
|
-
import {
|
|
4
|
+
import { Collection } from '@discordjs/collection';
|
|
5
|
+
import { RESTLike } from '@bakit/rest';
|
|
6
6
|
|
|
7
7
|
declare enum ShardState {
|
|
8
8
|
Idle = 0,
|
|
@@ -115,8 +115,8 @@ declare class ShardingManager extends EventEmitter<ShardingManagerEvents> {
|
|
|
115
115
|
#private;
|
|
116
116
|
readonly clusters: Collection<number, ClusterProcess>;
|
|
117
117
|
readonly options: Required<ShardingManagerOptions>;
|
|
118
|
-
readonly rest:
|
|
119
|
-
constructor(options: ShardingManagerOptions, rest?:
|
|
118
|
+
readonly rest: RESTLike;
|
|
119
|
+
constructor(options: ShardingManagerOptions, rest?: RESTLike);
|
|
120
120
|
get totalClusters(): number;
|
|
121
121
|
get totalShards(): number;
|
|
122
122
|
get ready(): boolean;
|
|
@@ -124,6 +124,7 @@ declare class ShardingManager extends EventEmitter<ShardingManagerEvents> {
|
|
|
124
124
|
kill(signal?: NodeJS.Signals): Promise<void>;
|
|
125
125
|
broadcast(payload: GatewaySendPayload): void;
|
|
126
126
|
broadcastEval<T>(fn: (cluster: Cluster) => T | Promise<T>): Promise<EvalResult<T>[]>;
|
|
127
|
+
send(shardId: number, payload: GatewaySendPayload): void;
|
|
127
128
|
protected requestIdentify(cluster: ClusterProcess, shardId: number): void;
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -188,6 +189,7 @@ declare class ClusterProcess extends EventEmitter<ClusterEvents> {
|
|
|
188
189
|
readonly id: number;
|
|
189
190
|
readonly process: ChildProcess;
|
|
190
191
|
constructor(manager: ShardingManager, id: number, options?: ClusterProcessOptions);
|
|
192
|
+
get shards(): Set<number>;
|
|
191
193
|
get killed(): boolean;
|
|
192
194
|
kill(signal?: NodeJS.Signals): void;
|
|
193
195
|
eval<T, C = unknown>(fn: (cluster: Cluster, ctx: C) => T | Promise<T>, ctx?: C): Promise<EvalResult<T>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import EventEmitter from 'node:events';
|
|
2
2
|
import { GatewayReadyDispatchData, GatewayReceivePayload, GatewayDispatchPayload, GatewaySendPayload } from 'discord-api-types/v10';
|
|
3
3
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
-
import { Collection } from '@
|
|
5
|
-
import {
|
|
4
|
+
import { Collection } from '@discordjs/collection';
|
|
5
|
+
import { RESTLike } from '@bakit/rest';
|
|
6
6
|
|
|
7
7
|
declare enum ShardState {
|
|
8
8
|
Idle = 0,
|
|
@@ -115,8 +115,8 @@ declare class ShardingManager extends EventEmitter<ShardingManagerEvents> {
|
|
|
115
115
|
#private;
|
|
116
116
|
readonly clusters: Collection<number, ClusterProcess>;
|
|
117
117
|
readonly options: Required<ShardingManagerOptions>;
|
|
118
|
-
readonly rest:
|
|
119
|
-
constructor(options: ShardingManagerOptions, rest?:
|
|
118
|
+
readonly rest: RESTLike;
|
|
119
|
+
constructor(options: ShardingManagerOptions, rest?: RESTLike);
|
|
120
120
|
get totalClusters(): number;
|
|
121
121
|
get totalShards(): number;
|
|
122
122
|
get ready(): boolean;
|
|
@@ -124,6 +124,7 @@ declare class ShardingManager extends EventEmitter<ShardingManagerEvents> {
|
|
|
124
124
|
kill(signal?: NodeJS.Signals): Promise<void>;
|
|
125
125
|
broadcast(payload: GatewaySendPayload): void;
|
|
126
126
|
broadcastEval<T>(fn: (cluster: Cluster) => T | Promise<T>): Promise<EvalResult<T>[]>;
|
|
127
|
+
send(shardId: number, payload: GatewaySendPayload): void;
|
|
127
128
|
protected requestIdentify(cluster: ClusterProcess, shardId: number): void;
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -188,6 +189,7 @@ declare class ClusterProcess extends EventEmitter<ClusterEvents> {
|
|
|
188
189
|
readonly id: number;
|
|
189
190
|
readonly process: ChildProcess;
|
|
190
191
|
constructor(manager: ShardingManager, id: number, options?: ClusterProcessOptions);
|
|
192
|
+
get shards(): Set<number>;
|
|
191
193
|
get killed(): boolean;
|
|
192
194
|
kill(signal?: NodeJS.Signals): void;
|
|
193
195
|
eval<T, C = unknown>(fn: (cluster: Cluster, ctx: C) => T | Promise<T>, ctx?: C): Promise<EvalResult<T>>;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,9 @@ import { GatewayOpcodes, GatewayDispatchEvents, GatewayCloseCodes } from 'discor
|
|
|
7
7
|
import { fork } from 'child_process';
|
|
8
8
|
import { dirname, resolve } from 'path';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
|
-
import { isCommonJS
|
|
10
|
+
import { isCommonJS } from '@bakit/utils';
|
|
11
|
+
import { Collection } from '@discordjs/collection';
|
|
12
|
+
import PQueue from 'p-queue';
|
|
11
13
|
import { REST } from '@bakit/rest';
|
|
12
14
|
|
|
13
15
|
// src/lib/Shard.ts
|
|
@@ -275,6 +277,10 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter {
|
|
|
275
277
|
}
|
|
276
278
|
process;
|
|
277
279
|
#pendingEvals = /* @__PURE__ */ new Map();
|
|
280
|
+
#shards = /* @__PURE__ */ new Set();
|
|
281
|
+
get shards() {
|
|
282
|
+
return new Set(this.#shards);
|
|
283
|
+
}
|
|
278
284
|
get killed() {
|
|
279
285
|
return this.process.killed || !this.process.connected;
|
|
280
286
|
}
|
|
@@ -343,7 +349,7 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter {
|
|
|
343
349
|
#handleIPC(message) {
|
|
344
350
|
if (this.#isValidPayload(message)) {
|
|
345
351
|
if (isDispatchPayload(message)) {
|
|
346
|
-
this
|
|
352
|
+
this.#handleDispatchPayload(message);
|
|
347
353
|
return;
|
|
348
354
|
}
|
|
349
355
|
if (isEvalResponsePayload(message)) {
|
|
@@ -352,6 +358,9 @@ var ClusterProcess = class _ClusterProcess extends EventEmitter {
|
|
|
352
358
|
}
|
|
353
359
|
}
|
|
354
360
|
}
|
|
361
|
+
#handleDispatchPayload(payload) {
|
|
362
|
+
payload.t === "shardAdd" && this.#shards.add(payload.d[0]), this.emit(payload.t, ...payload.d);
|
|
363
|
+
}
|
|
355
364
|
#handleEvalResponse(payload) {
|
|
356
365
|
let pending = this.#pendingEvals.get(payload.d.nonce);
|
|
357
366
|
if (!pending) {
|
|
@@ -529,22 +538,21 @@ var ShardingManager = class extends EventEmitter {
|
|
|
529
538
|
return this.#totalShards;
|
|
530
539
|
}
|
|
531
540
|
get ready() {
|
|
532
|
-
return this.#readyCount === this.totalClusters;
|
|
541
|
+
return this.totalClusters > 0 && this.#readyCount === this.totalClusters;
|
|
533
542
|
}
|
|
534
543
|
async spawn() {
|
|
535
544
|
this.#gatewayInfo = await this.rest.get("/gateway/bot");
|
|
536
545
|
let { session_start_limit: limit } = this.#gatewayInfo;
|
|
537
|
-
this.#totalShards = typeof this.options.totalShards == "number" ? this.options.totalShards : this.#gatewayInfo.shards, this.#identifyQueue = new
|
|
546
|
+
this.#totalShards = typeof this.options.totalShards == "number" ? this.options.totalShards : this.#gatewayInfo.shards, this.#identifyQueue = new PQueue({
|
|
538
547
|
concurrency: limit.max_concurrency,
|
|
539
548
|
intervalCap: limit.max_concurrency,
|
|
540
549
|
interval: 5e3
|
|
541
550
|
});
|
|
542
551
|
let { totalShards, totalClusters } = this;
|
|
543
552
|
this.emit("debug", `Spawning ${totalClusters} clusters (${totalShards} total shards)...`);
|
|
544
|
-
let promises = [];
|
|
545
553
|
for (let i = 0; i < totalClusters; i++)
|
|
546
|
-
|
|
547
|
-
|
|
554
|
+
this.#spawnCluster(i);
|
|
555
|
+
this.emit("debug", "All clusters spawned");
|
|
548
556
|
}
|
|
549
557
|
async kill(signal = "SIGTERM") {
|
|
550
558
|
this.emit("debug", "Shutting down all clusters...");
|
|
@@ -565,6 +573,12 @@ var ShardingManager = class extends EventEmitter {
|
|
|
565
573
|
let promises = this.clusters.map((cluster) => cluster.eval(fn));
|
|
566
574
|
return Promise.all(promises);
|
|
567
575
|
}
|
|
576
|
+
send(shardId, payload) {
|
|
577
|
+
let cluster = this.clusters.find((cluster2) => cluster2.shards.has(shardId));
|
|
578
|
+
if (!cluster)
|
|
579
|
+
throw new Error(`Shard ${shardId} not found`);
|
|
580
|
+
cluster.send(payload);
|
|
581
|
+
}
|
|
568
582
|
requestIdentify(cluster, shardId) {
|
|
569
583
|
this.#identifyQueue?.add(() => cluster.identifyShard(shardId));
|
|
570
584
|
}
|
|
@@ -572,7 +586,7 @@ var ShardingManager = class extends EventEmitter {
|
|
|
572
586
|
let start = clusterId * this.options.shardsPerCluster, end = Math.min(start + this.options.shardsPerCluster, this.totalShards);
|
|
573
587
|
return Array.from({ length: end - start }, (_, i) => start + i);
|
|
574
588
|
}
|
|
575
|
-
|
|
589
|
+
#spawnCluster(id) {
|
|
576
590
|
let shardIds = this.#getShardIdsForCluster(id), firstShardId = shardIds[0], lastShardId = shardIds[shardIds.length - 1];
|
|
577
591
|
this.emit("debug", `Spawning cluster ${id} (shards ${firstShardId}-${lastShardId})`);
|
|
578
592
|
let env = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bakit/gateway",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "Gateway manager for bakit framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -34,11 +34,13 @@
|
|
|
34
34
|
"author": "louiszn",
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@discordjs/collection": "^2.1.1",
|
|
37
38
|
"discord-api-types": "^0.38.38",
|
|
39
|
+
"p-queue": "^9.1.0",
|
|
38
40
|
"type-fest": "^4.41.0",
|
|
39
41
|
"ws": "^8.19.0",
|
|
40
|
-
"@bakit/rest": "^3.0.
|
|
41
|
-
"@bakit/utils": "^
|
|
42
|
+
"@bakit/rest": "^3.0.2",
|
|
43
|
+
"@bakit/utils": "^3.0.0"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@types/ws": "^8.18.1"
|