@capgo/capacitor-speech-recognition 7.0.1 → 7.2.0

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/README.md CHANGED
@@ -73,6 +73,7 @@ Add the following keys to your app `Info.plist`:
73
73
  * [`isListening()`](#islistening)
74
74
  * [`checkPermissions()`](#checkpermissions)
75
75
  * [`requestPermissions()`](#requestpermissions)
76
+ * [`getPluginVersion()`](#getpluginversion)
76
77
  * [`addListener('endOfSegmentedSession', ...)`](#addlistenerendofsegmentedsession-)
77
78
  * [`addListener('segmentResults', ...)`](#addlistenersegmentresults-)
78
79
  * [`addListener('partialResults', ...)`](#addlistenerpartialresults-)
@@ -184,6 +185,21 @@ Requests the microphone + speech recognition permissions.
184
185
  --------------------
185
186
 
186
187
 
188
+ ### getPluginVersion()
189
+
190
+ ```typescript
191
+ getPluginVersion() => Promise<{ version: string; }>
192
+ ```
193
+
194
+ Returns the native plugin version bundled with this package.
195
+
196
+ Useful when reporting issues to confirm that native and JS versions match.
197
+
198
+ **Returns:** <code>Promise&lt;{ version: string; }&gt;</code>
199
+
200
+ --------------------
201
+
202
+
187
203
  ### addListener('endOfSegmentedSession', ...)
188
204
 
189
205
  ```typescript
@@ -11,6 +11,7 @@ import com.getcapacitor.PluginCall;
11
11
  import java.util.List;
12
12
 
13
13
  public class Receiver extends BroadcastReceiver implements Constants {
14
+
14
15
  private List<String> supportedLanguagesList;
15
16
  private String languagePref;
16
17
  private final PluginCall call;
@@ -34,6 +34,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
34
34
 
35
35
  public static final String SPEECH_RECOGNITION = "speechRecognition";
36
36
  private static final String TAG = "SpeechRecognition";
37
+ private static final String PLUGIN_VERSION = "7.0.0";
37
38
 
38
39
  private Receiver languageReceiver;
39
40
  private SpeechRecognizer speechRecognizer;
@@ -63,11 +64,13 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
63
64
  @PluginMethod
64
65
  public void start(PluginCall call) {
65
66
  if (!SpeechRecognizer.isRecognitionAvailable(bridge.getContext())) {
67
+ Logger.warn(TAG, "start() called but speech recognizer unavailable");
66
68
  call.unavailable(NOT_AVAILABLE);
67
69
  return;
68
70
  }
69
71
 
70
72
  if (getPermissionState(SPEECH_RECOGNITION) != PermissionState.GRANTED) {
73
+ Logger.warn(TAG, "start() missing RECORD_AUDIO permission");
71
74
  call.reject(MISSING_PERMISSION);
72
75
  return;
73
76
  }
@@ -78,11 +81,23 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
78
81
  boolean partialResults = call.getBoolean("partialResults", false);
79
82
  boolean popup = call.getBoolean("popup", false);
80
83
  int allowForSilence = call.getInt("allowForSilence", 0);
84
+ Logger.info(
85
+ TAG,
86
+ String.format(
87
+ "Starting recognition | lang=%s maxResults=%d partial=%s popup=%s allowForSilence=%d",
88
+ language,
89
+ maxResults,
90
+ partialResults,
91
+ popup,
92
+ allowForSilence
93
+ )
94
+ );
81
95
  beginListening(language, maxResults, prompt, partialResults, popup, call, allowForSilence);
82
96
  }
83
97
 
84
98
  @PluginMethod
85
99
  public void stop(final PluginCall call) {
100
+ Logger.info(TAG, "stop() requested");
86
101
  try {
87
102
  stopListening();
88
103
  } catch (Exception ex) {
@@ -130,6 +145,13 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
130
145
  requestPermissionForAlias(SPEECH_RECOGNITION, call, "permissionsCallback");
131
146
  }
132
147
 
148
+ @PluginMethod
149
+ public void getPluginVersion(PluginCall call) {
150
+ JSObject ret = new JSObject();
151
+ ret.put("version", PLUGIN_VERSION);
152
+ call.resolve(ret);
153
+ }
154
+
133
155
  @PermissionCallback
134
156
  private void permissionsCallback(PluginCall call) {
135
157
  String state = permissionStateValue(getPermissionState(SPEECH_RECOGNITION));
@@ -229,6 +251,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
229
251
  try {
230
252
  lock.lock();
231
253
  if (listening) {
254
+ Logger.debug(TAG, "Stopping inline recognizer");
232
255
  speechRecognizer.stopListening();
233
256
  listening(false);
234
257
  }
@@ -280,6 +303,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
280
303
  JSObject ret = new JSObject();
281
304
  ret.put("status", "started");
282
305
  notifyListeners(LISTENING_EVENT, ret);
306
+ Logger.debug(TAG, "Listening started");
283
307
  } finally {
284
308
  lock.unlock();
285
309
  }
@@ -313,6 +337,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
313
337
  public void onError(int error) {
314
338
  stopListening();
315
339
  String errorMssg = getErrorText(error);
340
+ Logger.error(TAG, "Recognizer error: " + errorMssg, null);
316
341
 
317
342
  if (call != null) {
318
343
  call.reject(errorMssg);
@@ -325,6 +350,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
325
350
 
326
351
  try {
327
352
  JSArray jsArray = new JSArray(matches);
353
+ Logger.debug(TAG, "Received final results count=" + (matches == null ? 0 : matches.size()));
328
354
 
329
355
  if (call != null) {
330
356
  if (!partialResults) {
@@ -353,6 +379,7 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
353
379
  JSObject ret = new JSObject();
354
380
  ret.put("matches", previousPartialResults);
355
381
  notifyListeners(PARTIAL_RESULTS_EVENT, ret);
382
+ Logger.debug(TAG, "Partial results updated");
356
383
  }
357
384
  } catch (Exception ex) {}
358
385
  }
@@ -367,12 +394,14 @@ public class SpeechRecognitionPlugin extends Plugin implements Constants {
367
394
  JSObject ret = new JSObject();
368
395
  ret.put("matches", new JSArray(matches));
369
396
  notifyListeners(SEGMENT_RESULTS_EVENT, ret);
397
+ Logger.debug(TAG, "Segment results emitted");
370
398
  } catch (Exception ignored) {}
371
399
  }
372
400
 
373
401
  @Override
374
402
  public void onEndOfSegmentedSession() {
375
403
  notifyListeners(END_OF_SEGMENT_EVENT, new JSObject());
404
+ Logger.debug(TAG, "Segmented session ended");
376
405
  }
377
406
 
378
407
  @Override
package/dist/docs.json CHANGED
@@ -94,6 +94,16 @@
94
94
  ],
95
95
  "slug": "requestpermissions"
96
96
  },
97
+ {
98
+ "name": "getPluginVersion",
99
+ "signature": "() => Promise<{ version: string; }>",
100
+ "parameters": [],
101
+ "returns": "Promise<{ version: string; }>",
102
+ "tags": [],
103
+ "docs": "Returns the native plugin version bundled with this package.\n\nUseful when reporting issues to confirm that native and JS versions match.",
104
+ "complexTypes": [],
105
+ "slug": "getpluginversion"
106
+ },
97
107
  {
98
108
  "name": "addListener",
99
109
  "signature": "(eventName: 'endOfSegmentedSession', listenerFunc: () => void) => Promise<PluginListenerHandle>",
@@ -107,6 +107,14 @@ export interface SpeechRecognitionPlugin {
107
107
  * Requests the microphone + speech recognition permissions.
108
108
  */
109
109
  requestPermissions(): Promise<SpeechRecognitionPermissionStatus>;
110
+ /**
111
+ * Returns the native plugin version bundled with this package.
112
+ *
113
+ * Useful when reporting issues to confirm that native and JS versions match.
114
+ */
115
+ getPluginVersion(): Promise<{
116
+ version: string;
117
+ }>;
110
118
  /**
111
119
  * Listen for segmented session completion events (Android only).
112
120
  */
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Permission map returned by `checkPermissions` and `requestPermissions`.\n *\n * On Android the state maps to the `RECORD_AUDIO` permission.\n * On iOS it combines speech recognition plus microphone permission.\n */\nexport interface SpeechRecognitionPermissionStatus {\n speechRecognition: PermissionState;\n}\n\n/**\n * Configure how the recognizer behaves when calling {@link SpeechRecognitionPlugin.start}.\n */\nexport interface SpeechRecognitionStartOptions {\n /**\n * Locale identifier such as `en-US`. When omitted the device language is used.\n */\n language?: string;\n /**\n * Maximum number of final matches returned by native APIs. Defaults to `5`.\n */\n maxResults?: number;\n /**\n * Prompt message shown inside the Android system dialog (ignored on iOS).\n */\n prompt?: string;\n /**\n * When `true`, Android shows the OS speech dialog instead of running inline recognition.\n * Defaults to `false`.\n */\n popup?: boolean;\n /**\n * Emits partial transcription updates through the `partialResults` listener while audio is captured.\n */\n partialResults?: boolean;\n /**\n * Enables native punctuation handling where supported (iOS 16+).\n */\n addPunctuation?: boolean;\n /**\n * Allow a number of milliseconds of silence before splitting the recognition session into segments.\n * Required to be greater than zero and currently supported on Android only.\n */\n allowForSilence?: number;\n}\n\n/**\n * Raised whenever a partial transcription is produced.\n */\nexport interface SpeechRecognitionPartialResultEvent {\n matches: string[];\n}\n\n/**\n * Raised whenever a segmented result is produced (Android only).\n */\nexport interface SpeechRecognitionSegmentResultEvent {\n matches: string[];\n}\n\n/**\n * Raised when the listening state changes.\n */\nexport interface SpeechRecognitionListeningEvent {\n status: 'started' | 'stopped';\n}\n\nexport interface SpeechRecognitionAvailability {\n available: boolean;\n}\n\nexport interface SpeechRecognitionMatches {\n matches?: string[];\n}\n\nexport interface SpeechRecognitionLanguages {\n languages: string[];\n}\n\nexport interface SpeechRecognitionListening {\n listening: boolean;\n}\n\nexport interface SpeechRecognitionPlugin {\n /**\n * Checks whether the native speech recognition service is usable on the current device.\n */\n available(): Promise<SpeechRecognitionAvailability>;\n /**\n * Begins capturing audio and transcribing speech.\n *\n * When `partialResults` is `true`, the returned promise resolves immediately and updates are\n * streamed through the `partialResults` listener until {@link stop} is called.\n */\n start(options?: SpeechRecognitionStartOptions): Promise<SpeechRecognitionMatches>;\n /**\n * Stops listening and tears down native resources.\n */\n stop(): Promise<void>;\n /**\n * Gets the locales supported by the underlying recognizer.\n *\n * Android 13+ devices no longer expose this list; in that case `languages` is empty.\n */\n getSupportedLanguages(): Promise<SpeechRecognitionLanguages>;\n /**\n * Returns whether the plugin is actively listening for speech.\n */\n isListening(): Promise<SpeechRecognitionListening>;\n /**\n * Gets the current permission state.\n */\n checkPermissions(): Promise<SpeechRecognitionPermissionStatus>;\n /**\n * Requests the microphone + speech recognition permissions.\n */\n requestPermissions(): Promise<SpeechRecognitionPermissionStatus>;\n /**\n * Listen for segmented session completion events (Android only).\n */\n addListener(eventName: 'endOfSegmentedSession', listenerFunc: () => void): Promise<PluginListenerHandle>;\n /**\n * Listen for segmented recognition results (Android only).\n */\n addListener(\n eventName: 'segmentResults',\n listenerFunc: (event: SpeechRecognitionSegmentResultEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Listen for partial transcription updates emitted while `partialResults` is enabled.\n */\n addListener(\n eventName: 'partialResults',\n listenerFunc: (event: SpeechRecognitionPartialResultEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Listen for changes to the native listening state.\n */\n addListener(\n eventName: 'listeningState',\n listenerFunc: (event: SpeechRecognitionListeningEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Removes every registered listener.\n */\n removeAllListeners(): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\n/**\n * Permission map returned by `checkPermissions` and `requestPermissions`.\n *\n * On Android the state maps to the `RECORD_AUDIO` permission.\n * On iOS it combines speech recognition plus microphone permission.\n */\nexport interface SpeechRecognitionPermissionStatus {\n speechRecognition: PermissionState;\n}\n\n/**\n * Configure how the recognizer behaves when calling {@link SpeechRecognitionPlugin.start}.\n */\nexport interface SpeechRecognitionStartOptions {\n /**\n * Locale identifier such as `en-US`. When omitted the device language is used.\n */\n language?: string;\n /**\n * Maximum number of final matches returned by native APIs. Defaults to `5`.\n */\n maxResults?: number;\n /**\n * Prompt message shown inside the Android system dialog (ignored on iOS).\n */\n prompt?: string;\n /**\n * When `true`, Android shows the OS speech dialog instead of running inline recognition.\n * Defaults to `false`.\n */\n popup?: boolean;\n /**\n * Emits partial transcription updates through the `partialResults` listener while audio is captured.\n */\n partialResults?: boolean;\n /**\n * Enables native punctuation handling where supported (iOS 16+).\n */\n addPunctuation?: boolean;\n /**\n * Allow a number of milliseconds of silence before splitting the recognition session into segments.\n * Required to be greater than zero and currently supported on Android only.\n */\n allowForSilence?: number;\n}\n\n/**\n * Raised whenever a partial transcription is produced.\n */\nexport interface SpeechRecognitionPartialResultEvent {\n matches: string[];\n}\n\n/**\n * Raised whenever a segmented result is produced (Android only).\n */\nexport interface SpeechRecognitionSegmentResultEvent {\n matches: string[];\n}\n\n/**\n * Raised when the listening state changes.\n */\nexport interface SpeechRecognitionListeningEvent {\n status: 'started' | 'stopped';\n}\n\nexport interface SpeechRecognitionAvailability {\n available: boolean;\n}\n\nexport interface SpeechRecognitionMatches {\n matches?: string[];\n}\n\nexport interface SpeechRecognitionLanguages {\n languages: string[];\n}\n\nexport interface SpeechRecognitionListening {\n listening: boolean;\n}\n\nexport interface SpeechRecognitionPlugin {\n /**\n * Checks whether the native speech recognition service is usable on the current device.\n */\n available(): Promise<SpeechRecognitionAvailability>;\n /**\n * Begins capturing audio and transcribing speech.\n *\n * When `partialResults` is `true`, the returned promise resolves immediately and updates are\n * streamed through the `partialResults` listener until {@link stop} is called.\n */\n start(options?: SpeechRecognitionStartOptions): Promise<SpeechRecognitionMatches>;\n /**\n * Stops listening and tears down native resources.\n */\n stop(): Promise<void>;\n /**\n * Gets the locales supported by the underlying recognizer.\n *\n * Android 13+ devices no longer expose this list; in that case `languages` is empty.\n */\n getSupportedLanguages(): Promise<SpeechRecognitionLanguages>;\n /**\n * Returns whether the plugin is actively listening for speech.\n */\n isListening(): Promise<SpeechRecognitionListening>;\n /**\n * Gets the current permission state.\n */\n checkPermissions(): Promise<SpeechRecognitionPermissionStatus>;\n /**\n * Requests the microphone + speech recognition permissions.\n */\n requestPermissions(): Promise<SpeechRecognitionPermissionStatus>;\n /**\n * Returns the native plugin version bundled with this package.\n *\n * Useful when reporting issues to confirm that native and JS versions match.\n */\n getPluginVersion(): Promise<{ version: string }>;\n /**\n * Listen for segmented session completion events (Android only).\n */\n addListener(eventName: 'endOfSegmentedSession', listenerFunc: () => void): Promise<PluginListenerHandle>;\n /**\n * Listen for segmented recognition results (Android only).\n */\n addListener(\n eventName: 'segmentResults',\n listenerFunc: (event: SpeechRecognitionSegmentResultEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Listen for partial transcription updates emitted while `partialResults` is enabled.\n */\n addListener(\n eventName: 'partialResults',\n listenerFunc: (event: SpeechRecognitionPartialResultEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Listen for changes to the native listening state.\n */\n addListener(\n eventName: 'listeningState',\n listenerFunc: (event: SpeechRecognitionListeningEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Removes every registered listener.\n */\n removeAllListeners(): Promise<void>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -8,4 +8,7 @@ export declare class SpeechRecognitionWeb extends WebPlugin implements SpeechRec
8
8
  isListening(): Promise<SpeechRecognitionListening>;
9
9
  checkPermissions(): Promise<SpeechRecognitionPermissionStatus>;
10
10
  requestPermissions(): Promise<SpeechRecognitionPermissionStatus>;
11
+ getPluginVersion(): Promise<{
12
+ version: string;
13
+ }>;
11
14
  }
package/dist/esm/web.js CHANGED
@@ -21,5 +21,8 @@ export class SpeechRecognitionWeb extends WebPlugin {
21
21
  requestPermissions() {
22
22
  throw this.unimplemented('Speech recognition permissions are not handled on the web.');
23
23
  }
24
+ async getPluginVersion() {
25
+ return { version: 'web' };
26
+ }
24
27
  }
25
28
  //# sourceMappingURL=web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAY5C,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjD,SAAS;QACP,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,QAAwC;QAC5C,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,qBAAqB;QACnB,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,WAAW;QACT,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,gBAAgB;QACd,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC,CAAC;IACzF,CAAC;IAED,kBAAkB;QAChB,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC,CAAC;IACzF,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n SpeechRecognitionAvailability,\n SpeechRecognitionLanguages,\n SpeechRecognitionListening,\n SpeechRecognitionMatches,\n SpeechRecognitionPermissionStatus,\n SpeechRecognitionPlugin,\n SpeechRecognitionStartOptions,\n} from './definitions';\n\nexport class SpeechRecognitionWeb extends WebPlugin implements SpeechRecognitionPlugin {\n available(): Promise<SpeechRecognitionAvailability> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n start(_options?: SpeechRecognitionStartOptions): Promise<SpeechRecognitionMatches> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n stop(): Promise<void> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n getSupportedLanguages(): Promise<SpeechRecognitionLanguages> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n isListening(): Promise<SpeechRecognitionListening> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n checkPermissions(): Promise<SpeechRecognitionPermissionStatus> {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n\n requestPermissions(): Promise<SpeechRecognitionPermissionStatus> {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAY5C,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjD,SAAS;QACP,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,QAAwC;QAC5C,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,qBAAqB;QACnB,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,WAAW;QACT,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,gBAAgB;QACd,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC,CAAC;IACzF,CAAC;IAED,kBAAkB;QAChB,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC,CAAC;IACzF,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n SpeechRecognitionAvailability,\n SpeechRecognitionLanguages,\n SpeechRecognitionListening,\n SpeechRecognitionMatches,\n SpeechRecognitionPermissionStatus,\n SpeechRecognitionPlugin,\n SpeechRecognitionStartOptions,\n} from './definitions';\n\nexport class SpeechRecognitionWeb extends WebPlugin implements SpeechRecognitionPlugin {\n available(): Promise<SpeechRecognitionAvailability> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n start(_options?: SpeechRecognitionStartOptions): Promise<SpeechRecognitionMatches> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n stop(): Promise<void> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n getSupportedLanguages(): Promise<SpeechRecognitionLanguages> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n isListening(): Promise<SpeechRecognitionListening> {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n\n checkPermissions(): Promise<SpeechRecognitionPermissionStatus> {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n\n requestPermissions(): Promise<SpeechRecognitionPermissionStatus> {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n}\n"]}
@@ -28,6 +28,9 @@ class SpeechRecognitionWeb extends core.WebPlugin {
28
28
  requestPermissions() {
29
29
  throw this.unimplemented('Speech recognition permissions are not handled on the web.');
30
30
  }
31
+ async getPluginVersion() {
32
+ return { version: 'web' };
33
+ }
31
34
  }
32
35
 
33
36
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SpeechRecognition = registerPlugin('SpeechRecognition', {\n web: () => import('./web').then((m) => new m.SpeechRecognitionWeb()),\n});\nexport * from './definitions';\nexport { SpeechRecognition };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SpeechRecognitionWeb extends WebPlugin {\n available() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n start(_options) {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n stop() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n getSupportedLanguages() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n isListening() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n checkPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n requestPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,iBAAiB,GAAGA,mBAAc,CAAC,mBAAmB,EAAE;AAC9D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;AACxE,CAAC;;ACFM,MAAM,oBAAoB,SAASC,cAAS,CAAC;AACpD,IAAI,SAAS,GAAG;AAChB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,KAAK,CAAC,QAAQ,EAAE;AACpB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,IAAI,GAAG;AACX,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,qBAAqB,GAAG;AAC5B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,WAAW,GAAG;AAClB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,gBAAgB,GAAG;AACvB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;AAC9F,IAAI;AACJ,IAAI,kBAAkB,GAAG;AACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;AAC9F,IAAI;AACJ;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SpeechRecognition = registerPlugin('SpeechRecognition', {\n web: () => import('./web').then((m) => new m.SpeechRecognitionWeb()),\n});\nexport * from './definitions';\nexport { SpeechRecognition };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SpeechRecognitionWeb extends WebPlugin {\n available() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n start(_options) {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n stop() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n getSupportedLanguages() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n isListening() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n checkPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n requestPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,iBAAiB,GAAGA,mBAAc,CAAC,mBAAmB,EAAE;AAC9D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;AACxE,CAAC;;ACFM,MAAM,oBAAoB,SAASC,cAAS,CAAC;AACpD,IAAI,SAAS,GAAG;AAChB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,KAAK,CAAC,QAAQ,EAAE;AACpB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,IAAI,GAAG;AACX,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,qBAAqB,GAAG;AAC5B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,WAAW,GAAG;AAClB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,gBAAgB,GAAG;AACvB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;AAC9F,IAAI;AACJ,IAAI,kBAAkB,GAAG;AACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;AAC9F,IAAI;AACJ,IAAI,MAAM,gBAAgB,GAAG;AAC7B,QAAQ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;AACjC,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js CHANGED
@@ -27,6 +27,9 @@ var capacitorCapacitorSpeechRecognition = (function (exports, core) {
27
27
  requestPermissions() {
28
28
  throw this.unimplemented('Speech recognition permissions are not handled on the web.');
29
29
  }
30
+ async getPluginVersion() {
31
+ return { version: 'web' };
32
+ }
30
33
  }
31
34
 
32
35
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SpeechRecognition = registerPlugin('SpeechRecognition', {\n web: () => import('./web').then((m) => new m.SpeechRecognitionWeb()),\n});\nexport * from './definitions';\nexport { SpeechRecognition };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SpeechRecognitionWeb extends WebPlugin {\n available() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n start(_options) {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n stop() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n getSupportedLanguages() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n isListening() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n checkPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n requestPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,iBAAiB,GAAGA,mBAAc,CAAC,mBAAmB,EAAE;IAC9D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;IACxE,CAAC;;ICFM,MAAM,oBAAoB,SAASC,cAAS,CAAC;IACpD,IAAI,SAAS,GAAG;IAChB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,KAAK,CAAC,QAAQ,EAAE;IACpB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,IAAI,GAAG;IACX,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,qBAAqB,GAAG;IAC5B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,WAAW,GAAG;IAClB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,gBAAgB,GAAG;IACvB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;IAC9F,IAAI;IACJ,IAAI,kBAAkB,GAAG;IACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;IAC9F,IAAI;IACJ;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst SpeechRecognition = registerPlugin('SpeechRecognition', {\n web: () => import('./web').then((m) => new m.SpeechRecognitionWeb()),\n});\nexport * from './definitions';\nexport { SpeechRecognition };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SpeechRecognitionWeb extends WebPlugin {\n available() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n start(_options) {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n stop() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n getSupportedLanguages() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n isListening() {\n throw this.unimplemented('Speech recognition is not available on the web.');\n }\n checkPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n requestPermissions() {\n throw this.unimplemented('Speech recognition permissions are not handled on the web.');\n }\n async getPluginVersion() {\n return { version: 'web' };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,iBAAiB,GAAGA,mBAAc,CAAC,mBAAmB,EAAE;IAC9D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;IACxE,CAAC;;ICFM,MAAM,oBAAoB,SAASC,cAAS,CAAC;IACpD,IAAI,SAAS,GAAG;IAChB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,KAAK,CAAC,QAAQ,EAAE;IACpB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,IAAI,GAAG;IACX,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,qBAAqB,GAAG;IAC5B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,WAAW,GAAG;IAClB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,gBAAgB,GAAG;IACvB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;IAC9F,IAAI;IACJ,IAAI,kBAAkB,GAAG;IACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4DAA4D,CAAC;IAC9F,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;IACjC,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -11,6 +11,7 @@ private enum PermissionState: String {
11
11
 
12
12
  @objc(SpeechRecognitionPlugin)
13
13
  public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
14
+ private let pluginVersion: String = "7.2.0"
14
15
  public let identifier = "SpeechRecognitionPlugin"
15
16
  public let jsName = "SpeechRecognition"
16
17
  public let pluginMethods: [CAPPluginMethod] = [
@@ -20,7 +21,8 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
20
21
  CAPPluginMethod(name: "getSupportedLanguages", returnType: CAPPluginReturnPromise),
21
22
  CAPPluginMethod(name: "isListening", returnType: CAPPluginReturnPromise),
22
23
  CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise),
23
- CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise)
24
+ CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise),
25
+ CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
24
26
  ]
25
27
 
26
28
  private let audioEngine = AVAudioEngine()
@@ -41,11 +43,13 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
41
43
 
42
44
  @objc func start(_ call: CAPPluginCall) {
43
45
  if self.audioEngine.isRunning || recognitionTask != nil {
46
+ CAPLog.print("[SpeechRecognition] Attempted to start while already running")
44
47
  call.reject("Speech recognition is already running.")
45
48
  return
46
49
  }
47
50
 
48
51
  guard isSpeechPermissionGranted else {
52
+ CAPLog.print("[SpeechRecognition] Missing speech permission, rejecting start()")
49
53
  call.reject("Missing speech recognition permission.")
50
54
  return
51
55
  }
@@ -59,9 +63,11 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
59
63
 
60
64
  self.activeCall = call
61
65
  self.currentOptions = options
66
+ CAPLog.print("[SpeechRecognition] Starting session | language=\(options.language) partialResults=\(options.partialResults) punctuation=\(options.addPunctuation)")
62
67
 
63
68
  AVAudioSession.sharedInstance().requestRecordPermission { granted in
64
69
  guard granted else {
70
+ CAPLog.print("[SpeechRecognition] Microphone permission denied by user")
65
71
  DispatchQueue.main.async {
66
72
  call.reject("User denied microphone access.")
67
73
  self.cleanupRecognition(notifyStop: false)
@@ -76,6 +82,7 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
76
82
  }
77
83
 
78
84
  @objc func stop(_ call: CAPPluginCall) {
85
+ CAPLog.print("[SpeechRecognition] stop() invoked")
79
86
  cleanupRecognition(notifyStop: true)
80
87
  call.resolve()
81
88
  }
@@ -209,6 +216,7 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
209
216
 
210
217
  private func cleanupRecognition(notifyStop: Bool) {
211
218
  DispatchQueue.main.async {
219
+ CAPLog.print("[SpeechRecognition] Cleaning up recognition resources")
212
220
  if self.audioEngine.isRunning {
213
221
  self.audioEngine.stop()
214
222
  }
@@ -234,6 +242,7 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
234
242
 
235
243
  private func handleRecognitionError(_ error: Error) {
236
244
  DispatchQueue.main.async {
245
+ CAPLog.print("[SpeechRecognition] Error from recognizer: \(error.localizedDescription)")
237
246
  self.cleanupRecognition(notifyStop: true)
238
247
  self.activeCall?.reject(error.localizedDescription)
239
248
  }
@@ -272,6 +281,10 @@ public final class SpeechRecognitionPlugin: CAPPlugin, CAPBridgedPlugin {
272
281
 
273
282
  return .granted
274
283
  }
284
+
285
+ @objc func getPluginVersion(_ call: CAPPluginCall) {
286
+ call.resolve(["version": pluginVersion])
287
+ }
275
288
  }
276
289
 
277
290
  private struct RecognitionOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-speech-recognition",
3
- "version": "7.0.1",
3
+ "version": "7.2.0",
4
4
  "description": "Capacitor plugin for comprehensive on-device speech recognition with live partial results.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -39,8 +39,8 @@
39
39
  "verify:web": "npm run build",
40
40
  "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
41
41
  "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
42
- "eslint": "eslint . --ext .ts",
43
- "prettier": "prettier \"**/*.{css,html,ts,js,java,kt}\" --plugin=prettier-plugin-java",
42
+ "eslint": "eslint . --ext ts",
43
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
44
44
  "swiftlint": "node-swiftlint",
45
45
  "docgen": "docgen --api SpeechRecognitionPlugin --output-readme README.md --output-json dist/docs.json",
46
46
  "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",