@touchcastllc/napster-companion-api-dev 1.0.0-alpha.79 → 1.0.0-alpha.81

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.
@@ -76,17 +76,25 @@ export declare class EdgeMcpBridge {
76
76
  * Relay the current value of every registered resource to the agent once, as
77
77
  * an initial state seed — batched into a SINGLE `send_message` rather than one
78
78
  * per resource, so the agent gets the whole starting state in one context
79
- * injection. Feature-detects the toolkit's resource extension (`getResources` /
80
- * `readResource`) — a bare WebMCP surface has neither, so this is a no-op there.
81
- * Already-seeded URIs are skipped so a `resourcelistchanged` re-seed only emits
82
- * genuinely new resources. (Ongoing changes still relay per-resource via
83
- * `relayResourceUpdate`, since they happen one at a time.)
79
+ * injection. Deferred until the session's "ready" state, exactly like tool
80
+ * registration: before that the data channel isn't open and a send would be
81
+ * silently dropped — onSessionReady() runs the seed at the first moment it
82
+ * can succeed, reading each value fresh at that point. Feature-detects the
83
+ * toolkit's resource extension (`getResources` / `readResource`) — a bare
84
+ * WebMCP surface has neither, so this is a no-op there. Already-seeded URIs
85
+ * are skipped so a `resourcelistchanged` re-seed only emits genuinely new
86
+ * resources; URIs are marked seeded only after a successful send, so a
87
+ * refused send stays owed to the agent. (Ongoing changes still relay
88
+ * per-resource via `relayResourceUpdate`, since they happen one at a time.)
84
89
  */
85
90
  private seedResources;
86
91
  /**
87
92
  * Send the whole initial state set to the agent as ONE `role: 'system'`
88
93
  * message (one line per resource). `trigger_response: false` so the avatar
89
94
  * doesn't speak on the seed; `delay: true` to wait for any current speech.
95
+ * Returns true when the send went out; false when the channel refused it
96
+ * (not open / interaction stopped) so the caller leaves the URIs unmarked
97
+ * and a later seed trigger re-reads and re-delivers them.
90
98
  */
91
99
  private relayInitialState;
92
100
  /** Re-read the tool catalog from the model context. */
