@flowgram.ai/free-layout-core 0.2.27 → 0.2.29

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/esm/index.js CHANGED
@@ -72,6 +72,34 @@ import { Rectangle as Rectangle6, SizeSchema } from "@flowgram.ai/utils";
72
72
  import { bindConfigEntity } from "@flowgram.ai/core";
73
73
  import { delay } from "@flowgram.ai/utils";
74
74
 
75
+ // src/utils/build-group-json.ts
76
+ import { FlowNodeBaseType } from "@flowgram.ai/document";
77
+ var buildGroupJSON = (json) => {
78
+ const { nodes, edges } = json;
79
+ const groupJSONs = nodes.filter(
80
+ (nodeJSON) => nodeJSON.type === FlowNodeBaseType.GROUP
81
+ );
82
+ const nodeJSONMap = new Map(nodes.map((n) => [n.id, n]));
83
+ const groupNodeJSONs = groupJSONs.map((groupJSON) => {
84
+ const groupBlocks = (groupJSON.data.blockIDs ?? []).map((blockID) => nodeJSONMap.get(blockID)).filter(Boolean);
85
+ const groupEdges = edges?.filter(
86
+ (edge) => groupBlocks.some((block) => block.id === edge.sourceNodeID || block.id === edge.targetNodeID)
87
+ );
88
+ const groupNodeJSON = {
89
+ ...groupJSON,
90
+ blocks: groupBlocks,
91
+ edges: groupEdges
92
+ };
93
+ return groupNodeJSON;
94
+ });
95
+ const groupBlockSet = new Set(groupJSONs.map((groupJSON) => groupJSON.data.blockIDs).flat());
96
+ const processedNodes = nodes.filter((nodeJSON) => !groupBlockSet.has(nodeJSON.id)).concat(groupNodeJSONs);
97
+ return {
98
+ nodes: processedNodes,
99
+ edges
100
+ };
101
+ };
102
+
75
103
  // src/utils/nanoid.ts
76
104
  import { nanoid as nanoidOrigin } from "nanoid";
77
105
  function nanoid(n) {
@@ -173,15 +201,16 @@ var WorkflowPortEntity = class extends Entity {
173
201
  }
174
202
  // 设置连线的错误态,外部应使用 validate 进行更新
175
203
  set hasError(hasError) {
176
- this._hasError = hasError;
177
- this._onErrorChangedEmitter.fire();
204
+ if (hasError !== this._hasError) {
205
+ this._hasError = hasError;
206
+ this._onErrorChangedEmitter.fire();
207
+ }
178
208
  }
179
209
  validate() {
180
210
  const anyLineHasError = this.allLines.some((line) => {
181
211
  if (line.disposed || line.isHidden) {
182
212
  return false;
183
213
  }
184
- line.validateSelf();
185
214
  return line.hasError;
186
215
  });
187
216
  const isPortHasError = this.node.document.isErrorPort(this);
@@ -375,7 +404,6 @@ var WorkflowNodePortsData = class extends EntityData {
375
404
  port.allLines.forEach((line) => {
376
405
  line.validate();
377
406
  });
378
- port.validate();
379
407
  });
380
408
  }
381
409
  /**
@@ -506,6 +534,9 @@ var _WorkflowNodeLinesData = class _WorkflowNodeLinesData extends EntityData2 {
506
534
  get outputLines() {
507
535
  return this.data.outputLines;
508
536
  }
537
+ get allLines() {
538
+ return this.data.inputLines.concat(this.data.outputLines);
539
+ }
509
540
  /**
510
541
  * 输入节点
511
542
  */
@@ -721,6 +752,14 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
721
752
  if (opts.drawingTo) {
722
753
  this.isDrawing = true;
723
754
  }
755
+ this.onEntityChange(() => {
756
+ this.fromPort?.validate();
757
+ this.toPort?.validate();
758
+ });
759
+ this.onDispose(() => {
760
+ this.fromPort?.validate();
761
+ this.toPort?.validate();
762
+ });
724
763
  }
