@digitalsee-ai/rcs 2.0.4-beta6 → 2.0.4-rc3

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.
@@ -8,15 +8,10 @@ import { useWorkflow } from '../../hooks/useWorkflow';
8
8
  import { useAppDispatch } from '../../store';
9
9
  import { CanvasAPI, EdgeConfig as EngineEdgeConfig } from '../../types/engine';
10
10
  import { FlowDraftPayload } from '../../types/flowVersion';
11
+ import { TriggerNodeInfo } from '../../utils/triggerNode';
11
12
  import { Connection, Edge, EdgeChange, Node, NodeChange, useEdgesState, useNodesState, useReactFlow, useStoreApi } from '@xyflow/react';
12
13
  import { default as React } from 'react';
13
- /** 当前画布 trigger 节点信息;一个画布最多一个 trigger,记录它即可推导画布级状态。 */
14
- export interface TriggerNodeInfo {
15
- /** trigger 节点 id */
16
- id: string;
17
- /** 是否为 MCP Server 触发画布(trigger 节点的 action_key 指向 MCP Server) */
18
- isMcpServer: boolean;
19
- }
14
+ export type { TriggerNodeInfo } from '../../utils/triggerNode';
20
15
  export interface WorkflowCanvasStateResult {
21
16
  nodes: Node[];
22
17
  edges: Edge[];
@@ -0,0 +1,26 @@
1
+ import { ViewPlugin } from '@codemirror/view';
2
+ /** {{变量}} 高亮的 class 名,便于调试定位与外部样式覆盖 */
3
+ export declare const VARIABLE_HIGHLIGHT_CLASS = "workflow-code-variable";
4
+ /**
5
+ * 匹配带路径的节点变量 {{N节点ID.字段}}、全局变量 {{global.x}} 以及内置变量
6
+ * {{sys_tenant_id}} / {{response}},不把任意 {{...}} 当作变量。
7
+ */
8
+ export declare const buildVariableRegExp: () => RegExp;
9
+ /**
10
+ * 变量在编辑器中的展示文本:隐藏 {{global. 与 {{N节点ID. 前缀,只保留字段路径。
11
+ * 例如 {{global.userName}} -> {{userName}},{{ N1.profile.name }} -> {{profile.name}}。
12
+ */
13
+ export declare const buildVariableDisplayText: (raw: string) => string;
14
+ /**
15
+ * 给 CodeMirror 加 {{变量}} 高亮,并把变量块声明成原子区间。
16
+ *
17
+ * 结构与 JavascriptTagEditorField 的 placeholdersPlugin 保持一致:
18
+ * - 展示:用 replace 装饰把变量渲染成 {{字段路径}},隐藏 global. / N节点ID. 前缀,
19
+ * 不改变文档内容,复制、悬停提示与提交时仍是完整变量;
20
+ * - 原子区间:光标无法停在块中间(点击/方向键都落到块边界),选区端点也不会切进块内,
21
+ * 因此鼠标框选、双击与 Backspace/Delete 都是整块选中、整块删除。
22
+ *
23
+ * 做成工厂函数(同 placeholdersPlugin)是为了让每个编辑器实例持有独立的
24
+ * MatchDecorator 与正则实例,避免正则 lastIndex 在多实例间共享。
25
+ */
26
+ export declare const variableHighlightPlugin: () => ViewPlugin<any, undefined>;
@@ -1,3 +1,4 @@
1
1
  import { ViewPlugin } from '@codemirror/view';
2
2
  import { PlaceholderThemesType } from '../interface';
3
+ export declare const buildPlaceholderRegExp: () => RegExp;
3
4
  export declare const placeholdersPlugin: (themes: PlaceholderThemesType, mode?: string) => ViewPlugin<any, undefined>;
@@ -15,6 +15,7 @@ interface TextFieldProps extends IFieldSuperProps {
15
15
  lang?: CodeEditorLanguage;
16
16
  onFocus?: () => void;
17
17
  onBlur?: () => void;
18
+ required?: boolean;
18
19
  }
19
20
  export declare const TextField: (props: TextFieldProps) => import("react/jsx-runtime").JSX.Element;
20
21
  export {};
@@ -1,5 +1,12 @@
1
1
  import { Node } from '@xyflow/react';
2
- type TriggerCandidate = Pick<Node, 'type'> & Partial<Pick<Node, 'data'>>;
2
+ type TriggerCandidate = Pick<Node, 'type' | 'id'> & Partial<Pick<Node, 'data'>>;
3
+ /** 当前画布 trigger 节点信息;一个画布最多一个 trigger,记录它即可推导画布级状态。 */
4
+ export interface TriggerNodeInfo {
5
+ /** trigger 节点 id */
6
+ id: string;
7
+ /** 是否为 MCP Server 触发画布(trigger 节点的 action_key 指向 MCP Server) */
8
+ isMcpServer: boolean;
9
+ }
3
10
  /**
4
11
  * 判断节点是否为 Trigger 节点。
5
12
  *
@@ -10,4 +17,11 @@ type TriggerCandidate = Pick<Node, 'type'> & Partial<Pick<Node, 'data'>>;
10
17
  * 一个画布最多只有一个 trigger 节点,因此画布级推导只需记录该节点信息即可。
11
18
  */
12
19
  export declare const isTriggerNode: (node?: TriggerCandidate | null) => boolean;
20
+ /**
21
+ * 从节点列表解析画布级 trigger 信息。
22
+ *
23
+ * 一个画布最多只有一个 trigger,因此找到第一个即可;`null` 表示当前画布没有 trigger。
24
+ * 抽成纯函数便于覆盖“新增/删除 trigger 后画布状态”的回归用例。
25
+ */
26
+ export declare const findTriggerNodeInfo: (nodes: readonly TriggerCandidate[]) => TriggerNodeInfo | null;
13
27
  export {};
@@ -56,6 +56,8 @@ export interface ValueModeWrapperProps {
56
56
  onFocus?: () => void;
57
57
  /** 失去焦点时的回调 */
58
58
  onBlur?: () => void;
59
+ /** 用户通过输入控件改值时的回调(外部程序化写值不会触发) */
60
+ onUserEdit?: (value: string) => void;
59
61
  /** 自定义渲染普通模式的组件 */
60
62
  renderNormalMode?: (props: {
61
63
  value?: string;
@@ -84,6 +86,8 @@ export interface ValueModeWrapperProps {
84
86
  * 代码编辑器语言(json / javascript)
85
87
  */
86
88
  lang?: CodeEditorLanguage;
89
+ /** 是否必填 */
90
+ required?: boolean;
87
91
  }
88
92
  export declare const ValueModeWrapper: React.FC<ValueModeWrapperProps>;
89
93
  export default ValueModeWrapper;
@@ -66,6 +66,8 @@ export interface FieldComponentProps<T extends FieldDef = FieldDef, K = unknown>
66
66
  onChange?: (value: unknown) => void;
67
67
  /** 字段 ID(由 Form.Item 注入) */
68
68
  id?: string;
69
+ /** 是否必填 */
70
+ required?: boolean;
69
71
  }
70
72
  /**
71
73
  * 字段组件元数据
@@ -0,0 +1,167 @@
1
+ import { jsx as e, jsxs as l } from "react/jsx-runtime";
2
+ import { D as N, V as $, f as S, a as D, v as F, R as M, g as V, j as R, b as W, s as B } from "./index-C5Zcv_fc.mjs";
3
+ import { useEventEmitter as G, useSize as L } from "ahooks";
4
+ import { FormattedMessage as f } from "react-intl";
5
+ import { CloseCircleFilled as A, CheckCircleFilled as P } from "@ant-design/icons";
6
+ import { Button as k } from "antd";
7
+ import { useRef as y, useMemo as T, useCallback as g, useEffect as z } from "react";
8
+ import { createPortal as H } from "react-dom";
9
+ const K = "_ideWrapper_sfar6_1", O = {
10
+ ideWrapper: K
11
+ }, U = (n) => {
12
+ const { nodeId: i, onInsert: o, open: d } = n, a = G();
13
+ return a.useSubscription((c) => {
14
+ c.type === "insert" && o(c.expression);
15
+ }), /* @__PURE__ */ e(N.Provider, { value: { event$: a }, children: /* @__PURE__ */ e("div", { className: O.ideWrapper, children: /* @__PURE__ */ e($, { nodeId: i, onInsert: o, open: d }) }) });
16
+ }, q = "_siderContainer_fhkbn_1", J = {
17
+ siderContainer: q
18
+ };
19
+ function Q(n) {
20
+ return /* @__PURE__ */ e("div", { className: J.siderContainer, children: /* @__PURE__ */ e(U, { open: n.open, nodeId: n.nodeId, onInsert: n.onInsert }) });
21
+ }
22
+ const X = {
23
+ javascript: "link.flow.code_editor_language_javascript",
24
+ json: "link.flow.code_editor_language_json"
25
+ };
26
+ function Y({ language: n = "javascript" }) {
27
+ return /* @__PURE__ */ l("h2", { id: "workflow-online-ide-title", className: "workflow-online-ide-title", children: [
28
+ /* @__PURE__ */ e(f, { id: "link.flow.code_editor" }),
29
+ " (",
30
+ /* @__PURE__ */ e(f, { id: X[n] }),
31
+ ")"
32
+ ] });
33
+ }
34
+ function Z(n) {
35
+ return /* @__PURE__ */ l("div", { className: "workflow-online-ide-toolbar", children: [
36
+ /* @__PURE__ */ e(k, { size: "small", onClick: n.onCancel, icon: /* @__PURE__ */ e(A, {}), children: /* @__PURE__ */ e(f, { id: "app.common.word.cancel" }) }),
37
+ /* @__PURE__ */ e(k, { type: "primary", size: "small", onClick: n.onFinish, icon: /* @__PURE__ */ e(P, {}), children: /* @__PURE__ */ e(f, { id: "app.common.word.finish" }) })
38
+ ] });
39
+ }
40
+ const ee = [{ trigger: "log", content: "console.log('$1');$2", desc: "输出日志" }, { trigger: "imp", content: "import $1 from '$2';$3" }, { trigger: "loop", content: `for (let $1=0; i< $2.length;i++) {
41
+
42
+ }`, desc: "循环操作" }], ne = {
43
+ snippets: ee
44
+ }, oe = "_modalContainer_1ajlo_5", ie = "_editorContainer_1ajlo_16", te = "_sider_1ajlo_25", re = "_main_1ajlo_34", ae = "_header_1ajlo_40", se = "_editor_1ajlo_16", s = {
45
+ modalContainer: oe,
46
+ editorContainer: ie,
47
+ sider: te,
48
+ main: re,
49
+ header: ae,
50
+ editor: se
51
+ }, le = (n) => n === "javascript" ? [R()] : [W()], de = (n) => {
52
+ const i = n.matchBefore(/[\w$]*/);
53
+ return !i || i.from === i.to && !n.explicit ? null : {
54
+ from: i.from,
55
+ options: ne.snippets.map(
56
+ (o) => B(o.content, {
57
+ label: o.trigger,
58
+ detail: o.desc
59
+ })
60
+ )
61
+ };
62
+ };
63
+ function _e(n) {
64
+ var j;
65
+ const {
66
+ initialValue: i = "",
67
+ language: o = "javascript",
68
+ nodeId: d,
69
+ onCancel: a,
70
+ onChange: c,
71
+ onFinish: v,
72
+ open: m,
73
+ showVariableSidebar: E = !0
74
+ } = n, p = y(null), _ = y(null), u = L(_), x = T(
75
+ () => [
76
+ ...le(o),
77
+ ...o === "javascript" ? [D({ override: [de] })] : [],
78
+ F(),
79
+ S
80
+ ],
81
+ [o]
82
+ ), I = g((r) => {
83
+ var b;
84
+ const t = (b = p.current) == null ? void 0 : b.view;
85
+ if (!t)
86
+ return;
87
+ const h = t.state.selection.main;
88
+ t.dispatch({
89
+ changes: {
90
+ from: h.from,
91
+ to: h.to,
92
+ insert: r
93
+ },
94
+ selection: {
95
+ anchor: h.from + r.length
96
+ }
97
+ }), t.focus();
98
+ }, []), w = g(
99
+ () => {
100
+ var r, t;
101
+ return ((t = (r = p.current) == null ? void 0 : r.view) == null ? void 0 : t.state.doc.toString()) ?? i;
102
+ },
103
+ [i]
104
+ ), C = g(() => {
105
+ v(w());
106
+ }, [w, v]);
107
+ return z(() => {
108
+ if (!m)
109
+ return;
110
+ const r = (t) => {
111
+ t.key === "Escape" && (t.preventDefault(), a());
112
+ };
113
+ return window.addEventListener("keydown", r), () => window.removeEventListener("keydown", r);
114
+ }, [a, m]), H(
115
+ /* @__PURE__ */ e(
116
+ "div",
117
+ {
118
+ className: s.modalContainer,
119
+ ref: _,
120
+ style: { display: m ? "flex" : "none" },
121
+ role: "dialog",
122
+ "aria-modal": "true",
123
+ "aria-labelledby": "workflow-online-ide-title",
124
+ children: /* @__PURE__ */ l("div", { className: s.editorContainer, id: "javascript-code-editor", children: [
125
+ E ? /* @__PURE__ */ e("div", { className: s.sider, style: { maxWidth: "20%", padding: 0 }, children: /* @__PURE__ */ e(
126
+ Q,
127
+ {
128
+ onCancel: a,
129
+ onFinish: C,
130
+ editor: (j = p.current) == null ? void 0 : j.view,
131
+ nodeId: d ?? "",
132
+ open: !!m,
133
+ onInsert: I
134
+ }
135
+ ) }) : null,
136
+ /* @__PURE__ */ l("div", { className: s.main, children: [
137
+ /* @__PURE__ */ l("div", { className: s.header, children: [
138
+ /* @__PURE__ */ e(Y, { language: o }),
139
+ /* @__PURE__ */ e(Z, { onCancel: a, onFinish: C })
140
+ ] }),
141
+ /* @__PURE__ */ e("div", { className: s.editor, children: /* @__PURE__ */ e(
142
+ M,
143
+ {
144
+ ref: p,
145
+ value: i,
146
+ height: `${Math.max(((u == null ? void 0 : u.height) ?? 0) - 40, 0)}px`,
147
+ theme: V,
148
+ extensions: x,
149
+ onChange: c,
150
+ basicSetup: {
151
+ lineNumbers: !0,
152
+ foldGutter: !1
153
+ }
154
+ },
155
+ d
156
+ ) })
157
+ ] })
158
+ ] })
159
+ }
160
+ ),
161
+ document.body
162
+ );
163
+ }
164
+ export {
165
+ _e as default
166
+ };
167
+ //# sourceMappingURL=index-Bk0YRxdv.mjs.map