ls1intum / Apollon

UML Modeling Editor written in React
https://apollon-library.readthedocs.io
MIT License
66 stars 22 forks source link

make patching-induced rerenders stable #335

Closed loreanvictor closed 9 months ago

loreanvictor commented 9 months ago

Checklist

Motivation and Context

Currently in Apollon, when a patch is imported (via .importPatch()), it will result in all elements of the diagram being re-rendered (re-constructed from scratch), lowering performance and stability.

Description

This PR introduces an option for patcher-reducer to accept custom merge functions for updating state (instead of the default naive solution of object assignment). It also adds a specific merge function for ModelState that merges two model states gracefully, maintaining instance references and diagram boundaries, and gracefully updating diagram metadata. As a result, the subsequent re-render of the diagram maintains all SVG elements and only updates / reconstructs what is necessary.

Steps for Testing

  1. Clone this PR
  2. Clone Apollon standalone
  3. Link Apollon with this PR to Apollon standalone
  4. Build and run Apollon standalone. Share a diagram for collaboration, open in two separate browser instances.
  5. Inspect an element of the diagram in one browser instance, change something in the diagram in the other browser instance. The element should remain the same except for change of ownership or when it is deleted. You can verify this by adding a custom HTML attribute (e.g. data-x="42") to the element, and verifying that it still exists after the clients sync on the changes.

Test Coverage

File Branch Line
components/store/merge.ts 100% 100%
components/store/model-store.tsx 100% 100%
services/patcher/patcher-reducer.ts 100% 100%