@livekit/rtc-node 0.13.21 → 0.13.22

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