one
Version:
One is a React framework for web, iOS, and Android apps.
117 lines (114 loc) • 3.03 kB
JavaScript
import { Audio } from "../audio/index.mjs";
function constructor() {
if (typeof window === "undefined") return void 0;
const browser = window;
return browser.SpeechRecognition ?? browser.webkitSpeechRecognition;
}
let abortLatest;
let denied = false;
async function permissions(request) {
if (!constructor()) return {
status: "denied",
granted: false,
canAskAgain: false
};
const microphone = request ? await Audio.requestRecordingPermission() : await Audio.getRecordingPermissionStatus();
const status = denied || microphone === "denied" ? "denied" : microphone;
return {
status,
granted: status === "granted",
canAskAgain: status !== "denied"
};
}
function start(options, onEvent) {
if (typeof onEvent !== "function") throw new TypeError("Speech.start: onEvent must be a function");
const Recognizer = constructor();
if (!Recognizer) throw new Error("Speech.start needs an iOS or Android build");
abortLatest?.();
const recognition = new Recognizer();
recognition.lang = options.lang ?? navigator.language;
recognition.continuous = true;
recognition.interimResults = true;
let active = true, transcript = "";
const emit = (event) => {
if (active) onEvent(event);
};
const terminal = (event) => {
if (!active) return;
active = false;
if (abortLatest === abort) abortLatest = void 0;
onEvent(event);
};
const abort = () => {
if (!active) return;
active = false;
if (abortLatest === abort) abortLatest = void 0;
recognition.abort();
};
abortLatest = abort;
recognition.addEventListener("start", () => emit({
type: "start",
transcript
}));
recognition.addEventListener("result", (event) => {
if (!active) return;
const results = event.results;
const text = Array.from(results).map((result) => result[0].transcript).join(" ").trim();
if (text !== transcript) {
transcript = text;
emit({
type: "transcript",
transcript
});
}
});
recognition.addEventListener("end", () => terminal({
type: "end",
transcript
}));
recognition.addEventListener("error", (event) => {
const value = event;
if (value.error === "no-speech") {
terminal({
type: "end",
transcript
});
return;
}
const codes = {
"not-allowed": "not-allowed",
"service-not-allowed": "service-not-allowed",
"language-not-supported": "language-not-supported",
"audio-capture": "audio-capture",
aborted: "interrupted",
network: "network"
};
if (value.error === "not-allowed" || value.error === "service-not-allowed") denied = true;
terminal({
type: "error",
transcript,
error: codes[value.error] ?? "unknown",
message: value.message
});
});
try {
recognition.start();
} catch (error) {
abort();
throw error;
}
return {
stop: () => {
if (active) recognition.stop();
},
abort
};
}
const Speech = Object.freeze({
isAvailable: () => !!constructor(),
getPermissions: () => permissions(false),
requestPermissions: () => permissions(true),
start
});
export { Speech };
//# sourceMappingURL=index.mjs.map