import { trimTrailingSlash } from '../../utils/common'; // Denoise assets copied into public/element-call/denoise/ by vite.config.js's // lotusDenoise() plugin. The filenames here MUST match what that plugin writes // (and what the fork's TrackProcessor fetches at runtime). Grouped per model so // the smoke-check only probes what the active call will actually load. const DENOISE_ASSETS: Record = { rnnoise: ['rnnoiseWorklet.js', 'rnnoise.wasm', 'rnnoise_simd.wasm'], speex: ['speexWorklet.js', 'speex.wasm'], dtln: ['workadventure/audio-worklet.js'], deepfilternet: [ 'deepfilternet/index.esm.js', 'deepfilternet/v2/pkg/df_bg.wasm', 'deepfilternet/v2/models/DeepFilterNet3_onnx.tar.gz', ], }; // The noise-gate worklet is a shared asset the build ships for every model // (loaded when the gate is enabled), so probe it regardless of the model. const SHARED_ASSETS: readonly string[] = ['noiseGateWorklet.js']; /** * Fire-and-forget smoke-check for the ML-denoise asset contract. * * The fork's in-source denoiser (lotusDenoiseSource) loads its worklet/wasm/ESM * from `public/element-call/denoise/` at runtime; if the build's asset copy * step regressed, those fetches 404 and denoise silently degrades to a raw mic. * This HEAD-fetches the critical assets for the selected model and emits a * single console.warn listing any that are missing. No UI, no throw — purely a * developer/operator breadcrumb. * * @param model the selected denoise model (defaults to rnnoise) * @returns true if every probed asset responded OK, false otherwise */ export async function verifyDenoiseAssets(model = 'rnnoise'): Promise { const base = new URL( `${trimTrailingSlash(import.meta.env.BASE_URL)}/public/element-call/denoise/`, window.location.origin, ); const names = [...(DENOISE_ASSETS[model] ?? DENOISE_ASSETS.rnnoise), ...SHARED_ASSETS]; const results = await Promise.all( names.map(async (name): Promise => { try { const res = await fetch(new URL(name, base).href, { method: 'HEAD' }); return res.ok ? null : name; } catch { return name; } }), ); const missing = results.filter((n): n is string => n !== null); if (missing.length > 0) { console.warn( `[lotus-denoise] ML denoise assets missing under ${base.href} (model="${model}"): ${missing.join( ', ', )} — the in-source denoiser will fall back to a raw mic. Check vite.config.js lotusDenoise().`, ); return false; } return true; }