@hyperframes/producer 0.9.19 → 0.9.21

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.
@@ -12,6 +12,7 @@ export interface DistributedRenderOptions {
12
12
  chunkSize?: number;
13
13
  maxParallelChunks?: number;
14
14
  targetChunkFrames?: number;
15
+ minParallelChunks?: number;
15
16
  runtimeCap?: DistributedRenderConfig["runtimeCap"];
16
17
  rejectOnSystemFonts?: boolean;
17
18
  failClosedFontFetch?: boolean;
@@ -104,17 +104,19 @@ export interface DistributedRenderConfig extends Pick<RenderRequestOptions, "pag
104
104
  * chunks whose per-chunk frame count stays at or below this bound, still
105
105
  * capped by `maxParallelChunks`:
106
106
  *
107
- * chunkCount = clamp(ceil(totalFrames / targetChunkFrames), 1, maxParallelChunks)
107
+ * chunkCount = clamp(ceil(totalFrames / targetChunkFrames), minParallelChunks, maxParallelChunks)
108
108
  *
109
109
  * This bounds per-chunk render *time* (which scales with frames-per-chunk) so
110
110
  * a single chunk can't exceed a downstream per-chunk timeout on a long video,
111
- * while short videos still collapse to few chunks. It is a ceiling, not a
111
+ * while short videos drop to `minParallelChunks` (default 1). It is a ceiling, not a
112
112
  * fixed size: a video short enough to fit in fewer chunks gets fewer. Ignored
113
113
  * when `chunkSize` is set (an explicit fixed size already pins per-chunk
114
114
  * frames). Mutually exclusive with `chunkSize` in intent; if both are passed,
115
115
  * `chunkSize` wins and `targetChunkFrames` is a no-op.
116
116
  */
117
117
  targetChunkFrames?: number;
118
+ /** Fewest chunks a `targetChunkFrames`-sized plan uses, so a short video keeps this fan-out. */
119
+ minParallelChunks?: number;
118
120
  /** Runtime hint; consumed by future per-runtime budget checks. The current implementation records the value but does not enforce. */
119
121
  runtimeCap?: "lambda" | "temporal" | "cloud-run-job" | "k8s-job" | "none";
120
122
  /**
@@ -397,12 +399,12 @@ export declare function measurePlanDirBytes(planDir: string): number;
397
399
  * on tiny renders). Explicit numbers, including `240`, take precedence.
398
400
  *
399
401
  * Optional `targetChunkFrames` caps per-chunk frames in the auto-sized path:
400
- * the auto-sizer then targets `clamp(ceil(totalFrames / targetChunkFrames), 1,
401
- * maxParallelChunks)` chunks, so short videos collapse to fewer chunks and long
402
+ * the auto-sizer then targets `clamp(ceil(totalFrames / targetChunkFrames), minParallelChunks,
403
+ * maxParallelChunks)` chunks, so short videos drop to `minParallelChunks` and long
402
404
  * videos add chunks (up to the cap) to keep each one under the bound. It is a
403
405
  * no-op when omitted, and ignored when `configChunkSize` is set.
404
406
  */
405
- export declare function resolveChunkPlan(totalFrames: number, configChunkSize: number | undefined, maxParallelChunks: number, targetChunkFrames?: number): {
407
+ export declare function resolveChunkPlan(totalFrames: number, configChunkSize: number | undefined, maxParallelChunks: number, targetChunkFrames?: number, minParallelChunks?: number): {
406
408
  chunkCount: number;
407
409
  effectiveChunkSize: number;
408
410
  };
@@ -95,9 +95,9 @@ export interface VirtualTimeShimOptions {
95
95
  /**
96
96
  * Build the page-side virtual-time shim script.
97
97
  *
98
- * The shim freezes `Date.now`, `performance.now`, and the rAF/setTimeout
99
- * pipeline so a render seek can deterministically advance the page's
100
- * notion of "now". The renderer issues `__HF_VIRTUAL_TIME__.seekToTime(ms)`
98
+ * The shim freezes `Date.now`, `performance.now`, rAF, and the timers set
99
+ * after the first seek, so a render seek can deterministically advance the
100
+ * page's notion of "now". The renderer issues `__HF_VIRTUAL_TIME__.seekToTime(ms)`
101
101
  * before every frame capture; everything timing-related on the page sees
102
102
  * exactly `ms` until the next seek.
103
103
  *
@@ -44,16 +44,26 @@ import type { ProducerLogger } from "../../../logger.js";
44
44
  import type { ProgressCallback, RenderJob } from "../../renderOrchestrator.js";
45
45
  import type { SdrStreamingCapturePlan } from "../capturePlan.js";
46
46
  export declare function resolveCaptureStallTimeoutMs(): number;
47
- type StalledSession = {
47
+ export type StalledSession = {
48
48
  captureMode: CaptureSession["captureMode"];
49
49
  captureStep?: string;
50
50
  };
51
+ export declare const OPENING_CAPTURE_SESSION: StalledSession;
51
52
  export declare function raceAgainstStall<T>(promise: Promise<T>, deadlineMs: number, input: {
52
53
  session: StalledSession;
53
54
  frameIndex: number;
54
55
  totalFrames: number;
55
56
  stallTimeoutMs: number;
56
57
  }, signal?: AbortSignal): Promise<T>;
58
+ /**
59
+ * The setup budget for opening a session, initializing it, and the deferred drawElement init.
60
+ * It bounds each step, not setup as a whole: the clock drops a step longer than its suspend gap.
61
+ */
62
+ export declare function createSessionInitBudget(input: {
63
+ frameIndex: number;
64
+ totalFrames: number;
65
+ abortSignal: AbortSignal | undefined;
66
+ }): <T>(work: Promise<T>, stalled: StalledSession) => Promise<T>;
57
67
  /**
58
68
  * Pre-built ffmpeg streaming-encoder options, exactly matching the
59
69
  * second argument to `spawnStreamingEncoder`. The sequencer constructs
@@ -135,4 +145,3 @@ export declare function verifyDrawElementSample(session: CaptureSession, idx: nu
135
145
  verifyMinDb: number;
136
146
  }): Promise<void>;
137
147
  export declare function runCaptureStreamingStage(input: CaptureStreamingStageInput): Promise<CaptureStreamingStageResult>;
138
- export {};
@@ -1,5 +1,5 @@
1
1
  import { type CanvasResolution, type Fps, type FpsInput, type HfVfxCapture } from "@hyperframes/core";
2
- import { type EngineConfig, type ExtractionPhaseBreakdown, type VideoFrameFormat, type CaptureOptions, type CaptureVideoMetadataHint, type CaptureSession, type BeforeCaptureHook, type ProresProfile, type ParallelProgress, type WorkerTask, type CapturePerfSummary, type CaptureWarning, type SubTimelineWaitOutcome, type WorkerSizing, type StaticVerificationOutcome, explainDrawElementDisabled, type CaptureFailureKind, displaySize, type MotionBlurOptions } from "@hyperframes/engine";
2
+ import { type EngineConfig, type ExtractionPhaseBreakdown, type VideoFrameFormat, type CaptureOptions, type CaptureVideoMetadataHint, type CaptureSession, type BeforeCaptureHook, type ProresProfile, type ParallelProgress, type WorkerTask, type CapturePerfSummary, type CaptureWarning, type SubTimelineWaitOutcome, type WorkerSizing, type StaticVerificationOutcome, explainDrawElementDisabled, type CaptureFailureKind, displaySize, type MotionBlurOptions, type PageMotionBlurSummary } from "@hyperframes/engine";
3
3
  import { type ReferenceBackgroundResult } from "@hyperframes/engine";
4
4
  import { type ProducerLogger } from "../logger.js";
5
5
  import { type RenderOutputFormat } from "./render/renderFormat.js";
@@ -286,6 +286,7 @@ export interface RenderPerfSummary {
286
286
  noDamageFrames: number;
287
287
  hasDamageFrames: number;
288
288
  };
289
+ motionBlur?: PageMotionBlurSummary;
289
290
  /**
290
291
  * drawElement fast-capture outcome for this render (default-on release
291
292
  * visibility). Undefined when no capture session ran.
@@ -335,7 +336,7 @@ export interface RenderPerfSummary {
335
336
  parallelRouter?: string;
336
337
  /** Worker count the auto-resolution chose BEFORE the router pinned it to 3 — the single-worker-inversion counterfactual. Only set when the router fired. */
337
338
  preRouterWorkers?: number;
338
- /** Engine init-time gate: swiftshader | css_effect:* | at_risk_timeline | 3d_init_failed | supersampling | render_mode_hint. */
339
+ /** Engine init-time gate: swiftshader | webgl_unavailable | beginframe_no_self_verify | css_effect:* | at_risk_timeline | 3d_init_failed | supersampling | render_mode_hint. */
339
340
  gateReason?: string;
340
341
  /** Low-cardinality GPU bucket from DE session init (`<backend>/<vendor>`, e.g. `d3d11/nvidia`); |-joined across parallel sessions (bounded: one bucket per distinct backend on the host). */
341
342
  gpuRenderer?: string;
@@ -51,4 +51,6 @@ export declare function toExternalAssetKey(absPath: string): string;
51
51
  export declare function formatCaptureFrameName(index: number, ext: string): string;
52
52
  export declare function formatExportFrameName(index: number, ext: string): string;
53
53
  export declare function resolveRenderPaths(projectDir: string, outputPath: string | null | undefined, rendersDir?: string): RenderPaths;
54
+ /** The project file a data-composition-src names, as the preview reads it; null when it leaves the project. */
55
+ export declare function resolveCompositionSrc(projectDir: string, src: string): string | null;
54
56
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/producer",
3
- "version": "0.9.19",
3
+ "version": "0.9.21",
4
4
  "description": "HTML-to-video rendering engine using Chrome's BeginFrame API",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,11 +35,11 @@
35
35
  "postcss": "^8.4.0",
36
36
  "puppeteer": "~25.11.0",
37
37
  "puppeteer-core": "^25.11.0",
38
- "@hyperframes/core": "0.9.19",
39
- "@hyperframes/engine": "0.9.19",
40
- "@hyperframes/parsers": "0.9.19",
41
- "@hyperframes/lint": "0.9.19",
42
- "@hyperframes/studio-server": "0.9.19"
38
+ "@hyperframes/engine": "0.9.21",
39
+ "@hyperframes/parsers": "0.9.21",
40
+ "@hyperframes/studio-server": "0.9.21",
41
+ "@hyperframes/lint": "0.9.21",
42
+ "@hyperframes/core": "0.9.21"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^25.0.10",
@@ -48,7 +48,7 @@
48
48
  "tsx": "^4.21.0",
49
49
  "typescript": "^5.7.2",
50
50
  "vitest": "^4.1.11",
51
- "@hyperframes/aws-lambda": "0.9.19"
51
+ "@hyperframes/aws-lambda": "0.9.21"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=22"