From b10d06166a924150851fefaecd47eb21ec1173e7 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Mon, 4 Aug 2025 16:16:14 -0400 Subject: [PATCH] Bad circular dep fix: Lazily import and lose some types (needs long term solution) --- src/lib/litegraph/src/LGraph.ts | 12 +++++++----- src/lib/litegraph/src/canvas/LinkConnector.ts | 14 ++++++-------- .../litegraph/src/subgraph/SubgraphInputNode.ts | 11 +++++++++-- .../litegraph/src/subgraph/SubgraphOutputNode.ts | 11 +++++++++-- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 0ccf3421c..2cf84d1d3 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -33,7 +33,7 @@ import { MapProxyHandler } from "./MapProxyHandler" import { alignOutsideContainer, alignToContainer, createBounds } from "./measure" import { Reroute, type RerouteId } from "./Reroute" import { stringOrEmpty } from "./strings" -import { type GraphOrSubgraph, Subgraph } from "./subgraph/Subgraph" +import type { GraphOrSubgraph } from "./subgraph/Subgraph" import { SubgraphInput } from "./subgraph/SubgraphInput" import { SubgraphOutput } from "./subgraph/SubgraphOutput" import { findUsedSubgraphIds, getBoundaryLinks, groupResolvedByOutput, mapSubgraphInputsAndLinks, mapSubgraphOutputsAndLinks, multiClone, splitPositionables } from "./subgraph/subgraphUtils" @@ -130,7 +130,7 @@ export class LGraph implements LinkNetwork, BaseLGraph, Serialisable() - readonly _subgraphs: Map = new Map() + readonly _subgraphs: Map = new Map() _nodes: (LGraphNode | SubgraphNode)[] = [] _nodes_by_id: Record = {} @@ -331,7 +331,7 @@ export class LGraph implements LinkNetwork, BaseLGraph, Serialisable c.clear()) } - get subgraphs(): Map { + get subgraphs(): Map { return this.rootGraph._subgraphs } @@ -1402,9 +1402,11 @@ export class LGraph implements LinkNetwork, BaseLGraph, Serialisable): { subgraph: Subgraph, node: SubgraphNode } { + convertToSubgraph(items: Set): { subgraph: any, node: SubgraphNode } { if (items.size === 0) throw new Error("Cannot convert to subgraph: nothing to convert") const { state, revision, config } = this diff --git a/src/lib/litegraph/src/canvas/LinkConnector.ts b/src/lib/litegraph/src/canvas/LinkConnector.ts index 8a44a68f5..522e76cbc 100644 --- a/src/lib/litegraph/src/canvas/LinkConnector.ts +++ b/src/lib/litegraph/src/canvas/LinkConnector.ts @@ -12,9 +12,7 @@ import type { IBaseWidget } from "@/lib/litegraph/src/types/widgets" import { SUBGRAPH_INPUT_ID, SUBGRAPH_OUTPUT_ID } from "@/lib/litegraph/src/constants" import { CustomEventTarget } from "@/lib/litegraph/src/infrastructure/CustomEventTarget" import { LLink } from "@/lib/litegraph/src/LLink" -import { Subgraph } from "@/lib/litegraph/src/subgraph/Subgraph" -import { SubgraphInputNode } from "@/lib/litegraph/src/subgraph/SubgraphInputNode" -import { SubgraphOutputNode } from "@/lib/litegraph/src/subgraph/SubgraphOutputNode" +import { Subgraph } from "@/lib/litegraph/src/litegraph" import { LinkDirection } from "@/lib/litegraph/src/types/globalEnums" import { FloatingRenderLink } from "./FloatingRenderLink" @@ -310,7 +308,7 @@ export class LinkConnector { this.#setLegacyLinks(true) } - dragNewFromSubgraphInput(network: LinkNetwork, inputNode: SubgraphInputNode, input: SubgraphInput, fromReroute?: Reroute): void { + dragNewFromSubgraphInput(network: LinkNetwork, inputNode: any, input: SubgraphInput, fromReroute?: Reroute): void { if (this.isConnecting) throw new Error("Already dragging links.") const renderLink = new ToInputFromIoNodeLink(network, inputNode, input, fromReroute) @@ -321,7 +319,7 @@ export class LinkConnector { this.#setLegacyLinks(false) } - dragNewFromSubgraphOutput(network: LinkNetwork, outputNode: SubgraphOutputNode, output: SubgraphOutput, fromReroute?: Reroute): void { + dragNewFromSubgraphOutput(network: LinkNetwork, outputNode: any, output: SubgraphOutput, fromReroute?: Reroute): void { if (this.isConnecting) throw new Error("Already dragging links.") const renderLink = new ToOutputFromIoNodeLink(network, outputNode, output, fromReroute) @@ -499,19 +497,19 @@ export class LinkConnector { } } - dropOnIoNode(ioNode: SubgraphInputNode | SubgraphOutputNode, event: CanvasPointerEvent): void { + dropOnIoNode(ioNode: any, event: CanvasPointerEvent): void { const { renderLinks, state } = this const { connectingTo } = state const { canvasX, canvasY } = event - if (connectingTo === "input" && ioNode instanceof SubgraphOutputNode) { + if (connectingTo === "input" && ioNode.id === SUBGRAPH_OUTPUT_ID) { const output = ioNode.getSlotInPosition(canvasX, canvasY) if (!output) throw new Error("No output slot found for link.") for (const link of renderLinks) { link.connectToSubgraphOutput(output, this.events) } - } else if (connectingTo === "output" && ioNode instanceof SubgraphInputNode) { + } else if (connectingTo === "output" && ioNode.id === SUBGRAPH_INPUT_ID) { const input = ioNode.getSlotInPosition(canvasX, canvasY) if (!input) throw new Error("No input slot found for link.") diff --git a/src/lib/litegraph/src/subgraph/SubgraphInputNode.ts b/src/lib/litegraph/src/subgraph/SubgraphInputNode.ts index 30bbdea5f..cd49789da 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphInputNode.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphInputNode.ts @@ -14,13 +14,20 @@ import { LLink } from "@/lib/litegraph/src/LLink" import { NodeSlotType } from "@/lib/litegraph/src/types/globalEnums" import { findFreeSlotOfType } from "@/lib/litegraph/src/utils/collections" -import { EmptySubgraphInput } from "./EmptySubgraphInput" import { SubgraphIONodeBase } from "./SubgraphIONodeBase" export class SubgraphInputNode extends SubgraphIONodeBase implements Positionable { readonly id: NodeId = SUBGRAPH_INPUT_ID - readonly emptySlot: EmptySubgraphInput = new EmptySubgraphInput(this) + private _emptySlot?: any // EmptySubgraphInput type + get emptySlot(): any { + if (!this._emptySlot) { + // Lazy load to avoid circular dependency + const { EmptySubgraphInput } = require("./EmptySubgraphInput") + this._emptySlot = new EmptySubgraphInput(this) + } + return this._emptySlot + } get slots() { return this.subgraph.inputs diff --git a/src/lib/litegraph/src/subgraph/SubgraphOutputNode.ts b/src/lib/litegraph/src/subgraph/SubgraphOutputNode.ts index c5ff9caa7..dd759627e 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphOutputNode.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphOutputNode.ts @@ -14,13 +14,20 @@ import { SUBGRAPH_OUTPUT_ID } from "@/lib/litegraph/src/constants" import { Rectangle } from "@/lib/litegraph/src/infrastructure/Rectangle" import { findFreeSlotOfType } from "@/lib/litegraph/src/utils/collections" -import { EmptySubgraphOutput } from "./EmptySubgraphOutput" import { SubgraphIONodeBase } from "./SubgraphIONodeBase" export class SubgraphOutputNode extends SubgraphIONodeBase implements Positionable { readonly id: NodeId = SUBGRAPH_OUTPUT_ID - readonly emptySlot: EmptySubgraphOutput = new EmptySubgraphOutput(this) + private _emptySlot?: any // EmptySubgraphOutput type + get emptySlot(): any { + if (!this._emptySlot) { + // Lazy load to avoid circular dependency + const { EmptySubgraphOutput } = require("./EmptySubgraphOutput") + this._emptySlot = new EmptySubgraphOutput(this) + } + return this._emptySlot + } get slots() { return this.subgraph.outputs