@memberjunction/video-studio-render-worker 0.0.1-seed.1 → 6.2.0-edge.7

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.
Files changed (59) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +139 -4
  3. package/assets/fonts/Inter-OFL.txt +93 -0
  4. package/assets/fonts/Inter-Regular.ttf +0 -0
  5. package/assets/fonts/JetBrainsMono-OFL.txt +93 -0
  6. package/assets/fonts/JetBrainsMono-Regular.ttf +0 -0
  7. package/dist/backend.d.ts +201 -0
  8. package/dist/backend.d.ts.map +1 -0
  9. package/dist/backend.js +205 -0
  10. package/dist/backend.js.map +1 -0
  11. package/dist/bundle.d.ts +112 -0
  12. package/dist/bundle.d.ts.map +1 -0
  13. package/dist/bundle.js +433 -0
  14. package/dist/bundle.js.map +1 -0
  15. package/dist/checks/dom-rules.d.ts +57 -0
  16. package/dist/checks/dom-rules.d.ts.map +1 -0
  17. package/dist/checks/dom-rules.js +205 -0
  18. package/dist/checks/dom-rules.js.map +1 -0
  19. package/dist/checks/hyperframes-check.d.ts +37 -0
  20. package/dist/checks/hyperframes-check.d.ts.map +1 -0
  21. package/dist/checks/hyperframes-check.js +161 -0
  22. package/dist/checks/hyperframes-check.js.map +1 -0
  23. package/dist/checks/static-checks.d.ts +46 -0
  24. package/dist/checks/static-checks.d.ts.map +1 -0
  25. package/dist/checks/static-checks.js +681 -0
  26. package/dist/checks/static-checks.js.map +1 -0
  27. package/dist/hyperframes-backend.d.ts +53 -0
  28. package/dist/hyperframes-backend.d.ts.map +1 -0
  29. package/dist/hyperframes-backend.js +733 -0
  30. package/dist/hyperframes-backend.js.map +1 -0
  31. package/dist/index.d.ts +20 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +20 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/jobs.d.ts +88 -0
  36. package/dist/jobs.d.ts.map +1 -0
  37. package/dist/jobs.js +650 -0
  38. package/dist/jobs.js.map +1 -0
  39. package/dist/lint-gate.d.ts +21 -0
  40. package/dist/lint-gate.d.ts.map +1 -0
  41. package/dist/lint-gate.js +528 -0
  42. package/dist/lint-gate.js.map +1 -0
  43. package/dist/main.d.ts +47 -0
  44. package/dist/main.d.ts.map +1 -0
  45. package/dist/main.js +195 -0
  46. package/dist/main.js.map +1 -0
  47. package/dist/one-shot.d.ts +37 -0
  48. package/dist/one-shot.d.ts.map +1 -0
  49. package/dist/one-shot.js +228 -0
  50. package/dist/one-shot.js.map +1 -0
  51. package/dist/preamble.d.ts +69 -0
  52. package/dist/preamble.d.ts.map +1 -0
  53. package/dist/preamble.js +331 -0
  54. package/dist/preamble.js.map +1 -0
  55. package/dist/server.d.ts +75 -0
  56. package/dist/server.d.ts.map +1 -0
  57. package/dist/server.js +526 -0
  58. package/dist/server.js.map +1 -0
  59. package/package.json +43 -5
