@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.es.js CHANGED
@@ -3298,7 +3298,7 @@ const retryable = async (rpc, signal) => {
3298
3298
  return result;
3299
3299
  };
3300
3300
 
3301
- const version = "1.11.12";
3301
+ const version = "1.11.13";
3302
3302
  const [major, minor, patch] = version.split('.');
3303
3303
  let sdkInfo = {
3304
3304
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -6433,6 +6433,151 @@ const promiseWithResolvers = () => {
6433
6433
  };
6434
6434
  };
6435
6435
 
6436
+ const uninitialized = Symbol('uninitialized');
6437
+ /**
6438
+ * Lazily creates a value using a provided factory
6439
+ */
6440
+ function lazy(factory) {
6441
+ let value = uninitialized;
6442
+ return () => {
6443
+ if (value === uninitialized) {
6444
+ value = factory();
6445
+ }
6446
+ return value;
6447
+ };
6448
+ }
6449
+
6450
+ const timerWorker = {
6451
+ src: `var timerIdMapping = new Map();
6452
+ self.addEventListener('message', function (event) {
6453
+ var request = event.data;
6454
+ switch (request.type) {
6455
+ case 'setTimeout':
6456
+ case 'setInterval':
6457
+ timerIdMapping.set(request.id, (request.type === 'setTimeout' ? setTimeout : setInterval)(function () {
6458
+ tick(request.id);
6459
+ if (request.type === 'setTimeout') {
6460
+ timerIdMapping.delete(request.id);
6461
+ }
6462
+ }, request.timeout));
6463
+ break;
6464
+ case 'clearTimeout':
6465
+ case 'clearInterval':
6466
+ (request.type === 'clearTimeout' ? clearTimeout : clearInterval)(timerIdMapping.get(request.id));
6467
+ timerIdMapping.delete(request.id);
6468
+ break;
6469
+ }
6470
+ });
6471
+ function tick(id) {
6472
+ var message = { type: 'tick', id: id };
6473
+ self.postMessage(message);
6474
+ }`,
6475
+ };
6476
+
6477
+ class TimerWorker {
6478
+ constructor() {
6479
+ this.currentTimerId = 1;
6480
+ this.callbacks = new Map();
6481
+ this.fallback = false;
6482
+ }
6483
+ setup({ useTimerWorker = true } = {}) {
6484
+ if (!useTimerWorker) {
6485
+ this.fallback = true;
6486
+ return;
6487
+ }
6488
+ try {
6489
+ const source = timerWorker.src;
6490
+ const blob = new Blob([source], {
6491
+ type: 'application/javascript; charset=utf-8',
6492
+ });
6493
+ const script = URL.createObjectURL(blob);
6494
+ this.worker = new Worker(script, { name: 'str-timer-worker' });
6495
+ this.worker.addEventListener('message', (event) => {
6496
+ const { type, id } = event.data;
6497
+ if (type === 'tick') {
6498
+ this.callbacks.get(id)?.();
6499
+ }
6500
+ });
6501
+ }
6502
+ catch (err) {
6503
+ getLogger(['timer-worker'])('error', err);
6504
+ this.fallback = true;
6505
+ }
6506
+ }
6507
+ destroy() {
6508
+ this.callbacks.clear();
6509
+ this.worker?.terminate();
6510
+ this.worker = undefined;
6511
+ this.fallback = false;
6512
+ }
6513
+ get ready() {
6514
+ return this.fallback || Boolean(this.worker);
6515
+ }
6516
+ setInterval(callback, timeout) {
6517
+ return this.setTimer('setInterval', callback, timeout);
6518
+ }
6519
+ clearInterval(id) {
6520
+ this.clearTimer('clearInterval', id);
6521
+ }
6522
+ setTimeout(callback, timeout) {
6523
+ return this.setTimer('setTimeout', callback, timeout);
6524
+ }
6525
+ clearTimeout(id) {
6526
+ this.clearTimer('clearTimeout', id);
6527
+ }
6528
+ setTimer(type, callback, timeout) {
6529
+ if (!this.ready) {
6530
+ this.setup();
6531
+ }
6532
+ if (this.fallback) {
6533
+ return (type === 'setTimeout' ? setTimeout : setInterval)(callback, timeout);
6534
+ }
6535
+ const id = this.getTimerId();
6536
+ this.callbacks.set(id, () => {
6537
+ callback();
6538
+ // Timeouts are one-off operations, so no need to keep callback reference
6539
+ // after timer has fired
6540
+ if (type === 'setTimeout') {
6541
+ this.callbacks.delete(id);
6542
+ }
6543
+ });
6544
+ this.sendMessage({ type, id, timeout });
6545
+ return id;
6546
+ }
6547
+ clearTimer(type, id) {
6548
+ if (!id) {
6549
+ return;
6550
+ }
6551
+ if (!this.ready) {
6552
+ this.setup();
6553
+ }
6554
+ if (this.fallback) {
6555
+ (type === 'clearTimeout' ? clearTimeout : clearInterval)(id);
6556
+ return;
6557
+ }
6558
+ this.callbacks.delete(id);
6559
+ this.sendMessage({ type, id });
6560
+ }
6561
+ getTimerId() {
6562
+ return this.currentTimerId++;
6563
+ }
6564
+ sendMessage(message) {
6565
+ if (!this.worker) {
6566
+ throw new Error("Cannot use timer worker before it's set up");
6567
+ }
6568
+ this.worker.postMessage(message);
6569
+ }
6570
+ }
6571
+ let timerWorkerEnabled = false;
6572
+ const enableTimerWorker = () => {
6573
+ timerWorkerEnabled = true;
6574
+ };
6575
+ const getTimers = lazy(() => {
6576
+ const instance = new TimerWorker();
6577
+ instance.setup({ useTimerWorker: timerWorkerEnabled });
6578
+ return instance;
6579
+ });
6580
+
6436
6581
  /**
6437
6582
  * The client used for exchanging information with the SFU.
6438
6583
  */
