@runanywhere/core 0.17.2 → 0.17.3
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/package.json
CHANGED
|
@@ -8,11 +8,41 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Platform, PermissionsAndroid, NativeModules } from 'react-native';
|
|
11
|
-
import { EventBus } from '../../Public/Events';
|
|
12
11
|
import { SDKLogger } from '../../Foundation/Logging/Logger/SDKLogger';
|
|
13
12
|
|
|
14
13
|
const logger = new SDKLogger('AudioCaptureManager');
|
|
15
14
|
|
|
15
|
+
// Lazy-load EventBus to avoid circular dependency issues during module initialization
|
|
16
|
+
// The circular dependency: AudioCaptureManager -> EventBus -> SDKLogger -> ... -> AudioCaptureManager
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
let _eventBus: any = null;
|
|
19
|
+
function getEventBus() {
|
|
20
|
+
if (!_eventBus) {
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
_eventBus = require('../../Public/Events').EventBus;
|
|
24
|
+
} catch {
|
|
25
|
+
logger.warning('EventBus not available');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return _eventBus;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Safely publish an event to the EventBus
|
|
33
|
+
* Handles cases where EventBus may not be fully initialized
|
|
34
|
+
*/
|
|
35
|
+
function safePublish(eventType: string, event: Record<string, unknown>): void {
|
|
36
|
+
try {
|
|
37
|
+
const eventBus = getEventBus();
|
|
38
|
+
if (eventBus?.publish) {
|
|
39
|
+
eventBus.publish(eventType, event);
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// Ignore EventBus errors - events are non-critical for audio functionality
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
16
46
|
// Native iOS Audio Module (provided by the app)
|
|
17
47
|
const NativeAudioModule = Platform.OS === 'ios' ? NativeModules.NativeAudioModule : null;
|
|
18
48
|
|
|
@@ -156,7 +186,7 @@ export class AudioCaptureManager {
|
|
|
156
186
|
this.state = 'recording';
|
|
157
187
|
|
|
158
188
|
logger.info('Starting audio recording...');
|
|
159
|
-
|
|
189
|
+
safePublish('Voice', { type: 'recordingStarted' });
|
|
160
190
|
|
|
161
191
|
if (Platform.OS === 'ios') {
|
|
162
192
|
await this.startIOSRecording();
|
|
@@ -186,7 +216,7 @@ export class AudioCaptureManager {
|
|
|
186
216
|
path = await this.stopAndroidRecording();
|
|
187
217
|
}
|
|
188
218
|
|
|
189
|
-
|
|
219
|
+
safePublish('Voice', { type: 'recordingStopped', duration: durationMs / 1000 });
|
|
190
220
|
|
|
191
221
|
this.audioDataCallback = null;
|
|
192
222
|
this.recordingStartTime = null;
|
|
@@ -8,11 +8,26 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Platform, NativeModules } from 'react-native';
|
|
11
|
-
import { EventBus } from '../../Public/Events';
|
|
12
11
|
import { SDKLogger } from '../../Foundation/Logging/Logger/SDKLogger';
|
|
13
12
|
|
|
14
13
|
const logger = new SDKLogger('AudioPlaybackManager');
|
|
15
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Safely publish an event to the EventBus
|
|
17
|
+
* Uses lazy loading to avoid circular dependency issues during module initialization
|
|
18
|
+
*/
|
|
19
|
+
function safePublish(eventType: string, event: Record<string, unknown>): void {
|
|
20
|
+
try {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
22
|
+
const { EventBus } = require('../../Public/Events');
|
|
23
|
+
if (EventBus?.publish) {
|
|
24
|
+
EventBus.publish(eventType, event);
|
|
25
|
+
}
|
|
26
|
+
} catch {
|
|
27
|
+
// Ignore EventBus errors - events are non-critical for playback functionality
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
16
31
|
// Native iOS Audio Module
|
|
17
32
|
const NativeAudioModule = Platform.OS === 'ios' ? NativeModules.NativeAudioModule : null;
|
|
18
33
|
|
|
@@ -151,7 +166,7 @@ export class AudioPlaybackManager {
|
|
|
151
166
|
this.state = 'error';
|
|
152
167
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
153
168
|
logger.error(`Playback failed: ${err.message}`);
|
|
154
|
-
|
|
169
|
+
safePublish('Voice', { type: 'playbackFailed', error: err.message });
|
|
155
170
|
|
|
156
171
|
if (this.errorCallback) {
|
|
157
172
|
this.errorCallback(err);
|
|
@@ -168,7 +183,7 @@ export class AudioPlaybackManager {
|
|
|
168
183
|
this.state = 'playing';
|
|
169
184
|
|
|
170
185
|
logger.info(`Playing audio file: ${filePath}`);
|
|
171
|
-
|
|
186
|
+
safePublish('Voice', { type: 'playbackStarted' });
|
|
172
187
|
|
|
173
188
|
if (Platform.OS === 'ios') {
|
|
174
189
|
await this.playFileIOS(filePath);
|
|
@@ -196,7 +211,7 @@ export class AudioPlaybackManager {
|
|
|
196
211
|
this.currentSound = null;
|
|
197
212
|
}
|
|
198
213
|
|
|
199
|
-
|
|
214
|
+
safePublish('Voice', { type: 'playbackStopped' });
|
|
200
215
|
|
|
201
216
|
if (this.completionCallback) {
|
|
202
217
|
this.completionCallback();
|
|
@@ -217,7 +232,7 @@ export class AudioPlaybackManager {
|
|
|
217
232
|
}
|
|
218
233
|
|
|
219
234
|
logger.info('Playback paused');
|
|
220
|
-
|
|
235
|
+
safePublish('Voice', { type: 'playbackPaused' });
|
|
221
236
|
}
|
|
222
237
|
}
|
|
223
238
|
|
|
@@ -235,7 +250,7 @@ export class AudioPlaybackManager {
|
|
|
235
250
|
}
|
|
236
251
|
|
|
237
252
|
logger.info('Playback resumed');
|
|
238
|
-
|
|
253
|
+
safePublish('Voice', { type: 'playbackResumed' });
|
|
239
254
|
}
|
|
240
255
|
}
|
|
241
256
|
|
|
@@ -389,7 +404,7 @@ export class AudioPlaybackManager {
|
|
|
389
404
|
|
|
390
405
|
logger.info(`Playback completed (${duration.toFixed(2)}s)`);
|
|
391
406
|
|
|
392
|
-
|
|
407
|
+
safePublish('Voice', {
|
|
393
408
|
type: 'playbackCompleted',
|
|
394
409
|
duration,
|
|
395
410
|
});
|
|
@@ -28,9 +28,38 @@
|
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import { EventBus } from '../../Public/Events';
|
|
32
31
|
import { SDKLogger } from '../../Foundation/Logging/Logger/SDKLogger';
|
|
33
32
|
import { AudioCaptureManager } from './AudioCaptureManager';
|
|
33
|
+
|
|
34
|
+
// Lazy-load EventBus to avoid circular dependency issues during module initialization
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
let _eventBus: any = null;
|
|
37
|
+
function getEventBus() {
|
|
38
|
+
if (!_eventBus) {
|
|
39
|
+
try {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
41
|
+
_eventBus = require('../../Public/Events').EventBus;
|
|
42
|
+
} catch {
|
|
43
|
+
// EventBus not available
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return _eventBus;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Safely publish an event to the EventBus
|
|
51
|
+
* Handles cases where EventBus may not be fully initialized due to circular dependencies
|
|
52
|
+
*/
|
|
53
|
+
function safePublish(eventType: string, event: Record<string, unknown>): void {
|
|
54
|
+
try {
|
|
55
|
+
const eventBus = getEventBus();
|
|
56
|
+
if (eventBus?.publish) {
|
|
57
|
+
eventBus.publish(eventType, event);
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
// Ignore EventBus errors - events are non-critical for voice session functionality
|
|
61
|
+
}
|
|
62
|
+
}
|
|
34
63
|
import { AudioPlaybackManager } from './AudioPlaybackManager';
|
|
35
64
|
import * as STT from '../../Public/Extensions/RunAnywhere+STT';
|
|
36
65
|
import * as TextGeneration from '../../Public/Extensions/RunAnywhere+TextGeneration';
|
|
@@ -390,31 +419,31 @@ export class VoiceSessionHandle {
|
|
|
390
419
|
|
|
391
420
|
switch (eventBusType) {
|
|
392
421
|
case 'voiceSession_started':
|
|
393
|
-
|
|
422
|
+
safePublish('Voice', { type: 'voiceSession_started' });
|
|
394
423
|
break;
|
|
395
424
|
case 'voiceSession_listening':
|
|
396
|
-
|
|
425
|
+
safePublish('Voice', { type: 'voiceSession_listening', audioLevel: eventData.audioLevel });
|
|
397
426
|
break;
|
|
398
427
|
case 'voiceSession_speechStarted':
|
|
399
|
-
|
|
428
|
+
safePublish('Voice', { type: 'voiceSession_speechStarted' });
|
|
400
429
|
break;
|
|
401
430
|
case 'voiceSession_speechEnded':
|
|
402
|
-
|
|
431
|
+
safePublish('Voice', { type: 'voiceSession_speechEnded' });
|
|
403
432
|
break;
|
|
404
433
|
case 'voiceSession_processing':
|
|
405
|
-
|
|
434
|
+
safePublish('Voice', { type: 'voiceSession_processing' });
|
|
406
435
|
break;
|
|
407
436
|
case 'voiceSession_transcribed':
|
|
408
|
-
|
|
437
|
+
safePublish('Voice', { type: 'voiceSession_transcribed', transcription: eventData.transcription });
|
|
409
438
|
break;
|
|
410
439
|
case 'voiceSession_responded':
|
|
411
|
-
|
|
440
|
+
safePublish('Voice', { type: 'voiceSession_responded', response: eventData.response });
|
|
412
441
|
break;
|
|
413
442
|
case 'voiceSession_speaking':
|
|
414
|
-
|
|
443
|
+
safePublish('Voice', { type: 'voiceSession_speaking' });
|
|
415
444
|
break;
|
|
416
445
|
case 'voiceSession_turnCompleted':
|
|
417
|
-
|
|
446
|
+
safePublish('Voice', {
|
|
418
447
|
type: 'voiceSession_turnCompleted',
|
|
419
448
|
transcription: eventData.transcription,
|
|
420
449
|
response: eventData.response,
|
|
@@ -422,10 +451,10 @@ export class VoiceSessionHandle {
|
|
|
422
451
|
});
|
|
423
452
|
break;
|
|
424
453
|
case 'voiceSession_stopped':
|
|
425
|
-
|
|
454
|
+
safePublish('Voice', { type: 'voiceSession_stopped' });
|
|
426
455
|
break;
|
|
427
456
|
case 'voiceSession_error':
|
|
428
|
-
|
|
457
|
+
safePublish('Voice', { type: 'voiceSession_error', error: eventData.error });
|
|
429
458
|
break;
|
|
430
459
|
}
|
|
431
460
|
}
|