diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 04f2a4a4fe..486831e136 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -1571,8 +1571,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 = { @@ -1714,10 +1727,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 @@ -2013,33 +2026,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) continue 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 38f74efaad..518869503d 100644 --- a/src/lib/litegraph/src/subgraph/subgraphUtils.ts +++ b/src/lib/litegraph/src/subgraph/subgraphUtils.ts @@ -4,6 +4,7 @@ import { LGraphNode } from '@/lib/litegraph/src/LGraphNode' import { LLink } from '@/lib/litegraph/src/LLink' import type { ResolvedConnection } from '@/lib/litegraph/src/LLink' import { Reroute } from '@/lib/litegraph/src/Reroute' +import type { RerouteId } from '@/lib/litegraph/src/Reroute' import { SUBGRAPH_INPUT_ID, SUBGRAPH_OUTPUT_ID @@ -259,10 +260,29 @@ export function groupResolvedByOutput( return groupedByOutput } +function mapReroutes( + link: SerialisableLLink, + reroutes: Map +) { + 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) + } + + const lastId = child.parentId + child.parentId = undefined + return lastId +} export function mapSubgraphInputsAndLinks( resolvedInputLinks: ResolvedConnection[], - links: SerialisableLLink[] + links: SerialisableLLink[], + reroutes: Map ): SubgraphIO[] { // Group matching links const groupedByOutput = groupResolvedByOutput(resolvedInputLinks) @@ -279,8 +299,10 @@ export function mapSubgraphInputsAndLinks( if (!input) continue const linkData = link.asSerialisable() + link.parentId = mapReroutes(link, reroutes) linkData.origin_id = SUBGRAPH_INPUT_ID linkData.origin_slot = inputs.length + links.push(linkData) inputLinks.push(linkData) } @@ -340,7 +362,8 @@ export function mapSubgraphInputsAndLinks( */ export function mapSubgraphOutputsAndLinks( resolvedOutputLinks: ResolvedConnection[], - links: SerialisableLLink[] + links: SerialisableLLink[], + reroutes: Map ): SubgraphIO[] { // Group matching links const groupedByOutput = groupResolvedByOutput(resolvedOutputLinks) @@ -355,10 +378,11 @@ export function mapSubgraphOutputsAndLinks( const { link, output } = resolved if (!output) continue - // Link const linkData = link.asSerialisable() + linkData.parentId = mapReroutes(link, reroutes) linkData.target_id = SUBGRAPH_OUTPUT_ID linkData.target_slot = outputs.length + links.push(linkData) outputLinks.push(linkData) }