{"version":3,"file":"voice-io.mjs","sources":["../src/constants.ts","../src/voice-io.ts"],"sourcesContent":["export const STATES = {\n  IDLE: 'IDLE',\n  LISTENING: 'LISTENING',\n  THINKING: 'THINKING',\n  RESPONDING: 'RESPONDING'\n} as const; ","import { STATES } from './constants';\nimport { VoiceIOState, VoiceIOConfig, SynthesisConfig, RecognitionConfig, RecognitionResult, LanguageInfo } from './types/voice-io';\nimport { SpeechRecognition, SpeechRecognitionEvent, SpeechRecognitionErrorEvent, SpeechRecognitionResult, SpeechSynthesisVoice, SpeechSynthesisErrorEvent } from './types/web-speech-api';\n\n// Add type assertion for SpeechRecognition\nconst SpeechRecognitionAPI = (window.SpeechRecognition || window.webkitSpeechRecognition) as typeof SpeechRecognition;\n\n/**\n * Default configuration for VoiceIO instance\n * @type {VoiceIOConfig}\n */\nconst DEFAULT_CONFIG: VoiceIOConfig = {\n  // Event handlers\n  onListenStart: undefined,\n  onListenEnd: undefined,\n  onRecognitionResult: undefined,\n  onVoiceStart: undefined,\n  onVoiceEnd: undefined,\n  onError: undefined,\n\n  // Synthesis settings\n  synthesis: {\n    pitch: 1,\n    rate: 1\n  },\n\n  // Recognition settings\n  recognition: {\n    continuous: true,\n    interimResults: true,\n    lang: 'en-US',\n    maxAlternatives: 3\n  },\n\n  // Add new callbacks\n  onLanguagesLoaded: undefined,\n  onVoicesLoaded: undefined,\n};\n\n/**\n * VoiceIO - A class to handle browser-based speech recognition and synthesis\n * @class\n * @throws {Error} If speech recognition or synthesis is not supported by the browser\n */\nexport class VoiceIO {\n  private readonly config: VoiceIOConfig;\n  private readonly states: typeof STATES = STATES;\n  private state: VoiceIOState = STATES.IDLE;\n  private recognizer!: SpeechRecognition;\n  private synthesizer!: SpeechSynthesis;\n  private recognitionResults: RecognitionResult[][] = [];\n  private accumulatedTranscript: string = '';\n  private selectedLanguage: string;\n  private selectedVoice: SpeechSynthesisVoice | null = null;\n  private voices: SpeechSynthesisVoice[] = [];\n  private voicesLoaded: boolean = false;\n  private readonly recognitionLanguages: LanguageInfo[] = [\n    { code: 'en-US', name: 'English' },\n    { code: 'es-ES', name: 'Español' },\n    { code: 'fr-FR', name: 'Français' },\n    { code: 'de-DE', name: 'Deutsch' },\n    { code: 'it-IT', name: 'Italiano' },\n    { code: 'ja-JP', name: '日本語' },\n    { code: 'ko-KR', name: '한국어' },\n    { code: 'zh-CN', name: '中文' }\n  ];\n\n  /**\n   * Creates a new VoiceIO instance\n   * @param {Partial<VoiceIOConfig>} config - Configuration options\n   * @param {(() => void)} [config.onListenStart] - Callback when speech recognition starts\n   * @param {(() => void)} [config.onListenEnd] - Callback when speech recognition ends\n   * @param {((results: RecognitionResult[][], bestTranscript: string, accumulatedTranscript: string) => void)} [config.onRecognitionResult] - Callback for speech recognition results\n   * @param {((utterance: SpeechSynthesisUtterance) => void)} [config.onVoiceStart] - Callback when speech synthesis starts\n   * @param {((utterance: SpeechSynthesisUtterance) => void)} [config.onVoiceEnd] - Callback when speech synthesis ends\n   * @param {((error: SpeechRecognitionErrorEvent | SpeechSynthesisErrorEvent) => void)} [config.onError] - Callback for error handling\n   * @param {((languages: LanguageInfo[]) => void)} [config.onLanguagesLoaded] - Callback when available languages are loaded\n   * @param {((voices: SpeechSynthesisVoice[]) => void)} [config.onVoicesLoaded] - Callback when available voices are loaded\n   */\n  constructor(config: Partial<VoiceIOConfig> = {}) {\n    // Check browser support first\n    if (!('SpeechRecognition' in window) && !('webkitSpeechRecognition' in window)) {\n      throw new Error('Speech recognition is not supported in this browser');\n    }\n    if (!('speechSynthesis' in window)) {\n      throw new Error('Speech synthesis is not supported in this browser');\n    }\n\n    // So these can be accessed directly without a separate import\n    this.states = STATES;\n    this.state = this.states.IDLE;\n\n    // Merge configs\n    this.config = {\n      ...DEFAULT_CONFIG,\n      synthesis: { ...DEFAULT_CONFIG.synthesis, ...config.synthesis },\n      recognition: { ...DEFAULT_CONFIG.recognition, ...config.recognition },\n      ...config\n    };\n\n    this.selectedLanguage = this.config.recognition!.lang!;\n\n    // Initialize recognizer first\n    this.initRecognizer();\n\n    // Initialize synthesizer and set up voice loading\n    this.synthesizer = window.speechSynthesis;\n\n    // Set up voice changed listener first\n    this.synthesizer.onvoiceschanged = () => {\n      this.voices = this.synthesizer.getVoices();\n      this.handleVoicesLoaded();\n    };\n\n    // Try loading voices immediately as well (for browsers that load synchronously)\n    this.voices = this.synthesizer.getVoices();\n    this.handleVoicesLoaded();\n\n    // Clean up on page unload\n    window.addEventListener('beforeunload', () => this.cleanup());\n  }\n\n  /**\n   * Initializes the speech recognition system\n   * @private\n   * @throws {Error} If speech recognition is not supported\n   */\n  private initRecognizer(): void {\n    if (!SpeechRecognitionAPI) {\n      throw new Error('Speech recognition not supported');\n    }\n    this.recognizer = new SpeechRecognitionAPI();\n    Object.assign(this.recognizer, this.config.recognition);\n\n    this.recognizer.onstart = () => {\n      this.config.onListenStart?.();\n    };\n\n    this.recognizer.onresult = (evt) => this.handleRecognitionResult(evt);\n\n    this.recognizer.onspeechend = () => {\n      this.recognizer.stop();\n    };\n\n    this.recognizer.onend = () => {\n      // Only call onListenEnd here, when recognition fully ends\n      this.config.onListenEnd?.();\n    };\n\n    this.recognizer.onerror = (error: SpeechRecognitionErrorEvent) => {\n      this.handleError(error, 'recognizer');\n    };\n  }\n\n  /**\n   * Handles the loading of speech synthesis voices\n   * @private\n   * Note: Some browsers (like Chrome) load voices asynchronously, which is why we need this handler\n   */\n  private handleVoicesLoaded(): void {\n    this.voicesLoaded = true;\n    \n    // Force refresh voices list\n    this.voices = this.synthesizer.getVoices();\n\n    // Get available languages based on available voices\n    const availableLanguages = this.getAvailableLanguages();\n\n    // Always notify about languages, even if empty\n    this.config.onLanguagesLoaded?.(availableLanguages);\n\n    if (availableLanguages.length > 0) {\n        // If no language selected or current language isn't available,\n        // select first available language\n        const currentLanguageIsValid = availableLanguages.some(\n            l => l.code === this.selectedLanguage\n        );\n\n        if (!this.selectedLanguage || !currentLanguageIsValid) {\n            // Select first available language\n            this.setLanguage(availableLanguages[0].code);\n        } else {\n            // Current language is valid, just update voices\n            const availableVoices = this.getVoicesForCurrentLanguage();\n            \n            // Select first voice if none selected\n            if (availableVoices.length > 0 && !this.selectedVoice) {\n                this.setVoice(availableVoices[0].name);\n            }\n            \n            // Always notify about voices for current language, even if empty\n            this.config.onVoicesLoaded?.(availableVoices);\n        }\n    } else {\n        // Notify with empty voices list if no languages available\n        this.config.onVoicesLoaded?.([]);\n    }\n  }\n\n  /**\n   * Processes speech recognition results\n   * @private\n   * @param {SpeechRecognitionEvent} evt - The recognition event\n   * Note: Accumulates final transcripts and manages recognition state\n   */\n  private handleRecognitionResult(evt: SpeechRecognitionEvent): void {\n    // Convert results to a more usable format\n    const results = Array.from(evt.results).map(resultArray => {\n      return Array.from(resultArray).map(result => ({\n        transcript: result.transcript,\n        confidence: result.confidence,\n        isFinal: resultArray.isFinal\n      }));\n    });\n\n    // Get the best transcript by taking highest confidence result from each group\n    const bestTranscript = results\n      .map(alternatives => alternatives.reduce((best, current) =>\n        current.confidence > best.confidence ? current : best\n      ))\n      .map(result => result.transcript)\n      .join(' ');\n\n    // Accumulate final transcripts\n    const lastResult = results[results.length - 1];\n    // Stop recognizing if we have final results\n    if (lastResult && lastResult[0].isFinal) {\n      this.accumulatedTranscript = (this.accumulatedTranscript + ' ' + bestTranscript).trim();\n      this.stopRecognizing();\n      // Use setState but skip cleanup since we just stopped recognizing\n      this.state = this.states.IDLE; // Directly set state to avoid cleanup\n    }\n\n    this.recognitionResults = results;\n    this.config.onRecognitionResult?.(results, bestTranscript, this.accumulatedTranscript);\n  }\n\n  /**\n   * Sets the state to IDLE and performs cleanup\n   * @private\n   * Note: Resets accumulated transcript when starting new session\n   */\n  private setIdle(): void {\n    this.cleanup();\n  }\n\n  /**\n   * Starts listening for speech input\n   * @private\n   * Note: Resets accumulated transcript when starting new session\n   */\n  private setListening(): void {\n    // If we're currently speaking, just stop that\n    // No need for full cleanup which would also stop recognition\n    if (this.state === STATES.RESPONDING) {\n      this.stopSpeaking();\n    } else {\n      this.cleanup();\n    }\n\n    this.accumulatedTranscript = ''; // Reset accumulated transcript when starting new session\n    this.recognizer.start();\n  }\n\n  /**\n   * Sets the state to THINKING (transitional state)\n   * @private\n   */\n  private setThinking(): void {\n    this.cleanup();\n  }\n\n  /**\n   * Initiates speech synthesis\n   * @private\n   * @param {string} text - The text to synthesize\n   */\n  private setSpeaking(text: string): void {\n    this.cleanup();\n    const utterance = new SpeechSynthesisUtterance(text);\n\n    // Apply config settings\n    Object.assign(utterance, this.config.synthesis);\n\n    // Set the voice and language\n    if (this.selectedVoice) {\n      utterance.voice = this.selectedVoice;\n      utterance.lang = this.selectedVoice.lang; // Use full language code from voice\n    } else {\n      utterance.lang = this.selectedLanguage;\n    }\n\n    // Add event handlers\n    utterance.onend = () => {\n      this.setState(STATES.IDLE);\n      this.config.onVoiceEnd?.(utterance);\n    };\n    utterance.onstart = () => {\n      this.config.onVoiceStart?.(utterance);\n    };\n    utterance.onerror = (error) => {\n      this.handleError(error, 'utterance');\n    };\n    this.synthesizer.speak(utterance);\n  }\n\n  /**\n   * Changes the current state of the VoiceIO instance\n   * @param {VoiceIOState} newState - The state to transition to\n   * @param {string} [textToSynthesize] - Text to speak when transitioning to RESPONDING state\n   * @throws {Error} If the state is invalid\n   */\n  setState(newState: VoiceIOState, textToSynthesize?: string): void {\n    // Don't do anything if state is invalid or same\n    if (!(newState in STATES)) {\n      throw new Error(`Invalid state: ${newState}`);\n    }\n    if (this.state === newState) {\n      return console.log('No Voice I/O state change');\n    }\n\n    // Update the state first\n    this.state = newState;\n\n    // Then handle the state change\n    switch (newState) {\n      case STATES.IDLE:\n        return this.setIdle();\n      case STATES.RESPONDING:\n        return this.setSpeaking(textToSynthesize!);\n      case STATES.LISTENING:\n        return this.setListening();\n      case STATES.THINKING:\n        return this.setThinking();\n    }\n  }\n\n  /**\n   * Handles errors from speech recognition or synthesis\n   * @private\n   * @param {SpeechRecognitionErrorEvent | SpeechSynthesisErrorEvent} error - The error that occurred\n   * @param {string} label - Label identifying the error source\n   */\n  private handleError(error: SpeechRecognitionErrorEvent | SpeechSynthesisErrorEvent, label: string): void {\n    console.info(`Voice I/O ${label} error`, error);\n    this.config.onError?.(error);\n    this.stopRecognizing();\n    this.setState(STATES.IDLE);\n  }\n\n  /**\n   * Stops the speech recognition process\n   * @private\n   */\n  private stopRecognizing(): void {\n    if (this.recognizer) {\n      try {\n        this.recognizer.stop();\n      } catch (err) {\n        console.warn('Error stopping recognition:', err);\n      }\n    }\n  }\n\n  /**\n   * Stops any ongoing speech synthesis\n   * @private\n   */\n  private stopSpeaking(): void {\n    if (this.synthesizer.speaking) {\n      this.synthesizer.cancel();\n    }\n  }\n\n  /**\n   * Performs cleanup of speech recognition and synthesis\n   * @public\n   */\n  cleanup(): void {\n    try {\n      this.stopSpeaking();\n      this.stopRecognizing();\n    } catch (err) {\n      this.handleError(err as SpeechRecognitionErrorEvent | SpeechSynthesisErrorEvent, \"cleanup\");\n    }\n  }\n\n  /**\n   * Gets all available speech synthesis voices\n   * @returns {SpeechSynthesisVoice[]} Array of available voices\n   */\n  getVoices(): SpeechSynthesisVoice[] {\n    return this.voices;\n  }\n\n  /**\n   * Gets the current state of the VoiceIO instance\n   * @returns {VoiceIOState} Current state from STATES enum\n   */\n  getState(): VoiceIOState {\n    return this.state;\n  }\n\n  /**\n   * Sets the language for both speech recognition and synthesis\n   * @param {string} languageCode - Language code (e.g., 'en-US')\n   * Note: Automatically selects the first available voice for the new language\n   */\n  setLanguage(languageCode: string): void {\n    this.selectedLanguage = languageCode;\n    this.config.recognition!.lang = languageCode;\n\n    // Get voices for new language\n    const availableVoices = this.getVoicesForCurrentLanguage();\n\n    // Reset voice selection\n    this.selectedVoice = null;\n    this.config!.synthesis!.voice = undefined;\n\n    // Always select first available voice for this language\n    if (availableVoices.length > 0) {\n      this.setVoice(availableVoices[0].name);\n    }\n\n    // Notify about available voices for this language\n    this.config.onVoicesLoaded?.(availableVoices);\n\n    // Reinitialize recognizer\n    this.initRecognizer();\n  }\n\n  /**\n   * Gets available voices for the currently selected language\n   * @private\n   * @returns {SpeechSynthesisVoice[]} Array of voices matching current language\n   * Note: Matches based on language prefix (e.g., 'en' for 'en-US')\n   */\n  private getVoicesForCurrentLanguage(): SpeechSynthesisVoice[] {\n    // Get language prefix (e.g., 'en' from 'en-US')\n    const currentLangPrefix = this.selectedLanguage.split('-')[0].toLowerCase();\n\n    return this.voices.filter(voice => {\n      const voiceLangPrefix = voice.lang.split('-')[0].toLowerCase();\n      return voiceLangPrefix === currentLangPrefix;\n    });\n  }\n\n  /**\n   * Sets the voice for speech synthesis\n   * @param {string} voiceName - Name of the voice to use\n   * Note: Only allows voices that match the current language\n   */\n  setVoice(voiceName: string): void {\n    const validVoices = this.getVoicesForCurrentLanguage();\n    const voice = validVoices.find(v => v.name === voiceName);\n    if (voice) {\n      this.selectedVoice = voice;\n      this.config.synthesis!.voice = voice;\n    } else {\n      console.warn('Selected voice is not available for current language');\n    }\n  }\n\n  /**\n   * Gets the currently selected language code\n   * @returns {string} Selected language code\n   */\n  getSelectedLanguage(): string {\n    return this.selectedLanguage;\n  }\n\n  /**\n   * Gets the currently selected voice\n   * @returns {SpeechSynthesisVoice|null} Selected voice or null if none selected\n   */\n  getSelectedVoice(): SpeechSynthesisVoice | null {\n    return this.selectedVoice;\n  }\n\n  /**\n   * Gets available languages that have both recognition and synthesis support\n   * @returns {Array<{code: string, name: string, prefix: string}>} Array of available languages\n   * Note: Only returns languages that have both recognition and synthesis support\n   */\n  getAvailableLanguages(): LanguageInfo[] {\n    // Ensure we have the latest voices list\n    const currentVoices = this.synthesizer.getVoices();\n    if (currentVoices.length > 0) {\n        this.voices = currentVoices;\n    }\n\n    if (!this.voices || this.voices.length === 0) {\n        return [];\n    }\n\n    // Get languages that have synthesis voices\n    const synthLanguages = new Set(\n        this.voices.map(voice => voice.lang.split('-')[0].toLowerCase())\n    );\n\n    // Filter recognition languages to only those that also have synthesis support\n    return this.recognitionLanguages\n        .filter(lang => {\n            const langPrefix = lang.code.split('-')[0].toLowerCase();\n            return synthLanguages.has(langPrefix);\n        })\n        .map(lang => ({\n            code: lang.code,\n            name: lang.name,\n            prefix: lang.code.split('-')[0].toLowerCase()\n        }));\n  }\n}"],"names":[],"mappings":"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"}