@rxflow/base 0.0.2-alpha.7 → 0.0.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAgB,YAAY,EAA6D,MAAM,eAAe,CAAC;AAItH,OAAO,KAAK,EAAE,EAAO,SAAS,EAAC,MAAM,OAAO,CAAC;AAY7C,iBAAS,QAAQ,CACf,EACE,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAuB,EACvB,cAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,EACxB,WAAwB,EACxB,YAAY,EAAE,SAAiC,EAC/C,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,EAAE,YAAY,GAAG;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjD,2CAuKF;;AAED,wBAA8B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAgB,YAAY,EAA6D,MAAM,eAAe,CAAC;AAItH,OAAO,KAAK,EAAE,EAAO,SAAS,EAAU,MAAM,OAAO,CAAC;AAYtD,iBAAS,QAAQ,CACf,EACE,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAuB,EACvB,cAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,EACxB,WAAwB,EACxB,YAAY,EAAE,SAAiC,EAC/C,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,EAAE,YAAY,GAAG;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjD,2CAsMF;;AAED,wBAA8B"}
@@ -57,6 +57,36 @@ function Controls({
57
57
  const [isFullscreen, {
58
58
  toggleFullscreen
59
59
  }] = (0, _ahooks.useFullscreen)(containerRef);
60
+ const tooltipPlacement = (0, _react2.useMemo)(() => {
61
+ switch (position) {
62
+ case 'top-left':
63
+ case 'center-left':
64
+ case 'top-center':
65
+ if (orientation === 'horizontal') {
66
+ return 'bottom';
67
+ }
68
+ return 'right';
69
+ case 'top-right':
70
+ case 'center-right':
71
+ if (orientation === 'horizontal') {
72
+ return 'bottom';
73
+ }
74
+ return 'left';
75
+ case 'bottom-left':
76
+ case 'bottom-center':
77
+ if (orientation === 'horizontal') {
78
+ return 'top';
79
+ }
80
+ return 'right';
81
+ case 'bottom-right':
82
+ if (orientation === 'horizontal') {
83
+ return 'top';
84
+ }
85
+ return 'left';
86
+ default:
87
+ return 'top';
88
+ }
89
+ }, []);
60
90
  const store = (0, _react.useStoreApi)();
61
91
  const {
62
92
  isInteractive,
@@ -104,7 +134,7 @@ function Controls({
104
134
  children: [showZoom && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
105
135
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
106
136
  title: '放大',
107
- placement: 'right',
137
+ placement: tooltipPlacement,
108
138
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
109
139
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
110
140
  onClick: onZoomInHandler,
@@ -117,7 +147,7 @@ function Controls({
117
147
  })
118
148
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
119
149
  title: '缩小',
120
- placement: 'right',
150
+ placement: tooltipPlacement,
121
151
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
122
152
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
123
153
  onClick: onZoomOutHandler,
@@ -131,7 +161,7 @@ function Controls({
131
161
  })]
132
162
  }), showFitView && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
133
163
  title: '自适应视图',
134
- placement: 'right',
164
+ placement: tooltipPlacement,
135
165
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
136
166
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
137
167
  className: "react-flow__controls-fitview",
@@ -143,7 +173,7 @@ function Controls({
143
173
  })
144
174
  }), showFullscreen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
145
175
  title: isFullscreen ? '取消全屏' : '全屏',
146
- placement: 'right',
176
+ placement: tooltipPlacement,
147
177
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
148
178
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
149
179
  className: "react-flow__controls-fullscreen",
@@ -155,7 +185,7 @@ function Controls({
155
185
  })
156
186
  }), showMiniMap && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
157
187
  title: minimapVisible ? '关闭缩略图' : '开启缩略图',
158
- placement: 'right',
188
+ placement: tooltipPlacement,
159
189
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
160
190
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
161
191
  className: "react-flow__controls-interactive",
@@ -167,7 +197,7 @@ function Controls({
167
197
  })
168
198
  }), showInteractive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
169
199
  title: isInteractive ? '解锁' : '锁定',
170
- placement: 'right',
200
+ placement: tooltipPlacement,
171
201
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
172
202
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
173
203
  className: "react-flow__controls-interactive",
@@ -179,7 +209,7 @@ function Controls({
179
209
  })
