Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
nits
  • Loading branch information
christian-byrne committed Nov 27, 2025
commit 94036ddac796dee80948b53e5bc941bc6ea9abbe
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import type {
LGraphNode,
Subgraph
} from '@/lib/litegraph/src/litegraph'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
import { collectAllNodes } from '@/utils/graphTraversalUtil'

type NodeDefLookup = Record<string, unknown>
export type NodeDefLookup = Record<string, ComfyNodeDefImpl | undefined>

const isNodeMissingDefinition = (
node: LGraphNode,
Expand All @@ -24,7 +25,7 @@ export const collectMissingNodes = (
nodeDefsByName: MaybeRef<NodeDefLookup>
): LGraphNode[] => {
if (!graph) return []
const lookup = unref(nodeDefsByName) ?? {}
const lookup = unref(nodeDefsByName)
return collectAllNodes(graph, (node) => isNodeMissingDefinition(node, lookup))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@ import {
collectMissingNodes,
graphHasMissingNodes
} from '@/workbench/extensions/manager/utils/graphHasMissingNodes'
import type { NodeDefLookup } from '@/workbench/extensions/manager/utils/graphHasMissingNodes'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'

type NodeDefs = Record<string, unknown>
type NodeDefs = NodeDefLookup

let nodeIdCounter = 0
const mockNodeDef = {} as ComfyNodeDefImpl

const createGraph = (nodes: LGraphNode[] = []): LGraph => {
return { nodes } as unknown as LGraph
return { nodes } as Partial<LGraph> as LGraph
}

const createSubgraph = (nodes: LGraphNode[]): Subgraph => {
return { nodes } as unknown as Subgraph
return { nodes } as Partial<Subgraph> as Subgraph
}

const createNode = (
type?: string,
subgraphNodes?: LGraphNode[]
): LGraphNode => {
return {
id: Math.random(),
id: nodeIdCounter++,
type,
isSubgraphNode: subgraphNodes ? () => true : undefined,
subgraph: subgraphNodes ? createSubgraph(subgraphNodes) : undefined
Expand All @@ -37,11 +42,19 @@ describe('graphHasMissingNodes', () => {
expect(graphHasMissingNodes(null, {})).toBe(false)
})

it('returns false when graph is undefined', () => {
expect(graphHasMissingNodes(undefined, {})).toBe(false)
})

it('returns false when graph has no nodes', () => {
expect(graphHasMissingNodes(createGraph(), {})).toBe(false)
})

it('returns false when every node has a definition', () => {
const graph = createGraph([createNode('FooNode'), createNode('BarNode')])
const nodeDefs: NodeDefs = {
FooNode: {},
BarNode: {}
FooNode: mockNodeDef,
BarNode: mockNodeDef
}

expect(graphHasMissingNodes(graph, nodeDefs)).toBe(false)
Expand All @@ -53,7 +66,7 @@ describe('graphHasMissingNodes', () => {
createNode('MissingNode')
])
const nodeDefs: NodeDefs = {
FooNode: {}
FooNode: mockNodeDef
}

expect(graphHasMissingNodes(graph, nodeDefs)).toBe(true)
Expand All @@ -64,7 +77,7 @@ describe('graphHasMissingNodes', () => {
createNode('ContainerNode', [createNode('InnerMissing')])
])
const nodeDefs: NodeDefs = {
ContainerNode: {}
ContainerNode: mockNodeDef
}

const missingNodes = collectMissingNodes(graph, nodeDefs)
Expand All @@ -80,4 +93,23 @@ describe('graphHasMissingNodes', () => {

expect(graphHasMissingNodes(graph, {})).toBe(false)
})

it('traverses deeply nested subgraphs', () => {
const deepGraph = createGraph([
createNode('Layer1', [
createNode('Layer2', [
createNode('Layer3', [createNode('MissingDeep')])
])
])
])
const nodeDefs: NodeDefs = {
Layer1: mockNodeDef,
Layer2: mockNodeDef,
Layer3: mockNodeDef
}

const missingNodes = collectMissingNodes(deepGraph, nodeDefs)
expect(missingNodes).toHaveLength(1)
expect(missingNodes[0]?.type).toBe('MissingDeep')
})
})
Loading