@digitalsee-ai/rcs 2.0.0-beta5 → 2.0.0-beta8

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.
@@ -71,3 +71,27 @@ export declare function getSelfLoopPath(params: SelfLoopPathParams): {
71
71
  labelX: number;
72
72
  labelY: number;
73
73
  };
74
+ export interface LoopBackPathParams {
75
+ sourceX: number;
76
+ sourceY: number;
77
+ sourcePosition: Position | undefined;
78
+ targetX: number;
79
+ targetY: number;
80
+ targetPosition: Position | undefined;
81
+ /** 圆角半径(透传 EDGE_BORDER_RADIUS) */
82
+ borderRadius: number;
83
+ }
84
+ /**
85
+ * 生成多节点回环边的路径:绕到链路下方走大 U 形,避免与中间节点/边交叉。
86
+ *
87
+ * 与自环不同,多节点回环两端距离远、中间隔着整条链路的节点,
88
+ * SmoothStep 的 centerY 水平段会穿过节点形成 8 字交叉。
89
+ * 本函数强制走"下方 U 形":source 端先向开口方向伸出 L 再向下绕、
90
+ * target 端先向开口方向伸出 L 再向上收,中间水平段在所有节点下方
91
+ * (source 下绕、target 上绕,两端反向错开,不与链路同高交叉)。
92
+ */
93
+ export declare function getLoopBackPath(params: LoopBackPathParams): {
94
+ edgePath: string;
95
+ labelX: number;
96
+ labelY: number;
97
+ };
@@ -1,5 +1,5 @@
1
1
  import { NodeAddInfo } from '../types/NodeAddContext';
2
- import { Node } from '@xyflow/react';
2
+ import { Edge, Node } from '@xyflow/react';
3
3
  interface HandleExtenderVisibilityOptions {
4
4
  type: 'source' | 'target';
5
5
  handleId?: string;
@@ -28,16 +28,24 @@ interface SelfConnectionDragOptions {
28
28
  type: string;
29
29
  } | null;
30
30
  fromNode: Node | null;
31
+ toHandle?: {
32
+ id?: string | null;
33
+ nodeId: string;
34
+ type: string;
35
+ } | null;
36
+ toNode?: Node | null;
31
37
  };
32
38
  nodeId: string;
33
39
  handleId: string;
34
40
  }
35
41
  /**
36
- * 判断进行中的拖线是否为"本节点自身输出桩发起、且 (sourceHandle -> handleId)
37
- * 命中 auto_connect 声明"的自连。命中时满载 target 桩临时解除禁用
38
- * (自连不占 maxConnections 名额),拖线结束(成功/取消)后自动恢复。
42
+ * 判断进行中的拖线是否为允许突破 maxConnections 限制的回环类连线:
43
+ * 1. 本节点自身输出桩发起、且 (sourceHandle -> handleId) 命中 auto_connect 声明的自连;
44
+ * 2. 多节点回环:fromHandle.nodeId 的祖先链上含 toHandle.nodeId,
45
+ * 新边闭合环路(回环连线不计入连线次数限制)。
46
+ * 命中时满载 target 桩临时解除禁用,拖线结束(成功/取消)后自动恢复。
39
47
  */
