mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 14:27:40 +00:00
443 lines
14 KiB
TypeScript
443 lines
14 KiB
TypeScript
import type { ContextMenu } from "./ContextMenu"
|
|
import type { LGraphNode, NodeId } from "./LGraphNode"
|
|
import type { LinkId, LLink } from "./LLink"
|
|
import type { Reroute, RerouteId } from "./Reroute"
|
|
import type { LinkDirection, RenderShape } from "./types/globalEnums"
|
|
|
|
export type Dictionary<T> = { [key: string]: T }
|
|
|
|
/** Allows all properties to be null. The same as `Partial<T>`, but adds null instead of undefined. */
|
|
export type NullableProperties<T> = {
|
|
[P in keyof T]: T[P] | null
|
|
}
|
|
|
|
/**
|
|
* If {@link T} is `null` or `undefined`, evaluates to {@link Result}. Otherwise, evaluates to {@link T}.
|
|
* Useful for functions that return e.g. `undefined` when a param is nullish.
|
|
*/
|
|
export type WhenNullish<T, Result> = T & {} | (T extends null ? Result : T extends undefined ? Result : T & {})
|
|
|
|
/** A type with each of the {@link Properties} made optional. */
|
|
export type OptionalProps<T, Properties extends keyof T> = Omit<T, Properties> & { [K in Properties]?: T[K] }
|
|
|
|
/** A type with each of the {@link Properties} marked as required. */
|
|
export type RequiredProps<T, Properties extends keyof T> = Omit<T, Properties> & { [K in Properties]-?: T[K] }
|
|
|
|
/** Bitwise AND intersection of two types; returns a new, non-union type that includes only properties that exist on both types. */
|
|
export type SharedIntersection<T1, T2> = {
|
|
[P in keyof T1 as P extends keyof T2 ? P : never]: T1[P]
|
|
} & {
|
|
[P in keyof T2 as P extends keyof T1 ? P : never]: T2[P]
|
|
}
|
|
|
|
export type CanvasColour = string | CanvasGradient | CanvasPattern
|
|
|
|
/**
|
|
* Any object that has a {@link boundingRect}.
|
|
*/
|
|
export interface HasBoundingRect {
|
|
/**
|
|
* A rectangle that represents the outer edges of the item.
|
|
*
|
|
* Used for various calculations, such as overlap, selective rendering, and click checks.
|
|
* For most items, this is cached position & size as `x, y, width, height`.
|
|
* Some items (such as nodes and slots) may extend above and/or to the left of their {@link pos}.
|
|
* @readonly
|
|
* @see {@link move}
|
|
*/
|
|
readonly boundingRect: ReadOnlyRect
|
|
}
|
|
|
|
/** An object containing a set of child objects */
|
|
export interface Parent<TChild> {
|
|
/** All objects owned by the parent object. */
|
|
readonly children?: ReadonlySet<TChild>
|
|
}
|
|
|
|
/**
|
|
* An object that can be positioned, selected, and moved.
|
|
*
|
|
* May contain other {@link Positionable} objects.
|
|
*/
|
|
export interface Positionable extends Parent<Positionable>, HasBoundingRect {
|
|
readonly id: NodeId | RerouteId | number
|
|
/**
|
|
* Position in graph coordinates. This may be the top-left corner,
|
|
* the centre, or another point depending on concrete type.
|
|
* @default 0,0
|
|
*/
|
|
readonly pos: Point
|
|
/** true if this object is part of the selection, otherwise false. */
|
|
selected?: boolean
|
|
|
|
/** See {@link IPinnable.pinned} */
|
|
readonly pinned?: boolean
|
|
|
|
/**
|
|
* Adds a delta to the current position.
|
|
* @param deltaX X value to add to current position
|
|
* @param deltaY Y value to add to current position
|
|
* @param skipChildren If true, any child objects like group contents will not be moved
|
|
*/
|
|
move(deltaX: number, deltaY: number, skipChildren?: boolean): void
|
|
|
|
/**
|
|
* Snaps this item to a grid.
|
|
*
|
|
* Position values are rounded to the nearest multiple of {@link snapTo}.
|
|
* @param snapTo The size of the grid to align to
|
|
* @returns `true` if it moved, or `false` if the snap was rejected (e.g. `pinned`)
|
|
*/
|
|
snapToGrid(snapTo: number): boolean
|
|
|
|
/** Called whenever the item is selected */
|
|
onSelected?(): void
|
|
/** Called whenever the item is deselected */
|
|
onDeselected?(): void
|
|
}
|
|
|
|
/**
|
|
* A color option to customize the color of {@link LGraphNode} or {@link LGraphGroup}.
|
|
* @see {@link LGraphCanvas.node_colors}
|
|
*/
|
|
export interface ColorOption {
|
|
color: string
|
|
bgcolor: string
|
|
groupcolor: string
|
|
}
|
|
|
|
/**
|
|
* An object that can be colored with a {@link ColorOption}.
|
|
*/
|
|
export interface IColorable {
|
|
setColorOption(colorOption: ColorOption | null): void
|
|
getColorOption(): ColorOption | null
|
|
}
|
|
|
|
/**
|
|
* An object that can be pinned.
|
|
*
|
|
* Prevents the object being accidentally moved or resized by mouse interaction.
|
|
*/
|
|
export interface IPinnable {
|
|
readonly pinned: boolean
|
|
pin(value?: boolean): void
|
|
unpin(): void
|
|
}
|
|
|
|
export interface ReadonlyLinkNetwork {
|
|
readonly links: ReadonlyMap<LinkId, LLink>
|
|
readonly reroutes: ReadonlyMap<RerouteId, Reroute>
|
|
readonly floatingLinks: ReadonlyMap<LinkId, LLink>
|
|
getNodeById(id: NodeId | null | undefined): LGraphNode | null
|
|
getLink(id: null | undefined): undefined
|
|
getLink(id: LinkId | null | undefined): LLink | undefined
|
|
getReroute(parentId: null | undefined): undefined
|
|
getReroute(parentId: RerouteId | null | undefined): Reroute | undefined
|
|
}
|
|
|
|
/**
|
|
* Contains a list of links, reroutes, and nodes.
|
|
*/
|
|
export interface LinkNetwork extends ReadonlyLinkNetwork {
|
|
readonly links: Map<LinkId, LLink>
|
|
readonly reroutes: Map<RerouteId, Reroute>
|
|
addFloatingLink(link: LLink): LLink
|
|
removeReroute(id: number): unknown
|
|
removeFloatingLink(link: LLink): void
|
|
}
|
|
|
|
/**
|
|
* Locates graph items.
|
|
*/
|
|
export interface ItemLocator {
|
|
getNodeOnPos(x: number, y: number, nodeList?: LGraphNode[]): LGraphNode | null
|
|
getRerouteOnPos(x: number, y: number): Reroute | undefined
|
|
}
|
|
|
|
/** Contains a cached 2D canvas path and a centre point, with an optional forward angle. */
|
|
export interface LinkSegment {
|
|
/** Link / reroute ID */
|
|
readonly id: LinkId | RerouteId
|
|
/** The {@link id} of the reroute that this segment starts from (output side), otherwise `undefined`. */
|
|
readonly parentId?: RerouteId
|
|
|
|
/** The last canvas 2D path that was used to render this segment */
|
|
path?: Path2D
|
|
/** Centre point of the {@link path}. Calculated during render only - can be inaccurate */
|
|
readonly _pos: Float32Array
|
|
/**
|
|
* Y-forward along the {@link path} from its centre point, in radians.
|
|
* `undefined` if using circles for link centres.
|
|
* Calculated during render only - can be inaccurate.
|
|
*/
|
|
_centreAngle?: number
|
|
|
|
/** Whether the link is currently being moved. @internal */
|
|
_dragging?: boolean
|
|
|
|
/** Output node ID */
|
|
readonly origin_id: NodeId | undefined
|
|
/** Output slot index */
|
|
readonly origin_slot: number | undefined
|
|
}
|
|
|
|
export interface IInputOrOutput {
|
|
// If an input, this will be defined
|
|
input?: INodeInputSlot | null
|
|
// If an output, this will be defined
|
|
output?: INodeOutputSlot | null
|
|
}
|
|
|
|
export interface IFoundSlot extends IInputOrOutput {
|
|
// Slot index
|
|
slot: number
|
|
// Centre point of the rendered slot connection
|
|
link_pos: Point
|
|
}
|
|
|
|
/** A point represented as `[x, y]` co-ordinates */
|
|
export type Point = [x: number, y: number] | Float32Array | Float64Array
|
|
|
|
/** A size represented as `[width, height]` */
|
|
export type Size = [width: number, height: number] | Float32Array | Float64Array
|
|
|
|
/** A very firm array */
|
|
type ArRect = [x: number, y: number, width: number, height: number]
|
|
|
|
/** A rectangle starting at top-left coordinates `[x, y, width, height]` */
|
|
export type Rect = ArRect | Float32Array | Float64Array
|
|
|
|
/** A point represented as `[x, y]` co-ordinates that will not be modified */
|
|
export type ReadOnlyPoint =
|
|
| readonly [x: number, y: number]
|
|
| ReadOnlyTypedArray<Float32Array>
|
|
| ReadOnlyTypedArray<Float64Array>
|
|
|
|
/** A size represented as `[width, height]` that will not be modified */
|
|
export type ReadOnlySize =
|
|
| readonly [width: number, height: number]
|
|
| ReadOnlyTypedArray<Float32Array>
|
|
| ReadOnlyTypedArray<Float64Array>
|
|
|
|
/** A rectangle starting at top-left coordinates `[x, y, width, height]` that will not be modified */
|
|
export type ReadOnlyRect =
|
|
| readonly [x: number, y: number, width: number, height: number]
|
|
| ReadOnlyTypedArray<Float32Array>
|
|
| ReadOnlyTypedArray<Float64Array>
|
|
|
|
type TypedArrays =
|
|
| Int8Array
|
|
| Uint8Array
|
|
| Uint8ClampedArray
|
|
| Int16Array
|
|
| Uint16Array
|
|
| Int32Array
|
|
| Uint32Array
|
|
| Float32Array
|
|
| Float64Array
|
|
|
|
type TypedBigIntArrays = BigInt64Array | BigUint64Array
|
|
export type ReadOnlyTypedArray<T extends TypedArrays | TypedBigIntArrays> =
|
|
Omit<Readonly<T>, "fill" | "copyWithin" | "reverse" | "set" | "sort" | "subarray">
|
|
|
|
/** Union of property names that are of type Match */
|
|
export type KeysOfType<T, Match> = Exclude<{ [P in keyof T]: T[P] extends Match ? P : never }[keyof T], undefined>
|
|
|
|
/** A new type that contains only the properties of T that are of type Match */
|
|
export type PickByType<T, Match> = { [P in keyof T]: Extract<T[P], Match> }
|
|
|
|
/** The names of all (optional) methods and functions in T */
|
|
export type MethodNames<T> = KeysOfType<T, ((...args: any) => any) | undefined>
|
|
|
|
export interface IBoundaryNodes {
|
|
top: LGraphNode
|
|
right: LGraphNode
|
|
bottom: LGraphNode
|
|
left: LGraphNode
|
|
}
|
|
|
|
export type Direction = "top" | "bottom" | "left" | "right"
|
|
|
|
/** Resize handle positions (compass points) */
|
|
export type CompassDirection = "N" | "NE" | "E" | "SE" | "S" | "SW" | "W" | "NW"
|
|
|
|
/**
|
|
* A string that represents a specific data / slot type, e.g. `STRING`.
|
|
*
|
|
* Can be comma-delimited to specify multiple allowed types, e.g. `STRING,INT`.
|
|
*/
|
|
export type ISlotType = number | string
|
|
|
|
export interface INodeSlot extends HasBoundingRect {
|
|
/**
|
|
* The name of the slot in English.
|
|
* Will be included in the serialized data.
|
|
*/
|
|
name: string
|
|
/**
|
|
* The localized name of the slot to display in the UI.
|
|
* Takes higher priority than {@link name} if set.
|
|
* Will be included in the serialized data.
|
|
*/
|
|
localized_name?: string
|
|
/**
|
|
* The name of the slot to display in the UI, modified by the user.
|
|
* Takes higher priority than {@link display_name} if set.
|
|
* Will be included in the serialized data.
|
|
*/
|
|
label?: string
|
|
|
|
type: ISlotType
|
|
dir?: LinkDirection
|
|
removable?: boolean
|
|
shape?: RenderShape
|
|
color_off?: CanvasColour
|
|
color_on?: CanvasColour
|
|
locked?: boolean
|
|
nameLocked?: boolean
|
|
pos?: Point
|
|
/** @remarks Automatically calculated; not included in serialisation. */
|
|
boundingRect: Rect
|
|
/**
|
|
* A list of floating link IDs that are connected to this slot.
|
|
* This is calculated at runtime; it is **not** serialized.
|
|
*/
|
|
_floatingLinks?: Set<LLink>
|
|
/**
|
|
* Whether the slot has errors. It is **not** serialized.
|
|
*/
|
|
hasErrors?: boolean
|
|
}
|
|
|
|
export interface INodeFlags {
|
|
skip_repeated_outputs?: boolean
|
|
allow_interaction?: boolean
|
|
pinned?: boolean
|
|
collapsed?: boolean
|
|
/** Configuration setting for {@link LGraphNode.connectInputToOutput} */
|
|
keepAllLinksOnBypass?: boolean
|
|
}
|
|
|
|
/**
|
|
* A widget that is linked to a slot.
|
|
*
|
|
* This is set by the ComfyUI_frontend logic. See
|
|
* https://github.com/Comfy-Org/ComfyUI_frontend/blob/b80e0e1a3c74040f328c4e344326c969c97f67e0/src/extensions/core/widgetInputs.ts#L659
|
|
*/
|
|
export interface IWidgetLocator {
|
|
name: string
|
|
[key: string | symbol]: unknown
|
|
}
|
|
|
|
export interface INodeInputSlot extends INodeSlot {
|
|
link: LinkId | null
|
|
widget?: IWidgetLocator
|
|
}
|
|
|
|
export interface IWidgetInputSlot extends INodeInputSlot {
|
|
widget: IWidgetLocator
|
|
}
|
|
|
|
export interface INodeOutputSlot extends INodeSlot {
|
|
links: LinkId[] | null
|
|
_data?: unknown
|
|
slot_index?: number
|
|
}
|
|
|
|
/** Links */
|
|
export interface ConnectingLink extends IInputOrOutput {
|
|
node: LGraphNode
|
|
slot: number
|
|
pos: Point
|
|
direction?: LinkDirection
|
|
afterRerouteId?: RerouteId
|
|
/** The first reroute on a chain */
|
|
firstRerouteId?: RerouteId
|
|
/** The link being moved, or `undefined` if creating a new link. */
|
|
link?: LLink
|
|
}
|
|
|
|
interface IContextMenuBase {
|
|
title?: string
|
|
className?: string
|
|
}
|
|
|
|
/** ContextMenu */
|
|
export interface IContextMenuOptions<TValue = unknown, TExtra = unknown> extends IContextMenuBase {
|
|
ignore_item_callbacks?: boolean
|
|
parentMenu?: ContextMenu<TValue>
|
|
event?: MouseEvent
|
|
extra?: TExtra
|
|
/** @deprecated Context menu scrolling is now controlled by the browser */
|
|
scroll_speed?: number
|
|
left?: number
|
|
top?: number
|
|
/** @deprecated Context menus no longer scale using transform */
|
|
scale?: number
|
|
node?: LGraphNode
|
|
autoopen?: boolean
|
|
callback?(
|
|
value?: string | IContextMenuValue<TValue>,
|
|
options?: unknown,
|
|
event?: MouseEvent,
|
|
previous_menu?: ContextMenu<TValue>,
|
|
extra?: unknown,
|
|
): void | boolean
|
|
}
|
|
|
|
export interface IContextMenuValue<TValue = unknown, TExtra = unknown, TCallbackValue = unknown> extends IContextMenuBase {
|
|
value?: TValue
|
|
content: string | undefined
|
|
has_submenu?: boolean
|
|
disabled?: boolean
|
|
submenu?: IContextMenuSubmenu<TValue>
|
|
property?: string
|
|
type?: string
|
|
slot?: IFoundSlot
|
|
callback?(
|
|
this: ContextMenuDivElement<TValue>,
|
|
value?: TCallbackValue,
|
|
options?: unknown,
|
|
event?: MouseEvent,
|
|
previous_menu?: ContextMenu<TValue>,
|
|
extra?: TExtra,
|
|
): void | boolean
|
|
}
|
|
|
|
export interface IContextMenuSubmenu<TValue = unknown> extends IContextMenuOptions<TValue> {
|
|
options: ConstructorParameters<typeof ContextMenu<TValue>>[0]
|
|
}
|
|
|
|
export interface ContextMenuDivElement<TValue = unknown> extends HTMLDivElement {
|
|
value?: string | IContextMenuValue<TValue>
|
|
onclick_callback?: never
|
|
}
|
|
|
|
export type INodeSlotContextItem = [string, ISlotType, Partial<INodeInputSlot & INodeOutputSlot>]
|
|
|
|
export interface DefaultConnectionColors {
|
|
getConnectedColor(type: ISlotType): CanvasColour
|
|
getDisconnectedColor(type: ISlotType): CanvasColour
|
|
}
|
|
/**
|
|
* Shorthand for {@link Parameters} of optional callbacks.
|
|
* @example
|
|
* ```ts
|
|
* const { onClick } = CustomClass.prototype
|
|
* CustomClass.prototype.onClick = function (...args: CallbackParams<typeof onClick>) {
|
|
* const r = onClick?.apply(this, args)
|
|
* // ...
|
|
* return r
|
|
* }
|
|
* ```
|
|
*/
|
|
export type CallbackParams<T extends ((...args: any) => any) | undefined> =
|
|
Parameters<Exclude<T, undefined>>
|
|
|
|
/**
|
|
* Shorthand for {@link ReturnType} of optional callbacks.
|
|
* @see {@link CallbackParams}
|
|
*/
|
|
export type CallbackReturn<T extends ((...args: any) => any) | undefined> = ReturnType<Exclude<T, undefined>>
|