@signalwire/js 4.0.0-beta.1 → 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/index.cjs CHANGED
@@ -12,11 +12,21 @@ var Destroyable = class {
12
12
  this._destroyed$ = new rxjs.Subject();
13
13
  }
14
14
  destroy() {
15
+ this._observableCache?.clear();
15
16
  this.subscriptions.forEach((sub) => sub.unsubscribe());
16
17
  this.subjects.forEach((subject) => subject.complete());
17
18
  this._destroyed$.next();
18
19
  this._destroyed$.complete();
19
20
  }
21
+ cachedObservable(key, factory) {
22
+ this._observableCache ??= /* @__PURE__ */ new Map();
23
+ let cached = this._observableCache.get(key);
24
+ if (!cached) {
25
+ cached = factory();
26
+ this._observableCache.set(key, cached);
27
+ }
28
+ return cached;
29
+ }
20
30
  subscribeTo(observable, observerOrNext) {
21
31
  const subscription = observable.subscribe(observerOrNext);
22
32
  this.subscriptions.push(subscription);
@@ -37,7 +47,7 @@ var Destroyable = class {
37
47
  return subject;
38
48
  }
39
49
  get $() {
40
- return (0, rxjs.merge)(...this.subjects.map((s) => s instanceof rxjs.BehaviorSubject ? s.pipe((0, rxjs.skip)(1)) : s)).pipe((0, rxjs.map)((_) => this));
50
+ return this.cachedObservable("$", () => (0, rxjs.merge)(...this.subjects.map((s) => s instanceof rxjs.BehaviorSubject ? s.pipe((0, rxjs.skip)(1)) : s)).pipe((0, rxjs.map)((_) => this)));
41
51
  }
42
52
  /**
43
53
  * Observable that emits when the instance is destroyed
@@ -588,8 +598,9 @@ const selectDevice = (devices = [], selected, preferred) => {
588
598
  return selected;
589
599
  };
590
600
  var NavigatorDeviceController = class extends Destroyable {
591
- constructor() {
601
+ constructor(webRTCApiProvider) {
592
602
  super();
603
+ this.webRTCApiProvider = webRTCApiProvider;
593
604
  this.deviceChangeHandler = () => {
594
605
  logger$18.debug("[DeviceController] Device change detected");
595
606
  this.enumerateDevices();
@@ -613,25 +624,25 @@ var NavigatorDeviceController = class extends Destroyable {
613
624
  return {};
614
625
  }
615
626
  get errors$() {
616
- return this._errors$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
627
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
617
628
  }
618
629
  get audioInputDevices$() {
619
- return this._devicesState$.pipe((0, rxjs.map)((state) => state.audioinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$));
630
+ return this.cachedObservable("audioInputDevices$", () => this._devicesState$.pipe((0, rxjs.map)((state) => state.audioinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$)));
620
631
  }
621
632
  get audioOutputDevices$() {
622
- return this._devicesState$.pipe((0, rxjs.map)((state) => state.audiooutput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$));
633
+ return this.cachedObservable("audioOutputDevices$", () => this._devicesState$.pipe((0, rxjs.map)((state) => state.audiooutput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$)));
623
634
  }
624
635
  get videoInputDevices$() {
625
- return this._devicesState$.pipe((0, rxjs.map)((state) => state.videoinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$));
636
+ return this.cachedObservable("videoInputDevices$", () => this._devicesState$.pipe((0, rxjs.map)((state) => state.videoinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$)));
626
637
  }
627
638
  get selectedAudioInputDevice$() {
628
- return this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.audioinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected audio input device changed:", info)));
639
+ return this.cachedObservable("selectedAudioInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.audioinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected audio input device changed:", info))));
629
640
  }
630
641
  get selectedAudioOutputDevice$() {
631
- return this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.audiooutput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected audio output device changed:", info)));
642
+ return this.cachedObservable("selectedAudioOutputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.audiooutput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected audio output device changed:", info))));
632
643
  }
633
644
  get selectedVideoInputDevice$() {
634
- return this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.videoinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected video input device changed:", info)));
645
+ return this.cachedObservable("selectedVideoInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, rxjs.map)((state) => state.videoinput), (0, rxjs.distinctUntilChanged)(), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.tap)((info) => logger$18.debug("[DeviceController] Selected video input device changed:", info))));
635
646
  }
636
647
  get selectedAudioInputDevice() {
637
648
  return this._selectedDevicesState$.value.audioinput;
@@ -671,24 +682,22 @@ var NavigatorDeviceController = class extends Destroyable {
671
682
  });
672
683
  }
673
684
  init() {
674
- if (navigator.mediaDevices) {
675
- this.subscribeTo(this._devicesState$.pipe((0, rxjs.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
676
- const currentSelected = this._selectedDevicesState$.value;
677
- const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
678
- const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
679
- const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
680
- if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
681
- audioinput: newAudioInput,
682
- audiooutput: newAudioOutput,
683
- videoinput: newVideoInput
684
- });
685
+ this.subscribeTo(this._devicesState$.pipe((0, rxjs.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
686
+ const currentSelected = this._selectedDevicesState$.value;
687
+ const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
688
+ const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
689
+ const newVideoInput = selectDevice(devicesState.videoinput, currentSelected.videoinput, PreferencesContainer.instance.preferredVideoInput);
690
+ if (newAudioInput !== currentSelected.audioinput || newAudioOutput !== currentSelected.audiooutput || newVideoInput !== currentSelected.videoinput) this._selectedDevicesState$.next({
691
+ audioinput: newAudioInput,
692
+ audiooutput: newAudioOutput,
693
+ videoinput: newVideoInput
685
694
  });
686
- this.enumerateDevices();
687
- }
695
+ });
696
+ this.enumerateDevices();
688
697
  }
689
698
  enableDeviceMonitoring() {
690
699
  this.disableDeviceMonitoring();
691
- navigator.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
700
+ this.webRTCApiProvider.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
692
701
  if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, rxjs.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
693
702
  logger$18.debug("[DeviceController] Polling devices due to interval");
694
703
  this.enumerateDevices();
@@ -696,7 +705,7 @@ var NavigatorDeviceController = class extends Destroyable {
696
705
  this.enumerateDevices();
697
706
  }
698
707
  disableDeviceMonitoring() {
699
- navigator.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
708
+ this.webRTCApiProvider.mediaDevices.removeEventListener("devicechange", this.deviceChangeHandler);
700
709
  if (this._devicesPoolingSubscription) {
701
710
  this._devicesPoolingSubscription.unsubscribe();
702
711
  this._devicesPoolingSubscription = void 0;
@@ -704,7 +713,7 @@ var NavigatorDeviceController = class extends Destroyable {
704
713
  }
705
714
  async enumerateDevices() {
706
715
  try {
707
- const devicesByKind = (await navigator.mediaDevices.enumerateDevices()).reduce((acc, device) => {
716
+ const devicesByKind = (await this.webRTCApiProvider.mediaDevices.enumerateDevices()).reduce((acc, device) => {
708
717
  acc[device.kind].push(device);
709
718
  return acc;
710
719
  }, {
@@ -727,7 +736,7 @@ var NavigatorDeviceController = class extends Destroyable {
727
736
  if (deviceInfo.kind === "audiooutput") return null;
728
737
  try {
729
738
  const constraints = this.deviceInfoToConstraints(deviceInfo);
730
- const stream = await navigator.mediaDevices.getUserMedia({
739
+ const stream = await this.webRTCApiProvider.mediaDevices.getUserMedia({
731
740
  audio: deviceInfo.kind === "audioinput" ? constraints : false,
732
741
  video: deviceInfo.kind === "videoinput" ? constraints : false
733
742
  });
@@ -899,9 +908,23 @@ var DependencyContainer = class {
899
908
  this._webSocketConstructor = WebSocketConstructor;
900
909
  }
901
910
  get deviceController() {
902
- this._deviceController ??= new NavigatorDeviceController();
911
+ this._deviceController ??= new NavigatorDeviceController(this.webRTCApiProvider);
903
912
  return this._deviceController;
904
913
  }
914
+ get webRTCApiProvider() {
915
+ if (!this._webRTCApiProvider) {
916
+ if (typeof RTCPeerConnection === "undefined" || typeof navigator === "undefined") throw new require_operators.DependencyError("WebRTCApiProvider: RTCPeerConnection or navigator.mediaDevices is not available. Please provide a custom webRTCApiProvider in SignalWireOptions.");
917
+ this._webRTCApiProvider = {
918
+ RTCPeerConnection,
919
+ mediaDevices: navigator.mediaDevices
920
+ };
921
+ }
922
+ return this._webRTCApiProvider;
923
+ }
924
+ set webRTCApiProvider(webRTCApiProvider) {
925
+ this._webRTCApiProvider = webRTCApiProvider;
926
+ this._deviceController = void 0;
927
+ }
905
928
  get authorizationStateKey() {
906
929
  return `sw:${this.subscriberId}:as`;
907
930
  }
@@ -1375,7 +1398,7 @@ var SelfCapabilities = class extends Destroyable {
1375
1398
  }
1376
1399
  /** Observable for self member capabilities */
1377
1400
  get self$() {
1378
- return this._state$.pipe((0, rxjs.map)((state) => state.self), (0, rxjs.distinctUntilChanged)());
1401
+ return this.cachedObservable("self$", () => this._state$.pipe((0, rxjs.map)((state) => state.self), (0, rxjs.distinctUntilChanged)()));
1379
1402
  }
1380
1403
  /** Current self member capabilities */
1381
1404
  get self() {
@@ -1383,7 +1406,7 @@ var SelfCapabilities = class extends Destroyable {
1383
1406
  }
1384
1407
  /** Observable for other member capabilities */
1385
1408
  get member$() {
1386
- return this._state$.pipe((0, rxjs.map)((state) => state.member), (0, rxjs.distinctUntilChanged)());
1409
+ return this.cachedObservable("member$", () => this._state$.pipe((0, rxjs.map)((state) => state.member), (0, rxjs.distinctUntilChanged)()));
1387
1410
  }
1388
1411
  /** Current other member capabilities */
1389
1412
  get member() {
@@ -1391,7 +1414,7 @@ var SelfCapabilities = class extends Destroyable {
1391
1414
  }
1392
1415
  /** Observable for end call capability */
1393
1416
  get end$() {
1394
- return this._state$.pipe((0, rxjs.map)((state) => state.end), (0, rxjs.distinctUntilChanged)());
1417
+ return this.cachedObservable("end$", () => this._state$.pipe((0, rxjs.map)((state) => state.end), (0, rxjs.distinctUntilChanged)()));
1395
1418
  }
1396
1419
  /** Current end call capability */
1397
1420
  get end() {
@@ -1399,7 +1422,7 @@ var SelfCapabilities = class extends Destroyable {
1399
1422
  }
1400
1423
  /** Observable for set layout capability */
1401
1424
  get setLayout$() {
1402
- return this._state$.pipe((0, rxjs.map)((state) => state.setLayout), (0, rxjs.distinctUntilChanged)());
1425
+ return this.cachedObservable("setLayout$", () => this._state$.pipe((0, rxjs.map)((state) => state.setLayout), (0, rxjs.distinctUntilChanged)()));
1403
1426
  }
1404
1427
  /** Current set layout capability */
1405
1428
  get setLayout() {
@@ -1407,7 +1430,7 @@ var SelfCapabilities = class extends Destroyable {
1407
1430
  }
1408
1431
  /** Observable for send digit capability */
1409
1432
  get sendDigit$() {
1410
- return this._state$.pipe((0, rxjs.map)((state) => state.sendDigit), (0, rxjs.distinctUntilChanged)());
1433
+ return this.cachedObservable("sendDigit$", () => this._state$.pipe((0, rxjs.map)((state) => state.sendDigit), (0, rxjs.distinctUntilChanged)()));
1411
1434
  }
1412
1435
  /** Current send digit capability */
1413
1436
  get sendDigit() {
@@ -1415,7 +1438,7 @@ var SelfCapabilities = class extends Destroyable {
1415
1438
  }
1416
1439
  /** Observable for vmuted hide capability */
1417
1440
  get vmutedHide$() {
1418
- return this._state$.pipe((0, rxjs.map)((state) => state.vmutedHide), (0, rxjs.distinctUntilChanged)());
1441
+ return this.cachedObservable("vmutedHide$", () => this._state$.pipe((0, rxjs.map)((state) => state.vmutedHide), (0, rxjs.distinctUntilChanged)()));
1419
1442
  }
1420
1443
  /** Current vmuted hide capability */
1421
1444
  get vmutedHide() {
@@ -1423,7 +1446,7 @@ var SelfCapabilities = class extends Destroyable {
1423
1446
  }
1424
1447
  /** Observable for lock capability */
1425
1448
  get lock$() {
1426
- return this._state$.pipe((0, rxjs.map)((state) => state.lock), (0, rxjs.distinctUntilChanged)());
1449
+ return this.cachedObservable("lock$", () => this._state$.pipe((0, rxjs.map)((state) => state.lock), (0, rxjs.distinctUntilChanged)()));
1427
1450
  }
1428
1451
  /** Current lock capability */
1429
1452
  get lock() {
@@ -1431,7 +1454,7 @@ var SelfCapabilities = class extends Destroyable {
1431
1454
  }
1432
1455
  /** Observable for device capability */
1433
1456
  get device$() {
1434
- return this._state$.pipe((0, rxjs.map)((state) => state.device), (0, rxjs.distinctUntilChanged)());
1457
+ return this.cachedObservable("device$", () => this._state$.pipe((0, rxjs.map)((state) => state.device), (0, rxjs.distinctUntilChanged)()));
1435
1458
  }
1436
1459
  /** Current device capability */
1437
1460
  get device() {
@@ -1439,7 +1462,7 @@ var SelfCapabilities = class extends Destroyable {
1439
1462
  }
1440
1463
  /** Observable for screenshare capability */
1441
1464
  get screenshare$() {
1442
- return this._state$.pipe((0, rxjs.map)((state) => state.screenshare), (0, rxjs.distinctUntilChanged)());
1465
+ return this.cachedObservable("screenshare$", () => this._state$.pipe((0, rxjs.map)((state) => state.screenshare), (0, rxjs.distinctUntilChanged)()));
1443
1466
  }
1444
1467
  /** Current screenshare capability */
1445
1468
  get screenshare() {
@@ -1492,83 +1515,83 @@ var Participant = class extends Destroyable {
1492
1515
  }
1493
1516
  /** Observable of the participant's display name. */
1494
1517
  get name$() {
1495
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.name), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1518
+ return this.cachedObservable("name$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.name), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1496
1519
  }
1497
1520
  /** Observable of the participant type (e.g. `'member'`, `'screen'`). */
1498
1521
  get type$() {
1499
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.type), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1522
+ return this.cachedObservable("type$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.type), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1500
1523
  }
1501
1524
  /** Observable indicating whether the participant has raised their hand. */
1502
1525
  get handraised$() {
1503
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.handraised), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1526
+ return this.cachedObservable("handraised$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.handraised), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1504
1527
  }
1505
1528
  /** Observable indicating whether the participant is visible in the layout. */
1506
1529
  get visible$() {
1507
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.visible), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1530
+ return this.cachedObservable("visible$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.visible), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1508
1531
  }
1509
1532
  /** Observable indicating whether the participant's audio is muted. */
1510
1533
  get audioMuted$() {
1511
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.audio_muted), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1534
+ return this.cachedObservable("audioMuted$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.audio_muted), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1512
1535
  }
1513
1536
  /** Observable indicating whether the participant's video is muted. */
1514
1537
  get videoMuted$() {
1515
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.video_muted), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1538
+ return this.cachedObservable("videoMuted$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.video_muted), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1516
1539
  }
1517
1540
  /** Observable indicating whether the participant is deafened. */
1518
1541
  get deaf$() {
1519
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.deaf), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1542
+ return this.cachedObservable("deaf$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.deaf), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1520
1543
  }
1521
1544
  /** Observable of the participant's microphone input volume. */
1522
1545
  get inputVolume$() {
1523
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.input_volume), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1546
+ return this.cachedObservable("inputVolume$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.input_volume), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1524
1547
  }
1525
1548
  /** Observable of the participant's speaker output volume. */
1526
1549
  get outputVolume$() {
1527
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.output_volume), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1550
+ return this.cachedObservable("outputVolume$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.output_volume), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1528
1551
  }
1529
1552
  /** Observable of the microphone input sensitivity level. */
1530
1553
  get inputSensitivity$() {
1531
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.input_sensitivity), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1554
+ return this.cachedObservable("inputSensitivity$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.input_sensitivity), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1532
1555
  }
1533
1556
  /** Observable indicating whether echo cancellation is enabled. */
1534
1557
  get echoCancellation$() {
1535
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.echo_cancellation), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1558
+ return this.cachedObservable("echoCancellation$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.echo_cancellation), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1536
1559
  }
1537
1560
  /** Observable indicating whether auto-gain control is enabled. */
1538
1561
  get autoGain$() {
1539
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.auto_gain), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1562
+ return this.cachedObservable("autoGain$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.auto_gain), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1540
1563
  }
1541
1564
  /** Observable indicating whether noise suppression is enabled. */
1542
1565
  get noiseSuppression$() {
1543
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.noise_suppression), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1566
+ return this.cachedObservable("noiseSuppression$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.noise_suppression), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1544
1567
  }
1545
1568
  /** Observable indicating whether low-bitrate mode is active. */
1546
1569
  get lowbitrate$() {
1547
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.lowbitrate), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1570
+ return this.cachedObservable("lowbitrate$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.lowbitrate), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1548
1571
  }
1549
1572
  /** Observable indicating whether noise reduction is active. */
1550
1573
  get denoise$() {
1551
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.denoise), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1574
+ return this.cachedObservable("denoise$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.denoise), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1552
1575
  }
1553
1576
  /** Observable of custom metadata for this participant. */
1554
1577
  get meta$() {
1555
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.meta), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1578
+ return this.cachedObservable("meta$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.meta), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1556
1579
  }
1557
1580
  /** Observable of the participant's subscriber ID. */
1558
1581
  get subscriberId$() {
1559
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.subscriber_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1582
+ return this.cachedObservable("subscriberId$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.subscriber_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1560
1583
  }
1561
1584
  /** Observable of the participant's address ID. */
1562
1585
  get addressId$() {
1563
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.address_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1586
+ return this.cachedObservable("addressId$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.address_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1564
1587
  }
1565
1588
  /** Observable of the server node ID for this participant. */
1566
1589
  get nodeId$() {
1567
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.node_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1590
+ return this.cachedObservable("nodeId$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.node_id), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1568
1591
  }
1569
1592
  /** Observable indicating whether the participant is currently speaking. */
1570
1593
  get isTalking$() {
1571
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.talking), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1594
+ return this.cachedObservable("isTalking$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.talking), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1572
1595
  }
1573
1596
  /** Whether the participant is currently speaking. */
1574
1597
  get isTalking() {
@@ -1576,7 +1599,7 @@ var Participant = class extends Destroyable {
1576
1599
  }
1577
1600
  /** Observable of the participant's layout position. */
1578
1601
  get position$() {
1579
- return this._state$.pipe((0, rxjs_operators.map)((state) => state.position), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull());
1602
+ return this.cachedObservable("position$", () => this._state$.pipe((0, rxjs_operators.map)((state) => state.position), (0, rxjs_operators.distinctUntilChanged)(), require_operators.filterNull()));
1580
1603
  }
1581
1604
  /** Current layout position. */
1582
1605
  get position() {
@@ -1895,7 +1918,7 @@ function isJSONRPCRequest(value) {
1895
1918
  return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "method") && typeof value.method === "string";
1896
1919
  }
1897
1920
  function isJSONRPCResponse(value) {
1898
- return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && hasProperty(value, "result");
1921
+ return isObject(value) && hasProperty(value, "jsonrpc") && value.jsonrpc === "2.0" && hasProperty(value, "id") && typeof value.id === "string" && (hasProperty(value, "result") || hasProperty(value, "error"));
1899
1922
  }
1900
1923
 
1901
1924
  //#endregion
@@ -1976,10 +1999,10 @@ var CallEventsManager = class extends Destroyable {
1976
1999
  this.initSubscriptions();
1977
2000
  }
1978
2001
  get participants$() {
1979
- return this._participants$.asObservable().pipe((0, rxjs.map)((participantsRecord) => Object.values(participantsRecord)));
2002
+ return this.cachedObservable("participants$", () => this._participants$.asObservable().pipe((0, rxjs.map)((participantsRecord) => Object.values(participantsRecord))));
1980
2003
  }
1981
2004
  get self$() {
1982
- return this._self$.asObservable().pipe(require_operators.filterNull());
2005
+ return this.cachedObservable("self$", () => this._self$.asObservable().pipe(require_operators.filterNull()));
1983
2006
  }
1984
2007
  get status$() {
1985
2008
  return this._status$.asObservable();
@@ -1997,40 +2020,40 @@ var CallEventsManager = class extends Destroyable {
1997
2020
  return this.callIds.has(callId);
1998
2021
  }
1999
2022
  get recording$() {
2000
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.recording), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2023
+ return this.cachedObservable("recording$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.recording), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2001
2024
  }
2002
2025
  get recordings$() {
2003
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.recordings), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2026
+ return this.cachedObservable("recordings$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.recordings), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2004
2027
  }
2005
2028
  get streaming$() {
2006
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.streaming), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2029
+ return this.cachedObservable("streaming$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.streaming), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2007
2030
  }
2008
2031
  get streams$() {
2009
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.streams), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2032
+ return this.cachedObservable("streams$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.streams), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2010
2033
  }
2011
2034
  get playbacks$() {
2012
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.playbacks), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2035
+ return this.cachedObservable("playbacks$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.playbacks), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2013
2036
  }
2014
2037
  get raiseHandPriority$() {
2015
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.prioritize_handraise), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2038
+ return this.cachedObservable("raiseHandPriority$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.prioritize_handraise), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2016
2039
  }
2017
2040
  get locked$() {
2018
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.locked), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2041
+ return this.cachedObservable("locked$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.locked), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2019
2042
  }
2020
2043
  get meta$() {
2021
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.meta), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2044
+ return this.cachedObservable("meta$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.meta), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2022
2045
  }
2023
2046
  get capabilities$() {
2024
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.capabilities), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2047
+ return this.cachedObservable("capabilities$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.capabilities), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2025
2048
  }
2026
2049
  get layout$() {
2027
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.layout_name), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2050
+ return this.cachedObservable("layout$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.layout_name), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2028
2051
  }
2029
2052
  get layouts$() {
2030
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.layouts), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2053
+ return this.cachedObservable("layouts$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.layouts), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2031
2054
  }
2032
2055
  get layoutLayers$() {
2033
- return this._sessionState$.pipe((0, rxjs.map)((state) => state.layout_layers), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull());
2056
+ return this.cachedObservable("layoutLayers$", () => this._sessionState$.pipe((0, rxjs.map)((state) => state.layout_layers), (0, rxjs.distinctUntilChanged)(), require_operators.filterNull()));
2034
2057
  }
2035
2058
  get self() {
2036
2059
  return this._self$.value;
@@ -2166,19 +2189,19 @@ var CallEventsManager = class extends Destroyable {
2166
2189
  this._participants$.next(this._participants$.value);
2167
2190
  }
2168
2191
  get callJoinedEvent$() {
2169
- return this.webRtcCallSession.callEvent$.pipe((0, rxjs.filter)(isCallJoinedPayload), (0, rxjs.tap)((event) => {
2192
+ return this.cachedObservable("callJoinedEvent$", () => this.webRtcCallSession.callEvent$.pipe((0, rxjs.filter)(isCallJoinedPayload), (0, rxjs.tap)((event) => {
2170
2193
  logger$15.debug("[CallEventsManager] Call joined event:", event);
2171
- }));
2194
+ })));
2172
2195
  }
2173
2196
  get layoutChangedEvent$() {
2174
- return this.webRtcCallSession.callEvent$.pipe(require_operators.filterAs(isLayoutChangedPayload, "layout"), (0, rxjs.tap)((event) => {
2197
+ return this.cachedObservable("layoutChangedEvent$", () => this.webRtcCallSession.callEvent$.pipe(require_operators.filterAs(isLayoutChangedPayload, "layout"), (0, rxjs.tap)((event) => {
2175
2198
  logger$15.debug("[CallEventsManager] Layout changed event:", event);
2176
- }));
2199
+ })));
2177
2200
  }
2178
2201
  get memberUpdates$() {
2179
- return (0, rxjs.merge)(this.webRtcCallSession.memberJoined$, this.webRtcCallSession.memberUpdated$, this.webRtcCallSession.memberTalking$).pipe((0, rxjs.map)((event) => event.member), (0, rxjs.tap)((event) => {
2202
+ return this.cachedObservable("memberUpdates$", () => (0, rxjs.merge)(this.webRtcCallSession.memberJoined$, this.webRtcCallSession.memberUpdated$, this.webRtcCallSession.memberTalking$).pipe((0, rxjs.map)((event) => event.member), (0, rxjs.tap)((event) => {
2180
2203
  logger$15.debug("[CallEventsManager] Member update event:", event);
2181
- }));
2204
+ })));
2182
2205
  }
2183
2206
  destroy() {
2184
2207
  Object.values(this._participants$.value).forEach((participant) => {
@@ -2817,7 +2840,7 @@ var RTCPeerConnectionController = class extends Destroyable {
2817
2840
  logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
2818
2841
  return;
2819
2842
  }
2820
- const streamTrack = (await navigator.mediaDevices.getUserMedia({ [kind]: {
2843
+ const streamTrack = (await this.getUserMedia({ [kind]: {
2821
2844
  ...track.getConstraints(),
2822
2845
  ...this.deviceController.deviceInfoToConstraints(deviceInfo)
2823
2846
  } })).getTracks().find((t) => t.kind === kind);
@@ -2906,43 +2929,43 @@ var RTCPeerConnectionController = class extends Destroyable {
2906
2929
  };
2907
2930
  }
2908
2931
  get iceGatheringState$() {
2909
- return this._iceGatheringState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2932
+ return this.cachedObservable("iceGatheringState$", () => this._iceGatheringState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2910
2933
  }
2911
2934
  get mediaTrackEnded$() {
2912
- return this.localStreamController.mediaTrackEnded$.pipe((0, rxjs.takeUntil)(this.destroyed$));
2935
+ return this.cachedObservable("mediaTrackEnded$", () => this.localStreamController.mediaTrackEnded$.pipe((0, rxjs.takeUntil)(this.destroyed$)));
2913
2936
  }
2914
2937
  get errors$() {
2915
- return this._errors$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2938
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2916
2939
  }
2917
2940
  get iceCandidates$() {
2918
- return this._iceCandidates$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2941
+ return this.cachedObservable("iceCandidates$", () => this._iceCandidates$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2919
2942
  }
2920
2943
  get initialized$() {
2921
- return this._initialized$.asObservable().pipe((0, rxjs.filter)((initialized) => initialized), (0, rxjs.takeUntil)(this.destroyed$));
2944
+ return this.cachedObservable("initialized$", () => this._initialized$.asObservable().pipe((0, rxjs.filter)((initialized) => initialized), (0, rxjs.takeUntil)(this.destroyed$)));
2922
2945
  }
2923
2946
  get remoteDescription$() {
2924
- return this._remoteDescription$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2947
+ return this.cachedObservable("remoteDescription$", () => this._remoteDescription$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2925
2948
  }
2926
2949
  get localStream$() {
2927
- return this.localStreamController.localStream$.pipe((0, rxjs.takeUntil)(this.destroyed$));
2950
+ return this.cachedObservable("localStream$", () => this.localStreamController.localStream$.pipe((0, rxjs.takeUntil)(this.destroyed$)));
2928
2951
  }
2929
2952
  get remoteStream$() {
2930
- return this._remoteStream$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2953
+ return this.cachedObservable("remoteStream$", () => this._remoteStream$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2931
2954
  }
2932
2955
  get localAudioTracks$() {
2933
- return this.localStreamController.localAudioTracks$.pipe((0, rxjs.takeUntil)(this.destroyed$));
2956
+ return this.cachedObservable("localAudioTracks$", () => this.localStreamController.localAudioTracks$.pipe((0, rxjs.takeUntil)(this.destroyed$)));
2934
2957
  }
2935
2958
  get localVideoTracks$() {
2936
- return this.localStreamController.localVideoTracks$.pipe((0, rxjs.takeUntil)(this.destroyed$));
2959
+ return this.cachedObservable("localVideoTracks$", () => this.localStreamController.localVideoTracks$.pipe((0, rxjs.takeUntil)(this.destroyed$)));
2937
2960
  }
2938
2961
  get iceConnectionState$() {
2939
- return this._iceConnectionState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2962
+ return this.cachedObservable("iceConnectionState$", () => this._iceConnectionState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2940
2963
  }
2941
2964
  get connectionState$() {
2942
- return this._connectionState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2965
+ return this.cachedObservable("connectionState$", () => this._connectionState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2943
2966
  }
2944
2967
  get signalingState$() {
2945
- return this._signalingState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$));
2968
+ return this.cachedObservable("signalingState$", () => this._signalingState$.asObservable().pipe((0, rxjs.takeUntil)(this.destroyed$)));
2946
2969
  }
2947
2970
  get type() {
2948
2971
  return this._type;
@@ -3008,7 +3031,7 @@ var RTCPeerConnectionController = class extends Destroyable {
3008
3031
  };
3009
3032
  }
3010
3033
  get WebRTCPeerConnectionConstructor() {
3011
- return this.options.WebRTCPeerConnectionConstructor ?? RTCPeerConnection;
3034
+ return this.options.webRTCApiProvider?.RTCPeerConnection ?? RTCPeerConnection;
3012
3035
  }
3013
3036
  get offerOptions() {
3014
3037
  const options = { iceRestart: this.firstSDPExchangeCompleted ? true : void 0 };
@@ -3275,10 +3298,12 @@ var RTCPeerConnectionController = class extends Destroyable {
3275
3298
  }
3276
3299
  }
3277
3300
  async getUserMedia(constraints) {
3278
- return this.options.getUserMedia?.(constraints) ?? navigator.mediaDevices.getUserMedia(constraints);
3301
+ return (this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices).getUserMedia(constraints);
3279
3302
  }
3280
3303
  async getDisplayMedia(options) {
3281
- return this.options.getDisplayMedia?.(options) ?? navigator.mediaDevices.getDisplayMedia(options);
3304
+ const mediaDevices = this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices;
3305
+ if (!mediaDevices.getDisplayMedia) throw new require_operators.DependencyError("getDisplayMedia is not supported by the current WebRTC provider");
3306
+ return mediaDevices.getDisplayMedia(options);
3282
3307
  }
3283
3308
  async setupRemoteTracks() {
3284
3309
  if (!this.peerConnection) throw new require_operators.DependencyError("RTCPeerConnection is not initialized");
@@ -3442,11 +3467,12 @@ var VertoManager = class extends Destroyable {
3442
3467
  }
3443
3468
  };
3444
3469
  var WebRTCVertoManager = class extends VertoManager {
3445
- constructor(webRtcCallSession, attachManager, deviceController, options = {}) {
3470
+ constructor(webRtcCallSession, attachManager, deviceController, webRTCApiProvider, options = {}) {
3446
3471
  super(webRtcCallSession);
3447
3472
  this.webRtcCallSession = webRtcCallSession;
3448
3473
  this.attachManager = attachManager;
3449
3474
  this.deviceController = deviceController;
3475
+ this.webRTCApiProvider = webRTCApiProvider;
3450
3476
  this._rtcPeerConnections$ = this.createBehaviorSubject([]);
3451
3477
  this._selfId$ = this.createBehaviorSubject(null);
3452
3478
  this._signalingStatus$ = this.createBehaviorSubject(null);
@@ -3520,11 +3546,11 @@ var WebRTCVertoManager = class extends VertoManager {
3520
3546
  return rtcPeerConnection;
3521
3547
  }
3522
3548
  get signalingStatus$() {
3523
- return (0, rxjs.merge)(this._signalingStatus$.pipe(require_operators.filterNull()), this.mainPeerConnection.connectionState$.pipe((0, rxjs.filter)((connectionState) => [
3549
+ return this.cachedObservable("signalingStatus$", () => (0, rxjs.merge)(this._signalingStatus$.pipe(require_operators.filterNull()), this.mainPeerConnection.connectionState$.pipe((0, rxjs.filter)((connectionState) => [
3524
3550
  "connected",
3525
3551
  "disconnected",
3526
3552
  "failed"
3527
- ].includes(connectionState))));
3553
+ ].includes(connectionState)))));
3528
3554
  }
3529
3555
  initSubscriptions() {
3530
3556
  this.subscribeTo(this.vertoAnswer$, (event) => {
@@ -3572,19 +3598,19 @@ var WebRTCVertoManager = class extends VertoManager {
3572
3598
  return this._selfId$.value;
3573
3599
  }
3574
3600
  get vertoAnswer$() {
3575
- return this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoAnswerInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$));
3601
+ return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoAnswerInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
3576
3602
  }
3577
3603
  get vertoMediaParams$() {
3578
- return this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoMediaParamsInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$));
3604
+ return this.cachedObservable("vertoMediaParams$", () => this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoMediaParamsInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
3579
3605
  }
3580
3606
  get vertoBye$() {
3581
- return this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoByeMessage, "params"), (0, rxjs.takeUntil)(this.destroyed$));
3607
+ return this.cachedObservable("vertoBye$", () => this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoByeMessage, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
3582
3608
  }
3583
3609
  get vertoAttach$() {
3584
- return this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoAttachMessage, "params"), (0, rxjs.takeUntil)(this.destroyed$));
3610
+ return this.cachedObservable("vertoAttach$", () => this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoAttachMessage, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
3585
3611
  }
3586
3612
  get vertoPing$() {
3587
- return this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoPingInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$));
3613
+ return this.cachedObservable("vertoPing$", () => this.webRtcCallSession.webrtcMessages$.pipe(require_operators.filterAs(isVertoPingInnerParams, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
3588
3614
  }
3589
3615
  async executeVerto(message, optionals = {}) {
3590
3616
  const webrtcVertoMessage = WebrtcVerto({
@@ -3609,7 +3635,7 @@ var WebRTCVertoManager = class extends VertoManager {
3609
3635
  }
3610
3636
  async sendLocalDescription(message, rtcPeerConnController) {
3611
3637
  const vertoMethod = message.method;
3612
- const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController);
3638
+ const optionalsParams = this.getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod);
3613
3639
  try {
3614
3640
  const response = await this.executeVerto(message, optionalsParams);
3615
3641
  switch (vertoMethod) {
@@ -3686,6 +3712,7 @@ var WebRTCVertoManager = class extends VertoManager {
3686
3712
  inputVideoStream: options.inputVideoStream,
3687
3713
  receiveAudio: options.receiveAudio,
3688
3714
  receiveVideo: options.receiveVideo,
3715
+ webRTCApiProvider: this.webRTCApiProvider,
3689
3716
  ...this.RTCPeerConnectionConfig
3690
3717
  }, options.initOffer, this.deviceController);
3691
3718
  this.setupLocalDescriptionHandler(rtcPeerConnController);
@@ -3752,18 +3779,18 @@ var WebRTCVertoManager = class extends VertoManager {
3752
3779
  this.callSession?.destroy();
3753
3780
  });
3754
3781
  }
3755
- getSendLocalSDPOptionalParams(rtcPeerConnController) {
3782
+ getSendLocalSDPOptionalParams(rtcPeerConnController, vertoMethod) {
3756
3783
  let subscribe = void 0;
3757
- const initial = !rtcPeerConnController.firstSDPExchangeCompleted;
3758
- if (initial) {
3784
+ if (!rtcPeerConnController.firstSDPExchangeCompleted) {
3759
3785
  subscribe = [];
3760
3786
  if (rtcPeerConnController.isMainDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeMainDevice);
3761
3787
  else if (rtcPeerConnController.isAdditionalDevice) subscribe.push(...PreferencesContainer.instance.inviteSubscribeAdditionalDevice);
3762
3788
  else if (rtcPeerConnController.isScreenShare) subscribe.push(...PreferencesContainer.instance.inviteSubscribeScreenshare);
3763
3789
  }
3790
+ const isInvite = vertoMethod === "verto.invite";
3764
3791
  return {
3765
3792
  callID: rtcPeerConnController.id,
3766
- node_id: initial ? "" : this._nodeId$.value ?? "",
3793
+ node_id: isInvite ? "" : this._nodeId$.value ?? "",
3767
3794
  subscribe
3768
3795
  };
3769
3796
  }
@@ -3864,7 +3891,8 @@ var WebRTCVertoManager = class extends VertoManager {
3864
3891
  rtcPeerConnController = new RTCPeerConnectionController({
3865
3892
  ...options,
3866
3893
  ...this.RTCPeerConnectionConfig,
3867
- propose
3894
+ propose,
3895
+ webRTCApiProvider: this.webRTCApiProvider
3868
3896
  }, void 0, this.deviceController);
3869
3897
  this.setupLocalDescriptionHandler(rtcPeerConnController);
3870
3898
  if (propose === "screenshare") this._screenShareId = rtcPeerConnController.id;
@@ -4145,7 +4173,7 @@ var WebRTCCall = class extends Destroyable {
4145
4173
  }
4146
4174
  /** Observable of the current call status (e.g. `'ringing'`, `'connected'`). */
4147
4175
  get status$() {
4148
- return (0, rxjs.merge)(this._status$.asObservable(), this.vertoManager.signalingStatus$);
4176
+ return this.cachedObservable("status$", () => (0, rxjs.merge)(this._status$.asObservable(), this.vertoManager.signalingStatus$));
4149
4177
  }
4150
4178
  /** Observable of the participants list, emits on join/leave/update. */
4151
4179
  get participants$() {
@@ -4249,7 +4277,7 @@ var WebRTCCall = class extends Destroyable {
4249
4277
  return this.vertoManager.mediaDirections;
4250
4278
  }
4251
4279
  get participantsId$() {
4252
- return this.participants$.pipe((0, rxjs.map)((participants) => participants.map((participant) => participant.id)));
4280
+ return this.cachedObservable("participantsId$", () => this.participants$.pipe((0, rxjs.map)((participants) => participants.map((participant) => participant.id))));
4253
4281
  }
4254
4282
  /** Executes a raw JSON-RPC request on the client session. */
4255
4283
  async execute(request, options) {
@@ -4284,35 +4312,35 @@ var WebRTCCall = class extends Destroyable {
4284
4312
  }
4285
4313
  }
4286
4314
  get callSessionEvents$() {
4287
- return this.clientSession.signalingEvent$.pipe((0, rxjs.filter)((event) => this.isCallSessionEvent(event)), (0, rxjs.tap)((event) => logger$9.debug("[Call] Received call session event:", event)), (0, rxjs.takeUntil)(this.destroyed$));
4315
+ return this.cachedObservable("callSessionEvents$", () => this.clientSession.signalingEvent$.pipe((0, rxjs.filter)((event) => this.isCallSessionEvent(event)), (0, rxjs.tap)((event) => logger$9.debug("[Call] Received call session event:", event)), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.share)()));
4288
4316
  }
4289
4317
  /** Observable of call-updated events. */
4290
4318
  get callUpdated$() {
4291
- return this.callSessionEvents$.pipe(require_operators.filterAs(isCallUpdatedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4319
+ return this.cachedObservable("callUpdated$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isCallUpdatedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4292
4320
  }
4293
4321
  /** Observable of member-joined events. */
4294
4322
  get memberJoined$() {
4295
- return this.callSessionEvents$.pipe(require_operators.filterAs(isMemberJoinedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4323
+ return this.cachedObservable("memberJoined$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isMemberJoinedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4296
4324
  }
4297
4325
  /** Observable of member-left events. */
4298
4326
  get memberLeft$() {
4299
- return this.callSessionEvents$.pipe(require_operators.filterAs(isMemberLeftMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4327
+ return this.cachedObservable("memberLeft$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isMemberLeftMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4300
4328
  }
4301
4329
  /** Observable of member-updated events (mute, volume, etc.). */
4302
4330
  get memberUpdated$() {
4303
- return this.callSessionEvents$.pipe(require_operators.filterAs(isMemberUpdatedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4331
+ return this.cachedObservable("memberUpdated$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isMemberUpdatedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4304
4332
  }
4305
4333
  /** Observable of member-talking events (speech start/stop). */
4306
4334
  get memberTalking$() {
4307
- return this.callSessionEvents$.pipe(require_operators.filterAs(isMemberTalkingMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4335
+ return this.cachedObservable("memberTalking$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isMemberTalkingMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4308
4336
  }
4309
4337
  /** Observable of call state-change events. */
4310
4338
  get callStates$() {
4311
- return this.callSessionEvents$.pipe(require_operators.filterAs(isCallStateMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4339
+ return this.cachedObservable("callStates$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isCallStateMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4312
4340
  }
4313
4341
  /** Observable of layout-changed events. */
4314
4342
  get layoutUpdates$() {
4315
- return this.callSessionEvents$.pipe(require_operators.filterAs(isLayoutChangedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$));
4343
+ return this.cachedObservable("layoutUpdates$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isLayoutChangedMetadata, "params"), (0, rxjs.takeUntil)(this.destroyed$)));
4316
4344
  }
4317
4345
  /** Underlying `RTCPeerConnection`, for advanced use cases. */
4318
4346
  get rtcPeerConnection() {
@@ -4320,19 +4348,19 @@ var WebRTCCall = class extends Destroyable {
4320
4348
  }
4321
4349
  /** Observable of raw signaling events as plain objects. */
4322
4350
  get signalingEvent$() {
4323
- return this.callEvent$.pipe((0, rxjs.map)((event) => JSON.parse(JSON.stringify(event))));
4351
+ return this.cachedObservable("signalingEvent$", () => this.callEvent$.pipe((0, rxjs.map)((event) => JSON.parse(JSON.stringify(event)))));
4324
4352
  }
4325
4353
  /** Observable of WebRTC-specific signaling messages. */
4326
4354
  get webrtcMessages$() {
4327
- return this.callSessionEvents$.pipe(require_operators.filterAs(isWebrtcMessageMetadata, "params"), (0, rxjs.tap)((event) => logger$9.debug("[Call] Event is a WebRTC message event:", event)), (0, rxjs.takeUntil)(this.destroyed$));
4355
+ return this.cachedObservable("webrtcMessages$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isWebrtcMessageMetadata, "params"), (0, rxjs.tap)((event) => logger$9.debug("[Call] Event is a WebRTC message event:", event)), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.share)()));
4328
4356
  }
4329
4357
  /** Observable of call-level signaling events. */
4330
4358
  get callEvent$() {
4331
- return this.callSessionEvents$.pipe(require_operators.filterAs(isSignalwireCallMetadata, "params"), (0, rxjs.tap)((event) => logger$9.debug("[Call] Event is a call event:", event)), (0, rxjs.takeUntil)(this.destroyed$));
4359
+ return this.cachedObservable("callEvent$", () => this.callSessionEvents$.pipe(require_operators.filterAs(isSignalwireCallMetadata, "params"), (0, rxjs.tap)((event) => logger$9.debug("[Call] Event is a call event:", event)), (0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.share)()));
4332
4360
  }
4333
4361
  /** Observable of layout-changed signaling events. */
4334
4362
  get layoutEvent$() {
4335
- return this.callEvent$.pipe(require_operators.filterAs(isLayoutChangedMetadata, "params"));
4363
+ return this.cachedObservable("layoutEvent$", () => this.callEvent$.pipe(require_operators.filterAs(isLayoutChangedMetadata, "params")));
4336
4364
  }
4337
4365
  /** Hangs up the call and releases all resources. */
4338
4366
  async hangup() {
@@ -4393,10 +4421,11 @@ var WebRTCCall = class extends Destroyable {
4393
4421
  * Eliminates circular dependencies by centralizing Call and Manager creation.
4394
4422
  */
4395
4423
  var CallFactory = class {
4396
- constructor(sessionManager, deviceController, attachManager) {
4424
+ constructor(sessionManager, deviceController, attachManager, webRTCApiProvider) {
4397
4425
  this.sessionManager = sessionManager;
4398
4426
  this.deviceController = deviceController;
4399
4427
  this.attachManager = attachManager;
4428
+ this.webRTCApiProvider = webRTCApiProvider;
4400
4429
  }
4401
4430
  /**
4402
4431
  * Create a new WebRTCCall with properly initialized managers
@@ -4405,7 +4434,7 @@ var CallFactory = class {
4405
4434
  return new WebRTCCall(this.sessionManager, options, {
4406
4435
  initializeManagers: (callInstance) => {
4407
4436
  return {
4408
- vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, {
4437
+ vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, this.webRTCApiProvider, {
4409
4438
  nodeId: options.nodeId,
4410
4439
  onError: (error) => {
4411
4440
  callInstance.emitError(error);
@@ -4484,7 +4513,7 @@ var EntityCollection = class extends Destroyable {
4484
4513
  return this.fetchController.hasMore ?? true;
4485
4514
  }
4486
4515
  get updated$() {
4487
- return this.loading$.pipe((0, rxjs.distinctUntilChanged)(), (0, rxjs.skip)(1), (0, rxjs.filter)((loading) => !loading), (0, rxjs.map)(() => void 0), (0, rxjs.takeUntil)(this._destroy$));
4516
+ return this.cachedObservable("updated$", () => this.loading$.pipe((0, rxjs.distinctUntilChanged)(), (0, rxjs.skip)(1), (0, rxjs.filter)((loading) => !loading), (0, rxjs.map)(() => void 0), (0, rxjs.takeUntil)(this._destroy$)));
4488
4517
  }
4489
4518
  get values() {
4490
4519
  return Array.from(this.collectionData.values());
@@ -4564,7 +4593,7 @@ var EntityCollectionTransformed = class {
4564
4593
  return this.originalCollection.values.filter(this.filter).map(this.mapper);
4565
4594
  }
4566
4595
  get values$() {
4567
- return this.originalCollection.values$.pipe((0, rxjs.map)((values) => values.filter(this.filter).map(this.mapper)));
4596
+ return this._values$ ??= this.originalCollection.values$.pipe((0, rxjs.map)((values) => values.filter(this.filter).map(this.mapper)));
4568
4597
  }
4569
4598
  get$(id) {
4570
4599
  const original$ = this.originalCollection.get$(id);
@@ -4637,7 +4666,7 @@ var Address = class extends Destroyable {
4637
4666
  }
4638
4667
  /** Observable of the human-readable display name. */
4639
4668
  get displayName$() {
4640
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.map)((state) => state.display_name), (0, rxjs.takeUntil)(this.destroyed$));
4669
+ return this.cachedObservable("displayName$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.map)((state) => state.display_name), (0, rxjs.takeUntil)(this.destroyed$)));
4641
4670
  }
4642
4671
  /** Human-readable display name. */
4643
4672
  get displayName() {
@@ -4646,7 +4675,7 @@ var Address = class extends Destroyable {
4646
4675
  }
4647
4676
  /** Observable of the preview image URL. */
4648
4677
  get previewUrl$() {
4649
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.map)((state) => state.preview_url), (0, rxjs.takeUntil)(this.destroyed$));
4678
+ return this.cachedObservable("previewUrl$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.map)((state) => state.preview_url), (0, rxjs.takeUntil)(this.destroyed$)));
4650
4679
  }
4651
4680
  /** Preview image URL. */
4652
4681
  get previewUrl() {
@@ -4655,7 +4684,7 @@ var Address = class extends Destroyable {
4655
4684
  }
4656
4685
  /** Observable of the cover image URL. */
4657
4686
  get coverUrl$() {
4658
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.cover_url), (0, rxjs.takeUntil)(this.destroyed$));
4687
+ return this.cachedObservable("coverUrl$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.cover_url), (0, rxjs.takeUntil)(this.destroyed$)));
4659
4688
  }
4660
4689
  /** Cover image URL. */
4661
4690
  get coverUrl() {
@@ -4664,7 +4693,7 @@ var Address = class extends Destroyable {
4664
4693
  }
4665
4694
  /** Observable of the underlying resource ID. */
4666
4695
  get resourceId$() {
4667
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.resource_id), (0, rxjs.takeUntil)(this.destroyed$));
4696
+ return this.cachedObservable("resourceId$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.resource_id), (0, rxjs.takeUntil)(this.destroyed$)));
4668
4697
  }
4669
4698
  /** Underlying resource ID. */
4670
4699
  get resourceId() {
@@ -4673,7 +4702,7 @@ var Address = class extends Destroyable {
4673
4702
  }
4674
4703
  /** Observable of the resource type (e.g. `'room'`, `'subscriber'`). */
4675
4704
  get type$() {
4676
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.type), (0, rxjs.takeUntil)(this.destroyed$));
4705
+ return this.cachedObservable("type$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.type), (0, rxjs.takeUntil)(this.destroyed$)));
4677
4706
  }
4678
4707
  /** Resource type (e.g. `'room'`, `'subscriber'`). */
4679
4708
  get type() {
@@ -4682,7 +4711,7 @@ var Address = class extends Destroyable {
4682
4711
  }
4683
4712
  /** Observable of available communication channels (audio, video, messaging). */
4684
4713
  get channels$() {
4685
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.channels), (0, rxjs.takeUntil)(this.destroyed$));
4714
+ return this.cachedObservable("channels$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.channels), (0, rxjs.takeUntil)(this.destroyed$)));
4686
4715
  }
4687
4716
  /** Available communication channels. */
4688
4717
  get channels() {
@@ -4696,7 +4725,7 @@ var Address = class extends Destroyable {
4696
4725
  }
4697
4726
  /** Observable indicating whether the address (room) is locked. */
4698
4727
  get locked$() {
4699
- return this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.locked), (0, rxjs.takeUntil)(this.destroyed$));
4728
+ return this.cachedObservable("locked$", () => this._state$.pipe(require_operators.filterNull(), (0, rxjs.shareReplay)(1), (0, rxjs.map)((state) => state.locked), (0, rxjs.takeUntil)(this.destroyed$)));
4700
4729
  }
4701
4730
  /** Sends a text message to this address. */
4702
4731
  async sendText(text) {
@@ -4817,7 +4846,7 @@ const getAddressSearchURI = (options) => {
4817
4846
  return name;
4818
4847
  };
4819
4848
  var ClientSessionManager = class extends Destroyable {
4820
- constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager) {
4849
+ constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider) {
4821
4850
  super();
4822
4851
  this.credential = credential;
4823
4852
  this.transport = transport;
@@ -4840,11 +4869,11 @@ var ClientSessionManager = class extends Destroyable {
4840
4869
  this._calls$ = this.createBehaviorSubject({});
4841
4870
  this._iceServers$ = this.createBehaviorSubject([]);
4842
4871
  attachManager.setSession(this);
4843
- this.callFactory = new CallFactory(this, deviceController, attachManager);
4872
+ this.callFactory = new CallFactory(this, deviceController, attachManager, webRTCApiProvider);
4844
4873
  this.initialized$ = (0, rxjs.defer)(() => (0, rxjs.from)(this.init())).pipe((0, rxjs.shareReplay)(1), (0, rxjs.takeUntil)(this.destroyed$));
4845
4874
  }
4846
4875
  get incomingCalls$() {
4847
- return this.calls$.pipe((0, rxjs.map)((calls) => calls.filter((call) => call.direction === "inbound")));
4876
+ return this.cachedObservable("incomingCalls$", () => this.calls$.pipe((0, rxjs.map)((calls) => calls.filter((call) => call.direction === "inbound"))));
4848
4877
  }
4849
4878
  get incomingCalls() {
4850
4879
  return Object.values(this._calls$.value).filter((call) => call.direction === "inbound");
@@ -4856,7 +4885,7 @@ var ClientSessionManager = class extends Destroyable {
4856
4885
  return this._subscriberInfo$.value;
4857
4886
  }
4858
4887
  get calls$() {
4859
- return this._calls$.pipe((0, rxjs.map)((calls) => Object.values(calls)));
4888
+ return this.cachedObservable("calls$", () => this._calls$.pipe((0, rxjs.map)((calls) => Object.values(calls))));
4860
4889
  }
4861
4890
  get calls() {
4862
4891
  return Object.values(this._calls$.value);
@@ -4959,20 +4988,20 @@ var ClientSessionManager = class extends Destroyable {
4959
4988
  }
4960
4989
  }
4961
4990
  get authStateEvent$() {
4962
- return this.signalingEvent$.pipe((0, rxjs.tap)((msg) => {
4991
+ return this.cachedObservable("authStateEvent$", () => this.signalingEvent$.pipe((0, rxjs.tap)((msg) => {
4963
4992
  logger$6.debug("[Session] Received incoming message:", msg);
4964
4993
  }), require_operators.filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, rxjs.tap)((event) => {
4965
4994
  logger$6.debug("[Session] Authorization state event received:", event.authorization_state);
4966
- }));
4995
+ })));
4967
4996
  }
4968
4997
  get signalingEvent$() {
4969
- return this.transport.incomingEvent$.pipe(require_operators.filterAs(isSignalwireRequest, "params"));
4998
+ return this.cachedObservable("signalingEvent$", () => this.transport.incomingEvent$.pipe(require_operators.filterAs(isSignalwireRequest, "params"), (0, rxjs.share)()));
4970
4999
  }
4971
5000
  get vertoInvite$() {
4972
- return this.signalingEvent$.pipe((0, rxjs.filter)(isWebrtcMessageMetadata), (0, rxjs.filter)((event) => isVertoInviteMessage(event.params)), (0, rxjs.map)((event) => ({
5001
+ return this.cachedObservable("vertoInvite$", () => this.signalingEvent$.pipe((0, rxjs.filter)(isWebrtcMessageMetadata), (0, rxjs.filter)((event) => isVertoInviteMessage(event.params)), (0, rxjs.map)((event) => ({
4973
5002
  node_id: event.node_id,
4974
5003
  ...event.params.params
4975
- })));
5004
+ }))));
4976
5005
  }
4977
5006
  get contexts() {
4978
5007
  return [];
@@ -5137,6 +5166,9 @@ var ClientSessionWrapper = class {
5137
5166
  get signalingEvent$() {
5138
5167
  return this.clientSessionManager.signalingEvent$;
5139
5168
  }
5169
+ get iceServers() {
5170
+ return this.clientSessionManager.iceServers;
5171
+ }
5140
5172
  async execute(request, options) {
5141
5173
  return this.clientSessionManager.execute(request, options);
5142
5174
  }
@@ -5724,6 +5756,7 @@ var SignalWire = class extends Destroyable {
5724
5756
  if (this._options.storageImplementation) this._deps.storageImpl = this._options.storageImplementation;
5725
5757
  if (this._options.webSocketConstructor) this._deps.WebSocket = this._options.webSocketConstructor;
5726
5758
  if (this._options.savePreferences) this.preferences.enableSavePreferences(this._deps.storage);
5759
+ if (this._options.webRTCApiProvider) this._deps.webRTCApiProvider = this._options.webRTCApiProvider;
5727
5760
  this._deviceController = this._deps.deviceController;
5728
5761
  if (!this._options.skipDeviceMonitoring) this._deviceController.enableDeviceMonitoring();
5729
5762
  this.subscribeTo(this._deviceController.errors$, (error) => {
@@ -5779,7 +5812,7 @@ var SignalWire = class extends Destroyable {
5779
5812
  async init() {
5780
5813
  this._subscriber$.next(new Subscriber(this._deps.http));
5781
5814
  if (!this._options.skipConnection) await this.connect();
5782
- if (this._options.skipReconnect && this._attachManager) await this._attachManager.flush();
5815
+ if (!this._options.reconnectAttachedCalls && this._attachManager) await this._attachManager.flush();
5783
5816
  if (!this._options.skipRegister) this.register();
5784
5817
  this.handleAttachments();
5785
5818
  }
@@ -5848,7 +5881,7 @@ var SignalWire = class extends Destroyable {
5848
5881
  };
5849
5882
  this._transport = new TransportManager(this._deps.storage, this._deps.protocolKey, this._deps.WebSocket, PreferencesContainer.instance.relayHost ?? this._deps.relayHost, errorHandler);
5850
5883
  this._attachManager = new AttachManager(this._deps.storage, this._deps.deviceController, PreferencesContainer.instance.reconnectCallsTimeout, this._deps.attachedCallsKey);
5851
- this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager);
5884
+ this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider);
5852
5885
  this._publicSession = new ClientSessionWrapper(this._clientSession);
5853
5886
  this.subscribeTo(this._clientSession.errors$, (error) => {
5854
5887
  this._errors$.next(error);
@@ -5918,7 +5951,7 @@ var SignalWire = class extends Destroyable {
5918
5951
  }
5919
5952
  /** Observable that emits `true` when the client is both connected and authenticated. */
5920
5953
  get ready$() {
5921
- return this._isConnected$.pipe((0, rxjs.switchMap)((connected) => connected ? this._clientSession.authenticated$ : (0, rxjs.of)(false)));
5954
+ return this.cachedObservable("ready$", () => this._isConnected$.pipe((0, rxjs.switchMap)((connected) => connected ? this._clientSession.authenticated$ : (0, rxjs.of)(false))));
5922
5955
  }
5923
5956
  /** Observable stream of errors from transport, authentication, and devices. */
5924
5957
  get errors$() {
@@ -6197,13 +6230,16 @@ exports.Address = Address;
6197
6230
  exports.CallCreateError = require_operators.CallCreateError;
6198
6231
  exports.ClientPreferences = ClientPreferences;
6199
6232
  exports.CollectionFetchError = require_operators.CollectionFetchError;
6233
+ exports.InvalidCredentialsError = require_operators.InvalidCredentialsError;
6200
6234
  exports.MediaTrackError = require_operators.MediaTrackError;
6201
6235
  exports.MessageParseError = require_operators.MessageParseError;
6202
6236
  exports.Participant = Participant;
6237
+ exports.SelfCapabilities = SelfCapabilities;
6203
6238
  exports.SelfParticipant = SelfParticipant;
6204
6239
  exports.SignalWire = SignalWire;
6205
6240
  exports.StaticCredentialProvider = StaticCredentialProvider;
6206
6241
  exports.Subscriber = Subscriber;
6242
+ exports.UnexpectedError = require_operators.UnexpectedError;
6207
6243
  exports.VertoPongError = require_operators.VertoPongError;
6208
6244
  exports.WebRTCCall = WebRTCCall;
6209
6245
  exports.embeddableCall = embeddableCall;