@livekit/rtc-node 0.13.21 → 0.13.23

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 (135) hide show
  1. package/dist/async_queue.cjs +80 -0
  2. package/dist/async_queue.cjs.map +1 -0
  3. package/dist/async_queue.d.cts +30 -0
  4. package/dist/async_queue.d.ts +30 -0
  5. package/dist/async_queue.d.ts.map +1 -0
  6. package/dist/async_queue.js +56 -0
  7. package/dist/async_queue.js.map +1 -0
  8. package/dist/audio_frame.cjs +5 -0
  9. package/dist/audio_frame.cjs.map +1 -1
  10. package/dist/audio_frame.d.cts +3 -0
  11. package/dist/audio_frame.d.ts +3 -0
  12. package/dist/audio_frame.d.ts.map +1 -1
  13. package/dist/audio_frame.js +5 -0
  14. package/dist/audio_frame.js.map +1 -1
  15. package/dist/audio_mixer.cjs +281 -0
  16. package/dist/audio_mixer.cjs.map +1 -0
  17. package/dist/audio_mixer.d.cts +121 -0
  18. package/dist/audio_mixer.d.ts +121 -0
  19. package/dist/audio_mixer.d.ts.map +1 -0
  20. package/dist/audio_mixer.js +256 -0
  21. package/dist/audio_mixer.js.map +1 -0
  22. package/dist/audio_stream.cjs +18 -5
  23. package/dist/audio_stream.cjs.map +1 -1
  24. package/dist/audio_stream.d.cts +4 -3
  25. package/dist/audio_stream.d.ts +4 -3
  26. package/dist/audio_stream.d.ts.map +1 -1
  27. package/dist/audio_stream.js +18 -5
  28. package/dist/audio_stream.js.map +1 -1
  29. package/dist/data_streams/stream_reader.cjs.map +1 -1
  30. package/dist/data_streams/stream_reader.js.map +1 -1
  31. package/dist/frame_processor.cjs +38 -0
  32. package/dist/frame_processor.cjs.map +1 -0
  33. package/dist/frame_processor.d.cts +29 -0
  34. package/dist/frame_processor.d.ts +29 -0
  35. package/dist/frame_processor.d.ts.map +1 -0
  36. package/dist/frame_processor.js +14 -0
  37. package/dist/frame_processor.js.map +1 -0
  38. package/dist/index.cjs +6 -0
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +3 -0
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +6 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/participant.cjs +4 -4
  46. package/dist/participant.cjs.map +1 -1
  47. package/dist/participant.d.cts +2 -2
  48. package/dist/participant.d.ts +2 -2
  49. package/dist/participant.d.ts.map +1 -1
  50. package/dist/participant.js +4 -4
  51. package/dist/participant.js.map +1 -1
  52. package/dist/proto/audio_frame_pb.cjs.map +1 -1
  53. package/dist/proto/audio_frame_pb.js.map +1 -1
  54. package/dist/proto/e2ee_pb.cjs.map +1 -1
  55. package/dist/proto/e2ee_pb.js.map +1 -1
  56. package/dist/proto/ffi_pb.cjs +4 -2
  57. package/dist/proto/ffi_pb.cjs.map +1 -1
  58. package/dist/proto/ffi_pb.d.cts +13 -1
  59. package/dist/proto/ffi_pb.d.ts +13 -1
  60. package/dist/proto/ffi_pb.d.ts.map +1 -1
  61. package/dist/proto/ffi_pb.js +5 -3
  62. package/dist/proto/ffi_pb.js.map +1 -1
  63. package/dist/proto/handle_pb.cjs.map +1 -1
  64. package/dist/proto/handle_pb.js.map +1 -1
  65. package/dist/proto/participant_pb.cjs +26 -4
  66. package/dist/proto/participant_pb.cjs.map +1 -1
  67. package/dist/proto/participant_pb.d.cts +31 -2
  68. package/dist/proto/participant_pb.d.ts +31 -2
  69. package/dist/proto/participant_pb.d.ts.map +1 -1
  70. package/dist/proto/participant_pb.js +24 -3
  71. package/dist/proto/participant_pb.js.map +1 -1
  72. package/dist/proto/room_pb.cjs +29 -2
  73. package/dist/proto/room_pb.cjs.map +1 -1
  74. package/dist/proto/room_pb.d.cts +30 -7
  75. package/dist/proto/room_pb.d.ts +30 -7
  76. package/dist/proto/room_pb.d.ts.map +1 -1
  77. package/dist/proto/room_pb.js +28 -2
  78. package/dist/proto/room_pb.js.map +1 -1
  79. package/dist/proto/rpc_pb.cjs.map +1 -1
  80. package/dist/proto/rpc_pb.js.map +1 -1
  81. package/dist/proto/stats_pb.cjs.map +1 -1
  82. package/dist/proto/stats_pb.js.map +1 -1
  83. package/dist/proto/track_pb.cjs.map +1 -1
  84. package/dist/proto/track_pb.js.map +1 -1
  85. package/dist/proto/track_publication_pb.cjs +66 -2
  86. package/dist/proto/track_publication_pb.cjs.map +1 -1
  87. package/dist/proto/track_publication_pb.d.cts +56 -1
  88. package/dist/proto/track_publication_pb.d.ts +56 -1
  89. package/dist/proto/track_publication_pb.d.ts.map +1 -1
  90. package/dist/proto/track_publication_pb.js +62 -1
  91. package/dist/proto/track_publication_pb.js.map +1 -1
  92. package/dist/proto/video_frame_pb.cjs +3 -1
  93. package/dist/proto/video_frame_pb.cjs.map +1 -1
  94. package/dist/proto/video_frame_pb.d.cts +5 -1
  95. package/dist/proto/video_frame_pb.d.ts +5 -1
  96. package/dist/proto/video_frame_pb.d.ts.map +1 -1
  97. package/dist/proto/video_frame_pb.js +3 -1
  98. package/dist/proto/video_frame_pb.js.map +1 -1
  99. package/dist/room.cjs +286 -288
  100. package/dist/room.cjs.map +1 -1
  101. package/dist/room.d.cts +11 -11
  102. package/dist/room.d.ts +11 -11
  103. package/dist/room.d.ts.map +1 -1
  104. package/dist/room.js +287 -289
  105. package/dist/room.js.map +1 -1
  106. package/dist/version.cjs +1 -1
  107. package/dist/version.cjs.map +1 -1
  108. package/dist/version.d.cts +1 -1
  109. package/dist/version.d.ts +1 -1
  110. package/dist/version.js +1 -1
  111. package/dist/version.js.map +1 -1
  112. package/package.json +9 -8
  113. package/src/async_queue.test.ts +250 -0
  114. package/src/async_queue.ts +80 -0
  115. package/src/audio_frame.ts +7 -0
  116. package/src/audio_mixer.test.ts +167 -0
  117. package/src/audio_mixer.ts +407 -0
  118. package/src/audio_stream.ts +22 -7
  119. package/src/data_streams/stream_reader.ts +4 -4
  120. package/src/frame_processor.ts +29 -0
  121. package/src/index.ts +6 -0
  122. package/src/participant.ts +5 -5
  123. package/src/proto/audio_frame_pb.ts +1 -1
  124. package/src/proto/e2ee_pb.ts +1 -1
  125. package/src/proto/ffi_pb.ts +16 -2
  126. package/src/proto/handle_pb.ts +1 -1
  127. package/src/proto/participant_pb.ts +45 -1
  128. package/src/proto/room_pb.ts +52 -8
  129. package/src/proto/rpc_pb.ts +1 -1
  130. package/src/proto/stats_pb.ts +1 -1
  131. package/src/proto/track_pb.ts +1 -1
  132. package/src/proto/track_publication_pb.ts +105 -1
  133. package/src/proto/video_frame_pb.ts +7 -1
  134. package/src/room.ts +297 -300
  135. package/src/version.ts +1 -1
