vocallabsai-sdk 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +328 -0
  3. package/lib/VocalLabsSDK.d.ts +33 -0
  4. package/lib/VocalLabsSDK.d.ts.map +1 -0
  5. package/lib/VocalLabsSDK.js +192 -0
  6. package/lib/audio/AudioManager.d.ts +37 -0
  7. package/lib/audio/AudioManager.d.ts.map +1 -0
  8. package/lib/audio/AudioManager.js +127 -0
  9. package/lib/audio/AudioQueueService.d.ts +105 -0
  10. package/lib/audio/AudioQueueService.d.ts.map +1 -0
  11. package/lib/audio/AudioQueueService.js +544 -0
  12. package/lib/audio/index.d.ts +2 -0
  13. package/lib/audio/index.d.ts.map +1 -0
  14. package/lib/audio/index.js +5 -0
  15. package/lib/call/CallManager.d.ts +12 -0
  16. package/lib/call/CallManager.d.ts.map +1 -0
  17. package/lib/call/CallManager.js +24 -0
  18. package/lib/call/index.d.ts +2 -0
  19. package/lib/call/index.d.ts.map +1 -0
  20. package/lib/call/index.js +5 -0
  21. package/lib/config/constants.d.ts +5 -0
  22. package/lib/config/constants.d.ts.map +1 -0
  23. package/lib/config/constants.js +7 -0
  24. package/lib/config/index.d.ts +2 -0
  25. package/lib/config/index.d.ts.map +1 -0
  26. package/lib/config/index.js +5 -0
  27. package/lib/index.d.ts +8 -0
  28. package/lib/index.d.ts.map +1 -0
  29. package/lib/index.js +30 -0
  30. package/lib/types/index.d.ts +68 -0
  31. package/lib/types/index.d.ts.map +1 -0
  32. package/lib/types/index.js +20 -0
  33. package/lib/utils/index.d.ts +2 -0
  34. package/lib/utils/index.d.ts.map +1 -0
  35. package/lib/utils/index.js +6 -0
  36. package/lib/utils/logger.d.ts +16 -0
  37. package/lib/utils/logger.d.ts.map +1 -0
  38. package/lib/utils/logger.js +53 -0
  39. package/package.json +73 -0
  40. package/src/VocalLabsSDK.ts +343 -0
  41. package/src/audio/AudioManager.ts +213 -0
  42. package/src/audio/AudioQueueService.ts +733 -0
  43. package/src/audio/index.ts +1 -0
  44. package/src/call/CallManager.ts +46 -0
  45. package/src/call/index.ts +1 -0
  46. package/src/config/constants.ts +8 -0
  47. package/src/config/index.ts +1 -0
  48. package/src/index.ts +18 -0
  49. package/src/types/index.ts +101 -0
  50. package/src/types/react-native.d.ts +100 -0
  51. package/src/utils/index.ts +1 -0
  52. package/src/utils/logger.ts +71 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Subspace
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,328 @@
1
+ # VocalLabs SDK
2
+
3
+ A lightweight React Native SDK for VocalLabs audio calls with built-in audio streaming. Connect directly to calls using call ID and WebSocket URL - no API polling, no authentication, just simple direct connections.
4
+
5
+ ## Features
6
+
7
+ - 🎤 **Direct Connection** - Connect directly with call ID and WebSocket URL
8
+ - 🎧 **Audio Streaming** - Real-time audio with WebSocket support
9
+ - 🔇 **Mute Control** - Built-in mute/unmute functionality
10
+ - 📈 **Statistics** - Real-time audio and sending stats
11
+ - 🎯 **Event-Driven** - Comprehensive event system for all actions
12
+ - 📝 **TypeScript** - Full TypeScript support with type definitions
13
+ - ⚡ **Lightweight** - No authentication, no polling, minimal overhead
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install vocal-native-sdk
19
+ # or
20
+ yarn add vocal-native-sdk
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```typescript
26
+ import VocalLabsSDK from 'vocal-native-sdk';
27
+
28
+ // 1. Initialize SDK (optional config)
29
+ const sdk = new VocalLabsSDK({
30
+ sampleRate: 8000,
31
+ enableLogs: true,
32
+ });
33
+
34
+ // 2. Setup event listeners
35
+ sdk.on('onAudioConnected', () => {
36
+ console.log('Audio connected!');
37
+ });
38
+
39
+ sdk.on('onUserConnected', (connected) => {
40
+ console.log('User connected:', connected);
41
+ });
42
+
43
+ sdk.on('onMuteChanged', (isMuted) => {
44
+ console.log('Mute status:', isMuted);
45
+ });
46
+
47
+ // 3. Connect with either callId, websocketUrl, or both
48
+ // If both provided, websocketUrl is used (prioritized)
49
+
50
+ // Option 1: Just websocket URL (callId extracted from query params)
51
+ await sdk.connect({ websocketUrl: 'wss://rupture2.vocallabs.ai/ws?callId=test-call-123&sampleRate=8000' });
52
+
53
+ // Option 2: Just call ID
54
+ await sdk.connect({ callId: 'test-call-123' });
55
+
56
+ // Option 3: Both (websocketUrl takes priority)
57
+ await sdk.connect({
58
+ callId: 'test-call-123',
59
+ websocketUrl: 'wss://rupture2.vocallabs.ai/ws?callId=test-call-123&sampleRate=8000'
60
+ });
61
+
62
+ // 4. Control the call
63
+ sdk.toggleMute(); // Toggle mute
64
+ sdk.setVolume(0.8); // Set volume
65
+ const stats = sdk.getStats(); // Get statistics
66
+
67
+ // 5. Disconnect when done
68
+ sdk.disconnect();
69
+ ```
70
+
71
+ ## Configuration
72
+
73
+ ### SDK Configuration Options
74
+
75
+ ```typescript
76
+ interface SDKConfig {
77
+ sampleRate?: number; // Optional: Audio sample rate (default: 8000)
78
+ enableLogs?: boolean; // Optional: Enable console logs (default: true)
79
+ }
80
+ ```
81
+
82
+ ### Example with Custom Configuration
83
+
84
+ ```typescript
85
+ const sdk = new VocalLabsSDK({
86
+ sampleRate: 16000,
87
+ enableLogs: false,
88
+ });
89
+ ```
90
+
91
+ ## API Reference
92
+
93
+ ### Main Methods
94
+
95
+ #### `initializeAudioService(audioService)`
96
+ Initialize the SDK with your AudioAPIService instance. **Must be called before connecting audio.**
97
+
98
+ ```typescript
99
+ const audioService = new AudioAPIService();
100
+ sdk.initializeAudioService(audioService);
101
+ ```
102
+
103
+ #### `connect({ callId?, websocketUrl? })`
104
+ Connect directly to a call. Provide either callId, websocketUrl, or both. If both are provided, websocketUrl takes priority.
105
+
106
+ ```typescript
107
+ // With just websocket URL (callId extracted from query params)
108
+ await sdk.connect({ websocketUrl: 'wss://rupture2.vocallabs.ai/ws?callId=test-123&sampleRate=8000' });
109
+
110
+ // With just call ID
111
+ await sdk.connect({ callId: 'test-123' });
112
+
113
+ // With both (websocket URL is prioritized)
114
+ await sdk.connect({
115
+ callId: 'test-123',
116
+ websocketUrl: 'wss://rupture2.vocallabs.ai/ws?callId=test-123&sampleRate=8000'
117
+ });
118
+ ```
119
+
120
+ #### `disconnect()`
121
+ Disconnect from the current call and clean up.
122
+
123
+ ```typescript
124
+ sdk.disconnect();
125
+ ```
126
+
127
+ #### `toggleMute()`
128
+ Toggle microphone mute state.
129
+
130
+ ```typescript
131
+ const isMuted = sdk.toggleMute();
132
+ console.log('Muted:', isMuted);
133
+ ```
134
+
135
+ #### `setVolume(volume)`
136
+ Set audio volume (0.0 to 1.0).
137
+
138
+ ```typescript
139
+ sdk.setVolume(0.8);
140
+ ```
141
+
142
+ #### `getState()`
143
+ Get current SDK state.
144
+
145
+ ```typescript
146
+ const state = sdk.getState();
147
+ console.log(state.isConnected, state.isMuted, state.currentCallId);
148
+ ```
149
+
150
+ #### `getStats()`
151
+ Get audio and sending statistics.
152
+
153
+ ```typescript
154
+ const stats = sdk.getStats();
155
+ console.log('Sent chunks:', stats.sending.sentChunks);
156
+ console.log('Received chunks:', stats.audio.receivedChunks);
157
+ ```
158
+
159
+ #### `dispose()`
160
+ Clean up all resources.
161
+
162
+ ```typescript
163
+ await sdk.dispose();
164
+ ```
165
+
166
+ ## Events
167
+
168
+ The SDK provides a comprehensive event system:
169
+
170
+ ### Audio Events
171
+ - `onAudioConnected` - Audio stream connected
172
+ - `onAudioDisconnected` - Audio stream disconnected
173
+ - `onUserConnected` - Other user connected to the call
174
+ - `onUserDisconnected` - Other user disconnected
175
+ - `onMuteChanged` - Mute state changed
176
+ - `onStatsUpdate` - Statistics updated
177
+
178
+ ### General Events
179
+ - `onError` - General error occurred
180
+ - `onLog` - Log message (if logging enabled)
181
+
182
+ ### Event Usage Example
183
+
184
+ ```typescript
185
+ sdk.on('onAudioConnected', () => {
186
+ console.log('Audio connected successfully');
187
+ });
188
+
189
+ sdk.on('onUserConnected', (connected) => {
190
+ if (connected) {
191
+ console.log('Other user joined the call');
192
+ }
193
+ });
194
+ });
195
+
196
+ sdk.on('onStatsUpdate', ({ audio, sending }) => {
197
+ console.log(`Queue size: ${audio.queueSize}`);
198
+ console.log(`Sent chunks: ${sending.sentChunks}`);
199
+ });
200
+ ```
201
+
202
+ ## Complete Example with React Native Component
203
+
204
+ ```typescript
205
+ import React, { useEffect, useRef, useState } from 'react';
206
+ import { View, Button, Text } from 'react-native';
207
+ import SubspaceCallSDK from 'subspace-call-sdk';
208
+ import AudioAPIService from './services/AudioService';
209
+
210
+ const CallScreen = ({ userId, friendId }) => {
211
+ const sdkRef = useRef<VocalLabsSDK | null>(null);
212
+ const [isConnected, setIsConnected] = useState(false);
213
+ const [isMuted, setIsMuted] = useState(false);
214
+
215
+ useEffect(() => {
216
+ // Initialize SDK
217
+ const sdk = new VocalLabsSDK({
218
+ sampleRate: 8000,
219
+ enableLogs: true,
220
+ });
221
+
222
+ // Setup listeners
223
+ sdk.on('onAudioConnected', () => {
224
+ setIsConnected(true);
225
+ console.log('Audio connected');
226
+ });
227
+
228
+ sdk.on('onAudioDisconnected', () => {
229
+ setIsConnected(false);
230
+ });
231
+
232
+ sdk.on('onMuteChanged', (muted) => {
233
+ setIsMuted(muted);
234
+ });
235
+
236
+ sdkRef.current = sdk;
237
+
238
+ return () => {
239
+ sdk.dispose();
240
+ };websocketUrl: string) => {
241
+ if (!sdkRef.current) return;
242
+
243
+ try {
244
+ // Just provide the websocket URL
245
+ await sdkRef.current.connect({ websocketUrl }
246
+ try {
247
+ // Provide either callId, websocketUrl, or both
248
+ await sdkRef.current.connect(callId, websocketUrl);
249
+ } catch (error) {
250
+ console.error('Failed to connect:', error);
251
+ }
252
+ };
253
+
254
+ const endCall = () => {
255
+ sdkRef.current?.disconnect();
256
+ };
257
+
258
+ const toggleMute = () => {
259
+ sdkRef.current?.toggleMute();
260
+ };
261
+
262
+ return (
263
+ <View>
264
+ <Text>Connected: {isConnected ? 'Yes' : 'No'}</Text>
265
+ <Text>Muted: {isMuted ? 'Yes' : 'No'}</Text>
266
+
267
+ <Button
268
+ title="Start Call"
269
+ onPress={() => startCall('wss://rupture2.vocallabs.ai/ws?callId=test-123&sampleRate=8000')}
270
+ />
271
+ <Button title="Toggle Mute" onPress={toggleMute} />
272
+ <Button title="End Call" onPress={endCall} />
273
+ </View>
274
+ );
275
+ };
276
+
277
+ export default CallScreen;
278
+ ```
279
+
280
+ ## Error Handling
281
+
282
+ The SDK provides detailed error information:
283
+
284
+ ```typescript
285
+ import { SDKError, ErrorCode } from 'vocal-native-sdk';
286
+
287
+ try {
288
+ await sdk.connect({ websocketUrl: 'wss://rupture2.vocallabs.ai/ws?callId=test-123&sampleRate=8000' });
289
+ } catch (error) {
290
+ if (error instanceof SDKError) {
291
+ switch (error.code) {
292
+ case ErrorCode.INVALID_CONFIG:
293
+ console.log('Invalid configuration or URL');
294
+ break;
295
+ case ErrorCode.AUDIO_CONNECTION_FAILED:
296
+ console.log('Audio connection failed');
297
+ break;
298
+ // ... handle other error codes
299
+ }
300
+ }
301
+ }
302
+ ```
303
+
304
+ ## TypeScript Support
305
+
306
+ The SDK is written in TypeScript and provides full type definitions:
307
+
308
+ ```typescript
309
+ import VocalLabsSDK, {
310
+ CallData,
311
+ SDKState,
312
+ AudioStats,
313
+ SendingStats
314
+ } from 'vocal-native-sdk';
315
+ ```
316
+
317
+ ## Requirements
318
+
319
+ - React Native >= 0.60.0
320
+ - React >= 16.8.0
321
+
322
+ ## License
323
+
324
+ MIT
325
+
326
+ ## Support
327
+
328
+ For issues and questions, please open an issue on GitHub.
@@ -0,0 +1,33 @@
1
+ import { SDKConfig, SDKState, EventType, EventCallback, CallData, AudioStats, SendingStats } from './types';
2
+ export declare class VocalLabsSDK {
3
+ private callManager;
4
+ private audioManager;
5
+ private logger;
6
+ private config;
7
+ private state;
8
+ private listeners;
9
+ constructor(config?: SDKConfig);
10
+ private setupAudioCallbacks;
11
+ connect(options: {
12
+ callId?: string;
13
+ websocketUrl?: string;
14
+ }): Promise<void>;
15
+ disconnect(): void;
16
+ toggleMute(): boolean;
17
+ setVolume(volume: number): void;
18
+ clearAudioQueue(): void;
19
+ getState(): SDKState;
20
+ getCurrentCall(): CallData | null;
21
+ getStats(): {
22
+ audio: AudioStats | null;
23
+ sending: SendingStats | null;
24
+ };
25
+ isMuted(): boolean;
26
+ isConnected(): boolean;
27
+ on<T = any>(event: EventType, callback: EventCallback<T>): void;
28
+ off<T = any>(event: EventType, callback: EventCallback<T>): void;
29
+ private _emit;
30
+ dispose(): Promise<void>;
31
+ }
32
+ export default VocalLabsSDK;
33
+ //# sourceMappingURL=VocalLabsSDK.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VocalLabsSDK.d.ts","sourceRoot":"","sources":["../src/VocalLabsSDK.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,SAAS,EACT,QAAQ,EAER,SAAS,EACT,aAAa,EACb,QAAQ,EAGR,UAAU,EACV,YAAY,EACb,MAAM,SAAS,CAAC;AAMjB,qBAAa,YAAY;IAEvB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,MAAM,CAAsB;IAGpC,OAAO,CAAC,KAAK,CAKX;IAGF,OAAO,CAAC,SAAS,CASf;gBAEU,MAAM,CAAC,EAAE,SAAS;IA8B9B,OAAO,CAAC,mBAAmB;IAqCrB,OAAO,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDjF,UAAU,IAAI,IAAI;IAoBlB,UAAU,IAAI,OAAO;IAcrB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO/B,eAAe,IAAI,IAAI;IAOvB,QAAQ,IAAI,QAAQ;IAOpB,cAAc,IAAI,QAAQ,GAAG,IAAI;IAOjC,QAAQ,IAAI;QAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAA;KAAE;IAOtE,OAAO,IAAI,OAAO;IAOlB,WAAW,IAAI,OAAO;IAOtB,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAW/D,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAWhE,OAAO,CAAC,KAAK;IAeP,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA2B/B;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VocalLabsSDK = void 0;
4
+ const types_1 = require("./types");
5
+ const constants_1 = require("./config/constants");
6
+ const logger_1 = require("./utils/logger");
7
+ const CallManager_1 = require("./call/CallManager");
8
+ const AudioManager_1 = require("./audio/AudioManager");
9
+ class VocalLabsSDK {
10
+ constructor(config) {
11
+ this.state = {
12
+ isInitialized: false,
13
+ isConnected: false,
14
+ currentCallId: null,
15
+ isMuted: false,
16
+ };
17
+ this.listeners = {
18
+ onAudioConnected: [],
19
+ onAudioDisconnected: [],
20
+ onUserConnected: [],
21
+ onUserDisconnected: [],
22
+ onMuteChanged: [],
23
+ onStatsUpdate: [],
24
+ onError: [],
25
+ onLog: [],
26
+ };
27
+ this.config = {
28
+ sampleRate: config?.sampleRate || constants_1.DEFAULT_CONFIG.SAMPLE_RATE,
29
+ enableLogs: config?.enableLogs !== false,
30
+ };
31
+ this.logger = new logger_1.Logger(this.config.enableLogs);
32
+ this.logger.setLogCallback((message, type) => {
33
+ this._emit('onLog', { message, type });
34
+ });
35
+ this.callManager = new CallManager_1.CallManager(this.logger);
36
+ this.audioManager = new AudioManager_1.AudioManager(this.logger, this.config.sampleRate);
37
+ this.setupAudioCallbacks();
38
+ this.logger.info('🚀 VocalLabs SDK initialized with built-in audio support');
39
+ this.state.isInitialized = true;
40
+ }
41
+ setupAudioCallbacks() {
42
+ this.audioManager.onConnected(() => {
43
+ this.state.isConnected = true;
44
+ this._emit('onAudioConnected');
45
+ });
46
+ this.audioManager.onDisconnected(() => {
47
+ this.state.isConnected = false;
48
+ this._emit('onAudioDisconnected');
49
+ });
50
+ this.audioManager.onMuteChanged((isMuted) => {
51
+ this.state.isMuted = isMuted;
52
+ this._emit('onMuteChanged', isMuted);
53
+ });
54
+ this.audioManager.onUserConnected((connected) => {
55
+ if (connected) {
56
+ this._emit('onUserConnected', true);
57
+ }
58
+ else {
59
+ this._emit('onUserDisconnected', false);
60
+ }
61
+ });
62
+ this.audioManager.onStatsUpdate((stats) => {
63
+ this._emit('onStatsUpdate', stats);
64
+ });
65
+ }
66
+ async connect(options) {
67
+ try {
68
+ if (!this.state.isInitialized) {
69
+ throw new types_1.SDKError('SDK not initialized', types_1.ErrorCode.NOT_INITIALIZED);
70
+ }
71
+ let { callId, websocketUrl } = options;
72
+ if (!callId && !websocketUrl) {
73
+ throw new types_1.SDKError('Either callId or websocketUrl must be provided', types_1.ErrorCode.INVALID_CONFIG);
74
+ }
75
+ if (!callId && websocketUrl) {
76
+ try {
77
+ const url = new URL(websocketUrl);
78
+ const callIdParam = url.searchParams.get('callId');
79
+ callId = callIdParam || `call-${Date.now()}`;
80
+ this.logger.info(`Extracted callId from URL: ${callId}`);
81
+ }
82
+ catch (e) {
83
+ callId = `call-${Date.now()}`;
84
+ this.logger.warning('Could not parse URL, using generated callId');
85
+ }
86
+ }
87
+ this.logger.info(`Connecting to call: ${callId}`);
88
+ const callData = {
89
+ call_id: callId,
90
+ websocket: websocketUrl || '',
91
+ };
92
+ this.callManager.setCurrentCall(callData);
93
+ this.state.currentCallId = callId;
94
+ await this.audioManager.connect({
95
+ callId: callId,
96
+ sampleRate: this.config.sampleRate,
97
+ wsUrl: websocketUrl,
98
+ });
99
+ this.logger.info('✅ Connected successfully');
100
+ }
101
+ catch (error) {
102
+ this._emit('onError', error);
103
+ throw error;
104
+ }
105
+ }
106
+ disconnect() {
107
+ this.logger.info('Disconnecting...');
108
+ this.audioManager.disconnect();
109
+ this.callManager.clearCurrentCall();
110
+ this.state.isConnected = false;
111
+ this.state.currentCallId = null;
112
+ this.state.isMuted = false;
113
+ this.logger.info('✅ Disconnected');
114
+ }
115
+ toggleMute() {
116
+ try {
117
+ const isMuted = this.audioManager.toggleMute();
118
+ this.state.isMuted = isMuted;
119
+ return isMuted;
120
+ }
121
+ catch (error) {
122
+ this._emit('onError', error);
123
+ throw error;
124
+ }
125
+ }
126
+ setVolume(volume) {
127
+ this.audioManager.setVolume(volume);
128
+ }
129
+ clearAudioQueue() {
130
+ this.audioManager.clearQueue();
131
+ }
132
+ getState() {
133
+ return { ...this.state };
134
+ }
135
+ getCurrentCall() {
136
+ return this.callManager.getCurrentCall();
137
+ }
138
+ getStats() {
139
+ return this.audioManager.getStats();
140
+ }
141
+ isMuted() {
142
+ return this.state.isMuted;
143
+ }
144
+ isConnected() {
145
+ return this.state.isConnected;
146
+ }
147
+ on(event, callback) {
148
+ if (this.listeners[event]) {
149
+ this.listeners[event].push(callback);
150
+ }
151
+ else {
152
+ this.logger.warning(`Unknown event: ${event}`);
153
+ }
154
+ }
155
+ off(event, callback) {
156
+ if (this.listeners[event]) {
157
+ this.listeners[event] = this.listeners[event].filter((cb) => cb !== callback);
158
+ }
159
+ }
160
+ _emit(event, data) {
161
+ if (this.listeners[event]) {
162
+ this.listeners[event].forEach((callback) => {
163
+ try {
164
+ callback(data);
165
+ }
166
+ catch (error) {
167
+ this.logger.error(`Error in ${event} listener:`, error);
168
+ }
169
+ });
170
+ }
171
+ }
172
+ async dispose() {
173
+ this.logger.info('Disposing SDK...');
174
+ if (this.state.isConnected) {
175
+ this.disconnect();
176
+ }
177
+ this.callManager.dispose();
178
+ await this.audioManager.dispose();
179
+ Object.keys(this.listeners).forEach((key) => {
180
+ this.listeners[key] = [];
181
+ });
182
+ this.state = {
183
+ isInitialized: false,
184
+ isConnected: false,
185
+ currentCallId: null,
186
+ isMuted: false,
187
+ };
188
+ this.logger.info('✅ SDK disposed');
189
+ }
190
+ }
191
+ exports.VocalLabsSDK = VocalLabsSDK;
192
+ exports.default = VocalLabsSDK;
@@ -0,0 +1,37 @@
1
+ import { AudioStats, SendingStats, AudioConnectionOptions } from '../types';
2
+ import { Logger } from '../utils/logger';
3
+ export declare class AudioManager {
4
+ private audioService;
5
+ private logger;
6
+ private sampleRate;
7
+ private isInitialized;
8
+ private onConnectedCallback?;
9
+ private onDisconnectedCallback?;
10
+ private onMuteChangedCallback?;
11
+ private onUserConnectedCallback?;
12
+ private onStatsUpdateCallback?;
13
+ constructor(logger: Logger, sampleRate?: number);
14
+ isServiceInitialized(): boolean;
15
+ private setupCallbacks;
16
+ connect(options: AudioConnectionOptions): Promise<void>;
17
+ disconnect(): void;
18
+ toggleMute(): boolean;
19
+ isMuted(): boolean;
20
+ isConnected(): boolean;
21
+ setVolume(volume: number): void;
22
+ clearQueue(): void;
23
+ getStats(): {
24
+ audio: AudioStats;
25
+ sending: SendingStats;
26
+ };
27
+ onConnected(callback: () => void): void;
28
+ onDisconnected(callback: () => void): void;
29
+ onMuteChanged(callback: (isMuted: boolean) => void): void;
30
+ onUserConnected(callback: (connected: boolean) => void): void;
31
+ onStatsUpdate(callback: (stats: {
32
+ audio: AudioStats;
33
+ sending: SendingStats;
34
+ }) => void): void;
35
+ dispose(): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=AudioManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioManager.d.ts","sourceRoot":"","sources":["../../src/audio/AudioManager.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,sBAAsB,EAAuB,MAAM,UAAU,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzC,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAkB;IAGvC,OAAO,CAAC,mBAAmB,CAAC,CAAa;IACzC,OAAO,CAAC,sBAAsB,CAAC,CAAa;IAC5C,OAAO,CAAC,qBAAqB,CAAC,CAA6B;IAC3D,OAAO,CAAC,uBAAuB,CAAC,CAA+B;IAC/D,OAAO,CAAC,qBAAqB,CAAC,CAAgE;gBAElF,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,MAAmC;IAc3E,oBAAoB,IAAI,OAAO;IAO/B,OAAO,CAAC,cAAc;IA+ChB,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC7D,UAAU,IAAI,IAAI;IAQlB,UAAU,IAAI,OAAO;IAQrB,OAAO,IAAI,OAAO;IAOlB,WAAW,IAAI,OAAO;IAOtB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO/B,UAAU,IAAI,IAAI;IAOlB,QAAQ,IAAI;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,OAAO,EAAE,YAAY,CAAA;KAAE;IAUxD,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;IAIhC,cAAc,CAAC,QAAQ,EAAE,MAAM,IAAI;IAInC,aAAa,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI;IAIlD,eAAe,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;IAItD,aAAa,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,OAAO,EAAE,YAAY,CAAA;KAAE,KAAK,IAAI;IAO/E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}