pnpm add @texuli/workflows
import { applyWorkflowOps, createWorkflow, defineNodeTypes } from '@texuli/workflows/model';
const registry = defineNodeTypes([
{
"type": "request",
"label": "Request",
"category": "Start",
"ports": [
{
"id": "out",
"direction": "out",
"dataType": "any"
}
]
},
{
"type": "approval",
"label": "Approval",
"category": "Review",
"ports": [
{
"id": "in",
"direction": "in",
"dataType": "any"
},
{
"id": "yes",
"direction": "out",
"dataType": "any",
"label": "Approved"
}
]
},
{
"type": "end",
"label": "End",
"category": "Done",
"ports": [
{
"id": "in",
"direction": "in",
"dataType": "any"
}
]
}
]);
const built = applyWorkflowOps(createWorkflow(), [
{
"op": "addNode",
"node": {
"id": "ask",
"type": "request",
"label": "Expense submitted",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "addNode",
"node": {
"id": "lead",
"type": "approval",
"label": "Team lead",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "addNode",
"node": {
"id": "paid",
"type": "end",
"label": "Paid",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "connect",
"edge": {
"id": "e1",
"from": {
"node": "ask",
"port": "out"
},
"to": {
"node": "lead",
"port": "in"
}
}
},
{
"op": "connect",
"edge": {
"id": "e2",
"from": {
"node": "lead",
"port": "yes"
},
"to": {
"node": "paid",
"port": "in"
}
}
}
], { registry });
if (built.ok) {
console.log(built.graph.nodes.map((node) => node.id));
}
import { layoutMoves, layoutWorkflow } from '@texuli/workflows/layout';
import { applyWorkflowOps, createWorkflow, defineNodeTypes } from '@texuli/workflows/model';
const registry = defineNodeTypes([
{
"type": "request",
"label": "Request",
"category": "Start",
"ports": [
{
"id": "out",
"direction": "out",
"dataType": "any"
}
]
},
{
"type": "approval",
"label": "Approval",
"category": "Review",
"ports": [
{
"id": "in",
"direction": "in",
"dataType": "any"
},
{
"id": "yes",
"direction": "out",
"dataType": "any",
"label": "Approved"
}
]
},
{
"type": "end",
"label": "End",
"category": "Done",
"ports": [
{
"id": "in",
"direction": "in",
"dataType": "any"
}
]
}
]);
const built = applyWorkflowOps(createWorkflow(), [
{
"op": "addNode",
"node": {
"id": "ask",
"type": "request",
"label": "Expense submitted",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "addNode",
"node": {
"id": "lead",
"type": "approval",
"label": "Team lead",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "addNode",
"node": {
"id": "paid",
"type": "end",
"label": "Paid",
"position": {
"x": 0,
"y": 0
}
}
},
{
"op": "connect",
"edge": {
"id": "e1",
"from": {
"node": "ask",
"port": "out"
},
"to": {
"node": "lead",
"port": "in"
}
}
},
{
"op": "connect",
"edge": {
"id": "e2",
"from": {
"node": "lead",
"port": "yes"
},
"to": {
"node": "paid",
"port": "in"
}
}
}
], { registry });
if (built.ok) {
const moves = layoutMoves(layoutWorkflow(built.graph, { direction: 'LR' }));
const laid = applyWorkflowOps(built.graph, [{ op: 'moveNodes', moves }], { registry });
if (laid.ok) {
console.log(laid.graph.nodes.length);
}
}
<script lang="ts">
import { WorkflowEditor } from '@texuli/workflows/editor';
import { applyWorkflowOps, createWorkflow, defineNodeTypes } from '@texuli/workflows/model';
import '@texuli/tokens/base.css';
const registry = defineNodeTypes([{"type":"request","label":"Request","category":"Start","ports":[{"id":"out","direction":"out","dataType":"any"}]},{"type":"approval","label":"Approval","category":"Review","ports":[{"id":"in","direction":"in","dataType":"any"},{"id":"yes","direction":"out","dataType":"any","label":"Approved"}]},{"type":"end","label":"End","category":"Done","ports":[{"id":"in","direction":"in","dataType":"any"}]}]);
const built = applyWorkflowOps(createWorkflow(), [{"op":"addNode","node":{"id":"ask","type":"request","label":"Expense submitted","position":{"x":0,"y":0}}},{"op":"addNode","node":{"id":"lead","type":"approval","label":"Team lead","position":{"x":0,"y":0}}},{"op":"addNode","node":{"id":"paid","type":"end","label":"Paid","position":{"x":0,"y":0}}},{"op":"connect","edge":{"id":"e1","from":{"node":"ask","port":"out"},"to":{"node":"lead","port":"in"}}},{"op":"connect","edge":{"id":"e2","from":{"node":"lead","port":"yes"},"to":{"node":"paid","port":"in"}}}], { registry });
let graph = $state.raw(built.ok ? built.graph : createWorkflow());
</script>
<WorkflowEditor {graph} {registry} onchange={(next) => (graph = next)} />