@livekit/rtc-node 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/audio_frame.cjs +94 -0
  2. package/dist/audio_frame.cjs.map +1 -0
  3. package/dist/audio_frame.js +64 -67
  4. package/dist/audio_frame.js.map +1 -1
  5. package/dist/audio_resampler.cjs +153 -0
  6. package/dist/audio_resampler.cjs.map +1 -0
  7. package/dist/audio_resampler.js +129 -134
  8. package/dist/audio_resampler.js.map +1 -1
  9. package/dist/audio_source.cjs +116 -0
  10. package/dist/audio_source.cjs.map +1 -0
  11. package/dist/audio_source.js +92 -85
  12. package/dist/audio_source.js.map +1 -1
  13. package/dist/audio_stream.cjs +104 -0
  14. package/dist/audio_stream.cjs.map +1 -0
  15. package/dist/audio_stream.js +77 -78
  16. package/dist/audio_stream.js.map +1 -1
  17. package/dist/e2ee.cjs +268 -0
  18. package/dist/e2ee.cjs.map +1 -0
  19. package/dist/e2ee.d.ts.map +1 -1
  20. package/dist/e2ee.js +244 -221
  21. package/dist/e2ee.js.map +1 -1
  22. package/dist/ffi_client.cjs +101 -0
  23. package/dist/ffi_client.cjs.map +1 -0
  24. package/dist/ffi_client.js +73 -48
  25. package/dist/ffi_client.js.map +1 -1
  26. package/dist/index.cjs +188 -0
  27. package/dist/index.cjs.map +1 -0
  28. package/dist/index.js +130 -48
  29. package/dist/index.js.map +1 -1
  30. package/dist/napi/native.d.cjs +17 -0
  31. package/dist/napi/native.d.cjs.map +1 -0
  32. package/dist/napi/native.d.js +1 -0
  33. package/dist/napi/native.d.js.map +1 -0
  34. package/dist/napi/native.d.ts +5 -5
  35. package/dist/native.cjs +301 -0
  36. package/dist/native.d.ts +19 -0
  37. package/dist/native.js +15 -0
  38. package/dist/participant.cjs +388 -0
  39. package/dist/participant.cjs.map +1 -0
  40. package/dist/participant.js +363 -339
  41. package/dist/participant.js.map +1 -1
  42. package/dist/proto/audio_frame_pb.cjs +193 -0
  43. package/dist/proto/audio_frame_pb.cjs.map +1 -0
  44. package/dist/proto/audio_frame_pb.js +120 -320
  45. package/dist/proto/audio_frame_pb.js.map +1 -1
  46. package/dist/proto/e2ee_pb.cjs +131 -0
  47. package/dist/proto/e2ee_pb.cjs.map +1 -0
  48. package/dist/proto/e2ee_pb.js +76 -202
  49. package/dist/proto/e2ee_pb.js.map +1 -1
  50. package/dist/proto/ffi_pb.cjs +76 -0
  51. package/dist/proto/ffi_pb.cjs.map +1 -0
  52. package/dist/proto/ffi_pb.js +33 -92
  53. package/dist/proto/ffi_pb.js.map +1 -1
  54. package/dist/proto/handle_pb.cjs +33 -0
  55. package/dist/proto/handle_pb.cjs.map +1 -0
  56. package/dist/proto/handle_pb.js +6 -22
  57. package/dist/proto/handle_pb.js.map +1 -1
  58. package/dist/proto/participant_pb.cjs +50 -0
  59. package/dist/proto/participant_pb.cjs.map +1 -0
  60. package/dist/proto/participant_pb.js +19 -57
  61. package/dist/proto/participant_pb.js.map +1 -1
  62. package/dist/proto/room_pb.cjs +370 -0
  63. package/dist/proto/room_pb.cjs.map +1 -0
  64. package/dist/proto/room_pb.js +239 -632
  65. package/dist/proto/room_pb.js.map +1 -1
  66. package/dist/proto/rpc_pb.cjs +63 -0
  67. package/dist/proto/rpc_pb.cjs.map +1 -0
  68. package/dist/proto/rpc_pb.js +26 -72
  69. package/dist/proto/rpc_pb.js.map +1 -1
  70. package/dist/proto/stats_pb.cjs +256 -0
  71. package/dist/proto/stats_pb.cjs.map +1 -0
  72. package/dist/proto/stats_pb.js +175 -456
  73. package/dist/proto/stats_pb.js.map +1 -1
  74. package/dist/proto/track_pb.cjs +116 -0
  75. package/dist/proto/track_pb.cjs.map +1 -0
  76. package/dist/proto/track_pb.js +65 -171
  77. package/dist/proto/track_pb.js.map +1 -1
  78. package/dist/proto/video_frame_pb.cjs +161 -0
  79. package/dist/proto/video_frame_pb.cjs.map +1 -0
  80. package/dist/proto/video_frame_pb.js +101 -269
  81. package/dist/proto/video_frame_pb.js.map +1 -1
  82. package/dist/room.cjs +440 -0
  83. package/dist/room.cjs.map +1 -0
  84. package/dist/room.js +384 -373
  85. package/dist/room.js.map +1 -1
  86. package/dist/rpc.cjs +89 -0
  87. package/dist/rpc.cjs.map +1 -0
  88. package/dist/rpc.js +59 -63
  89. package/dist/rpc.js.map +1 -1
  90. package/dist/track.cjs +100 -0
  91. package/dist/track.cjs.map +1 -0
  92. package/dist/track.js +66 -62
  93. package/dist/track.js.map +1 -1
  94. package/dist/track_publication.cjs +106 -0
  95. package/dist/track_publication.cjs.map +1 -0
  96. package/dist/track_publication.js +76 -74
  97. package/dist/track_publication.js.map +1 -1
  98. package/dist/transcription.cjs +17 -0
  99. package/dist/transcription.cjs.map +1 -0
  100. package/dist/transcription.js +0 -1
  101. package/dist/transcription.js.map +1 -1
  102. package/dist/types.cjs +17 -0
  103. package/dist/types.cjs.map +1 -0
  104. package/dist/types.js +0 -1
  105. package/dist/types.js.map +1 -1
  106. package/dist/version.cjs +29 -0
  107. package/dist/version.cjs.map +1 -0
  108. package/dist/version.d.ts +1 -1
  109. package/dist/version.js +4 -1
  110. package/dist/version.js.map +1 -1
  111. package/dist/video_frame.cjs +242 -0
  112. package/dist/video_frame.cjs.map +1 -0
  113. package/dist/video_frame.js +212 -201
  114. package/dist/video_frame.js.map +1 -1
  115. package/dist/video_source.cjs +63 -0
  116. package/dist/video_source.cjs.map +1 -0
  117. package/dist/video_source.d.ts.map +1 -1
  118. package/dist/video_source.js +42 -37
  119. package/dist/video_source.js.map +1 -1
  120. package/dist/video_stream.cjs +103 -0
  121. package/dist/video_stream.cjs.map +1 -0
  122. package/dist/video_stream.js +76 -77
  123. package/dist/video_stream.js.map +1 -1
  124. package/package.json +18 -9
  125. package/src/audio_frame.ts +2 -2
  126. package/src/audio_source.ts +2 -2
  127. package/src/e2ee.ts +2 -2
  128. package/src/napi/native.d.ts +5 -5
  129. package/src/version.ts +1 -1
  130. package/src/video_frame.ts +1 -1
  131. package/src/video_source.ts +5 -1
