expo-speech 13.0.0-canary-20240814-ce0f7d5 → 13.0.0-canary-20240912-1059f85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -14,6 +14,8 @@
14
14
 
15
15
  ### 💡 Others
16
16
 
17
+ - [Web] Change module registration. ([#29870](https://github.com/expo/expo/pull/29870) by [@aleqsio](https://github.com/aleqsio))
18
+
17
19
  ## 12.0.2 — 2024-05-09
18
20
 
19
21
  ### 🐛 Bug fixes
@@ -1,5 +1,24 @@
1
+ import { NativeModule } from 'expo-modules-core';
1
2
  import { SpeechOptions, WebVoice } from './Speech.types';
2
- declare const _default: {
3
+ type ExpoSpeechEvents = {
4
+ 'Exponent.speakingStarted': (params: {
5
+ id: string;
6
+ nativeEvent: SpeechSynthesisEvent;
7
+ }) => void;
8
+ 'Exponent.speakingDone': (params: {
9
+ id: string;
10
+ nativeEvent: SpeechSynthesisEvent;
11
+ }) => void;
12
+ 'Exponent.speakingStopped': (params: {
13
+ id: string;
14
+ nativeEvent: SpeechSynthesisEvent;
15
+ }) => void;
16
+ 'Exponent.speakingError': (params: {
17
+ id: string;
18
+ nativeEvent: SpeechSynthesisEvent;
19
+ }) => void;
20
+ };
21
+ declare class ExpoSpeech extends NativeModule<ExpoSpeechEvents> {
3
22
  speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance>;
4
23
  getVoices(): Promise<WebVoice[]>;
5
24
  isSpeaking(): Promise<boolean>;
@@ -7,6 +26,7 @@ declare const _default: {
7
26
  pause(): Promise<void>;
8
27
  resume(): Promise<void>;
9
28
  maxSpeechInputLength: number;
10
- };
29
+ }
30
+ declare const _default: typeof ExpoSpeech;
11
31
  export default _default;
12
32
  //# sourceMappingURL=ExponentSpeech.web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExponentSpeech.web.d.ts","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;;cAwBrD,MAAM,QAAQ,MAAM,WAAW,aAAa,GAAG,QAAQ,wBAAwB,CAAC;iBAiE7E,QAAQ,QAAQ,EAAE,CAAC;kBAYlB,QAAQ,OAAO,CAAC;YAGtB,QAAQ,IAAI,CAAC;aAGZ,QAAQ,IAAI,CAAC;cAGZ,QAAQ,IAAI,CAAC;;;AAvF/B,wBA2FG"}
1
+ {"version":3,"file":"ExponentSpeech.web.d.ts","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;AAuBvE,KAAK,gBAAgB,GAAG;IACtB,0BAA0B,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,CAAC;IAChG,uBAAuB,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7F,0BAA0B,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,CAAC;IAChG,wBAAwB,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/F,CAAC;AAEF,cAAM,UAAW,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAC/C,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAiE1F,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYhC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAG9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAGrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAGtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAG7B,oBAAoB,SAA2B;CAChD;;AAED,wBAA6C"}
@@ -1,4 +1,4 @@
1
- import { CodedError, createWebModule } from 'expo-modules-core';
1
+ import { CodedError, NativeModule, registerWebModule } from 'expo-modules-core';
2
2
  import { VoiceQuality } from './Speech.types';
3
3
  //https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text
4
4
  const MAX_SPEECH_INPUT_LENGTH = 32767;
@@ -17,7 +17,7 @@ async function getVoices() {
17
17
  };
18
18
  });
19
19
  }
