demowright 2.4.0 → 2.6.0

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.
@@ -20,6 +20,8 @@ interface SegmentStep {
20
20
  kind: "segment";
21
21
  text: string;
22
22
  action?: SegmentAction;
23
+ /** Runs BEFORE narration starts — use for navigation, page.goto(), scrolls, etc. */
24
+ setup?: () => Promise<void>;
23
25
  }
24
26
  interface TransitionStep {
25
27
  kind: "transition";
@@ -104,9 +106,18 @@ declare class VideoScriptImpl {
104
106
  title(text: string, opts?: TitleOptions): this;
105
107
  /**
106
108
  * Add a narrated segment — TTS audio drives timing, callback runs paced actions.
107
- * Same as NarrationPlan's `.annotate()` but named `.segment()` for clarity.
109
+ *
110
+ * Two signatures (backwards-compatible):
111
+ * .segment("narration", async (pace) => { ... })
112
+ * .segment("narration", { setup: async () => { ... }, action: async (pace) => { ... } })
113
+ *
114
+ * `setup` runs BEFORE narration starts — use for page.goto(), scrolling, etc.
115
+ * `action` runs DURING narration — use for visual actions like safeMove, hover.
108
116
  */
109
- segment(text: string, action?: SegmentAction): this;
117
+ segment(text: string, actionOrOpts?: SegmentAction | {
118
+ setup?: () => Promise<void>;
119
+ action?: SegmentAction;
120
+ }): this;
110
121
  /**
111
122
  * Add a transition between segments.
112
123
  * Applied as an ffmpeg filter during render.
@@ -282,13 +282,29 @@ var init_video_script = __esmMin((() => {
282
282
  }
283
283
  /**
284
284
  * Add a narrated segment — TTS audio drives timing, callback runs paced actions.
285
- * Same as NarrationPlan's `.annotate()` but named `.segment()` for clarity.
285
+ *
286
+ * Two signatures (backwards-compatible):
287
+ * .segment("narration", async (pace) => { ... })
288
+ * .segment("narration", { setup: async () => { ... }, action: async (pace) => { ... } })
289
+ *
290
+ * `setup` runs BEFORE narration starts — use for page.goto(), scrolling, etc.
291
+ * `action` runs DURING narration — use for visual actions like safeMove, hover.
286
292
  */
287
- segment(text, action) {
288
- this.steps.push({
293
+ segment(text, actionOrOpts) {
294
+ if (typeof actionOrOpts === "function") this.steps.push({
295
+ kind: "segment",
296
+ text,
297
+ action: actionOrOpts
298
+ });
299
+ else if (actionOrOpts && typeof actionOrOpts === "object") this.steps.push({
289
300
  kind: "segment",
290
301
  text,
291
- action
302
+ action: actionOrOpts.action,
303
+ setup: actionOrOpts.setup
304
+ });
305
+ else this.steps.push({
306
+ kind: "segment",
307
+ text
292
308
  });
293
309
  return this;
294
310
  }
@@ -459,7 +475,7 @@ var init_video_script = __esmMin((() => {
459
475
  let segmentIndex = 0;
460
476
  for (let i = 0; i < this.steps.length; i++) {
461
477
  const step = this.steps[i];
462
- const stepStartMs = Date.now();
478
+ let stepStartMs = Date.now();
463
479
  if (step.kind === "title" || step.kind === "outro") {
464
480
  const bg = step.background ?? DEFAULT_BG;
465
481
  const cardTts = step.narration ? this.prepared.get(`card-${i}`) : void 0;
@@ -499,6 +515,10 @@ var init_video_script = __esmMin((() => {
499
515
  overrunMs: 0
500
516
  });
501
517
  } else if (step.kind === "segment") {
518
+ if (step.setup) {
519
+ await step.setup();
520
+ stepStartMs = Date.now();
521
+ }
502
522
  const segId = `step-${segmentIndex}`;
503
523
  segmentIndex++;
504
524
  const segment = this.prepared.get(segId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "demowright",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
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": {