@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.
@@ -9968,8 +9968,9 @@ const selectDevice = (devices = [], selected, preferred) => {
9968
9968
  return selected;
9969
9969
  };
9970
9970
  var NavigatorDeviceController = class extends Destroyable {
9971
- constructor() {
9971
+ constructor(webRTCApiProvider) {
9972
9972
  super();
9973
+ this.webRTCApiProvider = webRTCApiProvider;
9973
9974
  this.deviceChangeHandler = () => {
9974
9975
  logger$19.debug("[DeviceController] Device change detected");
9975
9976
  this.enumerateDevices();
@@ -10051,24 +10052,22 @@ var NavigatorDeviceController = class extends Destroyable {
10051
10052
  });
10052
10053
  }
10053
10054
  init() {
10054
- if (navigator.mediaDevices) {
10055
- this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10056
- const currentSelected = this._selectedDevicesState$.value;
10057
- const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10058
- const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
10059
- const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
10060
- if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
10061
- audioinput: newAudioInput,
10062
- audiooutput: newAudioOutput,
10063
- videoinput: newVideoInput
10064
- });
10055
+ this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10056
+ const currentSelected = this._selectedDevicesState$.value;
10057
+ const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10058
+ const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
10059
+ const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
10060
+ if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
10061
+ audioinput: newAudioInput,
10062
+ audiooutput: newAudioOutput,
10063
+ videoinput: newVideoInput
10065
10064
  });
10066
- this.enumerateDevices();
10067
- }
10065
+ });
10066
+ this.enumerateDevices();
10068
10067
  }