@@ -0,0 +1,201 @@
1
+ import type { CheckIssue, ExtractedKeyframe, RenderHealth, RenderProgress, RenderWorkerErrorBody, RenderWorkerErrorCode } from '@memberjunction/video-studio-core';
2
+ /** Pinned `@hyperframes/producer` version reported by the worker. */
3
+ export declare const PINNED_HYPERFRAMES_VERSION = "0.8.134";
4
+ /** Valid 1x1 transparent PNG used by `FakeRenderBackend`. */
5
+ export declare const FAKE_ONE_BY_ONE_PNG: Buffer<ArrayBuffer>;
6
+ /** Minimal valid ISO BMFF (`ftyp`) header bytes used by `FakeRenderBackend`. */
7
+ export declare const FAKE_MP4_BYTES: Buffer<ArrayBuffer>;
8
+ /**
9
+ * Structured error thrown inside the render worker with an HTTP-mappable error code.
10
+ */
11
+ export declare class RenderWorkerError extends Error {
12
+ readonly Code: RenderWorkerErrorCode;
13
+ readonly Issues?: CheckIssue[];
14
+ constructor(code: RenderWorkerErrorCode, message: string, issues?: CheckIssue[]);
15
+ /**
16
+ * Converts this error into the wire-format `RenderWorkerErrorBody`.
17
+ */
18
+ ToBody(): RenderWorkerErrorBody;
19
+ }
20
+ /**
21
+ * Parameters passed to `RenderBackend.Render` for an unpacked bundle on disk.
22
+ */
23
+ export interface BackendRenderJob {
24
+ /** Absolute path to the unpacked bundle directory. */
25
+ RootDir: string;
26
+ /** Relative entry HTML path inside `RootDir`. */
27
+ EntryFile: string;
28
+ /** Output frame width in pixels. */
29
+ Width: number;
30
+ /** Output frame height in pixels. */
31
+ Height: number;
32
+ /** Output frame rate in frames per second. */
33
+ Fps: number;
34
+ /** Optional explicit duration override in seconds. */
35
+ DurationSeconds?: number;
36
+ /** Optional encoding quality preset. */
37
+ Quality?: 'draft' | 'standard' | 'high';
38
+ }
39
+ /**
40
+ * Parameters passed to `RenderBackend.CaptureStills` for an unpacked bundle on disk.
41
+ */
42
+ export interface BackendStillsJob {
43
+ /** Absolute path to the unpacked bundle directory. */
44
+ RootDir: string;
45
+ /** Relative entry HTML path inside `RootDir`. */
46
+ EntryFile: string;
47
+ /** Viewport width in pixels. */
48
+ Width: number;
49
+ /** Viewport height in pixels. */
50
+ Height: number;
51
+ /** Frame rate in frames per second. */
52
+ Fps: number;
53
+ /** Timestamps in seconds to capture in a single browser session. */
54
+ TimestampsSeconds: number[];
55
+ /** Output image format (`png` or `jpeg`). */
56
+ ImageFormat: 'png' | 'jpeg';
57
+ /** Optional JPEG quality (`1-100`). */
58
+ JpegQuality?: number;
59
+ }
60
+ /**
61
+ * Media metadata probed from a rendered MP4 file.
62
+ */
63
+ export interface BackendProbeResult {
64
+ /** Probed duration in seconds. */
65
+ DurationSeconds: number;
66
+ /** Whether the file contains an audio stream with non-zero duration. */
67
+ HasAudio: boolean;
68
+ /** Probed video width in pixels. */
69
+ Width: number;
70
+ /** Probed video height in pixels. */
71
+ Height: number;
72
+ }
73
+ /**
74
+ * Parameters passed to `RenderBackend.RunCheckCli` and `RenderBackend.MeasureText` for an unpacked bundle on disk.
75
+ */
76
+ export interface BackendCheckJob {
77
+ /** Absolute path to the unpacked bundle directory. */
78
+ RootDir: string;
79
+ /** Relative entry HTML path inside `RootDir`. */
80
+ EntryFile: string;
81
+ /** Viewport width in pixels. */
82
+ Width: number;
83
+ /** Viewport height in pixels. */
84
+ Height: number;
85
+ /** Frame rate in frames per second (defaults to 30). */
86
+ Fps?: number;
87
+ }
88
+ /**
89
+ * Visible text element measurement captured in the headless browser DOM at a specific timestamp (VS-RND-5).
90
+ */
91
+ export interface MeasuredText {
92
+ /** Trimmed visible text owned by the element. */
93
+ Text: string;
94
+ /** Bounding box left coordinate in CSS pixels relative to the viewport. */
95
+ Left: number;
96
+ /** Bounding box top coordinate in CSS pixels relative to the viewport. */
97
+ Top: number;
98
+ /** Bounding box width in CSS pixels. */
99
+ Width: number;
100
+ /** Bounding box height in CSS pixels. */
101
+ Height: number;
102
+ /** Computed `font-size` in pixels. */
103
+ FontSizePx: number;
104
+ /** First computed `font-family` name (unquoted). */
105
+ FontFamily: string;
106
+ /** True when the first computed `font-family` is a loaded `FontFace` in `document.fonts`. */
107
+ FontIsBundled: boolean;
108
+ /** True when the element or an ancestor carries `data-mj-bound`. */
109
+ IsBound: boolean;
110
+ /** The `data-mj-bound` attribute value from the element or its nearest bound ancestor, when `IsBound` is true. */
111
+ BoundKey?: string;
112
+ /** Short CSS selector path identifying the element. */
113
+ Selector: string;
114
+ /** Sample timestamp in seconds at which the measurement was taken. */
115
+ TimestampSeconds: number;
116
+ }
117
+ /**
118
+ * Pluggable rendering backend interface separating job orchestration and HTTP transport
119
+ * from HyperFrames, Chromium, and ffmpeg execution.
120
+ */
121
+ export interface RenderBackend {
122
+ /** Runs static project and media URL lint checks on an unpacked bundle directory. */
123
+ Lint(dir: string, entry: string): Promise<{
124
+ Issues: CheckIssue[];
125
+ Block: boolean;
126
+ }>;
127
+ /** Runs `hyperframes check --json` in a restricted subprocess and maps findings to `CheckIssue[]`. */
128
+ RunCheckCli(job: BackendCheckJob, signal?: AbortSignal): Promise<CheckIssue[]>;
129
+ /** Seeks the composition to each timestamp in `timestampsSeconds` and measures visible text elements. */
130
+ MeasureText(job: BackendCheckJob, timestampsSeconds: readonly number[], signal?: AbortSignal): Promise<MeasuredText[][]>;
131
+ /** Renders an unpacked composition to an MP4 file on disk, emitting progress events. */
132
+ Render(job: BackendRenderJob, onProgress: (progress: RenderProgress) => void, signal?: AbortSignal): Promise<{
133
+ OutputPath: string;
134
+ FrameCount: number;
135
+ }>;
136
+ /** Captures one or more still frames in a single headless browser session. */
137
+ CaptureStills(job: BackendStillsJob, signal?: AbortSignal): Promise<Uint8Array[]>;
138
+ /** Probes an MP4 file for duration, dimensions, and audio stream presence. */
139
+ Probe(videoPath: string): Promise<BackendProbeResult>;
140
+ /** Extracts representative keyframes (scene changes + uniform samples) from an MP4 file. */
141
+ ExtractKeyframes(videoPath: string, outDir: string, max: number, signal?: AbortSignal): Promise<ExtractedKeyframe[]>;
142
+ /** Checks runtime dependencies and returns version and health status. */
143
+ Health(): Promise<RenderHealth>;
144
+ /** Returns the installed renderer version string. */
145
+ GetRendererVersion(): string;
146
+ }
147
+ /**
148
+ * Configuration options for `FakeRenderBackend` in unit and contract tests.
149
+ */
150
+ export interface FakeRenderBackendOptions {
151
+ /** Additional lint issues returned by `Lint()`. */
152
+ ExtraLintIssues?: CheckIssue[];
153
+ /** Whether `Lint()` should report `Block: true`. */
154
+ BlockLint?: boolean;
155
+ /** Scripted CLI check issues returned by `RunCheckCli()` (defaults to `[]`). */
156
+ CheckCliIssues?: CheckIssue[];
157
+ /** Optional error thrown by `RunCheckCli()` to test fault tolerance. */
158
+ ThrowOnCheckCli?: Error;
159
+ /** Scripted DOM text measurements returned by `MeasureText()` (defaults to `[]`). */
160
+ MeasuredTexts?: MeasuredText[][];
161
+ /** Optional error thrown by `MeasureText()` to test fault tolerance. */
162
+ ThrowOnMeasureText?: Error;
163
+ /** Delay in milliseconds between each of the 5 progress steps (defaults to 20 ms). */
164
+ StepDelayMs?: number;
165
+ /** Simulated audio presence returned by `Probe()` (defaults to `true`). */
166
+ HasAudio?: boolean;
167
+ /** Simulated health status returned by `Health()` (defaults to `true`). */
168
+ Healthy?: boolean;
169
+ }
170
+ /**
171
+ * Deterministic in-memory/temp-file `RenderBackend` requiring neither Chromium nor ffmpeg.
172
+ */
173
+ export declare class FakeRenderBackend implements RenderBackend {
174
+ private readonly options;
175
+ private lastProbe;
176
+ LintCallCount: number;
177
+ RunCheckCliCallCount: number;
178
+ MeasureTextCallCount: number;
179
+ LastMeasuredTimestamps: number[];
180
+ LastCheckCliJob?: BackendCheckJob;
181
+ LastMeasureTextJob?: BackendCheckJob;
182
+ LastCheckCliSignal?: AbortSignal;
183
+ LastMeasureTextSignal?: AbortSignal;
184
+ constructor(options?: FakeRenderBackendOptions);
185
+ Lint(_dir: string, _entry: string): Promise<{
186
+ Issues: CheckIssue[];
187
+ Block: boolean;
188
+ }>;
189
+ RunCheckCli(job: BackendCheckJob, signal?: AbortSignal): Promise<CheckIssue[]>;
190
+ MeasureText(job: BackendCheckJob, timestampsSeconds: readonly number[], signal?: AbortSignal): Promise<MeasuredText[][]>;
191
+ Render(job: BackendRenderJob, onProgress: (progress: RenderProgress) => void, signal?: AbortSignal): Promise<{
192
+ OutputPath: string;
193
+ FrameCount: number;
194
+ }>;
195
+ CaptureStills(job: BackendStillsJob, signal?: AbortSignal): Promise<Uint8Array[]>;
196
+ Probe(_videoPath: string): Promise<BackendProbeResult>;
197
+ ExtractKeyframes(_videoPath: string, _outDir: string, max: number, signal?: AbortSignal): Promise<ExtractedKeyframe[]>;
198
+ Health(): Promise<RenderHealth>;
199
+ GetRendererVersion(): string;
200
+ }
201
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ /** Pinned `@hyperframes/producer` version reported by the worker. */
4
+ export const PINNED_HYPERFRAMES_VERSION = '0.8.134';
5
+ /** Valid 1x1 transparent PNG used by `FakeRenderBackend`. */
6
+ export const FAKE_ONE_BY_ONE_PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', 'base64');
7
+ /** Minimal valid ISO BMFF (`ftyp`) header bytes used by `FakeRenderBackend`. */
8
+ export const FAKE_MP4_BYTES = Buffer.from([
9
+ 0x00, 0x00, 0x00, 0x18,
10
+ 0x66, 0x74, 0x79, 0x70, // 'ftyp'
11
+ 0x6d, 0x70, 0x34, 0x32, // 'mp42'
12
+ 0x00, 0x00, 0x00, 0x00,
13
+ 0x6d, 0x70, 0x34, 0x32, // 'mp42'
14
+ 0x69, 0x73, 0x6f, 0x6d, // 'isom'
15
+ ]);
16
+ /**
17
+ * Structured error thrown inside the render worker with an HTTP-mappable error code.
18
+ */
19
+ export class RenderWorkerError extends Error {
20
+ constructor(code, message, issues) {
21
+ super(message);
22
+ this.name = 'RenderWorkerError';
23
+ this.Code = code;
24
+ this.Issues = issues;
25
+ }
26
+ /**
27
+ * Converts this error into the wire-format `RenderWorkerErrorBody`.
28
+ */
29
+ ToBody() {
30
+ const body = {
31
+ Code: this.Code,
32
+ Message: this.message,
33
+ };
34
+ if (this.Issues && this.Issues.length > 0) {
35
+ body.Issues = this.Issues;
36
+ }
37
+ return body;
38
+ }
39
+ }
40
+ /**
41
+ * Deterministic in-memory/temp-file `RenderBackend` requiring neither Chromium nor ffmpeg.
42
+ */
43
+ export class FakeRenderBackend {
44
+ constructor(options = {}) {
45
+ this.lastProbe = {
46
+ DurationSeconds: 3,
47
+ HasAudio: true,
48
+ Width: 1280,
49
+ Height: 720,
50
+ };
51
+ this.LintCallCount = 0;
52
+ this.RunCheckCliCallCount = 0;
53
+ this.MeasureTextCallCount = 0;
54
+ this.LastMeasuredTimestamps = [];
55
+ this.options = options;
56
+ }
57
+ async Lint(_dir, _entry) {
58
+ this.LintCallCount++;
59
+ const extra = this.options.ExtraLintIssues ? [...this.options.ExtraLintIssues] : [];
60
+ const hasError = extra.some((issue) => issue.Severity === 'Error');
61
+ return {
62
+ Issues: extra,
63
+ Block: Boolean(this.options.BlockLint) || hasError,
64
+ };
65
+ }
66
+ async RunCheckCli(job, signal) {
67
+ throwIfAborted(signal);
68
+ this.RunCheckCliCallCount++;
69
+ this.LastCheckCliJob = { ...job };
70
+ this.LastCheckCliSignal = signal;
71
+ if (this.options.ThrowOnCheckCli) {
72
+ throw this.options.ThrowOnCheckCli;
73
+ }
74
+ return this.options.CheckCliIssues ? [...this.options.CheckCliIssues] : [];
75
+ }
76
+ async MeasureText(job, timestampsSeconds, signal) {
77
+ throwIfAborted(signal);
78
+ this.MeasureTextCallCount++;
79
+ this.LastMeasureTextJob = { ...job };
80
+ this.LastMeasureTextSignal = signal;
81
+ this.LastMeasuredTimestamps = [...timestampsSeconds];
82
+ if (this.options.ThrowOnMeasureText) {
83
+ throw this.options.ThrowOnMeasureText;
84
+ }
85
+ if (this.options.MeasuredTexts) {
86
+ return this.options.MeasuredTexts.map((group) => [...group]);
87
+ }
88
+ return [];
89
+ }
90
+ async Render(job, onProgress, signal) {
91
+ throwIfAborted(signal);
92
+ const entryContent = await fs.readFile(path.join(job.RootDir, job.EntryFile), 'utf8');
93
+ const durationSeconds = job.DurationSeconds ?? parseDurationFromHtml(entryContent) ?? 3;
94
+ const totalFrames = Math.max(1, Math.round(durationSeconds * job.Fps));
95
+ const stepDelayMs = this.options.StepDelayMs ?? 20;
96
+ if (entryContent.includes('data-fake-hang')) {
97
+ onProgress({
98
+ Phase: 'Rendering',
99
+ RenderedFrames: 1,
100
+ TotalFrames: totalFrames,
101
+ Percent: Math.round((1 / totalFrames) * 100),
102
+ ElapsedMs: 1,
103
+ });
104
+ await waitForAbort(signal);
105
+ }
106
+ const totalSteps = 5;
107
+ const startMs = Date.now();
108
+ for (let step = 1; step <= totalSteps; step++) {
109
+ await delayWithSignal(stepDelayMs, signal);
110
+ const completedFrames = Math.round((step / totalSteps) * totalFrames);
111
+ onProgress({
112
+ Phase: step < totalSteps ? 'Rendering' : 'Encoding',
113
+ RenderedFrames: completedFrames,
114
+ TotalFrames: totalFrames,
115
+ Percent: Math.round((step / totalSteps) * 100),
116
+ ElapsedMs: Date.now() - startMs,
117
+ });
118
+ }
119
+ const outputPath = path.join(job.RootDir, 'fake-output.mp4');
120
+ await fs.writeFile(outputPath, FAKE_MP4_BYTES);
121
+ this.lastProbe = {
122
+ DurationSeconds: durationSeconds,
123
+ HasAudio: this.options.HasAudio ?? true,
124
+ Width: job.Width,
125
+ Height: job.Height,
126
+ };
127
+ return { OutputPath: outputPath, FrameCount: totalFrames };
128
+ }
129
+ async CaptureStills(job, signal) {
130
+ throwIfAborted(signal);
131
+ return job.TimestampsSeconds.map(() => new Uint8Array(FAKE_ONE_BY_ONE_PNG));
132
+ }
133
+ async Probe(_videoPath) {
134
+ return { ...this.lastProbe };
135
+ }
136
+ async ExtractKeyframes(_videoPath, _outDir, max, signal) {
137
+ throwIfAborted(signal);
138
+ const cap = Math.max(1, Math.min(max, 4));
139
+ const frames = [];
140
+ for (let i = 0; i < cap; i++) {
141
+ frames.push({
142
+ Index: i,
143
+ TimestampSeconds: i * 0.5,
144
+ Reason: i === 1 ? 'SceneChange' : 'UniformSample',
145
+ MimeType: 'image/png',
146
+ Width: 1280,
147
+ Height: 720,
148
+ ImageBase64: FAKE_ONE_BY_ONE_PNG.toString('base64'),
149
+ });
150
+ }
151
+ return frames;
152
+ }
153
+ async Health() {
154
+ const healthy = this.options.Healthy ?? true;
155
+ return {
156
+ Healthy: healthy,
157
+ NodeVersion: process.version,
158
+ HyperFramesVersion: PINNED_HYPERFRAMES_VERSION,
159
+ ChromiumVersion: healthy ? 'fake-chromium-146.0' : undefined,
160
+ FfmpegVersion: healthy ? 'fake-ffmpeg-7.1' : undefined,
161
+ Errors: healthy ? [] : ['Fake backend configured unhealthy.'],
162
+ };
163
+ }
164
+ GetRendererVersion() {
165
+ return PINNED_HYPERFRAMES_VERSION;
166
+ }
167
+ }
168
+ function parseDurationFromHtml(html) {
169
+ const match = /\bdata-duration\s*=\s*(?:"([0-9.]+)"|'([0-9.]+)')/i.exec(html);
170
+ const raw = match?.[1] ?? match?.[2];
171
+ if (!raw) {
172
+ return undefined;
173
+ }
174
+ const parsed = Number.parseFloat(raw);
175
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
176
+ }
177
+ function throwIfAborted(signal) {
178
+ if (signal?.aborted) {
179
+ throw new RenderWorkerError('Cancelled', 'Render job was cancelled.');
180
+ }
181
+ }
182
+ function delayWithSignal(ms, signal) {
183
+ throwIfAborted(signal);
184
+ return new Promise((resolve, reject) => {
185
+ const timer = setTimeout(() => {
186
+ signal?.removeEventListener('abort', onAbort);
187
+ resolve();
188
+ }, ms);
189
+ const onAbort = () => {
190
+ clearTimeout(timer);
191
+ reject(new RenderWorkerError('Cancelled', 'Render job was cancelled.'));
192
+ };
193
+ signal?.addEventListener('abort', onAbort, { once: true });
194
+ });
195
+ }
196
+ function waitForAbort(signal) {
197
+ throwIfAborted(signal);
198
+ return new Promise((_resolve, reject) => {
199
+ const onAbort = () => {
200
+ reject(new RenderWorkerError('Cancelled', 'Render job was cancelled.'));
201
+ };
202
+ signal?.addEventListener('abort', onAbort, { once: true });
203
+ });
204
+ }
205
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAUlC,qEAAqE;AACrE,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAC;AAEpD,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAC1C,kGAAkG,EAClG,QAAQ,CACX,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC;IACtC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACtB,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS;IACjC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS;IACjC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACtB,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS;IACjC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS;CACpC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAIxC,YAAmB,IAA2B,EAAE,OAAe,EAAE,MAAqB;QAClF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,MAAM;QACT,MAAM,IAAI,GAA0B;YAChC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC;QACF,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAsKD;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAiB1B,YAAmB,UAAoC,EAAE;QAfjD,cAAS,GAAuB;YACpC,eAAe,EAAE,CAAC;YAClB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,GAAG;SACd,CAAC;QACK,kBAAa,GAAG,CAAC,CAAC;QAClB,yBAAoB,GAAG,CAAC,CAAC;QACzB,yBAAoB,GAAG,CAAC,CAAC;QACzB,2BAAsB,GAAa,EAAE,CAAC;QAOzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,MAAc;QAC1C,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QACnE,OAAO;YACH,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,QAAQ;SACrD,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,GAAoB,EAAE,MAAoB;QAC/D,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;QACjC,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;QACvC,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC;IAEM,KAAK,CAAC,WAAW,CACpB,GAAoB,EACpB,iBAAoC,EACpC,MAAoB;QAEpB,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,kBAAkB,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC;QACpC,IAAI,CAAC,sBAAsB,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC;QACrD,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAClC,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;QAC1C,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,MAAM,CACf,GAAqB,EACrB,UAA8C,EAC9C,MAAoB;QAEpB,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACtF,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACxF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;QAEnD,IAAI,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC1C,UAAU,CAAC;gBACP,KAAK,EAAE,WAAW;gBAClB,cAAc,EAAE,CAAC;gBACjB,WAAW,EAAE,WAAW;gBACxB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC;gBAC5C,SAAS,EAAE,CAAC;aACf,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC3C,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,WAAW,CAAC,CAAC;YACtE,UAAU,CAAC;gBACP,KAAK,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU;gBACnD,cAAc,EAAE,eAAe;gBAC/B,WAAW,EAAE,WAAW;gBACxB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC;gBAC9C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;aAClC,CAAC,CAAC;QACP,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAC7D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG;YACb,eAAe,EAAE,eAAe;YAChC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI;YACvC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;SACrB,CAAC;QAEF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IAC/D,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,GAAqB,EAAE,MAAoB;QAClE,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAChF,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,UAAkB;QACjC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,gBAAgB,CACzB,UAAkB,EAClB,OAAe,EACf,GAAW,EACX,MAAoB;QAEpB,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACR,KAAK,EAAE,CAAC;gBACR,gBAAgB,EAAE,CAAC,GAAG,GAAG;gBACzB,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe;gBACjD,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,GAAG;gBACX,WAAW,EAAE,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;aACtD,CAAC,CAAC;QACP,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,MAAM;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;QAC7C,OAAO;YACH,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,OAAO,CAAC,OAAO;YAC5B,kBAAkB,EAAE,0BAA0B;YAC9C,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS;YAC5D,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;YACtD,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,oCAAoC,CAAC;SAChE,CAAC;IACN,CAAC;IAEM,kBAAkB;QACrB,OAAO,0BAA0B,CAAC;IACtC,CAAC;CACJ;AAED,SAAS,qBAAqB,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,oDAAoD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACtE,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB;IACxC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,iBAAiB,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;IAC1E,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,EAAU,EAAE,MAAoB;IACrD,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACd,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,GAAG,GAAS,EAAE;YACvB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,iBAAiB,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC,CAAC;QAC5E,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,MAAoB;IACtC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,GAAS,EAAE;YACvB,MAAM,CAAC,IAAI,iBAAiB,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC,CAAC;QAC5E,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { type RenderProjectBundle, type VideoFormat } from '@memberjunction/video-studio-core';
2
+ import { type PreambleRuntimeOptions } from './preamble.js';
3
+ /** Maximum number of `Files` + `Assets` entries allowed in a single bundle. */
4
+ export declare const MAX_BUNDLE_ENTRIES = 2000;
5
+ /** Minimum allowed output frame dimension in pixels. */
6
+ export declare const MIN_FRAME_DIMENSION = 16;
7
+ /** Maximum allowed output frame dimension in pixels. */
8
+ export declare const MAX_FRAME_DIMENSION = 4096;
9
+ /** Maximum allowed relative deviation (1%) from the format's target aspect ratio. */
10
+ export declare const MAX_ASPECT_RATIO_TOLERANCE = 0.01;
11
+ /** Minimum allowed frame rate in frames per second. */
12
+ export declare const MIN_FPS = 1;
13
+ /** Maximum allowed frame rate in frames per second. */
14
+ export declare const MAX_FPS = 60;
15
+ /** Maximum allowed composition duration in seconds. */
16
+ export declare const MAX_DURATION_SECONDS = 600;
17
+ /**
18
+ * Unpacked composition bundle staged in an isolated temporary directory on disk.
19
+ */
20
+ export interface StagedBundle {
21
+ /** Absolute path to the temporary root directory for this bundle. */
22
+ readonly RootDir: string;
23
+ /** Absolute path to the entry HTML file inside `RootDir`. */
24
+ readonly EntryPath: string;
25
+ /** Idempotently removes `RootDir` and all unpacked files. */
26
+ Cleanup(): Promise<void>;
27
+ }
28
+ /**
29
+ * Options for `StageRenderBundle`.
30
+ */
31
+ export interface StageBundleOptions {
32
+ /** Optional parent directory for `mkdtemp` (defaults to `os.tmpdir()`). */
33
+ TempRoot?: string;
34
+ /** Optional frame geometry forwarded to the `window.MJVideo` preamble. */
35
+ Geometry?: {
36
+ Width?: number;
37
+ Height?: number;
38
+ Fps?: number;
39
+ DurationSeconds?: number;
40
+ };
41
+ /**
42
+ * Whether to inject the CSP `<meta>` and `window.MJVideo` preamble into `.html` files
43
+ * during initial staging (defaults to `true`).
44
+ */
45
+ InjectPreamble?: boolean;
46
+ }
47
+ /**
48
+ * Parameters validated by `ValidateRenderGeometry`.
49
+ */
50
+ export interface RenderGeometryParams {
51
+ Format: VideoFormat;
52
+ Width: number;
53
+ Height: number;
54
+ Fps?: number;
55
+ DurationSeconds?: number;
56
+ }
57
+ /**
58
+ * Validates a `RenderProjectBundle`, throwing `RenderWorkerError('InvalidBundle', ...)` on any violation.
59
+ */
60
+ export declare function ValidateRenderBundle(bundle: RenderProjectBundle): void;
61
+ /**
62
+ * Validates a bundle-relative path according to Step 5 security rules.
63
+ */
64
+ export declare function ValidateBundleRelativePath(relPath: string, label: string): void;
65
+ /**
66
+ * Validates render request geometry, frame rate, and duration, throwing `InvalidRequest` on error.
67
+ */
68
+ export declare function ValidateRenderGeometry(params: RenderGeometryParams): void;
69
+ export interface CompositionGeometryMatchParams {
70
+ Width: number;
71
+ Height: number;
72
+ DurationSeconds?: number;
73
+ }
74
+ /**
75
+ * Validates that the entry HTML's `data-width`, `data-height`, and `data-duration` attributes
76
+ * (if present on `[data-composition-id]`) match the request's `Width`, `Height`, and `DurationSeconds`,
77
+ * throwing `RenderWorkerError('GEOMETRY_MISMATCH', ...)` (HTTP 400) on mismatch.
78
+ */
79
+ export declare function ValidateCompositionGeometryMatch(bundle: RenderProjectBundle, params: CompositionGeometryMatchParams): void;
80
+ /**
81
+ * Reads the entry HTML's `data-fps` attribute on `[data-composition-id]` (or falls back to `defaultFps`),
82
+ * range-checking it against `MIN_FPS..MAX_FPS` with `RenderWorkerError('InvalidRequest', ...)`.
83
+ */
84
+ export declare function ResolveCompositionFps(bundle: RenderProjectBundle, defaultFps?: number): number;
85
+ /**
86
+ * Reads the entry HTML's `data-duration` attribute on `[data-composition-id]` (or falls back to
87
+ * `defaultDurationSeconds`), range-checking it against `(0, MAX_DURATION_SECONDS]` with
88
+ * `RenderWorkerError('InvalidRequest', ...)`.
89
+ */
90
+ export declare function ResolveCompositionDuration(bundle: RenderProjectBundle, defaultDurationSeconds?: number): number;
91
+ /**
92
+ * Stages a validated `RenderProjectBundle` into a fresh `mkdtemp` directory and injects the preamble
93
+ * into every `.html` / `.htm` file (unless `options.InjectPreamble === false`).
94
+ */
95
+ export declare function StageRenderBundle(bundle: RenderProjectBundle, options?: StageBundleOptions): Promise<StagedBundle>;
96
+ /**
97
+ * Injects the CSP `<meta>`, bundled default `@font-face` `<style>`, and `window.MJVideo`
98
+ * preamble into every `.html` / `.htm` file of a bundle that was staged with `InjectPreamble: false`,
99
+ * and stages the worker's bundled SIL OFL default fonts (`Inter` and `JetBrains Mono`) into `__mj_fonts/`.
100
+ */
101
+ export declare function ApplyPreambleToStagedBundle(rootDir: string, bundle: RenderProjectBundle, preambleOptions: PreambleRuntimeOptions): Promise<void>;
102
+ /**
103
+ * Validates that `dataBase64` is a well-formed base64 string and returns the decoded `Buffer`.
104
+ */
105
+ export declare function ValidateStrictBase64(dataBase64: string, label: string, allowEmpty?: boolean, errorCode?: 'InvalidBundle' | 'InvalidRequest'): Buffer;
106
+ /**
107
+ * Shared entry helper used by `CaptureStills`, `RunCheckCli`, and `MeasureText` to ensure
108
+ * `path.join(rootDir, 'index.html')` matches `entryFile` by always overwriting `index.html`
109
+ * when `entryFile !== 'index.html'` (VS-RND-1 Fix 7b / VS-RND-5 Fix 5).
110
+ */
111
+ export declare function EnsureIndexHtmlForServer(rootDir: string, entryFile: string): Promise<void>;
112
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"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"}