@signalwire/js 4.0.0-beta.2 → 4.0.0-beta.3

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/browser.mjs CHANGED
@@ -9964,8 +9964,9 @@ const selectDevice = (devices = [], selected, preferred) => {
9964
9964
  return selected;
9965
9965
  };
9966
9966
  var NavigatorDeviceController = class extends Destroyable {
9967
- constructor() {
9967
+ constructor(webRTCApiProvider) {
9968
9968
  super();
9969
+ this.webRTCApiProvider = webRTCApiProvider;
9969
9970
  this.deviceChangeHandler = () => {
9970
9971
  logger$19.debug("[DeviceController] Device change detected");
9971
9972
  this.enumerateDevices();
@@ -10047,24 +10048,22 @@ var NavigatorDeviceController = class extends Destroyable {
10047
10048
  });
10048
10049
  }
10049
10050
  init() {
10050
- if (navigator.mediaDevices) {
10051
- this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10052
- const currentSelected = this._selectedDevicesState$.value;
10053
- const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10054
- const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
10055
- const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
10056
- if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
10057
- audioinput: newAudioInput,
10058
- audiooutput: newAudioOutput,
10059
- videoinput: newVideoInput
10060
- });
10051
+ this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10052
+ const currentSelected = this._selectedDevicesState$.value;
10053
+ const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10054
+ const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
10055
+ const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
10056
+ if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
10057
+ audioinput: newAudioInput,
10058
+ audiooutput: newAudioOutput,
10059
+ videoinput: newVideoInput
10061
10060
  });
10062
- this.enumerateDevices();
10063
- }
10061
+ });
10062
+ this.enumerateDevices();
10064
10063
  }
