livekit-client 1.9.3 → 1.9.4
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -0
- package/dist/livekit-client.esm.mjs +4981 -5091
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/AsyncQueue.d.ts +23 -0
- package/dist/src/AsyncQueue.d.ts.map +1 -0
- package/dist/src/api/SignalClient.d.ts +2 -2
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +1 -2
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/timers.d.ts +4 -5
- package/dist/src/room/timers.d.ts.map +1 -1
- package/dist/ts4.2/src/AsyncQueue.d.ts +23 -0
- package/dist/ts4.2/src/api/SignalClient.d.ts +2 -2
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -2
- package/dist/ts4.2/src/room/timers.d.ts +4 -5
- package/package.json +7 -20
- package/src/AsyncQueue.test.ts +99 -0
- package/src/AsyncQueue.ts +57 -0
- package/src/api/SignalClient.ts +4 -4
- package/src/connectionHelper/ConnectionCheck.ts +1 -1
- package/src/room/PCTransport.ts +1 -1
@@ -0,0 +1,23 @@
|
|
1
|
+
type QueueTask<T> = () => PromiseLike<T>;
|
2
|
+
declare enum QueueTaskStatus {
|
3
|
+
'WAITING' = 0,
|
4
|
+
'RUNNING' = 1,
|
5
|
+
'COMPLETED' = 2
|
6
|
+
}
|
7
|
+
type QueueTaskInfo = {
|
8
|
+
id: number;
|
9
|
+
enqueuedAt: number;
|
10
|
+
executedAt?: number;
|
11
|
+
status: QueueTaskStatus;
|
12
|
+
};
|
13
|
+
export declare class AsyncQueue {
|
14
|
+
private pendingTasks;
|
15
|
+
private taskMutex;
|
16
|
+
private nextTaskIndex;
|
17
|
+
constructor();
|
18
|
+
run<T>(task: QueueTask<T>): Promise<T>;
|
19
|
+
flush(): Promise<void>;
|
20
|
+
snapshot(): QueueTaskInfo[];
|
21
|
+
}
|
22
|
+
export {};
|
23
|
+
//# sourceMappingURL=AsyncQueue.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"AsyncQueue.d.ts","sourceRoot":"","sources":["../../src/AsyncQueue.ts"],"names":[],"mappings":"AAEA,KAAK,SAAS,CAAC,CAAC,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC;AAEzC,aAAK,eAAe;IAClB,SAAS,IAAA;IACT,SAAS,IAAA;IACT,WAAW,IAAA;CACZ;AAED,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,qBAAa,UAAU;IACrB,OAAO,CAAC,YAAY,CAA6B;IAEjD,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,aAAa,CAAS;;IAQxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAmBzB,KAAK;IAIX,QAAQ;CAGT"}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import Queue from 'async-await-queue';
|
2
1
|
import 'webrtc-adapter';
|
2
|
+
import { AsyncQueue } from '../AsyncQueue';
|
3
3
|
import { ParticipantInfo, ReconnectReason, Room, SpeakerInfo, VideoLayer } from '../proto/livekit_models';
|
4
4
|
import { AddTrackRequest, ConnectionQualityUpdate, JoinResponse, LeaveRequest, ReconnectResponse, SessionDescription, SignalRequest, SignalTarget, SimulateScenario, StreamStateUpdate, SubscribedQualityUpdate, SubscriptionPermissionUpdate, SyncState, TrackPermission, TrackPublishedResponse, TrackUnpublishedResponse, UpdateSubscription, UpdateTrackSettings } from '../proto/livekit_rtc';
|
5
5
|
interface ConnectOpts {
|
@@ -26,7 +26,7 @@ type SignalMessage = SignalRequest['message'];
|
|
26
26
|
export declare class SignalClient {
|
27
27
|
isConnected: boolean;
|
28
28
|
isReconnecting: boolean;
|
29
|
-
requestQueue:
|
29
|
+
requestQueue: AsyncQueue;
|
30
30
|
queuedRequests: Array<() => Promise<void>>;
|
31
31
|
useJSON: boolean;
|
32
32
|
/** signal rtt in milliseconds */
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"SignalClient.d.ts","sourceRoot":"","sources":["../../../src/api/SignalClient.ts"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"SignalClient.d.ts","sourceRoot":"","sources":["../../../src/api/SignalClient.ts"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"PCTransport.d.ts","sourceRoot":"","sources":["../../../src/room/PCTransport.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"PCTransport.d.ts","sourceRoot":"","sources":["../../../src/room/PCTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAQtC,gBAAgB;AAChB,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,QAAQ;;;CAGX,CAAC;AAEX,gBAAgB;AAChB,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,YAAY;IACnD,EAAE,EAAE,iBAAiB,CAAC;IAEtB,iBAAiB,EAAE,mBAAmB,EAAE,CAAM;IAE9C,aAAa,EAAE,OAAO,CAAS;IAE/B,WAAW,EAAE,OAAO,CAAS;IAE7B,aAAa,EAAE,gBAAgB,EAAE,CAAM;IAEvC,gBAAgB,EAAE,MAAM,EAAE,CAAM;IAEhC,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;gBAEzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAQrF,IAAI,cAAc,IAAI,OAAO,CAE5B;IAEK,eAAe,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D,oBAAoB,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBxE,SAAS;iDAA2B,KAAK,KAAK,IAAI;;MAW1C;IAEF,kBAAkB,CAAC,OAAO,CAAC,EAAE,eAAe;IAwF5C,kBAAkB,IAAI,OAAO,CAAC,yBAAyB,CAAC;IAY9D,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAQ9D,KAAK;YAMS,yBAAyB;CA4BxC"}
|
@@ -1,13 +1,12 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
/**
|
3
2
|
* Timers that can be overridden with platform specific implementations
|
4
3
|
* that ensure that they are fired. These should be used when it is critical
|
5
4
|
* that the timer fires on time.
|
6
5
|
*/
|
7
6
|
export default class CriticalTimers {
|
8
|
-
static setTimeout: (
|
9
|
-
static setInterval: (
|
10
|
-
static clearTimeout: (
|
11
|
-
static clearInterval: (
|
7
|
+
static setTimeout: (handler: TimerHandler, timeout?: number | undefined, ...arguments: any[]) => number;
|
8
|
+
static setInterval: (handler: TimerHandler, timeout?: number | undefined, ...arguments: any[]) => number;
|
9
|
+
static clearTimeout: (id: number | undefined) => void;
|
10
|
+
static clearInterval: (id: number | undefined) => void;
|
12
11
|
}
|
13
12
|
//# sourceMappingURL=timers.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/room/timers.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/room/timers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IAEjC,MAAM,CAAC,UAAU,uFAAmE;IAGpF,MAAM,CAAC,WAAW,uFAAqE;IAEvF,MAAM,CAAC,YAAY,mCAAuE;IAE1F,MAAM,CAAC,aAAa,mCAAyE;CAC9F"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
type QueueTask<T> = () => PromiseLike<T>;
|
2
|
+
declare enum QueueTaskStatus {
|
3
|
+
'WAITING' = 0,
|
4
|
+
'RUNNING' = 1,
|
5
|
+
'COMPLETED' = 2
|
6
|
+
}
|
7
|
+
type QueueTaskInfo = {
|
8
|
+
id: number;
|
9
|
+
enqueuedAt: number;
|
10
|
+
executedAt?: number;
|
11
|
+
status: QueueTaskStatus;
|
12
|
+
};
|
13
|
+
export declare class AsyncQueue {
|
14
|
+
private pendingTasks;
|
15
|
+
private taskMutex;
|
16
|
+
private nextTaskIndex;
|
17
|
+
constructor();
|
18
|
+
run<T>(task: QueueTask<T>): Promise<T>;
|
19
|
+
flush(): Promise<void>;
|
20
|
+
snapshot(): QueueTaskInfo[];
|
21
|
+
}
|
22
|
+
export {};
|
23
|
+
//# sourceMappingURL=AsyncQueue.d.ts.map
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import Queue from 'async-await-queue';
|
2
1
|
import 'webrtc-adapter';
|
2
|
+
import { AsyncQueue } from '../AsyncQueue';
|
3
3
|
import { ParticipantInfo, ReconnectReason, Room, SpeakerInfo, VideoLayer } from '../proto/livekit_models';
|
4
4
|
import { AddTrackRequest, ConnectionQualityUpdate, JoinResponse, LeaveRequest, ReconnectResponse, SessionDescription, SignalRequest, SignalTarget, SimulateScenario, StreamStateUpdate, SubscribedQualityUpdate, SubscriptionPermissionUpdate, SyncState, TrackPermission, TrackPublishedResponse, TrackUnpublishedResponse, UpdateSubscription, UpdateTrackSettings } from '../proto/livekit_rtc';
|
5
5
|
interface ConnectOpts {
|
@@ -26,7 +26,7 @@ type SignalMessage = SignalRequest['message'];
|
|
26
26
|
export declare class SignalClient {
|
27
27
|
isConnected: boolean;
|
28
28
|
isReconnecting: boolean;
|
29
|
-
requestQueue:
|
29
|
+
requestQueue: AsyncQueue;
|
30
30
|
queuedRequests: Array<() => Promise<void>>;
|
31
31
|
useJSON: boolean;
|
32
32
|
/** signal rtt in milliseconds */
|
@@ -1,13 +1,12 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
/**
|
3
2
|
* Timers that can be overridden with platform specific implementations
|
4
3
|
* that ensure that they are fired. These should be used when it is critical
|
5
4
|
* that the timer fires on time.
|
6
5
|
*/
|
7
6
|
export default class CriticalTimers {
|
8
|
-
static setTimeout: (
|
9
|
-
static setInterval: (
|
10
|
-
static clearTimeout: (
|
11
|
-
static clearInterval: (
|
7
|
+
static setTimeout: (handler: TimerHandler, timeout?: number | undefined, ...arguments: any[]) => number;
|
8
|
+
static setInterval: (handler: TimerHandler, timeout?: number | undefined, ...arguments: any[]) => number;
|
9
|
+
static clearTimeout: (id: number | undefined) => void;
|
10
|
+
static clearInterval: (id: number | undefined) => void;
|
12
11
|
}
|
13
12
|
//# sourceMappingURL=timers.d.ts.map
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "livekit-client",
|
3
|
-
"version": "1.9.
|
3
|
+
"version": "1.9.4",
|
4
4
|
"description": "JavaScript/TypeScript client SDK for LiveKit",
|
5
5
|
"main": "./dist/livekit-client.umd.js",
|
6
6
|
"unpkg": "./dist/livekit-client.umd.js",
|
@@ -36,11 +36,11 @@
|
|
36
36
|
"deploy": "gh-pages -d example/dist",
|
37
37
|
"format": "prettier --write src example/sample.ts",
|
38
38
|
"format:check": "prettier --check src",
|
39
|
-
"release": "yarn build && changeset publish",
|
40
|
-
"downlevel-dts": "downlevel-dts ./dist/ ./dist/ts4.2 --to=4.2"
|
39
|
+
"release": "yarn build && yarn compat && changeset publish",
|
40
|
+
"downlevel-dts": "downlevel-dts ./dist/ ./dist/ts4.2 --to=4.2",
|
41
|
+
"compat": "eslint --no-eslintrc --config ./.eslintrc.dist.cjs ./dist/livekit-client.umd.js"
|
41
42
|
},
|
42
43
|
"dependencies": {
|
43
|
-
"async-await-queue": "^1.2.1",
|
44
44
|
"events": "^3.3.0",
|
45
45
|
"loglevel": "^1.8.0",
|
46
46
|
"protobufjs": "^7.0.0",
|
@@ -61,16 +61,17 @@
|
|
61
61
|
"@rollup/plugin-node-resolve": "15.0.2",
|
62
62
|
"@rollup/plugin-terser": "^0.4.0",
|
63
63
|
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
64
|
+
"@types/events": "^3.0.0",
|
64
65
|
"@types/jest": "29.5.1",
|
65
66
|
"@types/sdp-transform": "2.4.6",
|
66
67
|
"@types/ua-parser-js": "0.7.36",
|
67
|
-
"@types/ws": "8.5.4",
|
68
68
|
"@typescript-eslint/eslint-plugin": "5.59.2",
|
69
69
|
"@typescript-eslint/parser": "5.59.2",
|
70
70
|
"downlevel-dts": "^0.11.0",
|
71
71
|
"eslint": "8.39.0",
|
72
72
|
"eslint-config-airbnb-typescript": "17.0.0",
|
73
73
|
"eslint-config-prettier": "8.8.0",
|
74
|
+
"eslint-plugin-ecmascript-compat": "^3.0.0",
|
74
75
|
"eslint-plugin-import": "2.27.5",
|
75
76
|
"gh-pages": "5.0.0",
|
76
77
|
"jest": "29.5.0",
|
@@ -86,19 +87,5 @@
|
|
86
87
|
"typedoc-plugin-no-inherit": "1.4.0",
|
87
88
|
"typescript": "5.0.4",
|
88
89
|
"vite": "4.3.4"
|
89
|
-
}
|
90
|
-
"browserslist": [
|
91
|
-
"safari >= 11",
|
92
|
-
"ios_saf >= 11",
|
93
|
-
"chrome >= 64",
|
94
|
-
"and_chr >= 64",
|
95
|
-
"android >= 64",
|
96
|
-
"firefox >= 53",
|
97
|
-
"and_ff >= 53",
|
98
|
-
"edge >= 79",
|
99
|
-
"Opera >= 52",
|
100
|
-
"Samsung >= 9.2",
|
101
|
-
"not IE 11",
|
102
|
-
"not dead"
|
103
|
-
]
|
90
|
+
}
|
104
91
|
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import { AsyncQueue } from './AsyncQueue';
|
2
|
+
import { sleep } from './room/utils';
|
3
|
+
|
4
|
+
describe('asyncQueue', () => {
|
5
|
+
it('runs multiple tasks in order', async () => {
|
6
|
+
const queue = new AsyncQueue();
|
7
|
+
const tasksExecuted: number[] = [];
|
8
|
+
|
9
|
+
for (let i = 0; i < 5; i++) {
|
10
|
+
queue.run(async () => {
|
11
|
+
await sleep(50);
|
12
|
+
tasksExecuted.push(i);
|
13
|
+
});
|
14
|
+
}
|
15
|
+
await queue.flush();
|
16
|
+
expect(tasksExecuted).toMatchObject([0, 1, 2, 3, 4]);
|
17
|
+
});
|
18
|
+
it('runs tasks sequentially and not in parallel', async () => {
|
19
|
+
const queue = new AsyncQueue();
|
20
|
+
const results: number[] = [];
|
21
|
+
for (let i = 0; i < 5; i++) {
|
22
|
+
queue.run(async () => {
|
23
|
+
results.push(i);
|
24
|
+
await sleep(10);
|
25
|
+
results.push(i);
|
26
|
+
});
|
27
|
+
}
|
28
|
+
await queue.flush();
|
29
|
+
expect(results).toMatchObject([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]);
|
30
|
+
});
|
31
|
+
it('continues executing tasks if one task throws an error', async () => {
|
32
|
+
const queue = new AsyncQueue();
|
33
|
+
|
34
|
+
let task1threw = false;
|
35
|
+
let task2Executed = false;
|
36
|
+
|
37
|
+
queue
|
38
|
+
.run(async () => {
|
39
|
+
await sleep(100);
|
40
|
+
throw Error('task 1 throws');
|
41
|
+
})
|
42
|
+
.catch(() => {
|
43
|
+
task1threw = true;
|
44
|
+
});
|
45
|
+
|
46
|
+
await queue
|
47
|
+
.run(async () => {
|
48
|
+
task2Executed = true;
|
49
|
+
})
|
50
|
+
.catch(() => {
|
51
|
+
fail('task 2 should not have thrown');
|
52
|
+
});
|
53
|
+
|
54
|
+
expect(task1threw).toBeTruthy();
|
55
|
+
expect(task2Executed).toBeTruthy();
|
56
|
+
});
|
57
|
+
it('returns the result of the task', async () => {
|
58
|
+
const queue = new AsyncQueue();
|
59
|
+
|
60
|
+
const result = await queue.run(async () => {
|
61
|
+
await sleep(10);
|
62
|
+
return 'result';
|
63
|
+
});
|
64
|
+
|
65
|
+
expect(result).toBe('result');
|
66
|
+
});
|
67
|
+
it('returns only when the enqueued task and all previous tasks have completed', async () => {
|
68
|
+
const queue = new AsyncQueue();
|
69
|
+
const tasksExecuted: number[] = [];
|
70
|
+
for (let i = 0; i < 10; i += 1) {
|
71
|
+
queue.run(async () => {
|
72
|
+
await sleep(10);
|
73
|
+
tasksExecuted.push(i);
|
74
|
+
return i;
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
78
|
+
const result = await queue.run(async () => {
|
79
|
+
await sleep(10);
|
80
|
+
tasksExecuted.push(999);
|
81
|
+
return 'result';
|
82
|
+
});
|
83
|
+
|
84
|
+
expect(result).toBe('result');
|
85
|
+
expect(tasksExecuted).toMatchObject([...new Array(10).fill(0).map((_, idx) => idx), 999]);
|
86
|
+
});
|
87
|
+
it('can handle queue sizes of up to 10_000 tasks', async () => {
|
88
|
+
const queue = new AsyncQueue();
|
89
|
+
const tasksExecuted: number[] = [];
|
90
|
+
|
91
|
+
for (let i = 0; i < 10_000; i++) {
|
92
|
+
queue.run(async () => {
|
93
|
+
tasksExecuted.push(i);
|
94
|
+
});
|
95
|
+
}
|
96
|
+
await queue.flush();
|
97
|
+
expect(tasksExecuted).toMatchObject(new Array(10_000).fill(0).map((_, idx) => idx));
|
98
|
+
});
|
99
|
+
});
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { Mutex } from './room/utils';
|
2
|
+
|
3
|
+
type QueueTask<T> = () => PromiseLike<T>;
|
4
|
+
|
5
|
+
enum QueueTaskStatus {
|
6
|
+
'WAITING',
|
7
|
+
'RUNNING',
|
8
|
+
'COMPLETED',
|
9
|
+
}
|
10
|
+
|
11
|
+
type QueueTaskInfo = {
|
12
|
+
id: number;
|
13
|
+
enqueuedAt: number;
|
14
|
+
executedAt?: number;
|
15
|
+
status: QueueTaskStatus;
|
16
|
+
};
|
17
|
+
|
18
|
+
export class AsyncQueue {
|
19
|
+
private pendingTasks: Map<number, QueueTaskInfo>;
|
20
|
+
|
21
|
+
private taskMutex: Mutex;
|
22
|
+
|
23
|
+
private nextTaskIndex: number;
|
24
|
+
|
25
|
+
constructor() {
|
26
|
+
this.pendingTasks = new Map();
|
27
|
+
this.taskMutex = new Mutex();
|
28
|
+
this.nextTaskIndex = 0;
|
29
|
+
}
|
30
|
+
|
31
|
+
async run<T>(task: QueueTask<T>) {
|
32
|
+
const taskInfo: QueueTaskInfo = {
|
33
|
+
id: this.nextTaskIndex++,
|
34
|
+
enqueuedAt: Date.now(),
|
35
|
+
status: QueueTaskStatus.WAITING,
|
36
|
+
};
|
37
|
+
this.pendingTasks.set(taskInfo.id, taskInfo);
|
38
|
+
const unlock = await this.taskMutex.lock();
|
39
|
+
try {
|
40
|
+
taskInfo.executedAt = Date.now();
|
41
|
+
taskInfo.status = QueueTaskStatus.RUNNING;
|
42
|
+
return await task();
|
43
|
+
} finally {
|
44
|
+
taskInfo.status = QueueTaskStatus.COMPLETED;
|
45
|
+
this.pendingTasks.delete(taskInfo.id);
|
46
|
+
unlock();
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
async flush() {
|
51
|
+
return this.run(async () => {});
|
52
|
+
}
|
53
|
+
|
54
|
+
snapshot() {
|
55
|
+
return Array.from(this.pendingTasks.values());
|
56
|
+
}
|
57
|
+
}
|
package/src/api/SignalClient.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import Queue from 'async-await-queue';
|
2
1
|
import 'webrtc-adapter';
|
2
|
+
import { AsyncQueue } from '../AsyncQueue';
|
3
3
|
import log from '../logger';
|
4
4
|
import {
|
5
5
|
ClientInfo,
|
@@ -76,7 +76,7 @@ const passThroughQueueSignals: Array<SignalKind> = [
|
|
76
76
|
];
|
77
77
|
|
78
78
|
function canPassThroughQueue(req: SignalMessage): boolean {
|
79
|
-
const canPass = passThroughQueueSignals.
|
79
|
+
const canPass = passThroughQueueSignals.indexOf(req!.$case) >= 0;
|
80
80
|
log.trace('request allowed to bypass queue:', { canPass, req });
|
81
81
|
return canPass;
|
82
82
|
}
|
@@ -87,7 +87,7 @@ export class SignalClient {
|
|
87
87
|
|
88
88
|
isReconnecting: boolean;
|
89
89
|
|
90
|
-
requestQueue:
|
90
|
+
requestQueue: AsyncQueue;
|
91
91
|
|
92
92
|
queuedRequests: Array<() => Promise<void>>;
|
93
93
|
|
@@ -154,7 +154,7 @@ export class SignalClient {
|
|
154
154
|
this.isConnected = false;
|
155
155
|
this.isReconnecting = false;
|
156
156
|
this.useJSON = useJSON;
|
157
|
-
this.requestQueue = new
|
157
|
+
this.requestQueue = new AsyncQueue();
|
158
158
|
this.queuedRequests = [];
|
159
159
|
this.closingLock = new Mutex();
|
160
160
|
}
|
package/src/room/PCTransport.ts
CHANGED