demowright 2.0.4 → 2.0.6

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/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as defaultOptions } from "./setup-x03ZBQi1.mjs";
1
+ import { n as defaultOptions } from "./setup-B6UqVosV.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  //#region src/config.ts
4
4
  /**
package/dist/helpers.mjs CHANGED
@@ -1,7 +1,30 @@
1
- import { c as isHudActive, d as storeAudioSegment, o as getTtsProvider, s as init_hud_registry } from "./hud-registry-D74THrir.mjs";
1
+ import { c as isHudActive, d as storeAudioSegment, o as getTtsProvider, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
2
2
  //#region src/helpers.ts
3
3
  init_hud_registry();
4
4
  /**
5
+ * Run `page.evaluate(fn, arg)` but bail out after `timeoutMs` if the page
6
+ * event loop is blocked (heavy SSR hydration, busy service worker, etc.).
7
+ *
8
+ * On timeout, logs a warning and resolves with `undefined` so recordings
9
+ * keep going instead of hitting the full Playwright test timeout. The
10
+ * underlying `page.evaluate` promise is left to settle on its own.
11
+ */
12
+ async function evaluateWithTimeout(page, fn, arg, timeoutMs = 1e4, label = "page.evaluate") {
13
+ let timer;
14
+ const evalPromise = page.evaluate(fn, arg);
15
+ evalPromise.catch(() => {});
16
+ try {
17
+ return await Promise.race([evalPromise, new Promise((resolve) => {
18
+ timer = setTimeout(() => {
19
+ console.warn(`[demowright] ${label} timed out after ${timeoutMs}ms — page event loop likely blocked. Skipping.`);
20
+ resolve(void 0);
21
+ }, timeoutMs);
22
+ })]);
23
+ } finally {
24
+ if (timer) clearTimeout(timer);
25
+ }
26
+ }
27
+ /**
5
28
  * Wait for `ms` milliseconds, but only when demowright is active.
6
29
  * Use this instead of `page.waitForTimeout()` for recording-only pauses.
7
30
  */
@@ -183,13 +206,7 @@ async function narrate(page, text, callbackOrOptions, callback) {
183
206
  else await playTtsAudio(page, wavBuf);
184
207
  return;
185
208
  } catch {}
186
- const opts = {
187
- rate: options?.rate ?? 1,
188
- pitch: options?.pitch ?? 1,
189
- volume: options?.volume ?? 1,
190
- voice: options?.voice
191
- };
192
- const speechPromise = page.evaluate(([t, o]) => {
209
+ const speechPromise = evaluateWithTimeout(page, ([t, o]) => {
193
210
  return new Promise((resolve) => {
194
211
  const synth = window.speechSynthesis;
195
212
  if (!synth) {
@@ -214,7 +231,12 @@ async function narrate(page, text, callbackOrOptions, callback) {
214
231
  resolve();
215
232
  }
216
233
  });
217
- }, [text, opts]);
234
+ }, [text, {
235
+ rate: options?.rate ?? 1,
236
+ pitch: options?.pitch ?? 1,
237
+ volume: options?.volume ?? 1,
238
+ voice: options?.voice
239
+ }], 1e4, "narrate(speechSynthesis)");
218
240
  if (cb) await Promise.all([speechPromise, cb()]);
219
241
  else await speechPromise;
220
242
  }
