@signalwire/js 4.0.0-rc.1 → 4.0.0-rc.2
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 +283 -156
- package/dist/browser.mjs.map +1 -1
- package/dist/browser.umd.js +283 -155
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +196 -232
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +69 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +121 -158
- package/dist/index.mjs.map +1 -1
- package/dist/operators/index.cjs +1 -1
- package/dist/operators/index.mjs +1 -1
- package/dist/{operators-D6a2J1KA.cjs → operators-B8ipd4Xl.cjs} +561 -1
- package/dist/operators-B8ipd4Xl.cjs.map +1 -0
- package/dist/{operators-CX_lCCJm.mjs → operators-BlUtq-t0.mjs} +166 -2
- package/dist/operators-BlUtq-t0.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/operators-CX_lCCJm.mjs.map +0 -1
- package/dist/operators-D6a2J1KA.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_operators = require('./operators-
|
|
1
|
+
const require_operators = require('./operators-B8ipd4Xl.cjs');
|
|
2
2
|
let jwt_decode = require("jwt-decode");
|
|
3
3
|
let rxjs = require("rxjs");
|
|
4
4
|
let uuid = require("uuid");
|
|
@@ -404,137 +404,6 @@ var DeviceHistoryManager = class {
|
|
|
404
404
|
}
|
|
405
405
|
};
|
|
406
406
|
|
|
407
|
-
//#endregion
|
|
408
|
-
//#region src/core/constants.ts
|
|
409
|
-
const INVITE_VERSION = 1e3;
|
|
410
|
-
const DEFAULT_ICE_CANDIDATE_TIMEOUT_MS = 600;
|
|
411
|
-
const DEFAULT_ICE_GATHERING_TIMEOUT_MS = 6e3;
|
|
412
|
-
const DEFAULT_RECONNECT_CALLS_TIMEOUT_MS = 300 * 1e3;
|
|
413
|
-
const DEFAULT_CONNECTION_TIMEOUT_MS = 1e4;
|
|
414
|
-
const DEFAULT_RECONNECT_DELAY_MIN_MS = 100;
|
|
415
|
-
const DEFAULT_RECONNECT_DELAY_MAX_MS = 3e3;
|
|
416
|
-
const DEFAULT_DEVICE_DEBOUNCE_TIME_MS = 1500;
|
|
417
|
-
const DEFAULT_DEVICE_POLLING_INTERVAL_MS = 0;
|
|
418
|
-
const PREFERENCES_STORAGE_KEY = "sw:preferences";
|
|
419
|
-
/** Scope value that enables automatic token refresh. */
|
|
420
|
-
const SAT_REFRESH_SCOPE = "sat:refresh";
|
|
421
|
-
/** API endpoints for device token operations. */
|
|
422
|
-
const DEVICE_TOKEN_ENDPOINT = "/api/fabric/subscriber/devices/token";
|
|
423
|
-
const DEVICE_REFRESH_ENDPOINT = "/api/fabric/subscriber/devices/refresh";
|
|
424
|
-
/** Default device token TTL in seconds (15 minutes). */
|
|
425
|
-
const DEVICE_TOKEN_DEFAULT_EXPIRE_IN = 900;
|
|
426
|
-
/** Buffer time in milliseconds before expiry to trigger refresh. */
|
|
427
|
-
const DEVICE_TOKEN_REFRESH_BUFFER_MS = 3e4;
|
|
428
|
-
/** Maximum retry attempts for device token refresh on transient failure. */
|
|
429
|
-
const DEVICE_TOKEN_REFRESH_MAX_RETRIES = 3;
|
|
430
|
-
/** Base delay in milliseconds for exponential backoff on refresh retry. */
|
|
431
|
-
const DEVICE_TOKEN_REFRESH_RETRY_BASE_MS = 1e3;
|
|
432
|
-
/** Maximum retry attempts for developer credential refresh on transient failure. */
|
|
433
|
-
const CREDENTIAL_REFRESH_MAX_RETRIES = 5;
|
|
434
|
-
/** Base delay in milliseconds for exponential backoff on credential refresh retry. */
|
|
435
|
-
const CREDENTIAL_REFRESH_RETRY_BASE_MS = 1e3;
|
|
436
|
-
/** Maximum delay in milliseconds for credential refresh backoff. */
|
|
437
|
-
const CREDENTIAL_REFRESH_MAX_DELAY_MS = 3e4;
|
|
438
|
-
/** Buffer in milliseconds before token expiry to trigger refresh. */
|
|
439
|
-
const CREDENTIAL_REFRESH_BUFFER_MS = 5e3;
|
|
440
|
-
/**
|
|
441
|
-
* Maximum time the coordinator will wait for `DeviceTokenManager.activate()`
|
|
442
|
-
* to resolve before treating the activation as failed and falling back to
|
|
443
|
-
* the developer-provided refresh path. Prevents a wedged HTTP layer from
|
|
444
|
-
* leaving the session with no active refresh mechanism.
|
|
445
|
-
*/
|
|
446
|
-
const CREDENTIAL_ACTIVATE_TIMEOUT_MS = 3e4;
|
|
447
|
-
/** JSON-RPC error code for requester validation failure (corrupted auth state). */
|
|
448
|
-
const RPC_ERROR_REQUESTER_VALIDATION_FAILED = -32003;
|
|
449
|
-
/** JSON-RPC error code for invalid params (e.g., missing authentication block). */
|
|
450
|
-
const RPC_ERROR_INVALID_PARAMS = -32602;
|
|
451
|
-
/** JSON-RPC error code for authentication failure (invalid token, missing DPoP, etc.). */
|
|
452
|
-
const RPC_ERROR_AUTHENTICATION_FAILED = -32002;
|
|
453
|
-
/** Default polling interval for RTCPeerConnection.getStats() in milliseconds. */
|
|
454
|
-
const DEFAULT_STATS_POLLING_INTERVAL_MS = 1e3;
|
|
455
|
-
/** Number of initial samples used to build a baseline for spike detection. */
|
|
456
|
-
const DEFAULT_STATS_BASELINE_SAMPLES = 10;
|
|
457
|
-
/** Duration in ms with no inbound audio packets before emitting a critical issue. */
|
|
458
|
-
const DEFAULT_STATS_NO_PACKET_THRESHOLD_MS = 2e3;
|
|
459
|
-
/** Multiplier applied to baseline RTT to detect a warning-level RTT spike. */
|
|
460
|
-
const DEFAULT_STATS_RTT_SPIKE_MULTIPLIER = 3;
|
|
461
|
-
/** Packet loss fraction (0-1) above which a warning is emitted. */
|
|
462
|
-
const DEFAULT_STATS_PACKET_LOSS_THRESHOLD = .05;
|
|
463
|
-
/** Multiplier applied to baseline jitter to detect a jitter spike. */
|
|
464
|
-
const DEFAULT_STATS_JITTER_SPIKE_MULTIPLIER = 4;
|
|
465
|
-
/** Number of seconds of metrics history to retain. */
|
|
466
|
-
const DEFAULT_STATS_HISTORY_SIZE = 30;
|
|
467
|
-
/** Maximum keyframe requests allowed within a single burst window. */
|
|
468
|
-
const DEFAULT_KEYFRAME_MAX_BURST$1 = 3;
|
|
469
|
-
/** Duration of the keyframe burst window in milliseconds. */
|
|
470
|
-
const DEFAULT_KEYFRAME_BURST_WINDOW_MS$1 = 3e3;
|
|
471
|
-
/** Cooldown period in ms after burst limit is reached before allowing more keyframes. */
|
|
472
|
-
const DEFAULT_KEYFRAME_COOLDOWN_MS$1 = 1e4;
|
|
473
|
-
/** Minimum time between re-INVITE attempts in milliseconds. */
|
|
474
|
-
const DEFAULT_REINVITE_DEBOUNCE_TIME_MS = 1e4;
|
|
475
|
-
/** Maximum number of re-INVITE attempts per call. */
|
|
476
|
-
const DEFAULT_REINVITE_MAX_ATTEMPTS = 3;
|
|
477
|
-
/** Timeout for a single re-INVITE attempt in milliseconds. */
|
|
478
|
-
const DEFAULT_REINVITE_TIMEOUT_MS = 5e3;
|
|
479
|
-
/** Debounce window in ms to collapse multiple detection signals into one trigger. */
|
|
480
|
-
const DEFAULT_RECOVERY_DEBOUNCE_TIME_MS = 2e3;
|
|
481
|
-
/** Cooldown period in ms between recovery attempts. */
|
|
482
|
-
const DEFAULT_RECOVERY_COOLDOWN_MS = 1e4;
|
|
483
|
-
/** Grace period in ms before treating ICE 'disconnected' as a failure. */
|
|
484
|
-
const DEFAULT_ICE_DISCONNECTED_GRACE_PERIOD_MS = 3e3;
|
|
485
|
-
/** Timeout for a single ICE restart attempt in milliseconds. */
|
|
486
|
-
const DEFAULT_ICE_RESTART_TIMEOUT_MS$1 = 5e3;
|
|
487
|
-
/** Maximum recovery attempts before emitting 'max_attempts_reached'. */
|
|
488
|
-
const DEFAULT_MAX_RECOVERY_ATTEMPTS = 3;
|
|
489
|
-
/** Upper bound in ms for waiting on iceGatheringState === 'complete' after an ICE restart. */
|
|
490
|
-
const ICE_GATHERING_COMPLETE_TIMEOUT_MS = 1e4;
|
|
491
|
-
/** Upper bound in ms for waiting on RTCPeerConnection.connectionState === 'connected' after a recovery ICE restart. */
|
|
492
|
-
const PEER_CONNECTION_RECOVERY_WAIT_MS = 5e3;
|
|
493
|
-
/** Polling interval in ms while waiting for RTCPeerConnection.connectionState to transition. */
|
|
494
|
-
const PEER_CONNECTION_RECOVERY_POLL_MS = 100;
|
|
495
|
-
/** Polling interval for LocalAudioPipeline.level$ (ms). ~30fps is smooth for meters. */
|
|
496
|
-
const AUDIO_LEVEL_POLL_INTERVAL_MS = 33;
|
|
497
|
-
/** RMS level threshold (0..1) above which the local participant is considered speaking. */
|
|
498
|
-
const VAD_THRESHOLD = .03;
|
|
499
|
-
/** Hold window in ms below the threshold before speaking$ flips back to false. */
|
|
500
|
-
const VAD_HOLD_MS = 250;
|
|
501
|
-
/** Whether to persist device selections to storage by default. */
|
|
502
|
-
const DEFAULT_PERSIST_DEVICE_SELECTION = true;
|
|
503
|
-
/** Whether to auto-apply device changes to active calls by default. */
|
|
504
|
-
const DEFAULT_SYNC_DEVICES_TO_ACTIVE_CALLS = true;
|
|
505
|
-
/** Storage keys for persisted device selections. */
|
|
506
|
-
const DEVICE_STORAGE_KEY_AUDIO_INPUT = "sw:device:audioinput";
|
|
507
|
-
const DEVICE_STORAGE_KEY_AUDIO_OUTPUT = "sw:device:audiooutput";
|
|
508
|
-
const DEVICE_STORAGE_KEY_VIDEO_INPUT = "sw:device:videoinput";
|
|
509
|
-
/** Whether to auto-mute video when the tab becomes hidden. */
|
|
510
|
-
const DEFAULT_AUTO_MUTE_VIDEO_ON_HIDDEN = false;
|
|
511
|
-
/** Whether to re-enumerate devices when the page becomes visible. */
|
|
512
|
-
const DEFAULT_REFRESH_DEVICES_ON_VISIBLE = true;
|
|
513
|
-
/** Whether to check peer connection health when the page becomes visible. */
|
|
514
|
-
const DEFAULT_CHECK_CONNECTION_ON_VISIBLE = true;
|
|
515
|
-
/** Whether automatic video degradation on low bandwidth is enabled. */
|
|
516
|
-
const DEFAULT_ENABLE_AUTO_DEGRADATION = true;
|
|
517
|
-
/** Bitrate in kbps below which video is automatically disabled. */
|
|
518
|
-
const DEFAULT_DEGRADATION_BITRATE_THRESHOLD_KBPS = 150;
|
|
519
|
-
/** Bitrate in kbps above which video is automatically re-enabled (hysteresis). */
|
|
520
|
-
const DEFAULT_DEGRADATION_RECOVERY_THRESHOLD_KBPS = 300;
|
|
521
|
-
/** Whether relay-only escalation is enabled as a last-resort recovery tier. */
|
|
522
|
-
const DEFAULT_ENABLE_RELAY_FALLBACK = true;
|
|
523
|
-
/** Whether to listen for browser online/offline/connection events. */
|
|
524
|
-
const DEFAULT_ENABLE_NETWORK_CHANGE_DETECTION = true;
|
|
525
|
-
/** Whether to intercept server-sent media-timeout hangups and attempt recovery. */
|
|
526
|
-
const DEFAULT_ENABLE_SERVER_HANGUP_INTERCEPTION = true;
|
|
527
|
-
/** Default video track constraints applied when video is enabled without explicit constraints. */
|
|
528
|
-
const DEFAULT_VIDEO_CONSTRAINTS = {
|
|
529
|
-
width: { ideal: 1280 },
|
|
530
|
-
height: { ideal: 720 },
|
|
531
|
-
aspectRatio: 16 / 9
|
|
532
|
-
};
|
|
533
|
-
/** Whether stereo Opus is enabled by default. */
|
|
534
|
-
const DEFAULT_STEREO_AUDIO = false;
|
|
535
|
-
/** Max average bitrate for stereo Opus in bits per second. */
|
|
536
|
-
const DEFAULT_STEREO_MAX_AVERAGE_BITRATE = 51e4;
|
|
537
|
-
|
|
538
407
|
//#endregion
|
|
539
408
|
//#region src/utils/time.ts
|
|
540
409
|
function fromSecToMs(seconds) {
|
|
@@ -553,16 +422,16 @@ var PreferencesContainer = class PreferencesContainer {
|
|
|
553
422
|
return this._instance;
|
|
554
423
|
}
|
|
555
424
|
constructor() {
|
|
556
|
-
this.deviceDebounceTime = DEFAULT_DEVICE_DEBOUNCE_TIME_MS;
|
|
557
|
-
this.devicePollingInterval = DEFAULT_DEVICE_POLLING_INTERVAL_MS;
|
|
558
|
-
this.reconnectCallsTimeout = DEFAULT_RECONNECT_CALLS_TIMEOUT_MS;
|
|
559
|
-
this.connectionTimeout = DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
560
|
-
this.reconnectDelayMin = DEFAULT_RECONNECT_DELAY_MIN_MS;
|
|
561
|
-
this.reconnectDelayMax = DEFAULT_RECONNECT_DELAY_MAX_MS;
|
|
425
|
+
this.deviceDebounceTime = require_operators.DEFAULT_DEVICE_DEBOUNCE_TIME_MS;
|
|
426
|
+
this.devicePollingInterval = require_operators.DEFAULT_DEVICE_POLLING_INTERVAL_MS;
|
|
427
|
+
this.reconnectCallsTimeout = require_operators.DEFAULT_RECONNECT_CALLS_TIMEOUT_MS;
|
|
428
|
+
this.connectionTimeout = require_operators.DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
429
|
+
this.reconnectDelayMin = require_operators.DEFAULT_RECONNECT_DELAY_MIN_MS;
|
|
430
|
+
this.reconnectDelayMax = require_operators.DEFAULT_RECONNECT_DELAY_MAX_MS;
|
|
562
431
|
this.disableUdpIceServers = false;
|
|
563
432
|
this.relayOnly = false;
|
|
564
|
-
this.iceCandidateTimeout = DEFAULT_ICE_CANDIDATE_TIMEOUT_MS;
|
|
565
|
-
this.iceGatheringTimeout = DEFAULT_ICE_GATHERING_TIMEOUT_MS;
|
|
433
|
+
this.iceCandidateTimeout = require_operators.DEFAULT_ICE_CANDIDATE_TIMEOUT_MS;
|
|
434
|
+
this.iceGatheringTimeout = require_operators.DEFAULT_ICE_GATHERING_TIMEOUT_MS;
|
|
566
435
|
this.defaultSignalWireOptions = {
|
|
567
436
|
skipConnection: false,
|
|
568
437
|
skipRegister: false,
|
|
@@ -589,38 +458,38 @@ var PreferencesContainer = class PreferencesContainer {
|
|
|
589
458
|
"call.joined"
|
|
590
459
|
];
|
|
591
460
|
this.userVariables = {};
|
|
592
|
-
this.statsPollingInterval = DEFAULT_STATS_POLLING_INTERVAL_MS;
|
|
593
|
-
this.statsBaselineSamples = DEFAULT_STATS_BASELINE_SAMPLES;
|
|
594
|
-
this.statsNoPacketThreshold = DEFAULT_STATS_NO_PACKET_THRESHOLD_MS;
|
|
595
|
-
this.statsRttSpikeMultiplier = DEFAULT_STATS_RTT_SPIKE_MULTIPLIER;
|
|
596
|
-
this.statsPacketLossThreshold = DEFAULT_STATS_PACKET_LOSS_THRESHOLD;
|
|
597
|
-
this.statsJitterSpikeMultiplier = DEFAULT_STATS_JITTER_SPIKE_MULTIPLIER;
|
|
598
|
-
this.statsHistorySize = DEFAULT_STATS_HISTORY_SIZE;
|
|
599
|
-
this.keyframeMaxBurst = DEFAULT_KEYFRAME_MAX_BURST
|
|
600
|
-
this.keyframeBurstWindow = DEFAULT_KEYFRAME_BURST_WINDOW_MS
|
|
601
|
-
this.keyframeCooldown = DEFAULT_KEYFRAME_COOLDOWN_MS
|
|
602
|
-
this.reinviteDebounceTime = DEFAULT_REINVITE_DEBOUNCE_TIME_MS;
|
|
603
|
-
this.reinviteMaxAttempts = DEFAULT_REINVITE_MAX_ATTEMPTS;
|
|
604
|
-
this.reinviteTimeout = DEFAULT_REINVITE_TIMEOUT_MS;
|
|
605
|
-
this.recoveryDebounceTime = DEFAULT_RECOVERY_DEBOUNCE_TIME_MS;
|
|
606
|
-
this.recoveryCooldown = DEFAULT_RECOVERY_COOLDOWN_MS;
|
|
607
|
-
this.iceDisconnectedGracePeriod = DEFAULT_ICE_DISCONNECTED_GRACE_PERIOD_MS;
|
|
608
|
-
this.iceRestartTimeout = DEFAULT_ICE_RESTART_TIMEOUT_MS
|
|
609
|
-
this.maxRecoveryAttempts = DEFAULT_MAX_RECOVERY_ATTEMPTS;
|
|
610
|
-
this.enableRelayFallback = DEFAULT_ENABLE_RELAY_FALLBACK;
|
|
611
|
-
this.enableNetworkChangeDetection = DEFAULT_ENABLE_NETWORK_CHANGE_DETECTION;
|
|
612
|
-
this.enableServerHangupInterception = DEFAULT_ENABLE_SERVER_HANGUP_INTERCEPTION;
|
|
613
|
-
this.persistDeviceSelection = DEFAULT_PERSIST_DEVICE_SELECTION;
|
|
614
|
-
this.syncDevicesToActiveCalls = DEFAULT_SYNC_DEVICES_TO_ACTIVE_CALLS;
|
|
615
|
-
this.autoMuteVideoOnHidden = DEFAULT_AUTO_MUTE_VIDEO_ON_HIDDEN;
|
|
616
|
-
this.refreshDevicesOnVisible = DEFAULT_REFRESH_DEVICES_ON_VISIBLE;
|
|
617
|
-
this.checkConnectionOnVisible = DEFAULT_CHECK_CONNECTION_ON_VISIBLE;
|
|
461
|
+
this.statsPollingInterval = require_operators.DEFAULT_STATS_POLLING_INTERVAL_MS;
|
|
462
|
+
this.statsBaselineSamples = require_operators.DEFAULT_STATS_BASELINE_SAMPLES;
|
|
463
|
+
this.statsNoPacketThreshold = require_operators.DEFAULT_STATS_NO_PACKET_THRESHOLD_MS;
|
|
464
|
+
this.statsRttSpikeMultiplier = require_operators.DEFAULT_STATS_RTT_SPIKE_MULTIPLIER;
|
|
465
|
+
this.statsPacketLossThreshold = require_operators.DEFAULT_STATS_PACKET_LOSS_THRESHOLD;
|
|
466
|
+
this.statsJitterSpikeMultiplier = require_operators.DEFAULT_STATS_JITTER_SPIKE_MULTIPLIER;
|
|
467
|
+
this.statsHistorySize = require_operators.DEFAULT_STATS_HISTORY_SIZE;
|
|
468
|
+
this.keyframeMaxBurst = require_operators.DEFAULT_KEYFRAME_MAX_BURST;
|
|
469
|
+
this.keyframeBurstWindow = require_operators.DEFAULT_KEYFRAME_BURST_WINDOW_MS;
|
|
470
|
+
this.keyframeCooldown = require_operators.DEFAULT_KEYFRAME_COOLDOWN_MS;
|
|
471
|
+
this.reinviteDebounceTime = require_operators.DEFAULT_REINVITE_DEBOUNCE_TIME_MS;
|
|
472
|
+
this.reinviteMaxAttempts = require_operators.DEFAULT_REINVITE_MAX_ATTEMPTS;
|
|
473
|
+
this.reinviteTimeout = require_operators.DEFAULT_REINVITE_TIMEOUT_MS;
|
|
474
|
+
this.recoveryDebounceTime = require_operators.DEFAULT_RECOVERY_DEBOUNCE_TIME_MS;
|
|
475
|
+
this.recoveryCooldown = require_operators.DEFAULT_RECOVERY_COOLDOWN_MS;
|
|
476
|
+
this.iceDisconnectedGracePeriod = require_operators.DEFAULT_ICE_DISCONNECTED_GRACE_PERIOD_MS;
|
|
477
|
+
this.iceRestartTimeout = require_operators.DEFAULT_ICE_RESTART_TIMEOUT_MS;
|
|
478
|
+
this.maxRecoveryAttempts = require_operators.DEFAULT_MAX_RECOVERY_ATTEMPTS;
|
|
479
|
+
this.enableRelayFallback = require_operators.DEFAULT_ENABLE_RELAY_FALLBACK;
|
|
480
|
+
this.enableNetworkChangeDetection = require_operators.DEFAULT_ENABLE_NETWORK_CHANGE_DETECTION;
|
|
481
|
+
this.enableServerHangupInterception = require_operators.DEFAULT_ENABLE_SERVER_HANGUP_INTERCEPTION;
|
|
482
|
+
this.persistDeviceSelection = require_operators.DEFAULT_PERSIST_DEVICE_SELECTION;
|
|
483
|
+
this.syncDevicesToActiveCalls = require_operators.DEFAULT_SYNC_DEVICES_TO_ACTIVE_CALLS;
|
|
484
|
+
this.autoMuteVideoOnHidden = require_operators.DEFAULT_AUTO_MUTE_VIDEO_ON_HIDDEN;
|
|
485
|
+
this.refreshDevicesOnVisible = require_operators.DEFAULT_REFRESH_DEVICES_ON_VISIBLE;
|
|
486
|
+
this.checkConnectionOnVisible = require_operators.DEFAULT_CHECK_CONNECTION_ON_VISIBLE;
|
|
618
487
|
this.defaultAudioConstraints = void 0;
|
|
619
488
|
this.defaultVideoConstraints = void 0;
|
|
620
|
-
this.stereoAudio = DEFAULT_STEREO_AUDIO;
|
|
621
|
-
this.enableAutoDegradation = DEFAULT_ENABLE_AUTO_DEGRADATION;
|
|
622
|
-
this.degradationBitrateThreshold = DEFAULT_DEGRADATION_BITRATE_THRESHOLD_KBPS;
|
|
623
|
-
this.degradationRecoveryThreshold = DEFAULT_DEGRADATION_RECOVERY_THRESHOLD_KBPS;
|
|
489
|
+
this.stereoAudio = require_operators.DEFAULT_STEREO_AUDIO;
|
|
490
|
+
this.enableAutoDegradation = require_operators.DEFAULT_ENABLE_AUTO_DEGRADATION;
|
|
491
|
+
this.degradationBitrateThreshold = require_operators.DEFAULT_DEGRADATION_BITRATE_THRESHOLD_KBPS;
|
|
492
|
+
this.degradationRecoveryThreshold = require_operators.DEFAULT_DEGRADATION_RECOVERY_THRESHOLD_KBPS;
|
|
624
493
|
this.preferredVideoCodecs = [];
|
|
625
494
|
this.preferredAudioCodecs = [];
|
|
626
495
|
}
|
|
@@ -1207,14 +1076,14 @@ var ClientPreferences = class {
|
|
|
1207
1076
|
_saveToStorage() {
|
|
1208
1077
|
if (!this._storage) return;
|
|
1209
1078
|
const data = collectStoredPreferences();
|
|
1210
|
-
this._storage.setItem(PREFERENCES_STORAGE_KEY, data, "local").catch((error) => {
|
|
1079
|
+
this._storage.setItem(require_operators.PREFERENCES_STORAGE_KEY, data, "local").catch((error) => {
|
|
1211
1080
|
logger$30.error(`[ClientPreferences] Failed to save preferences: ${String(error)}`);
|
|
1212
1081
|
});
|
|
1213
1082
|
}
|
|
1214
1083
|
/** Loads preferences from storage and applies them to the container. */
|
|
1215
1084
|
_loadFromStorage() {
|
|
1216
1085
|
if (!this._storage) return;
|
|
1217
|
-
this._storage.getItem(PREFERENCES_STORAGE_KEY, "local").then((stored) => {
|
|
1086
|
+
this._storage.getItem(require_operators.PREFERENCES_STORAGE_KEY, "local").then((stored) => {
|
|
1218
1087
|
if (stored) applyStoredPreferences(stored);
|
|
1219
1088
|
}).catch((error) => {
|
|
1220
1089
|
logger$30.error(`[ClientPreferences] Failed to load preferences: ${String(error)}`);
|
|
@@ -1241,9 +1110,9 @@ function toError(value) {
|
|
|
1241
1110
|
const logger$29 = require_operators.getLogger();
|
|
1242
1111
|
/** Maps a device kind to its storage key. */
|
|
1243
1112
|
const DEVICE_STORAGE_KEYS = {
|
|
1244
|
-
audioinput: DEVICE_STORAGE_KEY_AUDIO_INPUT,
|
|
1245
|
-
audiooutput: DEVICE_STORAGE_KEY_AUDIO_OUTPUT,
|
|
1246
|
-
videoinput: DEVICE_STORAGE_KEY_VIDEO_INPUT
|
|
1113
|
+
audioinput: require_operators.DEVICE_STORAGE_KEY_AUDIO_INPUT,
|
|
1114
|
+
audiooutput: require_operators.DEVICE_STORAGE_KEY_AUDIO_OUTPUT,
|
|
1115
|
+
videoinput: require_operators.DEVICE_STORAGE_KEY_VIDEO_INPUT
|
|
1247
1116
|
};
|
|
1248
1117
|
const initialDevicesState = {
|
|
1249
1118
|
audioinput: [],
|
|
@@ -3687,12 +3556,21 @@ var SelfParticipant = class extends Participant {
|
|
|
3687
3556
|
noise_suppression: true
|
|
3688
3557
|
});
|
|
3689
3558
|
}
|
|
3690
|
-
/**
|
|
3559
|
+
/**
|
|
3560
|
+
* Starts sharing the local screen.
|
|
3561
|
+
*
|
|
3562
|
+
* The call is unaffected when acquisition fails.
|
|
3563
|
+
*
|
|
3564
|
+
* @throws The raw `getDisplayMedia` error. A dismissed picker or a
|
|
3565
|
+
* permission denial rejects with a `NotAllowedError` `DOMException` —
|
|
3566
|
+
* inspect `error.name` to tell benign cancels apart from real failures.
|
|
3567
|
+
*/
|
|
3691
3568
|
async startScreenShare() {
|
|
3692
3569
|
try {
|
|
3693
3570
|
await this.vertoManager.addScreenMedia();
|
|
3694
3571
|
} catch (error) {
|
|
3695
3572
|
logger$23.error("[Participant.startScreenShare] Screen share error:", error);
|
|
3573
|
+
throw error;
|
|
3696
3574
|
}
|
|
3697
3575
|
}
|
|
3698
3576
|
/** Observable of the current screen share status. */
|
|
@@ -3707,12 +3585,20 @@ var SelfParticipant = class extends Participant {
|
|
|
3707
3585
|
async stopScreenShare() {
|
|
3708
3586
|
return this.vertoManager.removeScreenMedia();
|
|
3709
3587
|
}
|
|
3710
|
-
/**
|
|
3588
|
+
/**
|
|
3589
|
+
* Adds an additional media input device to the call.
|
|
3590
|
+
*
|
|
3591
|
+
* The call is unaffected when acquisition fails.
|
|
3592
|
+
*
|
|
3593
|
+
* @throws The raw `getUserMedia` error (e.g. `NotAllowedError` on
|
|
3594
|
+
* permission denial) — inspect `error.name` to decide how to react.
|
|
3595
|
+
*/
|
|
3711
3596
|
async addAdditionalDevice(options) {
|
|
3712
3597
|
try {
|
|
3713
3598
|
await this.vertoManager.addInputDevice(options);
|
|
3714
3599
|
} catch (error) {
|
|
3715
|
-
logger$23.error("[Participant.
|
|
3600
|
+
logger$23.error("[Participant.addAdditionalDevice] Additional device error:", error);
|
|
3601
|
+
throw error;
|
|
3716
3602
|
}
|
|
3717
3603
|
}
|
|
3718
3604
|
/** Removes an additional media input device by ID. */
|
|
@@ -4315,7 +4201,7 @@ function reorderCodecs(sdp, preferredVideo = [], preferredAudio = []) {
|
|
|
4315
4201
|
* // a=fmtp:111 minptime=10;useinbandfec=1;stereo=1;sprop-stereo=1;maxaveragebitrate=510000
|
|
4316
4202
|
* ```
|
|
4317
4203
|
*/
|
|
4318
|
-
function enableStereoOpus(sdp, maxBitrate = DEFAULT_STEREO_MAX_AVERAGE_BITRATE) {
|
|
4204
|
+
function enableStereoOpus(sdp, maxBitrate = require_operators.DEFAULT_STEREO_MAX_AVERAGE_BITRATE) {
|
|
4319
4205
|
if (!sdp) return sdp;
|
|
4320
4206
|
const opusPayloadType = findOpusPayloadType(sdp);
|
|
4321
4207
|
if (opusPayloadType === null) return sdp;
|
|
@@ -4444,8 +4330,8 @@ var ICEGatheringController = class extends Destroyable {
|
|
|
4444
4330
|
state: "new",
|
|
4445
4331
|
validSDP: false
|
|
4446
4332
|
});
|
|
4447
|
-
this.iceCandidateTimeout = options.iceCandidateTimeout ?? DEFAULT_ICE_CANDIDATE_TIMEOUT_MS;
|
|
4448
|
-
this.iceGatheringTimeout = options.iceGatheringTimeout ?? DEFAULT_ICE_GATHERING_TIMEOUT_MS;
|
|
4333
|
+
this.iceCandidateTimeout = options.iceCandidateTimeout ?? require_operators.DEFAULT_ICE_CANDIDATE_TIMEOUT_MS;
|
|
4334
|
+
this.iceGatheringTimeout = options.iceGatheringTimeout ?? require_operators.DEFAULT_ICE_GATHERING_TIMEOUT_MS;
|
|
4449
4335
|
this.relayOnly = options.relayOnly ?? false;
|
|
4450
4336
|
this.setupEventListeners();
|
|
4451
4337
|
this.subscribeTo(this.peerConnectionControllerNegotiating$.pipe((0, rxjs.filter)((isNegotiating) => isNegotiating)), (isNegotiating) => {
|
|
@@ -4590,9 +4476,9 @@ var LocalAudioPipeline = class extends Destroyable {
|
|
|
4590
4476
|
this._destination = this._audioContext.createMediaStreamDestination();
|
|
4591
4477
|
this._gainNode.connect(this._analyser);
|
|
4592
4478
|
this._analyser.connect(this._destination);
|
|
4593
|
-
this._speakingThreshold = options.speakingThreshold ?? VAD_THRESHOLD;
|
|
4594
|
-
this._speakingHoldMs = options.speakingHoldMs ?? VAD_HOLD_MS;
|
|
4595
|
-
this._pollIntervalMs = options.pollIntervalMs ?? AUDIO_LEVEL_POLL_INTERVAL_MS;
|
|
4479
|
+
this._speakingThreshold = options.speakingThreshold ?? require_operators.VAD_THRESHOLD;
|
|
4480
|
+
this._speakingHoldMs = options.speakingHoldMs ?? require_operators.VAD_HOLD_MS;
|
|
4481
|
+
this._pollIntervalMs = options.pollIntervalMs ?? require_operators.AUDIO_LEVEL_POLL_INTERVAL_MS;
|
|
4596
4482
|
const initial = options.initialGain ?? 1;
|
|
4597
4483
|
this._gain$.next(initial);
|
|
4598
4484
|
this.applyEffectiveGain();
|
|
@@ -5206,7 +5092,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5206
5092
|
logger$17.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
|
|
5207
5093
|
} catch (error) {
|
|
5208
5094
|
logger$17.error(`[RTCPeerConnectionController] Failed to select ${kind} input device:`, error);
|
|
5209
|
-
this._errors$.next(
|
|
5095
|
+
this._errors$.next(new require_operators.MediaTrackError("updateSelectedInputDevice", kind, error));
|
|
5210
5096
|
throw error;
|
|
5211
5097
|
}
|
|
5212
5098
|
};
|
|
@@ -5428,7 +5314,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5428
5314
|
case "main":
|
|
5429
5315
|
default: return {
|
|
5430
5316
|
...options,
|
|
5431
|
-
offerToReceiveAudio: true,
|
|
5317
|
+
offerToReceiveAudio: this.options.receiveAudio ?? true,
|
|
5432
5318
|
offerToReceiveVideo: this.options.receiveVideo ?? Boolean(this.inputVideoDeviceConstraints)
|
|
5433
5319
|
};
|
|
5434
5320
|
}
|
|
@@ -5582,13 +5468,14 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5582
5468
|
*/
|
|
5583
5469
|
async acceptInbound(mediaOverrides) {
|
|
5584
5470
|
if (mediaOverrides) {
|
|
5585
|
-
const { audio, video, receiveAudio, receiveVideo } = mediaOverrides;
|
|
5471
|
+
const { audio, video, receiveAudio, receiveVideo, fallbackToReceiveOnly } = mediaOverrides;
|
|
5586
5472
|
this.options = {
|
|
5587
5473
|
...this.options,
|
|
5588
5474
|
...audio !== void 0 ? { audio } : {},
|
|
5589
5475
|
...video !== void 0 ? { video } : {},
|
|
5590
5476
|
...receiveAudio !== void 0 ? { receiveAudio } : {},
|
|
5591
|
-
...receiveVideo !== void 0 ? { receiveVideo } : {}
|
|
5477
|
+
...receiveVideo !== void 0 ? { receiveVideo } : {},
|
|
5478
|
+
...fallbackToReceiveOnly !== void 0 ? { fallbackToReceiveOnly } : {}
|
|
5592
5479
|
};
|
|
5593
5480
|
this.transceiverController?.updateOptions({
|
|
5594
5481
|
receiveAudio: this.receiveAudio,
|
|
@@ -5719,7 +5606,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5719
5606
|
if (policyChanged) this.restoreIceTransportPolicy();
|
|
5720
5607
|
throw error;
|
|
5721
5608
|
}
|
|
5722
|
-
if (policyChanged) (0, rxjs.firstValueFrom)((0, rxjs.race)(this._iceGatheringState$.pipe((0, rxjs.filter)((state) => state === "complete"), (0, rxjs.take)(1)), (0, rxjs.timer)(ICE_GATHERING_COMPLETE_TIMEOUT_MS).pipe((0, rxjs.map)(() => "timeout")))).then(() => this.restoreIceTransportPolicy()).catch((error) => {
|
|
5609
|
+
if (policyChanged) (0, rxjs.firstValueFrom)((0, rxjs.race)(this._iceGatheringState$.pipe((0, rxjs.filter)((state) => state === "complete"), (0, rxjs.take)(1)), (0, rxjs.timer)(require_operators.ICE_GATHERING_COMPLETE_TIMEOUT_MS).pipe((0, rxjs.map)(() => "timeout")))).then(() => this.restoreIceTransportPolicy()).catch((error) => {
|
|
5723
5610
|
logger$17.warn("[RTCPeerConnectionController] Error waiting for ICE gathering to complete:", error);
|
|
5724
5611
|
this.restoreIceTransportPolicy();
|
|
5725
5612
|
});
|
|
@@ -5745,7 +5632,19 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5745
5632
|
}
|
|
5746
5633
|
async setupLocalTracks() {
|
|
5747
5634
|
logger$17.debug("[RTCPeerConnectionController] Setting up local tracks/transceivers.");
|
|
5748
|
-
|
|
5635
|
+
if (this.hasNoLocalMediaToSend()) {
|
|
5636
|
+
if (!this.receiveAudio && !this.receiveVideo) throw new require_operators.InvalidParams("Call requests no media: enable audio/video or receiveAudio/receiveVideo");
|
|
5637
|
+
logger$17.debug("[RTCPeerConnectionController] No local media requested; negotiating receive-only.");
|
|
5638
|
+
this.setupReceiveOnlyTransceivers();
|
|
5639
|
+
return;
|
|
5640
|
+
}
|
|
5641
|
+
let localStream;
|
|
5642
|
+
try {
|
|
5643
|
+
localStream = this.localStream ?? await this.localStreamController.buildLocalStream();
|
|
5644
|
+
} catch (error) {
|
|
5645
|
+
this.handleLocalMediaFailure(error);
|
|
5646
|
+
return;
|
|
5647
|
+
}
|
|
5749
5648
|
if (this.transceiverController?.useAddStream ?? false) {
|
|
5750
5649
|
logger$17.warn("[RTCPeerConnectionController] Using deprecated addStream API to add local stream.");
|
|
5751
5650
|
this.peerConnection?.addStream(localStream);
|
|
@@ -5772,6 +5671,48 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5772
5671
|
}
|
|
5773
5672
|
}
|
|
5774
5673
|
}
|
|
5674
|
+
/** True for a main connection with no local media to send. */
|
|
5675
|
+
hasNoLocalMediaToSend() {
|
|
5676
|
+
const hasInputStreams = Boolean(this.options.inputAudioStream ?? this.options.inputVideoStream);
|
|
5677
|
+
return this.propose === "main" && !this.localStream && !hasInputStreams && !this.inputAudioDeviceConstraints && !this.inputVideoDeviceConstraints;
|
|
5678
|
+
}
|
|
5679
|
+
/** The media kinds this connection wants to send: 'audiovideo' | 'video' | 'audio'. */
|
|
5680
|
+
get requestedMediaKinds() {
|
|
5681
|
+
const wantsAudio = Boolean(this.inputAudioDeviceConstraints);
|
|
5682
|
+
const wantsVideo = Boolean(this.inputVideoDeviceConstraints);
|
|
5683
|
+
if (wantsAudio && wantsVideo) return "audiovideo";
|
|
5684
|
+
return wantsVideo ? "video" : "audio";
|
|
5685
|
+
}
|
|
5686
|
+
/**
|
|
5687
|
+
* Handle a local media acquisition failure with a typed, semantically
|
|
5688
|
+
* accurate MediaAccessError created at the acquisition site:
|
|
5689
|
+
* - Auxiliary connections (screenshare / additional-device) throw a
|
|
5690
|
+
* non-fatal error — VertoManager surfaces it and the call is unaffected.
|
|
5691
|
+
* - The main connection degrades to receive-only when allowed (default),
|
|
5692
|
+
* otherwise fails with a fatal error.
|
|
5693
|
+
*/
|
|
5694
|
+
handleLocalMediaFailure(error) {
|
|
5695
|
+
if (this.propose === "screenshare") throw new require_operators.MediaAccessError("startScreenShare", "screen", error, false);
|
|
5696
|
+
if (this.propose === "additional-device") throw new require_operators.MediaAccessError("addInputDevice", this.requestedMediaKinds, error, false);
|
|
5697
|
+
const canReceive = this.receiveAudio || this.receiveVideo;
|
|
5698
|
+
if (!((this.options.fallbackToReceiveOnly ?? true) && canReceive)) throw new require_operators.MediaAccessError("acquireLocalMedia", this.requestedMediaKinds, error, true);
|
|
5699
|
+
logger$17.warn("[RTCPeerConnectionController] Local media unavailable; continuing receive-only:", error);
|
|
5700
|
+
this._errors$.next(new require_operators.MediaAccessError("acquireLocalMedia", this.requestedMediaKinds, error, false));
|
|
5701
|
+
this.setupReceiveOnlyTransceivers();
|
|
5702
|
+
}
|
|
5703
|
+
/**
|
|
5704
|
+
* Negotiate receive-only m-lines when there are no local tracks to send.
|
|
5705
|
+
* Only offer-type connections add transceivers — answer-type connections
|
|
5706
|
+
* reuse the transceivers created from the remote offer.
|
|
5707
|
+
*/
|
|
5708
|
+
setupReceiveOnlyTransceivers() {
|
|
5709
|
+
if (this.type !== "offer") return;
|
|
5710
|
+
if (this.transceiverController?.useAddTransceivers ?? false) {
|
|
5711
|
+
this.peerConnection?.addTransceiver("audio", { direction: this.receiveAudio ? "recvonly" : "inactive" });
|
|
5712
|
+
this.peerConnection?.addTransceiver("video", { direction: this.receiveVideo ? "recvonly" : "inactive" });
|
|
5713
|
+
}
|
|
5714
|
+
if (!this.isNegotiating) this.negotiationNeeded$.next();
|
|
5715
|
+
}
|
|
5775
5716
|
async getUserMedia(constraints) {
|
|
5776
5717
|
return (this.options.webRTCApiProvider?.mediaDevices ?? navigator.mediaDevices).getUserMedia(constraints);
|
|
5777
5718
|
}
|
|
@@ -5808,7 +5749,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5808
5749
|
stream = await this.getUserMedia({ audio: constraints });
|
|
5809
5750
|
} catch (error) {
|
|
5810
5751
|
logger$17.error("[RTCPeerConnectionController] Failed to re-acquire mic for pipeline restore:", error);
|
|
5811
|
-
this._errors$.next(
|
|
5752
|
+
this._errors$.next(new require_operators.MediaTrackError("restoreAudioPipelineInput", "audio", error));
|
|
5812
5753
|
return;
|
|
5813
5754
|
}
|
|
5814
5755
|
const newTrack = stream.getAudioTracks().at(0);
|
|
@@ -5870,7 +5811,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5870
5811
|
logger$17.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
|
|
5871
5812
|
} catch (error) {
|
|
5872
5813
|
logger$17.error(`[RTCPeerConnectionController] Failed to add ${track.kind} track:`, error);
|
|
5873
|
-
this._errors$.next(
|
|
5814
|
+
this._errors$.next(new require_operators.MediaTrackError("addLocalTrack", track.kind, error));
|
|
5874
5815
|
throw error;
|
|
5875
5816
|
}
|
|
5876
5817
|
}
|
|
@@ -5895,7 +5836,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5895
5836
|
logger$17.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
|
|
5896
5837
|
} catch (error) {
|
|
5897
5838
|
logger$17.error(`[RTCPeerConnectionController] Failed to remove ${sender.track?.kind} track:`, error);
|
|
5898
|
-
this._errors$.next(
|
|
5839
|
+
this._errors$.next(new require_operators.MediaTrackError("removeLocalTrack", sender.track?.kind ?? "unknown", error));
|
|
5899
5840
|
throw error;
|
|
5900
5841
|
}
|
|
5901
5842
|
}
|
|
@@ -6503,6 +6444,7 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6503
6444
|
inputVideoStream: options.inputVideoStream,
|
|
6504
6445
|
receiveAudio: options.receiveAudio,
|
|
6505
6446
|
receiveVideo: options.receiveVideo,
|
|
6447
|
+
fallbackToReceiveOnly: options.fallbackToReceiveOnly,
|
|
6506
6448
|
webRTCApiProvider: this.webRTCApiProvider,
|
|
6507
6449
|
preferredVideoCodecs: options.preferredVideoCodecs,
|
|
6508
6450
|
preferredAudioCodecs: options.preferredAudioCodecs,
|
|
@@ -6674,7 +6616,7 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6674
6616
|
screenShare: rtcPeerConnectionController.isScreenShare,
|
|
6675
6617
|
additionalDevice: rtcPeerConnectionController.isAdditionalDevice,
|
|
6676
6618
|
pingSupported: true,
|
|
6677
|
-
version: INVITE_VERSION
|
|
6619
|
+
version: require_operators.INVITE_VERSION
|
|
6678
6620
|
};
|
|
6679
6621
|
}
|
|
6680
6622
|
muteMainAudioInputDevice() {
|
|
@@ -6729,9 +6671,11 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6729
6671
|
await this.initAdditionalPeerConnection("screenshare", options);
|
|
6730
6672
|
}
|
|
6731
6673
|
async initAdditionalPeerConnection(propose, options) {
|
|
6674
|
+
const isScreenShare = propose === "screenshare";
|
|
6675
|
+
let firstPeerConnectionError;
|
|
6732
6676
|
let rtcPeerConnController = null;
|
|
6733
6677
|
try {
|
|
6734
|
-
this._screenShareStatus$.next("starting");
|
|
6678
|
+
if (isScreenShare) this._screenShareStatus$.next("starting");
|
|
6735
6679
|
rtcPeerConnController = new RTCPeerConnectionController({
|
|
6736
6680
|
...options,
|
|
6737
6681
|
...this.RTCPeerConnectionConfig,
|
|
@@ -6739,21 +6683,27 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6739
6683
|
webRTCApiProvider: this.webRTCApiProvider
|
|
6740
6684
|
}, void 0, this.deviceController);
|
|
6741
6685
|
this.setupLocalDescriptionHandler(rtcPeerConnController);
|
|
6742
|
-
if (
|
|
6686
|
+
if (isScreenShare) this._screenShareId = rtcPeerConnController.id;
|
|
6743
6687
|
this._rtcPeerConnectionsMap.set(rtcPeerConnController.id, rtcPeerConnController);
|
|
6744
6688
|
this._rtcPeerConnections$.next(Array.from(this._rtcPeerConnectionsMap.values()));
|
|
6745
6689
|
this.subscribeTo(rtcPeerConnController.errors$, (error) => {
|
|
6746
|
-
|
|
6690
|
+
firstPeerConnectionError ??= error;
|
|
6691
|
+
this.onError?.(error, { fatal: false });
|
|
6747
6692
|
});
|
|
6748
6693
|
await (0, rxjs.firstValueFrom)(rtcPeerConnController.connectionState$.pipe((0, rxjs.filter)((state) => state === "connected"), (0, rxjs.take)(1), (0, rxjs.timeout)(this._screenShareTimeoutMs), (0, rxjs.takeUntil)(this.destroyed$)));
|
|
6749
|
-
this._screenShareStatus$.next("started");
|
|
6750
|
-
logger$16.info(
|
|
6694
|
+
if (isScreenShare) this._screenShareStatus$.next("started");
|
|
6695
|
+
logger$16.info(`[WebRTCManager] Additional peer connection connected (${propose}).`);
|
|
6751
6696
|
return rtcPeerConnController.id;
|
|
6752
6697
|
} catch (error) {
|
|
6753
6698
|
logger$16.warn("[WebRTCManager] Error initializing additional peer connection:", error);
|
|
6754
|
-
this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
6755
6699
|
if (rtcPeerConnController) rtcPeerConnController.destroy();
|
|
6756
|
-
this._screenShareStatus$.next("none");
|
|
6700
|
+
if (isScreenShare) this._screenShareStatus$.next("none");
|
|
6701
|
+
if (firstPeerConnectionError) throw firstPeerConnectionError instanceof require_operators.MediaAccessError && firstPeerConnectionError.originalError instanceof Error ? firstPeerConnectionError.originalError : firstPeerConnectionError;
|
|
6702
|
+
if (error instanceof rxjs.EmptyError) {
|
|
6703
|
+
logger$16.debug("[WebRTCManager] Additional peer connection aborted before connecting.");
|
|
6704
|
+
return;
|
|
6705
|
+
}
|
|
6706
|
+
throw error instanceof Error ? error : new Error(String(error), { cause: error });
|
|
6757
6707
|
}
|
|
6758
6708
|
}
|
|
6759
6709
|
async removeInputDevices(id) {
|
|
@@ -6868,7 +6818,7 @@ var RemoteAudioMeter = class extends Destroyable {
|
|
|
6868
6818
|
this._analyser.fftSize = 2048;
|
|
6869
6819
|
this._analyser.smoothingTimeConstant = .3;
|
|
6870
6820
|
this._analyserBuffer = new Uint8Array(new ArrayBuffer(this._analyser.fftSize));
|
|
6871
|
-
this._pollIntervalMs = options.pollIntervalMs ?? AUDIO_LEVEL_POLL_INTERVAL_MS;
|
|
6821
|
+
this._pollIntervalMs = options.pollIntervalMs ?? require_operators.AUDIO_LEVEL_POLL_INTERVAL_MS;
|
|
6872
6822
|
}
|
|
6873
6823
|
/** RMS level of the remote audio, 0..1. 0 when no stream is attached. */
|
|
6874
6824
|
get level$() {
|
|
@@ -8248,13 +8198,13 @@ var WebRTCCall = class extends Destroyable {
|
|
|
8248
8198
|
async waitForPeerConnectionConnected() {
|
|
8249
8199
|
const pc = this.rtcPeerConnection;
|
|
8250
8200
|
if (!pc) return false;
|
|
8251
|
-
const deadline = Date.now() + PEER_CONNECTION_RECOVERY_WAIT_MS;
|
|
8201
|
+
const deadline = Date.now() + require_operators.PEER_CONNECTION_RECOVERY_WAIT_MS;
|
|
8252
8202
|
for (;;) {
|
|
8253
8203
|
const state = pc.connectionState;
|
|
8254
8204
|
if (state === "connected") return true;
|
|
8255
8205
|
if (state === "failed" || state === "closed") return false;
|
|
8256
8206
|
if (Date.now() >= deadline) return false;
|
|
8257
|
-
await new Promise((resolve) => setTimeout(resolve, PEER_CONNECTION_RECOVERY_POLL_MS));
|
|
8207
|
+
await new Promise((resolve) => setTimeout(resolve, require_operators.PEER_CONNECTION_RECOVERY_POLL_MS));
|
|
8258
8208
|
}
|
|
8259
8209
|
}
|
|
8260
8210
|
/**
|
|
@@ -8696,6 +8646,7 @@ function inferCallErrorKind(error) {
|
|
|
8696
8646
|
if (error instanceof require_operators.RPCTimeoutError) return "timeout";
|
|
8697
8647
|
if (error instanceof require_operators.JSONRPCError) return "signaling";
|
|
8698
8648
|
if (error instanceof require_operators.MediaTrackError) return "media";
|
|
8649
|
+
if (error instanceof require_operators.MediaAccessError) return "media";
|
|
8699
8650
|
if (error instanceof require_operators.WebSocketConnectionError || error instanceof require_operators.TransportConnectionError) return "network";
|
|
8700
8651
|
return "internal";
|
|
8701
8652
|
}
|
|
@@ -8704,14 +8655,15 @@ function inferCallErrorKind(error) {
|
|
|
8704
8655
|
* destroy the call, because the session will reauthenticate and any pending
|
|
8705
8656
|
* RPC can then be retried. */
|
|
8706
8657
|
const RECOVERABLE_RPC_CODES = new Set([
|
|
8707
|
-
RPC_ERROR_REQUESTER_VALIDATION_FAILED,
|
|
8708
|
-
RPC_ERROR_AUTHENTICATION_FAILED,
|
|
8709
|
-
RPC_ERROR_INVALID_PARAMS
|
|
8658
|
+
require_operators.RPC_ERROR_REQUESTER_VALIDATION_FAILED,
|
|
8659
|
+
require_operators.RPC_ERROR_AUTHENTICATION_FAILED,
|
|
8660
|
+
require_operators.RPC_ERROR_INVALID_PARAMS
|
|
8710
8661
|
]);
|
|
8711
8662
|
/** Determines whether an error should be fatal (destroy the call). */
|
|
8712
8663
|
function isFatalError(error) {
|
|
8713
8664
|
if (error instanceof require_operators.VertoPongError) return false;
|
|
8714
8665
|
if (error instanceof require_operators.MediaTrackError) return false;
|
|
8666
|
+
if (error instanceof require_operators.MediaAccessError) return error.fatal;
|
|
8715
8667
|
if (error instanceof require_operators.RPCTimeoutError) return false;
|
|
8716
8668
|
if (error instanceof require_operators.JSONRPCError && RECOVERABLE_RPC_CODES.has(error.code)) return false;
|
|
8717
8669
|
return true;
|
|
@@ -8737,10 +8689,10 @@ var CallFactory = class {
|
|
|
8737
8689
|
return {
|
|
8738
8690
|
vertoManager: new WebRTCVertoManager(callInstance, this.attachManager, this.deviceController, this.webRTCApiProvider, {
|
|
8739
8691
|
nodeId: options.nodeId,
|
|
8740
|
-
onError: (error) => {
|
|
8692
|
+
onError: (error, options$1) => {
|
|
8741
8693
|
const callError = {
|
|
8742
8694
|
kind: inferCallErrorKind(error),
|
|
8743
|
-
fatal: isFatalError(error),
|
|
8695
|
+
fatal: options$1?.fatal ?? isFatalError(error),
|
|
8744
8696
|
error,
|
|
8745
8697
|
callId: callInstance.id
|
|
8746
8698
|
};
|
|
@@ -9199,6 +9151,17 @@ var PendingRPC = class PendingRPC {
|
|
|
9199
9151
|
//#endregion
|
|
9200
9152
|
//#region src/managers/ClientSessionManager.ts
|
|
9201
9153
|
const logger$9 = require_operators.getLogger();
|
|
9154
|
+
/**
|
|
9155
|
+
* Decide whether an error emitted on `call.errors$` during dial should
|
|
9156
|
+
* abort the dial. A non-fatal MediaAccessError means the call degraded to
|
|
9157
|
+
* receive-only and still connects — everything else rejects `dial()` with
|
|
9158
|
+
* the real cause.
|
|
9159
|
+
*
|
|
9160
|
+
* Pure function — exported for unit testing.
|
|
9161
|
+
*/
|
|
9162
|
+
function shouldAbortDial(callError) {
|
|
9163
|
+
return callError.fatal || !(callError.error instanceof require_operators.MediaAccessError);
|
|
9164
|
+
}
|
|
9202
9165
|
const getAddressSearchURI = (options) => {
|
|
9203
9166
|
const to = options.to?.split("?")[0];
|
|
9204
9167
|
const from$8 = options.from?.startsWith("subscriber://") ? options.from.replace("subscriber://", "") : options.from;
|
|
@@ -9424,7 +9387,7 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
9424
9387
|
}
|
|
9425
9388
|
async handleAuthenticationError(error) {
|
|
9426
9389
|
logger$9.error("Authentication error:", error);
|
|
9427
|
-
const isRecoverableAuthError = error instanceof require_operators.JSONRPCError && (error.code === RPC_ERROR_REQUESTER_VALIDATION_FAILED || error.code === RPC_ERROR_INVALID_PARAMS || error.code === RPC_ERROR_AUTHENTICATION_FAILED);
|
|
9390
|
+
const isRecoverableAuthError = error instanceof require_operators.JSONRPCError && (error.code === require_operators.RPC_ERROR_REQUESTER_VALIDATION_FAILED || error.code === require_operators.RPC_ERROR_INVALID_PARAMS || error.code === require_operators.RPC_ERROR_AUTHENTICATION_FAILED);
|
|
9428
9391
|
const hasStoredState = await (0, rxjs.firstValueFrom)(this.authorizationState$.pipe((0, rxjs.take)(1))) !== void 0;
|
|
9429
9392
|
if (isRecoverableAuthError && hasStoredState) {
|
|
9430
9393
|
logger$9.debug("[Session] Recoverable auth error — cleaning up stored state and reconnecting fresh");
|
|
@@ -9625,7 +9588,7 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
9625
9588
|
to: destinationURI,
|
|
9626
9589
|
...options
|
|
9627
9590
|
});
|
|
9628
|
-
await (0, rxjs.firstValueFrom)((0, rxjs.race)(callSession.selfId$.pipe((0, rxjs.filter)((id) => Boolean(id)), (0, rxjs.take)(1), (0, rxjs.timeout)(this.callCreateTimeout)), callSession.errors$.pipe((0, rxjs.take)(1), (0, rxjs.switchMap)((callError) => (0, rxjs.throwError)(() => callError.error)))));
|
|
9591
|
+
await (0, rxjs.firstValueFrom)((0, rxjs.race)(callSession.selfId$.pipe((0, rxjs.filter)((id) => Boolean(id)), (0, rxjs.take)(1), (0, rxjs.timeout)(this.callCreateTimeout)), callSession.errors$.pipe((0, rxjs.filter)(shouldAbortDial), (0, rxjs.take)(1), (0, rxjs.switchMap)((callError) => (0, rxjs.throwError)(() => callError.error)))));
|
|
9629
9592
|
this._calls$.next({
|
|
9630
9593
|
[`${callSession.id}`]: callSession,
|
|
9631
9594
|
...this._calls$.value
|
|
@@ -9789,7 +9752,7 @@ function resolveExpiresAt(data) {
|
|
|
9789
9752
|
if (data.expires_at) return data.expires_at;
|
|
9790
9753
|
if (data.expires_in) return Math.floor(Date.now() / 1e3) + data.expires_in;
|
|
9791
9754
|
logger$7.warn("[DeviceToken] Could not determine token expiry, using default");
|
|
9792
|
-
return Math.floor(Date.now() / 1e3) + DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9755
|
+
return Math.floor(Date.now() / 1e3) + require_operators.DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9793
9756
|
}
|
|
9794
9757
|
/**
|
|
9795
9758
|
* Resolves the token TTL in seconds from a fresh response.
|
|
@@ -9802,7 +9765,7 @@ function resolveExpiresAt(data) {
|
|
|
9802
9765
|
function resolveExpireIn(data) {
|
|
9803
9766
|
if (data.expires_in) return data.expires_in;
|
|
9804
9767
|
if (data.expires_at) return Math.max(data.expires_at - Math.floor(Date.now() / 1e3), 1);
|
|
9805
|
-
return DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9768
|
+
return require_operators.DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9806
9769
|
}
|
|
9807
9770
|
/**
|
|
9808
9771
|
* Manages the Client Bound SAT lifecycle: activation, token exchange,
|
|
@@ -9822,10 +9785,10 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9822
9785
|
this._currentToken$ = this.createBehaviorSubject(null);
|
|
9823
9786
|
this._refreshInProgress = false;
|
|
9824
9787
|
this._paused = false;
|
|
9825
|
-
this._effectiveExpireIn = DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9788
|
+
this._effectiveExpireIn = require_operators.DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
|
|
9826
9789
|
this.subscribeTo(this._currentToken$.pipe((0, rxjs.filter)(Boolean), (0, rxjs.switchMap)((tokenData) => {
|
|
9827
9790
|
const expiresAt = resolveExpiresAt(tokenData);
|
|
9828
|
-
const refreshIn = Math.max(expiresAt * 1e3 - Date.now() - DEVICE_TOKEN_REFRESH_BUFFER_MS, 1e3);
|
|
9791
|
+
const refreshIn = Math.max(expiresAt * 1e3 - Date.now() - require_operators.DEVICE_TOKEN_REFRESH_BUFFER_MS, 1e3);
|
|
9829
9792
|
logger$7.debug(`[DeviceToken] Scheduling Client Bound SAT refresh in ${refreshIn}ms`);
|
|
9830
9793
|
return (0, rxjs.timer)(refreshIn);
|
|
9831
9794
|
})), () => {
|
|
@@ -9853,7 +9816,7 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9853
9816
|
*/
|
|
9854
9817
|
async activate(user, session, updateCredential) {
|
|
9855
9818
|
const { satClaims } = user;
|
|
9856
|
-
if (!satClaims?.scope?.includes(SAT_REFRESH_SCOPE)) {
|
|
9819
|
+
if (!satClaims?.scope?.includes(require_operators.SAT_REFRESH_SCOPE)) {
|
|
9857
9820
|
logger$7.debug("[DeviceToken] No sat:refresh scope, skipping Client Bound SAT activation");
|
|
9858
9821
|
return {
|
|
9859
9822
|
activated: false,
|
|
@@ -9896,7 +9859,7 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9896
9859
|
* reactive pipeline is about to refresh it anyway).
|
|
9897
9860
|
*/
|
|
9898
9861
|
isTokenFresh(token) {
|
|
9899
|
-
return resolveExpiresAt(token) * 1e3 - Date.now() > DEVICE_TOKEN_REFRESH_BUFFER_MS;
|
|
9862
|
+
return resolveExpiresAt(token) * 1e3 - Date.now() > require_operators.DEVICE_TOKEN_REFRESH_BUFFER_MS;
|
|
9900
9863
|
}
|
|
9901
9864
|
/**
|
|
9902
9865
|
* Obtains a Client Bound SAT from `/api/fabric/subscriber/devices/token`.
|
|
@@ -9905,14 +9868,14 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9905
9868
|
async obtainToken() {
|
|
9906
9869
|
const dpopProof = await this.dpopManager.createHttpProof({
|
|
9907
9870
|
method: "POST",
|
|
9908
|
-
uri: DEVICE_TOKEN_ENDPOINT
|
|
9871
|
+
uri: require_operators.DEVICE_TOKEN_ENDPOINT
|
|
9909
9872
|
});
|
|
9910
9873
|
const response = await this.http.request({
|
|
9911
|
-
url: DEVICE_TOKEN_ENDPOINT,
|
|
9874
|
+
url: require_operators.DEVICE_TOKEN_ENDPOINT,
|
|
9912
9875
|
...POST_PARAMS,
|
|
9913
9876
|
body: JSON.stringify({
|
|
9914
9877
|
dpop_token: dpopProof,
|
|
9915
|
-
expire_in: DEVICE_TOKEN_DEFAULT_EXPIRE_IN
|
|
9878
|
+
expire_in: require_operators.DEVICE_TOKEN_DEFAULT_EXPIRE_IN
|
|
9916
9879
|
})
|
|
9917
9880
|
});
|
|
9918
9881
|
if (!response.ok || !response.body) throw new require_operators.DeviceTokenError(`Failed to obtain device token: ${response.status} ${response.statusText}`);
|
|
@@ -9931,11 +9894,11 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9931
9894
|
logger$7.debug("[DeviceToken] Refreshing Client Bound SAT");
|
|
9932
9895
|
const dpopProof = await this.dpopManager.createHttpProof({
|
|
9933
9896
|
method: "POST",
|
|
9934
|
-
uri: DEVICE_REFRESH_ENDPOINT,
|
|
9897
|
+
uri: require_operators.DEVICE_REFRESH_ENDPOINT,
|
|
9935
9898
|
accessToken: currentToken
|
|
9936
9899
|
});
|
|
9937
9900
|
const response = await this.http.request({
|
|
9938
|
-
url: DEVICE_REFRESH_ENDPOINT,
|
|
9901
|
+
url: require_operators.DEVICE_REFRESH_ENDPOINT,
|
|
9939
9902
|
...POST_PARAMS,
|
|
9940
9903
|
body: JSON.stringify({
|
|
9941
9904
|
dpop_token: dpopProof,
|
|
@@ -9996,12 +9959,12 @@ var DeviceTokenManager = class extends Destroyable {
|
|
|
9996
9959
|
*/
|
|
9997
9960
|
async retryRefresh(session, currentToken, updateCredential) {
|
|
9998
9961
|
let lastError;
|
|
9999
|
-
for (let attempt = 0; attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES; attempt++) try {
|
|
9962
|
+
for (let attempt = 0; attempt < require_operators.DEVICE_TOKEN_REFRESH_MAX_RETRIES; attempt++) try {
|
|
10000
9963
|
return await this.refreshToken(session, currentToken, updateCredential);
|
|
10001
9964
|
} catch (error) {
|
|
10002
9965
|
lastError = error;
|
|
10003
|
-
if (attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES - 1) {
|
|
10004
|
-
const delay = DEVICE_TOKEN_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt);
|
|
9966
|
+
if (attempt < require_operators.DEVICE_TOKEN_REFRESH_MAX_RETRIES - 1) {
|
|
9967
|
+
const delay = require_operators.DEVICE_TOKEN_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt);
|
|
10005
9968
|
logger$7.warn(`[DeviceToken] Refresh attempt ${attempt + 1} failed, retrying in ${delay}ms`);
|
|
10006
9969
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
10007
9970
|
}
|
|
@@ -10078,7 +10041,7 @@ var CredentialRefreshCoordinator = class extends Destroyable {
|
|
|
10078
10041
|
*/
|
|
10079
10042
|
scheduleDeveloperRefresh(provider, expiresAt, attempt = 0) {
|
|
10080
10043
|
if (this._developerTimerId !== void 0) clearTimeout(this._developerTimerId);
|
|
10081
|
-
const refreshInterval = attempt === 0 ? Math.max(expiresAt - Date.now() - CREDENTIAL_REFRESH_BUFFER_MS, 1e3) : Math.min(CREDENTIAL_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt) * (.5 + Math.random() * .5), CREDENTIAL_REFRESH_MAX_DELAY_MS);
|
|
10044
|
+
const refreshInterval = attempt === 0 ? Math.max(expiresAt - Date.now() - require_operators.CREDENTIAL_REFRESH_BUFFER_MS, 1e3) : Math.min(require_operators.CREDENTIAL_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt) * (.5 + Math.random() * .5), require_operators.CREDENTIAL_REFRESH_MAX_DELAY_MS);
|
|
10082
10045
|
this._developerTimerId = setTimeout(async () => {
|
|
10083
10046
|
try {
|
|
10084
10047
|
if (!provider.refresh) throw new require_operators.InvalidCredentialsError("Credential provider does not support refresh");
|
|
@@ -10089,9 +10052,9 @@ var CredentialRefreshCoordinator = class extends Destroyable {
|
|
|
10089
10052
|
if (newCredentials.expiry_at) this.scheduleDeveloperRefresh(provider, newCredentials.expiry_at, 0);
|
|
10090
10053
|
} catch (error) {
|
|
10091
10054
|
const nextAttempt = attempt + 1;
|
|
10092
|
-
logger$6.error(`[Coordinator] Credential refresh failed (attempt ${nextAttempt}/${CREDENTIAL_REFRESH_MAX_RETRIES}):`, error);
|
|
10055
|
+
logger$6.error(`[Coordinator] Credential refresh failed (attempt ${nextAttempt}/${require_operators.CREDENTIAL_REFRESH_MAX_RETRIES}):`, error);
|
|
10093
10056
|
this.deps.notifier.onError(error instanceof Error ? error : new Error(String(error), { cause: error }));
|
|
10094
|
-
if (nextAttempt < CREDENTIAL_REFRESH_MAX_RETRIES) this.scheduleDeveloperRefresh(provider, expiresAt, nextAttempt);
|
|
10057
|
+
if (nextAttempt < require_operators.CREDENTIAL_REFRESH_MAX_RETRIES) this.scheduleDeveloperRefresh(provider, expiresAt, nextAttempt);
|
|
10095
10058
|
else {
|
|
10096
10059
|
logger$6.error("[Coordinator] Credential refresh exhausted all retries. Disconnecting.");
|
|
10097
10060
|
this.deps.notifier.onError(new require_operators.TokenRefreshError("Credential refresh failed after max retries"));
|
|
@@ -10195,7 +10158,7 @@ var CredentialRefreshCoordinator = class extends Destroyable {
|
|
|
10195
10158
|
activated: false,
|
|
10196
10159
|
reason: "activation-timeout"
|
|
10197
10160
|
});
|
|
10198
|
-
}, CREDENTIAL_ACTIVATE_TIMEOUT_MS);
|
|
10161
|
+
}, require_operators.CREDENTIAL_ACTIVATE_TIMEOUT_MS);
|
|
10199
10162
|
inner.then((result) => {
|
|
10200
10163
|
clearTimeout(timer$3);
|
|
10201
10164
|
resolve(result);
|
|
@@ -11331,7 +11294,7 @@ var SignalWire = class extends Destroyable {
|
|
|
11331
11294
|
logger$1.warn("[SignalWire] Failed to initialize VisibilityController:", error);
|
|
11332
11295
|
}
|
|
11333
11296
|
try {
|
|
11334
|
-
this._diagnosticsCollector = new DiagnosticsCollector({ sdkVersion: "4.0.0-rc.
|
|
11297
|
+
this._diagnosticsCollector = new DiagnosticsCollector({ sdkVersion: "4.0.0-rc.2" });
|
|
11335
11298
|
} catch (error) {
|
|
11336
11299
|
logger$1.warn("[SignalWire] Failed to initialize DiagnosticsCollector:", error);
|
|
11337
11300
|
}
|
|
@@ -11865,7 +11828,7 @@ var StaticCredentialProvider = class {
|
|
|
11865
11828
|
/**
|
|
11866
11829
|
* Library version from package.json, injected at build time.
|
|
11867
11830
|
*/
|
|
11868
|
-
const version = "4.0.0-rc.
|
|
11831
|
+
const version = "4.0.0-rc.2";
|
|
11869
11832
|
/**
|
|
11870
11833
|
* Flag indicating the library has been loaded and is ready to use.
|
|
11871
11834
|
* For UMD builds: `window.SignalWire.ready`
|
|
@@ -11887,7 +11850,7 @@ const ready = true;
|
|
|
11887
11850
|
*/
|
|
11888
11851
|
const emitReadyEvent = () => {
|
|
11889
11852
|
if (typeof window !== "undefined") {
|
|
11890
|
-
const event = new CustomEvent("signalwire:js:ready", { detail: { version: "4.0.0-rc.
|
|
11853
|
+
const event = new CustomEvent("signalwire:js:ready", { detail: { version: "4.0.0-rc.2" } });
|
|
11891
11854
|
window.dispatchEvent(event);
|
|
11892
11855
|
}
|
|
11893
11856
|
};
|
|
@@ -11902,6 +11865,7 @@ exports.DPoPInitError = require_operators.DPoPInitError;
|
|
|
11902
11865
|
exports.DeviceTokenError = require_operators.DeviceTokenError;
|
|
11903
11866
|
exports.EmbedTokenCredentialProvider = EmbedTokenCredentialProvider;
|
|
11904
11867
|
exports.InvalidCredentialsError = require_operators.InvalidCredentialsError;
|
|
11868
|
+
exports.MediaAccessError = require_operators.MediaAccessError;
|
|
11905
11869
|
exports.MediaTrackError = require_operators.MediaTrackError;
|
|
11906
11870
|
exports.MessageParseError = require_operators.MessageParseError;
|
|
11907
11871
|
exports.OverconstrainedFallbackError = require_operators.OverconstrainedFallbackError;
|