@flowgram.ai/free-layout-core 0.1.12 → 0.1.14

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 (42) hide show
  1. package/dist/esm/{chunk-DE4324TR.js → chunk-IYUZVBAO.js} +1 -1
  2. package/dist/esm/chunk-IYUZVBAO.js.map +1 -0
  3. package/dist/esm/chunk-LJH3TSLZ.js +7 -0
  4. package/dist/esm/chunk-LJH3TSLZ.js.map +1 -0
  5. package/dist/esm/chunk-TQLT57GW.js +1 -0
  6. package/dist/esm/chunk-TQLT57GW.js.map +1 -0
  7. package/dist/esm/index.js +157 -60
  8. package/dist/esm/index.js.map +1 -1
  9. package/dist/esm/typings/index.js +10 -5
  10. package/dist/esm/typings/workflow-drag.js +2 -0
  11. package/dist/esm/typings/workflow-drag.js.map +1 -0
  12. package/dist/esm/typings/workflow-operation.js +8 -0
  13. package/dist/esm/typings/workflow-operation.js.map +1 -0
  14. package/dist/index.d.mts +121 -7
  15. package/dist/index.d.ts +121 -7
  16. package/dist/index.js +203 -105
  17. package/dist/index.js.map +1 -1
  18. package/dist/typings/index.d.mts +2 -1
  19. package/dist/typings/index.d.ts +2 -1
  20. package/dist/typings/index.js +7 -2
  21. package/dist/typings/index.js.map +1 -1
  22. package/dist/typings/workflow-drag.d.mts +8 -0
  23. package/dist/typings/workflow-drag.d.ts +8 -0
  24. package/dist/typings/workflow-drag.js +19 -0
  25. package/dist/typings/workflow-drag.js.map +1 -0
  26. package/dist/typings/workflow-json.d.mts +1 -1
  27. package/dist/typings/workflow-json.d.ts +1 -1
  28. package/dist/typings/workflow-line.d.mts +1 -1
  29. package/dist/typings/workflow-line.d.ts +1 -1
  30. package/dist/typings/workflow-node.d.mts +1 -1
  31. package/dist/typings/workflow-node.d.ts +1 -1
  32. package/dist/typings/workflow-node.js.map +1 -1
  33. package/dist/typings/workflow-operation.d.mts +24 -0
  34. package/dist/typings/workflow-operation.d.ts +24 -0
  35. package/dist/typings/workflow-operation.js +31 -0
  36. package/dist/typings/workflow-operation.js.map +1 -0
  37. package/dist/typings/workflow-registry.d.mts +1 -1
  38. package/dist/typings/workflow-registry.d.ts +1 -1
  39. package/dist/{workflow-line-entity-BJQBRDgJ.d.mts → workflow-line-entity-CF97dniV.d.mts} +90 -170
  40. package/dist/{workflow-line-entity-CEitdjhk.d.ts → workflow-line-entity-niuFXSbE.d.ts} +90 -170
  41. package/package.json +9 -9
  42. package/dist/esm/chunk-DE4324TR.js.map +0 -1
