@uipath/apollo-react 4.18.0 → 4.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/canvas/components/AddNodePanel/AddNodeManager.helpers.cjs +60 -4
  2. package/dist/canvas/components/AddNodePanel/AddNodeManager.helpers.d.ts.map +1 -1
  3. package/dist/canvas/components/AddNodePanel/AddNodeManager.helpers.js +61 -5
  4. package/dist/canvas/components/AddNodePanel/createAddNodePreview.cjs +19 -0
  5. package/dist/canvas/components/AddNodePanel/createAddNodePreview.d.ts.map +1 -1
  6. package/dist/canvas/components/AddNodePanel/createAddNodePreview.js +19 -0
  7. package/dist/canvas/components/LoopNode/LoopNode.cjs +13 -13
  8. package/dist/canvas/components/LoopNode/LoopNode.d.ts.map +1 -1
  9. package/dist/canvas/components/LoopNode/LoopNode.js +13 -13
  10. package/dist/canvas/components/LoopNode/LoopNodePreview.cjs +3 -1
  11. package/dist/canvas/components/LoopNode/LoopNodePreview.d.ts.map +1 -1
  12. package/dist/canvas/components/LoopNode/LoopNodePreview.js +3 -1
  13. package/dist/canvas/storybook-utils/manifests/node-definitions.d.ts.map +1 -1
  14. package/dist/canvas/storybook-utils/mocks/nodes.d.ts +6 -6
  15. package/dist/canvas/storybook-utils/mocks/nodes.d.ts.map +1 -1
  16. package/dist/canvas/utils/NodeUtils.cjs +15 -3
  17. package/dist/canvas/utils/NodeUtils.d.ts +5 -1
  18. package/dist/canvas/utils/NodeUtils.d.ts.map +1 -1
  19. package/dist/canvas/utils/NodeUtils.js +15 -3
  20. package/dist/canvas/utils/container.cjs +73 -42
  21. package/dist/canvas/utils/container.d.ts +17 -4
  22. package/dist/canvas/utils/container.d.ts.map +1 -1
  23. package/dist/canvas/utils/container.js +69 -41
  24. package/dist/canvas/utils/createPreviewGraph.cjs +14 -2
  25. package/dist/canvas/utils/createPreviewGraph.d.ts +2 -0
  26. package/dist/canvas/utils/createPreviewGraph.d.ts.map +1 -1
  27. package/dist/canvas/utils/createPreviewGraph.js +14 -2
  28. package/dist/canvas/utils/createPreviewNode.cjs +8 -5
  29. package/dist/canvas/utils/createPreviewNode.d.ts +21 -7
  30. package/dist/canvas/utils/createPreviewNode.d.ts.map +1 -1
  31. package/dist/canvas/utils/createPreviewNode.js +8 -5
  32. package/package.json +3 -3
@@ -29,9 +29,12 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  alignNodeToPreview: ()=>alignNodeToPreview
30
30
  });
31
31
  const react_cjs_namespaceObject = require("../../xyflow/react.cjs");
32
+ const external_constants_cjs_namespaceObject = require("../../constants.cjs");
32
33
  const index_cjs_namespaceObject = require("../../utils/index.cjs");
33
34
  const collapse_cjs_namespaceObject = require("../../utils/collapse.cjs");
34
35
  const container_cjs_namespaceObject = require("../../utils/container.cjs");
36
+ const NodeUtils_cjs_namespaceObject = require("../../utils/NodeUtils.cjs");
37
+ const TOP_LEVEL_INSERTION_GAP_PX = 5 * external_constants_cjs_namespaceObject.GRID_SPACING;
35
38
  function getOriginalEdge(previewNode) {
36
39
  return previewNode?.data?.originalEdge ?? null;
37
40
  }
@@ -106,11 +109,57 @@ function resolveScopedCollisions(nodes, insertedNode, options) {
106
109
  insertedNode: resolvedSiblingById.get(insertedNode.id)
107
110
  };
108
111
  }
