mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Fix reactivity washing in refreshNodeSlots (#7802)
Creating a copy with spread resulted in a copy which was not reactive. Solves a bug where all widgets on a node in vue mode would cease to be reactive after any connection is made to the node. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7802-Fix-reactivity-washing-in-refreshNodeSlots-2d96d73d3650819e842ff46030bebfa1) by [Unito](https://www.unito.io) --------- Co-authored-by: Alexander Brown <drjkl@comfy.org>
This commit is contained in:
@@ -245,17 +245,10 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
|
||||
})
|
||||
|
||||
// Update only widgets with new slot metadata, keeping other widget data intact
|
||||
const updatedWidgets = currentData.widgets?.map((widget) => {
|
||||
for (const widget of currentData.widgets ?? []) {
|
||||
const slotInfo = slotMetadata.get(widget.name)
|
||||
return slotInfo ? { ...widget, slotMetadata: slotInfo } : widget
|
||||
})
|
||||
|
||||
vueNodeData.set(nodeId, {
|
||||
...currentData,
|
||||
widgets: updatedWidgets,
|
||||
inputs: nodeRef.inputs ? [...nodeRef.inputs] : undefined,
|
||||
outputs: nodeRef.outputs ? [...nodeRef.outputs] : undefined
|
||||
})
|
||||
if (slotInfo) widget.slotMetadata = slotInfo
|
||||
}
|
||||
}
|
||||
|
||||
// Extract safe data from LiteGraph node for Vue consumption
|
||||
|
||||
49
tests-ui/tests/composables/graph/useGraphNodeManager.test.ts
Normal file
49
tests-ui/tests/composables/graph/useGraphNodeManager.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { setActivePinia } from 'pinia'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick, watch } from 'vue'
|
||||
|
||||
import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
|
||||
import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums'
|
||||
|
||||
setActivePinia(createTestingPinia())
|
||||
|
||||
function createTestGraph() {
|
||||
const graph = new LGraph()
|
||||
const node = new LGraphNode('test')
|
||||
node.addInput('input', 'INT')
|
||||
node.addWidget('number', 'testnum', 2, () => undefined, {})
|
||||
graph.add(node)
|
||||
|
||||
const { vueNodeData } = useGraphNodeManager(graph)
|
||||
const onReactivityUpdate = vi.fn()
|
||||
watch(vueNodeData, onReactivityUpdate)
|
||||
|
||||
return [node, graph, onReactivityUpdate] as const
|
||||
}
|
||||
|
||||
describe('Node Reactivity', () => {
|
||||
it('should trigger on callback', async () => {
|
||||
const [node, , onReactivityUpdate] = createTestGraph()
|
||||
|
||||
node.widgets![0].callback!(2)
|
||||
await nextTick()
|
||||
expect(onReactivityUpdate).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should remain reactive after a connection is made', async () => {
|
||||
const [node, graph, onReactivityUpdate] = createTestGraph()
|
||||
|
||||
graph.trigger('node:slot-links:changed', {
|
||||
nodeId: '1',
|
||||
slotType: NodeSlotType.INPUT
|
||||
})
|
||||
await nextTick()
|
||||
onReactivityUpdate.mockClear()
|
||||
|
||||
node.widgets![0].callback!(2)
|
||||
await nextTick()
|
||||
expect(onReactivityUpdate).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user