@webex/internal-plugin-mercury 3.0.0-bnr.5 → 3.0.0-next.10
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/.eslintrc.js +6 -0
- package/README.md +14 -1
- package/babel.config.js +3 -0
- package/dist/config.js +1 -2
- package/dist/config.js.map +1 -1
- package/dist/errors.js +8 -11
- package/dist/errors.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mercury.js +75 -63
- package/dist/mercury.js.map +1 -1
- package/dist/socket/index.js.map +1 -1
- package/dist/socket/socket-base.js +57 -42
- package/dist/socket/socket-base.js.map +1 -1
- package/dist/socket/socket.js +1 -2
- package/dist/socket/socket.js.map +1 -1
- package/dist/socket/socket.shim.js +1 -2
- package/dist/socket/socket.shim.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +35 -16
- package/process +1 -0
- package/src/mercury.js +63 -52
- package/src/socket/socket-base.js +61 -28
- package/test/integration/spec/webex.js +3 -2
- package/test/unit/spec/mercury.js +87 -9
- package/test/unit/spec/socket.js +18 -1
- package/dist/types/config.d.ts +0 -10
- package/dist/types/errors.d.ts +0 -31
- package/dist/types/index.d.ts +0 -4
- package/dist/types/mercury.d.ts +0 -2
- package/dist/types/socket/index.d.ts +0 -1
- package/dist/types/socket/socket-base.d.ts +0 -120
- package/dist/types/socket/socket.d.ts +0 -2
- package/dist/types/socket/socket.shim.d.ts +0 -2
- package/test/unit/spec/_setup.js +0 -5
|
@@ -30,6 +30,7 @@ export default class Socket extends EventEmitter {
|
|
|
30
30
|
*/
|
|
31
31
|
constructor() {
|
|
32
32
|
super();
|
|
33
|
+
this._domain = 'unknown-domain';
|
|
33
34
|
this.onmessage = this.onmessage.bind(this);
|
|
34
35
|
this.onclose = this.onclose.bind(this);
|
|
35
36
|
}
|
|
@@ -111,10 +112,10 @@ export default class Socket extends EventEmitter {
|
|
|
111
112
|
return;
|
|
112
113
|
}
|
|
113
114
|
// logger is defined once open is called
|
|
114
|
-
this.logger.info(
|
|
115
|
+
this.logger.info(`socket,${this._domain}: closing`);
|
|
115
116
|
|
|
116
117
|
if (socket.readyState === 2 || socket.readyState === 3) {
|
|
117
|
-
this.logger.info(
|
|
118
|
+
this.logger.info(`socket,${this._domain}: already closed`);
|
|
118
119
|
resolve();
|
|
119
120
|
|
|
120
121
|
return;
|
|
@@ -134,7 +135,7 @@ export default class Socket extends EventEmitter {
|
|
|
134
135
|
|
|
135
136
|
const closeTimer = safeSetTimeout(() => {
|
|
136
137
|
try {
|
|
137
|
-
this.logger.info(
|
|
138
|
+
this.logger.info(`socket,${this._domain}: no close event received, forcing closure`);
|
|
138
139
|
resolve(
|
|
139
140
|
this.onclose({
|
|
140
141
|
code: 1000,
|
|
@@ -142,12 +143,12 @@ export default class Socket extends EventEmitter {
|
|
|
142
143
|
})
|
|
143
144
|
);
|
|
144
145
|
} catch (error) {
|
|
145
|
-
this.logger.warn(
|
|
146
|
+
this.logger.warn(`socket,${this._domain}: force-close failed`, error);
|
|
146
147
|
}
|
|
147
148
|
}, this.forceCloseDelay);
|
|
148
149
|
|
|
149
150
|
socket.onclose = (event) => {
|
|
150
|
-
this.logger.info(
|
|
151
|
+
this.logger.info(`socket,${this._domain}: close event fired`, event.code, event.reason);
|
|
151
152
|
clearTimeout(closeTimer);
|
|
152
153
|
this.onclose(event);
|
|
153
154
|
resolve(event);
|
|
@@ -171,6 +172,12 @@ export default class Socket extends EventEmitter {
|
|
|
171
172
|
* @returns {Promise}
|
|
172
173
|
*/
|
|
173
174
|
open(url, options) {
|
|
175
|
+
try {
|
|
176
|
+
this._domain = new URL(url).hostname;
|
|
177
|
+
} catch {
|
|
178
|
+
this._domain = url;
|
|
179
|
+
}
|
|
180
|
+
|
|
174
181
|
return new Promise((resolve, reject) => {
|
|
175
182
|
/* eslint complexity: [0] */
|
|
176
183
|
if (!url) {
|
|
@@ -201,7 +208,7 @@ export default class Socket extends EventEmitter {
|
|
|
201
208
|
|
|
202
209
|
const WebSocket = Socket.getWebSocketConstructor();
|
|
203
210
|
|
|
204
|
-
this.logger.info(
|
|
211
|
+
this.logger.info(`socket,${this._domain}: creating WebSocket`);
|
|
205
212
|
const socket = new WebSocket(url, [], options);
|
|
206
213
|
|
|
207
214
|
socket.binaryType = 'arraybuffer';
|
|
@@ -209,7 +216,7 @@ export default class Socket extends EventEmitter {
|
|
|
209
216
|
|
|
210
217
|
socket.onclose = (event) => {
|
|
211
218
|
event = this._fixCloseCode(event);
|
|
212
|
-
this.logger.info(
|
|
219
|
+
this.logger.info(`socket,${this._domain}: closed before open`, event.code, event.reason);
|
|
213
220
|
switch (event.code) {
|
|
214
221
|
case 1005:
|
|
215
222
|
// IE 11 doesn't seem to allow 4XXX codes, so if we get a 1005, assume
|
|
@@ -231,10 +238,10 @@ export default class Socket extends EventEmitter {
|
|
|
231
238
|
};
|
|
232
239
|
|
|
233
240
|
socket.onopen = () => {
|
|
234
|
-
this.logger.info(
|
|
241
|
+
this.logger.info(`socket,${this._domain}: connected`);
|
|
235
242
|
this._authorize()
|
|
236
243
|
.then(() => {
|
|
237
|
-
this.logger.info(
|
|
244
|
+
this.logger.info(`socket,${this._domain}: authorized`);
|
|
238
245
|
socket.onclose = this.onclose;
|
|
239
246
|
resolve();
|
|
240
247
|
})
|
|
@@ -242,11 +249,11 @@ export default class Socket extends EventEmitter {
|
|
|
242
249
|
};
|
|
243
250
|
|
|
244
251
|
socket.onerror = (event) => {
|
|
245
|
-
this.logger.warn(
|
|
252
|
+
this.logger.warn(`socket,${this._domain}: error event fired`, event);
|
|
246
253
|
};
|
|
247
254
|
|
|
248
255
|
sockets.set(this, socket);
|
|
249
|
-
this.logger.info(
|
|
256
|
+
this.logger.info(`socket,${this._domain}: waiting for server`);
|
|
250
257
|
});
|
|
251
258
|
}
|
|
252
259
|
|
|
@@ -256,7 +263,7 @@ export default class Socket extends EventEmitter {
|
|
|
256
263
|
* @returns {undefined}
|
|
257
264
|
*/
|
|
258
265
|
onclose(event) {
|
|
259
|
-
this.logger.info(
|
|
266
|
+
this.logger.info(`socket,${this._domain}: closed`, event.code, event.reason);
|
|
260
267
|
clearTimeout(this.pongTimer);
|
|
261
268
|
clearTimeout(this.pingTimer);
|
|
262
269
|
|
|
@@ -278,10 +285,10 @@ export default class Socket extends EventEmitter {
|
|
|
278
285
|
const data = JSON.parse(event.data);
|
|
279
286
|
const sequenceNumber = parseInt(data.sequenceNumber, 10);
|
|
280
287
|
|
|
281
|
-
this.logger.debug(
|
|
288
|
+
this.logger.debug(`socket,${this._domain}: sequence number: `, sequenceNumber);
|
|
282
289
|
if (this.expectedSequenceNumber && sequenceNumber !== this.expectedSequenceNumber) {
|
|
283
290
|
this.logger.debug(
|
|
284
|
-
`socket: sequence number mismatch indicates lost mercury message. expected: ${this.expectedSequenceNumber}, actual: ${sequenceNumber}`
|
|
291
|
+
`socket,${this._domain}: sequence number mismatch indicates lost mercury message. expected: ${this.expectedSequenceNumber}, actual: ${sequenceNumber}`
|
|
285
292
|
);
|
|
286
293
|
this.emit('sequence-mismatch', sequenceNumber, this.expectedSequenceNumber);
|
|
287
294
|
}
|
|
@@ -303,7 +310,7 @@ export default class Socket extends EventEmitter {
|
|
|
303
310
|
// message from Mercury. At this time, the only action we have is to
|
|
304
311
|
// ignore it and move on.
|
|
305
312
|
/* istanbul ignore next */
|
|
306
|
-
this.logger.warn(
|
|
313
|
+
this.logger.warn(`socket,${this._domain}: error while receiving WebSocket message`, error);
|
|
307
314
|
}
|
|
308
315
|
}
|
|
309
316
|
|
|
@@ -357,7 +364,7 @@ export default class Socket extends EventEmitter {
|
|
|
357
364
|
*/
|
|
358
365
|
_authorize() {
|
|
359
366
|
return new Promise((resolve) => {
|
|
360
|
-
this.logger.info(
|
|
367
|
+
this.logger.info(`socket,${this._domain}: authorizing`);
|
|
361
368
|
this.send({
|
|
362
369
|
id: uuid.v4(),
|
|
363
370
|
type: 'authorization',
|
|
@@ -395,12 +402,18 @@ export default class Socket extends EventEmitter {
|
|
|
395
402
|
if (event.code === 1005 && event.reason) {
|
|
396
403
|
switch (event.reason.toLowerCase()) {
|
|
397
404
|
case 'replaced':
|
|
398
|
-
this.logger.info(
|
|
405
|
+
this.logger.info(
|
|
406
|
+
`socket,${this._domain}: fixing CloseEvent code for reason: `,
|
|
407
|
+
event.reason
|
|
408
|
+
);
|
|
399
409
|
event.code = 4000;
|
|
400
410
|
break;
|
|
401
411
|
case 'authentication failed':
|
|
402
412
|
case 'authentication did not happen within the timeout window of 30000 seconds.':
|
|
403
|
-
this.logger.info(
|
|
413
|
+
this.logger.info(
|
|
414
|
+
`socket,${this._domain}: fixing CloseEvent code for reason: `,
|
|
415
|
+
event.reason
|
|
416
|
+
);
|
|
404
417
|
event.code = 1008;
|
|
405
418
|
break;
|
|
406
419
|
default:
|
|
@@ -420,10 +433,12 @@ export default class Socket extends EventEmitter {
|
|
|
420
433
|
_ping(id) {
|
|
421
434
|
const confirmPongId = (event) => {
|
|
422
435
|
try {
|
|
423
|
-
this.logger.debug(
|
|
436
|
+
this.logger.debug(`socket,${this._domain}: pong`, event.data.id);
|
|
424
437
|
if (event.data && event.data.id !== id) {
|
|
425
|
-
this.logger.info(
|
|
426
|
-
|
|
438
|
+
this.logger.info(
|
|
439
|
+
`socket,${this._domain}: received pong for wrong ping id, closing socket`
|
|
440
|
+
);
|
|
441
|
+
this.logger.debug(`socket,${this._domain}: expected`, id, 'received', event.data.id);
|
|
427
442
|
this.close({
|
|
428
443
|
code: 1000,
|
|
429
444
|
reason: 'Pong mismatch',
|
|
@@ -433,24 +448,29 @@ export default class Socket extends EventEmitter {
|
|
|
433
448
|
// This try/catch block was added as a debugging step; to the best of my
|
|
434
449
|
// knowledge, the above can never throw.
|
|
435
450
|
/* istanbul ignore next */
|
|
436
|
-
this.logger.error(
|
|
451
|
+
this.logger.error(`socket,${this._domain}: error occurred in confirmPongId`, error);
|
|
437
452
|
}
|
|
438
453
|
};
|
|
439
454
|
|
|
440
455
|
const onPongNotReceived = () => {
|
|
441
456
|
try {
|
|
442
|
-
this.logger.info(
|
|
457
|
+
this.logger.info(
|
|
458
|
+
`socket,${this._domain}: pong not receive in expected period, closing socket`
|
|
459
|
+
);
|
|
443
460
|
this.close({
|
|
444
461
|
code: 1000,
|
|
445
462
|
reason: 'Pong not received',
|
|
446
463
|
}).catch((reason) => {
|
|
447
|
-
this.logger.warn(
|
|
464
|
+
this.logger.warn(
|
|
465
|
+
`socket,${this._domain}: failed to close socket after missed pong`,
|
|
466
|
+
reason
|
|
467
|
+
);
|
|
448
468
|
});
|
|
449
469
|
} catch (error) {
|
|
450
470
|
// This try/catch block was added as a debugging step; to the best of my
|
|
451
471
|
// knowledge, the above can never throw.
|
|
452
472
|
/* istanbul ignore next */
|
|
453
|
-
this.logger.error(
|
|
473
|
+
this.logger.error(`socket,${this._domain}: error occurred in onPongNotReceived`, error);
|
|
454
474
|
}
|
|
455
475
|
};
|
|
456
476
|
|
|
@@ -462,16 +482,29 @@ export default class Socket extends EventEmitter {
|
|
|
462
482
|
// This try/catch block was added as a debugging step; to the best of my
|
|
463
483
|
// knowledge, the above can never throw.
|
|
464
484
|
/* istanbul ignore next */
|
|
465
|
-
this.logger.error(
|
|
485
|
+
this.logger.error(
|
|
486
|
+
`socket,${this._domain}: error occurred in scheduleNextPingAndCancelPongTimer`,
|
|
487
|
+
error
|
|
488
|
+
);
|
|
466
489
|
}
|
|
467
490
|
};
|
|
468
491
|
|
|
492
|
+
const calculateLatency = (pingTimestamp) => {
|
|
493
|
+
const now = performance.now();
|
|
494
|
+
const latency = now - pingTimestamp;
|
|
495
|
+
|
|
496
|
+
this.logger.debug(`socket,${this._domain}: latency: `, latency);
|
|
497
|
+
this.emit('ping-pong-latency', latency);
|
|
498
|
+
};
|
|
499
|
+
|
|
469
500
|
id = id || uuid.v4();
|
|
501
|
+
const pingTimestamp = performance.now();
|
|
502
|
+
|
|
470
503
|
this.pongTimer = safeSetTimeout(onPongNotReceived, this.pongTimeout);
|
|
471
504
|
this.once('pong', scheduleNextPingAndCancelPongTimer);
|
|
472
505
|
this.once('pong', confirmPongId);
|
|
473
|
-
|
|
474
|
-
this.logger.debug(`socket: ping ${id}`);
|
|
506
|
+
this.once('pong', () => calculateLatency(pingTimestamp));
|
|
507
|
+
this.logger.debug(`socket,${this._domain}: ping ${id}`);
|
|
475
508
|
|
|
476
509
|
return this.send({
|
|
477
510
|
id,
|
|
@@ -32,12 +32,13 @@ describe('plugin-mercury', function () {
|
|
|
32
32
|
);
|
|
33
33
|
|
|
34
34
|
describe('onBeforeLogout()', () => {
|
|
35
|
-
it('disconnects the web socket', () =>
|
|
35
|
+
it('disconnects the web socket', () => {
|
|
36
36
|
webex.logout({noRedirect: true}).then(() => {
|
|
37
37
|
assert.called(webex.internal.mercury.disconnect);
|
|
38
38
|
assert.isFalse(webex.internal.mercury.connected);
|
|
39
39
|
assert.called(webex.internal.device.unregister);
|
|
40
40
|
assert.isFalse(webex.internal.device.registered);
|
|
41
|
-
})
|
|
41
|
+
});
|
|
42
|
+
});
|
|
42
43
|
});
|
|
43
44
|
});
|
|
@@ -152,9 +152,8 @@ describe('plugin-mercury', () => {
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
describe('when `maxRetries` is set', () => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
mercury.config.maxRetries = 2;
|
|
155
|
+
|
|
156
|
+
const check = () => {
|
|
158
157
|
socketOpenStub.restore();
|
|
159
158
|
socketOpenStub = sinon.stub(Socket.prototype, 'open');
|
|
160
159
|
socketOpenStub.returns(Promise.reject(new ConnectionError()));
|
|
@@ -182,12 +181,42 @@ describe('plugin-mercury', () => {
|
|
|
182
181
|
.then(() => {
|
|
183
182
|
assert.calledThrice(Socket.prototype.open);
|
|
184
183
|
clock.tick(5 * mercury.config.backoffTimeReset);
|
|
185
|
-
|
|
186
184
|
return assert.isRejected(promise);
|
|
187
185
|
})
|
|
188
186
|
.then(() => {
|
|
189
187
|
assert.calledThrice(Socket.prototype.open);
|
|
190
188
|
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// skipping due to apparent bug with lolex in all browsers but Chrome.
|
|
192
|
+
// if initial retries is zero and mercury has never connected max retries is used
|
|
193
|
+
skipInBrowser(it)('fails after `maxRetries` attempts', () => {
|
|
194
|
+
mercury.config.maxRetries = 2;
|
|
195
|
+
mercury.config.initialConnectionMaxRetries = 0;
|
|
196
|
+
|
|
197
|
+
return check();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// initial retries is non-zero so takes precedence over maxRetries when mercury has never connected
|
|
201
|
+
skipInBrowser(it)('fails after `initialConnectionMaxRetries` attempts', () => {
|
|
202
|
+
mercury.config.maxRetries = 0;
|
|
203
|
+
mercury.config.initialConnectionMaxRetries = 2;
|
|
204
|
+
return check();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// initial retries is non-zero so takes precedence over maxRetries when mercury has never connected
|
|
208
|
+
skipInBrowser(it)('fails after `initialConnectionMaxRetries` attempts', () => {
|
|
209
|
+
mercury.config.initialConnectionMaxRetries = 2;
|
|
210
|
+
mercury.config.maxRetries = 5;
|
|
211
|
+
return check();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// when mercury has connected maxRetries is used and the initialConnectionMaxRetries is ignored
|
|
215
|
+
skipInBrowser(it)('fails after `initialConnectionMaxRetries` attempts', () => {
|
|
216
|
+
mercury.config.initialConnectionMaxRetries = 5;
|
|
217
|
+
mercury.config.maxRetries = 2;
|
|
218
|
+
mercury.hasEverConnected = true;
|
|
219
|
+
return check();
|
|
191
220
|
});
|
|
192
221
|
});
|
|
193
222
|
|
|
@@ -541,7 +570,10 @@ describe('plugin-mercury', () => {
|
|
|
541
570
|
// The socket will never be unset (which seems bad)
|
|
542
571
|
assert.isDefined(mercury.socket, 'Mercury socket is not defined');
|
|
543
572
|
|
|
544
|
-
return assert.isRejected(promise)
|
|
573
|
+
return assert.isRejected(promise).then((error) => {
|
|
574
|
+
// connection did not fail, so no last error
|
|
575
|
+
assert.isUndefined(mercury.getLastError());
|
|
576
|
+
});
|
|
545
577
|
});
|
|
546
578
|
});
|
|
547
579
|
|
|
@@ -560,20 +592,53 @@ describe('plugin-mercury', () => {
|
|
|
560
592
|
return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
|
|
561
593
|
assert.equal(
|
|
562
594
|
reason.message,
|
|
563
|
-
'
|
|
595
|
+
'Mercury: prevent socket open when backoffCall no longer defined'
|
|
564
596
|
);
|
|
565
597
|
});
|
|
566
598
|
});
|
|
599
|
+
|
|
600
|
+
it('sets lastError when retrying', () => {
|
|
601
|
+
const realError = new Error('FORCED');
|
|
602
|
+
|
|
603
|
+
socketOpenStub.restore();
|
|
604
|
+
socketOpenStub = sinon.stub(Socket.prototype, 'open');
|
|
605
|
+
socketOpenStub.onCall(0).returns(Promise.reject(realError));
|
|
606
|
+
const promise = mercury.connect();
|
|
607
|
+
|
|
608
|
+
// Wait for the connect call to setup
|
|
609
|
+
return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
|
|
610
|
+
// Calling disconnect will abort the backoffCall, close the socket, and
|
|
611
|
+
// reject the connect
|
|
612
|
+
mercury.disconnect();
|
|
613
|
+
|
|
614
|
+
return assert.isRejected(promise).then((error) => {
|
|
615
|
+
const lastError = mercury.getLastError();
|
|
616
|
+
|
|
617
|
+
assert.equal(error.message, "Mercury Connection Aborted");
|
|
618
|
+
assert.isDefined(lastError);
|
|
619
|
+
assert.equal(lastError, realError);
|
|
620
|
+
});
|
|
621
|
+
});
|
|
622
|
+
});
|
|
567
623
|
});
|
|
568
624
|
});
|
|
569
625
|
|
|
570
626
|
describe('#_emit()', () => {
|
|
571
|
-
it('emits Error-safe events', () => {
|
|
627
|
+
it('emits Error-safe events and log the error with the call parameters', () => {
|
|
628
|
+
const error = 'error';
|
|
629
|
+
const event = {data: 'some data'};
|
|
572
630
|
mercury.on('break', () => {
|
|
573
|
-
throw
|
|
631
|
+
throw error;
|
|
574
632
|
});
|
|
633
|
+
sinon.stub(mercury.logger, 'error');
|
|
575
634
|
|
|
576
|
-
return Promise.resolve(mercury._emit('break'))
|
|
635
|
+
return Promise.resolve(mercury._emit('break', event)).then((res) => {
|
|
636
|
+
assert.calledWith(mercury.logger.error, 'Mercury: error occurred in event handler', {
|
|
637
|
+
error,
|
|
638
|
+
arguments: ['break', event],
|
|
639
|
+
});
|
|
640
|
+
return res;
|
|
641
|
+
});
|
|
577
642
|
});
|
|
578
643
|
});
|
|
579
644
|
|
|
@@ -707,5 +772,18 @@ describe('plugin-mercury', () => {
|
|
|
707
772
|
.then((wsUrl) => assert.match(wsUrl, /multipleConnections/)));
|
|
708
773
|
});
|
|
709
774
|
});
|
|
775
|
+
|
|
776
|
+
describe('ping pong latency event is forwarded', () => {
|
|
777
|
+
it('should forward ping pong latency event', () => {
|
|
778
|
+
const spy = sinon.spy();
|
|
779
|
+
|
|
780
|
+
mercury.on('ping-pong-latency', spy);
|
|
781
|
+
|
|
782
|
+
return mercury.connect().then(() => {
|
|
783
|
+
assert.calledWith(spy, 0);
|
|
784
|
+
assert.calledOnce(spy);
|
|
785
|
+
});
|
|
786
|
+
});
|
|
787
|
+
});
|
|
710
788
|
});
|
|
711
789
|
});
|
package/test/unit/spec/socket.js
CHANGED
|
@@ -39,7 +39,7 @@ describe('plugin-mercury', () => {
|
|
|
39
39
|
clock.uninstall();
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
beforeEach(
|
|
42
|
+
beforeEach(() => {
|
|
43
43
|
sinon.stub(Socket, 'getWebSocketConstructor').callsFake(
|
|
44
44
|
() =>
|
|
45
45
|
function (...args) {
|
|
@@ -809,6 +809,23 @@ describe('plugin-mercury', () => {
|
|
|
809
809
|
reason: 'Pong mismatch',
|
|
810
810
|
});
|
|
811
811
|
});
|
|
812
|
+
|
|
813
|
+
it('emits ping pong latency correctly', () => {
|
|
814
|
+
const spy = sinon.spy();
|
|
815
|
+
|
|
816
|
+
socket.on('ping-pong-latency', spy);
|
|
817
|
+
|
|
818
|
+
socket._ping(123);
|
|
819
|
+
mockWebSocket.emit('message', {
|
|
820
|
+
data: JSON.stringify({
|
|
821
|
+
type: 'pong',
|
|
822
|
+
id: 123,
|
|
823
|
+
}),
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
assert.calledWith(spy, 0);
|
|
827
|
+
assert.calledOnce(spy);
|
|
828
|
+
});
|
|
812
829
|
});
|
|
813
830
|
});
|
|
814
831
|
});
|
package/dist/types/config.d.ts
DELETED
package/dist/types/errors.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exception thrown when a websocket gets closed
|
|
3
|
-
*/
|
|
4
|
-
export class ConnectionError {
|
|
5
|
-
static defaultMessage: string;
|
|
6
|
-
/**
|
|
7
|
-
* @param {CloseEvent} event
|
|
8
|
-
* @returns {string}
|
|
9
|
-
*/
|
|
10
|
-
parse(event?: CloseEvent): string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* thrown for CloseCode 4400
|
|
14
|
-
*/
|
|
15
|
-
export class UnknownResponse extends ConnectionError {
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* thrown for CloseCode 4400
|
|
19
|
-
*/
|
|
20
|
-
export class BadRequest extends ConnectionError {
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* thrown for CloseCode 4401
|
|
24
|
-
*/
|
|
25
|
-
export class NotAuthorized extends ConnectionError {
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* thrown for CloseCode 4403
|
|
29
|
-
*/
|
|
30
|
-
export class Forbidden extends ConnectionError {
|
|
31
|
-
}
|
package/dist/types/index.d.ts
DELETED
package/dist/types/mercury.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from "./socket";
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generalized socket abstraction
|
|
3
|
-
*/
|
|
4
|
-
export default class Socket extends EventEmitter {
|
|
5
|
-
/**
|
|
6
|
-
* Provides the environmentally appropriate constructor (ws in NodeJS,
|
|
7
|
-
* WebSocket in browsers)
|
|
8
|
-
* @returns {WebSocket}
|
|
9
|
-
*/
|
|
10
|
-
static getWebSocketConstructor(): WebSocket;
|
|
11
|
-
/**
|
|
12
|
-
* constructor
|
|
13
|
-
* @returns {Socket}
|
|
14
|
-
*/
|
|
15
|
-
constructor();
|
|
16
|
-
/**
|
|
17
|
-
* Handles incoming message events
|
|
18
|
-
* @param {MessageEvent} event
|
|
19
|
-
* @returns {undefined}
|
|
20
|
-
*/
|
|
21
|
-
onmessage(event: MessageEvent): undefined;
|
|
22
|
-
/**
|
|
23
|
-
* Handles incoming CloseEvents
|
|
24
|
-
* @param {CloseEvent} event
|
|
25
|
-
* @returns {undefined}
|
|
26
|
-
*/
|
|
27
|
-
onclose(event: CloseEvent): undefined;
|
|
28
|
-
/**
|
|
29
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
get binaryType(): string;
|
|
33
|
-
/**
|
|
34
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
35
|
-
* @returns {number}
|
|
36
|
-
*/
|
|
37
|
-
get bufferedAmount(): number;
|
|
38
|
-
/**
|
|
39
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
40
|
-
* @returns {string}
|
|
41
|
-
*/
|
|
42
|
-
get extensions(): string;
|
|
43
|
-
/**
|
|
44
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
45
|
-
* @returns {string}
|
|
46
|
-
*/
|
|
47
|
-
get protocol(): string;
|
|
48
|
-
/**
|
|
49
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
50
|
-
* @returns {number}
|
|
51
|
-
*/
|
|
52
|
-
get readyState(): number;
|
|
53
|
-
/**
|
|
54
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
55
|
-
* @returns {string}
|
|
56
|
-
*/
|
|
57
|
-
get url(): string;
|
|
58
|
-
/**
|
|
59
|
-
* Closes the socket
|
|
60
|
-
* @param {Object} options
|
|
61
|
-
* @param {string} options.reason
|
|
62
|
-
* @param {number} options.code
|
|
63
|
-
* @returns {Promise}
|
|
64
|
-
*/
|
|
65
|
-
close(options: {
|
|
66
|
-
reason: string;
|
|
67
|
-
code: number;
|
|
68
|
-
}): Promise<any>;
|
|
69
|
-
/**
|
|
70
|
-
* Opens a WebSocket
|
|
71
|
-
* @param {string} url
|
|
72
|
-
* @param {options} options
|
|
73
|
-
* @param {number} options.forceCloseDelay (required)
|
|
74
|
-
* @param {number} options.pingInterval (required)
|
|
75
|
-
* @param {number} options.pongTimeout (required)
|
|
76
|
-
* @param {string} options.token (required)
|
|
77
|
-
* @param {string} options.trackingId (required)
|
|
78
|
-
* @param {Logger} options.logger (required)
|
|
79
|
-
* @param {string} options.logLevelToken
|
|
80
|
-
* @returns {Promise}
|
|
81
|
-
*/
|
|
82
|
-
open(url: string, options: any): Promise<any>;
|
|
83
|
-
expectedSequenceNumber: any;
|
|
84
|
-
/**
|
|
85
|
-
* Sends a message up the socket
|
|
86
|
-
* @param {mixed} data
|
|
87
|
-
* @returns {Promise}
|
|
88
|
-
*/
|
|
89
|
-
send(data: mixed): Promise<any>;
|
|
90
|
-
/**
|
|
91
|
-
* Sends an acknowledgment for a specific event
|
|
92
|
-
* @param {MessageEvent} event
|
|
93
|
-
* @returns {Promise}
|
|
94
|
-
*/
|
|
95
|
-
_acknowledge(event: MessageEvent): Promise<any>;
|
|
96
|
-
/**
|
|
97
|
-
* Sends an auth message up the socket
|
|
98
|
-
* @private
|
|
99
|
-
* @returns {Promise}
|
|
100
|
-
*/
|
|
101
|
-
private _authorize;
|
|
102
|
-
/**
|
|
103
|
-
* Deals with the fact that some browsers drop some close codes (but not
|
|
104
|
-
* close reasons).
|
|
105
|
-
* @param {CloseEvent} event
|
|
106
|
-
* @private
|
|
107
|
-
* @returns {CloseEvent}
|
|
108
|
-
*/
|
|
109
|
-
private _fixCloseCode;
|
|
110
|
-
/**
|
|
111
|
-
* Sends a ping up the socket and confirms we get it back
|
|
112
|
-
* @param {[type]} id
|
|
113
|
-
* @private
|
|
114
|
-
* @returns {[type]}
|
|
115
|
-
*/
|
|
116
|
-
private _ping;
|
|
117
|
-
pingTimer: any;
|
|
118
|
-
pongTimer: any;
|
|
119
|
-
}
|
|
120
|
-
import { EventEmitter } from "events";
|