@eventcatalog/visualiser 5.0.0-beta.1 → 5.0.0-beta.3

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/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  useState as useState15,
6
6
  useCallback as useCallback13,
7
7
  useRef as useRef9,
8
- memo as memo45
8
+ memo as memo46
9
9
  } from "react";
10
10
  import { createPortal } from "react-dom";
11
11
  import {
@@ -1019,10 +1019,13 @@ function TruncatedResourceName({
1019
1019
  const updateTruncation = () => {
1020
1020
  setIsTruncated(element.scrollWidth > element.clientWidth);
1021
1021
  };
1022
- updateTruncation();
1023
1022
  if (typeof ResizeObserver === "undefined") {
1023
+ const frame = requestAnimationFrame(updateTruncation);
1024
1024
  window.addEventListener("resize", updateTruncation);
1025
- return () => window.removeEventListener("resize", updateTruncation);
1025
+ return () => {
1026
+ cancelAnimationFrame(frame);
1027
+ window.removeEventListener("resize", updateTruncation);
1028
+ };
1026
1029
  }
1027
1030
  const observer = new ResizeObserver(updateTruncation);
1028
1031
  observer.observe(element);
@@ -4239,7 +4242,8 @@ var DomainCard_default = memo17(function DomainCardNode({ data }) {
4239
4242
  systemsCount = 0,
4240
4243
  servicesCount = 0,
4241
4244
  entitiesCount = 0,
4242
- subdomain = false
4245
+ subdomain = false,
4246
+ navigable = true
4243
4247
  } = data;
4244
4248
  const { id, version, name, summary } = domain;
4245
4249
  const stats = [
@@ -4251,14 +4255,16 @@ var DomainCard_default = memo17(function DomainCardNode({ data }) {
4251
4255
  return /* @__PURE__ */ jsxs17(
4252
4256
  "div",
4253
4257
  {
4254
- role: "button",
4255
- tabIndex: 0,
4256
- onClick: goToDiagram,
4257
- onKeyDown: (e) => {
4258
- if (e.key === "Enter" || e.key === " ") goToDiagram();
4259
- },
4260
- title: `Open the ${name} diagram`,
4261
- className: "relative min-w-48 max-w-60 rounded-xl border-2 border-yellow-400 overflow-visible cursor-pointer",
4258
+ ...navigable ? {
4259
+ role: "button",
4260
+ tabIndex: 0,
4261
+ onClick: goToDiagram,
4262
+ onKeyDown: (e) => {
4263
+ if (e.key === "Enter" || e.key === " ") goToDiagram();
4264
+ },
4265
+ title: `Open the ${name} diagram`
4266
+ } : {},
4267
+ className: `relative min-w-48 max-w-60 rounded-xl border-2 border-yellow-400 overflow-visible${navigable ? " cursor-pointer" : ""}`,
4262
4268
  style: CARD_STYLE,
4263
4269
  children: [
4264
4270
  /* @__PURE__ */ jsx19(
@@ -6026,12 +6032,14 @@ var System_default = memo27(function SystemNode({ data }) {
6026
6032
  entitiesCount = 0,
6027
6033
  containersCount = 0,
6028
6034
  messagesCount = 0,
6029
- isFocused = false
6035
+ isFocused = false,
6036
+ navigable = true
6030
6037
  } = data;
6031
6038
  const { id, version, name, summary, scope } = system;
6032
6039
  const isExternal = scope === "external";
6033
6040
  const isDark = useDarkMode();
6034
6041
  const isFlowStep = Boolean(data.step);
6042
+ const opensMap = navigable && !isFlowStep;
6035
6043
  const stats = [
6036
6044
  { icon: ServerIcon3, label: "Services", count: servicesCount },
6037
6045
  { icon: MessageSquareIcon, label: "Messages", count: messagesCount },
@@ -6045,7 +6053,7 @@ var System_default = memo27(function SystemNode({ data }) {
6045
6053
  return /* @__PURE__ */ jsxs28(
6046
6054
  "div",
6047
6055
  {
6048
- ...isFlowStep ? {} : {
6056
+ ...!opensMap ? {} : {
6049
6057
  role: "button",
6050
6058
  tabIndex: 0,
6051
6059
  onClick: goToMap,
@@ -6056,7 +6064,7 @@ var System_default = memo27(function SystemNode({ data }) {
6056
6064
  },
6057
6065
  className: classNames18(
6058
6066
  "relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible",
6059
- !isFlowStep && "cursor-pointer",
6067
+ opensMap && "cursor-pointer",
6060
6068
  isExternal ? "border-dashed border-violet-400" : "border-violet-500"
6061
6069
  ),
6062
6070
  style: {
@@ -11256,6 +11264,7 @@ var animateLayout = ({
11256
11264
  toEdges,
11257
11265
  setNodes,
11258
11266
  setEdges,
11267
+ getCurrentNodes,
11259
11268
  morphs = [],
11260
11269
  nodeOrigin = [0, 0],
11261
11270
  onDone
@@ -11325,7 +11334,18 @@ var animateLayout = ({
11325
11334
  );
11326
11335
  return [...nodes, ...exitingNodes];
11327
11336
  };
11328
- setNodes(frame(0));
11337
+ const setNodesKeepingSize = (nodes) => {
11338
+ const measured = new Map(
11339
+ getCurrentNodes().map((node) => [node.id, node.measured])
11340
+ );
11341
+ setNodes(
11342
+ nodes.map((node) => {
11343
+ const measuredSize = measured.get(node.id);
11344
+ return measuredSize ? { ...node, measured: measuredSize } : node;
11345
+ })
11346
+ );
11347
+ };
11348
+ setNodesKeepingSize(frame(0));
11329
11349
  setEdges([
11330
11350
  ...toEdges.map(
11331
11351
  (edge) => fromEdgeIds.has(edge.id) ? edge : { ...edge, className: "ec-enter" }
@@ -11336,11 +11356,11 @@ var animateLayout = ({
11336
11356
  let animationFrame = requestAnimationFrame(function tick(now) {
11337
11357
  const t = Math.min(1, (now - start) / LAYOUT_ANIMATION_DURATION);
11338
11358
  if (t < 1) {
11339
- setNodes(frame(easeInOut(t)));
11359
+ setNodesKeepingSize(frame(easeInOut(t)));
11340
11360
  animationFrame = requestAnimationFrame(tick);
11341
11361
  return;
11342
11362
  }
11343
- setNodes(toNodes);
11363
+ setNodesKeepingSize(toNodes);
11344
11364
  setEdges(
11345
11365
  (edges) => edges.filter((edge) => toEdgeIds.has(edge.id)).map(
11346
11366
  (edge) => edge.className === "ec-enter" ? { ...edge, className: void 0 } : edge
@@ -11571,6 +11591,7 @@ var useNodeVisibility = ({
11571
11591
  toEdges: target.edges,
11572
11592
  setNodes,
11573
11593
  setEdges,
11594
+ getCurrentNodes: () => nodesRef.current,
11574
11595
  // When switching graphs, systems expand into their group (or back), e.g.
11575
11596
  // a system in its context diagram
11576
11597
  morphs: from ? getSystemMorphs(from.nodes, target.nodes) : [],
@@ -12076,6 +12097,23 @@ var NodeContextMenu_default = memo44(function NodeContextMenu({
12076
12097
  ] });
12077
12098
  });
12078
12099
 
12100
+ // src/utils/node-memo.ts
12101
+ import { memo as memo45 } from "react";
12102
+ var POSITION_PROPS = /* @__PURE__ */ new Set(["positionAbsoluteX", "positionAbsoluteY"]);
12103
+ var equalExceptPosition = (previous, next) => {
12104
+ const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(next)]);
12105
+ for (const key of keys) {
12106
+ if (POSITION_PROPS.has(key)) continue;
12107
+ if (!Object.is(
12108
+ previous[key],
12109
+ next[key]
12110
+ ))
12111
+ return false;
12112
+ }
12113
+ return true;
12114
+ };
12115
+ var memoNode = (Component) => memo45(Component, equalExceptPosition);
12116
+
12079
12117
  // src/utils/export-image.ts
12080
12118
  import { getViewportForBounds } from "@xyflow/react";
12081
12119
  var MIN_IMAGE_WIDTH = 1024;
@@ -13365,7 +13403,7 @@ var LEGEND_ICONS = {
13365
13403
  field: { Icon: Box, colorClass: "text-cyan-600" }
13366
13404
  };
13367
13405
  var getLegendIcon = (key) => LEGEND_ICONS[key];
13368
- var LegendPanel = memo45(function LegendPanel2({
13406
+ var LegendPanel = memo46(function LegendPanel2({
13369
13407
  legend,
13370
13408
  hiddenKeys,
13371
13409
  showMinimap,
@@ -13527,15 +13565,17 @@ var NodeGraphBuilder = ({
13527
13565
  }, []);
13528
13566
  const nodeTypes = useMemo17(() => {
13529
13567
  const wrapWithContextMenu = (Component) => {
13530
- const Wrapped = memo45((props) => {
13568
+ const Wrapped = (props) => {
13531
13569
  const items = props.data?.contextMenu;
13532
13570
  if (!items?.length) return /* @__PURE__ */ jsx56(Component, { ...props });
13533
13571
  return /* @__PURE__ */ jsx56(NodeContextMenu_default, { items, children: /* @__PURE__ */ jsx56(Component, { ...props }) });
13534
- });
13572
+ };
13535
13573
  Wrapped.displayName = `WithContextMenu(${Component.displayName || Component.name || "Component"})`;
13536
13574
  return Wrapped;
13537
13575
  };
13538
- return {
13576
+ const ReadOnlyNoteNode = (props) => /* @__PURE__ */ jsx56(NoteNode_default, { ...props, readOnly: true });
13577
+ ReadOnlyNoteNode.displayName = "ReadOnlyNoteNode";
13578
+ const types = {
13539
13579
  service: wrapWithContextMenu(ServiceNode_default),
13540
13580
  services: wrapWithContextMenu(ServiceNode_default),
13541
13581
  agent: wrapWithContextMenu(Agent_default),
@@ -13574,13 +13614,19 @@ var NodeGraphBuilder = ({
13574
13614
  "system-group": SystemGroupNode_default,
13575
13615
  "domain-group": SystemGroupNode_default,
13576
13616
  "context-domain": DomainCard_default,
13577
- note: memo45((props) => /* @__PURE__ */ jsx56(NoteNode_default, { ...props, readOnly: true })),
13617
+ note: ReadOnlyNoteNode,
13578
13618
  field: wrapWithContextMenu(FieldNode_default),
13579
13619
  messageGroup: MessageGroupNode_default,
13580
13620
  messageGroupExpanded: MessageGroupExpandedNode_default,
13581
13621
  flowExpanded: FlowExpandedNode_default,
13582
13622
  swimlane: SwimlaneNode_default
13583
13623
  };
13624
+ return Object.fromEntries(
13625
+ Object.entries(types).map(([type, Component]) => [
13626
+ type,
13627
+ memoNode(Component)
13628
+ ])
13629
+ );
13584
13630
  }, []);
13585
13631
  const edgeTypes2 = useMemo17(
13586
13632
  () => ({
@@ -15618,6 +15664,7 @@ export {
15618
15664
  DATA,
15619
15665
  DataNode_default as Data,
15620
15666
  DataProduct_default as DataProductNode,
15667
+ DomainCard_default as DomainCardNode,
15621
15668
  Domain_default as DomainNode,
15622
15669
  ENTITY_TARGET_HANDLE_ID,
15623
15670
  EVENT,