Merge pull request #641 from heygen-com/fix/bundler-runtime-and-joins

fix(bundler): inline runtime body, drop bare-semi joins, drop empty catch binding
This commit is contained in:
James Russo
2026-05-05 22:53:59 -07:00
committed by GitHub
8 changed files with 213 additions and 77 deletions
+4 -21
View File
@@ -1,6 +1,6 @@
import { defineCommand } from "citty";
import { existsSync, readFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import type { Example } from "./_examples.js";
import { c } from "../ui/colors.js";
@@ -107,27 +107,10 @@ async function seekTo(page: import("puppeteer-core").Page, time: number): Promis
}
async function bundleProjectHtml(projectDir: string): Promise<string> {
// `bundleToSingleHtml` now inlines the runtime IIFE by default, so the
// previous post-bundle runtime substitution is no longer needed.
const { bundleToSingleHtml } = await import("@hyperframes/core/compiler");
let html = await bundleToSingleHtml(projectDir);
const runtimePath = resolve(
__dirname,
"..",
"..",
"..",
"core",
"dist",
"hyperframe.runtime.iife.js",
);
if (existsSync(runtimePath)) {
const runtimeSource = readFileSync(runtimePath, "utf-8");
html = html.replace(
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
() => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`,
);
}
return html;
return bundleToSingleHtml(projectDir);
}
async function alignViewportToComposition(
+3 -14
View File
@@ -97,20 +97,9 @@ async function captureSnapshots(
const numFrames = opts.frames ?? 5;
// 1. Bundle
let html = await bundleToSingleHtml(projectDir);
// Inject local runtime if available.
// Uses the same multi-strategy resolver as the studio preview server
// (runtimeSource.ts) so snapshot works in dev (tsx), built CLI, and npx.
const { loadRuntimeSource } = await import("../server/runtimeSource.js");
const runtimeSource = await loadRuntimeSource();
if (runtimeSource) {
html = html.replace(
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
() => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`,
);
}
// 1. Bundle. `bundleToSingleHtml` now inlines the runtime IIFE by default,
// so the previous post-bundle runtime substitution is no longer needed.
const html = await bundleToSingleHtml(projectDir);
const server = await serveStaticProjectHtml(projectDir, html);
+5 -19
View File
@@ -1,6 +1,6 @@
import { defineCommand } from "citty";
import { existsSync, readFileSync } from "node:fs";
import { resolve, join, dirname } from "node:path";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { resolveProject } from "../utils/project.js";
import { resolveCompositionViewportFromHtml } from "../utils/compositionViewport.js";
@@ -113,24 +113,10 @@ async function validateInBrowser(
const { bundleToSingleHtml } = await import("@hyperframes/core/compiler");
const { ensureBrowser } = await import("../browser/manager.js");
let html = await bundleToSingleHtml(projectDir);
const runtimePath = resolve(
__dirname,
"..",
"..",
"..",
"core",
"dist",
"hyperframe.runtime.iife.js",
);
if (existsSync(runtimePath)) {
const runtimeSource = readFileSync(runtimePath, "utf-8");
html = html.replace(
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
() => `<script data-hyperframes-preview-runtime="1">${runtimeSource}</script>`,
);
}
// `bundleToSingleHtml` now inlines the runtime IIFE by default, so the
// previous post-bundle regex substitution (which matched `src="..."` on the
// runtime tag) is no longer needed — there's no `src` attribute to match.
const html = await bundleToSingleHtml(projectDir);
const { createServer } = await import("node:http");
const { getMimeType } = await import("@hyperframes/core/studio-api");
+5 -2
View File
@@ -153,8 +153,11 @@ export function createStudioServer(options: StudioServerOptions): StudioServer {
async bundle(dir: string): Promise<string | null> {
try {
const { bundleToSingleHtml } = await import("@hyperframes/core/compiler");
let html = await bundleToSingleHtml(dir);
// Fix empty runtime src from bundler — point to the local runtime endpoint
// Studio dev server: ask the bundler for an empty `src=""` placeholder so
// we can point it at our hot-reloadable local runtime endpoint. Inlining
// ~150 KB of runtime body on every preview render would defeat browser
// caching across composition edits.
let html = await bundleToSingleHtml(dir, { runtime: "placeholder" });
html = html.replace(
'data-hyperframes-preview-runtime="1" src=""',
'data-hyperframes-preview-runtime="1" src="/api/runtime.js"',