react-native-wakeword-sid 1.1.209 → 1.1.211

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.
@@ -1 +1 @@
1
- 22a7d3a03cf611623990763e52c2c9b1 keyworddetection-1.0.0.aar
1
+ 29f76a7f2526d57eaba9203dae00b06e keyworddetection-1.0.0.aar
@@ -1 +1 @@
1
- c9ec5e1fd232f58f0db17b11731b66295321786f keyworddetection-1.0.0.aar
1
+ 54adcc23c784604563a27e74a089780ac73781f1 keyworddetection-1.0.0.aar
@@ -19,6 +19,7 @@ import java.util.HashMap;
19
19
  import java.util.Map;
20
20
  import java.util.concurrent.ExecutorService;
21
21
  import java.util.concurrent.Executors;
22
+ import java.util.concurrent.ConcurrentHashMap;
22
23
  import java.util.concurrent.atomic.AtomicInteger;
23
24
 
24
25
 
@@ -39,13 +40,13 @@ public class KeyWordRNBridge extends ReactContextBaseJavaModule {
39
40
  SpeakerVerification.SpeakerEnrollment enrollment;
40
41
  }
41
42
 
42
- private final Map<String, SVEngineHolder> svEngines = new HashMap<>();
43
+ private final Map<String, SVEngineHolder> svEngines = new ConcurrentHashMap<>();
43
44
 
44
- private final Map<String, SpeakerVerification.SpeakerVerificationMicController> svMicControllers = new HashMap<>();
45
- private final Map<String, Boolean> svAutoOnboarding = new HashMap<>();
46
- private final Map<String, Integer> svAutoTarget = new HashMap<>();
47
- private final Map<String, Integer> svAutoCollected = new HashMap<>();
48
- private final Map<String, String> svAutoEnrollmentId = new HashMap<>();
45
+ private final Map<String, SpeakerVerification.SpeakerVerificationMicController> svMicControllers = new ConcurrentHashMap<>();
46
+ private final Map<String, Boolean> svAutoOnboarding = new ConcurrentHashMap<>();
47
+ private final Map<String, Integer> svAutoTarget = new ConcurrentHashMap<>();
48
+ private final Map<String, Integer> svAutoCollected = new ConcurrentHashMap<>();
49
+ private final Map<String, String> svAutoEnrollmentId = new ConcurrentHashMap<>();
49
50
  // IMPORTANT: serialize ALL SV ops to avoid races with mic frames / onboarding state.
50
51
  private final ExecutorService svExec = Executors.newSingleThreadExecutor();
51
52
  private final AtomicInteger svJobN = new AtomicInteger(0);
@@ -804,18 +805,26 @@ public class KeyWordRNBridge extends ReactContextBaseJavaModule {
804
805
  }
805
806
  @ReactMethod
806
807
  public void destroySpeakerVerificationMicController(String controllerId, Promise promise) {
807
- SpeakerVerification.SpeakerVerificationMicController ctrl = svMicControllers.remove(controllerId);
808
+ SpeakerVerification.SpeakerVerificationMicController ctrl = svMicControllers.get(controllerId);
808
809
  if (ctrl == null) {
809
810
  promise.reject("SVMicNotFound", "No speaker mic controller with ID: " + controllerId);
810
811
  return;
811
812
  }
812
813
 
813
- try { ctrl.stop(); } catch (Throwable ignore) {}
814
-
815
- WritableMap out = Arguments.createMap();
816
- out.putBoolean("ok", true);
817
- out.putString("controllerId", controllerId);
818
- promise.resolve(out);
814
+ final int job = svJobN.incrementAndGet();
815
+ svExec.execute(() -> {
816
+ try {
817
+ try { ctrl.stop(); } catch (Throwable ignore) {}
818
+ svMicControllers.remove(controllerId); // remove only after stop
819
+ WritableMap out = Arguments.createMap();
820
+ out.putBoolean("ok", true);
821
+ out.putString("controllerId", controllerId);
822
+ out.putInt("job", job);
823
+ promise.resolve(out);
824
+ } catch (Throwable t) {
825
+ promise.reject("SVMicDestroyError", String.valueOf(t.getMessage()), t);
826
+ }
827
+ });
819
828
  }
820
829
 
821
830
  @ReactMethod
@@ -976,15 +985,20 @@ public class KeyWordRNBridge extends ReactContextBaseJavaModule {
976
985
  return;
977
986
  }
978
987
 
979
- try {
980
- ctrl.stop();
981
- WritableMap out = Arguments.createMap();
982
- out.putBoolean("ok", true);
983
- out.putString("controllerId", controllerId);
984
- promise.resolve(out);
985
- } catch (Throwable t) {
986
- promise.reject("SVMicStopError", String.valueOf(t.getMessage()), t);
987
- }
988
+ final int job = svJobN.incrementAndGet();
989
+ svExec.execute(() -> {
990
+ try {
991
+ ctrl.stop();
992
+ WritableMap out = Arguments.createMap();
993
+ out.putBoolean("ok", true);
994
+ out.putString("controllerId", controllerId);
995
+ out.putInt("job", job);
996
+ promise.resolve(out);
997
+ } catch (Throwable t) {
998
+ promise.reject("SVMicStopError", String.valueOf(t.getMessage()), t);
999
+ }
1000
+ });
1001
+
988
1002
  }
