use-before-delete.tsx
Overview
The use-before-delete.tsx file defines a custom React hook, useBeforeDelete, which provides pre-deletion logic for nodes and edges within a RAG (Red-Amber-Green) flow graph editor. This logic determines whether certain nodes or edges should be prevented from deletion based on their types and relationships. It is designed to be used with a graph manipulation library (likely @xyflow/react) that supports a OnBeforeDelete callback to intercept and filter deletions before they are finalized.
The key purpose is to protect critical flow nodes—specifically nodes labeled as Begin and IterationStart operators—from being deleted under certain conditions, thereby maintaining graph integrity and preventing accidental removal of essential flow elements.
Detailed Explanation
Constants
const UndeletableNodes = [Operator.Begin, Operator.IterationStart];
Purpose: Defines an array of node types (
Operator.BeginandOperator.IterationStart) that have special deletion rules or are generally protected from deletion under specific conditions.
Function: useBeforeDelete
export function useBeforeDelete() {
...
}
Purpose: A custom React hook that encapsulates and returns the
handleBeforeDeletecallback function. This function implements the logic to determine which nodes and edges are allowed to be deleted.Returns: An object containing the function
handleBeforeDelete.
Method: handleBeforeDelete
const handleBeforeDelete: OnBeforeDelete<RAGFlowNodeType> = async ({
nodes,
edges,
}) => { ... }
Type:
OnBeforeDelete<RAGFlowNodeType>(an asynchronous callback type from@xyflow/react)Parameters:
nodes: Array of nodes proposed for deletion. Each node is of typeRAGFlowNodeType.edges: Array of edges proposed for deletion.
Returns: A Promise resolving to an object containing filtered arrays of
nodesandedgesthat are allowed to be deleted.
Implementation Details
Accessing Operator Type by Node ID
const getOperatorTypeFromId = useGraphStore( (state) => state.getOperatorTypeFromId, );Uses a Zustand-based store (
useGraphStore) to retrieve a function that maps node IDs to their operator types.This is used to inspect edge source nodes to inform deletion decisions.
Filtering Nodes
const toBeDeletedNodes = nodes.filter((node) => { const operatorType = node.data?.label as Operator; if (operatorType === Operator.Begin) { return false; } if ( operatorType === Operator.IterationStart && !nodes.some((x) => x.id === node.parentId) ) { return false; } return true; });Nodes labeled as
Beginare never deleted.Nodes labeled
IterationStartare protected from deletion if their parent node is not also being deleted in the same operation.All other nodes are allowed to be deleted.
Filtering Edges
const toBeDeletedEdges = edges.filter((edge) => { const sourceType = getOperatorTypeFromId(edge.source) as Operator; const downStreamNodes = nodes.filter((x) => x.id === edge.target); if ( UndeletableNodes.includes(sourceType) && downStreamNodes.length === 0 ) { if (!nodes.some((x) => x.id === edge.source)) { return true; } return false; } return true; });Edges whose source node is one of the
UndeletableNodes(BeginorIterationStart) are carefully checked.If the downstream node (edge target) is not slated for deletion, then:
If the source node is not being deleted in this batch, the edge can be deleted.
Otherwise, the edge cannot be deleted to avoid disconnecting important nodes.
All other edges are allowed to be deleted.
Return Value
The function returns the filtered list of nodes and edges that are permitted to be deleted. This result is used by the consuming graph component/library to proceed with deletion.
Usage Example
import React from 'react';
import { useBeforeDelete } from './use-before-delete';
import { FlowGraph } from '@xyflow/react';
function MyFlowEditor() {
const { handleBeforeDelete } = useBeforeDelete();
return (
<FlowGraph
onBeforeDelete={handleBeforeDelete}
/* other props */
/>
);
}
The returned
handleBeforeDeletefunction is passed as theonBeforeDeletecallback to the flow graph component.This ensures that when a user attempts to delete nodes or edges, the pre-deletion checks are applied.
Interaction with Other Parts of the System
useGraphStore: This hook depends on the global or local graph store to get operator types by node ID. This store likely manages the graph state, including node metadata.OperatorEnum/Constants: The file importsOperatorconstants from../constant, which define the types of operators (likeBegin,IterationStart) used to identify protected nodes.@xyflow/react: The hook interfaces with this library'sOnBeforeDeletetype, indicating that the flow graph component from this library supports pre-deletion interception.RAGFlowNodeTypeInterface: Defines the shape of nodes in the flow, imported from the database flow interfaces.
Important Notes
The deletion protection logic is primarily about preserving the integrity of the flow start points (
Begin) and iteration entry points (IterationStart).The hook ensures that
IterationStartnodes are only deleted if their parent node is also deleted in the same operation, preventing orphan nodes.The edge deletion logic prevents cutting off edges from protected nodes unless the source node itself is being deleted.
Mermaid Component Diagram
flowchart TD
A[useBeforeDelete Hook]
A --> B[handleBeforeDelete Function]
B --> C[Filter Nodes]
B --> D[Filter Edges]
C --> E{Node Type}
E -->|Begin| F[Exclude from deletion]
E -->|IterationStart| G{Parent node also deleted?}
G -->|No| F
G -->|Yes| H[Include for deletion]
E -->|Other| H
D --> I{Edge Source Type}
I -->|Begin or IterationStart| J{Downstream node in deletion?}
J -->|No + Source node not deleted| K[Allow edge deletion]
J -->|Otherwise| L[Prevent edge deletion]
I -->|Other| K
Summary
The use-before-delete.tsx file implements a critical safeguard mechanism in a flow editor application, ensuring essential nodes and their connecting edges are not inadvertently deleted. By filtering out protected nodes and edges before the deletion operation completes, it maintains the structural and logical correctness of the flow graph. This file interacts closely with graph state management and the flow graph rendering library, integrating seamlessly to provide a robust user experience.