mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
A sub-composition ROOT is addressed by its data-composition-id, but the SDK's whole element<->tween attribution is data-hf-id based, so the prior fix's [data-composition-id] selector was invisible to three readers (validateOp/can, selectorMatchesId -> setTiming + removeElement cascade, buildAnimationIdMap -> getElement.animationIds), diverging can from apply and orphaning tweens. Root fix: make composition ids first-class resolvable addresses and emit the canonical selector everywhere. - resolveScoped (model.ts): for a bare id with no data-hf-id match, fall back to [data-composition-id]. data-hf-id keeps precedence; scoped-path and canonical behavior intact. Fixes validateOp gating, findById/getElement, and every op handler for comp-root targets in one place. - gsapTargetSelector (mutate.ts): resolve the target and emit [data-hf-id="<resolved host hf-id>"] (canonical). Normal targets unchanged; comp-root targets resolve via comp-id -> host -> host hf-id. Defensive [data-composition-id] only when the resolved element has no hf-id. - setTiming syncs the GSAP tween via the resolved element's data-hf-id so a comp-root target matches its host tween; removeElement cascade already covers the host hf-id via collectSubtreeHfIds. - export escapeHfId; escape both the querySelector probe and the emitted selector string. Tests: comp-id resolveScoped fallback + precedence (session.subcomp), canonical selector, validateOp accept, setTiming sync, removeElement cascade, and getElement.animationIds for comp-root tweens (mutate.gsap). The prior test only called applyOp, masking all of this. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>