@stacks/blockchain-api-client 7.1.1 → 7.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.umd.js CHANGED
@@ -376,7 +376,7 @@
376
376
  }, check);
377
377
  }
378
378
 
379
- var BASE_PATH = "https://stacks-node-api.mainnet.stacks.co".replace(/\/+$/, "");
379
+ var BASE_PATH = "https://api.mainnet.hiro.so".replace(/\/+$/, "");
380
380
 
381
381
  var isBlob = function isBlob(value) {
382
382
  return typeof Blob !== 'undefined' && value instanceof Blob;
@@ -5849,6 +5849,7 @@
5849
5849
  'server_version': !exists(json, 'server_version') ? undefined : json['server_version'],
5850
5850
  'status': json['status'],
5851
5851
  'pox_v1_unlock_height': !exists(json, 'pox_v1_unlock_height') ? undefined : json['pox_v1_unlock_height'],
5852
+ 'pox_v2_unlock_height': !exists(json, 'pox_v2_unlock_height') ? undefined : json['pox_v2_unlock_height'],
5852
5853
  'chain_tip': !exists(json, 'chain_tip') ? undefined : ChainTipFromJSON(json['chain_tip'])
5853
5854
  };
5854
5855
  }
@@ -5865,6 +5866,7 @@
5865
5866
  'server_version': value.server_version,
5866
5867
  'status': value.status,
5867
5868
  'pox_v1_unlock_height': value.pox_v1_unlock_height,
5869
+ 'pox_v2_unlock_height': value.pox_v2_unlock_height,
5868
5870
  'chain_tip': ChainTipToJSON(value.chain_tip)
5869
5871
  };
5870
5872
  }
@@ -7325,7 +7327,7 @@
7325
7327
  }
7326
7328
  }
7327
7329
  /**
7328
- * Add 500 STX tokens to the specified testnet address. Testnet STX addresses begin with `ST`. If the `stacking` parameter is set to `true`, the faucet will add the required number of tokens for individual stacking to the specified testnet address. The endpoint returns the transaction ID, which you can use to view the transaction in the [Stacks Explorer](https://explorer.stacks.co/?chain=testnet). The tokens are delivered once the transaction has been included in an anchor block. A common reason for failed faucet transactions is that the faucet has run out of tokens. If you are experiencing failed faucet transactions to a testnet address, you can get help in [Discord](https://stacks.chat). **Note:** This is a testnet only endpoint. This endpoint will not work on the mainnet.
7330
+ * Add 500 STX tokens to the specified testnet address. Testnet STX addresses begin with `ST`. If the `stacking` parameter is set to `true`, the faucet will add the required number of tokens for individual stacking to the specified testnet address. The endpoint returns the transaction ID, which you can use to view the transaction in the [Stacks Explorer](https://explorer.hiro.so/?chain=testnet). The tokens are delivered once the transaction has been included in an anchor block. A common reason for failed faucet transactions is that the faucet has run out of tokens. If you are experiencing failed faucet transactions to a testnet address, you can get help in [Discord](https://stacks.chat). **Note:** This is a testnet only endpoint. This endpoint will not work on the mainnet.
7329
7331
  * Get STX testnet tokens
7330
7332
  */
7331
7333
  ;
@@ -7366,7 +7368,7 @@
7366
7368
  }
7367
7369
  }
7368
7370
  /**
7369
- * Add 500 STX tokens to the specified testnet address. Testnet STX addresses begin with `ST`. If the `stacking` parameter is set to `true`, the faucet will add the required number of tokens for individual stacking to the specified testnet address. The endpoint returns the transaction ID, which you can use to view the transaction in the [Stacks Explorer](https://explorer.stacks.co/?chain=testnet). The tokens are delivered once the transaction has been included in an anchor block. A common reason for failed faucet transactions is that the faucet has run out of tokens. If you are experiencing failed faucet transactions to a testnet address, you can get help in [Discord](https://stacks.chat). **Note:** This is a testnet only endpoint. This endpoint will not work on the mainnet.
7371
+ * Add 500 STX tokens to the specified testnet address. Testnet STX addresses begin with `ST`. If the `stacking` parameter is set to `true`, the faucet will add the required number of tokens for individual stacking to the specified testnet address. The endpoint returns the transaction ID, which you can use to view the transaction in the [Stacks Explorer](https://explorer.hiro.so/?chain=testnet). The tokens are delivered once the transaction has been included in an anchor block. A common reason for failed faucet transactions is that the faucet has run out of tokens. If you are experiencing failed faucet transactions to a testnet address, you can get help in [Discord](https://stacks.chat). **Note:** This is a testnet only endpoint. This endpoint will not work on the mainnet.
7370
7372
  * Get STX testnet tokens
7371
7373
  */
7372
7374
  ;
@@ -7550,7 +7552,7 @@
7550
7552
  var _proto = FungibleTokensApi.prototype;
7551
7553
 
7552
7554
  /**
7553
- * Retrieves the metadata for fungible tokens for a given contract id
7555
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves the metadata for fungible tokens for a given contract id
7554
7556
  * Fungible tokens metadata for contract id
7555
7557
  */
7556
7558
  _proto.getContractFtMetadataRaw = function getContractFtMetadataRaw(requestParameters, initOverrides) {
@@ -7578,7 +7580,7 @@
7578
7580
  }
7579
7581
  }
7580
7582
  /**
7581
- * Retrieves the metadata for fungible tokens for a given contract id
7583
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves the metadata for fungible tokens for a given contract id
7582
7584
  * Fungible tokens metadata for contract id
7583
7585
  */
7584
7586
  ;
@@ -7595,7 +7597,7 @@
7595
7597
  }
7596
7598
  }
7597
7599
  /**
7598
- * Retrieves list of fungible tokens with their metadata. More information on Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#fungible-tokens).
7600
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves list of fungible tokens with their metadata. More information on Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#fungible-tokens).
7599
7601
  * Fungible tokens metadata list
7600
7602
  */
7601
7603
  ;
@@ -7630,7 +7632,7 @@
7630
7632
  }
7631
7633
  }
7632
7634
  /**
7633
- * Retrieves list of fungible tokens with their metadata. More information on Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#fungible-tokens).
7635
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves list of fungible tokens with their metadata. More information on Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#fungible-tokens).
7634
7636
  * Fungible tokens metadata list
7635
7637
  */
7636
7638
  ;
@@ -8729,7 +8731,7 @@
8729
8731
  var _proto = NonFungibleTokensApi.prototype;
8730
8732
 
8731
8733
  /**
8732
- * Retrieves metadata for non fungible tokens for a given contract id. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8734
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves metadata for non fungible tokens for a given contract id. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8733
8735
  * Non fungible tokens metadata for contract ID
8734
8736
  */
8735
8737
  _proto.getContractNftMetadataRaw = function getContractNftMetadataRaw(requestParameters, initOverrides) {
@@ -8757,7 +8759,7 @@
8757
8759
  }
8758
8760
  }
8759
8761
  /**
8760
- * Retrieves metadata for non fungible tokens for a given contract id. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8762
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves metadata for non fungible tokens for a given contract id. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8761
8763
  * Non fungible tokens metadata for contract ID
8762
8764
  */
8763
8765
  ;
@@ -8922,7 +8924,7 @@
8922
8924
  }
8923
8925
  }
8924
8926
  /**
8925
- * Retrieves a list of non fungible tokens with their metadata. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8927
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves a list of non fungible tokens with their metadata. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8926
8928
  * Non fungible tokens metadata list
8927
8929
  */
8928
8930
  ;
@@ -8957,7 +8959,7 @@
8957
8959
  }
8958
8960
  }
8959
8961
  /**
8960
- * Retrieves a list of non fungible tokens with their metadata. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8962
+ * **NOTE:** This endpoint is deprecated in favor of the [Token Metadata Service](https://github.com/hirosystems/token-metadata-service). Retrieves a list of non fungible tokens with their metadata. More information on Non-Fungible Tokens on the Stacks blockchain can be found [here](https://docs.stacks.co/write-smart-contracts/tokens#non-fungible-tokens-nfts).
8961
8963
  * Non fungible tokens metadata list
8962
8964
  */
8963
8965
  ;
@@ -11441,7 +11443,7 @@
11441
11443
  validateMessage(object, true);
11442
11444
  return object;
11443
11445
  }