10065
10064
  enableDeviceMonitoring() {
10066
10065
  this.disableDeviceMonitoring();
10067
- navigator.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10066
+ this.webRTCApiProvider.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10068
10067
  if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$20.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10069
10068
  logger$19.debug("[DeviceController] Polling devices due to interval");
10070
10069
  this.enumerateDevices();
@@ -10072,7 +10071,7 @@ var NavigatorDeviceController = class extends Destroyable {
10072
10071
  this.enumerateDevices();
10073
10072
  }
10074
10073
  disableDeviceMonitoring() {
10075
- navigator.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
10074
+ this.webRTCApiProvider.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
10076
10075
  if (this._devicesPoolingSubscription) {
10077
10076
  this._devicesPoolingSubscription.unsubscribe();
10078
10077
  this._devicesPoolingSubscription = void 0;
@@ -10080,7 +10079,7 @@ var NavigatorDeviceController = class extends Destroyable {
10080
10079
  }
10081
10080
  async enumerateDevices() {
10082
10081
  try {
10083
- const devicesByKind = (await navigator.mediaDevices.enumerateDevices()).reduce((acc, device) => {
10082
+ const devicesByKind = (await this.webRTCApiProvider.mediaDevices.enumerateDevices()).reduce((acc, device) => {
10084
10083
  acc[device.kind].push(device);
10085
10084
  return acc;
10086
10085
  }, {
@@ -10103,7 +10102,7 @@ var NavigatorDeviceController = class extends Destroyable {
10103
10102
  if (deviceInfo.kind === "audiooutput") return null;
10104
10103
  try {
10105
10104
  const constraints = this.deviceInfoToConstraints(deviceInfo);
10106
- const stream = await navigator.mediaDevices.getUserMedia({
10105
+ const stream = await this.webRTCApiProvider.mediaDevices.getUserMedia({
10107
10106
  audio: deviceInfo.kind === "audioinput" ? constraints : false,
10108
10107
  video: deviceInfo.kind === "videoinput" ? constraints : false
10109
10108
  });
@@ -10275,9 +10274,23 @@ var DependencyContainer = class {
10275
10274
  this._webSocketConstructor = WebSocketConstructor;
10276
10275
  }
10277
10276
  get deviceController() {
10278
- this._deviceController ??= new NavigatorDeviceController();
10277
+ this._deviceController ??= new NavigatorDeviceController(this.webRTCApiProvider);
10279
10278
  return this._deviceController;
10280
10279
  }
10280
+ get webRTCApiProvider() {
10281
+ if (!this._webRTCApiProvider) {
10282
+ if (typeof RTCPeerConnection === "undefined" || typeof navigator === "undefined") throw new DependencyError("WebRTCApiProvider: RTCPeerConnection or navigator.mediaDevices is not available. Please provide a custom webRTCApiProvider in SignalWireOptions.");
10283
+ this._webRTCApiProvider = {
10284
+ RTCPeerConnection,
10285
+ mediaDevices: navigator.mediaDevices
10286
+ };
10287
+ }
10288
+ return this._webRTCApiProvider;
10289
+ }
10290
+ set webRTCApiProvider(webRTCApiProvider) {
10291
+ this._webRTCApiProvider = webRTCApiProvider;
10292
+ this._deviceController = void 0;
10293
+ }
10281
10294
  get authorizationStateKey() {
10282
10295
  return `sw:${this.subscriberId}:as`;
10283
10296
  }
@@ -12188,7 +12201,7 @@ function isJSONRPCRequest(value) {
12188
12201
  return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "method") && typeof value.method === "string";
12189
12202
  }
12190
12203
  function isJSONRPCResponse(value) {
12191
- return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "result");
12204
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && (hasProperty(value, "result") || hasProperty(value, "error"));
12192
12205
  }
12193
12206
 
12194
12207
  //#endregion
@@ -13230,7 +13243,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13230
13243
  logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13231
13244
  return;
13232
13245
  }
13233
- const streamTrack = (await navigator.mediaDevices.getUserMedia({ [kind]: {
13246
+ const streamTrack = (await this.getUserMedia({ [kind]: {
13234
13247
  ...track.getConstraints(),
13235
13248
  ...this.deviceController.deviceInfoToConstraints(deviceInfo)
13236
13249
  } })).getTracks().find((t) => t.kind === kind);
@@ -13421,7 +13434,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13421
13434
  };
13422
13435
  }
13423
13436
  get WebRTCPeerConnectionConstructor() {
13424
- return this.options.WebRTCPeerConnectionConstructor ?? RTCPeerConnection;
13437
+ return this.options.webRTCApiProvider?.RTCPeerConnection ?? RTCPeerConnection;
13425
13438
  }
13426
13439
  get offerOptions() {
13427
13440
  const options = { iceRestart: this.firstSDPExchangeCompleted ? true : void 0 };
@@ -13688,10 +13701,12 @@ var RTCPeerConnectionController = class extends Destroyable {
13688
13701
  }
13689
13702
  }
13690
13703
  async getUserMedia(constraints) {
13691
- return this.options.getUserMedia?.(constraints) ?? navigator.mediaDevices.getUserMedia(constraints);
13704
+ return (this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices).getUserMedia(constraints);
13692
13705
  }
13693
13706
  async getDisplayMedia(options) {
13694
- return this.options.getDisplayMedia?.(options) ?? navigator.mediaDevices.getDisplayMedia(options);
13707
+ const mediaDevices = this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices;
13708
+ if (!mediaDevices.getDisplayMedia) throw new DependencyError("getDisplayMedia is not supported by the current WebRTC provider");
13709
+ return mediaDevices.getDisplayMedia(options);
13695
13710
  }
13696
13711
  async setupRemoteTracks() {
13697
13712
  if (!this.peerConnection) throw new DependencyError("RTCPeerConnection is not initialized");
@@ -13856,11 +13871,12 @@ var VertoManager = class extends Destroyable {
13856
13871
  }
13857
13872
  };
13858
13873
  var WebRTCVertoManager = class extends VertoManager {
13859
- constructor(webRtcCallSession, attachManager, deviceController, options = {}) {
13874
+ constructor(webRtcCallSession, attachManager, deviceController, webRTCApiProvider, options = {}) {
13860
13875
  super(webRtcCallSession);
13861
13876
  this.webRtcCallSession = webRtcCallSession;
13862
13877
  this.attachManager = attachManager;
13863
13878
  this.deviceController = deviceController;
13879
+ this.webRTCApiProvider = webRTCApiProvider;
13864
13880
  this._rtcPeerConnections$ = this.createBehaviorSubject([]);
13865
13881
  this._selfId$ = this.createBehaviorSubject(null);
13866
13882
  this._signalingStatus$ = this.createBehaviorSubject(null);
@@ -14023,7 +14039,7 @@ var WebRTCVertoManager = class extends VertoManager {
14023
14039
  }
14024
14040
  async sendLocalDescription(message, rtcPeerConnController) {
14025
14041
  const vertoMethod = message.method;
14026
- const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController);
14042
+ const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod);
14027
14043
  try {
14028
14044
  const response = await this.executeVerto(message, optionalsParams);
14029
14045
  switch (vertoMethod) {
@@ -14100,6 +14116,7 @@ var WebRTCVertoManager = class extends VertoManager {
14100
14116
  inputVideoStream: options.inputVideoStream,
14101
14117
  receiveAudio: options.receiveAudio,
14102
14118
  receiveVideo: options.receiveVideo,
14119
+ webRTCApiProvider: this.webRTCApiProvider,
14103
14120
  ...this.RTCPeerConnectionConfig
14104
14121
  }, options.initOffer, this.deviceController);
14105
14122
  this.setupLocalDescriptionHandler(rtcPeerConnController);
@@ -14166,18 +14183,18 @@ var WebRTCVertoManager = class extends VertoManager {
14166
14183
  this.callSession?.destroy();
14167
14184
  });
14168
14185
  }
14169
- getSendLocalSDPOptionalParams(rtcPeerConnController) {
14186
+ getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod) {
14170
14187
  let subscribe = void 0;
14171
- const initial = !rtcPeerConnController.firstSDPExchangeCompleted;
14172
- if (initial) {
14188
+ if (!rtcPeerConnController.firstSDPExchangeCompleted) {
14173
14189
  subscribe = [];
14174
14190
  if (rtcPeerConnController.isMainDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeMainDevice);
14175
14191
  else if (rtcPeerConnController.isAdditionalDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeAdditionalDevice);
14176
14192
  else if (rtcPeerConnController.isScreenShare) subscribe.push(...PreferencesContainer.instance.inviteSubscribeScreenshare);
14177
14193
  }
14194
+ const isInvite = vertoMethod === "verto.invite";
14178
14195
  return {
14179
14196
  callID: rtcPeerConnController.id,
14180
- node_id: initial ? "" : this._nodeId$.value ?? "",
14197
+ node_id: isInvite ? "" : this._nodeId$.value ?? "",
14181
14198
  subscribe
14182
14199
  };
14183
14200
  }
@@ -14278,7 +14295,8 @@ var WebRTCVertoManager = class extends VertoManager {
14278
14295
  rtcPeerConnController = new RTCPeerConnectionController({
14279
14296
  ...options,
14280
14297
  ...this.RTCPeerConnectionConfig,
14281
- propose
14298
+ propose,
14299
+ webRTCApiProvider: this.webRTCApiProvider
14282
14300
  }, void 0, this.deviceController);
14283
14301
  this.setupLocalDescriptionHandler(rtcPeerConnController);
14284
14302
  if (propose === "screenshare") this._screenShareId = rtcPeerConnController.id;
@@ -14808,10 +14826,11 @@ var WebRTCCall = class extends Destroyable {
14808
14826
  * Eliminates circular dependencies by centralizing Call and Manager creation.
14809
14827
  */
14810
14828
  var CallFactory = class {
14811
- constructor(sessionManager, deviceController, attachManager) {
14829
+ constructor(sessionManager, deviceController, attachManager, webRTCApiProvider) {
14812
14830
  this.sessionManager = sessionManager;
14813
14831
  this.deviceController = deviceController;
14814
14832
  this.attachManager = attachManager;
14833
+ this.webRTCApiProvider = webRTCApiProvider;
14815
14834
  }
14816
14835
  /**
14817
14836
  * Create a new WebRTCCall with properly initialized managers
@@ -14820,7 +14839,7 @@ var CallFactory = class {
14820
14839
  return new WebRTCCall(this.sessionManager, options, {
14821
14840
  initializeManagers: (callInstance) => {
14822
14841
  return {
14823
- vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, {
14842
+ vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, this.webRTCApiProvider, {
14824
14843
  nodeId: options.nodeId,
14825
14844
  onError: (error) => {
14826
14845
  callInstance.emitError(error);
@@ -15236,7 +15255,7 @@ const getAddressSearchURI = (options) => {
15236
15255
  return name;
15237
15256
  };
15238
15257
  var ClientSessionManager = class extends Destroyable {
15239
- constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager) {
15258
+ constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider) {
15240
15259
  super();
15241
15260
  this.credential = credential;
15242
15261
  this.transport = transport;
@@ -15259,7 +15278,7 @@ var ClientSessionManager = class extends Destroyable {
15259
15278
  this._calls$ = this.createBehaviorSubject({});
15260
15279
  this._iceServers$ = this.createBehaviorSubject([]);
15261
15280
  attachManager.setSession(this);
15262
- this.callFactory = new CallFactory(this, deviceController, attachManager);
15281
+ this.callFactory = new CallFactory(this, deviceController, attachManager, webRTCApiProvider);
15263
15282
  this.initialized$ = (0, import_cjs$5.defer)(() => (0, import_cjs$5.from)(this.init())).pipe((0, import_cjs$5.shareReplay)(1), (0, import_cjs$5.takeUntil)(this.destroyed$));
15264
15283
  }
15265
15284
  get incomingCalls$() {
@@ -16151,6 +16170,7 @@ var SignalWire = class extends Destroyable {
16151
16170
  if (this._options.storageImplementation) this._deps.storageImpl = this._options.storageImplementation;
16152
16171
  if (this._options.webSocketConstructor) this._deps.WebSocket = this._options.webSocketConstructor;
16153
16172
  if (this._options.savePreferences) this.preferences.enableSavePreferences(this._deps.storage);
16173
+ if (this._options.webRTCApiProvider) this._deps.webRTCApiProvider = this._options.webRTCApiProvider;
16154
16174
  this._deviceController = this._deps.deviceController;
16155
16175
  if (!this._options.skipDeviceMonitoring) this._deviceController.enableDeviceMonitoring();
16156
16176
  this.subscribeTo(this._deviceController.errors$, (error) => {
@@ -16275,7 +16295,7 @@ var SignalWire = class extends Destroyable {
16275
16295
  };
16276
16296
  this._transport = new TransportManager(this._deps.storage, this._deps.protocolKey, this._deps.WebSocket, PreferencesContainer.instance.relayHost ?? this._deps.relayHost, errorHandler);
16277
16297
  this._attachManager = new AttachManager(this._deps.storage, this._deps.deviceController, PreferencesContainer.instance.reconnectCallsTimeout, this._deps.attachedCallsKey);
16278
- this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager);
16298
+ this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider);
16279
16299
  this._publicSession = new ClientSessionWrapper(this._clientSession);
16280
16300
  this.subscribeTo(this._clientSession.errors$, (error) => {
16281
16301
  this._errors$.next(error);