@eventcatalog/core 2.64.3 → 2.65.0-beta.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 (35) hide show
  1. package/README.md +2 -1
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +1 -1
  5. package/dist/analytics/log-build.js +3 -3
  6. package/dist/{chunk-CXZKUSOU.js → chunk-2ZXSFW7J.js} +1 -1
  7. package/dist/chunk-622JYJWG.js +109 -0
  8. package/dist/{chunk-C7L3FLQL.js → chunk-6MJGAOPK.js} +1 -1
  9. package/dist/chunk-BH3JMNAV.js +12 -0
  10. package/dist/{chunk-WAWMXWSY.js → chunk-GGFP7ZBX.js} +1 -1
  11. package/dist/constants.cjs +1 -1
  12. package/dist/constants.js +1 -1
  13. package/dist/eventcatalog.cjs +139 -24
  14. package/dist/eventcatalog.js +9 -3
  15. package/dist/migrations/index.cjs +150 -0
  16. package/dist/migrations/index.d.cts +3 -0
  17. package/dist/migrations/index.d.ts +3 -0
  18. package/dist/migrations/index.js +7 -0
  19. package/dist/migrations/message-channels-to-service-channels.cjs +139 -0
  20. package/dist/migrations/message-channels-to-service-channels.d.cts +6 -0
  21. package/dist/migrations/message-channels-to-service-channels.d.ts +6 -0
  22. package/dist/migrations/message-channels-to-service-channels.js +6 -0
  23. package/eventcatalog/src/components/MDX/NodeGraph/Edges/AnimatedMessageEdge.tsx +42 -28
  24. package/eventcatalog/src/components/MDX/SchemaViewer/SchemaViewerRoot.astro +1 -0
  25. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +41 -35
  26. package/eventcatalog/src/content.config.ts +31 -3
  27. package/eventcatalog/src/enterprise/eventcatalog-chat/providers/ai-provider.ts +0 -4
  28. package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +35 -15
  29. package/eventcatalog/src/utils/channels.ts +73 -1
  30. package/eventcatalog/src/utils/collections/util.ts +7 -0
  31. package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +75 -0
  32. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +856 -61
  33. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +46 -70
  34. package/eventcatalog/src/utils/node-graphs/utils/utils.ts +26 -80
  35. package/package.json +2 -2
@@ -6,11 +6,12 @@ import {
6
6
  generatedIdForEdge,
7
7
  calculatedNodes,
8
8
  createEdge,
9
- getChannelNodesAndEdges,
10
9
  } from '@utils/node-graphs/utils/utils';
10
+
11
11
  import { findMatchingNodes, getItemsFromCollectionByIdAndSemverOrLatest } from '@utils/collections/util';
12
12
  import { MarkerType } from '@xyflow/react';
13
13
  import type { CollectionMessageTypes } from '@types';
14
+ import { getNodesAndEdgesForConsumedMessage, getNodesAndEdgesForProducedMessage } from './message-node-graph';
14
15
 
15
16
  type DagreGraph = any;
16
17
 
