@wazo/sdk 0.49.4 → 0.49.5

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.js CHANGED
@@ -4925,6 +4925,13 @@ const addIcesInAllBundles = (sdp)=>{
4925
4925
  return external_sdp_transform_default().write(parsedSdp);
4926
4926
  };
4927
4927
  const wazoLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-sdh') : console;
4928
+ const TRANSIENT_SIGNALING_STATES = new Set([
4929
+ 'have-local-offer',
4930
+ 'have-local-pranswer',
4931
+ 'have-remote-pranswer'
4932
+ ]);
4933
+ const SIGNALING_STATE_SETTLE_TIMEOUT = 3000;
4934
+ const ON_CLOSED = 'sdh-closed';
4928
4935
  const wazoMediaStreamFactory = (constraints)=>{
4929
4936
  if (!constraints.audio && !constraints.video) return Promise.resolve(new MediaStream());
4930
4937
  if (void 0 === navigator.mediaDevices) return Promise.reject(new Error('Media devices not available in insecure contexts.'));
@@ -5037,6 +5044,7 @@ class WazoSessionDescriptionHandler extends session_description_handler_namespac
5037
5044
  }
5038
5045
  close() {
5039
5046
  wazoLogger.info('closing sdh');
5047
+ this.eventEmitter.emit(ON_CLOSED);
5040
5048
  if (this.isWeb) return super.close();
5041
5049
  this.logger.debug("SessionDescriptionHandler.close");
5042
5050
  if (void 0 === this._peerConnection) return;
@@ -5052,9 +5060,83 @@ class WazoSessionDescriptionHandler extends session_description_handler_namespac
5052
5060
  this._peerConnection.close();
5053
5061
  this._peerConnection = void 0;
5054
5062
  }
