Skip to content

fix(joint-react): prevent stale layout:update entries from resurrecting removed cells (dev) - #3495

Open
samuelgja wants to merge 5 commits into
clientIO:devfrom
samuelgja:fix/react-external-graph-undo-dev
Open

fix(joint-react): prevent stale layout:update entries from resurrecting removed cells (dev)#3495
samuelgja wants to merge 5 commits into
clientIO:devfrom
samuelgja:fix/react-external-graph-undo-dev

Conversation

@samuelgja

Copy link
Copy Markdown
Contributor

Description

Dev-branch port of the externally-owned-graph undo fix (see the companion PR against
master: #3494). The reworked projection on dev (immutable snapshot
container with stageWrite/stageRemove pending buckets) carries the identical defect —
verified by running the same failing test against dev before the fix.

Same three invariants, adapted to the staged container:

  • add/change entries are gated on graph membership; a stale entry repairs a lingering
    record via stageRemove (only when currentRecord(id) exists, so the incremental delta
    is not polluted with removals of never-present ids).
  • remove entries only apply when the cell has actually left the graph (paper view-unmount
    notifications can name still-mounted cells, e.g. viewport culling).
  • The orphaned-link sweep runs once per batch over the committed snapshot plus both pending
    buckets, keyed on the batch's removed-element set, and skips links the graph still holds.

Plus the same use-create-portal-paper.tsx recheck of pendingLinks after element-portal
commits, and the same test files.

Note for the future masterdev sync: this PR pre-resolves the merge for
graph-projection.ts — on conflict, take the dev side (it already contains the fix, and
the shared external-graph-undo.test.tsx verifies the resolution). No changeset here on
purpose: the master PR carries the release entry, and a second one would duplicate the
changelog when dev merges down.

Motivation and Context

Same customer report as the master PR: delete an element with a link, undo, and the
restored element renders empty with its link permanently hidden. master is the patch line
for the affected 4.3.5 release; this keeps dev's state rework from shipping the same bug.

Screenshots (if appropriate):

@samuelgja
samuelgja requested review from kumilingus and a lite review from Copilot September 3, 2026 06:01
@samuelgja
samuelgja marked this pull request as ready for review September 3, 2026 06:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new remove handling can emit incremental “removed” ids for records that never existed in the container (data-less layout:update removals), which can break consumers relying on accurate deltas.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Ports the external-graph undo fix to dev’s staged snapshot container so stale layout:update entries can’t resurrect removed records, and so link records don’t remain stranded/hidden after delete+undo in externally-owned graphs.

Changes:

  • Harden graphProjection against stale add/change/remove entries by gating writes/removals on current graph membership and sweeping orphaned link records once per removal batch.
  • Add/adjust tests to reproduce the stale-record + missed-link-removal scenarios and assert container correctness.
  • Recheck pendingLinks after element-portal React commits so links parked hidden by insertView don’t remain hidden indefinitely.
File summaries
File Description
packages/joint-react/src/store/graph-projection.ts Adds graph-membership gating for staged writes/removals and a post-batch orphan-link sweep to prevent stale records from resurfacing.
packages/joint-react/src/store/tests/graph-projection-edge-cases.test.ts Updates edge-case test to simulate a missed link removal and verify the new orphan-link sweep behavior.
packages/joint-react/src/hooks/use-create-portal-paper.tsx Adds a useEffect to re-run checkPendingLinks() after portal content commits.
packages/joint-react/src/components/graph/tests/external-graph-undo.test.tsx New integration-style tests covering delete+undo and stale layout:update races for externally-owned graphs.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/joint-react/src/store/graph-projection.ts
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.

2 participants