@rxflow/base 0.0.2 → 0.0.4-alpha.0

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.
Files changed (131) hide show
  1. package/cjs/Flow.d.ts +1 -1
  2. package/cjs/Flow.d.ts.map +1 -1
  3. package/cjs/Flow.js +28 -10
  4. package/cjs/components/Legend/index.d.ts.map +1 -1
  5. package/cjs/components/Legend/index.js +2 -1
  6. package/cjs/components/Popover/index.d.ts +1 -9
  7. package/cjs/components/Popover/index.d.ts.map +1 -1
  8. package/cjs/components/Popover/index.js +14 -75
  9. package/cjs/components/Tooltip/index.d.ts +1 -10
  10. package/cjs/components/Tooltip/index.d.ts.map +1 -1
  11. package/cjs/components/Tooltip/index.js +11 -83
  12. package/cjs/edges/manhattan.d.ts.map +1 -1
  13. package/cjs/edges/manhattan.js +100 -30
  14. package/cjs/hoc/createFlow.d.ts +30 -4
  15. package/cjs/hoc/createFlow.d.ts.map +1 -1
  16. package/cjs/hoc/createFlow.js +45 -18
  17. package/cjs/hooks/index.d.ts +5 -2
  18. package/cjs/hooks/index.d.ts.map +1 -1
  19. package/cjs/hooks/index.js +44 -22
  20. package/cjs/hooks/props/index.d.ts +12 -0
  21. package/cjs/hooks/props/index.d.ts.map +1 -0
  22. package/cjs/hooks/props/index.js +49 -0
  23. package/cjs/hooks/props/useFlowProps.d.ts +23 -0
  24. package/cjs/hooks/props/useFlowProps.d.ts.map +1 -0
  25. package/cjs/hooks/props/useFlowProps.js +34 -0
  26. package/cjs/hooks/props/useGetFlowProps.d.ts +19 -0
  27. package/cjs/hooks/props/useGetFlowProps.d.ts.map +1 -0
  28. package/cjs/hooks/props/useGetFlowProps.js +38 -0
  29. package/cjs/hooks/props/useGetInputProps.d.ts +18 -0
  30. package/cjs/hooks/props/useGetInputProps.d.ts.map +1 -0
  31. package/cjs/hooks/props/useGetInputProps.js +38 -0
  32. package/cjs/hooks/props/useInputProps.d.ts +14 -0
  33. package/cjs/hooks/props/useInputProps.d.ts.map +1 -0
  34. package/cjs/hooks/props/useInputProps.js +33 -0
  35. package/cjs/hooks/useListenRender.js +4 -4
  36. package/cjs/hooks/useTheme.d.ts.map +1 -1
  37. package/cjs/hooks/useTheme.js +3 -2
  38. package/cjs/index.d.ts +6 -3
  39. package/cjs/index.d.ts.map +1 -1
  40. package/cjs/index.js +46 -14
  41. package/cjs/providers/FlowProvider.d.ts +7 -1
  42. package/cjs/providers/FlowProvider.d.ts.map +1 -1
  43. package/cjs/providers/FlowProvider.js +33 -14
  44. package/cjs/store/PropsStore.d.ts +11 -6
  45. package/cjs/store/PropsStore.d.ts.map +1 -1
  46. package/cjs/store/PropsStore.js +55 -39
  47. package/cjs/types/props.d.ts +83 -0
  48. package/cjs/types/props.d.ts.map +1 -0
  49. package/cjs/types/props.js +5 -0
  50. package/cjs/types.d.ts +5 -1
  51. package/cjs/types.d.ts.map +1 -1
  52. package/cjs/utils/wrapNodeTypes.d.ts +30 -0
  53. package/cjs/utils/wrapNodeTypes.d.ts.map +1 -0
  54. package/cjs/utils/wrapNodeTypes.js +56 -0
  55. package/cjs/workers/manhattan.worker.js +12534 -31
  56. package/cjs/workers/manhattan.worker.js.map +7 -0
  57. package/esm/Flow.d.ts +1 -1
  58. package/esm/Flow.d.ts.map +1 -1
  59. package/esm/Flow.js +30 -16
  60. package/esm/components/Legend/index.d.ts.map +1 -1
  61. package/esm/components/Legend/index.js +3 -2
  62. package/esm/components/Popover/index.d.ts +1 -9
  63. package/esm/components/Popover/index.d.ts.map +1 -1
  64. package/esm/components/Popover/index.js +16 -87
  65. package/esm/components/Tooltip/index.d.ts +1 -10
  66. package/esm/components/Tooltip/index.d.ts.map +1 -1
  67. package/esm/components/Tooltip/index.js +14 -97
  68. package/esm/edges/manhattan.d.ts.map +1 -1
  69. package/esm/edges/manhattan.js +95 -23
  70. package/esm/hoc/createFlow.d.ts +30 -4
  71. package/esm/hoc/createFlow.d.ts.map +1 -1
  72. package/esm/hoc/createFlow.js +48 -20
  73. package/esm/hooks/index.d.ts +5 -2
  74. package/esm/hooks/index.d.ts.map +1 -1
  75. package/esm/hooks/index.js +8 -3
  76. package/esm/hooks/props/index.d.ts +12 -0
  77. package/esm/hooks/props/index.d.ts.map +1 -0
  78. package/esm/hooks/props/index.js +12 -0
  79. package/esm/hooks/props/useFlowProps.d.ts +23 -0
  80. package/esm/hooks/props/useFlowProps.d.ts.map +1 -0
  81. package/esm/hooks/props/useFlowProps.js +29 -0
  82. package/esm/hooks/props/useGetFlowProps.d.ts +19 -0
  83. package/esm/hooks/props/useGetFlowProps.d.ts.map +1 -0
  84. package/esm/hooks/props/useGetFlowProps.js +31 -0
  85. package/esm/hooks/props/useGetInputProps.d.ts +18 -0
  86. package/esm/hooks/props/useGetInputProps.d.ts.map +1 -0
  87. package/esm/hooks/props/useGetInputProps.js +31 -0
  88. package/esm/hooks/props/useInputProps.d.ts +14 -0
  89. package/esm/hooks/props/useInputProps.d.ts.map +1 -0
  90. package/esm/hooks/props/useInputProps.js +27 -0
  91. package/esm/hooks/useListenRender.js +4 -4
  92. package/esm/hooks/useTheme.d.ts.map +1 -1
  93. package/esm/hooks/useTheme.js +3 -2
  94. package/esm/index.d.ts +6 -3
  95. package/esm/index.d.ts.map +1 -1
  96. package/esm/index.js +22 -3
  97. package/esm/providers/FlowProvider.d.ts +7 -1
  98. package/esm/providers/FlowProvider.d.ts.map +1 -1
  99. package/esm/providers/FlowProvider.js +36 -15
  100. package/esm/store/PropsStore.d.ts +11 -6
  101. package/esm/store/PropsStore.d.ts.map +1 -1
  102. package/esm/store/PropsStore.js +75 -34
  103. package/esm/types/props.d.ts +83 -0
  104. package/esm/types/props.d.ts.map +1 -0
  105. package/esm/types/props.js +1 -0
  106. package/esm/types.d.ts +5 -1
  107. package/esm/types.d.ts.map +1 -1
  108. package/esm/utils/wrapNodeTypes.d.ts +30 -0
  109. package/esm/utils/wrapNodeTypes.d.ts.map +1 -0
  110. package/esm/utils/wrapNodeTypes.js +55 -0
  111. package/esm/workers/manhattan.worker.js +1 -1
  112. package/esm/workers/manhattan.worker.js.map +7 -0
  113. package/package.json +5 -3
  114. package/cjs/hooks/props/useGetProps.d.ts +0 -6
  115. package/cjs/hooks/props/useGetProps.d.ts.map +0 -1
  116. package/cjs/hooks/props/useGetProps.js +0 -29
  117. package/cjs/hooks/props/useProps.d.ts +0 -2
  118. package/cjs/hooks/props/useProps.d.ts.map +0 -1
  119. package/cjs/hooks/props/useProps.js +0 -20
  120. package/cjs/hooks/props/usePropsSelector.d.ts +0 -13
  121. package/cjs/hooks/props/usePropsSelector.d.ts.map +0 -1
  122. package/cjs/hooks/props/usePropsSelector.js +0 -37
  123. package/esm/hooks/props/useGetProps.d.ts +0 -6
  124. package/esm/hooks/props/useGetProps.d.ts.map +0 -1
  125. package/esm/hooks/props/useGetProps.js +0 -21
  126. package/esm/hooks/props/useProps.d.ts +0 -2
  127. package/esm/hooks/props/useProps.d.ts.map +0 -1
  128. package/esm/hooks/props/useProps.js +0 -14
  129. package/esm/hooks/props/usePropsSelector.d.ts +0 -13
  130. package/esm/hooks/props/usePropsSelector.d.ts.map +0 -1
  131. package/esm/hooks/props/usePropsSelector.js +0 -31
