livekit-client 2.5.10 → 2.6.1
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 +54 -0
- 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 +431 -45
- 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/api/SignalClient.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +2 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/RegionUrlProvider.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/errors.d.ts +2 -2
- package/dist/src/room/errors.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +56 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/rpc.d.ts +96 -0
- package/dist/src/room/rpc.d.ts.map +1 -0
- package/dist/src/room/track/RemoteAudioTrack.d.ts +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts +2 -2
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/index.d.ts +2 -0
- package/dist/ts4.2/src/room/PCTransport.d.ts +2 -0
- package/dist/ts4.2/src/room/errors.d.ts +2 -2
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +56 -0
- package/dist/ts4.2/src/room/rpc.d.ts +96 -0
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +2 -1
- package/dist/ts4.2/src/room/track/utils.d.ts +2 -2
- package/package.json +2 -2
- package/src/api/SignalClient.ts +19 -3
- package/src/index.ts +2 -0
- package/src/room/PCTransport.ts +42 -29
- package/src/room/PCTransportManager.ts +6 -1
- package/src/room/RTCEngine.ts +13 -3
- package/src/room/RegionUrlProvider.ts +3 -1
- package/src/room/Room.ts +9 -3
- package/src/room/errors.ts +2 -2
- package/src/room/participant/LocalParticipant.test.ts +304 -0
- package/src/room/participant/LocalParticipant.ts +340 -1
- package/src/room/rpc.ts +172 -0
- package/src/room/track/RemoteAudioTrack.ts +1 -1
- package/src/room/track/RemoteVideoTrack.ts +1 -1
- package/src/room/track/utils.ts +1 -6
@@ -0,0 +1,96 @@
|
|
1
|
+
import { RpcError as RpcError_Proto } from '@livekit/protocol';
|
2
|
+
/** Parameters for initiating an RPC call */
|
3
|
+
export interface PerformRpcParams {
|
4
|
+
/** The `identity` of the destination participant */
|
5
|
+
destinationIdentity: string;
|
6
|
+
/** The method name to call */
|
7
|
+
method: string;
|
8
|
+
/** The method payload */
|
9
|
+
payload: string;
|
10
|
+
/** Timeout for receiving a response after initial connection (milliseconds). Default: 10000 */
|
11
|
+
responseTimeout?: number;
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* Data passed to method handler for incoming RPC invocations
|
15
|
+
*/
|
16
|
+
export interface RpcInvocationData {
|
17
|
+
/**
|
18
|
+
* The unique request ID. Will match at both sides of the call, useful for debugging or logging.
|
19
|
+
*/
|
20
|
+
requestId: string;
|
21
|
+
/**
|
22
|
+
* The unique participant identity of the caller.
|
23
|
+
*/
|
24
|
+
callerIdentity: string;
|
25
|
+
/**
|
26
|
+
* The payload of the request. User-definable format, typically JSON.
|
27
|
+
*/
|
28
|
+
payload: string;
|
29
|
+
/**
|
30
|
+
* The maximum time the caller will wait for a response.
|
31
|
+
*/
|
32
|
+
responseTimeout: number;
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* Specialized error handling for RPC methods.
|
36
|
+
*
|
37
|
+
* Instances of this type, when thrown in a method handler, will have their `message`
|
38
|
+
* serialized and sent across the wire. The sender will receive an equivalent error on the other side.
|
39
|
+
*
|
40
|
+
* Built-in types are included but developers may use any string, with a max length of 256 bytes.
|
41
|
+
*/
|
42
|
+
export declare class RpcError extends Error {
|
43
|
+
static MAX_MESSAGE_BYTES: number;
|
44
|
+
static MAX_DATA_BYTES: number;
|
45
|
+
code: number;
|
46
|
+
data?: string;
|
47
|
+
/**
|
48
|
+
* Creates an error object with the given code and message, plus an optional data payload.
|
49
|
+
*
|
50
|
+
* If thrown in an RPC method handler, the error will be sent back to the caller.
|
51
|
+
*
|
52
|
+
* Error codes 1001-1999 are reserved for built-in errors (see RpcError.ErrorCode for their meanings).
|
53
|
+
*/
|
54
|
+
constructor(code: number, message: string, data?: string);
|
55
|
+
/**
|
56
|
+
* @internal
|
57
|
+
*/
|
58
|
+
static fromProto(proto: RpcError_Proto): RpcError;
|
59
|
+
/**
|
60
|
+
* @internal
|
61
|
+
*/
|
62
|
+
toProto(): RpcError_Proto;
|
63
|
+
static ErrorCode: {
|
64
|
+
readonly APPLICATION_ERROR: 1500;
|
65
|
+
readonly CONNECTION_TIMEOUT: 1501;
|
66
|
+
readonly RESPONSE_TIMEOUT: 1502;
|
67
|
+
readonly RECIPIENT_DISCONNECTED: 1503;
|
68
|
+
readonly RESPONSE_PAYLOAD_TOO_LARGE: 1504;
|
69
|
+
readonly SEND_FAILED: 1505;
|
70
|
+
readonly UNSUPPORTED_METHOD: 1400;
|
71
|
+
readonly RECIPIENT_NOT_FOUND: 1401;
|
72
|
+
readonly REQUEST_PAYLOAD_TOO_LARGE: 1402;
|
73
|
+
readonly UNSUPPORTED_SERVER: 1403;
|
74
|
+
readonly UNSUPPORTED_VERSION: 1404;
|
75
|
+
};
|
76
|
+
/**
|
77
|
+
* @internal
|
78
|
+
*/
|
79
|
+
static ErrorMessage: Record<keyof typeof RpcError.ErrorCode, string>;
|
80
|
+
/**
|
81
|
+
* Creates an error object from the code, with an auto-populated message.
|
82
|
+
*
|
83
|
+
* @internal
|
84
|
+
*/
|
85
|
+
static builtIn(key: keyof typeof RpcError.ErrorCode, data?: string): RpcError;
|
86
|
+
}
|
87
|
+
export declare const MAX_PAYLOAD_BYTES = 15360;
|
88
|
+
/**
|
89
|
+
* @internal
|
90
|
+
*/
|
91
|
+
export declare function byteLength(str: string): number;
|
92
|
+
/**
|
93
|
+
* @internal
|
94
|
+
*/
|
95
|
+
export declare function truncateBytes(str: string, maxBytes: number): string;
|
96
|
+
//# sourceMappingURL=rpc.d.ts.map
|
@@ -50,6 +50,6 @@ export default class RemoteAudioTrack extends RemoteTrack<Track.Kind.Audio> {
|
|
50
50
|
private connectWebAudio;
|
51
51
|
private disconnectWebAudio;
|
52
52
|
protected monitorReceiver: () => Promise<void>;
|
53
|
-
|
53
|
+
getReceiverStats(): Promise<AudioReceiverStats | undefined>;
|
54
54
|
}
|
55
55
|
//# sourceMappingURL=RemoteAudioTrack.d.ts.map
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { VideoReceiverStats } from '../stats';
|
1
2
|
import type { LoggerOptions } from '../types';
|
2
3
|
import RemoteTrack from './RemoteTrack';
|
3
4
|
import { Track } from './Track';
|
@@ -35,7 +36,7 @@ export default class RemoteVideoTrack extends RemoteTrack<Track.Kind.Video> {
|
|
35
36
|
/** @internal */
|
36
37
|
getDecoderImplementation(): string | undefined;
|
37
38
|
protected monitorReceiver: () => Promise<void>;
|
38
|
-
|
39
|
+
getReceiverStats(): Promise<VideoReceiverStats | undefined>;
|
39
40
|
private stopObservingElement;
|
40
41
|
protected handleAppVisibilityChanged(): Promise<void>;
|
41
42
|
private readonly debouncedHandleResize;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { TrackPublishedResponse } from '@livekit/protocol';
|
2
2
|
import { Track } from './Track';
|
3
3
|
import type { TrackPublication } from './TrackPublication';
|
4
|
-
import type { AudioCaptureOptions, CreateLocalTracksOptions, ScreenShareCaptureOptions, VideoCaptureOptions } from './options';
|
4
|
+
import type { AudioCaptureOptions, CreateLocalTracksOptions, ScreenShareCaptureOptions, VideoCaptureOptions, VideoCodec } from './options';
|
5
5
|
import type { AudioTrack } from './types';
|
6
6
|
export declare function mergeDefaultOptions(options?: CreateLocalTracksOptions, audioDefaults?: AudioCaptureOptions, videoDefaults?: VideoCaptureOptions): CreateLocalTracksOptions;
|
7
7
|
export declare function constraintsForOptions(options: CreateLocalTracksOptions): MediaStreamConstraints;
|
@@ -26,7 +26,7 @@ export declare function sourceToKind(source: Track.Source): MediaDeviceKind | un
|
|
26
26
|
* @internal
|
27
27
|
*/
|
28
28
|
export declare function screenCaptureToDisplayMediaStreamOptions(options: ScreenShareCaptureOptions): DisplayMediaStreamOptions;
|
29
|
-
export declare function mimeTypeToVideoCodecString(mimeType: string):
|
29
|
+
export declare function mimeTypeToVideoCodecString(mimeType: string): VideoCodec;
|
30
30
|
export declare function getTrackPublicationInfo<T extends TrackPublication>(tracks: T[]): TrackPublishedResponse[];
|
31
31
|
export declare function getLogContextFromTrack(track: Track | TrackPublication): Record<string, unknown>;
|
32
32
|
export declare function supportsSynchronizationSources(): boolean;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "livekit-client",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.6.1",
|
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",
|
@@ -88,7 +88,7 @@
|
|
88
88
|
"build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && pnpm downlevel-dts",
|
89
89
|
"build:watch": "rollup --watch --config --bundleConfigAsCjs",
|
90
90
|
"build:worker:watch": "rollup --watch --config rollup.config.worker.js --bundleConfigAsCjs",
|
91
|
-
"build-docs": "typedoc",
|
91
|
+
"build-docs": "typedoc && mkdir -p docs/assets/github && cp .github/*.png docs/assets/github/ && find docs -name '*.html' -type f -exec sed -i.bak 's|=\"/.github/|=\"assets/github/|g' {} + && find docs -name '*.bak' -delete",
|
92
92
|
"proto": "protoc --es_out src/proto --es_opt target=ts -I./protocol ./protocol/livekit_rtc.proto ./protocol/livekit_models.proto",
|
93
93
|
"examples:demo": "vite examples/demo -c vite.config.mjs",
|
94
94
|
"lint": "eslint src",
|
package/src/api/SignalClient.ts
CHANGED
@@ -272,12 +272,22 @@ export class SignalClient {
|
|
272
272
|
const abortHandler = async () => {
|
273
273
|
this.close();
|
274
274
|
clearTimeout(wsTimeout);
|
275
|
-
reject(
|
275
|
+
reject(
|
276
|
+
new ConnectionError(
|
277
|
+
'room connection has been cancelled (signal)',
|
278
|
+
ConnectionErrorReason.Cancelled,
|
279
|
+
),
|
280
|
+
);
|
276
281
|
};
|
277
282
|
|
278
283
|
const wsTimeout = setTimeout(() => {
|
279
284
|
this.close();
|
280
|
-
reject(
|
285
|
+
reject(
|
286
|
+
new ConnectionError(
|
287
|
+
'room connection has timed out (signal)',
|
288
|
+
ConnectionErrorReason.ServerUnreachable,
|
289
|
+
),
|
290
|
+
);
|
281
291
|
}, opts.websocketTimeout);
|
282
292
|
|
283
293
|
if (abortSignal?.aborted) {
|
@@ -391,6 +401,7 @@ export class SignalClient {
|
|
391
401
|
reject(
|
392
402
|
new ConnectionError(
|
393
403
|
`did not receive join response, got ${resp.message?.case} instead`,
|
404
|
+
ConnectionErrorReason.InternalError,
|
394
405
|
),
|
395
406
|
);
|
396
407
|
}
|
@@ -407,7 +418,12 @@ export class SignalClient {
|
|
407
418
|
|
408
419
|
this.ws.onclose = (ev: CloseEvent) => {
|
409
420
|
if (this.isEstablishingConnection) {
|
410
|
-
reject(
|
421
|
+
reject(
|
422
|
+
new ConnectionError(
|
423
|
+
'Websocket got closed during a (re)connection attempt',
|
424
|
+
ConnectionErrorReason.InternalError,
|
425
|
+
),
|
426
|
+
);
|
411
427
|
}
|
412
428
|
|
413
429
|
this.log.warn(`websocket closed`, {
|
package/src/index.ts
CHANGED
@@ -39,6 +39,8 @@ import {
|
|
39
39
|
} from './room/utils';
|
40
40
|
import { getBrowser } from './utils/browserParser';
|
41
41
|
|
42
|
+
export { RpcError, type RpcInvocationData, type PerformRpcParams } from './room/rpc';
|
43
|
+
|
42
44
|
export * from './connectionHelper/ConnectionCheck';
|
43
45
|
export * from './connectionHelper/checks/Checker';
|
44
46
|
export * from './e2ee';
|
package/src/room/PCTransport.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { EventEmitter } from 'events';
|
2
|
-
import type { MediaDescription } from 'sdp-transform';
|
2
|
+
import type { MediaDescription, SessionDescription } from 'sdp-transform';
|
3
3
|
import { parse, write } from 'sdp-transform';
|
4
4
|
import { debounce } from 'ts-debounce';
|
5
5
|
import log, { LoggerNames, getLogger } from '../logger';
|
@@ -48,6 +48,8 @@ export default class PCTransport extends EventEmitter {
|
|
48
48
|
|
49
49
|
private loggerOptions: LoggerOptions;
|
50
50
|
|
51
|
+
private ddExtID = 0;
|
52
|
+
|
51
53
|
pendingCandidates: RTCIceCandidateInit[] = [];
|
52
54
|
|
53
55
|
restartingIce: boolean = false;
|
@@ -288,7 +290,7 @@ export default class PCTransport extends EventEmitter {
|
|
288
290
|
}
|
289
291
|
|
290
292
|
if (isSVCCodec(trackbr.codec)) {
|
291
|
-
ensureVideoDDExtensionForSVC(media);
|
293
|
+
this.ensureVideoDDExtensionForSVC(media, sdpParsed);
|
292
294
|
}
|
293
295
|
|
294
296
|
// TODO: av1 slow starting issue already fixed in chrome 124, clean this after some versions
|
@@ -503,6 +505,44 @@ export default class PCTransport extends EventEmitter {
|
|
503
505
|
throw new NegotiationError(msg);
|
504
506
|
}
|
505
507
|
}
|
508
|
+
|
509
|
+
private ensureVideoDDExtensionForSVC(
|
510
|
+
media: {
|
511
|
+
type: string;
|
512
|
+
port: number;
|
513
|
+
protocol: string;
|
514
|
+
payloads?: string | undefined;
|
515
|
+
} & MediaDescription,
|
516
|
+
sdp: SessionDescription,
|
517
|
+
) {
|
518
|
+
const ddFound = media.ext?.some((ext): boolean => {
|
519
|
+
if (ext.uri === ddExtensionURI) {
|
520
|
+
return true;
|
521
|
+
}
|
522
|
+
return false;
|
523
|
+
});
|
524
|
+
|
525
|
+
if (!ddFound) {
|
526
|
+
if (this.ddExtID === 0) {
|
527
|
+
let maxID = 0;
|
528
|
+
sdp.media.forEach((m) => {
|
529
|
+
if (m.type !== 'video') {
|
530
|
+
return;
|
531
|
+
}
|
532
|
+
m.ext?.forEach((ext) => {
|
533
|
+
if (ext.value > maxID) {
|
534
|
+
maxID = ext.value;
|
535
|
+
}
|
536
|
+
});
|
537
|
+
});
|
538
|
+
this.ddExtID = maxID + 1;
|
539
|
+
}
|
540
|
+
media.ext?.push({
|
541
|
+
value: this.ddExtID,
|
542
|
+
uri: ddExtensionURI,
|
543
|
+
});
|
544
|
+
}
|
545
|
+
}
|
506
546
|
}
|
507
547
|
|
508
548
|
function ensureAudioNackAndStereo(
|
@@ -555,33 +595,6 @@ function ensureAudioNackAndStereo(
|
|
555
595
|
}
|
556
596
|
}
|
557
597
|
|
558
|
-
function ensureVideoDDExtensionForSVC(
|
559
|
-
media: {
|
560
|
-
type: string;
|
561
|
-
port: number;
|
562
|
-
protocol: string;
|
563
|
-
payloads?: string | undefined;
|
564
|
-
} & MediaDescription,
|
565
|
-
) {
|
566
|
-
let maxID = 0;
|
567
|
-
const ddFound = media.ext?.some((ext): boolean => {
|
568
|
-
if (ext.uri === ddExtensionURI) {
|
569
|
-
return true;
|
570
|
-
}
|
571
|
-
if (ext.value > maxID) {
|
572
|
-
maxID = ext.value;
|
573
|
-
}
|
574
|
-
return false;
|
575
|
-
});
|
576
|
-
|
577
|
-
if (!ddFound) {
|
578
|
-
media.ext?.push({
|
579
|
-
value: maxID + 1,
|
580
|
-
uri: ddExtensionURI,
|
581
|
-
});
|
582
|
-
}
|
583
|
-
}
|
584
|
-
|
585
598
|
function extractStereoAndNackAudioFromOffer(offer: RTCSessionDescriptionInit): {
|
586
599
|
stereoMids: string[];
|
587
600
|
nackMids: string[];
|
@@ -342,7 +342,12 @@ export class PCTransportManager {
|
|
342
342
|
|
343
343
|
const connectTimeout = CriticalTimers.setTimeout(() => {
|
344
344
|
abortController?.signal.removeEventListener('abort', abortHandler);
|
345
|
-
reject(
|
345
|
+
reject(
|
346
|
+
new ConnectionError(
|
347
|
+
'could not establish pc connection',
|
348
|
+
ConnectionErrorReason.InternalError,
|
349
|
+
),
|
350
|
+
);
|
346
351
|
}, timeout);
|
347
352
|
|
348
353
|
while (this.state !== PCTransportState.CONNECTED) {
|
package/src/room/RTCEngine.ts
CHANGED
@@ -313,7 +313,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
313
313
|
const publicationTimeout = setTimeout(() => {
|
314
314
|
delete this.pendingTrackResolvers[req.cid];
|
315
315
|
reject(
|
316
|
-
new ConnectionError(
|
316
|
+
new ConnectionError(
|
317
|
+
'publication of local track timed out, no response from server',
|
318
|
+
ConnectionErrorReason.InternalError,
|
319
|
+
),
|
317
320
|
);
|
318
321
|
}, 10_000);
|
319
322
|
this.pendingTrackResolvers[req.cid] = {
|
@@ -1061,7 +1064,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1061
1064
|
} catch (e: any) {
|
1062
1065
|
// TODO do we need a `failed` state here for the PC?
|
1063
1066
|
this.pcState = PCState.Disconnected;
|
1064
|
-
throw new ConnectionError(
|
1067
|
+
throw new ConnectionError(
|
1068
|
+
`could not establish PC connection, ${e.message}`,
|
1069
|
+
ConnectionErrorReason.InternalError,
|
1070
|
+
);
|
1065
1071
|
}
|
1066
1072
|
}
|
1067
1073
|
|
@@ -1126,7 +1132,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1126
1132
|
const transport = subscriber ? this.pcManager.subscriber : this.pcManager.publisher;
|
1127
1133
|
const transportName = subscriber ? 'Subscriber' : 'Publisher';
|
1128
1134
|
if (!transport) {
|
1129
|
-
throw new ConnectionError(
|
1135
|
+
throw new ConnectionError(
|
1136
|
+
`${transportName} connection not set`,
|
1137
|
+
ConnectionErrorReason.InternalError,
|
1138
|
+
);
|
1130
1139
|
}
|
1131
1140
|
|
1132
1141
|
let needNegotiation = false;
|
@@ -1167,6 +1176,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
1167
1176
|
|
1168
1177
|
throw new ConnectionError(
|
1169
1178
|
`could not establish ${transportName} connection, state: ${transport.getICEConnectionState()}`,
|
1179
|
+
ConnectionErrorReason.InternalError,
|
1170
1180
|
);
|
1171
1181
|
}
|
1172
1182
|
|
@@ -70,7 +70,9 @@ export class RegionUrlProvider {
|
|
70
70
|
} else {
|
71
71
|
throw new ConnectionError(
|
72
72
|
`Could not fetch region settings: ${regionSettingsResponse.statusText}`,
|
73
|
-
regionSettingsResponse.status === 401
|
73
|
+
regionSettingsResponse.status === 401
|
74
|
+
? ConnectionErrorReason.NotAllowed
|
75
|
+
: ConnectionErrorReason.InternalError,
|
74
76
|
regionSettingsResponse.status,
|
75
77
|
);
|
76
78
|
}
|
package/src/room/Room.ts
CHANGED
@@ -714,7 +714,10 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
714
714
|
} catch (err) {
|
715
715
|
await this.engine.close();
|
716
716
|
this.recreateEngine();
|
717
|
-
const resultingError = new ConnectionError(
|
717
|
+
const resultingError = new ConnectionError(
|
718
|
+
`could not establish signal connection`,
|
719
|
+
ConnectionErrorReason.ServerUnreachable,
|
720
|
+
);
|
718
721
|
if (err instanceof Error) {
|
719
722
|
resultingError.message = `${resultingError.message}: ${err.message}`;
|
720
723
|
}
|
@@ -732,7 +735,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
732
735
|
if (abortController.signal.aborted) {
|
733
736
|
await this.engine.close();
|
734
737
|
this.recreateEngine();
|
735
|
-
throw new ConnectionError(`Connection attempt aborted
|
738
|
+
throw new ConnectionError(`Connection attempt aborted`, ConnectionErrorReason.Cancelled);
|
736
739
|
}
|
737
740
|
|
738
741
|
try {
|
@@ -783,7 +786,9 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
783
786
|
this.log.warn('abort connection attempt', this.logContext);
|
784
787
|
this.abortController?.abort();
|
785
788
|
// in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
|
786
|
-
this.connectFuture?.reject?.(
|
789
|
+
this.connectFuture?.reject?.(
|
790
|
+
new ConnectionError('Client initiated disconnect', ConnectionErrorReason.Cancelled),
|
791
|
+
);
|
787
792
|
this.connectFuture = undefined;
|
788
793
|
}
|
789
794
|
// send leave
|
@@ -1414,6 +1419,7 @@ class Room extends (EventEmitter as new () => TypedEmitter<RoomEventCallbacks>)
|
|
1414
1419
|
participant.unpublishTrack(publication.trackSid, true);
|
1415
1420
|
});
|
1416
1421
|
this.emit(RoomEvent.ParticipantDisconnected, participant);
|
1422
|
+
this.localParticipant?.handleParticipantDisconnected(participant.identity);
|
1417
1423
|
}
|
1418
1424
|
|
1419
1425
|
// updates are sent only when there's a change to speaker ordering
|
package/src/room/errors.ts
CHANGED
@@ -20,9 +20,9 @@ export const enum ConnectionErrorReason {
|
|
20
20
|
export class ConnectionError extends LivekitError {
|
21
21
|
status?: number;
|
22
22
|
|
23
|
-
reason
|
23
|
+
reason: ConnectionErrorReason;
|
24
24
|
|
25
|
-
constructor(message
|
25
|
+
constructor(message: string, reason: ConnectionErrorReason, status?: number) {
|
26
26
|
super(1, message);
|
27
27
|
this.status = status;
|
28
28
|
this.reason = reason;
|