teckos-client 0.3.3 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/dist/ITeckosClient.d.ts +18 -0
  2. package/dist/TeckosClient.d.ts +35 -0
  3. package/dist/TeckosClientWithJWT.d.ts +12 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.js +40 -43
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.min.js +1 -1
  8. package/dist/teckos-client.cjs.development.js +611 -0
  9. package/dist/teckos-client.cjs.development.js.map +1 -0
  10. package/dist/teckos-client.cjs.production.min.js +2 -0
  11. package/dist/teckos-client.cjs.production.min.js.map +1 -0
  12. package/dist/teckos-client.esm.js +608 -0
  13. package/dist/teckos-client.esm.js.map +1 -0
  14. package/dist/types/ConnectionState.d.ts +7 -0
  15. package/dist/types/Options.d.ts +10 -0
  16. package/dist/types/Packet.d.ts +6 -0
  17. package/dist/types/PacketType.d.ts +5 -0
  18. package/dist/types/SocketEvent.d.ts +10 -0
  19. package/dist/types/index.d.ts +7 -0
  20. package/dist/util/Converter.d.ts +4 -0
  21. package/dist/util/SocketEventEmitter.d.ts +23 -0
  22. package/es/index.js +34 -39
  23. package/es/index.mjs +1 -1
  24. package/lib/index.js +37 -58
  25. package/package.json +6 -7
  26. package/src/ITeckosClient.ts +2 -3
  27. package/src/TeckosClient.ts +29 -29
  28. package/src/TeckosClientWithJWT.ts +6 -6
  29. package/src/index.ts +3 -3
  30. package/types/ITeckosClient.d.ts +2 -3
  31. package/types/TeckosClient.d.ts +5 -5
  32. package/types/index.d.ts +3 -3
  33. package/src/ITeckosClient.js +0 -2
  34. package/src/ITeckosClient.js.map +0 -1
  35. package/src/TeckosClient.js +0 -235
  36. package/src/TeckosClient.js.map +0 -1
  37. package/src/TeckosClientWithJWT.js +0 -63
  38. package/src/TeckosClientWithJWT.js.map +0 -1
  39. package/src/index.js +0 -8
  40. package/src/index.js.map +0 -1
  41. package/src/types/ConnectionState.js +0 -9
  42. package/src/types/ConnectionState.js.map +0 -1
  43. package/src/types/Options.js +0 -2
  44. package/src/types/Options.js.map +0 -1
  45. package/src/types/Packet.js +0 -2
  46. package/src/types/Packet.js.map +0 -1
  47. package/src/types/PacketType.js +0 -7
  48. package/src/types/PacketType.js.map +0 -1
  49. package/src/types/SocketEvent.js +0 -2
  50. package/src/types/SocketEvent.js.map +0 -1
  51. package/src/types/index.js +0 -4
  52. package/src/types/index.js.map +0 -1
  53. package/src/util/Converter.js +0 -6
  54. package/src/util/Converter.js.map +0 -1
  55. package/src/util/SocketEventEmitter.js +0 -99
  56. package/src/util/SocketEventEmitter.js.map +0 -1