@@ -16,27 +16,79 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
16
  *
17
17
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
18
18
  */
19
- import { BaseEdge, useStoreApi } from '@xyflow/react';
19
+ import { BaseEdge, useStoreApi, getSmoothStepPath, Position } from '@xyflow/react';
20
20
  import { memo, useState, useEffect, useRef } from "react";
21
21
  import { getManHattanPath } from '@rxflow/manhattan';
22
22
  import { wrap } from 'comlink';
23
23
  import { jsx as _jsx } from "react/jsx-runtime";
24
+ /**
25
+ * 判断是否为简单的就近连接场景
26
+ * 这些场景不需要复杂的 Manhattan 算法,直接使用 SmoothStep 即可
27
+ *
28
+ * 就近连接规则:
29
+ * - 右锚点 → 左锚点(source 在 target 左侧)
30
+ * - 左锚点 → 右锚点(source 在 target 右侧)
31
+ * - 下锚点 → 上锚点(source 在 target 上方)
32
+ * - 上锚点 → 下锚点(source 在 target 下方)
33
+ */
34
+ function isSimpleConnection(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition) {
35
+ // 右 → 左:source 在左侧,target 在右侧
36
+ if (sourcePosition === Position.Right && targetPosition === Position.Left) {
37
+ return sourceX < targetX;
38
+ }
39
+
40
+ // 左 → 右:source 在右侧,target 在左侧
41
+ if (sourcePosition === Position.Left && targetPosition === Position.Right) {
42
+ return sourceX > targetX;
43
+ }
44
+
45
+ // 下 → 上:source 在上方,target 在下方
46
+ if (sourcePosition === Position.Bottom && targetPosition === Position.Top) {
47
+ return sourceY < targetY;
48
+ }
49
+
50
+ // 上 → 下:source 在下方,target 在上方
51
+ if (sourcePosition === Position.Top && targetPosition === Position.Bottom) {
52
+ return sourceY > targetY;
53
+ }
54
+ return false;
55
+ }
56
+
24
57
  // 全局 Worker 实例(单例)
