@sinhala-typer/voice-typing
v0.1.0
Published
A generic Web Speech API + Web Audio voice-typing wrapper: diffed text edits (not wholesale replacement) as recognition refines each utterance, plus a volume meter. Not Sinhala-specific - locale is fully configurable.
Maintainers
Readme
@sinhala-typer/voice-typing
A generic Web Speech API + Web Audio voice-typing wrapper. Not
Sinhala-specific — despite the package scope, lang is fully
caller-configurable and this has zero dependency on
@sinhala-typer/typing-engine
or any other package in this monorepo. It happens to ship alongside a
Sinhala typing tool; it isn't about Sinhala.
What it adds on top of the raw SpeechRecognition API:
- Diffed edits, not wholesale replacement. The Web Speech API repeatedly
re-reports a growing/refining transcript for the same utterance
(
"hell"→"hello"→"hello world"). This computes the minimal{ deleteCount, insertText }delta between what you last showed and the new transcript, so you never have to blindly delete-and-retype the whole phrase on every update. - A volume meter (
AnalyserNode-based, not the deprecatedScriptProcessorNode) for "is it hearing me" visual feedback — a second, independent microphone stream, sinceSpeechRecognitionexposes no way to observe its own internal audio capture. - A start-timeout safeguard. In some environments
recognition.start()returns normally but the browser never fires any event — notonstart, notonerror. Left alone this hangs a UI in "listening" forever; this package gives up and reports a clean error after 8 seconds if the browser never confirms it actually started. - Structured errors, not raw browser error strings.
Install
npm install @sinhala-typer/voice-typingUsage
import { createVoiceTyping } from "@sinhala-typer/voice-typing";
const voice = createVoiceTyping({
lang: "en-US", // defaults to "si-LK" if omitted
onEdit: (edit) => {
// apply edit.deleteCount / edit.insertText to your own text buffer,
// e.g. via @sinhala-typer/typing-engine-dom's TypingController.applyExternalEdit()
},
onStateChange: (state) => console.log(state), // "idle" | "listening"
onVolumeChange: (level) => console.log(level), // 0-1
onError: (error) => console.error(error.code, error.message),
});
if (voice.isSupported) {
voice.start();
// later:
voice.stop();
}Browser support
Requires SpeechRecognition/webkitSpeechRecognition. Chrome, Edge, and
Safari support it; Firefox has never shipped it — this is a real,
permanent platform gap, not something this package works around. Check
isSupported and hide/disable your UI accordingly rather than assuming it's
always available.
API
createVoiceTyping(options)→VoiceTypingControllerisSupported: booleanstart()/stop()
VoiceTypingOptions:lang?: string— BCP-47 locale, defaults to"si-LK".onEdit(edit: Edit)— required.Edit = { deleteCount: number; insertText: string }.onStateChange?(state: "idle" | "listening")onVolumeChange?(level: number)— 0-1, best-effort (silently omitted if the browser denies the metering microphone stream).onError?(error: VoiceTypingError)—VoiceTypingError.codeis one of"not-allowed" | "no-speech" | "audio-capture" | "unsupported" | "unknown".
License
MIT
