Update Litegraph (TypeScript conversion) (#1145)

* Fix various type errors

* Fix rest of ts errors

* update litegraph

* nit
This commit is contained in:
Chenlei Hu
2024-10-07 11:31:54 -04:00
committed by GitHub
parent 9cbfc9856b
commit dee1ec1a2a
15 changed files with 36 additions and 69 deletions

8
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.3.10",
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
"@comfyorg/litegraph": "^0.7.84",
"@comfyorg/litegraph": "^0.8.0",
"@primevue/themes": "^4.0.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vueuse/core": "^11.0.0",
@@ -1911,9 +1911,9 @@
"dev": true
},
"node_modules/@comfyorg/litegraph": {
"version": "0.7.84",
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.7.84.tgz",
"integrity": "sha512-gataCzqlLsfw0G7VoJpaMrbBOY18pQ8nQGMOm0CJhiZy7Pp+IGTPhVi0d+tvBwW08ILkfYVqevxXs+rrwyzzAg==",
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.8.0.tgz",
"integrity": "sha512-VUER05ldXpi+lcLidK3/tTOfw8c60dnSr2TxVwGULM/b0Zc34m8MoQhxmFcWka8wRplrsU0YqOxT8kfHB8zyMA==",
"license": "MIT"
},
"node_modules/@cspotcode/source-map-support": {

View File

@@ -64,7 +64,7 @@
},
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
"@comfyorg/litegraph": "^0.7.84",
"@comfyorg/litegraph": "^0.8.0",
"@primevue/themes": "^4.0.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vueuse/core": "^11.0.0",

View File

