@stream-io/video-client 1.11.12 → 1.11.13

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
@@ -3318,7 +3318,7 @@ const retryable = async (rpc, signal) => {
3318
3318
  return result;
3319
3319
  };
3320
3320
 
3321
- const version = "1.11.12";
3321
+ const version = "1.11.13";
3322
3322
  const [major, minor, patch] = version.split('.');
3323
3323
  let sdkInfo = {
3324
3324
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -6453,6 +6453,151 @@ const promiseWithResolvers = () => {
6453
6453
  };
6454
6454
  };
6455
6455
 
6456
+ const uninitialized = Symbol('uninitialized');
6457
+ /**
6458
+ * Lazily creates a value using a provided factory
6459
+ */
6460
+ function lazy(factory) {
6461
+ let value = uninitialized;
6462
+ return () => {
6463
+ if (value === uninitialized) {
6464
+ value = factory();
6465
+ }
6466
+ return value;
6467
+ };
6468
+ }
6469
+
6470
+ const timerWorker = {
6471
+ src: `var timerIdMapping = new Map();
6472
+ self.addEventListener('message', function (event) {
6473
+ var request = event.data;
6474
+ switch (request.type) {
6475
+ case 'setTimeout':
6476
+ case 'setInterval':
6477
+ timerIdMapping.set(request.id, (request.type === 'setTimeout' ? setTimeout : setInterval)(function () {
6478
+ tick(request.id);
6479
+ if (request.type === 'setTimeout') {
6480
+ timerIdMapping.delete(request.id);
6481
+ }
6482
+ }, request.timeout));
6483
+ break;
6484
+ case 'clearTimeout':
6485
+ case 'clearInterval':
6486
+ (request.type === 'clearTimeout' ? clearTimeout : clearInterval)(timerIdMapping.get(request.id));
6487
+ timerIdMapping.delete(request.id);
6488
+ break;
6489
+ }
6490
+ });
6491
+ function tick(id) {
6492
+ var message = { type: 'tick', id: id };
6493
+ self.postMessage(message);
6494
+ }`,
6495
+ };
6496
+
6497
+ class TimerWorker {
6498
+ constructor() {
6499
+ this.currentTimerId = 1;
6500
+ this.callbacks = new Map();
6501
+ this.fallback = false;
6502
+ }
6503
+ setup({ useTimerWorker = true } = {}) {
6504
+ if (!useTimerWorker) {
6505
+ this.fallback = true;
6506
+ return;
6507
+ }
6508
+ try {
6509
+ const source = timerWorker.src;
6510
+ const blob = new Blob([source], {
6511
+ type: 'application/javascript; charset=utf-8',
6512
+ });
6513
+ const script = URL.createObjectURL(blob);
6514
+ this.worker = new Worker(script, { name: 'str-timer-worker' });
6515
+ this.worker.addEventListener('message', (event) => {
6516
+ const { type, id } = event.data;
6517
+ if (type === 'tick') {
6518
+ this.callbacks.get(id)?.();
6519
+ }
6520
+ });
6521
+ }
6522
+ catch (err) {
6523
+ getLogger(['timer-worker'])('error', err);
6524
+ this.fallback = true;
6525
+ }
6526
+ }
6527
+ destroy() {
6528
+ this.callbacks.clear();
6529
+ this.worker?.terminate();
6530
+ this.worker = undefined;
6531
+ this.fallback = false;
6532
+ }
6533
+ get ready() {
6534
+ return this.fallback || Boolean(this.worker);
6535
+ }
6536
+ setInterval(callback, timeout) {
6537
+ return this.setTimer('setInterval', callback, timeout);
6538
+ }
6539
+ clearInterval(id) {
6540
+ this.clearTimer('clearInterval', id);
6541
+ }
6542
+ setTimeout(callback, timeout) {
6543
+ return this.setTimer('setTimeout', callback, timeout);
6544
+ }
6545
+ clearTimeout(id) {
6546
+ this.clearTimer('clearTimeout', id);
6547
+ }
6548
+ setTimer(type, callback, timeout) {
6549
+ if (!this.ready) {
6550
+ this.setup();
6551
+ }
6552
+ if (this.fallback) {
6553
+ return (type === 'setTimeout' ? setTimeout : setInterval)(callback, timeout);
6554
+ }
6555
+ const id = this.getTimerId();
6556
+ this.callbacks.set(id, () => {
6557
+ callback();
6558
+ // Timeouts are one-off operations, so no need to keep callback reference
6559
+ // after timer has fired
6560
+ if (type === 'setTimeout') {
6561
+ this.callbacks.delete(id);
6562
+ }
6563
+ });
6564
+ this.sendMessage({ type, id, timeout });
6565
+ return id;
6566
+ }
6567
+ clearTimer(type, id) {
6568
+ if (!id) {
6569
+ return;
6570
+ }
6571
+ if (!this.ready) {
6572
+ this.setup();
6573
+ }
6574
+ if (this.fallback) {
6575
+ (type === 'clearTimeout' ? clearTimeout : clearInterval)(id);
6576
+ return;
6577
+ }
6578
+ this.callbacks.delete(id);
6579
+ this.sendMessage({ type, id });
6580
+ }
6581
+ getTimerId() {
6582
+ return this.currentTimerId++;
6583
+ }
6584
+ sendMessage(message) {
6585
+ if (!this.worker) {
6586
+ throw new Error("Cannot use timer worker before it's set up");
6587
+ }
6588
+ this.worker.postMessage(message);
6589
+ }
6590
+ }
6591
+ let timerWorkerEnabled = false;
6592
+ const enableTimerWorker = () => {
6593
+ timerWorkerEnabled = true;
6594
+ };
6595
+ const getTimers = lazy(() => {
6596
+ const instance = new TimerWorker();
6597
+ instance.setup({ useTimerWorker: timerWorkerEnabled });
6598
+ return instance;
6599
+ });
6600
+
6456
6601
  /**
6457
6602
  * The client used for exchanging information with the SFU.
6458
6603
  */
