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