@bakit/gateway 2.1.8 → 3.0.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.
@@ -0,0 +1,23 @@
1
+ import { Cluster, ClusterProcess } from '@bakit/gateway';
2
+
3
+ // src/lib/internal/cluster.ts
4
+ var {
5
+ BAKIT_CLUSTER_ID,
6
+ BAKIT_DISCORD_TOKEN,
7
+ BAKIT_DISCORD_INTENTS,
8
+ BAKIT_DISCORD_GATEWAY_URL,
9
+ BAKIT_DISCORD_GATEWAY_VERSION,
10
+ BAKIT_CLUSTER_SHARD_TOTAL,
11
+ BAKIT_CLUSTER_SHARD_LIST
12
+ } = process.env, cluster = new Cluster(Number(BAKIT_CLUSTER_ID), {
13
+ token: BAKIT_DISCORD_TOKEN,
14
+ intents: Number(BAKIT_DISCORD_INTENTS),
15
+ total: Number(BAKIT_CLUSTER_SHARD_TOTAL),
16
+ shards: JSON.parse(BAKIT_CLUSTER_SHARD_LIST),
17
+ gateway: {
18
+ baseURL: BAKIT_DISCORD_GATEWAY_URL,
19
+ version: Number(BAKIT_DISCORD_GATEWAY_VERSION)
20
+ }
21
+ });
22
+ ClusterProcess.bindProcess(cluster);
23
+ await cluster.spawn();
package/dist/index.d.ts CHANGED
@@ -1,155 +1,201 @@
1
- import { EventBus, ReadonlyCollection } from '@bakit/utils';
2
- import { GatewayReadyDispatchData, GatewayReceivePayload, GatewayDispatchPayload, GatewaySendPayload } from 'discord-api-types/gateway';
3
- import { ValueOf } from 'type-fest';
4
- import { GatewayReadyDispatchData as GatewayReadyDispatchData$1, GatewayReceivePayload as GatewayReceivePayload$1, GatewayDispatchPayload as GatewayDispatchPayload$1, GatewaySendPayload as GatewaySendPayload$1 } from 'discord-api-types/v10';
5
- import { REST } from '@bakit/rest';
1
+ import EventEmitter from 'node:events';
2
+ import { GatewayReadyDispatchData, GatewayReceivePayload, GatewayDispatchPayload, GatewaySendPayload } from 'discord-api-types/v10';
3
+ import { ChildProcess } from 'node:child_process';
4
+ import { Collection } from '@bakit/utils';
5
+ import { REST, RESTProxy } from '@bakit/rest';
6
6
 
7
+ declare enum ShardState {
8
+ Idle = 0,
9
+ Connecting = 1,
10
+ Ready = 2,
11
+ Resuming = 3,
12
+ Disconnecting = 4,
13
+ Disconnected = 5
14
+ }
15
+ declare enum ShardStrategy {
16
+ Resume = 0,
17
+ Reconnect = 1,
18
+ Shutdown = 2
19
+ }
7
20
  interface ShardOptions {
8
- id: number;
9
21
  total: number;
10
22
  token: string;
11
23
  intents: number | bigint;
12
- gateway?: ShardGatewayOptions;
13
- }
14
- interface ShardGatewayOptions {
15
- baseURL: string;
16
- version: number;
24
+ gateway: {
25
+ baseURL: string;
26
+ version: number;
27
+ };
17
28
  }