25
58
  var workerInstance = null;
26
59
  var workerApi = null;
60
+ var workerInitFailed = false;
61
+
62
+ /**
63
+ * 创建 Worker
64
+ * 使用预编译的 .js bundle,不使用 type: 'module' 以获得更好的浏览器兼容性
65
+ */
66
+ function tryCreateWorker() {
67
+ try {
68
+ return new Worker(new URL('../workers/manhattan.worker.js', import.meta.url));
69
+ } catch (error) {
70
+ console.warn('[ManhattanEdge] Worker creation failed:', error);
71
+ return null;
72
+ }
73
+ }
27
74
 
28
75
  // 获取或创建 Worker
29
76
  function getWorker() {
30
77
  if (typeof window === 'undefined') return null; // SSR 环境
78
+ if (workerInitFailed) return null; // 之前初始化失败,不再尝试
31
79
 
32
80
  if (!workerInstance || !workerApi) {
33
81
  try {
34
- workerInstance = new Worker(new URL('../workers/manhattan.worker.ts', import.meta.url), {
35
- type: 'module'
36
- });
37
- workerApi = wrap(workerInstance);
82
+ workerInstance = tryCreateWorker();
83
+ if (workerInstance) {
84
+ workerApi = wrap(workerInstance);
85
+ } else {
86
+ workerInitFailed = true;
87
+ return null;
88
+ }
38
89
  } catch (error) {
39
90
  console.warn('[ManhattanEdge] Worker initialization failed, using main thread:', error);
91
+ workerInitFailed = true;
40
92
  return null;
41
93
  }
42
94
  }
@@ -54,7 +106,8 @@ var perfStats = {
54
106
  cacheHits: 0,
55
107
  cacheMisses: 0,
56
108
  workerCalculations: 0,
57
- mainThreadCalculations: 0
109
+ mainThreadCalculations: 0,
110
+ simplePathCalculations: 0 // 简单路径(使用 SmoothStep)
58
111
  };
59
112
 
60
113
  // 生成缓存 key
@@ -78,17 +131,20 @@ function resetPerfStats() {
78
131
  perfStats.cacheMisses = 0;
79
132
  perfStats.workerCalculations = 0;
80
133
  perfStats.mainThreadCalculations = 0;
134
+ perfStats.simplePathCalculations = 0;
81
135
  }
82
136
 
83
137
  // 打印统计
84
138
  function logPerfStats() {
85
139
  var totalDuration = performance.now() - perfStats.startTime;
86
140
  var cacheHitRate = perfStats.totalEdges > 0 ? (perfStats.cacheHits / perfStats.totalEdges * 100).toFixed(1) : '0';
141
+ var simplePathRate = perfStats.totalEdges > 0 ? (perfStats.simplePathCalculations / perfStats.totalEdges * 100).toFixed(1) : '0';
87
142
  console.log('=== Manhattan Edge Performance Stats ===');
88
143
  console.log("Total edges: ".concat(perfStats.totalEdges));
89
144
  console.log("Completed: ".concat(perfStats.completedEdges));
90
145
  console.log("Cache hits: ".concat(perfStats.cacheHits, " (").concat(cacheHitRate, "%)"));
91
146
  console.log("Cache misses: ".concat(perfStats.cacheMisses));
147
+ console.log("Simple paths (SmoothStep): ".concat(perfStats.simplePathCalculations, " (").concat(simplePathRate, "%)"));
92
148
  console.log("Worker calculations: ".concat(perfStats.workerCalculations));
93
149
  console.log("Main thread calculations: ".concat(perfStats.mainThreadCalculations));
94
150
  console.log("Total calculation time: ".concat(perfStats.totalTime.toFixed(2), "ms"));
@@ -148,7 +204,7 @@ export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
148
204
  perfStats.cacheMisses++;
149
205
  var calculatePath = /*#__PURE__*/function () {
150
206
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
151
- var startTime, calculatedPath, params, worker, endTime, duration;
207
+ var startTime, calculatedPath, _getSmoothStepPath, _getSmoothStepPath2, smoothPath, params, worker, endTime, duration;
152
208
  return _regeneratorRuntime().wrap(function _callee$(_context) {
153
209
  while (1) switch (_context.prev = _context.next) {
154
210
  case 0:
@@ -159,6 +215,24 @@ export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
159
215
  return _context.abrupt("return");
160
216
  case 2:
161
217
  startTime = performance.now();
218
+ if (!isSimpleConnection(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition)) {
219
+ _context.next = 9;
220
+ break;
221
+ }
222
+ perfStats.simplePathCalculations++;
223
+ _getSmoothStepPath = getSmoothStepPath({
224
+ sourceX: sourceX,
225
+ sourceY: sourceY,
226
+ sourcePosition: sourcePosition,
227
+ targetX: targetX,
228
+ targetY: targetY,
229
+ targetPosition: targetPosition
230
+ }), _getSmoothStepPath2 = _slicedToArray(_getSmoothStepPath, 1), smoothPath = _getSmoothStepPath2[0];
231
+ calculatedPath = smoothPath;
232
+ _context.next = 27;
233
+ break;
234
+ case 9:
235
+ // 复杂场景使用 Manhattan 算法
162
236
  params = {
163
237
  sourceNodeId: source,
164
238
  targetNodeId: target,
@@ -171,31 +245,31 @@ export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
171
245
  nodeLookup: nodeLookup
172
246
  }; // 尝试使用 Worker,失败则回退到主线程
173
247
  worker = getWorker();
174
- _context.prev = 5;
248
+ _context.prev = 11;
175
249
  if (!worker) {
176
- _context.next = 13;
250
+ _context.next = 19;
177
251
  break;
178
252
  }
179
253
  perfStats.workerCalculations++;
180
- _context.next = 10;
254
+ _context.next = 16;
181
255
  return worker.calculatePath(params);
182
- case 10:
256
+ case 16:
183
257
  calculatedPath = _context.sent;
184
- _context.next = 15;
258
+ _context.next = 21;
185
259
  break;
186
- case 13:
260
+ case 19:
187
261
  perfStats.mainThreadCalculations++;
188
262
  calculatedPath = getManHattanPath(params);
189
- case 15:
190
- _context.next = 21;
263
+ case 21:
264
+ _context.next = 27;
191
265
  break;
192
- case 17:
193
- _context.prev = 17;
194
- _context.t0 = _context["catch"](5);
266
+ case 23:
267
+ _context.prev = 23;
268
+ _context.t0 = _context["catch"](11);
195
269
  // Fallback 到主线程
196
270
  perfStats.mainThreadCalculations++;
197
271
  calculatedPath = getManHattanPath(params);
198
- case 21:
272
+ case 27:
199
273
  endTime = performance.now();
200
274
  duration = endTime - startTime; // 更新统计
201
275
  perfStats.completedEdges++;
@@ -220,18 +294,16 @@ export var ManhattanEdge = /*#__PURE__*/memo(function (_ref) {
220
294
  if (perfStats.completedEdges === perfStats.totalEdges) {
221
295
  logPerfStats();
222
296
  }
223
- case 30:
297
+ case 36:
224
298
  case "end":
225
299
  return _context.stop();
226
300
  }
227
- }, _callee, null, [[5, 17]]);
301
+ }, _callee, null, [[11, 23]]);
228
302
  }));
