livekit-client 2.8.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. package/README.md +18 -7
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +1 -0
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +3685 -2966
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/index.d.ts +7 -5
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/room/RTCEngine.d.ts +6 -0
  14. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  15. package/dist/src/room/Room.d.ts +50 -1
  16. package/dist/src/room/Room.d.ts.map +1 -1
  17. package/dist/src/room/StreamReader.d.ts +56 -0
  18. package/dist/src/room/StreamReader.d.ts.map +1 -0
  19. package/dist/src/room/StreamWriter.d.ts +16 -0
  20. package/dist/src/room/StreamWriter.d.ts.map +1 -0
  21. package/dist/src/room/errors.d.ts +3 -1
  22. package/dist/src/room/errors.d.ts.map +1 -1
  23. package/dist/src/room/participant/LocalParticipant.d.ts +23 -36
  24. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  25. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  26. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  27. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  28. package/dist/src/room/track/LocalTrack.d.ts +1 -0
  29. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  30. package/dist/src/room/track/LocalTrackPublication.d.ts +1 -0
  31. package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
  32. package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
  33. package/dist/src/room/track/RemoteTrack.d.ts +1 -0
  34. package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
  35. package/dist/src/room/track/RemoteTrackPublication.d.ts +1 -0
  36. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  37. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  38. package/dist/src/room/track/Track.d.ts +1 -0
  39. package/dist/src/room/track/Track.d.ts.map +1 -1
  40. package/dist/src/room/track/TrackPublication.d.ts +2 -1
  41. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  42. package/dist/src/room/track/create.d.ts.map +1 -1
  43. package/dist/src/room/track/facingMode.d.ts.map +1 -1
  44. package/dist/src/room/track/options.d.ts +18 -2
  45. package/dist/src/room/track/options.d.ts.map +1 -1
  46. package/dist/src/room/types.d.ts +43 -0
  47. package/dist/src/room/types.d.ts.map +1 -1
  48. package/dist/src/room/utils.d.ts +26 -0
  49. package/dist/src/room/utils.d.ts.map +1 -1
  50. package/dist/ts4.2/src/index.d.ts +7 -5
  51. package/dist/ts4.2/src/room/RTCEngine.d.ts +6 -0
  52. package/dist/ts4.2/src/room/Room.d.ts +49 -0
  53. package/dist/ts4.2/src/room/StreamReader.d.ts +56 -0
  54. package/dist/ts4.2/src/room/StreamWriter.d.ts +25 -0
  55. package/dist/ts4.2/src/room/errors.d.ts +3 -1
  56. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +23 -36
  57. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
  58. package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +1 -0
  59. package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +1 -0
  60. package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +1 -0
  61. package/dist/ts4.2/src/room/track/Track.d.ts +1 -0
  62. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +2 -1
  63. package/dist/ts4.2/src/room/track/options.d.ts +18 -2
  64. package/dist/ts4.2/src/room/types.d.ts +43 -0
  65. package/dist/ts4.2/src/room/utils.d.ts +26 -0
  66. package/package.json +3 -3
  67. package/src/api/SignalClient.ts +5 -2
  68. package/src/e2ee/E2eeManager.ts +2 -2
  69. package/src/index.ts +17 -1
  70. package/src/room/RTCEngine.ts +69 -2
  71. package/src/room/Room.ts +317 -25
  72. package/src/room/StreamReader.ts +177 -0
  73. package/src/room/StreamWriter.ts +32 -0
  74. package/src/room/errors.ts +16 -2
  75. package/src/room/participant/LocalParticipant.ts +320 -165
  76. package/src/room/participant/Participant.ts +2 -5
  77. package/src/room/participant/RemoteParticipant.ts +3 -2
  78. package/src/room/{participant/LocalParticipant.test.ts → rpc.test.ts} +22 -29
  79. package/src/room/track/LocalAudioTrack.ts +4 -3
  80. package/src/room/track/LocalTrack.ts +12 -4
  81. package/src/room/track/LocalTrackPublication.ts +6 -1
  82. package/src/room/track/LocalVideoTrack.ts +1 -1
  83. package/src/room/track/RemoteAudioTrack.ts +1 -0
  84. package/src/room/track/RemoteTrack.ts +4 -0
  85. package/src/room/track/RemoteTrackPublication.ts +8 -4
  86. package/src/room/track/RemoteVideoTrack.ts +1 -0
  87. package/src/room/track/Track.ts +2 -0
  88. package/src/room/track/TrackPublication.ts +6 -3
  89. package/src/room/track/create.ts +4 -3
  90. package/src/room/track/facingMode.ts +2 -1
  91. package/src/room/track/options.ts +20 -2
  92. package/src/room/track/utils.ts +1 -1
  93. package/src/room/types.ts +50 -0
  94. package/src/room/utils.ts +77 -0
