@wazo/sdk 0.37.28 → 0.37.32

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.
Files changed (81) hide show
  1. package/README.md +2 -1
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/api-client.test.js +30 -0
  4. package/esm/__tests__/web-rtc-client.test.js +65 -6
  5. package/esm/api/calld.js +30 -0
  6. package/esm/api-client.js +30 -0
  7. package/esm/checker/Checker.js +65 -6
  8. package/esm/checker/checks/aor.js +30 -0
  9. package/esm/checker/checks/api.js +30 -0
  10. package/esm/checker/checks/index.js +65 -6
  11. package/esm/checker/checks/webrtc-transport.js +65 -6
  12. package/esm/checker/checks/webrtc.js +65 -6
  13. package/esm/domain/AdHocAPIConference.js +30 -0
  14. package/esm/domain/CallSession.js +15 -3
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +45 -3
  18. package/esm/domain/Phone/WebRTCPhone.js +28 -6
  19. package/esm/domain/__tests__/CallSession.test.js +32 -3
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +15 -3
  21. package/esm/domain/__tests__/Room.test.js +15 -3
  22. package/esm/index.js +93 -12
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +93 -12
  26. package/esm/simple/Configuration.js +93 -12
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +93 -12
  29. package/esm/simple/index.js +93 -12
  30. package/esm/simple/room/LocalParticipant.js +93 -12
  31. package/esm/simple/room/Participant.js +93 -12
  32. package/esm/simple/room/RemoteParticipant.js +93 -12
  33. package/esm/simple/room/Room.js +93 -12
  34. package/esm/simple/room/SipRoom.js +93 -12
  35. package/esm/simple/room/Stream.js +93 -12
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  37. package/esm/simple/utils.js +93 -12
  38. package/esm/web-rtc-client.js +65 -6
  39. package/lib/__tests__/api-client.test.js +30 -0
  40. package/lib/__tests__/web-rtc-client.test.js +65 -6
  41. package/lib/api/calld.js +30 -0
  42. package/lib/api-client.js +30 -0
  43. package/lib/checker/Checker.js +65 -6
  44. package/lib/checker/checks/aor.js +30 -0
  45. package/lib/checker/checks/api.js +30 -0
  46. package/lib/checker/checks/index.js +65 -6
  47. package/lib/checker/checks/webrtc-transport.js +65 -6
  48. package/lib/checker/checks/webrtc.js +65 -6
  49. package/lib/domain/AdHocAPIConference.js +30 -0
  50. package/lib/domain/CallSession.js +15 -3
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +45 -3
  54. package/lib/domain/Phone/WebRTCPhone.js +28 -6
  55. package/lib/domain/__tests__/CallSession.test.js +32 -3
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +15 -3
  57. package/lib/domain/__tests__/Room.test.js +15 -3
  58. package/lib/index.js +93 -12
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +93 -12
  62. package/lib/simple/Configuration.js +93 -12
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +93 -12
  65. package/lib/simple/index.js +93 -12
  66. package/lib/simple/room/LocalParticipant.js +93 -12
  67. package/lib/simple/room/Participant.js +93 -12
  68. package/lib/simple/room/RemoteParticipant.js +93 -12
  69. package/lib/simple/room/Room.js +93 -12
  70. package/lib/simple/room/SipRoom.js +93 -12
  71. package/lib/simple/room/Stream.js +93 -12
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  73. package/lib/simple/utils.js +93 -12
  74. package/lib/web-rtc-client.js +65 -6
  75. package/package.json +1 -1
  76. package/src/api/calld.js +3 -0
  77. package/src/domain/CallSession.js +16 -4
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +13 -3
  80. package/src/domain/__tests__/CallSession.test.js +17 -0
  81. package/src/web-rtc-client.js +35 -6
@@ -4016,6 +4016,34 @@ var chatdMethods = (client , baseUrl ) => ({
4016
4016
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4017
4017
  });
4018
4018
 
