Skip to content

fix(studio): the preview reloads when any write a commit saved is not patched on screen - #4920

Merged
miguel-heygen merged 2 commits into
mainfrom
fix/studio-resize-size-preview
Oct 3, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
fix/studio-resize-size-preview

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

What

Two preview-sync fixes in the one place every GSAP commit's preview update goes through (applyPreviewSync and its batch caller in useGsapScriptCommits.ts). Both are about a write that is saved but not yet on screen.

  1. A batch patched in place only part of what it wrote. A batch passed on just the in-place patches that existed. When one call had a patch and another did not, the preview applied the patch, decided everything was on screen and skipped the soft reload, so the unpatched write stayed stale until a page reload. A batch now uses the in-place path only when every call in it brought a patch; otherwise it soft-reloads with the batch's own options.
  2. A deferred write with no patch lost its reload. A group drag defers each member's preview sync and carries a missed patch to the final render through a shared latch. A write with no patch at all never set that latch, so if the last member patched in place, the reload was skipped and the earlier member kept its old position on screen. A write with no patch now counts as not on screen, the same as a missed patch.

Edit bench

resize-size-px-r0-root-z100-mid, 6 runs each on one devbox: main drop 120.36 px in 6/6; #4889 alone drop 120.36 in 6/6; #4889 with this PR drop 0 in 6/6 (reload the same). A rare run passes without the fix, which is the batch race: the size and position writes only miss the reload when they land in one batch. The case's remaining undo failure is the separate undo-restore cause.

Full grid, one devbox: #4889 (acc76b9) with #4935 and this PR against #4889 alone. 261 of 1,562 cases are inaccurate with the stack, and every one of them is also inaccurate on #4889 alone, so the stack turns no passing case red.

Before

After a corner resize at 1 s the Size field reads 370, 247 but the preview box has snapped back to the old size.

Preview after the drop, old size

After

The preview box shows the new size right after the drop.

Preview after the drop, new size

Test plan

  • useGsapScriptCommits.test.tsx: a batch of [size write without a patch, position write with one] soft-reloads once and never fully reloads (fails without fix 1: 0 soft reloads); a deferred write with no patch sets the latch and the final render soft-reloads (fails without fix 2). 35/35 in the file, the new cases 3 runs in a row.
  • Neighbours: domGroupMoveBy 9, useDomEditSession 16, useGsapAwareEditing 29, useGsapAwareEditing.groupPlan 4. tsc, oxfmt, oxlint and the comment ratchet are clean.
  • Documentation updated (if applicable)

Rebased onto main after #4889 merged; the commits are unchanged.

Kept as its own PR under the size floor: it is the resize root fix, reviewed and bench-checked on its own, and folding it into #4935 (parsers) would mix two packages and reset both reviews.

@miguel-heygen
miguel-heygen force-pushed the fix/studio-resize-size-preview branch 2 times, most recently from c53d689 to 74364d0 Compare October 3, 2026 08:38
@miguel-heygen miguel-heygen changed the title fix(studio): show a resized size right after the drop, not after a reload fix(studio): the preview reloads when any write a commit saved is not patched on screen Oct 3, 2026
@miguel-heygen
miguel-heygen marked this pull request as ready for review October 3, 2026 18:47
Base automatically changed from fix/studio-playhead-writer-carrier to main October 3, 2026 20:10
@mintlify

mintlify Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Oct 3, 2026, 8:34 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

…ce patch

A corner resize saves size and position in one batch; only the position had an in-place patch,
so the preview patched it and skipped the reload, and the new size snapped back until reload.
… at the group's end

A group drag defers each member's preview sync and carries a missed patch to the final render.
A write with no patch at all never set that latch, so a last member that patched in place
skipped the reload and the earlier member kept its old position on screen.
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 1301 (base branch 1301), smooth 1138 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

@miguel-heygen
miguel-heygen merged commit da17c03 into main Oct 3, 2026
138 checks passed
@miguel-heygen
miguel-heygen deleted the fix/studio-resize-size-preview branch October 3, 2026 21:27
miguel-heygen added a commit that referenced this pull request Oct 3, 2026
… the start (#4935)

* fix(parsers): a keyframe edit no longer overrides an earlier tween at the start

Writing a keyframe into a tween that starts later added a t=0 hold for every position prop of
its first keyframe, so a from() that already moves x before it lost its start value. The hold
now skips props an earlier tween on the same target writes; both writers share one helper.

* fix(parsers): keep the hold for label-placed tweens and re-sync one-line scripts stably

The recast parser leaves a label start unresolved; an unknown start no longer counts as earlier,
so the hold stays. The acorn insert now ends the hold on its own line when the next statement
shares the timeline line, matching what removal takes, so a second sync changes no bytes.

* fix(parsers): the recast hold sync reads tween starts from the acorn parse

The recast parser cannot resolve label positions, so an earlier label-placed tween looked
unordered and kept a hold it should not. Both writers now decide holds on the same parse.

* revert(parsers): keep the recast hold sync on its own parse

Deciding recast holds on the acorn parse lost selectors only recast resolves (an element bound
through a helper). Recast is the migration fallback and keeps its old hold for a start it cannot
resolve; the earlier-label case is decided by the default acorn writer, which resolves labels.

* style(parsers): name the hold insert's line ending instead of commenting it

* style(parsers): fit the hold helper's doc in four lines

* test(studio): bank the from/to edits this fix makes accurate and the resizes #4920 fixed

This branch was successfully deployed

1 active deployment
staging - docs — 16f74dc5 Deployed Oct 3, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant