Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
code improve
  • Loading branch information
jtydhr88 committed Sep 19, 2025
commit 46ba1629ebe5dbddd17ca3dbe3882b10aed0e8ec
22 changes: 9 additions & 13 deletions src/core/graph/operations/IGraphMutationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import type {
CreateGroupParams,
CreateNodeParams,
CreateSubgraphParams,
CreateSubgraphResult,
DisconnectParams,
GraphMutationOperation,
NodeInputSlotParams,
OperationResultType,
Result,
SubgraphIndexParams,
SubgraphNameTypeParams,
Expand All @@ -26,15 +28,15 @@ import type { RerouteId } from '@/lib/litegraph/src/Reroute'
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'

export interface IGraphMutationService {
applyOperation(
operation: GraphMutationOperation
): Promise<Result<any, GraphMutationError>>
applyOperation<T extends GraphMutationOperation>(
operation: T
): Promise<Result<OperationResultType<T>, GraphMutationError>>

createNode(
params: CreateNodeParams
): Promise<Result<NodeId, GraphMutationError>>

getNodeById(nodeId: NodeId): LGraphNode
getNodeById(nodeId: NodeId): Promise<Result<LGraphNode, GraphMutationError>>

removeNode(nodeId: NodeId): Promise<Result<void, GraphMutationError>>

Expand Down Expand Up @@ -106,15 +108,9 @@ export interface IGraphMutationService {
params: NodeInputSlotParams
): Promise<Result<void, GraphMutationError>>

createSubgraph(params: CreateSubgraphParams): Promise<
Result<
{
subgraph: any
node: any
},
GraphMutationError
>
>
createSubgraph(
params: CreateSubgraphParams
): Promise<Result<CreateSubgraphResult, GraphMutationError>>

unpackSubgraph(
subgraphNodeId: NodeId
Expand Down
83 changes: 49 additions & 34 deletions src/core/graph/operations/graphMutationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import type {
CreateGroupParams,
CreateNodeParams,
CreateSubgraphParams,
CreateSubgraphResult,
DisconnectParams,
GraphMutationOperation,
NodeInputSlotParams,
OperationResultType,
Result,
SubgraphIndexParams,
SubgraphNameTypeParams,
Expand Down Expand Up @@ -50,13 +52,27 @@ export class GraphMutationService implements IGraphMutationService {
return app.graph
}

private getCanvas() {
return app.canvas
}

private getChangeTracker() {
return this.workflowStore.activeWorkflow?.changeTracker
}

async applyOperation(
async applyOperation<T extends GraphMutationOperation>(
operation: T
): Promise<Result<OperationResultType<T>, GraphMutationError>> {
const result = await this._executeOperation(operation)

return result as Result<OperationResultType<T>, GraphMutationError>
}

private async _executeOperation(
operation: GraphMutationOperation
): Promise<Result<any, GraphMutationError>> {
): Promise<
Result<OperationResultType<typeof operation>, GraphMutationError>
> {
switch (operation.type) {
case 'createNode':
return await this.createNode(operation.params)
Expand Down Expand Up @@ -127,7 +143,7 @@ export class GraphMutationService implements IGraphMutationService {
case 'redo':
return await this.redo()
default: {
const unknownOp = operation as any
const unknownOp = operation as { type: string }
console.warn('Unknown operation type:', unknownOp)
return {
success: false,
Expand All @@ -146,24 +162,15 @@ export class GraphMutationService implements IGraphMutationService {
params: CreateNodeParams
): Promise<Result<NodeId, GraphMutationError>> {
try {
const { type, properties, title, id } = params
const { type, properties, title } = params
const graph = this.getGraph()

const node = LiteGraph.createNode(type)
const node = LiteGraph.createNode(type, title)

if (!node) {
throw new Error(`Failed to create node of type: ${type}`)
}

// Set custom ID if provided (for loading workflows)
if (id !== undefined) {
node.id = id
}

if (title) {
node.title = title
}

if (properties) {
Object.assign(node.properties || {}, properties)
}
Expand All @@ -190,15 +197,26 @@ export class GraphMutationService implements IGraphMutationService {
}
}

getNodeById(nodeId: NodeId): LGraphNode {
const graph = this.getGraph()
const node = graph.getNodeById(nodeId)
getNodeById(nodeId: NodeId): Promise<Result<LGraphNode, GraphMutationError>> {
try {
const graph = this.getGraph()
const node = graph.getNodeById(nodeId)

if (!node) {
throw new Error(`Node with id ${nodeId} not found`)
}
if (!node) {
throw new Error(`Node with id ${nodeId} not found`)
}

return node
return Promise.resolve({ success: true, data: node })
} catch (error) {
return Promise.resolve({
success: false,
error: new GraphMutationError('Failed to get node by id', {
operation: 'getNodeById',
params: nodeId,
cause: error
})
})
}
}

async removeNode(nodeId: NodeId): Promise<Result<void, GraphMutationError>> {
Expand Down Expand Up @@ -1004,15 +1022,9 @@ export class GraphMutationService implements IGraphMutationService {
}
}

async createSubgraph(params: CreateSubgraphParams): Promise<
Result<
{
subgraph: any
node: any
},
GraphMutationError
>
> {
async createSubgraph(
params: CreateSubgraphParams
): Promise<Result<CreateSubgraphResult, GraphMutationError>> {
try {
const graph = this.getGraph()

Expand Down Expand Up @@ -1197,12 +1209,15 @@ export class GraphMutationService implements IGraphMutationService {

async clearGraph(): Promise<Result<void, GraphMutationError>> {
try {
// No params to validate for clear operation
const graph = this.getGraph()
const canvas = this.getCanvas()

graph.beforeChange()
graph.clear()
graph.afterChange()
//TODO same behavior as app.clear() to skip if it's a subgraph
if (graph && !canvas.subgraph) {
graph.beforeChange()
graph.clear()
graph.afterChange()
}
return { success: true, data: undefined }
} catch (error) {
return {
Expand Down
84 changes: 58 additions & 26 deletions src/core/graph/operations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
* Defines command types for graph mutation operations with CRDT support.
* Each command represents an atomic operation that can be applied, undone, and synchronized.
*/
import type { GroupId } from '@/lib/litegraph/src/LGraphGroup'
import type { Subgraph } from '@/lib/litegraph/src/LGraph'
import type { GroupId, LGraphGroup } from '@/lib/litegraph/src/LGraphGroup'
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
import type { LinkId } from '@/lib/litegraph/src/LLink'
import type { RerouteId } from '@/lib/litegraph/src/Reroute'
import type { SubgraphId } from '@/lib/litegraph/src/subgraph/SubgraphNode'
import type {
SubgraphId,
SubgraphNode
} from '@/lib/litegraph/src/subgraph/SubgraphNode'
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'

export type Result<T, E> =
Expand All @@ -16,15 +21,14 @@ export type Result<T, E> =

export interface CreateNodeParams {
type: string
properties?: Record<string, any>
properties?: Record<string, string | number | boolean | object>
title?: string
id?: NodeId // Support custom ID for loading workflows
}

export interface UpdateNodePropertyParams {
nodeId: NodeId
property: string
value: any
value: string | number | boolean | object | string[] | undefined
}

export interface UpdateNodeTitleParams {
Expand Down Expand Up @@ -78,18 +82,18 @@ export interface AddNodeInputParams {
nodeId: NodeId
name: string
type: string
extra_info?: Record<string, any>
extra_info?: Record<string, unknown>
}

export interface AddNodeOutputParams {
nodeId: NodeId
name: string
type: string
extra_info?: Record<string, any>
extra_info?: Record<string, unknown>
}

export interface CreateSubgraphParams {
selectedItems: Set<any>
selectedItems: Set<LGraphNode | LGraphGroup>
}

export interface NodeInputSlotParams {
Expand All @@ -113,7 +117,7 @@ export enum CommandOrigin {
}

export type GraphMutationOperation =
| createNodeCommand
| CreateNodeCommand
| RemoveNodeCommand
| UpdateNodePropertyCommand
| UpdateNodeTitleCommand
Expand Down Expand Up @@ -145,10 +149,8 @@ export type GraphMutationOperation =
| RemoveSubgraphInputCommand
| RemoveSubgraphOutputCommand
| ClearGraphCommand
| bypassNodeCommand
| unbypassNodeCommand
| undoCommand
| redoCommand
| UndoCommand
| RedoCommand

interface GraphOpBase {
/** Timestamp for ordering commands */
Expand All @@ -157,7 +159,7 @@ interface GraphOpBase {
origin: CommandOrigin
}

export interface createNodeCommand extends GraphOpBase {
export interface CreateNodeCommand extends GraphOpBase {
type: 'createNode'
params: CreateNodeParams
}
Expand Down Expand Up @@ -316,20 +318,50 @@ export interface ClearGraphCommand extends GraphOpBase {
type: 'clearGraph'
}

export interface bypassNodeCommand extends GraphOpBase {
type: 'bypassNode'
params: NodeId
}

export interface unbypassNodeCommand extends GraphOpBase {
type: 'unbypassNode'
params: NodeId
}

export interface undoCommand extends GraphOpBase {
export interface UndoCommand extends GraphOpBase {
type: 'undo'
}

export interface redoCommand extends GraphOpBase {
export interface RedoCommand extends GraphOpBase {
type: 'redo'
}

export type NodeIdReturnOperations = CreateNodeCommand | CloneNodeCommand

export type LinkIdReturnOperations = ConnectCommand

export type BooleanReturnOperations = DisconnectCommand

export type GroupIdReturnOperations = CreateGroupCommand

export type RerouteIdReturnOperations = AddRerouteCommand

export type NodeIdArrayReturnOperations = PasteNodesCommand

export type NumberReturnOperations =
| AddSubgraphNodeInputCommand
| AddSubgraphNodeOutputCommand

export interface CreateSubgraphResult {
subgraph: Subgraph
node: SubgraphNode
}

export type OperationResultType<T extends GraphMutationOperation> =
T extends NodeIdReturnOperations
? NodeId
: T extends LinkIdReturnOperations
? LinkId
: T extends BooleanReturnOperations
? boolean
: T extends GroupIdReturnOperations
? GroupId
: T extends RerouteIdReturnOperations
? RerouteId
: T extends NodeIdArrayReturnOperations
? NodeId[]
: T extends NumberReturnOperations
? number
: T extends CreateSubgraphCommand
? CreateSubgraphResult
: void
Loading