fix(nexus): unblank assistant page on piper-tts import error
The usePiperTts hook imported a non-existent 'tts' namespace from
@mintplex-labs/piper-tts-web@1.0.4. The package exports named
functions (stored, download, predict, etc.) at the top level, not
under a tts namespace. The failing named-import threw at module-link
time, which crashed the lazy chunk for PersonalAssistant.tsx and
left /NEX/assistant blank with only a React error boundary fallback.
Two fixes in one file:
1. Import as namespace:
import * as tts from "@mintplex-labs/piper-tts-web"
ESM namespace imports synthesize a 'tts' object whose members are
the package's named exports, so the existing tts.stored() /
tts.download() / tts.predict() call sites bind to real functions
without touching the hook body.
2. Wrap predict() Blob result in URL.createObjectURL() before passing
to new Audio(). predict() returns Promise<Blob>, not a URL string,
and Audio() cannot accept a Blob directly. Added a shared cleanup
callback that revokes the object URL on onended/onerror and in the
catch path so we don't leak blob URLs on every speak invocation.
Bug 1 was the page-blanking crash at module load. Bug 2 was a latent
runtime crash behind the speak button click handler, surfaced while
the file was already being edited.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
43ca8d3047
commit
137bd3d0f6
1 changed files with 12 additions and 7 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useCallback, useRef } from "react";
|
||||
import { tts } from "@mintplex-labs/piper-tts-web";
|
||||
import * as tts from "@mintplex-labs/piper-tts-web";
|
||||
|
||||
const DEFAULT_VOICE = "en_US-hfc_female-medium";
|
||||
|
||||
|
|
@ -36,20 +36,25 @@ export function usePiperTts() {
|
|||
audioRef.current = null;
|
||||
}
|
||||
setStatus("speaking");
|
||||
let objectUrl: string | null = null;
|
||||
try {
|
||||
const wav = await tts.predict({ text, voiceId: DEFAULT_VOICE });
|
||||
const audio = new Audio(wav);
|
||||
objectUrl = URL.createObjectURL(wav);
|
||||
const audio = new Audio(objectUrl);
|
||||
audioRef.current = audio;
|
||||
audio.onended = () => {
|
||||
audioRef.current = null;
|
||||
setStatus("ready");
|
||||
};
|
||||
audio.onerror = () => {
|
||||
const cleanup = () => {
|
||||
audioRef.current = null;
|
||||
if (objectUrl) {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
objectUrl = null;
|
||||
}
|
||||
setStatus("ready");
|
||||
};
|
||||
audio.onended = cleanup;
|
||||
audio.onerror = cleanup;
|
||||
await audio.play();
|
||||
} catch {
|
||||
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
||||
setStatus("ready");
|
||||
}
|
||||
}, [status]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue