@leia-org/luke-client 0.1.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 +69 -0
- package/dist/Luke.css +430 -0
- package/dist/components/AudioControls.d.ts +12 -0
- package/dist/components/AudioControls.d.ts.map +1 -0
- package/dist/components/AudioControls.js +43 -0
- package/dist/components/AudioControls.js.map +1 -0
- package/dist/components/ConnectionStatus.d.ts +7 -0
- package/dist/components/ConnectionStatus.d.ts.map +1 -0
- package/dist/components/ConnectionStatus.js +33 -0
- package/dist/components/ConnectionStatus.js.map +1 -0
- package/dist/components/LukeProvider.d.ts +5 -0
- package/dist/components/LukeProvider.d.ts.map +1 -0
- package/dist/components/LukeProvider.js +25 -0
- package/dist/components/LukeProvider.js.map +1 -0
- package/dist/components/TranscriptionDisplay.d.ts +9 -0
- package/dist/components/TranscriptionDisplay.d.ts.map +1 -0
- package/dist/components/TranscriptionDisplay.js +22 -0
- package/dist/components/TranscriptionDisplay.js.map +1 -0
- package/dist/hooks/useLuke.d.ts +3 -0
- package/dist/hooks/useLuke.d.ts.map +1 -0
- package/dist/hooks/useLuke.js +382 -0
- package/dist/hooks/useLuke.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/VoiceClientUI.d.ts +17 -0
- package/dist/ui/VoiceClientUI.d.ts.map +1 -0
- package/dist/ui/VoiceClientUI.js +84 -0
- package/dist/ui/VoiceClientUI.js.map +1 -0
- package/dist/ui/components/Icons.d.ts +8 -0
- package/dist/ui/components/Icons.d.ts.map +1 -0
- package/dist/ui/components/Icons.js +9 -0
- package/dist/ui/components/Icons.js.map +1 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/worker/audio-utils.d.ts +5 -0
- package/dist/worker/audio-utils.d.ts.map +1 -0
- package/dist/worker/audio-utils.js +52 -0
- package/dist/worker/audio-utils.js.map +1 -0
- package/dist/worker/audio.worker.d.ts +2 -0
- package/dist/worker/audio.worker.d.ts.map +1 -0
- package/dist/worker/audio.worker.js +60 -0
- package/dist/worker/audio.worker.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
import { useLukeContext } from '../components/LukeProvider.js';
|
|
4
|
+
import { MicIcon, StopIcon, TrashIcon, XIcon, MaximizeIcon, MinimizeIcon } from './components/Icons';
|
|
5
|
+
export const VoiceClientUI = ({ mode = 'modal', position = 'bottom-right', theme = 'light', title = 'Luke AI', width, height, onClose, showSettings = true }) => {
|
|
6
|
+
const { isConnected, isRecording, startRecording, stopRecording, transcription, clearTranscription, audioLevel, connectionState, connect, providers, selectedProvider, selectProvider, voices, selectedVoice, selectVoice, error } = useLukeContext();
|
|
7
|
+
const [isExpanded, setIsExpanded] = React.useState(mode === 'fullscreen');
|
|
8
|
+
const [currentMode, setCurrentMode] = React.useState(mode);
|
|
9
|
+
const [isSettingsOpen, setIsSettingsOpen] = React.useState(false);
|
|
10
|
+
// Auto-scroll logic
|
|
11
|
+
const [autoScroll, setAutoScroll] = React.useState(true);
|
|
12
|
+
const [hasScroll, setHasScroll] = React.useState(false);
|
|
13
|
+
const messagesRef = React.useRef(null);
|
|
14
|
+
const prevLengthRef = React.useRef(0);
|
|
15
|
+
// Check if scroll is needed
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (messagesRef.current) {
|
|
18
|
+
const { scrollHeight, clientHeight } = messagesRef.current;
|
|
19
|
+
setHasScroll(scrollHeight > clientHeight);
|
|
20
|
+
}
|
|
21
|
+
}, [transcription, currentMode, width, height]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
// Only scroll if autoScroll is enabled AND a NEW message has been added
|
|
24
|
+
// We compare current length with previous length to ignore updates to existing messages
|
|
25
|
+
if (autoScroll && transcription.length > prevLengthRef.current) {
|
|
26
|
+
if (messagesRef.current) {
|
|
27
|
+
// Use setTimeout to ensure DOM has updated
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
if (messagesRef.current) {
|
|
30
|
+
messagesRef.current.scrollTo({
|
|
31
|
+
top: messagesRef.current.scrollHeight,
|
|
32
|
+
behavior: 'smooth'
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}, 10);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
prevLengthRef.current = transcription.length;
|
|
39
|
+
}, [transcription, autoScroll]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
setCurrentMode(mode);
|
|
42
|
+
}, [mode]);
|
|
43
|
+
// Apply theme
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const root = document.documentElement;
|
|
46
|
+
if (theme === 'auto') {
|
|
47
|
+
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
48
|
+
root.setAttribute('data-luke-theme', isDark ? 'dark' : 'light');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
root.setAttribute('data-luke-theme', theme);
|
|
52
|
+
}
|
|
53
|
+
}, [theme]);
|
|
54
|
+
const handleMicClick = () => {
|
|
55
|
+
if (isRecording) {
|
|
56
|
+
stopRecording();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
startRecording();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const toggleMaximize = () => {
|
|
63
|
+
if (currentMode === 'modal') {
|
|
64
|
+
setCurrentMode('fullscreen');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
setCurrentMode('modal');
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const containerStyle = {};
|
|
71
|
+
if (currentMode === 'modal') {
|
|
72
|
+
if (width)
|
|
73
|
+
containerStyle.width = width;
|
|
74
|
+
if (height)
|
|
75
|
+
containerStyle.height = height;
|
|
76
|
+
}
|
|
77
|
+
return (_jsxs("div", { className: `luke-wrapper luke-mode-${currentMode} luke-pos-${position}`, style: containerStyle, "data-luke-theme": theme, children: [_jsxs("header", { className: "luke-header", children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [_jsx("div", { className: `status-dot ${connectionState === 'connected' ? 'connected' : ''}`, style: {
|
|
78
|
+
width: 8,
|
|
79
|
+
height: 8,
|
|
80
|
+
borderRadius: '50%',
|
|
81
|
+
background: connectionState === 'connected' ? 'var(--luke-success-color)' : 'var(--luke-text-secondary)'
|
|
82
|
+
} }), _jsx("span", { className: "luke-header-title", children: title })] }), _jsxs("div", { style: { display: 'flex', gap: '4px' }, children: [transcription.length > 0 && (_jsx("button", { onClick: clearTranscription, className: "luke-btn-icon", title: "Clear chat", children: _jsx(TrashIcon, {}) })), _jsx("button", { onClick: toggleMaximize, className: "luke-btn-icon", children: currentMode === 'modal' ? _jsx(MaximizeIcon, {}) : _jsx(MinimizeIcon, {}) }), onClose && (_jsx("button", { onClick: onClose, className: "luke-btn-icon", children: _jsx(XIcon, {}) }))] })] }), _jsxs("div", { className: "luke-body", children: [_jsx("div", { className: "luke-messages", ref: messagesRef, children: transcription.length === 0 ? (_jsx("div", { style: { flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--luke-text-secondary)', textAlign: 'center', fontSize: '14px', padding: '20px' }, children: isConnected ? 'Say hello!' : 'Connecting...' })) : (transcription.map((msg, idx) => (_jsxs("div", { className: `luke-message ${msg.role}`, children: [_jsx("span", { className: "luke-role-label", children: msg.role === 'user' ? 'You' : 'AI' }), _jsx("div", { className: "luke-bubble", children: msg.text })] }, idx)))) }), hasScroll && (_jsx("div", { style: { position: 'absolute', bottom: '260px', right: '20px', zIndex: 10 }, children: _jsx("button", { onClick: () => setAutoScroll(!autoScroll), className: `luke-btn-icon ${autoScroll ? 'active' : ''}`, title: autoScroll ? "Disable Auto-scroll" : "Enable Auto-scroll", style: { backgroundColor: autoScroll ? 'var(--luke-primary-bg)' : 'var(--luke-bg-color)', color: autoScroll ? 'var(--luke-primary-fg)' : 'var(--luke-text-secondary)', boxShadow: 'var(--luke-shadow-md)', width: 32, height: 32, borderRadius: '50%' }, children: _jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), _jsx("polyline", { points: "19 12 12 19 5 12" })] }) }) })), _jsxs("div", { className: "luke-controls", children: [error && (_jsx("div", { style: { padding: '8px', background: '#fee2e2', color: '#ef4444', borderRadius: '4px', fontSize: '12px' }, children: error.message })), connectionState === 'disconnected' ? (_jsx("button", { onClick: connect, style: { width: '100%', padding: '12px', background: 'var(--luke-primary-bg)', color: 'var(--luke-primary-fg)', border: 'none', borderRadius: '8px', cursor: 'pointer' }, children: "Connect" })) : (_jsxs("div", { className: "luke-mic-area", children: [_jsxs("div", { className: "luke-mic-wrapper", children: [isRecording && (_jsx("div", { className: "luke-visualizer", style: { transform: `translate(-50%, -50%) scale(${1 + audioLevel * 0.5})` } })), _jsx("button", { className: `luke-mic-btn ${isRecording ? 'active' : ''}`, onClick: handleMicClick, disabled: !isConnected, children: isRecording ? _jsx(StopIcon, {}) : _jsx(MicIcon, {}) })] }), _jsx("span", { className: "luke-status-text", children: isRecording ? 'Listening...' : 'Tap to speak' }), _jsxs("div", { className: "luke-pills-container", children: [selectedProvider && (_jsxs("div", { className: "luke-selection-pill", children: [_jsx("select", { value: selectedProvider.id, onChange: (e) => selectProvider(e.target.value), className: "luke-pill-select", children: providers.map(p => (_jsx("option", { value: p.id, children: p.name }, p.id))) }), _jsx("div", { className: "luke-pill-icon", children: _jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z" }), _jsx("path", { d: "M12 8v8" }), _jsx("path", { d: "M8 12h8" })] }) }), _jsx("span", { className: "luke-pill-label", children: selectedProvider.name }), _jsx("div", { className: "luke-pill-chevron", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "6 9 12 15 18 9" }) }) })] })), selectedVoice && (_jsxs("div", { className: "luke-selection-pill", children: [_jsx("select", { value: selectedVoice.id, onChange: (e) => selectVoice(e.target.value), className: "luke-pill-select", children: voices.map(v => (_jsx("option", { value: v.id, children: v.name }, v.id))) }), _jsx("div", { className: "luke-pill-icon", children: _jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }), _jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }), _jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }), _jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })] }) }), _jsx("span", { className: "luke-pill-label", children: selectedVoice.name }), _jsx("div", { className: "luke-pill-chevron", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "6 9 12 15 18 9" }) }) })] }))] })] }))] })] })] }));
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=VoiceClientUI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceClientUI.js","sourceRoot":"","sources":["../../src/ui/VoiceClientUI.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const MicIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const StopIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare const TrashIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare const SettingsIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const XIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare const MinimizeIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const MaximizeIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=Icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icons.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Icons.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,+CAOnB,CAAC;AAEF,eAAO,MAAM,QAAQ,+CAIpB,CAAC;AAEF,eAAO,MAAM,SAAS,+CAKrB,CAAC;AAEF,eAAO,MAAM,YAAY,+CAKxB,CAAC;AAEF,eAAO,MAAM,KAAK,+CAKjB,CAAC;AAEF,eAAO,MAAM,YAAY,+CAOxB,CAAC;AAEF,eAAO,MAAM,YAAY,+CAOxB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const MicIcon = () => (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }), _jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }), _jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }), _jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })] }));
|
|
3
|
+
export const StopIcon = () => (_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2", ry: "2" }) }));
|
|
4
|
+
export const TrashIcon = () => (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("polyline", { points: "3 6 5 6 21 6" }), _jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })] }));
|
|
5
|
+
export const SettingsIcon = () => (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("circle", { cx: "12", cy: "12", r: "3" }), _jsx("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })] }));
|
|
6
|
+
export const XIcon = () => (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }));
|
|
7
|
+
export const MinimizeIcon = () => (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "4", y1: "14", x2: "10", y2: "14" }), _jsx("line", { x1: "10", y1: "14", x2: "10", y2: "20" }), _jsx("line", { x1: "20", y1: "10", x2: "14", y2: "10" }), _jsx("line", { x1: "14", y1: "10", x2: "14", y2: "4" })] }));
|
|
8
|
+
export const MaximizeIcon = () => (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "15", y1: "3", x2: "21", y2: "3" }), _jsx("line", { x1: "21", y1: "3", x2: "21", y2: "9" }), _jsx("line", { x1: "9", y1: "21", x2: "3", y2: "21" }), _jsx("line", { x1: "3", y1: "21", x2: "3", y2: "15" })] }));
|
|
9
|
+
//# sourceMappingURL=Icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icons.js","sourceRoot":"","sources":["../../../src/ui/components/Icons.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function floatTo16BitPCM(float32Array: Float32Array): Int16Array;
|
|
2
|
+
export declare function pcm16ToFloat32(int16Array: Int16Array): Float32Array;
|
|
3
|
+
export declare function resampleAudio(inputSamples: Float32Array, inputRate: number, outputRate: number): Float32Array;
|
|
4
|
+
export declare function calculateAudioLevel(samples: Float32Array): number;
|
|
5
|
+
//# sourceMappingURL=audio-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../../src/worker/audio-utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,UAAU,CAWtE;AAGD,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,YAAY,CAQnE;AAGD,wBAAgB,aAAa,CACzB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACnB,YAAY,CAsBd;AAGD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CASjE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Audio utilities for PCM encoding/decoding
|
|
2
|
+
// Handles conversion between Float32Array (Web Audio) and Int16Array (PCM)
|
|
3
|
+
// Convert Float32 samples to 16-bit PCM
|
|
4
|
+
export function floatTo16BitPCM(float32Array) {
|
|
5
|
+
const int16Array = new Int16Array(float32Array.length);
|
|
6
|
+
for (let i = 0; i < float32Array.length; i++) {
|
|
7
|
+
// Clamp value between -1 and 1
|
|
8
|
+
const sample = Math.max(-1, Math.min(1, float32Array[i]));
|
|
9
|
+
// Convert to 16-bit integer
|
|
10
|
+
int16Array[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
|
|
11
|
+
}
|
|
12
|
+
return int16Array;
|
|
13
|
+
}
|
|
14
|
+
// Convert 16-bit PCM to Float32 samples
|
|
15
|
+
export function pcm16ToFloat32(int16Array) {
|
|
16
|
+
const float32Array = new Float32Array(int16Array.length);
|
|
17
|
+
for (let i = 0; i < int16Array.length; i++) {
|
|
18
|
+
float32Array[i] = int16Array[i] / (int16Array[i] < 0 ? 0x8000 : 0x7fff);
|
|
19
|
+
}
|
|
20
|
+
return float32Array;
|
|
21
|
+
}
|
|
22
|
+
// Resample audio to target sample rate
|
|
23
|
+
export function resampleAudio(inputSamples, inputRate, outputRate) {
|
|
24
|
+
if (inputRate === outputRate) {
|
|
25
|
+
return inputSamples;
|
|
26
|
+
}
|
|
27
|
+
const ratio = inputRate / outputRate;
|
|
28
|
+
const outputLength = Math.ceil(inputSamples.length / ratio);
|
|
29
|
+
const output = new Float32Array(outputLength);
|
|
30
|
+
for (let i = 0; i < outputLength; i++) {
|
|
31
|
+
const srcIndex = i * ratio;
|
|
32
|
+
const srcIndexFloor = Math.floor(srcIndex);
|
|
33
|
+
const srcIndexCeil = Math.min(srcIndexFloor + 1, inputSamples.length - 1);
|
|
34
|
+
const fraction = srcIndex - srcIndexFloor;
|
|
35
|
+
// Linear interpolation
|
|
36
|
+
output[i] =
|
|
37
|
+
inputSamples[srcIndexFloor] * (1 - fraction) +
|
|
38
|
+
inputSamples[srcIndexCeil] * fraction;
|
|
39
|
+
}
|
|
40
|
+
return output;
|
|
41
|
+
}
|
|
42
|
+
// Calculate RMS audio level (0-1 range)
|
|
43
|
+
export function calculateAudioLevel(samples) {
|
|
44
|
+
if (samples.length === 0)
|
|
45
|
+
return 0;
|
|
46
|
+
let sum = 0;
|
|
47
|
+
for (let i = 0; i < samples.length; i++) {
|
|
48
|
+
sum += samples[i] * samples[i];
|
|
49
|
+
}
|
|
50
|
+
return Math.sqrt(sum / samples.length);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=audio-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../../src/worker/audio-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.worker.d.ts","sourceRoot":"","sources":["../../src/worker/audio.worker.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Audio Worker
|
|
2
|
+
// Runs in a Web Worker to handle audio processing off the main thread
|
|
3
|
+
import { floatTo16BitPCM, pcm16ToFloat32, resampleAudio, calculateAudioLevel } from './audio-utils.js';
|
|
4
|
+
// Target sample rate (set by server based on provider)
|
|
5
|
+
let targetSampleRate = 16000;
|
|
6
|
+
// Browser audio context typically runs at 44100 or 48000 Hz
|
|
7
|
+
const BROWSER_SAMPLE_RATE = 48000;
|
|
8
|
+
// Handle incoming messages
|
|
9
|
+
self.onmessage = (event) => {
|
|
10
|
+
const message = event.data;
|
|
11
|
+
switch (message.type) {
|
|
12
|
+
case 'configure':
|
|
13
|
+
targetSampleRate = message.sampleRate;
|
|
14
|
+
break;
|
|
15
|
+
case 'encode':
|
|
16
|
+
encodeAudio(message.samples);
|
|
17
|
+
break;
|
|
18
|
+
case 'decode':
|
|
19
|
+
decodeAudio(message.pcmData);
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
// Encode Float32 audio from browser to PCM for server
|
|
24
|
+
function encodeAudio(samples) {
|
|
25
|
+
// Resample to target rate
|
|
26
|
+
const resampled = resampleAudio(samples, BROWSER_SAMPLE_RATE, targetSampleRate);
|
|
27
|
+
// Calculate audio level before encoding
|
|
28
|
+
const level = calculateAudioLevel(resampled);
|
|
29
|
+
// Convert to 16-bit PCM
|
|
30
|
+
const pcm = floatTo16BitPCM(resampled);
|
|
31
|
+
// Copy to new ArrayBuffer to ensure it's transferable
|
|
32
|
+
const buffer = new ArrayBuffer(pcm.byteLength);
|
|
33
|
+
new Int16Array(buffer).set(pcm);
|
|
34
|
+
// Send back to main thread
|
|
35
|
+
const response = {
|
|
36
|
+
type: 'encoded',
|
|
37
|
+
pcmData: buffer,
|
|
38
|
+
level,
|
|
39
|
+
};
|
|
40
|
+
self.postMessage(response);
|
|
41
|
+
}
|
|
42
|
+
// Decode PCM from server to Float32 for playback
|
|
43
|
+
function decodeAudio(pcmData) {
|
|
44
|
+
// Convert PCM to Int16Array
|
|
45
|
+
const pcm = new Int16Array(pcmData);
|
|
46
|
+
// Convert to Float32
|
|
47
|
+
const float32 = pcm16ToFloat32(pcm);
|
|
48
|
+
// Resample from server rate (24kHz output) to browser rate
|
|
49
|
+
const resampled = resampleAudio(float32, 24000, BROWSER_SAMPLE_RATE);
|
|
50
|
+
// Create copy of samples to ensure clean transfer
|
|
51
|
+
const result = new Float32Array(resampled.length);
|
|
52
|
+
result.set(resampled);
|
|
53
|
+
// Send back to main thread
|
|
54
|
+
const response = {
|
|
55
|
+
type: 'decoded',
|
|
56
|
+
samples: result,
|
|
57
|
+
};
|
|
58
|
+
self.postMessage(response);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=audio.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.worker.js","sourceRoot":"","sources":["../../src/worker/audio.worker.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,sEAAsE;AAEtE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAiCvG,uDAAuD;AACvD,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAKlC,2BAA2B;AAC3B,IAAI,CAAC,SAAS,GAAG,CAAC,KAAkC,EAAE,EAAE;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;IAE3B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACZ,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;YACtC,MAAM;QAEV,KAAK,QAAQ;YACT,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM;QAEV,KAAK,QAAQ;YACT,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM;IACd,CAAC;AACL,CAAC,CAAC;AAEF,sDAAsD;AACtD,SAAS,WAAW,CAAC,OAAqB;IACtC,0BAA0B;IAC1B,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;IAEhF,wCAAwC;IACxC,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAE7C,wBAAwB;IACxB,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAEvC,sDAAsD;IACtD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,MAAM,QAAQ,GAAoB;QAC9B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;QACf,KAAK;KACR,CAAC;IACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,iDAAiD;AACjD,SAAS,WAAW,CAAC,OAAoB;IACrC,4BAA4B;IAC5B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpC,qBAAqB;IACrB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAEpC,2DAA2D;IAC3D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC;IAErE,kDAAkD;IAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEtB,2BAA2B;IAC3B,MAAM,QAAQ,GAAoB;QAC9B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM;KAClB,CAAC;IACF,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.1.0",
|
|
3
|
+
"name": "@leia-org/luke-client",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "React client for realtime AI voice communication",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./style.css": "./dist/Luke.css"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/react": "^19.0.2",
|
|
20
|
+
"typescript": "^5.7.2",
|
|
21
|
+
"vitest": "^2.1.8"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc",
|
|
32
|
+
"dev": "tsc --watch",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"lint": "tsc --noEmit",
|
|
35
|
+
"postbuild": "cp src/ui/Luke.css dist/Luke.css"
|
|
36
|
+
}
|
|
37
|
+
}
|