mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
A window.__timelines entry is authored content and may be a partial RuntimeTimelineLike (duration/seek only, no pause). Timeline resolution is deliberately permissive — duration-based — and such compositions render fine, because the render path only seeks. But every interactive transport path (play/pause/seek, bind, rebind-tick, boot) called capturedTimeline.pause() unguarded, crashing studio playback with 'tl.pause is not a function' — the top recurring studio:unhandled_error in telemetry across versions 0.6.121 through 0.7.59 (~150-175/day). Guard all pause sites through one helper (typeof check + swallow, plus a once-per-page timeline_missing_pause analytics event so composition authors can find the partial timeline), matching the safeVoid pattern player.ts already uses. In the rebind restore path, pause is guarded separately so a missing pause() no longer aborts the seek/play restore behind it in the same try/catch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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"type: "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.