From fea504a41f15eeaa05ed23334d1721a77a69c36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Tue, 24 Mar 2026 17:43:28 -0400 Subject: [PATCH 1/6] feat(producer): support entryFile for rendering individual compositions Add optional `entryFile` parameter to the render API. When provided, the producer renders the specified HTML file instead of defaulting to index.html. This enables rendering individual sub-compositions (e.g. `compositions/intro.html`) without wrapping them in a full project. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/producer/src/server.ts | 14 +++++++++++--- .../producer/src/services/renderOrchestrator.ts | 8 +++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/producer/src/server.ts b/packages/producer/src/server.ts index a439ae727..26c95991e 100644 --- a/packages/producer/src/server.ts +++ b/packages/producer/src/server.ts @@ -69,6 +69,7 @@ interface RenderInput { workers?: number; useGpu: boolean; debug: boolean; + entryFile?: string; } interface PreparedRenderInput { @@ -91,7 +92,12 @@ function parseRenderOptions(body: Record): Omit 0 + ? body.entryFile.trim() + : undefined; + + return { outputPath, fps, quality, workers, useGpu, debug, entryFile }; } async function prepareRenderBody( @@ -104,8 +110,9 @@ async function prepareRenderBody( if (!existsSync(absProjectDir) || !statSync(absProjectDir).isDirectory()) { return { error: `Project directory not found: ${absProjectDir}` }; } - if (!existsSync(resolve(absProjectDir, "index.html"))) { - return { error: `No index.html in project directory: ${absProjectDir}` }; + const entry = options.entryFile || "index.html"; + if (!existsSync(resolve(absProjectDir, entry))) { + return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` }; } return { prepared: { input: { projectDir: absProjectDir, ...options } } }; } @@ -317,6 +324,7 @@ export function createRenderHandlers(options: HandlerOptions = {}): RenderHandle workers: input.workers, useGpu: input.useGpu, debug: input.debug, + entryFile: input.entryFile, logger: log, }); diff --git a/packages/producer/src/services/renderOrchestrator.ts b/packages/producer/src/services/renderOrchestrator.ts index 1205e8715..956c0ef76 100644 --- a/packages/producer/src/services/renderOrchestrator.ts +++ b/packages/producer/src/services/renderOrchestrator.ts @@ -93,6 +93,8 @@ export interface RenderConfig { workers?: number; useGpu?: boolean; debug?: boolean; + /** Entry HTML file relative to projectDir. Defaults to "index.html". */ + entryFile?: string; /** Full producer config. When provided, env vars are not read. */ producerConfig?: EngineConfig; /** Custom logger. Defaults to console-based defaultLogger. */ @@ -319,7 +321,11 @@ export async function executeRenderJob( restoreLogger = installDebugLogger(logPath, log); } - const htmlPath = join(projectDir, "index.html"); + const entryFile = job.config.entryFile || "index.html"; + const htmlPath = join(projectDir, entryFile); + if (!existsSync(htmlPath)) { + throw new Error(`Entry file not found: ${htmlPath}`); + } assertNotAborted(); // ── Stage 1: Compile ───────────────────────────────────────────────── From 55beb9a56d81964b6f7ffc204cc15b99b1e5bd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Tue, 24 Mar 2026 18:26:42 -0400 Subject: [PATCH 2/6] fix(producer): resolve runtime manifest in bundled builds + wrap sub-compositions - Add dist-sibling path to manifest resolver (fixes "Missing manifest" when running from bundled public-server.js) - Add wrapSubCompositionAsStandalone: when entryFile is a