@eventcatalog/core 2.12.3 → 2.13.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/public/icons/protocols/kafka.svg +1 -0
  4. package/scripts/catalog-to-astro-content-directory.js +13 -1
  5. package/scripts/default-files-for-collections/channels.md +8 -0
  6. package/scripts/map-catalog-to-astro.js +1 -0
  7. package/src/components/DocsNavigation.astro +4 -4
  8. package/src/components/Header.astro +1 -1
  9. package/src/components/Lists/PillListFlat.tsx +19 -12
  10. package/src/components/Lists/ProtocolList.tsx +88 -0
  11. package/src/components/MDX/ChannelInformation/ChannelInformation.tsx +79 -0
  12. package/src/components/MDX/Flow/Flow.astro +3 -3
  13. package/src/components/MDX/NodeGraph/DownloadButton.tsx +3 -3
  14. package/src/components/MDX/NodeGraph/Edges/AnimatedMessageEdge.tsx +82 -0
  15. package/src/components/MDX/NodeGraph/NodeGraph.astro +24 -67
  16. package/src/components/MDX/NodeGraph/NodeGraph.tsx +188 -17
  17. package/src/components/MDX/NodeGraph/Nodes/Channel.tsx +133 -0
  18. package/src/components/MDX/components.tsx +2 -0
  19. package/src/components/Seo.astro +0 -2
  20. package/src/components/SideBars/CatalogResourcesSideBar/index.tsx +4 -13
  21. package/src/components/SideBars/ChannelSideBar.astro +117 -0
  22. package/src/components/SideBars/MessageSideBar.astro +13 -0
  23. package/src/content/config.ts +37 -0
  24. package/src/icons/protocols/WebSocket.svg +1 -0
  25. package/src/icons/protocols/amqp.svg +1 -0
  26. package/src/icons/protocols/eventbridge.svg +6 -0
  27. package/src/icons/protocols/googlepubsub.svg +1 -0
  28. package/src/icons/protocols/http.svg +1 -0
  29. package/src/icons/protocols/index.ts +15 -0
  30. package/src/icons/protocols/jms.svg +1 -0
  31. package/src/icons/protocols/kafka.svg +1 -0
  32. package/src/icons/protocols/mercure.svg +20 -0
  33. package/src/icons/protocols/mqtt.svg +17 -0
  34. package/src/icons/protocols/nats.svg +13 -0
  35. package/src/icons/protocols/pulsar.svg +4 -0
  36. package/src/icons/protocols/redis.svg +1 -0
  37. package/src/icons/protocols/sns.svg +6 -0
  38. package/src/icons/protocols/solace.svg +1 -0
  39. package/src/icons/protocols/sqs.svg +7 -0
  40. package/src/icons/protocols/ws.svg +1 -0
  41. package/src/layouts/DiscoverLayout.astro +3 -3
  42. package/src/layouts/VerticalSideBarLayout.astro +10 -5
  43. package/src/layouts/VisualiserLayout.astro +3 -3
  44. package/src/pages/discover/[type]/index.astro +3 -3
  45. package/src/pages/docs/[type]/[id]/[version]/asyncapi/index.astro +2 -2
  46. package/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +2 -2
  47. package/src/pages/docs/[type]/[id]/[version]/index.astro +11 -4
  48. package/src/pages/docs/[type]/[id]/[version]/spec/index.astro +2 -2
  49. package/src/pages/docs/[type]/[id]/index.astro +17 -4
  50. package/src/pages/index.astro +3 -3
  51. package/src/pages/visualiser/[type]/[id]/[version]/index.astro +2 -2
  52. package/src/pages/visualiser/[type]/[id]/index.astro +2 -2
  53. package/src/remark-plugins/mermaid.ts +0 -1
  54. package/src/types/index.ts +2 -2
  55. package/src/utils/channels.ts +64 -0
  56. package/src/utils/collections/icons.ts +6 -0
  57. package/src/utils/commands.ts +6 -0
  58. package/src/utils/{config → eventcatalog-config}/catalog.ts +1 -1
  59. package/src/utils/events.ts +5 -0
  60. package/src/utils/{domains/node-graph.ts → node-graphs/domains-node-graph.ts} +2 -2
  61. package/src/utils/{flows/node-graph.ts → node-graphs/flows-node-graph.ts} +2 -2
  62. package/src/utils/node-graphs/message-node-graph.ts +216 -0
  63. package/src/utils/{services/node-graph.ts → node-graphs/services-node-graph.ts} +79 -54
  64. package/src/utils/node-graphs/utils/utils.ts +128 -0
  65. package/src/utils/{pages/pages.ts → page-loaders/page-data-loader.ts} +4 -2
  66. package/src/utils/queries.ts +5 -0
  67. package/tsconfig.json +2 -1
  68. package/src/remark-plugins/remark-modified-time.mjs +0 -9
  69. package/src/utils/commands/node-graph.ts +0 -144
  70. package/src/utils/events/node-graph.ts +0 -145
  71. package/src/utils/node-graph-utils/utils.ts +0 -29
  72. package/src/utils/queries/node-graph.ts +0 -144
  73. /package/src/pages/docs/[type]/[id]/[version]/spec/{styles.css → _styles.css} +0 -0
  74. /package/src/utils/{changelogs → collections}/changelogs.ts +0 -0
  75. /package/src/utils/{domains → collections}/domains.ts +0 -0
  76. /package/src/utils/{flows → collections}/flows.ts +0 -0
  77. /package/src/utils/{services → collections}/services.ts +0 -0
  78. /package/src/utils/{versions → collections}/versions.ts +0 -0
