@signalwire/js 4.0.0-dev-20260410161202 → 4.0.0-dev-20260410164129
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 +46 -35
- package/dist/browser.mjs.map +1 -1
- package/dist/browser.umd.js +46 -35
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +46 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +46 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1319,7 +1319,7 @@ var NavigatorDeviceController = class extends Destroyable {
|
|
|
1319
1319
|
enableAudioInput() {
|
|
1320
1320
|
if (this._audioInputDisabled$.value) {
|
|
1321
1321
|
this._audioInputDisabled$.next(false);
|
|
1322
|
-
const restored = this._lastAudioInputBeforeDisable ?? this.audioInputDevices[0]
|
|
1322
|
+
const restored = this._lastAudioInputBeforeDisable ?? this.audioInputDevices[0];
|
|
1323
1323
|
this._selectedDevicesState$.next({
|
|
1324
1324
|
...this._selectedDevicesState$.value,
|
|
1325
1325
|
audioinput: restored
|
|
@@ -1340,7 +1340,7 @@ var NavigatorDeviceController = class extends Destroyable {
|
|
|
1340
1340
|
enableVideoInput() {
|
|
1341
1341
|
if (this._videoInputDisabled$.value) {
|
|
1342
1342
|
this._videoInputDisabled$.next(false);
|
|
1343
|
-
const restored = this._lastVideoInputBeforeDisable ?? this.videoInputDevices[0]
|
|
1343
|
+
const restored = this._lastVideoInputBeforeDisable ?? this.videoInputDevices[0];
|
|
1344
1344
|
this._selectedDevicesState$.next({
|
|
1345
1345
|
...this._selectedDevicesState$.value,
|
|
1346
1346
|
videoinput: restored
|
|
@@ -2276,7 +2276,7 @@ function detectScreenShareAudio() {
|
|
|
2276
2276
|
* Safely retrieves navigator.mediaDevices, returning null if unavailable.
|
|
2277
2277
|
*/
|
|
2278
2278
|
function getNavigatorMediaDevices() {
|
|
2279
|
-
if (typeof navigator !== "undefined"
|
|
2279
|
+
if (typeof navigator !== "undefined") return navigator.mediaDevices;
|
|
2280
2280
|
return null;
|
|
2281
2281
|
}
|
|
2282
2282
|
|
|
@@ -2397,11 +2397,12 @@ var PreflightRunner = class extends Destroyable {
|
|
|
2397
2397
|
let pc;
|
|
2398
2398
|
try {
|
|
2399
2399
|
pc = new RTCPeerConnection({ iceServers: this.iceServers });
|
|
2400
|
+
const peerConnection = pc;
|
|
2400
2401
|
const candidateTypes = /* @__PURE__ */ new Set();
|
|
2401
2402
|
const startTime = Date.now();
|
|
2402
2403
|
const gatheringComplete = new Promise((resolve) => {
|
|
2403
2404
|
const timer$1 = setTimeout(resolve, ICE_GATHERING_TIMEOUT_MS);
|
|
2404
|
-
|
|
2405
|
+
peerConnection.onicecandidate = (event) => {
|
|
2405
2406
|
if (event.candidate) {
|
|
2406
2407
|
const candidateStr = event.candidate.candidate;
|
|
2407
2408
|
if (candidateStr.includes("typ host")) candidateTypes.add("host");
|
|
@@ -3936,8 +3937,8 @@ var CallEventsManager = class extends Destroyable {
|
|
|
3936
3937
|
}
|
|
3937
3938
|
updateParticipantPositions(layoutChangedEvent) {
|
|
3938
3939
|
if (Object.keys(this._participants$.value).length > 0 && !layoutChangedEvent.layers.some((layer) => !!layer.member_id)) logger$18.warn("[CallEventsManager] No layers with member_id found in layout.changed event. Nothing to update.");
|
|
3939
|
-
layoutChangedEvent.layers.filter((layer) =>
|
|
3940
|
-
if (!
|
|
3940
|
+
layoutChangedEvent.layers.filter((layer) => !!layer.member_id).filter((layer) => {
|
|
3941
|
+
if (!(layer.member_id in this._participants$.value)) {
|
|
3941
3942
|
logger$18.warn(`[CallEventsManager] Skipping layout layer for unknown member_id: ${layer.member_id}`);
|
|
3942
3943
|
return false;
|
|
3943
3944
|
}
|
|
@@ -5298,7 +5299,7 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5298
5299
|
const preferredAudioCodecs = this.options.preferredAudioCodecs ?? PreferencesContainer.instance.preferredAudioCodecs;
|
|
5299
5300
|
const preferredVideoCodecs = this.options.preferredVideoCodecs ?? PreferencesContainer.instance.preferredVideoCodecs;
|
|
5300
5301
|
const stereo = this.options.stereo ?? PreferencesContainer.instance.stereoAudio;
|
|
5301
|
-
if (preferredAudioCodecs
|
|
5302
|
+
if (preferredAudioCodecs.length > 0 || preferredVideoCodecs.length > 0) {
|
|
5302
5303
|
result = setCodecPreferences(result, preferredAudioCodecs, preferredVideoCodecs);
|
|
5303
5304
|
logger$14.debug("[RTCPeerConnectionController] Applied codec preferences to SDP", {
|
|
5304
5305
|
preferredAudioCodecs,
|
|
@@ -5540,11 +5541,9 @@ var RTCPeerConnectionController = class extends Destroyable {
|
|
|
5540
5541
|
oldTrack.stop();
|
|
5541
5542
|
this.localStreamController.removeTrack(trackId);
|
|
5542
5543
|
const newTrack = (await this.getUserMedia({ audio: mergedConstraints })).getAudioTracks()[0];
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
logger$14.debug(`[RTCPeerConnectionController] Audio track replaced for server-pushed params. New track: ${newTrack.id}`);
|
|
5547
|
-
}
|
|
5544
|
+
await sender.replaceTrack(newTrack);
|
|
5545
|
+
this.localStreamController.addTrack(newTrack);
|
|
5546
|
+
logger$14.debug(`[RTCPeerConnectionController] Audio track replaced for server-pushed params. New track: ${newTrack.id}`);
|
|
5548
5547
|
}
|
|
5549
5548
|
}
|
|
5550
5549
|
/**
|
|
@@ -5838,7 +5837,7 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
5838
5837
|
logger$13.warn("[WebRTCManager] No peer connection for keyframe request");
|
|
5839
5838
|
return;
|
|
5840
5839
|
}
|
|
5841
|
-
const videoReceiver = pc.getReceivers().find((r) => r.track
|
|
5840
|
+
const videoReceiver = pc.getReceivers().find((r) => r.track.kind === "video");
|
|
5842
5841
|
if (!videoReceiver) {
|
|
5843
5842
|
logger$13.warn("[WebRTCManager] No video receiver for keyframe request");
|
|
5844
5843
|
return;
|
|
@@ -5914,7 +5913,7 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
5914
5913
|
try {
|
|
5915
5914
|
const pc = controller.peerConnection;
|
|
5916
5915
|
if (!pc) continue;
|
|
5917
|
-
const videoReceiver = pc.getReceivers().find((r) => r.track
|
|
5916
|
+
const videoReceiver = pc.getReceivers().find((r) => r.track.kind === "video");
|
|
5918
5917
|
if (!videoReceiver) continue;
|
|
5919
5918
|
if (typeof videoReceiver.requestKeyFrame === "function") {
|
|
5920
5919
|
videoReceiver.requestKeyFrame();
|
|
@@ -6398,6 +6397,12 @@ function computePacketLossPercent(lost, received) {
|
|
|
6398
6397
|
if (total === 0) return 0;
|
|
6399
6398
|
return lost / total * 100;
|
|
6400
6399
|
}
|
|
6400
|
+
function isInboundRtpStat(stat) {
|
|
6401
|
+
return typeof stat === "object" && stat !== null && "type" in stat && stat.type === "inbound-rtp";
|
|
6402
|
+
}
|
|
6403
|
+
function isCandidatePairStat(stat) {
|
|
6404
|
+
return typeof stat === "object" && stat !== null && "type" in stat && stat.type === "candidate-pair";
|
|
6405
|
+
}
|
|
6401
6406
|
var RTCStatsMonitor = class extends Destroyable {
|
|
6402
6407
|
constructor(peerConnection, config = {}) {
|
|
6403
6408
|
super();
|
|
@@ -6529,17 +6534,15 @@ var RTCStatsMonitor = class extends Destroyable {
|
|
|
6529
6534
|
let roundTripTime = 0;
|
|
6530
6535
|
let availableOutgoingBitrate;
|
|
6531
6536
|
report.forEach((stat) => {
|
|
6532
|
-
if (stat.
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
videoPacketsLost += stat.packetsLost ?? 0;
|
|
6540
|
-
}
|
|
6537
|
+
if (isInboundRtpStat(stat)) if (stat.kind === "audio") {
|
|
6538
|
+
audioPacketsReceived += stat.packetsReceived ?? this.lastAudioPacketsReceived;
|
|
6539
|
+
audioPacketsLost += stat.packetsLost ?? 0;
|
|
6540
|
+
audioJitter = Math.max(audioJitter, (stat.jitter ?? 0) * 1e3);
|
|
6541
|
+
} else {
|
|
6542
|
+
videoPacketsReceived += stat.packetsReceived ?? this.lastVideoPacketsReceived;
|
|
6543
|
+
videoPacketsLost += stat.packetsLost ?? 0;
|
|
6541
6544
|
}
|
|
6542
|
-
if (stat
|
|
6545
|
+
if (isCandidatePairStat(stat) && stat.state === "succeeded" && stat.nominated) {
|
|
6543
6546
|
roundTripTime = stat.currentRoundTripTime ? stat.currentRoundTripTime * 1e3 : this.lastRoundTripTime;
|
|
6544
6547
|
availableOutgoingBitrate = stat.availableOutgoingBitrate ?? this.lastAvailableOutgoingBitrate;
|
|
6545
6548
|
}
|
|
@@ -7578,10 +7581,10 @@ var WebRTCCall = class extends Destroyable {
|
|
|
7578
7581
|
logger$10.debug("[Call] Recovery manager failed to enable video");
|
|
7579
7582
|
});
|
|
7580
7583
|
},
|
|
7581
|
-
isNegotiating: () => this.vertoManager.mainPeerConnection
|
|
7584
|
+
isNegotiating: () => this.vertoManager.mainPeerConnection.isNegotiating,
|
|
7582
7585
|
isWebSocketConnected: () => this._lastMergedStatus !== "disconnected",
|
|
7583
7586
|
isCallConnected: () => this._lastMergedStatus === "connected",
|
|
7584
|
-
getPeerConnectionState: () => pc.connectionState
|
|
7587
|
+
getPeerConnectionState: () => pc.connectionState
|
|
7585
7588
|
}, {
|
|
7586
7589
|
debounceTimeMs: prefs.recoveryDebounceTime,
|
|
7587
7590
|
cooldownMs: prefs.recoveryCooldown,
|
|
@@ -8792,7 +8795,7 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
8792
8795
|
*/
|
|
8793
8796
|
async handleVertoAttach(attach) {
|
|
8794
8797
|
const { callID } = attach;
|
|
8795
|
-
if (this._calls$.value
|
|
8798
|
+
if (callID in this._calls$.value) {
|
|
8796
8799
|
logger$7.debug(`[Session] Verto attach for existing call ${callID}, deferring to per-call handler`);
|
|
8797
8800
|
return;
|
|
8798
8801
|
}
|
|
@@ -9490,12 +9493,12 @@ var TransportManager = class extends Destroyable {
|
|
|
9490
9493
|
this.discardStaleEvents = () => {
|
|
9491
9494
|
return (0, rxjs.filter)((message) => {
|
|
9492
9495
|
if (!isSignalwireRequest(message)) return true;
|
|
9493
|
-
const eventChannel = message.params
|
|
9496
|
+
const eventChannel = message.params.event_channel;
|
|
9494
9497
|
if (!eventChannel) return true;
|
|
9495
9498
|
const currentProtocol = this._currentProtocol;
|
|
9496
9499
|
if (!currentProtocol) return true;
|
|
9497
9500
|
if (!eventChannel.includes(currentProtocol)) {
|
|
9498
|
-
const eventType = message.params.event_type
|
|
9501
|
+
const eventType = message.params.event_type;
|
|
9499
9502
|
logger$2.warn(`[Transport] Discarding stale event: ${eventType} (event_channel does not match current protocol)`);
|
|
9500
9503
|
return false;
|
|
9501
9504
|
}
|
|
@@ -9771,7 +9774,7 @@ var SignalWire = class extends Destroyable {
|
|
|
9771
9774
|
}
|
|
9772
9775
|
if (_credentials.expiry_at && credentialProvider?.refresh) {
|
|
9773
9776
|
const refreshFn = async () => {
|
|
9774
|
-
if (!credentialProvider
|
|
9777
|
+
if (!credentialProvider.refresh) throw new require_operators.InvalidCredentialsError("Credential provider does not support refresh");
|
|
9775
9778
|
return credentialProvider.refresh();
|
|
9776
9779
|
};
|
|
9777
9780
|
const refreshInterval = Math.max(_credentials.expiry_at - Date.now() - 5e3, 1e3);
|
|
@@ -10179,7 +10182,7 @@ var SignalWire = class extends Destroyable {
|
|
|
10179
10182
|
* ```
|
|
10180
10183
|
*/
|
|
10181
10184
|
async preflight(destination, options) {
|
|
10182
|
-
const iceServers = this._clientSession
|
|
10185
|
+
const iceServers = this._clientSession.iceServers ?? PreferencesContainer.instance.iceServers ?? [];
|
|
10183
10186
|
const isConnected = this._isConnected$.value;
|
|
10184
10187
|
return new PreflightRunner(this._deviceController, iceServers, isConnected, 0, async (dest, opts) => this.dial(dest, opts), options).run(destination);
|
|
10185
10188
|
}
|
|
@@ -10331,6 +10334,8 @@ var SignalWire = class extends Destroyable {
|
|
|
10331
10334
|
* Triggers the browser's media permission dialog and captures the user's device selections.
|
|
10332
10335
|
*
|
|
10333
10336
|
* @param options - Which permissions to request.
|
|
10337
|
+
* @param options.audio - Whether to request audio permission.
|
|
10338
|
+
* @param options.video - Whether to request video permission.
|
|
10334
10339
|
* @returns The permission result with selected devices.
|
|
10335
10340
|
*/
|
|
10336
10341
|
async requestMediaPermissions(options = {
|
|
@@ -10362,8 +10367,14 @@ var SignalWire = class extends Destroyable {
|
|
|
10362
10367
|
logger$1.warn("[SignalWire] Media permission request failed:", error);
|
|
10363
10368
|
}
|
|
10364
10369
|
await this._deviceController.enumerateDevices();
|
|
10365
|
-
if (audioGranted && selectedAudioDevice)
|
|
10366
|
-
|
|
10370
|
+
if (audioGranted && selectedAudioDevice) {
|
|
10371
|
+
const audioDeviceId = selectedAudioDevice.deviceId;
|
|
10372
|
+
selectedAudioDevice = this.audioInputDevices.find((d) => d.deviceId === audioDeviceId) ?? selectedAudioDevice;
|
|
10373
|
+
}
|
|
10374
|
+
if (videoGranted && selectedVideoDevice) {
|
|
10375
|
+
const videoDeviceId = selectedVideoDevice.deviceId;
|
|
10376
|
+
selectedVideoDevice = this.videoInputDevices.find((d) => d.deviceId === videoDeviceId) ?? selectedVideoDevice;
|
|
10377
|
+
}
|
|
10367
10378
|
if (audioGranted && selectedAudioDevice && !this.selectedAudioInputDevice) this.selectAudioInputDevice(selectedAudioDevice);
|
|
10368
10379
|
if (videoGranted && selectedVideoDevice && !this.selectedVideoInputDevice) this.selectVideoInputDevice(selectedVideoDevice);
|
|
10369
10380
|
return {
|
|
@@ -10396,8 +10407,8 @@ var SignalWire = class extends Destroyable {
|
|
|
10396
10407
|
this._deviceTokenManager?.destroy();
|
|
10397
10408
|
this._dpopManager?.destroy();
|
|
10398
10409
|
if (this._attachManager) this._attachManager.detachAll();
|
|
10399
|
-
this._transport
|
|
10400
|
-
this._clientSession
|
|
10410
|
+
this._transport.destroy();
|
|
10411
|
+
this._clientSession.destroy();
|
|
10401
10412
|
try {
|
|
10402
10413
|
this._networkMonitor?.destroy();
|
|
10403
10414
|
} catch {}
|