@stream-io/video-client 1.30.0 → 1.31.0

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 CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.31.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.30.1...@stream-io/video-client-1.31.0) (2025-09-17)
6
+
7
+ ### Features
8
+
9
+ - introduce @stream-io/worker-timers ([94c962b](https://github.com/GetStream/stream-video-js/commit/94c962b2c5f731c152771b7803a59664fa925477))
10
+
11
+ ### Bug Fixes
12
+
13
+ - **video-filters:** prevent background tab throttling ([#1920](https://github.com/GetStream/stream-video-js/issues/1920)) ([f93d5cc](https://github.com/GetStream/stream-video-js/commit/f93d5cc5785957c7f181fcaf689ec366df9e646b))
14
+
15
+ ## [1.30.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.30.0...@stream-io/video-client-1.30.1) (2025-09-16)
16
+
17
+ ### Bug Fixes
18
+
19
+ - don't apply default camera state if video is off ([#1917](https://github.com/GetStream/stream-video-js/issues/1917)) ([9cf1d75](https://github.com/GetStream/stream-video-js/commit/9cf1d752d824a0527fbb187df21d8a020590d4bb))
20
+ - **rn:** set direction state for flip after constraints are applied ([1f03c59](https://github.com/GetStream/stream-video-js/commit/1f03c59b9b3fecc0ff1f7cb6b0eccb083b4a3475))
21
+
5
22
  ## [1.30.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.29.0...@stream-io/video-client-1.30.0) (2025-09-11)
6
23
 
7
24
  - Skip tests for StreamVideoClient coordinator API ([aabe1d0](https://github.com/GetStream/stream-video-js/commit/aabe1d0ad3e3a95698b422991729e46289ab0277))
@@ -7,6 +7,7 @@ import { TwirpFetchTransport, TwirpErrorCode } from '@protobuf-ts/twirp-transpor
7
7
  import { ReplaySubject, combineLatest, BehaviorSubject, shareReplay, map, distinctUntilChanged, startWith, takeWhile, distinctUntilKeyChanged, fromEventPattern, concatMap, merge, from, fromEvent, tap, debounceTime, pairwise, of } from 'rxjs';
8
8
  import { UAParser } from 'ua-parser-js';
9
9
  import { parse, write } from 'sdp-transform';
10
+ import { WorkerTimer } from '@stream-io/worker-timer';
10
11
 
11
12
  /* tslint:disable */
12
13
  /**
@@ -5757,7 +5758,7 @@ const getSdkVersion = (sdk) => {
5757
5758
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
5758
5759
  };
5759
5760
 
5760
- const version = "1.30.0";
5761
+ const version = "1.31.0";
5761
5762
  const [major, minor, patch] = version.split('.');
5762
5763
  let sdkInfo = {
5763
5764
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -7894,137 +7895,12 @@ function lazy(factory) {
7894
7895
  };
7895
7896
  }
7896
7897
 
7897
- // Do not modify this file manually. Instead, edit worker.ts
7898
- // and the run ./generate-timer-worker.sh
7899
- const timerWorker = {
7900
- src: `const timerIdMapping = new Map();
7901
- self.addEventListener('message', (event) => {
7902
- const request = event.data;
7903
- switch (request.type) {
7904
- case 'setTimeout':
7905
- case 'setInterval':
7906
- timerIdMapping.set(request.id, (request.type === 'setTimeout' ? setTimeout : setInterval)(() => {
7907
- tick(request.id);
7908
- if (request.type === 'setTimeout') {
7909
- timerIdMapping.delete(request.id);
7910
- }
7911
- }, request.timeout));
7912
- break;
7913
- case 'clearTimeout':
7914
- case 'clearInterval':
7915
- (request.type === 'clearTimeout' ? clearTimeout : clearInterval)(timerIdMapping.get(request.id));
7916
- timerIdMapping.delete(request.id);
7917
- break;
7918
- }
7919
- });
7920
- function tick(id) {
7921
- const message = { type: 'tick', id };
7922
- self.postMessage(message);
7923
- }`,
7924
- };
7925
-
7926
- class TimerWorker {
7927
- constructor() {
7928
- this.currentTimerId = 1;
7929
- this.callbacks = new Map();
7930
- this.fallback = false;
7931
- }
7932
- setup({ useTimerWorker = true } = {}) {
7933
- if (!useTimerWorker) {
7934
- this.fallback = true;
7935
- return;
7936
- }
7937
- try {
7938
- const source = timerWorker.src;
7939
- const blob = new Blob([source], {
7940
- type: 'application/javascript; charset=utf-8',
7941
- });
7942
- const script = URL.createObjectURL(blob);
7943
- this.worker = new Worker(script, { name: 'str-timer-worker' });
7944
- this.worker.addEventListener('message', (event) => {
7945
- const { type, id } = event.data;
7946
- if (type === 'tick') {
7947
- this.callbacks.get(id)?.();
7948
- }
7949
- });
7950
- }
7951
- catch (err) {
7952
- getLogger(['timer-worker'])('error', err);
7953
- this.fallback = true;
7954
- }
7955
- }
7956
- destroy() {
7957
- this.callbacks.clear();
7958
- this.worker?.terminate();
7959
- this.worker = undefined;
7960
- this.fallback = false;
7961
- }
7962
- get ready() {
7963
- return this.fallback || Boolean(this.worker);
7964
- }
7965
- setInterval(callback, timeout) {
7966
- return this.setTimer('setInterval', callback, timeout);
7967
- }
7968
- clearInterval(id) {
7969
- this.clearTimer('clearInterval', id);
7970
- }
7971
- setTimeout(callback, timeout) {
7972
- return this.setTimer('setTimeout', callback, timeout);
7973
- }
7974
- clearTimeout(id) {
7975
- this.clearTimer('clearTimeout', id);
7976
- }
7977
- setTimer(type, callback, timeout) {
7978
- if (!this.ready) {
7979
- this.setup();
7980
- }
7981
- if (this.fallback) {
7982
- return (type === 'setTimeout' ? setTimeout : setInterval)(callback, timeout);
7983
- }
7984
- const id = this.getTimerId();
7985
- this.callbacks.set(id, () => {
7986
- callback();
7987
- // Timeouts are one-off operations, so no need to keep callback reference
7988
- // after timer has fired
7989
- if (type === 'setTimeout') {
7990
- this.callbacks.delete(id);
7991
- }
7992
- });
7993
- this.sendMessage({ type, id, timeout });
7994
- return id;
7995
- }
7996
- clearTimer(type, id) {
7997
- if (!id) {
7998
- return;
7999
- }
8000
- if (!this.ready) {
8001
- this.setup();
8002
- }
8003
- if (this.fallback) {
8004
- (type === 'clearTimeout' ? clearTimeout : clearInterval)(id);
8005
- return;
8006
- }
8007
- this.callbacks.delete(id);
8008
- this.sendMessage({ type, id });
8009
- }
8010
- getTimerId() {
8011
- return this.currentTimerId++;
8012
- }
8013
- sendMessage(message) {
8014
- if (!this.worker) {
8015
- throw new Error("Cannot use timer worker before it's set up");
8016
- }
8017
- this.worker.postMessage(message);
8018
- }
8019
- }
8020
7898
  let timerWorkerEnabled = false;
8021
7899
  const enableTimerWorker = () => {
8022
7900
  timerWorkerEnabled = true;
8023
7901
  };
8024
7902
  const getTimers = lazy(() => {
8025
- const instance = new TimerWorker();
8026
- instance.setup({ useTimerWorker: timerWorkerEnabled });
8027
- return instance;
7903
+ return new WorkerTimer({ useWorker: timerWorkerEnabled });
8028
7904
  });
8029
7905
 
8030
7906
  /**
@@ -10651,16 +10527,17 @@ class CameraManager extends InputMediaDeviceManager {
10651
10527
  this.logger('warn', 'Setting direction is not supported on this device');
10652
10528
  return;
10653
10529
  }
10654
- // providing both device id and direction doesn't work, so we deselect the device
10655
- this.state.setDirection(direction);
10656
- this.state.setDevice(undefined);
10657
10530
  if (isReactNative()) {
10658
10531
  const videoTrack = this.getTracks()[0];
10659
10532
  await videoTrack?.applyConstraints({
10660
10533
  facingMode: direction === 'front' ? 'user' : 'environment',
10661
10534
  });
10535
+ this.state.setDirection(direction);
10662
10536
  return;
10663
10537
  }
10538
+ // providing both device id and direction doesn't work, so we deselect the device
10539
+ this.state.setDirection(direction);
10540
+ this.state.setDevice(undefined);
10664
10541
  this.getTracks().forEach((track) => track.stop());
10665
10542
  try {
10666
10543
  await this.unmuteStream();
@@ -10725,7 +10602,7 @@ class CameraManager extends InputMediaDeviceManager {
10725
10602
  return;
10726
10603
  // Wait for any in progress camera operation
10727
10604
  await this.statusChangeSettled();
10728
- const { target_resolution, camera_facing, camera_default_on } = settings;
10605
+ const { target_resolution, camera_facing, camera_default_on, enabled } = settings;
10729
10606
  // normalize target resolution to landscape format.
10730
10607
  // on mobile devices, the device itself adjusts the resolution to portrait or landscape
10731
10608
  // depending on the orientation of the device. using portrait resolution
@@ -10745,7 +10622,9 @@ class CameraManager extends InputMediaDeviceManager {
10745
10622
  // The camera is already enabled (e.g. lobby screen). Publish the stream
10746
10623
  await this.publishStream(mediaStream);
10747
10624
  }
10748
- else if (this.state.status === undefined && camera_default_on) {
10625
+ else if (this.state.status === undefined &&
10626
+ camera_default_on &&
10627
+ enabled) {
10749
10628
  // Start camera if backend config specifies, and there is no local setting
10750
10629
  await this.enable();
10751
10630
  }
@@ -14661,7 +14540,7 @@ class StreamClient {
14661
14540
  this.getUserAgent = () => {
14662
14541
  if (!this.cachedUserAgent) {
14663
14542
  const { clientAppIdentifier = {} } = this.options;
14664
- const { sdkName = 'js', sdkVersion = "1.30.0", ...extras } = clientAppIdentifier;
14543
+ const { sdkName = 'js', sdkVersion = "1.31.0", ...extras } = clientAppIdentifier;
14665
14544
  this.cachedUserAgent = [
14666
14545
  `stream-video-${sdkName}-v${sdkVersion}`,
14667
14546
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),