40
- export declare function isAllowedSelfConnectionInProgress(options: SelfConnectionDragOptions): boolean;
48
+ export declare function isAllowedSelfConnectionInProgress(options: SelfConnectionDragOptions, currentEdges: Edge[]): boolean;
41
49
  interface BuildHandleNodeAddInfoOptions {
42
50
  type: 'source' | 'target';
43
51
  nodeId: string;
@@ -1,4 +1,4 @@
1
- import { ActionItem, LinkSearchParams, ModernNodeSelectorProps, NodeFetchResult, NodeTypeItem } from '../types';
1
+ import { ActionItem, LinkSearchParams, ModernNodeSelectorProps, NodeTypeItem } from '../types';
2
2
  import { NodeAddInfo } from '../../../types/NodeAddContext';
3
3
  type SearchHandler = NonNullable<ModernNodeSelectorProps['onSearch']>;
4
4
  type CategoryHandler = NonNullable<ModernNodeSelectorProps['onFetchCategories']>;
@@ -21,9 +21,9 @@ interface UseConnectableNodeSelectorProps {
21
21
  export declare function useConnectableNodeSelector({ nodeSelectorVisible, effectiveNodeAddInfo, workflowId, onSearch, onFetchCategories, onFetchNodesByCategory, }: UseConnectableNodeSelectorProps): {
22
22
  actionRequestContextKey: string;
23
23
  connectableContext: import('../utils/connectableQuery').ConnectableQueryContext;
24
- onSearch: (params?: LinkSearchParams) => Promise<NodeFetchResult>;
24
+ onSearch: (params?: LinkSearchParams) => Promise<import('../types').NodeFetchResult>;
25
25
  onFetchCategories: (type?: import('../types').CategoryRequestType) => Promise<import('../types').CategoryItem[]>;
26
- onFetchNodesByCategory: (params?: LinkSearchParams) => Promise<NodeFetchResult>;
26
+ onFetchNodesByCategory: (params?: LinkSearchParams) => Promise<import('../types').NodeFetchResult>;
27
27
  fetchNodeActions: (node: NodeTypeItem, _options?: FetchNodeActionOptions) => Promise<ActionItem[]>;
28
28
  };
29
29
  export {};
@@ -161,6 +161,7 @@ export declare const canvasGeometry: {
161
161
  HANDLE_SIZE: number;
162
162
  SELF_LOOP_EXIT_OFFSET: number;
163
163
  SELF_LOOP_DEPTH: number;
164
+ SELF_LOOP_TIP_OFFSET: number;
164
165
  };
165
166
  export declare const connectionRules: {
166
167
  undeletableEdgeTargetTypes: NodeType[];
@@ -3,8 +3,10 @@ import { Edge } from '@xyflow/react';
3
3
  /**
4
4
  * 过滤指定 Handle 上的边,用于 maxConnections 计数。
5
5
  *
6
- * 自环边(source === target,如 LOOP loop -> input)不占 target 桩的
7
- * maxConnections 名额;handleStatus 仍将其视为已连接样式。
6
+ * 回环类连线不占 target 桩的 maxConnections 名额:
7
+ * 1. 自环边(source === target,如 LOOP 的 loop -> input);
8
+ * 2. 多节点回环边(源节点位于本节点下游,即存在 本节点 -> ... -> 源节点 通路)。
9
+ * handleStatus 仍将其视为已连接样式。
8
10
  */
9
11
  export declare const filterHandleConnections: (edges: readonly Edge[], nodeId: string, handleId: string, handleType: HandleDirection) => Edge[];
10
12
  export declare function useHandleConnections(): {
@@ -32,18 +32,34 @@ export declare const panelSlice: import('@reduxjs/toolkit').Slice<PanelState, {
32
32
  };
33
33
  };
34
34
  sourceNode?: {
35
+ position: {
36
+ x: number;
37
+ y: number;
38
+ };
35
39
  data: {
36
40
  [x: string]: unknown;
37
41
  };
38
42
  id: string;
39
43
  type?: string;
44
+ measured?: {
45
+ width?: number;
46
+ height?: number;
47
+ };
40
48
  };
41
49
  targetNode?: {
50
+ position: {
51
+ x: number;
52
+ y: number;
53
+ };
42
54
  data: {
43
55
  [x: string]: unknown;
44
56
  };
45
57
  id: string;
46
58
  type?: string;
59
+ measured?: {
60
+ width?: number;
61
+ height?: number;
62
+ };
47
63
  };
48
64
  trigger?: boolean;
49
65
  protocol?: string;
@@ -75,18 +91,34 @@ export declare const panelSlice: import('@reduxjs/toolkit').Slice<PanelState, {
75
91
  };
76
92
  };
77
93
  sourceNode?: {
94
+ position: {
95
+ x: number;
96
+ y: number;
97
+ };
78
98
  data: {
79
99
  [x: string]: unknown;
80
100
  };
81
101
  id: string;
82
102
  type?: string;
103
+ measured?: {
104
+ width?: number;
105
+ height?: number;
106
+ };
83
107
  };
84
108
  targetNode?: {
109
+ position: {
110
+ x: number;
111
+ y: number;
112
+ };
85
113
  data: {
86
114
  [x: string]: unknown;
87
115
  };
88
116
  id: string;
89
117
  type?: string;
118
+ measured?: {
119
+ width?: number;
120
+ height?: number;
121
+ };
90
122
  };
91
123
  trigger?: boolean;
92
124
  protocol?: string;
@@ -118,18 +150,34 @@ export declare const panelSlice: import('@reduxjs/toolkit').Slice<PanelState, {
118
150
  };
119
151
  };
120
152
  sourceNode?: {
153
+ position: {
154
+ x: number;
155
+ y: number;
156
+ };
121
157
  data: {
122
158
  [x: string]: unknown;
123
159
  };
124
160
  id: string;
125
161
  type?: string;
162
+ measured?: {
163
+ width?: number;
164
+ height?: number;
165
+ };
126
166
  };
127
167
  targetNode?: {
168
+ position: {
169
+ x: number;
170
+ y: number;
171
+ };
128
172
  data: {
129
173
  [x: string]: unknown;
130
174
  };
131
175
  id: string;
132
176
  type?: string;
177
+ measured?: {
178
+ width?: number;
179
+ height?: number;
180
+ };
133
181
  };
134
182
  trigger?: boolean;
135
183
  protocol?: string;
@@ -161,18 +209,34 @@ export declare const panelSlice: import('@reduxjs/toolkit').Slice<PanelState, {
161
209
  };
162
210
  };
