livekit-client 1.9.3 → 1.9.4
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/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