diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 139919c60b..5deda12d1d 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -1510,8 +1510,21 @@ export class LGraph // Inputs, outputs, and links const links = internalLinks.map((x) => x.asSerialisable()) - const inputs = mapSubgraphInputsAndLinks(resolvedInputLinks, links) - const outputs = mapSubgraphOutputsAndLinks(resolvedOutputLinks, links) + + const internalReroutes = new Map([...reroutes].map((r) => [r.id, r])) + const externalReroutes = new Map( + [...this.reroutes].filter(([id]) => !internalReroutes.has(id)) + ) + const inputs = mapSubgraphInputsAndLinks( + resolvedInputLinks, + links, + internalReroutes + ) + const outputs = mapSubgraphOutputsAndLinks( + resolvedOutputLinks, + links, + externalReroutes + ) // Prepare subgraph data const data = { @@ -1657,10 +1670,10 @@ export class LGraph // Reconnect output links in parent graph i = 0 for (const [, connections] of outputsGroupedByOutput.entries()) { - // Special handling: Subgraph output node i++ for (const connection of connections) { const { input, inputNode, link, subgraphOutput } = connection + // Special handling: Subgraph output node if (link.target_id === SUBGRAPH_OUTPUT_ID) { link.origin_id = subgraphNode.id link.origin_slot = i - 1 @@ -1915,33 +1928,50 @@ export class LGraph while (parentId) { instance.parentId = parentId instance = this.reroutes.get(parentId) - if (!instance) throw new Error('Broken Id link when unpacking') + if (!instance) { + console.error('Broken Id link when unpacking') + break + } if (instance.linkIds.has(linkInstance.id)) throw new Error('Infinite parentId loop') instance.linkIds.add(linkInstance.id) parentId = instance.parentId } } + if (!instance) break parentId = newLink.iparent while (parentId) { const migratedId = rerouteIdMap.get(parentId) - if (!migratedId) throw new Error('Broken Id link when unpacking') + if (!migratedId) { + console.error('Broken Id link when unpacking') + break + } instance.parentId = migratedId instance = this.reroutes.get(migratedId) - if (!instance) throw new Error('Broken Id link when unpacking') + if (!instance) { + console.error('Broken Id link when unpacking') + break + } if (instance.linkIds.has(linkInstance.id)) throw new Error('Infinite parentId loop') instance.linkIds.add(linkInstance.id) const oldReroute = subgraphNode.subgraph.reroutes.get(parentId) - if (!oldReroute) throw new Error('Broken Id link when unpacking') + if (!oldReroute) { + console.error('Broken Id link when unpacking') + break + } parentId = oldReroute.parentId } + if (!instance) break if (!newLink.externalFirst) { parentId = newLink.eparent while (parentId) { instance.parentId = parentId instance = this.reroutes.get(parentId) - if (!instance) throw new Error('Broken Id link when unpacking') + if (!instance) { + console.error('Broken Id link when unpacking') + break + } if (instance.linkIds.has(linkInstance.id)) throw new Error('Infinite parentId loop') instance.linkIds.add(linkInstance.id) diff --git a/src/lib/litegraph/src/subgraph/subgraphUtils.ts b/src/lib/litegraph/src/subgraph/subgraphUtils.ts index c225dd7b86..bf11434e5f 100644 --- a/src/lib/litegraph/src/subgraph/subgraphUtils.ts +++ b/src/lib/litegraph/src/subgraph/subgraphUtils.ts @@ -2,7 +2,7 @@ import type { LGraph } from '@/lib/litegraph/src/LGraph' import { LGraphGroup } from '@/lib/litegraph/src/LGraphGroup' import { LGraphNode } from '@/lib/litegraph/src/LGraphNode' import { LLink, type ResolvedConnection } from '@/lib/litegraph/src/LLink' -import { Reroute } from '@/lib/litegraph/src/Reroute' +import { Reroute, type RerouteId } from '@/lib/litegraph/src/Reroute' import { SUBGRAPH_INPUT_ID, SUBGRAPH_OUTPUT_ID @@ -259,7 +259,8 @@ export function groupResolvedByOutput( export function mapSubgraphInputsAndLinks( resolvedInputLinks: ResolvedConnection[], - links: SerialisableLLink[] + links: SerialisableLLink[], + reroutes: Map ): SubgraphIO[] { // Group matching links const groupedByOutput = groupResolvedByOutput(resolvedInputLinks) @@ -274,8 +275,23 @@ export function mapSubgraphInputsAndLinks( for (const resolved of connections) { const { link, input } = resolved if (!input) continue - const linkData = link.asSerialisable() + + let child: SerialisableLLink | Reroute = linkData + let nextReroute = + child.parentId === undefined ? undefined : reroutes.get(child.parentId) + while (child.parentId !== undefined && nextReroute) { + child = nextReroute + nextReroute = + child.parentId === undefined + ? undefined + : reroutes.get(child.parentId) + } + //set outside link to first remaining reroute OR undefined + link.parentId = child.parentId + //ensure end of chain is undefined + child.parentId = undefined + linkData.origin_id = SUBGRAPH_INPUT_ID linkData.origin_slot = inputs.length links.push(linkData) @@ -337,7 +353,8 @@ export function mapSubgraphInputsAndLinks( */ export function mapSubgraphOutputsAndLinks( resolvedOutputLinks: ResolvedConnection[], - links: SerialisableLLink[] + links: SerialisableLLink[], + reroutes: Map ): SubgraphIO[] { // Group matching links const groupedByOutput = groupResolvedByOutput(resolvedOutputLinks) @@ -351,9 +368,21 @@ export function mapSubgraphOutputsAndLinks( for (const resolved of connections) { const { link, output } = resolved if (!output) continue - - // Link const linkData = link.asSerialisable() + + let child: SerialisableLLink | Reroute = link + let nextReroute = + child.parentId === undefined ? undefined : reroutes.get(child.parentId) + while (child.parentId !== undefined && nextReroute) { + child = nextReroute + nextReroute = + child.parentId === undefined + ? undefined + : reroutes.get(child.parentId) + } + linkData.parentId = child.parentId + child.parentId = undefined + linkData.target_id = SUBGRAPH_OUTPUT_ID linkData.target_slot = outputs.length links.push(linkData)