Skip to content

Commit b6b3870

Browse files
committed
fix: scope the placeholder size passthrough to expanded nodes with a recorded size
Guard the new `size` passthrough on two cases review surfaced: - `last_serialization` with no `size` (schema v0.4 / partial entries): the unconditional override wrote the LGraphNode constructor default [140, 60] into the saved workflow, a dimension the source file never had, pinning the real node to it once the pack is installed. Reverts the v0.4 snapshot churn along with it. - Collapsed placeholders: Vue nodes mode clears the CSS width/height floors on collapse, so the ResizeObserver -> layoutStore -> useLayoutSync chain writes the collapsed card's measurement back to `node.size`. Since `flags` is still replayed from the file, persisting that would pair `collapsed: false` with collapsed dimensions. Tests now drive geometry through `setPos`/`setSize` (the production mutators `LGraphCanvas` resizing uses) rather than raw field assignment.
1 parent c9f2b96 commit b6b3870

3 files changed

Lines changed: 41 additions & 11 deletions

File tree

src/lib/litegraph/src/LGraphNode.test.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,15 @@ describe('LGraphNode', () => {
101101
})
102102

103103
describe('missing-node placeholder serialization', () => {
104-
function createPlaceholder(): LGraphNode {
104+
function createPlaceholder(
105+
overrides: Partial<ISerialisedNode> = {}
106+
): LGraphNode {
105107
const lastSerialization = getMockISerialisedNode({
106108
type: 'UninstalledNodeType',
107109
pos: [100, 100],
108110
size: [140, 60],
109-
widgets_values: [512]
111+
widgets_values: [512],
112+
...overrides
110113
})
111114
const placeholder = new LGraphNode('')
112115
placeholder.last_serialization = lastSerialization
@@ -117,8 +120,8 @@ describe('LGraphNode', () => {
117120

118121
test('carries the live pos and size through to the replayed serialization', () => {
119122
const placeholder = createPlaceholder()
120-
placeholder.pos = [999, 888]
121-
placeholder.size = [777, 666]
123+
placeholder.setPos(999, 888)
124+
placeholder.setSize([777, 666])
122125

123126
const serialized = placeholder.serialize()
124127

@@ -128,13 +131,33 @@ describe('LGraphNode', () => {
128131

129132
test('still replays the fields it has no definition to regenerate', () => {
130133
const placeholder = createPlaceholder()
131-
placeholder.size = [777, 666]
134+
placeholder.setSize([777, 666])
132135

133136
const serialized = placeholder.serialize()
134137

135138
expect(serialized.type).toEqual('UninstalledNodeType')
136139
expect(serialized.widgets_values).toEqual([512])
137140
})
141+
142+
test('does not invent a size when the recorded serialization has none', () => {
143+
const placeholder = createPlaceholder()
144+
delete (placeholder.last_serialization as Partial<ISerialisedNode>).size
145+
146+
const serialized = placeholder.serialize()
147+
148+
expect(serialized).not.toHaveProperty('size')
149+
})
150+
151+
test('keeps the recorded size while collapsed, since flags are replayed from the file', () => {
152+
const placeholder = createPlaceholder({ flags: { collapsed: false } })
153+
placeholder.flags.collapsed = true
154+
placeholder.setSize([80, 30])
155+
156+
const serialized = placeholder.serialize()
157+
158+
expect(serialized.size).toEqual([140, 60])
159+
expect(serialized.flags).toEqual({ collapsed: false })
160+
})
138161
})
139162

140163
test('should configure inputs correctly', () => {

src/lib/litegraph/src/LGraphNode.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,13 +1060,24 @@ export class LGraphNode
10601060
}
10611061

10621062
// special case for when there were errors
1063-
if (this.constructor === LGraphNode && this.last_serialization)
1063+
if (this.constructor === LGraphNode && this.last_serialization) {
1064+
// Only an expanded placeholder whose file recorded a size has a live
1065+
// size worth keeping. Vue nodes mode drops the CSS width/height floors
1066+
// on collapse, so a collapsed node's size is a measurement of the
1067+
// collapsed card, and `flags` is replayed from the file — keeping both
1068+
// would pair `collapsed: false` with collapsed dimensions. With no
1069+
// recorded size there is no definition to compute a real one from, so
1070+
// keeping the live size would invent a dimension the file never had.
1071+
const carriesLiveSize =
1072+
this.last_serialization.size != null && !this.flags.collapsed
1073+
10641074
return {
10651075
...this.last_serialization,
10661076
mode: o.mode,
10671077
pos: o.pos,
1068-
size: o.size
1078+
...(carriesLiveSize && { size: o.size })
10691079
}
1080+
}
10701081

10711082
if (this.inputs)
10721083
o.inputs = this.inputs.map((input) => inputAsSerialisable(input))

src/lib/litegraph/src/__snapshots__/LGraph.test.ts.snap

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ exports[`LGraph > supports schema v0.4 graphs > oldSchemaGraph 1`] = `
3434
10,
3535
10,
3636
],
37-
"size": [
38-
140,
39-
60,
40-
],
4137
},
4238
],
4339
"revision": 0,

0 commit comments

Comments
 (0)