@@ -667,7 +667,6 @@ app.registerExtension({
// Sets the colors of node slots and links
if (colorPalette.colors.node_slot) {
Object.assign(
// @ts-expect-error
app.canvas.default_connection_color_byType,
colorPalette.colors.node_slot
)

View File

@@ -28,7 +28,6 @@ const ext = {
// We must request an animation frame for the current node of the active canvas to update.
requestAnimationFrame(() => {
// @ts-expect-error
const currentNode = LGraphCanvas.active_canvas.current_node
const clickedComboValue = currentNode.widgets
?.filter(

View File

@@ -98,6 +98,7 @@ class GroupNodeBuilder {
const nodesInOrder = app.graph.computeExecutionOrder(false)
this.nodes = this.nodes
.map((node) => ({ index: nodesInOrder.indexOf(node), node }))
// @ts-expect-error id might be string
.sort((a, b) => a.index - b.index || a.node.id - b.node.id)
.map(({ node }) => node)
}
@@ -801,7 +802,6 @@ export class GroupNodeHandler {
this.groupData.nodeData.nodes.map((n, i) => {
const innerNode = LiteGraph.createNode(n.type)
innerNode.configure(n)
// @ts-expect-error
innerNode.id = `${this.node.id}:${i}`
return innerNode
})

View File

@@ -1,3 +1,4 @@
import type { IContextMenuValue } from '@comfyorg/litegraph'
import { app } from '../../scripts/app'
import { mergeIfValid, getWidgetConfig, setWidgetConfig } from './widgetInputs'
import { LiteGraph, LGraphCanvas, LGraphNode } from '@comfyorg/litegraph'
@@ -32,12 +33,7 @@ app.registerExtension({
})
}
this.onConnectionsChange = function (
type,
index,
connected,
link_info
) {
this.onConnectionsChange = (type, index, connected, link_info) => {
this.applyOrientation()
// Prevent multiple connections to different types when we have no input
@@ -63,7 +59,7 @@ app.registerExtension({
}
// Find root input
let currentNode = this
let currentNode: LGraphNode | null = this
let updateNodes = []
let inputType = null
let inputNode = null
@@ -98,7 +94,7 @@ app.registerExtension({
}
// Find all outputs
const nodes = [this]
const nodes: LGraphNode[] = [this]
let outputType = null
while (nodes.length) {
currentNode = nodes.pop()
@@ -177,7 +173,7 @@ app.registerExtension({
}
if (!targetWidget) {
targetWidget = targetNode.widgets?.find(
(w) => w.name === targetInput.widget.name
(w) => w.name === (targetInput.widget as any).name
)
}
@@ -227,7 +223,7 @@ app.registerExtension({
this.isVirtualNode = true
}
getExtraMenuOptions(_, options) {
getExtraMenuOptions(_, options): IContextMenuValue[] {
options.unshift(
{
content:
@@ -268,6 +264,7 @@ app.registerExtension({
}
}
)
return []
}
applyOrientation() {
this.horizontal = this.properties.horizontal

View File

@@ -80,7 +80,6 @@ app.registerExtension({
let w, h
if (node.flags.collapsed) {
// @ts-expect-error
w = node._collapsed_width
h = LiteGraph.NODE_TITLE_HEIGHT
shiftY -= LiteGraph.NODE_TITLE_HEIGHT
@@ -161,7 +160,7 @@ app.registerExtension({
const s = ctx.strokeStyle
ctx.fillStyle = 'rgba(100, 100, 100, 0.33)'
ctx.strokeStyle = 'rgba(100, 100, 100, 0.66)'
ctx.rect(x, y, ...selectedAndMovingGroup.size)
ctx.rect(x, y, ...(selectedAndMovingGroup.size as [number, number]))
ctx.fill()
ctx.stroke()
ctx.fillStyle = f

View File

@@ -158,7 +158,7 @@ app.registerExtension({
const onAudioWidgetUpdate = () => {
audioUIWidget.element.src = api.apiURL(
getResourceURL(...splitFilePath(audioWidget.value))
getResourceURL(...splitFilePath(audioWidget.value as string))
)
}
// Initially load default audio file to audioUIWidget.

View File

@@ -60,7 +60,7 @@ class PrimitiveNode extends LGraphNode {
]
let v = this.widgets?.[0].value
if (v && this.properties[replacePropertyName]) {
v = applyTextReplacements(app, v)
v = applyTextReplacements(app, v as string)
}
// For each output link copy our value over the original widget value
@@ -97,7 +97,7 @@ class PrimitiveNode extends LGraphNode {
if (widget?.type === 'combo') {
widget.options.values = this.outputs[0].widget[GET_CONFIG]()[0]
if (!widget.options.values.includes(widget.value)) {
if (!widget.options.values.includes(widget.value as string)) {
widget.value = widget.options.values[0]
;(widget.callback as Function)(widget.value)
}
@@ -115,6 +115,7 @@ class PrimitiveNode extends LGraphNode {
for (let i = 0; i < this.widgets_values.length; i++) {
const w = this.widgets[i]
if (w) {
// @ts-expect-error change widget type from string to unknown
w.value = this.widgets_values[i]
}
}
@@ -247,6 +248,7 @@ class PrimitiveNode extends LGraphNode {
)
let filter = this.widgets_values?.[2]
if (filter && this.widgets.length === 3) {
// @ts-expect-error change widget type from string to unknown
this.widgets[2].value = filter
}
}
@@ -489,9 +491,7 @@ export function convertToInput(
const sz = node.size
const inputIsOptional = !!widget.options?.inputIsOptional
const input = node.addInput(widget.name, type, {
// @ts-expect-error GET_CONFIG is not defined in LiteGraph
widget: { name: widget.name, [GET_CONFIG]: () => config },
// @ts-expect-error LiteGraph.SlotShape is not typed.
...(inputIsOptional ? { shape: LiteGraph.SlotShape.HollowCircle } : {})
})

View File

@@ -1110,6 +1110,7 @@ export class ComfyApp {
// No image node selected: add a new one
if (!imageNode) {
const newNode = LiteGraph.createNode('LoadImage')
// @ts-expect-error array to Float32Array
newNode.pos = [...this.canvas.graph_mouse]
imageNode = this.graph.add(newNode)
this.graph.change()
@@ -1212,9 +1213,7 @@ export class ComfyApp {
// Move group by header
if (
LiteGraph.isInsideRectangle(
// @ts-expect-error
e.canvasX,
// @ts-expect-error
e.canvasY,
this.selected_group.pos[0],
this.selected_group.pos[1],
@@ -1574,7 +1573,6 @@ export class ComfyApp {
// ComfyUI's custom node mode enum value 4 => bypass/never.
let bgColor: string
// @ts-expect-error
if (node.mode === 4) {
// never
bgColor = app.bypassBgColor
@@ -1754,9 +1752,7 @@ export class ComfyApp {
#addAfterConfigureHandler() {
const app = this
// @ts-expect-error
const onConfigure = app.graph.onConfigure
// @ts-expect-error
app.graph.onConfigure = function () {
// Fire callbacks before the onConfigure, this is used by widget inputs to setup the config
for (const node of app.graph.nodes) {
@@ -2098,8 +2094,7 @@ export class ComfyApp {
// Node connection inputs
const inputOptions = inputIsRequired
? {}
: // @ts-expect-error LiteGraph.SlotShape is not typed.
{ shape: LiteGraph.SlotShape.HollowCircle }
: { shape: LiteGraph.SlotShape.HollowCircle }
this.addInput(inputName, type, inputOptions)
widgetCreated = false
}
@@ -2437,7 +2432,10 @@ export class ComfyApp {
for (let widget of node.widgets) {
if (node.type == 'KSampler' || node.type == 'KSamplerAdvanced') {
if (widget.name == 'sampler_name') {
if (widget.value.startsWith('sample_')) {
if (
typeof widget.value === 'string' &&
widget.value.startsWith('sample_')
) {
widget.value = widget.value.slice(7)
}
}
@@ -2449,8 +2447,10 @@ export class ComfyApp {
) {
if (widget.name == 'control_after_generate') {
if (widget.value === true) {
// @ts-expect-error change widget type from boolean to string
widget.value = 'randomize'
} else if (widget.value === false) {
// @ts-expect-error change widget type from boolean to string
widget.value = 'fixed'
}
}
@@ -2458,7 +2458,7 @@ export class ComfyApp {
if (reset_invalid_values) {
if (widget.type == 'combo') {
if (
!widget.options.values.includes(widget.value) &&
!widget.options.values.includes(widget.value as string) &&
widget.options.values.length > 0
) {
widget.value = widget.options.values[0]
@@ -2499,8 +2499,8 @@ export class ComfyApp {
}
}
const innerNodes = outerNode.getInnerNodes
? outerNode.getInnerNodes()
const innerNodes = outerNode['getInnerNodes']
? outerNode['getInnerNodes']()
: [outerNode]
for (const node of innerNodes) {
if (node.isVirtualNode) {
@@ -2520,8 +2520,8 @@ export class ComfyApp {
for (const outerNode of graph.computeExecutionOrder(false)) {
const skipNode = outerNode.mode === 2 || outerNode.mode === 4
const innerNodes =
!skipNode && outerNode.getInnerNodes
? outerNode.getInnerNodes()
!skipNode && outerNode['getInnerNodes']
? outerNode['getInnerNodes']()
: [outerNode]
for (const node of innerNodes) {
if (node.isVirtualNode) {
@@ -2868,7 +2868,6 @@ export class ComfyApp {
for (const id of ids) {
const data = apiData[id]
const node = LiteGraph.createNode(data.class_type)
// @ts-expect-error
node.id = isNaN(+id) ? id : +id
node.title = data._meta?.title ?? node.title
app.graph.add(node)
@@ -2901,7 +2900,6 @@ export class ComfyApp {
const widget = node.widgets?.find((w) => w.name === input)
if (widget) {
widget.value = value
// @ts-expect-error
widget.callback?.(value)
}
}
@@ -2936,7 +2934,6 @@ export class ComfyApp {
const widget = node.widgets?.find((w) => w.name === input)
if (widget) {
widget.value = value
// @ts-expect-error
widget.callback?.(value)
}
}

View File

@@ -32,7 +32,7 @@ export class ChangeTracker {
store() {
this.ds = {
scale: this.app.canvas.ds.scale,
offset: [...this.app.canvas.ds.offset]
offset: [this.app.canvas.ds.offset[0], this.app.canvas.ds.offset[1]]
}
}

View File

@@ -329,7 +329,6 @@ export class ComfyWorkflow {
const old = localStorage.getItem('litegrapheditor_clipboard')
const graph = new LGraph(data)
const canvas = new LGraphCanvas(null, graph, {
// @ts-expect-error
skip_events: true,
skip_render: true
})

View File

@@ -42,29 +42,6 @@ declare module '@comfyorg/litegraph' {
): DOMWidget
}
interface IWidget<TValue = any, TOptions = any> {
type?: string
/**
* Allows for additional cleanup when removing a widget when converting to input.
*/
onRemove?(): void
serializeValue?(node?: LGraphNode, i?: string)
beforeQueued?(): void
/**
* DOM element used for the widget
*/
element?: HTMLElement
tooltip?: string
origType?: IWidget['type']
origComputeSize?: IWidget['computeSize']
origSerializeValue?: IWidget['serializeValue']
}
interface INodeSlot {
widget?: unknown & { name?: string }
}

View File

@@ -6,6 +6,7 @@ import type {
INodeOutputSlot,
INodeSlot
} from '@comfyorg/litegraph'
import type { ISlotType } from '@comfyorg/litegraph'
import { LiteGraph } from '@comfyorg/litegraph'
export class ConnectingLinkImpl implements ConnectingLink {
@@ -39,7 +40,7 @@ export class ConnectingLinkImpl implements ConnectingLink {
)
}
get type(): string | null {
get type(): ISlotType | null {
const result = this.input ? this.input.type : this.output.type
return result === -1 ? null : result
}

View File

@@ -18,7 +18,7 @@ function createGraph(...nodes: LGraphNode[]) {
class DummyNode extends LGraphNode {
constructor() {
super()
super('dummy')
}
}
@@ -31,7 +31,6 @@ describe('LGraph', () => {
const result1 = graph.serialize({ sortNodes: true })
expect(result1.nodes).not.toHaveLength(0)
// @ts-expect-error Access private property.
graph._nodes = swapNodes(graph.nodes)
const result2 = graph.serialize({ sortNodes: true })