livekit-client 2.8.0 → 2.9.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.
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
  */