package/dist/index.js CHANGED
@@ -52,6 +52,8 @@ __export(src_exports, {
52
52
  WorkflowNodeEntity: () => WorkflowNodeEntity,
53
53
  WorkflowNodeLinesData: () => WorkflowNodeLinesData,
54
54
  WorkflowNodePortsData: () => WorkflowNodePortsData,
55
+ WorkflowOperationBaseService: () => WorkflowOperationBaseService,
56
+ WorkflowOperationBaseServiceImpl: () => WorkflowOperationBaseServiceImpl,
55
57
  WorkflowPortEntity: () => WorkflowPortEntity,
56
58
  WorkflowResetLayoutService: () => WorkflowResetLayoutService,
57
59
  WorkflowSelectService: () => WorkflowSelectService,
@@ -65,21 +67,21 @@ __export(src_exports, {
65
67
  getAntiOverlapPosition: () => getAntiOverlapPosition,
66
68
  getPortEntityId: () => getPortEntityId,
67
69
  nanoid: () => nanoid,
68
- useConfigEntity: () => import_core24.useConfigEntity,
70
+ useConfigEntity: () => import_core25.useConfigEntity,
69
71
  useCurrentDomNode: () => useCurrentDomNode,
70
72
  useCurrentEntity: () => useCurrentEntity,
71
- useEntities: () => import_core24.useEntities,
72
- useEntityDataFromContext: () => import_core24.useEntityDataFromContext,
73
- useEntityFromContext: () => import_core24.useEntityFromContext,
74
- useListenEvents: () => import_core24.useListenEvents,
73
+ useEntities: () => import_core25.useEntities,
74
+ useEntityDataFromContext: () => import_core25.useEntityDataFromContext,
75
+ useEntityFromContext: () => import_core25.useEntityFromContext,
76
+ useListenEvents: () => import_core25.useListenEvents,
75
77
  useNodeRender: () => useNodeRender,
76
- usePlayground: () => import_core24.usePlayground,
77
- usePlaygroundContainer: () => import_core24.usePlaygroundContainer,
78
- usePlaygroundContext: () => import_core24.usePlaygroundContext,
79
- usePlaygroundLatest: () => import_core24.usePlaygroundLatest,
78
+ usePlayground: () => import_core25.usePlayground,
79
+ usePlaygroundContainer: () => import_core25.usePlaygroundContainer,
80
+ usePlaygroundContext: () => import_core25.usePlaygroundContext,
81
+ usePlaygroundLatest: () => import_core25.usePlaygroundLatest,
80
82
  usePlaygroundReadonlyState: () => usePlaygroundReadonlyState,
81
- useRefresh: () => import_core24.useRefresh,
82
- useService: () => import_core24.useService,
83
+ useRefresh: () => import_core25.useRefresh,
84
+ useService: () => import_core25.useService,
83
85
  useWorkflowDocument: () => useWorkflowDocument
84
86
  });
85
87
  module.exports = __toCommonJS(src_exports);
@@ -97,14 +99,14 @@ var WorkflowCommands = /* @__PURE__ */ ((WorkflowCommands2) => {
97
99
  })(WorkflowCommands || {});
98
100
 
99
101
  // src/hooks/index.ts
100
- var import_core24 = require("@flowgram.ai/core");
102
+ var import_core25 = require("@flowgram.ai/core");
101
103
 
102
104
  // src/hooks/use-node-render.tsx
103
105
  var import_react2 = require("react");
104
106
  var import_reactive = require("@flowgram.ai/reactive");
105
107
  var import_node = require("@flowgram.ai/node");
106
- var import_document10 = require("@flowgram.ai/document");
107
- var import_core20 = require("@flowgram.ai/core");
108
+ var import_document12 = require("@flowgram.ai/document");
109
+ var import_core21 = require("@flowgram.ai/core");
108
110
 
109
111
  // src/service/workflow-select-service.ts
110
112
  var import_inversify = require("inversify");
@@ -178,11 +180,12 @@ var import_core8 = require("@flowgram.ai/core");
178
180
 
179
181
  // src/entity-datas/workflow-node-ports-data.ts
180
182
  var import_lodash_es = require("lodash-es");
181
- var import_document2 = require("@flowgram.ai/document");
183
+ var import_document3 = require("@flowgram.ai/document");
182
184
  var import_core5 = require("@flowgram.ai/core");
183
185
 
184
186
  // src/entities/workflow-port-entity.ts
185
187
  var import_utils5 = require("@flowgram.ai/utils");
188
+ var import_document2 = require("@flowgram.ai/document");
186
189
  var import_core4 = require("@flowgram.ai/core");
187
190
  var PORT_SIZE = 24;
188
191
  var WorkflowPortEntity = class extends import_core4.Entity {
@@ -230,7 +233,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
230
233
  }
231
234
  get point() {
232
235
  const { targetElement } = this;
233
- const { bounds } = this.node.getData(import_core4.TransformData);
236
+ const { bounds } = this.node.getData(import_document2.FlowNodeTransformData);
234
237
  if (targetElement) {
235
238
  const pos = domReactToBounds(targetElement.getBoundingClientRect()).center;
236
239
  return this.entityManager.getEntity(import_core4.PlaygroundConfigEntity).getPosFromMouseEvent({
@@ -259,7 +262,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
259
262
  */
260
263
  get relativePosition() {
261
264
  const { point } = this;
262
- const { bounds } = this.node.getData(import_core4.TransformData);
265
+ const { bounds } = this.node.getData(import_document2.FlowNodeTransformData);
263
266
  return {
264
267
  x: point.x - bounds.x,
265
268
  y: point.y - bounds.y
@@ -362,7 +365,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
362
365
  * 动态计算点位,通过 dom 的 data-port-key
363
366
  */
364
367
  updateDynamicPorts() {
365
- const domNode = this.entity.getData(import_document2.FlowNodeRenderData).node;
368
+ const domNode = this.entity.getData(import_document3.FlowNodeRenderData).node;
366
369
  const elements = domNode.querySelectorAll("[data-port-id]");
367
370
  const staticPorts = this._staticPorts;
368
371
  const dynamicPorts = [];
@@ -1139,20 +1142,20 @@ WorkflowHoverService = __decorateClass([
1139
1142
  var import_nanoid3 = require("nanoid");
1140
1143
  var import_inversify6 = require("inversify");
1141
1144
  var import_utils16 = require("@flowgram.ai/utils");
1142
- var import_document7 = require("@flowgram.ai/document");
1143
1145
  var import_document8 = require("@flowgram.ai/document");
1146
+ var import_document9 = require("@flowgram.ai/document");
1144
1147
  var import_core15 = require("@flowgram.ai/core");
1145
1148
 
1146
1149
  // src/workflow-lines-manager.ts
1147
1150
  var import_lodash_es3 = require("lodash-es");
1148
1151
  var import_inversify3 = require("inversify");
1149
1152
  var import_utils12 = require("@flowgram.ai/utils");
1150
- var import_document4 = require("@flowgram.ai/document");
1153
+ var import_document5 = require("@flowgram.ai/document");
1151
1154
  var import_core12 = require("@flowgram.ai/core");
1152
1155
 
1153
1156
  // src/workflow-document-option.ts
1154
1157
  var import_form_core2 = require("@flowgram.ai/form-core");
1155
- var import_document3 = require("@flowgram.ai/document");
1158
+ var import_document4 = require("@flowgram.ai/document");
1156
1159
  var import_core11 = require("@flowgram.ai/core");
1157
1160
 
1158
1161
  // src/utils/flow-node-form-data.ts
@@ -1185,6 +1188,9 @@ var LineColors = /* @__PURE__ */ ((LineColors2) => {
1185
1188
  return LineColors2;
1186
1189
  })(LineColors || {});
1187
1190
 
1191
+ // src/typings/workflow-operation.ts
1192
+ var WorkflowOperationBaseService = Symbol("WorkflowOperationBaseService");
1193
+
1188
1194
  // src/typings/index.ts
1189
1195
  var URLParams = Symbol("");
1190
1196
 
@@ -1235,7 +1241,7 @@ var WorkflowDocumentOptionsDefault = {
1235
1241
  const nodeMeta = node.getNodeMeta();
1236
1242
  const subCanvas = nodeMeta.subCanvas?.(node);
1237
1243
  if (subCanvas?.isCanvas === false) {
1238
- const canvasNodeTransform = subCanvas.canvasNode.getData(import_document3.FlowNodeTransformData);
1244
+ const canvasNodeTransform = subCanvas.canvasNode.getData(import_document4.FlowNodeTransformData);
1239
1245
  const { x, y } = canvasNodeTransform.transform.position;
1240
1246
  metaData.canvasPosition = { x, y };
1241
1247
  }
@@ -1533,12 +1539,12 @@ var WorkflowLinesManager = class {
1533
1539
  * @param pos - 鼠标位置
1534
1540
  */
1535
1541
  getNodeFromMousePos(pos) {
1536
- const allNodes = this.document.getAllNodes();
1542
+ const allNodes = this.document.getAllNodes().sort((a, b) => this.getNodeIndex(a) - this.getNodeIndex(b));
1537
1543
  const containNodes = [];
1538
1544
  const { selection } = this.selectService;
1539
1545
  const zoom = this.entityManager.getEntity(import_core12.PlaygroundConfigEntity)?.config?.zoom || 1;
1540
1546
  allNodes.forEach((node) => {
1541
- const { bounds } = node.getData(import_document4.FlowNodeTransformData);
1547
+ const { bounds } = node.getData(import_document5.FlowNodeTransformData);
1542
1548
  if (bounds.clone().pad(4 / zoom).contains(pos.x, pos.y)) {
1543
1549
  containNodes.push(node);
1544
1550
  }
@@ -1560,6 +1566,10 @@ var WorkflowLinesManager = class {
1560
1566
  registerData(line) {
1561
1567
  line.addData(WorkflowLineRenderData);
1562
1568
  }
1569
+ getNodeIndex(node) {
1570
+ const nodeRenderData = node.getData(import_document5.FlowNodeRenderData);
1571
+ return nodeRenderData.stackIndex;
1572
+ }
1563
1573
  };
1564
1574
  __decorateClass([
1565
1575
  (0, import_inversify3.inject)(WorkflowHoverService)
@@ -1582,12 +1592,12 @@ var import_nanoid2 = require("nanoid");
1582
1592
  var import_inversify5 = require("inversify");
1583
1593
  var import_utils14 = require("@flowgram.ai/utils");
1584
1594
  var import_form_core3 = require("@flowgram.ai/form-core");
1585
- var import_document6 = require("@flowgram.ai/document");
1595
+ var import_document7 = require("@flowgram.ai/document");
1586
1596
  var import_core14 = require("@flowgram.ai/core");
1587
1597
 
1588
1598
  // src/layout/free-layout.ts
1589
1599
  var import_inversify4 = require("inversify");
1590
- var import_document5 = require("@flowgram.ai/document");
1600
+ var import_document6 = require("@flowgram.ai/document");
1591
1601
  var import_core13 = require("@flowgram.ai/core");
1592
1602
  var import_utils13 = require("@flowgram.ai/utils");
1593
1603
  var FREE_LAYOUT_KEY = "free-layout";
@@ -1602,12 +1612,12 @@ var FreeLayout = class {
1602
1612
  * 更新布局
1603
1613
  */
1604
1614
  update() {
1605
- if (this.document.root.getData(import_document5.FlowNodeTransformData)?.localDirty) {
1615
+ if (this.document.root.getData(import_document6.FlowNodeTransformData)?.localDirty) {
1606
1616
  this.document.root.clearMemoGlobal();
1607
1617
  }
1608
1618
  }
1609
1619
  syncTransform(node) {
1610
- const transform = node.getData(import_document5.FlowNodeTransformData);
1620
+ const transform = node.getData(import_document6.FlowNodeTransformData);
1611
1621
  if (!transform.localDirty) {
1612
1622
  return;
1613
1623
  }
@@ -1621,7 +1631,7 @@ var FreeLayout = class {
1621
1631
  }
1622
1632
  node.parent.clearMemoGlobal();
1623
1633
  node.parent.clearMemoLocal();
1624
- const parentTransform = node.parent.getData(import_document5.FlowNodeTransformData);
1634
+ const parentTransform = node.parent.getData(import_document6.FlowNodeTransformData);
1625
1635
  parentTransform.transform.fireChange();
1626
1636
  }
1627
1637
  /**
@@ -1630,7 +1640,7 @@ var FreeLayout = class {
1630
1640
  */
1631
1641
  getPadding(node) {
1632
1642
  const { padding } = node.getNodeMeta();
1633
- const transform = node.getData(import_document5.FlowNodeTransformData);
1643
+ const transform = node.getData(import_document6.FlowNodeTransformData);
1634
1644
  if (padding) {
1635
1645
  return typeof padding === "function" ? padding(transform) : padding;
1636
1646
  }
@@ -1674,7 +1684,7 @@ __decorateClass([
1674
1684
  (0, import_inversify4.inject)(import_core13.PlaygroundConfigEntity)
1675
1685
  ], FreeLayout.prototype, "playgroundConfig", 2);
1676
1686
  __decorateClass([
1677
- (0, import_inversify4.inject)(import_document5.FlowDocumentProvider)
1687
+ (0, import_inversify4.inject)(import_document6.FlowDocumentProvider)
1678
1688
  ], FreeLayout.prototype, "documentProvider", 2);
1679
1689
  FreeLayout = __decorateClass([
1680
1690
  (0, import_inversify4.injectable)()
@@ -1683,7 +1693,7 @@ FreeLayout = __decorateClass([
1683
1693
  // src/workflow-document.ts
1684
1694
  var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890", 5);
1685
1695
  var WorkflowDocumentProvider = Symbol("WorkflowDocumentProvider");
1686
- var WorkflowDocument = class extends import_document6.FlowDocument {
1696
+ var WorkflowDocument = class extends import_document7.FlowDocument {
1687
1697
  constructor() {
1688
1698
  super(...arguments);
1689
1699
  this._onContentChangeEmitter = new import_utils14.Emitter();
@@ -1776,7 +1786,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1776
1786
  const { formMeta } = registry;
1777
1787
  const meta = node.getNodeMeta();
1778
1788
  const formData = getFlowNodeFormData(node);
1779
- const transform = node.getData(import_document6.FlowNodeTransformData);
1789
+ const transform = node.getData(import_document7.FlowNodeTransformData);
1780
1790
  const freeLayout = this.layout;
1781
1791
  transform.onDataChange(() => {
1782
1792
  freeLayout.syncTransform(node);
@@ -1824,10 +1834,10 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1824
1834
  );
1825
1835
  node.toDispose.push(
1826
1836
  import_utils14.Disposable.create(() => {
1827
- if (!node.parent || node.parent.flowNodeType === import_document6.FlowNodeBaseType.ROOT) {
1837
+ if (!node.parent || node.parent.flowNodeType === import_document7.FlowNodeBaseType.ROOT) {
1828
1838
  return;
1829
1839
  }
1830
- const parentTransform = node.parent.getData(import_document6.FlowNodeTransformData);
1840
+ const parentTransform = node.parent.getData(import_document7.FlowNodeTransformData);
1831
1841
  setTimeout(() => {
1832
1842
  parentTransform.fireChange();
1833
1843
  }, 0);
@@ -1894,6 +1904,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1894
1904
  }
1895
1905
  return this.createWorkflowNode(
1896
1906
  {
1907
+ ...json,
1897
1908
  id,
1898
1909
  type,
1899
1910
  meta: { position, ...json?.meta },
@@ -1907,10 +1918,10 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1907
1918
  );
1908
1919
  }
1909
1920
  getAllNodes() {
1910
- return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== import_document6.FlowNodeBaseType.ROOT);
1921
+ return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== import_document7.FlowNodeBaseType.ROOT);
1911
1922
  }
1912
1923
  getAllPorts() {
1913
- return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== import_document6.FlowNodeBaseType.ROOT);
1924
+ return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== import_document7.FlowNodeBaseType.ROOT);
1914
1925
  }
1915
1926
  /**
1916
1927
  * 获取画布中的非游离节点
@@ -1927,8 +1938,8 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1927
1938
  }));
1928
1939
  const startNodeId = allNode.find((node) => node.isStart).id;
1929
1940
  const endNodeId = allNode.find((node) => node.isNodeEnd).id;
1930
- const nodeInSubCanvas = allNode.filter((node) => node.parent?.flowNodeType === import_document6.FlowNodeBaseType.SUB_CANVAS).map((node) => node.id);
1931
- const associatedCache = /* @__PURE__ */ new Set([endNodeId, ...nodeInSubCanvas]);
1941
+ const nodeInContainer = allNode.filter((node) => node.parent?.getNodeMeta().isContainer).map((node) => node.id);
1942
+ const associatedCache = /* @__PURE__ */ new Set([endNodeId, ...nodeInContainer]);
1932
1943
  const bfs = (nodeId) => {
1933
1944
  if (associatedCache.has(nodeId)) {
1934
1945
  return;
@@ -2098,8 +2109,8 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2098
2109
  const flattenEdgeJSONs = [...rootEdges];
2099
2110
  const rootBlockIDs = rootNodes.map((node) => node.id);
2100
2111
  const rootEdgeIDs = rootEdges.map((edge) => this.getEdgeID(edge));
2101
- nodeBlocks.set(import_document6.FlowNodeBaseType.ROOT, rootBlockIDs);
2102
- nodeEdges.set(import_document6.FlowNodeBaseType.ROOT, rootEdgeIDs);
2112
+ nodeBlocks.set(import_document7.FlowNodeBaseType.ROOT, rootBlockIDs);
2113
+ nodeEdges.set(import_document7.FlowNodeBaseType.ROOT, rootEdgeIDs);
2103
2114
  rootNodes.forEach((nodeJSON) => {
2104
2115
  const { blocks, edges } = nodeJSON;
2105
2116
  if (blocks) {
@@ -2142,8 +2153,8 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2142
2153
  };
2143
2154
  const nodeMap = /* @__PURE__ */ new Map();
2144
2155
  const edgeMap = /* @__PURE__ */ new Map();
2145
- const rootBlockSet = new Set(nodeBlocks.get(import_document6.FlowNodeBaseType.ROOT) ?? []);
2146
- const rootEdgeSet = new Set(nodeEdges.get(import_document6.FlowNodeBaseType.ROOT) ?? []);
2156
+ const rootBlockSet = new Set(nodeBlocks.get(import_document7.FlowNodeBaseType.ROOT) ?? []);
2157
+ const rootEdgeSet = new Set(nodeEdges.get(import_document7.FlowNodeBaseType.ROOT) ?? []);
2147
2158
  flattenJSON.nodes.forEach((nodeJSON) => {
2148
2159
  nodeMap.set(nodeJSON.id, nodeJSON);
2149
2160
  });
@@ -2203,7 +2214,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2203
2214
  }
2204
2215
  toLineJSON(line) {
2205
2216
  const lineJSON = line.toJSON();
2206
- if (!line.to || !line.info.to || !line.toPort) {
2217
+ if (!line.from || !line.info.from || !line.fromPort || !line.to || !line.info.to || !line.toPort) {
2207
2218
  return;
2208
2219
  }
2209
2220
  const fromSubCanvas = this.getNodeSubCanvas(line.from);
@@ -2321,18 +2332,19 @@ var WorkflowDragService = class {
2321
2332
  }
2322
2333
  /**
2323
2334
  * 拖拽选中节点
2324
- * @param event
2335
+ * @param triggerEvent
2325
2336
  */
2326
- startDragSelectedNodes(event) {
2337
+ startDragSelectedNodes(triggerEvent) {
2327
2338
  let { selectedNodes } = this.selectService;
2328
- if (selectedNodes.length === 0 || this.playgroundConfig.readonly || this.playgroundConfig.disabled) {
2339
+ if (selectedNodes.length === 0 || this.playgroundConfig.readonly || this.playgroundConfig.disabled || this.isDragging) {
2329
2340
  return Promise.resolve(false);
2330
2341
  }
2342
+ this.isDragging = true;
2331
2343
  const sameParent = this.childrenOfContainer(selectedNodes);
2332
- if (sameParent && sameParent.flowNodeType !== import_document8.FlowNodeBaseType.ROOT) {
2344
+ if (sameParent && sameParent.flowNodeType !== import_document9.FlowNodeBaseType.ROOT) {
2333
2345
  selectedNodes = [sameParent];
2334
2346
  }
2335
- const { altKey } = event;
2347
+ const { altKey } = triggerEvent;
2336
2348
  let startPosition = this.getNodesPosition(selectedNodes);
2337
2349
  let startPositions = selectedNodes.map((node) => {
2338
2350
  const transform = node.getData(import_core15.TransformData);
@@ -2341,11 +2353,19 @@ var WorkflowDragService = class {
2341
2353
  let dragSuccess = false;
2342
2354
  const startTime = Date.now();
2343
2355
  const dragger = new import_core15.PlaygroundDrag({
2344
- onDragStart: () => {
2345
- this.isDragging = true;
2356
+ onDragStart: (dragEvent) => {
2357
+ this._nodesDragEmitter.fire({
2358
+ type: "onDragStart",
2359
+ nodes: selectedNodes,
2360
+ startPositions,
2361
+ altKey,
2362
+ dragEvent,
2363
+ triggerEvent,
2364
+ dragger
2365
+ });
2346
2366
  },
2347
- onDrag: (e) => {
2348
- if (!dragSuccess && checkDragSuccess(Date.now() - startTime, e)) {
2367
+ onDrag: (dragEvent) => {
2368
+ if (!dragSuccess && checkDragSuccess(Date.now() - startTime, dragEvent)) {
2349
2369
  dragSuccess = true;
2350
2370
  if (altKey) {
2351
2371
  const tryCopyNodes = selectedNodes;
@@ -2368,10 +2388,11 @@ var WorkflowDragService = class {
2368
2388
  }
2369
2389
  }
2370
2390
  const offset = this.getDragPosOffset({
2371
- event: e,
2391
+ event: dragEvent,
2372
2392
  selectedNodes,
2373
2393
  startPosition
2374
2394
  });
2395
+ const positions = [];
2375
2396
  selectedNodes.forEach((node, index) => {
2376
2397
  const transform = node.getData(import_core15.TransformData);
2377
2398
  const nodeStartPosition = startPositions[index];
@@ -2381,26 +2402,40 @@ var WorkflowDragService = class {
2381
2402
  };
2382
2403
  if (node.collapsedChildren?.length > 0) {
2383
2404
  node.collapsedChildren.forEach((childNode) => {
2384
- const childNodeTransformData = childNode.getData(import_document7.FlowNodeTransformData);
2405
+ const childNodeTransformData = childNode.getData(import_document8.FlowNodeTransformData);
2385
2406
  childNodeTransformData.fireChange();
2386
2407
  });
2387
2408
  }
2388
2409
  transform.update({
2389
2410
  position: newPosition
2390
2411
  });
2412
+ positions.push(newPosition);
2413
+ });
2414
+ this._nodesDragEmitter.fire({
2415
+ type: "onDragging",
2416
+ nodes: selectedNodes,
2417
+ startPositions,
2418
+ positions,
2419
+ altKey,
2420
+ dragEvent,
2421
+ triggerEvent,
2422
+ dragger
2391
2423
  });
2392
2424
  },
2393
- onDragEnd: () => {
2425
+ onDragEnd: (dragEvent) => {
2394
2426
  this.isDragging = false;
2395
2427
  this._nodesDragEmitter.fire({
2396
2428
  type: "onDragEnd",
2397
2429
  nodes: selectedNodes,
2398
2430
  startPositions,
2399
- altKey
2431
+ altKey,
2432
+ dragEvent,
2433
+ triggerEvent,
2434
+ dragger
2400
2435
  });
2401
2436
  }
2402
2437
  });
2403
- return dragger.start(event.clientX, event.clientY, this.playgroundConfig).then(() => dragSuccess);
2438
+ return dragger.start(triggerEvent.clientX, triggerEvent.clientY, this.playgroundConfig)?.then(() => dragSuccess);
2404
2439
  }
2405
2440
  /**
2406
2441
  * 通过拖入卡片添加
@@ -2472,6 +2507,13 @@ var WorkflowDragService = class {
2472
2507
  },
2473
2508
  onDragEnd: async (e) => {
2474
2509
  const dropNode = this._dropNode;
2510
+ const { allowDrop } = this.canDropToNode({
2511
+ dragNodeType: type,
2512
+ dropNode
2513
+ });
2514
+ if (!allowDrop) {
2515
+ return this.clearDrop();
2516
+ }
2475
2517
  const dragNode = await this.dropCard(type, e, data, dropNode);
2476
2518
  this.clearDrop();
2477
2519
  if (dragNode) {
@@ -2498,7 +2540,7 @@ var WorkflowDragService = class {
2498
2540
  if (!mousePos) {
2499
2541
  return { x: 0, y: 0 };
2500
2542
  }
2501
- if (!subNodeType || !containerNode || containerNode.flowNodeType === import_document8.FlowNodeBaseType.ROOT) {
2543
+ if (!subNodeType || !containerNode || containerNode.flowNodeType === import_document9.FlowNodeBaseType.ROOT) {
2502
2544
  return mousePos;
2503
2545
  }
2504
2546
  const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
@@ -2525,6 +2567,22 @@ var WorkflowDragService = class {
2525
2567
  dispose: () => this.posAdjusters.delete(adjuster)
2526
2568
  };
2527
2569
  }
2570
+ /**
2571
+ * 判断是否可以放置节点
2572
+ */
2573
+ canDropToNode(params) {
2574
+ const { dragNodeType, dropNode } = params;
2575
+ if (!dragNodeType) {
2576
+ return {
2577
+ allowDrop: false,
2578
+ message: "Please select a node to drop"
2579
+ };
2580
+ }
2581
+ return {
2582
+ allowDrop: true,
2583
+ dropNode
2584
+ };
2585
+ }
2528
2586
  /**
2529
2587
  * 获取拖拽偏移
2530
2588
  */
@@ -2555,23 +2613,24 @@ var WorkflowDragService = class {
2555
2613
  return offset;
2556
2614
  }
2557
2615
  updateDroppableTransforms() {
2558
- this._droppableTransforms = this.document.getRenderDatas(import_document7.FlowNodeTransformData, false).filter((transform) => {
2616
+ this._droppableTransforms = this.document.getRenderDatas(import_document8.FlowNodeTransformData, false).filter((transform) => {
2559
2617
  const { entity } = transform;
2560
2618
  if (entity.originParent) {
2561
2619
  return this.nodeSelectable(entity) && this.nodeSelectable(entity.originParent);
2562
2620
  }
2563
2621
  return this.nodeSelectable(entity);
2564
- }).filter((transform) => {
2565
- const { entity } = transform;
2566
- return entity.flowNodeType === import_document8.FlowNodeBaseType.SUB_CANVAS;
2567
- });
2622
+ }).filter((transform) => this.isContainer(transform.entity));
2623
+ }
2624
+ /** 是否容器节点 */
2625
+ isContainer(node) {
2626
+ return node?.getNodeMeta().isContainer ?? false;
2568
2627
  }
2569
2628
  /**
2570
2629
  * 获取节点整体位置
2571
2630
  */
2572
2631
  getNodesPosition(nodes) {
2573
2632
  const selectedBounds = import_utils16.Rectangle.enlarge(
2574
- nodes.map((n) => n.getData(import_document7.FlowNodeTransformData).bounds)
2633
+ nodes.map((n) => n.getData(import_document8.FlowNodeTransformData).bounds)
2575
2634
  );
2576
2635
  const position = {
2577
2636
  x: selectedBounds.x,
@@ -2621,7 +2680,7 @@ var WorkflowDragService = class {
2621
2680
  return {
2622
2681
  hasError: false
2623
2682
  };
2624
- } else if (toNode.flowNodeType === import_document8.FlowNodeBaseType.SUB_CANVAS) {
2683
+ } else if (this.isContainer(toNode)) {
2625
2684
  return {
2626
2685
  hasError: false
2627
2686
  };
@@ -2656,6 +2715,7 @@ var WorkflowDragService = class {
2656
2715
  if (originLine?.disabled || isFromInActivePort || this.playgroundConfig.readonly || this.playgroundConfig.disabled) {
2657
2716
  return { dragSuccess: false, newLine: void 0 };
2658
2717
  }
2718
+ this.selectService.clear();
2659
2719
  const config = this.playgroundConfig;
2660
2720
  const deferred = new import_utils16.PromiseDeferred();
2661
2721
  const preCursor = config.cursor;
@@ -2701,7 +2761,7 @@ var WorkflowDragService = class {
2701
2761
  type: "onDrag"
2702
2762
  });
2703
2763
  this.setLineColor(line, this.linesManager.lineColor.drawing);
2704
- if (toNode && toNode.flowNodeType !== import_document8.FlowNodeBaseType.SUB_CANVAS) {
2764
+ if (toNode && !this.isContainer(toNode)) {
2705
2765
  const portsData = toNode.getData(WorkflowNodePortsData);
2706
2766
  toPort = portsData.inputPorts[0];
2707
2767
  const { hasError } = this.handleDragOnNode(toNode, fromPort, line, toPort, originLine);
@@ -2830,7 +2890,7 @@ __decorateClass([
2830
2890
  (0, import_inversify6.inject)(WorkflowSelectService)
2831
2891
  ], WorkflowDragService.prototype, "selectService", 2);
2832
2892
  __decorateClass([
2833
- (0, import_inversify6.inject)(import_document7.FlowOperationBaseService)
2893
+ (0, import_inversify6.inject)(import_document8.FlowOperationBaseService)
2834
2894
  ], WorkflowDragService.prototype, "operationService", 2);
2835
2895
  __decorateClass([
2836
2896
  (0, import_inversify6.inject)(WorkflowDocumentOptions)
@@ -2849,13 +2909,13 @@ var import_core18 = require("@flowgram.ai/core");
2849
2909
  var import_utils17 = require("@flowgram.ai/utils");
2850
2910
 
2851
2911
  // src/utils/layout-to-positions.ts
2852
- var import_document9 = require("@flowgram.ai/document");
2912
+ var import_document10 = require("@flowgram.ai/document");
2853
2913
  var import_core16 = require("@flowgram.ai/core");
2854
2914
  var layoutToPositions = async (nodes, nodePositionMap) => {
2855
2915
  const newNodePositionMap = {};
2856
2916
  nodes.forEach((node) => {
2857
2917
  const transform = node.getData(import_core16.TransformData);
2858
- const nodeTransform = node.getData(import_document9.FlowNodeTransformData);
2918
+ const nodeTransform = node.getData(import_document10.FlowNodeTransformData);
2859
2919
  newNodePositionMap[node.id] = {
2860
2920
  x: transform.position.x,
2861
2921
  y: transform.position.y + nodeTransform.bounds.height / 2
@@ -2873,7 +2933,7 @@ var layoutToPositions = async (nodes, nodePositionMap) => {
2873
2933
  const deltaY = (nodePositionMap[node.id].y - transform.bounds.height / 2 - transform.position.y) * v.d / 100;
2874
2934
  if (node.collapsedChildren?.length > 0) {
2875
2935
  node.collapsedChildren.forEach((childNode) => {
2876
- const childNodeTransformData = childNode.getData(import_document9.FlowNodeTransformData);
2936
+ const childNodeTransformData = childNode.getData(import_document10.FlowNodeTransformData);
2877
2937
  childNodeTransformData.fireChange();
2878
2938
  });
2879
2939
  }
@@ -2952,12 +3012,47 @@ WorkflowResetLayoutService = __decorateClass([
2952
3012
  (0, import_inversify7.injectable)()
2953
3013
  ], WorkflowResetLayoutService);
2954
3014
 
3015
+ // src/service/workflow-operation-base-service.ts
3016
+ var import_inversify8 = require("inversify");
3017
+ var import_utils19 = require("@flowgram.ai/utils");
3018
+ var import_document11 = require("@flowgram.ai/document");
3019
+ var import_core19 = require("@flowgram.ai/core");
3020
+ var WorkflowOperationBaseServiceImpl = class extends import_document11.FlowOperationBaseServiceImpl {
3021
+ constructor() {
3022
+ super(...arguments);
3023
+ this.onNodePostionUpdateEmitter = new import_utils19.Emitter();
3024
+ this.onNodePostionUpdate = this.onNodePostionUpdateEmitter.event;
3025
+ }
3026
+ updateNodePosition(nodeOrId, position) {
3027
+ const node = this.toNodeEntity(nodeOrId);
3028
+ if (!node) {
3029
+ return;
3030
+ }
3031
+ const transformData = node.getData(import_core19.TransformData);
3032
+ const oldPosition = {
3033
+ x: transformData.position.x,
3034
+ y: transformData.position.y
3035
+ };
3036
+ transformData.update({
3037
+ position
3038
+ });
3039
+ this.onNodePostionUpdateEmitter.fire({
3040
+ node,
3041
+ oldPosition,
3042
+ newPosition: position
3043
+ });
3044
+ }
3045
+ };
3046
+ __decorateClass([
3047
+ (0, import_inversify8.inject)(WorkflowDocument)
3048
+ ], WorkflowOperationBaseServiceImpl.prototype, "document", 2);
3049
+
2955
3050
  // src/hooks/use-playground-readonly-state.ts
2956
3051
  var import_react = require("react");
2957
- var import_core19 = require("@flowgram.ai/core");
3052
+ var import_core20 = require("@flowgram.ai/core");
2958
3053
  function usePlaygroundReadonlyState(listenChange) {
2959
- const playground = (0, import_core19.usePlayground)();
2960
- const refresh = (0, import_core19.useRefresh)();
3054
+ const playground = (0, import_core20.usePlayground)();
3055
+ const refresh = (0, import_core20.useRefresh)();
2961
3056
  (0, import_react.useEffect)(() => {
2962
3057
  let dispose = void 0;
2963
3058
  if (listenChange) {
@@ -2973,12 +3068,12 @@ function checkTargetDraggable(el) {
2973
3068
  return el && el.tagName !== "INPUT" && el.tagName !== "TEXTAREA" && !el.closest(".flow-canvas-not-draggable");
2974
3069
  }
2975
3070
  function useNodeRender(nodeFromProps) {
2976
- const node = nodeFromProps || (0, import_react2.useContext)(import_core20.PlaygroundEntityContext);
2977
- const renderData = node.getData(import_document10.FlowNodeRenderData);
3071
+ const node = nodeFromProps || (0, import_react2.useContext)(import_core21.PlaygroundEntityContext);
3072
+ const renderData = node.getData(import_document12.FlowNodeRenderData);
2978
3073
  const portsData = node.getData(WorkflowNodePortsData);
2979
3074
  const readonly = usePlaygroundReadonlyState();
2980
- const dragService = (0, import_core20.useService)(WorkflowDragService);
2981
- const selectionService = (0, import_core20.useService)(WorkflowSelectService);
3075
+ const dragService = (0, import_core21.useService)(WorkflowDragService);
3076
+ const selectionService = (0, import_core21.useService)(WorkflowSelectService);
2982
3077
  const isDragging = (0, import_react2.useRef)(false);
2983
3078
  const nodeRef = (0, import_react2.useRef)(null);
2984
3079
  const [linkingNodeId, setLinkingNodeId] = (0, import_react2.useState)("");
@@ -3004,7 +3099,7 @@ function useNodeRender(nodeFromProps) {
3004
3099
  return;
3005
3100
  }
3006
3101
  isDragging.current = true;
3007
- dragService.startDragSelectedNodes(e).finally(
3102
+ dragService.startDragSelectedNodes(e)?.finally(
3008
3103
  () => setTimeout(() => {
3009
3104
  isDragging.current = false;
3010
3105
  })
@@ -3017,7 +3112,7 @@ function useNodeRender(nodeFromProps) {
3017
3112
  if (isDragging.current) {
3018
3113
  return;
3019
3114
  }
3020
- if (e.metaKey || e.shiftKey || e.ctrlKey) {
3115
+ if (e.shiftKey) {
3021
3116
  selectionService.toggleSelect(node);
3022
3117
  } else {
3023
3118
  selectionService.selectNode(node);
@@ -3029,7 +3124,7 @@ function useNodeRender(nodeFromProps) {
3029
3124
  [node]
3030
3125
  );
3031
3126
  const deleteNode = (0, import_react2.useCallback)(() => node.dispose(), [node]);
3032
- (0, import_core20.useListenEvents)(portsData.onDataChange);
3127
+ (0, import_core21.useListenEvents)(portsData.onDataChange);
3033
3128
  const isFirefox = navigator?.userAgent?.includes?.("Firefox");
3034
3129
  const onFocus = (0, import_react2.useCallback)(() => {
3035
3130
  if (isFirefox) {
@@ -3086,24 +3181,24 @@ function useNodeRender(nodeFromProps) {
3086
3181
  }
3087
3182
 
3088
3183
  // src/hooks/use-current-dom-node.ts
3089
- var import_document11 = require("@flowgram.ai/document");
3090
- var import_core21 = require("@flowgram.ai/core");
3184
+ var import_document13 = require("@flowgram.ai/document");
3185
+ var import_core22 = require("@flowgram.ai/core");
3091
3186
  function useCurrentDomNode() {
3092
- const entity = (0, import_core21.useEntityFromContext)();
3093
- const renderData = entity.getData(import_document11.FlowNodeRenderData);
3187
+ const entity = (0, import_core22.useEntityFromContext)();
3188
+ const renderData = entity.getData(import_document13.FlowNodeRenderData);
3094
3189
  return renderData.node;
3095
3190
  }
3096
3191
 
3097
3192
  // src/hooks/use-current-entity.ts
3098
- var import_core22 = require("@flowgram.ai/core");
3193
+ var import_core23 = require("@flowgram.ai/core");
3099
3194
  function useCurrentEntity() {
3100
- return (0, import_core22.useEntityFromContext)();
3195
+ return (0, import_core23.useEntityFromContext)();
3101
3196
  }
3102
3197
 
3103
3198
  // src/hooks/use-workflow-document.ts
3104
- var import_core23 = require("@flowgram.ai/core");
3199
+ var import_core24 = require("@flowgram.ai/core");
3105
3200
  function useWorkflowDocument() {
3106
- return (0, import_core23.useService)(WorkflowDocument);
3201
+ return (0, import_core24.useService)(WorkflowDocument);
3107
3202
  }
3108
3203
 
3109
3204
  // src/constants.ts
@@ -3119,18 +3214,18 @@ var InteractiveType = /* @__PURE__ */ ((InteractiveType2) => {
3119
3214
  })(InteractiveType || {});
3120
3215
 
3121
3216
  // src/workflow-document-container-module.ts
3122
- var import_inversify9 = require("inversify");
3123
- var import_document13 = require("@flowgram.ai/document");
3124
- var import_utils19 = require("@flowgram.ai/utils");
3217
+ var import_inversify10 = require("inversify");
3218
+ var import_utils20 = require("@flowgram.ai/utils");
3219
+ var import_document15 = require("@flowgram.ai/document");
3125
3220
 
3126
3221
  // src/workflow-document-contribution.ts
3127
- var import_inversify8 = require("inversify");
3128
- var import_document12 = require("@flowgram.ai/document");
3222
+ var import_inversify9 = require("inversify");
3223
+ var import_document14 = require("@flowgram.ai/document");
3129
3224
  var WorkflowDocumentContribution = class {
3130
3225
  registerDocument(document2) {
3131
3226
  document2.registerNodeDatas(
3132
- import_document12.FlowNodeTransformData,
3133
- import_document12.FlowNodeRenderData,
3227
+ import_document14.FlowNodeTransformData,
3228
+ import_document14.FlowNodeRenderData,
3134
3229
  WorkflowNodePortsData,
3135
3230
  WorkflowNodeLinesData
3136
3231
  );
@@ -3138,10 +3233,10 @@ var WorkflowDocumentContribution = class {
3138
3233
  }
3139
3234
  };
3140
3235
  __decorateClass([
3141
- (0, import_inversify8.inject)(FreeLayout)
3236
+ (0, import_inversify9.inject)(FreeLayout)
3142
3237
  ], WorkflowDocumentContribution.prototype, "freeLayout", 2);
3143
3238
  WorkflowDocumentContribution = __decorateClass([
3144
- (0, import_inversify8.injectable)()
3239
+ (0, import_inversify9.injectable)()
3145
3240
  ], WorkflowDocumentContribution);
3146
3241
 
3147
3242
  // src/utils/get-url-params.ts
@@ -3154,7 +3249,7 @@ function getUrlParams() {
3154
3249
  }
3155
3250
 
3156
3251
  // src/workflow-document-container-module.ts
3157
- var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3252
+ var WorkflowDocumentContainerModule = new import_inversify10.ContainerModule(
3158
3253
  (bind, unbind, isBound, rebind) => {
3159
3254
  bind(WorkflowDocument).toSelf().inSingletonScope();
3160
3255
  bind(WorkflowLinesManager).toSelf().inSingletonScope();
@@ -3163,18 +3258,19 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3163
3258
  bind(WorkflowSelectService).toSelf().inSingletonScope();
3164
3259
  bind(WorkflowHoverService).toSelf().inSingletonScope();
3165
3260
  bind(WorkflowResetLayoutService).toSelf().inSingletonScope();
3261
+ bind(WorkflowOperationBaseService).to(WorkflowOperationBaseServiceImpl).inSingletonScope();
3166
3262
  bind(URLParams).toDynamicValue(() => getUrlParams()).inSingletonScope();
3167
- (0, import_utils19.bindContributions)(bind, WorkflowDocumentContribution, [import_document13.FlowDocumentContribution]);
3263
+ (0, import_utils20.bindContributions)(bind, WorkflowDocumentContribution, [import_document15.FlowDocumentContribution]);
3168
3264
  bind(WorkflowDocumentOptions).toConstantValue({
3169
3265
  ...WorkflowDocumentOptionsDefault
3170
3266
  });
3171
- rebind(import_document13.FlowDocument).toService(WorkflowDocument);
3267
+ rebind(import_document15.FlowDocument).toService(WorkflowDocument);
3172
3268
  bind(WorkflowDocumentProvider).toDynamicValue((ctx) => () => ctx.container.get(WorkflowDocument)).inSingletonScope();
3173
3269
  }
3174
3270
  );
3175
3271
 
3176
3272
  // src/utils/simple-line.ts
3177
- var import_utils20 = require("@flowgram.ai/utils");
3273
+ var import_utils21 = require("@flowgram.ai/utils");
3178
3274
  var LINE_PADDING = 12;
3179
3275
  var WorkflowSimpleLineContribution = class {
3180
3276
  constructor(entity) {
@@ -3188,11 +3284,11 @@ var WorkflowSimpleLineContribution = class {
3188
3284
  return Number.MAX_SAFE_INTEGER;
3189
3285
  }
3190
3286
  const [start, end] = this.data.points;
3191
- return import_utils20.Point.getDistance(pos, this.projectPointOnLine(pos, start, end));
3287
+ return import_utils21.Point.getDistance(pos, this.projectPointOnLine(pos, start, end));
3192
3288
  }
3193
3289
  get bounds() {
3194
3290
  if (!this.data) {
3195
- return new import_utils20.Rectangle();
3291
+ return new import_utils21.Rectangle();
3196
3292
  }
3197
3293
  return this.data.bbox;
3198
3294
  }
@@ -3217,7 +3313,7 @@ var WorkflowSimpleLineContribution = class {
3217
3313
  y: toPos.y + targetOffset.y
3218
3314
  }
3219
3315
  ];
3220
- const bbox = import_utils20.Rectangle.createRectangleWithTwoPoints(points[0], points[1]);
3316
+ const bbox = import_utils21.Rectangle.createRectangleWithTwoPoints(points[0], points[1]);
3221
3317
  const adjustedPoints = points.map((p) => ({
3222
3318
  x: p.x - bbox.x + LINE_PADDING,
3223
3319
  y: p.y - bbox.y + LINE_PADDING
@@ -3273,6 +3369,8 @@ WorkflowSimpleLineContribution.type = "WorkflowSimpleLineContribution";
3273
3369
  WorkflowNodeEntity,
3274
3370
  WorkflowNodeLinesData,
3275
3371
  WorkflowNodePortsData,
3372
+ WorkflowOperationBaseService,
3373
+ WorkflowOperationBaseServiceImpl,
3276
3374
  WorkflowPortEntity,
3277
3375
  WorkflowResetLayoutService,
3278
3376
  WorkflowSelectService,