Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
46 changes: 38 additions & 8 deletions src/lib/litegraph/src/LGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
41 changes: 35 additions & 6 deletions src/lib/litegraph/src/subgraph/subgraphUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -259,7 +259,8 @@ export function groupResolvedByOutput(

export function mapSubgraphInputsAndLinks(
resolvedInputLinks: ResolvedConnection[],
links: SerialisableLLink[]
links: SerialisableLLink[],
reroutes: Map<RerouteId, Reroute>
): SubgraphIO[] {
// Group matching links
const groupedByOutput = groupResolvedByOutput(resolvedInputLinks)
Expand All @@ -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)
Expand Down Expand Up @@ -337,7 +353,8 @@ export function mapSubgraphInputsAndLinks(
*/
export function mapSubgraphOutputsAndLinks(
resolvedOutputLinks: ResolvedConnection[],
links: SerialisableLLink[]
links: SerialisableLLink[],
reroutes: Map<RerouteId, Reroute>
): SubgraphIO[] {
// Group matching links
const groupedByOutput = groupResolvedByOutput(resolvedOutputLinks)
Expand All @@ -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)
Expand Down