@@ -6511,7 +6656,7 @@ class StreamSfuClient {
6511
6656
  };
6512
6657
  this.handleWebSocketClose = () => {
6513
6658
  this.signalWs.removeEventListener('close', this.handleWebSocketClose);
6514
- clearInterval(this.keepAliveInterval);
6659
+ getTimers().clearInterval(this.keepAliveInterval);
6515
6660
  clearTimeout(this.connectionCheckTimeout);
6516
6661
  this.onSignalClose?.();
6517
6662
  };
@@ -6667,8 +6812,9 @@ class StreamSfuClient {
6667
6812
  this.signalWs.send(SfuRequest.toBinary(message));
6668
6813
  };
6669
6814
  this.keepAlive = () => {
6670
- clearInterval(this.keepAliveInterval);
6671
- this.keepAliveInterval = setInterval(() => {
6815
+ const timers = getTimers();
6816
+ timers.clearInterval(this.keepAliveInterval);
6817
+ this.keepAliveInterval = timers.setInterval(() => {
6672
6818
  this.ping().catch((e) => {
6673
6819
  this.logger('error', 'Error sending healthCheckRequest to SFU', e);
6674
6820
  });
@@ -8249,20 +8395,6 @@ function canQueryPermissions() {
8249
8395
  !!navigator.permissions?.query);
8250
8396
  }
8251
8397
 
8252
- const uninitialized = Symbol('uninitialized');
8253
- /**
8254
- * Lazily creates a value using a provided factory
8255
- */
8256
- function lazy(factory) {
8257
- let value = uninitialized;
8258
- return () => {
8259
- if (value === uninitialized) {
8260
- value = factory();
8261
- }
8262
- return value;
8263
- };
8264
- }
8265
-
8266
8398
  /**
8267
8399
  * Returns an Observable that emits the list of available devices
8268
8400
  * that meet the given constraints.
@@ -11809,9 +11941,12 @@ class StableWSConnection {
11809
11941
  * Schedules a next health check ping for websocket.
11810
11942
  */
11811
11943
  this.scheduleNextPing = () => {
11944
+ const timers = getTimers();
11945
+ if (this.healthCheckTimeoutRef) {
11946
+ timers.clearTimeout(this.healthCheckTimeoutRef);
11947
+ }
11812
11948
  // 30 seconds is the recommended interval (messenger uses this)
11813
- clearTimeout(this.healthCheckTimeoutRef);
11814
- this.healthCheckTimeoutRef = setTimeout(() => {
11949
+ this.healthCheckTimeoutRef = timers.setTimeout(() => {
11815
11950
  // send the healthcheck..., server replies with a health check event
11816
11951
  const data = [{ type: 'health.check', client_id: this.client.clientID }];
11817
11952
  // try to send on the connection
@@ -11954,8 +12089,12 @@ class StableWSConnection {
11954
12089
  this.isConnecting = false;
11955
12090
  this.isDisconnected = true;
11956
12091
  // start by removing all the listeners
11957
- clearInterval(this.healthCheckTimeoutRef);
11958
- clearInterval(this.connectionCheckTimeoutRef);
12092
+ if (this.healthCheckTimeoutRef) {
12093
+ getTimers().clearInterval(this.healthCheckTimeoutRef);
12094
+ }
12095
+ if (this.connectionCheckTimeoutRef) {
12096
+ clearInterval(this.connectionCheckTimeoutRef);
12097
+ }
11959
12098
  removeConnectionEventListeners(this.onlineStatusChanged);
11960
12099
  this.isHealthy = false;
11961
12100
  let isClosedPromise;
@@ -12655,7 +12794,7 @@ class StreamClient {
12655
12794
  return await this.wsConnection.connect(this.defaultWSTimeout);
12656
12795
  };
12657
12796
  this.getUserAgent = () => {
12658
- const version = "1.11.12";
12797
+ const version = "1.11.13";
12659
12798
  return (this.userAgent ||
12660
12799
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
12661
12800
  };
@@ -13066,10 +13205,14 @@ class StreamVideoClient {
13066
13205
  if (typeof apiKeyOrArgs === 'string') {
13067
13206
  logLevel = opts?.logLevel || logLevel;
13068
13207
  logger = opts?.logger || logger;
13208
+ if (opts?.expertimental_enableTimerWorker)
13209
+ enableTimerWorker();
13069
13210
  }
13070
13211
  else {
13071
13212
  logLevel = apiKeyOrArgs.options?.logLevel || logLevel;
13072
13213
  logger = apiKeyOrArgs.options?.logger || logger;
13214
+ if (apiKeyOrArgs.options?.expertimental_enableTimerWorker)
13215
+ enableTimerWorker();
13073
13216
  }
13074
13217
  setLogger(logger, logLevel);
13075
13218
  this.logger = getLogger(['client']);