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