package/dist/room.cjs CHANGED
@@ -70,7 +70,7 @@ class Room extends import_events.default {
70
70
  * the local participant to acquire the lock while doing state updates related to FFI events
71
71
  * before processing the next events
72
72
  */
73
- this.roomEventLock = new import_mutex.Mutex();
73
+ this.ffiEventLock = new import_mutex.Mutex();
74
74
  this.byteStreamControllers = /* @__PURE__ */ new Map();
75
75
  this.textStreamControllers = /* @__PURE__ */ new Map();
76
76
  this.byteStreamHandlers = /* @__PURE__ */ new Map();
@@ -79,304 +79,302 @@ class Room extends import_events.default {
79
79
  this.connectionState = import_room_pb.ConnectionState.CONN_DISCONNECTED;
80
80
  this.remoteParticipants = /* @__PURE__ */ new Map();
81
81
  this.onFfiEvent = async (ffiEvent) => {
82
- if (!this.localParticipant || !this.ffiHandle || !this.info) {
83
- this.preConnectEvents.push(ffiEvent);
84
- return;
85
- }
86
- for (const ev of this.preConnectEvents) {
87
- await this.processFfiEvent(ev);
82
+ const unlock = await this.ffiEventLock.lock();
83
+ try {
84
+ if (!this.localParticipant || !this.ffiHandle || !this.info) {
85
+ this.preConnectEvents.push(ffiEvent);
86
+ return;
87
+ }
88
+ for (const ev of this.preConnectEvents) {
89
+ await this.processFfiEvent(ev);
90
+ }
91
+ this.preConnectEvents = [];
92
+ await this.processFfiEvent(ffiEvent);
93
+ } finally {
94
+ unlock();
88
95
  }
89
- this.preConnectEvents = [];
90
- await this.processFfiEvent(ffiEvent);
91
96
  };
92
97
  this.processFfiEvent = async (ffiEvent) => {
93
98
  if (!this.localParticipant || !this.ffiHandle || !this.info) {
94
99
  throw new Error("processFfiEvent called before connect");
95
100
  }
96
- const unlock = await this.roomEventLock.lock();
97
- try {
98
- if (ffiEvent.message.case == "rpcMethodInvocation") {
99
- if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
100
- this.localParticipant.handleRpcMethodInvocation(
101
- ffiEvent.message.value.invocationId,
102
- ffiEvent.message.value.method,
103
- ffiEvent.message.value.requestId,
104
- ffiEvent.message.value.callerIdentity,
105
- ffiEvent.message.value.payload,
106
- ffiEvent.message.value.responseTimeoutMs
107
- );
108
- }
109
- return;
110
- } else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
111
- return;
101
+ if (ffiEvent.message.case == "rpcMethodInvocation") {
102
+ if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
103
+ this.localParticipant.handleRpcMethodInvocation(
104
+ ffiEvent.message.value.invocationId,
105
+ ffiEvent.message.value.method,
106
+ ffiEvent.message.value.requestId,
107
+ ffiEvent.message.value.callerIdentity,
108
+ ffiEvent.message.value.payload,
109
+ ffiEvent.message.value.responseTimeoutMs
110
+ );
112
111
  }
113
- const ev = ffiEvent.message.value.message;
114
- if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {
115
- console.log("Room event:", ev);
112
+ return;
113
+ } else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
114
+ return;
115
+ }
116
+ const ev = ffiEvent.message.value.message;
117
+ if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {
118
+ console.log("Room event:", ev);
119
+ }
120
+ if (ev.case == "participantConnected") {
121
+ const participant = this.createRemoteParticipant(ev.value.info);
122
+ this.remoteParticipants.set(participant.identity, participant);
123
+ this.emit("participantConnected" /* ParticipantConnected */, participant);
124
+ } else if (ev.case == "participantDisconnected") {
125
+ const participant = this.remoteParticipants.get(ev.value.participantIdentity);
126
+ if (participant) {
127
+ this.remoteParticipants.delete(participant.identity);
128
+ participant.info.disconnectReason = ev.value.disconnectReason;
129
+ this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
130
+ } else {
131
+ console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);
116
132
  }
117
- if (ev.case == "participantConnected") {
118
- const participant = this.createRemoteParticipant(ev.value.info);
119
- this.remoteParticipants.set(participant.identity, participant);
120
- this.emit("participantConnected" /* ParticipantConnected */, participant);
121
- } else if (ev.case == "participantDisconnected") {
122
- const participant = this.remoteParticipants.get(ev.value.participantIdentity);
123
- if (participant) {
124
- this.remoteParticipants.delete(participant.identity);
125
- participant.info.disconnectReason = ev.value.disconnectReason;
126
- this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
127
- } else {
128
- console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);
129
- }
130
- } else if (ev.case == "localTrackPublished") {
131
- const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
132
- this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
133
- } else if (ev.case == "localTrackUnpublished") {
134
- const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
135
- this.localParticipant.trackPublications.delete(ev.value.publicationSid);
136
- this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
137
- } else if (ev.case == "localTrackSubscribed") {
138
- const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
139
- if (publication) {
140
- publication.resolveFirstSubscription();
141
- this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
142
- } else {
143
- console.warn(
144
- `RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`
145
- );
146
- }
147
- } else if (ev.case == "trackPublished") {
148
- const participant = this.remoteParticipants.get(ev.value.participantIdentity);
149
- const publication = new import_track_publication.RemoteTrackPublication(ev.value.publication);
150
- if (participant) {
151
- participant.trackPublications.set(publication.sid, publication);
152
- } else {
153
- console.warn(
154
- `RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`
155
- );
133
+ } else if (ev.case == "localTrackPublished") {
134
+ const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
135
+ this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
136
+ } else if (ev.case == "localTrackUnpublished") {
137
+ const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
138
+ this.localParticipant.trackPublications.delete(ev.value.publicationSid);
139
+ this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
140
+ } else if (ev.case == "localTrackSubscribed") {
141
+ const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
142
+ if (publication) {
143
+ publication.resolveFirstSubscription();
144
+ this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
145
+ } else {
146
+ console.warn(`RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`);
147
+ }
148
+ } else if (ev.case == "trackPublished") {
149
+ const participant = this.remoteParticipants.get(ev.value.participantIdentity);
150
+ const publication = new import_track_publication.RemoteTrackPublication(ev.value.publication);
151
+ if (participant) {
152
+ participant.trackPublications.set(publication.sid, publication);
153
+ } else {
154
+ console.warn(
155
+ `RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`
156
+ );
157
+ }
158
+ this.emit("trackPublished" /* TrackPublished */, publication, participant);
159
+ } else if (ev.case == "trackUnpublished") {
160
+ const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
161
+ const publication = participant.trackPublications.get(ev.value.publicationSid);
162
+ participant.trackPublications.delete(ev.value.publicationSid);
163
+ if (publication) {
164
+ this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
165
+ } else {
166
+ console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);
167
+ }
168
+ } else if (ev.case == "trackSubscribed") {
169
+ const ownedTrack = ev.value.track;
170
+ const trackInfo = ownedTrack.info;
171
+ try {
172
+ const { participant, publication } = this.requirePublicationOfRemoteParticipant(
173
+ ev.value.participantIdentity,
174
+ trackInfo.sid
175
+ );
176
+ publication.subscribed = true;
177
+ if (trackInfo.kind == import_track_pb.TrackKind.KIND_VIDEO) {
178
+ publication.track = new import_track.RemoteVideoTrack(ownedTrack);
179
+ } else if (trackInfo.kind == import_track_pb.TrackKind.KIND_AUDIO) {
180
+ publication.track = new import_track.RemoteAudioTrack(ownedTrack);
156
181
  }
157
- this.emit("trackPublished" /* TrackPublished */, publication, participant);
158
- } else if (ev.case == "trackUnpublished") {
182
+ this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
183
+ } catch (e) {
184
+ console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);
185
+ }
186
+ } else if (ev.case == "trackUnsubscribed") {
187
+ try {
188
+ const { participant, publication } = this.requirePublicationOfRemoteParticipant(
189
+ ev.value.participantIdentity,
190
+ ev.value.trackSid
191
+ );
192
+ const track = publication.track;
193
+ publication.track = void 0;
194
+ publication.subscribed = false;
195
+ this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
196
+ } catch (e) {
197
+ console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);
198
+ }
199
+ } else if (ev.case == "trackSubscriptionFailed") {
200
+ try {
159
201
  const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
160
- const publication = participant.trackPublications.get(ev.value.publicationSid);
161
- participant.trackPublications.delete(ev.value.publicationSid);
162
- if (publication) {
163
- this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
164
- } else {
165
- console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);
166
- }
167
- } else if (ev.case == "trackSubscribed") {
168
- const ownedTrack = ev.value.track;
169
- const trackInfo = ownedTrack.info;
170
- try {
171
- const { participant, publication } = this.requirePublicationOfRemoteParticipant(
172
- ev.value.participantIdentity,
173
- trackInfo.sid
174
- );
175
- publication.subscribed = true;
176
- if (trackInfo.kind == import_track_pb.TrackKind.KIND_VIDEO) {
177
- publication.track = new import_track.RemoteVideoTrack(ownedTrack);
178
- } else if (trackInfo.kind == import_track_pb.TrackKind.KIND_AUDIO) {
179
- publication.track = new import_track.RemoteAudioTrack(ownedTrack);
180
- }
181
- this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
182
- } catch (e) {
183
- console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);
184
- }
185
- } else if (ev.case == "trackUnsubscribed") {
186
- try {
187
- const { participant, publication } = this.requirePublicationOfRemoteParticipant(
188
- ev.value.participantIdentity,
189
- ev.value.trackSid
190
- );
191
- const track = publication.track;
192
- publication.track = void 0;
193
- publication.subscribed = false;
194
- this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
195
- } catch (e) {
196
- console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);
197
- }
198
- } else if (ev.case == "trackSubscriptionFailed") {
199
- try {
200
- const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
201
- this.emit(
202
- "trackSubscriptionFailed" /* TrackSubscriptionFailed */,
203
- ev.value.trackSid,
204
- participant,
205
- ev.value.error
206
- );
207
- } catch (e) {
208
- console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);
209
- }
210
- } else if (ev.case == "trackMuted") {
211
- try {
212
- const { participant, publication } = this.requirePublicationOfParticipant(
213
- ev.value.participantIdentity,
214
- ev.value.trackSid
215
- );
216
- publication.info.muted = true;
217
- if (publication.track) {
218
- publication.track.info.muted = true;
219
- }
220
- this.emit("trackMuted" /* TrackMuted */, publication, participant);
221
- } catch (e) {
222
- console.warn(`RoomEvent.TrackMuted: ${e.message}`);
223
- }
224
- } else if (ev.case == "trackUnmuted") {
225
- try {
226
- const { participant, publication } = this.requirePublicationOfParticipant(
227
- ev.value.participantIdentity,
228
- ev.value.trackSid
229
- );
230
- publication.info.muted = false;
231
- if (publication.track) {
232
- publication.track.info.muted = false;
233
- }
234
- this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
235
- } catch (e) {
236
- console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);
237
- }
238
- } else if (ev.case == "activeSpeakersChanged") {
239
- try {
240
- const activeSpeakers = ev.value.participantIdentities.map(
241
- (identity) => this.requireParticipantByIdentity(identity)
242
- );
243
- this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
244
- } catch (e) {
245
- console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);
246
- }
247
- } else if (ev.case == "roomMetadataChanged") {
248
- this.info.metadata = ev.value.metadata ?? "";
249
- this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
250
- } else if (ev.case == "participantMetadataChanged") {
251
- try {
252
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
253
- participant.info.metadata = ev.value.metadata;
254
- this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
255
- } catch (e) {
256
- console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);
202
+ this.emit(
203
+ "trackSubscriptionFailed" /* TrackSubscriptionFailed */,
204
+ ev.value.trackSid,
205
+ participant,
206
+ ev.value.error
207
+ );
208
+ } catch (e) {
209
+ console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);
210
+ }
211
+ } else if (ev.case == "trackMuted") {
212
+ try {
213
+ const { participant, publication } = this.requirePublicationOfParticipant(
214
+ ev.value.participantIdentity,
215
+ ev.value.trackSid
216
+ );
217
+ publication.info.muted = true;
218
+ if (publication.track) {
219
+ publication.track.info.muted = true;
257
220
  }
258
- } else if (ev.case == "participantNameChanged") {
259
- try {
260
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
261
- participant.info.name = ev.value.name;
262
- this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
263
- } catch (e) {
264
- console.warn(`RoomEvent.ParticipantNameChanged: ${e.message}`);
221
+ this.emit("trackMuted" /* TrackMuted */, publication, participant);
222
+ } catch (e) {
223
+ console.warn(`RoomEvent.TrackMuted: ${e.message}`);
224
+ }
225
+ } else if (ev.case == "trackUnmuted") {
226
+ try {
227
+ const { participant, publication } = this.requirePublicationOfParticipant(
228
+ ev.value.participantIdentity,
229
+ ev.value.trackSid
230
+ );
231
+ publication.info.muted = false;
232
+ if (publication.track) {
233
+ publication.track.info.muted = false;
265
234
  }
266
- } else if (ev.case == "participantAttributesChanged") {
267
- try {
268
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
269
- participant.info.attributes = ev.value.attributes.reduce(
235
+ this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
236
+ } catch (e) {
237
+ console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);
238
+ }
239
+ } else if (ev.case == "activeSpeakersChanged") {
240
+ try {
241
+ const activeSpeakers = ev.value.participantIdentities.map(
242
+ (identity) => this.requireParticipantByIdentity(identity)
243
+ );
244
+ this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
245
+ } catch (e) {
246
+ console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);
247
+ }
248
+ } else if (ev.case == "roomMetadataChanged") {
249
+ this.info.metadata = ev.value.metadata ?? "";
250
+ this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
251
+ } else if (ev.case == "participantMetadataChanged") {
252
+ try {
253
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
254
+ participant.info.metadata = ev.value.metadata;
255
+ this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
256
+ } catch (e) {
257
+ console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);
258
+ }
259
+ } else if (ev.case == "participantNameChanged") {
260
+ try {
261
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
262
+ participant.info.name = ev.value.name;
263
+ this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
264
+ } catch (e) {
265
+ console.warn(`RoomEvent.ParticipantNameChanged: ${e.message}`);
266
+ }
267
+ } else if (ev.case == "participantAttributesChanged") {
268
+ try {
269
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
270
+ participant.info.attributes = ev.value.attributes.reduce(
271
+ (acc, value) => {
272
+ acc[value.key] = value.value;
273
+ return acc;
274
+ },
275
+ {}
276
+ );
277
+ if (Object.keys(ev.value.changedAttributes).length > 0) {
278
+ const changedAttributes = ev.value.changedAttributes.reduce(
270
279
  (acc, value) => {
271
280
  acc[value.key] = value.value;
272
281
  return acc;
273
282
  },
274
283
  {}
275
284
  );
276
- if (Object.keys(ev.value.changedAttributes).length > 0) {
277
- const changedAttributes = ev.value.changedAttributes.reduce(
278
- (acc, value) => {
279
- acc[value.key] = value.value;
280
- return acc;
281
- },
282
- {}
283
- );
284
- this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
285
- }
286
- } catch (e) {
287
- console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);
288
- }
289
- } else if (ev.case == "connectionQualityChanged") {
290
- try {
291
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
292
- this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
293
- } catch (e) {
294
- console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);
295
- }
296
- } else if (ev.case == "chatMessage") {
297
- const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
298
- const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
299
- const message = {
300
- id,
301
- message: messageText,
302
- timestamp: Number(timestamp),
303
- editTimestamp: Number(editTimestamp),
304
- generated
305
- };
306
- this.emit("chatMessage" /* ChatMessage */, message, participant);
307
- } else if (ev.case == "dataPacketReceived") {
308
- const participant = this.remoteParticipants.get(ev.value.participantIdentity);
309
- const dataPacket = ev.value.value;
310
- switch (dataPacket.case) {
311
- case "user":
312
- const buffer = import_ffi_client.FfiClient.instance.copyBuffer(
313
- dataPacket.value.data.data.dataPtr,
314
- Number(dataPacket.value.data.data.dataLen)
315
- );
316
- new import_ffi_client.FfiHandle(dataPacket.value.data.handle.id).dispose();
317
- this.emit(
318
- "dataReceived" /* DataReceived */,
319
- buffer,
320
- participant,
321
- ev.value.kind,
322
- dataPacket.value.topic
323
- );
324
- break;
325
- case "sipDtmf":
326
- const { code, digit } = dataPacket.value;
327
- this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
328
- break;
329
- default:
330
- break;
331
- }
332
- } else if (ev.case == "e2eeStateChanged") {
333
- if (ev.value.state == import_e2ee_pb.EncryptionState.INTERNAL_ERROR) {
334
- this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
285
+ this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
335
286
  }
336
- } else if (ev.case == "connectionStateChanged") {
337
- this.connectionState = ev.value.state;
338
- this.emit("connectionStateChanged" /* ConnectionStateChanged */, this.connectionState);
339
- } else if (ev.case == "disconnected") {
340
- this.emit("disconnected" /* Disconnected */, ev.value.reason);
341
- } else if (ev.case == "reconnecting") {
342
- this.emit("reconnecting" /* Reconnecting */);
343
- } else if (ev.case == "reconnected") {
344
- this.emit("reconnected" /* Reconnected */);
345
- } else if (ev.case == "roomSidChanged") {
346
- this.emit("roomSidChanged" /* RoomSidChanged */, ev.value.sid);
347
- } else if (ev.case === "streamHeaderReceived" && ev.value.header) {
348
- this.handleStreamHeader(ev.value.header, ev.value.participantIdentity);
349
- } else if (ev.case === "streamChunkReceived" && ev.value.chunk) {
350
- this.handleStreamChunk(ev.value.chunk);
351
- } else if (ev.case === "streamTrailerReceived" && ev.value.trailer) {
352
- this.handleStreamTrailer(ev.value.trailer);
353
- } else if (ev.case === "roomUpdated") {
354
- this.info = ev.value;
355
- this.emit("roomUpdated" /* RoomUpdated */);
356
- } else if (ev.case === "moved") {
357
- this.info = ev.value;
358
- this.emit("moved" /* Moved */);
359
- } else if (ev.case === "participantsUpdated") {
360
- for (const info of ev.value.participants) {
361
- const participant = this.retrieveParticipantByIdentity(info.identity);
362
- if (participant) {
363
- participant.info = info;
364
- }
365
- }
366
- } else if (ev.case === "participantEncryptionStatusChanged") {
367
- try {
368
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
287
+ } catch (e) {
288
+ console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);
289
+ }
290
+ } else if (ev.case == "connectionQualityChanged") {
291
+ try {
292
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
293
+ this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
294
+ } catch (e) {
295
+ console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);
296
+ }
297
+ } else if (ev.case == "chatMessage") {
298
+ const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
299
+ const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
300
+ const message = {
301
+ id,
302
+ message: messageText,
303
+ timestamp: Number(timestamp),
304
+ editTimestamp: Number(editTimestamp),
305
+ generated
306
+ };
307
+ this.emit("chatMessage" /* ChatMessage */, message, participant);
308
+ } else if (ev.case == "dataPacketReceived") {
309
+ const participant = this.remoteParticipants.get(ev.value.participantIdentity);
310
+ const dataPacket = ev.value.value;
311
+ switch (dataPacket.case) {
312
+ case "user":
313
+ const buffer = import_ffi_client.FfiClient.instance.copyBuffer(
314
+ dataPacket.value.data.data.dataPtr,
315
+ Number(dataPacket.value.data.data.dataLen)
316
+ );
317
+ new import_ffi_client.FfiHandle(dataPacket.value.data.handle.id).dispose();
369
318
  this.emit(
370
- "participantEncryptionStatusChanged" /* ParticipantEncryptionStatusChanged */,
371
- !!ev.value.isEncrypted,
372
- participant
319
+ "dataReceived" /* DataReceived */,
320
+ buffer,
321
+ participant,
322
+ ev.value.kind,
323
+ dataPacket.value.topic
373
324
  );
374
- } catch (e) {
375
- console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${e.message}`);
325
+ break;
326
+ case "sipDtmf":
327
+ const { code, digit } = dataPacket.value;
328
+ this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
329
+ break;
330
+ default:
331
+ break;
332
+ }
333
+ } else if (ev.case == "e2eeStateChanged") {
334
+ if (ev.value.state == import_e2ee_pb.EncryptionState.INTERNAL_ERROR) {
335
+ this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
336
+ }
337
+ } else if (ev.case == "connectionStateChanged") {
338
+ this.connectionState = ev.value.state;
339
+ this.emit("connectionStateChanged" /* ConnectionStateChanged */, this.connectionState);
340
+ } else if (ev.case == "disconnected") {
341
+ this.emit("disconnected" /* Disconnected */, ev.value.reason);
342
+ } else if (ev.case == "reconnecting") {
343
+ this.emit("reconnecting" /* Reconnecting */);
344
+ } else if (ev.case == "reconnected") {
345
+ this.emit("reconnected" /* Reconnected */);
346
+ } else if (ev.case == "roomSidChanged") {
347
+ this.emit("roomSidChanged" /* RoomSidChanged */, ev.value.sid);
348
+ } else if (ev.case === "streamHeaderReceived" && ev.value.header) {
349
+ this.handleStreamHeader(ev.value.header, ev.value.participantIdentity);
350
+ } else if (ev.case === "streamChunkReceived" && ev.value.chunk) {
351
+ this.handleStreamChunk(ev.value.chunk);
352
+ } else if (ev.case === "streamTrailerReceived" && ev.value.trailer) {
353
+ this.handleStreamTrailer(ev.value.trailer);
354
+ } else if (ev.case === "roomUpdated") {
355
+ this.info = ev.value;
356
+ this.emit("roomUpdated" /* RoomUpdated */);
357
+ } else if (ev.case === "moved") {
358
+ this.info = ev.value;
359
+ this.emit("moved" /* Moved */);
360
+ } else if (ev.case === "participantsUpdated") {
361
+ for (const info of ev.value.participants) {
362
+ const participant = this.retrieveParticipantByIdentity(info.identity);
363
+ if (participant) {
364
+ participant.info = info;
376
365
  }
377
366
  }
378
- } finally {
379
- unlock();
367
+ } else if (ev.case === "participantEncryptionStatusChanged") {
368
+ try {
369
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
370
+ this.emit(
371
+ "participantEncryptionStatusChanged" /* ParticipantEncryptionStatusChanged */,
372
+ !!ev.value.isEncrypted,
373
+ participant
374
+ );
375
+ } catch (e) {
376
+ console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${e.message}`);
377
+ }
380
378
  }
