@livekit/rtc-node 0.3.0 → 0.4.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.
Files changed (70) hide show
  1. package/Cargo.toml +2 -1
  2. package/README.md +81 -0
  3. package/dist/audio_frame.d.ts +2 -1
  4. package/dist/audio_frame.d.ts.map +1 -1
  5. package/dist/audio_frame.js +3 -3
  6. package/dist/audio_frame.js.map +1 -1
  7. package/dist/audio_source.d.ts +2 -2
  8. package/dist/audio_source.d.ts.map +1 -1
  9. package/dist/audio_source.js +6 -9
  10. package/dist/audio_source.js.map +1 -1
  11. package/dist/audio_stream.d.ts +3 -3
  12. package/dist/audio_stream.d.ts.map +1 -1
  13. package/dist/audio_stream.js +6 -6
  14. package/dist/audio_stream.js.map +1 -1
  15. package/dist/e2ee.d.ts.map +1 -1
  16. package/dist/e2ee.js +16 -16
  17. package/dist/e2ee.js.map +1 -1
  18. package/dist/ffi_client.d.ts +3 -3
  19. package/dist/ffi_client.d.ts.map +1 -1
  20. package/dist/ffi_client.js +8 -11
  21. package/dist/ffi_client.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/napi/native.js +1 -2
  27. package/dist/participant.d.ts +5 -4
  28. package/dist/participant.d.ts.map +1 -1
  29. package/dist/participant.js +15 -15
  30. package/dist/participant.js.map +1 -1
  31. package/dist/room.d.ts +25 -22
  32. package/dist/room.d.ts.map +1 -1
  33. package/dist/room.js +57 -55
  34. package/dist/room.js.map +1 -1
  35. package/dist/track.d.ts +3 -3
  36. package/dist/track.d.ts.map +1 -1
  37. package/dist/track.js +5 -8
  38. package/dist/track.js.map +1 -1
  39. package/dist/track_publication.d.ts +3 -3
  40. package/dist/track_publication.d.ts.map +1 -1
  41. package/dist/track_publication.js +1 -1
  42. package/dist/track_publication.js.map +1 -1
  43. package/dist/video_frame.d.ts +2 -1
  44. package/dist/video_frame.d.ts.map +1 -1
  45. package/dist/video_frame.js +1 -1
  46. package/dist/video_frame.js.map +1 -1
  47. package/dist/video_source.d.ts +3 -2
  48. package/dist/video_source.d.ts.map +1 -1
  49. package/dist/video_source.js +3 -3
  50. package/dist/video_source.js.map +1 -1
  51. package/dist/video_stream.d.ts +3 -3
  52. package/dist/video_stream.d.ts.map +1 -1
  53. package/dist/video_stream.js +8 -8
  54. package/dist/video_stream.js.map +1 -1
  55. package/package.json +9 -9
  56. package/src/audio_frame.ts +5 -5
  57. package/src/audio_source.ts +13 -14
  58. package/src/audio_stream.ts +13 -17
  59. package/src/e2ee.ts +25 -24
  60. package/src/ffi_client.ts +10 -11
  61. package/src/index.ts +1 -3
  62. package/src/napi/native.js +1 -2
  63. package/src/nodejs.rs +4 -2
  64. package/src/participant.ts +27 -29
  65. package/src/room.ts +93 -91
  66. package/src/track.ts +9 -11
  67. package/src/track_publication.ts +7 -7
  68. package/src/video_frame.ts +9 -16
  69. package/src/video_source.ts +10 -9
  70. package/src/video_stream.ts +17 -18
package/src/nodejs.rs CHANGED
@@ -16,8 +16,8 @@ use prost::Message;
16
16
  use std::sync::Arc;
17
17
 
18
18
  #[napi(ts_args_type = "callback: (data: Uint8Array) => void, captureLogs: boolean")]
