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