@@ -0,0 +1,128 @@
1
+ import { getCollection, type CollectionEntry } from 'astro:content';
2
+ import { MarkerType, Position, type Edge, type Node } from 'reactflow';
3
+ import dagre from 'dagre';
4
+ import { getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
5
+ import type { CollectionTypes } from '@types';
6
+
7
+ export const generateIdForNode = (node: CollectionEntry<CollectionTypes>) => {
8
+ return `${node.data.id}-${node.data.version}`;
9
+ };
10
+ export const generateIdForNodes = (nodes: any) => {
11
+ return nodes.map((node: any) => `${node.data.id}-${node.data.version}`).join('-');
12
+ };
13
+ export const generatedIdForEdge = (source: CollectionEntry<CollectionTypes>, target: CollectionEntry<CollectionTypes>) => {
14
+ return `${source.data.id}-${source.data.version}-${target.data.id}-${target.data.version}`;
15
+ };
16
+
17
+ export const calculatedNodes = (flow: dagre.graphlib.Graph, nodes: Node[]) => {
18
+ return nodes.map((node: any) => {
19
+ const { x, y } = flow.node(node.id);
20
+ return { ...node, position: { x, y } };
21
+ });
22
+ };
23
+
24
+ // Creates a new dagre graph
25
+ export const createDagreGraph = ({ ranksep = 180, nodesep = 50, ...rest }: any) => {
26
+ const graph = new dagre.graphlib.Graph({ compound: true });
27
+ graph.setGraph({ rankdir: 'LR', ranksep, nodesep, ...rest });
28
+ graph.setDefaultEdgeLabel(() => ({}));
29
+ return graph;
30
+ };
31
+
32
+ export const createEdge = (edgeOptions: Edge) => {
33
+ return {
34
+ label: 'subscribed by',
35
+ animated: false,
36
+ markerEnd: {
37
+ type: MarkerType.ArrowClosed,
38
+ width: 40,
39
+ height: 40,
40
+ },
41
+ style: {
42
+ strokeWidth: 1,
43
+ },
44
+ ...edgeOptions,
45
+ };
46
+ };
47
+
48
+ export const createNode = (values: Node): Node => {
49
+ return {
50
+ sourcePosition: Position.Right,
51
+ targetPosition: Position.Left,
52
+ ...values,
53
+ };
54
+ };
55
+
56
+ export const getChannelNodesAndEdges = ({
57
+ channels: channelsCollection,
58
+ channelsToRender,
59
+ source,
60
+ target,
61
+ channelToTargetLabel = 'sends from channel',
62
+ sourceToChannelLabel = 'sends to channel',
63
+ mode = 'full',
64
+ currentNodes = [],
65
+ }: {
66
+ channels: CollectionEntry<'channels'>[];
67
+ channelsToRender: { id: string; version: string }[];
68
+ source: CollectionEntry<CollectionTypes>;
69
+ target: CollectionEntry<CollectionTypes>;
70
+ channelToTargetLabel?: string;
71
+ sourceToChannelLabel?: string;
72
+ mode?: 'simple' | 'full';
73
+ currentNodes?: Node[];
74
+ }) => {
75
+ const nodes: Node[] = [];
76
+ const edges: Edge[] = [];
77
+
78
+ // Get the channels from the collection
79
+ const channels = channelsToRender
80
+ .map((channel) => getItemsFromCollectionByIdAndSemverOrLatest(channelsCollection, channel.id, channel.version)[0])
81
+ .filter((channel) => channel !== undefined);
82
+
83
+ channels.forEach((channel) => {
84
+ const channelId = generateIdForNodes([source, channel, target]);
85
+
86
+ // Need to check if the channel node is already in the graph
87
+ // if (!currentNodes.find((node) => node.id === channelId)) {
88
+ nodes.push(
89
+ createNode({
90
+ id: channelId,
91
+ data: { title: channel?.data.id, mode, channel, source, target },
92
+ position: { x: 0, y: 0 },
93
+ type: channel?.collection,
94
+ })
95
+ );
96
+ // }
97
+
98
+ // if the source (left node) is a service, use the target as the edge message
99
+ const edgeMessage = source.collection === 'services' ? target : source;
100
+
101
+ // Link from left to channel
102
+ edges.push(
103
+ createEdge({
104
+ // id: generatedIdForEdge(source, channel),
105
+ id: generateIdForNodes([source, channel, target]),
106
+ source: generateIdForNode(source),
107
+ target: channelId,
108
+ label: '',
109
+ // label: sourceToChannelLabel,
110
+ data: { message: edgeMessage },
111
+ })
112
+ );
113
+
114
+ // Link channel to service
115
+ edges.push(
116
+ createEdge({
117
+ // id: generatedIdForEdge(channel, target),
118
+ id: generateIdForNodes([channel, target, source]),
119
+ source: channelId,
120
+ target: generateIdForNode(target),
121
+ label: channelToTargetLabel,
122
+ data: { message: edgeMessage },
123
+ })
124
+ );
125
+ });
126
+
127
+ return { nodes, edges };
128
+ };
@@ -1,8 +1,9 @@
1
1
  import type { CollectionTypes, PageTypes } from '@types';
2
- import { getDomains } from '@utils/domains/domains';
2
+ import { getChannels } from '@utils/channels';
3
+ import { getDomains } from '@utils/collections/domains';
3
4
  import { getCommands, getEvents } from '@utils/messages';
4
5
  import { getQueries } from '@utils/queries';
5
- import { getServices } from '@utils/services/services';
6
+ import { getServices } from '@utils/collections/services';
6
7
  import type { CollectionEntry } from 'astro:content';
7
8
 
8
9
  export const pageDataLoader: Record<PageTypes, () => Promise<CollectionEntry<CollectionTypes>[]>> = {
@@ -11,4 +12,5 @@ export const pageDataLoader: Record<PageTypes, () => Promise<CollectionEntry<Col
11
12
  queries: getQueries,
12
13
  services: getServices,
13
14
  domains: getDomains,
15
+ channels: getChannels,
14
16
  };
@@ -23,6 +23,7 @@ export const getQueries = async ({ getAllVersions = true }: Props = {}): Promise
23
23
  });
