@stream-io/video-client 1.37.0 → 1.37.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/CHANGELOG.md +12 -0
- package/dist/index.browser.es.js +44 -7
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +44 -7
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +44 -7
- package/dist/index.es.js.map +1 -1
- package/dist/src/store/CallState.d.ts +9 -0
- package/package.json +1 -1
- package/src/helpers/DynascaleManager.ts +9 -3
- package/src/store/CallState.ts +37 -2
package/dist/index.cjs.js
CHANGED
|
@@ -4887,6 +4887,26 @@ const defaultEgress = {
|
|
|
4887
4887
|
hls: { playlist_url: '', status: '' },
|
|
4888
4888
|
rtmps: [],
|
|
4889
4889
|
};
|
|
4890
|
+
/**
|
|
4891
|
+
* Creates a stable participant filter function, ready to be used in combination
|
|
4892
|
+
* with the `useSyncExternalStore` hook.
|
|
4893
|
+
*
|
|
4894
|
+
* @param predicate the predicate to use.
|
|
4895
|
+
*/
|
|
4896
|
+
const createStableParticipantsFilter = (predicate) => {
|
|
4897
|
+
const empty = [];
|
|
4898
|
+
return (participants) => {
|
|
4899
|
+
// no need to filter if there are no participants
|
|
4900
|
+
if (!participants.length)
|
|
4901
|
+
return participants;
|
|
4902
|
+
// return a stable empty array if there are no remote participants
|
|
4903
|
+
// instead of creating an empty one
|
|
4904
|
+
const filteredParticipants = participants.filter(predicate);
|
|
4905
|
+
if (!filteredParticipants.length)
|
|
4906
|
+
return empty;
|
|
4907
|
+
return filteredParticipants;
|
|
4908
|
+
};
|
|
4909
|
+
};
|
|
4890
4910
|
/**
|
|
4891
4911
|
* Holds the state of the current call.
|
|
4892
4912
|
* @react You don't have to use this class directly, as we are exposing the state through Hooks.
|
|
@@ -5010,6 +5030,17 @@ class CallState {
|
|
|
5010
5030
|
this.setAnonymousParticipantCount = (count) => {
|
|
5011
5031
|
return this.setCurrentValue(this.anonymousParticipantCountSubject, count);
|
|
5012
5032
|
};
|
|
5033
|
+
/**
|
|
5034
|
+
* Returns the current participants array directly from the BehaviorSubject.
|
|
5035
|
+
* This bypasses the observable pipeline and is guaranteed to be synchronous.
|
|
5036
|
+
* Use this when you need the absolute latest value without any potential
|
|
5037
|
+
* timing issues from shareReplay/refCount.
|
|
5038
|
+
*
|
|
5039
|
+
* @internal
|
|
5040
|
+
*/
|
|
5041
|
+
this.getParticipantsSnapshot = () => {
|
|
5042
|
+
return this.participantsSubject.getValue();
|
|
5043
|
+
};
|
|
5013
5044
|
/**
|
|
5014
5045
|
* Sets the list of participants in the current call.
|
|
5015
5046
|
*
|
|
@@ -5555,8 +5586,8 @@ class CallState {
|
|
|
5555
5586
|
// in the original subject
|
|
5556
5587
|
rxjs.map((ps) => ps.sort(this.sortParticipantsBy)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5557
5588
|
this.localParticipant$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5558
|
-
this.remoteParticipants$ = this.participants$.pipe(rxjs.map((
|
|
5559
|
-
this.pinnedParticipants$ = this.participants$.pipe(rxjs.map((
|
|
5589
|
+
this.remoteParticipants$ = this.participants$.pipe(rxjs.map(createStableParticipantsFilter((p) => !p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5590
|
+
this.pinnedParticipants$ = this.participants$.pipe(rxjs.map(createStableParticipantsFilter((p) => !!p.pin)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5560
5591
|
this.dominantSpeaker$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isDominantSpeaker)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5561
5592
|
this.hasOngoingScreenShare$ = this.participants$.pipe(rxjs.map((participants) => participants.some((p) => hasScreenShare(p))), rxjs.distinctUntilChanged(), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
5562
5593
|
// dates
|
|
@@ -5989,7 +6020,7 @@ const getSdkVersion = (sdk) => {
|
|
|
5989
6020
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
5990
6021
|
};
|
|
5991
6022
|
|
|
5992
|
-
const version = "1.37.
|
|
6023
|
+
const version = "1.37.2";
|
|
5993
6024
|
const [major, minor, patch] = version.split('.');
|
|
5994
6025
|
let sdkInfo = {
|
|
5995
6026
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -9466,13 +9497,19 @@ class DynascaleManager {
|
|
|
9466
9497
|
}
|
|
9467
9498
|
get trackSubscriptions() {
|
|
9468
9499
|
const subscriptions = [];
|
|
9469
|
-
|
|
9500
|
+
// Use getParticipantsSnapshot() to bypass the observable pipeline
|
|
9501
|
+
// and avoid stale data caused by shareReplay with no active subscribers
|
|
9502
|
+
const participants = this.callState.getParticipantsSnapshot();
|
|
9503
|
+
const videoTrackSubscriptionOverrides = this.videoTrackSubscriptionOverridesSubject.getValue();
|
|
9504
|
+
for (const p of participants) {
|
|
9505
|
+
if (p.isLocalParticipant)
|
|
9506
|
+
continue;
|
|
9470
9507
|
// NOTE: audio tracks don't have to be requested explicitly
|
|
9471
9508
|
// as the SFU will implicitly subscribe us to all of them,
|
|
9472
9509
|
// once they become available.
|
|
9473
9510
|
if (p.videoDimension && hasVideo(p)) {
|
|
9474
|
-
const override =
|
|
9475
|
-
|
|
9511
|
+
const override = videoTrackSubscriptionOverrides[p.sessionId] ??
|
|
9512
|
+
videoTrackSubscriptionOverrides[globalOverrideKey];
|
|
9476
9513
|
if (override?.enabled !== false) {
|
|
9477
9514
|
subscriptions.push({
|
|
9478
9515
|
userId: p.userId,
|
|
@@ -14891,7 +14928,7 @@ class StreamClient {
|
|
|
14891
14928
|
this.getUserAgent = () => {
|
|
14892
14929
|
if (!this.cachedUserAgent) {
|
|
14893
14930
|
const { clientAppIdentifier = {} } = this.options;
|
|
14894
|
-
const { sdkName = 'js', sdkVersion = "1.37.
|
|
14931
|
+
const { sdkName = 'js', sdkVersion = "1.37.2", ...extras } = clientAppIdentifier;
|
|
14895
14932
|
this.cachedUserAgent = [
|
|
14896
14933
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
14897
14934
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|