Architecture
Flows → Workflow
Understand how select, drag, and drop interactions translate into workflow updates.
Select, Drag and Drop
Interacting with the workflow view produces FlowsChange objects, each representing the event that occurred, whether a node was selected, dragged, or dropped.
// src/shared/lib/flows/types/flows-change.ts
// ...
export type FlowsChange<T extends NodeEntity, U extends EdgeEntity> =
| NodeSelectChange<T, U>
| NodeDragChange<T, U>
| NodeDropChange<T, U>;
export interface NodeSelectChange<T extends NodeEntity, U extends EdgeEntity> {
type: "select";
node: FlowNode<T, U>;
selected: boolean;
}
export interface NodeDragChange<T extends NodeEntity, U extends EdgeEntity> {
type: "drag";
node: FlowNode<T, U>;
position: {
x: number;
y: number;
};
positionAbsolute: {
x: number;
y: number;
};
}
export interface NodeDropChange<T extends NodeEntity, U extends EdgeEntity> {
type: "drop";
node: FlowNode<T, U>;
}
The node property of each object holds information about the node that triggered the event, which may include information about the workflow element it belongs to, its type, and more.
{
"type": "select",
"node": {
"id": "fa87d235-b6a6-4e36-af2a-e360b4bddb1b/flow/block",
"type": "component",
"entity": {
"type": "elementType/action/flow/block",
"meta": {
"type": "elementType",
"elementType": "action",
"mode": "flow",
"item": "block",
"id": "fa87d235-b6a6-4e36-af2a-e360b4bddb1b",
"dropArea": false
},
"data": {
"...": "..."
}
},
"...": "..."
},
"selected": true
}
Workflow Changes
The properties of the FlowsChange object guide a chain of dispatcher functions toward the final handler, which is responsible for creating the WorkflowChange objects.

These dispatcher functions are built using the zet utility function, as shown in this file.
// src/shared/kits/workflow/mvc/controller/controller/index.ts
// ...
interface Zet {
object: TypedFlowsChange;
nested: ["node", "entity"];
filter: ["meta", "type"];
params: [Workflow, TypedFlows];
return: WorkflowChange[];
}
const dispatch = zet<Zet>(["node", "entity"], ["meta", "type"], {
global: globalChangeToWorkflowChanges,
elementType: elementTypeChangeToWorkflowChanges,
});
export function flowChangeToWorkflowChanges(
change: TypedFlowsChange,
workflow: Workflow,
flows: TypedFlows,
): WorkflowChange[] {
return dispatch(change, workflow, flows);
}
export type GlobalChange = Refine<{
object: TypedFlowsChange;
nested: ["node", "entity"];
filter: ["meta", "type"];
narrow: "global";
}>;
export type ElementTypeChange = Refine<{
object: TypedFlowsChange;
nested: ["node", "entity"];
filter: ["meta", "type"];
narrow: "elementType";
}>;
For an in-depth explanation of how this utility works, visit the following link.