Skip to content

Commit 339e1ac

Browse files
committed
fixup! fix(devtools): cluster-to-cluster relationships in signal graph
1 parent cd82034 commit 339e1ac

2 files changed

Lines changed: 166 additions & 18 deletions

File tree

devtools/projects/ng-devtools/src/lib/shared/signal-graph/devtools-signal-graph.spec.ts

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,4 +583,145 @@ describe('convertToDevtoolsSignalGraph', () => {
583583
},
584584
});
585585
});
586+
587+
it('should handle cluster-to-cluster dependencies with one-to-many relationship (1:N)', () => {
588+
const debugGraph: DebugSignalGraph = {
589+
nodes: [
590+
{
591+
id: 'a',
592+
kind: 'signal',
593+
epoch: 1,
594+
debuggable: false,
595+
preview: dummyPreview,
596+
label: 'Resource#foo.signalFoo',
597+
},
598+
{
599+
id: 'b',
600+
kind: 'computed',
601+
epoch: 1,
602+
debuggable: false,
603+
preview: dummyPreview,
604+
label: 'Resource#bar.computedBar',
605+
},
606+
{
607+
id: 'c',
608+
kind: 'computed',
609+
epoch: 1,
610+
debuggable: false,
611+
preview: dummyPreview,
612+
label: 'Resource#baz.computedBaz',
613+
},
614+
{
615+
id: 'd',
616+
kind: 'template',
617+
epoch: 1,
618+
debuggable: false,
619+
preview: dummyPreview,
620+
},
621+
],
622+
edges: [
623+
{producer: 0, consumer: 1},
624+
{producer: 0, consumer: 2},
625+
{producer: 1, consumer: 3},
626+
{producer: 2, consumer: 3},
627+
],
628+
};
629+
const graph = convertToDevtoolsSignalGraph(debugGraph);
630+
631+
expect(graph).toEqual({
632+
nodes: [
633+
{
634+
id: 'a',
635+
kind: 'signal',
636+
epoch: 1,
637+
debuggable: false,
638+
preview: dummyPreview,
639+
label: 'signalFoo',
640+
nodeType: 'signal',
641+
clusterId: 'cl_foo',
642+
},
643+
{
644+
id: 'b',
645+
kind: 'computed',
646+
epoch: 1,
647+
debuggable: false,
648+
preview: dummyPreview,
649+
label: 'computedBar',
650+
nodeType: 'signal',
651+
clusterId: 'cl_bar',
652+
},
653+
{
654+
id: 'c',
655+
kind: 'computed',
656+
epoch: 1,
657+
debuggable: false,
658+
preview: dummyPreview,
659+
label: 'computedBaz',
660+
nodeType: 'signal',
661+
clusterId: 'cl_baz',
662+
},
663+
{
664+
id: 'd',
665+
kind: 'template',
666+
epoch: 1,
667+
debuggable: false,
668+
preview: dummyPreview,
669+
nodeType: 'signal',
670+
clusterId: undefined,
671+
},
672+
{
673+
id: 'cl_foo',
674+
nodeType: 'cluster',
675+
clusterType: 'resource',
676+
label: 'foo',
677+
previewNode: undefined,
678+
},
679+
{
680+
id: 'cl_bar',
681+
nodeType: 'cluster',
682+
clusterType: 'resource',
683+
label: 'bar',
684+
previewNode: undefined,
685+
},
686+
{
687+
id: 'cl_baz',
688+
nodeType: 'cluster',
689+
clusterType: 'resource',
690+
label: 'baz',
691+
previewNode: undefined,
692+
},
693+
],
694+
edges: [
695+
{producer: 0, consumer: 1},
696+
{producer: 0, consumer: 2},
697+
{producer: 1, consumer: 3},
698+
{producer: 2, consumer: 3},
699+
{producer: 4, consumer: 1}, // foo->computedBar
700+
{producer: 4, consumer: 2}, // foo->computedBaz
701+
{producer: 5, consumer: 3}, // bar->template
702+
{producer: 0, consumer: 5}, // signalFoo->bar
703+
{producer: 6, consumer: 3}, // baz->template
704+
{producer: 0, consumer: 6}, // signalFoo->baz
705+
{producer: 4, consumer: 5}, // foo->bar
706+
{producer: 4, consumer: 6}, // foo->baz
707+
],
708+
clusters: {
709+
'cl_foo': {
710+
id: 'cl_foo',
711+
name: 'foo',
712+
type: 'resource',
713+
},
714+
'cl_bar': {
715+
id: 'cl_bar',
716+
name: 'bar',
717+
type: 'resource',
718+
},
719+
'cl_baz': {
720+
id: 'cl_baz',
721+
name: 'baz',
722+
type: 'resource',
723+
},
724+
},
725+
});
726+
});
586727
});

devtools/projects/ng-devtools/src/lib/shared/signal-graph/devtools-signal-graph.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,33 +103,40 @@ function processClusterToClusterDependencies(
103103
clusters: Cluster[],
104104
clusterIdxMap: Map<string, number>,
105105
) {
106-
// Creates a map of consumer index to cluster ID.
106+
// Creates a map of consumer index to cluster IDs.
107107
// We don't care about the producers since we are
108108
// interested only in cluster-to-cluster relationships,
109109
// so using either the consumers or the producers works.
110-
const consumerToClusterMap = new Map<number, string>();
110+
const consumerToClustersMap = new Map<number, string[]>();
111111
for (const cluster of clusters) {
112112
for (const consumerIdx of cluster.consumers) {
113-
consumerToClusterMap.set(consumerIdx, cluster.id);
113+
const existingClusters = consumerToClustersMap.get(consumerIdx);
114+
const clusters = existingClusters ?? [];
115+
clusters.push(cluster.id);
116+
117+
if (!existingClusters) {
118+
consumerToClustersMap.set(consumerIdx, clusters);
119+
}
114120
}
115121
}
116122

117-
for (let i = 0; i < graph.nodes.length; i++) {
118-
const producerClusterId = consumerToClusterMap.get(i);
119-
const node = graph.nodes[i];
123+
for (const [i, node] of graph.nodes.entries()) {
124+
if (isSignalNode(node) && node.clusterId) {
125+
const producerClusterIds = consumerToClustersMap.get(i);
126+
if (!producerClusterIds?.length) {
127+
continue;
128+
}
120129

121-
// Add an edge for all nodes that are part of a cluster
122-
// which are produced by nodes in other clusters.
123-
if (
124-
producerClusterId &&
125-
isSignalNode(node) &&
126-
node.clusterId &&
127-
node.clusterId !== producerClusterId
128-
) {
129-
graph.edges.push({
130-
producer: clusterIdxMap.get(producerClusterId)!,
131-
consumer: clusterIdxMap.get(node.clusterId)!,
132-
});
130+
// Add an edge for all nodes that are part of a cluster
131+
// which are produced by nodes in other clusters.
132+
for (const producerClusterId of producerClusterIds) {
133+
if (node.clusterId !== producerClusterId) {
134+
graph.edges.push({
135+
producer: clusterIdxMap.get(producerClusterId)!,
136+
consumer: clusterIdxMap.get(node.clusterId)!,
137+
});
138+
}
139+
}
133140
}
134141
}
135142
}

0 commit comments

Comments
 (0)