teckos-client 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.js +456 -5
- package/dist/index.min.js +1 -0
- package/es/index.js +459 -0
- package/es/index.mjs +1 -0
- package/lib/index.js +484 -0
- package/package.json +61 -46
- package/src/ITeckosClient.js +2 -0
- package/src/ITeckosClient.js.map +1 -0
- package/src/ITeckosClient.ts +3 -3
- package/src/TeckosClient.js +235 -0
- package/src/TeckosClient.js.map +1 -0
- package/src/TeckosClient.ts +40 -32
- package/src/TeckosClientWithJWT.js +63 -0
- package/src/TeckosClientWithJWT.js.map +1 -0
- package/src/TeckosClientWithJWT.ts +8 -10
- package/src/index.js +8 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +3 -3
- package/src/types/ConnectionState.js +9 -0
- package/src/types/ConnectionState.js.map +1 -0
- package/src/types/Options.js +2 -0
- package/src/types/Options.js.map +1 -0
- package/src/types/Packet.js +2 -0
- package/src/types/Packet.js.map +1 -0
- package/src/types/PacketType.js +7 -0
- package/src/types/PacketType.js.map +1 -0
- package/src/types/SocketEvent.js +2 -0
- package/src/types/SocketEvent.js.map +1 -0
- package/src/types/index.js +4 -0
- package/src/types/index.js.map +1 -0
- package/src/util/Converter.js +6 -0
- package/src/util/Converter.js.map +1 -0
- package/src/util/SocketEventEmitter.js +99 -0
- package/src/util/SocketEventEmitter.js.map +1 -0
- package/src/util/formatProdErrorMessage.ts +16 -0
- package/{dist → types}/ITeckosClient.d.ts +3 -3
- package/{dist → types}/TeckosClient.d.ts +6 -6
- package/{dist → types}/TeckosClientWithJWT.d.ts +0 -0
- package/types/index.d.ts +9 -0
- package/{dist → types}/types/ConnectionState.d.ts +0 -0
- package/{dist → types}/types/Options.d.ts +0 -0
- package/{dist → types}/types/Packet.d.ts +0 -0
- package/{dist → types}/types/PacketType.d.ts +0 -0
- package/{dist → types}/types/SocketEvent.d.ts +0 -0
- package/{dist → types}/types/index.d.ts +0 -0
- package/{dist → types}/util/Converter.d.ts +0 -0
- package/{dist → types}/util/SocketEventEmitter.d.ts +1 -1
- package/types/util/formatProdErrorMessage.d.ts +9 -0
- package/dist/index.d.ts +0 -9
- package/dist/teckos-client.cjs.development.js +0 -617
- package/dist/teckos-client.cjs.development.js.map +0 -1
- package/dist/teckos-client.cjs.production.min.js +0 -2
- package/dist/teckos-client.cjs.production.min.js.map +0 -1
- package/dist/teckos-client.esm.js +0 -614
- package/dist/teckos-client.esm.js.map +0 -1
package/lib/index.js
ADDED
@@ -0,0 +1,484 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
4
|
+
|
5
|
+
var IsomorphicWebSocket = require('isomorphic-ws');
|
6
|
+
|
7
|
+
function _interopNamespace(e) {
|
8
|
+
if (e && e.__esModule) return e;
|
9
|
+
var n = Object.create(null);
|
10
|
+
if (e) {
|
11
|
+
Object.keys(e).forEach(function (k) {
|
12
|
+
if (k !== 'default') {
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
15
|
+
enumerable: true,
|
16
|
+
get: function () { return e[k]; }
|
17
|
+
});
|
18
|
+
}
|
19
|
+
});
|
20
|
+
}
|
21
|
+
n["default"] = e;
|
22
|
+
return Object.freeze(n);
|
23
|
+
}
|
24
|
+
|
25
|
+
var IsomorphicWebSocket__namespace = /*#__PURE__*/_interopNamespace(IsomorphicWebSocket);
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js
|
29
|
+
*
|
30
|
+
* Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes
|
31
|
+
* during build.
|
32
|
+
* @param {number} code
|
33
|
+
*/
|
34
|
+
function formatProdErrorMessage(code) {
|
35
|
+
return `Minified Redux error #${code}; visit https://redux.js.org/Errors?code=${code} for the full message or ` + 'use the non-minified dev environment for full errors. ';
|
36
|
+
} // eslint-disable-next-line import/no-default-export
|
37
|
+
|
38
|
+
const enc = new TextEncoder();
|
39
|
+
const dec = new TextDecoder();
|
40
|
+
|
41
|
+
const encodePacket = packet => enc.encode(JSON.stringify(packet));
|
42
|
+
|
43
|
+
const decodePacket = buffer => JSON.parse(dec.decode(buffer).toString());
|
44
|
+
|
45
|
+
class SocketEventEmitter {
|
46
|
+
maxListeners = 50;
|
47
|
+
handlers = {};
|
48
|
+
addListener = (event, listener) => {
|
49
|
+
if (Object.keys(this.handlers).length === this.maxListeners) {
|
50
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : 'Max listeners reached');
|
51
|
+
}
|
52
|
+
|
53
|
+
if (typeof listener !== 'function') {
|
54
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'The given listener is not a function');
|
55
|
+
}
|
56
|
+
|
57
|
+
this.handlers[event] = this.handlers[event] || [];
|
58
|
+
this.handlers[event].push(listener);
|
59
|
+
return this;
|
60
|
+
};
|
61
|
+
once = (event, listener) => {
|
62
|
+
if (Object.keys(this.handlers).length === this.maxListeners) {
|
63
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : 'Max listeners reached');
|
64
|
+
}
|
65
|
+
|
66
|
+
if (typeof listener !== 'function') {
|
67
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(3) : 'The given listener is not a function');
|
68
|
+
}
|
69
|
+
|
70
|
+
this.handlers[event] = this.handlers[event] || [];
|
71
|
+
|
72
|
+
const onceWrapper = () => {
|
73
|
+
listener();
|
74
|
+
this.off(event, onceWrapper);
|
75
|
+
};
|
76
|
+
|
77
|
+
this.handlers[event].push(onceWrapper);
|
78
|
+
return this;
|
79
|
+
};
|
80
|
+
removeListener = (event, listener) => {
|
81
|
+
if (this.handlers[event]) {
|
82
|
+
this.handlers[event] = this.handlers[event].filter(handler => handler !== listener);
|
83
|
+
}
|
84
|
+
|
85
|
+
return this;
|
86
|
+
};
|
87
|
+
off = (event, listener) => this.removeListener(event, listener);
|
88
|
+
removeAllListeners = event => {
|
89
|
+
if (event) {
|
90
|
+
delete this.handlers[event];
|
91
|
+
} else {
|
92
|
+
this.handlers = {};
|
93
|
+
}
|
94
|
+
|
95
|
+
return this;
|
96
|
+
};
|
97
|
+
setMaxListeners = n => {
|
98
|
+
this.maxListeners = n;
|
99
|
+
return this;
|
100
|
+
};
|
101
|
+
getMaxListeners = () => this.maxListeners;
|
102
|
+
listeners = event => {
|
103
|
+
if (this.handlers[event]) {
|
104
|
+
return [...this.handlers[event]];
|
105
|
+
}
|
106
|
+
|
107
|
+
return [];
|
108
|
+
};
|
109
|
+
rawListeners = event => [...this.handlers[event]];
|
110
|
+
listenerCount = event => {
|
111
|
+
if (this.handlers[event]) {
|
112
|
+
return Object.keys(this.handlers[event]).length;
|
113
|
+
}
|
114
|
+
|
115
|
+
return 0;
|
116
|
+
};
|
117
|
+
prependListener = (event, listener) => {
|
118
|
+
if (Object.keys(this.handlers).length === this.maxListeners) {
|
119
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : 'Max listeners reached');
|
120
|
+
}
|
121
|
+
|
122
|
+
this.handlers[event] = this.handlers[event] || [];
|
123
|
+
this.handlers[event].unshift(listener);
|
124
|
+
return this;
|
125
|
+
};
|
126
|
+
prependOnceListener = (event, listener) => {
|
127
|
+
if (Object.keys(this.handlers).length === this.maxListeners) {
|
128
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(2) : 'Max listeners reached');
|
129
|
+
}
|
130
|
+
|
131
|
+
this.handlers[event] = this.handlers[event] || [];
|
132
|
+
|
133
|
+
const onceWrapper = () => {
|
134
|
+
listener();
|
135
|
+
this.off(event, onceWrapper);
|
136
|
+
};
|
137
|
+
|
138
|
+
this.handlers[event].unshift(onceWrapper);
|
139
|
+
return this;
|
140
|
+
};
|
141
|
+
eventNames = () => Object.keys(this.handlers);
|
142
|
+
on = (event, listener) => this.addListener(event, listener);
|
143
|
+
emit = (event, ...args) => {
|
144
|
+
const listeners = this.listeners(event);
|
145
|
+
|
146
|
+
if (listeners.length > 0) {
|
147
|
+
listeners.forEach(listener => {
|
148
|
+
if (listener) listener(args);
|
149
|
+
});
|
150
|
+
return true;
|
151
|
+
}
|
152
|
+
|
153
|
+
return false;
|
154
|
+
};
|
155
|
+
}
|
156
|
+
|
157
|
+
exports.PacketType = void 0;
|
158
|
+
|
159
|
+
(function (PacketType) {
|
160
|
+
PacketType[PacketType["EVENT"] = 0] = "EVENT";
|
161
|
+
PacketType[PacketType["ACK"] = 1] = "ACK";
|
162
|
+
})(exports.PacketType || (exports.PacketType = {}));
|
163
|
+
|
164
|
+
exports.ConnectionState = void 0;
|
165
|
+
|
166
|
+
(function (ConnectionState) {
|
167
|
+
ConnectionState["DISCONNECTED"] = "disconnected";
|
168
|
+
ConnectionState["CONNECTING"] = "connecting";
|
169
|
+
ConnectionState["CONNECTED"] = "connected";
|
170
|
+
ConnectionState["DISCONNECTING"] = "disconnecting";
|
171
|
+
})(exports.ConnectionState || (exports.ConnectionState = {}));
|
172
|
+
|
173
|
+
const DEFAULT_OPTIONS = {
|
174
|
+
reconnection: true,
|
175
|
+
reconnectionDelay: 1000,
|
176
|
+
reconnectionDelayMax: 5000,
|
177
|
+
reconnectionAttempts: Infinity,
|
178
|
+
randomizationFactor: 0.5,
|
179
|
+
timeout: 5000,
|
180
|
+
debug: false
|
181
|
+
};
|
182
|
+
|
183
|
+
class TeckosClient extends SocketEventEmitter {
|
184
|
+
url;
|
185
|
+
options;
|
186
|
+
ws;
|
187
|
+
currentReconnectDelay;
|
188
|
+
currentReconnectionAttempts = 0;
|
189
|
+
acks = new Map();
|
190
|
+
fnId = 0;
|
191
|
+
connectionTimeout;
|
192
|
+
reconnectionTimeout;
|
193
|
+
|
194
|
+
constructor(url, options) {
|
195
|
+
super();
|
196
|
+
this.options = { ...DEFAULT_OPTIONS,
|
197
|
+
...options
|
198
|
+
};
|
199
|
+
this.currentReconnectDelay = this.options.reconnectionDelay;
|
200
|
+
this.url = url;
|
201
|
+
}
|
202
|
+
|
203
|
+
attachHandler = () => {
|
204
|
+
if (this.ws) {
|
205
|
+
this.ws.onopen = this.handleOpen;
|
206
|
+
this.ws.onerror = this.handleError;
|
207
|
+
this.ws.onclose = this.handleClose;
|
208
|
+
this.ws.onmessage = this.handleMessage;
|
209
|
+
}
|
210
|
+
};
|
211
|
+
|
212
|
+
get webSocket() {
|
213
|
+
return this.ws;
|
214
|
+
}
|
215
|
+
|
216
|
+
connect = () => {
|
217
|
+
if (this.options.debug) console.log(`(teckos:client) Connecting to ${this.url}...`); // This will try to connect immediately
|
218
|
+
// eslint-disable-next-line new-cap
|
219
|
+
|
220
|
+
this.ws = new IsomorphicWebSocket__namespace.WebSocket(this.url); // Attach handlers
|
221
|
+
|
222
|
+
this.attachHandler(); // Handle timeout
|
223
|
+
|
224
|
+
this.connectionTimeout = setTimeout(() => {
|
225
|
+
if (this.ws && this.ws.readyState === 0
|
226
|
+
/* = CONNECTING */
|
227
|
+
) {
|
228
|
+
this.ws.close();
|
229
|
+
}
|
230
|
+
}, this.options.timeout);
|
231
|
+
};
|
232
|
+
reconnect = () => {
|
233
|
+
this.listeners('reconnect_attempt').forEach(listener => listener());
|
234
|
+
this.connect();
|
235
|
+
};
|
236
|
+
|
237
|
+
getConnectionState() {
|
238
|
+
if (this.ws) {
|
239
|
+
switch (this.ws.readyState) {
|
240
|
+
case 0
|
241
|
+
/* = CONNECTING */
|
242
|
+
:
|
243
|
+
return exports.ConnectionState.CONNECTING;
|
244
|
+
|
245
|
+
case 1
|
246
|
+
/* = OPEN */
|
247
|
+
:
|
248
|
+
return exports.ConnectionState.CONNECTED;
|
249
|
+
|
250
|
+
case 2
|
251
|
+
/* = CLOSING */
|
252
|
+
:
|
253
|
+
return exports.ConnectionState.DISCONNECTING;
|
254
|
+
|
255
|
+
default:
|
256
|
+
/* 3 = CLOSED */
|
257
|
+
return exports.ConnectionState.DISCONNECTED;
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
return exports.ConnectionState.DISCONNECTED;
|
262
|
+
}
|
263
|
+
|
264
|
+
get state() {
|
265
|
+
return this.getConnectionState();
|
266
|
+
}
|
267
|
+
|
268
|
+
get connected() {
|
269
|
+
return this.getConnectionState() === exports.ConnectionState.CONNECTED;
|
270
|
+
}
|
271
|
+
|
272
|
+
get disconnected() {
|
273
|
+
return this.getConnectionState() === exports.ConnectionState.DISCONNECTED;
|
274
|
+
}
|
275
|
+
|
276
|
+
emit = (event, ...args) => {
|
277
|
+
args.unshift(event);
|
278
|
+
const packet = {
|
279
|
+
type: exports.PacketType.EVENT,
|
280
|
+
data: args
|
281
|
+
};
|
282
|
+
|
283
|
+
if (typeof args[args.length - 1] === 'function') {
|
284
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
285
|
+
this.acks.set(this.fnId, args.pop());
|
286
|
+
packet.id = this.fnId;
|
287
|
+
this.fnId += 1;
|
288
|
+
}
|
289
|
+
|
290
|
+
return this.sendPackage(packet);
|
291
|
+
};
|
292
|
+
send = (...args) => {
|
293
|
+
args.unshift('message');
|
294
|
+
return this.sendPackage({
|
295
|
+
type: exports.PacketType.EVENT,
|
296
|
+
data: args
|
297
|
+
});
|
298
|
+
};
|
299
|
+
sendPackage = packet => {
|
300
|
+
if (this.ws !== undefined && this.ws.readyState === 1
|
301
|
+
/* = OPEN */
|
302
|
+
) {
|
303
|
+
const buffer = encodePacket(packet);
|
304
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Send packet: ${JSON.stringify(packet)}`);
|
305
|
+
this.ws.send(buffer);
|
306
|
+
return true;
|
307
|
+
}
|
308
|
+
|
309
|
+
return false;
|
310
|
+
};
|
311
|
+
handleMessage = msg => {
|
312
|
+
const packet = typeof msg.data === 'string' ? JSON.parse(msg.data) : decodePacket(msg.data);
|
313
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Got packet: ${JSON.stringify(packet)}`);
|
314
|
+
|
315
|
+
if (packet.type === exports.PacketType.EVENT) {
|
316
|
+
const event = packet.data[0];
|
317
|
+
const args = packet.data.slice(1);
|
318
|
+
|
319
|
+
if (event) {
|
320
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
321
|
+
this.listeners(event).forEach(listener => listener(...args));
|
322
|
+
} else {
|
323
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : `(teckos-client) [${this.url}] Got invalid event message: ${JSON.stringify(msg.data)}`);
|
324
|
+
}
|
325
|
+
} else if (packet.type === exports.PacketType.ACK && packet.id !== undefined) {
|
326
|
+
// Call assigned function
|
327
|
+
const ack = this.acks.get(packet.id);
|
328
|
+
|
329
|
+
if (typeof ack === 'function') {
|
330
|
+
ack.apply(this, packet.data);
|
331
|
+
this.acks.delete(packet.id);
|
332
|
+
}
|
333
|
+
} else {
|
334
|
+
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(1) : `(teckos-client) [${this.url}] Got invalid message type: ${packet.type}`);
|
335
|
+
}
|
336
|
+
};
|
337
|
+
handleOpen = () => {
|
338
|
+
if (this.currentReconnectionAttempts > 0) {
|
339
|
+
// Reset reconnection settings to default
|
340
|
+
this.currentReconnectDelay = this.options.reconnectionDelay;
|
341
|
+
this.currentReconnectionAttempts = 0; // Inform listeners
|
342
|
+
|
343
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Reconnected!`); // eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
344
|
+
|
345
|
+
this.listeners('reconnect').forEach(listener => listener());
|
346
|
+
} // Inform listeners
|
347
|
+
|
348
|
+
|
349
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Connected!`);
|
350
|
+
this.listeners('connect').forEach(listener => listener());
|
351
|
+
};
|
352
|
+
handleError = error => {
|
353
|
+
if (this.handlers && this.handlers.error) {
|
354
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Got error from server: ${JSON.stringify(error)}`);
|
355
|
+
this.handlers.error.forEach(listener => listener(error));
|
356
|
+
}
|
357
|
+
};
|
358
|
+
handleClose = () => {
|
359
|
+
// Stop connection timeout
|
360
|
+
if (this.connectionTimeout) {
|
361
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
362
|
+
clearTimeout(this.connectionTimeout);
|
363
|
+
} // Stop reconnection timeout
|
364
|
+
|
365
|
+
|
366
|
+
if (this.reconnectionTimeout) {
|
367
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
368
|
+
clearTimeout(this.reconnectionTimeout);
|
369
|
+
} // Inform listeners
|
370
|
+
|
371
|
+
|
372
|
+
if (this.currentReconnectionAttempts > 0) {
|
373
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Reconnect #${this.currentReconnectionAttempts} failed!`);
|
374
|
+
this.listeners('reconnect_error').forEach(listener => {
|
375
|
+
if (listener) listener();
|
376
|
+
});
|
377
|
+
} else {
|
378
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Disconnected!`);
|
379
|
+
this.listeners('disconnect').forEach(listener => {
|
380
|
+
if (listener) listener();
|
381
|
+
});
|
382
|
+
}
|
383
|
+
|
384
|
+
if (this.options.reconnection) {
|
385
|
+
// Apply reconnection logic
|
386
|
+
this.currentReconnectionAttempts += 1;
|
387
|
+
|
388
|
+
if (this.options.reconnectionAttempts === Infinity || this.currentReconnectionAttempts <= this.options.reconnectionAttempts) {
|
389
|
+
const timeout = Math.min(this.options.reconnectionDelayMax, this.currentReconnectDelay); // Increase reconnection delay
|
390
|
+
|
391
|
+
this.currentReconnectDelay = Math.round(this.currentReconnectDelay + this.currentReconnectDelay * this.options.randomizationFactor);
|
392
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Try reconnecting (${this.currentReconnectionAttempts}/${this.options.reconnectionAttempts}) in ${timeout}ms to ${this.url}...`);
|
393
|
+
this.reconnectionTimeout = setTimeout(() => {
|
394
|
+
this.reconnect();
|
395
|
+
}, timeout);
|
396
|
+
} else {
|
397
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Reconnection maximum of ${this.options.reconnectionAttempts} reached`);
|
398
|
+
this.listeners('reconnect_failed').forEach(listener => listener());
|
399
|
+
}
|
400
|
+
}
|
401
|
+
};
|
402
|
+
close = () => {
|
403
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Closing connection (client-side)`);
|
404
|
+
|
405
|
+
if (this.ws !== undefined) {
|
406
|
+
this.ws.onclose = () => {};
|
407
|
+
|
408
|
+
this.ws.close();
|
409
|
+
this.listeners('disconnect').forEach(listener => listener());
|
410
|
+
}
|
411
|
+
};
|
412
|
+
disconnect = () => {
|
413
|
+
this.close();
|
414
|
+
};
|
415
|
+
}
|
416
|
+
|
417
|
+
/* eslint-disable no-console */
|
418
|
+
|
419
|
+
class TeckosClientWithJWT extends TeckosClient {
|
420
|
+
token;
|
421
|
+
initialData;
|
422
|
+
receivedReady = false; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
423
|
+
|
424
|
+
constructor(url, options, token, initialData) {
|
425
|
+
super(url, options);
|
426
|
+
this.token = token; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
427
|
+
|
428
|
+
this.initialData = initialData;
|
429
|
+
this.on('disconnect', () => {
|
430
|
+
this.receivedReady = false;
|
431
|
+
});
|
432
|
+
}
|
433
|
+
|
434
|
+
getConnectionState() {
|
435
|
+
if (this.ws) {
|
436
|
+
switch (this.ws.readyState) {
|
437
|
+
case IsomorphicWebSocket__namespace.WebSocket.OPEN:
|
438
|
+
if (this.receivedReady) {
|
439
|
+
return exports.ConnectionState.CONNECTED;
|
440
|
+
}
|
441
|
+
|
442
|
+
return exports.ConnectionState.CONNECTING;
|
443
|
+
|
444
|
+
case IsomorphicWebSocket__namespace.WebSocket.CONNECTING:
|
445
|
+
return exports.ConnectionState.CONNECTING;
|
446
|
+
|
447
|
+
case IsomorphicWebSocket__namespace.WebSocket.CLOSING:
|
448
|
+
return exports.ConnectionState.DISCONNECTING;
|
449
|
+
|
450
|
+
default:
|
451
|
+
return exports.ConnectionState.DISCONNECTED;
|
452
|
+
}
|
453
|
+
}
|
454
|
+
|
455
|
+
return exports.ConnectionState.DISCONNECTED;
|
456
|
+
}
|
457
|
+
|
458
|
+
handleReadyEvent = () => {
|
459
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Connected!`);
|
460
|
+
this.receivedReady = true;
|
461
|
+
|
462
|
+
if (this.currentReconnectionAttempts > 0) {
|
463
|
+
if (this.options.debug) console.log(`(teckos:client) [${this.url}] Reconnected!`);
|
464
|
+
this.listeners('reconnect').forEach(listener => listener()); // Reset reconnection settings to default
|
465
|
+
|
466
|
+
this.currentReconnectDelay = this.options.reconnectionDelay;
|
467
|
+
this.currentReconnectionAttempts = 0;
|
468
|
+
}
|
469
|
+
|
470
|
+
this.listeners('connect').forEach(listener => listener());
|
471
|
+
};
|
472
|
+
handleOpen = () => {
|
473
|
+
this.receivedReady = false;
|
474
|
+
this.once('ready', this.handleReadyEvent);
|
475
|
+
if (this.options.debug) console.log(`(teckos:client) Connection opened, sending token now`);
|
476
|
+
this.emit('token', {
|
477
|
+
token: this.token,
|
478
|
+
...this.initialData
|
479
|
+
});
|
480
|
+
};
|
481
|
+
}
|
482
|
+
|
483
|
+
exports.TeckosClient = TeckosClient;
|
484
|
+
exports.TeckosClientWithJWT = TeckosClientWithJWT;
|
package/package.json
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
{
|
2
|
-
"version": "0.
|
2
|
+
"version": "0.3.0",
|
3
3
|
"license": "MIT",
|
4
|
-
"main": "
|
5
|
-
"
|
4
|
+
"main": "lib/teckos-client.js",
|
5
|
+
"unpkg": "dist/teckos-client.js",
|
6
|
+
"module": "es/teckos-client.js",
|
7
|
+
"types": "types/index.d.ts",
|
6
8
|
"files": [
|
7
9
|
"dist",
|
8
|
-
"
|
10
|
+
"lib",
|
11
|
+
"es",
|
12
|
+
"src",
|
13
|
+
"types"
|
9
14
|
],
|
10
|
-
"engines": {
|
11
|
-
"node": ">=10"
|
12
|
-
},
|
13
15
|
"keywords": [
|
14
16
|
"websocket",
|
15
17
|
"uwebsocket",
|
@@ -17,15 +19,15 @@
|
|
17
19
|
"callbacks"
|
18
20
|
],
|
19
21
|
"scripts": {
|
22
|
+
"clean": "rimraf lib dist es coverage types",
|
20
23
|
"dev:web": "webpack serve --config webpack.config.example.web.js",
|
21
24
|
"dev:node": "DEBUG=example*,teckos* nodemon --watch './src/**/*.ts,./example/node/**/*.ts' --exec 'ts-node' --project tsconfig.example.node.json example/node/index.ts",
|
22
25
|
"build:example:web": "npm run build && webpack --config webpack.config.example.web.js",
|
23
26
|
"build:example:node": "npm run build && tsc --p tsconfig.example.node.json",
|
24
|
-
"
|
25
|
-
"build": "
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"prepare": "tsdx build",
|
27
|
+
"check-types": "tsc --noEmit",
|
28
|
+
"build": "rollup -c",
|
29
|
+
"lint": "eslint --ext js,ts src",
|
30
|
+
"test": "NODE_OPTIONS=--experimental-vm-modules npx jest",
|
29
31
|
"size": "size-limit",
|
30
32
|
"analyze": "size-limit --why"
|
31
33
|
},
|
@@ -52,7 +54,6 @@
|
|
52
54
|
"bugs": {
|
53
55
|
"url": "https://github.com/delude88/teckos-client/issues"
|
54
56
|
},
|
55
|
-
"module": "dist/teckos-client.esm.js",
|
56
57
|
"size-limit": [
|
57
58
|
{
|
58
59
|
"path": "dist/teckos-client.cjs.production.min.js",
|
@@ -64,52 +65,66 @@
|
|
64
65
|
}
|
65
66
|
],
|
66
67
|
"devDependencies": {
|
67
|
-
"@babel/
|
68
|
-
"@babel/
|
69
|
-
"@babel/
|
68
|
+
"@babel/cli": "^7.17.10",
|
69
|
+
"@babel/core": "^7.18.5",
|
70
|
+
"@babel/eslint-parser": "^7.18.2",
|
71
|
+
"@babel/node": "^7.18.5",
|
72
|
+
"@babel/plugin-external-helpers": "^7.17.12",
|
73
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.18.0",
|
74
|
+
"@babel/plugin-transform-runtime": "^7.18.5",
|
75
|
+
"@babel/preset-env": "^7.18.2",
|
76
|
+
"@babel/preset-flow": "^7.17.12",
|
77
|
+
"@babel/preset-typescript": "^7.17.12",
|
78
|
+
"@babel/register": "^7.17.7",
|
79
|
+
"@rollup/plugin-babel": "^5.3.1",
|
80
|
+
"@rollup/plugin-node-resolve": "^13.3.0",
|
81
|
+
"@rollup/plugin-replace": "^4.0.0",
|
70
82
|
"@size-limit/preset-small-lib": "^7.0.8",
|
71
|
-
"@types/
|
72
|
-
"@types/
|
73
|
-
"@types/mocha": "^9.1.0",
|
74
|
-
"@types/node": "^17.0.23",
|
83
|
+
"@types/jest": "^28.1.3",
|
84
|
+
"@types/node": "^18.0.0",
|
75
85
|
"@types/ws": "^8.5.3",
|
76
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
77
|
-
"@typescript-eslint/parser": "^5.
|
86
|
+
"@typescript-eslint/eslint-plugin": "^5.29.0",
|
87
|
+
"@typescript-eslint/parser": "^5.29.0",
|
78
88
|
"babel-eslint": "^10.1.0",
|
79
|
-
"
|
89
|
+
"babel-jest": "^28.1.1",
|
80
90
|
"clean-webpack-plugin": "^4.0.0",
|
81
|
-
"
|
91
|
+
"cross-env": "^7.0.3",
|
92
|
+
"eslint": "^8.18.0",
|
82
93
|
"eslint-config-airbnb-base": "^15.0.0",
|
83
|
-
"eslint-config-airbnb-typescript": "^
|
94
|
+
"eslint-config-airbnb-typescript": "^17.0.0",
|
84
95
|
"eslint-config-prettier": "^8.5.0",
|
85
|
-
"eslint-config-react-app": "^7.0.
|
96
|
+
"eslint-config-react-app": "^7.0.1",
|
86
97
|
"eslint-plugin-flowtype": "^8.0.3",
|
87
|
-
"eslint-plugin-import": "^2.
|
98
|
+
"eslint-plugin-import": "^2.26.0",
|
88
99
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
89
100
|
"eslint-plugin-prettier": "^4.0.0",
|
90
101
|
"eslint-plugin-promise": "^6.0.0",
|
91
|
-
"eslint-plugin-react": "^7.
|
92
|
-
"eslint-plugin-react-hooks": "^4.
|
102
|
+
"eslint-plugin-react": "^7.30.0",
|
103
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
104
|
+
"glob": "^8.0.3",
|
93
105
|
"html-webpack-plugin": "^5.5.0",
|
94
|
-
"husky": "^
|
95
|
-
"ioredis": "^5.0.
|
96
|
-
"
|
97
|
-
"nodemon": "^2.0.
|
98
|
-
"prettier": "^2.
|
106
|
+
"husky": "^8.0.1",
|
107
|
+
"ioredis": "^5.0.6",
|
108
|
+
"jest": "^28.1.1",
|
109
|
+
"nodemon": "^2.0.18",
|
110
|
+
"prettier": "^2.7.1",
|
111
|
+
"rimraf": "^3.0.2",
|
112
|
+
"rollup": "^2.75.7",
|
113
|
+
"rollup-plugin-terser": "^7.0.2",
|
114
|
+
"rollup-plugin-typescript2": "^0.32.1",
|
99
115
|
"size-limit": "^7.0.8",
|
100
|
-
"teckos": "^0.
|
101
|
-
"ts-
|
102
|
-
"ts-node": "^10.
|
103
|
-
"
|
104
|
-
"
|
105
|
-
"
|
106
|
-
"webpack": "^
|
107
|
-
"
|
108
|
-
"webpack-dev-server": "^4.7.4",
|
109
|
-
"ws": "^8.5.0"
|
116
|
+
"teckos": "^0.9.6",
|
117
|
+
"ts-jest": "^28.0.5",
|
118
|
+
"ts-node": "^10.8.1",
|
119
|
+
"typescript": "^4.7.4",
|
120
|
+
"webpack": "^5.73.0",
|
121
|
+
"webpack-cli": "^4.10.0",
|
122
|
+
"webpack-dev-server": "^4.9.2",
|
123
|
+
"ws": "^8.8.0"
|
110
124
|
},
|
111
125
|
"dependencies": {
|
112
|
-
"
|
126
|
+
"@babel/runtime": "^7.18.3",
|
113
127
|
"isomorphic-ws": "^4.0.1"
|
114
|
-
}
|
128
|
+
},
|
129
|
+
"sideEffects": false
|
115
130
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ITeckosClient.js","sourceRoot":"","sources":["ITeckosClient.ts"],"names":[],"mappings":""}
|
package/src/ITeckosClient.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import
|
1
|
+
import * as IsomorphicWebSocket from 'isomorphic-ws'
|
2
2
|
import { ConnectionState, Packet, SocketEvent } from './types'
|
3
3
|
import { SocketEventEmitter } from './util/SocketEventEmitter'
|
4
4
|
|
5
5
|
interface ITeckosClient extends SocketEventEmitter<SocketEvent> {
|
6
|
-
ws: WebSocket | undefined
|
7
|
-
readonly webSocket: WebSocket | undefined
|
6
|
+
ws: IsomorphicWebSocket.WebSocket | undefined
|
7
|
+
readonly webSocket: IsomorphicWebSocket.WebSocket | undefined
|
8
8
|
readonly state: ConnectionState
|
9
9
|
readonly connected: boolean
|
10
10
|
readonly disconnected: boolean
|