# Dataflow

::alert
Not familiar with Dataflow concept? Check out the [Dataflow](https://retejs.org/docs/concepts/engine#dataflow) article to get up to speed
::

::references
  :::ref-example{link="/examples/processing/dataflow" title="Dataflow"}
  :::

  :::ref-example{link="/examples/3d-configurator" title="3D Configurator"}
  :::

  :::ref-example{link="/examples/allmatter" title="Allmatter"}
  :::

  :::ref-github{link="https://github.com/retejs/engine" title="Plugin"}
  :::
::

## Install dependencies

::kit
::

```bash
npm i rete rete-engine
```

## Prepare nodes

Let's take a look at a simplified example of a graph with two node types: `NumberNode` and `AddNode`. These nodes are built exclusively for processing (on the server-side, e.g.) and don't have any integrations with the user interface. You can find a link to the complete example with the UI at the end of the article.

```ts
const socket = new ClassicPreset.Socket("socket");

class NumberNode extends ClassicPreset.Node {
  constructor(public value: number) {
    super("Number");
    this.addOutput("value", new ClassicPreset.Output(socket, "Number"));
  }

  data(): { value: number } {
    return { value: this.value };
  }
}

class AddNode extends ClassicPreset.Node {
  constructor() {
    super("Add");
    this.addInput("left", new ClassicPreset.Input(socket, "Left"));
    this.addInput("right", new ClassicPreset.Input(socket, "Right"));
    this.addOutput("value", new ClassicPreset.Output(socket, "Number"));
  }

  data(inputs: { left?: number[]; right?: number[] }): { value: number } {
    const { left, right } = inputs;
    const value = (left && left[0] || 0) + (right && right[0] || 0)

    return { value };
  }
}

class Connection<
  A extends Node,
  B extends Node
> extends ClassicPreset.Connection<A, B> {}

type Node = NumberNode | AddNode;
type ConnProps = Connection<NumberNode, AddNode> | Connection<AddNode, AddNode>;
type Schemes = GetSchemes<Node, ConnProps>;
```

## Connect

```ts
import { DataflowEngine } from "rete-engine";
import { NodeEditor } from "rete";

const editor = new NodeEditor<Schemes>();
const engine = new DataflowEngine<Schemes>();

editor.use(engine);
```

## Add nodes and connections

```ts
const a = new NumberNode(1);
const b = new NumberNode(1);
const sum = new AddNode();

const con1 = new Connection(a, "value", c, "left");
const con2 = new Connection(b, "value", c, "right");

await editor.addNode(a);
await editor.addNode(b);
await editor.addNode(sum);

await editor.addConnection(con1);
await editor.addConnection(con2);
```

## Start the processing

Retrieve output data from the `sum` node.

```ts
const result = await engine.fetch(sum.id)
```

The value of `result` will be `{ value: 2 }`, which is the sum of the initial input values of the `sum` node.

If you want to modify `a.value` or `b.value`, you need to clear the cache before processing the graph again. The output values of nodes are cached to avoid repetitive node execution.

```ts
engine.reset() // reset all nodes
// or specific nodes
engine.reset(a.id)
engine.reset(b.id)
```

Additionally, the `data` methods can be async. In such cases, the `sum` node will wait for the `data` methods of its input nodes to complete execution. After all of them have returned a value, the engine will execute the `data` method of the `sum` node

Check out the complete result on the [Dataflow](https://retejs.org/examples/processing/dataflow) example page.