UNPKG

106 kBJavaScriptView Raw
1/*!
2 * Socket.IO v4.3.1
3 * (c) 2014-2021 Guillermo Rauch
4 * Released under the MIT License.
5 */
6(function (global, factory) {
7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8 typeof define === 'function' && define.amd ? define(factory) :
9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.io = factory());
10})(this, (function () { 'use strict';
11
12 function _typeof(obj) {
13 "@babel/helpers - typeof";
14
15 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
16 _typeof = function (obj) {
17 return typeof obj;
18 };
19 } else {
20 _typeof = function (obj) {
21 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
22 };
23 }
24
25 return _typeof(obj);
26 }
27
28 function _classCallCheck(instance, Constructor) {
29 if (!(instance instanceof Constructor)) {
30 throw new TypeError("Cannot call a class as a function");
31 }
32 }
33
34 function _defineProperties(target, props) {
35 for (var i = 0; i < props.length; i++) {
36 var descriptor = props[i];
37 descriptor.enumerable = descriptor.enumerable || false;
38 descriptor.configurable = true;
39 if ("value" in descriptor) descriptor.writable = true;
40 Object.defineProperty(target, descriptor.key, descriptor);
41 }
42 }
43
44 function _createClass(Constructor, protoProps, staticProps) {
45 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
46 if (staticProps) _defineProperties(Constructor, staticProps);
47 return Constructor;
48 }
49
50 function _extends() {
51 _extends = Object.assign || function (target) {
52 for (var i = 1; i < arguments.length; i++) {
53 var source = arguments[i];
54
55 for (var key in source) {
56 if (Object.prototype.hasOwnProperty.call(source, key)) {
57 target[key] = source[key];
58 }
59 }
60 }
61
62 return target;
63 };
64
65 return _extends.apply(this, arguments);
66 }
67
68 function _inherits(subClass, superClass) {
69 if (typeof superClass !== "function" && superClass !== null) {
70 throw new TypeError("Super expression must either be null or a function");
71 }
72
73 subClass.prototype = Object.create(superClass && superClass.prototype, {
74 constructor: {
75 value: subClass,
76 writable: true,
77 configurable: true
78 }
79 });
80 if (superClass) _setPrototypeOf(subClass, superClass);
81 }
82
83 function _getPrototypeOf(o) {
84 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
85 return o.__proto__ || Object.getPrototypeOf(o);
86 };
87 return _getPrototypeOf(o);
88 }
89
90 function _setPrototypeOf(o, p) {
91 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
92 o.__proto__ = p;
93 return o;
94 };
95
96 return _setPrototypeOf(o, p);
97 }
98
99 function _isNativeReflectConstruct() {
100 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
101 if (Reflect.construct.sham) return false;
102 if (typeof Proxy === "function") return true;
103
104 try {
105 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
106 return true;
107 } catch (e) {
108 return false;
109 }
110 }
111
112 function _assertThisInitialized(self) {
113 if (self === void 0) {
114 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
115 }
116
117 return self;
118 }
119
120 function _possibleConstructorReturn(self, call) {
121 if (call && (typeof call === "object" || typeof call === "function")) {
122 return call;
123 } else if (call !== void 0) {
124 throw new TypeError("Derived constructors may only return object or undefined");
125 }
126
127 return _assertThisInitialized(self);
128 }
129
130 function _createSuper(Derived) {
131 var hasNativeReflectConstruct = _isNativeReflectConstruct();
132
133 return function _createSuperInternal() {
134 var Super = _getPrototypeOf(Derived),
135 result;
136
137 if (hasNativeReflectConstruct) {
138 var NewTarget = _getPrototypeOf(this).constructor;
139
140 result = Reflect.construct(Super, arguments, NewTarget);
141 } else {
142 result = Super.apply(this, arguments);
143 }
144
145 return _possibleConstructorReturn(this, result);
146 };
147 }
148
149 function _superPropBase(object, property) {
150 while (!Object.prototype.hasOwnProperty.call(object, property)) {
151 object = _getPrototypeOf(object);
152 if (object === null) break;
153 }
154
155 return object;
156 }
157
158 function _get(target, property, receiver) {
159 if (typeof Reflect !== "undefined" && Reflect.get) {
160 _get = Reflect.get;
161 } else {
162 _get = function _get(target, property, receiver) {
163 var base = _superPropBase(target, property);
164
165 if (!base) return;
166 var desc = Object.getOwnPropertyDescriptor(base, property);
167
168 if (desc.get) {
169 return desc.get.call(receiver);
170 }
171
172 return desc.value;
173 };
174 }
175
176 return _get(target, property, receiver || target);
177 }
178
179 function _unsupportedIterableToArray(o, minLen) {
180 if (!o) return;
181 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
182 var n = Object.prototype.toString.call(o).slice(8, -1);
183 if (n === "Object" && o.constructor) n = o.constructor.name;
184 if (n === "Map" || n === "Set") return Array.from(o);
185 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
186 }
187
188 function _arrayLikeToArray(arr, len) {
189 if (len == null || len > arr.length) len = arr.length;
190
191 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
192
193 return arr2;
194 }
195
196 function _createForOfIteratorHelper(o, allowArrayLike) {
197 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
198
199 if (!it) {
200 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
201 if (it) o = it;
202 var i = 0;
203
204 var F = function () {};
205
206 return {
207 s: F,
208 n: function () {
209 if (i >= o.length) return {
210 done: true
211 };
212 return {
213 done: false,
214 value: o[i++]
215 };
216 },
217 e: function (e) {
218 throw e;
219 },
220 f: F
221 };
222 }
223
224 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
225 }
226
227 var normalCompletion = true,
228 didErr = false,
229 err;
230 return {
231 s: function () {
232 it = it.call(o);
233 },
234 n: function () {
235 var step = it.next();
236 normalCompletion = step.done;
237 return step;
238 },
239 e: function (e) {
240 didErr = true;
241 err = e;
242 },
243 f: function () {
244 try {
245 if (!normalCompletion && it.return != null) it.return();
246 } finally {
247 if (didErr) throw err;
248 }
249 }
250 };
251 }
252
253 /**
254 * Parses an URI
255 *
256 * @author Steven Levithan <stevenlevithan.com> (MIT license)
257 * @api private
258 */
259 var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
260 var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'];
261
262 var parseuri = function parseuri(str) {
263 var src = str,
264 b = str.indexOf('['),
265 e = str.indexOf(']');
266
267 if (b != -1 && e != -1) {
268 str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
269 }
270
271 var m = re.exec(str || ''),
272 uri = {},
273 i = 14;
274
275 while (i--) {
276 uri[parts[i]] = m[i] || '';
277 }
278
279 if (b != -1 && e != -1) {
280 uri.source = src;
281 uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
282 uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
283 uri.ipv6uri = true;
284 }
285
286 uri.pathNames = pathNames(uri, uri['path']);
287 uri.queryKey = queryKey(uri, uri['query']);
288 return uri;
289 };
290
291 function pathNames(obj, path) {
292 var regx = /\/{2,9}/g,
293 names = path.replace(regx, "/").split("/");
294
295 if (path.substr(0, 1) == '/' || path.length === 0) {
296 names.splice(0, 1);
297 }
298
299 if (path.substr(path.length - 1, 1) == '/') {
300 names.splice(names.length - 1, 1);
301 }
302
303 return names;
304 }
305
306 function queryKey(uri, query) {
307 var data = {};
308 query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
309 if ($1) {
310 data[$1] = $2;
311 }
312 });
313 return data;
314 }
315
316 /**
317 * URL parser.
318 *
319 * @param uri - url
320 * @param path - the request path of the connection
321 * @param loc - An object meant to mimic window.location.
322 * Defaults to window.location.
323 * @public
324 */
325
326 function url(uri) {
327 var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
328 var loc = arguments.length > 2 ? arguments[2] : undefined;
329 var obj = uri; // default to window.location
330
331 loc = loc || typeof location !== "undefined" && location;
332 if (null == uri) uri = loc.protocol + "//" + loc.host; // relative path support
333
334 if (typeof uri === "string") {
335 if ("/" === uri.charAt(0)) {
336 if ("/" === uri.charAt(1)) {
337 uri = loc.protocol + uri;
338 } else {
339 uri = loc.host + uri;
340 }
341 }
342
343 if (!/^(https?|wss?):\/\//.test(uri)) {
344 if ("undefined" !== typeof loc) {
345 uri = loc.protocol + "//" + uri;
346 } else {
347 uri = "https://" + uri;
348 }
349 } // parse
350
351
352 obj = parseuri(uri);
353 } // make sure we treat `localhost:80` and `localhost` equally
354
355
356 if (!obj.port) {
357 if (/^(http|ws)$/.test(obj.protocol)) {
358 obj.port = "80";
359 } else if (/^(http|ws)s$/.test(obj.protocol)) {
360 obj.port = "443";
361 }
362 }
363
364 obj.path = obj.path || "/";
365 var ipv6 = obj.host.indexOf(":") !== -1;
366 var host = ipv6 ? "[" + obj.host + "]" : obj.host; // define unique id
367
368 obj.id = obj.protocol + "://" + host + ":" + obj.port + path; // define href
369
370 obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port);
371 return obj;
372 }
373
374 var hasCors = {exports: {}};
375
376 /**
377 * Module exports.
378 *
379 * Logic borrowed from Modernizr:
380 *
381 * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
382 */
383
384 try {
385 hasCors.exports = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest();
386 } catch (err) {
387 // if XMLHttp support is disabled in IE then it will throw
388 // when trying to create
389 hasCors.exports = false;
390 }
391
392 var hasCORS = hasCors.exports;
393
394 var globalThis = (function () {
395 if (typeof self !== "undefined") {
396 return self;
397 } else if (typeof window !== "undefined") {
398 return window;
399 } else {
400 return Function("return this")();
401 }
402 })();
403
404 // browser shim for xmlhttprequest module
405 function XMLHttpRequest$1 (opts) {
406 var xdomain = opts.xdomain; // XMLHttpRequest can be disabled on IE
407
408 try {
409 if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
410 return new XMLHttpRequest();
411 }
412 } catch (e) {}
413
414 if (!xdomain) {
415 try {
416 return new globalThis[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
417 } catch (e) {}
418 }
419 }
420
421 function pick(obj) {
422 for (var _len = arguments.length, attr = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
423 attr[_key - 1] = arguments[_key];
424 }
425
426 return attr.reduce(function (acc, k) {
427 if (obj.hasOwnProperty(k)) {
428 acc[k] = obj[k];
429 }
430
431 return acc;
432 }, {});
433 } // Keep a reference to the real timeout functions so they can be used when overridden
434
435 var NATIVE_SET_TIMEOUT = setTimeout;
436 var NATIVE_CLEAR_TIMEOUT = clearTimeout;
437 function installTimerFunctions(obj, opts) {
438 if (opts.useNativeTimers) {
439 obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis);
440 obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis);
441 } else {
442 obj.setTimeoutFn = setTimeout.bind(globalThis);
443 obj.clearTimeoutFn = clearTimeout.bind(globalThis);
444 }
445 }
446
447 /**
448 * Expose `Emitter`.
449 */
450
451 var Emitter_1 = Emitter;
452 /**
453 * Initialize a new `Emitter`.
454 *
455 * @api public
456 */
457
458 function Emitter(obj) {
459 if (obj) return mixin(obj);
460 }
461 /**
462 * Mixin the emitter properties.
463 *
464 * @param {Object} obj
465 * @return {Object}
466 * @api private
467 */
468
469
470 function mixin(obj) {
471 for (var key in Emitter.prototype) {
472 obj[key] = Emitter.prototype[key];
473 }
474
475 return obj;
476 }
477 /**
478 * Listen on the given `event` with `fn`.
479 *
480 * @param {String} event
481 * @param {Function} fn
482 * @return {Emitter}
483 * @api public
484 */
485
486
487 Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
488 this._callbacks = this._callbacks || {};
489 (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
490 return this;
491 };
492 /**
493 * Adds an `event` listener that will be invoked a single
494 * time then automatically removed.
495 *
496 * @param {String} event
497 * @param {Function} fn
498 * @return {Emitter}
499 * @api public
500 */
501
502
503 Emitter.prototype.once = function (event, fn) {
504 function on() {
505 this.off(event, on);
506 fn.apply(this, arguments);
507 }
508
509 on.fn = fn;
510 this.on(event, on);
511 return this;
512 };
513 /**
514 * Remove the given callback for `event` or all
515 * registered callbacks.
516 *
517 * @param {String} event
518 * @param {Function} fn
519 * @return {Emitter}
520 * @api public
521 */
522
523
524 Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
525 this._callbacks = this._callbacks || {}; // all
526
527 if (0 == arguments.length) {
528 this._callbacks = {};
529 return this;
530 } // specific event
531
532
533 var callbacks = this._callbacks['$' + event];
534 if (!callbacks) return this; // remove all handlers
535
536 if (1 == arguments.length) {
537 delete this._callbacks['$' + event];
538 return this;
539 } // remove specific handler
540
541
542 var cb;
543
544 for (var i = 0; i < callbacks.length; i++) {
545 cb = callbacks[i];
546
547 if (cb === fn || cb.fn === fn) {
548 callbacks.splice(i, 1);
549 break;
550 }
551 } // Remove event specific arrays for event types that no
552 // one is subscribed for to avoid memory leak.
553
554
555 if (callbacks.length === 0) {
556 delete this._callbacks['$' + event];
557 }
558
559 return this;
560 };
561 /**
562 * Emit `event` with the given args.
563 *
564 * @param {String} event
565 * @param {Mixed} ...
566 * @return {Emitter}
567 */
568
569
570 Emitter.prototype.emit = function (event) {
571 this._callbacks = this._callbacks || {};
572 var args = new Array(arguments.length - 1),
573 callbacks = this._callbacks['$' + event];
574
575 for (var i = 1; i < arguments.length; i++) {
576 args[i - 1] = arguments[i];
577 }
578
579 if (callbacks) {
580 callbacks = callbacks.slice(0);
581
582 for (var i = 0, len = callbacks.length; i < len; ++i) {
583 callbacks[i].apply(this, args);
584 }
585 }
586
587 return this;
588 }; // alias used for reserved events (protected method)
589
590
591 Emitter.prototype.emitReserved = Emitter.prototype.emit;
592 /**
593 * Return array of callbacks for `event`.
594 *
595 * @param {String} event
596 * @return {Array}
597 * @api public
598 */
599
600 Emitter.prototype.listeners = function (event) {
601 this._callbacks = this._callbacks || {};
602 return this._callbacks['$' + event] || [];
603 };
604 /**
605 * Check if this emitter has `event` handlers.
606 *
607 * @param {String} event
608 * @return {Boolean}
609 * @api public
610 */
611
612
613 Emitter.prototype.hasListeners = function (event) {
614 return !!this.listeners(event).length;
615 };
616
617 var PACKET_TYPES = Object.create(null); // no Map = no polyfill
618
619 PACKET_TYPES["open"] = "0";
620 PACKET_TYPES["close"] = "1";
621 PACKET_TYPES["ping"] = "2";
622 PACKET_TYPES["pong"] = "3";
623 PACKET_TYPES["message"] = "4";
624 PACKET_TYPES["upgrade"] = "5";
625 PACKET_TYPES["noop"] = "6";
626 var PACKET_TYPES_REVERSE = Object.create(null);
627 Object.keys(PACKET_TYPES).forEach(function (key) {
628 PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
629 });
630 var ERROR_PACKET = {
631 type: "error",
632 data: "parser error"
633 };
634
635 var withNativeBlob$1 = typeof Blob === "function" || typeof Blob !== "undefined" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]";
636 var withNativeArrayBuffer$2 = typeof ArrayBuffer === "function"; // ArrayBuffer.isView method is not defined in IE10
637
638 var isView$1 = function isView(obj) {
639 return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj && obj.buffer instanceof ArrayBuffer;
640 };
641
642 var encodePacket = function encodePacket(_ref, supportsBinary, callback) {
643 var type = _ref.type,
644 data = _ref.data;
645
646 if (withNativeBlob$1 && data instanceof Blob) {
647 if (supportsBinary) {
648 return callback(data);
649 } else {
650 return encodeBlobAsBase64(data, callback);
651 }
652 } else if (withNativeArrayBuffer$2 && (data instanceof ArrayBuffer || isView$1(data))) {
653 if (supportsBinary) {
654 return callback(data);
655 } else {
656 return encodeBlobAsBase64(new Blob([data]), callback);
657 }
658 } // plain string
659
660
661 return callback(PACKET_TYPES[type] + (data || ""));
662 };
663
664 var encodeBlobAsBase64 = function encodeBlobAsBase64(data, callback) {
665 var fileReader = new FileReader();
666
667 fileReader.onload = function () {
668 var content = fileReader.result.split(",")[1];
669 callback("b" + content);
670 };
671
672 return fileReader.readAsDataURL(data);
673 };
674
675 /*
676 * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
677 * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
678 * Released under MIT License
679 */
680 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; // Use a lookup table to find the index.
681
682 var lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
683
684 for (var i$1 = 0; i$1 < chars.length; i$1++) {
685 lookup$1[chars.charCodeAt(i$1)] = i$1;
686 }
687
688 var decode$1 = function decode(base64) {
689 var bufferLength = base64.length * 0.75,
690 len = base64.length,
691 i,
692 p = 0,
693 encoded1,
694 encoded2,
695 encoded3,
696 encoded4;
697
698 if (base64[base64.length - 1] === '=') {
699 bufferLength--;
700
701 if (base64[base64.length - 2] === '=') {
702 bufferLength--;
703 }
704 }
705
706 var arraybuffer = new ArrayBuffer(bufferLength),
707 bytes = new Uint8Array(arraybuffer);
708
709 for (i = 0; i < len; i += 4) {
710 encoded1 = lookup$1[base64.charCodeAt(i)];
711 encoded2 = lookup$1[base64.charCodeAt(i + 1)];
712 encoded3 = lookup$1[base64.charCodeAt(i + 2)];
713 encoded4 = lookup$1[base64.charCodeAt(i + 3)];
714 bytes[p++] = encoded1 << 2 | encoded2 >> 4;
715 bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
716 bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
717 }
718
719 return arraybuffer;
720 };
721
722 var withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
723
724 var decodePacket = function decodePacket(encodedPacket, binaryType) {
725 if (typeof encodedPacket !== "string") {
726 return {
727 type: "message",
728 data: mapBinary(encodedPacket, binaryType)
729 };
730 }
731
732 var type = encodedPacket.charAt(0);
733
734 if (type === "b") {
735 return {
736 type: "message",
737 data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
738 };
739 }
740
741 var packetType = PACKET_TYPES_REVERSE[type];
742
743 if (!packetType) {
744 return ERROR_PACKET;
745 }
746
747 return encodedPacket.length > 1 ? {
748 type: PACKET_TYPES_REVERSE[type],
749 data: encodedPacket.substring(1)
750 } : {
751 type: PACKET_TYPES_REVERSE[type]
752 };
753 };
754
755 var decodeBase64Packet = function decodeBase64Packet(data, binaryType) {
756 if (withNativeArrayBuffer$1) {
757 var decoded = decode$1(data);
758 return mapBinary(decoded, binaryType);
759 } else {
760 return {
761 base64: true,
762 data: data
763 }; // fallback for old browsers
764 }
765 };
766
767 var mapBinary = function mapBinary(data, binaryType) {
768 switch (binaryType) {
769 case "blob":
770 return data instanceof ArrayBuffer ? new Blob([data]) : data;
771
772 case "arraybuffer":
773 default:
774 return data;
775 // assuming the data is already an ArrayBuffer
776 }
777 };
778
779 var SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
780
781 var encodePayload = function encodePayload(packets, callback) {
782 // some packets may be added to the array while encoding, so the initial length must be saved
783 var length = packets.length;
784 var encodedPackets = new Array(length);
785 var count = 0;
786 packets.forEach(function (packet, i) {
787 // force base64 encoding for binary packets
788 encodePacket(packet, false, function (encodedPacket) {
789 encodedPackets[i] = encodedPacket;
790
791 if (++count === length) {
792 callback(encodedPackets.join(SEPARATOR));
793 }
794 });
795 });
796 };
797
798 var decodePayload = function decodePayload(encodedPayload, binaryType) {
799 var encodedPackets = encodedPayload.split(SEPARATOR);
800 var packets = [];
801
802 for (var i = 0; i < encodedPackets.length; i++) {
803 var decodedPacket = decodePacket(encodedPackets[i], binaryType);
804 packets.push(decodedPacket);
805
806 if (decodedPacket.type === "error") {
807 break;
808 }
809 }
810
811 return packets;
812 };
813
814 var protocol$1 = 4;
815
816 var Transport = /*#__PURE__*/function (_Emitter) {
817 _inherits(Transport, _Emitter);
818
819 var _super = _createSuper(Transport);
820
821 /**
822 * Transport abstract constructor.
823 *
824 * @param {Object} options.
825 * @api private
826 */
827 function Transport(opts) {
828 var _this;
829
830 _classCallCheck(this, Transport);
831
832 _this = _super.call(this);
833 _this.writable = false;
834 installTimerFunctions(_assertThisInitialized(_this), opts);
835 _this.opts = opts;
836 _this.query = opts.query;
837 _this.readyState = "";
838 _this.socket = opts.socket;
839 return _this;
840 }
841 /**
842 * Emits an error.
843 *
844 * @param {String} str
845 * @return {Transport} for chaining
846 * @api protected
847 */
848
849
850 _createClass(Transport, [{
851 key: "onError",
852 value: function onError(msg, desc) {
853 var err = new Error(msg); // @ts-ignore
854
855 err.type = "TransportError"; // @ts-ignore
856
857 err.description = desc;
858
859 _get(_getPrototypeOf(Transport.prototype), "emit", this).call(this, "error", err);
860
861 return this;
862 }
863 /**
864 * Opens the transport.
865 *
866 * @api public
867 */
868
869 }, {
870 key: "open",
871 value: function open() {
872 if ("closed" === this.readyState || "" === this.readyState) {
873 this.readyState = "opening";
874 this.doOpen();
875 }
876
877 return this;
878 }
879 /**
880 * Closes the transport.
881 *
882 * @api public
883 */
884
885 }, {
886 key: "close",
887 value: function close() {
888 if ("opening" === this.readyState || "open" === this.readyState) {
889 this.doClose();
890 this.onClose();
891 }
892
893 return this;
894 }
895 /**
896 * Sends multiple packets.
897 *
898 * @param {Array} packets
899 * @api public
900 */
901
902 }, {
903 key: "send",
904 value: function send(packets) {
905 if ("open" === this.readyState) {
906 this.write(packets);
907 }
908 }
909 /**
910 * Called upon open
911 *
912 * @api protected
913 */
914
915 }, {
916 key: "onOpen",
917 value: function onOpen() {
918 this.readyState = "open";
919 this.writable = true;
920
921 _get(_getPrototypeOf(Transport.prototype), "emit", this).call(this, "open");
922 }
923 /**
924 * Called with data.
925 *
926 * @param {String} data
927 * @api protected
928 */
929
930 }, {
931 key: "onData",
932 value: function onData(data) {
933 var packet = decodePacket(data, this.socket.binaryType);
934 this.onPacket(packet);
935 }
936 /**
937 * Called with a decoded packet.
938 *
939 * @api protected
940 */
941
942 }, {
943 key: "onPacket",
944 value: function onPacket(packet) {
945 _get(_getPrototypeOf(Transport.prototype), "emit", this).call(this, "packet", packet);
946 }
947 /**
948 * Called upon close.
949 *
950 * @api protected
951 */
952
953 }, {
954 key: "onClose",
955 value: function onClose() {
956 this.readyState = "closed";
957
958 _get(_getPrototypeOf(Transport.prototype), "emit", this).call(this, "close");
959 }
960 }]);
961
962 return Transport;
963 }(Emitter_1);
964
965 var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''),
966 length = 64,
967 map = {},
968 seed = 0,
969 i = 0,
970 prev;
971 /**
972 * Return a string representing the specified number.
973 *
974 * @param {Number} num The number to convert.
975 * @returns {String} The string representation of the number.
976 * @api public
977 */
978
979 function encode(num) {
980 var encoded = '';
981
982 do {
983 encoded = alphabet[num % length] + encoded;
984 num = Math.floor(num / length);
985 } while (num > 0);
986
987 return encoded;
988 }
989 /**
990 * Return the integer value specified by the given string.
991 *
992 * @param {String} str The string to convert.
993 * @returns {Number} The integer value represented by the string.
994 * @api public
995 */
996
997
998 function decode(str) {
999 var decoded = 0;
1000
1001 for (i = 0; i < str.length; i++) {
1002 decoded = decoded * length + map[str.charAt(i)];
1003 }
1004
1005 return decoded;
1006 }
1007 /**
1008 * Yeast: A tiny growing id generator.
1009 *
1010 * @returns {String} A unique id.
1011 * @api public
1012 */
1013
1014
1015 function yeast() {
1016 var now = encode(+new Date());
1017 if (now !== prev) return seed = 0, prev = now;
1018 return now + '.' + encode(seed++);
1019 } //
1020 // Map each character to its index.
1021 //
1022
1023
1024 for (; i < length; i++) {
1025 map[alphabet[i]] = i;
1026 } //
1027 // Expose the `yeast`, `encode` and `decode` functions.
1028 //
1029
1030
1031 yeast.encode = encode;
1032 yeast.decode = decode;
1033 var yeast_1 = yeast;
1034
1035 var parseqs = {};
1036
1037 /**
1038 * Compiles a querystring
1039 * Returns string representation of the object
1040 *
1041 * @param {Object}
1042 * @api private
1043 */
1044
1045 parseqs.encode = function (obj) {
1046 var str = '';
1047
1048 for (var i in obj) {
1049 if (obj.hasOwnProperty(i)) {
1050 if (str.length) str += '&';
1051 str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
1052 }
1053 }
1054
1055 return str;
1056 };
1057 /**
1058 * Parses a simple querystring into an object
1059 *
1060 * @param {String} qs
1061 * @api private
1062 */
1063
1064
1065 parseqs.decode = function (qs) {
1066 var qry = {};
1067 var pairs = qs.split('&');
1068
1069 for (var i = 0, l = pairs.length; i < l; i++) {
1070 var pair = pairs[i].split('=');
1071 qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
1072 }
1073
1074 return qry;
1075 };
1076
1077 var Polling = /*#__PURE__*/function (_Transport) {
1078 _inherits(Polling, _Transport);
1079
1080 var _super = _createSuper(Polling);
1081
1082 function Polling() {
1083 var _this;
1084
1085 _classCallCheck(this, Polling);
1086
1087 _this = _super.apply(this, arguments);
1088 _this.polling = false;
1089 return _this;
1090 }
1091 /**
1092 * Transport name.
1093 */
1094
1095
1096 _createClass(Polling, [{
1097 key: "name",
1098 get: function get() {
1099 return "polling";
1100 }
1101 /**
1102 * Opens the socket (triggers polling). We write a PING message to determine
1103 * when the transport is open.
1104 *
1105 * @api private
1106 */
1107
1108 }, {
1109 key: "doOpen",
1110 value: function doOpen() {
1111 this.poll();
1112 }
1113 /**
1114 * Pauses polling.
1115 *
1116 * @param {Function} callback upon buffers are flushed and transport is paused
1117 * @api private
1118 */
1119
1120 }, {
1121 key: "pause",
1122 value: function pause(onPause) {
1123 var _this2 = this;
1124
1125 this.readyState = "pausing";
1126
1127 var pause = function pause() {
1128 _this2.readyState = "paused";
1129 onPause();
1130 };
1131
1132 if (this.polling || !this.writable) {
1133 var total = 0;
1134
1135 if (this.polling) {
1136 total++;
1137 this.once("pollComplete", function () {
1138 --total || pause();
1139 });
1140 }
1141
1142 if (!this.writable) {
1143 total++;
1144 this.once("drain", function () {
1145 --total || pause();
1146 });
1147 }
1148 } else {
1149 pause();
1150 }
1151 }
1152 /**
1153 * Starts polling cycle.
1154 *
1155 * @api public
1156 */
1157
1158 }, {
1159 key: "poll",
1160 value: function poll() {
1161 this.polling = true;
1162 this.doPoll();
1163 this.emit("poll");
1164 }
1165 /**
1166 * Overloads onData to detect payloads.
1167 *
1168 * @api private
1169 */
1170
1171 }, {
1172 key: "onData",
1173 value: function onData(data) {
1174 var _this3 = this;
1175
1176 var callback = function callback(packet) {
1177 // if its the first message we consider the transport open
1178 if ("opening" === _this3.readyState && packet.type === "open") {
1179 _this3.onOpen();
1180 } // if its a close packet, we close the ongoing requests
1181
1182
1183 if ("close" === packet.type) {
1184 _this3.onClose();
1185
1186 return false;
1187 } // otherwise bypass onData and handle the message
1188
1189
1190 _this3.onPacket(packet);
1191 }; // decode payload
1192
1193
1194 decodePayload(data, this.socket.binaryType).forEach(callback); // if an event did not trigger closing
1195
1196 if ("closed" !== this.readyState) {
1197 // if we got data we're not polling
1198 this.polling = false;
1199 this.emit("pollComplete");
1200
1201 if ("open" === this.readyState) {
1202 this.poll();
1203 }
1204 }
1205 }
1206 /**
1207 * For polling, send a close packet.
1208 *
1209 * @api private
1210 */
1211
1212 }, {
1213 key: "doClose",
1214 value: function doClose() {
1215 var _this4 = this;
1216
1217 var close = function close() {
1218 _this4.write([{
1219 type: "close"
1220 }]);
1221 };
1222
1223 if ("open" === this.readyState) {
1224 close();
1225 } else {
1226 // in case we're trying to close while
1227 // handshaking is in progress (GH-164)
1228 this.once("open", close);
1229 }
1230 }
1231 /**
1232 * Writes a packets payload.
1233 *
1234 * @param {Array} data packets
1235 * @param {Function} drain callback
1236 * @api private
1237 */
1238
1239 }, {
1240 key: "write",
1241 value: function write(packets) {
1242 var _this5 = this;
1243
1244 this.writable = false;
1245 encodePayload(packets, function (data) {
1246 _this5.doWrite(data, function () {
1247 _this5.writable = true;
1248
1249 _this5.emit("drain");
1250 });
1251 });
1252 }
1253 /**
1254 * Generates uri for connection.
1255 *
1256 * @api private
1257 */
1258
1259 }, {
1260 key: "uri",
1261 value: function uri() {
1262 var query = this.query || {};
1263 var schema = this.opts.secure ? "https" : "http";
1264 var port = ""; // cache busting is forced
1265
1266 if (false !== this.opts.timestampRequests) {
1267 query[this.opts.timestampParam] = yeast_1();
1268 }
1269
1270 if (!this.supportsBinary && !query.sid) {
1271 query.b64 = 1;
1272 } // avoid port if default for schema
1273
1274
1275 if (this.opts.port && ("https" === schema && Number(this.opts.port) !== 443 || "http" === schema && Number(this.opts.port) !== 80)) {
1276 port = ":" + this.opts.port;
1277 }
1278
1279 var encodedQuery = parseqs.encode(query);
1280 var ipv6 = this.opts.hostname.indexOf(":") !== -1;
1281 return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
1282 }
1283 }]);
1284
1285 return Polling;
1286 }(Transport);
1287
1288 /**
1289 * Empty function
1290 */
1291
1292 function empty() {}
1293
1294 var hasXHR2 = function () {
1295 var xhr = new XMLHttpRequest$1({
1296 xdomain: false
1297 });
1298 return null != xhr.responseType;
1299 }();
1300
1301 var XHR = /*#__PURE__*/function (_Polling) {
1302 _inherits(XHR, _Polling);
1303
1304 var _super = _createSuper(XHR);
1305
1306 /**
1307 * XHR Polling constructor.
1308 *
1309 * @param {Object} opts
1310 * @api public
1311 */
1312 function XHR(opts) {
1313 var _this;
1314
1315 _classCallCheck(this, XHR);
1316
1317 _this = _super.call(this, opts);
1318
1319 if (typeof location !== "undefined") {
1320 var isSSL = "https:" === location.protocol;
1321 var port = location.port; // some user agents have empty `location.port`
1322
1323 if (!port) {
1324 port = isSSL ? "443" : "80";
1325 }
1326
1327 _this.xd = typeof location !== "undefined" && opts.hostname !== location.hostname || port !== opts.port;
1328 _this.xs = opts.secure !== isSSL;
1329 }
1330 /**
1331 * XHR supports binary
1332 */
1333
1334
1335 var forceBase64 = opts && opts.forceBase64;
1336 _this.supportsBinary = hasXHR2 && !forceBase64;
1337 return _this;
1338 }
1339 /**
1340 * Creates a request.
1341 *
1342 * @param {String} method
1343 * @api private
1344 */
1345
1346
1347 _createClass(XHR, [{
1348 key: "request",
1349 value: function request() {
1350 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1351
1352 _extends(opts, {
1353 xd: this.xd,
1354 xs: this.xs
1355 }, this.opts);
1356
1357 return new Request(this.uri(), opts);
1358 }
1359 /**
1360 * Sends data.
1361 *
1362 * @param {String} data to send.
1363 * @param {Function} called upon flush.
1364 * @api private
1365 */
1366
1367 }, {
1368 key: "doWrite",
1369 value: function doWrite(data, fn) {
1370 var _this2 = this;
1371
1372 var req = this.request({
1373 method: "POST",
1374 data: data
1375 });
1376 req.on("success", fn);
1377 req.on("error", function (err) {
1378 _this2.onError("xhr post error", err);
1379 });
1380 }
1381 /**
1382 * Starts a poll cycle.
1383 *
1384 * @api private
1385 */
1386
1387 }, {
1388 key: "doPoll",
1389 value: function doPoll() {
1390 var _this3 = this;
1391
1392 var req = this.request();
1393 req.on("data", this.onData.bind(this));
1394 req.on("error", function (err) {
1395 _this3.onError("xhr poll error", err);
1396 });
1397 this.pollXhr = req;
1398 }
1399 }]);
1400
1401 return XHR;
1402 }(Polling);
1403 var Request = /*#__PURE__*/function (_Emitter) {
1404 _inherits(Request, _Emitter);
1405
1406 var _super2 = _createSuper(Request);
1407
1408 /**
1409 * Request constructor
1410 *
1411 * @param {Object} options
1412 * @api public
1413 */
1414 function Request(uri, opts) {
1415 var _this4;
1416
1417 _classCallCheck(this, Request);
1418
1419 _this4 = _super2.call(this);
1420 installTimerFunctions(_assertThisInitialized(_this4), opts);
1421 _this4.opts = opts;
1422 _this4.method = opts.method || "GET";
1423 _this4.uri = uri;
1424 _this4.async = false !== opts.async;
1425 _this4.data = undefined !== opts.data ? opts.data : null;
1426
1427 _this4.create();
1428
1429 return _this4;
1430 }
1431 /**
1432 * Creates the XHR object and sends the request.
1433 *
1434 * @api private
1435 */
1436
1437
1438 _createClass(Request, [{
1439 key: "create",
1440 value: function create() {
1441 var _this5 = this;
1442
1443 var opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
1444 opts.xdomain = !!this.opts.xd;
1445 opts.xscheme = !!this.opts.xs;
1446 var xhr = this.xhr = new XMLHttpRequest$1(opts);
1447
1448 try {
1449 xhr.open(this.method, this.uri, this.async);
1450
1451 try {
1452 if (this.opts.extraHeaders) {
1453 xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
1454
1455 for (var i in this.opts.extraHeaders) {
1456 if (this.opts.extraHeaders.hasOwnProperty(i)) {
1457 xhr.setRequestHeader(i, this.opts.extraHeaders[i]);
1458 }
1459 }
1460 }
1461 } catch (e) {}
1462
1463 if ("POST" === this.method) {
1464 try {
1465 xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
1466 } catch (e) {}
1467 }
1468
1469 try {
1470 xhr.setRequestHeader("Accept", "*/*");
1471 } catch (e) {} // ie6 check
1472
1473
1474 if ("withCredentials" in xhr) {
1475 xhr.withCredentials = this.opts.withCredentials;
1476 }
1477
1478 if (this.opts.requestTimeout) {
1479 xhr.timeout = this.opts.requestTimeout;
1480 }
1481
1482 xhr.onreadystatechange = function () {
1483 if (4 !== xhr.readyState) return;
1484
1485 if (200 === xhr.status || 1223 === xhr.status) {
1486 _this5.onLoad();
1487 } else {
1488 // make sure the `error` event handler that's user-set
1489 // does not throw in the same tick and gets caught here
1490 _this5.setTimeoutFn(function () {
1491 _this5.onError(typeof xhr.status === "number" ? xhr.status : 0);
1492 }, 0);
1493 }
1494 };
1495
1496 xhr.send(this.data);
1497 } catch (e) {
1498 // Need to defer since .create() is called directly from the constructor
1499 // and thus the 'error' event can only be only bound *after* this exception
1500 // occurs. Therefore, also, we cannot throw here at all.
1501 this.setTimeoutFn(function () {
1502 _this5.onError(e);
1503 }, 0);
1504 return;
1505 }
1506
1507 if (typeof document !== "undefined") {
1508 this.index = Request.requestsCount++;
1509 Request.requests[this.index] = this;
1510 }
1511 }
1512 /**
1513 * Called upon successful response.
1514 *
1515 * @api private
1516 */
1517
1518 }, {
1519 key: "onSuccess",
1520 value: function onSuccess() {
1521 this.emit("success");
1522 this.cleanup();
1523 }
1524 /**
1525 * Called if we have data.
1526 *
1527 * @api private
1528 */
1529
1530 }, {
1531 key: "onData",
1532 value: function onData(data) {
1533 this.emit("data", data);
1534 this.onSuccess();
1535 }
1536 /**
1537 * Called upon error.
1538 *
1539 * @api private
1540 */
1541
1542 }, {
1543 key: "onError",
1544 value: function onError(err) {
1545 this.emit("error", err);
1546 this.cleanup(true);
1547 }
1548 /**
1549 * Cleans up house.
1550 *
1551 * @api private
1552 */
1553
1554 }, {
1555 key: "cleanup",
1556 value: function cleanup(fromError) {
1557 if ("undefined" === typeof this.xhr || null === this.xhr) {
1558 return;
1559 }
1560
1561 this.xhr.onreadystatechange = empty;
1562
1563 if (fromError) {
1564 try {
1565 this.xhr.abort();
1566 } catch (e) {}
1567 }
1568
1569 if (typeof document !== "undefined") {
1570 delete Request.requests[this.index];
1571 }
1572
1573 this.xhr = null;
1574 }
1575 /**
1576 * Called upon load.
1577 *
1578 * @api private
1579 */
1580
1581 }, {
1582 key: "onLoad",
1583 value: function onLoad() {
1584 var data = this.xhr.responseText;
1585
1586 if (data !== null) {
1587 this.onData(data);
1588 }
1589 }
1590 /**
1591 * Aborts the request.
1592 *
1593 * @api public
1594 */
1595
1596 }, {
1597 key: "abort",
1598 value: function abort() {
1599 this.cleanup();
1600 }
1601 }]);
1602
1603 return Request;
1604 }(Emitter_1);
1605 Request.requestsCount = 0;
1606 Request.requests = {};
1607 /**
1608 * Aborts pending requests when unloading the window. This is needed to prevent
1609 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
1610 * emitted.
1611 */
1612
1613 if (typeof document !== "undefined") {
1614 // @ts-ignore
1615 if (typeof attachEvent === "function") {
1616 // @ts-ignore
1617 attachEvent("onunload", unloadHandler);
1618 } else if (typeof addEventListener === "function") {
1619 var terminationEvent = "onpagehide" in globalThis ? "pagehide" : "unload";
1620 addEventListener(terminationEvent, unloadHandler, false);
1621 }
1622 }
1623
1624 function unloadHandler() {
1625 for (var i in Request.requests) {
1626 if (Request.requests.hasOwnProperty(i)) {
1627 Request.requests[i].abort();
1628 }
1629 }
1630 }
1631
1632 var nextTick = function () {
1633 var isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
1634
1635 if (isPromiseAvailable) {
1636 return function (cb) {
1637 return Promise.resolve().then(cb);
1638 };
1639 } else {
1640 return function (cb, setTimeoutFn) {
1641 return setTimeoutFn(cb, 0);
1642 };
1643 }
1644 }();
1645 var WebSocket = globalThis.WebSocket || globalThis.MozWebSocket;
1646 var usingBrowserWebSocket = true;
1647 var defaultBinaryType = "arraybuffer";
1648
1649 var isReactNative = typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product.toLowerCase() === "reactnative";
1650 var WS = /*#__PURE__*/function (_Transport) {
1651 _inherits(WS, _Transport);
1652
1653 var _super = _createSuper(WS);
1654
1655 /**
1656 * WebSocket transport constructor.
1657 *
1658 * @api {Object} connection options
1659 * @api public
1660 */
1661 function WS(opts) {
1662 var _this;
1663
1664 _classCallCheck(this, WS);
1665
1666 _this = _super.call(this, opts);
1667 _this.supportsBinary = !opts.forceBase64;
1668 return _this;
1669 }
1670 /**
1671 * Transport name.
1672 *
1673 * @api public
1674 */
1675
1676
1677 _createClass(WS, [{
1678 key: "name",
1679 get: function get() {
1680 return "websocket";
1681 }
1682 /**
1683 * Opens socket.
1684 *
1685 * @api private
1686 */
1687
1688 }, {
1689 key: "doOpen",
1690 value: function doOpen() {
1691 if (!this.check()) {
1692 // let probe timeout
1693 return;
1694 }
1695
1696 var uri = this.uri();
1697 var protocols = this.opts.protocols; // React Native only supports the 'headers' option, and will print a warning if anything else is passed
1698
1699 var opts = isReactNative ? {} : pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity");
1700
1701 if (this.opts.extraHeaders) {
1702 opts.headers = this.opts.extraHeaders;
1703 }
1704
1705 try {
1706 this.ws = usingBrowserWebSocket && !isReactNative ? protocols ? new WebSocket(uri, protocols) : new WebSocket(uri) : new WebSocket(uri, protocols, opts);
1707 } catch (err) {
1708 return this.emit("error", err);
1709 }
1710
1711 this.ws.binaryType = this.socket.binaryType || defaultBinaryType;
1712 this.addEventListeners();
1713 }
1714 /**
1715 * Adds event listeners to the socket
1716 *
1717 * @api private
1718 */
1719
1720 }, {
1721 key: "addEventListeners",
1722 value: function addEventListeners() {
1723 var _this2 = this;
1724
1725 this.ws.onopen = function () {
1726 if (_this2.opts.autoUnref) {
1727 _this2.ws._socket.unref();
1728 }
1729
1730 _this2.onOpen();
1731 };
1732
1733 this.ws.onclose = this.onClose.bind(this);
1734
1735 this.ws.onmessage = function (ev) {
1736 return _this2.onData(ev.data);
1737 };
1738
1739 this.ws.onerror = function (e) {
1740 return _this2.onError("websocket error", e);
1741 };
1742 }
1743 /**
1744 * Writes data to socket.
1745 *
1746 * @param {Array} array of packets.
1747 * @api private
1748 */
1749
1750 }, {
1751 key: "write",
1752 value: function write(packets) {
1753 var _this3 = this;
1754
1755 this.writable = false; // encodePacket efficient as it uses WS framing
1756 // no need for encodePayload
1757
1758 var _loop = function _loop(i) {
1759 var packet = packets[i];
1760 var lastPacket = i === packets.length - 1;
1761 encodePacket(packet, _this3.supportsBinary, function (data) {
1762 // always create a new object (GH-437)
1763 var opts = {};
1764 // have a chance of informing us about it yet, in that case send will
1765 // throw an error
1766
1767
1768 try {
1769 if (usingBrowserWebSocket) {
1770 // TypeError is thrown when passing the second argument on Safari
1771 _this3.ws.send(data);
1772 }
1773 } catch (e) {}
1774
1775 if (lastPacket) {
1776 // fake drain
1777 // defer to next tick to allow Socket to clear writeBuffer
1778 nextTick(function () {
1779 _this3.writable = true;
1780
1781 _this3.emit("drain");
1782 }, _this3.setTimeoutFn);
1783 }
1784 });
1785 };
1786
1787 for (var i = 0; i < packets.length; i++) {
1788 _loop(i);
1789 }
1790 }
1791 /**
1792 * Closes socket.
1793 *
1794 * @api private
1795 */
1796
1797 }, {
1798 key: "doClose",
1799 value: function doClose() {
1800 if (typeof this.ws !== "undefined") {
1801 this.ws.close();
1802 this.ws = null;
1803 }
1804 }
1805 /**
1806 * Generates uri for connection.
1807 *
1808 * @api private
1809 */
1810
1811 }, {
1812 key: "uri",
1813 value: function uri() {
1814 var query = this.query || {};
1815 var schema = this.opts.secure ? "wss" : "ws";
1816 var port = ""; // avoid port if default for schema
1817
1818 if (this.opts.port && ("wss" === schema && Number(this.opts.port) !== 443 || "ws" === schema && Number(this.opts.port) !== 80)) {
1819 port = ":" + this.opts.port;
1820 } // append timestamp to URI
1821
1822
1823 if (this.opts.timestampRequests) {
1824 query[this.opts.timestampParam] = yeast_1();
1825 } // communicate binary support capabilities
1826
1827
1828 if (!this.supportsBinary) {
1829 query.b64 = 1;
1830 }
1831
1832 var encodedQuery = parseqs.encode(query);
1833 var ipv6 = this.opts.hostname.indexOf(":") !== -1;
1834 return schema + "://" + (ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) + port + this.opts.path + (encodedQuery.length ? "?" + encodedQuery : "");
1835 }
1836 /**
1837 * Feature detection for WebSocket.
1838 *
1839 * @return {Boolean} whether this transport is available.
1840 * @api public
1841 */
1842
1843 }, {
1844 key: "check",
1845 value: function check() {
1846 return !!WebSocket && !("__initialize" in WebSocket && this.name === WS.prototype.name);
1847 }
1848 }]);
1849
1850 return WS;
1851 }(Transport);
1852
1853 var transports = {
1854 websocket: WS,
1855 polling: XHR
1856 };
1857
1858 var Socket$1 = /*#__PURE__*/function (_Emitter) {
1859 _inherits(Socket, _Emitter);
1860
1861 var _super = _createSuper(Socket);
1862
1863 /**
1864 * Socket constructor.
1865 *
1866 * @param {String|Object} uri or options
1867 * @param {Object} opts - options
1868 * @api public
1869 */
1870 function Socket(uri) {
1871 var _this;
1872
1873 var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1874
1875 _classCallCheck(this, Socket);
1876
1877 _this = _super.call(this);
1878
1879 if (uri && "object" === _typeof(uri)) {
1880 opts = uri;
1881 uri = null;
1882 }
1883
1884 if (uri) {
1885 uri = parseuri(uri);
1886 opts.hostname = uri.host;
1887 opts.secure = uri.protocol === "https" || uri.protocol === "wss";
1888 opts.port = uri.port;
1889 if (uri.query) opts.query = uri.query;
1890 } else if (opts.host) {
1891 opts.hostname = parseuri(opts.host).host;
1892 }
1893
1894 installTimerFunctions(_assertThisInitialized(_this), opts);
1895 _this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol;
1896
1897 if (opts.hostname && !opts.port) {
1898 // if no port is specified manually, use the protocol default
1899 opts.port = _this.secure ? "443" : "80";
1900 }
1901
1902 _this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost");
1903 _this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : _this.secure ? "443" : "80");
1904 _this.transports = opts.transports || ["polling", "websocket"];
1905 _this.readyState = "";
1906 _this.writeBuffer = [];
1907 _this.prevBufferLen = 0;
1908 _this.opts = _extends({
1909 path: "/engine.io",
1910 agent: false,
1911 withCredentials: false,
1912 upgrade: true,
1913 timestampParam: "t",
1914 rememberUpgrade: false,
1915 rejectUnauthorized: true,
1916 perMessageDeflate: {
1917 threshold: 1024
1918 },
1919 transportOptions: {},
1920 closeOnBeforeunload: true
1921 }, opts);
1922 _this.opts.path = _this.opts.path.replace(/\/$/, "") + "/";
1923
1924 if (typeof _this.opts.query === "string") {
1925 _this.opts.query = parseqs.decode(_this.opts.query);
1926 } // set on handshake
1927
1928
1929 _this.id = null;
1930 _this.upgrades = null;
1931 _this.pingInterval = null;
1932 _this.pingTimeout = null; // set on heartbeat
1933
1934 _this.pingTimeoutTimer = null;
1935
1936 if (typeof addEventListener === "function") {
1937 if (_this.opts.closeOnBeforeunload) {
1938 // Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
1939 // ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
1940 // closed/reloaded)
1941 addEventListener("beforeunload", function () {
1942 if (_this.transport) {
1943 // silently close the transport
1944 _this.transport.removeAllListeners();
1945
1946 _this.transport.close();
1947 }
1948 }, false);
1949 }
1950
1951 if (_this.hostname !== "localhost") {
1952 _this.offlineEventListener = function () {
1953 _this.onClose("transport close");
1954 };
1955
1956 addEventListener("offline", _this.offlineEventListener, false);
1957 }
1958 }
1959
1960 _this.open();
1961
1962 return _this;
1963 }
1964 /**
1965 * Creates transport of the given type.
1966 *
1967 * @param {String} transport name
1968 * @return {Transport}
1969 * @api private
1970 */
1971
1972
1973 _createClass(Socket, [{
1974 key: "createTransport",
1975 value: function createTransport(name) {
1976 var query = clone(this.opts.query); // append engine.io protocol identifier
1977
1978 query.EIO = protocol$1; // transport name
1979
1980 query.transport = name; // session id if we already have one
1981
1982 if (this.id) query.sid = this.id;
1983
1984 var opts = _extends({}, this.opts.transportOptions[name], this.opts, {
1985 query: query,
1986 socket: this,
1987 hostname: this.hostname,
1988 secure: this.secure,
1989 port: this.port
1990 });
1991
1992 return new transports[name](opts);
1993 }
1994 /**
1995 * Initializes transport to use and starts probe.
1996 *
1997 * @api private
1998 */
1999
2000 }, {
2001 key: "open",
2002 value: function open() {
2003 var _this2 = this;
2004
2005 var transport;
2006
2007 if (this.opts.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1) {
2008 transport = "websocket";
2009 } else if (0 === this.transports.length) {
2010 // Emit error on next tick so it can be listened to
2011 this.setTimeoutFn(function () {
2012 _this2.emitReserved("error", "No transports available");
2013 }, 0);
2014 return;
2015 } else {
2016 transport = this.transports[0];
2017 }
2018
2019 this.readyState = "opening"; // Retry with the next transport if the transport is disabled (jsonp: false)
2020
2021 try {
2022 transport = this.createTransport(transport);
2023 } catch (e) {
2024 this.transports.shift();
2025 this.open();
2026 return;
2027 }
2028
2029 transport.open();
2030 this.setTransport(transport);
2031 }
2032 /**
2033 * Sets the current transport. Disables the existing one (if any).
2034 *
2035 * @api private
2036 */
2037
2038 }, {
2039 key: "setTransport",
2040 value: function setTransport(transport) {
2041 var _this3 = this;
2042
2043 if (this.transport) {
2044 this.transport.removeAllListeners();
2045 } // set up transport
2046
2047
2048 this.transport = transport; // set up transport listeners
2049
2050 transport.on("drain", this.onDrain.bind(this)).on("packet", this.onPacket.bind(this)).on("error", this.onError.bind(this)).on("close", function () {
2051 _this3.onClose("transport close");
2052 });
2053 }
2054 /**
2055 * Probes a transport.
2056 *
2057 * @param {String} transport name
2058 * @api private
2059 */
2060
2061 }, {
2062 key: "probe",
2063 value: function probe(name) {
2064 var _this4 = this;
2065
2066 var transport = this.createTransport(name);
2067 var failed = false;
2068 Socket.priorWebsocketSuccess = false;
2069
2070 var onTransportOpen = function onTransportOpen() {
2071 if (failed) return;
2072 transport.send([{
2073 type: "ping",
2074 data: "probe"
2075 }]);
2076 transport.once("packet", function (msg) {
2077 if (failed) return;
2078
2079 if ("pong" === msg.type && "probe" === msg.data) {
2080 _this4.upgrading = true;
2081
2082 _this4.emitReserved("upgrading", transport);
2083
2084 if (!transport) return;
2085 Socket.priorWebsocketSuccess = "websocket" === transport.name;
2086
2087 _this4.transport.pause(function () {
2088 if (failed) return;
2089 if ("closed" === _this4.readyState) return;
2090 cleanup();
2091
2092 _this4.setTransport(transport);
2093
2094 transport.send([{
2095 type: "upgrade"
2096 }]);
2097
2098 _this4.emitReserved("upgrade", transport);
2099
2100 transport = null;
2101 _this4.upgrading = false;
2102
2103 _this4.flush();
2104 });
2105 } else {
2106 var err = new Error("probe error"); // @ts-ignore
2107
2108 err.transport = transport.name;
2109
2110 _this4.emitReserved("upgradeError", err);
2111 }
2112 });
2113 };
2114
2115 function freezeTransport() {
2116 if (failed) return; // Any callback called by transport should be ignored since now
2117
2118 failed = true;
2119 cleanup();
2120 transport.close();
2121 transport = null;
2122 } // Handle any error that happens while probing
2123
2124
2125 var onerror = function onerror(err) {
2126 var error = new Error("probe error: " + err); // @ts-ignore
2127
2128 error.transport = transport.name;
2129 freezeTransport();
2130
2131 _this4.emitReserved("upgradeError", error);
2132 };
2133
2134 function onTransportClose() {
2135 onerror("transport closed");
2136 } // When the socket is closed while we're probing
2137
2138
2139 function onclose() {
2140 onerror("socket closed");
2141 } // When the socket is upgraded while we're probing
2142
2143
2144 function onupgrade(to) {
2145 if (transport && to.name !== transport.name) {
2146 freezeTransport();
2147 }
2148 } // Remove all listeners on the transport and on self
2149
2150
2151 var cleanup = function cleanup() {
2152 transport.removeListener("open", onTransportOpen);
2153 transport.removeListener("error", onerror);
2154 transport.removeListener("close", onTransportClose);
2155
2156 _this4.off("close", onclose);
2157
2158 _this4.off("upgrading", onupgrade);
2159 };
2160
2161 transport.once("open", onTransportOpen);
2162 transport.once("error", onerror);
2163 transport.once("close", onTransportClose);
2164 this.once("close", onclose);
2165 this.once("upgrading", onupgrade);
2166 transport.open();
2167 }
2168 /**
2169 * Called when connection is deemed open.
2170 *
2171 * @api private
2172 */
2173
2174 }, {
2175 key: "onOpen",
2176 value: function onOpen() {
2177 this.readyState = "open";
2178 Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
2179 this.emitReserved("open");
2180 this.flush(); // we check for `readyState` in case an `open`
2181 // listener already closed the socket
2182
2183 if ("open" === this.readyState && this.opts.upgrade && this.transport.pause) {
2184 var i = 0;
2185 var l = this.upgrades.length;
2186
2187 for (; i < l; i++) {
2188 this.probe(this.upgrades[i]);
2189 }
2190 }
2191 }
2192 /**
2193 * Handles a packet.
2194 *
2195 * @api private
2196 */
2197
2198 }, {
2199 key: "onPacket",
2200 value: function onPacket(packet) {
2201 if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) {
2202 this.emitReserved("packet", packet); // Socket is live - any packet counts
2203
2204 this.emitReserved("heartbeat");
2205
2206 switch (packet.type) {
2207 case "open":
2208 this.onHandshake(JSON.parse(packet.data));
2209 break;
2210
2211 case "ping":
2212 this.resetPingTimeout();
2213 this.sendPacket("pong");
2214 this.emitReserved("ping");
2215 this.emitReserved("pong");
2216 break;
2217
2218 case "error":
2219 var err = new Error("server error"); // @ts-ignore
2220
2221 err.code = packet.data;
2222 this.onError(err);
2223 break;
2224
2225 case "message":
2226 this.emitReserved("data", packet.data);
2227 this.emitReserved("message", packet.data);
2228 break;
2229 }
2230 }
2231 }
2232 /**
2233 * Called upon handshake completion.
2234 *
2235 * @param {Object} data - handshake obj
2236 * @api private
2237 */
2238
2239 }, {
2240 key: "onHandshake",
2241 value: function onHandshake(data) {
2242 this.emitReserved("handshake", data);
2243 this.id = data.sid;
2244 this.transport.query.sid = data.sid;
2245 this.upgrades = this.filterUpgrades(data.upgrades);
2246 this.pingInterval = data.pingInterval;
2247 this.pingTimeout = data.pingTimeout;
2248 this.onOpen(); // In case open handler closes socket
2249
2250 if ("closed" === this.readyState) return;
2251 this.resetPingTimeout();
2252 }
2253 /**
2254 * Sets and resets ping timeout timer based on server pings.
2255 *
2256 * @api private
2257 */
2258
2259 }, {
2260 key: "resetPingTimeout",
2261 value: function resetPingTimeout() {
2262 var _this5 = this;
2263
2264 this.clearTimeoutFn(this.pingTimeoutTimer);
2265 this.pingTimeoutTimer = this.setTimeoutFn(function () {
2266 _this5.onClose("ping timeout");
2267 }, this.pingInterval + this.pingTimeout);
2268
2269 if (this.opts.autoUnref) {
2270 this.pingTimeoutTimer.unref();
2271 }
2272 }
2273 /**
2274 * Called on `drain` event
2275 *
2276 * @api private
2277 */
2278
2279 }, {
2280 key: "onDrain",
2281 value: function onDrain() {
2282 this.writeBuffer.splice(0, this.prevBufferLen); // setting prevBufferLen = 0 is very important
2283 // for example, when upgrading, upgrade packet is sent over,
2284 // and a nonzero prevBufferLen could cause problems on `drain`
2285
2286 this.prevBufferLen = 0;
2287
2288 if (0 === this.writeBuffer.length) {
2289 this.emitReserved("drain");
2290 } else {
2291 this.flush();
2292 }
2293 }
2294 /**
2295 * Flush write buffers.
2296 *
2297 * @api private
2298 */
2299
2300 }, {
2301 key: "flush",
2302 value: function flush() {
2303 if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) {
2304 this.transport.send(this.writeBuffer); // keep track of current length of writeBuffer
2305 // splice writeBuffer and callbackBuffer on `drain`
2306
2307 this.prevBufferLen = this.writeBuffer.length;
2308 this.emitReserved("flush");
2309 }
2310 }
2311 /**
2312 * Sends a message.
2313 *
2314 * @param {String} message.
2315 * @param {Function} callback function.
2316 * @param {Object} options.
2317 * @return {Socket} for chaining.
2318 * @api public
2319 */
2320
2321 }, {
2322 key: "write",
2323 value: function write(msg, options, fn) {
2324 this.sendPacket("message", msg, options, fn);
2325 return this;
2326 }
2327 }, {
2328 key: "send",
2329 value: function send(msg, options, fn) {
2330 this.sendPacket("message", msg, options, fn);
2331 return this;
2332 }
2333 /**
2334 * Sends a packet.
2335 *
2336 * @param {String} packet type.
2337 * @param {String} data.
2338 * @param {Object} options.
2339 * @param {Function} callback function.
2340 * @api private
2341 */
2342
2343 }, {
2344 key: "sendPacket",
2345 value: function sendPacket(type, data, options, fn) {
2346 if ("function" === typeof data) {
2347 fn = data;
2348 data = undefined;
2349 }
2350
2351 if ("function" === typeof options) {
2352 fn = options;
2353 options = null;
2354 }
2355
2356 if ("closing" === this.readyState || "closed" === this.readyState) {
2357 return;
2358 }
2359
2360 options = options || {};
2361 options.compress = false !== options.compress;
2362 var packet = {
2363 type: type,
2364 data: data,
2365 options: options
2366 };
2367 this.emitReserved("packetCreate", packet);
2368 this.writeBuffer.push(packet);
2369 if (fn) this.once("flush", fn);
2370 this.flush();
2371 }
2372 /**
2373 * Closes the connection.
2374 *
2375 * @api public
2376 */
2377
2378 }, {
2379 key: "close",
2380 value: function close() {
2381 var _this6 = this;
2382
2383 var close = function close() {
2384 _this6.onClose("forced close");
2385
2386 _this6.transport.close();
2387 };
2388
2389 var cleanupAndClose = function cleanupAndClose() {
2390 _this6.off("upgrade", cleanupAndClose);
2391
2392 _this6.off("upgradeError", cleanupAndClose);
2393
2394 close();
2395 };
2396
2397 var waitForUpgrade = function waitForUpgrade() {
2398 // wait for upgrade to finish since we can't send packets while pausing a transport
2399 _this6.once("upgrade", cleanupAndClose);
2400
2401 _this6.once("upgradeError", cleanupAndClose);
2402 };
2403
2404 if ("opening" === this.readyState || "open" === this.readyState) {
2405 this.readyState = "closing";
2406
2407 if (this.writeBuffer.length) {
2408 this.once("drain", function () {
2409 if (_this6.upgrading) {
2410 waitForUpgrade();
2411 } else {
2412 close();
2413 }
2414 });
2415 } else if (this.upgrading) {
2416 waitForUpgrade();
2417 } else {
2418 close();
2419 }
2420 }
2421
2422 return this;
2423 }
2424 /**
2425 * Called upon transport error
2426 *
2427 * @api private
2428 */
2429
2430 }, {
2431 key: "onError",
2432 value: function onError(err) {
2433 Socket.priorWebsocketSuccess = false;
2434 this.emitReserved("error", err);
2435 this.onClose("transport error", err);
2436 }
2437 /**
2438 * Called upon transport close.
2439 *
2440 * @api private
2441 */
2442
2443 }, {
2444 key: "onClose",
2445 value: function onClose(reason, desc) {
2446 if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) {
2447 // clear timers
2448 this.clearTimeoutFn(this.pingTimeoutTimer); // stop event from firing again for transport
2449
2450 this.transport.removeAllListeners("close"); // ensure transport won't stay open
2451
2452 this.transport.close(); // ignore further transport communication
2453
2454 this.transport.removeAllListeners();
2455
2456 if (typeof removeEventListener === "function") {
2457 removeEventListener("offline", this.offlineEventListener, false);
2458 } // set ready state
2459
2460
2461 this.readyState = "closed"; // clear session id
2462
2463 this.id = null; // emit close event
2464
2465 this.emitReserved("close", reason, desc); // clean buffers after, so users can still
2466 // grab the buffers on `close` event
2467
2468 this.writeBuffer = [];
2469 this.prevBufferLen = 0;
2470 }
2471 }
2472 /**
2473 * Filters upgrades, returning only those matching client transports.
2474 *
2475 * @param {Array} server upgrades
2476 * @api private
2477 *
2478 */
2479
2480 }, {
2481 key: "filterUpgrades",
2482 value: function filterUpgrades(upgrades) {
2483 var filteredUpgrades = [];
2484 var i = 0;
2485 var j = upgrades.length;
2486
2487 for (; i < j; i++) {
2488 if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]);
2489 }
2490
2491 return filteredUpgrades;
2492 }
2493 }]);
2494
2495 return Socket;
2496 }(Emitter_1);
2497 Socket$1.protocol = protocol$1;
2498
2499 function clone(obj) {
2500 var o = {};
2501
2502 for (var i in obj) {
2503 if (obj.hasOwnProperty(i)) {
2504 o[i] = obj[i];
2505 }
2506 }
2507
2508 return o;
2509 }
2510
2511 var withNativeArrayBuffer = typeof ArrayBuffer === "function";
2512
2513 var isView = function isView(obj) {
2514 return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer;
2515 };
2516
2517 var toString = Object.prototype.toString;
2518 var withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && toString.call(Blob) === "[object BlobConstructor]";
2519 var withNativeFile = typeof File === "function" || typeof File !== "undefined" && toString.call(File) === "[object FileConstructor]";
2520 /**
2521 * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.
2522 *
2523 * @private
2524 */
2525
2526 function isBinary(obj) {
2527 return withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)) || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File;
2528 }
2529 function hasBinary(obj, toJSON) {
2530 if (!obj || _typeof(obj) !== "object") {
2531 return false;
2532 }
2533
2534 if (Array.isArray(obj)) {
2535 for (var i = 0, l = obj.length; i < l; i++) {
2536 if (hasBinary(obj[i])) {
2537 return true;
2538 }
2539 }
2540
2541 return false;
2542 }
2543
2544 if (isBinary(obj)) {
2545 return true;
2546 }
2547
2548 if (obj.toJSON && typeof obj.toJSON === "function" && arguments.length === 1) {
2549 return hasBinary(obj.toJSON(), true);
2550 }
2551
2552 for (var key in obj) {
2553 if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
2554 return true;
2555 }
2556 }
2557
2558 return false;
2559 }
2560
2561 /**
2562 * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder.
2563 *
2564 * @param {Object} packet - socket.io event packet
2565 * @return {Object} with deconstructed packet and list of buffers
2566 * @public
2567 */
2568
2569 function deconstructPacket(packet) {
2570 var buffers = [];
2571 var packetData = packet.data;
2572 var pack = packet;
2573 pack.data = _deconstructPacket(packetData, buffers);
2574 pack.attachments = buffers.length; // number of binary 'attachments'
2575
2576 return {
2577 packet: pack,
2578 buffers: buffers
2579 };
2580 }
2581
2582 function _deconstructPacket(data, buffers) {
2583 if (!data) return data;
2584
2585 if (isBinary(data)) {
2586 var placeholder = {
2587 _placeholder: true,
2588 num: buffers.length
2589 };
2590 buffers.push(data);
2591 return placeholder;
2592 } else if (Array.isArray(data)) {
2593 var newData = new Array(data.length);
2594
2595 for (var i = 0; i < data.length; i++) {
2596 newData[i] = _deconstructPacket(data[i], buffers);
2597 }
2598
2599 return newData;
2600 } else if (_typeof(data) === "object" && !(data instanceof Date)) {
2601 var _newData = {};
2602
2603 for (var key in data) {
2604 if (data.hasOwnProperty(key)) {
2605 _newData[key] = _deconstructPacket(data[key], buffers);
2606 }
2607 }
2608
2609 return _newData;
2610 }
2611
2612 return data;
2613 }
2614 /**
2615 * Reconstructs a binary packet from its placeholder packet and buffers
2616 *
2617 * @param {Object} packet - event packet with placeholders
2618 * @param {Array} buffers - binary buffers to put in placeholder positions
2619 * @return {Object} reconstructed packet
2620 * @public
2621 */
2622
2623
2624 function reconstructPacket(packet, buffers) {
2625 packet.data = _reconstructPacket(packet.data, buffers);
2626 packet.attachments = undefined; // no longer useful
2627
2628 return packet;
2629 }
2630
2631 function _reconstructPacket(data, buffers) {
2632 if (!data) return data;
2633
2634 if (data && data._placeholder) {
2635 return buffers[data.num]; // appropriate buffer (should be natural order anyway)
2636 } else if (Array.isArray(data)) {
2637 for (var i = 0; i < data.length; i++) {
2638 data[i] = _reconstructPacket(data[i], buffers);
2639 }
2640 } else if (_typeof(data) === "object") {
2641 for (var key in data) {
2642 if (data.hasOwnProperty(key)) {
2643 data[key] = _reconstructPacket(data[key], buffers);
2644 }
2645 }
2646 }
2647
2648 return data;
2649 }
2650
2651 /**
2652 * Protocol version.
2653 *
2654 * @public
2655 */
2656
2657 var protocol = 5;
2658 var PacketType;
2659
2660 (function (PacketType) {
2661 PacketType[PacketType["CONNECT"] = 0] = "CONNECT";
2662 PacketType[PacketType["DISCONNECT"] = 1] = "DISCONNECT";
2663 PacketType[PacketType["EVENT"] = 2] = "EVENT";
2664 PacketType[PacketType["ACK"] = 3] = "ACK";
2665 PacketType[PacketType["CONNECT_ERROR"] = 4] = "CONNECT_ERROR";
2666 PacketType[PacketType["BINARY_EVENT"] = 5] = "BINARY_EVENT";
2667 PacketType[PacketType["BINARY_ACK"] = 6] = "BINARY_ACK";
2668 })(PacketType || (PacketType = {}));
2669 /**
2670 * A socket.io Encoder instance
2671 */
2672
2673
2674 var Encoder = /*#__PURE__*/function () {
2675 function Encoder() {
2676 _classCallCheck(this, Encoder);
2677 }
2678
2679 _createClass(Encoder, [{
2680 key: "encode",
2681 value:
2682 /**
2683 * Encode a packet as a single string if non-binary, or as a
2684 * buffer sequence, depending on packet type.
2685 *
2686 * @param {Object} obj - packet object
2687 */
2688 function encode(obj) {
2689 if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {
2690 if (hasBinary(obj)) {
2691 obj.type = obj.type === PacketType.EVENT ? PacketType.BINARY_EVENT : PacketType.BINARY_ACK;
2692 return this.encodeAsBinary(obj);
2693 }
2694 }
2695
2696 return [this.encodeAsString(obj)];
2697 }
2698 /**
2699 * Encode packet as string.
2700 */
2701
2702 }, {
2703 key: "encodeAsString",
2704 value: function encodeAsString(obj) {
2705 // first is type
2706 var str = "" + obj.type; // attachments if we have them
2707
2708 if (obj.type === PacketType.BINARY_EVENT || obj.type === PacketType.BINARY_ACK) {
2709 str += obj.attachments + "-";
2710 } // if we have a namespace other than `/`
2711 // we append it followed by a comma `,`
2712
2713
2714 if (obj.nsp && "/" !== obj.nsp) {
2715 str += obj.nsp + ",";
2716 } // immediately followed by the id
2717
2718
2719 if (null != obj.id) {
2720 str += obj.id;
2721 } // json data
2722
2723
2724 if (null != obj.data) {
2725 str += JSON.stringify(obj.data);
2726 }
2727
2728 return str;
2729 }
2730 /**
2731 * Encode packet as 'buffer sequence' by removing blobs, and
2732 * deconstructing packet into object with placeholders and
2733 * a list of buffers.
2734 */
2735
2736 }, {
2737 key: "encodeAsBinary",
2738 value: function encodeAsBinary(obj) {
2739 var deconstruction = deconstructPacket(obj);
2740 var pack = this.encodeAsString(deconstruction.packet);
2741 var buffers = deconstruction.buffers;
2742 buffers.unshift(pack); // add packet info to beginning of data list
2743
2744 return buffers; // write all the buffers
2745 }
2746 }]);
2747
2748 return Encoder;
2749 }();
2750 /**
2751 * A socket.io Decoder instance
2752 *
2753 * @return {Object} decoder
2754 */
2755
2756 var Decoder = /*#__PURE__*/function (_Emitter) {
2757 _inherits(Decoder, _Emitter);
2758
2759 var _super = _createSuper(Decoder);
2760
2761 function Decoder() {
2762 _classCallCheck(this, Decoder);
2763
2764 return _super.call(this);
2765 }
2766 /**
2767 * Decodes an encoded packet string into packet JSON.
2768 *
2769 * @param {String} obj - encoded packet
2770 */
2771
2772
2773 _createClass(Decoder, [{
2774 key: "add",
2775 value: function add(obj) {
2776 var packet;
2777
2778 if (typeof obj === "string") {
2779 packet = this.decodeString(obj);
2780
2781 if (packet.type === PacketType.BINARY_EVENT || packet.type === PacketType.BINARY_ACK) {
2782 // binary packet's json
2783 this.reconstructor = new BinaryReconstructor(packet); // no attachments, labeled binary but no binary data to follow
2784
2785 if (packet.attachments === 0) {
2786 _get(_getPrototypeOf(Decoder.prototype), "emitReserved", this).call(this, "decoded", packet);
2787 }
2788 } else {
2789 // non-binary full packet
2790 _get(_getPrototypeOf(Decoder.prototype), "emitReserved", this).call(this, "decoded", packet);
2791 }
2792 } else if (isBinary(obj) || obj.base64) {
2793 // raw binary data
2794 if (!this.reconstructor) {
2795 throw new Error("got binary data when not reconstructing a packet");
2796 } else {
2797 packet = this.reconstructor.takeBinaryData(obj);
2798
2799 if (packet) {
2800 // received final buffer
2801 this.reconstructor = null;
2802
2803 _get(_getPrototypeOf(Decoder.prototype), "emitReserved", this).call(this, "decoded", packet);
2804 }
2805 }
2806 } else {
2807 throw new Error("Unknown type: " + obj);
2808 }
2809 }
2810 /**
2811 * Decode a packet String (JSON data)
2812 *
2813 * @param {String} str
2814 * @return {Object} packet
2815 */
2816
2817 }, {
2818 key: "decodeString",
2819 value: function decodeString(str) {
2820 var i = 0; // look up type
2821
2822 var p = {
2823 type: Number(str.charAt(0))
2824 };
2825
2826 if (PacketType[p.type] === undefined) {
2827 throw new Error("unknown packet type " + p.type);
2828 } // look up attachments if type binary
2829
2830
2831 if (p.type === PacketType.BINARY_EVENT || p.type === PacketType.BINARY_ACK) {
2832 var start = i + 1;
2833
2834 while (str.charAt(++i) !== "-" && i != str.length) {}
2835
2836 var buf = str.substring(start, i);
2837
2838 if (buf != Number(buf) || str.charAt(i) !== "-") {
2839 throw new Error("Illegal attachments");
2840 }
2841
2842 p.attachments = Number(buf);
2843 } // look up namespace (if any)
2844
2845
2846 if ("/" === str.charAt(i + 1)) {
2847 var _start = i + 1;
2848
2849 while (++i) {
2850 var c = str.charAt(i);
2851 if ("," === c) break;
2852 if (i === str.length) break;
2853 }
2854
2855 p.nsp = str.substring(_start, i);
2856 } else {
2857 p.nsp = "/";
2858 } // look up id
2859
2860
2861 var next = str.charAt(i + 1);
2862
2863 if ("" !== next && Number(next) == next) {
2864 var _start2 = i + 1;
2865
2866 while (++i) {
2867 var _c = str.charAt(i);
2868
2869 if (null == _c || Number(_c) != _c) {
2870 --i;
2871 break;
2872 }
2873
2874 if (i === str.length) break;
2875 }
2876
2877 p.id = Number(str.substring(_start2, i + 1));
2878 } // look up json data
2879
2880
2881 if (str.charAt(++i)) {
2882 var payload = tryParse(str.substr(i));
2883
2884 if (Decoder.isPayloadValid(p.type, payload)) {
2885 p.data = payload;
2886 } else {
2887 throw new Error("invalid payload");
2888 }
2889 }
2890
2891 return p;
2892 }
2893 }, {
2894 key: "destroy",
2895 value:
2896 /**
2897 * Deallocates a parser's resources
2898 */
2899 function destroy() {
2900 if (this.reconstructor) {
2901 this.reconstructor.finishedReconstruction();
2902 }
2903 }
2904 }], [{
2905 key: "isPayloadValid",
2906 value: function isPayloadValid(type, payload) {
2907 switch (type) {
2908 case PacketType.CONNECT:
2909 return _typeof(payload) === "object";
2910
2911 case PacketType.DISCONNECT:
2912 return payload === undefined;
2913
2914 case PacketType.CONNECT_ERROR:
2915 return typeof payload === "string" || _typeof(payload) === "object";
2916
2917 case PacketType.EVENT:
2918 case PacketType.BINARY_EVENT:
2919 return Array.isArray(payload) && payload.length > 0;
2920
2921 case PacketType.ACK:
2922 case PacketType.BINARY_ACK:
2923 return Array.isArray(payload);
2924 }
2925 }
2926 }]);
2927
2928 return Decoder;
2929 }(Emitter_1);
2930
2931 function tryParse(str) {
2932 try {
2933 return JSON.parse(str);
2934 } catch (e) {
2935 return false;
2936 }
2937 }
2938 /**
2939 * A manager of a binary event's 'buffer sequence'. Should
2940 * be constructed whenever a packet of type BINARY_EVENT is
2941 * decoded.
2942 *
2943 * @param {Object} packet
2944 * @return {BinaryReconstructor} initialized reconstructor
2945 */
2946
2947
2948 var BinaryReconstructor = /*#__PURE__*/function () {
2949 function BinaryReconstructor(packet) {
2950 _classCallCheck(this, BinaryReconstructor);
2951
2952 this.packet = packet;
2953 this.buffers = [];
2954 this.reconPack = packet;
2955 }
2956 /**
2957 * Method to be called when binary data received from connection
2958 * after a BINARY_EVENT packet.
2959 *
2960 * @param {Buffer | ArrayBuffer} binData - the raw binary data received
2961 * @return {null | Object} returns null if more binary data is expected or
2962 * a reconstructed packet object if all buffers have been received.
2963 */
2964
2965
2966 _createClass(BinaryReconstructor, [{
2967 key: "takeBinaryData",
2968 value: function takeBinaryData(binData) {
2969 this.buffers.push(binData);
2970
2971 if (this.buffers.length === this.reconPack.attachments) {
2972 // done with buffer list
2973 var packet = reconstructPacket(this.reconPack, this.buffers);
2974 this.finishedReconstruction();
2975 return packet;
2976 }
2977
2978 return null;
2979 }
2980 /**
2981 * Cleans up binary packet reconstruction variables.
2982 */
2983
2984 }, {
2985 key: "finishedReconstruction",
2986 value: function finishedReconstruction() {
2987 this.reconPack = null;
2988 this.buffers = [];
2989 }
2990 }]);
2991
2992 return BinaryReconstructor;
2993 }();
2994
2995 var parser = /*#__PURE__*/Object.freeze({
2996 __proto__: null,
2997 protocol: protocol,
2998 get PacketType () { return PacketType; },
2999 Encoder: Encoder,
3000 Decoder: Decoder
3001 });
3002
3003 function on(obj, ev, fn) {
3004 obj.on(ev, fn);
3005 return function subDestroy() {
3006 obj.off(ev, fn);
3007 };
3008 }
3009
3010 /**
3011 * Internal events.
3012 * These events can't be emitted by the user.
3013 */
3014
3015 var RESERVED_EVENTS = Object.freeze({
3016 connect: 1,
3017 connect_error: 1,
3018 disconnect: 1,
3019 disconnecting: 1,
3020 // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener
3021 newListener: 1,
3022 removeListener: 1
3023 });
3024 var Socket = /*#__PURE__*/function (_Emitter) {
3025 _inherits(Socket, _Emitter);
3026
3027 var _super = _createSuper(Socket);
3028
3029 /**
3030 * `Socket` constructor.
3031 *
3032 * @public
3033 */
3034 function Socket(io, nsp, opts) {
3035 var _this;
3036
3037 _classCallCheck(this, Socket);
3038
3039 _this = _super.call(this);
3040 _this.connected = false;
3041 _this.disconnected = true;
3042 _this.receiveBuffer = [];
3043 _this.sendBuffer = [];
3044 _this.ids = 0;
3045 _this.acks = {};
3046 _this.flags = {};
3047 _this.io = io;
3048 _this.nsp = nsp;
3049
3050 if (opts && opts.auth) {
3051 _this.auth = opts.auth;
3052 }
3053
3054 if (_this.io._autoConnect) _this.open();
3055 return _this;
3056 }
3057 /**
3058 * Subscribe to open, close and packet events
3059 *
3060 * @private
3061 */
3062
3063
3064 _createClass(Socket, [{
3065 key: "subEvents",
3066 value: function subEvents() {
3067 if (this.subs) return;
3068 var io = this.io;
3069 this.subs = [on(io, "open", this.onopen.bind(this)), on(io, "packet", this.onpacket.bind(this)), on(io, "error", this.onerror.bind(this)), on(io, "close", this.onclose.bind(this))];
3070 }
3071 /**
3072 * Whether the Socket will try to reconnect when its Manager connects or reconnects
3073 */
3074
3075 }, {
3076 key: "active",
3077 get: function get() {
3078 return !!this.subs;
3079 }
3080 /**
3081 * "Opens" the socket.
3082 *
3083 * @public
3084 */
3085
3086 }, {
3087 key: "connect",
3088 value: function connect() {
3089 if (this.connected) return this;
3090 this.subEvents();
3091 if (!this.io["_reconnecting"]) this.io.open(); // ensure open
3092
3093 if ("open" === this.io._readyState) this.onopen();
3094 return this;
3095 }
3096 /**
3097 * Alias for connect()
3098 */
3099
3100 }, {
3101 key: "open",
3102 value: function open() {
3103 return this.connect();
3104 }
3105 /**
3106 * Sends a `message` event.
3107 *
3108 * @return self
3109 * @public
3110 */
3111
3112 }, {
3113 key: "send",
3114 value: function send() {
3115 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3116 args[_key] = arguments[_key];
3117 }
3118
3119 args.unshift("message");
3120 this.emit.apply(this, args);
3121 return this;
3122 }
3123 /**
3124 * Override `emit`.
3125 * If the event is in `events`, it's emitted normally.
3126 *
3127 * @return self
3128 * @public
3129 */
3130
3131 }, {
3132 key: "emit",
3133 value: function emit(ev) {
3134 if (RESERVED_EVENTS.hasOwnProperty(ev)) {
3135 throw new Error('"' + ev + '" is a reserved event name');
3136 }
3137
3138 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
3139 args[_key2 - 1] = arguments[_key2];
3140 }
3141
3142 args.unshift(ev);
3143 var packet = {
3144 type: PacketType.EVENT,
3145 data: args
3146 };
3147 packet.options = {};
3148 packet.options.compress = this.flags.compress !== false; // event ack callback
3149
3150 if ("function" === typeof args[args.length - 1]) {
3151 this.acks[this.ids] = args.pop();
3152 packet.id = this.ids++;
3153 }
3154
3155 var isTransportWritable = this.io.engine && this.io.engine.transport && this.io.engine.transport.writable;
3156 var discardPacket = this.flags["volatile"] && (!isTransportWritable || !this.connected);
3157
3158 if (discardPacket) ; else if (this.connected) {
3159 this.packet(packet);
3160 } else {
3161 this.sendBuffer.push(packet);
3162 }
3163
3164 this.flags = {};
3165 return this;
3166 }
3167 /**
3168 * Sends a packet.
3169 *
3170 * @param packet
3171 * @private
3172 */
3173
3174 }, {
3175 key: "packet",
3176 value: function packet(_packet) {
3177 _packet.nsp = this.nsp;
3178
3179 this.io._packet(_packet);
3180 }
3181 /**
3182 * Called upon engine `open`.
3183 *
3184 * @private
3185 */
3186
3187 }, {
3188 key: "onopen",
3189 value: function onopen() {
3190 var _this2 = this;
3191
3192 if (typeof this.auth == "function") {
3193 this.auth(function (data) {
3194 _this2.packet({
3195 type: PacketType.CONNECT,
3196 data: data
3197 });
3198 });
3199 } else {
3200 this.packet({
3201 type: PacketType.CONNECT,
3202 data: this.auth
3203 });
3204 }
3205 }
3206 /**
3207 * Called upon engine or manager `error`.
3208 *
3209 * @param err
3210 * @private
3211 */
3212
3213 }, {
3214 key: "onerror",
3215 value: function onerror(err) {
3216 if (!this.connected) {
3217 this.emitReserved("connect_error", err);
3218 }
3219 }
3220 /**
3221 * Called upon engine `close`.
3222 *
3223 * @param reason
3224 * @private
3225 */
3226
3227 }, {
3228 key: "onclose",
3229 value: function onclose(reason) {
3230 this.connected = false;
3231 this.disconnected = true;
3232 delete this.id;
3233 this.emitReserved("disconnect", reason);
3234 }
3235 /**
3236 * Called with socket packet.
3237 *
3238 * @param packet
3239 * @private
3240 */
3241
3242 }, {
3243 key: "onpacket",
3244 value: function onpacket(packet) {
3245 var sameNamespace = packet.nsp === this.nsp;
3246 if (!sameNamespace) return;
3247
3248 switch (packet.type) {
3249 case PacketType.CONNECT:
3250 if (packet.data && packet.data.sid) {
3251 var id = packet.data.sid;
3252 this.onconnect(id);
3253 } else {
3254 this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));
3255 }
3256
3257 break;
3258
3259 case PacketType.EVENT:
3260 this.onevent(packet);
3261 break;
3262
3263 case PacketType.BINARY_EVENT:
3264 this.onevent(packet);
3265 break;
3266
3267 case PacketType.ACK:
3268 this.onack(packet);
3269 break;
3270
3271 case PacketType.BINARY_ACK:
3272 this.onack(packet);
3273 break;
3274
3275 case PacketType.DISCONNECT:
3276 this.ondisconnect();
3277 break;
3278
3279 case PacketType.CONNECT_ERROR:
3280 var err = new Error(packet.data.message); // @ts-ignore
3281
3282 err.data = packet.data.data;
3283 this.emitReserved("connect_error", err);
3284 break;
3285 }
3286 }
3287 /**
3288 * Called upon a server event.
3289 *
3290 * @param packet
3291 * @private
3292 */
3293
3294 }, {
3295 key: "onevent",
3296 value: function onevent(packet) {
3297 var args = packet.data || [];
3298
3299 if (null != packet.id) {
3300 args.push(this.ack(packet.id));
3301 }
3302
3303 if (this.connected) {
3304 this.emitEvent(args);
3305 } else {
3306 this.receiveBuffer.push(Object.freeze(args));
3307 }
3308 }
3309 }, {
3310 key: "emitEvent",
3311 value: function emitEvent(args) {
3312 if (this._anyListeners && this._anyListeners.length) {
3313 var listeners = this._anyListeners.slice();
3314
3315 var _iterator = _createForOfIteratorHelper(listeners),
3316 _step;
3317
3318 try {
3319 for (_iterator.s(); !(_step = _iterator.n()).done;) {
3320 var listener = _step.value;
3321 listener.apply(this, args);
3322 }
3323 } catch (err) {
3324 _iterator.e(err);
3325 } finally {
3326 _iterator.f();
3327 }
3328 }
3329
3330 _get(_getPrototypeOf(Socket.prototype), "emit", this).apply(this, args);
3331 }
3332 /**
3333 * Produces an ack callback to emit with an event.
3334 *
3335 * @private
3336 */
3337
3338 }, {
3339 key: "ack",
3340 value: function ack(id) {
3341 var self = this;
3342 var sent = false;
3343 return function () {
3344 // prevent double callbacks
3345 if (sent) return;
3346 sent = true;
3347
3348 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
3349 args[_key3] = arguments[_key3];
3350 }
3351
3352 self.packet({
3353 type: PacketType.ACK,
3354 id: id,
3355 data: args
3356 });
3357 };
3358 }
3359 /**
3360 * Called upon a server acknowlegement.
3361 *
3362 * @param packet
3363 * @private
3364 */
3365
3366 }, {
3367 key: "onack",
3368 value: function onack(packet) {
3369 var ack = this.acks[packet.id];
3370
3371 if ("function" === typeof ack) {
3372 ack.apply(this, packet.data);
3373 delete this.acks[packet.id];
3374 }
3375 }
3376 /**
3377 * Called upon server connect.
3378 *
3379 * @private
3380 */
3381
3382 }, {
3383 key: "onconnect",
3384 value: function onconnect(id) {
3385 this.id = id;
3386 this.connected = true;
3387 this.disconnected = false;
3388 this.emitBuffered();
3389 this.emitReserved("connect");
3390 }
3391 /**
3392 * Emit buffered events (received and emitted).
3393 *
3394 * @private
3395 */
3396
3397 }, {
3398 key: "emitBuffered",
3399 value: function emitBuffered() {
3400 var _this3 = this;
3401
3402 this.receiveBuffer.forEach(function (args) {
3403 return _this3.emitEvent(args);
3404 });
3405 this.receiveBuffer = [];
3406 this.sendBuffer.forEach(function (packet) {
3407 return _this3.packet(packet);
3408 });
3409 this.sendBuffer = [];
3410 }
3411 /**
3412 * Called upon server disconnect.
3413 *
3414 * @private
3415 */
3416
3417 }, {
3418 key: "ondisconnect",
3419 value: function ondisconnect() {
3420 this.destroy();
3421 this.onclose("io server disconnect");
3422 }
3423 /**
3424 * Called upon forced client/server side disconnections,
3425 * this method ensures the manager stops tracking us and
3426 * that reconnections don't get triggered for this.
3427 *
3428 * @private
3429 */
3430
3431 }, {
3432 key: "destroy",
3433 value: function destroy() {
3434 if (this.subs) {
3435 // clean subscriptions to avoid reconnections
3436 this.subs.forEach(function (subDestroy) {
3437 return subDestroy();
3438 });
3439 this.subs = undefined;
3440 }
3441
3442 this.io["_destroy"](this);
3443 }
3444 /**
3445 * Disconnects the socket manually.
3446 *
3447 * @return self
3448 * @public
3449 */
3450
3451 }, {
3452 key: "disconnect",
3453 value: function disconnect() {
3454 if (this.connected) {
3455 this.packet({
3456 type: PacketType.DISCONNECT
3457 });
3458 } // remove socket from pool
3459
3460
3461 this.destroy();
3462
3463 if (this.connected) {
3464 // fire events
3465 this.onclose("io client disconnect");
3466 }
3467
3468 return this;
3469 }
3470 /**
3471 * Alias for disconnect()
3472 *
3473 * @return self
3474 * @public
3475 */
3476
3477 }, {
3478 key: "close",
3479 value: function close() {
3480 return this.disconnect();
3481 }
3482 /**
3483 * Sets the compress flag.
3484 *
3485 * @param compress - if `true`, compresses the sending data
3486 * @return self
3487 * @public
3488 */
3489
3490 }, {
3491 key: "compress",
3492 value: function compress(_compress) {
3493 this.flags.compress = _compress;
3494 return this;
3495 }
3496 /**
3497 * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not
3498 * ready to send messages.
3499 *
3500 * @returns self
3501 * @public
3502 */
3503
3504 }, {
3505 key: "volatile",
3506 get: function get() {
3507 this.flags["volatile"] = true;
3508 return this;
3509 }
3510 /**
3511 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
3512 * callback.
3513 *
3514 * @param listener
3515 * @public
3516 */
3517
3518 }, {
3519 key: "onAny",
3520 value: function onAny(listener) {
3521 this._anyListeners = this._anyListeners || [];
3522
3523 this._anyListeners.push(listener);
3524
3525 return this;
3526 }
3527 /**
3528 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
3529 * callback. The listener is added to the beginning of the listeners array.
3530 *
3531 * @param listener
3532 * @public
3533 */
3534
3535 }, {
3536 key: "prependAny",
3537 value: function prependAny(listener) {
3538 this._anyListeners = this._anyListeners || [];
3539
3540 this._anyListeners.unshift(listener);
3541
3542 return this;
3543 }
3544 /**
3545 * Removes the listener that will be fired when any event is emitted.
3546 *
3547 * @param listener
3548 * @public
3549 */
3550
3551 }, {
3552 key: "offAny",
3553 value: function offAny(listener) {
3554 if (!this._anyListeners) {
3555 return this;
3556 }
3557
3558 if (listener) {
3559 var listeners = this._anyListeners;
3560
3561 for (var i = 0; i < listeners.length; i++) {
3562 if (listener === listeners[i]) {
3563 listeners.splice(i, 1);
3564 return this;
3565 }
3566 }
3567 } else {
3568 this._anyListeners = [];
3569 }
3570
3571 return this;
3572 }
3573 /**
3574 * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
3575 * e.g. to remove listeners.
3576 *
3577 * @public
3578 */
3579
3580 }, {
3581 key: "listenersAny",
3582 value: function listenersAny() {
3583 return this._anyListeners || [];
3584 }
3585 }]);
3586
3587 return Socket;
3588 }(Emitter_1);
3589
3590 /**
3591 * Expose `Backoff`.
3592 */
3593
3594 var backo2 = Backoff;
3595 /**
3596 * Initialize backoff timer with `opts`.
3597 *
3598 * - `min` initial timeout in milliseconds [100]
3599 * - `max` max timeout [10000]
3600 * - `jitter` [0]
3601 * - `factor` [2]
3602 *
3603 * @param {Object} opts
3604 * @api public
3605 */
3606
3607 function Backoff(opts) {
3608 opts = opts || {};
3609 this.ms = opts.min || 100;
3610 this.max = opts.max || 10000;
3611 this.factor = opts.factor || 2;
3612 this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
3613 this.attempts = 0;
3614 }
3615 /**
3616 * Return the backoff duration.
3617 *
3618 * @return {Number}
3619 * @api public
3620 */
3621
3622
3623 Backoff.prototype.duration = function () {
3624 var ms = this.ms * Math.pow(this.factor, this.attempts++);
3625
3626 if (this.jitter) {
3627 var rand = Math.random();
3628 var deviation = Math.floor(rand * this.jitter * ms);
3629 ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
3630 }
3631
3632 return Math.min(ms, this.max) | 0;
3633 };
3634 /**
3635 * Reset the number of attempts.
3636 *
3637 * @api public
3638 */
3639
3640
3641 Backoff.prototype.reset = function () {
3642 this.attempts = 0;
3643 };
3644 /**
3645 * Set the minimum duration
3646 *
3647 * @api public
3648 */
3649
3650
3651 Backoff.prototype.setMin = function (min) {
3652 this.ms = min;
3653 };
3654 /**
3655 * Set the maximum duration
3656 *
3657 * @api public
3658 */
3659
3660
3661 Backoff.prototype.setMax = function (max) {
3662 this.max = max;
3663 };
3664 /**
3665 * Set the jitter
3666 *
3667 * @api public
3668 */
3669
3670
3671 Backoff.prototype.setJitter = function (jitter) {
3672 this.jitter = jitter;
3673 };
3674
3675 var Manager = /*#__PURE__*/function (_Emitter) {
3676 _inherits(Manager, _Emitter);
3677
3678 var _super = _createSuper(Manager);
3679
3680 function Manager(uri, opts) {
3681 var _this;
3682
3683 _classCallCheck(this, Manager);
3684
3685 var _a;
3686
3687 _this = _super.call(this);
3688 _this.nsps = {};
3689 _this.subs = [];
3690
3691 if (uri && "object" === _typeof(uri)) {
3692 opts = uri;
3693 uri = undefined;
3694 }
3695
3696 opts = opts || {};
3697 opts.path = opts.path || "/socket.io";
3698 _this.opts = opts;
3699 installTimerFunctions(_assertThisInitialized(_this), opts);
3700
3701 _this.reconnection(opts.reconnection !== false);
3702
3703 _this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
3704
3705 _this.reconnectionDelay(opts.reconnectionDelay || 1000);
3706
3707 _this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
3708
3709 _this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);
3710
3711 _this.backoff = new backo2({
3712 min: _this.reconnectionDelay(),
3713 max: _this.reconnectionDelayMax(),
3714 jitter: _this.randomizationFactor()
3715 });
3716
3717 _this.timeout(null == opts.timeout ? 20000 : opts.timeout);
3718
3719 _this._readyState = "closed";
3720 _this.uri = uri;
3721
3722 var _parser = opts.parser || parser;
3723
3724 _this.encoder = new _parser.Encoder();
3725 _this.decoder = new _parser.Decoder();
3726 _this._autoConnect = opts.autoConnect !== false;
3727 if (_this._autoConnect) _this.open();
3728 return _this;
3729 }
3730
3731 _createClass(Manager, [{
3732 key: "reconnection",
3733 value: function reconnection(v) {
3734 if (!arguments.length) return this._reconnection;
3735 this._reconnection = !!v;
3736 return this;
3737 }
3738 }, {
3739 key: "reconnectionAttempts",
3740 value: function reconnectionAttempts(v) {
3741 if (v === undefined) return this._reconnectionAttempts;
3742 this._reconnectionAttempts = v;
3743 return this;
3744 }
3745 }, {
3746 key: "reconnectionDelay",
3747 value: function reconnectionDelay(v) {
3748 var _a;
3749
3750 if (v === undefined) return this._reconnectionDelay;
3751 this._reconnectionDelay = v;
3752 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v);
3753 return this;
3754 }
3755 }, {
3756 key: "randomizationFactor",
3757 value: function randomizationFactor(v) {
3758 var _a;
3759
3760 if (v === undefined) return this._randomizationFactor;
3761 this._randomizationFactor = v;
3762 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v);
3763 return this;
3764 }
3765 }, {
3766 key: "reconnectionDelayMax",
3767 value: function reconnectionDelayMax(v) {
3768 var _a;
3769
3770 if (v === undefined) return this._reconnectionDelayMax;
3771 this._reconnectionDelayMax = v;
3772 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v);
3773 return this;
3774 }
3775 }, {
3776 key: "timeout",
3777 value: function timeout(v) {
3778 if (!arguments.length) return this._timeout;
3779 this._timeout = v;
3780 return this;
3781 }
3782 /**
3783 * Starts trying to reconnect if reconnection is enabled and we have not
3784 * started reconnecting yet
3785 *
3786 * @private
3787 */
3788
3789 }, {
3790 key: "maybeReconnectOnOpen",
3791 value: function maybeReconnectOnOpen() {
3792 // Only try to reconnect if it's the first time we're connecting
3793 if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) {
3794 // keeps reconnection from firing twice for the same reconnection loop
3795 this.reconnect();
3796 }
3797 }
3798 /**
3799 * Sets the current transport `socket`.
3800 *
3801 * @param {Function} fn - optional, callback
3802 * @return self
3803 * @public
3804 */
3805
3806 }, {
3807 key: "open",
3808 value: function open(fn) {
3809 var _this2 = this;
3810
3811 if (~this._readyState.indexOf("open")) return this;
3812 this.engine = new Socket$1(this.uri, this.opts);
3813 var socket = this.engine;
3814 var self = this;
3815 this._readyState = "opening";
3816 this.skipReconnect = false; // emit `open`
3817
3818 var openSubDestroy = on(socket, "open", function () {
3819 self.onopen();
3820 fn && fn();
3821 }); // emit `error`
3822
3823 var errorSub = on(socket, "error", function (err) {
3824 self.cleanup();
3825 self._readyState = "closed";
3826
3827 _this2.emitReserved("error", err);
3828
3829 if (fn) {
3830 fn(err);
3831 } else {
3832 // Only do this if there is no fn to handle the error
3833 self.maybeReconnectOnOpen();
3834 }
3835 });
3836
3837 if (false !== this._timeout) {
3838 var timeout = this._timeout;
3839
3840 if (timeout === 0) {
3841 openSubDestroy(); // prevents a race condition with the 'open' event
3842 } // set timer
3843
3844
3845 var timer = this.setTimeoutFn(function () {
3846 openSubDestroy();
3847 socket.close(); // @ts-ignore
3848
3849 socket.emit("error", new Error("timeout"));
3850 }, timeout);
3851
3852 if (this.opts.autoUnref) {
3853 timer.unref();
3854 }
3855
3856 this.subs.push(function subDestroy() {
3857 clearTimeout(timer);
3858 });
3859 }
3860
3861 this.subs.push(openSubDestroy);
3862 this.subs.push(errorSub);
3863 return this;
3864 }
3865 /**
3866 * Alias for open()
3867 *
3868 * @return self
3869 * @public
3870 */
3871
3872 }, {
3873 key: "connect",
3874 value: function connect(fn) {
3875 return this.open(fn);
3876 }
3877 /**
3878 * Called upon transport open.
3879 *
3880 * @private
3881 */
3882
3883 }, {
3884 key: "onopen",
3885 value: function onopen() {
3886 // clear old subs
3887 this.cleanup(); // mark as open
3888
3889 this._readyState = "open";
3890 this.emitReserved("open"); // add new subs
3891
3892 var socket = this.engine;
3893 this.subs.push(on(socket, "ping", this.onping.bind(this)), on(socket, "data", this.ondata.bind(this)), on(socket, "error", this.onerror.bind(this)), on(socket, "close", this.onclose.bind(this)), on(this.decoder, "decoded", this.ondecoded.bind(this)));
3894 }
3895 /**
3896 * Called upon a ping.
3897 *
3898 * @private
3899 */
3900
3901 }, {
3902 key: "onping",
3903 value: function onping() {
3904 this.emitReserved("ping");
3905 }
3906 /**
3907 * Called with data.
3908 *
3909 * @private
3910 */
3911
3912 }, {
3913 key: "ondata",
3914 value: function ondata(data) {
3915 this.decoder.add(data);
3916 }
3917 /**
3918 * Called when parser fully decodes a packet.
3919 *
3920 * @private
3921 */
3922
3923 }, {
3924 key: "ondecoded",
3925 value: function ondecoded(packet) {
3926 this.emitReserved("packet", packet);
3927 }
3928 /**
3929 * Called upon socket error.
3930 *
3931 * @private
3932 */
3933
3934 }, {
3935 key: "onerror",
3936 value: function onerror(err) {
3937 this.emitReserved("error", err);
3938 }
3939 /**
3940 * Creates a new socket for the given `nsp`.
3941 *
3942 * @return {Socket}
3943 * @public
3944 */
3945
3946 }, {
3947 key: "socket",
3948 value: function socket(nsp, opts) {
3949 var socket = this.nsps[nsp];
3950
3951 if (!socket) {
3952 socket = new Socket(this, nsp, opts);
3953 this.nsps[nsp] = socket;
3954 }
3955
3956 return socket;
3957 }
3958 /**
3959 * Called upon a socket close.
3960 *
3961 * @param socket
3962 * @private
3963 */
3964
3965 }, {
3966 key: "_destroy",
3967 value: function _destroy(socket) {
3968 var nsps = Object.keys(this.nsps);
3969
3970 for (var _i = 0, _nsps = nsps; _i < _nsps.length; _i++) {
3971 var nsp = _nsps[_i];
3972 var _socket = this.nsps[nsp];
3973
3974 if (_socket.active) {
3975 return;
3976 }
3977 }
3978
3979 this._close();
3980 }
3981 /**
3982 * Writes a packet.
3983 *
3984 * @param packet
3985 * @private
3986 */
3987
3988 }, {
3989 key: "_packet",
3990 value: function _packet(packet) {
3991 var encodedPackets = this.encoder.encode(packet);
3992
3993 for (var i = 0; i < encodedPackets.length; i++) {
3994 this.engine.write(encodedPackets[i], packet.options);
3995 }
3996 }
3997 /**
3998 * Clean up transport subscriptions and packet buffer.
3999 *
4000 * @private
4001 */
4002
4003 }, {
4004 key: "cleanup",
4005 value: function cleanup() {
4006 this.subs.forEach(function (subDestroy) {
4007 return subDestroy();
4008 });
4009 this.subs.length = 0;
4010 this.decoder.destroy();
4011 }
4012 /**
4013 * Close the current socket.
4014 *
4015 * @private
4016 */
4017
4018 }, {
4019 key: "_close",
4020 value: function _close() {
4021 this.skipReconnect = true;
4022 this._reconnecting = false;
4023
4024 if ("opening" === this._readyState) {
4025 // `onclose` will not fire because
4026 // an open event never happened
4027 this.cleanup();
4028 }
4029
4030 this.backoff.reset();
4031 this._readyState = "closed";
4032 if (this.engine) this.engine.close();
4033 }
4034 /**
4035 * Alias for close()
4036 *
4037 * @private
4038 */
4039
4040 }, {
4041 key: "disconnect",
4042 value: function disconnect() {
4043 return this._close();
4044 }
4045 /**
4046 * Called upon engine close.
4047 *
4048 * @private
4049 */
4050
4051 }, {
4052 key: "onclose",
4053 value: function onclose(reason) {
4054 this.cleanup();
4055 this.backoff.reset();
4056 this._readyState = "closed";
4057 this.emitReserved("close", reason);
4058
4059 if (this._reconnection && !this.skipReconnect) {
4060 this.reconnect();
4061 }
4062 }
4063 /**
4064 * Attempt a reconnection.
4065 *
4066 * @private
4067 */
4068
4069 }, {
4070 key: "reconnect",
4071 value: function reconnect() {
4072 var _this3 = this;
4073
4074 if (this._reconnecting || this.skipReconnect) return this;
4075 var self = this;
4076
4077 if (this.backoff.attempts >= this._reconnectionAttempts) {
4078 this.backoff.reset();
4079 this.emitReserved("reconnect_failed");
4080 this._reconnecting = false;
4081 } else {
4082 var delay = this.backoff.duration();
4083 this._reconnecting = true;
4084 var timer = this.setTimeoutFn(function () {
4085 if (self.skipReconnect) return;
4086
4087 _this3.emitReserved("reconnect_attempt", self.backoff.attempts); // check again for the case socket closed in above events
4088
4089
4090 if (self.skipReconnect) return;
4091 self.open(function (err) {
4092 if (err) {
4093 self._reconnecting = false;
4094 self.reconnect();
4095
4096 _this3.emitReserved("reconnect_error", err);
4097 } else {
4098 self.onreconnect();
4099 }
4100 });
4101 }, delay);
4102
4103 if (this.opts.autoUnref) {
4104 timer.unref();
4105 }
4106
4107 this.subs.push(function subDestroy() {
4108 clearTimeout(timer);
4109 });
4110 }
4111 }
4112 /**
4113 * Called upon successful reconnect.
4114 *
4115 * @private
4116 */
4117
4118 }, {
4119 key: "onreconnect",
4120 value: function onreconnect() {
4121 var attempt = this.backoff.attempts;
4122 this._reconnecting = false;
4123 this.backoff.reset();
4124 this.emitReserved("reconnect", attempt);
4125 }
4126 }]);
4127
4128 return Manager;
4129 }(Emitter_1);
4130
4131 /**
4132 * Managers cache.
4133 */
4134
4135 var cache = {};
4136
4137 function lookup(uri, opts) {
4138 if (_typeof(uri) === "object") {
4139 opts = uri;
4140 uri = undefined;
4141 }
4142
4143 opts = opts || {};
4144 var parsed = url(uri, opts.path || "/socket.io");
4145 var source = parsed.source;
4146 var id = parsed.id;
4147 var path = parsed.path;
4148 var sameNamespace = cache[id] && path in cache[id]["nsps"];
4149 var newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace;
4150 var io;
4151
4152 if (newConnection) {
4153 io = new Manager(source, opts);
4154 } else {
4155 if (!cache[id]) {
4156 cache[id] = new Manager(source, opts);
4157 }
4158
4159 io = cache[id];
4160 }
4161
4162 if (parsed.query && !opts.query) {
4163 opts.query = parsed.queryKey;
4164 }
4165
4166 return io.socket(parsed.path, opts);
4167 } // so that "lookup" can be used both as a function (e.g. `io(...)`) and as a
4168 // namespace (e.g. `io.connect(...)`), for backward compatibility
4169
4170
4171 _extends(lookup, {
4172 Manager: Manager,
4173 Socket: Socket,
4174 io: lookup,
4175 connect: lookup
4176 });
4177
4178 if (typeof module !== "undefined") {
4179 module.exports = lookup;
4180 }
4181
4182 return lookup;
4183
4184}));
4185//# sourceMappingURL=socket.io.js.map