@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 +9 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +9 -23
- package/dist/index.mjs.map +1 -1
- package/dist/tts.d.ts +2 -23
- package/package.json +1 -1
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
|
-
|
|
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();
|