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


Main Types

RFState (Type Alias)

Defines the shape of the store state and actions.

Property / Method

Type

Description

nodes

RAGFlowNodeType[]

Current list of nodes in the flow graph.

edges

Edge[]

Current list of edges (connections) in the graph.

selectedNodeIds

string[]

IDs of currently selected nodes.

selectedEdgeIds

string[]

IDs of currently selected edges.

clickedNodeId

string

ID of the currently clicked node.

onNodesChange

(changes: NodeChange[]) => void

Callback to apply changes to nodes.

onEdgesChange

(changes: EdgeChange[]) => void

Callback to apply changes to edges.

onConnect

(connection: Connection) => void

Callback when a new edge connection is established.

onSelectionChange

(params: OnSelectionChangeParams) => void

Callback when node or edge selection changes.

setNodes

(nodes: RAGFlowNodeType[]) => void

Replace entire node list.

setEdges

(edges: Edge[]) => void

Replace entire edge list.

setEdgesByNodeId

(nodeId: string, edges: Edge[]) => void

Update downstream edges of a specified node, preserving others.

addNode

(node: RAGFlowNodeType) => void

Add a new node to the graph.

getNode

[(id?: string

null) => RAGFlowNodeType \

getEdge

[(id: string) => Edge \

undefined](/projects/311/71659)

addEdge

(connection: Connection) => void

Add a new edge connection.

updateNodeForm

[(nodeId: string, values: any, path?: (string

number)[]) => RAGFlowNodeType[]](/projects/311/73962)

updateFormDataOnConnect

(connection: Connection) => void

Update node form data after a new connection is made, based on operator type.

updateSwitchFormData

[(source: string, sourceHandle?: string

null, target?: string

deletePreviousEdgeOfClassificationNode

(connection: Connection) => void

Remove old edges from classification nodes when a new connection is made to the same anchor.

duplicateNode

(id: string, name: string) => void

Duplicate a node by ID with a new name, handles iteration nodes specially.

duplicateIterationNode

(id: string, name: string) => void

Duplicate an iteration node and its children nodes.

deleteEdge

() => void

Delete all selected edges.

deleteEdgeById

(id: string) => void

Delete a specific edge by ID and update related node forms.

deleteEdgeBySourceAndSourceHandle

(connection: Partial) => void

Delete edges by source node ID and source handle.

deleteNodeById

(id: string) => void

Delete a node by ID and remove related edges.

deleteIterationNodeById

(id: string) => void

Delete an iteration node and all its children nodes and related edges.

findNodeByName

[(operatorName: Operator) => RAGFlowNodeType \

undefined](/projects/311/73962)

updateMutableNodeFormItem

(id: string, field: string, value: any) => void

Update a single field in a node's form data.

getOperatorTypeFromId

[(id?: string

null) => string

getParentIdById

[(id?: string

null) => string

updateNodeName

(id: string, name: string) => void

Update the name of a node by ID.

generateNodeName

(name: string) => string

Generate a unique node name with an increasing index based on existing nodes.

setClickedNodeId

(id?: string) => void

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.


onEdgesChange(changes: EdgeChange[]): void

Applies changes to the edges array using React Flow's applyEdgeChanges.


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.


addNode(node: RAGFlowNodeType): void

Adds a new node to the graph.


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.


duplicateIterationNode(id: string, name: string): void

Duplicates an iteration node and all its child nodes recursively, generating new names and IDs accordingly.


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.


deleteEdgeById(id: string): void

Deletes an edge by its ID and clears corresponding form data in the source node depending on operator type.


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.


Important Implementation Details


Interaction with Other Parts of the System


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.