MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / compileForRender

Function compileForRender

packages/producer/src/services/htmlCompiler.ts:1501–1717  ·  view source on GitHub ↗
(
  projectDir: string,
  htmlPath: string,
  downloadDir: string,
  options: CompileForRenderOptions = {},
)

Source from the content-addressed store, hash-verified

1499 */
1500// fallow-ignore-next-line complexity
1501export async function compileForRender(
1502 projectDir: string,
1503 htmlPath: string,
1504 downloadDir: string,
1505 options: CompileForRenderOptions = {},
1506): Promise<CompiledComposition> {
1507 const rawHtml = rewriteUnresolvableGsapToCdn(readFileSync(htmlPath, "utf-8"), projectDir);
1508
1509 // Pre-flight: every data-composition-src reference must resolve to a
1510 // usable file before we spend any time compiling, launching a browser, or
1511 // waiting out a capture timeout. See EmptyCompositionError for why this is
1512 // unconditional (not gated behind --strict like lint warnings) — a render
1513 // that silently drops a scene is strictly worse than one that refuses to
1514 // start.
1515 assertSubCompositionsUsable(rawHtml, projectDir);
1516
1517 const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
1518 rawHtml,
1519 projectDir,
1520 downloadDir,
1521 options.log,
1522 );
1523
1524 // Parse sub-compositions first (extracts media + compiled HTML for each)
1525 const {
1526 videos: subVideos,
1527 audios: subAudios,
1528 images: subImages,
1529 subCompositions,
1530 } = await parseSubCompositions(compiledHtml, projectDir, downloadDir);
1531
1532 // Ensure the HTML is a full document before inlining sub-compositions.
1533 // When index.html is a fragment (no <html>/<head>/<body>), linkedom.parseHTML()
1534 // returns a document with null head/body, which causes inlineSubCompositions to
1535 // silently discard all collected composition styles and scripts.
1536 const fullHtml = ensureFullDocument(compiledHtml);
1537
1538 // Inline sub-compositions into the main HTML so the runtime takes the same
1539 // synchronous code path as the bundled preview (no async fetch of
1540 // data-composition-src). This mirrors what htmlBundler.ts does for preview.
1541 const inlinedHtml = inlineSubCompositions(fullHtml, subCompositions, projectDir);
1542
1543 // Strip preload="none" from media elements — the renderer needs to load all
1544 // media upfront for frame capture. Users add this to reduce browser memory in
1545 // preview, but it causes the headless renderer to never load the media, leading
1546 // to 45s timeout failures.
1547 const sanitizedHtml = inlinedHtml.replace(
1548 /(<(?:video|audio)\b[^>]*?)\s+preload\s*=\s*["']none["']/gi,
1549 "$1",
1550 );
1551 const renderModeHints = detectRenderModeHints(sanitizedHtml);
1552 const hasShaderTransitions = detectShaderTransitionUsage(sanitizedHtml);
1553
1554 const normalizedFontHtml = normalizeSystemFontPrimaryFamilies(
1555 injectTextRenderingRule(
1556 coalesceHeadStylesAndBodyScripts(promoteCssImportsToLinkTags(sanitizedHtml)),
1557 ),
1558 );

Callers 6

runTestSuiteFunction · 0.85
runCompilationTestFunction · 0.85
updateCompiledGoldenFunction · 0.85
runCompileStageFunction · 0.85

Calls 15

inlineSubCompositionsFunction · 0.90
parseVideoElementsFunction · 0.90
parseAudioElementsFunction · 0.90
parseImageElementsFunction · 0.90
analyzeKeyframeIntervalsFunction · 0.90
compileHtmlFileFunction · 0.85
parseSubCompositionsFunction · 0.85
ensureFullDocumentFunction · 0.85
detectRenderModeHintsFunction · 0.85

Tested by

no test coverage detected