@@ -119,42 +120,20 @@ export const getNodesAndEdges = async ({
119
120
  if (renderMessages) {
120
121
  // All the messages the service receives
121
122
  receives.forEach((receive) => {
122
- // Create the node for the message
123
- nodes.push({
124
- id: generateIdForNode(receive),
125
- type: receive?.collection,
126
- sourcePosition: 'right',
127
- targetPosition: 'left',
128
- data: { mode, message: { ...receive.data } },
123
+ const targetChannels = receivesRaw.find((receiveRaw) => receiveRaw.id === receive.data.id)?.from;
124
+
125
+ const { nodes: consumedMessageNodes, edges: consumedMessageEdges } = getNodesAndEdgesForConsumedMessage({
126
+ message: receive,
127
+ targetChannels: targetChannels,
128
+ services,
129
+ currentNodes: nodes,
130
+ target: service,
131
+ mode,
132
+ channels,
129
133
  });
130
134
 
131
- // does the message have channels defined?
132
- if (receive.data.channels) {
133
- const { nodes: channelNodes, edges: channelEdges } = getChannelNodesAndEdges({
134
- channels,
135
- channelsToRender: receive.data.channels,
136
- source: receive,
137
- channelToTargetLabel: getReceivesMessageByMessageType(receive?.collection),
138
- target: service,
139
- mode,
140
- currentNodes: nodes,
141
- channelRenderMode,
142
- });
143
-
144
- nodes.push(...channelNodes);
145
- edges.push(...channelEdges);
146
- } else {
147
- // No channels, just link the message to the service
148
- edges.push(
149
- createEdge({
150
- id: generatedIdForEdge(receive, service),
151
- source: generateIdForNode(receive),
152
- target: generateIdForNode(service),
153
- label: getReceivesMessageByMessageType(receive?.collection),
154
- data: { message: { ...receive.data } },
155
- })
156
- );
157
- }
135
+ nodes.push(...consumedMessageNodes);
136
+ edges.push(...consumedMessageEdges);
158
137
  });
159
138
  }
160
139
 
@@ -230,42 +209,22 @@ export const getNodesAndEdges = async ({
230
209
  });
231
210
 
232
211
  if (renderMessages) {
233
- // The messages the service sends
234
- sends.forEach((send, index) => {
235
- nodes.push({
236
- id: generateIdForNode(send),
237
- sourcePosition: 'right',
238
- targetPosition: 'left',
239
- data: { mode, message: { ...send.data } },
240
- type: send?.collection,
212
+ sends.forEach((send) => {
213
+ const sourceChannels = sendsRaw.find((sendRaw) => sendRaw.id === send.data.id)?.to;
214
+
215
+ const { nodes: producedMessageNodes, edges: producedMessageEdges } = getNodesAndEdgesForProducedMessage({
216
+ message: send,
217
+ sourceChannels: sourceChannels,
218
+ services,
219
+ currentNodes: nodes,
220
+ source: service,
221
+ currentEdges: edges,
222
+ mode,
223
+ channels,
241
224
  });
242
225
 
243
- if (send.data.channels) {
244
- const { nodes: channelNodes, edges: channelEdges } = getChannelNodesAndEdges({
245
- channels,
246
- channelsToRender: send.data.channels,
247
- source: service,
248
- target: send,
249
- mode,
250
- sourceToChannelLabel: `${getSendsMessageByMessageType(send?.collection)}`,
251
- channelToTargetLabel: getSendsMessageByMessageType(send?.collection),
252
- currentNodes: nodes,
253
- channelRenderMode,
254
- });
255
- nodes.push(...channelNodes);
256
- edges.push(...channelEdges);
257
- } else {
258
- // No channels, just link the message to the service
259
- edges.push(
260
- createEdge({
261
- id: generatedIdForEdge(service, send),
262
- source: generateIdForNode(service),
263
- target: generateIdForNode(send),
264
- label: getSendsMessageByMessageType(send?.collection),
265
- data: { message: { ...send.data } },
266
- })
267
- );
268
- }
226
+ nodes.push(...producedMessageNodes);
227
+ edges.push(...producedMessageEdges);
269
228
  });
270
229
 
271
230
  // Handle messages that are both sent and received
@@ -325,8 +284,25 @@ export const getNodesAndEdges = async ({
325
284
  // Render the diagram in memory getting the X and Y
326
285
  dagre.layout(flow);
327
286
 
287
+ // Find any duplicated edges, and merge them into one edge
288
+ const uniqueEdges = edges.reduce((acc: any[], edge: any) => {
289
+ const existingEdge = acc.find((e: any) => e.id === edge.id);
290
+ if (existingEdge) {
291
+ existingEdge.label = `${existingEdge.label} & ${edge.label}`;
292
+ // Add the custom colors to the existing edge which can be an array of strings
293
+ const value = Array.isArray(edge.data.customColor) ? edge.data.customColor : [edge.data.customColor];
294
+ const existingValue = Array.isArray(existingEdge.data.customColor)
295
+ ? existingEdge.data.customColor
296
+ : [existingEdge.data.customColor];
297
+ existingEdge.data.customColor = [...value, ...existingValue];
298
+ } else {
299
+ acc.push(edge);
300
+ }
301
+ return acc;
302
+ }, []);
303
+
328
304
  return {
329
305
  nodes: calculatedNodes(flow, nodes),
330
- edges,
306
+ edges: uniqueEdges,
331
307
  };
332
308
  };
@@ -27,26 +27,44 @@ export const generatedIdForEdge = (source: CollectionItem, target: CollectionIte
27
27
  return `${source.data.id}-${source.data.version}-${target.data.id}-${target.data.version}`;
28
28
  };
29
29
 
30
+ export const getColorFromString = (id: string) => {
31
+ // Takes the given id (string) and returns a custom hex color based on the id
32
+ // Create a hash from the string
33
+ let hash = 0;
34
+ for (let i = 0; i < id.length; i++) {
35
+ hash = id.charCodeAt(i) + ((hash << 5) - hash);
36
+ }
37
+
38
+ // Convert the hash into a hex color
39
+ let color = '#';
40
+ for (let i = 0; i < 3; i++) {
41
+ const value = (hash >> (i * 8)) & 0xff;
42
+ color += value.toString(16).padStart(2, '0');
43
+ }
44
+
45
+ return color;
46
+ };
47
+
30
48
  export const getEdgeLabelForServiceAsTarget = (data: MessageCollectionItem) => {
31
49
  const type = data.collection;
32
50
  switch (type) {
33
51
  case 'commands':
34
52
  return 'invokes';
35
53
  case 'events':
36
- return 'publishes event';
54
+ return 'publishes \nevent';
37
55
  case 'queries':
38
56
  return 'requests';
39
57
  default:
40
58
  return 'sends to';
41
59
  }
42
60
  };
43
- export const getEdgeLabelForMessageAsSource = (data: MessageCollectionItem) => {
61
+ export const getEdgeLabelForMessageAsSource = (data: MessageCollectionItem, throughChannel = false) => {
44
62
  const type = data.collection;
45
63
  switch (type) {
46
64
  case 'commands':
47
65
  return 'accepts';
48
66
  case 'events':
49
- return 'subscribed by';
67
+ return throughChannel ? 'subscribed to' : 'subscribed by';
50
68
  case 'queries':
51
69
  return 'accepts';
52
70
  default:
@@ -73,6 +91,11 @@ export const createEdge = (edgeOptions: Edge) => {
73
91
  return {
74
92
  label: 'subscribed by',
75
93
  animated: false,
94
+ // markerStart: {
95
+ // type: MarkerType.Arrow,
96
+ // width: 40,
97
+ // height: 40,
98
+ // },
76
99
  markerEnd: {
77
100
  type: MarkerType.ArrowClosed,
78
101
  width: 40,
@@ -93,83 +116,6 @@ export const createNode = (values: Node): Node => {
93
116
  };
94
117
  };
95
118
 
96
- export const getChannelNodesAndEdges = ({
97
- channels: channelsCollection,
98
- channelsToRender,
99
- source,
100
- target,
101
- channelToTargetLabel = 'sends from channel',
102
- sourceToChannelLabel = 'sends to channel',
103
- mode = 'full',
104
- currentNodes = [],
105
- channelRenderMode = 'flat',
106
- }: {
107
- channels: CollectionItem[];
108
- channelsToRender: { id: string; version: string }[];
109
- source: CollectionItem;
110
- target: CollectionItem;
111
- channelToTargetLabel?: string;
112
- sourceToChannelLabel?: string;
113
- mode?: 'simple' | 'full';
114
- currentNodes?: Node[];
115
- channelRenderMode?: 'flat' | 'single';
116
- }) => {
117
- const nodes: Node[] = [];
118
- const edges: Edge[] = [];
119
-
120
- // Get the channels from the collection
121
- const channels = channelsToRender
122
- .map((channel) => getItemsFromCollectionByIdAndSemverOrLatest(channelsCollection, channel.id, channel.version)[0])
123
- .filter((channel) => channel !== undefined);
124
-
125
- channels.forEach((channel) => {
126
- const singleChannel = channelRenderMode === 'single'; // Only one node per channel, other wise one node per channel connection
127
- const channelId = singleChannel ? generateIdForNodes([channel]) : generateIdForNodes([source, channel, target]);
128
-
129
- // Need to check if the channel node is already in the graph
130
- if (!currentNodes.find((node) => node.id === channelId)) {
131
- nodes.push(
132
- createNode({
133
- id: channelId,
134
- data: { title: channel?.data.id, mode, channel: { ...channel, ...channel.data }, source, target },
135
- position: { x: 0, y: 0 },
136
- type: channel?.collection,
137
- })
138
- );
139
- }
140
-
141
- // if the source (left node) is a service, use the target as the edge message
142
- const edgeMessage = source.collection === 'services' ? target : source;
143
-
144
- // Link from left to channel
145
- edges.push(
146
- createEdge({
147
- // id: generatedIdForEdge(source, channel),
148
- id: generateIdForNodes([source, channel, target]),
149
- source: generateIdForNode(source),
150
- target: channelId,
151
- label: '',
152
- // label: sourceToChannelLabel,
153
- data: { message: edgeMessage, source: edgeMessage, channel, target },
154
- })
155
- );
156
-
157
- // Link channel to service
158
- edges.push(
159
- createEdge({
160
- // id: generatedIdForEdge(channel, target),
161
- id: generateIdForNodes([channel, target, source]),
162
- source: channelId,
163
- target: generateIdForNode(target),
164
- label: channelToTargetLabel,
165
- data: { message: edgeMessage, source, channel, target },
166
- })
167
- );
168
- });
169
-
170
- return { nodes, edges };
171
- };
172
-
173
119
  type DagreGraph = any;
174
120
 
175
121
  export const getNodesAndEdgesFromDagre = ({
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "2.64.3",
9
+ "version": "2.65.0-beta.0",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -38,7 +38,7 @@
38
38
  "@eventcatalog/generator-ai": "^1.1.0",
39
39
  "@eventcatalog/license": "^0.0.7",
40
40
  "@eventcatalog/linter": "^0.0.2",
41
- "@eventcatalog/sdk": "^2.8.4",
41
+ "@eventcatalog/sdk": "^2.9.2",
42
42
  "@eventcatalog/visualizer": "^0.0.6",
43
43
  "@fontsource/inter": "^5.2.5",
44
44
  "@headlessui/react": "^2.0.3",