725
764
  /**
726
765
  * 转成线条 id
@@ -826,6 +865,7 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
826
865
  if (this.toPort === toPort) {
827
866
  return;
828
867
  }
868
+ const prePort = this.toPort;
829
869
  if (toPort && toPort.portType === "input" && this.linesManager.canAddLine(this.fromPort, toPort, true)) {
830
870
  const { node, portID } = toPort;
831
871
  this._to = node;
@@ -838,6 +878,9 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
838
878
  this.info.to = void 0;
839
879
  this.info.toPort = "";
840
880
  }
881
+ if (prePort) {
882
+ prePort.validate();
883
+ }
841
884
  this.fireChange();
842
885
  }
843
886
  /**
@@ -951,11 +994,12 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends Entity2 {
951
994
  }
952
995
  // 校验连线是否为错误态
953
996
  validate() {
954
- const { fromPort, toPort } = this;
955
997
  this.validateSelf();
956
- fromPort?.validate();
957
- toPort?.validate();
958
998
  }
999
+ /**
1000
+ * use `validate` instead
1001
+ * @deprecated
1002
+ */
959
1003
  validateSelf() {
960
1004
  const { fromPort, toPort } = this;
961
1005
  if (fromPort) {
@@ -1185,7 +1229,7 @@ import {
1185
1229
  FlowNodeTransformData as FlowNodeTransformData6,
1186
1230
  FlowOperationBaseService
1187
1231
  } from "@flowgram.ai/document";
1188
- import { FlowNodeBaseType as FlowNodeBaseType2 } from "@flowgram.ai/document";
1232
+ import { FlowNodeBaseType as FlowNodeBaseType3 } from "@flowgram.ai/document";
1189
1233
  import {
1190
1234
  CommandService,
1191
1235
  MouseTouchEvent,
@@ -1395,7 +1439,6 @@ var WorkflowLinesManager = class {
1395
1439
  }
1396
1440
  fromNode.removeLine(line);
1397
1441
  toNode?.removeLine(line);
1398
- line.validate();
1399
1442
  });
1400
1443
  line.onDispose(() => {
1401
1444
  if (available) {
@@ -1625,7 +1668,7 @@ import { Emitter as Emitter4 } from "@flowgram.ai/utils";
1625
1668
  import { NodeEngineContext } from "@flowgram.ai/form-core";
1626
1669
  import {
1627
1670
  FlowDocument,
1628
- FlowNodeBaseType,
1671
+ FlowNodeBaseType as FlowNodeBaseType2,
1629
1672
  FlowNodeTransformData as FlowNodeTransformData5
1630
1673
  } from "@flowgram.ai/document";
1631
1674
  import {
@@ -1918,7 +1961,7 @@ var WorkflowDocument = class extends FlowDocument {
1918
1961
  toJSON: () => this.toNodeJSON(node)
1919
1962
  });
1920
1963
  node.onDispose(() => {
1921
- if (!node.parent || node.parent.flowNodeType === FlowNodeBaseType.ROOT) {
1964
+ if (!node.parent || node.parent.flowNodeType === FlowNodeBaseType2.ROOT) {
1922
1965
  return;
1923
1966
  }
1924
1967
  const parentTransform = node.parent.getData(FlowNodeTransformData5);
@@ -2086,10 +2129,10 @@ var WorkflowDocument = class extends FlowDocument {
2086
2129
  );
2087
2130
  }
2088
2131
  getAllNodes() {
2089
- return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== FlowNodeBaseType.ROOT);
2132
+ return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== FlowNodeBaseType2.ROOT);
2090
2133
  }
2091
2134
  getAllPorts() {
2092
- return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== FlowNodeBaseType.ROOT);
2135
+ return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== FlowNodeBaseType2.ROOT);
2093
2136
  }
2094
2137
  /**
2095
2138
  * 获取画布中的非游离节点
@@ -2244,10 +2287,11 @@ var WorkflowDocument = class extends FlowDocument {
2244
2287
  */
2245
2288
  toJSON() {
2246
2289
  const rootJSON = this.toNodeJSON(this.root);
2247
- return {
2290
+ const json = {
2248
2291
  nodes: rootJSON.blocks ?? [],
2249
2292
  edges: rootJSON.edges ?? []
2250
2293
  };
2294
+ return json;
2251
2295
  }
2252
2296
  dispose() {
2253
2297
  super.dispose();
@@ -2259,10 +2303,11 @@ var WorkflowDocument = class extends FlowDocument {
2259
2303
  renderJSON(json, options) {
2260
2304
  const { parent = this.root, isClone = false } = options ?? {};
2261
2305
  const containerID = this.getNodeSubCanvas(parent)?.canvasNode.id ?? parent.id;
2262
- const nodes = json.nodes.map(
2306
+ const processedJSON = buildGroupJSON(json);
2307
+ const nodes = processedJSON.nodes.map(
2263
2308
  (nodeJSON) => this.createWorkflowNode(nodeJSON, isClone, containerID)
2264
2309
  );
2265
- const edges = json.edges.map((edge) => this.createWorkflowLine(edge, containerID)).filter(Boolean);
2310
+ const edges = processedJSON.edges.map((edge) => this.createWorkflowLine(edge, containerID)).filter(Boolean);
2266
2311
  return { nodes, edges };
2267
2312
  }
2268
2313
  getNodeSubCanvas(node) {
@@ -2272,13 +2317,19 @@ var WorkflowDocument = class extends FlowDocument {
2272
2317
  return subCanvas;
2273
2318
  }
2274
2319
  getNodeChildren(node) {
2275
- if (!node) return [];
2320
+ if (!node || node.flowNodeType === FlowNodeBaseType2.GROUP) return [];
2276
2321
  const subCanvas = this.getNodeSubCanvas(node);
2277
- const childrenWithCanvas = subCanvas ? subCanvas.canvasNode.collapsedChildren : node.collapsedChildren;
2278
- const children = childrenWithCanvas.filter((child) => {
2322
+ const realChildren = subCanvas ? subCanvas.canvasNode.blocks : node.blocks;
2323
+ const childrenWithoutSubCanvas = realChildren.filter((child) => {
2279
2324
  const childMeta = child.getNodeMeta();
2280
2325
  return !childMeta.subCanvas?.(node)?.isCanvas;
2281
2326
  }).filter(Boolean);
2327
+ const children = childrenWithoutSubCanvas.map((child) => {
2328
+ if (child.flowNodeType === FlowNodeBaseType2.GROUP) {
2329
+ return [child, ...child.blocks];
2330
+ }
2331
+ return child;
2332
+ }).flat();
2282
2333
  return children;
2283
2334
  }
2284
2335
  toLineJSON(line) {
@@ -2410,7 +2461,7 @@ var WorkflowDragService = class {
2410
2461
  }
2411
2462
  this.isDragging = true;
2412
2463
  const sameParent = this.childrenOfContainer(selectedNodes);
2413
- if (sameParent && sameParent.flowNodeType !== FlowNodeBaseType2.ROOT) {
2464
+ if (sameParent && sameParent.flowNodeType !== FlowNodeBaseType3.ROOT) {
2414
2465
  selectedNodes = [sameParent];
2415
2466
  }
2416
2467
  let startPosition = this.getNodesPosition(selectedNodes);
@@ -2580,7 +2631,7 @@ var WorkflowDragService = class {
2580
2631
  if (!mousePos) {
2581
2632
  return { x: 0, y: 0 };
2582
2633
  }
2583
- if (!subNodeType || !containerNode || containerNode.flowNodeType === FlowNodeBaseType2.ROOT) {
2634
+ if (!subNodeType || !containerNode || containerNode.flowNodeType === FlowNodeBaseType3.ROOT) {
2584
2635
  return mousePos;
2585
2636
  }
2586
2637
  const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
@@ -3502,6 +3553,7 @@ export {
3502
3553
  WorkflowSelectService,
3503
3554
  WorkflowSimpleLineContribution,
3504
3555
  bindConfigEntity,
3556
+ buildGroupJSON,
3505
3557
  compose,
3506
3558
  composeAsync,
3507
3559
  delay,