@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.js CHANGED
@@ -46,6 +46,7 @@ __export(index_exports, {
46
46
  DATA: () => DATA,
47
47
  Data: () => DataNode_default,
48
48
  DataProductNode: () => DataProduct_default,
49
+ DomainCardNode: () => DomainCard_default,
49
50
  DomainNode: () => Domain_default,
50
51
  ENTITY_TARGET_HANDLE_ID: () => ENTITY_TARGET_HANDLE_ID,
51
52
  EVENT: () => EVENT,
@@ -113,9 +114,9 @@ __export(index_exports, {
113
114
  module.exports = __toCommonJS(index_exports);
114
115
 
115
116
  // src/components/NodeGraph.tsx
116
- var import_react103 = require("react");
117
+ var import_react104 = require("react");
117
118
  var import_react_dom = require("react-dom");
118
- var import_react104 = require("@xyflow/react");
119
+ var import_react105 = require("@xyflow/react");
119
120
  var import_lucide_react42 = require("lucide-react");
120
121
  var DropdownMenu3 = __toESM(require("@radix-ui/react-dropdown-menu"));
121
122
  var import_html_to_image = require("html-to-image");
@@ -1085,10 +1086,13 @@ function TruncatedResourceName({
1085
1086
  const updateTruncation = () => {
1086
1087
  setIsTruncated(element.scrollWidth > element.clientWidth);
1087
1088
  };
1088
- updateTruncation();
1089
1089
  if (typeof ResizeObserver === "undefined") {
1090
+ const frame = requestAnimationFrame(updateTruncation);
1090
1091
  window.addEventListener("resize", updateTruncation);
1091
- return () => window.removeEventListener("resize", updateTruncation);
1092
+ return () => {
1093
+ cancelAnimationFrame(frame);
1094
+ window.removeEventListener("resize", updateTruncation);
1095
+ };
1092
1096
  }
1093
1097
  const observer = new ResizeObserver(updateTruncation);
1094
1098
  observer.observe(element);
@@ -4300,7 +4304,8 @@ var DomainCard_default = (0, import_react36.memo)(function DomainCardNode({ data
4300
4304
  systemsCount = 0,
4301
4305
  servicesCount = 0,
4302
4306
  entitiesCount = 0,
4303
- subdomain = false
4307
+ subdomain = false,
4308
+ navigable = true
4304
4309
  } = data;
4305
4310
  const { id, version, name, summary } = domain;
4306
4311
  const stats = [
@@ -4312,14 +4317,16 @@ var DomainCard_default = (0, import_react36.memo)(function DomainCardNode({ data
4312
4317
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4313
4318
  "div",
4314
4319
  {
4315
- role: "button",
4316
- tabIndex: 0,
4317
- onClick: goToDiagram,
4318
- onKeyDown: (e) => {
4319
- if (e.key === "Enter" || e.key === " ") goToDiagram();
4320
- },
4321
- title: `Open the ${name} diagram`,
4322
- className: "relative min-w-48 max-w-60 rounded-xl border-2 border-yellow-400 overflow-visible cursor-pointer",
4320
+ ...navigable ? {
4321
+ role: "button",
4322
+ tabIndex: 0,
4323
+ onClick: goToDiagram,
4324
+ onKeyDown: (e) => {
4325
+ if (e.key === "Enter" || e.key === " ") goToDiagram();
4326
+ },
4327
+ title: `Open the ${name} diagram`
4328
+ } : {},
4329
+ className: `relative min-w-48 max-w-60 rounded-xl border-2 border-yellow-400 overflow-visible${navigable ? " cursor-pointer" : ""}`,
4323
4330
  style: CARD_STYLE,
4324
4331
  children: [
4325
4332
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
@@ -6076,12 +6083,14 @@ var System_default = (0, import_react57.memo)(function SystemNode({ data }) {
6076
6083
  entitiesCount = 0,
6077
6084
  containersCount = 0,
6078
6085
  messagesCount = 0,
6079
- isFocused = false
6086
+ isFocused = false,
6087
+ navigable = true
6080
6088
  } = data;
6081
6089
  const { id, version, name, summary, scope } = system;
6082
6090
  const isExternal = scope === "external";
6083
6091
  const isDark = useDarkMode();
6084
6092
  const isFlowStep = Boolean(data.step);
6093
+ const opensMap = navigable && !isFlowStep;
6085
6094
  const stats = [
6086
6095
  { icon: import_lucide_react27.Server, label: "Services", count: servicesCount },
6087
6096
  { icon: import_lucide_react27.MessageSquare, label: "Messages", count: messagesCount },
@@ -6095,7 +6104,7 @@ var System_default = (0, import_react57.memo)(function SystemNode({ data }) {
6095
6104
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
6096
6105
  "div",
6097
6106
  {
6098
- ...isFlowStep ? {} : {
6107
+ ...!opensMap ? {} : {
6099
6108
  role: "button",
6100
6109
  tabIndex: 0,
6101
6110
  onClick: goToMap,
@@ -6106,7 +6115,7 @@ var System_default = (0, import_react57.memo)(function SystemNode({ data }) {
6106
6115
  },
6107
6116
  className: classNames18(
6108
6117
  "relative min-w-48 max-w-60 rounded-xl border-2 overflow-visible",
6109
- !isFlowStep && "cursor-pointer",
6118
+ opensMap && "cursor-pointer",
6110
6119
  isExternal ? "border-dashed border-violet-400" : "border-violet-500"
6111
6120
  ),
6112
6121
  style: {
@@ -11240,6 +11249,7 @@ var animateLayout = ({
11240
11249
  toEdges,
11241
11250
  setNodes,
11242
11251
  setEdges,
11252
+ getCurrentNodes,
11243
11253
  morphs = [],
11244
11254
  nodeOrigin = [0, 0],
11245
11255
  onDone
@@ -11309,7 +11319,18 @@ var animateLayout = ({
11309
11319
  );
11310
11320
  return [...nodes, ...exitingNodes];
11311
11321
  };
11312
- setNodes(frame(0));
11322
+ const setNodesKeepingSize = (nodes) => {
11323
+ const measured = new Map(
11324
+ getCurrentNodes().map((node) => [node.id, node.measured])
11325
+ );
11326
+ setNodes(
11327
+ nodes.map((node) => {
11328
+ const measuredSize = measured.get(node.id);
11329
+ return measuredSize ? { ...node, measured: measuredSize } : node;
11330
+ })
11331
+ );
11332
+ };
11333
+ setNodesKeepingSize(frame(0));
11313
11334
  setEdges([
11314
11335
  ...toEdges.map(
11315
11336
  (edge) => fromEdgeIds.has(edge.id) ? edge : { ...edge, className: "ec-enter" }
@@ -11320,11 +11341,11 @@ var animateLayout = ({
11320
11341
  let animationFrame = requestAnimationFrame(function tick(now) {
11321
11342
  const t = Math.min(1, (now - start) / LAYOUT_ANIMATION_DURATION);
11322
11343
  if (t < 1) {
11323
- setNodes(frame(easeInOut(t)));
11344
+ setNodesKeepingSize(frame(easeInOut(t)));
11324
11345
  animationFrame = requestAnimationFrame(tick);
11325
11346
  return;
11326
11347
  }
11327
- setNodes(toNodes);
11348
+ setNodesKeepingSize(toNodes);
11328
11349
  setEdges(
11329
11350
  (edges) => edges.filter((edge) => toEdgeIds.has(edge.id)).map(
11330
11351
  (edge) => edge.className === "ec-enter" ? { ...edge, className: void 0 } : edge
@@ -11555,6 +11576,7 @@ var useNodeVisibility = ({
11555
11576
  toEdges: target.edges,
11556
11577
  setNodes,
11557
11578
  setEdges,
11579
+ getCurrentNodes: () => nodesRef.current,
11558
11580
  // When switching graphs, systems expand into their group (or back), e.g.
11559
11581
  // a system in its context diagram
11560
11582
  morphs: from ? getSystemMorphs(from.nodes, target.nodes) : [],
@@ -12043,8 +12065,25 @@ var NodeContextMenu_default = (0, import_react98.memo)(function NodeContextMenu(
12043
12065
  ] });
12044
12066
  });
12045
12067
 
12068
+ // src/utils/node-memo.ts
12069
+ var import_react99 = require("react");
12070
+ var POSITION_PROPS = /* @__PURE__ */ new Set(["positionAbsoluteX", "positionAbsoluteY"]);
12071
+ var equalExceptPosition = (previous, next) => {
12072
+ const keys = /* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(next)]);
12073
+ for (const key of keys) {
12074
+ if (POSITION_PROPS.has(key)) continue;
12075
+ if (!Object.is(
12076
+ previous[key],
12077
+ next[key]
12078
+ ))
12079
+ return false;
12080
+ }
12081
+ return true;
12082
+ };
12083
+ var memoNode = (Component) => (0, import_react99.memo)(Component, equalExceptPosition);
12084
+
12046
12085
  // src/utils/export-image.ts
12047
- var import_react99 = require("@xyflow/react");
12086
+ var import_react100 = require("@xyflow/react");
12048
12087
  var MIN_IMAGE_WIDTH = 1024;
12049
12088
  var MIN_IMAGE_HEIGHT = 768;
12050
12089
  var EXPORT_PADDING = 40;
@@ -12057,7 +12096,7 @@ function getExportImageDimensions(nodesBounds) {
12057
12096
  };
12058
12097
  const width = Math.max(MIN_IMAGE_WIDTH, Math.ceil(paddedBounds.width));
12059
12098
  const height = Math.max(MIN_IMAGE_HEIGHT, Math.ceil(paddedBounds.height));
12060
- const viewport = (0, import_react99.getViewportForBounds)(paddedBounds, width, height, 0.5, 2, 0);
12099
+ const viewport = (0, import_react100.getViewportForBounds)(paddedBounds, width, height, 0.5, 2, 0);
12061
12100
  return { width, height, viewport };
12062
12101
  }
12063
12102
  function extractEcVarNames(cssText) {
@@ -12144,7 +12183,7 @@ function injectExportStyles(viewport) {
12144
12183
  }
12145
12184
 
12146
12185
  // src/utils/layout.ts
12147
- var import_react100 = require("@xyflow/react");
12186
+ var import_react101 = require("@xyflow/react");
12148
12187
  var EMPTY_GROUP_WIDTH = 200;
12149
12188
  var EMPTY_GROUP_HEIGHT = 80;
12150
12189
  var defaultSizes = {
@@ -12334,7 +12373,7 @@ async function layoutGraph(nodes, edges, { style } = {}) {
12334
12373
  const isCalls = edge.type === "calls";
12335
12374
  const isBidirectional = edge.type === "reads-writes";
12336
12375
  const arrowMarker = {
12337
- type: import_react100.MarkerType.ArrowClosed,
12376
+ type: import_react101.MarkerType.ArrowClosed,
12338
12377
  width: 20,
12339
12378
  height: 20,
12340
12379
  color: "rgb(var(--ec-page-text-muted))"
@@ -12483,9 +12522,9 @@ var buildMessageGroupExpansionNodes = ({
12483
12522
  };
12484
12523
 
12485
12524
  // src/components/NotesToolbarButton.tsx
12486
- var import_react101 = require("react");
12525
+ var import_react102 = require("react");
12487
12526
  var import_lucide_react41 = require("lucide-react");
12488
- var import_react102 = require("@xyflow/react");
12527
+ var import_react103 = require("@xyflow/react");
12489
12528
  var Dialog3 = __toESM(require("@radix-ui/react-dialog"));
12490
12529
  var import_jsx_runtime55 = require("react/jsx-runtime");
12491
12530
  var NODE_TYPE_META = {
@@ -12748,12 +12787,12 @@ function AllNotesModal({
12748
12787
  onClose,
12749
12788
  nodes
12750
12789
  }) {
12751
- const { setCenter, getZoom } = (0, import_react102.useReactFlow)();
12752
- const [selectedIdx, setSelectedIdx] = (0, import_react101.useState)(0);
12790
+ const { setCenter, getZoom } = (0, import_react103.useReactFlow)();
12791
+ const [selectedIdx, setSelectedIdx] = (0, import_react102.useState)(0);
12753
12792
  const portalContainer = usePortalContainer();
12754
12793
  const totalNotes = noteGroups.reduce((sum, g) => sum + g.notes.length, 0);
12755
12794
  const selected = noteGroups[selectedIdx] || noteGroups[0];
12756
- const handleNavigate = (0, import_react101.useCallback)(
12795
+ const handleNavigate = (0, import_react102.useCallback)(
12757
12796
  (nodeId) => {
12758
12797
  const node = nodes.find((n) => n.id === nodeId);
12759
12798
  if (!node) return;
@@ -13314,7 +13353,7 @@ var LEGEND_ICONS = {
13314
13353
  field: { Icon: import_lucide_react42.Box, colorClass: "text-cyan-600" }
13315
13354
  };
13316
13355
  var getLegendIcon = (key) => LEGEND_ICONS[key];
13317
- var LegendPanel = (0, import_react103.memo)(function LegendPanel2({
13356
+ var LegendPanel = (0, import_react104.memo)(function LegendPanel2({
13318
13357
  legend,
13319
13358
  hiddenKeys,
13320
13359
  showMinimap,
@@ -13322,7 +13361,7 @@ var LegendPanel = (0, import_react103.memo)(function LegendPanel2({
13322
13361
  }) {
13323
13362
  if (Object.keys(legend).length === 0) return null;
13324
13363
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
13325
- import_react104.Panel,
13364
+ import_react105.Panel,
13326
13365
  {
13327
13366
  position: "bottom-right",
13328
13367
  style: showMinimap ? LEGEND_PANEL_STYLE_WITH_MINIMAP : void 0,
@@ -13363,7 +13402,7 @@ var GROUP_EDGE_STYLE = {
13363
13402
  stroke: "var(--ec-edge-stroke, #6b7280)"
13364
13403
  };
13365
13404
  var GROUP_EDGE_MARKER = {
13366
- type: import_react104.MarkerType.ArrowClosed,
13405
+ type: import_react105.MarkerType.ArrowClosed,
13367
13406
  width: 20,
13368
13407
  height: 20
13369
13408
  };
@@ -13469,22 +13508,24 @@ var NodeGraphBuilder = ({
13469
13508
  onSaveLayout,
13470
13509
  onResetLayout
13471
13510
  }) => {
13472
- (0, import_react103.useEffect)(() => {
13511
+ (0, import_react104.useEffect)(() => {
13473
13512
  if (onBuildUrl) {
13474
13513
  setBuildUrlFn(onBuildUrl);
13475
13514
  }
13476
13515
  }, []);
13477
- const nodeTypes = (0, import_react103.useMemo)(() => {
13516
+ const nodeTypes = (0, import_react104.useMemo)(() => {
13478
13517
  const wrapWithContextMenu = (Component) => {
13479
- const Wrapped = (0, import_react103.memo)((props) => {
13518
+ const Wrapped = (props) => {
13480
13519
  const items = props.data?.contextMenu;
13481
13520
  if (!items?.length) return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Component, { ...props });
13482
13521
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(NodeContextMenu_default, { items, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Component, { ...props }) });
13483
- });
13522
+ };
13484
13523
  Wrapped.displayName = `WithContextMenu(${Component.displayName || Component.name || "Component"})`;
13485
13524
  return Wrapped;
13486
13525
  };
13487
- return {
13526
+ const ReadOnlyNoteNode = (props) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(NoteNode_default, { ...props, readOnly: true });
13527
+ ReadOnlyNoteNode.displayName = "ReadOnlyNoteNode";
13528
+ const types = {
13488
13529
  service: wrapWithContextMenu(ServiceNode_default),
13489
13530
  services: wrapWithContextMenu(ServiceNode_default),
13490
13531
  agent: wrapWithContextMenu(Agent_default),
@@ -13523,15 +13564,21 @@ var NodeGraphBuilder = ({
13523
13564
  "system-group": SystemGroupNode_default,
13524
13565
  "domain-group": SystemGroupNode_default,
13525
13566
  "context-domain": DomainCard_default,
13526
- note: (0, import_react103.memo)((props) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(NoteNode_default, { ...props, readOnly: true })),
13567
+ note: ReadOnlyNoteNode,
13527
13568
  field: wrapWithContextMenu(FieldNode_default),
13528
13569
  messageGroup: MessageGroupNode_default,
13529
13570
  messageGroupExpanded: MessageGroupExpandedNode_default,
13530
13571
  flowExpanded: FlowExpandedNode_default,
13531
13572
  swimlane: SwimlaneNode_default
13532
13573
  };
13574
+ return Object.fromEntries(
13575
+ Object.entries(types).map(([type, Component]) => [
13576
+ type,
13577
+ memoNode(Component)
13578
+ ])
13579
+ );
13533
13580
  }, []);
13534
- const edgeTypes2 = (0, import_react103.useMemo)(
13581
+ const edgeTypes2 = (0, import_react104.useMemo)(
13535
13582
  () => ({
13536
13583
  animated: AnimatedMessageEdge_default,
13537
13584
  multiline: MultilineEdgeLabel_default,
@@ -13542,8 +13589,8 @@ var NodeGraphBuilder = ({
13542
13589
  }),
13543
13590
  []
13544
13591
  );
13545
- const [nodes, setNodes, onNodesChange] = (0, import_react104.useNodesState)(initialNodes);
13546
- const [edges, setEdges, onEdgesChange] = (0, import_react104.useEdgesState)(initialEdges);
13592
+ const [nodes, setNodes, onNodesChange] = (0, import_react105.useNodesState)(initialNodes);
13593
+ const [edges, setEdges, onEdgesChange] = (0, import_react105.useEdgesState)(initialEdges);
13547
13594
  const {
13548
13595
  fitView,
13549
13596
  getNodes,
@@ -13553,13 +13600,13 @@ var NodeGraphBuilder = ({
13553
13600
  getEdges,
13554
13601
  getViewport,
13555
13602
  setViewport
13556
- } = (0, import_react104.useReactFlow)();
13557
- const storeApi = (0, import_react104.useStoreApi)();
13558
- const previousGraphInputRef = (0, import_react103.useRef)({
13603
+ } = (0, import_react105.useReactFlow)();
13604
+ const storeApi = (0, import_react105.useStoreApi)();
13605
+ const previousGraphInputRef = (0, import_react104.useRef)({
13559
13606
  nodes: initialNodes,
13560
13607
  edges: initialEdges
13561
13608
  });
13562
- (0, import_react103.useEffect)(() => {
13609
+ (0, import_react104.useEffect)(() => {
13563
13610
  const previousGraphInput = previousGraphInputRef.current;
13564
13611
  previousGraphInputRef.current = {
13565
13612
  nodes: initialNodes,
@@ -13574,46 +13621,46 @@ var NodeGraphBuilder = ({
13574
13621
  fitView({ duration: 300, padding: 0.2 });
13575
13622
  });
13576
13623
  }, [initialNodes, initialEdges, setNodes, setEdges, fitView]);
13577
- const [animateMessages, setAnimateMessages] = (0, import_react103.useState)(true);
13578
- const prepareEdges = (0, import_react103.useCallback)(
13624
+ const [animateMessages, setAnimateMessages] = (0, import_react104.useState)(true);
13625
+ const prepareEdges = (0, import_react104.useCallback)(
13579
13626
  (eds) => applyMessageAnimation(eds, animateMessages),
13580
13627
  [animateMessages]
13581
13628
  );
13582
- const [_activeStepIndex, _setActiveStepIndex] = (0, import_react103.useState)(null);
13583
- const [_isFullscreen, _setIsFullscreen] = (0, import_react103.useState)(false);
13584
- const [isShareModalOpen, setIsShareModalOpen] = (0, import_react103.useState)(false);
13585
- const [shareUrlCopySuccess, setShareUrlCopySuccess] = (0, import_react103.useState)(false);
13586
- const [isMermaidView, setIsMermaidView] = (0, import_react103.useState)(false);
13587
- const [showMinimap, setShowMinimap] = (0, import_react103.useState)(false);
13588
- const [hasLayoutChanges, setHasLayoutChanges] = (0, import_react103.useState)(false);
13589
- const [isSavingLayout, setIsSavingLayout] = (0, import_react103.useState)(false);
13590
- const initialPositionsRef = (0, import_react103.useRef)(
13629
+ const [_activeStepIndex, _setActiveStepIndex] = (0, import_react104.useState)(null);
13630
+ const [_isFullscreen, _setIsFullscreen] = (0, import_react104.useState)(false);
13631
+ const [isShareModalOpen, setIsShareModalOpen] = (0, import_react104.useState)(false);
13632
+ const [shareUrlCopySuccess, setShareUrlCopySuccess] = (0, import_react104.useState)(false);
13633
+ const [isMermaidView, setIsMermaidView] = (0, import_react104.useState)(false);
13634
+ const [showMinimap, setShowMinimap] = (0, import_react104.useState)(false);
13635
+ const [hasLayoutChanges, setHasLayoutChanges] = (0, import_react104.useState)(false);
13636
+ const [isSavingLayout, setIsSavingLayout] = (0, import_react104.useState)(false);
13637
+ const initialPositionsRef = (0, import_react104.useRef)(
13591
13638
  {}
13592
13639
  );
13593
- const [focusModeOpen, setFocusModeOpen] = (0, import_react103.useState)(false);
13594
- const [focusedNodeId, setFocusedNodeId] = (0, import_react103.useState)(null);
13595
- const [swimlanes, setSwimlanes] = (0, import_react103.useState)(null);
13596
- const swimlanesRef = (0, import_react103.useRef)(null);
13597
- const [swimlaneStyle, setSwimlaneStyle] = (0, import_react103.useState)("boxes");
13598
- const swimlaneStyleRef = (0, import_react103.useRef)("boxes");
13599
- const unlanedGraphRef = (0, import_react103.useRef)(null);
13600
- const [isNotesModalOpen, setIsNotesModalOpen] = (0, import_react103.useState)(false);
13601
- const openNotesModal = (0, import_react103.useCallback)(() => setIsNotesModalOpen(true), []);
13602
- const interactionCountRef = (0, import_react103.useRef)(0);
13603
- const startInteraction = (0, import_react103.useCallback)(() => {
13640
+ const [focusModeOpen, setFocusModeOpen] = (0, import_react104.useState)(false);
13641
+ const [focusedNodeId, setFocusedNodeId] = (0, import_react104.useState)(null);
13642
+ const [swimlanes, setSwimlanes] = (0, import_react104.useState)(null);
13643
+ const swimlanesRef = (0, import_react104.useRef)(null);
13644
+ const [swimlaneStyle, setSwimlaneStyle] = (0, import_react104.useState)("boxes");
13645
+ const swimlaneStyleRef = (0, import_react104.useRef)("boxes");
13646
+ const unlanedGraphRef = (0, import_react104.useRef)(null);
13647
+ const [isNotesModalOpen, setIsNotesModalOpen] = (0, import_react104.useState)(false);
13648
+ const openNotesModal = (0, import_react104.useCallback)(() => setIsNotesModalOpen(true), []);
13649
+ const interactionCountRef = (0, import_react104.useRef)(0);
13650
+ const startInteraction = (0, import_react104.useCallback)(() => {
13604
13651
  interactionCountRef.current += 1;
13605
13652
  if (interactionCountRef.current === 1) {
13606
13653
  reactFlowWrapperRef.current?.classList.add("ec-interaction-active");
13607
13654
  }
13608
13655
  }, []);
13609
- const endInteraction = (0, import_react103.useCallback)(() => {
13656
+ const endInteraction = (0, import_react104.useCallback)(() => {
13610
13657
  interactionCountRef.current = Math.max(0, interactionCountRef.current - 1);
13611
13658
  if (interactionCountRef.current === 0) {
13612
13659
  reactFlowWrapperRef.current?.classList.remove("ec-interaction-active");
13613
13660
  }
13614
13661
  }, []);
13615
- const hoveredEdgeNodesRef = (0, import_react103.useRef)([]);
13616
- const handleEdgeMouseEnter = (0, import_react103.useCallback)(
13662
+ const hoveredEdgeNodesRef = (0, import_react104.useRef)([]);
13663
+ const handleEdgeMouseEnter = (0, import_react104.useCallback)(
13617
13664
  (_, edge) => {
13618
13665
  const wrapper = reactFlowWrapperRef.current;
13619
13666
  if (!wrapper) return;
@@ -13625,15 +13672,15 @@ var NodeGraphBuilder = ({
13625
13672
  },
13626
13673
  []
13627
13674
  );
13628
- const handleEdgeMouseLeave = (0, import_react103.useCallback)(() => {
13675
+ const handleEdgeMouseLeave = (0, import_react104.useCallback)(() => {
13629
13676
  hoveredEdgeNodesRef.current.forEach(
13630
13677
  (el) => el.classList.remove("ec-edge-hover-node")
13631
13678
  );
13632
13679
  hoveredEdgeNodesRef.current = [];
13633
13680
  }, []);
13634
- const hoveredNodeEdgesRef = (0, import_react103.useRef)([]);
13635
- const hoveredNodePeersRef = (0, import_react103.useRef)([]);
13636
- const handleNodeMouseEnter = (0, import_react103.useCallback)(
13681
+ const hoveredNodeEdgesRef = (0, import_react104.useRef)([]);
13682
+ const hoveredNodePeersRef = (0, import_react104.useRef)([]);
13683
+ const handleNodeMouseEnter = (0, import_react104.useCallback)(
13637
13684
  (_, node) => {
13638
13685
  const wrapper = reactFlowWrapperRef.current;
13639
13686
  if (!wrapper) return;
@@ -13662,7 +13709,7 @@ var NodeGraphBuilder = ({
13662
13709
  },
13663
13710
  []
13664
13711
  );
13665
- const handleNodeMouseLeave = (0, import_react103.useCallback)(() => {
13712
+ const handleNodeMouseLeave = (0, import_react104.useCallback)(() => {
13666
13713
  hoveredNodeEdgesRef.current.forEach(
13667
13714
  (el) => el.classList.remove("ec-node-hover-edge")
13668
13715
  );
@@ -13672,30 +13719,30 @@ var NodeGraphBuilder = ({
13672
13719
  );
13673
13720
  hoveredNodePeersRef.current = [];
13674
13721
  }, []);
13675
- const hasChannels = (0, import_react103.useMemo)(
13722
+ const hasChannels = (0, import_react104.useMemo)(
13676
13723
  () => initialNodes.some((node) => node.type === "channels"),
13677
13724
  [initialNodes]
13678
13725
  );
13679
- const hasMessages = (0, import_react103.useMemo)(
13726
+ const hasMessages = (0, import_react104.useMemo)(
13680
13727
  () => initialNodes.some(isMessageNode),
13681
13728
  [initialNodes]
13682
13729
  );
13683
- const isFlowGraph = (0, import_react103.useMemo)(
13730
+ const isFlowGraph = (0, import_react104.useMemo)(
13684
13731
  () => initialEdges.some((edge) => edge.type === "flow-edge"),
13685
13732
  [initialEdges]
13686
13733
  );
13687
- const renderedSizeOf = (0, import_react103.useCallback)(
13734
+ const renderedSizeOf = (0, import_react104.useCallback)(
13688
13735
  (node) => {
13689
13736
  const measured = storeApi.getState().nodeLookup.get(node.id)?.measured;
13690
13737
  return measured?.width && measured?.height ? { width: measured.width, height: measured.height } : getNodeSize(node);
13691
13738
  },
13692
13739
  [storeApi]
13693
13740
  );
13694
- const beforeLayout = (0, import_react103.useCallback)(
13741
+ const beforeLayout = (0, import_react104.useCallback)(
13695
13742
  (graph) => swimlaneStyleRef.current === "lanes" ? removeSwimlanes(graph) : graph,
13696
13743
  []
13697
13744
  );
13698
- const afterLayout = (0, import_react103.useCallback)((graph) => {
13745
+ const afterLayout = (0, import_react104.useCallback)((graph) => {
13699
13746
  const groupBy = swimlanesRef.current;
13700
13747
  const style = swimlaneStyleRef.current;
13701
13748
  const current = getGrouping(graph.nodes);
@@ -13707,24 +13754,24 @@ var NodeGraphBuilder = ({
13707
13754
  unlanedGraphRef.current = unlaned;
13708
13755
  return layoutSwimlanes(unlaned, groupBy, { sizeOf: renderedSizeOf });
13709
13756
  }, []);
13710
- const hasLevels = (0, import_react103.useMemo)(
13757
+ const hasLevels = (0, import_react104.useMemo)(
13711
13758
  () => initialNodes.some(
13712
13759
  (node) => LEVEL_NODE_TYPES.includes(node.type || "")
13713
13760
  ),
13714
13761
  [initialNodes]
13715
13762
  );
13716
- const isContextGraph = (0, import_react103.useMemo)(
13763
+ const isContextGraph = (0, import_react104.useMemo)(
13717
13764
  () => initialNodes.every(
13718
13765
  (node) => CONTEXT_NODE_TYPES.includes(node.type || "")
13719
13766
  ),
13720
13767
  [initialNodes]
13721
13768
  );
13722
- const hasOtherDomains = (0, import_react103.useMemo)(
13769
+ const hasOtherDomains = (0, import_react104.useMemo)(
13723
13770
  () => mode === "full" && initialNodes.some((node) => !!node.data?.otherDomain),
13724
13771
  [initialNodes, mode]
13725
13772
  );
13726
- const legendRef = (0, import_react103.useRef)({});
13727
- const matchesLegendKey = (0, import_react103.useCallback)((node, key) => {
13773
+ const legendRef = (0, import_react104.useRef)({});
13774
+ const matchesLegendKey = (0, import_react104.useCallback)((node, key) => {
13728
13775
  const groupId = legendRef.current[key]?.groupId;
13729
13776
  return groupId ? node.data?.group?.id === groupId : node.type === key;
13730
13777
  }, []);
@@ -13760,7 +13807,7 @@ var NodeGraphBuilder = ({
13760
13807
  beforeLayout,
13761
13808
  afterLayout
13762
13809
  });
13763
- const switchGraph = (0, import_react103.useCallback)(
13810
+ const switchGraph = (0, import_react104.useCallback)(
13764
13811
  (showOverview) => onShowOverview?.(showOverview, {
13765
13812
  nodes: getNodes(),
13766
13813
  edges: getEdges(),
@@ -13768,7 +13815,7 @@ var NodeGraphBuilder = ({
13768
13815
  }),
13769
13816
  [onShowOverview, getNodes, getEdges, getViewport]
13770
13817
  );
13771
- const levels = (0, import_react103.useMemo)(() => {
13818
+ const levels = (0, import_react104.useMemo)(() => {
13772
13819
  if (isFlowGraph) return [];
13773
13820
  if (!overviewLabel && !isContextGraph && !hasLevels) return [];
13774
13821
  const selectDetailLevel = (level) => {
@@ -13810,7 +13857,7 @@ var NodeGraphBuilder = ({
13810
13857
  setDetailLevel,
13811
13858
  switchGraph
13812
13859
  ]);
13813
- const canvasTools = (0, import_react103.useMemo)(
13860
+ const canvasTools = (0, import_react104.useMemo)(
13814
13861
  () => hasOtherDomains ? [
13815
13862
  {
13816
13863
  label: highlightCrossDomain ? "Stop highlighting cross-domain communication" : "Highlight cross-domain communication",
@@ -13821,23 +13868,23 @@ var NodeGraphBuilder = ({
13821
13868
  ] : [],
13822
13869
  [hasOtherDomains, highlightCrossDomain, toggleHighlightCrossDomain]
13823
13870
  );
13824
- const searchRef = (0, import_react103.useRef)(null);
13825
- const reactFlowWrapperRef = (0, import_react103.useRef)(null);
13826
- const scrollableContainerRef = (0, import_react103.useRef)(null);
13827
- const nodesRef = (0, import_react103.useRef)(nodes);
13871
+ const searchRef = (0, import_react104.useRef)(null);
13872
+ const reactFlowWrapperRef = (0, import_react104.useRef)(null);
13873
+ const scrollableContainerRef = (0, import_react104.useRef)(null);
13874
+ const nodesRef = (0, import_react104.useRef)(nodes);
13828
13875
  nodesRef.current = nodes;
13829
- const edgesRef = (0, import_react103.useRef)(edges);
13876
+ const edgesRef = (0, import_react104.useRef)(edges);
13830
13877
  edgesRef.current = edges;
13831
- const subFlowLayoutRun = (0, import_react103.useRef)(0);
13832
- const hideChannelsRef = (0, import_react103.useRef)(hideChannels);
13878
+ const subFlowLayoutRun = (0, import_react104.useRef)(0);
13879
+ const hideChannelsRef = (0, import_react104.useRef)(hideChannels);
13833
13880
  hideChannelsRef.current = hideChannels;
13834
- const walkthroughKeyRef = (0, import_react103.useRef)("");
13881
+ const walkthroughKeyRef = (0, import_react104.useRef)("");
13835
13882
  const computedWalkthroughKey = `${nodes.map((n) => `${n.id}:${n.type}`).join(",")}|${edges.map((e) => `${e.source}>${e.target}`).join(",")}`;
13836
13883
  if (computedWalkthroughKey !== walkthroughKeyRef.current) {
13837
13884
  walkthroughKeyRef.current = computedWalkthroughKey;
13838
13885
  }
13839
13886
  const walkthroughKey = walkthroughKeyRef.current;
13840
- const { walkthroughNodes, walkthroughEdges } = (0, import_react103.useMemo)(() => {
13887
+ const { walkthroughNodes, walkthroughEdges } = (0, import_react104.useMemo)(() => {
13841
13888
  const wrapperNodeIds = new Set(
13842
13889
  nodes.filter((n) => isExpandedWrapper(n.type) || isSwimlaneNode(n)).map((n) => n.id)
13843
13890
  );
@@ -13848,13 +13895,13 @@ var NodeGraphBuilder = ({
13848
13895
  )
13849
13896
  };
13850
13897
  }, [walkthroughKey]);
13851
- const animateLayout2 = (0, import_react103.useCallback)(() => {
13898
+ const animateLayout2 = (0, import_react104.useCallback)(() => {
13852
13899
  const wrapper = reactFlowWrapperRef.current;
13853
13900
  if (!wrapper) return;
13854
13901
  wrapper.classList.add("ec-animating-layout");
13855
13902
  setTimeout(() => wrapper.classList.remove("ec-animating-layout"), 400);
13856
13903
  }, []);
13857
- const makeRoomForRenderedExpandedGroup = (0, import_react103.useCallback)(
13904
+ const makeRoomForRenderedExpandedGroup = (0, import_react104.useCallback)(
13858
13905
  (groupNodeId, groupBounds) => {
13859
13906
  const padding = 80;
13860
13907
  const protectedBounds = {
@@ -13883,7 +13930,7 @@ var NodeGraphBuilder = ({
13883
13930
  },
13884
13931
  [getIntersectingNodes, setNodes]
13885
13932
  );
13886
- const handleCollapseGroup = (0, import_react103.useCallback)(
13933
+ const handleCollapseGroup = (0, import_react104.useCallback)(
13887
13934
  (e) => {
13888
13935
  const target = e.target;
13889
13936
  const collapseBtn = target.closest(
@@ -13957,7 +14004,7 @@ var NodeGraphBuilder = ({
13957
14004
  },
13958
14005
  [initialNodes, initialEdges, setNodes, setEdges, animateLayout2]
13959
14006
  );
13960
- (0, import_react103.useEffect)(() => {
14007
+ (0, import_react104.useEffect)(() => {
13961
14008
  if (isDevMode && initialNodes.length > 0) {
13962
14009
  const positions = {};
13963
14010
  initialNodes.forEach((node) => {
@@ -13966,7 +14013,7 @@ var NodeGraphBuilder = ({
13966
14013
  initialPositionsRef.current = positions;
13967
14014
  }
13968
14015
  }, [isDevMode, initialNodes]);
13969
- const checkForLayoutChanges = (0, import_react103.useCallback)(() => {
14016
+ const checkForLayoutChanges = (0, import_react104.useCallback)(() => {
13970
14017
  if (!isDevMode) return;
13971
14018
  const initial = initialPositionsRef.current;
13972
14019
  if (Object.keys(initial).length === 0) return;
@@ -13976,7 +14023,7 @@ var NodeGraphBuilder = ({
13976
14023
  });
13977
14024
  setHasLayoutChanges(hasChanges);
13978
14025
  }, [isDevMode]);
13979
- const handleNodesChange = (0, import_react103.useCallback)(
14026
+ const handleNodesChange = (0, import_react104.useCallback)(
13980
14027
  (changes) => {
13981
14028
  onNodesChange(changes);
13982
14029
  const hasDragEnd = changes.some(
@@ -13988,7 +14035,7 @@ var NodeGraphBuilder = ({
13988
14035
  },
13989
14036
  [onNodesChange, checkForLayoutChanges]
13990
14037
  );
13991
- const resetNodesAndEdges = (0, import_react103.useCallback)(() => {
14038
+ const resetNodesAndEdges = (0, import_react104.useCallback)(() => {
13992
14039
  setNodes(
13993
14040
  (nds) => nds.map((node) => {
13994
14041
  node.style = { ...node.style, opacity: 1 };
@@ -14012,7 +14059,7 @@ var NodeGraphBuilder = ({
14012
14059
  })
14013
14060
  );
14014
14061
  }, [setNodes, setEdges, animateMessages]);
14015
- (0, import_react103.useEffect)(() => {
14062
+ (0, import_react104.useEffect)(() => {
14016
14063
  if (!focusNodeId) return;
14017
14064
  const targetNode = nodesRef.current.find((node) => node.id === focusNodeId);
14018
14065
  if (!targetNode) return;
@@ -14030,13 +14077,13 @@ var NodeGraphBuilder = ({
14030
14077
  });
14031
14078
  });
14032
14079
  }, [focusNodeId, focusRequestId, fitView, setNodes]);
14033
- (0, import_react103.useEffect)(() => {
14080
+ (0, import_react104.useEffect)(() => {
14034
14081
  if (fitRequestId == null) return;
14035
14082
  requestAnimationFrame(() => {
14036
14083
  fitView({ duration: 400, padding: 0.2 });
14037
14084
  });
14038
14085
  }, [fitRequestId, fitView]);
14039
- const handleNodeClick = (0, import_react103.useCallback)(
14086
+ const handleNodeClick = (0, import_react104.useCallback)(
14040
14087
  (_, node) => {
14041
14088
  if (onNodeClick) {
14042
14089
  onNodeClick(node);
@@ -14381,7 +14428,7 @@ var NodeGraphBuilder = ({
14381
14428
  setCenter
14382
14429
  ]
14383
14430
  );
14384
- const toggleAnimateMessages = (0, import_react103.useCallback)(() => {
14431
+ const toggleAnimateMessages = (0, import_react104.useCallback)(() => {
14385
14432
  setAnimateMessages((prev) => {
14386
14433
  const next = !prev;
14387
14434
  localStorage.setItem(
@@ -14391,10 +14438,10 @@ var NodeGraphBuilder = ({
14391
14438
  return next;
14392
14439
  });
14393
14440
  }, []);
14394
- const handleFitView = (0, import_react103.useCallback)(() => {
14441
+ const handleFitView = (0, import_react104.useCallback)(() => {
14395
14442
  fitView({ maxZoom: 1, duration: 400, padding: 0.2 });
14396
14443
  }, [fitView]);
14397
- (0, import_react103.useEffect)(() => {
14444
+ (0, import_react104.useEffect)(() => {
14398
14445
  if (disableMessageAnimation) {
14399
14446
  setAnimateMessages(false);
14400
14447
  return;
@@ -14420,16 +14467,16 @@ var NodeGraphBuilder = ({
14420
14467
  }
14421
14468
  }
14422
14469
  }, [animated, disableMessageAnimation, initialNodes.length]);
14423
- (0, import_react103.useEffect)(() => {
14470
+ (0, import_react104.useEffect)(() => {
14424
14471
  setEdges((eds) => applyMessageAnimation(eds, animateMessages));
14425
14472
  }, [animateMessages]);
14426
- (0, import_react103.useEffect)(() => {
14473
+ (0, import_react104.useEffect)(() => {
14427
14474
  if (transitionFrom) return;
14428
14475
  setTimeout(() => {
14429
14476
  fitView({ maxZoom: 1, duration: 800 });
14430
14477
  }, 150);
14431
14478
  }, []);
14432
- const generateMermaidCode = (0, import_react103.useCallback)(() => {
14479
+ const generateMermaidCode = (0, import_react104.useCallback)(() => {
14433
14480
  try {
14434
14481
  return convertToMermaid(nodesRef.current, edgesRef.current, {
14435
14482
  includeStyles: true,
@@ -14440,7 +14487,7 @@ var NodeGraphBuilder = ({
14440
14487
  return "";
14441
14488
  }
14442
14489
  }, []);
14443
- (0, import_react103.useEffect)(() => {
14490
+ (0, import_react104.useEffect)(() => {
14444
14491
  if (zoomOnScroll) return;
14445
14492
  const findScrollableContainer = () => {
14446
14493
  const selectors = [
@@ -14485,31 +14532,31 @@ var NodeGraphBuilder = ({
14485
14532
  };
14486
14533
  }
14487
14534
  }, [zoomOnScroll]);
14488
- const handlePaneClick = (0, import_react103.useCallback)(() => {
14535
+ const handlePaneClick = (0, import_react104.useCallback)(() => {
14489
14536
  searchRef.current?.hideSuggestions();
14490
14537
  resetNodesAndEdges();
14491
14538
  fitView({ maxZoom: 1, duration: 800 });
14492
14539
  }, [resetNodesAndEdges, fitView]);
14493
- const handleNodeSelect = (0, import_react103.useCallback)(
14540
+ const handleNodeSelect = (0, import_react104.useCallback)(
14494
14541
  (node) => {
14495
14542
  handleNodeClick(null, node);
14496
14543
  },
14497
14544
  [handleNodeClick]
14498
14545
  );
14499
- const handleSearchClear = (0, import_react103.useCallback)(() => {
14546
+ const handleSearchClear = (0, import_react104.useCallback)(() => {
14500
14547
  resetNodesAndEdges();
14501
14548
  fitView({ maxZoom: 1, duration: 800 });
14502
14549
  }, [resetNodesAndEdges, fitView]);
14503
- const downloadImage = (0, import_react103.useCallback)((dataUrl, filename) => {
14550
+ const downloadImage = (0, import_react104.useCallback)((dataUrl, filename) => {
14504
14551
  const a = document.createElement("a");
14505
14552
  a.setAttribute("download", `${filename || "eventcatalog"}.png`);
14506
14553
  a.setAttribute("href", dataUrl);
14507
14554
  a.click();
14508
14555
  }, []);
14509
- const openChat = (0, import_react103.useCallback)(() => {
14556
+ const openChat = (0, import_react104.useCallback)(() => {
14510
14557
  window.dispatchEvent(new CustomEvent("eventcatalog:open-chat"));
14511
14558
  }, []);
14512
- const handleSaveLayout = (0, import_react103.useCallback)(async () => {
14559
+ const handleSaveLayout = (0, import_react104.useCallback)(async () => {
14513
14560
  if (!resourceKey || !onSaveLayout) return false;
14514
14561
  if (swimlanesRef.current) return false;
14515
14562
  const positions = {};
@@ -14522,11 +14569,11 @@ var NodeGraphBuilder = ({
14522
14569
  });
14523
14570
  return await onSaveLayout(resourceKey, positions);
14524
14571
  }, [resourceKey, onSaveLayout]);
14525
- const handleResetLayout = (0, import_react103.useCallback)(async () => {
14572
+ const handleResetLayout = (0, import_react104.useCallback)(async () => {
14526
14573
  if (!resourceKey || !onResetLayout) return false;
14527
14574
  return await onResetLayout(resourceKey);
14528
14575
  }, [resourceKey, onResetLayout]);
14529
- const handleQuickSaveLayout = (0, import_react103.useCallback)(async () => {
14576
+ const handleQuickSaveLayout = (0, import_react104.useCallback)(async () => {
14530
14577
  setIsSavingLayout(true);
14531
14578
  const success = await handleSaveLayout();
14532
14579
  setIsSavingLayout(false);
@@ -14539,17 +14586,17 @@ var NodeGraphBuilder = ({
14539
14586
  setHasLayoutChanges(false);
14540
14587
  }
14541
14588
  }, [handleSaveLayout]);
14542
- const handleCopyArchitectureCode = (0, import_react103.useCallback)(async () => {
14589
+ const handleCopyArchitectureCode = (0, import_react104.useCallback)(async () => {
14543
14590
  const code = generateMermaidCode();
14544
14591
  await copyToClipboard(code);
14545
14592
  }, [generateMermaidCode]);
14546
- const handleCopyShareUrl = (0, import_react103.useCallback)(async () => {
14593
+ const handleCopyShareUrl = (0, import_react104.useCallback)(async () => {
14547
14594
  const url = typeof window !== "undefined" ? window.location.href : "";
14548
14595
  await copyToClipboard(url);
14549
14596
  setShareUrlCopySuccess(true);
14550
14597
  setTimeout(() => setShareUrlCopySuccess(false), 2e3);
14551
14598
  }, []);
14552
- const toggleFullScreen = (0, import_react103.useCallback)(() => {
14599
+ const toggleFullScreen = (0, import_react104.useCallback)(() => {
14553
14600
  if (!document.fullscreenElement) {
14554
14601
  reactFlowWrapperRef.current?.requestFullscreen().catch((err) => {
14555
14602
  console.error(
@@ -14560,7 +14607,7 @@ var NodeGraphBuilder = ({
14560
14607
  document.exitFullscreen();
14561
14608
  }
14562
14609
  }, []);
14563
- (0, import_react103.useEffect)(() => {
14610
+ (0, import_react104.useEffect)(() => {
14564
14611
  const handleFullscreenChange = () => {
14565
14612
  _setIsFullscreen(!!document.fullscreenElement);
14566
14613
  setTimeout(() => {
@@ -14572,8 +14619,8 @@ var NodeGraphBuilder = ({
14572
14619
  document.removeEventListener("fullscreenchange", handleFullscreenChange);
14573
14620
  };
14574
14621
  }, [fitView]);
14575
- const handleExportVisual = (0, import_react103.useCallback)(() => {
14576
- const nodesBounds = (0, import_react104.getNodesBounds)(getNodes(), {
14622
+ const handleExportVisual = (0, import_react104.useCallback)(() => {
14623
+ const nodesBounds = (0, import_react105.getNodesBounds)(getNodes(), {
14577
14624
  nodeLookup: storeApi.getState().nodeLookup
14578
14625
  });
14579
14626
  const { width, height, viewport } = getExportImageDimensions(nodesBounds);
@@ -14601,7 +14648,7 @@ var NodeGraphBuilder = ({
14601
14648
  if (controls) controls.style.display = "block";
14602
14649
  });
14603
14650
  }, [getNodes, storeApi, downloadImage, title]);
14604
- const getNodesByCollectionWithColors = (0, import_react103.useCallback)((nodes2) => {
14651
+ const getNodesByCollectionWithColors = (0, import_react104.useCallback)((nodes2) => {
14605
14652
  const colorClasses = {
14606
14653
  events: "bg-orange-600",
14607
14654
  agent: "bg-sky-600",
@@ -14662,18 +14709,18 @@ var NodeGraphBuilder = ({
14662
14709
  );
14663
14710
  return { ...legendForDomains, ...legendForNodes };
14664
14711
  }, []);
14665
- const legendKeyRef = (0, import_react103.useRef)("");
14712
+ const legendKeyRef = (0, import_react104.useRef)("");
14666
14713
  const computedLegendKey = nodes.map((n) => `${n.id}:${n.type}:${n.data.group?.id || ""}`).join(",");
14667
14714
  if (computedLegendKey !== legendKeyRef.current) {
14668
14715
  legendKeyRef.current = computedLegendKey;
14669
14716
  }
14670
14717
  const legendKey = legendKeyRef.current;
14671
- const graphLegend = (0, import_react103.useMemo)(
14718
+ const graphLegend = (0, import_react104.useMemo)(
14672
14719
  () => getNodesByCollectionWithColors(nodes),
14673
14720
  [getNodesByCollectionWithColors, legendKey]
14674
14721
  );
14675
- const legendEntries = (0, import_react103.useRef)(null);
14676
- const legend = (0, import_react103.useMemo)(() => {
14722
+ const legendEntries = (0, import_react104.useRef)(null);
14723
+ const legend = (0, import_react104.useMemo)(() => {
14677
14724
  legendEntries.current ?? (legendEntries.current = getNodesByCollectionWithColors(initialNodes));
14678
14725
  Object.assign(legendEntries.current, graphLegend);
14679
14726
  return Object.fromEntries(
@@ -14683,17 +14730,17 @@ var NodeGraphBuilder = ({
14683
14730
  );
14684
14731
  }, [graphLegend, hiddenLegendKeys]);
14685
14732
  legendRef.current = legend;
14686
- const nodeIdsKeyRef = (0, import_react103.useRef)("");
14733
+ const nodeIdsKeyRef = (0, import_react104.useRef)("");
14687
14734
  const computedNodeIdsKey = nodes.map((n) => n.id).join(",");
14688
14735
  if (computedNodeIdsKey !== nodeIdsKeyRef.current) {
14689
14736
  nodeIdsKeyRef.current = computedNodeIdsKey;
14690
14737
  }
14691
14738
  const nodeIdsKey = nodeIdsKeyRef.current;
14692
- const searchNodes = (0, import_react103.useMemo)(
14739
+ const searchNodes = (0, import_react104.useMemo)(
14693
14740
  () => nodes.filter((node) => !isSwimlaneNode(node)),
14694
14741
  [nodeIdsKey]
14695
14742
  );
14696
- const allNoteGroups = (0, import_react103.useMemo)(() => {
14743
+ const allNoteGroups = (0, import_react104.useMemo)(() => {
14697
14744
  const groups = [];
14698
14745
  for (const node of nodes) {
14699
14746
  const result = getNotesFromNode(node);
@@ -14708,13 +14755,13 @@ var NodeGraphBuilder = ({
14708
14755
  }
14709
14756
  return groups;
14710
14757
  }, [nodeIdsKey]);
14711
- const totalNotesCount = (0, import_react103.useMemo)(
14758
+ const totalNotesCount = (0, import_react104.useMemo)(
14712
14759
  () => allNoteGroups.reduce((sum, g) => sum + g.notes.length, 0),
14713
14760
  [allNoteGroups]
14714
14761
  );
14715
- const [walkthroughTrail, setWalkthroughTrail] = (0, import_react103.useState)([]);
14716
- const walkthroughTrailRef = (0, import_react103.useRef)([]);
14717
- const handleStepChange = (0, import_react103.useCallback)(
14762
+ const [walkthroughTrail, setWalkthroughTrail] = (0, import_react104.useState)([]);
14763
+ const walkthroughTrailRef = (0, import_react104.useRef)([]);
14764
+ const handleStepChange = (0, import_react104.useCallback)(
14718
14765
  (nodeId, shouldZoomOut, trail = nodeId ? [nodeId] : []) => {
14719
14766
  if (nodeId === null) {
14720
14767
  resetNodesAndEdges();
@@ -14772,12 +14819,12 @@ var NodeGraphBuilder = ({
14772
14819
  walkthroughTrailRef.current = trail;
14773
14820
  const canvas = reactFlowWrapperRef.current?.getBoundingClientRect();
14774
14821
  if (!canvas) return;
14775
- const bounds = (0, import_react104.getNodesBounds)([nodeId, ...nextNodeIds], {
14822
+ const bounds = (0, import_react105.getNodesBounds)([nodeId, ...nextNodeIds], {
14776
14823
  nodeLookup: storeApi.getState().nodeLookup
14777
14824
  });
14778
14825
  const cardSpace = Math.min(WALKTHROUGH_CARD_SPACE, canvas.height * 0.35);
14779
14826
  setViewport(
14780
- (0, import_react104.getViewportForBounds)(
14827
+ (0, import_react105.getViewportForBounds)(
14781
14828
  bounds,
14782
14829
  canvas.width,
14783
14830
  canvas.height - cardSpace,
@@ -14790,13 +14837,13 @@ var NodeGraphBuilder = ({
14790
14837
  },
14791
14838
  [setNodes, setEdges, resetNodesAndEdges, setViewport, storeApi]
14792
14839
  );
14793
- const swimlaneOptions = (0, import_react103.useMemo)(
14840
+ const swimlaneOptions = (0, import_react104.useMemo)(
14794
14841
  () => isFlowGraph ? FLOW_GROUP_BYS.filter(
14795
14842
  (groupBy) => hasSwimlanes(initialNodes, groupBy)
14796
14843
  ) : [],
14797
14844
  [isFlowGraph, initialNodes]
14798
14845
  );
14799
- const swimlaneCounts = (0, import_react103.useMemo)(
14846
+ const swimlaneCounts = (0, import_react104.useMemo)(
14800
14847
  () => Object.fromEntries(
14801
14848
  swimlaneOptions.map((groupBy) => [
14802
14849
  groupBy,
@@ -14805,9 +14852,9 @@ var NodeGraphBuilder = ({
14805
14852
  ),
14806
14853
  [swimlaneOptions, initialNodes]
14807
14854
  );
14808
- const [groupingShown, setGroupingShown] = (0, import_react103.useState)(0);
14809
- const groupingRun = (0, import_react103.useRef)(0);
14810
- const handleSwimlanesChange = (0, import_react103.useCallback)(
14855
+ const [groupingShown, setGroupingShown] = (0, import_react104.useState)(0);
14856
+ const groupingRun = (0, import_react104.useRef)(0);
14857
+ const handleSwimlanesChange = (0, import_react104.useCallback)(
14811
14858
  (requested, style = swimlaneStyleRef.current) => {
14812
14859
  const groupBy = style === "lanes" && requested === "domain-system" ? "domain" : requested;
14813
14860
  if (groupBy === swimlanesRef.current && style === swimlaneStyleRef.current)
@@ -14838,7 +14885,7 @@ var NodeGraphBuilder = ({
14838
14885
  },
14839
14886
  [animateLayout2, setNodes, setEdges, renderedSizeOf]
14840
14887
  );
14841
- (0, import_react103.useEffect)(() => {
14888
+ (0, import_react104.useEffect)(() => {
14842
14889
  if (groupingShown === 0) return;
14843
14890
  const trail = walkthroughTrailRef.current;
14844
14891
  if (trail.length > 0) {
@@ -14848,9 +14895,9 @@ var NodeGraphBuilder = ({
14848
14895
  fitView({ duration: 400, padding: 0.1 });
14849
14896
  }
14850
14897
  }, [groupingShown]);
14851
- const nodesInitialized = (0, import_react104.useNodesInitialized)();
14852
- const groupedOnLoad = (0, import_react103.useRef)(false);
14853
- (0, import_react103.useEffect)(() => {
14898
+ const nodesInitialized = (0, import_react105.useNodesInitialized)();
14899
+ const groupedOnLoad = (0, import_react104.useRef)(false);
14900
+ (0, import_react104.useEffect)(() => {
14854
14901
  if (!nodesInitialized || groupedOnLoad.current) return;
14855
14902
  groupedOnLoad.current = true;
14856
14903
  const fromUrl = readGroupFromUrl();
@@ -14951,7 +14998,7 @@ var NodeGraphBuilder = ({
14951
14998
  }
14952
14999
  ) })
14953
15000
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
14954
- import_react104.ReactFlow,
15001
+ import_react105.ReactFlow,
14955
15002
  {
14956
15003
  nodeTypes,
14957
15004
  proOptions: hideAttribution ? HIDE_ATTRIBUTION : void 0,
@@ -14966,7 +15013,7 @@ var NodeGraphBuilder = ({
14966
15013
  onEdgesChange,
14967
15014
  onEdgeMouseEnter: handleEdgeMouseEnter,
14968
15015
  onEdgeMouseLeave: handleEdgeMouseLeave,
14969
- connectionLineType: import_react104.ConnectionLineType.SmoothStep,
15016
+ connectionLineType: import_react105.ConnectionLineType.SmoothStep,
14970
15017
  nodeOrigin: NODE_ORIGIN,
14971
15018
  elevateNodesOnSelect: false,
14972
15019
  onNodeClick: handleNodeClick,
@@ -14981,7 +15028,7 @@ var NodeGraphBuilder = ({
14981
15028
  className: `relative${isLayingOut ? " ec-laying-out" : ""}${hasOtherDomains && highlightCrossDomain ? " ec-highlight-cross-domain" : ""}`,
14982
15029
  children: [
14983
15030
  /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
14984
- import_react104.Panel,
15031
+ import_react105.Panel,
14985
15032
  {
14986
15033
  position: "top-center",
14987
15034
  className: "w-full pr-6 pointer-events-none",
@@ -15101,8 +15148,8 @@ var NodeGraphBuilder = ({
15101
15148
  ]
15102
15149
  }
15103
15150
  ),
15104
- includeBackground && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react104.Background, { color: "var(--ec-bg-dots)", gap: 16 }),
15105
- includeBackground && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react104.Controls, {}),
15151
+ includeBackground && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react105.Background, { color: "var(--ec-bg-dots)", gap: 16 }),
15152
+ includeBackground && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react105.Controls, {}),
15106
15153
  mode === "full" && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15107
15154
  CanvasToolbar_default,
15108
15155
  {
@@ -15117,7 +15164,7 @@ var NodeGraphBuilder = ({
15117
15164
  }
15118
15165
  ),
15119
15166
  showMinimap && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15120
- import_react104.MiniMap,
15167
+ import_react105.MiniMap,
15121
15168
  {
15122
15169
  nodeStrokeWidth: 3,
15123
15170
  zoomable: true,
@@ -15126,7 +15173,7 @@ var NodeGraphBuilder = ({
15126
15173
  }
15127
15174
  ),
15128
15175
  swimlaneOptions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15129
- import_react104.Panel,
15176
+ import_react105.Panel,
15130
15177
  {
15131
15178
  position: "top-right",
15132
15179
  style: mode === "full" && showSearch ? SWIMLANE_PICKER_PANEL_STYLE_UNDER_SEARCH : void 0,
@@ -15143,7 +15190,7 @@ var NodeGraphBuilder = ({
15143
15190
  }
15144
15191
  ),
15145
15192
  isFlowGraph && showFlowWalkthrough && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(WalkthroughBadges_default, { trail: walkthroughTrail }),
15146
- isFlowGraph && showFlowWalkthrough && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react104.Panel, { position: "bottom-left", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15193
+ isFlowGraph && showFlowWalkthrough && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react105.Panel, { position: "bottom-left", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15147
15194
  StepWalkthrough_default,
15148
15195
  {
15149
15196
  nodes: walkthroughNodes,
@@ -15154,7 +15201,7 @@ var NodeGraphBuilder = ({
15154
15201
  }
15155
15202
  ) }),
15156
15203
  isDevMode && hasLayoutChanges && !swimlanes && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15157
- import_react104.Panel,
15204
+ import_react105.Panel,
15158
15205
  {
15159
15206
  position: "bottom-left",
15160
15207
  style: isFlowGraph && showFlowWalkthrough ? LAYOUT_CHANGE_PANEL_STYLE_WITH_WALKTHROUGH : LAYOUT_CHANGE_PANEL_STYLE_DEFAULT,
@@ -15317,8 +15364,8 @@ var NodeGraph = ({
15317
15364
  onSaveLayout,
15318
15365
  onResetLayout
15319
15366
  }) => {
15320
- const [graphLayout, setGraphLayout] = (0, import_react103.useState)(null);
15321
- (0, import_react103.useEffect)(() => {
15367
+ const [graphLayout, setGraphLayout] = (0, import_react104.useState)(null);
15368
+ (0, import_react104.useEffect)(() => {
15322
15369
  if (!graph) return setGraphLayout(null);
15323
15370
  let current = true;
15324
15371
  layoutGraph(graph.nodes, graph.edges, {
@@ -15336,16 +15383,16 @@ var NodeGraph = ({
15336
15383
  const includeKey = includeKeyProp !== void 0 ? includeKeyProp : graph?.options?.legend !== false;
15337
15384
  const showSearch = showSearchProp !== void 0 ? showSearchProp : graph?.options?.search !== false;
15338
15385
  const animated = animatedProp ?? graph?.options?.animated;
15339
- const [elem, setElem] = (0, import_react103.useState)(null);
15340
- const [showFooter, setShowFooter] = (0, import_react103.useState)(true);
15386
+ const [elem, setElem] = (0, import_react104.useState)(null);
15387
+ const [showFooter, setShowFooter] = (0, import_react104.useState)(true);
15341
15388
  const containerToRenderInto = portalId || `${id}-portal`;
15342
- const [showOverview, setShowOverview] = (0, import_react103.useState)(() => {
15389
+ const [showOverview, setShowOverview] = (0, import_react104.useState)(() => {
15343
15390
  if (!overviewGraph) return false;
15344
15391
  const level = new URLSearchParams(window.location.search).get("level");
15345
15392
  return level === null || level === "1";
15346
15393
  });
15347
- const [transitionFrom, setTransitionFrom] = (0, import_react103.useState)();
15348
- const handleShowOverview = (0, import_react103.useCallback)(
15394
+ const [transitionFrom, setTransitionFrom] = (0, import_react104.useState)();
15395
+ const handleShowOverview = (0, import_react104.useCallback)(
15349
15396
  (show, from) => {
15350
15397
  setTransitionFrom(from);
15351
15398
  setShowOverview(show);
@@ -15354,14 +15401,14 @@ var NodeGraph = ({
15354
15401
  []
15355
15402
  );
15356
15403
  const overview = showOverview ? overviewGraph : void 0;
15357
- const hiddenLegendKeys = (0, import_react103.useRef)([]);
15358
- const handleHiddenLegendKeysChange = (0, import_react103.useCallback)((keys) => {
15404
+ const hiddenLegendKeys = (0, import_react104.useRef)([]);
15405
+ const handleHiddenLegendKeysChange = (0, import_react104.useCallback)((keys) => {
15359
15406
  hiddenLegendKeys.current = keys;
15360
15407
  }, []);
15361
- (0, import_react103.useEffect)(() => {
15408
+ (0, import_react104.useEffect)(() => {
15362
15409
  setElem(document.getElementById(containerToRenderInto));
15363
15410
  }, []);
15364
- (0, import_react103.useEffect)(() => {
15411
+ (0, import_react104.useEffect)(() => {
15365
15412
  const urlParams = new URLSearchParams(window.location.search);
15366
15413
  const embed = urlParams.get("embed");
15367
15414
  if (embed === "true") {
@@ -15371,7 +15418,7 @@ var NodeGraph = ({
15371
15418
  if (!elem || graph && !graphLayout) return null;
15372
15419
  return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { children: (0, import_react_dom.createPortal)(
15373
15420
  // Remount when switching graphs so each starts from a clean state
15374
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react104.ReactFlowProvider, { children: [
15421
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react105.ReactFlowProvider, { children: [
15375
15422
  /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15376
15423
  NodeGraphBuilder,
15377
15424
  {
@@ -15568,6 +15615,7 @@ var exportNodeGraphForStudio = (data) => {
15568
15615
  DATA,
15569
15616
  Data,
15570
15617
  DataProductNode,
15618
+ DomainCardNode,
15571
15619
  DomainNode,
15572
15620
  ENTITY_TARGET_HANDLE_ID,
15573
15621
  EVENT,