store.ts
Overview
store.ts defines a centralized state management store for a flow-based graph editor using the Zustand library with Immer and Redux DevTools middleware. It manages the application's graph data structures, including nodes and edges, their selection states, and provides a comprehensive set of actions to manipulate and synchronize the graph state.
The store encapsulates logic for adding, deleting, updating, duplicating nodes and edges, handling connections, managing selection changes, and updating node forms. It is designed specifically for a React-based flow editor utilizing the @xyflow/react library and customized node types (RAGFlowNodeType).
This file is the core stateful backbone for the flow editor UI components, enabling reactive updates and complex interactions between nodes and edges in a graph workflow.
Key Features
Centralized management of nodes and edges collections.
Selection tracking for nodes and edges.
Node and edge lifecycle methods: add, delete, duplicate.
Connection handlers to maintain graph integrity.
Form data updates based on graph connections.
Special handling for different operator node types (e.g., Categorize, Switch, Iteration).
Integration with React Flow events (
OnNodesChange,OnEdgesChange,OnConnect).Utility function wrappers for node naming and form duplication.
Middleware integration for development tooling and immutable state updates.
Main Types
RFState (Type Alias)
Defines the shape of the store state and actions.
Property / Method | Type | Description |
|---|---|---|
|
| Current list of nodes in the flow graph. |
|
| Current list of edges (connections) in the graph. |
|
| IDs of currently selected nodes. |
|
| IDs of currently selected edges. |
|
| ID of the currently clicked node. |
| Callback to apply changes to nodes. | |
| Callback to apply changes to edges. | |
| Callback when a new edge connection is established. | |
| Callback when node or edge selection changes. | |
| Replace entire node list. | |
| Replace entire edge list. | |
| Update downstream edges of a specified node, preserving others. | |
| Add a new node to the graph. | |
| [(id?: string | null) => RAGFlowNodeType \ |
| [(id: string) => Edge \ | undefined](/projects/311/71659) |
| Add a new edge connection. | |
| [(nodeId: string, values: any, path?: (string | number)[]) => RAGFlowNodeType[]](/projects/311/73962) |
| Update node form data after a new connection is made, based on operator type. | |
| [(source: string, sourceHandle?: string | null, target?: string |
| Remove old edges from classification nodes when a new connection is made to the same anchor. | |
| Duplicate a node by ID with a new name, handles iteration nodes specially. | |
| Duplicate an iteration node and its children nodes. | |
| Delete all selected edges. | |
| Delete a specific edge by ID and update related node forms. | |
| Delete edges by source node ID and source handle. | |
| Delete a node by ID and remove related edges. | |
| Delete an iteration node and all its children nodes and related edges. | |
| [(operatorName: Operator) => RAGFlowNodeType \ | undefined](/projects/311/73962) |
| Update a single field in a node's form data. | |
| [(id?: string | null) => string |
| [(id?: string | null) => string |
| Update the name of a node by ID. | |
|
| Generate a unique node name with an increasing index based on existing nodes. |
| Set the currently clicked node ID. |
Detailed Explanation of Core Methods
onNodesChange(changes: NodeChange[]): void
Applies changes to the nodes array using React Flow's applyNodeChanges.
Parameters:
changes: Array of node change objects describing updates.
Returns:
voidUsage:
store.onNodesChange([{ id: 'node1', type: 'remove' }]);
onEdgesChange(changes: EdgeChange[]): void
Applies changes to the edges array using React Flow's applyEdgeChanges.
Parameters:
changes: Array of edge change objects describing updates.
Returns:
voidUsage:
store.onEdgesChange([{ id: 'edge1', type: 'remove' }]);
onConnect(connection: Connection): void
Handles the event of connecting two nodes by adding the edge, deleting any previous conflicting edges for classification nodes, and updating form data accordingly.
Parameters:
connection: Object containingsource,target, and optional handles.
Returns:
voidUsage:
store.onConnect({ source: 'node1', target: 'node2', sourceHandle: 'output' });
addNode(node: RAGFlowNodeType): void
Adds a new node to the graph.
Parameters:
node: The node object to add.
Returns:
voidUsage:
store.addNode(newNode);
duplicateNode(id: string, name: string): void
Duplicates an existing node by ID, assigning it a new name. If the node is an iteration node, it delegates to duplicateIterationNode.
Parameters:
id: ID of the node to duplicate.name: New name base for the duplicated node.
Returns:
voidUsage:
store.duplicateNode('node1', 'Duplicated Node');
duplicateIterationNode(id: string, name: string): void
Duplicates an iteration node and all its child nodes recursively, generating new names and IDs accordingly.
Parameters:
id: ID of the iteration node.name: New base name for duplication.
Returns:
voidUsage:
store.duplicateIterationNode('iterationNode1', 'Iteration Copy');
updateNodeForm(nodeId: string, values: any, path?: (string | number)[]): RAGFlowNodeType[]
Updates the form data of a node by merging or setting values at a specific path.
Parameters:
nodeId: ID of the node to update.values: New form values or partial updates.path: Optional array to specify nested path in the form.
Returns: Updated array of nodes.
Usage:
store.updateNodeForm('node1', { title: 'Updated' }); store.updateNodeForm('node1', 'targetNodeId', ['category_description', 'handle1', 'to']);
deleteEdgeById(id: string): void
Deletes an edge by its ID and clears corresponding form data in the source node depending on operator type.
Parameters:
id: ID of the edge to delete.
Returns:
voidUsage:
store.deleteEdgeById('edge1');
setEdgesByNodeId(nodeId: string, edges: Edge[]): void
Updates the downstream edges of a specific node by comparing with previous edges and applying changes only if different.
Parameters:
nodeId: ID of the node whose edges to update.edges: New set of downstream edges for this node.
Returns:
voidUsage:
store.setEdgesByNodeId('node1', newEdges);
Important Implementation Details
State Management: Uses Zustand with Immer middleware to enable immutable state updates in a mutable syntax.
Devtools Integration: Wrapped with Redux DevTools middleware for powerful state debugging.
React Flow Integration: Leverages React Flow's utilities (
applyNodeChanges,applyEdgeChanges,addEdge) for graph consistency.Node Duplication: Special care to duplicate iteration nodes and their children recursively while generating unique names and IDs.
Form Synchronization: On edge connection or deletion, updates the corresponding node's form data to keep the UI and data model consistent.
Selective Edge Replacement:
setEdgesByNodeIdreplaces only downstream edges for a node, preserving other edges.Operator Types Handling: Logic branches based on node operator type (
Relevant,Categorize,Switch,Iteration) to update forms and edge states accordingly.Utility Functions: Uses helper functions from
./utilsand constants from./constantto manage naming and indexing.
Interaction with Other Parts of the System
Node and Edge Types: Uses
RAGFlowNodeTypeimported from@/interfaces/database/flow.React Flow Library: Integrates with
@xyflow/reactfor graph data types and change handlers.Utility Methods: Imports naming and duplication helpers (
generateDuplicateNode,generateNodeNamesWithIncreasingIndex, etc.) from a local./utilsfile.Constants: Uses operator constants (
Operator,SwitchElseTo) from./constant.UI Components: This store is consumed by React components in the flow editor UI to read state and dispatch actions.
Usage Example
import useGraphStore from './store.ts';
function GraphEditor() {
const nodes = useGraphStore(state => state.nodes);
const edges = useGraphStore(state => state.edges);
const onNodesChange = useGraphStore(state => state.onNodesChange);
const onEdgesChange = useGraphStore(state => state.onEdgesChange);
const onConnect = useGraphStore(state => state.onConnect);
return (
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
/>
);
}
Mermaid Class Diagram
classDiagram
class RFState {
+nodes: RAGFlowNodeType[]
+edges: Edge[]
+selectedNodeIds: string[]
+selectedEdgeIds: string[]
+clickedNodeId: string
+onNodesChange(changes: NodeChange[]): void
+onEdgesChange(changes: EdgeChange[]): void
+onConnect(connection: Connection): void
+onSelectionChange(params: OnSelectionChangeParams): void
+setNodes(nodes: RAGFlowNodeType[]): void
+setEdges(edges: Edge[]): void
+setEdgesByNodeId(nodeId: string, edges: Edge[]): void
+addNode(node: RAGFlowNodeType): void
+getNode(id?: string | null): RAGFlowNodeType | undefined
+addEdge(connection: Connection): void
+getEdge(id: string): Edge | undefined
+updateFormDataOnConnect(connection: Connection): void
+updateSwitchFormData(source: string, sourceHandle?: string | null, target?: string | null): void
+deletePreviousEdgeOfClassificationNode(connection: Connection): void
+duplicateNode(id: string, name: string): void
+duplicateIterationNode(id: string, name: string): void
+deleteEdge(): void
+deleteEdgeById(id: string): void
+deleteNodeById(id: string): void
+deleteIterationNodeById(id: string): void
+deleteEdgeBySourceAndSourceHandle(connection: Partial~Connection~): void
+findNodeByName(operatorName: Operator): RAGFlowNodeType | undefined
+updateMutableNodeFormItem(id: string, field: string, value: any): void
+getOperatorTypeFromId(id?: string | null): string | undefined
+getParentIdById(id?: string | null): string | undefined
+updateNodeName(id: string, name: string): void
+generateNodeName(name: string): string
+setClickedNodeId(id?: string): void
}
class Connection
class Edge
class RAGFlowNodeType
RFState --> RAGFlowNodeType : nodes
RFState --> Edge : edges
RFState --> Connection : addEdge,onConnect
Summary
The store.ts file is a sophisticated state management module for a React-based graph editor, wrapping complex node/edge operations into a single Zustand-powered store. It bridges React Flow's graph model with UI form state, supporting advanced features like node duplication, conditional form updates, and selective edge management. This store is essential for maintaining graph consistency and enabling rich user interactions in the flow editor application.