@@ -6491,7 +6636,7 @@ class StreamSfuClient {
6491
6636
  };
6492
6637
  this.handleWebSocketClose = () => {
6493
6638
  this.signalWs.removeEventListener('close', this.handleWebSocketClose);
6494
- clearInterval(this.keepAliveInterval);
6639
+ getTimers().clearInterval(this.keepAliveInterval);
6495
6640
  clearTimeout(this.connectionCheckTimeout);
6496
6641
  this.onSignalClose?.();
6497
6642
  };
@@ -6647,8 +6792,9 @@ class StreamSfuClient {
6647
6792
  this.signalWs.send(SfuRequest.toBinary(message));
6648
6793
  };
6649
6794
  this.keepAlive = () => {
6650
- clearInterval(this.keepAliveInterval);
6651
- this.keepAliveInterval = setInterval(() => {
6795
+ const timers = getTimers();
6796
+ timers.clearInterval(this.keepAliveInterval);
6797
+ this.keepAliveInterval = timers.setInterval(() => {
6652
6798
  this.ping().catch((e) => {
6653
6799
  this.logger('error', 'Error sending healthCheckRequest to SFU', e);
6654
6800
  });
@@ -8229,20 +8375,6 @@ function canQueryPermissions() {
8229
8375
  !!navigator.permissions?.query);
8230
8376
  }
8231
8377
 
8232
- const uninitialized = Symbol('uninitialized');
8233
- /**
8234
- * Lazily creates a value using a provided factory
8235
- */
8236
- function lazy(factory) {
8237
- let value = uninitialized;
8238
- return () => {
8239
- if (value === uninitialized) {
8240
- value = factory();
8241
- }
8242
- return value;
8243
- };
8244
- }
8245
-
8246
8378
  /**
8247
8379
  * Returns an Observable that emits the list of available devices
8248
8380
  * that meet the given constraints.
@@ -11789,9 +11921,12 @@ class StableWSConnection {
11789
11921
  * Schedules a next health check ping for websocket.
11790
11922
  */
11791
11923
  this.scheduleNextPing = () => {
11924
+ const timers = getTimers();
11925
+ if (this.healthCheckTimeoutRef) {
11926
+ timers.clearTimeout(this.healthCheckTimeoutRef);
11927
+ }
11792
11928
  // 30 seconds is the recommended interval (messenger uses this)
11793
- clearTimeout(this.healthCheckTimeoutRef);
11794
- this.healthCheckTimeoutRef = setTimeout(() => {
11929
+ this.healthCheckTimeoutRef = timers.setTimeout(() => {
11795
11930
  // send the healthcheck..., server replies with a health check event
11796
11931
  const data = [{ type: 'health.check', client_id: this.client.clientID }];
11797
11932
  // try to send on the connection
@@ -11934,8 +12069,12 @@ class StableWSConnection {
11934
12069
  this.isConnecting = false;
11935
12070
  this.isDisconnected = true;
11936
12071
  // start by removing all the listeners
11937
- clearInterval(this.healthCheckTimeoutRef);
11938
- clearInterval(this.connectionCheckTimeoutRef);
12072
+ if (this.healthCheckTimeoutRef) {
12073
+ getTimers().clearInterval(this.healthCheckTimeoutRef);
12074
+ }
12075
+ if (this.connectionCheckTimeoutRef) {
12076
+ clearInterval(this.connectionCheckTimeoutRef);
12077
+ }
11939
12078
  removeConnectionEventListeners(this.onlineStatusChanged);
11940
12079
  this.isHealthy = false;
11941
12080
  let isClosedPromise;
@@ -12635,7 +12774,7 @@ class StreamClient {
12635
12774
  return await this.wsConnection.connect(this.defaultWSTimeout);
12636
12775
  };
12637
12776
  this.getUserAgent = () => {
12638
- const version = "1.11.12";
12777
+ const version = "1.11.13";
12639
12778
  return (this.userAgent ||
12640
12779
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
12641
12780
  };
@@ -13046,10 +13185,14 @@ class StreamVideoClient {
13046
13185
  if (typeof apiKeyOrArgs === 'string') {
13047
13186
  logLevel = opts?.logLevel || logLevel;
13048
13187
  logger = opts?.logger || logger;
13188
+ if (opts?.expertimental_enableTimerWorker)
13189
+ enableTimerWorker();
13049
13190
  }
13050
13191
  else {
13051
13192
  logLevel = apiKeyOrArgs.options?.logLevel || logLevel;
13052
13193
  logger = apiKeyOrArgs.options?.logger || logger;
13194
+ if (apiKeyOrArgs.options?.expertimental_enableTimerWorker)
13195
+ enableTimerWorker();
13053
13196
  }
13054
13197
  setLogger(logger, logLevel);
13055
13198
  this.logger = getLogger(['client']);