@flowgram.ai/free-layout-core 0.1.0-alpha.11 → 0.1.0-alpha.12

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.d.mts CHANGED
@@ -2,8 +2,8 @@ import { PlaygroundConfigEntity, CommandService, PlaygroundDragEvent, EntityData
2
2
  export { bindConfigEntity, useConfigEntity, useEntities, useEntityDataFromContext, useEntityFromContext, useListenEvents, usePlayground, usePlaygroundContainer, usePlaygroundContext, usePlaygroundLatest, useRefresh, useService } from '@flowgram.ai/core';
3
3
  import { NodeFormProps } from '@flowgram.ai/node';
4
4
  import { FlowOperationBaseService, FlowNodeType, FlowOperationBaseServiceImpl, FlowNodeEntityOrId, FlowNodeEntity } from '@flowgram.ai/document';
5
- import { W as WorkflowHoverService, a as WorkflowDocument, b as WorkflowLinesManager, c as WorkflowSelectService, d as WorkflowDocumentOptions, L as LineEventProps, N as NodesDragEvent, e as WorkflowNodeJSON, f as WorkflowPortEntity, g as WorkflowLineEntity, O as OnDragLineEnd, h as WorkflowPorts, i as WorkflowPortType, j as WorkflowPort, k as LineRenderType, l as WorkflowLineRenderContribution, m as LinePosition } from './workflow-line-entity-SJhFU8K_.mjs';
6
- export { K as HoverPosition, C as LINE_HOVER_DISTANCE, v as LineColor, w as LineColors, u as LineType, z as NodesDragEndEvent, y as NodesDragStartEvent, A as NodesDraggingEvent, P as POINT_RADIUS, H as PORT_SIZE, o as WORKFLOW_LINE_ENTITY, M as WorkfloEntityHoverable, s as WorkflowContentChangeEvent, r as WorkflowContentChangeType, R as WorkflowDocumentOptionsDefault, Q as WorkflowDocumentProvider, J as WorkflowEntityHoverable, q as WorkflowJSON, E as WorkflowLineEntityOpts, F as WorkflowLineInfo, D as WorkflowLinePortInfo, x as WorkflowLineRenderContributionFactory, G as WorkflowLineUIState, t as WorkflowNodeMeta, I as WorkflowPortEntityOpts, p as domReactToBounds, n as getPortEntityId, B as onDragLineEndParams } from './workflow-line-entity-SJhFU8K_.mjs';
5
+ import { W as WorkflowHoverService, a as WorkflowDocument, b as WorkflowLinesManager, c as WorkflowSelectService, d as WorkflowDocumentOptions, L as LineEventProps, N as NodesDragEvent, e as WorkflowNodeJSON, f as WorkflowPortEntity, g as WorkflowLineEntity, O as OnDragLineEnd, h as WorkflowJSON, i as WorkflowPorts, j as WorkflowPortType, k as WorkflowPort, l as LineRenderType, m as WorkflowLineRenderContribution, n as LinePosition } from './workflow-line-entity-Iq1OHmuK.mjs';
6
+ export { K as HoverPosition, C as LINE_HOVER_DISTANCE, v as LineColor, w as LineColors, u as LineType, z as NodesDragEndEvent, y as NodesDragStartEvent, A as NodesDraggingEvent, P as POINT_RADIUS, H as PORT_SIZE, p as WORKFLOW_LINE_ENTITY, M as WorkfloEntityHoverable, s as WorkflowContentChangeEvent, r as WorkflowContentChangeType, R as WorkflowDocumentOptionsDefault, Q as WorkflowDocumentProvider, J as WorkflowEntityHoverable, E as WorkflowLineEntityOpts, F as WorkflowLineInfo, D as WorkflowLinePortInfo, x as WorkflowLineRenderContributionFactory, G as WorkflowLineUIState, t as WorkflowNodeMeta, I as WorkflowPortEntityOpts, q as domReactToBounds, o as getPortEntityId, B as onDragLineEndParams } from './workflow-line-entity-Iq1OHmuK.mjs';
7
7
  import { W as WorkflowNodeEntity } from './workflow-sub-canvas-IQzlYvPD.mjs';
8
8
  export { a as WorkflowSubCanvas } from './workflow-sub-canvas-IQzlYvPD.mjs';
9
9
  import * as _flowgram_ai_utils from '@flowgram.ai/utils';
@@ -323,6 +323,13 @@ declare function useWorkflowDocument(): WorkflowDocument;
323
323
  */
324
324
  declare function usePlaygroundReadonlyState(listenChange?: boolean): boolean;
325
325
 
326
+ /**
327
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
328
+ * SPDX-License-Identifier: MIT
329
+ */
330
+
331
+ declare const buildGroupJSON: (json: WorkflowJSON) => WorkflowJSON;
332
+
326
333
  /**
327
334
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
328
335
  * SPDX-License-Identifier: MIT
@@ -474,6 +481,7 @@ declare class WorkflowNodeLinesData extends EntityData<WorkflowNodeLines> {
474
481
  * 输出线条
475
482
  */
476
483
  get outputLines(): WorkflowLineEntity[];
484
+ get allLines(): WorkflowLineEntity[];
477
485
  /**
478
486
  * 输入节点
479
487
  */
@@ -562,4 +570,4 @@ declare class WorkflowSimpleLineContribution implements WorkflowLineRenderContri
562
570
  private projectPointOnLine;
563
571
  }
564
572
 
