@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.
package/README.md CHANGED
@@ -1,45 +1,92 @@
1
1
  # @memberjunction/livekit-room-core
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ Framework-agnostic, pure-TypeScript core for the MJ-native realtime room UX. It wraps
4
+ [`livekit-client`](https://www.npmjs.com/package/livekit-client) into a single observable room controller
5
+ with a deep, **cancelable** event model — consumable from any framework (Angular, React, Vue) or plain TS.
4
6
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
7
+ This is **Layer A's engine** in the LiveKit room stack:
6
8
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
9
+ ```
10
+ @memberjunction/livekit-room-core ← you are here (pure TS, no UI)
11
+
12
+ @memberjunction/ng-livekit-room (portable Angular UI)
13
+
14
+ @memberjunction/ng-mj-livekit-room (MJ binding → realtime bridge)
15
+ ```
8
16
 
9
- ## Purpose
17
+ ## Why a core package?
10
18
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/livekit-room-core`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
19
+ The room logic — connect/disconnect, participant + track tracking, active speakers, audio metering,
20
+ device control, data-channel messages, cloud effects, E2EE has nothing to do with Angular. Keeping it
21
+ here means the Angular widget (and any future React binding) is a thin view over a tested engine, and the
22
+ logic unit-tests with **no WebRTC, no browser, no network** via an injectable `Room` factory seam.
15
23
 
16
- ## What is OIDC Trusted Publishing?
24
+ ## Install
17
25
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
26
+ ```bash
27
+ npm install @memberjunction/livekit-room-core livekit-client
28
+ # optional cloud effects:
29
+ npm install @livekit/krisp-noise-filter @livekit/track-processors
30
+ ```
19
31
 
20
- ## Setup Instructions
32
+ ## Quick start
21
33
 
22
- To properly configure OIDC trusted publishing for this package:
34
+ ```typescript
35
+ import { LiveKitRoomController } from '@memberjunction/livekit-room-core';
23
36
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
37
+ const room = new LiveKitRoomController();
28
38
 
29
- ## DO NOT USE THIS PACKAGE
39
+ // Render from the observable snapshot
40
+ room.State$.subscribe((state) => renderParticipants(state.Remote));
30
41
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
42
+ // Cancelable Before-events (veto an action)
43
+ room.Events.On('beforeDisconnect', (e) => {
44
+ if (!confirm('Leave the call?')) e.Cancel = true;
45
+ });
36
46
 
37
- ## More Information
47
+ // Transform an outgoing chat message
48
+ room.Events.On('beforeSendData', (e) => { e.Text = e.Text.trim(); });
38
49
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
50
+ await room.Connect('wss://livekit.myorg.com', signedToken, { DisplayName: 'Amith' });
51
+ await room.ToggleCamera();
52
+ await room.SendData('hello', 'lk-chat');
53
+ ```
42
54
 
43
- ---
55
+ ## What it gives you
44
56
 
45
- **Maintained for OIDC setup purposes only**
57
+ | Capability | API |
58
+ |---|---|
59
+ | Connect / leave | `Connect(url, token, options)`, `Disconnect()` |
60
+ | Local media | `ToggleMicrophone()` / `ToggleCamera()` / `ToggleScreenShare()`, `Set*Enabled()` |
61
+ | Devices | `ListDevices(kind)`, `SwitchDevice(kind, id)` |
62
+ | Data channel | `SendData(text, topic?)` |
63
+ | Audio autoplay unblock | `StartAudio()` + `State.AudioPlaybackBlocked` |
64
+ | Krisp noise filter (Cloud) | `SetNoiseFilterEnabled(bool)` |
65
+ | Background blur / virtual bg | `SetBackgroundEffect({ Kind: 'blur' \| 'image' \| 'none' })` |
66
+ | End-to-end encryption | `Connect(..., { E2EE: { Passphrase, Worker } })` |
67
+ | PreJoin preview (room-free) | `LiveKitMediaPreview` |
68
+ | Audio visualizer math | `LiveKitAudioMeter` |
69
+
70
+ ## The cancelable event architecture
71
+
72
+ `controller.Events` is a typed `LiveKitRoomEventBus`. **Before-events** run synchronously and may be
73
+ vetoed (`event.Cancel = true`) or mutated; **notification events** report what happened.
74
+
75
+ - Cancelable: `beforeConnect`, `beforeDisconnect`, `beforeMediaToggle`, `beforeSendData`, `beforeDeviceSwitch`
76
+ - Notifications: `connected`, `disconnected`, `reconnecting`, `reconnected`, `participantJoined`,
77
+ `participantLeft`, `activeSpeakersChanged`, `dataReceived`, `localMediaChanged`, `stateChanged`,
78
+ `audioPlaybackChanged`, `noiseFilterChanged`, `backgroundEffectChanged`, `error`
79
+
80
+ ## Testability
81
+
82
+ Inject a fake `Room` via the factory seam — no WebRTC needed:
83
+
84
+ ```typescript
85
+ const controller = new LiveKitRoomController({ RoomFactory: () => fakeRoom as unknown as Room });
86
+ ```
87
+
88
+ See `src/__tests__/` for the in-memory fake used by the package's own 22-test suite.
89
+
90
+ ## License
91
+
92
+ ISC © MemberJunction.com
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview {@link LiveKitAudioMeter} — a tiny, pure, DOM-free smoother that turns a stream of raw
3
+ * 0..1 audio levels (e.g. `participant.audioLevel`) into a smoothed level plus a set of bar bins for a
4
+ * voice visualizer. UI layers call {@link LiveKitAudioMeter.Next} on each animation frame; keeping the
5
+ * math here (not in a component) makes it framework-agnostic and unit-testable.
6
+ *
7
+ * @module @memberjunction/livekit-room-core
8
+ */
9
+ /** The number of visualizer bars produced by {@link LiveKitAudioMeter}. */
10
+ export declare const AUDIO_METER_BIN_COUNT = 7;
11
+ /** Below this level the meter is treated as silent (clamps idle noise to a flat baseline). */
12
+ export declare const AUDIO_METER_SILENCE_FLOOR = 0.04;
13
+ /** One smoothed frame of audio-visual data. */
14
+ export interface LiveKitAudioMeterFrame {
15
+ /** Smoothed level, 0..1. */
16
+ Level: number;
17
+ /** Smoothed bar bins, each 0..1, for a symmetric visualizer. */
18
+ Bins: number[];
19
+ /** Whether the source is effectively silent this frame. */
20
+ IsSilent: boolean;
21
+ }
22
+ /**
23
+ * Exponential-smoothing audio meter. Attack (rising) is faster than decay (falling) so the meter feels
24
+ * responsive when speech starts but settles gently — the standard VU-meter feel.
25
+ */
26
+ export declare class LiveKitAudioMeter {
27
+ private readonly attack;
28
+ private readonly decay;
29
+ private smoothed;
30
+ private readonly bins;
31
+ /**
32
+ * @param attack Smoothing factor when the level is rising, 0..1 (higher = snappier). Default 0.6.
33
+ * @param decay Smoothing factor when the level is falling, 0..1 (lower = slower fall). Default 0.18.
34
+ */
35
+ constructor(attack?: number, decay?: number);
36
+ /**
37
+ * Folds the latest raw level into the smoothed state and returns the current frame.
38
+ *
39
+ * @param rawLevel The latest raw audio level, 0..1.
40
+ * @returns The smoothed meter frame.
41
+ */
42
+ Next(rawLevel: number): LiveKitAudioMeterFrame;
43
+ /** Resets the meter to silence. */
44
+ Reset(): void;
45
+ /** Updates the bar bins with a center-weighted shape scaled by the smoothed level. */
46
+ private updateBins;
47
+ }
48
+ //# sourceMappingURL=audio-meter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-meter.d.ts","sourceRoot":"","sources":["../src/audio-meter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,8FAA8F;AAC9F,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,2DAA2D;IAC3D,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAS1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IATxB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsD;IAE3E;;;OAGG;gBAEgB,MAAM,SAAM,EACZ,KAAK,SAAO;IAG/B;;;;;OAKG;IACI,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB;IAUrD,mCAAmC;IAC5B,KAAK,IAAI,IAAI;IAKpB,sFAAsF;IACtF,OAAO,CAAC,UAAU;CAWnB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @fileoverview {@link LiveKitAudioMeter} — a tiny, pure, DOM-free smoother that turns a stream of raw
3
+ * 0..1 audio levels (e.g. `participant.audioLevel`) into a smoothed level plus a set of bar bins for a
4
+ * voice visualizer. UI layers call {@link LiveKitAudioMeter.Next} on each animation frame; keeping the
5
+ * math here (not in a component) makes it framework-agnostic and unit-testable.
6
+ *
7
+ * @module @memberjunction/livekit-room-core
8
+ */
9
+ /** The number of visualizer bars produced by {@link LiveKitAudioMeter}. */
10
+ export const AUDIO_METER_BIN_COUNT = 7;
11
+ /** Below this level the meter is treated as silent (clamps idle noise to a flat baseline). */
12
+ export const AUDIO_METER_SILENCE_FLOOR = 0.04;
13
+ /**
14
+ * Exponential-smoothing audio meter. Attack (rising) is faster than decay (falling) so the meter feels
15
+ * responsive when speech starts but settles gently — the standard VU-meter feel.
16
+ */
17
+ export class LiveKitAudioMeter {
18
+ /**
19
+ * @param attack Smoothing factor when the level is rising, 0..1 (higher = snappier). Default 0.6.
20
+ * @param decay Smoothing factor when the level is falling, 0..1 (lower = slower fall). Default 0.18.
21
+ */
22
+ constructor(attack = 0.6, decay = 0.18) {
23
+ this.attack = attack;
24
+ this.decay = decay;
25
+ this.smoothed = 0;
26
+ this.bins = new Array(AUDIO_METER_BIN_COUNT).fill(0);
27
+ }
28
+ /**
29
+ * Folds the latest raw level into the smoothed state and returns the current frame.
30
+ *
31
+ * @param rawLevel The latest raw audio level, 0..1.
32
+ * @returns The smoothed meter frame.
33
+ */
34
+ Next(rawLevel) {
35
+ const clamped = Math.max(0, Math.min(1, rawLevel));
36
+ const factor = clamped > this.smoothed ? this.attack : this.decay;
37
+ this.smoothed += (clamped - this.smoothed) * factor;
38
+ const isSilent = this.smoothed < AUDIO_METER_SILENCE_FLOOR;
39
+ this.updateBins(isSilent ? 0 : this.smoothed);
40
+ return { Level: isSilent ? 0 : this.smoothed, Bins: [...this.bins], IsSilent: isSilent };
41
+ }
42
+ /** Resets the meter to silence. */
43
+ Reset() {
44
+ this.smoothed = 0;
45
+ this.bins.fill(0);
46
+ }
47
+ /** Updates the bar bins with a center-weighted shape scaled by the smoothed level. */
48
+ updateBins(level) {
49
+ const center = (AUDIO_METER_BIN_COUNT - 1) / 2;
50
+ for (let i = 0; i < AUDIO_METER_BIN_COUNT; i++) {
51
+ // Center bars taller than edges; add a little per-bin variation for an organic look.
52
+ const distance = Math.abs(i - center) / center;
53
+ const shape = 1 - distance * 0.55;
54
+ const jitter = 0.85 + 0.15 * Math.sin(i * 1.7 + level * 6);
55
+ const target = level * shape * jitter;
56
+ this.bins[i] += (target - this.bins[i]) * (target > this.bins[i] ? this.attack : this.decay);
57
+ }
58
+ }
59
+ }
60
+ //# sourceMappingURL=audio-meter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-meter.js","sourceRoot":"","sources":["../src/audio-meter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAY9C;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAI5B;;;OAGG;IACH,YACmB,SAAS,GAAG,EACZ,QAAQ,IAAI;QADZ,WAAM,GAAN,MAAM,CAAM;QACZ,UAAK,GAAL,KAAK,CAAO;QATvB,aAAQ,GAAG,CAAC,CAAC;QACJ,SAAI,GAAa,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IASxE,CAAC;IAEJ;;;;;OAKG;IACI,IAAI,CAAC,QAAgB;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAClE,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;QAEpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,yBAAyB,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC3F,CAAC;IAED,mCAAmC;IAC5B,KAAK;QACV,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,sFAAsF;IAC9E,UAAU,CAAC,KAAa;QAC9B,MAAM,MAAM,GAAG,CAAC,qBAAqB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,qFAAqF;YACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC;YAC/C,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @fileoverview The LiveKit room **event architecture** — a typed, framework-agnostic event bus with
3
+ * **cancelable Before-events** (mirroring the MemberJunction conversations stack, where a handler sets
4
+ * `event.Cancel = true` to veto an action) plus informational notification events.
5
+ *
6
+ * Living in the core (not the Angular layer) means every consumer — the Angular widget, a future React
7
+ * binding, or a headless test harness — gets the same cancelable hooks. The Angular component simply
8
+ * re-surfaces these as `@Output()` `EventEmitter`s.
9
+ *
10
+ * **Cancellation contract:** Before-event handlers run **synchronously** in registration order. Any
11
+ * handler may set `event.Cancel = true`; the controller checks the flag immediately after dispatch and
12
+ * aborts the action when set. Before-events may also *mutate* documented payload fields (e.g.
13
+ * {@link LiveKitBeforeSendDataEvent.Text}) to transform the action before it proceeds.
14
+ *
15
+ * @module @memberjunction/livekit-room-core
16
+ */
17
+ import type { LiveKitBackgroundEffect, LiveKitDataMessage, LiveKitDevice, LiveKitDisconnectReason, LiveKitLocalMediaState, LiveKitParticipantView, LiveKitRoomConnectOptions, LiveKitRoomError, LiveKitRoomState } from './types.js';
18
+ /** Base shape for every cancelable Before-event. Set {@link Cancel} to `true` to veto the action. */
19
+ export interface LiveKitCancelableEvent {
20
+ /** Set to `true` in a handler to cancel the pending action. Defaults to `false`. */
21
+ Cancel: boolean;
22
+ }
23
+ /** Fired before the client connects. Cancelable. */
24
+ export interface LiveKitBeforeConnectEvent extends LiveKitCancelableEvent {
25
+ /** The server URL about to be connected to. */
26
+ ServerUrl: string;
27
+ /** The connect options about to be applied (mutable — a handler may adjust them). */
28
+ Options: LiveKitRoomConnectOptions;
29
+ }
30
+ /** Fired before the client disconnects/leaves the room. Cancelable (e.g. "leave call?" confirmation). */
31
+ export interface LiveKitBeforeDisconnectEvent extends LiveKitCancelableEvent {
32
+ /** Whether this disconnect was initiated by the user (vs. an internal reconnect cycle). */
33
+ UserInitiated: boolean;
34
+ }
35
+ /** Fired before a local-media track is toggled. Cancelable. */
36
+ export interface LiveKitBeforeMediaToggleEvent extends LiveKitCancelableEvent {
37
+ /** Which local-media kind is being toggled. */
38
+ Kind: 'microphone' | 'camera' | 'screen';
39
+ /** The target enabled state. */
40
+ Enabled: boolean;
41
+ }
42
+ /** Fired before a data-channel message is sent. Cancelable; {@link Text} is mutable for transformation. */
43
+ export interface LiveKitBeforeSendDataEvent extends LiveKitCancelableEvent {
44
+ /** The message text — a handler MAY rewrite this to transform the outgoing message. */
45
+ Text: string;
46
+ /** The optional topic. */
47
+ Topic?: string;
48
+ }
49
+ /** Fired before the active input/output device is switched. Cancelable. */
50
+ export interface LiveKitBeforeDeviceSwitchEvent extends LiveKitCancelableEvent {
51
+ /** The device kind being switched. */
52
+ Kind: LiveKitDevice['Kind'];
53
+ /** The target device id. */
54
+ DeviceId: string;
55
+ }
56
+ /** Fired when a participant joins the room. */
57
+ export interface LiveKitParticipantJoinedEvent {
58
+ /** The participant that joined. */
59
+ Participant: LiveKitParticipantView;
60
+ }
61
+ /** Fired when a participant leaves the room. */
62
+ export interface LiveKitParticipantLeftEvent {
63
+ /** The identity of the participant that left. */
64
+ Identity: string;
65
+ /** The participant's last-known view, when available. */
66
+ Participant?: LiveKitParticipantView;
67
+ }
68
+ /** Fired when the active-speaker set changes. */
69
+ export interface LiveKitActiveSpeakersEvent {
70
+ /** Identities currently flagged as active speakers, most-recent first. */
71
+ Identities: string[];
72
+ /** The active-speaker participant views. */
73
+ Speakers: LiveKitParticipantView[];
74
+ }
75
+ /** Fired when the room disconnects. */
76
+ export interface LiveKitDisconnectedEvent {
77
+ /** The normalized disconnect reason. */
78
+ Reason: LiveKitDisconnectReason;
79
+ }
80
+ /**
81
+ * The full event map: event name → payload type. Names use the `before*` prefix for cancelable events
82
+ * and a past-tense / noun form for notifications, matching the conversations-stack vocabulary.
83
+ */
84
+ export interface LiveKitRoomEventMap {
85
+ beforeConnect: LiveKitBeforeConnectEvent;
86
+ beforeDisconnect: LiveKitBeforeDisconnectEvent;
87
+ beforeMediaToggle: LiveKitBeforeMediaToggleEvent;
88
+ beforeSendData: LiveKitBeforeSendDataEvent;
89
+ beforeDeviceSwitch: LiveKitBeforeDeviceSwitchEvent;
90
+ connected: {
91
+ State: LiveKitRoomState;
92
+ };
93
+ disconnected: LiveKitDisconnectedEvent;
94
+ reconnecting: Record<string, never>;
95
+ reconnected: {
96
+ State: LiveKitRoomState;
97
+ };
98
+ participantJoined: LiveKitParticipantJoinedEvent;
99
+ participantLeft: LiveKitParticipantLeftEvent;
100
+ activeSpeakersChanged: LiveKitActiveSpeakersEvent;
101
+ dataReceived: LiveKitDataMessage;
102
+ localMediaChanged: LiveKitLocalMediaState;
103
+ stateChanged: LiveKitRoomState;
104
+ error: LiveKitRoomError;
105
+ /** Browser autoplay policy changed whether remote audio can play (prompt the user to enable sound). */
106
+ audioPlaybackChanged: {
107
+ CanPlayback: boolean;
108
+ };
109
+ /** The Krisp noise filter was toggled on the local microphone. */
110
+ noiseFilterChanged: {
111
+ Enabled: boolean;
112
+ };
113
+ /** The camera background effect changed. */
114
+ backgroundEffectChanged: {
115
+ Effect: LiveKitBackgroundEffect;
116
+ };
117
+ }
118
+ /** A handler for a given event type. */
119
+ export type LiveKitEventHandler<K extends keyof LiveKitRoomEventMap> = (event: LiveKitRoomEventMap[K]) => void;
120
+ /**
121
+ * A typed, synchronous event bus for LiveKit room events. Handlers fire in registration order; a thrown
122
+ * handler error is isolated (logged to `console.error`) so one bad subscriber cannot break the room or
123
+ * suppress later handlers.
124
+ */
125
+ export declare class LiveKitRoomEventBus {
126
+ private readonly handlers;
127
+ /**
128
+ * Subscribes to an event.
129
+ *
130
+ * @param type The event name.
131
+ * @param handler The handler to invoke.
132
+ * @returns An unsubscribe function.
133
+ */
134
+ On<K extends keyof LiveKitRoomEventMap>(type: K, handler: LiveKitEventHandler<K>): () => void;
135
+ /**
136
+ * Subscribes to an event for a single emission, then auto-unsubscribes.
137
+ *
138
+ * @param type The event name.
139
+ * @param handler The handler to invoke once.
140
+ * @returns An unsubscribe function (in case you want to cancel before it fires).
141
+ */
142
+ Once<K extends keyof LiveKitRoomEventMap>(type: K, handler: LiveKitEventHandler<K>): () => void;
143
+ /**
144
+ * Unsubscribes a handler from an event.
145
+ *
146
+ * @param type The event name.
147
+ * @param handler The handler to remove.
148
+ */
149
+ Off<K extends keyof LiveKitRoomEventMap>(type: K, handler: LiveKitEventHandler<K>): void;
150
+ /**
151
+ * Emits an event to all subscribers synchronously and returns the (possibly mutated) event — so the
152
+ * caller can read `Cancel` and any handler-applied transformations.
153
+ *
154
+ * @param type The event name.
155
+ * @param event The event payload.
156
+ * @returns The same event object after all handlers have run.
157
+ */
158
+ Emit<K extends keyof LiveKitRoomEventMap>(type: K, event: LiveKitRoomEventMap[K]): LiveKitRoomEventMap[K];
159
+ /** Removes all handlers. Called on controller dispose. */
160
+ Clear(): void;
161
+ }
162
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/events.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @fileoverview The LiveKit room **event architecture** — a typed, framework-agnostic event bus with
3
+ * **cancelable Before-events** (mirroring the MemberJunction conversations stack, where a handler sets
4
+ * `event.Cancel = true` to veto an action) plus informational notification events.
5
+ *
6
+ * Living in the core (not the Angular layer) means every consumer — the Angular widget, a future React
7
+ * binding, or a headless test harness — gets the same cancelable hooks. The Angular component simply
8
+ * re-surfaces these as `@Output()` `EventEmitter`s.
9
+ *
10
+ * **Cancellation contract:** Before-event handlers run **synchronously** in registration order. Any
11
+ * handler may set `event.Cancel = true`; the controller checks the flag immediately after dispatch and
12
+ * aborts the action when set. Before-events may also *mutate* documented payload fields (e.g.
13
+ * {@link LiveKitBeforeSendDataEvent.Text}) to transform the action before it proceeds.
14
+ *
15
+ * @module @memberjunction/livekit-room-core
16
+ */
17
+ /**
18
+ * A typed, synchronous event bus for LiveKit room events. Handlers fire in registration order; a thrown
19
+ * handler error is isolated (logged to `console.error`) so one bad subscriber cannot break the room or
20
+ * suppress later handlers.
21
+ */
22
+ export class LiveKitRoomEventBus {
23
+ constructor() {
24
+ this.handlers = new Map();
25
+ }
26
+ /**
27
+ * Subscribes to an event.
28
+ *
29
+ * @param type The event name.
30
+ * @param handler The handler to invoke.
31
+ * @returns An unsubscribe function.
32
+ */
33
+ On(type, handler) {
34
+ let set = this.handlers.get(type);
35
+ if (!set) {
36
+ set = new Set();
37
+ this.handlers.set(type, set);
38
+ }
39
+ set.add(handler);
40
+ return () => this.Off(type, handler);
41
+ }
42
+ /**
43
+ * Subscribes to an event for a single emission, then auto-unsubscribes.
44
+ *
45
+ * @param type The event name.
46
+ * @param handler The handler to invoke once.
47
+ * @returns An unsubscribe function (in case you want to cancel before it fires).
48
+ */
49
+ Once(type, handler) {
50
+ const off = this.On(type, (event) => {
51
+ off();
52
+ handler(event);
53
+ });
54
+ return off;
55
+ }
56
+ /**
57
+ * Unsubscribes a handler from an event.
58
+ *
59
+ * @param type The event name.
60
+ * @param handler The handler to remove.
61
+ */
62
+ Off(type, handler) {
63
+ this.handlers.get(type)?.delete(handler);
64
+ }
65
+ /**
66
+ * Emits an event to all subscribers synchronously and returns the (possibly mutated) event — so the
67
+ * caller can read `Cancel` and any handler-applied transformations.
68
+ *
69
+ * @param type The event name.
70
+ * @param event The event payload.
71
+ * @returns The same event object after all handlers have run.
72
+ */
73
+ Emit(type, event) {
74
+ const set = this.handlers.get(type);
75
+ if (set) {
76
+ for (const handler of set) {
77
+ try {
78
+ handler(event);
79
+ }
80
+ catch (err) {
81
+ // Isolate subscriber failures — never let one handler break the room or skip others.
82
+ console.error(`[LiveKitRoomEventBus] handler for "${String(type)}" threw:`, err);
83
+ }
84
+ }
85
+ }
86
+ return event;
87
+ }
88
+ /** Removes all handlers. Called on controller dispose. */
89
+ Clear() {
90
+ this.handlers.clear();
91
+ }
92
+ }
93
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAyHH;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACmB,aAAQ,GAAG,IAAI,GAAG,EAAkF,CAAC;IAuExH,CAAC;IArEC;;;;;;OAMG;IACI,EAAE,CAAsC,IAAO,EAAE,OAA+B;QACrF,IAAI,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,OAAyD,CAAC,CAAC;QACnE,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;OAMG;IACI,IAAI,CAAsC,IAAO,EAAE,OAA+B;QACvF,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;YAClC,GAAG,EAAE,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACI,GAAG,CAAsC,IAAO,EAAE,OAA+B;QACtF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,OAAyD,CAAC,CAAC;IAC7F,CAAC;IAED;;;;;;;OAOG;IACI,IAAI,CAAsC,IAAO,EAAE,KAA6B;QACrF,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,GAAG,EAAE,CAAC;YACR,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACF,OAAkC,CAAC,KAAK,CAAC,CAAC;gBAC7C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,qFAAqF;oBACrF,OAAO,CAAC,KAAK,CAAC,sCAAsC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;gBACnF,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0DAA0D;IACnD,KAAK;QACV,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview Public entry point for `@memberjunction/livekit-room-core`.
3
+ *
4
+ * Framework-agnostic, pure-TypeScript core for the MJ-native realtime room UX. Wraps `livekit-client`
5
+ * into an observable {@link LiveKitRoomController} and supporting helpers, consumable from any framework.
6
+ *
7
+ * @module @memberjunction/livekit-room-core
8
+ */
9
+ export { LiveKitRoomController, defaultRoomFactory, defaultRoleResolver, type LiveKitRoomFactory, type LiveKitRoleResolver, type LiveKitRoomControllerOptions, } from './livekit-room-controller.js';
10
+ export { LiveKitAudioMeter, AUDIO_METER_BIN_COUNT, AUDIO_METER_SILENCE_FLOOR, type LiveKitAudioMeterFrame } from './audio-meter.js';
11
+ export { LiveKitMediaPreview } from './livekit-preview.js';
12
+ export { applyNoiseFilter, applyBackgroundEffect } from './livekit-effects.js';
13
+ export { LiveKitRoomEventBus, type LiveKitEventHandler, type LiveKitRoomEventMap, type LiveKitCancelableEvent, type LiveKitBeforeConnectEvent, type LiveKitBeforeDisconnectEvent, type LiveKitBeforeMediaToggleEvent, type LiveKitBeforeSendDataEvent, type LiveKitBeforeDeviceSwitchEvent, type LiveKitParticipantJoinedEvent, type LiveKitParticipantLeftEvent, type LiveKitActiveSpeakersEvent, type LiveKitDisconnectedEvent, } from './events.js';
14
+ export type { LiveKitConnectionStatus, LiveKitDisconnectReason, LiveKitParticipantRole, LiveKitTrackKind, LiveKitParticipantView, LiveKitDataMessage, LiveKitRoomError, LiveKitLocalMediaState, LiveKitDevice, LiveKitRoomConnectOptions, LiveKitRoomState, LiveKitTrackSourceMapper, LiveKitBackgroundEffect, LiveKitE2EEOptions, } from './types.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEjI,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,GAC9B,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,yBAAyB,EACzB,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Public entry point for `@memberjunction/livekit-room-core`.
3
+ *
4
+ * Framework-agnostic, pure-TypeScript core for the MJ-native realtime room UX. Wraps `livekit-client`
5
+ * into an observable {@link LiveKitRoomController} and supporting helpers, consumable from any framework.
6
+ *
7
+ * @module @memberjunction/livekit-room-core
8
+ */
9
+ export { LiveKitRoomController, defaultRoomFactory, defaultRoleResolver, } from './livekit-room-controller.js';
10
+ export { LiveKitAudioMeter, AUDIO_METER_BIN_COUNT, AUDIO_METER_SILENCE_FLOOR } from './audio-meter.js';
11
+ export { LiveKitMediaPreview } from './livekit-preview.js';
12
+ export { applyNoiseFilter, applyBackgroundEffect } from './livekit-effects.js';
13
+ export { LiveKitRoomEventBus, } from './events.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,yBAAyB,EAA+B,MAAM,eAAe,CAAC;AAEjI,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,OAAO,EACL,mBAAmB,GAapB,MAAM,UAAU,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Lazy adapters for the optional LiveKit Cloud media-processor SDKs — the Krisp noise
3
+ * filter (`@livekit/krisp-noise-filter`) and camera background effects (`@livekit/track-processors`).
4
+ *
5
+ * These are loaded with dynamic `import()` deliberately (CLAUDE rule 8 exception #2/#3): they are optional,
6
+ * heavy (WASM) cloud features, so deferring the load keeps them off the critical path and lets the room
7
+ * degrade gracefully when a feature is unused. Both packages ARE declared in this package's dependencies.
8
+ *
9
+ * @module @memberjunction/livekit-room-core
10
+ */
11
+ import type { LocalAudioTrack, LocalVideoTrack } from 'livekit-client';
12
+ import type { LiveKitBackgroundEffect } from './types.js';
13
+ /**
14
+ * Applies (or removes) the Krisp noise filter on a local microphone track.
15
+ *
16
+ * @param track The local audio track to process.
17
+ * @param enabled Whether to enable the filter.
18
+ * @returns `true` if applied/removed successfully; `false` if unsupported or the SDK is unavailable.
19
+ */
20
+ export declare function applyNoiseFilter(track: LocalAudioTrack, enabled: boolean): Promise<boolean>;
21
+ /**
22
+ * Applies a background effect (blur / virtual background) to a local camera track, or clears it.
23
+ *
24
+ * @param track The local video track to process.
25
+ * @param effect The effect to apply (`'none'` clears any active processor).
26
+ * @returns `true` if applied/cleared successfully; `false` if the SDK is unavailable.
27
+ */
28
+ export declare function applyBackgroundEffect(track: LocalVideoTrack, effect: LiveKitBackgroundEffect): Promise<boolean>;
29
+ //# sourceMappingURL=livekit-effects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"livekit-effects.d.ts","sourceRoot":"","sources":["../src/livekit-effects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAejG;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,CAarH"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @fileoverview Lazy adapters for the optional LiveKit Cloud media-processor SDKs — the Krisp noise
3
+ * filter (`@livekit/krisp-noise-filter`) and camera background effects (`@livekit/track-processors`).
4
+ *
5
+ * These are loaded with dynamic `import()` deliberately (CLAUDE rule 8 exception #2/#3): they are optional,
6
+ * heavy (WASM) cloud features, so deferring the load keeps them off the critical path and lets the room
7
+ * degrade gracefully when a feature is unused. Both packages ARE declared in this package's dependencies.
8
+ *
9
+ * @module @memberjunction/livekit-room-core
10
+ */
11
+ /**
12
+ * Applies (or removes) the Krisp noise filter on a local microphone track.
13
+ *
14
+ * @param track The local audio track to process.
15
+ * @param enabled Whether to enable the filter.
16
+ * @returns `true` if applied/removed successfully; `false` if unsupported or the SDK is unavailable.
17
+ */
18
+ export async function applyNoiseFilter(track, enabled) {
19
+ try {
20
+ const mod = await import('@livekit/krisp-noise-filter');
21
+ if (!enabled) {
22
+ await track.stopProcessor();
23
+ return true;
24
+ }
25
+ if (!mod.isKrispNoiseFilterSupported()) {
26
+ return false;
27
+ }
28
+ await track.setProcessor(mod.KrispNoiseFilter());
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Applies a background effect (blur / virtual background) to a local camera track, or clears it.
37
+ *
38
+ * @param track The local video track to process.
39
+ * @param effect The effect to apply (`'none'` clears any active processor).
40
+ * @returns `true` if applied/cleared successfully; `false` if the SDK is unavailable.
41
+ */
42
+ export async function applyBackgroundEffect(track, effect) {
43
+ try {
44
+ const mod = await import('@livekit/track-processors');
45
+ if (effect.Kind === 'none') {
46
+ await track.stopProcessor();
47
+ return true;
48
+ }
49
+ const processor = effect.Kind === 'blur' ? mod.BackgroundBlur(effect.Radius ?? 10) : mod.VirtualBackground(effect.ImageUrl);
50
+ await track.setProcessor(processor);
51
+ return true;
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ //# sourceMappingURL=livekit-effects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"livekit-effects.js","sourceRoot":"","sources":["../src/livekit-effects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAsB,EAAE,OAAgB;IAC7E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAsB,EAAE,MAA+B;IACjG,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5H,MAAM,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}