229
303
  return function calculatePath() {
230
304
  return _ref2.apply(this, arguments);
231
305
  };
232
306
  }();
233
-
234
- // 直接执行异步计算(Worker 已经是异步的)
235
307
  calculatePath();
236
308
  return function () {
237
309
  isMountedRef.current = false;
@@ -1,14 +1,40 @@
1
1
  /**
2
2
  * @author: yanxianliang
3
3
  * @date: 2025-10-15 15:25
4
- * @modified:2025/10/15 15:25 by yanxianliang
4
+ * @modified:2025/1/17 by yanxianliang
5
5
  * @desc: 创建 Flow 组件
6
6
  *
7
- * 提供公众能力封装
7
+ * 提供公共能力封装,支持双层 Props 存储
8
8
  *
9
9
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
10
10
  */
11
- import { IBaseFlowProps } from "../types";
11
+ import { Edge, Node } from "@xyflow/react";
12
12
  import React, { PropsWithChildren } from "react";
13
- export declare function createFlow<Props = IBaseFlowProps, ExtendProps = {}>(FlowComponent: React.ComponentType<IBaseFlowProps & ExtendProps>, usePropsTransform?: (props: PropsWithChildren<Props>) => PropsWithChildren<IBaseFlowProps & ExtendProps>): (props: React.PropsWithChildren<Props>) => import("react/jsx-runtime").JSX.Element;
13
+ import { IBaseFlowProps } from "../types";
14
+ /**
15
+ * 创建 Flow 组件的工厂函数
16
+ *
17
+ * @param FlowComponent - 基础 Flow 组件
18
+ * @param usePropsTransform - Props 转换 hook,将输入 props 转换为 Flow props
19
+ *
20
+ * @example
21
+ * // 基础用法
22
+ * const MyFlow = createFlow(Flow);
23
+ *
24
+ * @example
25
+ * // 带 props 转换
26
+ * const BloodlineFlow = createFlow<IBloodlineFlowProps, BloodlineExtendProps>(
27
+ * Flow,
28
+ * (props) => {
29
+ * const { root, nodeTypes } = props;
30
+ * const nodes = useMemo(() => root ? [root] : [], [root]);
31
+ * return {
32
+ * ...props,
33
+ * nodes,
34
+ * nodeTypes: wrapNodeTypes(nodeTypes, BaseNodeWrapper),
35
+ * };
36
+ * }
37
+ * );
38
+ */
39
+ export declare function createFlow<TInputProps = IBaseFlowProps, TExtendProps = {}, NodeType extends Node = Node, EdgeType extends Edge = Edge>(FlowComponent: React.ComponentType<IBaseFlowProps<NodeType, EdgeType> & TExtendProps>, usePropsTransform?: (props: PropsWithChildren<TInputProps>) => PropsWithChildren<IBaseFlowProps<NodeType, EdgeType> & TExtendProps>): (props: React.PropsWithChildren<TInputProps>) => import("react/jsx-runtime").JSX.Element;
14
40
  //# sourceMappingURL=createFlow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createFlow.d.ts","sourceRoot":"","sources":["createFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAGxC,OAAO,KAAK,EAAE,EAAC,iBAAiB,EAAC,MAAM,OAAO,CAAC;AA0B/C,wBAAgB,UAAU,CAAC,KAAK,GAAG,cAAc,EAAE,WAAW,GAAG,EAAE,EACjE,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,EAChE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,iBAAiB,CAAC,cAAc,GAAG,WAAW,CAAC,sFAwBzG"}
1
+ {"version":3,"file":"createFlow.d.ts","sourceRoot":"","sources":["createFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,EAAE,EAAC,iBAAiB,EAAC,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAwBxC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CACxB,WAAW,GAAG,cAAc,EAC5B,YAAY,GAAG,EAAE,EACjB,QAAQ,SAAS,IAAI,GAAG,IAAI,EAC5B,QAAQ,SAAS,IAAI,GAAG,IAAI,EAE5B,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,EACrF,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,KAAK,iBAAiB,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,4FA4BpI"}
@@ -1,4 +1,5 @@
1
- var _excluded = ["children"];
1
+ var _excluded = ["children"],
2
+ _excluded2 = ["children"];
2
3
  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); }
