* 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>