@wazo/sdk 0.42.0 → 0.43.0-rc.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.
Files changed (39) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/web-rtc-client.test.js +1 -1
  3. package/esm/domain/Phone/CTIPhone.js +1 -1
  4. package/esm/domain/Phone/WebRTCPhone.js +4 -4
  5. package/esm/simple/Phone.js +1 -1
  6. package/esm/simple/room/Room.js +2 -2
  7. package/esm/types/domain/Phone/CTIPhone.d.ts +1 -1
  8. package/esm/types/domain/Phone/WebRTCPhone.d.ts +2 -2
  9. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  10. package/esm/types/domain/types.d.ts +3 -6
  11. package/esm/types/domain/types.d.ts.map +1 -1
  12. package/esm/types/simple/Phone.d.ts +3 -3
  13. package/esm/types/simple/Phone.d.ts.map +1 -1
  14. package/esm/types/web-rtc-client.d.ts +8 -10
  15. package/esm/types/web-rtc-client.d.ts.map +1 -1
  16. package/esm/web-rtc-client.js +18 -24
  17. package/lib/__tests__/web-rtc-client.test.js +1 -1
  18. package/lib/domain/Phone/CTIPhone.js +1 -1
  19. package/lib/domain/Phone/WebRTCPhone.js +9 -7
  20. package/lib/simple/Phone.js +1 -1
  21. package/lib/simple/room/Room.js +5 -5
  22. package/lib/types/domain/Phone/CTIPhone.d.ts +1 -1
  23. package/lib/types/domain/Phone/WebRTCPhone.d.ts +2 -2
  24. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  25. package/lib/types/domain/types.d.ts +3 -6
  26. package/lib/types/domain/types.d.ts.map +1 -1
  27. package/lib/types/simple/Phone.d.ts +3 -3
  28. package/lib/types/simple/Phone.d.ts.map +1 -1
  29. package/lib/types/web-rtc-client.d.ts +8 -10
  30. package/lib/types/web-rtc-client.d.ts.map +1 -1
  31. package/lib/web-rtc-client.js +147 -141
  32. package/package.json +1 -1
  33. package/src/__tests__/web-rtc-client.test.ts +1 -1
  34. package/src/domain/Phone/CTIPhone.ts +1 -1
  35. package/src/domain/Phone/WebRTCPhone.ts +4 -4
  36. package/src/domain/types.ts +3 -6
  37. package/src/simple/Phone.ts +4 -4
  38. package/src/simple/room/Room.ts +2 -2
  39. package/src/web-rtc-client.ts +20 -26
@@ -12,7 +12,7 @@ jest.mock('sip.js/lib/api/user-agent', () => ({
12
12
  },
13
13
  }));
14
14
 
15
- const client = new WebRTCClient({} as any, null, undefined);
15
+ const client = new WebRTCClient({} as any, undefined, undefined);
16
16
 
