|
2 | 2 | * Vue node lifecycle management for LiteGraph integration |
3 | 3 | * Provides event-driven reactivity with performance optimizations |
4 | 4 | */ |
5 | | -import { reactive } from 'vue' |
| 5 | +import { reactiveComputed } from '@vueuse/core' |
| 6 | +import { reactive, shallowReactive } from 'vue' |
6 | 7 |
|
7 | 8 | import { useChainCallback } from '@/composables/functional/useChainCallback' |
8 | 9 | import type { |
9 | 10 | INodeInputSlot, |
10 | 11 | INodeOutputSlot |
11 | 12 | } from '@/lib/litegraph/src/interfaces' |
| 13 | +import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets' |
12 | 14 | import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations' |
13 | 15 | import { LayoutSource } from '@/renderer/core/layout/types' |
14 | 16 | import type { InputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2' |
@@ -132,44 +134,57 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager { |
132 | 134 | }) |
133 | 135 | }) |
134 | 136 |
|
135 | | - const safeWidgets = node.widgets?.map((widget) => { |
136 | | - try { |
137 | | - // TODO: Use widget.getReactiveData() once TypeScript types are updated |
138 | | - let value = widget.value |
139 | | - |
140 | | - // For combo widgets, if value is undefined, use the first option as default |
141 | | - if ( |
142 | | - value === undefined && |
143 | | - widget.type === 'combo' && |
144 | | - widget.options?.values && |
145 | | - Array.isArray(widget.options.values) && |
146 | | - widget.options.values.length > 0 |
147 | | - ) { |
148 | | - value = widget.options.values[0] |
149 | | - } |
150 | | - const spec = nodeDefStore.getInputSpecForWidget(node, widget.name) |
151 | | - const slotInfo = slotMetadata.get(widget.name) |
152 | | - |
153 | | - return { |
154 | | - name: widget.name, |
155 | | - type: widget.type, |
156 | | - value: value, |
157 | | - label: widget.label, |
158 | | - options: widget.options ? { ...widget.options } : undefined, |
159 | | - callback: widget.callback, |
160 | | - spec, |
161 | | - slotMetadata: slotInfo, |
162 | | - isDOMWidget: isDOMWidget(widget) |
163 | | - } |
164 | | - } catch (error) { |
165 | | - return { |
166 | | - name: widget.name || 'unknown', |
167 | | - type: widget.type || 'text', |
168 | | - value: undefined |
169 | | - } |
| 137 | + const reactiveWidgets = shallowReactive<IBaseWidget[]>(node.widgets ?? []) |
| 138 | + Object.defineProperty(node, 'widgets', { |
| 139 | + get() { |
| 140 | + return reactiveWidgets |
| 141 | + }, |
| 142 | + set(v) { |
| 143 | + reactiveWidgets.splice(0, reactiveWidgets.length, ...v) |
170 | 144 | } |
171 | 145 | }) |
172 | 146 |
|
| 147 | + const safeWidgets = reactiveComputed<SafeWidgetData[]>( |
| 148 | + () => |
| 149 | + node.widgets?.map((widget) => { |
| 150 | + try { |
| 151 | + // TODO: Use widget.getReactiveData() once TypeScript types are updated |
| 152 | + let value = widget.value |
| 153 | + |
| 154 | + // For combo widgets, if value is undefined, use the first option as default |
| 155 | + if ( |
| 156 | + value === undefined && |
| 157 | + widget.type === 'combo' && |
| 158 | + widget.options?.values && |
| 159 | + Array.isArray(widget.options.values) && |
| 160 | + widget.options.values.length > 0 |
| 161 | + ) { |
| 162 | + value = widget.options.values[0] |
| 163 | + } |
| 164 | + const spec = nodeDefStore.getInputSpecForWidget(node, widget.name) |
| 165 | + const slotInfo = slotMetadata.get(widget.name) |
| 166 | + |
| 167 | + return { |
| 168 | + name: widget.name, |
| 169 | + type: widget.type, |
| 170 | + value: value, |
| 171 | + label: widget.label, |
| 172 | + options: widget.options ? { ...widget.options } : undefined, |
| 173 | + callback: widget.callback, |
| 174 | + spec, |
| 175 | + slotMetadata: slotInfo, |
| 176 | + isDOMWidget: isDOMWidget(widget) |
| 177 | + } |
| 178 | + } catch (error) { |
| 179 | + return { |
| 180 | + name: widget.name || 'unknown', |
| 181 | + type: widget.type || 'text', |
| 182 | + value: undefined |
| 183 | + } |
| 184 | + } |
| 185 | + }) ?? [] |
| 186 | + ) |
| 187 | + |
173 | 188 | const nodeType = |
174 | 189 | node.type || |
175 | 190 | node.constructor?.comfyClass || |
|
0 commit comments