mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
Review findings 8, 12, 13.
**12 — the reveal was dead in BOTH halves,** which is why nobody caught it: each
half hid the other.
- *Not already selected.* `openClipFxRack` raises the request and then selects
the clip asynchronously, so the selection landed AFTER and
`setSelectedElementId` cleared `revealedAudioFxTarget` — the very request that
caused the selection. The clear now spares a request whose `elementKey` is the
element being selected; any other selection still drops it, because a request
aimed elsewhere is stale.
- *Already selected.* `FxSection` consumed with
`useState(revealTarget ?? null)`, so `consumedReveal` initialised EQUAL to the
request and the `!==` never fired — and a second click on the same lane was
byte-identical, so also inert. It now consumes by nonce, initialised null,
which is what `PropertyPanelFlat` already does for the same hazard and for the
same reason. `propertyPanelAudioFxGroup` forwarded `automationTarget` and
dropped the nonce; it forwards both now.
**13 — an unescapable node id took the panel down instead of failing quietly.**
`revealRowSelector` interpolated chain strings straight into `querySelector`.
`parseAudioFxNode` accepts any non-empty string as an id and
`parseAutomationTarget` only splits on `.`, so a hand- or LLM-authored chain can
carry `a"]` — and the throw escaped a render-phase effect. Now escaped with the
repo's own `escapeCssString` (which `findElementForTimelineElement` uses for
exactly this) and wrapped, so a malformed selector returns false, which is the
documented "row not mounted yet" contract.
**8 — a hidden group had no way back.** The panel's visibility toggle is
withheld for any audio selection, and the group header carries no visibility
control now that mute and solo are gone — so a `data-hidden` bus was silent in
preview (the bus's mute gain) and absent from the render (every member dropped),
recoverable only by hand-editing the HTML. It is now offered while hidden, the
same door-from-the-inside `TimelineTrackPlainHeader` keeps for an audio TRACK
after the identical trap was diagnosed there on this branch.
That fix needed a second one to work: `selectedElementHidden` derives from
`timelineElements`, and after 0e86e64d2 a bus is not one — no timeline row, no
`hidden` flag. `isSelectionHidden` falls back to the element's own attribute.
`clearRevealedAudioFxTarget` is now called on unmount, closing a "left open"
item in the PR body. The whole reveal consumption moved to
`useAudioFxRevealSection.ts` because PropertyPanelFlat crossed 600 — the hook
holds all three hazards (currency, nonce, retirement) instead of restating them
at the call site.
studio: 103 editor files, 1276 tests. fallow 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