19
- fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
20
- let tsfn: ThreadsafeFunction<proto::FfiEvent, ErrorStrategy::Fatal> = cb
19
+ fn livekit_initialize(env: Env, cb: JsFunction, capture_logs: bool) {
20
+ let mut tsfn: ThreadsafeFunction<proto::FfiEvent, ErrorStrategy::Fatal> = cb
21
21
  .create_threadsafe_function(0, |ctx: ThreadSafeCallContext<proto::FfiEvent>| {
22
22
  let data = ctx.value.encode_to_vec();
23
23
  let buf = Uint8Array::new(data);
@@ -25,6 +25,8 @@ fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
25
25
  })
26
26
  .unwrap();
27
27
 
28
+ let _ = tsfn.unref(&env);
29
+
28
30
  FFI_SERVER.setup(server::FfiConfig {
29
31
  callback_fn: Arc::new(move |event| {
30
32
  let status = tsfn.call(event, ThreadsafeFunctionCallMode::NonBlocking);
@@ -1,34 +1,32 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
-
5
- import { FfiClient, FfiClientEvent, FfiHandle, FfiRequest } from './ffi_client.js';
6
- import { ParticipantInfo, OwnedParticipant } from './proto/participant_pb.js';
7
- import {
8
- DataPacketKind,
4
+ import { FfiClient, FfiHandle } from './ffi_client.js';
5
+ import type { OwnedParticipant, ParticipantInfo } from './proto/participant_pb.js';
6
+ import type {
9
7
  PublishDataCallback,
10
- PublishDataRequest,
11
8
  PublishDataResponse,
12
9
  PublishTrackCallback,
13
- PublishTrackRequest,
14
10
  PublishTrackResponse,
15
11
  TrackPublishOptions,
16
12
  UnpublishTrackCallback,
17
- UnpublishTrackRequest,
18
13
  UnpublishTrackResponse,
19
14
  UpdateLocalMetadataCallback,
20
- UpdateLocalMetadataRequest,
21
15
  UpdateLocalMetadataResponse,
22
16
  UpdateLocalNameCallback,
23
- UpdateLocalNameRequest,
24
17
  UpdateLocalNameResponse,
25
18
  } from './proto/room_pb.js';
26
19
  import {
27
- LocalTrackPublication,
28
- RemoteTrackPublication,
29
- TrackPublication,
30
- } from './track_publication.js';
31
- import { LocalTrack } from './track.js';
20
+ DataPacketKind,
21
+ PublishDataRequest,
22
+ PublishTrackRequest,
23
+ UnpublishTrackRequest,
24
+ UpdateLocalMetadataRequest,
25
+ UpdateLocalNameRequest,
26
+ } from './proto/room_pb.js';
27
+ import type { LocalTrack } from './track.js';
28
+ import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
29
+ import { LocalTrackPublication } from './track_publication.js';
32
30
 
33
31
  export abstract class Participant {
34
32
  /** @internal */
@@ -81,7 +79,7 @@ export class LocalParticipant extends Participant {
81
79
  trackPublications: Map<string, LocalTrackPublication> = new Map();
82
80
 
83
81
  async publishData(data: Uint8Array, options: DataPublishOptions) {
84
- let req = new PublishDataRequest({
82
+ const req = new PublishDataRequest({
85
83
  localParticipantHandle: this.ffi_handle.handle,
86
84
  dataPtr: FfiClient.instance.retrievePtr(data),
87
85
  dataLen: BigInt(data.byteLength),
@@ -97,11 +95,11 @@ export class LocalParticipant extends Participant {
97
95
  req.destinationSids = sids;
98
96
  }
99
97
 
100
- let res = FfiClient.instance.request<PublishDataResponse>({
98
+ const res = FfiClient.instance.request<PublishDataResponse>({
101
99
  message: { case: 'publishData', value: req },
102
100
  });
103
101
 
104
- let cb = await FfiClient.instance.waitFor<PublishDataCallback>((ev) => {
102
+ const cb = await FfiClient.instance.waitFor<PublishDataCallback>((ev) => {
105
103
  return ev.message.case == 'publishData' && ev.message.value.asyncId == res.asyncId;
106
104
  });
107
105
 
@@ -111,12 +109,12 @@ export class LocalParticipant extends Participant {
111
109
  }
112
110
 
113
111
  async updateMetadata(metadata: string) {
114
- let req = new UpdateLocalMetadataRequest({
112
+ const req = new UpdateLocalMetadataRequest({
115
113
  localParticipantHandle: this.ffi_handle.handle,
116
114
  metadata: metadata,
117
115
  });
118
116
 
119
- let res = FfiClient.instance.request<UpdateLocalMetadataResponse>({
117
+ const res = FfiClient.instance.request<UpdateLocalMetadataResponse>({
120
118
  message: { case: 'updateLocalMetadata', value: req },
121
119
  });
122
120
 
@@ -126,12 +124,12 @@ export class LocalParticipant extends Participant {
126
124
  }
127
125
 
128
126
  async updateName(name: string) {
129
- let req = new UpdateLocalNameRequest({
127
+ const req = new UpdateLocalNameRequest({
130
128
  localParticipantHandle: this.ffi_handle.handle,
131
129
  name: name,
132
130
  });
133
131
 
134
- let res = FfiClient.instance.request<UpdateLocalNameResponse>({
132
+ const res = FfiClient.instance.request<UpdateLocalNameResponse>({
135
133
  message: { case: 'updateLocalName', value: req },
136
134
  });
137
135
 
@@ -144,21 +142,21 @@ export class LocalParticipant extends Participant {
144
142
  track: LocalTrack,
145
143
  options: TrackPublishOptions,
146
144
  ): Promise<LocalTrackPublication> {
147
- let req = new PublishTrackRequest({
145
+ const req = new PublishTrackRequest({
148
146
  localParticipantHandle: this.ffi_handle.handle,
149
147
  trackHandle: track.ffi_handle.handle,
150
148
  options: options,
151
149
  });
152
150
 
153
- let res = FfiClient.instance.request<PublishTrackResponse>({
151
+ const res = FfiClient.instance.request<PublishTrackResponse>({
154
152
  message: { case: 'publishTrack', value: req },
155
153
  });
156
154
 
157
- let cb = await FfiClient.instance.waitFor<PublishTrackCallback>((ev) => {
155
+ const cb = await FfiClient.instance.waitFor<PublishTrackCallback>((ev) => {
158
156
  return ev.message.case == 'publishTrack' && ev.message.value.asyncId == res.asyncId;
159
157
  });
160
158
 
161
- let track_publication = new LocalTrackPublication(cb.publication);
159
+ const track_publication = new LocalTrackPublication(cb.publication);
162
160
  track_publication.track = track;
163
161
  this.trackPublications.set(track_publication.sid, track_publication);
164
162
 
@@ -166,12 +164,12 @@ export class LocalParticipant extends Participant {
166
164
  }
167
165
 
168
166
  async unpublishTrack(trackSid: string) {
169
- let req = new UnpublishTrackRequest({
167
+ const req = new UnpublishTrackRequest({
170
168
  localParticipantHandle: this.ffi_handle.handle,
171
169
  trackSid: trackSid,
172
170
  });
173
171
 
174
- let res = FfiClient.instance.request<UnpublishTrackResponse>({
172
+ const res = FfiClient.instance.request<UnpublishTrackResponse>({
175
173
  message: { case: 'unpublishTrack', value: req },
176
174
  });
177
175
 
@@ -179,7 +177,7 @@ export class LocalParticipant extends Participant {
179
177
  return ev.message.case == 'unpublishTrack' && ev.message.value.asyncId == res.asyncId;
180
178
  });
181
179
 
182
- let pub = this.trackPublications.get(trackSid);
180
+ const pub = this.trackPublications.get(trackSid);
183
181
  pub.track = undefined;
184
182
  this.trackPublications.delete(trackSid);
185
183
  }
package/src/room.ts CHANGED
@@ -1,35 +1,36 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
-
5
- import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
6
4
  import EventEmitter from 'events';
7
- import TypedEmitter from 'typed-emitter';
8
- import { FfiEvent } from './proto/ffi_pb.js';
9
- import { LocalParticipant, Participant, RemoteParticipant } from './participant.js';
10
- import {
5
+ import type TypedEmitter from 'typed-emitter';
6
+ import type { E2EEOptions } from './e2ee.js';
7
+ import { E2EEManager } from './e2ee.js';
8
+ import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
9
+ import type { Participant } from './participant.js';
10
+ import { LocalParticipant, RemoteParticipant } from './participant.js';
11
+ import { EncryptionState } from './proto/e2ee_pb.js';
12
+ import type { FfiEvent } from './proto/ffi_pb.js';
13
+ import type { OwnedParticipant } from './proto/participant_pb.js';
14
+ import type {
11
15
  ConnectCallback,
12
- ConnectRequest,
13
16
  ConnectResponse,
14
17
  ConnectionQuality,
15
- ConnectionState,
16
- ContinualGatheringPolicy,
17
18
  DataPacketKind,
18
19
  DisconnectResponse,
19
20
  IceServer,
20
- IceTransportType,
21
21
  RoomInfo,
22
22
  } from './proto/room_pb.js';
23
- import { E2EEManager, E2EEOptions, defaultE2EEOptions } from './e2ee.js';
24
- import { OwnedParticipant } from './proto/participant_pb.js';
25
23
  import {
26
- LocalTrackPublication,
27
- RemoteTrackPublication,
28
- TrackPublication,
29
- } from './track_publication.js';
30
- import { LocalTrack, RemoteAudioTrack, RemoteTrack, RemoteVideoTrack } from './track.js';
24
+ ConnectRequest,
25
+ ConnectionState,
26
+ ContinualGatheringPolicy,
27
+ IceTransportType,
28
+ } from './proto/room_pb.js';
31
29
  import { TrackKind } from './proto/track_pb.js';
32
- import { EncryptionState } from './proto/e2ee_pb.js';
30
+ import type { RemoteTrack } from './track.js';
31
+ import { RemoteAudioTrack, RemoteVideoTrack } from './track.js';
32
+ import type { LocalTrackPublication, TrackPublication } from './track_publication.js';
33
+ import { RemoteTrackPublication } from './track_publication.js';
33
34
 
34
35
  export interface RtcConfiguration {
35
36
  iceTransportType: IceTransportType;
@@ -90,7 +91,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
90
91
  async connect(url: string, token: string, opts?: RoomOptions) {
91
92
  const options = { ...defaultRoomOptions, ...opts };
92
93
 
93
- let req = new ConnectRequest({
94
+ const req = new ConnectRequest({
94
95
  url: url,
95
96
  token: token,
96
97
  options: {
@@ -108,14 +109,14 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
108
109
  },
109
110
  });
110
111
 
111
- let res = FfiClient.instance.request<ConnectResponse>({
112
+ const res = FfiClient.instance.request<ConnectResponse>({
112
113
  message: {
113
114
  case: 'connect',
114
115
  value: req,
115
116
  },
116
117
  });
117
118
 
118
- let cb = await FfiClient.instance.waitFor<ConnectCallback>((ev: FfiEvent) => {
119
+ const cb = await FfiClient.instance.waitFor<ConnectCallback>((ev: FfiEvent) => {
119
120
  return ev.message.case == 'connect' && ev.message.value.asyncId == res.asyncId;
120
121
  });
121
122
 
@@ -130,11 +131,11 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
130
131
  this.connectionState = ConnectionState.CONN_CONNECTED;
131
132
  this.localParticipant = new LocalParticipant(cb.localParticipant);
132
133
 
133
- for (let pt of cb.participants) {
134
- let rp = this.createRemoteParticipant(pt.participant);
134
+ for (const pt of cb.participants) {
135
+ const rp = this.createRemoteParticipant(pt.participant);
135
136
 
136
- for (let pub of pt.publications) {
137
- let publication = new RemoteTrackPublication(pub);
137
+ for (const pub of pt.publications) {
138
+ const publication = new RemoteTrackPublication(pub);
138
139
  rp.trackPublications.set(publication.sid, publication);
139
140
  }
140
141
  }
@@ -155,6 +156,9 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
155
156
  },
156
157
  },
157
158
  });
159
+
160
+ FfiClient.instance.removeAllListeners();
161
+ this.removeAllListeners();
158
162
  }
159
163
 
160
164
  private onFfiEvent = (ffiEvent: FfiEvent) => {
@@ -165,36 +169,36 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
165
169
  return;
166
170
  }
167
171
 
168
- let ev = ffiEvent.message.value.message;
172
+ const ev = ffiEvent.message.value.message;
169
173
  if (ev.case == 'participantConnected') {
170
- let participant = this.createRemoteParticipant(ev.value.info);
174
+ const participant = this.createRemoteParticipant(ev.value.info);
171
175
  this.remoteParticipants.set(participant.identity, participant);
172
176
  this.emit(RoomEvent.ParticipantConnected, participant);
173
177
  } else if (ev.case == 'participantDisconnected') {
174
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
178
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
175
179
  this.remoteParticipants.delete(participant.identity);
176
180
  this.emit(RoomEvent.ParticipantDisconnected, participant);
177
181
  } else if (ev.case == 'localTrackPublished') {
178
- let publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
179
- this.emit(RoomEvent.LocalTrackPublished, publication, publication.track);
182
+ const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
183
+ this.emit(RoomEvent.LocalTrackPublished, publication, this.localParticipant);
180
184
  } else if (ev.case == 'localTrackUnpublished') {
181
- let publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
185
+ const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
182
186
  this.localParticipant.trackPublications.delete(ev.value.publicationSid);
183
- this.emit(RoomEvent.LocalTrackUnpublished, publication);
187
+ this.emit(RoomEvent.LocalTrackUnpublished, publication, this.localParticipant);
184
188
  } else if (ev.case == 'trackPublished') {
185
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
186
- let publication = new RemoteTrackPublication(ev.value.publication);
189
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
190
+ const publication = new RemoteTrackPublication(ev.value.publication);
187
191
  participant.trackPublications.set(publication.sid, publication);
188
192
  this.emit(RoomEvent.TrackPublished, publication, participant);
189
193
  } else if (ev.case == 'trackUnpublished') {
190
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
191
- let publication = participant.trackPublications.get(ev.value.publicationSid);
194
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
195
+ const publication = participant.trackPublications.get(ev.value.publicationSid);
192
196
  participant.trackPublications.delete(ev.value.publicationSid);
193
197
  this.emit(RoomEvent.TrackUnpublished, publication, participant);
194
198
  } else if (ev.case == 'trackSubscribed') {
195
- let ownedTrack = ev.value.track;
196
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
197
- let publication = participant.trackPublications.get(ownedTrack.info.sid);
199
+ const ownedTrack = ev.value.track;
200
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
201
+ const publication = participant.trackPublications.get(ownedTrack.info.sid);
198
202
  publication.subscribed = true;
199
203
  if (ownedTrack.info.kind == TrackKind.KIND_VIDEO) {
200
204
  publication.track = new RemoteVideoTrack(ownedTrack);
@@ -204,70 +208,64 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
204
208
 
205
209
  this.emit(RoomEvent.TrackSubscribed, publication.track, publication, participant);
206
210
  } else if (ev.case == 'trackUnsubscribed') {
207
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
208
- let publication = participant.trackPublications.get(ev.value.trackSid);
211
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
212
+ const publication = participant.trackPublications.get(ev.value.trackSid);
209
213
  publication.track = undefined;
210
214
  publication.subscribed = false;
211
215
  this.emit(RoomEvent.TrackUnsubscribed, publication.track, publication, participant);
212
216
  } else if (ev.case == 'trackSubscriptionFailed') {
213
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
214
- this.emit(RoomEvent.TrackSubscriptionFailed, participant, ev.value.trackSid, ev.value.error);
217
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
218
+ this.emit(RoomEvent.TrackSubscriptionFailed, ev.value.trackSid, participant, ev.value.error);
215
219
  } else if (ev.case == 'trackMuted') {
216
- let participant = this.retrieveParticipant(ev.value.participantSid);
217
- let publication = participant.trackPublications.get(ev.value.trackSid);
220
+ const participant = this.retrieveParticipant(ev.value.participantSid);
221
+ const publication = participant.trackPublications.get(ev.value.trackSid);
218
222
  publication.info.muted = true;
219
223
  if (publication.track) {
220
224
  publication.track.info.muted = true;
221
225
  }
222
- this.emit(RoomEvent.TrackMuted, participant, publication);
226
+ this.emit(RoomEvent.TrackMuted, publication, participant);
223
227
  } else if (ev.case == 'trackUnmuted') {
224
- let participant = this.retrieveParticipant(ev.value.participantSid);
225
- let publication = participant.trackPublications.get(ev.value.trackSid);
228
+ const participant = this.retrieveParticipant(ev.value.participantSid);
229
+ const publication = participant.trackPublications.get(ev.value.trackSid);
226
230
  publication.info.muted = false;
227
231
  if (publication.track) {
228
232
  publication.track.info.muted = false;
229
233
  }
230
- this.emit(RoomEvent.TrackUnmuted, participant, publication);
234
+ this.emit(RoomEvent.TrackUnmuted, publication, participant);
231
235
  } else if (ev.case == 'activeSpeakersChanged') {
232
- let activeSpeakers = ev.value.participantSids.map((sid) =>
236
+ const activeSpeakers = ev.value.participantSids.map((sid) =>
233
237
  this.getRemoteParticipantBySid(sid),
234
238
  );
235
239
  this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
236
240
  } else if (ev.case == 'roomMetadataChanged') {
237
- let oldMetadata = this.info.metadata;
238
241
  this.info.metadata = ev.value.metadata;
239
- this.emit(RoomEvent.RoomMetadataChanged, oldMetadata, this.info.metadata);
242
+ this.emit(RoomEvent.RoomMetadataChanged, this.info.metadata);
240
243
  } else if (ev.case == 'participantMetadataChanged') {
241
- let participant = this.retrieveParticipant(ev.value.participantSid);
242
- let oldMetadata = participant.metadata;
244
+ const participant = this.retrieveParticipant(ev.value.participantSid);
243
245
  participant.info.metadata = ev.value.metadata;
244
- this.emit(
245
- RoomEvent.ParticipantMetadataChanged,
246
- participant,
247
- oldMetadata,
248
- participant.metadata,
249
- );
246
+ this.emit(RoomEvent.ParticipantMetadataChanged, participant.metadata, participant);
250
247
  } else if (ev.case == 'participantNameChanged') {
251
- let participant = this.retrieveParticipant(ev.value.participantSid);
252
- let oldName = participant.name;
248
+ const participant = this.retrieveParticipant(ev.value.participantSid);
253
249
  participant.info.name = ev.value.name;
254
- this.emit(RoomEvent.ParticipantNameChanged, participant, oldName, participant.name);
250
+ this.emit(RoomEvent.ParticipantNameChanged, participant.name, participant);
255
251
  } else if (ev.case == 'connectionQualityChanged') {
256
- let participant = this.retrieveParticipant(ev.value.participantSid);
257
- this.emit(RoomEvent.ConnectionQualityChanged, participant, ev.value.quality);
252
+ const participant = this.retrieveParticipant(ev.value.participantSid);
253
+ this.emit(RoomEvent.ConnectionQualityChanged, ev.value.quality, participant);
258
254
  } else if (ev.case == 'dataReceived') {
259
255
  // Can be undefined if the data is sent from a Server SDK
260
- let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
261
- let info = ev.value.data;
262
- let buffer = FfiClient.instance.copyBuffer(info.data.dataPtr, Number(info.data.dataLen));
256
+ const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
257
+ const info = ev.value.data;
258
+ const buffer = FfiClient.instance.copyBuffer(info.data.dataPtr, Number(info.data.dataLen));
263
259
  new FfiHandle(info.handle.id).dispose();
264
- this.emit(RoomEvent.DataReceived, buffer, ev.value.kind, participant);
260
+ this.emit(RoomEvent.DataReceived, buffer, participant, ev.value.kind, ev.value.topic);
265
261
  } else if (ev.case == 'e2eeStateChanged') {
266
- let participant = this.retrieveParticipant(ev.value.participantSid);
267
- this.emit(RoomEvent.E2EEStateChanged, participant, ev.value.state);
262
+ if (ev.value.state == EncryptionState.INTERNAL_ERROR) {
263
+ // throw generic error until Rust SDK is updated to supply the error alongside INTERNAL_ERROR
264
+ this.emit(RoomEvent.EncryptionError, new Error('internal server error'));
265
+ }
268
266
  } else if (ev.case == 'connectionStateChanged') {
269
267
  this.connectionState = ev.value.state;
270
- this.emit(RoomEvent.ConenctionStateChanged, this.connectionState);
268
+ this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);
271
269
  /*} else if (ev.case == 'connected') {
272
270
  this.emit(RoomEvent.Connected);*/
273
271
  } else if (ev.case == 'disconnected') {
@@ -311,8 +309,11 @@ export class ConnectError extends Error {
311
309
  export type RoomCallbacks = {
312
310
  participantConnected: (participant: RemoteParticipant) => void;
313
311
  participantDisconnected: (participant: RemoteParticipant) => void;
314
- localTrackPublished: (publication: LocalTrackPublication, track: LocalTrack) => void;
315
- localTrackUnpublished: (publication: LocalTrackPublication) => void;
312
+ localTrackPublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;
313
+ localTrackUnpublished: (
314
+ publication: LocalTrackPublication,
315
+ participant: LocalParticipant,
316
+ ) => void;
316
317
  trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;
317
318
  trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;
318
319
  trackSubscribed: (
@@ -326,26 +327,27 @@ export type RoomCallbacks = {
326
327
  participant: RemoteParticipant,
327
328
  ) => void;
328
329
  trackSubscriptionFailed: (
330
+ trackSid: string,
329
331
  participant: RemoteParticipant,
330
- publicationSid: string,
331
- error: string,
332
+ reason?: string,
332
333
  ) => void;
333
- trackMuted: (participant: Participant, publication: TrackPublication) => void;
334
- trackUnmuted: (participant: Participant, publication: TrackPublication) => void;
335
- activeSpeakersChanged: (speakers: RemoteParticipant[]) => void;
336
- roomMetadataChanged: (oldMetadata: string, metadata: string) => void;
337
- participantMetadataChanged: (
338
- participant: Participant,
339
- oldMetadata: string,
340
- metadata: string,
334
+ trackMuted: (publication: TrackPublication, participant: Participant) => void;
335
+ trackUnmuted: (publication: TrackPublication, participant: Participant) => void;
336
+ activeSpeakersChanged: (speakers: Participant[]) => void;
337
+ roomMetadataChanged: (metadata: string) => void;
338
+ participantMetadataChanged: (metadata: string | undefined, participant: Participant) => void;
339
+ participantNameChanged: (name: string, participant: Participant) => void;
340
+ connectionQualityChanged: (quality: ConnectionQuality, participant: Participant) => void;
341
+ dataReceived: (
342
+ payload: Uint8Array,
343
+ participant?: RemoteParticipant,
344
+ kind?: DataPacketKind,
345
+ topic?: string,
341
346
  ) => void;
342
- participantNameChanged: (participant: Participant, oldName: string, name: string) => void;
343
- connectionQualityChanged: (participant: Participant, quality: ConnectionQuality) => void;
344
- dataReceived: (data: Uint8Array, kind: DataPacketKind, participant?: RemoteParticipant) => void;
345
- e2eeStateChanged: (participant: Participant, state: EncryptionState) => void;
347
+ encryptionError: (error: Error) => void;
346
348
  connectionStateChanged: (state: ConnectionState) => void;
347
349
  connected: () => void;
348
- disconnected: () => void;
350
+ disconnected: (reason?: string) => void;
349
351
  reconnecting: () => void;
350
352
  reconnected: () => void;
351
353
  };
@@ -368,8 +370,8 @@ export enum RoomEvent {
368
370
  ParticipantNameChanged = 'participantNameChanged',
369
371
  ConnectionQualityChanged = 'connectionQualityChanged',
370
372
  DataReceived = 'dataReceived',
371
- E2EEStateChanged = 'e2eeStateChanged',
372
- ConenctionStateChanged = 'connectionStateChanged',
373
+ EncryptionError = 'encryptionError',
374
+ ConnectionStateChanged = 'connectionStateChanged',
373
375
  Connected = 'connected',
374
376
  Disconnected = 'disconnected',
375
377
  Reconnecting = 'reconnecting',
package/src/track.ts CHANGED
@@ -1,20 +1,18 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
-
5
- import { AudioSource } from './audio_source.js';
6
- import { FfiClient, FfiHandle, FfiRequest } from './ffi_client.js';
7
- import {
8
- CreateAudioTrackRequest,
4
+ import type { AudioSource } from './audio_source.js';
5
+ import { FfiClient, FfiHandle } from './ffi_client.js';
6
+ import type {
9
7
  CreateAudioTrackResponse,
10
- CreateVideoTrackRequest,
11
8
  CreateVideoTrackResponse,
12
9
  OwnedTrack,
13
10
  StreamState,
14
11
  TrackInfo,
15
12
  TrackKind,
16
13
  } from './proto/track_pb.js';
17
- import { VideoSource } from './video_source.js';
14
+ import { CreateAudioTrackRequest, CreateVideoTrackRequest } from './proto/track_pb.js';
15
+ import type { VideoSource } from './video_source.js';
18
16
 
19
17
  export abstract class Track {
20
18
  /** @internal */
@@ -55,12 +53,12 @@ export class LocalAudioTrack extends Track {
55
53
  }
56
54
 
57
55
  static createAudioTrack(name: string, source: AudioSource): LocalAudioTrack {
58
- let req = new CreateAudioTrackRequest({
56
+ const req = new CreateAudioTrackRequest({
59
57
  name: name,
60
58
  sourceHandle: source.ffiHandle.handle,
61
59
  });
62
60
 
63
- let res = FfiClient.instance.request<CreateAudioTrackResponse>({
61
+ const res = FfiClient.instance.request<CreateAudioTrackResponse>({
64
62
  message: { case: 'createAudioTrack', value: req },
65
63
  });
66
64
 
@@ -74,12 +72,12 @@ export class LocalVideoTrack extends Track {
74
72
  }
75
73
 
76
74
  static createVideoTrack(name: string, source: VideoSource): LocalVideoTrack {
77
- let req = new CreateVideoTrackRequest({
75
+ const req = new CreateVideoTrackRequest({
78
76
  name: name,
79
77
  sourceHandle: source.ffiHandle.handle,
80
78
  });
81
79
 
82
- let res = FfiClient.instance.request<CreateVideoTrackResponse>({
80
+ const res = FfiClient.instance.request<CreateVideoTrackResponse>({
83
81
  message: { case: 'createVideoTrack', value: req },
84
82
  });
85
83
 
@@ -1,18 +1,18 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
-
5
- import { FfiClient, FfiRequest } from './ffi_client.js';
4
+ import { FfiClient } from './ffi_client.js';
6
5
  import { FfiHandle } from './napi/native.js';
7
- import { EncryptionType } from './proto/e2ee_pb.js';
8
- import { SetSubscribedRequest, SetSubscribedResponse } from './proto/room_pb.js';
9
- import {
6
+ import type { EncryptionType } from './proto/e2ee_pb.js';
7
+ import type { SetSubscribedResponse } from './proto/room_pb.js';
8
+ import { SetSubscribedRequest } from './proto/room_pb.js';
9
+ import type {
10
10
  OwnedTrackPublication,
11
11
  TrackKind,
12
12
  TrackPublicationInfo,
13
13
  TrackSource,
14
14
  } from './proto/track_pb.js';
15
- import { Track } from './track.js';
15
+ import type { Track } from './track.js';
16
16
 
17
17
  export abstract class TrackPublication {
18
18
  /** @internal */
@@ -82,7 +82,7 @@ export class RemoteTrackPublication extends TrackPublication {
82
82
  }
83
83
 
84
84
  setSubscribed(subscribed: boolean) {
85
- let req = new SetSubscribedRequest({
85
+ const req = new SetSubscribedRequest({
86
86
  subscribe: subscribed,
87
87
  publicationHandle: this.ffiHandle.handle,
88
88
  });
@@ -1,14 +1,12 @@
1
1
  // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
2
  //
3
3
  // SPDX-License-Identifier: Apache-2.0
4
-
5
- import { FfiClient, FfiHandle, FfiRequest } from './ffi_client.js';
4
+ import { FfiClient, FfiRequest } from './ffi_client.js';
5
+ import type { OwnedVideoBuffer, VideoConvertResponse } from './proto/video_frame_pb.js';
6
6
  import {
7
- OwnedVideoBuffer,
8
7
  VideoBufferInfo,
9
8
  VideoBufferInfo_ComponentInfo,
10
9
  VideoBufferType,
11
- VideoConvertResponse,
12
10
  } from './proto/video_frame_pb.js';
13
11
 
14
12
  export class VideoFrame {
@@ -17,12 +15,7 @@ export class VideoFrame {
17
15
  height: number;
18
16
  type: VideoBufferType;
19
17
 
20
- constructor(
21
- data: Uint8Array,
22
- width: number,
23
- height: number,
24
- type: VideoBufferType,
25
- ) {
18
+ constructor(data: Uint8Array, width: number, height: number, type: VideoBufferType) {
26
19
  this.data = data;
27
20
  this.width = width;
28
21
  this.height = height;
@@ -31,7 +24,7 @@ export class VideoFrame {
31
24
 
32
25
  /** @internal */
33
26
  get dataPtr(): bigint {
34
- return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer))
27
+ return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer));
35
28
  }
36
29
 
37
30
  /** @internal */
@@ -60,7 +53,7 @@ export class VideoFrame {
60
53
 
61
54
  /** @internal */
62
55
  static fromOwnedInfo(owned: OwnedVideoBuffer): VideoFrame {
63
- let info = owned.info;
56
+ const info = owned.info;
64
57
  return new VideoFrame(
65
58
  FfiClient.instance.copyBuffer(
66
59
  info.dataPtr,
@@ -73,7 +66,7 @@ export class VideoFrame {
73
66
  }
74
67
 
75
68
  getPlane(planeNth: number): Uint8Array | void {
76
- const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height)
69
+ const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height);
77
70
  if (planeNth >= planeInfos.length) return;
78
71
 
79
72
  const planeInfo = planeInfos[planeNth];
@@ -91,12 +84,12 @@ export class VideoFrame {
91
84
  },
92
85
  },
93
86
  });
94
- const resp = FfiClient.instance.request<VideoConvertResponse>(req)
87
+ const resp = FfiClient.instance.request<VideoConvertResponse>(req);
95
88
  if (resp.error) {
96
- throw resp.error
89
+ throw resp.error;
97
90
  }
98
91
 
99
- return VideoFrame.fromOwnedInfo(resp.buffer)
92
+ return VideoFrame.fromOwnedInfo(resp.buffer);
100
93
  }
101
94
  }
102
95