20
- export default createWebModule({
20
+ class ExpoSpeech extends NativeModule {
21
21
  async speak(id, text, options) {
22
22
  if (text.length > MAX_SPEECH_INPUT_LENGTH) {
23
23
  throw new CodedError('ERR_SPEECH_INPUT_LENGTH', 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH);
@@ -68,7 +68,7 @@ export default createWebModule({
68
68
  message.text = text;
69
69
  window.speechSynthesis.speak(message);
70
70
  return message;
71
- },
71
+ }
72
72
  async getVoices() {
73
73
  const voices = await getVoices();
74
74
  return voices.map((voice) => ({
@@ -80,19 +80,20 @@ export default createWebModule({
80
80
  name: voice.name,
81
81
  voiceURI: voice.voiceURI,
82
82
  }));
83
- },
83
+ }
84
84
  async isSpeaking() {
85
85
  return window.speechSynthesis.speaking;
86
- },
86
+ }
87
87
  async stop() {
88
88
  return window.speechSynthesis.cancel();
89
- },
89
+ }
90
90
  async pause() {
91
91
  return window.speechSynthesis.pause();
92
- },
92
+ }
93
93
  async resume() {
94
94
  return window.speechSynthesis.resume();
95
- },
96
- maxSpeechInputLength: MAX_SPEECH_INPUT_LENGTH,
97
- });
95
+ }
96
+ maxSpeechInputLength = MAX_SPEECH_INPUT_LENGTH;
97
+ }
98
+ export default registerWebModule(ExpoSpeech);
98
99
  //# sourceMappingURL=ExponentSpeech.web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExponentSpeech.web.js","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, createWebModule } from 'expo-modules-core';\n\nimport { SpeechOptions, WebVoice, VoiceQuality } from './Speech.types';\n\n//https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text\nconst MAX_SPEECH_INPUT_LENGTH = 32767;\n\nasync function getVoices(): Promise<SpeechSynthesisVoice[]> {\n return new Promise<SpeechSynthesisVoice[]>((resolve) => {\n const voices = window.speechSynthesis.getVoices();\n\n if (voices.length > 0) {\n resolve(voices);\n return;\n }\n\n // when a page loads it takes some amount of time to populate the voices list\n // see https://stackoverflow.com/a/52005323/4337317\n window.speechSynthesis.onvoiceschanged = function () {\n const voices = window.speechSynthesis.getVoices();\n resolve(voices);\n };\n });\n}\n\nexport default createWebModule({\n async speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance> {\n if (text.length > MAX_SPEECH_INPUT_LENGTH) {\n throw new CodedError(\n 'ERR_SPEECH_INPUT_LENGTH',\n 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH\n );\n }\n\n const message = new SpeechSynthesisUtterance();\n\n if (typeof options.rate === 'number') {\n message.rate = options.rate;\n }\n if (typeof options.pitch === 'number') {\n message.pitch = options.pitch;\n }\n if (typeof options.language === 'string') {\n message.lang = options.language;\n }\n if (typeof options.volume === 'number') {\n message.volume = options.volume;\n }\n if ('_voiceIndex' in options && options._voiceIndex != null) {\n const voices = await getVoices();\n message.voice = voices[Math.min(voices.length - 1, Math.max(0, options._voiceIndex))];\n }\n if (typeof options.voice === 'string') {\n const voices = await getVoices();\n message.voice =\n voices[\n Math.max(\n 0,\n voices.findIndex((voice) => voice.voiceURI === options.voice)\n )\n ];\n }\n if (typeof options.onResume === 'function') {\n message.onresume = options.onResume;\n }\n if (typeof options.onMark === 'function') {\n message.onmark = options.onMark;\n }\n if (typeof options.onBoundary === 'function') {\n message.onboundary = options.onBoundary;\n }\n\n message.onstart = (nativeEvent: SpeechSynthesisEvent) => {\n (this as any).emit('Exponent.speakingStarted', { id, nativeEvent });\n };\n message.onend = (nativeEvent: SpeechSynthesisEvent) => {\n (this as any).emit('Exponent.speakingDone', { id, nativeEvent });\n };\n message.onpause = (nativeEvent: SpeechSynthesisEvent) => {\n (this as any).emit('Exponent.speakingStopped', { id, nativeEvent });\n };\n message.onerror = (nativeEvent: SpeechSynthesisErrorEvent) => {\n (this as any).emit('Exponent.speakingError', { id, nativeEvent });\n };\n\n message.text = text;\n\n window.speechSynthesis.speak(message);\n\n return message;\n },\n async getVoices(): Promise<WebVoice[]> {\n const voices = await getVoices();\n return voices.map((voice) => ({\n identifier: voice.voiceURI,\n quality: VoiceQuality.Default,\n isDefault: voice.default,\n language: voice.lang,\n localService: voice.localService,\n name: voice.name,\n voiceURI: voice.voiceURI,\n }));\n },\n async isSpeaking(): Promise<boolean> {\n return window.speechSynthesis.speaking;\n },\n async stop(): Promise<void> {\n return window.speechSynthesis.cancel();\n },\n async pause(): Promise<void> {\n return window.speechSynthesis.pause();\n },\n async resume(): Promise<void> {\n return window.speechSynthesis.resume();\n },\n maxSpeechInputLength: MAX_SPEECH_INPUT_LENGTH,\n});\n"]}
