@stream-io/video-client 1.0.1 → 1.0.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 +7 -0
- package/dist/index.browser.es.js +79 -47
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +79 -47
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +79 -47
- package/dist/index.es.js.map +1 -1
- package/dist/src/devices/InputMediaDeviceManager.d.ts +4 -5
- package/dist/src/devices/InputMediaDeviceManagerState.d.ts +14 -0
- package/package.json +1 -1
- package/src/Call.ts +2 -12
- package/src/devices/CameraManager.ts +2 -2
- package/src/devices/InputMediaDeviceManager.ts +58 -36
- package/src/devices/InputMediaDeviceManagerState.ts +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [1.0.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.1...@stream-io/video-client-1.0.2) (2024-05-13)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* optimistically toggle device status ([#1342](https://github.com/GetStream/stream-video-js/issues/1342)) ([2e4e470](https://github.com/GetStream/stream-video-js/commit/2e4e470347fce7c7499dd21a931e5dec74bf9618))
|
|
11
|
+
|
|
5
12
|
### [1.0.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.0...@stream-io/video-client-1.0.1) (2024-05-07)
|
|
6
13
|
|
|
7
14
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -10869,18 +10869,27 @@ class InputMediaDeviceManager {
|
|
|
10869
10869
|
* Starts stream.
|
|
10870
10870
|
*/
|
|
10871
10871
|
async enable() {
|
|
10872
|
-
if (this.state.
|
|
10872
|
+
if (this.state.optimisticStatus === 'enabled') {
|
|
10873
|
+
await this.statusChangePromise;
|
|
10873
10874
|
return;
|
|
10874
|
-
this.enablePromise = this.unmuteStream();
|
|
10875
|
-
try {
|
|
10876
|
-
await this.enablePromise;
|
|
10877
|
-
this.state.setStatus('enabled');
|
|
10878
|
-
this.enablePromise = undefined;
|
|
10879
|
-
}
|
|
10880
|
-
catch (error) {
|
|
10881
|
-
this.enablePromise = undefined;
|
|
10882
|
-
throw error;
|
|
10883
10875
|
}
|
|
10876
|
+
const signal = this.nextAbortableStatusChangeRequest('enabled');
|
|
10877
|
+
const doEnable = async () => {
|
|
10878
|
+
if (signal.aborted)
|
|
10879
|
+
return;
|
|
10880
|
+
try {
|
|
10881
|
+
await this.unmuteStream();
|
|
10882
|
+
this.state.setStatus('enabled');
|
|
10883
|
+
}
|
|
10884
|
+
finally {
|
|
10885
|
+
if (!signal.aborted)
|
|
10886
|
+
this.resetStatusChangeRequest();
|
|
10887
|
+
}
|
|
10888
|
+
};
|
|
10889
|
+
this.statusChangePromise = this.statusChangePromise
|
|
10890
|
+
? this.statusChangePromise.then(doEnable)
|
|
10891
|
+
: doEnable();
|
|
10892
|
+
await this.statusChangePromise;
|
|
10884
10893
|
}
|
|
10885
10894
|
/**
|
|
10886
10895
|
* Stops or pauses the stream based on state.disableMode
|
|
@@ -10888,19 +10897,28 @@ class InputMediaDeviceManager {
|
|
|
10888
10897
|
*/
|
|
10889
10898
|
async disable(forceStop = false) {
|
|
10890
10899
|
this.state.prevStatus = this.state.status;
|
|
10891
|
-
if (!forceStop && this.state.
|
|
10900
|
+
if (!forceStop && this.state.optimisticStatus === 'disabled') {
|
|
10901
|
+
await this.statusChangePromise;
|
|
10892
10902
|
return;
|
|
10893
|
-
const stopTracks = forceStop || this.state.disableMode === 'stop-tracks';
|
|
10894
|
-
this.disablePromise = this.muteStream(stopTracks);
|
|
10895
|
-
try {
|
|
10896
|
-
await this.disablePromise;
|
|
10897
|
-
this.state.setStatus('disabled');
|
|
10898
|
-
this.disablePromise = undefined;
|
|
10899
|
-
}
|
|
10900
|
-
catch (error) {
|
|
10901
|
-
this.disablePromise = undefined;
|
|
10902
|
-
throw error;
|
|
10903
10903
|
}
|
|
10904
|
+
const stopTracks = forceStop || this.state.disableMode === 'stop-tracks';
|
|
10905
|
+
const signal = this.nextAbortableStatusChangeRequest('disabled');
|
|
10906
|
+
const doDisable = async () => {
|
|
10907
|
+
if (signal.aborted)
|
|
10908
|
+
return;
|
|
10909
|
+
try {
|
|
10910
|
+
await this.muteStream(stopTracks);
|
|
10911
|
+
this.state.setStatus('disabled');
|
|
10912
|
+
}
|
|
10913
|
+
finally {
|
|
10914
|
+
if (!signal.aborted)
|
|
10915
|
+
this.resetStatusChangeRequest();
|
|
10916
|
+
}
|
|
10917
|
+
};
|
|
10918
|
+
this.statusChangePromise = this.statusChangePromise
|
|
10919
|
+
? this.statusChangePromise.then(doDisable)
|
|
10920
|
+
: doDisable();
|
|
10921
|
+
await this.statusChangePromise;
|
|
10904
10922
|
}
|
|
10905
10923
|
/**
|
|
10906
10924
|
* If status was previously enabled, it will re-enable the device.
|
|
@@ -10916,7 +10934,7 @@ class InputMediaDeviceManager {
|
|
|
10916
10934
|
* else it will disable it.
|
|
10917
10935
|
*/
|
|
10918
10936
|
async toggle() {
|
|
10919
|
-
if (this.state.
|
|
10937
|
+
if (this.state.optimisticStatus === 'enabled') {
|
|
10920
10938
|
return this.disable();
|
|
10921
10939
|
}
|
|
10922
10940
|
else {
|
|
@@ -11103,11 +11121,8 @@ class InputMediaDeviceManager {
|
|
|
11103
11121
|
this.state.setMediaStream(stream, await rootStream);
|
|
11104
11122
|
this.getTracks().forEach((track) => {
|
|
11105
11123
|
track.addEventListener('ended', async () => {
|
|
11106
|
-
if (this.
|
|
11107
|
-
await this.
|
|
11108
|
-
}
|
|
11109
|
-
if (this.disablePromise) {
|
|
11110
|
-
await this.disablePromise;
|
|
11124
|
+
if (this.statusChangePromise) {
|
|
11125
|
+
await this.statusChangePromise;
|
|
11111
11126
|
}
|
|
11112
11127
|
if (this.state.status === 'enabled') {
|
|
11113
11128
|
this.isTrackStoppedDueToTrackEnd = true;
|
|
@@ -11137,11 +11152,8 @@ class InputMediaDeviceManager {
|
|
|
11137
11152
|
if (!deviceId) {
|
|
11138
11153
|
return;
|
|
11139
11154
|
}
|
|
11140
|
-
if (this.
|
|
11141
|
-
await this.
|
|
11142
|
-
}
|
|
11143
|
-
if (this.disablePromise) {
|
|
11144
|
-
await this.disablePromise;
|
|
11155
|
+
if (this.statusChangePromise) {
|
|
11156
|
+
await this.statusChangePromise;
|
|
11145
11157
|
}
|
|
11146
11158
|
let isDeviceDisconnected = false;
|
|
11147
11159
|
let isDeviceReplaced = false;
|
|
@@ -11175,6 +11187,16 @@ class InputMediaDeviceManager {
|
|
|
11175
11187
|
findDeviceInList(devices, deviceId) {
|
|
11176
11188
|
return devices.find((d) => d.deviceId === deviceId && d.kind === this.mediaDeviceKind);
|
|
11177
11189
|
}
|
|
11190
|
+
nextAbortableStatusChangeRequest(status) {
|
|
11191
|
+
this.statusChangeAbortController?.abort();
|
|
11192
|
+
this.statusChangeAbortController = new AbortController();
|
|
11193
|
+
this.state.setPendingStatus(status);
|
|
11194
|
+
return this.statusChangeAbortController.signal;
|
|
11195
|
+
}
|
|
11196
|
+
resetStatusChangeRequest() {
|
|
11197
|
+
this.statusChangePromise = undefined;
|
|
11198
|
+
this.statusChangeAbortController = undefined;
|
|
11199
|
+
}
|
|
11178
11200
|
}
|
|
11179
11201
|
|
|
11180
11202
|
class InputMediaDeviceManagerState {
|
|
@@ -11189,6 +11211,7 @@ class InputMediaDeviceManagerState {
|
|
|
11189
11211
|
this.disableMode = disableMode;
|
|
11190
11212
|
this.permissionName = permissionName;
|
|
11191
11213
|
this.statusSubject = new BehaviorSubject(undefined);
|
|
11214
|
+
this.optimisticStatusSubject = new BehaviorSubject(undefined);
|
|
11192
11215
|
this.mediaStreamSubject = new BehaviorSubject(undefined);
|
|
11193
11216
|
this.selectedDeviceSubject = new BehaviorSubject(undefined);
|
|
11194
11217
|
this.defaultConstraintsSubject = new BehaviorSubject(undefined);
|
|
@@ -11207,6 +11230,12 @@ class InputMediaDeviceManagerState {
|
|
|
11207
11230
|
* An Observable that emits the device status
|
|
11208
11231
|
*/
|
|
11209
11232
|
this.status$ = this.statusSubject.asObservable().pipe(distinctUntilChanged());
|
|
11233
|
+
/**
|
|
11234
|
+
* An Observable the reflects the requested device status. Useful for optimistic UIs
|
|
11235
|
+
*/
|
|
11236
|
+
this.optimisticStatus$ = this.optimisticStatusSubject
|
|
11237
|
+
.asObservable()
|
|
11238
|
+
.pipe(distinctUntilChanged());
|
|
11210
11239
|
/**
|
|
11211
11240
|
* The default constraints for the device.
|
|
11212
11241
|
*/
|
|
@@ -11274,6 +11303,12 @@ class InputMediaDeviceManagerState {
|
|
|
11274
11303
|
get status() {
|
|
11275
11304
|
return this.getCurrentValue(this.status$);
|
|
11276
11305
|
}
|
|
11306
|
+
/**
|
|
11307
|
+
* The requested device status. Useful for optimistic UIs
|
|
11308
|
+
*/
|
|
11309
|
+
get optimisticStatus() {
|
|
11310
|
+
return this.getCurrentValue(this.optimisticStatus$);
|
|
11311
|
+
}
|
|
11277
11312
|
/**
|
|
11278
11313
|
* The currently selected device
|
|
11279
11314
|
*/
|
|
@@ -11293,6 +11328,13 @@ class InputMediaDeviceManagerState {
|
|
|
11293
11328
|
setStatus(status) {
|
|
11294
11329
|
this.setCurrentValue(this.statusSubject, status);
|
|
11295
11330
|
}
|
|
11331
|
+
/**
|
|
11332
|
+
* @internal
|
|
11333
|
+
* @param pendingStatus
|
|
11334
|
+
*/
|
|
11335
|
+
setPendingStatus(pendingStatus) {
|
|
11336
|
+
this.setCurrentValue(this.optimisticStatusSubject, pendingStatus);
|
|
11337
|
+
}
|
|
11296
11338
|
/**
|
|
11297
11339
|
* Updates the `mediaStream` state variable.
|
|
11298
11340
|
*
|
|
@@ -11412,9 +11454,9 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
11412
11454
|
async selectTargetResolution(resolution) {
|
|
11413
11455
|
this.targetResolution.height = resolution.height;
|
|
11414
11456
|
this.targetResolution.width = resolution.width;
|
|
11415
|
-
if (this.
|
|
11457
|
+
if (this.statusChangePromise && this.state.optimisticStatus === 'enabled') {
|
|
11416
11458
|
try {
|
|
11417
|
-
await this.
|
|
11459
|
+
await this.statusChangePromise;
|
|
11418
11460
|
}
|
|
11419
11461
|
catch (error) {
|
|
11420
11462
|
// couldn't enable device, target resolution will be applied the next time user attempts to start the device
|
|
@@ -13555,12 +13597,7 @@ class Call {
|
|
|
13555
13597
|
}
|
|
13556
13598
|
async initCamera(options) {
|
|
13557
13599
|
// Wait for any in progress camera operation
|
|
13558
|
-
|
|
13559
|
-
await this.camera.enablePromise;
|
|
13560
|
-
}
|
|
13561
|
-
if (this.camera.disablePromise) {
|
|
13562
|
-
await this.camera.disablePromise;
|
|
13563
|
-
}
|
|
13600
|
+
await this.camera.statusChangePromise;
|
|
13564
13601
|
if (this.state.localParticipant?.videoStream ||
|
|
13565
13602
|
!this.permissionsContext.hasPermission('send-video')) {
|
|
13566
13603
|
return;
|
|
@@ -13597,12 +13634,7 @@ class Call {
|
|
|
13597
13634
|
}
|
|
13598
13635
|
async initMic(options) {
|
|
13599
13636
|
// Wait for any in progress mic operation
|
|
13600
|
-
|
|
13601
|
-
await this.microphone.enablePromise;
|
|
13602
|
-
}
|
|
13603
|
-
if (this.microphone.disablePromise) {
|
|
13604
|
-
await this.microphone.disablePromise;
|
|
13605
|
-
}
|
|
13637
|
+
await this.microphone.statusChangePromise;
|
|
13606
13638
|
if (this.state.localParticipant?.audioStream ||
|
|
13607
13639
|
!this.permissionsContext.hasPermission('send-audio')) {
|
|
13608
13640
|
return;
|
|
@@ -15145,7 +15177,7 @@ class StreamClient {
|
|
|
15145
15177
|
});
|
|
15146
15178
|
};
|
|
15147
15179
|
this.getUserAgent = () => {
|
|
15148
|
-
const version = "1.0.
|
|
15180
|
+
const version = "1.0.2" ;
|
|
15149
15181
|
return (this.userAgent ||
|
|
15150
15182
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
15151
15183
|
};
|