@lightcone-ai/daemon 0.14.16 → 0.14.17

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": "@lightcone-ai/daemon",
3
- "version": "0.14.16",
3
+ "version": "0.14.17",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@ import {
11
11
  stopFfmpegCapture,
12
12
  waitForProcessExit,
13
13
  } from './ffmpeg-runner.js';
14
+ import { estimatePlanDurationMs } from './plan-estimator.js';
14
15
  import { executePlanPhases, normalizePlanPhases } from './plan-executor.js';
15
16
 
16
17
  const DEFAULT_VIEWPORT = Object.freeze({ width: 1080, height: 1920 });
@@ -64,47 +65,6 @@ function resolveUrl({ url, plan }) {
64
65
  throw error;
65
66
  }
66
67
 
67
- function estimatePlanDurationMs(plan = {}) {
68
- let phases = [];
69
- try {
70
- phases = normalizePlanPhases(plan);
71
- } catch {
72
- phases = [];
73
- }
74
-
75
- return phases.reduce((total, phase) => {
76
- const action = String(phase?.action ?? phase?.visual_action?.type ?? '').trim().toLowerCase();
77
- const durationMs = Number(phase?.duration_ms);
78
- const dwellMs = Number(phase?.dwell_ms);
79
- const transitionMs = Number(phase?.transition_ms ?? phase?.visual_action?.transition_ms);
80
- const effectiveHoldMs = Number.isFinite(dwellMs) && dwellMs > 0
81
- ? dwellMs
82
- : durationMs;
83
-
84
- if (action === 'hold' && Number.isFinite(effectiveHoldMs) && effectiveHoldMs > 0) {
85
- return total + effectiveHoldMs;
86
- }
87
- if (action === 'linear_scroll_during') {
88
- if (Number.isFinite(effectiveHoldMs) && effectiveHoldMs > 0) return total + effectiveHoldMs;
89
- return total + 1200;
90
- }
91
- if (action === 'scroll_to_dwell' || action === 'cursor_focus' || action === 'scroll_back') {
92
- let next = total;
93
- if (Number.isFinite(transitionMs) && transitionMs > 0) next += transitionMs;
94
- if (Number.isFinite(effectiveHoldMs) && effectiveHoldMs > 0) next += effectiveHoldMs;
95
- if (next === total) next += 1200;
96
- return next;
97
- }
98
- if (Number.isFinite(transitionMs) && transitionMs > 0) {
99
- return total + transitionMs;
100
- }
101
- if (Number.isFinite(durationMs) && durationMs > 0) {
102
- return total + durationMs;
103
- }
104
- return total + 800;
105
- }, 0);
106
- }
107
-
108
68
  function createXvfbExitError({ code, signal, stderr }) {
109
69
  const error = new Error(`xvfb_exited_unexpectedly:code=${code ?? 'null'}:signal=${signal ?? 'none'}`);
110
70
  error.code = 'XVFB_EXITED_UNEXPECTEDLY';
@@ -1,3 +1,5 @@
1
+ import { resolveDurationMs } from './phase-duration.js';
2
+
1
3
  function normalizeText(value) {
2
4
  if (typeof value !== 'string') return '';
3
5
  return value.trim();
@@ -85,16 +87,6 @@ function nowMs(getNowMs) {
85
87
  return Number(getNowMs?.()) || Date.now();
86
88
  }
87
89
 
88
- function resolveDurationMs(phase, fallback = 0) {
89
- const parsed = normalizeInteger(phase?.duration_ms, null);
90
- if (parsed !== null && parsed >= 0) return parsed;
91
- const dwellMs = normalizeInteger(phase?.dwell_ms, null);
92
- if (dwellMs !== null && dwellMs >= 0) return dwellMs;
93
- const secs = Number(phase?.duration_s);
94
- if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1000);
95
- return fallback;
96
- }
97
-
98
90
  function resolveTransitionMs(phase, fallback) {
99
91
  const parsed = normalizeInteger(phase?.transition_ms, null);
100
92
  if (parsed !== null && parsed >= 0) return parsed;