From 5d082b7f37be637a004e006b2a30adb56410a956 Mon Sep 17 00:00:00 2001 From: snomiao Date: Mon, 15 Sep 2025 08:01:39 +0000 Subject: [PATCH] refactor litegraph to solve circular dep --- scripts/verbatim.mjs | 130 +++++++++ src/lib/litegraph/src/ContextMenu.ts | 6 +- src/lib/litegraph/src/LGraph.ts | 73 ++--- src/lib/litegraph/src/LGraphCanvas.ts | 273 +++++++++--------- src/lib/litegraph/src/LGraphGroup.ts | 10 +- src/lib/litegraph/src/LGraphNode.ts | 186 ++++++------ src/lib/litegraph/src/LiteGraphSingleton.ts | 4 + src/lib/litegraph/src/draw.ts | 8 +- src/lib/litegraph/src/litegraph.ts | 4 +- src/lib/litegraph/src/node/NodeInputSlot.ts | 8 +- src/lib/litegraph/src/node/NodeOutputSlot.ts | 10 +- src/lib/litegraph/src/node/NodeSlot.ts | 11 +- .../src/subgraph/ExecutableNodeDTO.ts | 11 +- .../src/subgraph/SubgraphIONodeBase.ts | 7 +- .../litegraph/src/subgraph/SubgraphInput.ts | 6 +- .../litegraph/src/subgraph/SubgraphOutput.ts | 8 +- .../src/subgraph/SubgraphSlotBase.ts | 6 +- .../litegraph/src/subgraph/subgraphUtils.ts | 7 +- src/lib/litegraph/src/types/serialisation.ts | 4 +- src/lib/litegraph/src/utils/feedback.ts | 6 +- src/lib/litegraph/src/widgets/BaseWidget.ts | 20 +- src/lib/litegraph/src/widgets/ComboWidget.ts | 4 +- src/lib/litegraph/src/widgets/LegacyWidget.ts | 4 +- src/lib/litegraph/test/LGraph.test.ts | 9 +- .../test/LGraphCanvas.titleButtons.test.ts | 13 +- .../litegraph/test/LGraphNode.resize.test.ts | 5 +- src/lib/litegraph/test/LGraphNode.test.ts | 37 +-- src/lib/litegraph/test/litegraph.test.ts | 11 +- .../test/subgraph/SubgraphConversion.test.ts | 11 +- src/lib/litegraph/test/testExtensions.ts | 4 +- 30 files changed, 519 insertions(+), 377 deletions(-) create mode 100644 scripts/verbatim.mjs create mode 100644 src/lib/litegraph/src/LiteGraphSingleton.ts diff --git a/scripts/verbatim.mjs b/scripts/verbatim.mjs new file mode 100644 index 000000000..7b7c9c550 --- /dev/null +++ b/scripts/verbatim.mjs @@ -0,0 +1,130 @@ +#!/usr/bin/env bun + +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +// const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const __dirname = process.cwd() + +// Parse the tsc.log file to get all errors +async function parseErrors(file) { + const logContent = await fs.readFile(file, 'utf-8'); + const lines = logContent.split('\n').filter(line => line.includes('error TS1484')); + + const errors = []; + for (const line of lines) { + // Match the format: filepath(line,col): error TS1484: 'TypeName' is a type + // Note: Some lines may have a number prefix followed by → + const match = line.match(/(?:\d+→)?(.+?)\((\d+),(\d+)\): error TS1484: '(.+?)' is a type/); + if (match) { + const [, filePath, lineNum, colNum, typeName] = match; + errors.push({ + filePath: path.join(__dirname, filePath.trim()), + lineNum: parseInt(lineNum), + colNum: parseInt(colNum), + typeName + }); + } + } + + return errors; +} + +// Group errors by file +function groupByFile(errors) { + const grouped = {}; + for (const error of errors) { + if (!grouped[error.filePath]) { + grouped[error.filePath] = []; + } + grouped[error.filePath].push(error); + } + return grouped; +} + +// Process a single file +async function processFile(filePath, errors) { + try { + const content = await fs.readFile(filePath, 'utf-8'); + const lines = content.split('\n'); + + // Sort errors by line and column in reverse order to avoid position shifts + errors.sort((a, b) => { + if (a.lineNum !== b.lineNum) { + return b.lineNum - a.lineNum; + } + return b.colNum - a.colNum; + }); + + // Process each error + for (const error of errors) { + const lineIndex = error.lineNum - 1; + const line = lines[lineIndex]; + if (!line) continue; + + // Skip if already has 'type' keyword before this position + const beforePos = line.substring(0, error.colNum - 1); + if (beforePos.includes('import type') || beforePos.endsWith('{ type ') || beforePos.endsWith(', type ')) { + continue; + } + + // Insert "type " at the exact column position (column is 1-based) + const insertPos = error.colNum - 1; + lines[lineIndex] = line.substring(0, insertPos) + 'type ' + line.substring(insertPos); + } + + await fs.writeFile(filePath, lines.join('\n')); + console.log(`āœ“ Fixed ${errors.length} type imports in ${path.relative(__dirname, filePath)}`); + return true; + } catch (error) { + console.error(`āœ— Error processing ${filePath}:`, error.message); + return false; + } +} + +// Main function +async function main() { + console.log('šŸ”§ Fixing TypeScript type-only imports...\n'); + + const logFile = path.join(__dirname, 'tsc.log'); + + if (!await readFile(logFile).catch(() => null)) { + console.error('Unable to read tsc.log'); + console.error('Run this command to generate type errors and rerun this script again:'); + console.error('pnpm typecheck > tsc.log'); + return; + } + + console.log('Parsing tsc.log for type import errors...\n'); + const errors = await parseErrors(logFile); + console.log(`Found ${errors.length} type import errors\n`); + + const grouped = groupByFile(errors); + const files = Object.keys(grouped); + console.log(`Processing ${files.length} files...\n`); + + let successCount = 0; + let failCount = 0; + + for (const filePath of files) { + const success = await processFile(filePath, grouped[filePath]); + if (success) { + successCount++; + } else { + failCount++; + } + } + + console.log('\nšŸ“Š Summary:'); + console.log(`āœ“ Successfully processed: ${successCount} files`); + if (failCount > 0) { + console.log(`āœ— Failed to process: ${failCount} files`); + } + + console.log('\n✨ Refactoring complete!'); + console.log('Run "pnpm typecheck" to verify the fixes.'); +} + +// Run the script +main().catch(console.error); \ No newline at end of file diff --git a/src/lib/litegraph/src/ContextMenu.ts b/src/lib/litegraph/src/ContextMenu.ts index 40aed5c09..98f25ce8a 100644 --- a/src/lib/litegraph/src/ContextMenu.ts +++ b/src/lib/litegraph/src/ContextMenu.ts @@ -3,7 +3,7 @@ import type { IContextMenuOptions, IContextMenuValue } from './interfaces' -import { LiteGraph } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' // TODO: Replace this pattern with something more modern. export interface ContextMenu { @@ -182,7 +182,7 @@ export class ContextMenu { root.style.left = `${left}px` root.style.top = `${top}px` - if (LiteGraph.context_menu_scaling && options.scale) { + if (LiteGraphSingleton.context_menu_scaling && options.scale) { root.style.transform = `scale(${Math.round(options.scale * 4) * 0.25})` } } @@ -355,7 +355,7 @@ export class ContextMenu { ) { ContextMenu.trigger( this.parentMenu.root, - `${LiteGraph.pointerevents_method}leave`, + `${LiteGraphSingleton.pointerevents_method}leave`, e ) } diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 139919c60..174fa9e77 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -34,7 +34,8 @@ import type { Positionable, Size } from './interfaces' -import { LiteGraph, SubgraphNode } from './litegraph' +import { SubgraphNode } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' import { alignOutsideContainer, alignToContainer, @@ -274,7 +275,7 @@ export class LGraph * @param o data from previous serialization [optional] */ constructor(o?: ISerialisedGraph | SerialisableGraph) { - if (LiteGraph.debug) console.log('Graph created') + if (LiteGraphSingleton.debug) console.log('Graph created') /** @see MapProxyHandler */ const links = this._links @@ -424,7 +425,7 @@ export class LGraph this.sendEventToAllNodes('onStart') // launch - this.starttime = LiteGraph.getTime() + this.starttime = LiteGraphSingleton.getTime() this.last_update_time = this.starttime interval ||= 0 @@ -486,7 +487,7 @@ export class LGraph runStep(num: number, do_not_catch_errors: boolean, limit?: number): void { num = num || 1 - const start = LiteGraph.getTime() + const start = LiteGraphSingleton.getTime() this.globaltime = 0.001 * (start - this.starttime) const nodes = this._nodes_executable || this._nodes @@ -530,14 +531,14 @@ export class LGraph this.errors_in_execution = false } catch (error) { this.errors_in_execution = true - if (LiteGraph.throw_errors) throw error + if (LiteGraphSingleton.throw_errors) throw error - if (LiteGraph.debug) console.log('Error during execution:', error) + if (LiteGraphSingleton.debug) console.log('Error during execution:', error) this.stop() } } - const now = LiteGraph.getTime() + const now = LiteGraphSingleton.getTime() let elapsed = now - start if (elapsed == 0) elapsed = 1 @@ -662,7 +663,7 @@ export class LGraph L.push(M[i]) } - if (L.length != this._nodes.length && LiteGraph.debug) + if (L.length != this._nodes.length && LiteGraphSingleton.debug) console.warn('something went wrong, nodes missing') /** Ensure type is set */ @@ -718,16 +719,16 @@ export class LGraph if (!column) continue let max_size = 100 - let y = margin + LiteGraph.NODE_TITLE_HEIGHT + let y = margin + LiteGraphSingleton.NODE_TITLE_HEIGHT for (const node of column) { - node.pos[0] = layout == LiteGraph.VERTICAL_LAYOUT ? y : x - node.pos[1] = layout == LiteGraph.VERTICAL_LAYOUT ? x : y - const max_size_index = layout == LiteGraph.VERTICAL_LAYOUT ? 1 : 0 + node.pos[0] = layout == LiteGraphSingleton.VERTICAL_LAYOUT ? y : x + node.pos[1] = layout == LiteGraphSingleton.VERTICAL_LAYOUT ? x : y + const max_size_index = layout == LiteGraphSingleton.VERTICAL_LAYOUT ? 1 : 0 if (node.size[max_size_index] > max_size) { max_size = node.size[max_size_index] } - const node_size_index = layout == LiteGraph.VERTICAL_LAYOUT ? 0 : 1 - y += node.size[node_size_index] + margin + LiteGraph.NODE_TITLE_HEIGHT + const node_size_index = layout == LiteGraphSingleton.VERTICAL_LAYOUT ? 0 : 1 + y += node.size[node_size_index] + margin + LiteGraphSingleton.NODE_TITLE_HEIGHT } x += max_size + margin } @@ -831,7 +832,7 @@ export class LGraph const { state } = this // Ensure created items are snapped - if (LiteGraph.alwaysSnapToGrid) { + if (LiteGraphSingleton.alwaysSnapToGrid) { const snapTo = this.getSnapToGridSize() if (snapTo) node.snapToGrid(snapTo) } @@ -856,16 +857,16 @@ export class LGraph console.warn( 'LiteGraph: there is already a node with this ID, changing it' ) - node.id = LiteGraph.use_uuids ? LiteGraph.uuidv4() : ++state.lastNodeId + node.id = LiteGraphSingleton.use_uuids ? LiteGraphSingleton.uuidv4() : ++state.lastNodeId } - if (this._nodes.length >= LiteGraph.MAX_NUMBER_OF_NODES) { + if (this._nodes.length >= LiteGraphSingleton.MAX_NUMBER_OF_NODES) { throw 'LiteGraph: max number of nodes in a graph reached' } // give him an id - if (LiteGraph.use_uuids) { - if (node.id == null || node.id == -1) node.id = LiteGraph.uuidv4() + if (LiteGraphSingleton.use_uuids) { + if (node.id == null || node.id == -1) node.id = LiteGraphSingleton.uuidv4() } else { if (node.id == null || node.id == -1) { node.id = ++state.lastNodeId @@ -1128,9 +1129,9 @@ export class LGraph /** * Snaps the provided items to a grid. * - * Item positions are reounded to the nearest multiple of {@link LiteGraph.CANVAS_GRID_SIZE}. + * Item positions are reounded to the nearest multiple of {@link LiteGraphSingleton.CANVAS_GRID_SIZE}. * - * When {@link LiteGraph.alwaysSnapToGrid} is enabled + * When {@link LiteGraphSingleton.alwaysSnapToGrid} is enabled * and the grid size is falsy, a default of 1 is used. * @param items The items to be snapped to the grid * @todo Currently only snaps nodes. @@ -1150,9 +1151,9 @@ export class LGraph */ getSnapToGridSize(): number { // Default to 1 when always snapping - return LiteGraph.alwaysSnapToGrid - ? LiteGraph.CANVAS_GRID_SIZE || 1 - : LiteGraph.CANVAS_GRID_SIZE + return LiteGraphSingleton.alwaysSnapToGrid + ? LiteGraphSingleton.CANVAS_GRID_SIZE || 1 + : LiteGraphSingleton.CANVAS_GRID_SIZE } /** @@ -1164,11 +1165,11 @@ export class LGraph checkNodeTypes() { const { _nodes } = this for (const [i, node] of _nodes.entries()) { - const ctor = LiteGraph.registered_node_types[node.type] + const ctor = LiteGraphSingleton.registered_node_types[node.type] if (node.constructor == ctor) continue console.log('node being replaced by newer version:', node.type) - const newnode = LiteGraph.createNode(node.type) + const newnode = LiteGraphSingleton.createNode(node.type) if (!newnode) continue _nodes[i] = newnode newnode.configure(node.serialize()) @@ -1229,7 +1230,7 @@ export class LGraph /* Called when something visually changed (not the graph!) */ change(): void { - if (LiteGraph.debug) { + if (LiteGraphSingleton.debug) { console.log('Graph changed') } this.canvasAction((c) => c.setDirty(true, true)) @@ -1579,7 +1580,7 @@ export class LGraph }) // Create subgraph node object - const subgraphNode = LiteGraph.createNode(subgraph.id, subgraph.name, { + const subgraphNode = LiteGraphSingleton.createNode(subgraph.id, subgraph.name, { outputs: structuredClone(outputs) }) if (!subgraphNode) throw new Error('Failed to create subgraph node') @@ -1598,7 +1599,7 @@ export class LGraph ) //Correct for title height. It's included in bounding box, but not _posSize - subgraphNode.pos[1] += LiteGraph.NODE_TITLE_HEIGHT / 2 + subgraphNode.pos[1] += LiteGraphSingleton.NODE_TITLE_HEIGHT / 2 // Add the subgraph node to the graph this.add(subgraphNode) @@ -1719,7 +1720,7 @@ export class LGraph const movedNodes = multiClone(subgraphNode.subgraph.nodes) const nodeIdMap = new Map() for (const n_info of movedNodes) { - const node = LiteGraph.createNode(String(n_info.type), n_info.title) + const node = LiteGraphSingleton.createNode(String(n_info.type), n_info.title) if (!node) { throw new Error('Node not found') } @@ -2027,7 +2028,7 @@ export class LGraph definitions, config, extra, - version: LiteGraph.VERSION + version: LiteGraphSingleton.VERSION } } @@ -2052,7 +2053,7 @@ export class LGraph const { id, revision, config, state } = this const nodeList = - !LiteGraph.use_uuids && options?.sortNodes + !LiteGraphSingleton.use_uuids && options?.sortNodes ? // @ts-expect-error If LiteGraph.use_uuids is false, ids are numbers. [...this._nodes].sort((a, b) => a.id - b.id) : this._nodes @@ -2072,7 +2073,7 @@ export class LGraph // Save scale and offset const extra = { ...this.extra } - if (LiteGraph.saveViewportWithGraph) extra.ds = this.#getDragAndScale() + if (LiteGraphSingleton.saveViewportWithGraph) extra.ds = this.#getDragAndScale() if (!extra.ds) delete extra.ds const data: ReturnType = { @@ -2230,9 +2231,9 @@ export class LGraph if (nodesData) { for (const n_info of nodesData) { // stored info - let node = LiteGraph.createNode(String(n_info.type), n_info.title) + let node = LiteGraphSingleton.createNode(String(n_info.type), n_info.title) if (!node) { - if (LiteGraph.debug) + if (LiteGraphSingleton.debug) console.log('Node not found or has errors:', n_info.type) // in case of error we create a replacement node to avoid losing info @@ -2284,7 +2285,7 @@ export class LGraph if (groupData) { for (const data of groupData) { // TODO: Search/remove these global object refs - const group = new LiteGraph.LGraphGroup() + const group = new LiteGraphSingleton.LGraphGroup() group.configure(data) this.add(group) } diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index 9e7ef226f..222fbef30 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -52,7 +52,8 @@ import type { Rect, Size } from './interfaces' -import { LiteGraph, Rectangle, SubgraphNode, createUuidv4 } from './litegraph' +import { Rectangle, SubgraphNode, createUuidv4 } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' import { containsRect, createBounds, @@ -409,12 +410,12 @@ export class LGraphCanvas * @deprecated Use {@link LGraphNode.titleFontStyle} instead. */ get title_text_font(): string { - return `${LiteGraph.NODE_TEXT_SIZE}px ${LiteGraph.NODE_FONT}` + return `${LiteGraphSingleton.NODE_TEXT_SIZE}px ${LiteGraphSingleton.NODE_FONT}` } // #endregion Legacy accessors get inner_text_font(): string { - return `normal ${LiteGraph.NODE_SUBTEXT_SIZE}px ${LiteGraph.NODE_FONT}` + return `normal ${LiteGraphSingleton.NODE_SUBTEXT_SIZE}px ${LiteGraphSingleton.NODE_FONT}` } #maximumFrameGap = 0 @@ -433,14 +434,14 @@ export class LGraphCanvas * @deprecated Use {@link LiteGraphGlobal.ROUND_RADIUS} instead. */ get round_radius() { - return LiteGraph.ROUND_RADIUS + return LiteGraphSingleton.ROUND_RADIUS } /** * @deprecated Use {@link LiteGraphGlobal.ROUND_RADIUS} instead. */ set round_radius(value: number) { - LiteGraph.ROUND_RADIUS = value + LiteGraphSingleton.ROUND_RADIUS = value } // Cached LOD threshold values for performance @@ -459,7 +460,7 @@ export class LGraphCanvas return } - const baseFontSize = LiteGraph.NODE_TEXT_SIZE // 14px + const baseFontSize = LiteGraphSingleton.NODE_TEXT_SIZE // 14px const dprAdjustment = Math.sqrt(window.devicePixelRatio || 1) //Using sqrt here because higher DPR monitors do not linearily scale the readability of the font, instead they increase the font by some heurisitc, and to approximate we use sqrt to say bascially a DPR of 2 increases the readibility by 40%, 3 by 70% // Calculate the zoom level where text becomes unreadable @@ -788,7 +789,7 @@ export class LGraphCanvas // No longer in use // add menu when releasing link in empty space - if (LiteGraph.release_link_on_empty_shows_menu) { + if (LiteGraphSingleton.release_link_on_empty_shows_menu) { const linkReleaseContext = this.linkConnector.state.connectingTo === 'input' ? { @@ -835,8 +836,8 @@ export class LGraphCanvas // in range (1.01, 2.5). Less than 1 will invert the zoom direction this.zoom_speed = 1.1 - this.node_title_color = LiteGraph.NODE_TITLE_COLOR - this.default_link_color = LiteGraph.LINK_COLOR + this.node_title_color = LiteGraphSingleton.NODE_TITLE_COLOR + this.default_link_color = LiteGraphSingleton.LINK_COLOR this.default_connection_color = { input_off: '#778', input_on: '#7F7', @@ -959,7 +960,7 @@ export class LGraphCanvas ): void { const canvas = LGraphCanvas.active_canvas - const group = new LiteGraph.LGraphGroup() + const group = new LiteGraphSingleton.LGraphGroup() group.pos = canvas.convertEventToCanvasOffset(mouse_event) if (!canvas.graph) throw new NullGraphError() canvas.graph.add(group) @@ -1009,7 +1010,7 @@ export class LGraphCanvas prev_menu: ContextMenu, node: LGraphNode ): void { - new LiteGraph.ContextMenu(['Top', 'Bottom', 'Left', 'Right'], { + new LiteGraphSingleton.ContextMenu(['Top', 'Bottom', 'Left', 'Right'], { event, callback: inner_clicked, parentMenu: prev_menu @@ -1033,7 +1034,7 @@ export class LGraphCanvas event: MouseEvent, prev_menu: ContextMenu ): void { - new LiteGraph.ContextMenu(['Top', 'Bottom', 'Left', 'Right'], { + new LiteGraphSingleton.ContextMenu(['Top', 'Bottom', 'Left', 'Right'], { event, callback: inner_clicked, parentMenu: prev_menu @@ -1056,7 +1057,7 @@ export class LGraphCanvas event: MouseEvent, prev_menu: ContextMenu ): void { - new LiteGraph.ContextMenu(['Vertically', 'Horizontally'], { + new LiteGraphSingleton.ContextMenu(['Vertically', 'Horizontally'], { event, callback: inner_clicked, parentMenu: prev_menu @@ -1104,7 +1105,7 @@ export class LGraphCanvas ): void { if (!graph) return - const categories = LiteGraph.getNodeTypesCategories( + const categories = LiteGraphSingleton.getNodeTypesCategories( canvas.filter || graph.filter ).filter((category) => category.startsWith(base_category)) const entries: AddNodeMenu[] = [] @@ -1147,7 +1148,7 @@ export class LGraphCanvas } } - const nodes = LiteGraph.getNodeTypesInCategory( + const nodes = LiteGraphSingleton.getNodeTypesInCategory( base_category.slice(0, -1), canvas.filter || graph.filter ) @@ -1171,7 +1172,7 @@ export class LGraphCanvas const first_event = contextMenu.getFirstEvent() canvas.graph.beforeChange() - const node = LiteGraph.createNode(value.value) + const node = LiteGraphSingleton.createNode(value.value) if (node) { if (!first_event) throw new TypeError( @@ -1191,7 +1192,7 @@ export class LGraphCanvas entries.push(entry) } - new LiteGraph.ContextMenu( + new LiteGraphSingleton.ContextMenu( entries, { event: e, parentMenu: prev_menu }, // @ts-expect-error - extra parameter @@ -1220,12 +1221,12 @@ export class LGraphCanvas let entries: (IContextMenuValue | null)[] = [] if ( - LiteGraph.do_add_triggers_slots && + LiteGraphSingleton.do_add_triggers_slots && node.findOutputSlot('onExecuted') == -1 ) { entries.push({ content: 'On Executed', - value: ['onExecuted', LiteGraph.EVENT, { nameLocked: true }], + value: ['onExecuted', LiteGraphSingleton.EVENT, { nameLocked: true }], className: 'event' }) } @@ -1235,7 +1236,7 @@ export class LGraphCanvas if (!entries.length) return - new LiteGraph.ContextMenu(entries, { + new LiteGraphSingleton.ContextMenu(entries, { event: e, callback: inner_clicked, parentMenu: prev_menu, @@ -1263,7 +1264,7 @@ export class LGraphCanvas for (const i in value) { entries.push({ content: i, value: value[i] }) } - new LiteGraph.ContextMenu(entries, { + new LiteGraphSingleton.ContextMenu(entries, { event: e, callback: inner_clicked, parentMenu: prev_menu, @@ -1322,7 +1323,7 @@ export class LGraphCanvas return } - new LiteGraph.ContextMenu( + new LiteGraphSingleton.ContextMenu( entries, { event: e, @@ -1465,18 +1466,18 @@ export class LGraphCanvas let dialogCloseTimer: number dialog.addEventListener('mouseleave', function () { - if (LiteGraph.dialog_close_on_mouse_leave) { - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) { + if (LiteGraphSingleton.dialog_close_on_mouse_leave) { + if (!dialog.is_modified && LiteGraphSingleton.dialog_close_on_mouse_leave) { // @ts-expect-error - setTimeout type dialogCloseTimer = setTimeout( dialog.close, - LiteGraph.dialog_close_on_mouse_leave_delay + LiteGraphSingleton.dialog_close_on_mouse_leave_delay ) } } }) dialog.addEventListener('mouseenter', function () { - if (LiteGraph.dialog_close_on_mouse_leave) { + if (LiteGraphSingleton.dialog_close_on_mouse_leave) { if (dialogCloseTimer) clearTimeout(dialogCloseTimer) } }) @@ -1596,7 +1597,7 @@ export class LGraphCanvas menu: ContextMenu, node: LGraphNode ): boolean { - new LiteGraph.ContextMenu(LiteGraph.NODE_MODES, { + new LiteGraphSingleton.ContextMenu(LiteGraphSingleton.NODE_MODES, { event: e, callback: inner_clicked, parentMenu: menu, @@ -1606,9 +1607,9 @@ export class LGraphCanvas function inner_clicked(v: string) { if (!node) return - const kV = Object.values(LiteGraph.NODE_MODES).indexOf(v) + const kV = Object.values(LiteGraphSingleton.NODE_MODES).indexOf(v) const fApplyMultiNode = function (node: LGraphNode) { - if (kV !== -1 && LiteGraph.NODE_MODES[kV]) { + if (kV !== -1 && LiteGraphSingleton.NODE_MODES[kV]) { node.changeMode(kV) } else { console.warn(`unexpected mode: ${v}`) @@ -1664,7 +1665,7 @@ export class LGraphCanvas } values.push(value) } - new LiteGraph.ContextMenu(values, { + new LiteGraphSingleton.ContextMenu(values, { event: e, callback: inner_clicked, parentMenu: menu, @@ -1698,17 +1699,17 @@ export class LGraphCanvas static onMenuNodeShapes( // @ts-expect-error - unused parameter - value: IContextMenuValue<(typeof LiteGraph.VALID_SHAPES)[number]>, + value: IContextMenuValue<(typeof LiteGraphSingleton.VALID_SHAPES)[number]>, // @ts-expect-error - unused parameter - options: IContextMenuOptions<(typeof LiteGraph.VALID_SHAPES)[number]>, + options: IContextMenuOptions<(typeof LiteGraphSingleton.VALID_SHAPES)[number]>, e: MouseEvent, - menu?: ContextMenu<(typeof LiteGraph.VALID_SHAPES)[number]>, + menu?: ContextMenu<(typeof LiteGraphSingleton.VALID_SHAPES)[number]>, node?: LGraphNode ): boolean { if (!node) throw 'no node passed' - new LiteGraph.ContextMenu<(typeof LiteGraph.VALID_SHAPES)[number]>( - LiteGraph.VALID_SHAPES, + new LiteGraphSingleton.ContextMenu<(typeof LiteGraphSingleton.VALID_SHAPES)[number]>( + LiteGraphSingleton.VALID_SHAPES, { event: e, callback: inner_clicked, @@ -1717,7 +1718,7 @@ export class LGraphCanvas } ) - function inner_clicked(v: (typeof LiteGraph.VALID_SHAPES)[number]) { + function inner_clicked(v: (typeof LiteGraphSingleton.VALID_SHAPES)[number]) { if (!node) return if (!node.graph) throw new NullGraphError() @@ -2099,7 +2100,7 @@ export class LGraphCanvas if (this.#maximumFrameGap > 0) { // Manual FPS limit const gap = - this.#maximumFrameGap - (LiteGraph.getTime() - this.last_draw_time) + this.#maximumFrameGap - (LiteGraphSingleton.getTime() - this.last_draw_time) setTimeout(renderFrame.bind(this), Math.max(1, gap)) } else { // FPS limited by refresh rate @@ -2170,7 +2171,7 @@ export class LGraphCanvas // Hover transitions // TODO: Implement single lerp ease factor for current progress on hover in/out. // In drawNode, multiply by ease factor and differential value (e.g. bg alpha +0.5). - otherNode.lostFocusAt = LiteGraph.getTime() + otherNode.lostFocusAt = LiteGraphSingleton.getTime() this.node_over?.onMouseLeave?.(e) this.node_over = undefined @@ -2223,7 +2224,7 @@ export class LGraphCanvas this.canvas.focus() - LiteGraph.closeAllContextMenus(ref_window) + LiteGraphSingleton.closeAllContextMenus(ref_window) if (this.onMouse?.(e) == true) return @@ -2294,7 +2295,7 @@ export class LGraphCanvas } this.last_mouse = [x, y] - this.last_mouseclick = LiteGraph.getTime() + this.last_mouseclick = LiteGraphSingleton.getTime() this.last_mouse_dragging = true graph.change() @@ -2348,7 +2349,7 @@ export class LGraphCanvas if ( ctrlOrMeta && !e.altKey && - LiteGraph.canvasNavigationMode === 'legacy' + LiteGraphSingleton.canvasNavigationMode === 'legacy' ) { this.#setupNodeSelectionDrag(e, pointer, node) @@ -2363,7 +2364,7 @@ export class LGraphCanvas // clone node ALT dragging if ( - LiteGraph.alt_drag_do_clone_nodes && + LiteGraphSingleton.alt_drag_do_clone_nodes && e.altKey && !e.ctrlKey && node && @@ -2383,7 +2384,7 @@ export class LGraphCanvas if (node_data?.type != null) { // Ensure the cloned node is configured against the correct type (especially for SubgraphNodes) node_data.type = newType - const cloned = LiteGraph.createNode(newType) + const cloned = LiteGraphSingleton.createNode(newType) if (cloned) { cloned.configure(node_data) cloned.pos[0] += 5 @@ -2566,7 +2567,7 @@ export class LGraphCanvas } pointer.finally = () => (this.resizingGroup = null) } else { - const f = group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE + const f = group.font_size || LiteGraphSingleton.DEFAULT_GROUP_FONT_SIZE const headerHeight = f * 1.4 if ( isInRectangle( @@ -2617,7 +2618,7 @@ export class LGraphCanvas this.allow_dragcanvas ) { // allow dragging canvas if canvas is not in standard, or read-only (pan mode in standard) - if (LiteGraph.canvasNavigationMode !== 'standard' || this.read_only) { + if (LiteGraphSingleton.canvasNavigationMode !== 'standard' || this.read_only) { pointer.onClick = () => this.processSelect(null, e) pointer.finally = () => (this.dragging_canvas = false) this.dragging_canvas = true @@ -2714,11 +2715,11 @@ export class LGraphCanvas linkConnector.dragNewFromOutput(graph, node, output) this.#linkConnectorDrop() - if (LiteGraph.shift_click_do_break_link_from) { + if (LiteGraphSingleton.shift_click_do_break_link_from) { if (e.shiftKey) { node.disconnectOutput(i) } - } else if (LiteGraph.ctrl_alt_click_do_break_link) { + } else if (LiteGraphSingleton.ctrl_alt_click_do_break_link) { if (ctrlOrMeta && e.altKey && !e.shiftKey) { node.disconnectOutput(i) } @@ -2747,13 +2748,13 @@ export class LGraphCanvas pointer.onClick = () => node.onInputClick?.(i, e) const shouldBreakLink = - LiteGraph.ctrl_alt_click_do_break_link && + LiteGraphSingleton.ctrl_alt_click_do_break_link && ctrlOrMeta && e.altKey && !e.shiftKey if (input.link !== null || input._floatingLinks?.size) { // Existing link - if (shouldBreakLink || LiteGraph.click_do_break_link_to) { + if (shouldBreakLink || LiteGraphSingleton.click_do_break_link_to) { node.disconnectInput(i, true) } else if (e.shiftKey || this.allow_reconnect_links) { linkConnector.moveInputLink(graph, input) @@ -3028,7 +3029,7 @@ export class LGraphCanvas const { pointer } = this if ( - LiteGraph.middle_click_slot_add_default_node && + LiteGraphSingleton.middle_click_slot_add_default_node && node && this.allow_interaction && !this.read_only && @@ -3323,7 +3324,7 @@ export class LGraphCanvas } else if ( inputId != -1 && node.inputs[inputId] && - LiteGraph.isValidConnection( + LiteGraphSingleton.isValidConnection( firstLink.fromSlot.type, node.inputs[inputId].type ) @@ -3350,7 +3351,7 @@ export class LGraphCanvas if ( outputId != -1 && node.outputs[outputId] && - LiteGraph.isValidConnection( + LiteGraphSingleton.isValidConnection( firstLink.fromSlot.type, node.outputs[outputId].type ) @@ -3503,7 +3504,7 @@ export class LGraphCanvas */ #processDraggedItems(e: CanvasPointerEvent): void { const { graph } = this - if (e.shiftKey || LiteGraph.alwaysSnapToGrid) + if (e.shiftKey || LiteGraphSingleton.alwaysSnapToGrid) graph?.snapToGrid(this.selectedItems) this.dirty_canvas = true @@ -3527,7 +3528,7 @@ export class LGraphCanvas this.adjustMouseEvent(e) - const now = LiteGraph.getTime() + const now = LiteGraphSingleton.getTime() e.click_time = now - this.last_mouseclick /** The mouseup event occurred near the mousedown event. */ @@ -3629,7 +3630,7 @@ export class LGraphCanvas e.ctrlKey || (e.metaKey && navigator.platform.includes('Mac')) const isZoomModifier = isCtrlOrMacMeta && !e.altKey && !e.shiftKey - if (isZoomModifier || LiteGraph.canvasNavigationMode === 'legacy') { + if (isZoomModifier || LiteGraphSingleton.canvasNavigationMode === 'legacy') { // Legacy mode or standard mode with ctrl - use wheel for zoom if (isTrackpad) { // Trackpad gesture - use smooth scaling @@ -3870,7 +3871,7 @@ export class LGraphCanvas // if ctrl + shift + v is off, return when isConnectUnselected is true (shift is pressed) to maintain old behavior if ( - !LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && + !LiteGraphSingleton.ctrl_shift_v_paste_connect_unselected_outputs && connectInputs ) return @@ -3952,7 +3953,7 @@ export class LGraphCanvas // Nodes for (const info of parsed.nodes) { - const node = info.type == null ? null : LiteGraph.createNode(info.type) + const node = info.type == null ? null : LiteGraphSingleton.createNode(info.type) if (!node) { // failedNodes.push(info) continue @@ -3995,7 +3996,7 @@ export class LGraphCanvas // If it wasn't copied, use the original graph value if ( connectInputs && - LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs + LiteGraphSingleton.ctrl_shift_v_paste_connect_unselected_outputs ) { outNode ??= graph.getNodeById(info.origin_id) afterRerouteId ??= info.parentId @@ -4560,7 +4561,7 @@ export class LGraphCanvas return // fps counting - const now = LiteGraph.getTime() + const now = LiteGraphSingleton.getTime() this.render_time = (now - this.last_draw_time) * 0.001 this.last_draw_time = now @@ -4625,7 +4626,7 @@ export class LGraphCanvas // TODO: Set snapping value when changed instead of once per frame this.#snapToGrid = - this.#shiftDown || LiteGraph.alwaysSnapToGrid + this.#shiftDown || LiteGraphSingleton.alwaysSnapToGrid ? this.graph?.getSnapToGridSize() : undefined @@ -4718,9 +4719,9 @@ export class LGraphCanvas const connType = fromSlot.type const colour = - connType === LiteGraph.EVENT - ? LiteGraph.EVENT_LINK_COLOR - : LiteGraph.CONNECTING_LINK_COLOR + connType === LiteGraphSingleton.EVENT + ? LiteGraphSingleton.EVENT_LINK_COLOR + : LiteGraphSingleton.CONNECTING_LINK_COLOR // the connection being dragged by the mouse if (this.linkRenderer) { @@ -4746,7 +4747,7 @@ export class LGraphCanvas ctx.fillStyle = colour ctx.beginPath() - if (connType === LiteGraph.EVENT || connShape === RenderShape.BOX) { + if (connType === LiteGraphSingleton.EVENT || connShape === RenderShape.BOX) { ctx.rect(pos[0] - 6 + 0.5, pos[1] - 5 + 0.5, 14, 10) ctx.rect( highlightPos[0] - 6 + 0.5, @@ -4836,7 +4837,7 @@ export class LGraphCanvas /** Get the target snap / highlight point in graph space */ #getHighlightPosition(): ReadOnlyPoint { - return LiteGraph.snaps_for_comfy + return LiteGraphSingleton.snaps_for_comfy ? this.linkConnector.state.snapLinksPos ?? this._highlight_pos ?? this.graph_mouse @@ -4872,7 +4873,7 @@ export class LGraphCanvas const { linkConnector } = this const { overReroute, overWidget } = linkConnector if ( - !LiteGraph.snap_highlights_node || + !LiteGraphSingleton.snap_highlights_node || !linkConnector.isConnecting || linkConnectorSnap ) @@ -4889,7 +4890,7 @@ export class LGraphCanvas const area = node.boundingRect const gap = 3 - const radius = LiteGraph.ROUND_RADIUS + gap + const radius = LiteGraphSingleton.ROUND_RADIUS + gap const x = area[0] - gap const y = area[1] - gap @@ -4937,7 +4938,7 @@ export class LGraphCanvas const { pos: [nodeX, nodeY] } = node - const height = LiteGraph.NODE_WIDGET_HEIGHT + const height = LiteGraphSingleton.NODE_WIDGET_HEIGHT if ( overWidget.type.startsWith('custom') && computedHeight != null && @@ -4981,7 +4982,7 @@ export class LGraphCanvas ctx.save() ctx.translate(x, y) - ctx.font = `10px ${LiteGraph.DEFAULT_FONT}` + ctx.font = `10px ${LiteGraphSingleton.DEFAULT_FONT}` ctx.fillStyle = '#888' ctx.textAlign = 'left' if (this.graph) { @@ -5160,7 +5161,7 @@ export class LGraphCanvas // When Vue nodes mode is enabled, LiteGraph should not draw node chrome or widgets. // We still need to keep slot metrics and layout in sync for hit-testing and links. // Interaction system changes coming later, chances are vue nodes mode will be mostly broken on land - if (LiteGraph.vueNodesMode) { + if (LiteGraphSingleton.vueNodesMode) { // Prepare concrete slots and compute layout measures without rendering visuals. node._setConcreteSlots() if (!node.collapsed) { @@ -5177,7 +5178,7 @@ export class LGraphCanvas ctx.globalAlpha = editor_alpha if (this.render_shadows && !low_quality) { - ctx.shadowColor = LiteGraph.DEFAULT_SHADOW_COLOR + ctx.shadowColor = LiteGraphSingleton.DEFAULT_SHADOW_COLOR ctx.shadowOffsetX = 2 * this.ds.scale ctx.shadowOffsetY = 2 * this.ds.scale ctx.shadowBlur = 3 * this.ds.scale @@ -5217,7 +5218,7 @@ export class LGraphCanvas // Render title buttons (if not collapsed) if (node.title_buttons && !node.flags.collapsed) { - const title_height = LiteGraph.NODE_TITLE_HEIGHT + const title_height = LiteGraphSingleton.NODE_TITLE_HEIGHT let current_x = size[0] // Start flush with right edge for (let i = 0; i < node.title_buttons.length; i++) { @@ -5244,7 +5245,7 @@ export class LGraphCanvas ctx.shadowColor = 'transparent' // TODO: Legacy behaviour: onDrawForeground received ctx in this state - ctx.strokeStyle = LiteGraph.NODE_BOX_OUTLINE_COLOR + ctx.strokeStyle = LiteGraphSingleton.NODE_BOX_OUTLINE_COLOR // Draw Foreground node.onDrawForeground?.(ctx, this, this.canvas) @@ -5372,7 +5373,7 @@ export class LGraphCanvas ctx.strokeStyle = fgcolor ctx.fillStyle = bgcolor - const title_height = LiteGraph.NODE_TITLE_HEIGHT + const title_height = LiteGraphSingleton.NODE_TITLE_HEIGHT const { low_quality } = this const { collapsed } = node.flags @@ -5404,8 +5405,8 @@ export class LGraphCanvas area[2], area[3], shape == RenderShape.CARD - ? [LiteGraph.ROUND_RADIUS, LiteGraph.ROUND_RADIUS, 0, 0] - : [LiteGraph.ROUND_RADIUS] + ? [LiteGraphSingleton.ROUND_RADIUS, LiteGraphSingleton.ROUND_RADIUS, 0, 0] + : [LiteGraphSingleton.ROUND_RADIUS] ) } else if (shape == RenderShape.CIRCLE) { ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5, 0, Math.PI * 2) @@ -5533,7 +5534,7 @@ export class LGraphCanvas const visibleReroutes: Reroute[] = [] - const now = LiteGraph.getTime() + const now = LiteGraphSingleton.getTime() const { visible_area } = this LGraphCanvas.#margin_area[0] = visible_area[0] - 20 LGraphCanvas.#margin_area[1] = visible_area[1] - 20 @@ -5560,7 +5561,7 @@ export class LGraphCanvas const link = graph._links.get(link_id) if (!link) continue - const endPos: Point = LiteGraph.vueNodesMode // TODO: still use LG get pos if vue nodes is off until stable + const endPos: Point = LiteGraphSingleton.vueNodesMode // TODO: still use LG get pos if vue nodes is off until stable ? getSlotPosition(node, i, true) : node.getInputPos(i) @@ -5572,7 +5573,7 @@ export class LGraphCanvas const startPos: Point = outputId === -1 ? [start_node.pos[0] + 10, start_node.pos[1] + 10] - : LiteGraph.vueNodesMode // TODO: still use LG get pos if vue nodes is off until stable + : LiteGraphSingleton.vueNodesMode // TODO: still use LG get pos if vue nodes is off until stable ? getSlotPosition(start_node, outputId, false) : start_node.getOutputPos(outputId) @@ -5992,23 +5993,23 @@ export class LGraphCanvas for (const node of visible_nodes) { ctx.fillStyle = 'black' ctx.fillRect( - node.pos[0] - LiteGraph.NODE_TITLE_HEIGHT, - node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT + node.pos[0] - LiteGraphSingleton.NODE_TITLE_HEIGHT, + node.pos[1] - LiteGraphSingleton.NODE_TITLE_HEIGHT, + LiteGraphSingleton.NODE_TITLE_HEIGHT, + LiteGraphSingleton.NODE_TITLE_HEIGHT ) if (node.order == 0) { ctx.strokeRect( - node.pos[0] - LiteGraph.NODE_TITLE_HEIGHT + 0.5, - node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT + 0.5, - LiteGraph.NODE_TITLE_HEIGHT, - LiteGraph.NODE_TITLE_HEIGHT + node.pos[0] - LiteGraphSingleton.NODE_TITLE_HEIGHT + 0.5, + node.pos[1] - LiteGraphSingleton.NODE_TITLE_HEIGHT + 0.5, + LiteGraphSingleton.NODE_TITLE_HEIGHT, + LiteGraphSingleton.NODE_TITLE_HEIGHT ) } ctx.fillStyle = '#FFF' ctx.fillText( toString(node.order), - node.pos[0] + LiteGraph.NODE_TITLE_HEIGHT * -0.5, + node.pos[0] + LiteGraphSingleton.NODE_TITLE_HEIGHT * -0.5, node.pos[1] - 6 ) } @@ -6107,7 +6108,7 @@ export class LGraphCanvas const { origin_id, origin_slot } = segment if (origin_id == null || origin_slot == null) { - new LiteGraph.ContextMenu(['Link has no origin'], { + new LiteGraphSingleton.ContextMenu(['Link has no origin'], { event: e, title }) @@ -6119,7 +6120,7 @@ export class LGraphCanvas const options = ['Add Node', 'Add Reroute', null, 'Delete', null] - const menu = new LiteGraph.ContextMenu(options, { + const menu = new LiteGraphSingleton.ContextMenu(options, { event: e, title, callback: inner_clicked.bind(this) @@ -6282,10 +6283,10 @@ export class LGraphCanvas } // check for defaults nodes for this slottype - const fromSlotType = slotX.type == LiteGraph.EVENT ? '_event_' : slotX.type + const fromSlotType = slotX.type == LiteGraphSingleton.EVENT ? '_event_' : slotX.type const slotTypesDefault = isFrom - ? LiteGraph.slot_types_default_out - : LiteGraph.slot_types_default_in + ? LiteGraphSingleton.slot_types_default_out + : LiteGraphSingleton.slot_types_default_in if (slotTypesDefault?.[fromSlotType]) { // TODO: Remove "any" kludge let nodeNewType: any = false @@ -6314,7 +6315,7 @@ export class LGraphCanvas } // that.graph.beforeChange(); - const newNode = LiteGraph.createNode(nodeNewType) + const newNode = LiteGraphSingleton.createNode(nodeNewType) if (newNode) { // if is object pass options if (nodeNewOpts) { @@ -6493,10 +6494,10 @@ export class LGraphCanvas } // get defaults nodes for this slottype - const fromSlotType = slotX.type == LiteGraph.EVENT ? '_event_' : slotX.type + const fromSlotType = slotX.type == LiteGraphSingleton.EVENT ? '_event_' : slotX.type const slotTypesDefault = isFrom - ? LiteGraph.slot_types_default_out - : LiteGraph.slot_types_default_in + ? LiteGraphSingleton.slot_types_default_out + : LiteGraphSingleton.slot_types_default_in if (slotTypesDefault?.[fromSlotType]) { if (typeof slotTypesDefault[fromSlotType] == 'object') { for (const typeX in slotTypesDefault[fromSlotType]) { @@ -6508,7 +6509,7 @@ export class LGraphCanvas } // build menu - const menu = new LiteGraph.ContextMenu(options, { + const menu = new LiteGraphSingleton.ContextMenu(options, { event: opts.e, extra: slotX, title: @@ -6657,20 +6658,20 @@ export class LGraphCanvas let dialogCloseTimer: number let prevent_timeout = 0 - LiteGraph.pointerListenerAdd(dialog, 'leave', function () { + LiteGraphSingleton.pointerListenerAdd(dialog, 'leave', function () { if (prevent_timeout) return - if (LiteGraph.dialog_close_on_mouse_leave) { - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) { + if (LiteGraphSingleton.dialog_close_on_mouse_leave) { + if (!dialog.is_modified && LiteGraphSingleton.dialog_close_on_mouse_leave) { // @ts-expect-error - setTimeout type dialogCloseTimer = setTimeout( dialog.close, - LiteGraph.dialog_close_on_mouse_leave_delay + LiteGraphSingleton.dialog_close_on_mouse_leave_delay ) } } }) - LiteGraph.pointerListenerAdd(dialog, 'enter', function () { - if (LiteGraph.dialog_close_on_mouse_leave && dialogCloseTimer) + LiteGraphSingleton.pointerListenerAdd(dialog, 'enter', function () { + if (LiteGraphSingleton.dialog_close_on_mouse_leave && dialogCloseTimer) clearTimeout(dialogCloseTimer) }) const selInDia = dialog.querySelectorAll('select') @@ -6779,7 +6780,7 @@ export class LGraphCanvas node_to: null, // TODO check for registered_slot_[in/out]_types not empty // this will be checked for functionality enabled : filter on slot type, in and out - do_type_filter: LiteGraph.search_filter_enabled, + do_type_filter: LiteGraphSingleton.search_filter_enabled, // these are default: pass to set initially set values // @ts-expect-error Property missing from interface definition @@ -6788,9 +6789,9 @@ export class LGraphCanvas type_filter_out: false, show_general_if_none_on_typefilter: true, show_general_after_typefiltered: true, - hide_on_mouse_leave: LiteGraph.search_hide_on_mouse_leave, + hide_on_mouse_leave: LiteGraphSingleton.search_hide_on_mouse_leave, show_all_if_empty: true, - show_all_on_open: LiteGraph.search_show_all_on_open + show_all_on_open: LiteGraphSingleton.search_show_all_on_open } Object.assign(options, searchOptions) @@ -6851,7 +6852,7 @@ export class LGraphCanvas // FIXME: Remove "any" kludge let prevent_timeout: any = false let timeout_close: number | null = null - LiteGraph.pointerListenerAdd(dialog, 'enter', function () { + LiteGraphSingleton.pointerListenerAdd(dialog, 'enter', function () { if (timeout_close) { clearTimeout(timeout_close) timeout_close = null @@ -6946,12 +6947,12 @@ export class LGraphCanvas // if should filter on type, load and fill selected and choose elements if passed if (options.do_type_filter) { if (selIn) { - const aSlots = LiteGraph.slot_types_in + const aSlots = LiteGraphSingleton.slot_types_in const nSlots = aSlots.length if ( - options.type_filter_in == LiteGraph.EVENT || - options.type_filter_in == LiteGraph.ACTION + options.type_filter_in == LiteGraphSingleton.EVENT || + options.type_filter_in == LiteGraphSingleton.ACTION ) { options.type_filter_in = '_event_' } @@ -6974,11 +6975,11 @@ export class LGraphCanvas }) } if (selOut) { - const aSlots = LiteGraph.slot_types_out + const aSlots = LiteGraphSingleton.slot_types_out if ( - options.type_filter_out == LiteGraph.EVENT || - options.type_filter_out == LiteGraph.ACTION + options.type_filter_out == LiteGraphSingleton.EVENT || + options.type_filter_out == LiteGraphSingleton.ACTION ) { options.type_filter_out = '_event_' } @@ -7037,7 +7038,7 @@ export class LGraphCanvas if (!graphcanvas.graph) throw new NullGraphError() graphcanvas.graph.beforeChange() - const node = LiteGraph.createNode(name) + const node = LiteGraphSingleton.createNode(name) if (node) { node.pos = graphcanvas.convertEventToCanvasOffset(safeEvent) graphcanvas.graph.add(node, false) @@ -7190,7 +7191,7 @@ export class LGraphCanvas sOut = that.search_box.querySelector('.slot_out_type_filter') } - const keys = Object.keys(LiteGraph.registered_node_types) + const keys = Object.keys(LiteGraphSingleton.registered_node_types) const filtered = keys.filter((x) => inner_test_filter(x)) for (const item of filtered) { @@ -7210,7 +7211,7 @@ export class LGraphCanvas // FIXME: Undeclared variable again // @ts-expect-error Variable declared without type annotation filtered_extra = [] - for (const i in LiteGraph.registered_node_types) { + for (const i in LiteGraphSingleton.registered_node_types) { if ( inner_test_filter(i, { inTypeOverride: sIn && sIn.value ? '*' : false, @@ -7240,7 +7241,7 @@ export class LGraphCanvas ) { // @ts-expect-error Variable declared without type annotation filtered_extra = [] - for (const i in LiteGraph.registered_node_types) { + for (const i in LiteGraphSingleton.registered_node_types) { if (inner_test_filter(i, { skipFilter: true })) // @ts-expect-error Variable declared without type annotation filtered_extra.push(i) @@ -7271,7 +7272,7 @@ export class LGraphCanvas outTypeOverride: false } const opts = Object.assign(optsDef, optsIn) - const ctor = LiteGraph.registered_node_types[type] + const ctor = LiteGraphSingleton.registered_node_types[type] if (filter && ctor.filter != filter) return false if ( (!options.show_all_if_empty || str) && @@ -7288,18 +7289,18 @@ export class LGraphCanvas let sV = opts.inTypeOverride !== false ? opts.inTypeOverride : sIn.value // type is stored - if (sIn && sV && LiteGraph.registered_slot_in_types[sV]?.nodes) { + if (sIn && sV && LiteGraphSingleton.registered_slot_in_types[sV]?.nodes) { const doesInc = - LiteGraph.registered_slot_in_types[sV].nodes.includes(sType) + LiteGraphSingleton.registered_slot_in_types[sV].nodes.includes(sType) if (doesInc === false) return false } sV = sOut.value if (opts.outTypeOverride !== false) sV = opts.outTypeOverride // type is stored - if (sOut && sV && LiteGraph.registered_slot_out_types[sV]?.nodes) { + if (sOut && sV && LiteGraphSingleton.registered_slot_out_types[sV]?.nodes) { const doesInc = - LiteGraph.registered_slot_out_types[sV].nodes.includes(sType) + LiteGraphSingleton.registered_slot_out_types[sV].nodes.includes(sType) if (doesInc === false) return false } } @@ -7311,7 +7312,7 @@ export class LGraphCanvas const help = document.createElement('div') first ||= type - const nodeType = LiteGraph.registered_node_types[type] + const nodeType = LiteGraphSingleton.registered_node_types[type] if (nodeType?.title) { help.textContent = nodeType?.title const typeEl = document.createElement('span') @@ -7545,16 +7546,16 @@ export class LGraphCanvas dialog.addEventListener('mouseleave', function () { if (prevent_timeout) return - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) { + if (!dialog.is_modified && LiteGraphSingleton.dialog_close_on_mouse_leave) { // @ts-expect-error - setTimeout type dialogCloseTimer = setTimeout( dialog.close, - LiteGraph.dialog_close_on_mouse_leave_delay + LiteGraphSingleton.dialog_close_on_mouse_leave_delay ) } }) dialog.addEventListener('mouseenter', function () { - if (options.closeOnLeave || LiteGraph.dialog_close_on_mouse_leave) { + if (options.closeOnLeave || LiteGraphSingleton.dialog_close_on_mouse_leave) { if (dialogCloseTimer) clearTimeout(dialogCloseTimer) } }) @@ -7757,7 +7758,7 @@ export class LGraphCanvas innerChange(propname, v) return false } - new LiteGraph.ContextMenu( + new LiteGraphSingleton.ContextMenu( values, { event, @@ -7840,8 +7841,8 @@ export class LGraphCanvas if (typeof value !== 'string') throw new TypeError('Attempting to set mode to non-string value.') - const kV = Object.values(LiteGraph.NODE_MODES).indexOf(value) - if (kV !== -1 && LiteGraph.NODE_MODES[kV]) { + const kV = Object.values(LiteGraphSingleton.NODE_MODES).indexOf(value) + if (kV !== -1 && LiteGraphSingleton.NODE_MODES[kV]) { node.changeMode(kV) } else { console.warn(`unexpected mode: ${value}`) @@ -7872,12 +7873,12 @@ export class LGraphCanvas panel.addWidget('string', 'Title', node.title, {}, fUpdate) const mode = - node.mode == null ? undefined : LiteGraph.NODE_MODES[node.mode] + node.mode == null ? undefined : LiteGraphSingleton.NODE_MODES[node.mode] panel.addWidget( 'combo', 'Mode', mode, - { values: LiteGraph.NODE_MODES }, + { values: LiteGraphSingleton.NODE_MODES }, fUpdate ) @@ -8025,7 +8026,7 @@ export class LGraphCanvas | IContextMenuValue | IContextMenuValue | IContextMenuValue - | IContextMenuValue<(typeof LiteGraph.VALID_SHAPES)[number]> + | IContextMenuValue<(typeof LiteGraphSingleton.VALID_SHAPES)[number]> | null )[] if (node.getMenuOptions) { @@ -8247,10 +8248,10 @@ export class LGraphCanvas } // @ts-expect-error Slot type can be number and has number checks options.title = (slot.input ? slot.input.type : slot.output.type) || '*' - if (slot.input && slot.input.type == LiteGraph.ACTION) + if (slot.input && slot.input.type == LiteGraphSingleton.ACTION) options.title = 'Action' - if (slot.output && slot.output.type == LiteGraph.EVENT) + if (slot.output && slot.output.type == LiteGraphSingleton.EVENT) options.title = 'Event' } else { // on node @@ -8312,7 +8313,7 @@ export class LGraphCanvas if (!menu_info) return // @ts-expect-error Remove param ref_window - unused - new LiteGraph.ContextMenu(menu_info, options, ref_window) + new LiteGraphSingleton.ContextMenu(menu_info, options, ref_window) const createDialog = (options: IDialogOptions) => this.createDialog( diff --git a/src/lib/litegraph/src/LGraphGroup.ts b/src/lib/litegraph/src/LGraphGroup.ts index f00f302e6..f36840592 100644 --- a/src/lib/litegraph/src/LGraphGroup.ts +++ b/src/lib/litegraph/src/LGraphGroup.ts @@ -13,7 +13,7 @@ import type { Positionable, Size } from './interfaces' -import { LiteGraph } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' import { containsCentre, containsRect, @@ -39,7 +39,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { color?: string title: string font?: string - font_size: number = LiteGraph.DEFAULT_GROUP_FONT || 24 + font_size: number = LiteGraphSingleton.DEFAULT_GROUP_FONT || 24 _bounding: Float32Array = new Float32Array([ 10, 10, @@ -170,7 +170,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { */ draw(graphCanvas: LGraphCanvas, ctx: CanvasRenderingContext2D): void { const { padding, resizeLength, defaultColour } = LGraphGroup - const font_size = this.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE + const font_size = this.font_size || LiteGraphSingleton.DEFAULT_GROUP_FONT_SIZE const [x, y] = this._pos const [width, height] = this._size @@ -201,7 +201,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { ctx.fill() // Title - ctx.font = `${font_size}px ${LiteGraph.GROUP_FONT}` + ctx.font = `${font_size}px ${LiteGraphSingleton.GROUP_FONT}` ctx.textAlign = 'left' ctx.fillText( this.title + (this.pinned ? 'šŸ“Œ' : ''), @@ -209,7 +209,7 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable { y + font_size ) - if (LiteGraph.highlight_selected_group && this.selected) { + if (LiteGraphSingleton.highlight_selected_group && this.selected) { strokeShape(ctx, this._bounding, { title_height: this.titleHeight, padding diff --git a/src/lib/litegraph/src/LGraphNode.ts b/src/lib/litegraph/src/LGraphNode.ts index 20e26e211..c84167773 100644 --- a/src/lib/litegraph/src/LGraphNode.ts +++ b/src/lib/litegraph/src/LGraphNode.ts @@ -44,10 +44,10 @@ import type { } from './interfaces' import { type LGraphNodeConstructor, - LiteGraph, type Subgraph, type SubgraphNode } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' import { createBounds, isInRect, @@ -244,11 +244,11 @@ export class LGraphNode * The font style used to render the node's title text. */ get titleFontStyle(): string { - return `${LiteGraph.NODE_TEXT_SIZE}px ${LiteGraph.NODE_FONT}` + return `${LiteGraphSingleton.NODE_TEXT_SIZE}px ${LiteGraphSingleton.NODE_FONT}` } get innerFontStyle(): string { - return `normal ${LiteGraph.NODE_SUBTEXT_SIZE}px ${LiteGraph.NODE_FONT}` + return `normal ${LiteGraphSingleton.NODE_SUBTEXT_SIZE}px ${LiteGraphSingleton.NODE_FONT}` } get displayType(): string { @@ -303,13 +303,13 @@ export class LGraphNode /** The fg color used to render the node. */ get renderingColor(): string { - return this.color || this.constructor.color || LiteGraph.NODE_DEFAULT_COLOR + return this.color || this.constructor.color || LiteGraphSingleton.NODE_DEFAULT_COLOR } /** The bg color used to render the node. */ get renderingBgColor(): string { return ( - this.bgcolor || this.constructor.bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR + this.bgcolor || this.constructor.bgcolor || LiteGraphSingleton.NODE_DEFAULT_BGCOLOR ) } @@ -317,17 +317,17 @@ export class LGraphNode get renderingBoxColor(): string { if (this.boxcolor) return this.boxcolor - if (LiteGraph.node_box_coloured_when_on) { + if (LiteGraphSingleton.node_box_coloured_when_on) { if (this.action_triggered) return '#FFF' if (this.execute_triggered) return '#AAA' } - if (LiteGraph.node_box_coloured_by_mode) { + if (LiteGraphSingleton.node_box_coloured_by_mode) { const modeColour = - LiteGraph.NODE_MODES_COLORS[this.mode ?? LGraphEventMode.ALWAYS] + LiteGraphSingleton.NODE_MODES_COLORS[this.mode ?? LGraphEventMode.ALWAYS] if (modeColour) return modeColour } - return LiteGraph.NODE_DEFAULT_BOXCOLOR + return LiteGraphSingleton.NODE_DEFAULT_BOXCOLOR } /** @inheritdoc {@link IColorable.setColorOption} */ @@ -507,7 +507,7 @@ export class LGraphNode * The shape of the node used for rendering. @see {@link RenderShape} */ get renderingShape(): RenderShape { - return this._shape || this.constructor.shape || LiteGraph.NODE_DEFAULT_SHAPE + return this._shape || this.constructor.shape || LiteGraphSingleton.NODE_DEFAULT_SHAPE } public get is_selected(): boolean | undefined { @@ -720,7 +720,7 @@ export class LGraphNode return { padding: 12, lineWidth: 10, - color: LiteGraph.NODE_ERROR_COLOUR + color: LiteGraphSingleton.NODE_ERROR_COLOUR } } } @@ -734,10 +734,10 @@ export class LGraphNode } constructor(title: string, type?: string) { - this.id = LiteGraph.use_uuids ? LiteGraph.uuidv4() : -1 + this.id = LiteGraphSingleton.use_uuids ? LiteGraphSingleton.uuidv4() : -1 this.title = title || 'Unnamed' this.type = type ?? '' - this.size = [LiteGraph.NODE_WIDTH, 60] + this.size = [LiteGraphSingleton.NODE_WIDTH, 60] this.pos = [10, 10] this.strokeStyles = { error: this.#getErrorStrokeStyle, @@ -778,7 +778,7 @@ export class LGraphNode this[j]?.configure(info[j]) } else { // @ts-expect-error #594 - this[j] = LiteGraph.cloneObject(info[j], this[j]) + this[j] = LiteGraphSingleton.cloneObject(info[j], this[j]) } } else { // value @@ -863,7 +863,7 @@ export class LGraphNode type: this.type, pos: [this.pos[0], this.pos[1]], size: [this.size[0], this.size[1]], - flags: LiteGraph.cloneObject(this.flags), + flags: LiteGraphSingleton.cloneObject(this.flags), order: this.order, mode: this.mode, showAdvanced: this.showAdvanced @@ -881,7 +881,7 @@ export class LGraphNode if (this.title && this.title != this.constructor.title) o.title = this.title - if (this.properties) o.properties = LiteGraph.cloneObject(this.properties) + if (this.properties) o.properties = LiteGraphSingleton.cloneObject(this.properties) const { widgets } = this if (widgets && this.serialize_widgets) { @@ -911,11 +911,11 @@ export class LGraphNode /* Creates a clone of this node */ clone(): LGraphNode | null { if (this.type == null) return null - const node = LiteGraph.createNode(this.type) + const node = LiteGraphSingleton.createNode(this.type) if (!node) return null // we clone it because serialize returns shared containers - const data = LiteGraph.cloneObject(this.serialize()) + const data = LiteGraphSingleton.cloneObject(this.serialize()) const { inputs, outputs } = data // remove links @@ -934,7 +934,7 @@ export class LGraphNode // @ts-expect-error Exceptional case: id is removed so that the graph can assign a new one on add. delete data.id - if (LiteGraph.use_uuids) data.id = LiteGraph.uuidv4() + if (LiteGraphSingleton.use_uuids) data.id = LiteGraphSingleton.uuidv4() node.configure(data) @@ -1255,7 +1255,7 @@ export class LGraphNode addOnTriggerInput(): number { const trigS = this.findInputSlot('onTrigger') if (trigS == -1) { - this.addInput('onTrigger', LiteGraph.EVENT, { + this.addInput('onTrigger', LiteGraphSingleton.EVENT, { nameLocked: true }) return this.findInputSlot('onTrigger') @@ -1266,7 +1266,7 @@ export class LGraphNode addOnExecutedOutput(): number { const trigS = this.findOutputSlot('onExecuted') if (trigS == -1) { - this.addOutput('onExecuted', LiteGraph.ACTION, { + this.addOutput('onExecuted', LiteGraphSingleton.ACTION, { nameLocked: true }) return this.findOutputSlot('onExecuted') @@ -1298,7 +1298,7 @@ export class LGraphNode break // @ts-expect-error Not impl. - case LiteGraph.ON_REQUEST: + case LiteGraphSingleton.ON_REQUEST: break default: @@ -1385,12 +1385,12 @@ export class LGraphNode return } - if (this.graph) this.graph._last_trigger_time = LiteGraph.getTime() + if (this.graph) this.graph._last_trigger_time = LiteGraphSingleton.getTime() for (const [i, output] of outputs.entries()) { if ( !output || - output.type !== LiteGraph.EVENT || + output.type !== LiteGraphSingleton.EVENT || (action && output.name != action) ) { continue @@ -1430,7 +1430,7 @@ export class LGraphNode if (!links || !links.length) return if (!this.graph) throw new NullGraphError() - this.graph._last_trigger_time = LiteGraph.getTime() + this.graph._last_trigger_time = LiteGraphSingleton.getTime() // for every link attached here for (const id of links) { @@ -1441,7 +1441,7 @@ export class LGraphNode // not connected if (!link_info) continue - link_info._last_time = LiteGraph.getTime() + link_info._last_time = LiteGraphSingleton.getTime() const node = this.graph.getNodeById(link_info.target_id) // node not found? if (!node) continue @@ -1551,8 +1551,8 @@ export class LGraphNode this.outputs.push(output) this.onOutputAdded?.(output) - if (LiteGraph.auto_load_slot_types) - LiteGraph.registerNodeAndSlotType(this, type, true) + if (LiteGraphSingleton.auto_load_slot_types) + LiteGraphSingleton.registerNodeAndSlotType(this, type, true) this.expandToFitContent() this.setDirtyCanvas(true, true) @@ -1609,7 +1609,7 @@ export class LGraphNode this.expandToFitContent() this.onInputAdded?.(input) - LiteGraph.registerNodeAndSlotType(this, type) + LiteGraphSingleton.registerNodeAndSlotType(this, type) this.setDirtyCanvas(true, true) return input @@ -1656,9 +1656,9 @@ export class LGraphNode const size = out || new Float32Array([0, 0]) rows = Math.max(rows, 1) // although it should be graphcanvas.inner_text_font size - const font_size = LiteGraph.NODE_TEXT_SIZE + const font_size = LiteGraphSingleton.NODE_TEXT_SIZE - const padLeft = LiteGraph.NODE_TITLE_HEIGHT + const padLeft = LiteGraphSingleton.NODE_TITLE_HEIGHT const padRight = padLeft * 0.33 const title_width = padLeft + compute_text_size(this.title, this.titleFontStyle) + padRight @@ -1689,13 +1689,13 @@ export class LGraphNode } } - const minWidth = LiteGraph.NODE_WIDTH * (widgets?.length ? 1.5 : 1) + const minWidth = LiteGraphSingleton.NODE_WIDTH * (widgets?.length ? 1.5 : 1) // Text + slot width + centre padding const centrePadding = input_width && output_width ? 5 : 0 const slotsWidth = input_width + output_width + - 2 * LiteGraph.NODE_SLOT_HEIGHT + + 2 * LiteGraphSingleton.NODE_SLOT_HEIGHT + centrePadding // Total distance from edge of node to the inner edge of the widget 'previous' arrow button @@ -1706,7 +1706,7 @@ export class LGraphNode size[0] = Math.max(slotsWidth, widgetWidth, title_width, minWidth) size[1] = - (this.constructor.slot_start_y || 0) + rows * LiteGraph.NODE_SLOT_HEIGHT + (this.constructor.slot_start_y || 0) + rows * LiteGraphSingleton.NODE_SLOT_HEIGHT // Get widget height & expand size if necessary let widgets_height = 0 @@ -1725,7 +1725,7 @@ export class LGraphNode widget_height += minHeight } else { - widget_height += LiteGraph.NODE_WIDGET_HEIGHT + widget_height += LiteGraphSingleton.NODE_WIDGET_HEIGHT } widgets_height += widget_height + 4 } @@ -1758,7 +1758,7 @@ export class LGraphNode inResizeCorner(canvasX: number, canvasY: number): boolean { const rows = this.outputs ? this.outputs.length : 1 const outputs_offset = - (this.constructor.slot_start_y || 0) + rows * LiteGraph.NODE_SLOT_HEIGHT + (this.constructor.slot_start_y || 0) + rows * LiteGraphSingleton.NODE_SLOT_HEIGHT return isInRectangle( canvasX, canvasY, @@ -1959,7 +1959,7 @@ export class LGraphNode // If Vue nodes mode is enabled, skip LiteGraph's direct position update // The layout store will handle the movement and sync back to LiteGraph - if (LiteGraph.vueNodesMode) { + if (LiteGraphSingleton.vueNodesMode) { // Vue nodes handle their own dragging through the layout store // This prevents the snap-back issue from conflicting position updates return @@ -1983,7 +1983,7 @@ export class LGraphNode const renderTitle = titleMode != TitleMode.TRANSPARENT_TITLE && titleMode != TitleMode.NO_TITLE - const titleHeight = renderTitle ? LiteGraph.NODE_TITLE_HEIGHT : 0 + const titleHeight = renderTitle ? LiteGraphSingleton.NODE_TITLE_HEIGHT : 0 out[0] = this.pos[0] out[1] = this.pos[1] + -titleHeight @@ -1995,10 +1995,10 @@ export class LGraphNode this._collapsed_width = Math.min( this.size[0], ctx.measureText(this.getTitle() ?? '').width + - LiteGraph.NODE_TITLE_HEIGHT * 2 + LiteGraphSingleton.NODE_TITLE_HEIGHT * 2 ) - out[2] = this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH - out[3] = LiteGraph.NODE_TITLE_HEIGHT + out[2] = this._collapsed_width || LiteGraphSingleton.NODE_COLLAPSED_WIDTH + out[3] = LiteGraphSingleton.NODE_TITLE_HEIGHT } } @@ -2055,7 +2055,7 @@ export class LGraphNode * @returns true if the x,y point is in the collapse button area, otherwise false */ isPointInCollapse(x: number, y: number): boolean { - const squareLength = LiteGraph.NODE_TITLE_HEIGHT + const squareLength = LiteGraphSingleton.NODE_TITLE_HEIGHT return isInRectangle( x, y, @@ -2158,7 +2158,7 @@ export class LGraphNode const h = widget.computedHeight ?? widget.computeSize?.(nodeWidth)[1] ?? - LiteGraph.NODE_WIDGET_HEIGHT + LiteGraphSingleton.NODE_WIDGET_HEIGHT const maybeDOMWidget = widget as { margin?: number } const mtop = maybeDOMWidget.margin ?? -2 @@ -2439,10 +2439,10 @@ export class LGraphNode for (const sourceType of sourceTypes) { // TODO: Remove _event_ entirely. - const source = sourceType == '_event_' ? LiteGraph.EVENT : sourceType + const source = sourceType == '_event_' ? LiteGraphSingleton.EVENT : sourceType for (const destType of destTypes) { - const dest = destType == '_event_' ? LiteGraph.EVENT : destType + const dest = destType == '_event_' ? LiteGraphSingleton.EVENT : destType if (source == dest || source === '*' || dest === '*') { if (preferFreeSlot && (slot.links?.length || slot.link != null)) { @@ -2502,9 +2502,9 @@ export class LGraphNode if (slot >= 0 && slot !== null) return slot // TODO: Remove or reimpl. events. WILL CREATE THE onTrigger IN SLOT - if (opts.createEventInCase && slotType == LiteGraph.EVENT) { + if (opts.createEventInCase && slotType == LiteGraphSingleton.EVENT) { if (findInputs) return -1 - if (LiteGraph.do_add_triggers_slots) return node.addOnExecutedOutput() + if (LiteGraphSingleton.do_add_triggers_slots) return node.addOnExecutedOutput() } // connect to the first general output slot if not found a specific type and @@ -2517,7 +2517,7 @@ export class LGraphNode opts.wildcardToTyped && (slotType == 0 || slotType == '*' || slotType == '') ) { - const opt = { typesNotAccepted: [LiteGraph.EVENT] } + const opt = { typesNotAccepted: [LiteGraphSingleton.EVENT] } const nonEventSlot = findInputs ? node.findInputSlotFree(opt) : node.findOutputSlotFree(opt) @@ -2637,7 +2637,7 @@ export class LGraphNode ) { return ( this.id !== node.id && - LiteGraph.isValidConnection(fromSlot.type, toSlot.type) + LiteGraphSingleton.isValidConnection(fromSlot.type, toSlot.type) ) } @@ -2671,12 +2671,12 @@ export class LGraphNode if (typeof slot === 'string') { slot = this.findOutputSlot(slot) if (slot == -1) { - if (LiteGraph.debug) + if (LiteGraphSingleton.debug) console.log(`Connect: Error, no slot of name ${slot}`) return null } } else if (!outputs || slot >= outputs.length) { - if (LiteGraph.debug) console.log('Connect: Error, slot number not found') + if (LiteGraphSingleton.debug) console.log('Connect: Error, slot number not found') return null } @@ -2695,13 +2695,13 @@ export class LGraphNode if (typeof target_slot === 'string') { targetIndex = target_node.findInputSlot(target_slot) if (targetIndex == -1) { - if (LiteGraph.debug) + if (LiteGraphSingleton.debug) console.log(`Connect: Error, no slot of name ${targetIndex}`) return null } - } else if (target_slot === LiteGraph.EVENT) { + } else if (target_slot === LiteGraphSingleton.EVENT) { // TODO: Events - if (LiteGraph.do_add_triggers_slots) { + if (LiteGraphSingleton.do_add_triggers_slots) { target_node.changeMode(LGraphEventMode.ON_TRIGGER) targetIndex = target_node.findInputSlot('onTrigger') } else { @@ -2728,7 +2728,7 @@ export class LGraphNode !target_node.inputs || targetIndex >= target_node.inputs.length ) { - if (LiteGraph.debug) console.log('Connect: Error, slot number not found') + if (LiteGraphSingleton.debug) console.log('Connect: Error, slot number not found') return null } @@ -2739,8 +2739,8 @@ export class LGraphNode if (output.links?.length) { if ( - output.type === LiteGraph.EVENT && - !LiteGraph.allow_multi_output_for_events + output.type === LiteGraphSingleton.EVENT && + !LiteGraphSingleton.allow_multi_output_for_events ) { graph.beforeChange() // @ts-expect-error Unused param @@ -2783,7 +2783,7 @@ export class LGraphNode } // check targetSlot and check connection types - if (!LiteGraph.isValidConnection(output.type, input.type)) { + if (!LiteGraphSingleton.isValidConnection(output.type, input.type)) { this.setDirtyCanvas(false, true) return null } @@ -2954,12 +2954,12 @@ export class LGraphNode if (typeof slot === 'string') { slot = this.findOutputSlot(slot) if (slot == -1) { - if (LiteGraph.debug) + if (LiteGraphSingleton.debug) console.log(`Connect: Error, no slot of name ${slot}`) return false } } else if (!this.outputs || slot >= this.outputs.length) { - if (LiteGraph.debug) console.log('Connect: Error, slot number not found') + if (LiteGraphSingleton.debug) console.log('Connect: Error, slot number not found') return false } @@ -3074,12 +3074,12 @@ export class LGraphNode if (typeof slot === 'string') { slot = this.findInputSlot(slot) if (slot == -1) { - if (LiteGraph.debug) + if (LiteGraphSingleton.debug) console.log(`Connect: Error, no slot of name ${slot}`) return false } } else if (!this.inputs || slot >= this.inputs.length) { - if (LiteGraph.debug) { + if (LiteGraphSingleton.debug) { console.log('Connect: Error, slot number not found') } return false @@ -3183,16 +3183,16 @@ export class LGraphNode } = this if (this.flags.collapsed) { - const w = this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH + const w = this._collapsed_width || LiteGraphSingleton.NODE_COLLAPSED_WIDTH out[0] = is_input ? nodeX : nodeX + w - out[1] = nodeY - LiteGraph.NODE_TITLE_HEIGHT * 0.5 + out[1] = nodeY - LiteGraphSingleton.NODE_TITLE_HEIGHT * 0.5 return out } // weird feature that never got finished if (is_input && slot_number == -1) { - out[0] = nodeX + LiteGraph.NODE_TITLE_HEIGHT * 0.5 - out[1] = nodeY + LiteGraph.NODE_TITLE_HEIGHT * 0.5 + out[0] = nodeX + LiteGraphSingleton.NODE_TITLE_HEIGHT * 0.5 + out[1] = nodeY + LiteGraphSingleton.NODE_TITLE_HEIGHT * 0.5 return out } @@ -3211,7 +3211,7 @@ export class LGraphNode } // default vertical slots - const offset = LiteGraph.NODE_SLOT_HEIGHT * 0.5 + const offset = LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 const slotIndex = is_input ? this.#defaultVerticalInputs.indexOf(this.inputs[slot_number]) : this.#defaultVerticalOutputs.indexOf(this.outputs[slot_number]) @@ -3219,7 +3219,7 @@ export class LGraphNode out[0] = is_input ? nodeX + offset : nodeX + this.size[0] + 1 - offset out[1] = nodeY + - (slotIndex + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + + (slotIndex + 0.7) * LiteGraphSingleton.NODE_SLOT_HEIGHT + (this.constructor.slot_start_y || 0) return out } @@ -3297,7 +3297,7 @@ export class LGraphNode /** @see {@link snapToGrid} */ alignToGrid(): void { - this.snapToGrid(LiteGraph.CANVAS_GRID_SIZE) + this.snapToGrid(LiteGraphSingleton.CANVAS_GRID_SIZE) } /* Console output */ @@ -3321,7 +3321,7 @@ export class LGraphNode } const img: AsyncImageElement = new Image() - img.src = LiteGraph.node_images_path + url + img.src = LiteGraphSingleton.node_images_path + url img.ready = false const dirty = () => this.setDirtyCanvas(true) @@ -3416,7 +3416,7 @@ export class LGraphNode get width() { return this.collapsed - ? this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH + ? this._collapsed_width || LiteGraphSingleton.NODE_COLLAPSED_WIDTH : this.size[0] } @@ -3424,7 +3424,7 @@ export class LGraphNode * Returns the height of the node, including the title bar. */ get height() { - return LiteGraph.NODE_TITLE_HEIGHT + this.bodyHeight + return LiteGraphSingleton.NODE_TITLE_HEIGHT + this.bodyHeight } /** @@ -3447,7 +3447,7 @@ export class LGraphNode (acc, badge) => acc + badge.getWidth(ctx) + gap, 0 ) - const y = -(LiteGraph.NODE_TITLE_HEIGHT + gap) + const y = -(LiteGraphSingleton.NODE_TITLE_HEIGHT + gap) for (const badge of badgeInstances) { badge.draw(ctx, currentX, y - badge.height) @@ -3462,7 +3462,7 @@ export class LGraphNode ctx: CanvasRenderingContext2D, { scale, - title_height = LiteGraph.NODE_TITLE_HEIGHT, + title_height = LiteGraphSingleton.NODE_TITLE_HEIGHT, low_quality = false }: DrawTitleOptions ): void { @@ -3480,7 +3480,7 @@ export class LGraphNode } if (this.collapsed) { - ctx.shadowColor = LiteGraph.DEFAULT_SHADOW_COLOR + ctx.shadowColor = LiteGraphSingleton.DEFAULT_SHADOW_COLOR } ctx.fillStyle = this.constructor.title_color || fgcolor @@ -3495,8 +3495,8 @@ export class LGraphNode size[0], title_height, this.collapsed - ? [LiteGraph.ROUND_RADIUS] - : [LiteGraph.ROUND_RADIUS, LiteGraph.ROUND_RADIUS, 0, 0] + ? [LiteGraphSingleton.ROUND_RADIUS] + : [LiteGraphSingleton.ROUND_RADIUS, LiteGraphSingleton.ROUND_RADIUS, 0, 0] ) } ctx.fill() @@ -3513,7 +3513,7 @@ export class LGraphNode { scale, low_quality = false, - title_height = LiteGraph.NODE_TITLE_HEIGHT, + title_height = LiteGraphSingleton.NODE_TITLE_HEIGHT, box_size = 10 }: DrawTitleBoxOptions ): void { @@ -3589,7 +3589,7 @@ export class LGraphNode scale, default_title_color, low_quality = false, - title_height = LiteGraph.NODE_TITLE_HEIGHT + title_height = LiteGraphSingleton.NODE_TITLE_HEIGHT }: DrawTitleTextOptions ): void { const size = this.renderingSize @@ -3617,7 +3617,7 @@ export class LGraphNode const title = String(rawTitle) + (this.pinned ? 'šŸ“Œ' : '') if (title) { if (selected) { - ctx.fillStyle = LiteGraph.NODE_SELECTED_TITLE_COLOR + ctx.fillStyle = LiteGraphSingleton.NODE_SELECTED_TITLE_COLOR } else { ctx.fillStyle = this.constructor.title_text_color || default_title_color } @@ -3656,7 +3656,7 @@ export class LGraphNode ctx.fillText( displayTitle, title_height, - LiteGraph.NODE_TITLE_TEXT_Y - title_height + LiteGraphSingleton.NODE_TITLE_TEXT_Y - title_height ) } } @@ -3689,7 +3689,7 @@ export class LGraphNode if (input.link == null) continue const output = outputs[index] - if (!output || !LiteGraph.isValidConnection(input.type, output.type)) + if (!output || !LiteGraphSingleton.isValidConnection(input.type, output.type)) continue const inLink = _links.get(input.link) @@ -3713,7 +3713,7 @@ export class LGraphNode if (!inNode) continue for (const output of outputs) { - if (!LiteGraph.isValidConnection(input.type, output.type)) continue + if (!LiteGraphSingleton.isValidConnection(input.type, output.type)) continue bypassAllLinks(output, inNode, inLink, graph) break @@ -3764,7 +3764,7 @@ export class LGraphNode const nodeWidth = this.size[0] const { widgets } = this - const H = LiteGraph.NODE_WIDGET_HEIGHT + const H = LiteGraphSingleton.NODE_WIDGET_HEIGHT const showText = !lowQuality ctx.save() ctx.globalAlpha = editorAlpha @@ -3774,8 +3774,8 @@ export class LGraphNode const { y } = widget const outlineColour = widget.advanced - ? LiteGraph.WIDGET_ADVANCED_OUTLINE_COLOR - : LiteGraph.WIDGET_OUTLINE_COLOR + ? LiteGraphSingleton.WIDGET_ADVANCED_OUTLINE_COLOR + : LiteGraphSingleton.WIDGET_OUTLINE_COLOR widget.last_y = y // Disable widget if it is disabled or if the value is passed from socket connection. @@ -3833,12 +3833,12 @@ export class LGraphNode ? this.getInputPos(slotIndex) : this.getOutputPos(slotIndex) - slot.boundingRect[0] = pos[0] - LiteGraph.NODE_SLOT_HEIGHT * 0.5 - slot.boundingRect[1] = pos[1] - LiteGraph.NODE_SLOT_HEIGHT * 0.5 + slot.boundingRect[0] = pos[0] - LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 + slot.boundingRect[1] = pos[1] - LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 slot.boundingRect[2] = slot.isWidgetInputSlot ? BaseWidget.margin - : LiteGraph.NODE_SLOT_HEIGHT - slot.boundingRect[3] = LiteGraph.NODE_SLOT_HEIGHT + : LiteGraphSingleton.NODE_SLOT_HEIGHT + slot.boundingRect[3] = LiteGraphSingleton.NODE_SLOT_HEIGHT } #measureSlots(): ReadOnlyRect | null { @@ -3973,7 +3973,7 @@ export class LGraphNode w }) } else { - const height = LiteGraph.NODE_WIDGET_HEIGHT + 4 + const height = LiteGraphSingleton.NODE_WIDGET_HEIGHT + 4 w.computedHeight = height fixedWidgetHeight += height } @@ -4036,13 +4036,13 @@ export class LGraphNode // Only set custom pos if not using Vue positioning // Vue positioning calculates widget slot positions dynamically - if (!LiteGraph.vueNodesMode) { + if (!LiteGraphSingleton.vueNodesMode) { for (const widget of this.widgets) { const slot = slotByWidgetName.get(widget.name) if (!slot) continue const actualSlot = this.#concreteInputs[slot.index] - const offset = LiteGraph.NODE_SLOT_HEIGHT * 0.5 + const offset = LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 actualSlot.pos = [offset, widget.y + offset] this.#measureSlot(actualSlot, slot.index, true) } diff --git a/src/lib/litegraph/src/LiteGraphSingleton.ts b/src/lib/litegraph/src/LiteGraphSingleton.ts new file mode 100644 index 000000000..0c356be51 --- /dev/null +++ b/src/lib/litegraph/src/LiteGraphSingleton.ts @@ -0,0 +1,4 @@ +import { LiteGraphGlobal } from './LiteGraphGlobal'; + + +export const LiteGraphSingleton = new LiteGraphGlobal(); diff --git a/src/lib/litegraph/src/draw.ts b/src/lib/litegraph/src/draw.ts index 2b8987ef8..d329b65e9 100644 --- a/src/lib/litegraph/src/draw.ts +++ b/src/lib/litegraph/src/draw.ts @@ -1,6 +1,6 @@ import type { Rectangle } from './infrastructure/Rectangle' import type { CanvasColour, Rect } from './interfaces' -import { LiteGraph } from './litegraph' +import { LiteGraphSingleton } from './LiteGraphSingleton' import { RenderShape, TitleMode } from './types/globalEnums' const ELLIPSIS = '\u2026' @@ -80,12 +80,12 @@ export function strokeShape( }: IDrawBoundingOptions = {} ): void { // These param defaults are not compile-time static, and must be re-evaluated at runtime - round_radius ??= LiteGraph.ROUND_RADIUS - color ??= LiteGraph.NODE_BOX_OUTLINE_COLOR + round_radius ??= LiteGraphSingleton.ROUND_RADIUS + color ??= LiteGraphSingleton.NODE_BOX_OUTLINE_COLOR // Adjust area if title is transparent if (title_mode === TitleMode.TRANSPARENT_TITLE) { - const height = title_height ?? LiteGraph.NODE_TITLE_HEIGHT + const height = title_height ?? LiteGraphSingleton.NODE_TITLE_HEIGHT area[1] -= height area[3] += height } diff --git a/src/lib/litegraph/src/litegraph.ts b/src/lib/litegraph/src/litegraph.ts index 46202a219..1f4325c64 100644 --- a/src/lib/litegraph/src/litegraph.ts +++ b/src/lib/litegraph/src/litegraph.ts @@ -1,6 +1,6 @@ import type { ContextMenu } from './ContextMenu' import type { LGraphNode } from './LGraphNode' -import { LiteGraphGlobal } from './LiteGraphGlobal' +import { LiteGraphSingleton } from './LiteGraphSingleton' import type { ConnectingLink, Point } from './interfaces' import type { IContextMenuOptions, Size } from './interfaces' import { loadPolyfills } from './polyfills' @@ -10,7 +10,7 @@ import type { RenderShape, TitleMode } from './types/globalEnums' // Must remain above LiteGraphGlobal (circular dependency due to abstract factory behaviour in `configure`) export { Subgraph } from './subgraph/Subgraph' -export const LiteGraph = new LiteGraphGlobal() +export const LiteGraph = LiteGraphSingleton // Load legacy polyfills loadPolyfills() diff --git a/src/lib/litegraph/src/node/NodeInputSlot.ts b/src/lib/litegraph/src/node/NodeInputSlot.ts index 8a6af55e9..364437a0a 100644 --- a/src/lib/litegraph/src/node/NodeInputSlot.ts +++ b/src/lib/litegraph/src/node/NodeInputSlot.ts @@ -7,7 +7,7 @@ import type { OptionalProps, ReadOnlyPoint } from '@/lib/litegraph/src/interfaces' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { type IDrawOptions, NodeSlot } from '@/lib/litegraph/src/node/NodeSlot' import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput' import type { SubgraphOutput } from '@/lib/litegraph/src/subgraph/SubgraphOutput' @@ -33,7 +33,7 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { } get collapsedPos(): ReadOnlyPoint { - return [0, LiteGraph.NODE_TITLE_HEIGHT * -0.5] + return [0, LiteGraphSingleton.NODE_TITLE_HEIGHT * -0.5] } constructor( @@ -52,11 +52,11 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput ): boolean { if ('links' in fromSlot) { - return LiteGraph.isValidConnection(fromSlot.type, this.type) + return LiteGraphSingleton.isValidConnection(fromSlot.type, this.type) } if (isSubgraphInput(fromSlot)) { - return LiteGraph.isValidConnection(fromSlot.type, this.type) + return LiteGraphSingleton.isValidConnection(fromSlot.type, this.type) } return false diff --git a/src/lib/litegraph/src/node/NodeOutputSlot.ts b/src/lib/litegraph/src/node/NodeOutputSlot.ts index a1120dd8e..49e2eb88e 100644 --- a/src/lib/litegraph/src/node/NodeOutputSlot.ts +++ b/src/lib/litegraph/src/node/NodeOutputSlot.ts @@ -7,7 +7,7 @@ import type { OptionalProps, ReadOnlyPoint } from '@/lib/litegraph/src/interfaces' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { type IDrawOptions, NodeSlot } from '@/lib/litegraph/src/node/NodeSlot' import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput' import type { SubgraphOutput } from '@/lib/litegraph/src/subgraph/SubgraphOutput' @@ -26,8 +26,8 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot { get collapsedPos(): ReadOnlyPoint { return [ - this.#node._collapsed_width ?? LiteGraph.NODE_COLLAPSED_WIDTH, - LiteGraph.NODE_TITLE_HEIGHT * -0.5 + this.#node._collapsed_width ?? LiteGraphSingleton.NODE_COLLAPSED_WIDTH, + LiteGraphSingleton.NODE_TITLE_HEIGHT * -0.5 ] } @@ -46,11 +46,11 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot { fromSlot: INodeInputSlot | INodeOutputSlot | SubgraphInput | SubgraphOutput ): boolean { if ('link' in fromSlot) { - return LiteGraph.isValidConnection(this.type, fromSlot.type) + return LiteGraphSingleton.isValidConnection(this.type, fromSlot.type) } if (isSubgraphOutput(fromSlot)) { - return LiteGraph.isValidConnection(this.type, fromSlot.type) + return LiteGraphSingleton.isValidConnection(this.type, fromSlot.type) } return false diff --git a/src/lib/litegraph/src/node/NodeSlot.ts b/src/lib/litegraph/src/node/NodeSlot.ts index 48f0a443c..e8771b5a9 100644 --- a/src/lib/litegraph/src/node/NodeSlot.ts +++ b/src/lib/litegraph/src/node/NodeSlot.ts @@ -11,7 +11,8 @@ import type { Point, ReadOnlyPoint } from '@/lib/litegraph/src/interfaces' -import { LiteGraph, Rectangle } from '@/lib/litegraph/src/litegraph' +import { Rectangle } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { getCentre } from '@/lib/litegraph/src/measure' import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput' import type { SubgraphOutput } from '@/lib/litegraph/src/subgraph/SubgraphOutput' @@ -61,9 +62,9 @@ export abstract class NodeSlot extends SlotBase implements INodeSlot { get highlightColor(): CanvasColour { return ( - LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR ?? - LiteGraph.NODE_SELECTED_TITLE_COLOR ?? - LiteGraph.NODE_TEXT_COLOR + LiteGraphSingleton.NODE_TEXT_HIGHLIGHT_COLOR ?? + LiteGraphSingleton.NODE_SELECTED_TITLE_COLOR ?? + LiteGraphSingleton.NODE_TEXT_COLOR ) } @@ -123,7 +124,7 @@ export abstract class NodeSlot extends SlotBase implements INodeSlot { const labelColor = highlight ? this.highlightColor - : LiteGraph.NODE_TEXT_COLOR + : LiteGraphSingleton.NODE_TEXT_COLOR const pos = this.#centreOffset const slot_type = this.type diff --git a/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts index ed41f3a83..cd20f524c 100644 --- a/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts +++ b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.ts @@ -9,7 +9,8 @@ import type { CallbackReturn, ISlotType } from '@/lib/litegraph/src/interfaces' -import { LGraphEventMode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraphEventMode } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { Subgraph } from './Subgraph' import type { SubgraphNode } from './SubgraphNode' @@ -346,8 +347,8 @@ export class ExecutableNodeDTO implements ExecutableLGraphNode { // Prefer input with the same slot ID if ( oppositeInput && - LiteGraph.isValidConnection(oppositeInput.type, outputType) && - LiteGraph.isValidConnection(oppositeInput.type, type) + LiteGraphSingleton.isValidConnection(oppositeInput.type, outputType) && + LiteGraphSingleton.isValidConnection(oppositeInput.type, type) ) { return slot } @@ -359,8 +360,8 @@ export class ExecutableNodeDTO implements ExecutableLGraphNode { // Find first matching slot - prefer exact type return inputs.findIndex( (input) => - LiteGraph.isValidConnection(input.type, outputType) && - LiteGraph.isValidConnection(input.type, type) + LiteGraphSingleton.isValidConnection(input.type, outputType) && + LiteGraphSingleton.isValidConnection(input.type, type) ) } diff --git a/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.ts b/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.ts index 6ac81ac57..a60cc07f6 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphIONodeBase.ts @@ -13,9 +13,8 @@ import { type CanvasColour, type CanvasPointer, type CanvasPointerEvent, - type IContextMenuValue, - LiteGraph -} from '@/lib/litegraph/src/litegraph' + type IContextMenuValue} from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { snapPoint } from '@/lib/litegraph/src/measure' import { CanvasItem } from '@/lib/litegraph/src/types/globalEnums' import type { @@ -194,7 +193,7 @@ export abstract class SubgraphIONodeBase< const options: (IContextMenuValue | null)[] = this.#getSlotMenuOptions(slot) if (!(options.length > 0)) return - new LiteGraph.ContextMenu(options, { + new LiteGraphSingleton.ContextMenu(options, { event: event as any, title: slot.name || 'Subgraph Output', callback: (item: IContextMenuValue) => { diff --git a/src/lib/litegraph/src/subgraph/SubgraphInput.ts b/src/lib/litegraph/src/subgraph/SubgraphInput.ts index 63465d2b5..575a55fad 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphInput.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphInput.ts @@ -9,7 +9,7 @@ import type { Point, ReadOnlyRect } from '@/lib/litegraph/src/interfaces' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums' import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets' @@ -237,12 +237,12 @@ export class SubgraphInput extends SubgraphSlot { if (isNodeSlot(fromSlot)) { return ( 'link' in fromSlot && - LiteGraph.isValidConnection(this.type, fromSlot.type) + LiteGraphSingleton.isValidConnection(this.type, fromSlot.type) ) } if (isSubgraphOutput(fromSlot)) { - return LiteGraph.isValidConnection(this.type, fromSlot.type) + return LiteGraphSingleton.isValidConnection(this.type, fromSlot.type) } return false diff --git a/src/lib/litegraph/src/subgraph/SubgraphOutput.ts b/src/lib/litegraph/src/subgraph/SubgraphOutput.ts index 96901d423..c7f0a157b 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphOutput.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphOutput.ts @@ -9,7 +9,7 @@ import type { Point, ReadOnlyRect } from '@/lib/litegraph/src/interfaces' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums' import type { SubgraphInput } from './SubgraphInput' @@ -39,7 +39,7 @@ export class SubgraphOutput extends SubgraphSlot { const { subgraph } = this.parent // Validate type compatibility - if (!LiteGraph.isValidConnection(slot.type, this.type)) return + if (!LiteGraphSingleton.isValidConnection(slot.type, this.type)) return // Allow nodes to block connection const outputIndex = node.outputs.indexOf(slot) @@ -143,12 +143,12 @@ export class SubgraphOutput extends SubgraphSlot { if (isNodeSlot(fromSlot)) { return ( 'links' in fromSlot && - LiteGraph.isValidConnection(fromSlot.type, this.type) + LiteGraphSingleton.isValidConnection(fromSlot.type, this.type) ) } if (isSubgraphInput(fromSlot)) { - return LiteGraph.isValidConnection(fromSlot.type, this.type) + return LiteGraphSingleton.isValidConnection(fromSlot.type, this.type) } return false diff --git a/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts index 1634a769f..284dfa7c4 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotBase.ts @@ -14,7 +14,7 @@ import type { ReadOnlyRect, ReadOnlySize } from '@/lib/litegraph/src/interfaces' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { SlotBase } from '@/lib/litegraph/src/node/SlotBase' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import type { @@ -42,7 +42,7 @@ export abstract class SubgraphSlot implements SubgraphIO, Hoverable, Serialisable { static get defaultHeight() { - return LiteGraph.NODE_SLOT_HEIGHT + return LiteGraphSingleton.NODE_SLOT_HEIGHT } readonly #pos: Point = new Float32Array(2) @@ -228,7 +228,7 @@ export abstract class SubgraphSlot 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.fillStyle = highlight ? 'white' : LiteGraphSingleton.NODE_TEXT_COLOR || '#AAA' ctx.fillText(this.displayName, labelX, labelY) } diff --git a/src/lib/litegraph/src/subgraph/subgraphUtils.ts b/src/lib/litegraph/src/subgraph/subgraphUtils.ts index c225dd7b8..406fe88dc 100644 --- a/src/lib/litegraph/src/subgraph/subgraphUtils.ts +++ b/src/lib/litegraph/src/subgraph/subgraphUtils.ts @@ -12,7 +12,8 @@ import type { INodeOutputSlot, Positionable } from '@/lib/litegraph/src/interfaces' -import { LiteGraph, createUuidv4 } from '@/lib/litegraph/src/litegraph' +import { createUuidv4 } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import { nextUniqueName } from '@/lib/litegraph/src/strings' import type { ISerialisedNode, @@ -217,14 +218,14 @@ export function multiClone(nodes: Iterable): ISerialisedNode[] { // Selectively clone - keep IDs & links for (const node of nodes) { - const newNode = LiteGraph.createNode(node.type) + const newNode = LiteGraphSingleton.createNode(node.type) if (!newNode) { console.warn('Failed to create node', node.type) continue } // Must be cloned; litegraph "serialize" is mostly shallow clone - const data = LiteGraph.cloneObject(node.serialize()) + const data = LiteGraphSingleton.cloneObject(node.serialize()) newNode.configure(data) clonedNodes.push(newNode.serialize()) diff --git a/src/lib/litegraph/src/types/serialisation.ts b/src/lib/litegraph/src/types/serialisation.ts index 8ab446594..40f5d7f62 100644 --- a/src/lib/litegraph/src/types/serialisation.ts +++ b/src/lib/litegraph/src/types/serialisation.ts @@ -15,7 +15,7 @@ import type { Point, Size } from '../interfaces' -import type { LiteGraph } from '../litegraph' +import type { LiteGraphSingleton } from '../LiteGraphSingleton' import type { TWidgetValue } from '../types/widgets' import type { RenderShape } from './globalEnums' @@ -124,7 +124,7 @@ export interface ISerialisedGraph extends BaseExportedGraph { links: SerialisedLLinkArray[] floatingLinks?: SerialisableLLink[] groups: ISerialisedGroup[] - version: typeof LiteGraph.VERSION + version: typeof LiteGraphSingleton.VERSION extra?: LGraphExtra } diff --git a/src/lib/litegraph/src/utils/feedback.ts b/src/lib/litegraph/src/utils/feedback.ts index 8fbe54e20..6ccbeb66c 100644 --- a/src/lib/litegraph/src/utils/feedback.ts +++ b/src/lib/litegraph/src/utils/feedback.ts @@ -1,4 +1,4 @@ -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' /** Guard against unbound allocation. */ const UNIQUE_MESSAGE_LIMIT = 10_000 @@ -11,7 +11,7 @@ const sentWarnings: Set = new Set() * @param source A reference object to include alongside the message, e.g. `this`. */ export function warnDeprecated(message: string, source?: object): void { - if (!LiteGraph.alwaysRepeatWarnings) { + if (!LiteGraphSingleton.alwaysRepeatWarnings) { // Do not repeat if (sentWarnings.has(message)) return @@ -21,7 +21,7 @@ export function warnDeprecated(message: string, source?: object): void { sentWarnings.add(message) } - for (const callback of LiteGraph.onDeprecationWarning) { + for (const callback of LiteGraphSingleton.onDeprecationWarning) { callback(message, source) } } diff --git a/src/lib/litegraph/src/widgets/BaseWidget.ts b/src/lib/litegraph/src/widgets/BaseWidget.ts index c09668d9e..644fc1ad8 100644 --- a/src/lib/litegraph/src/widgets/BaseWidget.ts +++ b/src/lib/litegraph/src/widgets/BaseWidget.ts @@ -7,7 +7,7 @@ import type { LGraphNode, Size } from '@/lib/litegraph/src/litegraph' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets' @@ -147,28 +147,28 @@ export abstract class BaseWidget get outline_color() { return this.advanced - ? LiteGraph.WIDGET_ADVANCED_OUTLINE_COLOR - : LiteGraph.WIDGET_OUTLINE_COLOR + ? LiteGraphSingleton.WIDGET_ADVANCED_OUTLINE_COLOR + : LiteGraphSingleton.WIDGET_OUTLINE_COLOR } get background_color() { - return LiteGraph.WIDGET_BGCOLOR + return LiteGraphSingleton.WIDGET_BGCOLOR } get height() { - return LiteGraph.NODE_WIDGET_HEIGHT + return LiteGraphSingleton.NODE_WIDGET_HEIGHT } get text_color() { - return LiteGraph.WIDGET_TEXT_COLOR + return LiteGraphSingleton.WIDGET_TEXT_COLOR } get secondary_text_color() { - return LiteGraph.WIDGET_SECONDARY_TEXT_COLOR + return LiteGraphSingleton.WIDGET_SECONDARY_TEXT_COLOR } get disabledTextColor() { - return LiteGraph.WIDGET_DISABLED_TEXT_COLOR + return LiteGraphSingleton.WIDGET_DISABLED_TEXT_COLOR } get displayName() { @@ -255,7 +255,7 @@ export abstract class BaseWidget if (requiredWidth <= totalWidth) { // Draw label & value normally drawTextInArea({ ctx, text: displayName, area, align: 'left' }) - } else if (LiteGraph.truncateWidgetTextEvenly) { + } else if (LiteGraphSingleton.truncateWidgetTextEvenly) { // Label + value will not fit - scale evenly to fit const scale = (totalWidth - gap) / (requiredWidth - gap) area.width = labelWidth * scale @@ -265,7 +265,7 @@ export abstract class BaseWidget // Move the area to the right to render the value area.right = x + totalWidth area.setWidthRightAnchored(valueWidth * scale) - } else if (LiteGraph.truncateWidgetValuesFirst) { + } else if (LiteGraphSingleton.truncateWidgetValuesFirst) { // Label + value will not fit - use legacy scaling of value first const cappedLabelWidth = Math.min(labelWidth, totalWidth) diff --git a/src/lib/litegraph/src/widgets/ComboWidget.ts b/src/lib/litegraph/src/widgets/ComboWidget.ts index 6eab342d3..d572455d5 100644 --- a/src/lib/litegraph/src/widgets/ComboWidget.ts +++ b/src/lib/litegraph/src/widgets/ComboWidget.ts @@ -1,7 +1,7 @@ import { clamp } from 'es-toolkit/compat' import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import type { IComboWidget, IStringComboWidget @@ -133,7 +133,7 @@ export class ComboWidget // Handle center click - show dropdown menu const text_values = values != values_list ? Object.values(values) : values - new LiteGraph.ContextMenu(text_values, { + new LiteGraphSingleton.ContextMenu(text_values, { scale: Math.max(1, canvas.ds.scale), event: e, className: 'dark', diff --git a/src/lib/litegraph/src/widgets/LegacyWidget.ts b/src/lib/litegraph/src/widgets/LegacyWidget.ts index 273f610b6..a6605412d 100644 --- a/src/lib/litegraph/src/widgets/LegacyWidget.ts +++ b/src/lib/litegraph/src/widgets/LegacyWidget.ts @@ -1,5 +1,5 @@ import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../LiteGraphSingleton' import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets' import { BaseWidget, type DrawWidgetOptions } from './BaseWidget' @@ -27,7 +27,7 @@ export class LegacyWidget ctx: CanvasRenderingContext2D, options: DrawWidgetOptions ) { - const H = LiteGraph.NODE_WIDGET_HEIGHT + const H = LiteGraphSingleton.NODE_WIDGET_HEIGHT this.draw?.(ctx, this.node, options.width, this.y, H, !!options.showText) } diff --git a/src/lib/litegraph/test/LGraph.test.ts b/src/lib/litegraph/test/LGraph.test.ts index b54fd6224..2fe159928 100644 --- a/src/lib/litegraph/test/LGraph.test.ts +++ b/src/lib/litegraph/test/LGraph.test.ts @@ -1,6 +1,7 @@ import { describe } from 'vitest' -import { LGraph, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' import { test } from './testExtensions' @@ -17,8 +18,8 @@ describe('LGraph', () => { const directImport = await import('@/lib/litegraph/src/LGraph') const entryPointImport = await import('@/lib/litegraph/src/litegraph') - expect(LiteGraph.LGraph).toBe(directImport.LGraph) - expect(LiteGraph.LGraph).toBe(entryPointImport.LGraph) + expect(LiteGraphSingleton.LGraph).toBe(directImport.LGraph) + expect(LiteGraphSingleton.LGraph).toBe(entryPointImport.LGraph) }) test('populates optional values', ({ expect, minimalSerialisableGraph }) => { @@ -139,6 +140,6 @@ describe('Legacy LGraph Compatibility Layer', () => { }) test('is correctly assigned to LiteGraph', ({ expect }) => { - expect(LiteGraph.LGraph).toBe(LGraph) + expect(LiteGraphSingleton.LGraph).toBe(LGraph) }) }) diff --git a/src/lib/litegraph/test/LGraphCanvas.titleButtons.test.ts b/src/lib/litegraph/test/LGraphCanvas.titleButtons.test.ts index 0c87a270a..aee612776 100644 --- a/src/lib/litegraph/test/LGraphCanvas.titleButtons.test.ts +++ b/src/lib/litegraph/test/LGraphCanvas.titleButtons.test.ts @@ -1,7 +1,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { LGraphCanvas } from '@/lib/litegraph/src/LGraphCanvas' -import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraphNode } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' describe('LGraphCanvas Title Button Rendering', () => { let canvas: LGraphCanvas @@ -115,7 +116,7 @@ describe('LGraphCanvas Title Button Rendering', () => { // Check draw positions (right-aligned from node width) // First button (rightmost): 200 - 5 = 195, then subtract width // Second button: first button position - 5 - button width - const titleHeight = LiteGraph.NODE_TITLE_HEIGHT + const titleHeight = LiteGraphSingleton.NODE_TITLE_HEIGHT const buttonY = -titleHeight + (titleHeight - 20) / 2 // Centered expect(draw1).toHaveBeenCalledWith(ctx, 180, buttonY) // 200 - 20 expect(draw2).toHaveBeenCalledWith(ctx, 153, buttonY) // 180 - 2 - 25 @@ -180,7 +181,7 @@ describe('LGraphCanvas Title Button Rendering', () => { canvas.drawNode(node, ctx) - const titleHeight = LiteGraph.NODE_TITLE_HEIGHT + const titleHeight = LiteGraphSingleton.NODE_TITLE_HEIGHT // Check positions are correctly spaced (right to left) // Starting position: 200 @@ -209,7 +210,7 @@ describe('LGraphCanvas Title Button Rendering', () => { // Buttons should still be rendered in low quality mode const buttonY = - -LiteGraph.NODE_TITLE_HEIGHT + (LiteGraph.NODE_TITLE_HEIGHT - 20) / 2 + -LiteGraphSingleton.NODE_TITLE_HEIGHT + (LiteGraphSingleton.NODE_TITLE_HEIGHT - 20) / 2 expect(drawSpy).toHaveBeenCalledWith(ctx, 180, buttonY) }) @@ -236,7 +237,7 @@ describe('LGraphCanvas Title Button Rendering', () => { canvas.drawNode(node, ctx) - const titleHeight = LiteGraph.NODE_TITLE_HEIGHT + const titleHeight = LiteGraphSingleton.NODE_TITLE_HEIGHT // Small button (rightmost): 200 - 15 = 185 const buttonY = -titleHeight + (titleHeight - 20) / 2 @@ -263,7 +264,7 @@ describe('LGraphCanvas Title Button Rendering', () => { canvas.drawNode(node, ctx) - const titleHeight = LiteGraph.NODE_TITLE_HEIGHT + const titleHeight = LiteGraphSingleton.NODE_TITLE_HEIGHT // Should use new width: 300 - 20 = 280 const buttonY = -titleHeight + (titleHeight - 20) / 2 expect(drawSpy).toHaveBeenCalledWith(ctx, 280, buttonY) diff --git a/src/lib/litegraph/test/LGraphNode.resize.test.ts b/src/lib/litegraph/test/LGraphNode.resize.test.ts index 55da0cbc9..bd56c21d6 100644 --- a/src/lib/litegraph/test/LGraphNode.resize.test.ts +++ b/src/lib/litegraph/test/LGraphNode.resize.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect } from 'vitest' -import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraphNode } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' import { test } from './testExtensions' @@ -9,7 +10,7 @@ describe('LGraphNode resize functionality', () => { beforeEach(() => { // Set up LiteGraph constants needed for measure - LiteGraph.NODE_TITLE_HEIGHT = 20 + LiteGraphSingleton.NODE_TITLE_HEIGHT = 20 node = new LGraphNode('Test Node') node.pos = [100, 100] diff --git a/src/lib/litegraph/test/LGraphNode.test.ts b/src/lib/litegraph/test/LGraphNode.test.ts index ed7d15329..2c1cdd0da 100644 --- a/src/lib/litegraph/test/LGraphNode.test.ts +++ b/src/lib/litegraph/test/LGraphNode.test.ts @@ -1,7 +1,8 @@ import { afterEach, beforeEach, describe, expect, vi } from 'vitest' import type { INodeInputSlot, Point } from '@/lib/litegraph/src/interfaces' -import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraphNode } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' import { LGraph } from '@/lib/litegraph/src/litegraph' import { NodeInputSlot } from '@/lib/litegraph/src/node/NodeInputSlot' import { NodeOutputSlot } from '@/lib/litegraph/src/node/NodeOutputSlot' @@ -28,14 +29,14 @@ function getMockISerialisedNode( describe('LGraphNode', () => { let node: LGraphNode - let origLiteGraph: typeof LiteGraph + let origLiteGraph: typeof LiteGraphSingleton beforeEach(() => { - origLiteGraph = Object.assign({}, LiteGraph) + origLiteGraph = Object.assign({}, LiteGraphSingleton) // @ts-expect-error TODO: Fix after merge - Classes property not in type delete origLiteGraph.Classes - Object.assign(LiteGraph, { + Object.assign(LiteGraphSingleton, { NODE_TITLE_HEIGHT: 20, NODE_SLOT_HEIGHT: 15, NODE_TEXT_SIZE: 14, @@ -52,7 +53,7 @@ describe('LGraphNode', () => { }) afterEach(() => { - Object.assign(LiteGraph, origLiteGraph) + Object.assign(LiteGraphSingleton, origLiteGraph) }) test('should serialize position/size correctly', () => { @@ -460,8 +461,8 @@ describe('LGraphNode', () => { node.addOutput('output2', 'number') // Calculate expected positions - const slotOffset = LiteGraph.NODE_SLOT_HEIGHT * 0.5 - const slotSpacing = LiteGraph.NODE_SLOT_HEIGHT + const slotOffset = LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 + const slotSpacing = LiteGraphSingleton.NODE_SLOT_HEIGHT const nodeWidth = node.size[0] // Test input positions @@ -496,8 +497,8 @@ describe('LGraphNode', () => { node.addInput('default-input1', 'number') node.addInput('default-input2', 'number') - const slotOffset = LiteGraph.NODE_SLOT_HEIGHT * 0.5 - const slotSpacing = LiteGraph.NODE_SLOT_HEIGHT + const slotOffset = LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 + const slotSpacing = LiteGraphSingleton.NODE_SLOT_HEIGHT // Test: default positioned slots should be consecutive, ignoring absolute positioned ones expect(node.getInputPos(1)).toEqual([ @@ -576,7 +577,7 @@ describe('LGraphNode', () => { }) test('should return position based on title height when collapsed', () => { node.flags.collapsed = true - const expectedPos: Point = [100, 200 - LiteGraph.NODE_TITLE_HEIGHT * 0.5] + const expectedPos: Point = [100, 200 - LiteGraphSingleton.NODE_TITLE_HEIGHT * 0.5] expect(node.getInputSlotPos(inputSlot)).toEqual(expectedPos) }) @@ -600,12 +601,12 @@ describe('LGraphNode', () => { const slotIndex = 0 const nodeOffsetY = (node.constructor as any).slot_start_y || 0 const expectedY = - 200 + (slotIndex + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + nodeOffsetY - const expectedX = 100 + LiteGraph.NODE_SLOT_HEIGHT * 0.5 + 200 + (slotIndex + 0.7) * LiteGraphSingleton.NODE_SLOT_HEIGHT + nodeOffsetY + const expectedX = 100 + LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 expect(node.getInputSlotPos(inputSlot)).toEqual([expectedX, expectedY]) const slotIndex2 = 1 const expectedY2 = - 200 + (slotIndex2 + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + nodeOffsetY + 200 + (slotIndex2 + 0.7) * LiteGraphSingleton.NODE_SLOT_HEIGHT + nodeOffsetY expect(node.getInputSlotPos(inputSlot2)).toEqual([expectedX, expectedY2]) }) @@ -616,8 +617,8 @@ describe('LGraphNode', () => { const slotIndex = 0 const nodeOffsetY = 25 const expectedY = - 200 + (slotIndex + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + nodeOffsetY - const expectedX = 100 + LiteGraph.NODE_SLOT_HEIGHT * 0.5 + 200 + (slotIndex + 0.7) * LiteGraphSingleton.NODE_SLOT_HEIGHT + nodeOffsetY + const expectedX = 100 + LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 expect(node.getInputSlotPos(inputSlot)).toEqual([expectedX, expectedY]) delete (node.constructor as any).slot_start_y }) @@ -650,8 +651,8 @@ describe('LGraphNode', () => { const slotIndex = 0 const nodeOffsetY = (node.constructor as any).slot_start_y || 0 const expectedDefaultY = - 200 + (slotIndex + 0.7) * LiteGraph.NODE_SLOT_HEIGHT + nodeOffsetY - const expectedDefaultX = 100 + LiteGraph.NODE_SLOT_HEIGHT * 0.5 + 200 + (slotIndex + 0.7) * LiteGraphSingleton.NODE_SLOT_HEIGHT + nodeOffsetY + const expectedDefaultX = 100 + LiteGraphSingleton.NODE_SLOT_HEIGHT * 0.5 expect(node.getInputPos(0)).toEqual([expectedDefaultX, expectedDefaultY]) spy.mockRestore() }) @@ -660,7 +661,7 @@ describe('LGraphNode', () => { describe('removeInput/removeOutput on copied nodes', () => { beforeEach(() => { // Register a test node type so clone() can work - LiteGraph.registerNodeType('TestNode', LGraphNode) + LiteGraphSingleton.registerNodeType('TestNode', LGraphNode) }) test('should NOT throw error when calling removeInput on a copied node without graph', () => { diff --git a/src/lib/litegraph/test/litegraph.test.ts b/src/lib/litegraph/test/litegraph.test.ts index 1b9fcfd40..b6e37b207 100644 --- a/src/lib/litegraph/test/litegraph.test.ts +++ b/src/lib/litegraph/test/litegraph.test.ts @@ -2,14 +2,15 @@ import { clamp } from 'es-toolkit/compat' import { beforeEach, describe, expect, vi } from 'vitest' import { LiteGraphGlobal } from '@/lib/litegraph/src/LiteGraphGlobal' -import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LGraphCanvas } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' import { test } from './testExtensions' describe('Litegraph module', () => { test('contains a global export', ({ expect }) => { - expect(LiteGraph).toBeInstanceOf(LiteGraphGlobal) - expect(LiteGraph.LGraphCanvas).toBe(LGraphCanvas) + expect(LiteGraphSingleton).toBeInstanceOf(LiteGraphGlobal) + expect(LiteGraphSingleton.LGraphCanvas).toBe(LGraphCanvas) }) test('has the same structure', ({ expect }) => { @@ -36,8 +37,8 @@ describe('Import order dependency', () => { const directImport = await import('@/lib/litegraph/src/LGraph') // Sanity check that imports were cleared. - expect(Object.is(LiteGraph, entryPointImport.LiteGraph)).toBe(false) - expect(Object.is(LiteGraph.LGraph, directImport.LGraph)).toBe(false) + expect(Object.is(LiteGraphSingleton, entryPointImport.LiteGraphSingleton)).toBe(false) + expect(Object.is(LiteGraphSingleton.LGraph, directImport.LGraph)).toBe(false) } await expect(importNormally()).resolves.toBeUndefined() diff --git a/src/lib/litegraph/test/subgraph/SubgraphConversion.test.ts b/src/lib/litegraph/test/subgraph/SubgraphConversion.test.ts index 1fccdc603..be2e46385 100644 --- a/src/lib/litegraph/test/subgraph/SubgraphConversion.test.ts +++ b/src/lib/litegraph/test/subgraph/SubgraphConversion.test.ts @@ -4,9 +4,8 @@ import type { ISlotType } from '@/lib/litegraph/src/litegraph' import { LGraph, LGraphGroup, - LGraphNode, - LiteGraph -} from '@/lib/litegraph/src/litegraph' + LGraphNode} from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../../src/LiteGraphSingleton' import { createTestSubgraph, @@ -20,7 +19,7 @@ function createNode( title?: string ) { const type = JSON.stringify({ inputs, outputs }) - if (!LiteGraph.registered_node_types[type]) { + if (!LiteGraphSingleton.registered_node_types[type]) { class testnode extends LGraphNode { constructor(title: string) { super(title) @@ -31,9 +30,9 @@ function createNode( this.addOutput('output_' + o_count++, output) } } - LiteGraph.registered_node_types[type] = testnode + LiteGraphSingleton.registered_node_types[type] = testnode } - const node = LiteGraph.createNode(type, title) + const node = LiteGraphSingleton.createNode(type, title) if (!node) { throw new Error('Failed to create node') } diff --git a/src/lib/litegraph/test/testExtensions.ts b/src/lib/litegraph/test/testExtensions.ts index bb59e7221..13b4ee71e 100644 --- a/src/lib/litegraph/test/testExtensions.ts +++ b/src/lib/litegraph/test/testExtensions.ts @@ -1,7 +1,7 @@ import { test as baseTest } from 'vitest' import { LGraph } from '@/lib/litegraph/src/LGraph' -import { LiteGraph } from '@/lib/litegraph/src/litegraph' +import { LiteGraphSingleton } from '../src/LiteGraphSingleton' import type { ISerialisedGraph, @@ -74,7 +74,7 @@ export const dirtyTest = test.extend({ // Register node types for (const node of basicSerialisableGraph.nodes) { - LiteGraph.registerNodeType(node.type!, LiteGraph.LGraphNode) + LiteGraphSingleton.registerNodeType(node.type!, LiteGraphSingleton.LGraphNode) } await use(structuredClone(basicSerialisableGraph))