mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
Fixes two of the three adversarial findings from the second #2416 tip re-review; the third is a pre-existing runtime-protocol gap, explained in the PR thread rather than patched here. - The Grade rollback added in the previous commit could never fire through the real Studio callback: runDomEditCommit (the shared commit runner used by every data-attribute commit, not just Grade) catches persist failures internally and always resolves, reporting outcome only via its own onError side effect. A caller awaiting the promise never sees a rejection, so the revert-on-reject logic was dead code against the actual app. Added an optional onSettled(ok) callback to DomEditCommitRunnerConfig (purely additive — every existing caller that doesn't pass it is unaffected) and threaded it through commitDataAttribute -> handleDomAttributeLiveCommit -> the onSetAttributeLive prop type (now accepts an optional 3rd argument) -> useColorGradingController, which now drives the revert from the real signal. The promise-rejection path stays as a fallback for any other implementation of onSetAttributeLive that rejects instead. - Selection flushing performed a real side effect (writing the outgoing element's pending edit) during the render-phase identity-reset block. Adjusting STATE during render (comparing against a ref) is React's documented pattern, but it doesn't license actual I/O — React can invoke render more than once per commit, which could double-fire or misorder the write. The reset block now only enqueues the flush (a pure ref write); a new effect keyed on the identity performs it after commit. - Async persist completions (both the onSettled callback and its promise- rejection fallback) now capture the identity key the attempt was made for and check it against the CURRENT identity before touching confirmedGradingRef/grading/runtimeStatus. Without this, a persist that settles after selection has moved on to a THIRD element could clobber that element's freshly-reset state with a result that belongs to an element no longer selected. Not fixed here: the runtime Grade target (HfColorGradingTarget, used by core's resolveTarget to find the DOM element inside the preview iframe) has no source-file/composition-scope discriminator, matching the same gap selectionIdentityKey had before this stack — but fixing it means changing a wire-protocol type shared across core/player/studio and the legacy ColorGradingSection too. hfId (checked first, before id/selector) is minted uniquely per element at parse time in the common case, so this is a narrow residual risk for hfId-less same-selector elements across different source files, not a regression introduced by this stack. Flagged as a follow-up in the PR thread. New/updated regression tests: real onSettled(false) path (distinct from the promise-rejection fallback), and a stale in-flight persist settling after selection has moved on twice more. Full studio suite still at the known pre-existing 55-failure baseline, zero regressions.