From c24e8b35fa4a4f649ce920b1a71f0d27ca725fe9 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:50:34 +0200 Subject: [PATCH 1/5] feat(core): add `useNodeConnections` composable --- .../src/composables/useNodeConnections.ts | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 packages/core/src/composables/useNodeConnections.ts diff --git a/packages/core/src/composables/useNodeConnections.ts b/packages/core/src/composables/useNodeConnections.ts new file mode 100644 index 000000000..496cc4858 --- /dev/null +++ b/packages/core/src/composables/useNodeConnections.ts @@ -0,0 +1,119 @@ +import type { ComputedRef, MaybeRefOrGetter } from 'vue' +import { computed, ref, toRef, toValue, watch } from 'vue' +import type { HandleConnection, HandleElement, HandleType } from '../types' +import { useNodeId } from './useNodeId' +import { useVueFlow } from './useVueFlow' + +export interface UseNodeConnectionsParams { + type: MaybeRefOrGetter + nodeId?: MaybeRefOrGetter + onConnect?: (connections: HandleConnection[]) => void + onDisconnect?: (connections: HandleConnection[]) => void +} + +/** + * Composable that returns existing connections of a node. + * + * @public + * @param params + * @param params.type - handle type `source` or `target` + * @param params.nodeId - node id - if not provided, the node id from the `useNodeId` (meaning, the context-based injection) is used + * @param params.onConnect - gets called when a connection is created + * @param params.onDisconnect - gets called when a connection is removed + * + * @returns An array of connections + */ +export function useNodeConnections(params: UseNodeConnectionsParams): ComputedRef { + const { type, nodeId, onConnect, onDisconnect } = params + + const { connectionLookup, findNode } = useVueFlow() + + const _nodeId = useNodeId() + + const currentNodeId = toRef(() => toValue(nodeId) ?? _nodeId) + + const handleType = toRef(() => toValue(type)) + + const node = computed(() => findNode(currentNodeId.value)) + + const handleIds = computed(() => { + if (!node.value) { + return [] + } + + const handles: HandleElement['id'][] = [] + for (const handle of node.value?.handleBounds?.[handleType.value] ?? []) { + handles.push(handle.id) + } + + return handles + }) + + const prevConnections = ref | null>(null) + + const connectionsFromLookup = computed(() => { + const nodeConnections = [] as Map[] + + for (const handleId of handleIds.value) { + const connectionMap = connectionLookup.value.get(`${currentNodeId.value}-${handleType.value}-${handleId}`) + if (connectionMap) { + nodeConnections.push(connectionMap) + } + } + + return nodeConnections + }) + + watch( + [connectionsFromLookup, () => typeof onConnect !== 'undefined', () => typeof onDisconnect !== 'undefined'], + ([currentConnections]) => { + if (!currentConnections) { + return + } + + const newConnections = new Map() + + for (const connectionMap of currentConnections) { + for (const [key, connection] of connectionMap) { + newConnections.set(key, connection) + } + } + + if (!prevConnections.value) { + prevConnections.value = new Map(newConnections) + return + } + + const prevConnectionsValue = prevConnections.value + + const addedConnections = Array.from(newConnections.keys()).filter((key) => !prevConnectionsValue.has(key)) + + const removedConnections = Array.from(prevConnectionsValue.keys()).filter((key) => !newConnections.has(key)) + + if (addedConnections.length && onConnect) { + const added = addedConnections.map((key) => newConnections.get(key)!) + onConnect(added) + } + + if (removedConnections.length && onDisconnect) { + const removed = removedConnections.map((key) => prevConnectionsValue.get(key)!) + onDisconnect(removed) + } + + prevConnections.value = new Map(newConnections) + }, + { immediate: true }, + ) + + return computed(() => { + const connections = [] as HandleConnection[] + + for (const connectionMap of connectionsFromLookup.value) { + for (const connection of connectionMap.values()) { + connections.push(connection) + } + } + + return connections + }) +} From d8416842b14776b2d88493bf71c0a7c4106dea86 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sun, 9 Jun 2024 08:50:40 +0200 Subject: [PATCH 2/5] chore(core): export `useNodeConnections` --- packages/core/src/composables/useNodeConnections.ts | 3 ++- packages/core/src/index.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/composables/useNodeConnections.ts b/packages/core/src/composables/useNodeConnections.ts index 496cc4858..9ef53ab23 100644 --- a/packages/core/src/composables/useNodeConnections.ts +++ b/packages/core/src/composables/useNodeConnections.ts @@ -12,7 +12,8 @@ export interface UseNodeConnectionsParams { } /** - * Composable that returns existing connections of a node. + * Composable that returns existing connections of a node by handle type. + * This is useful when you want to get all connections of a node by a specific handle type. * * @public * @param params diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 371c4dfa9..782f2ed2b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -70,6 +70,7 @@ export { useGetPointerPosition } from './composables/useGetPointerPosition' export { useNodeId } from './composables/useNodeId' export { useConnection } from './composables/useConnection' export { useHandleConnections } from './composables/useHandleConnections' +export { useNodeConnections } from './composables/useNodeConnections' export { useNodesData } from './composables/useNodesData' export { useEdgesData } from './composables/useEdgesData' export { useNodesInitialized } from './composables/useNodesInitialized' From 91eca2333cdea3a489a332e3ce1b83e580a8ff43 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sun, 9 Jun 2024 09:06:41 +0200 Subject: [PATCH 3/5] chore(docs): update math example --- docs/examples/math/ResultNode.vue | 12 ++++++------ examples/vite/src/Math/ResultNode.vue | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/docs/examples/math/ResultNode.vue b/docs/examples/math/ResultNode.vue index 2e15a807d..999f1ab82 100644 --- a/docs/examples/math/ResultNode.vue +++ b/docs/examples/math/ResultNode.vue @@ -1,6 +1,6 @@