Skip to content

fix(array): reconcile by identifier when applySnapshot moves children - #2311

Open
lavrton wants to merge 2 commits into
mobxjs:masterfrom
lavrton:fix/array-apply-snapshot-moves
Open

lavrton wants to merge 2 commits into
mobxjs:masterfrom
lavrton:fix/array-apply-snapshot-moves

Conversation

@lavrton

@lavrton lavrton commented Oct 21, 2026 •

Copy link
Copy Markdown

What does this PR do and why?

Two changes to applySnapshot on arrays of identified children.

  1. A moved child keeps its node. Since Optimize applySnapshot for mostly unchanged snapshots #2285 an unchanged-length snapshot assigns each changed index in place, which reconciles against the one node at that index. When a child moved, every index between its old and new position gets a new node. Now, when a changed entry carries the identifier of another current child, the array uses replace, whose reconciliation finds the node by identifier and moves it. In Polotno, undoing one page reorder in a 100-page document recreated 71 pages; now none.

  2. A snapshot is validated once. areSame validated a candidate (type.is) before comparing identifiers, so during reconciliation's look-ahead an inserted snapshot was validated once per following child. The identifier check now comes first for plain types; a snapshotProcessor keeps the old order, since its preProcessor may throw on a snapshot of another union member (union.test.ts).

Steps to validate locally

  • bun test __tests__/core/array-apply-snapshot-moves.test.ts — all three tests fail on master.
  • NODE_ENV=development bun test and MST_TESTING=1 NODE_ENV=production bun test are green.

@lavrton lavrton closed this Oct 21, 2026
@lavrton lavrton reopened this Oct 21, 2026
@lavrton
lavrton marked this pull request as ready for review October 21, 2026 18:56

This branch has not been deployed

No deployments
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