mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Update Litegraph (TypeScript conversion) (#1145)
* Fix various type errors * Fix rest of ts errors * update litegraph * nit
This commit is contained in:
8
package-lock.json
generated
8
package-lock.json
generated
@@ -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": {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 } : {})
|
||||
})
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
23
src/types/litegraph-augmentation.d.ts
vendored
23
src/types/litegraph-augmentation.d.ts
vendored
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user