Files
ai.interactive.fiction/public/js/tts-handler.js
T

125 lines
3.3 KiB
JavaScript

/**
* TTS Handler Base Class
* Abstract base class defining the interface for all TTS handlers
*/
export class TTSHandler {
constructor() {
this.voiceOptions = {};
this.isReady = false;
// Set up event dispatcher
this.eventTarget = document.createElement('div');
}
/**
* Get handler ID
* @returns {string} - Handler identifier
*/
getId() {
throw new Error('getId() must be implemented by subclass');
}
/**
* Initialize the TTS handler
* @param {Function} progressCallback - Optional progress callback
* @returns {Promise<boolean>} - Resolves with success status
*/
async initialize(progressCallback = null) {
throw new Error('initialize() must be implemented by subclass');
}
/**
* Check if this TTS handler is available
* @returns {boolean} - True if handler is ready to use
*/
isAvailable() {
return this.isReady;
}
/**
* Check if voice is currently speaking
* @returns {boolean} - True if speaking
*/
isSpeaking() {
return false; // Default implementation
}
/**
* Speak text using this handler
* @param {string} text - The text to speak
* @param {Function} callback - Optional callback when speech completes
*/
speak(text, callback = null) {
throw new Error('speak() must be implemented by subclass');
}
/**
* Stop speech
*/
stop() {
throw new Error('stop() must be implemented by subclass');
}
/**
* Set voice options
* @param {Object} options - Voice options
*/
setVoiceOptions(options = {}) {
// Default implementation merges options
this.voiceOptions = { ...this.voiceOptions, ...options };
}
/**
* Get available voices
* @returns {Promise<Array>} - Resolves with array of voice objects
*/
async getVoices() {
return [];
}
/**
* Dispatch a custom event
* @param {string} eventName - Name of the event
* @param {Object} detail - Event details
*/
dispatchEvent(eventName, detail = {}) {
const event = new CustomEvent(eventName, {
detail: { handlerId: this.getId(), ...detail },
bubbles: true
});
this.eventTarget.dispatchEvent(event);
}
/**
* Add event listener
* @param {string} eventName - Name of the event
* @param {Function} callback - Event handler function
*/
addEventListener(eventName, callback) {
this.eventTarget.addEventListener(eventName, callback);
}
/**
* Remove event listener
* @param {string} eventName - Name of the event
* @param {Function} callback - Event handler function
*/
removeEventListener(eventName, callback) {
this.eventTarget.removeEventListener(eventName, callback);
}
/**
* Bind methods to this instance
* @param {Array<string>} methodNames - Array of method names to bind
*/
bindMethods(methodNames) {
if (!Array.isArray(methodNames)) return;
methodNames.forEach(methodName => {
if (typeof this[methodName] === 'function') {
this[methodName] = this[methodName].bind(this);
}
});
}
}