@@ -95,19 +103,26 @@ export declare class EdgeMcpBridge {
95
103
  private buildInlineFunctions;
96
104
  /**
97
105
  * Called by the SDK when the session reaches the "ready" state
98
- * (`avatar_state_changed` → `state: "ready"`). This is the only safe moment to
99
- * register tools — the realtime session silently drops `inline_functions` sent
100
- * before it's ready (e.g. on data-channel open). Marks the session ready,
101
- * resets the dedupe, and pushes the current tools. Re-fires on reconnect (a
102
- * fresh "ready").
106
+ * (`avatar_state_changed` → `state: "ready"`). This is the first moment the
107
+ * agent is reachable — the realtime session silently drops `inline_functions`
108
+ * sent before it's ready, and the data channel isn't open earlier (the
109
+ * "ready" event itself arrives over it). Marks the session ready, pushes the
110
+ * current tools, and delivers the initial state seed that bind() deferred.
111
+ *
112
+ * The backend can emit "ready" more than once per session; repeats are
113
+ * no-ops when nothing changed (the push dedupes on catalog content, the seed
114
+ * on delivered URIs). A genuinely NEW session never reaches this method on a
115
+ * live bridge: the SDK tears the whole instance down (destroyInstance →
116
+ * dispose) and the next init builds a fresh bridge with clean dedupe state.
103
117
  */
104
118
  onSessionReady(): void;
105
119
  /**
106
120
  * Register the page's WebMCP tools with the agent by sending the complete
107
- * current catalog as `set_settings.inline_functions`. Called on attach, on
108
- * every toolchange, and on data-channel open, so tools registered mid-session
109
- * reach the agent. No-op when not attached, when `registerInlineFunctions` is
110
- * disabled, or when the catalog is unchanged since the last successful push.
121
+ * current catalog as `set_settings.inline_functions`. Called on attach
122
+ * (deferred until ready), on session ready, and on every toolchange, so
123
+ * tools registered mid-session reach the agent. No-op when not attached,
124
+ * when `registerInlineFunctions` is disabled, or when the catalog is
125
+ * unchanged since the last successful push.
111
126
  */
112
127
  private pushInlineFunctions;
113
128
  /** True if `attach()` succeeded and the bridge has a live model context. */
@@ -126,7 +141,10 @@ export declare class EdgeMcpBridge {
126
141
  /**
127
142
  * Forward a toolkit resource update to the agent as a system message.
128
143
  * `trigger_response: false` keeps the avatar from speaking on every change;
129
- * `delay: true` waits for it to finish its current speech first.
144
+ * `delay: true` waits for it to finish its current speech first. Before the
145
+ * session's first "ready" this is a deliberate no-op — the channel can't
146
+ * carry the message yet, and the session-ready seed reads the then-current
147
+ * value anyway, so relaying earlier would only warn and drop.
130
148
  */
131
149
  private relayResourceUpdate;
132
150
  /**
@@ -1,5 +1,2 @@
1
1
  export { EdgeMcpBridge } from "./edge-mcp-bridge";
2
- export type { EdgeMcpBridgeOptions } from "./edge-mcp-bridge";
3
2
  export { normalizeFunctionCallEvent } from "./normalizeFunctionCallEvent";
4
- export { getModelContext, discoverModelContext } from "./edge-mcp-discovery";
5
- export type { EdgeMcpModelContext, EdgeMcpToolInfo, EdgeMcpToolAnnotations, EdgeMcpResourceUpdate, FunctionCallEvent, SendCommand, } from "./edge-mcp-types";
@@ -1,4 +1,4 @@
1
- import { type EventMessage, type CompanionFunction } from "../types";
1
+ import { type EventMessage } from "../types";
2
2
  import type { MediaCapture } from "../utils/MediaCapture";
3
3
  export interface WebRTCController {
4
4
  startWithToken: (token: string) => Promise<void>;
@@ -11,7 +11,6 @@ export interface WebRTCController {
11
11
  }
12
12
  interface WebRTCParams {
13
13
  currentAudioDeviceId?: string;
14
- functions?: CompanionFunction[];
15
14
  screenShareCapture?: MediaCapture | null;
16
15
  onChatMessage?: (data: EventMessage) => void;
17
16
  onConnectionSuccess?: () => void;
@@ -23,6 +22,18 @@ interface WebRTCParams {
23
22
  onDataChannel?: (dc: RTCDataChannel) => void;
24
23
  maxReconnectAttempts?: number;
25
24
  reconnectInterval?: number;
25
+ /**
26
+ * ICE servers for the peer connection. When omitted, servers from the
27
+ * connection token are used, else {@link DEFAULT_ICE_SERVERS}. Provide this to
28
+ * inject deployment-specific or ephemeral TURN credentials.
29
+ */
30
+ iceServers?: RTCIceServer[];
26
31
  }
32
+ /**
33
+ * Resolve the RTCPeerConnection ICE configuration. Prefers caller-supplied ICE
34
+ * servers (ideally short-lived, per-session credentials minted by the backend)
35
+ * and falls back to {@link DEFAULT_ICE_SERVERS} only when none are provided.
36
+ */
37
+ export declare function resolveRtcConfiguration(iceServers?: RTCIceServer[] | null): RTCConfiguration;
27
38
  export declare function createWebRTCController(params?: WebRTCParams): WebRTCController;
28
39
  export {};
@@ -1,8 +1,6 @@
1
1
  export { store } from "./store";
2
- export type { RootState, AppDispatch } from "./store";
2
+ export type { RootState } from "./store";
3
3
  export { setOnFeaturesUpdateCallback } from "./middleware/featuresUpdateMiddleware";
4
4
  export * from "./selectors";
5
- export { setSessionId, setAvatarReady, setDataChannel, setAvatarId, setVideoId, setStopInteraction, setMuted, setAutoMicActive, setVolume, setAvatarSpeaking, setScreenSharing, setUserTalking, addTranscript, setCustomVoiceId, setDefaultVoiceId, setConnectionToken, setCloseConnectionHandler, setSessionTerminatedByServer, resetAvatar, avatarReducer, } from "./slices/avatarSlice";
6
- export type { WebRTCStatus, AvatarState, Transcript, } from "./slices/avatarSlice";
7
- export { appReducer, setFeatures, resetFeatures, setPosition, setShowExperience, setDebugMode, } from "./slices/appSlice";
8
- export type { AppState } from "./slices/appSlice";
5
+ export { setSessionId, setAvatarReady, setDataChannel, setStopInteraction, setMuted, setAutoMicActive, setVolume, setAvatarSpeaking, setScreenSharing, setUserTalking, setConnectionToken, setCloseConnectionHandler, setSessionTerminatedByServer, resetAvatar, } from "./slices/avatarSlice";
6
+ export { setFeatures, resetFeatures, setPosition, setDebugMode, } from "./slices/appSlice";
@@ -1,25 +1,16 @@
1
1
  import { RootState } from "./index";
2
2
  import { FeatureConfig, Position } from "../types";
3
- import { Transcript } from "./slices/avatarSlice";
4
3
  /**
5
4
  * Avatar state selectors
6
5
  */
7
6
  export declare const selectSessionId: (state: RootState) => string | undefined;
8
7
  export declare const selectAvatarReady: (state: RootState) => boolean;
9
8
  export declare const selectDataChannel: (state: RootState) => RTCDataChannel | null;
10
- export declare const selectAvatarId: (state: RootState) => string | undefined;
11
- export declare const selectVideoId: (state: RootState) => string | undefined;
12
9
  export declare const selectMuted: (state: RootState) => boolean;
13
10
  export declare const selectAutoMicActive: (state: RootState) => boolean;
14
- export declare const selectVolume: (state: RootState) => number;
15
11
  export declare const selectAvatarSpeaking: (state: RootState) => boolean;
16
- export declare const selectScreenSharing: (state: RootState) => boolean;
17
12
  export declare const selectUserTalking: (state: RootState) => boolean;
18
- export declare const selectTranscript: (state: RootState) => Transcript | undefined;
19
- export declare const selectCustomVoiceId: (state: RootState) => string | undefined;
20
- export declare const selectDefaultVoiceId: (state: RootState) => string | undefined;
21
13
  export declare const selectConnectionToken: (state: RootState) => string | undefined;
22
- export declare const selectCompanionId: (state: RootState) => string | undefined;
23
14
  export declare const selectStopInteraction: (state: RootState) => boolean;
24
15
  export declare const selectCloseConnectionHandler: (state: RootState) => (() => void) | undefined;
25
16
  export declare const selectSessionTerminatedByServer: (state: RootState) => boolean;
@@ -28,7 +19,6 @@ export declare const selectSessionTerminatedByServer: (state: RootState) => bool
28
19
  */
29
20
  export declare const selectFeatures: (state: RootState) => FeatureConfig;
30
21
  export declare const selectPosition: (state: RootState) => Position | undefined;
31
- export declare const selectShowExperience: (state: RootState) => boolean;
32
22
  /**
33
23
  * Composite selectors
34
24
  */
@@ -2,11 +2,10 @@ import { Position, FeatureConfig } from "../../types";
2
2
  export interface AppState {
3
3
  features: FeatureConfig;
4
4
  position?: Position;
5
- showExperience: boolean;
6
5
  debugMode?: boolean;
7
6
  }
8
7
  export declare const setFeatures: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
9
8
  feature: keyof FeatureConfig;
10
9
  config: FeatureConfig[keyof FeatureConfig];
11
- }, "app/setFeatures">, resetFeatures: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"app/resetFeatures">, setPosition: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<Position | undefined, "app/setPosition">, setShowExperience: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "app/setShowExperience">, setDebugMode: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<boolean | undefined, "app/setDebugMode">;
10
+ }, "app/setFeatures">, resetFeatures: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"app/resetFeatures">, setPosition: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<Position | undefined, "app/setPosition">, setDebugMode: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<boolean | undefined, "app/setDebugMode">;
12
11
  export declare const appReducer: import("redux").Reducer<AppState>;
