{"version":3,"file":"index.js","names":[],"sources":["esm/platform/speech/index.js"],"sourcesContent":["import { Audio } from \"../audio\";\nfunction constructor() {\n  if (typeof window === \"undefined\") return void 0;\n  const browser = window;\n  return browser.SpeechRecognition ?? browser.webkitSpeechRecognition;\n}\nlet abortLatest;\nlet denied = false;\nasync function permissions(request) {\n  if (!constructor()) return { status: \"denied\", granted: false, canAskAgain: false };\n  const microphone = request ? await Audio.requestRecordingPermission() : await Audio.getRecordingPermissionStatus();\n  const status = denied || microphone === \"denied\" ? \"denied\" : microphone;\n  return { status, granted: status === \"granted\", canAskAgain: status !== \"denied\" };\n}\nfunction start(options, onEvent) {\n  if (typeof onEvent !== \"function\")\n    throw new TypeError(\"Speech.start: onEvent must be a function\");\n  const Recognizer = constructor();\n  if (!Recognizer) throw new Error(\"Speech.start needs an iOS or Android build\");\n  abortLatest?.();\n  const recognition = new Recognizer();\n  recognition.lang = options.lang ?? navigator.language;\n  recognition.continuous = true;\n  recognition.interimResults = true;\n  let active = true, transcript = \"\";\n  const emit = (event) => {\n    if (active) onEvent(event);\n  };\n  const terminal = (event) => {\n    if (!active) return;\n    active = false;\n    if (abortLatest === abort) abortLatest = void 0;\n    onEvent(event);\n  };\n  const abort = () => {\n    if (!active) return;\n    active = false;\n    if (abortLatest === abort) abortLatest = void 0;\n    recognition.abort();\n  };\n  abortLatest = abort;\n  recognition.addEventListener(\"start\", () => emit({ type: \"start\", transcript }));\n  recognition.addEventListener(\"result\", (event) => {\n    if (!active) return;\n    const results = event.results;\n    const text = Array.from(results).map((result) => result[0].transcript).join(\" \").trim();\n    if (text !== transcript) {\n      transcript = text;\n      emit({ type: \"transcript\", transcript });\n    }\n  });\n  recognition.addEventListener(\"end\", () => terminal({ type: \"end\", transcript }));\n  recognition.addEventListener(\"error\", (event) => {\n    const value = event;\n    if (value.error === \"no-speech\") {\n      terminal({ type: \"end\", transcript });\n      return;\n    }\n    const codes = {\n      \"not-allowed\": \"not-allowed\",\n      \"service-not-allowed\": \"service-not-allowed\",\n      \"language-not-supported\": \"language-not-supported\",\n      \"audio-capture\": \"audio-capture\",\n      aborted: \"interrupted\",\n      network: \"network\"\n    };\n    if (value.error === \"not-allowed\" || value.error === \"service-not-allowed\")\n      denied = true;\n    terminal({\n      type: \"error\",\n      transcript,\n      error: codes[value.error] ?? \"unknown\",\n      message: value.message\n    });\n  });\n  try {\n    recognition.start();\n  } catch (error) {\n    abort();\n    throw error;\n  }\n  return {\n    stop: () => {\n      if (active) recognition.stop();\n    },\n    abort\n  };\n}\nconst Speech = Object.freeze({\n  isAvailable: () => !!constructor(),\n  getPermissions: () => permissions(false),\n  requestPermissions: () => permissions(true),\n  start\n});\nexport {\n  Speech\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;AACA,SAAS,cAAc;CACrB,IAAI,OAAO,WAAW,aAAa,OAAO,KAAK;CAC/C,MAAM,UAAU;CAChB,OAAO,QAAQ,qBAAqB,QAAQ;AAC9C;AACA,IAAI;AACJ,IAAI,SAAS;AACb,eAAe,YAAY,SAAS;CAClC,IAAI,CAAC,YAAY,GAAG,OAAO;EAAE,QAAQ;EAAU,SAAS;EAAO,aAAa;CAAM;CAClF,MAAM,aAAa,UAAU,MAAM,MAAM,2BAA2B,IAAI,MAAM,MAAM,6BAA6B;CACjH,MAAM,SAAS,UAAU,eAAe,WAAW,WAAW;CAC9D,OAAO;EAAE;EAAQ,SAAS,WAAW;EAAW,aAAa,WAAW;CAAS;AACnF;AACA,SAAS,MAAM,SAAS,SAAS;CAC/B,IAAI,OAAO,YAAY,YACrB,MAAM,IAAI,UAAU,0CAA0C;CAChE,MAAM,aAAa,YAAY;CAC/B,IAAI,CAAC,YAAY,MAAM,IAAI,MAAM,4CAA4C;CAC7E,cAAc;CACd,MAAM,cAAc,IAAI,WAAW;CACnC,YAAY,OAAO,QAAQ,QAAQ,UAAU;CAC7C,YAAY,aAAa;CACzB,YAAY,iBAAiB;CAC7B,IAAI,SAAS,MAAM,aAAa;CAChC,MAAM,QAAQ,UAAU;EACtB,IAAI,QAAQ,QAAQ,KAAK;CAC3B;CACA,MAAM,YAAY,UAAU;EAC1B,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,IAAI,gBAAgB,OAAO,cAAc,KAAK;EAC9C,QAAQ,KAAK;CACf;CACA,MAAM,cAAc;EAClB,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,IAAI,gBAAgB,OAAO,cAAc,KAAK;EAC9C,YAAY,MAAM;CACpB;CACA,cAAc;CACd,YAAY,iBAAiB,eAAe,KAAK;EAAE,MAAM;EAAS;CAAW,CAAC,CAAC;CAC/E,YAAY,iBAAiB,WAAW,UAAU;EAChD,IAAI,CAAC,QAAQ;EACb,MAAM,UAAU,MAAM;EACtB,MAAM,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,WAAW,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;EACtF,IAAI,SAAS,YAAY;GACvB,aAAa;GACb,KAAK;IAAE,MAAM;IAAc;GAAW,CAAC;EACzC;CACF,CAAC;CACD,YAAY,iBAAiB,aAAa,SAAS;EAAE,MAAM;EAAO;CAAW,CAAC,CAAC;CAC/E,YAAY,iBAAiB,UAAU,UAAU;EAC/C,MAAM,QAAQ;EACd,IAAI,MAAM,UAAU,aAAa;GAC/B,SAAS;IAAE,MAAM;IAAO;GAAW,CAAC;GACpC;EACF;EACA,MAAM,QAAQ;GACZ,eAAe;GACf,uBAAuB;GACvB,0BAA0B;GAC1B,iBAAiB;GACjB,SAAS;GACT,SAAS;EACX;EACA,IAAI,MAAM,UAAU,iBAAiB,MAAM,UAAU,uBACnD,SAAS;EACX,SAAS;GACP,MAAM;GACN;GACA,OAAO,MAAM,MAAM,UAAU;GAC7B,SAAS,MAAM;EACjB,CAAC;CACH,CAAC;CACD,IAAI;EACF,YAAY,MAAM;CACpB,SAAS,OAAO;EACd,MAAM;EACN,MAAM;CACR;CACA,OAAO;EACL,YAAY;GACV,IAAI,QAAQ,YAAY,KAAK;EAC/B;EACA;CACF;AACF;AACA,MAAM,SAAS,OAAO,OAAO;CAC3B,mBAAmB,CAAC,CAAC,YAAY;CACjC,sBAAsB,YAAY,KAAK;CACvC,0BAA0B,YAAY,IAAI;CAC1C;AACF,CAAC"}