Files
hyperframes/packages/core
Vance Ingalls c1b8815cb2 feat(sdk): export getRootElements/isNewHostBoundary/bareId, fix relative data-start
Closes gaps surfaced by pacific#30298 (hyperframes layer panel), where consumer
code had to hand-roll fixes for things the SDK/core already solve or nearly solve:

- getRootElements(): getElements() flattens the tree, so every descendant also
  appears as its own top-level entry. buildRoots() already computes true roots
  internally; this exposes it directly instead of making consumers re-derive
  roots by filtering out descendant ids.
- Export isNewHostBoundary + bareId from @hyperframes/sdk: both already existed
  internally (engine/model.ts) but weren't exported, so consumers were
  duplicating sub-composition-boundary detection and scoped-id-to-DOM-leaf
  conversion by hand.
- Export stripEmbeddedRuntimeScripts + RUNTIME_BOOTSTRAP_ATTR from
  @hyperframes/core, and wire serialize({ stripRuntime: true }) on the SDK
  session: a proper tokenizing implementation already existed in
  compiler/htmlDocument.ts (handles more runtime-script marker variants than a
  naive regex), just never exported. The SDK itself imports these via narrow
  subpaths (./runtime/start-expression, ./compiler/html-document) rather than
  the wide ./compiler barrel, matching the SDK's existing import convention and
  avoiding pulling Node-only compiler code (fs/path) into browser bundles.
- Fix getElementTimings(): data-start can be a relative-reference expression
  ("intro", "intro + 2" — see parseStartExpression's grammar), not just an
  absolute number. The old code did a raw parseFloat() on it, which silently
  resolved any reference expression to 0. Now resolves references recursively
  against the target element's own resolved start + duration, Node-safe (no
  live GSAP timeline needed for this case).

14 new tests (session.timings.test.ts, session.subcomp.test.ts). Full sdk
suite: 417/417 passing. Full workspace build (incl. studio) verified clean.
2026-07-08 21:29:52 -07:00
..
2026-03-21 22:43:56 -07:00

@hyperframes/core

Types, parsers, generators, compiler, linter, runtime, and frame adapters for the Hyperframes video framework.

Install

npm install @hyperframes/core

Most users don't need to install core directly — the CLI, producer, and studio packages depend on it internally.

What's inside

Module Description
Types TimelineElement, CompositionSpec, Asset, canvas dimensions, defaults
Parsers parseHtml — extract timeline elements from HTML; parseGsapScript — parse GSAP animations
Generators generateHyperframesHtml — produce valid Hyperframes HTML from a composition spec
Compiler compileTimingAttrs — resolve data-start / data-duration into absolute times
Linter lintHyperframeHtml — validate Hyperframes HTML (missing attributes, overlapping tracks, etc.)
Runtime IIFE script injected into the browser — manages seek, media playback, and the window.__hf protocol
Frame Adapters Pluggable animation drivers (GSAP, Lottie, CSS, or custom)

Frame Adapters

A frame adapter tells the engine how to seek your animation to a specific frame:

import { createGSAPFrameAdapter } from "@hyperframes/core";

const adapter = createGSAPFrameAdapter({
  getTimeline: () => gsap.timeline(),
  compositionId: "my-video",
});

Implement FrameAdapter for custom animation runtimes:

import type { FrameAdapter } from "@hyperframes/core";

const myAdapter: FrameAdapter = {
  id: "my-adapter",
  getDurationFrames: () => 300,
  seekFrame: (frame) => {
    /* seek your animation */
  },
};

Parsing and generating HTML

import { parseHtml, generateHyperframesHtml } from "@hyperframes/core";

const { elements, metadata } = parseHtml(htmlString);
const html = generateHyperframesHtml(spec);

Linting

import { lintHyperframeHtml } from "@hyperframes/core/lint";

const result = lintHyperframeHtml(htmlString);
// result.findings: { severity, message, elementId }[]

Documentation

Full documentation: hyperframes.heygen.com/packages/core