180
210
  }), showForceLayout && /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Tooltip, {
181
211
  title: '美化布局',
182
- placement: 'right',
212
+ placement: tooltipPlacement,
183
213
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
184
214
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.ControlButton, {
185
215
  className: "react-flow__controls-layout",
@@ -2,7 +2,7 @@
2
2
  * @author: yanxianliang
3
3
  * @date: 2025-10-20 09:19
4
4
  * @modified:2025/10/20 09:19 by yanxianliang
5
- * @desc: 智能边
5
+ * @desc: 智能边 - 默认使用 Web Worker 计算
6
6
  *
7
7
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,EAAc,MAAM,eAAe,CAAC;AACpE,OAAO,EAAC,aAAa,EAAO,MAAM,OAAO,CAAC;AAG1C,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CAyCjD,CAAA"}
1
+ {"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,EAAc,MAAM,eAAe,CAAC;AACpE,OAAO,EAAC,aAAa,EAAoC,MAAM,OAAO,CAAC;AAgGvE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CA0IjD,CAAA"}
@@ -7,17 +7,96 @@ exports.ManhattanEdge = void 0;
7
7
  var _react = require("@xyflow/react");
8
8
  var _react2 = require("react");
9
9
  var _manhattan = require("@rxflow/manhattan");
10
+ var _comlink = require("comlink");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  /**
12
13
  * @author: yanxianliang
13
14
  * @date: 2025-10-20 09:19
14
15
  * @modified:2025/10/20 09:19 by yanxianliang
15
- * @desc: 智能边
16
+ * @desc: 智能边 - 默认使用 Web Worker 计算
16
17
  *
17
18
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
18
19
  */
19
20
 
21
+ // 全局 Worker 实例(单例)
22
+ let workerInstance = null;
23
+ let workerApi = null;
24
+
25
+ // 获取或创建 Worker
26
+ function getWorker() {
27
+ if (typeof window === 'undefined') return null; // SSR 环境
28
+
29
+ if (!workerInstance || !workerApi) {
30
+ try {
31
+ workerInstance = new Worker(new URL('../workers/manhattan.worker.ts', import.meta.url), {
32
+ type: 'module'
33
+ });
34
+ workerApi = (0, _comlink.wrap)(workerInstance);
35
+ } catch (error) {
36
+ console.warn('[ManhattanEdge] Worker initialization failed, using main thread:', error);
37
+ return null;
38
+ }
39
+ }
40
+ return workerApi;
41
+ }
42
+
43
+ // 全局性能统计
44
+ const perfStats = {
45
+ totalEdges: 0,
46
+ completedEdges: 0,
47
+ totalTime: 0,
48
+ maxTime: 0,
49
+ minTime: Infinity,
50
+ startTime: 0,
51
+ cacheHits: 0,
52
+ cacheMisses: 0,
53
+ workerCalculations: 0,
54
+ mainThreadCalculations: 0
55
+ };
56
+
57
+ // 生成缓存 key
58
+ function generateCacheKey(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition) {
59
+ const sx = Math.round(sourceX * 10) / 10;
60
+ const sy = Math.round(sourceY * 10) / 10;
61
+ const tx = Math.round(targetX * 10) / 10;
62
+ const ty = Math.round(targetY * 10) / 10;
63
+ return `${sx}-${sy}-${tx}-${ty}-${sourcePosition}-${targetPosition}`;
64
+ }
65
+
66
+ // 重置统计
67
+ function resetPerfStats() {
68
+ perfStats.totalEdges = 0;
69
+ perfStats.completedEdges = 0;
70
+ perfStats.totalTime = 0;
71
+ perfStats.maxTime = 0;
72
+ perfStats.minTime = Infinity;
73
+ perfStats.startTime = performance.now();
74
+ perfStats.cacheHits = 0;
75
+ perfStats.cacheMisses = 0;
76
+ perfStats.workerCalculations = 0;
77
+ perfStats.mainThreadCalculations = 0;
78
+ }
79
+
80
+ // 打印统计
81
+ function logPerfStats() {
82
+ const totalDuration = performance.now() - perfStats.startTime;
83
+ const cacheHitRate = perfStats.totalEdges > 0 ? (perfStats.cacheHits / perfStats.totalEdges * 100).toFixed(1) : '0';
84
+ console.log('=== Manhattan Edge Performance Stats ===');
85
+ console.log(`Total edges: ${perfStats.totalEdges}`);
86
+ console.log(`Completed: ${perfStats.completedEdges}`);
87
+ console.log(`Cache hits: ${perfStats.cacheHits} (${cacheHitRate}%)`);
88
+ console.log(`Cache misses: ${perfStats.cacheMisses}`);
89
+ console.log(`Worker calculations: ${perfStats.workerCalculations}`);
90
+ console.log(`Main thread calculations: ${perfStats.mainThreadCalculations}`);
91
+ console.log(`Total calculation time: ${perfStats.totalTime.toFixed(2)}ms`);
92
+ console.log(`Average time per edge: ${(perfStats.totalTime / perfStats.completedEdges).toFixed(2)}ms`);
93
+ console.log(`Max time: ${perfStats.maxTime.toFixed(2)}ms`);
94
+ console.log(`Min time: ${perfStats.minTime.toFixed(2)}ms`);
95
+ console.log(`Total elapsed time: ${totalDuration.toFixed(2)}ms`);
96
+ console.log('========================================');
97
+ }
20
98
  const ManhattanEdge = exports.ManhattanEdge = /*#__PURE__*/(0, _react2.memo)(({
99
+ id,
21
100
  source,
22
101
  target,
23
102
  sourceX,
@@ -30,30 +109,108 @@ const ManhattanEdge = exports.ManhattanEdge = /*#__PURE__*/(0, _react2.memo)(({
30
109
  const {
31
110
  getState
32
111
  } = (0, _react.useStoreApi)();
33
- const nodeLookup = getState().nodeLookup;
34
- const path = (0, _manhattan.getManHattanPath)({
35
- sourceNodeId: source,
36
- targetNodeId: target,
37
- sourceX,
38
- sourceY,
39
- sourcePosition,
40
- targetX,
41
- targetY,
42
- targetPosition,
43
- //
44
- // sourcePosition: {
45
- // x: sourceX,
46
- // y: sourceY
47
- // },
48
- // targetPosition: {
49
- // x: targetX,
50
- // y: targetY
51
- // },
52
- nodeLookup: nodeLookup
53
- // options: {
54
- // padding: 10
55
- // }
56
- });
112
+ const [path, setPath] = (0, _react2.useState)('');
113
+ const isMountedRef = (0, _react2.useRef)(true);
114
+ (0, _react2.useEffect)(() => {
115
+ isMountedRef.current = true;
116
+
117
+ // 第一个边开始计算时重置统计
118
+ if (perfStats.totalEdges === 0) {
119
+ resetPerfStats();
120
+ }
121
+ perfStats.totalEdges++;
122
+ const state = getState();
123
+ const {
124
+ edgeLookup,
125
+ nodeLookup
126
+ } = state;
127
+
128
+ // 获取当前 edge 对象
129
+ const currentEdge = edgeLookup.get(id);
130
+
131
+ // 生成缓存 key
132
+ const cacheKey = generateCacheKey(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
133
+
134
+ // 检查缓存
135
+ const cachedData = currentEdge?.data?.__manhattanPathCache;
136
+ if (cachedData && cachedData.key === cacheKey) {
137
+ perfStats.cacheHits++;
138
+ perfStats.completedEdges++;
139
+ setPath(cachedData.path);
140
+ if (perfStats.completedEdges === perfStats.totalEdges) {
141
+ logPerfStats();
142
+ }
143
+ return;
144
+ }
145
+ perfStats.cacheMisses++;
146
+ const calculatePath = async () => {
147
+ if (!isMountedRef.current) return;
148
+ const startTime = performance.now();
149
+ let calculatedPath;
150
+ const params = {
151
+ sourceNodeId: source,
152
+ targetNodeId: target,
153
+ sourceX,
154
+ sourceY,
155
+ sourcePosition,
156
+ targetX,
157
+ targetY,
158
+ targetPosition,
159
+ nodeLookup: nodeLookup
160
+ };
161
+
162
+ // 尝试使用 Worker,失败则回退到主线程
163
+ const worker = getWorker();
164
+ try {
165
+ if (worker) {
166
+ perfStats.workerCalculations++;
167
+ calculatedPath = await worker.calculatePath(params);
168
+ } else {
169
+ perfStats.mainThreadCalculations++;
170
+ calculatedPath = (0, _manhattan.getManHattanPath)(params);
171
+ }
172
+ } catch (error) {
173
+ // Fallback 到主线程
174
+ perfStats.mainThreadCalculations++;
175
+ calculatedPath = (0, _manhattan.getManHattanPath)(params);
176
+ }
177
+ const endTime = performance.now();
178
+ const duration = endTime - startTime;
179
+
180
+ // 更新统计
181
+ perfStats.completedEdges++;
182
+ perfStats.totalTime += duration;
183
+ perfStats.maxTime = Math.max(perfStats.maxTime, duration);
184
+ perfStats.minTime = Math.min(perfStats.minTime, duration);
185
+
186
+ // 缓存结果
187
+ if (currentEdge) {
188
+ if (!currentEdge.data) {
189
+ currentEdge.data = {};
190
+ }
191
+ currentEdge.data.__manhattanPathCache = {
192
+ key: cacheKey,
193
+ path: calculatedPath,
194
+ timestamp: Date.now()
195
+ };
196
+ }
197
+ if (isMountedRef.current) {
198
+ setPath(calculatedPath);
199
+ }
200
+ if (perfStats.completedEdges === perfStats.totalEdges) {
201
+ logPerfStats();
202
+ }
203
+ };
204
+
205
+ // 直接执行异步计算(Worker 已经是异步的)
206
+ calculatePath();
207
+ return () => {
208
+ isMountedRef.current = false;
209
+ };
210
+ }, [id, source, target, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, getState]);
211
+ if (!path) {
212
+ return null;
213
+ }
57
214
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.BaseEdge, {
58
215
  path: path
59
216
  });
@@ -1 +1 @@
1
- {"version":3,"file":"PropsStore.d.ts","sourceRoot":"","sources":["PropsStore.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAC,cAAc,EAAkB,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAc,EAAC,SAAS,EAA6B,MAAM,OAAO,CAAC;AAKnE,eAAO,MAAM,UAAU;WAQZ,eAAe,QAAQ,EAAE,QAAQ,CAAC;cAC/B,SAAS;6CAoDtB,CAAA"}
1
+ {"version":3,"file":"PropsStore.d.ts","sourceRoot":"","sources":["PropsStore.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAC,cAAc,EAAkB,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAc,EAAC,SAAS,EAA6B,MAAM,OAAO,CAAC;AAKnE,eAAO,MAAM,UAAU;WAQZ,eAAe,QAAQ,EAAE,QAAQ,CAAC;cAC/B,SAAS;6CAqDtB,CAAA"}
@@ -53,6 +53,8 @@ const PropsStore = ({
53
53
  }
54
54
  return map;
55
55
  }, [nodeTypes]);
56
+
57
+ // TODO 更新属性怎么更好的区分
56
58
  (0, _ahooks.useDeepCompareEffect)(() => {
57
59
  setState({
58
60
  props: props,
@@ -0,0 +1,21 @@
1
+ import { type GetManHattanPathParams } from '@rxflow/manhattan';
2
+ /**
3
+ * Worker 中的 Manhattan 路径计算服务
4
+ */
5
+ declare const manhattanWorker: {
6
+ /**
7
+ * 计算单条边的路径
8
+ */
9
+ calculatePath(params: GetManHattanPathParams): Promise<string>;
10
+ /**
11
+ * 批量计算多条边的路径
12
+ */
13
+ calculatePaths(paramsArray: GetManHattanPathParams[]): Promise<Array<{
14
+ id: string;
15
+ path: string;
16
+ error?: string;
17
+ }>>;
18
+ };
19
+ export type ManhattanWorkerType = typeof manhattanWorker;
20
+ export {};
21
+ //# sourceMappingURL=manhattan.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manhattan.worker.d.ts","sourceRoot":"","sources":["manhattan.worker.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAElF;;GAEG;AACH,QAAA,MAAM,eAAe;IACnB;;OAEG;0BACyB,sBAAsB,GAAG,QAAQ,MAAM,CAAC;IAIpE;;OAEG;gCAEY,sBAAsB,EAAE,GACpC,QAAQ,MAAM;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAiBhE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,eAAe,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ var _comlink = require("comlink");
4
+ var _manhattan = require("@rxflow/manhattan");
5
+ /**
6
+ * Manhattan 路径计算 Worker
7
+ * 使用 Comlink 暴露计算接口
8
+ */
9
+
10
+ /**
11
+ * Worker 中的 Manhattan 路径计算服务
12
+ */
13
+ const manhattanWorker = {
14
+ /**
15
+ * 计算单条边的路径
16
+ */
17
+ async calculatePath(params) {
18
+ return (0, _manhattan.getManHattanPath)(params);
19
+ },
20
+ /**
21
+ * 批量计算多条边的路径
22
+ */
23
+ async calculatePaths(paramsArray) {
24
+ return paramsArray.map((params, index) => {
25
+ try {
26
+ const path = (0, _manhattan.getManHattanPath)(params);
27
+ return {
28
+ id: `${params.sourceNodeId}-${params.targetNodeId}`,
29
+ path
30
+ };
31
+ } catch (error) {
32
+ return {
33
+ id: `${params.sourceNodeId}-${params.targetNodeId}`,
34
+ path: '',
35
+ error: error instanceof Error ? error.message : 'Unknown error'
36
+ };
37
+ }
38
+ });
39
+ }
40
+ };
41
+ (0, _comlink.expose)(manhattanWorker);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAgB,YAAY,EAA6D,MAAM,eAAe,CAAC;AAItH,OAAO,KAAK,EAAE,EAAO,SAAS,EAAC,MAAM,OAAO,CAAC;AAY7C,iBAAS,QAAQ,CACf,EACE,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAuB,EACvB,cAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,EACxB,WAAwB,EACxB,YAAY,EAAE,SAAiC,EAC/C,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,EAAE,YAAY,GAAG;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjD,2CAuKF;;AAED,wBAA8B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAgB,YAAY,EAA6D,MAAM,eAAe,CAAC;AAItH,OAAO,KAAK,EAAE,EAAO,SAAS,EAAU,MAAM,OAAO,CAAC;AAYtD,iBAAS,QAAQ,CACf,EACE,KAAK,EACL,QAAe,EACf,WAAkB,EAClB,eAAuB,EACvB,cAAqB,EACrB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,QAAwB,EACxB,WAAwB,EACxB,YAAY,EAAE,SAAiC,EAC/C,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,EAAE,YAAY,GAAG;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACjD,2CAsMF;;AAED,wBAA8B"}
@@ -20,7 +20,7 @@ import { ControlButton, Panel, useReactFlow, useStore, useStoreApi } from "@xyfl
20
20
  import { useFullscreen } from "ahooks";
21
21
  import { Tooltip } from 'antd';
22
22
  import cc from 'classcat';
23
- import React, { memo } from "react";
23
+ import React, { memo, useMemo } from "react";
24
24
  import { Fragment } from "react/jsx-runtime";
25
25
  import { shallow } from "zustand/shallow";
26
26
  import { FitViewIcon, ForceLayout, LockIcon, Minimap, UnlockIcon, UnMinimap } from "./icons";
@@ -65,6 +65,36 @@ function Controls(_ref) {
65
65
  _useFullscreen2 = _slicedToArray(_useFullscreen, 2),
66
66
  isFullscreen = _useFullscreen2[0],
67
67
  toggleFullscreen = _useFullscreen2[1].toggleFullscreen;
68
+ var tooltipPlacement = useMemo(function () {
69
+ switch (position) {
70
+ case 'top-left':
71
+ case 'center-left':
72
+ case 'top-center':
73
+ if (orientation === 'horizontal') {
74
+ return 'bottom';
75
+ }
76
+ return 'right';
77
+ case 'top-right':
78
+ case 'center-right':
79
+ if (orientation === 'horizontal') {
80
+ return 'bottom';
81
+ }
82
+ return 'left';
83
+ case 'bottom-left':
84
+ case 'bottom-center':
85
+ if (orientation === 'horizontal') {
86
+ return 'top';
87
+ }
88
+ return 'right';
89
+ case 'bottom-right':
90
+ if (orientation === 'horizontal') {
91
+ return 'top';
92
+ }
93
+ return 'left';
94
+ default:
95
+ return 'top';
96
+ }
97
+ }, []);
68
98
  var store = useStoreApi();
69
99
  var _useStore = useStore(selector, shallow),
70
100
  isInteractive = _useStore.isInteractive,
@@ -110,7 +140,7 @@ function Controls(_ref) {
110
140
  children: [showZoom && /*#__PURE__*/_jsxs(Fragment, {
111
141
  children: [/*#__PURE__*/_jsx(Tooltip, {
112
142
  title: '放大',
113
- placement: 'right',
143
+ placement: tooltipPlacement,
114
144
  children: /*#__PURE__*/_jsx("span", {
115
145
  children: /*#__PURE__*/_jsx(ControlButton, {
116
146
  onClick: onZoomInHandler,
@@ -123,7 +153,7 @@ function Controls(_ref) {
123
153
  })
124
154
  }), /*#__PURE__*/_jsx(Tooltip, {
125
155
  title: '缩小',
126
- placement: 'right',
156
+ placement: tooltipPlacement,
127
157
  children: /*#__PURE__*/_jsx("span", {
128
158
  children: /*#__PURE__*/_jsx(ControlButton, {
129
159
  onClick: onZoomOutHandler,
@@ -137,7 +167,7 @@ function Controls(_ref) {
137
167
  })]
138
168
  }), showFitView && /*#__PURE__*/_jsx(Tooltip, {
139
169
  title: '自适应视图',
140
- placement: 'right',
170
+ placement: tooltipPlacement,
141
171
  children: /*#__PURE__*/_jsx("span", {
142
172
  children: /*#__PURE__*/_jsx(ControlButton, {
143
173
  className: "react-flow__controls-fitview",
@@ -149,7 +179,7 @@ function Controls(_ref) {
149
179
  })
150
180
  }), showFullscreen && /*#__PURE__*/_jsx(Tooltip, {
151
181
  title: isFullscreen ? '取消全屏' : '全屏',
152
- placement: 'right',
182
+ placement: tooltipPlacement,
153
183
  children: /*#__PURE__*/_jsx("span", {
154
184
  children: /*#__PURE__*/_jsx(ControlButton, {
155
185
  className: "react-flow__controls-fullscreen",
@@ -161,7 +191,7 @@ function Controls(_ref) {
161
191
  })
162
192
  }), showMiniMap && /*#__PURE__*/_jsx(Tooltip, {
163
193
  title: minimapVisible ? '关闭缩略图' : '开启缩略图',
164
- placement: 'right',
194
+ placement: tooltipPlacement,
165
195
  children: /*#__PURE__*/_jsx("span", {
166
196
  children: /*#__PURE__*/_jsx(ControlButton, {
167
197
  className: "react-flow__controls-interactive",
@@ -173,7 +203,7 @@ function Controls(_ref) {
173
203
  })
174
204
  }), showInteractive && /*#__PURE__*/_jsx(Tooltip, {
175
205
  title: isInteractive ? '解锁' : '锁定',
176
- placement: 'right',
206
+ placement: tooltipPlacement,
177
207
  children: /*#__PURE__*/_jsx("span", {
178
208
  children: /*#__PURE__*/_jsx(ControlButton, {
179
209
  className: "react-flow__controls-interactive",
@@ -185,7 +215,7 @@ function Controls(_ref) {
185
215
  })
186
216
  }), showForceLayout && /*#__PURE__*/_jsx(Tooltip, {
187
217
  title: '美化布局',
188
- placement: 'right',
218
+ placement: tooltipPlacement,
189
219
  children: /*#__PURE__*/_jsx("span", {
190
220
  children: /*#__PURE__*/_jsx(ControlButton, {
191
221
  className: "react-flow__controls-layout",
@@ -2,7 +2,7 @@
2
2
  * @author: yanxianliang
3
3
  * @date: 2025-10-20 09:19
4
4
  * @modified:2025/10/20 09:19 by yanxianliang
5
- * @desc: 智能边
5
+ * @desc: 智能边 - 默认使用 Web Worker 计算
6
6
  *
7
7
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,EAAc,MAAM,eAAe,CAAC;AACpE,OAAO,EAAC,aAAa,EAAO,MAAM,OAAO,CAAC;AAG1C,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CAyCjD,CAAA"}
1
+ {"version":3,"file":"manhattan.d.ts","sourceRoot":"","sources":["manhattan.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAW,KAAK,SAAS,EAAc,MAAM,eAAe,CAAC;AACpE,OAAO,EAAC,aAAa,EAAoC,MAAM,OAAO,CAAC;AAgGvE,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,SAAS,CA0IjD,CAAA"}
@@ -1,17 +1,106 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
10
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
1
11
  /**
2
12
  * @author: yanxianliang
3
13
  * @date: 2025-10-20 09:19
4
14
  * @modified:2025/10/20 09:19 by yanxianliang
5
- * @desc: 智能边
15
+ * @desc: 智能边 - 默认使用 Web Worker 计算
6
16
  *
7
17
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
8
18
  */
9
19
  import { BaseEdge, useStoreApi } from '@xyflow/react';
10
- import { memo } from "react";
20
+ import { memo, useState, useEffect, useRef } from "react";
11
21
  import { getManHattanPath } from '@rxflow/manhattan';
22
+ import { wrap } from 'comlink';
12
23
  import { jsx as _jsx } from "react/jsx-runtime";
24
+ // 全局 Worker 实例(单例)
25
+ var workerInstance = null;
26
+ var workerApi = null;
27
+
28
+ // 获取或创建 Worker
29
+ function getWorker() {
30
+ if (typeof window === 'undefined') return null; // SSR 环境
31
+
32
+ if (!workerInstance || !workerApi) {
33
+ try {
34
+ workerInstance = new Worker(new URL('../workers/manhattan.worker.ts', import.meta.url), {
35
+ type: 'module'
36
+ });
37
+ workerApi = wrap(workerInstance);
38
+ } catch (error) {
39
+ console.warn('[ManhattanEdge] Worker initialization failed, using main thread:', error);
40
+ return null;
41
+ }
42
+ }
43
+ return workerApi;
44
+ }
45
+
46
+ // 全局性能统计
47
+ var perfStats = {
48
+ totalEdges: 0,
49
+ completedEdges: 0,
50
+ totalTime: 0,
51
+ maxTime: 0,
52
+ minTime: Infinity,
53
+ startTime: 0,
54
+ cacheHits: 0,
55
+ cacheMisses: 0,
56
+ workerCalculations: 0,
57
+ mainThreadCalculations: 0
58
+ };
59
+
60
+ // 生成缓存 key
61
+ function generateCacheKey(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition) {
62
+ var sx = Math.round(sourceX * 10) / 10;
63
+ var sy = Math.round(sourceY * 10) / 10;
64
+ var tx = Math.round(targetX * 10) / 10;
65
+ var ty = Math.round(targetY * 10) / 10;
66
+ return "".concat(sx, "-").concat(sy, "-").concat(tx, "-").concat(ty, "-").concat(sourcePosition, "-").concat(targetPosition);
67
+ }
68
+
69
+ // 重置统计
70
+ function resetPerfStats() {
71
+ perfStats.totalEdges = 0;
72
+ perfStats.completedEdges = 0;
73
+ perfStats.totalTime = 0;
74
+ perfStats.maxTime = 0;
75
+ perfStats.minTime = Infinity;
76
+ perfStats.startTime = performance.now();
77
+ perfStats.cacheHits = 0;
78
+ perfStats.cacheMisses = 0;
79
+ perfStats.workerCalculations = 0;
80
+ perfStats.mainThreadCalculations = 0;
81
+ }
82
+
83
+ // 打印统计
84
+ function logPerfStats() {
85
+ var totalDuration = performance.now() - perfStats.startTime;
86
+ var cacheHitRate = perfStats.totalEdges > 0 ? (perfStats.cacheHits / perfStats.totalEdges * 100).toFixed(1) : '0';
87
+ console.log('=== Manhattan Edge Performance Stats ===');
88
+ console.log("Total edges: ".concat(perfStats.totalEdges));
89
+ console.log("Completed: ".concat(perfStats.completedEdges));
90
+ console.log("Cache hits: ".concat(perfStats.cacheHits, " (").concat(cacheHitRate, "%)"));
91
+ console.log("Cache misses: ".concat(perfStats.cacheMisses));
92
+ console.log("Worker calculations: ".concat(perfStats.workerCalculations));
93
+ console.log("Main thread calculations: ".concat(perfStats.mainThreadCalculations));
94
+ console.log("Total calculation time: ".concat(perfStats.totalTime.toFixed(2), "ms"));
95
+ console.log("Average time per edge: ".concat((perfStats.totalTime / perfStats.completedEdges).toFixed(2), "ms"));
96
+ console.log("Max time: ".concat(perfStats.maxTime.toFixed(2), "ms"));
97
+ console.log("Min time: ".concat(perfStats.minTime.toFixed(2), "ms"));
98
+ console.log("Total elapsed time: ".concat(totalDuration.toFixed(2), "ms"));
99
+ console.log('========================================');
100
+ }
13
101
  export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
14
- var source = _ref.source,
102
+ var id = _ref.id,
103
+ source = _ref.source,
15
104
  target = _ref.target,
16
105
  sourceX = _ref.sourceX,
17
106
  sourceY = _ref.sourceY,
@@ -21,30 +110,136 @@ export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
21
110
  targetPosition = _ref.targetPosition;
22
111
  var _useStoreApi = useStoreApi(),
23
112
  getState = _useStoreApi.getState;
24
- var nodeLookup = getState().nodeLookup;
25
- var path = getManHattanPath({
26
- sourceNodeId: source,
27
- targetNodeId: target,
28
- sourceX: sourceX,
29
- sourceY: sourceY,
30
- sourcePosition: sourcePosition,
31
- targetX: targetX,
32
- targetY: targetY,
33
- targetPosition: targetPosition,
34
- //
35
- // sourcePosition: {
36
- // x: sourceX,
37
- // y: sourceY
38
- // },
39
- // targetPosition: {
40
- // x: targetX,
41
- // y: targetY
42
- // },
43
- nodeLookup: nodeLookup
44
- // options: {
45
- // padding: 10
46
- // }
47
- });
113
+ var _useState = useState(''),
114
+ _useState2 = _slicedToArray(_useState, 2),
115
+ path = _useState2[0],
116
+ setPath = _useState2[1];
117
+ var isMountedRef = useRef(true);
118
+ useEffect(function () {
119
+ var _currentEdge$data;
120
+ isMountedRef.current = true;
121
+
122
+ // 第一个边开始计算时重置统计
123
+ if (perfStats.totalEdges === 0) {
124
+ resetPerfStats();
125
+ }
126
+ perfStats.totalEdges++;
127
+ var state = getState();
128
+ var edgeLookup = state.edgeLookup,
129
+ nodeLookup = state.nodeLookup;
130
+
131
+ // 获取当前 edge 对象
132
+ var currentEdge = edgeLookup.get(id);
133
+
134
+ // 生成缓存 key
135
+ var cacheKey = generateCacheKey(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
136
+
137
+ // 检查缓存
138
+ var cachedData = currentEdge === null || currentEdge === void 0 || (_currentEdge$data = currentEdge.data) === null || _currentEdge$data === void 0 ? void 0 : _currentEdge$data.__manhattanPathCache;
139
+ if (cachedData && cachedData.key === cacheKey) {
140
+ perfStats.cacheHits++;
141
+ perfStats.completedEdges++;
142
+ setPath(cachedData.path);
143
+ if (perfStats.completedEdges === perfStats.totalEdges) {
144
+ logPerfStats();
145
+ }
146
+ return;
147
+ }
148
+ perfStats.cacheMisses++;
149
+ var calculatePath = /*#__PURE__*/function () {
150
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
151
+ var startTime, calculatedPath, params, worker, endTime, duration;
152
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
153
+ while (1) switch (_context.prev = _context.next) {
154
+ case 0:
155
+ if (isMountedRef.current) {
156
+ _context.next = 2;
157
+ break;
158
+ }
159
+ return _context.abrupt("return");
160
+ case 2:
161
+ startTime = performance.now();
162
+ params = {
163
+ sourceNodeId: source,
164
+ targetNodeId: target,
165
+ sourceX: sourceX,
166
+ sourceY: sourceY,
167
+ sourcePosition: sourcePosition,
168
+ targetX: targetX,
169
+ targetY: targetY,
170
+ targetPosition: targetPosition,
171
+ nodeLookup: nodeLookup
172
+ }; // 尝试使用 Worker,失败则回退到主线程
173
+ worker = getWorker();
174
+ _context.prev = 5;
175
+ if (!worker) {
176
+ _context.next = 13;
177
+ break;
178
+ }
179
+ perfStats.workerCalculations++;
180
+ _context.next = 10;
181
+ return worker.calculatePath(params);
182
+ case 10:
183
+ calculatedPath = _context.sent;
184
+ _context.next = 15;
185
+ break;
186
+ case 13:
187
+ perfStats.mainThreadCalculations++;
188
+ calculatedPath = getManHattanPath(params);
189
+ case 15:
190
+ _context.next = 21;
191
+ break;
192
+ case 17:
193
+ _context.prev = 17;
194
+ _context.t0 = _context["catch"](5);
195
+ // Fallback 到主线程
196
+ perfStats.mainThreadCalculations++;
197
+ calculatedPath = getManHattanPath(params);
198
+ case 21:
199
+ endTime = performance.now();
200
+ duration = endTime - startTime; // 更新统计
201
+ perfStats.completedEdges++;
202
+ perfStats.totalTime += duration;
203
+ perfStats.maxTime = Math.max(perfStats.maxTime, duration);
204
+ perfStats.minTime = Math.min(perfStats.minTime, duration);
205
+
206
+ // 缓存结果
207
+ if (currentEdge) {
208
+ if (!currentEdge.data) {
209
+ currentEdge.data = {};
210
+ }
211
+ currentEdge.data.__manhattanPathCache = {
212
+ key: cacheKey,
213
+ path: calculatedPath,
214
+ timestamp: Date.now()
215
+ };
216
+ }
217
+ if (isMountedRef.current) {
218
+ setPath(calculatedPath);
219
+ }
220
+ if (perfStats.completedEdges === perfStats.totalEdges) {
221
+ logPerfStats();
222
+ }
223
+ case 30:
224
+ case "end":
225
+ return _context.stop();
226
+ }
227
+ }, _callee, null, [[5, 17]]);
228
+ }));
229
+ return function calculatePath() {
230
+ return _ref2.apply(this, arguments);
231
+ };
232
+ }();
233
+
234
+ // 直接执行异步计算(Worker 已经是异步的)
235
+ calculatePath();
236
+ return function () {
237
+ isMountedRef.current = false;
238
+ };
239
+ }, [id, source, target, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, getState]);
240
+ if (!path) {
241
+ return null;
242
+ }
48
243
  return /*#__PURE__*/_jsx(BaseEdge, {
49
244
  path: path
50
245
  });
@@ -1 +1 @@
1
- {"version":3,"file":"PropsStore.d.ts","sourceRoot":"","sources":["PropsStore.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAC,cAAc,EAAkB,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAc,EAAC,SAAS,EAA6B,MAAM,OAAO,CAAC;AAKnE,eAAO,MAAM,UAAU;WAQZ,eAAe,QAAQ,EAAE,QAAQ,CAAC;cAC/B,SAAS;6CAoDtB,CAAA"}
1
+ {"version":3,"file":"PropsStore.d.ts","sourceRoot":"","sources":["PropsStore.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAC,cAAc,EAAkB,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAc,EAAC,SAAS,EAA6B,MAAM,OAAO,CAAC;AAKnE,eAAO,MAAM,UAAU;WAQZ,eAAe,QAAQ,EAAE,QAAQ,CAAC;cAC/B,SAAS;6CAqDtB,CAAA"}
@@ -46,6 +46,8 @@ export var PropsStore = function PropsStore(_ref) {
46
46
  }
47
47
  return map;
48
48
  }, [nodeTypes]);
49
+
50
+ // TODO 更新属性怎么更好的区分
49
51
  useDeepCompareEffect(function () {
50
52
  setState({
51
53
  props: props,
@@ -0,0 +1,21 @@
1
+ import { type GetManHattanPathParams } from '@rxflow/manhattan';
2
+ /**
3
+ * Worker 中的 Manhattan 路径计算服务
4
+ */
5
+ declare const manhattanWorker: {
6
+ /**
7
+ * 计算单条边的路径
8
+ */
9
+ calculatePath(params: GetManHattanPathParams): Promise<string>;
10
+ /**
11
+ * 批量计算多条边的路径
12
+ */
13
+ calculatePaths(paramsArray: GetManHattanPathParams[]): Promise<Array<{
14
+ id: string;
15
+ path: string;
16
+ error?: string;
17
+ }>>;
18
+ };
19
+ export type ManhattanWorkerType = typeof manhattanWorker;
20
+ export {};
21
+ //# sourceMappingURL=manhattan.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manhattan.worker.d.ts","sourceRoot":"","sources":["manhattan.worker.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAElF;;GAEG;AACH,QAAA,MAAM,eAAe;IACnB;;OAEG;0BACyB,sBAAsB,GAAG,QAAQ,MAAM,CAAC;IAIpE;;OAEG;gCAEY,sBAAsB,EAAE,GACpC,QAAQ,MAAM;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAiBhE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,eAAe,CAAC"}
@@ -0,0 +1,63 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ /**
6
+ * Manhattan 路径计算 Worker
7
+ * 使用 Comlink 暴露计算接口
8
+ */
9
+ import { expose } from 'comlink';
10
+ import { getManHattanPath } from '@rxflow/manhattan';
11
+
12
+ /**
13
+ * Worker 中的 Manhattan 路径计算服务
14
+ */
15
+ var manhattanWorker = {
16
+ /**
17
+ * 计算单条边的路径
18
+ */
19
+ calculatePath: function calculatePath(params) {
20
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
21
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
22
+ while (1) switch (_context.prev = _context.next) {
23
+ case 0:
24
+ return _context.abrupt("return", getManHattanPath(params));
25
+ case 1:
26
+ case "end":
27
+ return _context.stop();
28
+ }
29
+ }, _callee);
30
+ }))();
31
+ },
32
+ /**
33
+ * 批量计算多条边的路径
34
+ */
35
+ calculatePaths: function calculatePaths(paramsArray) {
36
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
37
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
38
+ while (1) switch (_context2.prev = _context2.next) {
39
+ case 0:
40
+ return _context2.abrupt("return", paramsArray.map(function (params, index) {
41
+ try {
42
+ var path = getManHattanPath(params);
43
+ return {
44
+ id: "".concat(params.sourceNodeId, "-").concat(params.targetNodeId),
45
+ path: path
46
+ };
47
+ } catch (error) {
48
+ return {
49
+ id: "".concat(params.sourceNodeId, "-").concat(params.targetNodeId),
50
+ path: '',
51
+ error: error instanceof Error ? error.message : 'Unknown error'
52
+ };
53
+ }
54
+ }));
55
+ case 1:
56
+ case "end":
57
+ return _context2.stop();
58
+ }
59
+ }, _callee2);
60
+ }))();
61
+ }
62
+ };
63
+ expose(manhattanWorker);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxflow/base",
3
- "version": "0.0.2-alpha.7",
3
+ "version": "0.0.2",
4
4
  "description": "BaseFlow - 核心 Flow 组件库",
5
5
  "keywords": [
6
6
  "reactflow",
@@ -42,7 +42,7 @@
42
42
  "dependencies": {
43
43
  "@ant-design/icons": "^6.0.0",
44
44
  "@antv/hierarchy": "0.6.14",
45
- "@rxflow/manhattan": "^0.0.2-alpha.7",
45
+ "@rxflow/manhattan": "^0.0.2",
46
46
  "@xyflow/react": "^12.8.6",
47
47
  "@xyflow/system": "^0.0.70",
48
48
  "@zumer/snapdom": "^1.9.9",