This is page 5 of 6. Use http://codebase.md/mikechambers/adb-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .gitattributes ├── .gitignore ├── adb-proxy-socket │ ├── .gitignore │ ├── package-lock.json │ ├── package.json │ ├── proxy.js │ └── README.md ├── cep │ ├── com.mikechambers.ae │ │ ├── .debug │ │ ├── commands.js │ │ ├── CSXS │ │ │ └── manifest.xml │ │ ├── index.html │ │ ├── jsx │ │ │ └── json-polyfill.jsx │ │ ├── lib │ │ │ └── CSInterface.js │ │ ├── main.js │ │ └── style.css │ └── com.mikechambers.ai │ ├── .debug │ ├── commands.js │ ├── CSXS │ │ └── manifest.xml │ ├── index.html │ ├── jsx │ │ ├── json-polyfill.jsx │ │ └── utils.jsx │ ├── lib │ │ └── CSInterface.js │ ├── main.js │ └── style.css ├── dxt │ ├── build │ ├── pr │ │ └── manifest.json │ └── ps │ └── manifest.json ├── images │ └── claud-attach-mcp.png ├── LICENSE.md ├── mcp │ ├── .gitignore │ ├── ae-mcp.py │ ├── ai-mcp.py │ ├── core.py │ ├── fonts.py │ ├── id-mcp.py │ ├── logger.py │ ├── pr-mcp.py │ ├── ps-batch-play.py │ ├── ps-mcp.py │ ├── pyproject.toml │ ├── requirements.txt │ ├── socket_client.py │ └── uv.lock ├── package-lock.json ├── README.md └── uxp ├── id │ ├── commands │ │ └── index.js │ ├── icons │ │ ├── [email protected] │ │ ├── [email protected] │ │ ├── [email protected] │ │ └── [email protected] │ ├── index.html │ ├── LICENSE │ ├── main.js │ ├── manifest.json │ ├── package.json │ ├── socket.io.js │ └── style.css ├── pr │ ├── commands │ │ ├── consts.js │ │ ├── core.js │ │ ├── index.js │ │ └── utils.js │ ├── icons │ │ ├── [email protected] │ │ ├── [email protected] │ │ ├── [email protected] │ │ └── [email protected] │ ├── index.html │ ├── LICENSE │ ├── main.js │ ├── manifest.json │ ├── package.json │ ├── socket.io.js │ └── style.css └── ps ├── commands │ ├── adjustment_layers.js │ ├── core.js │ ├── filters.js │ ├── index.js │ ├── layer_styles.js │ ├── layers.js │ ├── selection.js │ └── utils.js ├── icons │ ├── [email protected] │ ├── [email protected] │ ├── [email protected] │ └── [email protected] ├── index.html ├── LICENSE ├── main.js ├── manifest.json ├── package.json ├── socket.io.js └── style.css ``` # Files -------------------------------------------------------------------------------- /uxp/pr/socket.io.js: -------------------------------------------------------------------------------- ```javascript 1 | /*! 2 | * Socket.IO v4.8.1 3 | * (c) 2014-2024 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 i; 2673 | var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); 2674 | var len = split.length; 2675 | for (i = 0; i < len; i++) { 2676 | if (!split[i]) { 2677 | // ignore empty strings 2678 | continue; 2679 | } 2680 | namespaces = split[i].replace(/\*/g, '.*?'); 2681 | if (namespaces[0] === '-') { 2682 | createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$')); 2683 | } else { 2684 | createDebug.names.push(new RegExp('^' + namespaces + '$')); 2685 | } 2686 | } 2687 | } 2688 | 2689 | /** 2690 | * Disable debug output. 2691 | * 2692 | * @return {String} namespaces 2693 | * @api public 2694 | */ 2695 | function disable() { 2696 | var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { 2697 | return '-' + namespace; 2698 | }))).join(','); 2699 | createDebug.enable(''); 2700 | return namespaces; 2701 | } 2702 | 2703 | /** 2704 | * Returns true if the given mode name is enabled, false otherwise. 2705 | * 2706 | * @param {String} name 2707 | * @return {Boolean} 2708 | * @api public 2709 | */ 2710 | function enabled(name) { 2711 | if (name[name.length - 1] === '*') { 2712 | return true; 2713 | } 2714 | var i; 2715 | var len; 2716 | for (i = 0, len = createDebug.skips.length; i < len; i++) { 2717 | if (createDebug.skips[i].test(name)) { 2718 | return false; 2719 | } 2720 | } 2721 | for (i = 0, len = createDebug.names.length; i < len; i++) { 2722 | if (createDebug.names[i].test(name)) { 2723 | return true; 2724 | } 2725 | } 2726 | return false; 2727 | } 2728 | 2729 | /** 2730 | * Convert regexp to namespace 2731 | * 2732 | * @param {RegExp} regxep 2733 | * @return {String} namespace 2734 | * @api private 2735 | */ 2736 | function toNamespace(regexp) { 2737 | return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); 2738 | } 2739 | 2740 | /** 2741 | * Coerce `val`. 2742 | * 2743 | * @param {Mixed} val 2744 | * @return {Mixed} 2745 | * @api private 2746 | */ 2747 | function coerce(val) { 2748 | if (val instanceof Error) { 2749 | return val.stack || val.message; 2750 | } 2751 | return val; 2752 | } 2753 | 2754 | /** 2755 | * XXX DO NOT USE. This is a temporary stub function. 2756 | * XXX It WILL be removed in the next major release. 2757 | */ 2758 | function destroy() { 2759 | console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); 2760 | } 2761 | createDebug.enable(createDebug.load()); 2762 | return createDebug; 2763 | } 2764 | var common = setup; 2765 | 2766 | /* eslint-env browser */ 2767 | browser.exports; 2768 | (function (module, exports) { 2769 | /** 2770 | * This is the web browser implementation of `debug()`. 2771 | */ 2772 | 2773 | exports.formatArgs = formatArgs; 2774 | exports.save = save; 2775 | exports.load = load; 2776 | exports.useColors = useColors; 2777 | exports.storage = localstorage(); 2778 | exports.destroy = function () { 2779 | var warned = false; 2780 | return function () { 2781 | if (!warned) { 2782 | warned = true; 2783 | console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); 2784 | } 2785 | }; 2786 | }(); 2787 | 2788 | /** 2789 | * Colors. 2790 | */ 2791 | 2792 | 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']; 2793 | 2794 | /** 2795 | * Currently only WebKit-based Web Inspectors, Firefox >= v31, 2796 | * and the Firebug extension (any Firefox version) are known 2797 | * to support "%c" CSS customizations. 2798 | * 2799 | * TODO: add a `localStorage` variable to explicitly enable/disable colors 2800 | */ 2801 | 2802 | // eslint-disable-next-line complexity 2803 | function useColors() { 2804 | // NB: In an Electron preload script, document will be defined but not fully 2805 | // initialized. Since we know we're in Chrome, we'll just detect this case 2806 | // explicitly 2807 | if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { 2808 | return true; 2809 | } 2810 | 2811 | // Internet Explorer and Edge do not support colors. 2812 | if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { 2813 | return false; 2814 | } 2815 | 2816 | // Is webkit? http://stackoverflow.com/a/16459606/376773 2817 | // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 2818 | return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || 2819 | // Is firebug? http://stackoverflow.com/a/398120/376773 2820 | typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || 2821 | // Is firefox >= v31? 2822 | // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages 2823 | typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || 2824 | // Double check webkit in userAgent just in case we are in a worker 2825 | typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); 2826 | } 2827 | 2828 | /** 2829 | * Colorize log arguments if enabled. 2830 | * 2831 | * @api public 2832 | */ 2833 | 2834 | function formatArgs(args) { 2835 | args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); 2836 | if (!this.useColors) { 2837 | return; 2838 | } 2839 | var c = 'color: ' + this.color; 2840 | args.splice(1, 0, c, 'color: inherit'); 2841 | 2842 | // The final "%c" is somewhat tricky, because there could be other 2843 | // arguments passed either before or after the %c, so we need to 2844 | // figure out the correct index to insert the CSS into 2845 | var index = 0; 2846 | var lastC = 0; 2847 | args[0].replace(/%[a-zA-Z%]/g, function (match) { 2848 | if (match === '%%') { 2849 | return; 2850 | } 2851 | index++; 2852 | if (match === '%c') { 2853 | // We only are interested in the *last* %c 2854 | // (the user may have provided their own) 2855 | lastC = index; 2856 | } 2857 | }); 2858 | args.splice(lastC, 0, c); 2859 | } 2860 | 2861 | /** 2862 | * Invokes `console.debug()` when available. 2863 | * No-op when `console.debug` is not a "function". 2864 | * If `console.debug` is not available, falls back 2865 | * to `console.log`. 2866 | * 2867 | * @api public 2868 | */ 2869 | exports.log = console.debug || console.log || function () {}; 2870 | 2871 | /** 2872 | * Save `namespaces`. 2873 | * 2874 | * @param {String} namespaces 2875 | * @api private 2876 | */ 2877 | function save(namespaces) { 2878 | try { 2879 | if (namespaces) { 2880 | exports.storage.setItem('debug', namespaces); 2881 | } else { 2882 | exports.storage.removeItem('debug'); 2883 | } 2884 | } catch (error) { 2885 | // Swallow 2886 | // XXX (@Qix-) should we be logging these? 2887 | } 2888 | } 2889 | 2890 | /** 2891 | * Load `namespaces`. 2892 | * 2893 | * @return {String} returns the previously persisted debug modes 2894 | * @api private 2895 | */ 2896 | function load() { 2897 | var r; 2898 | try { 2899 | r = exports.storage.getItem('debug'); 2900 | } catch (error) { 2901 | // Swallow 2902 | // XXX (@Qix-) should we be logging these? 2903 | } 2904 | 2905 | // If debug isn't set in LS, and we're in Electron, try to load $DEBUG 2906 | if (!r && typeof process !== 'undefined' && 'env' in process) { 2907 | r = process.env.DEBUG; 2908 | } 2909 | return r; 2910 | } 2911 | 2912 | /** 2913 | * Localstorage attempts to return the localstorage. 2914 | * 2915 | * This is necessary because safari throws 2916 | * when a user disables cookies/localstorage 2917 | * and you attempt to access it. 2918 | * 2919 | * @return {LocalStorage} 2920 | * @api private 2921 | */ 2922 | 2923 | function localstorage() { 2924 | try { 2925 | // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context 2926 | // The Browser also has localStorage in the global context. 2927 | return localStorage; 2928 | } catch (error) { 2929 | // Swallow 2930 | // XXX (@Qix-) should we be logging these? 2931 | } 2932 | } 2933 | module.exports = common(exports); 2934 | var formatters = module.exports.formatters; 2935 | 2936 | /** 2937 | * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. 2938 | */ 2939 | 2940 | formatters.j = function (v) { 2941 | try { 2942 | return JSON.stringify(v); 2943 | } catch (error) { 2944 | return '[UnexpectedJSONParseError]: ' + error.message; 2945 | } 2946 | }; 2947 | })(browser, browser.exports); 2948 | var browserExports = browser.exports; 2949 | var debugModule = /*@__PURE__*/getDefaultExportFromCjs(browserExports); 2950 | 2951 | var debug$3 = debugModule("socket.io-client:url"); // debug() 2952 | /** 2953 | * URL parser. 2954 | * 2955 | * @param uri - url 2956 | * @param path - the request path of the connection 2957 | * @param loc - An object meant to mimic window.location. 2958 | * Defaults to window.location. 2959 | * @public 2960 | */ 2961 | function url(uri) { 2962 | var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; 2963 | var loc = arguments.length > 2 ? arguments[2] : undefined; 2964 | var obj = uri; 2965 | // default to window.location 2966 | loc = loc || typeof location !== "undefined" && location; 2967 | if (null == uri) uri = loc.protocol + "//" + loc.host; 2968 | // relative path support 2969 | if (typeof uri === "string") { 2970 | if ("/" === uri.charAt(0)) { 2971 | if ("/" === uri.charAt(1)) { 2972 | uri = loc.protocol + uri; 2973 | } else { 2974 | uri = loc.host + uri; 2975 | } 2976 | } 2977 | if (!/^(https?|wss?):\/\//.test(uri)) { 2978 | debug$3("protocol-less url %s", uri); 2979 | if ("undefined" !== typeof loc) { 2980 | uri = loc.protocol + "//" + uri; 2981 | } else { 2982 | uri = "https://" + uri; 2983 | } 2984 | } 2985 | // parse 2986 | debug$3("parse %s", uri); 2987 | obj = parse(uri); 2988 | } 2989 | // make sure we treat `localhost:80` and `localhost` equally 2990 | if (!obj.port) { 2991 | if (/^(http|ws)$/.test(obj.protocol)) { 2992 | obj.port = "80"; 2993 | } else if (/^(http|ws)s$/.test(obj.protocol)) { 2994 | obj.port = "443"; 2995 | } 2996 | } 2997 | obj.path = obj.path || "/"; 2998 | var ipv6 = obj.host.indexOf(":") !== -1; 2999 | var host = ipv6 ? "[" + obj.host + "]" : obj.host; 3000 | // define unique id 3001 | obj.id = obj.protocol + "://" + host + ":" + obj.port + path; 3002 | // define href 3003 | obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port); 3004 | return obj; 3005 | } 3006 | 3007 | var withNativeArrayBuffer = typeof ArrayBuffer === "function"; 3008 | var isView = function isView(obj) { 3009 | return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer; 3010 | }; 3011 | var toString = Object.prototype.toString; 3012 | var withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && toString.call(Blob) === "[object BlobConstructor]"; 3013 | var withNativeFile = typeof File === "function" || typeof File !== "undefined" && toString.call(File) === "[object FileConstructor]"; 3014 | /** 3015 | * Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File. 3016 | * 3017 | * @private 3018 | */ 3019 | function isBinary(obj) { 3020 | return withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)) || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File; 3021 | } 3022 | function hasBinary(obj, toJSON) { 3023 | if (!obj || _typeof(obj) !== "object") { 3024 | return false; 3025 | } 3026 | if (Array.isArray(obj)) { 3027 | for (var i = 0, l = obj.length; i < l; i++) { 3028 | if (hasBinary(obj[i])) { 3029 | return true; 3030 | } 3031 | } 3032 | return false; 3033 | } 3034 | if (isBinary(obj)) { 3035 | return true; 3036 | } 3037 | if (obj.toJSON && typeof obj.toJSON === "function" && arguments.length === 1) { 3038 | return hasBinary(obj.toJSON(), true); 3039 | } 3040 | for (var key in obj) { 3041 | if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { 3042 | return true; 3043 | } 3044 | } 3045 | return false; 3046 | } 3047 | 3048 | /** 3049 | * Replaces every Buffer | ArrayBuffer | Blob | File in packet with a numbered placeholder. 3050 | * 3051 | * @param {Object} packet - socket.io event packet 3052 | * @return {Object} with deconstructed packet and list of buffers 3053 | * @public 3054 | */ 3055 | function deconstructPacket(packet) { 3056 | var buffers = []; 3057 | var packetData = packet.data; 3058 | var pack = packet; 3059 | pack.data = _deconstructPacket(packetData, buffers); 3060 | pack.attachments = buffers.length; // number of binary 'attachments' 3061 | return { 3062 | packet: pack, 3063 | buffers: buffers 3064 | }; 3065 | } 3066 | function _deconstructPacket(data, buffers) { 3067 | if (!data) return data; 3068 | if (isBinary(data)) { 3069 | var placeholder = { 3070 | _placeholder: true, 3071 | num: buffers.length 3072 | }; 3073 | buffers.push(data); 3074 | return placeholder; 3075 | } else if (Array.isArray(data)) { 3076 | var newData = new Array(data.length); 3077 | for (var i = 0; i < data.length; i++) { 3078 | newData[i] = _deconstructPacket(data[i], buffers); 3079 | } 3080 | return newData; 3081 | } else if (_typeof(data) === "object" && !(data instanceof Date)) { 3082 | var _newData = {}; 3083 | for (var key in data) { 3084 | if (Object.prototype.hasOwnProperty.call(data, key)) { 3085 | _newData[key] = _deconstructPacket(data[key], buffers); 3086 | } 3087 | } 3088 | return _newData; 3089 | } 3090 | return data; 3091 | } 3092 | /** 3093 | * Reconstructs a binary packet from its placeholder packet and buffers 3094 | * 3095 | * @param {Object} packet - event packet with placeholders 3096 | * @param {Array} buffers - binary buffers to put in placeholder positions 3097 | * @return {Object} reconstructed packet 3098 | * @public 3099 | */ 3100 | function reconstructPacket(packet, buffers) { 3101 | packet.data = _reconstructPacket(packet.data, buffers); 3102 | delete packet.attachments; // no longer useful 3103 | return packet; 3104 | } 3105 | function _reconstructPacket(data, buffers) { 3106 | if (!data) return data; 3107 | if (data && data._placeholder === true) { 3108 | var isIndexValid = typeof data.num === "number" && data.num >= 0 && data.num < buffers.length; 3109 | if (isIndexValid) { 3110 | return buffers[data.num]; // appropriate buffer (should be natural order anyway) 3111 | } else { 3112 | throw new Error("illegal attachments"); 3113 | } 3114 | } else if (Array.isArray(data)) { 3115 | for (var i = 0; i < data.length; i++) { 3116 | data[i] = _reconstructPacket(data[i], buffers); 3117 | } 3118 | } else if (_typeof(data) === "object") { 3119 | for (var key in data) { 3120 | if (Object.prototype.hasOwnProperty.call(data, key)) { 3121 | data[key] = _reconstructPacket(data[key], buffers); 3122 | } 3123 | } 3124 | } 3125 | return data; 3126 | } 3127 | 3128 | /** 3129 | * These strings must not be used as event names, as they have a special meaning. 3130 | */ 3131 | var RESERVED_EVENTS$1 = ["connect", 3132 | // used on the client side 3133 | "connect_error", 3134 | // used on the client side 3135 | "disconnect", 3136 | // used on both sides 3137 | "disconnecting", 3138 | // used on the server side 3139 | "newListener", 3140 | // used by the Node.js EventEmitter 3141 | "removeListener" // used by the Node.js EventEmitter 3142 | ]; 3143 | /** 3144 | * Protocol version. 3145 | * 3146 | * @public 3147 | */ 3148 | var protocol = 5; 3149 | var PacketType; 3150 | (function (PacketType) { 3151 | PacketType[PacketType["CONNECT"] = 0] = "CONNECT"; 3152 | PacketType[PacketType["DISCONNECT"] = 1] = "DISCONNECT"; 3153 | PacketType[PacketType["EVENT"] = 2] = "EVENT"; 3154 | PacketType[PacketType["ACK"] = 3] = "ACK"; 3155 | PacketType[PacketType["CONNECT_ERROR"] = 4] = "CONNECT_ERROR"; 3156 | PacketType[PacketType["BINARY_EVENT"] = 5] = "BINARY_EVENT"; 3157 | PacketType[PacketType["BINARY_ACK"] = 6] = "BINARY_ACK"; 3158 | })(PacketType || (PacketType = {})); 3159 | /** 3160 | * A socket.io Encoder instance 3161 | */ 3162 | var Encoder = /*#__PURE__*/function () { 3163 | /** 3164 | * Encoder constructor 3165 | * 3166 | * @param {function} replacer - custom replacer to pass down to JSON.parse 3167 | */ 3168 | function Encoder(replacer) { 3169 | this.replacer = replacer; 3170 | } 3171 | /** 3172 | * Encode a packet as a single string if non-binary, or as a 3173 | * buffer sequence, depending on packet type. 3174 | * 3175 | * @param {Object} obj - packet object 3176 | */ 3177 | var _proto = Encoder.prototype; 3178 | _proto.encode = function encode(obj) { 3179 | if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) { 3180 | if (hasBinary(obj)) { 3181 | return this.encodeAsBinary({ 3182 | type: obj.type === PacketType.EVENT ? PacketType.BINARY_EVENT : PacketType.BINARY_ACK, 3183 | nsp: obj.nsp, 3184 | data: obj.data, 3185 | id: obj.id 3186 | }); 3187 | } 3188 | } 3189 | return [this.encodeAsString(obj)]; 3190 | } 3191 | /** 3192 | * Encode packet as string. 3193 | */; 3194 | _proto.encodeAsString = function encodeAsString(obj) { 3195 | // first is type 3196 | var str = "" + obj.type; 3197 | // attachments if we have them 3198 | if (obj.type === PacketType.BINARY_EVENT || obj.type === PacketType.BINARY_ACK) { 3199 | str += obj.attachments + "-"; 3200 | } 3201 | // if we have a namespace other than `/` 3202 | // we append it followed by a comma `,` 3203 | if (obj.nsp && "/" !== obj.nsp) { 3204 | str += obj.nsp + ","; 3205 | } 3206 | // immediately followed by the id 3207 | if (null != obj.id) { 3208 | str += obj.id; 3209 | } 3210 | // json data 3211 | if (null != obj.data) { 3212 | str += JSON.stringify(obj.data, this.replacer); 3213 | } 3214 | return str; 3215 | } 3216 | /** 3217 | * Encode packet as 'buffer sequence' by removing blobs, and 3218 | * deconstructing packet into object with placeholders and 3219 | * a list of buffers. 3220 | */; 3221 | _proto.encodeAsBinary = function encodeAsBinary(obj) { 3222 | var deconstruction = deconstructPacket(obj); 3223 | var pack = this.encodeAsString(deconstruction.packet); 3224 | var buffers = deconstruction.buffers; 3225 | buffers.unshift(pack); // add packet info to beginning of data list 3226 | return buffers; // write all the buffers 3227 | }; 3228 | return Encoder; 3229 | }(); 3230 | /** 3231 | * A socket.io Decoder instance 3232 | * 3233 | * @return {Object} decoder 3234 | */ 3235 | var Decoder = /*#__PURE__*/function (_Emitter) { 3236 | /** 3237 | * Decoder constructor 3238 | * 3239 | * @param {function} reviver - custom reviver to pass down to JSON.stringify 3240 | */ 3241 | function Decoder(reviver) { 3242 | var _this; 3243 | _this = _Emitter.call(this) || this; 3244 | _this.reviver = reviver; 3245 | return _this; 3246 | } 3247 | /** 3248 | * Decodes an encoded packet string into packet JSON. 3249 | * 3250 | * @param {String} obj - encoded packet 3251 | */ 3252 | _inheritsLoose(Decoder, _Emitter); 3253 | var _proto2 = Decoder.prototype; 3254 | _proto2.add = function add(obj) { 3255 | var packet; 3256 | if (typeof obj === "string") { 3257 | if (this.reconstructor) { 3258 | throw new Error("got plaintext data when reconstructing a packet"); 3259 | } 3260 | packet = this.decodeString(obj); 3261 | var isBinaryEvent = packet.type === PacketType.BINARY_EVENT; 3262 | if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) { 3263 | packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK; 3264 | // binary packet's json 3265 | this.reconstructor = new BinaryReconstructor(packet); 3266 | // no attachments, labeled binary but no binary data to follow 3267 | if (packet.attachments === 0) { 3268 | _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3269 | } 3270 | } else { 3271 | // non-binary full packet 3272 | _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3273 | } 3274 | } else if (isBinary(obj) || obj.base64) { 3275 | // raw binary data 3276 | if (!this.reconstructor) { 3277 | throw new Error("got binary data when not reconstructing a packet"); 3278 | } else { 3279 | packet = this.reconstructor.takeBinaryData(obj); 3280 | if (packet) { 3281 | // received final buffer 3282 | this.reconstructor = null; 3283 | _Emitter.prototype.emitReserved.call(this, "decoded", packet); 3284 | } 3285 | } 3286 | } else { 3287 | throw new Error("Unknown type: " + obj); 3288 | } 3289 | } 3290 | /** 3291 | * Decode a packet String (JSON data) 3292 | * 3293 | * @param {String} str 3294 | * @return {Object} packet 3295 | */; 3296 | _proto2.decodeString = function decodeString(str) { 3297 | var i = 0; 3298 | // look up type 3299 | var p = { 3300 | type: Number(str.charAt(0)) 3301 | }; 3302 | if (PacketType[p.type] === undefined) { 3303 | throw new Error("unknown packet type " + p.type); 3304 | } 3305 | // look up attachments if type binary 3306 | if (p.type === PacketType.BINARY_EVENT || p.type === PacketType.BINARY_ACK) { 3307 | var start = i + 1; 3308 | while (str.charAt(++i) !== "-" && i != str.length) {} 3309 | var buf = str.substring(start, i); 3310 | if (buf != Number(buf) || str.charAt(i) !== "-") { 3311 | throw new Error("Illegal attachments"); 3312 | } 3313 | p.attachments = Number(buf); 3314 | } 3315 | // look up namespace (if any) 3316 | if ("/" === str.charAt(i + 1)) { 3317 | var _start = i + 1; 3318 | while (++i) { 3319 | var c = str.charAt(i); 3320 | if ("," === c) break; 3321 | if (i === str.length) break; 3322 | } 3323 | p.nsp = str.substring(_start, i); 3324 | } else { 3325 | p.nsp = "/"; 3326 | } 3327 | // look up id 3328 | var next = str.charAt(i + 1); 3329 | if ("" !== next && Number(next) == next) { 3330 | var _start2 = i + 1; 3331 | while (++i) { 3332 | var _c = str.charAt(i); 3333 | if (null == _c || Number(_c) != _c) { 3334 | --i; 3335 | break; 3336 | } 3337 | if (i === str.length) break; 3338 | } 3339 | p.id = Number(str.substring(_start2, i + 1)); 3340 | } 3341 | // look up json data 3342 | if (str.charAt(++i)) { 3343 | var payload = this.tryParse(str.substr(i)); 3344 | if (Decoder.isPayloadValid(p.type, payload)) { 3345 | p.data = payload; 3346 | } else { 3347 | throw new Error("invalid payload"); 3348 | } 3349 | } 3350 | return p; 3351 | }; 3352 | _proto2.tryParse = function tryParse(str) { 3353 | try { 3354 | return JSON.parse(str, this.reviver); 3355 | } catch (e) { 3356 | return false; 3357 | } 3358 | }; 3359 | Decoder.isPayloadValid = function isPayloadValid(type, payload) { 3360 | switch (type) { 3361 | case PacketType.CONNECT: 3362 | return isObject(payload); 3363 | case PacketType.DISCONNECT: 3364 | return payload === undefined; 3365 | case PacketType.CONNECT_ERROR: 3366 | return typeof payload === "string" || isObject(payload); 3367 | case PacketType.EVENT: 3368 | case PacketType.BINARY_EVENT: 3369 | return Array.isArray(payload) && (typeof payload[0] === "number" || typeof payload[0] === "string" && RESERVED_EVENTS$1.indexOf(payload[0]) === -1); 3370 | case PacketType.ACK: 3371 | case PacketType.BINARY_ACK: 3372 | return Array.isArray(payload); 3373 | } 3374 | } 3375 | /** 3376 | * Deallocates a parser's resources 3377 | */; 3378 | _proto2.destroy = function destroy() { 3379 | if (this.reconstructor) { 3380 | this.reconstructor.finishedReconstruction(); 3381 | this.reconstructor = null; 3382 | } 3383 | }; 3384 | return Decoder; 3385 | }(Emitter); 3386 | /** 3387 | * A manager of a binary event's 'buffer sequence'. Should 3388 | * be constructed whenever a packet of type BINARY_EVENT is 3389 | * decoded. 3390 | * 3391 | * @param {Object} packet 3392 | * @return {BinaryReconstructor} initialized reconstructor 3393 | */ 3394 | var BinaryReconstructor = /*#__PURE__*/function () { 3395 | function BinaryReconstructor(packet) { 3396 | this.packet = packet; 3397 | this.buffers = []; 3398 | this.reconPack = packet; 3399 | } 3400 | /** 3401 | * Method to be called when binary data received from connection 3402 | * after a BINARY_EVENT packet. 3403 | * 3404 | * @param {Buffer | ArrayBuffer} binData - the raw binary data received 3405 | * @return {null | Object} returns null if more binary data is expected or 3406 | * a reconstructed packet object if all buffers have been received. 3407 | */ 3408 | var _proto3 = BinaryReconstructor.prototype; 3409 | _proto3.takeBinaryData = function takeBinaryData(binData) { 3410 | this.buffers.push(binData); 3411 | if (this.buffers.length === this.reconPack.attachments) { 3412 | // done with buffer list 3413 | var packet = reconstructPacket(this.reconPack, this.buffers); 3414 | this.finishedReconstruction(); 3415 | return packet; 3416 | } 3417 | return null; 3418 | } 3419 | /** 3420 | * Cleans up binary packet reconstruction variables. 3421 | */; 3422 | _proto3.finishedReconstruction = function finishedReconstruction() { 3423 | this.reconPack = null; 3424 | this.buffers = []; 3425 | }; 3426 | return BinaryReconstructor; 3427 | }(); 3428 | function isNamespaceValid(nsp) { 3429 | return typeof nsp === "string"; 3430 | } 3431 | // see https://caniuse.com/mdn-javascript_builtins_number_isinteger 3432 | var isInteger = Number.isInteger || function (value) { 3433 | return typeof value === "number" && isFinite(value) && Math.floor(value) === value; 3434 | }; 3435 | function isAckIdValid(id) { 3436 | return id === undefined || isInteger(id); 3437 | } 3438 | // see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript 3439 | function isObject(value) { 3440 | return Object.prototype.toString.call(value) === "[object Object]"; 3441 | } 3442 | function isDataValid(type, payload) { 3443 | switch (type) { 3444 | case PacketType.CONNECT: 3445 | return payload === undefined || isObject(payload); 3446 | case PacketType.DISCONNECT: 3447 | return payload === undefined; 3448 | case PacketType.EVENT: 3449 | return Array.isArray(payload) && (typeof payload[0] === "number" || typeof payload[0] === "string" && RESERVED_EVENTS$1.indexOf(payload[0]) === -1); 3450 | case PacketType.ACK: 3451 | return Array.isArray(payload); 3452 | case PacketType.CONNECT_ERROR: 3453 | return typeof payload === "string" || isObject(payload); 3454 | default: 3455 | return false; 3456 | } 3457 | } 3458 | function isPacketValid(packet) { 3459 | return isNamespaceValid(packet.nsp) && isAckIdValid(packet.id) && isDataValid(packet.type, packet.data); 3460 | } 3461 | 3462 | var parser = /*#__PURE__*/Object.freeze({ 3463 | __proto__: null, 3464 | protocol: protocol, 3465 | get PacketType () { return PacketType; }, 3466 | Encoder: Encoder, 3467 | Decoder: Decoder, 3468 | isPacketValid: isPacketValid 3469 | }); 3470 | 3471 | function on(obj, ev, fn) { 3472 | obj.on(ev, fn); 3473 | return function subDestroy() { 3474 | obj.off(ev, fn); 3475 | }; 3476 | } 3477 | 3478 | var debug$2 = debugModule("socket.io-client:socket"); // debug() 3479 | /** 3480 | * Internal events. 3481 | * These events can't be emitted by the user. 3482 | */ 3483 | var RESERVED_EVENTS = Object.freeze({ 3484 | connect: 1, 3485 | connect_error: 1, 3486 | disconnect: 1, 3487 | disconnecting: 1, 3488 | // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener 3489 | newListener: 1, 3490 | removeListener: 1 3491 | }); 3492 | /** 3493 | * A Socket is the fundamental class for interacting with the server. 3494 | * 3495 | * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate. 3496 | * 3497 | * @example 3498 | * const socket = io(); 3499 | * 3500 | * socket.on("connect", () => { 3501 | * console.log("connected"); 3502 | * }); 3503 | * 3504 | * // send an event to the server 3505 | * socket.emit("foo", "bar"); 3506 | * 3507 | * socket.on("foobar", () => { 3508 | * // an event was received from the server 3509 | * }); 3510 | * 3511 | * // upon disconnection 3512 | * socket.on("disconnect", (reason) => { 3513 | * console.log(`disconnected due to ${reason}`); 3514 | * }); 3515 | */ 3516 | var Socket = /*#__PURE__*/function (_Emitter) { 3517 | /** 3518 | * `Socket` constructor. 3519 | */ 3520 | function Socket(io, nsp, opts) { 3521 | var _this; 3522 | _this = _Emitter.call(this) || this; 3523 | /** 3524 | * Whether the socket is currently connected to the server. 3525 | * 3526 | * @example 3527 | * const socket = io(); 3528 | * 3529 | * socket.on("connect", () => { 3530 | * console.log(socket.connected); // true 3531 | * }); 3532 | * 3533 | * socket.on("disconnect", () => { 3534 | * console.log(socket.connected); // false 3535 | * }); 3536 | */ 3537 | _this.connected = false; 3538 | /** 3539 | * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will 3540 | * be transmitted by the server. 3541 | */ 3542 | _this.recovered = false; 3543 | /** 3544 | * Buffer for packets received before the CONNECT packet 3545 | */ 3546 | _this.receiveBuffer = []; 3547 | /** 3548 | * Buffer for packets that will be sent once the socket is connected 3549 | */ 3550 | _this.sendBuffer = []; 3551 | /** 3552 | * The queue of packets to be sent with retry in case of failure. 3553 | * 3554 | * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order. 3555 | * @private 3556 | */ 3557 | _this._queue = []; 3558 | /** 3559 | * A sequence to generate the ID of the {@link QueuedPacket}. 3560 | * @private 3561 | */ 3562 | _this._queueSeq = 0; 3563 | _this.ids = 0; 3564 | /** 3565 | * A map containing acknowledgement handlers. 3566 | * 3567 | * The `withError` attribute is used to differentiate handlers that accept an error as first argument: 3568 | * 3569 | * - `socket.emit("test", (err, value) => { ... })` with `ackTimeout` option 3570 | * - `socket.timeout(5000).emit("test", (err, value) => { ... })` 3571 | * - `const value = await socket.emitWithAck("test")` 3572 | * 3573 | * From those that don't: 3574 | * 3575 | * - `socket.emit("test", (value) => { ... });` 3576 | * 3577 | * In the first case, the handlers will be called with an error when: 3578 | * 3579 | * - the timeout is reached 3580 | * - the socket gets disconnected 3581 | * 3582 | * In the second case, the handlers will be simply discarded upon disconnection, since the client will never receive 3583 | * an acknowledgement from the server. 3584 | * 3585 | * @private 3586 | */ 3587 | _this.acks = {}; 3588 | _this.flags = {}; 3589 | _this.io = io; 3590 | _this.nsp = nsp; 3591 | if (opts && opts.auth) { 3592 | _this.auth = opts.auth; 3593 | } 3594 | _this._opts = _extends({}, opts); 3595 | if (_this.io._autoConnect) _this.open(); 3596 | return _this; 3597 | } 3598 | /** 3599 | * Whether the socket is currently disconnected 3600 | * 3601 | * @example 3602 | * const socket = io(); 3603 | * 3604 | * socket.on("connect", () => { 3605 | * console.log(socket.disconnected); // false 3606 | * }); 3607 | * 3608 | * socket.on("disconnect", () => { 3609 | * console.log(socket.disconnected); // true 3610 | * }); 3611 | */ 3612 | _inheritsLoose(Socket, _Emitter); 3613 | var _proto = Socket.prototype; 3614 | /** 3615 | * Subscribe to open, close and packet events 3616 | * 3617 | * @private 3618 | */ 3619 | _proto.subEvents = function subEvents() { 3620 | if (this.subs) return; 3621 | var io = this.io; 3622 | 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))]; 3623 | } 3624 | /** 3625 | * Whether the Socket will try to reconnect when its Manager connects or reconnects. 3626 | * 3627 | * @example 3628 | * const socket = io(); 3629 | * 3630 | * console.log(socket.active); // true 3631 | * 3632 | * socket.on("disconnect", (reason) => { 3633 | * if (reason === "io server disconnect") { 3634 | * // the disconnection was initiated by the server, you need to manually reconnect 3635 | * console.log(socket.active); // false 3636 | * } 3637 | * // else the socket will automatically try to reconnect 3638 | * console.log(socket.active); // true 3639 | * }); 3640 | */; 3641 | /** 3642 | * "Opens" the socket. 3643 | * 3644 | * @example 3645 | * const socket = io({ 3646 | * autoConnect: false 3647 | * }); 3648 | * 3649 | * socket.connect(); 3650 | */ 3651 | _proto.connect = function connect() { 3652 | if (this.connected) return this; 3653 | this.subEvents(); 3654 | if (!this.io["_reconnecting"]) this.io.open(); // ensure open 3655 | if ("open" === this.io._readyState) this.onopen(); 3656 | return this; 3657 | } 3658 | /** 3659 | * Alias for {@link connect()}. 3660 | */; 3661 | _proto.open = function open() { 3662 | return this.connect(); 3663 | } 3664 | /** 3665 | * Sends a `message` event. 3666 | * 3667 | * This method mimics the WebSocket.send() method. 3668 | * 3669 | * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send 3670 | * 3671 | * @example 3672 | * socket.send("hello"); 3673 | * 3674 | * // this is equivalent to 3675 | * socket.emit("message", "hello"); 3676 | * 3677 | * @return self 3678 | */; 3679 | _proto.send = function send() { 3680 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3681 | args[_key] = arguments[_key]; 3682 | } 3683 | args.unshift("message"); 3684 | this.emit.apply(this, args); 3685 | return this; 3686 | } 3687 | /** 3688 | * Override `emit`. 3689 | * If the event is in `events`, it's emitted normally. 3690 | * 3691 | * @example 3692 | * socket.emit("hello", "world"); 3693 | * 3694 | * // all serializable datastructures are supported (no need to call JSON.stringify) 3695 | * socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) }); 3696 | * 3697 | * // with an acknowledgement from the server 3698 | * socket.emit("hello", "world", (val) => { 3699 | * // ... 3700 | * }); 3701 | * 3702 | * @return self 3703 | */; 3704 | _proto.emit = function emit(ev) { 3705 | var _a, _b, _c; 3706 | if (RESERVED_EVENTS.hasOwnProperty(ev)) { 3707 | throw new Error('"' + ev.toString() + '" is a reserved event name'); 3708 | } 3709 | for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 3710 | args[_key2 - 1] = arguments[_key2]; 3711 | } 3712 | args.unshift(ev); 3713 | if (this._opts.retries && !this.flags.fromQueue && !this.flags["volatile"]) { 3714 | this._addToQueue(args); 3715 | return this; 3716 | } 3717 | var packet = { 3718 | type: PacketType.EVENT, 3719 | data: args 3720 | }; 3721 | packet.options = {}; 3722 | packet.options.compress = this.flags.compress !== false; 3723 | // event ack callback 3724 | if ("function" === typeof args[args.length - 1]) { 3725 | var id = this.ids++; 3726 | debug$2("emitting packet with ack id %d", id); 3727 | var ack = args.pop(); 3728 | this._registerAckCallback(id, ack); 3729 | packet.id = id; 3730 | } 3731 | var isTransportWritable = (_b = (_a = this.io.engine) === null || _a === void 0 ? void 0 : _a.transport) === null || _b === void 0 ? void 0 : _b.writable; 3732 | var isConnected = this.connected && !((_c = this.io.engine) === null || _c === void 0 ? void 0 : _c._hasPingExpired()); 3733 | var discardPacket = this.flags["volatile"] && !isTransportWritable; 3734 | if (discardPacket) { 3735 | debug$2("discard packet as the transport is not currently writable"); 3736 | } else if (isConnected) { 3737 | this.notifyOutgoingListeners(packet); 3738 | this.packet(packet); 3739 | } else { 3740 | this.sendBuffer.push(packet); 3741 | } 3742 | this.flags = {}; 3743 | return this; 3744 | } 3745 | /** 3746 | * @private 3747 | */; 3748 | _proto._registerAckCallback = function _registerAckCallback(id, ack) { 3749 | var _this2 = this; 3750 | var _a; 3751 | var timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout; 3752 | if (timeout === undefined) { 3753 | this.acks[id] = ack; 3754 | return; 3755 | } 3756 | // @ts-ignore 3757 | var timer = this.io.setTimeoutFn(function () { 3758 | delete _this2.acks[id]; 3759 | for (var i = 0; i < _this2.sendBuffer.length; i++) { 3760 | if (_this2.sendBuffer[i].id === id) { 3761 | debug$2("removing packet with ack id %d from the buffer", id); 3762 | _this2.sendBuffer.splice(i, 1); 3763 | } 3764 | } 3765 | debug$2("event with ack id %d has timed out after %d ms", id, timeout); 3766 | ack.call(_this2, new Error("operation has timed out")); 3767 | }, timeout); 3768 | var fn = function fn() { 3769 | // @ts-ignore 3770 | _this2.io.clearTimeoutFn(timer); 3771 | for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 3772 | args[_key3] = arguments[_key3]; 3773 | } 3774 | ack.apply(_this2, args); 3775 | }; 3776 | fn.withError = true; 3777 | this.acks[id] = fn; 3778 | } 3779 | /** 3780 | * Emits an event and waits for an acknowledgement 3781 | * 3782 | * @example 3783 | * // without timeout 3784 | * const response = await socket.emitWithAck("hello", "world"); 3785 | * 3786 | * // with a specific timeout 3787 | * try { 3788 | * const response = await socket.timeout(1000).emitWithAck("hello", "world"); 3789 | * } catch (err) { 3790 | * // the server did not acknowledge the event in the given delay 3791 | * } 3792 | * 3793 | * @return a Promise that will be fulfilled when the server acknowledges the event 3794 | */; 3795 | _proto.emitWithAck = function emitWithAck(ev) { 3796 | var _this3 = this; 3797 | for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { 3798 | args[_key4 - 1] = arguments[_key4]; 3799 | } 3800 | return new Promise(function (resolve, reject) { 3801 | var fn = function fn(arg1, arg2) { 3802 | return arg1 ? reject(arg1) : resolve(arg2); 3803 | }; 3804 | fn.withError = true; 3805 | args.push(fn); 3806 | _this3.emit.apply(_this3, [ev].concat(args)); 3807 | }); 3808 | } 3809 | /** 3810 | * Add the packet to the queue. 3811 | * @param args 3812 | * @private 3813 | */; 3814 | _proto._addToQueue = function _addToQueue(args) { 3815 | var _this4 = this; 3816 | var ack; 3817 | if (typeof args[args.length - 1] === "function") { 3818 | ack = args.pop(); 3819 | } 3820 | var packet = { 3821 | id: this._queueSeq++, 3822 | tryCount: 0, 3823 | pending: false, 3824 | args: args, 3825 | flags: _extends({ 3826 | fromQueue: true 3827 | }, this.flags) 3828 | }; 3829 | args.push(function (err) { 3830 | if (packet !== _this4._queue[0]) { 3831 | // the packet has already been acknowledged 3832 | return; 3833 | } 3834 | var hasError = err !== null; 3835 | if (hasError) { 3836 | if (packet.tryCount > _this4._opts.retries) { 3837 | debug$2("packet [%d] is discarded after %d tries", packet.id, packet.tryCount); 3838 | _this4._queue.shift(); 3839 | if (ack) { 3840 | ack(err); 3841 | } 3842 | } 3843 | } else { 3844 | debug$2("packet [%d] was successfully sent", packet.id); 3845 | _this4._queue.shift(); 3846 | if (ack) { 3847 | for (var _len5 = arguments.length, responseArgs = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) { 3848 | responseArgs[_key5 - 1] = arguments[_key5]; 3849 | } 3850 | ack.apply(void 0, [null].concat(responseArgs)); 3851 | } 3852 | } 3853 | packet.pending = false; 3854 | return _this4._drainQueue(); 3855 | }); 3856 | this._queue.push(packet); 3857 | this._drainQueue(); 3858 | } 3859 | /** 3860 | * Send the first packet of the queue, and wait for an acknowledgement from the server. 3861 | * @param force - whether to resend a packet that has not been acknowledged yet 3862 | * 3863 | * @private 3864 | */; 3865 | _proto._drainQueue = function _drainQueue() { 3866 | var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; 3867 | debug$2("draining queue"); 3868 | if (!this.connected || this._queue.length === 0) { 3869 | return; 3870 | } 3871 | var packet = this._queue[0]; 3872 | if (packet.pending && !force) { 3873 | debug$2("packet [%d] has already been sent and is waiting for an ack", packet.id); 3874 | return; 3875 | } 3876 | packet.pending = true; 3877 | packet.tryCount++; 3878 | debug$2("sending packet [%d] (try n°%d)", packet.id, packet.tryCount); 3879 | this.flags = packet.flags; 3880 | this.emit.apply(this, packet.args); 3881 | } 3882 | /** 3883 | * Sends a packet. 3884 | * 3885 | * @param packet 3886 | * @private 3887 | */; 3888 | _proto.packet = function packet(_packet) { 3889 | _packet.nsp = this.nsp; 3890 | this.io._packet(_packet); 3891 | } 3892 | /** 3893 | * Called upon engine `open`. 3894 | * 3895 | * @private 3896 | */; 3897 | _proto.onopen = function onopen() { 3898 | var _this5 = this; 3899 | debug$2("transport is open - connecting"); 3900 | if (typeof this.auth == "function") { 3901 | this.auth(function (data) { 3902 | _this5._sendConnectPacket(data); 3903 | }); 3904 | } else { 3905 | this._sendConnectPacket(this.auth); 3906 | } 3907 | } 3908 | /** 3909 | * Sends a CONNECT packet to initiate the Socket.IO session. 3910 | * 3911 | * @param data 3912 | * @private 3913 | */; 3914 | _proto._sendConnectPacket = function _sendConnectPacket(data) { 3915 | this.packet({ 3916 | type: PacketType.CONNECT, 3917 | data: this._pid ? _extends({ 3918 | pid: this._pid, 3919 | offset: this._lastOffset 3920 | }, data) : data 3921 | }); 3922 | } 3923 | /** 3924 | * Called upon engine or manager `error`. 3925 | * 3926 | * @param err 3927 | * @private 3928 | */; 3929 | _proto.onerror = function onerror(err) { 3930 | if (!this.connected) { 3931 | this.emitReserved("connect_error", err); 3932 | } 3933 | } 3934 | /** 3935 | * Called upon engine `close`. 3936 | * 3937 | * @param reason 3938 | * @param description 3939 | * @private 3940 | */; 3941 | _proto.onclose = function onclose(reason, description) { 3942 | debug$2("close (%s)", reason); 3943 | this.connected = false; 3944 | delete this.id; 3945 | this.emitReserved("disconnect", reason, description); 3946 | this._clearAcks(); 3947 | } 3948 | /** 3949 | * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from 3950 | * the server. 3951 | * 3952 | * @private 3953 | */; 3954 | _proto._clearAcks = function _clearAcks() { 3955 | var _this6 = this; 3956 | Object.keys(this.acks).forEach(function (id) { 3957 | var isBuffered = _this6.sendBuffer.some(function (packet) { 3958 | return String(packet.id) === id; 3959 | }); 3960 | if (!isBuffered) { 3961 | // note: handlers that do not accept an error as first argument are ignored here 3962 | var ack = _this6.acks[id]; 3963 | delete _this6.acks[id]; 3964 | if (ack.withError) { 3965 | ack.call(_this6, new Error("socket has been disconnected")); 3966 | } 3967 | } 3968 | }); 3969 | } 3970 | /** 3971 | * Called with socket packet. 3972 | * 3973 | * @param packet 3974 | * @private 3975 | */; 3976 | _proto.onpacket = function onpacket(packet) { 3977 | var sameNamespace = packet.nsp === this.nsp; 3978 | if (!sameNamespace) return; 3979 | switch (packet.type) { 3980 | case PacketType.CONNECT: 3981 | if (packet.data && packet.data.sid) { 3982 | this.onconnect(packet.data.sid, packet.data.pid); 3983 | } else { 3984 | 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/)")); 3985 | } 3986 | break; 3987 | case PacketType.EVENT: 3988 | case PacketType.BINARY_EVENT: 3989 | this.onevent(packet); 3990 | break; 3991 | case PacketType.ACK: 3992 | case PacketType.BINARY_ACK: 3993 | this.onack(packet); 3994 | break; 3995 | case PacketType.DISCONNECT: 3996 | this.ondisconnect(); 3997 | break; 3998 | case PacketType.CONNECT_ERROR: 3999 | this.destroy(); 4000 | var err = new Error(packet.data.message); 4001 | // @ts-ignore 4002 | err.data = packet.data.data; 4003 | this.emitReserved("connect_error", err); 4004 | break; 4005 | } 4006 | } 4007 | /** 4008 | * Called upon a server event. 4009 | * 4010 | * @param packet 4011 | * @private 4012 | */; 4013 | _proto.onevent = function onevent(packet) { 4014 | var args = packet.data || []; 4015 | debug$2("emitting event %j", args); 4016 | if (null != packet.id) { 4017 | debug$2("attaching ack callback to event"); 4018 | args.push(this.ack(packet.id)); 4019 | } 4020 | if (this.connected) { 4021 | this.emitEvent(args); 4022 | } else { 4023 | this.receiveBuffer.push(Object.freeze(args)); 4024 | } 4025 | }; 4026 | _proto.emitEvent = function emitEvent(args) { 4027 | if (this._anyListeners && this._anyListeners.length) { 4028 | var listeners = this._anyListeners.slice(); 4029 | var _iterator = _createForOfIteratorHelper(listeners), 4030 | _step; 4031 | try { 4032 | for (_iterator.s(); !(_step = _iterator.n()).done;) { 4033 | var listener = _step.value; 4034 | listener.apply(this, args); 4035 | } 4036 | } catch (err) { 4037 | _iterator.e(err); 4038 | } finally { 4039 | _iterator.f(); 4040 | } 4041 | } 4042 | _Emitter.prototype.emit.apply(this, args); 4043 | if (this._pid && args.length && typeof args[args.length - 1] === "string") { 4044 | this._lastOffset = args[args.length - 1]; 4045 | } 4046 | } 4047 | /** 4048 | * Produces an ack callback to emit with an event. 4049 | * 4050 | * @private 4051 | */; 4052 | _proto.ack = function ack(id) { 4053 | var self = this; 4054 | var sent = false; 4055 | return function () { 4056 | // prevent double callbacks 4057 | if (sent) return; 4058 | sent = true; 4059 | for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { 4060 | args[_key6] = arguments[_key6]; 4061 | } 4062 | debug$2("sending ack %j", args); 4063 | self.packet({ 4064 | type: PacketType.ACK, 4065 | id: id, 4066 | data: args 4067 | }); 4068 | }; 4069 | } 4070 | /** 4071 | * Called upon a server acknowledgement. 4072 | * 4073 | * @param packet 4074 | * @private 4075 | */; 4076 | _proto.onack = function onack(packet) { 4077 | var ack = this.acks[packet.id]; 4078 | if (typeof ack !== "function") { 4079 | debug$2("bad ack %s", packet.id); 4080 | return; 4081 | } 4082 | delete this.acks[packet.id]; 4083 | debug$2("calling ack %s with %j", packet.id, packet.data); 4084 | // @ts-ignore FIXME ack is incorrectly inferred as 'never' 4085 | if (ack.withError) { 4086 | packet.data.unshift(null); 4087 | } 4088 | // @ts-ignore 4089 | ack.apply(this, packet.data); 4090 | } 4091 | /** 4092 | * Called upon server connect. 4093 | * 4094 | * @private 4095 | */; 4096 | _proto.onconnect = function onconnect(id, pid) { 4097 | debug$2("socket connected with id %s", id); 4098 | this.id = id; 4099 | this.recovered = pid && this._pid === pid; 4100 | this._pid = pid; // defined only if connection state recovery is enabled 4101 | this.connected = true; 4102 | this.emitBuffered(); 4103 | this.emitReserved("connect"); 4104 | this._drainQueue(true); 4105 | } 4106 | /** 4107 | * Emit buffered events (received and emitted). 4108 | * 4109 | * @private 4110 | */; 4111 | _proto.emitBuffered = function emitBuffered() { 4112 | var _this7 = this; 4113 | this.receiveBuffer.forEach(function (args) { 4114 | return _this7.emitEvent(args); 4115 | }); 4116 | this.receiveBuffer = []; 4117 | this.sendBuffer.forEach(function (packet) { 4118 | _this7.notifyOutgoingListeners(packet); 4119 | _this7.packet(packet); 4120 | }); 4121 | this.sendBuffer = []; 4122 | } 4123 | /** 4124 | * Called upon server disconnect. 4125 | * 4126 | * @private 4127 | */; 4128 | _proto.ondisconnect = function ondisconnect() { 4129 | debug$2("server disconnect (%s)", this.nsp); 4130 | this.destroy(); 4131 | this.onclose("io server disconnect"); 4132 | } 4133 | /** 4134 | * Called upon forced client/server side disconnections, 4135 | * this method ensures the manager stops tracking us and 4136 | * that reconnections don't get triggered for this. 4137 | * 4138 | * @private 4139 | */; 4140 | _proto.destroy = function destroy() { 4141 | if (this.subs) { 4142 | // clean subscriptions to avoid reconnections 4143 | this.subs.forEach(function (subDestroy) { 4144 | return subDestroy(); 4145 | }); 4146 | this.subs = undefined; 4147 | } 4148 | this.io["_destroy"](this); 4149 | } 4150 | /** 4151 | * Disconnects the socket manually. In that case, the socket will not try to reconnect. 4152 | * 4153 | * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed. 4154 | * 4155 | * @example 4156 | * const socket = io(); 4157 | * 4158 | * socket.on("disconnect", (reason) => { 4159 | * // console.log(reason); prints "io client disconnect" 4160 | * }); 4161 | * 4162 | * socket.disconnect(); 4163 | * 4164 | * @return self 4165 | */; 4166 | _proto.disconnect = function disconnect() { 4167 | if (this.connected) { 4168 | debug$2("performing disconnect (%s)", this.nsp); 4169 | this.packet({ 4170 | type: PacketType.DISCONNECT 4171 | }); 4172 | } 4173 | // remove socket from pool 4174 | this.destroy(); 4175 | if (this.connected) { 4176 | // fire events 4177 | this.onclose("io client disconnect"); 4178 | } 4179 | return this; 4180 | } 4181 | /** 4182 | * Alias for {@link disconnect()}. 4183 | * 4184 | * @return self 4185 | */; 4186 | _proto.close = function close() { 4187 | return this.disconnect(); 4188 | } 4189 | /** 4190 | * Sets the compress flag. 4191 | * 4192 | * @example 4193 | * socket.compress(false).emit("hello"); 4194 | * 4195 | * @param compress - if `true`, compresses the sending data 4196 | * @return self 4197 | */; 4198 | _proto.compress = function compress(_compress) { 4199 | this.flags.compress = _compress; 4200 | return this; 4201 | } 4202 | /** 4203 | * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not 4204 | * ready to send messages. 4205 | * 4206 | * @example 4207 | * socket.volatile.emit("hello"); // the server may or may not receive it 4208 | * 4209 | * @returns self 4210 | */; 4211 | /** 4212 | * Sets a modifier for a subsequent event emission that the callback will be called with an error when the 4213 | * given number of milliseconds have elapsed without an acknowledgement from the server: 4214 | * 4215 | * @example 4216 | * socket.timeout(5000).emit("my-event", (err) => { 4217 | * if (err) { 4218 | * // the server did not acknowledge the event in the given delay 4219 | * } 4220 | * }); 4221 | * 4222 | * @returns self 4223 | */ 4224 | _proto.timeout = function timeout(_timeout) { 4225 | this.flags.timeout = _timeout; 4226 | return this; 4227 | } 4228 | /** 4229 | * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4230 | * callback. 4231 | * 4232 | * @example 4233 | * socket.onAny((event, ...args) => { 4234 | * console.log(`got ${event}`); 4235 | * }); 4236 | * 4237 | * @param listener 4238 | */; 4239 | _proto.onAny = function onAny(listener) { 4240 | this._anyListeners = this._anyListeners || []; 4241 | this._anyListeners.push(listener); 4242 | return this; 4243 | } 4244 | /** 4245 | * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4246 | * callback. The listener is added to the beginning of the listeners array. 4247 | * 4248 | * @example 4249 | * socket.prependAny((event, ...args) => { 4250 | * console.log(`got event ${event}`); 4251 | * }); 4252 | * 4253 | * @param listener 4254 | */; 4255 | _proto.prependAny = function prependAny(listener) { 4256 | this._anyListeners = this._anyListeners || []; 4257 | this._anyListeners.unshift(listener); 4258 | return this; 4259 | } 4260 | /** 4261 | * Removes the listener that will be fired when any event is emitted. 4262 | * 4263 | * @example 4264 | * const catchAllListener = (event, ...args) => { 4265 | * console.log(`got event ${event}`); 4266 | * } 4267 | * 4268 | * socket.onAny(catchAllListener); 4269 | * 4270 | * // remove a specific listener 4271 | * socket.offAny(catchAllListener); 4272 | * 4273 | * // or remove all listeners 4274 | * socket.offAny(); 4275 | * 4276 | * @param listener 4277 | */; 4278 | _proto.offAny = function offAny(listener) { 4279 | if (!this._anyListeners) { 4280 | return this; 4281 | } 4282 | if (listener) { 4283 | var listeners = this._anyListeners; 4284 | for (var i = 0; i < listeners.length; i++) { 4285 | if (listener === listeners[i]) { 4286 | listeners.splice(i, 1); 4287 | return this; 4288 | } 4289 | } 4290 | } else { 4291 | this._anyListeners = []; 4292 | } 4293 | return this; 4294 | } 4295 | /** 4296 | * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, 4297 | * e.g. to remove listeners. 4298 | */; 4299 | _proto.listenersAny = function listenersAny() { 4300 | return this._anyListeners || []; 4301 | } 4302 | /** 4303 | * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4304 | * callback. 4305 | * 4306 | * Note: acknowledgements sent to the server are not included. 4307 | * 4308 | * @example 4309 | * socket.onAnyOutgoing((event, ...args) => { 4310 | * console.log(`sent event ${event}`); 4311 | * }); 4312 | * 4313 | * @param listener 4314 | */; 4315 | _proto.onAnyOutgoing = function onAnyOutgoing(listener) { 4316 | this._anyOutgoingListeners = this._anyOutgoingListeners || []; 4317 | this._anyOutgoingListeners.push(listener); 4318 | return this; 4319 | } 4320 | /** 4321 | * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the 4322 | * callback. The listener is added to the beginning of the listeners array. 4323 | * 4324 | * Note: acknowledgements sent to the server are not included. 4325 | * 4326 | * @example 4327 | * socket.prependAnyOutgoing((event, ...args) => { 4328 | * console.log(`sent event ${event}`); 4329 | * }); 4330 | * 4331 | * @param listener 4332 | */; 4333 | _proto.prependAnyOutgoing = function prependAnyOutgoing(listener) { 4334 | this._anyOutgoingListeners = this._anyOutgoingListeners || []; 4335 | this._anyOutgoingListeners.unshift(listener); 4336 | return this; 4337 | } 4338 | /** 4339 | * Removes the listener that will be fired when any event is emitted. 4340 | * 4341 | * @example 4342 | * const catchAllListener = (event, ...args) => { 4343 | * console.log(`sent event ${event}`); 4344 | * } 4345 | * 4346 | * socket.onAnyOutgoing(catchAllListener); 4347 | * 4348 | * // remove a specific listener 4349 | * socket.offAnyOutgoing(catchAllListener); 4350 | * 4351 | * // or remove all listeners 4352 | * socket.offAnyOutgoing(); 4353 | * 4354 | * @param [listener] - the catch-all listener (optional) 4355 | */; 4356 | _proto.offAnyOutgoing = function offAnyOutgoing(listener) { 4357 | if (!this._anyOutgoingListeners) { 4358 | return this; 4359 | } 4360 | if (listener) { 4361 | var listeners = this._anyOutgoingListeners; 4362 | for (var i = 0; i < listeners.length; i++) { 4363 | if (listener === listeners[i]) { 4364 | listeners.splice(i, 1); 4365 | return this; 4366 | } 4367 | } 4368 | } else { 4369 | this._anyOutgoingListeners = []; 4370 | } 4371 | return this; 4372 | } 4373 | /** 4374 | * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, 4375 | * e.g. to remove listeners. 4376 | */; 4377 | _proto.listenersAnyOutgoing = function listenersAnyOutgoing() { 4378 | return this._anyOutgoingListeners || []; 4379 | } 4380 | /** 4381 | * Notify the listeners for each packet sent 4382 | * 4383 | * @param packet 4384 | * 4385 | * @private 4386 | */; 4387 | _proto.notifyOutgoingListeners = function notifyOutgoingListeners(packet) { 4388 | if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) { 4389 | var listeners = this._anyOutgoingListeners.slice(); 4390 | var _iterator2 = _createForOfIteratorHelper(listeners), 4391 | _step2; 4392 | try { 4393 | for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { 4394 | var listener = _step2.value; 4395 | listener.apply(this, packet.data); 4396 | } 4397 | } catch (err) { 4398 | _iterator2.e(err); 4399 | } finally { 4400 | _iterator2.f(); 4401 | } 4402 | } 4403 | }; 4404 | return _createClass(Socket, [{ 4405 | key: "disconnected", 4406 | get: function get() { 4407 | return !this.connected; 4408 | } 4409 | }, { 4410 | key: "active", 4411 | get: function get() { 4412 | return !!this.subs; 4413 | } 4414 | }, { 4415 | key: "volatile", 4416 | get: function get() { 4417 | this.flags["volatile"] = true; 4418 | return this; 4419 | } 4420 | }]); 4421 | }(Emitter); 4422 | 4423 | /** 4424 | * Initialize backoff timer with `opts`. 4425 | * 4426 | * - `min` initial timeout in milliseconds [100] 4427 | * - `max` max timeout [10000] 4428 | * - `jitter` [0] 4429 | * - `factor` [2] 4430 | * 4431 | * @param {Object} opts 4432 | * @api public 4433 | */ 4434 | function Backoff(opts) { 4435 | opts = opts || {}; 4436 | this.ms = opts.min || 100; 4437 | this.max = opts.max || 10000; 4438 | this.factor = opts.factor || 2; 4439 | this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; 4440 | this.attempts = 0; 4441 | } 4442 | /** 4443 | * Return the backoff duration. 4444 | * 4445 | * @return {Number} 4446 | * @api public 4447 | */ 4448 | Backoff.prototype.duration = function () { 4449 | var ms = this.ms * Math.pow(this.factor, this.attempts++); 4450 | if (this.jitter) { 4451 | var rand = Math.random(); 4452 | var deviation = Math.floor(rand * this.jitter * ms); 4453 | ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; 4454 | } 4455 | return Math.min(ms, this.max) | 0; 4456 | }; 4457 | /** 4458 | * Reset the number of attempts. 4459 | * 4460 | * @api public 4461 | */ 4462 | Backoff.prototype.reset = function () { 4463 | this.attempts = 0; 4464 | }; 4465 | /** 4466 | * Set the minimum duration 4467 | * 4468 | * @api public 4469 | */ 4470 | Backoff.prototype.setMin = function (min) { 4471 | this.ms = min; 4472 | }; 4473 | /** 4474 | * Set the maximum duration 4475 | * 4476 | * @api public 4477 | */ 4478 | Backoff.prototype.setMax = function (max) { 4479 | this.max = max; 4480 | }; 4481 | /** 4482 | * Set the jitter 4483 | * 4484 | * @api public 4485 | */ 4486 | Backoff.prototype.setJitter = function (jitter) { 4487 | this.jitter = jitter; 4488 | }; 4489 | 4490 | var debug$1 = debugModule("socket.io-client:manager"); // debug() 4491 | var Manager = /*#__PURE__*/function (_Emitter) { 4492 | function Manager(uri, opts) { 4493 | var _this; 4494 | var _a; 4495 | _this = _Emitter.call(this) || this; 4496 | _this.nsps = {}; 4497 | _this.subs = []; 4498 | if (uri && "object" === _typeof(uri)) { 4499 | opts = uri; 4500 | uri = undefined; 4501 | } 4502 | opts = opts || {}; 4503 | opts.path = opts.path || "/socket.io"; 4504 | _this.opts = opts; 4505 | installTimerFunctions(_this, opts); 4506 | _this.reconnection(opts.reconnection !== false); 4507 | _this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); 4508 | _this.reconnectionDelay(opts.reconnectionDelay || 1000); 4509 | _this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); 4510 | _this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5); 4511 | _this.backoff = new Backoff({ 4512 | min: _this.reconnectionDelay(), 4513 | max: _this.reconnectionDelayMax(), 4514 | jitter: _this.randomizationFactor() 4515 | }); 4516 | _this.timeout(null == opts.timeout ? 20000 : opts.timeout); 4517 | _this._readyState = "closed"; 4518 | _this.uri = uri; 4519 | var _parser = opts.parser || parser; 4520 | _this.encoder = new _parser.Encoder(); 4521 | _this.decoder = new _parser.Decoder(); 4522 | _this._autoConnect = opts.autoConnect !== false; 4523 | if (_this._autoConnect) _this.open(); 4524 | return _this; 4525 | } 4526 | _inheritsLoose(Manager, _Emitter); 4527 | var _proto = Manager.prototype; 4528 | _proto.reconnection = function reconnection(v) { 4529 | if (!arguments.length) return this._reconnection; 4530 | this._reconnection = !!v; 4531 | if (!v) { 4532 | this.skipReconnect = true; 4533 | } 4534 | return this; 4535 | }; 4536 | _proto.reconnectionAttempts = function reconnectionAttempts(v) { 4537 | if (v === undefined) return this._reconnectionAttempts; 4538 | this._reconnectionAttempts = v; 4539 | return this; 4540 | }; 4541 | _proto.reconnectionDelay = function reconnectionDelay(v) { 4542 | var _a; 4543 | if (v === undefined) return this._reconnectionDelay; 4544 | this._reconnectionDelay = v; 4545 | (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v); 4546 | return this; 4547 | }; 4548 | _proto.randomizationFactor = function randomizationFactor(v) { 4549 | var _a; 4550 | if (v === undefined) return this._randomizationFactor; 4551 | this._randomizationFactor = v; 4552 | (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v); 4553 | return this; 4554 | }; 4555 | _proto.reconnectionDelayMax = function reconnectionDelayMax(v) { 4556 | var _a; 4557 | if (v === undefined) return this._reconnectionDelayMax; 4558 | this._reconnectionDelayMax = v; 4559 | (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v); 4560 | return this; 4561 | }; 4562 | _proto.timeout = function timeout(v) { 4563 | if (!arguments.length) return this._timeout; 4564 | this._timeout = v; 4565 | return this; 4566 | } 4567 | /** 4568 | * Starts trying to reconnect if reconnection is enabled and we have not 4569 | * started reconnecting yet 4570 | * 4571 | * @private 4572 | */; 4573 | _proto.maybeReconnectOnOpen = function maybeReconnectOnOpen() { 4574 | // Only try to reconnect if it's the first time we're connecting 4575 | if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) { 4576 | // keeps reconnection from firing twice for the same reconnection loop 4577 | this.reconnect(); 4578 | } 4579 | } 4580 | /** 4581 | * Sets the current transport `socket`. 4582 | * 4583 | * @param {Function} fn - optional, callback 4584 | * @return self 4585 | * @public 4586 | */; 4587 | _proto.open = function open(fn) { 4588 | var _this2 = this; 4589 | debug$1("readyState %s", this._readyState); 4590 | if (~this._readyState.indexOf("open")) return this; 4591 | debug$1("opening %s", this.uri); 4592 | this.engine = new Socket$1(this.uri, this.opts); 4593 | var socket = this.engine; 4594 | var self = this; 4595 | this._readyState = "opening"; 4596 | this.skipReconnect = false; 4597 | // emit `open` 4598 | var openSubDestroy = on(socket, "open", function () { 4599 | self.onopen(); 4600 | fn && fn(); 4601 | }); 4602 | var onError = function onError(err) { 4603 | debug$1("error"); 4604 | _this2.cleanup(); 4605 | _this2._readyState = "closed"; 4606 | _this2.emitReserved("error", err); 4607 | if (fn) { 4608 | fn(err); 4609 | } else { 4610 | // Only do this if there is no fn to handle the error 4611 | _this2.maybeReconnectOnOpen(); 4612 | } 4613 | }; 4614 | // emit `error` 4615 | var errorSub = on(socket, "error", onError); 4616 | if (false !== this._timeout) { 4617 | var timeout = this._timeout; 4618 | debug$1("connect attempt will timeout after %d", timeout); 4619 | // set timer 4620 | var timer = this.setTimeoutFn(function () { 4621 | debug$1("connect attempt timed out after %d", timeout); 4622 | openSubDestroy(); 4623 | onError(new Error("timeout")); 4624 | socket.close(); 4625 | }, timeout); 4626 | if (this.opts.autoUnref) { 4627 | timer.unref(); 4628 | } 4629 | this.subs.push(function () { 4630 | _this2.clearTimeoutFn(timer); 4631 | }); 4632 | } 4633 | this.subs.push(openSubDestroy); 4634 | this.subs.push(errorSub); 4635 | return this; 4636 | } 4637 | /** 4638 | * Alias for open() 4639 | * 4640 | * @return self 4641 | * @public 4642 | */; 4643 | _proto.connect = function connect(fn) { 4644 | return this.open(fn); 4645 | } 4646 | /** 4647 | * Called upon transport open. 4648 | * 4649 | * @private 4650 | */; 4651 | _proto.onopen = function onopen() { 4652 | debug$1("open"); 4653 | // clear old subs 4654 | this.cleanup(); 4655 | // mark as open 4656 | this._readyState = "open"; 4657 | this.emitReserved("open"); 4658 | // add new subs 4659 | var socket = this.engine; 4660 | 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)), 4661 | // @ts-ignore 4662 | on(this.decoder, "decoded", this.ondecoded.bind(this))); 4663 | } 4664 | /** 4665 | * Called upon a ping. 4666 | * 4667 | * @private 4668 | */; 4669 | _proto.onping = function onping() { 4670 | this.emitReserved("ping"); 4671 | } 4672 | /** 4673 | * Called with data. 4674 | * 4675 | * @private 4676 | */; 4677 | _proto.ondata = function ondata(data) { 4678 | try { 4679 | this.decoder.add(data); 4680 | } catch (e) { 4681 | this.onclose("parse error", e); 4682 | } 4683 | } 4684 | /** 4685 | * Called when parser fully decodes a packet. 4686 | * 4687 | * @private 4688 | */; 4689 | _proto.ondecoded = function ondecoded(packet) { 4690 | var _this3 = this; 4691 | // the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a "parse error" 4692 | nextTick(function () { 4693 | _this3.emitReserved("packet", packet); 4694 | }, this.setTimeoutFn); 4695 | } 4696 | /** 4697 | * Called upon socket error. 4698 | * 4699 | * @private 4700 | */; 4701 | _proto.onerror = function onerror(err) { 4702 | debug$1("error", err); 4703 | this.emitReserved("error", err); 4704 | } 4705 | /** 4706 | * Creates a new socket for the given `nsp`. 4707 | * 4708 | * @return {Socket} 4709 | * @public 4710 | */; 4711 | _proto.socket = function socket(nsp, opts) { 4712 | var socket = this.nsps[nsp]; 4713 | if (!socket) { 4714 | socket = new Socket(this, nsp, opts); 4715 | this.nsps[nsp] = socket; 4716 | } else if (this._autoConnect && !socket.active) { 4717 | socket.connect(); 4718 | } 4719 | return socket; 4720 | } 4721 | /** 4722 | * Called upon a socket close. 4723 | * 4724 | * @param socket 4725 | * @private 4726 | */; 4727 | _proto._destroy = function _destroy(socket) { 4728 | var nsps = Object.keys(this.nsps); 4729 | for (var _i = 0, _nsps = nsps; _i < _nsps.length; _i++) { 4730 | var nsp = _nsps[_i]; 4731 | var _socket = this.nsps[nsp]; 4732 | if (_socket.active) { 4733 | debug$1("socket %s is still active, skipping close", nsp); 4734 | return; 4735 | } 4736 | } 4737 | this._close(); 4738 | } 4739 | /** 4740 | * Writes a packet. 4741 | * 4742 | * @param packet 4743 | * @private 4744 | */; 4745 | _proto._packet = function _packet(packet) { 4746 | debug$1("writing packet %j", packet); 4747 | var encodedPackets = this.encoder.encode(packet); 4748 | for (var i = 0; i < encodedPackets.length; i++) { 4749 | this.engine.write(encodedPackets[i], packet.options); 4750 | } 4751 | } 4752 | /** 4753 | * Clean up transport subscriptions and packet buffer. 4754 | * 4755 | * @private 4756 | */; 4757 | _proto.cleanup = function cleanup() { 4758 | debug$1("cleanup"); 4759 | this.subs.forEach(function (subDestroy) { 4760 | return subDestroy(); 4761 | }); 4762 | this.subs.length = 0; 4763 | this.decoder.destroy(); 4764 | } 4765 | /** 4766 | * Close the current socket. 4767 | * 4768 | * @private 4769 | */; 4770 | _proto._close = function _close() { 4771 | debug$1("disconnect"); 4772 | this.skipReconnect = true; 4773 | this._reconnecting = false; 4774 | this.onclose("forced close"); 4775 | } 4776 | /** 4777 | * Alias for close() 4778 | * 4779 | * @private 4780 | */; 4781 | _proto.disconnect = function disconnect() { 4782 | return this._close(); 4783 | } 4784 | /** 4785 | * Called when: 4786 | * 4787 | * - the low-level engine is closed 4788 | * - the parser encountered a badly formatted packet 4789 | * - all sockets are disconnected 4790 | * 4791 | * @private 4792 | */; 4793 | _proto.onclose = function onclose(reason, description) { 4794 | var _a; 4795 | debug$1("closed due to %s", reason); 4796 | this.cleanup(); 4797 | (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close(); 4798 | this.backoff.reset(); 4799 | this._readyState = "closed"; 4800 | this.emitReserved("close", reason, description); 4801 | if (this._reconnection && !this.skipReconnect) { 4802 | this.reconnect(); 4803 | } 4804 | } 4805 | /** 4806 | * Attempt a reconnection. 4807 | * 4808 | * @private 4809 | */; 4810 | _proto.reconnect = function reconnect() { 4811 | var _this4 = this; 4812 | if (this._reconnecting || this.skipReconnect) return this; 4813 | var self = this; 4814 | if (this.backoff.attempts >= this._reconnectionAttempts) { 4815 | debug$1("reconnect failed"); 4816 | this.backoff.reset(); 4817 | this.emitReserved("reconnect_failed"); 4818 | this._reconnecting = false; 4819 | } else { 4820 | var delay = this.backoff.duration(); 4821 | debug$1("will wait %dms before reconnect attempt", delay); 4822 | this._reconnecting = true; 4823 | var timer = this.setTimeoutFn(function () { 4824 | if (self.skipReconnect) return; 4825 | debug$1("attempting reconnect"); 4826 | _this4.emitReserved("reconnect_attempt", self.backoff.attempts); 4827 | // check again for the case socket closed in above events 4828 | if (self.skipReconnect) return; 4829 | self.open(function (err) { 4830 | if (err) { 4831 | debug$1("reconnect attempt error"); 4832 | self._reconnecting = false; 4833 | self.reconnect(); 4834 | _this4.emitReserved("reconnect_error", err); 4835 | } else { 4836 | debug$1("reconnect success"); 4837 | self.onreconnect(); 4838 | } 4839 | }); 4840 | }, delay); 4841 | if (this.opts.autoUnref) { 4842 | timer.unref(); 4843 | } 4844 | this.subs.push(function () { 4845 | _this4.clearTimeoutFn(timer); 4846 | }); 4847 | } 4848 | } 4849 | /** 4850 | * Called upon successful reconnect. 4851 | * 4852 | * @private 4853 | */; 4854 | _proto.onreconnect = function onreconnect() { 4855 | var attempt = this.backoff.attempts; 4856 | this._reconnecting = false; 4857 | this.backoff.reset(); 4858 | this.emitReserved("reconnect", attempt); 4859 | }; 4860 | return Manager; 4861 | }(Emitter); 4862 | 4863 | var debug = debugModule("socket.io-client"); // debug() 4864 | /** 4865 | * Managers cache. 4866 | */ 4867 | var cache = {}; 4868 | function lookup(uri, opts) { 4869 | if (_typeof(uri) === "object") { 4870 | opts = uri; 4871 | uri = undefined; 4872 | } 4873 | opts = opts || {}; 4874 | var parsed = url(uri, opts.path || "/socket.io"); 4875 | var source = parsed.source; 4876 | var id = parsed.id; 4877 | var path = parsed.path; 4878 | var sameNamespace = cache[id] && path in cache[id]["nsps"]; 4879 | var newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace; 4880 | var io; 4881 | if (newConnection) { 4882 | debug("ignoring socket cache for %s", source); 4883 | io = new Manager(source, opts); 4884 | } else { 4885 | if (!cache[id]) { 4886 | debug("new io instance for %s", source); 4887 | cache[id] = new Manager(source, opts); 4888 | } 4889 | io = cache[id]; 4890 | } 4891 | if (parsed.query && !opts.query) { 4892 | opts.query = parsed.queryKey; 4893 | } 4894 | return io.socket(parsed.path, opts); 4895 | } 4896 | // so that "lookup" can be used both as a function (e.g. `io(...)`) and as a 4897 | // namespace (e.g. `io.connect(...)`), for backward compatibility 4898 | _extends(lookup, { 4899 | Manager: Manager, 4900 | Socket: Socket, 4901 | io: lookup, 4902 | connect: lookup 4903 | }); 4904 | 4905 | return lookup; 4906 | 4907 | })); 4908 | //# sourceMappingURL=socket.io.js.map 4909 | ```