fix(joint-react): re-measure auto-sized elements after external size writes - #3485
Draft
samuelgja wants to merge 1 commit into
Draft
fix(joint-react): re-measure auto-sized elements after external size writes#3485samuelgja wants to merge 1 commit into
samuelgja wants to merge 1 commit into
Conversation
…writes An external size write (controlled-mode sync, cell.resize) on a measured element could leave the model silently diverged from the DOM: the measurement pipeline does not re-fire when the DOM did not change, and its last-measurement dedup memory swallowed a delivery repeating the pre-write numbers. Under rapid state toggling (e.g. collapse/expand of a measured card) this left elements stuck at a stale measured size. The graph store now invalidates the cell's measurement state on any non-autoSize change:size: the dedup memory is cleared and the active node is re-observed, which forces the ResizeObserver to deliver the current layout so the measured size is re-asserted. Re-activating a node from the measurement stack also starts with a clean memory, closing the same hole in the multi-hook fallback path.
samuelgja
force-pushed
the
fix/stale-auto-size-write
branch
from
August 26, 2026 04:18
8fca355 to
a0a1120
Compare
samuelgja
marked this pull request as draft
August 26, 2026 14:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Hardening of the auto-size measurement pipeline: writes from outside the pipeline (controlled-mode sync,
cell.resize()) and the ResizeObserver measurements no longer leave the model silently diverged from the DOM.Three defects fixed:
lastWidth/lastHeightguard — the model kept the external size while the DOM showed the measured one, permanently.The fix:
GraphStorelistens to every non-autoSizechange:sizeand invalidates the cell's measurement state — the dedup memory is cleared and the active node re-observed (unobserve()resets the observer's last-reported size, soobserve()forces a fresh delivery;observe()alone is a spec no-op for an already-observed target). The invalidation also records the size the write replaced: exactly one following delivery matching it is treated as a pre-re-render echo — dropped, with the node re-observed once more so the settled layout gets its own delivery. Re-activating a node from the multi-useMeasureElementstack also starts with clean measurement memory, closing the same dedup hole in the fallback path.The pipeline's own writes are marked with the
autoSizeoption and skipped, so there is no feedback loop; for unobserved (useModelGeometry) elements the listener is an O(1) no-op.Motivation and Context
Found while investigating a JointJS+ demo where rapid collapse/expand toggling desynced a group's size from its data. Note the scope honestly: the demo's element-orphaning itself turned out to be caused elsewhere (a spatial-index staleness in JointJS+, fixed separately there) — this PR does not claim to fix that. What it fixes are the measurement-pipeline defects above, which are real, deterministic, and reproducible in unit tests: without this change an element whose size is written externally can stay diverged from its rendered DOM indefinitely.
Tests (written first, failing before the fix): a graph-store integration test driving the real pipeline (measure → external resize → echo dropped → settled re-measurement wins), a re-observation mechanism test, an
autoSizeno-feedback-loop guard, echo one-shot semantics, and observer-level unit tests forinvalidate. Full suite green.