@memberjunction/livekit-room-core 0.0.1 → 5.42.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.
@@ -0,0 +1,601 @@
1
+ /**
2
+ * @fileoverview {@link LiveKitRoomController} — the framework-agnostic controller for ONE LiveKit room
3
+ * connection. Wraps the livekit-client `Room` behind an injectable factory seam so the controller (and
4
+ * every UI built on it) unit-tests with an in-memory fake `Room` — no WebRTC, no network, no browser.
5
+ *
6
+ * It normalizes LiveKit's event-rich, mutable `Room`/`Participant` surface into:
7
+ * - a single observable {@link LiveKitRoomState} snapshot ({@link State$}) the UI renders from, and
8
+ * - narrow event streams for transient things ({@link Data$}, {@link Errors$}).
9
+ *
10
+ * Media DOM-attach (`track.attach(element)`) stays in the UI layer via {@link LiveKitParticipantView.Raw};
11
+ * the controller never touches the DOM, which is what keeps it framework-agnostic.
12
+ *
13
+ * @module @memberjunction/livekit-room-core
14
+ */
15
+ import { ConnectionQuality, ConnectionState, DisconnectReason, ExternalE2EEKeyProvider, Room, RoomEvent, Track, } from 'livekit-client';
16
+ import { BehaviorSubject } from 'rxjs';
17
+ import { LiveKitRoomEventBus } from './events.js';
18
+ import { applyBackgroundEffect, applyNoiseFilter } from './livekit-effects.js';
19
+ /** The default factory — constructs a real livekit-client `Room`. */
20
+ export const defaultRoomFactory = (options) => new Room(options);
21
+ /**
22
+ * Default role resolver: reads a JSON `metadata` string for `{ "mjRole": "agent" | "host" }`, falling
23
+ * back to `'participant'`. The MJ bridge stamps the agent bot's metadata so its tile renders as the agent.
24
+ */
25
+ export const defaultRoleResolver = (participant) => {
26
+ const raw = participant.metadata;
27
+ if (raw) {
28
+ try {
29
+ const parsed = JSON.parse(raw);
30
+ const role = (parsed.mjRole ?? parsed.role ?? '').toLowerCase();
31
+ if (role === 'agent' || role === 'host' || role === 'participant') {
32
+ return role;
33
+ }
34
+ }
35
+ catch {
36
+ // metadata is not JSON — fall through to default
37
+ }
38
+ }
39
+ return 'participant';
40
+ };
41
+ /**
42
+ * Controls a single LiveKit room: connect/disconnect, local-media toggles, data messages, device
43
+ * switching, and a normalized observable state snapshot. One controller == one room connection.
44
+ */
45
+ export class LiveKitRoomController {
46
+ constructor(options = {}) {
47
+ this.room = null;
48
+ this.noiseFilterEnabled = false;
49
+ this.backgroundEffect = { Kind: 'none' };
50
+ this.e2eeEnabled = false;
51
+ this.e2eeKeyProvider = null;
52
+ this.textDecoder = new TextDecoder();
53
+ this.textEncoder = new TextEncoder();
54
+ this.roomFactory = options.RoomFactory ?? defaultRoomFactory;
55
+ this.roleResolver = options.RoleResolver ?? defaultRoleResolver;
56
+ this.Events = options.EventBus ?? new LiveKitRoomEventBus();
57
+ this.stateSubject = new BehaviorSubject(this.initialState());
58
+ }
59
+ // ── Observable surface ────────────────────────────────────────────────────────────
60
+ /** The normalized room-state snapshot. Emits the current value on subscribe, then on every change. */
61
+ get State$() {
62
+ return this.stateSubject.asObservable();
63
+ }
64
+ /** The current room-state snapshot (synchronous). */
65
+ get State() {
66
+ return this.stateSubject.value;
67
+ }
68
+ /** The current connection status (synchronous convenience). */
69
+ get Status() {
70
+ return this.stateSubject.value.Status;
71
+ }
72
+ // ── Lifecycle ───────────────────────────────────────────────────────────────────
73
+ /**
74
+ * Connects to a LiveKit room and brings the local participant online with the requested media.
75
+ *
76
+ * @param serverUrl The LiveKit server URL (e.g. `wss://livekit.myorg.com`).
77
+ * @param token The signed access token authorizing this participant to join a specific room.
78
+ * @param options Initial media + display-name options.
79
+ */
80
+ async Connect(serverUrl, token, options = {}) {
81
+ const before = this.Events.Emit('beforeConnect', { ServerUrl: serverUrl, Options: options, Cancel: false });
82
+ if (before.Cancel) {
83
+ return;
84
+ }
85
+ if (this.room) {
86
+ await this.Disconnect(false);
87
+ }
88
+ const room = this.roomFactory(this.buildRoomOptions(before.Options));
89
+ this.room = room;
90
+ this.e2eeEnabled = before.Options.E2EE != null;
91
+ this.wireRoomEvents(room);
92
+ this.patchState({ Status: 'connecting', DisconnectReason: undefined, E2EEEnabled: this.e2eeEnabled });
93
+ try {
94
+ await this.enableE2EEIfRequested(room, before.Options);
95
+ await room.connect(serverUrl, token, { autoSubscribe: true });
96
+ if (before.Options.DisplayName) {
97
+ await room.localParticipant.setName(before.Options.DisplayName);
98
+ }
99
+ await this.applyInitialMedia(room, before.Options);
100
+ await this.applyInitialEffects(before.Options);
101
+ this.rebuildState();
102
+ this.Events.Emit('connected', { State: this.stateSubject.value });
103
+ }
104
+ catch (err) {
105
+ this.emitError('connect', 'Failed to connect to the room.', err);
106
+ this.patchState({ Status: 'error' });
107
+ throw err;
108
+ }
109
+ }
110
+ /**
111
+ * Disconnects from the room and releases all resources. Safe to call when not connected.
112
+ *
113
+ * @param userInitiated Whether the user requested the leave (raises a cancelable `beforeDisconnect`).
114
+ * Internal reconnect cycles pass `false` to skip the veto hook. Defaults to `true`.
115
+ * @returns `true` if the disconnect proceeded, `false` if a `beforeDisconnect` handler canceled it.
116
+ */
117
+ async Disconnect(userInitiated = true) {
118
+ if (userInitiated) {
119
+ const before = this.Events.Emit('beforeDisconnect', { UserInitiated: true, Cancel: false });
120
+ if (before.Cancel) {
121
+ return false;
122
+ }
123
+ }
124
+ const room = this.room;
125
+ this.room = null;
126
+ this.resetEffectState();
127
+ if (room) {
128
+ try {
129
+ await room.disconnect();
130
+ }
131
+ catch (err) {
132
+ this.emitError('disconnect', 'Error while disconnecting.', err);
133
+ }
134
+ }
135
+ this.patchState({ ...this.initialState(), Status: 'disconnected' });
136
+ return true;
137
+ }
138
+ /** Resets the cloud-effect / E2EE tracking fields to defaults (on disconnect). */
139
+ resetEffectState() {
140
+ this.noiseFilterEnabled = false;
141
+ this.backgroundEffect = { Kind: 'none' };
142
+ this.e2eeEnabled = false;
143
+ }
144
+ /** Disposes the controller, tears down the connection, and clears all subscribers. */
145
+ Dispose() {
146
+ void this.Disconnect(false);
147
+ this.stateSubject.complete();
148
+ this.Events.Clear();
149
+ }
150
+ // ── Local media controls ──────────────────────────────────────────────────────────
151
+ /** Enables or disables the local microphone. */
152
+ async SetMicrophoneEnabled(enabled) {
153
+ await this.toggleLocalMedia('microphone', enabled);
154
+ }
155
+ /** Enables or disables the local camera. */
156
+ async SetCameraEnabled(enabled) {
157
+ await this.toggleLocalMedia('camera', enabled);
158
+ }
159
+ /** Starts or stops local screen sharing. */
160
+ async SetScreenShareEnabled(enabled) {
161
+ await this.toggleLocalMedia('screen', enabled);
162
+ }
163
+ /** Toggles the microphone and returns the new state. */
164
+ async ToggleMicrophone() {
165
+ const next = !this.stateSubject.value.LocalMedia.MicrophoneEnabled;
166
+ await this.SetMicrophoneEnabled(next);
167
+ return next;
168
+ }
169
+ /** Toggles the camera and returns the new state. */
170
+ async ToggleCamera() {
171
+ const next = !this.stateSubject.value.LocalMedia.CameraEnabled;
172
+ await this.SetCameraEnabled(next);
173
+ return next;
174
+ }
175
+ /** Toggles screen sharing and returns the new state. */
176
+ async ToggleScreenShare() {
177
+ const next = !this.stateSubject.value.LocalMedia.ScreenShareEnabled;
178
+ await this.SetScreenShareEnabled(next);
179
+ return next;
180
+ }
181
+ // ── Data channel ────────────────────────────────────────────────────────────────
182
+ /**
183
+ * Sends a text message on the LiveKit data channel (reliable publish to all participants).
184
+ *
185
+ * @param text The message text.
186
+ * @param topic Optional topic to publish under (for routing on the receiving side).
187
+ */
188
+ async SendData(text, topic) {
189
+ if (!this.room) {
190
+ return;
191
+ }
192
+ const before = this.Events.Emit('beforeSendData', { Text: text, Topic: topic, Cancel: false });
193
+ if (before.Cancel) {
194
+ return;
195
+ }
196
+ try {
197
+ const payload = this.textEncoder.encode(before.Text);
198
+ await this.room.localParticipant.publishData(payload, { reliable: true, topic: before.Topic });
199
+ }
200
+ catch (err) {
201
+ this.emitError('data', 'Failed to send data message.', err);
202
+ }
203
+ }
204
+ // ── Audio playback / cloud effects ────────────────────────────────────────────────
205
+ /**
206
+ * Resumes audio playback after a browser autoplay block (must be called from a user-gesture handler).
207
+ * Clears {@link LiveKitRoomState.AudioPlaybackBlocked} on success.
208
+ */
209
+ async StartAudio() {
210
+ if (!this.room) {
211
+ return;
212
+ }
213
+ try {
214
+ await this.room.startAudio();
215
+ this.patchState({ AudioPlaybackBlocked: !this.room.canPlaybackAudio });
216
+ }
217
+ catch (err) {
218
+ this.emitError('device', 'Failed to start audio playback.', err);
219
+ }
220
+ }
221
+ /**
222
+ * Enables/disables the Krisp noise filter on the local microphone (LiveKit Cloud).
223
+ *
224
+ * @param enabled Whether the filter should be on.
225
+ * @returns `true` if applied; `false` if unsupported or the SDK is unavailable.
226
+ */
227
+ async SetNoiseFilterEnabled(enabled) {
228
+ const track = this.getLocalAudioTrack();
229
+ if (!track) {
230
+ return false;
231
+ }
232
+ const ok = await applyNoiseFilter(track, enabled);
233
+ if (ok) {
234
+ this.noiseFilterEnabled = enabled;
235
+ this.patchState({ NoiseFilterEnabled: enabled });
236
+ this.Events.Emit('noiseFilterChanged', { Enabled: enabled });
237
+ }
238
+ return ok;
239
+ }
240
+ /**
241
+ * Applies a camera background effect (blur / virtual background), or clears it with `{ Kind: 'none' }`.
242
+ *
243
+ * @param effect The effect to apply.
244
+ * @returns `true` if applied; `false` if the SDK is unavailable or no camera track exists.
245
+ */
246
+ async SetBackgroundEffect(effect) {
247
+ const track = this.getLocalVideoTrack();
248
+ if (!track) {
249
+ return false;
250
+ }
251
+ const ok = await applyBackgroundEffect(track, effect);
252
+ if (ok) {
253
+ this.backgroundEffect = effect;
254
+ this.patchState({ BackgroundEffect: effect });
255
+ this.Events.Emit('backgroundEffectChanged', { Effect: effect });
256
+ }
257
+ return ok;
258
+ }
259
+ // ── Devices ─────────────────────────────────────────────────────────────────────
260
+ /**
261
+ * Enumerates available media devices of a given kind.
262
+ *
263
+ * @param kind The device kind to enumerate.
264
+ * @returns The available devices.
265
+ */
266
+ async ListDevices(kind) {
267
+ try {
268
+ const devices = await Room.getLocalDevices(kind);
269
+ return devices.map((d) => ({ DeviceId: d.deviceId, Label: d.label, Kind: kind }));
270
+ }
271
+ catch (err) {
272
+ this.emitError('device', `Failed to enumerate ${kind} devices.`, err);
273
+ return [];
274
+ }
275
+ }
276
+ /**
277
+ * Returns the `deviceId` of the currently-active device for a given kind, or `null`
278
+ * when no room is connected or the active device is unknown. Used by hosts to
279
+ * pre-select the active device in a device-picker UI.
280
+ *
281
+ * @param kind The device kind to query.
282
+ * @returns The active `deviceId`, or `null` if unavailable.
283
+ */
284
+ GetActiveDeviceId(kind) {
285
+ if (!this.room) {
286
+ return null;
287
+ }
288
+ return this.room.getActiveDevice(kind) ?? null;
289
+ }
290
+ /**
291
+ * Switches the active device for a given kind.
292
+ *
293
+ * @param kind The device kind to switch.
294
+ * @param deviceId The `deviceId` to switch to.
295
+ */
296
+ async SwitchDevice(kind, deviceId) {
297
+ if (!this.room) {
298
+ return;
299
+ }
300
+ const before = this.Events.Emit('beforeDeviceSwitch', { Kind: kind, DeviceId: deviceId, Cancel: false });
301
+ if (before.Cancel) {
302
+ return;
303
+ }
304
+ try {
305
+ await this.room.switchActiveDevice(kind, before.DeviceId);
306
+ }
307
+ catch (err) {
308
+ this.emitError('device', `Failed to switch ${kind} device.`, err);
309
+ }
310
+ }
311
+ // ── internals: event wiring ───────────────────────────────────────────────────────
312
+ /** Wires the room's event stream to state rebuilds + transient streams. */
313
+ wireRoomEvents(room) {
314
+ const rebuild = () => this.rebuildState();
315
+ room
316
+ .on(RoomEvent.Connected, rebuild)
317
+ .on(RoomEvent.ParticipantConnected, (p) => this.handleParticipantJoined(p))
318
+ .on(RoomEvent.ParticipantDisconnected, (p) => this.handleParticipantLeft(p))
319
+ .on(RoomEvent.TrackSubscribed, rebuild)
320
+ .on(RoomEvent.TrackUnsubscribed, rebuild)
321
+ .on(RoomEvent.LocalTrackPublished, rebuild)
322
+ .on(RoomEvent.LocalTrackUnpublished, rebuild)
323
+ .on(RoomEvent.TrackMuted, rebuild)
324
+ .on(RoomEvent.TrackUnmuted, rebuild)
325
+ .on(RoomEvent.ConnectionQualityChanged, rebuild)
326
+ .on(RoomEvent.ActiveSpeakersChanged, (speakers) => this.handleActiveSpeakers(speakers))
327
+ .on(RoomEvent.ConnectionStateChanged, (state) => this.handleConnectionState(state))
328
+ .on(RoomEvent.Reconnecting, () => {
329
+ this.patchState({ Status: 'reconnecting' });
330
+ this.Events.Emit('reconnecting', {});
331
+ })
332
+ .on(RoomEvent.Reconnected, () => {
333
+ this.rebuildState();
334
+ this.Events.Emit('reconnected', { State: this.stateSubject.value });
335
+ })
336
+ .on(RoomEvent.DataReceived, (payload, participant, _kind, topic) => this.handleData(payload, participant, topic))
337
+ .on(RoomEvent.Disconnected, (reason) => this.handleDisconnected(reason))
338
+ .on(RoomEvent.MediaDevicesError, (err) => this.emitError('device', err.message, err))
339
+ .on(RoomEvent.AudioPlaybackStatusChanged, () => this.handleAudioPlayback());
340
+ }
341
+ /** Reflects browser autoplay-policy changes into state + the `audioPlaybackChanged` event. */
342
+ handleAudioPlayback() {
343
+ const canPlayback = this.room?.canPlaybackAudio ?? true;
344
+ this.patchState({ AudioPlaybackBlocked: !canPlayback });
345
+ this.Events.Emit('audioPlaybackChanged', { CanPlayback: canPlayback });
346
+ }
347
+ /** Returns the local microphone track (for processors), or null. */
348
+ getLocalAudioTrack() {
349
+ const pub = this.room?.localParticipant.getTrackPublication(Track.Source.Microphone);
350
+ return pub?.audioTrack ?? null;
351
+ }
352
+ /** Returns the local camera track (for processors), or null. */
353
+ getLocalVideoTrack() {
354
+ const pub = this.room?.localParticipant.getTrackPublication(Track.Source.Camera);
355
+ return pub?.videoTrack ?? null;
356
+ }
357
+ /** Handles a participant joining — emits `participantJoined` then rebuilds. */
358
+ handleParticipantJoined(participant) {
359
+ this.Events.Emit('participantJoined', { Participant: this.buildView(participant) });
360
+ this.rebuildState();
361
+ }
362
+ /** Handles a participant leaving — emits `participantLeft` then rebuilds. */
363
+ handleParticipantLeft(participant) {
364
+ this.Events.Emit('participantLeft', { Identity: participant.identity, Participant: this.buildView(participant) });
365
+ this.rebuildState();
366
+ }
367
+ /** Handles the `ActiveSpeakersChanged` event — updates the active-speaker identity list. */
368
+ handleActiveSpeakers(speakers) {
369
+ const identities = speakers.map((s) => s.identity);
370
+ const views = speakers.map((s) => this.buildView(s));
371
+ this.patchState({ ActiveSpeakerIdentities: identities });
372
+ this.rebuildState();
373
+ this.Events.Emit('activeSpeakersChanged', { Identities: identities, Speakers: views });
374
+ }
375
+ /** Handles connection-state transitions, mapping to the normalized status. */
376
+ handleConnectionState(state) {
377
+ this.patchState({ Status: this.mapConnectionStatus(state) });
378
+ }
379
+ /** Handles an inbound data-channel message. */
380
+ handleData(payload, participant, topic) {
381
+ let text = '';
382
+ try {
383
+ text = this.textDecoder.decode(payload);
384
+ }
385
+ catch {
386
+ text = '';
387
+ }
388
+ this.Events.Emit('dataReceived', {
389
+ Text: text,
390
+ Bytes: payload,
391
+ Topic: topic,
392
+ FromIdentity: participant?.identity,
393
+ FromDisplayName: participant?.name ?? participant?.identity,
394
+ ReceivedAt: Date.now(),
395
+ });
396
+ }
397
+ /** Handles a room disconnect — records the reason and resets to disconnected state. */
398
+ handleDisconnected(reason) {
399
+ this.room = null;
400
+ const mapped = this.mapDisconnectReason(reason);
401
+ this.patchState({
402
+ ...this.initialState(),
403
+ Status: 'disconnected',
404
+ DisconnectReason: mapped,
405
+ });
406
+ this.Events.Emit('disconnected', { Reason: mapped });
407
+ }
408
+ // ── internals: state building ─────────────────────────────────────────────────────
409
+ /** Rebuilds the full state snapshot from the live room and emits it. */
410
+ rebuildState() {
411
+ const room = this.room;
412
+ if (!room) {
413
+ return;
414
+ }
415
+ const local = room.localParticipant ? this.buildView(room.localParticipant) : undefined;
416
+ const remote = Array.from(room.remoteParticipants.values()).map((p) => this.buildView(p));
417
+ this.patchState({
418
+ Status: this.mapConnectionStatus(room.state),
419
+ RoomName: room.name,
420
+ Local: local,
421
+ Remote: remote,
422
+ LocalMedia: this.readLocalMedia(room),
423
+ AudioPlaybackBlocked: !room.canPlaybackAudio,
424
+ NoiseFilterEnabled: this.noiseFilterEnabled,
425
+ BackgroundEffect: this.backgroundEffect,
426
+ E2EEEnabled: this.e2eeEnabled,
427
+ });
428
+ }
429
+ /** Maps a livekit-client participant onto the normalized {@link LiveKitParticipantView}. */
430
+ buildView(participant) {
431
+ return {
432
+ Identity: participant.identity,
433
+ DisplayName: participant.name && participant.name.length > 0 ? participant.name : participant.identity,
434
+ IsLocal: this.room?.localParticipant === participant,
435
+ Role: this.roleResolver(participant),
436
+ IsSpeaking: participant.isSpeaking,
437
+ AudioLevel: participant.audioLevel ?? 0,
438
+ HasAudio: this.hasLiveTrack(participant, Track.Source.Microphone),
439
+ HasVideo: this.hasLiveTrack(participant, Track.Source.Camera),
440
+ IsScreenSharing: this.hasLiveTrack(participant, Track.Source.ScreenShare),
441
+ ConnectionQuality: this.mapConnectionQuality(participant.connectionQuality),
442
+ Raw: participant,
443
+ };
444
+ }
445
+ /** Whether the participant has a published, unmuted track for the given source. */
446
+ hasLiveTrack(participant, source) {
447
+ const pub = participant.getTrackPublication(source);
448
+ return pub != null && !pub.isMuted;
449
+ }
450
+ /** Reads the local-media toggle state from the room's local participant. */
451
+ readLocalMedia(room) {
452
+ const lp = room.localParticipant;
453
+ return {
454
+ MicrophoneEnabled: lp ? lp.isMicrophoneEnabled : false,
455
+ CameraEnabled: lp ? lp.isCameraEnabled : false,
456
+ ScreenShareEnabled: lp ? lp.isScreenShareEnabled : false,
457
+ };
458
+ }
459
+ /** Toggles a local-media kind via the local participant, surfacing failures as device errors. */
460
+ async toggleLocalMedia(kind, enabled) {
461
+ if (!this.room) {
462
+ return;
463
+ }
464
+ const before = this.Events.Emit('beforeMediaToggle', { Kind: kind, Enabled: enabled, Cancel: false });
465
+ if (before.Cancel) {
466
+ return;
467
+ }
468
+ const lp = this.room.localParticipant;
469
+ try {
470
+ if (kind === 'microphone') {
471
+ await lp.setMicrophoneEnabled(enabled);
472
+ }
473
+ else if (kind === 'camera') {
474
+ await lp.setCameraEnabled(enabled);
475
+ }
476
+ else {
477
+ await lp.setScreenShareEnabled(enabled);
478
+ }
479
+ this.rebuildState();
480
+ this.Events.Emit('localMediaChanged', this.stateSubject.value.LocalMedia);
481
+ }
482
+ catch (err) {
483
+ this.emitError('device', `Failed to ${enabled ? 'enable' : 'disable'} ${kind}.`, err);
484
+ }
485
+ }
486
+ /** Applies the requested initial media (mic on by default, camera off — voice-first), honoring device ids. */
487
+ async applyInitialMedia(room, options) {
488
+ const wantMic = options.EnableMicrophone ?? true;
489
+ const wantCam = options.EnableCamera ?? false;
490
+ if (wantMic) {
491
+ await room.localParticipant.setMicrophoneEnabled(true, options.MicrophoneDeviceId ? { deviceId: options.MicrophoneDeviceId } : undefined);
492
+ }
493
+ if (wantCam) {
494
+ await room.localParticipant.setCameraEnabled(true, options.CameraDeviceId ? { deviceId: options.CameraDeviceId } : undefined);
495
+ }
496
+ }
497
+ /** Applies the requested initial cloud effects (noise filter, background) after media is published. */
498
+ async applyInitialEffects(options) {
499
+ if (options.NoiseFilterEnabled) {
500
+ await this.SetNoiseFilterEnabled(true);
501
+ }
502
+ if (options.BackgroundEffect && options.BackgroundEffect.Kind !== 'none') {
503
+ await this.SetBackgroundEffect(options.BackgroundEffect);
504
+ }
505
+ }
506
+ /** Merges E2EE into the livekit-client room options when requested. */
507
+ buildRoomOptions(options) {
508
+ this.e2eeKeyProvider = null;
509
+ if (!options.E2EE) {
510
+ return options.RoomOptions;
511
+ }
512
+ this.e2eeKeyProvider = new ExternalE2EEKeyProvider();
513
+ return {
514
+ ...options.RoomOptions,
515
+ e2ee: { keyProvider: this.e2eeKeyProvider, worker: options.E2EE.Worker },
516
+ };
517
+ }
518
+ /** Sets the E2EE key from the passphrase and enables encryption (no-op when not requested). */
519
+ async enableE2EEIfRequested(room, options) {
520
+ if (!options.E2EE || !this.e2eeKeyProvider) {
521
+ return;
522
+ }
523
+ await this.e2eeKeyProvider.setKey(options.E2EE.Passphrase);
524
+ await room.setE2EEEnabled(true);
525
+ }
526
+ // ── internals: mapping + emit helpers ──────────────────────────────────────────────
527
+ /** Maps livekit-client `ConnectionState` to the normalized {@link LiveKitConnectionStatus}. */
528
+ mapConnectionStatus(state) {
529
+ switch (state) {
530
+ case ConnectionState.Connecting:
531
+ return 'connecting';
532
+ case ConnectionState.Connected:
533
+ return 'connected';
534
+ case ConnectionState.Reconnecting:
535
+ case ConnectionState.SignalReconnecting:
536
+ return 'reconnecting';
537
+ case ConnectionState.Disconnected:
538
+ return 'disconnected';
539
+ default:
540
+ return 'idle';
541
+ }
542
+ }
543
+ /** Maps livekit-client `ConnectionQuality` to the normalized bucket. */
544
+ mapConnectionQuality(quality) {
545
+ switch (quality) {
546
+ case ConnectionQuality.Excellent:
547
+ return 'excellent';
548
+ case ConnectionQuality.Good:
549
+ return 'good';
550
+ case ConnectionQuality.Poor:
551
+ return 'poor';
552
+ case ConnectionQuality.Lost:
553
+ return 'lost';
554
+ default:
555
+ return 'unknown';
556
+ }
557
+ }
558
+ /** Maps livekit-client `DisconnectReason` to the normalized {@link LiveKitDisconnectReason}. */
559
+ mapDisconnectReason(reason) {
560
+ switch (reason) {
561
+ case DisconnectReason.CLIENT_INITIATED:
562
+ return 'client-initiated';
563
+ case DisconnectReason.SERVER_SHUTDOWN:
564
+ return 'server-shutdown';
565
+ case DisconnectReason.PARTICIPANT_REMOVED:
566
+ return 'participant-removed';
567
+ case DisconnectReason.ROOM_DELETED:
568
+ return 'room-deleted';
569
+ case DisconnectReason.DUPLICATE_IDENTITY:
570
+ return 'duplicate-identity';
571
+ case DisconnectReason.CONNECTION_TIMEOUT:
572
+ return 'connection-lost';
573
+ default:
574
+ return reason == null ? 'client-initiated' : 'unknown';
575
+ }
576
+ }
577
+ /** Pushes a partial update onto the current state snapshot, emits it, and fires `stateChanged`. */
578
+ patchState(patch) {
579
+ const next = { ...this.stateSubject.value, ...patch };
580
+ this.stateSubject.next(next);
581
+ this.Events.Emit('stateChanged', next);
582
+ }
583
+ /** Emits a normalized error via the `error` event. */
584
+ emitError(kind, message, cause) {
585
+ this.Events.Emit('error', { Kind: kind, Message: message, Cause: cause });
586
+ }
587
+ /** The initial / reset room state. */
588
+ initialState() {
589
+ return {
590
+ Status: 'idle',
591
+ Remote: [],
592
+ ActiveSpeakerIdentities: [],
593
+ LocalMedia: { MicrophoneEnabled: false, CameraEnabled: false, ScreenShareEnabled: false },
594
+ AudioPlaybackBlocked: false,
595
+ NoiseFilterEnabled: false,
596
+ BackgroundEffect: { Kind: 'none' },
597
+ E2EEEnabled: false,
598
+ };
599
+ }
600
+ }
601
+ //# sourceMappingURL=livekit-room-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"livekit-room-controller.js","sourceRoot":"","sources":["../src/livekit-room-controller.ts"],"names":[],"mappings":"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"}