Fixed rerendering of edges & simplified rerendering of nodes

This commit is contained in:
peterkogo
2024-12-12 12:11:07 +01:00
parent 24735aa003
commit 9105d22c46
6 changed files with 31 additions and 24 deletions
@@ -45,7 +45,11 @@
initialHeight, initialHeight,
width, width,
height, height,
dragHandle dragHandle,
internals: {
z: zIndex = 0,
positionAbsolute: { x: positionX, y: positionY }
}
} = $derived(node); } = $derived(node);
let { id } = node; let { id } = node;
@@ -55,19 +59,6 @@
let connectable = $derived(_connectable ?? store.nodesConnectable); let connectable = $derived(_connectable ?? store.nodesConnectable);
let initialized = $derived(nodeHasDimensions(node)); let initialized = $derived(nodeHasDimensions(node));
// we also pass store.nodes to this function to rerender when a node changes
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getInternalNode(node: Node, nodes: Node[]) {
return { ...store.nodeLookup.get(node.id)! };
}
let {
internals: {
z: zIndex = 0,
positionAbsolute: { x: positionX, y: positionY }
}
} = $derived(getInternalNode(node, store.nodes));
function isInParentLookup(id: string) { function isInParentLookup(id: string) {
return store.parentLookup.has(id); return store.parentLookup.has(id);
} }
@@ -1,12 +1,12 @@
import type { SvelteFlowStore } from '$lib/store/types'; import type { SvelteFlowStore } from '$lib/store/types';
import type { Node } from '$lib/types'; import type { InternalNode } from '$lib/types';
export type ConnectableContext = { export type ConnectableContext = {
value: boolean; value: boolean;
}; };
export type NodeWrapperProps = { export type NodeWrapperProps = {
node: Node; node: InternalNode;
store: SvelteFlowStore; store: SvelteFlowStore;
nodeClickDistance?: number; nodeClickDistance?: number;
resizeObserver?: ResizeObserver | null; resizeObserver?: ResizeObserver | null;
@@ -28,10 +28,17 @@
continue; continue;
} }
// we reuse the previous edge object if the source and target node are the same as before // we reuse the previous edge object if
// references to internalNodes that haven't changed stay the same // the current and previous edge are the same
// and the source and target node are the same
// and references to internalNodes are the same
const previous = previousLayoutedEdges.get(edge.id); const previous = previousLayoutedEdges.get(edge.id);
if (previous && sourceNode == previous.sourceNode && targetNode == previous.targetNode) { if (
previous &&
edge == previous.edge &&
sourceNode == previous.sourceNode &&
targetNode == previous.targetNode
) {
layoutedEdges.set(edge.id, previous); layoutedEdges.set(edge.id, previous);
continue; continue;
} }
@@ -58,7 +65,8 @@
}), }),
...edgePosition, ...edgePosition,
sourceNode, sourceNode,
targetNode targetNode,
edge
}); });
} }
} }
@@ -3,8 +3,9 @@
import { NodeWrapper } from '$lib/components/NodeWrapper'; import { NodeWrapper } from '$lib/components/NodeWrapper';
import type { NodeEvents } from '$lib/types'; import type { Node, NodeEvents } from '$lib/types';
import type { SvelteFlowStore } from '$lib/store/types'; import type { SvelteFlowStore } from '$lib/store/types';
import type { NodeLookup } from '@xyflow/system';
let { let {
store, store,
@@ -41,10 +42,15 @@
onDestroy(() => { onDestroy(() => {
resizeObserver?.disconnect(); resizeObserver?.disconnect();
}); });
// We pass an unused reference to nodes to trigger a re-render
function getNodes(nodeLookup: NodeLookup, nodes: Node[]) {
return nodeLookup.values();
}
</script> </script>
<div class="svelte-flow__nodes"> <div class="svelte-flow__nodes">
{#each store.nodes as node (node.id)} {#each getNodes(store.nodeLookup, store.nodes) as node (node.id)}
<NodeWrapper <NodeWrapper
{store} {store}
{node} {node}
@@ -91,13 +91,14 @@ export const getInitialStore = (signals: StoreSignals) => {
connectionLookup: ConnectionLookup = new Map(); connectionLookup: ConnectionLookup = new Map();
edgeLookup: EdgeLookup = new Map(); edgeLookup: EdgeLookup = new Map();
adoptNodes: Set<string> = $derived.by(() => { adoptNodes: true = $derived.by(() => {
return adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, { adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, {
nodeExtent: this.nodeExtent, nodeExtent: this.nodeExtent,
nodeOrigin: this.nodeOrigin, nodeOrigin: this.nodeOrigin,
elevateNodesOnSelect: false, elevateNodesOnSelect: false,
checkEquality: true checkEquality: true
}); });
return true;
}); });
adoptEdges: true = $derived.by(() => { adoptEdges: true = $derived.by(() => {
updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges); updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges);
+1
View File
@@ -176,4 +176,5 @@ export type EdgeLayouted = Pick<
targetNode?: Node; targetNode?: Node;
sourceHandleId?: string | null; sourceHandleId?: string | null;
targetHandleId?: string | null; targetHandleId?: string | null;
edge: Edge;
}; };