@@ -0,0 +1,611 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
+
7
+ var debug = _interopDefault(require('debug'));
8
+ var WebSocket = _interopDefault(require('isomorphic-ws'));
9
+
10
+ function _defineProperties(target, props) {
11
+ for (var i = 0; i < props.length; i++) {
12
+ var descriptor = props[i];
13
+ descriptor.enumerable = descriptor.enumerable || false;
14
+ descriptor.configurable = true;
15
+ if ("value" in descriptor) descriptor.writable = true;
16
+ Object.defineProperty(target, descriptor.key, descriptor);
17
+ }
18
+ }
19
+
20
+ function _createClass(Constructor, protoProps, staticProps) {
21
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
22
+ if (staticProps) _defineProperties(Constructor, staticProps);
23
+ return Constructor;
24
+ }
25
+
26
+ function _extends() {
27
+ _extends = Object.assign || function (target) {
28
+ for (var i = 1; i < arguments.length; i++) {
29
+ var source = arguments[i];
30
+
31
+ for (var key in source) {
32
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
33
+ target[key] = source[key];
34
+ }
35
+ }
36
+ }
37
+
38
+ return target;
39
+ };
40
+
41
+ return _extends.apply(this, arguments);
42
+ }
43
+
44
+ function _inheritsLoose(subClass, superClass) {
45
+ subClass.prototype = Object.create(superClass.prototype);
46
+ subClass.prototype.constructor = subClass;
47
+
48
+ _setPrototypeOf(subClass, superClass);
49
+ }
50
+
51
+ function _setPrototypeOf(o, p) {
52
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
53
+ o.__proto__ = p;
54
+ return o;
55
+ };
56
+
57
+ return _setPrototypeOf(o, p);
58
+ }
59
+
60
+ function _assertThisInitialized(self) {
61
+ if (self === void 0) {
62
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
63
+ }
64
+
65
+ return self;
66
+ }
67
+
68
+ var enc = /*#__PURE__*/new TextEncoder();
69
+ var dec = /*#__PURE__*/new TextDecoder();
70
+
71
+ var encodePacket = function encodePacket(packet) {
72
+ return enc.encode(JSON.stringify(packet));
73
+ };
74
+
75
+ var decodePacket = function decodePacket(buffer) {
76
+ return JSON.parse(dec.decode(buffer).toString());
77
+ };
78
+
79
+ (function (PacketType) {
80
+ PacketType[PacketType["EVENT"] = 0] = "EVENT";
81
+ PacketType[PacketType["ACK"] = 1] = "ACK";
82
+ })(exports.PacketType || (exports.PacketType = {}));
83
+
84
+ (function (ConnectionState) {
85
+ ConnectionState["DISCONNECTED"] = "disconnected";
86
+ ConnectionState["CONNECTING"] = "connecting";
87
+ ConnectionState["CONNECTED"] = "connected";
88
+ ConnectionState["DISCONNECTING"] = "disconnecting";
89
+ })(exports.ConnectionState || (exports.ConnectionState = {}));
90
+
91
+ var SocketEventEmitter = function SocketEventEmitter() {
92
+ var _this = this;
93
+
94
+ this.maxListeners = 50;
95
+ this.handlers = {};
96
+
97
+ this.addListener = function (event, listener) {
98
+ if (Object.keys(_this.handlers).length === _this.maxListeners) {
99
+ throw new Error('Max listeners reached');
100
+ }
101
+
102
+ if (typeof listener !== 'function') {
103
+ throw new Error('The given listener is not a function');
104
+ }
105
+
106
+ _this.handlers[event] = _this.handlers[event] || [];
107
+
108
+ _this.handlers[event].push(listener);
109
+
110
+ return _this;
111
+ };
112
+
113
+ this.once = function (event, listener) {
114
+ if (Object.keys(_this.handlers).length === _this.maxListeners) {
115
+ throw new Error('Max listeners reached');
116
+ }
117
+
118
+ if (typeof listener !== 'function') {
119
+ throw new Error('The given listener is not a function');
120
+ }
121
+
122
+ _this.handlers[event] = _this.handlers[event] || [];
123
+
124
+ var onceWrapper = function onceWrapper() {
125
+ listener();
126
+
127
+ _this.off(event, onceWrapper);
128
+ };
129
+
130
+ _this.handlers[event].push(onceWrapper);
131
+
132
+ return _this;
133
+ };
134
+
135
+ this.removeListener = function (event, listener) {
136
+ if (_this.handlers[event]) {
137
+ _this.handlers[event] = _this.handlers[event].filter(function (handler) {
138
+ return handler !== listener;
139
+ });
140
+ }
141
+
142
+ return _this;
143
+ };
144
+
145
+ this.off = function (event, listener) {
146
+ return _this.removeListener(event, listener);
147
+ };
148
+
149
+ this.removeAllListeners = function (event) {
150
+ if (event) {
151
+ delete _this.handlers[event];
152
+ } else {
153
+ _this.handlers = {};
154
+ }
155
+
156
+ return _this;
157
+ };
158
+
159
+ this.setMaxListeners = function (n) {
160
+ _this.maxListeners = n;
161
+ return _this;
162
+ };
163
+
164
+ this.getMaxListeners = function () {
165
+ return _this.maxListeners;
166
+ };
167
+
168
+ this.listeners = function (event) {
169
+ if (_this.handlers[event]) {
170
+ return [].concat(_this.handlers[event]);
171
+ }
172
+
173
+ return [];
174
+ };
175
+
176
+ this.rawListeners = function (event) {
177
+ return [].concat(_this.handlers[event]);
178
+ };
179
+
180
+ this.listenerCount = function (event) {
181
+ if (_this.handlers[event]) {
182
+ return Object.keys(_this.handlers[event]).length;
183
+ }
184
+
185
+ return 0;
186
+ };
187
+
188
+ this.prependListener = function (event, listener) {
189
+ if (Object.keys(_this.handlers).length === _this.maxListeners) {
190
+ throw new Error('Max listeners reached');
191
+ }
192
+
193
+ _this.handlers[event] = _this.handlers[event] || [];
194
+
195
+ _this.handlers[event].unshift(listener);
196
+
197
+ return _this;
198
+ };
199
+
200
+ this.prependOnceListener = function (event, listener) {
201
+ if (Object.keys(_this.handlers).length === _this.maxListeners) {
202
+ throw new Error('Max listeners reached');
203
+ }
204
+
205
+ _this.handlers[event] = _this.handlers[event] || [];
206
+
207
+ var onceWrapper = function onceWrapper() {
208
+ listener();
209
+
210
+ _this.off(event, onceWrapper);
211
+ };
212
+
213
+ _this.handlers[event].unshift(onceWrapper);
214
+
215
+ return _this;
216
+ };
217
+
218
+ this.eventNames = function () {
219
+ return Object.keys(_this.handlers);
220
+ };
221
+
222
+ this.on = function (event, listener) {
223
+ return _this.addListener(event, listener);
224
+ };
225
+
226
+ this.emit = function (event) {
227
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
228
+ args[_key - 1] = arguments[_key];
229
+ }
230
+
231
+ var listeners = _this.listeners(event);
232
+
233
+ if (listeners.length > 0) {
234
+ listeners.forEach(function (listener) {
235
+ if (listener) listener(args);
236
+ });
237
+ return true;
238
+ }
239
+
240
+ return false;
241
+ };
242
+ };
243
+
244
+ var d = /*#__PURE__*/debug('teckos:client');
245
+ var DEFAULT_OPTIONS = {
246
+ reconnection: true,
247
+ reconnectionDelay: 1000,
248
+ reconnectionDelayMax: 5000,
249
+ reconnectionAttempts: Infinity,
250
+ randomizationFactor: 0.5,
251
+ timeout: 5000,
252
+ debug: false
253
+ };
254
+
255
+ var TeckosClient = /*#__PURE__*/function (_SocketEventEmitter) {
256
+ _inheritsLoose(TeckosClient, _SocketEventEmitter);
257
+
258
+ function TeckosClient(url, options) {
259
+ var _this;
260
+
261
+ _this = _SocketEventEmitter.call(this) || this;
262
+ _this.currentReconnectionAttempts = 0;
263
+ _this.acks = new Map();
264
+ _this.fnId = 0;
265
+
266
+ _this.attachHandler = function () {
267
+ if (_this.ws) {
268
+ _this.ws.onopen = _this.handleOpen;
269
+ _this.ws.onerror = _this.handleError;
270
+ _this.ws.onclose = _this.handleClose;
271
+ _this.ws.onmessage = _this.handleMessage;
272
+ }
273
+ };
274
+
275
+ _this.connect = function () {
276
+ if (_this.options.debug) d("Connecting to " + _this.url + "..."); // This will try to connect immediately
277
+
278
+ _this.ws = new WebSocket(_this.url); // Attach handlers
279
+
280
+ _this.attachHandler(); // Handle timeout
281
+
282
+
283
+ _this.connectionTimeout = setTimeout(function () {
284
+ if (_this.ws && _this.ws.readyState === WebSocket.CONNECTING) {
285
+ _this.ws.close();
286
+ }
287
+ }, _this.options.timeout);
288
+ };
289
+
290
+ _this.reconnect = function () {
291
+ _this.listeners('reconnect_attempt').forEach(function (listener) {
292
+ return listener();
293
+ });
294
+
295
+ _this.connect();
296
+ };
297
+
298
+ _this.emit = function (event) {
299
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
300
+ args[_key - 1] = arguments[_key];
301
+ }
302
+
303
+ args.unshift(event);
304
+ var packet = {
305
+ type: exports.PacketType.EVENT,
306
+ data: args
307
+ };
308
+
309
+ if (typeof args[args.length - 1] === 'function') {
310
+ _this.acks.set(_this.fnId, args.pop());
311
+
312
+ packet.id = _this.fnId;
313
+ _this.fnId += 1;
314
+ }
315
+
316
+ return _this.sendPackage(packet);
317
+ };
318
+
319
+ _this.send = function () {
320
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
321
+ args[_key2] = arguments[_key2];
322
+ }
323
+
324
+ args.unshift('message');
325
+ return _this.sendPackage({
326
+ type: exports.PacketType.EVENT,
327
+ data: args
328
+ });
329
+ };
330
+
331
+ _this.sendPackage = function (packet) {
332
+ if (_this.ws !== undefined && _this.ws.readyState === WebSocket.OPEN) {
333
+ var buffer = encodePacket(packet);
334
+ if (_this.options.debug) d("[" + _this.url + "] Send packet: " + JSON.stringify(packet));
335
+
336
+ _this.ws.send(buffer);
337
+
338
+ return true;
339
+ }
340
+
341
+ return false;
342
+ };
343
+
344
+ _this.handleMessage = function (msg) {
345
+ var packet = typeof msg.data === 'string' ? JSON.parse(msg.data) : decodePacket(msg.data);
346
+ if (_this.options.debug) d("[" + _this.url + "] Got packet: " + JSON.stringify(packet));
347
+
348
+ if (packet.type === exports.PacketType.EVENT) {
349
+ var event = packet.data[0];
350
+ var args = packet.data.slice(1);
351
+
352
+ if (event) {
353
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
354
+ _this.listeners(event).forEach(function (listener) {
355
+ return listener.apply(void 0, args);
356
+ });
357
+ } else {
358
+ throw new Error("[teckos-client@" + _this.url + "] Got invalid event message: " + JSON.stringify(msg.data));
359
+ }
360
+ } else if (packet.type === exports.PacketType.ACK && packet.id !== undefined) {
361
+ // Call assigned function
362
+ var ack = _this.acks.get(packet.id);
363
+
364
+ if (typeof ack === 'function') {
365
+ ack.apply(_assertThisInitialized(_this), packet.data);
366
+
367
+ _this.acks["delete"](packet.id);
368
+ }
369
+ } else {
370
+ throw new Error("[teckos-client@" + _this.url + "] Got invalid message type: " + packet.type);
371
+ }
372
+ };
373
+
374
+ _this.handleOpen = function () {
375
+ if (_this.currentReconnectionAttempts > 0) {
376
+ // Reset reconnection settings to default
377
+ _this.currentReconnectDelay = _this.options.reconnectionDelay;
378
+ _this.currentReconnectionAttempts = 0; // Inform listeners
379
+
380
+ if (_this.options.debug) d("[" + _this.url + "] Reconnected!"); // eslint-disable-next-line @typescript-eslint/no-unsafe-return
381
+
382
+ _this.listeners('reconnect').forEach(function (listener) {
383
+ return listener();
384
+ });
385
+ } // Inform listeners
386
+
387
+
388
+ if (_this.options.debug) d("[" + _this.url + "] Connected!");
389
+
390
+ _this.listeners('connect').forEach(function (listener) {
391
+ return listener();
392
+ });
393
+ };
394
+
395
+ _this.handleError = function (error) {
396
+ if (_this.handlers && _this.handlers.error) {
397
+ if (_this.options.debug) d("[" + _this.url + "] Got error from server: " + JSON.stringify(error));
398
+
399
+ _this.handlers.error.forEach(function (listener) {
400
+ return listener(error);
401
+ });
402
+ }
403
+ };
404
+
405
+ _this.handleClose = function () {
406
+ // Stop connection timeout
407
+ if (_this.connectionTimeout) {
408
+ clearTimeout(_this.connectionTimeout);
409
+ } // Stop reconnection timeout
410
+
411
+
412
+ if (_this.reconnectionTimeout) {
413
+ clearTimeout(_this.reconnectionTimeout);
414
+ } // Inform listeners
415
+
416
+
417
+ if (_this.currentReconnectionAttempts > 0) {
418
+ if (_this.options.debug) d("[" + _this.url + "] Reconnect #" + _this.currentReconnectionAttempts + " failed!");
419
+
420
+ _this.listeners('reconnect_error').forEach(function (listener) {
421
+ if (listener) listener();
422
+ });
423
+ } else {
424
+ if (_this.options.debug) d("[" + _this.url + "] Disconnected!");
425
+
426
+ _this.listeners('disconnect').forEach(function (listener) {
427
+ if (listener) listener();
428
+ });
429
+ }
430
+
431
+ if (_this.options.reconnection) {
432
+ // Apply reconnection logic
433
+ _this.currentReconnectionAttempts += 1;
434
+
435
+ if (_this.options.reconnectionAttempts === Infinity || _this.currentReconnectionAttempts <= _this.options.reconnectionAttempts) {
436
+ var timeout = Math.min(_this.options.reconnectionDelayMax, _this.currentReconnectDelay); // Increase reconnection delay
437
+
438
+ _this.currentReconnectDelay = Math.round(_this.currentReconnectDelay + _this.currentReconnectDelay * _this.options.randomizationFactor);
439
+ if (_this.options.debug) d("[" + _this.url + "] Try reconnecting (" + _this.currentReconnectionAttempts + "/" + _this.options.reconnectionAttempts + ") in " + timeout + "ms to " + _this.url + "...");
440
+ _this.reconnectionTimeout = setTimeout(function () {
441
+ _this.reconnect();
442
+ }, timeout);
443
+ } else {
444
+ if (_this.options.debug) d("[" + _this.url + "] Reconnection maximum of " + _this.options.reconnectionAttempts + " reached");
445
+
446
+ _this.listeners('reconnect_failed').forEach(function (listener) {
447
+ return listener();
448
+ });
449
+ }
450
+ }
451
+ };
452
+
453
+ _this.close = function () {
454
+ if (_this.options.debug) d("[" + _this.url + "] Closing connection (client-side)");
455
+
456
+ if (_this.ws !== undefined) {
457
+ _this.ws.onclose = function () {};
458
+
459
+ _this.ws.close();
460
+
461
+ _this.listeners('disconnect').forEach(function (listener) {
462
+ return listener();
463
+ });
464
+ }
465
+ };
466
+
467
+ _this.disconnect = function () {
468
+ _this.close();
469
+ };
470
+
471
+ _this.options = _extends({}, DEFAULT_OPTIONS, options);
472
+ _this.currentReconnectDelay = _this.options.reconnectionDelay;
473
+ _this.url = url;
474
+ return _this;
475
+ }
476
+
477
+ var _proto = TeckosClient.prototype;
478
+
479
+ _proto.getConnectionState = function getConnectionState() {
480
+ if (this.ws) {
481
+ switch (this.ws.readyState) {
482
+ case WebSocket.OPEN:
483
+ return exports.ConnectionState.CONNECTED;
484
+
485
+ case WebSocket.CONNECTING:
486
+ return exports.ConnectionState.CONNECTING;
487
+
488
+ case WebSocket.CLOSING:
489
+ return exports.ConnectionState.DISCONNECTING;
490
+
491
+ default:
492
+ return exports.ConnectionState.DISCONNECTED;
493
+ }
494
+ }
495
+
496
+ return exports.ConnectionState.DISCONNECTED;
497
+ };
498
+
499
+ _createClass(TeckosClient, [{
500
+ key: "webSocket",
501
+ get: function get() {
502
+ return this.ws;
503
+ }
504
+ }, {
505
+ key: "state",
506
+ get: function get() {
507
+ return this.getConnectionState();
508
+ }
509
+ }, {
510
+ key: "connected",
511
+ get: function get() {
512
+ return this.getConnectionState() === exports.ConnectionState.CONNECTED;
513
+ }
514
+ }, {
515
+ key: "disconnected",
516
+ get: function get() {
517
+ return this.getConnectionState() === exports.ConnectionState.DISCONNECTED;
518
+ }
519
+ }]);
520
+
521
+ return TeckosClient;
522
+ }(SocketEventEmitter);
523
+
524
+ var d$1 = /*#__PURE__*/debug('teckos:client');
525
+
526
+ var TeckosClientWithJWT = /*#__PURE__*/function (_TeckosClient) {
527
+ _inheritsLoose(TeckosClientWithJWT, _TeckosClient);
528
+
529
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
530
+ function TeckosClientWithJWT(url, options, token, initialData) {
531
+ var _this;
532
+
533
+ _this = _TeckosClient.call(this, url, options) || this;
534
+ _this.receivedReady = false;
535
+
536
+ _this.handleReadyEvent = function () {
537
+ if (_this.options.debug) d$1("[" + _this.url + "] Connected!");
538
+ _this.receivedReady = true;
539
+
540
+ if (_this.currentReconnectionAttempts > 0) {
541
+ if (_this.options.debug) d$1("[" + _this.url + "] Reconnected!");
542
+
543
+ _this.listeners('reconnect').forEach(function (listener) {
544
+ return listener();
545
+ }); // Reset reconnection settings to default
546
+
547
+
548
+ _this.currentReconnectDelay = _this.options.reconnectionDelay;
549
+ _this.currentReconnectionAttempts = 0;
550
+ }
551
+
552
+ _this.listeners('connect').forEach(function (listener) {
553
+ return listener();
554
+ });
555
+ };
556
+
557
+ _this.handleOpen = function () {
558
+ _this.receivedReady = false;
559
+
560
+ _this.once('ready', _this.handleReadyEvent);
561
+
562
+ if (_this.options.debug) d$1('Connection opened, sending token now');
563
+
564
+ _this.emit('token', _extends({
565
+ token: _this.token
566
+ }, _this.initialData));
567
+ };
568
+
569
+ _this.token = token; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
570
+
571
+ _this.initialData = initialData;
572
+
573
+ _this.on('disconnect', function () {
574
+ _this.receivedReady = false;
575
+ });
576
+
577
+ return _this;
578
+ }
579
+
580
+ var _proto = TeckosClientWithJWT.prototype;
581
+
582
+ _proto.getConnectionState = function getConnectionState() {
583
+ if (this.ws) {
584
+ switch (this.ws.readyState) {
585
+ case WebSocket.OPEN:
586
+ if (this.receivedReady) {
587
+ return exports.ConnectionState.CONNECTED;
588
+ }
589
+
590
+ return exports.ConnectionState.CONNECTING;
591
+
592
+ case WebSocket.CONNECTING:
593
+ return exports.ConnectionState.CONNECTING;
594
+
595
+ case WebSocket.CLOSING:
596
+ return exports.ConnectionState.DISCONNECTING;
597
+
598
+ default:
599
+ return exports.ConnectionState.DISCONNECTED;
600
+ }
601
+ }
602
+
603
+ return exports.ConnectionState.DISCONNECTED;
604
+ };
605
+
606
+ return TeckosClientWithJWT;
607
+ }(TeckosClient);
608
+
609
+ exports.TeckosClient = TeckosClient;
610
+ exports.TeckosClientWithJWT = TeckosClientWithJWT;
611
+ //# sourceMappingURL=teckos-client.cjs.development.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teckos-client.cjs.development.js","sources":["../src/util/Converter.ts","../src/types/PacketType.ts","../src/types/ConnectionState.ts","../src/util/SocketEventEmitter.ts","../src/TeckosClient.ts","../src/TeckosClientWithJWT.ts"],"sourcesContent":["import { Packet } from '../types'\n\nconst enc = new TextEncoder()\nconst dec = new TextDecoder()\n\nconst encodePacket = (packet: Packet): ArrayBufferLike => enc.encode(JSON.stringify(packet))\nconst decodePacket = (buffer: ArrayBuffer): Packet =>\n JSON.parse(dec.decode(buffer).toString()) as Packet\nexport { encodePacket, decodePacket }\n","enum PacketType {\n EVENT,\n ACK,\n}\nexport { PacketType }\n","enum ConnectionState {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n DISCONNECTING = 'disconnecting',\n}\nexport { ConnectionState }\n","export type Listener = (...args: any[]) => void\n\nclass SocketEventEmitter<T extends string> {\n protected maxListeners = 50\n\n protected handlers: {\n [event: string]: ((...args: any[]) => void)[]\n } = {}\n\n public addListener = (event: T, listener: (...args: any[]) => void): this => {\n if (Object.keys(this.handlers).length === this.maxListeners) {\n throw new Error('Max listeners reached')\n }\n if (typeof listener !== 'function') {\n throw new Error('The given listener is not a function')\n }\n this.handlers[event] = this.handlers[event] || []\n this.handlers[event].push(listener)\n return this\n }\n\n public once = (event: T, listener: (...args: any[]) => void): this => {\n if (Object.keys(this.handlers).length === this.maxListeners) {\n throw new Error('Max listeners reached')\n }\n if (typeof listener !== 'function') {\n throw new Error('The given listener is not a function')\n }\n this.handlers[event] = this.handlers[event] || []\n const onceWrapper = () => {\n listener()\n this.off(event, onceWrapper)\n }\n this.handlers[event].push(onceWrapper)\n return this\n }\n\n public removeListener = (event: T, listener: (...args: any[]) => void): this => {\n if (this.handlers[event]) {\n this.handlers[event] = this.handlers[event].filter((handler) => handler !== listener)\n }\n return this\n }\n\n public off = (event: T, listener: (...args: any[]) => void): this =>\n this.removeListener(event, listener)\n\n public removeAllListeners = (event?: T): this => {\n if (event) {\n delete this.handlers[event]\n } else {\n this.handlers = {}\n }\n return this\n }\n\n public setMaxListeners = (n: number): this => {\n this.maxListeners = n\n return this\n }\n\n public getMaxListeners = (): number => this.maxListeners\n\n public listeners = (event: T): Listener[] => {\n if (this.handlers[event]) {\n return [...this.handlers[event]]\n }\n return []\n }\n\n public rawListeners = (event: T): Listener[] => [...this.handlers[event]]\n\n public listenerCount = (event: T): number => {\n if (this.handlers[event]) {\n return Object.keys(this.handlers[event]).length\n }\n return 0\n }\n\n public prependListener = (event: T, listener: (...args: any[]) => void): this => {\n if (Object.keys(this.handlers).length === this.maxListeners) {\n throw new Error('Max listeners reached')\n }\n this.handlers[event] = this.handlers[event] || []\n this.handlers[event].unshift(listener)\n return this\n }\n\n public prependOnceListener = (event: T, listener: (...args: any[]) => void): this => {\n if (Object.keys(this.handlers).length === this.maxListeners) {\n throw new Error('Max listeners reached')\n }\n this.handlers[event] = this.handlers[event] || []\n const onceWrapper = () => {\n listener()\n this.off(event, onceWrapper)\n }\n this.handlers[event].unshift(onceWrapper)\n return this\n }\n\n public eventNames = (): T[] => Object.keys(this.handlers) as T[]\n\n public on = (event: T, listener: (...args: any[]) => void): this =>\n this.addListener(event, listener)\n\n public emit = (event: T, ...args: any[]): boolean => {\n const listeners = this.listeners(event)\n if (listeners.length > 0) {\n listeners.forEach((listener) => {\n if (listener) listener(args)\n })\n return true\n }\n return false\n }\n}\n\nexport { SocketEventEmitter }\n","import debug from 'debug'\nimport WebSocket from 'isomorphic-ws'\nimport { decodePacket, encodePacket } from './util/Converter'\nimport { ConnectionState, OptionalOptions, Options, Packet, PacketType, SocketEvent } from './types'\nimport { ITeckosClient } from './ITeckosClient'\nimport { SocketEventEmitter } from './util/SocketEventEmitter'\n\nconst d = debug('teckos:client')\n\nconst DEFAULT_OPTIONS: Options = {\n reconnection: true,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 5000,\n reconnectionAttempts: Infinity,\n randomizationFactor: 0.5,\n timeout: 5000,\n debug: false,\n}\n\nclass TeckosClient extends SocketEventEmitter<SocketEvent> implements ITeckosClient {\n protected readonly url: string\n\n protected readonly options: Options\n\n ws: WebSocket | undefined\n\n protected currentReconnectDelay: number\n\n protected currentReconnectionAttempts = 0\n\n protected acks: Map<number, (...args: any[]) => void> = new Map()\n\n protected fnId = 0\n\n protected connectionTimeout: any | undefined\n\n protected reconnectionTimeout: any | undefined\n\n constructor(url: string, options?: OptionalOptions) {\n super()\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n }\n this.currentReconnectDelay = this.options.reconnectionDelay\n this.url = url\n }\n\n protected attachHandler = (): void => {\n if (this.ws) {\n this.ws.onopen = this.handleOpen\n this.ws.onerror = this.handleError\n this.ws.onclose = this.handleClose\n this.ws.onmessage = this.handleMessage\n }\n }\n\n public get webSocket(): WebSocket | undefined {\n return this.ws\n }\n\n public connect = (): void => {\n if (this.options.debug) d(`Connecting to ${this.url}...`)\n\n // This will try to connect immediately\n this.ws = new WebSocket(this.url)\n // Attach handlers\n this.attachHandler()\n // Handle timeout\n this.connectionTimeout = setTimeout(() => {\n if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {\n this.ws.close()\n }\n }, this.options.timeout)\n }\n\n protected reconnect = (): void => {\n this.listeners('reconnect_attempt').forEach((listener) => listener())\n this.connect()\n }\n\n protected getConnectionState(): ConnectionState {\n if (this.ws) {\n switch (this.ws.readyState) {\n case WebSocket.OPEN:\n return ConnectionState.CONNECTED\n case WebSocket.CONNECTING:\n return ConnectionState.CONNECTING\n case WebSocket.CLOSING:\n return ConnectionState.DISCONNECTING\n default:\n return ConnectionState.DISCONNECTED\n }\n }\n return ConnectionState.DISCONNECTED\n }\n\n public get state(): ConnectionState {\n return this.getConnectionState()\n }\n\n get connected(): boolean {\n return this.getConnectionState() === ConnectionState.CONNECTED\n }\n\n get disconnected(): boolean {\n return this.getConnectionState() === ConnectionState.DISCONNECTED\n }\n\n public emit = (event: SocketEvent, ...args: any[]): boolean => {\n args.unshift(event)\n\n const packet: Packet = {\n type: PacketType.EVENT,\n data: args,\n }\n\n if (typeof args[args.length - 1] === 'function') {\n this.acks.set(this.fnId, args.pop())\n packet.id = this.fnId\n this.fnId += 1\n }\n\n return this.sendPackage(packet)\n }\n\n public send = (...args: any[]): boolean => {\n args.unshift('message')\n return this.sendPackage({\n type: PacketType.EVENT,\n data: args,\n })\n }\n\n public sendPackage = (packet: Packet): boolean => {\n if (this.ws !== undefined && this.ws.readyState === WebSocket.OPEN) {\n const buffer = encodePacket(packet)\n if (this.options.debug) d(`[${this.url}] Send packet: ${JSON.stringify(packet)}`)\n this.ws.send(buffer)\n return true\n }\n return false\n }\n\n protected handleMessage = (msg: WebSocket.MessageEvent): void => {\n const packet =\n typeof msg.data === 'string'\n ? (JSON.parse(msg.data) as Packet)\n : decodePacket(msg.data as ArrayBuffer)\n if (this.options.debug) d(`[${this.url}] Got packet: ${JSON.stringify(packet)}`)\n if (packet.type === PacketType.EVENT) {\n const event = packet.data[0] as SocketEvent\n const args = packet.data.slice(1)\n if (event) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n this.listeners(event).forEach((listener) => listener(...args))\n } else {\n throw new Error(\n `[teckos-client@${this.url}] Got invalid event message: ${JSON.stringify(\n msg.data\n )}`\n )\n }\n } else if (packet.type === PacketType.ACK && packet.id !== undefined) {\n // Call assigned function\n const ack = this.acks.get(packet.id)\n if (typeof ack === 'function') {\n ack.apply(this, packet.data)\n this.acks.delete(packet.id)\n }\n } else {\n throw new Error(`[teckos-client@${this.url}] Got invalid message type: ${packet.type}`)\n }\n }\n\n protected handleOpen = (): void => {\n if (this.currentReconnectionAttempts > 0) {\n // Reset reconnection settings to default\n this.currentReconnectDelay = this.options.reconnectionDelay\n this.currentReconnectionAttempts = 0\n\n // Inform listeners\n if (this.options.debug) d(`[${this.url}] Reconnected!`)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n this.listeners('reconnect').forEach((listener) => listener())\n }\n // Inform listeners\n if (this.options.debug) d(`[${this.url}] Connected!`)\n this.listeners('connect').forEach((listener) => listener())\n }\n\n protected handleError = (error: WebSocket.ErrorEvent): void => {\n if (this.handlers && this.handlers.error) {\n if (this.options.debug)\n d(`[${this.url}] Got error from server: ${JSON.stringify(error)}`)\n this.handlers.error.forEach((listener) => listener(error))\n }\n }\n\n protected handleClose = (): void => {\n // Stop connection timeout\n if (this.connectionTimeout) {\n clearTimeout(this.connectionTimeout)\n }\n // Stop reconnection timeout\n if (this.reconnectionTimeout) {\n clearTimeout(this.reconnectionTimeout)\n }\n\n // Inform listeners\n if (this.currentReconnectionAttempts > 0) {\n if (this.options.debug)\n d(`[${this.url}] Reconnect #${this.currentReconnectionAttempts} failed!`)\n this.listeners('reconnect_error').forEach((listener) => {\n if (listener) listener()\n })\n } else {\n if (this.options.debug) d(`[${this.url}] Disconnected!`)\n this.listeners('disconnect').forEach((listener) => {\n if (listener) listener()\n })\n }\n\n if (this.options.reconnection) {\n // Apply reconnection logic\n this.currentReconnectionAttempts += 1\n\n if (\n this.options.reconnectionAttempts === Infinity ||\n this.currentReconnectionAttempts <= this.options.reconnectionAttempts\n ) {\n const timeout = Math.min(\n this.options.reconnectionDelayMax,\n this.currentReconnectDelay\n )\n // Increase reconnection delay\n this.currentReconnectDelay = Math.round(\n this.currentReconnectDelay +\n this.currentReconnectDelay * this.options.randomizationFactor\n )\n\n if (this.options.debug)\n d(\n `[${this.url}] Try reconnecting (${this.currentReconnectionAttempts}/${this.options.reconnectionAttempts}) in ${timeout}ms to ${this.url}...`\n )\n this.reconnectionTimeout = setTimeout(() => {\n this.reconnect()\n }, timeout)\n } else {\n if (this.options.debug)\n d(\n `[${this.url}] Reconnection maximum of ${this.options.reconnectionAttempts} reached`\n )\n this.listeners('reconnect_failed').forEach((listener) => listener())\n }\n }\n }\n\n public close = (): void => {\n if (this.options.debug) d(`[${this.url}] Closing connection (client-side)`)\n if (this.ws !== undefined) {\n this.ws.onclose = () => {}\n this.ws.close()\n this.listeners('disconnect').forEach((listener) => listener())\n }\n }\n\n public disconnect = (): void => {\n this.close()\n }\n}\n\nexport { TeckosClient }\n","import debug from 'debug'\nimport WebSocket from 'isomorphic-ws'\nimport { TeckosClient } from './TeckosClient'\nimport { OptionalOptions, ConnectionState } from './types'\n\nconst d = debug('teckos:client')\n\nclass TeckosClientWithJWT extends TeckosClient {\n protected readonly token: string\n\n protected readonly initialData: any\n\n protected receivedReady = false\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n constructor(url: string, options: OptionalOptions, token: string, initialData?: any) {\n super(url, options)\n this.token = token\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n this.initialData = initialData\n this.on('disconnect', () => {\n this.receivedReady = false\n })\n }\n\n protected getConnectionState(): ConnectionState {\n if (this.ws) {\n switch (this.ws.readyState) {\n case WebSocket.OPEN:\n if (this.receivedReady) {\n return ConnectionState.CONNECTED\n }\n return ConnectionState.CONNECTING\n case WebSocket.CONNECTING:\n return ConnectionState.CONNECTING\n case WebSocket.CLOSING:\n return ConnectionState.DISCONNECTING\n default:\n return ConnectionState.DISCONNECTED\n }\n }\n return ConnectionState.DISCONNECTED\n }\n\n protected handleReadyEvent = (): void => {\n if (this.options.debug) d(`[${this.url}] Connected!`)\n this.receivedReady = true\n if (this.currentReconnectionAttempts > 0) {\n if (this.options.debug) d(`[${this.url}] Reconnected!`)\n this.listeners('reconnect').forEach((listener) => listener())\n // Reset reconnection settings to default\n this.currentReconnectDelay = this.options.reconnectionDelay\n this.currentReconnectionAttempts = 0\n }\n this.listeners('connect').forEach((listener) => listener())\n }\n\n protected handleOpen = (): void => {\n this.receivedReady = false\n this.once('ready', this.handleReadyEvent)\n if (this.options.debug) d('Connection opened, sending token now')\n this.emit('token', {\n token: this.token,\n ...this.initialData,\n })\n }\n}\n\nexport { TeckosClientWithJWT }\n"],"names":["enc","TextEncoder","dec","TextDecoder","encodePacket","packet","encode","JSON","stringify","decodePacket","buffer","parse","decode","toString","PacketType","ConnectionState","SocketEventEmitter","event","listener","Object","keys","handlers","length","maxListeners","Error","push","onceWrapper","off","filter","handler","removeListener","n","unshift","addListener","args","listeners","forEach","d","debug","DEFAULT_OPTIONS","reconnection","reconnectionDelay","reconnectionDelayMax","reconnectionAttempts","Infinity","randomizationFactor","timeout","TeckosClient","url","options","Map","ws","onopen","handleOpen","onerror","handleError","onclose","handleClose","onmessage","handleMessage","WebSocket","attachHandler","connectionTimeout","setTimeout","readyState","CONNECTING","close","connect","type","EVENT","data","acks","set","fnId","pop","id","sendPackage","undefined","OPEN","send","msg","slice","ACK","ack","get","apply","currentReconnectionAttempts","currentReconnectDelay","error","clearTimeout","reconnectionTimeout","Math","min","round","reconnect","getConnectionState","CONNECTED","CLOSING","DISCONNECTING","DISCONNECTED","TeckosClientWithJWT","token","initialData","receivedReady","once","handleReadyEvent","emit","on"],"mappings":"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"}