@aranzatech/diagrams-core
v0.2.8
Published
Core canvas engine — ReactFlow wrapper, ELK routing, Dagre layout, alignment
Readme
@aranzatech/diagrams-core
Core primitives for the Aranza diagram ecosystem. This package is intentionally diagram-agnostic: BPMN, ERD, UML, C4 and future diagram packages should build their domain semantics on top of these shared canvas, model, command, rules, layout, routing and alignment utilities.
What Belongs Here
- Pure graph/model operations shared by all diagram types.
- Pure command stack and undo/redo primitives.
- Pure modeling-rule hooks that domain packages can use to enforce semantics.
- ReactFlow canvas wrappers and hooks.
- Generic layout, routing and alignment utilities.
What Does Not Belong Here
- BPMN, ERD, UML or C4-specific node semantics.
- Flowable, Camunda or any execution-engine integration.
- Domain XML import/export.
- Validation rules that require diagram-specific knowledge.
Public Subpaths
import { DiagramCanvas, useDiagramState } from "@aranzatech/diagrams-core/canvas";
import { addNode, connectNodes } from "@aranzatech/diagrams-core/model";
import { CommandStack } from "@aranzatech/diagrams-core/commands";
import { createModelingRules } from "@aranzatech/diagrams-core/rules";
import { serializeDiagram } from "@aranzatech/diagrams-core/serialization";
import { applyLayout } from "@aranzatech/diagrams-core/layout";
import { OrthogonalEdge } from "@aranzatech/diagrams-core/routing";
import { routeEdgesOrthogonally } from "@aranzatech/diagrams-core/elk-routing";
import { alignNodes } from "@aranzatech/diagrams-core/alignment";Pure Vs React
Pure modules are safe to use in Node.js, browser workers and import/export code:
modelcommandsrulesserializationalignment- pure routing path helpers
React modules depend on React and ReactFlow:
canvas- React hooks such as
useDiagramState,useAutoLayout,useAlignment - React edge components such as
OrthogonalEdge
ELK-backed routing/layout is async and imports elkjs only when used.
Apps that render DiagramCanvas must load ReactFlow styles once:
import "@xyflow/react/dist/style.css";Generic Model Example
import {
createDiagramState,
addNode,
connectNodes,
} from "@aranzatech/diagrams-core/model";
let diagram = createDiagramState();
diagram = addNode(diagram, {
id: "a",
type: "task",
position: { x: 0, y: 0 },
data: { label: "A" },
});
diagram = addNode(diagram, {
id: "b",
type: "task",
position: { x: 200, y: 0 },
data: { label: "B" },
});
diagram = connectNodes(diagram, {
source: "a",
target: "b",
id: "a-b",
});Selection And Clipboard
import {
copyElements,
pasteElements,
setSelection,
} from "@aranzatech/diagrams-core/model";
const selected = setSelection(diagram, {
nodeIds: ["a", "b"],
edgeIds: ["a-b"],
});
const clipboard = copyElements(selected);
const pasted = pasteElements(selected, clipboard, {
offset: { x: 40, y: 40 },
});Command Stack Example
import { CommandStack, createCompositeCommand } from "@aranzatech/diagrams-core/commands";
import { addNode } from "@aranzatech/diagrams-core/model";
const stack = new CommandStack({ nodes: [], edges: [] });
stack.execute({
id: "add-node",
execute: (state) =>
addNode(state, {
id: "n1",
type: "default",
position: { x: 0, y: 0 },
data: {},
}),
});
stack.undo();
stack.redo();createCompositeCommand and executeCommands let editors group multiple
modeling changes into one undoable transaction.
Modeling Rules Example
import { createModelingRules, evaluateModelingRules } from "@aranzatech/diagrams-core/rules";
const rules = createModelingRules({
connect: [
({ source }) =>
source?.type === "end" ? "End nodes cannot create outgoing edges." : true,
],
});
const result = evaluateModelingRules(rules, {
action: "connect",
state: diagram,
source,
target,
});Serialization Example
import {
deserializeDiagram,
serializeDiagram,
} from "@aranzatech/diagrams-core/serialization";
const json = serializeDiagram(diagram, {
diagramType: "bpmn",
metadata: { source: "designer" },
});
const restored = deserializeDiagram(json);