@eventcatalog/visualiser 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/studio.mjs CHANGED
@@ -10,17 +10,19 @@ import {
10
10
  ToolbarButton,
11
11
  ToolbarDivider,
12
12
  ZoomLevel,
13
+ addExportBranding,
13
14
  diagramNodeComponents,
15
+ eventcatalog_logo_default,
14
16
  getExportImageDimensions,
15
17
  injectExportStyles,
16
18
  memoNode
17
- } from "./chunk-6OORHWMU.mjs";
18
- import "./chunk-Q3OM5AL5.mjs";
19
+ } from "./chunk-ZHXUMAPK.mjs";
20
+ import "./chunk-STJQWGKW.mjs";
19
21
  import {
20
22
  getMessagesLabel,
21
23
  getNodeSize,
22
24
  layoutWithElk
23
- } from "./chunk-Z3G354GF.mjs";
25
+ } from "./chunk-P2DH6CFV.mjs";
24
26
  import {
25
27
  LEVELS,
26
28
  MESSAGE_TYPES,
@@ -44,7 +46,18 @@ var EDGE_MARKER = {
44
46
  width: 18,
45
47
  height: 18
46
48
  };
47
- var PRODUCERS = ["service", "agent", "actor", "externalSystem", "view"];
49
+ var PRODUCERS = [
50
+ "service",
51
+ "agent",
52
+ "actor",
53
+ "externalSystem",
54
+ "view",
55
+ // Domains send messages themselves too (`sends` in a domain's frontmatter), as a box or a card. Studio on the
56
+ // web's model only has services sending and receiving (model-canvas.ts), so these edges are labelled but not
57
+ // kept as relations there
58
+ "domain-group",
59
+ "context-domain"
60
+ ];
48
61
  var PRODUCER_LABELS = {
49
62
  commands: "invokes",
50
63
  events: "publishes \nevent",
@@ -986,10 +999,17 @@ var addCanvasContent = (doc, { nodes, connections, levels }) => doc.transact(()
986
999
  const edge = connectNodes(doc, { source: from, target: to }, label);
987
1000
  const [source, target] = [placed.get(from), placed.get(to)];
988
1001
  if (!route || "error" in edge || !source || !target) return;
1002
+ const { sourceHeight, targetHeight, ...drawn } = route;
989
1003
  routes.set(edge.id, {
990
- ...route,
991
- source: getAbsolutePosition(source, placed),
992
- target: getAbsolutePosition(target, placed)
1004
+ ...drawn,
1005
+ source: {
1006
+ ...getAbsolutePosition(source, placed),
1007
+ ...sourceHeight && { height: sourceHeight }
1008
+ },
1009
+ target: {
1010
+ ...getAbsolutePosition(target, placed),
1011
+ ...targetHeight && { height: targetHeight }
1012
+ }
993
1013
  });
994
1014
  });
995
1015
  if (routes.size) setEdgeRoutes(doc, routes);
@@ -2829,11 +2849,6 @@ function pickDiagramFile() {
2829
2849
 
2830
2850
  // src/studio/export-image.ts
2831
2851
  import { toPng } from "html-to-image";
2832
-
2833
- // src/studio/eventcatalog-logo.svg?raw
2834
- var eventcatalog_logo_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="58 54 1133 1133" aria-hidden="true" fill="currentColor">\n<path fill-rule="evenodd" d="M 445 55 c -174.6 0.5 -188.1 0.7 -196.5 2.3 -20.7 4.1 -35.3 8.5 -51 15.3 -66.7 28.8 -114.7 86.9 -130.3 157.9 l -2.6 12 -0.4 371 c -0.2 261 0 373.8 0.8 380.5 4.6 40.7 21.8 79.6 49.8 113 36.8 43.9 89.5 72.4 144.2 77.9 5.9 0.6 148.2 1.1 372.5 1.3 345.2 0.3 363.5 0.2 373 -1.5 32.1 -5.7 58.7 -16.4 85.5 -34.2 53.2 -35.3 89.1 -93.6 96 -156 0.8 -7.2 1 -114.8 0.8 -381.5 l -0.3 -371.5 -2.2 -10.4 c -7.7 -35.9 -18.8 -61.1 -38.9 -88.2 -9.5 -12.8 -30.7 -34.1 -43.4 -43.5 -34.4 -25.6 -73.7 -40.9 -113.5 -44.3 -12.5 -1.1 -182.7 -1.1 -543.5 -0.1 z m -26.3 152.5 c 30.7 11.6 86.7 67 122.9 121.6 l 8.4 12.6 9.7 -2.3 c 13.3 -3.3 30.3 -6.1 44.8 -7.5 15.1 -1.5 51.8 -0.6 67.5 1.6 10.1 1.4 37.1 6.8 40.5 8.1 0.7 0.3 3.6 -3.4 7.1 -8.8 18.3 -29.1 37.9 -53.5 64.7 -80.7 31.8 -32.2 53.3 -47 68.5 -47.1 10.5 -0 16.2 4.1 22.3 16.1 11.6 23 17.3 80.8 15 153.1 l -1 33.7 6 14.7 c 3.2 8 7.8 20.4 10 27.5 2.3 7.1 4.5 12.9 4.9 12.9 0.4 -0 5 -1.5 10.1 -3.4 29.8 -10.8 61.4 -20.5 89.6 -27.5 20 -5.1 21.5 -5.1 25.9 -0.7 2.9 2.9 3.4 4.1 3.4 7.9 0 3.4 -0.6 5.3 -2.5 7.5 -2.9 3.5 -4.7 4.3 -18 7.7 -23.9 6.3 -83.7 25.2 -103 32.5 -2 0.8 -2 1.2 -1 10.6 0.5 5.3 1.5 9.9 2 10 0.6 0.2 16.8 2.4 36 4.9 69.6 9.1 85.9 11.5 89.4 13.3 10.1 5.1 7.6 20.4 -3.6 21.9 -3.7 0.5 -26.4 -2.1 -63.3 -7.2 -18.4 -2.6 -56.7 -7.5 -58 -7.5 -0.4 -0 -1 0.8 -1.2 1.8 -0.4 1.4 -2.9 2.3 -11.4 4.1 -50.2 10.3 -130.1 33.1 -167.9 47.8 -35.1 13.6 -69.4 33.4 -96.1 55.6 -6.6 5.4 -10.1 7.7 -10.9 7.1 -0.7 -0.5 -5.8 -4.6 -11.5 -9.2 -25 -20.2 -55.1 -37.5 -88.5 -50.7 -39.3 -15.6 -111.9 -36.5 -170.7 -49.1 -15.1 -3.2 -17.8 -4.1 -17.8 -5.6 0 -2.4 0.4 -2.4 -35 2.2 -16.8 2.2 -42.6 5.7 -57.5 7.6 -14.8 2 -28.8 3.3 -31 3 -5.9 -0.7 -9.5 -5.1 -9.5 -11.5 0 -5.7 2.4 -9.4 7.3 -11 3.2 -1.1 62.2 -9.4 103.2 -14.6 11.6 -1.5 21.3 -3 21.7 -3.3 0.3 -0.4 0.9 -5 1.3 -10.3 l 0.7 -9.6 -30.3 -10.1 c -24.9 -8.3 -73.2 -22.8 -85.2 -25.6 -1.5 -0.4 -4.1 -1.9 -5.8 -3.4 -2.6 -2.3 -3.3 -3.8 -3.7 -8 -0.4 -4.7 -0.2 -5.4 2.5 -8.1 1.7 -1.6 4.3 -3.3 5.8 -3.7 5.8 -1.4 46 9.3 88.5 23.7 16.2 5.5 30.3 10.3 31.2 10.6 1 0.3 2 -0.1 2.2 -0.8 4.6 -14.9 9 -27.2 14 -39.4 l 6.2 -15 -1 -32.5 c -1.5 -48.5 0.9 -93.8 6.4 -122.4 5 -25.8 12 -40.4 21.9 -45.6 5.4 -2.9 15.3 -2.6 23.8 0.5 z m -67.6 364.4 c 81.9 16.7 161.5 40.4 199.3 59.3 11.7 5.9 29.8 16.7 34.1 20.3 l 3 2.6 -9.5 -0.4 c -8.7 -0.4 -15.5 -2.1 -78.5 -19.7 -37.9 -10.6 -76 -21.2 -84.5 -23.5 -56.6 -15.7 -123.4 -34.6 -123.8 -35 -0.6 -0.6 13.5 -2.8 37.3 -5.8 6.4 -0.8 8.6 -0.6 22.6 2.2 z m 589.5 -0.4 c 10.4 1.4 20.4 2.8 22.3 3.2 3.4 0.6 -40.5 13.5 -170.9 50.2 -20.1 5.7 -42.6 12 -50 14.1 -50.1 14.2 -53.5 15 -60.8 15 -4 -0 -7.2 -0.3 -7.2 -0.8 0 -2.1 28.9 -19.2 45.8 -27.1 36.1 -16.7 110.6 -38.3 193.2 -55.9 6.6 -1.4 7.1 -1.4 27.6 1.3 z m -672.2 33.1 c 13.2 3.6 31.1 8.5 39.6 10.9 8.5 2.4 35.3 9.8 59.5 16.4 52.5 14.3 120.5 33 167.5 46.1 22.9 6.3 23.5 6.6 24.9 9.6 0.8 1.8 1.1 45.6 1.1 162.2 0 175.7 0.4 164.2 -5.9 164.2 -1.5 -0 -12.4 -2.7 -24.2 -6.1 -20.6 -5.8 -66.3 -18.6 -188.9 -52.7 -31.6 -8.8 -63.1 -17.5 -70 -19.2 -13 -3.3 -16.3 -4.8 -17.9 -7.8 -1.1 -2.1 -7.2 -104.7 -15.6 -262.7 -1.3 -25.9 -2.7 -50.5 -3.1 -54.7 -0.6 -7.3 -0.5 -7.8 2 -10.2 1.4 -1.5 3.5 -2.6 4.7 -2.6 1.2 -0 13 3 26.3 6.6 z m 748.1 -5.6 c 3.9 1.5 4.4 4.2 3.4 19.5 -0.8 12.4 -4.2 70.9 -15 256 -2.6 46 -3.3 53.3 -4.8 55.5 -1.9 2.6 1.3 1.6 -78.6 23.9 -9.9 2.8 -34.2 9.6 -54 15.1 -19.8 5.6 -50.4 14.1 -68 19 -17.6 4.9 -45.7 12.8 -62.5 17.5 -16.7 4.7 -31.7 8.5 -33.2 8.5 -6.3 -0 -5.9 11.3 -5.6 -165.1 0.2 -88.2 0.7 -161.2 1.2 -162.1 0.9 -1.9 4.6 -3.1 32.6 -10.7 10.2 -2.8 25.9 -7.1 35 -9.6 9.1 -2.5 32 -8.9 51 -14.1 47.4 -13.1 124.2 -34.5 168.5 -46.9 14.3 -4 26.3 -7.4 26.7 -7.4 0.4 -0.1 1.8 0.3 3.3 0.9 z m -351.7 95.3 c 0.9 0.7 1.2 35.1 1.2 166.7 l 0 165.9 -2.2 1.3 c -1.8 1 -10.2 1.3 -35.1 1.3 -31.4 -0 -32.9 -0.1 -34.3 -1.9 -2.1 -2.9 -2.1 -330.7 0 -332.8 1.1 -1.2 7.6 -1.4 35.2 -1.4 18.7 0.1 34.5 0.5 35.2 0.9 z"/>\n</svg>\n';
2835
-
2836
- // src/studio/export-image.ts
2837
2852
  var PIXEL_RATIO = 2;
2838
2853
  var translateOf = (element) => {
2839
2854
  const matrix = new DOMMatrix(getComputedStyle(element).transform);
@@ -2863,76 +2878,6 @@ function drawnBounds(viewport) {
2863
2878
  height: Math.max(...rects.map((r) => r.y + r.height)) - top
2864
2879
  };
2865
2880
  }
2866
- var loadImage = (src) => new Promise((resolve, reject) => {
2867
- const image = new Image();
2868
- image.onload = () => resolve(image);
2869
- image.onerror = reject;
2870
- image.src = src;
2871
- });
2872
- var themeColor = (name, alpha = 1) => {
2873
- const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim() || getComputedStyle(document.body).getPropertyValue(name).trim();
2874
- return value ? `rgb(${value} / ${alpha})` : alpha === 1 ? "#0f172a" : `rgb(15 23 42 / ${alpha})`;
2875
- };
2876
- async function withBranding(dataUrl) {
2877
- const image = await loadImage(dataUrl);
2878
- const canvas = document.createElement("canvas");
2879
- canvas.width = image.width;
2880
- canvas.height = image.height;
2881
- const context = canvas.getContext("2d");
2882
- if (!context) return dataUrl;
2883
- context.drawImage(image, 0, 0);
2884
- await document.fonts?.ready;
2885
- const r = Math.max(
2886
- PIXEL_RATIO,
2887
- Math.min(canvas.width / 1200, canvas.height / 500)
2888
- );
2889
- const text = themeColor("--ec-page-text");
2890
- const muted = themeColor("--ec-page-text-muted");
2891
- const font = (weight) => `${weight} ${12 * r}px Inter, ui-sans-serif, system-ui, sans-serif`;
2892
- const parts = [
2893
- { label: "Made with ", weight: 400, color: muted },
2894
- { label: "EventCatalog", weight: 600, color: text },
2895
- { label: " \xB7 eventcatalog.dev", weight: 400, color: muted }
2896
- ];
2897
- const widths = parts.map((part) => {
2898
- context.font = font(part.weight);
2899
- return context.measureText(part.label).width;
2900
- });
2901
- const logoSize = 16 * r;
2902
- const paddingX = 12 * r;
2903
- const gap = 7 * r;
2904
- const height = 30 * r;
2905
- const width = paddingX * 2 + logoSize + gap + widths.reduce((sum, w) => sum + w, 0);
2906
- const margin = 20 * r;
2907
- const x = canvas.width - width - margin;
2908
- const y = canvas.height - height - margin;
2909
- context.fillStyle = themeColor("--ec-card-bg", 0.96);
2910
- context.strokeStyle = themeColor("--ec-page-border");
2911
- context.lineWidth = r;
2912
- context.beginPath();
2913
- context.roundRect(x, y, width, height, height / 2);
2914
- context.fill();
2915
- context.stroke();
2916
- const logo = await loadImage(
2917
- `data:image/svg+xml;charset=utf-8,${encodeURIComponent(eventcatalog_logo_default.replace(/currentColor/g, text))}`
2918
- );
2919
- context.drawImage(
2920
- logo,
2921
- x + paddingX,
2922
- y + (height - logoSize) / 2,
2923
- logoSize,
2924
- logoSize
2925
- );
2926
- let textX = x + paddingX + logoSize + gap;
2927
- context.textBaseline = "middle";
2928
- parts.forEach((part, index) => {
2929
- context.font = font(part.weight);
2930
- context.fillStyle = part.color;
2931
- context.fillText(part.label, textX, y + height / 2 + r);
2932
- textX += widths[index];
2933
- });
2934
- return canvas.toDataURL("image/png");
2935
- }
2936
2881
  async function canvasImage(container) {
2937
2882
  const viewport = container.querySelector(
2938
2883
  ".react-flow__viewport"
@@ -2959,11 +2904,7 @@ async function canvasImage(container) {
2959
2904
  removeExportStyles();
2960
2905
  container.classList.remove("ec-exporting");
2961
2906
  }
2962
- try {
2963
- return await withBranding(dataUrl);
2964
- } catch {
2965
- return dataUrl;
2966
- }
2907
+ return addExportBranding(dataUrl, PIXEL_RATIO);
2967
2908
  }
2968
2909
 
2969
2910
  // src/studio/components/canvas-nodes.tsx
@@ -2984,7 +2925,8 @@ import {
2984
2925
  Position as Position2,
2985
2926
  ResizeControlVariant,
2986
2927
  useReactFlow,
2987
- useStoreApi as useStoreApi2
2928
+ useStoreApi as useStoreApi2,
2929
+ useUpdateNodeInternals
2988
2930
  } from "@xyflow/react";
2989
2931
 
2990
2932
  // src/studio/components/TeamNode.tsx
@@ -3388,6 +3330,10 @@ var GroupNode = memo2(function GroupNode2(props) {
3388
3330
  const locked = useContext(LockedContext);
3389
3331
  const data = useDomainData(props);
3390
3332
  const store = useStoreApi2();
3333
+ const updateNodeInternals = useUpdateNodeInternals();
3334
+ useEffect2(() => {
3335
+ updateNodeInternals(props.id);
3336
+ }, [updateNodeInternals, props.id, props.width, props.height]);
3391
3337
  const contents = useRef(null);
3392
3338
  const onResizeStart = useCallback(() => {
3393
3339
  const { nodeLookup } = store.getState();
@@ -6524,6 +6470,47 @@ function Field({
6524
6470
  children
6525
6471
  ] });
6526
6472
  }
6473
+
6474
+ // src/studio/components/RemeasureHandles.tsx
6475
+ import { memo as memo9, useEffect as useEffect10 } from "react";
6476
+ import {
6477
+ useStore as useStore2,
6478
+ useUpdateNodeInternals as useUpdateNodeInternals2
6479
+ } from "@xyflow/react";
6480
+ var selectDomNode = (state) => state.domNode;
6481
+ var RemeasureHandles = memo9(function RemeasureHandles2() {
6482
+ const domNode = useStore2(selectDomNode);
6483
+ const updateNodeInternals = useUpdateNodeInternals2();
6484
+ useEffect10(() => {
6485
+ if (!domNode) return;
6486
+ const pending = /* @__PURE__ */ new Set();
6487
+ let frame = 0;
6488
+ const flush = () => {
6489
+ frame = 0;
6490
+ updateNodeInternals([...pending]);
6491
+ pending.clear();
6492
+ };
6493
+ const remeasure = (event) => {
6494
+ const element = event.target;
6495
+ if (!element.classList?.contains("react-flow__node")) return;
6496
+ const resized = event.type === "transitionend" ? ["width", "height"].includes(
6497
+ event.propertyName
6498
+ ) : event.animationName === "studio-node-in";
6499
+ const id = element.dataset.id;
6500
+ if (!resized || !id) return;
6501
+ pending.add(id);
6502
+ frame || (frame = requestAnimationFrame(flush));
6503
+ };
6504
+ domNode.addEventListener("animationend", remeasure);
6505
+ domNode.addEventListener("transitionend", remeasure);
6506
+ return () => {
6507
+ cancelAnimationFrame(frame);
6508
+ domNode.removeEventListener("animationend", remeasure);
6509
+ domNode.removeEventListener("transitionend", remeasure);
6510
+ };
6511
+ }, [domNode, updateNodeInternals]);
6512
+ return null;
6513
+ });
6527
6514
  export {
6528
6515
  AgentMark,
6529
6516
  CANVAS_STATUSES,
@@ -6577,6 +6564,7 @@ export {
6577
6564
  PaletteItem,
6578
6565
  PaletteSection,
6579
6566
  Picture,
6567
+ RemeasureHandles,
6580
6568
  SEVERITIES,
6581
6569
  SHORTCUTS,
6582
6570
  STATUS,