@xapp/chat-widget 1.74.8 → 1.76.0

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/dist/index.es.js CHANGED
@@ -796,7 +796,7 @@ var ChatButton = function (_a) {
796
796
  };
797
797
  }, [mobileWidth]);
798
798
  var maxSvgSize = 22;
799
- var svgSize = Math.min(maxSvgSize, (+buttonWidth / +defaultWidgetButtonWidth) * maxSvgSize);
799
+ var svgSize = Math.min(maxSvgSize, (+buttonWidth / 48) * maxSvgSize);
800
800
  return (React$1.createElement("button", { "aria-label": "open chat", className: "xapp-chat-button ".concat(addClass || "").trim(), onClick: onClick },
801
801
  React$1.createElement("div", { id: "xapp-widget-button", className: "xapp-chat-button__btn", style: {
802
802
  width: "".concat(buttonWidth, "px"),
@@ -2784,13 +2784,7 @@ var ROUTER_USER = "router";
2784
2784
  var serverInfo = {
2785
2785
  deviceId: "Router",
2786
2786
  userId: ROUTER_USER,
2787
- isAdmin: false,
2788
- displayName: "XAPP Server",
2789
- urlAttributes: {
2790
- path: [],
2791
- query: {}
2792
- }
2793
- };
2787
+ displayName: "XAPP Server"};
2794
2788
  var StentorRouterChat = /** @class */ (function () {
2795
2789
  function StentorRouterChat(config, options) {
2796
2790
  var _a, _b;
@@ -3908,6 +3902,15 @@ Emitter.prototype.hasListeners = function(event){
3908
3902
  return !! this.listeners(event).length;
3909
3903
  };
3910
3904
 
3905
+ const nextTick = (() => {
3906
+ const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
3907
+ if (isPromiseAvailable) {
3908
+ return (cb) => Promise.resolve().then(cb);
3909
+ }
3910
+ else {
3911
+ return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
3912
+ }
3913
+ })();
3911
3914
  const globalThisShim = (() => {
3912
3915
  if (typeof self !== "undefined") {
3913
3916
  return self;
@@ -3919,6 +3922,8 @@ const globalThisShim = (() => {
3919
3922
  return Function("return this")();
3920
3923
  }
3921
3924
  })();
3925
+ const defaultBinaryType = "arraybuffer";
3926
+ function createCookieJar() { }
3922
3927
 
3923
3928
  function pick(obj, ...attr) {
3924
3929
  return attr.reduce((acc, k) => {
@@ -3971,6 +3976,13 @@ function utf8Length(str) {
3971
3976
  }
3972
3977
  return length;
3973
3978
  }
3979
+ /**
3980
+ * Generates a random 8-characters string.
3981
+ */
3982
+ function randomString$1() {
3983
+ return (Date.now().toString(36).substring(3) +
3984
+ Math.random().toString(36).substring(2, 5));
3985
+ }
3974
3986
 
3975
3987
  // imported from https://github.com/galkn/querystring
3976
3988
  /**
@@ -3980,7 +3992,7 @@ function utf8Length(str) {
3980
3992
  * @param {Object}
3981
3993
  * @api private
3982
3994
  */
3983
- function encode$1(obj) {
3995
+ function encode(obj) {
3984
3996
  let str = '';
3985
3997
  for (let i in obj) {
3986
3998
  if (obj.hasOwnProperty(i)) {
@@ -4029,6 +4041,7 @@ class Transport extends Emitter_1 {
4029
4041
  this.opts = opts;
4030
4042
  this.query = opts.query;
4031
4043
  this.socket = opts.socket;
4044
+ this.supportsBinary = !opts.forceBase64;
4032
4045
  }
4033
4046
  /**
4034
4047
  * Emits an error.
@@ -4137,115 +4150,15 @@ class Transport extends Emitter_1 {
4137
4150
  }
4138
4151
  }
4139
4152
  _query(query) {
4140
- const encodedQuery = encode$1(query);
4153
+ const encodedQuery = encode(query);
4141
4154
  return encodedQuery.length ? "?" + encodedQuery : "";
4142
4155
  }
4143
4156
  }
4144
4157
 
4145
- // imported from https://github.com/unshiftio/yeast
4146
- const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
4147
- let seed = 0, i = 0, prev;
4148
- /**
4149
- * Return a string representing the specified number.
4150
- *
4151
- * @param {Number} num The number to convert.
4152
- * @returns {String} The string representation of the number.
4153
- * @api public
4154
- */
4155
- function encode(num) {
4156
- let encoded = '';
4157
- do {
4158
- encoded = alphabet[num % length] + encoded;
4159
- num = Math.floor(num / length);
4160
- } while (num > 0);
4161
- return encoded;
4162
- }
4163
- /**
4164
- * Yeast: A tiny growing id generator.
4165
- *
4166
- * @returns {String} A unique id.
4167
- * @api public
4168
- */
4169
- function yeast() {
4170
- const now = encode(+new Date());
4171
- if (now !== prev)
4172
- return seed = 0, prev = now;
4173
- return now + '.' + encode(seed++);
4174
- }
4175
- //
4176
- // Map each character to its index.
4177
- //
4178
- for (; i < length; i++)
4179
- map[alphabet[i]] = i;
4180
-
4181
- // imported from https://github.com/component/has-cors
4182
- let value = false;
4183
- try {
4184
- value = typeof XMLHttpRequest !== 'undefined' &&
4185
- 'withCredentials' in new XMLHttpRequest();
4186
- }
4187
- catch (err) {
4188
- // if XMLHttp support is disabled in IE then it will throw
4189
- // when trying to create
4190
- }
4191
- const hasCORS = value;
4192
-
4193
- // browser shim for xmlhttprequest module
4194
- function XHR(opts) {
4195
- const xdomain = opts.xdomain;
4196
- // XMLHttpRequest can be disabled on IE
4197
- try {
4198
- if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
4199
- return new XMLHttpRequest();
4200
- }
4201
- }
4202
- catch (e) { }
4203
- if (!xdomain) {
4204
- try {
4205
- return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
4206
- }
4207
- catch (e) { }
4208
- }
4209
- }
4210
- function createCookieJar() { }
4211
-
4212
- function empty$2() { }
4213
- const hasXHR2 = (function () {
4214
- const xhr = new XHR({
4215
- xdomain: false,
4216
- });
4217
- return null != xhr.responseType;
4218
- })();
4219
4158
  class Polling extends Transport {
4220
- /**
4221
- * XHR Polling constructor.
4222
- *
4223
- * @param {Object} opts
4224
- * @package
4225
- */
4226
- constructor(opts) {
4227
- super(opts);
4228
- this.polling = false;
4229
- if (typeof location !== "undefined") {
4230
- const isSSL = "https:" === location.protocol;
4231
- let port = location.port;
4232
- // some user agents have empty `location.port`
4233
- if (!port) {
4234
- port = isSSL ? "443" : "80";
4235
- }
4236
- this.xd =
4237
- (typeof location !== "undefined" &&
4238
- opts.hostname !== location.hostname) ||
4239
- port !== opts.port;
4240
- }
4241
- /**
4242
- * XHR supports binary
4243
- */
4244
- const forceBase64 = opts && opts.forceBase64;
4245
- this.supportsBinary = hasXHR2 && !forceBase64;
4246
- if (this.opts.withCredentials) {
4247
- this.cookieJar = createCookieJar();
4248
- }
4159
+ constructor() {
4160
+ super(...arguments);
4161
+ this._polling = false;
4249
4162
  }
4250
4163
  get name() {
4251
4164
  return "polling";
@@ -4257,7 +4170,7 @@ class Polling extends Transport {
4257
4170
  * @protected
4258
4171
  */
4259
4172
  doOpen() {
4260
- this.poll();
4173
+ this._poll();
4261
4174
  }
4262
4175
  /**
4263
4176
  * Pauses polling.
@@ -4271,9 +4184,9 @@ class Polling extends Transport {
4271
4184
  this.readyState = "paused";
4272
4185
  onPause();
4273
4186
  };
4274
- if (this.polling || !this.writable) {
4187
+ if (this._polling || !this.writable) {
4275
4188
  let total = 0;
4276
- if (this.polling) {
4189
+ if (this._polling) {
4277
4190
  total++;
4278
4191
  this.once("pollComplete", function () {
4279
4192
  --total || pause();
@@ -4295,8 +4208,8 @@ class Polling extends Transport {
4295
4208
  *
4296
4209
  * @private
4297
4210
  */
4298
- poll() {
4299
- this.polling = true;
4211
+ _poll() {
4212
+ this._polling = true;
4300
4213
  this.doPoll();
4301
4214
  this.emitReserved("poll");
4302
4215
  }
@@ -4324,10 +4237,10 @@ class Polling extends Transport {
4324
4237
  // if an event did not trigger closing
4325
4238
  if ("closed" !== this.readyState) {
4326
4239
  // if we got data we're not polling
4327
- this.polling = false;
4240
+ this._polling = false;
4328
4241
  this.emitReserved("pollComplete");
4329
4242
  if ("open" === this.readyState) {
4330
- this.poll();
4243
+ this._poll();
4331
4244
  }
4332
4245
  }
4333
4246
  }
@@ -4374,22 +4287,49 @@ class Polling extends Transport {
4374
4287
  const query = this.query || {};
4375
4288
  // cache busting is forced
4376
4289
  if (false !== this.opts.timestampRequests) {
4377
- query[this.opts.timestampParam] = yeast();
4290
+ query[this.opts.timestampParam] = randomString$1();
4378
4291
  }
4379
4292
  if (!this.supportsBinary && !query.sid) {
4380
4293
  query.b64 = 1;
4381
4294
  }
4382
4295
  return this.createUri(schema, query);
4383
4296
  }
4297
+ }
4298
+
4299
+ // imported from https://github.com/component/has-cors
4300
+ let value = false;
4301
+ try {
4302
+ value = typeof XMLHttpRequest !== 'undefined' &&
4303
+ 'withCredentials' in new XMLHttpRequest();
4304
+ }
4305
+ catch (err) {
4306
+ // if XMLHttp support is disabled in IE then it will throw
4307
+ // when trying to create
4308
+ }
4309
+ const hasCORS = value;
4310
+
4311
+ function empty$2() { }
4312
+ class BaseXHR extends Polling {
4384
4313
  /**
4385
- * Creates a request.
4314
+ * XHR Polling constructor.
4386
4315
  *
4387
- * @param {String} method
4388
- * @private
4316
+ * @param {Object} opts
4317
+ * @package
4389
4318
  */
4390
- request(opts = {}) {
4391
- Object.assign(opts, { xd: this.xd, cookieJar: this.cookieJar }, this.opts);
4392
- return new Request(this.uri(), opts);
4319
+ constructor(opts) {
4320
+ super(opts);
4321
+ if (typeof location !== "undefined") {
4322
+ const isSSL = "https:" === location.protocol;
4323
+ let port = location.port;
4324
+ // some user agents have empty `location.port`
4325
+ if (!port) {
4326
+ port = isSSL ? "443" : "80";
4327
+ }
4328
+ this.xd =
4329
+ (typeof location !== "undefined" &&
4330
+ opts.hostname !== location.hostname) ||
4331
+ port !== opts.port;
4332
+ }
4393
4333
  }
4394
4334
  /**
4395
4335
  * Sends data.
@@ -4429,39 +4369,41 @@ class Request extends Emitter_1 {
4429
4369
  * @param {Object} options
4430
4370
  * @package
4431
4371
  */
4432
- constructor(uri, opts) {
4372
+ constructor(createRequest, uri, opts) {
4433
4373
  super();
4374
+ this.createRequest = createRequest;
4434
4375
  installTimerFunctions(this, opts);
4435
- this.opts = opts;
4436
- this.method = opts.method || "GET";
4437
- this.uri = uri;
4438
- this.data = undefined !== opts.data ? opts.data : null;
4439
- this.create();
4376
+ this._opts = opts;
4377
+ this._method = opts.method || "GET";
4378
+ this._uri = uri;
4379
+ this._data = undefined !== opts.data ? opts.data : null;
4380
+ this._create();
4440
4381
  }
4441
4382
  /**
4442
4383
  * Creates the XHR object and sends the request.
4443
4384
  *
4444
4385
  * @private
4445
4386
  */
4446
- create() {
4387
+ _create() {
4447
4388
  var _a;
4448
- const opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
4449
- opts.xdomain = !!this.opts.xd;
4450
- const xhr = (this.xhr = new XHR(opts));
4389
+ const opts = pick(this._opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
4390
+ opts.xdomain = !!this._opts.xd;
4391
+ const xhr = (this._xhr = this.createRequest(opts));
4451
4392
  try {
4452
- xhr.open(this.method, this.uri, true);
4393
+ xhr.open(this._method, this._uri, true);
4453
4394
  try {
4454
- if (this.opts.extraHeaders) {
4395
+ if (this._opts.extraHeaders) {
4396
+ // @ts-ignore
4455
4397
  xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
4456
- for (let i in this.opts.extraHeaders) {
4457
- if (this.opts.extraHeaders.hasOwnProperty(i)) {
4458
- xhr.setRequestHeader(i, this.opts.extraHeaders[i]);
4398
+ for (let i in this._opts.extraHeaders) {
4399
+ if (this._opts.extraHeaders.hasOwnProperty(i)) {
4400
+ xhr.setRequestHeader(i, this._opts.extraHeaders[i]);
4459
4401
  }
4460
4402
  }
4461
4403
  }
4462
4404
  }
4463
4405
  catch (e) { }
4464
- if ("POST" === this.method) {
4406
+ if ("POST" === this._method) {
4465
4407
  try {
4466
4408
  xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8");
4467
4409
  }
@@ -4471,46 +4413,48 @@ class Request extends Emitter_1 {
4471
4413
  xhr.setRequestHeader("Accept", "*/*");
4472
4414
  }
4473
4415
  catch (e) { }
4474
- (_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
4416
+ (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
4475
4417
  // ie6 check
4476
4418
  if ("withCredentials" in xhr) {
4477
- xhr.withCredentials = this.opts.withCredentials;
4419
+ xhr.withCredentials = this._opts.withCredentials;
4478
4420
  }
4479
- if (this.opts.requestTimeout) {
4480
- xhr.timeout = this.opts.requestTimeout;
4421
+ if (this._opts.requestTimeout) {
4422
+ xhr.timeout = this._opts.requestTimeout;
4481
4423
  }
4482
4424
  xhr.onreadystatechange = () => {
4483
4425
  var _a;
4484
4426
  if (xhr.readyState === 3) {
4485
- (_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(xhr);
4427
+ (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(
4428
+ // @ts-ignore
4429
+ xhr.getResponseHeader("set-cookie"));
4486
4430
  }
4487
4431
  if (4 !== xhr.readyState)
4488
4432
  return;
4489
4433
  if (200 === xhr.status || 1223 === xhr.status) {
4490
- this.onLoad();
4434
+ this._onLoad();
4491
4435
  }
4492
4436
  else {
4493
4437
  // make sure the `error` event handler that's user-set
4494
4438
  // does not throw in the same tick and gets caught here
4495
4439
  this.setTimeoutFn(() => {
4496
- this.onError(typeof xhr.status === "number" ? xhr.status : 0);
4440
+ this._onError(typeof xhr.status === "number" ? xhr.status : 0);
4497
4441
  }, 0);
4498
4442
  }
4499
4443
  };
4500
- xhr.send(this.data);
4444
+ xhr.send(this._data);
4501
4445
  }
4502
4446
  catch (e) {
4503
4447
  // Need to defer since .create() is called directly from the constructor
4504
4448
  // and thus the 'error' event can only be only bound *after* this exception
4505
4449
  // occurs. Therefore, also, we cannot throw here at all.
4506
4450
  this.setTimeoutFn(() => {
4507
- this.onError(e);
4451
+ this._onError(e);
4508
4452
  }, 0);
4509
4453
  return;
4510
4454
  }
4511
4455
  if (typeof document !== "undefined") {
4512
- this.index = Request.requestsCount++;
4513
- Request.requests[this.index] = this;
4456
+ this._index = Request.requestsCount++;
4457
+ Request.requests[this._index] = this;
4514
4458
  }
4515
4459
  }
4516
4460
  /**
@@ -4518,42 +4462,42 @@ class Request extends Emitter_1 {
4518
4462
  *
4519
4463
  * @private
4520
4464
  */
4521
- onError(err) {
4522
- this.emitReserved("error", err, this.xhr);
4523
- this.cleanup(true);
4465
+ _onError(err) {
4466
+ this.emitReserved("error", err, this._xhr);
4467
+ this._cleanup(true);
4524
4468
  }
4525
4469
  /**
4526
4470
  * Cleans up house.
4527
4471
  *
4528
4472
  * @private
4529
4473
  */
4530
- cleanup(fromError) {
4531
- if ("undefined" === typeof this.xhr || null === this.xhr) {
4474
+ _cleanup(fromError) {
4475
+ if ("undefined" === typeof this._xhr || null === this._xhr) {
4532
4476
  return;
4533
4477
  }
4534
- this.xhr.onreadystatechange = empty$2;
4478
+ this._xhr.onreadystatechange = empty$2;
4535
4479
  if (fromError) {
4536
4480
  try {
4537
- this.xhr.abort();
4481
+ this._xhr.abort();
4538
4482
  }
4539
4483
  catch (e) { }
4540
4484
  }
4541
4485
  if (typeof document !== "undefined") {
4542
- delete Request.requests[this.index];
4486
+ delete Request.requests[this._index];
4543
4487
  }
4544
- this.xhr = null;
4488
+ this._xhr = null;
4545
4489
  }
4546
4490
  /**
4547
4491
  * Called upon load.
4548
4492
  *
4549
4493
  * @private
4550
4494
  */
4551
- onLoad() {
4552
- const data = this.xhr.responseText;
4495
+ _onLoad() {
4496
+ const data = this._xhr.responseText;
4553
4497
  if (data !== null) {
4554
4498
  this.emitReserved("data", data);
4555
4499
  this.emitReserved("success");
4556
- this.cleanup();
4500
+ this._cleanup();
4557
4501
  }
4558
4502
  }
4559
4503
  /**
@@ -4562,7 +4506,7 @@ class Request extends Emitter_1 {
4562
4506
  * @package
4563
4507
  */
4564
4508
  abort() {
4565
- this.cleanup();
4509
+ this._cleanup();
4566
4510
  }
4567
4511
  }
4568
4512
  Request.requestsCount = 0;
@@ -4590,43 +4534,56 @@ function unloadHandler() {
4590
4534
  }
4591
4535
  }
4592
4536
  }
4593
-
4594
- const nextTick = (() => {
4595
- const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
4596
- if (isPromiseAvailable) {
4597
- return (cb) => Promise.resolve().then(cb);
4537
+ const hasXHR2 = (function () {
4538
+ const xhr = newRequest({
4539
+ xdomain: false,
4540
+ });
4541
+ return xhr && xhr.responseType !== null;
4542
+ })();
4543
+ /**
4544
+ * HTTP long-polling based on the built-in `XMLHttpRequest` object.
4545
+ *
4546
+ * Usage: browser
4547
+ *
4548
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
4549
+ */
4550
+ class XHR extends BaseXHR {
4551
+ constructor(opts) {
4552
+ super(opts);
4553
+ const forceBase64 = opts && opts.forceBase64;
4554
+ this.supportsBinary = hasXHR2 && !forceBase64;
4598
4555
  }
4599
- else {
4600
- return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
4556
+ request(opts = {}) {
4557
+ Object.assign(opts, { xd: this.xd }, this.opts);
4558
+ return new Request(newRequest, this.uri(), opts);
4601
4559
  }
4602
- })();
4603
- const WebSocket$1 = globalThisShim.WebSocket || globalThisShim.MozWebSocket;
4604
- const usingBrowserWebSocket = true;
4605
- const defaultBinaryType = "arraybuffer";
4560
+ }
4561
+ function newRequest(opts) {
4562
+ const xdomain = opts.xdomain;
4563
+ // XMLHttpRequest can be disabled on IE
4564
+ try {
4565
+ if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
4566
+ return new XMLHttpRequest();
4567
+ }
4568
+ }
4569
+ catch (e) { }
4570
+ if (!xdomain) {
4571
+ try {
4572
+ return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
4573
+ }
4574
+ catch (e) { }
4575
+ }
4576
+ }
4606
4577
 
4607
4578
  // detect ReactNative environment
4608
4579
  const isReactNative = typeof navigator !== "undefined" &&
4609
4580
  typeof navigator.product === "string" &&
4610
4581
  navigator.product.toLowerCase() === "reactnative";
4611
- class WS extends Transport {
4612
- /**
4613
- * WebSocket transport constructor.
4614
- *
4615
- * @param {Object} opts - connection options
4616
- * @protected
4617
- */
4618
- constructor(opts) {
4619
- super(opts);
4620
- this.supportsBinary = !opts.forceBase64;
4621
- }
4582
+ class BaseWS extends Transport {
4622
4583
  get name() {
4623
4584
  return "websocket";
4624
4585
  }
4625
4586
  doOpen() {
4626
- if (!this.check()) {
4627
- // let probe timeout
4628
- return;
4629
- }
4630
4587
  const uri = this.uri();
4631
4588
  const protocols = this.opts.protocols;
4632
4589
  // React Native only supports the 'headers' option, and will print a warning if anything else is passed
@@ -4637,12 +4594,7 @@ class WS extends Transport {
4637
4594
  opts.headers = this.opts.extraHeaders;
4638
4595
  }
4639
4596
  try {
4640
- this.ws =
4641
- usingBrowserWebSocket && !isReactNative
4642
- ? protocols
4643
- ? new WebSocket$1(uri, protocols)
4644
- : new WebSocket$1(uri)
4645
- : new WebSocket$1(uri, protocols, opts);
4597
+ this.ws = this.createSocket(uri, protocols, opts);
4646
4598
  }
4647
4599
  catch (err) {
4648
4600
  return this.emitReserved("error", err);
@@ -4677,16 +4629,11 @@ class WS extends Transport {
4677
4629
  const packet = packets[i];
4678
4630
  const lastPacket = i === packets.length - 1;
4679
4631
  encodePacket(packet, this.supportsBinary, (data) => {
4680
- // always create a new object (GH-437)
4681
- const opts = {};
4682
4632
  // Sometimes the websocket has already been closed but the browser didn't
4683
4633
  // have a chance of informing us about it yet, in that case send will
4684
4634
  // throw an error
4685
4635
  try {
4686
- if (usingBrowserWebSocket) {
4687
- // TypeError is thrown when passing the second argument on Safari
4688
- this.ws.send(data);
4689
- }
4636
+ this.doWrite(packet, data);
4690
4637
  }
4691
4638
  catch (e) {
4692
4639
  }
@@ -4703,6 +4650,7 @@ class WS extends Transport {
4703
4650
  }
4704
4651
  doClose() {
4705
4652
  if (typeof this.ws !== "undefined") {
4653
+ this.ws.onerror = () => { };
4706
4654
  this.ws.close();
4707
4655
  this.ws = null;
4708
4656
  }
@@ -4717,7 +4665,7 @@ class WS extends Transport {
4717
4665
  const query = this.query || {};
4718
4666
  // append timestamp to URI
4719
4667
  if (this.opts.timestampRequests) {
4720
- query[this.opts.timestampParam] = yeast();
4668
+ query[this.opts.timestampParam] = randomString$1();
4721
4669
  }
4722
4670
  // communicate binary support capabilities
4723
4671
  if (!this.supportsBinary) {
@@ -4725,29 +4673,51 @@ class WS extends Transport {
4725
4673
  }
4726
4674
  return this.createUri(schema, query);
4727
4675
  }
4728
- /**
4729
- * Feature detection for WebSocket.
4730
- *
4731
- * @return {Boolean} whether this transport is available.
4732
- * @private
4733
- */
4734
- check() {
4735
- return !!WebSocket$1;
4676
+ }
4677
+ const WebSocketCtor = globalThisShim.WebSocket || globalThisShim.MozWebSocket;
4678
+ /**
4679
+ * WebSocket transport based on the built-in `WebSocket` object.
4680
+ *
4681
+ * Usage: browser, Node.js (since v21), Deno, Bun
4682
+ *
4683
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
4684
+ * @see https://caniuse.com/mdn-api_websocket
4685
+ * @see https://nodejs.org/api/globals.html#websocket
4686
+ */
4687
+ class WS extends BaseWS {
4688
+ createSocket(uri, protocols, opts) {
4689
+ return !isReactNative
4690
+ ? protocols
4691
+ ? new WebSocketCtor(uri, protocols)
4692
+ : new WebSocketCtor(uri)
4693
+ : new WebSocketCtor(uri, protocols, opts);
4694
+ }
4695
+ doWrite(_packet, data) {
4696
+ this.ws.send(data);
4736
4697
  }
4737
4698
  }
4738
4699
 
4700
+ /**
4701
+ * WebTransport transport based on the built-in `WebTransport` object.
4702
+ *
4703
+ * Usage: browser, Node.js (with the `@fails-components/webtransport` package)
4704
+ *
4705
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/WebTransport
4706
+ * @see https://caniuse.com/webtransport
4707
+ */
4739
4708
  class WT extends Transport {
4740
4709
  get name() {
4741
4710
  return "webtransport";
4742
4711
  }
4743
4712
  doOpen() {
4744
- // @ts-ignore
4745
- if (typeof WebTransport !== "function") {
4746
- return;
4713
+ try {
4714
+ // @ts-ignore
4715
+ this._transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
4747
4716
  }
4748
- // @ts-ignore
4749
- this.transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
4750
- this.transport.closed
4717
+ catch (err) {
4718
+ return this.emitReserved("error", err);
4719
+ }
4720
+ this._transport.closed
4751
4721
  .then(() => {
4752
4722
  this.onClose();
4753
4723
  })
@@ -4755,13 +4725,13 @@ class WT extends Transport {
4755
4725
  this.onError("webtransport error", err);
4756
4726
  });
4757
4727
  // note: we could have used async/await, but that would require some additional polyfills
4758
- this.transport.ready.then(() => {
4759
- this.transport.createBidirectionalStream().then((stream) => {
4728
+ this._transport.ready.then(() => {
4729
+ this._transport.createBidirectionalStream().then((stream) => {
4760
4730
  const decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, this.socket.binaryType);
4761
4731
  const reader = stream.readable.pipeThrough(decoderStream).getReader();
4762
4732
  const encoderStream = createPacketEncoderStream();
4763
4733
  encoderStream.readable.pipeTo(stream.writable);
4764
- this.writer = encoderStream.writable.getWriter();
4734
+ this._writer = encoderStream.writable.getWriter();
4765
4735
  const read = () => {
4766
4736
  reader
4767
4737
  .read()
@@ -4780,7 +4750,7 @@ class WT extends Transport {
4780
4750
  if (this.query.sid) {
4781
4751
  packet.data = `{"sid":"${this.query.sid}"}`;
4782
4752
  }
4783
- this.writer.write(packet).then(() => this.onOpen());
4753
+ this._writer.write(packet).then(() => this.onOpen());
4784
4754
  });
4785
4755
  });
4786
4756
  }
@@ -4789,7 +4759,7 @@ class WT extends Transport {
4789
4759
  for (let i = 0; i < packets.length; i++) {
4790
4760
  const packet = packets[i];
4791
4761
  const lastPacket = i === packets.length - 1;
4792
- this.writer.write(packet).then(() => {
4762
+ this._writer.write(packet).then(() => {
4793
4763
  if (lastPacket) {
4794
4764
  nextTick(() => {
4795
4765
  this.writable = true;
@@ -4801,14 +4771,14 @@ class WT extends Transport {
4801
4771
  }
4802
4772
  doClose() {
4803
4773
  var _a;
4804
- (_a = this.transport) === null || _a === void 0 ? void 0 : _a.close();
4774
+ (_a = this._transport) === null || _a === void 0 ? void 0 : _a.close();
4805
4775
  }
4806
4776
  }
4807
4777
 
4808
4778
  const transports = {
4809
4779
  websocket: WS,
4810
4780
  webtransport: WT,
4811
- polling: Polling,
4781
+ polling: XHR,
4812
4782
  };
4813
4783
 
4814
4784
  // imported from https://github.com/galkn/parseuri
@@ -4835,7 +4805,7 @@ const parts = [
4835
4805
  'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
4836
4806
  ];
4837
4807
  function parse$2(str) {
4838
- if (str.length > 2000) {
4808
+ if (str.length > 8000) {
4839
4809
  throw "URI too long";
4840
4810
  }
4841
4811
  const src = str, b = str.indexOf('['), e = str.indexOf(']');
@@ -4876,28 +4846,71 @@ function queryKey(uri, query) {
4876
4846
  return data;
4877
4847
  }
4878
4848
 
4879
- let Socket$1 = class Socket extends Emitter_1 {
4849
+ const withEventListeners = typeof addEventListener === "function" &&
4850
+ typeof removeEventListener === "function";
4851
+ const OFFLINE_EVENT_LISTENERS = [];
4852
+ if (withEventListeners) {
4853
+ // within a ServiceWorker, any event handler for the 'offline' event must be added on the initial evaluation of the
4854
+ // script, so we create one single event listener here which will forward the event to the socket instances
4855
+ addEventListener("offline", () => {
4856
+ OFFLINE_EVENT_LISTENERS.forEach((listener) => listener());
4857
+ }, false);
4858
+ }
4859
+ /**
4860
+ * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
4861
+ * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
4862
+ *
4863
+ * This class comes without upgrade mechanism, which means that it will keep the first low-level transport that
4864
+ * successfully establishes the connection.
4865
+ *
4866
+ * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
4867
+ *
4868
+ * @example
4869
+ * import { SocketWithoutUpgrade, WebSocket } from "engine.io-client";
4870
+ *
4871
+ * const socket = new SocketWithoutUpgrade({
4872
+ * transports: [WebSocket]
4873
+ * });
4874
+ *
4875
+ * socket.on("open", () => {
4876
+ * socket.send("hello");
4877
+ * });
4878
+ *
4879
+ * @see SocketWithUpgrade
4880
+ * @see Socket
4881
+ */
4882
+ class SocketWithoutUpgrade extends Emitter_1 {
4880
4883
  /**
4881
4884
  * Socket constructor.
4882
4885
  *
4883
4886
  * @param {String|Object} uri - uri or options
4884
4887
  * @param {Object} opts - options
4885
4888
  */
4886
- constructor(uri, opts = {}) {
4889
+ constructor(uri, opts) {
4887
4890
  super();
4888
4891
  this.binaryType = defaultBinaryType;
4889
4892
  this.writeBuffer = [];
4893
+ this._prevBufferLen = 0;
4894
+ this._pingInterval = -1;
4895
+ this._pingTimeout = -1;
4896
+ this._maxPayload = -1;
4897
+ /**
4898
+ * The expiration timestamp of the {@link _pingTimeoutTimer} object is tracked, in case the timer is throttled and the
4899
+ * callback is not fired on time. This can happen for example when a laptop is suspended or when a phone is locked.
4900
+ */
4901
+ this._pingTimeoutTime = Infinity;
4890
4902
  if (uri && "object" === typeof uri) {
4891
4903
  opts = uri;
4892
4904
  uri = null;
4893
4905
  }
4894
4906
  if (uri) {
4895
- uri = parse$2(uri);
4896
- opts.hostname = uri.host;
4897
- opts.secure = uri.protocol === "https" || uri.protocol === "wss";
4898
- opts.port = uri.port;
4899
- if (uri.query)
4900
- opts.query = uri.query;
4907
+ const parsedUri = parse$2(uri);
4908
+ opts.hostname = parsedUri.host;
4909
+ opts.secure =
4910
+ parsedUri.protocol === "https" || parsedUri.protocol === "wss";
4911
+ opts.port = parsedUri.port;
4912
+ if (parsedUri.query)
4913
+ opts.query = parsedUri.query;
4901
4914
  }
4902
4915
  else if (opts.host) {
4903
4916
  opts.hostname = parse$2(opts.host).host;
@@ -4921,13 +4934,13 @@ let Socket$1 = class Socket extends Emitter_1 {
4921
4934
  : this.secure
4922
4935
  ? "443"
4923
4936
  : "80");
4924
- this.transports = opts.transports || [
4925
- "polling",
4926
- "websocket",
4927
- "webtransport",
4928
- ];
4929
- this.writeBuffer = [];
4930
- this.prevBufferLen = 0;
4937
+ this.transports = [];
4938
+ this._transportsByName = {};
4939
+ opts.transports.forEach((t) => {
4940
+ const transportName = t.prototype.name;
4941
+ this.transports.push(transportName);
4942
+ this._transportsByName[transportName] = t;
4943
+ });
4931
4944
  this.opts = Object.assign({
4932
4945
  path: "/engine.io",
4933
4946
  agent: false,
@@ -4949,37 +4962,33 @@ let Socket$1 = class Socket extends Emitter_1 {
4949
4962
  if (typeof this.opts.query === "string") {
4950
4963
  this.opts.query = decode(this.opts.query);
4951
4964
  }
4952
- // set on handshake
4953
- this.id = null;
4954
- this.upgrades = null;
4955
- this.pingInterval = null;
4956
- this.pingTimeout = null;
4957
- // set on heartbeat
4958
- this.pingTimeoutTimer = null;
4959
- if (typeof addEventListener === "function") {
4965
+ if (withEventListeners) {
4960
4966
  if (this.opts.closeOnBeforeunload) {
4961
4967
  // Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
4962
4968
  // ensures every browser behaves the same (no "disconnect" event at the Socket.IO level when the page is
4963
4969
  // closed/reloaded)
4964
- this.beforeunloadEventListener = () => {
4970
+ this._beforeunloadEventListener = () => {
4965
4971
  if (this.transport) {
4966
4972
  // silently close the transport
4967
4973
  this.transport.removeAllListeners();
4968
4974
  this.transport.close();
4969
4975
  }
4970
4976
  };
4971
- addEventListener("beforeunload", this.beforeunloadEventListener, false);
4977
+ addEventListener("beforeunload", this._beforeunloadEventListener, false);
4972
4978
  }
4973
4979
  if (this.hostname !== "localhost") {
4974
- this.offlineEventListener = () => {
4975
- this.onClose("transport close", {
4980
+ this._offlineEventListener = () => {
4981
+ this._onClose("transport close", {
4976
4982
  description: "network connection lost",
4977
4983
  });
4978
4984
  };
4979
- addEventListener("offline", this.offlineEventListener, false);
4985
+ OFFLINE_EVENT_LISTENERS.push(this._offlineEventListener);
4980
4986
  }
4981
4987
  }
4982
- this.open();
4988
+ if (this.opts.withCredentials) {
4989
+ this._cookieJar = createCookieJar();
4990
+ }
4991
+ this._open();
4983
4992
  }
4984
4993
  /**
4985
4994
  * Creates transport of the given type.
@@ -5004,40 +5013,28 @@ let Socket$1 = class Socket extends Emitter_1 {
5004
5013
  secure: this.secure,
5005
5014
  port: this.port,
5006
5015
  }, this.opts.transportOptions[name]);
5007
- return new transports[name](opts);
5016
+ return new this._transportsByName[name](opts);
5008
5017
  }
5009
5018
  /**
5010
5019
  * Initializes transport to use and starts probe.
5011
5020
  *
5012
5021
  * @private
5013
5022
  */
5014
- open() {
5015
- let transport;
5016
- if (this.opts.rememberUpgrade &&
5017
- Socket.priorWebsocketSuccess &&
5018
- this.transports.indexOf("websocket") !== -1) {
5019
- transport = "websocket";
5020
- }
5021
- else if (0 === this.transports.length) {
5023
+ _open() {
5024
+ if (this.transports.length === 0) {
5022
5025
  // Emit error on next tick so it can be listened to
5023
5026
  this.setTimeoutFn(() => {
5024
5027
  this.emitReserved("error", "No transports available");
5025
5028
  }, 0);
5026
5029
  return;
5027
5030
  }
5028
- else {
5029
- transport = this.transports[0];
5030
- }
5031
+ const transportName = this.opts.rememberUpgrade &&
5032
+ SocketWithoutUpgrade.priorWebsocketSuccess &&
5033
+ this.transports.indexOf("websocket") !== -1
5034
+ ? "websocket"
5035
+ : this.transports[0];
5031
5036
  this.readyState = "opening";
5032
- // Retry with the next transport if the transport is disabled (jsonp: false)
5033
- try {
5034
- transport = this.createTransport(transport);
5035
- }
5036
- catch (e) {
5037
- this.transports.shift();
5038
- this.open();
5039
- return;
5040
- }
5037
+ const transport = this.createTransport(transportName);
5041
5038
  transport.open();
5042
5039
  this.setTransport(transport);
5043
5040
  }
@@ -5054,111 +5051,10 @@ let Socket$1 = class Socket extends Emitter_1 {
5054
5051
  this.transport = transport;
5055
5052
  // set up transport listeners
5056
5053
  transport
5057
- .on("drain", this.onDrain.bind(this))
5058
- .on("packet", this.onPacket.bind(this))
5059
- .on("error", this.onError.bind(this))
5060
- .on("close", (reason) => this.onClose("transport close", reason));
5061
- }
5062
- /**
5063
- * Probes a transport.
5064
- *
5065
- * @param {String} name - transport name
5066
- * @private
5067
- */
5068
- probe(name) {
5069
- let transport = this.createTransport(name);
5070
- let failed = false;
5071
- Socket.priorWebsocketSuccess = false;
5072
- const onTransportOpen = () => {
5073
- if (failed)
5074
- return;
5075
- transport.send([{ type: "ping", data: "probe" }]);
5076
- transport.once("packet", (msg) => {
5077
- if (failed)
5078
- return;
5079
- if ("pong" === msg.type && "probe" === msg.data) {
5080
- this.upgrading = true;
5081
- this.emitReserved("upgrading", transport);
5082
- if (!transport)
5083
- return;
5084
- Socket.priorWebsocketSuccess = "websocket" === transport.name;
5085
- this.transport.pause(() => {
5086
- if (failed)
5087
- return;
5088
- if ("closed" === this.readyState)
5089
- return;
5090
- cleanup();
5091
- this.setTransport(transport);
5092
- transport.send([{ type: "upgrade" }]);
5093
- this.emitReserved("upgrade", transport);
5094
- transport = null;
5095
- this.upgrading = false;
5096
- this.flush();
5097
- });
5098
- }
5099
- else {
5100
- const err = new Error("probe error");
5101
- // @ts-ignore
5102
- err.transport = transport.name;
5103
- this.emitReserved("upgradeError", err);
5104
- }
5105
- });
5106
- };
5107
- function freezeTransport() {
5108
- if (failed)
5109
- return;
5110
- // Any callback called by transport should be ignored since now
5111
- failed = true;
5112
- cleanup();
5113
- transport.close();
5114
- transport = null;
5115
- }
5116
- // Handle any error that happens while probing
5117
- const onerror = (err) => {
5118
- const error = new Error("probe error: " + err);
5119
- // @ts-ignore
5120
- error.transport = transport.name;
5121
- freezeTransport();
5122
- this.emitReserved("upgradeError", error);
5123
- };
5124
- function onTransportClose() {
5125
- onerror("transport closed");
5126
- }
5127
- // When the socket is closed while we're probing
5128
- function onclose() {
5129
- onerror("socket closed");
5130
- }
5131
- // When the socket is upgraded while we're probing
5132
- function onupgrade(to) {
5133
- if (transport && to.name !== transport.name) {
5134
- freezeTransport();
5135
- }
5136
- }
5137
- // Remove all listeners on the transport and on self
5138
- const cleanup = () => {
5139
- transport.removeListener("open", onTransportOpen);
5140
- transport.removeListener("error", onerror);
5141
- transport.removeListener("close", onTransportClose);
5142
- this.off("close", onclose);
5143
- this.off("upgrading", onupgrade);
5144
- };
5145
- transport.once("open", onTransportOpen);
5146
- transport.once("error", onerror);
5147
- transport.once("close", onTransportClose);
5148
- this.once("close", onclose);
5149
- this.once("upgrading", onupgrade);
5150
- if (this.upgrades.indexOf("webtransport") !== -1 &&
5151
- name !== "webtransport") {
5152
- // favor WebTransport
5153
- this.setTimeoutFn(() => {
5154
- if (!failed) {
5155
- transport.open();
5156
- }
5157
- }, 200);
5158
- }
5159
- else {
5160
- transport.open();
5161
- }
5054
+ .on("drain", this._onDrain.bind(this))
5055
+ .on("packet", this._onPacket.bind(this))
5056
+ .on("error", this._onError.bind(this))
5057
+ .on("close", (reason) => this._onClose("transport close", reason));
5162
5058
  }
5163
5059
  /**
5164
5060
  * Called when connection is deemed open.
@@ -5167,46 +5063,38 @@ let Socket$1 = class Socket extends Emitter_1 {
5167
5063
  */
5168
5064
  onOpen() {
5169
5065
  this.readyState = "open";
5170
- Socket.priorWebsocketSuccess = "websocket" === this.transport.name;
5066
+ SocketWithoutUpgrade.priorWebsocketSuccess =
5067
+ "websocket" === this.transport.name;
5171
5068
  this.emitReserved("open");
5172
5069
  this.flush();
5173
- // we check for `readyState` in case an `open`
5174
- // listener already closed the socket
5175
- if ("open" === this.readyState && this.opts.upgrade) {
5176
- let i = 0;
5177
- const l = this.upgrades.length;
5178
- for (; i < l; i++) {
5179
- this.probe(this.upgrades[i]);
5180
- }
5181
- }
5182
5070
  }
5183
5071
  /**
5184
5072
  * Handles a packet.
5185
5073
  *
5186
5074
  * @private
5187
5075
  */
5188
- onPacket(packet) {
5076
+ _onPacket(packet) {
5189
5077
  if ("opening" === this.readyState ||
5190
5078
  "open" === this.readyState ||
5191
5079
  "closing" === this.readyState) {
5192
5080
  this.emitReserved("packet", packet);
5193
5081
  // Socket is live - any packet counts
5194
5082
  this.emitReserved("heartbeat");
5195
- this.resetPingTimeout();
5196
5083
  switch (packet.type) {
5197
5084
  case "open":
5198
5085
  this.onHandshake(JSON.parse(packet.data));
5199
5086
  break;
5200
5087
  case "ping":
5201
- this.sendPacket("pong");
5088
+ this._sendPacket("pong");
5202
5089
  this.emitReserved("ping");
5203
5090
  this.emitReserved("pong");
5091
+ this._resetPingTimeout();
5204
5092
  break;
5205
5093
  case "error":
5206
5094
  const err = new Error("server error");
5207
5095
  // @ts-ignore
5208
5096
  err.code = packet.data;
5209
- this.onError(err);
5097
+ this._onError(err);
5210
5098
  break;
5211
5099
  case "message":
5212
5100
  this.emitReserved("data", packet.data);
@@ -5225,28 +5113,29 @@ let Socket$1 = class Socket extends Emitter_1 {
5225
5113
  this.emitReserved("handshake", data);
5226
5114
  this.id = data.sid;
5227
5115
  this.transport.query.sid = data.sid;
5228
- this.upgrades = this.filterUpgrades(data.upgrades);
5229
- this.pingInterval = data.pingInterval;
5230
- this.pingTimeout = data.pingTimeout;
5231
- this.maxPayload = data.maxPayload;
5116
+ this._pingInterval = data.pingInterval;
5117
+ this._pingTimeout = data.pingTimeout;
5118
+ this._maxPayload = data.maxPayload;
5232
5119
  this.onOpen();
5233
5120
  // In case open handler closes socket
5234
5121
  if ("closed" === this.readyState)
5235
5122
  return;
5236
- this.resetPingTimeout();
5123
+ this._resetPingTimeout();
5237
5124
  }
5238
5125
  /**
5239
5126
  * Sets and resets ping timeout timer based on server pings.
5240
5127
  *
5241
5128
  * @private
5242
5129
  */
5243
- resetPingTimeout() {
5244
- this.clearTimeoutFn(this.pingTimeoutTimer);
5245
- this.pingTimeoutTimer = this.setTimeoutFn(() => {
5246
- this.onClose("ping timeout");
5247
- }, this.pingInterval + this.pingTimeout);
5130
+ _resetPingTimeout() {
5131
+ this.clearTimeoutFn(this._pingTimeoutTimer);
5132
+ const delay = this._pingInterval + this._pingTimeout;
5133
+ this._pingTimeoutTime = Date.now() + delay;
5134
+ this._pingTimeoutTimer = this.setTimeoutFn(() => {
5135
+ this._onClose("ping timeout");
5136
+ }, delay);
5248
5137
  if (this.opts.autoUnref) {
5249
- this.pingTimeoutTimer.unref();
5138
+ this._pingTimeoutTimer.unref();
5250
5139
  }
5251
5140
  }
5252
5141
  /**
@@ -5254,12 +5143,12 @@ let Socket$1 = class Socket extends Emitter_1 {
5254
5143
  *
5255
5144
  * @private
5256
5145
  */
5257
- onDrain() {
5258
- this.writeBuffer.splice(0, this.prevBufferLen);
5146
+ _onDrain() {
5147
+ this.writeBuffer.splice(0, this._prevBufferLen);
5259
5148
  // setting prevBufferLen = 0 is very important
5260
5149
  // for example, when upgrading, upgrade packet is sent over,
5261
5150
  // and a nonzero prevBufferLen could cause problems on `drain`
5262
- this.prevBufferLen = 0;
5151
+ this._prevBufferLen = 0;
5263
5152
  if (0 === this.writeBuffer.length) {
5264
5153
  this.emitReserved("drain");
5265
5154
  }
@@ -5277,11 +5166,11 @@ let Socket$1 = class Socket extends Emitter_1 {
5277
5166
  this.transport.writable &&
5278
5167
  !this.upgrading &&
5279
5168
  this.writeBuffer.length) {
5280
- const packets = this.getWritablePackets();
5169
+ const packets = this._getWritablePackets();
5281
5170
  this.transport.send(packets);
5282
5171
  // keep track of current length of writeBuffer
5283
5172
  // splice writeBuffer and callbackBuffer on `drain`
5284
- this.prevBufferLen = packets.length;
5173
+ this._prevBufferLen = packets.length;
5285
5174
  this.emitReserved("flush");
5286
5175
  }
5287
5176
  }
@@ -5291,8 +5180,8 @@ let Socket$1 = class Socket extends Emitter_1 {
5291
5180
  *
5292
5181
  * @private
5293
5182
  */
5294
- getWritablePackets() {
5295
- const shouldCheckPayloadSize = this.maxPayload &&
5183
+ _getWritablePackets() {
5184
+ const shouldCheckPayloadSize = this._maxPayload &&
5296
5185
  this.transport.name === "polling" &&
5297
5186
  this.writeBuffer.length > 1;
5298
5187
  if (!shouldCheckPayloadSize) {
@@ -5304,27 +5193,56 @@ let Socket$1 = class Socket extends Emitter_1 {
5304
5193
  if (data) {
5305
5194
  payloadSize += byteLength(data);
5306
5195
  }
5307
- if (i > 0 && payloadSize > this.maxPayload) {
5196
+ if (i > 0 && payloadSize > this._maxPayload) {
5308
5197
  return this.writeBuffer.slice(0, i);
5309
5198
  }
5310
5199
  payloadSize += 2; // separator + packet type
5311
5200
  }
5312
5201
  return this.writeBuffer;
5313
5202
  }
5203
+ /**
5204
+ * Checks whether the heartbeat timer has expired but the socket has not yet been notified.
5205
+ *
5206
+ * Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the
5207
+ * `write()` method then the message would not be buffered by the Socket.IO client.
5208
+ *
5209
+ * @return {boolean}
5210
+ * @private
5211
+ */
5212
+ /* private */ _hasPingExpired() {
5213
+ if (!this._pingTimeoutTime)
5214
+ return true;
5215
+ const hasExpired = Date.now() > this._pingTimeoutTime;
5216
+ if (hasExpired) {
5217
+ this._pingTimeoutTime = 0;
5218
+ nextTick(() => {
5219
+ this._onClose("ping timeout");
5220
+ }, this.setTimeoutFn);
5221
+ }
5222
+ return hasExpired;
5223
+ }
5314
5224
  /**
5315
5225
  * Sends a message.
5316
5226
  *
5317
5227
  * @param {String} msg - message.
5318
5228
  * @param {Object} options.
5319
- * @param {Function} callback function.
5229
+ * @param {Function} fn - callback function.
5320
5230
  * @return {Socket} for chaining.
5321
5231
  */
5322
5232
  write(msg, options, fn) {
5323
- this.sendPacket("message", msg, options, fn);
5233
+ this._sendPacket("message", msg, options, fn);
5324
5234
  return this;
5325
5235
  }
5236
+ /**
5237
+ * Sends a message. Alias of {@link Socket#write}.
5238
+ *
5239
+ * @param {String} msg - message.
5240
+ * @param {Object} options.
5241
+ * @param {Function} fn - callback function.
5242
+ * @return {Socket} for chaining.
5243
+ */
5326
5244
  send(msg, options, fn) {
5327
- this.sendPacket("message", msg, options, fn);
5245
+ this._sendPacket("message", msg, options, fn);
5328
5246
  return this;
5329
5247
  }
5330
5248
  /**
@@ -5336,7 +5254,7 @@ let Socket$1 = class Socket extends Emitter_1 {
5336
5254
  * @param {Function} fn - callback function.
5337
5255
  * @private
5338
5256
  */
5339
- sendPacket(type, data, options, fn) {
5257
+ _sendPacket(type, data, options, fn) {
5340
5258
  if ("function" === typeof data) {
5341
5259
  fn = data;
5342
5260
  data = undefined;
@@ -5366,7 +5284,7 @@ let Socket$1 = class Socket extends Emitter_1 {
5366
5284
  */
5367
5285
  close() {
5368
5286
  const close = () => {
5369
- this.onClose("forced close");
5287
+ this._onClose("forced close");
5370
5288
  this.transport.close();
5371
5289
  };
5372
5290
  const cleanupAndClose = () => {
@@ -5405,31 +5323,44 @@ let Socket$1 = class Socket extends Emitter_1 {
5405
5323
  *
5406
5324
  * @private
5407
5325
  */
5408
- onError(err) {
5409
- Socket.priorWebsocketSuccess = false;
5326
+ _onError(err) {
5327
+ SocketWithoutUpgrade.priorWebsocketSuccess = false;
5328
+ if (this.opts.tryAllTransports &&
5329
+ this.transports.length > 1 &&
5330
+ this.readyState === "opening") {
5331
+ this.transports.shift();
5332
+ return this._open();
5333
+ }
5410
5334
  this.emitReserved("error", err);
5411
- this.onClose("transport error", err);
5335
+ this._onClose("transport error", err);
5412
5336
  }
5413
5337
  /**
5414
5338
  * Called upon transport close.
5415
5339
  *
5416
5340
  * @private
5417
5341
  */
5418
- onClose(reason, description) {
5342
+ _onClose(reason, description) {
5419
5343
  if ("opening" === this.readyState ||
5420
5344
  "open" === this.readyState ||
5421
5345
  "closing" === this.readyState) {
5422
5346
  // clear timers
5423
- this.clearTimeoutFn(this.pingTimeoutTimer);
5347
+ this.clearTimeoutFn(this._pingTimeoutTimer);
5424
5348
  // stop event from firing again for transport
5425
5349
  this.transport.removeAllListeners("close");
5426
5350
  // ensure transport won't stay open
5427
5351
  this.transport.close();
5428
5352
  // ignore further transport communication
5429
5353
  this.transport.removeAllListeners();
5430
- if (typeof removeEventListener === "function") {
5431
- removeEventListener("beforeunload", this.beforeunloadEventListener, false);
5432
- removeEventListener("offline", this.offlineEventListener, false);
5354
+ if (withEventListeners) {
5355
+ if (this._beforeunloadEventListener) {
5356
+ removeEventListener("beforeunload", this._beforeunloadEventListener, false);
5357
+ }
5358
+ if (this._offlineEventListener) {
5359
+ const i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener);
5360
+ if (i !== -1) {
5361
+ OFFLINE_EVENT_LISTENERS.splice(i, 1);
5362
+ }
5363
+ }
5433
5364
  }
5434
5365
  // set ready state
5435
5366
  this.readyState = "closed";
@@ -5440,27 +5371,199 @@ let Socket$1 = class Socket extends Emitter_1 {
5440
5371
  // clean buffers after, so users can still
5441
5372
  // grab the buffers on `close` event
5442
5373
  this.writeBuffer = [];
5443
- this.prevBufferLen = 0;
5374
+ this._prevBufferLen = 0;
5444
5375
  }
5445
5376
  }
5377
+ }
5378
+ SocketWithoutUpgrade.protocol = protocol$1;
5379
+ /**
5380
+ * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
5381
+ * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
5382
+ *
5383
+ * This class comes with an upgrade mechanism, which means that once the connection is established with the first
5384
+ * low-level transport, it will try to upgrade to a better transport.
5385
+ *
5386
+ * In order to allow tree-shaking, there are no transports included, that's why the `transports` option is mandatory.
5387
+ *
5388
+ * @example
5389
+ * import { SocketWithUpgrade, WebSocket } from "engine.io-client";
5390
+ *
5391
+ * const socket = new SocketWithUpgrade({
5392
+ * transports: [WebSocket]
5393
+ * });
5394
+ *
5395
+ * socket.on("open", () => {
5396
+ * socket.send("hello");
5397
+ * });
5398
+ *
5399
+ * @see SocketWithoutUpgrade
5400
+ * @see Socket
5401
+ */
5402
+ class SocketWithUpgrade extends SocketWithoutUpgrade {
5403
+ constructor() {
5404
+ super(...arguments);
5405
+ this._upgrades = [];
5406
+ }
5407
+ onOpen() {
5408
+ super.onOpen();
5409
+ if ("open" === this.readyState && this.opts.upgrade) {
5410
+ for (let i = 0; i < this._upgrades.length; i++) {
5411
+ this._probe(this._upgrades[i]);
5412
+ }
5413
+ }
5414
+ }
5415
+ /**
5416
+ * Probes a transport.
5417
+ *
5418
+ * @param {String} name - transport name
5419
+ * @private
5420
+ */
5421
+ _probe(name) {
5422
+ let transport = this.createTransport(name);
5423
+ let failed = false;
5424
+ SocketWithoutUpgrade.priorWebsocketSuccess = false;
5425
+ const onTransportOpen = () => {
5426
+ if (failed)
5427
+ return;
5428
+ transport.send([{ type: "ping", data: "probe" }]);
5429
+ transport.once("packet", (msg) => {
5430
+ if (failed)
5431
+ return;
5432
+ if ("pong" === msg.type && "probe" === msg.data) {
5433
+ this.upgrading = true;
5434
+ this.emitReserved("upgrading", transport);
5435
+ if (!transport)
5436
+ return;
5437
+ SocketWithoutUpgrade.priorWebsocketSuccess =
5438
+ "websocket" === transport.name;
5439
+ this.transport.pause(() => {
5440
+ if (failed)
5441
+ return;
5442
+ if ("closed" === this.readyState)
5443
+ return;
5444
+ cleanup();
5445
+ this.setTransport(transport);
5446
+ transport.send([{ type: "upgrade" }]);
5447
+ this.emitReserved("upgrade", transport);
5448
+ transport = null;
5449
+ this.upgrading = false;
5450
+ this.flush();
5451
+ });
5452
+ }
5453
+ else {
5454
+ const err = new Error("probe error");
5455
+ // @ts-ignore
5456
+ err.transport = transport.name;
5457
+ this.emitReserved("upgradeError", err);
5458
+ }
5459
+ });
5460
+ };
5461
+ function freezeTransport() {
5462
+ if (failed)
5463
+ return;
5464
+ // Any callback called by transport should be ignored since now
5465
+ failed = true;
5466
+ cleanup();
5467
+ transport.close();
5468
+ transport = null;
5469
+ }
5470
+ // Handle any error that happens while probing
5471
+ const onerror = (err) => {
5472
+ const error = new Error("probe error: " + err);
5473
+ // @ts-ignore
5474
+ error.transport = transport.name;
5475
+ freezeTransport();
5476
+ this.emitReserved("upgradeError", error);
5477
+ };
5478
+ function onTransportClose() {
5479
+ onerror("transport closed");
5480
+ }
5481
+ // When the socket is closed while we're probing
5482
+ function onclose() {
5483
+ onerror("socket closed");
5484
+ }
5485
+ // When the socket is upgraded while we're probing
5486
+ function onupgrade(to) {
5487
+ if (transport && to.name !== transport.name) {
5488
+ freezeTransport();
5489
+ }
5490
+ }
5491
+ // Remove all listeners on the transport and on self
5492
+ const cleanup = () => {
5493
+ transport.removeListener("open", onTransportOpen);
5494
+ transport.removeListener("error", onerror);
5495
+ transport.removeListener("close", onTransportClose);
5496
+ this.off("close", onclose);
5497
+ this.off("upgrading", onupgrade);
5498
+ };
5499
+ transport.once("open", onTransportOpen);
5500
+ transport.once("error", onerror);
5501
+ transport.once("close", onTransportClose);
5502
+ this.once("close", onclose);
5503
+ this.once("upgrading", onupgrade);
5504
+ if (this._upgrades.indexOf("webtransport") !== -1 &&
5505
+ name !== "webtransport") {
5506
+ // favor WebTransport
5507
+ this.setTimeoutFn(() => {
5508
+ if (!failed) {
5509
+ transport.open();
5510
+ }
5511
+ }, 200);
5512
+ }
5513
+ else {
5514
+ transport.open();
5515
+ }
5516
+ }
5517
+ onHandshake(data) {
5518
+ this._upgrades = this._filterUpgrades(data.upgrades);
5519
+ super.onHandshake(data);
5520
+ }
5446
5521
  /**
5447
5522
  * Filters upgrades, returning only those matching client transports.
5448
5523
  *
5449
5524
  * @param {Array} upgrades - server upgrades
5450
5525
  * @private
5451
5526
  */
5452
- filterUpgrades(upgrades) {
5527
+ _filterUpgrades(upgrades) {
5453
5528
  const filteredUpgrades = [];
5454
- let i = 0;
5455
- const j = upgrades.length;
5456
- for (; i < j; i++) {
5529
+ for (let i = 0; i < upgrades.length; i++) {
5457
5530
  if (~this.transports.indexOf(upgrades[i]))
5458
5531
  filteredUpgrades.push(upgrades[i]);
5459
5532
  }
5460
5533
  return filteredUpgrades;
5461
5534
  }
5535
+ }
5536
+ /**
5537
+ * This class provides a WebSocket-like interface to connect to an Engine.IO server. The connection will be established
5538
+ * with one of the available low-level transports, like HTTP long-polling, WebSocket or WebTransport.
5539
+ *
5540
+ * This class comes with an upgrade mechanism, which means that once the connection is established with the first
5541
+ * low-level transport, it will try to upgrade to a better transport.
5542
+ *
5543
+ * @example
5544
+ * import { Socket } from "engine.io-client";
5545
+ *
5546
+ * const socket = new Socket();
5547
+ *
5548
+ * socket.on("open", () => {
5549
+ * socket.send("hello");
5550
+ * });
5551
+ *
5552
+ * @see SocketWithoutUpgrade
5553
+ * @see SocketWithUpgrade
5554
+ */
5555
+ let Socket$1 = class Socket extends SocketWithUpgrade {
5556
+ constructor(uri, opts = {}) {
5557
+ const o = typeof uri === "object" ? uri : opts;
5558
+ if (!o.transports ||
5559
+ (o.transports && typeof o.transports[0] === "string")) {
5560
+ o.transports = (o.transports || ["polling", "websocket", "webtransport"])
5561
+ .map((transportName) => transports[transportName])
5562
+ .filter((t) => !!t);
5563
+ }
5564
+ super(uri, o);
5565
+ }
5462
5566
  };
5463
- Socket$1.protocol = protocol$1;
5464
5567
 
5465
5568
  Socket$1.protocol;
5466
5569
 
@@ -6216,6 +6319,7 @@ class Socket extends Emitter_1 {
6216
6319
  * @return self
6217
6320
  */
6218
6321
  emit(ev, ...args) {
6322
+ var _a, _b, _c;
6219
6323
  if (RESERVED_EVENTS.hasOwnProperty(ev)) {
6220
6324
  throw new Error('"' + ev.toString() + '" is a reserved event name');
6221
6325
  }
@@ -6237,12 +6341,11 @@ class Socket extends Emitter_1 {
6237
6341
  this._registerAckCallback(id, ack);
6238
6342
  packet.id = id;
6239
6343
  }
6240
- const isTransportWritable = this.io.engine &&
6241
- this.io.engine.transport &&
6242
- this.io.engine.transport.writable;
6243
- const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);
6344
+ const isTransportWritable = (_b = (_a = this.io.engine) === null || _a === void 0 ? void 0 : _a.transport) === null || _b === void 0 ? void 0 : _b.writable;
6345
+ const isConnected = this.connected && !((_c = this.io.engine) === null || _c === void 0 ? void 0 : _c._hasPingExpired());
6346
+ const discardPacket = this.flags.volatile && !isTransportWritable;
6244
6347
  if (discardPacket) ;
6245
- else if (this.connected) {
6348
+ else if (isConnected) {
6246
6349
  this.notifyOutgoingListeners(packet);
6247
6350
  this.packet(packet);
6248
6351
  }
@@ -6965,6 +7068,9 @@ class Manager extends Emitter_1 {
6965
7068
  if (!arguments.length)
6966
7069
  return this._reconnection;
6967
7070
  this._reconnection = !!v;
7071
+ if (!v) {
7072
+ this.skipReconnect = true;
7073
+ }
6968
7074
  return this;
6969
7075
  }
6970
7076
  reconnectionAttempts(v) {
@@ -7093,7 +7199,9 @@ class Manager extends Emitter_1 {
7093
7199
  this.emitReserved("open");
7094
7200
  // add new subs
7095
7201
  const socket = this.engine;
7096
- this.subs.push(on(socket, "ping", this.onping.bind(this)), on(socket, "data", this.ondata.bind(this)), on(socket, "error", this.onerror.bind(this)), on(socket, "close", this.onclose.bind(this)), on(this.decoder, "decoded", this.ondecoded.bind(this)));
7202
+ this.subs.push(on(socket, "ping", this.onping.bind(this)), on(socket, "data", this.ondata.bind(this)), on(socket, "error", this.onerror.bind(this)), on(socket, "close", this.onclose.bind(this)),
7203
+ // @ts-ignore
7204
+ on(this.decoder, "decoded", this.ondecoded.bind(this)));
7097
7205
  }
7098
7206
  /**
7099
7207
  * Called upon a ping.
@@ -7199,8 +7307,6 @@ class Manager extends Emitter_1 {
7199
7307
  this.skipReconnect = true;
7200
7308
  this._reconnecting = false;
7201
7309
  this.onclose("forced close");
7202
- if (this.engine)
7203
- this.engine.close();
7204
7310
  }
7205
7311
  /**
7206
7312
  * Alias for close()
@@ -7211,12 +7317,18 @@ class Manager extends Emitter_1 {
7211
7317
  return this._close();
7212
7318
  }
7213
7319
  /**
7214
- * Called upon engine close.
7320
+ * Called when:
7321
+ *
7322
+ * - the low-level engine is closed
7323
+ * - the parser encountered a badly formatted packet
7324
+ * - all sockets are disconnected
7215
7325
  *
7216
7326
  * @private
7217
7327
  */
7218
7328
  onclose(reason, description) {
7329
+ var _a;
7219
7330
  this.cleanup();
7331
+ (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close();
7220
7332
  this.backoff.reset();
7221
7333
  this._readyState = "closed";
7222
7334
  this.emitReserved("close", reason, description);
@@ -8605,7 +8717,7 @@ function useSuggestions(search, context) {
8605
8717
  shift(-1);
8606
8718
  break;
8607
8719
  case "next":
8608
- shift(+1);
8720
+ shift(1);
8609
8721
  break;
8610
8722
  case "cancel":
8611
8723
  setSuggestionIndex(-1);
@@ -14291,8 +14403,6 @@ var lightFormattersExports = lightFormatters.exports;
14291
14403
  var _index6 = _interopRequireDefault(addLeadingZerosExports);
14292
14404
  var _index7 = _interopRequireDefault(lightFormattersExports);
14293
14405
  var dayPeriodEnum = {
14294
- am: 'am',
14295
- pm: 'pm',
14296
14406
  midnight: 'midnight',
14297
14407
  noon: 'noon',
14298
14408
  morning: 'morning',
@@ -19610,9 +19720,9 @@ var unsupportedIterableToArrayExports = unsupportedIterableToArray.exports;
19610
19720
  s: F,
19611
19721
  n: function n() {
19612
19722
  return _n >= r.length ? {
19613
- done: !0
19723
+ done: true
19614
19724
  } : {
19615
- done: !1,
19725
+ done: false,
19616
19726
  value: r[_n++]
19617
19727
  };
19618
19728
  },
@@ -19625,8 +19735,8 @@ var unsupportedIterableToArrayExports = unsupportedIterableToArray.exports;
19625
19735
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
19626
19736
  }
19627
19737
  var o,
19628
- a = !0,
19629
- u = !1;
19738
+ a = true,
19739
+ u = false;
19630
19740
  return {
19631
19741
  s: function s() {
19632
19742
  t = t.call(r);
@@ -19636,7 +19746,7 @@ var unsupportedIterableToArrayExports = unsupportedIterableToArray.exports;
19636
19746
  return a = r.done, r;
19637
19747
  },
19638
19748
  e: function e(r) {
19639
- u = !0, o = r;
19749
+ u = true, o = r;
19640
19750
  },
19641
19751
  f: function f() {
19642
19752
  try {
@@ -19688,11 +19798,11 @@ var setPrototypeOfExports = setPrototypeOf.exports;
19688
19798
  t.prototype = Object.create(e && e.prototype, {
19689
19799
  constructor: {
19690
19800
  value: t,
19691
- writable: !0,
19692
- configurable: !0
19801
+ writable: true,
19802
+ configurable: true
19693
19803
  }
19694
19804
  }), Object.defineProperty(t, "prototype", {
19695
- writable: !1
19805
+ writable: false
19696
19806
  }), e && setPrototypeOf(t, e);
19697
19807
  }
19698
19808
  module.exports = _inherits, module.exports.__esModule = true, module.exports["default"] = module.exports;
@@ -19818,12 +19928,12 @@ var toPropertyKeyExports = toPropertyKey.exports;
19818
19928
  function _defineProperties(e, r) {
19819
19929
  for (var t = 0; t < r.length; t++) {
19820
19930
  var o = r[t];
19821
- o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, toPropertyKey(o.key), o);
19931
+ o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, toPropertyKey(o.key), o);
19822
19932
  }
19823
19933
  }
19824
19934
  function _createClass(e, r, t) {
19825
19935
  return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
19826
- writable: !1
19936
+ writable: false
19827
19937
  }), e;
19828
19938
  }
19829
19939
  module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
@@ -19838,9 +19948,9 @@ var defineProperty = {exports: {}};
19838
19948
  function _defineProperty(e, r, t) {
19839
19949
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
19840
19950
  value: t,
19841
- enumerable: !0,
19842
- configurable: !0,
19843
- writable: !0
19951
+ enumerable: true,
19952
+ configurable: true,
19953
+ writable: true
19844
19954
  }) : e[r] = t, e;
19845
19955
  }
19846
19956
  module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;