Fix visited set bug in Graph class and refactor GenericNode component (#1917)

* format

* chore: Fix visited set bug in Graph class

* Refactor GenericNode component to improve build status handling
This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-05-17 15:28:02 -07:00 • committed by GitHub
commit c3353bec37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 31 deletions

View file

@ -468,9 +468,9 @@ class Graph:
"""Marks a branch of the graph.""" """Marks a branch of the graph."""
if visited is None: if visited is None:
visited = set() visited = set()
visited.add(vertex_id)
if vertex_id in visited: if vertex_id in visited:
return return
visited.add(vertex_id)
self.mark_vertex(vertex_id, state) self.mark_vertex(vertex_id, state)

View file

@ -303,7 +303,7 @@ export default function GenericNode({
) => { ) => {
let isInvalid = validationStatus && !validationStatus.valid; let isInvalid = validationStatus && !validationStatus.valid;
if (buildStatus === BuildStatus.INACTIVE && isInvalid) { if (buildStatus === BuildStatus.INACTIVE) {
// INACTIVE should have its own class // INACTIVE should have its own class
return "inactive-status"; return "inactive-status";
} }
@ -329,6 +329,7 @@ export default function GenericNode({
buildStatus, buildStatus,
validationStatus validationStatus
); );
const baseBorderClass = getBaseBorderClass(selected); const baseBorderClass = getBaseBorderClass(selected);
const nodeSizeClass = getNodeSizeClass(showNode); const nodeSizeClass = getNodeSizeClass(showNode);
return classNames( return classNames(
@ -383,7 +384,6 @@ export default function GenericNode({
isOutdated, isOutdated,
selected, selected,
]); ]);
return ( return (
<> <>
{memoizedNodeToolbarComponent} {memoizedNodeToolbarComponent}

View file

@ -44,7 +44,6 @@ import { getInputsAndOutputs } from "../utils/storeUtils";
import useAlertStore from "./alertStore"; import useAlertStore from "./alertStore";
import { useDarkStore } from "./darkStore"; import { useDarkStore } from "./darkStore";
import useFlowsManagerStore from "./flowsManagerStore"; import useFlowsManagerStore from "./flowsManagerStore";
import FlowPage from "../pages/FlowPage";
// this is our useStore hook that we can use in our components to get parts of the store and call actions // this is our useStore hook that we can use in our components to get parts of the store and call actions
const useFlowStore = create<FlowStoreType>((set, get) => ({ const useFlowStore = create<FlowStoreType>((set, get) => ({
@ -80,7 +79,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
updateFlowPool: ( updateFlowPool: (
nodeId: string, nodeId: string,
data: FlowPoolObjectType | ChatOutputType | chatInputType, data: FlowPoolObjectType | ChatOutputType | chatInputType,
buildId?: string, buildId?: string
) => { ) => {
let newFlowPool = cloneDeep({ ...get().flowPool }); let newFlowPool = cloneDeep({ ...get().flowPool });
if (!newFlowPool[nodeId]) { if (!newFlowPool[nodeId]) {
@ -171,7 +170,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
flowsManager.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
newChange, newChange,
newEdges, newEdges,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }
); );
} }
}, },
@ -187,7 +186,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
flowsManager.autoSaveCurrentFlow( flowsManager.autoSaveCurrentFlow(
get().nodes, get().nodes,
newChange, newChange,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }
); );
} }
}, },
@ -205,7 +204,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
return newChange; return newChange;
} }
return node; return node;
}), })
); );
}, },
getNode: (id: string) => { getNode: (id: string) => {
@ -216,8 +215,8 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
get().nodes.filter((node) => get().nodes.filter((node) =>
typeof nodeId === "string" typeof nodeId === "string"
? node.id !== nodeId ? node.id !== nodeId
: !nodeId.includes(node.id), : !nodeId.includes(node.id)
), )
); );
}, },
deleteEdge: (edgeId) => { deleteEdge: (edgeId) => {
@ -225,8 +224,8 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
get().edges.filter((edge) => get().edges.filter((edge) =>
typeof edgeId === "string" typeof edgeId === "string"
? edge.id !== edgeId ? edge.id !== edgeId
: !edgeId.includes(edge.id), : !edgeId.includes(edge.id)
), )
); );
}, },
paste: (selection, position) => { paste: (selection, position) => {
@ -292,7 +291,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
let source = idsMap[edge.source]; let source = idsMap[edge.source];
let target = idsMap[edge.target]; let target = idsMap[edge.target];
const sourceHandleObject: sourceHandleType = scapeJSONParse( const sourceHandleObject: sourceHandleType = scapeJSONParse(
edge.sourceHandle!, edge.sourceHandle!
); );
let sourceHandle = scapedJSONStringfy({ let sourceHandle = scapedJSONStringfy({
...sourceHandleObject, ...sourceHandleObject,
@ -302,7 +301,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
edge.data.sourceHandle = sourceHandleObject; edge.data.sourceHandle = sourceHandleObject;
const targetHandleObject: targetHandleType = scapeJSONParse( const targetHandleObject: targetHandleType = scapeJSONParse(
edge.targetHandle!, edge.targetHandle!
); );
let targetHandle = scapedJSONStringfy({ let targetHandle = scapedJSONStringfy({
...targetHandleObject, ...targetHandleObject,
@ -323,7 +322,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
className: "stroke-gray-900 ", className: "stroke-gray-900 ",
selected: false, selected: false,
}, },
newEdges.map((edge) => ({ ...edge, selected: false })), newEdges.map((edge) => ({ ...edge, selected: false }))
); );
}); });
get().setEdges(newEdges); get().setEdges(newEdges);
@ -342,10 +341,10 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
}); });
const newNodes = get().nodes.filter( const newNodes = get().nodes.filter(
(node) => !nodesIdsSelected.includes(node.id), (node) => !nodesIdsSelected.includes(node.id)
); );
const newEdges = get().edges.filter( const newEdges = get().edges.filter(
(edge) => !edgesIdsSelected.includes(edge.id), (edge) => !edgesIdsSelected.includes(edge.id)
); );
set({ nodes: newNodes, edges: newEdges }); set({ nodes: newNodes, edges: newEdges });
@ -403,7 +402,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
style: { stroke: "#555" }, style: { stroke: "#555" },
className: "stroke-foreground stroke-connection", className: "stroke-foreground stroke-connection",
}, },
oldEdges, oldEdges
); );
return newEdges; return newEdges;
@ -413,7 +412,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
.autoSaveCurrentFlow( .autoSaveCurrentFlow(
get().nodes, get().nodes,
newEdges, newEdges,
get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }
); );
}, },
unselectAll: () => { unselectAll: () => {
@ -444,7 +443,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
function validateSubgraph(nodes: string[]) { function validateSubgraph(nodes: string[]) {
const errorsObjs = validateNodes( const errorsObjs = validateNodes(
get().nodes.filter((node) => nodes.includes(node.id)), get().nodes.filter((node) => nodes.includes(node.id)),
get().edges, get().edges
); );
const errors = errorsObjs.map((obj) => obj.errors).flat(); const errors = errorsObjs.map((obj) => obj.errors).flat();
@ -463,10 +462,15 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
function handleBuildUpdate( function handleBuildUpdate(
vertexBuildData: VertexBuildTypeAPI, vertexBuildData: VertexBuildTypeAPI,
status: BuildStatus, status: BuildStatus,
runId: string, runId: string
) { ) {
console.log("handleBuildUpdate", vertexBuildData, status, runId);
if (vertexBuildData && vertexBuildData.inactivated_vertices) { if (vertexBuildData && vertexBuildData.inactivated_vertices) {
get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices);
get().updateBuildStatus(
vertexBuildData.inactivated_vertices,
BuildStatus.INACTIVE
);
} }
if (vertexBuildData.next_vertices_ids) { if (vertexBuildData.next_vertices_ids) {
@ -481,11 +485,14 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
// next_vertices_ids should be next_vertices_ids without the inactivated vertices // next_vertices_ids should be next_vertices_ids without the inactivated vertices
const next_vertices_ids = vertexBuildData.next_vertices_ids.filter( const next_vertices_ids = vertexBuildData.next_vertices_ids.filter(
(id) => !vertexBuildData.inactivated_vertices?.includes(id), (id) => !vertexBuildData.inactivated_vertices?.includes(id)
);
const top_level_vertices = vertexBuildData.top_level_vertices.filter(
(vertex) => !vertexBuildData.inactivated_vertices?.includes(vertex.id)
); );
const nextVertices: VertexLayerElementType[] = zip( const nextVertices: VertexLayerElementType[] = zip(
next_vertices_ids, next_vertices_ids,
vertexBuildData.top_level_vertices, top_level_vertices
).map(([id, reference]) => ({ id: id!, reference })); ).map(([id, reference]) => ({ id: id!, reference }));
const newLayers = [ const newLayers = [
@ -502,15 +509,12 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
runId: runId, runId: runId,
verticesToRun: get().verticesBuild!.verticesToRun, verticesToRun: get().verticesBuild!.verticesToRun,
}); });
get().updateBuildStatus( get().updateBuildStatus(top_level_vertices, BuildStatus.TO_BUILD);
vertexBuildData.top_level_vertices,
BuildStatus.TO_BUILD,
);
} }
get().addDataToFlowPool( get().addDataToFlowPool(
{ ...vertexBuildData, buildId: runId }, { ...vertexBuildData, buildId: runId },
vertexBuildData.id, vertexBuildData.id
); );
useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status);
@ -519,7 +523,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
const newFlowBuildStatus = { ...get().flowBuildStatus }; const newFlowBuildStatus = { ...get().flowBuildStatus };
// filter out the vertices that are not status // filter out the vertices that are not status
const verticesToUpdate = verticesIds?.filter( const verticesToUpdate = verticesIds?.filter(
(id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT, (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT
); );
if (verticesToUpdate) { if (verticesToUpdate) {
@ -584,7 +588,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
verticesLayers: VertexLayerElementType[][]; verticesLayers: VertexLayerElementType[][];
runId: string; runId: string;
verticesToRun: string[]; verticesToRun: string[];
} | null, } | null
) => { ) => {
set({ verticesBuild: vertices }); set({ verticesBuild: vertices });
}, },
@ -609,7 +613,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
// that are going to be built // that are going to be built
verticesIds: get().verticesBuild!.verticesIds.filter( verticesIds: get().verticesBuild!.verticesIds.filter(
// keep the vertices that are not in the list of vertices to remove // keep the vertices that are not in the list of vertices to remove
(vertex) => !vertices.includes(vertex), (vertex) => !vertices.includes(vertex)
), ),
}, },
}); });