149 lines
3.9 KiB
JavaScript
149 lines
3.9 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');
|
|
|
|
// Module state tracking - conform to BaseModule interface
|
|
this.state = 'PENDING';
|
|
}
|
|
|
|
/**
|
|
* 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 [];
|
|
}
|
|
|
|
/**
|
|
* Get the current module state
|
|
* @returns {string} - Current state
|
|
*/
|
|
getState() {
|
|
return this.state;
|
|
}
|
|
|
|
/**
|
|
* Change the module state
|
|
* @param {string} newState - The new state
|
|
*/
|
|
changeState(newState) {
|
|
this.state = newState;
|
|
|
|
// Dispatch state change event
|
|
this.dispatchEvent('state:changed', {
|
|
state: newState
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
});
|
|
}
|
|
}
|