@stream-io/video-client 1.9.3 → 1.10.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/dist/index.cjs.js CHANGED
@@ -862,6 +862,76 @@ var WebsocketReconnectStrategy;
862
862
  */
863
863
  WebsocketReconnectStrategy[WebsocketReconnectStrategy["MIGRATE"] = 4] = "MIGRATE";
864
864
  })(WebsocketReconnectStrategy || (WebsocketReconnectStrategy = {}));
865
+ /**
866
+ * AndroidThermalState is reported by the Android API. The full list of values is documented here
867
+ * https://developer.android.com/reference/android/os/PowerManager.html#getCurrentThermalStatus()
868
+ *
869
+ * @generated from protobuf enum stream.video.sfu.models.AndroidThermalState
870
+ */
871
+ var AndroidThermalState;
872
+ (function (AndroidThermalState) {
873
+ /**
874
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_UNSPECIFIED = 0;
875
+ */
876
+ AndroidThermalState[AndroidThermalState["UNSPECIFIED"] = 0] = "UNSPECIFIED";
877
+ /**
878
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_NONE = 1;
879
+ */
880
+ AndroidThermalState[AndroidThermalState["NONE"] = 1] = "NONE";
881
+ /**
882
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_LIGHT = 2;
883
+ */
884
+ AndroidThermalState[AndroidThermalState["LIGHT"] = 2] = "LIGHT";
885
+ /**
886
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_MODERATE = 3;
887
+ */
888
+ AndroidThermalState[AndroidThermalState["MODERATE"] = 3] = "MODERATE";
889
+ /**
890
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_SEVERE = 4;
891
+ */
892
+ AndroidThermalState[AndroidThermalState["SEVERE"] = 4] = "SEVERE";
893
+ /**
894
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_CRITICAL = 5;
895
+ */
896
+ AndroidThermalState[AndroidThermalState["CRITICAL"] = 5] = "CRITICAL";
897
+ /**
898
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_EMERGENCY = 6;
899
+ */
900
+ AndroidThermalState[AndroidThermalState["EMERGENCY"] = 6] = "EMERGENCY";
901
+ /**
902
+ * @generated from protobuf enum value: ANDROID_THERMAL_STATE_SHUTDOWN = 7;
903
+ */
904
+ AndroidThermalState[AndroidThermalState["SHUTDOWN"] = 7] = "SHUTDOWN";
905
+ })(AndroidThermalState || (AndroidThermalState = {}));
906
+ /**
907
+ * AppleThermalState is the thermal state as reported by Apple devices when available or applicable to the platform.
908
+ * The full list of states (enum) is available here: https://developer.apple.com/documentation/foundation/processinfo/thermalstate
909
+ *
910
+ * @generated from protobuf enum stream.video.sfu.models.AppleThermalState
911
+ */
912
+ var AppleThermalState;
913
+ (function (AppleThermalState) {
914
+ /**
915
+ * @generated from protobuf enum value: APPLE_THERMAL_STATE_UNSPECIFIED = 0;
916
+ */
917
+ AppleThermalState[AppleThermalState["UNSPECIFIED"] = 0] = "UNSPECIFIED";
918
+ /**
919
+ * @generated from protobuf enum value: APPLE_THERMAL_STATE_NOMINAL = 1;
920
+ */
921
+ AppleThermalState[AppleThermalState["NOMINAL"] = 1] = "NOMINAL";
922
+ /**
923
+ * @generated from protobuf enum value: APPLE_THERMAL_STATE_FAIR = 2;
924
+ */
925
+ AppleThermalState[AppleThermalState["FAIR"] = 2] = "FAIR";
926
+ /**
927
+ * @generated from protobuf enum value: APPLE_THERMAL_STATE_SERIOUS = 3;
928
+ */
929
+ AppleThermalState[AppleThermalState["SERIOUS"] = 3] = "SERIOUS";
930
+ /**
931
+ * @generated from protobuf enum value: APPLE_THERMAL_STATE_CRITICAL = 4;
932
+ */
933
+ AppleThermalState[AppleThermalState["CRITICAL"] = 4] = "CRITICAL";
934
+ })(AppleThermalState || (AppleThermalState = {}));
865
935
  // @generated message type with reflection information, may provide speed optimized methods