5055
- updateDirection(options, isConference = false, audioOnly = false) {
5063
+ rollbackDescription() {
5064
+ const peerConnection = this._peerConnection;
5065
+ const signalingState = peerConnection?.signalingState;
5066
+ const rollbackWith = (apply)=>{
5067
+ wazoLogger.info('rolling back the rejected offer', {
5068
+ signalingState
5069
+ });
5070
+ return Promise.resolve().then(apply).then(()=>{
5071
+ wazoLogger.info('offer rolled back', {
5072
+ signalingState: peerConnection.signalingState
5073
+ });
5074
+ }).catch((error)=>{
5075
+ wazoLogger.warn('rolling back the offer failed', {
5076
+ message: error?.message,
5077
+ signalingState: peerConnection.signalingState
5078
+ });
5079
+ });
5080
+ };
5081
+ if ('have-local-offer' === signalingState && peerConnection.setLocalDescription) return rollbackWith(()=>peerConnection.setLocalDescription({
5082
+ type: 'rollback'
5083
+ }));
5084
+ if ('have-remote-offer' === signalingState && peerConnection.setRemoteDescription) return rollbackWith(()=>peerConnection.setRemoteDescription({
5085
+ type: 'rollback'
5086
+ }));
5087
+ return Promise.resolve();
5088
+ }
5089
+ waitForSettledSignalingState(timeout = SIGNALING_STATE_SETTLE_TIMEOUT) {
5090
+ const peerConnection = this._peerConnection;
5091
+ if (!peerConnection?.addEventListener) return Promise.reject(new Error(`Invalid signaling state ${peerConnection?.signalingState}`));
5092
+ if (!TRANSIENT_SIGNALING_STATES.has(peerConnection.signalingState)) return 'closed' === peerConnection.signalingState ? Promise.reject(new Error('Invalid signaling state closed')) : Promise.resolve();
5093
+ return new Promise((resolve, reject)=>{
5094
+ let timeoutId;
5095
+ let onSignalingStateChange;
5096
+ let onClosed;
5097
+ const stopListening = ()=>{
5098
+ clearTimeout(timeoutId);
5099
+ this.eventEmitter.removeListener(ON_CLOSED, onClosed);
5100
+ peerConnection.removeEventListener?.('signalingstatechange', onSignalingStateChange);
5101
+ };
5102
+ onSignalingStateChange = ()=>{
5103
+ const { signalingState } = peerConnection;
5104
+ if ('closed' === signalingState) {
5105
+ reject(new Error(`Invalid signaling state ${signalingState}`));
5106
+ stopListening();
5107
+ return;
5108
+ }
5109
+ if (!TRANSIENT_SIGNALING_STATES.has(signalingState)) {
5110
+ resolve();
5111
+ stopListening();
5112
+ }
5113
+ };
5114
+ onClosed = ()=>{
5115
+ reject(new Error('Peer connection closed.'));
5116
+ stopListening();
5117
+ };
5118
+ timeoutId = setTimeout(()=>{
5119
+ const { signalingState } = peerConnection;
5120
+ reject(new Error(`Invalid signaling state ${signalingState}`));
5121
+ wazoLogger.warn('signaling state did not settle, dropping the direction update', {
5122
+ signalingState,
5123
+ timeout
5124
+ });
5125
+ stopListening();
5126
+ }, timeout);
5127
+ this.eventEmitter.once(ON_CLOSED, onClosed);
5128
+ peerConnection.addEventListener('signalingstatechange', onSignalingStateChange);
5129
+ });
5130
+ }
5131
+ updateDirection(options, isConference = false, audioOnly = false, hasWaitedForSettledState = false) {
5056
5132
  if (void 0 === this._peerConnection) return Promise.reject(new Error('Peer connection closed.'));
5057
5133
  if (!this._peerConnection.getTransceivers) return Promise.resolve();
5134
+ if (!hasWaitedForSettledState && TRANSIENT_SIGNALING_STATES.has(this._peerConnection.signalingState)) {
5135
+ wazoLogger.info('direction update issued mid-negotiation, waiting for the signaling state to settle', {
5136
+ signalingState: this._peerConnection.signalingState
5137
+ });
5138
+ return this.waitForSettledSignalingState().then(()=>this.updateDirection(options, isConference, audioOnly, true));
5139
+ }
5058
5140
  switch(this._peerConnection.signalingState){
5059
5141
  case 'stable':
5060
5142
  {
package/dist/index.mjs CHANGED
@@ -4838,6 +4838,13 @@ const addIcesInAllBundles = (sdp)=>{
4838
4838
  return __WEBPACK_EXTERNAL_MODULE_sdp_transform_45b84e5d__["default"].write(parsedSdp);
4839
4839
  };
4840
4840
  const wazoLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-sdh') : console;
4841
+ const TRANSIENT_SIGNALING_STATES = new Set([
4842
+ 'have-local-offer',
4843
+ 'have-local-pranswer',
4844
+ 'have-remote-pranswer'
4845
+ ]);
4846
+ const SIGNALING_STATE_SETTLE_TIMEOUT = 3000;
4847
+ const ON_CLOSED = 'sdh-closed';
4841
4848
  const wazoMediaStreamFactory = (constraints)=>{
4842
4849
  if (!constraints.audio && !constraints.video) return Promise.resolve(new MediaStream());
4843
4850
  if (void 0 === navigator.mediaDevices) return Promise.reject(new Error('Media devices not available in insecure contexts.'));
@@ -4950,6 +4957,7 @@ class WazoSessionDescriptionHandler extends __WEBPACK_EXTERNAL_MODULE_sip_js_lib
4950
4957
  }
4951
4958
  close() {
4952
4959
  wazoLogger.info('closing sdh');
4960
+ this.eventEmitter.emit(ON_CLOSED);
4953
4961
  if (this.isWeb) return super.close();
4954
4962
  this.logger.debug("SessionDescriptionHandler.close");
4955
4963
  if (void 0 === this._peerConnection) return;
@@ -4965,9 +4973,83 @@ class WazoSessionDescriptionHandler extends __WEBPACK_EXTERNAL_MODULE_sip_js_lib
4965
4973
  this._peerConnection.close();
4966
4974
  this._peerConnection = void 0;
4967
4975
  }
4968
- updateDirection(options, isConference = false, audioOnly = false) {
4976
+ rollbackDescription() {
4977
+ const peerConnection = this._peerConnection;
4978
+ const signalingState = peerConnection?.signalingState;
4979
+ const rollbackWith = (apply)=>{
4980
+ wazoLogger.info('rolling back the rejected offer', {
4981
+ signalingState
4982
+ });
4983
+ return Promise.resolve().then(apply).then(()=>{
4984
+ wazoLogger.info('offer rolled back', {
4985
+ signalingState: peerConnection.signalingState
4986
+ });
4987
+ }).catch((error)=>{
4988
+ wazoLogger.warn('rolling back the offer failed', {
4989
+ message: error?.message,
4990
+ signalingState: peerConnection.signalingState
4991
+ });
4992
+ });
4993
+ };
4994
+ if ('have-local-offer' === signalingState && peerConnection.setLocalDescription) return rollbackWith(()=>peerConnection.setLocalDescription({
4995
+ type: 'rollback'
4996
+ }));
4997
+ if ('have-remote-offer' === signalingState && peerConnection.setRemoteDescription) return rollbackWith(()=>peerConnection.setRemoteDescription({
4998
+ type: 'rollback'
4999
+ }));
5000
+ return Promise.resolve();
5001
+ }
5002
+ waitForSettledSignalingState(timeout = SIGNALING_STATE_SETTLE_TIMEOUT) {
5003
+ const peerConnection = this._peerConnection;
5004
+ if (!peerConnection?.addEventListener) return Promise.reject(new Error(`Invalid signaling state ${peerConnection?.signalingState}`));
5005
+ if (!TRANSIENT_SIGNALING_STATES.has(peerConnection.signalingState)) return 'closed' === peerConnection.signalingState ? Promise.reject(new Error('Invalid signaling state closed')) : Promise.resolve();
5006
+ return new Promise((resolve, reject)=>{
5007
+ let timeoutId;
5008
+ let onSignalingStateChange;
5009
+ let onClosed;
5010
+ const stopListening = ()=>{
5011
+ clearTimeout(timeoutId);
5012
+ this.eventEmitter.removeListener(ON_CLOSED, onClosed);
5013
+ peerConnection.removeEventListener?.('signalingstatechange', onSignalingStateChange);
5014
+ };
5015
+ onSignalingStateChange = ()=>{
5016
+ const { signalingState } = peerConnection;
5017
+ if ('closed' === signalingState) {
5018
+ reject(new Error(`Invalid signaling state ${signalingState}`));
5019
+ stopListening();
5020
+ return;
5021
+ }
5022
+ if (!TRANSIENT_SIGNALING_STATES.has(signalingState)) {
5023
+ resolve();
5024
+ stopListening();
5025
+ }
5026
+ };
5027
+ onClosed = ()=>{
5028
+ reject(new Error('Peer connection closed.'));
5029
+ stopListening();
5030
+ };
5031
+ timeoutId = setTimeout(()=>{
5032
+ const { signalingState } = peerConnection;
5033
+ reject(new Error(`Invalid signaling state ${signalingState}`));
5034
+ wazoLogger.warn('signaling state did not settle, dropping the direction update', {
5035
+ signalingState,
5036
+ timeout
5037
+ });
5038
+ stopListening();
5039
+ }, timeout);
5040
+ this.eventEmitter.once(ON_CLOSED, onClosed);
5041
+ peerConnection.addEventListener('signalingstatechange', onSignalingStateChange);
5042
+ });
5043
+ }
5044
+ updateDirection(options, isConference = false, audioOnly = false, hasWaitedForSettledState = false) {
4969
5045
  if (void 0 === this._peerConnection) return Promise.reject(new Error('Peer connection closed.'));
4970
5046
  if (!this._peerConnection.getTransceivers) return Promise.resolve();
5047
+ if (!hasWaitedForSettledState && TRANSIENT_SIGNALING_STATES.has(this._peerConnection.signalingState)) {
5048
+ wazoLogger.info('direction update issued mid-negotiation, waiting for the signaling state to settle', {
5049
+ signalingState: this._peerConnection.signalingState
5050
+ });
5051
+ return this.waitForSettledSignalingState().then(()=>this.updateDirection(options, isConference, audioOnly, true));
5052
+ }
4971
5053
  switch(this._peerConnection.signalingState){
4972
5054
  case 'stable':
4973
5055
  {
@@ -6,6 +6,7 @@ import { SessionDescriptionHandler } from 'sip.js/lib/platform/web/session-descr
6
6
  import { SessionDescriptionHandlerOptions } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-options';
7
7
  import { WazoSession } from '../domain/types';
8
8
  import { type Candidate } from '../utils/sdp';
9
+ export declare const SIGNALING_STATE_SETTLE_TIMEOUT = 3000;
9
10
  export declare const wazoMediaStreamFactory: (constraints: Record<string, any>) => Promise<MediaStream>;
10
11
  declare class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
11
12
  gatheredCandidates: Candidate[];
@@ -22,7 +23,9 @@ declare class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
22
23
  interToneGap: number;
23
24
  }): boolean;
24
25
  close(): void;
25
- updateDirection(options?: SessionDescriptionHandlerOptions, isConference?: boolean, audioOnly?: boolean): Promise<void>;
26
+ rollbackDescription(): Promise<void>;
27
+ waitForSettledSignalingState(timeout?: number): Promise<void>;
28
+ updateDirection(options?: SessionDescriptionHandlerOptions, isConference?: boolean, audioOnly?: boolean, hasWaitedForSettledState?: boolean): Promise<void>;
26
29
  setLocalMediaStream(stream: MediaStream): Promise<void>;
27
30
  getLocalMediaStream(options: Record<string, any>): Promise<any>;
28
31
  private _constraintsEqual;
@@ -1 +1 @@
1
- {"version":3,"file":"WazoSessionDescriptionHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/WazoSessionDescriptionHandler.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0EAA0E,CAAC;AACnH,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,+FAA+F,CAAC;AAC5J,OAAO,EAAE,yBAAyB,EAAE,MAAM,iFAAiF,CAAC;AAC5H,OAAO,EAAE,gCAAgC,EAAE,MAAM,yFAAyF,CAAC;AAC3I,OAAO,EAAkB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,KAAK,SAAS,EAA+C,MAAM,cAAc,CAAC;AAI3F,eAAO,MAAM,sBAAsB,gBAAiB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAAO,CAAC,WAAW,CAgB5F,CAAC;AAEF,cAAM,6BAA8B,SAAQ,yBAAyB;IACnE,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAEhC,YAAY,EAAE,YAAY,CAAC;IAE3B,KAAK,EAAE,OAAO,CAAC;IAEf,OAAO,EAAE,WAAW,CAAC;gBAGT,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sCAAsC,EAAE,sCAAsC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW;IAOxL,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG;IAIxD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG;IAIzD,2BAA2B,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzF,cAAc,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAuGhH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACa,GAAG,OAAO;IAqB9C,KAAK,IAAI,IAAI;IAwCb,eAAe,CAAC,OAAO,CAAC,EAAE,gCAAgC,EAAE,YAAY,UAAQ,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoLnH,mBAAmB,CAAC,MAAM,EAAE,WAAW;IA+FvC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAwC/D,OAAO,CAAC,iBAAiB;CAe1B;AAED,eAAe,6BAA6B,CAAC"}
1
+ {"version":3,"file":"WazoSessionDescriptionHandler.d.ts","sourceRoot":"","sources":["../../../src/lib/WazoSessionDescriptionHandler.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0EAA0E,CAAC;AACnH,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,+FAA+F,CAAC;AAC5J,OAAO,EAAE,yBAAyB,EAAE,MAAM,iFAAiF,CAAC;AAC5H,OAAO,EAAE,gCAAgC,EAAE,MAAM,yFAAyF,CAAC;AAC3I,OAAO,EAAkB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,KAAK,SAAS,EAA+C,MAAM,cAAc,CAAC;AAW3F,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAKnD,eAAO,MAAM,sBAAsB,gBAAiB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAAO,CAAC,WAAW,CAgB5F,CAAC;AAEF,cAAM,6BAA8B,SAAQ,yBAAyB;IACnE,kBAAkB,EAAE,SAAS,EAAE,CAAC;IAEhC,YAAY,EAAE,YAAY,CAAC;IAE3B,KAAK,EAAE,OAAO,CAAC;IAEf,OAAO,EAAE,WAAW,CAAC;gBAGT,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,sCAAsC,EAAE,sCAAsC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW;IAOxL,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG;IAIxD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG;IAIzD,2BAA2B,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzF,cAAc,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAuGhH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACa,GAAG,OAAO;IAqB9C,KAAK,IAAI,IAAI;IAwDb,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCpC,4BAA4B,CAAC,OAAO,GAAE,MAAuC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqE7F,eAAe,CAAC,OAAO,CAAC,EAAE,gCAAgC,EAAE,YAAY,UAAQ,EAAE,SAAS,UAAQ,EAAE,wBAAwB,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA6LrJ,mBAAmB,CAAC,MAAM,EAAE,WAAW;IA+FvC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAwC/D,OAAO,CAAC,iBAAiB;CAe1B;AAED,eAAe,6BAA6B,CAAC"}
package/dist/wazo-sdk.js CHANGED
@@ -50077,6 +50077,13 @@ and limitations under the License.
50077
50077
  return lib.write(parsedSdp);
50078
50078
  };
50079
50079
  const wazoLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-sdh') : console;
50080
+ const TRANSIENT_SIGNALING_STATES = new Set([
50081
+ 'have-local-offer',
50082
+ 'have-local-pranswer',
50083
+ 'have-remote-pranswer'
50084
+ ]);
50085
+ const SIGNALING_STATE_SETTLE_TIMEOUT = 3000;
50086
+ const ON_CLOSED = 'sdh-closed';
50080
50087
  const wazoMediaStreamFactory = (constraints)=>{
50081
50088
  if (!constraints.audio && !constraints.video) return Promise.resolve(new MediaStream());
50082
50089
  if (void 0 === navigator.mediaDevices) return Promise.reject(new Error('Media devices not available in insecure contexts.'));
@@ -50189,6 +50196,7 @@ and limitations under the License.
50189
50196
  }
50190
50197
  close() {
50191
50198
  wazoLogger.info('closing sdh');
50199
+ this.eventEmitter.emit(ON_CLOSED);
50192
50200
  if (this.isWeb) return super.close();
50193
50201
  this.logger.debug("SessionDescriptionHandler.close");
50194
50202
  if (void 0 === this._peerConnection) return;
@@ -50204,9 +50212,83 @@ and limitations under the License.
50204
50212
  this._peerConnection.close();
50205
50213
  this._peerConnection = void 0;
50206
50214
  }
50207
- updateDirection(options, isConference = false, audioOnly = false) {
50215
+ rollbackDescription() {
50216
+ const peerConnection = this._peerConnection;
50217
+ const signalingState = peerConnection?.signalingState;
50218
+ const rollbackWith = (apply)=>{
50219
+ wazoLogger.info('rolling back the rejected offer', {
50220
+ signalingState
50221
+ });
50222
+ return Promise.resolve().then(apply).then(()=>{
50223
+ wazoLogger.info('offer rolled back', {
50224
+ signalingState: peerConnection.signalingState
50225
+ });
50226
+ }).catch((error)=>{
50227
+ wazoLogger.warn('rolling back the offer failed', {
50228
+ message: error?.message,
50229
+ signalingState: peerConnection.signalingState
50230
+ });
50231
+ });
50232
+ };
50233
+ if ('have-local-offer' === signalingState && peerConnection.setLocalDescription) return rollbackWith(()=>peerConnection.setLocalDescription({
50234
+ type: 'rollback'
50235
+ }));
50236
+ if ('have-remote-offer' === signalingState && peerConnection.setRemoteDescription) return rollbackWith(()=>peerConnection.setRemoteDescription({
50237
+ type: 'rollback'
50238
+ }));
50239
+ return Promise.resolve();
50240
+ }
50241
+ waitForSettledSignalingState(timeout = SIGNALING_STATE_SETTLE_TIMEOUT) {
50242
+ const peerConnection = this._peerConnection;
50243
+ if (!peerConnection?.addEventListener) return Promise.reject(new Error(`Invalid signaling state ${peerConnection?.signalingState}`));
50244
+ if (!TRANSIENT_SIGNALING_STATES.has(peerConnection.signalingState)) return 'closed' === peerConnection.signalingState ? Promise.reject(new Error('Invalid signaling state closed')) : Promise.resolve();
50245
+ return new Promise((resolve, reject)=>{
50246
+ let timeoutId;
50247
+ let onSignalingStateChange;
50248
+ let onClosed;
50249
+ const stopListening = ()=>{
50250
+ clearTimeout(timeoutId);
50251
+ this.eventEmitter.removeListener(ON_CLOSED, onClosed);
50252
+ peerConnection.removeEventListener?.('signalingstatechange', onSignalingStateChange);
50253
+ };
50254
+ onSignalingStateChange = ()=>{
50255
+ const { signalingState } = peerConnection;
50256
+ if ('closed' === signalingState) {
50257
+ reject(new Error(`Invalid signaling state ${signalingState}`));
50258
+ stopListening();
50259
+ return;
50260
+ }
50261
+ if (!TRANSIENT_SIGNALING_STATES.has(signalingState)) {
50262
+ resolve();
50263
+ stopListening();
50264
+ }
50265
+ };
50266
+ onClosed = ()=>{
50267
+ reject(new Error('Peer connection closed.'));
50268
+ stopListening();
50269
+ };
50270
+ timeoutId = setTimeout(()=>{
50271
+ const { signalingState } = peerConnection;
50272
+ reject(new Error(`Invalid signaling state ${signalingState}`));
50273
+ wazoLogger.warn('signaling state did not settle, dropping the direction update', {
50274
+ signalingState,
50275
+ timeout
50276
+ });
50277
+ stopListening();
50278
+ }, timeout);
50279
+ this.eventEmitter.once(ON_CLOSED, onClosed);
50280
+ peerConnection.addEventListener('signalingstatechange', onSignalingStateChange);
50281
+ });
50282
+ }
50283
+ updateDirection(options, isConference = false, audioOnly = false, hasWaitedForSettledState = false) {
50208
50284
  if (void 0 === this._peerConnection) return Promise.reject(new Error('Peer connection closed.'));
50209
50285
  if (!this._peerConnection.getTransceivers) return Promise.resolve();
50286
+ if (!hasWaitedForSettledState && TRANSIENT_SIGNALING_STATES.has(this._peerConnection.signalingState)) {
50287
+ wazoLogger.info('direction update issued mid-negotiation, waiting for the signaling state to settle', {
50288
+ signalingState: this._peerConnection.signalingState
50289
+ });
50290
+ return this.waitForSettledSignalingState().then(()=>this.updateDirection(options, isConference, audioOnly, true));
50291
+ }
50210
50292
  switch(this._peerConnection.signalingState){
50211
50293
  case 'stable':
50212
50294
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "0.49.4",
3
+ "version": "0.49.5",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/types/index.d.ts",