18
29
  interface ShardEvents {
19
- ready: [payload: GatewayReadyDispatchData];
30
+ ready: [data: GatewayReadyDispatchData];
20
31
  disconnect: [code: number];
21
32
  resume: [];
22
33
  error: [error: Error];
23
34
  debug: [message: string];
24
35
  raw: [payload: GatewayReceivePayload];
25
36
  dispatch: [payload: GatewayDispatchPayload];
26
- requestIdentify: [];
27
- }
28
- /**
29
- * High-level lifecycle state of the shard connection.
30
- */
31
- declare const ShardState: {
32
- /** Not connected. */
33
- Idle: number;
34
- /** Initialzing connection. */
35
- Connecting: number;
36
- /** Connected to gateway and identified. */
37
- Ready: number;
38
- /** Resuming the session. */
39
- Resuming: number;
40
- /** Disconnected the connection. */
41
- Disconnected: number;
42
- };
43
- type ShardState = ValueOf<typeof ShardState>;
44
- /**
45
- * Strategy describes *what to do next after a disconnect*.
46
- * This is intentionally separate from ShardState.
47
- */
48
- declare const ShardStrategy: {
49
- /** No decision yet (default on close). */
50
- Unknown: number;
51
- /** Reconnect with IDENTIFY (new session). */
52
- Reconnect: number;
53
- /** Reconnect and try RESUME. */
54
- Resume: number;
55
- /** Do not reconnect. */
56
- Shutdown: number;
57
- };
58
- type ShardStrategy = ValueOf<typeof ShardStrategy>;
59
- interface Shard extends EventBus<ShardEvents> {
37
+ needIdentify: [];
38
+ }
39
+ declare class Shard extends EventEmitter<ShardEvents> {
40
+ #private;
60
41
  readonly id: number;
61
- readonly state: ShardState;
62
- readonly latency: number;
42
+ readonly options: ShardOptions;
43
+ constructor(id: number, options: ShardOptions);
44
+ get state(): ShardState;
45
+ get latency(): number;
46
+ get resumable(): boolean;
63
47
  connect(): Promise<void>;
64
- disconnect(code?: number): Promise<void>;
65
- send(payload: GatewaySendPayload): void;
48
+ disconnect(code: number): Promise<void>;
49
+ resume(): void;
66
50
  identify(): void;
51
+ send(payload: GatewaySendPayload): void;
52
+ sendHeartbeat(): void;
67
53
  }
68
- /**
69
- * Creates a shard object which can be used to connect to the Discord gateway.
70
- *
71
- * @param {ShardOptions} options - The options to create the shard with.
72
- * @returns {Shard} - The created shard object.
73
- */
74
- declare function createShard(options: ShardOptions): Shard;
75
54
 
