Jelajahi Sumber

fix: fall back when voice native module is missing

paoloanzn 2 bulan lalu
induk
melakukan
26d7bcc4a8
1 mengubah file dengan 36 tambahan dan 8 penghapusan
  1. 36 8
      src/services/voice.ts

+ 36 - 8
src/services/voice.ts

@@ -17,20 +17,48 @@ import { getPlatform } from '../utils/platform.js'
 // (post-wake, post-boot). Load happens on first voice keypress — no
 // preload, because there's no way to make dlopen non-blocking and a
 // startup freeze is worse than a first-press delay.
-type AudioNapi = typeof import('audio-capture-napi')
+type AudioNapi = {
+  isNativeAudioAvailable(): boolean
+  isNativeRecordingActive(): boolean
+  startNativeRecording(
+    onData: (data: Buffer) => void,
+    onEnd: () => void,
+  ): boolean
+  stopNativeRecording(): void
+}
+
+const unavailableAudioNapi: AudioNapi = {
+  isNativeAudioAvailable: () => false,
+  isNativeRecordingActive: () => false,
+  startNativeRecording: () => false,
+  stopNativeRecording: () => {},
+}
+
 let audioNapi: AudioNapi | null = null
 let audioNapiPromise: Promise<AudioNapi> | null = null
 
 function loadAudioNapi(): Promise<AudioNapi> {
   audioNapiPromise ??= (async () => {
     const t0 = Date.now()
-    const mod = await import('audio-capture-napi')
-    // vendor/audio-capture-src/index.ts defers require(...node) until the
-    // first function call — trigger it here so timing reflects real cost.
-    mod.isNativeAudioAvailable()
-    audioNapi = mod
-    logForDebugging(`[voice] audio-capture-napi loaded in ${Date.now() - t0}ms`)
-    return mod
+    try {
+      const mod = (await import('audio-capture-napi')) as AudioNapi
+      // vendor/audio-capture-src/index.ts defers require(...node) until the
+      // first function call — trigger it here so timing reflects real cost.
+      mod.isNativeAudioAvailable()
+      audioNapi = mod
+      logForDebugging(
+        `[voice] audio-capture-napi loaded in ${Date.now() - t0}ms`,
+      )
+      return mod
+    } catch (error) {
+      const message =
+        error instanceof Error ? error.message : 'unknown load error'
+      audioNapi = unavailableAudioNapi
+      logForDebugging(
+        `[voice] audio-capture-napi unavailable, falling back: ${message}`,
+      )
+      return unavailableAudioNapi
+    }
   })()
   return audioNapiPromise
 }