cloudstorm 0.1.4 → 0.3.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,136 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from "events";
3
+ import BetterWs from "../structures/BetterWs";
4
+ interface ConnectorEvents {
5
+ queueIdentify: [number];
6
+ event: [import("../Types").IWSMessage];
7
+ ready: [boolean];
8
+ error: [string];
9
+ disconnect: [number, string, boolean];
10
+ }
11
+ interface DiscordConnector {
12
+ addListener<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
13
+ emit<E extends keyof ConnectorEvents>(event: E, ...args: ConnectorEvents[E]): boolean;
14
+ eventNames(): Array<keyof ConnectorEvents>;
15
+ listenerCount(event: keyof ConnectorEvents): number;
16
+ listeners(event: keyof ConnectorEvents): Array<(...args: Array<any>) => any>;
17
+ off<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
18
+ on<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
19
+ once<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
20
+ prependListener<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
21
+ prependOnceListener<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
22
+ rawListeners(event: keyof ConnectorEvents): Array<(...args: Array<any>) => any>;
23
+ removeAllListeners(event?: keyof ConnectorEvents): this;
24
+ removeListener<E extends keyof ConnectorEvents>(event: E, listener: (...args: ConnectorEvents[E]) => any): this;
25
+ }
26
+ /**
27
+ * Class used for acting based on received events.
28
+ *
29
+ * This class is automatically instantiated by the library and is documented for reference.
30
+ */
31
+ declare class DiscordConnector extends EventEmitter {
32
+ id: number;
33
+ client: import("../Client");
34
+ options: import("../Client")["options"];
35
+ reconnect: boolean;
36
+ betterWs: BetterWs | null;
37
+ heartbeatTimeout: NodeJS.Timeout | null;
38
+ heartbeatInterval: number;
39
+ _trace: string | null;
40
+ seq: number;
41
+ status: string;
42
+ sessionId: string | null;
43
+ lastACKAt: number;
44
+ lastHeartbeatSend: number;
45
+ latency: number;
46
+ /**
47
+ * Create a new Discord Connector.
48
+ * @param id id of the shard that created this class.
49
+ * @param client Main client instance.
50
+ */
51
+ constructor(id: number, client: import("../Client"));
52
+ /**
53
+ * Connect to Discord.
54
+ */
55
+ connect(): void;
56
+ /**
57
+ * Close the websocket connection and disconnect.
58
+ */
59
+ disconnect(): Promise<void>;
60
+ /**
61
+ * Called with a parsed Websocket message to execute further actions.
62
+ * @param message Message that was received.
63
+ */
64
+ private messageAction;
65
+ /**
66
+ * Reset this connector to be ready to resume or hard reconnect, then connect.
67
+ * @param resume Whether or not the client intends to send an OP 6 RESUME later.
68
+ */
69
+ private _reconnect;
70
+ /**
71
+ * Hard reset this connector.
72
+ */
73
+ private reset;
74
+ /**
75
+ * Clear the heart beat interval, set it to null and set the cached heartbeat_interval as 0.
76
+ */
77
+ private clearHeartBeat;
78
+ /**
79
+ * Send an OP 2 IDENTIFY to the gateway or an OP 6 RESUME if forceful identify is falsy.
80
+ * @param force Whether CloudStorm should send an OP 2 IDENTIFY even if there's a session that could be resumed.
81
+ */
82
+ identify(force?: boolean): Promise<void>;
83
+ /**
84
+ * Send an OP 6 RESUME to the gateway.
85
+ */
86
+ private resume;
87
+ /**
88
+ * Send an OP 1 HEARTBEAT to the gateway.
89
+ */
90
+ private heartbeat;
91
+ /**
92
+ * Handle dispatch events.
93
+ * @param message Message received from the websocket.
94
+ */
95
+ private handleDispatch;
96
+ /**
97
+ * Handle a close from the underlying websocket.
98
+ * @param code Websocket close code.
99
+ * @param reason Close reason if any.
100
+ */
101
+ private handleWsClose;
102
+ /**
103
+ * Send an OP 3 PRESENCE_UPDATE to the gateway.
104
+ * @param data Presence data to send.
105
+ */
106
+ presenceUpdate(data?: import("../Types").IPresence): Promise<void>;
107
+ /**
108
+ * Send an OP 4 VOICE_STATE_UPDATE to the gateway.
109
+ * @param data Voice state update data to send.
110
+ */
111
+ voiceStateUpdate(data: import("../Types").IVoiceStateUpdate): Promise<void>;
112
+ /**
113
+ * Send an OP 8 REQUEST_GUILD_MEMBERS to the gateway.
114
+ * @param data Data to send.
115
+ */
116
+ requestGuildMembers(data: import("../Types").IRequestGuildMembers): Promise<void>;
117
+ /**
118
+ * Checks presence data and fills in missing elements.
119
+ * @param data Data to send.
120
+ * @returns Data after it's fixed/checked.
121
+ */
122
+ private _checkPresenceData;
123
+ /**
124
+ * Checks voice state update data and fills in missing elements.
125
+ * @param data Data to send.
126
+ * @returns Data after it's fixed/checked.
127
+ */
128
+ private _checkVoiceStateUpdateData;
129
+ /**
130
+ * Checks request guild members data and fills in missing elements.
131
+ * @param data Data to send.
132
+ * @returns Data after it's fixed/checked.
133
+ */
134
+ private _checkRequestGuildMembersData;
135
+ }
136
+ export = DiscordConnector;
@@ -0,0 +1,413 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const events_1 = require("events");
6
+ const BetterWs_1 = __importDefault(require("../structures/BetterWs"));
7
+ const Constants_1 = require("../Constants");
8
+ const Intents_1 = __importDefault(require("../Intents"));
9
+ const ws_1 = __importDefault(require("ws"));
10
+ let reconnecting = false;
11
+ /**
12
+ * Class used for acting based on received events.
13
+ *
14
+ * This class is automatically instantiated by the library and is documented for reference.
15
+ */
16
+ class DiscordConnector extends events_1.EventEmitter {
17
+ /**
18
+ * Create a new Discord Connector.
19
+ * @param id id of the shard that created this class.
20
+ * @param client Main client instance.
21
+ */
22
+ constructor(id, client) {
23
+ super();
24
+ this.betterWs = null;
25
+ this.heartbeatTimeout = null;
26
+ this.heartbeatInterval = 0;
27
+ this._trace = null;
28
+ this.seq = 0;
29
+ this.status = "init";
30
+ this.sessionId = null;
31
+ this.lastACKAt = 0;
32
+ this.lastHeartbeatSend = 0;
33
+ this.latency = 0;
34
+ this.id = id;
35
+ this.client = client;
36
+ this.options = client.options;
37
+ this.reconnect = this.options.reconnect || true;
38
+ }
39
+ /**
40
+ * Connect to Discord.
41
+ */
42
+ connect() {
43
+ if (!this.betterWs) {
44
+ this.betterWs = new BetterWs_1.default(this.options.endpoint);
45
+ }
46
+ else {
47
+ this.betterWs.removeAllListeners();
48
+ this.betterWs.recreateWs(this.options.endpoint);
49
+ }
50
+ this.betterWs.on("ws_open", () => {
51
+ this.status = "connecting";
52
+ reconnecting = false;
53
+ });
54
+ this.betterWs.on("ws_message", msg => this.messageAction(msg));
55
+ this.betterWs.on("ws_close", (code, reason) => this.handleWsClose(code, reason));
56
+ this.betterWs.on("debug", event => {
57
+ this.client.emit("debug", event);
58
+ });
59
+ this.betterWs.on("debug_send", data => {
60
+ this.client.emit("rawSend", data);
61
+ });
62
+ }
63
+ /**
64
+ * Close the websocket connection and disconnect.
65
+ */
66
+ async disconnect() {
67
+ var _a;
68
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.close(1000, "Disconnected by User");
69
+ }
70
+ /**
71
+ * Called with a parsed Websocket message to execute further actions.
72
+ * @param message Message that was received.
73
+ */
74
+ async messageAction(message) {
75
+ this.client.emit("rawReceive", message);
76
+ if (message.s) {
77
+ if (message.s > this.seq + 1) {
78
+ this.client.emit("debug", `Shard ${this.id}, invalid sequence: current: ${this.seq} message: ${message.s}`);
79
+ this.seq = message.s;
80
+ this.resume();
81
+ }
82
+ this.seq = message.s;
83
+ }
84
+ switch (message.op) {
85
+ case Constants_1.GATEWAY_OP_CODES.DISPATCH:
86
+ this.handleDispatch(message);
87
+ break;
88
+ case Constants_1.GATEWAY_OP_CODES.HEARTBEAT:
89
+ this.heartbeat();
90
+ break;
91
+ case Constants_1.GATEWAY_OP_CODES.RECONNECT:
92
+ this.client.emit("debug", `Gateway asked shard ${this.id} to reconnect`);
93
+ if (this.options.reconnect)
94
+ this._reconnect(true);
95
+ else
96
+ this.disconnect();
97
+ break;
98
+ case Constants_1.GATEWAY_OP_CODES.INVALID_SESSION:
99
+ if (message.d && this.sessionId) {
100
+ this.resume();
101
+ }
102
+ else {
103
+ this.seq = 0;
104
+ this.sessionId = "";
105
+ this.emit("queueIdentify", this.id);
106
+ }
107
+ break;
108
+ case Constants_1.GATEWAY_OP_CODES.HELLO:
109
+ this.heartbeat();
110
+ this.heartbeatInterval = message.d.heartbeat_interval;
111
+ this.heartbeatTimeout = setInterval(() => {
112
+ if (this.lastACKAt <= Date.now() - (this.heartbeatInterval + 5000)) {
113
+ this.client.emit("debug", `Shard ${this.id} has not received a heartbeat ACK in ${this.heartbeatInterval + 5000}ms.`);
114
+ if (this.options.reconnect)
115
+ this._reconnect(true);
116
+ else
117
+ this.disconnect();
118
+ }
119
+ else {
120
+ this.heartbeat();
121
+ }
122
+ }, this.heartbeatInterval);
123
+ this._trace = message.d._trace;
124
+ this.identify();
125
+ this.client.emit("debug", `Shard ${this.id} received HELLO`);
126
+ break;
127
+ case Constants_1.GATEWAY_OP_CODES.HEARTBEAT_ACK:
128
+ this.lastACKAt = Date.now();
129
+ this.latency = this.lastACKAt - this.lastHeartbeatSend;
130
+ break;
131
+ default:
132
+ this.emit("event", message);
133
+ }
134
+ }
135
+ /**
136
+ * Reset this connector to be ready to resume or hard reconnect, then connect.
137
+ * @param resume Whether or not the client intends to send an OP 6 RESUME later.
138
+ */
139
+ async _reconnect(resume = false) {
140
+ var _a, _b, _c;
141
+ if (resume)
142
+ reconnecting = true;
143
+ if (((_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.ws.readyState) === ws_1.default.CONNECTING) {
144
+ this.emit("error", `Client was attempting to ${resume ? "resume" : "reconnect"} while the WebSocket was still in the connecting state. This should never happen.${this.options.reconnect ? " Restarting the connect loop." : ""}`);
145
+ this.reset();
146
+ if (this.options.reconnect)
147
+ this.connect();
148
+ }
149
+ // This is for instances where the gateway asks the client to reconnect. The ws would be closed by the time the code reaches here.
150
+ if (((_b = this.betterWs) === null || _b === void 0 ? void 0 : _b.ws.readyState) === ws_1.default.OPEN)
151
+ await ((_c = this.betterWs) === null || _c === void 0 ? void 0 : _c.close(resume ? 4000 : 1012, "reconnecting"));
152
+ if (resume) {
153
+ this.clearHeartBeat();
154
+ }
155
+ else {
156
+ this.reset();
157
+ }
158
+ this.connect();
159
+ }
160
+ /**
161
+ * Hard reset this connector.
162
+ */
163
+ reset() {
164
+ this.sessionId = null;
165
+ this.seq = 0;
166
+ this.lastACKAt = 0;
167
+ this._trace = null;
168
+ this.clearHeartBeat();
169
+ }
170
+ /**
171
+ * Clear the heart beat interval, set it to null and set the cached heartbeat_interval as 0.
172
+ */
173
+ clearHeartBeat() {
174
+ if (this.heartbeatTimeout)
175
+ clearInterval(this.heartbeatTimeout);
176
+ this.heartbeatTimeout = null;
177
+ this.heartbeatInterval = 0;
178
+ }
179
+ /**
180
+ * Send an OP 2 IDENTIFY to the gateway or an OP 6 RESUME if forceful identify is falsy.
181
+ * @param force Whether CloudStorm should send an OP 2 IDENTIFY even if there's a session that could be resumed.
182
+ */
183
+ async identify(force) {
184
+ var _a;
185
+ if (this.sessionId && !force) {
186
+ return this.resume();
187
+ }
188
+ const data = {
189
+ op: Constants_1.GATEWAY_OP_CODES.IDENTIFY,
190
+ d: {
191
+ token: this.options.token,
192
+ properties: {
193
+ $os: process.platform,
194
+ $browser: "CloudStorm",
195
+ $device: "CloudStorm"
196
+ },
197
+ large_threshold: this.options.largeGuildThreshold,
198
+ shard: [this.id, this.options.shardAmount],
199
+ intents: this.options.intents ? Intents_1.default.resolve(this.options.intents) : 0
200
+ }
201
+ };
202
+ if (this.options.initialPresence)
203
+ Object.assign(data.d, { presence: this._checkPresenceData(this.options.initialPresence) });
204
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.sendMessage(data);
205
+ }
206
+ /**
207
+ * Send an OP 6 RESUME to the gateway.
208
+ */
209
+ async resume() {
210
+ var _a;
211
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.sendMessage({
212
+ op: Constants_1.GATEWAY_OP_CODES.RESUME,
213
+ d: { seq: this.seq, token: this.options.token, session_id: this.sessionId }
214
+ });
215
+ }
216
+ /**
217
+ * Send an OP 1 HEARTBEAT to the gateway.
218
+ */
219
+ heartbeat() {
220
+ var _a, _b;
221
+ if (((_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.ws.readyState) !== ws_1.default.OPEN)
222
+ return;
223
+ (_b = this.betterWs) === null || _b === void 0 ? void 0 : _b.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.HEARTBEAT, d: this.seq });
224
+ this.lastHeartbeatSend = Date.now();
225
+ }
226
+ /**
227
+ * Handle dispatch events.
228
+ * @param message Message received from the websocket.
229
+ */
230
+ handleDispatch(message) {
231
+ switch (message.t) {
232
+ case "READY":
233
+ case "RESUMED":
234
+ if (message.t === "READY") {
235
+ this.sessionId = message.d.session_id;
236
+ }
237
+ this.status = "ready";
238
+ this._trace = message.d._trace;
239
+ this.emit("ready", message.t === "RESUMED");
240
+ this.emit("event", message);
241
+ break;
242
+ default:
243
+ this.emit("event", message);
244
+ }
245
+ }
246
+ /**
247
+ * Handle a close from the underlying websocket.
248
+ * @param code Websocket close code.
249
+ * @param reason Close reason if any.
250
+ */
251
+ handleWsClose(code, reason) {
252
+ var _a;
253
+ let gracefulClose = false;
254
+ this.status = "disconnected";
255
+ // Disallowed Intents.
256
+ if (code === 4014) {
257
+ this.emit("error", "Disallowed Intents, check your client options and application page.");
258
+ }
259
+ // Invalid Intents.
260
+ if (code === 4013) {
261
+ this.emit("error", "Invalid Intents data, check your client options.");
262
+ }
263
+ // Invalid API version.
264
+ if (code === 4012) {
265
+ this.emit("error", "Invalid API version.");
266
+ }
267
+ // Sharding required.
268
+ if (code === 4011) {
269
+ this.emit("error", "Shard would be on over 2500 guilds. Add more shards.");
270
+ }
271
+ // Invalid shard.
272
+ if (code === 4010) {
273
+ this.emit("error", "Invalid sharding data, check your client options.");
274
+ }
275
+ // Session timed out.
276
+ // force identify if the session is marked as invalid.
277
+ if (code === 4009) {
278
+ this.emit("error", "Session timed out.");
279
+ this.clearHeartBeat();
280
+ this.connect();
281
+ }
282
+ // Rate limited.
283
+ if (code === 4008) {
284
+ this.emit("error", "You are being rate limited. Wait before sending more packets.");
285
+ this.clearHeartBeat();
286
+ this.connect();
287
+ }
288
+ // Invalid sequence.
289
+ if (code === 4007) {
290
+ this.emit("error", "Invalid sequence. Reconnecting and starting a new session.");
291
+ this.reset();
292
+ this.connect();
293
+ }
294
+ // Already authenticated.
295
+ if (code === 4005) {
296
+ this.emit("error", "You sent more than one OP 2 IDENTIFY payload while the websocket was open.");
297
+ this.clearHeartBeat();
298
+ this.connect();
299
+ }
300
+ // Authentication failed.
301
+ if (code === 4004) {
302
+ this.emit("error", "Tried to connect with an invalid token");
303
+ }
304
+ // Not authenticated.
305
+ if (code === 4003) {
306
+ this.emit("error", "You tried to send a packet before sending an OP 2 IDENTIFY or OP 6 RESUME.");
307
+ this.clearHeartBeat();
308
+ this.connect();
309
+ }
310
+ // Decode error.
311
+ if (code === 4002) {
312
+ this.emit("error", "You sent an invalid payload");
313
+ this.clearHeartBeat();
314
+ this.connect();
315
+ }
316
+ // Invalid opcode.
317
+ if (code === 4001) {
318
+ this.emit("error", "You sent an invalid opcode or invalid payload for an opcode");
319
+ this.clearHeartBeat();
320
+ this.connect();
321
+ }
322
+ // Generic error / safe self closing code.
323
+ if (code === 4000) {
324
+ if (reconnecting) {
325
+ gracefulClose = true;
326
+ }
327
+ else {
328
+ this.emit("error", "Error code 4000 received. Attempting to resume");
329
+ this.clearHeartBeat();
330
+ this.connect();
331
+ }
332
+ }
333
+ // Don't try to reconnect when true
334
+ if (code === 1000 && reason === "Disconnected by User") {
335
+ gracefulClose = true;
336
+ }
337
+ if (gracefulClose) {
338
+ this.clearHeartBeat();
339
+ (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
340
+ }
341
+ this.emit("disconnect", code, reason, gracefulClose);
342
+ }
343
+ /**
344
+ * Send an OP 3 PRESENCE_UPDATE to the gateway.
345
+ * @param data Presence data to send.
346
+ */
347
+ async presenceUpdate(data = {}) {
348
+ var _a;
349
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.PRESENCE_UPDATE, d: this._checkPresenceData(data) });
350
+ }
351
+ /**
352
+ * Send an OP 4 VOICE_STATE_UPDATE to the gateway.
353
+ * @param data Voice state update data to send.
354
+ */
355
+ async voiceStateUpdate(data) {
356
+ var _a;
357
+ if (!data) {
358
+ return Promise.resolve();
359
+ }
360
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.VOICE_STATE_UPDATE, d: this._checkVoiceStateUpdateData(data) });
361
+ }
362
+ /**
363
+ * Send an OP 8 REQUEST_GUILD_MEMBERS to the gateway.
364
+ * @param data Data to send.
365
+ */
366
+ async requestGuildMembers(data) {
367
+ var _a;
368
+ return (_a = this.betterWs) === null || _a === void 0 ? void 0 : _a.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.REQUEST_GUILD_MEMBERS, d: this._checkRequestGuildMembersData(data) });
369
+ }
370
+ /**
371
+ * Checks presence data and fills in missing elements.
372
+ * @param data Data to send.
373
+ * @returns Data after it's fixed/checked.
374
+ */
375
+ _checkPresenceData(data) {
376
+ data.status = data.status || "online";
377
+ data.activities = data.activities && Array.isArray(data.activities) ? data.activities : null;
378
+ if (data.activities) {
379
+ for (const activity of data.activities) {
380
+ const index = data.activities.indexOf(activity);
381
+ if (activity.type === undefined)
382
+ activity.type = activity.url ? 1 : 0;
383
+ if (!activity.name)
384
+ data.activities.splice(index, 1);
385
+ }
386
+ }
387
+ data.afk = data.afk || false;
388
+ data.since = data.since || false;
389
+ return data;
390
+ }
391
+ /**
392
+ * Checks voice state update data and fills in missing elements.
393
+ * @param data Data to send.
394
+ * @returns Data after it's fixed/checked.
395
+ */
396
+ _checkVoiceStateUpdateData(data) {
397
+ data.channel_id = data.channel_id || null;
398
+ data.self_mute = data.self_mute || false;
399
+ data.self_deaf = data.self_deaf || false;
400
+ return data;
401
+ }
402
+ /**
403
+ * Checks request guild members data and fills in missing elements.
404
+ * @param data Data to send.
405
+ * @returns Data after it's fixed/checked.
406
+ */
407
+ _checkRequestGuildMembersData(data) {
408
+ data.query = data.query || "";
409
+ data.limit = data.limit || 0;
410
+ return data;
411
+ }
412
+ }
413
+ module.exports = DiscordConnector;
@@ -0,0 +1,5 @@
1
+ import Client from "./Client";
2
+ import Constants from "./Constants";
3
+ import Intents from "./Intents";
4
+ export * from "./Types";
5
+ export { Client, Constants, Intents };
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.Intents = exports.Constants = exports.Client = void 0;
17
+ const Client_1 = __importDefault(require("./Client"));
18
+ exports.Client = Client_1.default;
19
+ const Constants_1 = __importDefault(require("./Constants"));
20
+ exports.Constants = Constants_1.default;
21
+ const Intents_1 = __importDefault(require("./Intents"));
22
+ exports.Intents = Intents_1.default;
23
+ __exportStar(require("./Types"), exports);
@@ -0,0 +1,85 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from "events";
3
+ import zlib from "zlib-sync";
4
+ import WebSocket from "ws";
5
+ import RatelimitBucket from "./RatelimitBucket";
6
+ interface BWSEvents {
7
+ error: [Error | string];
8
+ ws_open: [];
9
+ ws_close: [number, string];
10
+ ws_message: [import("../Types").IGatewayMessage];
11
+ debug_send: [import("../Types").IWSMessage];
12
+ debug: [string];
13
+ }
14
+ interface BetterWs {
15
+ addListener<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
16
+ emit<E extends keyof BWSEvents>(event: E, ...args: BWSEvents[E]): boolean;
17
+ eventNames(): Array<keyof BWSEvents>;
18
+ listenerCount(event: keyof BWSEvents): number;
19
+ listeners(event: keyof BWSEvents): Array<(...args: Array<any>) => any>;
20
+ off<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
21
+ on<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
22
+ once<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
23
+ prependListener<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
24
+ prependOnceListener<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
25
+ rawListeners(event: keyof BWSEvents): Array<(...args: Array<any>) => any>;
26
+ removeAllListeners(event?: keyof BWSEvents): this;
27
+ removeListener<E extends keyof BWSEvents>(event: E, listener: (...args: BWSEvents[E]) => any): this;
28
+ }
29
+ /**
30
+ * Helper Class for simplifying the websocket connection to Discord.
31
+ */
32
+ declare class BetterWs extends EventEmitter {
33
+ ws: WebSocket;
34
+ wsBucket: RatelimitBucket;
35
+ presenceBucket: RatelimitBucket;
36
+ zlibInflate: zlib.Inflate;
37
+ options: WebSocket.ClientOptions;
38
+ /**
39
+ * Create a new BetterWs instance.
40
+ */
41
+ constructor(address: string, options?: import("ws").ClientOptions);
42
+ /**
43
+ * Get the raw websocket connection currently used.
44
+ */
45
+ get rawWs(): WebSocket;
46
+ /**
47
+ * Add eventlisteners to a passed websocket connection.
48
+ * @param ws Websocket.
49
+ */
50
+ private bindWs;
51
+ /**
52
+ * Create a new websocket connection if the old one was closed/destroyed.
53
+ * @param address Address to connect to.
54
+ * @param options Options used by the websocket connection.
55
+ */
56
+ recreateWs(address: string, options?: import("ws").ClientOptions): void;
57
+ /**
58
+ * Called upon opening of the websocket connection.
59
+ */
60
+ private onOpen;
61
+ /**
62
+ * Called once a websocket message is received,
63
+ * uncompresses the message using zlib and parses it via Erlpack or JSON.parse.
64
+ * @param message Message received by websocket.
65
+ */
66
+ private onMessage;
67
+ /**
68
+ * Called when the websocket connection closes for some reason.
69
+ * @param code Websocket close code.
70
+ * @param reason Reason of the close if any.
71
+ */
72
+ private onClose;
73
+ /**
74
+ * Send a message to the Discord gateway.
75
+ * @param data Data to send.
76
+ */
77
+ sendMessage(data: any): Promise<void>;
78
+ /**
79
+ * Close the current websocket connection.
80
+ * @param code Websocket close code to use.
81
+ * @param reason Reason of the disconnect.
82
+ */
83
+ close(code?: number, reason?: string): Promise<void>;
84
+ }
85
+ export = BetterWs;