76
- interface GatewayWorkerOptions {
77
- id: number;
78
- total: number;
55
+ interface ClusterOptions {
79
56
  token: string;
80
- intents: number | bigint;
57
+ intents: bigint | number;
81
58
  shards: number[];
82
- gatewayURL: string;
83
- }
84
- interface GatewayWorker extends EventBus<GatewayWorkerEvents> {
85
- readonly id: number;
86
- readonly shards: ReadonlyCollection<number, Shard>;
87
- readonly shardIds: number[];
88
- readonly latency: number;
89
- readonly state: GatewayWorkerState;
90
- start(): Promise<void>;
91
- stop(code?: number): Promise<void>;
92
- /**
93
- * Broadcast the given payload to all shards connections.
94
- * @param {GatewaySendPayload} payload - The payload to send.
95
- */
96
- broadcast(payload: GatewaySendPayload$1): void;
59
+ total: number;
60
+ gateway: {
61
+ baseURL: string;
62
+ version: number;
63
+ };
97
64
  }
98
- interface GatewayWorkerEvents {
99
- ready: [];
100
- stop: [];
101
- resume: [];
102
- degrade: [readyCount: number, total: number];
103
- shardReady: [shardId: number, payload: GatewayReadyDispatchData$1];
104
- shardDisconnect: [shardId: number, code: number];
105
- shardRaw: [shardId: number, payload: GatewayReceivePayload$1];
106
- shardDispatch: [shardId: number, payload: GatewayDispatchPayload$1];
107
- shardRequestIdentify: [shardId: number];
65
+ interface ClusterEvents {
66
+ shardAdd: [id: number];
67
+ shardReady: [id: number];
68
+ shardDisconnect: [id: number, code: number];
69
+ shardResume: [id: number];
70
+ shardError: [id: number, error: Error];
71
+ needIdentify: [id: number];
108
72
  debug: [message: string];
73
+ dispatch: [shardId: number, payload: GatewayDispatchPayload];
74
+ raw: [shardId: number, payload: GatewayReceivePayload];
75
+ ready: [];
109
76
  error: [error: Error];
110
77
  }
111
- declare const GatewayWorkerState: {
112
- readonly Idle: 0;
113
- readonly Starting: 1;
114
- readonly Ready: 2;
115
- readonly Degraded: 3;
116
- readonly Stopped: 4;
117
- };
118
- type GatewayWorkerState = ValueOf<typeof GatewayWorkerState>;
119
- declare function createWorker(options: GatewayWorkerOptions): GatewayWorker;
120
- declare function bindWorkerToProcess(worker: GatewayWorker): void;
121
- declare function getWorkerOptions(): GatewayWorkerOptions;
78
+ declare class Cluster extends EventEmitter<ClusterEvents> {
79
+ #private;
80
+ readonly id: number;
81
+ readonly options: ClusterOptions;
82
+ readonly shards: Collection<number, Shard>;
83
+ constructor(id: number, options: ClusterOptions);
84
+ get size(): number;
85
+ get ready(): boolean;
86
+ spawn(): Promise<void>;
87
+ shutdown(code?: number): Promise<void>;
88
+ broadcast(fn: (shard: Shard) => void): void;
89
+ send(payload: GatewaySendPayload): void;
90
+ send(shardId: number, payload: GatewaySendPayload): void;
91
+ }
122
92
 
123
- declare const DEFAULT_WORKER_PATH: string;
124
- interface GatewayManagerOptions {
93
+ interface ShardingManagerOptions {
125
94
  token: string;
126
- intents: number | bigint;
127
- workerPath?: string;
128
- gatewayURL?: string;
95
+ intents: bigint | number;
129
96
  totalShards?: number | "auto";
130
- shardsPerWorker?: number;
97
+ shardsPerCluster?: number;
131
98
  }
132
- declare const DEFAULT_GATEWAY_MANAGER_OPTIONS: {
133
- readonly gatewayURL: "wss://gateway.discord.gg";
134
- readonly totalShards: "auto";
135
- readonly shardsPerWorker: 5;
136
- };
137
- interface GatewayManagerEvents {
138
- error: [error: Error];
139
- shardReady: [workerId: number, shardId: number, payload: GatewayReadyDispatchData$1];
140
- shardDisconnect: [workerId: number, shardId: number, code?: number];
141
- shardRaw: [workerId: number, shardId: number, payload: GatewayReceivePayload$1];
142
- shardDispatch: [workerId: number, shardId: number, payload: GatewayDispatchPayload$1];
143
- workerReady: [workerId: number];
144
- workerStop: [workerId: number];
145
- }
146
- interface GatewayManager extends EventBus<GatewayManagerEvents> {
147
- readonly rest: REST;
99
+ interface ShardingManagerEvents {
100
+ shardAdd: [cluster: ClusterProcess, shardId: number];
101
+ shardReady: [cluster: ClusterProcess, shardId: number];
102
+ shardDisconnect: [cluster: ClusterProcess, shardId: number, code: number];
103
+ shardResume: [cluster: ClusterProcess, shardId: number];
104
+ shardError: [cluster: ClusterProcess, shardId: number, error: Error];
105
+ clusterCreate: [cluster: ClusterProcess];
106
+ clusterReady: [cluster: ClusterProcess];
107
+ clusterExit: [cluster: ClusterProcess, code: number | null];
108
+ clusterError: [cluster: ClusterProcess, error: Error];
109
+ dispatch: [cluster: ClusterProcess, shardId: number, payload: GatewayDispatchPayload];
110
+ raw: [cluster: ClusterProcess, shardId: number, payload: GatewayReceivePayload];
111
+ debug: [message: string];
112
+ ready: [];
113
+ }
114
+ declare class ShardingManager extends EventEmitter<ShardingManagerEvents> {
115
+ #private;
116
+ readonly clusters: Collection<number, ClusterProcess>;
117
+ readonly options: Required<ShardingManagerOptions>;
118
+ readonly rest: REST | RESTProxy;
119
+ constructor(options: ShardingManagerOptions, rest?: REST | RESTProxy);
120
+ get totalClusters(): number;
121
+ get totalShards(): number;
122
+ get ready(): boolean;
148
123
  spawn(): Promise<void>;
149
- broadcast(payload: GatewaySendPayload$1): void;
150
- sendToWorker(id: number, payload: GatewaySendPayload$1): void;
151
- sendToShard(id: number, payload: GatewaySendPayload$1): void;
124
+ kill(signal?: NodeJS.Signals): Promise<void>;
125
+ broadcast(payload: GatewaySendPayload): void;
126
+ broadcastEval<T>(fn: (cluster: Cluster) => T | Promise<T>): Promise<EvalResult<T>[]>;
127
+ protected requestIdentify(cluster: ClusterProcess, shardId: number): void;
128
+ }
129
+
130
+ type ClusterIPCDispatchPayload<E extends keyof ClusterEvents = keyof ClusterEvents> = {
131
+ op: "dispatch";
132
+ t: E;
133
+ d: ClusterEvents[E];
134
+ };
135
+ interface ClusterIPCIdentifyPayload {
136
+ op: "identify";
137
+ d: number;
138
+ }
139
+ interface ClusterIPCGatewaySendPayload {
140
+ op: "send";
141
+ d: {
142
+ shardId?: number;
143
+ data: GatewaySendPayload;
144
+ };
145
+ }
146
+ interface ClusterIPCEvalRequestPayload {
147
+ op: "eval";
148
+ d: {
149
+ nonce: string;
150
+ script: string;
151
+ };
152
+ }
153
+ interface ClusterIPCEvalResponsePayload {
154
+ op: "evalResponse";
155
+ d: {
156
+ nonce: string;
157
+ success: boolean;
158
+ result: unknown;
159
+ error?: string;
160
+ };
161
+ }
162
+ type ClusterIPCPayload = ClusterIPCDispatchPayload | ClusterIPCIdentifyPayload | ClusterIPCGatewaySendPayload | ClusterIPCEvalRequestPayload | ClusterIPCEvalResponsePayload;
163
+ interface EvalResult<T> {
164
+ /**
165
+ * Whether the evaluation was successful
166
+ */
167
+ success: boolean;
168
+ /**
169
+ * The result of the evaluation if successful
170
+ */
171
+ data?: T;
172
+ /**
173
+ * The error if evaluation failed
174
+ */
175
+ error?: Error;
176
+ /**
177
+ * The cluster process that executed the evaluation
178
+ */
179
+ cluster: ClusterProcess;
180
+ }
181
+ interface ClusterProcessOptions {
182
+ env?: NodeJS.ProcessEnv;
183
+ execArgv?: string[];
184
+ }
185
+ declare class ClusterProcess extends EventEmitter<ClusterEvents> {
186
+ #private;
187
+ readonly manager: ShardingManager;
188
+ readonly id: number;
189
+ readonly process: ChildProcess;
190
+ constructor(manager: ShardingManager, id: number, options?: ClusterProcessOptions);
191
+ get killed(): boolean;
192
+ kill(signal?: NodeJS.Signals): void;
193
+ eval<T, C = unknown>(fn: (cluster: Cluster, ctx: C) => T | Promise<T>, ctx?: C): Promise<EvalResult<T>>;
194
+ send(payload: GatewaySendPayload): void;
195
+ send(shardId: number, payload: GatewaySendPayload): void;
196
+ sendIPC(message: ClusterIPCPayload): void;
197
+ identifyShard(id: number): void;
198
+ static bindProcess(cluster: Cluster): void;
152
199
  }
153
- declare function createGatewayManager(options: GatewayManagerOptions, rest: REST): GatewayManager;
154
200
 
155
- export { DEFAULT_GATEWAY_MANAGER_OPTIONS, DEFAULT_WORKER_PATH, type GatewayManager, type GatewayManagerEvents, type GatewayManagerOptions, type GatewayWorker, type GatewayWorkerEvents, type GatewayWorkerOptions, GatewayWorkerState, type Shard, type ShardEvents, type ShardGatewayOptions, type ShardOptions, ShardState, ShardStrategy, bindWorkerToProcess, createGatewayManager, createShard, createWorker, getWorkerOptions };
201
+ export { Cluster, type ClusterEvents, type ClusterIPCDispatchPayload, type ClusterIPCEvalRequestPayload, type ClusterIPCEvalResponsePayload, type ClusterIPCGatewaySendPayload, type ClusterIPCIdentifyPayload, type ClusterIPCPayload, type ClusterOptions, ClusterProcess, type ClusterProcessOptions, type EvalResult, Shard, type ShardEvents, type ShardOptions, ShardState, ShardStrategy, ShardingManager, type ShardingManagerEvents, type ShardingManagerOptions };