digraph {
  rankdir = "LR";

  node [shape = "sqaure";];
  edge [color = "#4979c7";];

  onNodesChange -> NODE_REMOVED;
  NODE_REMOVED [label = "NODE_REMOVED {node, nodeConfig}";];
  onNodesChange -> NODE_MOVED;
  NODE_MOVED [label = "NODE_MOVED {}";];
  onEdgesChange -> EDGE_REMOVED;
  EDGE_REMOVED [label = "EDGE_REMOVED {oldEdge, newEdge=null, oldSrcNodeConfig, newSrcNodeConfig=null}";];
  onConnect -> EDGE_ADDED;
  EDGE_ADDED [label = "EDGE_ADDED {oldEdge=null, newEdge, oldSrcNodeConfig=null, newSrcNodeConfig}";];
  onConnect -> EDGE_REPLACED;
  EDGE_REPLACED [label = "EDGE_REPLACED {oldEdge, newEdge, oldSrcNodeConfig, newSrcNodeConfig}";];

  ADDING_NODE -> NODE_AND_VARIABLES_ADDED;
  ADDING_NODE [label = "ADDING_NODE {nodeType, x, y}";];
  NODE_AND_VARIABLES_ADDED [label = "NODE_AND_VARIABLES_ADDED {node, nodeConfig}";];

  UPDATING_NODE_CONFIG -> NODE_CONFIG_UPDATED;
  UPDATING_NODE_CONFIG [label = "UPDATING_NODE_CONFIG {nodeId, Partial<NodeConfig>}";];
  NODE_CONFIG_UPDATED [label = "NODE_CONFIG_UPDATED {}";];
  REMOVING_NODE -> NODE_REMOVED;
  REMOVING_NODE [label = "REMOVING_NODE {nodeId}";];
  NODE_REMOVED [label = "NODE_REMOVED {node, nodeConfig}";];

  ADDING_VAR -> VAR_ADDED;
  VAR_ADDED [label = "VAR_ADDED {oldVar = null, newVar, nodeConfig}";];
  REMOVING_VAR -> VAR_REMOVED;
  VAR_REMOVED [label = "VAR_REMOVED {oldVar, newVar = null, nodeConfig}";];
  UPDATING_VAR -> VAR_UPDATED;
  VAR_UPDATED [label = "VAR_UPDATED {oldVar, newVar, nodeConfig}";];

  // Derived

  NODE_REMOVED -> VAR_REMOVED;
  NODE_AND_VARIABLES_ADDED -> VAR_VALUE_MAP_UPDATED;
  NODE_AND_VARIABLES_ADDED -> CONTROL_RESULT_MAP_UPDATED;

  VAR_REMOVED -> EDGE_REMOVED;

  {EDGE_ADDED EDGE_REPLACED EDGE_REMOVED} -> VAR_UPDATED;

  {VAR_ADDED VAR_UPDATED VAR_REMOVED} -> VAR_VALUE_MAP_UPDATED;

  {EDGE_ADDED EDGE_REPLACED EDGE_REMOVED} -> CONTROL_RESULT_MAP_UPDATED;

  VAR_VALUE_MAP_UPDATED [label = "VAR_VALUE_MAP_UPDATED {}";];

  CONTROL_RESULT_MAP_UPDATED [label = "CONTROL_RESULT_MAP_UPDATED {}";];

  // For easier viewing

  subgraph cluster {
    label = "React Flow Events";
    onNodesChange;
    onEdgesChange;
    onConnect;
  }

  subgraph cluster_edge_node {
    ADDING_NODE;
    UPDATING_NODE_CONFIG;
    REMOVING_NODE;
    ADDING_VAR;
    UPDATING_VAR;
    REMOVING_VAR;
  }

  subgraph cluster_nodes {
    NODE_AND_VARIABLES_ADDED;
    NODE_MOVED;
    NODE_CONFIG_UPDATED;
    NODE_REMOVED;
  }

  subgraph cluster_edges {
    EDGE_ADDED;
    EDGE_REMOVED;
    EDGE_REPLACED;
  }

  subgraph cluster_vars {
    VAR_ADDED;
    VAR_UPDATED;
  }
}