10069
10068
  enableDeviceMonitoring() {
10070
10069
  this.disableDeviceMonitoring();
10071
- navigator.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10070
+ this.webRTCApiProvider.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10072
10071
  if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$20.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10073
10072
  logger$19.debug("[DeviceController] Polling devices due to interval");
10074
10073
  this.enumerateDevices();
@@ -10076,7 +10075,7 @@ var NavigatorDeviceController = class extends Destroyable {
10076
10075
  this.enumerateDevices();
10077
10076
  }
10078
10077
  disableDeviceMonitoring() {
10079
- navigator.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
10078
+ this.webRTCApiProvider.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
10080
10079
  if (this._devicesPoolingSubscription) {
10081
10080
  this._devicesPoolingSubscription.unsubscribe();
10082
10081
  this._devicesPoolingSubscription = void 0;
@@ -10084,7 +10083,7 @@ var NavigatorDeviceController = class extends Destroyable {
10084
10083
  }
10085
10084
  async enumerateDevices() {
10086
10085
  try {
10087
- const devicesByKind = (await navigator.mediaDevices.enumerateDevices()).reduce((acc, device) => {
10086
+ const devicesByKind = (await this.webRTCApiProvider.mediaDevices.enumerateDevices()).reduce((acc, device) => {
10088
10087
  acc[device.kind].push(device);
10089
10088
  return acc;
10090
10089
  }, {
@@ -10107,7 +10106,7 @@ var NavigatorDeviceController = class extends Destroyable {
10107
10106
  if (deviceInfo.kind === "audiooutput") return null;
10108
10107
  try {
10109
10108
  const constraints = this.deviceInfoToConstraints(deviceInfo);
10110
- const stream = await navigator.mediaDevices.getUserMedia({
10109
+ const stream = await this.webRTCApiProvider.mediaDevices.getUserMedia({
10111
10110
  audio: deviceInfo.kind === "audioinput" ? constraints : false,
10112
10111
  video: deviceInfo.kind === "videoinput" ? constraints : false
10113
10112
  });
@@ -10279,9 +10278,23 @@ var DependencyContainer = class {
10279
10278
  this._webSocketConstructor = WebSocketConstructor;
10280
10279
  }
10281
10280
  get deviceController() {
10282
- this._deviceController ??= new NavigatorDeviceController();
10281
+ this._deviceController ??= new NavigatorDeviceController(this.webRTCApiProvider);
10283
10282
  return this._deviceController;
10284
10283
  }
10284
+ get webRTCApiProvider() {
10285
+ if (!this._webRTCApiProvider) {
10286
+ 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.");
10287
+ this._webRTCApiProvider = {
10288
+ RTCPeerConnection,
10289
+ mediaDevices: navigator.mediaDevices
10290
+ };
10291
+ }
10292
+ return this._webRTCApiProvider;
10293
+ }
10294
+ set webRTCApiProvider(webRTCApiProvider) {
10295
+ this._webRTCApiProvider = webRTCApiProvider;
10296
+ this._deviceController = void 0;
10297
+ }
10285
10298
  get authorizationStateKey() {
10286
10299
  return `sw:${this.subscriberId}:as`;
10287
10300
  }
@@ -12192,7 +12205,7 @@ function isJSONRPCRequest(value) {
12192
12205
  return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "method") && typeof value.method === "string";
12193
12206
  }
12194
12207
  function isJSONRPCResponse(value) {
12195
- return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "result");
12208
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && (hasProperty(value, "result") || hasProperty(value, "error"));
12196
12209
  }
12197
12210
 
12198
12211
  //#endregion
@@ -13234,7 +13247,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13234
13247
  logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13235
13248
  return;
13236
13249
  }
13237
- const streamTrack = (await navigator.mediaDevices.getUserMedia({ [kind]: {
13250
+ const streamTrack = (await this.getUserMedia({ [kind]: {
13238
13251
  ...track.getConstraints(),
13239
13252
  ...this.deviceController.deviceInfoToConstraints(deviceInfo)
13240
13253
  } })).getTracks().find((t) => t.kind === kind);
@@ -13425,7 +13438,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13425
13438
  };
13426
13439
  }
13427
13440
  get WebRTCPeerConnectionConstructor() {
13428
- return this.options.WebRTCPeerConnectionConstructor ?? RTCPeerConnection;
13441
+ return this.options.webRTCApiProvider?.RTCPeerConnection ?? RTCPeerConnection;
13429
13442
  }
13430
13443
  get offerOptions() {
13431
13444
  const options = { iceRestart: this.firstSDPExchangeCompleted ? true : void 0 };
@@ -13692,10 +13705,12 @@ var RTCPeerConnectionController = class extends Destroyable {
13692
13705
  }
13693
13706
  }
13694
13707
  async getUserMedia(constraints) {
13695
- return this.options.getUserMedia?.(constraints) ?? navigator.mediaDevices.getUserMedia(constraints);
13708
+ return (this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices).getUserMedia(constraints);
13696
13709
  }
13697
13710
  async getDisplayMedia(options) {
13698
- return this.options.getDisplayMedia?.(options) ?? navigator.mediaDevices.getDisplayMedia(options);
13711
+ const mediaDevices = this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices;
13712
+ if (!mediaDevices.getDisplayMedia) throw new DependencyError("getDisplayMedia is not supported by the current WebRTC provider");
13713
+ return mediaDevices.getDisplayMedia(options);
13699
13714
  }
13700
13715
  async setupRemoteTracks() {
13701
13716
  if (!this.peerConnection) throw new DependencyError("RTCPeerConnection is not initialized");
@@ -13860,11 +13875,12 @@ var VertoManager = class extends Destroyable {
13860
13875
  }
13861
13876
  };
13862
13877
  var WebRTCVertoManager = class extends VertoManager {
13863
- constructor(webRtcCallSession, attachManager, deviceController, options = {}) {
13878
+ constructor(webRtcCallSession, attachManager, deviceController, webRTCApiProvider, options = {}) {
13864
13879
  super(webRtcCallSession);
13865
13880
  this.webRtcCallSession = webRtcCallSession;
13866
13881
  this.attachManager = attachManager;
13867
13882
  this.deviceController = deviceController;
13883
+ this.webRTCApiProvider = webRTCApiProvider;
13868
13884
  this._rtcPeerConnections$ = this.createBehaviorSubject([]);
13869
13885
  this._selfId$ = this.createBehaviorSubject(null);
13870
13886
  this._signalingStatus$ = this.createBehaviorSubject(null);
@@ -14027,7 +14043,7 @@ var WebRTCVertoManager = class extends VertoManager {
14027
14043
  }
14028
14044
  async sendLocalDescription(message, rtcPeerConnController) {
14029
14045
  const vertoMethod = message.method;
14030
- const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController);
14046
+ const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod);
14031
14047
  try {
14032
14048
  const response = await this.executeVerto(message, optionalsParams);
14033
14049
  switch (vertoMethod) {
@@ -14104,6 +14120,7 @@ var WebRTCVertoManager = class extends VertoManager {
14104
14120
  inputVideoStream: options.inputVideoStream,
14105
14121
  receiveAudio: options.receiveAudio,
14106
14122
  receiveVideo: options.receiveVideo,
14123
+ webRTCApiProvider: this.webRTCApiProvider,
14107
14124
  ...this.RTCPeerConnectionConfig
14108
14125
  }, options.initOffer, this.deviceController);
14109
14126
  this.setupLocalDescriptionHandler(rtcPeerConnController);
@@ -14170,18 +14187,18 @@ var WebRTCVertoManager = class extends VertoManager {
14170
14187
  this.callSession?.destroy();
14171
14188
  });
14172
14189
  }
14173
- getSendLocalSDPOptionalParams(rtcPeerConnController) {
14190
+ getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod) {
14174
14191
  let subscribe = void 0;
14175
- const initial = !rtcPeerConnController.firstSDPExchangeCompleted;
14176
- if (initial) {
14192
+ if (!rtcPeerConnController.firstSDPExchangeCompleted) {
14177
14193
  subscribe = [];
14178
14194
  if (rtcPeerConnController.isMainDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeMainDevice);
14179
14195
  else if (rtcPeerConnController.isAdditionalDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeAdditionalDevice);
14180
14196
  else if (rtcPeerConnController.isScreenShare) subscribe.push(...PreferencesContainer.instance.inviteSubscribeScreenshare);
14181
14197
  }
14198
+ const isInvite = vertoMethod === "verto.invite";
14182
14199
  return {
14183
14200
  callID: rtcPeerConnController.id,
14184
- node_id: initial ? "" : this._nodeId$.value ?? "",
14201
+ node_id: isInvite ? "" : this._nodeId$.value ?? "",
14185
14202
  subscribe
14186
14203
  };
14187
14204
  }
@@ -14282,7 +14299,8 @@ var WebRTCVertoManager = class extends VertoManager {
14282
14299
  rtcPeerConnController = new RTCPeerConnectionController({
14283
14300
  ...options,
14284
14301
  ...this.RTCPeerConnectionConfig,
14285
- propose
14302
+ propose,
14303
+ webRTCApiProvider: this.webRTCApiProvider
14286
14304
  }, void 0, this.deviceController);
14287
14305
  this.setupLocalDescriptionHandler(rtcPeerConnController);
14288
14306
  if (propose === "screenshare") this._screenShareId = rtcPeerConnController.id;
@@ -14812,10 +14830,11 @@ var WebRTCCall = class extends Destroyable {
14812
14830
  * Eliminates circular dependencies by centralizing Call and Manager creation.
14813
14831
  */
14814
14832
  var CallFactory = class {
14815
- constructor(sessionManager, deviceController, attachManager) {
14833
+ constructor(sessionManager, deviceController, attachManager, webRTCApiProvider) {
14816
14834
  this.sessionManager = sessionManager;
14817
14835
  this.deviceController = deviceController;
14818
14836
  this.attachManager = attachManager;
14837
+ this.webRTCApiProvider = webRTCApiProvider;
14819
14838
  }
14820
14839
  /**
14821
14840
  * Create a new WebRTCCall with properly initialized managers
@@ -14824,7 +14843,7 @@ var CallFactory = class {
14824
14843
  return new WebRTCCall(this.sessionManager, options, {
14825
14844
  initializeManagers: (callInstance) => {
14826
14845
  return {
14827
- vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, {
14846
+ vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, this.webRTCApiProvider, {
14828
14847
  nodeId: options.nodeId,
14829
14848
  onError: (error) => {
14830
14849
  callInstance.emitError(error);
@@ -15240,7 +15259,7 @@ const getAddressSearchURI = (options) => {
15240
15259
  return name;
15241
15260
  };
15242
15261
  var ClientSessionManager = class extends Destroyable {
15243
- constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager) {
15262
+ constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider) {
15244
15263
  super();
15245
15264
  this.credential = credential;
15246
15265
  this.transport = transport;
@@ -15263,7 +15282,7 @@ var ClientSessionManager = class extends Destroyable {
15263
15282
  this._calls$ = this.createBehaviorSubject({});
15264
15283
  this._iceServers$ = this.createBehaviorSubject([]);
15265
15284
  attachManager.setSession(this);
15266
- this.callFactory = new CallFactory(this, deviceController, attachManager);
15285
+ this.callFactory = new CallFactory(this, deviceController, attachManager, webRTCApiProvider);
15267
15286
  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$));
15268
15287
  }
15269
15288
  get incomingCalls$() {
@@ -16155,6 +16174,7 @@ var SignalWire = class extends Destroyable {
16155
16174
  if (this._options.storageImplementation) this._deps.storageImpl = this._options.storageImplementation;
16156
16175
  if (this._options.webSocketConstructor) this._deps.WebSocket = this._options.webSocketConstructor;
16157
16176
  if (this._options.savePreferences) this.preferences.enableSavePreferences(this._deps.storage);
16177
+ if (this._options.webRTCApiProvider) this._deps.webRTCApiProvider = this._options.webRTCApiProvider;
16158
16178
  this._deviceController = this._deps.deviceController;
16159
16179
  if (!this._options.skipDeviceMonitoring) this._deviceController.enableDeviceMonitoring();
16160
16180
  this.subscribeTo(this._deviceController.errors$, (error) => {
@@ -16279,7 +16299,7 @@ var SignalWire = class extends Destroyable {
16279
16299
  };
16280
16300
  this._transport = new TransportManager(this._deps.storage, this._deps.protocolKey, this._deps.WebSocket, PreferencesContainer.instance.relayHost ?? this._deps.relayHost, errorHandler);
16281
16301
  this._attachManager = new AttachManager(this._deps.storage, this._deps.deviceController, PreferencesContainer.instance.reconnectCallsTimeout, this._deps.attachedCallsKey);
16282
- this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager);
16302
+ this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider);
16283
16303
  this._publicSession = new ClientSessionWrapper(this._clientSession);
16284
16304
  this.subscribeTo(this._clientSession.errors$, (error) => {
16285
16305
  this._errors$.next(error);