@flowgram.ai/free-layout-core 0.1.6 → 0.1.8

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
@@ -28,9 +28,7 @@ var __decorateClass = (decorators, target, key, kind) => {
28
28
  // src/index.ts
29
29
  var src_exports = {};
30
30
  __export(src_exports, {
31
- BezierControlType: () => BezierControlType,
32
31
  EditorCursorState: () => EditorCursorState,
33
- FoldLine: () => FoldLine,
34
32
  InteractiveType: () => InteractiveType,
35
33
  LINE_HOVER_DISTANCE: () => LINE_HOVER_DISTANCE,
36
34
  LineColors: () => LineColors,
@@ -49,6 +47,7 @@ __export(src_exports, {
49
47
  WorkflowDragService: () => WorkflowDragService,
50
48
  WorkflowHoverService: () => WorkflowHoverService,
51
49
  WorkflowLineEntity: () => WorkflowLineEntity,
50
+ WorkflowLineRenderData: () => WorkflowLineRenderData,
52
51
  WorkflowLinesManager: () => WorkflowLinesManager,
53
52
  WorkflowNodeEntity: () => WorkflowNodeEntity,
54
53
  WorkflowNodeLinesData: () => WorkflowNodeLinesData,
@@ -56,32 +55,31 @@ __export(src_exports, {
56
55
  WorkflowPortEntity: () => WorkflowPortEntity,
57
56
  WorkflowResetLayoutService: () => WorkflowResetLayoutService,
58
57
  WorkflowSelectService: () => WorkflowSelectService,
58
+ WorkflowSimpleLineContribution: () => WorkflowSimpleLineContribution,
59
59
  bindConfigEntity: () => import_core3.bindConfigEntity,
60
- compose: () => import_utils3.compose,
61
- composeAsync: () => import_utils3.composeAsync,
62
- delay: () => import_utils6.delay,
60
+ compose: () => import_utils.compose,
61
+ composeAsync: () => import_utils.composeAsync,
62
+ delay: () => import_utils4.delay,
63
63
  domReactToBounds: () => domReactToBounds,
64
64
  fitView: () => fitView,
65
65
  getAntiOverlapPosition: () => getAntiOverlapPosition,
66
- getBezierHorizontalControlPoints: () => getBezierHorizontalControlPoints,
67
- getBezierVerticalControlPoints: () => getBezierVerticalControlPoints,
68
66
  getPortEntityId: () => getPortEntityId,
69
67
  nanoid: () => nanoid,
70
- useConfigEntity: () => import_core23.useConfigEntity,
68
+ useConfigEntity: () => import_core24.useConfigEntity,
71
69
  useCurrentDomNode: () => useCurrentDomNode,
72
70
  useCurrentEntity: () => useCurrentEntity,
73
- useEntities: () => import_core23.useEntities,
74
- useEntityDataFromContext: () => import_core23.useEntityDataFromContext,
75
- useEntityFromContext: () => import_core23.useEntityFromContext,
76
- useListenEvents: () => import_core23.useListenEvents,
71
+ useEntities: () => import_core24.useEntities,
72
+ useEntityDataFromContext: () => import_core24.useEntityDataFromContext,
73
+ useEntityFromContext: () => import_core24.useEntityFromContext,
74
+ useListenEvents: () => import_core24.useListenEvents,
77
75
  useNodeRender: () => useNodeRender,
78
- usePlayground: () => import_core23.usePlayground,
79
- usePlaygroundContainer: () => import_core23.usePlaygroundContainer,
80
- usePlaygroundContext: () => import_core23.usePlaygroundContext,
81
- usePlaygroundLatest: () => import_core23.usePlaygroundLatest,
76
+ usePlayground: () => import_core24.usePlayground,
77
+ usePlaygroundContainer: () => import_core24.usePlaygroundContainer,
78
+ usePlaygroundContext: () => import_core24.usePlaygroundContext,
79
+ usePlaygroundLatest: () => import_core24.usePlaygroundLatest,
82
80
  usePlaygroundReadonlyState: () => usePlaygroundReadonlyState,
83
- useRefresh: () => import_core23.useRefresh,
84
- useService: () => import_core23.useService,
81
+ useRefresh: () => import_core24.useRefresh,
82
+ useService: () => import_core24.useService,
85
83
  useWorkflowDocument: () => useWorkflowDocument
86
84
  });
87
85
  module.exports = __toCommonJS(src_exports);
@@ -99,332 +97,23 @@ var WorkflowCommands = /* @__PURE__ */ ((WorkflowCommands2) => {
99
97
  })(WorkflowCommands || {});
100
98
 
101
99
  // src/hooks/index.ts
102
- var import_core23 = require("@flowgram.ai/core");
100
+ var import_core24 = require("@flowgram.ai/core");
103
101
 
104
102
  // src/hooks/use-node-render.tsx
105
103
  var import_react2 = require("react");
106
104
  var import_reactive = require("@flowgram.ai/reactive");
107
105
  var import_node = require("@flowgram.ai/node");
108
106
  var import_document10 = require("@flowgram.ai/document");
109
- var import_core19 = require("@flowgram.ai/core");
107
+ var import_core20 = require("@flowgram.ai/core");
110
108
 
111
109
  // src/service/workflow-select-service.ts
112
110
  var import_inversify = require("inversify");
113
- var import_core7 = require("@flowgram.ai/core");
111
+ var import_core9 = require("@flowgram.ai/core");
114
112
  var import_utils9 = require("@flowgram.ai/utils");
115
113
 
116
114
  // src/utils/index.ts
117
115
  var import_core3 = require("@flowgram.ai/core");
118
- var import_utils6 = require("@flowgram.ai/utils");
119
-
120
- // src/utils/fold-line.ts
121
- var import_utils = require("@flowgram.ai/utils");
122
- function pointLineDistance(p1, p2, p3) {
123
- let len;
124
- if (p1.x - p2.x === 0) {
125
- len = Math.abs(p3.x - p1.x);
126
- } else {
127
- const A = (p1.y - p2.y) / (p1.x - p2.x);
128
- const B = p1.y - A * p1.x;
129
- len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));
130
- }
131
- return len;
132
- }
133
- var FoldLine;
134
- ((FoldLine2) => {
135
- const EDGE_RADIUS = 5;
136
- const OFFSET = 20;
137
- function getEdgeCenter({ source, target }) {
138
- const xOffset = Math.abs(target.x - source.x) / 2;
139
- const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;
140
- const yOffset = Math.abs(target.y - source.y) / 2;
141
- const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;
142
- return [centerX, centerY];
143
- }
144
- const getDirection = ({ source, target }) => source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };
145
- function getPoints({ source, target }) {
146
- const sourceDir = { x: 1, y: 0 };
147
- const targetDir = { x: -1, y: 0 };
148
- const sourceGapped = {
149
- x: source.x + sourceDir.x * OFFSET,
150
- y: source.y + sourceDir.y * OFFSET
151
- };
152
- const targetGapped = {
153
- x: target.x + targetDir.x * OFFSET,
154
- y: target.y + targetDir.y * OFFSET
155
- };
156
- const dir = getDirection({
157
- source: sourceGapped,
158
- target: targetGapped
159
- });
160
- const dirAccessor = dir.x !== 0 ? "x" : "y";
161
- const currDir = dir[dirAccessor];
162
- let points = [];
163
- let centerX, centerY;
164
- const [defaultCenterX, defaultCenterY] = getEdgeCenter({
165
- source,
166
- target
167
- });
168
- if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {
169
- centerX = defaultCenterX;
170
- centerY = defaultCenterY;
171
- const verticalSplit = [
172
- { x: centerX, y: sourceGapped.y },
173
- { x: centerX, y: targetGapped.y }
174
- ];
175
- const horizontalSplit = [
176
- { x: sourceGapped.x, y: centerY },
177
- { x: targetGapped.x, y: centerY }
178
- ];
179
- if (sourceDir[dirAccessor] === currDir) {
180
- points = dirAccessor === "x" ? verticalSplit : horizontalSplit;
181
- } else {
182
- points = dirAccessor === "x" ? horizontalSplit : verticalSplit;
183
- }
184
- } else {
185
- const sourceTarget = [{ x: sourceGapped.x, y: targetGapped.y }];
186
- const targetSource = [{ x: targetGapped.x, y: sourceGapped.y }];
187
- if (dirAccessor === "x") {
188
- points = sourceDir.x === currDir ? targetSource : sourceTarget;
189
- } else {
190
- points = sourceDir.y === currDir ? sourceTarget : targetSource;
191
- }
192
- const dirAccessorOpposite = dirAccessor === "x" ? "y" : "x";
193
- const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];
194
- const sourceGtTargetOppo = sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];
195
- const sourceLtTargetOppo = sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];
196
- const flipSourceTarget = sourceDir[dirAccessor] === 1 && (!isSameDir && sourceGtTargetOppo || isSameDir && sourceLtTargetOppo) || sourceDir[dirAccessor] !== 1 && (!isSameDir && sourceLtTargetOppo || isSameDir && sourceGtTargetOppo);
197
- if (flipSourceTarget) {
198
- points = dirAccessor === "x" ? sourceTarget : targetSource;
199
- }
200
- const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };
201
- const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };
202
- const maxXDistance = Math.max(
203
- Math.abs(sourceGapPoint.x - points[0].x),
204
- Math.abs(targetGapPoint.x - points[0].x)
205
- );
206
- const maxYDistance = Math.max(
207
- Math.abs(sourceGapPoint.y - points[0].y),
208
- Math.abs(targetGapPoint.y - points[0].y)
209
- );
210
- if (maxXDistance >= maxYDistance) {
211
- centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;
212
- centerY = points[0].y;
213
- } else {
214
- centerX = points[0].x;
215
- centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;
216
- }
217
- }
218
- const pathPoints = [
219
- source,
220
- { x: sourceGapped.x, y: sourceGapped.y },
221
- ...points,
222
- { x: targetGapped.x, y: targetGapped.y },
223
- target
224
- ];
225
- return pathPoints;
226
- }
227
- FoldLine2.getPoints = getPoints;
228
- function getBend(a, b, c) {
229
- const bendSize = Math.min(
230
- import_utils.Point.getDistance(a, b) / 2,
231
- import_utils.Point.getDistance(b, c) / 2,
232
- EDGE_RADIUS
233
- );
234
- const { x, y } = b;
235
- if (a.x === x && x === c.x || a.y === y && y === c.y) {
236
- return `L${x} ${y}`;
237
- }
238
- if (a.y === y) {
239
- const xDir2 = a.x < c.x ? -1 : 1;
240
- const yDir2 = a.y < c.y ? 1 : -1;
241
- return `L ${x + bendSize * xDir2},${y}Q ${x},${y} ${x},${y + bendSize * yDir2}`;
242
- }
243
- const xDir = a.x < c.x ? 1 : -1;
244
- const yDir = a.y < c.y ? -1 : 1;
245
- return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
246
- }
247
- function getSmoothStepPath(points) {
248
- const path = points.reduce((res, p, i) => {
249
- let segment = "";
250
- if (i > 0 && i < points.length - 1) {
251
- segment = getBend(points[i - 1], p, points[i + 1]);
252
- } else {
253
- segment = `${i === 0 ? "M" : "L"}${p.x} ${p.y}`;
254
- }
255
- res += segment;
256
- return res;
257
- }, "");
258
- return path;
259
- }
260
- FoldLine2.getSmoothStepPath = getSmoothStepPath;
261
- function getBounds(points) {
262
- const xList = points.map((p) => p.x);
263
- const yList = points.map((p) => p.y);
264
- const left = Math.min(...xList);
265
- const right = Math.max(...xList);
266
- const top = Math.min(...yList);
267
- const bottom = Math.max(...yList);
268
- return import_utils.Rectangle.createRectangleWithTwoPoints(
269
- {
270
- x: left,
271
- y: top
272
- },
273
- {
274
- x: right,
275
- y: bottom
276
- }
277
- );
278
- }
279
- FoldLine2.getBounds = getBounds;
280
- function getFoldLineToPointDistance(points, pos) {
281
- const bounds = getBounds(points);
282
- if (bounds.contains(pos.x, pos.y)) {
283
- const lines = points.reduce((res, point, index) => {
284
- if (index === 0) {
285
- return res;
286
- }
287
- res.push([points[index - 1], point]);
288
- return res;
289
- }, []);
290
- return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));
291
- }
292
- return Math.min(...points.map((p) => import_utils.Point.getDistance(p, pos)));
293
- }
294
- FoldLine2.getFoldLineToPointDistance = getFoldLineToPointDistance;
295
- })(FoldLine || (FoldLine = {}));
296
-
297
- // src/utils/bezier.ts
298
- var import_utils2 = require("@flowgram.ai/utils");
299
- var BezierControlType = /* @__PURE__ */ ((BezierControlType2) => {
300
- BezierControlType2[BezierControlType2["RIGHT_TOP"] = 0] = "RIGHT_TOP";
301
- BezierControlType2[BezierControlType2["RIGHT_BOTTOM"] = 1] = "RIGHT_BOTTOM";
302
- BezierControlType2[BezierControlType2["LEFT_TOP"] = 2] = "LEFT_TOP";
303
- BezierControlType2[BezierControlType2["LEFT_BOTTOM"] = 3] = "LEFT_BOTTOM";
304
- return BezierControlType2;
305
- })(BezierControlType || {});
306
- var CONTROL_MAX = 300;
307
- function getBezierHorizontalControlPoints(fromPos, toPos) {
308
- const rect = import_utils2.Rectangle.createRectangleWithTwoPoints(fromPos, toPos);
309
- let type;
310
- if (fromPos.x <= toPos.x) {
311
- type = fromPos.y <= toPos.y ? 1 /* RIGHT_BOTTOM */ : 0 /* RIGHT_TOP */;
312
- } else {
313
- type = fromPos.y <= toPos.y ? 3 /* LEFT_BOTTOM */ : 2 /* LEFT_TOP */;
314
- }
315
- let controls;
316
- switch (type) {
317
- case 0 /* RIGHT_TOP */:
318
- controls = [
319
- {
320
- x: rect.rightBottom.x - rect.width / 2,
321
- y: rect.rightBottom.y
322
- },
323
- {
324
- x: rect.leftTop.x + rect.width / 2,
325
- y: rect.leftTop.y
326
- }
327
- ];
328
- break;
329
- case 1 /* RIGHT_BOTTOM */:
330
- controls = [
331
- {
332
- x: rect.rightTop.x - rect.width / 2,
333
- y: rect.rightTop.y
334
- },
335
- {
336
- x: rect.leftBottom.x + rect.width / 2,
337
- y: rect.leftBottom.y
338
- }
339
- ];
340
- break;
341
- case 2 /* LEFT_TOP */:
342
- controls = [
343
- {
344
- x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),
345
- y: rect.rightBottom.y
346
- },
347
- {
348
- x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),
349
- y: rect.leftTop.y
350
- }
351
- ];
352
- break;
353
- case 3 /* LEFT_BOTTOM */:
354
- controls = [
355
- {
356
- x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),
357
- y: rect.rightTop.y
358
- },
359
- {
360
- x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),
361
- y: rect.leftBottom.y
362
- }
363
- ];
364
- }
365
- return controls;
366
- }
367
- function getBezierVerticalControlPoints(fromPos, toPos) {
368
- const rect = import_utils2.Rectangle.createRectangleWithTwoPoints(fromPos, toPos);
369
- let type;
370
- if (fromPos.y <= toPos.y) {
371
- type = fromPos.x <= toPos.x ? 1 /* RIGHT_BOTTOM */ : 3 /* LEFT_BOTTOM */;
372
- } else {
373
- type = fromPos.x <= toPos.x ? 0 /* RIGHT_TOP */ : 2 /* LEFT_TOP */;
374
- }
375
- let controls;
376
- switch (type) {
377
- case 1 /* RIGHT_BOTTOM */:
378
- controls = [
379
- {
380
- x: rect.leftTop.x,
381
- y: rect.leftTop.y + rect.height / 2
382
- },
383
- {
384
- x: rect.rightBottom.x,
385
- y: rect.rightBottom.y - rect.height / 2
386
- }
387
- ];
388
- break;
389
- case 3 /* LEFT_BOTTOM */:
390
- controls = [
391
- {
392
- x: rect.rightTop.x,
393
- y: rect.rightTop.y + rect.height / 2
394
- },
395
- {
396
- x: rect.leftBottom.x,
397
- y: rect.leftBottom.y - rect.height / 2
398
- }
399
- ];
400
- break;
401
- case 0 /* RIGHT_TOP */:
402
- controls = [
403
- {
404
- x: rect.leftBottom.x,
405
- y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX)
406
- },
407
- {
408
- x: rect.rightTop.x,
409
- y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX)
410
- }
411
- ];
412
- break;
413
- case 2 /* LEFT_TOP */:
414
- controls = [
415
- {
416
- x: rect.rightBottom.x,
417
- y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX)
418
- },
419
- {
420
- x: rect.leftTop.x,
421
- y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX)
422
- }
423
- ];
424
- break;
425
- }
426
- return controls;
427
- }
116
+ var import_utils4 = require("@flowgram.ai/utils");
428
117
 
