CONTEXT FOR THIS WRITE-UP

Preserved from the existing engineering journal. Code, records, and diagrams are illustrative. Historical performance figures in these notes are not independently reproduced benchmarks or current project claims.

01 — The State Synchronization Problem

Why managing visual nodes and execution state requires extreme decoupling

Building a visual data pipeline editor like DataflowX introduces a classic distributed state problem on the client side: the visual representation of nodes (coordinates, dragging states) must remain distinct from the logical execution state (payloads, schemas, connections).

Tying execution payloads directly to React Flow node states results in massive re-render cascades whenever a user drags a node across the canvas.

02 — The Dual-Store Architecture

Separating the canvas from the compiler

To achieve 60fps dragging while maintaining complex JSON schema validation for node properties, I implemented a dual-store architecture using Zustand.

Store A (The Canvas) strictly handles x/y coordinates, zoom levels, and viewport transitions. Store B (The Compiler) maintains the abstract syntax tree of the pipeline, handling topological sorting, cycle detection, and payload generation.

ENGINEERING DECISION
decisionDecoupled Zustand Stores with Selector Subscriptions
reasonReact Flow requires high-frequency updates during drag events. If the logical state (which can be deeply nested JSON) sits in the same store, it forces unnecessary deep equality checks.
tradeoffRequires an explicit sync step when a logical edge is created, slightly increasing boilerplate.
resultZero frame drops during complex graph manipulations with 50+ nodes.

03 — Real-Time Cycle Detection

Preventing infinite loops before execution

A data pipeline must be a Directed Acyclic Graph (DAG). If a user attempts to connect the output of a downstream node back to an upstream node, the backend execution engine will hang in an infinite loop.

Instead of waiting for the backend to reject the payload, DataflowX implements an immediate Depth-First Search (DFS) cycle detection algorithm directly in the edge connection handler.

O(V+E) Cycle Detection on Edge Connect
const onConnect = useCallback((connection: Connection) => {
  const willCreateCycle = detectCycle(nodes, edges, connection);
  
  if (willCreateCycle) {
    toast.error("Cyclic dependencies are not allowed in DataflowX pipelines.");
    return;
  }
  
  setEdges((eds) => addEdge(connection, eds));
}, [nodes, edges]);

Why this mattersFailing fast on the client prevents invalid state payloads from ever reaching the execution queue, saving backend compute resources and providing instant UX feedback.

LOOKING BACK

What I learned.

01

Visual state is not logical state

Treat the canvas UI merely as a renderer for an underlying graph data structure, not as the source of truth for execution logic.

02

Topological sorting is foundational

Mastering graph traversal algorithms (DFS, Kahn’s algorithm) is mandatory when building any kind of visual workflow automation.

THANKS FOR READING.

The useful part of a technical problem is often the question it leaves you with.

Continue the conversation