@ztimson/utils 0.28.11 → 0.28.12

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/dist/index.cjs CHANGED
@@ -2537,6 +2537,7 @@ ${err.message || err.toString()}`);
2537
2537
  }
2538
2538
  class TTS {
2539
2539
  static QUALITY_PATTERNS = ["Google", "Microsoft", "Samantha", "Premium", "Natural", "Neural"];
2540
+ static _errorHandlerInstalled = false;
2540
2541
  _currentUtterance = null;
2541
2542
  _voicesLoaded;
2542
2543
  _stoppedUtterances = /* @__PURE__ */ new WeakSet();
@@ -2572,8 +2573,8 @@ ${err.message || err.toString()}`);
2572
2573
  this._voice = value;
2573
2574
  if (this._currentUtterance && value) this._currentUtterance.voice = value;
2574
2575
  }
2575
- /** Create a TTS instance with optional configuration */
2576
2576
  constructor(config) {
2577
+ TTS.installErrorHandler();
2577
2578
  this._voicesLoaded = this.initializeVoices();
2578
2579
  if (config) {
2579
2580
  if (config.rate !== void 0) this._rate = config.rate;
@@ -2582,7 +2583,13 @@ ${err.message || err.toString()}`);
2582
2583
  this._voice = config.voice === null ? void 0 : config.voice || void 0;
2583
2584
  }
2584
2585
  }
2585
- /** Initializes voice loading and sets default voice if needed */
2586
+ static installErrorHandler() {
2587
+ if (this._errorHandlerInstalled) return;
2588
+ window.addEventListener("unhandledrejection", (event) => {
2589
+ if (event.reason?.error === "interrupted" && event.reason instanceof SpeechSynthesisErrorEvent) event.preventDefault();
2590
+ });
2591
+ this._errorHandlerInstalled = true;
2592
+ }
2586
2593
  initializeVoices() {
2587
2594
  return new Promise((resolve) => {
2588
2595
  const voices = window.speechSynthesis.getVoices();
@@ -2599,11 +2606,6 @@ ${err.message || err.toString()}`);
2599
2606
  }
2600
2607
  });
2601
2608
  }
2602
- /**
2603
- * Selects the best available TTS voice, prioritizing high-quality options
2604
- * @param lang Speaking language
2605
- * @returns Highest quality voice
2606
- */
2607
2609
  static bestVoice(lang = "en") {
2608
2610
  const voices = window.speechSynthesis.getVoices();
2609
2611
  for (const pattern of this.QUALITY_PATTERNS) {
@@ -2612,11 +2614,9 @@ ${err.message || err.toString()}`);
2612
2614
  }
2613
2615
  return voices.find((v) => v.lang.startsWith(lang));
2614
2616
  }
2615
- /** Cleans text for TTS by removing emojis, markdown and code block */
2616
2617
  static cleanText(text) {
2617
2618
  return removeEmojis(text).replace(/```[\s\S]*?```/g, " code block ").replace(/[#*_~`]/g, "");
2618
2619
  }
2619
- /** Creates a speech utterance with current options */
2620
2620
  createUtterance(text) {
2621
2621
  const cleanedText = TTS.cleanText(text);
2622
2622
  const utterance = new SpeechSynthesisUtterance(cleanedText);
@@ -2627,7 +2627,6 @@ ${err.message || err.toString()}`);
2627
2627
  utterance.volume = this._volume;
2628
2628
  return utterance;
2629
2629
  }
2630
- /** Speaks text and returns a Promise which resolves once complete */
2631
2630
  async speak(text) {
2632
2631
  if (!text.trim()) return Promise.resolve();
2633
2632
  await this._voicesLoaded;
@@ -2646,24 +2645,11 @@ ${err.message || err.toString()}`);
2646
2645
  window.speechSynthesis.speak(utterance);
2647
2646
  });
2648
2647
  }
2649
- /** Stops all TTS */
2650
2648
  stop() {
2651
2649
  if (this._currentUtterance) this._stoppedUtterances.add(this._currentUtterance);
2652
2650
  window.speechSynthesis.cancel();
2653
2651
  this._currentUtterance = null;
2654
2652
  }
2655
- /**
2656
- * Initialize a stream that chunks text into sentences and speak them.
2657
- *
2658
- * @example
2659
- * const stream = tts.speakStream();
2660
- * stream.next("Hello ");
2661
- * stream.next("World. How");
2662
- * stream.next(" are you?");
2663
- * await stream.done();
2664
- *
2665
- * @returns Object with next function for passing chunk of streamed text and done for completing the stream
2666
- */
2667
2653
  speakStream() {
2668
2654
  let buffer = "";
2669
2655
  let streamPromise = Promise.resolve();