866
936
  class CallState$Type extends runtime.MessageType {
867
937
  constructor() {
@@ -1300,9 +1370,92 @@ class CallGrants$Type extends runtime.MessageType {
1300
1370
  * @generated MessageType for protobuf message stream.video.sfu.models.CallGrants
1301
1371
  */
1302
1372
  const CallGrants = new CallGrants$Type();
1373
+ // @generated message type with reflection information, may provide speed optimized methods
1374
+ class InputDevices$Type extends runtime.MessageType {
1375
+ constructor() {
1376
+ super('stream.video.sfu.models.InputDevices', [
1377
+ {
1378
+ no: 1,
1379
+ name: 'available_devices',
1380
+ kind: 'scalar',
1381
+ repeat: 2 /*RepeatType.UNPACKED*/,
1382
+ T: 9 /*ScalarType.STRING*/,
1383
+ },
1384
+ {
1385
+ no: 2,
1386
+ name: 'current_device',
1387
+ kind: 'scalar',
1388
+ T: 9 /*ScalarType.STRING*/,
1389
+ },
1390
+ { no: 3, name: 'is_permitted', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
1391
+ ]);
1392
+ }
1393
+ }
1394
+ /**
1395
+ * @generated MessageType for protobuf message stream.video.sfu.models.InputDevices
1396
+ */
1397
+ const InputDevices = new InputDevices$Type();
1398
+ // @generated message type with reflection information, may provide speed optimized methods
1399
+ class AndroidState$Type extends runtime.MessageType {
1400
+ constructor() {
1401
+ super('stream.video.sfu.models.AndroidState', [
1402
+ {
1403
+ no: 1,
1404
+ name: 'thermal_state',
1405
+ kind: 'enum',
1406
+ T: () => [
1407
+ 'stream.video.sfu.models.AndroidThermalState',
1408
+ AndroidThermalState,
1409
+ 'ANDROID_THERMAL_STATE_',
1410
+ ],
1411
+ },
1412
+ {
1413
+ no: 2,
1414
+ name: 'is_power_saver_mode',
1415
+ kind: 'scalar',
1416
+ T: 8 /*ScalarType.BOOL*/,
1417
+ },
1418
+ ]);
1419
+ }
1420
+ }
1421
+ /**
1422
+ * @generated MessageType for protobuf message stream.video.sfu.models.AndroidState
1423
+ */
1424
+ const AndroidState = new AndroidState$Type();
1425
+ // @generated message type with reflection information, may provide speed optimized methods
1426
+ class AppleState$Type extends runtime.MessageType {
1427
+ constructor() {
1428
+ super('stream.video.sfu.models.AppleState', [
1429
+ {
1430
+ no: 1,
1431
+ name: 'thermal_state',
1432
+ kind: 'enum',
1433
+ T: () => [
1434
+ 'stream.video.sfu.models.AppleThermalState',
1435
+ AppleThermalState,
1436
+ 'APPLE_THERMAL_STATE_',
1437
+ ],
1438
+ },
1439
+ {
1440
+ no: 2,
1441
+ name: 'is_low_power_mode_enabled',
1442
+ kind: 'scalar',
1443
+ T: 8 /*ScalarType.BOOL*/,
1444
+ },
1445
+ ]);
1446
+ }
1447
+ }
1448
+ /**
1449
+ * @generated MessageType for protobuf message stream.video.sfu.models.AppleState
1450
+ */
1451
+ const AppleState = new AppleState$Type();
1303
1452
 
1304
1453
  var models = /*#__PURE__*/Object.freeze({
1305
1454
  __proto__: null,
1455
+ AndroidState: AndroidState,
1456
+ get AndroidThermalState () { return AndroidThermalState; },
1457
+ AppleState: AppleState,
1458
+ get AppleThermalState () { return AppleThermalState; },
1306
1459
  Browser: Browser,
1307
1460
  Call: Call$1,
1308
1461
  get CallEndedReason () { return CallEndedReason; },
@@ -1316,6 +1469,7 @@ var models = /*#__PURE__*/Object.freeze({
1316
1469
  get ErrorCode () { return ErrorCode; },
1317
1470
  get GoAwayReason () { return GoAwayReason; },
1318
1471
  ICETrickle: ICETrickle$1,
1472
+ InputDevices: InputDevices,
1319
1473
  OS: OS,
1320
1474
  Participant: Participant,
1321
1475
  ParticipantCount: ParticipantCount,
@@ -1415,6 +1569,22 @@ class SendStatsRequest$Type extends runtime.MessageType {
1415
1569
  kind: 'scalar',
1416
1570
  T: 9 /*ScalarType.STRING*/,
1417
1571
  },
1572
+ { no: 7, name: 'audio_devices', kind: 'message', T: () => InputDevices },
1573
+ { no: 8, name: 'video_devices', kind: 'message', T: () => InputDevices },
1574
+ {
1575
+ no: 9,
1576
+ name: 'android',
1577
+ kind: 'message',
1578
+ oneof: 'deviceState',
1579
+ T: () => AndroidState,
1580
+ },
1581
+ {
1582
+ no: 10,
1583
+ name: 'apple',
1584
+ kind: 'message',
1585
+ oneof: 'deviceState',
1586
+ T: () => AppleState,
1587
+ },
1418
1588
  ]);
1419
1589
  }
1420
1590
  }
@@ -2959,7 +3129,7 @@ const retryable = async (rpc, signal) => {
2959
3129
  return result;
2960
3130
  };
2961
3131
 
2962
- const version = "1.9.3";
3132
+ const version = "1.10.0";
2963
3133
  const [major, minor, patch] = version.split('.');
2964
3134
  let sdkInfo = {
2965
3135
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -3689,9 +3859,10 @@ const setCurrentValue = (subject, update) => {
3689
3859
  *
3690
3860
  * @param observable the observable to subscribe to.
3691
3861
  * @param handler the handler to call when the observable emits a value.
3862
+ * @param onError an optional error handler.
3692
3863
  */
3693
- const createSubscription = (observable, handler) => {
3694
- const subscription = observable.subscribe(handler);
3864
+ const createSubscription = (observable, handler, onError = (error) => getLogger(['RxUtils'])('warn', 'An observable emitted an error', error)) => {
3865
+ const subscription = observable.subscribe({ next: handler, error: onError });
3695
3866
  return () => {
3696
3867
  subscription.unsubscribe();
3697
3868
  };
@@ -3706,12 +3877,9 @@ const createSubscription = (observable, handler) => {
3706
3877
  */
3707
3878
  const createSafeAsyncSubscription = (observable, handler) => {
3708
3879
  const tag = Symbol();
3709
- const subscription = observable.subscribe((value) => {
3880
+ return createSubscription(observable, (value) => {
3710
3881
  withoutConcurrency(tag, () => handler(value));
3711
3882
  });
3712
- return () => {
3713
- subscription.unsubscribe();
3714
- };
3715
3883
  };
3716
3884
 
3717
3885
  var rxUtils = /*#__PURE__*/Object.freeze({
@@ -6981,8 +7149,38 @@ const aggregate = (stats) => {
6981
7149
  };
6982
7150
 
6983
7151
  class SfuStatsReporter {
6984
- constructor(sfuClient, { options, clientDetails, subscriber, publisher }) {
7152
+ constructor(sfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, }) {
6985
7153
  this.logger = getLogger(['SfuStatsReporter']);
7154
+ this.inputDevices = new Map();
7155
+ this.observeDevice = (device, kind) => {
7156
+ const { hasBrowserPermission$ } = device.state;
7157
+ this.unsubscribeDevicePermissionsSubscription?.();
7158
+ this.unsubscribeDevicePermissionsSubscription = createSubscription(rxjs.combineLatest([hasBrowserPermission$, this.state.ownCapabilities$]), ([hasPermission, ownCapabilities]) => {
7159
+ // cleanup the previous listDevices() subscription in case
7160
+ // permissions or capabilities have changed.
7161
+ // we will subscribe again if everything is in order.
7162
+ this.unsubscribeListDevicesSubscription?.();
7163
+ const hasCapability = kind === 'mic'
7164
+ ? ownCapabilities.includes(OwnCapability.SEND_AUDIO)
7165
+ : ownCapabilities.includes(OwnCapability.SEND_VIDEO);
7166
+ if (!hasPermission || !hasCapability) {
7167
+ this.inputDevices.set(kind, {
7168
+ currentDevice: '',
7169
+ availableDevices: [],
7170
+ isPermitted: false,
7171
+ });
7172
+ return;
7173
+ }
7174
+ this.unsubscribeListDevicesSubscription = createSubscription(rxjs.combineLatest([device.listDevices(), device.state.selectedDevice$]), ([devices, deviceId]) => {
7175
+ const selected = devices.find((d) => d.deviceId === deviceId);
7176
+ this.inputDevices.set(kind, {
7177
+ currentDevice: selected?.label || deviceId || '',
7178
+ availableDevices: devices.map((d) => d.label),
7179
+ isPermitted: true,
7180
+ });
7181
+ });
7182
+ });
7183
+ };
6986
7184
  this.run = async () => {
6987
7185
  const [subscriberStats, publisherStats] = await Promise.all([
6988
7186
  this.subscriber.getStats().then(flatten).then(JSON.stringify),
@@ -6994,11 +7192,16 @@ class SfuStatsReporter {
6994
7192
  webrtcVersion: this.webRTCVersion,
6995
7193
  subscriberStats,
6996
7194
  publisherStats,
7195
+ audioDevices: this.inputDevices.get('mic'),
7196
+ videoDevices: this.inputDevices.get('camera'),
7197
+ deviceState: { oneofKind: undefined },
6997
7198
  });
6998
7199
  };
6999
7200
  this.start = () => {
7000
7201
  if (this.options.reporting_interval_ms <= 0)
7001
7202
  return;
7203
+ this.observeDevice(this.microphone, 'mic');
7204
+ this.observeDevice(this.camera, 'camera');
7002
7205
  clearInterval(this.intervalId);
7003
7206
  this.intervalId = setInterval(() => {
7004
7207
  this.run().catch((err) => {
@@ -7007,6 +7210,11 @@ class SfuStatsReporter {
7007
7210
  }, this.options.reporting_interval_ms);
7008
7211
  };
7009
7212
  this.stop = () => {
7213
+ this.unsubscribeDevicePermissionsSubscription?.();
7214
+ this.unsubscribeDevicePermissionsSubscription = undefined;
7215
+ this.unsubscribeListDevicesSubscription?.();
7216
+ this.unsubscribeListDevicesSubscription = undefined;
7217
+ this.inputDevices.clear();
7010
7218
  clearInterval(this.intervalId);
7011
7219
  this.intervalId = undefined;
7012
7220
  };
@@ -7014,11 +7222,15 @@ class SfuStatsReporter {
7014
7222
  this.options = options;
7015
7223
  this.subscriber = subscriber;
7016
7224
  this.publisher = publisher;
7017
- const webRTCInfo = getWebRTCInfo();
7225
+ this.microphone = microphone;
7226
+ this.camera = camera;
7227
+ this.state = state;
7018
7228
  const { sdk, browser } = clientDetails;
7019
7229
  this.sdkName = getSdkName(sdk);
7020
7230
  this.sdkVersion = getSdkVersion(sdk);
7021
- // The WebRTC version if passed from the SDK, it is taken else the browser info is sent.
7231
+ // use the WebRTC version if set by the SDK (React Native) otherwise,
7232
+ // use the browser version as a fallback
7233
+ const webRTCInfo = getWebRTCInfo();
7022
7234
  this.webRTCVersion =
7023
7235
  webRTCInfo?.version ||
7024
7236
  `${browser?.name || ''}-${browser?.version || ''}` ||
@@ -9803,6 +10015,9 @@ class Call {
9803
10015
  options: statsOptions,
9804
10016
  subscriber: this.subscriber,
9805
10017
  publisher: this.publisher,
10018
+ microphone: this.microphone,
10019
+ camera: this.camera,
10020
+ state: this.state,
9806
10021
  });
9807
10022
  this.sfuStatsReporter.start();
9808
10023
  }
@@ -12112,7 +12327,7 @@ class StreamClient {
12112
12327
  }
12113
12328
  if ((this._isUsingServerAuth() || this.node) &&
12114
12329
  !this.options.allowServerSideConnect) {
12115
- this.logger('warn', 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add "allowServerSideConnect: true" to the client options to disable this warning.');
12330
+ this.logger('warn', 'Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/');
12116
12331
  }
12117
12332
  // we generate the client id client side
12118
12333
  this.userID = user.id;
@@ -12488,7 +12703,7 @@ class StreamClient {
12488
12703
  });
12489
12704
  };
12490
12705
  this.getUserAgent = () => {
12491
- const version = "1.9.3";
12706
+ const version = "1.10.0";
12492
12707
  return (this.userAgent ||
12493
12708
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
12494
12709
  };