Files
hyperframes/packages/core
Vance Ingalls 0126db7712 Merge origin/main into the audio stack
Twelve of the stack's feature commits landed on main as squashes (#3274
through #3292, plus #3401's canary removal); the 96 review-and-fix commits
that followed them here did not, and main moved 64 commits on in the
meantime. This reconciles the two.

58 files conflicted. 44 were audio-only — main's side there is the
squashed form of commits this branch already carries and has since
superseded, so the branch side stands. The rest needed real work, in both
directions:

**Taken from main, absent here.**
- `ensureAudioGroupInertStyle` (#3278's review). An `<hf-audio-group>` is
  an unknown custom element, so it still takes a flex/grid slot and can
  open a line box — adding a group shifted authored layout. The helper and
  its `init.ts` call never came back to the branch, and this branch is
  what emits the element.
- `#3383`'s ended-audio replay: `canSeekEndedMediaBackward` and its five
  siblings in `media.ts`, with all six tests. Not present here in any
  form.
- `#3380`'s `asetpts=N/SR/TB` between `apad` and `atrim`. Also applied to
  `mixGroupMembers`, the group submix, which is new on this branch and so
  had the same bug in a path main's fix could not reach: delayed members
  padded then amix'd, where a group of four or more silently loses one.
- `#3401`'s `displayNumber` thread. The header derives its row from the
  group-aware order and the undo label from ascending element keys, so
  once a group exists the same click said "Hide track 2" and recorded
  "Hide track 1".
- `#3413`/`#3421`'s viewport handling — the popover's height cap and
  `inset()`, and `resolveFloatingPanelPosition` for the grouping dialog,
  which lives in a track header at the bottom of the window.
- Two extractions this branch had inline and at exactly the 600-line cap:
  `useTimelineDeleteOps` and `editingModeSlice`. Bodies were identical.

**Kept from the branch, against main.** Mute and solo are gone by
deliberate breaking change (`remove mute and solo from tracks and groups`,
`remove the group volume slider and level meter`), so eight files main
still carries are deleted again, `PlayerControls` keeps no
`previewIframeRef` (it existed only to feed `SoloBanner`), the
group-levels branch comes out of main's new `previewMessageRouter`, and
`STRIP_H` goes with the bus strip it sized. Main's
`TimelineTrackPlainHeader.test.tsx` is rewritten against the control that
actually exists — the visibility eye, withheld from an audible audio row
and offered back once hidden, which is the only way out of `data-hidden`.

**Unioned.** `TimelineFxPopover` — main's positioning, this branch's
audition telemetry (`auditionPresetChain`, `storedChain`,
`onAuditionTracked`); `SKILL.md` — main's #3416 "keep the carve group a
voice group" beside this branch's bus section, with the canary paragraph
dropped since the canaries no longer exist.

Every port is mutation-checked. core 2508, studio 4460, lint 528, engine
1630, cli 2813, sdk 549, producer green; tsc, oxlint, oxfmt, fallow and
the 600-line cap clean.
2026-08-23 03:04:47 -07:00
..
2026-08-22 11:16:32 -04: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