1
+ {"version":3,"file":"ExponentSpeech.web.js","sourceRoot":"","sources":["../src/Speech/ExponentSpeech.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, NativeModule, registerWebModule } from 'expo-modules-core';\n\nimport { SpeechOptions, WebVoice, VoiceQuality } from './Speech.types';\n\n//https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/text\nconst MAX_SPEECH_INPUT_LENGTH = 32767;\n\nasync function getVoices(): Promise<SpeechSynthesisVoice[]> {\n return new Promise<SpeechSynthesisVoice[]>((resolve) => {\n const voices = window.speechSynthesis.getVoices();\n\n if (voices.length > 0) {\n resolve(voices);\n return;\n }\n\n // when a page loads it takes some amount of time to populate the voices list\n // see https://stackoverflow.com/a/52005323/4337317\n window.speechSynthesis.onvoiceschanged = function () {\n const voices = window.speechSynthesis.getVoices();\n resolve(voices);\n };\n });\n}\n\ntype ExpoSpeechEvents = {\n 'Exponent.speakingStarted': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;\n 'Exponent.speakingDone': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;\n 'Exponent.speakingStopped': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;\n 'Exponent.speakingError': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;\n};\n\nclass ExpoSpeech extends NativeModule<ExpoSpeechEvents> {\n async speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance> {\n if (text.length > MAX_SPEECH_INPUT_LENGTH) {\n throw new CodedError(\n 'ERR_SPEECH_INPUT_LENGTH',\n 'Speech input text is too long! Limit of input length is: ' + MAX_SPEECH_INPUT_LENGTH\n );\n }\n\n const message = new SpeechSynthesisUtterance();\n\n if (typeof options.rate === 'number') {\n message.rate = options.rate;\n }\n if (typeof options.pitch === 'number') {\n message.pitch = options.pitch;\n }\n if (typeof options.language === 'string') {\n message.lang = options.language;\n }\n if (typeof options.volume === 'number') {\n message.volume = options.volume;\n }\n if ('_voiceIndex' in options && options._voiceIndex != null) {\n const voices = await getVoices();\n message.voice = voices[Math.min(voices.length - 1, Math.max(0, options._voiceIndex))];\n }\n if (typeof options.voice === 'string') {\n const voices = await getVoices();\n message.voice =\n voices[\n Math.max(\n 0,\n voices.findIndex((voice) => voice.voiceURI === options.voice)\n )\n ];\n }\n if (typeof options.onResume === 'function') {\n message.onresume = options.onResume;\n }\n if (typeof options.onMark === 'function') {\n message.onmark = options.onMark;\n }\n if (typeof options.onBoundary === 'function') {\n message.onboundary = options.onBoundary;\n }\n\n message.onstart = (nativeEvent: SpeechSynthesisEvent) => {\n this.emit('Exponent.speakingStarted', { id, nativeEvent });\n };\n message.onend = (nativeEvent: SpeechSynthesisEvent) => {\n this.emit('Exponent.speakingDone', { id, nativeEvent });\n };\n message.onpause = (nativeEvent: SpeechSynthesisEvent) => {\n this.emit('Exponent.speakingStopped', { id, nativeEvent });\n };\n message.onerror = (nativeEvent: SpeechSynthesisErrorEvent) => {\n this.emit('Exponent.speakingError', { id, nativeEvent });\n };\n\n message.text = text;\n\n window.speechSynthesis.speak(message);\n\n return message;\n }\n async getVoices(): Promise<WebVoice[]> {\n const voices = await getVoices();\n return voices.map((voice) => ({\n identifier: voice.voiceURI,\n quality: VoiceQuality.Default,\n isDefault: voice.default,\n language: voice.lang,\n localService: voice.localService,\n name: voice.name,\n voiceURI: voice.voiceURI,\n }));\n }\n async isSpeaking(): Promise<boolean> {\n return window.speechSynthesis.speaking;\n }\n async stop(): Promise<void> {\n return window.speechSynthesis.cancel();\n }\n async pause(): Promise<void> {\n return window.speechSynthesis.pause();\n }\n async resume(): Promise<void> {\n return window.speechSynthesis.resume();\n }\n maxSpeechInputLength = MAX_SPEECH_INPUT_LENGTH;\n}\n\nexport default registerWebModule(ExpoSpeech);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-speech",
3
- "version": "13.0.0-canary-20240814-ce0f7d5",
3
+ "version": "13.0.0-canary-20240912-1059f85",
4
4
  "description": "Provides text-to-speech functionality.",
5
5
  "main": "build/Speech.js",
6
6
  "types": "build/Speech.d.ts",
@@ -37,10 +37,10 @@
37
37
  },
38
38
  "dependencies": {},
39
39
  "devDependencies": {
40
- "expo-module-scripts": "3.6.0-canary-20240814-ce0f7d5"
40
+ "expo-module-scripts": "3.6.0-canary-20240912-1059f85"
41
41
  },
42
42
  "peerDependencies": {
43
- "expo": "*"
43
+ "expo": "52.0.0-canary-20240912-1059f85"
44
44
  },
45
- "gitHead": "ce0f7d5c7eaec2c8d06ee4e0dc0e58cd6c1612ed"
45
+ "gitHead": "1059f8556047a3e02fa319e8b2459274571f4e6f"
46
46
  }