17
17
  describe('WebRTC client', () => {
18
18
  it('should compute muted/unmuted state', async () => {
@@ -300,7 +300,7 @@ export default class CTIPhone extends Emitter implements Phone {
300
300
 
301
301
  changeVideoInputDevice() { return Promise.resolve(null); }
302
302
 
303
- changeAudioDevice() {}
303
+ changeAudioDevice() { return Promise.resolve(); }
304
304
 
305
305
  changeRingDevice() {}
306
306
 
@@ -612,12 +612,12 @@ export default class WebRTCPhone extends Emitter implements Phone {
612
612
  return callSession;
613
613
  }
614
614
 
615
- changeAudioDevice(id: string) {
615
+ async changeAudioDevice(id: string) {
616
616
  logger.info('WebRTC phone - change audio device', {
617
617
  deviceId: id,
618
618
  });
619
619
  this.audioOutputDeviceId = id;
620
- this.client.changeAudioOutputDevice(id);
620
+ return this.client.changeAudioOutputDevice(id);
621
621
  }
622
622
 
623
623
  createAudioElementFor(sessionId: string) {
@@ -1528,7 +1528,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1528
1528
  this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
1529
1529
  }, 2000);
1530
1530
  });
1531
- this.client.on(this.client.ACCEPTED, (sipSession: WazoSession) => {
1531
+ this.client.on(this.client.ACCEPTED, async (sipSession: WazoSession) => {
1532
1532
  const sessionId = this.getSipSessionId(sipSession);
1533
1533
  const hasSession = (sessionId in this.callSessions);
1534
1534
  logger.info('WebRTC call accepted', {
@@ -1546,7 +1546,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1546
1546
  this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
1547
1547
 
1548
1548
  if (this.audioOutputDeviceId) {
1549
- this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
1549
+ await this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
1550
1550
  }
1551
1551
  });
1552
1552
  this.client.on('ended', () => {});
@@ -237,7 +237,6 @@ export type WebRtcConfig = {
237
237
  media?: MediaConfig;
238
238
  iceCheckingTimeout?: number;
239
239
  log?: Record<string, any>;
240
- audioOutputDeviceId?: string;
241
240
  audioOutputVolume?: number;
242
241
  userAgentString?: string;
243
242
  heartbeatDelay?: number;
@@ -245,13 +244,11 @@ export type WebRtcConfig = {
245
244
  maxHeartbeats?: number;
246
245
  skipRegister?: boolean;
247
246
  userUuid?: string,
247
+ uaConfigOverrides?: UserAgentConfigOverrides,
248
+ audioDeviceOutput?: string,
249
+ audioDeviceRing?: string
248
250
  }; // @see https://github.com/onsip/SIP.js/blob/master/src/Web/Simple.js
249
251
 
250
- export type ConnectionOptions = WebRtcConfig & {
251
- uaConfigOverrides: UserAgentConfigOverrides,
252
- audioDeviceOutput: string,
253
- audioDeviceRing: string
254
- };
255
252
  export type IncomingResponse = SipIncomingResponse & { session: any };
256
253
 
257
254
  export type PeerConnection = RTCPeerConnection & {
@@ -11,7 +11,7 @@ import IssueReporter from '../service/IssueReporter';
11
11
  import Emitter from '../utils/Emitter';
12
12
  import Wazo from './index';
13
13
  import SFUNotAvailableError from '../domain/SFUNotAvailableError';
14
- import { ConnectionOptions, WazoSession } from '../domain/types';
14
+ import { WazoSession, WebRtcConfig } from '../domain/types';
15
15
 
16
16
  const logger = IssueReporter.loggerFor('simple-phone');
17
17
  const sipLogger = IssueReporter.loggerFor('sip.js');
@@ -127,7 +127,7 @@ export class Phone extends Emitter {
127
127
  this.SessionState = SessionState;
128
128
  }
129
129
 
130
- async connect(rawOptions: Partial<ConnectionOptions> = {}, sipLine: SipLine | null | undefined = null): Promise<void> {
130
+ async connect(rawOptions: Partial<WebRtcConfig> = {}, sipLine: SipLine | null | undefined = null): Promise<void> {
131
131
  const options = rawOptions;
132
132
  if (this.phone) {
133
133
  // Already connected
@@ -162,7 +162,7 @@ export class Phone extends Emitter {
162
162
  server: string,
163
163
  sipLine: SipLine,
164
164
  displayName: string,
165
- rawOptions: Partial<ConnectionOptions> = {},
165
+ rawOptions: Partial<WebRtcConfig> = {},
166
166
  ): void {
167
167
  if (this.phone) {
168
168
  // Already connected
@@ -194,7 +194,7 @@ export class Phone extends Emitter {
194
194
  password: sipLine.secret,
195
195
  uri: `${sipLine.username}@${server}`,
196
196
  ...options,
197
- }, null, options.uaConfigOverrides);
197
+ }, undefined, options.uaConfigOverrides);
198
198
  this.phone = new WebRTCPhone(this.client, options.audioDeviceOutput, true, options.audioDeviceRing);
199
199
 
200
200
  this._transferEvents();
@@ -492,13 +492,13 @@ class Room extends Emitter {
492
492
  // Listen to REINVITE to ba able to map msid after upgrading to video in a audio only conference
493
493
  // This allow to map msid with the non parsed (eg without the `stripVideo` modifier) SDP
494
494
  Wazo.Phone.phone.on(Wazo.Phone.phone.client.ON_REINVITE, this._boundOnReinvite);
495
- this.on(this.ON_AUDIO_STREAM, stream => {
495
+ this.on(this.ON_AUDIO_STREAM, async stream => {
496
496
  logger.info('on room audio stream');
497
497
  this.audioStream = stream;
498
498
 
499
499
  if (!this.roomAudioElement) {
500
500
  const sessionId = Wazo.Phone.phone?.getSipSessionId(Wazo.Phone.phone?.currentSipSession as WazoSession);
501
- this.roomAudioElement = Wazo.Phone.phone?.createAudioElementFor(sessionId as string) as HTMLAudioElement;
501
+ this.roomAudioElement = await Wazo.Phone.phone?.createAudioElementFor(sessionId as string) as HTMLAudioElement;
502
502
  this.roomAudioElement.srcObject = stream;
503
503
  } else {
504
504
  this.roomAudioElement.srcObject = stream;
@@ -90,7 +90,7 @@ export default class WebRTCClient extends Emitter {
90
90
 
91
91
  audio: MediaTrackConstraintSet | boolean | undefined;
92
92
 
93
- audioElements: Record<string, HTMLAudioElement & { setSinkId?: (id: string) => void }>;
93
+ audioElements: Record<string, HTMLAudioElement>;
94
94
 
95
95
  video: MediaTrackConstraintSet | boolean | undefined;
96
96
 
@@ -182,7 +182,7 @@ export default class WebRTCClient extends Emitter {
182
182
  return [];
183
183
  }
184
184
 
185
- constructor(config: WebRtcConfig, session: WazoSession | null | undefined, uaConfigOverrides?: UserAgentConfigOverrides) {
185
+ constructor(config: WebRtcConfig, session?: WazoSession, uaConfigOverrides?: UserAgentConfigOverrides) {
186
186
  super();
187
187
 
188
188
  // For debug purpose
@@ -198,7 +198,7 @@ export default class WebRTCClient extends Emitter {
198
198
  this.userAgent = this.createUserAgent(uaConfigOverrides);
199
199
  });
200
200
 
201
- this.audioOutputDeviceId = config.audioOutputDeviceId;
201
+ this.audioOutputDeviceId = config.audioDeviceOutput;
202
202
  this.audioOutputVolume = config.audioOutputVolume || 1;
203
203
 
204
204
  if (config.media) {
@@ -1246,20 +1246,14 @@ export default class WebRTCClient extends Emitter {
1246
1246
  this.audioOutputVolume = volume;
1247
1247
  }
1248
1248
 
1249
- changeAudioOutputDevice(id: string) {
1249
+ async changeAudioOutputDevice(id: string) {
1250
1250
  logger.info('Changing audio output device', {
1251
1251
  id,
1252
1252
  });
1253
1253
  this.audioOutputDeviceId = id;
1254
- Object.values(this.audioElements).forEach(audioElement => {
1255
- // `setSinkId` method is not included in any flow type definitions for HTMLAudioElements but is a valid method
1256
- // audioElement is an array of HTMLAudioElements, and HTMLAudioElement inherits the method from HTMLMediaElement
1257
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement
1258
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId
1259
- if (audioElement.setSinkId) {
1260
- audioElement.setSinkId(id);
1261
- }
1262
- });
1254
+ const promises: Promise<void>[] = [];
1255
+ Object.values(this.audioElements).forEach(audioElement => promises.push(audioElement.setSinkId(id)));
1256
+ await Promise.allSettled(promises);
1263
1257
  }
1264
1258
 
1265
1259
  async changeAudioInputDevice(id: string, session: WazoSession | null | undefined, force?: boolean): Promise<MediaStream | null> {
@@ -1735,7 +1729,7 @@ export default class WebRTCClient extends Emitter {
1735
1729
  }
1736
1730
  }
1737
1731
 
1738
- updateLocalStream(sipSessionId: string, newStream: MediaStream): void {
1732
+ async updateLocalStream(sipSessionId: string, newStream: MediaStream): Promise<void> {
1739
1733
  const sipSession = this.sipSessions[sipSessionId];
1740
1734
 
1741
1735
  if (!sipSession) {
@@ -1756,7 +1750,7 @@ export default class WebRTCClient extends Emitter {
1756
1750
  this.setLocalMediaStream(sipSessionId, newStream);
1757
1751
 
1758
1752
  // Update the local video element
1759
- this._setupMedias(sipSession, newStream);
1753
+ await this._setupMedias(sipSession, newStream);
1760
1754
  }
1761
1755
 
1762
1756
  updateRemoteStream(sessionId: string, allTracks = true): void {
@@ -1832,14 +1826,14 @@ export default class WebRTCClient extends Emitter {
1832
1826
  return sessionId in this.conferences;
1833
1827
  }
1834
1828
 
1835
- createAudioElementFor(sessionId: string): HTMLAudioElement {
1829
+ async createAudioElementFor(sessionId: string): Promise<HTMLAudioElement> {
1836
1830
  const audio: HTMLAudioElement = document.createElement('audio');
1837
1831
  audio.setAttribute('id', `audio-${sessionId}`);
1838
1832
 
1839
1833
  logger.info('creating audio element', { sessionId, audioOutputDeviceId: this.audioOutputDeviceId });
1840
1834
 
1841
- if ((audio as any).setSinkId && this.audioOutputDeviceId) {
1842
- (audio as any).setSinkId(this.audioOutputDeviceId);
1835
+ if (this.audioOutputDeviceId) {
1836
+ await audio.setSinkId(this.audioOutputDeviceId);
1843
1837
  }
1844
1838
 
1845
1839
  if (document.body) {
@@ -2135,7 +2129,7 @@ export default class WebRTCClient extends Emitter {
2135
2129
  oldInviteRequest(request);
2136
2130
  };
2137
2131
 
2138
- session.delegate.onInvite = (request: IncomingRequestMessage) => {
2132
+ session.delegate.onInvite = async (request: IncomingRequestMessage) => {
2139
2133
  let updatedCalleeName: string | null = null;
2140
2134
  let updatedNumber = null;
2141
2135
 
@@ -2165,14 +2159,14 @@ export default class WebRTCClient extends Emitter {
2165
2159
 
2166
2160
  this.updateRemoteStream(sipSessionId, false);
2167
2161
 
2168
- this._setupMedias(session);
2162
+ await this._setupMedias(session);
2169
2163
 
2170
2164
  return this.eventEmitter.emit(ON_REINVITE, session, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
2171
2165
  };
2172
2166
  }
2173
2167
 
2174
- _onProgress(session: WazoSession, early = false): void {
2175
- this._setupMedias(session);
2168
+ async _onProgress(session: WazoSession, early = false): Promise<void> {
2169
+ await this._setupMedias(session);
2176
2170
 
2177
2171
  const sessionId = this.getSipSessionId(session).substr(0, 20);
2178
2172
  this.updateRemoteStream(sessionId);
@@ -2183,7 +2177,7 @@ export default class WebRTCClient extends Emitter {
2183
2177
  this.eventEmitter.emit(early ? ON_EARLY_MEDIA : ON_PROGRESS, session);
2184
2178
  }
2185
2179
 
2186
- _onAccepted(session: WazoSession, sessionDialog?: SessionDialog, withEvent = true, initAllTracks = true): void {
2180
+ async _onAccepted(session: WazoSession, sessionDialog?: SessionDialog, withEvent = true, initAllTracks = true): Promise<void> {
2187
2181
  logger.info('on call accepted', {
2188
2182
  id: session.id,
2189
2183
  clientId: this.clientId,
@@ -2191,7 +2185,7 @@ export default class WebRTCClient extends Emitter {
2191
2185
  });
2192
2186
  this.storeSipSession(session);
2193
2187
 
2194
- this._setupMedias(session);
2188
+ await this._setupMedias(session);
2195
2189
 
2196
2190
  this.updateRemoteStream(this.getSipSessionId(session), initAllTracks);
2197
2191
  const pc = (session.sessionDescriptionHandler as SessionDescriptionHandler)?.peerConnection;
@@ -2253,7 +2247,7 @@ export default class WebRTCClient extends Emitter {
2253
2247
  return Boolean(session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo));
2254
2248
  }
2255
2249
 
2256
- _setupMedias(session: WazoSession, newStream: MediaStream | null | undefined = null): void {
2250
+ async _setupMedias(session: WazoSession, newStream: MediaStream | null | undefined = null): Promise<void> {
2257
2251
  if (!this._isWeb()) {
2258
2252
  logger.info('Setup media on mobile, no need to setup html element, bailing');
2259
2253
  return;
@@ -2271,7 +2265,7 @@ export default class WebRTCClient extends Emitter {
2271
2265
  }
2272
2266
 
2273
2267
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
2274
- this.createAudioElementFor(sessionId);
2268
+ await this.createAudioElementFor(sessionId);
2275
2269
  }
2276
2270
 
2277
2271
  const audioElement = this.audioElements[sessionId];