44 */
55import { nextTick , reactive } from 'vue'
66
7+ import { useChainCallback } from '@/composables/functional/useChainCallback'
78import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
89import { LayoutSource } from '@/renderer/core/layout/types'
910import { type Bounds , QuadTree } from '@/renderer/core/spatial/QuadTree'
@@ -595,6 +596,7 @@ export const useGraphNodeManager = (graph: LGraph): GraphNodeManager => {
595596
596597 /**
597598 * Handles node addition to the graph - sets up Vue state and spatial indexing
599+ * Defers position extraction until after potential configure() calls
598600 */
599601 const handleNodeAdded = (
600602 node : LGraphNode ,
@@ -618,27 +620,48 @@ export const useGraphNodeManager = (graph: LGraph): GraphNodeManager => {
618620 lastUpdate : performance . now ( ) ,
619621 culled : false
620622 } )
621- nodePositions . set ( id , { x : node . pos [ 0 ] , y : node . pos [ 1 ] } )
622- nodeSizes . set ( id , { width : node . size [ 0 ] , height : node . size [ 1 ] } )
623- attachMetadata ( node )
624623
625- // Add to spatial index for viewport culling
626- const bounds : Bounds = {
627- x : node . pos [ 0 ] ,
628- y : node . pos [ 1 ] ,
629- width : node . size [ 0 ] ,
630- height : node . size [ 1 ]
624+ const initializeVueNodeLayout = ( ) => {
625+ // Extract actual positions after configure() has potentially updated them
626+ const nodePosition = { x : node . pos [ 0 ] , y : node . pos [ 1 ] }
627+ const nodeSize = { width : node . size [ 0 ] , height : node . size [ 1 ] }
628+
629+ nodePositions . set ( id , nodePosition )
630+ nodeSizes . set ( id , nodeSize )
631+ attachMetadata ( node )
632+
633+ // Add to spatial index for viewport culling with final positions
634+ const nodeBounds : Bounds = {
635+ x : nodePosition . x ,
636+ y : nodePosition . y ,
637+ width : nodeSize . width ,
638+ height : nodeSize . height
639+ }
640+ spatialIndex . insert ( id , nodeBounds , id )
641+
642+ // Add node to layout store with final positions
643+ setSource ( LayoutSource . Canvas )
644+ void createNode ( id , {
645+ position : nodePosition ,
646+ size : nodeSize ,
647+ zIndex : node . order || 0 ,
648+ visible : true
649+ } )
631650 }
632- spatialIndex . insert ( id , bounds , id )
633651
634- // Add node to layout store
635- setSource ( LayoutSource . Canvas )
636- void createNode ( id , {
637- position : { x : node . pos [ 0 ] , y : node . pos [ 1 ] } ,
638- size : { width : node . size [ 0 ] , height : node . size [ 1 ] } ,
639- zIndex : node . order || 0 ,
640- visible : true
641- } )
652+ // Check if we're in the middle of configuring the graph (workflow loading)
653+ if ( window . app ?. configuringGraph ) {
654+ // During workflow loading - defer layout initialization until configure completes
655+ // Chain our callback with any existing onAfterGraphConfigured callback
656+ node . onAfterGraphConfigured = useChainCallback (
657+ node . onAfterGraphConfigured ,
658+ initializeVueNodeLayout
659+ )
660+ } else {
661+ // Not during workflow loading - initialize layout immediately
662+ // This handles individual node additions during normal operation
663+ initializeVueNodeLayout ( )
664+ }
642665
643666 // Call original callback if provided
644667 if ( originalCallback ) {
0 commit comments