112
+ function shiftForEdgeInsertion({ nodes, edges, previewNode, insertedNode, getNodeSize }) {
113
+ const originalEdge = getOriginalEdge(previewNode);
114
+ if (!originalEdge) return null;
115
+ const targetNode = nodes.find((node)=>node.id === originalEdge.target);
116
+ if (!targetNode || targetNode.parentId !== insertedNode.parentId) return null;
117
+ const insertedSize = getNodeSize(insertedNode);
118
+ let insertedX = insertedNode.position.x;
119
+ const sourceNode = nodes.find((node)=>node.id === originalEdge.source);
120
+ if (sourceNode && sourceNode.parentId === insertedNode.parentId) {
121
+ const sourceSize = getNodeSize(sourceNode);
122
+ const requiredInsertedLeft = sourceNode.position.x + sourceSize.width + TOP_LEVEL_INSERTION_GAP_PX;
123
+ if (insertedX < requiredInsertedLeft) insertedX = (0, NodeUtils_cjs_namespaceObject.snapUpToGrid)(requiredInsertedLeft);
124
+ }
125
+ const isBackEdge = void 0 !== sourceNode && sourceNode.parentId === insertedNode.parentId && sourceNode.position.x >= targetNode.position.x;
126
+ const requiredTargetLeft = insertedX + insertedSize.width + TOP_LEVEL_INSERTION_GAP_PX;
127
+ const downstreamShift = !isBackEdge && targetNode.position.x < requiredTargetLeft ? (0, NodeUtils_cjs_namespaceObject.snapUpToGrid)(requiredTargetLeft - targetNode.position.x) : 0;
128
+ const chainIds = downstreamShift > 0 ? new Set((0, container_cjs_namespaceObject.collectLinearDownstreamSiblings)({
129
+ startNodeId: targetNode.id,
130
+ parentId: insertedNode.parentId,
131
+ nodes,
132
+ edges
133
+ })) : new Set();
134
+ chainIds.delete(originalEdge.source);
135
+ const insertedXChanged = insertedX !== insertedNode.position.x;
136
+ if (!insertedXChanged && 0 === chainIds.size) return null;
137
+ const updatedInsertedNode = insertedXChanged ? {
138
+ ...insertedNode,
139
+ position: {
140
+ x: insertedX,
141
+ y: insertedNode.position.y
142
+ }
143
+ } : insertedNode;
144
+ const updatedNodes = nodes.map((node)=>{
145
+ if (node.id === insertedNode.id) return updatedInsertedNode;
146
+ if (chainIds.has(node.id)) return {
147
+ ...node,
148
+ position: {
149
+ x: node.position.x + downstreamShift,
150
+ y: node.position.y
151
+ }
152
+ };
153
+ return node;
154
+ });
155
+ return {
156
+ nodes: updatedNodes,
157
+ insertedNode: updatedInsertedNode
158
+ };
159
+ }
109
160
  function placeAddedNode({ nodes, edges, previewNode, insertedNode, registry, ignoredNodeTypes }) {
110
161
  const getDimensions = (node)=>getManifestAwareNodeDimensions(registry, node);
111
- const placement = (0, container_cjs_namespaceObject.getContainerPlacement)({
112
- previewNode
113
- });
162
+ const placement = (0, container_cjs_namespaceObject.getContainerPlacement)(previewNode);
114
163
  if (placement) {
115
164
  const containerNode = nodes.find((node)=>node.id === placement.containerId);
116
165
  if (!containerNode) return resolveScopedCollisions(nodes, insertedNode, {
@@ -136,7 +185,14 @@ function placeAddedNode({ nodes, edges, previewNode, insertedNode, registry, ign
136
185
  insertedNode: resolvedNodes.find((node)=>node.id === insertedNode.id)
137
186
  };
138
187
  }
139
- return resolveScopedCollisions(nodes, insertedNode, {
188
+ const shifted = shiftForEdgeInsertion({
189
+ nodes,
190
+ edges,
191
+ previewNode,
192
+ insertedNode,
193
+ getNodeSize: getDimensions
194
+ });
195
+ return resolveScopedCollisions(shifted?.nodes ?? nodes, shifted?.insertedNode ?? insertedNode, {
140
196
  ignoredNodeTypes,
141
197
  getNodeSize: getDimensions
142
198
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AddNodeManager.helpers.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/AddNodeManager.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAajD,UAAU,sBAAsB;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,IAAI,CAAC;CACpB;AAMD,wBAAgB,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAEjF;AAmCD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,IAAI,EACjB,kBAAkB,EAAE,yBAAyB,EAAE,EAC/C,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC,IAAI,CA2DN;AA6BD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,gBAAgB,GACjB,EAAE;IACD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,IAAI,CAAC;IAClB,YAAY,EAAE,IAAI,CAAC;IACnB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG,sBAAsB,CA8CzB"}
1
+ {"version":3,"file":"AddNodeManager.helpers.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/AddNodeManager.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAG3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAsBjD,UAAU,sBAAsB;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,IAAI,CAAC;CACpB;AAMD,wBAAgB,eAAe,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAEjF;AAmCD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,IAAI,EACjB,kBAAkB,EAAE,yBAAyB,EAAE,EAC/C,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC,IAAI,CA2DN;AAqID,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,gBAAgB,GACjB,EAAE;IACD,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,IAAI,CAAC;IAClB,YAAY,EAAE,IAAI,CAAC;IACnB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG,sBAAsB,CAsDzB"}
@@ -1,7 +1,10 @@
1
1
  import { Position } from "../../xyflow/react.js";
2
+ import { GRID_SPACING } from "../../constants.js";
2
3
  import { resolveCollisions } from "../../utils/index.js";
3
4
  import { getExpandedSize } from "../../utils/collapse.js";
4
- import { getContainerFitGeometry, getContainerPlacement, getContainerSafeArea, getNodeDimensions, isContainerNodeManifest, placeContainerNode } from "../../utils/container.js";
5
+ import { collectLinearDownstreamSiblings, getContainerFitGeometry, getContainerPlacement, getContainerSafeArea, getNodeDimensions, isContainerNodeManifest, placeContainerNode } from "../../utils/container.js";
6
+ import { snapUpToGrid } from "../../utils/NodeUtils.js";
7
+ const TOP_LEVEL_INSERTION_GAP_PX = 5 * GRID_SPACING;
5
8
  function getOriginalEdge(previewNode) {
6
9
  return previewNode?.data?.originalEdge ?? null;
7
10
  }
@@ -76,11 +79,57 @@ function resolveScopedCollisions(nodes, insertedNode, options) {
76
79
  insertedNode: resolvedSiblingById.get(insertedNode.id)
77
80
  };
78
81
  }
82
+ function shiftForEdgeInsertion({ nodes, edges, previewNode, insertedNode, getNodeSize }) {
83
+ const originalEdge = getOriginalEdge(previewNode);
84
+ if (!originalEdge) return null;
85
+ const targetNode = nodes.find((node)=>node.id === originalEdge.target);
86
+ if (!targetNode || targetNode.parentId !== insertedNode.parentId) return null;
87
+ const insertedSize = getNodeSize(insertedNode);
88
+ let insertedX = insertedNode.position.x;
89
+ const sourceNode = nodes.find((node)=>node.id === originalEdge.source);
90
+ if (sourceNode && sourceNode.parentId === insertedNode.parentId) {
91
+ const sourceSize = getNodeSize(sourceNode);
92
+ const requiredInsertedLeft = sourceNode.position.x + sourceSize.width + TOP_LEVEL_INSERTION_GAP_PX;
93
+ if (insertedX < requiredInsertedLeft) insertedX = snapUpToGrid(requiredInsertedLeft);
94
+ }
95
+ const isBackEdge = void 0 !== sourceNode && sourceNode.parentId === insertedNode.parentId && sourceNode.position.x >= targetNode.position.x;
96
+ const requiredTargetLeft = insertedX + insertedSize.width + TOP_LEVEL_INSERTION_GAP_PX;
97
+ const downstreamShift = !isBackEdge && targetNode.position.x < requiredTargetLeft ? snapUpToGrid(requiredTargetLeft - targetNode.position.x) : 0;
98
+ const chainIds = downstreamShift > 0 ? new Set(collectLinearDownstreamSiblings({
99
+ startNodeId: targetNode.id,
100
+ parentId: insertedNode.parentId,
101
+ nodes,
102
+ edges
103
+ })) : new Set();
104
+ chainIds.delete(originalEdge.source);
105
+ const insertedXChanged = insertedX !== insertedNode.position.x;
106
+ if (!insertedXChanged && 0 === chainIds.size) return null;
107
+ const updatedInsertedNode = insertedXChanged ? {
108
+ ...insertedNode,
109
+ position: {
110
+ x: insertedX,
111
+ y: insertedNode.position.y
112
+ }
113
+ } : insertedNode;
114
+ const updatedNodes = nodes.map((node)=>{
115
+ if (node.id === insertedNode.id) return updatedInsertedNode;
116
+ if (chainIds.has(node.id)) return {
117
+ ...node,
118
+ position: {
119
+ x: node.position.x + downstreamShift,
120
+ y: node.position.y
121
+ }
122
+ };
123
+ return node;
124
+ });
125
+ return {
126
+ nodes: updatedNodes,
127
+ insertedNode: updatedInsertedNode
128
+ };
129
+ }
79
130
  function placeAddedNode({ nodes, edges, previewNode, insertedNode, registry, ignoredNodeTypes }) {
80
131
  const getDimensions = (node)=>getManifestAwareNodeDimensions(registry, node);
81
- const placement = getContainerPlacement({
82
- previewNode
83
- });
132
+ const placement = getContainerPlacement(previewNode);
84
133
  if (placement) {
85
134
  const containerNode = nodes.find((node)=>node.id === placement.containerId);
86
135
  if (!containerNode) return resolveScopedCollisions(nodes, insertedNode, {
@@ -106,7 +155,14 @@ function placeAddedNode({ nodes, edges, previewNode, insertedNode, registry, ign
106
155
  insertedNode: resolvedNodes.find((node)=>node.id === insertedNode.id)
107
156
  };
108
157
  }
109
- return resolveScopedCollisions(nodes, insertedNode, {
158
+ const shifted = shiftForEdgeInsertion({
159
+ nodes,
160
+ edges,
161
+ previewNode,
162
+ insertedNode,
163
+ getNodeSize: getDimensions
164
+ });
165
+ return resolveScopedCollisions(shifted?.nodes ?? nodes, shifted?.insertedNode ?? insertedNode, {
110
166
  ignoredNodeTypes,
111
167
  getNodeSize: getDimensions
112
168
  });
@@ -28,7 +28,24 @@ __webpack_require__.d(__webpack_exports__, {
28
28
  });
29
29
  const react_cjs_namespaceObject = require("../../xyflow/react.cjs");
30
30
  const createPreviewGraph_cjs_namespaceObject = require("../../utils/createPreviewGraph.cjs");
31
+ const manifest_resolver_cjs_namespaceObject = require("../../utils/manifest-resolver.cjs");
31
32
  const LoopNode_helpers_cjs_namespaceObject = require("../LoopNode/LoopNode.helpers.cjs");
33
+ function buildSourceBoundaryResolver(sourceNodeId, reactFlowInstance, getManifestForNode) {
34
+ const sourceNode = reactFlowInstance.getNode(sourceNodeId);
35
+ if (!sourceNode) return;
36
+ const manifest = getManifestForNode(sourceNode);
37
+ if (!manifest?.handleConfiguration) return;
38
+ const resolvedGroups = (0, manifest_resolver_cjs_namespaceObject.resolveHandles)(manifest.handleConfiguration, {
39
+ ...sourceNode.data,
40
+ nodeId: sourceNode.id
41
+ });
42
+ const handleToBoundary = new Map();
43
+ for (const group of resolvedGroups){
44
+ const boundary = group.boundary ?? 'outer';
45
+ for (const handle of group.handles)handleToBoundary.set(handle.id, boundary);
46
+ }
47
+ return (handleId)=>handleToBoundary.get(handleId);
48
+ }
32
49
  function createAddNodePreview(sourceNodeId, sourceHandleId, reactFlowInstance, handlePosition = react_cjs_namespaceObject.Position.Right, sourceHandleType = 'source', ignoredNodeTypes = [], options = {}) {
33
50
  const source = {
34
51
  nodeId: sourceNodeId,
@@ -40,12 +57,14 @@ function createAddNodePreview(sourceNodeId, sourceHandleId, reactFlowInstance, h
40
57
  reactFlowInstance,
41
58
  getManifestForNode: options.getManifestForNode
42
59
  }) : null;
60
+ const sourceBoundaryOf = options.getManifestForNode ? buildSourceBoundaryResolver(sourceNodeId, reactFlowInstance, options.getManifestForNode) : void 0;
43
61
  (0, createPreviewGraph_cjs_namespaceObject.showPreviewGraph)({
44
62
  source,
45
63
  reactFlowInstance,
46
64
  sourceHandleType,
47
65
  handlePosition,
48
66
  ignoredNodeTypes,
67
+ sourceBoundaryOf,
49
68
  ...overrides ?? {}
50
69
  });
51
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createAddNodePreview.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/createAddNodePreview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAE5F,OAAO,EACL,KAAK,gCAAgC,EAEtC,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,gCAAgC,CAAC;CACvD;AAcD,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,EACpC,cAAc,GAAE,QAAyB,EACzC,gBAAgB,GAAE,QAAQ,GAAG,QAAmB,EAChD,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,qBAA0B,GAClC,IAAI,CAsBN"}
1
+ {"version":3,"file":"createAddNodePreview.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/createAddNodePreview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAI5F,OAAO,EACL,KAAK,gCAAgC,EAEtC,MAAM,8BAA8B,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,gCAAgC,CAAC;CACvD;AAoDD,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,EACpC,cAAc,GAAE,QAAyB,EACzC,gBAAgB,GAAE,QAAQ,GAAG,QAAmB,EAChD,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,qBAA0B,GAClC,IAAI,CA0BN"}
@@ -1,6 +1,23 @@
1
1
  import { Position } from "../../xyflow/react.js";
2
2
  import { showPreviewGraph } from "../../utils/createPreviewGraph.js";
3
+ import { resolveHandles } from "../../utils/manifest-resolver.js";
3
4
  import { resolveContainerAddNodePreview } from "../LoopNode/LoopNode.helpers.js";
5
+ function buildSourceBoundaryResolver(sourceNodeId, reactFlowInstance, getManifestForNode) {
6
+ const sourceNode = reactFlowInstance.getNode(sourceNodeId);
7
+ if (!sourceNode) return;
8
+ const manifest = getManifestForNode(sourceNode);
9
+ if (!manifest?.handleConfiguration) return;
10
+ const resolvedGroups = resolveHandles(manifest.handleConfiguration, {
11
+ ...sourceNode.data,
12
+ nodeId: sourceNode.id
13
+ });
14
+ const handleToBoundary = new Map();
15
+ for (const group of resolvedGroups){
16
+ const boundary = group.boundary ?? 'outer';
17
+ for (const handle of group.handles)handleToBoundary.set(handle.id, boundary);
18
+ }
19
+ return (handleId)=>handleToBoundary.get(handleId);
20
+ }
4
21
  function createAddNodePreview(sourceNodeId, sourceHandleId, reactFlowInstance, handlePosition = Position.Right, sourceHandleType = 'source', ignoredNodeTypes = [], options = {}) {
5
22
  const source = {
6
23
  nodeId: sourceNodeId,
@@ -12,12 +29,14 @@ function createAddNodePreview(sourceNodeId, sourceHandleId, reactFlowInstance, h
12
29
  reactFlowInstance,
13
30
  getManifestForNode: options.getManifestForNode
14
31
  }) : null;
32
+ const sourceBoundaryOf = options.getManifestForNode ? buildSourceBoundaryResolver(sourceNodeId, reactFlowInstance, options.getManifestForNode) : void 0;
15
33
  showPreviewGraph({
16
34
  source,
17
35
  reactFlowInstance,
18
36
  sourceHandleType,
19
37
  handlePosition,
20
38
  ignoredNodeTypes,
39
+ sourceBoundaryOf,
21
40
  ...overrides ?? {}
22
41
  });
23
42
  }
@@ -272,9 +272,14 @@ function LoopNodeComponent(props) {
272
272
  }),
273
273
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(BodyFrame, {
274
274
  isEmpty: showEmptyStateButton,
275
- isLoading: isLoading,
276
- onAddFirstChild: handleEmptyClick
275
+ isLoading: isLoading
277
276
  }),
277
+ showEmptyStateButton ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
278
+ className: (0, apollo_wind_namespaceObject.cn)('pointer-events-none absolute left-1/2 top-1/2', '-translate-x-1/2 -translate-y-1/2'),
279
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(EmptyState, {
280
+ onAddFirstChild: handleEmptyClick
281
+ })
282
+ }) : null,
278
283
  toolbarConfig && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbar_index_cjs_namespaceObject.NodeToolbar, {
279
284
  nodeId: id,
280
285
  config: toolbarConfig,
@@ -356,19 +361,14 @@ function EmptyState({ onAddFirstChild }) {
356
361
  })
357
362
  });
358
363
  }
359
- function BodyFrame({ isEmpty, isLoading, onAddFirstChild }) {
360
- return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
364
+ function BodyFrame({ isEmpty, isLoading }) {
365
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
361
366
  "data-testid": "loop-body-frame",
362
367
  "data-empty": isEmpty ? 'true' : 'false',
363
- className: (0, apollo_wind_namespaceObject.cn)('relative m-2.5 flex flex-1 rounded-xl border-[1.5px] border-dashed border-border-subtle bg-transparent', 'pointer-events-none', isEmpty && 'items-center justify-center'),
364
- children: [
365
- isLoading ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
366
- className: "m-6 h-14 w-full animate-pulse rounded-[18px] bg-(--canvas-background-overlay)"
367
- }) : null,
368
- isEmpty ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(EmptyState, {
369
- onAddFirstChild: onAddFirstChild
370
- }) : null
371
- ]
368
+ className: (0, apollo_wind_namespaceObject.cn)('relative m-2.5 flex flex-1 rounded-xl border-[1.5px] border-dashed border-border-subtle bg-transparent', 'pointer-events-none'),
369
+ children: isLoading ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
370
+ className: "m-6 h-14 w-full animate-pulse rounded-[18px] bg-(--canvas-background-overlay)"
371
+ }) : null
372
372
  });
373
373
  }
374
374
  function ResizeControls({ onResize }) {
@@ -1 +1 @@
1
- {"version":3,"file":"LoopNode.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/LoopNode/LoopNode.tsx"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAyEtD,iBAAS,iBAAiB,CAAC,KAAK,EAAE,aAAa,2CA0N9C;AAED,eAAO,MAAM,QAAQ,+DAA0B,CAAC"}
1
+ {"version":3,"file":"LoopNode.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/LoopNode/LoopNode.tsx"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAyEtD,iBAAS,iBAAiB,CAAC,KAAK,EAAE,aAAa,2CAgO9C;AAED,eAAO,MAAM,QAAQ,+DAA0B,CAAC"}
@@ -244,9 +244,14 @@ function LoopNodeComponent(props) {
244
244
  }),
245
245
  /*#__PURE__*/ jsx(BodyFrame, {
246
246
  isEmpty: showEmptyStateButton,
247
- isLoading: isLoading,
248
- onAddFirstChild: handleEmptyClick
247
+ isLoading: isLoading
249
248
  }),
249
+ showEmptyStateButton ? /*#__PURE__*/ jsx("div", {
250
+ className: cn('pointer-events-none absolute left-1/2 top-1/2', '-translate-x-1/2 -translate-y-1/2'),
251
+ children: /*#__PURE__*/ jsx(EmptyState, {
252
+ onAddFirstChild: handleEmptyClick
253
+ })
254
+ }) : null,
250
255
  toolbarConfig && /*#__PURE__*/ jsx(NodeToolbar, {
251
256
  nodeId: id,
252
257
  config: toolbarConfig,
@@ -328,19 +333,14 @@ function EmptyState({ onAddFirstChild }) {
328
333
  })
329
334
  });
330
335
  }
331
- function BodyFrame({ isEmpty, isLoading, onAddFirstChild }) {
332
- return /*#__PURE__*/ jsxs("div", {
336
+ function BodyFrame({ isEmpty, isLoading }) {
337
+ return /*#__PURE__*/ jsx("div", {
333
338
  "data-testid": "loop-body-frame",
334
339
  "data-empty": isEmpty ? 'true' : 'false',
335
- className: cn('relative m-2.5 flex flex-1 rounded-xl border-[1.5px] border-dashed border-border-subtle bg-transparent', 'pointer-events-none', isEmpty && 'items-center justify-center'),
336
- children: [
337
- isLoading ? /*#__PURE__*/ jsx("div", {
338
- className: "m-6 h-14 w-full animate-pulse rounded-[18px] bg-(--canvas-background-overlay)"
339
- }) : null,
340
- isEmpty ? /*#__PURE__*/ jsx(EmptyState, {
341
- onAddFirstChild: onAddFirstChild
342
- }) : null
343
- ]
340
+ className: cn('relative m-2.5 flex flex-1 rounded-xl border-[1.5px] border-dashed border-border-subtle bg-transparent', 'pointer-events-none'),
341
+ children: isLoading ? /*#__PURE__*/ jsx("div", {
342
+ className: "m-6 h-14 w-full animate-pulse rounded-[18px] bg-(--canvas-background-overlay)"
343
+ }) : null
344
344
  });
345
345
  }
346
346
  function ResizeControls({ onResize }) {
@@ -26,6 +26,7 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  showCenteredContainerPreview: ()=>showCenteredContainerPreview
28
28
  });
29
+ const container_cjs_namespaceObject = require("../../utils/container.cjs");
29
30
  const createPreviewGraph_cjs_namespaceObject = require("../../utils/createPreviewGraph.cjs");
30
31
  const NodeUtils_cjs_namespaceObject = require("../../utils/NodeUtils.cjs");
31
32
  const external_LoopNode_helpers_cjs_namespaceObject = require("./LoopNode.helpers.cjs");
@@ -35,9 +36,10 @@ function showCenteredContainerPreview({ containerId, reactFlowInstance, previewH
35
36
  const allNodes = reactFlowInstance.getNodes();
36
37
  const containerAbsolutePosition = (0, NodeUtils_cjs_namespaceObject.getAbsolutePosition)(containerNode, allNodes);
37
38
  const relativeCenter = (0, external_LoopNode_helpers_cjs_namespaceObject.getContainerRelativeBodyCenter)(containerNode);
39
+ const containerSize = (0, container_cjs_namespaceObject.getNodeDimensions)(containerNode);
38
40
  const previewCenter = {
39
41
  x: (0, NodeUtils_cjs_namespaceObject.snapToGrid)(containerAbsolutePosition.x + relativeCenter.x),
40
- y: (0, NodeUtils_cjs_namespaceObject.snapToGrid)(containerAbsolutePosition.y + relativeCenter.y)
42
+ y: (0, NodeUtils_cjs_namespaceObject.snapToGrid)(containerAbsolutePosition.y + containerSize.height / 2)
41
43
  };
42
44
  const placement = {
43
45
  containerId,
@@ -1 +1 @@
1
- {"version":3,"file":"LoopNodePreview.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/LoopNode/LoopNodePreview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAIlF,OAAO,EACL,KAAK,iCAAiC,EAEvC,MAAM,oBAAoB,CAAC;AAE5B,wBAAgB,4BAA4B,CAAC,EAC3C,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,cAAc,EAAE,iCAAiC,CAAC;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,QAmCA"}
1
+ {"version":3,"file":"LoopNodePreview.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/LoopNode/LoopNodePreview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAIlF,OAAO,EACL,KAAK,iCAAiC,EAEvC,MAAM,oBAAoB,CAAC;AAE5B,wBAAgB,4BAA4B,CAAC,EAC3C,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,cAAc,EAAE,iCAAiC,CAAC;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,QAuCA"}
@@ -1,3 +1,4 @@
1
+ import { getNodeDimensions } from "../../utils/container.js";
1
2
  import { showPreviewGraph } from "../../utils/createPreviewGraph.js";
2
3
  import { getAbsolutePosition, snapToGrid } from "../../utils/NodeUtils.js";
3
4
  import { getContainerRelativeBodyCenter } from "./LoopNode.helpers.js";
@@ -7,9 +8,10 @@ function showCenteredContainerPreview({ containerId, reactFlowInstance, previewH
7
8
  const allNodes = reactFlowInstance.getNodes();
8
9
  const containerAbsolutePosition = getAbsolutePosition(containerNode, allNodes);
9
10
  const relativeCenter = getContainerRelativeBodyCenter(containerNode);
11
+ const containerSize = getNodeDimensions(containerNode);
10
12
  const previewCenter = {
11
13
  x: snapToGrid(containerAbsolutePosition.x + relativeCenter.x),
12
- y: snapToGrid(containerAbsolutePosition.y + relativeCenter.y)
14
+ y: snapToGrid(containerAbsolutePosition.y + containerSize.height / 2)
13
15
  };
14
16
  const placement = {
15
17
  containerId,
@@ -1 +1 @@
1
- {"version":3,"file":"node-definitions.d.ts","sourceRoot":"","sources":["../../../../src/canvas/storybook-utils/manifests/node-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,YAAY,EAi4B1C,CAAC"}
1
+ {"version":3,"file":"node-definitions.d.ts","sourceRoot":"","sources":["../../../../src/canvas/storybook-utils/manifests/node-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,YAAY,EAq4B1C,CAAC"}
@@ -17,27 +17,27 @@ export declare const NodePositions: {
17
17
  };
18
18
  readonly row2col1: {
19
19
  readonly x: 96;
20
- readonly y: 255;
20
+ readonly y: 256;
21
21
  };
22
22
  readonly row2col2: {
23
23
  readonly x: 288;
24
- readonly y: 255;
24
+ readonly y: 256;
25
25
  };
26
26
  readonly row2col3: {
27
27
  readonly x: 480;
28
- readonly y: 255;
28
+ readonly y: 256;
29
29
  };
30
30
  readonly row3col1: {
31
31
  readonly x: 96;
32
- readonly y: 414;
32
+ readonly y: 416;
33
33
  };
34
34
  readonly row3col2: {
35
35
  readonly x: 288;
36
- readonly y: 414;
36
+ readonly y: 416;
37
37
  };
38
38
  readonly row3col3: {
39
39
  readonly x: 480;
40
- readonly y: 414;
40
+ readonly y: 416;
41
41
  };
42
42
  };
43
43
  export interface CreateNodeOptions<T = Record<string, unknown>> {
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../../../src/canvas/storybook-utils/mocks/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKnF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmBhB,CAAC;AAKX,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE5D,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAEpC,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IAEjC,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,SAAS,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAE7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,eAAe,CAAC,EACZ,aAAa,GACb,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,eAAe,GACf,YAAY,CAAC;CAClB;AAsBD,wBAAgB,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAsCxB;AAiBD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAEtC,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,KAAK,CACT,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CACzF,CAAC;IAEF,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAuCvB;AAKD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAsCE,MAAM,EAAE;;;;;;;;;CAW1B,CAAC;AAkBX,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,iBAAiB,CAAC,GAC5D,IAAI,CAAC,YAAY,CAAC,EAAE,CA6BtB"}
1
+ {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../../../src/canvas/storybook-utils/mocks/nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAWnF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmBhB,CAAC;AAKX,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE5D,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,QAAQ,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAEpC,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IAEjC,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,SAAS,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QAEpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAE7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,eAAe,CAAC,EACZ,aAAa,GACb,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,eAAe,GACf,YAAY,CAAC;CAClB;AAsBD,wBAAgB,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpD,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAsCxB;AAiBD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAEtC,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,KAAK,CACT,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,SAAS,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CACzF,CAAC;IAEF,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAuCvB;AAKD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAsCE,MAAM,EAAE;;;;;;;;;CAW1B,CAAC;AAkBX,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,iBAAiB,CAAC,GAC5D,IAAI,CAAC,YAAY,CAAC,EAAE,CA6BtB"}
@@ -132,22 +132,34 @@ const resolveCollisions = (nodes, { maxIterations = 50, overlapThreshold = 0, ma
132
132
  });
133
133
  return nodes.map((n)=>resolvedMap.get(n.id) ?? n);
134
134
  };
135
- function resolveHandleContext(internalNode, handleId, handlePosition) {
135
+ function resolveHandleContext(internalNode, handleId, handlePosition, options) {
136
136
  const allHandles = [
137
137
  ...internalNode.internals.handleBounds?.source ?? [],
138
138
  ...internalNode.internals.handleBounds?.target ?? []
139
139
  ];
140
140
  const matchedHandle = allHandles.find((h)=>h.id === handleId);
141
141
  if (!matchedHandle) return;
142
+ const peers = filterRailPeers(allHandles, handleId, handlePosition, options?.boundaryOf);
142
143
  return {
143
144
  anchor: {
144
145
  x: internalNode.internals.positionAbsolute.x + matchedHandle.x + matchedHandle.width / 2,
145
146
  y: internalNode.internals.positionAbsolute.y + matchedHandle.y + matchedHandle.height / 2
146
147
  },
147
- index: getHandleIndex(handleId, handlePosition, allHandles),
148
- count: allHandles.filter((h)=>h.position === handlePosition).length
148
+ index: getHandleIndex(handleId, handlePosition, peers),
149
+ count: peers.length
149
150
  };
150
151
  }
152
+ function filterRailPeers(allHandles, handleId, handlePosition, boundaryOf) {
153
+ const samePosition = allHandles.filter((h)=>h.position === handlePosition);
154
+ if (!boundaryOf) return samePosition;
155
+ const targetBoundary = boundaryOf(handleId);
156
+ if (void 0 === targetBoundary) return samePosition;
157
+ return samePosition.filter((h)=>{
158
+ if (!h.id) return false;
159
+ const peerBoundary = boundaryOf(h.id);
160
+ return void 0 === peerBoundary || peerBoundary === targetBoundary;
161
+ });
162
+ }
151
163
  function getHandleIndex(handleId, position, allHandles) {
152
164
  const peers = allHandles.filter((h)=>h.position === position).sort((a, b)=>position === react_cjs_namespaceObject.Position.Left || position === react_cjs_namespaceObject.Position.Right ? a.y - b.y : a.x - b.x);
153
165
  const index = peers.findIndex((h)=>h.id === handleId);
@@ -35,6 +35,10 @@ export type HandleContext = {
35
35
  index: number | null;
36
36
  count: number;
37
37
  };
38
- export declare function resolveHandleContext(internalNode: InternalNode, handleId: string, handlePosition: Position): HandleContext | undefined;
38
+ export type HandleBoundaryResolver = (handleId: string) => 'outer' | 'inner' | undefined;
39
+ export interface ResolveHandleContextOptions {
40
+ boundaryOf?: HandleBoundaryResolver;
41
+ }
42
+ export declare function resolveHandleContext(internalNode: InternalNode, handleId: string, handlePosition: Position, options?: ResolveHandleContextOptions): HandleContext | undefined;
39
43
  export declare function getHandleIndex(handleId: string, position: Position, allHandles: Handle[]): number | null;
40
44
  //# sourceMappingURL=NodeUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeUtils.d.ts","sourceRoot":"","sources":["../../../src/canvas/utils/NodeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,QAAQ,EACR,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,0CAA0C,CAAC;AAQlD,eAAO,MAAM,kBAAkB,GAAI,OAAO,cAAc,YAAkC,CAAC;AAS3F,eAAO,MAAM,mBAAmB,GAAI,MAAM,IAAI,EAAE,OAAO,IAAI,EAAE,KAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAWrF,CAAC;AAeF,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,IAAI,EAAE,EACb,eAAe,EAAE,UAAU,EAC3B,YAAY,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/C,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,EAC9C,MAAM,SAAmB,EACzB,gBAAgB,GAAE,MAAM,EAAO,EAC/B,iBAAiB,GAAE;IAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CAA8B,GACvF,UAAU,CAgCZ;AAED,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAE1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,MAE5C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAE9C,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAE/D,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,yBAAyB,KAAK,IAAI,EAAE,CAAC;AAyChG,eAAO,MAAM,iBAAiB,EAAE,kBA8E/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAMF,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,QAAQ,GACvB,aAAa,GAAG,SAAS,CAgB3B;AAWD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAAE,GACnB,MAAM,GAAG,IAAI,CAQf"}
1
+ {"version":3,"file":"NodeUtils.d.ts","sourceRoot":"","sources":["../../../src/canvas/utils/NodeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,QAAQ,EACR,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,0CAA0C,CAAC;AAQlD,eAAO,MAAM,kBAAkB,GAAI,OAAO,cAAc,YAAkC,CAAC;AAS3F,eAAO,MAAM,mBAAmB,GAAI,MAAM,IAAI,EAAE,OAAO,IAAI,EAAE,KAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAWrF,CAAC;AAeF,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,IAAI,EAAE,EACb,eAAe,EAAE,UAAU,EAC3B,YAAY,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/C,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,EAC9C,MAAM,SAAmB,EACzB,gBAAgB,GAAE,MAAM,EAAO,EAC/B,iBAAiB,GAAE;IAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CAA8B,GACvF,UAAU,CAgCZ;AAED,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAE1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,MAE5C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAE9C,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,MAE/D,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,yBAAyB,KAAK,IAAI,EAAE,CAAC;AAyChG,eAAO,MAAM,iBAAiB,EAAE,kBA8E/B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AASF,MAAM,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzF,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC;AAMD,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,QAAQ,EACxB,OAAO,CAAC,EAAE,2BAA2B,GACpC,aAAa,GAAG,SAAS,CAkB3B;AAoCD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAAE,GACnB,MAAM,GAAG,IAAI,CAQf"}
@@ -95,22 +95,34 @@ const resolveCollisions = (nodes, { maxIterations = 50, overlapThreshold = 0, ma
95
95
  });
96
96
  return nodes.map((n)=>resolvedMap.get(n.id) ?? n);
97
97
  };
98
- function resolveHandleContext(internalNode, handleId, handlePosition) {
98
+ function resolveHandleContext(internalNode, handleId, handlePosition, options) {
99
99
  const allHandles = [
100
100
  ...internalNode.internals.handleBounds?.source ?? [],
101
101
  ...internalNode.internals.handleBounds?.target ?? []
102
102
  ];
103
103
  const matchedHandle = allHandles.find((h)=>h.id === handleId);
104
104
  if (!matchedHandle) return;
105
+ const peers = filterRailPeers(allHandles, handleId, handlePosition, options?.boundaryOf);
105
106
  return {
106
107
  anchor: {
107
108
  x: internalNode.internals.positionAbsolute.x + matchedHandle.x + matchedHandle.width / 2,
108
109
  y: internalNode.internals.positionAbsolute.y + matchedHandle.y + matchedHandle.height / 2
109
110
  },
110
- index: getHandleIndex(handleId, handlePosition, allHandles),
111
- count: allHandles.filter((h)=>h.position === handlePosition).length
111
+ index: getHandleIndex(handleId, handlePosition, peers),
112
+ count: peers.length
112
113
  };
113
114
  }
115
+ function filterRailPeers(allHandles, handleId, handlePosition, boundaryOf) {
116
+ const samePosition = allHandles.filter((h)=>h.position === handlePosition);
117
+ if (!boundaryOf) return samePosition;
118
+ const targetBoundary = boundaryOf(handleId);
119
+ if (void 0 === targetBoundary) return samePosition;
120
+ return samePosition.filter((h)=>{
121
+ if (!h.id) return false;
122
+ const peerBoundary = boundaryOf(h.id);
123
+ return void 0 === peerBoundary || peerBoundary === targetBoundary;
124
+ });
125
+ }
114
126
  function getHandleIndex(handleId, position, allHandles) {
115
127
  const peers = allHandles.filter((h)=>h.position === position).sort((a, b)=>position === Position.Left || position === Position.Right ? a.y - b.y : a.x - b.x);
116
128
  const index = peers.findIndex((h)=>h.id === handleId);