@@ -224,7 +246,7 @@ async function narrate(page, text, callbackOrOptions, callback) {
224
246
  */
225
247
  async function caption(page, text, durationMs = 3e3) {
226
248
  if (!await isHudActive(page)) return;
227
- await page.evaluate(([t, d]) => {
249
+ await evaluateWithTimeout(page, ([t, d]) => {
228
250
  const el = document.createElement("div");
229
251
  el.textContent = t;
230
252
  el.style.cssText = [
@@ -260,7 +282,7 @@ async function caption(page, text, durationMs = 3e3) {
260
282
  }
261
283
  document.body.appendChild(el);
262
284
  setTimeout(() => el.remove(), d);
263
- }, [text, durationMs]);
285
+ }, [text, durationMs], 1e4, "caption");
264
286
  }
265
287
  /** @deprecated Use `caption()` instead. */
266
288
  const subtitle = caption;
@@ -11,12 +11,17 @@ function registerHudPage(page, config) {
11
11
  */
12
12
  async function isHudActive(page) {
13
13
  if (hudPages.has(page)) return true;
14
+ let timer;
14
15
  try {
15
- const active = await page.evaluate(() => !!window.__qaHud);
16
+ const active = await Promise.race([page.evaluate(() => !!window.__qaHud).catch(() => false), new Promise((resolve) => {
17
+ timer = setTimeout(() => resolve(false), 5e3);
18
+ })]);
16
19
  if (active) hudPages.set(page, { tts: g.__qaHudGlobal.tts || false });
17
20
  return active;
18
21
  } catch {
19
22
  return false;
23
+ } finally {
24
+ if (timer) clearTimeout(timer);
20
25
  }
21
26
  }
22
27
  /**
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { r as AudioWriter, t as applyHud } from "./setup-x03ZBQi1.mjs";
2
- import { i as getGlobalTtsProvider, s as init_hud_registry } from "./hud-registry-D74THrir.mjs";
1
+ import { r as AudioWriter, t as applyHud } from "./setup-B6UqVosV.mjs";
2
+ import { i as getGlobalTtsProvider, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
3
3
  import { buildFfmpegCommand, createVideoScript, t as init_video_script } from "./video-script.mjs";
4
4
  import { annotate, caption, clickEl, hudWait, moveTo, moveToEl, narrate, subtitle, typeKeys } from "./helpers.mjs";
5
5
  import { installAutoAnnotate } from "./auto-annotate.mjs";
@@ -1,5 +1,5 @@
1
1
  import { r as __toCommonJS } from "./chunk-C0p4GxOx.mjs";
2
- import { a as getRenderJob, l as registerHudPage, n as getCurrentSpec, s as init_hud_registry, t as getAudioSegments, u as setGlobalOutputDir } from "./hud-registry-D74THrir.mjs";
2
+ import { a as getRenderJob, l as registerHudPage, n as getCurrentSpec, s as init_hud_registry, t as getAudioSegments, u as setGlobalOutputDir } from "./hud-registry-Wfd4b4Nu.mjs";
3
3
  import { n as video_script_exports, t as init_video_script } from "./video-script.mjs";
4
4
  import { execSync } from "node:child_process";
5
5
  import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
package/dist/setup.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as defaultOptions, t as applyHud } from "./setup-x03ZBQi1.mjs";
1
+ import { n as defaultOptions, t as applyHud } from "./setup-B6UqVosV.mjs";
2
2
  export { applyHud, defaultOptions };
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll, t as __esmMin } from "./chunk-C0p4GxOx.mjs";
2
- import { c as isHudActive, d as storeAudioSegment, f as storeRenderJob, i as getGlobalTtsProvider, o as getTtsProvider, r as getGlobalOutputDir, s as init_hud_registry } from "./hud-registry-D74THrir.mjs";
2
+ import { c as isHudActive, d as storeAudioSegment, f as storeRenderJob, i as getGlobalTtsProvider, o as getTtsProvider, r as getGlobalOutputDir, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
3
3
  import { mkdirSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  //#region src/video-script.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "demowright",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "Playwright video production plugin — cursor overlay, keystroke badges, TTS narration, and narration-driven video scripts for test recordings",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,7 +45,6 @@
45
45
  "prepublishOnly": "tsdown"
46
46
  },
47
47
  "devDependencies": {
48
- "@playwright/test": "^1.52.0",
49
48
  "@types/node": "^25.5.2",
50
49
  "@typescript/native-preview": "^7.0.0-dev.20260405.1",
51
50
  "semantic-release": "^25.0.3",