381
379
  };
382
380
  }
@@ -452,10 +450,10 @@ class Room extends import_events.default {
452
450
  }
453
451
  /**
454
452
  * Connects to a LiveKit room using the provided URL and access token.
455
- * @param url The WebSocket URL of the LiveKit server
456
- * @param token A valid LiveKit access token for authentication
457
- * @param opts Optional room configuration options
458
- * @throws ConnectError if connection fails
453
+ * @param url - The WebSocket URL of the LiveKit server
454
+ * @param token - A valid LiveKit access token for authentication
455
+ * @param opts - Optional room configuration options
456
+ * @throws ConnectError - if connection fails
459
457
  */
460
458
  async connect(url, token, opts) {
461
459
  const options = { ...defaultRoomOptions, ...opts };
@@ -485,7 +483,7 @@ class Room extends import_events.default {
485
483
  this.connectionState = import_room_pb.ConnectionState.CONN_CONNECTED;
486
484
  this.localParticipant = new import_participant.LocalParticipant(
487
485
  cb.message.value.localParticipant,
488
- this.roomEventLock
486
+ this.ffiEventLock
489
487
  );
490
488
  for (const pt of cb.message.value.participants) {
491
489
  const rp = this.createRemoteParticipant(pt.participant);
@@ -518,7 +516,7 @@ class Room extends import_events.default {
518
516
  }
519
517
  });
520
518
  await import_ffi_client.FfiClient.instance.waitFor((ev) => {
521
- return ev.message.case == "connect" && ev.message.value.asyncId == res.asyncId;
519
+ return ev.message.case == "disconnect" && ev.message.value.asyncId == res.asyncId;
522
520
  });
523
521
  import_ffi_client.FfiClient.instance.removeListener(import_ffi_client.FfiClientEvent.FfiEvent, this.onFfiEvent);
524
522
  this.removeAllListeners();
@@ -526,9 +524,9 @@ class Room extends import_events.default {
526
524
  /**
527
525
  * Registers a handler for incoming text data streams on a specific topic.
528
526
  * Text streams are used for receiving structured text data from other participants.
529
- * @param topic The topic to listen for text streams on
530
- * @param callback Function to handle incoming text stream data
531
- * @throws Error if a handler for this topic is already registered
527
+ * @param topic - The topic to listen for text streams on
528
+ * @param callback - Function to handle incoming text stream data
529
+ * @throws Error - if a handler for this topic is already registered
532
530
  */
533
531
  registerTextStreamHandler(topic, callback) {
534
532
  if (this.textStreamHandlers.has(topic)) {
@@ -542,9 +540,9 @@ class Room extends import_events.default {
542
540
  /**
543
541
  * Registers a handler for incoming byte data streams on a specific topic.
544
542
  * Byte streams are used for receiving binary data like files from other participants.
545
- * @param topic The topic to listen for byte streams on
546
- * @param callback Function to handle incoming byte stream data
547
- * @throws Error if a handler for this topic is already registered
543
+ * @param topic - The topic to listen for byte streams on
544
+ * @param callback - Function to handle incoming byte stream data
545
+ * @throws Error - if a handler for this topic is already registered
548
546
  */
549
547
  registerByteStreamHandler(topic, callback) {
550
548
  if (this.byteStreamHandlers.has(topic)) {