Refactored everything into modules.
This commit is contained in:
+40
-57
@@ -2,12 +2,12 @@
|
||||
* TTS Factory for AI Interactive Fiction
|
||||
* Attempts to use Kokoro TTS first, then falls back to browser TTS if needed
|
||||
*/
|
||||
import { kokoroHandler } from './kokoro-handler.js';
|
||||
import { browserTtsHandler } from './tts-handler.js';
|
||||
|
||||
class TTSFactory {
|
||||
export class TTSFactory {
|
||||
constructor() {
|
||||
this.activeTTSHandler = null;
|
||||
this.kokoroHandler = null;
|
||||
this.browserTTSHandler = null;
|
||||
this.initializationAttempted = false;
|
||||
this.usingKokoro = false;
|
||||
this.initializationPromise = null; // Promise for the factory initialization
|
||||
@@ -35,54 +35,36 @@ class TTSFactory {
|
||||
let kokoroInitialized = false;
|
||||
// Try to initialize Kokoro first (preferred option)
|
||||
try {
|
||||
// Check if KokoroHandler class is defined (loaded via script tag)
|
||||
if (typeof KokoroHandler !== 'undefined') {
|
||||
console.log('Attempting to initialize Kokoro TTS...');
|
||||
this.kokoroHandler = new KokoroHandler();
|
||||
|
||||
// --- Increase Timeout for Kokoro Initialization ---
|
||||
// Wait for KokoroHandler's internal initialization promise
|
||||
// Use Promise.race to add a longer timeout specifically for Kokoro init
|
||||
const kokoroTimeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Kokoro initialization timed out in factory')), 60000) // 60 seconds timeout
|
||||
);
|
||||
console.log('Attempting to initialize Kokoro TTS...');
|
||||
|
||||
// --- Increase Timeout for Kokoro Initialization ---
|
||||
// Wait for KokoroHandler's internal initialization promise
|
||||
// Use Promise.race to add a longer timeout specifically for Kokoro init
|
||||
const kokoroTimeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Kokoro initialization timed out in factory')), 60000) // 60 seconds timeout
|
||||
);
|
||||
|
||||
try {
|
||||
kokoroInitialized = await Promise.race([
|
||||
this.kokoroHandler.initializationPromise,
|
||||
kokoroTimeoutPromise
|
||||
]);
|
||||
} catch (timeoutError) {
|
||||
console.error(timeoutError.message); // Log the timeout error
|
||||
kokoroInitialized = false;
|
||||
}
|
||||
// --- End Increase Timeout ---
|
||||
|
||||
if (kokoroInitialized) {
|
||||
console.log('Kokoro Handler reported successful initialization.');
|
||||
} else {
|
||||
console.warn('Kokoro Handler reported failed or timed out initialization.');
|
||||
}
|
||||
try {
|
||||
kokoroInitialized = await Promise.race([
|
||||
kokoroHandler.initializationPromise,
|
||||
kokoroTimeoutPromise
|
||||
]);
|
||||
} catch (timeoutError) {
|
||||
console.error(timeoutError.message); // Log the timeout error
|
||||
kokoroInitialized = false;
|
||||
}
|
||||
// --- End Increase Timeout ---
|
||||
|
||||
if (kokoroInitialized) {
|
||||
console.log('Kokoro Handler reported successful initialization.');
|
||||
} else {
|
||||
console.warn('KokoroHandler class not found when factory initialized.');
|
||||
console.warn('Kokoro Handler reported failed or timed out initialization.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating or initializing Kokoro Handler:', error);
|
||||
console.error('Error initializing Kokoro Handler:', error);
|
||||
kokoroInitialized = false; // Ensure it's marked as failed
|
||||
}
|
||||
|
||||
// Initialize browser TTS as fallback (can happen in parallel)
|
||||
try {
|
||||
if (typeof TTSHandler !== 'undefined') {
|
||||
console.log('Initializing browser TTS as fallback...');
|
||||
this.browserTTSHandler = new TTSHandler();
|
||||
} else {
|
||||
console.warn('TTSHandler class not found when factory initialized.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing browser TTS:', error);
|
||||
}
|
||||
|
||||
// Decide which handler to use based on Kokoro's success
|
||||
this.selectActiveHandler(kokoroInitialized);
|
||||
resolve(); // Resolve the factory's promise
|
||||
@@ -91,23 +73,21 @@ class TTSFactory {
|
||||
return this.initializationPromise;
|
||||
}
|
||||
|
||||
// Removed waitForKokoroInitialization as KokoroHandler now manages its own promise
|
||||
|
||||
/**
|
||||
* Select which TTS handler to use
|
||||
* @param {boolean} kokoroInitialized - Whether Kokoro initialization succeeded
|
||||
*/
|
||||
selectActiveHandler(kokoroInitialized) {
|
||||
// First choice: Kokoro if it's available and initialized successfully
|
||||
if (kokoroInitialized && this.kokoroHandler && this.kokoroHandler.kokoroReady) {
|
||||
if (kokoroInitialized && kokoroHandler.kokoroReady) {
|
||||
console.log('Using Kokoro TTS as primary TTS system');
|
||||
this.activeTTSHandler = this.kokoroHandler;
|
||||
this.activeTTSHandler = kokoroHandler;
|
||||
this.usingKokoro = true;
|
||||
}
|
||||
// Fallback to browser TTS if available
|
||||
else if (this.browserTTSHandler) {
|
||||
else if (browserTtsHandler) {
|
||||
console.log('Falling back to browser TTS.');
|
||||
this.activeTTSHandler = this.browserTTSHandler;
|
||||
this.activeTTSHandler = browserTtsHandler;
|
||||
this.usingKokoro = false;
|
||||
}
|
||||
// No TTS available
|
||||
@@ -117,7 +97,7 @@ class TTSFactory {
|
||||
this.usingKokoro = false;
|
||||
}
|
||||
|
||||
// Expose the active handler as the global ttsHandler
|
||||
// Expose the active handler as the global ttsHandler for compatibility
|
||||
window.ttsHandler = this.activeTTSHandler;
|
||||
|
||||
// Log the active TTS system
|
||||
@@ -160,8 +140,8 @@ class TTSFactory {
|
||||
* @param {string} type - Either 'kokoro' or 'browser'
|
||||
*/
|
||||
switchTTS(type) {
|
||||
if (type === 'kokoro' && this.kokoroHandler && this.kokoroHandler.kokoroReady) {
|
||||
this.activeTTSHandler = this.kokoroHandler;
|
||||
if (type === 'kokoro' && kokoroHandler && kokoroHandler.kokoroReady) {
|
||||
this.activeTTSHandler = kokoroHandler;
|
||||
this.usingKokoro = true;
|
||||
window.ttsHandler = this.activeTTSHandler;
|
||||
console.log('Switched to Kokoro TTS');
|
||||
@@ -169,8 +149,8 @@ class TTSFactory {
|
||||
const ttsReadyEvent = new CustomEvent('tts-ready', { detail: { available: true, type: 'kokoro', handler: this.activeTTSHandler } });
|
||||
window.dispatchEvent(ttsReadyEvent);
|
||||
return true;
|
||||
} else if (type === 'browser' && this.browserTTSHandler) {
|
||||
this.activeTTSHandler = this.browserTTSHandler;
|
||||
} else if (type === 'browser' && browserTtsHandler) {
|
||||
this.activeTTSHandler = browserTtsHandler;
|
||||
this.usingKokoro = false;
|
||||
window.ttsHandler = this.activeTTSHandler;
|
||||
console.log('Switched to browser TTS');
|
||||
@@ -185,5 +165,8 @@ class TTSFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// Create the global TTS factory instance
|
||||
window.ttsFactory = new TTSFactory();
|
||||
// Create and export singleton instance
|
||||
export const ttsFactory = new TTSFactory();
|
||||
|
||||
// Keep a reference in window for compatibility with existing code
|
||||
window.ttsFactory = ttsFactory;
|
||||
Reference in New Issue
Block a user