4019
+ //
4020
+
4021
+
4022
+
4023
+
4024
+
4025
+ class MeetingStatus {
4026
+
4027
+
4028
+
4029
+
4030
+ constructor({
4031
+ full,
4032
+ } = {}) {
4033
+ this.full = full;
4034
+
4035
+ // Useful to compare instead of instanceof with minified code
4036
+ this.type = 'MeetingStatus';
4037
+ }
4038
+
4039
+ static parse(plain ) {
4040
+ return new MeetingStatus({
4041
+ full: plain.full,
4042
+ });
4043
+ }
4044
+
4045
+ }
4046
+
4019
4047
  /* */
4020
4048
 
4021
4049
 
@@ -4210,6 +4238,8 @@ var calldMethods = (client , baseUrl ) => ({
4210
4238
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4211
4239
  ApiRequester.successResponseParser),
4212
4240
 
4241
+ guestGetMeetingStatus: (meetingUuid ) =>
4242
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4213
4243
  });
4214
4244
 
4215
4245
  //
@@ -3248,6 +3248,7 @@ var updateFrom = (instance , from ) => {
3248
3248
 
3249
3249
 
3250
3250
 
3251
+
3251
3252
 
3252
3253
 
3253
3254
 
@@ -3295,14 +3296,14 @@ class CallSession {
3295
3296
 
3296
3297
 
3297
3298
 
3299
+ // = creationTime
3300
+
3298
3301
 
3299
3302
 
3300
3303
 
3301
3304
 
3302
3305
 
3303
3306
 
3304
-
3305
-
3306
3307
 
3307
3308
 
3308
3309
 
@@ -3366,6 +3367,7 @@ class CallSession {
3366
3367
  recordingPaused,
3367
3368
  videoRemotelyDowngraded,
3368
3369
  sipSession,
3370
+ answerTime,
3369
3371
  } ) {
3370
3372
  this.callId = callId;
3371
3373
  this.sipCallId = sipCallId;
@@ -3393,6 +3395,7 @@ class CallSession {
3393
3395
  this.recordingPaused = recordingPaused || false;
3394
3396
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3395
3397
  this.sipSession = sipSession;
3398
+ this.answerTime = answerTime || this.answerTime;
3396
3399
 
3397
3400
  // Useful to compare instead of instanceof with minified code
3398
3401
  this.type = 'CallSession';
@@ -3423,7 +3426,7 @@ class CallSession {
3423
3426
  }
3424
3427
 
3425
3428
  answer() {
3426
- this.answered = true;
3429
+ this.answerTime = new Date();
3427
3430
  }
3428
3431
 
3429
3432
  systemAnswer() {
@@ -3579,6 +3582,15 @@ class CallSession {
3579
3582
  return newFrom(callSession, CallSession);
3580
3583
  }
3581
3584
 
3585
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3586
+ set answered(value ) {
3587
+ this.answerTime = value ? this.answerTime || new Date() : null;
3588
+ }
3589
+
3590
+ get answered() {
3591
+ return !!this.answerTime;
3592
+ }
3593
+
3582
3594
  static parseCall(call ) {
3583
3595
  return new CallSession({
3584
3596
  callId: call.id,
@@ -4830,6 +4842,34 @@ var chatdMethods = (client , baseUrl ) => ({
4830
4842
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4831
4843
  });
4832
4844
 
4845
+ //
4846
+
4847
+
4848
+
4849
+
4850
+
4851
+ class MeetingStatus {
4852
+
4853
+
4854
+
4855
+
4856
+ constructor({
4857
+ full,
4858
+ } = {}) {
4859
+ this.full = full;
4860
+
4861
+ // Useful to compare instead of instanceof with minified code
4862
+ this.type = 'MeetingStatus';
4863
+ }
4864
+
4865
+ static parse(plain ) {
4866
+ return new MeetingStatus({
4867
+ full: plain.full,
4868
+ });
4869
+ }
4870
+
4871
+ }
4872
+
4833
4873
  /* */
4834
4874
 
4835
4875
 
@@ -5024,6 +5064,8 @@ var calldMethods = (client , baseUrl ) => ({
5024
5064
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5025
5065
  ApiRequester.successResponseParser),
5026
5066
 
5067
+ guestGetMeetingStatus: (meetingUuid ) =>
5068
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5027
5069
  });
5028
5070
 
5029
5071
  //
@@ -6361,6 +6403,7 @@ const MAX_REGISTER_TRIES = 10;
6361
6403
 
6362
6404
 
6363
6405
 
6406
+
6364
6407
 
6365
6408
 
6366
6409
 
@@ -6402,6 +6445,7 @@ class WebRTCClient extends Emitter {
6402
6445
 
6403
6446
 
6404
6447
 
6448
+
6405
6449
 
6406
6450
  // sugar
6407
6451
 
@@ -6464,6 +6508,7 @@ class WebRTCClient extends Emitter {
6464
6508
  this.conferences = {};
6465
6509
  this.networkMonitoringInterval = {};
6466
6510
  this.sessionNetworkStats = {};
6511
+ this.forceClosed = false;
6467
6512
 
6468
6513
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6469
6514
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6585,6 +6630,8 @@ class WebRTCClient extends Emitter {
6585
6630
  skipRegister: this.skipRegister,
6586
6631
  };
6587
6632
 
6633
+ this.forceClosed = false;
6634
+
6588
6635
  if (this.skipRegister) {
6589
6636
  logger$9.info('sdk webrtc skip register...', logInfo);
6590
6637
  return Promise.resolve();
@@ -6609,7 +6656,15 @@ class WebRTCClient extends Emitter {
6609
6656
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6610
6657
 
6611
6658
  const onRegisterFailed = () => {
6612
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6659
+ logger$9.info('sdk webrtc registering failed', {
6660
+ tries,
6661
+ registerer: !!this.registerer,
6662
+ forceClosed: this.forceClosed,
6663
+ });
6664
+ if (this.forceClosed) {
6665
+ return;
6666
+ }
6667
+
6613
6668
  this.connectionPromise = null;
6614
6669
  if (this.registerer && this.registerer.waiting) {
6615
6670
  this.registerer.waitingToggle(false);
@@ -6887,8 +6942,9 @@ class WebRTCClient extends Emitter {
6887
6942
  }
6888
6943
  }
6889
6944
 
6890
- async close() {
6891
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6945
+ async close(force = false) {
6946
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6947
+ this.forceClosed = force;
6892
6948
  this._cleanupMedia();
6893
6949
  this.connectionPromise = null;
6894
6950
 
@@ -6907,7 +6963,7 @@ class WebRTCClient extends Emitter {
6907
6963
  this.userAgent.delegate = null;
6908
6964
  this.userAgent.stateChange.removeAllListeners();
6909
6965
 
6910
- await this._disconnectTransport();
6966
+ await this._disconnectTransport(force);
6911
6967
 
6912
6968
  this._cleanupRegister();
6913
6969
 
@@ -7977,6 +8033,13 @@ class WebRTCClient extends Emitter {
7977
8033
  }
7978
8034
 
7979
8035
  _createWebRTCConfiguration(configOverrides = {}) {
8036
+ let { host } = this.config;
8037
+ let port = this.config.port || 443;
8038
+
8039
+ if (this.config.websocketSip) {
8040
+ [host, port = 443] = this.config.websocketSip.split(':');
8041
+ }
8042
+
7980
8043
  const config = {
7981
8044
  authorizationUsername: this.config.authorizationUser,
7982
8045
  authorizationPassword: this.config.password,
@@ -8012,7 +8075,7 @@ class WebRTCClient extends Emitter {
8012
8075
  },
8013
8076
  transportOptions: {
8014
8077
  traceSip: configOverrides.traceSip || false,
8015
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8078
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8016
8079
  },
8017
8080
  sessionDescriptionHandlerFactoryOptions: {
8018
8081
  modifiers: [replaceLocalIpModifier],
@@ -8336,7 +8399,15 @@ class WebRTCClient extends Emitter {
8336
8399
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8337
8400
  }
8338
8401
 
8339
- async _disconnectTransport() {
8402
+ async _disconnectTransport(force = false) {
8403
+ if (force) {
8404
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8405
+ this.userAgent.transport.disconnectResolve = () => {};
8406
+ // eslint-disable-next-line
8407
+ this.userAgent.transport._ws.close(1000);
8408
+ return;
8409
+ }
8410
+
8340
8411
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8341
8412
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8342
8413
  try {
@@ -9072,6 +9143,8 @@ class WebRTCPhone extends Emitter {
9072
9143
  this.removeIncomingSessions(sipSessionId);
9073
9144
  }
9074
9145
 
9146
+ callSession.answerTime = new Date();
9147
+ this._updateCallSession(callSession);
9075
9148
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9076
9149
 
9077
9150
  return callSession;
@@ -9287,6 +9360,8 @@ class WebRTCPhone extends Emitter {
9287
9360
  }
9288
9361
 
9289
9362
  this.shouldSendReinvite = false;
9363
+ callSession.answerTime = new Date();
9364
+ this._updateCallSession(callSession);
9290
9365
  this.acceptedSessions[callSession.getId()] = true;
9291
9366
 
9292
9367
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9386,7 +9461,7 @@ class WebRTCPhone extends Emitter {
9386
9461
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9387
9462
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9388
9463
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9389
- this.holdSipSession(this.currentSipSession, callSession);
9464
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9390
9465
  }
9391
9466
 
9392
9467
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9597,6 +9672,7 @@ class WebRTCPhone extends Emitter {
9597
9672
  }
9598
9673
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9599
9674
  callSession.creationTime = new Date();
9675
+ this._updateCallSession(callSession);
9600
9676
 
9601
9677
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9602
9678
 
@@ -9738,7 +9814,7 @@ class WebRTCPhone extends Emitter {
9738
9814
  return this.client && this.client.isConference(callSession.sipCallId);
9739
9815
  }
9740
9816
 
9741
- async close() {
9817
+ async close(force = false) {
9742
9818
  logger$8.info('WebRTC close');
9743
9819
 
9744
9820
  try {
@@ -9750,7 +9826,7 @@ class WebRTCPhone extends Emitter {
9750
9826
  logger$8.error('WebRTC close, unregister error', e);
9751
9827
  }
9752
9828
 
9753
- this.client.close();
9829
+ this.client.close(force);
9754
9830
  this.unbind();
9755
9831
 
9756
9832
  this.incomingSessions = [];
@@ -9876,6 +9952,8 @@ class WebRTCPhone extends Emitter {
9876
9952
  }
9877
9953
 
9878
9954
  callSession.creationTime = new Date();
9955
+ this._updateCallSession(callSession);
9956
+
9879
9957
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9880
9958
  });
9881
9959
 
@@ -9919,6 +9997,8 @@ class WebRTCPhone extends Emitter {
9919
9997
  logger$8.info('WebRTC call rejected', session.id);
9920
9998
  const callSession = this._createCallSession(session);
9921
9999
  callSession.endTime = new Date();
10000
+ this._updateCallSession(callSession);
10001
+
9922
10002
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9923
10003
  });
9924
10004
 
@@ -10143,6 +10223,7 @@ class WebRTCPhone extends Emitter {
10143
10223
  displayName: identity ? identity.displayName || number : number,
10144
10224
  startTime: fromSession ? fromSession.startTime : new Date(),
10145
10225
  creationTime: fromSession ? fromSession.creationTime : null,
10226
+ answerTime: fromSession ? fromSession.answerTime : null,
10146
10227
  endTime: fromSession ? fromSession.endTime : null,
10147
10228
  answered: state === SessionState.Established,
10148
10229
  paused: this.client.isCallHeld(sipSession),
@@ -3248,6 +3248,7 @@ var updateFrom = (instance , from ) => {
3248
3248
 
3249
3249
 
3250
3250
 
3251
+
3251
3252
 
3252
3253
 
3253
3254
 
@@ -3295,14 +3296,14 @@ class CallSession {
3295
3296
 
3296
3297
 
3297
3298
 
3299
+ // = creationTime
3300
+
3298
3301
 
3299
3302
 
3300
3303
 
3301
3304
 
3302
3305
 
3303
3306
 
3304
-
3305
-
3306
3307
 
3307
3308
 
3308
3309
 
@@ -3366,6 +3367,7 @@ class CallSession {
3366
3367
  recordingPaused,
3367
3368
  videoRemotelyDowngraded,
3368
3369
  sipSession,
3370
+ answerTime,
3369
3371
  } ) {
3370
3372
  this.callId = callId;
3371
3373
  this.sipCallId = sipCallId;
@@ -3393,6 +3395,7 @@ class CallSession {
3393
3395
  this.recordingPaused = recordingPaused || false;
3394
3396
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3395
3397
  this.sipSession = sipSession;
3398
+ this.answerTime = answerTime || this.answerTime;
3396
3399
 
3397
3400
  // Useful to compare instead of instanceof with minified code
3398
3401
  this.type = 'CallSession';
@@ -3423,7 +3426,7 @@ class CallSession {
3423
3426
  }
3424
3427
 
3425
3428
  answer() {
3426
- this.answered = true;
3429
+ this.answerTime = new Date();
3427
3430
  }
3428
3431
 
3429
3432
  systemAnswer() {
@@ -3579,6 +3582,15 @@ class CallSession {
3579
3582
  return newFrom(callSession, CallSession);
3580
3583
  }
3581
3584
 
3585
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3586
+ set answered(value ) {
3587
+ this.answerTime = value ? this.answerTime || new Date() : null;
3588
+ }
3589
+
3590
+ get answered() {
3591
+ return !!this.answerTime;
3592
+ }
3593
+
3582
3594
  static parseCall(call ) {
3583
3595
  return new CallSession({
3584
3596
  callId: call.id,
@@ -4830,6 +4842,34 @@ var chatdMethods = (client , baseUrl ) => ({
4830
4842
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4831
4843
  });
4832
4844
 
4845
+ //
4846
+
4847
+
4848
+
4849
+
4850
+
4851
+ class MeetingStatus {
4852
+
4853
+
4854
+
4855
+
4856
+ constructor({
4857
+ full,
4858
+ } = {}) {
4859
+ this.full = full;
4860
+
4861
+ // Useful to compare instead of instanceof with minified code
4862
+ this.type = 'MeetingStatus';
4863
+ }
4864
+
4865
+ static parse(plain ) {
4866
+ return new MeetingStatus({
4867
+ full: plain.full,
4868
+ });
4869
+ }
4870
+
4871
+ }
4872
+
4833
4873
  /* */
4834
4874
 
4835
4875
 
@@ -5024,6 +5064,8 @@ var calldMethods = (client , baseUrl ) => ({
5024
5064
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5025
5065
  ApiRequester.successResponseParser),
5026
5066
 
5067
+ guestGetMeetingStatus: (meetingUuid ) =>
5068
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5027
5069
  });
5028
5070
 
5029
5071
  //
@@ -6361,6 +6403,7 @@ const MAX_REGISTER_TRIES = 10;
6361
6403
 
6362
6404
 
6363
6405
 
6406
+
6364
6407
 
6365
6408
 
6366
6409
 
@@ -6402,6 +6445,7 @@ class WebRTCClient extends Emitter {
6402
6445
 
6403
6446
 
6404
6447
 
6448
+
6405
6449
 
6406
6450
  // sugar
6407
6451
 
@@ -6464,6 +6508,7 @@ class WebRTCClient extends Emitter {
6464
6508
  this.conferences = {};
6465
6509
  this.networkMonitoringInterval = {};
6466
6510
  this.sessionNetworkStats = {};
6511
+ this.forceClosed = false;
6467
6512
 
6468
6513
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6469
6514
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6585,6 +6630,8 @@ class WebRTCClient extends Emitter {
6585
6630
  skipRegister: this.skipRegister,
6586
6631
  };
6587
6632
 
6633
+ this.forceClosed = false;
6634
+
6588
6635
  if (this.skipRegister) {
6589
6636
  logger$9.info('sdk webrtc skip register...', logInfo);
6590
6637
  return Promise.resolve();
@@ -6609,7 +6656,15 @@ class WebRTCClient extends Emitter {
6609
6656
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6610
6657
 
6611
6658
  const onRegisterFailed = () => {
6612
- logger$9.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6659
+ logger$9.info('sdk webrtc registering failed', {
6660
+ tries,
6661
+ registerer: !!this.registerer,
6662
+ forceClosed: this.forceClosed,
6663
+ });
6664
+ if (this.forceClosed) {
6665
+ return;
6666
+ }
6667
+
6613
6668
  this.connectionPromise = null;
6614
6669
  if (this.registerer && this.registerer.waiting) {
6615
6670
  this.registerer.waitingToggle(false);
@@ -6887,8 +6942,9 @@ class WebRTCClient extends Emitter {
6887
6942
  }
6888
6943
  }
6889
6944
 
6890
- async close() {
6891
- logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
6945
+ async close(force = false) {
6946
+ logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
6947
+ this.forceClosed = force;
6892
6948
  this._cleanupMedia();
6893
6949
  this.connectionPromise = null;
6894
6950
 
@@ -6907,7 +6963,7 @@ class WebRTCClient extends Emitter {
6907
6963
  this.userAgent.delegate = null;
6908
6964
  this.userAgent.stateChange.removeAllListeners();
6909
6965
 
6910
- await this._disconnectTransport();
6966
+ await this._disconnectTransport(force);
6911
6967
 
6912
6968
  this._cleanupRegister();
6913
6969
 
@@ -7977,6 +8033,13 @@ class WebRTCClient extends Emitter {
7977
8033
  }
7978
8034
 
7979
8035
  _createWebRTCConfiguration(configOverrides = {}) {
8036
+ let { host } = this.config;
8037
+ let port = this.config.port || 443;
8038
+
8039
+ if (this.config.websocketSip) {
8040
+ [host, port = 443] = this.config.websocketSip.split(':');
8041
+ }
8042
+
7980
8043
  const config = {
7981
8044
  authorizationUsername: this.config.authorizationUser,
7982
8045
  authorizationPassword: this.config.password,
@@ -8012,7 +8075,7 @@ class WebRTCClient extends Emitter {
8012
8075
  },
8013
8076
  transportOptions: {
8014
8077
  traceSip: configOverrides.traceSip || false,
8015
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8078
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8016
8079
  },
8017
8080
  sessionDescriptionHandlerFactoryOptions: {
8018
8081
  modifiers: [replaceLocalIpModifier],
@@ -8336,7 +8399,15 @@ class WebRTCClient extends Emitter {
8336
8399
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8337
8400
  }
8338
8401
 
8339
- async _disconnectTransport() {
8402
+ async _disconnectTransport(force = false) {
8403
+ if (force) {
8404
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8405
+ this.userAgent.transport.disconnectResolve = () => {};
8406
+ // eslint-disable-next-line
8407
+ this.userAgent.transport._ws.close(1000);
8408
+ return;
8409
+ }
8410
+
8340
8411
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8341
8412
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8342
8413
  try {
@@ -9072,6 +9143,8 @@ class WebRTCPhone extends Emitter {
9072
9143
  this.removeIncomingSessions(sipSessionId);
9073
9144
  }
9074
9145
 
9146
+ callSession.answerTime = new Date();
9147
+ this._updateCallSession(callSession);
9075
9148
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9076
9149
 
9077
9150
  return callSession;
@@ -9287,6 +9360,8 @@ class WebRTCPhone extends Emitter {
9287
9360
  }
9288
9361
 
9289
9362
  this.shouldSendReinvite = false;
9363
+ callSession.answerTime = new Date();
9364
+ this._updateCallSession(callSession);
9290
9365
  this.acceptedSessions[callSession.getId()] = true;
9291
9366
 
9292
9367
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9386,7 +9461,7 @@ class WebRTCPhone extends Emitter {
9386
9461
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9387
9462
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9388
9463
  logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9389
- this.holdSipSession(this.currentSipSession, callSession);
9464
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9390
9465
  }
9391
9466
 
9392
9467
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9597,6 +9672,7 @@ class WebRTCPhone extends Emitter {
9597
9672
  }
9598
9673
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9599
9674
  callSession.creationTime = new Date();
9675
+ this._updateCallSession(callSession);
9600
9676
 
9601
9677
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9602
9678
 
@@ -9738,7 +9814,7 @@ class WebRTCPhone extends Emitter {
9738
9814
  return this.client && this.client.isConference(callSession.sipCallId);
9739
9815
  }
9740
9816
 
9741
- async close() {
9817
+ async close(force = false) {
9742
9818
  logger$8.info('WebRTC close');
9743
9819
 
9744
9820
  try {
@@ -9750,7 +9826,7 @@ class WebRTCPhone extends Emitter {
9750
9826
  logger$8.error('WebRTC close, unregister error', e);
9751
9827
  }
9752
9828
 
9753
- this.client.close();
9829
+ this.client.close(force);
9754
9830
  this.unbind();
9755
9831
 
9756
9832
  this.incomingSessions = [];
@@ -9876,6 +9952,8 @@ class WebRTCPhone extends Emitter {
9876
9952
  }
9877
9953
 
9878
9954
  callSession.creationTime = new Date();
9955
+ this._updateCallSession(callSession);
9956
+
9879
9957
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
9880
9958
  });
9881
9959
 
@@ -9919,6 +9997,8 @@ class WebRTCPhone extends Emitter {
9919
9997
  logger$8.info('WebRTC call rejected', session.id);
9920
9998
  const callSession = this._createCallSession(session);
9921
9999
  callSession.endTime = new Date();
10000
+ this._updateCallSession(callSession);
10001
+
9922
10002
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
9923
10003
  });
9924
10004
 
@@ -10143,6 +10223,7 @@ class WebRTCPhone extends Emitter {
10143
10223
  displayName: identity ? identity.displayName || number : number,
10144
10224
  startTime: fromSession ? fromSession.startTime : new Date(),
10145
10225
  creationTime: fromSession ? fromSession.creationTime : null,
10226
+ answerTime: fromSession ? fromSession.answerTime : null,
10146
10227
  endTime: fromSession ? fromSession.endTime : null,
10147
10228
  answered: state === SessionState.Established,
10148
10229
  paused: this.client.isCallHeld(sipSession),
@@ -4016,6 +4016,34 @@ var chatdMethods = (client , baseUrl ) => ({
4016
4016
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4017
4017
  });
4018
4018
 
4019
+ //
4020
+
4021
+
4022
+
4023
+
4024
+
4025
+ class MeetingStatus {
4026
+
4027
+
4028
+
4029
+
4030
+ constructor({
4031
+ full,
4032
+ } = {}) {
4033
+ this.full = full;
4034
+
4035
+ // Useful to compare instead of instanceof with minified code
4036
+ this.type = 'MeetingStatus';
4037
+ }
4038
+
4039
+ static parse(plain ) {
4040
+ return new MeetingStatus({
4041
+ full: plain.full,
4042
+ });
4043
+ }
4044
+
4045
+ }
4046
+
4019
4047
  /* */
4020
4048
 
4021
4049
 
@@ -4210,6 +4238,8 @@ var calldMethods = (client , baseUrl ) => ({
4210
4238
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4211
4239
  ApiRequester.successResponseParser),
4212
4240
 
4241
+ guestGetMeetingStatus: (meetingUuid ) =>
4242
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4213
4243
  });
4214
4244
 
4215
4245
  //