@@ -773,7 +773,15 @@ export class TraceTree {
773
773
throw new Error ( 'Parent node is missing, this should be unreachable code' ) ;
774
774
}
775
775
776
+ const index = node . parent . children . indexOf ( node ) ;
777
+ node . parent . children [ index ] = autoGroupedNode ;
778
+
779
+ autoGroupedNode . head . parent = autoGroupedNode ;
776
780
autoGroupedNode . groupCount = groupMatchCount + 1 ;
781
+ autoGroupedNode . space = [
782
+ start * autoGroupedNode . multiplier ,
783
+ ( end - start ) * autoGroupedNode . multiplier ,
784
+ ] ;
777
785
778
786
for ( const error of errors ) {
779
787
autoGroupedNode . errors . add ( error ) ;
@@ -783,18 +791,10 @@ export class TraceTree {
783
791
autoGroupedNode . performance_issues . add ( performanceIssue ) ;
784
792
}
785
793
786
- autoGroupedNode . space = [
787
- start * autoGroupedNode . multiplier ,
788
- ( end - start ) * autoGroupedNode . multiplier ,
789
- ] ;
790
-
791
794
for ( const c of tail . children ) {
792
795
c . parent = autoGroupedNode ;
793
796
queue . push ( c ) ;
794
797
}
795
-
796
- const index = node . parent . children . indexOf ( node ) ;
797
- node . parent . children [ index ] = autoGroupedNode ;
798
798
}
799
799
}
800
800
@@ -1144,7 +1144,34 @@ export class TraceTree {
1144
1144
1145
1145
// We are at the last path segment (the node that the user clicked on)
1146
1146
// and we should scroll the view to this node.
1147
- const index = tree . list . findIndex ( node => node === current ) ;
1147
+ let index = current ? tree . list . findIndex ( node => node === current ) : - 1 ;
1148
+
1149
+ // We have found the node, yet it is somehow not in the visible tree.
1150
+ // This means that the path we were given did not match the current tree.
1151
+ // This sometimes happens when we receive external links like span-x, txn-y
1152
+ // however the resulting tree looks like span-x, autogroup, txn-y. In this case,
1153
+ // we should expand the autogroup node and try to find the node again.
1154
+ if ( current && index === - 1 ) {
1155
+ let parent_node = current . parent ;
1156
+ while ( parent_node ) {
1157
+ // Transactions break autogrouping chains, so we can stop here
1158
+ if ( isTransactionNode ( parent_node ) ) {
1159
+ break ;
1160
+ }
1161
+ if ( isAutogroupedNode ( parent_node ) ) {
1162
+ tree . expand ( parent_node , true ) ;
1163
+ index = current ? tree . list . findIndex ( node => node === current ) : - 1 ;
1164
+ // This is very wasteful as it performs O(n^2) search each time we expand a node...
1165
+ // In most cases though, we should be operating on a tree with sub 10k elements and hopefully
1166
+ // a low autogrouped node count.
1167
+ if ( index !== - 1 ) {
1168
+ break ;
1169
+ }
1170
+ }
1171
+ parent_node = parent_node . parent ;
1172
+ }
1173
+ }
1174
+
1148
1175
if ( index === - 1 ) {
1149
1176
throw new Error ( `Couldn't find node in list ${ scrollQueue . join ( ',' ) } ` ) ;
1150
1177
}
@@ -1730,10 +1757,16 @@ export class TraceTreeNode<T extends TraceTree.NodeValue = TraceTree.NodeValue>
1730
1757
while ( queue . length > 0 ) {
1731
1758
const next = queue . pop ( ) ! ;
1732
1759
1733
- if ( predicate ( next ) ) return next ;
1760
+ if ( predicate ( next ) ) {
1761
+ return next ;
1762
+ }
1734
1763
1735
- for ( const child of next . children ) {
1736
- queue . push ( child ) ;
1764
+ if ( isParentAutogroupedNode ( next ) ) {
1765
+ queue . push ( next . head ) ;
1766
+ } else {
1767
+ for ( const child of next . children ) {
1768
+ queue . push ( child ) ;
1769
+ }
1737
1770
}
1738
1771
}
1739
1772
@@ -1859,12 +1892,6 @@ export class NoDataNode extends TraceTreeNode<null> {
1859
1892
1860
1893
// Generates a ID of the tree node based on its type
1861
1894
function nodeToId ( n : TraceTreeNode < TraceTree . NodeValue > ) : TraceTree . NodePath {
1862
- if ( isTransactionNode ( n ) ) {
1863
- return `txn-${ n . value . event_id } ` ;
1864
- }
1865
- if ( isSpanNode ( n ) ) {
1866
- return `span-${ n . value . span_id } ` ;
1867
- }
1868
1895
if ( isAutogroupedNode ( n ) ) {
1869
1896
if ( isParentAutogroupedNode ( n ) ) {
1870
1897
return `ag-${ n . head . value . span_id } ` ;
@@ -1876,6 +1903,12 @@ function nodeToId(n: TraceTreeNode<TraceTree.NodeValue>): TraceTree.NodePath {
1876
1903
}
1877
1904
}
1878
1905
}
1906
+ if ( isTransactionNode ( n ) ) {
1907
+ return `txn-${ n . value . event_id } ` ;
1908
+ }
1909
+ if ( isSpanNode ( n ) ) {
1910
+ return `span-${ n . value . span_id } ` ;
1911
+ }
1879
1912
if ( isTraceNode ( n ) ) {
1880
1913
return `trace-root` ;
1881
1914
}
@@ -2082,7 +2115,6 @@ function findInTreeFromSegment(
2082
2115
if ( type === 'txn' && isTransactionNode ( node ) ) {
2083
2116
return node . value . event_id === id ;
2084
2117
}
2085
-
2086
2118
if ( type === 'span' && isSpanNode ( node ) ) {
2087
2119
return node . value . span_id === id ;
2088
2120
}
0 commit comments