@@ -3,16 +3,10 @@ export interface WebRTCStatus {
3
3
  reason: string;
4
4
  message: string;
5
5
  }
6
- export interface Transcript {
7
- role: string;
8
- content: string;
9
- }
10
6
  export interface AvatarState {
11
7
  sessionId?: string;
12
8
  avatarReady: boolean;
13
9
  dataChannel: RTCDataChannel | null;
14
- avatarId?: string;
15
- videoId?: string;
16
10
  stopInteraction: boolean;
17
11
  muted: boolean;
18
12
  autoMicActive: boolean;
@@ -20,13 +14,9 @@ export interface AvatarState {
20
14
  avatarSpeaking: boolean;
21
15
  isScreenSharing: boolean;
22
16
  isUserTalking: boolean;
23
- transcript?: Transcript;
24
- customVoiceId: string | undefined;
25
- defaultVoiceId: string | undefined;
26
17
  connectionToken?: string;
27
- companionId?: string;
28
18
  closeConnectionHandler?: () => void;
29
19
  sessionTerminatedByServer: boolean;
30
20
  }
31
- export declare const setSessionId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setSessionId">, setAvatarReady: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAvatarReady">, setDataChannel: import("@reduxjs/toolkit").ActionCreatorWithPayload<RTCDataChannel | null, "avatar/setDataChannel">, setAvatarId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setAvatarId">, setVideoId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setVideoId">, setStopInteraction: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setStopInteraction">, setMuted: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setMuted">, setAutoMicActive: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAutoMicActive">, setVolume: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "avatar/setVolume">, setAvatarSpeaking: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAvatarSpeaking">, setScreenSharing: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setScreenSharing">, setUserTalking: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setUserTalking">, addTranscript: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<Transcript | undefined, "avatar/addTranscript">, setCustomVoiceId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setCustomVoiceId">, setDefaultVoiceId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setDefaultVoiceId">, setConnectionToken: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setConnectionToken">, setCloseConnectionHandler: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<(() => void) | undefined, "avatar/setCloseConnectionHandler">, setSessionTerminatedByServer: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setSessionTerminatedByServer">, resetAvatar: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"avatar/resetAvatar">;
21
+ export declare const setSessionId: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setSessionId">, setAvatarReady: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAvatarReady">, setDataChannel: import("@reduxjs/toolkit").ActionCreatorWithPayload<RTCDataChannel | null, "avatar/setDataChannel">, setStopInteraction: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setStopInteraction">, setMuted: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setMuted">, setAutoMicActive: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAutoMicActive">, setVolume: import("@reduxjs/toolkit").ActionCreatorWithPayload<number, "avatar/setVolume">, setAvatarSpeaking: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setAvatarSpeaking">, setScreenSharing: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setScreenSharing">, setUserTalking: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setUserTalking">, setConnectionToken: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<string | undefined, "avatar/setConnectionToken">, setCloseConnectionHandler: import("@reduxjs/toolkit").ActionCreatorWithOptionalPayload<(() => void) | undefined, "avatar/setCloseConnectionHandler">, setSessionTerminatedByServer: import("@reduxjs/toolkit").ActionCreatorWithPayload<boolean, "avatar/setSessionTerminatedByServer">, resetAvatar: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"avatar/resetAvatar">;
32
22
  export declare const avatarReducer: import("redux").Reducer<AvatarState>;
@@ -1,10 +1,10 @@
1
1
  export declare const store: import("@reduxjs/toolkit").EnhancedStore<{
2
- avatar: import(".").AvatarState;
3
- app: import(".").AppState;
2
+ avatar: import("./slices/avatarSlice").AvatarState;
3
+ app: import("./slices/appSlice").AppState;
4
4
  }, import("redux").UnknownAction, import("@reduxjs/toolkit").Tuple<[import("redux").StoreEnhancer<{
5
5
  dispatch: import("redux-thunk").ThunkDispatch<{
6
- avatar: import(".").AvatarState;
7
- app: import(".").AppState;
6
+ avatar: import("./slices/avatarSlice").AvatarState;
7
+ app: import("./slices/appSlice").AppState;
8
8
  }, undefined, import("redux").UnknownAction>;
9
9
  }>, import("redux").StoreEnhancer]>>;
10
10
  export type RootState = ReturnType<typeof store.getState>;
@@ -142,12 +142,6 @@ export interface FeatureConfig {
142
142
  backgroundRemoval?: {
143
143
  enabled: boolean;
144
144
  };
145
- /** Waveform display settings shown during audio playback/recording. */
146
- waveform?: {
147
- enabled: boolean;
148
- /** Optional CSS color value for the waveform. Defaults are applied by the SDK if omitted. */
149
- color?: string;
150
- };
151
145
  /** Automatically hide or perform actions after a period of inactivity. */
152
146
  inactiveTimeout?: {
153
147
  enabled: boolean;
@@ -331,12 +325,37 @@ export interface NapsterCompanionApiConfig {
331
325
  layout?: "fixed" | "inline";
332
326
  /**
333
327
  * AI companion function definitions for function calling support.
334
- * These functions are sent to the server when the connection is established,
335
- * allowing the AI to invoke them during conversation.
328
+ *
329
+ * Functions are configured server-side and baked into the connection at
330
+ * session-creation time (the connection API / token). To register tools
331
+ * mid-session from the page, use the WebMCP bridge, which pushes them as
332
+ * `set_settings.inline_functions` after the session reaches "ready".
333
+ *
334
+ * @deprecated The SDK no longer sends these over the data channel — supplying
335
+ * them here has no effect. Configure functions via the connection API instead.
336
336
  */
337
337
  functions?: CompanionFunction[];
338
338
  /** Enable debug logging throughout the SDK. When enabled, detailed logs will be output to the console. */
339
339
  debug?: boolean;
340
+ /**
341
+ * ICE servers (STUN/TURN) for the underlying WebRTC connection. When set,
342
+ * these override the SDK's built-in defaults. Provide deployment-specific or,
343
+ * preferably, short-lived TURN credentials here instead of relying on static
344
+ * ones shipped in client code. The connection token, when it carries its own
345
+ * ICE servers, takes precedence over this value.
346
+ */
347
+ iceServers?: RTCIceServer[];
348
+ /**
349
+ * `targetOrigin` used when the SDK relays data-channel messages to
350
+ * `window.parent` (the `"avatar-data-channel-message"` event).
351
+ *
352
+ * Defaults to the current origin, so private session data (chat transcripts,
353
+ * avatar state) is only ever delivered to a same-origin parent. When the SDK
354
+ * is embedded cross-origin, set this to the trusted embedder's origin (e.g.
355
+ * `"https://app.example.com"`). Setting it to `"*"` broadcasts to any parent
356
+ * origin and is insecure — use only if you understand the exposure.
357
+ */
358
+ parentOrigin?: string;
340
359
  /**
341
360
  * Read WebMCP tools from a same-origin child iframe's `document.modelContext` instead of
342
361
  * this window's. Set by the persistent-agent shell (`mountShell` with `persist`) so the
@@ -17,9 +17,9 @@ type ClassInput = ClassValue | ClassArray | ClassObject;
17
17
  */
18
18
  export declare function cn(...inputs: ClassInput[]): string;
19
19
  /**
20
- * Common CSS class name constants for the WaveForm component
20
+ * Common CSS class name constants for the control bar
21
21
  */
22
- export declare const WaveFormClasses: {
22
+ export declare const ControlClasses: {
23
23
  readonly icon: "np_companion-action-btn-container-icon";
24
24
  readonly persistFillColor: "np_companion-persist-fill-color";
25
25
  readonly alignMiddle: "np_companion-align-middle";
@@ -28,12 +28,9 @@ export declare const WaveFormClasses: {
28
28
  readonly callEnd: "np_companion-action-btn-container-call-end";
29
29
  readonly container: "np_companion-action-btn-container-container";
30
30
  readonly wrapper: "np_companion-action-btn-container-wrapper";
31
- readonly canvas: "np_companion-action-btn-container-canvas";
32
31
  readonly controls: "np_companion-action-btn-container-controls";
33
32
  readonly left: "np_companion-action-btn-container-left";
34
- readonly middle: "np_companion-action-btn-container-middle";
35
33
  readonly right: "np_companion-action-btn-container-right";
36
- readonly wave: "np_companion-action-btn-container-wave";
37
34
  readonly stop: "np_companion-action-btn-container-stop";
38
35
  readonly questionBar: "np_companion-chat-question-bar-container";
39
36
  readonly talking: "np_companion-talking";
@@ -9,6 +9,11 @@ export interface DecodedBase64TokenType {
9
9
  connection: {
10
10
  id: string;
11
11
  signalingEndpoint: string;
12
+ /**
13
+ * Optional per-session ICE servers. When the backend mints ephemeral TURN
14
+ * credentials, it delivers them here so they never live in client code.
15
+ */
16
+ iceServers?: RTCIceServer[];
12
17
  };
13
18
  expiresAt: string;
14
19
  }
@@ -1,13 +1,4 @@
1
1
  import type { MouthLandmarks } from "../types";
2
- /**
3
- * MediaPipe Face Mesh landmark indices for mouth detection.
4
- */
5
- export declare const MOUTH_LANDMARK_INDICES: {
6
- readonly upperLip: 13;
7
- readonly lowerLip: 14;
8
- readonly leftCorner: 61;
9
- readonly rightCorner: 291;
10
- };
11
2
  /**
12
3
  * Creates a rolling average smoother for mouth-opening ratios.
13
4
  */
@@ -20,9 +20,9 @@ export declare class SVGBuilder {
20
20
  }
21
21
  export declare const svgBuilder: SVGBuilder;
22
22
  /**
23
- * Predefined SVG icons for WaveForm component
23
+ * Predefined SVG icons for the control bar buttons
24
24
  */
25
- export declare const WaveFormIcons: {
25
+ export declare const ControlIcons: {
26
26
  micUnmuted(): SVGSVGElement;
27
27
  micMuted(): SVGSVGElement;
28
28
  stop(): SVGSVGElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@touchcastllc/napster-companion-api-dev",
3
- "version": "1.0.0-alpha.79",
3
+ "version": "1.0.0-alpha.81",
4
4
  "keywords": [
5
5
  "napster",
6
6
  "companion-api",
@@ -1,18 +0,0 @@
1
- import "./Preview.css";
2
- export interface PreviewOptions {
3
- previewUrl?: string;
4
- idleVideoUrl?: string;
5
- onStartClick: () => void;
6
- isLoading?: boolean;
7
- onVideoLoaded?: (loaded: boolean) => void;
8
- shouldAnimate?: boolean;
9
- }
10
- export interface PreviewController {
11
- update: (opts: Partial<PreviewOptions>) => void;
12
- destroy: () => void;
13
- }
14
- /**
15
- * Vanilla Preview implementation. Renders a canvas over an optional looping video
16
- * and exposes a \"Start\" button. Designed to be lightweight and framework-free.
17
- */
18
- export declare function createPreview(mount: HTMLElement, options: PreviewOptions): PreviewController;
@@ -1,18 +0,0 @@
1
- import "./VolumeControl.css";
2
- import { BaseController } from "../../types";
3
- export interface VolumeControlOptions {
4
- initialVolume?: number;
5
- onChange?: (volume: number) => void;
6
- onMuteToggle?: (isMuted: boolean) => void;
7
- }
8
- export interface VolumeControlController extends BaseController<VolumeControlOptions> {
9
- setVolume: (volume: number) => void;
10
- getVolume: () => number;
11
- toggleMute: () => void;
12
- isMuted: () => boolean;
13
- }
14
- /**
15
- * Vanilla VolumeControl component.
16
- * Creates a circular button with speaker icon and vertical volume slider.
17
- */
18
- export declare function createVolumeControl(mount: HTMLElement, options?: VolumeControlOptions): VolumeControlController;
@@ -1,34 +0,0 @@
1
- /**
2
- * Waveform component constants
3
- */
4
- export declare const WAVEFORM_CONSTANTS: {
5
- /** Timeout in milliseconds before hiding controls on mouse inactivity */
6
- readonly MOUSE_HIDE_TIMEOUT_MS: 5000;
7
- /** Number of frames to maintain "talking" state after voice stops */
8
- readonly TALKING_COOLDOWN_FRAMES: 30;
9
- /** Minimum number of consecutive frames above threshold to consider user talking */
10
- readonly TALKING_REQUIRED_FRAMES: 3;
11
- /** Minimum amplitude threshold to detect voice activity */
12
- readonly TALKING_THRESHOLD: 6;
13
- /** Scale factor for waveform amplitude visualization */
14
- readonly AMPLITUDE_SCALE_FACTOR: 0.8;
15
- /** Canvas dimensions */
16
- readonly CANVAS_WIDTH: 160;
17
- readonly CANVAS_HEIGHT: 40;
18
- /** Waveform bar styling */
19
- readonly BAR_WIDTH: 2;
20
- readonly BAR_GAP: 1;
21
- /** FFT size for audio analysis */
22
- readonly FFT_SIZE: 256;
23
- };
24
- /**
25
- * Waveform visual effects
26
- */
27
- export declare const WAVEFORM_EFFECTS: {
28
- /** CSS filter for active talking state */
29
- readonly TALKING_FILTER: "brightness(0) saturate(100%) invert(48%) sepia(93%) saturate(1720%) hue-rotate(346deg) brightness(101%) contrast(103%)";
30
- /** CSS filter for inactive state */
31
- readonly INACTIVE_FILTER: "none";
32
- /** Transition duration for filter changes */
33
- readonly TRANSITION: "filter 0.3s ease";
34
- };