Comfy-Org / Comfy-Org/ComfyUI_frontend
Implement Graph Mutation Service Architecture
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
# Graph Mutation Service/Gateway/Interface Architecture
The proposed graph mutation architecture represents a fundamental shift from scattered direct LiteGraph API calls to a centralized, validated, and observable mutation pipeline. The architecture follows this flow:
**View → Controllers → Services → Graph Mutation Service → CRDT System → Gateway → Interface → Data Model**
This design enables transaction support, undo/redo, validation, and future multiplayer capabilities while maintaining clean separation of concerns.
## Core Architecture Components
### 1. Graph Mutation Service (Central Pipeline)
The GraphMutationService acts as the single point of entry for ALL graph modifications:
```typescript
interface GraphMutationService {
// All mutations flow through typed methods
addNode(params: AddNodeParams): Promise
updateNodePosition(nodeId: NodeId, pos: [number, number]): Promise
connect(params: ConnectParams): Promise
transaction(fn: () => Promise): Promise
undo(): Promise
redo(): Promise
}
```
**Key Features:**
- Enforces validation before any mutation
- Integrates with CRDT for history tracking
- Supports atomic transactions
- Enables undo/redo naturally through CRDT commands
### 2. Graph Data Model (Pure Data Layer)
Complete separation of data from rendering concerns:
```typescript
interface GraphModel {
nodes: Map // No positions, colors
links: Map // No path data
metadata: GraphMetadata
}
interface NodeData {
id: NodeId
type: string
inputs: PortData[]
outputs: PortData[]
properties: Record
widgets: WidgetData[]
// NO visual properties (position, size, color)
}
```
This enables renderer-agnostic workflows and clean data serialization.
### 3. Graph Gateway (Projection Layer)
The Gateway creates view-specific projections of the pure data model:
```typescript
interface GraphGateway {
getGraph(): GraphModel // Pure data
getCanvasProjection(): CanvasGraphData // With positions
getLinearProjection(): LinearGraphData // Without positions
get3DProjection(): Graph3DData // With spatial data
}
```
This allows the same workflow to be rendered in multiple ways simultaneously.
### 4. Controller Layer (User Intent)
Controllers interpret user actions into semantic operations:
```typescript
class NodeController {
async deleteNodes(nodeIds: NodeId[]) {
// Validate operation
const validation = await this.validator.validateNodeDeletion(nodeIds)
if (!validation.valid) throw new ValidationError(validation.errors)
// Execute through command pattern
const command = new DeleteNodesCommand(nodeIds, this.graphMutation)
await this.commands.execute(command)
}
}
```
## Integration Patterns
### CRDT Integration
All mutations become CRDT operations for history and potential multiplayer:
```typescript
class GraphMutationServiceImpl {
async addNode(params: AddNodeParams): Promise {
await this.validator.validateAddNode(params)
const operation = new AddNodeOperation(params)
const result = await this.crdt.apply(operation) // Enables undo/redo
return result.nodeId
}
}
```
## Migration Strategy
The implementation follows a careful three-phase approach:
### Phase 1: Parallel Implementation
- Build new service alongside existing code
- Route new features through service
- Add migration shims
### Phase 2: Gradual Migration
- Start with high-value operations (node creation/deletion)
- Add deprecation warnings
- Migrate module by module
### Phase 3: Enforcement
- Make LiteGraph private
- Expose only controllers
- Remove direct access
## Key Benefits
1. **Single Source of Truth**: All mutations through one validated pipeline
2. **Transaction Support**: Complex operations can be atomic
3. **Natural Undo/Redo**: Through CRDT command pattern
4. **Multiplayer Ready**: Commands are serializable
5. **Testability**: Business logic separated from UI
6. **Type Safety**: Full TypeScript with validated DTOs
7. **Performance Monitoring**: Can track every mutation
## Trade-offs and Considerations
### Performance Concerns
- Abstraction layer adds overhead
- Mitigation: Batch operations, optimize hot paths
### LiteGraph Integration
- Must handle LiteGraph's internal mutations
- Solution: Gradually replace internals with adapters
### Extension Compatibility
- Breaking change for extensions
- Solution: Compatibility layer with deprecation period
┆Issue is synchronized with this [Notion page](https://www.notion.so/Issue-4691-Implement-Graph-Mutation-Service-Architecture-2466d73d3650817cb4f1e2470ab933c6) by [Unito](https://www.unito.io)
Contributor guide
Assessment
This issue has not been assessed yet.