Phase 1+2 구현: Electron 뼈대 + STT/핫키/오케스트레이터
Phase 1: - 프로젝트 초기화 (TypeScript strict, electron-vite, ESLint, Prettier) - shared 타입 (ipc-channels 113채널, types, errors, constants) - 메인 프로세스 뼈대 (bootstrap, lifecycle, 단일 인스턴스) - LoggerService, ConfigService (electron-store ESM dynamic import) - React 19 + MUI 7 Dashboard, 시스템 트레이 Phase 2: - AudioCaptureService (node-record-lpcm16, PCM16 16kHz mono) - HotkeyService (uiohook-napi, 더블프레스, holdMode/toggleMode) - LocalSTTService (faster-whisper Python sidecar, 이중 조건 플러시) - VoiceModeService 오케스트레이터 (이중 상태머신, Action Queue) - Python sidecar (FastAPI: health/load/transcribe/shutdown) - IPC 핸들러 (voice, stt, hotkey) + Preload API 확장
This commit is contained in:
parent
e24bb8378c
commit
1d152d01a1
46 changed files with 10828 additions and 4 deletions
78
src/main/bootstrap.ts
Normal file
78
src/main/bootstrap.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// src/main/bootstrap.ts — 초기화 시퀀스
|
||||
|
||||
import { app, dialog } from 'electron'
|
||||
import { initLoggerService, getLogger } from './services/LoggerService'
|
||||
import { initConfigService } from './services/ConfigService'
|
||||
import { getHotkeyService } from './services/HotkeyService'
|
||||
import { getVoiceModeService } from './services/VoiceModeService'
|
||||
import { createMainWindow } from './windows/WindowManager'
|
||||
import { createTray } from './windows/TrayManager'
|
||||
import { registerAllIpcHandlers } from './ipc'
|
||||
|
||||
const logger = getLogger('bootstrap')
|
||||
|
||||
interface BootstrapStep {
|
||||
name: string
|
||||
critical: boolean
|
||||
fn: () => Promise<void>
|
||||
}
|
||||
|
||||
export async function bootstrap(): Promise<void> {
|
||||
const steps: BootstrapStep[] = [
|
||||
{ name: 'logger', critical: false, fn: initLogger },
|
||||
{ name: 'config', critical: false, fn: initConfig },
|
||||
{ name: 'create-windows', critical: true, fn: createWindows },
|
||||
{ name: 'tray', critical: false, fn: initTray },
|
||||
{ name: 'ipc-handlers', critical: true, fn: initIpcHandlers },
|
||||
{ name: 'hotkey', critical: false, fn: initHotkey },
|
||||
{ name: 'voice-mode', critical: false, fn: initVoiceMode }
|
||||
]
|
||||
|
||||
for (const step of steps) {
|
||||
try {
|
||||
await step.fn()
|
||||
logger.info(`[bootstrap] ${step.name} initialized`)
|
||||
} catch (error) {
|
||||
logger.error(`[bootstrap] ${step.name} failed:`, error)
|
||||
if (step.critical) {
|
||||
dialog.showErrorBox(
|
||||
'D3RO-VOICE 초기화 실패',
|
||||
`${step.name}: ${error instanceof Error ? error.message : String(error)}`
|
||||
)
|
||||
app.quit()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function initLogger(): Promise<void> {
|
||||
initLoggerService()
|
||||
}
|
||||
|
||||
async function initConfig(): Promise<void> {
|
||||
initConfigService()
|
||||
}
|
||||
|
||||
async function createWindows(): Promise<void> {
|
||||
createMainWindow()
|
||||
}
|
||||
|
||||
async function initTray(): Promise<void> {
|
||||
createTray()
|
||||
}
|
||||
|
||||
async function initIpcHandlers(): Promise<void> {
|
||||
registerAllIpcHandlers()
|
||||
}
|
||||
|
||||
async function initHotkey(): Promise<void> {
|
||||
const hotkey = getHotkeyService()
|
||||
hotkey.loadFromConfig()
|
||||
hotkey.start()
|
||||
}
|
||||
|
||||
async function initVoiceMode(): Promise<void> {
|
||||
const voiceMode = getVoiceModeService()
|
||||
voiceMode.connectHotkey()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue