55 * a knob-paint bug once threw only when a card had a coloured knob — invisible
66 * on an idle canvas, fatal on node creation.
77 */
8- import { act , useLayoutEffect } from 'react'
8+ import { act , Profiler , useLayoutEffect } from 'react'
99import {
1010 normalizeWorkflowEdgeSourceHandle ,
1111 normalizeWorkflowEdgeTargetHandle ,
@@ -83,26 +83,26 @@ function mount(element: React.ReactElement) {
8383 return { host, root }
8484}
8585
86- const NO_EDGES : Edge [ ] = [ ]
87-
8886function SubflowMountFixture ( {
8987 id,
9088 kind,
9189 parentId,
92- edges = NO_EDGES ,
90+ edges,
91+ onRender,
9392} : {
9493 id : string
9594 kind : 'loop' | 'parallel'
9695 parentId ?: string
9796 edges ?: Edge [ ]
97+ onRender ?: ( ) => void
9898} ) {
9999 const reactFlowStore = useReactFlowStoreApi ( )
100100
101101 useLayoutEffect ( ( ) => {
102- reactFlowStore . setState ( { edges } )
102+ if ( edges ) reactFlowStore . setState ( { edges } )
103103 } , [ edges , reactFlowStore ] )
104104
105- return (
105+ const view = (
106106 < SubflowNodeView
107107 id = { id }
108108 data = { { kind, name : kind === 'loop' ? 'Loop' : 'Parallel' , parentId, isPreview : true } }
@@ -114,6 +114,14 @@ function SubflowMountFixture({
114114 onSelect = { ( ) => undefined }
115115 />
116116 )
117+
118+ return onRender ? (
119+ < Profiler id = { id } onRender = { onRender } >
120+ { view }
121+ </ Profiler >
122+ ) : (
123+ view
124+ )
117125}
118126
119127function getSubflowSilhouette ( host : HTMLElement , caseName : string ) {
@@ -1077,6 +1085,44 @@ describe('WorkflowBlockBorder mount', () => {
10771085 }
10781086 )
10791087
1088+ it ( 'does not rerender a nested subflow when unrelated edges change' , ( ) => {
1089+ const baselineRender = vi . fn ( )
1090+ const unrelatedEdgeRender = vi . fn ( )
1091+ const unrelatedEdges : Edge [ ] = [
1092+ {
1093+ id : 'unrelated-edge' ,
1094+ source : 'other-source' ,
1095+ sourceHandle : 'source' ,
1096+ target : 'other-target' ,
1097+ targetHandle : 'target' ,
1098+ } ,
1099+ ]
1100+
1101+ mount (
1102+ < div >
1103+ < ReactFlowProvider >
1104+ < SubflowMountFixture
1105+ id = 'baseline-nested-loop'
1106+ kind = 'loop'
1107+ parentId = 'parent-loop'
1108+ onRender = { baselineRender }
1109+ />
1110+ </ ReactFlowProvider >
1111+ < ReactFlowProvider >
1112+ < SubflowMountFixture
1113+ id = 'unrelated-edge-nested-loop'
1114+ kind = 'loop'
1115+ parentId = 'parent-loop'
1116+ edges = { unrelatedEdges }
1117+ onRender = { unrelatedEdgeRender }
1118+ />
1119+ </ ReactFlowProvider >
1120+ </ div >
1121+ )
1122+
1123+ expect ( unrelatedEdgeRender ) . toHaveBeenCalledTimes ( baselineRender . mock . calls . length )
1124+ } )
1125+
10801126 it ( 'retracts a selected loop action swell after hover ends' , ( ) => {
10811127 vi . useFakeTimers ( )
10821128 vi . stubGlobal (
0 commit comments