@ztimson/utils 0.28.11 → 0.28.13

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
@@ -2326,7 +2326,68 @@ ${opts.message || this.desc}`;
2326
2326
  function findTemplateVars(html) {
2327
2327
  const variables = /* @__PURE__ */ new Set();
2328
2328
  const arrays = /* @__PURE__ */ new Set();
2329
- const excluded = /* @__PURE__ */ new Set(["true", "false", "null", "undefined"]);
2329
+ const excluded = /* @__PURE__ */ new Set([
2330
+ "let",
2331
+ "const",
2332
+ "var",
2333
+ "function",
2334
+ "if",
2335
+ "while",
2336
+ "do",
2337
+ "this",
2338
+ "typeof",
2339
+ "new",
2340
+ "instanceof",
2341
+ "in",
2342
+ "for",
2343
+ "else",
2344
+ "case",
2345
+ "break",
2346
+ "continue",
2347
+ "switch",
2348
+ "default",
2349
+ "with",
2350
+ "eval",
2351
+ "arguments",
2352
+ "void",
2353
+ "delete",
2354
+ "null",
2355
+ "undefined",
2356
+ "true",
2357
+ "false",
2358
+ "async",
2359
+ "await",
2360
+ "try",
2361
+ "catch",
2362
+ "finally",
2363
+ "throw",
2364
+ "return",
2365
+ "yield",
2366
+ "debugger",
2367
+ "extends",
2368
+ "import",
2369
+ "export",
2370
+ "class",
2371
+ "super",
2372
+ "static",
2373
+ "get",
2374
+ "set",
2375
+ "constructor",
2376
+ "enum",
2377
+ "implements",
2378
+ "interface",
2379
+ "package",
2380
+ "private",
2381
+ "protected",
2382
+ "public",
2383
+ "abstract",
2384
+ "final",
2385
+ "native",
2386
+ "synchronized",
2387
+ "throws",
2388
+ "transient",
2389
+ "volatile"
2390
+ ]);
2330
2391
  for (const loop of matchAll(html, /\{\{\s*?\*\s*?(.+?)\s+in\s+(.+?)\s*?}}/g)) {
2331
2392
  const [element, index = "index"] = loop[1].replaceAll(/[()\s]/g, "").split(",");
2332
2393
  excluded.add(element);
@@ -2537,6 +2598,7 @@ ${err.message || err.toString()}`);
2537
2598
  }
2538
2599
  class TTS {
2539
2600
  static QUALITY_PATTERNS = ["Google", "Microsoft", "Samantha", "Premium", "Natural", "Neural"];
2601
+ static _errorHandlerInstalled = false;
2540
2602
  _currentUtterance = null;
2541
2603
  _voicesLoaded;
2542
2604
  _stoppedUtterances = /* @__PURE__ */ new WeakSet();
@@ -2572,8 +2634,8 @@ ${err.message || err.toString()}`);
2572
2634
  this._voice = value;
2573
2635
  if (this._currentUtterance && value) this._currentUtterance.voice = value;
2574
2636
  }
2575
- /** Create a TTS instance with optional configuration */
2576
2637
  constructor(config) {
2638
+ TTS.installErrorHandler();
2577
2639
  this._voicesLoaded = this.initializeVoices();
2578
2640
  if (config) {
2579
2641
  if (config.rate !== void 0) this._rate = config.rate;
@@ -2582,7 +2644,13 @@ ${err.message || err.toString()}`);
2582
2644
  this._voice = config.voice === null ? void 0 : config.voice || void 0;
2583
2645
  }
2584
2646
  }
2585
- /** Initializes voice loading and sets default voice if needed */
2647
+ static installErrorHandler() {
2648
+ if (this._errorHandlerInstalled) return;
2649
+ window.addEventListener("unhandledrejection", (event) => {
2650
+ if (event.reason?.error === "interrupted" && event.reason instanceof SpeechSynthesisErrorEvent) event.preventDefault();
2651
+ });
2652
+ this._errorHandlerInstalled = true;
2653
+ }
2586
2654
  initializeVoices() {
2587
2655
  return new Promise((resolve) => {
2588
2656
  const voices = window.speechSynthesis.getVoices();
@@ -2599,11 +2667,6 @@ ${err.message || err.toString()}`);
2599
2667
  }
2600
2668
  });
2601
2669
  }
2602
- /**
2603
- * Selects the best available TTS voice, prioritizing high-quality options
2604
- * @param lang Speaking language
2605
- * @returns Highest quality voice
2606
- */
2607
2670
  static bestVoice(lang = "en") {
2608
2671
  const voices = window.speechSynthesis.getVoices();
2609
2672
  for (const pattern of this.QUALITY_PATTERNS) {
@@ -2612,11 +2675,9 @@ ${err.message || err.toString()}`);
2612
2675
  }
2613
2676
  return voices.find((v) => v.lang.startsWith(lang));
2614
2677
  }
2615
- /** Cleans text for TTS by removing emojis, markdown and code block */
2616
2678
  static cleanText(text) {
2617
2679
  return removeEmojis(text).replace(/```[\s\S]*?```/g, " code block ").replace(/[#*_~`]/g, "");
2618
2680
  }
2619
- /** Creates a speech utterance with current options */
2620
2681
  createUtterance(text) {
2621
2682
  const cleanedText = TTS.cleanText(text);
2622
2683
  const utterance = new SpeechSynthesisUtterance(cleanedText);
@@ -2627,7 +2688,6 @@ ${err.message || err.toString()}`);
2627
2688
  utterance.volume = this._volume;
2628
2689
  return utterance;
2629
2690
  }
2630
- /** Speaks text and returns a Promise which resolves once complete */
2631
2691
  async speak(text) {
2632
2692
  if (!text.trim()) return Promise.resolve();
2633
2693
  await this._voicesLoaded;
@@ -2646,24 +2706,11 @@ ${err.message || err.toString()}`);
2646
2706
  window.speechSynthesis.speak(utterance);
2647
2707
  });
2648
2708
  }
2649
- /** Stops all TTS */
2650
2709
  stop() {
2651
2710
  if (this._currentUtterance) this._stoppedUtterances.add(this._currentUtterance);
2652
2711
  window.speechSynthesis.cancel();
2653
2712
  this._currentUtterance = null;
2654
2713
  }
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
2714
  speakStream() {
2668
2715
  let buffer = "";
2669
2716
  let streamPromise = Promise.resolve();