[Bug] Fix remove of floatingLinks (#792)

Resolves https://github.com/Comfy-Org/litegraph.js/issues/791

This PR fixes removal of floating links.

---------

Co-authored-by: filtered <176114999+webfiltered@users.noreply.github.com>
This commit is contained in:
Chenlei Hu
2025-03-16 18:13:24 -04:00
committed by GitHub
parent dbc605e4da
commit 94b9ecec71
5 changed files with 96 additions and 1 deletions

View File

@@ -900,6 +900,13 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
}
}
// Floating links
for (const link of this.floatingLinks.values()) {
if (link.origin_id === node.id || link.target_id === node.id) {
this.removeFloatingLink(link)
}
}
// callback
node.onRemoved?.()
@@ -1401,6 +1408,10 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
if (reroute.floatingLinkIds.size === 0) {
delete reroute.floating
}
if (reroute.floatingLinkIds.size === 0 && reroute.linkIds.size === 0) {
this.removeReroute(reroute.id)
}
}
}

View File

@@ -32,6 +32,18 @@ describe("LGraph", () => {
const fromOldSchema = new LGraph(oldSchemaGraph)
expect(fromOldSchema).toMatchSnapshot("oldSchemaGraph")
})
describe("Reroutes", () => {
test("Floating reroute should be removed when node and link are removed", ({ expect, floatingLinkGraph }) => {
const graph = new LGraph(floatingLinkGraph)
expect(graph.nodes.length).toBe(1)
graph.remove(graph.nodes[0])
expect(graph.nodes.length).toBe(0)
expect(graph.links.size).toBe(0)
expect(graph.floatingLinks.size).toBe(0)
expect(graph.reroutes.size).toBe(0)
})
})
})
describe("Legacy LGraph Compatibility Layer", () => {

View File

@@ -0,0 +1,68 @@
{
"id": "d175890f-716a-4ece-ba33-1d17a513b7be",
"revision": 0,
"last_node_id": 2,
"last_link_id": 1,
"nodes": [
{
"id": 2,
"type": "VAEDecode",
"pos": [63.44815444946289, 178.71633911132812],
"size": [210, 46],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": []
}
],
"properties": {
"Node name for S&R": "VAEDecode"
},
"widgets_values": []
}
],
"links": [],
"floatingLinks": [
{
"id": 4,
"origin_id": 2,
"origin_slot": 0,
"target_id": -1,
"target_slot": -1,
"type": "IMAGE",
"parentId": 1
}
],
"groups": [],
"config": {},
"extra": {
"linkExtensions": [],
"reroutes": [
{
"id": 1,
"pos": [393.2383117675781, 194.61941528320312],
"linkIds": [],
"floating": {
"slotType": "output"
}
}
]
},
"version": 0.4
}

View File

@@ -5,12 +5,14 @@ import { test as baseTest } from "vitest"
import { LGraph } from "@/LGraph"
import { LiteGraph } from "@/litegraph"
import floatingLink from "./assets/floatingLink.json"
import { basicSerialisableGraph, minimalSerialisableGraph, oldSchemaGraph } from "./assets/testGraphs"
interface LitegraphFixtures {
minimalGraph: LGraph
minimalSerialisableGraph: SerialisableGraph
oldSchemaGraph: ISerialisedGraph
floatingLinkGraph: ISerialisedGraph
}
/** These fixtures alter global state, and are difficult to reset. Relies on a single test per-file to reset state. */
@@ -29,6 +31,7 @@ export const test = baseTest.extend<LitegraphFixtures>({
},
minimalSerialisableGraph: structuredClone(minimalSerialisableGraph),
oldSchemaGraph: structuredClone(oldSchemaGraph),
floatingLinkGraph: structuredClone(floatingLink as unknown as ISerialisedGraph),
})
/** Test that use {@link DirtyFixtures}. One test per file. */

View File

@@ -5,7 +5,8 @@
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true
"noUnusedParameters": true,
"resolveJsonModule": true
},
"include": ["**/*"]
}