11444
- function parse(message) {
11446
+ function parse$1(message) {
11445
11447
  if (!isString(message)) {
11446
11448
  return new JsonRpcParsed(JsonRpcError.invalidRequest(message), "invalid" /* invalid */);
11447
11449
  }
@@ -12043,7 +12045,7 @@
12043
12045
  this.eventEmitter = new eventemitter3.EventEmitter();
12044
12046
  this.webSocket = webSocket;
12045
12047
  webSocket.addEventListener('message', function (event) {
12046
- var parsed = parse(event.data);
12048
+ var parsed = parse$1(event.data);
12047
12049
  var rpcObjects = Array.isArray(parsed) ? parsed : [parsed];
12048
12050
  rpcObjects.forEach(function (obj) {
12049
12051
  if (obj.type === "notification"
@@ -12410,209 +12412,164 @@
12410
12412
  }
12411
12413
  }
12412
12414
 
12413
- /**
12414
- * Parses an URI
12415
- *
12416
- * @author Steven Levithan <stevenlevithan.com> (MIT license)
12417
- * @api private
12418
- */
12419
- var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
12420
-
12421
- var parts = [
12422
- 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
12423
- ];
12424
-
12425
- var parseuri = function parseuri(str) {
12426
- var src = str,
12427
- b = str.indexOf('['),
12428
- e = str.indexOf(']');
12429
-
12430
- if (b != -1 && e != -1) {
12431
- str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
12432
- }
12433
-
12434
- var m = re.exec(str || ''),
12435
- uri = {},
12436
- i = 14;
12437
-
12438
- while (i--) {
12439
- uri[parts[i]] = m[i] || '';
12440
- }
12441
-
12442
- if (b != -1 && e != -1) {
12443
- uri.source = src;
12444
- uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
12445
- uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
12446
- uri.ipv6uri = true;
12447
- }
12448
-
12449
- uri.pathNames = pathNames(uri, uri['path']);
12450
- uri.queryKey = queryKey(uri, uri['query']);
12415
+ const PACKET_TYPES = Object.create(null); // no Map = no polyfill
12416
+ PACKET_TYPES["open"] = "0";
12417
+ PACKET_TYPES["close"] = "1";
12418
+ PACKET_TYPES["ping"] = "2";
12419
+ PACKET_TYPES["pong"] = "3";
12420
+ PACKET_TYPES["message"] = "4";
12421
+ PACKET_TYPES["upgrade"] = "5";
12422
+ PACKET_TYPES["noop"] = "6";
12423
+ const PACKET_TYPES_REVERSE = Object.create(null);
12424
+ Object.keys(PACKET_TYPES).forEach(key => {
12425
+ PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
12426
+ });
12427
+ const ERROR_PACKET = { type: "error", data: "parser error" };
12451
12428
 
12452
- return uri;
12429
+ const withNativeBlob$1 = typeof Blob === "function" ||
12430
+ (typeof Blob !== "undefined" &&
12431
+ Object.prototype.toString.call(Blob) === "[object BlobConstructor]");
12432
+ const withNativeArrayBuffer$2 = typeof ArrayBuffer === "function";
12433
+ // ArrayBuffer.isView method is not defined in IE10
12434
+ const isView$1 = obj => {
12435
+ return typeof ArrayBuffer.isView === "function"
12436
+ ? ArrayBuffer.isView(obj)
12437
+ : obj && obj.buffer instanceof ArrayBuffer;
12453
12438
  };
12454
-
12455
- function pathNames(obj, path) {
12456
- var regx = /\/{2,9}/g,
12457
- names = path.replace(regx, "/").split("/");
12458
-
12459
- if (path.substr(0, 1) == '/' || path.length === 0) {
12460
- names.splice(0, 1);
12461
- }
12462
- if (path.substr(path.length - 1, 1) == '/') {
12463
- names.splice(names.length - 1, 1);
12464
- }
12465
-
12466
- return names;
12467
- }
12468
-
12469
- function queryKey(uri, query) {
12470
- var data = {};
12471
-
12472
- query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
12473
- if ($1) {
12474
- data[$1] = $2;
12475
- }
12476
- });
12477
-
12478
- return data;
12479
- }
12480
-
12481
- /**
12482
- * URL parser.
12483
- *
12484
- * @param uri - url
12485
- * @param path - the request path of the connection
12486
- * @param loc - An object meant to mimic window.location.
12487
- * Defaults to window.location.
12488
- * @public
12489
- */
12490
- function url(uri, path = "", loc) {
12491
- let obj = uri;
12492
- // default to window.location
12493
- loc = loc || (typeof location !== "undefined" && location);
12494
- if (null == uri)
12495
- uri = loc.protocol + "//" + loc.host;
12496
- // relative path support
12497
- if (typeof uri === "string") {
12498
- if ("/" === uri.charAt(0)) {
12499
- if ("/" === uri.charAt(1)) {
12500
- uri = loc.protocol + uri;
12501
- }
12502
- else {
12503
- uri = loc.host + uri;
12504
- }
12439
+ const encodePacket = ({ type, data }, supportsBinary, callback) => {
12440
+ if (withNativeBlob$1 && data instanceof Blob) {
12441
+ if (supportsBinary) {
12442
+ return callback(data);
12505
12443
  }
12506
- if (!/^(https?|wss?):\/\//.test(uri)) {
12507
- if ("undefined" !== typeof loc) {
12508
- uri = loc.protocol + "//" + uri;
12509
- }
12510
- else {
12511
- uri = "https://" + uri;
12512
- }
12444
+ else {
12445
+ return encodeBlobAsBase64(data, callback);
12513
12446
  }
12514
- // parse
12515
- obj = parseuri(uri);
12516
12447
  }
12517
- // make sure we treat `localhost:80` and `localhost` equally
12518
- if (!obj.port) {
12519
- if (/^(http|ws)$/.test(obj.protocol)) {
12520
- obj.port = "80";
12448
+ else if (withNativeArrayBuffer$2 &&
12449
+ (data instanceof ArrayBuffer || isView$1(data))) {
12450
+ if (supportsBinary) {
12451
+ return callback(data);
12521
12452
  }
12522
- else if (/^(http|ws)s$/.test(obj.protocol)) {
12523
- obj.port = "443";
12453
+ else {
12454
+ return encodeBlobAsBase64(new Blob([data]), callback);
12524
12455
  }
12525
12456
  }
12526
- obj.path = obj.path || "/";
12527
- const ipv6 = obj.host.indexOf(":") !== -1;
12528
- const host = ipv6 ? "[" + obj.host + "]" : obj.host;
12529
- // define unique id
12530
- obj.id = obj.protocol + "://" + host + ":" + obj.port + path;
12531
- // define href
12532
- obj.href =
12533
- obj.protocol +
12534
- "://" +
12535
- host +
12536
- (loc && loc.port === obj.port ? "" : ":" + obj.port);
12537
- return obj;
12538
- }
12539
-
12540
- var hasCors = createCommonjsModule(function (module) {
12541
- /**
12542
- * Module exports.
12543
- *
12544
- * Logic borrowed from Modernizr:
12545
- *
12546
- * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
12547
- */
12457
+ // plain string
12458
+ return callback(PACKET_TYPES[type] + (data || ""));
12459
+ };
12460
+ const encodeBlobAsBase64 = (data, callback) => {
12461
+ const fileReader = new FileReader();
12462
+ fileReader.onload = function () {
12463
+ const content = fileReader.result.split(",")[1];
12464
+ callback("b" + (content || ""));
12465
+ };
12466
+ return fileReader.readAsDataURL(data);
12467
+ };
12548
12468
 
12549
- try {
12550
- module.exports = typeof XMLHttpRequest !== 'undefined' &&
12551
- 'withCredentials' in new XMLHttpRequest();
12552
- } catch (err) {
12553
- // if XMLHttp support is disabled in IE then it will throw
12554
- // when trying to create
12555
- module.exports = false;
12469
+ // imported from https://github.com/socketio/base64-arraybuffer
12470
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
12471
+ // Use a lookup table to find the index.
12472
+ const lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
12473
+ for (let i = 0; i < chars.length; i++) {
12474
+ lookup$1[chars.charCodeAt(i)] = i;
12556
12475
  }
12557
- });
12558
-
12559
- var globalThis = (() => {
12560
- if (typeof self !== "undefined") {
12561
- return self;
12562
- }
12563
- else if (typeof window !== "undefined") {
12564
- return window;
12476
+ const decode$1 = (base64) => {
12477
+ let bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
12478
+ if (base64[base64.length - 1] === '=') {
12479
+ bufferLength--;
12480
+ if (base64[base64.length - 2] === '=') {
12481
+ bufferLength--;
12482
+ }
12565
12483
  }
12566
- else {
12567
- return Function("return this")();
12484
+ const arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
12485
+ for (i = 0; i < len; i += 4) {
12486
+ encoded1 = lookup$1[base64.charCodeAt(i)];
12487
+ encoded2 = lookup$1[base64.charCodeAt(i + 1)];
12488
+ encoded3 = lookup$1[base64.charCodeAt(i + 2)];
12489
+ encoded4 = lookup$1[base64.charCodeAt(i + 3)];
12490
+ bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
12491
+ bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
12492
+ bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
12568
12493
  }
12569
- })();
12494
+ return arraybuffer;
12495
+ };
12570
12496
 
12571
- // browser shim for xmlhttprequest module
12572
- function XMLHttpRequest$1 (opts) {
12573
- const xdomain = opts.xdomain;
12574
- // XMLHttpRequest can be disabled on IE
12575
- try {
12576
- if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCors)) {
12577
- return new XMLHttpRequest();
12578
- }
12497
+ const withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
12498
+ const decodePacket = (encodedPacket, binaryType) => {
12499
+ if (typeof encodedPacket !== "string") {
12500
+ return {
12501
+ type: "message",
12502
+ data: mapBinary(encodedPacket, binaryType)
12503
+ };
12579
12504
  }
12580
- catch (e) { }
12581
- if (!xdomain) {
12582
- try {
12583
- return new globalThis[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
12584
- }
12585
- catch (e) { }
12505
+ const type = encodedPacket.charAt(0);
12506
+ if (type === "b") {
12507
+ return {
12508
+ type: "message",
12509
+ data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
12510
+ };
12586
12511
  }
12587
- }
12588
-
12589
- function pick(obj, ...attr) {
12590
- return attr.reduce((acc, k) => {
12591
- if (obj.hasOwnProperty(k)) {
12592
- acc[k] = obj[k];
12512
+ const packetType = PACKET_TYPES_REVERSE[type];
12513
+ if (!packetType) {
12514
+ return ERROR_PACKET;
12515
+ }
12516
+ return encodedPacket.length > 1
12517
+ ? {
12518
+ type: PACKET_TYPES_REVERSE[type],
12519
+ data: encodedPacket.substring(1)
12593
12520
  }
12594
- return acc;
12595
- }, {});
12596
- }
12597
- // Keep a reference to the real timeout functions so they can be used when overridden
12598
- const NATIVE_SET_TIMEOUT = setTimeout;
12599
- const NATIVE_CLEAR_TIMEOUT = clearTimeout;
12600
- function installTimerFunctions(obj, opts) {
12601
- if (opts.useNativeTimers) {
12602
- obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis);
12603
- obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis);
12521
+ : {
12522
+ type: PACKET_TYPES_REVERSE[type]
12523
+ };
12524
+ };
12525
+ const decodeBase64Packet = (data, binaryType) => {
12526
+ if (withNativeArrayBuffer$1) {
12527
+ const decoded = decode$1(data);
12528
+ return mapBinary(decoded, binaryType);
12604
12529
  }
12605
12530
  else {
12606
- obj.setTimeoutFn = setTimeout.bind(globalThis);
12607
- obj.clearTimeoutFn = clearTimeout.bind(globalThis);
12531
+ return { base64: true, data }; // fallback for old browsers
12608
12532
  }
12609
- }
12610
-
12611
- /**
12612
- * Expose `Emitter`.
12613
- */
12533
+ };
12534
+ const mapBinary = (data, binaryType) => {
12535
+ switch (binaryType) {
12536
+ case "blob":
12537
+ return data instanceof ArrayBuffer ? new Blob([data]) : data;
12538
+ case "arraybuffer":
12539
+ default:
12540
+ return data; // assuming the data is already an ArrayBuffer
12541
+ }
12542
+ };
12614
12543
 
12615
- var Emitter_1 = Emitter;
12544
+ const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
12545
+ const encodePayload = (packets, callback) => {
12546
+ // some packets may be added to the array while encoding, so the initial length must be saved
12547
+ const length = packets.length;
12548
+ const encodedPackets = new Array(length);
12549
+ let count = 0;
12550
+ packets.forEach((packet, i) => {
12551
+ // force base64 encoding for binary packets
12552
+ encodePacket(packet, false, encodedPacket => {
12553
+ encodedPackets[i] = encodedPacket;
12554
+ if (++count === length) {
12555
+ callback(encodedPackets.join(SEPARATOR));
12556
+ }
12557
+ });
12558
+ });
12559
+ };
12560
+ const decodePayload = (encodedPayload, binaryType) => {
12561
+ const encodedPackets = encodedPayload.split(SEPARATOR);
12562
+ const packets = [];
12563
+ for (let i = 0; i < encodedPackets.length; i++) {
12564
+ const decodedPacket = decodePacket(encodedPackets[i], binaryType);
12565
+ packets.push(decodedPacket);
12566
+ if (decodedPacket.type === "error") {
12567
+ break;
12568
+ }
12569
+ }
12570
+ return packets;
12571
+ };
12572
+ const protocol$1 = 4;
12616
12573
 
12617
12574
  /**
12618
12575
  * Initialize a new `Emitter`.
@@ -12784,175 +12741,84 @@
12784
12741
  return !! this.listeners(event).length;
12785
12742
  };
12786
12743
 
12787
- const PACKET_TYPES = Object.create(null); // no Map = no polyfill
12788
- PACKET_TYPES["open"] = "0";
12789
- PACKET_TYPES["close"] = "1";
12790
- PACKET_TYPES["ping"] = "2";
12791
- PACKET_TYPES["pong"] = "3";
12792
- PACKET_TYPES["message"] = "4";
12793
- PACKET_TYPES["upgrade"] = "5";
12794
- PACKET_TYPES["noop"] = "6";
12795
- const PACKET_TYPES_REVERSE = Object.create(null);
12796
- Object.keys(PACKET_TYPES).forEach(key => {
12797
- PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
12798
- });
12799
- const ERROR_PACKET = { type: "error", data: "parser error" };
12800
-
12801
- const withNativeBlob$1 = typeof Blob === "function" ||
12802
- (typeof Blob !== "undefined" &&
12803
- Object.prototype.toString.call(Blob) === "[object BlobConstructor]");
12804
- const withNativeArrayBuffer$2 = typeof ArrayBuffer === "function";
12805
- // ArrayBuffer.isView method is not defined in IE10
12806
- const isView$1 = obj => {
12807
- return typeof ArrayBuffer.isView === "function"
12808
- ? ArrayBuffer.isView(obj)
12809
- : obj && obj.buffer instanceof ArrayBuffer;
12810
- };
12811
- const encodePacket = ({ type, data }, supportsBinary, callback) => {
12812
- if (withNativeBlob$1 && data instanceof Blob) {
12813
- if (supportsBinary) {
12814
- return callback(data);
12815
- }
12816
- else {
12817
- return encodeBlobAsBase64(data, callback);
12818
- }
12819
- }
12820
- else if (withNativeArrayBuffer$2 &&
12821
- (data instanceof ArrayBuffer || isView$1(data))) {
12822
- if (supportsBinary) {
12823
- return callback(data);
12824
- }
12825
- else {
12826
- return encodeBlobAsBase64(new Blob([data]), callback);
12827
- }
12744
+ const globalThisShim = (() => {
12745
+ if (typeof self !== "undefined") {
12746
+ return self;
12828
12747
  }
12829
- // plain string
12830
- return callback(PACKET_TYPES[type] + (data || ""));
12831
- };
12832
- const encodeBlobAsBase64 = (data, callback) => {
12833
- const fileReader = new FileReader();
12834
- fileReader.onload = function () {
12835
- const content = fileReader.result.split(",")[1];
12836
- callback("b" + content);
12837
- };
12838
- return fileReader.readAsDataURL(data);
12839
- };
12840
-
12841
- /*
12842
- * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
12843
- * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
12844
- * Released under MIT License
12845
- */
12846
- var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
12847
- // Use a lookup table to find the index.
12848
- var lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
12849
- for (var i$1 = 0; i$1 < chars.length; i$1++) {
12850
- lookup$1[chars.charCodeAt(i$1)] = i$1;
12851
- }
12852
- var decode$2 = function (base64) {
12853
- var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
12854
- if (base64[base64.length - 1] === '=') {
12855
- bufferLength--;
12856
- if (base64[base64.length - 2] === '=') {
12857
- bufferLength--;
12858
- }
12748
+ else if (typeof window !== "undefined") {
12749
+ return window;
12859
12750
  }
12860
- var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
12861
- for (i = 0; i < len; i += 4) {
12862
- encoded1 = lookup$1[base64.charCodeAt(i)];
12863
- encoded2 = lookup$1[base64.charCodeAt(i + 1)];
12864
- encoded3 = lookup$1[base64.charCodeAt(i + 2)];
12865
- encoded4 = lookup$1[base64.charCodeAt(i + 3)];
12866
- bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
12867
- bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
12868
- bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
12751
+ else {
12752
+ return Function("return this")();
12869
12753
  }
12870
- return arraybuffer;
12871
- };
12754
+ })();
12872
12755
 
12873
- const withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
12874
- const decodePacket = (encodedPacket, binaryType) => {
12875
- if (typeof encodedPacket !== "string") {
12876
- return {
12877
- type: "message",
12878
- data: mapBinary(encodedPacket, binaryType)
12879
- };
12880
- }
12881
- const type = encodedPacket.charAt(0);
12882
- if (type === "b") {
12883
- return {
12884
- type: "message",
12885
- data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
12886
- };
12887
- }
12888
- const packetType = PACKET_TYPES_REVERSE[type];
12889
- if (!packetType) {
12890
- return ERROR_PACKET;
12891
- }
12892
- return encodedPacket.length > 1
12893
- ? {
12894
- type: PACKET_TYPES_REVERSE[type],
12895
- data: encodedPacket.substring(1)
12756
+ function pick(obj, ...attr) {
12757
+ return attr.reduce((acc, k) => {
12758
+ if (obj.hasOwnProperty(k)) {
12759
+ acc[k] = obj[k];
12896
12760
  }
12897
- : {
12898
- type: PACKET_TYPES_REVERSE[type]
12899
- };
12900
- };
12901
- const decodeBase64Packet = (data, binaryType) => {
12902
- if (withNativeArrayBuffer$1) {
12903
- const decoded = decode$2(data);
12904
- return mapBinary(decoded, binaryType);
12761
+ return acc;
12762
+ }, {});
12763
+ }
12764
+ // Keep a reference to the real timeout functions so they can be used when overridden
12765
+ const NATIVE_SET_TIMEOUT = globalThisShim.setTimeout;
12766
+ const NATIVE_CLEAR_TIMEOUT = globalThisShim.clearTimeout;
12767
+ function installTimerFunctions(obj, opts) {
12768
+ if (opts.useNativeTimers) {
12769
+ obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThisShim);
12770
+ obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThisShim);
12905
12771
  }
12906
12772
  else {
12907
- return { base64: true, data }; // fallback for old browsers
12908
- }
12909
- };
12910
- const mapBinary = (data, binaryType) => {
12911
- switch (binaryType) {
12912
- case "blob":
12913
- return data instanceof ArrayBuffer ? new Blob([data]) : data;
12914
- case "arraybuffer":
12915
- default:
12916
- return data; // assuming the data is already an ArrayBuffer
12917
- }
12918
- };
12919
-
12920
- const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
12921
- const encodePayload = (packets, callback) => {
12922
- // some packets may be added to the array while encoding, so the initial length must be saved
12923
- const length = packets.length;
12924
- const encodedPackets = new Array(length);
12925
- let count = 0;
12926
- packets.forEach((packet, i) => {
12927
- // force base64 encoding for binary packets
12928
- encodePacket(packet, false, encodedPacket => {
12929
- encodedPackets[i] = encodedPacket;
12930
- if (++count === length) {
12931
- callback(encodedPackets.join(SEPARATOR));
12932
- }
12933
- });
12934
- });
12935
- };
12936
- const decodePayload = (encodedPayload, binaryType) => {
12937
- const encodedPackets = encodedPayload.split(SEPARATOR);
12938
- const packets = [];
12939
- for (let i = 0; i < encodedPackets.length; i++) {
12940
- const decodedPacket = decodePacket(encodedPackets[i], binaryType);
12941
- packets.push(decodedPacket);
12942
- if (decodedPacket.type === "error") {
12943
- break;
12773
+ obj.setTimeoutFn = globalThisShim.setTimeout.bind(globalThisShim);
12774
+ obj.clearTimeoutFn = globalThisShim.clearTimeout.bind(globalThisShim);
12775
+ }
12776
+ }
12777
+ // base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)
12778
+ const BASE64_OVERHEAD = 1.33;
12779
+ // we could also have used `new Blob([obj]).size`, but it isn't supported in IE9
12780
+ function byteLength(obj) {
12781
+ if (typeof obj === "string") {
12782
+ return utf8Length(obj);
12783
+ }
12784
+ // arraybuffer or blob
12785
+ return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD);
12786
+ }
12787
+ function utf8Length(str) {
12788
+ let c = 0, length = 0;
12789
+ for (let i = 0, l = str.length; i < l; i++) {
12790
+ c = str.charCodeAt(i);
12791
+ if (c < 0x80) {
12792
+ length += 1;
12793
+ }
12794
+ else if (c < 0x800) {
12795
+ length += 2;
12796
+ }
12797
+ else if (c < 0xd800 || c >= 0xe000) {
12798
+ length += 3;
12799
+ }
12800
+ else {
12801
+ i++;
12802
+ length += 4;
12944
12803
  }
12945
12804
  }
12946
- return packets;
12947
- };
12948
- const protocol$1 = 4;
12805
+ return length;
12806
+ }
12949
12807
 
12950
- class Transport extends Emitter_1 {
12808
+ class TransportError extends Error {
12809
+ constructor(reason, description, context) {
12810
+ super(reason);
12811
+ this.description = description;
12812
+ this.context = context;
12813
+ this.type = "TransportError";
12814
+ }
12815
+ }
12816
+ class Transport extends Emitter {
12951
12817
  /**
12952
12818
  * Transport abstract constructor.
12953
12819
  *
12954
- * @param {Object} options.
12955
- * @api private
12820
+ * @param {Object} opts - options
12821
+ * @protected
12956
12822
  */
12957
12823
  constructor(opts) {
12958
12824
  super();
@@ -12960,44 +12826,34 @@
12960
12826
  installTimerFunctions(this, opts);
12961
12827
  this.opts = opts;
12962
12828
  this.query = opts.query;
12963
- this.readyState = "";
12964
12829
  this.socket = opts.socket;
12965
12830
  }
12966
12831
  /**
12967
12832
  * Emits an error.
12968
12833
  *
12969
- * @param {String} str
12834
+ * @param {String} reason
12835
+ * @param description
12836
+ * @param context - the error context
12970
12837
  * @return {Transport} for chaining
12971
- * @api protected
12838
+ * @protected
12972
12839
  */
12973
- onError(msg, desc) {
12974
- const err = new Error(msg);
12975
- // @ts-ignore
12976
- err.type = "TransportError";
12977
- // @ts-ignore
12978
- err.description = desc;
12979
- super.emit("error", err);
12840
+ onError(reason, description, context) {
12841
+ super.emitReserved("error", new TransportError(reason, description, context));
12980
12842
  return this;
12981
12843
  }
12982
12844
  /**
12983
12845
  * Opens the transport.
12984
- *
12985
- * @api public
12986
12846
  */
12987
12847
  open() {
12988
- if ("closed" === this.readyState || "" === this.readyState) {
12989
- this.readyState = "opening";
12990
- this.doOpen();
12991
- }
12848
+ this.readyState = "opening";
12849
+ this.doOpen();
12992
12850
  return this;
12993
12851
  }
12994
12852
  /**
12995
12853
  * Closes the transport.
12996
- *
12997
- * @api public
12998
12854
  */
12999
12855
  close() {
13000
- if ("opening" === this.readyState || "open" === this.readyState) {
12856
+ if (this.readyState === "opening" || this.readyState === "open") {
13001
12857
  this.doClose();
13002
12858
  this.onClose();
13003
12859
  }
@@ -13007,28 +12863,27 @@
13007
12863
  * Sends multiple packets.
13008
12864
  *
13009
12865
  * @param {Array} packets
13010
- * @api public
13011
12866
  */
13012
12867
  send(packets) {
13013
- if ("open" === this.readyState) {
12868
+ if (this.readyState === "open") {
13014
12869
  this.write(packets);
13015
12870
  }
13016
12871
  }
13017
12872
  /**
13018
12873
  * Called upon open
13019
12874
  *
13020
- * @api protected
12875
+ * @protected
13021
12876
  */
13022
12877
  onOpen() {
13023
12878
  this.readyState = "open";
13024
12879
  this.writable = true;
13025
- super.emit("open");
12880
+ super.emitReserved("open");
13026
12881
  }
13027
12882
  /**
13028
12883
  * Called with data.
13029
12884
  *
13030
12885
  * @param {String} data
13031
- * @api protected
12886
+ * @protected
13032
12887
  */
13033
12888
  onData(data) {
13034
12889
  const packet = decodePacket(data, this.socket.binaryType);
@@ -13037,64 +12892,46 @@
13037
12892
  /**
13038
12893
  * Called with a decoded packet.
13039
12894
  *
13040
- * @api protected
12895
+ * @protected
13041
12896
  */
13042
12897
  onPacket(packet) {
13043
- super.emit("packet", packet);
12898
+ super.emitReserved("packet", packet);
13044
12899
  }
13045
12900
  /**
13046
12901
  * Called upon close.
13047
12902
  *
13048
- * @api protected
12903
+ * @protected
13049
12904
  */
13050
- onClose() {
12905
+ onClose(details) {
13051
12906
  this.readyState = "closed";
13052
- super.emit("close");
12907
+ super.emitReserved("close", details);
13053
12908
  }
12909
+ /**
12910
+ * Pauses the transport, in order not to lose packets during an upgrade.
12911
+ *
12912
+ * @param onPause
12913
+ */
12914
+ pause(onPause) { }
13054
12915
  }
13055
12916
 
13056
- var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('')
13057
- , length = 64
13058
- , map = {}
13059
- , seed = 0
13060
- , i = 0
13061
- , prev;
13062
-
12917
+ // imported from https://github.com/unshiftio/yeast
12918
+ const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
12919
+ let seed = 0, i = 0, prev;
13063
12920
  /**
13064
12921
  * Return a string representing the specified number.
13065
12922
  *
13066
12923
  * @param {Number} num The number to convert.
13067
12924
  * @returns {String} The string representation of the number.
13068
- * @api public
13069
- */
13070
- function encode$1(num) {
13071
- var encoded = '';
13072
-
13073
- do {
13074
- encoded = alphabet[num % length] + encoded;
13075
- num = Math.floor(num / length);
13076
- } while (num > 0);
13077
-
13078
- return encoded;
13079
- }
13080
-
13081
- /**
13082
- * Return the integer value specified by the given string.
13083
- *
13084
- * @param {String} str The string to convert.
13085
- * @returns {Number} The integer value represented by the string.
13086
- * @api public
13087
- */
13088
- function decode$1(str) {
13089
- var decoded = 0;
13090
-
13091
- for (i = 0; i < str.length; i++) {
13092
- decoded = decoded * length + map[str.charAt(i)];
13093
- }
13094
-
13095
- return decoded;
12925
+ * @api public
12926
+ */
12927
+ function encode$1(num) {
12928
+ let encoded = '';
12929
+ do {
12930
+ encoded = alphabet[num % length] + encoded;
12931
+ num = Math.floor(num / length);
12932
+ } while (num > 0);
12933
+ return encoded;
13096
12934
  }
13097
-
13098
12935
  /**
13099
12936
  * Yeast: A tiny growing id generator.
13100
12937
  *
@@ -13102,24 +12939,18 @@
13102
12939
  * @api public
13103
12940
  */
13104
12941
  function yeast() {
13105
- var now = encode$1(+new Date());
13106
-
13107
- if (now !== prev) return seed = 0, prev = now;
13108
- return now +'.'+ encode$1(seed++);
12942
+ const now = encode$1(+new Date());
12943
+ if (now !== prev)
12944
+ return seed = 0, prev = now;
12945
+ return now + '.' + encode$1(seed++);
13109
12946
  }
13110
-
13111
12947
  //
13112
12948
  // Map each character to its index.
13113
12949
  //
13114
- for (; i < length; i++) map[alphabet[i]] = i;
13115
-
13116
- //
13117
- // Expose the `yeast`, `encode` and `decode` functions.
13118
- //
13119
- yeast.encode = encode$1;
13120
- yeast.decode = decode$1;
13121
- var yeast_1 = yeast;
12950
+ for (; i < length; i++)
12951
+ map[alphabet[i]] = i;
13122
12952
 
12953
+ // imported from https://github.com/galkn/querystring
13123
12954
  /**
13124
12955
  * Compiles a querystring
13125
12956
  * Returns string representation of the object
@@ -13127,49 +12958,99 @@
13127
12958
  * @param {Object}
13128
12959
  * @api private
13129
12960
  */
13130
- var encode = function (obj) {
13131
- var str = '';
13132
-
13133
- for (var i in obj) {
13134
- if (obj.hasOwnProperty(i)) {
13135
- if (str.length) str += '&';
13136
- str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
12961
+ function encode(obj) {
12962
+ let str = '';
12963
+ for (let i in obj) {
12964
+ if (obj.hasOwnProperty(i)) {
12965
+ if (str.length)
12966
+ str += '&';
12967
+ str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
12968
+ }
13137
12969
  }
13138
- }
13139
-
13140
- return str;
13141
- };
13142
-
12970
+ return str;
12971
+ }
13143
12972
  /**
13144
12973
  * Parses a simple querystring into an object
13145
12974
  *
13146
12975
  * @param {String} qs
13147
12976
  * @api private
13148
12977
  */
12978
+ function decode(qs) {
12979
+ let qry = {};
12980
+ let pairs = qs.split('&');
12981
+ for (let i = 0, l = pairs.length; i < l; i++) {
12982
+ let pair = pairs[i].split('=');
12983
+ qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
12984
+ }
12985
+ return qry;
12986
+ }
13149
12987
 
13150
- var decode = function(qs){
13151
- var qry = {};
13152
- var pairs = qs.split('&');
13153
- for (var i = 0, l = pairs.length; i < l; i++) {
13154
- var pair = pairs[i].split('=');
13155
- qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
13156
- }
13157
- return qry;
13158
- };
12988
+ // imported from https://github.com/component/has-cors
12989
+ let value = false;
12990
+ try {
12991
+ value = typeof XMLHttpRequest !== 'undefined' &&
12992
+ 'withCredentials' in new XMLHttpRequest();
12993
+ }
12994
+ catch (err) {
12995
+ // if XMLHttp support is disabled in IE then it will throw
12996
+ // when trying to create
12997
+ }
12998
+ const hasCORS = value;
13159
12999
 
13160
- var parseqs = {
13161
- encode: encode,
13162
- decode: decode
13163
- };
13000
+ // browser shim for xmlhttprequest module
13001
+ function XHR(opts) {
13002
+ const xdomain = opts.xdomain;
13003
+ // XMLHttpRequest can be disabled on IE
13004
+ try {
13005
+ if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
13006
+ return new XMLHttpRequest();
13007
+ }
13008
+ }
13009
+ catch (e) { }
13010
+ if (!xdomain) {
13011
+ try {
13012
+ return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
13013
+ }
13014
+ catch (e) { }
13015
+ }
13016
+ }
13164
13017
 
13018
+ function empty() { }
13019
+ const hasXHR2 = (function () {
13020
+ const xhr = new XHR({
13021
+ xdomain: false,
13022
+ });
13023
+ return null != xhr.responseType;
13024
+ })();
13165
13025
  class Polling extends Transport {
13166
- constructor() {
13167
- super(...arguments);
13168
- this.polling = false;
13169
- }
13170
13026
  /**
13171
- * Transport name.
13027
+ * XHR Polling constructor.
13028
+ *
13029
+ * @param {Object} opts
13030
+ * @package
13172
13031
  */
13032
+ constructor(opts) {
13033
+ super(opts);
13034
+ this.polling = false;
13035
+ if (typeof location !== "undefined") {
13036
+ const isSSL = "https:" === location.protocol;
13037
+ let port = location.port;
13038
+ // some user agents have empty `location.port`
13039
+ if (!port) {
13040
+ port = isSSL ? "443" : "80";
13041
+ }
13042
+ this.xd =
13043
+ (typeof location !== "undefined" &&
13044
+ opts.hostname !== location.hostname) ||
13045
+ port !== opts.port;
13046
+ this.xs = opts.secure !== isSSL;
13047
+ }
13048
+ /**
13049
+ * XHR supports binary
13050
+ */
13051
+ const forceBase64 = opts && opts.forceBase64;
13052
+ this.supportsBinary = hasXHR2 && !forceBase64;
13053
+ }
13173
13054
  get name() {
13174
13055
  return "polling";
13175
13056
  }
@@ -13177,7 +13058,7 @@
13177
13058
  * Opens the socket (triggers polling). We write a PING message to determine
13178
13059
  * when the transport is open.
13179
13060
  *
13180
- * @api private
13061
+ * @protected
13181
13062
  */
13182
13063
  doOpen() {
13183
13064
  this.poll();
@@ -13185,8 +13066,8 @@
13185
13066
  /**
13186
13067
  * Pauses polling.
13187
13068
  *
13188
- * @param {Function} callback upon buffers are flushed and transport is paused
13189
- * @api private
13069
+ * @param {Function} onPause - callback upon buffers are flushed and transport is paused
13070
+ * @package
13190
13071
  */
13191
13072
  pause(onPause) {
13192
13073
  this.readyState = "pausing";
@@ -13216,27 +13097,27 @@
13216
13097
  /**
13217
13098
  * Starts polling cycle.
13218
13099
  *
13219
- * @api public
13100
+ * @private
13220
13101
  */
13221
13102
  poll() {
13222
13103
  this.polling = true;
13223
13104
  this.doPoll();
13224
- this.emit("poll");
13105
+ this.emitReserved("poll");
13225
13106
  }
13226
13107
  /**
13227
13108
  * Overloads onData to detect payloads.
13228
13109
  *
13229
- * @api private
13110
+ * @protected
13230
13111
  */
13231
13112
  onData(data) {
13232
- const callback = packet => {
13113
+ const callback = (packet) => {
13233
13114
  // if its the first message we consider the transport open
13234
13115
  if ("opening" === this.readyState && packet.type === "open") {
13235
13116
  this.onOpen();
13236
13117
  }
13237
13118
  // if its a close packet, we close the ongoing requests
13238
13119
  if ("close" === packet.type) {
13239
- this.onClose();
13120
+ this.onClose({ description: "transport closed by the server" });
13240
13121
  return false;
13241
13122
  }
13242
13123
  // otherwise bypass onData and handle the message
@@ -13248,7 +13129,7 @@
13248
13129
  if ("closed" !== this.readyState) {
13249
13130
  // if we got data we're not polling
13250
13131
  this.polling = false;
13251
- this.emit("pollComplete");
13132
+ this.emitReserved("pollComplete");
13252
13133
  if ("open" === this.readyState) {
13253
13134
  this.poll();
13254
13135
  }
@@ -13257,7 +13138,7 @@
13257
13138
  /**
13258
13139
  * For polling, send a close packet.
13259
13140
  *
13260
- * @api private
13141
+ * @protected
13261
13142
  */
13262
13143
  doClose() {
13263
13144
  const close = () => {
@@ -13275,23 +13156,22 @@
13275
13156
  /**
13276
13157
  * Writes a packets payload.
13277
13158
  *
13278
- * @param {Array} data packets
13279
- * @param {Function} drain callback
13280
- * @api private
13159
+ * @param {Array} packets - data packets
13160
+ * @protected
13281
13161
  */
13282
13162
  write(packets) {
13283
13163
  this.writable = false;
13284
- encodePayload(packets, data => {
13164
+ encodePayload(packets, (data) => {
13285
13165
  this.doWrite(data, () => {
13286
13166
  this.writable = true;
13287
- this.emit("drain");
13167
+ this.emitReserved("drain");
13288
13168
  });
13289
13169
  });
13290
13170
  }
13291
13171
  /**
13292
13172
  * Generates uri for connection.
13293
13173
  *
13294
- * @api private
13174
+ * @private
13295
13175
  */
13296
13176
  uri() {
13297
13177
  let query = this.query || {};
@@ -13299,7 +13179,7 @@
13299
13179
  let port = "";
13300
13180
  // cache busting is forced
13301
13181
  if (false !== this.opts.timestampRequests) {
13302
- query[this.opts.timestampParam] = yeast_1();
13182
+ query[this.opts.timestampParam] = yeast();
13303
13183
  }
13304
13184
  if (!this.supportsBinary && !query.sid) {
13305
13185
  query.b64 = 1;
@@ -13310,7 +13190,7 @@
13310
13190
  ("http" === schema && Number(this.opts.port) !== 80))) {
13311
13191
  port = ":" + this.opts.port;
13312
13192
  }
13313
- const encodedQuery = parseqs.encode(query);
13193
+ const encodedQuery = encode(query);
13314
13194
  const ipv6 = this.opts.hostname.indexOf(":") !== -1;
13315
13195
  return (schema +
13316
13196
  "://" +
@@ -13319,52 +13199,11 @@
13319
13199
  this.opts.path +
13320
13200
  (encodedQuery.length ? "?" + encodedQuery : ""));
13321
13201
  }
13322
- }
13323
-
13324
- /* global attachEvent */
13325
- /**
13326
- * Empty function
13327
- */
13328
- function empty() { }
13329
- const hasXHR2 = (function () {
13330
- const xhr = new XMLHttpRequest$1({
13331
- xdomain: false
13332
- });
13333
- return null != xhr.responseType;
13334
- })();
13335
- class XHR extends Polling {
13336
- /**
13337
- * XHR Polling constructor.
13338
- *
13339
- * @param {Object} opts
13340
- * @api public
13341
- */
13342
- constructor(opts) {
13343
- super(opts);
13344
- if (typeof location !== "undefined") {
13345
- const isSSL = "https:" === location.protocol;
13346
- let port = location.port;
13347
- // some user agents have empty `location.port`
13348
- if (!port) {
13349
- port = isSSL ? "443" : "80";
13350
- }
13351
- this.xd =
13352
- (typeof location !== "undefined" &&
13353
- opts.hostname !== location.hostname) ||
13354
- port !== opts.port;
13355
- this.xs = opts.secure !== isSSL;
13356
- }
13357
- /**
13358
- * XHR supports binary
13359
- */
13360
- const forceBase64 = opts && opts.forceBase64;
13361
- this.supportsBinary = hasXHR2 && !forceBase64;
13362
- }
13363
13202
  /**
13364
13203
  * Creates a request.
13365
13204
  *
13366
13205
  * @param {String} method
13367
- * @api private
13206
+ * @private
13368
13207
  */
13369
13208
  request(opts = {}) {
13370
13209
  Object.assign(opts, { xd: this.xd, xs: this.xs }, this.opts);
@@ -13375,38 +13214,38 @@
13375
13214
  *
13376
13215
  * @param {String} data to send.
13377
13216
  * @param {Function} called upon flush.
13378
- * @api private
13217
+ * @private
13379
13218
  */
13380
13219
  doWrite(data, fn) {
13381
13220
  const req = this.request({
13382
13221
  method: "POST",
13383
- data: data
13222
+ data: data,
13384
13223
  });
13385
13224
  req.on("success", fn);
13386
- req.on("error", err => {
13387
- this.onError("xhr post error", err);
13225
+ req.on("error", (xhrStatus, context) => {
13226
+ this.onError("xhr post error", xhrStatus, context);
13388
13227
  });
13389
13228
  }
13390
13229
  /**
13391
13230
  * Starts a poll cycle.
13392
13231
  *
13393
- * @api private
13232
+ * @private
13394
13233
  */
13395
13234
  doPoll() {
13396
13235
  const req = this.request();
13397
13236
  req.on("data", this.onData.bind(this));
13398
- req.on("error", err => {
13399
- this.onError("xhr poll error", err);
13237
+ req.on("error", (xhrStatus, context) => {
13238
+ this.onError("xhr poll error", xhrStatus, context);
13400
13239
  });
13401
13240
  this.pollXhr = req;
13402
13241
  }
13403
13242
  }
13404
- class Request extends Emitter_1 {
13243
+ class Request extends Emitter {
13405
13244
  /**
13406
13245
  * Request constructor
13407
13246
  *
13408
13247
  * @param {Object} options
13409
- * @api public
13248
+ * @package
13410
13249
  */
13411
13250
  constructor(uri, opts) {
13412
13251
  super();
@@ -13421,13 +13260,13 @@
13421
13260
  /**
13422
13261
  * Creates the XHR object and sends the request.
13423
13262
  *
13424
- * @api private
13263
+ * @private
13425
13264
  */
13426
13265
  create() {
13427
13266
  const opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
13428
13267
  opts.xdomain = !!this.opts.xd;
13429
13268
  opts.xscheme = !!this.opts.xs;
13430
- const xhr = (this.xhr = new XMLHttpRequest$1(opts));
13269
+ const xhr = (this.xhr = new XHR(opts));
13431
13270
  try {
13432
13271
  xhr.open(this.method, this.uri, this.async);
13433
13272
  try {
@@ -13488,37 +13327,19 @@
13488
13327
  Request.requests[this.index] = this;
13489
13328
  }
13490
13329
  }
13491
- /**
13492
- * Called upon successful response.
13493
- *
13494
- * @api private
13495
- */
13496
- onSuccess() {
13497
- this.emit("success");
13498
- this.cleanup();
13499
- }
13500
- /**
13501
- * Called if we have data.
13502
- *
13503
- * @api private
13504
- */
13505
- onData(data) {
13506
- this.emit("data", data);
13507
- this.onSuccess();
13508
- }
13509
13330
  /**
13510
13331
  * Called upon error.
13511
13332
  *
13512
- * @api private
13333
+ * @private
13513
13334
  */
13514
13335
  onError(err) {
13515
- this.emit("error", err);
13336
+ this.emitReserved("error", err, this.xhr);
13516
13337
  this.cleanup(true);
13517
13338
  }
13518
13339
  /**
13519
13340
  * Cleans up house.
13520
13341
  *
13521
- * @api private
13342
+ * @private
13522
13343
  */
13523
13344
  cleanup(fromError) {
13524
13345
  if ("undefined" === typeof this.xhr || null === this.xhr) {
@@ -13539,18 +13360,20 @@
13539
13360
  /**
13540
13361
  * Called upon load.
13541
13362
  *
13542
- * @api private
13363
+ * @private
13543
13364
  */
13544
13365
  onLoad() {
13545
13366
  const data = this.xhr.responseText;
13546
13367
  if (data !== null) {
13547
- this.onData(data);
13368
+ this.emitReserved("data", data);
13369
+ this.emitReserved("success");
13370
+ this.cleanup();
13548
13371
  }
13549
13372
  }
13550
13373
  /**
13551
13374
  * Aborts the request.
13552
13375
  *
13553
- * @api public
13376
+ * @package
13554
13377
  */
13555
13378
  abort() {
13556
13379
  this.cleanup();
@@ -13570,7 +13393,7 @@
13570
13393
  attachEvent("onunload", unloadHandler);
13571
13394
  }
13572
13395
  else if (typeof addEventListener === "function") {
13573
- const terminationEvent = "onpagehide" in globalThis ? "pagehide" : "unload";
13396
+ const terminationEvent = "onpagehide" in globalThisShim ? "pagehide" : "unload";
13574
13397
  addEventListener(terminationEvent, unloadHandler, false);
13575
13398
  }
13576
13399
  }
@@ -13585,13 +13408,13 @@
13585
13408
  const nextTick = (() => {
13586
13409
  const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
13587
13410
  if (isPromiseAvailable) {
13588
- return cb => Promise.resolve().then(cb);
13411
+ return (cb) => Promise.resolve().then(cb);
13589
13412
  }
13590
13413
  else {
13591
13414
  return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
13592
13415
  }
13593
13416
  })();
13594
- const WebSocket$1 = globalThis.WebSocket || globalThis.MozWebSocket;
13417
+ const WebSocket$1 = globalThisShim.WebSocket || globalThisShim.MozWebSocket;
13595
13418
  const usingBrowserWebSocket = true;
13596
13419
  const defaultBinaryType = "arraybuffer";
13597
13420
 
@@ -13603,26 +13426,16 @@
13603
13426
  /**
13604
13427
  * WebSocket transport constructor.
13605
13428
  *
13606
- * @api {Object} connection options
13607
- * @api public
13429
+ * @param {Object} opts - connection options
13430
+ * @protected
13608
13431
  */
13609
13432
  constructor(opts) {
13610
13433
  super(opts);
13611
13434
  this.supportsBinary = !opts.forceBase64;
13612
13435
  }
13613
- /**
13614
- * Transport name.
13615
- *
13616
- * @api public
13617
- */
13618
13436
  get name() {
13619
13437
  return "websocket";
13620
13438
  }
13621
- /**
13622
- * Opens socket.
13623
- *
13624
- * @api private
13625
- */
13626
13439
  doOpen() {
13627
13440
  if (!this.check()) {
13628
13441
  // let probe timeout
@@ -13646,7 +13459,7 @@
13646
13459
  : new WebSocket$1(uri, protocols, opts);
13647
13460
  }
13648
13461
  catch (err) {
13649
- return this.emit("error", err);
13462
+ return this.emitReserved("error", err);
13650
13463
  }
13651
13464
  this.ws.binaryType = this.socket.binaryType || defaultBinaryType;
13652
13465
  this.addEventListeners();
@@ -13654,7 +13467,7 @@
13654
13467
  /**
13655
13468
  * Adds event listeners to the socket
13656
13469
  *
13657
- * @api private
13470
+ * @private
13658
13471
  */
13659
13472
  addEventListeners() {
13660
13473
  this.ws.onopen = () => {
@@ -13663,16 +13476,13 @@
13663
13476
  }
13664
13477
  this.onOpen();
13665
13478
  };
13666
- this.ws.onclose = this.onClose.bind(this);
13667
- this.ws.onmessage = ev => this.onData(ev.data);
13668
- this.ws.onerror = e => this.onError("websocket error", e);
13479
+ this.ws.onclose = (closeEvent) => this.onClose({
13480
+ description: "websocket connection closed",
13481
+ context: closeEvent,
13482
+ });
13483
+ this.ws.onmessage = (ev) => this.onData(ev.data);
13484
+ this.ws.onerror = (e) => this.onError("websocket error", e);
13669
13485
  }
13670
- /**
13671
- * Writes data to socket.
13672
- *
13673
- * @param {Array} array of packets.
13674
- * @api private
13675
- */
13676
13486
  write(packets) {
13677
13487
  this.writable = false;
13678
13488
  // encodePacket efficient as it uses WS framing
@@ -13680,7 +13490,7 @@
13680
13490
  for (let i = 0; i < packets.length; i++) {
13681
13491
  const packet = packets[i];
13682
13492
  const lastPacket = i === packets.length - 1;
13683
- encodePacket(packet, this.supportsBinary, data => {
13493
+ encodePacket(packet, this.supportsBinary, (data) => {
13684
13494
  // always create a new object (GH-437)
13685
13495
  const opts = {};
13686
13496
  // Sometimes the websocket has already been closed but the browser didn't
@@ -13699,17 +13509,12 @@
13699
13509
  // defer to next tick to allow Socket to clear writeBuffer
13700
13510
  nextTick(() => {
13701
13511
  this.writable = true;
13702
- this.emit("drain");
13512
+ this.emitReserved("drain");
13703
13513
  }, this.setTimeoutFn);
13704
13514
  }
13705
13515
  });
13706
13516
  }
13707
13517
  }
13708
- /**
13709
- * Closes socket.
13710
- *
13711
- * @api private
13712
- */
13713
13518
  doClose() {
13714
13519
  if (typeof this.ws !== "undefined") {
13715
13520
  this.ws.close();
@@ -13719,7 +13524,7 @@
13719
13524
  /**
13720
13525
  * Generates uri for connection.
13721
13526
  *
13722
- * @api private
13527
+ * @private
13723
13528
  */
13724
13529
  uri() {
13725
13530
  let query = this.query || {};
@@ -13733,13 +13538,13 @@
13733
13538
  }
13734
13539
  // append timestamp to URI
13735
13540
  if (this.opts.timestampRequests) {
13736
- query[this.opts.timestampParam] = yeast_1();
13541
+ query[this.opts.timestampParam] = yeast();
13737
13542
  }
13738
13543
  // communicate binary support capabilities
13739
13544
  if (!this.supportsBinary) {
13740
13545
  query.b64 = 1;
13741
13546
  }
13742
- const encodedQuery = parseqs.encode(query);
13547
+ const encodedQuery = encode(query);
13743
13548
  const ipv6 = this.opts.hostname.indexOf(":") !== -1;
13744
13549
  return (schema +
13745
13550
  "://" +
@@ -13752,35 +13557,96 @@
13752
13557
  * Feature detection for WebSocket.
13753
13558
  *
13754
13559
  * @return {Boolean} whether this transport is available.
13755
- * @api public
13560
+ * @private
13756
13561
  */
13757
13562
  check() {
13758
- return (!!WebSocket$1 &&
13759
- !("__initialize" in WebSocket$1 && this.name === WS.prototype.name));
13563
+ return !!WebSocket$1;
13760
13564
  }
13761
13565
  }
13762
13566
 
13763
13567
  const transports = {
13764
13568
  websocket: WS,
13765
- polling: XHR
13569
+ polling: Polling,
13766
13570
  };
13767
13571
 
13768
- class Socket$1 extends Emitter_1 {
13572
+ // imported from https://github.com/galkn/parseuri
13573
+ /**
13574
+ * Parses a URI
13575
+ *
13576
+ * Note: we could also have used the built-in URL object, but it isn't supported on all platforms.
13577
+ *
13578
+ * See:
13579
+ * - https://developer.mozilla.org/en-US/docs/Web/API/URL
13580
+ * - https://caniuse.com/url
13581
+ * - https://www.rfc-editor.org/rfc/rfc3986#appendix-B
13582
+ *
13583
+ * History of the parse() method:
13584
+ * - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c
13585
+ * - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3
13586
+ * - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242
13587
+ *
13588
+ * @author Steven Levithan <stevenlevithan.com> (MIT license)
13589
+ * @api private
13590
+ */
13591
+ const re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
13592
+ const parts = [
13593
+ 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
13594
+ ];
13595
+ function parse(str) {
13596
+ const src = str, b = str.indexOf('['), e = str.indexOf(']');
13597
+ if (b != -1 && e != -1) {
13598
+ str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
13599
+ }
13600
+ let m = re.exec(str || ''), uri = {}, i = 14;
13601
+ while (i--) {
13602
+ uri[parts[i]] = m[i] || '';
13603
+ }
13604
+ if (b != -1 && e != -1) {
13605
+ uri.source = src;
13606
+ uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
13607
+ uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
13608
+ uri.ipv6uri = true;
13609
+ }
13610
+ uri.pathNames = pathNames(uri, uri['path']);
13611
+ uri.queryKey = queryKey(uri, uri['query']);
13612
+ return uri;
13613
+ }
13614
+ function pathNames(obj, path) {
13615
+ const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
13616
+ if (path.slice(0, 1) == '/' || path.length === 0) {
13617
+ names.splice(0, 1);
13618
+ }
13619
+ if (path.slice(-1) == '/') {
13620
+ names.splice(names.length - 1, 1);
13621
+ }
13622
+ return names;
13623
+ }
13624
+ function queryKey(uri, query) {
13625
+ const data = {};
13626
+ query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
13627
+ if ($1) {
13628
+ data[$1] = $2;
13629
+ }
13630
+ });
13631
+ return data;
13632
+ }
13633
+
13634
+ class Socket$1 extends Emitter {
13769
13635
  /**
13770
13636
  * Socket constructor.
13771
13637
  *
13772
- * @param {String|Object} uri or options
13638
+ * @param {String|Object} uri - uri or options
13773
13639
  * @param {Object} opts - options
13774
- * @api public
13775
13640
  */
13776
13641
  constructor(uri, opts = {}) {
13777
13642
  super();
13643
+ this.writeBuffer = [];
13778
13644
  if (uri && "object" === typeof uri) {
13779
13645
  opts = uri;
13780
13646
  uri = null;
13781
13647
  }
13782
13648
  if (uri) {
13783
- uri = parseuri(uri);
13649
+ uri = parse(uri);
13784
13650
  opts.hostname = uri.host;
13785
13651
  opts.secure = uri.protocol === "https" || uri.protocol === "wss";
13786
13652
  opts.port = uri.port;
@@ -13788,7 +13654,7 @@
13788
13654
  opts.query = uri.query;
13789
13655
  }
13790
13656
  else if (opts.host) {
13791
- opts.hostname = parseuri(opts.host).host;
13657
+ opts.hostname = parse(opts.host).host;
13792
13658
  }
13793
13659
  installTimerFunctions(this, opts);
13794
13660
  this.secure =
@@ -13810,7 +13676,6 @@
13810
13676
  ? "443"
13811
13677
  : "80");
13812
13678
  this.transports = opts.transports || ["polling", "websocket"];
13813
- this.readyState = "";
13814
13679
  this.writeBuffer = [];
13815
13680
  this.prevBufferLen = 0;
13816
13681
  this.opts = Object.assign({
@@ -13820,16 +13685,19 @@
13820
13685
  upgrade: true,
13821
13686
  timestampParam: "t",
13822
13687
  rememberUpgrade: false,
13688
+ addTrailingSlash: true,
13823
13689
  rejectUnauthorized: true,
13824
13690
  perMessageDeflate: {
13825
- threshold: 1024
13691
+ threshold: 1024,
13826
13692
  },
13827
13693
  transportOptions: {},
13828
- closeOnBeforeunload: true
13694
+ closeOnBeforeunload: true,
13829
13695
  }, opts);
13830
- this.opts.path = this.opts.path.replace(/\/$/, "") + "/";
13696
+ this.opts.path =
13697
+ this.opts.path.replace(/\/$/, "") +
13698
+ (this.opts.addTrailingSlash ? "/" : "");
13831
13699
  if (typeof this.opts.query === "string") {
13832
- this.opts.query = parseqs.decode(this.opts.query);
13700
+ this.opts.query = decode(this.opts.query);
13833
13701
  }
13834
13702
  // set on handshake
13835
13703
  this.id = null;
@@ -13843,17 +13711,20 @@
13843
13711
  // Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
13844
13712
  // ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
13845
13713
  // closed/reloaded)
13846
- addEventListener("beforeunload", () => {
13714
+ this.beforeunloadEventListener = () => {
13847
13715
  if (this.transport) {
13848
13716
  // silently close the transport
13849
13717
  this.transport.removeAllListeners();
13850
13718
  this.transport.close();
13851
13719
  }
13852
- }, false);
13720
+ };
13721
+ addEventListener("beforeunload", this.beforeunloadEventListener, false);
13853
13722
  }
13854
13723
  if (this.hostname !== "localhost") {
13855
13724
  this.offlineEventListener = () => {
13856
- this.onClose("transport close");
13725
+ this.onClose("transport close", {
13726
+ description: "network connection lost",
13727
+ });
13857
13728
  };
13858
13729
  addEventListener("offline", this.offlineEventListener, false);
13859
13730
  }
@@ -13863,12 +13734,12 @@
13863
13734
  /**
13864
13735
  * Creates transport of the given type.
13865
13736
  *
13866
- * @param {String} transport name
13737
+ * @param {String} name - transport name
13867
13738
  * @return {Transport}
13868
- * @api private
13739
+ * @private
13869
13740
  */
13870
13741
  createTransport(name) {
13871
- const query = clone(this.opts.query);
13742
+ const query = Object.assign({}, this.opts.query);
13872
13743
  // append engine.io protocol identifier
13873
13744
  query.EIO = protocol$1;
13874
13745
  // transport name
@@ -13881,14 +13752,14 @@
13881
13752
  socket: this,
13882
13753
  hostname: this.hostname,
13883
13754
  secure: this.secure,
13884
- port: this.port
13755
+ port: this.port,
13885
13756
  });
13886
13757
  return new transports[name](opts);
13887
13758
  }
13888
13759
  /**
13889
13760
  * Initializes transport to use and starts probe.
13890
13761
  *
13891
- * @api private
13762
+ * @private
13892
13763
  */
13893
13764
  open() {
13894
13765
  let transport;
@@ -13923,7 +13794,7 @@
13923
13794
  /**
13924
13795
  * Sets the current transport. Disables the existing one (if any).
13925
13796
  *
13926
- * @api private
13797
+ * @private
13927
13798
  */
13928
13799
  setTransport(transport) {
13929
13800
  if (this.transport) {
@@ -13936,15 +13807,13 @@
13936
13807
  .on("drain", this.onDrain.bind(this))
13937
13808
  .on("packet", this.onPacket.bind(this))
13938
13809
  .on("error", this.onError.bind(this))
13939
- .on("close", () => {
13940
- this.onClose("transport close");
13941
- });
13810
+ .on("close", (reason) => this.onClose("transport close", reason));
13942
13811
  }
13943
13812
  /**
13944
13813
  * Probes a transport.
13945
13814
  *
13946
- * @param {String} transport name
13947
- * @api private
13815
+ * @param {String} name - transport name
13816
+ * @private
13948
13817
  */
13949
13818
  probe(name) {
13950
13819
  let transport = this.createTransport(name);
@@ -13954,7 +13823,7 @@
13954
13823
  if (failed)
13955
13824
  return;
13956
13825
  transport.send([{ type: "ping", data: "probe" }]);
13957
- transport.once("packet", msg => {
13826
+ transport.once("packet", (msg) => {
13958
13827
  if (failed)
13959
13828
  return;
13960
13829
  if ("pong" === msg.type && "probe" === msg.data) {
@@ -13995,7 +13864,7 @@
13995
13864
  transport = null;
13996
13865
  }
13997
13866
  // Handle any error that happens while probing
13998
- const onerror = err => {
13867
+ const onerror = (err) => {
13999
13868
  const error = new Error("probe error: " + err);
14000
13869
  // @ts-ignore
14001
13870
  error.transport = transport.name;
@@ -14033,7 +13902,7 @@
14033
13902
  /**
14034
13903
  * Called when connection is deemed open.
14035
13904
  *
14036
- * @api private
13905
+ * @private
14037
13906
  */
14038
13907
  onOpen() {
14039
13908
  this.readyState = "open";
@@ -14042,9 +13911,7 @@
14042
13911
  this.flush();
14043
13912
  // we check for `readyState` in case an `open`
14044
13913
  // listener already closed the socket
14045
- if ("open" === this.readyState &&
14046
- this.opts.upgrade &&
14047
- this.transport.pause) {
13914
+ if ("open" === this.readyState && this.opts.upgrade) {
14048
13915
  let i = 0;
14049
13916
  const l = this.upgrades.length;
14050
13917
  for (; i < l; i++) {
@@ -14055,7 +13922,7 @@
14055
13922
  /**
14056
13923
  * Handles a packet.
14057
13924
  *
14058
- * @api private
13925
+ * @private
14059
13926
  */
14060
13927
  onPacket(packet) {
14061
13928
  if ("opening" === this.readyState ||
@@ -14091,7 +13958,7 @@
14091
13958
  * Called upon handshake completion.
14092
13959
  *
14093
13960
  * @param {Object} data - handshake obj
14094
- * @api private
13961
+ * @private
14095
13962
  */
14096
13963
  onHandshake(data) {
14097
13964
  this.emitReserved("handshake", data);
@@ -14100,6 +13967,7 @@
14100
13967
  this.upgrades = this.filterUpgrades(data.upgrades);
14101
13968
  this.pingInterval = data.pingInterval;
14102
13969
  this.pingTimeout = data.pingTimeout;
13970
+ this.maxPayload = data.maxPayload;
14103
13971
  this.onOpen();
14104
13972
  // In case open handler closes socket
14105
13973
  if ("closed" === this.readyState)
@@ -14109,7 +13977,7 @@
14109
13977
  /**
14110
13978
  * Sets and resets ping timeout timer based on server pings.
14111
13979
  *
14112
- * @api private
13980
+ * @private
14113
13981
  */
14114
13982
  resetPingTimeout() {
14115
13983
  this.clearTimeoutFn(this.pingTimeoutTimer);
@@ -14123,7 +13991,7 @@
14123
13991
  /**
14124
13992
  * Called on `drain` event
14125
13993
  *
14126
- * @api private
13994
+ * @private
14127
13995
  */
14128
13996
  onDrain() {
14129
13997
  this.writeBuffer.splice(0, this.prevBufferLen);
@@ -14141,28 +14009,54 @@
14141
14009
  /**
14142
14010
  * Flush write buffers.
14143
14011
  *
14144
- * @api private
14012
+ * @private
14145
14013
  */
14146
14014
  flush() {
14147
14015
  if ("closed" !== this.readyState &&
14148
14016
  this.transport.writable &&
14149
14017
  !this.upgrading &&
14150
14018
  this.writeBuffer.length) {
14151
- this.transport.send(this.writeBuffer);
14019
+ const packets = this.getWritablePackets();
14020
+ this.transport.send(packets);
14152
14021
  // keep track of current length of writeBuffer
14153
14022
  // splice writeBuffer and callbackBuffer on `drain`
14154
- this.prevBufferLen = this.writeBuffer.length;
14023
+ this.prevBufferLen = packets.length;
14155
14024
  this.emitReserved("flush");
14156
14025
  }
14157
14026
  }
14027
+ /**
14028
+ * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
14029
+ * long-polling)
14030
+ *
14031
+ * @private
14032
+ */
14033
+ getWritablePackets() {
14034
+ const shouldCheckPayloadSize = this.maxPayload &&
14035
+ this.transport.name === "polling" &&
14036
+ this.writeBuffer.length > 1;
14037
+ if (!shouldCheckPayloadSize) {
14038
+ return this.writeBuffer;
14039
+ }
14040
+ let payloadSize = 1; // first packet type
14041
+ for (let i = 0; i < this.writeBuffer.length; i++) {
14042
+ const data = this.writeBuffer[i].data;
14043
+ if (data) {
14044
+ payloadSize += byteLength(data);
14045
+ }
14046
+ if (i > 0 && payloadSize > this.maxPayload) {
14047
+ return this.writeBuffer.slice(0, i);
14048
+ }
14049
+ payloadSize += 2; // separator + packet type
14050
+ }
14051
+ return this.writeBuffer;
14052
+ }
14158
14053
  /**
14159
14054
  * Sends a message.
14160
14055
  *
14161
- * @param {String} message.
14162
- * @param {Function} callback function.
14056
+ * @param {String} msg - message.
14163
14057
  * @param {Object} options.
14058
+ * @param {Function} callback function.
14164
14059
  * @return {Socket} for chaining.
14165
- * @api public
14166
14060
  */
14167
14061
  write(msg, options, fn) {
14168
14062
  this.sendPacket("message", msg, options, fn);
@@ -14175,11 +14069,11 @@
14175
14069
  /**
14176
14070
  * Sends a packet.
14177
14071
  *
14178
- * @param {String} packet type.
14072
+ * @param {String} type: packet type.
14179
14073
  * @param {String} data.
14180
14074
  * @param {Object} options.
14181
- * @param {Function} callback function.
14182
- * @api private
14075
+ * @param {Function} fn - callback function.
14076
+ * @private
14183
14077
  */
14184
14078
  sendPacket(type, data, options, fn) {
14185
14079
  if ("function" === typeof data) {
@@ -14198,7 +14092,7 @@
14198
14092
  const packet = {
14199
14093
  type: type,
14200
14094
  data: data,
14201
- options: options
14095
+ options: options,
14202
14096
  };
14203
14097
  this.emitReserved("packetCreate", packet);
14204
14098
  this.writeBuffer.push(packet);
@@ -14208,8 +14102,6 @@
14208
14102
  }
14209
14103
  /**
14210
14104
  * Closes the connection.
14211
- *
14212
- * @api public
14213
14105
  */
14214
14106
  close() {
14215
14107
  const close = () => {
@@ -14250,7 +14142,7 @@
14250
14142
  /**
14251
14143
  * Called upon transport error
14252
14144
  *
14253
- * @api private
14145
+ * @private
14254
14146
  */
14255
14147
  onError(err) {
14256
14148
  Socket$1.priorWebsocketSuccess = false;
@@ -14260,9 +14152,9 @@
14260
14152
  /**
14261
14153
  * Called upon transport close.
14262
14154
  *
14263
- * @api private
14155
+ * @private
14264
14156
  */
14265
- onClose(reason, desc) {
14157
+ onClose(reason, description) {
14266
14158
  if ("opening" === this.readyState ||
14267
14159
  "open" === this.readyState ||
14268
14160
  "closing" === this.readyState) {
@@ -14275,6 +14167,7 @@
14275
14167
  // ignore further transport communication
14276
14168
  this.transport.removeAllListeners();
14277
14169
  if (typeof removeEventListener === "function") {
14170
+ removeEventListener("beforeunload", this.beforeunloadEventListener, false);
14278
14171
  removeEventListener("offline", this.offlineEventListener, false);
14279
14172
  }
14280
14173
  // set ready state
@@ -14282,7 +14175,7 @@
14282
14175
  // clear session id
14283
14176
  this.id = null;
14284
14177
  // emit close event
14285
- this.emitReserved("close", reason, desc);
14178
+ this.emitReserved("close", reason, description);
14286
14179
  // clean buffers after, so users can still
14287
14180
  // grab the buffers on `close` event
14288
14181
  this.writeBuffer = [];
@@ -14292,9 +14185,8 @@
14292
14185
  /**
14293
14186
  * Filters upgrades, returning only those matching client transports.
14294
14187
  *
14295
- * @param {Array} server upgrades
14296
- * @api private
14297
- *
14188
+ * @param {Array} upgrades - server upgrades
14189
+ * @private
14298
14190
  */
14299
14191
  filterUpgrades(upgrades) {
14300
14192
  const filteredUpgrades = [];
@@ -14304,18 +14196,68 @@
14304
14196
  if (~this.transports.indexOf(upgrades[i]))
14305
14197
  filteredUpgrades.push(upgrades[i]);
14306
14198
  }
14307
- return filteredUpgrades;
14199
+ return filteredUpgrades;
14200
+ }
14201
+ }
14202
+ Socket$1.protocol = protocol$1;
14203
+
14204
+ /**
14205
+ * URL parser.
14206
+ *
14207
+ * @param uri - url
14208
+ * @param path - the request path of the connection
14209
+ * @param loc - An object meant to mimic window.location.
14210
+ * Defaults to window.location.
14211
+ * @public
14212
+ */
14213
+ function url(uri, path = "", loc) {
14214
+ let obj = uri;
14215
+ // default to window.location
14216
+ loc = loc || (typeof location !== "undefined" && location);
14217
+ if (null == uri)
14218
+ uri = loc.protocol + "//" + loc.host;
14219
+ // relative path support
14220
+ if (typeof uri === "string") {
14221
+ if ("/" === uri.charAt(0)) {
14222
+ if ("/" === uri.charAt(1)) {
14223
+ uri = loc.protocol + uri;
14224
+ }
14225
+ else {
14226
+ uri = loc.host + uri;
14227
+ }
14228
+ }
14229
+ if (!/^(https?|wss?):\/\//.test(uri)) {
14230
+ if ("undefined" !== typeof loc) {
14231
+ uri = loc.protocol + "//" + uri;
14232
+ }
14233
+ else {
14234
+ uri = "https://" + uri;
14235
+ }
14236
+ }
14237
+ // parse
14238
+ obj = parse(uri);
14308
14239
  }
14309
- }
14310
- Socket$1.protocol = protocol$1;
14311
- function clone(obj) {
14312
- const o = {};
14313
- for (let i in obj) {
14314
- if (obj.hasOwnProperty(i)) {
14315
- o[i] = obj[i];
14240
+ // make sure we treat `localhost:80` and `localhost` equally
14241
+ if (!obj.port) {
14242
+ if (/^(http|ws)$/.test(obj.protocol)) {
14243
+ obj.port = "80";
14244
+ }
14245
+ else if (/^(http|ws)s$/.test(obj.protocol)) {
14246
+ obj.port = "443";
14316
14247
  }
14317
14248
  }
14318
- return o;
14249
+ obj.path = obj.path || "/";
14250
+ const ipv6 = obj.host.indexOf(":") !== -1;
14251
+ const host = ipv6 ? "[" + obj.host + "]" : obj.host;
14252
+ // define unique id
14253
+ obj.id = obj.protocol + "://" + host + ":" + obj.port + path;
14254
+ // define href
14255
+ obj.href =
14256
+ obj.protocol +
14257
+ "://" +
14258
+ host +
14259
+ (loc && loc.port === obj.port ? "" : ":" + obj.port);
14260
+ return obj;
14319
14261
  }
14320
14262
 
14321
14263
  const withNativeArrayBuffer = typeof ArrayBuffer === "function";
@@ -14402,7 +14344,7 @@
14402
14344
  else if (typeof data === "object" && !(data instanceof Date)) {
14403
14345
  const newData = {};
14404
14346
  for (const key in data) {
14405
- if (data.hasOwnProperty(key)) {
14347
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
14406
14348
  newData[key] = _deconstructPacket(data[key], buffers);
14407
14349
  }
14408
14350
  }
@@ -14420,14 +14362,22 @@
14420
14362
  */
14421
14363
  function reconstructPacket(packet, buffers) {
14422
14364
  packet.data = _reconstructPacket(packet.data, buffers);
14423
- packet.attachments = undefined; // no longer useful
14365
+ delete packet.attachments; // no longer useful
14424
14366
  return packet;
14425
14367
  }
14426
14368
  function _reconstructPacket(data, buffers) {
14427
14369
  if (!data)
14428
14370
  return data;
14429
- if (data && data._placeholder) {
14430
- return buffers[data.num]; // appropriate buffer (should be natural order anyway)
14371
+ if (data && data._placeholder === true) {
14372
+ const isIndexValid = typeof data.num === "number" &&
14373
+ data.num >= 0 &&
14374
+ data.num < buffers.length;
14375
+ if (isIndexValid) {
14376
+ return buffers[data.num]; // appropriate buffer (should be natural order anyway)
14377
+ }
14378
+ else {
14379
+ throw new Error("illegal attachments");
14380
+ }
14431
14381
  }
14432
14382
  else if (Array.isArray(data)) {
14433
14383
  for (let i = 0; i < data.length; i++) {
@@ -14436,7 +14386,7 @@
14436
14386
  }
14437
14387
  else if (typeof data === "object") {
14438
14388
  for (const key in data) {
14439
- if (data.hasOwnProperty(key)) {
14389
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
14440
14390
  data[key] = _reconstructPacket(data[key], buffers);
14441
14391
  }
14442
14392
  }
@@ -14464,6 +14414,14 @@
14464
14414
  * A socket.io Encoder instance
14465
14415
  */
14466
14416
  class Encoder {
14417
+ /**
14418
+ * Encoder constructor
14419
+ *
14420
+ * @param {function} replacer - custom replacer to pass down to JSON.parse
14421
+ */
14422
+ constructor(replacer) {
14423
+ this.replacer = replacer;
14424
+ }
14467
14425
  /**
14468
14426
  * Encode a packet as a single string if non-binary, or as a
14469
14427
  * buffer sequence, depending on packet type.
@@ -14473,11 +14431,14 @@
14473
14431
  encode(obj) {
14474
14432
  if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) {
14475
14433
  if (hasBinary(obj)) {
14476
- obj.type =
14477
- obj.type === PacketType.EVENT
14434
+ return this.encodeAsBinary({
14435
+ type: obj.type === PacketType.EVENT
14478
14436
  ? PacketType.BINARY_EVENT
14479
- : PacketType.BINARY_ACK;
14480
- return this.encodeAsBinary(obj);
14437
+ : PacketType.BINARY_ACK,
14438
+ nsp: obj.nsp,
14439
+ data: obj.data,
14440
+ id: obj.id,
14441
+ });
14481
14442
  }
14482
14443
  }
14483
14444
  return [this.encodeAsString(obj)];
@@ -14504,7 +14465,7 @@
14504
14465
  }
14505
14466
  // json data
14506
14467
  if (null != obj.data) {
14507
- str += JSON.stringify(obj.data);
14468
+ str += JSON.stringify(obj.data, this.replacer);
14508
14469
  }
14509
14470
  return str;
14510
14471
  }
@@ -14526,9 +14487,15 @@
14526
14487
  *
14527
14488
  * @return {Object} decoder
14528
14489
  */
14529
- class Decoder extends Emitter_1 {
14530
- constructor() {
14490
+ class Decoder extends Emitter {
14491
+ /**
14492
+ * Decoder constructor
14493
+ *
14494
+ * @param {function} reviver - custom reviver to pass down to JSON.stringify
14495
+ */
14496
+ constructor(reviver) {
14531
14497
  super();
14498
+ this.reviver = reviver;
14532
14499
  }
14533
14500
  /**
14534
14501
  * Decodes an encoded packet string into packet JSON.
@@ -14538,9 +14505,13 @@
14538
14505
  add(obj) {
14539
14506
  let packet;
14540
14507
  if (typeof obj === "string") {
14508
+ if (this.reconstructor) {
14509
+ throw new Error("got plaintext data when reconstructing a packet");
14510
+ }
14541
14511
  packet = this.decodeString(obj);
14542
- if (packet.type === PacketType.BINARY_EVENT ||
14543
- packet.type === PacketType.BINARY_ACK) {
14512
+ const isBinaryEvent = packet.type === PacketType.BINARY_EVENT;
14513
+ if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) {
14514
+ packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK;
14544
14515
  // binary packet's json
14545
14516
  this.reconstructor = new BinaryReconstructor(packet);
14546
14517
  // no attachments, labeled binary but no binary data to follow
@@ -14629,7 +14600,7 @@
14629
14600
  }
14630
14601
  // look up json data
14631
14602
  if (str.charAt(++i)) {
14632
- const payload = tryParse(str.substr(i));
14603
+ const payload = this.tryParse(str.substr(i));
14633
14604
  if (Decoder.isPayloadValid(p.type, payload)) {
14634
14605
  p.data = payload;
14635
14606
  }
@@ -14639,6 +14610,14 @@
14639
14610
  }
14640
14611
  return p;
14641
14612
  }
14613
+ tryParse(str) {
14614
+ try {
14615
+ return JSON.parse(str, this.reviver);
14616
+ }
14617
+ catch (e) {
14618
+ return false;
14619
+ }
14620
+ }
14642
14621
  static isPayloadValid(type, payload) {
14643
14622
  switch (type) {
14644
14623
  case PacketType.CONNECT:
@@ -14661,17 +14640,10 @@
14661
14640
  destroy() {
14662
14641
  if (this.reconstructor) {
14663
14642
  this.reconstructor.finishedReconstruction();
14643
+ this.reconstructor = null;
14664
14644
  }
14665
14645
  }
14666
14646
  }
14667
- function tryParse(str) {
14668
- try {
14669
- return JSON.parse(str);
14670
- }
14671
- catch (e) {
14672
- return false;
14673
- }
14674
- }
14675
14647
  /**
14676
14648
  * A manager of a binary event's 'buffer sequence'. Should
14677
14649
  * be constructed whenever a packet of type BINARY_EVENT is
@@ -14741,18 +14713,76 @@
14741
14713
  newListener: 1,
14742
14714
  removeListener: 1,
14743
14715
  });
14744
- class Socket extends Emitter_1 {
14716
+ /**
14717
+ * A Socket is the fundamental class for interacting with the server.
14718
+ *
14719
+ * A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate.
14720
+ *
14721
+ * @example
14722
+ * const socket = io();
14723
+ *
14724
+ * socket.on("connect", () => {
14725
+ * console.log("connected");
14726
+ * });
14727
+ *
14728
+ * // send an event to the server
14729
+ * socket.emit("foo", "bar");
14730
+ *
14731
+ * socket.on("foobar", () => {
14732
+ * // an event was received from the server
14733
+ * });
14734
+ *
14735
+ * // upon disconnection
14736
+ * socket.on("disconnect", (reason) => {
14737
+ * console.log(`disconnected due to ${reason}`);
14738
+ * });
14739
+ */
14740
+ class Socket extends Emitter {
14745
14741
  /**
14746
14742
  * `Socket` constructor.
14747
- *
14748
- * @public
14749
14743
  */
14750
14744
  constructor(io, nsp, opts) {
14751
14745
  super();
14746
+ /**
14747
+ * Whether the socket is currently connected to the server.
14748
+ *
14749
+ * @example
14750
+ * const socket = io();
14751
+ *
14752
+ * socket.on("connect", () => {
14753
+ * console.log(socket.connected); // true
14754
+ * });
14755
+ *
14756
+ * socket.on("disconnect", () => {
14757
+ * console.log(socket.connected); // false
14758
+ * });
14759
+ */
14752
14760
  this.connected = false;
14753
- this.disconnected = true;
14761
+ /**
14762
+ * Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will
14763
+ * be transmitted by the server.
14764
+ */
14765
+ this.recovered = false;
14766
+ /**
14767
+ * Buffer for packets received before the CONNECT packet
14768
+ */
14754
14769
  this.receiveBuffer = [];
14770
+ /**
14771
+ * Buffer for packets that will be sent once the socket is connected
14772
+ */
14755
14773
  this.sendBuffer = [];
14774
+ /**
14775
+ * The queue of packets to be sent with retry in case of failure.
14776
+ *
14777
+ * Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order.
14778
+ * @private
14779
+ */
14780
+ this._queue = [];
14781
+ /**
14782
+ * A sequence to generate the ID of the {@link QueuedPacket}.
14783
+ * @private
14784
+ */
14785
+ this._queueSeq = 0;
14756
14786
  this.ids = 0;
14757
14787
  this.acks = {};
14758
14788
  this.flags = {};
@@ -14761,9 +14791,27 @@
14761
14791
  if (opts && opts.auth) {
14762
14792
  this.auth = opts.auth;
14763
14793
  }
14794
+ this._opts = Object.assign({}, opts);
14764
14795
  if (this.io._autoConnect)
14765
14796
  this.open();
14766
14797
  }
14798
+ /**
14799
+ * Whether the socket is currently disconnected
14800
+ *
14801
+ * @example
14802
+ * const socket = io();
14803
+ *
14804
+ * socket.on("connect", () => {
14805
+ * console.log(socket.disconnected); // false
14806
+ * });
14807
+ *
14808
+ * socket.on("disconnect", () => {
14809
+ * console.log(socket.disconnected); // true
14810
+ * });
14811
+ */
14812
+ get disconnected() {
14813
+ return !this.connected;
14814
+ }
14767
14815
  /**
14768
14816
  * Subscribe to open, close and packet events
14769
14817
  *
@@ -14781,7 +14829,21 @@
14781
14829
  ];
14782
14830
  }
14783
14831
  /**
14784
- * Whether the Socket will try to reconnect when its Manager connects or reconnects
14832
+ * Whether the Socket will try to reconnect when its Manager connects or reconnects.
14833
+ *
14834
+ * @example
14835
+ * const socket = io();
14836
+ *
14837
+ * console.log(socket.active); // true
14838
+ *
14839
+ * socket.on("disconnect", (reason) => {
14840
+ * if (reason === "io server disconnect") {
14841
+ * // the disconnection was initiated by the server, you need to manually reconnect
14842
+ * console.log(socket.active); // false
14843
+ * }
14844
+ * // else the socket will automatically try to reconnect
14845
+ * console.log(socket.active); // true
14846
+ * });
14785
14847
  */
14786
14848
  get active() {
14787
14849
  return !!this.subs;
@@ -14789,7 +14851,12 @@
14789
14851
  /**
14790
14852
  * "Opens" the socket.
14791
14853
  *
14792
- * @public
14854
+ * @example
14855
+ * const socket = io({
14856
+ * autoConnect: false
14857
+ * });
14858
+ *
14859
+ * socket.connect();
14793
14860
  */
14794
14861
  connect() {
14795
14862
  if (this.connected)
@@ -14802,7 +14869,7 @@
14802
14869
  return this;
14803
14870
  }
14804
14871
  /**
14805
- * Alias for connect()
14872
+ * Alias for {@link connect()}.
14806
14873
  */
14807
14874
  open() {
14808
14875
  return this.connect();
@@ -14810,8 +14877,17 @@
14810
14877
  /**
14811
14878
  * Sends a `message` event.
14812
14879
  *
14880
+ * This method mimics the WebSocket.send() method.
14881
+ *
14882
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
14883
+ *
14884
+ * @example
14885
+ * socket.send("hello");
14886
+ *
14887
+ * // this is equivalent to
14888
+ * socket.emit("message", "hello");
14889
+ *
14813
14890
  * @return self
14814
- * @public
14815
14891
  */
14816
14892
  send(...args) {
14817
14893
  args.unshift("message");
@@ -14822,14 +14898,28 @@
14822
14898
  * Override `emit`.
14823
14899
  * If the event is in `events`, it's emitted normally.
14824
14900
  *
14901
+ * @example
14902
+ * socket.emit("hello", "world");
14903
+ *
14904
+ * // all serializable datastructures are supported (no need to call JSON.stringify)
14905
+ * socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) });
14906
+ *
14907
+ * // with an acknowledgement from the server
14908
+ * socket.emit("hello", "world", (val) => {
14909
+ * // ...
14910
+ * });
14911
+ *
14825
14912
  * @return self
14826
- * @public
14827
14913
  */
14828
14914
  emit(ev, ...args) {
14829
14915
  if (RESERVED_EVENTS.hasOwnProperty(ev)) {
14830
- throw new Error('"' + ev + '" is a reserved event name');
14916
+ throw new Error('"' + ev.toString() + '" is a reserved event name');
14831
14917
  }
14832
14918
  args.unshift(ev);
14919
+ if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {
14920
+ this._addToQueue(args);
14921
+ return this;
14922
+ }
14833
14923
  const packet = {
14834
14924
  type: PacketType.EVENT,
14835
14925
  data: args,
@@ -14849,6 +14939,7 @@
14849
14939
  const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);
14850
14940
  if (discardPacket) ;
14851
14941
  else if (this.connected) {
14942
+ this.notifyOutgoingListeners(packet);
14852
14943
  this.packet(packet);
14853
14944
  }
14854
14945
  else {
@@ -14861,7 +14952,8 @@
14861
14952
  * @private
14862
14953
  */
14863
14954
  _registerAckCallback(id, ack) {
14864
- const timeout = this.flags.timeout;
14955
+ var _a;
14956
+ const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout;
14865
14957
  if (timeout === undefined) {
14866
14958
  this.acks[id] = ack;
14867
14959
  return;
@@ -14882,6 +14974,99 @@
14882
14974
  ack.apply(this, [null, ...args]);
14883
14975
  };
14884
14976
  }
14977
+ /**
14978
+ * Emits an event and waits for an acknowledgement
14979
+ *
14980
+ * @example
14981
+ * // without timeout
14982
+ * const response = await socket.emitWithAck("hello", "world");
14983
+ *
14984
+ * // with a specific timeout
14985
+ * try {
14986
+ * const response = await socket.timeout(1000).emitWithAck("hello", "world");
14987
+ * } catch (err) {
14988
+ * // the server did not acknowledge the event in the given delay
14989
+ * }
14990
+ *
14991
+ * @return a Promise that will be fulfilled when the server acknowledges the event
14992
+ */
14993
+ emitWithAck(ev, ...args) {
14994
+ // the timeout flag is optional
14995
+ const withErr = this.flags.timeout !== undefined || this._opts.ackTimeout !== undefined;
14996
+ return new Promise((resolve, reject) => {
14997
+ args.push((arg1, arg2) => {
14998
+ if (withErr) {
14999
+ return arg1 ? reject(arg1) : resolve(arg2);
15000
+ }
15001
+ else {
15002
+ return resolve(arg1);
15003
+ }
15004
+ });
15005
+ this.emit(ev, ...args);
15006
+ });
15007
+ }
15008
+ /**
15009
+ * Add the packet to the queue.
15010
+ * @param args
15011
+ * @private
15012
+ */
15013
+ _addToQueue(args) {
15014
+ let ack;
15015
+ if (typeof args[args.length - 1] === "function") {
15016
+ ack = args.pop();
15017
+ }
15018
+ const packet = {
15019
+ id: this._queueSeq++,
15020
+ tryCount: 0,
15021
+ pending: false,
15022
+ args,
15023
+ flags: Object.assign({ fromQueue: true }, this.flags),
15024
+ };
15025
+ args.push((err, ...responseArgs) => {
15026
+ if (packet !== this._queue[0]) {
15027
+ // the packet has already been acknowledged
15028
+ return;
15029
+ }
15030
+ const hasError = err !== null;
15031
+ if (hasError) {
15032
+ if (packet.tryCount > this._opts.retries) {
15033
+ this._queue.shift();
15034
+ if (ack) {
15035
+ ack(err);
15036
+ }
15037
+ }
15038
+ }
15039
+ else {
15040
+ this._queue.shift();
15041
+ if (ack) {
15042
+ ack(null, ...responseArgs);
15043
+ }
15044
+ }
15045
+ packet.pending = false;
15046
+ return this._drainQueue();
15047
+ });
15048
+ this._queue.push(packet);
15049
+ this._drainQueue();
15050
+ }
15051
+ /**
15052
+ * Send the first packet of the queue, and wait for an acknowledgement from the server.
15053
+ * @param force - whether to resend a packet that has not been acknowledged yet
15054
+ *
15055
+ * @private
15056
+ */
15057
+ _drainQueue(force = false) {
15058
+ if (!this.connected || this._queue.length === 0) {
15059
+ return;
15060
+ }
15061
+ const packet = this._queue[0];
15062
+ if (packet.pending && !force) {
15063
+ return;
15064
+ }
15065
+ packet.pending = true;
15066
+ packet.tryCount++;
15067
+ this.flags = packet.flags;
15068
+ this.emit.apply(this, packet.args);
15069
+ }
14885
15070
  /**
14886
15071
  * Sends a packet.
14887
15072
  *
@@ -14900,13 +15085,27 @@
14900
15085
  onopen() {
14901
15086
  if (typeof this.auth == "function") {
14902
15087
  this.auth((data) => {
14903
- this.packet({ type: PacketType.CONNECT, data });
15088
+ this._sendConnectPacket(data);
14904
15089
  });
14905
15090
  }
14906
15091
  else {
14907
- this.packet({ type: PacketType.CONNECT, data: this.auth });
15092
+ this._sendConnectPacket(this.auth);
14908
15093
  }
14909
15094
  }
15095
+ /**
15096
+ * Sends a CONNECT packet to initiate the Socket.IO session.
15097
+ *
15098
+ * @param data
15099
+ * @private
15100
+ */
15101
+ _sendConnectPacket(data) {
15102
+ this.packet({
15103
+ type: PacketType.CONNECT,
15104
+ data: this._pid
15105
+ ? Object.assign({ pid: this._pid, offset: this._lastOffset }, data)
15106
+ : data,
15107
+ });
15108
+ }
14910
15109
  /**
14911
15110
  * Called upon engine or manager `error`.
14912
15111
  *
@@ -14922,13 +15121,13 @@
14922
15121
  * Called upon engine `close`.
14923
15122
  *
14924
15123
  * @param reason
15124
+ * @param description
14925
15125
  * @private
14926
15126
  */
14927
- onclose(reason) {
15127
+ onclose(reason, description) {
14928
15128
  this.connected = false;
14929
- this.disconnected = true;
14930
15129
  delete this.id;
14931
- this.emitReserved("disconnect", reason);
15130
+ this.emitReserved("disconnect", reason, description);
14932
15131
  }
14933
15132
  /**
14934
15133
  * Called with socket packet.
@@ -14943,22 +15142,17 @@
14943
15142
  switch (packet.type) {
14944
15143
  case PacketType.CONNECT:
14945
15144
  if (packet.data && packet.data.sid) {
14946
- const id = packet.data.sid;
14947
- this.onconnect(id);
15145
+ this.onconnect(packet.data.sid, packet.data.pid);
14948
15146
  }
14949
15147
  else {
14950
15148
  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/)"));
14951
15149
  }
14952
15150
  break;
14953
15151
  case PacketType.EVENT:
14954
- this.onevent(packet);
14955
- break;
14956
15152
  case PacketType.BINARY_EVENT:
14957
15153
  this.onevent(packet);
14958
15154
  break;
14959
15155
  case PacketType.ACK:
14960
- this.onack(packet);
14961
- break;
14962
15156
  case PacketType.BINARY_ACK:
14963
15157
  this.onack(packet);
14964
15158
  break;
@@ -15000,6 +15194,9 @@
15000
15194
  }
15001
15195
  }
15002
15196
  super.emit.apply(this, args);
15197
+ if (this._pid && args.length && typeof args[args.length - 1] === "string") {
15198
+ this._lastOffset = args[args.length - 1];
15199
+ }
15003
15200
  }
15004
15201
  /**
15005
15202
  * Produces an ack callback to emit with an event.
@@ -15039,12 +15236,14 @@
15039
15236
  *
15040
15237
  * @private
15041
15238
  */
15042
- onconnect(id) {
15239
+ onconnect(id, pid) {
15043
15240
  this.id = id;
15241
+ this.recovered = pid && this._pid === pid;
15242
+ this._pid = pid; // defined only if connection state recovery is enabled
15044
15243
  this.connected = true;
15045
- this.disconnected = false;
15046
15244
  this.emitBuffered();
15047
15245
  this.emitReserved("connect");
15246
+ this._drainQueue(true);
15048
15247
  }
15049
15248
  /**
15050
15249
  * Emit buffered events (received and emitted).
@@ -15054,7 +15253,10 @@
15054
15253
  emitBuffered() {
15055
15254
  this.receiveBuffer.forEach((args) => this.emitEvent(args));
15056
15255
  this.receiveBuffer = [];
15057
- this.sendBuffer.forEach((packet) => this.packet(packet));
15256
+ this.sendBuffer.forEach((packet) => {
15257
+ this.notifyOutgoingListeners(packet);
15258
+ this.packet(packet);
15259
+ });
15058
15260
  this.sendBuffer = [];
15059
15261
  }
15060
15262
  /**
@@ -15082,10 +15284,20 @@
15082
15284
  this.io["_destroy"](this);
15083
15285
  }
15084
15286
  /**
15085
- * Disconnects the socket manually.
15287
+ * Disconnects the socket manually. In that case, the socket will not try to reconnect.
15288
+ *
15289
+ * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed.
15290
+ *
15291
+ * @example
15292
+ * const socket = io();
15293
+ *
15294
+ * socket.on("disconnect", (reason) => {
15295
+ * // console.log(reason); prints "io client disconnect"
15296
+ * });
15297
+ *
15298
+ * socket.disconnect();
15086
15299
  *
15087
15300
  * @return self
15088
- * @public
15089
15301
  */
15090
15302
  disconnect() {
15091
15303
  if (this.connected) {
@@ -15100,10 +15312,9 @@
15100
15312
  return this;
15101
15313
  }
15102
15314
  /**
15103
- * Alias for disconnect()
15315
+ * Alias for {@link disconnect()}.
15104
15316
  *
15105
15317
  * @return self
15106
- * @public
15107
15318
  */
15108
15319
  close() {
15109
15320
  return this.disconnect();
@@ -15111,9 +15322,11 @@
15111
15322
  /**
15112
15323
  * Sets the compress flag.
15113
15324
  *
15325
+ * @example
15326
+ * socket.compress(false).emit("hello");
15327
+ *
15114
15328
  * @param compress - if `true`, compresses the sending data
15115
15329
  * @return self
15116
- * @public
15117
15330
  */
15118
15331
  compress(compress) {
15119
15332
  this.flags.compress = compress;
@@ -15123,8 +15336,10 @@
15123
15336
  * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not
15124
15337
  * ready to send messages.
15125
15338
  *
15339
+ * @example
15340
+ * socket.volatile.emit("hello"); // the server may or may not receive it
15341
+ *
15126
15342
  * @returns self
15127
- * @public
15128
15343
  */
15129
15344
  get volatile() {
15130
15345
  this.flags.volatile = true;
@@ -15134,16 +15349,14 @@
15134
15349
  * Sets a modifier for a subsequent event emission that the callback will be called with an error when the
15135
15350
  * given number of milliseconds have elapsed without an acknowledgement from the server:
15136
15351
  *
15137
- * ```
15352
+ * @example
15138
15353
  * socket.timeout(5000).emit("my-event", (err) => {
15139
15354
  * if (err) {
15140
15355
  * // the server did not acknowledge the event in the given delay
15141
15356
  * }
15142
15357
  * });
15143
- * ```
15144
15358
  *
15145
15359
  * @returns self
15146
- * @public
15147
15360
  */
15148
15361
  timeout(timeout) {
15149
15362
  this.flags.timeout = timeout;
@@ -15153,8 +15366,12 @@
15153
15366
  * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
15154
15367
  * callback.
15155
15368
  *
15369
+ * @example
15370
+ * socket.onAny((event, ...args) => {
15371
+ * console.log(`got ${event}`);
15372
+ * });
15373
+ *
15156
15374
  * @param listener
15157
- * @public
15158
15375
  */
15159
15376
  onAny(listener) {
15160
15377
  this._anyListeners = this._anyListeners || [];
@@ -15165,8 +15382,12 @@
15165
15382
  * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
15166
15383
  * callback. The listener is added to the beginning of the listeners array.
15167
15384
  *
15385
+ * @example
15386
+ * socket.prependAny((event, ...args) => {
15387
+ * console.log(`got event ${event}`);
15388
+ * });
15389
+ *
15168
15390
  * @param listener
15169
- * @public
15170
15391
  */
15171
15392
  prependAny(listener) {
15172
15393
  this._anyListeners = this._anyListeners || [];
@@ -15176,8 +15397,20 @@
15176
15397
  /**
15177
15398
  * Removes the listener that will be fired when any event is emitted.
15178
15399
  *
15400
+ * @example
15401
+ * const catchAllListener = (event, ...args) => {
15402
+ * console.log(`got event ${event}`);
15403
+ * }
15404
+ *
15405
+ * socket.onAny(catchAllListener);
15406
+ *
15407
+ * // remove a specific listener
15408
+ * socket.offAny(catchAllListener);
15409
+ *
15410
+ * // or remove all listeners
15411
+ * socket.offAny();
15412
+ *
15179
15413
  * @param listener
15180
- * @public
15181
15414
  */
15182
15415
  offAny(listener) {
15183
15416
  if (!this._anyListeners) {
@@ -15200,20 +15433,106 @@
15200
15433
  /**
15201
15434
  * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
15202
15435
  * e.g. to remove listeners.
15203
- *
15204
- * @public
15205
15436
  */
15206
15437
  listenersAny() {
15207
15438
  return this._anyListeners || [];
15208
15439
  }
15440
+ /**
15441
+ * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
15442
+ * callback.
15443
+ *
15444
+ * Note: acknowledgements sent to the server are not included.
15445
+ *
15446
+ * @example
15447
+ * socket.onAnyOutgoing((event, ...args) => {
15448
+ * console.log(`sent event ${event}`);
15449
+ * });
15450
+ *
15451
+ * @param listener
15452
+ */
15453
+ onAnyOutgoing(listener) {
15454
+ this._anyOutgoingListeners = this._anyOutgoingListeners || [];
15455
+ this._anyOutgoingListeners.push(listener);
15456
+ return this;
15457
+ }
15458
+ /**
15459
+ * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
15460
+ * callback. The listener is added to the beginning of the listeners array.
15461
+ *
15462
+ * Note: acknowledgements sent to the server are not included.
15463
+ *
15464
+ * @example
15465
+ * socket.prependAnyOutgoing((event, ...args) => {
15466
+ * console.log(`sent event ${event}`);
15467
+ * });
15468
+ *
15469
+ * @param listener
15470
+ */
15471
+ prependAnyOutgoing(listener) {
15472
+ this._anyOutgoingListeners = this._anyOutgoingListeners || [];
15473
+ this._anyOutgoingListeners.unshift(listener);
15474
+ return this;
15475
+ }
15476
+ /**
15477
+ * Removes the listener that will be fired when any event is emitted.
15478
+ *
15479
+ * @example
15480
+ * const catchAllListener = (event, ...args) => {
15481
+ * console.log(`sent event ${event}`);
15482
+ * }
15483
+ *
15484
+ * socket.onAnyOutgoing(catchAllListener);
15485
+ *
15486
+ * // remove a specific listener
15487
+ * socket.offAnyOutgoing(catchAllListener);
15488
+ *
15489
+ * // or remove all listeners
15490
+ * socket.offAnyOutgoing();
15491
+ *
15492
+ * @param [listener] - the catch-all listener (optional)
15493
+ */
15494
+ offAnyOutgoing(listener) {
15495
+ if (!this._anyOutgoingListeners) {
15496
+ return this;
15497
+ }
15498
+ if (listener) {
15499
+ const listeners = this._anyOutgoingListeners;
15500
+ for (let i = 0; i < listeners.length; i++) {
15501
+ if (listener === listeners[i]) {
15502
+ listeners.splice(i, 1);
15503
+ return this;
15504
+ }
15505
+ }
15506
+ }
15507
+ else {
15508
+ this._anyOutgoingListeners = [];
15509
+ }
15510
+ return this;
15511
+ }
15512
+ /**
15513
+ * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
15514
+ * e.g. to remove listeners.
15515
+ */
15516
+ listenersAnyOutgoing() {
15517
+ return this._anyOutgoingListeners || [];
15518
+ }
15519
+ /**
15520
+ * Notify the listeners for each packet sent
15521
+ *
15522
+ * @param packet
15523
+ *
15524
+ * @private
15525
+ */
15526
+ notifyOutgoingListeners(packet) {
15527
+ if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {
15528
+ const listeners = this._anyOutgoingListeners.slice();
15529
+ for (const listener of listeners) {
15530
+ listener.apply(this, packet.data);
15531
+ }
15532
+ }
15533
+ }
15209
15534
  }
15210
15535
 
15211
- /**
15212
- * Expose `Backoff`.
15213
- */
15214
-
15215
- var backo2 = Backoff;
15216
-
15217
15536
  /**
15218
15537
  * Initialize backoff timer with `opts`.
15219
15538
  *
@@ -15225,74 +15544,63 @@
15225
15544
  * @param {Object} opts
15226
15545
  * @api public
15227
15546
  */
15228
-
15229
15547
  function Backoff(opts) {
15230
- opts = opts || {};
15231
- this.ms = opts.min || 100;
15232
- this.max = opts.max || 10000;
15233
- this.factor = opts.factor || 2;
15234
- this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
15235
- this.attempts = 0;
15548
+ opts = opts || {};
15549
+ this.ms = opts.min || 100;
15550
+ this.max = opts.max || 10000;
15551
+ this.factor = opts.factor || 2;
15552
+ this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
15553
+ this.attempts = 0;
15236
15554
  }
15237
-
15238
15555
  /**
15239
15556
  * Return the backoff duration.
15240
15557
  *
15241
15558
  * @return {Number}
15242
15559
  * @api public
15243
15560
  */
15244
-
15245
- Backoff.prototype.duration = function(){
15246
- var ms = this.ms * Math.pow(this.factor, this.attempts++);
15247
- if (this.jitter) {
15248
- var rand = Math.random();
15249
- var deviation = Math.floor(rand * this.jitter * ms);
15250
- ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
15251
- }
15252
- return Math.min(ms, this.max) | 0;
15561
+ Backoff.prototype.duration = function () {
15562
+ var ms = this.ms * Math.pow(this.factor, this.attempts++);
15563
+ if (this.jitter) {
15564
+ var rand = Math.random();
15565
+ var deviation = Math.floor(rand * this.jitter * ms);
15566
+ ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
15567
+ }
15568
+ return Math.min(ms, this.max) | 0;
15253
15569
  };
15254
-
15255
15570
  /**
15256
15571
  * Reset the number of attempts.
15257
15572
  *
15258
15573
  * @api public
15259
15574
  */
15260
-
15261
- Backoff.prototype.reset = function(){
15262
- this.attempts = 0;
15575
+ Backoff.prototype.reset = function () {
15576
+ this.attempts = 0;
15263
15577
  };
15264
-
15265
15578
  /**
15266
15579
  * Set the minimum duration
15267
15580
  *
15268
15581
  * @api public
15269
15582
  */
15270
-
15271
- Backoff.prototype.setMin = function(min){
15272
- this.ms = min;
15583
+ Backoff.prototype.setMin = function (min) {
15584
+ this.ms = min;
15273
15585
  };
15274
-
15275
15586
  /**
15276
15587
  * Set the maximum duration
15277
15588
  *
15278
15589
  * @api public
15279
15590
  */
15280
-
15281
- Backoff.prototype.setMax = function(max){
15282
- this.max = max;
15591
+ Backoff.prototype.setMax = function (max) {
15592
+ this.max = max;
15283
15593
  };
15284
-
15285
15594
  /**
15286
15595
  * Set the jitter
15287
15596
  *
15288
15597
  * @api public
15289
15598
  */
15290
-
15291
- Backoff.prototype.setJitter = function(jitter){
15292
- this.jitter = jitter;
15599
+ Backoff.prototype.setJitter = function (jitter) {
15600
+ this.jitter = jitter;
15293
15601
  };
15294
15602
 
15295
- class Manager extends Emitter_1 {
15603
+ class Manager extends Emitter {
15296
15604
  constructor(uri, opts) {
15297
15605
  var _a;
15298
15606
  super();
@@ -15311,7 +15619,7 @@
15311
15619
  this.reconnectionDelay(opts.reconnectionDelay || 1000);
15312
15620
  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
15313
15621
  this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);
15314
- this.backoff = new backo2({
15622
+ this.backoff = new Backoff({
15315
15623
  min: this.reconnectionDelay(),
15316
15624
  max: this.reconnectionDelayMax(),
15317
15625
  jitter: this.randomizationFactor(),
@@ -15477,7 +15785,12 @@
15477
15785
  * @private
15478
15786
  */
15479
15787
  ondata(data) {
15480
- this.decoder.add(data);
15788
+ try {
15789
+ this.decoder.add(data);
15790
+ }
15791
+ catch (e) {
15792
+ this.onclose("parse error", e);
15793
+ }
15481
15794
  }
15482
15795
  /**
15483
15796
  * Called when parser fully decodes a packet.
@@ -15485,7 +15798,10 @@
15485
15798
  * @private
15486
15799
  */
15487
15800
  ondecoded(packet) {
15488
- this.emitReserved("packet", packet);
15801
+ // the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a "parse error"
15802
+ nextTick(() => {
15803
+ this.emitReserved("packet", packet);
15804
+ }, this.setTimeoutFn);
15489
15805
  }
15490
15806
  /**
15491
15807
  * Called upon socket error.
@@ -15507,6 +15823,9 @@
15507
15823
  socket = new Socket(this, nsp, opts);
15508
15824
  this.nsps[nsp] = socket;
15509
15825
  }
15826
+ else if (this._autoConnect && !socket.active) {
15827
+ socket.connect();
15828
+ }
15510
15829
  return socket;
15511
15830
  }
15512
15831
  /**
@@ -15572,11 +15891,11 @@
15572
15891
  *
15573
15892
  * @private
15574
15893
  */
15575
- onclose(reason) {
15894
+ onclose(reason, description) {
15576
15895
  this.cleanup();
15577
15896
  this.backoff.reset();
15578
15897
  this._readyState = "closed";
15579
- this.emitReserved("close", reason);
15898
+ this.emitReserved("close", reason, description);
15580
15899
  if (this._reconnection && !this.skipReconnect) {
15581
15900
  this.reconnect();
15582
15901
  }