72018aa389
Configures vite-plugin-static-copy to serve @ricky0123/vad-web's ONNX model, audio worklet, and onnxruntime-web WASM files from the site root. useOnnxPreloader warms the model cache during page idle so the first mic click is instant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import { ref, readonly } from 'vue'
|
|
|
|
/**
|
|
* Idle-preload the Silero VAD ONNX model and its companion assets.
|
|
*
|
|
* `@ricky0123/vad-web` pulls ~2MB of ONNX model + ~5MB of onnxruntime-web
|
|
* WASM the first time `MicVAD.new()` runs. Calling `defaultModelFetcher`
|
|
* during page idle warms the browser cache so the first mic click feels
|
|
* instant. If the preload fails, VAD simply loads lazily on first click.
|
|
*/
|
|
const ready = ref(false)
|
|
let loading = false
|
|
|
|
export function useOnnxPreloader() {
|
|
async function preload() {
|
|
if (ready.value || loading) return
|
|
loading = true
|
|
try {
|
|
const { defaultModelFetcher } = await import('@ricky0123/vad-web')
|
|
// Asset lives at site root because vite-plugin-static-copy drops it
|
|
// there. Match whatever path MicVAD will use at call time (see useVad).
|
|
await defaultModelFetcher('/silero_vad_v5.onnx')
|
|
ready.value = true
|
|
} catch {
|
|
// Non-fatal — MicVAD will load the model itself on first use.
|
|
} finally {
|
|
loading = false
|
|
}
|
|
}
|
|
|
|
function schedulePreload() {
|
|
if (ready.value) return
|
|
if (typeof window === 'undefined') return
|
|
if ('requestIdleCallback' in window) {
|
|
(window as Window & { requestIdleCallback: (cb: () => void, opts: { timeout: number }) => void })
|
|
.requestIdleCallback(() => void preload(), { timeout: 5000 })
|
|
} else {
|
|
setTimeout(() => void preload(), 5000)
|
|
}
|
|
}
|
|
|
|
return { ready: readonly(ready), schedulePreload }
|
|
}
|