@@ -219,13 +219,13 @@ function buildGraphNested(
219219 }
220220 const isChainedParallel =
221221 isParallel &&
222- stage . children . length === 1 &&
222+ stage . children . length > 0 &&
223223 stage . children [ 0 ] . children . length > 0 &&
224224 stage . children [ 0 ] . children [ 0 ] . type === "PARALLEL" &&
225225 stage . name === stage . children [ 0 ] . name ;
226226 const isSkipped = stage . state === Result . skipped ;
227227 const firstChildIsSkipped =
228- hasChildren && stage . children [ 0 ] . state === Result . skipped ;
228+ effectiveFirstChildStage ( stage . children ) ? .state === Result . skipped ;
229229
230230 const hasBranchLabel =
231231 isParallel &&
@@ -302,6 +302,13 @@ function buildGraphNested(
302302 }
303303}
304304
305+ function effectiveFirstChildStage ( children : StageInfo [ ] ) : StageInfo | null {
306+ if ( children . length === 0 ) return null ;
307+ if ( children [ 0 ] . type === "PARALLEL" ) return children [ 0 ] ;
308+ if ( children [ 0 ] . children . length === 0 ) return children [ 0 ] ;
309+ return effectiveFirstChildStage ( children [ 0 ] . children ) ;
310+ }
311+
305312function computePositions (
306313 node : GraphNode ,
307314 extraXp : number ,
@@ -348,6 +355,17 @@ function computeConnections(node: GraphNode): CompositeConnection[] {
348355 return connections ;
349356}
350357
358+ function resolveNestedSequentialGraphNode ( node : GraphNode ) : GraphNode {
359+ // This node is a leaf.
360+ if ( node . children . length === 0 ) return node ;
361+ // Parallel nesting: Connect directly to parallel children.
362+ if ( node . hasParallel ) return node ;
363+ // Sequential nesting with first child skipped: Connect to parent (non-skipped) before starting the skipped curve.
364+ if ( node . firstChildIsSkipped ) return node ;
365+ // Sequential nesting: Connect directly to 1st child, recursively resolve it.
366+ return resolveNestedSequentialGraphNode ( node . children [ 0 ] ) ;
367+ }
368+
351369function computeTailNodes (
352370 connections : CompositeConnection [ ] ,
353371 node : GraphNode ,
@@ -363,17 +381,6 @@ function computeTailNodes(
363381 // Collect nodes in a Set. With two skipped nodes next to each other, we need to deduplicate them.
364382 const sourceNodes = new Set < GraphNode > ( ) ;
365383 const skippedNodes = new Set < GraphNode > ( ) ;
366- const resolveDestination = ( node : GraphNode ) : GraphNode [ ] => {
367- if ( node . hasParallel ) {
368- // Connect directly to parallel children
369- return node . children ;
370- }
371- if ( node . children . length > 0 ) {
372- // Connect directly to 1st child, recusively resolve it.
373- return resolveDestination ( node . children [ 0 ] ) ;
374- }
375- return [ node ] ;
376- } ;
377384 const connect = (
378385 tailNodes : GraphNode [ ] ,
379386 destination : GraphNode ,
@@ -386,22 +393,26 @@ function computeTailNodes(
386393 skippedNodes . add ( node ) ;
387394 }
388395 }
389- const destinationNodes = resolveDestination ( destination ) ;
396+ destination = resolveNestedSequentialGraphNode ( destination ) ;
397+ const destinationNodes = destination . hasParallel
398+ ? destination . children
399+ : [ destination ] ;
390400 if ( ! destinationNodes . some ( ( n ) => ! n . isSkipped ) ) {
391401 for ( const node of destinationNodes ) skippedNodes . add ( node ) ;
392402 return ;
393403 }
404+ if ( ! sourceNodes . size ) throw new Error ( "bug: empty sourceNodes" ) ;
394405 connections . push ( {
395406 sourceNodes : Array . from ( sourceNodes ) ,
396407 destinationNodes,
397408 skippedNodes : Array . from ( skippedNodes ) ,
398- hasBranchLabels : destinationNodes . some ( ( n ) => n . hasBranchLabel ) ,
409+ hasBranchLabels : destination . shiftX > 0 , // shift curved connections
399410 } ) ;
400411 sourceNodes . clear ( ) ;
401412 skippedNodes . clear ( ) ;
402413 } ;
403- if ( node . isParallel ) {
404- // Non-parallel stages will have been connected already via resolveDestination .
414+ if ( node . isParallel || node . firstChildIsSkipped ) {
415+ // See comments in resolveNestedSequentialGraphNode .
405416 connect ( [ node ] , node . children [ 0 ] , true ) ;
406417 }
407418 for ( let i = 0 ; i < node . children . length - 1 ; i ++ ) {
0 commit comments