mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-01 11:10:00 +00:00
Add Subgraphs (#3905)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import type { ColorOption, LGraph } from '@comfyorg/litegraph'
|
||||
import { ColorOption, LGraph, Reroute } from '@comfyorg/litegraph'
|
||||
import { LGraphGroup, LGraphNode, isColorable } from '@comfyorg/litegraph'
|
||||
import type { ISerialisedGraph } from '@comfyorg/litegraph/dist/types/serialisation'
|
||||
import type {
|
||||
ExportedSubgraph,
|
||||
ISerialisableNodeInput,
|
||||
ISerialisedGraph
|
||||
} from '@comfyorg/litegraph/dist/types/serialisation'
|
||||
import type {
|
||||
IBaseWidget,
|
||||
IComboWidget
|
||||
@@ -50,6 +54,10 @@ export const isLGraphGroup = (item: unknown): item is LGraphGroup => {
|
||||
return item instanceof LGraphGroup
|
||||
}
|
||||
|
||||
export const isReroute = (item: unknown): item is Reroute => {
|
||||
return item instanceof Reroute
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color option of all canvas items if they are all the same.
|
||||
* @param items - The items to get the color option of.
|
||||
@@ -163,12 +171,11 @@ export function fixLinkInputSlots(graph: LGraph) {
|
||||
* This should match the serialization format of legacy widget conversion.
|
||||
*
|
||||
* @param graph - The graph to compress widget input slots for.
|
||||
* @throws If an infinite loop is detected.
|
||||
*/
|
||||
export function compressWidgetInputSlots(graph: ISerialisedGraph) {
|
||||
for (const node of graph.nodes) {
|
||||
node.inputs = node.inputs?.filter(
|
||||
(input) => !(input.widget && input.link === null)
|
||||
)
|
||||
node.inputs = node.inputs?.filter(matchesLegacyApi)
|
||||
|
||||
for (const [inputIndex, input] of node.inputs?.entries() ?? []) {
|
||||
if (input.link) {
|
||||
@@ -179,4 +186,44 @@ export function compressWidgetInputSlots(graph: ISerialisedGraph) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compressSubgraphWidgetInputSlots(graph.definitions?.subgraphs)
|
||||
}
|
||||
|
||||
function matchesLegacyApi(input: ISerialisableNodeInput) {
|
||||
return !(input.widget && input.link === null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplication to handle the legacy link arrays in the root workflow.
|
||||
* @see compressWidgetInputSlots
|
||||
* @param subgraph The subgraph to compress widget input slots for.
|
||||
*/
|
||||
function compressSubgraphWidgetInputSlots(
|
||||
subgraphs: ExportedSubgraph[] | undefined,
|
||||
visited = new WeakSet<ExportedSubgraph>()
|
||||
) {
|
||||
if (!subgraphs) return
|
||||
|
||||
for (const subgraph of subgraphs) {
|
||||
if (visited.has(subgraph)) throw new Error('Infinite loop detected')
|
||||
visited.add(subgraph)
|
||||
|
||||
if (subgraph.nodes) {
|
||||
for (const node of subgraph.nodes) {
|
||||
node.inputs = node.inputs?.filter(matchesLegacyApi)
|
||||
|
||||
if (!subgraph.links) continue
|
||||
|
||||
for (const [inputIndex, input] of node.inputs?.entries() ?? []) {
|
||||
if (input.link) {
|
||||
const link = subgraph.links.find((link) => link.id === input.link)
|
||||
if (link) link.target_slot = inputIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compressSubgraphWidgetInputSlots(subgraph.definitions?.subgraphs, visited)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user