72 lines
2.5 KiB
TypeScript
72 lines
2.5 KiB
TypeScript
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<HandleType>
|
|
id?: MaybeRefOrGetter<string | null>
|
|
nodeId?: MaybeRefOrGetter<string | null>
|
|
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<Connection[]> {
|
|
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<Map<string, Connection>>()
|
|
|
|
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() ?? []))
|
|
}
|