diff --git a/.changeset/plenty-garlics-fail.md b/.changeset/plenty-garlics-fail.md new file mode 100644 index 00000000..c6bd753e --- /dev/null +++ b/.changeset/plenty-garlics-fail.md @@ -0,0 +1,5 @@ +--- +'@xyflow/svelte': patch +--- + +Fix `useNodeConnections` callbacks firing only when returned signal is used diff --git a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte index a9f14360..2f9f72bb 100644 --- a/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte +++ b/examples/svelte/src/routes/examples/usenodesdata/ResultNode.svelte @@ -16,6 +16,15 @@ handleType: 'target' }); + useNodeConnections({ + onConnect: (connection) => { + console.log('Connection made:', connection); + }, + onDisconnect: (connection) => { + console.log('Connection disconnected:', connection); + } + }); + let nodeData = $derived( useNodesData(connections.current.map((connection) => connection.source)) ); diff --git a/packages/svelte/src/lib/hooks/useNodeConnections.svelte.ts b/packages/svelte/src/lib/hooks/useNodeConnections.svelte.ts index 111fc715..8e7216b6 100644 --- a/packages/svelte/src/lib/hooks/useNodeConnections.svelte.ts +++ b/packages/svelte/src/lib/hooks/useNodeConnections.svelte.ts @@ -17,6 +17,8 @@ type UseNodeConnectionsParams = { onDisconnect?: (connections: Connection[]) => void; }; +type ConnectionMap = Map; + const initialConnections: NodeConnection[] = []; /** @@ -42,26 +44,46 @@ export function useNodeConnections({ const contextNodeId = getContext('svelteflow__node_id'); const nodeId = id ?? contextNodeId; - let prevConnections: Map = new Map(); + let connectionMaps: { previous: ConnectionMap; next: ConnectionMap } = { + previous: new Map(), + next: new Map() + }; let connectionsArray: NodeConnection[] = initialConnections; const connections = $derived.by(() => { // eslint-disable-next-line @typescript-eslint/no-unused-expressions edges; + + const prevConnections = connectionMaps.next; const nextConnections = connectionLookup.get( `${nodeId}${handleType ? (handleId ? `-${handleType}-${handleId}` : `-${handleType}`) : ''}` ) ?? new Map(); if (!areConnectionMapsEqual(nextConnections, prevConnections)) { - if (onConnect) handleConnectionChange(nextConnections, prevConnections, onConnect); - if (onDisconnect) handleConnectionChange(prevConnections, nextConnections, onDisconnect); - - prevConnections = nextConnections; + connectionMaps = { + previous: prevConnections, + next: nextConnections + }; connectionsArray = Array.from(nextConnections.values() || initialConnections); } return connectionsArray; }); + $effect(() => { + // We subscribe to changes to the connections only when onConnect/onDisconnect are provided + if (onConnect) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + connections; + handleConnectionChange(connectionMaps.next, connectionMaps.previous, onConnect); + } + + if (onDisconnect) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + connections; + handleConnectionChange(connectionMaps.previous, connectionMaps.next, onDisconnect); + } + }); + return { get current() { return connections;