Apply teammates' changes item by item instead of reloading the page (#208)

* Apply teammates' changes item by item instead of reloading the page

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Hold duplicates and full page swaps, look up rotation targets by id, keep held items in place

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep each element's sortIndex so a deletion re-sends no other element

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Send a moved element's new stacking, keep held undrawable lineup bases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Stack by hydrated order on ties; held items take the server's place

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep unchanged items as they are on a merge; rebuild only new drawing paths

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Judge unchanged against what the canvas drew, not the last ack

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Held items conflict against what the user saw, not an unseen ack

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Count acks of ops this session sent as seen, even after more typing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Back out the unchanged-item reuse; keep its regression tests

Reusing unchanged items on a merge needed live sync to track what the
canvas drew separately from what the server acked, and each attempt at
that left another way to rewind a revision. Server-wins for every item
the user isn't holding is the reviewed behaviour; its path rebuild cost
matches the full reload it replaced. The three new tests still hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
d967315486Dara Adedeji committed on 9/28/2026, 4:43:12 PM· committed by GitHubparentd7d9d58
20 files changedLine totals unavailable