565
- export { EditorCursorState, InteractiveType, LineEventProps, LinePosition, LineRenderType, NodePostionUpdateEvent, type NodeRenderReturnType, NodesDragEvent, OnDragLineEnd, type PositionMap, type StraightData, WorkflowCommands, WorkflowDocument, WorkflowDocumentContainerModule, WorkflowDocumentOptions, WorkflowDragService, WorkflowHoverService, WorkflowLineEntity, WorkflowLineRenderContribution, WorkflowLineRenderData, type WorkflowLineRenderDataSchema, WorkflowLinesManager, WorkflowNodeEntity, WorkflowNodeJSON, type WorkflowNodeLines, WorkflowNodeLinesData, WorkflowNodePortsData, WorkflowOperationBaseService, WorkflowOperationBaseServiceImpl, WorkflowPort, WorkflowPortEntity, WorkflowPortType, WorkflowPorts, WorkflowResetLayoutService, WorkflowSelectService, WorkflowSimpleLineContribution, fitView, getAntiOverlapPosition, nanoid, useCurrentDomNode, useCurrentEntity, useNodeRender, usePlaygroundReadonlyState, useWorkflowDocument };
573
+ export { EditorCursorState, InteractiveType, LineEventProps, LinePosition, LineRenderType, NodePostionUpdateEvent, type NodeRenderReturnType, NodesDragEvent, OnDragLineEnd, type PositionMap, type StraightData, WorkflowCommands, WorkflowDocument, WorkflowDocumentContainerModule, WorkflowDocumentOptions, WorkflowDragService, WorkflowHoverService, WorkflowJSON, WorkflowLineEntity, WorkflowLineRenderContribution, WorkflowLineRenderData, type WorkflowLineRenderDataSchema, WorkflowLinesManager, WorkflowNodeEntity, WorkflowNodeJSON, type WorkflowNodeLines, WorkflowNodeLinesData, WorkflowNodePortsData, WorkflowOperationBaseService, WorkflowOperationBaseServiceImpl, WorkflowPort, WorkflowPortEntity, WorkflowPortType, WorkflowPorts, WorkflowResetLayoutService, WorkflowSelectService, WorkflowSimpleLineContribution, buildGroupJSON, fitView, getAntiOverlapPosition, nanoid, useCurrentDomNode, useCurrentEntity, useNodeRender, usePlaygroundReadonlyState, useWorkflowDocument };
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import { PlaygroundConfigEntity, CommandService, PlaygroundDragEvent, EntityData
2
2
  export { bindConfigEntity, useConfigEntity, useEntities, useEntityDataFromContext, useEntityFromContext, useListenEvents, usePlayground, usePlaygroundContainer, usePlaygroundContext, usePlaygroundLatest, useRefresh, useService } from '@flowgram.ai/core';
3
3
  import { NodeFormProps } from '@flowgram.ai/node';
4
4
  import { FlowOperationBaseService, FlowNodeType, FlowOperationBaseServiceImpl, FlowNodeEntityOrId, FlowNodeEntity } from '@flowgram.ai/document';
5
- import { W as WorkflowHoverService, a as WorkflowDocument, b as WorkflowLinesManager, c as WorkflowSelectService, d as WorkflowDocumentOptions, L as LineEventProps, N as NodesDragEvent, e as WorkflowNodeJSON, f as WorkflowPortEntity, g as WorkflowLineEntity, O as OnDragLineEnd, h as WorkflowPorts, i as WorkflowPortType, j as WorkflowPort, k as LineRenderType, l as WorkflowLineRenderContribution, m as LinePosition } from './workflow-line-entity-Z4omkx2m.js';
6
- export { K as HoverPosition, C as LINE_HOVER_DISTANCE, v as LineColor, w as LineColors, u as LineType, z as NodesDragEndEvent, y as NodesDragStartEvent, A as NodesDraggingEvent, P as POINT_RADIUS, H as PORT_SIZE, o as WORKFLOW_LINE_ENTITY, M as WorkfloEntityHoverable, s as WorkflowContentChangeEvent, r as WorkflowContentChangeType, R as WorkflowDocumentOptionsDefault, Q as WorkflowDocumentProvider, J as WorkflowEntityHoverable, q as WorkflowJSON, E as WorkflowLineEntityOpts, F as WorkflowLineInfo, D as WorkflowLinePortInfo, x as WorkflowLineRenderContributionFactory, G as WorkflowLineUIState, t as WorkflowNodeMeta, I as WorkflowPortEntityOpts, p as domReactToBounds, n as getPortEntityId, B as onDragLineEndParams } from './workflow-line-entity-Z4omkx2m.js';
5
+ import { W as WorkflowHoverService, a as WorkflowDocument, b as WorkflowLinesManager, c as WorkflowSelectService, d as WorkflowDocumentOptions, L as LineEventProps, N as NodesDragEvent, e as WorkflowNodeJSON, f as WorkflowPortEntity, g as WorkflowLineEntity, O as OnDragLineEnd, h as WorkflowJSON, i as WorkflowPorts, j as WorkflowPortType, k as WorkflowPort, l as LineRenderType, m as WorkflowLineRenderContribution, n as LinePosition } from './workflow-line-entity-LhmV98jq.js';
6
+ export { K as HoverPosition, C as LINE_HOVER_DISTANCE, v as LineColor, w as LineColors, u as LineType, z as NodesDragEndEvent, y as NodesDragStartEvent, A as NodesDraggingEvent, P as POINT_RADIUS, H as PORT_SIZE, p as WORKFLOW_LINE_ENTITY, M as WorkfloEntityHoverable, s as WorkflowContentChangeEvent, r as WorkflowContentChangeType, R as WorkflowDocumentOptionsDefault, Q as WorkflowDocumentProvider, J as WorkflowEntityHoverable, E as WorkflowLineEntityOpts, F as WorkflowLineInfo, D as WorkflowLinePortInfo, x as WorkflowLineRenderContributionFactory, G as WorkflowLineUIState, t as WorkflowNodeMeta, I as WorkflowPortEntityOpts, q as domReactToBounds, o as getPortEntityId, B as onDragLineEndParams } from './workflow-line-entity-LhmV98jq.js';
7
7
  import { W as WorkflowNodeEntity } from './workflow-sub-canvas-IQzlYvPD.js';
8
8
  export { a as WorkflowSubCanvas } from './workflow-sub-canvas-IQzlYvPD.js';
9
9
  import * as _flowgram_ai_utils from '@flowgram.ai/utils';
@@ -323,6 +323,13 @@ declare function useWorkflowDocument(): WorkflowDocument;
323
323
  */
324
324
  declare function usePlaygroundReadonlyState(listenChange?: boolean): boolean;
325
325
 
326
+ /**
327
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
328
+ * SPDX-License-Identifier: MIT
329
+ */
330
+
331
+ declare const buildGroupJSON: (json: WorkflowJSON) => WorkflowJSON;
332
+
326
333
  /**
327
334
  * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
328
335
  * SPDX-License-Identifier: MIT
@@ -474,6 +481,7 @@ declare class WorkflowNodeLinesData extends EntityData<WorkflowNodeLines> {
474
481
  * 输出线条
475
482
  */
476
483
  get outputLines(): WorkflowLineEntity[];
484
+ get allLines(): WorkflowLineEntity[];
477
485
  /**
478
486
  * 输入节点
479
487
  */
@@ -562,4 +570,4 @@ declare class WorkflowSimpleLineContribution implements WorkflowLineRenderContri
562
570
  private projectPointOnLine;
563
571
  }
