@flowgram.ai/document 0.1.0-alpha.7 → 0.1.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -85,11 +85,17 @@ var FlowNodeBaseType = /* @__PURE__ */ ((FlowNodeBaseType2) => {
85
85
  FlowNodeBaseType2["BLOCK_ORDER_ICON"] = "blockOrderIcon";
86
86
  FlowNodeBaseType2["GROUP"] = "group";
87
87
  FlowNodeBaseType2["END"] = "end";
88
+ FlowNodeBaseType2["BREAK"] = "break";
88
89
  FlowNodeBaseType2["CONDITION"] = "condition";
89
90
  FlowNodeBaseType2["SUB_CANVAS"] = "subCanvas";
91
+ FlowNodeBaseType2["MULTI_INPUTS"] = "multiInputs";
92
+ FlowNodeBaseType2["MULTI_OUTPUTS"] = "multiOutputs";
93
+ FlowNodeBaseType2["INPUT"] = "input";
94
+ FlowNodeBaseType2["OUTPUT"] = "output";
90
95
  return FlowNodeBaseType2;
91
96
  })(FlowNodeBaseType || {});
92
97
  var FlowNodeSplitType = /* @__PURE__ */ ((FlowNodeSplitType2) => {
98
+ FlowNodeSplitType2["SIMPLE_SPLIT"] = "simpleSplit";
93
99
  FlowNodeSplitType2["DYNAMIC_SPLIT"] = "dynamicSplit";
94
100
  FlowNodeSplitType2["STATIC_SPLIT"] = "staticSplit";
95
101
  return FlowNodeSplitType2;
@@ -233,13 +239,37 @@ var DEFAULT_FLOW_NODE_META = (nodeType, document) => {
233
239
  };
234
240
  var FlowNodeRegistry;
235
241
  ((FlowNodeRegistry4) => {
242
+ function mergeChildRegistries(r1 = [], r2 = []) {
243
+ if (r1.length === 0 || r2.length === 0) {
244
+ return [...r1, ...r2];
245
+ }
246
+ const r1Filter = r1.map((r1Current) => {
247
+ const r2Current = r2.find((n) => n.type === r1Current.type);
248
+ if (r2Current) {
249
+ return merge(r1Current, r2Current, r1Current.type);
250
+ }
251
+ return r1Current;
252
+ });
253
+ const r2Filter = r2.filter((n) => !r1.some((r) => r.type === n.type));
254
+ return [...r1Filter, ...r2Filter];
255
+ }
256
+ FlowNodeRegistry4.mergeChildRegistries = mergeChildRegistries;
236
257
  function merge(registry1, registry2, finalType) {
258
+ const extendKeys = registry1.__extends__ ? registry1.__extends__.slice() : [];
259
+ if (registry1.type !== registry2.type) {
260
+ extendKeys.unshift(registry1.type);
261
+ }
237
262
  return {
238
263
  ...registry1,
239
264
  ...registry2,
265
+ extendChildRegistries: mergeChildRegistries(
266
+ registry1.extendChildRegistries,
267
+ registry2.extendChildRegistries
268
+ ),
240
269
  meta: { ...registry1.meta, ...registry2.meta },
241
270
  extend: void 0,
242
- type: finalType
271
+ type: finalType,
272
+ __extends__: extendKeys
243
273
  };
244
274
  }
245
275
  FlowNodeRegistry4.merge = merge;
@@ -1448,13 +1478,15 @@ var FlowVirtualTree = class _FlowVirtualTree {
1448
1478
  get size() {
1449
1479
  return this.map.size;
1450
1480
  }
1451
- toString() {
1481
+ toString(showType) {
1452
1482
  const ret = [];
1453
1483
  this.traverse((node, depth) => {
1454
1484
  if (depth === 0) {
1455
1485
  ret.push(node.id);
1456
1486
  } else {
1457
- ret.push(`|${new Array(depth).fill("--").join("")} ${node.id}`);
1487
+ ret.push(
1488
+ `|${new Array(depth).fill("--").join("")} ${showType ? `${node.flowNodeType}(${node.id})` : node.id}`
1489
+ );
1458
1490
  }
1459
1491
  });
1460
1492
  return `${ret.join("\n")}`;
@@ -1720,6 +1752,13 @@ var FlowDocument = class {
1720
1752
  this.onNodeCreate = this.onNodeCreateEmitter.event;
1721
1753
  this.onNodeDispose = this.onNodeDisposeEmitter.event;
1722
1754
  this.onLayoutChange = this.onLayoutChangeEmitter.event;
1755
+ this._disposed = false;
1756
+ }
1757
+ /**
1758
+ *
1759
+ */
1760
+ get disposed() {
1761
+ return this._disposed;
1723
1762
  }
1724
1763
  init() {
1725
1764
  if (!this.options) this.options = FlowDocumentOptionsDefault;
@@ -1745,6 +1784,7 @@ var FlowDocument = class {
1745
1784
  * @param fireRender 是否要触发渲染,默认 true
1746
1785
  */
1747
1786
  fromJSON(json, fireRender = true) {
1787
+ if (this._disposed) return;
1748
1788
  this.originTree.clear();
1749
1789
  this.renderTree.clear();
1750
1790
  this.entityManager.changeEntityLocked = true;
@@ -1813,7 +1853,7 @@ var FlowDocument = class {
1813
1853
  * @param data
1814
1854
  * @param addedNodes
1815
1855
  */
1816
- addNode(data, addedNodes, ignoreCreateEvent) {
1856
+ addNode(data, addedNodes) {
1817
1857
  const { id, type = "block", originParent, parent, meta, hidden, index } = data;
1818
1858
  let node = this.getNode(id);
1819
1859
  let isNew = false;
@@ -1834,10 +1874,10 @@ var FlowDocument = class {
1834
1874
  const datas = dataRegistries ? this.nodeDataRegistries.concat(...dataRegistries) : this.nodeDataRegistries;
1835
1875
  node.addInitializeData(datas);
1836
1876
  node.onDispose(() => this.onNodeDisposeEmitter.fire({ node }));
1837
- if (this.options.fromNodeJSON) {
1838
- this.options.fromNodeJSON(node, data);
1839
- }
1877
+ this.options.fromNodeJSON?.(node, data, true);
1840
1878
  isNew = true;
1879
+ } else {
1880
+ this.options.fromNodeJSON?.(node, data, false);
1841
1881
  }
1842
1882
  node.initData({
1843
1883
  originParent,
@@ -1849,7 +1889,6 @@ var FlowDocument = class {
1849
1889
  if (node.isStart) {
1850
1890
  this.root.addChild(node);
1851
1891
  }
1852
- this.onNodeUpdateEmitter.fire({ node, data });
1853
1892
  addedNodes?.push(node);
1854
1893
  if (register.onCreate) {
1855
1894
  const extendNodes = register.onCreate(node, data);
@@ -1863,11 +1902,14 @@ var FlowDocument = class {
1863
1902
  this.addBlocksAsChildren(node, data.blocks, addedNodes);
1864
1903
  }
1865
1904
  }
1866
- if (isNew && !ignoreCreateEvent) {
1905
+ if (isNew) {
1867
1906
  this.onNodeCreateEmitter.fire({
1868
1907
  node,
1869
- data
1908
+ data,
1909
+ json: data
1870
1910
  });
1911
+ } else {
1912
+ this.onNodeUpdateEmitter.fire({ node, data, json: data });
1871
1913
  }
1872
1914
  return node;
1873
1915
  }
@@ -1903,18 +1945,16 @@ var FlowDocument = class {
1903
1945
  parent: node
1904
1946
  });
1905
1947
  addedNodes.push(blockIconNode);
1906
- if (blocks.length > 0) {
1907
- const inlineBlocksNode = this.addNode({
1908
- id: `$inlineBlocks$${node.id}`,
1909
- type: "inlineBlocks" /* INLINE_BLOCKS */,
1910
- originParent: node,
1911
- parent: node
1912
- });
1913
- addedNodes.push(inlineBlocksNode);
1914
- blocks.forEach((blockData) => {
1915
- this.addBlock(node, blockData, addedNodes);
1916
- });
1917
- }
1948
+ const inlineBlocksNode = this.addNode({
1949
+ id: `$inlineBlocks$${node.id}`,
1950
+ type: "inlineBlocks" /* INLINE_BLOCKS */,
1951
+ originParent: node,
1952
+ parent: node
1953
+ });
1954
+ addedNodes.push(inlineBlocksNode);
1955
+ blocks.forEach((blockData) => {
1956
+ this.addBlock(node, blockData, addedNodes);
1957
+ });
1918
1958
  return addedNodes;
1919
1959
  }
1920
1960
  /**
@@ -1979,10 +2019,22 @@ var FlowDocument = class {
1979
2019
  meta: {
1980
2020
  ...preRegistry?.meta,
1981
2021
  ...newRegistry?.meta
1982
- }
2022
+ },
2023
+ extendChildRegistries: FlowNodeRegistry.mergeChildRegistries(
2024
+ preRegistry?.extendChildRegistries,
2025
+ newRegistry?.extendChildRegistries
2026
+ )
1983
2027
  });
1984
2028
  });
1985
2029
  }
2030
+ /**
2031
+ * Check node extend
2032
+ * @param currentType
2033
+ * @param parentType
2034
+ */
2035
+ isExtend(currentType, parentType) {
2036
+ return (this.getNodeRegistry(currentType).__extends__ || []).includes(parentType);
2037
+ }
1986
2038
  /**
1987
2039
  * 导出数据,可以重载
1988
2040
  */
@@ -2006,6 +2058,7 @@ var FlowDocument = class {
2006
2058
  const customDefaultRegistry = this.options.getNodeDefaultRegistry?.(type);
2007
2059
  let register = this.registers.get(type) || { type };
2008
2060
  const extendRegisters = [];
2061
+ const extendKey = register.extend;
2009
2062
  if (register.extend && this.registers.has(register.extend)) {
2010
2063
  register = FlowNodeRegistry.merge(
2011
2064
  this.getNodeRegistry(register.extend),
@@ -2036,6 +2089,9 @@ var FlowDocument = class {
2036
2089
  ...register.meta
2037
2090
  }
2038
2091
  };
2092
+ if (extendKey) {
2093
+ res.extend = extendKey;
2094
+ }
2039
2095
  this.nodeRegistryCache.set(typeKey, res);
2040
2096
  return res;
2041
2097
  }
@@ -2086,8 +2142,8 @@ var FlowDocument = class {
2086
2142
  getAllNodes() {
2087
2143
  return this.entityManager.getEntities(FlowNodeEntity);
2088
2144
  }
2089
- toString() {
2090
- return this.originTree.toString();
2145
+ toString(showType) {
2146
+ return this.originTree.toString(showType);
2091
2147
  }
2092
2148
  /**
2093
2149
  * 返回需要渲染的数据
@@ -2182,6 +2238,7 @@ var FlowDocument = class {
2182
2238
  );
2183
2239
  }
2184
2240
  dispose() {
2241
+ if (this._disposed) return;
2185
2242
  this.registers.clear();
2186
2243
  this.nodeRegistryCache.clear();
2187
2244
  this.originTree.dispose();
@@ -2190,6 +2247,7 @@ var FlowDocument = class {
2190
2247
  this.onNodeCreateEmitter.dispose();
2191
2248
  this.onNodeDisposeEmitter.dispose();
2192
2249
  this.onLayoutChangeEmitter.dispose();
2250
+ this._disposed = true;
2193
2251
  }
2194
2252
  };
2195
2253
  __decorateClass([
@@ -2217,135 +2275,427 @@ FlowDocument = __decorateClass([
2217
2275
  var import_inversify8 = require("inversify");
2218
2276
 
2219
2277
  // src/services/flow-drag-service.ts
2220
- var import_inversify5 = require("inversify");
2221
- var import_core10 = require("@flowgram.ai/core");
2222
- var import_utils9 = require("@flowgram.ai/utils");
2223
-
2224
- // src/services/flow-operation-base-service.ts
2225
2278
  var import_inversify3 = require("inversify");
2226
2279
  var import_utils8 = require("@flowgram.ai/utils");
2227
2280
  var import_core8 = require("@flowgram.ai/core");
2228
- var FlowOperationBaseServiceImpl = class {
2229
- constructor() {
2230
- this.onNodeAddEmitter = new import_utils8.Emitter();
2231
- this.onNodeAdd = this.onNodeAddEmitter.event;
2232
- this.toDispose = new import_utils8.DisposableCollection();
2233
- this.onNodeMoveEmitter = new import_utils8.Emitter();
2234
- this.onNodeMove = this.onNodeMoveEmitter.event;
2281
+
2282
+ // src/services/flow-group-service/flow-group-controller.ts
2283
+ var FlowGroupController = class _FlowGroupController {
2284
+ constructor(groupNode) {
2285
+ this.groupNode = groupNode;
2235
2286
  }
2236
- init() {
2237
- this.toDispose.pushAll([this.onNodeAddEmitter, this.onNodeMoveEmitter]);
2287
+ get nodes() {
2288
+ return this.groupNode.collapsedChildren || [];
2238
2289
  }
2239
- addNode(nodeJSON, config = {}) {
2240
- const { parent, index, hidden } = config;
2241
- let parentEntity;
2242
- if (parent) {
2243
- parentEntity = this.toNodeEntity(parent);
2290
+ get collapsed() {
2291
+ const groupTransformData = this.groupNode.getData(FlowNodeTransformData);
2292
+ return groupTransformData.collapsed;
2293
+ }
2294
+ collapse() {
2295
+ this.collapsed = true;
2296
+ }
2297
+ expand() {
2298
+ this.collapsed = false;
2299
+ }
2300
+ /** 获取分组外围的最大边框 */
2301
+ get bounds() {
2302
+ const groupNodeBounds = this.groupNode.getData(FlowNodeTransformData).bounds;
2303
+ return groupNodeBounds;
2304
+ }
2305
+ /** 是否是开始节点 */
2306
+ isStartNode(node) {
2307
+ if (!node) {
2308
+ return false;
2244
2309
  }
2245
- let register;
2246
- if (parentEntity) {
2247
- register = parentEntity.getNodeRegistry();
2310
+ const nodes = this.nodes;
2311
+ if (!nodes[0]) {
2312
+ return false;
2248
2313
  }
2249
- const addJSON = {
2250
- ...nodeJSON,
2251
- type: nodeJSON.type || "block" /* BLOCK */
2252
- };
2253
- const addNodeData = {
2254
- ...addJSON,
2255
- parent: parentEntity,
2256
- index,
2257
- hidden
2258
- };
2259
- let added;
2260
- if (parentEntity && register?.addChild) {
2261
- added = register.addChild(parentEntity, addJSON, {
2262
- index,
2263
- hidden
2264
- });
2265
- } else {
2266
- added = this.document.addNode(addNodeData);
2314
+ return node.id === nodes[0].id;
2315
+ }
2316
+ /** 是否是结束节点 */
2317
+ isEndNode(node) {
2318
+ if (!node) {
2319
+ return false;
2267
2320
  }
2268
- this.onNodeAddEmitter.fire({
2269
- node: added,
2270
- data: addNodeData
2271
- });
2272
- return added;
2321
+ const nodes = this.nodes;
2322
+ if (!nodes[nodes.length - 1]) {
2323
+ return false;
2324
+ }
2325
+ return node.id === nodes[nodes.length - 1].id;
2273
2326
  }
2274
- addFromNode(fromNode, nodeJSON) {
2275
- return this.document.addFromNode(fromNode, nodeJSON);
2327
+ set note(note) {
2328
+ this.groupNode.getNodeMeta().note = note;
2276
2329
  }
2277
- deleteNode(node) {
2278
- this.document.removeNode(node);
2330
+ get note() {
2331
+ return this.groupNode.getNodeMeta().note || "";
2279
2332
  }
2280
- deleteNodes(nodes) {
2281
- (nodes || []).forEach((node) => {
2282
- this.deleteNode(node);
2283
- });
2333
+ set noteHeight(height) {
2334
+ this.groupNode.getNodeMeta().noteHeight = height;
2284
2335
  }
2285
- addBlock(target, blockJSON, config = {}) {
2286
- const { parent, index } = config;
2287
- return this.document.addBlock(target, blockJSON, void 0, parent, index);
2336
+ get noteHeight() {
2337
+ return this.groupNode.getNodeMeta().noteHeight || 0;
2288
2338
  }
2289
- moveNode(node, config = {}) {
2290
- const { parent: newParent, index } = config;
2291
- const entity = this.toNodeEntity(node);
2292
- const parent = entity?.parent;
2293
- if (!parent) {
2294
- return;
2339
+ get positionConfig() {
2340
+ return this.groupNode.getNodeMeta().positionConfig;
2341
+ }
2342
+ set collapsed(collapsed) {
2343
+ const groupTransformData = this.groupNode.getData(FlowNodeTransformData);
2344
+ groupTransformData.collapsed = collapsed;
2345
+ groupTransformData.localDirty = true;
2346
+ if (groupTransformData.parent) groupTransformData.parent.localDirty = true;
2347
+ if (groupTransformData.parent?.firstChild)
2348
+ groupTransformData.parent.firstChild.localDirty = true;
2349
+ }
2350
+ set hovered(hovered) {
2351
+ const groupRenderData = this.groupNode.getData(FlowNodeRenderData);
2352
+ if (hovered) {
2353
+ groupRenderData.toggleMouseEnter();
2354
+ } else {
2355
+ groupRenderData.toggleMouseLeave();
2295
2356
  }
2296
- const newParentEntity = newParent ? this.toNodeEntity(newParent) : parent;
2297
- if (!newParentEntity) {
2298
- console.warn("no new parent found", newParent);
2357
+ if (groupRenderData.hovered === hovered) {
2299
2358
  return;
2300
2359
  }
2301
- let toIndex = typeof index === "undefined" ? newParentEntity.collapsedChildren.length : index;
2302
- return this.doMoveNode(entity, newParentEntity, toIndex);
2360
+ groupRenderData.hovered = hovered;
2303
2361
  }
2304
- /**
2305
- * 拖拽节点
2306
- * @param param0
2307
- * @returns
2308
- */
2309
- dragNodes({ dropNode, nodes }) {
2310
- if (nodes.length === 0) {
2362
+ get hovered() {
2363
+ const groupRenderData = this.groupNode.getData(FlowNodeRenderData);
2364
+ return groupRenderData.hovered;
2365
+ }
2366
+ static create(groupNode) {
2367
+ if (!groupNode) {
2311
2368
  return;
2312
2369
  }
2313
- const startNode = nodes[0];
2314
- const fromParent = startNode.parent;
2315
- const toParent = dropNode.parent;
2316
- if (!fromParent || !toParent) {
2370
+ if (!FlowGroupUtils.isGroupNode(groupNode)) {
2317
2371
  return;
2318
2372
  }
2319
- const fromIndex = fromParent.children.findIndex((child) => child === startNode);
2320
- const dropIndex = toParent.children.findIndex((child) => child === dropNode);
2321
- let toIndex = dropIndex + 1;
2322
- if (fromParent === toParent && fromIndex < dropIndex) {
2323
- toIndex = toIndex - nodes.length;
2373
+ return new _FlowGroupController(groupNode);
2374
+ }
2375
+ };
2376
+
2377
+ // src/services/flow-group-service/flow-group-utils.ts
2378
+ var FlowGroupUtils;
2379
+ ((FlowGroupUtils2) => {
2380
+ const findNodeParents = (node) => {
2381
+ const parents = [];
2382
+ let parent = node.parent;
2383
+ while (parent) {
2384
+ parents.push(parent);
2385
+ parent = parent.parent;
2324
2386
  }
2325
- const value = {
2326
- nodeIds: nodes.map((node) => node.id),
2327
- fromParentId: fromParent.id,
2328
- toParentId: toParent.id,
2329
- fromIndex,
2330
- toIndex
2331
- };
2332
- return this.apply({
2333
- type: "moveChildNodes" /* moveChildNodes */,
2334
- value
2387
+ return parents;
2388
+ };
2389
+ const isNodeInGroup = (node) => {
2390
+ if (node?.parent?.flowNodeType === "group" /* GROUP */) {
2391
+ return true;
2392
+ }
2393
+ return false;
2394
+ };
2395
+ FlowGroupUtils2.validate = (nodes) => {
2396
+ if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {
2397
+ return false;
2398
+ }
2399
+ const isGroupRelatedNode = nodes.some((node) => (0, FlowGroupUtils2.isGroupNode)(node));
2400
+ if (isGroupRelatedNode) return false;
2401
+ const hasGroup = nodes.some((node) => node && isNodeInGroup(node));
2402
+ if (hasGroup) return false;
2403
+ const parent = nodes[0].parent;
2404
+ const isSameParent = nodes.every((node) => node.parent === parent);
2405
+ if (!isSameParent) return false;
2406
+ const indexes = nodes.map((node) => node.index).sort((a, b) => a - b);
2407
+ const isIndexContinuous = indexes.every((index, i, arr) => {
2408
+ if (i === 0) {
2409
+ return true;
2410
+ }
2411
+ return index === arr[i - 1] + 1;
2335
2412
  });
2413
+ if (!isIndexContinuous) return false;
2414
+ const parents = findNodeParents(nodes[0]);
2415
+ const parentsInGroup = parents.some((parent2) => isNodeInGroup(parent2));
2416
+ if (parentsInGroup) return false;
2417
+ return true;
2418
+ };
2419
+ FlowGroupUtils2.getNodeGroupController = (node) => {
2420
+ if (!node) {
2421
+ return;
2422
+ }
2423
+ if (!isNodeInGroup(node)) {
2424
+ return;
2425
+ }
2426
+ const groupNode = node?.parent;
2427
+ return FlowGroupController.create(groupNode);
2428
+ };
2429
+ FlowGroupUtils2.getNodeRecursionGroupController = (node) => {
2430
+ if (!node) {
2431
+ return;
2432
+ }
2433
+ const group = (0, FlowGroupUtils2.getNodeGroupController)(node);
2434
+ if (group) {
2435
+ return group;
2436
+ }
2437
+ if (node.parent) {
2438
+ return (0, FlowGroupUtils2.getNodeRecursionGroupController)(node.parent);
2439
+ }
2440
+ return;
2441
+ };
2442
+ FlowGroupUtils2.isGroupNode = (group) => group.flowNodeType === "group" /* GROUP */;
2443
+ })(FlowGroupUtils || (FlowGroupUtils = {}));
2444
+
2445
+ // src/services/flow-drag-service.ts
2446
+ var FlowDragService = class {
2447
+ constructor() {
2448
+ this.onDropEmitter = new import_utils8.Emitter();
2449
+ this.onDrop = this.onDropEmitter.event;
2336
2450
  }
2337
- /**
2338
- * 执行操作
2339
- * @param operation 可序列化的操作
2340
- * @returns 操作返回
2341
- */
2342
- apply(operation) {
2343
- const document = this.document;
2344
- switch (operation.type) {
2345
- case "addFromNode" /* addFromNode */:
2346
- return document.addFromNode(operation.value.fromId, operation.value.data);
2347
- case "deleteFromNode" /* deleteFromNode */:
2348
- return document.getNode(operation.value?.data?.id)?.dispose();
2451
+ get renderState() {
2452
+ return this.document.renderState;
2453
+ }
2454
+ // 拖拽所有节点中的首个节点
2455
+ get dragStartNode() {
2456
+ return this.renderState.getDragStartEntity();
2457
+ }
2458
+ // 拖拽的所有节点
2459
+ get dragNodes() {
2460
+ return this.renderState.getDragEntities();
2461
+ }
2462
+ // 放置的区域
2463
+ get dropNodeId() {
2464
+ return this.renderState.getNodeDroppingId();
2465
+ }
2466
+ // 是否在拖拽分支
2467
+ get isDragBranch() {
2468
+ return this.dragStartNode?.isInlineBlock;
2469
+ }
2470
+ // 拖拽的所有节点及其自节点
2471
+ get nodeDragIdsWithChildren() {
2472
+ return this.renderState.config.nodeDragIdsWithChildren || [];
2473
+ }
2474
+ get dragging() {
2475
+ const renderData = this.dragStartNode?.getData(FlowNodeRenderData);
2476
+ return !!renderData?.dragging;
2477
+ }
2478
+ get labelSide() {
2479
+ return this.renderState.config.dragLabelSide;
2480
+ }
2481
+ /**
2482
+ * 放置到目标分支
2483
+ */
2484
+ dropBranch() {
2485
+ this.dropNode();
2486
+ }
2487
+ /**
2488
+ * 移动到目标节点
2489
+ */
2490
+ dropNode() {
2491
+ const dropEntity = this.document.getNode(this.dropNodeId);
2492
+ if (!dropEntity) {
2493
+ return;
2494
+ }
2495
+ const sortNodes = [];
2496
+ let curr = this.dragStartNode;
2497
+ while (curr && this.dragNodes.includes(curr)) {
2498
+ sortNodes.push(curr);
2499
+ curr = curr.next;
2500
+ }
2501
+ this.operationService.dragNodes({
2502
+ dropNode: dropEntity,
2503
+ nodes: sortNodes
2504
+ });
2505
+ if (sortNodes.length > 0) {
2506
+ this.onDropEmitter.fire({
2507
+ dropNode: dropEntity,
2508
+ dragNodes: sortNodes
2509
+ });
2510
+ }
2511
+ }
2512
+ /**
2513
+ * 拖拽是否可以释放在该节点后面
2514
+ */
2515
+ isDroppableNode(node) {
2516
+ if (!this.dragging || this.isDragBranch) {
2517
+ return false;
2518
+ }
2519
+ if (this.nodeDragIdsWithChildren.includes(node.id) || node.next && this.nodeDragIdsWithChildren.includes(node.next.id)) {
2520
+ return false;
2521
+ }
2522
+ if (node.isInlineBlocks || node.isInlineBlock) {
2523
+ return false;
2524
+ }
2525
+ const hasGroupNode = this.dragNodes.some(
2526
+ (node2) => node2.flowNodeType === "group" /* GROUP */
2527
+ );
2528
+ if (hasGroupNode) {
2529
+ const group = FlowGroupUtils.getNodeRecursionGroupController(node);
2530
+ if (group) {
2531
+ return false;
2532
+ }
2533
+ }
2534
+ return true;
2535
+ }
2536
+ /**
2537
+ * 拖拽分支是否可以释放在该分支
2538
+ * @param node 拖拽的分支节点
2539
+ * @param side 分支的前面还是后面
2540
+ */
2541
+ isDroppableBranch(node, side = "normal_branch" /* NORMAL_BRANCH */) {
2542
+ if (this.isDragBranch) {
2543
+ if (
2544
+ // 拖拽到分支
2545
+ !node.isInlineBlock || // 只能在同一分支条件下
2546
+ node.parent !== this.dragStartNode.parent || // 自己不能拖拽给自己
2547
+ node === this.dragStartNode
2548
+ ) {
2549
+ return false;
2550
+ }
2551
+ if (side === "normal_branch" /* NORMAL_BRANCH */ && node.next !== this.dragStartNode) {
2552
+ return true;
2553
+ }
2554
+ if (side === "pre_branch" /* PRE_BRANCH */ && node.pre !== this.dragStartNode) {
2555
+ return true;
2556
+ }
2557
+ }
2558
+ return false;
2559
+ }
2560
+ };
2561
+ __decorateClass([
2562
+ (0, import_inversify3.inject)(FlowDocument)
2563
+ ], FlowDragService.prototype, "document", 2);
2564
+ __decorateClass([
2565
+ (0, import_inversify3.inject)(FlowOperationBaseService)
2566
+ ], FlowDragService.prototype, "operationService", 2);
2567
+ __decorateClass([
2568
+ (0, import_inversify3.inject)(import_core8.EntityManager)
2569
+ ], FlowDragService.prototype, "entityManager", 2);
2570
+ FlowDragService = __decorateClass([
2571
+ (0, import_inversify3.injectable)()
2572
+ ], FlowDragService);
2573
+
2574
+ // src/services/flow-operation-base-service.ts
2575
+ var import_inversify4 = require("inversify");
2576
+ var import_utils9 = require("@flowgram.ai/utils");
2577
+ var import_core9 = require("@flowgram.ai/core");
2578
+ var FlowOperationBaseServiceImpl = class {
2579
+ constructor() {
2580
+ this.onNodeAddEmitter = new import_utils9.Emitter();
2581
+ this.onNodeAdd = this.onNodeAddEmitter.event;
2582
+ this.toDispose = new import_utils9.DisposableCollection();
2583
+ this.onNodeMoveEmitter = new import_utils9.Emitter();
2584
+ this.onNodeMove = this.onNodeMoveEmitter.event;
2585
+ }
2586
+ init() {
2587
+ this.toDispose.pushAll([this.onNodeAddEmitter, this.onNodeMoveEmitter]);
2588
+ }
2589
+ addNode(nodeJSON, config = {}) {
2590
+ const { parent, index, hidden } = config;
2591
+ let parentEntity;
2592
+ if (parent) {
2593
+ parentEntity = this.toNodeEntity(parent);
2594
+ }
2595
+ let register;
2596
+ if (parentEntity) {
2597
+ register = parentEntity.getNodeRegistry();
2598
+ }
2599
+ const addJSON = {
2600
+ ...nodeJSON,
2601
+ type: nodeJSON.type || "block" /* BLOCK */
2602
+ };
2603
+ const addNodeData = {
2604
+ ...addJSON,
2605
+ parent: parentEntity,
2606
+ index,
2607
+ hidden
2608
+ };
2609
+ let added;
2610
+ if (parentEntity && register?.addChild) {
2611
+ added = register.addChild(parentEntity, addJSON, {
2612
+ index,
2613
+ hidden
2614
+ });
2615
+ } else {
2616
+ added = this.document.addNode(addNodeData);
2617
+ }
2618
+ this.onNodeAddEmitter.fire({
2619
+ node: added,
2620
+ data: addNodeData
2621
+ });
2622
+ return added;
2623
+ }
2624
+ addFromNode(fromNode, nodeJSON) {
2625
+ return this.document.addFromNode(fromNode, nodeJSON);
2626
+ }
2627
+ deleteNode(node) {
2628
+ this.document.removeNode(node);
2629
+ }
2630
+ deleteNodes(nodes) {
2631
+ (nodes || []).forEach((node) => {
2632
+ this.deleteNode(node);
2633
+ });
2634
+ }
2635
+ addBlock(target, blockJSON, config = {}) {
2636
+ const { parent, index } = config;
2637
+ return this.document.addBlock(target, blockJSON, void 0, parent, index);
2638
+ }
2639
+ moveNode(node, config = {}) {
2640
+ const { parent: newParent, index } = config;
2641
+ const entity = this.toNodeEntity(node);
2642
+ const parent = entity?.parent;
2643
+ if (!parent) {
2644
+ return;
2645
+ }
2646
+ const newParentEntity = newParent ? this.toNodeEntity(newParent) : parent;
2647
+ if (!newParentEntity) {
2648
+ console.warn("no new parent found", newParent);
2649
+ return;
2650
+ }
2651
+ let toIndex = typeof index === "undefined" ? newParentEntity.collapsedChildren.length : index;
2652
+ return this.doMoveNode(entity, newParentEntity, toIndex);
2653
+ }
2654
+ /**
2655
+ * 拖拽节点
2656
+ * @param param0
2657
+ * @returns
2658
+ */
2659
+ dragNodes({ dropNode, nodes }) {
2660
+ if (nodes.length === 0) {
2661
+ return;
2662
+ }
2663
+ const startNode = nodes[0];
2664
+ const fromParent = startNode.parent;
2665
+ const toParent = dropNode.parent;
2666
+ if (!fromParent || !toParent) {
2667
+ return;
2668
+ }
2669
+ const fromIndex = fromParent.children.findIndex((child) => child === startNode);
2670
+ const dropIndex = toParent.children.findIndex((child) => child === dropNode);
2671
+ let toIndex = dropIndex + 1;
2672
+ if (fromParent === toParent && fromIndex < dropIndex) {
2673
+ toIndex = toIndex - nodes.length;
2674
+ }
2675
+ const value = {
2676
+ nodeIds: nodes.map((node) => node.id),
2677
+ fromParentId: fromParent.id,
2678
+ toParentId: toParent.id,
2679
+ fromIndex,
2680
+ toIndex
2681
+ };
2682
+ return this.apply({
2683
+ type: "moveChildNodes" /* moveChildNodes */,
2684
+ value
2685
+ });
2686
+ }
2687
+ /**
2688
+ * 执行操作
2689
+ * @param operation 可序列化的操作
2690
+ * @returns 操作返回
2691
+ */
2692
+ apply(operation) {
2693
+ const document = this.document;
2694
+ switch (operation.type) {
2695
+ case "addFromNode" /* addFromNode */:
2696
+ return document.addFromNode(operation.value.fromId, operation.value.data);
2697
+ case "deleteFromNode" /* deleteFromNode */:
2698
+ return document.getNode(operation.value?.data?.id)?.dispose();
2349
2699
  case "addBlock" /* addBlock */: {
2350
2700
  let parent;
2351
2701
  if (operation.value.parentId) {
@@ -2470,29 +2820,29 @@ var FlowOperationBaseServiceImpl = class {
2470
2820
  }
2471
2821
  };
2472
2822
  __decorateClass([
2473
- (0, import_inversify3.inject)(import_core8.EntityManager)
2823
+ (0, import_inversify4.inject)(import_core9.EntityManager)
2474
2824
  ], FlowOperationBaseServiceImpl.prototype, "entityManager", 2);
2475
2825
  __decorateClass([
2476
- (0, import_inversify3.inject)(FlowDocument)
2826
+ (0, import_inversify4.inject)(FlowDocument)
2477
2827
  ], FlowOperationBaseServiceImpl.prototype, "document", 2);
2478
2828
  __decorateClass([
2479
- (0, import_inversify3.postConstruct)()
2829
+ (0, import_inversify4.postConstruct)()
2480
2830
  ], FlowOperationBaseServiceImpl.prototype, "init", 1);
2481
2831
  FlowOperationBaseServiceImpl = __decorateClass([
2482
- (0, import_inversify3.injectable)()
2832
+ (0, import_inversify4.injectable)()
2483
2833
  ], FlowOperationBaseServiceImpl);
2484
2834
 
2485
- // src/services/flow-group-service.ts
2835
+ // src/services/flow-group-service/flow-group-service.ts
2486
2836
  var import_nanoid = require("nanoid");
2487
- var import_inversify4 = require("inversify");
2488
- var import_core9 = require("@flowgram.ai/core");
2837
+ var import_inversify5 = require("inversify");
2838
+ var import_core10 = require("@flowgram.ai/core");
2489
2839
  var FlowGroupService = class {
2490
2840
  /** 创建分组节点 */
2491
2841
  createGroup(nodes) {
2492
2842
  if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {
2493
2843
  return;
2494
2844
  }
2495
- if (!FlowGroupController.validate(nodes)) {
2845
+ if (!FlowGroupUtils.validate(nodes)) {
2496
2846
  return;
2497
2847
  }
2498
2848
  const sortedNodes = nodes.sort((a, b) => a.index - b.index);
@@ -2562,309 +2912,18 @@ var FlowGroupService = class {
2562
2912
  return FlowGroupController.create(group);
2563
2913
  }
2564
2914
  static validate(nodes) {
2565
- return FlowGroupController.validate(nodes);
2915
+ return FlowGroupUtils.validate(nodes);
2566
2916
  }
2567
2917
  };
2568
2918
  __decorateClass([
2569
- (0, import_inversify4.inject)(import_core9.EntityManager)
2919
+ (0, import_inversify5.inject)(import_core10.EntityManager)
2570
2920
  ], FlowGroupService.prototype, "entityManager", 2);
2571
2921
  __decorateClass([
2572
- (0, import_inversify4.inject)(FlowOperationBaseService)
2922
+ (0, import_inversify5.inject)(FlowOperationBaseService)
2573
2923
  ], FlowGroupService.prototype, "operationService", 2);
2574
2924
  FlowGroupService = __decorateClass([
2575
- (0, import_inversify4.injectable)()
2925
+ (0, import_inversify5.injectable)()
2576
2926
  ], FlowGroupService);
2577
- var FlowGroupController = class _FlowGroupController {
2578
- constructor(groupNode) {
2579
- this.groupNode = groupNode;
2580
- }
2581
- get nodes() {
2582
- return this.groupNode.collapsedChildren || [];
2583
- }
2584
- get collapsed() {
2585
- const groupTransformData = this.groupNode.getData(FlowNodeTransformData);
2586
- return groupTransformData.collapsed;
2587
- }
2588
- collapse() {
2589
- this.collapsed = true;
2590
- }
2591
- expand() {
2592
- this.collapsed = false;
2593
- }
2594
- /** 获取分组外围的最大边框 */
2595
- get bounds() {
2596
- const groupNodeBounds = this.groupNode.getData(FlowNodeTransformData).bounds;
2597
- return groupNodeBounds;
2598
- }
2599
- /** 是否是开始节点 */
2600
- isStartNode(node) {
2601
- if (!node) {
2602
- return false;
2603
- }
2604
- const nodes = this.nodes;
2605
- if (!nodes[0]) {
2606
- return false;
2607
- }
2608
- return node.id === nodes[0].id;
2609
- }
2610
- /** 是否是结束节点 */
2611
- isEndNode(node) {
2612
- if (!node) {
2613
- return false;
2614
- }
2615
- const nodes = this.nodes;
2616
- if (!nodes[nodes.length - 1]) {
2617
- return false;
2618
- }
2619
- return node.id === nodes[nodes.length - 1].id;
2620
- }
2621
- set note(note) {
2622
- this.groupNode.getNodeMeta().note = note;
2623
- }
2624
- get note() {
2625
- return this.groupNode.getNodeMeta().note || "";
2626
- }
2627
- set noteHeight(height) {
2628
- this.groupNode.getNodeMeta().noteHeight = height;
2629
- }
2630
- get noteHeight() {
2631
- return this.groupNode.getNodeMeta().noteHeight || 0;
2632
- }
2633
- get positionConfig() {
2634
- return this.groupNode.getNodeMeta().positionConfig;
2635
- }
2636
- set collapsed(collapsed) {
2637
- const groupTransformData = this.groupNode.getData(FlowNodeTransformData);
2638
- groupTransformData.collapsed = collapsed;
2639
- groupTransformData.localDirty = true;
2640
- if (groupTransformData.parent) groupTransformData.parent.localDirty = true;
2641
- if (groupTransformData.parent?.firstChild)
2642
- groupTransformData.parent.firstChild.localDirty = true;
2643
- }
2644
- set hovered(hovered) {
2645
- const groupRenderData = this.groupNode.getData(FlowNodeRenderData);
2646
- if (hovered) {
2647
- groupRenderData.toggleMouseEnter();
2648
- } else {
2649
- groupRenderData.toggleMouseLeave();
2650
- }
2651
- if (groupRenderData.hovered === hovered) {
2652
- return;
2653
- }
2654
- groupRenderData.hovered = hovered;
2655
- }
2656
- get hovered() {
2657
- const groupRenderData = this.groupNode.getData(FlowNodeRenderData);
2658
- return groupRenderData.hovered;
2659
- }
2660
- static create(groupNode) {
2661
- if (!groupNode) {
2662
- return;
2663
- }
2664
- if (!_FlowGroupController.isGroupNode(groupNode)) {
2665
- return;
2666
- }
2667
- return new _FlowGroupController(groupNode);
2668
- }
2669
- /** 判断节点能否组成分组 */
2670
- static validate(nodes) {
2671
- if (!nodes || !Array.isArray(nodes) || nodes.length === 0) {
2672
- return false;
2673
- }
2674
- const isGroupRelatedNode = nodes.some((node) => _FlowGroupController.isGroupNode(node));
2675
- if (isGroupRelatedNode) return false;
2676
- const hasGroup = nodes.some((node) => node && this.isNodeInGroup(node));
2677
- if (hasGroup) return false;
2678
- const parent = nodes[0].parent;
2679
- const isSameParent = nodes.every((node) => node.parent === parent);
2680
- if (!isSameParent) return false;
2681
- const indexes = nodes.map((node) => node.index).sort((a, b) => a - b);
2682
- const isIndexContinuous = indexes.every((index, i, arr) => {
2683
- if (i === 0) {
2684
- return true;
2685
- }
2686
- return index === arr[i - 1] + 1;
2687
- });
2688
- if (!isIndexContinuous) return false;
2689
- const parents = this.findNodeParents(nodes[0]);
2690
- const parentsInGroup = parents.some((parent2) => this.isNodeInGroup(parent2));
2691
- if (parentsInGroup) return false;
2692
- return true;
2693
- }
2694
- /** 获取节点分组控制 */
2695
- static getNodeGroupController(node) {
2696
- if (!node) {
2697
- return;
2698
- }
2699
- if (!this.isNodeInGroup(node)) {
2700
- return;
2701
- }
2702
- const groupNode = node?.parent;
2703
- return _FlowGroupController.create(groupNode);
2704
- }
2705
- /** 向上递归查找分组递归控制 */
2706
- static getNodeRecursionGroupController(node) {
2707
- if (!node) {
2708
- return;
2709
- }
2710
- const group = this.getNodeGroupController(node);
2711
- if (group) {
2712
- return group;
2713
- }
2714
- if (node.parent) {
2715
- return this.getNodeRecursionGroupController(node.parent);
2716
- }
2717
- return;
2718
- }
2719
- /** 是否分组节点 */
2720
- static isGroupNode(group) {
2721
- return group.flowNodeType === "group" /* GROUP */;
2722
- }
2723
- /** 找到节点所有上级 */
2724
- static findNodeParents(node) {
2725
- const parents = [];
2726
- let parent = node.parent;
2727
- while (parent) {
2728
- parents.push(parent);
2729
- parent = parent.parent;
2730
- }
2731
- return parents;
2732
- }
2733
- /** 节点是否处于分组中 */
2734
- static isNodeInGroup(node) {
2735
- if (node?.parent?.flowNodeType === "group" /* GROUP */) {
2736
- return true;
2737
- }
2738
- return false;
2739
- }
2740
- };
2741
-
2742
- // src/services/flow-drag-service.ts
2743
- var FlowDragService = class {
2744
- constructor() {
2745
- this.onDropEmitter = new import_utils9.Emitter();
2746
- this.onDrop = this.onDropEmitter.event;
2747
- }
2748
- get renderState() {
2749
- return this.document.renderState;
2750
- }
2751
- // 拖拽所有节点中的首个节点
2752
- get dragStartNode() {
2753
- return this.renderState.getDragStartEntity();
2754
- }
2755
- // 拖拽的所有节点
2756
- get dragNodes() {
2757
- return this.renderState.getDragEntities();
2758
- }
2759
- // 放置的区域
2760
- get dropNodeId() {
2761
- return this.renderState.getNodeDroppingId();
2762
- }
2763
- // 是否在拖拽分支
2764
- get isDragBranch() {
2765
- return this.dragStartNode?.isInlineBlock;
2766
- }
2767
- // 拖拽的所有节点及其自节点
2768
- get nodeDragIdsWithChildren() {
2769
- return this.renderState.config.nodeDragIdsWithChildren || [];
2770
- }
2771
- get dragging() {
2772
- const renderData = this.dragStartNode?.getData(FlowNodeRenderData);
2773
- return !!renderData?.dragging;
2774
- }
2775
- get labelSide() {
2776
- return this.renderState.config.dragLabelSide;
2777
- }
2778
- /**
2779
- * 放置到目标分支
2780
- */
2781
- dropBranch() {
2782
- this.dropNode();
2783
- }
2784
- /**
2785
- * 移动到目标节点
2786
- */
2787
- dropNode() {
2788
- const dropEntity = this.document.getNode(this.dropNodeId);
2789
- if (!dropEntity) {
2790
- return;
2791
- }
2792
- const sortNodes = [];
2793
- let curr = this.dragStartNode;
2794
- while (curr && this.dragNodes.includes(curr)) {
2795
- sortNodes.push(curr);
2796
- curr = curr.next;
2797
- }
2798
- this.operationService.dragNodes({
2799
- dropNode: dropEntity,
2800
- nodes: sortNodes
2801
- });
2802
- if (sortNodes.length > 0) {
2803
- this.onDropEmitter.fire({
2804
- dropNode: dropEntity,
2805
- dragNodes: sortNodes
2806
- });
2807
- }
2808
- }
2809
- /**
2810
- * 拖拽是否可以释放在该节点后面
2811
- */
2812
- isDroppableNode(node) {
2813
- if (!this.dragging || this.isDragBranch) {
2814
- return false;
2815
- }
2816
- if (this.nodeDragIdsWithChildren.includes(node.id) || node.next && this.nodeDragIdsWithChildren.includes(node.next.id)) {
2817
- return false;
2818
- }
2819
- if (node.isInlineBlocks || node.isInlineBlock) {
2820
- return false;
2821
- }
2822
- const hasGroupNode = this.dragNodes.some((node2) => node2.flowNodeType === "group" /* GROUP */);
2823
- if (hasGroupNode) {
2824
- const group = FlowGroupController.getNodeRecursionGroupController(node);
2825
- if (group) {
2826
- return false;
2827
- }
2828
- }
2829
- return true;
2830
- }
2831
- /**
2832
- * 拖拽分支是否可以释放在该分支
2833
- * @param node 拖拽的分支节点
2834
- * @param side 分支的前面还是后面
2835
- */
2836
- isDroppableBranch(node, side = "normal_branch" /* NORMAL_BRANCH */) {
2837
- if (this.isDragBranch) {
2838
- if (
2839
- // 拖拽到分支
2840
- !node.isInlineBlock || // 只能在同一分支条件下
2841
- node.parent !== this.dragStartNode.parent || // 自己不能拖拽给自己
2842
- node === this.dragStartNode
2843
- ) {
2844
- return false;
2845
- }
2846
- if (side === "normal_branch" /* NORMAL_BRANCH */ && node.next !== this.dragStartNode) {
2847
- return true;
2848
- }
2849
- if (side === "pre_branch" /* PRE_BRANCH */ && node.pre !== this.dragStartNode) {
2850
- return true;
2851
- }
2852
- }
2853
- return false;
2854
- }
2855
- };
2856
- __decorateClass([
2857
- (0, import_inversify5.inject)(FlowDocument)
2858
- ], FlowDragService.prototype, "document", 2);
2859
- __decorateClass([
2860
- (0, import_inversify5.inject)(FlowOperationBaseService)
2861
- ], FlowDragService.prototype, "operationService", 2);
2862
- __decorateClass([
2863
- (0, import_inversify5.inject)(import_core10.EntityManager)
2864
- ], FlowDragService.prototype, "entityManager", 2);
2865
- FlowDragService = __decorateClass([
2866
- (0, import_inversify5.injectable)()
2867
- ], FlowDragService);
2868
2927
 
2869
2928
  // src/layout/vertical-fixed-layout.ts
2870
2929
  var import_inversify6 = require("inversify");