npm i rete rete-engine
Let's take a simple example of a graph with two types of nodes: Log
and Delay
. These nodes can perform specific operations and pass control to outgoing nodes in a certain way
At the end of the article, you can find a link to the full example that includes visual components.
Defining a node class that logs a message and passes control to outgoing nodes via the exec
port:
const socket = new ClassicPreset.Socket("socket");
class Log extends ClassicPreset.Node {
constructor(public message: string) {
super("Log");
this.addInput("exec", new ClassicPreset.Input(socket, "Exec", true));
this.addOutput("exec", new ClassicPreset.Output(socket, "Exec"));
}
execute(input: "exec", forward: (output: "exec") => void) {
console.log(this.message);
forward("exec");
}
}
Defining a class that handles delays, where the only purpose is to pass control to outgoing nodes through the exec
port after a specified timeout:
class Delay extends ClassicPreset.Node {
constructor(private seconds: number) {
super("Delay");
this.addInput("exec", new ClassicPreset.Input(socket, "Exec", true));
this.addOutput("exec", new ClassicPreset.Output(socket, "Exec"));
}
execute(input: "exec" | undefined, forward: (output: "exec") => void) {
setTimeout(() => forward("exec"), seconds * 1000)
}
}
class Connection<A extends NodeProps, B extends NodeProps> extends ClassicPreset.Connection<A, B> {}
type NodeProps = Start | Log | Delay;
type ConnProps =
| Connection<Start, Log>
| Connection<Delay, Log>
| Connection<Log, Delay>
| Connection<Log, Log>
| Connection<Delay, Delay>;
type Schemes = GetSchemes<NodeProps, ConnProps>;
import { ControlFlowEngine } from "rete-engine";
import { NodeEditor } from "rete";
const editor = new NodeEditor<Schemes>();
const engine = new ControlFlowEngine<Schemes>();
editor.use(engine);
Let's add a sequence of nodes in the form of Log -> Delay -> Log
const log1 = new Log("log before delay");
const delay = new Delay(2);
const log2 = new Log("log after delay");
const con2 = new Connection(log1, "exec", delay, "exec");
const con3 = new Connection(delay, "exec", log2, "exec");
await editor.addNode(log1);
await editor.addNode(delay);
await editor.addNode(log2);
await editor.addConnection(con2);
await editor.addConnection(con3);
The node log1
serves as the starting point for the graph execution.
engine.execute(log1.id);
This operation triggers the execute
method of the Log
class, with undefined
as the input
parameter because the node was directly called, without being passed from an incoming node.
Then, calling forward("exec")
passes control to all the outgoing nodes. In our case, the Delay
node does the same thing but after a delay using setTimeout
.
Logs:
"log before delay"
// delay for 2 seconds
"log after delay"
Check out the complete result on the Control flow example page.