Adds a 'Any Switch' that will choose the first non-null input. Fixes #26. Also, correct link colors on reroute input nodes

This commit is contained in:
rgthree
2023-10-01 00:10:02 -04:00
parent c01735c1b1
commit 0034199e76
10 changed files with 425 additions and 34 deletions
+2
View File
@@ -27,6 +27,7 @@ from .py.context_big import RgthreeBigContext
from .py.ksampler_config import RgthreeKSamplerConfig
from .py.sdxl_power_prompt_postive import RgthreeSDXLPowerPromptPositive
from .py.sdxl_power_prompt_simple import RgthreeSDXLPowerPromptSimple
from .py.any_switch import RgthreeAnySwitch
NODE_CLASS_MAPPINGS = {
RgthreeBigContext.NAME: RgthreeBigContext,
@@ -44,6 +45,7 @@ NODE_CLASS_MAPPINGS = {
RgthreeSDXLEmptyLatentImage.NAME: RgthreeSDXLEmptyLatentImage,
RgthreeSDXLPowerPromptPositive.NAME: RgthreeSDXLPowerPromptPositive,
RgthreeSDXLPowerPromptSimple.NAME: RgthreeSDXLPowerPromptSimple,
RgthreeAnySwitch.NAME: RgthreeAnySwitch,
}
+52
View File
@@ -0,0 +1,52 @@
import json
from .context_utils import is_context_empty
from .constants import get_category, get_name
from .utils import any_type
def is_none(value):
"""Checks if a value is none. Pulled out in case we want to expand what 'None' means."""
if value is not None:
if isinstance(value, dict) and 'model' in value and 'clip' in value:
return is_context_empty(value)
return value is None
class RgthreeAnySwitch:
"""The any switch. """
NAME = get_name("Any Switch")
CATEGORY = get_category()
@classmethod
def INPUT_TYPES(cls): # pylint: disable = invalid-name, missing-function-docstring
return {
"required": {},
"optional": {
"any_01": (any_type,),
"any_02": (any_type,),
"any_03": (any_type,),
"any_04": (any_type,),
"any_05": (any_type,),
},
}
RETURN_TYPES = (any_type,)
RETURN_NAMES = ('*',)
FUNCTION = "switch"
def switch(self, any_01=None, any_02=None, any_03=None, any_04=None, any_05=None):
"""Chooses the first non-empty item to output."""
any_value = None
if not is_none(any_01):
any_value = any_01
elif not is_none(any_02):
any_value = any_02
elif not is_none(any_03):
any_value = any_03
elif not is_none(any_04):
any_value = any_04
elif not is_none(any_05):
any_value = any_05
return (any_value,)
+9
View File
@@ -0,0 +1,9 @@
class AnyType(str):
"""A special class that is always equal in not equal comparisons. Credit to pythongosssss"""
def __ne__(self, __value: object) -> bool:
return False
any_type = AnyType("*")
+110
View File
@@ -0,0 +1,110 @@
// / <reference path="../node_modules/litegraph.js/src/litegraph.d.ts" />
// @ts-ignore
import { app } from "../../scripts/app.js";
// @ts-ignore
import { ComfyWidgets } from "../../scripts/widgets.js";
import type {
INodeInputSlot,
INodeOutputSlot,
LGraphNodeConstructor,
LLink,
SerializedLGraphNode,
LGraphNode as TLGraphNode,
LiteGraph as TLiteGraph,
} from "./typings/litegraph.js";
import type { ComfyApp, ComfyObjectInfo } from "./typings/comfy.js";
import {
IoDirection,
addConnectionLayoutSupport,
applyMixins,
followConnectionUntilType,
replaceNode,
} from "./utils.js";
import { RgthreeBaseNode } from "./base_node.js";
declare const LiteGraph: typeof TLiteGraph;
declare const LGraphNode: typeof TLGraphNode;
let hasShownAlertForUpdatingInt = false;
class AnySwitchforMixin extends RgthreeBaseNode {
static comfyClass? = "";
private scheduleStabilizePromise: Promise<void> | null = null;
private nodeType: string | string[] | null = null;
override onConnectionsChange(
type: number,
slotIndex: number,
isConnected: boolean,
linkInfo: LLink,
ioSlot: INodeOutputSlot | INodeInputSlot,
) {
super.onConnectionsChange?.(type, slotIndex, isConnected, linkInfo, ioSlot);
this.scheduleStabilize();
}
onConnectionsChainChange() {
this.scheduleStabilize();
}
scheduleStabilize(ms = 64) {
if (!this.scheduleStabilizePromise) {
this.scheduleStabilizePromise = new Promise((resolve) => {
setTimeout(() => {
this.scheduleStabilizePromise = null;
this.stabilize();
resolve();
}, ms);
});
}
return this.scheduleStabilizePromise;
}
stabilize() {
// We prefer the inputs, then the output.
let connectedType = followConnectionUntilType(this, IoDirection.INPUT, undefined, true);
if (!connectedType) {
connectedType = followConnectionUntilType(this, IoDirection.OUTPUT, undefined, true);
}
// TODO: What this doesn't do is broadcast to other nodes when its type changes. Reroute node
// does, but, for now, if this was connected to another Any Switch, say, the second one wouldn't
// change its type when the first does. The user would need to change the connections.
this.nodeType = connectedType?.type || "*";
for (const input of this.inputs) {
input.type = this.nodeType as string; // So, types can indeed be arrays,,
}
for (const output of this.outputs) {
output.type = this.nodeType as string; // So, types can indeed be arrays,,
output.label =
output.type === 'RGTHREE_CONTEXT' ? 'CONTEXT' :
Array.isArray(this.nodeType) || this.nodeType.includes(",")
? connectedType?.label || String(this.nodeType)
: String(this.nodeType);
}
}
static override setUp<T extends RgthreeBaseNode>(nodeType: new(title?: any) => T) {
AnySwitchforMixin.title = (nodeType as any).title;
AnySwitchforMixin.type = (nodeType as any).type || (nodeType as any).title;
AnySwitchforMixin.comfyClass = (nodeType as any).comfyClass;
setTimeout(() => {
AnySwitchforMixin.category = (nodeType as any).category;
});
applyMixins(nodeType, [RgthreeBaseNode, AnySwitchforMixin]);
addConnectionLayoutSupport(nodeType, app, [["Left"], ["Right"]]);
}
}
app.registerExtension({
name: "rgthree.AnySwitch",
async beforeRegisterNodeDef(
nodeType: LGraphNodeConstructor,
nodeData: ComfyObjectInfo,
app: ComfyApp,
) {
if (nodeData.name === "Any Switch (rgthree)") {
AnySwitchforMixin.setUp(nodeType as any);
}
},
});
+15 -6
View File
@@ -157,6 +157,7 @@ app.registerExtension({
let updateNodes = [];
let inputType = null;
let inputNode = null;
let inputNodeOutputSlot = null;
while (currentNode) {
updateNodes.unshift(currentNode);
const linkId: number | null = currentNode.inputs[0]!.link;
@@ -183,8 +184,9 @@ app.registerExtension({
}
} else {
// We've found the end
inputNode = currentNode;
inputType = node.outputs[link.origin_slot]?.type ?? null;
inputNode = node;
inputNodeOutputSlot = link.origin_slot;
inputType = node.outputs[inputNodeOutputSlot]?.type ?? null;
break;
}
} else {
@@ -196,6 +198,7 @@ app.registerExtension({
// Find all outputs
const nodes: TLGraphNode[] = [this];
let outputNode = null;
let outputType = null;
while (nodes.length) {
currentNode = nodes.pop()!;
@@ -232,6 +235,7 @@ app.registerExtension({
node.disconnectInput(link.target_slot);
} else {
outputType = nodeOutType;
outputNode = node;
}
}
}
@@ -261,12 +265,17 @@ app.registerExtension({
}
}
if (inputNode) {
const link = app.graph.links[inputNode.inputs[0]!.link];
if (link) {
link.color = color;
if (inputNode && inputNodeOutputSlot != null) {
const links = inputNode.outputs[inputNodeOutputSlot]!.links;
for (const l of links || []) {
const link = app.graph.links[l];
if (link) {
link.color = color;
}
}
}
(inputNode as any)?.onConnectionsChainChange?.();
(outputNode as any)?.onConnectionsChainChange?.();
app.graph.setDirtyCanvas(true, true);
}
+12 -1
View File
@@ -622,7 +622,7 @@ export declare class LGraphNode {
// end @rgthree added
static title_color: string;
static title_color?: string;
static title: string;
static type: null | string;
static widgets_up: boolean;
@@ -1089,6 +1089,17 @@ export declare class LGraphNode {
export type LGraphNodeConstructor<T extends LGraphNode = LGraphNode> = {
new (): T;
// @rgthree
title_mode?:
typeof LiteGraph.NORMAL_TITLE |
typeof LiteGraph.TRANSPARENT_TITLE |
typeof LiteGraph.AUTOHIDE_TITLE |
typeof LiteGraph.NO_TITLE;
title: string;
category: string;
type: string;
comfyClass?: string;
};
export type SerializedLGraphGroup = {
+85 -13
View File
@@ -407,15 +407,15 @@ export function getConnectedInputNodes(
currentNode?: TLGraphNode,
slot?: number,
passThroughFollowing = PassThroughFollowing.ALL,
) {
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing);
) : TLGraphNode[] {
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
}
export function getConnectedInputNodesAndFilterPassThroughs(
startNode: TLGraphNode,
currentNode?: TLGraphNode,
slot?: number,
passThroughFollowing = PassThroughFollowing.ALL,
) {
) : TLGraphNode[] {
return filterOutPassthroughNodes(
getConnectedInputNodes(startNode, currentNode, slot, passThroughFollowing),
passThroughFollowing,
@@ -426,38 +426,39 @@ export function getConnectedOutputNodes(
currentNode?: TLGraphNode,
slot?: number,
passThroughFollowing = PassThroughFollowing.ALL,
) {
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing);
) : TLGraphNode[] {
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
}
export function getConnectedOutputNodesAndFilterPassThroughs(
startNode: TLGraphNode,
currentNode?: TLGraphNode,
slot?: number,
passThroughFollowing = PassThroughFollowing.ALL,
) {
) : TLGraphNode[] {
return filterOutPassthroughNodes(
getConnectedOutputNodes(startNode, currentNode, slot, passThroughFollowing),
passThroughFollowing,
);
}
function getConnectedNodes(
export function getConnectedNodes(
startNode: TLGraphNode,
dir = IoDirection.INPUT,
currentNode?: TLGraphNode,
slot?: number,
passThroughFollowing = PassThroughFollowing.ALL,
) {
) : {node:TLGraphNode, slot: number}[] {
currentNode = currentNode || startNode;
let rootNodes: TLGraphNode[] = [];
let rootNodes: {node:TLGraphNode, slot: number}[] = [];
const slotsToRemove = [];
if (startNode === currentNode || shouldPassThrough(currentNode, passThroughFollowing)) {
// const removeDups = startNode === currentNode;
let linkIds: Array<number | null>;
if (dir == IoDirection.OUTPUT) {
linkIds = currentNode.outputs?.flatMap((i) => i.links);
linkIds = currentNode.outputs?.flatMap((i) => i.links) || [];
} else {
linkIds = currentNode.inputs?.map((i) => i.link);
linkIds = currentNode.inputs?.map((i) => i.link) || [];
}
if (typeof slot == "number" && slot > -1) {
if (linkIds[slot]) {
@@ -473,12 +474,13 @@ function getConnectedNodes(
continue;
}
const connectedId = dir == IoDirection.OUTPUT ? link.target_id : link.origin_id;
const originSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
const originNode: TLGraphNode = graph.getNodeById(connectedId)!;
if (!link) {
console.error("No connected node found... weird");
continue;
}
if (rootNodes.includes(originNode)) {
if (rootNodes.some((n) => n.node == originNode)) {
console.log(
`${startNode.title} (${startNode.id}) seems to have two links to ${originNode.title} (${
originNode.id
@@ -486,7 +488,7 @@ function getConnectedNodes(
);
} else {
// Add the node and, if it's a pass through, let's collect all its nodes as well.
rootNodes.push(originNode);
rootNodes.push({node: originNode, slot: originSlot});
if (shouldPassThrough(originNode, passThroughFollowing)) {
for (const foundNode of getConnectedNodes(startNode, dir, originNode)) {
if (!rootNodes.includes(foundNode)) {
@@ -500,6 +502,76 @@ function getConnectedNodes(
return rootNodes;
}
type ConnectionType = { type: string | string[]; label: string | undefined };
/**
* Follows a connection until we find a type associated with a slot.
* `skipSelf` skips the current slot, useful when we may have a dynamic slot that we want to start
* from, but find a type _after_ it (in case it needs to change).
*/
export function followConnectionUntilType(
node: TLGraphNode,
dir: IoDirection,
slotNum?: number,
skipSelf = false,
): ConnectionType | null {
const slots = dir === IoDirection.OUTPUT ? node.outputs : node.inputs;
if (!slots || !slots.length) {
return null;
}
let type: ConnectionType | null = null;
if (slotNum) {
if (!slots[slotNum]) {
return null;
}
type = getTypeFromSlot(slots[slotNum], dir, skipSelf);
} else {
for (const slot of slots) {
type = getTypeFromSlot(slot, dir, skipSelf);
if (type) {
break;
}
}
}
return type;
}
/**
* Gets the type from a slot. If the type is '*' then it will follow the node to find the next slot.
*/
function getTypeFromSlot(
slot: INodeInputSlot | INodeOutputSlot | undefined,
dir: IoDirection,
skipSelf = false,
): ConnectionType | null {
let graph = app.graph as LGraph;
let type = slot?.type;
if (!skipSelf && type != null && type != "*") {
return { type: type as string, label: slot?.label || slot?.name };
}
const links = getSlotLinks(slot);
for (const link of links) {
const connectedId = dir == IoDirection.OUTPUT ? link.link.target_id : link.link.origin_id;
const connectedSlotNum =
dir == IoDirection.OUTPUT ? link.link.target_slot : link.link.origin_slot;
const connectedNode: TLGraphNode = graph.getNodeById(connectedId)!;
// Reversed since if we're traveling down the output we want the connected node's input, etc.
const connectedSlots =
dir === IoDirection.OUTPUT ? connectedNode.inputs : connectedNode.outputs;
let connectedSlot = connectedSlots[connectedSlotNum];
console.log(connectedSlot);
if (connectedSlot?.type != null && connectedSlot?.type != "*") {
return {
type: connectedSlot.type as string,
label: connectedSlot?.label || connectedSlot?.name,
};
} else if (connectedSlot?.type == "*") {
return followConnectionUntilType(connectedNode, dir);
}
}
return null;
}
export async function replaceNode(
existingNode: TLGraphNode,
typeOrNewNode: string | TLGraphNode,
+68
View File
@@ -0,0 +1,68 @@
import { app } from "../../scripts/app.js";
import { IoDirection, addConnectionLayoutSupport, applyMixins, followConnectionUntilType, } from "./utils.js";
import { RgthreeBaseNode } from "./base_node.js";
let hasShownAlertForUpdatingInt = false;
class AnySwitchforMixin extends RgthreeBaseNode {
constructor() {
super(...arguments);
this.scheduleStabilizePromise = null;
this.nodeType = null;
}
onConnectionsChange(type, slotIndex, isConnected, linkInfo, ioSlot) {
var _a;
(_a = super.onConnectionsChange) === null || _a === void 0 ? void 0 : _a.call(this, type, slotIndex, isConnected, linkInfo, ioSlot);
this.scheduleStabilize();
}
onConnectionsChainChange() {
this.scheduleStabilize();
}
scheduleStabilize(ms = 64) {
if (!this.scheduleStabilizePromise) {
this.scheduleStabilizePromise = new Promise((resolve) => {
setTimeout(() => {
this.scheduleStabilizePromise = null;
this.stabilize();
resolve();
}, ms);
});
}
return this.scheduleStabilizePromise;
}
stabilize() {
let connectedType = followConnectionUntilType(this, IoDirection.INPUT, undefined, true);
if (!connectedType) {
connectedType = followConnectionUntilType(this, IoDirection.OUTPUT, undefined, true);
}
this.nodeType = (connectedType === null || connectedType === void 0 ? void 0 : connectedType.type) || "*";
for (const input of this.inputs) {
input.type = this.nodeType;
}
for (const output of this.outputs) {
output.type = this.nodeType;
output.label =
output.type === 'RGTHREE_CONTEXT' ? 'CONTEXT' :
Array.isArray(this.nodeType) || this.nodeType.includes(",")
? (connectedType === null || connectedType === void 0 ? void 0 : connectedType.label) || String(this.nodeType)
: String(this.nodeType);
}
}
static setUp(nodeType) {
AnySwitchforMixin.title = nodeType.title;
AnySwitchforMixin.type = nodeType.type || nodeType.title;
AnySwitchforMixin.comfyClass = nodeType.comfyClass;
setTimeout(() => {
AnySwitchforMixin.category = nodeType.category;
});
applyMixins(nodeType, [RgthreeBaseNode, AnySwitchforMixin]);
addConnectionLayoutSupport(nodeType, app, [["Left"], ["Right"]]);
}
}
AnySwitchforMixin.comfyClass = "";
app.registerExtension({
name: "rgthree.AnySwitch",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name === "Any Switch (rgthree)") {
AnySwitchforMixin.setUp(nodeType);
}
},
});
+16 -7
View File
@@ -85,7 +85,7 @@ app.registerExtension({
return this.schedulePromise;
}
stabilize() {
var _a, _b, _c, _d, _e;
var _a, _b, _c, _d, _e, _f, _g;
if (this.configuring) {
return;
}
@@ -93,6 +93,7 @@ app.registerExtension({
let updateNodes = [];
let inputType = null;
let inputNode = null;
let inputNodeOutputSlot = null;
while (currentNode) {
updateNodes.unshift(currentNode);
const linkId = currentNode.inputs[0].link;
@@ -115,8 +116,9 @@ app.registerExtension({
}
}
else {
inputNode = currentNode;
inputType = (_b = (_a = node.outputs[link.origin_slot]) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : null;
inputNode = node;
inputNodeOutputSlot = link.origin_slot;
inputType = (_b = (_a = node.outputs[inputNodeOutputSlot]) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : null;
break;
}
}
@@ -126,6 +128,7 @@ app.registerExtension({
}
}
const nodes = [this];
let outputNode = null;
let outputType = null;
while (nodes.length) {
currentNode = nodes.pop();
@@ -157,6 +160,7 @@ app.registerExtension({
}
else {
outputType = nodeOutType;
outputNode = node;
}
}
}
@@ -179,12 +183,17 @@ app.registerExtension({
}
}
}
if (inputNode) {
const link = app.graph.links[inputNode.inputs[0].link];
if (link) {
link.color = color;
if (inputNode && inputNodeOutputSlot != null) {
const links = inputNode.outputs[inputNodeOutputSlot].links;
for (const l of links || []) {
const link = app.graph.links[l];
if (link) {
link.color = color;
}
}
}
(_f = inputNode === null || inputNode === void 0 ? void 0 : inputNode.onConnectionsChainChange) === null || _f === void 0 ? void 0 : _f.call(inputNode);
(_g = outputNode === null || outputNode === void 0 ? void 0 : outputNode.onConnectionsChainChange) === null || _g === void 0 ? void 0 : _g.call(outputNode);
app.graph.setDirtyCanvas(true, true);
}
computeSize(out) {
+56 -7
View File
@@ -283,18 +283,18 @@ export function filterOutPassthroughNodes(nodes, passThroughFollowing = PassThro
return nodes.filter((n) => !shouldPassThrough(n, passThroughFollowing));
}
export function getConnectedInputNodes(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing);
return getConnectedNodes(startNode, IoDirection.INPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
}
export function getConnectedInputNodesAndFilterPassThroughs(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
return filterOutPassthroughNodes(getConnectedInputNodes(startNode, currentNode, slot, passThroughFollowing), passThroughFollowing);
}
export function getConnectedOutputNodes(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing);
return getConnectedNodes(startNode, IoDirection.OUTPUT, currentNode, slot, passThroughFollowing).map(n => n.node);
}
export function getConnectedOutputNodesAndFilterPassThroughs(startNode, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
return filterOutPassthroughNodes(getConnectedOutputNodes(startNode, currentNode, slot, passThroughFollowing), passThroughFollowing);
}
function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
export function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot, passThroughFollowing = PassThroughFollowing.ALL) {
var _a, _b;
currentNode = currentNode || startNode;
let rootNodes = [];
@@ -302,10 +302,10 @@ function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot
if (startNode === currentNode || shouldPassThrough(currentNode, passThroughFollowing)) {
let linkIds;
if (dir == IoDirection.OUTPUT) {
linkIds = (_a = currentNode.outputs) === null || _a === void 0 ? void 0 : _a.flatMap((i) => i.links);
linkIds = ((_a = currentNode.outputs) === null || _a === void 0 ? void 0 : _a.flatMap((i) => i.links)) || [];
}
else {
linkIds = (_b = currentNode.inputs) === null || _b === void 0 ? void 0 : _b.map((i) => i.link);
linkIds = ((_b = currentNode.inputs) === null || _b === void 0 ? void 0 : _b.map((i) => i.link)) || [];
}
if (typeof slot == "number" && slot > -1) {
if (linkIds[slot]) {
@@ -322,16 +322,17 @@ function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot
continue;
}
const connectedId = dir == IoDirection.OUTPUT ? link.target_id : link.origin_id;
const originSlot = dir == IoDirection.OUTPUT ? link.target_slot : link.origin_slot;
const originNode = graph.getNodeById(connectedId);
if (!link) {
console.error("No connected node found... weird");
continue;
}
if (rootNodes.includes(originNode)) {
if (rootNodes.some((n) => n.node == originNode)) {
console.log(`${startNode.title} (${startNode.id}) seems to have two links to ${originNode.title} (${originNode.id}). One may be stale: ${linkIds.join(", ")}`);
}
else {
rootNodes.push(originNode);
rootNodes.push({ node: originNode, slot: originSlot });
if (shouldPassThrough(originNode, passThroughFollowing)) {
for (const foundNode of getConnectedNodes(startNode, dir, originNode)) {
if (!rootNodes.includes(foundNode)) {
@@ -344,6 +345,54 @@ function getConnectedNodes(startNode, dir = IoDirection.INPUT, currentNode, slot
}
return rootNodes;
}
export function followConnectionUntilType(node, dir, slotNum, skipSelf = false) {
const slots = dir === IoDirection.OUTPUT ? node.outputs : node.inputs;
if (!slots || !slots.length) {
return null;
}
let type = null;
if (slotNum) {
if (!slots[slotNum]) {
return null;
}
type = getTypeFromSlot(slots[slotNum], dir, skipSelf);
}
else {
for (const slot of slots) {
type = getTypeFromSlot(slot, dir, skipSelf);
if (type) {
break;
}
}
}
return type;
}
function getTypeFromSlot(slot, dir, skipSelf = false) {
let graph = app.graph;
let type = slot === null || slot === void 0 ? void 0 : slot.type;
if (!skipSelf && type != null && type != "*") {
return { type: type, label: (slot === null || slot === void 0 ? void 0 : slot.label) || (slot === null || slot === void 0 ? void 0 : slot.name) };
}
const links = getSlotLinks(slot);
for (const link of links) {
const connectedId = dir == IoDirection.OUTPUT ? link.link.target_id : link.link.origin_id;
const connectedSlotNum = dir == IoDirection.OUTPUT ? link.link.target_slot : link.link.origin_slot;
const connectedNode = graph.getNodeById(connectedId);
const connectedSlots = dir === IoDirection.OUTPUT ? connectedNode.inputs : connectedNode.outputs;
let connectedSlot = connectedSlots[connectedSlotNum];
console.log(connectedSlot);
if ((connectedSlot === null || connectedSlot === void 0 ? void 0 : connectedSlot.type) != null && (connectedSlot === null || connectedSlot === void 0 ? void 0 : connectedSlot.type) != "*") {
return {
type: connectedSlot.type,
label: (connectedSlot === null || connectedSlot === void 0 ? void 0 : connectedSlot.label) || (connectedSlot === null || connectedSlot === void 0 ? void 0 : connectedSlot.name),
};
}
else if ((connectedSlot === null || connectedSlot === void 0 ? void 0 : connectedSlot.type) == "*") {
return followConnectionUntilType(connectedNode, dir);
}
}
return null;
}
export async function replaceNode(existingNode, typeOrNewNode, inputNameMap) {
const existingCtor = existingNode.constructor;
const newNode = typeof typeOrNewNode === "string" ? LiteGraph.createNode(typeOrNewNode) : typeOrNewNode;