From 438d0fc222a83e15f993da0c80770dd504a265a7 Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Mon, 8 Dec 2025 10:35:46 -0800 Subject: [PATCH 1/3] Fix disconnection of moved input links --- src/lib/litegraph/src/canvas/ToInputFromIoNodeLink.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/litegraph/src/canvas/ToInputFromIoNodeLink.ts b/src/lib/litegraph/src/canvas/ToInputFromIoNodeLink.ts index e98c59d87a..073c777f1f 100644 --- a/src/lib/litegraph/src/canvas/ToInputFromIoNodeLink.ts +++ b/src/lib/litegraph/src/canvas/ToInputFromIoNodeLink.ts @@ -63,6 +63,9 @@ export class ToInputFromIoNodeLink implements RenderLink { if (existingLink) { // Moving an existing link + const { input, inputNode } = existingLink.resolve(this.network) + if (inputNode && input) + this.node._disconnectNodeInput(inputNode, input, existingLink) events.dispatch('input-moved', this) } else { // Creating a new link From 500b0ce6c00261e90b27728076acfd63b1c3582b Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Mon, 8 Dec 2025 11:12:28 -0800 Subject: [PATCH 2/3] Add test. Remove unneeded skips --- ...nkConnectorSubgraphInputValidation.test.ts | 64 ++++++++++++++++--- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts b/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts index 9570765261..5ff28735b3 100644 --- a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts +++ b/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts @@ -1,15 +1,20 @@ // TODO: Fix these tests after migration import { beforeEach, describe, expect, it, vi } from 'vitest' -import { LinkConnector } from '@/lib/litegraph/src/litegraph' -import { MovingOutputLink } from '@/lib/litegraph/src/litegraph' -import { ToOutputRenderLink } from '@/lib/litegraph/src/litegraph' -import { LGraphNode, LLink } from '@/lib/litegraph/src/litegraph' +import { + LinkConnector, + MovingOutputLink, + ToOutputRenderLink, + LGraphNode, + LLink +} from '@/lib/litegraph/src/litegraph' +import { ToInputFromIoNodeLink } from '@/lib/litegraph/src/canvas/ToInputFromIoNodeLink' import type { NodeInputSlot } from '@/lib/litegraph/src/litegraph' +import { LinkDirection } from '@/lib/litegraph/src/types/globalEnums' import { createTestSubgraph } from '../subgraph/fixtures/subgraphHelpers' -describe.skip('LinkConnector SubgraphInput connection validation', () => { +describe('LinkConnector SubgraphInput connection validation', () => { let connector: LinkConnector const mockSetConnectingLinks = vi.fn() @@ -17,8 +22,49 @@ describe.skip('LinkConnector SubgraphInput connection validation', () => { connector = new LinkConnector(mockSetConnectingLinks) vi.clearAllMocks() }) + describe('Link disconnection validation', () => { + it('should properly cleanup a moved input link', () => { + const subgraph = createTestSubgraph({ + inputs: [{ name: 'number_input', type: 'number' }] + }) + + const fromTargetNode = new LGraphNode('TargetNode') + fromTargetNode.addInput('number_in', 'number') + fromTargetNode.onConnectionsChange = vi.fn() + subgraph.add(fromTargetNode) + + const toTargetNode = new LGraphNode('TargetNode') + toTargetNode.addInput('number_in', 'number') + toTargetNode.onConnectionsChange = vi.fn() + subgraph.add(toTargetNode) + + const startLink = subgraph.inputNode.slots[0].connect( + fromTargetNode.inputs[0], + fromTargetNode + ) + + const renderLink = new ToInputFromIoNodeLink( + subgraph, + subgraph.inputNode, + subgraph.inputNode.slots[0], + undefined, + LinkDirection.CENTER, + startLink + ) + renderLink.connectToInput( + toTargetNode, + toTargetNode.inputs[0], + connector.events + ) + + expect(fromTargetNode.inputs[0].link).toBeNull() + expect(toTargetNode.inputs[0].link).not.toBeNull() + expect(toTargetNode.onConnectionsChange).toHaveBeenCalled() + expect(fromTargetNode.onConnectionsChange).toHaveBeenCalled() + }) + }) - describe.skip('MovingOutputLink validation', () => { + describe('MovingOutputLink validation', () => { it('should implement canConnectToSubgraphInput method', () => { const subgraph = createTestSubgraph({ inputs: [{ name: 'number_input', type: 'number' }] @@ -113,7 +159,7 @@ describe.skip('LinkConnector SubgraphInput connection validation', () => { }) }) - describe.skip('ToOutputRenderLink validation', () => { + describe('ToOutputRenderLink validation', () => { it('should implement canConnectToSubgraphInput method', () => { // Create a minimal valid setup const subgraph = createTestSubgraph() @@ -130,7 +176,7 @@ describe.skip('LinkConnector SubgraphInput connection validation', () => { }) }) - describe.skip('dropOnIoNode validation', () => { + describe('dropOnIoNode validation', () => { it('should prevent invalid connections when dropping on SubgraphInputNode', () => { const subgraph = createTestSubgraph({ inputs: [{ name: 'number_input', type: 'number' }] @@ -232,7 +278,7 @@ describe.skip('LinkConnector SubgraphInput connection validation', () => { }) }) - describe.skip('isSubgraphInputValidDrop', () => { + describe('isSubgraphInputValidDrop', () => { it('should check if render links can connect to SubgraphInput', () => { const subgraph = createTestSubgraph({ inputs: [{ name: 'number_input', type: 'number' }] From 6d705efa00f60547616ae8a51ac166cdbd5f8794 Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Mon, 8 Dec 2025 11:35:48 -0800 Subject: [PATCH 3/3] Don't track connection changes during init --- .../canvas/LinkConnectorSubgraphInputValidation.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts b/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts index 5ff28735b3..072a0fb4c3 100644 --- a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts +++ b/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts @@ -30,12 +30,10 @@ describe('LinkConnector SubgraphInput connection validation', () => { const fromTargetNode = new LGraphNode('TargetNode') fromTargetNode.addInput('number_in', 'number') - fromTargetNode.onConnectionsChange = vi.fn() subgraph.add(fromTargetNode) const toTargetNode = new LGraphNode('TargetNode') toTargetNode.addInput('number_in', 'number') - toTargetNode.onConnectionsChange = vi.fn() subgraph.add(toTargetNode) const startLink = subgraph.inputNode.slots[0].connect( @@ -43,6 +41,9 @@ describe('LinkConnector SubgraphInput connection validation', () => { fromTargetNode ) + fromTargetNode.onConnectionsChange = vi.fn() + toTargetNode.onConnectionsChange = vi.fn() + const renderLink = new ToInputFromIoNodeLink( subgraph, subgraph.inputNode, @@ -59,8 +60,8 @@ describe('LinkConnector SubgraphInput connection validation', () => { expect(fromTargetNode.inputs[0].link).toBeNull() expect(toTargetNode.inputs[0].link).not.toBeNull() - expect(toTargetNode.onConnectionsChange).toHaveBeenCalled() - expect(fromTargetNode.onConnectionsChange).toHaveBeenCalled() + expect(toTargetNode.onConnectionsChange).toHaveBeenCalledTimes(1) + expect(fromTargetNode.onConnectionsChange).toHaveBeenCalledTimes(1) }) })