Flow Composer
Visual canvas for connecting logic flows
Flow Composer
The Flow Composer is a powerful visual tool for connecting entire logic flows together to create complex, large-scale applications. It's like Figma for logic - a beautiful, intuitive canvas where you can compose sophisticated systems from reusable building blocks.
Overview
While the Logic Builder works at the block level (individual operations), the Flow Composer works at the flow level (complete workflows). This allows you to:
- Connect multiple logic flows together
- Create data pipelines across flows
- Build complex systems from reusable components
- Visualize and manage flow relationships
- Execute complete compositions
Getting Started
Opening Flow Composer
- Navigate to Singularity in the main menu
- Click on Flow Composer
- Select or create a new composition
Your First Composition
Create a New Composition
- Click the "New" button in the header
- Give your composition a meaningful name
Add Flows to Canvas
- Browse available flows in the left sidebar
- Drag a flow onto the canvas
- Position it where you want
Connect Flows
- Click an output port (right side) on one flow
- Click an input port (left side) on another flow
- A connection line is created
Save Your Work
- Click the "Save" button in the header
- Your composition is stored and can be loaded later
Canvas Interactions
Mouse Controls
| Action | Control |
|---|---|
| Pan canvas | Middle-click drag OR Shift + left-click drag |
| Zoom in/out | Mouse wheel |
| Add flow | Drag from library |
| Select flow | Left-click |
| Multi-select | Ctrl + left-click |
| Connect flows | Click output port → click input port |
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| Ctrl+Z | Undo |
| Ctrl+Y or Ctrl+Shift+Z | Redo |
| Delete | Remove selected nodes |
| Ctrl+A | Select all nodes |
| Ctrl+S | Save composition (when implemented) |
Canvas Controls
Located in the bottom-right corner:
- Zoom In (+): Increase canvas zoom
- Zoom Out (-): Decrease canvas zoom
- Reset Zoom: Return to 100% zoom
- Toggle Grid: Show/hide background grid
Flow Nodes
Understanding Flow Nodes
Each flow node on the canvas represents a complete logic flow:
- Name: The flow's identifier
- Ports: Connection points (inputs on left, outputs on right)
- Metadata: Block count, complexity, status
- Visual Indicators:
- Border color: Category
- Icon: Flow type
- Badge: Complexity (simple/medium/complex)
Node States
- Idle: Normal state, ready to execute
- Selected: Highlighted, can be moved or deleted
- Executing: Currently running (animated)
- Completed: Successfully executed
- Error: Execution failed
Connections
Creating Connections
- Click an output port (right side) on the source flow
- Move cursor to input port (left side) on the target flow
- Click the input port to complete the connection
Connection Types
- Solid line: Data connection
- Dashed line: Control flow
- Animated: Active data flow (during execution)
Connection Validation
The system automatically validates connections:
- ✅ Valid: Green line, compatible data types
- ❌ Invalid: Red line, incompatible types
- ⚠️ Warning: Yellow line, potential issues
Removing Connections
- Right-click a connection → Select "Delete"
- Select connection and press Delete key
Working with Compositions
Creating a Composition
// Compositions are automatically created when you:
// 1. Click "New" button
// 2. Add first flow to empty canvas
Saving a Composition
- Manual save: Click "Save" button
- Auto-save: Enabled by default (every 5 minutes)
- Save triggers on: Add/remove nodes, create/delete connections
Loading a Composition
- Click "Load" button in header
- Select from list of saved compositions
- Composition loads with all nodes and connections
Cloning a Composition
- Open the composition you want to clone
- Click "Clone" in the actions menu
- A copy is created with "(Copy)" appended to the name
Exporting/Importing
Export
// Export to JSON file
const json = await compositionService.exportComposition(compositionId);
// Download or share the JSON
Import
// Import from JSON file
await compositionService.importComposition(jsonString);
Advanced Features
Multi-Universe Support
Compositions can reference flows from different universes:
// Flows are tagged with universeId
// You can mix flows from multiple universes
// Great for reusing logic across projects
Execution Orchestration
Execute an entire composition:
- Select the composition
- Click "Execute" button
- Watch flows execute in sequence
- View results in execution panel
Undo/Redo
- Undo (Ctrl+Z): Reverts last change
- Redo (Ctrl+Y): Reapplies undone change
- History Limit: Last 50 actions stored
Grid Snapping
- Toggle: Click grid icon in canvas controls
- Size: Default 20px (configurable)
- Behavior: Nodes snap to nearest grid point
Best Practices
Organization
- Group Related Flows: Keep flows that work together close
- Use Categories: Color-code by category
- Name Meaningfully: Clear names help understanding
- Add Descriptions: Document what each flow does
Performance
- Limit Complexity: Keep compositions under 20 flows
- Optimize Flows: Each flow should be efficient
- Avoid Cycles: Circular dependencies cause issues
- Test Incrementally: Test as you build
Reusability
- Create Generic Flows: Make flows reusable
- Parameterize Inputs: Use flow inputs for flexibility
- Document Interfaces: Clear input/output contracts
- Version Control: Use Git for composition backups
Integration with Other Systems
Space-Map Integration
// Get logic statistics for a universe
const stats = await spaceMapIntegration.getUniverseLogicStats(universeId);
// { flowCount: 5, compositionCount: 2, blockCount: 23 }
// Navigate to flow composer from universe detail
const url = spaceMapIntegration.getFlowComposerUrl(universeId);
this.router.navigateByUrl(url);
Editor Integration
// Execute composition from widget event
const result = await editorIntegration.executeCompositionFromWidget(
compositionId,
eventData,
{ widgetId, pageId, universeId }
);
Common Workflows
Building a Data Pipeline
- Add a Data Source flow
- Add Transform flows for processing
- Add a Data Sink flow for storage
- Connect them in sequence
- Test with sample data
Creating a User Authentication System
- Add Login Form flow
- Add Validation flow
- Add Database Check flow
- Add Session Creation flow
- Connect with error handling
Implementing a Workflow
- Add Trigger flow (e.g., button click)
- Add Business Logic flows
- Add Notification flow
- Add Logging flow
- Connect with branching logic
Troubleshooting
Canvas Issues
Problem: Canvas is frozen or unresponsive
- Solution: Refresh the page, composition auto-saves
Problem: Can't zoom or pan
- Solution: Check that you're not in connection mode (click ESC)
Connection Issues
Problem: Can't create connection
- Solution: Ensure you're connecting output → input (not input → output)
Problem: Connection shows as invalid
- Solution: Check data type compatibility between ports
Performance Issues
Problem: Canvas is slow with many nodes
- Solution: Split into multiple smaller compositions
Problem: Execution takes too long
- Solution: Profile individual flows, optimize bottlenecks
Tips & Tricks
Productivity
- Use Ctrl+A to select all nodes, then drag to reposition
- Double-click canvas to create a new node (when implemented)
- Use search in flow library to quickly find flows
Visualization
- Zoom out to see the big picture
- Zoom in for detailed work
- Use grid for precise alignment
- Color-code flows by category
Collaboration
- Export compositions as JSON for version control
- Document complex compositions with README
- Use consistent naming conventions
- Review compositions with team before deployment
API Reference
FlowComposerComponent
// Key methods
async addFlowNode(flow: LogicFlow, position: { x: number; y: number })
async createConnection(sourceNodeId, sourcePortId, targetNodeId, targetPortId)
async saveComposition()
async loadComposition(compositionId: string)
undo()
redo()
FlowCompositionService
// CRUD operations
async createComposition(data: Partial<FlowComposition>): Promise<FlowComposition>
async getComposition(id: string): Promise<FlowComposition | null>
async updateComposition(id: string, updates: Partial<FlowComposition>)
async deleteComposition(id: string)
async listCompositions(filters?: { universeId?: string })
// Node management
async addNode(compositionId, flowId, position)
async removeNode(compositionId, nodeId)
// Connection management
async addConnection(compositionId, sourceNodeId, sourcePortId, targetNodeId, targetPortId)
async removeConnection(compositionId, connectionId)
// Advanced
async cloneComposition(compositionId: string)
async exportComposition(compositionId: string): Promise<string>
async importComposition(json: string)
See Also
- Logic Builder - Build individual flows
- Cross-Library Integration - Connect with other systems
- AI Tools - Leverage AI for flow building
- Execution Engine - How flows are executed
Next Steps
- Practice: Create a simple composition
- Explore: Try connecting different flow types
- Learn: Study example compositions
- Build: Create your own complex systems
- Share: Export and share your compositions
Remember: The Flow Composer is all about visual thinking. Don't be afraid to experiment and iterate!