mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 18:26:17 +00:00
feat(registry): bring back the video-primitive moves (#3169)
Restores the 208 catalog items reverted after their previews 404'd in production, this time on the payload mechanism rather than the .html files that caused the outage. The generator no longer writes a preview document to docs/public. That writer, and the machinery under it, existed only to produce files the docs host discards, so it is gone rather than bypassed. Items now embed the composition itself via a payload, which is what the previous change already does for the items that were already in the catalog. The variables explorer is parked, not restored: it drove its preview through the same unpublished .html path, so it would have shown an empty frame. Items that declare variables get the live player plus the static variables table, and reconnecting the explorer to payloads is a follow-up.
This commit is contained in:
@@ -3,8 +3,9 @@ import { mkdtempSync, writeFileSync, mkdirSync, symlinkSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { parseHTML } from "linkedom";
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, it, expect, vi } from "vitest";
|
||||
import { bundleToSingleHtml } from "./htmlBundler";
|
||||
import { resetUnknownEnumWarnings } from "../runtime/getVariables";
|
||||
import { getHyperframeRuntimeScript } from "../generated/runtime-inline";
|
||||
|
||||
function makeTempProject(files: Record<string, string>): string {
|
||||
@@ -1388,3 +1389,124 @@ describe("bundleToSingleHtml", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* A sub-composition given a value outside a declared enum's `options` falls
|
||||
* back silently. The runtime guard in getVariables.ts cannot see it: the
|
||||
* bundler bakes the per-instance values into `window.__hfVariablesByComp` at
|
||||
* compile time and the sub-comp's scoped `getVariables` shim only reads that
|
||||
* table. Compile time is therefore the only place the defect is observable on
|
||||
* this path, so the same warning is emitted here.
|
||||
*/
|
||||
describe("bundleToSingleHtml unknown enum values", () => {
|
||||
let warnings: string[];
|
||||
|
||||
beforeEach(() => {
|
||||
resetUnknownEnumWarnings();
|
||||
warnings = [];
|
||||
vi.spyOn(console, "warn").mockImplementation((...args: unknown[]) => {
|
||||
warnings.push(args.map(String).join(" "));
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
resetUnknownEnumWarnings();
|
||||
});
|
||||
|
||||
const enumWarnings = () => warnings.filter((w) => w.includes("runtime_unknown_enum_value"));
|
||||
|
||||
const ACCENT_ENUM =
|
||||
'[{"id":"accent","type":"enum","label":"Accent","default":"green","options":["green","blue","violet"]}]';
|
||||
|
||||
function makeSubCompProject(variableValues: string, declaration = ACCENT_ENUM): string {
|
||||
return makeTempProject({
|
||||
"index.html": `<!doctype html>
|
||||
<html><head></head><body>
|
||||
<div id="root" data-composition-id="main" data-width="1920" data-height="1080">
|
||||
<div
|
||||
data-composition-id="card"
|
||||
data-composition-src="compositions/card.html"
|
||||
data-variable-values='${variableValues}'></div>
|
||||
</div>
|
||||
<script>window.__timelines={};</script>
|
||||
</body></html>`,
|
||||
"compositions/card.html": `<!doctype html>
|
||||
<html data-composition-variables='${declaration}'>
|
||||
<body>
|
||||
<div data-composition-id="card" data-width="1920" data-height="1080"></div>
|
||||
</body>
|
||||
</html>`,
|
||||
});
|
||||
}
|
||||
|
||||
it("warns when a sub-composition instance value is not a declared option", async () => {
|
||||
await bundleToSingleHtml(makeSubCompProject('{"accent":"orange"}'));
|
||||
|
||||
expect(enumWarnings()).toEqual([
|
||||
'[hyperframes] runtime_unknown_enum_value: card variable "accent" got "orange", ' +
|
||||
"which is not a declared option (green, blue, violet). " +
|
||||
'Rendering "green" instead.',
|
||||
]);
|
||||
});
|
||||
|
||||
it("is silent when the instance value is a declared option", async () => {
|
||||
await bundleToSingleHtml(makeSubCompProject('{"accent":"violet"}'));
|
||||
|
||||
expect(enumWarnings()).toEqual([]);
|
||||
});
|
||||
|
||||
it("never inspects a variable declared without options", async () => {
|
||||
const declaration = '[{"id":"accent","type":"string","label":"Accent","default":"green"}]';
|
||||
await bundleToSingleHtml(makeSubCompProject('{"accent":"orange"}', declaration));
|
||||
|
||||
expect(enumWarnings()).toEqual([]);
|
||||
});
|
||||
|
||||
it("is silent for a declared enum absent from the instance values", async () => {
|
||||
await bundleToSingleHtml(makeSubCompProject('{"unrelated":"whatever"}'));
|
||||
|
||||
expect(enumWarnings()).toEqual([]);
|
||||
});
|
||||
|
||||
it("passes the unknown value through to the bundle unrewritten", async () => {
|
||||
const bundled = await bundleToSingleHtml(makeSubCompProject('{"accent":"orange"}'));
|
||||
|
||||
expect(bundled).toContain("window.__hfVariablesByComp = Object.assign({}, ");
|
||||
expect(bundled).toContain('{ "card": { "accent": "orange" } }');
|
||||
expect(bundled).toMatch(/\[data-composition-id="card"\]\s*\{[^}]*--accent:\s*orange/);
|
||||
expect(bundled).not.toContain("--accent: green");
|
||||
});
|
||||
|
||||
it("warns once for the same composition, variable and value across bundles", async () => {
|
||||
const dir = makeSubCompProject('{"accent":"orange"}');
|
||||
await bundleToSingleHtml(dir);
|
||||
await bundleToSingleHtml(dir);
|
||||
|
||||
expect(enumWarnings()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("warns for a <template>-mounted composition too", async () => {
|
||||
const dir = makeTempProject({
|
||||
"index.html": `<!doctype html>
|
||||
<html><head></head><body>
|
||||
<div id="root" data-composition-id="main" data-width="1920" data-height="1080">
|
||||
<div data-composition-id="card" data-variable-values='{"accent":"orange"}'></div>
|
||||
</div>
|
||||
<template id="card-template">
|
||||
<div data-composition-id="card" data-width="1920" data-height="1080"
|
||||
data-composition-variables='${ACCENT_ENUM}'></div>
|
||||
</template>
|
||||
<script>window.__timelines={};</script>
|
||||
</body></html>`,
|
||||
});
|
||||
|
||||
await bundleToSingleHtml(dir);
|
||||
|
||||
expect(enumWarnings()).toEqual([
|
||||
'[hyperframes] runtime_unknown_enum_value: card variable "accent" got "orange", ' +
|
||||
"which is not a declared option (green, blue, violet). " +
|
||||
'Rendering "green" instead.',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { markFlattenedInnerRoot } from "../runtime/flattenedRoot";
|
||||
export { FLATTENED_INNER_ROOT_STRIP_ATTRS } from "../runtime/flattenedRoot";
|
||||
import { parseHostVariableValues } from "../runtime/getVariables";
|
||||
import { parseHostVariableValues, warnUnknownEnumValues } from "../runtime/getVariables";
|
||||
import { cssVariableName } from "../tokenSlug";
|
||||
import { readFileSync, existsSync } from "fs";
|
||||
import { resolve, relative, dirname, isAbsolute, sep } from "path";
|
||||
@@ -980,6 +980,13 @@ export async function bundleToSingleHtml(
|
||||
if (runtimeCompId && Object.keys(mergedVariables).length > 0) {
|
||||
compVariablesByComp[runtimeCompId] = mergedVariables;
|
||||
}
|
||||
// Same defect on the <template> mount as on the data-composition-src
|
||||
// mount (see inlineSubCompositions): the merged instance values are
|
||||
// baked in here, so only compile time can see a value that falls back.
|
||||
if (runtimeCompId) {
|
||||
warnUnknownEnumValues(innerDoc.documentElement, mergedVariables, runtimeCompId);
|
||||
warnUnknownEnumValues(innerRoot, mergedVariables, runtimeCompId);
|
||||
}
|
||||
pushSubCompVariableStyles(
|
||||
innerDoc,
|
||||
innerRoot,
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
rewriteInlineStyleAssetUrls,
|
||||
type AssetExists,
|
||||
} from "./rewriteSubCompPaths";
|
||||
import { warnUnknownEnumValues } from "../runtime/getVariables";
|
||||
import {
|
||||
scopeCssToComposition,
|
||||
wrapInlineScriptWithErrorBoundary,
|
||||
@@ -272,6 +273,14 @@ export function inlineSubCompositions(
|
||||
if (Object.keys(mergedVariables).length > 0) {
|
||||
variablesByComp[runtimeCompId] = mergedVariables;
|
||||
}
|
||||
// Compile time is the only place this defect is visible on the sub-comp
|
||||
// path: the instance value is baked into `__hfVariablesByComp` right
|
||||
// here, and the scoped `getVariables` shim only reads that table, so the
|
||||
// runtime's identical guard never runs. Same helper, so the message and
|
||||
// the per-process dedupe set are shared with the runtime path and the
|
||||
// author sees one warning either way.
|
||||
warnUnknownEnumValues(compDoc.documentElement, mergedVariables, runtimeCompId);
|
||||
warnUnknownEnumValues(innerRoot, mergedVariables, runtimeCompId);
|
||||
}
|
||||
|
||||
// `<head>` <link>/<script src> are hoisted into the ROOT document, so they
|
||||
|
||||
Reference in New Issue
Block a user