@webex/internal-plugin-mercury 3.8.1-web-workers-keepalive.1 → 3.9.0-multiple-llm.1

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.
@@ -33,6 +33,8 @@ export default class Socket extends EventEmitter {
33
33
  this._domain = 'unknown-domain';
34
34
  this.onmessage = this.onmessage.bind(this);
35
35
  this.onclose = this.onclose.bind(this);
36
+ // Increase max listeners to avoid memory leak warning in tests
37
+ this.setMaxListeners(5);
36
38
  }
37
39
 
38
40
  /**
@@ -358,9 +360,20 @@ export default class Socket extends EventEmitter {
358
360
  return Promise.reject(new Error('`event.data.id` is required'));
359
361
  }
360
362
 
363
+ // Don't try to acknowledge if socket is not in open state
364
+ if (this.readyState !== 1) {
365
+ return Promise.resolve(); // Silently ignore acknowledgment for closed sockets
366
+ }
367
+
361
368
  return this.send({
362
369
  messageId: event.data.id,
363
370
  type: 'ack',
371
+ }).catch((error) => {
372
+ // Gracefully handle send errors (like INVALID_STATE_ERROR) to prevent test issues
373
+ if (error.message === 'INVALID_STATE_ERROR') {
374
+ return Promise.resolve(); // Socket was closed, ignore the acknowledgment
375
+ }
376
+ throw error; // Re-throw other errors
364
377
  });
365
378
  }
366
379
 
@@ -38,14 +38,31 @@ describe('plugin-mercury', () => {
38
38
  },
39
39
  timestamp: Date.now(),
40
40
  trackingId: `suffix_${uuid.v4()}_${Date.now()}`,
41
+ sessionId: 'mercury-default-session',
41
42
  };
42
43
 
43
44
  beforeEach(() => {
44
45
  clock = FakeTimers.install({now: Date.now()});
45
46
  });
46
47
 
47
- afterEach(() => {
48
+ afterEach(async () => {
48
49
  clock.uninstall();
50
+ // Clean up mercury socket and mockWebSocket
51
+ if (mercury && mercury.socket) {
52
+ try {
53
+ await mercury.socket.close();
54
+ } catch (e) {}
55
+ }
56
+ if (mockWebSocket && typeof mockWebSocket.close === 'function') {
57
+ mockWebSocket.close();
58
+ }
59
+ // Restore stubs
60
+ if (Socket.getWebSocketConstructor.restore) {
61
+ Socket.getWebSocketConstructor.restore();
62
+ }
63
+ if (socketOpenStub && socketOpenStub.restore) {
64
+ socketOpenStub.restore();
65
+ }
49
66
  });
50
67
 
51
68
  beforeEach(() => {
@@ -76,6 +93,7 @@ describe('plugin-mercury', () => {
76
93
  });
77
94
 
78
95
  mercury = webex.internal.mercury;
96
+ mercury.defaultSessionId = 'mercury-default-session';
79
97
  });
80
98
 
81
99
  afterEach(() => {
@@ -301,7 +319,7 @@ describe('plugin-mercury', () => {
301
319
  })
302
320
  .then(() => {
303
321
  assert.called(offlineSpy);
304
- assert.calledWith(offlineSpy, {code, reason});
322
+ assert.calledWith(offlineSpy, {code, reason, sessionId: 'mercury-default-session'});
305
323
  switch (action) {
306
324
  case 'close':
307
325
  assert.called(permanentSpy);
@@ -97,9 +97,32 @@ describe('plugin-mercury', () => {
97
97
  });
98
98
 
99
99
  mercury = webex.internal.mercury;
100
+ mercury.defaultSessionId = 'mercury-default-session';
100
101
  });
101
102
 
102
- afterEach(() => {
103
+ afterEach(async () => {
104
+ // Clean up Mercury connections and internal state
105
+ if (mercury) {
106
+ try {
107
+ await mercury.disconnectAll();
108
+ } catch (e) {
109
+ // Ignore cleanup errors
110
+ }
111
+ // Clear any remaining connection promises
112
+ if (mercury._connectPromises) {
113
+ mercury._connectPromises.clear();
114
+ }
115
+ }
116
+
117
+ // Ensure mock socket is properly closed
118
+ if (mockWebSocket && typeof mockWebSocket.close === 'function') {
119
+ try {
120
+ mockWebSocket.close();
121
+ } catch (e) {
122
+ // Ignore cleanup errors
123
+ }
124
+ }
125
+
103
126
  if (socketOpenStub) {
104
127
  socketOpenStub.restore();
105
128
  }
@@ -107,6 +130,9 @@ describe('plugin-mercury', () => {
107
130
  if (Socket.getWebSocketConstructor.restore) {
108
131
  Socket.getWebSocketConstructor.restore();
109
132
  }
133
+
134
+ // Small delay to ensure all async operations complete
135
+ await new Promise(resolve => setTimeout(resolve, 10));
110
136
  });
111
137
 
112
138
  describe('#listen()', () => {
@@ -436,9 +462,13 @@ describe('plugin-mercury', () => {
436
462
 
437
463
  // skipping due to apparent bug with lolex in all browsers but Chrome.
438
464
  skipInBrowser(it)('does not continue attempting to connect', () => {
439
- mercury.connect();
465
+ const promise = mercury.connect();
466
+
467
+ // Wait for the connection to be established before proceeding
468
+ mockWebSocket.open();
440
469
 
441
- return promiseTick(2)
470
+ return promise.then(() =>
471
+ promiseTick(2)
442
472
  .then(() => {
443
473
  clock.tick(6 * webex.internal.mercury.config.backoffTimeReset);
444
474
 
@@ -446,7 +476,8 @@ describe('plugin-mercury', () => {
446
476
  })
447
477
  .then(() => {
448
478
  assert.calledOnce(Socket.prototype.open);
449
- });
479
+ })
480
+ );
450
481
  });
451
482
  });
452
483
 
@@ -521,11 +552,11 @@ describe('plugin-mercury', () => {
521
552
  });
522
553
 
523
554
  describe('#logout()', () => {
524
- it('calls disconnect and logs', () => {
555
+ it('calls disconnectAll and logs', () => {
525
556
  sinon.stub(mercury.logger, 'info');
526
- sinon.stub(mercury, 'disconnect');
557
+ sinon.stub(mercury, 'disconnectAll');
527
558
  mercury.logout();
528
- assert.called(mercury.disconnect);
559
+ assert.called(mercury.disconnectAll);
529
560
  assert.calledTwice(mercury.logger.info);
530
561
 
531
562
  assert.calledWith(mercury.logger.info.getCall(0), 'Mercury: logout() called');
@@ -537,24 +568,24 @@ describe('plugin-mercury', () => {
537
568
  });
538
569
 
539
570
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout', () => {
540
- sinon.stub(mercury, 'disconnect');
571
+ sinon.stub(mercury, 'disconnectAll');
541
572
  mercury.config.beforeLogoutOptionsCloseReason = 'done (permanent)';
542
573
  mercury.logout();
543
- assert.calledWith(mercury.disconnect, {code: 3050, reason: 'done (permanent)'});
574
+ assert.calledWith(mercury.disconnectAll, {code: 3050, reason: 'done (permanent)'});
544
575
  });
545
576
 
546
577
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send code 3050 for logout if the reason is different than standard', () => {
547
- sinon.stub(mercury, 'disconnect');
578
+ sinon.stub(mercury, 'disconnectAll');
548
579
  mercury.config.beforeLogoutOptionsCloseReason = 'test';
549
580
  mercury.logout();
550
- assert.calledWith(mercury.disconnect, {code: 3050, reason: 'test'});
581
+ assert.calledWith(mercury.disconnectAll, {code: 3050, reason: 'test'});
551
582
  });
552
583
 
553
584
  it('uses the config.beforeLogoutOptionsCloseReason to disconnect and will send undefined for logout if the reason is same as standard', () => {
554
- sinon.stub(mercury, 'disconnect');
585
+ sinon.stub(mercury, 'disconnectAll');
555
586
  mercury.config.beforeLogoutOptionsCloseReason = 'done (forced)';
556
587
  mercury.logout();
557
- assert.calledWith(mercury.disconnect, undefined);
588
+ assert.calledWith(mercury.disconnectAll, undefined);
558
589
  });
559
590
  });
560
591
 
@@ -660,12 +691,12 @@ describe('plugin-mercury', () => {
660
691
  return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
661
692
  // By this time backoffCall and mercury socket should be defined by the
662
693
  // 'connect' call
663
- assert.isDefined(mercury.backoffCall, 'Mercury backoffCall is not defined');
694
+ assert.isDefined(mercury.backoffCalls.get('mercury-default-session'), 'Mercury backoffCall is not defined');
664
695
  assert.isDefined(mercury.socket, 'Mercury socket is not defined');
665
696
  // Calling disconnect will abort the backoffCall, close the socket, and
666
697
  // reject the connect
667
698
  mercury.disconnect();
668
- assert.isUndefined(mercury.backoffCall, 'Mercury backoffCall is still defined');
699
+ assert.isUndefined(mercury.backoffCalls.get('mercury-default-session'), 'Mercury backoffCall is still defined');
669
700
  // The socket will never be unset (which seems bad)
670
701
  assert.isDefined(mercury.socket, 'Mercury socket is not defined');
671
702
 
@@ -683,15 +714,15 @@ describe('plugin-mercury', () => {
683
714
 
684
715
  let reason;
685
716
 
686
- mercury.backoffCall = undefined;
687
- mercury._attemptConnection('ws://example.com', (_reason) => {
717
+ mercury.backoffCalls.clear();
718
+ mercury._attemptConnection('ws://example.com', 'mercury-default-session',(_reason) => {
688
719
  reason = _reason;
689
720
  });
690
721
 
691
722
  return promiseTick(webex.internal.mercury.config.backoffTimeReset).then(() => {
692
723
  assert.equal(
693
724
  reason.message,
694
- 'Mercury: prevent socket open when backoffCall no longer defined'
725
+ `Mercury: prevent socket open when backoffCall no longer defined for ${mercury.defaultSessionId}`
695
726
  );
696
727
  });
697
728
  });
@@ -713,7 +744,7 @@ describe('plugin-mercury', () => {
713
744
  return assert.isRejected(promise).then((error) => {
714
745
  const lastError = mercury.getLastError();
715
746
 
716
- assert.equal(error.message, 'Mercury Connection Aborted');
747
+ assert.equal(error.message, `Mercury Connection Aborted for ${mercury.defaultSessionId}`);
717
748
  assert.isDefined(lastError);
718
749
  assert.equal(lastError, realError);
719
750
  });
@@ -807,7 +838,7 @@ describe('plugin-mercury', () => {
807
838
  },
808
839
  };
809
840
  assert.isUndefined(mercury.mercuryTimeOffset);
810
- mercury._setTimeOffset(event);
841
+ mercury._setTimeOffset('mercury-default-session', event);
811
842
  assert.isDefined(mercury.mercuryTimeOffset);
812
843
  assert.isTrue(mercury.mercuryTimeOffset > 0);
813
844
  });
@@ -817,7 +848,7 @@ describe('plugin-mercury', () => {
817
848
  wsWriteTimestamp: Date.now() + 60000,
818
849
  },
819
850
  };
820
- mercury._setTimeOffset(event);
851
+ mercury._setTimeOffset('mercury-default-session', event);
821
852
  assert.isTrue(mercury.mercuryTimeOffset < 0);
822
853
  });
823
854
  it('handles invalid wsWriteTimestamp', () => {
@@ -828,7 +859,7 @@ describe('plugin-mercury', () => {
828
859
  wsWriteTimestamp: invalidTimestamp,
829
860
  },
830
861
  };
831
- mercury._setTimeOffset(event);
862
+ mercury._setTimeOffset('mercury-default-session', event);
832
863
  assert.isUndefined(mercury.mercuryTimeOffset);
833
864
  });
834
865
  });