// src/main/ipc/stt-handlers.ts import { ipcMain } from 'electron' import { IPC_CHANNELS } from '@d3ro/core/ipc-channels' import { ipcSuccess, ipcError, ErrorCode, D3ROError } from '@d3ro/core/errors' import { getLocalSTTService } from '../services/LocalSTTService' import { configGet, configSet } from '../services/ConfigService' import { getMainWindow } from '../windows/WindowManager' import type { SetSTTModelParams, SetSTTLanguageParams, DownloadModelParams, } from '@d3ro/core/types' function safeSendToRenderer(channel: string, data: unknown): void { const win = getMainWindow() if (win && !win.isDestroyed()) { win.webContents.send(channel, data) } } export function registerSTTHandlers(): void { // 다운로드 진행률 → 렌더러 getLocalSTTService().on('download-progress', (payload) => { safeSendToRenderer(IPC_CHANNELS.STT.DOWNLOAD_PROGRESS, payload) }) ipcMain.handle(IPC_CHANNELS.STT.GET_STATUS, async () => { try { const stt = getLocalSTTService() return ipcSuccess(stt.getStatus()) } catch (error) { const message = error instanceof Error ? error.message : String(error) return ipcError(ErrorCode.STTSidecarCommunicationFailed, `Failed to get STT status: ${message}`) } }) ipcMain.handle(IPC_CHANNELS.STT.GET_MODELS, async () => { try { const stt = getLocalSTTService() return ipcSuccess(await stt.getModels()) } catch (error) { const message = error instanceof Error ? error.message : String(error) return ipcError(ErrorCode.STTModelNotFound, `Failed to get models: ${message}`) } }) ipcMain.handle(IPC_CHANNELS.STT.GET_ACTIVE_MODEL, async () => { return ipcSuccess(configGet('sttModelId')) }) ipcMain.handle(IPC_CHANNELS.STT.SET_MODEL, async (_event, params: SetSTTModelParams) => { try { configSet('sttModelId', params.modelId) const stt = getLocalSTTService() await stt.initialize(params.modelId) return ipcSuccess(undefined) } catch (error) { const message = error instanceof Error ? error.message : String(error) return ipcError(ErrorCode.STTModelLoadFailed, `Failed to set STT model: ${message}`) } }) ipcMain.handle( IPC_CHANNELS.STT.DOWNLOAD_MODEL, async (_event, params: DownloadModelParams) => { try { await getLocalSTTService().downloadModel(params.modelId) return ipcSuccess(undefined) } catch (err) { if (err instanceof D3ROError) { return ipcError(err.code, err.message) } const msg = err instanceof Error ? err.message : String(err) return ipcError(ErrorCode.STTModelDownloadFailed, `Model download failed: ${msg}`) } }, ) ipcMain.handle(IPC_CHANNELS.STT.CANCEL_DOWNLOAD, async () => { await getLocalSTTService().cancelDownload() return ipcSuccess(undefined) }) ipcMain.handle(IPC_CHANNELS.STT.GET_LANGUAGE, async () => { return ipcSuccess(configGet('sttLanguage')) }) ipcMain.handle(IPC_CHANNELS.STT.SET_LANGUAGE, async (_event, params: SetSTTLanguageParams) => { configSet('sttLanguage', params.language) return ipcSuccess(undefined) }) }