mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-27 10:14:06 +00:00
[TS] Improve types and (#1043)
This commit is contained in:
@@ -1477,11 +1477,12 @@ export class LGraph implements LinkNetwork, BaseLGraph, Serialisable<Serialisabl
|
||||
|
||||
// State
|
||||
if (data.state) {
|
||||
const { state: { lastGroupId, lastLinkId, lastNodeId, lastRerouteId } } = data
|
||||
if (lastGroupId != null) this.state.lastGroupId = lastGroupId
|
||||
if (lastLinkId != null) this.state.lastLinkId = lastLinkId
|
||||
if (lastNodeId != null) this.state.lastNodeId = lastNodeId
|
||||
if (lastRerouteId != null) this.state.lastRerouteId = lastRerouteId
|
||||
const { lastGroupId, lastLinkId, lastNodeId, lastRerouteId } = data.state
|
||||
const { state } = this
|
||||
if (lastGroupId != null) state.lastGroupId = lastGroupId
|
||||
if (lastLinkId != null) state.lastLinkId = lastLinkId
|
||||
if (lastNodeId != null) state.lastNodeId = lastNodeId
|
||||
if (lastRerouteId != null) state.lastRerouteId = lastRerouteId
|
||||
}
|
||||
|
||||
// Links
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ContextMenu } from "./ContextMenu"
|
||||
import type { LGraphCanvasEventMap } from "./infrastructure/LGraphCanvasEventMap"
|
||||
import type {
|
||||
CanvasColour,
|
||||
ColorOption,
|
||||
@@ -27,7 +28,6 @@ import type {
|
||||
} from "./interfaces"
|
||||
import type { LGraph } from "./LGraph"
|
||||
import type {
|
||||
CanvasEventDetail,
|
||||
CanvasMouseEvent,
|
||||
CanvasPointerEvent,
|
||||
CanvasPointerExtensions,
|
||||
@@ -3151,7 +3151,7 @@ export class LGraphCanvas {
|
||||
)
|
||||
}
|
||||
|
||||
emitEvent(detail: CanvasEventDetail): void {
|
||||
emitEvent(detail: LGraphCanvasEventMap["litegraph:canvas"]): void {
|
||||
this.canvas.dispatchEvent(
|
||||
new CustomEvent("litegraph:canvas", {
|
||||
bubbles: true,
|
||||
|
||||
@@ -1421,13 +1421,15 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
|
||||
* @param type string defining the output type ("vec3","number",...)
|
||||
* @param extra_info this can be used to have special properties of an output (label, special color, position, etc)
|
||||
*/
|
||||
addOutput(
|
||||
addOutput<TProperties extends Partial<INodeOutputSlot>>(
|
||||
name: string,
|
||||
type: ISlotType,
|
||||
extra_info?: Partial<INodeOutputSlot>,
|
||||
): INodeOutputSlot {
|
||||
const output = new NodeOutputSlot({ name, type, links: null }, this)
|
||||
if (extra_info) Object.assign(output, extra_info)
|
||||
extra_info?: TProperties,
|
||||
): INodeOutputSlot & TProperties {
|
||||
const output = Object.assign(
|
||||
new NodeOutputSlot({ name, type, links: null }, this),
|
||||
extra_info,
|
||||
)
|
||||
|
||||
this.outputs ||= []
|
||||
this.outputs.push(output)
|
||||
@@ -1470,10 +1472,13 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
|
||||
* @param type string defining the input type ("vec3","number",...), it its a generic one use 0
|
||||
* @param extra_info this can be used to have special properties of an input (label, color, position, etc)
|
||||
*/
|
||||
addInput(name: string, type: ISlotType, extra_info?: Partial<INodeInputSlot>): INodeInputSlot {
|
||||
type = type || 0
|
||||
const input = new NodeInputSlot({ name: name, type: type, link: null }, this)
|
||||
if (extra_info) Object.assign(input, extra_info)
|
||||
addInput<TProperties extends Partial<INodeInputSlot>>(name: string, type: ISlotType, extra_info?: TProperties): INodeInputSlot & TProperties {
|
||||
type ||= 0
|
||||
|
||||
const input = Object.assign(
|
||||
new NodeInputSlot({ name, type, link: null }, this),
|
||||
extra_info,
|
||||
)
|
||||
|
||||
this.inputs ||= []
|
||||
this.inputs.push(input)
|
||||
|
||||
@@ -22,7 +22,7 @@ export type SerialisedLLinkArray = [
|
||||
type: ISlotType,
|
||||
]
|
||||
|
||||
interface ResolvedConnection {
|
||||
export interface ResolvedConnection {
|
||||
inputNode: LGraphNode | undefined
|
||||
outputNode: LGraphNode | undefined
|
||||
input: INodeInputSlot | undefined
|
||||
|
||||
@@ -1,21 +1,84 @@
|
||||
/** {@link Omit} all properties that evaluate to `never`. */
|
||||
type NeverNever<T> = {
|
||||
[K in keyof T as T[K] extends never ? never : K]: T[K]
|
||||
}
|
||||
|
||||
/** {@link Pick} only properties that evaluate to `never`. */
|
||||
type PickNevers<T> = {
|
||||
[K in keyof T as T[K] extends never ? K : never]: T[K]
|
||||
}
|
||||
import type { NeverNever, PickNevers } from "@/types/utility"
|
||||
|
||||
type EventListeners<T> = {
|
||||
readonly [K in keyof T]: ((this: EventTarget, ev: CustomEvent<T[K]>) => any) | EventListenerObject | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Has strongly-typed overrides of {@link EventTarget.addEventListener} and {@link EventTarget.removeEventListener}.
|
||||
*/
|
||||
export interface ICustomEventTarget<
|
||||
EventMap extends Record<Keys, unknown>,
|
||||
Keys extends keyof EventMap & string = keyof EventMap & string,
|
||||
> {
|
||||
addEventListener<K extends Keys>(
|
||||
type: K,
|
||||
listener: EventListeners<EventMap>[K],
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void
|
||||
|
||||
removeEventListener<K extends Keys>(
|
||||
type: K,
|
||||
listener: EventListeners<EventMap>[K],
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void
|
||||
|
||||
/** @deprecated Use {@link dispatch}. */
|
||||
dispatchEvent(event: never): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Capable of dispatching strongly-typed events via {@link dispatch}.
|
||||
* Overloads are used to ensure detail param is correctly optional.
|
||||
*/
|
||||
export interface CustomEventDispatcher<
|
||||
EventMap extends Record<Keys, unknown>,
|
||||
Keys extends keyof EventMap & string = keyof EventMap & string,
|
||||
> {
|
||||
dispatch<T extends keyof NeverNever<EventMap>>(type: T, detail: EventMap[T]): boolean
|
||||
dispatch<T extends keyof PickNevers<EventMap>>(type: T): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* A strongly-typed, custom {@link EventTarget} that can dispatch and listen for events.
|
||||
*
|
||||
* 1. Define an event map
|
||||
* ```ts
|
||||
* export interface CustomEventMap {
|
||||
* "my-event": { message: string }
|
||||
* "simple-event": never
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* 2. Create an event emitter
|
||||
* ```ts
|
||||
* // By subclassing
|
||||
* class MyClass extends CustomEventTarget<CustomEventMap> {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* // Or simply create an instance:
|
||||
* const events = new CustomEventTarget<CustomEventMap>()
|
||||
* ```
|
||||
*
|
||||
* 3. Dispatch events
|
||||
* ```ts
|
||||
* // Extended class
|
||||
* const myClass = new MyClass()
|
||||
* myClass.dispatch("my-event", { message: "Hello, world!" })
|
||||
* myClass.dispatch("simple-event")
|
||||
*
|
||||
* // Instance
|
||||
* const events = new CustomEventTarget<CustomEventMap>()
|
||||
* events.dispatch("my-event", { message: "Hello, world!" })
|
||||
* events.dispatch("simple-event")
|
||||
* ```
|
||||
*/
|
||||
export class CustomEventTarget<
|
||||
EventMap extends Record<Keys, unknown>,
|
||||
Keys extends keyof EventMap & string = keyof EventMap & string,
|
||||
> extends EventTarget {
|
||||
>
|
||||
extends EventTarget implements ICustomEventTarget<EventMap, Keys> {
|
||||
/**
|
||||
* Type-safe event dispatching.
|
||||
* @see {@link EventTarget.dispatchEvent}
|
||||
|
||||
28
src/infrastructure/LGraphCanvasEventMap.ts
Normal file
28
src/infrastructure/LGraphCanvasEventMap.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { ConnectingLink } from "@/interfaces"
|
||||
import type { LGraphGroup } from "@/LGraphGroup"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { CanvasPointerEvent } from "@/types/events"
|
||||
|
||||
export interface LGraphCanvasEventMap {
|
||||
"litegraph:canvas":
|
||||
| { subType: "before-change" | "after-change" }
|
||||
| {
|
||||
subType: "empty-release"
|
||||
originalEvent?: CanvasPointerEvent
|
||||
linkReleaseContext?: { links: ConnectingLink[] }
|
||||
}
|
||||
| {
|
||||
subType: "group-double-click"
|
||||
originalEvent?: CanvasPointerEvent
|
||||
group: LGraphGroup
|
||||
}
|
||||
| {
|
||||
subType: "empty-double-click"
|
||||
originalEvent?: CanvasPointerEvent
|
||||
}
|
||||
| {
|
||||
subType: "node-double-click"
|
||||
originalEvent?: CanvasPointerEvent
|
||||
node: LGraphNode
|
||||
}
|
||||
}
|
||||
@@ -417,3 +417,23 @@ 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>>
|
||||
|
||||
@@ -82,7 +82,6 @@ export interface LGraphNodeConstructor<T extends LGraphNode = LGraphNode> {
|
||||
title_color?: string
|
||||
title_text_color?: string
|
||||
keepAllLinksOnBypass: boolean
|
||||
nodeData: any
|
||||
}
|
||||
|
||||
// End backwards compat
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
import type { LGraphGroup } from "../LGraphGroup"
|
||||
import type { LGraphNode } from "../LGraphNode"
|
||||
import type { ConnectingLink, LinkReleaseContextExtended } from "../litegraph"
|
||||
import type { IWidget } from "./widgets"
|
||||
import type { LinkReleaseContextExtended } from "../litegraph"
|
||||
|
||||
/** For Canvas*Event - adds graph space co-ordinates (property names are shipped) */
|
||||
export interface ICanvasPosition {
|
||||
@@ -57,12 +56,9 @@ export interface CanvasDragEvent extends
|
||||
|
||||
export type CanvasEventDetail =
|
||||
| GenericEventDetail
|
||||
| DragggingCanvasEventDetail
|
||||
| ReadOnlyEventDetail
|
||||
| GroupDoubleClickEventDetail
|
||||
| NodeDoubleClickEventDetail
|
||||
| EmptyDoubleClickEventDetail
|
||||
| ConnectingWidgetLinkEventDetail
|
||||
| EmptyReleaseEventDetail
|
||||
|
||||
export interface GenericEventDetail {
|
||||
@@ -78,13 +74,6 @@ export interface EmptyReleaseEventDetail extends OriginalEvent {
|
||||
linkReleaseContext: LinkReleaseContextExtended
|
||||
}
|
||||
|
||||
export interface ConnectingWidgetLinkEventDetail {
|
||||
subType: "connectingWidgetLink"
|
||||
link: ConnectingLink
|
||||
node: LGraphNode
|
||||
widget: IWidget
|
||||
}
|
||||
|
||||
export interface EmptyDoubleClickEventDetail extends OriginalEvent {
|
||||
subType: "empty-double-click"
|
||||
}
|
||||
@@ -98,13 +87,3 @@ export interface NodeDoubleClickEventDetail extends OriginalEvent {
|
||||
subType: "node-double-click"
|
||||
node: LGraphNode
|
||||
}
|
||||
|
||||
export interface DragggingCanvasEventDetail {
|
||||
subType: "dragging-canvas"
|
||||
draggingCanvas: boolean
|
||||
}
|
||||
|
||||
export interface ReadOnlyEventDetail {
|
||||
subType: "read-only"
|
||||
readOnly: boolean
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export interface BaseExportedGraph {
|
||||
/** Unique graph ID. Automatically generated if not provided. */
|
||||
id: UUID
|
||||
revision: number
|
||||
config: LGraphConfig
|
||||
config?: LGraphConfig
|
||||
/** Details of the appearance and location of subgraphs shown in this graph. Similar to */
|
||||
subgraphs?: ExportedSubgraphInstance[]
|
||||
/** Definitions of re-usable objects that are referenced elsewhere in this exported graph. */
|
||||
@@ -161,7 +161,7 @@ export interface ISerialisedGroup {
|
||||
title: string
|
||||
bounding: number[]
|
||||
color?: string
|
||||
font_size: number
|
||||
font_size?: number
|
||||
flags?: IGraphGroupFlags
|
||||
}
|
||||
|
||||
|
||||
13
src/types/utility.ts
Normal file
13
src/types/utility.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* General-purpose, TypeScript utility types.
|
||||
*/
|
||||
|
||||
/** {@link Pick} only properties that evaluate to `never`. */
|
||||
export type PickNevers<T> = {
|
||||
[K in keyof T as T[K] extends never ? K : never]: T[K]
|
||||
}
|
||||
|
||||
/** {@link Omit} all properties that evaluate to `never`. */
|
||||
export type NeverNever<T> = {
|
||||
[K in keyof T as T[K] extends never ? never : K]: T[K]
|
||||
}
|
||||
Reference in New Issue
Block a user