@eventcatalog/core 2.11.6 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/components/MDX/NodeGraph/NodeGraph.tsx +13 -2
- package/src/components/MDX/NodeGraph/Nodes/Command.tsx +3 -6
- package/src/components/MDX/NodeGraph/Nodes/Event.tsx +3 -6
- package/src/components/MDX/NodeGraph/Nodes/ExternalSystem.tsx +3 -3
- package/src/components/MDX/NodeGraph/Nodes/Query.tsx +2 -2
- package/src/components/MDX/NodeGraph/Nodes/Service.tsx +3 -3
- package/src/components/MDX/NodeGraph/Nodes/Step.tsx +3 -6
- package/src/components/MDX/NodeGraph/Nodes/User.tsx +2 -5
- package/src/components/Tables/Table.tsx +0 -4
- package/src/layouts/DiscoverLayout.astro +1 -1
- package/src/layouts/VerticalSideBarLayout.astro +2 -2
- package/src/utils/collections/util.ts +12 -0
- package/src/utils/commands/node-graph.ts +29 -3
- package/src/utils/events/node-graph.ts +26 -0
- package/src/utils/queries/node-graph.ts +29 -3
- package/src/utils/services/node-graph.ts +31 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @eventcatalog/core
|
|
2
2
|
|
|
3
|
+
## 2.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a136d50: feat(core): services can now send and receive the same messages in vis…
|
|
8
|
+
|
|
9
|
+
## 2.11.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 159e2d4: feat(core): added ability to embed discovery table
|
|
14
|
+
|
|
3
15
|
## 2.11.6
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -81,6 +81,7 @@ const NodeGraphBuilder = ({
|
|
|
81
81
|
setEdges((eds) =>
|
|
82
82
|
eds.map((edge) => {
|
|
83
83
|
edge.style = { ...edge.style, opacity: 1 };
|
|
84
|
+
edge.labelStyle = { ...edge.labelStyle, opacity: 1 };
|
|
84
85
|
return { ...edge, animated: false };
|
|
85
86
|
})
|
|
86
87
|
);
|
|
@@ -107,9 +108,19 @@ const NodeGraphBuilder = ({
|
|
|
107
108
|
if (edge.source === node.id || edge.target === node.id) {
|
|
108
109
|
connectedNodeIds.add(edge.source);
|
|
109
110
|
connectedNodeIds.add(edge.target);
|
|
110
|
-
return {
|
|
111
|
+
return {
|
|
112
|
+
...edge,
|
|
113
|
+
style: { ...edge.style, opacity: 1 },
|
|
114
|
+
labelStyle: { ...edge.labelStyle, opacity: 1 },
|
|
115
|
+
animated: true,
|
|
116
|
+
};
|
|
111
117
|
}
|
|
112
|
-
return {
|
|
118
|
+
return {
|
|
119
|
+
...edge,
|
|
120
|
+
style: { ...edge.style, opacity: 0.1 },
|
|
121
|
+
labelStyle: { ...edge.labelStyle, opacity: 0.1 },
|
|
122
|
+
animated: false,
|
|
123
|
+
};
|
|
113
124
|
});
|
|
114
125
|
|
|
115
126
|
const updatedNodes = nodes.map((n) => {
|
|
@@ -18,13 +18,10 @@ function classNames(...classes: any) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export default function CommandNode({ data, sourcePosition, targetPosition }: any) {
|
|
21
|
-
const { mode, message
|
|
21
|
+
const { mode, message } = data as Data;
|
|
22
22
|
|
|
23
23
|
const { name, version, summary, owners = [], producers = [], consumers = [] } = message.data;
|
|
24
24
|
|
|
25
|
-
const renderTarget = showTarget || (targetPosition && producers.length > 0);
|
|
26
|
-
const renderSource = showSource || (sourcePosition && consumers.length > 0);
|
|
27
|
-
|
|
28
25
|
return (
|
|
29
26
|
<div className={classNames('w-full rounded-md border flex justify-start bg-white text-black border-blue-400')}>
|
|
30
27
|
<div
|
|
@@ -41,8 +38,8 @@ export default function CommandNode({ data, sourcePosition, targetPosition }: an
|
|
|
41
38
|
)}
|
|
42
39
|
</div>
|
|
43
40
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
44
|
-
{
|
|
45
|
-
{
|
|
41
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
42
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
46
43
|
<div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
|
|
47
44
|
<span className="text-xs font-bold block pb-0.5">{name}</span>
|
|
48
45
|
<div className="flex justify-between">
|
|
@@ -18,13 +18,10 @@ function classNames(...classes: any) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export default function EventNode({ data, sourcePosition, targetPosition }: any) {
|
|
21
|
-
const { mode, message
|
|
21
|
+
const { mode, message } = data as Data;
|
|
22
22
|
|
|
23
23
|
const { name, version, summary, owners = [], producers = [], consumers = [] } = message.data;
|
|
24
24
|
|
|
25
|
-
const renderTarget = showTarget || (targetPosition && producers.length > 0);
|
|
26
|
-
const renderSource = showSource || (sourcePosition && consumers.length > 0);
|
|
27
|
-
|
|
28
25
|
return (
|
|
29
26
|
<div className={classNames('w-full rounded-md border flex justify-start bg-white text-black border-orange-400')}>
|
|
30
27
|
<div
|
|
@@ -41,8 +38,8 @@ export default function EventNode({ data, sourcePosition, targetPosition }: any)
|
|
|
41
38
|
)}
|
|
42
39
|
</div>
|
|
43
40
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
44
|
-
{
|
|
45
|
-
{
|
|
41
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
42
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
46
43
|
<div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
|
|
47
44
|
<span className="text-xs font-bold block pb-0.5">{name}</span>
|
|
48
45
|
<div className="flex justify-between">
|
|
@@ -18,7 +18,7 @@ function classNames(...classes: any) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export default function ExternalSystemNode({ data, sourcePosition, targetPosition }: any) {
|
|
21
|
-
const { mode, step
|
|
21
|
+
const { mode, step } = data as Data;
|
|
22
22
|
const { externalSystem } = step;
|
|
23
23
|
const { name, summary, url } = externalSystem;
|
|
24
24
|
|
|
@@ -43,8 +43,8 @@ export default function ExternalSystemNode({ data, sourcePosition, targetPositio
|
|
|
43
43
|
)}
|
|
44
44
|
</div>
|
|
45
45
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
46
|
-
{
|
|
47
|
-
{
|
|
46
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
47
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
48
48
|
<div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
|
|
49
49
|
<div className="h-full ">
|
|
50
50
|
<span className="text-sm font-bold pb-0.5 block w-full">{name}</span>
|
|
@@ -22,8 +22,8 @@ export default function QueryNode({ data, sourcePosition, targetPosition }: any)
|
|
|
22
22
|
|
|
23
23
|
const { name, version, summary, owners = [], producers = [], consumers = [] } = message.data;
|
|
24
24
|
|
|
25
|
-
const renderTarget = showTarget || (targetPosition && producers.length > 0);
|
|
26
|
-
const renderSource = showSource || (sourcePosition && consumers.length > 0);
|
|
25
|
+
const renderTarget = true; //showTarget || (targetPosition && producers.length > 0);
|
|
26
|
+
const renderSource = true; // showSource || (sourcePosition && consumers.length > 0);
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
29
|
<div className={classNames('w-full rounded-md border flex justify-start bg-white text-black border-green-400')}>
|
|
@@ -17,7 +17,7 @@ function classNames(...classes: any) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export default function ServiceNode({ data, sourcePosition, targetPosition }: any) {
|
|
20
|
-
const { label, bgColor = 'bg-blue-500', mode, service
|
|
20
|
+
const { label, bgColor = 'bg-blue-500', mode, service } = data as Data;
|
|
21
21
|
|
|
22
22
|
const { version, owners = [], sends = [], receives = [], name } = service.data;
|
|
23
23
|
|
|
@@ -37,8 +37,8 @@ export default function ServiceNode({ data, sourcePosition, targetPosition }: an
|
|
|
37
37
|
)}
|
|
38
38
|
</div>
|
|
39
39
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
40
|
-
{
|
|
41
|
-
{
|
|
40
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
41
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
42
42
|
<div className={classNames(mode === 'full' ? `border-b border-gray-200` : '')}>
|
|
43
43
|
<span className="text-xs font-bold block pt-0.5 pb-0.5">{name}</span>
|
|
44
44
|
<div className="flex justify-between">
|
|
@@ -16,13 +16,10 @@ function classNames(...classes: any) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export default function StepNode({ data, sourcePosition, targetPosition }: any) {
|
|
19
|
-
const { mode, step
|
|
19
|
+
const { mode, step } = data as Data;
|
|
20
20
|
|
|
21
21
|
const { title, summary } = step;
|
|
22
22
|
|
|
23
|
-
const renderTarget = showTarget || true;
|
|
24
|
-
const renderSource = showSource || true;
|
|
25
|
-
|
|
26
23
|
return (
|
|
27
24
|
<div className={classNames('w-full rounded-md border flex justify-start bg-white text-black border-blue-400 min-h-[3em]')}>
|
|
28
25
|
<div
|
|
@@ -38,8 +35,8 @@ export default function StepNode({ data, sourcePosition, targetPosition }: any)
|
|
|
38
35
|
)}
|
|
39
36
|
</div>
|
|
40
37
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
41
|
-
{
|
|
42
|
-
{
|
|
38
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
39
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
43
40
|
|
|
44
41
|
{!summary && (
|
|
45
42
|
<div className="h-full flex items-center">
|
|
@@ -21,9 +21,6 @@ export default function UserNode({ data, sourcePosition, targetPosition }: any)
|
|
|
21
21
|
|
|
22
22
|
const { summary, actor: { name } = {} } = step;
|
|
23
23
|
|
|
24
|
-
const renderTarget = showTarget || true;
|
|
25
|
-
const renderSource = showSource || true;
|
|
26
|
-
|
|
27
24
|
return (
|
|
28
25
|
<div
|
|
29
26
|
className={classNames(
|
|
@@ -45,8 +42,8 @@ export default function UserNode({ data, sourcePosition, targetPosition }: any)
|
|
|
45
42
|
)}
|
|
46
43
|
</div>
|
|
47
44
|
<div className="p-1 min-w-60 max-w-[min-content]">
|
|
48
|
-
{
|
|
49
|
-
{
|
|
45
|
+
{targetPosition && <Handle type="target" position={targetPosition} />}
|
|
46
|
+
{sourcePosition && <Handle type="source" position={sourcePosition} />}
|
|
50
47
|
|
|
51
48
|
{(!summary || mode !== 'full') && (
|
|
52
49
|
<div className="h-full ">
|
|
@@ -40,10 +40,6 @@ export const Table = ({
|
|
|
40
40
|
const [data, _setData] = useState(initialData);
|
|
41
41
|
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
42
42
|
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
console.log(window.location.pathname);
|
|
45
|
-
}, []);
|
|
46
|
-
|
|
47
43
|
useEffect(() => {
|
|
48
44
|
const urlParams = new URLSearchParams(window.location.search);
|
|
49
45
|
const id = urlParams.get('id');
|
|
@@ -102,7 +102,7 @@ const tabs = [
|
|
|
102
102
|
<!-- Table -->
|
|
103
103
|
<div class="pb-20 ml-6">
|
|
104
104
|
<div>
|
|
105
|
-
<div class="sm:flex sm:items-center py-4 pb-4">
|
|
105
|
+
<div class="sm:flex sm:items-center py-4 pb-4" id="discover-title">
|
|
106
106
|
<div class="sm:flex-auto space-y-2">
|
|
107
107
|
<h1 class="text-4xl font-semibold text-gray-900 capitalize">{title}</h1>
|
|
108
108
|
<p class="text-md text-gray-700">{subtitle}</p>
|
|
@@ -232,7 +232,9 @@ const showSideBarOnLoad = currentNavigationItem?.sidebar;
|
|
|
232
232
|
'eventcatalog-header',
|
|
233
233
|
'eventcatalog-header-spacer',
|
|
234
234
|
'visualiser-footer',
|
|
235
|
+
// /discover page elements
|
|
235
236
|
'discover-collection-tabs',
|
|
237
|
+
'discover-title',
|
|
236
238
|
];
|
|
237
239
|
|
|
238
240
|
elementsToHide.forEach((id) => {
|
|
@@ -266,8 +268,6 @@ const showSideBarOnLoad = currentNavigationItem?.sidebar;
|
|
|
266
268
|
|
|
267
269
|
const navItem = navigationItems.find((navItem) => navItem.id === id);
|
|
268
270
|
|
|
269
|
-
console.log(navItem);
|
|
270
|
-
|
|
271
271
|
if (!navItem.sidebar || !currentPath.includes(navItem.id)) {
|
|
272
272
|
window.location.href = navItem.href;
|
|
273
273
|
return;
|
|
@@ -57,3 +57,15 @@ export const getItemsFromCollectionByIdAndSemverOrLatest = <T extends { data: {
|
|
|
57
57
|
// latest version
|
|
58
58
|
return sorted.length > 0 ? [sorted[sorted.length - 1]] : [];
|
|
59
59
|
};
|
|
60
|
+
|
|
61
|
+
export const findMatchingNodes = (
|
|
62
|
+
nodesA: CollectionEntry<'events' | 'commands' | 'queries' | 'services'>[],
|
|
63
|
+
nodesB: CollectionEntry<'events' | 'commands' | 'queries' | 'services'>[]
|
|
64
|
+
) => {
|
|
65
|
+
// Track messages that are both sent and received
|
|
66
|
+
return nodesA.filter((nodeA) => {
|
|
67
|
+
return nodesB.some((nodeB) => {
|
|
68
|
+
return nodeB.data.id === nodeA.data.id && nodeB.data.version === nodeA.data.version;
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findMatchingNodes } from '@utils/collections/util';
|
|
1
2
|
import { getCommands } from '@utils/commands';
|
|
2
3
|
import { calculatedNodes, createDagreGraph, generateIdForNode, generatedIdForEdge } from '@utils/node-graph-utils/utils';
|
|
3
4
|
import { type CollectionEntry } from 'astro:content';
|
|
@@ -33,6 +34,9 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
33
34
|
const producers = (command.data.producers as CollectionEntry<'services'>[]) || [];
|
|
34
35
|
const consumers = (command.data.consumers as CollectionEntry<'services'>[]) || [];
|
|
35
36
|
|
|
37
|
+
// Track nodes that are both sent and received
|
|
38
|
+
const bothSentAndReceived = findMatchingNodes(producers, consumers);
|
|
39
|
+
|
|
36
40
|
if (producers && producers.length > 0) {
|
|
37
41
|
producers.forEach((producer, index) => {
|
|
38
42
|
nodes.push({
|
|
@@ -40,7 +44,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
40
44
|
type: producer?.collection,
|
|
41
45
|
sourcePosition: 'right',
|
|
42
46
|
targetPosition: 'left',
|
|
43
|
-
data: { mode, service: producer
|
|
47
|
+
data: { mode, service: producer },
|
|
44
48
|
position: { x: 250, y: 0 },
|
|
45
49
|
});
|
|
46
50
|
edges.push({
|
|
@@ -67,7 +71,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
67
71
|
id: generateIdForNode(command),
|
|
68
72
|
sourcePosition: 'right',
|
|
69
73
|
targetPosition: 'left',
|
|
70
|
-
data: { mode, message: command
|
|
74
|
+
data: { mode, message: command },
|
|
71
75
|
position: { x: 0, y: 0 },
|
|
72
76
|
type: command.collection,
|
|
73
77
|
});
|
|
@@ -78,7 +82,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
78
82
|
id: generateIdForNode(consumer),
|
|
79
83
|
sourcePosition: 'right',
|
|
80
84
|
targetPosition: 'left',
|
|
81
|
-
data: { title: consumer?.data.id, mode, service: consumer
|
|
85
|
+
data: { title: consumer?.data.id, mode, service: consumer },
|
|
82
86
|
position: { x: 0, y: 0 },
|
|
83
87
|
type: consumer?.collection,
|
|
84
88
|
});
|
|
@@ -100,6 +104,28 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
100
104
|
});
|
|
101
105
|
});
|
|
102
106
|
|
|
107
|
+
// Handle nodes that are both sent and received
|
|
108
|
+
bothSentAndReceived.forEach((message) => {
|
|
109
|
+
if (message) {
|
|
110
|
+
edges.push({
|
|
111
|
+
id: generatedIdForEdge(command, message) + '-both',
|
|
112
|
+
source: generateIdForNode(command),
|
|
113
|
+
target: generateIdForNode(message),
|
|
114
|
+
type: 'smoothstep',
|
|
115
|
+
label: `publishes and subscribes`,
|
|
116
|
+
animated: false,
|
|
117
|
+
markerEnd: {
|
|
118
|
+
type: MarkerType.ArrowClosed,
|
|
119
|
+
width: 40,
|
|
120
|
+
height: 40,
|
|
121
|
+
},
|
|
122
|
+
style: {
|
|
123
|
+
strokeWidth: 1,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
103
129
|
nodes.forEach((node: any) => {
|
|
104
130
|
flow.setNode(node.id, { width: 150, height: 100 });
|
|
105
131
|
});
|
|
@@ -4,6 +4,7 @@ import type { CollectionEntry } from 'astro:content';
|
|
|
4
4
|
import dagre from 'dagre';
|
|
5
5
|
import { calculatedNodes, createDagreGraph, generatedIdForEdge, generateIdForNode } from '../node-graph-utils/utils';
|
|
6
6
|
import { MarkerType } from 'reactflow';
|
|
7
|
+
import { findMatchingNodes } from '@utils/collections/util';
|
|
7
8
|
|
|
8
9
|
type DagreGraph = any;
|
|
9
10
|
|
|
@@ -34,6 +35,9 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
34
35
|
const producers = (event.data.producers as CollectionEntry<'services'>[]) || [];
|
|
35
36
|
const consumers = (event.data.consumers as CollectionEntry<'services'>[]) || [];
|
|
36
37
|
|
|
38
|
+
// Track nodes that are both sent and received
|
|
39
|
+
const bothSentAndReceived = findMatchingNodes(producers, consumers);
|
|
40
|
+
|
|
37
41
|
if (producers && producers.length > 0) {
|
|
38
42
|
producers.forEach((producer) => {
|
|
39
43
|
nodes.push({
|
|
@@ -101,6 +105,28 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
101
105
|
});
|
|
102
106
|
});
|
|
103
107
|
|
|
108
|
+
// Handle messages that are both sent and received
|
|
109
|
+
bothSentAndReceived.forEach((message) => {
|
|
110
|
+
if (message) {
|
|
111
|
+
edges.push({
|
|
112
|
+
id: generatedIdForEdge(event, message) + '-both',
|
|
113
|
+
source: generateIdForNode(event),
|
|
114
|
+
target: generateIdForNode(message),
|
|
115
|
+
type: 'smoothstep',
|
|
116
|
+
label: `publishes and subscribes`,
|
|
117
|
+
animated: false,
|
|
118
|
+
markerEnd: {
|
|
119
|
+
type: MarkerType.ArrowClosed,
|
|
120
|
+
width: 40,
|
|
121
|
+
height: 40,
|
|
122
|
+
},
|
|
123
|
+
style: {
|
|
124
|
+
strokeWidth: 1,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
104
130
|
nodes.forEach((node: any) => {
|
|
105
131
|
flow.setNode(node.id, { width: 150, height: 100 });
|
|
106
132
|
});
|
|
@@ -3,6 +3,7 @@ import type { CollectionEntry } from 'astro:content';
|
|
|
3
3
|
import dagre from 'dagre';
|
|
4
4
|
import { calculatedNodes, createDagreGraph, generatedIdForEdge, generateIdForNode } from '../node-graph-utils/utils';
|
|
5
5
|
import { MarkerType } from 'reactflow';
|
|
6
|
+
import { findMatchingNodes } from '@utils/collections/util';
|
|
6
7
|
|
|
7
8
|
type DagreGraph = any;
|
|
8
9
|
|
|
@@ -33,6 +34,9 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
33
34
|
const producers = (query.data.producers as CollectionEntry<'services'>[]) || [];
|
|
34
35
|
const consumers = (query.data.consumers as CollectionEntry<'services'>[]) || [];
|
|
35
36
|
|
|
37
|
+
// Track nodes that are both sent and received
|
|
38
|
+
const bothSentAndReceived = findMatchingNodes(producers, consumers);
|
|
39
|
+
|
|
36
40
|
if (producers && producers.length > 0) {
|
|
37
41
|
producers.forEach((producer) => {
|
|
38
42
|
nodes.push({
|
|
@@ -40,7 +44,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
40
44
|
type: producer?.collection,
|
|
41
45
|
sourcePosition: 'right',
|
|
42
46
|
targetPosition: 'left',
|
|
43
|
-
data: { mode, service: producer
|
|
47
|
+
data: { mode, service: producer },
|
|
44
48
|
position: { x: 250, y: 0 },
|
|
45
49
|
});
|
|
46
50
|
edges.push({
|
|
@@ -67,7 +71,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
67
71
|
id: generateIdForNode(query),
|
|
68
72
|
sourcePosition: 'right',
|
|
69
73
|
targetPosition: 'left',
|
|
70
|
-
data: { mode, message: query
|
|
74
|
+
data: { mode, message: query },
|
|
71
75
|
position: { x: 0, y: 0 },
|
|
72
76
|
type: query.collection,
|
|
73
77
|
});
|
|
@@ -78,7 +82,7 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
78
82
|
id: generateIdForNode(consumer),
|
|
79
83
|
sourcePosition: 'right',
|
|
80
84
|
targetPosition: 'left',
|
|
81
|
-
data: { title: consumer?.data.id, mode, service: consumer
|
|
85
|
+
data: { title: consumer?.data.id, mode, service: consumer },
|
|
82
86
|
position: { x: 0, y: 0 },
|
|
83
87
|
type: consumer?.collection,
|
|
84
88
|
});
|
|
@@ -100,6 +104,28 @@ export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simpl
|
|
|
100
104
|
});
|
|
101
105
|
});
|
|
102
106
|
|
|
107
|
+
// Handle nodes that are both sent and received
|
|
108
|
+
bothSentAndReceived.forEach((message) => {
|
|
109
|
+
if (message) {
|
|
110
|
+
edges.push({
|
|
111
|
+
id: generatedIdForEdge(query, message) + '-both',
|
|
112
|
+
source: generateIdForNode(query),
|
|
113
|
+
target: generateIdForNode(message),
|
|
114
|
+
type: 'smoothstep',
|
|
115
|
+
label: `publishes and subscribes`,
|
|
116
|
+
animated: false,
|
|
117
|
+
markerEnd: {
|
|
118
|
+
type: MarkerType.ArrowClosed,
|
|
119
|
+
width: 40,
|
|
120
|
+
height: 40,
|
|
121
|
+
},
|
|
122
|
+
style: {
|
|
123
|
+
strokeWidth: 1,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
103
129
|
nodes.forEach((node: any) => {
|
|
104
130
|
flow.setNode(node.id, { width: 150, height: 100 });
|
|
105
131
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getCollection, type CollectionEntry } from 'astro:content';
|
|
2
2
|
import dagre from 'dagre';
|
|
3
3
|
import { createDagreGraph, generateIdForNode, generatedIdForEdge, calculatedNodes } from '@utils/node-graph-utils/utils';
|
|
4
|
-
import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
|
|
4
|
+
import { findMatchingNodes, getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
|
|
5
5
|
import { MarkerType } from 'reactflow';
|
|
6
6
|
|
|
7
7
|
type DagreGraph = any;
|
|
@@ -78,10 +78,12 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
78
78
|
const receives = (receivesHydrated as CollectionEntry<'events' | 'commands' | 'queries'>[]) || [];
|
|
79
79
|
const sends = (sendsHydrated as CollectionEntry<'events' | 'commands' | 'queries'>[]) || [];
|
|
80
80
|
|
|
81
|
-
//
|
|
81
|
+
// Track messages that are both sent and received
|
|
82
|
+
const bothSentAndReceived = findMatchingNodes(receives, sends);
|
|
82
83
|
|
|
84
|
+
// Get all the data from them
|
|
83
85
|
if (receives && receives.length > 0) {
|
|
84
|
-
//All the messages the service receives
|
|
86
|
+
// All the messages the service receives
|
|
85
87
|
receives.forEach((receive, index) => {
|
|
86
88
|
nodes.push({
|
|
87
89
|
id: generateIdForNode(receive),
|
|
@@ -89,7 +91,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
89
91
|
sourcePosition: 'right',
|
|
90
92
|
targetPosition: 'left',
|
|
91
93
|
data: { mode, message: receive, showTarget: renderAllEdges },
|
|
92
|
-
position: { x: 250, y:
|
|
94
|
+
position: { x: 250, y: index * 100 },
|
|
93
95
|
});
|
|
94
96
|
edges.push({
|
|
95
97
|
id: generatedIdForEdge(receive, service),
|
|
@@ -121,13 +123,13 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
121
123
|
});
|
|
122
124
|
|
|
123
125
|
// The messages the service sends
|
|
124
|
-
sends.forEach((send) => {
|
|
126
|
+
sends.forEach((send, index) => {
|
|
125
127
|
nodes.push({
|
|
126
128
|
id: generateIdForNode(send),
|
|
127
129
|
sourcePosition: 'right',
|
|
128
130
|
targetPosition: 'left',
|
|
129
131
|
data: { mode, message: send, showSource: renderAllEdges },
|
|
130
|
-
position: { x:
|
|
132
|
+
position: { x: 500, y: index * 100 },
|
|
131
133
|
type: send?.collection,
|
|
132
134
|
});
|
|
133
135
|
edges.push({
|
|
@@ -148,6 +150,28 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
148
150
|
});
|
|
149
151
|
});
|
|
150
152
|
|
|
153
|
+
// Handle messages that are both sent and received
|
|
154
|
+
bothSentAndReceived.forEach((message) => {
|
|
155
|
+
if (message) {
|
|
156
|
+
edges.push({
|
|
157
|
+
id: generatedIdForEdge(service, message) + '-both',
|
|
158
|
+
source: generateIdForNode(service),
|
|
159
|
+
target: generateIdForNode(message),
|
|
160
|
+
type: 'smoothstep',
|
|
161
|
+
label: `${getSendsMessageByMessageType(message?.collection)} & ${getReceivesMessageByMessageType(message?.collection)}`,
|
|
162
|
+
animated: false,
|
|
163
|
+
markerEnd: {
|
|
164
|
+
type: MarkerType.ArrowClosed,
|
|
165
|
+
width: 40,
|
|
166
|
+
height: 40,
|
|
167
|
+
},
|
|
168
|
+
style: {
|
|
169
|
+
strokeWidth: 1,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
151
175
|
nodes.forEach((node: any) => {
|
|
152
176
|
flow.setNode(node.id, { width: 150, height: 100 });
|
|
153
177
|
});
|
|
@@ -156,7 +180,7 @@ export const getNodesAndEdges = async ({ id, defaultFlow, version, mode = 'simpl
|
|
|
156
180
|
flow.setEdge(edge.source, edge.target);
|
|
157
181
|
});
|
|
158
182
|
|
|
159
|
-
// Render the diagram in memory getting
|
|
183
|
+
// Render the diagram in memory getting the X and Y
|
|
160
184
|
dagre.layout(flow);
|
|
161
185
|
|
|
162
186
|
return {
|