import type { ComputedRef } from 'vue' import { computed, ref, watch } from 'vue' import type { MaybeRefOrGetter } from '@vueuse/core' import { toRef, toValue } from '@vueuse/core' import type { Connection, HandleType } from '../types' import { areConnectionMapsEqual, handleConnectionChange } from '../utils' import { useNodeId } from './useNodeId' import { useVueFlow } from './useVueFlow' export interface UseHandleConnectionsParams { type: MaybeRefOrGetter id?: MaybeRefOrGetter nodeId?: MaybeRefOrGetter onConnect?: (connections: Connection[]) => void onDisconnect?: (connections: Connection[]) => void } /** * Composable that returns existing connections of a handle * * @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.id - the handle id (this is required if the node has multiple handles of the same type) * @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 useHandleConnections(params: UseHandleConnectionsParams): ComputedRef { const { type, id, nodeId, onConnect, onDisconnect } = params const { connectionLookup } = useVueFlow() const _nodeId = useNodeId() const currentNodeId = toRef(() => toValue(nodeId) ?? _nodeId) const handleType = toRef(() => toValue(type)) const handleId = toRef(() => toValue(id) ?? null) const connections = ref>() watch( () => connectionLookup.value.get(`${currentNodeId.value}-${handleType.value}-${handleId.value}`), (nextConnections) => { if (areConnectionMapsEqual(connections.value, nextConnections)) { return } connections.value = nextConnections }, { immediate: true }, ) watch( [connections, () => typeof onConnect !== 'undefined', () => typeof onDisconnect !== 'undefined'], ([currentConnections], [prevConnections]) => { if (prevConnections && prevConnections !== currentConnections) { const _connections = currentConnections ?? new Map() handleConnectionChange(prevConnections, _connections, onDisconnect) handleConnectionChange(_connections, prevConnections, onConnect) } }, { immediate: true }, ) return computed(() => Array.from(connections.value?.values() ?? [])) }