UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

136 lines (135 loc) • 3.9 kB
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 });