mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
fix: skip non-serializable source widgets in promoted view serialization
Add sourceSerialize getter to PromotedWidgetView that checks the resolved source widget's serialize flag. SubgraphNode.serialize() and configure now filter out views whose source widget has serialize=false, preventing preview/audio/video widget values from being persisted.
This commit is contained in:
@@ -24,6 +24,8 @@ export interface PromotedWidgetView extends IBaseWidget {
|
||||
* origin.
|
||||
*/
|
||||
readonly disambiguatingSourceNodeId?: string
|
||||
/** Whether the resolved source widget is workflow-persistent. */
|
||||
readonly sourceSerialize: boolean
|
||||
}
|
||||
|
||||
export function isPromotedWidgetView(
|
||||
|
||||
@@ -77,6 +77,15 @@ class PromotedWidgetView implements IPromotedWidgetView {
|
||||
|
||||
readonly serialize = false
|
||||
|
||||
/**
|
||||
* Whether the resolved source widget is workflow-persistent.
|
||||
* Used by SubgraphNode.serialize to skip preview/audio/video widgets
|
||||
* whose source sets serialize = false.
|
||||
*/
|
||||
get sourceSerialize(): boolean {
|
||||
return this.resolveDeepest()?.widget.serialize !== false
|
||||
}
|
||||
|
||||
last_y?: number
|
||||
computedHeight?: number
|
||||
|
||||
|
||||
@@ -132,4 +132,35 @@ describe('SubgraphNode multi-instance widget isolation', () => {
|
||||
expect(restoredWidget?.value).toBe(33)
|
||||
expect(restoredWidget?.serializeValue?.(restoredInstance, 0)).toBe(33)
|
||||
})
|
||||
|
||||
it('skips non-serializable source widgets during serialize', () => {
|
||||
const subgraph = createTestSubgraph({
|
||||
inputs: [{ name: 'value', type: 'number' }]
|
||||
})
|
||||
|
||||
const { node, widget } = createNodeWithWidget('TestNode', 10)
|
||||
subgraph.add(node)
|
||||
subgraph.inputNode.slots[0].connect(node.inputs[0], node)
|
||||
|
||||
// Mark the source widget as non-persistent (e.g. preview widget)
|
||||
widget.serialize = false
|
||||
|
||||
const instance = createTestSubgraphNode(subgraph, { id: 501 })
|
||||
instance.configure({
|
||||
id: 501,
|
||||
type: subgraph.id,
|
||||
pos: [100, 100],
|
||||
size: [200, 100],
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
mode: 0,
|
||||
order: 0,
|
||||
flags: {},
|
||||
properties: { proxyWidgets: [['-1', 'widget']] },
|
||||
widgets_values: []
|
||||
})
|
||||
|
||||
const serialized = instance.serialize()
|
||||
expect(serialized.widgets_values).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1138,15 +1138,16 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
store.promote(this.rootGraph.id, this.id, source)
|
||||
}
|
||||
|
||||
// Restore per-instance promoted widget values from serialized widgets_values.
|
||||
// LGraphNode.configure skips promoted widgets (serialize === false), so they
|
||||
// must be applied here after the promoted views are created.
|
||||
// Hydrate per-instance promoted widget values from serialized data.
|
||||
// LGraphNode.configure skips promoted widgets (serialize === false on
|
||||
// the view), so they must be applied here after promoted views exist.
|
||||
// Only iterate serializable views to match what serialize() wrote.
|
||||
if (this._pendingWidgetsValues) {
|
||||
const views = this._getPromotedViews()
|
||||
let i = 0
|
||||
for (const view of views) {
|
||||
if (!view.sourceSerialize) continue
|
||||
if (i >= this._pendingWidgetsValues.length) break
|
||||
// Use the setter which stores in instance Map AND syncs to inner node
|
||||
view.value = this._pendingWidgetsValues[i++] as typeof view.value
|
||||
}
|
||||
this._pendingWidgetsValues = undefined
|
||||
@@ -1611,8 +1612,9 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph {
|
||||
const serialized = super.serialize()
|
||||
const views = this._getPromotedViews()
|
||||
|
||||
if (views.length > 0) {
|
||||
serialized.widgets_values = views.map((view) => {
|
||||
const serializableViews = views.filter((view) => view.sourceSerialize)
|
||||
if (serializableViews.length > 0) {
|
||||
serialized.widgets_values = serializableViews.map((view) => {
|
||||
const value = view.serializeValue
|
||||
? view.serializeValue(this, -1)
|
||||
: view.value
|
||||
|
||||
Reference in New Issue
Block a user