diff --git a/eslint.config.js b/eslint.config.js index 5bb59cc98..7d7ad7eef 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -59,7 +59,6 @@ export default tseslint.config( rules: { // Temporarily disabled // See https://github.com/Comfy-Org/litegraph.js/issues/629 - "unicorn/prefer-export-from": "off", "unicorn/catch-error-name": "off", "unicorn/consistent-existence-index-check": "off", "unicorn/no-array-callback-reference": "off", diff --git a/src/litegraph.ts b/src/litegraph.ts index 4591eac1d..320cbab05 100644 --- a/src/litegraph.ts +++ b/src/litegraph.ts @@ -1,94 +1,18 @@ -import type { LabelPosition, SlotDirection, SlotShape, SlotType } from "./draw" +import type { ContextMenu } from "./ContextMenu" import type { ConnectingLink, Point } from "./interfaces" import type { - CanvasColour, - ColorOption, - Direction, - IBoundaryNodes, - IColorable, IContextMenuOptions, - IContextMenuValue, - IFoundSlot, - IInputOrOutput, - INodeFlags, - INodeInputSlot, - INodeOutputSlot, INodeSlot, - IOptionalSlotData, - ISlotType, - KeysOfType, - MethodNames, - PickByType, - Rect, - Rect32, Size, } from "./interfaces" +import type { LGraphNode } from "./LGraphNode" import type { CanvasEventDetail } from "./types/events" import type { RenderShape, TitleMode } from "./types/globalEnums" -import type { IWidget } from "./types/widgets" -import { ContextMenu } from "./ContextMenu" -import { CurveEditor } from "./CurveEditor" -import { DragAndScale } from "./DragAndScale" -import { LGraph } from "./LGraph" -import { BadgePosition, LGraphBadge } from "./LGraphBadge" -import { LGraphCanvas, type LGraphCanvasState } from "./LGraphCanvas" -import { LGraphGroup } from "./LGraphGroup" -import { LGraphNode } from "./LGraphNode" import { LiteGraphGlobal } from "./LiteGraphGlobal" -import { LLink } from "./LLink" import { loadPolyfills } from "./polyfills" export const LiteGraph = new LiteGraphGlobal() -export { - ContextMenu, - CurveEditor, - DragAndScale, - LGraph, - LGraphCanvas, - LGraphCanvasState, - LGraphGroup, - LGraphNode, - LLink, -} -export { - CanvasColour, - ColorOption, - ConnectingLink, - Direction, - IBoundaryNodes, - IColorable, - IContextMenuOptions, - IContextMenuValue, - IFoundSlot, - IInputOrOutput, - INodeFlags, - INodeInputSlot, - INodeOutputSlot, - INodeSlot, - IOptionalSlotData, - ISlotType, - KeysOfType, - MethodNames, - PickByType, - Rect, - Rect32, - Size, -} -export { isColorable } from "./utils/type" -export { IWidget } -export { BadgePosition, LGraphBadge } -export { LabelPosition, SlotDirection, SlotShape, SlotType } -export { CanvasPointer } from "./CanvasPointer" -export { strokeShape } from "./draw" -export { createBounds } from "./measure" -export { Reroute } from "./Reroute" -export { CanvasItem, EaseFunction, LGraphEventMode, LinkMarkerShape, RenderShape, TitleMode } from "./types/globalEnums" -export type { - ISerialisedGraph, - SerialisableGraph, - SerialisableLLink, -} from "./types/serialisation" export function clamp(v: number, a: number, b: number): number { return a > v ? a : (b < v ? b : v) @@ -162,3 +86,57 @@ export interface LGraphNodeConstructor { } // End backwards compat + +export { CanvasPointer } from "./CanvasPointer" +export { ContextMenu } from "./ContextMenu" +export { CurveEditor } from "./CurveEditor" +export { DragAndScale } from "./DragAndScale" +export { LabelPosition, SlotDirection, SlotShape, SlotType } from "./draw" +export { strokeShape } from "./draw" +export type { + CanvasColour, + ColorOption, + ConnectingLink, + Direction, + IBoundaryNodes, + IColorable, + IContextMenuOptions, + IContextMenuValue, + IFoundSlot, + IInputOrOutput, + INodeFlags, + INodeInputSlot, + INodeOutputSlot, + INodeSlot, + IOptionalSlotData, + ISlotType, + KeysOfType, + MethodNames, + PickByType, + Rect, + Rect32, + Size, +} from "./interfaces" +export { LGraph } from "./LGraph" +export { BadgePosition, LGraphBadge } from "./LGraphBadge" +export { LGraphCanvas, type LGraphCanvasState } from "./LGraphCanvas" +export { LGraphGroup } from "./LGraphGroup" +export { LGraphNode } from "./LGraphNode" +export { LLink } from "./LLink" +export { createBounds } from "./measure" +export { Reroute } from "./Reroute" +export { + CanvasItem, + EaseFunction, + LGraphEventMode, + LinkMarkerShape, + RenderShape, + TitleMode, +} from "./types/globalEnums" +export type { + ISerialisedGraph, + SerialisableGraph, + SerialisableLLink, +} from "./types/serialisation" +export type { IWidget } from "./types/widgets" +export { isColorable } from "./utils/type" diff --git a/test/litegraph.test.ts b/test/litegraph.test.ts index 2f271d288..4513b7919 100644 --- a/test/litegraph.test.ts +++ b/test/litegraph.test.ts @@ -1,11 +1,11 @@ -import { describe, expect } from "vitest" +import { beforeEach, describe, expect, vi } from "vitest" import { clamp, LGraphCanvas, LiteGraph } from "@/litegraph" import { LiteGraphGlobal } from "@/LiteGraphGlobal" import { test } from "./testExtensions" -describe.concurrent("Litegraph module", () => { +describe("Litegraph module", () => { test("contains a global export", ({ expect }) => { expect(LiteGraph).toBeInstanceOf(LiteGraphGlobal) expect(LiteGraph.LGraphCanvas).toBe(LGraphCanvas) @@ -21,3 +21,35 @@ describe.concurrent("Litegraph module", () => { expect(clamp(Infinity, 18, 29)).toStrictEqual(29) }) }) + +describe("Import order dependency", () => { + beforeEach(() => { + vi.resetModules() + }) + + // Test can be safely removed if import order requirements are resolved. + test("Throws when entry point is not imported first", async ({ expect }) => { + async function importSubmoduleFirst() { + const directImport = await import("@/LGraph") + const entryPointImport = await import("@/litegraph") + + // Unreachable. + if (directImport !== entryPointImport) return + } + + await expect(importSubmoduleFirst).rejects.toThrow("Cannot set properties of undefined (setting 'link_type_colors')") + }) + + test("Imports without error when entry point is imported first", async ({ expect }) => { + async function importNormally() { + const entryPointImport = await import("@/litegraph") + const directImport = await import("@/LGraph") + + // Sanity check that imports were cleared. + expect(Object.is(LiteGraph, entryPointImport.LiteGraph)).toBe(false) + expect(Object.is(LiteGraph.LGraph, directImport.LGraph)).toBe(false) + } + + await expect(importNormally()).resolves.toBeUndefined() + }) +})