vendor: 155,836 bytes, lines 1-4955
1/*! 2 * Socket.IO v4.8.3 3 * (c) 2014-2025 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 _arrayLikeToArray(r, a) { 13 (null == a || a > r.length) && (a = r.length); 14 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; 15 return n; 16 } 17 function _arrayWithoutHoles(r) { 18 if (Array.isArray(r)) return _arrayLikeToArray(r); 19 } 20 function _construct(t, e, r) { 21 if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); 22 var o = [null]; 23 o.push.apply(o, e); 24 var p = new (t.bind.apply(t, o))(); 25 return r && _setPrototypeOf(p, r.prototype), p; 26 } 27 function _defineProperties(e, r) { 28 for (var t = 0; t < r.length; t++) { 29 var o = r[t]; 30 o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); 31 } 32 } 33 function _createClass(e, r, t) { 34 return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { 35 writable: !1 36 }), e; 37 } 38 function _createForOfIteratorHelper(r, e) { 39 var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; 40 if (!t) { 41 if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { 42 t && (r = t); 43 var n = 0, 44 F = function () {}; 45 return { 46 s: F, 47 n: function () { 48 return n >= r.length ? { 49 done: !0 50 } : { 51 done: !1, 52 value: r[n++] 53 }; 54 }, 55 e: function (r) { 56 throw r; 57 }, 58 f: F 59 }; 60 } 61 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 62 } 63 var o, 64 a = !0, 65 u = !1; 66 return { 67 s: function () { 68 t = t.call(r); 69 }, 70 n: function () { 71 var r = t.next(); 72 return a = r.done, r; 73 }, 74 e: function (r) { 75 u = !0, o = r; 76 }, 77 f: function () { 78 try { 79 a || null == t.return || t.return(); 80 } finally { 81 if (u) throw o; 82 } 83 } 84 }; 85 } 86 function _extends() { 87 return _extends = Object.assign ? Object.assign.bind() : function (n) { 88 for (var e = 1; e < arguments.length; e++) { 89 var t = arguments[e]; 90 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); 91 } 92 return n; 93 }, _extends.apply(null, arguments); 94 } 95 function _getPrototypeOf(t) { 96 return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { 97 return t.__proto__ || Object.getPrototypeOf(t); 98 }, _getPrototypeOf(t); 99 } 100 function _inheritsLoose(t, o) { 101 t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); 102 } 103 function _isNativeFunction(t) { 104 try { 105 return -1 !== Function.toString.call(t).indexOf("[native code]"); 106 } catch (n) { 107 return "function" == typeof t; 108 } 109 } 110 function _isNativeReflectConstruct() { 111 try { 112 var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); 113 } catch (t) {} 114 return (_isNativeReflectConstruct = function () { 115 return !!t; 116 })(); 117 } 118 function _iterableToArray(r) { 119 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); 120 } 121 function _nonIterableSpread() { 122 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 123 } 124 function _setPrototypeOf(t, e) { 125 return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { 126 return t.__proto__ = e, t; 127 }, _setPrototypeOf(t, e); 128 } 129 function _toConsumableArray(r) { 130 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); 131 } 132 function _toPrimitive(t, r) { 133 if ("object" != typeof t || !t) return t; 134 var e = t[Symbol.toPrimitive]; 135 if (void 0 !== e) { 136 var i = e.call(t, r || "default"); 137 if ("object" != typeof i) return i; 138 throw new TypeError("@@toPrimitive must return a primitive value."); 139 } 140 return ("string" === r ? String : Number)(t); 141 } 142 function _toPropertyKey(t) { 143 var i = _toPrimitive(t, "string"); 144 return "symbol" == typeof i ? i : i + ""; 145 } 146 function _typeof(o) { 147 "@babel/helpers - typeof"; 148 149 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { 150 return typeof o; 151 } : function (o) { 152 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; 153 }, _typeof(o); 154 } 155 function _unsupportedIterableToArray(r, a) { 156 if (r) { 157 if ("string" == typeof r) return _arrayLikeToArray(r, a); 158 var t = {}.toString.call(r).slice(8, -1); 159 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; 160 } 161 } 162 function _wrapNativeSuper(t) { 163 var r = "function" == typeof Map ? new Map() : void 0; 164 return _wrapNativeSuper = function (t) { 165 if (null === t || !_isNativeFunction(t)) return t; 166 if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function"); 167 if (void 0 !== r) { 168 if (r.has(t)) return r.get(t); 169 r.set(t, Wrapper); 170 } 171 function Wrapper() { 172 return _construct(t, arguments, _getPrototypeOf(this).constructor); 173 } 174 return Wrapper.prototype = Object.create(t.prototype, { 175 constructor: { 176 value: Wrapper, 177 enumerable: !1, 178 writable: !0, 179 configurable: !0 180 } 181 }), _setPrototypeOf(Wrapper, t); 182 }, _wrapNativeSuper(t); 183 } 184 185 var PACKET_TYPES = Object.create(null); // no Map = no polyfill 186 PACKET_TYPES["open"] = "0"; 187 PACKET_TYPES["close"] = "1"; 188 PACKET_TYPES["ping"] = "2"; 189 PACKET_TYPES["pong"] = "3"; 190 PACKET_TYPES["message"] = "4"; 191 PACKET_TYPES["upgrade"] = "5"; 192 PACKET_TYPES["noop"] = "6"; 193 var PACKET_TYPES_REVERSE = Object.create(null); 194 Object.keys(PACKET_TYPES).forEach(function (key) { 195 PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key; 196 }); 197 var ERROR_PACKET = { 198 type: "error", 199 data: "parser error" 200 }; 201 202 var withNativeBlob$1 = typeof Blob === "function" || typeof Blob !== "undefined" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]"; 203 var withNativeArrayBuffer$2 = typeof ArrayBuffer === "function"; 204 // ArrayBuffer.isView method is not defined in IE10 205 var isView$1 = function isView(obj) { 206 return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj && obj.buffer instanceof ArrayBuffer; 207 }; 208 var encodePacket = function encodePacket(_ref, supportsBinary, callback) { 209 var type = _ref.type, 210 data = _ref.data; 211 if (withNativeBlob$1 && data instanceof Blob) { 212 if (supportsBinary) { 213 return callback(data); 214 } else { 215 return encodeBlobAsBase64(data, callback); 216 } 217 } else if (withNativeArrayBuffer$2 && (data instanceof ArrayBuffer || isView$1(data))) { 218 if (supportsBinary) { 219 return callback(data); 220 } else { 221 return encodeBlobAsBase64(new Blob([data]), callback); 222 } 223 } 224 // plain string 225 return callback(PACKET_TYPES[type] + (data || "")); 226 }; 227 var encodeBlobAsBase64 = function encodeBlobAsBase64(data, callback) { 228 var fileReader = new FileReader(); 229 fileReader.onload = function () { 230 var content = fileReader.result.split(",")[1]; 231 callback("b" + (content || "")); 232 }; 233 return fileReader.readAsDataURL(data); 234 }; 235 function toArray(data) { 236 if (data instanceof Uint8Array) { 237 return data; 238 } else if (data instanceof ArrayBuffer) { 239 return new Uint8Array(data); 240 } else { 241 return new Uint8Array(data.buffer, data.byteOffset, data.byteLength); 242 } 243 } 244 var TEXT_ENCODER; 245 function encodePacketToBinary(packet, callback) { 246 if (withNativeBlob$1 && packet.data instanceof Blob) { 247 return packet.data.arrayBuffer().then(toArray).then(callback); 248 } else if (withNativeArrayBuffer$2 && (packet.data instanceof ArrayBuffer || isView$1(packet.data))) { 249 return callback(toArray(packet.data)); 250 } 251 encodePacket(packet, false, function (encoded) { 252 if (!TEXT_ENCODER) { 253 TEXT_ENCODER = new TextEncoder(); 254 } 255 callback(TEXT_ENCODER.encode(encoded)); 256 }); 257 } 258 259 // imported from https://github.com/socketio/base64-arraybuffer 260 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 261 // Use a lookup table to find the index. 262 var lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256); 263 for (var i = 0; i < chars.length; i++) { 264 lookup$1[chars.charCodeAt(i)] = i; 265 } 266 var decode$1 = function decode(base64) { 267 var bufferLength = base64.length * 0.75, 268 len = base64.length, 269 i, 270 p = 0, 271 encoded1, 272 encoded2, 273 encoded3, 274 encoded4; 275 if (base64[base64.length - 1] === '=') { 276 bufferLength--; 277 if (base64[base64.length - 2] === '=') { 278 bufferLength--; 279 } 280 } 281 var arraybuffer = new ArrayBuffer(bufferLength), 282 bytes = new Uint8Array(arraybuffer); 283 for (i = 0; i < len; i += 4) { 284 encoded1 = lookup$1[base64.charCodeAt(i)]; 285 encoded2 = lookup$1[base64.charCodeAt(i + 1)]; 286 encoded3 = lookup$1[base64.charCodeAt(i + 2)]; 287 encoded4 = lookup$1[base64.charCodeAt(i + 3)]; 288 bytes[p++] = encoded1 << 2 | encoded2 >> 4; 289 bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; 290 bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; 291 } 292 return arraybuffer; 293 }; 294 295 var withNativeArrayBuffer$1 = typeof ArrayBuffer === "function"; 296 var decodePacket = function decodePacket(encodedPacket, binaryType) { 297 if (typeof encodedPacket !== "string") { 298 return { 299 type: "message", 300 data: mapBinary(encodedPacket, binaryType) 301 }; 302 } 303 var type = encodedPacket.charAt(0); 304 if (type === "b") { 305 return { 306 type: "message", 307 data: decodeBase64Packet(encodedPacket.substring(1), binaryType) 308 }; 309 } 310 var packetType = PACKET_TYPES_REVERSE[type]; 311 if (!packetType) { 312 return ERROR_PACKET; 313 } 314 return encodedPacket.length > 1 ? { 315 type: PACKET_TYPES_REVERSE[type], 316 data: encodedPacket.substring(1) 317 } : { 318 type: PACKET_TYPES_REVERSE[type] 319 }; 320 }; 321 var decodeBase64Packet = function decodeBase64Packet(data, binaryType) { 322 if (withNativeArrayBuffer$1) { 323 var decoded = decode$1(data); 324 return mapBinary(decoded, binaryType); 325 } else { 326 return { 327 base64: true, 328 data: data 329 }; // fallback for old browsers 330 } 331 }; 332 var mapBinary = function mapBinary(data, binaryType) { 333 switch (binaryType) { 334 case "blob": 335 if (data instanceof Blob) { 336 // from WebSocket + binaryType "blob" 337 return data; 338 } else { 339 // from HTTP long-polling or WebTransport 340 return new Blob([data]); 341 } 342 case "arraybuffer": 343 default: 344 if (data instanceof ArrayBuffer) { 345 // from HTTP long-polling (base64) or WebSocket + binaryType "arraybuffer" 346 return data; 347 } else { 348 // from WebTransport (Uint8Array) 349 return data.buffer; 350 } 351 } 352 }; 353 354 var SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text 355 var encodePayload = function encodePayload(packets, callback) { 356 // some packets may be added to the array while encoding, so the initial length must be saved 357 var length = packets.length; 358 var encodedPackets = new Array(length); 359 var count = 0; 360 packets.forEach(function (packet, i) { 361 // force base64 encoding for binary packets 362 encodePacket(packet, false, function (encodedPacket) { 363 encodedPackets[i] = encodedPacket; 364 if (++count === length) { 365 callback(encodedPackets.join(SEPARATOR)); 366 } 367 }); 368 }); 369 }; 370 var decodePayload = function decodePayload(encodedPayload, binaryType) { 371 var encodedPackets = encodedPayload.split(SEPARATOR); 372 var packets = []; 373 for (var i = 0; i < encodedPackets.length; i++) { 374 var decodedPacket = decodePacket(encodedPackets[i], binaryType); 375 packets.push(decodedPacket); 376 if (decodedPacket.type === "error") { 377 break; 378 } 379 } 380 return packets; 381 }; 382 function createPacketEncoderStream() { 383 return new TransformStream({ 384 transform: function transform(packet, controller) { 385 encodePacketToBinary(packet, function (encodedPacket) { 386 var payloadLength = encodedPacket.length; 387 var header; 388 // inspired by the WebSocket format: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#decoding_payload_length 389 if (payloadLength < 126) { 390 header = new Uint8Array(1); 391 new DataView(header.buffer).setUint8(0, payloadLength); 392 } else if (payloadLength < 65536) { 393 header = new Uint8Array(3); 394 var view = new DataView(header.buffer); 395 view.setUint8(0, 126); 396 view.setUint16(1, payloadLength); 397 } else { 398 header = new Uint8Array(9); 399 var _view = new DataView(header.buffer); 400 _view.setUint8(0, 127); 401 _view.setBigUint64(1, BigInt(payloadLength)); 402 } 403 // first bit indicates whether the payload is plain text (0) or binary (1) 404 if (packet.data && typeof packet.data !== "string") { 405 header[0] |= 0x80; 406 } 407 controller.enqueue(header); 408 controller.enqueue(encodedPacket); 409 }); 410 } 411 }); 412 } 413 var TEXT_DECODER; 414 function totalLength(chunks) { 415 return chunks.reduce(function (acc, chunk) { 416 return acc + chunk.length; 417 }, 0); 418 } 419 function concatChunks(chunks, size) { 420 if (chunks[0].length === size) { 421 return chunks.shift(); 422 } 423 var buffer = new Uint8Array(size); 424 var j = 0; 425 for (var i = 0; i < size; i++) { 426 buffer[i] = chunks[0][j++]; 427 if (j === chunks[0].length) { 428 chunks.shift(); 429 j = 0; 430 } 431 } 432 if (chunks.length && j < chunks[0].length) { 433 chunks[0] = chunks[0].slice(j); 434 } 435 return buffer; 436 } 437 function createPacketDecoderStream(maxPayload, binaryType) { 438 if (!TEXT_DECODER) { 439 TEXT_DECODER = new TextDecoder(); 440 } 441 var chunks = []; 442 var state = 0 /* State.READ_HEADER */; 443 var expectedLength = -1; 444 var isBinary = false; 445 return new TransformStream({ 446 transform: function transform(chunk, controller) { 447 chunks.push(chunk); 448 while (true) { 449 if (state === 0 /* State.READ_HEADER */) { 450 if (totalLength(chunks) < 1) { 451 break; 452 } 453 var header = concatChunks(chunks, 1); 454 isBinary = (header[0] & 0x80) === 0x80; 455 expectedLength = header[0] & 0x7f; 456 if (expectedLength < 126) { 457 state = 3 /* State.READ_PAYLOAD */; 458 } else if (expectedLength === 126) { 459 state = 1 /* State.READ_EXTENDED_LENGTH_16 */; 460 } else { 461 state = 2 /* State.READ_EXTENDED_LENGTH_64 */; 462 } 463 } else if (state === 1 /* State.READ_EXTENDED_LENGTH_16 */) { 464 if (totalLength(chunks) < 2) { 465 break; 466 } 467 var headerArray = concatChunks(chunks, 2); 468 expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0); 469 state = 3 /* State.READ_PAYLOAD */; 470 } else if (state === 2 /* State.READ_EXTENDED_LENGTH_64 */) { 471 if (totalLength(chunks) < 8) { 472 break; 473 } 474 var _headerArray = concatChunks(chunks, 8); 475 var view = new DataView(_headerArray.buffer, _headerArray.byteOffset, _headerArray.length); 476 var n = view.getUint32(0); 477 if (n > Math.pow(2, 53 - 32) - 1) { 478 // the maximum safe integer in JavaScript is 2^53 - 1 479 controller.enqueue(ERROR_PACKET); 480 break; 481 } 482 expectedLength = n * Math.pow(2, 32) + view.getUint32(4); 483 state = 3 /* State.READ_PAYLOAD */; 484 } else { 485 if (totalLength(chunks) < expectedLength) { 486 break; 487 } 488 var data = concatChunks(chunks, expectedLength); 489 controller.enqueue(decodePacket(isBinary ? data : TEXT_DECODER.decode(data), binaryType)); 490 state = 0 /* State.READ_HEADER */; 491 } 492 if (expectedLength === 0 || expectedLength > maxPayload) { 493 controller.enqueue(ERROR_PACKET); 494 break; 495 } 496 } 497 } 498 }); 499 } 500 var protocol$1 = 4; 501 502 /** 503 * Initialize a new `Emitter`. 504 * 505 * @api public 506 */ 507 508 function Emitter(obj) { 509 if (obj) return mixin(obj); 510 } 511 512 /** 513 * Mixin the emitter properties. 514 * 515 * @param {Object} obj 516 * @return {Object} 517 * @api private 518 */ 519 520 function mixin(obj) { 521 for (var key in Emitter.prototype) { 522 obj[key] = Emitter.prototype[key]; 523 } 524 return obj; 525 } 526 527 /** 528 * Listen on the given `event` with `fn`. 529 * 530 * @param {String} event 531 * @param {Function} fn 532 * @return {Emitter} 533 * @api public 534 */ 535 536 Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { 537 this._callbacks = this._callbacks || {}; 538 (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); 539 return this; 540 }; 541 542 /** 543 * Adds an `event` listener that will be invoked a single 544 * time then automatically removed. 545 * 546 * @param {String} event 547 * @param {Function} fn 548 * @return {Emitter} 549 * @api public 550 */ 551 552 Emitter.prototype.once = function (event, fn) { 553 function on() { 554 this.off(event, on); 555 fn.apply(this, arguments); 556 } 557 on.fn = fn; 558 this.on(event, on); 559 return this; 560 }; 561 562 /** 563 * Remove the given callback for `event` or all 564 * registered callbacks. 565 * 566 * @param {String} event 567 * @param {Function} fn 568 * @return {Emitter} 569 * @api public 570 */ 571 572 Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { 573 this._callbacks = this._callbacks || {}; 574 575 // all 576 if (0 == arguments.length) { 577 this._callbacks = {}; 578 return this; 579 } 580 581 // specific event 582 var callbacks = this._callbacks['$' + event]; 583 if (!callbacks) return this; 584 585 // remove all handlers 586 if (1 == arguments.length) { 587 delete this._callbacks['$' + event]; 588 return this; 589 } 590 591 // remove specific handler 592 var cb; 593 for (var i = 0; i < callbacks.length; i++) { 594 cb = callbacks[i]; 595 if (cb === fn || cb.fn === fn) { 596 callbacks.splice(i, 1); 597 break; 598 } 599 } 600 601 // Remove event specific arrays for event types that no 602 // one is subscribed for to avoid memory leak. 603 if (callbacks.length === 0) { 604 delete this._callbacks['$' + event]; 605 } 606 return this; 607 }; 608 609 /** 610 * Emit `event` with the given args. 611 * 612 * @param {String} event 613 * @param {Mixed} ... 614 * @return {Emitter} 615 */ 616 617 Emitter.prototype.emit = function (event) { 618 this._callbacks = this._callbacks || {}; 619 var args = new Array(arguments.length - 1), 620 callbacks = this._callbacks['$' + event]; 621 for (var i = 1; i < arguments.length; i++) { 622 args[i - 1] = arguments[i]; 623 } 624 if (callbacks) { 625 callbacks = callbacks.slice(0); 626 for (var i = 0, len = callbacks.length; i < len; ++i) { 627 callbacks[i].apply(this, args); 628 } 629 } 630 return this; 631 }; 632 633 // alias used for reserved events (protected method) 634 Emitter.prototype.emitReserved = Emitter.prototype.emit; 635 636 /** 637 * Return array of callbacks for `event`. 638 * 639 * @param {String} event 640 * @return {Array} 641 * @api public 642 */ 643 644 Emitter.prototype.listeners = function (event) { 645 this._callbacks = this._callbacks || {}; 646 return this._callbacks['$' + event] || []; 647 }; 648 649 /** 650 * Check if this emitter has `event` handlers. 651 * 652 * @param {String} event 653 * @return {Boolean} 654 * @api public 655 */ 656 657 Emitter.prototype.hasListeners = function (event) { 658 return !!this.listeners(event).length; 659 }; 660 661 var nextTick = function () { 662 var isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function"; 663 if (isPromiseAvailable) { 664 return function (cb) { 665 return Promise.resolve().then(cb); 666 }; 667 } else { 668 return function (cb, setTimeoutFn) { 669 return setTimeoutFn(cb, 0); 670 }; 671 } 672 }(); 673 var globalThisShim = function () { 674 if (typeof self !== "undefined") { 675 return self; 676 } else if (typeof window !== "undefined") { 677 return window; 678 } else { 679 return Function("return this")(); 680 } 681 }(); 682 var defaultBinaryType = "arraybuffer"; 683 function createCookieJar() {} 684 685 function pick(obj) { 686 for (var _len = arguments.length, attr = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 687 attr[_key - 1] = arguments[_key]; 688 } 689 return attr.reduce(function (acc, k) { 690 if (obj.hasOwnProperty(k)) { 691 acc[k] = obj[k]; 692 } 693 return acc; 694 }, {}); 695 } 696 // Keep a reference to the real timeout functions so they can be used when overridden 697 var NATIVE_SET_TIMEOUT = globalThisShim.setTimeout; 698 var NATIVE_CLEAR_TIMEOUT = globalThisShim.clearTimeout; 699 function installTimerFunctions(obj, opts) { 700 if (opts.useNativeTimers) { 701 obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThisShim); 702 obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThisShim); 703 } else { 704 obj.setTimeoutFn = globalThisShim.setTimeout.bind(globalThisShim); 705 obj.clearTimeoutFn = globalThisShim.clearTimeout.bind(globalThisShim); 706 } 707 } 708 // base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64) 709 var BASE64_OVERHEAD = 1.33; 710 // we could also have used `new Blob([obj]).size`, but it isn't supported in IE9 711 function byteLength(obj) { 712 if (typeof obj === "string") { 713 return utf8Length(obj); 714 } 715 // arraybuffer or blob 716 return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD); 717 } 718 function utf8Length(str) { 719 var c = 0, 720 length = 0; 721 for (var i = 0, l = str.length; i < l; i++) { 722 c = str.charCodeAt(i); 723 if (c < 0x80) { 724 length += 1; 725 } else if (c < 0x800) { 726 length += 2; 727 } else if (c < 0xd800 || c >= 0xe000) { 728 length += 3; 729 } else { 730 i++; 731 length += 4; 732 } 733 } 734 return length; 735 } 736 /** 737 * Generates a random 8-characters string. 738 */ 739 function randomString() { 740 return Date.now().toString(36).substring(3) + Math.random().toString(36).substring(2, 5); 741 } 742 743 // imported from https://github.com/galkn/querystring 744 /** 745 * Compiles a querystring 746 * Returns string representation of the object 747 * 748 * @param {Object} 749 * @api private 750 */ 751 function encode(obj) { 752 var str = ''; 753 for (var i in obj) { 754 if (obj.hasOwnProperty(i)) { 755 if (str.length) str += '&'; 756 str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); 757 } 758 } 759 return str; 760 } 761 /** 762 * Parses a simple querystring into an object 763 * 764 * @param {String} qs 765 * @api private 766 */ 767 function decode(qs) { 768 var qry = {}; 769 var pairs = qs.split('&'); 770 for (var i = 0, l = pairs.length; i < l; i++) { 771 var pair = pairs[i].split('='); 772 qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); 773 } 774 return qry; 775 } 776 777 var TransportError = /*#__PURE__*/function (_Error) { 778 function TransportError(reason, description, context) { 779 var _this; 780 _this = _Error.call(this, reason) || this; 781 _this.description = description; 782 _this.context = context; 783 _this.type = "TransportError"; 784 return _this; 785 } 786 _inheritsLoose(TransportError, _Error); 787 return TransportError; 788 }( /*#__PURE__*/_wrapNativeSuper(Error)); 789 var Transport = /*#__PURE__*/function (_Emitter) { 790 /** 791 * Transport abstract constructor. 792 * 793 * @param {Object} opts - options 794 * @protected 795 */ 796 function Transport(opts) { 797 var _this2; 798 _this2 = _Emitter.call(this) || this; 799 _this2.writable = false; 800 installTimerFunctions(_this2, opts); 801 _this2.opts = opts; 802 _this2.query = opts.query; 803 _this2.socket = opts.socket; 804 _this2.supportsBinary = !opts.forceBase64; 805 return _this2; 806 } 807 /** 808 * Emits an error. 809 * 810 * @param {String} reason 811 * @param description 812 * @param context - the error context 813 * @return {Transport} for chaining 814 * @protected 815 */ 816 _inheritsLoose(Transport, _Emitter); 817 var _proto = Transport.prototype; 818 _proto.onError = function onError(reason, description, context) { 819 _Emitter.prototype.emitReserved.call(this, "error", new TransportError(reason, description, context)); 820 return this; 821 } 822 /** 823 * Opens the transport. 824 */; 825 _proto.open = function open() { 826 this.readyState = "opening"; 827 this.doOpen(); 828 return this; 829 } 830 /** 831 * Closes the transport. 832 */; 833 _proto.close = function close() { 834 if (this.readyState === "opening" || this.readyState === "open") { 835 this.doClose(); 836 this.onClose(); 837 } 838 return this; 839 } 840 /** 841 * Sends multiple packets. 842 * 843 * @param {Array} packets 844 */; 845 _proto.send = function send(packets) { 846 if (this.readyState === "open") { 847 this.write(packets); 848 } 849 } 850 /** 851 * Called upon open 852 * 853 * @protected 854 */; 855 _proto.onOpen = function onOpen() { 856 this.readyState = "open"; 857 this.writable = true; 858 _Emitter.prototype.emitReserved.call(this, "open"); 859 } 860 /** 861 * Called with data. 862 * 863 * @param {String} data 864 * @protected 865 */; 866 _proto.onData = function onData(data) { 867 var packet = decodePacket(data, this.socket.binaryType); 868 this.onPacket(packet); 869 } 870 /** 871 * Called with a decoded packet. 872 * 873 * @protected 874 */; 875 _proto.onPacket = function onPacket(packet) { 876 _Emitter.prototype.emitReserved.call(this, "packet", packet); 877 } 878 /** 879 * Called upon close. 880 * 881 * @protected 882 */; 883 _proto.onClose = function onClose(details) { 884 this.readyState = "closed"; 885 _Emitter.prototype.emitReserved.call(this, "close", details); 886 } 887 /** 888 * Pauses the transport, in order not to lose packets during an upgrade. 889 * 890 * @param onPause 891 */; 892 _proto.pause = function pause(onPause) {}; 893 _proto.createUri = function createUri(schema) { 894 var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 895 return schema + "://" + this._hostname() + this._port() + this.opts.path + this._query(query); 896 }; 897 _proto._hostname = function _hostname() { 898 var hostname = this.opts.hostname; 899 return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]"; 900 }; 901 _proto._port = function _port() { 902 if (this.opts.port && (this.opts.secure && Number(this.opts.port) !== 443 || !this.opts.secure && Number(this.opts.port) !== 80)) { 903 return ":" + this.opts.port; 904 } else { 905 return ""; 906 } 907 }; 908 _proto._query = function _query(query) { 909 var encodedQuery = encode(query); 910 return encodedQuery.length ? "?" + encodedQuery : ""; 911 }; 912 return Transport; 913 }(Emitter); 914 915 var Polling = /*#__PURE__*/function (_Transport) { 916 function Polling() { 917 var _this; 918 _this = _Transport.apply(this, arguments) || this; 919 _this._polling = false; 920 return _this; 921 } 922 _inheritsLoose(Polling, _Transport); 923 var _proto = Polling.prototype; 924 /** 925 * Opens the socket (triggers polling). We write a PING message to determine 926 * when the transport is open. 927 * 928 * @protected 929 */ 930 _proto.doOpen = function doOpen() { 931 this._poll(); 932 } 933 /** 934 * Pauses polling. 935 * 936 * @param {Function} onPause - callback upon buffers are flushed and transport is paused 937 * @package 938 */; 939 _proto.pause = function pause(onPause) { 940 var _this2 = this; 941 this.readyState = "pausing"; 942 var pause = function pause() { 943 _this2.readyState = "paused"; 944 onPause(); 945 }; 946 if (this._polling || !this.writable) { 947 var total = 0; 948 if (this._polling) { 949 total++; 950 this.once("pollComplete", function () { 951 --total || pause(); 952 }); 953 } 954 if (!this.writable) { 955 total++; 956 this.once("drain", function () { 957 --total || pause(); 958 }); 959 } 960 } else { 961 pause(); 962 } 963 } 964 /** 965 * Starts polling cycle. 966 * 967 * @private 968 */; 969 _proto._poll = function _poll() { 970 this._polling = true; 971 this.doPoll(); 972 this.emitReserved("poll"); 973 } 974 /** 975 * Overloads onData to detect payloads. 976 * 977 * @protected 978 */; 979 _proto.onData = function onData(data) { 980 var _this3 = this; 981 var callback = function callback(packet) { 982 // if its the first message we consider the transport open 983 if ("opening" === _this3.readyState && packet.type === "open") { 984 _this3.onOpen(); 985 } 986 // if its a close packet, we close the ongoing requests 987 if ("close" === packet.type) { 988 _this3.onClose({ 989 description: "transport closed by the server" 990 }); 991 return false; 992 } 993 // otherwise bypass onData and handle the message 994 _this3.onPacket(packet); 995 }; 996 // decode payload 997 decodePayload(data, this.socket.binaryType).forEach(callback); 998 // if an event did not trigger closing 999 if ("closed" !== this.readyState) { 1000 // if we got data we're not polling 1001 this._polling = false; 1002 this.emitReserved("pollComplete"); 1003 if ("open" === this.readyState) { 1004 this._poll(); 1005 } 1006 } 1007 } 1008 /** 1009 * For polling, send a close packet. 1010 * 1011 * @protected 1012 */; 1013 _proto.doClose = function doClose() { 1014 var _this4 = this; 1015 var close = function close() { 1016 _this4.write([{ 1017 type: "close" 1018 }]); 1019 }; 1020 if ("open" === this.readyState) { 1021 close(); 1022 } else { 1023 // in case we're trying to close while 1024 // handshaking is in progress (GH-164) 1025 this.once("open", close); 1026 } 1027 } 1028 /** 1029 * Writes a packets payload. 1030 * 1031 * @param {Array} packets - data packets 1032 * @protected 1033 */; 1034 _proto.write = function write(packets) { 1035 var _this5 = this; 1036 this.writable = false; 1037 encodePayload(packets, function (data) { 1038 _this5.doWrite(data, function () { 1039 _this5.writable = true; 1040 _this5.emitReserved("drain"); 1041 }); 1042 }); 1043 } 1044 /** 1045 * Generates uri for connection. 1046 * 1047 * @private 1048 */; 1049 _proto.uri = function uri() { 1050 var schema = this.opts.secure ? "https" : "http"; 1051 var query = this.query || {}; 1052 // cache busting is forced 1053 if (false !== this.opts.timestampRequests) { 1054 query[this.opts.timestampParam] = randomString(); 1055 } 1056 if (!this.supportsBinary && !query.sid) { 1057 query.b64 = 1; 1058 } 1059 return this.createUri(schema, query); 1060 }; 1061 return _createClass(Polling, [{ 1062 key: "name", 1063 get: function get() { 1064 return "polling"; 1065 } 1066 }]); 1067 }(Transport); 1068 1069 // imported from https://github.com/component/has-cors 1070 var value = false; 1071 try { 1072 value = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest(); 1073 } catch (err) { 1074 // if XMLHttp support is disabled in IE then it will throw 1075 // when trying to create 1076 } 1077 var hasCORS = value; 1078 1079 function empty() {} 1080 var BaseXHR = /*#__PURE__*/function (_Polling) { 1081 /** 1082 * XHR Polling constructor. 1083 * 1084 * @param {Object} opts 1085 * @package 1086 */ 1087 function BaseXHR(opts) { 1088 var _this; 1089 _this = _Polling.call(this, opts) || this; 1090 if (typeof location !== "undefined") { 1091 var isSSL = "https:" === location.protocol; 1092 var port = location.port; 1093 // some user agents have empty `location.port` 1094 if (!port) { 1095 port = isSSL ? "443" : "80"; 1096 } 1097 _this.xd = typeof location !== "undefined" && opts.hostname !== location.hostname || port !== opts.port; 1098 } 1099 return _this; 1100 } 1101 /** 1102 * Sends data. 1103 * 1104 * @param {String} data to send. 1105 * @param {Function} called upon flush. 1106 * @private 1107 */ 1108 _inheritsLoose(BaseXHR, _Polling); 1109 var _proto = BaseXHR.prototype; 1110 _proto.doWrite = function doWrite(data, fn) { 1111 var _this2 = this; 1112 var req = this.request({ 1113 method: "POST", 1114 data: data 1115 }); 1116 req.on("success", fn); 1117 req.on("error", function (xhrStatus, context) { 1118 _this2.onError("xhr post error", xhrStatus, context); 1119 }); 1120 } 1121 /** 1122 * Starts a poll cycle. 1123 * 1124 * @private 1125 */; 1126 _proto.doPoll = function doPoll() { 1127 var _this3 = this; 1128 var req = this.request(); 1129 req.on("data", this.onData.bind(this)); 1130 req.on("error", function (xhrStatus, context) { 1131 _this3.onError("xhr poll error", xhrStatus, context); 1132 }); 1133 this.pollXhr = req; 1134 }; 1135 return BaseXHR; 1136 }(Polling); 1137 var Request = /*#__PURE__*/function (_Emitter) { 1138 /** 1139 * Request constructor 1140 * 1141 * @param {Object} options 1142 * @package 1143 */ 1144 function Request(createRequest, uri, opts) { 1145 var _this4; 1146 _this4 = _Emitter.call(this) || this; 1147 _this4.createRequest = createRequest; 1148 installTimerFunctions(_this4, opts); 1149 _this4._opts = opts; 1150 _this4._method = opts.method || "GET"; 1151 _this4._uri = uri; 1152 _this4._data = undefined !== opts.data ? opts.data : null; 1153 _this4._create(); 1154 return _this4; 1155 } 1156 /** 1157 * Creates the XHR object and sends the request. 1158 * 1159 * @private 1160 */ 1161 _inheritsLoose(Request, _Emitter); 1162 var _proto2 = Request.prototype; 1163 _proto2._create = function _create() { 1164 var _this5 = this; 1165 var _a; 1166 var opts = pick(this._opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref"); 1167 opts.xdomain = !!this._opts.xd; 1168 var xhr = this._xhr = this.createRequest(opts); 1169 try { 1170 xhr.open(this._method, this._uri, true); 1171 try { 1172 if (this._opts.extraHeaders) { 1173 // @ts-ignore 1174 xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true); 1175 for (var i in this._opts.extraHeaders) { 1176 if (this._opts.extraHeaders.hasOwnProperty(i)) { 1177 xhr.setRequestHeader(i, this._opts.extraHeaders[i]); 1178 } 1179 } 1180 } 1181 } catch (e) {} 1182 if ("POST" === this._method) { 1183 try { 1184 xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8"); 1185 } catch (e) {} 1186 } 1187 try { 1188 xhr.setRequestHeader("Accept", "*/*"); 1189 } catch (e) {} 1190 (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr); 1191 // ie6 check 1192 if ("withCredentials" in xhr) { 1193 xhr.withCredentials = this._opts.withCredentials; 1194 } 1195 if (this._opts.requestTimeout) { 1196 xhr.timeout = this._opts.requestTimeout; 1197 } 1198 xhr.onreadystatechange = function () { 1199 var _a; 1200 if (xhr.readyState === 3) { 1201 (_a = _this5._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies( 1202 // @ts-ignore 1203 xhr.getResponseHeader("set-cookie")); 1204 } 1205 if (4 !== xhr.readyState) return; 1206 if (200 === xhr.status || 1223 === xhr.status) { 1207 _this5._onLoad(); 1208 } else { 1209 // make sure the `error` event handler that's user-set 1210 // does not throw in the same tick and gets caught here 1211 _this5.setTimeoutFn(function () { 1212 _this5._onError(typeof xhr.status === "number" ? xhr.status : 0); 1213 }, 0); 1214 } 1215 }; 1216 xhr.send(this._data); 1217 } catch (e) { 1218 // Need to defer since .create() is called directly from the constructor 1219 // and thus the 'error' event can only be only bound *after* this exception 1220 // occurs. Therefore, also, we cannot throw here at all. 1221 this.setTimeoutFn(function () { 1222 _this5._onError(e); 1223 }, 0); 1224 return; 1225 } 1226 if (typeof document !== "undefined") { 1227 this._index = Request.requestsCount++; 1228 Request.requests[this._index] = this; 1229 } 1230 } 1231 /** 1232 * Called upon error. 1233 * 1234 * @private 1235 */; 1236 _proto2._onError = function _onError(err) { 1237 this.emitReserved("error", err, this._xhr); 1238 this._cleanup(true); 1239 } 1240 /** 1241 * Cleans up house. 1242 * 1243 * @private 1244 */; 1245 _proto2._cleanup = function _cleanup(fromError) { 1246 if ("undefined" === typeof this._xhr || null === this._xhr) { 1247 return; 1248 } 1249 this._xhr.onreadystatechange = empty; 1250 if (fromError) { 1251 try { 1252 this._xhr.abort(); 1253 } catch (e) {} 1254 } 1255 if (typeof document !== "undefined") { 1256 delete Request.requests[this._index]; 1257 } 1258 this._xhr = null; 1259 } 1260 /** 1261 * Called upon load. 1262 * 1263 * @private 1264 */; 1265 _proto2._onLoad = function _onLoad() { 1266 var data = this._xhr.responseText; 1267 if (data !== null) { 1268 this.emitReserved("data", data); 1269 this.emitReserved("success"); 1270 this._cleanup(); 1271 } 1272 } 1273 /** 1274 * Aborts the request. 1275 * 1276 * @package 1277 */; 1278 _proto2.abort = function abort() { 1279 this._cleanup(); 1280 }; 1281 return Request; 1282 }(Emitter); 1283 Request.requestsCount = 0; 1284 Request.requests = {}; 1285 /** 1286 * Aborts pending requests when unloading the window. This is needed to prevent 1287 * memory leaks (e.g. when using IE) and to ensure that no spurious error is 1288 * emitted. 1289 */ 1290 if (typeof document !== "undefined") { 1291 // @ts-ignore 1292 if (typeof attachEvent === "function") { 1293 // @ts-ignore 1294 attachEvent("onunload", unloadHandler); 1295 } else if (typeof addEventListener === "function") { 1296 var terminationEvent = "onpagehide" in globalThisShim ? "pagehide" : "unload"; 1297 addEventListener(terminationEvent, unloadHandler, false); 1298 } 1299 } 1300 function unloadHandler() { 1301 for (var i in Request.requests) { 1302 if (Request.requests.hasOwnProperty(i)) { 1303 Request.requests[i].abort(); 1304 } 1305 } 1306 } 1307 var hasXHR2 = function () { 1308 var xhr = newRequest({ 1309 xdomain: false 1310 }); 1311 return xhr && xhr.responseType !== null; 1312 }(); 1313 /** 1314 * HTTP long-polling based on the built-in `XMLHttpRequest` object. 1315 * 1316 * Usage: browser 1317 * 1318 * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest 1319 */ 1320 var XHR = /*#__PURE__*/function (_BaseXHR) { 1321 function XHR(opts) { 1322 var _this6; 1323 _this6 = _BaseXHR.call(this, opts) || this; 1324 var forceBase64 = opts && opts.forceBase64; 1325 _this6.supportsBinary = hasXHR2 && !forceBase64; 1326 return _this6; 1327 } 1328 _inheritsLoose(XHR, _BaseXHR); 1329 var _proto3 = XHR.prototype; 1330 _proto3.request = function request() { 1331 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1332 _extends(opts, { 1333 xd: this.xd 1334 }, this.opts); 1335 return new Request(newRequest, this.uri(), opts); 1336 }; 1337 return XHR; 1338 }(BaseXHR); 1339 function newRequest(opts) { 1340 var xdomain = opts.xdomain; 1341 // XMLHttpRequest can be disabled on IE 1342 try { 1343 if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) { 1344 return new XMLHttpRequest(); 1345 } 1346 } catch (e) {} 1347 if (!xdomain) { 1348 try { 1349 return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP"); 1350 } catch (e) {} 1351 } 1352 } 1353 1354 // detect ReactNative environment 1355 var isReactNative = typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product.toLowerCase() === "reactnative"; 1356 var BaseWS = /*#__PURE__*/function (_Transport) { 1357 function BaseWS() { 1358 return _Transport.apply(this, arguments) || this; 1359 } 1360 _inheritsLoose(BaseWS, _Transport); 1361 var _proto = BaseWS.prototype; 1362 _proto.doOpen = function doOpen() { 1363 var uri = this.uri(); 1364 var protocols = this.opts.protocols; 1365 // React Native only supports the 'headers' option, and will print a warning if anything else is passed 1366 var opts = isReactNative ? {} : pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity"); 1367 if (this.opts.extraHeaders) { 1368 opts.headers = this.opts.extraHeaders; 1369 } 1370 try { 1371 this.ws = this.createSocket(uri, protocols, opts); 1372 } catch (err) { 1373 return this.emitReserved("error", err); 1374 } 1375 this.ws.binaryType = this.socket.binaryType; 1376 this.addEventListeners(); 1377 } 1378 /** 1379 * Adds event listeners to the socket 1380 * 1381 * @private 1382 */; 1383 _proto.addEventListeners = function addEventListeners() { 1384 var _this = this; 1385 this.ws.onopen = function () { 1386 if (_this.opts.autoUnref) { 1387 _this.ws._socket.unref(); 1388 } 1389 _this.onOpen(); 1390 }; 1391 this.ws.onclose = function (closeEvent) { 1392 return _this.onClose({ 1393 description: "websocket connection closed", 1394 context: closeEvent 1395 }); 1396 }; 1397 this.ws.onmessage = function (ev) { 1398 return _this.onData(ev.data); 1399 }; 1400 this.ws.onerror = function (e) { 1401 return _this.onError("websocket error", e); 1402 }; 1403 }; 1404 _proto.write = function write(packets) { 1405 var _this2 = this; 1406 this.writable = false; 1407 // encodePacket efficient as it uses WS framing 1408 // no need for encodePayload 1409 var _loop = function _loop() { 1410 var packet = packets[i]; 1411 var lastPacket = i === packets.length - 1; 1412 encodePacket(packet, _this2.supportsBinary, function (data) { 1413 // Sometimes the websocket has already been closed but the browser didn't 1414 // have a chance of informing us about it yet, in that case send will 1415 // throw an error 1416 try { 1417 _this2.doWrite(packet, data); 1418 } catch (e) {} 1419 if (lastPacket) { 1420 // fake drain 1421 // defer to next tick to allow Socket to clear writeBuffer 1422 nextTick(function () { 1423 _this2.writable = true; 1424 _this2.emitReserved("drain"); 1425 }, _this2.setTimeoutFn); 1426 } 1427 }); 1428 }; 1429 for (var i = 0; i < packets.length; i++) { 1430 _loop(); 1431 } 1432 }; 1433 _proto.doClose = function doClose() { 1434 if (typeof this.ws !== "undefined") { 1435 this.ws.onerror = function () {}; 1436 this.ws.close(); 1437 this.ws = null; 1438 } 1439 } 1440 /** 1441 * Generates uri for connection. 1442 * 1443 * @private 1444 */; 1445 _proto.uri = function uri() { 1446 var schema = this.opts.secure ? "wss" : "ws"; 1447 var query = this.query || {}; 1448 // append timestamp to URI 1449 if (this.opts.timestampRequests) { 1450 query[this.opts.timestampParam] = randomString(); 1451 } 1452 // communicate binary support capabilities 1453 if (!this.supportsBinary) { 1454 query.b64 = 1; 1455 } 1456 return this.createUri(schema, query); 1457 }; 1458 return _createClass(BaseWS, [{ 1459 key: "name", 1460 get: function get() { 1461 return "websocket"; 1462 } 1463 }]); 1464 }(Transport); 1465 var WebSocketCtor = globalThisShim.WebSocket || globalThisShim.MozWebSocket; 1466 /** 1467 * WebSocket transport based on the built-in `WebSocket` object. 1468 * 1469 * Usage: browser, Node.js (since v21), Deno, Bun 1470 * 1471 * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket 1472 * @see https://caniuse.com/mdn-api_websocket 1473 * @see https://nodejs.org/api/globals.html#websocket 1474 */ 1475 var WS = /*#__PURE__*/function (_BaseWS) { 1476 function WS() { 1477 return _BaseWS.apply(this, arguments) || this; 1478 } 1479 _inheritsLoose(WS, _BaseWS); 1480 var _proto2 = WS.prototype; 1481 _proto2.createSocket = function createSocket(uri, protocols, opts) { 1482 return !isReactNative ? protocols ? new WebSocketCtor(uri, protocols) : new WebSocketCtor(uri) : new WebSocketCtor(uri, protocols, opts); 1483 }; 1484 _proto2.doWrite = function doWrite(_packet, data) { 1485 this.ws.send(data); 1486 }; 1487 return WS; 1488 }(BaseWS); 1489 1490 /** 1491 * WebTransport transport based on the built-in `WebTransport` object. 1492 * 1493 * Usage: browser, Node.js (with the `@fails-components/webtransport` package) 1494 * 1495 * @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport 1496 * @see https://caniuse.com/webtransport 1497 */ 1498 var WT = /*#__PURE__*/function (_Transport) { 1499 function WT() { 1500 return _Transport.apply(this, arguments) || this; 1501 } 1502 _inheritsLoose(WT, _Transport); 1503 var _proto = WT.prototype; 1504 _proto.doOpen = function doOpen() { 1505 var _this = this; 1506 try { 1507 // @ts-ignore 1508 this._transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]); 1509 } catch (err) { 1510 return this.emitReserved("error", err); 1511 } 1512 this._transport.closed.then(function () { 1513 _this.onClose(); 1514 })["catch"](function (err) { 1515 _this.onError("webtransport error", err); 1516 }); 1517 // note: we could have used async/await, but that would require some additional polyfills 1518 this._transport.ready.then(function () { 1519 _this._transport.createBidirectionalStream().then(function (stream) { 1520 var decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, _this.socket.binaryType); 1521 var reader = stream.readable.pipeThrough(decoderStream).getReader(); 1522 var encoderStream = createPacketEncoderStream(); 1523 encoderStream.readable.pipeTo(stream.writable); 1524 _this._writer = encoderStream.writable.getWriter(); 1525 var read = function read() { 1526 reader.read().then(function (_ref) { 1527 var done = _ref.done, 1528 value = _ref.value; 1529 if (done) { 1530 return; 1531 } 1532 _this.onPacket(value); 1533 read(); 1534 })["catch"](function (err) {}); 1535 }; 1536 read(); 1537 var packet = { 1538 type: "open" 1539 }; 1540 if (_this.query.sid) { 1541 packet.data = "{\"sid\":\"".concat(_this.query.sid, "\"}"); 1542 } 1543 _this._writer.write(packet).then(function () { 1544 return _this.onOpen(); 1545 }); 1546 }); 1547 }); 1548 }; 1549 _proto.write = function write(packets) { 1550 var _this2 = this; 1551 this.writable = false; 1552 var _loop = function _loop() { 1553 var packet = packets[i]; 1554 var lastPacket = i === packets.length - 1; 1555 _this2._writer.write(packet).then(function () { 1556 if (lastPacket) { 1557 nextTick(function () { 1558 _this2.writable = true; 1559 _this2.emitReserved("drain"); 1560 }, _this2.setTimeoutFn); 1561 } 1562 }); 1563 }; 1564 for (var i = 0; i < packets.length; i++) { 1565 _loop(); 1566 } 1567 }; 1568 _proto.doClose = function doClose() { 1569 var _a; 1570 (_a = this._transport) === null || _a === void 0 ? void 0 : _a.close(); 1571 }; 1572 return _createClass(WT, [{ 1573 key: "name", 1574 get: function get() { 1575 return "webtransport"; 1576 } 1577 }]); 1578 }(Transport); 1579 1580 var transports = { 1581 websocket: WS, 1582 webtransport: WT, 1583 polling: XHR 1584 }; 1585 1586 // imported from https://github.com/galkn/parseuri 1587 /** 1588 * Parses a URI 1589 * 1590 * Note: we could also have used the built-in URL object, but it isn't supported on all platforms. 1591 * 1592 * See: 1593 * - https://developer.mozilla.org/en-US/docs/Web/API/URL 1594 * - https://caniuse.com/url 1595 * - https://www.rfc-editor.org/rfc/rfc3986#appendix-B 1596 * 1597 * History of the parse() method: 1598 * - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c 1599 * - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3 1600 * - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242 1601 * 1602 * @author Steven Levithan <stevenlevithan.com> (MIT license) 1603 * @api private 1604 */ 1605 var re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; 1606 var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor']; 1607 function parse(str) { 1608 if (str.length > 8000) { 1609 throw "URI too long"; 1610 } 1611 var src = str, 1612 b = str.indexOf('['), 1613 e = str.indexOf(']'); 1614 if (b != -1 && e != -1) { 1615 str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); 1616 } 1617 var m = re.exec(str || ''), 1618 uri = {}, 1619 i = 14; 1620 while (i--) { 1621 uri[parts[i]] = m[i] || ''; 1622 } 1623 if (b != -1 && e != -1) { 1624 uri.source = src; 1625 uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); 1626 uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); 1627 uri.ipv6uri = true; 1628 } 1629 uri.pathNames = pathNames(uri, uri['path']); 1630 uri.queryKey = queryKey(uri, uri['query']); 1631 return uri; 1632 } 1633 function pathNames(obj, path) { 1634 var regx = /\/{2,9}/g, 1635 names = path.replace(regx, "/").split("/"); 1636 if (path.slice(0, 1) == '/' || path.length === 0) { 1637 names.splice(0, 1); 1638 } 1639 if (path.slice(-1) == '/') { 1640 names.splice(names.length - 1, 1); 1641 } 1642 return names; 1643 } 1644 function queryKey(uri, query) { 1645 var data = {}; 1646 query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) { 1647 if ($1) { 1648 data[$1] = $2; 1649 } 1650 }); 1651 return data; 1652 } 1653 1654 var withEventListeners = typeof addEventListener === "function" && typeof removeEventListener === "function"; 1655 var OFFLINE_EVENT_LISTENERS = []; 1656 if (withEventListeners) { 1657 // within a ServiceWorker, any event handler for the 'offline' event must be added on the initial evaluation of the 1658 // script, so we create one single event listener here which will forward the event to the socket instances 1659 addEventListener("offline", function () { 1660 OFFLINE_EVENT_LISTENERS.forEach(function (listener) { 1661 return listener(); 1662 }); 1663 }, false); 1664 } 1665 /** 1666 * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established 1667 * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport. 1668 * 1669 * This class comes without upgrade mechanism, which means that it will keep the first low-level transport that 1670 * successfully establishes the connection. 1671 * 1672 * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory. 1673 * 1674 * @example 1675 * import { SocketWithoutUpgrade, WebSocket } from "engine.io-client"; 1676 * 1677 * const socket = new SocketWithoutUpgrade({ 1678 * transports: [WebSocket] 1679 * }); 1680 * 1681 * socket.on("open", () => { 1682 * socket.send("hello"); 1683 * }); 1684 * 1685 * @see SocketWithUpgrade 1686 * @see Socket 1687 */ 1688 var SocketWithoutUpgrade = /*#__PURE__*/function (_Emitter) { 1689 /** 1690 * Socket constructor. 1691 * 1692 * @param {String|Object} uri - uri or options 1693 * @param {Object} opts - options 1694 */ 1695 function SocketWithoutUpgrade(uri, opts) { 1696 var _this; 1697 _this = _Emitter.call(this) || this; 1698 _this.binaryType = defaultBinaryType; 1699 _this.writeBuffer = []; 1700 _this._prevBufferLen = 0; 1701 _this._pingInterval = -1; 1702 _this._pingTimeout = -1; 1703 _this._maxPayload = -1; 1704 /** 1705 * The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the 1706 * callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked. 1707 */ 1708 _this._pingTimeoutTime = Infinity; 1709 if (uri && "object" === _typeof(uri)) { 1710 opts = uri; 1711 uri = null; 1712 } 1713 if (uri) { 1714 var parsedUri = parse(uri); 1715 opts.hostname = parsedUri.host; 1716 opts.secure = parsedUri.protocol === "https" || parsedUri.protocol === "wss"; 1717 opts.port = parsedUri.port; 1718 if (parsedUri.query) opts.query = parsedUri.query; 1719 } else if (opts.host) { 1720 opts.hostname = parse(opts.host).host; 1721 } 1722 installTimerFunctions(_this, opts); 1723 _this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol; 1724 if (opts.hostname && !opts.port) { 1725 // if no port is specified manually, use the protocol default 1726 opts.port = _this.secure ? "443" : "80"; 1727 } 1728 _this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost"); 1729 _this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : _this.secure ? "443" : "80"); 1730 _this.transports = []; 1731 _this._transportsByName = {}; 1732 opts.transports.forEach(function (t) { 1733 var transportName = t.prototype.name; 1734 _this.transports.push(transportName); 1735 _this._transportsByName[transportName] = t; 1736 }); 1737 _this.opts = _extends({ 1738 path: "/engine.io", 1739 agent: false, 1740 withCredentials: false, 1741 upgrade: true, 1742 timestampParam: "t", 1743 rememberUpgrade: false, 1744 addTrailingSlash: true, 1745 rejectUnauthorized: true, 1746 perMessageDeflate: { 1747 threshold: 1024 1748 }, 1749 transportOptions: {}, 1750 closeOnBeforeunload: false 1751 }, opts); 1752 _this.opts.path = _this.opts.path.replace(/\/$/, "") + (_this.opts.addTrailingSlash ? "/" : ""); 1753 if (typeof _this.opts.query === "string") { 1754 _this.opts.query = decode(_this.opts.query); 1755 } 1756 if (withEventListeners) { 1757 if (_this.opts.closeOnBeforeunload) { 1758 // Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener 1759 // ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is 1760 // closed/reloaded) 1761 _this._beforeunloadEventListener = function () { 1762 if (_this.transport) { 1763 // silently close the transport 1764 _this.transport.removeAllListeners(); 1765 _this.transport.close(); 1766 } 1767 }; 1768 addEventListener("beforeunload", _this._beforeunloadEventListener, false); 1769 } 1770 if (_this.hostname !== "localhost") { 1771 _this._offlineEventListener = function () { 1772 _this._onClose("transport close", { 1773 description: "network connection lost" 1774 }); 1775 }; 1776 OFFLINE_EVENT_LISTENERS.push(_this._offlineEventListener); 1777 } 1778 } 1779 if (_this.opts.withCredentials) { 1780 _this._cookieJar = createCookieJar(); 1781 } 1782 _this._open(); 1783 return _this; 1784 } 1785 /** 1786 * Creates transport of the given type. 1787 * 1788 * @param {String} name - transport name 1789 * @return {Transport} 1790 * @private 1791 */ 1792 _inheritsLoose(SocketWithoutUpgrade, _Emitter); 1793 var _proto = SocketWithoutUpgrade.prototype; 1794 _proto.createTransport = function createTransport(name) { 1795 var query = _extends({}, this.opts.query); 1796 // append engine.io protocol identifier 1797 query.EIO = protocol$1; 1798 // transport name 1799 query.transport = name; 1800 // session id if we already have one 1801 if (this.id) query.sid = this.id; 1802 var opts = _extends({}, this.opts, { 1803 query: query, 1804 socket: this, 1805 hostname: this.hostname, 1806 secure: this.secure, 1807 port: this.port 1808 }, this.opts.transportOptions[name]); 1809 return new this._transportsByName[name](opts); 1810 } 1811 /** 1812 * Initializes transport to use and starts probe. 1813 * 1814 * @private 1815 */; 1816 _proto._open = function _open() { 1817 var _this2 = this; 1818 if (this.transports.length === 0) { 1819 // Emit error on next tick so it can be listened to 1820 this.setTimeoutFn(function () { 1821 _this2.emitReserved("error", "No transports available"); 1822 }, 0); 1823 return; 1824 } 1825 var transportName = this.opts.rememberUpgrade && SocketWithoutUpgrade.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1 ? "websocket" : this.transports[0]; 1826 this.readyState = "opening"; 1827 var transport = this.createTransport(transportName); 1828 transport.open(); 1829 this.setTransport(transport); 1830 } 1831 /** 1832 * Sets the current transport. Disables the existing one (if any). 1833 * 1834 * @private 1835 */; 1836 _proto.setTransport = function setTransport(transport) { 1837 var _this3 = this; 1838 if (this.transport) { 1839 this.transport.removeAllListeners(); 1840 } 1841 // set up transport 1842 this.transport = transport; 1843 // set up transport listeners 1844 transport.on("drain", this._onDrain.bind(this)).on("packet", this._onPacket.bind(this)).on("error", this._onError.bind(this)).on("close", function (reason) { 1845 return _this3._onClose("transport close", reason); 1846 }); 1847 } 1848 /** 1849 * Called when connection is deemed open. 1850 * 1851 * @private 1852 */; 1853 _proto.onOpen = function onOpen() { 1854 this.readyState = "open"; 1855 SocketWithoutUpgrade.priorWebsocketSuccess = "websocket" === this.transport.name; 1856 this.emitReserved("open"); 1857 this.flush(); 1858 } 1859 /** 1860 * Handles a packet. 1861 * 1862 * @private 1863 */; 1864 _proto._onPacket = function _onPacket(packet) { 1865 if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { 1866 this.emitReserved("packet", packet); 1867 // Socket is live - any packet counts 1868 this.emitReserved("heartbeat"); 1869 switch (packet.type) { 1870 case "open": 1871 this.onHandshake(JSON.parse(packet.data)); 1872 break; 1873 case "ping": 1874 this._sendPacket("pong"); 1875 this.emitReserved("ping"); 1876 this.emitReserved("pong"); 1877 this._resetPingTimeout(); 1878 break; 1879 case "error": 1880 var err = new Error("server error"); 1881 // @ts-ignore 1882 err.code = packet.data; 1883 this._onError(err); 1884 break; 1885 case "message": 1886 this.emitReserved("data", packet.data); 1887 this.emitReserved("message", packet.data); 1888 break; 1889 } 1890 } 1891 } 1892 /** 1893 * Called upon handshake completion. 1894 * 1895 * @param {Object} data - handshake obj 1896 * @private 1897 */; 1898 _proto.onHandshake = function onHandshake(data) { 1899 this.emitReserved("handshake", data); 1900 this.id = data.sid; 1901 this.transport.query.sid = data.sid; 1902 this._pingInterval = data.pingInterval; 1903 this._pingTimeout = data.pingTimeout; 1904 this._maxPayload = data.maxPayload; 1905 this.onOpen(); 1906 // In case open handler closes socket 1907 if ("closed" === this.readyState) return; 1908 this._resetPingTimeout(); 1909 } 1910 /** 1911 * Sets and resets ping timeout timer based on server pings. 1912 * 1913 * @private 1914 */; 1915 _proto._resetPingTimeout = function _resetPingTimeout() { 1916 var _this4 = this; 1917 this.clearTimeoutFn(this._pingTimeoutTimer); 1918 var delay = this._pingInterval + this._pingTimeout; 1919 this._pingTimeoutTime = Date.now() + delay; 1920 this._pingTimeoutTimer = this.setTimeoutFn(function () { 1921 _this4._onClose("ping timeout"); 1922 }, delay); 1923 if (this.opts.autoUnref) { 1924 this._pingTimeoutTimer.unref(); 1925 } 1926 } 1927 /** 1928 * Called on `drain` event 1929 * 1930 * @private 1931 */; 1932 _proto._onDrain = function _onDrain() { 1933 this.writeBuffer.splice(0, this._prevBufferLen); 1934 // setting prevBufferLen = 0 is very important 1935 // for example, when upgrading, upgrade packet is sent over, 1936 // and a nonzero prevBufferLen could cause problems on `drain` 1937 this._prevBufferLen = 0; 1938 if (0 === this.writeBuffer.length) { 1939 this.emitReserved("drain"); 1940 } else { 1941 this.flush(); 1942 } 1943 } 1944 /** 1945 * Flush write buffers. 1946 * 1947 * @private 1948 */; 1949 _proto.flush = function flush() { 1950 if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) { 1951 var packets = this._getWritablePackets(); 1952 this.transport.send(packets); 1953 // keep track of current length of writeBuffer 1954 // splice writeBuffer and callbackBuffer on `drain` 1955 this._prevBufferLen = packets.length; 1956 this.emitReserved("flush"); 1957 } 1958 } 1959 /** 1960 * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP 1961 * long-polling) 1962 * 1963 * @private 1964 */; 1965 _proto._getWritablePackets = function _getWritablePackets() { 1966 var shouldCheckPayloadSize = this._maxPayload && this.transport.name === "polling" && this.writeBuffer.length > 1; 1967 if (!shouldCheckPayloadSize) { 1968 return this.writeBuffer; 1969 } 1970 var payloadSize = 1; // first packet type 1971 for (var i = 0; i < this.writeBuffer.length; i++) { 1972 var data = this.writeBuffer[i].data; 1973 if (data) { 1974 payloadSize += byteLength(data); 1975 } 1976 if (i > 0 && payloadSize > this._maxPayload) { 1977 return this.writeBuffer.slice(0, i); 1978 } 1979 payloadSize += 2; // separator + packet type 1980 } 1981 return this.writeBuffer; 1982 } 1983 /** 1984 * Checks whether the heartbeat timer has expired but the socket has not yet been notified. 1985 * 1986 * Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the 1987 * `write()` method then the message would not be buffered by the Socket.IO client. 1988 * 1989 * @return {boolean} 1990 * @private 1991 */ 1992 /* private */; 1993 _proto._hasPingExpired = function _hasPingExpired() { 1994 var _this5 = this; 1995 if (!this._pingTimeoutTime) return true; 1996 var hasExpired = Date.now() > this._pingTimeoutTime; 1997 if (hasExpired) { 1998 this._pingTimeoutTime = 0; 1999 nextTick(function () { 2000 _this5._onClose("ping timeout"); 2001 }, this.setTimeoutFn); 2002 } 2003 return hasExpired; 2004 } 2005 /** 2006 * Sends a message. 2007 * 2008 * @param {String} msg - message. 2009 * @param {Object} options. 2010 * @param {Function} fn - callback function. 2011 * @return {Socket} for chaining. 2012 */; 2013 _proto.write = function write(msg, options, fn) { 2014 this._sendPacket("message", msg, options, fn); 2015 return this; 2016 } 2017 /** 2018 * Sends a message. Alias of {@link Socket#write}. 2019 * 2020 * @param {String} msg - message. 2021 * @param {Object} options. 2022 * @param {Function} fn - callback function. 2023 * @return {Socket} for chaining. 2024 */; 2025 _proto.send = function send(msg, options, fn) { 2026 this._sendPacket("message", msg, options, fn); 2027 return this; 2028 } 2029 /** 2030 * Sends a packet. 2031 * 2032 * @param {String} type: packet type. 2033 * @param {String} data. 2034 * @param {Object} options. 2035 * @param {Function} fn - callback function. 2036 * @private 2037 */; 2038 _proto._sendPacket = function _sendPacket(type, data, options, fn) { 2039 if ("function" === typeof data) { 2040 fn = data; 2041 data = undefined; 2042 } 2043 if ("function" === typeof options) { 2044 fn = options; 2045 options = null; 2046 } 2047 if ("closing" === this.readyState || "closed" === this.readyState) { 2048 return; 2049 } 2050 options = options || {}; 2051 options.compress = false !== options.compress; 2052 var packet = { 2053 type: type, 2054 data: data, 2055 options: options 2056 }; 2057 this.emitReserved("packetCreate", packet); 2058 this.writeBuffer.push(packet); 2059 if (fn) this.once("flush", fn); 2060 this.flush(); 2061 } 2062 /** 2063 * Closes the connection. 2064 */; 2065 _proto.close = function close() { 2066 var _this6 = this; 2067 var close = function close() { 2068 _this6._onClose("forced close"); 2069 _this6.transport.close(); 2070 }; 2071 var cleanupAndClose = function cleanupAndClose() { 2072 _this6.off("upgrade", cleanupAndClose); 2073 _this6.off("upgradeError", cleanupAndClose); 2074 close(); 2075 }; 2076 var waitForUpgrade = function waitForUpgrade() { 2077 // wait for upgrade to finish since we can't send packets while pausing a transport 2078 _this6.once("upgrade", cleanupAndClose); 2079 _this6.once("upgradeError", cleanupAndClose); 2080 }; 2081 if ("opening" === this.readyState || "open" === this.readyState) { 2082 this.readyState = "closing"; 2083 if (this.writeBuffer.length) { 2084 this.once("drain", function () { 2085 if (_this6.upgrading) { 2086 waitForUpgrade(); 2087 } else { 2088 close(); 2089 } 2090 }); 2091 } else if (this.upgrading) { 2092 waitForUpgrade(); 2093 } else { 2094 close(); 2095 } 2096 } 2097 return this; 2098 } 2099 /** 2100 * Called upon transport error 2101 * 2102 * @private 2103 */; 2104 _proto._onError = function _onError(err) { 2105 SocketWithoutUpgrade.priorWebsocketSuccess = false; 2106 if (this.opts.tryAllTransports && this.transports.length > 1 && this.readyState === "opening") { 2107 this.transports.shift(); 2108 return this._open(); 2109 } 2110 this.emitReserved("error", err); 2111 this._onClose("transport error", err); 2112 } 2113 /** 2114 * Called upon transport close. 2115 * 2116 * @private 2117 */; 2118 _proto._onClose = function _onClose(reason, description) { 2119 if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { 2120 // clear timers 2121 this.clearTimeoutFn(this._pingTimeoutTimer); 2122 // stop event from firing again for transport 2123 this.transport.removeAllListeners("close"); 2124 // ensure transport won't stay open 2125 this.transport.close(); 2126 // ignore further transport communication 2127 this.transport.removeAllListeners(); 2128 if (withEventListeners) { 2129 if (this._beforeunloadEventListener) { 2130 removeEventListener("beforeunload", this._beforeunloadEventListener, false); 2131 } 2132 if (this._offlineEventListener) { 2133 var i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener); 2134 if (i !== -1) { 2135 OFFLINE_EVENT_LISTENERS.splice(i, 1); 2136 } 2137 } 2138 } 2139 // set ready state 2140 this.readyState = "closed"; 2141 // clear session id 2142 this.id = null; 2143 // emit close event 2144 this.emitReserved("close", reason, description); 2145 // clean buffers after, so users can still 2146 // grab the buffers on `close` event 2147 this.writeBuffer = []; 2148 this._prevBufferLen = 0; 2149 } 2150 }; 2151 return SocketWithoutUpgrade; 2152 }(Emitter); 2153 SocketWithoutUpgrade.protocol = protocol$1; 2154 /** 2155 * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established 2156 * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport. 2157 * 2158 * This class comes with an upgrade mechanism, which means that once the connection is established with the first 2159 * low-level transport, it will try to upgrade to a better transport. 2160 * 2161 * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory. 2162 * 2163 * @example 2164 * import { SocketWithUpgrade, WebSocket } from "engine.io-client"; 2165 * 2166 * const socket = new SocketWithUpgrade({ 2167 * transports: [WebSocket] 2168 * }); 2169 * 2170 * socket.on("open", () => { 2171 * socket.send("hello"); 2172 * }); 2173 * 2174 * @see SocketWithoutUpgrade 2175 * @see Socket 2176 */ 2177 var SocketWithUpgrade = /*#__PURE__*/function (_SocketWithoutUpgrade) { 2178 function SocketWithUpgrade() { 2179 var _this7; 2180 _this7 = _SocketWithoutUpgrade.apply(this, arguments) || this; 2181 _this7._upgrades = []; 2182 return _this7; 2183 } 2184 _inheritsLoose(SocketWithUpgrade, _SocketWithoutUpgrade); 2185 var _proto2 = SocketWithUpgrade.prototype; 2186 _proto2.onOpen = function onOpen() { 2187 _SocketWithoutUpgrade.prototype.onOpen.call(this); 2188 if ("open" === this.readyState && this.opts.upgrade) { 2189 for (var i = 0; i < this._upgrades.length; i++) { 2190 this._probe(this._upgrades[i]); 2191 } 2192 } 2193 } 2194 /** 2195 * Probes a transport. 2196 * 2197 * @param {String} name - transport name 2198 * @private 2199 */; 2200 _proto2._probe = function _probe(name) { 2201 var _this8 = this; 2202 var transport = this.createTransport(name); 2203 var failed = false; 2204 SocketWithoutUpgrade.priorWebsocketSuccess = false; 2205 var onTransportOpen = function onTransportOpen() { 2206 if (failed) return; 2207 transport.send([{ 2208 type: "ping", 2209 data: "probe" 2210 }]); 2211 transport.once("packet", function (msg) { 2212 if (failed) return; 2213 if ("pong" === msg.type && "probe" === msg.data) { 2214 _this8.upgrading = true; 2215 _this8.emitReserved("upgrading", transport); 2216 if (!transport) return; 2217 SocketWithoutUpgrade.priorWebsocketSuccess = "websocket" === transport.name; 2218 _this8.transport.pause(function () { 2219 if (failed) return; 2220 if ("closed" === _this8.readyState) return; 2221 cleanup(); 2222 _this8.setTransport(transport); 2223 transport.send([{ 2224 type: "upgrade" 2225 }]); 2226 _this8.emitReserved("upgrade", transport); 2227 transport = null; 2228 _this8.upgrading = false; 2229 _this8.flush(); 2230 }); 2231 } else { 2232 var err = new Error("probe error"); 2233 // @ts-ignore 2234 err.transport = transport.name; 2235 _this8.emitReserved("upgradeError", err); 2236 } 2237 }); 2238 }; 2239 function freezeTransport() { 2240 if (failed) return; 2241 // Any callback called by transport should be ignored since now 2242 failed = true; 2243 cleanup(); 2244 transport.close(); 2245 transport = null; 2246 } 2247 // Handle any error that happens while probing 2248 var onerror = function onerror(err) { 2249 var error = new Error("probe error: " + err); 2250 // @ts-ignore 2251 error.transport = transport.name; 2252 freezeTransport(); 2253 _this8.emitReserved("upgradeError", error); 2254 }; 2255 function onTransportClose() { 2256 onerror("transport closed"); 2257 } 2258 // When the socket is closed while we're probing 2259 function onclose() { 2260 onerror("socket closed"); 2261 } 2262 // When the socket is upgraded while we're probing 2263 function onupgrade(to) { 2264 if (transport && to.name !== transport.name) { 2265 freezeTransport(); 2266 } 2267 } 2268 // Remove all listeners on the transport and on self 2269 var cleanup = function cleanup() { 2270 transport.removeListener("open", onTransportOpen); 2271 transport.removeListener("error", onerror); 2272 transport.removeListener("close", onTransportClose); 2273 _this8.off("close", onclose); 2274 _this8.off("upgrading", onupgrade); 2275 }; 2276 transport.once("open", onTransportOpen); 2277 transport.once("error", onerror); 2278 transport.once("close", onTransportClose); 2279 this.once("close", onclose); 2280 this.once("upgrading", onupgrade); 2281 if (this._upgrades.indexOf("webtransport") !== -1 && name !== "webtransport") { 2282 // favor WebTransport 2283 this.setTimeoutFn(function () { 2284 if (!failed) { 2285 transport.open(); 2286 } 2287 }, 200); 2288 } else { 2289 transport.open(); 2290 } 2291 }; 2292 _proto2.onHandshake = function onHandshake(data) { 2293 this._upgrades = this._filterUpgrades(data.upgrades); 2294 _SocketWithoutUpgrade.prototype.onHandshake.call(this, data); 2295 } 2296 /** 2297 * Filters upgrades, returning only those matching client transports. 2298 * 2299 * @param {Array} upgrades - server upgrades 2300 * @private 2301 */; 2302 _proto2._filterUpgrades = function _filterUpgrades(upgrades) { 2303 var filteredUpgrades = []; 2304 for (var i = 0; i < upgrades.length; i++) { 2305 if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]); 2306 } 2307 return filteredUpgrades; 2308 }; 2309 return SocketWithUpgrade; 2310 }(SocketWithoutUpgrade); 2311 /** 2312 * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established 2313 * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport. 2314 * 2315 * This class comes with an upgrade mechanism, which means that once the connection is established with the first 2316 * low-level transport, it will try to upgrade to a better transport. 2317 * 2318 * @example 2319 * import { Socket } from "engine.io-client"; 2320 * 2321 * const socket = new Socket(); 2322 * 2323 * socket.on("open", () => { 2324 * socket.send("hello"); 2325 * }); 2326 * 2327 * @see SocketWithoutUpgrade 2328 * @see SocketWithUpgrade 2329 */ 2330 var Socket$1 = /*#__PURE__*/function (_SocketWithUpgrade) { 2331 function Socket(uri) { 2332 var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2333 var o = _typeof(uri) === "object" ? uri : opts; 2334 if (!o.transports || o.transports && typeof o.transports[0] === "string") { 2335 o.transports = (o.transports || ["polling", "websocket", "webtransport"]).map(function (transportName) { 2336 return transports[transportName]; 2337 }).filter(function (t) { 2338 return !!t; 2339 }); 2340 } 2341 return _SocketWithUpgrade.call(this, uri, o) || this; 2342 } 2343 _inheritsLoose(Socket, _SocketWithUpgrade); 2344 return Socket; 2345 }(SocketWithUpgrade); 2346 2347 Socket$1.protocol; 2348 2349 function getDefaultExportFromCjs (x) { 2350 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 2351 } 2352 2353 var browser = {exports: {}}; 2354 2355 var ms; 2356 var hasRequiredMs; 2357 function requireMs() { 2358 if (hasRequiredMs) return ms; 2359 hasRequiredMs = 1; 2360 var s = 1000; 2361 var m = s * 60; 2362 var h = m * 60; 2363 var d = h * 24; 2364 var w = d * 7; 2365 var y = d * 365.25; 2366 2367 /** 2368 * Parse or format the given `val`. 2369 * 2370 * Options: 2371 * 2372 * - `long` verbose formatting [false] 2373 * 2374 * @param {String|Number} val 2375 * @param {Object} [options] 2376 * @throws {Error} throw an error if val is not a non-empty string or a number 2377 * @return {String|Number} 2378 * @api public 2379 */ 2380 2381 ms = function ms(val, options) { 2382 options = options || {}; 2383 var type = _typeof(val); 2384 if (type === 'string' && val.length > 0) { 2385 return parse(val); 2386 } else if (type === 'number' && isFinite(val)) { 2387 return options["long"] ? fmtLong(val) : fmtShort(val); 2388 } 2389 throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); 2390 }; 2391 2392 /** 2393 * Parse the given `str` and return milliseconds. 2394 * 2395 * @param {String} str 2396 * @return {Number} 2397 * @api private 2398 */ 2399 2400 function parse(str) { 2401 str = String(str); 2402 if (str.length > 100) { 2403 return; 2404 } 2405 var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); 2406 if (!match) { 2407 return; 2408 } 2409 var n = parseFloat(match[1]); 2410 var type = (match[2] || 'ms').toLowerCase(); 2411 switch (type) { 2412 case 'years': 2413 case 'year': 2414 case 'yrs': 2415 case 'yr': 2416 case 'y': 2417 return n * y; 2418 case 'weeks': 2419 case 'week': 2420 case 'w': 2421 return n * w; 2422 case 'days': 2423 case 'day': 2424 case 'd': 2425 return n * d; 2426 case 'hours': 2427 case 'hour': 2428 case 'hrs': 2429 case 'hr': 2430 case 'h': 2431 return n * h; 2432 case 'minutes': 2433 case 'minute': 2434 case 'mins': 2435 case 'min': 2436 case 'm': 2437 return n * m; 2438 case 'seconds': 2439 case 'second': 2440 case 'secs': 2441 case 'sec': 2442 case 's': 2443 return n * s; 2444 case 'milliseconds': 2445 case 'millisecond': 2446 case 'msecs': 2447 case 'msec': 2448 case 'ms': 2449 return n; 2450 default: 2451 return undefined; 2452 } 2453 } 2454 2455 /** 2456 * Short format for `ms`. 2457 * 2458 * @param {Number} ms 2459 * @return {String} 2460 * @api private 2461 */ 2462 2463 function fmtShort(ms) { 2464 var msAbs = Math.abs(ms); 2465 if (msAbs >= d) { 2466 return Math.round(ms / d) + 'd'; 2467 } 2468 if (msAbs >= h) { 2469 return Math.round(ms / h) + 'h'; 2470 } 2471 if (msAbs >= m) { 2472 return Math.round(ms / m) + 'm'; 2473 } 2474 if (msAbs >= s) { 2475 return Math.round(ms / s) + 's'; 2476 } 2477 return ms + 'ms'; 2478 } 2479 2480 /** 2481 * Long format for `ms`. 2482 * 2483 * @param {Number} ms 2484 * @return {String} 2485 * @api private 2486 */ 2487 2488 function fmtLong(ms) { 2489 var msAbs = Math.abs(ms); 2490 if (msAbs >= d) { 2491 return plural(ms, msAbs, d, 'day'); 2492 } 2493 if (msAbs >= h) { 2494 return plural(ms, msAbs, h, 'hour'); 2495 } 2496 if (msAbs >= m) { 2497 return plural(ms, msAbs, m, 'minute'); 2498 } 2499 if (msAbs >= s) { 2500 return plural(ms, msAbs, s, 'second'); 2501 } 2502 return ms + ' ms'; 2503 } 2504 2505 /** 2506 * Pluralization helper. 2507 */ 2508 2509 function plural(ms, msAbs, n, name) { 2510 var isPlural = msAbs >= n * 1.5; 2511 return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); 2512 } 2513 return ms; 2514 } 2515 2516 /** 2517 * This is the common logic for both the Node.js and web browser 2518 * implementations of `debug()`. 2519 */ 2520 2521 function setup(env) { 2522 createDebug.debug = createDebug; 2523 createDebug["default"] = createDebug; 2524 createDebug.coerce = coerce; 2525 createDebug.disable = disable; 2526 createDebug.enable = enable; 2527 createDebug.enabled = enabled; 2528 createDebug.humanize = requireMs(); 2529 createDebug.destroy = destroy; 2530 Object.keys(env).forEach(function (key) { 2531 createDebug[key] = env[key]; 2532 }); 2533 2534 /** 2535 * The currently active debug mode names, and names to skip. 2536 */ 2537 2538 createDebug.names = []; 2539 createDebug.skips = []; 2540 2541 /** 2542 * Map of special "%n" handling functions, for the debug "format" argument. 2543 * 2544 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". 2545 */ 2546 createDebug.formatters = {}; 2547 2548 /** 2549 * Selects a color for a debug namespace 2550 * @param {String} namespace The namespace string for the debug instance to be colored 2551 * @return {Number|String} An ANSI color code for the given namespace 2552 * @api private 2553 */ 2554 function selectColor(namespace) { 2555 var hash = 0; 2556 for (var i = 0; i < namespace.length; i++) { 2557 hash = (hash << 5) - hash + namespace.charCodeAt(i); 2558 hash |= 0; // Convert to 32bit integer 2559 } 2560 return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; 2561 } 2562 createDebug.selectColor = selectColor; 2563 2564 /** 2565 * Create a debugger with the given `namespace`. 2566 * 2567 * @param {String} namespace 2568 * @return {Function} 2569 * @api public 2570 */ 2571 function createDebug(namespace) { 2572 var prevTime; 2573 var enableOverride = null; 2574 var namespacesCache; 2575 var enabledCache; 2576 function debug() { 2577 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 2578 args[_key] = arguments[_key]; 2579 } 2580 // Disabled? 2581 if (!debug.enabled) { 2582 return; 2583 } 2584 var self = debug; 2585 2586 // Set `diff` timestamp 2587 var curr = Number(new Date()); 2588 var ms = curr - (prevTime || curr); 2589 self.diff = ms; 2590 self.prev = prevTime; 2591 self.curr = curr; 2592 prevTime = curr; 2593 args[0] = createDebug.coerce(args[0]); 2594 if (typeof args[0] !== 'string') { 2595 // Anything else let's inspect with %O 2596 args.unshift('%O'); 2597 } 2598 2599 // Apply any `formatters` transformations 2600 var index = 0; 2601 args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { 2602 // If we encounter an escaped % then don't increase the array index 2603 if (match === '%%') { 2604 return '%'; 2605 } 2606 index++; 2607 var formatter = createDebug.formatters[format]; 2608 if (typeof formatter === 'function') { 2609 var val = args[index]; 2610 match = formatter.call(self, val); 2611 2612 // Now we need to remove `args[index]` since it's inlined in the `format` 2613 args.splice(index, 1); 2614 index--; 2615 } 2616 return match; 2617 }); 2618 2619 // Apply env-specific formatting (colors, etc.) 2620 createDebug.formatArgs.call(self, args); 2621 var logFn = self.log || createDebug.log; 2622 logFn.apply(self, args); 2623 } 2624 debug.namespace = namespace; 2625 debug.useColors = createDebug.useColors(); 2626 debug.color = createDebug.selectColor(namespace); 2627 debug.extend = extend; 2628 debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. 2629 2630 Object.defineProperty(debug, 'enabled', { 2631 enumerable: true, 2632 configurable: false, 2633 get: function get() { 2634 if (enableOverride !== null) { 2635 return enableOverride; 2636 } 2637 if (namespacesCache !== createDebug.namespaces) { 2638 namespacesCache = createDebug.namespaces; 2639 enabledCache = createDebug.enabled(namespace); 2640 } 2641 return enabledCache; 2642 }, 2643 set: function set(v) { 2644 enableOverride = v; 2645 } 2646 }); 2647 2648 // Env-specific initialization logic for debug instances 2649 if (typeof createDebug.init === 'function') { 2650 createDebug.init(debug); 2651 } 2652 return debug; 2653 } 2654 function extend(namespace, delimiter) { 2655 var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); 2656 newDebug.log = this.log; 2657 return newDebug; 2658 } 2659 2660 /** 2661 * Enables a debug mode by namespaces. This can include modes 2662 * separated by a colon and wildcards. 2663 * 2664 * @param {String} namespaces 2665 * @api public 2666 */ 2667 function enable(namespaces) { 2668 createDebug.save(namespaces); 2669 createDebug.namespaces = namespaces; 2670 createDebug.names = []; 2671 createDebug.skips = []; 2672 var split = (typeof namespaces === 'string' ? namespaces : '').trim().replace(/\s+/g, ',').split(',').filter(Boolean); 2673 var _iterator = _createForOfIteratorHelper(split), 2674 _step; 2675 try { 2676 for (_iterator.s(); !(_step = _iterator.n()).done;) { 2677 var ns = _step.value; 2678 if (ns[0] === '-') { 2679 createDebug.skips.push(ns.slice(1)); 2680 } else { 2681 createDebug.names.push(ns); 2682 } 2683 } 2684 } catch (err) { 2685 _iterator.e(err); 2686 } finally { 2687 _iterator.f(); 2688 } 2689 } 2690 2691 /** 2692 * Checks if the given string matches a namespace template, honoring 2693 * asterisks as wildcards. 2694 * 2695 * @param {String} search 2696 * @param {String} template 2697 * @return {Boolean} 2698 */ 2699 function matchesTemplate(search, template) { 2700 var searchIndex = 0; 2701 var templateIndex = 0; 2702 var starIndex = -1; 2703 var matchIndex = 0; 2704 while (searchIndex < search.length) { 2705 if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { 2706 // Match character or proceed with wildcard 2707 if (template[templateIndex] === '*') { 2708 starIndex = templateIndex; 2709 matchIndex = searchIndex; 2710 templateIndex++; // Skip the '*' 2711 } else { 2712 searchIndex++; 2713 templateIndex++; 2714 } 2715 } else if (starIndex !== -1) { 2716 // eslint-disable-line no-negated-condition 2717 // Backtrack to the last '*' and try to match more characters 2718 templateIndex = starIndex + 1; 2719 matchIndex++; 2720 searchIndex = matchIndex; 2721 } else { 2722 return false; // No match 2723 } 2724 } 2725 2726 // Handle trailing '*' in template 2727 while (templateIndex < template.length && template[templateIndex] === '*') { 2728 templateIndex++; 2729 } 2730 return templateIndex === template.length; 2731 } 2732 2733 /** 2734 * Disable debug output. 2735 * 2736 * @return {String} namespaces 2737 * @api public 2738 */ 2739 function disable() { 2740 var namespaces = [].concat(_toConsumableArray(createDebug.names), _toConsumableArray(createDebug.skips.map(function (namespace) { 2741 return '-' + namespace; 2742 }))).join(','); 2743 createDebug.enable(''); 2744 return namespaces; 2745 } 2746 2747 /** 2748 * Returns true if the given mode name is enabled, false otherwise. 2749 * 2750 * @param {String} name 2751 * @return {Boolean} 2752 * @api public 2753 */ 2754 function enabled(name) { 2755 var _iterator2 = _createForOfIteratorHelper(createDebug.skips), 2756 _step2; 2757 try { 2758 for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { 2759 var skip = _step2.value; 2760 if (matchesTemplate(name, skip)) { 2761 return false; 2762 } 2763 } 2764 } catch (err) { 2765 _iterator2.e(err); 2766 } finally { 2767 _iterator2.f(); 2768 } 2769 var _iterator3 = _createForOfIteratorHelper(createDebug.names), 2770 _step3; 2771 try { 2772 for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { 2773 var ns = _step3.value; 2774 if (matchesTemplate(name, ns)) { 2775 return true; 2776 } 2777 } 2778 } catch (err) { 2779 _iterator3.e(err); 2780 } finally { 2781 _iterator3.f(); 2782 } 2783 return false; 2784 } 2785 2786 /** 2787 * Coerce `val`. 2788 * 2789 * @param {Mixed} val 2790 * @return {Mixed} 2791 * @api private 2792 */ 2793 function coerce(val) { 2794 if (val instanceof Error) { 2795 return val.stack || val.message; 2796 } 2797 return val; 2798 } 2799 2800 /** 2801 * XXX DO NOT USE. This is a temporary stub function. 2802 * XXX It WILL be removed in the next major release. 2803 */ 2804 function destroy() { 2805 console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); 2806 } 2807 createDebug.enable(createDebug.load()); 2808 return createDebug; 2809 } 2810 var common = setup; 2811 2812 /* eslint-env browser */ 2813 browser.exports; 2814 (function (module, exports) { 2815 /** 2816 * This is the web browser implementation of `debug()`. 2817 */ 2818 2819 exports.formatArgs = formatArgs; 2820 exports.save = save; 2821 exports.load = load; 2822 exports.useColors = useColors; 2823 exports.storage = localstorage(); 2824 exports.destroy = function () { 2825 var warned = false; 2826 return function () { 2827 if (!warned) { 2828 warned = true; 2829 console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); 2830 } 2831 }; 2832 }(); 2833 2834 /** 2835 * Colors. 2836 */ 2837 2838 exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; 2839 2840 /** 2841 * Currently only WebKit-based Web Inspectors, Firefox >= v31, 2842 * and the Firebug extension (any Firefox version) are known 2843 * to support "%c" CSS customizations. 2844 * 2845 * TODO: add a `localStorage` variable to explicitly enable/disable colors 2846 */ 2847 2848 // eslint-disable-next-line complexity 2849 function useColors() { 2850 // NB: In an Electron preload script, document will be defined but not fully 2851 // initialized. Since we know we're in Chrome, we'll just detect this case 2852 // explicitly 2853 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { 2854 return true; 2855 } 2856 2857 // Internet Explorer and Edge do not support colors. 2858 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { 2859 return false; 2860 } 2861 var m; 2862 2863 // Is webkit? http://stackoverflow.com/a/16459606/376773 2864 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 2865 // eslint-disable-next-line no-return-assign 2866 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || 2867 // Is firebug? http://stackoverflow.com/a/398120/376773 2868 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || 2869 // Is firefox >= v31? 2870 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages 2871 typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || 2872 // Double check webkit in userAgent just in case we are in a worker 2873 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); 2874 } 2875 2876 /** 2877 * Colorize log arguments if enabled. 2878 * 2879 * @api public 2880 */ 2881 2882 function formatArgs(args) { 2883 args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); 2884 if (!this.useColors) { 2885 return; 2886 } 2887 var c = 'color: ' + this.color; 2888 args.splice(1, 0, c, 'color: inherit'); 2889 2890 // The final "%c" is somewhat tricky, because there could be other 2891 // arguments passed either before or after the %c, so we need to 2892 // figure out the correct index to insert the CSS into 2893 var index = 0; 2894 var lastC = 0; 2895 args[0].replace(/%[a-zA-Z%]/g, function (match) { 2896 if (match === '%%') { 2897 return; 2898 } 2899 index++; 2900 if (match === '%c') { 2901 // We only are interested in the *last* %c 2902 // (the user may have provided their own) 2903 lastC = index; 2904 } 2905 }); 2906 args.splice(lastC, 0, c); 2907 } 2908 2909 /** 2910 * Invokes `console.debug()` when available. 2911 * No-op when `console.debug` is not a "function". 2912 * If `console.debug` is not available, falls back 2913 * to `console.log`. 2914 * 2915 * @api public 2916 */ 2917 exports.log = console.debug || console.log || function () {}; 2918 2919 /** 2920 * Save `namespaces`. 2921 * 2922 * @param {String} namespaces 2923 * @api private 2924 */ 2925 function save(namespaces) { 2926 try { 2927 if (namespaces) { 2928 exports.storage.setItem('debug', namespaces); 2929 } else { 2930 exports.storage.removeItem('debug'); 2931 } 2932 } catch (error) { 2933 // Swallow 2934 // XXX (@Qix-) should we be logging these? 2935 } 2936 } 2937 2938 /** 2939 * Load `namespaces`. 2940 * 2941 * @return {String} returns the previously persisted debug modes 2942 * @api private 2943 */ 2944 function load() { 2945 var r; 2946 try { 2947 r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG'); 2948 } catch (error) { 2949 // Swallow 2950 // XXX (@Qix-) should we be logging these? 2951 } 2952 2953 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG 2954 if (!r && typeof process !== 'undefined' && 'env' in process) { 2955 r = process.env.DEBUG; 2956 } 2957 return r; 2958 } 2959 2960 /** 2961 * Localstorage attempts to return the localstorage. 2962 * 2963 * This is necessary because safari throws 2964 * when a user disables cookies/localstorage 2965 * and you attempt to access it. 2966 * 2967 * @return {LocalStorage} 2968 * @api private 2969 */ 2970 2971 function localstorage() { 2972 try { 2973 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context 2974 // The Browser also has localStorage in the global context. 2975 return localStorage; 2976 } catch (error) { 2977 // Swallow 2978 // XXX (@Qix-) should we be logging these? 2979 } 2980 } 2981 module.exports = common(exports); 2982 var formatters = module.exports.formatters; 2983 2984 /** 2985 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. 2986 */ 2987 2988 formatters.j = function (v) { 2989 try { 2990 return JSON.stringify(v); 2991 } catch (error) { 2992 return '[UnexpectedJSONParseError]: ' + error.message; 2993 } 2994 }; 2995 })(browser, browser.exports); 2996 var browserExports = browser.exports; 2997 var debugModule = /*@__PURE__*/getDefaultExportFromCjs(browserExports); 2998 2999 var debug$3 = debugModule("socket.io-client:url"); // debug() 3000 /** 3001 * URL parser. 3002 * 3003 * @param uri - url 3004 * @param path - the request path of the connection 3005 * @param loc - An object meant to mimic window.location. 3006 * Defaults to window.location. 3007 * @public 3008 */ 3009 function url(uri) { 3010 var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; 3011 var loc = arguments.length > 2 ? arguments[2] : undefined; 3012 var obj = uri; 3013 // default to window.location 3014 loc = loc || typeof location !== "undefined" && location; 3015 if (null == uri) uri = loc.protocol + "//" + loc.host; 3016 // relative path support 3017 if (typeof uri === "string") { 3018 if ("/" === uri.charAt(0)) { 3019 if ("/" === uri.charAt(1)) { 3020 uri = loc.protocol + uri; 3021 } else { 3022 uri = loc.host + uri; 3023 } 3024 } 3025 if (!/^(https?|wss?):\/\//.test(uri)) { 3026 debug$3("protocol-less url %s", uri); 3027 if ("undefined" !== typeof loc) { 3028 uri = loc.protocol + "//" + uri; 3029 } else { 3030 uri = "https://" + uri; 3031 } 3032 } 3033 // parse 3034 debug$3("parse %s", uri); 3035 obj = parse(uri); 3036 } 3037 // make sure we treat `localhost:80` and `localhost` equally 3038 if (!obj.port) { 3039 if (/^(http|ws)$/.test(obj.protocol)) { 3040 obj.port = "80"; 3041 } else if (/^(http|ws)s$/.test(obj.protocol)) { 3042 obj.port = "443"; 3043 } 3044 } 3045 obj.path = obj.path || "/"; 3046 var ipv6 = obj.host.indexOf(":") !== -1; 3047 var host = ipv6 ? "[" + obj.host + "]" : obj.host; 3048 // define unique id 3049 obj.id = obj.protocol + "://" + host + ":" + obj.port + path; 3050 // define href 3051 obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port); 3052 return obj; 3053 } 3054 3055 var withNativeArrayBuffer = typeof ArrayBuffer === "function"; 3056 var isView = function isView(obj) { 3057 return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer; 3058 }; 3059 var toString = Object.prototype.toString; 3060 var withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && toString.call(Blob) === "[object BlobConstructor]"; 3061 var withNativeFile = typeof File === "function" || typeof File !== "undefined" && toString.call(File) === "[object FileConstructor]"; 3062 /** 3063 * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File. 3064 * 3065 * @private 3066 */ 3067 function isBinary(obj) { 3068 return withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)) || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File; 3069 } 3070 function hasBinary(obj, toJSON) { 3071 if (!obj || _typeof(obj) !== "object") { 3072 return false; 3073 } 3074 if (Array.isArray(obj)) { 3075 for (var i = 0, l = obj.length; i < l; i++) { 3076 if (hasBinary(obj[i])) { 3077 return true; 3078 } 3079 } 3080 return false; 3081 } 3082 if (isBinary(obj)) { 3083 return true; 3084 } 3085 if (obj.toJSON && typeof obj.toJSON === "function" && arguments.length === 1) { 3086 return hasBinary(obj.toJSON(), true); 3087 } 3088 for (var key in obj) { 3089 if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { 3090 return true; 3091 } 3092 } 3093 return false; 3094 } 3095 3096 /** 3097 * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder. 3098 * 3099 * @param {Object} packet - socket.io event packet 3100 * @return {Object} with deconstructed packet and list of buffers 3101 * @public 3102 */ 3103 function deconstructPacket(packet) { 3104 var buffers = []; 3105 var packetData = packet.data; 3106 var pack = packet; 3107 pack.data = _deconstructPacket(packetData, buffers); 3108 pack.attachments = buffers.length; // number of binary 'attachments' 3109 return { 3110 packet: pack, 3111 buffers: buffers 3112 }; 3113 } 3114 function _deconstructPacket(data, buffers) { 3115 if (!data) return data; 3116 if (isBinary(data)) { 3117 var placeholder = { 3118 _placeholder: true, 3119 num: buffers.length 3120 }; 3121 buffers.push(data); 3122 return placeholder; 3123 } else if (Array.isArray(data)) { 3124 var newData = new Array(data.length); 3125 for (var i = 0; i < data.length; i++) { 3126 newData[i] = _deconstructPacket(data[i], buffers); 3127 } 3128 return newData; 3129 } else if (_typeof(data) === "object" && !(data instanceof Date)) { 3130 var _newData = {}; 3131 for (var key in data) { 3132 if (Object.prototype.hasOwnProperty.call(data, key)) { 3133 _newData[key] = _deconstructPacket(data[key], buffers); 3134 } 3135 } 3136 return _newData; 3137 } 3138 return data; 3139 } 3140 /** 3141 * Reconstructs a binary packet from its placeholder packet and buffers 3142 * 3143 * @param {Object} packet - event packet with placeholders 3144 * @param {Array} buffers - binary buffers to put in placeholder positions 3145 * @return {Object} reconstructed packet 3146 * @public 3147 */ 3148 function reconstructPacket(packet, buffers) { 3149 packet.data = _reconstructPacket(packet.data, buffers); 3150 delete packet.attachments; // no longer useful 3151 return packet; 3152 } 3153 function _reconstructPacket(data, buffers) { 3154 if (!data) return data; 3155 if (data && data._placeholder === true) { 3156 var isIndexValid = typeof data.num === "number" && data.num >= 0 && data.num < buffers.length; 3157 if (isIndexValid) { 3158 return buffers[data.num]; // appropriate buffer (should be natural order anyway) 3159 } else { 3160 throw new Error("illegal attachments"); 3161 } 3162 } else if (Array.isArray(data)) { 3163 for (var i = 0; i < data.length; i++) { 3164 data[i] = _reconstructPacket(data[i], buffers); 3165 } 3166 } else if (_typeof(data) === "object") { 3167 for (var key in data) { 3168 if (Object.prototype.hasOwnProperty.call(data, key)) { 3169 data[key] = _reconstructPacket(data[key], buffers); 3170 } 3171 } 3172 } 3173 return data; 3174 } 3175 3176 /** 3177 * These strings must not be used as event names, as they have a special meaning. 3178 */ 3179 var RESERVED_EVENTS$1 = ["connect", 3180 // used on the client side 3181 "connect_error", 3182 // used on the client side 3183 "disconnect", 3184 // used on both sides 3185 "disconnecting", 3186 // used on the server side 3187 "newListener", 3188 // used by the Node.js EventEmitter 3189 "removeListener" // used by the Node.js EventEmitter 3190 ]; 3191 /** 3192 * Protocol version. 3193 * 3194 * @public 3195 */ 3196 var protocol = 5; 3197 var PacketType; 3198 (function (PacketType) { 3199 PacketType[PacketType["CONNECT"] = 0] = "CONNECT"; 3200 PacketType[PacketType["DISCONNECT"] = 1] = "DISCONNECT"; 3201 PacketType[PacketType["EVENT"] = 2] = "EVENT"; 3202 PacketType[PacketType["ACK"] = 3] = "ACK"; 3203 PacketType[PacketType["CONNECT_ERROR"] = 4] = "CONNECT_ERROR"; 3204 PacketType[PacketType["BINARY_EVENT"] = 5] = "BINARY_EVENT"; 3205 PacketType[PacketType["BINARY_ACK"] = 6] = "BINARY_ACK"; 3206 })(PacketType || (PacketType = {})); 3207 /** 3208 * A socket.io Encoder instance 3209 */ 3210 var Encoder = /*#__PURE__*/function () { 3211 /** 3212 * Encoder constructor 3213 * 3214 * @param {function} replacer - custom replacer to pass down to JSON.parse 3215 */ 3216 function Encoder(replacer) { 3217 this.replacer = replacer; 3218 } 3219 /** 3220 * Encode a packet as a single string if non-binary, or as a 3221 * buffer sequence, depending on packet type. 3222 * 3223 * @param {Object} obj - packet object 3224 */ 3225 var _proto = Encoder.prototype; 3226 _proto.encode = function encode(obj) { 3227 if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) { 3228 if (hasBinary(obj)) { 3229 return this.encodeAsBinary({ 3230 type: obj.type === PacketType.EVENT ? PacketType.BINARY_EVENT : PacketType.BINARY_ACK, 3231 nsp: obj.nsp, 3232 data: obj.data, 3233 id: obj.id 3234 }); 3235 } 3236 } 3237 return [this.encodeAsString(obj)]; 3238 } 3239 /** 3240 * Encode packet as string. 3241 */; 3242 _proto.encodeAsString = function encodeAsString(obj) { 3243 // first is type 3244 var str = "" + obj.type; 3245 // attachments if we have them 3246 if (obj.type === PacketType.BINARY_EVENT || obj.type === PacketType.BINARY_ACK) { 3247 str += obj.attachments + "-"; 3248 } 3249 // if we have a namespace other than `/` 3250 // we append it followed by a comma `,` 3251 if (obj.nsp && "/" !== obj.nsp) { 3252 str += obj.nsp + ","; 3253 } 3254 // immediately followed by the id 3255 if (null != obj.id) { 3256 str += obj.id; 3257 } 3258 // json data 3259 if (null != obj.data) { 3260 str += JSON.stringify(obj.data, this.replacer); 3261 } 3262 return str; 3263 } 3264 /** 3265 * Encode packet as 'buffer sequence' by removing blobs, and 3266 * deconstructing packet into object with placeholders and 3267 * a list of buffers. 3268 */; 3269 _proto.encodeAsBinary = function encodeAsBinary(obj) { 3270 var deconstruction = deconstructPacket(obj); 3271 var pack = this.encodeAsString(deconstruction.packet); 3272 var buffers = deconstruction.buffers; 3273 buffers.unshift(pack); // add packet info to beginning of data list 3274 return buffers; // write all the buffers 3275 }; 3276 return Encoder; 3277 }(); 3278 /** 3279 * A socket.io Decoder instance 3280 * 3281 * @return {Object} decoder 3282 */ 3283 var Decoder = /*#__PURE__*/function (_Emitter) { 3284 /** 3285 * Decoder constructor 3286 * 3287 * @param {function} reviver - custom reviver to pass down to JSON.stringify 3288 */ 3289 function Decoder(reviver) { 3290 var _this; 3291 _this = _Emitter.call(this) || this; 3292 _this.reviver = reviver; 3293 return _this; 3294 } 3295 /** 3296 * Decodes an encoded packet string into packet JSON. 3297 * 3298 * @param {String} obj - encoded packet 3299 */ 3300 _inheritsLoose(Decoder, _Emitter); 3301 var _proto2 = Decoder.prototype; 3302 _proto2.add = function add(obj) { 3303 var packet; 3304 if (typeof obj === "string") { 3305 if (this.reconstructor) { 3306 throw new Error("got plaintext data when reconstructing a packet"); 3307 } 3308 packet = this.decodeString(obj); 3309 var isBinaryEvent = packet.type === PacketType.BINARY_EVENT; 3310 if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) { 3311 packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK; 3312 // binary packet's json 3313 this.reconstructor = new BinaryReconstructor(packet); 3314 // no attachments, labeled binary but no binary data to follow 3315 if (packet.attachments === 0) { 3316 _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3317 } 3318 } else { 3319 // non-binary full packet 3320 _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3321 } 3322 } else if (isBinary(obj) || obj.base64) { 3323 // raw binary data 3324 if (!this.reconstructor) { 3325 throw new Error("got binary data when not reconstructing a packet"); 3326 } else { 3327 packet = this.reconstructor.takeBinaryData(obj); 3328 if (packet) { 3329 // received final buffer 3330 this.reconstructor = null; 3331 _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3332 } 3333 } 3334 } else { 3335 throw new Error("Unknown type: " + obj); 3336 } 3337 } 3338 /** 3339 * Decode a packet String (JSON data) 3340 * 3341 * @param {String} str 3342 * @return {Object} packet 3343 */; 3344 _proto2.decodeString = function decodeString(str) { 3345 var i = 0; 3346 // look up type 3347 var p = { 3348 type: Number(str.charAt(0)) 3349 }; 3350 if (PacketType[p.type] === undefined) { 3351 throw new Error("unknown packet type " + p.type); 3352 } 3353 // look up attachments if type binary 3354 if (p.type === PacketType.BINARY_EVENT || p.type === PacketType.BINARY_ACK) { 3355 var start = i + 1; 3356 while (str.charAt(++i) !== "-" && i != str.length) {} 3357 var buf = str.substring(start, i); 3358 if (buf != Number(buf) || str.charAt(i) !== "-") { 3359 throw new Error("Illegal attachments"); 3360 } 3361 p.attachments = Number(buf); 3362 } 3363 // look up namespace (if any) 3364 if ("/" === str.charAt(i + 1)) { 3365 var _start = i + 1; 3366 while (++i) { 3367 var c = str.charAt(i); 3368 if ("," === c) break; 3369 if (i === str.length) break; 3370 } 3371 p.nsp = str.substring(_start, i); 3372 } else { 3373 p.nsp = "/"; 3374 } 3375 // look up id 3376 var next = str.charAt(i + 1); 3377 if ("" !== next && Number(next) == next) { 3378 var _start2 = i + 1; 3379 while (++i) { 3380 var _c = str.charAt(i); 3381 if (null == _c || Number(_c) != _c) { 3382 --i; 3383 break; 3384 } 3385 if (i === str.length) break; 3386 } 3387 p.id = Number(str.substring(_start2, i + 1)); 3388 } 3389 // look up json data 3390 if (str.charAt(++i)) { 3391 var payload = this.tryParse(str.substr(i)); 3392 if (Decoder.isPayloadValid(p.type, payload)) { 3393 p.data = payload; 3394 } else { 3395 throw new Error("invalid payload"); 3396 } 3397 } 3398 return p; 3399 }; 3400 _proto2.tryParse = function tryParse(str) { 3401 try { 3402 return JSON.parse(str, this.reviver); 3403 } catch (e) { 3404 return false; 3405 } 3406 }; 3407 Decoder.isPayloadValid = function isPayloadValid(type, payload) { 3408 switch (type) { 3409 case PacketType.CONNECT: 3410 return isObject(payload); 3411 case PacketType.DISCONNECT: 3412 return payload === undefined; 3413 case PacketType.CONNECT_ERROR: 3414 return typeof payload === "string" || isObject(payload); 3415 case PacketType.EVENT: 3416 case PacketType.BINARY_EVENT: 3417 return Array.isArray(payload) && (typeof payload[0] === "number" || typeof payload[0] === "string" && RESERVED_EVENTS$1.indexOf(payload[0]) === -1); 3418 case PacketType.ACK: 3419 case PacketType.BINARY_ACK: 3420 return Array.isArray(payload); 3421 } 3422 } 3423 /** 3424 * Deallocates a parser's resources 3425 */; 3426 _proto2.destroy = function destroy() { 3427 if (this.reconstructor) { 3428 this.reconstructor.finishedReconstruction(); 3429 this.reconstructor = null; 3430 } 3431 }; 3432 return Decoder; 3433 }(Emitter); 3434 /** 3435 * A manager of a binary event's 'buffer sequence'. Should 3436 * be constructed whenever a packet of type BINARY_EVENT is 3437 * decoded. 3438 * 3439 * @param {Object} packet 3440 * @return {BinaryReconstructor} initialized reconstructor 3441 */ 3442 var BinaryReconstructor = /*#__PURE__*/function () { 3443 function BinaryReconstructor(packet) { 3444 this.packet = packet; 3445 this.buffers = []; 3446 this.reconPack = packet; 3447 } 3448 /** 3449 * Method to be called when binary data received from connection 3450 * after a BINARY_EVENT packet. 3451 * 3452 * @param {Buffer | ArrayBuffer} binData - the raw binary data received 3453 * @return {null | Object} returns null if more binary data is expected or 3454 * a reconstructed packet object if all buffers have been received. 3455 */ 3456 var _proto3 = BinaryReconstructor.prototype; 3457 _proto3.takeBinaryData = function takeBinaryData(binData) { 3458 this.buffers.push(binData); 3459 if (this.buffers.length === this.reconPack.attachments) { 3460 // done with buffer list 3461 var packet = reconstructPacket(this.reconPack, this.buffers); 3462 this.finishedReconstruction(); 3463 return packet; 3464 } 3465 return null; 3466 } 3467 /** 3468 * Cleans up binary packet reconstruction variables. 3469 */; 3470 _proto3.finishedReconstruction = function finishedReconstruction() { 3471 this.reconPack = null; 3472 this.buffers = []; 3473 }; 3474 return BinaryReconstructor; 3475 }(); 3476 function isNamespaceValid(nsp) { 3477 return typeof nsp === "string"; 3478 } 3479 // see https://caniuse.com/mdn-javascript_builtins_number_isinteger 3480 var isInteger = Number.isInteger || function (value) { 3481 return typeof value === "number" && isFinite(value) && Math.floor(value) === value; 3482 }; 3483 function isAckIdValid(id) { 3484 return id === undefined || isInteger(id); 3485 } 3486 // see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript 3487 function isObject(value) { 3488 return Object.prototype.toString.call(value) === "[object Object]"; 3489 } 3490 function isDataValid(type, payload) { 3491 switch (type) { 3492 case PacketType.CONNECT: 3493 return payload === undefined || isObject(payload); 3494 case PacketType.DISCONNECT: 3495 return payload === undefined; 3496 case PacketType.EVENT: 3497 return Array.isArray(payload) && (typeof payload[0] === "number" || typeof payload[0] === "string" && RESERVED_EVENTS$1.indexOf(payload[0]) === -1); 3498 case PacketType.ACK: 3499 return Array.isArray(payload); 3500 case PacketType.CONNECT_ERROR: 3501 return typeof payload === "string" || isObject(payload); 3502 default: 3503 return false; 3504 } 3505 } 3506 function isPacketValid(packet) { 3507 return isNamespaceValid(packet.nsp) && isAckIdValid(packet.id) && isDataValid(packet.type, packet.data); 3508 } 3509 3510 var parser = /*#__PURE__*/Object.freeze({ 3511 __proto__: null, 3512 protocol: protocol, 3513 get PacketType () { return PacketType; }, 3514 Encoder: Encoder, 3515 Decoder: Decoder, 3516 isPacketValid: isPacketValid 3517 }); 3518 3519 function on(obj, ev, fn) { 3520 obj.on(ev, fn); 3521 return function subDestroy() { 3522 obj.off(ev, fn); 3523 }; 3524 } 3525 3526 var debug$2 = debugModule("socket.io-client:socket"); // debug() 3527 /** 3528 * Internal events. 3529 * These events can't be emitted by the user. 3530 */ 3531 var RESERVED_EVENTS = Object.freeze({ 3532 connect: 1, 3533 connect_error: 1, 3534 disconnect: 1, 3535 disconnecting: 1, 3536 // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener 3537 newListener: 1, 3538 removeListener: 1 3539 }); 3540 /** 3541 * A Socket is the fundamental class for interacting with the server. 3542 * 3543 * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate. 3544 * 3545 * @example 3546 * const socket = io(); 3547 * 3548 * socket.on("connect", () => { 3549 * console.log("connected"); 3550 * }); 3551 * 3552 * // send an event to the server 3553 * socket.emit("foo", "bar"); 3554 * 3555 * socket.on("foobar", () => { 3556 * // an event was received from the server 3557 * }); 3558 * 3559 * // upon disconnection 3560 * socket.on("disconnect", (reason) => { 3561 * console.log(`disconnected due to ${reason}`); 3562 * }); 3563 */ 3564 var Socket = /*#__PURE__*/function (_Emitter) { 3565 /** 3566 * `Socket` constructor. 3567 */ 3568 function Socket(io, nsp, opts) { 3569 var _this; 3570 _this = _Emitter.call(this) || this; 3571 /** 3572 * Whether the socket is currently connected to the server. 3573 * 3574 * @example 3575 * const socket = io(); 3576 * 3577 * socket.on("connect", () => { 3578 * console.log(socket.connected); // true 3579 * }); 3580 * 3581 * socket.on("disconnect", () => { 3582 * console.log(socket.connected); // false 3583 * }); 3584 */ 3585 _this.connected = false; 3586 /** 3587 * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will 3588 * be transmitted by the server. 3589 */ 3590 _this.recovered = false; 3591 /** 3592 * Buffer for packets received before the CONNECT packet 3593 */ 3594 _this.receiveBuffer = []; 3595 /** 3596 * Buffer for packets that will be sent once the socket is connected 3597 */ 3598 _this.sendBuffer = []; 3599 /** 3600 * The queue of packets to be sent with retry in case of failure. 3601 * 3602 * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order. 3603 * @private 3604 */ 3605 _this._queue = []; 3606 /** 3607 * A sequence to generate the ID of the {@link QueuedPacket}. 3608 * @private 3609 */ 3610 _this._queueSeq = 0; 3611 _this.ids = 0; 3612 /** 3613 * A map containing acknowledgement handlers. 3614 * 3615 * The `withError` attribute is used to differentiate handlers that accept an error as first argument: 3616 * 3617 * - `socket.emit("test", (err, value) => { ... })` with `ackTimeout` option 3618 * - `socket.timeout(5000).emit("test", (err, value) => { ... })` 3619 * - `const value = await socket.emitWithAck("test")` 3620 * 3621 * From those that don't: 3622 * 3623 * - `socket.emit("test", (value) => { ... });` 3624 * 3625 * In the first case, the handlers will be called with an error when: 3626 * 3627 * - the timeout is reached 3628 * - the socket gets disconnected 3629 * 3630 * In the second case, the handlers will be simply discarded upon disconnection, since the client will never receive 3631 * an acknowledgement from the server. 3632 * 3633 * @private 3634 */ 3635 _this.acks = {}; 3636 _this.flags = {}; 3637 _this.io = io; 3638 _this.nsp = nsp; 3639 if (opts && opts.auth) { 3640 _this.auth = opts.auth; 3641 } 3642 _this._opts = _extends({}, opts); 3643 if (_this.io._autoConnect) _this.open(); 3644 return _this; 3645 } 3646 /** 3647 * Whether the socket is currently disconnected 3648 * 3649 * @example 3650 * const socket = io(); 3651 * 3652 * socket.on("connect", () => { 3653 * console.log(socket.disconnected); // false 3654 * }); 3655 * 3656 * socket.on("disconnect", () => { 3657 * console.log(socket.disconnected); // true 3658 * }); 3659 */ 3660 _inheritsLoose(Socket, _Emitter); 3661 var _proto = Socket.prototype; 3662 /** 3663 * Subscribe to open, close and packet events 3664 * 3665 * @private 3666 */ 3667 _proto.subEvents = function subEvents() { 3668 if (this.subs) return; 3669 var io = this.io; 3670 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))]; 3671 } 3672 /** 3673 * Whether the Socket will try to reconnect when its Manager connects or reconnects. 3674 * 3675 * @example 3676 * const socket = io(); 3677 * 3678 * console.log(socket.active); // true 3679 * 3680 * socket.on("disconnect", (reason) => { 3681 * if (reason === "io server disconnect") { 3682 * // the disconnection was initiated by the server, you need to manually reconnect 3683 * console.log(socket.active); // false 3684 * } 3685 * // else the socket will automatically try to reconnect 3686 * console.log(socket.active); // true 3687 * }); 3688 */; 3689 /** 3690 * "Opens" the socket. 3691 * 3692 * @example 3693 * const socket = io({ 3694 * autoConnect: false 3695 * }); 3696 * 3697 * socket.connect(); 3698 */ 3699 _proto.connect = function connect() { 3700 if (this.connected) return this; 3701 this.subEvents(); 3702 if (!this.io["_reconnecting"]) this.io.open(); // ensure open 3703 if ("open" === this.io._readyState) this.onopen(); 3704 return this; 3705 } 3706 /** 3707 * Alias for {@link connect()}. 3708 */; 3709 _proto.open = function open() { 3710 return this.connect(); 3711 } 3712 /** 3713 * Sends a `message` event. 3714 * 3715 * This method mimics the WebSocket.send() method. 3716 * 3717 * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send 3718 * 3719 * @example 3720 * socket.send("hello"); 3721 * 3722 * // this is equivalent to 3723 * socket.emit("message", "hello"); 3724 * 3725 * @return self 3726 */; 3727 _proto.send = function send() { 3728 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3729 args[_key] = arguments[_key]; 3730 } 3731 args.unshift("message"); 3732 this.emit.apply(this, args); 3733 return this; 3734 } 3735 /** 3736 * Override `emit`. 3737 * If the event is in `events`, it's emitted normally. 3738 * 3739 * @example 3740 * socket.emit("hello", "world"); 3741 * 3742 * // all serializable datastructures are supported (no need to call JSON.stringify) 3743 * socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) }); 3744 * 3745 * // with an acknowledgement from the server 3746 * socket.emit("hello", "world", (val) => { 3747 * // ... 3748 * }); 3749 * 3750 * @return self 3751 */; 3752 _proto.emit = function emit(ev) { 3753 var _a, _b, _c; 3754 if (RESERVED_EVENTS.hasOwnProperty(ev)) { 3755 throw new Error('"' + ev.toString() + '" is a reserved event name'); 3756 } 3757 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 3758 args[_key2 - 1] = arguments[_key2]; 3759 } 3760 args.unshift(ev); 3761 if (this._opts.retries && !this.flags.fromQueue && !this.flags["volatile"]) { 3762 this._addToQueue(args); 3763 return this; 3764 } 3765 var packet = { 3766 type: PacketType.EVENT, 3767 data: args 3768 }; 3769 packet.options = {}; 3770 packet.options.compress = this.flags.compress !== false; 3771 // event ack callback 3772 if ("function" === typeof args[args.length - 1]) { 3773 var id = this.ids++; 3774 debug$2("emitting packet with ack id %d", id); 3775 var ack = args.pop(); 3776 this._registerAckCallback(id, ack); 3777 packet.id = id; 3778 } 3779 var isTransportWritable = (_b = (_a = this.io.engine) === null || _a === void 0 ? void 0 : _a.transport) === null || _b === void 0 ? void 0 : _b.writable; 3780 var isConnected = this.connected && !((_c = this.io.engine) === null || _c === void 0 ? void 0 : _c._hasPingExpired()); 3781 var discardPacket = this.flags["volatile"] && !isTransportWritable; 3782 if (discardPacket) { 3783 debug$2("discard packet as the transport is not currently writable"); 3784 } else if (isConnected) { 3785 this.notifyOutgoingListeners(packet); 3786 this.packet(packet); 3787 } else { 3788 this.sendBuffer.push(packet); 3789 } 3790 this.flags = {}; 3791 return this; 3792 } 3793 /** 3794 * @private 3795 */; 3796 _proto._registerAckCallback = function _registerAckCallback(id, ack) { 3797 var _this2 = this; 3798 var _a; 3799 var timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout; 3800 if (timeout === undefined) { 3801 this.acks[id] = ack; 3802 return; 3803 } 3804 // @ts-ignore 3805 var timer = this.io.setTimeoutFn(function () { 3806 delete _this2.acks[id]; 3807 for (var i = 0; i < _this2.sendBuffer.length; i++) { 3808 if (_this2.sendBuffer[i].id === id) { 3809 debug$2("removing packet with ack id %d from the buffer", id); 3810 _this2.sendBuffer.splice(i, 1); 3811 } 3812 } 3813 debug$2("event with ack id %d has timed out after %d ms", id, timeout); 3814 ack.call(_this2, new Error("operation has timed out")); 3815 }, timeout); 3816 var fn = function fn() { 3817 // @ts-ignore 3818 _this2.io.clearTimeoutFn(timer); 3819 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 3820 args[_key3] = arguments[_key3]; 3821 } 3822 ack.apply(_this2, args); 3823 }; 3824 fn.withError = true; 3825 this.acks[id] = fn; 3826 } 3827 /** 3828 * Emits an event and waits for an acknowledgement 3829 * 3830 * @example 3831 * // without timeout 3832 * const response = await socket.emitWithAck("hello", "world"); 3833 * 3834 * // with a specific timeout 3835 * try { 3836 * const response = await socket.timeout(1000).emitWithAck("hello", "world"); 3837 * } catch (err) { 3838 * // the server did not acknowledge the event in the given delay 3839 * } 3840 * 3841 * @return a Promise that will be fulfilled when the server acknowledges the event 3842 */; 3843 _proto.emitWithAck = function emitWithAck(ev) { 3844 var _this3 = this; 3845 for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { 3846 args[_key4 - 1] = arguments[_key4]; 3847 } 3848 return new Promise(function (resolve, reject) { 3849 var fn = function fn(arg1, arg2) { 3850 return arg1 ? reject(arg1) : resolve(arg2); 3851 }; 3852 fn.withError = true; 3853 args.push(fn); 3854 _this3.emit.apply(_this3, [ev].concat(args)); 3855 }); 3856 } 3857 /** 3858 * Add the packet to the queue. 3859 * @param args 3860 * @private 3861 */; 3862 _proto._addToQueue = function _addToQueue(args) { 3863 var _this4 = this; 3864 var ack; 3865 if (typeof args[args.length - 1] === "function") { 3866 ack = args.pop(); 3867 } 3868 var packet = { 3869 id: this._queueSeq++, 3870 tryCount: 0, 3871 pending: false, 3872 args: args, 3873 flags: _extends({ 3874 fromQueue: true 3875 }, this.flags) 3876 }; 3877 args.push(function (err) { 3878 if (packet !== _this4._queue[0]) { 3879 return debug$2("packet [%d] already acknowledged", packet.id); 3880 } 3881 var hasError = err !== null; 3882 if (hasError) { 3883 if (packet.tryCount > _this4._opts.retries) { 3884 debug$2("packet [%d] is discarded after %d tries", packet.id, packet.tryCount); 3885 _this4._queue.shift(); 3886 if (ack) { 3887 ack(err); 3888 } 3889 } 3890 } else { 3891 debug$2("packet [%d] was successfully sent", packet.id); 3892 _this4._queue.shift(); 3893 if (ack) { 3894 for (var _len5 = arguments.length, responseArgs = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { 3895 responseArgs[_key5 - 1] = arguments[_key5]; 3896 } 3897 ack.apply(void 0, [null].concat(responseArgs)); 3898 } 3899 } 3900 packet.pending = false; 3901 return _this4._drainQueue(); 3902 }); 3903 this._queue.push(packet); 3904 this._drainQueue(); 3905 } 3906 /** 3907 * Send the first packet of the queue, and wait for an acknowledgement from the server. 3908 * @param force - whether to resend a packet that has not been acknowledged yet 3909 * 3910 * @private 3911 */; 3912 _proto._drainQueue = function _drainQueue() { 3913 var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; 3914 debug$2("draining queue"); 3915 if (!this.connected || this._queue.length === 0) { 3916 return; 3917 } 3918 var packet = this._queue[0]; 3919 if (packet.pending && !force) { 3920 debug$2("packet [%d] has already been sent and is waiting for an ack", packet.id); 3921 return; 3922 } 3923 packet.pending = true; 3924 packet.tryCount++; 3925 debug$2("sending packet [%d] (try n°%d)", packet.id, packet.tryCount); 3926 this.flags = packet.flags; 3927 this.emit.apply(this, packet.args); 3928 } 3929 /** 3930 * Sends a packet. 3931 * 3932 * @param packet 3933 * @private 3934 */; 3935 _proto.packet = function packet(_packet) { 3936 _packet.nsp = this.nsp; 3937 this.io._packet(_packet); 3938 } 3939 /** 3940 * Called upon engine `open`. 3941 * 3942 * @private 3943 */; 3944 _proto.onopen = function onopen() { 3945 var _this5 = this; 3946 debug$2("transport is open - connecting"); 3947 if (typeof this.auth == "function") { 3948 this.auth(function (data) { 3949 _this5._sendConnectPacket(data); 3950 }); 3951 } else { 3952 this._sendConnectPacket(this.auth); 3953 } 3954 } 3955 /** 3956 * Sends a CONNECT packet to initiate the Socket.IO session. 3957 * 3958 * @param data 3959 * @private 3960 */; 3961 _proto._sendConnectPacket = function _sendConnectPacket(data) { 3962 this.packet({ 3963 type: PacketType.CONNECT, 3964 data: this._pid ? _extends({ 3965 pid: this._pid, 3966 offset: this._lastOffset 3967 }, data) : data 3968 }); 3969 } 3970 /** 3971 * Called upon engine or manager `error`. 3972 * 3973 * @param err 3974 * @private 3975 */; 3976 _proto.onerror = function onerror(err) { 3977 if (!this.connected) { 3978 this.emitReserved("connect_error", err); 3979 } 3980 } 3981 /** 3982 * Called upon engine `close`. 3983 * 3984 * @param reason 3985 * @param description 3986 * @private 3987 */; 3988 _proto.onclose = function onclose(reason, description) { 3989 debug$2("close (%s)", reason); 3990 this.connected = false; 3991 delete this.id; 3992 this.emitReserved("disconnect", reason, description); 3993 this._clearAcks(); 3994 } 3995 /** 3996 * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from 3997 * the server. 3998 * 3999 * @private 4000 */; 4001 _proto._clearAcks = function _clearAcks() { 4002 var _this6 = this; 4003 Object.keys(this.acks).forEach(function (id) { 4004 var isBuffered = _this6.sendBuffer.some(function (packet) { 4005 return String(packet.id) === id; 4006 }); 4007 if (!isBuffered) { 4008 // note: handlers that do not accept an error as first argument are ignored here 4009 var ack = _this6.acks[id]; 4010 delete _this6.acks[id]; 4011 if (ack.withError) { 4012 ack.call(_this6, new Error("socket has been disconnected")); 4013 } 4014 } 4015 }); 4016 } 4017 /** 4018 * Called with socket packet. 4019 * 4020 * @param packet 4021 * @private 4022 */; 4023 _proto.onpacket = function onpacket(packet) { 4024 var sameNamespace = packet.nsp === this.nsp; 4025 if (!sameNamespace) return; 4026 switch (packet.type) { 4027 case PacketType.CONNECT: 4028 if (packet.data && packet.data.sid) { 4029 this.onconnect(packet.data.sid, packet.data.pid); 4030 } else { 4031 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/)")); 4032 } 4033 break; 4034 case PacketType.EVENT: 4035 case PacketType.BINARY_EVENT: 4036 this.onevent(packet); 4037 break; 4038 case PacketType.ACK: 4039 case PacketType.BINARY_ACK: 4040 this.onack(packet); 4041 break; 4042 case PacketType.DISCONNECT: 4043 this.ondisconnect(); 4044 break; 4045 case PacketType.CONNECT_ERROR: 4046 this.destroy(); 4047 var err = new Error(packet.data.message); 4048 // @ts-ignore 4049 err.data = packet.data.data; 4050 this.emitReserved("connect_error", err); 4051 break; 4052 } 4053 } 4054 /** 4055 * Called upon a server event. 4056 * 4057 * @param packet 4058 * @private 4059 */; 4060 _proto.onevent = function onevent(packet) { 4061 var args = packet.data || []; 4062 debug$2("emitting event %j", args); 4063 if (null != packet.id) { 4064 debug$2("attaching ack callback to event"); 4065 args.push(this.ack(packet.id)); 4066 } 4067 if (this.connected) { 4068 this.emitEvent(args); 4069 } else { 4070 this.receiveBuffer.push(Object.freeze(args)); 4071 } 4072 }; 4073 _proto.emitEvent = function emitEvent(args) { 4074 if (this._anyListeners && this._anyListeners.length) { 4075 var listeners = this._anyListeners.slice(); 4076 var _iterator = _createForOfIteratorHelper(listeners), 4077 _step; 4078 try { 4079 for (_iterator.s(); !(_step = _iterator.n()).done;) { 4080 var listener = _step.value; 4081 listener.apply(this, args); 4082 } 4083 } catch (err) { 4084 _iterator.e(err); 4085 } finally { 4086 _iterator.f(); 4087 } 4088 } 4089 _Emitter.prototype.emit.apply(this, args); 4090 if (this._pid && args.length && typeof args[args.length - 1] === "string") { 4091 this._lastOffset = args[args.length - 1]; 4092 } 4093 } 4094 /** 4095 * Produces an ack callback to emit with an event. 4096 * 4097 * @private 4098 */; 4099 _proto.ack = function ack(id) { 4100 var self = this; 4101 var sent = false; 4102 return function () { 4103 // prevent double callbacks 4104 if (sent) return; 4105 sent = true; 4106 for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { 4107 args[_key6] = arguments[_key6]; 4108 } 4109 debug$2("sending ack %j", args); 4110 self.packet({ 4111 type: PacketType.ACK, 4112 id: id, 4113 data: args 4114 }); 4115 }; 4116 } 4117 /** 4118 * Called upon a server acknowledgement. 4119 * 4120 * @param packet 4121 * @private 4122 */; 4123 _proto.onack = function onack(packet) { 4124 var ack = this.acks[packet.id]; 4125 if (typeof ack !== "function") { 4126 debug$2("bad ack %s", packet.id); 4127 return; 4128 } 4129 delete this.acks[packet.id]; 4130 debug$2("calling ack %s with %j", packet.id, packet.data); 4131 // @ts-ignore FIXME ack is incorrectly inferred as 'never' 4132 if (ack.withError) { 4133 packet.data.unshift(null); 4134 } 4135 // @ts-ignore 4136 ack.apply(this, packet.data); 4137 } 4138 /** 4139 * Called upon server connect. 4140 * 4141 * @private 4142 */; 4143 _proto.onconnect = function onconnect(id, pid) { 4144 debug$2("socket connected with id %s", id); 4145 this.id = id; 4146 this.recovered = pid && this._pid === pid; 4147 this._pid = pid; // defined only if connection state recovery is enabled 4148 this.connected = true; 4149 this.emitBuffered(); 4150 this._drainQueue(true); 4151 this.emitReserved("connect"); 4152 } 4153 /** 4154 * Emit buffered events (received and emitted). 4155 * 4156 * @private 4157 */; 4158 _proto.emitBuffered = function emitBuffered() { 4159 var _this7 = this; 4160 this.receiveBuffer.forEach(function (args) { 4161 return _this7.emitEvent(args); 4162 }); 4163 this.receiveBuffer = []; 4164 this.sendBuffer.forEach(function (packet) { 4165 _this7.notifyOutgoingListeners(packet); 4166 _this7.packet(packet); 4167 }); 4168 this.sendBuffer = []; 4169 } 4170 /** 4171 * Called upon server disconnect. 4172 * 4173 * @private 4174 */; 4175 _proto.ondisconnect = function ondisconnect() { 4176 debug$2("server disconnect (%s)", this.nsp); 4177 this.destroy(); 4178 this.onclose("io server disconnect"); 4179 } 4180 /** 4181 * Called upon forced client/server side disconnections, 4182 * this method ensures the manager stops tracking us and 4183 * that reconnections don't get triggered for this. 4184 * 4185 * @private 4186 */; 4187 _proto.destroy = function destroy() { 4188 if (this.subs) { 4189 // clean subscriptions to avoid reconnections 4190 this.subs.forEach(function (subDestroy) { 4191 return subDestroy(); 4192 }); 4193 this.subs = undefined; 4194 } 4195 this.io["_destroy"](this); 4196 } 4197 /** 4198 * Disconnects the socket manually. In that case, the socket will not try to reconnect. 4199 * 4200 * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed. 4201 * 4202 * @example 4203 * const socket = io(); 4204 * 4205 * socket.on("disconnect", (reason) => { 4206 * // console.log(reason); prints "io client disconnect" 4207 * }); 4208 * 4209 * socket.disconnect(); 4210 * 4211 * @return self 4212 */; 4213 _proto.disconnect = function disconnect() { 4214 if (this.connected) { 4215 debug$2("performing disconnect (%s)", this.nsp); 4216 this.packet({ 4217 type: PacketType.DISCONNECT 4218 }); 4219 } 4220 // remove socket from pool 4221 this.destroy(); 4222 if (this.connected) { 4223 // fire events 4224 this.onclose("io client disconnect"); 4225 } 4226 return this; 4227 } 4228 /** 4229 * Alias for {@link disconnect()}. 4230 * 4231 * @return self 4232 */; 4233 _proto.close = function close() { 4234 return this.disconnect(); 4235 } 4236 /** 4237 * Sets the compress flag. 4238 * 4239 * @example 4240 * socket.compress(false).emit("hello"); 4241 * 4242 * @param compress - if `true`, compresses the sending data 4243 * @return self 4244 */; 4245 _proto.compress = function compress(_compress) { 4246 this.flags.compress = _compress; 4247 return this; 4248 } 4249 /** 4250 * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not 4251 * ready to send messages. 4252 * 4253 * @example 4254 * socket.volatile.emit("hello"); // the server may or may not receive it 4255 * 4256 * @returns self 4257 */; 4258 /** 4259 * Sets a modifier for a subsequent event emission that the callback will be called with an error when the 4260 * given number of milliseconds have elapsed without an acknowledgement from the server: 4261 * 4262 * @example 4263 * socket.timeout(5000).emit("my-event", (err) => { 4264 * if (err) { 4265 * // the server did not acknowledge the event in the given delay 4266 * } 4267 * }); 4268 * 4269 * @returns self 4270 */ 4271 _proto.timeout = function timeout(_timeout) { 4272 this.flags.timeout = _timeout; 4273 return this; 4274 } 4275 /** 4276 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4277 * callback. 4278 * 4279 * @example 4280 * socket.onAny((event, ...args) => { 4281 * console.log(`got ${event}`); 4282 * }); 4283 * 4284 * @param listener 4285 */; 4286 _proto.onAny = function onAny(listener) { 4287 this._anyListeners = this._anyListeners || []; 4288 this._anyListeners.push(listener); 4289 return this; 4290 } 4291 /** 4292 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4293 * callback. The listener is added to the beginning of the listeners array. 4294 * 4295 * @example 4296 * socket.prependAny((event, ...args) => { 4297 * console.log(`got event ${event}`); 4298 * }); 4299 * 4300 * @param listener 4301 */; 4302 _proto.prependAny = function prependAny(listener) { 4303 this._anyListeners = this._anyListeners || []; 4304 this._anyListeners.unshift(listener); 4305 return this; 4306 } 4307 /** 4308 * Removes the listener that will be fired when any event is emitted. 4309 * 4310 * @example 4311 * const catchAllListener = (event, ...args) => { 4312 * console.log(`got event ${event}`); 4313 * } 4314 * 4315 * socket.onAny(catchAllListener); 4316 * 4317 * // remove a specific listener 4318 * socket.offAny(catchAllListener); 4319 * 4320 * // or remove all listeners 4321 * socket.offAny(); 4322 * 4323 * @param listener 4324 */; 4325 _proto.offAny = function offAny(listener) { 4326 if (!this._anyListeners) { 4327 return this; 4328 } 4329 if (listener) { 4330 var listeners = this._anyListeners; 4331 for (var i = 0; i < listeners.length; i++) { 4332 if (listener === listeners[i]) { 4333 listeners.splice(i, 1); 4334 return this; 4335 } 4336 } 4337 } else { 4338 this._anyListeners = []; 4339 } 4340 return this; 4341 } 4342 /** 4343 * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, 4344 * e.g. to remove listeners. 4345 */; 4346 _proto.listenersAny = function listenersAny() { 4347 return this._anyListeners || []; 4348 } 4349 /** 4350 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4351 * callback. 4352 * 4353 * Note: acknowledgements sent to the server are not included. 4354 * 4355 * @example 4356 * socket.onAnyOutgoing((event, ...args) => { 4357 * console.log(`sent event ${event}`); 4358 * }); 4359 * 4360 * @param listener 4361 */; 4362 _proto.onAnyOutgoing = function onAnyOutgoing(listener) { 4363 this._anyOutgoingListeners = this._anyOutgoingListeners || []; 4364 this._anyOutgoingListeners.push(listener); 4365 return this; 4366 } 4367 /** 4368 * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4369 * callback. The listener is added to the beginning of the listeners array. 4370 * 4371 * Note: acknowledgements sent to the server are not included. 4372 * 4373 * @example 4374 * socket.prependAnyOutgoing((event, ...args) => { 4375 * console.log(`sent event ${event}`); 4376 * }); 4377 * 4378 * @param listener 4379 */; 4380 _proto.prependAnyOutgoing = function prependAnyOutgoing(listener) { 4381 this._anyOutgoingListeners = this._anyOutgoingListeners || []; 4382 this._anyOutgoingListeners.unshift(listener); 4383 return this; 4384 } 4385 /** 4386 * Removes the listener that will be fired when any event is emitted. 4387 * 4388 * @example 4389 * const catchAllListener = (event, ...args) => { 4390 * console.log(`sent event ${event}`); 4391 * } 4392 * 4393 * socket.onAnyOutgoing(catchAllListener); 4394 * 4395 * // remove a specific listener 4396 * socket.offAnyOutgoing(catchAllListener); 4397 * 4398 * // or remove all listeners 4399 * socket.offAnyOutgoing(); 4400 * 4401 * @param [listener] - the catch-all listener (optional) 4402 */; 4403 _proto.offAnyOutgoing = function offAnyOutgoing(listener) { 4404 if (!this._anyOutgoingListeners) { 4405 return this; 4406 } 4407 if (listener) { 4408 var listeners = this._anyOutgoingListeners; 4409 for (var i = 0; i < listeners.length; i++) { 4410 if (listener === listeners[i]) { 4411 listeners.splice(i, 1); 4412 return this; 4413 } 4414 } 4415 } else { 4416 this._anyOutgoingListeners = []; 4417 } 4418 return this; 4419 } 4420 /** 4421 * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, 4422 * e.g. to remove listeners. 4423 */; 4424 _proto.listenersAnyOutgoing = function listenersAnyOutgoing() { 4425 return this._anyOutgoingListeners || []; 4426 } 4427 /** 4428 * Notify the listeners for each packet sent 4429 * 4430 * @param packet 4431 * 4432 * @private 4433 */; 4434 _proto.notifyOutgoingListeners = function notifyOutgoingListeners(packet) { 4435 if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) { 4436 var listeners = this._anyOutgoingListeners.slice(); 4437 var _iterator2 = _createForOfIteratorHelper(listeners), 4438 _step2; 4439 try { 4440 for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { 4441 var listener = _step2.value; 4442 listener.apply(this, packet.data); 4443 } 4444 } catch (err) { 4445 _iterator2.e(err); 4446 } finally { 4447 _iterator2.f(); 4448 } 4449 } 4450 }; 4451 return _createClass(Socket, [{ 4452 key: "disconnected", 4453 get: function get() { 4454 return !this.connected; 4455 } 4456 }, { 4457 key: "active", 4458 get: function get() { 4459 return !!this.subs; 4460 } 4461 }, { 4462 key: "volatile", 4463 get: function get() { 4464 this.flags["volatile"] = true; 4465 return this; 4466 } 4467 }]); 4468 }(Emitter); 4469 4470 /** 4471 * Initialize backoff timer with `opts`. 4472 * 4473 * - `min` initial timeout in milliseconds [100] 4474 * - `max` max timeout [10000] 4475 * - `jitter` [0] 4476 * - `factor` [2] 4477 * 4478 * @param {Object} opts 4479 * @api public 4480 */ 4481 function Backoff(opts) { 4482 opts = opts || {}; 4483 this.ms = opts.min || 100; 4484 this.max = opts.max || 10000; 4485 this.factor = opts.factor || 2; 4486 this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; 4487 this.attempts = 0; 4488 } 4489 /** 4490 * Return the backoff duration. 4491 * 4492 * @return {Number} 4493 * @api public 4494 */ 4495 Backoff.prototype.duration = function () { 4496 var ms = this.ms * Math.pow(this.factor, this.attempts++); 4497 if (this.jitter) { 4498 var rand = Math.random(); 4499 var deviation = Math.floor(rand * this.jitter * ms); 4500 ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; 4501 } 4502 return Math.min(ms, this.max) | 0; 4503 }; 4504 /** 4505 * Reset the number of attempts. 4506 * 4507 * @api public 4508 */ 4509 Backoff.prototype.reset = function () { 4510 this.attempts = 0; 4511 }; 4512 /** 4513 * Set the minimum duration 4514 * 4515 * @api public 4516 */ 4517 Backoff.prototype.setMin = function (min) { 4518 this.ms = min; 4519 }; 4520 /** 4521 * Set the maximum duration 4522 * 4523 * @api public 4524 */ 4525 Backoff.prototype.setMax = function (max) { 4526 this.max = max; 4527 }; 4528 /** 4529 * Set the jitter 4530 * 4531 * @api public 4532 */ 4533 Backoff.prototype.setJitter = function (jitter) { 4534 this.jitter = jitter; 4535 }; 4536 4537 var debug$1 = debugModule("socket.io-client:manager"); // debug() 4538 var Manager = /*#__PURE__*/function (_Emitter) { 4539 function Manager(uri, opts) { 4540 var _this; 4541 var _a; 4542 _this = _Emitter.call(this) || this; 4543 _this.nsps = {}; 4544 _this.subs = []; 4545 if (uri && "object" === _typeof(uri)) { 4546 opts = uri; 4547 uri = undefined; 4548 } 4549 opts = opts || {}; 4550 opts.path = opts.path || "/socket.io"; 4551 _this.opts = opts; 4552 installTimerFunctions(_this, opts); 4553 _this.reconnection(opts.reconnection !== false); 4554 _this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); 4555 _this.reconnectionDelay(opts.reconnectionDelay || 1000); 4556 _this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); 4557 _this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5); 4558 _this.backoff = new Backoff({ 4559 min: _this.reconnectionDelay(), 4560 max: _this.reconnectionDelayMax(), 4561 jitter: _this.randomizationFactor() 4562 }); 4563 _this.timeout(null == opts.timeout ? 20000 : opts.timeout); 4564 _this._readyState = "closed"; 4565 _this.uri = uri; 4566 var _parser = opts.parser || parser; 4567 _this.encoder = new _parser.Encoder(); 4568 _this.decoder = new _parser.Decoder(); 4569 _this._autoConnect = opts.autoConnect !== false; 4570 if (_this._autoConnect) _this.open(); 4571 return _this; 4572 } 4573 _inheritsLoose(Manager, _Emitter); 4574 var _proto = Manager.prototype; 4575 _proto.reconnection = function reconnection(v) { 4576 if (!arguments.length) return this._reconnection; 4577 this._reconnection = !!v; 4578 if (!v) { 4579 this.skipReconnect = true; 4580 } 4581 return this; 4582 }; 4583 _proto.reconnectionAttempts = function reconnectionAttempts(v) { 4584 if (v === undefined) return this._reconnectionAttempts; 4585 this._reconnectionAttempts = v; 4586 return this; 4587 }; 4588 _proto.reconnectionDelay = function reconnectionDelay(v) { 4589 var _a; 4590 if (v === undefined) return this._reconnectionDelay; 4591 this._reconnectionDelay = v; 4592 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v); 4593 return this; 4594 }; 4595 _proto.randomizationFactor = function randomizationFactor(v) { 4596 var _a; 4597 if (v === undefined) return this._randomizationFactor; 4598 this._randomizationFactor = v; 4599 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v); 4600 return this; 4601 }; 4602 _proto.reconnectionDelayMax = function reconnectionDelayMax(v) { 4603 var _a; 4604 if (v === undefined) return this._reconnectionDelayMax; 4605 this._reconnectionDelayMax = v; 4606 (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v); 4607 return this; 4608 }; 4609 _proto.timeout = function timeout(v) { 4610 if (!arguments.length) return this._timeout; 4611 this._timeout = v; 4612 return this; 4613 } 4614 /** 4615 * Starts trying to reconnect if reconnection is enabled and we have not 4616 * started reconnecting yet 4617 * 4618 * @private 4619 */; 4620 _proto.maybeReconnectOnOpen = function maybeReconnectOnOpen() { 4621 // Only try to reconnect if it's the first time we're connecting 4622 if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) { 4623 // keeps reconnection from firing twice for the same reconnection loop 4624 this.reconnect(); 4625 } 4626 } 4627 /** 4628 * Sets the current transport `socket`. 4629 * 4630 * @param {Function} fn - optional, callback 4631 * @return self 4632 * @public 4633 */; 4634 _proto.open = function open(fn) { 4635 var _this2 = this; 4636 debug$1("readyState %s", this._readyState); 4637 if (~this._readyState.indexOf("open")) return this; 4638 debug$1("opening %s", this.uri); 4639 this.engine = new Socket$1(this.uri, this.opts); 4640 var socket = this.engine; 4641 var self = this; 4642 this._readyState = "opening"; 4643 this.skipReconnect = false; 4644 // emit `open` 4645 var openSubDestroy = on(socket, "open", function () { 4646 self.onopen(); 4647 fn && fn(); 4648 }); 4649 var onError = function onError(err) { 4650 debug$1("error"); 4651 _this2.cleanup(); 4652 _this2._readyState = "closed"; 4653 _this2.emitReserved("error", err); 4654 if (fn) { 4655 fn(err); 4656 } else { 4657 // Only do this if there is no fn to handle the error 4658 _this2.maybeReconnectOnOpen(); 4659 } 4660 }; 4661 // emit `error` 4662 var errorSub = on(socket, "error", onError); 4663 if (false !== this._timeout) { 4664 var timeout = this._timeout; 4665 debug$1("connect attempt will timeout after %d", timeout); 4666 // set timer 4667 var timer = this.setTimeoutFn(function () { 4668 debug$1("connect attempt timed out after %d", timeout); 4669 openSubDestroy(); 4670 onError(new Error("timeout")); 4671 socket.close(); 4672 }, timeout); 4673 if (this.opts.autoUnref) { 4674 timer.unref(); 4675 } 4676 this.subs.push(function () { 4677 _this2.clearTimeoutFn(timer); 4678 }); 4679 } 4680 this.subs.push(openSubDestroy); 4681 this.subs.push(errorSub); 4682 return this; 4683 } 4684 /** 4685 * Alias for open() 4686 * 4687 * @return self 4688 * @public 4689 */; 4690 _proto.connect = function connect(fn) { 4691 return this.open(fn); 4692 } 4693 /** 4694 * Called upon transport open. 4695 * 4696 * @private 4697 */; 4698 _proto.onopen = function onopen() { 4699 debug$1("open"); 4700 // clear old subs 4701 this.cleanup(); 4702 // mark as open 4703 this._readyState = "open"; 4704 this.emitReserved("open"); 4705 // add new subs 4706 var socket = this.engine; 4707 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)), 4708 // @ts-ignore 4709 on(this.decoder, "decoded", this.ondecoded.bind(this))); 4710 } 4711 /** 4712 * Called upon a ping. 4713 * 4714 * @private 4715 */; 4716 _proto.onping = function onping() { 4717 this.emitReserved("ping"); 4718 } 4719 /** 4720 * Called with data. 4721 * 4722 * @private 4723 */; 4724 _proto.ondata = function ondata(data) { 4725 try { 4726 this.decoder.add(data); 4727 } catch (e) { 4728 this.onclose("parse error", e); 4729 } 4730 } 4731 /** 4732 * Called when parser fully decodes a packet. 4733 * 4734 * @private 4735 */; 4736 _proto.ondecoded = function ondecoded(packet) { 4737 var _this3 = this; 4738 // the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a "parse error" 4739 nextTick(function () { 4740 _this3.emitReserved("packet", packet); 4741 }, this.setTimeoutFn); 4742 } 4743 /** 4744 * Called upon socket error. 4745 * 4746 * @private 4747 */; 4748 _proto.onerror = function onerror(err) { 4749 debug$1("error", err); 4750 this.emitReserved("error", err); 4751 } 4752 /** 4753 * Creates a new socket for the given `nsp`. 4754 * 4755 * @return {Socket} 4756 * @public 4757 */; 4758 _proto.socket = function socket(nsp, opts) { 4759 var socket = this.nsps[nsp]; 4760 if (!socket) { 4761 socket = new Socket(this, nsp, opts); 4762 this.nsps[nsp] = socket; 4763 } else if (this._autoConnect && !socket.active) { 4764 socket.connect(); 4765 } 4766 return socket; 4767 } 4768 /** 4769 * Called upon a socket close. 4770 * 4771 * @param socket 4772 * @private 4773 */; 4774 _proto._destroy = function _destroy(socket) { 4775 var nsps = Object.keys(this.nsps); 4776 for (var _i = 0, _nsps = nsps; _i < _nsps.length; _i++) { 4777 var nsp = _nsps[_i]; 4778 var _socket = this.nsps[nsp]; 4779 if (_socket.active) { 4780 debug$1("socket %s is still active, skipping close", nsp); 4781 return; 4782 } 4783 } 4784 this._close(); 4785 } 4786 /** 4787 * Writes a packet. 4788 * 4789 * @param packet 4790 * @private 4791 */; 4792 _proto._packet = function _packet(packet) { 4793 debug$1("writing packet %j", packet); 4794 var encodedPackets = this.encoder.encode(packet); 4795 for (var i = 0; i < encodedPackets.length; i++) { 4796 this.engine.write(encodedPackets[i], packet.options); 4797 } 4798 } 4799 /** 4800 * Clean up transport subscriptions and packet buffer. 4801 * 4802 * @private 4803 */; 4804 _proto.cleanup = function cleanup() { 4805 debug$1("cleanup"); 4806 this.subs.forEach(function (subDestroy) { 4807 return subDestroy(); 4808 }); 4809 this.subs.length = 0; 4810 this.decoder.destroy(); 4811 } 4812 /** 4813 * Close the current socket. 4814 * 4815 * @private 4816 */; 4817 _proto._close = function _close() { 4818 debug$1("disconnect"); 4819 this.skipReconnect = true; 4820 this._reconnecting = false; 4821 this.onclose("forced close"); 4822 } 4823 /** 4824 * Alias for close() 4825 * 4826 * @private 4827 */; 4828 _proto.disconnect = function disconnect() { 4829 return this._close(); 4830 } 4831 /** 4832 * Called when: 4833 * 4834 * - the low-level engine is closed 4835 * - the parser encountered a badly formatted packet 4836 * - all sockets are disconnected 4837 * 4838 * @private 4839 */; 4840 _proto.onclose = function onclose(reason, description) { 4841 var _a; 4842 debug$1("closed due to %s", reason); 4843 this.cleanup(); 4844 (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close(); 4845 this.backoff.reset(); 4846 this._readyState = "closed"; 4847 this.emitReserved("close", reason, description); 4848 if (this._reconnection && !this.skipReconnect) { 4849 this.reconnect(); 4850 } 4851 } 4852 /** 4853 * Attempt a reconnection. 4854 * 4855 * @private 4856 */; 4857 _proto.reconnect = function reconnect() { 4858 var _this4 = this; 4859 if (this._reconnecting || this.skipReconnect) return this; 4860 var self = this; 4861 if (this.backoff.attempts >= this._reconnectionAttempts) { 4862 debug$1("reconnect failed"); 4863 this.backoff.reset(); 4864 this.emitReserved("reconnect_failed"); 4865 this._reconnecting = false; 4866 } else { 4867 var delay = this.backoff.duration(); 4868 debug$1("will wait %dms before reconnect attempt", delay); 4869 this._reconnecting = true; 4870 var timer = this.setTimeoutFn(function () { 4871 if (self.skipReconnect) return; 4872 debug$1("attempting reconnect"); 4873 _this4.emitReserved("reconnect_attempt", self.backoff.attempts); 4874 // check again for the case socket closed in above events 4875 if (self.skipReconnect) return; 4876 self.open(function (err) { 4877 if (err) { 4878 debug$1("reconnect attempt error"); 4879 self._reconnecting = false; 4880 self.reconnect(); 4881 _this4.emitReserved("reconnect_error", err); 4882 } else { 4883 debug$1("reconnect success"); 4884 self.onreconnect(); 4885 } 4886 }); 4887 }, delay); 4888 if (this.opts.autoUnref) { 4889 timer.unref(); 4890 } 4891 this.subs.push(function () { 4892 _this4.clearTimeoutFn(timer); 4893 }); 4894 } 4895 } 4896 /** 4897 * Called upon successful reconnect. 4898 * 4899 * @private 4900 */; 4901 _proto.onreconnect = function onreconnect() { 4902 var attempt = this.backoff.attempts; 4903 this._reconnecting = false; 4904 this.backoff.reset(); 4905 this.emitReserved("reconnect", attempt); 4906 }; 4907 return Manager; 4908 }(Emitter); 4909 4910 var debug = debugModule("socket.io-client"); // debug() 4911 /** 4912 * Managers cache. 4913 */ 4914 var cache = {}; 4915 function lookup(uri, opts) { 4916 if (_typeof(uri) === "object") { 4917 opts = uri; 4918 uri = undefined; 4919 } 4920 opts = opts || {}; 4921 var parsed = url(uri, opts.path || "/socket.io"); 4922 var source = parsed.source; 4923 var id = parsed.id; 4924 var path = parsed.path; 4925 var sameNamespace = cache[id] && path in cache[id]["nsps"]; 4926 var newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace; 4927 var io; 4928 if (newConnection) { 4929 debug("ignoring socket cache for %s", source); 4930 io = new Manager(source, opts); 4931 } else { 4932 if (!cache[id]) { 4933 debug("new io instance for %s", source); 4934 cache[id] = new Manager(source, opts); 4935 } 4936 io = cache[id]; 4937 } 4938 if (parsed.query && !opts.query) { 4939 opts.query = parsed.queryKey; 4940 } 4941 return io.socket(parsed.path, opts); 4942 } 4943 // so that "lookup" can be used both as a function (e.g. `io(...)`) and as a 4944 // namespace (e.g. `io.connect(...)`), for backward compatibility 4945 _extends(lookup, { 4946 Manager: Manager, 4947 Socket: Socket, 4948 io: lookup, 4949 connect: lookup 4950 }); 4951 4952 return lookup; 4953 4954})); 4955//# sourceMappingURL=socket.io.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.