@xapp/chat-widget 1.40.5 → 1.41.2

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
@@ -45,7 +45,7 @@ function useConnectionInfo(env) {
45
45
  return useServerConfig(env, nonce);
46
46
  }
47
47
 
48
- /*! *****************************************************************************
48
+ /******************************************************************************
49
49
  Copyright (c) Microsoft Corporation.
50
50
 
51
51
  Permission to use, copy, modify, and/or distribute this software for any
@@ -3013,6 +3013,10 @@ function getPermissionResponse(botResponse, now) {
3013
3013
  };
3014
3014
  }
3015
3015
 
3016
+ /**
3017
+ * Default configuration messages
3018
+ * @returns
3019
+ */
3016
3020
  function getConfigurableMessages() {
3017
3021
  return {
3018
3022
  items: [
@@ -3036,8 +3040,10 @@ function getConfigurableMessages() {
3036
3040
  function getConfigurableMessagesConfig(messages) {
3037
3041
  var items = messages.items;
3038
3042
  var config = [{ retry: 0, delay: 5, text: "" }];
3039
- for (var i = 0; i < items.length; i++) {
3040
- config.push({ retry: i + 1, delay: items[i].delay, text: items[i].text });
3043
+ if (Array.isArray(items) && items.length > 0) {
3044
+ for (var i = 0; i < items.length; i++) {
3045
+ config.push({ retry: i + 1, delay: items[i].delay, text: items[i].text });
3046
+ }
3041
3047
  }
3042
3048
  return config;
3043
3049
  }
@@ -3423,7 +3429,7 @@ var StentorDirectChat = /** @class */ (function () {
3423
3429
  responseMessage.msg = {
3424
3430
  //eslint-disable-next-line
3425
3431
  //@ts-ignore
3426
- text: (botResponse === null || botResponse === void 0 ? void 0 : botResponse.hasOwnProperty("errorText")) ? botResponse.errorText : "Oops. The bot doesn't respond... Try later!"
3432
+ text: (botResponse === null || botResponse === void 0 ? void 0 : botResponse.hasOwnProperty("errorText")) ? botResponse.errorText : "The assistant is not responding right now. Please close the widget and open it again."
3427
3433
  };
3428
3434
  }
3429
3435
  this.stopTyping();
@@ -3508,246 +3514,203 @@ var StentorLocalChat = /** @class */ (function () {
3508
3514
  return StentorLocalChat;
3509
3515
  }());
3510
3516
 
3511
- /**
3512
- * Parses an URI
3513
- *
3514
- * @author Steven Levithan <stevenlevithan.com> (MIT license)
3515
- * @api private
3516
- */
3517
-
3518
- var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
3519
-
3520
- var parts = [
3521
- 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
3522
- ];
3523
-
3524
- var parseuri = function parseuri(str) {
3525
- var src = str,
3526
- b = str.indexOf('['),
3527
- e = str.indexOf(']');
3517
+ const PACKET_TYPES = Object.create(null); // no Map = no polyfill
3518
+ PACKET_TYPES["open"] = "0";
3519
+ PACKET_TYPES["close"] = "1";
3520
+ PACKET_TYPES["ping"] = "2";
3521
+ PACKET_TYPES["pong"] = "3";
3522
+ PACKET_TYPES["message"] = "4";
3523
+ PACKET_TYPES["upgrade"] = "5";
3524
+ PACKET_TYPES["noop"] = "6";
3525
+ const PACKET_TYPES_REVERSE = Object.create(null);
3526
+ Object.keys(PACKET_TYPES).forEach(key => {
3527
+ PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
3528
+ });
3529
+ const ERROR_PACKET = { type: "error", data: "parser error" };
3528
3530
 
3529
- if (b != -1 && e != -1) {
3530
- str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
3531
+ const withNativeBlob$1 = typeof Blob === "function" ||
3532
+ (typeof Blob !== "undefined" &&
3533
+ Object.prototype.toString.call(Blob) === "[object BlobConstructor]");
3534
+ const withNativeArrayBuffer$2 = typeof ArrayBuffer === "function";
3535
+ // ArrayBuffer.isView method is not defined in IE10
3536
+ const isView$1 = obj => {
3537
+ return typeof ArrayBuffer.isView === "function"
3538
+ ? ArrayBuffer.isView(obj)
3539
+ : obj && obj.buffer instanceof ArrayBuffer;
3540
+ };
3541
+ const encodePacket = ({ type, data }, supportsBinary, callback) => {
3542
+ if (withNativeBlob$1 && data instanceof Blob) {
3543
+ if (supportsBinary) {
3544
+ return callback(data);
3545
+ }
3546
+ else {
3547
+ return encodeBlobAsBase64(data, callback);
3548
+ }
3531
3549
  }
3532
-
3533
- var m = re.exec(str || ''),
3534
- uri = {},
3535
- i = 14;
3536
-
3537
- while (i--) {
3538
- uri[parts[i]] = m[i] || '';
3550
+ else if (withNativeArrayBuffer$2 &&
3551
+ (data instanceof ArrayBuffer || isView$1(data))) {
3552
+ if (supportsBinary) {
3553
+ return callback(data);
3554
+ }
3555
+ else {
3556
+ return encodeBlobAsBase64(new Blob([data]), callback);
3557
+ }
3539
3558
  }
3559
+ // plain string
3560
+ return callback(PACKET_TYPES[type] + (data || ""));
3561
+ };
3562
+ const encodeBlobAsBase64 = (data, callback) => {
3563
+ const fileReader = new FileReader();
3564
+ fileReader.onload = function () {
3565
+ const content = fileReader.result.split(",")[1];
3566
+ callback("b" + content);
3567
+ };
3568
+ return fileReader.readAsDataURL(data);
3569
+ };
3540
3570
 
3541
- if (b != -1 && e != -1) {
3542
- uri.source = src;
3543
- uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
3544
- uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
3545
- uri.ipv6uri = true;
3571
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
3572
+ // Use a lookup table to find the index.
3573
+ const lookup$1 = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
3574
+ for (let i = 0; i < chars.length; i++) {
3575
+ lookup$1[chars.charCodeAt(i)] = i;
3576
+ }
3577
+ const decode$1 = (base64) => {
3578
+ let bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
3579
+ if (base64[base64.length - 1] === '=') {
3580
+ bufferLength--;
3581
+ if (base64[base64.length - 2] === '=') {
3582
+ bufferLength--;
3583
+ }
3546
3584
  }
3547
-
3548
- uri.pathNames = pathNames(uri, uri['path']);
3549
- uri.queryKey = queryKey(uri, uri['query']);
3550
-
3551
- return uri;
3585
+ const arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
3586
+ for (i = 0; i < len; i += 4) {
3587
+ encoded1 = lookup$1[base64.charCodeAt(i)];
3588
+ encoded2 = lookup$1[base64.charCodeAt(i + 1)];
3589
+ encoded3 = lookup$1[base64.charCodeAt(i + 2)];
3590
+ encoded4 = lookup$1[base64.charCodeAt(i + 3)];
3591
+ bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
3592
+ bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
3593
+ bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
3594
+ }
3595
+ return arraybuffer;
3552
3596
  };
3553
3597
 
3554
- function pathNames(obj, path) {
3555
- var regx = /\/{2,9}/g,
3556
- names = path.replace(regx, "/").split("/");
3557
-
3558
- if (path.substr(0, 1) == '/' || path.length === 0) {
3559
- names.splice(0, 1);
3598
+ const withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
3599
+ const decodePacket = (encodedPacket, binaryType) => {
3600
+ if (typeof encodedPacket !== "string") {
3601
+ return {
3602
+ type: "message",
3603
+ data: mapBinary(encodedPacket, binaryType)
3604
+ };
3560
3605
  }
3561
- if (path.substr(path.length - 1, 1) == '/') {
3562
- names.splice(names.length - 1, 1);
3606
+ const type = encodedPacket.charAt(0);
3607
+ if (type === "b") {
3608
+ return {
3609
+ type: "message",
3610
+ data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
3611
+ };
3563
3612
  }
3564
-
3565
- return names;
3566
- }
3567
-
3568
- function queryKey(uri, query) {
3569
- var data = {};
3570
-
3571
- query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
3572
- if ($1) {
3573
- data[$1] = $2;
3613
+ const packetType = PACKET_TYPES_REVERSE[type];
3614
+ if (!packetType) {
3615
+ return ERROR_PACKET;
3616
+ }
3617
+ return encodedPacket.length > 1
3618
+ ? {
3619
+ type: PACKET_TYPES_REVERSE[type],
3620
+ data: encodedPacket.substring(1)
3574
3621
  }
3622
+ : {
3623
+ type: PACKET_TYPES_REVERSE[type]
3624
+ };
3625
+ };
3626
+ const decodeBase64Packet = (data, binaryType) => {
3627
+ if (withNativeArrayBuffer$1) {
3628
+ const decoded = decode$1(data);
3629
+ return mapBinary(decoded, binaryType);
3630
+ }
3631
+ else {
3632
+ return { base64: true, data }; // fallback for old browsers
3633
+ }
3634
+ };
3635
+ const mapBinary = (data, binaryType) => {
3636
+ switch (binaryType) {
3637
+ case "blob":
3638
+ return data instanceof ArrayBuffer ? new Blob([data]) : data;
3639
+ case "arraybuffer":
3640
+ default:
3641
+ return data; // assuming the data is already an ArrayBuffer
3642
+ }
3643
+ };
3644
+
3645
+ const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
3646
+ const encodePayload = (packets, callback) => {
3647
+ // some packets may be added to the array while encoding, so the initial length must be saved
3648
+ const length = packets.length;
3649
+ const encodedPackets = new Array(length);
3650
+ let count = 0;
3651
+ packets.forEach((packet, i) => {
3652
+ // force base64 encoding for binary packets
3653
+ encodePacket(packet, false, encodedPacket => {
3654
+ encodedPackets[i] = encodedPacket;
3655
+ if (++count === length) {
3656
+ callback(encodedPackets.join(SEPARATOR));
3657
+ }
3658
+ });
3575
3659
  });
3660
+ };
3661
+ const decodePayload = (encodedPayload, binaryType) => {
3662
+ const encodedPackets = encodedPayload.split(SEPARATOR);
3663
+ const packets = [];
3664
+ for (let i = 0; i < encodedPackets.length; i++) {
3665
+ const decodedPacket = decodePacket(encodedPackets[i], binaryType);
3666
+ packets.push(decodedPacket);
3667
+ if (decodedPacket.type === "error") {
3668
+ break;
3669
+ }
3670
+ }
3671
+ return packets;
3672
+ };
3673
+ const protocol$1 = 4;
3576
3674
 
3577
- return data;
3578
- }
3675
+ /**
3676
+ * Expose `Emitter`.
3677
+ */
3678
+
3679
+ var Emitter_1 = Emitter;
3579
3680
 
3580
3681
  /**
3581
- * URL parser.
3682
+ * Initialize a new `Emitter`.
3582
3683
  *
3583
- * @param uri - url
3584
- * @param path - the request path of the connection
3585
- * @param loc - An object meant to mimic window.location.
3586
- * Defaults to window.location.
3587
- * @public
3684
+ * @api public
3588
3685
  */
3589
- function url(uri, path = "", loc) {
3590
- let obj = uri;
3591
- // default to window.location
3592
- loc = loc || (typeof location !== "undefined" && location);
3593
- if (null == uri)
3594
- uri = loc.protocol + "//" + loc.host;
3595
- // relative path support
3596
- if (typeof uri === "string") {
3597
- if ("/" === uri.charAt(0)) {
3598
- if ("/" === uri.charAt(1)) {
3599
- uri = loc.protocol + uri;
3600
- }
3601
- else {
3602
- uri = loc.host + uri;
3603
- }
3604
- }
3605
- if (!/^(https?|wss?):\/\//.test(uri)) {
3606
- if ("undefined" !== typeof loc) {
3607
- uri = loc.protocol + "//" + uri;
3608
- }
3609
- else {
3610
- uri = "https://" + uri;
3611
- }
3612
- }
3613
- // parse
3614
- obj = parseuri(uri);
3615
- }
3616
- // make sure we treat `localhost:80` and `localhost` equally
3617
- if (!obj.port) {
3618
- if (/^(http|ws)$/.test(obj.protocol)) {
3619
- obj.port = "80";
3620
- }
3621
- else if (/^(http|ws)s$/.test(obj.protocol)) {
3622
- obj.port = "443";
3623
- }
3624
- }
3625
- obj.path = obj.path || "/";
3626
- const ipv6 = obj.host.indexOf(":") !== -1;
3627
- const host = ipv6 ? "[" + obj.host + "]" : obj.host;
3628
- // define unique id
3629
- obj.id = obj.protocol + "://" + host + ":" + obj.port + path;
3630
- // define href
3631
- obj.href =
3632
- obj.protocol +
3633
- "://" +
3634
- host +
3635
- (loc && loc.port === obj.port ? "" : ":" + obj.port);
3636
- return obj;
3637
- }
3638
3686
 
3639
- var hasCors = {exports: {}};
3687
+ function Emitter(obj) {
3688
+ if (obj) return mixin(obj);
3689
+ }
3640
3690
 
3641
3691
  /**
3642
- * Module exports.
3643
- *
3644
- * Logic borrowed from Modernizr:
3692
+ * Mixin the emitter properties.
3645
3693
  *
3646
- * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
3694
+ * @param {Object} obj
3695
+ * @return {Object}
3696
+ * @api private
3647
3697
  */
3648
3698
 
3649
- try {
3650
- hasCors.exports = typeof XMLHttpRequest !== 'undefined' &&
3651
- 'withCredentials' in new XMLHttpRequest();
3652
- } catch (err) {
3653
- // if XMLHttp support is disabled in IE then it will throw
3654
- // when trying to create
3655
- hasCors.exports = false;
3699
+ function mixin(obj) {
3700
+ for (var key in Emitter.prototype) {
3701
+ obj[key] = Emitter.prototype[key];
3702
+ }
3703
+ return obj;
3656
3704
  }
3657
3705
 
3658
- var hasCORS = hasCors.exports;
3659
-
3660
- var globalThis$1 = (() => {
3661
- if (typeof self !== "undefined") {
3662
- return self;
3663
- }
3664
- else if (typeof window !== "undefined") {
3665
- return window;
3666
- }
3667
- else {
3668
- return Function("return this")();
3669
- }
3670
- })();
3671
-
3672
- // browser shim for xmlhttprequest module
3673
- function XMLHttpRequest$1 (opts) {
3674
- const xdomain = opts.xdomain;
3675
- // XMLHttpRequest can be disabled on IE
3676
- try {
3677
- if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
3678
- return new XMLHttpRequest();
3679
- }
3680
- }
3681
- catch (e) { }
3682
- if (!xdomain) {
3683
- try {
3684
- return new globalThis$1[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
3685
- }
3686
- catch (e) { }
3687
- }
3688
- }
3689
-
3690
- function pick(obj, ...attr) {
3691
- return attr.reduce((acc, k) => {
3692
- if (obj.hasOwnProperty(k)) {
3693
- acc[k] = obj[k];
3694
- }
3695
- return acc;
3696
- }, {});
3697
- }
3698
- // Keep a reference to the real timeout functions so they can be used when overridden
3699
- const NATIVE_SET_TIMEOUT = setTimeout;
3700
- const NATIVE_CLEAR_TIMEOUT = clearTimeout;
3701
- function installTimerFunctions(obj, opts) {
3702
- if (opts.useNativeTimers) {
3703
- obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThis$1);
3704
- obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThis$1);
3705
- }
3706
- else {
3707
- obj.setTimeoutFn = setTimeout.bind(globalThis$1);
3708
- obj.clearTimeoutFn = clearTimeout.bind(globalThis$1);
3709
- }
3710
- }
3711
-
3712
- /**
3713
- * Expose `Emitter`.
3714
- */
3715
-
3716
- var Emitter_1 = Emitter;
3717
-
3718
- /**
3719
- * Initialize a new `Emitter`.
3720
- *
3721
- * @api public
3722
- */
3723
-
3724
- function Emitter(obj) {
3725
- if (obj) return mixin(obj);
3726
- }
3727
-
3728
- /**
3729
- * Mixin the emitter properties.
3730
- *
3731
- * @param {Object} obj
3732
- * @return {Object}
3733
- * @api private
3734
- */
3735
-
3736
- function mixin(obj) {
3737
- for (var key in Emitter.prototype) {
3738
- obj[key] = Emitter.prototype[key];
3739
- }
3740
- return obj;
3741
- }
3742
-
3743
- /**
3744
- * Listen on the given `event` with `fn`.
3745
- *
3746
- * @param {String} event
3747
- * @param {Function} fn
3748
- * @return {Emitter}
3749
- * @api public
3750
- */
3706
+ /**
3707
+ * Listen on the given `event` with `fn`.
3708
+ *
3709
+ * @param {String} event
3710
+ * @param {Function} fn
3711
+ * @return {Emitter}
3712
+ * @api public
3713
+ */
3751
3714
 
3752
3715
  Emitter.prototype.on =
3753
3716
  Emitter.prototype.addEventListener = function(event, fn){
@@ -3885,201 +3848,78 @@ Emitter.prototype.hasListeners = function(event){
3885
3848
  return !! this.listeners(event).length;
3886
3849
  };
3887
3850
 
3888
- const PACKET_TYPES = Object.create(null); // no Map = no polyfill
3889
- PACKET_TYPES["open"] = "0";
3890
- PACKET_TYPES["close"] = "1";
3891
- PACKET_TYPES["ping"] = "2";
3892
- PACKET_TYPES["pong"] = "3";
3893
- PACKET_TYPES["message"] = "4";
3894
- PACKET_TYPES["upgrade"] = "5";
3895
- PACKET_TYPES["noop"] = "6";
3896
- const PACKET_TYPES_REVERSE = Object.create(null);
3897
- Object.keys(PACKET_TYPES).forEach(key => {
3898
- PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
3899
- });
3900
- const ERROR_PACKET = { type: "error", data: "parser error" };
3901
-
3902
- const withNativeBlob$1 = typeof Blob === "function" ||
3903
- (typeof Blob !== "undefined" &&
3904
- Object.prototype.toString.call(Blob) === "[object BlobConstructor]");
3905
- const withNativeArrayBuffer$2 = typeof ArrayBuffer === "function";
3906
- // ArrayBuffer.isView method is not defined in IE10
3907
- const isView$1 = obj => {
3908
- return typeof ArrayBuffer.isView === "function"
3909
- ? ArrayBuffer.isView(obj)
3910
- : obj && obj.buffer instanceof ArrayBuffer;
3911
- };
3912
- const encodePacket = ({ type, data }, supportsBinary, callback) => {
3913
- if (withNativeBlob$1 && data instanceof Blob) {
3914
- if (supportsBinary) {
3915
- return callback(data);
3916
- }
3917
- else {
3918
- return encodeBlobAsBase64(data, callback);
3919
- }
3851
+ const globalThisShim = (() => {
3852
+ if (typeof self !== "undefined") {
3853
+ return self;
3920
3854
  }
3921
- else if (withNativeArrayBuffer$2 &&
3922
- (data instanceof ArrayBuffer || isView$1(data))) {
3923
- if (supportsBinary) {
3924
- return callback(data);
3925
- }
3926
- else {
3927
- return encodeBlobAsBase64(new Blob([data]), callback);
3928
- }
3855
+ else if (typeof window !== "undefined") {
3856
+ return window;
3929
3857
  }
3930
- // plain string
3931
- return callback(PACKET_TYPES[type] + (data || ""));
3932
- };
3933
- const encodeBlobAsBase64 = (data, callback) => {
3934
- const fileReader = new FileReader();
3935
- fileReader.onload = function () {
3936
- const content = fileReader.result.split(",")[1];
3937
- callback("b" + content);
3938
- };
3939
- return fileReader.readAsDataURL(data);
3940
- };
3941
-
3942
- var base64Arraybuffer_umd = {exports: {}};
3858
+ else {
3859
+ return Function("return this")();
3860
+ }
3861
+ })();
3943
3862
 
3944
- /*
3945
- * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
3946
- * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
3947
- * Released under MIT License
3948
- */
3949
-
3950
- (function (module, exports) {
3951
- (function (global, factory) {
3952
- factory(exports) ;
3953
- }(commonjsGlobal, (function (exports) {
3954
- var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
3955
- // Use a lookup table to find the index.
3956
- var lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
3957
- for (var i = 0; i < chars.length; i++) {
3958
- lookup[chars.charCodeAt(i)] = i;
3959
- }
3960
- var encode = function (arraybuffer) {
3961
- var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';
3962
- for (i = 0; i < len; i += 3) {
3963
- base64 += chars[bytes[i] >> 2];
3964
- base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
3965
- base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
3966
- base64 += chars[bytes[i + 2] & 63];
3967
- }
3968
- if (len % 3 === 2) {
3969
- base64 = base64.substring(0, base64.length - 1) + '=';
3863
+ function pick(obj, ...attr) {
3864
+ return attr.reduce((acc, k) => {
3865
+ if (obj.hasOwnProperty(k)) {
3866
+ acc[k] = obj[k];
3970
3867
  }
3971
- else if (len % 3 === 1) {
3972
- base64 = base64.substring(0, base64.length - 2) + '==';
3868
+ return acc;
3869
+ }, {});
3870
+ }
3871
+ // Keep a reference to the real timeout functions so they can be used when overridden
3872
+ const NATIVE_SET_TIMEOUT = setTimeout;
3873
+ const NATIVE_CLEAR_TIMEOUT = clearTimeout;
3874
+ function installTimerFunctions(obj, opts) {
3875
+ if (opts.useNativeTimers) {
3876
+ obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThisShim);
3877
+ obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThisShim);
3878
+ }
3879
+ else {
3880
+ obj.setTimeoutFn = setTimeout.bind(globalThisShim);
3881
+ obj.clearTimeoutFn = clearTimeout.bind(globalThisShim);
3882
+ }
3883
+ }
3884
+ // base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)
3885
+ const BASE64_OVERHEAD = 1.33;
3886
+ // we could also have used `new Blob([obj]).size`, but it isn't supported in IE9
3887
+ function byteLength(obj) {
3888
+ if (typeof obj === "string") {
3889
+ return utf8Length(obj);
3890
+ }
3891
+ // arraybuffer or blob
3892
+ return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD);
3893
+ }
3894
+ function utf8Length(str) {
3895
+ let c = 0, length = 0;
3896
+ for (let i = 0, l = str.length; i < l; i++) {
3897
+ c = str.charCodeAt(i);
3898
+ if (c < 0x80) {
3899
+ length += 1;
3973
3900
  }
3974
- return base64;
3975
- };
3976
- var decode = function (base64) {
3977
- var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
3978
- if (base64[base64.length - 1] === '=') {
3979
- bufferLength--;
3980
- if (base64[base64.length - 2] === '=') {
3981
- bufferLength--;
3982
- }
3901
+ else if (c < 0x800) {
3902
+ length += 2;
3983
3903
  }
3984
- var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
3985
- for (i = 0; i < len; i += 4) {
3986
- encoded1 = lookup[base64.charCodeAt(i)];
3987
- encoded2 = lookup[base64.charCodeAt(i + 1)];
3988
- encoded3 = lookup[base64.charCodeAt(i + 2)];
3989
- encoded4 = lookup[base64.charCodeAt(i + 3)];
3990
- bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
3991
- bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
3992
- bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
3904
+ else if (c < 0xd800 || c >= 0xe000) {
3905
+ length += 3;
3993
3906
  }
3994
- return arraybuffer;
3995
- };
3996
-
3997
- exports.decode = decode;
3998
- exports.encode = encode;
3999
-
4000
- Object.defineProperty(exports, '__esModule', { value: true });
4001
-
4002
- })));
4003
-
4004
- }(base64Arraybuffer_umd, base64Arraybuffer_umd.exports));
4005
-
4006
- const withNativeArrayBuffer$1 = typeof ArrayBuffer === "function";
4007
- const decodePacket = (encodedPacket, binaryType) => {
4008
- if (typeof encodedPacket !== "string") {
4009
- return {
4010
- type: "message",
4011
- data: mapBinary(encodedPacket, binaryType)
4012
- };
4013
- }
4014
- const type = encodedPacket.charAt(0);
4015
- if (type === "b") {
4016
- return {
4017
- type: "message",
4018
- data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
4019
- };
4020
- }
4021
- const packetType = PACKET_TYPES_REVERSE[type];
4022
- if (!packetType) {
4023
- return ERROR_PACKET;
4024
- }
4025
- return encodedPacket.length > 1
4026
- ? {
4027
- type: PACKET_TYPES_REVERSE[type],
4028
- data: encodedPacket.substring(1)
3907
+ else {
3908
+ i++;
3909
+ length += 4;
4029
3910
  }
4030
- : {
4031
- type: PACKET_TYPES_REVERSE[type]
4032
- };
4033
- };
4034
- const decodeBase64Packet = (data, binaryType) => {
4035
- if (withNativeArrayBuffer$1) {
4036
- const decoded = base64Arraybuffer_umd.exports.decode(data);
4037
- return mapBinary(decoded, binaryType);
4038
- }
4039
- else {
4040
- return { base64: true, data }; // fallback for old browsers
4041
- }
4042
- };
4043
- const mapBinary = (data, binaryType) => {
4044
- switch (binaryType) {
4045
- case "blob":
4046
- return data instanceof ArrayBuffer ? new Blob([data]) : data;
4047
- case "arraybuffer":
4048
- default:
4049
- return data; // assuming the data is already an ArrayBuffer
4050
3911
  }
4051
- };
3912
+ return length;
3913
+ }
4052
3914
 
4053
- const SEPARATOR = String.fromCharCode(30); // see https://en.wikipedia.org/wiki/Delimiter#ASCII_delimited_text
4054
- const encodePayload = (packets, callback) => {
4055
- // some packets may be added to the array while encoding, so the initial length must be saved
4056
- const length = packets.length;
4057
- const encodedPackets = new Array(length);
4058
- let count = 0;
4059
- packets.forEach((packet, i) => {
4060
- // force base64 encoding for binary packets
4061
- encodePacket(packet, false, encodedPacket => {
4062
- encodedPackets[i] = encodedPacket;
4063
- if (++count === length) {
4064
- callback(encodedPackets.join(SEPARATOR));
4065
- }
4066
- });
4067
- });
4068
- };
4069
- const decodePayload = (encodedPayload, binaryType) => {
4070
- const encodedPackets = encodedPayload.split(SEPARATOR);
4071
- const packets = [];
4072
- for (let i = 0; i < encodedPackets.length; i++) {
4073
- const decodedPacket = decodePacket(encodedPackets[i], binaryType);
4074
- packets.push(decodedPacket);
4075
- if (decodedPacket.type === "error") {
4076
- break;
4077
- }
3915
+ class TransportError extends Error {
3916
+ constructor(reason, description, context) {
3917
+ super(reason);
3918
+ this.description = description;
3919
+ this.context = context;
3920
+ this.type = "TransportError";
4078
3921
  }
4079
- return packets;
4080
- };
4081
- const protocol$1 = 4;
4082
-
3922
+ }
4083
3923
  class Transport extends Emitter_1 {
4084
3924
  /**
4085
3925
  * Transport abstract constructor.
@@ -4099,17 +3939,14 @@ class Transport extends Emitter_1 {
4099
3939
  /**
4100
3940
  * Emits an error.
4101
3941
  *
4102
- * @param {String} str
3942
+ * @param {String} reason
3943
+ * @param description
3944
+ * @param context - the error context
4103
3945
  * @return {Transport} for chaining
4104
3946
  * @api protected
4105
3947
  */
4106
- onError(msg, desc) {
4107
- const err = new Error(msg);
4108
- // @ts-ignore
4109
- err.type = "TransportError";
4110
- // @ts-ignore
4111
- err.description = desc;
4112
- super.emit("error", err);
3948
+ onError(reason, description, context) {
3949
+ super.emitReserved("error", new TransportError(reason, description, context));
4113
3950
  return this;
4114
3951
  }
4115
3952
  /**
@@ -4155,7 +3992,7 @@ class Transport extends Emitter_1 {
4155
3992
  onOpen() {
4156
3993
  this.readyState = "open";
4157
3994
  this.writable = true;
4158
- super.emit("open");
3995
+ super.emitReserved("open");
4159
3996
  }
4160
3997
  /**
4161
3998
  * Called with data.
@@ -4173,26 +4010,22 @@ class Transport extends Emitter_1 {
4173
4010
  * @api protected
4174
4011
  */
4175
4012
  onPacket(packet) {
4176
- super.emit("packet", packet);
4013
+ super.emitReserved("packet", packet);
4177
4014
  }
4178
4015
  /**
4179
4016
  * Called upon close.
4180
4017
  *
4181
4018
  * @api protected
4182
4019
  */
4183
- onClose() {
4020
+ onClose(details) {
4184
4021
  this.readyState = "closed";
4185
- super.emit("close");
4022
+ super.emitReserved("close", details);
4186
4023
  }
4187
4024
  }
4188
4025
 
4189
- var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('')
4190
- , length = 64
4191
- , map = {}
4192
- , seed = 0
4193
- , i = 0
4194
- , prev;
4195
-
4026
+ // imported from https://github.com/unshiftio/yeast
4027
+ const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {};
4028
+ let seed = 0, i = 0, prev;
4196
4029
  /**
4197
4030
  * Return a string representing the specified number.
4198
4031
  *
@@ -4200,34 +4033,14 @@ var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_
4200
4033
  * @returns {String} The string representation of the number.
4201
4034
  * @api public
4202
4035
  */
4203
- function encode(num) {
4204
- var encoded = '';
4205
-
4206
- do {
4207
- encoded = alphabet[num % length] + encoded;
4208
- num = Math.floor(num / length);
4209
- } while (num > 0);
4210
-
4211
- return encoded;
4212
- }
4213
-
4214
- /**
4215
- * Return the integer value specified by the given string.
4216
- *
4217
- * @param {String} str The string to convert.
4218
- * @returns {Number} The integer value represented by the string.
4219
- * @api public
4220
- */
4221
- function decode(str) {
4222
- var decoded = 0;
4223
-
4224
- for (i = 0; i < str.length; i++) {
4225
- decoded = decoded * length + map[str.charAt(i)];
4226
- }
4227
-
4228
- return decoded;
4036
+ function encode$1(num) {
4037
+ let encoded = '';
4038
+ do {
4039
+ encoded = alphabet[num % length] + encoded;
4040
+ num = Math.floor(num / length);
4041
+ } while (num > 0);
4042
+ return encoded;
4229
4043
  }
4230
-
4231
4044
  /**
4232
4045
  * Yeast: A tiny growing id generator.
4233
4046
  *
@@ -4235,26 +4048,18 @@ function decode(str) {
4235
4048
  * @api public
4236
4049
  */
4237
4050
  function yeast() {
4238
- var now = encode(+new Date());
4239
-
4240
- if (now !== prev) return seed = 0, prev = now;
4241
- return now +'.'+ encode(seed++);
4051
+ const now = encode$1(+new Date());
4052
+ if (now !== prev)
4053
+ return seed = 0, prev = now;
4054
+ return now + '.' + encode$1(seed++);
4242
4055
  }
4243
-
4244
4056
  //
4245
4057
  // Map each character to its index.
4246
4058
  //
4247
- for (; i < length; i++) map[alphabet[i]] = i;
4248
-
4249
- //
4250
- // Expose the `yeast`, `encode` and `decode` functions.
4251
- //
4252
- yeast.encode = encode;
4253
- yeast.decode = decode;
4254
- var yeast_1 = yeast;
4255
-
4256
- var parseqs = {};
4059
+ for (; i < length; i++)
4060
+ map[alphabet[i]] = i;
4257
4061
 
4062
+ // imported from https://github.com/galkn/querystring
4258
4063
  /**
4259
4064
  * Compiles a querystring
4260
4065
  * Returns string representation of the object
@@ -4262,41 +4067,98 @@ var parseqs = {};
4262
4067
  * @param {Object}
4263
4068
  * @api private
4264
4069
  */
4265
-
4266
- parseqs.encode = function (obj) {
4267
- var str = '';
4268
-
4269
- for (var i in obj) {
4270
- if (obj.hasOwnProperty(i)) {
4271
- if (str.length) str += '&';
4272
- str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
4070
+ function encode(obj) {
4071
+ let str = '';
4072
+ for (let i in obj) {
4073
+ if (obj.hasOwnProperty(i)) {
4074
+ if (str.length)
4075
+ str += '&';
4076
+ str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
4077
+ }
4273
4078
  }
4274
- }
4275
-
4276
- return str;
4277
- };
4278
-
4079
+ return str;
4080
+ }
4279
4081
  /**
4280
4082
  * Parses a simple querystring into an object
4281
4083
  *
4282
4084
  * @param {String} qs
4283
4085
  * @api private
4284
4086
  */
4087
+ function decode(qs) {
4088
+ let qry = {};
4089
+ let pairs = qs.split('&');
4090
+ for (let i = 0, l = pairs.length; i < l; i++) {
4091
+ let pair = pairs[i].split('=');
4092
+ qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
4093
+ }
4094
+ return qry;
4095
+ }
4285
4096
 
4286
- parseqs.decode = function(qs){
4287
- var qry = {};
4288
- var pairs = qs.split('&');
4289
- for (var i = 0, l = pairs.length; i < l; i++) {
4290
- var pair = pairs[i].split('=');
4291
- qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
4292
- }
4293
- return qry;
4294
- };
4097
+ // imported from https://github.com/component/has-cors
4098
+ let value = false;
4099
+ try {
4100
+ value = typeof XMLHttpRequest !== 'undefined' &&
4101
+ 'withCredentials' in new XMLHttpRequest();
4102
+ }
4103
+ catch (err) {
4104
+ // if XMLHttp support is disabled in IE then it will throw
4105
+ // when trying to create
4106
+ }
4107
+ const hasCORS = value;
4108
+
4109
+ // browser shim for xmlhttprequest module
4110
+ function XHR(opts) {
4111
+ const xdomain = opts.xdomain;
4112
+ // XMLHttpRequest can be disabled on IE
4113
+ try {
4114
+ if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
4115
+ return new XMLHttpRequest();
4116
+ }
4117
+ }
4118
+ catch (e) { }
4119
+ if (!xdomain) {
4120
+ try {
4121
+ return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP");
4122
+ }
4123
+ catch (e) { }
4124
+ }
4125
+ }
4295
4126
 
4127
+ function empty$2() { }
4128
+ const hasXHR2 = (function () {
4129
+ const xhr = new XHR({
4130
+ xdomain: false
4131
+ });
4132
+ return null != xhr.responseType;
4133
+ })();
4296
4134
  class Polling extends Transport {
4297
- constructor() {
4298
- super(...arguments);
4135
+ /**
4136
+ * XHR Polling constructor.
4137
+ *
4138
+ * @param {Object} opts
4139
+ * @api public
4140
+ */
4141
+ constructor(opts) {
4142
+ super(opts);
4299
4143
  this.polling = false;
4144
+ if (typeof location !== "undefined") {
4145
+ const isSSL = "https:" === location.protocol;
4146
+ let port = location.port;
4147
+ // some user agents have empty `location.port`
4148
+ if (!port) {
4149
+ port = isSSL ? "443" : "80";
4150
+ }
4151
+ this.xd =
4152
+ (typeof location !== "undefined" &&
4153
+ opts.hostname !== location.hostname) ||
4154
+ port !== opts.port;
4155
+ this.xs = opts.secure !== isSSL;
4156
+ }
4157
+ /**
4158
+ * XHR supports binary
4159
+ */
4160
+ const forceBase64 = opts && opts.forceBase64;
4161
+ this.supportsBinary = hasXHR2 && !forceBase64;
4300
4162
  }
4301
4163
  /**
4302
4164
  * Transport name.
@@ -4352,7 +4214,7 @@ class Polling extends Transport {
4352
4214
  poll() {
4353
4215
  this.polling = true;
4354
4216
  this.doPoll();
4355
- this.emit("poll");
4217
+ this.emitReserved("poll");
4356
4218
  }
4357
4219
  /**
4358
4220
  * Overloads onData to detect payloads.
@@ -4367,7 +4229,7 @@ class Polling extends Transport {
4367
4229
  }
4368
4230
  // if its a close packet, we close the ongoing requests
4369
4231
  if ("close" === packet.type) {
4370
- this.onClose();
4232
+ this.onClose({ description: "transport closed by the server" });
4371
4233
  return false;
4372
4234
  }
4373
4235
  // otherwise bypass onData and handle the message
@@ -4379,7 +4241,7 @@ class Polling extends Transport {
4379
4241
  if ("closed" !== this.readyState) {
4380
4242
  // if we got data we're not polling
4381
4243
  this.polling = false;
4382
- this.emit("pollComplete");
4244
+ this.emitReserved("pollComplete");
4383
4245
  if ("open" === this.readyState) {
4384
4246
  this.poll();
4385
4247
  }
@@ -4415,7 +4277,7 @@ class Polling extends Transport {
4415
4277
  encodePayload(packets, data => {
4416
4278
  this.doWrite(data, () => {
4417
4279
  this.writable = true;
4418
- this.emit("drain");
4280
+ this.emitReserved("drain");
4419
4281
  });
4420
4282
  });
4421
4283
  }
@@ -4430,7 +4292,7 @@ class Polling extends Transport {
4430
4292
  let port = "";
4431
4293
  // cache busting is forced
4432
4294
  if (false !== this.opts.timestampRequests) {
4433
- query[this.opts.timestampParam] = yeast_1();
4295
+ query[this.opts.timestampParam] = yeast();
4434
4296
  }
4435
4297
  if (!this.supportsBinary && !query.sid) {
4436
4298
  query.b64 = 1;
@@ -4441,7 +4303,7 @@ class Polling extends Transport {
4441
4303
  ("http" === schema && Number(this.opts.port) !== 80))) {
4442
4304
  port = ":" + this.opts.port;
4443
4305
  }
4444
- const encodedQuery = parseqs.encode(query);
4306
+ const encodedQuery = encode(query);
4445
4307
  const ipv6 = this.opts.hostname.indexOf(":") !== -1;
4446
4308
  return (schema +
4447
4309
  "://" +
@@ -4450,47 +4312,6 @@ class Polling extends Transport {
4450
4312
  this.opts.path +
4451
4313
  (encodedQuery.length ? "?" + encodedQuery : ""));
4452
4314
  }
4453
- }
4454
-
4455
- /* global attachEvent */
4456
- /**
4457
- * Empty function
4458
- */
4459
- function empty$2() { }
4460
- const hasXHR2 = (function () {
4461
- const xhr = new XMLHttpRequest$1({
4462
- xdomain: false
4463
- });
4464
- return null != xhr.responseType;
4465
- })();
4466
- class XHR extends Polling {
4467
- /**
4468
- * XHR Polling constructor.
4469
- *
4470
- * @param {Object} opts
4471
- * @api public
4472
- */
4473
- constructor(opts) {
4474
- super(opts);
4475
- if (typeof location !== "undefined") {
4476
- const isSSL = "https:" === location.protocol;
4477
- let port = location.port;
4478
- // some user agents have empty `location.port`
4479
- if (!port) {
4480
- port = isSSL ? "443" : "80";
4481
- }
4482
- this.xd =
4483
- (typeof location !== "undefined" &&
4484
- opts.hostname !== location.hostname) ||
4485
- port !== opts.port;
4486
- this.xs = opts.secure !== isSSL;
4487
- }
4488
- /**
4489
- * XHR supports binary
4490
- */
4491
- const forceBase64 = opts && opts.forceBase64;
4492
- this.supportsBinary = hasXHR2 && !forceBase64;
4493
- }
4494
4315
  /**
4495
4316
  * Creates a request.
4496
4317
  *
@@ -4514,8 +4335,8 @@ class XHR extends Polling {
4514
4335
  data: data
4515
4336
  });
4516
4337
  req.on("success", fn);
4517
- req.on("error", err => {
4518
- this.onError("xhr post error", err);
4338
+ req.on("error", (xhrStatus, context) => {
4339
+ this.onError("xhr post error", xhrStatus, context);
4519
4340
  });
4520
4341
  }
4521
4342
  /**
@@ -4526,8 +4347,8 @@ class XHR extends Polling {
4526
4347
  doPoll() {
4527
4348
  const req = this.request();
4528
4349
  req.on("data", this.onData.bind(this));
4529
- req.on("error", err => {
4530
- this.onError("xhr poll error", err);
4350
+ req.on("error", (xhrStatus, context) => {
4351
+ this.onError("xhr poll error", xhrStatus, context);
4531
4352
  });
4532
4353
  this.pollXhr = req;
4533
4354
  }
@@ -4558,7 +4379,7 @@ class Request extends Emitter_1 {
4558
4379
  const opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
4559
4380
  opts.xdomain = !!this.opts.xd;
4560
4381
  opts.xscheme = !!this.opts.xs;
4561
- const xhr = (this.xhr = new XMLHttpRequest$1(opts));
4382
+ const xhr = (this.xhr = new XHR(opts));
4562
4383
  try {
4563
4384
  xhr.open(this.method, this.uri, this.async);
4564
4385
  try {
@@ -4614,28 +4435,10 @@ class Request extends Emitter_1 {
4614
4435
  }, 0);
4615
4436
  return;
4616
4437
  }
4617
- if (typeof document !== "undefined") {
4618
- this.index = Request.requestsCount++;
4619
- Request.requests[this.index] = this;
4620
- }
4621
- }
4622
- /**
4623
- * Called upon successful response.
4624
- *
4625
- * @api private
4626
- */
4627
- onSuccess() {
4628
- this.emit("success");
4629
- this.cleanup();
4630
- }
4631
- /**
4632
- * Called if we have data.
4633
- *
4634
- * @api private
4635
- */
4636
- onData(data) {
4637
- this.emit("data", data);
4638
- this.onSuccess();
4438
+ if (typeof document !== "undefined") {
4439
+ this.index = Request.requestsCount++;
4440
+ Request.requests[this.index] = this;
4441
+ }
4639
4442
  }
4640
4443
  /**
4641
4444
  * Called upon error.
@@ -4643,7 +4446,7 @@ class Request extends Emitter_1 {
4643
4446
  * @api private
4644
4447
  */
4645
4448
  onError(err) {
4646
- this.emit("error", err);
4449
+ this.emitReserved("error", err, this.xhr);
4647
4450
  this.cleanup(true);
4648
4451
  }
4649
4452
  /**
@@ -4675,7 +4478,9 @@ class Request extends Emitter_1 {
4675
4478
  onLoad() {
4676
4479
  const data = this.xhr.responseText;
4677
4480
  if (data !== null) {
4678
- this.onData(data);
4481
+ this.emitReserved("data", data);
4482
+ this.emitReserved("success");
4483
+ this.cleanup();
4679
4484
  }
4680
4485
  }
4681
4486
  /**
@@ -4701,7 +4506,7 @@ if (typeof document !== "undefined") {
4701
4506
  attachEvent("onunload", unloadHandler);
4702
4507
  }
4703
4508
  else if (typeof addEventListener === "function") {
4704
- const terminationEvent = "onpagehide" in globalThis$1 ? "pagehide" : "unload";
4509
+ const terminationEvent = "onpagehide" in globalThisShim ? "pagehide" : "unload";
4705
4510
  addEventListener(terminationEvent, unloadHandler, false);
4706
4511
  }
4707
4512
  }
@@ -4722,7 +4527,7 @@ const nextTick = (() => {
4722
4527
  return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
4723
4528
  }
4724
4529
  })();
4725
- const WebSocket = globalThis$1.WebSocket || globalThis$1.MozWebSocket;
4530
+ const WebSocket = globalThisShim.WebSocket || globalThisShim.MozWebSocket;
4726
4531
  const usingBrowserWebSocket = true;
4727
4532
  const defaultBinaryType = "arraybuffer";
4728
4533
 
@@ -4777,7 +4582,7 @@ class WS extends Transport {
4777
4582
  : new WebSocket(uri, protocols, opts);
4778
4583
  }
4779
4584
  catch (err) {
4780
- return this.emit("error", err);
4585
+ return this.emitReserved("error", err);
4781
4586
  }
4782
4587
  this.ws.binaryType = this.socket.binaryType || defaultBinaryType;
4783
4588
  this.addEventListeners();
@@ -4794,7 +4599,10 @@ class WS extends Transport {
4794
4599
  }
4795
4600
  this.onOpen();
4796
4601
  };
4797
- this.ws.onclose = this.onClose.bind(this);
4602
+ this.ws.onclose = closeEvent => this.onClose({
4603
+ description: "websocket connection closed",
4604
+ context: closeEvent
4605
+ });
4798
4606
  this.ws.onmessage = ev => this.onData(ev.data);
4799
4607
  this.ws.onerror = e => this.onError("websocket error", e);
4800
4608
  }
@@ -4830,7 +4638,7 @@ class WS extends Transport {
4830
4638
  // defer to next tick to allow Socket to clear writeBuffer
4831
4639
  nextTick(() => {
4832
4640
  this.writable = true;
4833
- this.emit("drain");
4641
+ this.emitReserved("drain");
4834
4642
  }, this.setTimeoutFn);
4835
4643
  }
4836
4644
  });
@@ -4864,13 +4672,13 @@ class WS extends Transport {
4864
4672
  }
4865
4673
  // append timestamp to URI
4866
4674
  if (this.opts.timestampRequests) {
4867
- query[this.opts.timestampParam] = yeast_1();
4675
+ query[this.opts.timestampParam] = yeast();
4868
4676
  }
4869
4677
  // communicate binary support capabilities
4870
4678
  if (!this.supportsBinary) {
4871
4679
  query.b64 = 1;
4872
4680
  }
4873
- const encodedQuery = parseqs.encode(query);
4681
+ const encodedQuery = encode(query);
4874
4682
  const ipv6 = this.opts.hostname.indexOf(":") !== -1;
4875
4683
  return (schema +
4876
4684
  "://" +
@@ -4886,16 +4694,65 @@ class WS extends Transport {
4886
4694
  * @api public
4887
4695
  */
4888
4696
  check() {
4889
- return (!!WebSocket &&
4890
- !("__initialize" in WebSocket && this.name === WS.prototype.name));
4697
+ return !!WebSocket;
4891
4698
  }
4892
4699
  }
4893
4700
 
4894
4701
  const transports = {
4895
4702
  websocket: WS,
4896
- polling: XHR
4703
+ polling: Polling
4897
4704
  };
4898
4705
 
4706
+ // imported from https://github.com/galkn/parseuri
4707
+ /**
4708
+ * Parses an URI
4709
+ *
4710
+ * @author Steven Levithan <stevenlevithan.com> (MIT license)
4711
+ * @api private
4712
+ */
4713
+ const re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
4714
+ const parts = [
4715
+ 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
4716
+ ];
4717
+ function parse$2(str) {
4718
+ const src = str, b = str.indexOf('['), e = str.indexOf(']');
4719
+ if (b != -1 && e != -1) {
4720
+ str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
4721
+ }
4722
+ let m = re.exec(str || ''), uri = {}, i = 14;
4723
+ while (i--) {
4724
+ uri[parts[i]] = m[i] || '';
4725
+ }
4726
+ if (b != -1 && e != -1) {
4727
+ uri.source = src;
4728
+ uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
4729
+ uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
4730
+ uri.ipv6uri = true;
4731
+ }
4732
+ uri.pathNames = pathNames(uri, uri['path']);
4733
+ uri.queryKey = queryKey(uri, uri['query']);
4734
+ return uri;
4735
+ }
4736
+ function pathNames(obj, path) {
4737
+ const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/");
4738
+ if (path.substr(0, 1) == '/' || path.length === 0) {
4739
+ names.splice(0, 1);
4740
+ }
4741
+ if (path.substr(path.length - 1, 1) == '/') {
4742
+ names.splice(names.length - 1, 1);
4743
+ }
4744
+ return names;
4745
+ }
4746
+ function queryKey(uri, query) {
4747
+ const data = {};
4748
+ query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) {
4749
+ if ($1) {
4750
+ data[$1] = $2;
4751
+ }
4752
+ });
4753
+ return data;
4754
+ }
4755
+
4899
4756
  class Socket$1 extends Emitter_1 {
4900
4757
  /**
4901
4758
  * Socket constructor.
@@ -4911,7 +4768,7 @@ class Socket$1 extends Emitter_1 {
4911
4768
  uri = null;
4912
4769
  }
4913
4770
  if (uri) {
4914
- uri = parseuri(uri);
4771
+ uri = parse$2(uri);
4915
4772
  opts.hostname = uri.host;
4916
4773
  opts.secure = uri.protocol === "https" || uri.protocol === "wss";
4917
4774
  opts.port = uri.port;
@@ -4919,7 +4776,7 @@ class Socket$1 extends Emitter_1 {
4919
4776
  opts.query = uri.query;
4920
4777
  }
4921
4778
  else if (opts.host) {
4922
- opts.hostname = parseuri(opts.host).host;
4779
+ opts.hostname = parse$2(opts.host).host;
4923
4780
  }
4924
4781
  installTimerFunctions(this, opts);
4925
4782
  this.secure =
@@ -4960,7 +4817,7 @@ class Socket$1 extends Emitter_1 {
4960
4817
  }, opts);
4961
4818
  this.opts.path = this.opts.path.replace(/\/$/, "") + "/";
4962
4819
  if (typeof this.opts.query === "string") {
4963
- this.opts.query = parseqs.decode(this.opts.query);
4820
+ this.opts.query = decode(this.opts.query);
4964
4821
  }
4965
4822
  // set on handshake
4966
4823
  this.id = null;
@@ -4984,7 +4841,9 @@ class Socket$1 extends Emitter_1 {
4984
4841
  }
4985
4842
  if (this.hostname !== "localhost") {
4986
4843
  this.offlineEventListener = () => {
4987
- this.onClose("transport close");
4844
+ this.onClose("transport close", {
4845
+ description: "network connection lost"
4846
+ });
4988
4847
  };
4989
4848
  addEventListener("offline", this.offlineEventListener, false);
4990
4849
  }
@@ -4999,7 +4858,7 @@ class Socket$1 extends Emitter_1 {
4999
4858
  * @api private
5000
4859
  */
5001
4860
  createTransport(name) {
5002
- const query = clone(this.opts.query);
4861
+ const query = Object.assign({}, this.opts.query);
5003
4862
  // append engine.io protocol identifier
5004
4863
  query.EIO = protocol$1;
5005
4864
  // transport name
@@ -5067,9 +4926,7 @@ class Socket$1 extends Emitter_1 {
5067
4926
  .on("drain", this.onDrain.bind(this))
5068
4927
  .on("packet", this.onPacket.bind(this))
5069
4928
  .on("error", this.onError.bind(this))
5070
- .on("close", () => {
5071
- this.onClose("transport close");
5072
- });
4929
+ .on("close", reason => this.onClose("transport close", reason));
5073
4930
  }
5074
4931
  /**
5075
4932
  * Probes a transport.
@@ -5231,6 +5088,7 @@ class Socket$1 extends Emitter_1 {
5231
5088
  this.upgrades = this.filterUpgrades(data.upgrades);
5232
5089
  this.pingInterval = data.pingInterval;
5233
5090
  this.pingTimeout = data.pingTimeout;
5091
+ this.maxPayload = data.maxPayload;
5234
5092
  this.onOpen();
5235
5093
  // In case open handler closes socket
5236
5094
  if ("closed" === this.readyState)
@@ -5279,13 +5137,40 @@ class Socket$1 extends Emitter_1 {
5279
5137
  this.transport.writable &&
5280
5138
  !this.upgrading &&
5281
5139
  this.writeBuffer.length) {
5282
- this.transport.send(this.writeBuffer);
5140
+ const packets = this.getWritablePackets();
5141
+ this.transport.send(packets);
5283
5142
  // keep track of current length of writeBuffer
5284
5143
  // splice writeBuffer and callbackBuffer on `drain`
5285
- this.prevBufferLen = this.writeBuffer.length;
5144
+ this.prevBufferLen = packets.length;
5286
5145
  this.emitReserved("flush");
5287
5146
  }
5288
5147
  }
5148
+ /**
5149
+ * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP
5150
+ * long-polling)
5151
+ *
5152
+ * @private
5153
+ */
5154
+ getWritablePackets() {
5155
+ const shouldCheckPayloadSize = this.maxPayload &&
5156
+ this.transport.name === "polling" &&
5157
+ this.writeBuffer.length > 1;
5158
+ if (!shouldCheckPayloadSize) {
5159
+ return this.writeBuffer;
5160
+ }
5161
+ let payloadSize = 1; // first packet type
5162
+ for (let i = 0; i < this.writeBuffer.length; i++) {
5163
+ const data = this.writeBuffer[i].data;
5164
+ if (data) {
5165
+ payloadSize += byteLength(data);
5166
+ }
5167
+ if (i > 0 && payloadSize > this.maxPayload) {
5168
+ return this.writeBuffer.slice(0, i);
5169
+ }
5170
+ payloadSize += 2; // separator + packet type
5171
+ }
5172
+ return this.writeBuffer;
5173
+ }
5289
5174
  /**
5290
5175
  * Sends a message.
5291
5176
  *
@@ -5393,7 +5278,7 @@ class Socket$1 extends Emitter_1 {
5393
5278
  *
5394
5279
  * @api private
5395
5280
  */
5396
- onClose(reason, desc) {
5281
+ onClose(reason, description) {
5397
5282
  if ("opening" === this.readyState ||
5398
5283
  "open" === this.readyState ||
5399
5284
  "closing" === this.readyState) {
@@ -5413,7 +5298,7 @@ class Socket$1 extends Emitter_1 {
5413
5298
  // clear session id
5414
5299
  this.id = null;
5415
5300
  // emit close event
5416
- this.emitReserved("close", reason, desc);
5301
+ this.emitReserved("close", reason, description);
5417
5302
  // clean buffers after, so users can still
5418
5303
  // grab the buffers on `close` event
5419
5304
  this.writeBuffer = [];
@@ -5439,18 +5324,68 @@ class Socket$1 extends Emitter_1 {
5439
5324
  }
5440
5325
  }
5441
5326
  Socket$1.protocol = protocol$1;
5442
- function clone(obj) {
5443
- const o = {};
5444
- for (let i in obj) {
5445
- if (obj.hasOwnProperty(i)) {
5446
- o[i] = obj[i];
5327
+
5328
+ Socket$1.protocol;
5329
+
5330
+ /**
5331
+ * URL parser.
5332
+ *
5333
+ * @param uri - url
5334
+ * @param path - the request path of the connection
5335
+ * @param loc - An object meant to mimic window.location.
5336
+ * Defaults to window.location.
5337
+ * @public
5338
+ */
5339
+ function url(uri, path = "", loc) {
5340
+ let obj = uri;
5341
+ // default to window.location
5342
+ loc = loc || (typeof location !== "undefined" && location);
5343
+ if (null == uri)
5344
+ uri = loc.protocol + "//" + loc.host;
5345
+ // relative path support
5346
+ if (typeof uri === "string") {
5347
+ if ("/" === uri.charAt(0)) {
5348
+ if ("/" === uri.charAt(1)) {
5349
+ uri = loc.protocol + uri;
5350
+ }
5351
+ else {
5352
+ uri = loc.host + uri;
5353
+ }
5354
+ }
5355
+ if (!/^(https?|wss?):\/\//.test(uri)) {
5356
+ if ("undefined" !== typeof loc) {
5357
+ uri = loc.protocol + "//" + uri;
5358
+ }
5359
+ else {
5360
+ uri = "https://" + uri;
5361
+ }
5362
+ }
5363
+ // parse
5364
+ obj = parse$2(uri);
5365
+ }
5366
+ // make sure we treat `localhost:80` and `localhost` equally
5367
+ if (!obj.port) {
5368
+ if (/^(http|ws)$/.test(obj.protocol)) {
5369
+ obj.port = "80";
5370
+ }
5371
+ else if (/^(http|ws)s$/.test(obj.protocol)) {
5372
+ obj.port = "443";
5447
5373
  }
5448
5374
  }
5449
- return o;
5375
+ obj.path = obj.path || "/";
5376
+ const ipv6 = obj.host.indexOf(":") !== -1;
5377
+ const host = ipv6 ? "[" + obj.host + "]" : obj.host;
5378
+ // define unique id
5379
+ obj.id = obj.protocol + "://" + host + ":" + obj.port + path;
5380
+ // define href
5381
+ obj.href =
5382
+ obj.protocol +
5383
+ "://" +
5384
+ host +
5385
+ (loc && loc.port === obj.port ? "" : ":" + obj.port);
5386
+ return obj;
5450
5387
  }
5451
5388
 
5452
- Socket$1.protocol;
5453
-
5454
5389
  const withNativeArrayBuffer = typeof ArrayBuffer === "function";
5455
5390
  const isView = (obj) => {
5456
5391
  return typeof ArrayBuffer.isView === "function"
@@ -5597,6 +5532,14 @@ var PacketType;
5597
5532
  * A socket.io Encoder instance
5598
5533
  */
5599
5534
  class Encoder {
5535
+ /**
5536
+ * Encoder constructor
5537
+ *
5538
+ * @param {function} replacer - custom replacer to pass down to JSON.parse
5539
+ */
5540
+ constructor(replacer) {
5541
+ this.replacer = replacer;
5542
+ }
5600
5543
  /**
5601
5544
  * Encode a packet as a single string if non-binary, or as a
5602
5545
  * buffer sequence, depending on packet type.
@@ -5637,7 +5580,7 @@ class Encoder {
5637
5580
  }
5638
5581
  // json data
5639
5582
  if (null != obj.data) {
5640
- str += JSON.stringify(obj.data);
5583
+ str += JSON.stringify(obj.data, this.replacer);
5641
5584
  }
5642
5585
  return str;
5643
5586
  }
@@ -5660,8 +5603,14 @@ class Encoder {
5660
5603
  * @return {Object} decoder
5661
5604
  */
5662
5605
  class Decoder extends Emitter_1 {
5663
- constructor() {
5606
+ /**
5607
+ * Decoder constructor
5608
+ *
5609
+ * @param {function} reviver - custom reviver to pass down to JSON.stringify
5610
+ */
5611
+ constructor(reviver) {
5664
5612
  super();
5613
+ this.reviver = reviver;
5665
5614
  }
5666
5615
  /**
5667
5616
  * Decodes an encoded packet string into packet JSON.
@@ -5762,7 +5711,7 @@ class Decoder extends Emitter_1 {
5762
5711
  }
5763
5712
  // look up json data
5764
5713
  if (str.charAt(++i)) {
5765
- const payload = tryParse(str.substr(i));
5714
+ const payload = this.tryParse(str.substr(i));
5766
5715
  if (Decoder.isPayloadValid(p.type, payload)) {
5767
5716
  p.data = payload;
5768
5717
  }
@@ -5772,6 +5721,14 @@ class Decoder extends Emitter_1 {
5772
5721
  }
5773
5722
  return p;
5774
5723
  }
5724
+ tryParse(str) {
5725
+ try {
5726
+ return JSON.parse(str, this.reviver);
5727
+ }
5728
+ catch (e) {
5729
+ return false;
5730
+ }
5731
+ }
5775
5732
  static isPayloadValid(type, payload) {
5776
5733
  switch (type) {
5777
5734
  case PacketType.CONNECT:
@@ -5797,14 +5754,6 @@ class Decoder extends Emitter_1 {
5797
5754
  }
5798
5755
  }
5799
5756
  }
5800
- function tryParse(str) {
5801
- try {
5802
- return JSON.parse(str);
5803
- }
5804
- catch (e) {
5805
- return false;
5806
- }
5807
- }
5808
5757
  /**
5809
5758
  * A manager of a binary event's 'buffer sequence'. Should
5810
5759
  * be constructed whenever a packet of type BINARY_EVENT is
@@ -5883,7 +5832,6 @@ class Socket extends Emitter_1 {
5883
5832
  constructor(io, nsp, opts) {
5884
5833
  super();
5885
5834
  this.connected = false;
5886
- this.disconnected = true;
5887
5835
  this.receiveBuffer = [];
5888
5836
  this.sendBuffer = [];
5889
5837
  this.ids = 0;
@@ -5897,6 +5845,12 @@ class Socket extends Emitter_1 {
5897
5845
  if (this.io._autoConnect)
5898
5846
  this.open();
5899
5847
  }
5848
+ /**
5849
+ * Whether the socket is currently disconnected
5850
+ */
5851
+ get disconnected() {
5852
+ return !this.connected;
5853
+ }
5900
5854
  /**
5901
5855
  * Subscribe to open, close and packet events
5902
5856
  *
@@ -5982,6 +5936,7 @@ class Socket extends Emitter_1 {
5982
5936
  const discardPacket = this.flags.volatile && (!isTransportWritable || !this.connected);
5983
5937
  if (discardPacket) ;
5984
5938
  else if (this.connected) {
5939
+ this.notifyOutgoingListeners(packet);
5985
5940
  this.packet(packet);
5986
5941
  }
5987
5942
  else {
@@ -6055,13 +6010,13 @@ class Socket extends Emitter_1 {
6055
6010
  * Called upon engine `close`.
6056
6011
  *
6057
6012
  * @param reason
6013
+ * @param description
6058
6014
  * @private
6059
6015
  */
6060
- onclose(reason) {
6016
+ onclose(reason, description) {
6061
6017
  this.connected = false;
6062
- this.disconnected = true;
6063
6018
  delete this.id;
6064
- this.emitReserved("disconnect", reason);
6019
+ this.emitReserved("disconnect", reason, description);
6065
6020
  }
6066
6021
  /**
6067
6022
  * Called with socket packet.
@@ -6084,14 +6039,10 @@ class Socket extends Emitter_1 {
6084
6039
  }
6085
6040
  break;
6086
6041
  case PacketType.EVENT:
6087
- this.onevent(packet);
6088
- break;
6089
6042
  case PacketType.BINARY_EVENT:
6090
6043
  this.onevent(packet);
6091
6044
  break;
6092
6045
  case PacketType.ACK:
6093
- this.onack(packet);
6094
- break;
6095
6046
  case PacketType.BINARY_ACK:
6096
6047
  this.onack(packet);
6097
6048
  break;
@@ -6175,7 +6126,6 @@ class Socket extends Emitter_1 {
6175
6126
  onconnect(id) {
6176
6127
  this.id = id;
6177
6128
  this.connected = true;
6178
- this.disconnected = false;
6179
6129
  this.emitBuffered();
6180
6130
  this.emitReserved("connect");
6181
6131
  }
@@ -6187,7 +6137,10 @@ class Socket extends Emitter_1 {
6187
6137
  emitBuffered() {
6188
6138
  this.receiveBuffer.forEach((args) => this.emitEvent(args));
6189
6139
  this.receiveBuffer = [];
6190
- this.sendBuffer.forEach((packet) => this.packet(packet));
6140
+ this.sendBuffer.forEach((packet) => {
6141
+ this.notifyOutgoingListeners(packet);
6142
+ this.packet(packet);
6143
+ });
6191
6144
  this.sendBuffer = [];
6192
6145
  }
6193
6146
  /**
@@ -6339,14 +6292,112 @@ class Socket extends Emitter_1 {
6339
6292
  listenersAny() {
6340
6293
  return this._anyListeners || [];
6341
6294
  }
6295
+ /**
6296
+ * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
6297
+ * callback.
6298
+ *
6299
+ * @param listener
6300
+ *
6301
+ * <pre><code>
6302
+ *
6303
+ * socket.onAnyOutgoing((event, ...args) => {
6304
+ * console.log(event);
6305
+ * });
6306
+ *
6307
+ * </pre></code>
6308
+ *
6309
+ * @public
6310
+ */
6311
+ onAnyOutgoing(listener) {
6312
+ this._anyOutgoingListeners = this._anyOutgoingListeners || [];
6313
+ this._anyOutgoingListeners.push(listener);
6314
+ return this;
6315
+ }
6316
+ /**
6317
+ * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
6318
+ * callback. The listener is added to the beginning of the listeners array.
6319
+ *
6320
+ * @param listener
6321
+ *
6322
+ * <pre><code>
6323
+ *
6324
+ * socket.prependAnyOutgoing((event, ...args) => {
6325
+ * console.log(event);
6326
+ * });
6327
+ *
6328
+ * </pre></code>
6329
+ *
6330
+ * @public
6331
+ */
6332
+ prependAnyOutgoing(listener) {
6333
+ this._anyOutgoingListeners = this._anyOutgoingListeners || [];
6334
+ this._anyOutgoingListeners.unshift(listener);
6335
+ return this;
6336
+ }
6337
+ /**
6338
+ * Removes the listener that will be fired when any event is emitted.
6339
+ *
6340
+ * @param listener
6341
+ *
6342
+ * <pre><code>
6343
+ *
6344
+ * const handler = (event, ...args) => {
6345
+ * console.log(event);
6346
+ * }
6347
+ *
6348
+ * socket.onAnyOutgoing(handler);
6349
+ *
6350
+ * // then later
6351
+ * socket.offAnyOutgoing(handler);
6352
+ *
6353
+ * </pre></code>
6354
+ *
6355
+ * @public
6356
+ */
6357
+ offAnyOutgoing(listener) {
6358
+ if (!this._anyOutgoingListeners) {
6359
+ return this;
6360
+ }
6361
+ if (listener) {
6362
+ const listeners = this._anyOutgoingListeners;
6363
+ for (let i = 0; i < listeners.length; i++) {
6364
+ if (listener === listeners[i]) {
6365
+ listeners.splice(i, 1);
6366
+ return this;
6367
+ }
6368
+ }
6369
+ }
6370
+ else {
6371
+ this._anyOutgoingListeners = [];
6372
+ }
6373
+ return this;
6374
+ }
6375
+ /**
6376
+ * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
6377
+ * e.g. to remove listeners.
6378
+ *
6379
+ * @public
6380
+ */
6381
+ listenersAnyOutgoing() {
6382
+ return this._anyOutgoingListeners || [];
6383
+ }
6384
+ /**
6385
+ * Notify the listeners for each packet sent
6386
+ *
6387
+ * @param packet
6388
+ *
6389
+ * @private
6390
+ */
6391
+ notifyOutgoingListeners(packet) {
6392
+ if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) {
6393
+ const listeners = this._anyOutgoingListeners.slice();
6394
+ for (const listener of listeners) {
6395
+ listener.apply(this, packet.data);
6396
+ }
6397
+ }
6398
+ }
6342
6399
  }
6343
6400
 
6344
- /**
6345
- * Expose `Backoff`.
6346
- */
6347
-
6348
- var backo2 = Backoff;
6349
-
6350
6401
  /**
6351
6402
  * Initialize backoff timer with `opts`.
6352
6403
  *
@@ -6358,71 +6409,60 @@ var backo2 = Backoff;
6358
6409
  * @param {Object} opts
6359
6410
  * @api public
6360
6411
  */
6361
-
6362
6412
  function Backoff(opts) {
6363
- opts = opts || {};
6364
- this.ms = opts.min || 100;
6365
- this.max = opts.max || 10000;
6366
- this.factor = opts.factor || 2;
6367
- this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
6368
- this.attempts = 0;
6413
+ opts = opts || {};
6414
+ this.ms = opts.min || 100;
6415
+ this.max = opts.max || 10000;
6416
+ this.factor = opts.factor || 2;
6417
+ this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
6418
+ this.attempts = 0;
6369
6419
  }
6370
-
6371
6420
  /**
6372
6421
  * Return the backoff duration.
6373
6422
  *
6374
6423
  * @return {Number}
6375
6424
  * @api public
6376
6425
  */
6377
-
6378
- Backoff.prototype.duration = function(){
6379
- var ms = this.ms * Math.pow(this.factor, this.attempts++);
6380
- if (this.jitter) {
6381
- var rand = Math.random();
6382
- var deviation = Math.floor(rand * this.jitter * ms);
6383
- ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
6384
- }
6385
- return Math.min(ms, this.max) | 0;
6426
+ Backoff.prototype.duration = function () {
6427
+ var ms = this.ms * Math.pow(this.factor, this.attempts++);
6428
+ if (this.jitter) {
6429
+ var rand = Math.random();
6430
+ var deviation = Math.floor(rand * this.jitter * ms);
6431
+ ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
6432
+ }
6433
+ return Math.min(ms, this.max) | 0;
6386
6434
  };
6387
-
6388
6435
  /**
6389
6436
  * Reset the number of attempts.
6390
6437
  *
6391
6438
  * @api public
6392
6439
  */
6393
-
6394
- Backoff.prototype.reset = function(){
6395
- this.attempts = 0;
6440
+ Backoff.prototype.reset = function () {
6441
+ this.attempts = 0;
6396
6442
  };
6397
-
6398
6443
  /**
6399
6444
  * Set the minimum duration
6400
6445
  *
6401
6446
  * @api public
6402
6447
  */
6403
-
6404
- Backoff.prototype.setMin = function(min){
6405
- this.ms = min;
6448
+ Backoff.prototype.setMin = function (min) {
6449
+ this.ms = min;
6406
6450
  };
6407
-
6408
6451
  /**
6409
6452
  * Set the maximum duration
6410
6453
  *
6411
6454
  * @api public
6412
6455
  */
6413
-
6414
- Backoff.prototype.setMax = function(max){
6415
- this.max = max;
6456
+ Backoff.prototype.setMax = function (max) {
6457
+ this.max = max;
6416
6458
  };
6417
-
6418
6459
  /**
6419
6460
  * Set the jitter
6420
6461
  *
6421
6462
  * @api public
6422
6463
  */
6423
-
6424
- Backoff.prototype.setJitter = function(jitter){
6425
- this.jitter = jitter;
6464
+ Backoff.prototype.setJitter = function (jitter) {
6465
+ this.jitter = jitter;
6426
6466
  };
6427
6467
 
6428
6468
  class Manager extends Emitter_1 {
@@ -6444,7 +6484,7 @@ class Manager extends Emitter_1 {
6444
6484
  this.reconnectionDelay(opts.reconnectionDelay || 1000);
6445
6485
  this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
6446
6486
  this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5);
6447
- this.backoff = new backo2({
6487
+ this.backoff = new Backoff({
6448
6488
  min: this.reconnectionDelay(),
6449
6489
  max: this.reconnectionDelayMax(),
6450
6490
  jitter: this.randomizationFactor(),
@@ -6705,11 +6745,11 @@ class Manager extends Emitter_1 {
6705
6745
  *
6706
6746
  * @private
6707
6747
  */
6708
- onclose(reason) {
6748
+ onclose(reason, description) {
6709
6749
  this.cleanup();
6710
6750
  this.backoff.reset();
6711
6751
  this._readyState = "closed";
6712
- this.emitReserved("close", reason);
6752
+ this.emitReserved("close", reason, description);
6713
6753
  if (this._reconnection && !this.skipReconnect) {
6714
6754
  this.reconnect();
6715
6755
  }
@@ -7637,6 +7677,35 @@ var ChatMessage = function (props) {
7637
7677
  React$1.createElement("div", { className: "chat-msg-container ".concat(getClassName(props.message)) }, renderByType())));
7638
7678
  };
7639
7679
 
7680
+ /**
7681
+ * value must be like "60m", "2h" etc.
7682
+ */
7683
+ function convertToSeconds(value) {
7684
+ var unit = value === null || value === void 0 ? void 0 : value.slice(-1);
7685
+ var number = parseFloat(value === null || value === void 0 ? void 0 : value.slice(0, -1));
7686
+ switch (unit) {
7687
+ case "d": {
7688
+ return number * 24 * 60 * 60;
7689
+ }
7690
+ case "h": {
7691
+ return number * 60 * 60;
7692
+ }
7693
+ case "m": {
7694
+ return number * 60;
7695
+ }
7696
+ case "s": {
7697
+ return number;
7698
+ }
7699
+ default: {
7700
+ return number;
7701
+ }
7702
+ }
7703
+ }
7704
+
7705
+ function checkSessionExpiration(duration, lastMessageTimestamp, lastTimestamp) {
7706
+ return lastTimestamp - lastMessageTimestamp > convertToSeconds(duration);
7707
+ }
7708
+
7640
7709
  function useExternalScript(url) {
7641
7710
  useEffect(function () {
7642
7711
  if (!url) {
@@ -30769,7 +30838,10 @@ var ChatWidgetWrapper = function (props) {
30769
30838
  }, [connection, rawConfig]);
30770
30839
  var token = useSelector(function (state) { return state.connection.token; });
30771
30840
  var options = useMemo(function () {
30772
- var _a;
30841
+ var configurableMessages = getConfigurableMessages();
30842
+ if (rawConfig.configurableMessages && Array.isArray(rawConfig.configurableMessages.items) && rawConfig.configurableMessages.items.length > 0) {
30843
+ configurableMessages = rawConfig.configurableMessages;
30844
+ }
30773
30845
  return {
30774
30846
  token: token,
30775
30847
  bot: {
@@ -30777,7 +30849,7 @@ var ChatWidgetWrapper = function (props) {
30777
30849
  displayName: rawConfig.botName,
30778
30850
  avatarPath: rawConfig.avatarUrl
30779
30851
  },
30780
- configurableMessages: (_a = rawConfig.configurableMessages) !== null && _a !== void 0 ? _a : getConfigurableMessages()
30852
+ configurableMessages: configurableMessages
30781
30853
  };
30782
30854
  }, [token, rawConfig]);
30783
30855
  var chatServer = useChatServer(connection, options);
@@ -30816,7 +30888,13 @@ var ChatWidget = function (props) {
30816
30888
  set$1("visible", newVisible);
30817
30889
  }, [staticMode]);
30818
30890
  useEffect(function () {
30819
- // For reopen widget after move on same window
30891
+ var _a;
30892
+ if (checkSessionExpiration(chatState === null || chatState === void 0 ? void 0 : chatState.sessionExpiration, (_a = chatState === null || chatState === void 0 ? void 0 : chatState.chats[chatState.chats.length - 1]) === null || _a === void 0 ? void 0 : _a.timestamp, chatState === null || chatState === void 0 ? void 0 : chatState.lastTimestamp)) {
30893
+ innerDispatch(reset());
30894
+ }
30895
+ }, []);
30896
+ useEffect(function () {
30897
+ // For reopen widget after move on same windowyar
30820
30898
  if (get("opened")) {
30821
30899
  setVisible(true);
30822
30900
  }
@@ -30986,7 +31064,7 @@ function createDefaultState(state) {
30986
31064
  connectionStatus: "offline",
30987
31065
  token: null,
30988
31066
  greetingRequested: false
30989
- }, accountStatus: "offline", departments: {}, visitor: DEFAULT_VISITOR, agents: {}, chats: [], lastTimestamp: 0, lastRatingRequestTimestamp: 0, hasRating: false, isChatting: false, queuePosition: 0, failureMsg: null, visitorId: visitorFingerprint(), chips: [] }, state);
31067
+ }, accountStatus: "offline", departments: {}, visitor: DEFAULT_VISITOR, agents: {}, chats: [], lastTimestamp: 0, lastRatingRequestTimestamp: 0, hasRating: false, isChatting: false, queuePosition: 0, failureMsg: null, visitorId: visitorFingerprint(), chips: [], sessionExpiration: "24h" }, state);
30990
31068
  }
30991
31069
  var DEFAULT_STATE = createDefaultState();
30992
31070
 
@@ -31183,7 +31261,7 @@ function createChatStore(config, dataStorage) {
31183
31261
  if (dataStorage === void 0) { dataStorage = localStorage; }
31184
31262
  var connection = config.connection;
31185
31263
  var storage = new BrowserStateStorage(dataStorage, "xappchat.".concat(connection.serverUrl, ".").concat(connection.accountKey));
31186
- var defaultState = createDefaultState({ accessToken: config.accessToken, userId: config.userId, attributes: config.attributes });
31264
+ var defaultState = createDefaultState({ accessToken: config.accessToken, userId: config.userId, attributes: config.attributes, sessionExpiration: config.sessionExpiration });
31187
31265
  var chatReducer = persistStateReducer(storage, defaultState, storeHandler);
31188
31266
  var middlewares = [
31189
31267
  thunk
@@ -31193,19 +31271,20 @@ function createChatStore(config, dataStorage) {
31193
31271
  }
31194
31272
 
31195
31273
  var ChatWidgetContainer = function (props) {
31196
- var _a, _b, _c, _d;
31274
+ var _a, _b, _c, _d, _e;
31197
31275
  var messageMiddleware = useStandardMiddleware();
31198
31276
  var connection = useServerConfig(props.config);
31199
31277
  var chatStore = useMemo(function () {
31200
- var _a, _b, _c;
31278
+ var _a, _b, _c, _d;
31201
31279
  return createChatStore({
31202
31280
  connection: connection,
31203
31281
  userId: (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId,
31204
31282
  accessToken: (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken,
31205
31283
  attributes: (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes,
31284
+ sessionExpiration: (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration
31206
31285
  });
31207
- }, [connection, (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId, (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken, (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes]);
31208
- if ((_d = props.config) === null || _d === void 0 ? void 0 : _d.disabled) {
31286
+ }, [connection, (_a = props.config) === null || _a === void 0 ? void 0 : _a.userId, (_b = props.config) === null || _b === void 0 ? void 0 : _b.accessToken, (_c = props.config) === null || _c === void 0 ? void 0 : _c.attributes, (_d = props.config) === null || _d === void 0 ? void 0 : _d.sessionExpiration]);
31287
+ if ((_e = props.config) === null || _e === void 0 ? void 0 : _e.disabled) {
31209
31288
  return React$1.createElement(React$1.Fragment, null);
31210
31289
  }
31211
31290
  var widgetProps = __assign(__assign({}, props), { messageMiddleware: messageMiddleware });