989
1003
  @ReactMethod
990
1004
  public void startVerifyContinuousFromMic(String controllerId, boolean resetState, double hopSeconds, Promise promise) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-wakeword-sid",
3
- "version": "1.1.209",
3
+ "version": "1.1.211",
4
4
  "description": "Voice/Wake-word detection library for React Native",
5
5
  "main": "wakewords/index.js",
6
6
  "types": "wakewords/index.d.ts",
@@ -132,12 +132,7 @@ export class SpeakerVerificationMicController {
132
132
  }
133
133
 
134
134
  async create(configJson) {
135
-
136
135
  assertMethod('createSpeakerVerificationMicController');
137
- const cfg =
138
- typeof configJson === 'string'
139
- ? configJson
140
- : JSON.stringify(configJson ?? {});
141
136
  // IMPORTANT: must pass a REAL JSON string, not "[object Object]"
142
137
  const jsonStr = (typeof configJson === 'string')
143
138
  ? configJson
@@ -235,42 +230,43 @@ async function verifyFromMicWithEnrollment(enrollmentJson, setUiMessage) {
235
230
 
236
231
  const ctrl = await createSpeakerVerificationMicController('svMicVerify1');
237
232
  await ctrl.create(JSON.stringify(micConfig));
238
-
239
- // IMPORTANT: set enrollment BEFORE starting verify
240
- await ctrl.setEnrollmentJson(enrollmentJson);
241
-
242
- const waitVerify = (timeoutMs = 60_000) =>
243
- new Promise<any>((resolve, reject) => {
244
- const offR = onSpeakerVerificationVerifyResult((e) => {
245
- if (e?.controllerId !== 'svMicVerify1') return;
246
- offR?.();
247
- offE?.();
248
- resolve(e);
233
+ try {
234
+ // IMPORTANT: set enrollment BEFORE starting verify
235
+ await ctrl.setEnrollmentJson(enrollmentJson);
236
+
237
+ const waitVerify = (timeoutMs = 60_000) =>
238
+ new Promise<any>((resolve, reject) => {
239
+ const offR = onSpeakerVerificationVerifyResult((e) => {
240
+ if (e?.controllerId !== 'svMicVerify1') return;
241
+ offR?.();
242
+ offE?.();
243
+ resolve(e);
244
+ });
245
+ const offE = onSpeakerVerificationError((e) => {
246
+ if (e?.controllerId !== 'svMicVerify1') return;
247
+ offR?.();
248
+ offE?.();
249
+ reject(new Error(`[SVJS] verify error: ${JSON.stringify(e)}`));
250
+ });
251
+ setTimeout(() => {
252
+ offR?.();
253
+ offE?.();
254
+ reject(new Error('NO_SPEECH_TIMEOUT'));
255
+ }, timeoutMs);
249
256
  });
250
- const offE = onSpeakerVerificationError((e) => {
251
- if (e?.controllerId !== 'svMicVerify1') return;
252
- offR?.();
253
- offE?.();
254
- reject(new Error(`[SVJS] verify error: ${JSON.stringify(e)}`));
255
- });
256
- setTimeout(() => {
257
- offR?.();
258
- offE?.();
259
- reject(new Error('NO_SPEECH_TIMEOUT'));
260
- }, timeoutMs);
261
- });
262
-
263
- // start one verify pass (native should emit onSpeakerVerificationVerifyResult)
264
- setUiMessage?.('🎙️ Mic verify: please speak (up to 60s)...');
265
- await ctrl.startVerifyFromMic(true);
266
-
267
- const res = await waitVerify(60_000);
268
- console.log('[SVJS] mic verify result event:', res);
269
- setUiMessage?.(`✅ Mic verify done → score=${res?.bestScore ?? res?.score ?? 'n/a'}`);
270
-
271
- await ctrl.stop().catch(() => {});
272
- await ctrl.destroy().catch(() => {});
273
- return res;
257
+
258
+ // start one verify pass (native should emit onSpeakerVerificationVerifyResult)
259
+ setUiMessage?.('🎙️ Mic verify: please speak (up to 60s)...');
260
+ await ctrl.startVerifyFromMic(true);
261
+
262
+ const res = await waitVerify(60_000);
263
+ console.log('[SVJS] mic verify result event:', res);
264
+ setUiMessage?.(`✅ Mic verify done → score=${res?.bestScore ?? res?.score ?? 'n/a'}`);
265
+ return res;
266
+ } finally {
267
+ await ctrl.stop().catch(() => {});
268
+ await ctrl.destroy().catch(() => {});
269
+ }
274
270
  }
275
271
 
276
272
  // ============================================================