163
211
  sourceNode?: {
212
+ position: {
213
+ x: number;
214
+ y: number;
215
+ };
164
216
  data: {
165
217
  [x: string]: unknown;
166
218
  };
167
219
  id: string;
168
220
  type?: string;
221
+ measured?: {
222
+ width?: number;
223
+ height?: number;
224
+ };
169
225
  };
170
226
  targetNode?: {
227
+ position: {
228
+ x: number;
229
+ y: number;
230
+ };
171
231
  data: {
172
232
  [x: string]: unknown;
173
233
  };
174
234
  id: string;
175
235
  type?: string;
236
+ measured?: {
237
+ width?: number;
238
+ height?: number;
239
+ };
176
240
  };
177
241
  trigger?: boolean;
178
242
  protocol?: string;
@@ -1,6 +1,6 @@
1
1
  import { Node } from '@xyflow/react';
2
2
  /** 节点选择器只需保留 MCP 判定需要的轻量锚点信息,避免 Redux 声明泄漏 ReactFlow 样式类型。 */
3
- export type NodeAddAnchorNode = Pick<Node, 'id' | 'type' | 'data'>;
3
+ export type NodeAddAnchorNode = Pick<Node, 'id' | 'type' | 'data' | 'position' | 'measured'>;
4
4
  /** 边上插入节点时保留的原边上下文。 */
