mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-04 20:50:06 +00:00
Add slot compatibility checking for subgraph slots (#1182)
This commit is contained in:
@@ -4212,7 +4212,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
}
|
||||
|
||||
// Draw subgraph IO nodes
|
||||
this.subgraph?.draw(ctx, this.colourGetter)
|
||||
this.subgraph?.draw(ctx, this.colourGetter, this.linkConnector.renderLinks[0]?.fromSlot, this.editor_alpha)
|
||||
|
||||
// on top (debug)
|
||||
if (this.render_execution_order) {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import type { INodeInputSlot, INodeOutputSlot, OptionalProps, ReadOnlyPoint } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { LinkId } from "@/LLink"
|
||||
import type { SubgraphInput } from "@/subgraph/SubgraphInput"
|
||||
import type { SubgraphOutput } from "@/subgraph/SubgraphOutput"
|
||||
import type { IBaseWidget } from "@/types/widgets"
|
||||
|
||||
import { LabelPosition } from "@/draw"
|
||||
import { LiteGraph } from "@/litegraph"
|
||||
import { type IDrawOptions, NodeSlot } from "@/node/NodeSlot"
|
||||
import { isSubgraphInput } from "@/subgraph/subgraphUtils"
|
||||
|
||||
export class NodeInputSlot extends NodeSlot implements INodeInputSlot {
|
||||
link: LinkId | null
|
||||
@@ -38,8 +41,16 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot {
|
||||
return this.link != null
|
||||
}
|
||||
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot): boolean {
|
||||
return "links" in fromSlot && LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean {
|
||||
if ("links" in fromSlot) {
|
||||
return LiteGraph.isValidConnection(fromSlot.type, this.type)
|
||||
}
|
||||
|
||||
if (isSubgraphInput(fromSlot)) {
|
||||
return LiteGraph.isValidConnection(fromSlot.type, this.type)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override draw(ctx: CanvasRenderingContext2D, options: Omit<IDrawOptions, "doStroke" | "labelPosition">) {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import type { INodeInputSlot, INodeOutputSlot, OptionalProps, ReadOnlyPoint } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { LinkId } from "@/LLink"
|
||||
import type { SubgraphInput } from "@/subgraph/SubgraphInput"
|
||||
import type { SubgraphOutput } from "@/subgraph/SubgraphOutput"
|
||||
|
||||
import { LabelPosition } from "@/draw"
|
||||
import { LiteGraph } from "@/litegraph"
|
||||
import { type IDrawOptions, NodeSlot } from "@/node/NodeSlot"
|
||||
import { isSubgraphOutput } from "@/subgraph/subgraphUtils"
|
||||
|
||||
export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot {
|
||||
#node: LGraphNode
|
||||
@@ -32,8 +35,16 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot {
|
||||
this.#node = node
|
||||
}
|
||||
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot): boolean {
|
||||
return "link" in fromSlot && LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean {
|
||||
if ("link" in fromSlot) {
|
||||
return LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
}
|
||||
|
||||
if (isSubgraphOutput(fromSlot)) {
|
||||
return LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override get isConnected(): boolean {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { CanvasColour, DefaultConnectionColors, INodeInputSlot, INodeOutputSlot, INodeSlot, ISubgraphInput, OptionalProps, Point, ReadOnlyPoint } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { SubgraphInput } from "@/subgraph/SubgraphInput"
|
||||
import type { SubgraphOutput } from "@/subgraph/SubgraphOutput"
|
||||
|
||||
import { LabelPosition, SlotShape, SlotType } from "@/draw"
|
||||
import { LiteGraph, Rectangle } from "@/litegraph"
|
||||
@@ -68,7 +70,7 @@ export abstract class NodeSlot extends SlotBase implements INodeSlot {
|
||||
* Whether this slot is a valid target for a dragging link.
|
||||
* @param fromSlot The slot that the link is being connected from.
|
||||
*/
|
||||
abstract isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot): boolean
|
||||
abstract isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean
|
||||
|
||||
/**
|
||||
* The label to display in the UI.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SubgraphEventMap } from "@/infrastructure/SubgraphEventMap"
|
||||
import type { DefaultConnectionColors } from "@/interfaces"
|
||||
import type { DefaultConnectionColors, INodeInputSlot, INodeOutputSlot } from "@/interfaces"
|
||||
import type { LGraphCanvas } from "@/LGraphCanvas"
|
||||
import type { ExportedSubgraph, ExposedWidget, ISerialisedGraph, Serialisable, SerialisableGraph } from "@/types/serialisation"
|
||||
|
||||
@@ -206,9 +206,9 @@ export class Subgraph extends LGraph implements BaseLGraph, Serialisable<Exporte
|
||||
}
|
||||
}
|
||||
|
||||
draw(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void {
|
||||
this.inputNode.draw(ctx, colorContext)
|
||||
this.outputNode.draw(ctx, colorContext)
|
||||
draw(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void {
|
||||
this.inputNode.draw(ctx, colorContext, fromSlot, editorAlpha)
|
||||
this.outputNode.draw(ctx, colorContext, fromSlot, editorAlpha)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Subgraph } from "./Subgraph"
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { LinkConnector } from "@/canvas/LinkConnector"
|
||||
import type { DefaultConnectionColors, Hoverable, Point, Positionable } from "@/interfaces"
|
||||
import type { DefaultConnectionColors, Hoverable, INodeInputSlot, INodeOutputSlot, Point, Positionable } from "@/interfaces"
|
||||
import type { NodeId } from "@/LGraphNode"
|
||||
import type { ExportedSubgraphIONode, Serialisable } from "@/types/serialisation"
|
||||
|
||||
@@ -249,24 +249,23 @@ export abstract class SubgraphIONodeBase<TSlot extends SubgraphInput | SubgraphO
|
||||
size[1] = currentY - y + roundedRadius
|
||||
}
|
||||
|
||||
draw(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void {
|
||||
draw(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void {
|
||||
const { lineWidth, strokeStyle, fillStyle, font, textBaseline } = ctx
|
||||
this.drawProtected(ctx, colorContext)
|
||||
this.drawProtected(ctx, colorContext, fromSlot, editorAlpha)
|
||||
Object.assign(ctx, { lineWidth, strokeStyle, fillStyle, font, textBaseline })
|
||||
}
|
||||
|
||||
/** @internal Leaves {@link ctx} dirty. */
|
||||
protected abstract drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void
|
||||
protected abstract drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void
|
||||
|
||||
/** @internal Leaves {@link ctx} dirty. */
|
||||
protected drawSlots(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void {
|
||||
protected drawSlots(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void {
|
||||
ctx.fillStyle = "#AAA"
|
||||
ctx.font = "12px Arial"
|
||||
ctx.textBaseline = "middle"
|
||||
|
||||
for (const slot of this.allSlots) {
|
||||
slot.draw({ ctx, colorContext })
|
||||
slot.drawLabel(ctx)
|
||||
slot.draw({ ctx, colorContext, fromSlot, editorAlpha })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import type { SubgraphInputNode } from "./SubgraphInputNode"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { SubgraphInputEventMap } from "@/infrastructure/SubgraphInputEventMap"
|
||||
import type { INodeInputSlot, Point, ReadOnlyRect } from "@/interfaces"
|
||||
import type { INodeInputSlot, INodeOutputSlot, Point, ReadOnlyRect } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { RerouteId } from "@/Reroute"
|
||||
import type { IBaseWidget } from "@/types/widgets"
|
||||
|
||||
import { CustomEventTarget } from "@/infrastructure/CustomEventTarget"
|
||||
import { LiteGraph } from "@/litegraph"
|
||||
import { LLink } from "@/LLink"
|
||||
import { NodeSlotType } from "@/types/globalEnums"
|
||||
|
||||
import { SubgraphSlot } from "./SubgraphSlotBase"
|
||||
import { isNodeSlot, isSubgraphOutput } from "./subgraphUtils"
|
||||
|
||||
/**
|
||||
* An input "slot" from a parent graph into a subgraph.
|
||||
@@ -211,4 +214,21 @@ export class SubgraphInput extends SubgraphSlot {
|
||||
pos[0] = right - height * 0.5
|
||||
pos[1] = top + height * 0.5
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slot is a valid target for a connection from the given slot.
|
||||
* For SubgraphInput (which acts as an output inside the subgraph),
|
||||
* the fromSlot should be an input slot.
|
||||
*/
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean {
|
||||
if (isNodeSlot(fromSlot)) {
|
||||
return "link" in fromSlot && LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
}
|
||||
|
||||
if (isSubgraphOutput(fromSlot)) {
|
||||
return LiteGraph.isValidConnection(this.type, fromSlot.type)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { LinkConnector } from "@/canvas/LinkConnector"
|
||||
import type { CanvasPointer } from "@/CanvasPointer"
|
||||
import type { DefaultConnectionColors, INodeInputSlot, ISlotType, Positionable } from "@/interfaces"
|
||||
import type { DefaultConnectionColors, INodeInputSlot, INodeOutputSlot, ISlotType, Positionable } from "@/interfaces"
|
||||
import type { LGraphNode, NodeId } from "@/LGraphNode"
|
||||
import type { RerouteId } from "@/Reroute"
|
||||
import type { CanvasPointerEvent } from "@/types/events"
|
||||
@@ -170,7 +171,7 @@ export class SubgraphInputNode extends SubgraphIONodeBase<SubgraphInput> impleme
|
||||
)
|
||||
}
|
||||
|
||||
override drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void {
|
||||
override drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void {
|
||||
const { roundedRadius } = SubgraphIONodeBase
|
||||
const transform = ctx.getTransform()
|
||||
|
||||
@@ -194,6 +195,6 @@ export class SubgraphInputNode extends SubgraphIONodeBase<SubgraphInput> impleme
|
||||
// Restore context
|
||||
ctx.setTransform(transform)
|
||||
|
||||
this.drawSlots(ctx, colorContext)
|
||||
this.drawSlots(ctx, colorContext, fromSlot, editorAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphOutputNode } from "./SubgraphOutputNode"
|
||||
import type { INodeOutputSlot, Point, ReadOnlyRect } from "@/interfaces"
|
||||
import type { INodeInputSlot, INodeOutputSlot, Point, ReadOnlyRect } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { RerouteId } from "@/Reroute"
|
||||
|
||||
import { LiteGraph } from "@/litegraph"
|
||||
import { LLink } from "@/LLink"
|
||||
import { NodeSlotType } from "@/types/globalEnums"
|
||||
import { removeFromArray } from "@/utils/collections"
|
||||
|
||||
import { SubgraphSlot } from "./SubgraphSlotBase"
|
||||
import { isNodeSlot, isSubgraphInput } from "./subgraphUtils"
|
||||
|
||||
/**
|
||||
* An output "slot" from a subgraph to a parent graph.
|
||||
@@ -26,6 +29,9 @@ export class SubgraphOutput extends SubgraphSlot {
|
||||
override connect(slot: INodeOutputSlot, node: LGraphNode, afterRerouteId?: RerouteId): LLink | undefined {
|
||||
const { subgraph } = this.parent
|
||||
|
||||
// Validate type compatibility
|
||||
if (!LiteGraph.isValidConnection(slot.type, this.type)) return
|
||||
|
||||
// Allow nodes to block connection
|
||||
const outputIndex = node.outputs.indexOf(slot)
|
||||
if (outputIndex === -1) throw new Error("Slot is not an output of the given node")
|
||||
@@ -111,4 +117,21 @@ export class SubgraphOutput extends SubgraphSlot {
|
||||
pos[0] = left + height * 0.5
|
||||
pos[1] = top + height * 0.5
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this slot is a valid target for a connection from the given slot.
|
||||
* For SubgraphOutput (which acts as an input inside the subgraph),
|
||||
* the fromSlot should be an output slot.
|
||||
*/
|
||||
override isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean {
|
||||
if (isNodeSlot(fromSlot)) {
|
||||
return "links" in fromSlot && LiteGraph.isValidConnection(fromSlot.type, this.type)
|
||||
}
|
||||
|
||||
if (isSubgraphInput(fromSlot)) {
|
||||
return LiteGraph.isValidConnection(fromSlot.type, this.type)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { LinkConnector } from "@/canvas/LinkConnector"
|
||||
import type { CanvasPointer } from "@/CanvasPointer"
|
||||
import type { DefaultConnectionColors, ISlotType, Positionable } from "@/interfaces"
|
||||
import type { INodeOutputSlot } from "@/interfaces"
|
||||
import type { DefaultConnectionColors, INodeInputSlot, INodeOutputSlot, ISlotType, Positionable } from "@/interfaces"
|
||||
import type { LGraphNode, NodeId } from "@/LGraphNode"
|
||||
import type { LLink } from "@/LLink"
|
||||
import type { RerouteId } from "@/Reroute"
|
||||
@@ -90,7 +90,7 @@ export class SubgraphOutputNode extends SubgraphIONodeBase<SubgraphOutput> imple
|
||||
return findFreeSlotOfType(this.slots, type, slot => slot.linkIds.length > 0)?.slot
|
||||
}
|
||||
|
||||
override drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors): void {
|
||||
override drawProtected(ctx: CanvasRenderingContext2D, colorContext: DefaultConnectionColors, fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput, editorAlpha?: number): void {
|
||||
const { roundedRadius } = SubgraphIONodeBase
|
||||
const transform = ctx.getTransform()
|
||||
|
||||
@@ -114,6 +114,6 @@ export class SubgraphOutputNode extends SubgraphIONodeBase<SubgraphOutput> imple
|
||||
// Restore context
|
||||
ctx.setTransform(transform)
|
||||
|
||||
this.drawSlots(ctx, colorContext)
|
||||
this.drawSlots(ctx, colorContext, fromSlot, editorAlpha)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphInputNode } from "./SubgraphInputNode"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { SubgraphOutputNode } from "./SubgraphOutputNode"
|
||||
import type { DefaultConnectionColors, Hoverable, INodeInputSlot, INodeOutputSlot, Point, ReadOnlyRect, ReadOnlySize } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
@@ -19,6 +21,8 @@ export interface SubgraphSlotDrawOptions {
|
||||
ctx: CanvasRenderingContext2D
|
||||
colorContext: DefaultConnectionColors
|
||||
lowQuality?: boolean
|
||||
fromSlot?: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput
|
||||
editorAlpha?: number
|
||||
}
|
||||
|
||||
/** Shared base class for the slots used on Subgraph . */
|
||||
@@ -132,22 +136,32 @@ export abstract class SubgraphSlot extends SlotBase implements SubgraphIO, Hover
|
||||
this.linkIds.length = 0
|
||||
}
|
||||
|
||||
/** @remarks Leaves the context dirty. */
|
||||
drawLabel(ctx: CanvasRenderingContext2D): void {
|
||||
if (!this.displayName) return
|
||||
|
||||
const [x, y] = this.labelPos
|
||||
ctx.fillStyle = this.isPointerOver ? "white" : (LiteGraph.NODE_TEXT_COLOR || "#AAA")
|
||||
|
||||
ctx.fillText(this.displayName, x, y)
|
||||
}
|
||||
/**
|
||||
* Checks if this slot is a valid target for a connection from the given slot.
|
||||
* @param fromSlot The slot that is being dragged to connect to this slot.
|
||||
* @returns true if the connection is valid, false otherwise.
|
||||
*/
|
||||
abstract isValidTarget(fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput): boolean
|
||||
|
||||
/** @remarks Leaves the context dirty. */
|
||||
draw({ ctx, colorContext, lowQuality }: SubgraphSlotDrawOptions): void {
|
||||
draw({ ctx, colorContext, lowQuality, fromSlot, editorAlpha = 1 }: SubgraphSlotDrawOptions): void {
|
||||
// Assertion: SlotShape is a subset of RenderShape
|
||||
const shape = this.shape as unknown as SlotShape
|
||||
const { isPointerOver, pos: [x, y] } = this
|
||||
|
||||
// Check if this slot is a valid target for the current dragging connection
|
||||
const isValidTarget = fromSlot ? this.isValidTarget(fromSlot) : true
|
||||
const isValid = !fromSlot || isValidTarget
|
||||
|
||||
// Only highlight if the slot is valid AND mouse is over it
|
||||
const highlight = isValid && isPointerOver
|
||||
|
||||
// Save current alpha
|
||||
const previousAlpha = ctx.globalAlpha
|
||||
|
||||
// Set opacity based on validity when dragging a connection
|
||||
ctx.globalAlpha = isValid ? editorAlpha : 0.4 * editorAlpha
|
||||
|
||||
ctx.beginPath()
|
||||
|
||||
// Default rendering for circle, hollow circle.
|
||||
@@ -161,17 +175,28 @@ export abstract class SubgraphSlot extends SlotBase implements SubgraphIO, Hover
|
||||
ctx.lineWidth = 3
|
||||
ctx.strokeStyle = color
|
||||
|
||||
const radius = isPointerOver ? 4 : 3
|
||||
const radius = highlight ? 4 : 3
|
||||
ctx.arc(x, y, radius, 0, Math.PI * 2)
|
||||
ctx.stroke()
|
||||
} else {
|
||||
// Normal circle
|
||||
ctx.fillStyle = color
|
||||
|
||||
const radius = isPointerOver ? 5 : 4
|
||||
const radius = highlight ? 5 : 4
|
||||
ctx.arc(x, y, radius, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
}
|
||||
|
||||
// Draw label with current opacity
|
||||
if (this.displayName) {
|
||||
const [labelX, labelY] = this.labelPos
|
||||
// Also apply highlight logic to text color
|
||||
ctx.fillStyle = highlight ? "white" : (LiteGraph.NODE_TEXT_COLOR || "#AAA")
|
||||
ctx.fillText(this.displayName, labelX, labelY)
|
||||
}
|
||||
|
||||
// Restore alpha
|
||||
ctx.globalAlpha = previousAlpha
|
||||
}
|
||||
|
||||
asSerialisable(): SubgraphIO {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { INodeOutputSlot, Positionable } from "@/interfaces"
|
||||
import type { SubgraphInput } from "./SubgraphInput"
|
||||
import type { SubgraphOutput } from "./SubgraphOutput"
|
||||
import type { INodeInputSlot, INodeOutputSlot, Positionable } from "@/interfaces"
|
||||
import type { LGraph } from "@/LGraph"
|
||||
import type { ISerialisedNode, SerialisableLLink, SubgraphIO } from "@/types/serialisation"
|
||||
|
||||
@@ -336,3 +338,33 @@ export function mapSubgraphOutputsAndLinks(resolvedOutputLinks: ResolvedConnecti
|
||||
}
|
||||
return outputs
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if a slot is a SubgraphInput.
|
||||
* @param slot The slot to check
|
||||
* @returns true if the slot is a SubgraphInput
|
||||
*/
|
||||
export function isSubgraphInput(slot: unknown): slot is SubgraphInput {
|
||||
return slot != null && typeof slot === "object" && "parent" in slot &&
|
||||
slot.parent instanceof SubgraphInputNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if a slot is a SubgraphOutput.
|
||||
* @param slot The slot to check
|
||||
* @returns true if the slot is a SubgraphOutput
|
||||
*/
|
||||
export function isSubgraphOutput(slot: unknown): slot is SubgraphOutput {
|
||||
return slot != null && typeof slot === "object" && "parent" in slot &&
|
||||
slot.parent instanceof SubgraphOutputNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if a slot is a regular node slot (INodeInputSlot or INodeOutputSlot).
|
||||
* @param slot The slot to check
|
||||
* @returns true if the slot is a regular node slot
|
||||
*/
|
||||
export function isNodeSlot(slot: unknown): slot is INodeInputSlot | INodeOutputSlot {
|
||||
return slot != null && typeof slot === "object" &&
|
||||
("link" in slot || "links" in slot)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user