mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
* feat(core): a composition with no authored length takes it from its clips A new resolver in @hyperframes/parsers returns a composition length as authored, derived from its latest clip end, or unresolved, and counts clips whose length is still pending. The runtime uses it in its two existing max-end loops with identical results, and as a last resort only when no timeline, floor or caller length exists, so a composition that has a length today keeps it. The derived source is published on window.__hf.durationSource for render telemetry. Lint reports a root that has timed clips but no data-duration as a warning that says where to author it, and still errors when there is nothing to derive from. * refactor(core): resolve the runtime duration floor in one call The declared duration and sub-composition ends were resolved separately and maxed by hand; one resolver call over both gives the same latest end. * fix(core): a derived composition length waits for every clip length and reports honestly Review follow-up. The runtime returns a content-derived length only when no clip is still pending, so a renderer that reads duration once cannot lock in a short one. window.__hf.durationSource is cleared whenever a timeline or floor supplies the length, and the diagnostic fires only for a derived length. Lint says "at least Ns", counts reference-start clips as known only at runtime, and ignores a data-end before data-start. * fix(core): a sub-composition with no known length counts as pending A host whose own timeline is not registered yet no longer lets the content-derived length show early. Tests pin the pending host and that the diagnostic fires only for a derived length. * fix(core): a loaded Lottie with no registered animation keeps the length pending Lottie registers from author scripts with no DOM marker, and nothing re-derives the length after it registers. A composition with clips and a loaded Lottie library therefore stays at zero, as before, instead of locking in the clips length and cutting the animation short. * test(core): a registered Lottie supplies the length and the clips length is not used Pins the other side of the pending Lottie rule. Once an animation reports a length it enters the duration floor, so the content-derived fallback is never consulted. * test(core): the declared and DotLottie pending branches are covered
Hyperframe Runtime Engine
This folder owns the runtime that powers preview and producer parity.
Current Direction
- Runtime source of truth is converging on
hyperframe.ts. - Build produces:
dist/hyperframe.runtime.iife.js(browser bootstrap)dist/hyperframe.runtime.mjs(tooling/tests)dist/hyperframe.manifest.json(version + sha256 + artifact map)
- FE owns iframe runtime injection.
- BE persists raw generated HTML without injecting runtime scripts.
- Producer validates pinned runtime checksum from manifest before render.
Runtime Contract (Stable Surface)
Globals:
window.__playerwindow.__playerReadywindow.__renderReadywindow.__timelineswindow.__clipManifest
postMessage:
- parent -> runtime control:
source: "hf-parent"type: "control"- actions:
play,pause,seek,set-muted,set-playback-rate,enable-pick-mode,disable-pick-mode
- runtime -> parent events:
source: "hf-preview"type: "state"andtype: "timeline";timelinecarriesassetsReady(whether the composition's media, images and fonts have settled) and the runtime then poststype: "assets-ready"once, so a parent that cannot read the iframe can gate playbacktype: "ready"— emitted once wheninstallRuntimeControlBridgeregisters the control-message listener. The parent uses it to replay current playback state (set-muted,set-volume,set-playback-rate) so any control message sent before the listener was installed isn't lost. Emitted again on every iframe reload because the new runtime instance starts with no state.
Determinism baseline:
renderSeekis the producer-canonical seek path.- 30fps quantization and readiness gates are correctness requirements.
Build
bun run --filter @hyperframes/core build:hyperframes-runtime
Security Expectations
- Runtime bootstrap URL must be version-pinned and host-allowlisted.
- Iframe bridge payloads must be schema-validated.
- Unsafe URL schemes (
javascript:and unapproveddata:) are rejected. - Fail closed if runtime bootstrap/handshake is not healthy.
Product Editing Model
- Primary mode: prompt + element picking.
- Secondary mode: manual precision controls.
- Avoid timeline-first manual workflows as default product path.