/
shardManager.ts
122 lines (106 loc) · 4.09 KB
/
shardManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { DiscordGatewayPayload } from "../../types/discord.ts";
import { PickPartial } from "../../types/shared.ts";
import { Collection } from "../../util/collection.ts";
import { CreateShard, createShard } from "../shard/createShard.ts";
import { Shard, ShardGatewayConfig } from "../shard/types.ts";
// TODO: debug
/** This is a Shard manager.
* This does not manage a specific range of Shard but the provided Shards on create or when an identify is requested.
* The aim of this is to provide an easy to use manager which can be used by workers or any other kind of separate process.
*/
export type ShardManager = ReturnType<typeof createShardManager>;
/** Create a new Shard manager.
* This does not manage a specific range of Shard but the provided Shards on create or when an identify is requested.
* The aim of this is to provide an easy to use manager which can be used by workers or any other kind of separate process.
*/
export function createShardManager(options: CreateShardManager) {
return {
// ----------
// PROPERTIES
// ----------
/** Options which are used to create a new Shard. */
createShardOptions: {
...options.createShardOptions,
events: {
...options.createShardOptions?.events,
message: options.createShardOptions?.events?.message ?? options.handleMessage,
},
},
/** Gateway configuration which is used when creating a Shard. */
gatewayConfig: options.gatewayConfig,
/** Managed Shards. */
shards: new Collection(
options.shardIds.map((shardId) => {
const shard = createShard({
...options.createShardOptions,
id: shardId,
totalShards: options.totalShards,
gatewayConfig: options.gatewayConfig,
requestIdentify: async function () {
return await options.requestIdentify(shardId);
},
});
return [shardId, shard] as const;
}),
),
/** Total amount of Shards used by the bot. */
totalShards: options.totalShards,
// ----------
// METHODS
// ----------
/** Tell the manager to identify a Shard.
* If this Shard is not already managed this will also add the Shard to the manager.
*/
identify: async function (shardId: number) {
let shard = this.shards.get(shardId);
if (!shard) {
shard = createShard({
...this.createShardOptions,
id: shardId,
totalShards: this.totalShards,
gatewayConfig: this.gatewayConfig,
requestIdentify: async function () {
return await options.requestIdentify(shardId);
},
});
this.shards.set(shardId, shard);
}
return await shard.identify();
},
/** Kill a shard.
* Close a shards connection to Discord's gateway (if any) and remove it from the manager.
*/
kill: async function (shardId: number) {
const shard = this.shards.get(shardId);
if (!shard) return;
this.shards.delete(shardId);
return await shard.shutdown();
},
/** This function communicates with the parent manager,
* in order to know whether this manager is allowed to identify a new shard.
*/
requestIdentify: options.requestIdentify,
};
}
export interface CreateShardManager {
// ----------
// PROPERTIES
// ----------
/** Options which are used to create a new Shard. */
createShardOptions?: Omit<CreateShard, "id" | "totalShards" | "requestIdentify" | "gatewayConfig">;
/** Gateway configuration which is used when creating a Shard. */
gatewayConfig: PickPartial<ShardGatewayConfig, "token">;
/** Ids of the Shards which should be managed. */
shardIds: number[];
/** Total amount of Shard used by the bot. */
totalShards: number;
// ----------
// METHODS
// ----------
/** This function is used when a shard receives any message from Discord. */
handleMessage(shard: Shard, message: DiscordGatewayPayload): unknown;
/** This function communicates with the parent manager,
* in order to know whether this manager is allowed to identify a new shard. #
*/
requestIdentify(shardId: number): Promise<void>;
}