cloudstorm 0.4.0 → 0.4.3
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/README.md +2 -4
- package/dist/Client.js +6 -16
- package/dist/Intents.d.ts +2 -0
- package/dist/Intents.js +3 -1
- package/dist/Shard.d.ts +0 -1
- package/dist/Shard.js +2 -9
- package/dist/ShardManager.js +12 -30
- package/dist/Types.d.ts +4 -31
- package/dist/connector/DiscordConnector.d.ts +5 -4
- package/dist/connector/DiscordConnector.js +67 -93
- package/dist/structures/BetterWs.d.ts +17 -54
- package/dist/structures/BetterWs.js +504 -154
- package/dist/structures/RatelimitBucket.js +3 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -14
|
@@ -6,7 +6,6 @@ const events_1 = require("events");
|
|
|
6
6
|
const BetterWs_1 = __importDefault(require("../structures/BetterWs"));
|
|
7
7
|
const Constants_1 = require("../Constants");
|
|
8
8
|
const Intents_1 = __importDefault(require("../Intents"));
|
|
9
|
-
const ws_1 = __importDefault(require("ws"));
|
|
10
9
|
let reconnecting = false;
|
|
11
10
|
/**
|
|
12
11
|
* Class used for acting based on received events.
|
|
@@ -21,51 +20,44 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
21
20
|
*/
|
|
22
21
|
constructor(id, client) {
|
|
23
22
|
super();
|
|
24
|
-
this.betterWs = null;
|
|
25
23
|
this.heartbeatTimeout = null;
|
|
26
24
|
this.heartbeatInterval = 0;
|
|
27
25
|
this._trace = null;
|
|
28
26
|
this.seq = 0;
|
|
29
|
-
this.status = "
|
|
27
|
+
this.status = "disconnected";
|
|
30
28
|
this.sessionId = null;
|
|
31
29
|
this.lastACKAt = 0;
|
|
32
30
|
this.lastHeartbeatSend = 0;
|
|
33
31
|
this.latency = 0;
|
|
32
|
+
this._closing = false;
|
|
34
33
|
this.id = id;
|
|
35
34
|
this.client = client;
|
|
36
35
|
this.options = client.options;
|
|
37
36
|
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, this.options.ws);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
this.betterWs.removeAllListeners();
|
|
48
|
-
this.betterWs.recreateWs(this.options.endpoint, this.options.ws);
|
|
49
|
-
}
|
|
37
|
+
this.betterWs = new BetterWs_1.default(this.options.endpoint, this.options.ws);
|
|
50
38
|
this.betterWs.on("ws_open", () => {
|
|
51
39
|
this.status = "connecting";
|
|
40
|
+
this.emit("stateChange", "connecting");
|
|
52
41
|
reconnecting = false;
|
|
53
42
|
});
|
|
54
43
|
this.betterWs.on("ws_message", msg => this.messageAction(msg));
|
|
55
44
|
this.betterWs.on("ws_close", (code, reason) => this.handleWsClose(code, reason));
|
|
56
|
-
this.betterWs.on("debug", event =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
this.betterWs.on("debug", event => this.client.emit("debug", event));
|
|
46
|
+
this.betterWs.on("debug_send", data => this.client.emit("rawSend", data));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Connect to Discord.
|
|
50
|
+
*/
|
|
51
|
+
connect() {
|
|
52
|
+
this._closing = false;
|
|
53
|
+
return this.betterWs.connect();
|
|
62
54
|
}
|
|
63
55
|
/**
|
|
64
56
|
* Close the websocket connection and disconnect.
|
|
65
57
|
*/
|
|
66
58
|
async disconnect() {
|
|
67
|
-
|
|
68
|
-
return
|
|
59
|
+
this._closing = true;
|
|
60
|
+
return this.betterWs.close(1000, "Disconnected by User");
|
|
69
61
|
}
|
|
70
62
|
/**
|
|
71
63
|
* Called with a parsed Websocket message to execute further actions.
|
|
@@ -96,9 +88,8 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
96
88
|
this.disconnect();
|
|
97
89
|
break;
|
|
98
90
|
case Constants_1.GATEWAY_OP_CODES.INVALID_SESSION:
|
|
99
|
-
if (message.d && this.sessionId)
|
|
91
|
+
if (message.d && this.sessionId)
|
|
100
92
|
this.resume();
|
|
101
|
-
}
|
|
102
93
|
else {
|
|
103
94
|
this.seq = 0;
|
|
104
95
|
this.sessionId = "";
|
|
@@ -116,9 +107,8 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
116
107
|
else
|
|
117
108
|
this.disconnect();
|
|
118
109
|
}
|
|
119
|
-
else
|
|
110
|
+
else
|
|
120
111
|
this.heartbeat();
|
|
121
|
-
}
|
|
122
112
|
}, this.heartbeatInterval);
|
|
123
113
|
this._trace = message.d._trace;
|
|
124
114
|
this.identify();
|
|
@@ -137,24 +127,15 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
137
127
|
* @param resume Whether or not the client intends to send an OP 6 RESUME later.
|
|
138
128
|
*/
|
|
139
129
|
async _reconnect(resume = false) {
|
|
140
|
-
var _a, _b, _c;
|
|
141
130
|
if (resume)
|
|
142
131
|
reconnecting = true;
|
|
143
|
-
if (
|
|
144
|
-
this.emit("error", `Client was attempting to ${resume ? "resume" : "reconnect"} while the WebSocket was still in the connecting state. This should never happen
|
|
145
|
-
|
|
146
|
-
|
|
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) {
|
|
132
|
+
if (this.betterWs.status === 2)
|
|
133
|
+
void this.client.emit("error", `Client was attempting to ${resume ? "resume" : "reconnect"} while the WebSocket was still in the connecting state. This should never happen.`);
|
|
134
|
+
await this.betterWs.close(resume ? 4000 : 1012, "reconnecting");
|
|
135
|
+
if (resume)
|
|
153
136
|
this.clearHeartBeat();
|
|
154
|
-
|
|
155
|
-
else {
|
|
137
|
+
else
|
|
156
138
|
this.reset();
|
|
157
|
-
}
|
|
158
139
|
this.connect();
|
|
159
140
|
}
|
|
160
141
|
/**
|
|
@@ -181,10 +162,12 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
181
162
|
* @param force Whether CloudStorm should send an OP 2 IDENTIFY even if there's a session that could be resumed.
|
|
182
163
|
*/
|
|
183
164
|
async identify(force) {
|
|
184
|
-
|
|
185
|
-
|
|
165
|
+
if (this.betterWs.status !== 1)
|
|
166
|
+
void this.client.emit("debug", "Client was attempting to identify when the ws was not open");
|
|
167
|
+
if (this.sessionId && !force)
|
|
186
168
|
return this.resume();
|
|
187
|
-
|
|
169
|
+
this.status = "identifying";
|
|
170
|
+
this.emit("stateChange", "identifying");
|
|
188
171
|
const data = {
|
|
189
172
|
op: Constants_1.GATEWAY_OP_CODES.IDENTIFY,
|
|
190
173
|
d: {
|
|
@@ -201,14 +184,17 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
201
184
|
};
|
|
202
185
|
if (this.options.initialPresence)
|
|
203
186
|
Object.assign(data.d, { presence: this._checkPresenceData(this.options.initialPresence) });
|
|
204
|
-
return
|
|
187
|
+
return this.betterWs.sendMessage(data);
|
|
205
188
|
}
|
|
206
189
|
/**
|
|
207
190
|
* Send an OP 6 RESUME to the gateway.
|
|
208
191
|
*/
|
|
209
192
|
async resume() {
|
|
210
|
-
|
|
211
|
-
|
|
193
|
+
if (this.betterWs.status !== 1)
|
|
194
|
+
void this.client.emit("debug", "Client was attempting to resume when the ws was not open");
|
|
195
|
+
this.status = "resuming";
|
|
196
|
+
this.emit("stateChange", "resuming");
|
|
197
|
+
return this.betterWs.sendMessage({
|
|
212
198
|
op: Constants_1.GATEWAY_OP_CODES.RESUME,
|
|
213
199
|
d: { seq: this.seq, token: this.options.token, session_id: this.sessionId }
|
|
214
200
|
});
|
|
@@ -217,10 +203,9 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
217
203
|
* Send an OP 1 HEARTBEAT to the gateway.
|
|
218
204
|
*/
|
|
219
205
|
heartbeat() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
(_b = this.betterWs) === null || _b === void 0 ? void 0 : _b.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.HEARTBEAT, d: this.seq });
|
|
206
|
+
if (this.betterWs.status !== 1)
|
|
207
|
+
void this.client.emit("debug", "Client was attempting to heartbeat when the ws was not open");
|
|
208
|
+
this.betterWs.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.HEARTBEAT, d: this.seq });
|
|
224
209
|
this.lastHeartbeatSend = Date.now();
|
|
225
210
|
}
|
|
226
211
|
/**
|
|
@@ -231,10 +216,10 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
231
216
|
switch (message.t) {
|
|
232
217
|
case "READY":
|
|
233
218
|
case "RESUMED":
|
|
234
|
-
if (message.t === "READY")
|
|
219
|
+
if (message.t === "READY")
|
|
235
220
|
this.sessionId = message.d.session_id;
|
|
236
|
-
}
|
|
237
221
|
this.status = "ready";
|
|
222
|
+
this.emit("stateChange", "ready");
|
|
238
223
|
this._trace = message.d._trace;
|
|
239
224
|
this.emit("ready", message.t === "RESUMED");
|
|
240
225
|
this.emit("event", message);
|
|
@@ -249,94 +234,87 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
249
234
|
* @param reason Close reason if any.
|
|
250
235
|
*/
|
|
251
236
|
handleWsClose(code, reason) {
|
|
252
|
-
var _a;
|
|
253
237
|
let gracefulClose = false;
|
|
254
238
|
this.status = "disconnected";
|
|
239
|
+
this.emit("stateChange", "disconnected");
|
|
255
240
|
// Disallowed Intents.
|
|
256
|
-
if (code === 4014)
|
|
257
|
-
this.emit("error", "Disallowed Intents, check your client options and application page.");
|
|
258
|
-
}
|
|
241
|
+
if (code === 4014)
|
|
242
|
+
this.client.emit("error", "Disallowed Intents, check your client options and application page.");
|
|
259
243
|
// Invalid Intents.
|
|
260
|
-
if (code === 4013)
|
|
261
|
-
this.emit("error", "Invalid Intents data, check your client options.");
|
|
262
|
-
}
|
|
244
|
+
if (code === 4013)
|
|
245
|
+
this.client.emit("error", "Invalid Intents data, check your client options.");
|
|
263
246
|
// Invalid API version.
|
|
264
|
-
if (code === 4012)
|
|
265
|
-
this.emit("error", "Invalid API version.");
|
|
266
|
-
}
|
|
247
|
+
if (code === 4012)
|
|
248
|
+
this.client.emit("error", "Invalid API version.");
|
|
267
249
|
// Sharding required.
|
|
268
|
-
if (code === 4011)
|
|
269
|
-
this.emit("error", "Shard would be on over 2500 guilds. Add more shards.");
|
|
270
|
-
}
|
|
250
|
+
if (code === 4011)
|
|
251
|
+
this.client.emit("error", "Shard would be on over 2500 guilds. Add more shards.");
|
|
271
252
|
// Invalid shard.
|
|
272
|
-
if (code === 4010)
|
|
273
|
-
this.emit("error", "Invalid sharding data, check your client options.");
|
|
274
|
-
}
|
|
253
|
+
if (code === 4010)
|
|
254
|
+
this.client.emit("error", "Invalid sharding data, check your client options.");
|
|
275
255
|
// Session timed out.
|
|
276
256
|
// force identify if the session is marked as invalid.
|
|
277
257
|
if (code === 4009) {
|
|
278
|
-
this.emit("error", "Session timed out.");
|
|
258
|
+
this.client.emit("error", "Session timed out.");
|
|
279
259
|
this.clearHeartBeat();
|
|
280
260
|
this.connect();
|
|
281
261
|
}
|
|
282
262
|
// Rate limited.
|
|
283
263
|
if (code === 4008) {
|
|
284
|
-
this.emit("error", "You are being rate limited. Wait before sending more packets.");
|
|
264
|
+
this.client.emit("error", "You are being rate limited. Wait before sending more packets.");
|
|
285
265
|
this.clearHeartBeat();
|
|
286
266
|
this.connect();
|
|
287
267
|
}
|
|
288
268
|
// Invalid sequence.
|
|
289
269
|
if (code === 4007) {
|
|
290
|
-
this.emit("error", "Invalid sequence. Reconnecting and starting a new session.");
|
|
270
|
+
this.client.emit("error", "Invalid sequence. Reconnecting and starting a new session.");
|
|
291
271
|
this.reset();
|
|
292
272
|
this.connect();
|
|
293
273
|
}
|
|
294
274
|
// Already authenticated.
|
|
295
275
|
if (code === 4005) {
|
|
296
|
-
this.emit("error", "You sent more than one OP 2 IDENTIFY payload while the websocket was open.");
|
|
276
|
+
this.client.emit("error", "You sent more than one OP 2 IDENTIFY payload while the websocket was open.");
|
|
297
277
|
this.clearHeartBeat();
|
|
298
278
|
this.connect();
|
|
299
279
|
}
|
|
300
280
|
// Authentication failed.
|
|
301
|
-
if (code === 4004)
|
|
302
|
-
this.emit("error", "Tried to connect with an invalid token");
|
|
303
|
-
}
|
|
281
|
+
if (code === 4004)
|
|
282
|
+
this.client.emit("error", "Tried to connect with an invalid token");
|
|
304
283
|
// Not authenticated.
|
|
305
284
|
if (code === 4003) {
|
|
306
|
-
this.emit("error", "You tried to send a packet before sending an OP 2 IDENTIFY or OP 6 RESUME.");
|
|
285
|
+
this.client.emit("error", "You tried to send a packet before sending an OP 2 IDENTIFY or OP 6 RESUME.");
|
|
307
286
|
this.clearHeartBeat();
|
|
308
287
|
this.connect();
|
|
309
288
|
}
|
|
310
289
|
// Decode error.
|
|
311
290
|
if (code === 4002) {
|
|
312
|
-
this.emit("error", "You sent an invalid payload");
|
|
291
|
+
this.client.emit("error", "You sent an invalid payload");
|
|
313
292
|
this.clearHeartBeat();
|
|
314
293
|
this.connect();
|
|
315
294
|
}
|
|
316
295
|
// Invalid opcode.
|
|
317
296
|
if (code === 4001) {
|
|
318
|
-
this.emit("error", "You sent an invalid opcode or invalid payload for an opcode");
|
|
297
|
+
this.client.emit("error", "You sent an invalid opcode or invalid payload for an opcode");
|
|
319
298
|
this.clearHeartBeat();
|
|
320
299
|
this.connect();
|
|
321
300
|
}
|
|
322
301
|
// Generic error / safe self closing code.
|
|
323
302
|
if (code === 4000) {
|
|
324
|
-
if (reconnecting)
|
|
303
|
+
if (reconnecting)
|
|
325
304
|
gracefulClose = true;
|
|
326
|
-
}
|
|
327
305
|
else {
|
|
328
|
-
this.emit("error", "Error code 4000 received. Attempting to resume");
|
|
306
|
+
this.client.emit("error", "Error code 4000 received. Attempting to resume");
|
|
329
307
|
this.clearHeartBeat();
|
|
330
308
|
this.connect();
|
|
331
309
|
}
|
|
332
310
|
}
|
|
333
311
|
// Don't try to reconnect when true
|
|
334
|
-
if (code === 1000 &&
|
|
312
|
+
if (code === 1000 && this._closing)
|
|
335
313
|
gracefulClose = true;
|
|
336
|
-
|
|
314
|
+
this._closing = false;
|
|
337
315
|
if (gracefulClose) {
|
|
338
316
|
this.clearHeartBeat();
|
|
339
|
-
|
|
317
|
+
this.betterWs.removeAllListeners();
|
|
340
318
|
}
|
|
341
319
|
this.emit("disconnect", code, reason, gracefulClose);
|
|
342
320
|
}
|
|
@@ -345,27 +323,23 @@ class DiscordConnector extends events_1.EventEmitter {
|
|
|
345
323
|
* @param data Presence data to send.
|
|
346
324
|
*/
|
|
347
325
|
async presenceUpdate(data) {
|
|
348
|
-
|
|
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) });
|
|
326
|
+
return this.betterWs.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.PRESENCE_UPDATE, d: this._checkPresenceData(data) });
|
|
350
327
|
}
|
|
351
328
|
/**
|
|
352
329
|
* Send an OP 4 VOICE_STATE_UPDATE to the gateway.
|
|
353
330
|
* @param data Voice state update data to send.
|
|
354
331
|
*/
|
|
355
332
|
async voiceStateUpdate(data) {
|
|
356
|
-
|
|
357
|
-
if (!data) {
|
|
333
|
+
if (!data)
|
|
358
334
|
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) });
|
|
335
|
+
return this.betterWs.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.VOICE_STATE_UPDATE, d: this._checkVoiceStateUpdateData(data) });
|
|
361
336
|
}
|
|
362
337
|
/**
|
|
363
338
|
* Send an OP 8 REQUEST_GUILD_MEMBERS to the gateway.
|
|
364
339
|
* @param data Data to send.
|
|
365
340
|
*/
|
|
366
341
|
async requestGuildMembers(data) {
|
|
367
|
-
|
|
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) });
|
|
342
|
+
return this.betterWs.sendMessage({ op: Constants_1.GATEWAY_OP_CODES.REQUEST_GUILD_MEMBERS, d: this._checkRequestGuildMembersData(data) });
|
|
369
343
|
}
|
|
370
344
|
/**
|
|
371
345
|
* Checks presence data and fills in missing elements.
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
|
-
import zlib from "zlib-sync";
|
|
4
|
-
import WebSocket from "ws";
|
|
5
3
|
import RatelimitBucket from "./RatelimitBucket";
|
|
6
4
|
interface BWSEvents {
|
|
7
|
-
error: [Error | string];
|
|
8
5
|
ws_open: [];
|
|
9
6
|
ws_close: [number, string];
|
|
10
7
|
ws_message: [import("../Types").IGatewayMessage];
|
|
@@ -30,58 +27,24 @@ interface BetterWs {
|
|
|
30
27
|
* Helper Class for simplifying the websocket connection to Discord.
|
|
31
28
|
*/
|
|
32
29
|
declare class BetterWs extends EventEmitter {
|
|
33
|
-
|
|
30
|
+
encoding: "etf" | "json";
|
|
31
|
+
compress: boolean;
|
|
32
|
+
address: string;
|
|
33
|
+
options: import("../Types").IClientWSOptions;
|
|
34
34
|
wsBucket: RatelimitBucket;
|
|
35
35
|
presenceBucket: RatelimitBucket;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* Add eventlisteners to a passed websocket connection.
|
|
50
|
-
* @param ws Websocket.
|
|
51
|
-
*/
|
|
52
|
-
private bindWs;
|
|
53
|
-
/**
|
|
54
|
-
* Create a new websocket connection if the old one was closed/destroyed.
|
|
55
|
-
* @param address Address to connect to.
|
|
56
|
-
* @param options Options used by the websocket connection.
|
|
57
|
-
*/
|
|
58
|
-
recreateWs(address: string, options?: import("../Types").IClientWSOptions): void;
|
|
59
|
-
/**
|
|
60
|
-
* Called upon opening of the websocket connection.
|
|
61
|
-
*/
|
|
62
|
-
private onOpen;
|
|
63
|
-
/**
|
|
64
|
-
* Called once a websocket message is received,
|
|
65
|
-
* uncompresses the message using zlib and parses it via Erlpack or JSON.parse.
|
|
66
|
-
* @param message Message received by websocket.
|
|
67
|
-
*/
|
|
68
|
-
private onMessage;
|
|
69
|
-
/**
|
|
70
|
-
* Called when the websocket connection closes for some reason.
|
|
71
|
-
* @param code Websocket close code.
|
|
72
|
-
* @param reason Reason of the close if any.
|
|
73
|
-
*/
|
|
74
|
-
private onClose;
|
|
75
|
-
/**
|
|
76
|
-
* Send a message to the Discord gateway.
|
|
77
|
-
* @param data Data to send.
|
|
78
|
-
*/
|
|
79
|
-
sendMessage(data: any): Promise<void>;
|
|
80
|
-
/**
|
|
81
|
-
* Close the current websocket connection.
|
|
82
|
-
* @param code Websocket close code to use.
|
|
83
|
-
* @param reason Reason of the disconnect.
|
|
84
|
-
*/
|
|
85
|
-
close(code?: number, reason?: string): Promise<void>;
|
|
36
|
+
private _socket;
|
|
37
|
+
private _internal;
|
|
38
|
+
private _connecting;
|
|
39
|
+
constructor(address: string, options: import("../Types").IClientWSOptions);
|
|
40
|
+
get status(): 2 | 3 | 4 | 1;
|
|
41
|
+
connect(): Promise<void>;
|
|
42
|
+
close(code: number, reason?: string): Promise<void>;
|
|
43
|
+
sendMessage(data: import("../Types").IWSMessage): Promise<void>;
|
|
44
|
+
private _write;
|
|
45
|
+
private _onError;
|
|
46
|
+
private _onClose;
|
|
47
|
+
private _onReadable;
|
|
48
|
+
private _processFrame;
|
|
86
49
|
}
|
|
87
50
|
export = BetterWs;
|