mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
Fixes the four blockers from the #2416 re-review at head d6a40c38b: - FlatSlider's onPointerUp calls releasePointerCapture() explicitly, which fires lostpointercapture SYNCHRONOUSLY in real browsers — the prior unconditional onLostPointerCapture resync ran mid-onPointerUp, flipping draggingRef false before onPointerUp's own check, silently dropping every normal drag-release's final commitDraft(). happy-dom doesn't replicate the synchronous cascade, so this shipped without a failing test. Added an explicitReleaseRef flag set right before each deliberate releasePointerCapture() call so onLostPointerCapture can tell "our own release, caller's logic already handles it" apart from a genuine external capture loss. Added a regression test that monkey-patches releasePointerCapture to reproduce the real-browser ordering. - persistColorGradingValue read onSetAttributeLiveRef.current (reassigned every render) instead of the callback live when the debounced edit was scheduled — a timer for element A firing after a re-render for element B would wrongly call B's callback with A's data. Removed the ref; the callback is now an explicit parameter captured by commitColorGrading's own closure (added to its useCallback deps) and threaded through to persistColorGradingValue and flushPendingPersist. - flushPendingPersist passed () => true as its isLatestAttempt checker, bypassing the per-commit version guard entirely. Now calls bumpDomEditCommitVersion(gradingVersionRef) like a regular debounced commit, so a newer edit landing before the flushed write settles still wins the race. - The selection-identity cleanup effect stopped clearing statusTimersRef during an earlier refactor — stale RUNTIME_STATUS_REFRESH_DELAYS timers for an outgoing element could fire after switching selection and stamp the new element's runtimeStatus with the old element's answer. Restored the clear in the same effect cleanup. Also gave the Custom LUT and "Copy grade to" scope <select> controls aria-labels — both had their visible text in a sibling span/text node, so neither had an accessible name. Full studio suite still at the known pre-existing 55-failure baseline (variablePromoteIntegration, useGsapPropertyDebounce, sdkCutover(Parity), sdkResolverShadow), zero new regressions. Typecheck, oxlint, oxfmt clean.
@hyperframes/studio
Browser-based composition editor UI for Hyperframes. Provides a visual timeline, code editor, and live preview for building video compositions.
Install
npm install @hyperframes/studio
What it does
The studio is a React application with:
- Visual timeline — drag, resize, and arrange elements on tracks
- Code editor — edit HTML and GSAP scripts with CodeMirror (syntax highlighting, autocomplete)
- Live preview — see changes in real time as you edit
- Composition inspector — view and modify element properties
Development
The studio is embedded in the hyperframes preview command. To develop the studio UI itself:
cd packages/studio
bun run dev # Start Vite dev server
bun run build # Build for production
bun run typecheck # Type-check
Tech stack
- React 18/19, Zustand (state management)
- CodeMirror 6 (editor)
- Tailwind CSS (styling)
- Vite (bundler)
- Phosphor Icons
Documentation
Full documentation: hyperframes.heygen.com/packages/studio
Related packages
@hyperframes/core— types and parsers used by the editorhyperframes— CLI that serves the studio viahyperframes preview