@@ -1,12 +1,13 @@
1
1
  import { Codec, ParticipantInfo, ParticipantPermission } from '@livekit/protocol';
2
2
  import type { InternalRoomOptions } from '../../options';
3
3
  import type RTCEngine from '../RTCEngine';
4
+ import { TextStreamWriter } from '../StreamWriter';
4
5
  import type { PerformRpcParams, RpcInvocationData } from '../rpc';
5
6
  import LocalTrack from '../track/LocalTrack';
6
7
  import LocalTrackPublication from '../track/LocalTrackPublication';
7
8
  import { Track } from '../track/Track';
8
9
  import type { AudioCaptureOptions, BackupVideoCodec, CreateLocalTracksOptions, ScreenShareCaptureOptions, TrackPublishOptions, VideoCaptureOptions } from '../track/options';
9
- import type { ChatMessage, DataPublishOptions } from '../types';
10
+ import type { ChatMessage, DataPublishOptions, SendTextOptions, StreamTextOptions, TextStreamInfo } from '../types';
10
11
  import Participant from './Participant';
11
12
  import type { ParticipantTrackPermission } from './ParticipantTrackPermission';
12
13
  export default class LocalParticipant extends Participant {
@@ -28,13 +29,13 @@ export default class LocalParticipant extends Participant {
28
29
  private roomOptions;
29
30
  private encryptionType;
30
31
  private reconnectFuture?;
32
+ private rpcHandlers;
31
33
  private pendingSignalRequests;
32
34
  private enabledPublishVideoCodecs;
33
- private rpcHandlers;
34
35
  private pendingAcks;
35
36
  private pendingResponses;
36
37
  /** @internal */
37
- constructor(sid: string, identity: string, engine: RTCEngine, options: InternalRoomOptions);
38
+ constructor(sid: string, identity: string, engine: RTCEngine, options: InternalRoomOptions, roomRpcHandlers: Map<string, (data: RpcInvocationData) => Promise<string>>);
38
39
  get lastCameraError(): Error | undefined;
39
40
  get lastMicrophoneError(): Error | undefined;
40
41
  get isE2EEEnabled(): boolean;
@@ -148,13 +149,29 @@ export default class LocalParticipant extends Participant {
148
149
  * @param digit DTMF digit
149
150
  */
150
151
  publishDtmf(code: number, digit: string): Promise<void>;
151
- sendChatMessage(text: string): Promise<ChatMessage>;
152
+ sendChatMessage(text: string, options?: SendTextOptions): Promise<ChatMessage>;
152
153
  editChatMessage(editText: string, originalMessage: ChatMessage): Promise<{
153
154
  readonly message: string;
154
155
  readonly editTimestamp: number;
155
156
  readonly id: string;
156
157
  readonly timestamp: number;
158
+ readonly attachedFiles?: Array<File>;
159
+ }>;
160
+ sendText(text: string, options?: SendTextOptions): Promise<TextStreamInfo>;
161
+ /**
162
+ * @internal
163
+ * @experimental CAUTION, might get removed in a minor release
164
+ */
165
+ streamText(options?: StreamTextOptions): Promise<TextStreamWriter>;
166
+ sendFile(file: File, options?: {
167
+ mimeType?: string;
168
+ topic?: string;
169
+ destinationIdentities?: Array<string>;
170
+ onProgress?: (progress: number) => void;
171
+ }): Promise<{
172
+ id: string;
157
173
  }>;
174
+ private _sendFile;
158
175
  /**
159
176
  * Initiate an RPC call to a remote participant
160
177
  * @param params - Parameters for initiating the RPC call, see {@link PerformRpcParams}
@@ -163,36 +180,11 @@ export default class LocalParticipant extends Participant {
163
180
  */
164
181
  performRpc({ destinationIdentity, method, payload, responseTimeout, }: PerformRpcParams): Promise<string>;
165
182
  /**
166
- * Establishes the participant as a receiver for calls of the specified RPC method.
167
- * Will overwrite any existing callback for the same method.
168
- *
169
- * @param method - The name of the indicated RPC method
170
- * @param handler - Will be invoked when an RPC request for this method is received
171
- * @returns A promise that resolves when the method is successfully registered
172
- *
173
- * @example
174
- * ```typescript
175
- * room.localParticipant?.registerRpcMethod(
176
- * 'greet',
177
- * async (data: RpcInvocationData) => {
178
- * console.log(`Received greeting from ${data.callerIdentity}: ${data.payload}`);
179
- * return `Hello, ${data.callerIdentity}!`;
180
- * }
181
- * );
182
- * ```
183
- *
184
- * The handler should return a Promise that resolves to a string.
185
- * If unable to respond within `responseTimeout`, the request will result in an error on the caller's side.
186
- *
187
- * You may throw errors of type `RpcError` with a string `message` in the handler,
188
- * and they will be received on the caller's side with the message intact.
189
- * Other errors thrown in your handler will not be transmitted as-is, and will instead arrive to the caller as `1500` ("Application Error").
183
+ * @deprecated use `room.registerRpcMethod` instead
190
184
  */
191
185
  registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>): void;
192
186
  /**
193
- * Unregisters a previously registered RPC method.
194
- *
195
- * @param method - The name of the RPC method to unregister
187
+ * @deprecated use `room.unregisterRpcMethod` instead
196
188
  */
197
189
  unregisterRpcMethod(method: string): void;
198
190
  /**
@@ -215,14 +207,9 @@ export default class LocalParticipant extends Participant {
215
207
  setTrackSubscriptionPermissions(allParticipantsAllowed: boolean, participantTrackPermissions?: ParticipantTrackPermission[]): void;
216
208
  private handleIncomingRpcAck;
217
209
  private handleIncomingRpcResponse;
218
- private handleIncomingRpcRequest;
219
210
  /** @internal */
220
211
  private publishRpcRequest;
221
212
  /** @internal */
222
- private publishRpcResponse;
223
- /** @internal */
224
- private publishRpcAck;
225
- /** @internal */
226
213
  handleParticipantDisconnected(participantIdentity: string): void;
227
214
  /** @internal */
228
215
  setEnabledPublishCodecs(codecs: Codec[]): void;
@@ -38,6 +38,7 @@ export default abstract class LocalTrack<TrackKind extends Track.Kind = Track.Ki
38
38
  get isUpstreamPaused(): boolean;
39
39
  get isUserProvided(): boolean;
40
40
  get mediaStreamTrack(): MediaStreamTrack;
41
+ get isLocal(): boolean;
41
42
  /**
42
43
  * @internal
43
44
  * returns mediaStreamTrack settings of the capturing mediastreamtrack source - ignoring processors
@@ -15,6 +15,7 @@ export default class LocalTrackPublication extends TrackPublication {
15
15
  get isMuted(): boolean;
16
16
  get audioTrack(): LocalAudioTrack | undefined;
17
17
  get videoTrack(): LocalVideoTrack | undefined;
18
+ get isLocal(): boolean;
18
19
  /**
19
20
  * Mute the track associated with this publication
20
21
  */
@@ -4,6 +4,7 @@ export default abstract class RemoteTrack<TrackKind extends Track.Kind = Track.K
4
4
  /** @internal */
5
5
  receiver: RTCRtpReceiver | undefined;
6
6
  constructor(mediaTrack: MediaStreamTrack, sid: string, kind: TrackKind, receiver: RTCRtpReceiver, loggerOptions?: LoggerOptions);
7
+ get isLocal(): boolean;
7
8
  /** @internal */
8
9
  setMuted(muted: boolean): void;
9
10
  /** @internal */
@@ -27,6 +27,7 @@ export default class RemoteTrackPublication extends TrackPublication {
27
27
  get isSubscribed(): boolean;
28
28
  get isDesired(): boolean;
29
29
  get isEnabled(): boolean;
30
+ get isLocal(): boolean;
30
31
  /**
31
32
  * disable server from sending down data for this track. this is useful when
32
33
  * the participant is off screen, you may disable streaming down their video
@@ -46,6 +46,7 @@ export declare abstract class Track<TrackKind extends Track.Kind = Track.Kind> e
46
46
  /** current receive bits per second */
47
47
  get currentBitrate(): number;
48
48
  get mediaStreamTrack(): MediaStreamTrack;
49
+ abstract get isLocal(): boolean;
49
50
  /**
50
51
  * @internal
51
52
  * used for keep mediaStream's first id, since it's id might change
@@ -9,7 +9,7 @@ import type RemoteTrack from './RemoteTrack';
9
9
  import RemoteVideoTrack from './RemoteVideoTrack';
10
10
  import { Track } from './Track';
11
11
  declare const TrackPublication_base: new () => TypedEventEmitter<PublicationEventCallbacks>;
12
- export declare class TrackPublication extends TrackPublication_base {
12
+ export declare abstract class TrackPublication extends TrackPublication_base {
13
13
  kind: Track.Kind;
14
14
  trackName: string;
15
15
  trackSid: Track.SID;
@@ -37,6 +37,7 @@ export declare class TrackPublication extends TrackPublication_base {
37
37
  get isEnabled(): boolean;
38
38
  get isSubscribed(): boolean;
39
39
  get isEncrypted(): boolean;
40
+ abstract get isLocal(): boolean;
40
41
  /**
41
42
  * an [AudioTrack] if this publication holds an audio track
42
43
  */
@@ -6,8 +6,7 @@ export interface TrackPublishDefaults {
6
6
  */
7
7
  videoEncoding?: VideoEncoding;
8
8
  /**
9
- * Multi-codec Simulcast
10
- * VP9 and AV1 are not supported by all browser clients. When backupCodec is
9
+ * Advanced codecs (VP9/AV1/H265) are not supported by all browser clients. When backupCodec is
11
10
  * set, when an incompatible client attempts to subscribe to the track, LiveKit
12
11
  * will automatically publish a secondary track encoded with the backup codec.
13
12
  *
@@ -20,6 +19,19 @@ export interface TrackPublishDefaults {
20
19
  codec: BackupVideoCodec;
21
20
  encoding?: VideoEncoding;
22
21
  };
22
+ /**
23
+ * When backup codec is enabled, there are two options to decide whether to
24
+ * send the primary codec at the same time:
25
+ * * codec regression: publisher stops sending primary codec and all subscribers
26
+ * will receive backup codec even if the primary codec is supported on their browser. It is the default
27
+ * behavior and provides maximum compatibility. It also reduces CPU
28
+ * and bandwidth consumption for publisher.
29
+ * * multi-codec simulcast: publisher encodes and sends both codecs at same time,
30
+ * subscribers will get most efficient codec. It will provide most bandwidth
31
+ * efficiency, especially in the large 1:N room but requires more device performance
32
+ * and bandwidth consumption for publisher.
33
+ */
34
+ backupCodecPolicy?: BackupCodecPolicy;
23
35
  /**
24
36
  * encoding parameters for screen share track
25
37
  */
@@ -280,6 +292,10 @@ export declare const videoCodecs: readonly [
280
292
  export type VideoCodec = (typeof videoCodecs)[number];
281
293
  export type BackupVideoCodec = (typeof backupCodecs)[number];
282
294
  export declare function isBackupCodec(codec: string): codec is BackupVideoCodec;
295
+ export declare enum BackupCodecPolicy {
296
+ REGRESSION = 0,
297
+ SIMULCAST = 1
298
+ }
283
299
  /**
284
300
  * scalability modes for svc.
285
301
  */
@@ -1,3 +1,4 @@
1
+ import type { DataStream_Chunk } from '@livekit/protocol';
1
2
  export type SimulationOptions = {
2
3
  publish?: {
3
4
  audio?: boolean;
@@ -11,6 +12,22 @@ export type SimulationOptions = {
11
12
  video?: boolean;
12
13
  };
13
14
  };
15
+ export interface SendTextOptions {
16
+ topic?: string;
17
+ destinationIdentities?: Array<string>;
18
+ attachments?: Array<File>;
19
+ onProgress?: (progress: number) => void;
20
+ }
21
+ export interface StreamTextOptions {
22
+ topic?: string;
23
+ destinationIdentities?: Array<string>;
24
+ type?: 'create' | 'update';
25
+ streamId?: string;
26
+ version?: number;
27
+ attachedStreamIds?: Array<string>;
28
+ replyToStreamId?: string;
29
+ totalSize?: number;
30
+ }
14
31
  export type DataPublishOptions = {
15
32
  /**
16
33
  * whether to send this as reliable or lossy.
@@ -50,5 +67,31 @@ export interface ChatMessage {
50
67
  timestamp: number;
51
68
  message: string;
52
69
  editTimestamp?: number;
70
+ attachedFiles?: Array<File>;
71
+ }
72
+ export interface StreamController<T extends DataStream_Chunk> {
73
+ info: BaseStreamInfo;
74
+ controller: ReadableStreamDefaultController<T>;
75
+ startTime: number;
76
+ endTime?: number;
53
77
  }
78
+ export interface BaseStreamInfo {
79
+ id: string;
80
+ mimeType: string;
81
+ topic: string;
82
+ timestamp: number;
83
+ /** total size in bytes for finite streams and undefined for streams of unknown size */
84
+ size?: number;
85
+ attributes?: Record<string, string>;
86
+ }
87
+ export interface ByteStreamInfo extends BaseStreamInfo {
88
+ name: string;
89
+ }
90
+ export interface TextStreamInfo extends BaseStreamInfo {
91
+ }
92
+ export type TextStreamChunk = {
93
+ index: number;
94
+ current: string;
95
+ collected: string;
96
+ };
54
97
  //# sourceMappingURL=types.d.ts.map
@@ -1,7 +1,18 @@
1
1
  import { ChatMessage as ChatMessageModel, ClientInfo, DisconnectReason, Transcription as TranscriptionModel } from '@livekit/protocol';
2
2
  import type { ConnectionError } from './errors';
3
+ import type LocalParticipant from './participant/LocalParticipant';
4
+ import type Participant from './participant/Participant';
5
+ import type RemoteParticipant from './participant/RemoteParticipant';
3
6
  import type LocalAudioTrack from './track/LocalAudioTrack';
7
+ import type LocalTrack from './track/LocalTrack';
8
+ import type LocalTrackPublication from './track/LocalTrackPublication';
9
+ import type LocalVideoTrack from './track/LocalVideoTrack';
4
10
  import type RemoteAudioTrack from './track/RemoteAudioTrack';
11
+ import type RemoteTrack from './track/RemoteTrack';
12
+ import type RemoteTrackPublication from './track/RemoteTrackPublication';
13
+ import type RemoteVideoTrack from './track/RemoteVideoTrack';
14
+ import { Track } from './track/Track';
15
+ import type { TrackPublication } from './track/TrackPublication';
5
16
  import type { VideoCodec } from './track/options';
6
17
  import type { ChatMessage, TranscriptionSegment } from './types';
7
18
  export declare const ddExtensionURI = "https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension";
@@ -89,4 +100,19 @@ export declare function toHttpUrl(url: string): string;
89
100
  export declare function extractTranscriptionSegments(transcription: TranscriptionModel, firstReceivedTimesMap: Map<string, number>): TranscriptionSegment[];
90
101
  export declare function extractChatMessage(msg: ChatMessageModel): ChatMessage;
91
102
  export declare function getDisconnectReasonFromConnectionError(e: ConnectionError): DisconnectReason;
103
+ /** convert bigints to numbers preserving undefined values */
104
+ export declare function bigIntToNumber<T extends BigInt | undefined>(value: T): T extends BigInt ? number : undefined;
105
+ /** convert numbers to bigints preserving undefined values */
106
+ export declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
107
+ export declare function isLocalTrack(track: Track | MediaStreamTrack | undefined): track is LocalTrack;
108
+ export declare function isAudioTrack(track: Track | undefined): track is LocalAudioTrack | RemoteAudioTrack;
109
+ export declare function isVideoTrack(track: Track | undefined): track is LocalVideoTrack | RemoteVideoTrack;
110
+ export declare function isLocalVideoTrack(track: Track | MediaStreamTrack | undefined): track is LocalVideoTrack;
111
+ export declare function isLocalAudioTrack(track: Track | MediaStreamTrack | undefined): track is LocalAudioTrack;
112
+ export declare function isRemoteTrack(track: Track | undefined): track is RemoteTrack;
113
+ export declare function isRemotePub(pub: TrackPublication | undefined): pub is RemoteTrackPublication;
114
+ export declare function isLocalPub(pub: TrackPublication | undefined): pub is LocalTrackPublication;
115
+ export declare function isRemoteVideoTrack(track: Track | undefined): track is RemoteVideoTrack;
116
+ export declare function isLocalParticipant(p: Participant): p is LocalParticipant;
117
+ export declare function isRemoteParticipant(p: Participant): p is RemoteParticipant;
92
118
  //# sourceMappingURL=utils.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livekit-client",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
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",
@@ -37,7 +37,7 @@
37
37
  "license": "Apache-2.0",
38
38
  "dependencies": {
39
39
  "@livekit/mutex": "1.1.1",
40
- "@livekit/protocol": "1.30.0",
40
+ "@livekit/protocol": "1.33.0",
41
41
  "events": "^3.3.0",
42
42
  "loglevel": "^1.8.0",
43
43
  "sdp-transform": "^2.14.1",
@@ -81,7 +81,7 @@
81
81
  "typedoc": "0.27.6",
82
82
  "typedoc-plugin-no-inherit": "1.4.0",
83
83
  "typescript": "5.7.2",
84
- "vite": "5.4.11",
84
+ "vite": "5.4.12",
85
85
  "vitest": "^1.0.0"
86
86
  },
87
87
  "scripts": {
@@ -294,7 +294,10 @@ export class SignalClient {
294
294
  abortHandler();
295
295
  }
296
296
  abortSignal?.addEventListener('abort', abortHandler);
297
- this.log.debug(`connecting to ${url + params}`, this.logContext);
297
+ this.log.debug(
298
+ `connecting to ${url + params.replace(/access_token=([^&#$]*)/, 'access_token=<redacted>')}`,
299
+ this.logContext,
300
+ );
298
301
  if (this.ws) {
299
302
  await this.close(false);
300
303
  }
@@ -326,7 +329,7 @@ export class SignalClient {
326
329
  } catch (e) {
327
330
  reject(
328
331
  new ConnectionError(
329
- 'server was not reachable',
332
+ e instanceof Error ? e.message : 'server was not reachable',
330
333
  ConnectionErrorReason.ServerUnreachable,
331
334
  ),
332
335
  );
@@ -7,11 +7,11 @@ import type Room from '../room/Room';
7
7
  import { ConnectionState } from '../room/Room';
8
8
  import { DeviceUnsupportedError } from '../room/errors';
9
9
  import { EngineEvent, ParticipantEvent, RoomEvent } from '../room/events';
10
- import LocalTrack from '../room/track/LocalTrack';
11
10
  import type RemoteTrack from '../room/track/RemoteTrack';
12
11
  import type { Track } from '../room/track/Track';
13
12
  import type { VideoCodec } from '../room/track/options';
14
13
  import { mimeTypeToVideoCodecString } from '../room/track/utils';
14
+ import { isLocalTrack } from '../room/utils';
15
15
  import type { BaseKeyProvider } from './KeyProvider';
16
16
  import { E2EE_FLAG } from './constants';
17
17
  import { type E2EEManagerCallbacks, EncryptionEvent, KeyProviderEvent } from './events';
@@ -317,7 +317,7 @@ export class E2EEManager
317
317
  }
318
318
 
319
319
  private setupE2EESender(track: Track, sender: RTCRtpSender) {
320
- if (!(track instanceof LocalTrack) || !sender) {
320
+ if (!isLocalTrack(track) || !sender) {
321
321
  if (!sender) log.warn('early return because sender is not ready');
322
322
  return;
323
323
  }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Mutex } from '@livekit/mutex';
2
- import { DataPacket_Kind, DisconnectReason, SubscriptionError } from '@livekit/protocol';
2
+ import { DataPacket_Kind, DisconnectReason, SubscriptionError, TrackType } from '@livekit/protocol';
3
3
  import { LogLevel, LoggerNames, getLogger, setLogExtension, setLogLevel } from './logger';
4
4
  import DefaultReconnectPolicy from './room/DefaultReconnectPolicy';
5
5
  import type { ReconnectContext, ReconnectPolicy } from './room/ReconnectPolicy';
@@ -32,7 +32,13 @@ import {
32
32
  createAudioAnalyser,
33
33
  getEmptyAudioStreamTrack,
34
34
  getEmptyVideoStreamTrack,
35
+ isAudioTrack,
35
36
  isBrowserSupported,
37
+ isLocalParticipant,
38
+ isLocalTrack,
39
+ isRemoteParticipant,
40
+ isRemoteTrack,
41
+ isVideoTrack,
36
42
  supportsAV1,
37
43
  supportsAdaptiveStream,
38
44
  supportsDynacast,
@@ -55,11 +61,14 @@ export { facingModeFromDeviceLabel, facingModeFromLocalTrack } from './room/trac
55
61
  export * from './room/track/options';
56
62
  export * from './room/track/processor/types';
57
63
  export * from './room/track/types';
64
+ export type * from './room/StreamReader';
65
+ export type * from './room/StreamWriter';
58
66
  export type {
59
67
  DataPublishOptions,
60
68
  SimulationScenario,
61
69
  TranscriptionSegment,
62
70
  ChatMessage,
71
+ SendTextOptions,
63
72
  } from './room/types';
64
73
  export * from './version';
65
74
  export {
@@ -100,6 +109,12 @@ export {
100
109
  supportsDynacast,
101
110
  supportsVP9,
102
111
  Mutex,
112
+ isAudioTrack,
113
+ isLocalTrack,
114
+ isRemoteTrack,
115
+ isVideoTrack,
116
+ isLocalParticipant,
117
+ isRemoteParticipant,
103
118
  };
104
119
  export type {
105
120
  AudioAnalyserOptions,
@@ -112,4 +127,5 @@ export type {
112
127
  VideoSenderStats,
113
128
  ReconnectContext,
114
129
  ReconnectPolicy,
130
+ TrackType,
115
131
  };
@@ -16,6 +16,8 @@ import {
16
16
  type ReconnectResponse,
17
17
  RequestResponse,
18
18
  Room as RoomModel,
19
+ RpcAck,
20
+ RpcResponse,
19
21
  SignalTarget,
20
22
  SpeakerInfo,
21
23
  type StreamStateUpdate,
@@ -54,6 +56,7 @@ import {
54
56
  UnexpectedConnectionState,
55
57
  } from './errors';
56
58
  import { EngineEvent } from './events';
59
+ import { RpcError } from './rpc';
57
60
  import CriticalTimers from './timers';
58
61
  import type LocalTrack from './track/LocalTrack';
59
62
  import type LocalTrackPublication from './track/LocalTrackPublication';
@@ -64,7 +67,14 @@ import type { Track } from './track/Track';
64
67
  import type { TrackPublishOptions, VideoCodec } from './track/options';
65
68
  import { getTrackPublicationInfo } from './track/utils';
66
69
  import type { LoggerOptions } from './types';
67
- import { isVideoCodec, isWeb, sleep, supportsAddTrack, supportsTransceiver } from './utils';
70
+ import {
71
+ isVideoCodec,
72
+ isVideoTrack,
73
+ isWeb,
74
+ sleep,
75
+ supportsAddTrack,
76
+ supportsTransceiver,
77
+ } from './utils';
68
78
 
69
79
  const lossyDataChannel = '_lossy';
70
80
  const reliableDataChannel = '_reliable';
@@ -657,6 +667,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
657
667
  return;
658
668
  }
659
669
  const dp = DataPacket.fromBinary(new Uint8Array(buffer));
670
+
660
671
  if (dp.value?.case === 'speaker') {
661
672
  // dispatch speaker updates
662
673
  this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.value.speakers);
@@ -745,7 +756,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
745
756
  streams.push(track.mediaStream);
746
757
  }
747
758
 
748
- if (track instanceof LocalVideoTrack) {
759
+ if (isVideoTrack(track)) {
749
760
  track.codec = opts.videoCodec;
750
761
  }
751
762
 
@@ -1089,6 +1100,46 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1089
1100
  });
1090
1101
  };
1091
1102
 
1103
+ /** @internal */
1104
+ async publishRpcResponse(
1105
+ destinationIdentity: string,
1106
+ requestId: string,
1107
+ payload: string | null,
1108
+ error: RpcError | null,
1109
+ ) {
1110
+ const packet = new DataPacket({
1111
+ destinationIdentities: [destinationIdentity],
1112
+ kind: DataPacket_Kind.RELIABLE,
1113
+ value: {
1114
+ case: 'rpcResponse',
1115
+ value: new RpcResponse({
1116
+ requestId,
1117
+ value: error
1118
+ ? { case: 'error', value: error.toProto() }
1119
+ : { case: 'payload', value: payload ?? '' },
1120
+ }),
1121
+ },
1122
+ });
1123
+
1124
+ await this.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
1125
+ }
1126
+
1127
+ /** @internal */
1128
+ async publishRpcAck(destinationIdentity: string, requestId: string) {
1129
+ const packet = new DataPacket({
1130
+ destinationIdentities: [destinationIdentity],
1131
+ kind: DataPacket_Kind.RELIABLE,
1132
+ value: {
1133
+ case: 'rpcAck',
1134
+ value: new RpcAck({
1135
+ requestId,
1136
+ }),
1137
+ },
1138
+ });
1139
+
1140
+ await this.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
1141
+ }
1142
+
1092
1143
  /* @internal */
1093
1144
  async sendDataPacket(packet: DataPacket, kind: DataPacket_Kind) {
1094
1145
  const msg = packet.toBinary();
@@ -1119,6 +1170,22 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1119
1170
  }
1120
1171
  };
1121
1172
 
1173
+ waitForBufferStatusLow(kind: DataPacket_Kind): Promise<void> {
1174
+ return new Promise(async (resolve, reject) => {
1175
+ if (this.isBufferStatusLow(kind)) {
1176
+ resolve();
1177
+ } else {
1178
+ const onClosing = () => reject('Engine closed');
1179
+ this.once(EngineEvent.Closing, onClosing);
1180
+ while (!this.dcBufferStatus.get(kind)) {
1181
+ await sleep(10);
1182
+ }
1183
+ this.off(EngineEvent.Closing, onClosing);
1184
+ resolve();
1185
+ }
1186
+ });
1187
+ }
1188
+
1122
1189
  /**
1123
1190
  * @internal
1124
1191
  */