Files
Miguel Ángel 70187a13b5 perf(core): the preview mounts and draws only the scenes near the playhead (#6189)
* perf(core): skip rendering preview scenes far from the playhead

* refactor(core): split the far-scene pass into small helpers

* perf(core): a first render reveals only the clips it reaches

* fix(core): reveal the clips holding first-rendered tweens, wherever their window is

* feat(core): a scene may load a project helper and wait for fonts and still swap

* perf(core): the preview mounts only the scenes near the playhead

* perf(core): a seek waits only for the scene it lands in; neighbours mount one per turn

* feat(studio): selecting a clip in an unmounted scene mounts that scene first

* fix(core): a source a play and a seek both need is fetched and decoded once

* fix(core): a scene mounting during play joins the mix without restarting what plays

* fix(studio): selecting a clip waits on a scene mount only in a preview that unmounts scenes

* fix(core): far scenes still mount after an edit, and an edit to a parked scene keeps its styles

* perf(core): web audio schedules a clip only as the playhead comes near it

* chore(studio): trim the scene hold helper's comments to its package's share

* fix(core): a scene the preview unmounts is freed, not kept by audio, caches or old roots

* fix(studio): an unmounted scene's rows and their state come from the markup it mounts with

* perf(core): the preview mounts scenes ahead of play and keeps recent ones mounted

* refactor(core): keep the far-scene neighbour rule private to its module

* style(core): format the far-scene neighbour rule

* perf(core): the preview unmounts scenes the playhead leaves, as kept ones slowed each mount

* fix(core): scenes that measure text, call their own animate or wait on font loads can unmount

* fix(core): each preview scene carries the helpers it loads, so it mounts on its own

* fix(core): a mounted scene shows though its stand-in was hidden by display

* fix(core): a helper scenes share runs once for the film, and a remounted scene keeps showing

* fix(core): a scene that also publishes its timeline under another id stays mounted

* feat(core): scenes that draw in 2D or chain the timeline they register can unmount

* perf(core): a play frame that draws nothing new skips the hidden-clip lookup

* fix(core): a GSAP file copied into a project counts as the library for scene unmounting

* style(core): drop an unneeded escape in the registered-chain pattern

* chore: core and producer size budgets make room for the preview scene window

* fix(core): a scene that draws on a 2D canvas stays mounted

* fix(core): a scene the preview unmounts lets go of timelines it built after a font wait

* perf(core): a scene leaving the playhead keeps its last rendered size, no forced layout at the cut

* refactor(core): the far-scene skip keeps last-render boxes in their own helper

* fix(core): a mounting scene never records the runtime's root timeline as its own

* chore(producer): raise the size budget to the measured size with the preview runtime inlined

* docs(core): keep the far-scene and scene-memory comments within the comment limits

* perf(core): style each hidden clip visible once ahead of its cut, so the cut frame does not

* fix(core): a seek into a scene still mounting as a neighbour waits for that mount

* chore(core): keep comment share and size budgets to main plus the measured core growth
2026-10-25 19:39:14 +00:00
..
2026-10-25 18:13:20 +00: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)

Generated composition trust

Composition generators require trusted authors for code-bearing inputs. styles and generateHyperframesStyles preserve authored CSS, which can load external resources. animations may contain __raw: values that are emitted as JavaScript; includeScripts: true includes executable timeline code. serializeGsapAnimations also accepts raw preamble, postamble, and a code-bearing timelineVar. Never fill these inputs with untrusted data. Attribute encoding and closing-tag containment are not a sandbox; render untrusted compositions in an appropriately isolated execution environment and never serve them on a privileged origin.

Text content retains the supported inline-formatting sanitizer contract. The clip parser intentionally flattens inner formatting to text, so parse/generate is not a lossless replacement for editing the source HTML.

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