one
Version:
One is a React framework for web, iOS, and Android apps.
136 lines (135 loc) • 3.9 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var speech_exports = {};
__export(speech_exports, { Speech: () => Speech });
module.exports = __toCommonJS(speech_exports);
var import_audio = require("../audio/index.cjs");
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 import_audio.Audio.requestRecordingPermission() : await import_audio.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
});