mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-09 23:20:04 +00:00
fix: Prune invalid builder mappings on load (#9376)
## Summary - extract resolveNode to reusable util - remove mid builder pruning - handle missing widgets with label ## Review Focus `resolveNode` was simplified for subgraphs by calling getNodeById on each of the subgraphs instead of searching their inner nodes manually. ## Screenshots (if applicable) "Widget not visible" <img width="657" height="822" alt="image" src="https://github.com/user-attachments/assets/ab7d1e87-3210-4e54-876a-07881974b5c7" /> <img width="674" height="375" alt="image" src="https://github.com/user-attachments/assets/c50ec871-d423-43d6-8e1e-7b1a362f621c" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9376-fix-Prune-invalid-builder-mappings-on-load-3196d73d3650811280c2d459ed0271af) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -15,15 +15,21 @@ import {
|
||||
createNode,
|
||||
isAnimatedOutput,
|
||||
isVideoOutput,
|
||||
migrateWidgetsValues
|
||||
migrateWidgetsValues,
|
||||
resolveNode
|
||||
} from '@/utils/litegraphUtil'
|
||||
|
||||
vi.mock('@/lib/litegraph/src/litegraph', () => ({
|
||||
vi.mock('@/lib/litegraph/src/litegraph', async (importOriginal) => ({
|
||||
...(await importOriginal()),
|
||||
LiteGraph: {
|
||||
createNode: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/scripts/app', () => ({
|
||||
app: { rootGraph: null }
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/updates/common/toastStore', () => ({
|
||||
useToastStore: vi.fn(() => ({
|
||||
addAlert: vi.fn(),
|
||||
@@ -384,3 +390,53 @@ describe('compressWidgetInputSlots', () => {
|
||||
expect(graph.links).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveNode', () => {
|
||||
function mockGraph(
|
||||
nodeList: Partial<LGraphNode>[],
|
||||
subgraphs?: Map<string, LGraph>
|
||||
) {
|
||||
const nodesById: Record<string, LGraphNode> = {}
|
||||
for (const n of nodeList) {
|
||||
nodesById[String(n.id)] = n as LGraphNode
|
||||
}
|
||||
return {
|
||||
nodes: nodeList as LGraphNode[],
|
||||
getNodeById(id: unknown) {
|
||||
return id != null ? (nodesById[String(id)] ?? null) : null
|
||||
},
|
||||
subgraphs: subgraphs ?? new Map()
|
||||
} as unknown as LGraph
|
||||
}
|
||||
|
||||
it('returns undefined when graph is nullish', () => {
|
||||
expect(resolveNode(1, null)).toBeUndefined()
|
||||
expect(resolveNode(1, undefined)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('finds a node in the main graph', () => {
|
||||
const node = { id: 5 } as LGraphNode
|
||||
const graph = mockGraph([node])
|
||||
expect(resolveNode(5, graph)).toBe(node)
|
||||
})
|
||||
|
||||
it('finds a node in a subgraph', () => {
|
||||
const subNode = { id: 10 } as LGraphNode
|
||||
const subgraph = mockGraph([subNode])
|
||||
const graph = mockGraph([], new Map([['sg-1', subgraph]]))
|
||||
expect(resolveNode(10, graph)).toBe(subNode)
|
||||
})
|
||||
|
||||
it('returns undefined when node is not found anywhere', () => {
|
||||
const graph = mockGraph([{ id: 1 } as LGraphNode])
|
||||
expect(resolveNode(999, graph)).toBeUndefined()
|
||||
})
|
||||
|
||||
it('prefers main graph over subgraph', () => {
|
||||
const mainNode = { id: 1, title: 'main' } as LGraphNode
|
||||
const subNode = { id: 1, title: 'sub' } as LGraphNode
|
||||
const subgraph = mockGraph([subNode])
|
||||
const graph = mockGraph([mainNode], new Map([['sg-1', subgraph]]))
|
||||
expect(resolveNode(1, graph)).toBe(mainNode)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user