@designesy/read-along 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@designesy/read-along",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Embeddable bimodal read-along web component: karaoke-sync word highlighting with pluggable TTS engines (Web Speech, pre-synthesized audio, or your own).",
5
5
  "type": "module",
6
6
  "main": "src/read-along.js",
@@ -26,7 +26,10 @@ const CHARS_PER_SEC = 14.5; // ~150 wpm × ~5.8 chars/word, heuristic at rate 1
26
26
 
27
27
  export class WebSpeechEngine {
28
28
  constructor(options = {}) {
29
- this.lang = options.lang ?? navigator.language ?? "en-US";
29
+ // navigator is NOT a global on Node < 21, and this engine must be
30
+ // constructible outside a browser (the component imports it
31
+ // unconditionally). Read it defensively rather than assuming a DOM.
32
+ this.lang = options.lang ?? (typeof navigator !== "undefined" ? navigator.language : null) ?? "en-US";
30
33
  this.rate = options.rate ?? 1;
31
34
  this.pitch = options.pitch ?? 1;
32
35
  this.voiceName = options.voiceName ?? null;
@@ -341,7 +344,8 @@ export class WebSpeechEngine {
341
344
  // Desktop-Chrome-only belt-and-suspenders for the ~15s watchdog
342
345
  // (chromium:41294170). On Android, pause()/resume() mid-utterance
343
346
  // breaks synthesis entirely — sentence chunking alone is the fix there.
344
- if (/Android/i.test(navigator.userAgent)) return;
347
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
348
+ if (/Android/i.test(ua)) return;
345
349
  this._keepalive = setInterval(() => {
346
350
  if (this._stopped || this._paused || this._visualOnly) return;
347
351
  if (speechSynthesis.speaking && !speechSynthesis.paused) {