diff --git a/__init__.py b/__init__.py index 1a50faf..21e5602 100644 --- a/__init__.py +++ b/__init__.py @@ -8,19 +8,22 @@ ### import os -# todo: don't override this if the user has that setup already -os.environ["TF_FORCE_GPU_ALLOW_GROWTH"] = "true" -os.environ["TF_GPU_ALLOCATOR"] = "cuda_malloc_async" +# TODO: don't override this if the user has that setup already +if not os.environ.get("TF_FORCE_GPU_ALLOW_GROWTH"): + os.environ["TF_FORCE_GPU_ALLOW_GROWTH"] = "true" + +if not os.environ.get("TF_GPU_ALLOCATOR"): + os.environ["TF_GPU_ALLOCATOR"] = "cuda_malloc_async" import ast import contextlib import importlib import json import logging -import os import shutil import traceback from importlib import reload +from pathlib import Path from aiohttp import web from server import PromptServer @@ -39,11 +42,10 @@ WEB_DIRECTORY = "./web" __version__ = "0.2.0" -def extract_nodes_from_source(filename): +def extract_nodes_from_source(filename: Path): source_code = "" - with open(filename, encoding="utf8") as file: - source_code = file.read() + source_code = filename.read_text(encoding="utf-8") nodes = [] @@ -107,28 +109,58 @@ def load_nodes(): # - REGISTER WEB EXTENSIONS -web_extensions_root = comfy_dir / "web" / "extensions" -web_mtb = web_extensions_root / "mtb" +def uninstall_old_web_extensions(): + web_extensions_root = comfy_dir / "web" / "extensions" + web_mtb = web_extensions_root / "mtb" -if web_mtb.exists() and hasattr(nodes, "EXTENSION_WEB_DIRS"): - try: - if web_mtb.is_symlink(): - web_mtb.unlink() - else: - shutil.rmtree(web_mtb) - except Exception as e: - log.warning( - f"Failed to remove web mtb directory: {e}\nPlease manually remove it from disk ({web_mtb}) and restart the server." - ) + if web_mtb.exists() and hasattr(nodes, "EXTENSION_WEB_DIRS"): + try: + if web_mtb.is_symlink(): + web_mtb.unlink() + else: + shutil.rmtree(web_mtb) + except Exception as e: + log.warning( + f"Failed to remove web mtb directory: {e}\nPlease manually remove it from disk ({web_mtb}) and restart the server." + ) + + +# uninstall_old_web_extensions() + + +# - GATHER WIKI PAGES +def wiki_to_classname(s: str): + wiki_name = s.replace("nodes-", "", 1) + return "MTB_" + "".join( + [part.capitalize() for part in wiki_name.split("-")] + ) + + +wiki = here / "wiki" +node_docs = {} +if wiki.exists() and wiki.is_dir(): + node_docs = { + wiki_to_classname(x.stem): x.read_text(encoding="utf-8") + for x in (wiki / "nodes").glob("*.md") + } # - REGISTER NODES nodes, failed = load_nodes() for node_class in nodes: class_name = node_class.__name__ - # fallback to __doc__ - if not hasattr(node_class, "DESCRIPTION") and node_class.__doc__: - node_class.DESCRIPTION = node_class.__doc__ + linked_doc = node_docs.get(class_name) + + if not hasattr(node_class, "DESCRIPTION"): + if linked_doc: + log.debug(f"Found linked doc for {class_name}") + node_class.DESCRIPTION = linked_doc + elif node_class.__doc__: + node_class.DESCRIPTION = node_class.__doc__ + else: + log.debug( + f"None of the methods could retrive documentation for {class_name}" + ) node_label = f"{get_label(class_name)} (mtb)" NODE_CLASS_MAPPINGS[node_label] = node_class diff --git a/biome.json b/biome.json index 1a67f8e..7bfd11c 100644 --- a/biome.json +++ b/biome.json @@ -1,19 +1,22 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.6.1/schema.json", - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true - } - }, - "javascript": { - "formatter": { - "quoteStyle": "single", - "semicolons": "asNeeded", - "indentWidth": 2 - } - } -} +{ + "$schema": "https://biomejs.dev/schemas/1.6.1/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "formatter": { + "lineEnding": "lf" + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "semicolons": "asNeeded", + "indentWidth": 2 + } + } +} diff --git a/log.py b/log.py index 271e814..06473ac 100644 --- a/log.py +++ b/log.py @@ -36,7 +36,7 @@ class Formatter(logging.Formatter): return formatter.format(record) -def mklog(name, level=base_log_level): +def mklog(name: str, level: int = base_log_level): logger = logging.getLogger(name) logger.setLevel(level) @@ -58,23 +58,23 @@ def mklog(name, level=base_log_level): log = mklog(__package__, base_log_level) -def log_user(arg): - print("\033[34mComfy MTB Utils:\033[0m {arg}") +def log_user(arg: str): + print(f"\033[34mComfy MTB Utils:\033[0m {arg}") -def get_summary(docstring): +def get_summary(docstring: str): return docstring.strip().split("\n\n", 1)[0] -def blue_text(text): +def blue_text(text: str): return f"\033[94m{text}\033[0m" -def cyan_text(text): +def cyan_text(text: str): return f"\033[96m{text}\033[0m" -def get_label(label): +def get_label(label: str): if label.startswith("MTB_"): label = label[4:] words = re.findall(r"(?:^|[A-Z])[a-z]*", label) diff --git a/pyproject.toml b/pyproject.toml index 0e33e2c..9120a58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,26 @@ docutils = "0.17.1" jupyter-book = "^0.15.1" sphinx-autobuild = "^2021.3.14" +[tool.pyright] +include = ["."] +exclude = [ + "**/node_modules", + "**/__pycache__", + "src/experimental", + "src/typestubs", +] +ignore = ["src/oldstuff"] +defineConstant = { DEBUG = true } +extraPaths = ["python", "../.."] +stubPath = "src/stubs" + +reportMissingImports = true +reportMissingTypeStubs = false +typeCheckingMode = "basic" + +pythonVersion = "3.9" +pythonPlatform = "Windows" + [tool.pytest.ini_options] log_level = "DEBUG" log_cli = true diff --git a/types/shared.d.ts b/types/shared.d.ts index fbb391d..75759e9 100644 --- a/types/shared.d.ts +++ b/types/shared.d.ts @@ -1,9 +1,20 @@ // Some manual types I use to facilitate developing on top of // Comfy's Litegraph implementation. -import type { ContextMenuItem, LGraphNode } from '../web/types/litegraph' +import type { + ContextMenuItem, + LGraphNode, + IWidget, +} from '../web/types/litegraph' -export type { ContextMenuItem } from '../web/types/litegraph' +export type { + ComfyExtension, + ComfyObjectInfo, + ComfyObjectInfoConfig, +} from '../web/types/comfy' +export type { ContextMenuItem, IWidget, LLink } from '../web/types/litegraph' + +export type VectorWidget = IWidget export interface NodeData { category: str description: str @@ -16,18 +27,20 @@ export interface NodeData { output_node: boolean } -export interface ExtendedLGraphNode { +export interface LGraphNodeExtension { onNodeCreated: () => void getExtraMenuOptions: () => ContextMenuItem[] } +export type LGraphNodeExtended = LGraphNode & LGraphNodeExtension + export interface NodeType /*extends LGraphNode*/ { category: str comfyClass: str length: 0 name: str nodeData: NodeData - prototype: LGraphNode & ExtendedLGraphNode + prototype: LGraphNodeExtended title: str type: str } @@ -43,7 +56,7 @@ export type OnConnectionsChangeParams = Parameters< LGraphNode['onConnectionsChange'] > export type OnNodeCreatedParams = Parameters< - ExtendedLGraphNode['onNodeCreated'] + LGraphNodeExtension['onNodeCreated'] > export interface DocumentationOptions { diff --git a/types/typedefs.js b/types/typedefs.js index e199b25..eece354 100644 --- a/types/typedefs.js +++ b/types/typedefs.js @@ -5,5 +5,13 @@ * @typedef {import("./shared.d.ts").OnDrawForegroundParams} OnDrawForegroundParams * @typedef {import("./shared.d.ts").OnMouseDownParams} OnMouseDownParams * @typedef {import("./shared.d.ts").OnConnectionsChangeParams} OnConnectionsChangeParams - * @typedef {import("./shared.d.ts").getExtraMenuOptionsParams} getExtraMenuOptionsParams + * @typedef {import("./shared.d.ts").ContextMenuItem} ContextMenuItem + * @typedef {import("./shared.d.ts").IWidget} IWidget + * @typedef {import("./shared.d.ts").VectorWidget} VectorWidget + * @typedef {import("./shared.d.ts").LGraphNodeExtended} LGraphNode + * @typedef {import("./shared.d.ts").LLink} LLink + * @typedef {import("./shared.d.ts").INodeInputSlot} INodeInputSlot + * @typedef {import("./shared.d.ts").INodeOutputSlot} INodeOutputSlot + * INodeInputSlot, INodeOutputSlot */ + diff --git a/web/comfy_shared.js b/web/comfy_shared.js index 84f663e..86c99ac 100644 --- a/web/comfy_shared.js +++ b/web/comfy_shared.js @@ -3,7 +3,7 @@ * Project: comfy_mtb * Author: Mel Massadian * - * Copyright (c) 2023 Mel Massadian + * Copyright (c) 2023-2024 Mel Massadian * */ @@ -83,6 +83,25 @@ export const log = (...args) => { //- WIDGET UTILS export const CONVERTED_TYPE = 'converted-widget' +/** + * @param {LGraphNode} node + * @param {LLink} link + * @returns {{to:LGraphNode, from:LGraphNode, type:'error' | 'incoming' | 'outgoing'}} + */ +export const nodesFromLink = (node, link) => { + const fromNode = app.graph.getNodeById(link.origin_id) + const toNode = app.graph.getNodeById(link.target_id) + + let tp = 'error' + + if (fromNode.id === node.id) { + tp = 'outgoing' + } else if (toNode.id === node.id) { + tp = 'incoming' + } + + return { to: toNode, from: fromNode, type: tp } +} export const hasWidgets = (node) => { if (!node.widgets || !node.widgets?.[Symbol.iterator]) { @@ -158,8 +177,19 @@ export function getWidgetType(config) { } return { type, linkType } } + +/** + * @param {NodeType} nodeType + * @param {str} prefix + * @param {str | [str]} inputType + * @param {{link?:LLink, ioSlot?:INodeInputSlot | INodeOutputSlot}?} opts + * @returns + */ + export const setupDynamicConnections = (nodeType, prefix, inputType, opts) => { infoLogger('Setting up dynamic connections for', nodeType) + + /** @type {{link?:LLink, ioSlot?:INodeInputSlot | INodeOutputSlot}} */ const options = opts || {} const onNodeCreated = nodeType.prototype.onNodeCreated const inputList = typeof inputType === 'object' @@ -171,50 +201,32 @@ export const setupDynamicConnections = (nodeType, prefix, inputType, opts) => { } const onConnectionsChange = nodeType.prototype.onConnectionsChange -<<<<<<< HEAD - nodeType.prototype.onConnectionsChange = function ( - type, - slotIndex, - isConnected, - link, - ioSlot, - ) { - infoLogger(`Connection changed for ${this.type}`, { + /** + * @param {OnConnectionsChangeParams} args + */ + nodeType.prototype.onConnectionsChange = function (...args) { + const [type, slotIndex, isConnected, link, ioSlot] = args + + options.link = link + options.ioSlot = ioSlot + const r = onConnectionsChange + ? onConnectionsChange.apply(this, [ + type, + slotIndex, + isConnected, + link, + ioSlot, + ]) + : undefined + options.DEBUG = { node: this, type, slotIndex, isConnected, link, ioSlot, - }) - options.link = link - options.ioSlot = ioSlot + } -||||||| dff5b22 - nodeType.prototype.onConnectionsChange = function ( - type, - index, - connected, - link_info, - ) { -======= - - /** - * @param {OnConnectionsChangeParams} args - */ - nodeType.prototype.onConnectionsChange = function (...args) { - const [_type, index, connected, _link_info] = args ->>>>>>> main - const r = onConnectionsChange - ? onConnectionsChange.apply( - this, - type, - slotIndex, - isConnected, - link, - ioSlot, - ) - : undefined dynamic_connection( this, slotIndex, @@ -226,79 +238,16 @@ export const setupDynamicConnections = (nodeType, prefix, inputType, opts) => { return r } } -/** - * cleanup dynamic inputs - * - * @param {import("../../../web/types/litegraph.d.ts").LGraphNode} node - The target node - * @param {bool} connected - Was this event connecting or disconnecting - * @param {string} connectionPrefix - The common prefix of the dynamic inputs - * @param {string|[string]} connectionType - The type of the dynamic connection - * @param {{nameInput?:[string]}} [opts] - extra options - */ - -const clean_dynamic_state = ( - node, - connected, - connectionPrefix, - connectionType, - opts, -) => { - infoLogger('CLEANING', { node, connectionPrefix, connectionType, opts }) - const options = opts || {} - const nameArray = options.nameArray || [] - - const listConnection = typeof connectionType === 'object' - const conType = listConnection ? '*' : connectionType - infoLogger('connected', connected) - - if (connected) { - // Remove inputs and their widget if not linked. - for (let n = 0; n < node.inputs.length; n++) { - const element = node.inputs[n] - if (!element.link) { - if (node.widgets) { - const w = node.widgets.find((w) => w.name === element.name) - if (w) { - w.onRemoved?.() - node.widgets.length = node.widgets.length - 1 - } - } - node.removeInput(n) - } - } - } - // make inputs sequential again - for (let i = 0; i < node.inputs.length; i++) { - let name = `${connectionPrefix}${i + 1}` - - if (nameArray.length > 0) { - name = i < nameArray.length ? nameArray[i] : name - } - - node.inputs[i].label = name - node.inputs[i].name = name - } - // add an extra input - if (node.inputs[node.inputs.length - 1].link !== undefined) { - const nextIndex = node.inputs.length - let name = `${connectionPrefix}${nextIndex + 1}` - if (nameArray.length > 0) { - name = nextIndex < nameArray.length ? nameArray[nextIndex] : name - } - log(`Adding input ${nextIndex + 1} (${name})`) - node.addInput(name, conType) - } -} /** * Main logic around dynamic inputs * - * @param {import("../../../web/types/litegraph.d.ts").LGraphNode} node - The target node + * @param {LGraphNode} node - The target node * @param {number} index - The slot index of the currently changed connection * @param {bool} connected - Was this event connecting or disconnecting * @param {string} [connectionPrefix] - The common prefix of the dynamic inputs * @param {string|[string]} [connectionType] - The type of the dynamic connection - * @param {{nameInput?:[string]}} [opts] - extra options + * @param {{link?:LLink, ioSlot?:INodeInputSlot | INodeOutputSlot}} [opts] - extra options */ export const dynamic_connection = ( node, @@ -308,17 +257,13 @@ export const dynamic_connection = ( connectionType = '*', opts = undefined, ) => { - infoLogger('MTB Dynamic Connection', { - node, - node_inputs: node.inputs, - index, - connected, - connectionPrefix, - connectionType, - opts, - }) + /* @type {{link?:LLink, ioSlot?:INodeInputSlot | INodeOutputSlot}} [opts] - extra options*/ const options = opts || {} - if (!node.inputs[index].name.startsWith(connectionPrefix)) { + + if ( + node.inputs.length > 0 && + !node.inputs[index].name.startsWith(connectionPrefix) + ) { return } @@ -327,17 +272,14 @@ export const dynamic_connection = ( const conType = listConnection ? '*' : connectionType const nameArray = options.nameArray || [] - // clean_dynamic_state( - // node, - // connected, - // connectionPrefix, - // connectionType, - // options, - // ) - // + const clean_inputs = () => { + if (node.inputs.length === 0) return - if (connected) { - // Remove inputs and their widget if not linked. + let w_count = node.widgets?.length || 0 + let i_count = node.inputs?.length || 0 + infoLogger(`Cleaning inputs: [BEFORE] (w: ${w_count} | inputs: ${i_count})`) + + const to_remove = [] for (let n = 0; n < node.inputs.length; n++) { const element = node.inputs[n] if (!element.link) { @@ -348,33 +290,80 @@ export const dynamic_connection = ( node.widgets.length = node.widgets.length - 1 } } - node.removeInput(n) + infoLogger(`Removing input ${n}`) + to_remove.push(n) } } - } - // make inputs sequential again - for (let i = 0; i < node.inputs.length; i++) { - let name = `${connectionPrefix}${i + 1}` + for (let i = 0; i < to_remove.length; i++) { + const id = to_remove[i] - if (nameArray.length > 0) { - name = i < nameArray.length ? nameArray[i] : name + node.removeInput(id) + i_count -= 1 + } + node.inputs.length = i_count + + w_count = node.widgets?.length || 0 + i_count = node.inputs?.length || 0 + infoLogger(`Cleaning inputs: [AFTER] (w: ${w_count} | inputs: ${i_count})`) + + infoLogger('Cleaning inputs: making it sequential again') + // make inputs sequential again + for (let i = 0; i < node.inputs.length; i++) { + let name = `${connectionPrefix}${i + 1}` + + if (nameArray.length > 0) { + name = i < nameArray.length ? nameArray[i] : name + } + + node.inputs[i].label = name + node.inputs[i].name = name + } + } + if (!connected) { + if (!options.link) { + infoLogger('Disconnecting', { options }) + + clean_inputs() + } else { + if (!options.ioSlot.link) { + node.connectionTransit = true + } else { + node.connectionTransit = false + clean_inputs() + } + infoLogger('Reconnecting', { options }) + } + } + + if (connected) { + if (options.link) { + const { from, to, type } = nodesFromLink(node, options.link) + if (type === 'outgoing') return + infoLogger('Connecting', { options, from, to, type }) + } else { + infoLogger('Connecting', { options }) } - node.inputs[i].label = name - node.inputs[i].name = name - } + if (node.connectionTransit) { + infoLogger('In Transit') + node.connectionTransit = false + } - // add an extra input - if (node.inputs[node.inputs.length - 1].link !== undefined) { - const nextIndex = node.inputs.length - const name = - nextIndex < nameArray.length - ? nameArray[nextIndex] - : `${connectionPrefix}${nextIndex + 1}` + // Remove inputs and their widget if not linked. + clean_inputs() - log(`Adding input ${nextIndex + 1} (${name})`) + if (node.inputs.length === 0) return + // add an extra input + if (node.inputs[node.inputs.length - 1].link !== null) { + const nextIndex = node.inputs.length + const name = + nextIndex < nameArray.length + ? nameArray[nextIndex] + : `${connectionPrefix}${nextIndex + 1}` - node.addInput(name, listConnection ? '*' : connectionType) + infoLogger(`Adding input ${nextIndex + 1} (${name})`) + node.addInput(name, conType) + } } } @@ -784,6 +773,7 @@ export const addDocumentation = ( const iconMargin = options.icon_margin || 4 let docElement = null let wrapper = null + const drawFg = nodeType.prototype.onDrawForeground /** @@ -798,15 +788,14 @@ export const addDocumentation = ( // icon position const x = this.size[0] - iconSize - iconMargin + let resizeHandle + // create it if (this.show_doc && docElement === null) { create_documentation_stylesheet() docElement = document.createElement('div') docElement.classList.add('documentation-popup') document.body.appendChild(docElement) - // docElement.innerHTML = documentationConverter.makeHtml( - // nodeData.description, - // ) wrapper = document.createElement('div') wrapper.classList.add('documentation-wrapper') @@ -814,24 +803,21 @@ export const addDocumentation = ( docElement.appendChild(wrapper) // resize handle - const resizeHandle = document.createElement('div') - resizeHandle.style.width = '10px' - resizeHandle.style.height = '10px' - // resizeHandle.style.background = 'gray' + resizeHandle = document.createElement('div') + resizeHandle.style.width = '0' + resizeHandle.style.height = '0' resizeHandle.style.position = 'absolute' resizeHandle.style.bottom = '0' resizeHandle.style.right = '0' - // resizeHandle.style.left = '95%' + resizeHandle.style.cursor = 'se-resize' resizeHandle.style.userSelect = 'none' - const borderColor = getComputedStyle(document.documentElement) - .getPropertyValue('--border-color') - .trim() - resizeHandle.style.borderTop = '10px solid transparent' - resizeHandle.style.borderLeft = '10px solid transparent' - resizeHandle.style.borderBottom = `10px solid ${borderColor}` - resizeHandle.style.borderRight = `10px solid ${borderColor}` + resizeHandle.style.borderWidth = '15px' + resizeHandle.style.borderStyle = 'solid' + + resizeHandle.style.borderColor = + 'transparent var(--border-color) var(--border-color) transparent' wrapper.appendChild(resizeHandle) let isResizing = false @@ -841,41 +827,53 @@ export const addDocumentation = ( let startWidth let startHeight - resizeHandle.addEventListener('mousedown', (e) => { - e.stopPropagation() - isResizing = true - startX = e.clientX - startY = e.clientY - startWidth = Number.parseInt( - document.defaultView.getComputedStyle(docElement).width, - 10, - ) - startHeight = Number.parseInt( - document.defaultView.getComputedStyle(docElement).height, - 10, - ) - }) + resizeHandle.addEventListener( + 'mousedown', + (e) => { + e.stopPropagation() + isResizing = true + startX = e.clientX + startY = e.clientY + startWidth = Number.parseInt( + document.defaultView.getComputedStyle(docElement).width, + 10, + ) + startHeight = Number.parseInt( + document.defaultView.getComputedStyle(docElement).height, + 10, + ) + }, - document.addEventListener('mousemove', (e) => { - console.log('Moving mouse') - if (!isResizing) return - const newWidth = startWidth + e.clientX - startX - const newHeight = startHeight + e.clientY - startY + { signal: this.docCtrl.signal }, + ) - docElement.style.width = `${newWidth}px` - docElement.style.height = `${newHeight}px` + document.addEventListener( + 'mousemove', + (e) => { + if (!isResizing) return + const newWidth = startWidth + e.clientX - startX + const newHeight = startHeight + e.clientY - startY - this.docPos = { - width: `${newWidth}px`, - height: `${newHeight}px`, - } - }) + docElement.style.width = `${newWidth}px` + docElement.style.height = `${newHeight}px` - document.addEventListener('mouseup', () => { - isResizing = false - }) + this.docPos = { + width: `${newWidth}px`, + height: `${newHeight}px`, + } + }, + { signal: this.docCtrl.signal }, + ) + + document.addEventListener( + 'mouseup', + () => { + isResizing = false + }, + { signal: this.docCtrl.signal }, + ) } else if (!this.show_doc && docElement !== null) { - docElement.parentNode.removeChild(docElement) + docElement.remove() docElement = null } @@ -900,12 +898,6 @@ export const addDocumentation = ( top: `${transform.d + transform.f}px`, width: this.docPos ? this.docPos.width : `${this.size[0] * 1.5}px`, height: this.docPos?.height, - // width: `${this.size[0] * 2}px`, - // height: `${(widget.parent?.inputHeight || 32) - (margin * 2)}px`, - // height: `${this.size[1] || this.parent?.inputHeight || 32}px`, - - // background: !node.color ? "" : node.color, - // color: "blue", //!node.color ? "" : "white", }) if (this.docPos === undefined) { @@ -914,23 +906,22 @@ export const addDocumentation = ( height: docElement.style.height, } } - - // docElement.style.left = 140 - rect.right + "px"; - // docElement.style.top = rect.top + "px"; } ctx.save() - ctx.translate(x, iconSize - 34) // Position the icon on the canvas - ctx.scale(iconSize / 32, iconSize / 32) // Scale the icon to the desired size + ctx.translate(x, iconSize - 34) + ctx.scale(iconSize / 32, iconSize / 32) ctx.strokeStyle = 'rgba(255,255,255,0.3)' ctx.lineCap = 'round' ctx.lineJoin = 'round' ctx.lineWidth = 2.4 - // ctx.stroke(questionMark); ctx.font = 'bold 36px monospace' ctx.fillText('?', 0, 24) + + // ctx.font = `bold ${this.show_doc ? 36 : 24}px monospace` + // ctx.fillText(`${this.show_doc ? '▼' : '▶'}`, 24, 24) ctx.restore() return r @@ -958,6 +949,11 @@ export const addDocumentation = ( } else { this.show_doc = !this.show_doc } + if (this.show_doc) { + this.docCtrl = new AbortController() + } else { + this.docCtrl.abort() + } return true // Return true to indicate the event was handled } diff --git a/web/debug.js b/web/debug.js index 5a22425..d97c441 100644 --- a/web/debug.js +++ b/web/debug.js @@ -37,14 +37,14 @@ app.registerExtension({ } const onConnectionsChange = nodeType.prototype.onConnectionsChange - nodeType.prototype.onConnectionsChange = function ( - type, - index, - connected, - link_info, - ) { + /** + * @param {OnConnectionsChangeParams} args + */ + + nodeType.prototype.onConnectionsChange = function (...args) { + const [_type, index, connected, link_info] = args const r = onConnectionsChange - ? onConnectionsChange.apply(this, arguments) + ? onConnectionsChange.apply(this, args) : undefined // TODO: remove all widgets on disconnect once computed shared.dynamic_connection(this, index, connected, 'anything_', '*') @@ -54,9 +54,10 @@ app.registerExtension({ // const fromNode = this.graph._nodes.find( // (otherNode) => otherNode.id === link_info.origin_id, // ) - const fromNode = app.graph.getNodeById(link_info.origin_id) - if (!fromNode) return - const type = fromNode.outputs[link_info.origin_slot].type + // const fromNode = app.graph.getNodeById(link_info.origin_id) + const { from } = shared.nodesFromLink(this, link_info) + if (!from || this.inputs.length === 0) return + const type = from.outputs[link_info.origin_slot].type this.inputs[index].type = type // this.inputs[index].label = type.toLowerCase() } @@ -85,7 +86,7 @@ app.registerExtension({ this.widgets.length = 1 } let widgetI = 1 - console.log(message) + // console.log(message) if (message.text) { for (const txt of message.text) { const w = this.addCustomWidget( diff --git a/web/mtb_widgets.js b/web/mtb_widgets.js index 7734d59..b6d43d9 100644 --- a/web/mtb_widgets.js +++ b/web/mtb_widgets.js @@ -7,10 +7,7 @@ * */ -/** - * @typedef {import("../../../web/types/litegraph.d.ts").IWidget} IWidget - * @typedef {import("../../../web/types/litegraph.d.ts").IWidget} VectorWidget - */ +/// // TODO: Use the builtin addDOMWidget everywhere appropriate