From 6fd9d19797ca72997d0c0afdbb71418e2238c825 Mon Sep 17 00:00:00 2001
From: Peter
Date: Thu, 5 Oct 2023 13:28:04 +0200
Subject: [PATCH] feat(react, svelte) added getIncomers & getOutgoers to
use...Flow()
---
packages/react/src/hooks/useReactFlow.ts | 36 +++++++++++++++++--
packages/react/src/types/instance.ts | 2 ++
.../svelte/src/lib/hooks/useSvelteFlow.ts | 24 +++++++++++++
packages/system/src/utils/graph.ts | 8 ++---
4 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts
index cec31cc8..8e94954a 100644
--- a/packages/react/src/hooks/useReactFlow.ts
+++ b/packages/react/src/hooks/useReactFlow.ts
@@ -1,5 +1,13 @@
import { useCallback, useMemo } from 'react';
-import { getElementsToRemove, getOverlappingArea, isRectObject, nodeToRect, type Rect } from '@xyflow/system';
+import {
+ getElementsToRemove,
+ getIncomersBase,
+ getOutgoersBase,
+ getOverlappingArea,
+ isRectObject,
+ nodeToRect,
+ type Rect,
+} from '@xyflow/system';
import useViewportHelper from './useViewportHelper';
import { useStoreApi } from '../hooks/useStore';
@@ -224,7 +232,7 @@ export default function useReactFlow(): ReactFlo
);
const getConnectedEdges = useCallback((node) => {
- const edges = store.getState().edges;
+ const { edges } = store.getState();
const nodeIds = new Set();
if (typeof node === 'string') {
@@ -238,6 +246,26 @@ export default function useReactFlow(): ReactFlo
return edges.filter((edge) => nodeIds.has(edge.source) || nodeIds.has(edge.target));
}, []);
+ const getIncomers = useCallback((node) => {
+ const { nodes, edges } = store.getState();
+
+ if (typeof node === 'string') {
+ return getIncomersBase({ id: node }, nodes, edges);
+ }
+
+ return getIncomersBase(node, nodes, edges);
+ }, []);
+
+ const getOutgoers = useCallback((node) => {
+ const { nodes, edges } = store.getState();
+
+ if (typeof node == 'string') {
+ return getOutgoersBase({ id: node }, nodes, edges);
+ }
+
+ return getOutgoersBase(node, nodes, edges);
+ }, []);
+
return useMemo(() => {
return {
...viewportHelper,
@@ -254,6 +282,8 @@ export default function useReactFlow(): ReactFlo
getIntersectingNodes,
isNodeIntersecting,
getConnectedEdges,
+ getIncomers,
+ getOutgoers,
};
}, [
viewportHelper,
@@ -270,5 +300,7 @@ export default function useReactFlow(): ReactFlo
getIntersectingNodes,
isNodeIntersecting,
getConnectedEdges,
+ getIncomers,
+ getOutgoers,
]);
}
diff --git a/packages/react/src/types/instance.ts b/packages/react/src/types/instance.ts
index 0bc61617..694329fb 100644
--- a/packages/react/src/types/instance.ts
+++ b/packages/react/src/types/instance.ts
@@ -40,6 +40,8 @@ export namespace Instance {
partially?: boolean
) => boolean;
export type getConnectedEdges = (id: string | (Partial & { id: Node['id'] })[]) => Edge[];
+ export type getIncomers = (node: string | (Partial & { id: Node['id'] })) => Node[];
+ export type getOutgoers = (node: string | (Partial & { id: Node['id'] })) => Node[];
}
export type ReactFlowInstance = {
diff --git a/packages/svelte/src/lib/hooks/useSvelteFlow.ts b/packages/svelte/src/lib/hooks/useSvelteFlow.ts
index 191b2ea0..c3b6caec 100644
--- a/packages/svelte/src/lib/hooks/useSvelteFlow.ts
+++ b/packages/svelte/src/lib/hooks/useSvelteFlow.ts
@@ -1,5 +1,7 @@
import { get, type Writable } from 'svelte/store';
import {
+ getIncomersBase,
+ getOutgoersBase,
pointToRendererPoint,
type Project,
type SetCenterOptions,
@@ -27,6 +29,8 @@ export function useSvelteFlow(): {
nodes: SvelteFlowStore['nodes'];
edges: SvelteFlowStore['edges'];
getConnectedEdges: (id: string | (Partial & { id: Node['id'] })[]) => Edge[];
+ getIncomers: (node: string | (Partial & { id: Node['id'] })) => Node[];
+ getOutgoers: (node: string | (Partial & { id: Node['id'] })) => Node[];
} {
const {
zoomIn,
@@ -101,6 +105,26 @@ export function useSvelteFlow(): {
return _edges.filter((edge) => nodeIds.has(edge.source) || nodeIds.has(edge.target));
},
+ getIncomers: (node) => {
+ const _edges = get(edges);
+ const _nodes = get(nodes);
+
+ if (typeof node === 'string') {
+ return getIncomersBase({ id: node }, _nodes, _edges);
+ }
+
+ return getIncomersBase(node, _nodes, _edges);
+ },
+ getOutgoers: (node) => {
+ const _edges = get(edges);
+ const _nodes = get(nodes);
+
+ if (typeof node == 'string') {
+ return getOutgoersBase({ id: node }, _nodes, _edges);
+ }
+
+ return getOutgoersBase(node, _nodes, _edges);
+ },
viewport: viewport
};
}
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index e72642be..17467503 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -35,11 +35,11 @@ export const isNodeBase = 'id' in element && !('source' in element) && !('target' in element);
export const getOutgoersBase = (
- node: NodeType,
+ node: Partial & { id: string },
nodes: NodeType[],
edges: EdgeType[]
): NodeType[] => {
- if (!isNodeBase(node)) {
+ if (!node.id) {
return [];
}
@@ -54,11 +54,11 @@ export const getOutgoersBase = (
- node: NodeType,
+ node: Partial & { id: string },
nodes: NodeType[],
edges: EdgeType[]
): NodeType[] => {
- if (!isNodeBase(node)) {
+ if (!node.id) {
return [];
}
const incomersIds = new Set();