fix(core): avoid live volume probe during render

This commit is contained in:
James
2026-07-26 22:39:58 +00:00
parent 2dddb4c463
commit 477defc7e7
11 changed files with 219 additions and 1 deletions
@@ -5,6 +5,7 @@ import { tmpdir } from "node:os";
import {
closeFileServerSafely,
createFileServer,
RENDER_CAPTURE_MODE_SHIM,
HF_BRIDGE_SCRIPT,
HF_EARLY_STUB,
injectScriptsAtHeadStart,
@@ -315,6 +316,33 @@ describe("parseRangeHeader", () => {
});
describe("createFileServer", () => {
it("marks producer pages as render capture before the runtime loads", async () => {
const projectDir = mkdtempSync(join(tmpdir(), "hf-file-server-render-mode-"));
try {
writeFileSync(
join(projectDir, "index.html"),
"<!doctype html><html><head></head><body></body></html>",
);
const runtimeScript = "globalThis.__hfRuntimeLoaded = true;";
const server = await createFileServer({
projectDir,
preHeadScripts: [],
headScripts: [runtimeScript],
});
try {
const response = await fetch(`${server.url}/index.html`);
expect(response.status).toBe(200);
const html = await response.text();
expect(html).toContain(RENDER_CAPTURE_MODE_SHIM);
expect(html.indexOf(RENDER_CAPTURE_MODE_SHIM)).toBeLessThan(html.indexOf(runtimeScript));
} finally {
server.close();
}
} finally {
rmSync(projectDir, { recursive: true, force: true });
}
});
it("serves ES modules with a JavaScript MIME type", async () => {
const projectDir = mkdtempSync(join(tmpdir(), "hf-file-server-mjs-"));
try {
+13 -1
View File
@@ -677,6 +677,14 @@ export interface FileServerHandle {
addPreHeadScript: (script: string) => void;
}
/**
* Set before the Hyperframes runtime executes so render/probe pages can avoid
* preview-only initialization work that mutates the live visual timeline.
* Audio automation is discovered by the producer in an isolated pass and
* baked before frame capture.
*/
export const RENDER_CAPTURE_MODE_SHIM = "globalThis.__HF_RENDER_CAPTURE_MODE = true;";
/**
* Close a file server handle, swallowing and logging any error.
*
@@ -710,7 +718,11 @@ export function createFileServer(options: FileServerOptions): Promise<FileServer
// bodyScripts later upgrades this stub with `seek` / `duration` once the
// Hyperframe runtime's __player is ready, while preserving any fields
// already written.
const preHeadScripts = [HF_EARLY_STUB, ...(options.preHeadScripts ?? [])];
const preHeadScripts = [
HF_EARLY_STUB,
RENDER_CAPTURE_MODE_SHIM,
...(options.preHeadScripts ?? []),
];
// Default scripts: Hyperframe runtime in <head>, render mode in </body>
const headScripts = options.headScripts ?? [getVerifiedHyperframeRuntimeSource()];
const bodyScripts = options.bodyScripts ?? [buildRenderModeScript(options.fps), HF_BRIDGE_SCRIPT];