564
572
 
565
- export { EditorCursorState, InteractiveType, LineEventProps, LinePosition, LineRenderType, NodePostionUpdateEvent, type NodeRenderReturnType, NodesDragEvent, OnDragLineEnd, type PositionMap, type StraightData, WorkflowCommands, WorkflowDocument, WorkflowDocumentContainerModule, WorkflowDocumentOptions, WorkflowDragService, WorkflowHoverService, WorkflowLineEntity, WorkflowLineRenderContribution, WorkflowLineRenderData, type WorkflowLineRenderDataSchema, WorkflowLinesManager, WorkflowNodeEntity, WorkflowNodeJSON, type WorkflowNodeLines, WorkflowNodeLinesData, WorkflowNodePortsData, WorkflowOperationBaseService, WorkflowOperationBaseServiceImpl, WorkflowPort, WorkflowPortEntity, WorkflowPortType, WorkflowPorts, WorkflowResetLayoutService, WorkflowSelectService, WorkflowSimpleLineContribution, fitView, getAntiOverlapPosition, nanoid, useCurrentDomNode, useCurrentEntity, useNodeRender, usePlaygroundReadonlyState, useWorkflowDocument };
573
+ export { EditorCursorState, InteractiveType, LineEventProps, LinePosition, LineRenderType, NodePostionUpdateEvent, type NodeRenderReturnType, NodesDragEvent, OnDragLineEnd, type PositionMap, type StraightData, WorkflowCommands, WorkflowDocument, WorkflowDocumentContainerModule, WorkflowDocumentOptions, WorkflowDragService, WorkflowHoverService, WorkflowJSON, WorkflowLineEntity, WorkflowLineRenderContribution, WorkflowLineRenderData, type WorkflowLineRenderDataSchema, WorkflowLinesManager, WorkflowNodeEntity, WorkflowNodeJSON, type WorkflowNodeLines, WorkflowNodeLinesData, WorkflowNodePortsData, WorkflowOperationBaseService, WorkflowOperationBaseServiceImpl, WorkflowPort, WorkflowPortEntity, WorkflowPortType, WorkflowPorts, WorkflowResetLayoutService, WorkflowSelectService, WorkflowSimpleLineContribution, buildGroupJSON, fitView, getAntiOverlapPosition, nanoid, useCurrentDomNode, useCurrentEntity, useNodeRender, usePlaygroundReadonlyState, useWorkflowDocument };
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ __export(src_exports, {
59
59
  WorkflowSelectService: () => WorkflowSelectService,
60
60
  WorkflowSimpleLineContribution: () => WorkflowSimpleLineContribution,
61
61
  bindConfigEntity: () => import_core3.bindConfigEntity,
62
+ buildGroupJSON: () => buildGroupJSON,
62
63
  compose: () => import_utils.compose,
63
64
  composeAsync: () => import_utils.composeAsync,
64
65
  delay: () => import_utils4.delay,
@@ -105,7 +106,7 @@ var import_core25 = require("@flowgram.ai/core");
105
106
  var import_react2 = require("react");
106
107
  var import_reactive = require("@flowgram.ai/reactive");
107
108
  var import_node = require("@flowgram.ai/node");
108
- var import_document12 = require("@flowgram.ai/document");
109
+ var import_document13 = require("@flowgram.ai/document");
109
110
  var import_core21 = require("@flowgram.ai/core");
110
111
 
111
112
  // src/service/workflow-select-service.ts
@@ -117,6 +118,34 @@ var import_utils9 = require("@flowgram.ai/utils");
117
118
  var import_core3 = require("@flowgram.ai/core");
118
119
  var import_utils4 = require("@flowgram.ai/utils");
119
120
 
121
+ // src/utils/build-group-json.ts
122
+ var import_document = require("@flowgram.ai/document");
123
+ var buildGroupJSON = (json) => {
124
+ const { nodes, edges } = json;
125
+ const groupJSONs = nodes.filter(
126
+ (nodeJSON) => nodeJSON.type === import_document.FlowNodeBaseType.GROUP
127
+ );
128
+ const nodeJSONMap = new Map(nodes.map((n) => [n.id, n]));
129
+ const groupNodeJSONs = groupJSONs.map((groupJSON) => {
130
+ const groupBlocks = (groupJSON.data.blockIDs ?? []).map((blockID) => nodeJSONMap.get(blockID)).filter(Boolean);
131
+ const groupEdges = edges?.filter(
132
+ (edge) => groupBlocks.some((block) => block.id === edge.sourceNodeID || block.id === edge.targetNodeID)
133
+ );
134
+ const groupNodeJSON = {
135
+ ...groupJSON,
136
+ blocks: groupBlocks,
137
+ edges: groupEdges
138
+ };
139
+ return groupNodeJSON;
140
+ });
141
+ const groupBlockSet = new Set(groupJSONs.map((groupJSON) => groupJSON.data.blockIDs).flat());
142
+ const processedNodes = nodes.filter((nodeJSON) => !groupBlockSet.has(nodeJSON.id)).concat(groupNodeJSONs);
143
+ return {
144
+ nodes: processedNodes,
145
+ edges
146
+ };
147
+ };
148
+
120
149
  // src/utils/nanoid.ts
121
150
  var import_nanoid = require("nanoid");
122
151
  function nanoid(n) {
@@ -170,8 +199,8 @@ function domReactToBounds(react) {
170
199
  }
171
200
 
172
201
  // src/entities/workflow-node-entity.ts
173
- var import_document = require("@flowgram.ai/document");
174
- var WorkflowNodeEntity = import_document.FlowNodeEntity;
202
+ var import_document2 = require("@flowgram.ai/document");
203
+ var WorkflowNodeEntity = import_document2.FlowNodeEntity;
175
204
 
176
205
  // src/entities/workflow-line-entity.ts
177
206
  var import_lodash_es2 = require("lodash-es");
@@ -180,12 +209,12 @@ var import_core8 = require("@flowgram.ai/core");
180
209
 
181
210
  // src/entity-datas/workflow-node-ports-data.ts
182
211
  var import_lodash_es = require("lodash-es");
183
- var import_document3 = require("@flowgram.ai/document");
212
+ var import_document4 = require("@flowgram.ai/document");
184
213
  var import_core5 = require("@flowgram.ai/core");
185
214
 
186
215
  // src/entities/workflow-port-entity.ts
187
216
  var import_utils5 = require("@flowgram.ai/utils");
188
- var import_document2 = require("@flowgram.ai/document");
217
+ var import_document3 = require("@flowgram.ai/document");
189
218
  var import_core4 = require("@flowgram.ai/core");
190
219
  var PORT_SIZE = 24;
191
220
  var WorkflowPortEntity = class extends import_core4.Entity {
@@ -214,15 +243,16 @@ var WorkflowPortEntity = class extends import_core4.Entity {
214
243
  }
215
244
  // 设置连线的错误态,外部应使用 validate 进行更新
216
245
  set hasError(hasError) {
217
- this._hasError = hasError;
218
- this._onErrorChangedEmitter.fire();
246
+ if (hasError !== this._hasError) {
247
+ this._hasError = hasError;
248
+ this._onErrorChangedEmitter.fire();
249
+ }
219
250
  }
220
251
  validate() {
221
252
  const anyLineHasError = this.allLines.some((line) => {
222
253
  if (line.disposed || line.isHidden) {
223
254
  return false;
224
255
  }
225
- line.validateSelf();
226
256
  return line.hasError;
227
257
  });
228
258
  const isPortHasError = this.node.document.isErrorPort(this);
@@ -233,7 +263,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
233
263
  }
234
264
  get point() {
235
265
  const { targetElement } = this;
236
- const { bounds } = this.node.getData(import_document2.FlowNodeTransformData);
266
+ const { bounds } = this.node.getData(import_document3.FlowNodeTransformData);
237
267
  if (targetElement) {
238
268
  const pos = domReactToBounds(targetElement.getBoundingClientRect()).center;
239
269
  return this.entityManager.getEntity(import_core4.PlaygroundConfigEntity).getPosFromMouseEvent({
@@ -262,7 +292,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
262
292
  */
263
293
  get relativePosition() {
264
294
  const { point } = this;
265
- const { bounds } = this.node.getData(import_document2.FlowNodeTransformData);
295
+ const { bounds } = this.node.getData(import_document3.FlowNodeTransformData);
266
296
  return {
267
297
  x: point.x - bounds.x,
268
298
  y: point.y - bounds.y
@@ -372,7 +402,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
372
402
  * 动态计算点位,通过 dom 的 data-port-key
373
403
  */
374
404
  updateDynamicPorts() {
375
- const domNode = this.entity.getData(import_document3.FlowNodeRenderData).node;
405
+ const domNode = this.entity.getData(import_document4.FlowNodeRenderData).node;
376
406
  const elements = domNode.querySelectorAll("[data-port-id]");
377
407
  const staticPorts = this._staticPorts;
378
408
  const dynamicPorts = [];
@@ -416,7 +446,6 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
416
446
  port.allLines.forEach((line) => {
417
447
  line.validate();
418
448
  });
419
- port.validate();
420
449
  });
421
450
  }
422
451
  /**
@@ -547,6 +576,9 @@ var _WorkflowNodeLinesData = class _WorkflowNodeLinesData extends import_core6.E
547
576
  get outputLines() {
548
577
  return this.data.outputLines;
549
578
  }
579
+ get allLines() {
580
+ return this.data.inputLines.concat(this.data.outputLines);
581
+ }
550
582
  /**
551
583
  * 输入节点
552
584
  */
@@ -762,6 +794,14 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
762
794
  if (opts.drawingTo) {
763
795
  this.isDrawing = true;
764
796
  }
797
+ this.onEntityChange(() => {
798
+ this.fromPort?.validate();
799
+ this.toPort?.validate();
800
+ });
801
+ this.onDispose(() => {
802
+ this.fromPort?.validate();
803
+ this.toPort?.validate();
804
+ });
765
805
  }
766
806
  /**
767
807
  * 转成线条 id
@@ -867,6 +907,7 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
867
907
  if (this.toPort === toPort) {
868
908
  return;
869
909
  }
910
+ const prePort = this.toPort;
870
911
  if (toPort && toPort.portType === "input" && this.linesManager.canAddLine(this.fromPort, toPort, true)) {
871
912
  const { node, portID } = toPort;
872
913
  this._to = node;
@@ -879,6 +920,9 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
879
920
  this.info.to = void 0;
880
921
  this.info.toPort = "";
881
922
  }
923
+ if (prePort) {
924
+ prePort.validate();
925
+ }
882
926
  this.fireChange();
883
927
  }
884
928
  /**
@@ -992,11 +1036,12 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity
992
1036
  }
993
1037
  // 校验连线是否为错误态
994
1038
  validate() {
995
- const { fromPort, toPort } = this;
996
1039
  this.validateSelf();
997
- fromPort?.validate();
998
- toPort?.validate();
999
1040
  }
1041
+ /**
1042
+ * use `validate` instead
1043
+ * @deprecated
1044
+ */
1000
1045
  validateSelf() {
1001
1046
  const { fromPort, toPort } = this;
1002
1047
  if (fromPort) {
@@ -1215,20 +1260,20 @@ WorkflowHoverService = __decorateClass([
1215
1260
  var import_nanoid3 = require("nanoid");
1216
1261
  var import_inversify6 = require("inversify");
1217
1262
  var import_utils16 = require("@flowgram.ai/utils");
1218
- var import_document8 = require("@flowgram.ai/document");
1219
1263
  var import_document9 = require("@flowgram.ai/document");
1264
+ var import_document10 = require("@flowgram.ai/document");
1220
1265
  var import_core15 = require("@flowgram.ai/core");
1221
1266
 
1222
1267
  // src/workflow-lines-manager.ts
1223
1268
  var import_lodash_es3 = require("lodash-es");
1224
1269
  var import_inversify3 = require("inversify");
1225
1270
  var import_utils12 = require("@flowgram.ai/utils");
1226
- var import_document5 = require("@flowgram.ai/document");
1271
+ var import_document6 = require("@flowgram.ai/document");
1227
1272
  var import_core12 = require("@flowgram.ai/core");
1228
1273
 
1229
1274
  // src/workflow-document-option.ts
1230
1275
  var import_form_core2 = require("@flowgram.ai/form-core");
1231
- var import_document4 = require("@flowgram.ai/document");
1276
+ var import_document5 = require("@flowgram.ai/document");
1232
1277
  var import_core11 = require("@flowgram.ai/core");
1233
1278
 
1234
1279
  // src/utils/flow-node-form-data.ts
@@ -1320,7 +1365,7 @@ var WorkflowDocumentOptionsDefault = {
1320
1365
  const nodeMeta = node.getNodeMeta();
1321
1366
  const subCanvas = nodeMeta.subCanvas?.(node);
1322
1367
  if (subCanvas?.isCanvas === false) {
1323
- const canvasNodeTransform = subCanvas.canvasNode.getData(import_document4.FlowNodeTransformData);
1368
+ const canvasNodeTransform = subCanvas.canvasNode.getData(import_document5.FlowNodeTransformData);
1324
1369
  const { x, y } = canvasNodeTransform.transform.position;
1325
1370
  metaData.canvasPosition = { x, y };
1326
1371
  }
@@ -1457,7 +1502,6 @@ var WorkflowLinesManager = class {
1457
1502
  }
1458
1503
  fromNode.removeLine(line);
1459
1504
  toNode?.removeLine(line);
1460
- line.validate();
1461
1505
  });
1462
1506
  line.onDispose(() => {
1463
1507
  if (available) {
@@ -1652,7 +1696,7 @@ var WorkflowLinesManager = class {
1652
1696
  const allNodes = this.getSortedNodes();
1653
1697
  const zoom = this.entityManager.getEntity(import_core12.PlaygroundConfigEntity)?.config?.zoom || 1;
1654
1698
  const containNodes = allNodes.map((node) => {
1655
- const { bounds } = node.getData(import_document5.FlowNodeTransformData);
1699
+ const { bounds } = node.getData(import_document6.FlowNodeTransformData);
1656
1700
  if (bounds.clone().pad(4 / zoom).contains(pos.x, pos.y)) {
1657
1701
  return node;
1658
1702
  }
@@ -1660,7 +1704,7 @@ var WorkflowLinesManager = class {
1660
1704
  return containNodes;
1661
1705
  }
1662
1706
  getNodeIndex(node) {
1663
- const nodeRenderData = node.getData(import_document5.FlowNodeRenderData);
1707
+ const nodeRenderData = node.getData(import_document6.FlowNodeRenderData);
1664
1708
  return nodeRenderData.stackIndex;
1665
1709
  }
1666
1710
  };
@@ -1685,13 +1729,13 @@ var import_nanoid2 = require("nanoid");
1685
1729
  var import_inversify5 = require("inversify");
1686
1730
  var import_utils14 = require("@flowgram.ai/utils");
1687
1731
  var import_form_core3 = require("@flowgram.ai/form-core");
1688
- var import_document7 = require("@flowgram.ai/document");
1732
+ var import_document8 = require("@flowgram.ai/document");
1689
1733
  var import_core14 = require("@flowgram.ai/core");
1690
1734
 
1691
1735
  // src/layout/free-layout.ts
1692
1736
  var import_inversify4 = require("inversify");
1693
1737
  var import_utils13 = require("@flowgram.ai/utils");
1694
- var import_document6 = require("@flowgram.ai/document");
1738
+ var import_document7 = require("@flowgram.ai/document");
1695
1739
  var import_core13 = require("@flowgram.ai/core");
1696
1740
  var FREE_LAYOUT_KEY = "free-layout";
1697
1741
  var FreeLayout = class {
@@ -1705,12 +1749,12 @@ var FreeLayout = class {
1705
1749
  * 更新布局
1706
1750
  */
1707
1751
  update() {
1708
- if (this.document.root.getData(import_document6.FlowNodeTransformData)?.localDirty) {
1752
+ if (this.document.root.getData(import_document7.FlowNodeTransformData)?.localDirty) {
1709
1753
  this.document.root.clearMemoGlobal();
1710
1754
  }
1711
1755
  }
1712
1756
  syncTransform(node) {
1713
- const transform = node.getData(import_document6.FlowNodeTransformData);
1757
+ const transform = node.getData(import_document7.FlowNodeTransformData);
1714
1758
  if (!transform.localDirty) {
1715
1759
  return;
1716
1760
  }
@@ -1724,7 +1768,7 @@ var FreeLayout = class {
1724
1768
  }
1725
1769
  node.parent.clearMemoGlobal();
1726
1770
  node.parent.clearMemoLocal();
1727
- const parentTransform = node.parent.getData(import_document6.FlowNodeTransformData);
1771
+ const parentTransform = node.parent.getData(import_document7.FlowNodeTransformData);
1728
1772
  parentTransform.transform.fireChange();
1729
1773
  }
1730
1774
  /**
@@ -1748,7 +1792,7 @@ var FreeLayout = class {
1748
1792
  */
1749
1793
  getPadding(node) {
1750
1794
  const { padding } = node.getNodeMeta();
1751
- const transform = node.getData(import_document6.FlowNodeTransformData);
1795
+ const transform = node.getData(import_document7.FlowNodeTransformData);
1752
1796
  if (padding) {
1753
1797
  return typeof padding === "function" ? padding(transform) : padding;
1754
1798
  }
@@ -1816,7 +1860,7 @@ __decorateClass([
1816
1860
  (0, import_inversify4.inject)(import_core13.PlaygroundConfigEntity)
1817
1861
  ], FreeLayout.prototype, "playgroundConfig", 2);
1818
1862
  __decorateClass([
1819
- (0, import_inversify4.inject)(import_document6.FlowDocumentProvider)
1863
+ (0, import_inversify4.inject)(import_document7.FlowDocumentProvider)
1820
1864
  ], FreeLayout.prototype, "documentProvider", 2);
1821
1865
  FreeLayout = __decorateClass([
1822
1866
  (0, import_inversify4.injectable)()
@@ -1825,7 +1869,7 @@ FreeLayout = __decorateClass([
1825
1869
  // src/workflow-document.ts
1826
1870
  var nanoid2 = (0, import_nanoid2.customAlphabet)("1234567890", 5);
1827
1871
  var WorkflowDocumentProvider = Symbol("WorkflowDocumentProvider");
1828
- var WorkflowDocument = class extends import_document7.FlowDocument {
1872
+ var WorkflowDocument = class extends import_document8.FlowDocument {
1829
1873
  constructor() {
1830
1874
  super(...arguments);
1831
1875
  this._onContentChangeEmitter = new import_utils14.Emitter();
@@ -1922,7 +1966,7 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
1922
1966
  const { formMeta } = registry;
1923
1967
  const meta = node.getNodeMeta();
1924
1968
  const formData = getFlowNodeFormData(node);
1925
- const transform = node.getData(import_document7.FlowNodeTransformData);
1969
+ const transform = node.getData(import_document8.FlowNodeTransformData);
1926
1970
  const freeLayout = this.layout;
1927
1971
  if (!isExistedNode) {
1928
1972
  transform.onDataChange(() => {
@@ -1964,10 +2008,10 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
1964
2008
  toJSON: () => this.toNodeJSON(node)
1965
2009
  });
1966
2010
  node.onDispose(() => {
1967
- if (!node.parent || node.parent.flowNodeType === import_document7.FlowNodeBaseType.ROOT) {
2011
+ if (!node.parent || node.parent.flowNodeType === import_document8.FlowNodeBaseType.ROOT) {
1968
2012
  return;
1969
2013
  }
1970
- const parentTransform = node.parent.getData(import_document7.FlowNodeTransformData);
2014
+ const parentTransform = node.parent.getData(import_document8.FlowNodeTransformData);
1971
2015
  parentTransform.fireChange();
1972
2016
  });
1973
2017
  let lastDeleteNodeData;
@@ -2132,10 +2176,10 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
2132
2176
  );
2133
2177
  }
2134
2178
  getAllNodes() {
2135
- return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== import_document7.FlowNodeBaseType.ROOT);
2179
+ return this.entityManager.getEntities(WorkflowNodeEntity).filter((n) => n.id !== import_document8.FlowNodeBaseType.ROOT);
2136
2180
  }
2137
2181
  getAllPorts() {
2138
- return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== import_document7.FlowNodeBaseType.ROOT);
2182
+ return this.entityManager.getEntities(WorkflowPortEntity).filter((p) => p.node.id !== import_document8.FlowNodeBaseType.ROOT);
2139
2183
  }
2140
2184
  /**
2141
2185
  * 获取画布中的非游离节点
@@ -2290,10 +2334,11 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
2290
2334
  */
2291
2335
  toJSON() {
2292
2336
  const rootJSON = this.toNodeJSON(this.root);
2293
- return {
2337
+ const json = {
2294
2338
  nodes: rootJSON.blocks ?? [],
2295
2339
  edges: rootJSON.edges ?? []
2296
2340
  };
2341
+ return json;
2297
2342
  }
2298
2343
  dispose() {
2299
2344
  super.dispose();
@@ -2305,10 +2350,11 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
2305
2350
  renderJSON(json, options) {
2306
2351
  const { parent = this.root, isClone = false } = options ?? {};
2307
2352
  const containerID = this.getNodeSubCanvas(parent)?.canvasNode.id ?? parent.id;
2308
- const nodes = json.nodes.map(
2353
+ const processedJSON = buildGroupJSON(json);
2354
+ const nodes = processedJSON.nodes.map(
2309
2355
  (nodeJSON) => this.createWorkflowNode(nodeJSON, isClone, containerID)
2310
2356
  );
2311
- const edges = json.edges.map((edge) => this.createWorkflowLine(edge, containerID)).filter(Boolean);
2357
+ const edges = processedJSON.edges.map((edge) => this.createWorkflowLine(edge, containerID)).filter(Boolean);
2312
2358
  return { nodes, edges };
2313
2359
  }
2314
2360
  getNodeSubCanvas(node) {
@@ -2318,13 +2364,19 @@ var WorkflowDocument = class extends import_document7.FlowDocument {
2318
2364
  return subCanvas;
2319
2365
  }
2320
2366
  getNodeChildren(node) {
2321
- if (!node) return [];
2367
+ if (!node || node.flowNodeType === import_document8.FlowNodeBaseType.GROUP) return [];
2322
2368
  const subCanvas = this.getNodeSubCanvas(node);
2323
- const childrenWithCanvas = subCanvas ? subCanvas.canvasNode.collapsedChildren : node.collapsedChildren;
2324
- const children = childrenWithCanvas.filter((child) => {
2369
+ const realChildren = subCanvas ? subCanvas.canvasNode.blocks : node.blocks;
2370
+ const childrenWithoutSubCanvas = realChildren.filter((child) => {
2325
2371
  const childMeta = child.getNodeMeta();
2326
2372
  return !childMeta.subCanvas?.(node)?.isCanvas;
2327
2373
  }).filter(Boolean);
2374
+ const children = childrenWithoutSubCanvas.map((child) => {
2375
+ if (child.flowNodeType === import_document8.FlowNodeBaseType.GROUP) {
2376
+ return [child, ...child.blocks];
2377
+ }
2378
+ return child;
2379
+ }).flat();
2328
2380
  return children;
2329
2381
  }
2330
2382
  toLineJSON(line) {
@@ -2456,7 +2508,7 @@ var WorkflowDragService = class {
2456
2508
  }
2457
2509
  this.isDragging = true;
2458
2510
  const sameParent = this.childrenOfContainer(selectedNodes);
2459
- if (sameParent && sameParent.flowNodeType !== import_document9.FlowNodeBaseType.ROOT) {
2511
+ if (sameParent && sameParent.flowNodeType !== import_document10.FlowNodeBaseType.ROOT) {
2460
2512
  selectedNodes = [sameParent];
2461
2513
  }
2462
2514
  let startPosition = this.getNodesPosition(selectedNodes);
@@ -2626,7 +2678,7 @@ var WorkflowDragService = class {
2626
2678
  if (!mousePos) {
2627
2679
  return { x: 0, y: 0 };
2628
2680
  }
2629
- if (!subNodeType || !containerNode || containerNode.flowNodeType === import_document9.FlowNodeBaseType.ROOT) {
2681
+ if (!subNodeType || !containerNode || containerNode.flowNodeType === import_document10.FlowNodeBaseType.ROOT) {
2630
2682
  return mousePos;
2631
2683
  }
2632
2684
  const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
@@ -2712,7 +2764,7 @@ var WorkflowDragService = class {
2712
2764
  return offset;
2713
2765
  }
2714
2766
  updateDroppableTransforms() {
2715
- this._droppableTransforms = this.document.getRenderDatas(import_document8.FlowNodeTransformData, false).filter((transform) => {
2767
+ this._droppableTransforms = this.document.getRenderDatas(import_document9.FlowNodeTransformData, false).filter((transform) => {
2716
2768
  const { entity } = transform;
2717
2769
  if (entity.originParent) {
2718
2770
  return this.nodeSelectable(entity) && this.nodeSelectable(entity.originParent);
@@ -2729,7 +2781,7 @@ var WorkflowDragService = class {
2729
2781
  */
2730
2782
  getNodesPosition(nodes) {
2731
2783
  const selectedBounds = import_utils16.Rectangle.enlarge(
2732
- nodes.map((n) => n.getData(import_document8.FlowNodeTransformData).bounds)
2784
+ nodes.map((n) => n.getData(import_document9.FlowNodeTransformData).bounds)
2733
2785
  );
2734
2786
  const position = {
2735
2787
  x: selectedBounds.x,
@@ -3009,7 +3061,7 @@ __decorateClass([
3009
3061
  (0, import_inversify6.inject)(WorkflowSelectService)
3010
3062
  ], WorkflowDragService.prototype, "selectService", 2);
3011
3063
  __decorateClass([
3012
- (0, import_inversify6.inject)(import_document8.FlowOperationBaseService)
3064
+ (0, import_inversify6.inject)(import_document9.FlowOperationBaseService)
3013
3065
  ], WorkflowDragService.prototype, "operationService", 2);
3014
3066
  __decorateClass([
3015
3067
  (0, import_inversify6.inject)(WorkflowDocumentOptions)
@@ -3028,13 +3080,13 @@ var import_core18 = require("@flowgram.ai/core");
3028
3080
  var import_utils17 = require("@flowgram.ai/utils");
3029
3081
 
3030
3082
  // src/utils/layout-to-positions.ts
3031
- var import_document10 = require("@flowgram.ai/document");
3083
+ var import_document11 = require("@flowgram.ai/document");
3032
3084
  var import_core16 = require("@flowgram.ai/core");
3033
3085
  var layoutToPositions = async (nodes, nodePositionMap) => {
3034
3086
  const newNodePositionMap = {};
3035
3087
  nodes.forEach((node) => {
3036
3088
  const transform = node.getData(import_core16.TransformData);
3037
- const nodeTransform = node.getData(import_document10.FlowNodeTransformData);
3089
+ const nodeTransform = node.getData(import_document11.FlowNodeTransformData);
3038
3090
  newNodePositionMap[node.id] = {
3039
3091
  x: transform.position.x,
3040
3092
  y: transform.position.y + nodeTransform.bounds.height / 2
@@ -3130,9 +3182,9 @@ WorkflowResetLayoutService = __decorateClass([
3130
3182
  // src/service/workflow-operation-base-service.ts
3131
3183
  var import_inversify8 = require("inversify");
3132
3184
  var import_utils19 = require("@flowgram.ai/utils");
3133
- var import_document11 = require("@flowgram.ai/document");
3185
+ var import_document12 = require("@flowgram.ai/document");
3134
3186
  var import_core19 = require("@flowgram.ai/core");
3135
- var WorkflowOperationBaseServiceImpl = class extends import_document11.FlowOperationBaseServiceImpl {
3187
+ var WorkflowOperationBaseServiceImpl = class extends import_document12.FlowOperationBaseServiceImpl {
3136
3188
  constructor() {
3137
3189
  super(...arguments);
3138
3190
  this.onNodePostionUpdateEmitter = new import_utils19.Emitter();
@@ -3184,7 +3236,7 @@ function checkTargetDraggable(el) {
3184
3236
  }
3185
3237
  function useNodeRender(nodeFromProps) {
3186
3238
  const node = nodeFromProps || (0, import_react2.useContext)(import_core21.PlaygroundEntityContext);
3187
- const renderData = node.getData(import_document12.FlowNodeRenderData);
3239
+ const renderData = node.getData(import_document13.FlowNodeRenderData);
3188
3240
  const portsData = node.getData(WorkflowNodePortsData);
3189
3241
  const readonly = usePlaygroundReadonlyState();
3190
3242
  const dragService = (0, import_core21.useService)(WorkflowDragService);
@@ -3351,11 +3403,11 @@ function useNodeRender(nodeFromProps) {
3351
3403
  }
3352
3404
 
3353
3405
  // src/hooks/use-current-dom-node.ts
3354
- var import_document13 = require("@flowgram.ai/document");
3406
+ var import_document14 = require("@flowgram.ai/document");
3355
3407
  var import_core22 = require("@flowgram.ai/core");
3356
3408
  function useCurrentDomNode() {
3357
3409
  const entity = (0, import_core22.useEntityFromContext)();
3358
- const renderData = entity.getData(import_document13.FlowNodeRenderData);
3410
+ const renderData = entity.getData(import_document14.FlowNodeRenderData);
3359
3411
  return renderData.node;
3360
3412
  }
3361
3413
 
@@ -3386,16 +3438,16 @@ var InteractiveType = /* @__PURE__ */ ((InteractiveType2) => {
3386
3438
  // src/workflow-document-container-module.ts
3387
3439
  var import_inversify10 = require("inversify");
3388
3440
  var import_utils20 = require("@flowgram.ai/utils");
3389
- var import_document15 = require("@flowgram.ai/document");
3441
+ var import_document16 = require("@flowgram.ai/document");
3390
3442
 
3391
3443
  // src/workflow-document-contribution.ts
3392
3444
  var import_inversify9 = require("inversify");
3393
- var import_document14 = require("@flowgram.ai/document");
3445
+ var import_document15 = require("@flowgram.ai/document");
3394
3446
  var WorkflowDocumentContribution = class {
3395
3447
  registerDocument(document2) {
3396
3448
  document2.registerNodeDatas(
3397
- import_document14.FlowNodeTransformData,
3398
- import_document14.FlowNodeRenderData,
3449
+ import_document15.FlowNodeTransformData,
3450
+ import_document15.FlowNodeRenderData,
3399
3451
  WorkflowNodePortsData,
3400
3452
  WorkflowNodeLinesData
3401
3453
  );
@@ -3430,11 +3482,11 @@ var WorkflowDocumentContainerModule = new import_inversify10.ContainerModule(
3430
3482
  bind(WorkflowResetLayoutService).toSelf().inSingletonScope();
3431
3483
  bind(WorkflowOperationBaseService).to(WorkflowOperationBaseServiceImpl).inSingletonScope();
3432
3484
  bind(URLParams).toDynamicValue(() => getUrlParams()).inSingletonScope();
3433
- (0, import_utils20.bindContributions)(bind, WorkflowDocumentContribution, [import_document15.FlowDocumentContribution]);
3485
+ (0, import_utils20.bindContributions)(bind, WorkflowDocumentContribution, [import_document16.FlowDocumentContribution]);
3434
3486
  bind(WorkflowDocumentOptions).toConstantValue({
3435
3487
  ...WorkflowDocumentOptionsDefault
3436
3488
  });
3437
- rebind(import_document15.FlowDocument).toService(WorkflowDocument);
3489
+ rebind(import_document16.FlowDocument).toService(WorkflowDocument);
3438
3490
  bind(WorkflowDocumentProvider).toDynamicValue((ctx) => () => ctx.container.get(WorkflowDocument)).inSingletonScope();
3439
3491
  }
3440
3492
  );
@@ -3546,6 +3598,7 @@ WorkflowSimpleLineContribution.type = "WorkflowSimpleLineContribution";
3546
3598
  WorkflowSelectService,
3547
3599
  WorkflowSimpleLineContribution,
3548
3600
  bindConfigEntity,
3601
+ buildGroupJSON,
3549
3602
  compose,
3550
3603
  composeAsync,
3551
3604
  delay,