3
4
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
4
5
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
@@ -10,24 +11,28 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
10
11
  /**
11
12
  * @author: yanxianliang
12
13
  * @date: 2025-10-15 15:25
13
- * @modified:2025/10/15 15:25 by yanxianliang
14
+ * @modified:2025/1/17 by yanxianliang
14
15
  * @desc: 创建 Flow 组件
15
16
  *
16
- * 提供公众能力封装
17
+ * 提供公共能力封装,支持双层 Props 存储
17
18
  *
18
19
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
19
20
  */
20
21
 
21
22
  import { ConfigProvider } from "antd";
22
23
  import React from "react";
23
- import { useProps } from "../hooks/props/useProps";
24
+ import { useFlowProps } from "../hooks";
24
25
  import { PropsStore } from "../store/PropsStore";
25
26
  import { withFlowProvider } from "./withFlowProvider";
27
+
28
+ /**
29
+ * 内部组件:从 store 获取 props 并渲染 Flow
30
+ */
26
31
  import { jsx as _jsx } from "react/jsx-runtime";
27
- var RenderFlowWithProp = function RenderFlowWithProp(_ref) {
32
+ var RenderFlowWithProps = function RenderFlowWithProps(_ref) {
28
33
  var FlowComponent = _ref.FlowComponent,
29
34
  children = _ref.children;
30
- var props = useProps();
35
+ var props = useFlowProps();
31
36
  if (!props) {
32
37
  return null;
33
38
  }
@@ -36,31 +41,54 @@ var RenderFlowWithProp = function RenderFlowWithProp(_ref) {
36
41
  }));
