The framework provides a flexible plugin and message system, which enables you to extend the functionality of various components and manage their behavior. This can be achieved by using pipes for specific message types.
Validation will be implemented for adding nodes, where nodes of a certain type will be prevented until the starting node is added
editor.addPipe(context => {
if (context.type === 'nodecreate') {
if (context.data instanceof EndNode) {
const hasBeginNode = editor.getNodes().some(n => n instanceof BeginNode)
if (!hasBeginNode) {
alert('cannot add EndNode until BeginNode is added')
return
}
}
}
return context
})
where EndNode
and BeginNode
are classes that extend ClassicPreset.Node
.
This particular case utilized a method of preventing message propagation by specifying return
with no value. This technique is appropriate for types like nodecreate
, noderemove
, connectioncreate
and connectionremove
.
The same principle can be used to prevent messages of connectioncreate
type.
editor.addPipe((context) => {
if (context.type === "connectioncreate") {
if (!canCreateConnection(editor, context.data)) {
alert("Sockets are not compatible");
return;
}
}
return context;
});
where canCreateConnection
is any function that takes a connection instance context.data
and returns a boolean.
Let's take the Chatbot example, particularly the modules chatbot/utils.ts
and chatbot/sockets.ts
, and apply the same approach to our canCreateConnection
function. First, we'll implement advanced sockets:
import { ClassicPreset } from "rete";
export class ActionSocket extends ClassicPreset.Socket {
constructor() {
super("Action");
}
isCompatibleWith(socket: ClassicPreset.Socket) {
return socket instanceof ActionSocket;
}
}
export class TextSocket extends ClassicPreset.Socket {
constructor() {
super("Text");
}
isCompatibleWith(socket: ClassicPreset.Socket) {
return socket instanceof TextSocket;
}
}
by using isCompatibleWith
method, socket types are able to specify which other socket types they are compatible.
After that, we will implement our function which takes a connection as an argument, returns the corresponding sockets from the nodes, and checks them for compatibility.
export function canCreateConnection(editor: NodeEditor<Schemes>, connection: Schemes["Connection"]) {
const { source, target } = getConnectionSockets(editor, connection);
return source && target && source.isCompatibleWith(target)
}
where getConnectionSockets
function was taken from the aforementioned example.