@xapp/chat-widget 1.70.2 → 1.72.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.css +1 -10
- package/dist/index.es.js +887 -303
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +887 -303
- package/dist/index.js.map +1 -1
- package/dist/xapp-chat-widget.css +1 -10
- package/dist/xapp-chat-widget.js +4 -4
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +16 -16
package/dist/index.es.js
CHANGED
|
@@ -2296,9 +2296,9 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
2296
2296
|
return __assign(__assign({}, user), { nick: user.nick || bot.nick || "Bot", displayName: user.displayName || bot.displayName || "Bot", avatarPath: user.avatarPath || bot.avatarPath });
|
|
2297
2297
|
};
|
|
2298
2298
|
StentorDirectChat.prototype.sendChatMsgRequest = function (serviceRequest, cb) {
|
|
2299
|
-
var _a;
|
|
2300
2299
|
return __awaiter$1(this, void 0, void 0, function () {
|
|
2301
2300
|
var agentResponse;
|
|
2301
|
+
var _a;
|
|
2302
2302
|
return __generator$1(this, function (_b) {
|
|
2303
2303
|
switch (_b.label) {
|
|
2304
2304
|
case 0: return [4 /*yield*/, this.postMessage(serviceRequest)];
|
|
@@ -2354,10 +2354,10 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
2354
2354
|
StentorDirectChat.prototype.wakeup = function () {
|
|
2355
2355
|
};
|
|
2356
2356
|
StentorDirectChat.prototype.postMessage = function (message) {
|
|
2357
|
-
var _a, _b, _c, _d, _e;
|
|
2358
2357
|
return __awaiter$1(this, void 0, void 0, function () {
|
|
2359
|
-
var request, userId, sessionId, accessToken, attributes, now, permissionRequest, expired, text, granted, userProfile, isEmail, configurableMessages, botResponse, successResult, success, fail, i, timeout, responseMessage;
|
|
2358
|
+
var request, userId, sessionId, accessToken, attributes, rwgToken, merchantId, environment, now, permissionRequest, expired, text, granted, userProfile, isEmail, configurableMessages, botResponse, successResult, success, fail, i, timeout, responseMessage;
|
|
2360
2359
|
var _this = this;
|
|
2360
|
+
var _a, _b, _c, _d, _e;
|
|
2361
2361
|
return __generator$1(this, function (_f) {
|
|
2362
2362
|
switch (_f.label) {
|
|
2363
2363
|
case 0:
|
|
@@ -2365,6 +2365,18 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
2365
2365
|
sessionId = this._sessionId;
|
|
2366
2366
|
accessToken = this._accessToken;
|
|
2367
2367
|
attributes = this._attributes || {};
|
|
2368
|
+
rwgToken = localStorage.getItem("xa_rwg_token");
|
|
2369
|
+
if (rwgToken) {
|
|
2370
|
+
attributes["rwg_token"] = rwgToken;
|
|
2371
|
+
}
|
|
2372
|
+
merchantId = localStorage.getItem("xa_merchant_id");
|
|
2373
|
+
if (merchantId) {
|
|
2374
|
+
attributes["merchant_id"] = merchantId;
|
|
2375
|
+
}
|
|
2376
|
+
environment = localStorage.getItem("xa_environment");
|
|
2377
|
+
if (environment) {
|
|
2378
|
+
attributes["environment"] = environment;
|
|
2379
|
+
}
|
|
2368
2380
|
now = new Date().getTime();
|
|
2369
2381
|
if (this.isNewSession && !((_a = message === null || message === void 0 ? void 0 : message.msg) === null || _a === void 0 ? void 0 : _a.text)) {
|
|
2370
2382
|
request = {
|
|
@@ -2824,7 +2836,7 @@ var StentorRouterChat = /** @class */ (function () {
|
|
|
2824
2836
|
_this.dispatch(setConnectionStatus("offline"));
|
|
2825
2837
|
}
|
|
2826
2838
|
};
|
|
2827
|
-
// Server ping (not sent
|
|
2839
|
+
// Server ping (not sent periodically - at least not for now)
|
|
2828
2840
|
this.handlers["account status"] = function (_data, _sender, ts) {
|
|
2829
2841
|
dispatch({
|
|
2830
2842
|
type: "account_status",
|
|
@@ -3154,9 +3166,11 @@ var StentorRouterChat = /** @class */ (function () {
|
|
|
3154
3166
|
nick: senderToNick(serverInfo),
|
|
3155
3167
|
avatarPath: serverInfo.avatarPath
|
|
3156
3168
|
},
|
|
3157
|
-
msg: {
|
|
3169
|
+
msg: {
|
|
3170
|
+
text: this.noOfServerErrors === 0 ?
|
|
3158
3171
|
"I cannot connect to the server. Please try later." :
|
|
3159
|
-
"Nope. Still no luck. I still cannot connect to the server. Please don't give up."
|
|
3172
|
+
"Nope. Still no luck. I still cannot connect to the server. Please don't give up."
|
|
3173
|
+
},
|
|
3160
3174
|
timestamp: new Date().getTime(),
|
|
3161
3175
|
}
|
|
3162
3176
|
});
|
|
@@ -3279,12 +3293,24 @@ var StentorRouterChat = /** @class */ (function () {
|
|
|
3279
3293
|
};
|
|
3280
3294
|
StentorRouterChat.prototype.postMessage = function (message) {
|
|
3281
3295
|
return __awaiter$1(this, void 0, void 0, function () {
|
|
3282
|
-
var userId, sessionId, accessToken, attributes, request;
|
|
3296
|
+
var userId, sessionId, accessToken, attributes, rwgToken, merchantId, environment, request;
|
|
3283
3297
|
return __generator$1(this, function (_a) {
|
|
3284
3298
|
userId = this._userId;
|
|
3285
3299
|
sessionId = this._sessionId;
|
|
3286
3300
|
accessToken = this.accessToken;
|
|
3287
3301
|
attributes = this.attributes || {};
|
|
3302
|
+
rwgToken = localStorage.getItem("xa_rwg_token");
|
|
3303
|
+
if (rwgToken) {
|
|
3304
|
+
attributes["rwg_token"] = rwgToken;
|
|
3305
|
+
}
|
|
3306
|
+
merchantId = localStorage.getItem("xa_merchant_id");
|
|
3307
|
+
if (merchantId) {
|
|
3308
|
+
attributes["merchant_id"] = merchantId;
|
|
3309
|
+
}
|
|
3310
|
+
environment = localStorage.getItem("xa_environment");
|
|
3311
|
+
if (environment) {
|
|
3312
|
+
attributes["environment"] = environment;
|
|
3313
|
+
}
|
|
3288
3314
|
request = requestFromMessage(message, userId, this.isNewSession, sessionId, accessToken, attributes, this.visitorInfo);
|
|
3289
3315
|
this.emit("new message", request);
|
|
3290
3316
|
return [2 /*return*/];
|
|
@@ -3367,7 +3393,7 @@ PACKET_TYPES["message"] = "4";
|
|
|
3367
3393
|
PACKET_TYPES["upgrade"] = "5";
|
|
3368
3394
|
PACKET_TYPES["noop"] = "6";
|
|
3369
3395
|
const PACKET_TYPES_REVERSE = Object.create(null);
|
|
3370
|
-
Object.keys(PACKET_TYPES).forEach(key => {
|
|
3396
|
+
Object.keys(PACKET_TYPES).forEach((key) => {
|
|
3371
3397
|
PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key;
|
|
3372
3398
|
});
|
|
3373
3399
|
const ERROR_PACKET = { type: "error", data: "parser error" };
|
|
@@ -3377,7 +3403,7 @@ const withNativeBlob$1 = typeof Blob === "function" ||
|
|
|
3377
3403
|
Object.prototype.toString.call(Blob) === "[object BlobConstructor]");
|
|
3378
3404
|
const withNativeArrayBuffer$2 = typeof ArrayBuffer === "function";
|
|
3379
3405
|
// ArrayBuffer.isView method is not defined in IE10
|
|
3380
|
-
const isView$1 = obj => {
|
|
3406
|
+
const isView$1 = (obj) => {
|
|
3381
3407
|
return typeof ArrayBuffer.isView === "function"
|
|
3382
3408
|
? ArrayBuffer.isView(obj)
|
|
3383
3409
|
: obj && obj.buffer instanceof ArrayBuffer;
|
|
@@ -3411,6 +3437,33 @@ const encodeBlobAsBase64 = (data, callback) => {
|
|
|
3411
3437
|
};
|
|
3412
3438
|
return fileReader.readAsDataURL(data);
|
|
3413
3439
|
};
|
|
3440
|
+
function toArray(data) {
|
|
3441
|
+
if (data instanceof Uint8Array) {
|
|
3442
|
+
return data;
|
|
3443
|
+
}
|
|
3444
|
+
else if (data instanceof ArrayBuffer) {
|
|
3445
|
+
return new Uint8Array(data);
|
|
3446
|
+
}
|
|
3447
|
+
else {
|
|
3448
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
let TEXT_ENCODER;
|
|
3452
|
+
function encodePacketToBinary(packet, callback) {
|
|
3453
|
+
if (withNativeBlob$1 && packet.data instanceof Blob) {
|
|
3454
|
+
return packet.data.arrayBuffer().then(toArray).then(callback);
|
|
3455
|
+
}
|
|
3456
|
+
else if (withNativeArrayBuffer$2 &&
|
|
3457
|
+
(packet.data instanceof ArrayBuffer || isView$1(packet.data))) {
|
|
3458
|
+
return callback(toArray(packet.data));
|
|
3459
|
+
}
|
|
3460
|
+
encodePacket(packet, false, (encoded) => {
|
|
3461
|
+
if (!TEXT_ENCODER) {
|
|
3462
|
+
TEXT_ENCODER = new TextEncoder();
|
|
3463
|
+
}
|
|
3464
|
+
callback(TEXT_ENCODER.encode(encoded));
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3414
3467
|
|
|
3415
3468
|
// imported from https://github.com/socketio/base64-arraybuffer
|
|
3416
3469
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
@@ -3445,14 +3498,14 @@ const decodePacket = (encodedPacket, binaryType) => {
|
|
|
3445
3498
|
if (typeof encodedPacket !== "string") {
|
|
3446
3499
|
return {
|
|
3447
3500
|
type: "message",
|
|
3448
|
-
data: mapBinary(encodedPacket, binaryType)
|
|
3501
|
+
data: mapBinary(encodedPacket, binaryType),
|
|
3449
3502
|
};
|
|
3450
3503
|
}
|
|
3451
3504
|
const type = encodedPacket.charAt(0);
|
|
3452
3505
|
if (type === "b") {
|
|
3453
3506
|
return {
|
|
3454
3507
|
type: "message",
|
|
3455
|
-
data: decodeBase64Packet(encodedPacket.substring(1), binaryType)
|
|
3508
|
+
data: decodeBase64Packet(encodedPacket.substring(1), binaryType),
|
|
3456
3509
|
};
|
|
3457
3510
|
}
|
|
3458
3511
|
const packetType = PACKET_TYPES_REVERSE[type];
|
|
@@ -3462,10 +3515,10 @@ const decodePacket = (encodedPacket, binaryType) => {
|
|
|
3462
3515
|
return encodedPacket.length > 1
|
|
3463
3516
|
? {
|
|
3464
3517
|
type: PACKET_TYPES_REVERSE[type],
|
|
3465
|
-
data: encodedPacket.substring(1)
|
|
3518
|
+
data: encodedPacket.substring(1),
|
|
3466
3519
|
}
|
|
3467
3520
|
: {
|
|
3468
|
-
type: PACKET_TYPES_REVERSE[type]
|
|
3521
|
+
type: PACKET_TYPES_REVERSE[type],
|
|
3469
3522
|
};
|
|
3470
3523
|
};
|
|
3471
3524
|
const decodeBase64Packet = (data, binaryType) => {
|
|
@@ -3480,10 +3533,24 @@ const decodeBase64Packet = (data, binaryType) => {
|
|
|
3480
3533
|
const mapBinary = (data, binaryType) => {
|
|
3481
3534
|
switch (binaryType) {
|
|
3482
3535
|
case "blob":
|
|
3483
|
-
|
|
3536
|
+
if (data instanceof Blob) {
|
|
3537
|
+
// from WebSocket + binaryType "blob"
|
|
3538
|
+
return data;
|
|
3539
|
+
}
|
|
3540
|
+
else {
|
|
3541
|
+
// from HTTP long-polling or WebTransport
|
|
3542
|
+
return new Blob([data]);
|
|
3543
|
+
}
|
|
3484
3544
|
case "arraybuffer":
|
|
3485
3545
|
default:
|
|
3486
|
-
|
|
3546
|
+
if (data instanceof ArrayBuffer) {
|
|
3547
|
+
// from HTTP long-polling (base64) or WebSocket + binaryType "arraybuffer"
|
|
3548
|
+
return data;
|
|
3549
|
+
}
|
|
3550
|
+
else {
|
|
3551
|
+
// from WebTransport (Uint8Array)
|
|
3552
|
+
return data.buffer;
|
|
3553
|
+
}
|
|
3487
3554
|
}
|
|
3488
3555
|
};
|
|
3489
3556
|
|
|
@@ -3495,7 +3562,7 @@ const encodePayload = (packets, callback) => {
|
|
|
3495
3562
|
let count = 0;
|
|
3496
3563
|
packets.forEach((packet, i) => {
|
|
3497
3564
|
// force base64 encoding for binary packets
|
|
3498
|
-
encodePacket(packet, false, encodedPacket => {
|
|
3565
|
+
encodePacket(packet, false, (encodedPacket) => {
|
|
3499
3566
|
encodedPackets[i] = encodedPacket;
|
|
3500
3567
|
if (++count === length) {
|
|
3501
3568
|
callback(encodedPackets.join(SEPARATOR));
|
|
@@ -3515,6 +3582,131 @@ const decodePayload = (encodedPayload, binaryType) => {
|
|
|
3515
3582
|
}
|
|
3516
3583
|
return packets;
|
|
3517
3584
|
};
|
|
3585
|
+
function createPacketEncoderStream() {
|
|
3586
|
+
// @ts-expect-error
|
|
3587
|
+
return new TransformStream({
|
|
3588
|
+
transform(packet, controller) {
|
|
3589
|
+
encodePacketToBinary(packet, (encodedPacket) => {
|
|
3590
|
+
const payloadLength = encodedPacket.length;
|
|
3591
|
+
let header;
|
|
3592
|
+
// inspired by the WebSocket format: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#decoding_payload_length
|
|
3593
|
+
if (payloadLength < 126) {
|
|
3594
|
+
header = new Uint8Array(1);
|
|
3595
|
+
new DataView(header.buffer).setUint8(0, payloadLength);
|
|
3596
|
+
}
|
|
3597
|
+
else if (payloadLength < 65536) {
|
|
3598
|
+
header = new Uint8Array(3);
|
|
3599
|
+
const view = new DataView(header.buffer);
|
|
3600
|
+
view.setUint8(0, 126);
|
|
3601
|
+
view.setUint16(1, payloadLength);
|
|
3602
|
+
}
|
|
3603
|
+
else {
|
|
3604
|
+
header = new Uint8Array(9);
|
|
3605
|
+
const view = new DataView(header.buffer);
|
|
3606
|
+
view.setUint8(0, 127);
|
|
3607
|
+
view.setBigUint64(1, BigInt(payloadLength));
|
|
3608
|
+
}
|
|
3609
|
+
// first bit indicates whether the payload is plain text (0) or binary (1)
|
|
3610
|
+
if (packet.data && typeof packet.data !== "string") {
|
|
3611
|
+
header[0] |= 0x80;
|
|
3612
|
+
}
|
|
3613
|
+
controller.enqueue(header);
|
|
3614
|
+
controller.enqueue(encodedPacket);
|
|
3615
|
+
});
|
|
3616
|
+
},
|
|
3617
|
+
});
|
|
3618
|
+
}
|
|
3619
|
+
let TEXT_DECODER;
|
|
3620
|
+
function totalLength(chunks) {
|
|
3621
|
+
return chunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
3622
|
+
}
|
|
3623
|
+
function concatChunks(chunks, size) {
|
|
3624
|
+
if (chunks[0].length === size) {
|
|
3625
|
+
return chunks.shift();
|
|
3626
|
+
}
|
|
3627
|
+
const buffer = new Uint8Array(size);
|
|
3628
|
+
let j = 0;
|
|
3629
|
+
for (let i = 0; i < size; i++) {
|
|
3630
|
+
buffer[i] = chunks[0][j++];
|
|
3631
|
+
if (j === chunks[0].length) {
|
|
3632
|
+
chunks.shift();
|
|
3633
|
+
j = 0;
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
if (chunks.length && j < chunks[0].length) {
|
|
3637
|
+
chunks[0] = chunks[0].slice(j);
|
|
3638
|
+
}
|
|
3639
|
+
return buffer;
|
|
3640
|
+
}
|
|
3641
|
+
function createPacketDecoderStream(maxPayload, binaryType) {
|
|
3642
|
+
if (!TEXT_DECODER) {
|
|
3643
|
+
TEXT_DECODER = new TextDecoder();
|
|
3644
|
+
}
|
|
3645
|
+
const chunks = [];
|
|
3646
|
+
let state = 0 /* READ_HEADER */;
|
|
3647
|
+
let expectedLength = -1;
|
|
3648
|
+
let isBinary = false;
|
|
3649
|
+
// @ts-expect-error
|
|
3650
|
+
return new TransformStream({
|
|
3651
|
+
transform(chunk, controller) {
|
|
3652
|
+
chunks.push(chunk);
|
|
3653
|
+
while (true) {
|
|
3654
|
+
if (state === 0 /* READ_HEADER */) {
|
|
3655
|
+
if (totalLength(chunks) < 1) {
|
|
3656
|
+
break;
|
|
3657
|
+
}
|
|
3658
|
+
const header = concatChunks(chunks, 1);
|
|
3659
|
+
isBinary = (header[0] & 0x80) === 0x80;
|
|
3660
|
+
expectedLength = header[0] & 0x7f;
|
|
3661
|
+
if (expectedLength < 126) {
|
|
3662
|
+
state = 3 /* READ_PAYLOAD */;
|
|
3663
|
+
}
|
|
3664
|
+
else if (expectedLength === 126) {
|
|
3665
|
+
state = 1 /* READ_EXTENDED_LENGTH_16 */;
|
|
3666
|
+
}
|
|
3667
|
+
else {
|
|
3668
|
+
state = 2 /* READ_EXTENDED_LENGTH_64 */;
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
else if (state === 1 /* READ_EXTENDED_LENGTH_16 */) {
|
|
3672
|
+
if (totalLength(chunks) < 2) {
|
|
3673
|
+
break;
|
|
3674
|
+
}
|
|
3675
|
+
const headerArray = concatChunks(chunks, 2);
|
|
3676
|
+
expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0);
|
|
3677
|
+
state = 3 /* READ_PAYLOAD */;
|
|
3678
|
+
}
|
|
3679
|
+
else if (state === 2 /* READ_EXTENDED_LENGTH_64 */) {
|
|
3680
|
+
if (totalLength(chunks) < 8) {
|
|
3681
|
+
break;
|
|
3682
|
+
}
|
|
3683
|
+
const headerArray = concatChunks(chunks, 8);
|
|
3684
|
+
const view = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length);
|
|
3685
|
+
const n = view.getUint32(0);
|
|
3686
|
+
if (n > Math.pow(2, 53 - 32) - 1) {
|
|
3687
|
+
// the maximum safe integer in JavaScript is 2^53 - 1
|
|
3688
|
+
controller.enqueue(ERROR_PACKET);
|
|
3689
|
+
break;
|
|
3690
|
+
}
|
|
3691
|
+
expectedLength = n * Math.pow(2, 32) + view.getUint32(4);
|
|
3692
|
+
state = 3 /* READ_PAYLOAD */;
|
|
3693
|
+
}
|
|
3694
|
+
else {
|
|
3695
|
+
if (totalLength(chunks) < expectedLength) {
|
|
3696
|
+
break;
|
|
3697
|
+
}
|
|
3698
|
+
const data = concatChunks(chunks, expectedLength);
|
|
3699
|
+
controller.enqueue(decodePacket(isBinary ? data : TEXT_DECODER.decode(data), binaryType));
|
|
3700
|
+
state = 0 /* READ_HEADER */;
|
|
3701
|
+
}
|
|
3702
|
+
if (expectedLength === 0 || expectedLength > maxPayload) {
|
|
3703
|
+
controller.enqueue(ERROR_PACKET);
|
|
3704
|
+
break;
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
},
|
|
3708
|
+
});
|
|
3709
|
+
}
|
|
3518
3710
|
const protocol$1 = 4;
|
|
3519
3711
|
|
|
3520
3712
|
/**
|
|
@@ -3714,16 +3906,16 @@ function pick(obj, ...attr) {
|
|
|
3714
3906
|
}, {});
|
|
3715
3907
|
}
|
|
3716
3908
|
// Keep a reference to the real timeout functions so they can be used when overridden
|
|
3717
|
-
const NATIVE_SET_TIMEOUT = setTimeout;
|
|
3718
|
-
const NATIVE_CLEAR_TIMEOUT = clearTimeout;
|
|
3909
|
+
const NATIVE_SET_TIMEOUT = globalThisShim.setTimeout;
|
|
3910
|
+
const NATIVE_CLEAR_TIMEOUT = globalThisShim.clearTimeout;
|
|
3719
3911
|
function installTimerFunctions(obj, opts) {
|
|
3720
3912
|
if (opts.useNativeTimers) {
|
|
3721
3913
|
obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThisShim);
|
|
3722
3914
|
obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThisShim);
|
|
3723
3915
|
}
|
|
3724
3916
|
else {
|
|
3725
|
-
obj.setTimeoutFn = setTimeout.bind(globalThisShim);
|
|
3726
|
-
obj.clearTimeoutFn = clearTimeout.bind(globalThisShim);
|
|
3917
|
+
obj.setTimeoutFn = globalThisShim.setTimeout.bind(globalThisShim);
|
|
3918
|
+
obj.clearTimeoutFn = globalThisShim.clearTimeout.bind(globalThisShim);
|
|
3727
3919
|
}
|
|
3728
3920
|
}
|
|
3729
3921
|
// base64 encoded buffers are about 33% bigger (https://en.wikipedia.org/wiki/Base64)
|
|
@@ -3757,6 +3949,41 @@ function utf8Length(str) {
|
|
|
3757
3949
|
return length;
|
|
3758
3950
|
}
|
|
3759
3951
|
|
|
3952
|
+
// imported from https://github.com/galkn/querystring
|
|
3953
|
+
/**
|
|
3954
|
+
* Compiles a querystring
|
|
3955
|
+
* Returns string representation of the object
|
|
3956
|
+
*
|
|
3957
|
+
* @param {Object}
|
|
3958
|
+
* @api private
|
|
3959
|
+
*/
|
|
3960
|
+
function encode$1(obj) {
|
|
3961
|
+
let str = '';
|
|
3962
|
+
for (let i in obj) {
|
|
3963
|
+
if (obj.hasOwnProperty(i)) {
|
|
3964
|
+
if (str.length)
|
|
3965
|
+
str += '&';
|
|
3966
|
+
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
return str;
|
|
3970
|
+
}
|
|
3971
|
+
/**
|
|
3972
|
+
* Parses a simple querystring into an object
|
|
3973
|
+
*
|
|
3974
|
+
* @param {String} qs
|
|
3975
|
+
* @api private
|
|
3976
|
+
*/
|
|
3977
|
+
function decode(qs) {
|
|
3978
|
+
let qry = {};
|
|
3979
|
+
let pairs = qs.split('&');
|
|
3980
|
+
for (let i = 0, l = pairs.length; i < l; i++) {
|
|
3981
|
+
let pair = pairs[i].split('=');
|
|
3982
|
+
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
|
|
3983
|
+
}
|
|
3984
|
+
return qry;
|
|
3985
|
+
}
|
|
3986
|
+
|
|
3760
3987
|
class TransportError extends Error {
|
|
3761
3988
|
constructor(reason, description, context) {
|
|
3762
3989
|
super(reason);
|
|
@@ -3769,8 +3996,8 @@ class Transport extends Emitter_1 {
|
|
|
3769
3996
|
/**
|
|
3770
3997
|
* Transport abstract constructor.
|
|
3771
3998
|
*
|
|
3772
|
-
* @param {Object} options
|
|
3773
|
-
* @
|
|
3999
|
+
* @param {Object} opts - options
|
|
4000
|
+
* @protected
|
|
3774
4001
|
*/
|
|
3775
4002
|
constructor(opts) {
|
|
3776
4003
|
super();
|
|
@@ -3778,7 +4005,6 @@ class Transport extends Emitter_1 {
|
|
|
3778
4005
|
installTimerFunctions(this, opts);
|
|
3779
4006
|
this.opts = opts;
|
|
3780
4007
|
this.query = opts.query;
|
|
3781
|
-
this.readyState = "";
|
|
3782
4008
|
this.socket = opts.socket;
|
|
3783
4009
|
}
|
|
3784
4010
|
/**
|
|
@@ -3788,7 +4014,7 @@ class Transport extends Emitter_1 {
|
|
|
3788
4014
|
* @param description
|
|
3789
4015
|
* @param context - the error context
|
|
3790
4016
|
* @return {Transport} for chaining
|
|
3791
|
-
* @
|
|
4017
|
+
* @protected
|
|
3792
4018
|
*/
|
|
3793
4019
|
onError(reason, description, context) {
|
|
3794
4020
|
super.emitReserved("error", new TransportError(reason, description, context));
|
|
@@ -3796,23 +4022,17 @@ class Transport extends Emitter_1 {
|
|
|
3796
4022
|
}
|
|
3797
4023
|
/**
|
|
3798
4024
|
* Opens the transport.
|
|
3799
|
-
*
|
|
3800
|
-
* @api public
|
|
3801
4025
|
*/
|
|
3802
4026
|
open() {
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
this.doOpen();
|
|
3806
|
-
}
|
|
4027
|
+
this.readyState = "opening";
|
|
4028
|
+
this.doOpen();
|
|
3807
4029
|
return this;
|
|
3808
4030
|
}
|
|
3809
4031
|
/**
|
|
3810
4032
|
* Closes the transport.
|
|
3811
|
-
*
|
|
3812
|
-
* @api public
|
|
3813
4033
|
*/
|
|
3814
4034
|
close() {
|
|
3815
|
-
if ("opening"
|
|
4035
|
+
if (this.readyState === "opening" || this.readyState === "open") {
|
|
3816
4036
|
this.doClose();
|
|
3817
4037
|
this.onClose();
|
|
3818
4038
|
}
|
|
@@ -3822,17 +4042,16 @@ class Transport extends Emitter_1 {
|
|
|
3822
4042
|
* Sends multiple packets.
|
|
3823
4043
|
*
|
|
3824
4044
|
* @param {Array} packets
|
|
3825
|
-
* @api public
|
|
3826
4045
|
*/
|
|
3827
4046
|
send(packets) {
|
|
3828
|
-
if ("open"
|
|
4047
|
+
if (this.readyState === "open") {
|
|
3829
4048
|
this.write(packets);
|
|
3830
4049
|
}
|
|
3831
4050
|
}
|
|
3832
4051
|
/**
|
|
3833
4052
|
* Called upon open
|
|
3834
4053
|
*
|
|
3835
|
-
* @
|
|
4054
|
+
* @protected
|
|
3836
4055
|
*/
|
|
3837
4056
|
onOpen() {
|
|
3838
4057
|
this.readyState = "open";
|
|
@@ -3843,7 +4062,7 @@ class Transport extends Emitter_1 {
|
|
|
3843
4062
|
* Called with data.
|
|
3844
4063
|
*
|
|
3845
4064
|
* @param {String} data
|
|
3846
|
-
* @
|
|
4065
|
+
* @protected
|
|
3847
4066
|
*/
|
|
3848
4067
|
onData(data) {
|
|
3849
4068
|
const packet = decodePacket(data, this.socket.binaryType);
|
|
@@ -3852,7 +4071,7 @@ class Transport extends Emitter_1 {
|
|
|
3852
4071
|
/**
|
|
3853
4072
|
* Called with a decoded packet.
|
|
3854
4073
|
*
|
|
3855
|
-
* @
|
|
4074
|
+
* @protected
|
|
3856
4075
|
*/
|
|
3857
4076
|
onPacket(packet) {
|
|
3858
4077
|
super.emitReserved("packet", packet);
|
|
@@ -3860,12 +4079,44 @@ class Transport extends Emitter_1 {
|
|
|
3860
4079
|
/**
|
|
3861
4080
|
* Called upon close.
|
|
3862
4081
|
*
|
|
3863
|
-
* @
|
|
4082
|
+
* @protected
|
|
3864
4083
|
*/
|
|
3865
4084
|
onClose(details) {
|
|
3866
4085
|
this.readyState = "closed";
|
|
3867
4086
|
super.emitReserved("close", details);
|
|
3868
4087
|
}
|
|
4088
|
+
/**
|
|
4089
|
+
* Pauses the transport, in order not to lose packets during an upgrade.
|
|
4090
|
+
*
|
|
4091
|
+
* @param onPause
|
|
4092
|
+
*/
|
|
4093
|
+
pause(onPause) { }
|
|
4094
|
+
createUri(schema, query = {}) {
|
|
4095
|
+
return (schema +
|
|
4096
|
+
"://" +
|
|
4097
|
+
this._hostname() +
|
|
4098
|
+
this._port() +
|
|
4099
|
+
this.opts.path +
|
|
4100
|
+
this._query(query));
|
|
4101
|
+
}
|
|
4102
|
+
_hostname() {
|
|
4103
|
+
const hostname = this.opts.hostname;
|
|
4104
|
+
return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]";
|
|
4105
|
+
}
|
|
4106
|
+
_port() {
|
|
4107
|
+
if (this.opts.port &&
|
|
4108
|
+
((this.opts.secure && Number(this.opts.port !== 443)) ||
|
|
4109
|
+
(!this.opts.secure && Number(this.opts.port) !== 80))) {
|
|
4110
|
+
return ":" + this.opts.port;
|
|
4111
|
+
}
|
|
4112
|
+
else {
|
|
4113
|
+
return "";
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
_query(query) {
|
|
4117
|
+
const encodedQuery = encode$1(query);
|
|
4118
|
+
return encodedQuery.length ? "?" + encodedQuery : "";
|
|
4119
|
+
}
|
|
3869
4120
|
}
|
|
3870
4121
|
|
|
3871
4122
|
// imported from https://github.com/unshiftio/yeast
|
|
@@ -3878,7 +4129,7 @@ let seed = 0, i = 0, prev;
|
|
|
3878
4129
|
* @returns {String} The string representation of the number.
|
|
3879
4130
|
* @api public
|
|
3880
4131
|
*/
|
|
3881
|
-
function encode
|
|
4132
|
+
function encode(num) {
|
|
3882
4133
|
let encoded = '';
|
|
3883
4134
|
do {
|
|
3884
4135
|
encoded = alphabet[num % length] + encoded;
|
|
@@ -3893,10 +4144,10 @@ function encode$1(num) {
|
|
|
3893
4144
|
* @api public
|
|
3894
4145
|
*/
|
|
3895
4146
|
function yeast() {
|
|
3896
|
-
const now = encode
|
|
4147
|
+
const now = encode(+new Date());
|
|
3897
4148
|
if (now !== prev)
|
|
3898
4149
|
return seed = 0, prev = now;
|
|
3899
|
-
return now + '.' + encode
|
|
4150
|
+
return now + '.' + encode(seed++);
|
|
3900
4151
|
}
|
|
3901
4152
|
//
|
|
3902
4153
|
// Map each character to its index.
|
|
@@ -3904,41 +4155,6 @@ function yeast() {
|
|
|
3904
4155
|
for (; i < length; i++)
|
|
3905
4156
|
map[alphabet[i]] = i;
|
|
3906
4157
|
|
|
3907
|
-
// imported from https://github.com/galkn/querystring
|
|
3908
|
-
/**
|
|
3909
|
-
* Compiles a querystring
|
|
3910
|
-
* Returns string representation of the object
|
|
3911
|
-
*
|
|
3912
|
-
* @param {Object}
|
|
3913
|
-
* @api private
|
|
3914
|
-
*/
|
|
3915
|
-
function encode(obj) {
|
|
3916
|
-
let str = '';
|
|
3917
|
-
for (let i in obj) {
|
|
3918
|
-
if (obj.hasOwnProperty(i)) {
|
|
3919
|
-
if (str.length)
|
|
3920
|
-
str += '&';
|
|
3921
|
-
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
|
|
3922
|
-
}
|
|
3923
|
-
}
|
|
3924
|
-
return str;
|
|
3925
|
-
}
|
|
3926
|
-
/**
|
|
3927
|
-
* Parses a simple querystring into an object
|
|
3928
|
-
*
|
|
3929
|
-
* @param {String} qs
|
|
3930
|
-
* @api private
|
|
3931
|
-
*/
|
|
3932
|
-
function decode(qs) {
|
|
3933
|
-
let qry = {};
|
|
3934
|
-
let pairs = qs.split('&');
|
|
3935
|
-
for (let i = 0, l = pairs.length; i < l; i++) {
|
|
3936
|
-
let pair = pairs[i].split('=');
|
|
3937
|
-
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
|
|
3938
|
-
}
|
|
3939
|
-
return qry;
|
|
3940
|
-
}
|
|
3941
|
-
|
|
3942
4158
|
// imported from https://github.com/component/has-cors
|
|
3943
4159
|
let value = false;
|
|
3944
4160
|
try {
|
|
@@ -3968,11 +4184,12 @@ function XHR(opts) {
|
|
|
3968
4184
|
catch (e) { }
|
|
3969
4185
|
}
|
|
3970
4186
|
}
|
|
4187
|
+
function createCookieJar() { }
|
|
3971
4188
|
|
|
3972
4189
|
function empty$2() { }
|
|
3973
4190
|
const hasXHR2 = (function () {
|
|
3974
4191
|
const xhr = new XHR({
|
|
3975
|
-
xdomain: false
|
|
4192
|
+
xdomain: false,
|
|
3976
4193
|
});
|
|
3977
4194
|
return null != xhr.responseType;
|
|
3978
4195
|
})();
|
|
@@ -3981,7 +4198,7 @@ class Polling extends Transport {
|
|
|
3981
4198
|
* XHR Polling constructor.
|
|
3982
4199
|
*
|
|
3983
4200
|
* @param {Object} opts
|
|
3984
|
-
* @
|
|
4201
|
+
* @package
|
|
3985
4202
|
*/
|
|
3986
4203
|
constructor(opts) {
|
|
3987
4204
|
super(opts);
|
|
@@ -3997,17 +4214,16 @@ class Polling extends Transport {
|
|
|
3997
4214
|
(typeof location !== "undefined" &&
|
|
3998
4215
|
opts.hostname !== location.hostname) ||
|
|
3999
4216
|
port !== opts.port;
|
|
4000
|
-
this.xs = opts.secure !== isSSL;
|
|
4001
4217
|
}
|
|
4002
4218
|
/**
|
|
4003
4219
|
* XHR supports binary
|
|
4004
4220
|
*/
|
|
4005
4221
|
const forceBase64 = opts && opts.forceBase64;
|
|
4006
4222
|
this.supportsBinary = hasXHR2 && !forceBase64;
|
|
4223
|
+
if (this.opts.withCredentials) {
|
|
4224
|
+
this.cookieJar = createCookieJar();
|
|
4225
|
+
}
|
|
4007
4226
|
}
|
|
4008
|
-
/**
|
|
4009
|
-
* Transport name.
|
|
4010
|
-
*/
|
|
4011
4227
|
get name() {
|
|
4012
4228
|
return "polling";
|
|
4013
4229
|
}
|
|
@@ -4015,7 +4231,7 @@ class Polling extends Transport {
|
|
|
4015
4231
|
* Opens the socket (triggers polling). We write a PING message to determine
|
|
4016
4232
|
* when the transport is open.
|
|
4017
4233
|
*
|
|
4018
|
-
* @
|
|
4234
|
+
* @protected
|
|
4019
4235
|
*/
|
|
4020
4236
|
doOpen() {
|
|
4021
4237
|
this.poll();
|
|
@@ -4023,8 +4239,8 @@ class Polling extends Transport {
|
|
|
4023
4239
|
/**
|
|
4024
4240
|
* Pauses polling.
|
|
4025
4241
|
*
|
|
4026
|
-
* @param {Function} callback upon buffers are flushed and transport is paused
|
|
4027
|
-
* @
|
|
4242
|
+
* @param {Function} onPause - callback upon buffers are flushed and transport is paused
|
|
4243
|
+
* @package
|
|
4028
4244
|
*/
|
|
4029
4245
|
pause(onPause) {
|
|
4030
4246
|
this.readyState = "pausing";
|
|
@@ -4054,7 +4270,7 @@ class Polling extends Transport {
|
|
|
4054
4270
|
/**
|
|
4055
4271
|
* Starts polling cycle.
|
|
4056
4272
|
*
|
|
4057
|
-
* @
|
|
4273
|
+
* @private
|
|
4058
4274
|
*/
|
|
4059
4275
|
poll() {
|
|
4060
4276
|
this.polling = true;
|
|
@@ -4064,10 +4280,10 @@ class Polling extends Transport {
|
|
|
4064
4280
|
/**
|
|
4065
4281
|
* Overloads onData to detect payloads.
|
|
4066
4282
|
*
|
|
4067
|
-
* @
|
|
4283
|
+
* @protected
|
|
4068
4284
|
*/
|
|
4069
4285
|
onData(data) {
|
|
4070
|
-
const callback = packet => {
|
|
4286
|
+
const callback = (packet) => {
|
|
4071
4287
|
// if its the first message we consider the transport open
|
|
4072
4288
|
if ("opening" === this.readyState && packet.type === "open") {
|
|
4073
4289
|
this.onOpen();
|
|
@@ -4095,7 +4311,7 @@ class Polling extends Transport {
|
|
|
4095
4311
|
/**
|
|
4096
4312
|
* For polling, send a close packet.
|
|
4097
4313
|
*
|
|
4098
|
-
* @
|
|
4314
|
+
* @protected
|
|
4099
4315
|
*/
|
|
4100
4316
|
doClose() {
|
|
4101
4317
|
const close = () => {
|
|
@@ -4113,13 +4329,12 @@ class Polling extends Transport {
|
|
|
4113
4329
|
/**
|
|
4114
4330
|
* Writes a packets payload.
|
|
4115
4331
|
*
|
|
4116
|
-
* @param {Array} data packets
|
|
4117
|
-
* @
|
|
4118
|
-
* @api private
|
|
4332
|
+
* @param {Array} packets - data packets
|
|
4333
|
+
* @protected
|
|
4119
4334
|
*/
|
|
4120
4335
|
write(packets) {
|
|
4121
4336
|
this.writable = false;
|
|
4122
|
-
encodePayload(packets, data => {
|
|
4337
|
+
encodePayload(packets, (data) => {
|
|
4123
4338
|
this.doWrite(data, () => {
|
|
4124
4339
|
this.writable = true;
|
|
4125
4340
|
this.emitReserved("drain");
|
|
@@ -4129,12 +4344,11 @@ class Polling extends Transport {
|
|
|
4129
4344
|
/**
|
|
4130
4345
|
* Generates uri for connection.
|
|
4131
4346
|
*
|
|
4132
|
-
* @
|
|
4347
|
+
* @private
|
|
4133
4348
|
*/
|
|
4134
4349
|
uri() {
|
|
4135
|
-
let query = this.query || {};
|
|
4136
4350
|
const schema = this.opts.secure ? "https" : "http";
|
|
4137
|
-
|
|
4351
|
+
const query = this.query || {};
|
|
4138
4352
|
// cache busting is forced
|
|
4139
4353
|
if (false !== this.opts.timestampRequests) {
|
|
4140
4354
|
query[this.opts.timestampParam] = yeast();
|
|
@@ -4142,29 +4356,16 @@ class Polling extends Transport {
|
|
|
4142
4356
|
if (!this.supportsBinary && !query.sid) {
|
|
4143
4357
|
query.b64 = 1;
|
|
4144
4358
|
}
|
|
4145
|
-
|
|
4146
|
-
if (this.opts.port &&
|
|
4147
|
-
(("https" === schema && Number(this.opts.port) !== 443) ||
|
|
4148
|
-
("http" === schema && Number(this.opts.port) !== 80))) {
|
|
4149
|
-
port = ":" + this.opts.port;
|
|
4150
|
-
}
|
|
4151
|
-
const encodedQuery = encode(query);
|
|
4152
|
-
const ipv6 = this.opts.hostname.indexOf(":") !== -1;
|
|
4153
|
-
return (schema +
|
|
4154
|
-
"://" +
|
|
4155
|
-
(ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) +
|
|
4156
|
-
port +
|
|
4157
|
-
this.opts.path +
|
|
4158
|
-
(encodedQuery.length ? "?" + encodedQuery : ""));
|
|
4359
|
+
return this.createUri(schema, query);
|
|
4159
4360
|
}
|
|
4160
4361
|
/**
|
|
4161
4362
|
* Creates a request.
|
|
4162
4363
|
*
|
|
4163
4364
|
* @param {String} method
|
|
4164
|
-
* @
|
|
4365
|
+
* @private
|
|
4165
4366
|
*/
|
|
4166
4367
|
request(opts = {}) {
|
|
4167
|
-
Object.assign(opts, { xd: this.xd,
|
|
4368
|
+
Object.assign(opts, { xd: this.xd, cookieJar: this.cookieJar }, this.opts);
|
|
4168
4369
|
return new Request(this.uri(), opts);
|
|
4169
4370
|
}
|
|
4170
4371
|
/**
|
|
@@ -4172,12 +4373,12 @@ class Polling extends Transport {
|
|
|
4172
4373
|
*
|
|
4173
4374
|
* @param {String} data to send.
|
|
4174
4375
|
* @param {Function} called upon flush.
|
|
4175
|
-
* @
|
|
4376
|
+
* @private
|
|
4176
4377
|
*/
|
|
4177
4378
|
doWrite(data, fn) {
|
|
4178
4379
|
const req = this.request({
|
|
4179
4380
|
method: "POST",
|
|
4180
|
-
data: data
|
|
4381
|
+
data: data,
|
|
4181
4382
|
});
|
|
4182
4383
|
req.on("success", fn);
|
|
4183
4384
|
req.on("error", (xhrStatus, context) => {
|
|
@@ -4187,7 +4388,7 @@ class Polling extends Transport {
|
|
|
4187
4388
|
/**
|
|
4188
4389
|
* Starts a poll cycle.
|
|
4189
4390
|
*
|
|
4190
|
-
* @
|
|
4391
|
+
* @private
|
|
4191
4392
|
*/
|
|
4192
4393
|
doPoll() {
|
|
4193
4394
|
const req = this.request();
|
|
@@ -4203,7 +4404,7 @@ class Request extends Emitter_1 {
|
|
|
4203
4404
|
* Request constructor
|
|
4204
4405
|
*
|
|
4205
4406
|
* @param {Object} options
|
|
4206
|
-
* @
|
|
4407
|
+
* @package
|
|
4207
4408
|
*/
|
|
4208
4409
|
constructor(uri, opts) {
|
|
4209
4410
|
super();
|
|
@@ -4211,22 +4412,21 @@ class Request extends Emitter_1 {
|
|
|
4211
4412
|
this.opts = opts;
|
|
4212
4413
|
this.method = opts.method || "GET";
|
|
4213
4414
|
this.uri = uri;
|
|
4214
|
-
this.async = false !== opts.async;
|
|
4215
4415
|
this.data = undefined !== opts.data ? opts.data : null;
|
|
4216
4416
|
this.create();
|
|
4217
4417
|
}
|
|
4218
4418
|
/**
|
|
4219
4419
|
* Creates the XHR object and sends the request.
|
|
4220
4420
|
*
|
|
4221
|
-
* @
|
|
4421
|
+
* @private
|
|
4222
4422
|
*/
|
|
4223
4423
|
create() {
|
|
4424
|
+
var _a;
|
|
4224
4425
|
const opts = pick(this.opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref");
|
|
4225
4426
|
opts.xdomain = !!this.opts.xd;
|
|
4226
|
-
opts.xscheme = !!this.opts.xs;
|
|
4227
4427
|
const xhr = (this.xhr = new XHR(opts));
|
|
4228
4428
|
try {
|
|
4229
|
-
xhr.open(this.method, this.uri,
|
|
4429
|
+
xhr.open(this.method, this.uri, true);
|
|
4230
4430
|
try {
|
|
4231
4431
|
if (this.opts.extraHeaders) {
|
|
4232
4432
|
xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true);
|
|
@@ -4248,6 +4448,7 @@ class Request extends Emitter_1 {
|
|
|
4248
4448
|
xhr.setRequestHeader("Accept", "*/*");
|
|
4249
4449
|
}
|
|
4250
4450
|
catch (e) { }
|
|
4451
|
+
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr);
|
|
4251
4452
|
// ie6 check
|
|
4252
4453
|
if ("withCredentials" in xhr) {
|
|
4253
4454
|
xhr.withCredentials = this.opts.withCredentials;
|
|
@@ -4256,6 +4457,10 @@ class Request extends Emitter_1 {
|
|
|
4256
4457
|
xhr.timeout = this.opts.requestTimeout;
|
|
4257
4458
|
}
|
|
4258
4459
|
xhr.onreadystatechange = () => {
|
|
4460
|
+
var _a;
|
|
4461
|
+
if (xhr.readyState === 3) {
|
|
4462
|
+
(_a = this.opts.cookieJar) === null || _a === void 0 ? void 0 : _a.parseCookies(xhr);
|
|
4463
|
+
}
|
|
4259
4464
|
if (4 !== xhr.readyState)
|
|
4260
4465
|
return;
|
|
4261
4466
|
if (200 === xhr.status || 1223 === xhr.status) {
|
|
@@ -4288,7 +4493,7 @@ class Request extends Emitter_1 {
|
|
|
4288
4493
|
/**
|
|
4289
4494
|
* Called upon error.
|
|
4290
4495
|
*
|
|
4291
|
-
* @
|
|
4496
|
+
* @private
|
|
4292
4497
|
*/
|
|
4293
4498
|
onError(err) {
|
|
4294
4499
|
this.emitReserved("error", err, this.xhr);
|
|
@@ -4297,7 +4502,7 @@ class Request extends Emitter_1 {
|
|
|
4297
4502
|
/**
|
|
4298
4503
|
* Cleans up house.
|
|
4299
4504
|
*
|
|
4300
|
-
* @
|
|
4505
|
+
* @private
|
|
4301
4506
|
*/
|
|
4302
4507
|
cleanup(fromError) {
|
|
4303
4508
|
if ("undefined" === typeof this.xhr || null === this.xhr) {
|
|
@@ -4318,7 +4523,7 @@ class Request extends Emitter_1 {
|
|
|
4318
4523
|
/**
|
|
4319
4524
|
* Called upon load.
|
|
4320
4525
|
*
|
|
4321
|
-
* @
|
|
4526
|
+
* @private
|
|
4322
4527
|
*/
|
|
4323
4528
|
onLoad() {
|
|
4324
4529
|
const data = this.xhr.responseText;
|
|
@@ -4331,7 +4536,7 @@ class Request extends Emitter_1 {
|
|
|
4331
4536
|
/**
|
|
4332
4537
|
* Aborts the request.
|
|
4333
4538
|
*
|
|
4334
|
-
* @
|
|
4539
|
+
* @package
|
|
4335
4540
|
*/
|
|
4336
4541
|
abort() {
|
|
4337
4542
|
this.cleanup();
|
|
@@ -4366,7 +4571,7 @@ function unloadHandler() {
|
|
|
4366
4571
|
const nextTick = (() => {
|
|
4367
4572
|
const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function";
|
|
4368
4573
|
if (isPromiseAvailable) {
|
|
4369
|
-
return cb => Promise.resolve().then(cb);
|
|
4574
|
+
return (cb) => Promise.resolve().then(cb);
|
|
4370
4575
|
}
|
|
4371
4576
|
else {
|
|
4372
4577
|
return (cb, setTimeoutFn) => setTimeoutFn(cb, 0);
|
|
@@ -4384,26 +4589,16 @@ class WS extends Transport {
|
|
|
4384
4589
|
/**
|
|
4385
4590
|
* WebSocket transport constructor.
|
|
4386
4591
|
*
|
|
4387
|
-
* @
|
|
4388
|
-
* @
|
|
4592
|
+
* @param {Object} opts - connection options
|
|
4593
|
+
* @protected
|
|
4389
4594
|
*/
|
|
4390
4595
|
constructor(opts) {
|
|
4391
4596
|
super(opts);
|
|
4392
4597
|
this.supportsBinary = !opts.forceBase64;
|
|
4393
4598
|
}
|
|
4394
|
-
/**
|
|
4395
|
-
* Transport name.
|
|
4396
|
-
*
|
|
4397
|
-
* @api public
|
|
4398
|
-
*/
|
|
4399
4599
|
get name() {
|
|
4400
4600
|
return "websocket";
|
|
4401
4601
|
}
|
|
4402
|
-
/**
|
|
4403
|
-
* Opens socket.
|
|
4404
|
-
*
|
|
4405
|
-
* @api private
|
|
4406
|
-
*/
|
|
4407
4602
|
doOpen() {
|
|
4408
4603
|
if (!this.check()) {
|
|
4409
4604
|
// let probe timeout
|
|
@@ -4429,13 +4624,13 @@ class WS extends Transport {
|
|
|
4429
4624
|
catch (err) {
|
|
4430
4625
|
return this.emitReserved("error", err);
|
|
4431
4626
|
}
|
|
4432
|
-
this.ws.binaryType = this.socket.binaryType
|
|
4627
|
+
this.ws.binaryType = this.socket.binaryType;
|
|
4433
4628
|
this.addEventListeners();
|
|
4434
4629
|
}
|
|
4435
4630
|
/**
|
|
4436
4631
|
* Adds event listeners to the socket
|
|
4437
4632
|
*
|
|
4438
|
-
* @
|
|
4633
|
+
* @private
|
|
4439
4634
|
*/
|
|
4440
4635
|
addEventListeners() {
|
|
4441
4636
|
this.ws.onopen = () => {
|
|
@@ -4444,19 +4639,13 @@ class WS extends Transport {
|
|
|
4444
4639
|
}
|
|
4445
4640
|
this.onOpen();
|
|
4446
4641
|
};
|
|
4447
|
-
this.ws.onclose = closeEvent => this.onClose({
|
|
4642
|
+
this.ws.onclose = (closeEvent) => this.onClose({
|
|
4448
4643
|
description: "websocket connection closed",
|
|
4449
|
-
context: closeEvent
|
|
4644
|
+
context: closeEvent,
|
|
4450
4645
|
});
|
|
4451
|
-
this.ws.onmessage = ev => this.onData(ev.data);
|
|
4452
|
-
this.ws.onerror = e => this.onError("websocket error", e);
|
|
4646
|
+
this.ws.onmessage = (ev) => this.onData(ev.data);
|
|
4647
|
+
this.ws.onerror = (e) => this.onError("websocket error", e);
|
|
4453
4648
|
}
|
|
4454
|
-
/**
|
|
4455
|
-
* Writes data to socket.
|
|
4456
|
-
*
|
|
4457
|
-
* @param {Array} array of packets.
|
|
4458
|
-
* @api private
|
|
4459
|
-
*/
|
|
4460
4649
|
write(packets) {
|
|
4461
4650
|
this.writable = false;
|
|
4462
4651
|
// encodePacket efficient as it uses WS framing
|
|
@@ -4464,7 +4653,7 @@ class WS extends Transport {
|
|
|
4464
4653
|
for (let i = 0; i < packets.length; i++) {
|
|
4465
4654
|
const packet = packets[i];
|
|
4466
4655
|
const lastPacket = i === packets.length - 1;
|
|
4467
|
-
encodePacket(packet, this.supportsBinary, data => {
|
|
4656
|
+
encodePacket(packet, this.supportsBinary, (data) => {
|
|
4468
4657
|
// always create a new object (GH-437)
|
|
4469
4658
|
const opts = {};
|
|
4470
4659
|
// Sometimes the websocket has already been closed but the browser didn't
|
|
@@ -4489,11 +4678,6 @@ class WS extends Transport {
|
|
|
4489
4678
|
});
|
|
4490
4679
|
}
|
|
4491
4680
|
}
|
|
4492
|
-
/**
|
|
4493
|
-
* Closes socket.
|
|
4494
|
-
*
|
|
4495
|
-
* @api private
|
|
4496
|
-
*/
|
|
4497
4681
|
doClose() {
|
|
4498
4682
|
if (typeof this.ws !== "undefined") {
|
|
4499
4683
|
this.ws.close();
|
|
@@ -4503,18 +4687,11 @@ class WS extends Transport {
|
|
|
4503
4687
|
/**
|
|
4504
4688
|
* Generates uri for connection.
|
|
4505
4689
|
*
|
|
4506
|
-
* @
|
|
4690
|
+
* @private
|
|
4507
4691
|
*/
|
|
4508
4692
|
uri() {
|
|
4509
|
-
let query = this.query || {};
|
|
4510
4693
|
const schema = this.opts.secure ? "wss" : "ws";
|
|
4511
|
-
|
|
4512
|
-
// avoid port if default for schema
|
|
4513
|
-
if (this.opts.port &&
|
|
4514
|
-
(("wss" === schema && Number(this.opts.port) !== 443) ||
|
|
4515
|
-
("ws" === schema && Number(this.opts.port) !== 80))) {
|
|
4516
|
-
port = ":" + this.opts.port;
|
|
4517
|
-
}
|
|
4694
|
+
const query = this.query || {};
|
|
4518
4695
|
// append timestamp to URI
|
|
4519
4696
|
if (this.opts.timestampRequests) {
|
|
4520
4697
|
query[this.opts.timestampParam] = yeast();
|
|
@@ -4523,43 +4700,121 @@ class WS extends Transport {
|
|
|
4523
4700
|
if (!this.supportsBinary) {
|
|
4524
4701
|
query.b64 = 1;
|
|
4525
4702
|
}
|
|
4526
|
-
|
|
4527
|
-
const ipv6 = this.opts.hostname.indexOf(":") !== -1;
|
|
4528
|
-
return (schema +
|
|
4529
|
-
"://" +
|
|
4530
|
-
(ipv6 ? "[" + this.opts.hostname + "]" : this.opts.hostname) +
|
|
4531
|
-
port +
|
|
4532
|
-
this.opts.path +
|
|
4533
|
-
(encodedQuery.length ? "?" + encodedQuery : ""));
|
|
4703
|
+
return this.createUri(schema, query);
|
|
4534
4704
|
}
|
|
4535
4705
|
/**
|
|
4536
4706
|
* Feature detection for WebSocket.
|
|
4537
4707
|
*
|
|
4538
4708
|
* @return {Boolean} whether this transport is available.
|
|
4539
|
-
* @
|
|
4709
|
+
* @private
|
|
4540
4710
|
*/
|
|
4541
4711
|
check() {
|
|
4542
4712
|
return !!WebSocket$1;
|
|
4543
4713
|
}
|
|
4544
4714
|
}
|
|
4545
4715
|
|
|
4716
|
+
class WT extends Transport {
|
|
4717
|
+
get name() {
|
|
4718
|
+
return "webtransport";
|
|
4719
|
+
}
|
|
4720
|
+
doOpen() {
|
|
4721
|
+
// @ts-ignore
|
|
4722
|
+
if (typeof WebTransport !== "function") {
|
|
4723
|
+
return;
|
|
4724
|
+
}
|
|
4725
|
+
// @ts-ignore
|
|
4726
|
+
this.transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]);
|
|
4727
|
+
this.transport.closed
|
|
4728
|
+
.then(() => {
|
|
4729
|
+
this.onClose();
|
|
4730
|
+
})
|
|
4731
|
+
.catch((err) => {
|
|
4732
|
+
this.onError("webtransport error", err);
|
|
4733
|
+
});
|
|
4734
|
+
// note: we could have used async/await, but that would require some additional polyfills
|
|
4735
|
+
this.transport.ready.then(() => {
|
|
4736
|
+
this.transport.createBidirectionalStream().then((stream) => {
|
|
4737
|
+
const decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, this.socket.binaryType);
|
|
4738
|
+
const reader = stream.readable.pipeThrough(decoderStream).getReader();
|
|
4739
|
+
const encoderStream = createPacketEncoderStream();
|
|
4740
|
+
encoderStream.readable.pipeTo(stream.writable);
|
|
4741
|
+
this.writer = encoderStream.writable.getWriter();
|
|
4742
|
+
const read = () => {
|
|
4743
|
+
reader
|
|
4744
|
+
.read()
|
|
4745
|
+
.then(({ done, value }) => {
|
|
4746
|
+
if (done) {
|
|
4747
|
+
return;
|
|
4748
|
+
}
|
|
4749
|
+
this.onPacket(value);
|
|
4750
|
+
read();
|
|
4751
|
+
})
|
|
4752
|
+
.catch((err) => {
|
|
4753
|
+
});
|
|
4754
|
+
};
|
|
4755
|
+
read();
|
|
4756
|
+
const packet = { type: "open" };
|
|
4757
|
+
if (this.query.sid) {
|
|
4758
|
+
packet.data = `{"sid":"${this.query.sid}"}`;
|
|
4759
|
+
}
|
|
4760
|
+
this.writer.write(packet).then(() => this.onOpen());
|
|
4761
|
+
});
|
|
4762
|
+
});
|
|
4763
|
+
}
|
|
4764
|
+
write(packets) {
|
|
4765
|
+
this.writable = false;
|
|
4766
|
+
for (let i = 0; i < packets.length; i++) {
|
|
4767
|
+
const packet = packets[i];
|
|
4768
|
+
const lastPacket = i === packets.length - 1;
|
|
4769
|
+
this.writer.write(packet).then(() => {
|
|
4770
|
+
if (lastPacket) {
|
|
4771
|
+
nextTick(() => {
|
|
4772
|
+
this.writable = true;
|
|
4773
|
+
this.emitReserved("drain");
|
|
4774
|
+
}, this.setTimeoutFn);
|
|
4775
|
+
}
|
|
4776
|
+
});
|
|
4777
|
+
}
|
|
4778
|
+
}
|
|
4779
|
+
doClose() {
|
|
4780
|
+
var _a;
|
|
4781
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.close();
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
|
|
4546
4785
|
const transports = {
|
|
4547
4786
|
websocket: WS,
|
|
4548
|
-
|
|
4787
|
+
webtransport: WT,
|
|
4788
|
+
polling: Polling,
|
|
4549
4789
|
};
|
|
4550
4790
|
|
|
4551
4791
|
// imported from https://github.com/galkn/parseuri
|
|
4552
4792
|
/**
|
|
4553
|
-
* Parses
|
|
4793
|
+
* Parses a URI
|
|
4794
|
+
*
|
|
4795
|
+
* Note: we could also have used the built-in URL object, but it isn't supported on all platforms.
|
|
4796
|
+
*
|
|
4797
|
+
* See:
|
|
4798
|
+
* - https://developer.mozilla.org/en-US/docs/Web/API/URL
|
|
4799
|
+
* - https://caniuse.com/url
|
|
4800
|
+
* - https://www.rfc-editor.org/rfc/rfc3986#appendix-B
|
|
4801
|
+
*
|
|
4802
|
+
* History of the parse() method:
|
|
4803
|
+
* - first commit: https://github.com/socketio/socket.io-client/commit/4ee1d5d94b3906a9c052b459f1a818b15f38f91c
|
|
4804
|
+
* - export into its own module: https://github.com/socketio/engine.io-client/commit/de2c561e4564efeb78f1bdb1ba39ef81b2822cb3
|
|
4805
|
+
* - reimport: https://github.com/socketio/engine.io-client/commit/df32277c3f6d622eec5ed09f493cae3f3391d242
|
|
4554
4806
|
*
|
|
4555
4807
|
* @author Steven Levithan <stevenlevithan.com> (MIT license)
|
|
4556
4808
|
* @api private
|
|
4557
4809
|
*/
|
|
4558
|
-
const re = /^(?:(?![
|
|
4810
|
+
const re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
|
|
4559
4811
|
const parts = [
|
|
4560
4812
|
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
|
|
4561
4813
|
];
|
|
4562
4814
|
function parse$2(str) {
|
|
4815
|
+
if (str.length > 2000) {
|
|
4816
|
+
throw "URI too long";
|
|
4817
|
+
}
|
|
4563
4818
|
const src = str, b = str.indexOf('['), e = str.indexOf(']');
|
|
4564
4819
|
if (b != -1 && e != -1) {
|
|
4565
4820
|
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
|
|
@@ -4602,12 +4857,13 @@ class Socket$1 extends Emitter_1 {
|
|
|
4602
4857
|
/**
|
|
4603
4858
|
* Socket constructor.
|
|
4604
4859
|
*
|
|
4605
|
-
* @param {String|Object} uri or options
|
|
4860
|
+
* @param {String|Object} uri - uri or options
|
|
4606
4861
|
* @param {Object} opts - options
|
|
4607
|
-
* @api public
|
|
4608
4862
|
*/
|
|
4609
4863
|
constructor(uri, opts = {}) {
|
|
4610
4864
|
super();
|
|
4865
|
+
this.binaryType = defaultBinaryType;
|
|
4866
|
+
this.writeBuffer = [];
|
|
4611
4867
|
if (uri && "object" === typeof uri) {
|
|
4612
4868
|
opts = uri;
|
|
4613
4869
|
uri = null;
|
|
@@ -4642,8 +4898,11 @@ class Socket$1 extends Emitter_1 {
|
|
|
4642
4898
|
: this.secure
|
|
4643
4899
|
? "443"
|
|
4644
4900
|
: "80");
|
|
4645
|
-
this.transports = opts.transports || [
|
|
4646
|
-
|
|
4901
|
+
this.transports = opts.transports || [
|
|
4902
|
+
"polling",
|
|
4903
|
+
"websocket",
|
|
4904
|
+
"webtransport",
|
|
4905
|
+
];
|
|
4647
4906
|
this.writeBuffer = [];
|
|
4648
4907
|
this.prevBufferLen = 0;
|
|
4649
4908
|
this.opts = Object.assign({
|
|
@@ -4653,14 +4912,17 @@ class Socket$1 extends Emitter_1 {
|
|
|
4653
4912
|
upgrade: true,
|
|
4654
4913
|
timestampParam: "t",
|
|
4655
4914
|
rememberUpgrade: false,
|
|
4915
|
+
addTrailingSlash: true,
|
|
4656
4916
|
rejectUnauthorized: true,
|
|
4657
4917
|
perMessageDeflate: {
|
|
4658
|
-
threshold: 1024
|
|
4918
|
+
threshold: 1024,
|
|
4659
4919
|
},
|
|
4660
4920
|
transportOptions: {},
|
|
4661
|
-
closeOnBeforeunload:
|
|
4921
|
+
closeOnBeforeunload: false,
|
|
4662
4922
|
}, opts);
|
|
4663
|
-
this.opts.path =
|
|
4923
|
+
this.opts.path =
|
|
4924
|
+
this.opts.path.replace(/\/$/, "") +
|
|
4925
|
+
(this.opts.addTrailingSlash ? "/" : "");
|
|
4664
4926
|
if (typeof this.opts.query === "string") {
|
|
4665
4927
|
this.opts.query = decode(this.opts.query);
|
|
4666
4928
|
}
|
|
@@ -4688,7 +4950,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4688
4950
|
if (this.hostname !== "localhost") {
|
|
4689
4951
|
this.offlineEventListener = () => {
|
|
4690
4952
|
this.onClose("transport close", {
|
|
4691
|
-
description: "network connection lost"
|
|
4953
|
+
description: "network connection lost",
|
|
4692
4954
|
});
|
|
4693
4955
|
};
|
|
4694
4956
|
addEventListener("offline", this.offlineEventListener, false);
|
|
@@ -4699,9 +4961,9 @@ class Socket$1 extends Emitter_1 {
|
|
|
4699
4961
|
/**
|
|
4700
4962
|
* Creates transport of the given type.
|
|
4701
4963
|
*
|
|
4702
|
-
* @param {String} transport name
|
|
4964
|
+
* @param {String} name - transport name
|
|
4703
4965
|
* @return {Transport}
|
|
4704
|
-
* @
|
|
4966
|
+
* @private
|
|
4705
4967
|
*/
|
|
4706
4968
|
createTransport(name) {
|
|
4707
4969
|
const query = Object.assign({}, this.opts.query);
|
|
@@ -4712,19 +4974,19 @@ class Socket$1 extends Emitter_1 {
|
|
|
4712
4974
|
// session id if we already have one
|
|
4713
4975
|
if (this.id)
|
|
4714
4976
|
query.sid = this.id;
|
|
4715
|
-
const opts = Object.assign({}, this.opts
|
|
4977
|
+
const opts = Object.assign({}, this.opts, {
|
|
4716
4978
|
query,
|
|
4717
4979
|
socket: this,
|
|
4718
4980
|
hostname: this.hostname,
|
|
4719
4981
|
secure: this.secure,
|
|
4720
|
-
port: this.port
|
|
4721
|
-
});
|
|
4982
|
+
port: this.port,
|
|
4983
|
+
}, this.opts.transportOptions[name]);
|
|
4722
4984
|
return new transports[name](opts);
|
|
4723
4985
|
}
|
|
4724
4986
|
/**
|
|
4725
4987
|
* Initializes transport to use and starts probe.
|
|
4726
4988
|
*
|
|
4727
|
-
* @
|
|
4989
|
+
* @private
|
|
4728
4990
|
*/
|
|
4729
4991
|
open() {
|
|
4730
4992
|
let transport;
|
|
@@ -4759,7 +5021,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4759
5021
|
/**
|
|
4760
5022
|
* Sets the current transport. Disables the existing one (if any).
|
|
4761
5023
|
*
|
|
4762
|
-
* @
|
|
5024
|
+
* @private
|
|
4763
5025
|
*/
|
|
4764
5026
|
setTransport(transport) {
|
|
4765
5027
|
if (this.transport) {
|
|
@@ -4772,13 +5034,13 @@ class Socket$1 extends Emitter_1 {
|
|
|
4772
5034
|
.on("drain", this.onDrain.bind(this))
|
|
4773
5035
|
.on("packet", this.onPacket.bind(this))
|
|
4774
5036
|
.on("error", this.onError.bind(this))
|
|
4775
|
-
.on("close", reason => this.onClose("transport close", reason));
|
|
5037
|
+
.on("close", (reason) => this.onClose("transport close", reason));
|
|
4776
5038
|
}
|
|
4777
5039
|
/**
|
|
4778
5040
|
* Probes a transport.
|
|
4779
5041
|
*
|
|
4780
|
-
* @param {String} transport name
|
|
4781
|
-
* @
|
|
5042
|
+
* @param {String} name - transport name
|
|
5043
|
+
* @private
|
|
4782
5044
|
*/
|
|
4783
5045
|
probe(name) {
|
|
4784
5046
|
let transport = this.createTransport(name);
|
|
@@ -4788,7 +5050,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4788
5050
|
if (failed)
|
|
4789
5051
|
return;
|
|
4790
5052
|
transport.send([{ type: "ping", data: "probe" }]);
|
|
4791
|
-
transport.once("packet", msg => {
|
|
5053
|
+
transport.once("packet", (msg) => {
|
|
4792
5054
|
if (failed)
|
|
4793
5055
|
return;
|
|
4794
5056
|
if ("pong" === msg.type && "probe" === msg.data) {
|
|
@@ -4829,7 +5091,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4829
5091
|
transport = null;
|
|
4830
5092
|
}
|
|
4831
5093
|
// Handle any error that happens while probing
|
|
4832
|
-
const onerror = err => {
|
|
5094
|
+
const onerror = (err) => {
|
|
4833
5095
|
const error = new Error("probe error: " + err);
|
|
4834
5096
|
// @ts-ignore
|
|
4835
5097
|
error.transport = transport.name;
|
|
@@ -4862,12 +5124,23 @@ class Socket$1 extends Emitter_1 {
|
|
|
4862
5124
|
transport.once("close", onTransportClose);
|
|
4863
5125
|
this.once("close", onclose);
|
|
4864
5126
|
this.once("upgrading", onupgrade);
|
|
4865
|
-
|
|
5127
|
+
if (this.upgrades.indexOf("webtransport") !== -1 &&
|
|
5128
|
+
name !== "webtransport") {
|
|
5129
|
+
// favor WebTransport
|
|
5130
|
+
this.setTimeoutFn(() => {
|
|
5131
|
+
if (!failed) {
|
|
5132
|
+
transport.open();
|
|
5133
|
+
}
|
|
5134
|
+
}, 200);
|
|
5135
|
+
}
|
|
5136
|
+
else {
|
|
5137
|
+
transport.open();
|
|
5138
|
+
}
|
|
4866
5139
|
}
|
|
4867
5140
|
/**
|
|
4868
5141
|
* Called when connection is deemed open.
|
|
4869
5142
|
*
|
|
4870
|
-
* @
|
|
5143
|
+
* @private
|
|
4871
5144
|
*/
|
|
4872
5145
|
onOpen() {
|
|
4873
5146
|
this.readyState = "open";
|
|
@@ -4876,9 +5149,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4876
5149
|
this.flush();
|
|
4877
5150
|
// we check for `readyState` in case an `open`
|
|
4878
5151
|
// listener already closed the socket
|
|
4879
|
-
if ("open" === this.readyState &&
|
|
4880
|
-
this.opts.upgrade &&
|
|
4881
|
-
this.transport.pause) {
|
|
5152
|
+
if ("open" === this.readyState && this.opts.upgrade) {
|
|
4882
5153
|
let i = 0;
|
|
4883
5154
|
const l = this.upgrades.length;
|
|
4884
5155
|
for (; i < l; i++) {
|
|
@@ -4889,7 +5160,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4889
5160
|
/**
|
|
4890
5161
|
* Handles a packet.
|
|
4891
5162
|
*
|
|
4892
|
-
* @
|
|
5163
|
+
* @private
|
|
4893
5164
|
*/
|
|
4894
5165
|
onPacket(packet) {
|
|
4895
5166
|
if ("opening" === this.readyState ||
|
|
@@ -4898,12 +5169,12 @@ class Socket$1 extends Emitter_1 {
|
|
|
4898
5169
|
this.emitReserved("packet", packet);
|
|
4899
5170
|
// Socket is live - any packet counts
|
|
4900
5171
|
this.emitReserved("heartbeat");
|
|
5172
|
+
this.resetPingTimeout();
|
|
4901
5173
|
switch (packet.type) {
|
|
4902
5174
|
case "open":
|
|
4903
5175
|
this.onHandshake(JSON.parse(packet.data));
|
|
4904
5176
|
break;
|
|
4905
5177
|
case "ping":
|
|
4906
|
-
this.resetPingTimeout();
|
|
4907
5178
|
this.sendPacket("pong");
|
|
4908
5179
|
this.emitReserved("ping");
|
|
4909
5180
|
this.emitReserved("pong");
|
|
@@ -4925,7 +5196,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4925
5196
|
* Called upon handshake completion.
|
|
4926
5197
|
*
|
|
4927
5198
|
* @param {Object} data - handshake obj
|
|
4928
|
-
* @
|
|
5199
|
+
* @private
|
|
4929
5200
|
*/
|
|
4930
5201
|
onHandshake(data) {
|
|
4931
5202
|
this.emitReserved("handshake", data);
|
|
@@ -4944,7 +5215,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4944
5215
|
/**
|
|
4945
5216
|
* Sets and resets ping timeout timer based on server pings.
|
|
4946
5217
|
*
|
|
4947
|
-
* @
|
|
5218
|
+
* @private
|
|
4948
5219
|
*/
|
|
4949
5220
|
resetPingTimeout() {
|
|
4950
5221
|
this.clearTimeoutFn(this.pingTimeoutTimer);
|
|
@@ -4958,7 +5229,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4958
5229
|
/**
|
|
4959
5230
|
* Called on `drain` event
|
|
4960
5231
|
*
|
|
4961
|
-
* @
|
|
5232
|
+
* @private
|
|
4962
5233
|
*/
|
|
4963
5234
|
onDrain() {
|
|
4964
5235
|
this.writeBuffer.splice(0, this.prevBufferLen);
|
|
@@ -4976,7 +5247,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
4976
5247
|
/**
|
|
4977
5248
|
* Flush write buffers.
|
|
4978
5249
|
*
|
|
4979
|
-
* @
|
|
5250
|
+
* @private
|
|
4980
5251
|
*/
|
|
4981
5252
|
flush() {
|
|
4982
5253
|
if ("closed" !== this.readyState &&
|
|
@@ -5020,11 +5291,10 @@ class Socket$1 extends Emitter_1 {
|
|
|
5020
5291
|
/**
|
|
5021
5292
|
* Sends a message.
|
|
5022
5293
|
*
|
|
5023
|
-
* @param {String} message.
|
|
5024
|
-
* @param {Function} callback function.
|
|
5294
|
+
* @param {String} msg - message.
|
|
5025
5295
|
* @param {Object} options.
|
|
5296
|
+
* @param {Function} callback function.
|
|
5026
5297
|
* @return {Socket} for chaining.
|
|
5027
|
-
* @api public
|
|
5028
5298
|
*/
|
|
5029
5299
|
write(msg, options, fn) {
|
|
5030
5300
|
this.sendPacket("message", msg, options, fn);
|
|
@@ -5037,11 +5307,11 @@ class Socket$1 extends Emitter_1 {
|
|
|
5037
5307
|
/**
|
|
5038
5308
|
* Sends a packet.
|
|
5039
5309
|
*
|
|
5040
|
-
* @param {String} packet type.
|
|
5310
|
+
* @param {String} type: packet type.
|
|
5041
5311
|
* @param {String} data.
|
|
5042
5312
|
* @param {Object} options.
|
|
5043
|
-
* @param {Function} callback function.
|
|
5044
|
-
* @
|
|
5313
|
+
* @param {Function} fn - callback function.
|
|
5314
|
+
* @private
|
|
5045
5315
|
*/
|
|
5046
5316
|
sendPacket(type, data, options, fn) {
|
|
5047
5317
|
if ("function" === typeof data) {
|
|
@@ -5060,7 +5330,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
5060
5330
|
const packet = {
|
|
5061
5331
|
type: type,
|
|
5062
5332
|
data: data,
|
|
5063
|
-
options: options
|
|
5333
|
+
options: options,
|
|
5064
5334
|
};
|
|
5065
5335
|
this.emitReserved("packetCreate", packet);
|
|
5066
5336
|
this.writeBuffer.push(packet);
|
|
@@ -5070,8 +5340,6 @@ class Socket$1 extends Emitter_1 {
|
|
|
5070
5340
|
}
|
|
5071
5341
|
/**
|
|
5072
5342
|
* Closes the connection.
|
|
5073
|
-
*
|
|
5074
|
-
* @api public
|
|
5075
5343
|
*/
|
|
5076
5344
|
close() {
|
|
5077
5345
|
const close = () => {
|
|
@@ -5112,7 +5380,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
5112
5380
|
/**
|
|
5113
5381
|
* Called upon transport error
|
|
5114
5382
|
*
|
|
5115
|
-
* @
|
|
5383
|
+
* @private
|
|
5116
5384
|
*/
|
|
5117
5385
|
onError(err) {
|
|
5118
5386
|
Socket$1.priorWebsocketSuccess = false;
|
|
@@ -5122,7 +5390,7 @@ class Socket$1 extends Emitter_1 {
|
|
|
5122
5390
|
/**
|
|
5123
5391
|
* Called upon transport close.
|
|
5124
5392
|
*
|
|
5125
|
-
* @
|
|
5393
|
+
* @private
|
|
5126
5394
|
*/
|
|
5127
5395
|
onClose(reason, description) {
|
|
5128
5396
|
if ("opening" === this.readyState ||
|
|
@@ -5155,9 +5423,8 @@ class Socket$1 extends Emitter_1 {
|
|
|
5155
5423
|
/**
|
|
5156
5424
|
* Filters upgrades, returning only those matching client transports.
|
|
5157
5425
|
*
|
|
5158
|
-
* @param {Array} server upgrades
|
|
5159
|
-
* @
|
|
5160
|
-
*
|
|
5426
|
+
* @param {Array} upgrades - server upgrades
|
|
5427
|
+
* @private
|
|
5161
5428
|
*/
|
|
5162
5429
|
filterUpgrades(upgrades) {
|
|
5163
5430
|
const filteredUpgrades = [];
|
|
@@ -5367,6 +5634,17 @@ function _reconstructPacket(data, buffers) {
|
|
|
5367
5634
|
return data;
|
|
5368
5635
|
}
|
|
5369
5636
|
|
|
5637
|
+
/**
|
|
5638
|
+
* These strings must not be used as event names, as they have a special meaning.
|
|
5639
|
+
*/
|
|
5640
|
+
const RESERVED_EVENTS$1 = [
|
|
5641
|
+
"connect",
|
|
5642
|
+
"connect_error",
|
|
5643
|
+
"disconnect",
|
|
5644
|
+
"disconnecting",
|
|
5645
|
+
"newListener",
|
|
5646
|
+
"removeListener", // used by the Node.js EventEmitter
|
|
5647
|
+
];
|
|
5370
5648
|
/**
|
|
5371
5649
|
* Protocol version.
|
|
5372
5650
|
*
|
|
@@ -5455,6 +5733,10 @@ class Encoder {
|
|
|
5455
5733
|
return buffers; // write all the buffers
|
|
5456
5734
|
}
|
|
5457
5735
|
}
|
|
5736
|
+
// see https://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript
|
|
5737
|
+
function isObject(value) {
|
|
5738
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
5739
|
+
}
|
|
5458
5740
|
/**
|
|
5459
5741
|
* A socket.io Decoder instance
|
|
5460
5742
|
*
|
|
@@ -5594,14 +5876,17 @@ class Decoder extends Emitter_1 {
|
|
|
5594
5876
|
static isPayloadValid(type, payload) {
|
|
5595
5877
|
switch (type) {
|
|
5596
5878
|
case PacketType.CONNECT:
|
|
5597
|
-
return
|
|
5879
|
+
return isObject(payload);
|
|
5598
5880
|
case PacketType.DISCONNECT:
|
|
5599
5881
|
return payload === undefined;
|
|
5600
5882
|
case PacketType.CONNECT_ERROR:
|
|
5601
|
-
return typeof payload === "string" ||
|
|
5883
|
+
return typeof payload === "string" || isObject(payload);
|
|
5602
5884
|
case PacketType.EVENT:
|
|
5603
5885
|
case PacketType.BINARY_EVENT:
|
|
5604
|
-
return Array.isArray(payload) &&
|
|
5886
|
+
return (Array.isArray(payload) &&
|
|
5887
|
+
(typeof payload[0] === "number" ||
|
|
5888
|
+
(typeof payload[0] === "string" &&
|
|
5889
|
+
RESERVED_EVENTS$1.indexOf(payload[0]) === -1)));
|
|
5605
5890
|
case PacketType.ACK:
|
|
5606
5891
|
case PacketType.BINARY_ACK:
|
|
5607
5892
|
return Array.isArray(payload);
|
|
@@ -5686,18 +5971,100 @@ const RESERVED_EVENTS = Object.freeze({
|
|
|
5686
5971
|
newListener: 1,
|
|
5687
5972
|
removeListener: 1,
|
|
5688
5973
|
});
|
|
5974
|
+
/**
|
|
5975
|
+
* A Socket is the fundamental class for interacting with the server.
|
|
5976
|
+
*
|
|
5977
|
+
* A Socket belongs to a certain Namespace (by default /) and uses an underlying {@link Manager} to communicate.
|
|
5978
|
+
*
|
|
5979
|
+
* @example
|
|
5980
|
+
* const socket = io();
|
|
5981
|
+
*
|
|
5982
|
+
* socket.on("connect", () => {
|
|
5983
|
+
* console.log("connected");
|
|
5984
|
+
* });
|
|
5985
|
+
*
|
|
5986
|
+
* // send an event to the server
|
|
5987
|
+
* socket.emit("foo", "bar");
|
|
5988
|
+
*
|
|
5989
|
+
* socket.on("foobar", () => {
|
|
5990
|
+
* // an event was received from the server
|
|
5991
|
+
* });
|
|
5992
|
+
*
|
|
5993
|
+
* // upon disconnection
|
|
5994
|
+
* socket.on("disconnect", (reason) => {
|
|
5995
|
+
* console.log(`disconnected due to ${reason}`);
|
|
5996
|
+
* });
|
|
5997
|
+
*/
|
|
5689
5998
|
class Socket extends Emitter_1 {
|
|
5690
5999
|
/**
|
|
5691
6000
|
* `Socket` constructor.
|
|
5692
|
-
*
|
|
5693
|
-
* @public
|
|
5694
6001
|
*/
|
|
5695
6002
|
constructor(io, nsp, opts) {
|
|
5696
6003
|
super();
|
|
6004
|
+
/**
|
|
6005
|
+
* Whether the socket is currently connected to the server.
|
|
6006
|
+
*
|
|
6007
|
+
* @example
|
|
6008
|
+
* const socket = io();
|
|
6009
|
+
*
|
|
6010
|
+
* socket.on("connect", () => {
|
|
6011
|
+
* console.log(socket.connected); // true
|
|
6012
|
+
* });
|
|
6013
|
+
*
|
|
6014
|
+
* socket.on("disconnect", () => {
|
|
6015
|
+
* console.log(socket.connected); // false
|
|
6016
|
+
* });
|
|
6017
|
+
*/
|
|
5697
6018
|
this.connected = false;
|
|
6019
|
+
/**
|
|
6020
|
+
* Whether the connection state was recovered after a temporary disconnection. In that case, any missed packets will
|
|
6021
|
+
* be transmitted by the server.
|
|
6022
|
+
*/
|
|
6023
|
+
this.recovered = false;
|
|
6024
|
+
/**
|
|
6025
|
+
* Buffer for packets received before the CONNECT packet
|
|
6026
|
+
*/
|
|
5698
6027
|
this.receiveBuffer = [];
|
|
6028
|
+
/**
|
|
6029
|
+
* Buffer for packets that will be sent once the socket is connected
|
|
6030
|
+
*/
|
|
5699
6031
|
this.sendBuffer = [];
|
|
6032
|
+
/**
|
|
6033
|
+
* The queue of packets to be sent with retry in case of failure.
|
|
6034
|
+
*
|
|
6035
|
+
* Packets are sent one by one, each waiting for the server acknowledgement, in order to guarantee the delivery order.
|
|
6036
|
+
* @private
|
|
6037
|
+
*/
|
|
6038
|
+
this._queue = [];
|
|
6039
|
+
/**
|
|
6040
|
+
* A sequence to generate the ID of the {@link QueuedPacket}.
|
|
6041
|
+
* @private
|
|
6042
|
+
*/
|
|
6043
|
+
this._queueSeq = 0;
|
|
5700
6044
|
this.ids = 0;
|
|
6045
|
+
/**
|
|
6046
|
+
* A map containing acknowledgement handlers.
|
|
6047
|
+
*
|
|
6048
|
+
* The `withError` attribute is used to differentiate handlers that accept an error as first argument:
|
|
6049
|
+
*
|
|
6050
|
+
* - `socket.emit("test", (err, value) => { ... })` with `ackTimeout` option
|
|
6051
|
+
* - `socket.timeout(5000).emit("test", (err, value) => { ... })`
|
|
6052
|
+
* - `const value = await socket.emitWithAck("test")`
|
|
6053
|
+
*
|
|
6054
|
+
* From those that don't:
|
|
6055
|
+
*
|
|
6056
|
+
* - `socket.emit("test", (value) => { ... });`
|
|
6057
|
+
*
|
|
6058
|
+
* In the first case, the handlers will be called with an error when:
|
|
6059
|
+
*
|
|
6060
|
+
* - the timeout is reached
|
|
6061
|
+
* - the socket gets disconnected
|
|
6062
|
+
*
|
|
6063
|
+
* In the second case, the handlers will be simply discarded upon disconnection, since the client will never receive
|
|
6064
|
+
* an acknowledgement from the server.
|
|
6065
|
+
*
|
|
6066
|
+
* @private
|
|
6067
|
+
*/
|
|
5701
6068
|
this.acks = {};
|
|
5702
6069
|
this.flags = {};
|
|
5703
6070
|
this.io = io;
|
|
@@ -5705,11 +6072,23 @@ class Socket extends Emitter_1 {
|
|
|
5705
6072
|
if (opts && opts.auth) {
|
|
5706
6073
|
this.auth = opts.auth;
|
|
5707
6074
|
}
|
|
6075
|
+
this._opts = Object.assign({}, opts);
|
|
5708
6076
|
if (this.io._autoConnect)
|
|
5709
6077
|
this.open();
|
|
5710
6078
|
}
|
|
5711
6079
|
/**
|
|
5712
6080
|
* Whether the socket is currently disconnected
|
|
6081
|
+
*
|
|
6082
|
+
* @example
|
|
6083
|
+
* const socket = io();
|
|
6084
|
+
*
|
|
6085
|
+
* socket.on("connect", () => {
|
|
6086
|
+
* console.log(socket.disconnected); // false
|
|
6087
|
+
* });
|
|
6088
|
+
*
|
|
6089
|
+
* socket.on("disconnect", () => {
|
|
6090
|
+
* console.log(socket.disconnected); // true
|
|
6091
|
+
* });
|
|
5713
6092
|
*/
|
|
5714
6093
|
get disconnected() {
|
|
5715
6094
|
return !this.connected;
|
|
@@ -5731,7 +6110,21 @@ class Socket extends Emitter_1 {
|
|
|
5731
6110
|
];
|
|
5732
6111
|
}
|
|
5733
6112
|
/**
|
|
5734
|
-
* Whether the Socket will try to reconnect when its Manager connects or reconnects
|
|
6113
|
+
* Whether the Socket will try to reconnect when its Manager connects or reconnects.
|
|
6114
|
+
*
|
|
6115
|
+
* @example
|
|
6116
|
+
* const socket = io();
|
|
6117
|
+
*
|
|
6118
|
+
* console.log(socket.active); // true
|
|
6119
|
+
*
|
|
6120
|
+
* socket.on("disconnect", (reason) => {
|
|
6121
|
+
* if (reason === "io server disconnect") {
|
|
6122
|
+
* // the disconnection was initiated by the server, you need to manually reconnect
|
|
6123
|
+
* console.log(socket.active); // false
|
|
6124
|
+
* }
|
|
6125
|
+
* // else the socket will automatically try to reconnect
|
|
6126
|
+
* console.log(socket.active); // true
|
|
6127
|
+
* });
|
|
5735
6128
|
*/
|
|
5736
6129
|
get active() {
|
|
5737
6130
|
return !!this.subs;
|
|
@@ -5739,7 +6132,12 @@ class Socket extends Emitter_1 {
|
|
|
5739
6132
|
/**
|
|
5740
6133
|
* "Opens" the socket.
|
|
5741
6134
|
*
|
|
5742
|
-
* @
|
|
6135
|
+
* @example
|
|
6136
|
+
* const socket = io({
|
|
6137
|
+
* autoConnect: false
|
|
6138
|
+
* });
|
|
6139
|
+
*
|
|
6140
|
+
* socket.connect();
|
|
5743
6141
|
*/
|
|
5744
6142
|
connect() {
|
|
5745
6143
|
if (this.connected)
|
|
@@ -5752,7 +6150,7 @@ class Socket extends Emitter_1 {
|
|
|
5752
6150
|
return this;
|
|
5753
6151
|
}
|
|
5754
6152
|
/**
|
|
5755
|
-
* Alias for connect()
|
|
6153
|
+
* Alias for {@link connect()}.
|
|
5756
6154
|
*/
|
|
5757
6155
|
open() {
|
|
5758
6156
|
return this.connect();
|
|
@@ -5760,8 +6158,17 @@ class Socket extends Emitter_1 {
|
|
|
5760
6158
|
/**
|
|
5761
6159
|
* Sends a `message` event.
|
|
5762
6160
|
*
|
|
6161
|
+
* This method mimics the WebSocket.send() method.
|
|
6162
|
+
*
|
|
6163
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
6164
|
+
*
|
|
6165
|
+
* @example
|
|
6166
|
+
* socket.send("hello");
|
|
6167
|
+
*
|
|
6168
|
+
* // this is equivalent to
|
|
6169
|
+
* socket.emit("message", "hello");
|
|
6170
|
+
*
|
|
5763
6171
|
* @return self
|
|
5764
|
-
* @public
|
|
5765
6172
|
*/
|
|
5766
6173
|
send(...args) {
|
|
5767
6174
|
args.unshift("message");
|
|
@@ -5772,14 +6179,28 @@ class Socket extends Emitter_1 {
|
|
|
5772
6179
|
* Override `emit`.
|
|
5773
6180
|
* If the event is in `events`, it's emitted normally.
|
|
5774
6181
|
*
|
|
6182
|
+
* @example
|
|
6183
|
+
* socket.emit("hello", "world");
|
|
6184
|
+
*
|
|
6185
|
+
* // all serializable datastructures are supported (no need to call JSON.stringify)
|
|
6186
|
+
* socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) });
|
|
6187
|
+
*
|
|
6188
|
+
* // with an acknowledgement from the server
|
|
6189
|
+
* socket.emit("hello", "world", (val) => {
|
|
6190
|
+
* // ...
|
|
6191
|
+
* });
|
|
6192
|
+
*
|
|
5775
6193
|
* @return self
|
|
5776
|
-
* @public
|
|
5777
6194
|
*/
|
|
5778
6195
|
emit(ev, ...args) {
|
|
5779
6196
|
if (RESERVED_EVENTS.hasOwnProperty(ev)) {
|
|
5780
|
-
throw new Error('"' + ev + '" is a reserved event name');
|
|
6197
|
+
throw new Error('"' + ev.toString() + '" is a reserved event name');
|
|
5781
6198
|
}
|
|
5782
6199
|
args.unshift(ev);
|
|
6200
|
+
if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) {
|
|
6201
|
+
this._addToQueue(args);
|
|
6202
|
+
return this;
|
|
6203
|
+
}
|
|
5783
6204
|
const packet = {
|
|
5784
6205
|
type: PacketType.EVENT,
|
|
5785
6206
|
data: args,
|
|
@@ -5812,7 +6233,8 @@ class Socket extends Emitter_1 {
|
|
|
5812
6233
|
* @private
|
|
5813
6234
|
*/
|
|
5814
6235
|
_registerAckCallback(id, ack) {
|
|
5815
|
-
|
|
6236
|
+
var _a;
|
|
6237
|
+
const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout;
|
|
5816
6238
|
if (timeout === undefined) {
|
|
5817
6239
|
this.acks[id] = ack;
|
|
5818
6240
|
return;
|
|
@@ -5827,11 +6249,101 @@ class Socket extends Emitter_1 {
|
|
|
5827
6249
|
}
|
|
5828
6250
|
ack.call(this, new Error("operation has timed out"));
|
|
5829
6251
|
}, timeout);
|
|
5830
|
-
|
|
6252
|
+
const fn = (...args) => {
|
|
5831
6253
|
// @ts-ignore
|
|
5832
6254
|
this.io.clearTimeoutFn(timer);
|
|
5833
|
-
ack.apply(this,
|
|
6255
|
+
ack.apply(this, args);
|
|
6256
|
+
};
|
|
6257
|
+
fn.withError = true;
|
|
6258
|
+
this.acks[id] = fn;
|
|
6259
|
+
}
|
|
6260
|
+
/**
|
|
6261
|
+
* Emits an event and waits for an acknowledgement
|
|
6262
|
+
*
|
|
6263
|
+
* @example
|
|
6264
|
+
* // without timeout
|
|
6265
|
+
* const response = await socket.emitWithAck("hello", "world");
|
|
6266
|
+
*
|
|
6267
|
+
* // with a specific timeout
|
|
6268
|
+
* try {
|
|
6269
|
+
* const response = await socket.timeout(1000).emitWithAck("hello", "world");
|
|
6270
|
+
* } catch (err) {
|
|
6271
|
+
* // the server did not acknowledge the event in the given delay
|
|
6272
|
+
* }
|
|
6273
|
+
*
|
|
6274
|
+
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
6275
|
+
*/
|
|
6276
|
+
emitWithAck(ev, ...args) {
|
|
6277
|
+
return new Promise((resolve, reject) => {
|
|
6278
|
+
const fn = (arg1, arg2) => {
|
|
6279
|
+
return arg1 ? reject(arg1) : resolve(arg2);
|
|
6280
|
+
};
|
|
6281
|
+
fn.withError = true;
|
|
6282
|
+
args.push(fn);
|
|
6283
|
+
this.emit(ev, ...args);
|
|
6284
|
+
});
|
|
6285
|
+
}
|
|
6286
|
+
/**
|
|
6287
|
+
* Add the packet to the queue.
|
|
6288
|
+
* @param args
|
|
6289
|
+
* @private
|
|
6290
|
+
*/
|
|
6291
|
+
_addToQueue(args) {
|
|
6292
|
+
let ack;
|
|
6293
|
+
if (typeof args[args.length - 1] === "function") {
|
|
6294
|
+
ack = args.pop();
|
|
6295
|
+
}
|
|
6296
|
+
const packet = {
|
|
6297
|
+
id: this._queueSeq++,
|
|
6298
|
+
tryCount: 0,
|
|
6299
|
+
pending: false,
|
|
6300
|
+
args,
|
|
6301
|
+
flags: Object.assign({ fromQueue: true }, this.flags),
|
|
5834
6302
|
};
|
|
6303
|
+
args.push((err, ...responseArgs) => {
|
|
6304
|
+
if (packet !== this._queue[0]) {
|
|
6305
|
+
// the packet has already been acknowledged
|
|
6306
|
+
return;
|
|
6307
|
+
}
|
|
6308
|
+
const hasError = err !== null;
|
|
6309
|
+
if (hasError) {
|
|
6310
|
+
if (packet.tryCount > this._opts.retries) {
|
|
6311
|
+
this._queue.shift();
|
|
6312
|
+
if (ack) {
|
|
6313
|
+
ack(err);
|
|
6314
|
+
}
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6317
|
+
else {
|
|
6318
|
+
this._queue.shift();
|
|
6319
|
+
if (ack) {
|
|
6320
|
+
ack(null, ...responseArgs);
|
|
6321
|
+
}
|
|
6322
|
+
}
|
|
6323
|
+
packet.pending = false;
|
|
6324
|
+
return this._drainQueue();
|
|
6325
|
+
});
|
|
6326
|
+
this._queue.push(packet);
|
|
6327
|
+
this._drainQueue();
|
|
6328
|
+
}
|
|
6329
|
+
/**
|
|
6330
|
+
* Send the first packet of the queue, and wait for an acknowledgement from the server.
|
|
6331
|
+
* @param force - whether to resend a packet that has not been acknowledged yet
|
|
6332
|
+
*
|
|
6333
|
+
* @private
|
|
6334
|
+
*/
|
|
6335
|
+
_drainQueue(force = false) {
|
|
6336
|
+
if (!this.connected || this._queue.length === 0) {
|
|
6337
|
+
return;
|
|
6338
|
+
}
|
|
6339
|
+
const packet = this._queue[0];
|
|
6340
|
+
if (packet.pending && !force) {
|
|
6341
|
+
return;
|
|
6342
|
+
}
|
|
6343
|
+
packet.pending = true;
|
|
6344
|
+
packet.tryCount++;
|
|
6345
|
+
this.flags = packet.flags;
|
|
6346
|
+
this.emit.apply(this, packet.args);
|
|
5835
6347
|
}
|
|
5836
6348
|
/**
|
|
5837
6349
|
* Sends a packet.
|
|
@@ -5851,13 +6363,27 @@ class Socket extends Emitter_1 {
|
|
|
5851
6363
|
onopen() {
|
|
5852
6364
|
if (typeof this.auth == "function") {
|
|
5853
6365
|
this.auth((data) => {
|
|
5854
|
-
this.
|
|
6366
|
+
this._sendConnectPacket(data);
|
|
5855
6367
|
});
|
|
5856
6368
|
}
|
|
5857
6369
|
else {
|
|
5858
|
-
this.
|
|
6370
|
+
this._sendConnectPacket(this.auth);
|
|
5859
6371
|
}
|
|
5860
6372
|
}
|
|
6373
|
+
/**
|
|
6374
|
+
* Sends a CONNECT packet to initiate the Socket.IO session.
|
|
6375
|
+
*
|
|
6376
|
+
* @param data
|
|
6377
|
+
* @private
|
|
6378
|
+
*/
|
|
6379
|
+
_sendConnectPacket(data) {
|
|
6380
|
+
this.packet({
|
|
6381
|
+
type: PacketType.CONNECT,
|
|
6382
|
+
data: this._pid
|
|
6383
|
+
? Object.assign({ pid: this._pid, offset: this._lastOffset }, data)
|
|
6384
|
+
: data,
|
|
6385
|
+
});
|
|
6386
|
+
}
|
|
5861
6387
|
/**
|
|
5862
6388
|
* Called upon engine or manager `error`.
|
|
5863
6389
|
*
|
|
@@ -5880,6 +6406,26 @@ class Socket extends Emitter_1 {
|
|
|
5880
6406
|
this.connected = false;
|
|
5881
6407
|
delete this.id;
|
|
5882
6408
|
this.emitReserved("disconnect", reason, description);
|
|
6409
|
+
this._clearAcks();
|
|
6410
|
+
}
|
|
6411
|
+
/**
|
|
6412
|
+
* Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from
|
|
6413
|
+
* the server.
|
|
6414
|
+
*
|
|
6415
|
+
* @private
|
|
6416
|
+
*/
|
|
6417
|
+
_clearAcks() {
|
|
6418
|
+
Object.keys(this.acks).forEach((id) => {
|
|
6419
|
+
const isBuffered = this.sendBuffer.some((packet) => String(packet.id) === id);
|
|
6420
|
+
if (!isBuffered) {
|
|
6421
|
+
// note: handlers that do not accept an error as first argument are ignored here
|
|
6422
|
+
const ack = this.acks[id];
|
|
6423
|
+
delete this.acks[id];
|
|
6424
|
+
if (ack.withError) {
|
|
6425
|
+
ack.call(this, new Error("socket has been disconnected"));
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6428
|
+
});
|
|
5883
6429
|
}
|
|
5884
6430
|
/**
|
|
5885
6431
|
* Called with socket packet.
|
|
@@ -5894,8 +6440,7 @@ class Socket extends Emitter_1 {
|
|
|
5894
6440
|
switch (packet.type) {
|
|
5895
6441
|
case PacketType.CONNECT:
|
|
5896
6442
|
if (packet.data && packet.data.sid) {
|
|
5897
|
-
|
|
5898
|
-
this.onconnect(id);
|
|
6443
|
+
this.onconnect(packet.data.sid, packet.data.pid);
|
|
5899
6444
|
}
|
|
5900
6445
|
else {
|
|
5901
6446
|
this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));
|
|
@@ -5947,6 +6492,9 @@ class Socket extends Emitter_1 {
|
|
|
5947
6492
|
}
|
|
5948
6493
|
}
|
|
5949
6494
|
super.emit.apply(this, args);
|
|
6495
|
+
if (this._pid && args.length && typeof args[args.length - 1] === "string") {
|
|
6496
|
+
this._lastOffset = args[args.length - 1];
|
|
6497
|
+
}
|
|
5950
6498
|
}
|
|
5951
6499
|
/**
|
|
5952
6500
|
* Produces an ack callback to emit with an event.
|
|
@@ -5969,28 +6517,37 @@ class Socket extends Emitter_1 {
|
|
|
5969
6517
|
};
|
|
5970
6518
|
}
|
|
5971
6519
|
/**
|
|
5972
|
-
* Called upon a server
|
|
6520
|
+
* Called upon a server acknowledgement.
|
|
5973
6521
|
*
|
|
5974
6522
|
* @param packet
|
|
5975
6523
|
* @private
|
|
5976
6524
|
*/
|
|
5977
6525
|
onack(packet) {
|
|
5978
6526
|
const ack = this.acks[packet.id];
|
|
5979
|
-
if ("function"
|
|
5980
|
-
|
|
5981
|
-
|
|
6527
|
+
if (typeof ack !== "function") {
|
|
6528
|
+
return;
|
|
6529
|
+
}
|
|
6530
|
+
delete this.acks[packet.id];
|
|
6531
|
+
// @ts-ignore FIXME ack is incorrectly inferred as 'never'
|
|
6532
|
+
if (ack.withError) {
|
|
6533
|
+
packet.data.unshift(null);
|
|
5982
6534
|
}
|
|
6535
|
+
// @ts-ignore
|
|
6536
|
+
ack.apply(this, packet.data);
|
|
5983
6537
|
}
|
|
5984
6538
|
/**
|
|
5985
6539
|
* Called upon server connect.
|
|
5986
6540
|
*
|
|
5987
6541
|
* @private
|
|
5988
6542
|
*/
|
|
5989
|
-
onconnect(id) {
|
|
6543
|
+
onconnect(id, pid) {
|
|
5990
6544
|
this.id = id;
|
|
6545
|
+
this.recovered = pid && this._pid === pid;
|
|
6546
|
+
this._pid = pid; // defined only if connection state recovery is enabled
|
|
5991
6547
|
this.connected = true;
|
|
5992
6548
|
this.emitBuffered();
|
|
5993
6549
|
this.emitReserved("connect");
|
|
6550
|
+
this._drainQueue(true);
|
|
5994
6551
|
}
|
|
5995
6552
|
/**
|
|
5996
6553
|
* Emit buffered events (received and emitted).
|
|
@@ -6031,10 +6588,20 @@ class Socket extends Emitter_1 {
|
|
|
6031
6588
|
this.io["_destroy"](this);
|
|
6032
6589
|
}
|
|
6033
6590
|
/**
|
|
6034
|
-
* Disconnects the socket manually.
|
|
6591
|
+
* Disconnects the socket manually. In that case, the socket will not try to reconnect.
|
|
6592
|
+
*
|
|
6593
|
+
* If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed.
|
|
6594
|
+
*
|
|
6595
|
+
* @example
|
|
6596
|
+
* const socket = io();
|
|
6597
|
+
*
|
|
6598
|
+
* socket.on("disconnect", (reason) => {
|
|
6599
|
+
* // console.log(reason); prints "io client disconnect"
|
|
6600
|
+
* });
|
|
6601
|
+
*
|
|
6602
|
+
* socket.disconnect();
|
|
6035
6603
|
*
|
|
6036
6604
|
* @return self
|
|
6037
|
-
* @public
|
|
6038
6605
|
*/
|
|
6039
6606
|
disconnect() {
|
|
6040
6607
|
if (this.connected) {
|
|
@@ -6049,10 +6616,9 @@ class Socket extends Emitter_1 {
|
|
|
6049
6616
|
return this;
|
|
6050
6617
|
}
|
|
6051
6618
|
/**
|
|
6052
|
-
* Alias for disconnect()
|
|
6619
|
+
* Alias for {@link disconnect()}.
|
|
6053
6620
|
*
|
|
6054
6621
|
* @return self
|
|
6055
|
-
* @public
|
|
6056
6622
|
*/
|
|
6057
6623
|
close() {
|
|
6058
6624
|
return this.disconnect();
|
|
@@ -6060,9 +6626,11 @@ class Socket extends Emitter_1 {
|
|
|
6060
6626
|
/**
|
|
6061
6627
|
* Sets the compress flag.
|
|
6062
6628
|
*
|
|
6629
|
+
* @example
|
|
6630
|
+
* socket.compress(false).emit("hello");
|
|
6631
|
+
*
|
|
6063
6632
|
* @param compress - if `true`, compresses the sending data
|
|
6064
6633
|
* @return self
|
|
6065
|
-
* @public
|
|
6066
6634
|
*/
|
|
6067
6635
|
compress(compress) {
|
|
6068
6636
|
this.flags.compress = compress;
|
|
@@ -6072,8 +6640,10 @@ class Socket extends Emitter_1 {
|
|
|
6072
6640
|
* Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not
|
|
6073
6641
|
* ready to send messages.
|
|
6074
6642
|
*
|
|
6643
|
+
* @example
|
|
6644
|
+
* socket.volatile.emit("hello"); // the server may or may not receive it
|
|
6645
|
+
*
|
|
6075
6646
|
* @returns self
|
|
6076
|
-
* @public
|
|
6077
6647
|
*/
|
|
6078
6648
|
get volatile() {
|
|
6079
6649
|
this.flags.volatile = true;
|
|
@@ -6083,16 +6653,14 @@ class Socket extends Emitter_1 {
|
|
|
6083
6653
|
* Sets a modifier for a subsequent event emission that the callback will be called with an error when the
|
|
6084
6654
|
* given number of milliseconds have elapsed without an acknowledgement from the server:
|
|
6085
6655
|
*
|
|
6086
|
-
*
|
|
6656
|
+
* @example
|
|
6087
6657
|
* socket.timeout(5000).emit("my-event", (err) => {
|
|
6088
6658
|
* if (err) {
|
|
6089
6659
|
* // the server did not acknowledge the event in the given delay
|
|
6090
6660
|
* }
|
|
6091
6661
|
* });
|
|
6092
|
-
* ```
|
|
6093
6662
|
*
|
|
6094
6663
|
* @returns self
|
|
6095
|
-
* @public
|
|
6096
6664
|
*/
|
|
6097
6665
|
timeout(timeout) {
|
|
6098
6666
|
this.flags.timeout = timeout;
|
|
@@ -6102,8 +6670,12 @@ class Socket extends Emitter_1 {
|
|
|
6102
6670
|
* Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
|
|
6103
6671
|
* callback.
|
|
6104
6672
|
*
|
|
6673
|
+
* @example
|
|
6674
|
+
* socket.onAny((event, ...args) => {
|
|
6675
|
+
* console.log(`got ${event}`);
|
|
6676
|
+
* });
|
|
6677
|
+
*
|
|
6105
6678
|
* @param listener
|
|
6106
|
-
* @public
|
|
6107
6679
|
*/
|
|
6108
6680
|
onAny(listener) {
|
|
6109
6681
|
this._anyListeners = this._anyListeners || [];
|
|
@@ -6114,8 +6686,12 @@ class Socket extends Emitter_1 {
|
|
|
6114
6686
|
* Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
|
|
6115
6687
|
* callback. The listener is added to the beginning of the listeners array.
|
|
6116
6688
|
*
|
|
6689
|
+
* @example
|
|
6690
|
+
* socket.prependAny((event, ...args) => {
|
|
6691
|
+
* console.log(`got event ${event}`);
|
|
6692
|
+
* });
|
|
6693
|
+
*
|
|
6117
6694
|
* @param listener
|
|
6118
|
-
* @public
|
|
6119
6695
|
*/
|
|
6120
6696
|
prependAny(listener) {
|
|
6121
6697
|
this._anyListeners = this._anyListeners || [];
|
|
@@ -6125,8 +6701,20 @@ class Socket extends Emitter_1 {
|
|
|
6125
6701
|
/**
|
|
6126
6702
|
* Removes the listener that will be fired when any event is emitted.
|
|
6127
6703
|
*
|
|
6704
|
+
* @example
|
|
6705
|
+
* const catchAllListener = (event, ...args) => {
|
|
6706
|
+
* console.log(`got event ${event}`);
|
|
6707
|
+
* }
|
|
6708
|
+
*
|
|
6709
|
+
* socket.onAny(catchAllListener);
|
|
6710
|
+
*
|
|
6711
|
+
* // remove a specific listener
|
|
6712
|
+
* socket.offAny(catchAllListener);
|
|
6713
|
+
*
|
|
6714
|
+
* // or remove all listeners
|
|
6715
|
+
* socket.offAny();
|
|
6716
|
+
*
|
|
6128
6717
|
* @param listener
|
|
6129
|
-
* @public
|
|
6130
6718
|
*/
|
|
6131
6719
|
offAny(listener) {
|
|
6132
6720
|
if (!this._anyListeners) {
|
|
@@ -6149,8 +6737,6 @@ class Socket extends Emitter_1 {
|
|
|
6149
6737
|
/**
|
|
6150
6738
|
* Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
|
|
6151
6739
|
* e.g. to remove listeners.
|
|
6152
|
-
*
|
|
6153
|
-
* @public
|
|
6154
6740
|
*/
|
|
6155
6741
|
listenersAny() {
|
|
6156
6742
|
return this._anyListeners || [];
|
|
@@ -6159,17 +6745,14 @@ class Socket extends Emitter_1 {
|
|
|
6159
6745
|
* Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
|
|
6160
6746
|
* callback.
|
|
6161
6747
|
*
|
|
6162
|
-
*
|
|
6163
|
-
*
|
|
6164
|
-
* <pre><code>
|
|
6748
|
+
* Note: acknowledgements sent to the server are not included.
|
|
6165
6749
|
*
|
|
6750
|
+
* @example
|
|
6166
6751
|
* socket.onAnyOutgoing((event, ...args) => {
|
|
6167
|
-
* console.log(event);
|
|
6752
|
+
* console.log(`sent event ${event}`);
|
|
6168
6753
|
* });
|
|
6169
6754
|
*
|
|
6170
|
-
*
|
|
6171
|
-
*
|
|
6172
|
-
* @public
|
|
6755
|
+
* @param listener
|
|
6173
6756
|
*/
|
|
6174
6757
|
onAnyOutgoing(listener) {
|
|
6175
6758
|
this._anyOutgoingListeners = this._anyOutgoingListeners || [];
|
|
@@ -6180,17 +6763,14 @@ class Socket extends Emitter_1 {
|
|
|
6180
6763
|
* Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the
|
|
6181
6764
|
* callback. The listener is added to the beginning of the listeners array.
|
|
6182
6765
|
*
|
|
6183
|
-
*
|
|
6184
|
-
*
|
|
6185
|
-
* <pre><code>
|
|
6766
|
+
* Note: acknowledgements sent to the server are not included.
|
|
6186
6767
|
*
|
|
6768
|
+
* @example
|
|
6187
6769
|
* socket.prependAnyOutgoing((event, ...args) => {
|
|
6188
|
-
* console.log(event);
|
|
6770
|
+
* console.log(`sent event ${event}`);
|
|
6189
6771
|
* });
|
|
6190
6772
|
*
|
|
6191
|
-
*
|
|
6192
|
-
*
|
|
6193
|
-
* @public
|
|
6773
|
+
* @param listener
|
|
6194
6774
|
*/
|
|
6195
6775
|
prependAnyOutgoing(listener) {
|
|
6196
6776
|
this._anyOutgoingListeners = this._anyOutgoingListeners || [];
|
|
@@ -6200,22 +6780,20 @@ class Socket extends Emitter_1 {
|
|
|
6200
6780
|
/**
|
|
6201
6781
|
* Removes the listener that will be fired when any event is emitted.
|
|
6202
6782
|
*
|
|
6203
|
-
* @
|
|
6204
|
-
*
|
|
6205
|
-
*
|
|
6206
|
-
*
|
|
6207
|
-
* const handler = (event, ...args) => {
|
|
6208
|
-
* console.log(event);
|
|
6783
|
+
* @example
|
|
6784
|
+
* const catchAllListener = (event, ...args) => {
|
|
6785
|
+
* console.log(`sent event ${event}`);
|
|
6209
6786
|
* }
|
|
6210
6787
|
*
|
|
6211
|
-
* socket.onAnyOutgoing(
|
|
6788
|
+
* socket.onAnyOutgoing(catchAllListener);
|
|
6212
6789
|
*
|
|
6213
|
-
* //
|
|
6214
|
-
* socket.offAnyOutgoing(
|
|
6790
|
+
* // remove a specific listener
|
|
6791
|
+
* socket.offAnyOutgoing(catchAllListener);
|
|
6215
6792
|
*
|
|
6216
|
-
*
|
|
6793
|
+
* // or remove all listeners
|
|
6794
|
+
* socket.offAnyOutgoing();
|
|
6217
6795
|
*
|
|
6218
|
-
* @
|
|
6796
|
+
* @param [listener] - the catch-all listener (optional)
|
|
6219
6797
|
*/
|
|
6220
6798
|
offAnyOutgoing(listener) {
|
|
6221
6799
|
if (!this._anyOutgoingListeners) {
|
|
@@ -6238,8 +6816,6 @@ class Socket extends Emitter_1 {
|
|
|
6238
6816
|
/**
|
|
6239
6817
|
* Returns an array of listeners that are listening for any event that is specified. This array can be manipulated,
|
|
6240
6818
|
* e.g. to remove listeners.
|
|
6241
|
-
*
|
|
6242
|
-
* @public
|
|
6243
6819
|
*/
|
|
6244
6820
|
listenersAnyOutgoing() {
|
|
6245
6821
|
return this._anyOutgoingListeners || [];
|
|
@@ -6439,36 +7015,33 @@ class Manager extends Emitter_1 {
|
|
|
6439
7015
|
self.onopen();
|
|
6440
7016
|
fn && fn();
|
|
6441
7017
|
});
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
self._readyState = "closed";
|
|
7018
|
+
const onError = (err) => {
|
|
7019
|
+
this.cleanup();
|
|
7020
|
+
this._readyState = "closed";
|
|
6446
7021
|
this.emitReserved("error", err);
|
|
6447
7022
|
if (fn) {
|
|
6448
7023
|
fn(err);
|
|
6449
7024
|
}
|
|
6450
7025
|
else {
|
|
6451
7026
|
// Only do this if there is no fn to handle the error
|
|
6452
|
-
|
|
7027
|
+
this.maybeReconnectOnOpen();
|
|
6453
7028
|
}
|
|
6454
|
-
}
|
|
7029
|
+
};
|
|
7030
|
+
// emit `error`
|
|
7031
|
+
const errorSub = on(socket, "error", onError);
|
|
6455
7032
|
if (false !== this._timeout) {
|
|
6456
7033
|
const timeout = this._timeout;
|
|
6457
|
-
if (timeout === 0) {
|
|
6458
|
-
openSubDestroy(); // prevents a race condition with the 'open' event
|
|
6459
|
-
}
|
|
6460
7034
|
// set timer
|
|
6461
7035
|
const timer = this.setTimeoutFn(() => {
|
|
6462
7036
|
openSubDestroy();
|
|
7037
|
+
onError(new Error("timeout"));
|
|
6463
7038
|
socket.close();
|
|
6464
|
-
// @ts-ignore
|
|
6465
|
-
socket.emit("error", new Error("timeout"));
|
|
6466
7039
|
}, timeout);
|
|
6467
7040
|
if (this.opts.autoUnref) {
|
|
6468
7041
|
timer.unref();
|
|
6469
7042
|
}
|
|
6470
|
-
this.subs.push(
|
|
6471
|
-
|
|
7043
|
+
this.subs.push(() => {
|
|
7044
|
+
this.clearTimeoutFn(timer);
|
|
6472
7045
|
});
|
|
6473
7046
|
}
|
|
6474
7047
|
this.subs.push(openSubDestroy);
|
|
@@ -6513,7 +7086,12 @@ class Manager extends Emitter_1 {
|
|
|
6513
7086
|
* @private
|
|
6514
7087
|
*/
|
|
6515
7088
|
ondata(data) {
|
|
6516
|
-
|
|
7089
|
+
try {
|
|
7090
|
+
this.decoder.add(data);
|
|
7091
|
+
}
|
|
7092
|
+
catch (e) {
|
|
7093
|
+
this.onclose("parse error", e);
|
|
7094
|
+
}
|
|
6517
7095
|
}
|
|
6518
7096
|
/**
|
|
6519
7097
|
* Called when parser fully decodes a packet.
|
|
@@ -6521,7 +7099,10 @@ class Manager extends Emitter_1 {
|
|
|
6521
7099
|
* @private
|
|
6522
7100
|
*/
|
|
6523
7101
|
ondecoded(packet) {
|
|
6524
|
-
|
|
7102
|
+
// the nextTick call prevents an exception in a user-provided event listener from triggering a disconnection due to a "parse error"
|
|
7103
|
+
nextTick(() => {
|
|
7104
|
+
this.emitReserved("packet", packet);
|
|
7105
|
+
}, this.setTimeoutFn);
|
|
6525
7106
|
}
|
|
6526
7107
|
/**
|
|
6527
7108
|
* Called upon socket error.
|
|
@@ -6543,6 +7124,9 @@ class Manager extends Emitter_1 {
|
|
|
6543
7124
|
socket = new Socket(this, nsp, opts);
|
|
6544
7125
|
this.nsps[nsp] = socket;
|
|
6545
7126
|
}
|
|
7127
|
+
else if (this._autoConnect && !socket.active) {
|
|
7128
|
+
socket.connect();
|
|
7129
|
+
}
|
|
6546
7130
|
return socket;
|
|
6547
7131
|
}
|
|
6548
7132
|
/**
|
|
@@ -6655,8 +7239,8 @@ class Manager extends Emitter_1 {
|
|
|
6655
7239
|
if (this.opts.autoUnref) {
|
|
6656
7240
|
timer.unref();
|
|
6657
7241
|
}
|
|
6658
|
-
this.subs.push(
|
|
6659
|
-
|
|
7242
|
+
this.subs.push(() => {
|
|
7243
|
+
this.clearTimeoutFn(timer);
|
|
6660
7244
|
});
|
|
6661
7245
|
}
|
|
6662
7246
|
}
|