24
24
 
25
25
  const services = await getCollection('services');
26
+ const allChannels = await getCollection('channels');
26
27
 
27
28
  return queries.map((query) => {
28
29
  const { latestVersion, versions } = getVersionForCollectionItem(query, queries);
@@ -43,10 +44,14 @@ export const getQueries = async ({ getAllVersions = true }: Props = {}): Promise
43
44
  })
44
45
  );
45
46
 
47
+ const messageChannels = query.data.channels || [];
48
+ const channelsForQuery = allChannels.filter((c) => messageChannels.some((channel) => c.data.id === channel.id));
49
+
46
50
  return {
47
51
  ...query,
48
52
  data: {
49
53
  ...query.data,
54
+ messageChannels: channelsForQuery,
50
55
  producers,
51
56
  consumers,
52
57
  versions,
package/tsconfig.json CHANGED
@@ -5,7 +5,8 @@
5
5
  "baseUrl": ".",
6
6
  "paths": {
7
7
  "@config": ["./eventcatalog.config.js"],
8
- "@eventcatalog": ["src/utils/config/catalog.ts"],
8
+ "@eventcatalog": ["src/utils/eventcatalog-config/catalog.ts"],
9
+ "@icons/*": ["src/icons/*"],
9
10
  "@components/*": ["src/components/*"],
10
11
  "@catalog/components/*": ["src/custom-defined-components/*"],
11
12
  "@types": ["src/types/index.ts"],
@@ -1,9 +0,0 @@
1
- import { execSync } from "child_process";
2
-
3
- export function remarkModifiedTime() {
4
- return function (_, file) {
5
- const filepath = file.history[0];
6
- const result = execSync(`git log -1 --pretty="format:%cI" "${filepath}"`);
7
- file.data.astro.frontmatter.lastModified = result.toString();
8
- };
9
- }
@@ -1,144 +0,0 @@
1
- import { findMatchingNodes } from '@utils/collections/util';
2
- import { getCommands } from '@utils/commands';
3
- import { calculatedNodes, createDagreGraph, generateIdForNode, generatedIdForEdge } from '@utils/node-graph-utils/utils';
4
- import { type CollectionEntry } from 'astro:content';
5
- import dagre from 'dagre';
6
- import { MarkerType } from 'reactflow';
7
-
8
- type DagreGraph = any;
9
-
10
- interface Props {
11
- id: string;
12
- version: string;
13
- defaultFlow?: DagreGraph;
14
- mode?: 'simple' | 'full';
15
- }
16
-
17
- export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple' }: Props) => {
18
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
19
- const nodes = [] as any,
20
- edges = [] as any;
21
-
22
- const commands = await getCommands();
23
-
24
- const command = commands.find((command) => command.data.id === id && command.data.version === version);
25
-
26
- // Nothing found...
27
- if (!command) {
28
- return {
29
- nodes: [],
30
- edges: [],
31
- };
32
- }
33
-
34
- const producers = (command.data.producers as CollectionEntry<'services'>[]) || [];
35
- const consumers = (command.data.consumers as CollectionEntry<'services'>[]) || [];
36
-
37
- // Track nodes that are both sent and received
38
- const bothSentAndReceived = findMatchingNodes(producers, consumers);
39
-
40
- if (producers && producers.length > 0) {
41
- producers.forEach((producer, index) => {
42
- nodes.push({
43
- id: generateIdForNode(producer),
44
- type: producer?.collection,
45
- sourcePosition: 'right',
46
- targetPosition: 'left',
47
- data: { mode, service: producer },
48
- position: { x: 250, y: 0 },
49
- });
50
- edges.push({
51
- id: generatedIdForEdge(producer, command),
52
- source: generateIdForNode(producer),
53
- target: generateIdForNode(command),
54
- type: 'smoothstep',
55
- label: 'invokes',
56
- animated: false,
57
- markerEnd: {
58
- type: MarkerType.ArrowClosed,
59
- width: 40,
60
- height: 40,
61
- },
62
- style: {
63
- strokeWidth: 1,
64
- },
65
- });
66
- });
67
- }
68
-
69
- // The service itself
70
- nodes.push({
71
- id: generateIdForNode(command),
72
- sourcePosition: 'right',
73
- targetPosition: 'left',
74
- data: { mode, message: command },
75
- position: { x: 0, y: 0 },
76
- type: command.collection,
77
- });
78
-
79
- // The messages the service sends
80
- consumers.forEach((consumer) => {
81
- nodes.push({
82
- id: generateIdForNode(consumer),
83
- sourcePosition: 'right',
84
- targetPosition: 'left',
85
- data: { title: consumer?.data.id, mode, service: consumer },
86
- position: { x: 0, y: 0 },
87
- type: consumer?.collection,
88
- });
89
- edges.push({
90
- id: generatedIdForEdge(command, consumer),
91
- source: generateIdForNode(command),
92
- target: generateIdForNode(consumer),
93
- type: 'smoothstep',
94
- label: 'accepts',
95
- animated: false,
96
- markerEnd: {
97
- type: MarkerType.ArrowClosed,
98
- width: 40,
99
- height: 40,
100
- },
101
- style: {
102
- strokeWidth: 1,
103
- },
104
- });
105
- });
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
-
129
- nodes.forEach((node: any) => {
130
- flow.setNode(node.id, { width: 150, height: 100 });
131
- });
132
-
133
- edges.forEach((edge: any) => {
134
- flow.setEdge(edge.source, edge.target);
135
- });
136
-
137
- // Render the diagram in memory getting hte X and Y
138
- dagre.layout(flow);
139
-
140
- return {
141
- nodes: calculatedNodes(flow, nodes),
142
- edges: edges,
143
- };
144
- };
@@ -1,145 +0,0 @@
1
- // import { getColor } from '@utils/colors';
2
- import { getEvents } from '@utils/events';
3
- import type { CollectionEntry } from 'astro:content';
4
- import dagre from 'dagre';
5
- import { calculatedNodes, createDagreGraph, generatedIdForEdge, generateIdForNode } from '../node-graph-utils/utils';
6
- import { MarkerType } from 'reactflow';
7
- import { findMatchingNodes } from '@utils/collections/util';
8
-
9
- type DagreGraph = any;
10
-
11
- interface Props {
12
- id: string;
13
- version: string;
14
- defaultFlow?: DagreGraph;
15
- mode?: 'simple' | 'full';
16
- }
17
-
18
- export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple' }: Props) => {
19
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
20
- const nodes = [] as any,
21
- edges = [] as any;
22
-
23
- const events = await getEvents();
24
-
25
- const event = events.find((event) => event.data.id === id && event.data.version === version);
26
-
27
- // Nothing found...
28
- if (!event) {
29
- return {
30
- nodes: [],
31
- edges: [],
32
- };
33
- }
34
-
35
- const producers = (event.data.producers as CollectionEntry<'services'>[]) || [];
36
- const consumers = (event.data.consumers as CollectionEntry<'services'>[]) || [];
37
-
38
- // Track nodes that are both sent and received
39
- const bothSentAndReceived = findMatchingNodes(producers, consumers);
40
-
41
- if (producers && producers.length > 0) {
42
- producers.forEach((producer) => {
43
- nodes.push({
44
- id: generateIdForNode(producer),
45
- type: producer?.collection,
46
- sourcePosition: 'right',
47
- targetPosition: 'left',
48
- data: { mode, service: producer, showTarget: false },
49
- position: { x: 250, y: 0 },
50
- });
51
- edges.push({
52
- id: generatedIdForEdge(producer, event),
53
- source: generateIdForNode(producer),
54
- target: generateIdForNode(event),
55
- type: 'smoothstep',
56
- label: 'publishes event',
57
- animated: false,
58
- markerEnd: {
59
- type: MarkerType.ArrowClosed,
60
- width: 40,
61
- height: 40,
62
- },
63
- style: {
64
- strokeWidth: 1,
65
- },
66
- });
67
- });
68
- }
69
-
70
- // The event itself
71
- nodes.push({
72
- id: generateIdForNode(event),
73
- sourcePosition: 'right',
74
- targetPosition: 'left',
75
- data: { mode, message: event, showTarget: producers.length > 0, showSource: consumers.length > 0 },
76
- position: { x: 0, y: 0 },
77
- type: event.collection,
78
- });
79
-
80
- // The messages the service sends
81
- consumers.forEach((consumer) => {
82
- nodes.push({
83
- id: generateIdForNode(consumer),
84
- sourcePosition: 'right',
85
- targetPosition: 'left',
86
- data: { title: consumer?.data.id, mode, service: consumer, showSource: false },
87
- position: { x: 0, y: 0 },
88
- type: consumer?.collection,
89
- });
90
- edges.push({
91
- id: generatedIdForEdge(event, consumer),
92
- source: generateIdForNode(event),
93
- target: generateIdForNode(consumer),
94
- type: 'smoothstep',
95
- label: 'subscribed by',
96
- animated: false,
97
- markerEnd: {
98
- type: MarkerType.ArrowClosed,
99
- width: 40,
100
- height: 40,
101
- },
102
- style: {
103
- strokeWidth: 1,
104
- },
105
- });
106
- });
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
-
130
- nodes.forEach((node: any) => {
131
- flow.setNode(node.id, { width: 150, height: 100 });
132
- });
133
-
134
- edges.forEach((edge: any) => {
135
- flow.setEdge(edge.source, edge.target);
136
- });
137
-
138
- // Render the diagram in memory getting hte X and Y
139
- dagre.layout(flow);
140
-
141
- return {
142
- nodes: calculatedNodes(flow, nodes),
143
- edges: edges,
144
- };
145
- };
@@ -1,29 +0,0 @@
1
- import type { CollectionEntry } from 'astro:content';
2
- import type { Node } from 'reactflow';
3
- import dagre from 'dagre';
4
-
5
- export const generateIdForNode = (node: CollectionEntry<'events' | 'services' | 'commands' | 'queries'>) => {
6
- return `${node.data.id}-${node.data.version}`;
7
- };
8
-
9
- export const generatedIdForEdge = (
10
- source: CollectionEntry<'events' | 'services' | 'commands' | 'queries'>,
11
- target: CollectionEntry<'events' | 'services' | 'commands' | 'queries'>
12
- ) => {
13
- return `${source.data.id}-${source.data.version}-${target.data.id}-${target.data.version}`;
14
- };
15
-
16
- export const calculatedNodes = (flow: dagre.graphlib.Graph, nodes: Node[]) => {
17
- return nodes.map((node: any) => {
18
- const { x, y } = flow.node(node.id);
19
- return { ...node, position: { x, y } };
20
- });
21
- };
22
-
23
- // Creates a new dagre graph
24
- export const createDagreGraph = ({ ranksep = 180, nodesep = 50, ...rest }: any) => {
25
- const graph = new dagre.graphlib.Graph({ compound: true });
26
- graph.setGraph({ rankdir: 'LR', ranksep, nodesep, ...rest });
27
- graph.setDefaultEdgeLabel(() => ({}));
28
- return graph;
29
- };
@@ -1,144 +0,0 @@
1
- import { getQueries } from '@utils/queries';
2
- import type { CollectionEntry } from 'astro:content';
3
- import dagre from 'dagre';
4
- import { calculatedNodes, createDagreGraph, generatedIdForEdge, generateIdForNode } from '../node-graph-utils/utils';
5
- import { MarkerType } from 'reactflow';
6
- import { findMatchingNodes } from '@utils/collections/util';
7
-
8
- type DagreGraph = any;
9
-
10
- interface Props {
11
- id: string;
12
- version: string;
13
- defaultFlow?: DagreGraph;
14
- mode?: 'simple' | 'full';
15
- }
16
-
17
- export const getNodesAndEdges = async ({ id, version, defaultFlow, mode = 'simple' }: Props) => {
18
- const flow = defaultFlow || createDagreGraph({ ranksep: 300, nodesep: 50 });
19
- const nodes = [] as any,
20
- edges = [] as any;
21
-
22
- const queries = await getQueries();
23
-
24
- const query = queries.find((query) => query.data.id === id && query.data.version === version);
25
-
26
- // Nothing found...
27
- if (!query) {
28
- return {
29
- nodes: [],
30
- edges: [],
31
- };
32
- }
33
-
34
- const producers = (query.data.producers as CollectionEntry<'services'>[]) || [];
35
- const consumers = (query.data.consumers as CollectionEntry<'services'>[]) || [];
36
-
37
- // Track nodes that are both sent and received
38
- const bothSentAndReceived = findMatchingNodes(producers, consumers);
39
-
40
- if (producers && producers.length > 0) {
41
- producers.forEach((producer) => {
42
- nodes.push({
43
- id: generateIdForNode(producer),
44
- type: producer?.collection,
45
- sourcePosition: 'right',
46
- targetPosition: 'left',
47
- data: { mode, service: producer },
48
- position: { x: 250, y: 0 },
49
- });
50
- edges.push({
51
- id: generatedIdForEdge(producer, query),
52
- source: generateIdForNode(producer),
53
- target: generateIdForNode(query),
54
- type: 'smoothstep',
55
- label: 'requests',
56
- animated: false,
57
- markerEnd: {
58
- type: MarkerType.ArrowClosed,
59
- width: 40,
60
- height: 40,
61
- },
62
- style: {
63
- strokeWidth: 1,
64
- },
65
- });
66
- });
67
- }
68
-
69
- // The query itself
70
- nodes.push({
71
- id: generateIdForNode(query),
72
- sourcePosition: 'right',
73
- targetPosition: 'left',
74
- data: { mode, message: query },
75
- position: { x: 0, y: 0 },
76
- type: query.collection,
77
- });
78
-
79
- // The messages the service sends
80
- consumers.forEach((consumer) => {
81
- nodes.push({
82
- id: generateIdForNode(consumer),
83
- sourcePosition: 'right',
84
- targetPosition: 'left',
85
- data: { title: consumer?.data.id, mode, service: consumer },
86
- position: { x: 0, y: 0 },
87
- type: consumer?.collection,
88
- });
89
- edges.push({
90
- id: generatedIdForEdge(query, consumer),
91
- source: generateIdForNode(query),
92
- target: generateIdForNode(consumer),
93
- type: 'smoothstep',
94
- label: 'accepts',
95
- animated: false,
96
- markerEnd: {
97
- type: MarkerType.ArrowClosed,
98
- width: 40,
99
- height: 40,
100
- },
101
- style: {
102
- strokeWidth: 1,
103
- },
104
- });
105
- });
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
-
129
- nodes.forEach((node: any) => {
130
- flow.setNode(node.id, { width: 150, height: 100 });
131
- });
132
-
133
- edges.forEach((edge: any) => {
134
- flow.setEdge(edge.source, edge.target);
135
- });
136
-
137
- // Render the diagram in memory getting hte X and Y
138
- dagre.layout(flow);
139
-
140
- return {
141
- nodes: calculatedNodes(flow, nodes),
142
- edges: edges,
143
- };
144
- };
File without changes
File without changes
File without changes
File without changes