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