37
42
  };
38
43
 
39
- // 不支持外部使用组件时自定义 Node类型,可以在使用 hooks 传入,hooks 会进行类型转换。
40
- // TODO 还可以技进行优化, Flow 的 props 怎么进行传入??如何支持布局,布局前对 props 转换再传入??? 属性传递还是要考虑清楚,属性构建,存储需要存储外面传进来的
44
+ /**
45
+ * 创建 Flow 组件的工厂函数
46
+ *
47
+ * @param FlowComponent - 基础 Flow 组件
48
+ * @param usePropsTransform - Props 转换 hook,将输入 props 转换为 Flow props
49
+ *
50
+ * @example
51
+ * // 基础用法
52
+ * const MyFlow = createFlow(Flow);
53
+ *
54
+ * @example
55
+ * // 带 props 转换
56
+ * const BloodlineFlow = createFlow<IBloodlineFlowProps, BloodlineExtendProps>(
57
+ * Flow,
58
+ * (props) => {
59
+ * const { root, nodeTypes } = props;
60
+ * const nodes = useMemo(() => root ? [root] : [], [root]);
61
+ * return {
62
+ * ...props,
63
+ * nodes,
64
+ * nodeTypes: wrapNodeTypes(nodeTypes, BaseNodeWrapper),
65
+ * };
66
+ * }
67
+ * );
68
+ */
41
69
  export function createFlow(FlowComponent, usePropsTransform) {
42
- // 支持外部在使用时自定义 NodeType,
70
+ // 创建包装后的组件
43
71
  return withFlowProvider(function (props) {
44
- var _props = props;
72
+ // 转换 props
73
+ var flowProps = props;
45
74
  if (usePropsTransform) {
46
- // 外部传入了 hook
47
- _props = usePropsTransform(props);
75
+ flowProps = usePropsTransform(props);
48
76
  }
49
- var _props2 = _props,
50
- children = _props2.children,
51
- others = _objectWithoutProperties(_props2, _excluded);
52
- // 外部的props,内置的,转换函数,转换之后的 props,支持转换函数
77
+ var _flowProps = flowProps,
78
+ children = _flowProps.children,
79
+ flowPropsWithoutChildren = _objectWithoutProperties(_flowProps, _excluded);
80
+ var inputChildren = props.children,
81
+ inputPropsWithoutChildren = _objectWithoutProperties(props, _excluded2);
53
82
  return /*#__PURE__*/_jsx(ConfigProvider, {
54
83
  prefixCls: 'rxflow',
55
84
  children: /*#__PURE__*/_jsx(PropsStore, {
56
- props: others,
57
- children: /*#__PURE__*/_jsx(RenderFlowWithProp, {
85
+ inputProps: inputPropsWithoutChildren,
86
+ flowProps: flowPropsWithoutChildren,
87
+ children: /*#__PURE__*/_jsx(RenderFlowWithProps, {
58
88
  FlowComponent: FlowComponent,
59
89
  children: children
60
90
  })
61
91
  })
62
92
  });
63
93
  });
64
-
65
- // hooks 直接绑定在 Flow 上,是不是更好,可以直接和传入的 nodeType 进行绑定。
66
94
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @author: yanxianliang
3
3
  * @date: 2025-07-02 21:07
4
+ * @modified:2025/1/17 by yanxianliang
4
5
  * @desc: export hooks
5
6
  *
6
7
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
@@ -11,12 +12,14 @@ export * from './useThemeVars';
11
12
  export * from './node/useNodeInitialize';
12
13
  export * from './node/useNodeTypeMap';
13
14
  export * from './useFlowId';
14
- export * from './props/usePropsSelector';
15
- export * from './props/useGetProps';
16
15
  export * from './node/useNodes';
17
16
  export * from './render/useForceUpdate';
18
17
  export * from './edges/useOnEdgesChange';
19
18
  export * from './state/useSetState';
20
19
  export * from './state/useGetState';
21
20
  export * from './state/useSelector';
21
+ export * from './props/useInputProps';
22
+ export * from './props/useFlowProps';
23
+ export * from './props/useGetInputProps';
24
+ export * from './props/useGetFlowProps';
22
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAEhC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAEhC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @author: yanxianliang
3
3
  * @date: 2025-07-02 21:07
4
+ * @modified:2025/1/17 by yanxianliang
4
5
  * @desc: export hooks
5
6
  *
6
7
  * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
@@ -12,11 +13,15 @@ export * from "./useThemeVars";
12
13
  export * from "./node/useNodeInitialize";
13
14
  export * from "./node/useNodeTypeMap";
14
15
  export * from "./useFlowId";
15
- export * from "./props/usePropsSelector";
16
- export * from "./props/useGetProps";
17
16
  export * from "./node/useNodes";
18
17
  export * from "./render/useForceUpdate";
19
18
  export * from "./edges/useOnEdgesChange";
20
19
  export * from "./state/useSetState";
21
20
  export * from "./state/useGetState";
22
- export * from "./state/useSelector";
21
+ export * from "./state/useSelector";
22
+
23
+ // Props hooks
24
+ export * from "./props/useInputProps";
25
+ export * from "./props/useFlowProps";
26
+ export * from "./props/useGetInputProps";
27
+ export * from "./props/useGetFlowProps";
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: Props hooks 导出
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+ export * from './useInputProps';
9
+ export * from './useFlowProps';
10
+ export * from './useGetInputProps';
11
+ export * from './useGetFlowProps';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: Props hooks 导出
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+
9
+ export * from "./useInputProps";
10
+ export * from "./useFlowProps";
11
+ export * from "./useGetInputProps";
12
+ export * from "./useGetFlowProps";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: 获取转换后的 Flow props(传给 Flow 组件的)
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+ import { IBaseFlowProps } from "../../types";
9
+ /**
10
+ * 获取转换后的 Flow props
11
+ *
12
+ * @example
13
+ * // 获取全部 flow props
14
+ * const flowProps = useFlowProps<IBaseFlowProps>();
15
+ *
16
+ * @example
17
+ * // 使用 selector 获取特定属性
18
+ * const nodes = useFlowProps(state => state.nodes);
19
+ * const theme = useFlowProps(state => state.theme);
20
+ */
21
+ export declare function useFlowProps<TFlowProps = IBaseFlowProps>(): TFlowProps;
22
+ export declare function useFlowProps<TFlowProps = IBaseFlowProps, U = unknown>(selector: (state: TFlowProps) => U): U;
23
+ //# sourceMappingURL=useFlowProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFlowProps.d.ts","sourceRoot":"","sources":["useFlowProps.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,UAAU,GAAG,cAAc,KAAK,UAAU,CAAC;AACxE,wBAAgB,YAAY,CAAC,UAAU,GAAG,cAAc,EAAE,CAAC,GAAG,OAAO,EACnE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,CAAC,GACjC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: 获取转换后的 Flow props(传给 Flow 组件的)
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+
9
+ import { useSelector } from "../state/useSelector";
10
+
11
+ /**
12
+ * 获取转换后的 Flow props
13
+ *
14
+ * @example
15
+ * // 获取全部 flow props
16
+ * const flowProps = useFlowProps<IBaseFlowProps>();
17
+ *
18
+ * @example
19
+ * // 使用 selector 获取特定属性
20
+ * const nodes = useFlowProps(state => state.nodes);
21
+ * const theme = useFlowProps(state => state.theme);
22
+ */
23
+
24
+ export function useFlowProps(selector) {
25
+ return useSelector(function (state) {
26
+ var flowProps = state.flowProps;
27
+ return selector ? selector(flowProps) : flowProps;
28
+ });
29
+ }
@@ -0,0 +1,19 @@
1
+ import { IBaseFlowProps } from "../../types";
2
+ /**
3
+ * 获取转换后 Flow props 的 getter 函数
4
+ * 用于在回调函数中获取最新的 props,避免闭包问题
5
+ *
6
+ * @example
7
+ * const getFlowProps = useGetFlowProps<IBaseFlowProps>();
8
+ *
9
+ * const handleClick = () => {
10
+ * const nodes = getFlowProps(state => state.nodes);
11
+ * // 或获取全部
12
+ * const allProps = getFlowProps();
13
+ * };
14
+ */
15
+ export declare const useGetFlowProps: <TFlowProps = IBaseFlowProps<import("@xyflow/react").Node, import("@xyflow/react").Edge>>() => {
16
+ (): TFlowProps;
17
+ <U>(selector: (state: TFlowProps) => U): U;
18
+ };
19
+ //# sourceMappingURL=useGetFlowProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGetFlowProps.d.ts","sourceRoot":"","sources":["useGetFlowProps.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe;QAGP,UAAU;0BACQ,UAAU,KAAK,CAAC,GAAG,CAAC;CAO1D,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: 获取转换后 Flow props 的 getter 函数(非响应式)
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+ import { useCallback } from "react";
9
+ import { useGetState } from "../state/useGetState";
10
+
11
+ /**
12
+ * 获取转换后 Flow props 的 getter 函数
13
+ * 用于在回调函数中获取最新的 props,避免闭包问题
14
+ *
15
+ * @example
16
+ * const getFlowProps = useGetFlowProps<IBaseFlowProps>();
17
+ *
18
+ * const handleClick = () => {
19
+ * const nodes = getFlowProps(state => state.nodes);
20
+ * // 或获取全部
21
+ * const allProps = getFlowProps();
22
+ * };
23
+ */
24
+ export var useGetFlowProps = function useGetFlowProps() {
25
+ var getState = useGetState();
26
+ function getter(selector) {
27
+ var flowProps = getState().flowProps;
28
+ return selector ? selector(flowProps) : flowProps;
29
+ }
30
+ return useCallback(getter, [getState]);
31
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 获取原始输入 props 的 getter 函数
3
+ * 用于在回调函数中获取最新的 props,避免闭包问题
4
+ *
5
+ * @example
6
+ * const getInputProps = useGetInputProps<IBloodlineFlowProps>();
7
+ *
8
+ * const handleClick = () => {
9
+ * const root = getInputProps(state => state.root);
10
+ * // 或获取全部
11
+ * const allProps = getInputProps();
12
+ * };
13
+ */
14
+ export declare const useGetInputProps: <TInputProps = Record<string, any>>() => {
15
+ (): TInputProps;
16
+ <U>(selector: (state: TInputProps) => U): U;
17
+ };
18
+ //# sourceMappingURL=useGetInputProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGetInputProps.d.ts","sourceRoot":"","sources":["useGetInputProps.ts"],"names":[],"mappings":"AAWA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;QAGR,WAAW;0BACO,WAAW,KAAK,CAAC,GAAG,CAAC;CAO3D,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @author: yanxianliang
3
+ * @date: 2025-01-17
4
+ * @desc: 获取原始输入 props 的 getter 函数(非响应式)
5
+ *
6
+ * Copyright (c) 2025 by yanxianliang, All Rights Reserved.
7
+ */
8
+ import { useCallback } from "react";
9
+ import { useGetState } from "../state/useGetState";
10
+
11
+ /**
12
+ * 获取原始输入 props 的 getter 函数
13
+ * 用于在回调函数中获取最新的 props,避免闭包问题
14
+ *
15
+ * @example
16
+ * const getInputProps = useGetInputProps<IBloodlineFlowProps>();
17
+ *
18
+ * const handleClick = () => {
19
+ * const root = getInputProps(state => state.root);
20
+ * // 或获取全部
21
+ * const allProps = getInputProps();
22
+ * };
23
+ */
24
+ export var useGetInputProps = function useGetInputProps() {
25
+ var getState = useGetState();
26
+ function getter(selector) {
27
+ var inputProps = getState().inputProps;
28
+ return selector ? selector(inputProps) : inputProps;
29
+ }
30
+ return useCallback(getter, [getState]);
31
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 获取原始输入 props
3
+ *
4
+ * @example
5
+ * // 获取全部原始 props
6
+ * const inputProps = useInputProps<IBloodlineFlowProps>();
7
+ *
8
+ * @example
9
+ * // 使用 selector 获取特定属性
10
+ * const root = useInputProps<IBloodlineFlowProps, BaseBloodNode>(state => state.root);
11
+ */
12
+ export declare function useInputProps<TInputProps = Record<string, any>>(): TInputProps;
13
+ export declare function useInputProps<TInputProps = Record<string, any>, U = unknown>(selector: (state: TInputProps) => U): U;
14
+ //# sourceMappingURL=useInputProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInputProps.d.ts","sourceRoot":"","sources":["useInputProps.ts"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,WAAW,CAAC;AAChF,wBAAgB,aAAa,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAC1E,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,CAAC,GAClC,CAAC,CAAC"}