mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
Remove redundant state from Widget store.
This commit is contained in:
@@ -38,10 +38,12 @@ describe('Node Reactivity', () => {
|
||||
expect((widget as any)._nodeId).toBe(node.id)
|
||||
|
||||
// Initial value should be in store after setNodeId was called
|
||||
expect(store.get(node.id, 'testnum')).toBe(2)
|
||||
expect(store.getWidget(node.id, 'testnum')?.value).toBe(2)
|
||||
|
||||
const onValueChange = vi.fn()
|
||||
const widgetValue = computed(() => store.get(node.id, 'testnum'))
|
||||
const widgetValue = computed(
|
||||
() => store.getWidget(node.id, 'testnum')?.value
|
||||
)
|
||||
watch(widgetValue, onValueChange)
|
||||
|
||||
widget.value = 42
|
||||
@@ -62,7 +64,9 @@ describe('Node Reactivity', () => {
|
||||
})
|
||||
await nextTick()
|
||||
|
||||
const widgetValue = computed(() => store.get(node.id, 'testnum'))
|
||||
const widgetValue = computed(
|
||||
() => store.getWidget(node.id, 'testnum')?.value
|
||||
)
|
||||
watch(widgetValue, onValueChange)
|
||||
|
||||
node.widgets![0].value = 99
|
||||
|
||||
@@ -240,15 +240,6 @@ export function extractVueNodeData(node: LGraphNode): VueNodeData {
|
||||
// Extract safe widget data
|
||||
const slotMetadata = new Map<string, WidgetSlotMetadata>()
|
||||
|
||||
const reactiveWidgets = shallowReactive<IBaseWidget[]>(node.widgets ?? [])
|
||||
Object.defineProperty(node, 'widgets', {
|
||||
get() {
|
||||
return reactiveWidgets
|
||||
},
|
||||
set(v) {
|
||||
reactiveWidgets.splice(0, reactiveWidgets.length, ...v)
|
||||
}
|
||||
})
|
||||
const reactiveInputs = shallowReactive<INodeInputSlot[]>(node.inputs ?? [])
|
||||
Object.defineProperty(node, 'inputs', {
|
||||
get() {
|
||||
|
||||
@@ -54,7 +54,6 @@ describe('useWidget', () => {
|
||||
expect(value.value).toBe(42)
|
||||
|
||||
value.value = 100
|
||||
expect(store.get(1, 'test_widget')).toBe(100)
|
||||
expect(store.getWidget(1, 'test_widget')?.value).toBe(100)
|
||||
})
|
||||
|
||||
@@ -95,7 +94,7 @@ describe('useWidget', () => {
|
||||
expect(value.value).toBe(false)
|
||||
expect(isHidden.value).toBe(false)
|
||||
|
||||
store.set(1, 'test_widget', true)
|
||||
store.getWidget(1, 'test_widget')!.value = true
|
||||
expect(value.value).toBe(true)
|
||||
|
||||
store.setHidden(1, 'test_widget', true)
|
||||
|
||||
@@ -27,7 +27,9 @@ export function useWidget(
|
||||
|
||||
const value = computed({
|
||||
get: () => widget.value?.value,
|
||||
set: (v: unknown) => store.set(toValue(nodeId), toValue(widgetName), v)
|
||||
set: (v: unknown) => {
|
||||
if (widget.value) widget.value.value = v
|
||||
}
|
||||
})
|
||||
|
||||
const isHidden = computed(() => widget.value?.hidden ?? false)
|
||||
|
||||
@@ -111,9 +111,10 @@ describe('BaseWidget store integration', () => {
|
||||
widget.setNodeId(1)
|
||||
|
||||
widget.value = 99
|
||||
expect(store.get(1, 'valueWidget')).toBe(99)
|
||||
expect(store.getWidget(1, 'valueWidget')?.value).toBe(99)
|
||||
|
||||
store.set(1, 'valueWidget', 55)
|
||||
const state = store.getWidget(1, 'valueWidget')!
|
||||
state.value = 55
|
||||
expect(widget.value).toBe(55)
|
||||
})
|
||||
})
|
||||
@@ -158,11 +159,11 @@ describe('BaseWidget store integration', () => {
|
||||
expect(state?.label).toBeUndefined()
|
||||
})
|
||||
|
||||
it('registers widget value in values map', () => {
|
||||
it('registers widget value accessible via getWidget', () => {
|
||||
const widget = createTestWidget(node, { name: 'valuesWidget', value: 77 })
|
||||
widget.setNodeId(1)
|
||||
|
||||
expect(store.get(1, 'valuesWidget')).toBe(77)
|
||||
expect(store.getWidget(1, 'valuesWidget')?.value).toBe(77)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ export abstract class BaseWidget<
|
||||
get value(): TWidget['value'] {
|
||||
if (this._nodeId !== undefined) {
|
||||
const store = useWidgetValueStore()
|
||||
const storeValue = store.get(this._nodeId, this.name)
|
||||
const storeValue = store.getWidget(this._nodeId, this.name)?.value
|
||||
if (storeValue !== undefined) {
|
||||
return storeValue as TWidget['value']
|
||||
}
|
||||
@@ -196,7 +196,8 @@ export abstract class BaseWidget<
|
||||
this._internalValue = value
|
||||
if (this._nodeId !== undefined) {
|
||||
const store = useWidgetValueStore()
|
||||
store.set(this._nodeId, this.name, value)
|
||||
const state = store.getWidget(this._nodeId, this.name)
|
||||
if (state) state.value = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ const nodeBadges = computed<NodeBadgeProps[]>(() => {
|
||||
if (relevantNames.length > 0 && nodeData?.id != null) {
|
||||
for (const name of relevantNames) {
|
||||
// Access value from store to create reactive dependency
|
||||
void widgetStore.get(nodeData.id, name)
|
||||
void widgetStore.getWidget(nodeData.id, name)?.value
|
||||
}
|
||||
}
|
||||
// Access input connections for regular inputs
|
||||
|
||||
@@ -178,7 +178,7 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
const widgetState = widgetValueStore.getWidget(nodeId, widget.name)
|
||||
|
||||
// Get value from store (falls back to undefined if not registered)
|
||||
const value = widgetValueStore.get(nodeId, widget.name) as WidgetValue
|
||||
const value = widgetState?.value as WidgetValue
|
||||
|
||||
// Build options from store state, with slot-linked override for disabled
|
||||
const storeOptions = widgetState?.options ?? {}
|
||||
@@ -208,7 +208,7 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
|
||||
function updateHandler(newValue: WidgetValue) {
|
||||
// Update value in store
|
||||
widgetValueStore.set(nodeId, widget.name, newValue)
|
||||
if (widgetState) widgetState.value = newValue
|
||||
// Invoke LiteGraph callback wrapper (handles triggerDraw, etc.)
|
||||
widget.callback?.(newValue)
|
||||
}
|
||||
|
||||
@@ -9,56 +9,32 @@ describe('useWidgetValueStore', () => {
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
})
|
||||
|
||||
describe('value management (legacy API)', () => {
|
||||
it('stores and retrieves values', () => {
|
||||
describe('widgetState.value access', () => {
|
||||
it('getWidget returns undefined for unregistered widget', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'seed', 12345)
|
||||
expect(store.get('node-1', 'seed')).toBe(12345)
|
||||
expect(store.getWidget('missing', 'widget')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('returns undefined for missing values', () => {
|
||||
it('widgetState.value can be read and written directly', () => {
|
||||
const store = useWidgetValueStore()
|
||||
expect(store.get('missing', 'widget')).toBeUndefined()
|
||||
})
|
||||
const state = store.registerWidget('node-1', 'seed', 'number', 100)
|
||||
expect(state.value).toBe(100)
|
||||
|
||||
it('removes single widget value', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'seed', 100)
|
||||
store.remove('node-1', 'seed')
|
||||
expect(store.get('node-1', 'seed')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('removes all widgets for a node', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'seed', 1)
|
||||
store.set('node-1', 'steps', 20)
|
||||
store.set('node-2', 'seed', 2)
|
||||
|
||||
store.removeNode('node-1')
|
||||
|
||||
expect(store.get('node-1', 'seed')).toBeUndefined()
|
||||
expect(store.get('node-1', 'steps')).toBeUndefined()
|
||||
expect(store.get('node-2', 'seed')).toBe(2)
|
||||
})
|
||||
|
||||
it('overwrites existing values', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'seed', 100)
|
||||
store.set('node-1', 'seed', 200)
|
||||
expect(store.get('node-1', 'seed')).toBe(200)
|
||||
state.value = 200
|
||||
expect(store.getWidget('node-1', 'seed')?.value).toBe(200)
|
||||
})
|
||||
|
||||
it('stores different value types', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'text', 'hello')
|
||||
store.set('node-1', 'number', 42)
|
||||
store.set('node-1', 'boolean', true)
|
||||
store.set('node-1', 'array', [1, 2, 3])
|
||||
store.registerWidget('node-1', 'text', 'string', 'hello')
|
||||
store.registerWidget('node-1', 'number', 'number', 42)
|
||||
store.registerWidget('node-1', 'boolean', 'toggle', true)
|
||||
store.registerWidget('node-1', 'array', 'combo', [1, 2, 3])
|
||||
|
||||
expect(store.get('node-1', 'text')).toBe('hello')
|
||||
expect(store.get('node-1', 'number')).toBe(42)
|
||||
expect(store.get('node-1', 'boolean')).toBe(true)
|
||||
expect(store.get('node-1', 'array')).toEqual([1, 2, 3])
|
||||
expect(store.getWidget('node-1', 'text')?.value).toBe('hello')
|
||||
expect(store.getWidget('node-1', 'number')?.value).toBe(42)
|
||||
expect(store.getWidget('node-1', 'boolean')?.value).toBe(true)
|
||||
expect(store.getWidget('node-1', 'array')?.value).toEqual([1, 2, 3])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -100,12 +76,6 @@ describe('useWidgetValueStore', () => {
|
||||
expect(state.options).toEqual({ multiline: true })
|
||||
})
|
||||
|
||||
it('also sets the value in the values map', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.registerWidget('node-1', 'seed', 'number', 42)
|
||||
expect(store.get('node-1', 'seed')).toBe(42)
|
||||
})
|
||||
|
||||
it('unregisters a widget', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.registerWidget('node-1', 'seed', 'number', 100)
|
||||
@@ -113,7 +83,6 @@ describe('useWidgetValueStore', () => {
|
||||
store.unregisterWidget('node-1', 'seed')
|
||||
|
||||
expect(store.getWidget('node-1', 'seed')).toBeUndefined()
|
||||
expect(store.get('node-1', 'seed')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('unregisters all widgets for a node', () => {
|
||||
@@ -126,9 +95,7 @@ describe('useWidgetValueStore', () => {
|
||||
|
||||
expect(store.getWidget('node-1', 'seed')).toBeUndefined()
|
||||
expect(store.getWidget('node-1', 'steps')).toBeUndefined()
|
||||
expect(store.getWidget('node-2', 'seed')).toBeDefined()
|
||||
expect(store.get('node-1', 'seed')).toBeUndefined()
|
||||
expect(store.get('node-2', 'seed')).toBe(2)
|
||||
expect(store.getWidget('node-2', 'seed')?.value).toBe(2)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -247,22 +214,4 @@ describe('useWidgetValueStore', () => {
|
||||
expect(() => store.setLabel('missing', 'widget', 'test')).not.toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('value sync between APIs', () => {
|
||||
it('set() updates registered widget state value', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.registerWidget('node-1', 'seed', 'number', 100)
|
||||
|
||||
store.set('node-1', 'seed', 200)
|
||||
|
||||
expect(store.get('node-1', 'seed')).toBe(200)
|
||||
expect(store.getWidget('node-1', 'seed')?.value).toBe(200)
|
||||
})
|
||||
|
||||
it('set() works for unregistered widgets', () => {
|
||||
const store = useWidgetValueStore()
|
||||
store.set('node-1', 'seed', 100)
|
||||
expect(store.get('node-1', 'seed')).toBe(100)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -24,39 +24,12 @@ export interface WidgetState {
|
||||
}
|
||||
|
||||
export const useWidgetValueStore = defineStore('widgetValue', () => {
|
||||
const values = ref(new Map<WidgetKey, unknown>())
|
||||
const widgetStates = ref(new Map<WidgetKey, WidgetState>())
|
||||
|
||||
function makeKey(nodeId: NodeId, widgetName: string): WidgetKey {
|
||||
return `${nodeId}:${widgetName}`
|
||||
}
|
||||
|
||||
function get(nodeId: NodeId, widgetName: string): unknown {
|
||||
return values.value.get(makeKey(nodeId, widgetName))
|
||||
}
|
||||
|
||||
function set(nodeId: NodeId, widgetName: string, value: unknown): void {
|
||||
const key = makeKey(nodeId, widgetName)
|
||||
values.value.set(key, value)
|
||||
const state = widgetStates.value.get(key)
|
||||
if (state) {
|
||||
state.value = value
|
||||
}
|
||||
}
|
||||
|
||||
function remove(nodeId: NodeId, widgetName: string): void {
|
||||
values.value.delete(makeKey(nodeId, widgetName))
|
||||
}
|
||||
|
||||
function removeNode(nodeId: NodeId): void {
|
||||
const prefix = `${nodeId}:`
|
||||
for (const key of values.value.keys()) {
|
||||
if (key.startsWith(prefix)) {
|
||||
values.value.delete(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerWidget(
|
||||
nodeId: NodeId,
|
||||
name: string,
|
||||
@@ -84,14 +57,11 @@ export const useWidgetValueStore = defineStore('widgetValue', () => {
|
||||
serialize: options.serialize ?? true
|
||||
}
|
||||
widgetStates.value.set(key, state)
|
||||
values.value.set(key, value)
|
||||
return state
|
||||
}
|
||||
|
||||
function unregisterWidget(nodeId: NodeId, widgetName: string): void {
|
||||
const key = makeKey(nodeId, widgetName)
|
||||
widgetStates.value.delete(key)
|
||||
values.value.delete(key)
|
||||
widgetStates.value.delete(makeKey(nodeId, widgetName))
|
||||
}
|
||||
|
||||
function unregisterNode(nodeId: NodeId): void {
|
||||
@@ -101,7 +71,6 @@ export const useWidgetValueStore = defineStore('widgetValue', () => {
|
||||
widgetStates.value.delete(key)
|
||||
}
|
||||
}
|
||||
removeNode(nodeId)
|
||||
}
|
||||
|
||||
function getWidget(
|
||||
@@ -190,12 +159,7 @@ export const useWidgetValueStore = defineStore('widgetValue', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
values,
|
||||
widgetStates,
|
||||
get,
|
||||
set,
|
||||
remove,
|
||||
removeNode,
|
||||
registerWidget,
|
||||
unregisterWidget,
|
||||
unregisterNode,
|
||||
|
||||
Reference in New Issue
Block a user