5
5
  export interface NodeAddEdgeContext {
6
6
  id: string;
@@ -0,0 +1,12 @@
1
+ import { Edge } from '@xyflow/react';
2
+ /**
3
+ * 判断 fromNodeId -> toNodeId 的连线是否会形成回环。
4
+ *
5
+ * 从 fromNodeId 出发沿入边(edge.target === current)向上遍历祖先链:
6
+ * - 途中遇到 toNodeId,说明已存在 toNodeId -> ... -> fromNodeId 的通路,
7
+ * 新边将闭合环路,返回 true;
8
+ * - 遍历到根(无入边)仍未遇到,返回 false。
9
+ *
10
+ * 用 visited 集合防止图中已有环导致死循环。
11
+ */
12
+ export declare function isLoopEdgeLine(fromNodeId: string, toNodeId: string, edges: Edge[]): boolean;
@@ -1,8 +1,8 @@
1
1
  import { jsx as t, jsxs as v } from "react/jsx-runtime";
2
- import { D as T, V as L, e as x, i as P, t as l, f as R, d as O } from "./index-BmQBE_IZ.mjs";
3
- import { useEventEmitter as B, useReactive as W, useSize as A } from "ahooks";
2
+ import { D as T, V as L, e as x, i as P, t as l, f as R, d as O } from "./index-DJvNGsCf.mjs";
3
+ import { useEventEmitter as B, useReactive as W, useSize as H } from "ahooks";
4
4
  import { FormattedMessage as I } from "react-intl";
5
- import { CloseCircleFilled as H, CheckCircleFilled as K } from "@ant-design/icons";
5
+ import { CloseCircleFilled as A, CheckCircleFilled as K } from "@ant-design/icons";
6
6
  import { Button as M } from "antd";
7
7
  import * as z from "monaco-editor";
8
8
  import { useRef as k, useEffect as N } from "react";
@@ -26,10 +26,7 @@ const G = "_modalContainer_8inkd_5", Q = "_editorContainer_8inkd_16", U = "_side
26
26
  siderContainer: ie
27
27
  };
28
28
  function re(e) {
29
- return /* @__PURE__ */ v("div", { className: oe.siderContainer, children: [
30
- /* @__PURE__ */ t("div", { children: /* @__PURE__ */ t(te, { open: e.open, nodeId: e.nodeId, onInsert: e.onInsert }) }),
31
- /* @__PURE__ */ t("div", { style: { textAlign: "center" } })
32
- ] });
29
+ return /* @__PURE__ */ t("div", { className: oe.siderContainer, children: /* @__PURE__ */ t(te, { open: e.open, nodeId: e.nodeId, onInsert: e.onInsert }) });
33
30
  }
