mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 22:59:14 +00:00
fix: resolve circular dependency to enable verbatimModuleSyntax
- Use lazy initialization for EmptySubgraphInput/Output in SubgraphInputNode/OutputNode - Replace direct instanceof checks with identity checks in LinkConnector - Enable verbatimModuleSyntax in tsconfig.json - Convert runtime imports to type-only imports where appropriate - Use factory functions with require() to break circular dependencies This resolves the circular dependency chain: EmptySubgraphInput → SubgraphInput → SubgraphInputNode → EmptySubgraphInput The require() usage is necessary here to break the circular dependency at module initialization time. ESLint rules have been disabled for these specific cases. Fixes #5545
This commit is contained in:
@@ -17,8 +17,8 @@ import type {
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot
|
||||
} from '@/lib/litegraph/src/interfaces'
|
||||
import { EmptySubgraphInput } from '@/lib/litegraph/src/subgraph/EmptySubgraphInput'
|
||||
import { EmptySubgraphOutput } from '@/lib/litegraph/src/subgraph/EmptySubgraphOutput'
|
||||
import type { EmptySubgraphInput } from '@/lib/litegraph/src/subgraph/EmptySubgraphInput'
|
||||
import type { EmptySubgraphOutput } from '@/lib/litegraph/src/subgraph/EmptySubgraphOutput'
|
||||
import { Subgraph } from '@/lib/litegraph/src/subgraph/Subgraph'
|
||||
import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput'
|
||||
import { SubgraphInputNode } from '@/lib/litegraph/src/subgraph/SubgraphInputNode'
|
||||
@@ -673,7 +673,7 @@ export class LinkConnector {
|
||||
link.connectToSubgraphOutput(targetSlot, this.events)
|
||||
|
||||
// If we just connected to an EmptySubgraphOutput, check if we should reuse the slot
|
||||
if (output instanceof EmptySubgraphOutput && ioNode.slots.length > 0) {
|
||||
if (output === ioNode.emptySlot && ioNode.slots.length > 0) {
|
||||
// Get the last created slot (newest one)
|
||||
const createdSlot = ioNode.slots[ioNode.slots.length - 1]
|
||||
|
||||
@@ -719,7 +719,7 @@ export class LinkConnector {
|
||||
link.connectToSubgraphInput(targetSlot, this.events)
|
||||
|
||||
// If we just connected to an EmptySubgraphInput, check if we should reuse the slot
|
||||
if (input instanceof EmptySubgraphInput && ioNode.slots.length > 0) {
|
||||
if (input === ioNode.emptySlot && ioNode.slots.length > 0) {
|
||||
// Get the last created slot (newest one)
|
||||
const createdSlot = ioNode.slots[ioNode.slots.length - 1]
|
||||
|
||||
|
||||
@@ -16,18 +16,29 @@ import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { findFreeSlotOfType } from '@/lib/litegraph/src/utils/collections'
|
||||
|
||||
import { EmptySubgraphInput } from './EmptySubgraphInput'
|
||||
import { SubgraphIONodeBase } from './SubgraphIONodeBase'
|
||||
import type { SubgraphInput } from './SubgraphInput'
|
||||
import type { SubgraphOutput } from './SubgraphOutput'
|
||||
|
||||
// Import the type only to avoid circular dependency at runtime
|
||||
import type { EmptySubgraphInput } from './EmptySubgraphInput'
|
||||
|
||||
export class SubgraphInputNode
|
||||
extends SubgraphIONodeBase<SubgraphInput>
|
||||
implements Positionable
|
||||
{
|
||||
readonly id: NodeId = SUBGRAPH_INPUT_ID
|
||||
|
||||
readonly emptySlot: EmptySubgraphInput = new EmptySubgraphInput(this)
|
||||
#emptySlot?: EmptySubgraphInput
|
||||
|
||||
get emptySlot(): EmptySubgraphInput {
|
||||
if (!this.#emptySlot) {
|
||||
// Lazy initialization to break circular dependency
|
||||
// Import is deferred until first access
|
||||
this.#emptySlot = createEmptySubgraphInput(this)
|
||||
}
|
||||
return this.#emptySlot
|
||||
}
|
||||
|
||||
get slots() {
|
||||
return this.subgraph.inputs
|
||||
@@ -264,3 +275,12 @@ export class SubgraphInputNode
|
||||
this.drawSlots(ctx, colorContext, fromSlot, editorAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
// Factory function to break circular dependency
|
||||
// This is defined outside the class to avoid module loading issues
|
||||
function createEmptySubgraphInput(parent: SubgraphInputNode): EmptySubgraphInput {
|
||||
// Import here is safe because it happens after module initialization
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||
const { EmptySubgraphInput } = require('./EmptySubgraphInput') as typeof import('./EmptySubgraphInput')
|
||||
return new EmptySubgraphInput(parent)
|
||||
}
|
||||
|
||||
@@ -16,18 +16,29 @@ import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import type { SubgraphIO } from '@/lib/litegraph/src/types/serialisation'
|
||||
import { findFreeSlotOfType } from '@/lib/litegraph/src/utils/collections'
|
||||
|
||||
import { EmptySubgraphOutput } from './EmptySubgraphOutput'
|
||||
import { SubgraphIONodeBase } from './SubgraphIONodeBase'
|
||||
import type { SubgraphInput } from './SubgraphInput'
|
||||
import type { SubgraphOutput } from './SubgraphOutput'
|
||||
|
||||
// Import the type only to avoid circular dependency at runtime
|
||||
import type { EmptySubgraphOutput } from './EmptySubgraphOutput'
|
||||
|
||||
export class SubgraphOutputNode
|
||||
extends SubgraphIONodeBase<SubgraphOutput>
|
||||
implements Positionable
|
||||
{
|
||||
readonly id: NodeId = SUBGRAPH_OUTPUT_ID
|
||||
|
||||
readonly emptySlot: EmptySubgraphOutput = new EmptySubgraphOutput(this)
|
||||
#emptySlot?: EmptySubgraphOutput
|
||||
|
||||
get emptySlot(): EmptySubgraphOutput {
|
||||
if (!this.#emptySlot) {
|
||||
// Lazy initialization to break circular dependency
|
||||
// Import is deferred until first access
|
||||
this.#emptySlot = createEmptySubgraphOutput(this)
|
||||
}
|
||||
return this.#emptySlot
|
||||
}
|
||||
|
||||
get slots() {
|
||||
return this.subgraph.outputs
|
||||
@@ -158,3 +169,12 @@ export class SubgraphOutputNode
|
||||
this.drawSlots(ctx, colorContext, fromSlot, editorAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
// Factory function to break circular dependency
|
||||
// This is defined outside the class to avoid module loading issues
|
||||
function createEmptySubgraphOutput(parent: SubgraphOutputNode): EmptySubgraphOutput {
|
||||
// Import here is safe because it happens after module initialization
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
|
||||
const { EmptySubgraphOutput } = require('./EmptySubgraphOutput') as typeof import('./EmptySubgraphOutput')
|
||||
return new EmptySubgraphOutput(parent)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"downlevelIteration": true,
|
||||
"noImplicitOverride": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
||||
Reference in New Issue
Block a user