livekit-client 2.18.10 → 2.19.0
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/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +720 -430
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.pt.worker.js.map +1 -1
- package/dist/livekit-client.pt.worker.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +0 -3
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +4 -2
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +5 -13
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +5 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/rpc/client/RpcClientManager.d.ts +39 -0
- package/dist/src/room/rpc/client/RpcClientManager.d.ts.map +1 -0
- package/dist/src/room/rpc/client/events.d.ts +8 -0
- package/dist/src/room/rpc/client/events.d.ts.map +1 -0
- package/dist/src/room/rpc/index.d.ts +6 -0
- package/dist/src/room/rpc/index.d.ts.map +1 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts.map +1 -0
- package/dist/src/room/rpc/server/events.d.ts +8 -0
- package/dist/src/room/rpc/server/events.d.ts.map +1 -0
- package/dist/src/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/src/room/rpc/utils.d.ts.map +1 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/version.d.ts +8 -0
- package/dist/src/version.d.ts.map +1 -1
- package/dist/ts4.2/room/RTCEngine.d.ts +0 -3
- package/dist/ts4.2/room/Room.d.ts +4 -2
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +5 -13
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +5 -1
- package/dist/ts4.2/room/rpc/client/RpcClientManager.d.ts +43 -0
- package/dist/ts4.2/room/rpc/client/events.d.ts +8 -0
- package/dist/ts4.2/room/rpc/index.d.ts +7 -0
- package/dist/ts4.2/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/ts4.2/room/rpc/server/events.d.ts +8 -0
- package/dist/ts4.2/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/ts4.2/version.d.ts +8 -0
- package/package.json +1 -1
- package/src/room/RTCEngine.ts +0 -26
- package/src/room/Room.ts +83 -81
- package/src/room/participant/LocalParticipant.ts +16 -180
- package/src/room/participant/RemoteParticipant.ts +9 -0
- package/src/room/rpc/client/RpcClientManager.test.ts +430 -0
- package/src/room/rpc/client/RpcClientManager.ts +269 -0
- package/src/room/rpc/client/events.ts +9 -0
- package/src/room/rpc/index.ts +14 -0
- package/src/room/rpc/server/RpcServerManager.test.ts +471 -0
- package/src/room/rpc/server/RpcServerManager.ts +293 -0
- package/src/room/rpc/server/events.ts +9 -0
- package/src/room/{rpc.ts → rpc/utils.ts} +49 -8
- package/src/room/utils.ts +2 -1
- package/src/version.ts +10 -0
- package/dist/src/room/rpc.d.ts.map +0 -1
- package/src/room/rpc.test.ts +0 -301
package/src/room/rpc.test.ts
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
import { DataPacket, DataPacket_Kind } from '@livekit/protocol';
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import type { InternalRoomOptions } from '../options';
|
|
4
|
-
import type RTCEngine from './RTCEngine';
|
|
5
|
-
import Room from './Room';
|
|
6
|
-
import LocalParticipant from './participant/LocalParticipant';
|
|
7
|
-
import { ParticipantKind } from './participant/Participant';
|
|
8
|
-
import RemoteParticipant from './participant/RemoteParticipant';
|
|
9
|
-
import { RpcError } from './rpc';
|
|
10
|
-
|
|
11
|
-
describe('LocalParticipant', () => {
|
|
12
|
-
describe('registerRpcMethod', () => {
|
|
13
|
-
let room: Room;
|
|
14
|
-
let mockSendDataPacket: ReturnType<typeof vi.fn>;
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
mockSendDataPacket = vi.fn();
|
|
18
|
-
|
|
19
|
-
room = new Room();
|
|
20
|
-
room.engine.client = {
|
|
21
|
-
sendUpdateLocalMetadata: vi.fn(),
|
|
22
|
-
};
|
|
23
|
-
room.engine.on = vi.fn().mockReturnThis();
|
|
24
|
-
room.engine.sendDataPacket = mockSendDataPacket;
|
|
25
|
-
|
|
26
|
-
room.localParticipant.sid = 'test-sid';
|
|
27
|
-
room.localParticipant.identity = 'test-identity';
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should register an RPC method handler', async () => {
|
|
31
|
-
const methodName = 'testMethod';
|
|
32
|
-
const handler = vi.fn().mockResolvedValue('test response');
|
|
33
|
-
|
|
34
|
-
room.registerRpcMethod(methodName, handler);
|
|
35
|
-
|
|
36
|
-
const mockCaller = new RemoteParticipant(
|
|
37
|
-
{} as any,
|
|
38
|
-
'remote-sid',
|
|
39
|
-
'remote-identity',
|
|
40
|
-
'Remote Participant',
|
|
41
|
-
'',
|
|
42
|
-
undefined,
|
|
43
|
-
undefined,
|
|
44
|
-
ParticipantKind.STANDARD,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
await room.handleIncomingRpcRequest(
|
|
48
|
-
mockCaller.identity,
|
|
49
|
-
'test-request-id',
|
|
50
|
-
methodName,
|
|
51
|
-
'test payload',
|
|
52
|
-
5000,
|
|
53
|
-
1,
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
expect(handler).toHaveBeenCalledWith({
|
|
57
|
-
requestId: 'test-request-id',
|
|
58
|
-
callerIdentity: mockCaller.identity,
|
|
59
|
-
payload: 'test payload',
|
|
60
|
-
responseTimeout: 5000,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Check if sendDataPacket was called twice (once for ACK and once for response)
|
|
64
|
-
expect(mockSendDataPacket).toHaveBeenCalledTimes(2);
|
|
65
|
-
|
|
66
|
-
// Check if the first call was for ACK
|
|
67
|
-
expect(mockSendDataPacket.mock.calls[0][0].value.case).toBe('rpcAck');
|
|
68
|
-
expect(mockSendDataPacket.mock.calls[0][1]).toBe(DataPacket_Kind.RELIABLE);
|
|
69
|
-
|
|
70
|
-
// Check if the second call was for response
|
|
71
|
-
expect(mockSendDataPacket.mock.calls[1][0].value.case).toBe('rpcResponse');
|
|
72
|
-
expect(mockSendDataPacket.mock.calls[1][1]).toBe(DataPacket_Kind.RELIABLE);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should catch and transform unhandled errors in the RPC method handler', async () => {
|
|
76
|
-
const methodName = 'errorMethod';
|
|
77
|
-
const errorMessage = 'Test error';
|
|
78
|
-
const handler = vi.fn().mockRejectedValue(new Error(errorMessage));
|
|
79
|
-
|
|
80
|
-
room.registerRpcMethod(methodName, handler);
|
|
81
|
-
|
|
82
|
-
const mockCaller = new RemoteParticipant(
|
|
83
|
-
{} as any,
|
|
84
|
-
'remote-sid',
|
|
85
|
-
'remote-identity',
|
|
86
|
-
'Remote Participant',
|
|
87
|
-
'',
|
|
88
|
-
undefined,
|
|
89
|
-
undefined,
|
|
90
|
-
ParticipantKind.STANDARD,
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
await room.handleIncomingRpcRequest(
|
|
94
|
-
mockCaller.identity,
|
|
95
|
-
'test-error-request-id',
|
|
96
|
-
methodName,
|
|
97
|
-
'test payload',
|
|
98
|
-
5000,
|
|
99
|
-
1,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
expect(handler).toHaveBeenCalledWith({
|
|
103
|
-
requestId: 'test-error-request-id',
|
|
104
|
-
callerIdentity: mockCaller.identity,
|
|
105
|
-
payload: 'test payload',
|
|
106
|
-
responseTimeout: 5000,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Check if sendDataPacket was called twice (once for ACK and once for error response)
|
|
110
|
-
expect(mockSendDataPacket).toHaveBeenCalledTimes(2);
|
|
111
|
-
|
|
112
|
-
// Check if the second call was for error response
|
|
113
|
-
const errorResponse = mockSendDataPacket.mock.calls[1][0].value.value.value.value;
|
|
114
|
-
expect(errorResponse.code).toBe(RpcError.ErrorCode.APPLICATION_ERROR);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should pass through RpcError thrown by the RPC method handler', async () => {
|
|
118
|
-
const methodName = 'rpcErrorMethod';
|
|
119
|
-
const errorCode = 101;
|
|
120
|
-
const errorMessage = 'some-error-message';
|
|
121
|
-
const handler = vi.fn().mockRejectedValue(new RpcError(errorCode, errorMessage));
|
|
122
|
-
|
|
123
|
-
room.localParticipant.registerRpcMethod(methodName, handler);
|
|
124
|
-
|
|
125
|
-
const mockCaller = new RemoteParticipant(
|
|
126
|
-
{} as any,
|
|
127
|
-
'remote-sid',
|
|
128
|
-
'remote-identity',
|
|
129
|
-
'Remote Participant',
|
|
130
|
-
'',
|
|
131
|
-
undefined,
|
|
132
|
-
undefined,
|
|
133
|
-
ParticipantKind.STANDARD,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
await room.handleIncomingRpcRequest(
|
|
137
|
-
mockCaller.identity,
|
|
138
|
-
'test-rpc-error-request-id',
|
|
139
|
-
methodName,
|
|
140
|
-
'test payload',
|
|
141
|
-
5000,
|
|
142
|
-
1,
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
expect(handler).toHaveBeenCalledWith({
|
|
146
|
-
requestId: 'test-rpc-error-request-id',
|
|
147
|
-
callerIdentity: mockCaller.identity,
|
|
148
|
-
payload: 'test payload',
|
|
149
|
-
responseTimeout: 5000,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Check if sendDataPacket was called twice (once for ACK and once for error response)
|
|
153
|
-
expect(mockSendDataPacket).toHaveBeenCalledTimes(2);
|
|
154
|
-
|
|
155
|
-
// Check if the second call was for error response
|
|
156
|
-
const errorResponse = mockSendDataPacket.mock.calls[1][0].value.value.value.value;
|
|
157
|
-
expect(errorResponse.code).toBe(errorCode);
|
|
158
|
-
expect(errorResponse.message).toBe(errorMessage);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
describe('performRpc', () => {
|
|
163
|
-
let localParticipant: LocalParticipant;
|
|
164
|
-
let mockRemoteParticipant: RemoteParticipant;
|
|
165
|
-
let mockEngine: RTCEngine;
|
|
166
|
-
let mockRoomOptions: InternalRoomOptions;
|
|
167
|
-
let mockSendDataPacket: ReturnType<typeof vi.fn>;
|
|
168
|
-
|
|
169
|
-
beforeEach(() => {
|
|
170
|
-
mockSendDataPacket = vi.fn();
|
|
171
|
-
mockEngine = {
|
|
172
|
-
client: {
|
|
173
|
-
sendUpdateLocalMetadata: vi.fn(),
|
|
174
|
-
},
|
|
175
|
-
on: vi.fn().mockReturnThis(),
|
|
176
|
-
sendDataPacket: mockSendDataPacket,
|
|
177
|
-
} as unknown as RTCEngine;
|
|
178
|
-
|
|
179
|
-
mockRoomOptions = {} as InternalRoomOptions;
|
|
180
|
-
|
|
181
|
-
localParticipant = new LocalParticipant(
|
|
182
|
-
'local-sid',
|
|
183
|
-
'local-identity',
|
|
184
|
-
mockEngine,
|
|
185
|
-
mockRoomOptions,
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
mockRemoteParticipant = new RemoteParticipant(
|
|
189
|
-
{} as any,
|
|
190
|
-
'remote-sid',
|
|
191
|
-
'remote-identity',
|
|
192
|
-
'Remote Participant',
|
|
193
|
-
'',
|
|
194
|
-
undefined,
|
|
195
|
-
undefined,
|
|
196
|
-
ParticipantKind.STANDARD,
|
|
197
|
-
);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('should send RPC request and receive successful response', async () => {
|
|
201
|
-
const method = 'testMethod';
|
|
202
|
-
const payload = 'testPayload';
|
|
203
|
-
const responsePayload = 'responsePayload';
|
|
204
|
-
|
|
205
|
-
mockSendDataPacket.mockImplementationOnce((packet: DataPacket) => {
|
|
206
|
-
const requestId = packet.value.value.id;
|
|
207
|
-
setTimeout(() => {
|
|
208
|
-
localParticipant.handleIncomingRpcAck(requestId);
|
|
209
|
-
setTimeout(() => {
|
|
210
|
-
localParticipant.handleIncomingRpcResponse(requestId, responsePayload, null);
|
|
211
|
-
}, 10);
|
|
212
|
-
}, 10);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
const result = await localParticipant.performRpc({
|
|
216
|
-
destinationIdentity: mockRemoteParticipant.identity,
|
|
217
|
-
method,
|
|
218
|
-
payload,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
expect(mockSendDataPacket).toHaveBeenCalledTimes(1);
|
|
222
|
-
expect(result).toBe(responsePayload);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('should handle RPC request timeout', async () => {
|
|
226
|
-
const method = 'timeoutMethod';
|
|
227
|
-
const payload = 'timeoutPayload';
|
|
228
|
-
|
|
229
|
-
const timeout = 50;
|
|
230
|
-
|
|
231
|
-
const resultPromise = localParticipant.performRpc({
|
|
232
|
-
destinationIdentity: mockRemoteParticipant.identity,
|
|
233
|
-
method,
|
|
234
|
-
payload,
|
|
235
|
-
responseTimeout: timeout,
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
mockSendDataPacket.mockImplementationOnce(() => {
|
|
239
|
-
return new Promise((resolve) => {
|
|
240
|
-
setTimeout(resolve, timeout + 10);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
const startTime = Date.now();
|
|
245
|
-
|
|
246
|
-
await expect(resultPromise).rejects.toThrow('Response timeout');
|
|
247
|
-
|
|
248
|
-
const elapsedTime = Date.now() - startTime;
|
|
249
|
-
expect(elapsedTime).toBeGreaterThanOrEqual(timeout);
|
|
250
|
-
expect(elapsedTime).toBeLessThan(timeout + 50); // Allow some margin for test execution
|
|
251
|
-
|
|
252
|
-
expect(mockSendDataPacket).toHaveBeenCalledTimes(1);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should handle RPC error response', async () => {
|
|
256
|
-
const method = 'errorMethod';
|
|
257
|
-
const payload = 'errorPayload';
|
|
258
|
-
const errorCode = 101;
|
|
259
|
-
const errorMessage = 'Test error message';
|
|
260
|
-
|
|
261
|
-
mockSendDataPacket.mockImplementationOnce((packet: DataPacket) => {
|
|
262
|
-
const requestId = packet.value.value.id;
|
|
263
|
-
setTimeout(() => {
|
|
264
|
-
localParticipant.handleIncomingRpcAck(requestId);
|
|
265
|
-
localParticipant.handleIncomingRpcResponse(
|
|
266
|
-
requestId,
|
|
267
|
-
null,
|
|
268
|
-
new RpcError(errorCode, errorMessage),
|
|
269
|
-
);
|
|
270
|
-
}, 10);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
await expect(
|
|
274
|
-
localParticipant.performRpc({
|
|
275
|
-
destinationIdentity: mockRemoteParticipant.identity,
|
|
276
|
-
method,
|
|
277
|
-
payload,
|
|
278
|
-
}),
|
|
279
|
-
).rejects.toThrow(errorMessage);
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
it('should handle participant disconnection during RPC request', async () => {
|
|
283
|
-
const method = 'disconnectMethod';
|
|
284
|
-
const payload = 'disconnectPayload';
|
|
285
|
-
|
|
286
|
-
mockSendDataPacket.mockImplementationOnce(() => Promise.resolve());
|
|
287
|
-
|
|
288
|
-
const resultPromise = localParticipant.performRpc({
|
|
289
|
-
destinationIdentity: mockRemoteParticipant.identity,
|
|
290
|
-
method,
|
|
291
|
-
payload,
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
// Simulate a small delay before disconnection
|
|
295
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
296
|
-
localParticipant.handleParticipantDisconnected(mockRemoteParticipant.identity);
|
|
297
|
-
|
|
298
|
-
await expect(resultPromise).rejects.toThrow('Recipient disconnected');
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
});
|