livekit-client 2.18.3 → 2.18.4
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/livekit-client.esm.mjs +221 -76
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +2 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +4 -0
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +4 -3
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +1 -1
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/ts4.2/room/RTCEngine.d.ts +2 -0
- package/dist/ts4.2/room/Room.d.ts +2 -0
- package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +4 -0
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +4 -3
- package/dist/ts4.2/room/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/room/PCTransport.ts +4 -3
- package/src/room/RTCEngine.ts +19 -0
- package/src/room/Room.ts +72 -20
- package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +331 -16
- package/src/room/data-track/incoming/IncomingDataTrackManager.ts +92 -41
- package/src/room/participant/RemoteParticipant.ts +14 -2
- package/src/room/types.ts +2 -1
- package/src/utils/deferrable-map.ts +2 -2
|
@@ -8704,6 +8704,11 @@ function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {
|
|
|
8704
8704
|
if (!window.RTCPeerConnection) {
|
|
8705
8705
|
return;
|
|
8706
8706
|
}
|
|
8707
|
+
const addEventListener = Object.getOwnPropertyDescriptor(EventTarget.prototype, 'addEventListener');
|
|
8708
|
+
if (!addEventListener.writable) {
|
|
8709
|
+
log$4('Unable to polyfill events');
|
|
8710
|
+
return;
|
|
8711
|
+
}
|
|
8707
8712
|
const proto = window.RTCPeerConnection.prototype;
|
|
8708
8713
|
const nativeAddEventListener = proto.addEventListener;
|
|
8709
8714
|
proto.addEventListener = function (nativeEventName, cb) {
|
|
@@ -8846,7 +8851,7 @@ function detectBrowser(window) {
|
|
|
8846
8851
|
// Chrome 74 removed webkitGetUserMedia on http as well so we need the
|
|
8847
8852
|
// more complicated fallback to webkitRTCPeerConnection.
|
|
8848
8853
|
result.browser = 'chrome';
|
|
8849
|
-
result.version = parseInt(extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2));
|
|
8854
|
+
result.version = parseInt(extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2)) || null;
|
|
8850
8855
|
} else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) {
|
|
8851
8856
|
// Safari.
|
|
8852
8857
|
result.browser = 'safari';
|
|
@@ -9120,7 +9125,11 @@ function shimGetUserMedia$2(window, browserDetails) {
|
|
|
9120
9125
|
function shimMediaStream(window) {
|
|
9121
9126
|
window.MediaStream = window.MediaStream || window.webkitMediaStream;
|
|
9122
9127
|
}
|
|
9123
|
-
function shimOnTrack$1(window) {
|
|
9128
|
+
function shimOnTrack$1(window, browserDetails) {
|
|
9129
|
+
if (browserDetails.version > 102) {
|
|
9130
|
+
// Unified plan is supported so no need to do anything.
|
|
9131
|
+
return;
|
|
9132
|
+
}
|
|
9124
9133
|
if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) {
|
|
9125
9134
|
Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
|
|
9126
9135
|
get() {
|
|
@@ -9283,7 +9292,10 @@ function shimGetSendersWithDtmf(window) {
|
|
|
9283
9292
|
});
|
|
9284
9293
|
}
|
|
9285
9294
|
}
|
|
9286
|
-
function shimSenderReceiverGetStats(window) {
|
|
9295
|
+
function shimSenderReceiverGetStats(window, browserDetails) {
|
|
9296
|
+
if (browserDetails.version >= 67) {
|
|
9297
|
+
return;
|
|
9298
|
+
}
|
|
9287
9299
|
if (!(typeof window === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
|
|
9288
9300
|
return;
|
|
9289
9301
|
}
|
|
@@ -9650,6 +9662,10 @@ function shimPeerConnection$1(window, browserDetails) {
|
|
|
9650
9662
|
|
|
9651
9663
|
// Attempt to fix ONN in plan-b mode.
|
|
9652
9664
|
function fixNegotiationNeeded(window, browserDetails) {
|
|
9665
|
+
if (browserDetails.version > 102) {
|
|
9666
|
+
// Plan-B is no longer supported.
|
|
9667
|
+
return;
|
|
9668
|
+
}
|
|
9653
9669
|
wrapPeerConnectionEvent(window, 'negotiationneeded', e => {
|
|
9654
9670
|
const pc = e.target;
|
|
9655
9671
|
if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === 'plan-b') {
|
|
@@ -9785,6 +9801,15 @@ function shimPeerConnection(window, browserDetails) {
|
|
|
9785
9801
|
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
|
9786
9802
|
});
|
|
9787
9803
|
}
|
|
9804
|
+
}
|
|
9805
|
+
function shimGetStats(window, browserDetails) {
|
|
9806
|
+
if (typeof window !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {
|
|
9807
|
+
return; // probably media.peerconnection.enabled=false in about:config
|
|
9808
|
+
}
|
|
9809
|
+
if (browserDetails.version >= 151) {
|
|
9810
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1056433
|
|
9811
|
+
return;
|
|
9812
|
+
}
|
|
9788
9813
|
const modernStatsTypes = {
|
|
9789
9814
|
inboundrtp: 'inbound-rtp',
|
|
9790
9815
|
outboundrtp: 'outbound-rtp',
|
|
@@ -9795,6 +9820,10 @@ function shimPeerConnection(window, browserDetails) {
|
|
|
9795
9820
|
const nativeGetStats = window.RTCPeerConnection.prototype.getStats;
|
|
9796
9821
|
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
|
9797
9822
|
const [selector, onSucc, onErr] = arguments;
|
|
9823
|
+
if (this.signalingState === 'closed') {
|
|
9824
|
+
// No longer required in FF151+
|
|
9825
|
+
return Promise.resolve(new Map());
|
|
9826
|
+
}
|
|
9798
9827
|
return nativeGetStats.apply(this, [selector || null]).then(stats => {
|
|
9799
9828
|
if (browserDetails.version < 53 && !onSucc) {
|
|
9800
9829
|
// Shim only promise getStats with spec-hyphens in type names
|
|
@@ -10009,7 +10038,7 @@ function shimCreateAnswer(window) {
|
|
|
10009
10038
|
}
|
|
10010
10039
|
return origCreateAnswer.apply(this, arguments);
|
|
10011
10040
|
};
|
|
10012
|
-
}var firefoxShim=/*#__PURE__*/Object.freeze({__proto__:null,shimAddTransceiver:shimAddTransceiver,shimCreateAnswer:shimCreateAnswer,shimCreateOffer:shimCreateOffer,shimGetDisplayMedia:shimGetDisplayMedia,shimGetParameters:shimGetParameters,shimGetUserMedia:shimGetUserMedia$1,shimOnTrack:shimOnTrack,shimPeerConnection:shimPeerConnection,shimRTCDataChannel:shimRTCDataChannel,shimReceiverGetStats:shimReceiverGetStats,shimRemoveStream:shimRemoveStream,shimSenderGetStats:shimSenderGetStats});/*
|
|
10041
|
+
}var firefoxShim=/*#__PURE__*/Object.freeze({__proto__:null,shimAddTransceiver:shimAddTransceiver,shimCreateAnswer:shimCreateAnswer,shimCreateOffer:shimCreateOffer,shimGetDisplayMedia:shimGetDisplayMedia,shimGetParameters:shimGetParameters,shimGetStats:shimGetStats,shimGetUserMedia:shimGetUserMedia$1,shimOnTrack:shimOnTrack,shimPeerConnection:shimPeerConnection,shimRTCDataChannel:shimRTCDataChannel,shimReceiverGetStats:shimReceiverGetStats,shimRemoveStream:shimRemoveStream,shimSenderGetStats:shimSenderGetStats});/*
|
|
10013
10042
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
10014
10043
|
*
|
|
10015
10044
|
* Use of this source code is governed by a BSD-style license
|
|
@@ -10444,7 +10473,7 @@ function requireSdp() {
|
|
|
10444
10473
|
const type = candidate.type;
|
|
10445
10474
|
sdp.push('typ');
|
|
10446
10475
|
sdp.push(type);
|
|
10447
|
-
if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
|
|
10476
|
+
if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort !== undefined) {
|
|
10448
10477
|
sdp.push('raddr');
|
|
10449
10478
|
sdp.push(candidate.relatedAddress);
|
|
10450
10479
|
sdp.push('rport');
|
|
@@ -10517,6 +10546,8 @@ function requireSdp() {
|
|
|
10517
10546
|
// Parses a fmtp line, returns dictionary. Sample input:
|
|
10518
10547
|
// a=fmtp:96 vbr=on;cng=on
|
|
10519
10548
|
// Also deals with vbr=on; cng=on
|
|
10549
|
+
// Non-key-value such as telephone-events `0-15` get parsed as
|
|
10550
|
+
// {`0-15`:undefined}
|
|
10520
10551
|
SDPUtils.parseFmtp = function (line) {
|
|
10521
10552
|
const parsed = {};
|
|
10522
10553
|
let kv;
|
|
@@ -11290,15 +11321,21 @@ function shimMaxMessageSize(window, browserDetails) {
|
|
|
11290
11321
|
return origSetRemoteDescription.apply(this, arguments);
|
|
11291
11322
|
};
|
|
11292
11323
|
}
|
|
11293
|
-
function shimSendThrowTypeError(window) {
|
|
11324
|
+
function shimSendThrowTypeError(window, browserDetails) {
|
|
11294
11325
|
if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) {
|
|
11295
11326
|
return;
|
|
11296
11327
|
}
|
|
11328
|
+
if (browserDetails.browser === 'chrome' && browserDetails.version > 149) {
|
|
11329
|
+
// Fixed by https://issues.chromium.org/issues/490588131
|
|
11330
|
+
return;
|
|
11331
|
+
}
|
|
11297
11332
|
|
|
11298
11333
|
// Note: Although Firefox >= 57 has a native implementation, the maximum
|
|
11299
11334
|
// message size can be reset for all data channels at a later stage.
|
|
11300
11335
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
|
|
11301
|
-
|
|
11336
|
+
if (browserDetails.browser === 'firefox' && browserDetails.version > 60) {
|
|
11337
|
+
return;
|
|
11338
|
+
}
|
|
11302
11339
|
function wrapDcSend(dc, pc) {
|
|
11303
11340
|
const origDataChannelSend = dc.send;
|
|
11304
11341
|
dc.send = function send() {
|
|
@@ -11536,16 +11573,16 @@ function adapterFactory() {
|
|
|
11536
11573
|
shimGetUserMedia$2(window, browserDetails);
|
|
11537
11574
|
shimMediaStream(window);
|
|
11538
11575
|
shimPeerConnection$1(window, browserDetails);
|
|
11539
|
-
shimOnTrack$1(window);
|
|
11576
|
+
shimOnTrack$1(window, browserDetails);
|
|
11540
11577
|
shimAddTrackRemoveTrack(window, browserDetails);
|
|
11541
11578
|
shimGetSendersWithDtmf(window);
|
|
11542
|
-
shimSenderReceiverGetStats(window);
|
|
11579
|
+
shimSenderReceiverGetStats(window, browserDetails);
|
|
11543
11580
|
fixNegotiationNeeded(window, browserDetails);
|
|
11544
11581
|
shimRTCIceCandidate(window);
|
|
11545
11582
|
shimRTCIceCandidateRelayProtocol(window);
|
|
11546
11583
|
shimConnectionState(window);
|
|
11547
11584
|
shimMaxMessageSize(window, browserDetails);
|
|
11548
|
-
shimSendThrowTypeError(window);
|
|
11585
|
+
shimSendThrowTypeError(window, browserDetails);
|
|
11549
11586
|
removeExtmapAllowMixed(window, browserDetails);
|
|
11550
11587
|
break;
|
|
11551
11588
|
case 'firefox':
|
|
@@ -11562,6 +11599,7 @@ function adapterFactory() {
|
|
|
11562
11599
|
shimParameterlessSetLocalDescription(window);
|
|
11563
11600
|
shimGetUserMedia$1(window, browserDetails);
|
|
11564
11601
|
shimPeerConnection(window, browserDetails);
|
|
11602
|
+
shimGetStats(window, browserDetails);
|
|
11565
11603
|
shimOnTrack(window);
|
|
11566
11604
|
shimRemoveStream(window);
|
|
11567
11605
|
shimSenderGetStats(window);
|
|
@@ -11574,7 +11612,7 @@ function adapterFactory() {
|
|
|
11574
11612
|
shimRTCIceCandidate(window);
|
|
11575
11613
|
shimConnectionState(window);
|
|
11576
11614
|
shimMaxMessageSize(window, browserDetails);
|
|
11577
|
-
shimSendThrowTypeError(window);
|
|
11615
|
+
shimSendThrowTypeError(window, browserDetails);
|
|
11578
11616
|
break;
|
|
11579
11617
|
case 'safari':
|
|
11580
11618
|
if (!safariShim || !options.shimSafari) {
|
|
@@ -11599,7 +11637,7 @@ function adapterFactory() {
|
|
|
11599
11637
|
shimRTCIceCandidate(window);
|
|
11600
11638
|
shimRTCIceCandidateRelayProtocol(window);
|
|
11601
11639
|
shimMaxMessageSize(window, browserDetails);
|
|
11602
|
-
shimSendThrowTypeError(window);
|
|
11640
|
+
shimSendThrowTypeError(window, browserDetails);
|
|
11603
11641
|
removeExtmapAllowMixed(window, browserDetails);
|
|
11604
11642
|
break;
|
|
11605
11643
|
default:
|
|
@@ -11706,7 +11744,7 @@ function getMatch(exp, ua) {
|
|
|
11706
11744
|
}
|
|
11707
11745
|
function getOSVersion(ua) {
|
|
11708
11746
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
|
11709
|
-
}var version$1 = "2.18.
|
|
11747
|
+
}var version$1 = "2.18.4";const version = version$1;
|
|
11710
11748
|
const protocolVersion = 16;/** Base error that all LiveKit specific custom errors inherit from. */
|
|
11711
11749
|
class LivekitError extends Error {
|
|
11712
11750
|
constructor(code, message, options) {
|
|
@@ -17120,6 +17158,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
17120
17158
|
if (!this._pc) {
|
|
17121
17159
|
return;
|
|
17122
17160
|
}
|
|
17161
|
+
this.pendingInitialOffer = undefined;
|
|
17123
17162
|
this._pc.close();
|
|
17124
17163
|
this._pc.onconnectionstatechange = null;
|
|
17125
17164
|
this._pc.oniceconnectionstatechange = null;
|
|
@@ -17207,7 +17246,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
17207
17246
|
this.remoteStereoMids = stereoMids;
|
|
17208
17247
|
this.remoteNackMids = nackMids;
|
|
17209
17248
|
} else if (sd.type === 'answer') {
|
|
17210
|
-
if (this.pendingInitialOffer) {
|
|
17249
|
+
if (this.pendingInitialOffer && this._pc) {
|
|
17211
17250
|
const initialOffer = this.pendingInitialOffer;
|
|
17212
17251
|
this.pendingInitialOffer = undefined;
|
|
17213
17252
|
const sdpParsed = libExports.parse((_a = initialOffer.sdp) !== null && _a !== void 0 ? _a : '');
|
|
@@ -17529,6 +17568,7 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
17529
17568
|
}
|
|
17530
17569
|
setMungedSDP(sd, munged, remote) {
|
|
17531
17570
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17571
|
+
var _a, _b;
|
|
17532
17572
|
if (munged) {
|
|
17533
17573
|
const originalSdp = sd.sdp;
|
|
17534
17574
|
sd.sdp = munged;
|
|
@@ -17550,9 +17590,9 @@ class PCTransport extends eventsExports.EventEmitter {
|
|
|
17550
17590
|
}
|
|
17551
17591
|
try {
|
|
17552
17592
|
if (remote) {
|
|
17553
|
-
yield this.
|
|
17593
|
+
yield (_a = this._pc) === null || _a === void 0 ? void 0 : _a.setRemoteDescription(sd);
|
|
17554
17594
|
} else {
|
|
17555
|
-
yield this.
|
|
17595
|
+
yield (_b = this._pc) === null || _b === void 0 ? void 0 : _b.setLocalDescription(sd);
|
|
17556
17596
|
}
|
|
17557
17597
|
} catch (e) {
|
|
17558
17598
|
let msg = 'unknown error';
|
|
@@ -20333,6 +20373,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20333
20373
|
/** specifies how often an initial join connection is allowed to retry */
|
|
20334
20374
|
this.maxJoinAttempts = 1;
|
|
20335
20375
|
this.shouldFailNext = false;
|
|
20376
|
+
this.shouldFailOnV1Path = false;
|
|
20336
20377
|
this.log = livekitLogger;
|
|
20337
20378
|
this.reliableDataSequence = 1;
|
|
20338
20379
|
this.reliableMessageBuffer = new DataPacketBuffer();
|
|
@@ -20634,6 +20675,11 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20634
20675
|
if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
|
|
20635
20676
|
throw ConnectionError.cancelled('Connection aborted');
|
|
20636
20677
|
}
|
|
20678
|
+
if (!useV0Path && _this2.shouldFailOnV1Path) {
|
|
20679
|
+
_this2.shouldFailOnV1Path = false;
|
|
20680
|
+
throw ConnectionError.serviceNotFound('Simulated v1 path failure', 'v0-rtc');
|
|
20681
|
+
}
|
|
20682
|
+
livekitLogger.warn('joining signal with ', url);
|
|
20637
20683
|
const joinResponse = yield _this2.client.join(url, token, opts, abortSignal, useV0Path, offerProto);
|
|
20638
20684
|
_this2._isClosed = false;
|
|
20639
20685
|
_this2.latestJoinResponse = joinResponse;
|
|
@@ -20683,6 +20729,10 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
20683
20729
|
}
|
|
20684
20730
|
} else if (e.reason === ConnectionErrorReason.ServiceNotFound) {
|
|
20685
20731
|
_this2.log.warn("Initial connection failed: ".concat(e.message, " \u2013 Retrying"));
|
|
20732
|
+
if (_this2.pcManager) {
|
|
20733
|
+
_this2.pcManager.onStateChange = undefined;
|
|
20734
|
+
yield _this2.cleanupPeerConnections();
|
|
20735
|
+
}
|
|
20686
20736
|
return _this2.join(url, token, opts, abortSignal, true);
|
|
20687
20737
|
}
|
|
20688
20738
|
}
|
|
@@ -21783,6 +21833,11 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
21783
21833
|
// debugging method to fail the next reconnect/resume attempt
|
|
21784
21834
|
this.shouldFailNext = true;
|
|
21785
21835
|
}
|
|
21836
|
+
/* @internal */
|
|
21837
|
+
failNextV1Path() {
|
|
21838
|
+
// debugging method to fail the next connection attempt for /rtc/v1 to trigger the fallback version
|
|
21839
|
+
this.shouldFailOnV1Path = true;
|
|
21840
|
+
}
|
|
21786
21841
|
dataChannelsInfo() {
|
|
21787
21842
|
const infos = [];
|
|
21788
21843
|
const getInfo = (dc, target) => {
|
|
@@ -23540,55 +23595,82 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23540
23595
|
let bufferSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : READABLE_STREAM_DEFAULT_BUFFER_SIZE;
|
|
23541
23596
|
let streamController = null;
|
|
23542
23597
|
const sfuSubscriptionComplete = new Future();
|
|
23598
|
+
const detachSignal = () => {
|
|
23599
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
23600
|
+
};
|
|
23601
|
+
const cleanup = () => {
|
|
23602
|
+
detachSignal();
|
|
23603
|
+
if (!streamController) {
|
|
23604
|
+
log$1.warn("ReadableStream subscribed to ".concat(sid, " was not started."));
|
|
23605
|
+
return;
|
|
23606
|
+
}
|
|
23607
|
+
const descriptor = this.descriptors.get(sid);
|
|
23608
|
+
if (!descriptor) {
|
|
23609
|
+
log$1.warn("Unknown track ".concat(sid, ", skipping cancel..."));
|
|
23610
|
+
return;
|
|
23611
|
+
}
|
|
23612
|
+
if (descriptor.subscription.type !== 'active') {
|
|
23613
|
+
log$1.warn("Subscription for track ".concat(sid, " is not active, skipping cancel..."));
|
|
23614
|
+
return;
|
|
23615
|
+
}
|
|
23616
|
+
descriptor.subscription.streamControllers.delete(streamController);
|
|
23617
|
+
// If no active stream controllers are left, also unsubscribe on the SFU end.
|
|
23618
|
+
if (descriptor.subscription.streamControllers.size === 0) {
|
|
23619
|
+
this.unSubscribeRequest(descriptor.info.sid);
|
|
23620
|
+
}
|
|
23621
|
+
};
|
|
23622
|
+
const onAbort = () => {
|
|
23623
|
+
var _a;
|
|
23624
|
+
if (!streamController) {
|
|
23625
|
+
return;
|
|
23626
|
+
}
|
|
23627
|
+
const currentDescriptor = this.descriptors.get(sid);
|
|
23628
|
+
if ((currentDescriptor === null || currentDescriptor === void 0 ? void 0 : currentDescriptor.subscription.type) === 'active') {
|
|
23629
|
+
currentDescriptor.subscription.streamControllers.delete(streamController);
|
|
23630
|
+
}
|
|
23631
|
+
streamController.error(DataTrackSubscribeError.cancelled());
|
|
23632
|
+
(_a = sfuSubscriptionComplete.reject) === null || _a === void 0 ? void 0 : _a.call(sfuSubscriptionComplete, DataTrackSubscribeError.cancelled());
|
|
23633
|
+
cleanup();
|
|
23634
|
+
};
|
|
23543
23635
|
const stream = new ReadableStream({
|
|
23544
23636
|
start: controller => {
|
|
23545
23637
|
streamController = controller;
|
|
23546
|
-
const onAbort = () => {
|
|
23547
|
-
var _a;
|
|
23548
|
-
controller.error(DataTrackSubscribeError.cancelled());
|
|
23549
|
-
(_a = sfuSubscriptionComplete.reject) === null || _a === void 0 ? void 0 : _a.call(sfuSubscriptionComplete, DataTrackSubscribeError.cancelled());
|
|
23550
|
-
};
|
|
23551
23638
|
this.subscribeRequest(sid, signal).then(() => __awaiter(this, void 0, void 0, function* () {
|
|
23552
|
-
var _a;
|
|
23553
|
-
signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort);
|
|
23639
|
+
var _a, _b, _c;
|
|
23554
23640
|
const descriptor = this.descriptors.get(sid);
|
|
23555
23641
|
if (!descriptor) {
|
|
23556
23642
|
log$1.error("Unknown track ".concat(sid));
|
|
23643
|
+
const err = DataTrackSubscribeError.disconnected();
|
|
23644
|
+
controller.error(err);
|
|
23645
|
+
(_a = sfuSubscriptionComplete.reject) === null || _a === void 0 ? void 0 : _a.call(sfuSubscriptionComplete, err);
|
|
23557
23646
|
return;
|
|
23558
23647
|
}
|
|
23559
23648
|
if (descriptor.subscription.type !== 'active') {
|
|
23560
23649
|
log$1.error("Subscription for track ".concat(sid, " is not active"));
|
|
23650
|
+
const err = DataTrackSubscribeError.disconnected();
|
|
23651
|
+
controller.error(err);
|
|
23652
|
+
(_b = sfuSubscriptionComplete.reject) === null || _b === void 0 ? void 0 : _b.call(sfuSubscriptionComplete, err);
|
|
23561
23653
|
return;
|
|
23562
23654
|
}
|
|
23563
|
-
|
|
23564
|
-
|
|
23655
|
+
// Attach the abort signal, aborting immediately if the abort signal was fired while
|
|
23656
|
+
// subscribeRequest was in flight.
|
|
23657
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
23658
|
+
onAbort();
|
|
23659
|
+
return;
|
|
23660
|
+
}
|
|
23661
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort);
|
|
23662
|
+
descriptor.subscription.streamControllers.set(controller, detachSignal);
|
|
23663
|
+
(_c = sfuSubscriptionComplete.resolve) === null || _c === void 0 ? void 0 : _c.call(sfuSubscriptionComplete);
|
|
23565
23664
|
})).catch(err => {
|
|
23566
23665
|
var _a;
|
|
23666
|
+
// subscribeRequest rejected (cancelled, timed out, disconnected). The signal
|
|
23667
|
+
// listener was never attached in this path, so nothing to detach.
|
|
23567
23668
|
controller.error(err);
|
|
23568
23669
|
(_a = sfuSubscriptionComplete.reject) === null || _a === void 0 ? void 0 : _a.call(sfuSubscriptionComplete, err);
|
|
23569
|
-
}).finally(() => {
|
|
23570
|
-
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
23571
23670
|
});
|
|
23572
23671
|
},
|
|
23573
23672
|
cancel: () => {
|
|
23574
|
-
|
|
23575
|
-
log$1.warn("ReadableStream subscribed to ".concat(sid, " was not started."));
|
|
23576
|
-
return;
|
|
23577
|
-
}
|
|
23578
|
-
const descriptor = this.descriptors.get(sid);
|
|
23579
|
-
if (!descriptor) {
|
|
23580
|
-
log$1.warn("Unknown track ".concat(sid, ", skipping cancel..."));
|
|
23581
|
-
return;
|
|
23582
|
-
}
|
|
23583
|
-
if (descriptor.subscription.type !== 'active') {
|
|
23584
|
-
log$1.warn("Subscription for track ".concat(sid, " is not active, skipping cancel..."));
|
|
23585
|
-
return;
|
|
23586
|
-
}
|
|
23587
|
-
descriptor.subscription.streamControllers.delete(streamController);
|
|
23588
|
-
// If no active stream controllers are left, also unsubscribe on the SFU end.
|
|
23589
|
-
if (descriptor.subscription.streamControllers.size === 0) {
|
|
23590
|
-
this.unSubscribeRequest(descriptor.info.sid);
|
|
23591
|
-
}
|
|
23673
|
+
cleanup();
|
|
23592
23674
|
}
|
|
23593
23675
|
}, new CountQueuingStrategy({
|
|
23594
23676
|
highWaterMark: bufferSize
|
|
@@ -23726,9 +23808,7 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23726
23808
|
log$1.warn("Unexpected descriptor state in unSubscribeRequest, expected active, found ".concat((_a = descriptor.subscription) === null || _a === void 0 ? void 0 : _a.type));
|
|
23727
23809
|
return;
|
|
23728
23810
|
}
|
|
23729
|
-
|
|
23730
|
-
controller.close();
|
|
23731
|
-
}
|
|
23811
|
+
this.closeStreamControllers(descriptor.subscription.streamControllers, sid);
|
|
23732
23812
|
// FIXME: this might be wrong? Shouldn't this only occur if it is the last subscription to
|
|
23733
23813
|
// terminate?
|
|
23734
23814
|
const previousDescriptorSubscription = descriptor.subscription;
|
|
@@ -23741,6 +23821,23 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23741
23821
|
subscribe: false
|
|
23742
23822
|
});
|
|
23743
23823
|
}
|
|
23824
|
+
/** Detach abort-signal listeners and close all downstream stream controllers for an active
|
|
23825
|
+
* subscription. Used when the subscription is being torn down by the manager (unsubscribe,
|
|
23826
|
+
* unpublish, or shutdown). */
|
|
23827
|
+
closeStreamControllers(streamControllers, sid) {
|
|
23828
|
+
for (const [controller, detachSignal] of streamControllers) {
|
|
23829
|
+
// Detach before close so we don't leak a listener on the user's AbortSignal.
|
|
23830
|
+
detachSignal();
|
|
23831
|
+
try {
|
|
23832
|
+
controller.close();
|
|
23833
|
+
} catch (err) {
|
|
23834
|
+
// Defensive: if the controller has already been errored (e.g. by a racing abort whose
|
|
23835
|
+
// listener removed itself before we got here), close() throws. There's nothing
|
|
23836
|
+
// meaningful to do other than log — the stream is already terminal.
|
|
23837
|
+
log$1.warn("Failed to close readable stream for track ".concat(sid, ": ").concat(err));
|
|
23838
|
+
}
|
|
23839
|
+
}
|
|
23840
|
+
}
|
|
23744
23841
|
/** SFU notification that track publications have changed.
|
|
23745
23842
|
*
|
|
23746
23843
|
* This event is produced from both {@link JoinResponse} and {@link ParticipantUpdate}
|
|
@@ -23822,9 +23919,7 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23822
23919
|
}
|
|
23823
23920
|
this.descriptors.delete(sid);
|
|
23824
23921
|
if (descriptor.subscription.type === 'active') {
|
|
23825
|
-
descriptor.subscription.streamControllers
|
|
23826
|
-
controller.close();
|
|
23827
|
-
});
|
|
23922
|
+
this.closeStreamControllers(descriptor.subscription.streamControllers, sid);
|
|
23828
23923
|
this.subscriptionHandles.delete(descriptor.subscription.subcriptionHandle);
|
|
23829
23924
|
}
|
|
23830
23925
|
this.emit('trackUnpublished', {
|
|
@@ -23874,7 +23969,7 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23874
23969
|
type: 'active',
|
|
23875
23970
|
subcriptionHandle: assignedHandle,
|
|
23876
23971
|
pipeline,
|
|
23877
|
-
streamControllers: new
|
|
23972
|
+
streamControllers: new Map()
|
|
23878
23973
|
};
|
|
23879
23974
|
this.subscriptionHandles.set(assignedHandle, sid);
|
|
23880
23975
|
(_b = (_a = previousDescriptorSubscription.completionFuture).resolve) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
@@ -23911,7 +24006,7 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23911
24006
|
return;
|
|
23912
24007
|
}
|
|
23913
24008
|
// Broadcast to all downstream subscribers
|
|
23914
|
-
for (const controller of descriptor.subscription.streamControllers) {
|
|
24009
|
+
for (const controller of descriptor.subscription.streamControllers.keys()) {
|
|
23915
24010
|
if (controller.desiredSize !== null && controller.desiredSize <= 0) {
|
|
23916
24011
|
log$1.warn("Cannot send frame to subscribers: readable stream is full (desiredSize is ".concat(controller.desiredSize, "). To increase this threshold, set a higher 'options.highWaterMark' when calling .subscribe()."));
|
|
23917
24012
|
continue;
|
|
@@ -23969,7 +24064,7 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
|
|
|
23969
24064
|
(_b = (_a = descriptor.subscription.completionFuture).reject) === null || _b === void 0 ? void 0 : _b.call(_a, DataTrackSubscribeError.disconnected());
|
|
23970
24065
|
}
|
|
23971
24066
|
if (descriptor.subscription.type === 'active') {
|
|
23972
|
-
descriptor.subscription.streamControllers
|
|
24067
|
+
this.closeStreamControllers(descriptor.subscription.streamControllers, descriptor.info.sid);
|
|
23973
24068
|
}
|
|
23974
24069
|
}
|
|
23975
24070
|
this.descriptors.clear();
|
|
@@ -27718,14 +27813,14 @@ class DeferrableMap extends Map {
|
|
|
27718
27813
|
this.pending = new Map();
|
|
27719
27814
|
}
|
|
27720
27815
|
set(key, value) {
|
|
27721
|
-
var _a;
|
|
27816
|
+
var _a, _b;
|
|
27722
27817
|
super.set(key, value);
|
|
27723
27818
|
// Resolve any futures waiting on this key.
|
|
27724
|
-
const futures = this.pending.get(key);
|
|
27819
|
+
const futures = (_a = this.pending) === null || _a === void 0 ? void 0 : _a.get(key);
|
|
27725
27820
|
if (futures) {
|
|
27726
27821
|
for (const future of futures) {
|
|
27727
27822
|
if (!future.isResolved) {
|
|
27728
|
-
(
|
|
27823
|
+
(_b = future.resolve) === null || _b === void 0 ? void 0 : _b.call(future, value);
|
|
27729
27824
|
}
|
|
27730
27825
|
}
|
|
27731
27826
|
this.pending.delete(key);
|
|
@@ -27733,7 +27828,7 @@ class DeferrableMap extends Map {
|
|
|
27733
27828
|
return this;
|
|
27734
27829
|
}
|
|
27735
27830
|
get [Symbol.toStringTag]() {
|
|
27736
|
-
return '
|
|
27831
|
+
return 'DeferrableMap';
|
|
27737
27832
|
}
|
|
27738
27833
|
getDeferred(key, signal) {
|
|
27739
27834
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -28056,8 +28151,13 @@ class DeferrableMap extends Map {
|
|
|
28056
28151
|
}
|
|
28057
28152
|
}class RemoteParticipant extends Participant {
|
|
28058
28153
|
/** @internal */
|
|
28059
|
-
static fromParticipantInfo(signalClient, pi, loggerOptions) {
|
|
28060
|
-
return new RemoteParticipant(signalClient, pi.sid, pi.identity, pi.name, pi.metadata, pi.attributes, loggerOptions, pi.kind
|
|
28154
|
+
static fromParticipantInfo(signalClient, pi, loggerOptions, manager) {
|
|
28155
|
+
return new RemoteParticipant(signalClient, pi.sid, pi.identity, pi.name, pi.metadata, pi.attributes, loggerOptions, pi.kind, pi.dataTracks.map(dti => {
|
|
28156
|
+
const info = DataTrackInfo.from(dti);
|
|
28157
|
+
return new RemoteDataTrack(info, manager, {
|
|
28158
|
+
publisherIdentity: pi.identity
|
|
28159
|
+
});
|
|
28160
|
+
}));
|
|
28061
28161
|
}
|
|
28062
28162
|
get logContext() {
|
|
28063
28163
|
return Object.assign(Object.assign({}, super.logContext), {
|
|
@@ -28068,12 +28168,15 @@ class DeferrableMap extends Map {
|
|
|
28068
28168
|
/** @internal */
|
|
28069
28169
|
constructor(signalClient, sid, identity, name, metadata, attributes, loggerOptions) {
|
|
28070
28170
|
let kind = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : ParticipantInfo_Kind.STANDARD;
|
|
28171
|
+
let remoteDataTracks = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : [];
|
|
28071
28172
|
super(sid, identity || '', name, metadata, attributes, loggerOptions, kind);
|
|
28072
28173
|
this.signalClient = signalClient;
|
|
28073
28174
|
this.trackPublications = new Map();
|
|
28074
28175
|
this.audioTrackPublications = new Map();
|
|
28075
28176
|
this.videoTrackPublications = new Map();
|
|
28076
|
-
this.dataTracks = new DeferrableMap(
|
|
28177
|
+
this.dataTracks = new DeferrableMap(remoteDataTracks.map(remoteDataTrack => {
|
|
28178
|
+
return [remoteDataTrack.info.name, remoteDataTrack];
|
|
28179
|
+
}));
|
|
28077
28180
|
this.volumeMap = new Map();
|
|
28078
28181
|
}
|
|
28079
28182
|
addTrackPublication(publication) {
|
|
@@ -29367,18 +29470,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
29367
29470
|
}).on(EngineEvent.DCBufferStatusChanged, (status, kind) => {
|
|
29368
29471
|
this.emit(RoomEvent.DCBufferStatusChanged, status, kind);
|
|
29369
29472
|
}).on(EngineEvent.LocalTrackSubscribed, subscribedSid => {
|
|
29370
|
-
|
|
29371
|
-
let {
|
|
29372
|
-
trackSid
|
|
29373
|
-
} = _ref2;
|
|
29374
|
-
return trackSid === subscribedSid;
|
|
29375
|
-
});
|
|
29376
|
-
if (!trackPublication) {
|
|
29377
|
-
this.log.warn('could not find local track subscription for subscribed event', this.logContext);
|
|
29378
|
-
return;
|
|
29379
|
-
}
|
|
29380
|
-
this.localParticipant.emit(ParticipantEvent.LocalTrackSubscribed, trackPublication);
|
|
29381
|
-
this.emitWhenConnected(RoomEvent.LocalTrackSubscribed, trackPublication, this.localParticipant);
|
|
29473
|
+
this.handleLocalTrackSubscribed(subscribedSid);
|
|
29382
29474
|
}).on(EngineEvent.RoomMoved, roomMoved => {
|
|
29383
29475
|
this.log.debug('room moved', roomMoved);
|
|
29384
29476
|
if (roomMoved.room) {
|
|
@@ -29414,8 +29506,8 @@ class Room extends eventsExports.EventEmitter {
|
|
|
29414
29506
|
}
|
|
29415
29507
|
this.outgoingDataTrackManager.receivedSfuUnpublishResponse(event.info.pubHandle);
|
|
29416
29508
|
}).on(EngineEvent.DataTrackSubscriberHandles, event => {
|
|
29417
|
-
const handleToSidMapping = new Map(Object.entries(event.subHandles).map(
|
|
29418
|
-
let [key, value] =
|
|
29509
|
+
const handleToSidMapping = new Map(Object.entries(event.subHandles).map(_ref2 => {
|
|
29510
|
+
let [key, value] = _ref2;
|
|
29419
29511
|
return [parseInt(key, 10), value.trackSid];
|
|
29420
29512
|
}));
|
|
29421
29513
|
this.incomingDataTrackManager.receivedSfuSubscriberHandles(handleToSidMapping);
|
|
@@ -29521,6 +29613,9 @@ class Room extends eventsExports.EventEmitter {
|
|
|
29521
29613
|
// @ts-expect-error function is private
|
|
29522
29614
|
yield this.engine.client.handleOnClose('simulate disconnect');
|
|
29523
29615
|
break;
|
|
29616
|
+
case 'fail-on-v1-path':
|
|
29617
|
+
this.engine.failNextV1Path();
|
|
29618
|
+
break;
|
|
29524
29619
|
case 'speaker':
|
|
29525
29620
|
req = new SimulateScenario({
|
|
29526
29621
|
scenario: {
|
|
@@ -29844,6 +29939,56 @@ class Room extends eventsExports.EventEmitter {
|
|
|
29844
29939
|
this.emit(RoomEvent.EncryptionError, new Error("Encrypted ".concat(publication.source, " track received from participant ").concat(participant.sid, ", but room does not have encryption enabled!")));
|
|
29845
29940
|
}
|
|
29846
29941
|
}
|
|
29942
|
+
handleLocalTrackSubscribed(subscribedSid) {
|
|
29943
|
+
const findPublication = () => this.localParticipant.getTrackPublications().find(_ref3 => {
|
|
29944
|
+
let {
|
|
29945
|
+
trackSid
|
|
29946
|
+
} = _ref3;
|
|
29947
|
+
return trackSid === subscribedSid;
|
|
29948
|
+
});
|
|
29949
|
+
const trackPublication = findPublication();
|
|
29950
|
+
if (trackPublication) {
|
|
29951
|
+
this.emitLocalTrackSubscribed(trackPublication);
|
|
29952
|
+
return;
|
|
29953
|
+
}
|
|
29954
|
+
// the track publication may not be registered yet if the server signals
|
|
29955
|
+
// the subscription before publishTrack has finished adding the publication.
|
|
29956
|
+
// defer with a timeout until LocalTrackPublished fires for the matching trackSid
|
|
29957
|
+
this.log.debug('deferring LocalTrackSubscribed, publication not yet available', Object.assign(Object.assign({}, this.logContext), {
|
|
29958
|
+
subscribedSid
|
|
29959
|
+
}));
|
|
29960
|
+
const TIMEOUT_MS = 10000;
|
|
29961
|
+
let timer;
|
|
29962
|
+
const onPublished = pub => {
|
|
29963
|
+
if (pub.trackSid === subscribedSid) {
|
|
29964
|
+
cleanup();
|
|
29965
|
+
this.emitLocalTrackSubscribed(pub);
|
|
29966
|
+
}
|
|
29967
|
+
};
|
|
29968
|
+
const cleanup = () => {
|
|
29969
|
+
clearTimeout(timer);
|
|
29970
|
+
this.localParticipant.off(ParticipantEvent.LocalTrackPublished, onPublished);
|
|
29971
|
+
this.off(RoomEvent.Disconnected, cleanup);
|
|
29972
|
+
};
|
|
29973
|
+
this.localParticipant.on(ParticipantEvent.LocalTrackPublished, onPublished);
|
|
29974
|
+
this.once(RoomEvent.Disconnected, cleanup);
|
|
29975
|
+
timer = setTimeout(() => {
|
|
29976
|
+
cleanup();
|
|
29977
|
+
// final attempt in case the publication was added without emitting the event
|
|
29978
|
+
const pub = findPublication();
|
|
29979
|
+
if (pub) {
|
|
29980
|
+
this.emitLocalTrackSubscribed(pub);
|
|
29981
|
+
} else {
|
|
29982
|
+
this.log.warn('could not find local track publication for LocalTrackSubscribed event after timeout', Object.assign(Object.assign({}, this.logContext), {
|
|
29983
|
+
subscribedSid
|
|
29984
|
+
}));
|
|
29985
|
+
}
|
|
29986
|
+
}, TIMEOUT_MS);
|
|
29987
|
+
}
|
|
29988
|
+
emitLocalTrackSubscribed(trackPublication) {
|
|
29989
|
+
this.localParticipant.emit(ParticipantEvent.LocalTrackSubscribed, trackPublication);
|
|
29990
|
+
this.emitWhenConnected(RoomEvent.LocalTrackSubscribed, trackPublication, this.localParticipant);
|
|
29991
|
+
}
|
|
29847
29992
|
handleDisconnect() {
|
|
29848
29993
|
let shouldStopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
29849
29994
|
let reason = arguments.length > 1 ? arguments[1] : undefined;
|
|
@@ -30048,7 +30193,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
30048
30193
|
participant = RemoteParticipant.fromParticipantInfo(this.engine.client, info, {
|
|
30049
30194
|
loggerContextCb: () => this.logContext,
|
|
30050
30195
|
loggerName: this.options.loggerName
|
|
30051
|
-
});
|
|
30196
|
+
}, this.incomingDataTrackManager);
|
|
30052
30197
|
} else {
|
|
30053
30198
|
participant = new RemoteParticipant(this.engine.client, '', identity, undefined, undefined, undefined, {
|
|
30054
30199
|
loggerContextCb: () => this.logContext,
|