mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-15 01:48:06 +00:00
Compare commits
4 Commits
fix/eslint
...
austin/str
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65900a8069 | ||
|
|
5ea7a56b64 | ||
|
|
109173fad1 | ||
|
|
f1cb8edcaa |
@@ -3,6 +3,8 @@
|
||||
*/
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
|
||||
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
|
||||
export class VueNodeHelpers {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
@@ -39,7 +41,7 @@ export class VueNodeHelpers {
|
||||
/**
|
||||
* Get all Vue node IDs currently in the DOM
|
||||
*/
|
||||
async getNodeIds(): Promise<string[]> {
|
||||
async getNodeIds(): Promise<NodeId[]> {
|
||||
return await this.nodes.evaluateAll((nodes) =>
|
||||
nodes
|
||||
.map((n) => n.getAttribute('data-node-id'))
|
||||
@@ -50,14 +52,14 @@ export class VueNodeHelpers {
|
||||
/**
|
||||
* Select a specific Vue node by ID
|
||||
*/
|
||||
async selectNode(nodeId: string): Promise<void> {
|
||||
async selectNode(nodeId: nodeId): Promise<void> {
|
||||
await this.page.locator(`[data-node-id="${nodeId}"]`).click()
|
||||
}
|
||||
|
||||
/**
|
||||
* Select multiple Vue nodes by IDs using Ctrl+click
|
||||
*/
|
||||
async selectNodes(nodeIds: string[]): Promise<void> {
|
||||
async selectNodes(nodeIds: NodeId[]): Promise<void> {
|
||||
if (nodeIds.length === 0) return
|
||||
|
||||
// Select first node normally
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
|
||||
interface ChatHistoryEntry {
|
||||
@@ -33,7 +35,7 @@ async function renderChatHistory(page: Page, history: ChatHistoryEntry[]) {
|
||||
}
|
||||
|
||||
test.describe('Chat History Widget', () => {
|
||||
let nodeId: string
|
||||
let nodeId: NodeId
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
nodeId = await renderChatHistory(comfyPage.page, [
|
||||
|
||||
@@ -574,7 +574,7 @@ export class LGraph
|
||||
const S: LGraphNode[] = []
|
||||
const M: Dictionary<LGraphNode> = {}
|
||||
// to avoid repeating links
|
||||
const visited_links: Record<NodeId, boolean> = {}
|
||||
const visited_links: Record<LinkId, boolean> = {}
|
||||
const remaining_links: Record<NodeId, number> = {}
|
||||
|
||||
// search for the nodes without inputs (starting nodes)
|
||||
|
||||
@@ -6168,14 +6168,14 @@ export class LGraphCanvas
|
||||
|
||||
case 'Delete': {
|
||||
// segment can be a Reroute object, in which case segment.id is the reroute id
|
||||
const linkId =
|
||||
segment instanceof Reroute
|
||||
? segment.linkIds.values().next().value
|
||||
: segment.id
|
||||
if (linkId !== undefined) {
|
||||
graph.removeLink(linkId)
|
||||
// Clean up layout store
|
||||
layoutStore.deleteLinkLayout(linkId)
|
||||
const linkIds =
|
||||
segment instanceof Reroute ? segment.linkIds : [segment.id]
|
||||
for (const linkId of linkIds) {
|
||||
if (linkId !== undefined) {
|
||||
graph.removeLink(linkId)
|
||||
// Clean up layout store
|
||||
layoutStore.deleteLinkLayout(linkId)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@ import type {
|
||||
ReadOnlyPoint,
|
||||
ReadOnlyRect,
|
||||
Rect,
|
||||
Size
|
||||
Size,
|
||||
UniqueId
|
||||
} from './interfaces'
|
||||
import {
|
||||
type LGraphNodeConstructor,
|
||||
@@ -90,7 +91,7 @@ import { type WidgetTypeMap, toConcreteWidget } from './widgets/widgetMap'
|
||||
|
||||
// #region Types
|
||||
|
||||
export type NodeId = number | string
|
||||
export type NodeId = UniqueId<number | string, 'NodeId'>
|
||||
|
||||
export type NodeProperty = string | number | boolean | object
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@ import type { LGraphNode, NodeId } from './LGraphNode'
|
||||
import type { Reroute, RerouteId } from './Reroute'
|
||||
import type {
|
||||
CanvasColour,
|
||||
ILinkSegment,
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot,
|
||||
ISlotType,
|
||||
LinkNetwork,
|
||||
LinkSegment,
|
||||
ReadonlyLinkNetwork
|
||||
ReadonlyLinkNetwork,
|
||||
UniqueId
|
||||
} from './interfaces'
|
||||
import type {
|
||||
Serialisable,
|
||||
@@ -24,7 +26,7 @@ import type {
|
||||
|
||||
const layoutMutations = useLayoutMutations()
|
||||
|
||||
export type LinkId = number
|
||||
export type LinkId = UniqueId<number, 'LinkId'>
|
||||
|
||||
export type SerialisedLLinkArray = [
|
||||
id: LinkId,
|
||||
@@ -90,7 +92,7 @@ type BasicReadonlyNetwork = Pick<
|
||||
>
|
||||
|
||||
// this is the class in charge of storing link information
|
||||
export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
|
||||
export class LLink implements ILinkSegment, Serialisable<SerialisableLLink> {
|
||||
static _drawDebug = false
|
||||
|
||||
/** Link ID */
|
||||
|
||||
@@ -6,21 +6,22 @@ import type { LGraphNode, NodeId } from './LGraphNode'
|
||||
import { LLink, type LinkId } from './LLink'
|
||||
import type {
|
||||
CanvasColour,
|
||||
ILinkSegment,
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot,
|
||||
LinkNetwork,
|
||||
LinkSegment,
|
||||
Point,
|
||||
Positionable,
|
||||
ReadOnlyRect,
|
||||
ReadonlyLinkNetwork
|
||||
ReadonlyLinkNetwork,
|
||||
UniqueId
|
||||
} from './interfaces'
|
||||
import { distance, isPointInRect } from './measure'
|
||||
import type { Serialisable, SerialisableReroute } from './types/serialisation'
|
||||
|
||||
const layoutMutations = useLayoutMutations()
|
||||
|
||||
export type RerouteId = number
|
||||
export type RerouteId = UniqueId<number, 'RerouteId'>
|
||||
|
||||
/** The input or output slot that an incomplete reroute link is connected to. */
|
||||
export interface FloatingRerouteSlot {
|
||||
@@ -36,7 +37,7 @@ export interface FloatingRerouteSlot {
|
||||
* and a `WeakRef` to a {@link LinkNetwork} to resolve them.
|
||||
*/
|
||||
export class Reroute
|
||||
implements Positionable, LinkSegment, Serialisable<SerialisableReroute>
|
||||
implements Positionable, ILinkSegment, Serialisable<SerialisableReroute>
|
||||
{
|
||||
static radius: number = 10
|
||||
/** Maximum distance from reroutes to their bezier curve control points. */
|
||||
|
||||
@@ -11,6 +11,9 @@ import type { SubgraphOutputNode } from './subgraph/SubgraphOutputNode'
|
||||
import type { LinkDirection, RenderShape } from './types/globalEnums'
|
||||
import type { IBaseWidget } from './types/widgets'
|
||||
|
||||
declare const __brand: unique symbol
|
||||
export type UniqueId<T, B> = T & { [__brand]?: B }
|
||||
|
||||
export type Dictionary<T> = { [key: string]: T }
|
||||
|
||||
/** Allows all properties to be null. The same as `Partial<T>`, but adds null instead of undefined. */
|
||||
@@ -183,8 +186,10 @@ export interface ItemLocator {
|
||||
): SubgraphInputNode | SubgraphOutputNode | undefined
|
||||
}
|
||||
|
||||
export type LinkSegment = Reroute | LLink
|
||||
|
||||
/** Contains a cached 2D canvas path and a centre point, with an optional forward angle. */
|
||||
export interface LinkSegment {
|
||||
export interface ILinkSegment {
|
||||
/** Link / reroute ID */
|
||||
readonly id: LinkId | RerouteId
|
||||
/** The {@link id} of the reroute that this segment starts from (output side), otherwise `undefined`. */
|
||||
|
||||
@@ -182,14 +182,14 @@ interface WorkflowStore {
|
||||
activeSubgraph: Subgraph | undefined
|
||||
/** Updates the {@link subgraphNamePath} and {@link isSubgraphActive} values. */
|
||||
updateActiveGraph: () => void
|
||||
executionIdToCurrentId: (id: string) => any
|
||||
executionIdToCurrentId: (id: NodeExecutionId) => any
|
||||
nodeIdToNodeLocatorId: (nodeId: NodeId, subgraph?: Subgraph) => NodeLocatorId
|
||||
nodeExecutionIdToNodeLocatorId: (
|
||||
nodeExecutionId: NodeExecutionId | string
|
||||
nodeExecutionId: NodeExecutionId
|
||||
) => NodeLocatorId | null
|
||||
nodeLocatorIdToNodeId: (locatorId: NodeLocatorId | string) => NodeId | null
|
||||
nodeLocatorIdToNodeId: (locatorId: NodeLocatorId) => NodeId | null
|
||||
nodeLocatorIdToNodeExecutionId: (
|
||||
locatorId: NodeLocatorId | string,
|
||||
locatorId: NodeLocatorId,
|
||||
targetSubgraph?: Subgraph
|
||||
) => NodeExecutionId | null
|
||||
}
|
||||
@@ -518,14 +518,14 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
isSubgraphActive.value = isSubgraph(subgraph)
|
||||
}
|
||||
|
||||
const subgraphNodeIdToSubgraph = (id: string, graph: LGraph | Subgraph) => {
|
||||
const subgraphNodeIdToSubgraph = (id: NodeId, graph: LGraph | Subgraph) => {
|
||||
const node = graph.getNodeById(id)
|
||||
if (node?.isSubgraphNode()) return node.subgraph
|
||||
}
|
||||
|
||||
const getSubgraphsFromInstanceIds = (
|
||||
currentGraph: LGraph | Subgraph,
|
||||
subgraphNodeIds: string[],
|
||||
subgraphNodeIds: NodeId[],
|
||||
subgraphs: Subgraph[] = []
|
||||
): Subgraph[] => {
|
||||
const currentPart = subgraphNodeIds.shift()
|
||||
@@ -538,7 +538,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
return getSubgraphsFromInstanceIds(subgraph, subgraphNodeIds, subgraphs)
|
||||
}
|
||||
|
||||
const executionIdToCurrentId = (id: string) => {
|
||||
const executionIdToCurrentId = (id: NodeExecutionId) => {
|
||||
const subgraph = activeSubgraph.value
|
||||
|
||||
// Short-circuit: ID belongs to the parent workflow / no active subgraph
|
||||
@@ -588,11 +588,11 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
* @returns The NodeLocatorId or null if conversion fails
|
||||
*/
|
||||
const nodeExecutionIdToNodeLocatorId = (
|
||||
nodeExecutionId: NodeExecutionId | string
|
||||
nodeExecutionId: NodeExecutionId
|
||||
): NodeLocatorId | null => {
|
||||
// Handle simple node IDs (root graph - no colons)
|
||||
if (!nodeExecutionId.includes(':')) {
|
||||
return nodeExecutionId
|
||||
return nodeExecutionId as NodeLocatorId
|
||||
}
|
||||
|
||||
const parts = parseNodeExecutionId(nodeExecutionId)
|
||||
@@ -623,9 +623,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
* @param locatorId The NodeLocatorId
|
||||
* @returns The local node ID or null if invalid
|
||||
*/
|
||||
const nodeLocatorIdToNodeId = (
|
||||
locatorId: NodeLocatorId | string
|
||||
): NodeId | null => {
|
||||
const nodeLocatorIdToNodeId = (locatorId: NodeLocatorId): NodeId | null => {
|
||||
const parsed = parseNodeLocatorId(locatorId)
|
||||
return parsed?.localNodeId ?? null
|
||||
}
|
||||
@@ -637,7 +635,7 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
* @returns The execution ID or null if the node is not accessible from the target context
|
||||
*/
|
||||
const nodeLocatorIdToNodeExecutionId = (
|
||||
locatorId: NodeLocatorId | string,
|
||||
locatorId: NodeLocatorId,
|
||||
targetSubgraph?: Subgraph
|
||||
): NodeExecutionId | null => {
|
||||
const parsed = parseNodeLocatorId(locatorId)
|
||||
|
||||
@@ -151,8 +151,9 @@ export const useLitegraphService = () => {
|
||||
*/
|
||||
#setupStrokeStyles() {
|
||||
this.strokeStyles['running'] = function (this: LGraphNode) {
|
||||
const nodeId = String(this.id)
|
||||
const nodeLocatorId = useWorkflowStore().nodeIdToNodeLocatorId(nodeId)
|
||||
const nodeLocatorId = useWorkflowStore().nodeIdToNodeLocatorId(
|
||||
this.id
|
||||
)
|
||||
const state =
|
||||
useExecutionStore().nodeLocationProgressStates[nodeLocatorId]?.state
|
||||
if (state === 'running') {
|
||||
@@ -376,7 +377,7 @@ export const useLitegraphService = () => {
|
||||
node.title = nodeDef.display_name || nodeDef.name
|
||||
}
|
||||
|
||||
async function registerNodeDef(nodeId: string, nodeDefV1: ComfyNodeDefV1) {
|
||||
async function registerNodeDef(type: string, nodeDefV1: ComfyNodeDefV1) {
|
||||
const node = class ComfyNode extends LGraphNode {
|
||||
static comfyClass: string
|
||||
static override title: string
|
||||
@@ -416,8 +417,9 @@ export const useLitegraphService = () => {
|
||||
*/
|
||||
#setupStrokeStyles() {
|
||||
this.strokeStyles['running'] = function (this: LGraphNode) {
|
||||
const nodeId = String(this.id)
|
||||
const nodeLocatorId = useWorkflowStore().nodeIdToNodeLocatorId(nodeId)
|
||||
const nodeLocatorId = useWorkflowStore().nodeIdToNodeLocatorId(
|
||||
this.id
|
||||
)
|
||||
const state =
|
||||
useExecutionStore().nodeLocationProgressStates[nodeLocatorId]?.state
|
||||
if (state === 'running') {
|
||||
@@ -649,7 +651,7 @@ export const useLitegraphService = () => {
|
||||
|
||||
const nodeDef = new ComfyNodeDefImpl(nodeDefV1)
|
||||
node.nodeData = nodeDef
|
||||
LiteGraph.registerNodeType(nodeId, node)
|
||||
LiteGraph.registerNodeType(type, node)
|
||||
// Note: Do not following assignments before `LiteGraph.registerNodeType`
|
||||
// because `registerNodeType` will overwrite the assignments.
|
||||
node.category = nodeDef.category
|
||||
|
||||
@@ -28,7 +28,7 @@ import type {
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||
import type { NodeLocatorId } from '@/types/nodeIdentification'
|
||||
import type { NodeExecutionId, NodeLocatorId } from '@/types/nodeIdentification'
|
||||
import { createNodeLocatorId } from '@/types/nodeIdentification'
|
||||
|
||||
interface QueuedPrompt {
|
||||
@@ -78,8 +78,10 @@ function getSubgraphsFromInstanceIds(
|
||||
* @param nodeId The node ID from execution context (could be execution ID)
|
||||
* @returns The NodeLocatorId
|
||||
*/
|
||||
function executionIdToNodeLocatorId(nodeId: string | number): NodeLocatorId {
|
||||
const nodeIdStr = String(nodeId)
|
||||
function executionIdToNodeLocatorId(
|
||||
executionId: NodeExecutionId
|
||||
): NodeLocatorId {
|
||||
const nodeIdStr = String(executionId)
|
||||
|
||||
if (!nodeIdStr.includes(':')) {
|
||||
// It's a top-level node ID
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { UniqueId } from '@/lib/litegraph/src/interfaces'
|
||||
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'
|
||||
|
||||
/**
|
||||
@@ -15,7 +16,7 @@ import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSche
|
||||
* Unlike execution IDs which change based on the instance path,
|
||||
* NodeLocatorId remains the same for all instances of a particular node.
|
||||
*/
|
||||
export type NodeLocatorId = string
|
||||
export type NodeLocatorId = UniqueId<string, 'NodeLocatorId'>
|
||||
|
||||
/**
|
||||
* An execution identifier representing a node's position in nested subgraphs.
|
||||
@@ -24,7 +25,8 @@ export type NodeLocatorId = string
|
||||
* Format: Colon-separated path of node IDs
|
||||
* Example: "123:456:789" (node 789 in subgraph 456 in subgraph 123)
|
||||
*/
|
||||
export type NodeExecutionId = string
|
||||
declare const __executionIdBrand: unique symbol
|
||||
export type NodeExecutionId = UniqueId<string, 'NodeExecutionId'>
|
||||
|
||||
/**
|
||||
* Type guard to check if a value is a NodeLocatorId
|
||||
@@ -105,7 +107,7 @@ export function createNodeLocatorId(
|
||||
* @param id The NodeExecutionId to parse
|
||||
* @returns Array of node IDs from root to target, or null if not an execution ID
|
||||
*/
|
||||
export function parseNodeExecutionId(id: string): NodeId[] | null {
|
||||
export function parseNodeExecutionId(id: NodeExecutionId): NodeId[] | null {
|
||||
if (!isNodeExecutionId(id)) return null
|
||||
|
||||
return id
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type {
|
||||
LGraph,
|
||||
LGraphNode,
|
||||
@@ -9,7 +10,7 @@ import { parseNodeLocatorId } from '@/types/nodeIdentification'
|
||||
import { isSubgraphIoNode } from './typeGuardUtil'
|
||||
|
||||
interface NodeWithId {
|
||||
id: string | number
|
||||
id: NodeId
|
||||
subgraphId?: string | null
|
||||
}
|
||||
|
||||
@@ -19,7 +20,7 @@ interface NodeWithId {
|
||||
* @param nodeData - Node data containing id and optional subgraphId
|
||||
* @returns The locator ID string
|
||||
*/
|
||||
export function getLocatorIdFromNodeData(nodeData: NodeWithId): string {
|
||||
export function getLocatorIdFromNodeData(nodeData: NodeWithId): NodeLocatorId {
|
||||
return nodeData.subgraphId
|
||||
? `${nodeData.subgraphId}:${String(nodeData.id)}`
|
||||
: String(nodeData.id)
|
||||
@@ -31,7 +32,9 @@ export function getLocatorIdFromNodeData(nodeData: NodeWithId): string {
|
||||
* @param executionId - The execution ID (e.g., "123:456:789" or "789")
|
||||
* @returns Array of node IDs in the path, or null if invalid
|
||||
*/
|
||||
export function parseExecutionId(executionId: string): string[] | null {
|
||||
export function parseExecutionId(
|
||||
executionId: NodeExecutionId
|
||||
): string[] | null {
|
||||
if (!executionId || typeof executionId !== 'string') return null
|
||||
return executionId.split(':').filter((part) => part.length > 0)
|
||||
}
|
||||
@@ -55,7 +58,9 @@ export function getLocalNodeIdFromExecutionId(
|
||||
* @param executionId - The execution ID (e.g., "123:456:789" or "789")
|
||||
* @returns Array of subgraph node IDs (excluding the final node ID), or empty array
|
||||
*/
|
||||
export function getSubgraphPathFromExecutionId(executionId: string): string[] {
|
||||
export function getSubgraphPathFromExecutionId(
|
||||
executionId: NodeExecutionId
|
||||
): string[] {
|
||||
const parts = parseExecutionId(executionId)
|
||||
return parts ? parts.slice(0, -1) : []
|
||||
}
|
||||
@@ -196,7 +201,7 @@ export function collectAllNodes(
|
||||
*/
|
||||
export function findNodeInHierarchy(
|
||||
graph: LGraph | Subgraph,
|
||||
nodeId: string | number
|
||||
nodeId: NodeId
|
||||
): LGraphNode | null {
|
||||
// Check current graph
|
||||
const node = graph.getNodeById(nodeId)
|
||||
@@ -284,7 +289,7 @@ export function findSubgraphPathById(
|
||||
*/
|
||||
export function getNodeByExecutionId(
|
||||
rootGraph: LGraph,
|
||||
executionId: string
|
||||
executionId: NodeExecutionId
|
||||
): LGraphNode | null {
|
||||
if (!rootGraph) return null
|
||||
|
||||
@@ -316,7 +321,7 @@ export function getNodeByExecutionId(
|
||||
*/
|
||||
export function getNodeByLocatorId(
|
||||
rootGraph: LGraph,
|
||||
locatorId: NodeLocatorId | string
|
||||
locatorId: NodeLocatorId
|
||||
): LGraphNode | null {
|
||||
if (!rootGraph) return null
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { SerialisedLLinkArray } from '@/lib/litegraph/src/LLink'
|
||||
import type { LinkId, SerialisedLLinkArray } from '@/lib/litegraph/src/LLink'
|
||||
import type { LGraph, LGraphNode, LLink } from '@/lib/litegraph/src/litegraph'
|
||||
import type {
|
||||
ISerialisedGraph,
|
||||
@@ -105,7 +105,7 @@ export function fixBadLinks(
|
||||
|
||||
const data: {
|
||||
patchedNodes: Array<ISerialisedNode | LGraphNode>
|
||||
deletedLinks: number[]
|
||||
deletedLinks: LinkId[]
|
||||
} = {
|
||||
patchedNodes: [],
|
||||
deletedLinks: []
|
||||
@@ -419,7 +419,7 @@ export function fixBadLinks(
|
||||
for (let i = data.deletedLinks.length - 1; i >= 0; i--) {
|
||||
logger.log(`Deleting link #${data.deletedLinks[i]}.`)
|
||||
if ((graph as LGraph).getNodeById) {
|
||||
delete graph.links[data.deletedLinks[i]!]
|
||||
delete (graph as LGraph).links[data.deletedLinks[i]!]
|
||||
} else {
|
||||
graph = graph as ISerialisedGraph
|
||||
// Sometimes we got objects for links if passed after ComfyUI's loadGraphData modifies the
|
||||
|
||||
@@ -16,7 +16,6 @@ vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
|
||||
|
||||
// Remove any previous global types
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
interface Window {}
|
||||
}
|
||||
|
||||
@@ -148,7 +147,7 @@ describe('useExecutionStore - NodeLocatorId conversions', () => {
|
||||
})
|
||||
|
||||
it('should handle numeric node IDs', () => {
|
||||
const result = store.executionIdToNodeLocatorId(123)
|
||||
const result = store.executionIdToNodeLocatorId('123')
|
||||
|
||||
// For numeric IDs, it should convert to string and return as-is
|
||||
expect(result).toBe('123')
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type {
|
||||
LGraph,
|
||||
LGraphNode,
|
||||
@@ -61,7 +62,7 @@ function createMockSubgraph(id: string, nodes: LGraphNode[]): Subgraph {
|
||||
id,
|
||||
_nodes: nodes,
|
||||
nodes: nodes,
|
||||
getNodeById: (nodeId: string | number) =>
|
||||
getNodeById: (nodeId: NodeId) =>
|
||||
nodes.find((n) => String(n.id) === String(nodeId)) || null
|
||||
} as unknown as Subgraph
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user