@rxflow/base 0.0.2-alpha.8 → 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.
- package/cjs/edges/manhattan.d.ts +1 -1
- package/cjs/edges/manhattan.d.ts.map +1 -1
- package/cjs/edges/manhattan.js +182 -25
- package/cjs/workers/manhattan.worker.d.ts +21 -0
- package/cjs/workers/manhattan.worker.d.ts.map +1 -0
- package/cjs/workers/manhattan.worker.js +41 -0
- package/esm/edges/manhattan.d.ts +1 -1
- package/esm/edges/manhattan.d.ts.map +1 -1
- package/esm/edges/manhattan.js +222 -27
- package/esm/workers/manhattan.worker.d.ts +21 -0
- package/esm/workers/manhattan.worker.d.ts.map +1 -0
- package/esm/workers/manhattan.worker.js +63 -0
- package/package.json +2 -2
package/cjs/edges/manhattan.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/cjs/edges/manhattan.js
CHANGED
|
@@ -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
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
});
|
|
@@ -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);
|
package/esm/edges/manhattan.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/esm/edges/manhattan.js
CHANGED
|
@@ -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
|
|
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
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
//
|
|
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
|
});
|
|
@@ -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
|
|
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
|
|
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",
|