[TS] Use strict mode in LGraphNode - initial (#598)

- Part of effort to convert LGraphNode to TS strict
- Adds some small runtime changes - no impact expected, but it is
possible
- Runtime changes are in separate commits from compile-time type changes
- Risk of downstream impact is low
This commit is contained in:
filtered
2025-02-26 04:19:27 +11:00
committed by GitHub
parent 0b84ca83d8
commit 4636367de2
7 changed files with 41 additions and 25 deletions

View File

@@ -35,7 +35,7 @@ export class ContextMenu {
* - ignore_item_callbacks: ignores the callback inside the item, it just calls the options.callback * - ignore_item_callbacks: ignores the callback inside the item, it just calls the options.callback
* - event: you can pass a MouseEvent, this way the ContextMenu appears in that position * - event: you can pass a MouseEvent, this way the ContextMenu appears in that position
*/ */
constructor(values: (IContextMenuValue | string)[], options: IContextMenuOptions) { constructor(values: (IContextMenuValue | string | null)[], options: IContextMenuOptions) {
options ||= {} options ||= {}
this.options = options this.options = options

View File

@@ -206,7 +206,7 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
onGetNodeMenuOptions?(options: IContextMenuValue[], node: LGraphNode): void onGetNodeMenuOptions?(options: IContextMenuValue[], node: LGraphNode): void
onNodeConnectionChange?( onNodeConnectionChange?(
nodeSlotType: ISlotType, nodeSlotType: ISlotType,
targetNode: LGraphNode, targetNode: LGraphNode | null | undefined,
slotIndex: number, slotIndex: number,
sourceNode?: LGraphNode, sourceNode?: LGraphNode,
sourceSlotIndex?: number, sourceSlotIndex?: number,
@@ -570,8 +570,11 @@ export class LGraph implements LinkNetwork, Serialisable<SerialisableGraph> {
continue continue
} }
if (set_level && (!target_node._level || target_node._level <= node._level)) { if (set_level) {
target_node._level = node._level + 1 node._level ??= 0
if (!target_node._level || target_node._level <= node._level) {
target_node._level = node._level + 1
}
} }
// mark as visited // mark as visited

View File

@@ -190,7 +190,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
// Execution order, automatically computed during run // Execution order, automatically computed during run
order?: number order?: number
mode: LGraphEventMode mode?: LGraphEventMode
last_serialization?: ISerialisedNode last_serialization?: ISerialisedNode
serialize_widgets?: boolean serialize_widgets?: boolean
/** /**
@@ -221,8 +221,9 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
/** The box color used to render the node. */ /** The box color used to render the node. */
get renderingBoxColor(): string { get renderingBoxColor(): string {
let colState = LiteGraph.node_box_coloured_by_mode && LiteGraph.NODE_MODES_COLORS[this.mode] const mode = this.mode ?? LGraphEventMode.ALWAYS
? LiteGraph.NODE_MODES_COLORS[this.mode] let colState = LiteGraph.node_box_coloured_by_mode && LiteGraph.NODE_MODES_COLORS[mode]
? LiteGraph.NODE_MODES_COLORS[mode]
: undefined : undefined
if (LiteGraph.node_box_coloured_when_on) { if (LiteGraph.node_box_coloured_when_on) {
@@ -255,10 +256,10 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
) ?? null ) ?? null
} }
exec_version: number exec_version?: number
action_call?: string action_call?: string
execute_triggered: number execute_triggered?: number
action_triggered: number action_triggered?: number
widgets_up?: boolean widgets_up?: boolean
widgets_start_y?: number widgets_start_y?: number
lostFocusAt?: number lostFocusAt?: number
@@ -271,11 +272,11 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
* The width of the node when collapsed. * The width of the node when collapsed.
* Updated by {@link LGraphCanvas.drawNode} * Updated by {@link LGraphCanvas.drawNode}
*/ */
_collapsed_width: number _collapsed_width?: number
/** Called once at the start of every frame. Caller may change the values in {@link out}, which will be reflected in {@link boundingRect}. */ /** Called once at the start of every frame. Caller may change the values in {@link out}, which will be reflected in {@link boundingRect}. */
onBounding?(this: LGraphNode, out: Rect): void onBounding?(this: LGraphNode, out: Rect): void
console?: string[] console?: string[]
_level: number _level?: number
_shape?: RenderShape _shape?: RenderShape
mouseOver?: IMouseOverData mouseOver?: IMouseOverData
redraw_on_mouse?: boolean redraw_on_mouse?: boolean
@@ -345,7 +346,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
return this.flags.collapsed ? [this._collapsed_width, 0] : this._size return this.flags.collapsed ? [this._collapsed_width, 0] : this._size
} }
get shape(): RenderShape { get shape(): RenderShape | undefined {
return this._shape return this._shape
} }
@@ -378,7 +379,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
return this._shape || this.constructor.shape || LiteGraph.NODE_DEFAULT_SHAPE return this._shape || this.constructor.shape || LiteGraph.NODE_DEFAULT_SHAPE
} }
public get is_selected(): boolean { public get is_selected(): boolean | undefined {
return this.selected return this.selected
} }
@@ -421,7 +422,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
type: ISlotType, type: ISlotType,
index: number, index: number,
isConnected: boolean, isConnected: boolean,
link_info: LLink, link_info: LLink | null | undefined,
inputOrOutput: INodeInputSlot | INodeOutputSlot, inputOrOutput: INodeInputSlot | INodeOutputSlot,
): void ): void
onInputAdded?(this: LGraphNode, input: INodeInputSlot): void onInputAdded?(this: LGraphNode, input: INodeInputSlot): void
@@ -513,8 +514,8 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
onOutputDblClick?(this: LGraphNode, index: number, e: CanvasMouseEvent): void onOutputDblClick?(this: LGraphNode, index: number, e: CanvasMouseEvent): void
// TODO: Return type // TODO: Return type
onGetPropertyInfo?(this: LGraphNode, property: string): any onGetPropertyInfo?(this: LGraphNode, property: string): any
onNodeOutputAdd?(this: LGraphNode, value): void onNodeOutputAdd?(this: LGraphNode, value: unknown): void
onNodeInputAdd?(this: LGraphNode, value): void onNodeInputAdd?(this: LGraphNode, value: unknown): void
onMenuNodeInputs?( onMenuNodeInputs?(
this: LGraphNode, this: LGraphNode,
entries: IOptionalSlotData<INodeInputSlot>[], entries: IOptionalSlotData<INodeInputSlot>[],
@@ -612,17 +613,22 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
continue continue
} }
// @ts-ignore #594
if (info[j] == null) { if (info[j] == null) {
continue continue
// @ts-ignore #594
} else if (typeof info[j] == "object") { } else if (typeof info[j] == "object") {
// object // @ts-ignore #594
if (this[j]?.configure) { if (this[j]?.configure) {
// @ts-ignore #594
this[j]?.configure(info[j]) this[j]?.configure(info[j])
} else { } else {
// @ts-ignore #594
this[j] = LiteGraph.cloneObject(info[j], this[j]) this[j] = LiteGraph.cloneObject(info[j], this[j])
} }
} else { } else {
// value // value
// @ts-ignore #594
this[j] = info[j] this[j] = info[j]
} }
} }
@@ -711,6 +717,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
if (this.widgets[i]) if (this.widgets[i])
o.widgets_values[i] = this.widgets[i].value o.widgets_values[i] = this.widgets[i].value
else else
// @ts-ignore #595 No-null
o.widgets_values[i] = null o.widgets_values[i] = null
} }
} }
@@ -728,7 +735,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
} }
/* Creates a clone of this node */ /* Creates a clone of this node */
clone(): LGraphNode { clone(): LGraphNode | null {
const node = LiteGraph.createNode(this.type) const node = LiteGraph.createNode(this.type)
if (!node) return null if (!node) return null
@@ -3049,7 +3056,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
* @returns `true` if any new links were established, otherwise `false`. * @returns `true` if any new links were established, otherwise `false`.
* @todo Decision: Change API to return array of new links instead? * @todo Decision: Change API to return array of new links instead?
*/ */
connectInputToOutput(): boolean { connectInputToOutput(): boolean | undefined {
const { inputs, outputs, graph } = this const { inputs, outputs, graph } = this
if (!inputs || !outputs) return if (!inputs || !outputs) return

View File

@@ -15,7 +15,7 @@ import {
} from "./types/globalEnums" } from "./types/globalEnums"
import { LGraphNode } from "./LGraphNode" import { LGraphNode } from "./LGraphNode"
import { SlotShape, SlotDirection, SlotType, LabelPosition } from "./draw" import { SlotShape, SlotDirection, SlotType, LabelPosition } from "./draw"
import type { Dictionary, ISlotType, Rect } from "./interfaces" import type { Dictionary, ISlotType, Rect, WhenNullish } from "./interfaces"
import { distance, isInsideRectangle, overlapBounding } from "./measure" import { distance, isInsideRectangle, overlapBounding } from "./measure"
import { Reroute } from "./Reroute" import { Reroute } from "./Reroute"
@@ -563,8 +563,8 @@ export class LiteGraphGlobal {
// separated just to improve if it doesn't work // separated just to improve if it doesn't work
/** @deprecated Prefer {@link structuredClone} */ /** @deprecated Prefer {@link structuredClone} */
cloneObject<T extends object>(obj: T, target?: T): T | null { cloneObject<T extends object | undefined | null>(obj: T, target?: T): WhenNullish<T, null> {
if (obj == null) return null if (obj == null) return null as WhenNullish<T, null>
const r = JSON.parse(JSON.stringify(obj)) const r = JSON.parse(JSON.stringify(obj))
if (!target) return r if (!target) return r

View File

@@ -13,6 +13,12 @@ export type NullableProperties<T> = {
[P in keyof T]: T[P] | null [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 & {})
export type CanvasColour = string | CanvasGradient | CanvasPattern export type CanvasColour = string | CanvasGradient | CanvasPattern
/** An object containing a set of child objects */ /** An object containing a set of child objects */

View File

@@ -143,7 +143,7 @@ export interface LiteGraphCanvasEvent extends CustomEvent<CanvasEventDetail> {}
/** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */ /** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */
export interface LGraphNodeConstructor<T extends LGraphNode = LGraphNode> { export interface LGraphNodeConstructor<T extends LGraphNode = LGraphNode> {
title?: string title: string
type?: string type?: string
size?: Size size?: Size
min_height?: number min_height?: number

View File

@@ -91,7 +91,7 @@ export interface ISerialisedGroup {
id: number id: number
title: string title: string
bounding: number[] bounding: number[]
color: string color?: string
font_size: number font_size: number
flags?: IGraphGroupFlags flags?: IGraphGroupFlags
} }