@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.mjs CHANGED
@@ -2322,7 +2322,68 @@ class TemplateError extends BadRequestError {
2322
2322
  function findTemplateVars(html) {
2323
2323
  const variables = /* @__PURE__ */ new Set();
2324
2324
  const arrays = /* @__PURE__ */ new Set();
2325
- const excluded = /* @__PURE__ */ new Set(["true", "false", "null", "undefined"]);
2325
+ const excluded = /* @__PURE__ */ new Set([
2326
+ "let",
2327
+ "const",
2328
+ "var",
2329
+ "function",
2330
+ "if",
2331
+ "while",
2332
+ "do",
2333
+ "this",
2334
+ "typeof",
2335
+ "new",
2336
+ "instanceof",
2337
+ "in",
2338
+ "for",
2339
+ "else",
2340
+ "case",
2341
+ "break",
2342
+ "continue",
2343
+ "switch",
2344
+ "default",
2345
+ "with",
2346
+ "eval",
2347
+ "arguments",
2348
+ "void",
2349
+ "delete",
2350
+ "null",
2351
+ "undefined",
2352
+ "true",
2353
+ "false",
2354
+ "async",
2355
+ "await",
2356
+ "try",
2357
+ "catch",
2358
+ "finally",
2359
+ "throw",
2360
+ "return",
2361
+ "yield",
2362
+ "debugger",
2363
+ "extends",
2364
+ "import",
2365
+ "export",
2366
+ "class",
2367
+ "super",
2368
+ "static",
2369
+ "get",
2370
+ "set",
2371
+ "constructor",
2372
+ "enum",
2373
+ "implements",
2374
+ "interface",
2375
+ "package",
2376
+ "private",
2377
+ "protected",
2378
+ "public",
2379
+ "abstract",
2380
+ "final",
2381
+ "native",
2382
+ "synchronized",
2383
+ "throws",
2384
+ "transient",
2385
+ "volatile"
2386
+ ]);
2326
2387
  for (const loop of matchAll(html, /\{\{\s*?\*\s*?(.+?)\s+in\s+(.+?)\s*?}}/g)) {
2327
2388
  const [element, index = "index"] = loop[1].replaceAll(/[()\s]/g, "").split(",");
2328
2389
  excluded.add(element);
@@ -2533,6 +2594,7 @@ ${err.message || err.toString()}`);
2533
2594
  }
2534
2595
  class TTS {
2535
2596
  static QUALITY_PATTERNS = ["Google", "Microsoft", "Samantha", "Premium", "Natural", "Neural"];
2597
+ static _errorHandlerInstalled = false;
2536
2598
  _currentUtterance = null;
2537
2599
  _voicesLoaded;
2538
2600
  _stoppedUtterances = /* @__PURE__ */ new WeakSet();
@@ -2568,8 +2630,8 @@ class TTS {
2568
2630
  this._voice = value;
2569
2631
  if (this._currentUtterance && value) this._currentUtterance.voice = value;
2570
2632
  }
2571
- /** Create a TTS instance with optional configuration */
2572
2633
  constructor(config) {
2634
+ TTS.installErrorHandler();
2573
2635
  this._voicesLoaded = this.initializeVoices();
2574
2636
  if (config) {
2575
2637
  if (config.rate !== void 0) this._rate = config.rate;
@@ -2578,7 +2640,13 @@ class TTS {
2578
2640
  this._voice = config.voice === null ? void 0 : config.voice || void 0;
2579
2641
  }
2580
2642
  }
2581
- /** Initializes voice loading and sets default voice if needed */
2643
+ static installErrorHandler() {
2644
+ if (this._errorHandlerInstalled) return;
2645
+ window.addEventListener("unhandledrejection", (event) => {
2646
+ if (event.reason?.error === "interrupted" && event.reason instanceof SpeechSynthesisErrorEvent) event.preventDefault();
2647
+ });
2648
+ this._errorHandlerInstalled = true;
2649
+ }
2582
2650
  initializeVoices() {
2583
2651
  return new Promise((resolve) => {
2584
2652
  const voices = window.speechSynthesis.getVoices();
@@ -2595,11 +2663,6 @@ class TTS {
2595
2663
  }
2596
2664
  });
2597
2665
  }
2598
- /**
2599
- * Selects the best available TTS voice, prioritizing high-quality options
2600
- * @param lang Speaking language
2601
- * @returns Highest quality voice
2602
- */
2603
2666
  static bestVoice(lang = "en") {
2604
2667
  const voices = window.speechSynthesis.getVoices();
2605
2668
  for (const pattern of this.QUALITY_PATTERNS) {
@@ -2608,11 +2671,9 @@ class TTS {
2608
2671
  }
2609
2672
  return voices.find((v) => v.lang.startsWith(lang));
2610
2673
  }
2611
- /** Cleans text for TTS by removing emojis, markdown and code block */
2612
2674
  static cleanText(text) {
2613
2675
  return removeEmojis(text).replace(/```[\s\S]*?```/g, " code block ").replace(/[#*_~`]/g, "");
2614
2676
  }
2615
- /** Creates a speech utterance with current options */
2616
2677
  createUtterance(text) {
2617
2678
  const cleanedText = TTS.cleanText(text);
2618
2679
  const utterance = new SpeechSynthesisUtterance(cleanedText);
@@ -2623,7 +2684,6 @@ class TTS {
2623
2684
  utterance.volume = this._volume;
2624
2685
  return utterance;
2625
2686
  }
2626
- /** Speaks text and returns a Promise which resolves once complete */
2627
2687
  async speak(text) {
2628
2688
  if (!text.trim()) return Promise.resolve();
2629
2689
  await this._voicesLoaded;
@@ -2642,24 +2702,11 @@ class TTS {
2642
2702
  window.speechSynthesis.speak(utterance);
2643
2703
  });
2644
2704
  }
2645
- /** Stops all TTS */
2646
2705
  stop() {
2647
2706
  if (this._currentUtterance) this._stoppedUtterances.add(this._currentUtterance);
2648
2707
  window.speechSynthesis.cancel();
2649
2708
  this._currentUtterance = null;
2650
2709
  }
2651
- /**
2652
- * Initialize a stream that chunks text into sentences and speak them.
2653
- *
2654
- * @example
2655
- * const stream = tts.speakStream();
2656
- * stream.next("Hello ");
2657
- * stream.next("World. How");
2658
- * stream.next(" are you?");
2659
- * await stream.done();
2660
- *
2661
- * @returns Object with next function for passing chunk of streamed text and done for completing the stream
2662
- */
2663
2710
  speakStream() {
2664
2711
  let buffer = "";
2665
2712
  let streamPromise = Promise.resolve();