Revert "feat(registry): the video-primitive moves, documented and customisable (#3090)" (#3162)

This reverts commit 3b53bfd2f7.
This commit is contained in:
Miguel Ángel
2026-08-10 14:47:47 -04:00
committed by GitHub
parent 3b53bfd2f7
commit c86d4013f5
2328 changed files with 5906 additions and 458525 deletions
+1 -21
View File
@@ -7,7 +7,6 @@ import {
filterVariablesIfAbsent,
parseHostVariableValues,
readDeclaredDefaults,
warnUnknownEnumValues,
readRenderOverrides,
} from "./getVariables";
@@ -400,12 +399,6 @@ async function mountCompositionContent(params: {
* separate document root so no declared defaults are passed.
*/
declaredVariableDefaults?: Record<string, unknown>;
/**
* The element `declaredVariableDefaults` was read from. Carries the full
* declaration (option sets, not just defaults) so the out-of-set enum guard
* can run on the same merge. Same population rule as the defaults above.
*/
variableDeclarer?: Element;
onDiagnostic?: (payload: {
code: string;
details: Record<string, string | number | boolean | null | string[]>;
@@ -727,7 +720,6 @@ export async function loadExternalCompositions(
// dual-carrier contract from #2081) loses its defaults on this lazy
// external-load path — see inlineSubCompositions for the fixed path.
declaredVariableDefaults: readDeclaredDefaults(doc.documentElement),
variableDeclarer: doc.documentElement,
onDiagnostic: params.onDiagnostic,
});
} catch (error) {
@@ -760,11 +752,7 @@ export async function loadExternalCompositions(
* custom properties from a previous mount are cleared before (re)applying.
*/
function stashInstanceVariables(
params: {
host: Element;
declaredVariableDefaults?: Record<string, unknown>;
variableDeclarer?: Element;
},
params: { host: Element; declaredVariableDefaults?: Record<string, unknown> },
contentNode: Node,
runtimeScopeCompositionId: string,
): void {
@@ -775,14 +763,6 @@ function stashInstanceVariables(
...declaredDefaults,
...parseHostVariableValues(params.host),
};
// The sub-comp path never reaches the top-level getVariables(), so the
// out-of-set enum guard runs here too, against the same merged values the
// instance reads back out of __hfVariablesByComp.
warnUnknownEnumValues(
params.variableDeclarer ?? (contentNode instanceof Element ? contentNode : null),
merged,
runtimeScopeCompositionId,
);
clearAppliedCssVariables(params.host);
if (Object.keys(merged).length > 0) {
if (!window.__hfVariablesByComp) window.__hfVariablesByComp = {};
+2 -136
View File
@@ -1,8 +1,8 @@
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { getVariables, readDeclaredDefaults, resetUnknownEnumWarnings } from "./getVariables";
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { getVariables, readDeclaredDefaults } from "./getVariables";
const VARIABLES_ATTR = "data-composition-variables";
@@ -204,140 +204,6 @@ describe("readDeclaredDefaults", () => {
});
});
describe("out-of-set enum values (observability only — never changes the returned map)", () => {
// One enum plus a number and a string, so "only enums are inspected" is
// pinned by the same declaration the warning reads.
const DECLARED = JSON.stringify([
{
id: "accent",
type: "enum",
label: "Accent",
default: "green",
options: [
{ value: "green", label: "Green" },
{ value: "blue", label: "Blue" },
{ value: "violet", label: "Violet" },
],
},
{ id: "swap_at", type: "number", label: "Swap at", default: 0.5 },
{ id: "title", type: "string", label: "Title", default: "Hello" },
]);
const DEFAULTS = { accent: "green", swap_at: 0.5, title: "Hello" };
let warnings: string[];
beforeEach(() => {
resetUnknownEnumWarnings();
document.body.innerHTML = "";
setDeclared(DECLARED);
document.documentElement.setAttribute("data-composition-id", "morph-swap");
setOverrides(undefined);
warnings = [];
vi.spyOn(console, "warn").mockImplementation((...args: unknown[]) => {
warnings.push(args.map(String).join(" "));
});
});
afterEach(() => {
vi.restoreAllMocks();
document.documentElement.removeAttribute("data-composition-id");
setDeclared(null);
setOverrides(undefined);
resetUnknownEnumWarnings();
});
it("a declared option warns nothing", () => {
setOverrides({ accent: "violet" });
expect(getVariables()).toEqual({ ...DEFAULTS, accent: "violet" });
expect(warnings).toEqual([]);
});
it("an absent value warns nothing — absent is the normal case", () => {
expect(getVariables()).toEqual(DEFAULTS);
expect(warnings).toEqual([]);
});
it("an enum declared without a default and never set warns nothing", () => {
setDeclared(
JSON.stringify([
{ id: "accent", type: "enum", label: "Accent", options: [{ value: "green" }] },
]),
);
expect(getVariables()).toEqual({});
expect(warnings).toEqual([]);
});
it("an out-of-set value warns once, naming composition, variable, value and fallback", () => {
setOverrides({ accent: "orange" });
expect(getVariables()).toEqual({ ...DEFAULTS, accent: "orange" });
expect(warnings).toHaveLength(1);
const message = warnings[0] ?? "";
expect(message).toContain("runtime_unknown_enum_value");
expect(message).toContain("morph-swap");
expect(message).toContain('"accent"');
expect(message).toContain('got "orange"');
expect(message).toContain("green, blue, violet");
expect(message).toContain('Rendering "green" instead');
});
it("falls back to the root composition id when the declarer carries none", () => {
// The real top-level shape: <html> declares, the root <div> has the id.
document.documentElement.removeAttribute("data-composition-id");
document.body.innerHTML = '<div data-composition-id="hero-scene"></div>';
setOverrides({ accent: "orange" });
getVariables();
expect(warnings).toHaveLength(1);
expect(warnings[0]).toContain("hero-scene");
});
it("the same bad value twice warns once; a different bad value warns again", () => {
setOverrides({ accent: "orange" });
getVariables();
getVariables();
expect(warnings).toHaveLength(1);
setOverrides({ accent: "puce" });
getVariables();
expect(warnings).toHaveLength(2);
expect(warnings[1]).toContain('got "puce"');
});
it("non-enum variables are never inspected (any number or string is legal)", () => {
setOverrides({ swap_at: 9.9, title: "anything at all" });
expect(getVariables()).toEqual({ ...DEFAULTS, swap_at: 9.9, title: "anything at all" });
expect(warnings).toEqual([]);
});
it("does not warn when the declared default is itself out of set — nothing fell back", () => {
setDeclared(
JSON.stringify([
{
id: "accent",
type: "enum",
label: "Accent",
default: "orange",
options: [{ value: "green" }, { value: "blue" }],
},
]),
);
expect(getVariables()).toEqual({ accent: "orange" });
expect(warnings).toEqual([]);
});
it("returns byte-identical values whether the value is in set or not", () => {
setOverrides({ accent: "violet" });
const good = getVariables();
setOverrides({ accent: "orange" });
const bad = getVariables();
expect(warnings).toHaveLength(1);
// Same keys, same non-enum values, and the bad value passed through
// untouched — the composition's own guard still owns the coercion.
expect(Object.keys(bad)).toEqual(Object.keys(good));
expect(bad).toEqual({ ...good, accent: "orange" });
expect(bad.accent).toBe("orange");
});
});
describe("css variable injection (figma brand-token chain)", () => {
afterEach(() => {
document.documentElement.removeAttribute(VARIABLES_ATTR);
+18 -129
View File
@@ -42,132 +42,7 @@ export function getVariables<
}
const overrides = readRenderOverrides();
const merged = { ...declaredDefaults, ...overrides };
for (const el of declarers) warnUnknownEnumValues(el, merged);
return merged as Partial<T>;
}
/**
* An enum variable given a value outside its declared `options` is coerced to
* the composition's default by the composition's own guard. That fallback is
* deliberate (a bad value must never break a frame) but it was silent, so a
* meaningless value could sit in a project indefinitely and look correct only
* by coincidence. Warn; do not change what renders.
*
* Reads the option set straight off `data-composition-variables`, so it covers
* every declared enum, not just the `accentColors` guard shape, and needs no
* per-composition code. Deduped per composition+variable+value so a remount
* (studio re-init, seek) cannot spam the console.
*
* Silent for a valid value, for an absent one (an absent variable resolves to
* its own declared default), and for a value that already equals that default
* (nothing fell back).
*/
const warnedUnknownEnumValues = new Set<string>();
/**
* The declaration array on an element, or empty when there isn't a usable one.
*
* One owner for `getAttribute` -> `JSON.parse` -> "is it an array", because
* every reader of this attribute needs exactly that and each copy was a place
* the three answers could drift apart.
*/
function readDeclarations(el: Element | null | undefined): Record<string, unknown>[] {
const raw = el?.getAttribute("data-composition-variables");
if (!raw) return [];
let parsed: unknown;
try {
parsed = JSON.parse(raw);
} catch {
return [];
}
if (!Array.isArray(parsed)) return [];
return parsed.filter(
(entry): entry is Record<string, unknown> => !!entry && typeof entry === "object",
);
}
/**
* What to call the composition in a warning.
*
* The canonical top-level shape declares the variables on `<html>`, which
* carries no id: the composition id sits on the root element below it. Without
* the descendant lookup the message reads "composition variable ...", naming
* nothing in a project that has more than one.
*/
function compositionLabel(declarer: Element, compositionId?: string): string {
return (
compositionId?.trim() ||
declarer.getAttribute("data-composition-id")?.trim() ||
declarer.querySelector("[data-composition-id]")?.getAttribute("data-composition-id")?.trim() ||
"composition"
);
}
/** The declared option values of an enum entry, as comparable primitives. */
function declaredOptions(entry: Record<string, unknown>): (string | number)[] {
if (!Array.isArray(entry.options)) return [];
return entry.options
.map((option) =>
option && typeof option === "object" ? (option as Record<string, unknown>).value : option,
)
.filter((v): v is string | number => typeof v === "string" || typeof v === "number");
}
/**
* Did `resolved` hand this entry a value outside its own option set?
*
* Silent for a valid value, for an absent one (an absent variable resolves to
* its own declared default), and for a value that already equals that default,
* because then nothing fell back. A default outside its own option set is a
* declaration defect for the linter to catch; warning here would print the
* self-contradictory "got X ... rendering X".
*/
function unknownEnumValue(
entry: Record<string, unknown>,
resolved: Record<string, unknown>,
): { id: string; value: unknown; allowed: (string | number)[] } | null {
if (typeof entry.id !== "string") return null;
const value = resolved[entry.id];
if (value === undefined || value === null) return null;
if ("default" in entry && String(value) === String(entry.default)) return null;
const allowed = declaredOptions(entry);
// Stringified compare: `--variables` / `data-variable-values` can deliver a
// declared numeric option as a string, and that is not the defect here.
if (allowed.length === 0 || allowed.some((v) => String(v) === String(value))) return null;
return { id: entry.id, value, allowed };
}
export function warnUnknownEnumValues(
declarer: Element | null | undefined,
resolved: Record<string, unknown>,
compositionId?: string,
): void {
if (!declarer) return;
const entries = readDeclarations(declarer);
if (entries.length === 0) return;
const move = compositionLabel(declarer, compositionId);
for (const entry of entries) {
const found = unknownEnumValue(entry, resolved);
if (!found) continue;
// Deduped per composition+variable+value so a remount (studio re-init,
// seek) cannot spam the console.
const key = `${move}|${found.id}|${String(found.value)}`;
if (warnedUnknownEnumValues.has(key)) continue;
warnedUnknownEnumValues.add(key);
const fallback = "default" in entry ? JSON.stringify(entry.default) : "the composition default";
console.warn(
`[hyperframes] runtime_unknown_enum_value: ${move} variable "${found.id}" got ${JSON.stringify(found.value)}, which is not a declared option (${found.allowed.join(", ")}). Rendering ${fallback} instead.`,
);
}
}
/** Test-only: clear the per-page dedupe set. */
export function resetUnknownEnumWarnings(): void {
warnedUnknownEnumValues.clear();
return { ...declaredDefaults, ...overrides } as Partial<T>;
}
/**
@@ -177,10 +52,24 @@ export function resetUnknownEnumWarnings(): void {
* compositionLoader can compute the same defaults map for sub-comp instances.
*/
export function readDeclaredDefaults(root: Element | null): Record<string, unknown> {
if (!root) return {};
const raw = root.getAttribute("data-composition-variables");
if (!raw) return {};
let parsed: unknown;
try {
parsed = JSON.parse(raw);
} catch {
return {};
}
if (!Array.isArray(parsed)) return {};
const out: Record<string, unknown> = {};
for (const entry of readDeclarations(root)) {
if (typeof entry.id !== "string" || !("default" in entry)) continue;
out[entry.id] = entry.default;
for (const entry of parsed) {
if (!entry || typeof entry !== "object") continue;
const e = entry as Record<string, unknown>;
if (typeof e.id !== "string" || !("default" in e)) continue;
out[e.id] = e.default;
}
return out;
}