likec4 1.9.0 → 1.10.1

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.
@@ -2307,6 +2307,17 @@ const isEdgeBase = (element) => "id" in element && "source" in element && "targe
2307
2307
  x: node.position.x - offsetX,
2308
2308
  y: node.position.y - offsetY
2309
2309
  };
2310
+ }, getNodesBounds = (nodes, params = { nodeOrigin: [0, 0], nodeLookup: void 0 }) => {
2311
+ if (nodes.length === 0)
2312
+ return { x: 0, y: 0, width: 0, height: 0 };
2313
+ const box = nodes.reduce((currBox, nodeOrId) => {
2314
+ const isId = typeof nodeOrId == "string";
2315
+ let currentNode = !params.nodeLookup && !isId ? nodeOrId : void 0;
2316
+ params.nodeLookup && (currentNode = isId ? params.nodeLookup.get(nodeOrId) : isInternalNodeBase(nodeOrId) ? nodeOrId : params.nodeLookup.get(nodeOrId.id));
2317
+ const nodeBox = currentNode ? nodeToBox(currentNode, params.nodeOrigin) : { x: 0, y: 0, x2: 0, y2: 0 };
2318
+ return getBoundsOfBoxes(currBox, nodeBox);
2319
+ }, { x: 1 / 0, y: 1 / 0, x2: -1 / 0, y2: -1 / 0 });
2320
+ return boxToRect(box);
2310
2321
  }, getInternalNodesBounds = (nodeLookup, params = {}) => {
2311
2322
  if (nodeLookup.size === 0)
2312
2323
  return { x: 0, y: 0, width: 0, height: 0 };
@@ -2349,30 +2360,26 @@ async function fitView({ nodes, width, height, panZoom, minZoom, maxZoom }, opti
2349
2360
  const bounds = getInternalNodesBounds(nodes), viewport = getViewportForBounds(bounds, width, height, options?.minZoom ?? minZoom, options?.maxZoom ?? maxZoom, options?.padding ?? 0.1);
2350
2361
  return await panZoom.setViewport(viewport, { duration: options?.duration }), Promise.resolve(!0);
2351
2362
  }
2352
- function clampNodeExtent(node, extent) {
2353
- return !extent || extent === "parent" ? extent : [extent[0], [extent[1][0] - (node.measured?.width ?? 0), extent[1][1] - (node.measured?.height ?? 0)]];
2354
- }
2355
2363
  function calculateNodePosition({ nodeId, nextPosition, nodeLookup, nodeOrigin = [0, 0], nodeExtent, onError }) {
2356
2364
  const node = nodeLookup.get(nodeId), parentNode = node.parentId ? nodeLookup.get(node.parentId) : void 0, { x: parentX, y: parentY } = parentNode ? parentNode.internals.positionAbsolute : { x: 0, y: 0 }, origin = node.origin ?? nodeOrigin;
2357
- let currentExtent = clampNodeExtent(node, node.extent || nodeExtent);
2365
+ let extent = nodeExtent;
2358
2366
  if (node.extent === "parent" && !node.expandParent)
2359
2367
  if (!parentNode)
2360
2368
  onError?.("005", errorMessages.error005());
2361
2369
  else {
2362
- const nodeWidth = node.measured.width, nodeHeight = node.measured.height, parentWidth = parentNode.measured.width, parentHeight = parentNode.measured.height;
2363
- nodeWidth && nodeHeight && parentWidth && parentHeight && (currentExtent = [
2370
+ const parentWidth = parentNode.measured.width, parentHeight = parentNode.measured.height;
2371
+ parentWidth && parentHeight && (extent = [
2364
2372
  [parentX, parentY],
2365
- [parentX + parentWidth - nodeWidth, parentY + parentHeight - nodeHeight]
2373
+ [parentX + parentWidth, parentY + parentHeight]
2366
2374
  ]);
2367
2375
  }
2368
- else parentNode && isCoordinateExtent(node.extent) && (currentExtent = [
2376
+ else parentNode && isCoordinateExtent(node.extent) && (extent = [
2369
2377
  [node.extent[0][0] + parentX, node.extent[0][1] + parentY],
2370
2378
  [node.extent[1][0] + parentX, node.extent[1][1] + parentY]
2371
2379
  ]);
2372
- const positionAbsolute = isCoordinateExtent(currentExtent) ? clampPosition(nextPosition, currentExtent) : nextPosition;
2380
+ const positionAbsolute = isCoordinateExtent(extent) ? clampPosition(nextPosition, extent, node.measured) : nextPosition;
2373
2381
  return {
2374
2382
  position: {
2375
- // TODO: is there a better way to do this?
2376
2383
  x: positionAbsolute.x - parentX + node.measured.width * origin[0],
2377
2384
  y: positionAbsolute.y - parentY + node.measured.height * origin[1]
2378
2385
  },
@@ -2401,10 +2408,18 @@ async function getElementsToRemove({ nodesToRemove = [], edgesToRemove = [], nod
2401
2408
  });
2402
2409
  return typeof onBeforeDeleteResult == "boolean" ? onBeforeDeleteResult ? { edges: matchingEdges, nodes: matchingNodes } : { edges: [], nodes: [] } : onBeforeDeleteResult;
2403
2410
  }
2404
- const clamp = (val, min = 0, max = 1) => Math.min(Math.max(val, min), max), clampPosition = (position = { x: 0, y: 0 }, extent) => ({
2405
- x: clamp(position.x, extent[0][0], extent[1][0]),
2406
- y: clamp(position.y, extent[0][1], extent[1][1])
2407
- }), calcAutoPanVelocity = (value, min, max) => value < min ? clamp(Math.abs(value - min), 1, min) / min : value > max ? -clamp(Math.abs(value - max), 1, min) / min : 0, calcAutoPan = (pos, bounds, speed = 15, distance2 = 40) => {
2411
+ const clamp = (val, min = 0, max = 1) => Math.min(Math.max(val, min), max), clampPosition = (position = { x: 0, y: 0 }, extent, dimensions) => ({
2412
+ x: clamp(position.x, extent[0][0], extent[1][0] - (dimensions?.width ?? 0)),
2413
+ y: clamp(position.y, extent[0][1], extent[1][1] - (dimensions?.height ?? 0))
2414
+ });
2415
+ function clampPositionToParent(childPosition, childDimensions, parent) {
2416
+ const { width: parentWidth, height: parentHeight } = getNodeDimensions(parent), { x: parentX, y: parentY } = parent.internals.positionAbsolute;
2417
+ return clampPosition(childPosition, [
2418
+ [parentX, parentY],
2419
+ [parentX + parentWidth, parentY + parentHeight]
2420
+ ], childDimensions);
2421
+ }
2422
+ const calcAutoPanVelocity = (value, min, max) => value < min ? clamp(Math.abs(value - min), 1, min) / min : value > max ? -clamp(Math.abs(value - max), 1, min) / min : 0, calcAutoPan = (pos, bounds, speed = 15, distance2 = 40) => {
2408
2423
  const xMovement = calcAutoPanVelocity(pos.x, distance2, bounds.width - distance2) * speed, yMovement = calcAutoPanVelocity(pos.y, distance2, bounds.height - distance2) * speed;
2409
2424
  return [xMovement, yMovement];
2410
2425
  }, getBoundsOfBoxes = (box1, box2) => ({
@@ -2759,63 +2774,83 @@ function createMarkerIds(edges, { id: id2, defaultColor, defaultMarkerStart, def
2759
2774
  }
2760
2775
  const defaultOptions = {
2761
2776
  nodeOrigin: [0, 0],
2777
+ nodeExtent: infiniteExtent,
2762
2778
  elevateNodesOnSelect: !0,
2763
2779
  defaults: {}
2764
2780
  }, adoptUserNodesDefaultOptions = {
2765
2781
  ...defaultOptions,
2766
2782
  checkEquality: !0
2767
2783
  };
2784
+ function mergeObjects(base, incoming) {
2785
+ const result = { ...base };
2786
+ for (const key in incoming)
2787
+ incoming[key] !== void 0 && (result[key] = incoming[key]);
2788
+ return result;
2789
+ }
2768
2790
  function updateAbsolutePositions(nodeLookup, parentLookup, options) {
2769
- const _options = { ...defaultOptions, ...options };
2791
+ const _options = mergeObjects(defaultOptions, options);
2770
2792
  for (const node of nodeLookup.values())
2771
- node.parentId && updateChildPosition(node, nodeLookup, parentLookup, _options);
2793
+ node.parentId && updateChildNode(node, nodeLookup, parentLookup, _options);
2772
2794
  }
2773
2795
  function adoptUserNodes(nodes, nodeLookup, parentLookup, options) {
2774
- const _options = { ...adoptUserNodesDefaultOptions, ...options }, tmpLookup = new Map(nodeLookup);
2796
+ const _options = mergeObjects(adoptUserNodesDefaultOptions, options), tmpLookup = new Map(nodeLookup), selectedNodeZ = _options?.elevateNodesOnSelect ? 1e3 : 0;
2775
2797
  nodeLookup.clear(), parentLookup.clear();
2776
- const selectedNodeZ = options?.elevateNodesOnSelect ? 1e3 : 0;
2777
2798
  for (const userNode of nodes) {
2778
2799
  let internalNode = tmpLookup.get(userNode.id);
2779
- _options.checkEquality && userNode === internalNode?.internals.userNode || (internalNode = {
2780
- ..._options.defaults,
2781
- ...userNode,
2782
- measured: {
2783
- width: userNode.measured?.width,
2784
- height: userNode.measured?.height
2785
- },
2786
- internals: {
2787
- positionAbsolute: getNodePositionWithOrigin(userNode, _options.nodeOrigin),
2788
- // if user re-initializes the node or removes `measured` for whatever reason, we reset the handleBounds so that the node gets re-measured
2789
- handleBounds: userNode.measured ? internalNode?.internals.handleBounds : void 0,
2790
- z: calculateZ(userNode, selectedNodeZ),
2791
- userNode
2792
- }
2793
- }), nodeLookup.set(userNode.id, internalNode), userNode.parentId && updateChildPosition(internalNode, nodeLookup, parentLookup, options);
2800
+ if (_options.checkEquality && userNode === internalNode?.internals.userNode)
2801
+ nodeLookup.set(userNode.id, internalNode);
2802
+ else {
2803
+ const positionWithOrigin = getNodePositionWithOrigin(userNode, _options.nodeOrigin), extent = isCoordinateExtent(userNode.extent) ? userNode.extent : _options.nodeExtent, clampedPosition = clampPosition(positionWithOrigin, extent, getNodeDimensions(userNode));
2804
+ internalNode = {
2805
+ ..._options.defaults,
2806
+ ...userNode,
2807
+ measured: {
2808
+ width: userNode.measured?.width,
2809
+ height: userNode.measured?.height
2810
+ },
2811
+ internals: {
2812
+ positionAbsolute: clampedPosition,
2813
+ // if user re-initializes the node or removes `measured` for whatever reason, we reset the handleBounds so that the node gets re-measured
2814
+ handleBounds: userNode.measured ? internalNode?.internals.handleBounds : void 0,
2815
+ z: calculateZ(userNode, selectedNodeZ),
2816
+ userNode
2817
+ }
2818
+ }, nodeLookup.set(userNode.id, internalNode);
2819
+ }
2820
+ userNode.parentId && updateChildNode(internalNode, nodeLookup, parentLookup, options);
2794
2821
  }
2795
2822
  }
2796
- function updateChildPosition(node, nodeLookup, parentLookup, options) {
2797
- const _options = { ...defaultOptions, ...options }, parentId = node.parentId, parentNode = nodeLookup.get(parentId);
2823
+ function updateParentLookup(node, parentLookup) {
2824
+ if (!node.parentId)
2825
+ return;
2826
+ const childNodes = parentLookup.get(node.parentId);
2827
+ childNodes ? childNodes.set(node.id, node) : parentLookup.set(node.parentId, /* @__PURE__ */ new Map([[node.id, node]]));
2828
+ }
2829
+ function updateChildNode(node, nodeLookup, parentLookup, options) {
2830
+ const { elevateNodesOnSelect, nodeOrigin, nodeExtent } = mergeObjects(defaultOptions, options), parentId = node.parentId, parentNode = nodeLookup.get(parentId);
2798
2831
  if (!parentNode) {
2799
2832
  console.warn(`Parent node ${parentId} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);
2800
2833
  return;
2801
2834
  }
2802
- const childNodes = parentLookup.get(parentId);
2803
- childNodes ? childNodes.set(node.id, node) : parentLookup.set(parentId, /* @__PURE__ */ new Map([[node.id, node]]));
2804
- const selectedNodeZ = options?.elevateNodesOnSelect ? 1e3 : 0, { x, y, z } = calculateChildXYZ(node, parentNode, _options.nodeOrigin, selectedNodeZ), currPosition = node.internals.positionAbsolute, positionChanged = x !== currPosition.x || y !== currPosition.y;
2835
+ updateParentLookup(node, parentLookup);
2836
+ const selectedNodeZ = elevateNodesOnSelect ? 1e3 : 0, { x, y, z } = calculateChildXYZ(node, parentNode, nodeOrigin, nodeExtent, selectedNodeZ), { positionAbsolute } = node.internals, positionChanged = x !== positionAbsolute.x || y !== positionAbsolute.y;
2805
2837
  (positionChanged || z !== node.internals.z) && (node.internals = {
2806
2838
  ...node.internals,
2807
- positionAbsolute: positionChanged ? { x, y } : currPosition,
2839
+ positionAbsolute: positionChanged ? { x, y } : positionAbsolute,
2808
2840
  z
2809
2841
  });
2810
2842
  }
2811
2843
  function calculateZ(node, selectedNodeZ) {
2812
2844
  return (isNumeric(node.zIndex) ? node.zIndex : 0) + (node.selected ? selectedNodeZ : 0);
2813
2845
  }
2814
- function calculateChildXYZ(childNode, parentNode, nodeOrigin, selectedNodeZ) {
2815
- const position = getNodePositionWithOrigin(childNode, nodeOrigin), childZ = calculateZ(childNode, selectedNodeZ), parentZ = parentNode.internals.z ?? 0;
2846
+ function calculateChildXYZ(childNode, parentNode, nodeOrigin, nodeExtent, selectedNodeZ) {
2847
+ const { x: parentX, y: parentY } = parentNode.internals.positionAbsolute, childDimensions = getNodeDimensions(childNode), positionWithOrigin = getNodePositionWithOrigin(childNode, nodeOrigin), clampedPosition = isCoordinateExtent(childNode.extent) ? clampPosition(positionWithOrigin, childNode.extent, childDimensions) : positionWithOrigin;
2848
+ let absolutePosition = clampPosition({ x: parentX + clampedPosition.x, y: parentY + clampedPosition.y }, nodeExtent, childDimensions);
2849
+ childNode.extent === "parent" && (absolutePosition = clampPositionToParent(absolutePosition, childDimensions, parentNode));
2850
+ const childZ = calculateZ(childNode, selectedNodeZ), parentZ = parentNode.internals.z ?? 0;
2816
2851
  return {
2817
- x: parentNode.internals.positionAbsolute.x + position.x,
2818
- y: parentNode.internals.positionAbsolute.y + position.y,
2852
+ x: absolutePosition.x,
2853
+ y: absolutePosition.y,
2819
2854
  z: parentZ > childZ ? parentZ : childZ
2820
2855
  };
2821
2856
  }
@@ -2857,7 +2892,7 @@ function handleExpandParent(children2, nodeLookup, parentLookup, nodeOrigin = [0
2857
2892
  });
2858
2893
  }), changes;
2859
2894
  }
2860
- function updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOrigin) {
2895
+ function updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOrigin, nodeExtent) {
2861
2896
  const viewportNode = domNode?.querySelector(".xyflow__viewport");
2862
2897
  let updatedInternals = !1;
2863
2898
  if (!viewportNode)
@@ -2874,15 +2909,16 @@ function updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOri
2874
2909
  else {
2875
2910
  const dimensions = getDimensions(update.nodeElement), dimensionChanged = node.measured.width !== dimensions.width || node.measured.height !== dimensions.height;
2876
2911
  if (!!(dimensions.width && dimensions.height && (dimensionChanged || !node.internals.handleBounds || update.force))) {
2877
- const nodeBounds = update.nodeElement.getBoundingClientRect();
2878
- node.measured = dimensions, node.internals = {
2912
+ const nodeBounds = update.nodeElement.getBoundingClientRect(), extent = isCoordinateExtent(node.extent) ? node.extent : nodeExtent;
2913
+ let { positionAbsolute } = node.internals;
2914
+ node.parentId && node.extent === "parent" ? positionAbsolute = clampPositionToParent(positionAbsolute, dimensions, nodeLookup.get(node.parentId)) : extent && (positionAbsolute = clampPosition(positionAbsolute, extent, dimensions)), node.measured = dimensions, node.internals = {
2879
2915
  ...node.internals,
2880
- positionAbsolute: getNodePositionWithOrigin(node, nodeOrigin),
2916
+ positionAbsolute,
2881
2917
  handleBounds: {
2882
2918
  source: getHandleBounds("source", update.nodeElement, nodeBounds, zoom2, node.id),
2883
2919
  target: getHandleBounds("target", update.nodeElement, nodeBounds, zoom2, node.id)
2884
2920
  }
2885
- }, node.parentId && updateChildPosition(node, nodeLookup, parentLookup, { nodeOrigin }), updatedInternals = !0, dimensionChanged && (changes.push({
2921
+ }, node.parentId && updateChildNode(node, nodeLookup, parentLookup, { nodeOrigin }), updatedInternals = !0, dimensionChanged && (changes.push({
2886
2922
  id: node.id,
2887
2923
  type: "dimensions",
2888
2924
  dimensions
@@ -3132,11 +3168,11 @@ function getClosestHandle(position, connectionRadius, nodeLookup, fromHandle) {
3132
3168
  }
3133
3169
  return closestHandles[0];
3134
3170
  }
3135
- function getHandle(nodeId, handleType, handleId, nodeLookup, withAbsolutePosition = !1) {
3171
+ function getHandle(nodeId, handleType, handleId, nodeLookup, connectionMode, withAbsolutePosition = !1) {
3136
3172
  const node = nodeLookup.get(nodeId);
3137
3173
  if (!node)
3138
3174
  return null;
3139
- const handles = node.internals.handleBounds?.[handleType], handle = (handleId ? handles?.find((h2) => h2.id === handleId) : handles?.[0]) ?? null;
3175
+ const handles = connectionMode === "strict" ? node.internals.handleBounds?.[handleType] : [...node.internals.handleBounds?.source ?? [], ...node.internals.handleBounds?.target ?? []], handle = (handleId ? handles?.find((h2) => h2.id === handleId) : handles?.[0]) ?? null;
3140
3176
  return handle && withAbsolutePosition ? { ...handle, ...getHandlePosition(node, handle, handle.position, !0) } : handle;
3141
3177
  }
3142
3178
  function getHandleType(edgeUpdaterType, handleDomNode) {
@@ -3153,7 +3189,7 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
3153
3189
  const { x, y } = getEventPosition(event), clickedHandle = doc?.elementFromPoint(x, y), handleType = getHandleType(edgeUpdaterType, clickedHandle), containerBounds = domNode?.getBoundingClientRect();
3154
3190
  if (!containerBounds || !handleType)
3155
3191
  return;
3156
- const fromHandleInternal = getHandle(nodeId, handleType, handleId, nodeLookup);
3192
+ const fromHandleInternal = getHandle(nodeId, handleType, handleId, nodeLookup, connectionMode);
3157
3193
  if (!fromHandleInternal)
3158
3194
  return;
3159
3195
  let position = getEventPosition(event, containerBounds), autoPanStarted = !1, connection = null, isValid = !1, handleDomNode = null;
@@ -3243,7 +3279,7 @@ function isValidHandle(event, { handle, connectionMode, fromNodeId, fromHandleId
3243
3279
  };
3244
3280
  result.connection = connection;
3245
3281
  const isValid = connectable && connectableEnd && (connectionMode === ConnectionMode.Strict ? isTarget && handleType === "source" || !isTarget && handleType === "target" : handleNodeId !== fromNodeId || handleId !== fromHandleId);
3246
- result.isValid = isValid && isValidConnection(connection), result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, !1);
3282
+ result.isValid = isValid && isValidConnection(connection), result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, connectionMode, !1);
3247
3283
  }
3248
3284
  return result;
3249
3285
  }
@@ -3387,7 +3423,7 @@ function createFilter({ zoomActivationKeyPressed, zoomOnScroll, zoomOnPinch, pan
3387
3423
  return (!event.ctrlKey || event.type === "wheel") && buttonAllowed;
3388
3424
  };
3389
3425
  }
3390
- function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onTransformChange, onDraggingChange }) {
3426
+ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onDraggingChange }) {
3391
3427
  const zoomPanValues = {
3392
3428
  isZoomingOrPanning: !1,
3393
3429
  usedRightMouseButton: !1,
@@ -3412,7 +3448,7 @@ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExte
3412
3448
  d3ZoomInstance?.transform(getD3Transition(d3Selection, options?.duration, () => resolve(!0)), transform2);
3413
3449
  }) : Promise.resolve(!1);
3414
3450
  }
3415
- function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib }) {
3451
+ function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib, onTransformChange }) {
3416
3452
  userSelectionActive && !zoomPanValues.isZoomingOrPanning && destroy();
3417
3453
  const wheelHandler = panOnScroll && !zoomActivationKeyPressed && !userSelectionActive ? createPanOnScrollHandler({
3418
3454
  zoomPanValues,
@@ -4044,10 +4080,10 @@ const useViewportHelper = () => {
4044
4080
  }), []);
4045
4081
  };
4046
4082
  function applyChanges(changes, elements) {
4047
- const updatedElements = [], changesMap = /* @__PURE__ */ new Map();
4083
+ const updatedElements = [], changesMap = /* @__PURE__ */ new Map(), addItemChanges = [];
4048
4084
  for (const change of changes)
4049
4085
  if (change.type === "add") {
4050
- updatedElements.push(change.item);
4086
+ addItemChanges.push(change);
4051
4087
  continue;
4052
4088
  } else if (change.type === "remove" || change.type === "replace")
4053
4089
  changesMap.set(change.id, [change]);
@@ -4072,7 +4108,9 @@ function applyChanges(changes, elements) {
4072
4108
  applyChange(change, updatedElement);
4073
4109
  updatedElements.push(updatedElement);
4074
4110
  }
4075
- return updatedElements;
4111
+ return addItemChanges.length && addItemChanges.forEach((change) => {
4112
+ change.index !== void 0 ? updatedElements.splice(change.index, 0, { ...change.item }) : updatedElements.push({ ...change.item });
4113
+ }), updatedElements;
4076
4114
  }
4077
4115
  function applyChange(change, element) {
4078
4116
  switch (change.type) {
@@ -4113,9 +4151,9 @@ function getSelectionChanges(items, selectedIds = /* @__PURE__ */ new Set(), mut
4113
4151
  }
4114
4152
  function getElementsDiffChanges({ items = [], lookup }) {
4115
4153
  const changes = [], itemsLookup = new Map(items.map((item) => [item.id, item]));
4116
- for (const item of items) {
4154
+ for (const [index2, item] of items.entries()) {
4117
4155
  const lookupItem = lookup.get(item.id), storeItem = lookupItem?.internals?.userNode ?? lookupItem;
4118
- storeItem !== void 0 && storeItem !== item && changes.push({ id: item.id, item, type: "replace" }), storeItem === void 0 && changes.push({ item, type: "add" });
4156
+ storeItem !== void 0 && storeItem !== item && changes.push({ id: item.id, item, type: "replace" }), storeItem === void 0 && changes.push({ item, type: "add", index: index2 });
4119
4157
  }
4120
4158
  for (const [id2] of lookup)
4121
4159
  itemsLookup.get(id2) === void 0 && changes.push({ id: id2, type: "remove" });
@@ -4296,7 +4334,12 @@ function useReactFlow() {
4296
4334
  const nextData = typeof dataUpdate == "function" ? dataUpdate(edge) : dataUpdate;
4297
4335
  return options.replace ? { ...edge, data: nextData } : { ...edge, data: { ...edge.data, ...nextData } };
4298
4336
  }, options);
4299
- }
4337
+ },
4338
+ getNodesBounds: (nodes) => {
4339
+ const { nodeLookup, nodeOrigin } = store.getState();
4340
+ return getNodesBounds(nodes, { nodeLookup, nodeOrigin });
4341
+ },
4342
+ getHandleConnections: ({ type, id: id2, nodeId }) => Array.from(store.getState().connectionLookup.get(`${nodeId}-${type}-${id2 ?? null}`)?.values() ?? [])
4300
4343
  };
4301
4344
  }, []);
4302
4345
  return useMemo(() => ({
@@ -4347,7 +4390,11 @@ const containerStyle = {
4347
4390
  });
4348
4391
  function ZoomPane({ onPaneContextMenu, zoomOnScroll = !0, zoomOnPinch = !0, panOnScroll = !1, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = !0, panOnDrag = !0, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = !0, children: children2, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, paneClickDistance }) {
4349
4392
  const store = useStoreApi(), zoomPane = useRef(null), { userSelectionActive, lib } = useStore(selector$j, shallow$1), zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode), panZoom = useRef();
4350
- return useResizeHandler(zoomPane), useEffect(() => {
4393
+ useResizeHandler(zoomPane);
4394
+ const onTransformChange = useCallback((transform2) => {
4395
+ onViewportChange?.({ x: transform2[0], y: transform2[1], zoom: transform2[2] }), isControlledViewport || store.setState({ transform: transform2 });
4396
+ }, [onViewportChange, isControlledViewport]);
4397
+ return useEffect(() => {
4351
4398
  if (zoomPane.current) {
4352
4399
  panZoom.current = XYPanZoom({
4353
4400
  domNode: zoomPane.current,
@@ -4356,9 +4403,6 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = !0, zoomOnPinch = !0, panO
4356
4403
  translateExtent,
4357
4404
  viewport: defaultViewport2,
4358
4405
  paneClickDistance,
4359
- onTransformChange: (transform2) => {
4360
- onViewportChange?.({ x: transform2[0], y: transform2[1], zoom: transform2[2] }), isControlledViewport || store.setState({ transform: transform2 });
4361
- },
4362
4406
  onDraggingChange: (paneDragging) => store.setState({ paneDragging }),
4363
4407
  onPanZoomStart: (event, vp) => {
4364
4408
  const { onViewportChangeStart, onMoveStart } = store.getState();
@@ -4397,7 +4441,8 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = !0, zoomOnPinch = !0, panO
4397
4441
  noPanClassName,
4398
4442
  userSelectionActive,
4399
4443
  noWheelClassName,
4400
- lib
4444
+ lib,
4445
+ onTransformChange
4401
4446
  });
4402
4447
  }, [
4403
4448
  onPaneContextMenu,
@@ -4413,7 +4458,8 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = !0, zoomOnPinch = !0, panO
4413
4458
  noPanClassName,
4414
4459
  userSelectionActive,
4415
4460
  noWheelClassName,
4416
- lib
4461
+ lib,
4462
+ onTransformChange
4417
4463
  ]), jsx("div", { className: "react-flow__renderer", ref: zoomPane, style: containerStyle, children: children2 });
4418
4464
  }
4419
4465
  const selector$i = (s) => ({
@@ -4823,7 +4869,7 @@ function NodeWrapper({ id: id2, onClick, onMouseEnter, onMouseMove, onMouseLeave
4823
4869
  }), moveSelectedNodes = useMoveSelectedNodes();
4824
4870
  if (node.hidden)
4825
4871
  return null;
4826
- const nodeDimensions = getNodeDimensions(node), inlineDimensions = getNodeInlineStyleDimensions(node), clampedPosition = nodeExtent ? clampPosition(internals.positionAbsolute, nodeExtent) : internals.positionAbsolute, hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave, onMouseEnterHandler = onMouseEnter ? (event) => onMouseEnter(event, { ...internals.userNode }) : void 0, onMouseMoveHandler = onMouseMove ? (event) => onMouseMove(event, { ...internals.userNode }) : void 0, onMouseLeaveHandler = onMouseLeave ? (event) => onMouseLeave(event, { ...internals.userNode }) : void 0, onContextMenuHandler = onContextMenu ? (event) => onContextMenu(event, { ...internals.userNode }) : void 0, onDoubleClickHandler = onDoubleClick ? (event) => onDoubleClick(event, { ...internals.userNode }) : void 0, onSelectNodeHandler = (event) => {
4872
+ const nodeDimensions = getNodeDimensions(node), inlineDimensions = getNodeInlineStyleDimensions(node), hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave, onMouseEnterHandler = onMouseEnter ? (event) => onMouseEnter(event, { ...internals.userNode }) : void 0, onMouseMoveHandler = onMouseMove ? (event) => onMouseMove(event, { ...internals.userNode }) : void 0, onMouseLeaveHandler = onMouseLeave ? (event) => onMouseLeave(event, { ...internals.userNode }) : void 0, onContextMenuHandler = onContextMenu ? (event) => onContextMenu(event, { ...internals.userNode }) : void 0, onDoubleClickHandler = onDoubleClick ? (event) => onDoubleClick(event, { ...internals.userNode }) : void 0, onSelectNodeHandler = (event) => {
4827
4873
  const { selectNodesOnDrag, nodeDragThreshold } = store.getState();
4828
4874
  isSelectable && (!selectNodesOnDrag || !isDraggable || nodeDragThreshold > 0) && handleNodeClick({
4829
4875
  id: id2,
@@ -4841,7 +4887,7 @@ function NodeWrapper({ id: id2, onClick, onMouseEnter, onMouseMove, onMouseLeave
4841
4887
  nodeRef
4842
4888
  });
4843
4889
  } else isDraggable && node.selected && Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key) && (store.setState({
4844
- ariaLiveMessage: `Moved selected node ${event.key.replace("Arrow", "").toLowerCase()}. New position, x: ${~~clampedPosition.x}, y: ${~~clampedPosition.y}`
4890
+ ariaLiveMessage: `Moved selected node ${event.key.replace("Arrow", "").toLowerCase()}. New position, x: ${~~internals.positionAbsolute.x}, y: ${~~internals.positionAbsolute.y}`
4845
4891
  }), moveSelectedNodes({
4846
4892
  direction: arrowKeyDiffs[event.key],
4847
4893
  factor: event.shiftKey ? 4 : 1
@@ -4864,12 +4910,12 @@ function NodeWrapper({ id: id2, onClick, onMouseEnter, onMouseMove, onMouseLeave
4864
4910
  }
4865
4911
  ]), ref: nodeRef, style: {
4866
4912
  zIndex: internals.z,
4867
- transform: `translate(${clampedPosition.x}px,${clampedPosition.y}px)`,
4913
+ transform: `translate(${internals.positionAbsolute.x}px,${internals.positionAbsolute.y}px)`,
4868
4914
  pointerEvents: hasPointerEvents ? "all" : "none",
4869
4915
  visibility: hasDimensions ? "visible" : "hidden",
4870
4916
  ...node.style,
4871
4917
  ...inlineDimensions
4872
- }, "data-id": id2, "data-testid": `rf__node-${id2}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : void 0, "aria-describedby": disableKeyboardA11y ? void 0 : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id2, children: jsx(NodeComponent, { id: id2, data: node.data, type: nodeType, positionAbsoluteX: clampedPosition.x, positionAbsoluteY: clampedPosition.y, selected: node.selected, selectable: isSelectable, draggable: isDraggable, deletable: node.deletable ?? !0, isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging, dragHandle: node.dragHandle, zIndex: internals.z, parentId: node.parentId, ...nodeDimensions }) }) });
4918
+ }, "data-id": id2, "data-testid": `rf__node-${id2}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : void 0, "aria-describedby": disableKeyboardA11y ? void 0 : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id2, children: jsx(NodeComponent, { id: id2, data: node.data, type: nodeType, positionAbsoluteX: internals.positionAbsolute.x, positionAbsoluteY: internals.positionAbsolute.y, selected: node.selected, selectable: isSelectable, draggable: isDraggable, deletable: node.deletable ?? !0, isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging, dragHandle: node.dragHandle, zIndex: internals.z, parentId: node.parentId, ...nodeDimensions }) }) });
4873
4919
  }
4874
4920
  const selector$b = (s) => ({
4875
4921
  nodesDraggable: s.nodesDraggable,
@@ -5096,25 +5142,25 @@ const builtinEdgeTypes = {
5096
5142
  function EdgeAnchor({ position, centerX, centerY, radius = 10, onMouseDown, onMouseEnter, onMouseOut, type }) {
5097
5143
  return jsx("circle", { onMouseDown, onMouseEnter, onMouseOut, className: cc([EdgeUpdaterClassName, `${EdgeUpdaterClassName}-${type}`]), cx: shiftX(centerX, radius, position), cy: shiftY(centerY, radius, position), r: radius, stroke: "transparent", fill: "transparent" });
5098
5144
  }
5099
- function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, targetHandleId, sourceHandleId, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onReconnect, onReconnectStart, onReconnectEnd, setReconnecting, setUpdateHover }) {
5100
- const store = useStoreApi(), handleEdgeUpdater = (event, isSourceHandle) => {
5145
+ function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onReconnect, onReconnectStart, onReconnectEnd, setReconnecting, setUpdateHover }) {
5146
+ const store = useStoreApi(), handleEdgeUpdater = (event, oppositeHandle) => {
5101
5147
  if (event.button !== 0)
5102
5148
  return;
5103
- const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodeLookup, rfId: flowId, panBy: panBy2, updateConnection } = store.getState(), nodeId = isSourceHandle ? edge.target : edge.source, handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null, handleType = isSourceHandle ? "target" : "source", isTarget = isSourceHandle;
5104
- setReconnecting(!0), onReconnectStart?.(event, edge, handleType);
5149
+ const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodeLookup, rfId: flowId, panBy: panBy2, updateConnection } = store.getState(), isTarget = oppositeHandle.type === "target";
5150
+ setReconnecting(!0), onReconnectStart?.(event, edge, oppositeHandle.type);
5105
5151
  const _onReconnectEnd = (evt, connectionState) => {
5106
- setReconnecting(!1), onReconnectEnd?.(evt, edge, handleType, connectionState);
5152
+ setReconnecting(!1), onReconnectEnd?.(evt, edge, oppositeHandle.type, connectionState);
5107
5153
  }, onConnectEdge = (connection) => onReconnect?.(edge, connection);
5108
5154
  XYHandle.onPointerDown(event.nativeEvent, {
5109
5155
  autoPanOnConnect,
5110
5156
  connectionMode,
5111
5157
  connectionRadius,
5112
5158
  domNode,
5113
- handleId,
5114
- nodeId,
5159
+ handleId: oppositeHandle.id,
5160
+ nodeId: oppositeHandle.nodeId,
5115
5161
  nodeLookup,
5116
5162
  isTarget,
5117
- edgeUpdaterType: handleType,
5163
+ edgeUpdaterType: oppositeHandle.type,
5118
5164
  lib,
5119
5165
  flowId,
5120
5166
  cancelConnection,
@@ -5128,8 +5174,8 @@ function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, targetHandl
5128
5174
  getTransform: () => store.getState().transform,
5129
5175
  getFromHandle: () => store.getState().connection.fromHandle
5130
5176
  });
5131
- }, onReconnectSourceMouseDown = (event) => handleEdgeUpdater(event, !0), onReconnectTargetMouseDown = (event) => handleEdgeUpdater(event, !1), onReconnectMouseEnter = () => setUpdateHover(!0), onReconnectMouseOut = () => setUpdateHover(!1);
5132
- return jsxs(Fragment, { children: [(isReconnectable === "source" || isReconnectable === !0) && jsx(EdgeAnchor, { position: sourcePosition, centerX: sourceX, centerY: sourceY, radius: reconnectRadius, onMouseDown: onReconnectSourceMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "source" }), (isReconnectable === "target" || isReconnectable === !0) && jsx(EdgeAnchor, { position: targetPosition, centerX: targetX, centerY: targetY, radius: reconnectRadius, onMouseDown: onReconnectTargetMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "target" })] });
5177
+ }, onReconnectSourceMouseDown = (event) => handleEdgeUpdater(event, { nodeId: edge.target, id: edge.targetHandle ?? null, type: "target" }), onReconnectTargetMouseDown = (event) => handleEdgeUpdater(event, { nodeId: edge.source, id: edge.sourceHandle ?? null, type: "source" }), onReconnectMouseEnter = () => setUpdateHover(!0), onReconnectMouseOut = () => setUpdateHover(!1);
5178
+ return jsxs(Fragment, { children: [(isReconnectable === !0 || isReconnectable === "source") && jsx(EdgeAnchor, { position: sourcePosition, centerX: sourceX, centerY: sourceY, radius: reconnectRadius, onMouseDown: onReconnectSourceMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "source" }), (isReconnectable === !0 || isReconnectable === "target") && jsx(EdgeAnchor, { position: targetPosition, centerX: targetX, centerY: targetY, radius: reconnectRadius, onMouseDown: onReconnectTargetMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "target" })] });
5133
5179
  }
5134
5180
  function EdgeWrapper({ id: id2, edgesFocusable, edgesReconnectable, elementsSelectable, onClick, onDoubleClick, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, rfId, edgeTypes, noPanClassName, onError, disableKeyboardA11y }) {
5135
5181
  let edge = useStore((s) => s.edgeLookup.get(id2));
@@ -5197,7 +5243,7 @@ function EdgeWrapper({ id: id2, edgesFocusable, edgesReconnectable, elementsSele
5197
5243
  updating: updateHover,
5198
5244
  selectable: isSelectable
5199
5245
  }
5200
- ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!reconnecting && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? !0, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isReconnectable && jsx(EdgeUpdateAnchors, { edge, isReconnectable, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setReconnecting, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle })] }) });
5246
+ ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!reconnecting && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? !0, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isReconnectable && jsx(EdgeUpdateAnchors, { edge, isReconnectable, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setReconnecting })] }) });
5201
5247
  }
5202
5248
  const selector$a = (s) => ({
5203
5249
  width: s.width,
@@ -5302,10 +5348,11 @@ function GraphViewComponent({ nodeTypes, edgeTypes, onInit, onNodeClick, onEdgeC
5302
5348
  return useNodeOrEdgeTypesWarning(nodeTypes), useNodeOrEdgeTypesWarning(edgeTypes), useStylesLoadedWarning(), useOnInitHandler(onInit), useViewportSync(viewport), jsx(FlowRenderer, { onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, paneClickDistance, deleteKeyCode, selectionKeyCode, selectionOnDrag, selectionMode, onSelectionStart, onSelectionEnd, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, elementsSelectable, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, onSelectionContextMenu, preventScrolling, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes, onEdgeClick, onEdgeDoubleClick, onReconnect, onReconnectStart, onReconnectEnd, onlyRenderVisibleElements, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, defaultMarkerColor, noPanClassName, disableKeyboardA11y, rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx(NodeRenderer, { nodeTypes, onNodeClick, onNodeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, nodeClickDistance, onlyRenderVisibleElements, noPanClassName, noDragClassName, disableKeyboardA11y, nodeExtent, rfId }), jsx("div", { className: "react-flow__viewport-portal" })] }) });
5303
5349
  }
5304
5350
  GraphViewComponent.displayName = "GraphView";
5305
- const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView2, nodeOrigin } = {}) => {
5306
- const nodeLookup = /* @__PURE__ */ new Map(), parentLookup = /* @__PURE__ */ new Map(), connectionLookup = /* @__PURE__ */ new Map(), edgeLookup = /* @__PURE__ */ new Map(), storeEdges = defaultEdges ?? edges ?? [], storeNodes = defaultNodes ?? nodes ?? [], storeNodeOrigin = nodeOrigin ?? [0, 0];
5351
+ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView2, nodeOrigin, nodeExtent } = {}) => {
5352
+ const nodeLookup = /* @__PURE__ */ new Map(), parentLookup = /* @__PURE__ */ new Map(), connectionLookup = /* @__PURE__ */ new Map(), edgeLookup = /* @__PURE__ */ new Map(), storeEdges = defaultEdges ?? edges ?? [], storeNodes = defaultNodes ?? nodes ?? [], storeNodeOrigin = nodeOrigin ?? [0, 0], storeNodeExtent = nodeExtent ?? infiniteExtent;
5307
5353
  updateConnectionLookup(connectionLookup, edgeLookup, storeEdges), adoptUserNodes(storeNodes, nodeLookup, parentLookup, {
5308
5354
  nodeOrigin: storeNodeOrigin,
5355
+ nodeExtent: storeNodeExtent,
5309
5356
  elevateNodesOnSelect: !1
5310
5357
  });
5311
5358
  let transform2 = [0, 0, 1];
@@ -5334,7 +5381,7 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5334
5381
  minZoom: 0.5,
5335
5382
  maxZoom: 2,
5336
5383
  translateExtent: infiniteExtent,
5337
- nodeExtent: infiniteExtent,
5384
+ nodeExtent: storeNodeExtent,
5338
5385
  nodesSelectionActive: !1,
5339
5386
  userSelectionActive: !1,
5340
5387
  userSelectionRect: null,
@@ -5373,11 +5420,16 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5373
5420
  lib: "react",
5374
5421
  debug: !1
5375
5422
  };
5376
- }, createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, nodeOrigin }) => createWithEqualityFn((set2, get2) => ({
5377
- ...getInitialState({ nodes, edges, width, height, fitView: fitView$1, nodeOrigin, defaultNodes, defaultEdges }),
5423
+ }, createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, nodeOrigin, nodeExtent }) => createWithEqualityFn((set2, get2) => ({
5424
+ ...getInitialState({ nodes, edges, width, height, fitView: fitView$1, nodeOrigin, nodeExtent, defaultNodes, defaultEdges }),
5378
5425
  setNodes: (nodes2) => {
5379
5426
  const { nodeLookup, parentLookup, nodeOrigin: nodeOrigin2, elevateNodesOnSelect } = get2();
5380
- adoptUserNodes(nodes2, nodeLookup, parentLookup, { nodeOrigin: nodeOrigin2, elevateNodesOnSelect, checkEquality: !0 }), set2({ nodes: nodes2 });
5427
+ adoptUserNodes(nodes2, nodeLookup, parentLookup, {
5428
+ nodeOrigin: nodeOrigin2,
5429
+ nodeExtent,
5430
+ elevateNodesOnSelect,
5431
+ checkEquality: !0
5432
+ }), set2({ nodes: nodes2 });
5381
5433
  },
5382
5434
  setEdges: (edges2) => {
5383
5435
  const { connectionLookup, edgeLookup } = get2();
@@ -5397,9 +5449,9 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5397
5449
  // changes its dimensions, this function is called to measure the
5398
5450
  // new dimensions and update the nodes.
5399
5451
  updateNodeInternals: (updates, params = { triggerFitView: !0 }) => {
5400
- const { triggerNodeChanges, nodeLookup, parentLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin: nodeOrigin2, debug, fitViewSync } = get2(), { changes, updatedInternals } = updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOrigin2);
5452
+ const { triggerNodeChanges, nodeLookup, parentLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin: nodeOrigin2, nodeExtent: nodeExtent2, debug, fitViewSync } = get2(), { changes, updatedInternals } = updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOrigin2, nodeExtent2);
5401
5453
  if (updatedInternals) {
5402
- if (updateAbsolutePositions(nodeLookup, parentLookup, { nodeOrigin: nodeOrigin2 }), params.triggerFitView) {
5454
+ if (updateAbsolutePositions(nodeLookup, parentLookup, { nodeOrigin: nodeOrigin2, nodeExtent: nodeExtent2 }), params.triggerFitView) {
5403
5455
  let nextFitViewDone = fitViewDone;
5404
5456
  !fitViewDone && fitViewOnInit && (nextFitViewDone = fitViewSync({
5405
5457
  ...fitViewOnInitOptions,
@@ -5495,21 +5547,14 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5495
5547
  const { edges: edges2, nodes: nodes2, triggerNodeChanges, triggerEdgeChanges } = get2(), nodeChanges = nodes2.reduce((res, node) => node.selected ? [...res, createSelectionChange(node.id, !1)] : res, []), edgeChanges = edges2.reduce((res, edge) => edge.selected ? [...res, createSelectionChange(edge.id, !1)] : res, []);
5496
5548
  triggerNodeChanges(nodeChanges), triggerEdgeChanges(edgeChanges);
5497
5549
  },
5498
- setNodeExtent: (nodeExtent) => {
5499
- const { nodeLookup } = get2();
5500
- for (const [, node] of nodeLookup) {
5501
- const positionAbsolute = clampPosition(node.internals.positionAbsolute, nodeExtent);
5502
- nodeLookup.set(node.id, {
5503
- ...node,
5504
- internals: {
5505
- ...node.internals,
5506
- positionAbsolute
5507
- }
5508
- });
5509
- }
5510
- set2({
5511
- nodeExtent
5512
- });
5550
+ setNodeExtent: (nextNodeExtent) => {
5551
+ const { nodes: nodes2, nodeLookup, parentLookup, nodeOrigin: nodeOrigin2, elevateNodesOnSelect, nodeExtent: nodeExtent2 } = get2();
5552
+ nextNodeExtent[0][0] === nodeExtent2[0][0] && nextNodeExtent[0][1] === nodeExtent2[0][1] && nextNodeExtent[1][0] === nodeExtent2[1][0] && nextNodeExtent[1][1] === nodeExtent2[1][1] || (adoptUserNodes(nodes2, nodeLookup, parentLookup, {
5553
+ nodeOrigin: nodeOrigin2,
5554
+ nodeExtent: nextNodeExtent,
5555
+ elevateNodesOnSelect,
5556
+ checkEquality: !1
5557
+ }), set2({ nodeExtent: nextNodeExtent }));
5513
5558
  },
5514
5559
  panBy: (delta) => {
5515
5560
  const { transform: transform2, width: width2, height: height2, panZoom, translateExtent } = get2();
@@ -5555,7 +5600,7 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5555
5600
  },
5556
5601
  reset: () => set2({ ...getInitialState() })
5557
5602
  }), Object.is);
5558
- function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView2, nodeOrigin, children: children2 }) {
5603
+ function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView2, nodeOrigin, nodeExtent, children: children2 }) {
5559
5604
  const [store] = useState(() => createStore({
5560
5605
  nodes,
5561
5606
  edges,
@@ -5564,12 +5609,13 @@ function ReactFlowProvider({ initialNodes: nodes, initialEdges: edges, defaultNo
5564
5609
  width,
5565
5610
  height,
5566
5611
  fitView: fitView2,
5567
- nodeOrigin
5612
+ nodeOrigin,
5613
+ nodeExtent
5568
5614
  }));
5569
5615
  return jsx(Provider$1, { value: store, children: jsx(BatchProvider, { children: children2 }) });
5570
5616
  }
5571
- function Wrapper({ children: children2, nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView2, nodeOrigin }) {
5572
- return useContext(StoreContext) ? jsx(Fragment, { children: children2 }) : jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView2, nodeOrigin, children: children2 });
5617
+ function Wrapper({ children: children2, nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView2, nodeOrigin, nodeExtent }) {
5618
+ return useContext(StoreContext) ? jsx(Fragment, { children: children2 }) : jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes, defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView2, nodeOrigin, nodeExtent, children: children2 });
5573
5619
  }
5574
5620
  const wrapperStyle = {
5575
5621
  width: "100%",
@@ -5580,7 +5626,7 @@ const wrapperStyle = {
5580
5626
  };
5581
5627
  function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes, edgeTypes, onNodeClick, onEdgeClick, onInit, onMove, onMoveStart, onMoveEnd, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onNodesDelete, onEdgesDelete, onDelete, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onBeforeDelete, connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, deleteKeyCode = "Backspace", selectionKeyCode = "Shift", selectionOnDrag = !1, selectionMode = SelectionMode.Full, panActivationKeyCode = "Space", multiSelectionKeyCode = isMacOs() ? "Meta" : "Control", zoomActivationKeyCode = isMacOs() ? "Meta" : "Control", snapToGrid, snapGrid, onlyRenderVisibleElements = !1, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesReconnectable, elementsSelectable = !0, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = !0, nodeExtent, defaultMarkerColor = "#b1b1b7", zoomOnScroll = !0, zoomOnPinch = !0, panOnScroll = !1, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = !0, panOnDrag = !0, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, paneClickDistance = 0, nodeClickDistance = 0, children: children2, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius = 10, onNodesChange, onEdgesChange, noDragClassName = "nodrag", noWheelClassName = "nowheel", noPanClassName = "nopan", fitView: fitView2, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = !1, autoPanOnConnect, autoPanOnNodeDrag, autoPanSpeed, connectionRadius, isValidConnection, onError, style: style2, id: id2, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = "light", debug, ...rest }, ref) {
5582
5628
  const rfId = id2 || "1", colorModeClassName = useColorModeClass(colorMode);
5583
- return jsx("div", { ...rest, style: { ...style2, ...wrapperStyle }, ref, className: cc(["react-flow", className, colorModeClassName]), "data-testid": "rf__wrapper", id: id2, children: jsxs(Wrapper, { nodes, edges, width, height, fitView: fitView2, nodeOrigin, children: [jsx(GraphView, { onInit, onNodeClick, onEdgeClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, nodeTypes, edgeTypes, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, deleteKeyCode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent, minZoom, maxZoom, preventScrolling, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, paneClickDistance, nodeClickDistance, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, defaultMarkerColor, noDragClassName, noWheelClassName, noPanClassName, rfId, disableKeyboardA11y, nodeExtent, viewport, onViewportChange }), jsx(StoreUpdater, { nodes, edges, defaultNodes, defaultEdges, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, nodesDraggable, nodesConnectable, nodesFocusable, edgesFocusable, edgesReconnectable, elementsSelectable, elevateNodesOnSelect, elevateEdgesOnSelect, minZoom, maxZoom, nodeExtent, onNodesChange, onEdgesChange, snapToGrid, snapGrid, connectionMode, translateExtent, connectOnClick, defaultEdgeOptions, fitView: fitView2, fitViewOptions, onNodesDelete, onEdgesDelete, onDelete, onNodeDragStart, onNodeDrag, onNodeDragStop, onSelectionDrag, onSelectionDragStart, onSelectionDragStop, onMove, onMoveStart, onMoveEnd, noPanClassName, nodeOrigin, rfId, autoPanOnConnect, autoPanOnNodeDrag, autoPanSpeed, onError, connectionRadius, isValidConnection, selectNodesOnDrag, nodeDragThreshold, onBeforeDelete, paneClickDistance, debug }), jsx(SelectionListener, { onSelectionChange }), children2, jsx(Attribution, { proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId, disableKeyboardA11y })] }) });
5629
+ return jsx("div", { ...rest, style: { ...style2, ...wrapperStyle }, ref, className: cc(["react-flow", className, colorModeClassName]), "data-testid": "rf__wrapper", id: id2, children: jsxs(Wrapper, { nodes, edges, width, height, fitView: fitView2, nodeOrigin, nodeExtent, children: [jsx(GraphView, { onInit, onNodeClick, onEdgeClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, nodeTypes, edgeTypes, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, deleteKeyCode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent, minZoom, maxZoom, preventScrolling, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, paneClickDistance, nodeClickDistance, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, defaultMarkerColor, noDragClassName, noWheelClassName, noPanClassName, rfId, disableKeyboardA11y, nodeExtent, viewport, onViewportChange }), jsx(StoreUpdater, { nodes, edges, defaultNodes, defaultEdges, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, nodesDraggable, nodesConnectable, nodesFocusable, edgesFocusable, edgesReconnectable, elementsSelectable, elevateNodesOnSelect, elevateEdgesOnSelect, minZoom, maxZoom, nodeExtent, onNodesChange, onEdgesChange, snapToGrid, snapGrid, connectionMode, translateExtent, connectOnClick, defaultEdgeOptions, fitView: fitView2, fitViewOptions, onNodesDelete, onEdgesDelete, onDelete, onNodeDragStart, onNodeDrag, onNodeDragStop, onSelectionDrag, onSelectionDragStart, onSelectionDragStop, onMove, onMoveStart, onMoveEnd, noPanClassName, nodeOrigin, rfId, autoPanOnConnect, autoPanOnNodeDrag, autoPanSpeed, onError, connectionRadius, isValidConnection, selectNodesOnDrag, nodeDragThreshold, onBeforeDelete, paneClickDistance, debug }), jsx(SelectionListener, { onSelectionChange }), children2, jsx(Attribution, { proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId, disableKeyboardA11y })] }) });
5584
5630
  }
5585
5631
  var index = fixedForwardRef(ReactFlow);
5586
5632
  const selector$6 = (s) => s.domNode?.querySelector(".react-flow__edgelabel-renderer");
@@ -5660,7 +5706,10 @@ function BackgroundComponent({
5660
5706
  className,
5661
5707
  patternClassName
5662
5708
  }) {
5663
- const ref = useRef(null), { transform: transform2, patternId } = useStore(selector$3, shallow$1), patternSize = size || defaultSize[variant], isDots = variant === BackgroundVariant.Dots, isCross = variant === BackgroundVariant.Cross, gapXY = Array.isArray(gap) ? gap : [gap, gap], scaledGap = [gapXY[0] * transform2[2] || 1, gapXY[1] * transform2[2] || 1], scaledSize = patternSize * transform2[2], offsetXY = Array.isArray(offset) ? offset : [offset, offset], scaledOffset = [offsetXY[0] * transform2[2] || 1, offsetXY[1] * transform2[2] || 1], patternDimensions = isCross ? [scaledSize, scaledSize] : scaledGap, _patternId = `${patternId}${id2 || ""}`;
5709
+ const ref = useRef(null), { transform: transform2, patternId } = useStore(selector$3, shallow$1), patternSize = size || defaultSize[variant], isDots = variant === BackgroundVariant.Dots, isCross = variant === BackgroundVariant.Cross, gapXY = Array.isArray(gap) ? gap : [gap, gap], scaledGap = [gapXY[0] * transform2[2] || 1, gapXY[1] * transform2[2] || 1], scaledSize = patternSize * transform2[2], offsetXY = Array.isArray(offset) ? offset : [offset, offset], patternDimensions = isCross ? [scaledSize, scaledSize] : scaledGap, scaledOffset = [
5710
+ offsetXY[0] * transform2[2] || 1 + patternDimensions[0] / 2,
5711
+ offsetXY[1] * transform2[2] || 1 + patternDimensions[1] / 2
5712
+ ], _patternId = `${patternId}${id2 || ""}`;
5664
5713
  return jsxs("svg", { className: cc(["react-flow__background", className]), style: {
5665
5714
  ...style2,
5666
5715
  ...containerStyle,
@@ -5742,18 +5791,17 @@ function MiniMapNodes({
5742
5791
  )) });
5743
5792
  }
5744
5793
  function NodeComponentWrapperInner({ id: id2, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick }) {
5745
- const { node, x, y } = useStore((s) => {
5746
- const node2 = s.nodeLookup.get(id2), { x: x2, y: y2 } = node2.internals.positionAbsolute;
5794
+ const { node, x, y, width, height } = useStore((s) => {
5795
+ const node2 = s.nodeLookup.get(id2), { x: x2, y: y2 } = node2.internals.positionAbsolute, { width: width2, height: height2 } = getNodeDimensions(node2);
5747
5796
  return {
5748
5797
  node: node2,
5749
5798
  x: x2,
5750
- y: y2
5799
+ y: y2,
5800
+ width: width2,
5801
+ height: height2
5751
5802
  };
5752
5803
  }, shallow$1);
5753
- if (!node || node.hidden || !nodeHasDimensions(node))
5754
- return null;
5755
- const { width, height } = getNodeDimensions(node);
5756
- return jsx(NodeComponent, { x, y, width, height, style: node.style, selected: !!node.selected, className: nodeClassNameFunc(node), color: nodeColorFunc(node), borderRadius: nodeBorderRadius, strokeColor: nodeStrokeColorFunc(node), strokeWidth: nodeStrokeWidth, shapeRendering, onClick, id: node.id });
5804
+ return !node || node.hidden || !nodeHasDimensions(node) ? null : jsx(NodeComponent, { x, y, width, height, style: node.style, selected: !!node.selected, className: nodeClassNameFunc(node), color: nodeColorFunc(node), borderRadius: nodeBorderRadius, strokeColor: nodeStrokeColorFunc(node), strokeWidth: nodeStrokeWidth, shapeRendering, onClick, id: node.id });
5757
5805
  }
5758
5806
  const NodeComponentWrapper = memo(NodeComponentWrapperInner);
5759
5807
  var MiniMapNodes$1 = memo(MiniMapNodes);