|
1 | | -import type { LGraph, LGraphNode, NodeId } from '@comfyorg/litegraph' |
2 | | -import { LGraphEventMode } from '@comfyorg/litegraph' |
| 1 | +import type { LGraph, NodeId } from '@comfyorg/litegraph' |
| 2 | +import { |
| 3 | + ExecutableNodeDTO, |
| 4 | + LGraphEventMode, |
| 5 | + SubgraphNode |
| 6 | +} from '@comfyorg/litegraph' |
3 | 7 |
|
4 | 8 | import type { |
5 | 9 | ComfyApiWorkflow, |
@@ -74,20 +78,31 @@ export const graphToPrompt = async ( |
74 | 78 | workflow.extra ??= {} |
75 | 79 | workflow.extra.frontendVersion = __COMFYUI_FRONTEND_VERSION__ |
76 | 80 |
|
| 81 | + const computedNodeDtos = graph |
| 82 | + .computeExecutionOrder(false) |
| 83 | + .map( |
| 84 | + (node) => |
| 85 | + new ExecutableNodeDTO( |
| 86 | + node, |
| 87 | + [], |
| 88 | + node instanceof SubgraphNode ? node : undefined |
| 89 | + ) |
| 90 | + ) |
| 91 | + |
77 | 92 | let output: ComfyApiWorkflow = {} |
78 | 93 | // Process nodes in order of execution |
79 | | - for (const outerNode of graph.computeExecutionOrder(false)) { |
80 | | - const skipNode = |
| 94 | + for (const outerNode of computedNodeDtos) { |
| 95 | + // Don't serialize muted nodes |
| 96 | + if ( |
81 | 97 | outerNode.mode === LGraphEventMode.NEVER || |
82 | 98 | outerNode.mode === LGraphEventMode.BYPASS |
83 | | - const innerNodes = |
84 | | - !skipNode && outerNode.getInnerNodes |
85 | | - ? outerNode.getInnerNodes() |
86 | | - : [outerNode] |
87 | | - for (const node of innerNodes) { |
| 99 | + ) { |
| 100 | + continue |
| 101 | + } |
| 102 | + |
| 103 | + for (const node of outerNode.getInnerNodes()) { |
88 | 104 | if ( |
89 | 105 | node.isVirtualNode || |
90 | | - // Don't serialize muted nodes |
91 | 106 | node.mode === LGraphEventMode.NEVER || |
92 | 107 | node.mode === LGraphEventMode.BYPASS |
93 | 108 | ) { |
@@ -120,58 +135,14 @@ export const graphToPrompt = async ( |
120 | 135 |
|
121 | 136 | // Store all node links |
122 | 137 | for (const [i, input] of node.inputs.entries()) { |
123 | | - let parent: LGraphNode | null | undefined = node.getInputNode(i) |
124 | | - if (!parent) continue |
125 | | - |
126 | | - let link = node.getInputLink(i) |
127 | | - while ( |
128 | | - parent?.mode === LGraphEventMode.BYPASS || |
129 | | - parent?.isVirtualNode |
130 | | - ) { |
131 | | - if (!link) break |
132 | | - |
133 | | - if (parent.isVirtualNode) { |
134 | | - link = parent.getInputLink(link.origin_slot) |
135 | | - if (!link) break |
136 | | - |
137 | | - parent = parent.isSubgraphNode() |
138 | | - ? parent.resolveSubgraphOutputLink(link.origin_slot)?.outputNode |
139 | | - : parent.getInputNode(link.target_slot) |
140 | | - |
141 | | - if (!parent) break |
142 | | - } else if (!parent.inputs) { |
143 | | - // Maintains existing behaviour if parent.getInputLink is overriden |
144 | | - break |
145 | | - } else if (parent.mode === LGraphEventMode.BYPASS) { |
146 | | - // Bypass nodes by finding first input with matching type |
147 | | - const parentInputIndexes = Object.keys(parent.inputs).map(Number) |
148 | | - // Prioritise exact slot index |
149 | | - const indexes = [link.origin_slot].concat(parentInputIndexes) |
150 | | - |
151 | | - const matchingIndex = indexes.find( |
152 | | - (index) => parent?.inputs[index]?.type === input.type |
153 | | - ) |
154 | | - // No input types match |
155 | | - if (matchingIndex === undefined) break |
156 | | - |
157 | | - link = parent.getInputLink(matchingIndex) |
158 | | - if (link) parent = parent.getInputNode(matchingIndex) |
159 | | - } |
160 | | - } |
161 | | - |
162 | | - if (link) { |
163 | | - if (parent?.updateLink) { |
164 | | - // Subgraph node / groupNode callback; deprecated, should be replaced |
165 | | - link = parent.updateLink(link) |
166 | | - } |
167 | | - if (link) { |
168 | | - inputs[input.name] = [ |
169 | | - String(link.origin_id), |
170 | | - // @ts-expect-error link.origin_slot is already number. |
171 | | - parseInt(link.origin_slot) |
172 | | - ] |
173 | | - } |
174 | | - } |
| 138 | + const resolvedInput = node.resolveInput(i) |
| 139 | + if (!resolvedInput) continue |
| 140 | + |
| 141 | + inputs[input.name] = [ |
| 142 | + String(resolvedInput.origin_id), |
| 143 | + // @ts-expect-error link.origin_slot is already number. |
| 144 | + parseInt(resolvedInput.origin_slot) |
| 145 | + ] |
175 | 146 | } |
176 | 147 |
|
177 | 148 | output[String(node.id)] = { |
|
0 commit comments