diff --git a/src/lib/litegraph/src/LGraphNode.ts b/src/lib/litegraph/src/LGraphNode.ts index 22c831f5c5..88af48f02d 100644 --- a/src/lib/litegraph/src/LGraphNode.ts +++ b/src/lib/litegraph/src/LGraphNode.ts @@ -40,7 +40,8 @@ import type { ReadOnlyPoint, ReadOnlyRect, Rect, - Size + Size, + UniqueId } from './interfaces' import { type LGraphNodeConstructor, @@ -90,9 +91,7 @@ import { type WidgetTypeMap, toConcreteWidget } from './widgets/widgetMap' // #region Types -export type NodeId = - | (number & { type?: 'NodeId' }) - | (string & { type?: 'NodeId' }) +export type NodeId = UniqueId export type NodeProperty = string | number | boolean | object diff --git a/src/lib/litegraph/src/LLink.ts b/src/lib/litegraph/src/LLink.ts index ee1b555626..ebcd023510 100644 --- a/src/lib/litegraph/src/LLink.ts +++ b/src/lib/litegraph/src/LLink.ts @@ -15,7 +15,8 @@ import type { ISlotType, LinkNetwork, LinkSegment, - ReadonlyLinkNetwork + ReadonlyLinkNetwork, + UniqueId } from './interfaces' import type { Serialisable, @@ -25,7 +26,7 @@ import type { const layoutMutations = useLayoutMutations() -export type LinkId = number & { type?: 'LinkId' } +export type LinkId = UniqueId export type SerialisedLLinkArray = [ id: LinkId, diff --git a/src/lib/litegraph/src/Reroute.ts b/src/lib/litegraph/src/Reroute.ts index 499f9a55a2..9bf7ffee09 100644 --- a/src/lib/litegraph/src/Reroute.ts +++ b/src/lib/litegraph/src/Reroute.ts @@ -13,14 +13,15 @@ import type { 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 & { type?: 'RerouteId' } +export type RerouteId = UniqueId /** The input or output slot that an incomplete reroute link is connected to. */ export interface FloatingRerouteSlot { diff --git a/src/lib/litegraph/src/interfaces.ts b/src/lib/litegraph/src/interfaces.ts index eca525a7a5..39066c6b9e 100644 --- a/src/lib/litegraph/src/interfaces.ts +++ b/src/lib/litegraph/src/interfaces.ts @@ -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 & { [__brand]?: B } + export type Dictionary = { [key: string]: T } /** Allows all properties to be null. The same as `Partial`, but adds null instead of undefined. */ diff --git a/src/types/nodeIdentification.ts b/src/types/nodeIdentification.ts index c4fc7b9de4..10d7956f12 100644 --- a/src/types/nodeIdentification.ts +++ b/src/types/nodeIdentification.ts @@ -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 & { type?: 'LocatorId' } +export type NodeLocatorId = UniqueId /** * An execution identifier representing a node's position in nested subgraphs. @@ -24,7 +25,8 @@ export type NodeLocatorId = string & { type?: 'LocatorId' } * Format: Colon-separated path of node IDs * Example: "123:456:789" (node 789 in subgraph 456 in subgraph 123) */ -export type NodeExecutionId = string & { type?: 'ExecutionId' } +declare const __executionIdBrand: unique symbol +export type NodeExecutionId = UniqueId /** * Type guard to check if a value is a NodeLocatorId