@contentgrowth/llm-service 0.9.7 → 0.9.9

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.
@@ -209,6 +209,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
209
209
  onResultRef.current = onResult;
210
210
  onEndRef.current = onEnd;
211
211
  }, [onResult, onEnd]);
212
+ const isStartingRef = (0, import_react2.useRef)(false);
212
213
  (0, import_react2.useEffect)(() => {
213
214
  if (typeof window !== "undefined") {
214
215
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
@@ -218,10 +219,14 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
218
219
  recognition.continuous = true;
219
220
  recognition.interimResults = true;
220
221
  recognition.onstart = () => {
222
+ console.log("[useSpeechRecognition] Native onstart event fired");
223
+ isStartingRef.current = false;
221
224
  setIsListening(true);
222
225
  setError(null);
223
226
  };
224
227
  recognition.onend = () => {
228
+ console.log("[useSpeechRecognition] Native onend event fired");
229
+ isStartingRef.current = false;
225
230
  if (isSimulatingRef.current) {
226
231
  return;
227
232
  }
@@ -245,6 +250,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
245
250
  };
246
251
  recognition.onerror = (event) => {
247
252
  console.error("[useSpeechRecognition] Native onerror event:", event.error);
253
+ isStartingRef.current = false;
248
254
  if (event.error === "not-allowed" && process.env.NODE_ENV === "development") {
249
255
  console.warn("Speech recognition blocked. Simulating input for development...");
250
256
  isSimulatingRef.current = true;
@@ -269,6 +275,7 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
269
275
  }
270
276
  }
271
277
  return () => {
278
+ console.log("[useSpeechRecognition] Effect cleanup - stopping recognition");
272
279
  if (isSimulatingRef.current && simulationTimeoutRef.current) {
273
280
  clearTimeout(simulationTimeoutRef.current);
274
281
  simulationTimeoutRef.current = null;
@@ -280,21 +287,40 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
280
287
  }, []);
281
288
  (0, import_react2.useEffect)(() => {
282
289
  if (recognitionRef.current) {
290
+ console.log("[useSpeechRecognition] Updating language to:", language);
283
291
  recognitionRef.current.lang = language;
284
292
  }
285
293
  }, [language]);
286
294
  const start = (0, import_react2.useCallback)(() => {
287
- if (recognitionRef.current && !isListening) {
288
- try {
289
- setTranscript("");
290
- recognitionRef.current.start();
291
- } catch (e) {
292
- console.error("[useSpeechRecognition] Failed to start speech recognition:", e);
293
- }
294
- } else {
295
+ console.log("[useSpeechRecognition] start() called");
296
+ if (isSimulatingRef.current) return;
297
+ if (!recognitionRef.current) {
298
+ console.error("[useSpeechRecognition] Recognition instance missing");
299
+ return;
300
+ }
301
+ if (isStartingRef.current) {
302
+ console.warn("[useSpeechRecognition] Already starting - ignoring duplicate call");
303
+ return;
304
+ }
305
+ if (recognitionRef.current.isListening) {
306
+ console.warn("[useSpeechRecognition] Already listening - ignoring");
307
+ }
308
+ if (isListening) {
309
+ console.warn("[useSpeechRecognition] App state says already listening - ignoring");
310
+ return;
311
+ }
312
+ try {
313
+ setTranscript("");
314
+ isStartingRef.current = true;
315
+ recognitionRef.current.start();
316
+ console.log("[useSpeechRecognition] recognition.start() executed");
317
+ } catch (error2) {
318
+ isStartingRef.current = false;
319
+ console.error("[useSpeechRecognition] Failed to start recognition:", error2);
295
320
  }
296
321
  }, [isListening]);
297
322
  const stop = (0, import_react2.useCallback)(() => {
323
+ console.log("[useSpeechRecognition] stop() called");
298
324
  if (isSimulatingRef.current) {
299
325
  if (simulationTimeoutRef.current) {
300
326
  clearTimeout(simulationTimeoutRef.current);
@@ -308,11 +334,11 @@ var useSpeechRecognition = (onResult, onEnd, language = "en-US") => {
308
334
  if (onEndRef.current) onEndRef.current();
309
335
  return;
310
336
  }
311
- if (recognitionRef.current && isListening) {
337
+ if (recognitionRef.current) {
312
338
  recognitionRef.current.stop();
313
- } else {
339
+ console.log("[useSpeechRecognition] recognition.stop() executed");
314
340
  }
315
- }, [isListening, onResult, onEnd]);
341
+ }, []);
316
342
  const resetTranscript = (0, import_react2.useCallback)(() => {
317
343
  setTranscript("");
318
344
  }, []);
@@ -921,51 +947,70 @@ var TapToTalk = ({
921
947
  });
922
948
  const isListening = !!voiceTrigger || nativeSpeech.isListening || customRecorder.isRecording;
923
949
  const isActive = isListening || isTranscribing;
950
+ const processingRef = (0, import_react6.useRef)(false);
924
951
  const toggleVoice = async () => {
925
- const now = Date.now();
926
- if (now - tapCountRef.current.lastTap < 500) {
927
- tapCountRef.current.count++;
928
- } else {
929
- tapCountRef.current.count = 1;
930
- }
931
- tapCountRef.current.lastTap = now;
932
- if (tapCountRef.current.count >= 5) {
933
- setShowDebug((prev) => !prev);
934
- tapCountRef.current.count = 0;
935
- if (isActive) {
936
- if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
937
- else customRecorder.stop();
938
- setVoiceTrigger(null);
939
- }
952
+ if (processingRef.current) {
953
+ console.log("[TapToTalk] toggleVoice ignored - processing");
940
954
  return;
941
955
  }
942
- if (isActive) {
943
- if (isTranscribing && !isListening) return;
944
- if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") {
945
- nativeSpeech.stop();
956
+ processingRef.current = true;
957
+ console.log("[TapToTalk] toggleVoice called. isActive:", isActive);
958
+ try {
959
+ const now = Date.now();
960
+ if (now - tapCountRef.current.lastTap < 500) {
961
+ tapCountRef.current.count++;
946
962
  } else {
947
- customRecorder.stop();
963
+ tapCountRef.current.count = 1;
948
964
  }
949
- setVoiceTrigger(null);
950
- } else {
951
- setErrorMsg(null);
952
- onFocusTarget == null ? void 0 : onFocusTarget();
953
- setVoiceTrigger("click");
954
- if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "custom") {
955
- try {
956
- await customRecorder.start();
957
- } catch (e) {
958
- setErrorMsg("Mic access denied");
965
+ tapCountRef.current.lastTap = now;
966
+ if (tapCountRef.current.count >= 5) {
967
+ setShowDebug((prev) => !prev);
968
+ tapCountRef.current.count = 0;
969
+ if (isActive) {
970
+ console.log("[TapToTalk] Debug trigger force-stop");
971
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") nativeSpeech.stop();
972
+ else customRecorder.stop();
959
973
  setVoiceTrigger(null);
960
974
  }
961
- } else {
962
- if (!nativeSpeech.isSupported) {
963
- setErrorMsg("Speech not supported");
964
- setVoiceTrigger(null);
975
+ return;
976
+ }
977
+ if (isActive) {
978
+ if (isTranscribing && !isListening) {
979
+ console.log("[TapToTalk] Ignoring click during transcription");
965
980
  return;
966
981
  }
967
- nativeSpeech.start();
982
+ console.log("[TapToTalk] Stopping voice...");
983
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "native") {
984
+ nativeSpeech.stop();
985
+ } else {
986
+ customRecorder.stop();
987
+ }
988
+ setVoiceTrigger(null);
989
+ } else {
990
+ console.log("[TapToTalk] Starting voice...");
991
+ setErrorMsg(null);
992
+ onFocusTarget == null ? void 0 : onFocusTarget();
993
+ setVoiceTrigger("click");
994
+ if ((voiceConfig == null ? void 0 : voiceConfig.mode) === "custom") {
995
+ try {
996
+ await customRecorder.start();
997
+ } catch (e) {
998
+ setErrorMsg("Mic access denied");
999
+ setVoiceTrigger(null);
1000
+ }
1001
+ } else {
1002
+ if (!nativeSpeech.isSupported) {
1003
+ setErrorMsg("Speech not supported");
1004
+ setVoiceTrigger(null);
1005
+ return;
1006
+ }
1007
+ nativeSpeech.start();
1008
+ }
968
1009
  }
1010
+ } finally {
1011
+ setTimeout(() => {
1012
+ processingRef.current = false;
1013
+ }, 300);
969
1014
  }
970
1015
  };
971
1016
  let bgColor = accentColor;