34
31
  function se({ language: e = "javascript" }) {
35
32
  return /* @__PURE__ */ v("h2", { id: "workflow-online-ide-title", className: "workflow-online-ide-title", children: [
@@ -39,7 +36,7 @@ function se({ language: e = "javascript" }) {
39
36
  }
40
37
  function ae(e) {
41
38
  return /* @__PURE__ */ v("div", { className: "workflow-online-ide-toolbar", children: [
42
- /* @__PURE__ */ t(M, { size: "small", onClick: e.onCancel, icon: /* @__PURE__ */ t(H, {}), children: /* @__PURE__ */ t(I, { id: "app.common.word.cancel" }) }),
39
+ /* @__PURE__ */ t(M, { size: "small", onClick: e.onCancel, icon: /* @__PURE__ */ t(A, {}), children: /* @__PURE__ */ t(I, { id: "app.common.word.cancel" }) }),
43
40
  /* @__PURE__ */ t(M, { type: "primary", size: "small", onClick: e.onFinish, icon: /* @__PURE__ */ t(K, {}), children: /* @__PURE__ */ t(I, { id: "app.common.word.finish" }) })
44
41
  ] });
45
42
  }
@@ -114,7 +111,7 @@ function V(e, i) {
114
111
  u.length !== a.length && e.editor.setModelMarkers(i, d, u.map(ge));
115
112
  });
116
113
  }
117
- function fe(e, i) {
114
+ function pe(e, i) {
118
115
  const o = [].map((c) => ({
119
116
  insertText: c,
120
117
  kind: e.languages.CompletionItemKind.Function,
@@ -133,7 +130,7 @@ function fe(e, i) {
133
130
  // 触发提示的字符 可以定义多个
134
131
  });
135
132
  }
136
- function pe(e) {
133
+ function fe(e) {
137
134
  return e.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
138
135
  noSemanticValidation: !0,
139
136
  noSyntaxValidation: !1
@@ -157,20 +154,20 @@ function Ie(e) {
157
154
  code: "",
158
155
  range: new z.Range(1, 1, 1, 1)
159
156
  }), b = (n, r) => {
160
- n.onDidChangeCursorPosition((f) => {
161
- const m = f.position, { lineNumber: p = 0, column: C = 0 } = m;
162
- g.range = new r.Range(p, C, p, C);
157
+ n.onDidChangeCursorPosition((p) => {
158
+ const m = p.position, { lineNumber: f = 0, column: C = 0 } = m;
159
+ g.range = new r.Range(f, C, f, C);
163
160
  }), d.current = n, n.focus(), g.code = n.getValue();
164
161
  const j = r.languages.registerHoverProvider(s, {
165
- provideHover: (f, m) => new Promise((p) => {
166
- const h = x(f.getValue()).find(
162
+ provideHover: (p, m) => new Promise((f) => {
163
+ const h = x(p.getValue()).find(
167
164
  (F) => P(F, m.lineNumber, m.column)
168
165
  );
169
166
  if (!h) {
170
- p(null);
167
+ f(null);
171
168
  return;
172
169
  }
173
- p({
170
+ f({
174
171
  range: new r.Range(
175
172
  h.startLine,
176
173
  h.startColumn,
@@ -182,13 +179,13 @@ function Ie(e) {
182
179
  })
183
180
  }), _ = n.getModel();
184
181
  if (_) {
185
- let f = !1;
186
- const m = r.editor.onDidChangeMarkers((p) => {
187
- f || !p.some((C) => C.toString() === _.uri.toString()) || (f = !0, window.setTimeout(() => {
182
+ let p = !1;
183
+ const m = r.editor.onDidChangeMarkers((f) => {
184
+ p || !f.some((C) => C.toString() === _.uri.toString()) || (p = !0, window.setTimeout(() => {
188
185
  try {
189
186
  V(r, _);
190
187
  } finally {
191
- f = !1;
188
+ p = !1;
192
189
  }
193
190
  }, 0));
194
191
  });
@@ -198,7 +195,7 @@ function Ie(e) {
198
195
  }, E = (n) => {
199
196
  u.current.forEach((r) => {
200
197
  r.dispose();
201
- }), u.current = [fe(n, s)], s === "javascript" && u.current.push(pe(n));
198
+ }), u.current = [pe(n, s)], s === "javascript" && u.current.push(fe(n));
202
199
  };
203
200
  N(
204
201
  () => () => {
@@ -227,7 +224,7 @@ function Ie(e) {
227
224
  }, $ = () => {
228
225
  var n;
229
226
  (n = e.onFinish) == null || n.call(e, g.code);
230
- }, D = k(null), y = A(D);
227
+ }, D = k(null), y = H(D);
231
228
  return q(
232
229
  /* @__PURE__ */ t(
233
230
  "div",
@@ -239,7 +236,7 @@ function Ie(e) {
239
236
  "aria-modal": "true",
240
237
  "aria-labelledby": "workflow-online-ide-title",
241
238
  children: /* @__PURE__ */ v("div", { className: w.editorContainer, id: "javascript-code-editor", children: [
242
- a ? /* @__PURE__ */ t("div", { className: w.sider, children: /* @__PURE__ */ t(
239
+ a ? /* @__PURE__ */ t("div", { className: w.sider, style: { maxWidth: "20%", padding: 0 }, children: /* @__PURE__ */ t(
243
240
  re,
244
241
  {
245
242
  onCancel: e.onCancel,
@@ -282,4 +279,4 @@ function Ie(e) {
282
279
  export {
283
280
  Ie as default
284
281
  };
285
- //# sourceMappingURL=index-BsVgIib3.mjs.map
282
+ //# sourceMappingURL=index-DBoa8kIP.mjs.map