fix: sync DOM widget default values to widgetValueStore on registration (#9164)

## Description

DOM widgets (textarea/customtext) override the `value` getter via
`Object.defineProperty` to use `getValue()/setValue()` with a fallback
to `inputEl.value`. But `BaseWidget.setNodeId()` registered
`_state.value` (undefined from constructor) instead of `this.value` (the
actual getter).

This caused Vue nodes (Nodes 2.0) to read `undefined` from the store and
display empty textareas, while execution correctly fell back to
`inputEl.value`.

**Fix:** Use `this.value` in `setNodeId()` so the store is initialized
with the actual widget value.

**Impact:** Fixes Nano Banana / Nano Banana Pro `system_prompt` showing
empty in Nodes 2.0 while still sending the correct value during
execution.

## Thread

https://ampcode.com/threads/T-019c8e99-49ce-77f5-bf2a-a32320fac477

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9164-fix-sync-DOM-widget-default-values-to-widgetValueStore-on-registration-3116d73d36508169a2fbd8308d9eec91)
by [Unito](https://www.unito.io)
This commit is contained in:
Hunter
2026-02-26 00:35:59 -05:00
committed by GitHub
parent 5cfd1aa77e
commit 9ff985a792
2 changed files with 33 additions and 0 deletions

View File

@@ -162,6 +162,38 @@ describe('BaseWidget store integration', () => {
})
})
describe('DOM widget value registration', () => {
it('registers value from getter when value property is overridden', () => {
const defaultValue = 'You are an expert image-generation engine.'
const widget = createTestWidget(node, {
name: 'system_prompt',
value: undefined as unknown as number
})
// Simulate what addDOMWidget does: override value with getter/setter
// that falls back to a default (like inputEl.value for textarea widgets)
Object.defineProperty(widget, 'value', {
get() {
const graphId = widget.node.graph?.rootGraph.id
if (!graphId) return defaultValue
const state = store.getWidget(graphId, node.id, 'system_prompt')
return (state?.value as string) ?? defaultValue
},
set(v: string) {
const graphId = widget.node.graph?.rootGraph.id
if (!graphId) return
const state = store.getWidget(graphId, node.id, 'system_prompt')
if (state) state.value = v
}
})
widget.setNodeId(node.id)
const state = store.getWidget(graph.id, node.id, 'system_prompt')
expect(state?.value).toBe(defaultValue)
})
})
describe('fallback behavior', () => {
it('uses internal value before registration', () => {
const widget = createTestWidget(node, {

View File

@@ -140,6 +140,7 @@ export abstract class BaseWidget<TWidget extends IBaseWidget = IBaseWidget>
this._state = useWidgetValueStore().registerWidget(graphId, {
...this._state,
value: this.value,
nodeId
})
}