Files
hyperframes/packages/core
Vance IngallsandClaude Opus 5 71ca86456c perf(core): reuse the FFT scratch arrays across carve windows
Both analysis loops allocated a fresh `Float64Array(4096)` pair inside the
per-window loop. A 5-minute 48 kHz voiceover is ~7030 windows, so one carve
churned ~460 MB of transient Float64Array through the main thread — the panel's
thread — for a measurement that needs 64 KiB of scratch. Now one pair is reused;
`re` is fully overwritten each window and only `im` has to be cleared.

Wall-clock is unchanged (591 ms vs 596 ms on that file, within noise): the FFT
dominates and a bump allocation is nearly free. This is a GC-pressure fix, not a
latency one, and the band values it produces are bit-identical.

The review's third loop is `analyseCarveDuck`, which runs `windowDb` rather than
an FFT and allocates nothing per window — nothing to fix there.

Striding the Welch hops was tried and REJECTED. It is 27x faster on a 5-minute
voiceover (427 ms -> 15 ms), but it moves the result: at strength 0.9 the chosen
band set changed (630 Hz became 160 Hz), and it did not converge back to the
full read even at 2048 windows. That is the author's carve being silently
redrawn to save time on a measurement that already locks the rack while it runs.
The reason is recorded in the code so it is not re-attempted.

Falsified by deleting `im.fill(0)` from both loops: five tests fail, including
the two added here — a steady tone must measure the same bands whatever its
length, and its dynamics envelope must sit still rather than sliding as the
contamination accumulates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 12:01:42 -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