@@ -1,4 +1,4 @@
1
- import { CodedError, createWebModule } from 'expo-modules-core';
1
+ import { CodedError, NativeModule, registerWebModule } from 'expo-modules-core';
2
2
 
3
3
  import { SpeechOptions, WebVoice, VoiceQuality } from './Speech.types';
4
4
 
@@ -23,7 +23,14 @@ async function getVoices(): Promise<SpeechSynthesisVoice[]> {
23
23
  });
24
24
  }
25
25
 
26
- export default createWebModule({
26
+ type ExpoSpeechEvents = {
27
+ 'Exponent.speakingStarted': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;
28
+ 'Exponent.speakingDone': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;
29
+ 'Exponent.speakingStopped': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;
30
+ 'Exponent.speakingError': (params: { id: string; nativeEvent: SpeechSynthesisEvent }) => void;
31
+ };
32
+
33
+ class ExpoSpeech extends NativeModule<ExpoSpeechEvents> {
27
34
  async speak(id: string, text: string, options: SpeechOptions): Promise<SpeechSynthesisUtterance> {
28
35
  if (text.length > MAX_SPEECH_INPUT_LENGTH) {
29
36
  throw new CodedError(
@@ -71,16 +78,16 @@ export default createWebModule({
71
78
  }
72
79
 
73
80
  message.onstart = (nativeEvent: SpeechSynthesisEvent) => {
74
- (this as any).emit('Exponent.speakingStarted', { id, nativeEvent });
81
+ this.emit('Exponent.speakingStarted', { id, nativeEvent });
75
82
  };
76
83
  message.onend = (nativeEvent: SpeechSynthesisEvent) => {
77
- (this as any).emit('Exponent.speakingDone', { id, nativeEvent });
84
+ this.emit('Exponent.speakingDone', { id, nativeEvent });
78
85
  };
79
86
  message.onpause = (nativeEvent: SpeechSynthesisEvent) => {
80
- (this as any).emit('Exponent.speakingStopped', { id, nativeEvent });
87
+ this.emit('Exponent.speakingStopped', { id, nativeEvent });
81
88
  };
82
89
  message.onerror = (nativeEvent: SpeechSynthesisErrorEvent) => {
83
- (this as any).emit('Exponent.speakingError', { id, nativeEvent });
90
+ this.emit('Exponent.speakingError', { id, nativeEvent });
84
91
  };
85
92
 
86
93
  message.text = text;
@@ -88,7 +95,7 @@ export default createWebModule({
88
95
  window.speechSynthesis.speak(message);
89
96
 
90
97
  return message;
91
- },
98
+ }
92
99
  async getVoices(): Promise<WebVoice[]> {
93
100
  const voices = await getVoices();
94
101
  return voices.map((voice) => ({
@@ -100,18 +107,20 @@ export default createWebModule({
100
107
  name: voice.name,
101
108
  voiceURI: voice.voiceURI,
102
109
  }));
103
- },
110
+ }
104
111
  async isSpeaking(): Promise<boolean> {
105
112
  return window.speechSynthesis.speaking;
106
- },
113
+ }
107
114
  async stop(): Promise<void> {
108
115
  return window.speechSynthesis.cancel();
109
- },
116
+ }
110
117
  async pause(): Promise<void> {
111
118
  return window.speechSynthesis.pause();
112
- },
119
+ }
113
120
  async resume(): Promise<void> {
114
121
  return window.speechSynthesis.resume();
115
- },
116
- maxSpeechInputLength: MAX_SPEECH_INPUT_LENGTH,
117
- });
122
+ }
123
+ maxSpeechInputLength = MAX_SPEECH_INPUT_LENGTH;
124
+ }
125
+
126
+ export default registerWebModule(ExpoSpeech);