@flowgram.ai/free-layout-core 0.1.0-alpha.35 → 0.1.0-alpha.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +472 -62
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +462 -52
- package/dist/index.js.map +1 -1
- package/dist/typings/index.d.mts +1 -1
- package/dist/typings/index.d.ts +1 -1
- package/dist/typings/workflow-drag.d.mts +1 -1
- package/dist/typings/workflow-drag.d.ts +1 -1
- package/dist/typings/workflow-json.d.mts +1 -1
- package/dist/typings/workflow-json.d.ts +1 -1
- package/dist/typings/workflow-line.d.mts +1 -1
- package/dist/typings/workflow-line.d.ts +1 -1
- package/dist/typings/workflow-node.d.mts +1 -1
- package/dist/typings/workflow-node.d.ts +1 -1
- package/dist/typings/workflow-operation.d.mts +1 -1
- package/dist/typings/workflow-operation.d.ts +1 -1
- package/dist/typings/workflow-registry.d.mts +1 -1
- package/dist/typings/workflow-registry.d.ts +1 -1
- package/dist/typings/workflow-sub-canvas.d.mts +1 -1
- package/dist/typings/workflow-sub-canvas.d.ts +1 -1
- package/dist/{workflow-node-entity-C6bFzfXc.d.mts → workflow-node-entity-BQBXdOoa.d.mts} +46 -2
- package/dist/{workflow-node-entity-03Q7Fvv6.d.ts → workflow-node-entity-Da9FrkWn.d.ts} +46 -2
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -365,7 +365,14 @@ var WorkflowPortEntity = class extends import_core4.Entity {
|
|
|
365
365
|
);
|
|
366
366
|
}
|
|
367
367
|
isHovered(x, y) {
|
|
368
|
-
|
|
368
|
+
const { point } = this;
|
|
369
|
+
const size = this._size || { width: PORT_SIZE, height: PORT_SIZE };
|
|
370
|
+
const halfWidth = size.width / 2;
|
|
371
|
+
const halfHeight = size.height / 2;
|
|
372
|
+
if (size.width <= 0 || size.height <= 0) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
return x >= point.x - halfWidth && x <= point.x + halfWidth && y >= point.y - halfHeight && y <= point.y + halfHeight;
|
|
369
376
|
}
|
|
370
377
|
/**
|
|
371
378
|
* 相对节点左上角的位置
|
|
@@ -466,6 +473,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
466
473
|
this._staticPorts = [];
|
|
467
474
|
/** 存储 port 实体的 id,用于判断 port 是否存在 */
|
|
468
475
|
this._portIDSet = /* @__PURE__ */ new Set();
|
|
476
|
+
this._portDisposeIDSet = /* @__PURE__ */ new Set();
|
|
469
477
|
this.entity = entity;
|
|
470
478
|
const meta = entity.getNodeMeta();
|
|
471
479
|
const defaultPorts = meta.useDynamicPort ? [] : [{ type: "input" }, { type: "output" }];
|
|
@@ -552,6 +560,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
552
560
|
});
|
|
553
561
|
ports.forEach((port) => this.updatePortEntity(port));
|
|
554
562
|
this._prePorts = ports;
|
|
563
|
+
this.clearPortsCache();
|
|
555
564
|
this.fireChange();
|
|
556
565
|
}
|
|
557
566
|
this.allPorts.forEach((port) => {
|
|
@@ -564,19 +573,28 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
564
573
|
* 获取所有 port entities
|
|
565
574
|
*/
|
|
566
575
|
get allPorts() {
|
|
567
|
-
|
|
576
|
+
if (!this._allPortsCache) {
|
|
577
|
+
this._allPortsCache = Array.from(this._portIDSet).map((portId) => this.getPortEntity(portId)).filter(Boolean);
|
|
578
|
+
}
|
|
579
|
+
return this._allPortsCache;
|
|
568
580
|
}
|
|
569
581
|
/**
|
|
570
582
|
* 获取输入点位
|
|
571
583
|
*/
|
|
572
584
|
get inputPorts() {
|
|
573
|
-
|
|
585
|
+
if (!this._inputPortsCache) {
|
|
586
|
+
this._inputPortsCache = this.allPorts.filter((port) => port.portType === "input");
|
|
587
|
+
}
|
|
588
|
+
return this._inputPortsCache;
|
|
574
589
|
}
|
|
575
590
|
/**
|
|
576
591
|
* 获取输出点位
|
|
577
592
|
*/
|
|
578
593
|
get outputPorts() {
|
|
579
|
-
|
|
594
|
+
if (!this._outputPortsCache) {
|
|
595
|
+
this._outputPortsCache = this.allPorts.filter((port) => port.portType === "output");
|
|
596
|
+
}
|
|
597
|
+
return this._outputPortsCache;
|
|
580
598
|
}
|
|
581
599
|
/**
|
|
582
600
|
* 获取输入点位置
|
|
@@ -588,7 +606,7 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
588
606
|
* 获取输出点位置
|
|
589
607
|
*/
|
|
590
608
|
get outputPoints() {
|
|
591
|
-
return this.
|
|
609
|
+
return this.outputPorts.map((port) => port.point);
|
|
592
610
|
}
|
|
593
611
|
/**
|
|
594
612
|
* 根据 key 获取 输入点位置
|
|
@@ -617,6 +635,11 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
617
635
|
getPortId(portType, portKey = "") {
|
|
618
636
|
return getPortEntityId(this.entity, portType, portKey);
|
|
619
637
|
}
|
|
638
|
+
clearPortsCache() {
|
|
639
|
+
this._allPortsCache = void 0;
|
|
640
|
+
this._inputPortsCache = void 0;
|
|
641
|
+
this._outputPortsCache = void 0;
|
|
642
|
+
}
|
|
620
643
|
/**
|
|
621
644
|
* 创建 port 实体
|
|
622
645
|
*/
|
|
@@ -630,10 +653,18 @@ var WorkflowNodePortsData = class extends import_core5.EntityData {
|
|
|
630
653
|
...portInfo
|
|
631
654
|
});
|
|
632
655
|
}
|
|
633
|
-
|
|
634
|
-
this.
|
|
635
|
-
|
|
636
|
-
|
|
656
|
+
if (!this._portDisposeIDSet.has(id)) {
|
|
657
|
+
this._portDisposeIDSet.add(id);
|
|
658
|
+
portEntity.onDispose(() => {
|
|
659
|
+
this._portIDSet.delete(id);
|
|
660
|
+
this._portDisposeIDSet.delete(id);
|
|
661
|
+
this.clearPortsCache();
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
if (!this._portIDSet.has(id)) {
|
|
665
|
+
this._portIDSet.add(id);
|
|
666
|
+
this.clearPortsCache();
|
|
667
|
+
}
|
|
637
668
|
return portEntity;
|
|
638
669
|
}
|
|
639
670
|
/**
|
|
@@ -1491,7 +1522,6 @@ var import_document10 = require("@flowgram.ai/document");
|
|
|
1491
1522
|
var import_core15 = require("@flowgram.ai/core");
|
|
1492
1523
|
|
|
1493
1524
|
// src/workflow-lines-manager.ts
|
|
1494
|
-
var import_lodash_es3 = require("lodash-es");
|
|
1495
1525
|
var import_inversify3 = require("inversify");
|
|
1496
1526
|
var import_utils12 = require("@flowgram.ai/utils");
|
|
1497
1527
|
var import_document6 = require("@flowgram.ai/document");
|
|
@@ -1612,6 +1642,12 @@ var WorkflowDocumentOptionsDefault = {
|
|
|
1612
1642
|
};
|
|
1613
1643
|
|
|
1614
1644
|
// src/workflow-lines-manager.ts
|
|
1645
|
+
var NODE_HIT_CELL_SIZE = 512;
|
|
1646
|
+
var LINE_HIT_CELL_SIZE = 512;
|
|
1647
|
+
var PORT_NODE_BOUNDS_PADDING = 96;
|
|
1648
|
+
var NODE_INDEX_MIN_SIZE = 128;
|
|
1649
|
+
var LINE_INDEX_MIN_SIZE = 128;
|
|
1650
|
+
var MAX_SPATIAL_CELLS_PER_ITEM = 64;
|
|
1615
1651
|
var WorkflowLinesManager = class {
|
|
1616
1652
|
constructor() {
|
|
1617
1653
|
this.toDispose = new import_utils12.DisposableCollection();
|
|
@@ -1635,11 +1671,35 @@ var WorkflowLinesManager = class {
|
|
|
1635
1671
|
this.isDrawing = false;
|
|
1636
1672
|
}
|
|
1637
1673
|
init(doc) {
|
|
1674
|
+
if (this.document === doc) {
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1638
1677
|
this.document = doc;
|
|
1678
|
+
this.toDispose.pushAll([
|
|
1679
|
+
this.entityManager.onEntityChange((entityType) => {
|
|
1680
|
+
if (entityType === WorkflowNodeEntity.type) {
|
|
1681
|
+
this.invalidateNodeHitCaches();
|
|
1682
|
+
}
|
|
1683
|
+
if (entityType === WorkflowLineEntity.type || entityType === WorkflowPortEntity.type) {
|
|
1684
|
+
this.invalidateLineHitCache();
|
|
1685
|
+
this.outsidePortNodesCache = void 0;
|
|
1686
|
+
}
|
|
1687
|
+
}),
|
|
1688
|
+
this.entityManager.onEntityDataChange(({ entityDataType }) => {
|
|
1689
|
+
if (entityDataType === import_document6.FlowNodeTransformData.type) {
|
|
1690
|
+
this.invalidateSpatialHitCaches();
|
|
1691
|
+
}
|
|
1692
|
+
})
|
|
1693
|
+
]);
|
|
1639
1694
|
}
|
|
1640
1695
|
forceUpdate() {
|
|
1641
1696
|
this.onForceUpdateEmitter.fire();
|
|
1642
1697
|
}
|
|
1698
|
+
invalidateSortedNodesCache() {
|
|
1699
|
+
this.sortedNodesCache = void 0;
|
|
1700
|
+
this.sortedNodesCacheVersion = void 0;
|
|
1701
|
+
this.invalidateNodeHitCaches();
|
|
1702
|
+
}
|
|
1643
1703
|
get lineType() {
|
|
1644
1704
|
return this._lineType;
|
|
1645
1705
|
}
|
|
@@ -1668,6 +1728,7 @@ var WorkflowLinesManager = class {
|
|
|
1668
1728
|
}
|
|
1669
1729
|
if (newType !== this._lineType) {
|
|
1670
1730
|
this._lineType = newType;
|
|
1731
|
+
this.lineSpatialCache = void 0;
|
|
1671
1732
|
this.getAllLines().forEach((line) => {
|
|
1672
1733
|
line.getData(WorkflowLineRenderData).update();
|
|
1673
1734
|
});
|
|
@@ -1826,17 +1887,26 @@ var WorkflowLinesManager = class {
|
|
|
1826
1887
|
*/
|
|
1827
1888
|
getCloseInLineFromMousePos(mousePos, minDistance = LINE_HOVER_DISTANCE) {
|
|
1828
1889
|
let targetLine, targetLineDist;
|
|
1829
|
-
this.
|
|
1890
|
+
const lines = this.getLineHitCandidates(mousePos, minDistance);
|
|
1891
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1892
|
+
const line = lines[i];
|
|
1893
|
+
if (!this.isPointInBounds(mousePos, line.bounds, minDistance)) {
|
|
1894
|
+
continue;
|
|
1895
|
+
}
|
|
1830
1896
|
const dist = line.getHoverDist(mousePos);
|
|
1831
|
-
if (dist <= minDistance && (
|
|
1897
|
+
if (dist <= minDistance && (targetLineDist === void 0 || targetLineDist >= dist)) {
|
|
1832
1898
|
targetLineDist = dist;
|
|
1833
1899
|
targetLine = line;
|
|
1834
1900
|
}
|
|
1835
|
-
}
|
|
1901
|
+
}
|
|
1836
1902
|
return targetLine;
|
|
1837
1903
|
}
|
|
1838
1904
|
dispose() {
|
|
1839
1905
|
this.portLineMap.clear();
|
|
1906
|
+
this.sortedNodeSpatialCache = void 0;
|
|
1907
|
+
this.hoverNodeSpatialCache = void 0;
|
|
1908
|
+
this.lineSpatialCache = void 0;
|
|
1909
|
+
this.outsidePortNodesCache = void 0;
|
|
1840
1910
|
this.toDispose.dispose();
|
|
1841
1911
|
}
|
|
1842
1912
|
get disposed() {
|
|
@@ -1951,39 +2021,45 @@ var WorkflowLinesManager = class {
|
|
|
1951
2021
|
* @param pos
|
|
1952
2022
|
*/
|
|
1953
2023
|
getPortFromMousePos(pos, portType) {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2024
|
+
return this.getHoveredPortFromSortedNodes(pos, this.getSortedNodes(), portType);
|
|
2025
|
+
}
|
|
2026
|
+
getPortsFromMousePos(pos) {
|
|
2027
|
+
return this.getHoveredPortsFromSortedNodes(pos, this.getSortedNodes(), void 0, {
|
|
2028
|
+
collectBoth: true
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
getNodeAndPortFromMousePos(pos, portType) {
|
|
2032
|
+
const sortedNodes = this.getSortedNodes();
|
|
2033
|
+
const nodeHitInfo = this.getNodeHitInfoFromSortedNodes(
|
|
2034
|
+
pos,
|
|
2035
|
+
sortedNodes,
|
|
2036
|
+
this.selectService.selection
|
|
2037
|
+
);
|
|
2038
|
+
const ports = this.getHoveredPortsFromSortedNodes(pos, sortedNodes, portType, {
|
|
2039
|
+
topCoverNode: nodeHitInfo.topCoverNode
|
|
2040
|
+
});
|
|
2041
|
+
return {
|
|
2042
|
+
node: nodeHitInfo.topNode,
|
|
2043
|
+
port: ports.port
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
getHoverNodeFromMousePos(pos) {
|
|
2047
|
+
const nodes = this.getHoverNodes();
|
|
2048
|
+
const candidates = this.getHoverNodeHitCandidates(pos, nodes);
|
|
2049
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
2050
|
+
const node = candidates[i];
|
|
2051
|
+
const { bounds } = node.getData(import_document6.FlowNodeTransformData);
|
|
2052
|
+
if (this.isPointInBounds(pos, bounds)) {
|
|
2053
|
+
return node;
|
|
1967
2054
|
}
|
|
1968
2055
|
}
|
|
1969
|
-
return targetPort;
|
|
1970
2056
|
}
|
|
1971
2057
|
/**
|
|
1972
2058
|
* 根据鼠标位置找到 node
|
|
1973
2059
|
* @param pos - 鼠标位置
|
|
1974
2060
|
*/
|
|
1975
2061
|
getNodeFromMousePos(pos) {
|
|
1976
|
-
|
|
1977
|
-
const containNodes = this.getContainNodesFromMousePos(pos);
|
|
1978
|
-
if (selection?.length) {
|
|
1979
|
-
const filteredNodes = containNodes.filter(
|
|
1980
|
-
(node) => selection.some((_node) => node.id === _node.id)
|
|
1981
|
-
);
|
|
1982
|
-
if (filteredNodes?.length) {
|
|
1983
|
-
return (0, import_lodash_es3.last)(filteredNodes);
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
return (0, import_lodash_es3.last)(containNodes);
|
|
2062
|
+
return this.getTopNodeFromSortedNodes(pos, this.getSortedNodes(), this.selectService.selection);
|
|
1987
2063
|
}
|
|
1988
2064
|
registerContribution(factory) {
|
|
1989
2065
|
this.contributionFactories.push(factory);
|
|
@@ -1993,19 +2069,352 @@ var WorkflowLinesManager = class {
|
|
|
1993
2069
|
line.addData(WorkflowLineRenderData);
|
|
1994
2070
|
}
|
|
1995
2071
|
getSortedNodes() {
|
|
1996
|
-
|
|
2072
|
+
const nodeVersion = this.entityManager.getEntityVersion(WorkflowNodeEntity);
|
|
2073
|
+
if (this.sortedNodesCache && this.sortedNodesCacheVersion === nodeVersion) {
|
|
2074
|
+
return this.sortedNodesCache;
|
|
2075
|
+
}
|
|
2076
|
+
this.sortedNodesCache = [...this.document.getAllNodes()].sort(
|
|
2077
|
+
(a, b) => this.getNodeIndex(a) - this.getNodeIndex(b)
|
|
2078
|
+
);
|
|
2079
|
+
this.sortedNodesCacheVersion = nodeVersion;
|
|
2080
|
+
this.sortedNodeSpatialCache = void 0;
|
|
2081
|
+
this.outsidePortNodesCache = void 0;
|
|
2082
|
+
return this.sortedNodesCache;
|
|
2083
|
+
}
|
|
2084
|
+
invalidateNodeHitCaches() {
|
|
2085
|
+
this.sortedNodeSpatialCache = void 0;
|
|
2086
|
+
this.hoverNodeSpatialCache = void 0;
|
|
2087
|
+
this.outsidePortNodesCache = void 0;
|
|
2088
|
+
}
|
|
2089
|
+
invalidateLineHitCache() {
|
|
2090
|
+
this.lineSpatialCache = void 0;
|
|
2091
|
+
}
|
|
2092
|
+
invalidateSpatialHitCaches() {
|
|
2093
|
+
this.invalidateNodeHitCaches();
|
|
2094
|
+
this.invalidateLineHitCache();
|
|
2095
|
+
}
|
|
2096
|
+
getHoveredPortFromSortedNodes(pos, sortedNodes, portType) {
|
|
2097
|
+
return this.getHoveredPortsFromSortedNodes(pos, sortedNodes, portType).port;
|
|
2098
|
+
}
|
|
2099
|
+
getHoveredPortsFromSortedNodes(pos, sortedNodes, portType, options = {}) {
|
|
2100
|
+
let inputPort;
|
|
2101
|
+
let outputPort;
|
|
2102
|
+
let anyPort;
|
|
2103
|
+
const { collectBoth = false } = options;
|
|
2104
|
+
const needInput = !portType || portType === "input";
|
|
2105
|
+
const needOutput = !portType || portType === "output";
|
|
2106
|
+
const needAny = !portType && !collectBoth;
|
|
2107
|
+
const candidates = this.getSortedNodeHitCandidates(pos, sortedNodes, PORT_NODE_BOUNDS_PADDING);
|
|
2108
|
+
const checkedNodes = candidates.length === sortedNodes.length ? void 0 : new Set(candidates);
|
|
2109
|
+
for (let i = candidates.length - 1; i >= 0; i--) {
|
|
2110
|
+
const node = candidates[i];
|
|
2111
|
+
if (!this.isPointNearNodePorts(pos, node)) {
|
|
2112
|
+
continue;
|
|
2113
|
+
}
|
|
2114
|
+
const result = this.collectHoveredPorts(node.ports.allPorts, pos, {
|
|
2115
|
+
needInput,
|
|
2116
|
+
needOutput,
|
|
2117
|
+
needAny,
|
|
2118
|
+
inputPort,
|
|
2119
|
+
outputPort,
|
|
2120
|
+
anyPort
|
|
2121
|
+
});
|
|
2122
|
+
inputPort = result.inputPort;
|
|
2123
|
+
outputPort = result.outputPort;
|
|
2124
|
+
anyPort = result.anyPort;
|
|
2125
|
+
if (portType === "input" && inputPort || portType === "output" && outputPort || !portType && (collectBoth ? inputPort && outputPort : anyPort)) {
|
|
2126
|
+
break;
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
if (checkedNodes && !(portType === "input" && inputPort || portType === "output" && outputPort || !portType && (collectBoth ? inputPort && outputPort : anyPort))) {
|
|
2130
|
+
const outsidePortNodes = this.getOutsidePortNodes(sortedNodes);
|
|
2131
|
+
for (let i = outsidePortNodes.length - 1; i >= 0; i--) {
|
|
2132
|
+
const node = outsidePortNodes[i];
|
|
2133
|
+
if (checkedNodes.has(node)) {
|
|
2134
|
+
continue;
|
|
2135
|
+
}
|
|
2136
|
+
const result = this.collectHoveredPorts(node.ports.allPorts, pos, {
|
|
2137
|
+
needInput,
|
|
2138
|
+
needOutput,
|
|
2139
|
+
needAny,
|
|
2140
|
+
inputPort,
|
|
2141
|
+
outputPort,
|
|
2142
|
+
anyPort
|
|
2143
|
+
});
|
|
2144
|
+
inputPort = result.inputPort;
|
|
2145
|
+
outputPort = result.outputPort;
|
|
2146
|
+
anyPort = result.anyPort;
|
|
2147
|
+
if (portType === "input" && inputPort || portType === "output" && outputPort || !portType && (collectBoth ? inputPort && outputPort : anyPort)) {
|
|
2148
|
+
break;
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
const needCoverCheck = inputPort || outputPort || anyPort;
|
|
2153
|
+
const topCoverNode = needCoverCheck ? options.topCoverNode || this.getNodeHitInfoFromSortedNodes(pos, sortedNodes).topCoverNode : void 0;
|
|
2154
|
+
inputPort = this.filterCoveredPort(inputPort, topCoverNode);
|
|
2155
|
+
outputPort = this.filterCoveredPort(outputPort, topCoverNode);
|
|
2156
|
+
anyPort = this.filterCoveredPort(anyPort, topCoverNode);
|
|
2157
|
+
return {
|
|
2158
|
+
input: inputPort,
|
|
2159
|
+
output: outputPort,
|
|
2160
|
+
port: portType === "input" ? inputPort : portType === "output" ? outputPort : anyPort
|
|
2161
|
+
};
|
|
1997
2162
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2163
|
+
collectHoveredPorts(ports, pos, options) {
|
|
2164
|
+
let { inputPort, outputPort, anyPort } = options;
|
|
2165
|
+
for (let i = 0; i < ports.length; i++) {
|
|
2166
|
+
const port = ports[i];
|
|
2167
|
+
if ((!options.needAny || anyPort) && (!options.needInput || inputPort) && (!options.needOutput || outputPort)) {
|
|
2168
|
+
break;
|
|
2169
|
+
}
|
|
2170
|
+
if (port.isHovered(pos.x, pos.y)) {
|
|
2171
|
+
if (!anyPort && options.needAny) {
|
|
2172
|
+
anyPort = port;
|
|
2173
|
+
}
|
|
2174
|
+
if (!inputPort && options.needInput && port.portType === "input") {
|
|
2175
|
+
inputPort = port;
|
|
2176
|
+
}
|
|
2177
|
+
if (!outputPort && options.needOutput && port.portType === "output") {
|
|
2178
|
+
outputPort = port;
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
return {
|
|
2183
|
+
inputPort,
|
|
2184
|
+
outputPort,
|
|
2185
|
+
anyPort
|
|
2186
|
+
};
|
|
2187
|
+
}
|
|
2188
|
+
filterCoveredPort(port, topCoverNode) {
|
|
2189
|
+
if (port && topCoverNode && topCoverNode !== port.node) {
|
|
2190
|
+
return void 0;
|
|
2191
|
+
}
|
|
2192
|
+
return port;
|
|
2193
|
+
}
|
|
2194
|
+
getTopNodeFromSortedNodes(pos, sortedNodes, selection) {
|
|
2195
|
+
return this.getNodeHitInfoFromSortedNodes(pos, sortedNodes, selection).topNode;
|
|
2196
|
+
}
|
|
2197
|
+
getNodeHitInfoFromSortedNodes(pos, sortedNodes, selection) {
|
|
2001
2198
|
const zoom = this.entityManager.getEntity(import_core12.PlaygroundConfigEntity)?.config?.zoom || 1;
|
|
2002
|
-
const
|
|
2199
|
+
const padding = 4 / zoom;
|
|
2200
|
+
const selectedIDs = selection?.length ? new Set(selection.map((node) => node.id)) : void 0;
|
|
2201
|
+
const candidates = this.getSortedNodeHitCandidates(pos, sortedNodes, padding);
|
|
2202
|
+
let topCoverNode;
|
|
2203
|
+
for (let i = candidates.length - 1; i >= 0; i--) {
|
|
2204
|
+
const node = candidates[i];
|
|
2003
2205
|
const { bounds } = node.getData(import_document6.FlowNodeTransformData);
|
|
2004
|
-
if (
|
|
2005
|
-
|
|
2206
|
+
if (!this.isPointInBounds(pos, bounds, padding)) {
|
|
2207
|
+
continue;
|
|
2006
2208
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2209
|
+
if (!topCoverNode) {
|
|
2210
|
+
topCoverNode = node;
|
|
2211
|
+
}
|
|
2212
|
+
if (!selectedIDs) {
|
|
2213
|
+
return {
|
|
2214
|
+
topCoverNode,
|
|
2215
|
+
topNode: node
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
if (selectedIDs.has(node.id)) {
|
|
2219
|
+
return {
|
|
2220
|
+
topCoverNode,
|
|
2221
|
+
topNode: node
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
return {
|
|
2226
|
+
topCoverNode,
|
|
2227
|
+
topNode: topCoverNode
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
getHoverNodeHitCandidates(pos, nodes) {
|
|
2231
|
+
if (nodes.length < NODE_INDEX_MIN_SIZE) {
|
|
2232
|
+
return nodes;
|
|
2233
|
+
}
|
|
2234
|
+
const nodeVersion = this.entityManager.getEntityVersion(WorkflowNodeEntity);
|
|
2235
|
+
const transformVersion = this.entityManager.getEntityDataVersion(import_document6.FlowNodeTransformData);
|
|
2236
|
+
const activatedID = this.selectService.activatedNode?.id;
|
|
2237
|
+
if (!this.hoverNodeSpatialCache || this.hoverNodeSpatialCache.nodeVersion !== nodeVersion || this.hoverNodeSpatialCache.transformVersion !== transformVersion || this.hoverNodeSpatialCache.activatedID !== activatedID || this.hoverNodeSpatialCache.nodes !== nodes) {
|
|
2238
|
+
this.hoverNodeSpatialCache = {
|
|
2239
|
+
nodeVersion,
|
|
2240
|
+
transformVersion,
|
|
2241
|
+
activatedID,
|
|
2242
|
+
nodes,
|
|
2243
|
+
index: this.createSpatialIndex(
|
|
2244
|
+
nodes,
|
|
2245
|
+
(node) => node.getData(import_document6.FlowNodeTransformData).bounds,
|
|
2246
|
+
NODE_HIT_CELL_SIZE
|
|
2247
|
+
)
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
2250
|
+
return this.querySpatialIndex(this.hoverNodeSpatialCache.index, pos);
|
|
2251
|
+
}
|
|
2252
|
+
getSortedNodeHitCandidates(pos, sortedNodes, padding = 0) {
|
|
2253
|
+
if (sortedNodes.length < NODE_INDEX_MIN_SIZE) {
|
|
2254
|
+
return sortedNodes;
|
|
2255
|
+
}
|
|
2256
|
+
const nodeVersion = this.entityManager.getEntityVersion(WorkflowNodeEntity);
|
|
2257
|
+
const transformVersion = this.entityManager.getEntityDataVersion(import_document6.FlowNodeTransformData);
|
|
2258
|
+
if (!this.sortedNodeSpatialCache || this.sortedNodeSpatialCache.nodeVersion !== nodeVersion || this.sortedNodeSpatialCache.transformVersion !== transformVersion || this.sortedNodeSpatialCache.nodes !== sortedNodes) {
|
|
2259
|
+
this.sortedNodeSpatialCache = {
|
|
2260
|
+
nodeVersion,
|
|
2261
|
+
transformVersion,
|
|
2262
|
+
nodes: sortedNodes,
|
|
2263
|
+
index: this.createSpatialIndex(
|
|
2264
|
+
sortedNodes,
|
|
2265
|
+
(node) => node.getData(import_document6.FlowNodeTransformData).bounds,
|
|
2266
|
+
NODE_HIT_CELL_SIZE
|
|
2267
|
+
)
|
|
2268
|
+
};
|
|
2269
|
+
}
|
|
2270
|
+
return this.querySpatialIndex(this.sortedNodeSpatialCache.index, pos, padding);
|
|
2271
|
+
}
|
|
2272
|
+
getLineHitCandidates(pos, padding) {
|
|
2273
|
+
const lines = this.getAllLines();
|
|
2274
|
+
if (lines.length < LINE_INDEX_MIN_SIZE) {
|
|
2275
|
+
return lines;
|
|
2276
|
+
}
|
|
2277
|
+
const lineVersion = this.entityManager.getEntityVersion(WorkflowLineEntity);
|
|
2278
|
+
const portVersion = this.entityManager.getEntityVersion(WorkflowPortEntity);
|
|
2279
|
+
const transformVersion = this.entityManager.getEntityDataVersion(import_document6.FlowNodeTransformData);
|
|
2280
|
+
if (!this.lineSpatialCache || this.lineSpatialCache.lineVersion !== lineVersion || this.lineSpatialCache.portVersion !== portVersion || this.lineSpatialCache.transformVersion !== transformVersion) {
|
|
2281
|
+
this.lineSpatialCache = {
|
|
2282
|
+
lineVersion,
|
|
2283
|
+
portVersion,
|
|
2284
|
+
transformVersion,
|
|
2285
|
+
index: this.createSpatialIndex(lines, (line) => line.bounds, LINE_HIT_CELL_SIZE)
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
return this.querySpatialIndex(this.lineSpatialCache.index, pos, padding);
|
|
2289
|
+
}
|
|
2290
|
+
createSpatialIndex(items, getBounds, cellSize) {
|
|
2291
|
+
const index = {
|
|
2292
|
+
cellSize,
|
|
2293
|
+
cells: /* @__PURE__ */ new Map(),
|
|
2294
|
+
overflowItems: [],
|
|
2295
|
+
order: /* @__PURE__ */ new Map()
|
|
2296
|
+
};
|
|
2297
|
+
items.forEach((item, itemIndex) => {
|
|
2298
|
+
index.order.set(item, itemIndex);
|
|
2299
|
+
const bounds = getBounds(item);
|
|
2300
|
+
if (!this.canIndexBounds(bounds)) {
|
|
2301
|
+
index.overflowItems.push(item);
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
const minCellX = this.getSpatialCell(bounds.x, cellSize);
|
|
2305
|
+
const maxCellX = this.getSpatialCell(bounds.right, cellSize);
|
|
2306
|
+
const minCellY = this.getSpatialCell(bounds.y, cellSize);
|
|
2307
|
+
const maxCellY = this.getSpatialCell(bounds.bottom, cellSize);
|
|
2308
|
+
const cellCount = (maxCellX - minCellX + 1) * (maxCellY - minCellY + 1);
|
|
2309
|
+
if (cellCount > MAX_SPATIAL_CELLS_PER_ITEM) {
|
|
2310
|
+
index.overflowItems.push(item);
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
for (let x = minCellX; x <= maxCellX; x++) {
|
|
2314
|
+
for (let y = minCellY; y <= maxCellY; y++) {
|
|
2315
|
+
const key = this.getSpatialCellKey(x, y);
|
|
2316
|
+
let cellItems = index.cells.get(key);
|
|
2317
|
+
if (!cellItems) {
|
|
2318
|
+
cellItems = [];
|
|
2319
|
+
index.cells.set(key, cellItems);
|
|
2320
|
+
}
|
|
2321
|
+
cellItems.push(item);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
});
|
|
2325
|
+
return index;
|
|
2326
|
+
}
|
|
2327
|
+
querySpatialIndex(index, pos, padding = 0) {
|
|
2328
|
+
const minCellX = this.getSpatialCell(pos.x - padding, index.cellSize);
|
|
2329
|
+
const maxCellX = this.getSpatialCell(pos.x + padding, index.cellSize);
|
|
2330
|
+
const minCellY = this.getSpatialCell(pos.y - padding, index.cellSize);
|
|
2331
|
+
const maxCellY = this.getSpatialCell(pos.y + padding, index.cellSize);
|
|
2332
|
+
const candidates = [];
|
|
2333
|
+
const candidateSet = /* @__PURE__ */ new Set();
|
|
2334
|
+
const pushCandidate = (item) => {
|
|
2335
|
+
if (candidateSet.has(item)) {
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
candidateSet.add(item);
|
|
2339
|
+
candidates.push(item);
|
|
2340
|
+
};
|
|
2341
|
+
for (let x = minCellX; x <= maxCellX; x++) {
|
|
2342
|
+
for (let y = minCellY; y <= maxCellY; y++) {
|
|
2343
|
+
const cellItems = index.cells.get(this.getSpatialCellKey(x, y));
|
|
2344
|
+
if (cellItems) {
|
|
2345
|
+
cellItems.forEach(pushCandidate);
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
index.overflowItems.forEach(pushCandidate);
|
|
2350
|
+
return candidates.sort((a, b) => (index.order.get(a) ?? 0) - (index.order.get(b) ?? 0));
|
|
2351
|
+
}
|
|
2352
|
+
getSpatialCell(value, cellSize) {
|
|
2353
|
+
return Math.floor(value / cellSize);
|
|
2354
|
+
}
|
|
2355
|
+
getSpatialCellKey(x, y) {
|
|
2356
|
+
return `${x}:${y}`;
|
|
2357
|
+
}
|
|
2358
|
+
canIndexBounds(bounds) {
|
|
2359
|
+
return Number.isFinite(bounds.x) && Number.isFinite(bounds.y) && Number.isFinite(bounds.width) && Number.isFinite(bounds.height) && bounds.width > 0 && bounds.height > 0;
|
|
2360
|
+
}
|
|
2361
|
+
isPointNearNodePorts(pos, node) {
|
|
2362
|
+
const { bounds } = node.getData(import_document6.FlowNodeTransformData);
|
|
2363
|
+
return this.isPointInBounds(pos, bounds, PORT_NODE_BOUNDS_PADDING);
|
|
2364
|
+
}
|
|
2365
|
+
hasPortOutsideNodeBounds(node) {
|
|
2366
|
+
const { bounds } = node.getData(import_document6.FlowNodeTransformData);
|
|
2367
|
+
return node.ports.allPorts.some((port) => {
|
|
2368
|
+
if (port.targetElement) {
|
|
2369
|
+
return true;
|
|
2370
|
+
}
|
|
2371
|
+
return !this.isPointInBounds(port.point, bounds, PORT_NODE_BOUNDS_PADDING);
|
|
2372
|
+
});
|
|
2373
|
+
}
|
|
2374
|
+
getOutsidePortNodes(sortedNodes) {
|
|
2375
|
+
const nodeVersion = this.entityManager.getEntityVersion(WorkflowNodeEntity);
|
|
2376
|
+
const portVersion = this.entityManager.getEntityVersion(WorkflowPortEntity);
|
|
2377
|
+
const transformVersion = this.entityManager.getEntityDataVersion(import_document6.FlowNodeTransformData);
|
|
2378
|
+
if (this.outsidePortNodesCache && this.outsidePortNodesCache.nodeVersion === nodeVersion && this.outsidePortNodesCache.portVersion === portVersion && this.outsidePortNodesCache.transformVersion === transformVersion && this.outsidePortNodesCache.sortedNodes === sortedNodes) {
|
|
2379
|
+
return this.outsidePortNodesCache.outsideNodes;
|
|
2380
|
+
}
|
|
2381
|
+
const outsideNodes = sortedNodes.filter((node) => this.hasPortOutsideNodeBounds(node));
|
|
2382
|
+
this.outsidePortNodesCache = {
|
|
2383
|
+
nodeVersion,
|
|
2384
|
+
portVersion,
|
|
2385
|
+
transformVersion,
|
|
2386
|
+
sortedNodes,
|
|
2387
|
+
outsideNodes
|
|
2388
|
+
};
|
|
2389
|
+
return outsideNodes;
|
|
2390
|
+
}
|
|
2391
|
+
getHoverNodes() {
|
|
2392
|
+
const nodeVersion = this.entityManager.getEntityVersion(WorkflowNodeEntity);
|
|
2393
|
+
const activatedID = this.selectService.activatedNode?.id;
|
|
2394
|
+
if (this.hoverNodesCache && this.hoverNodesCacheVersion === nodeVersion && this.hoverNodesCacheActivatedID === activatedID) {
|
|
2395
|
+
return this.hoverNodesCache;
|
|
2396
|
+
}
|
|
2397
|
+
const nodes = this.document.getAllNodes().filter(
|
|
2398
|
+
(node) => node.id !== "root" && node.flowNodeType !== import_document6.FlowNodeBaseType.ROOT && node.flowNodeType !== import_document6.FlowNodeBaseType.GROUP
|
|
2399
|
+
).reverse();
|
|
2400
|
+
if (activatedID) {
|
|
2401
|
+
const activatedIndex = nodes.findIndex((node) => node.id === activatedID);
|
|
2402
|
+
if (activatedIndex > 0) {
|
|
2403
|
+
const [activatedNode] = nodes.splice(activatedIndex, 1);
|
|
2404
|
+
nodes.unshift(activatedNode);
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
this.hoverNodesCache = nodes;
|
|
2408
|
+
this.hoverNodesCacheVersion = nodeVersion;
|
|
2409
|
+
this.hoverNodesCacheActivatedID = activatedID;
|
|
2410
|
+
this.hoverNodeSpatialCache = void 0;
|
|
2411
|
+
return this.hoverNodesCache;
|
|
2412
|
+
}
|
|
2413
|
+
isPointInBounds(pos, bounds, padding = 0) {
|
|
2414
|
+
if (bounds.width + padding * 2 <= 0 || bounds.height + padding * 2 <= 0) {
|
|
2415
|
+
return false;
|
|
2416
|
+
}
|
|
2417
|
+
return pos.x >= bounds.x - padding && pos.x <= bounds.right + padding && pos.y >= bounds.y - padding && pos.y <= bounds.bottom + padding;
|
|
2009
2418
|
}
|
|
2010
2419
|
getNodeIndex(node) {
|
|
2011
2420
|
const nodeRenderData = node.getData(import_document6.FlowNodeRenderData);
|
|
@@ -3407,15 +3816,15 @@ var WorkflowDragService = class {
|
|
|
3407
3816
|
}
|
|
3408
3817
|
updateDrawingLine(isDrawingTo, line, dragPos, originLine) {
|
|
3409
3818
|
let hasError = false;
|
|
3410
|
-
const mouseNode = this.linesManager.getNodeFromMousePos(dragPos);
|
|
3411
3819
|
let toNode;
|
|
3412
3820
|
let toPort;
|
|
3413
3821
|
let fromPort;
|
|
3414
3822
|
let fromNode;
|
|
3415
3823
|
if (isDrawingTo) {
|
|
3824
|
+
const mouseHitInfo = this.linesManager.getNodeAndPortFromMousePos(dragPos, "input");
|
|
3416
3825
|
fromPort = line.fromPort;
|
|
3417
|
-
toNode =
|
|
3418
|
-
toPort =
|
|
3826
|
+
toNode = mouseHitInfo.node;
|
|
3827
|
+
toPort = mouseHitInfo.port;
|
|
3419
3828
|
if (toNode && this.canBuildContainerLine(toNode, dragPos)) {
|
|
3420
3829
|
toPort = this.getNearestPort(toNode, dragPos, "input");
|
|
3421
3830
|
hasError = this.checkDraggingPort(isDrawingTo, line, toNode, toPort, originLine).hasError;
|
|
@@ -3442,9 +3851,10 @@ var WorkflowDragService = class {
|
|
|
3442
3851
|
};
|
|
3443
3852
|
}
|
|
3444
3853
|
} else {
|
|
3854
|
+
const mouseHitInfo = this.linesManager.getNodeAndPortFromMousePos(dragPos, "output");
|
|
3445
3855
|
toPort = line.toPort;
|
|
3446
|
-
fromNode =
|
|
3447
|
-
fromPort =
|
|
3856
|
+
fromNode = mouseHitInfo.node;
|
|
3857
|
+
fromPort = mouseHitInfo.port;
|
|
3448
3858
|
if (fromNode && this.canBuildContainerLine(fromNode, dragPos)) {
|
|
3449
3859
|
fromPort = this.getNearestPort(fromNode, dragPos, "output");
|
|
3450
3860
|
hasError = this.checkDraggingPort(
|