429
118
  // src/utils/nanoid.ts
430
119
  var import_nanoid = require("nanoid");
@@ -433,13 +122,13 @@ function nanoid(n) {
433
122
  }
434
123
 
435
124
  // src/utils/compose.ts
436
- var import_utils3 = require("@flowgram.ai/utils");
125
+ var import_utils = require("@flowgram.ai/utils");
437
126
 
438
127
  // src/utils/fit-view.ts
439
128
  var import_core = require("@flowgram.ai/core");
440
- var import_utils4 = require("@flowgram.ai/utils");
129
+ var import_utils2 = require("@flowgram.ai/utils");
441
130
  var fitView = (doc, playgroundConfig, easing = true) => {
442
- const bounds = import_utils4.Rectangle.enlarge(
131
+ const bounds = import_utils2.Rectangle.enlarge(
443
132
  doc.getAllNodes().map((node) => node.getData(import_core.TransformData).bounds)
444
133
  );
445
134
  return playgroundConfig.fitView(bounds, easing, 30);
@@ -471,11 +160,11 @@ function getAntiOverlapPosition(doc, position, containerNode) {
471
160
  }
472
161
 
473
162
  // src/utils/statics.ts
474
- var import_utils5 = require("@flowgram.ai/utils");
163
+ var import_utils3 = require("@flowgram.ai/utils");
475
164
  var getPortEntityId = (node, portType, portID = "") => `port_${portType}_${node.id}_${portID}`;
476
165
  var WORKFLOW_LINE_ENTITY = "WorkflowLineEntity";
477
166
  function domReactToBounds(react) {
478
- return new import_utils5.Rectangle(react.x, react.y, react.width, react.height);
167
+ return new import_utils3.Rectangle(react.x, react.y, react.width, react.height);
479
168
  }
480
169
 
481
170
  // src/entities/workflow-node-entity.ts
@@ -484,24 +173,8 @@ var WorkflowNodeEntity = import_document.FlowNodeEntity;
484
173
 
485
174
  // src/entities/workflow-line-entity.ts
486
175
  var import_lodash_es2 = require("lodash-es");
487
- var import_bezier_js = require("bezier-js");
488
176
  var import_utils8 = require("@flowgram.ai/utils");
489
- var import_core6 = require("@flowgram.ai/core");
490
-
491
- // src/typings/workflow-line.ts
492
- var LineType = /* @__PURE__ */ ((LineType2) => {
493
- LineType2[LineType2["BEZIER"] = 0] = "BEZIER";
494
- LineType2[LineType2["LINE_CHART"] = 1] = "LINE_CHART";
495
- return LineType2;
496
- })(LineType || {});
497
- var LineColors = /* @__PURE__ */ ((LineColors2) => {
498
- LineColors2["HIDDEN"] = "transparent";
499
- LineColors2["DEFUALT"] = "#4d53e8";
500
- LineColors2["DRAWING"] = "#5DD6E3";
501
- LineColors2["HOVER"] = "#37d0ff";
502
- LineColors2["ERROR"] = "red";
503
- return LineColors2;
504
- })(LineColors || {});
177
+ var import_core8 = require("@flowgram.ai/core");
505
178
 
506
179
  // src/entity-datas/workflow-node-ports-data.ts
507
180
  var import_lodash_es = require("lodash-es");
@@ -509,7 +182,7 @@ var import_document2 = require("@flowgram.ai/document");
509
182
  var import_core5 = require("@flowgram.ai/core");
510
183
 
511
184
  // src/entities/workflow-port-entity.ts
512
- var import_utils7 = require("@flowgram.ai/utils");
185
+ var import_utils5 = require("@flowgram.ai/utils");
513
186
  var import_core4 = require("@flowgram.ai/core");
514
187
  var PORT_SIZE = 24;
515
188
  var WorkflowPortEntity = class extends import_core4.Entity {
@@ -519,7 +192,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
519
192
  this.portID = "";
520
193
  this._disabled = false;
521
194
  this._hasError = false;
522
- this._onErrorChangedEmitter = new import_utils7.Emitter();
195
+ this._onErrorChangedEmitter = new import_utils5.Emitter();
523
196
  this.onErrorChanged = this._onErrorChangedEmitter.event;
524
197
  this.portID = opts.portID || "";
525
198
  this.portType = opts.type;
@@ -576,7 +249,7 @@ var WorkflowPortEntity = class extends import_core4.Entity {
576
249
  get bounds() {
577
250
  const { point } = this;
578
251
  const halfSize = PORT_SIZE / 2;
579
- return new import_utils7.Rectangle(point.x - halfSize, point.y - halfSize, PORT_SIZE, PORT_SIZE);
252
+ return new import_utils5.Rectangle(point.x - halfSize, point.y - halfSize, PORT_SIZE, PORT_SIZE);
580
253
  }
581
254
  isHovered(x, y) {
582
255
  return this.bounds.contains(x, y);
@@ -832,10 +505,222 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
832
505
  };
833
506
  WorkflowNodePortsData.type = "WorkflowNodePortsData";
834
507
 
508
+ // src/entity-datas/workflow-node-lines-data.ts
509
+ var import_utils6 = require("@flowgram.ai/utils");
510
+ var import_core6 = require("@flowgram.ai/core");
511
+ var _WorkflowNodeLinesData = class _WorkflowNodeLinesData extends import_core6.EntityData {
512
+ getDefaultData() {
513
+ return {
514
+ inputLines: [],
515
+ outputLines: []
516
+ };
517
+ }
518
+ constructor(entity) {
519
+ super(entity);
520
+ this.entity = entity;
521
+ this.toDispose.push(
522
+ import_utils6.Disposable.create(() => {
523
+ this.inputLines.slice().forEach((line) => line.dispose());
524
+ this.outputLines.slice().forEach((line) => line.dispose());
525
+ })
526
+ );
527
+ }
528
+ /**
529
+ * 输入线条
530
+ */
531
+ get inputLines() {
532
+ return this.data.inputLines;
533
+ }
534
+ /**
535
+ * 输出线条
536
+ */
537
+ get outputLines() {
538
+ return this.data.outputLines;
539
+ }
540
+ /**
541
+ * 输入节点
542
+ */
543
+ get inputNodes() {
544
+ return this.inputLines.map((l) => l.from).filter(Boolean);
545
+ }
546
+ /**
547
+ * 所有输入节点
548
+ */
549
+ get allInputNodes() {
550
+ const nodeSet = /* @__PURE__ */ new Set();
551
+ const handleNode = (node) => {
552
+ if (nodeSet.has(node)) {
553
+ return;
554
+ }
555
+ nodeSet.add(node);
556
+ const { inputNodes } = node.getData(_WorkflowNodeLinesData);
557
+ if (!inputNodes || !inputNodes.length) {
558
+ return;
559
+ }
560
+ inputNodes.forEach((inputNode) => {
561
+ if (inputNode?.parent === node || node?.parent === inputNode) {
562
+ return;
563
+ }
564
+ handleNode(inputNode);
565
+ });
566
+ };
567
+ handleNode(this.entity);
568
+ nodeSet.delete(this.entity);
569
+ return Array.from(nodeSet);
570
+ }
571
+ /**
572
+ * 输出节点
573
+ */
574
+ get outputNodes() {
575
+ return this.outputLines.map((l) => l.to).filter(Boolean);
576
+ }
577
+ /**
578
+ * 输入输出节点
579
+ */
580
+ get allOutputNodes() {
581
+ const nodeSet = /* @__PURE__ */ new Set();
582
+ const handleNode = (node) => {
583
+ if (nodeSet.has(node)) {
584
+ return;
585
+ }
586
+ nodeSet.add(node);
587
+ const { outputNodes } = node.getData(_WorkflowNodeLinesData);
588
+ if (!outputNodes || !outputNodes.length) {
589
+ return;
590
+ }
591
+ outputNodes.forEach((outputNode) => {
592
+ if (outputNode?.parent === node || node?.parent === outputNode) {
593
+ return;
594
+ }
595
+ handleNode(outputNode);
596
+ });
597
+ };
598
+ handleNode(this.entity);
599
+ nodeSet.delete(this.entity);
600
+ return Array.from(nodeSet);
601
+ }
602
+ addLine(line) {
603
+ if (line.from === this.entity) {
604
+ this.outputLines.push(line);
605
+ } else {
606
+ this.inputLines.push(line);
607
+ }
608
+ this.fireChange();
609
+ }
610
+ removeLine(line) {
611
+ const { inputLines, outputLines } = this;
612
+ const inputIndex = inputLines.indexOf(line);
613
+ const outputIndex = outputLines.indexOf(line);
614
+ if (inputIndex !== -1) {
615
+ inputLines.splice(inputIndex, 1);
616
+ this.fireChange();
617
+ }
618
+ if (outputIndex !== -1) {
619
+ outputLines.splice(outputIndex, 1);
620
+ this.fireChange();
621
+ }
622
+ }
623
+ };
624
+ _WorkflowNodeLinesData.type = "WorkflowNodeLinesData";
625
+ var WorkflowNodeLinesData = _WorkflowNodeLinesData;
626
+
627
+ // src/entity-datas/workflow-line-render-data.ts
628
+ var import_utils7 = require("@flowgram.ai/utils");
629
+ var import_core7 = require("@flowgram.ai/core");
630
+ var WorkflowLineRenderData = class extends import_core7.EntityData {
631
+ constructor(entity) {
632
+ super(entity);
633
+ this.syncContributions();
634
+ }
635
+ getDefaultData() {
636
+ return {
637
+ version: "",
638
+ contributions: /* @__PURE__ */ new Map(),
639
+ position: {
640
+ from: { x: 0, y: 0 },
641
+ to: { x: 0, y: 0 }
642
+ }
643
+ };
644
+ }
645
+ get renderVersion() {
646
+ return this.data.version;
647
+ }
648
+ get position() {
649
+ return this.data.position;
650
+ }
651
+ get path() {
652
+ return this.currentLine?.path ?? "";
653
+ }
654
+ calcDistance(pos) {
655
+ return this.currentLine?.calcDistance(pos) ?? Number.MAX_SAFE_INTEGER;
656
+ }
657
+ get bounds() {
658
+ return this.currentLine?.bounds ?? new import_utils7.Rectangle();
659
+ }
660
+ /**
661
+ * 更新数据
662
+ * WARNING: 这个方法,必须在 requestAnimationFrame / useLayoutEffect 中调用,否则会引起浏览器强制重排
663
+ */
664
+ update() {
665
+ this.syncContributions();
666
+ const oldVersion = this.data.version;
667
+ this.updatePosition();
668
+ const newVersion = this.data.version;
669
+ if (oldVersion === newVersion) {
670
+ return;
671
+ }
672
+ this.data.version = newVersion;
673
+ this.currentLine?.update({
674
+ fromPos: this.data.position.from,
675
+ toPos: this.data.position.to
676
+ });
677
+ }
678
+ get lineType() {
679
+ return this.entity.renderType ?? this.entity.linesManager.lineType;
680
+ }
681
+ /**
682
+ * 更新版本
683
+ * WARNING: 这个方法,必须在 requestAnimationFrame / useLayoutEffect 中调用,否则会引起浏览器强制重排
684
+ */
685
+ updatePosition() {
686
+ this.data.position.from = this.entity.from.getData(WorkflowNodePortsData).getOutputPoint(this.entity.info.fromPort);
687
+ this.data.position.to = this.entity.info.drawingTo ?? this.entity.to?.getData(WorkflowNodePortsData)?.getInputPoint(this.entity.info.toPort) ?? {
688
+ x: this.data.position.from.x,
689
+ y: this.data.position.from.y
690
+ };
691
+ this.data.version = [
692
+ this.lineType,
693
+ this.data.position.from.x,
694
+ this.data.position.from.y,
695
+ this.data.position.to.x,
696
+ this.data.position.to.y
697
+ ].join("-");
698
+ }
699
+ get currentLine() {
700
+ return this.data.contributions.get(this.lineType);
701
+ }
702
+ syncContributions() {
703
+ if (this.entity.linesManager.contributionFactories.length === this.data.contributions.size) {
704
+ return;
705
+ }
706
+ this.entity.linesManager.contributionFactories.forEach((factory) => {
707
+ this.registerContribution(factory);
708
+ });
709
+ }
710
+ registerContribution(contributionFactory) {
711
+ if (this.data.contributions.has(contributionFactory.type)) {
712
+ return;
713
+ }
714
+ const contribution = new contributionFactory(this.entity);
715
+ this.data.contributions.set(contributionFactory.type, contribution);
716
+ }
717
+ };
718
+ WorkflowLineRenderData.type = "WorkflowLineRenderData";
719
+
835
720
  // src/entities/workflow-line-entity.ts
836
721
  var LINE_HOVER_DISTANCE = 8;
837
722
  var POINT_RADIUS = 10;
838
- var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity {
723
+ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core8.Entity {
839
724
  constructor(opts) {
840
725
  super(opts);
841
726
  this._processing = false;
@@ -846,10 +731,6 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity
846
731
  this.info = {
847
732
  from: ""
848
733
  };
849
- /**
850
- * 贝塞尔线条版本
851
- */
852
- this._bezierVersion = "";
853
734
  this.document = opts.document;
854
735
  this.linesManager = opts.linesManager;
855
736
  this.initInfo({
@@ -975,59 +856,17 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity
975
856
  this.fireChange();
976
857
  }
977
858
  }
978
- /**
979
- * 创建贝塞尔线条
980
- * @param fromPos 前置节点位置
981
- * @param toPos 后置节点位置
982
- * @returns 贝塞尔线条数据
983
- */
984
- createBezier(fromPos, toPos) {
985
- const controls = this.vertical ? getBezierVerticalControlPoints(fromPos, toPos) : getBezierHorizontalControlPoints(fromPos, toPos);
986
- const bezier = new import_bezier_js.Bezier([fromPos, ...controls, toPos]);
987
- const bbox = bezier.bbox();
988
- const bboxBounds = new import_utils8.Rectangle(
989
- bbox.x.min,
990
- bbox.y.min,
991
- bbox.x.max - bbox.x.min,
992
- bbox.y.max - bbox.y.min
993
- );
994
- const foldPoints = FoldLine.getPoints({
995
- source: {
996
- x: fromPos.x + POINT_RADIUS,
997
- y: fromPos.y
998
- },
999
- target: {
1000
- x: toPos.x - POINT_RADIUS,
1001
- y: toPos.y
1002
- }
1003
- });
1004
- const foldPath = FoldLine.getSmoothStepPath(foldPoints);
1005
- this._bezier = {
1006
- fromPos,
1007
- toPos,
1008
- bezier,
1009
- bbox: bboxBounds,
1010
- controls,
1011
- foldPath,
1012
- foldPoints,
1013
- foldBounds: FoldLine.getBounds(foldPoints)
1014
- };
1015
- return this._bezier;
1016
- }
1017
859
  /**
1018
860
  * 获取线条的边框位置大小
1019
861
  */
1020
862
  get bounds() {
1021
- return this.bezier.bbox;
863
+ return this.getData(WorkflowLineRenderData).bounds;
1022
864
  }
1023
865
  /**
1024
866
  * 获取点和线最接近的距离
1025
867
  */
1026
- getHoverDist(pos, lineType = 0 /* BEZIER */) {
1027
- if (lineType === 0 /* BEZIER */) {
1028
- return import_utils8.Point.getDistance(pos, this.bezier.bezier.project(pos));
1029
- }
1030
- return FoldLine.getFoldLineToPointDistance(this.bezier.foldPoints, pos);
868
+ getHoverDist(pos) {
869
+ return this.getData(WorkflowLineRenderData).calcDistance(pos);
1031
870
  }
1032
871
  get fromPort() {
1033
872
  return this.from.getData(WorkflowNodePortsData).getPortEntityByKey("output", this.info.fromPort);
@@ -1042,37 +881,7 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity
1042
881
  * 获取线条真实的输入输出节点坐标
1043
882
  */
1044
883
  get position() {
1045
- const { bezier } = this;
1046
- return {
1047
- from: bezier.fromPos,
1048
- to: bezier.toPos
1049
- };
1050
- }
1051
- /**
1052
- * 获取贝塞尔数据
1053
- * 根据两边节点的位置信息创建贝塞尔曲线
1054
- */
1055
- get bezier() {
1056
- if (!this._bezier) {
1057
- this.refreshBezier();
1058
- }
1059
- return this._bezier;
1060
- }
1061
- refreshBezier() {
1062
- const fromPos = this.from.getData(WorkflowNodePortsData).getOutputPoint(this.info.fromPort);
1063
- const toPos = this.info.drawingTo || this.to.getData(WorkflowNodePortsData).getInputPoint(this.info.toPort);
1064
- const bezierVersion = [fromPos.x, fromPos.y, toPos.x, toPos.y].join("-");
1065
- if (this._bezier && this._bezierVersion === bezierVersion) {
1066
- return;
1067
- }
1068
- this._bezierVersion = bezierVersion;
1069
- this._bezier = this.createBezier(fromPos, toPos);
1070
- }
1071
- /**
1072
- * 可以用于判断线条点位信息是否变化
1073
- */
1074
- get bezierDataVersion() {
1075
- return this._bezierVersion;
884
+ return this.getData(WorkflowLineRenderData).position;
1076
885
  }
1077
886
  /** 是否反转箭头 */
1078
887
  get reverse() {
@@ -1094,17 +903,17 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity
1094
903
  get vertical() {
1095
904
  return this.linesManager.isVerticalLine(this);
1096
905
  }
906
+ /** 获取线条渲染器类型 */
907
+ get renderType() {
908
+ return this.linesManager.setLineRenderType(this);
909
+ }
910
+ /** 获取线条样式 */
911
+ get className() {
912
+ return this.linesManager.setLineClassName(this) ?? "";
913
+ }
1097
914
  get color() {
1098
915
  return this.linesManager.getLineColor(this);
1099
916
  }
1100
- // get defaultToPos(): IPoint {
1101
- // const fromPos = this.from.getData(TransformComponent)!.toBounds.center;
1102
- //
1103
- // return {
1104
- // x: fromPos.x + DEFAULT_LINE_LENGTH,
1105
- // y: fromPos.y,
1106
- // };
1107
- // }
1108
917
  /**
1109
918
  * 初始化线条
1110
919
  * @param info 线条信息
@@ -1136,15 +945,6 @@ var _WorkflowLineEntity = class _WorkflowLineEntity extends import_core6.Entity
1136
945
  }
1137
946
  return _WorkflowLineEntity.portInfoToLineId(line) === this.id;
1138
947
  }
1139
- /**
1140
- * 框选 贝塞尔曲线
1141
- * TODO 这个方法可能有性能问题,后续看看有没有更好的方式
1142
- * @param rect
1143
- */
1144
- intersectsRectangle(rect) {
1145
- const dots = this.bezier.bezier.getLUT(50);
1146
- return dots.some((dot) => rect.contains(dot.x, dot.y));
1147
- }
1148
948
  canRemove(newLineInfo) {
1149
949
  return this.linesManager.canRemove(this, newLineInfo);
1150
950
  }
@@ -1245,12 +1045,12 @@ var WorkflowSelectService = class {
1245
1045
  async selectNodeAndScrollToView(node, fitView2) {
1246
1046
  this.selectNodeAndFocus(node);
1247
1047
  const DELAY_TIME = 30;
1248
- await (0, import_utils6.delay)(DELAY_TIME);
1048
+ await (0, import_utils4.delay)(DELAY_TIME);
1249
1049
  const scrollConfig = {
1250
1050
  entities: [node]
1251
1051
  };
1252
1052
  if (fitView2) {
1253
- const bounds = import_utils9.Rectangle.enlarge([node.getData(import_core7.TransformData).bounds]).pad(
1053
+ const bounds = import_utils9.Rectangle.enlarge([node.getData(import_core9.TransformData).bounds]).pad(
1254
1054
  30,
1255
1055
  30
1256
1056
  );
@@ -1268,10 +1068,10 @@ var WorkflowSelectService = class {
1268
1068
  }
1269
1069
  };
1270
1070
  __decorateClass([
1271
- (0, import_inversify.inject)(import_core7.SelectionService)
1071
+ (0, import_inversify.inject)(import_core9.SelectionService)
1272
1072
  ], WorkflowSelectService.prototype, "selectionService", 2);
1273
1073
  __decorateClass([
1274
- (0, import_inversify.inject)(import_core7.Playground)
1074
+ (0, import_inversify.inject)(import_core9.Playground)
1275
1075
  ], WorkflowSelectService.prototype, "playground", 2);
1276
1076
  WorkflowSelectService = __decorateClass([
1277
1077
  (0, import_inversify.injectable)()
@@ -1279,7 +1079,7 @@ WorkflowSelectService = __decorateClass([
1279
1079
 
1280
1080
  // src/service/workflow-hover-service.ts
1281
1081
  var import_inversify2 = require("inversify");
1282
- var import_core8 = require("@flowgram.ai/core");
1082
+ var import_core10 = require("@flowgram.ai/core");
1283
1083
  var import_utils11 = require("@flowgram.ai/utils");
1284
1084
  var WorkflowHoverService = class {
1285
1085
  constructor() {
@@ -1329,7 +1129,7 @@ var WorkflowHoverService = class {
1329
1129
  }
1330
1130
  };
1331
1131
  __decorateClass([
1332
- (0, import_inversify2.inject)(import_core8.EntityManager)
1132
+ (0, import_inversify2.inject)(import_core10.EntityManager)
1333
1133
  ], WorkflowHoverService.prototype, "entityManager", 2);
1334
1134
  WorkflowHoverService = __decorateClass([
1335
1135
  (0, import_inversify2.injectable)()
@@ -1338,22 +1138,22 @@ WorkflowHoverService = __decorateClass([
1338
1138
  // src/service/workflow-drag-service.ts
1339
1139
  var import_nanoid3 = require("nanoid");
1340
1140
  var import_inversify6 = require("inversify");
1341
- var import_utils17 = require("@flowgram.ai/utils");
1141
+ var import_utils16 = require("@flowgram.ai/utils");
1342
1142
  var import_document7 = require("@flowgram.ai/document");
1343
1143
  var import_document8 = require("@flowgram.ai/document");
1344
- var import_core14 = require("@flowgram.ai/core");
1144
+ var import_core15 = require("@flowgram.ai/core");
1345
1145
 
1346
1146
  // src/workflow-lines-manager.ts
1347
1147
  var import_lodash_es3 = require("lodash-es");
1348
1148
  var import_inversify3 = require("inversify");
1349
- var import_utils13 = require("@flowgram.ai/utils");
1149
+ var import_utils12 = require("@flowgram.ai/utils");
1350
1150
  var import_document4 = require("@flowgram.ai/document");
1351
- var import_core11 = require("@flowgram.ai/core");
1151
+ var import_core12 = require("@flowgram.ai/core");
1352
1152
 
1353
1153
  // src/workflow-document-option.ts
1354
1154
  var import_form_core2 = require("@flowgram.ai/form-core");
1355
1155
  var import_document3 = require("@flowgram.ai/document");
1356
- var import_core9 = require("@flowgram.ai/core");
1156
+ var import_core11 = require("@flowgram.ai/core");
1357
1157
 
1358
1158
  // src/utils/flow-node-form-data.ts
1359
1159
  var import_form_core = require("@flowgram.ai/form-core");
@@ -1378,7 +1178,7 @@ var WorkflowDocumentOptionsDefault = {
1378
1178
  if (nodeError) {
1379
1179
  throw nodeError;
1380
1180
  }
1381
- const transform = node.getData(import_core9.TransformData);
1181
+ const transform = node.getData(import_core11.TransformData);
1382
1182
  let formJSON = toFormJSON(node);
1383
1183
  const metaData = {};
1384
1184
  const nodeMeta = node.getNodeMeta();
@@ -1401,6 +1201,21 @@ var WorkflowDocumentOptionsDefault = {
1401
1201
  }
1402
1202
  };
1403
1203
 
1204
+ // src/typings/workflow-line.ts
1205
+ var LineType = /* @__PURE__ */ ((LineType2) => {
1206
+ LineType2[LineType2["BEZIER"] = 0] = "BEZIER";
1207
+ LineType2[LineType2["LINE_CHART"] = 1] = "LINE_CHART";
1208
+ return LineType2;
1209
+ })(LineType || {});
1210
+ var LineColors = /* @__PURE__ */ ((LineColors2) => {
1211
+ LineColors2["HIDDEN"] = "transparent";
1212
+ LineColors2["DEFUALT"] = "#4d53e8";
1213
+ LineColors2["DRAWING"] = "#5DD6E3";
1214
+ LineColors2["HOVER"] = "#37d0ff";
1215
+ LineColors2["ERROR"] = "red";
1216
+ return LineColors2;
1217
+ })(LineColors || {});
1218
+
1404
1219
  // src/typings/workflow-json.ts
1405
1220
  var WorkflowContentChangeType = /* @__PURE__ */ ((WorkflowContentChangeType2) => {
1406
1221
  WorkflowContentChangeType2["ADD_NODE"] = "ADD_NODE";
@@ -1416,133 +1231,14 @@ var WorkflowContentChangeType = /* @__PURE__ */ ((WorkflowContentChangeType2) =>
1416
1231
  // src/typings/index.ts
1417
1232
  var URLParams = Symbol("");
1418
1233
 
1419
- // src/entity-datas/workflow-node-lines-data.ts
1420
- var import_utils12 = require("@flowgram.ai/utils");
1421
- var import_core10 = require("@flowgram.ai/core");
1422
- var _WorkflowNodeLinesData = class _WorkflowNodeLinesData extends import_core10.EntityData {
1423
- getDefaultData() {
1424
- return {
1425
- inputLines: [],
1426
- outputLines: []
1427
- };
1428
- }
1429
- constructor(entity) {
1430
- super(entity);
1431
- this.entity = entity;
1432
- this.toDispose.push(
1433
- import_utils12.Disposable.create(() => {
1434
- this.inputLines.slice().forEach((line) => line.dispose());
1435
- this.outputLines.slice().forEach((line) => line.dispose());
1436
- })
1437
- );
1438
- }
1439
- /**
1440
- * 输入线条
1441
- */
1442
- get inputLines() {
1443
- return this.data.inputLines;
1444
- }
1445
- /**
1446
- * 输出线条
1447
- */
1448
- get outputLines() {
1449
- return this.data.outputLines;
1450
- }
1451
- /**
1452
- * 输入节点
1453
- */
1454
- get inputNodes() {
1455
- return this.inputLines.map((l) => l.from).filter(Boolean);
1456
- }
1457
- /**
1458
- * 所有输入节点
1459
- */
1460
- get allInputNodes() {
1461
- const nodeSet = /* @__PURE__ */ new Set();
1462
- const handleNode = (node) => {
1463
- if (nodeSet.has(node)) {
1464
- return;
1465
- }
1466
- nodeSet.add(node);
1467
- const { inputNodes } = node.getData(_WorkflowNodeLinesData);
1468
- if (!inputNodes || !inputNodes.length) {
1469
- return;
1470
- }
1471
- inputNodes.forEach((inputNode) => {
1472
- if (inputNode?.parent === node || node?.parent === inputNode) {
1473
- return;
1474
- }
1475
- handleNode(inputNode);
1476
- });
1477
- };
1478
- handleNode(this.entity);
1479
- nodeSet.delete(this.entity);
1480
- return Array.from(nodeSet);
1481
- }
1482
- /**
1483
- * 输出节点
1484
- */
1485
- get outputNodes() {
1486
- return this.outputLines.map((l) => l.to).filter(Boolean);
1487
- }
1488
- /**
1489
- * 输入输出节点
1490
- */
1491
- get allOutputNodes() {
1492
- const nodeSet = /* @__PURE__ */ new Set();
1493
- const handleNode = (node) => {
1494
- if (nodeSet.has(node)) {
1495
- return;
1496
- }
1497
- nodeSet.add(node);
1498
- const { outputNodes } = node.getData(_WorkflowNodeLinesData);
1499
- if (!outputNodes || !outputNodes.length) {
1500
- return;
1501
- }
1502
- outputNodes.forEach((outputNode) => {
1503
- if (outputNode?.parent === node || node?.parent === outputNode) {
1504
- return;
1505
- }
1506
- handleNode(outputNode);
1507
- });
1508
- };
1509
- handleNode(this.entity);
1510
- nodeSet.delete(this.entity);
1511
- return Array.from(nodeSet);
1512
- }
1513
- addLine(line) {
1514
- if (line.from === this.entity) {
1515
- this.outputLines.push(line);
1516
- } else {
1517
- this.inputLines.push(line);
1518
- }
1519
- this.fireChange();
1520
- }
1521
- removeLine(line) {
1522
- const { inputLines, outputLines } = this;
1523
- const inputIndex = inputLines.indexOf(line);
1524
- const outputIndex = outputLines.indexOf(line);
1525
- if (inputIndex !== -1) {
1526
- inputLines.splice(inputIndex, 1);
1527
- this.fireChange();
1528
- }
1529
- if (outputIndex !== -1) {
1530
- outputLines.splice(outputIndex, 1);
1531
- this.fireChange();
1532
- }
1533
- }
1534
- };
1535
- _WorkflowNodeLinesData.type = "WorkflowNodeLinesData";
1536
- var WorkflowNodeLinesData = _WorkflowNodeLinesData;
1537
-
1538
1234
  // src/workflow-lines-manager.ts
1539
1235
  var WorkflowLinesManager = class {
1540
1236
  constructor() {
1541
- this.toDispose = new import_utils13.DisposableCollection();
1237
+ this.toDispose = new import_utils12.DisposableCollection();
1542
1238
  // 线条类型
1543
1239
  this._lineType = 0 /* BEZIER */;
1544
- this.onAvailableLinesChangeEmitter = new import_utils13.Emitter();
1545
- this.onForceUpdateEmitter = new import_utils13.Emitter();
1240
+ this.onAvailableLinesChangeEmitter = new import_utils12.Emitter();
1241
+ this.onForceUpdateEmitter = new import_utils12.Emitter();
1546
1242
  /**
1547
1243
  * 有效的线条被添加或者删除时候触发,未连上的线条不算
1548
1244
  */
@@ -1551,6 +1247,7 @@ var WorkflowLinesManager = class {
1551
1247
  * 强制渲染 lines
1552
1248
  */
1553
1249
  this.onForceUpdate = this.onForceUpdateEmitter.event;
1250
+ this.contributionFactories = [];
1554
1251
  /**
1555
1252
  * 是否在调整线条
1556
1253
  */
@@ -1589,7 +1286,12 @@ var WorkflowLinesManager = class {
1589
1286
  }
1590
1287
  if (newType !== this._lineType) {
1591
1288
  this._lineType = newType;
1592
- this.entityManager.fireEntityChanged(WorkflowLineEntity.type);
1289
+ this.getAllLines().forEach((line) => {
1290
+ line.getData(WorkflowLineRenderData).update();
1291
+ });
1292
+ window.requestAnimationFrame(() => {
1293
+ this.entityManager.fireEntityChanged(WorkflowLineEntity.type);
1294
+ });
1593
1295
  }
1594
1296
  return this._lineType;
1595
1297
  }
@@ -1639,6 +1341,7 @@ var WorkflowLinesManager = class {
1639
1341
  to,
1640
1342
  drawingTo
1641
1343
  });
1344
+ this.registerData(line);
1642
1345
  fromNode.addLine(line);
1643
1346
  toNode?.addLine(line);
1644
1347
  line.onDispose(() => {
@@ -1650,7 +1353,7 @@ var WorkflowLinesManager = class {
1650
1353
  line.validate();
1651
1354
  });
1652
1355
  line.toDispose.push(
1653
- import_utils13.Disposable.create(() => {
1356
+ import_utils12.Disposable.create(() => {
1654
1357
  if (available) {
1655
1358
  this.onAvailableLinesChangeEmitter.fire({
1656
1359
  type: "DELETE_LINE" /* DELETE_LINE */,
@@ -1679,7 +1382,7 @@ var WorkflowLinesManager = class {
1679
1382
  getCloseInLineFromMousePos(mousePos, minDistance = LINE_HOVER_DISTANCE) {
1680
1383
  let targetLine, targetLineDist;
1681
1384
  this.getAllLines().forEach((line) => {
1682
- const dist = line.getHoverDist(mousePos, this.lineType);
1385
+ const dist = line.getHoverDist(mousePos);
1683
1386
  if (dist <= minDistance && (!targetLineDist || targetLineDist >= dist)) {
1684
1387
  targetLineDist = dist;
1685
1388
  targetLine = line;
@@ -1729,6 +1432,18 @@ var WorkflowLinesManager = class {
1729
1432
  }
1730
1433
  return false;
1731
1434
  }
1435
+ setLineRenderType(line) {
1436
+ if (this.options.setLineRenderType) {
1437
+ return this.options.setLineRenderType(line);
1438
+ }
1439
+ return void 0;
1440
+ }
1441
+ setLineClassName(line) {
1442
+ if (this.options.setLineClassName) {
1443
+ return this.options.setLineClassName(line);
1444
+ }
1445
+ return void 0;
1446
+ }
1732
1447
  getLineColor(line) {
1733
1448
  if (line.isHidden) {
1734
1449
  return this.lineColor.hidden;
@@ -1785,7 +1500,7 @@ var WorkflowLinesManager = class {
1785
1500
  const allPorts = this.entityManager.getEntities(WorkflowPortEntity).filter((port) => port.node.flowNodeType !== "root");
1786
1501
  const targetPort = allPorts.find((port) => port.isHovered(pos.x, pos.y));
1787
1502
  if (targetPort) {
1788
- const targetNode = this.document.getAllNodes().slice().reverse().filter((node) => targetPort.node?.parent?.id !== node.id).find((node) => node.getData(import_core11.TransformData).contains(pos.x, pos.y));
1503
+ const targetNode = this.document.getAllNodes().slice().reverse().filter((node) => targetPort.node?.parent?.id !== node.id).find((node) => node.getData(import_core12.TransformData).contains(pos.x, pos.y));
1789
1504
  if (targetNode && targetNode !== targetPort.node) {
1790
1505
  return;
1791
1506
  }
@@ -1800,7 +1515,7 @@ var WorkflowLinesManager = class {
1800
1515
  const allNodes = this.document.getAllNodes();
1801
1516
  const containNodes = [];
1802
1517
  const { selection } = this.selectService;
1803
- const zoom = this.entityManager.getEntity(import_core11.PlaygroundConfigEntity)?.config?.zoom || 1;
1518
+ const zoom = this.entityManager.getEntity(import_core12.PlaygroundConfigEntity)?.config?.zoom || 1;
1804
1519
  allNodes.forEach((node) => {
1805
1520
  const { bounds } = node.getData(import_document4.FlowNodeTransformData);
1806
1521
  if (bounds.clone().pad(4 / zoom).contains(pos.x, pos.y)) {
@@ -1817,6 +1532,13 @@ var WorkflowLinesManager = class {
1817
1532
  }
1818
1533
  return (0, import_lodash_es3.last)(containNodes);
1819
1534
  }
1535
+ registerContribution(factory) {
1536
+ this.contributionFactories.push(factory);
1537
+ return this;
1538
+ }
1539
+ registerData(line) {
1540
+ line.addData(WorkflowLineRenderData);
1541
+ }
1820
1542
  };
1821
1543
  __decorateClass([
1822
1544
  (0, import_inversify3.inject)(WorkflowHoverService)
@@ -1825,7 +1547,7 @@ __decorateClass([
1825
1547
  (0, import_inversify3.inject)(WorkflowSelectService)
1826
1548
  ], WorkflowLinesManager.prototype, "selectService", 2);
1827
1549
  __decorateClass([
1828
- (0, import_inversify3.inject)(import_core11.EntityManager)
1550
+ (0, import_inversify3.inject)(import_core12.EntityManager)
1829
1551
  ], WorkflowLinesManager.prototype, "entityManager", 2);
1830
1552
  __decorateClass([
1831
1553
  (0, import_inversify3.inject)(WorkflowDocumentOptions)
@@ -1837,16 +1559,16 @@ WorkflowLinesManager = __decorateClass([
1837
1559
  // src/workflow-document.ts
1838
1560
  var import_nanoid2 = require("nanoid");
1839
1561
  var import_inversify5 = require("inversify");
1840
- var import_utils15 = require("@flowgram.ai/utils");
1562
+ var import_utils14 = require("@flowgram.ai/utils");
1841
1563
  var import_form_core3 = require("@flowgram.ai/form-core");
1842
1564
  var import_document6 = require("@flowgram.ai/document");
1843
- var import_core13 = require("@flowgram.ai/core");
1565
+ var import_core14 = require("@flowgram.ai/core");
1844
1566
 
1845
1567
  // src/layout/free-layout.ts
1846
1568
  var import_inversify4 = require("inversify");
1847
1569
  var import_document5 = require("@flowgram.ai/document");
1848
- var import_core12 = require("@flowgram.ai/core");
1849
- var import_utils14 = require("@flowgram.ai/utils");
1570
+ var import_core13 = require("@flowgram.ai/core");
1571
+ var import_utils13 = require("@flowgram.ai/utils");
1850
1572
  var FREE_LAYOUT_KEY = "free-layout";
1851
1573
  var FreeLayout = class {
1852
1574
  constructor() {
@@ -1891,18 +1613,18 @@ var FreeLayout = class {
1891
1613
  if (padding) {
1892
1614
  return typeof padding === "function" ? padding(transform) : padding;
1893
1615
  }
1894
- return import_utils14.PaddingSchema.empty();
1616
+ return import_utils13.PaddingSchema.empty();
1895
1617
  }
1896
1618
  /**
1897
1619
  * 默认滚动到 fitview 区域
1898
1620
  * @param contentSize
1899
1621
  */
1900
1622
  getInitScroll(contentSize) {
1901
- const bounds = import_utils14.Rectangle.enlarge(
1902
- this.document.getAllNodes().map((node) => node.getData(import_core12.TransformData).bounds)
1623
+ const bounds = import_utils13.Rectangle.enlarge(
1624
+ this.document.getAllNodes().map((node) => node.getData(import_core13.TransformData).bounds)
1903
1625
  ).pad(30, 30);
1904
1626
  const viewport = this.playgroundConfig.getViewport(false);
1905
- const zoom = import_utils14.SizeSchema.fixSize(bounds, viewport);
1627
+ const zoom = import_utils13.SizeSchema.fixSize(bounds, viewport);
1906
1628
  return {
1907
1629
  scrollX: (bounds.x + bounds.width / 2) * zoom - this.playgroundConfig.config.width / 2,
1908
1630
  scrollY: (bounds.y + bounds.height / 2) * zoom - this.playgroundConfig.config.height / 2
@@ -1912,13 +1634,13 @@ var FreeLayout = class {
1912
1634
  * 获取默认输入点
1913
1635
  */
1914
1636
  getDefaultInputPoint(node) {
1915
- return node.getData(import_core12.TransformData).bounds.leftCenter;
1637
+ return node.getData(import_core13.TransformData).bounds.leftCenter;
1916
1638
  }
1917
1639
  /**
1918
1640
  * 获取默认输出点
1919
1641
  */
1920
1642
  getDefaultOutputPoint(node) {
1921
- return node.getData(import_core12.TransformData).bounds.rightCenter;
1643
+ return node.getData(import_core13.TransformData).bounds.rightCenter;
1922
1644
  }
1923
1645
  /**
1924
1646
  * 水平中心点
@@ -1928,7 +1650,7 @@ var FreeLayout = class {
1928
1650
  }
1929
1651
  };
1930
1652
  __decorateClass([
1931
- (0, import_inversify4.inject)(import_core12.PlaygroundConfigEntity)
1653
+ (0, import_inversify4.inject)(import_core13.PlaygroundConfigEntity)
1932
1654
  ], FreeLayout.prototype, "playgroundConfig", 2);
1933
1655
  __decorateClass([
1934
1656
  (0, import_inversify4.inject)(import_document5.FlowDocumentProvider)
@@ -1943,10 +1665,10 @@ var WorkflowDocumentProvider = Symbol("WorkflowDocumentProvider");
1943
1665
  var WorkflowDocument = class extends import_document6.FlowDocument {
1944
1666
  constructor() {
1945
1667
  super(...arguments);
1946
- this._onContentChangeEmitter = new import_utils15.Emitter();
1947
- this.onLoadedEmitter = new import_utils15.Emitter();
1668
+ this._onContentChangeEmitter = new import_utils14.Emitter();
1669
+ this.onLoadedEmitter = new import_utils14.Emitter();
1948
1670
  this.onContentChange = this._onContentChangeEmitter.event;
1949
- this._onReloadEmitter = new import_utils15.Emitter();
1671
+ this._onReloadEmitter = new import_utils14.Emitter();
1950
1672
  this.onReload = this._onReloadEmitter.event;
1951
1673
  this.disposed = false;
1952
1674
  /**
@@ -1986,7 +1708,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
1986
1708
  this._loading = true;
1987
1709
  this.clear();
1988
1710
  this.fromJSON(json);
1989
- await (0, import_utils6.delay)(delayTime);
1711
+ await (0, import_utils4.delay)(delayTime);
1990
1712
  this._loading = false;
1991
1713
  this._onReloadEmitter.fire(this);
1992
1714
  }
@@ -2042,7 +1764,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2042
1764
  if (!position) {
2043
1765
  position = this.getNodeDefaultPosition(json.type);
2044
1766
  }
2045
- node.getData(import_core13.TransformData).update({
1767
+ node.getData(import_core14.TransformData).update({
2046
1768
  position
2047
1769
  });
2048
1770
  if (formMeta && formData) {
@@ -2055,7 +1777,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2055
1777
  });
2056
1778
  });
2057
1779
  }
2058
- const positionData = node.getData(import_core13.PositionData);
1780
+ const positionData = node.getData(import_core14.PositionData);
2059
1781
  positionData.onDataChange(() => {
2060
1782
  this.fireContentChange({
2061
1783
  type: "MOVE_NODE" /* MOVE_NODE */,
@@ -2071,7 +1793,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2071
1793
  toJSON: () => this.toNodeJSON(node)
2072
1794
  });
2073
1795
  node.toDispose.push(
2074
- import_utils15.Disposable.create(() => {
1796
+ import_utils14.Disposable.create(() => {
2075
1797
  this.fireContentChange({
2076
1798
  type: "DELETE_NODE" /* DELETE_NODE */,
2077
1799
  entity: node,
@@ -2080,7 +1802,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2080
1802
  })
2081
1803
  );
2082
1804
  node.toDispose.push(
2083
- import_utils15.Disposable.create(() => {
1805
+ import_utils14.Disposable.create(() => {
2084
1806
  if (!node.parent || node.parent.flowNodeType === import_document6.FlowNodeBaseType.ROOT) {
2085
1807
  return;
2086
1808
  }
@@ -2101,7 +1823,7 @@ var WorkflowDocument = class extends import_document6.FlowDocument {
2101
1823
  );
2102
1824
  }
2103
1825
  if (subCanvas) {
2104
- const canvasTransform = subCanvas.canvasNode.getData(import_core13.TransformData);
1826
+ const canvasTransform = subCanvas.canvasNode.getData(import_core14.TransformData);
2105
1827
  canvasTransform.update({
2106
1828
  position: subCanvas.parentNode.getNodeMeta()?.canvasPosition
2107
1829
  });
@@ -2524,10 +2246,10 @@ __decorateClass([
2524
2246
  (0, import_inversify5.inject)(WorkflowLinesManager)
2525
2247
  ], WorkflowDocument.prototype, "linesManager", 2);
2526
2248
  __decorateClass([
2527
- (0, import_inversify5.inject)(import_core13.PlaygroundConfigEntity)
2249
+ (0, import_inversify5.inject)(import_core14.PlaygroundConfigEntity)
2528
2250
  ], WorkflowDocument.prototype, "playgroundConfig", 2);
2529
2251
  __decorateClass([
2530
- (0, import_core13.injectPlaygroundContext)()
2252
+ (0, import_core14.injectPlaygroundContext)()
2531
2253
  ], WorkflowDocument.prototype, "playgroundContext", 2);
2532
2254
  __decorateClass([
2533
2255
  (0, import_inversify5.inject)(WorkflowDocumentOptions)
@@ -2557,12 +2279,12 @@ function checkDragSuccess(time, e, originLine) {
2557
2279
  }
2558
2280
  var WorkflowDragService = class {
2559
2281
  constructor() {
2560
- this._onDragLineEventEmitter = new import_utils17.Emitter();
2282
+ this._onDragLineEventEmitter = new import_utils16.Emitter();
2561
2283
  this.onDragLineEventChange = this._onDragLineEventEmitter.event;
2562
2284
  this.isDragging = false;
2563
- this._nodesDragEmitter = new import_utils17.Emitter();
2285
+ this._nodesDragEmitter = new import_utils16.Emitter();
2564
2286
  this.onNodesDrag = this._nodesDragEmitter.event;
2565
- this._toDispose = new import_utils17.DisposableCollection();
2287
+ this._toDispose = new import_utils16.DisposableCollection();
2566
2288
  this._droppableTransforms = [];
2567
2289
  this.posAdjusters = /* @__PURE__ */ new Set();
2568
2290
  this._onDragLineEndCallbacks = /* @__PURE__ */ new Map();
@@ -2589,12 +2311,12 @@ var WorkflowDragService = class {
2589
2311
  const { altKey } = event;
2590
2312
  let startPosition = this.getNodesPosition(selectedNodes);
2591
2313
  let startPositions = selectedNodes.map((node) => {
2592
- const transform = node.getData(import_core14.TransformData);
2314
+ const transform = node.getData(import_core15.TransformData);
2593
2315
  return { x: transform.position.x, y: transform.position.y };
2594
2316
  });
2595
2317
  let dragSuccess = false;
2596
2318
  const startTime = Date.now();
2597
- const dragger = new import_core14.PlaygroundDrag({
2319
+ const dragger = new import_core15.PlaygroundDrag({
2598
2320
  onDragStart: () => {
2599
2321
  this.isDragging = true;
2600
2322
  },
@@ -2609,7 +2331,7 @@ var WorkflowDragService = class {
2609
2331
  selectedNodes = newNodes;
2610
2332
  startPosition = this.getNodesPosition(tryCopyNodes);
2611
2333
  startPositions = tryCopyNodes.filter((n) => !n.getNodeMeta().copyDisable).map((node) => {
2612
- const transform = node.getData(import_core14.TransformData);
2334
+ const transform = node.getData(import_core15.TransformData);
2613
2335
  return {
2614
2336
  x: transform.position.x,
2615
2337
  y: transform.position.y
@@ -2626,7 +2348,7 @@ var WorkflowDragService = class {
2626
2348
  startPosition
2627
2349
  });
2628
2350
  selectedNodes.forEach((node, index) => {
2629
- const transform = node.getData(import_core14.TransformData);
2351
+ const transform = node.getData(import_core15.TransformData);
2630
2352
  const nodeStartPosition = startPositions[index];
2631
2353
  const newPosition = {
2632
2354
  x: nodeStartPosition.x + offset.x,
@@ -2684,14 +2406,14 @@ var WorkflowDragService = class {
2684
2406
  async startDragCard(type, event, data, cloneNode) {
2685
2407
  let domNode;
2686
2408
  let startPos = { x: 0, y: 0 };
2687
- const deferred = new import_utils17.PromiseDeferred();
2688
- const dragger = new import_core14.PlaygroundDrag({
2409
+ const deferred = new import_utils16.PromiseDeferred();
2410
+ const dragger = new import_core15.PlaygroundDrag({
2689
2411
  onDragStart: (e) => {
2690
2412
  const targetNode = event.currentTarget;
2691
2413
  domNode = cloneNode ? cloneNode(e) : targetNode.cloneNode(true);
2692
2414
  const bounds = targetNode.getBoundingClientRect();
2693
2415
  startPos = { x: bounds.left, y: bounds.top };
2694
- import_utils17.domUtils.setStyle(domNode, {
2416
+ import_utils16.domUtils.setStyle(domNode, {
2695
2417
  zIndex: 1e3,
2696
2418
  position: "absolute",
2697
2419
  left: startPos.x,
@@ -2709,17 +2431,17 @@ var WorkflowDragService = class {
2709
2431
  domNode.style.left = `${left}px`;
2710
2432
  domNode.style.top = `${right}px`;
2711
2433
  const { x, y } = this.playgroundConfig.getPosFromMouseEvent(e);
2712
- const draggingRect = new import_utils17.Rectangle(x, y, 170, 90);
2434
+ const draggingRect = new import_utils16.Rectangle(x, y, 170, 90);
2713
2435
  const collisionTransform = this._droppableTransforms.find((transform) => {
2714
2436
  const { bounds, entity } = transform;
2715
2437
  const padding = this.document.layout.getPadding(entity);
2716
- const transformRect = new import_utils17.Rectangle(
2438
+ const transformRect = new import_utils16.Rectangle(
2717
2439
  bounds.x + padding.left + padding.right,
2718
2440
  bounds.y,
2719
2441
  bounds.width,
2720
2442
  bounds.height
2721
2443
  );
2722
- return import_utils17.Rectangle.intersects(draggingRect, transformRect);
2444
+ return import_utils16.Rectangle.intersects(draggingRect, transformRect);
2723
2445
  });
2724
2446
  this.updateDropNode(collisionTransform?.entity);
2725
2447
  },
@@ -2735,7 +2457,7 @@ var WorkflowDragService = class {
2735
2457
  domNode.style.left = `${startPos.x}px`;
2736
2458
  domNode.style.top = `${startPos.y}px`;
2737
2459
  const TIMEOUT = 200;
2738
- await (0, import_utils17.delay)(TIMEOUT);
2460
+ await (0, import_utils16.delay)(TIMEOUT);
2739
2461
  domNode.remove();
2740
2462
  deferred.resolve();
2741
2463
  }
@@ -2756,7 +2478,7 @@ var WorkflowDragService = class {
2756
2478
  }
2757
2479
  const isParentEmpty = !containerNode.children || containerNode.children.length === 0;
2758
2480
  const parentPadding = this.document.layout.getPadding(containerNode);
2759
- const parentTransform = containerNode.getData(import_core14.TransformData);
2481
+ const parentTransform = containerNode.getData(import_core15.TransformData);
2760
2482
  if (isParentEmpty && resetEmptyPos) {
2761
2483
  return {
2762
2484
  x: 0,
@@ -2823,7 +2545,7 @@ var WorkflowDragService = class {
2823
2545
  * 获取节点整体位置
2824
2546
  */
2825
2547
  getNodesPosition(nodes) {
2826
- const selectedBounds = import_utils17.Rectangle.enlarge(
2548
+ const selectedBounds = import_utils16.Rectangle.enlarge(
2827
2549
  nodes.map((n) => n.getData(import_document7.FlowNodeTransformData).bounds)
2828
2550
  );
2829
2551
  const position = {
@@ -2910,12 +2632,12 @@ var WorkflowDragService = class {
2910
2632
  return { dragSuccess: false, newLine: void 0 };
2911
2633
  }
2912
2634
  const config = this.playgroundConfig;
2913
- const deferred = new import_utils17.PromiseDeferred();
2635
+ const deferred = new import_utils16.PromiseDeferred();
2914
2636
  const preCursor = config.cursor;
2915
2637
  let line, toPort, toNode, lineErrorReset = false;
2916
2638
  const startTime = Date.now();
2917
2639
  let dragSuccess = false;
2918
- const dragger = new import_core14.PlaygroundDrag({
2640
+ const dragger = new import_core15.PlaygroundDrag({
2919
2641
  onDrag: (e) => {
2920
2642
  if (!line && checkDragSuccess(Date.now() - startTime, e, originLine)) {
2921
2643
  if (originLine) {
@@ -3065,7 +2787,7 @@ var WorkflowDragService = class {
3065
2787
  }
3066
2788
  };
3067
2789
  __decorateClass([
3068
- (0, import_inversify6.inject)(import_core14.PlaygroundConfigEntity)
2790
+ (0, import_inversify6.inject)(import_core15.PlaygroundConfigEntity)
3069
2791
  ], WorkflowDragService.prototype, "playgroundConfig", 2);
3070
2792
  __decorateClass([
3071
2793
  (0, import_inversify6.inject)(WorkflowHoverService)
@@ -3077,7 +2799,7 @@ __decorateClass([
3077
2799
  (0, import_inversify6.inject)(WorkflowLinesManager)
3078
2800
  ], WorkflowDragService.prototype, "linesManager", 2);
3079
2801
  __decorateClass([
3080
- (0, import_inversify6.inject)(import_core14.CommandService)
2802
+ (0, import_inversify6.inject)(import_core15.CommandService)
3081
2803
  ], WorkflowDragService.prototype, "commandService", 2);
3082
2804
  __decorateClass([
3083
2805
  (0, import_inversify6.inject)(WorkflowSelectService)
@@ -3094,17 +2816,17 @@ WorkflowDragService = __decorateClass([
3094
2816
 
3095
2817
  // src/service/workflow-reset-layout-service.ts
3096
2818
  var import_inversify7 = require("inversify");
3097
- var import_core16 = require("@flowgram.ai/core");
3098
2819
  var import_core17 = require("@flowgram.ai/core");
3099
- var import_utils18 = require("@flowgram.ai/utils");
2820
+ var import_core18 = require("@flowgram.ai/core");
2821
+ var import_utils17 = require("@flowgram.ai/utils");
3100
2822
 
3101
2823
  // src/utils/layout-to-positions.ts
3102
2824
  var import_document9 = require("@flowgram.ai/document");
3103
- var import_core15 = require("@flowgram.ai/core");
2825
+ var import_core16 = require("@flowgram.ai/core");
3104
2826
  var layoutToPositions = async (nodes, nodePositionMap) => {
3105
2827
  const newNodePositionMap = {};
3106
2828
  nodes.forEach((node) => {
3107
- const transform = node.getData(import_core15.TransformData);
2829
+ const transform = node.getData(import_core16.TransformData);
3108
2830
  const nodeTransform = node.getData(import_document9.FlowNodeTransformData);
3109
2831
  newNodePositionMap[node.id] = {
3110
2832
  x: transform.position.x,
@@ -3112,13 +2834,13 @@ var layoutToPositions = async (nodes, nodePositionMap) => {
3112
2834
  };
3113
2835
  });
3114
2836
  return new Promise((resolve) => {
3115
- (0, import_core15.startTween)({
2837
+ (0, import_core16.startTween)({
3116
2838
  from: { d: 0 },
3117
2839
  to: { d: 100 },
3118
2840
  duration: 300,
3119
2841
  onUpdate: (v) => {
3120
2842
  nodes.forEach((node) => {
3121
- const transform = node.getData(import_core15.TransformData);
2843
+ const transform = node.getData(import_core16.TransformData);
3122
2844
  const deltaX = (nodePositionMap[node.id].x - transform.position.x) * v.d / 100;
3123
2845
  const deltaY = (nodePositionMap[node.id].y - transform.bounds.height / 2 - transform.position.y) * v.d / 100;
3124
2846
  if (node.collapsedChildren?.length > 0) {
@@ -3145,12 +2867,12 @@ var layoutToPositions = async (nodes, nodePositionMap) => {
3145
2867
  // src/service/workflow-reset-layout-service.ts
3146
2868
  var WorkflowResetLayoutService = class {
3147
2869
  constructor() {
3148
- this._resetLayoutEmitter = new import_utils18.Emitter();
2870
+ this._resetLayoutEmitter = new import_utils17.Emitter();
3149
2871
  /**
3150
2872
  * reset layout事件
3151
2873
  */
3152
2874
  this.onResetLayout = this._resetLayoutEmitter.event;
3153
- this._toDispose = new import_utils18.DisposableCollection();
2875
+ this._toDispose = new import_utils17.DisposableCollection();
3154
2876
  }
3155
2877
  init() {
3156
2878
  this._toDispose.push(this._resetLayoutEmitter);
@@ -3187,13 +2909,13 @@ var WorkflowResetLayoutService = class {
3187
2909
  }
3188
2910
  };
3189
2911
  __decorateClass([
3190
- (0, import_inversify7.inject)(import_core16.PlaygroundConfigEntity)
2912
+ (0, import_inversify7.inject)(import_core17.PlaygroundConfigEntity)
3191
2913
  ], WorkflowResetLayoutService.prototype, "_config", 2);
3192
2914
  __decorateClass([
3193
2915
  (0, import_inversify7.inject)(WorkflowDocument)
3194
2916
  ], WorkflowResetLayoutService.prototype, "_document", 2);
3195
2917
  __decorateClass([
3196
- (0, import_inversify7.inject)(import_core17.EntityManager)
2918
+ (0, import_inversify7.inject)(import_core18.EntityManager)
3197
2919
  ], WorkflowResetLayoutService.prototype, "_entityManager", 2);
3198
2920
  __decorateClass([
3199
2921
  (0, import_inversify7.postConstruct)()
@@ -3204,10 +2926,10 @@ WorkflowResetLayoutService = __decorateClass([
3204
2926
 
3205
2927
  // src/hooks/use-playground-readonly-state.ts
3206
2928
  var import_react = require("react");
3207
- var import_core18 = require("@flowgram.ai/core");
2929
+ var import_core19 = require("@flowgram.ai/core");
3208
2930
  function usePlaygroundReadonlyState(listenChange) {
3209
- const playground = (0, import_core18.usePlayground)();
3210
- const refresh = (0, import_core18.useRefresh)();
2931
+ const playground = (0, import_core19.usePlayground)();
2932
+ const refresh = (0, import_core19.useRefresh)();
3211
2933
  (0, import_react.useEffect)(() => {
3212
2934
  let dispose = void 0;
3213
2935
  if (listenChange) {
@@ -3223,12 +2945,12 @@ function checkTargetDraggable(el) {
3223
2945
  return el && el.tagName !== "INPUT" && el.tagName !== "TEXTAREA" && !el.closest(".flow-canvas-not-draggable");
3224
2946
  }
3225
2947
  function useNodeRender(nodeFromProps) {
3226
- const node = nodeFromProps || (0, import_react2.useContext)(import_core19.PlaygroundEntityContext);
2948
+ const node = nodeFromProps || (0, import_react2.useContext)(import_core20.PlaygroundEntityContext);
3227
2949
  const renderData = node.getData(import_document10.FlowNodeRenderData);
3228
2950
  const portsData = node.getData(WorkflowNodePortsData);
3229
2951
  const readonly = usePlaygroundReadonlyState();
3230
- const dragService = (0, import_core19.useService)(WorkflowDragService);
3231
- const selectionService = (0, import_core19.useService)(WorkflowSelectService);
2952
+ const dragService = (0, import_core20.useService)(WorkflowDragService);
2953
+ const selectionService = (0, import_core20.useService)(WorkflowSelectService);
3232
2954
  const isDragging = (0, import_react2.useRef)(false);
3233
2955
  const nodeRef = (0, import_react2.useRef)(null);
3234
2956
  const [linkingNodeId, setLinkingNodeId] = (0, import_react2.useState)("");
@@ -3279,7 +3001,7 @@ function useNodeRender(nodeFromProps) {
3279
3001
  [node]
3280
3002
  );
3281
3003
  const deleteNode = (0, import_react2.useCallback)(() => node.dispose(), [node]);
3282
- (0, import_core19.useListenEvents)(selectionService.onSelectionChanged, portsData.onDataChange);
3004
+ (0, import_core20.useListenEvents)(selectionService.onSelectionChanged, portsData.onDataChange);
3283
3005
  const isFirefox = navigator?.userAgent?.includes?.("Firefox");
3284
3006
  const onFocus = (0, import_react2.useCallback)(() => {
3285
3007
  if (isFirefox) {
@@ -3337,23 +3059,23 @@ function useNodeRender(nodeFromProps) {
3337
3059
 
3338
3060
  // src/hooks/use-current-dom-node.ts
3339
3061
  var import_document11 = require("@flowgram.ai/document");
3340
- var import_core20 = require("@flowgram.ai/core");
3062
+ var import_core21 = require("@flowgram.ai/core");
3341
3063
  function useCurrentDomNode() {
3342
- const entity = (0, import_core20.useEntityFromContext)();
3064
+ const entity = (0, import_core21.useEntityFromContext)();
3343
3065
  const renderData = entity.getData(import_document11.FlowNodeRenderData);
3344
3066
  return renderData.node;
3345
3067
  }
3346
3068
 
3347
3069
  // src/hooks/use-current-entity.ts
3348
- var import_core21 = require("@flowgram.ai/core");
3070
+ var import_core22 = require("@flowgram.ai/core");
3349
3071
  function useCurrentEntity() {
3350
- return (0, import_core21.useEntityFromContext)();
3072
+ return (0, import_core22.useEntityFromContext)();
3351
3073
  }
3352
3074
 
3353
3075
  // src/hooks/use-workflow-document.ts
3354
- var import_core22 = require("@flowgram.ai/core");
3076
+ var import_core23 = require("@flowgram.ai/core");
3355
3077
  function useWorkflowDocument() {
3356
- return (0, import_core22.useService)(WorkflowDocument);
3078
+ return (0, import_core23.useService)(WorkflowDocument);
3357
3079
  }
3358
3080
 
3359
3081
  // src/constants.ts
@@ -3371,7 +3093,7 @@ var InteractiveType = /* @__PURE__ */ ((InteractiveType2) => {
3371
3093
  // src/workflow-document-container-module.ts
3372
3094
  var import_inversify9 = require("inversify");
3373
3095
  var import_document13 = require("@flowgram.ai/document");
3374
- var import_utils20 = require("@flowgram.ai/utils");
3096
+ var import_utils19 = require("@flowgram.ai/utils");
3375
3097
 
3376
3098
  // src/workflow-document-contribution.ts
3377
3099
  var import_inversify8 = require("inversify");
@@ -3414,7 +3136,7 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3414
3136
  bind(WorkflowHoverService).toSelf().inSingletonScope();
3415
3137
  bind(WorkflowResetLayoutService).toSelf().inSingletonScope();
3416
3138
  bind(URLParams).toDynamicValue(() => getUrlParams()).inSingletonScope();
3417
- (0, import_utils20.bindContributions)(bind, WorkflowDocumentContribution, [import_document13.FlowDocumentContribution]);
3139
+ (0, import_utils19.bindContributions)(bind, WorkflowDocumentContribution, [import_document13.FlowDocumentContribution]);
3418
3140
  bind(WorkflowDocumentOptions).toConstantValue({
3419
3141
  ...WorkflowDocumentOptionsDefault
3420
3142
  });
@@ -3422,11 +3144,84 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3422
3144
  bind(WorkflowDocumentProvider).toDynamicValue((ctx) => () => ctx.container.get(WorkflowDocument)).inSingletonScope();
3423
3145
  }
3424
3146
  );
3147
+
3148
+ // src/utils/simple-line.ts
3149
+ var import_utils20 = require("@flowgram.ai/utils");
3150
+ var LINE_PADDING = 12;
3151
+ var WorkflowSimpleLineContribution = class {
3152
+ constructor(entity) {
3153
+ this.entity = entity;
3154
+ }
3155
+ get path() {
3156
+ return this.data?.path ?? "";
3157
+ }
3158
+ calcDistance(pos) {
3159
+ if (!this.data) {
3160
+ return Number.MAX_SAFE_INTEGER;
3161
+ }
3162
+ const [start, end] = this.data.points;
3163
+ return import_utils20.Point.getDistance(pos, this.projectPointOnLine(pos, start, end));
3164
+ }
3165
+ get bounds() {
3166
+ if (!this.data) {
3167
+ return new import_utils20.Rectangle();
3168
+ }
3169
+ return this.data.bbox;
3170
+ }
3171
+ update(params) {
3172
+ const { fromPos, toPos } = params;
3173
+ const { vertical } = this.entity;
3174
+ const sourceOffset = {
3175
+ x: vertical ? 0 : POINT_RADIUS,
3176
+ y: vertical ? POINT_RADIUS : 0
3177
+ };
3178
+ const targetOffset = {
3179
+ x: vertical ? 0 : -POINT_RADIUS,
3180
+ y: vertical ? -POINT_RADIUS : 0
3181
+ };
3182
+ const points = [
3183
+ {
3184
+ x: fromPos.x + sourceOffset.x,
3185
+ y: fromPos.y + sourceOffset.y
3186
+ },
3187
+ {
3188
+ x: toPos.x + targetOffset.x,
3189
+ y: toPos.y + targetOffset.y
3190
+ }
3191
+ ];
3192
+ const bbox = import_utils20.Rectangle.createRectangleWithTwoPoints(points[0], points[1]);
3193
+ const adjustedPoints = points.map((p) => ({
3194
+ x: p.x - bbox.x + LINE_PADDING,
3195
+ y: p.y - bbox.y + LINE_PADDING
3196
+ }));
3197
+ const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;
3198
+ this.data = {
3199
+ points,
3200
+ path,
3201
+ bbox
3202
+ };
3203
+ }
3204
+ projectPointOnLine(point, lineStart, lineEnd) {
3205
+ const dx = lineEnd.x - lineStart.x;
3206
+ const dy = lineEnd.y - lineStart.y;
3207
+ if (dx === 0) {
3208
+ return { x: lineStart.x, y: point.y };
3209
+ }
3210
+ if (dy === 0) {
3211
+ return { x: point.x, y: lineStart.y };
3212
+ }
3213
+ const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);
3214
+ const clampedT = Math.max(0, Math.min(1, t));
3215
+ return {
3216
+ x: lineStart.x + clampedT * dx,
3217
+ y: lineStart.y + clampedT * dy
3218
+ };
3219
+ }
3220
+ };
3221
+ WorkflowSimpleLineContribution.type = "WorkflowSimpleLineContribution";
3425
3222
  // Annotate the CommonJS export names for ESM import in node:
3426
3223
  0 && (module.exports = {
3427
- BezierControlType,
3428
3224
  EditorCursorState,
3429
- FoldLine,
3430
3225
  InteractiveType,
3431
3226
  LINE_HOVER_DISTANCE,
3432
3227
  LineColors,
@@ -3445,6 +3240,7 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3445
3240
  WorkflowDragService,
3446
3241
  WorkflowHoverService,
3447
3242
  WorkflowLineEntity,
3243
+ WorkflowLineRenderData,
3448
3244
  WorkflowLinesManager,
3449
3245
  WorkflowNodeEntity,
3450
3246
  WorkflowNodeLinesData,
@@ -3452,6 +3248,7 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3452
3248
  WorkflowPortEntity,
3453
3249
  WorkflowResetLayoutService,
3454
3250
  WorkflowSelectService,
3251
+ WorkflowSimpleLineContribution,
3455
3252
  bindConfigEntity,
3456
3253
  compose,
3457
3254
  composeAsync,
@@ -3459,8 +3256,6 @@ var WorkflowDocumentContainerModule = new import_inversify9.ContainerModule(
3459
3256
  domReactToBounds,
3460
3257
  fitView,
3461
3258
  getAntiOverlapPosition,
3462
- getBezierHorizontalControlPoints,
3463
- getBezierVerticalControlPoints,
3464
3259
  getPortEntityId,
3465
3260
  nanoid,
3466
3261
  useConfigEntity,