mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 12:54:29 +00:00
* fix(studio): serialize GSAP script commits per file (shadow request race) Rapid GSAP edits (ease/duration/keyframe/property) fired overlapping read-modify-write POSTs to one script file — coalesceKey only dedupes edit history, not requests. The gsap_fidelity shadow then diffed an op against whichever POST's scriptText resolved, which could predate that op → false "expected null, actual power2.out" mismatches. Server persists correctly; a pure client request-pairing race. Adds createKeyedSerializer (per-key promise chain, rejection-safe, self- cleaning). commitMutation now serializes every GSAP-script commit per target file by default (key `gsap-file:<path>`) — covering all op types and all animations, not just one meta family — so same-file POSTs can't interleave. Distinct files run concurrently; an explicit serializeKey still overrides. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(studio): dedup shadow numeric-equal + GSAP script extraction Code-review cleanup (no behavior change): - Extract the relative-epsilon float compare into shared sdkShadowNumeric.relEqual, used by both timing parity (sdkShadow) and GSAP value fidelity (numericEqual) — was duplicated verbatim, risking divergent tuning. - Export extractGsapScript from sdkShadowGsapFidelity and import it in the keyframe shadow instead of the byte-identical clone (the regex + marker set must stay in sync with document.ts; one copy is safer). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 lines
571 B
TypeScript
12 lines
571 B
TypeScript
/**
|
|
* Relative-epsilon numeric equality shared by the shadow diffs (timing parity +
|
|
* GSAP value fidelity). Both writers round-trip durations/positions through JS
|
|
* number formatting, so a value like 3.1 can read back as 3.0999999999999996.
|
|
* Treat values within 1e-6 * max(1, |a|, |b|) as equal — tight enough that a
|
|
* real 2 vs 1 (or 0.5 vs 0.49) still flags, loose enough to absorb float noise.
|
|
*/
|
|
export function relEqual(a: number, b: number): boolean {
|
|
if (a === b) return true;
|
|
return Math.abs(a - b) <= 1e-6 * Math.max(1, Math.abs(a), Math.abs(b));
|
|
}
|