1import { SyntheticPlatformEmitter, CodedError } from 'expo-modules-core';
2import { VoiceQuality } from './Speech.types';
3//https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text
4const MAX_SPEECH_INPUT_LENGTH = 32767;
5async function getVoices() {
6    return new Promise((resolve) => {
7        const voices = window.speechSynthesis.getVoices();
8        if (voices.length > 0) {
9            resolve(voices);
10            return;
11        }
12        // when a page loads it takes some amount of time to populate the voices list
13        // see https://stackoverflow.com/a/52005323/4337317
14        window.speechSynthesis.onvoiceschanged = function () {
15            const voices = window.speechSynthesis.getVoices();
16            resolve(voices);
17        };
18    });
19}
20export default {
21    get name() {
22        return 'ExponentSpeech';
23    },
24    async speak(id, text, options) {
25        if (text.length > MAX_SPEECH_INPUT_LENGTH) {
26            throw new CodedError('ERR_SPEECH_INPUT_LENGTH', 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH);
27        }
28        const message = new SpeechSynthesisUtterance();
29        if (typeof options.rate === 'number') {
30            message.rate = options.rate;
31        }
32        if (typeof options.pitch === 'number') {
33            message.pitch = options.pitch;
34        }
35        if (typeof options.language === 'string') {
36            message.lang = options.language;
37        }
38        if (typeof options.volume === 'number') {
39            message.volume = options.volume;
40        }
41        if ('_voiceIndex' in options && options._voiceIndex != null) {
42            const voices = await getVoices();
43            message.voice = voices[Math.min(voices.length - 1, Math.max(0, options._voiceIndex))];
44        }
45        if (typeof options.voice === 'string') {
46            const voices = await getVoices();
47            message.voice =
48                voices[Math.max(0, voices.findIndex((voice) => voice.voiceURI === options.voice))];
49        }
50        if (typeof options.onResume === 'function') {
51            message.onresume = options.onResume;
52        }
53        if (typeof options.onMark === 'function') {
54            message.onmark = options.onMark;
55        }
56        if (typeof options.onBoundary === 'function') {
57            message.onboundary = options.onBoundary;
58        }
59        message.onstart = (nativeEvent) => {
60            SyntheticPlatformEmitter.emit('Exponent.speakingStarted', { id, nativeEvent });
61        };
62        message.onend = (nativeEvent) => {
63            SyntheticPlatformEmitter.emit('Exponent.speakingDone', { id, nativeEvent });
64        };
65        message.onpause = (nativeEvent) => {
66            SyntheticPlatformEmitter.emit('Exponent.speakingStopped', { id, nativeEvent });
67        };
68        message.onerror = (nativeEvent) => {
69            SyntheticPlatformEmitter.emit('Exponent.speakingError', { id, nativeEvent });
70        };
71        message.text = text;
72        window.speechSynthesis.speak(message);
73        return message;
74    },
75    async getVoices() {
76        const voices = await getVoices();
77        return voices.map((voice) => ({
78            identifier: voice.voiceURI,
79            quality: VoiceQuality.Default,
80            isDefault: voice.default,
81            language: voice.lang,
82            localService: voice.localService,
83            name: voice.name,
84            voiceURI: voice.voiceURI,
85        }));
86    },
87    async isSpeaking() {
88        return window.speechSynthesis.speaking;
89    },
90    async stop() {
91        return window.speechSynthesis.cancel();
92    },
93    async pause() {
94        return window.speechSynthesis.pause();
95    },
96    async resume() {
97        return window.speechSynthesis.resume();
98    },
99    maxSpeechInputLength: MAX_SPEECH_INPUT_LENGTH,
100};
101//# sourceMappingURL=ExponentSpeech.web.js.map