package/dist/room.js CHANGED
@@ -1,396 +1,407 @@
1
- // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
- //
3
- // SPDX-License-Identifier: Apache-2.0
4
- import { create } from '@bufbuild/protobuf';
5
- import EventEmitter from 'events';
6
- import { E2EEManager } from './e2ee.js';
7
- import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
8
- import { LocalParticipant, RemoteParticipant } from './participant.js';
9
- import { EncryptionState } from './proto/e2ee_pb.js';
10
- import { ConnectRequestSchema, ConnectionState, ContinualGatheringPolicy, IceTransportType, } from './proto/room_pb.js';
11
- import { TrackKind } from './proto/track_pb.js';
12
- import { RemoteAudioTrack, RemoteVideoTrack } from './track.js';
13
- import { RemoteTrackPublication } from './track_publication.js';
14
- export const defaultRtcConfiguration = {
15
- iceTransportType: IceTransportType.TRANSPORT_ALL,
16
- continualGatheringPolicy: ContinualGatheringPolicy.GATHER_CONTINUALLY,
17
- iceServers: [],
1
+ import { create } from "@bufbuild/protobuf";
2
+ import EventEmitter from "events";
3
+ import { E2EEManager } from "./e2ee.js";
4
+ import { FfiClient, FfiClientEvent, FfiHandle } from "./ffi_client.js";
5
+ import { LocalParticipant, RemoteParticipant } from "./participant.js";
6
+ import { EncryptionState } from "./proto/e2ee_pb.js";
7
+ import {
8
+ ConnectRequestSchema,
9
+ ConnectionState,
10
+ ContinualGatheringPolicy,
11
+ IceTransportType
12
+ } from "./proto/room_pb.js";
13
+ import { TrackKind } from "./proto/track_pb.js";
14
+ import { RemoteAudioTrack, RemoteVideoTrack } from "./track.js";
15
+ import { RemoteTrackPublication } from "./track_publication.js";
16
+ const defaultRtcConfiguration = {
17
+ iceTransportType: IceTransportType.TRANSPORT_ALL,
18
+ continualGatheringPolicy: ContinualGatheringPolicy.GATHER_CONTINUALLY,
19
+ iceServers: []
18
20
  };
19
- export const defaultRoomOptions = {
20
- autoSubscribe: true,
21
- dynacast: false,
22
- e2ee: undefined,
23
- rtcConfig: undefined,
24
- adaptiveStream: false,
25
- joinRetries: 1,
21
+ const defaultRoomOptions = {
22
+ autoSubscribe: true,
23
+ dynacast: false,
24
+ e2ee: void 0,
25
+ rtcConfig: void 0,
26
+ adaptiveStream: false,
27
+ joinRetries: 1
26
28
  };
27
- export class Room extends EventEmitter {
28
- constructor() {
29
- super();
30
- this.connectionState = ConnectionState.CONN_DISCONNECTED;
31
- this.remoteParticipants = new Map();
32
- this.onFfiEvent = (ffiEvent) => {
33
- if (!this.localParticipant || !this.ffiHandle || !this.info) {
34
- throw TypeError('cannot handle ffi events before connectCallback');
35
- }
36
- if (ffiEvent.message.case == 'rpcMethodInvocation') {
37
- if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
38
- this.localParticipant.handleRpcMethodInvocation(ffiEvent.message.value.invocationId, ffiEvent.message.value.method, ffiEvent.message.value.requestId, ffiEvent.message.value.callerIdentity, ffiEvent.message.value.payload, ffiEvent.message.value.responseTimeoutMs);
39
- }
40
- return;
41
- }
42
- else if (ffiEvent.message.case != 'roomEvent' ||
43
- ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
44
- return;
45
- }
46
- const ev = ffiEvent.message.value.message;
47
- if (ev.case == 'participantConnected') {
48
- const participant = this.createRemoteParticipant(ev.value.info);
49
- this.remoteParticipants.set(participant.identity, participant);
50
- this.emit(RoomEvent.ParticipantConnected, participant);
51
- }
52
- else if (ev.case == 'participantDisconnected') {
53
- const participant = this.remoteParticipants.get(ev.value.participantIdentity);
54
- if (participant) {
55
- this.remoteParticipants.delete(participant.identity);
56
- this.emit(RoomEvent.ParticipantDisconnected, participant);
57
- }
58
- }
59
- else if (ev.case == 'localTrackPublished') {
60
- const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
61
- if (!publication) {
62
- throw new TypeError('local track publication not found');
63
- }
64
- this.emit(RoomEvent.LocalTrackPublished, publication, this.localParticipant);
65
- }
66
- else if (ev.case == 'localTrackUnpublished') {
67
- const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
68
- this.localParticipant.trackPublications.delete(ev.value.publicationSid);
69
- if (publication) {
70
- this.emit(RoomEvent.LocalTrackUnpublished, publication, this.localParticipant);
71
- }
72
- }
73
- else if (ev.case == 'localTrackSubscribed') {
74
- const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
75
- if (!publication) {
76
- throw new TypeError('local track publication not found');
77
- }
78
- publication.resolveFirstSubscription();
79
- this.emit(RoomEvent.LocalTrackSubscribed, publication.track);
80
- }
81
- else if (ev.case == 'trackPublished') {
82
- const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
83
- const publication = new RemoteTrackPublication(ev.value.publication);
84
- participant.trackPublications.set(publication.sid, publication);
85
- this.emit(RoomEvent.TrackPublished, publication, participant);
86
- }
87
- else if (ev.case == 'trackUnpublished') {
88
- const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
89
- const publication = participant.trackPublications.get(ev.value.publicationSid);
90
- participant.trackPublications.delete(ev.value.publicationSid);
91
- if (publication) {
92
- this.emit(RoomEvent.TrackUnpublished, publication, participant);
93
- }
94
- }
95
- else if (ev.case == 'trackSubscribed') {
96
- const ownedTrack = ev.value.track;
97
- const trackInfo = ownedTrack.info;
98
- const { participant, publication } = this.requirePublicationOfRemoteParticipant(ev.value.participantIdentity, trackInfo.sid);
99
- publication.subscribed = true;
100
- if (trackInfo.kind == TrackKind.KIND_VIDEO) {
101
- publication.track = new RemoteVideoTrack(ownedTrack);
102
- }
103
- else if (trackInfo.kind == TrackKind.KIND_AUDIO) {
104
- publication.track = new RemoteAudioTrack(ownedTrack);
105
- }
106
- this.emit(RoomEvent.TrackSubscribed, publication.track, publication, participant);
107
- }
108
- else if (ev.case == 'trackUnsubscribed') {
109
- const { participant, publication } = this.requirePublicationOfRemoteParticipant(ev.value.participantIdentity, ev.value.trackSid);
110
- const track = publication.track;
111
- publication.track = undefined;
112
- publication.subscribed = false;
113
- this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);
114
- }
115
- else if (ev.case == 'trackSubscriptionFailed') {
116
- const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
117
- this.emit(RoomEvent.TrackSubscriptionFailed, ev.value.trackSid, participant, ev.value.error);
118
- }
119
- else if (ev.case == 'trackMuted') {
120
- const { participant, publication } = this.requirePublicationOfParticipant(ev.value.participantIdentity, ev.value.trackSid);
121
- publication.info.muted = true;
122
- if (publication.track) {
123
- publication.track.info.muted = true;
124
- }
125
- this.emit(RoomEvent.TrackMuted, publication, participant);
126
- }
127
- else if (ev.case == 'trackUnmuted') {
128
- const { participant, publication } = this.requirePublicationOfParticipant(ev.value.participantIdentity, ev.value.trackSid);
129
- publication.info.muted = false;
130
- if (publication.track) {
131
- publication.track.info.muted = false;
132
- }
133
- this.emit(RoomEvent.TrackUnmuted, publication, participant);
134
- }
135
- else if (ev.case == 'activeSpeakersChanged') {
136
- const activeSpeakers = ev.value.participantIdentities.map((identity) => this.requireParticipantByIdentity(identity));
137
- this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
138
- }
139
- else if (ev.case == 'roomMetadataChanged') {
140
- this.info.metadata = ev.value.metadata;
141
- this.emit(RoomEvent.RoomMetadataChanged, this.info.metadata);
142
- }
143
- else if (ev.case == 'participantMetadataChanged') {
144
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
145
- participant.info.metadata = ev.value.metadata;
146
- this.emit(RoomEvent.ParticipantMetadataChanged, participant.metadata, participant);
147
- }
148
- else if (ev.case == 'participantNameChanged') {
149
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
150
- participant.info.name = ev.value.name;
151
- this.emit(RoomEvent.ParticipantNameChanged, participant.name, participant);
152
- }
153
- else if (ev.case == 'participantAttributesChanged') {
154
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
155
- participant.info.attributes = ev.value.attributes.reduce((acc, value) => {
156
- acc[value.key] = value.value;
157
- return acc;
158
- }, {});
159
- if (Object.keys(ev.value.changedAttributes).length > 0) {
160
- const changedAttributes = ev.value.changedAttributes.reduce((acc, value) => {
161
- acc[value.key] = value.value;
162
- return acc;
163
- }, {});
164
- this.emit(RoomEvent.ParticipantAttributesChanged, changedAttributes, participant);
165
- }
166
- }
167
- else if (ev.case == 'connectionQualityChanged') {
168
- const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
169
- this.emit(RoomEvent.ConnectionQualityChanged, ev.value.quality, participant);
170
- }
171
- else if (ev.case == 'chatMessage') {
172
- const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
173
- const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
174
- const message = {
175
- id,
176
- message: messageText,
177
- timestamp: Number(timestamp),
178
- editTimestamp: Number(editTimestamp),
179
- generated,
180
- };
181
- this.emit(RoomEvent.ChatMessage, message, participant);
182
- }
183
- else if (ev.case == 'dataPacketReceived') {
184
- // Can be undefined if the data is sent from a Server SDK
185
- const participant = this.remoteParticipants.get(ev.value.participantIdentity);
186
- const dataPacket = ev.value.value;
187
- switch (dataPacket.case) {
188
- case 'user':
189
- const data = dataPacket.value.data.data;
190
- const buffer = FfiClient.instance.copyBuffer(data.dataPtr, Number(data.dataLen));
191
- new FfiHandle(dataPacket.value.data.handle.id).dispose();
192
- this.emit(RoomEvent.DataReceived, buffer, participant, ev.value.kind, dataPacket.value.topic);
193
- break;
194
- case 'sipDtmf':
195
- const { code, digit } = dataPacket.value;
196
- this.emit(RoomEvent.DtmfReceived, code, digit, participant);
197
- break;
198
- default:
199
- break;
200
- }
201
- }
202
- else if (ev.case == 'e2eeStateChanged') {
203
- if (ev.value.state == EncryptionState.INTERNAL_ERROR) {
204
- // throw generic error until Rust SDK is updated to supply the error alongside INTERNAL_ERROR
205
- this.emit(RoomEvent.EncryptionError, new Error('internal server error'));
206
- }
207
- }
208
- else if (ev.case == 'connectionStateChanged') {
209
- this.connectionState = ev.value.state;
210
- this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);
211
- /*} else if (ev.case == 'connected') {
212
- this.emit(RoomEvent.Connected);*/
213
- }
214
- else if (ev.case == 'disconnected') {
215
- this.emit(RoomEvent.Disconnected, ev.value.reason);
216
- }
217
- else if (ev.case == 'reconnecting') {
218
- this.emit(RoomEvent.Reconnecting);
219
- }
220
- else if (ev.case == 'reconnected') {
221
- this.emit(RoomEvent.Reconnected);
222
- }
223
- else if (ev.case == 'roomSidChanged') {
224
- this.emit(RoomEvent.RoomSidChanged, ev.value.sid);
225
- }
226
- };
227
- }
228
- get name() {
229
- return this.info?.name;
230
- }
231
- get metadata() {
232
- return this.info?.metadata;
233
- }
234
- get isConnected() {
235
- return this.ffiHandle != undefined && this.connectionState != ConnectionState.CONN_DISCONNECTED;
236
- }
237
- async getSid() {
238
- if (!this.isConnected) {
239
- return '';
29
+ class Room extends EventEmitter {
30
+ constructor() {
31
+ super();
32
+ this.connectionState = ConnectionState.CONN_DISCONNECTED;
33
+ this.remoteParticipants = /* @__PURE__ */ new Map();
34
+ this.onFfiEvent = (ffiEvent) => {
35
+ if (!this.localParticipant || !this.ffiHandle || !this.info) {
36
+ throw TypeError("cannot handle ffi events before connectCallback");
37
+ }
38
+ if (ffiEvent.message.case == "rpcMethodInvocation") {
39
+ if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
40
+ this.localParticipant.handleRpcMethodInvocation(
41
+ ffiEvent.message.value.invocationId,
42
+ ffiEvent.message.value.method,
43
+ ffiEvent.message.value.requestId,
44
+ ffiEvent.message.value.callerIdentity,
45
+ ffiEvent.message.value.payload,
46
+ ffiEvent.message.value.responseTimeoutMs
47
+ );
240
48
  }
241
- if (this.info && this.info.sid !== '') {
242
- return this.info.sid;
49
+ return;
50
+ } else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
51
+ return;
52
+ }
53
+ const ev = ffiEvent.message.value.message;
54
+ if (ev.case == "participantConnected") {
55
+ const participant = this.createRemoteParticipant(ev.value.info);
56
+ this.remoteParticipants.set(participant.identity, participant);
57
+ this.emit("participantConnected" /* ParticipantConnected */, participant);
58
+ } else if (ev.case == "participantDisconnected") {
59
+ const participant = this.remoteParticipants.get(ev.value.participantIdentity);
60
+ if (participant) {
61
+ this.remoteParticipants.delete(participant.identity);
62
+ this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
243
63
  }
244
- return new Promise((resolve, reject) => {
245
- const handleRoomUpdate = (sid) => {
246
- if (sid !== '') {
247
- this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);
248
- resolve(sid);
249
- }
250
- };
251
- this.on(RoomEvent.RoomSidChanged, handleRoomUpdate);
252
- this.once(RoomEvent.Disconnected, () => {
253
- this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);
254
- reject('Room disconnected before room server id was available');
255
- });
256
- });
257
- }
258
- async connect(url, token, opts) {
259
- const options = { ...defaultRoomOptions, ...opts };
260
- const req = create(ConnectRequestSchema, {
261
- url: url,
262
- token: token,
263
- options,
264
- });
265
- const res = FfiClient.instance.request({
266
- message: {
267
- case: 'connect',
268
- value: req,
269
- },
270
- });
271
- const cb = await FfiClient.instance.waitFor((ev) => {
272
- return ev.message.case == 'connect' && ev.message.value.asyncId == res.asyncId;
273
- });
274
- if (cb.message.case !== 'result') {
275
- throw new ConnectError(cb.message.value ?? 'Unknown error');
64
+ } else if (ev.case == "localTrackPublished") {
65
+ const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
66
+ if (!publication) {
67
+ throw new TypeError("local track publication not found");
276
68
  }
277
- const { room, localParticipant, participants } = cb.message.value;
278
- this.ffiHandle = new FfiHandle(room.handle.id);
279
- if (options.e2ee) {
280
- this.e2eeManager = new E2EEManager(this.ffiHandle.handle, options.e2ee);
69
+ this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
70
+ } else if (ev.case == "localTrackUnpublished") {
71
+ const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
72
+ this.localParticipant.trackPublications.delete(ev.value.publicationSid);
73
+ if (publication) {
74
+ this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
281
75
  }
282
- this.info = room.info;
283
- this.connectionState = ConnectionState.CONN_CONNECTED;
284
- this.localParticipant = new LocalParticipant(localParticipant);
285
- for (const pt of participants) {
286
- const rp = this.createRemoteParticipant(pt.participant);
287
- for (const pub of pt.publications) {
288
- const publication = new RemoteTrackPublication(pub);
289
- rp.trackPublications.set(publication.sid, publication);
290
- }
76
+ } else if (ev.case == "localTrackSubscribed") {
77
+ const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
78
+ if (!publication) {
79
+ throw new TypeError("local track publication not found");
291
80
  }
292
- FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onFfiEvent);
293
- }
294
- async disconnect() {
295
- if (!this.isConnected || !this.ffiHandle) {
296
- return;
81
+ publication.resolveFirstSubscription();
82
+ this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
83
+ } else if (ev.case == "trackPublished") {
84
+ const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
85
+ const publication = new RemoteTrackPublication(ev.value.publication);
86
+ participant.trackPublications.set(publication.sid, publication);
87
+ this.emit("trackPublished" /* TrackPublished */, publication, participant);
88
+ } else if (ev.case == "trackUnpublished") {
89
+ const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
90
+ const publication = participant.trackPublications.get(ev.value.publicationSid);
91
+ participant.trackPublications.delete(ev.value.publicationSid);
92
+ if (publication) {
93
+ this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
297
94
  }
298
- FfiClient.instance.request({
299
- message: {
300
- case: 'disconnect',
301
- value: {
302
- roomHandle: this.ffiHandle.handle,
303
- },
304
- },
305
- });
306
- FfiClient.instance.removeListener(FfiClientEvent.FfiEvent, this.onFfiEvent);
307
- this.removeAllListeners();
308
- }
309
- retrieveParticipantByIdentity(identity) {
310
- if (this.localParticipant?.identity === identity) {
311
- return this.localParticipant;
95
+ } else if (ev.case == "trackSubscribed") {
96
+ const ownedTrack = ev.value.track;
97
+ const trackInfo = ownedTrack.info;
98
+ const { participant, publication } = this.requirePublicationOfRemoteParticipant(
99
+ ev.value.participantIdentity,
100
+ trackInfo.sid
101
+ );
102
+ publication.subscribed = true;
103
+ if (trackInfo.kind == TrackKind.KIND_VIDEO) {
104
+ publication.track = new RemoteVideoTrack(ownedTrack);
105
+ } else if (trackInfo.kind == TrackKind.KIND_AUDIO) {
106
+ publication.track = new RemoteAudioTrack(ownedTrack);
312
107
  }
313
- else {
314
- return this.remoteParticipants.get(identity);
108
+ this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
109
+ } else if (ev.case == "trackUnsubscribed") {
110
+ const { participant, publication } = this.requirePublicationOfRemoteParticipant(
111
+ ev.value.participantIdentity,
112
+ ev.value.trackSid
113
+ );
114
+ const track = publication.track;
115
+ publication.track = void 0;
116
+ publication.subscribed = false;
117
+ this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
118
+ } else if (ev.case == "trackSubscriptionFailed") {
119
+ const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
120
+ this.emit("trackSubscriptionFailed" /* TrackSubscriptionFailed */, ev.value.trackSid, participant, ev.value.error);
121
+ } else if (ev.case == "trackMuted") {
122
+ const { participant, publication } = this.requirePublicationOfParticipant(
123
+ ev.value.participantIdentity,
124
+ ev.value.trackSid
125
+ );
126
+ publication.info.muted = true;
127
+ if (publication.track) {
128
+ publication.track.info.muted = true;
315
129
  }
316
- }
317
- requireParticipantByIdentity(identity) {
318
- if (this.localParticipant?.identity === identity) {
319
- return this.localParticipant;
130
+ this.emit("trackMuted" /* TrackMuted */, publication, participant);
131
+ } else if (ev.case == "trackUnmuted") {
132
+ const { participant, publication } = this.requirePublicationOfParticipant(
133
+ ev.value.participantIdentity,
134
+ ev.value.trackSid
135
+ );
136
+ publication.info.muted = false;
137
+ if (publication.track) {
138
+ publication.track.info.muted = false;
320
139
  }
321
- else if (this.remoteParticipants.has(identity)) {
322
- return this.remoteParticipants.get(identity);
140
+ this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
141
+ } else if (ev.case == "activeSpeakersChanged") {
142
+ const activeSpeakers = ev.value.participantIdentities.map(
143
+ (identity) => this.requireParticipantByIdentity(identity)
144
+ );
145
+ this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
146
+ } else if (ev.case == "roomMetadataChanged") {
147
+ this.info.metadata = ev.value.metadata;
148
+ this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
149
+ } else if (ev.case == "participantMetadataChanged") {
150
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
151
+ participant.info.metadata = ev.value.metadata;
152
+ this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
153
+ } else if (ev.case == "participantNameChanged") {
154
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
155
+ participant.info.name = ev.value.name;
156
+ this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
157
+ } else if (ev.case == "participantAttributesChanged") {
158
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
159
+ participant.info.attributes = ev.value.attributes.reduce(
160
+ (acc, value) => {
161
+ acc[value.key] = value.value;
162
+ return acc;
163
+ },
164
+ {}
165
+ );
166
+ if (Object.keys(ev.value.changedAttributes).length > 0) {
167
+ const changedAttributes = ev.value.changedAttributes.reduce(
168
+ (acc, value) => {
169
+ acc[value.key] = value.value;
170
+ return acc;
171
+ },
172
+ {}
173
+ );
174
+ this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
323
175
  }
324
- else {
325
- throw new TypeError(`participant ${identity} not found`);
176
+ } else if (ev.case == "connectionQualityChanged") {
177
+ const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
178
+ this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
179
+ } else if (ev.case == "chatMessage") {
180
+ const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
181
+ const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
182
+ const message = {
183
+ id,
184
+ message: messageText,
185
+ timestamp: Number(timestamp),
186
+ editTimestamp: Number(editTimestamp),
187
+ generated
188
+ };
189
+ this.emit("chatMessage" /* ChatMessage */, message, participant);
190
+ } else if (ev.case == "dataPacketReceived") {
191
+ const participant = this.remoteParticipants.get(ev.value.participantIdentity);
192
+ const dataPacket = ev.value.value;
193
+ switch (dataPacket.case) {
194
+ case "user":
195
+ const data = dataPacket.value.data.data;
196
+ const buffer = FfiClient.instance.copyBuffer(data.dataPtr, Number(data.dataLen));
197
+ new FfiHandle(dataPacket.value.data.handle.id).dispose();
198
+ this.emit(
199
+ "dataReceived" /* DataReceived */,
200
+ buffer,
201
+ participant,
202
+ ev.value.kind,
203
+ dataPacket.value.topic
204
+ );
205
+ break;
206
+ case "sipDtmf":
207
+ const { code, digit } = dataPacket.value;
208
+ this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
209
+ break;
210
+ default:
211
+ break;
326
212
  }
327
- }
328
- requireRemoteParticipant(identity) {
329
- const participant = this.remoteParticipants.get(identity);
330
- if (!participant) {
331
- throw new TypeError(`participant ${identity} not found`);
213
+ } else if (ev.case == "e2eeStateChanged") {
214
+ if (ev.value.state == EncryptionState.INTERNAL_ERROR) {
215
+ this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
332
216
  }
333
- return participant;
217
+ } else if (ev.case == "connectionStateChanged") {
218
+ this.connectionState = ev.value.state;
219
+ this.emit("connectionStateChanged" /* ConnectionStateChanged */, this.connectionState);
220
+ } else if (ev.case == "disconnected") {
221
+ this.emit("disconnected" /* Disconnected */, ev.value.reason);
222
+ } else if (ev.case == "reconnecting") {
223
+ this.emit("reconnecting" /* Reconnecting */);
224
+ } else if (ev.case == "reconnected") {
225
+ this.emit("reconnected" /* Reconnected */);
226
+ } else if (ev.case == "roomSidChanged") {
227
+ this.emit("roomSidChanged" /* RoomSidChanged */, ev.value.sid);
228
+ }
229
+ };
230
+ }
231
+ get name() {
232
+ var _a;
233
+ return (_a = this.info) == null ? void 0 : _a.name;
234
+ }
235
+ get metadata() {
236
+ var _a;
237
+ return (_a = this.info) == null ? void 0 : _a.metadata;
238
+ }
239
+ get isConnected() {
240
+ return this.ffiHandle != void 0 && this.connectionState != ConnectionState.CONN_DISCONNECTED;
241
+ }
242
+ async getSid() {
243
+ if (!this.isConnected) {
244
+ return "";
334
245
  }
335
- requirePublicationOfParticipant(identity, trackSid) {
336
- const participant = this.requireParticipantByIdentity(identity);
337
- const publication = participant.trackPublications.get(trackSid);
338
- if (!publication) {
339
- throw new TypeError(`publication ${trackSid} not found`);
340
- }
341
- return { participant, publication };
246
+ if (this.info && this.info.sid !== "") {
247
+ return this.info.sid;
342
248
  }
343
- requirePublicationOfRemoteParticipant(identity, trackSid) {
344
- const participant = this.requireRemoteParticipant(identity);
345
- const publication = participant.trackPublications.get(trackSid);
346
- if (!publication) {
347
- throw new TypeError(`publication ${trackSid} not found`);
249
+ return new Promise((resolve, reject) => {
250
+ const handleRoomUpdate = (sid) => {
251
+ if (sid !== "") {
252
+ this.off("roomSidChanged" /* RoomSidChanged */, handleRoomUpdate);
253
+ resolve(sid);
348
254
  }
349
- return { participant, publication };
255
+ };
256
+ this.on("roomSidChanged" /* RoomSidChanged */, handleRoomUpdate);
257
+ this.once("disconnected" /* Disconnected */, () => {
258
+ this.off("roomSidChanged" /* RoomSidChanged */, handleRoomUpdate);
259
+ reject("Room disconnected before room server id was available");
260
+ });
261
+ });
262
+ }
263
+ async connect(url, token, opts) {
264
+ const options = { ...defaultRoomOptions, ...opts };
265
+ const req = create(ConnectRequestSchema, {
266
+ url,
267
+ token,
268
+ options
269
+ });
270
+ const res = FfiClient.instance.request({
271
+ message: {
272
+ case: "connect",
273
+ value: req
274
+ }
275
+ });
276
+ const cb = await FfiClient.instance.waitFor((ev) => {
277
+ return ev.message.case == "connect" && ev.message.value.asyncId == res.asyncId;
278
+ });
279
+ if (cb.message.case !== "result") {
280
+ throw new ConnectError(cb.message.value ?? "Unknown error");
281
+ }
282
+ const { room, localParticipant, participants } = cb.message.value;
283
+ this.ffiHandle = new FfiHandle(room.handle.id);
284
+ if (options.e2ee) {
285
+ this.e2eeManager = new E2EEManager(this.ffiHandle.handle, options.e2ee);
286
+ }
287
+ this.info = room.info;
288
+ this.connectionState = ConnectionState.CONN_CONNECTED;
289
+ this.localParticipant = new LocalParticipant(localParticipant);
290
+ for (const pt of participants) {
291
+ const rp = this.createRemoteParticipant(pt.participant);
292
+ for (const pub of pt.publications) {
293
+ const publication = new RemoteTrackPublication(pub);
294
+ rp.trackPublications.set(publication.sid, publication);
295
+ }
296
+ }
297
+ FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onFfiEvent);
298
+ }
299
+ async disconnect() {
300
+ if (!this.isConnected || !this.ffiHandle) {
301
+ return;
350
302
  }
351
- createRemoteParticipant(ownedInfo) {
352
- if (this.remoteParticipants.has(ownedInfo.info.identity)) {
353
- throw new Error('Participant already exists');
303
+ FfiClient.instance.request({
304
+ message: {
305
+ case: "disconnect",
306
+ value: {
307
+ roomHandle: this.ffiHandle.handle
354
308
  }
355
- const participant = new RemoteParticipant(ownedInfo);
356
- this.remoteParticipants.set(ownedInfo.info.identity, participant);
357
- return participant;
309
+ }
310
+ });
311
+ FfiClient.instance.removeListener(FfiClientEvent.FfiEvent, this.onFfiEvent);
312
+ this.removeAllListeners();
313
+ }
314
+ retrieveParticipantByIdentity(identity) {
315
+ var _a;
316
+ if (((_a = this.localParticipant) == null ? void 0 : _a.identity) === identity) {
317
+ return this.localParticipant;
318
+ } else {
319
+ return this.remoteParticipants.get(identity);
358
320
  }
359
- }
360
- export class ConnectError extends Error {
361
- constructor(message) {
362
- super(message);
321
+ }
322
+ requireParticipantByIdentity(identity) {
323
+ var _a;
324
+ if (((_a = this.localParticipant) == null ? void 0 : _a.identity) === identity) {
325
+ return this.localParticipant;
326
+ } else if (this.remoteParticipants.has(identity)) {
327
+ return this.remoteParticipants.get(identity);
328
+ } else {
329
+ throw new TypeError(`participant ${identity} not found`);
330
+ }
331
+ }
332
+ requireRemoteParticipant(identity) {
333
+ const participant = this.remoteParticipants.get(identity);
334
+ if (!participant) {
335
+ throw new TypeError(`participant ${identity} not found`);
336
+ }
337
+ return participant;
338
+ }
339
+ requirePublicationOfParticipant(identity, trackSid) {
340
+ const participant = this.requireParticipantByIdentity(identity);
341
+ const publication = participant.trackPublications.get(trackSid);
342
+ if (!publication) {
343
+ throw new TypeError(`publication ${trackSid} not found`);
344
+ }
345
+ return { participant, publication };
346
+ }
347
+ requirePublicationOfRemoteParticipant(identity, trackSid) {
348
+ const participant = this.requireRemoteParticipant(identity);
349
+ const publication = participant.trackPublications.get(trackSid);
350
+ if (!publication) {
351
+ throw new TypeError(`publication ${trackSid} not found`);
363
352
  }
353
+ return { participant, publication };
354
+ }
355
+ createRemoteParticipant(ownedInfo) {
356
+ if (this.remoteParticipants.has(ownedInfo.info.identity)) {
357
+ throw new Error("Participant already exists");
358
+ }
359
+ const participant = new RemoteParticipant(ownedInfo);
360
+ this.remoteParticipants.set(ownedInfo.info.identity, participant);
361
+ return participant;
362
+ }
363
+ }
364
+ class ConnectError extends Error {
365
+ constructor(message) {
366
+ super(message);
367
+ }
364
368
  }
365
- export var RoomEvent;
366
- (function (RoomEvent) {
367
- RoomEvent["ParticipantConnected"] = "participantConnected";
368
- RoomEvent["ParticipantDisconnected"] = "participantDisconnected";
369
- RoomEvent["LocalTrackPublished"] = "localTrackPublished";
370
- RoomEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
371
- RoomEvent["LocalTrackSubscribed"] = "localTrackSubscribed";
372
- RoomEvent["TrackPublished"] = "trackPublished";
373
- RoomEvent["TrackUnpublished"] = "trackUnpublished";
374
- RoomEvent["TrackSubscribed"] = "trackSubscribed";
375
- RoomEvent["TrackUnsubscribed"] = "trackUnsubscribed";
376
- RoomEvent["TrackSubscriptionFailed"] = "trackSubscriptionFailed";
377
- RoomEvent["TrackMuted"] = "trackMuted";
378
- RoomEvent["TrackUnmuted"] = "trackUnmuted";
379
- RoomEvent["ActiveSpeakersChanged"] = "activeSpeakersChanged";
380
- RoomEvent["RoomMetadataChanged"] = "roomMetadataChanged";
381
- RoomEvent["RoomSidChanged"] = "roomSidChanged";
382
- RoomEvent["ParticipantMetadataChanged"] = "participantMetadataChanged";
383
- RoomEvent["ParticipantNameChanged"] = "participantNameChanged";
384
- RoomEvent["ParticipantAttributesChanged"] = "participantAttributesChanged";
385
- RoomEvent["ConnectionQualityChanged"] = "connectionQualityChanged";
386
- RoomEvent["DataReceived"] = "dataReceived";
387
- RoomEvent["ChatMessage"] = "chatMessage";
388
- RoomEvent["DtmfReceived"] = "dtmfReceived";
389
- RoomEvent["EncryptionError"] = "encryptionError";
390
- RoomEvent["ConnectionStateChanged"] = "connectionStateChanged";
391
- RoomEvent["Connected"] = "connected";
392
- RoomEvent["Disconnected"] = "disconnected";
393
- RoomEvent["Reconnecting"] = "reconnecting";
394
- RoomEvent["Reconnected"] = "reconnected";
395
- })(RoomEvent || (RoomEvent = {}));
369
+ var RoomEvent = /* @__PURE__ */ ((RoomEvent2) => {
370
+ RoomEvent2["ParticipantConnected"] = "participantConnected";
371
+ RoomEvent2["ParticipantDisconnected"] = "participantDisconnected";
372
+ RoomEvent2["LocalTrackPublished"] = "localTrackPublished";
373
+ RoomEvent2["LocalTrackUnpublished"] = "localTrackUnpublished";
374
+ RoomEvent2["LocalTrackSubscribed"] = "localTrackSubscribed";
375
+ RoomEvent2["TrackPublished"] = "trackPublished";
376
+ RoomEvent2["TrackUnpublished"] = "trackUnpublished";
377
+ RoomEvent2["TrackSubscribed"] = "trackSubscribed";
378
+ RoomEvent2["TrackUnsubscribed"] = "trackUnsubscribed";
379
+ RoomEvent2["TrackSubscriptionFailed"] = "trackSubscriptionFailed";
380
+ RoomEvent2["TrackMuted"] = "trackMuted";
381
+ RoomEvent2["TrackUnmuted"] = "trackUnmuted";
382
+ RoomEvent2["ActiveSpeakersChanged"] = "activeSpeakersChanged";
383
+ RoomEvent2["RoomMetadataChanged"] = "roomMetadataChanged";
384
+ RoomEvent2["RoomSidChanged"] = "roomSidChanged";
385
+ RoomEvent2["ParticipantMetadataChanged"] = "participantMetadataChanged";
386
+ RoomEvent2["ParticipantNameChanged"] = "participantNameChanged";
387
+ RoomEvent2["ParticipantAttributesChanged"] = "participantAttributesChanged";
388
+ RoomEvent2["ConnectionQualityChanged"] = "connectionQualityChanged";
389
+ RoomEvent2["DataReceived"] = "dataReceived";
390
+ RoomEvent2["ChatMessage"] = "chatMessage";
391
+ RoomEvent2["DtmfReceived"] = "dtmfReceived";
392
+ RoomEvent2["EncryptionError"] = "encryptionError";
393
+ RoomEvent2["ConnectionStateChanged"] = "connectionStateChanged";
394
+ RoomEvent2["Connected"] = "connected";
395
+ RoomEvent2["Disconnected"] = "disconnected";
396
+ RoomEvent2["Reconnecting"] = "reconnecting";
397
+ RoomEvent2["Reconnected"] = "reconnected";
398
+ return RoomEvent2;
399
+ })(RoomEvent || {});
400
+ export {
401
+ ConnectError,
402
+ Room,
403
+ RoomEvent,
404
+ defaultRoomOptions,
405
+ defaultRtcConfiguration
406
+ };
396
407
  //# sourceMappingURL=room.js.map