Flow Builder
Flow Builder protocol schemas
@module studio/flow-builder
Studio Flow Builder Protocol
Defines the specification for the visual Flow Builder (automation canvas) within ObjectStack Studio. Covers:
- Node Shape Registry: Shape and visual style per FlowNodeAction type
- Canvas Node: Position, size, and rendering hints for each node on canvas
- Canvas Edge: Visual properties for sequence flows (normal, default, fault, back-edge)
- Flow Builder Config: Canvas settings, palette, minimap, and toolbar
Architecture
┌──────────────────────────────────────────────────────────────┐
│ Toolbar (run / save / undo / zoom / layout) │
├──────────┬───────────────────────────────────┬───────────────┤
│ Node │ Canvas │ Property │
│ Palette │ ┌─────┐ ┌──────────┐ │ Panel │
│ │ │start│───▶│ decision │──▶ ... │ (node-aware) │
│ ─ BPMN │ └─────┘ └──────────┘ │ │
│ ─ CRUD │ ┌──────────┐ │ ─ config │
│ ─ Logic │ │parallel │ │ ─ edges │
│ ─ HTTP │ │ gateway │ │ ─ validation │
├──────────┴───────────────────────────────────┴───────────────┤
│ Minimap / Zoom Controls │
└──────────────────────────────────────────────────────────────┘Source: packages/spec/src/studio/flow-builder.zod.ts
TypeScript Usage
import { FlowBuilderConfigSchema, FlowCanvasEdgeSchema, FlowCanvasEdgeStyleSchema, FlowCanvasNodeSchema, FlowLayoutAlgorithmSchema, FlowLayoutDirectionSchema, FlowNodeRenderDescriptorSchema, FlowNodeShapeSchema } from '@objectstack/spec/studio';
import type { FlowBuilderConfig, FlowCanvasEdge, FlowCanvasEdgeStyle, FlowCanvasNode, FlowLayoutAlgorithm, FlowLayoutDirection, FlowNodeRenderDescriptor, FlowNodeShape } from '@objectstack/spec/studio';
// Validate data
const result = FlowBuilderConfigSchema.parse(data);FlowBuilderConfig
Studio Flow Builder configuration
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| snap | { enabled: boolean; gridSize: integer; showGrid: boolean } | optional (default: {"enabled":true,"gridSize":16,"showGrid":true}) | Canvas snap-to-grid settings |
| zoom | { min: number; max: number; default: number; step: number } | optional (default: {"min":0.25,"max":3,"default":1,"step":0.1}) | Canvas zoom settings |
| layoutAlgorithm | Enum<'dagre' | 'elk' | 'force' | 'manual'> | optional (default: "dagre") | Default auto-layout algorithm |
| layoutDirection | Enum<'TB' | 'BT' | 'LR' | 'RL'> | optional (default: "TB") | Default auto-layout direction |
| nodeDescriptors | { action: string; shape: Enum<'rounded_rect' | 'circle' | 'diamond' | 'parallelogram' | 'hexagon' | …>; icon: string; defaultLabel: string; … }[] | optional | Custom node render descriptors (merged with built-in defaults) |
| showMinimap | boolean | optional (default: true) | Show minimap panel |
| showPropertyPanel | boolean | optional (default: true) | Show property panel |
| showPalette | boolean | optional (default: true) | Show node palette sidebar |
| undoLimit | integer | optional (default: 50) | Maximum undo history steps |
| animateExecution | boolean | optional (default: true) | Animate edges during execution preview |
| connectionValidation | boolean | optional (default: true) | Validate connections before creating edges |
Nested Shape: FlowBuilderConfig.snap
| Property | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | optional (default: true) | Enable snap-to-grid |
| gridSize | integer | optional (default: 16) | Snap grid size in pixels |
| showGrid | boolean | optional (default: true) | Show grid overlay |
Nested Shape: FlowBuilderConfig.zoom
| Property | Type | Required | Description |
|---|---|---|---|
| min | number | optional (default: 0.25) | Minimum zoom level |
| max | number | optional (default: 3) | Maximum zoom level |
| default | number | optional (default: 1) | Default zoom level |
| step | number | optional (default: 0.1) | Zoom step |
Nested Shape: FlowBuilderConfig.nodeDescriptors[number]
Visual render descriptor for a flow node type
| Property | Type | Required | Description |
|---|---|---|---|
| action | string | ✅ | FlowNodeAction value (e.g., "parallel_gateway") |
| shape | Enum<'rounded_rect' | 'circle' | 'diamond' | 'parallelogram' | 'hexagon' | …> | ✅ | Shape to render |
| icon | string | ✅ | Lucide icon name |
| defaultLabel | string | ✅ | Default display label |
| defaultWidth | integer | optional (default: 120) | Default width in pixels |
| defaultHeight | integer | optional (default: 60) | Default height in pixels |
| fillColor | string | optional (default: "#ffffff") | Node fill color (CSS value) |
| borderColor | string | optional (default: "#94a3b8") | Node border color (CSS value) |
| allowBoundaryEvents | boolean | optional (default: false) | Whether boundary events can be attached to this node type |
| paletteCategory | Enum<'event' | 'gateway' | 'activity' | 'data' | 'subflow'> | ✅ | Palette category for grouping |
FlowCanvasEdge
Canvas layout and visual data for a flow edge
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| edgeId | string | ✅ | Corresponding FlowEdge.id |
| style | Enum<'solid' | 'dashed' | 'dotted' | 'bold' | 'back'> | optional (default: "solid") | Line style |
| color | string | optional (default: "#94a3b8") | Edge line color |
| labelPosition | number | optional (default: 0.5) | Position of the condition label along the edge |
| waypoints | { x: number; y: number }[] | optional | Manual waypoints for edge routing |
| animated | boolean | optional (default: false) | Show animated flow indicator |
Nested Shape: FlowCanvasEdge.waypoints[number]
| Property | Type | Required | Description |
|---|---|---|---|
| x | number | ✅ | Waypoint X |
| y | number | ✅ | Waypoint Y |
FlowCanvasEdgeStyle
Edge line style
Allowed Values
soliddasheddottedboldback
FlowCanvasNode
Canvas layout data for a flow node
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| nodeId | string | ✅ | Corresponding FlowNode.id |
| x | number | ✅ | X position on canvas |
| y | number | ✅ | Y position on canvas |
| width | integer | optional | Width override in pixels |
| height | integer | optional | Height override in pixels |
| collapsed | boolean | optional (default: false) | Whether the node is collapsed |
| fillColor | string | optional | Fill color override |
| borderColor | string | optional | Border color override |
| annotation | string | optional | User annotation displayed near the node |
FlowLayoutAlgorithm
Auto-layout algorithm for the flow canvas
Allowed Values
dagreelkforcemanual
FlowLayoutDirection
Auto-layout direction
Allowed Values
TBBTLRRL
FlowNodeRenderDescriptor
Visual render descriptor for a flow node type
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| action | string | ✅ | FlowNodeAction value (e.g., "parallel_gateway") |
| shape | Enum<'rounded_rect' | 'circle' | 'diamond' | 'parallelogram' | 'hexagon' | 'diamond_thick' | 'attached_circle' | 'screen_rect'> | ✅ | Shape to render |
| icon | string | ✅ | Lucide icon name |
| defaultLabel | string | ✅ | Default display label |
| defaultWidth | integer | optional (default: 120) | Default width in pixels |
| defaultHeight | integer | optional (default: 60) | Default height in pixels |
| fillColor | string | optional (default: "#ffffff") | Node fill color (CSS value) |
| borderColor | string | optional (default: "#94a3b8") | Node border color (CSS value) |
| allowBoundaryEvents | boolean | optional (default: false) | Whether boundary events can be attached to this node type |
| paletteCategory | Enum<'event' | 'gateway' | 'activity' | 'data' | 'subflow'> | ✅ | Palette category for grouping |
FlowNodeShape
Visual shape for rendering a flow node on the canvas
Allowed Values
rounded_rectcirclediamondparallelogramhexagondiamond_thickattached_circlescreen_rect