ice-entity-designer 0.0.23 → 0.0.25

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.
@@ -81,16 +81,19 @@ export default class FlowDesigner {
81
81
  * 回调参数是当前流程的快照(与 serialize() 一致)。
82
82
  */
83
83
  subscribe(listener: (snapshot: string, designer: FlowDesigner) => void): () => void;
84
- private __emitChange;
84
+ protected __emitChange(): void;
85
85
  /** 订阅节点的拖拽事件:拖动是画布侧的行为,designer 需要感知才能广播与记历史 */
86
- private __attachNodeListeners;
86
+ protected __attachNodeListeners(node: any): void;
87
87
  private __detachNodeListeners;
88
88
  private __onBeforeMove;
89
89
  private __onAfterMove;
90
90
  private __endMoveSession;
91
91
  select(id: string | null): this;
92
92
  /** 没有给坐标时,按已有节点包围盒的下方网格错开摆放,避免新建节点互相压住 */
93
- private __defaultPlacement;
93
+ protected __defaultPlacement(width: number, height: number): {
94
+ left: number;
95
+ top: number;
96
+ };
94
97
  createNode(kind: FlowNodeKind, props?: any): any;
95
98
  /** 由节点的插槽位置算出连线端点(引擎按插槽吸附,端点需要给出初始坐标) */
96
99
  private __slotPoint;
@@ -142,7 +145,7 @@ export default class FlowDesigner {
142
145
  captureHistory(): void;
143
146
  /** 清空撤销/重做栈(用于「载入示例」这类不该占用历史的初始化操作) */
144
147
  resetHistory(): void;
145
- private __captureHistory;
148
+ protected __captureHistory(): void;
146
149
  private __applySnapshot;
147
150
  /**
148
151
  * 撤销:先记账(把当前状态压入 redo、从 undo 弹出目标),再回放目标快照,
@@ -81,16 +81,19 @@ export default class FlowDesigner {
81
81
  * 回调参数是当前流程的快照(与 serialize() 一致)。
82
82
  */
83
83
  subscribe(listener: (snapshot: string, designer: FlowDesigner) => void): () => void;
84
- private __emitChange;
84
+ protected __emitChange(): void;
85
85
  /** 订阅节点的拖拽事件:拖动是画布侧的行为,designer 需要感知才能广播与记历史 */
86
- private __attachNodeListeners;
86
+ protected __attachNodeListeners(node: any): void;
87
87
  private __detachNodeListeners;
88
88
  private __onBeforeMove;
89
89
  private __onAfterMove;
90
90
  private __endMoveSession;
91
91
  select(id: string | null): this;
92
92
  /** 没有给坐标时,按已有节点包围盒的下方网格错开摆放,避免新建节点互相压住 */
93
- private __defaultPlacement;
93
+ protected __defaultPlacement(width: number, height: number): {
94
+ left: number;
95
+ top: number;
96
+ };
94
97
  createNode(kind: FlowNodeKind, props?: any): any;
95
98
  /** 由节点的插槽位置算出连线端点(引擎按插槽吸附,端点需要给出初始坐标) */
96
99
  private __slotPoint;
@@ -142,7 +145,7 @@ export default class FlowDesigner {
142
145
  captureHistory(): void;
143
146
  /** 清空撤销/重做栈(用于「载入示例」这类不该占用历史的初始化操作) */
144
147
  resetHistory(): void;
145
- private __captureHistory;
148
+ protected __captureHistory(): void;
146
149
  private __applySnapshot;
147
150
  /**
148
151
  * 撤销:先记账(把当前状态压入 redo、从 undo 弹出目标),再回放目标快照,
@@ -57,6 +57,8 @@ declare class ICE {
57
57
  * backing store 尺寸也会被边框撑大。这里在刷新 rect 时一并读取 computedStyle 补偿。
58
58
  */
59
59
  private __contentBox;
60
+ /** 上次用于「位移增量」的矩形快照(不持有 DOMRect 引用,见 __rememberInputRect)。 */
61
+ private __inputRectSnapshot;
60
62
  selectionList: Array<any>;
61
63
  /** 插件宿主:组件 / 渲染 / 交互工具三层注册点,见 `src/plugin/PluginHost.ts`。 */
62
64
  plugins: PluginHost;
@@ -265,6 +267,23 @@ declare class ICE {
265
267
  */
266
268
  private __applyDevicePixelRatio;
267
269
  updateCanvasBoundingRect(): any;
270
+ /** 记下上次用于「位移增量」的矩形快照。
271
+ *
272
+ * 不能直接复用 `canvasBoundingClientRect` 做差:某些运行时(桩 / 小程序)返回的是
273
+ * **同一个可变对象**,此时 `rect === prev`,增量恒为 0,内容盒就再也不会跟着走。
274
+ */
275
+ private __rememberInputRect;
276
+ /**
277
+ * 输入路径的**轻量**刷新:只重读一次 `getBoundingClientRect()`,尺寸没变时把已缓存的
278
+ * 内容盒按位移平移,跳过一次 `getComputedStyle`(border/padding 不会每帧变)。
279
+ *
280
+ * 为什么移动事件必须每帧重读:页面滚动、画布上方插入内容(提示条 / 错误信息 / 广告位)
281
+ * 都会让缓存整体过期,过期期间 `clientX - rect.left` 恒定偏移 —— 命中检测、悬停、
282
+ * 拖拽全部错位,而移动事件恰恰是唯一高频入口,不刷新就没人来纠正它。
283
+ *
284
+ * 尺寸变化(窗口缩放、布局改动导致画布变大变小)时退回完整刷新,保证 border/padding 补偿正确。
285
+ */
286
+ refreshInputRect(): any;
268
287
  /**
269
288
  * 读取 canvas 内容盒:把 border-box 的 rect 补偿成「绘制区」的偏移与尺寸。
270
289
  * 无 getComputedStyle 的运行时(如小程序)补偿为 0,退回 rect 原值。
@@ -57,6 +57,8 @@ declare class ICE {
57
57
  * backing store 尺寸也会被边框撑大。这里在刷新 rect 时一并读取 computedStyle 补偿。
58
58
  */
59
59
  private __contentBox;
60
+ /** 上次用于「位移增量」的矩形快照(不持有 DOMRect 引用,见 __rememberInputRect)。 */
61
+ private __inputRectSnapshot;
60
62
  selectionList: Array<any>;
61
63
  /** 插件宿主:组件 / 渲染 / 交互工具三层注册点,见 `src/plugin/PluginHost.ts`。 */
62
64
  plugins: PluginHost;
@@ -265,6 +267,23 @@ declare class ICE {
265
267
  */
266
268
  private __applyDevicePixelRatio;
267
269
  updateCanvasBoundingRect(): any;
270
+ /** 记下上次用于「位移增量」的矩形快照。
271
+ *
272
+ * 不能直接复用 `canvasBoundingClientRect` 做差:某些运行时(桩 / 小程序)返回的是
273
+ * **同一个可变对象**,此时 `rect === prev`,增量恒为 0,内容盒就再也不会跟着走。
274
+ */
275
+ private __rememberInputRect;
276
+ /**
277
+ * 输入路径的**轻量**刷新:只重读一次 `getBoundingClientRect()`,尺寸没变时把已缓存的
278
+ * 内容盒按位移平移,跳过一次 `getComputedStyle`(border/padding 不会每帧变)。
279
+ *
280
+ * 为什么移动事件必须每帧重读:页面滚动、画布上方插入内容(提示条 / 错误信息 / 广告位)
281
+ * 都会让缓存整体过期,过期期间 `clientX - rect.left` 恒定偏移 —— 命中检测、悬停、
282
+ * 拖拽全部错位,而移动事件恰恰是唯一高频入口,不刷新就没人来纠正它。
283
+ *
284
+ * 尺寸变化(窗口缩放、布局改动导致画布变大变小)时退回完整刷新,保证 border/padding 补偿正确。
285
+ */
286
+ refreshInputRect(): any;
268
287
  /**
269
288
  * 读取 canvas 内容盒:把 border-box 的 rect 补偿成「绘制区」的偏移与尺寸。
270
289
  * 无 getComputedStyle 的运行时(如小程序)补偿为 0,退回 rect 原值。
@@ -47,8 +47,15 @@ declare class DOMEventDispatcher {
47
47
  private __dispatch;
48
48
  /**
49
49
  * 取 canvas 矩形用于坐标换算。
50
- * 移动类事件频率高(每帧可能多次),复用缓存;其余事件刷新一次,
51
- * 保证页面滚动 / 布局变化后命中检测不错位。
50
+ *
51
+ * **移动类事件也必须刷新**(走 `refreshInputRect` 轻量路径:只重读一次
52
+ * `getBoundingClientRect`,尺寸没变就平移已缓存的内容盒、不读 computedStyle),
53
+ * 其余事件走完整 `updateCanvasBoundingRect`。
54
+ *
55
+ * 为什么不做「一帧一次」的节流:布局变化(页面滚动、画布上方插入内容)可能就发生在
56
+ * 两次事件之间,节流会让第二次事件继续用过期矩形 —— 命中检测整体偏移、悬停直接落空。
57
+ * 实测一次 `getBoundingClientRect()` 在布局干净时约 0.22µs、强制重排的最坏情况约 2.8µs,
58
+ * 相对每帧渲染可忽略(见 AGENTS「性能相关铁律」)。
52
59
  */
53
60
  private __resolveCanvasRect;
54
61
  set stopped(flag: boolean);
@@ -47,8 +47,15 @@ declare class DOMEventDispatcher {
47
47
  private __dispatch;
48
48
  /**
49
49
  * 取 canvas 矩形用于坐标换算。
50
- * 移动类事件频率高(每帧可能多次),复用缓存;其余事件刷新一次,
51
- * 保证页面滚动 / 布局变化后命中检测不错位。
50
+ *
51
+ * **移动类事件也必须刷新**(走 `refreshInputRect` 轻量路径:只重读一次
52
+ * `getBoundingClientRect`,尺寸没变就平移已缓存的内容盒、不读 computedStyle),
53
+ * 其余事件走完整 `updateCanvasBoundingRect`。
54
+ *
55
+ * 为什么不做「一帧一次」的节流:布局变化(页面滚动、画布上方插入内容)可能就发生在
56
+ * 两次事件之间,节流会让第二次事件继续用过期矩形 —— 命中检测整体偏移、悬停直接落空。
57
+ * 实测一次 `getBoundingClientRect()` 在布局干净时约 0.22µs、强制重排的最坏情况约 2.8µs,
58
+ * 相对每帧渲染可忽略(见 AGENTS「性能相关铁律」)。
52
59
  */
53
60
  private __resolveCanvasRect;
54
61
  set stopped(flag: boolean);
@@ -232,6 +232,13 @@ declare class ICEPolyLine extends ICEDotPath {
232
232
  * 先绘制折线,再绘制连线标签(若 label 非空)。
233
233
  */
234
234
  protected doRender(): void;
235
+ /**
236
+ * 用「线色」把端点箭头三角形填实(`arrowStyle: 'filled'`,默认)。
237
+ *
238
+ * 面顶点由 `getArrowFaces()` 提供 —— 与 SVG 导出共用同一份口径(导出器也读它),
239
+ * 避免「画布填了、导出没填」(实心箭头在导出里变空心)。
240
+ */
241
+ getArrowFaces(): number[][][];
235
242
  /**
236
243
  * 用「线色」把端点箭头三角形填实(`arrowStyle: 'filled'`,默认)。
237
244
  *
@@ -232,6 +232,13 @@ declare class ICEPolyLine extends ICEDotPath {
232
232
  * 先绘制折线,再绘制连线标签(若 label 非空)。
233
233
  */
234
234
  protected doRender(): void;
235
+ /**
236
+ * 用「线色」把端点箭头三角形填实(`arrowStyle: 'filled'`,默认)。
237
+ *
238
+ * 面顶点由 `getArrowFaces()` 提供 —— 与 SVG 导出共用同一份口径(导出器也读它),
239
+ * 避免「画布填了、导出没填」(实心箭头在导出里变空心)。
240
+ */
241
+ getArrowFaces(): number[][][];
235
242
  /**
236
243
  * 用「线色」把端点箭头三角形填实(`arrowStyle: 'filled'`,默认)。
237
244
  *
@@ -25,6 +25,19 @@ export { validateBpmn } from './bpmn/bpmn_validate.mjs';
25
25
  export type { BpmnIssue } from './bpmn/bpmn_validate.mjs';
26
26
  export { toBpmnXml, fromBpmnXml } from './bpmn/bpmn_xml.mjs';
27
27
  export type { BpmnImportResult } from './bpmn/bpmn_xml.mjs';
28
+ export { default as UmlClass } from './uml/UmlClass.mjs';
29
+ export type { UmlClassKind } from './uml/UmlClass.mjs';
30
+ export { default as UmlRelation, UML_RELATION_KINDS, UML_RELATION_STYLE } from './uml/UmlRelation.mjs';
31
+ export type { UmlRelationKind, UmlMarker } from './uml/UmlRelation.mjs';
32
+ export { default as UmlDesigner } from './uml/UmlDesigner.mjs';
33
+ export type { UmlIssue } from './uml/UmlDesigner.mjs';
34
+ export { default as StateNode, STATECHART_NODE_KINDS } from './statechart/StateNode.mjs';
35
+ export type { StatechartNodeKind } from './statechart/StateNode.mjs';
36
+ export { default as StateTransition } from './statechart/StateTransition.mjs';
37
+ export { default as StatechartDesigner } from './statechart/StatechartDesigner.mjs';
38
+ export type { StatechartIssue } from './statechart/StatechartDesigner.mjs';
39
+ export { toPlantUml, fromPlantUml, arrowOf, detectUmlDialect } from './uml/uml_text.mjs';
40
+ export type { UmlTextImportResult } from './uml/uml_text.mjs';
28
41
  /**
29
42
  * 引擎内核(ice-render)在构建时已被打包进本包,这里一并导出。
30
43
  *
@@ -25,6 +25,19 @@ export { validateBpmn } from './bpmn/bpmn_validate';
25
25
  export type { BpmnIssue } from './bpmn/bpmn_validate';
26
26
  export { toBpmnXml, fromBpmnXml } from './bpmn/bpmn_xml';
27
27
  export type { BpmnImportResult } from './bpmn/bpmn_xml';
28
+ export { default as UmlClass } from './uml/UmlClass';
29
+ export type { UmlClassKind } from './uml/UmlClass';
30
+ export { default as UmlRelation, UML_RELATION_KINDS, UML_RELATION_STYLE } from './uml/UmlRelation';
31
+ export type { UmlRelationKind, UmlMarker } from './uml/UmlRelation';
32
+ export { default as UmlDesigner } from './uml/UmlDesigner';
33
+ export type { UmlIssue } from './uml/UmlDesigner';
34
+ export { default as StateNode, STATECHART_NODE_KINDS } from './statechart/StateNode';
35
+ export type { StatechartNodeKind } from './statechart/StateNode';
36
+ export { default as StateTransition } from './statechart/StateTransition';
37
+ export { default as StatechartDesigner } from './statechart/StatechartDesigner';
38
+ export type { StatechartIssue } from './statechart/StatechartDesigner';
39
+ export { toPlantUml, fromPlantUml, arrowOf, detectUmlDialect } from './uml/uml_text';
40
+ export type { UmlTextImportResult } from './uml/uml_text';
28
41
  /**
29
42
  * 引擎内核(ice-render)在构建时已被打包进本包,这里一并导出。
30
43
  *
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEGroup, ICEText } from '../ice-render/index.mjs';
9
+ export declare const STATECHART_NODE_KINDS: readonly ["initial", "final", "state", "composite"];
10
+ export declare type StatechartNodeKind = (typeof STATECHART_NODE_KINDS)[number];
11
+ /**
12
+ * @class StateNode 状态机的节点(伪状态 / 状态 / 复合状态)
13
+ *
14
+ * 复合组件(`hasDerivedChildren() === true`):内部形状与名字由 state 派生、不进文档。
15
+ * 四种记法:
16
+ * - `initial` 初始伪状态:实心圆
17
+ * - `final` 终止伪状态:同心圆(外圈 + 实心内圈)
18
+ * - `state` 普通状态:圆角矩形 + 居中名字
19
+ * - `composite` 复合状态:**容器** —— 名字靠左上,框里留给子状态;拖动它子状态一起走(引擎容器能力)
20
+ */
21
+ export default class StateNode extends ICEGroup {
22
+ static readonly typeId = "StateNode";
23
+ protected shapeComponent: any;
24
+ protected innerRingComponent: any;
25
+ protected labelComponent: ICEText | null;
26
+ hasDerivedChildren(): boolean;
27
+ constructor(props?: any);
28
+ protected static arrangeParam(props?: any): any;
29
+ /** 只有这些键变化才需要重建内部形状(拖动位置、选中态都不该重建) */
30
+ private static readonly __shapeKeys;
31
+ setState(patch: any): void;
32
+ applyPatch(patch?: any): void;
33
+ /** 伪状态(初始/终止)不显示名字 */
34
+ isPseudoState(): boolean;
35
+ /**
36
+ * 按 kind 重建内部形状与名字。
37
+ *
38
+ * zIndex 必须显式给:引擎在**构造时**分配自增 zIndex,后构造的会盖住先构造的
39
+ * (UML 那边就踩过「底色带盖住类名」),这里统一「形状在下、文字在上」。
40
+ */
41
+ protected syncShape(): void;
42
+ private __clearDerivedChildren;
43
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEGroup, ICEText } from '../ice-render/index';
9
+ export declare const STATECHART_NODE_KINDS: readonly ["initial", "final", "state", "composite"];
10
+ export declare type StatechartNodeKind = (typeof STATECHART_NODE_KINDS)[number];
11
+ /**
12
+ * @class StateNode 状态机的节点(伪状态 / 状态 / 复合状态)
13
+ *
14
+ * 复合组件(`hasDerivedChildren() === true`):内部形状与名字由 state 派生、不进文档。
15
+ * 四种记法:
16
+ * - `initial` 初始伪状态:实心圆
17
+ * - `final` 终止伪状态:同心圆(外圈 + 实心内圈)
18
+ * - `state` 普通状态:圆角矩形 + 居中名字
19
+ * - `composite` 复合状态:**容器** —— 名字靠左上,框里留给子状态;拖动它子状态一起走(引擎容器能力)
20
+ */
21
+ export default class StateNode extends ICEGroup {
22
+ static readonly typeId = "StateNode";
23
+ protected shapeComponent: any;
24
+ protected innerRingComponent: any;
25
+ protected labelComponent: ICEText | null;
26
+ hasDerivedChildren(): boolean;
27
+ constructor(props?: any);
28
+ protected static arrangeParam(props?: any): any;
29
+ /** 只有这些键变化才需要重建内部形状(拖动位置、选中态都不该重建) */
30
+ private static readonly __shapeKeys;
31
+ setState(patch: any): void;
32
+ applyPatch(patch?: any): void;
33
+ /** 伪状态(初始/终止)不显示名字 */
34
+ isPseudoState(): boolean;
35
+ /**
36
+ * 按 kind 重建内部形状与名字。
37
+ *
38
+ * zIndex 必须显式给:引擎在**构造时**分配自增 zIndex,后构造的会盖住先构造的
39
+ * (UML 那边就踩过「底色带盖住类名」),这里统一「形状在下、文字在上」。
40
+ */
41
+ protected syncShape(): void;
42
+ private __clearDerivedChildren;
43
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEPolyLine } from '../ice-render/index.mjs';
9
+ /**
10
+ * @class StateTransition 状态机的一次转移
11
+ *
12
+ * 记法:实线 + **实心箭头**,标签是 `事件 [守卫] / 动作`(UML 状态机与 PlantUML 状态图的通行写法)。
13
+ * 复用引擎折线(插槽吸附 / 正交·贝塞尔路由 / 跟随宿主 / 矢量导出),只把标签的三个部分拼好。
14
+ *
15
+ * 之所以单独一个类而不是直接用 ICEPolyLine:给一个**稳定 typeId**,
16
+ * 判型与序列化都靠它(应用层不要用 constructor.name,打包会 mangle)。
17
+ */
18
+ export default class StateTransition extends ICEPolyLine {
19
+ static readonly typeId = "StateTransition";
20
+ constructor(props?: any);
21
+ protected static arrangeParam(props?: any): any;
22
+ /**
23
+ * 标签拼装:`事件 [守卫] / 动作` —— 缺哪个省哪个(不会出现空括号或光秃秃的斜杠)。
24
+ */
25
+ static composeLabel(parts: {
26
+ event?: string;
27
+ guard?: string;
28
+ action?: string;
29
+ }): string;
30
+ setState(patch: any): void;
31
+ applyPatch(patch?: any): void;
32
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEPolyLine } from '../ice-render/index';
9
+ /**
10
+ * @class StateTransition 状态机的一次转移
11
+ *
12
+ * 记法:实线 + **实心箭头**,标签是 `事件 [守卫] / 动作`(UML 状态机与 PlantUML 状态图的通行写法)。
13
+ * 复用引擎折线(插槽吸附 / 正交·贝塞尔路由 / 跟随宿主 / 矢量导出),只把标签的三个部分拼好。
14
+ *
15
+ * 之所以单独一个类而不是直接用 ICEPolyLine:给一个**稳定 typeId**,
16
+ * 判型与序列化都靠它(应用层不要用 constructor.name,打包会 mangle)。
17
+ */
18
+ export default class StateTransition extends ICEPolyLine {
19
+ static readonly typeId = "StateTransition";
20
+ constructor(props?: any);
21
+ protected static arrangeParam(props?: any): any;
22
+ /**
23
+ * 标签拼装:`事件 [守卫] / 动作` —— 缺哪个省哪个(不会出现空括号或光秃秃的斜杠)。
24
+ */
25
+ static composeLabel(parts: {
26
+ event?: string;
27
+ guard?: string;
28
+ action?: string;
29
+ }): string;
30
+ setState(patch: any): void;
31
+ applyPatch(patch?: any): void;
32
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import FlowDesigner from '../flow/FlowDesigner.mjs';
9
+ export declare type StatechartIssue = {
10
+ level: 'error' | 'warning';
11
+ message: string;
12
+ id?: string;
13
+ };
14
+ /**
15
+ * @class StatechartDesigner 状态机设计器(第二个 domain pack)
16
+ *
17
+ * 与 `UmlDesigner` 同构:`FlowDesigner` 的薄扩展,只做四件事 ——
18
+ * 建状态机图元、类型过滤、**几何自动嵌套**(复合状态是容器)、语义校验。
19
+ * 选择 / 增删改 / 连线 / 撤销重做 / 快照 / 适应视图 / 矢量导出全部继承。
20
+ */
21
+ export default class StatechartDesigner extends FlowDesigner {
22
+ private __nesting;
23
+ constructor(ice: any);
24
+ get nodes(): any[];
25
+ get edges(): any[];
26
+ /** 建状态(initial / final / state / composite),复合状态会自动把落在框内的状态收进容器 */
27
+ createState(props?: any): any;
28
+ /** 建一次转移;两端必须都是状态(否则抛错,与 FlowDesigner.createEdge 同一契约) */
29
+ createTransition(props?: any): any;
30
+ /**
31
+ * 几何自动嵌套:新状态的中心落在某个**复合状态**的框内就嵌进去(引擎容器能力)。
32
+ *
33
+ * 与 BPMN 的池/泳道同一套做法:`adoptChild`(**不能**用 removeChild —— 它会 destory 组件),
34
+ * 再把坐标换算成「以父容器左上角为原点」。
35
+ */
36
+ private __nestByGeometry;
37
+ /**
38
+ * 状态机语义校验:
39
+ * - 每个状态机要有**初始状态**(否则没有入口);
40
+ * - **终止状态不应有出边**(它表示流程结束);
41
+ * - **可达性**:从初始状态出发沿转移走不到的普通状态要提醒(画了但永远到不了);
42
+ * - 未连接的状态(既没有入边也没有出边)单独提示,和「不可达」区分开。
43
+ */
44
+ validateStatechart(): StatechartIssue[];
45
+ private __portPoint;
46
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import FlowDesigner from '../flow/FlowDesigner';
9
+ export declare type StatechartIssue = {
10
+ level: 'error' | 'warning';
11
+ message: string;
12
+ id?: string;
13
+ };
14
+ /**
15
+ * @class StatechartDesigner 状态机设计器(第二个 domain pack)
16
+ *
17
+ * 与 `UmlDesigner` 同构:`FlowDesigner` 的薄扩展,只做四件事 ——
18
+ * 建状态机图元、类型过滤、**几何自动嵌套**(复合状态是容器)、语义校验。
19
+ * 选择 / 增删改 / 连线 / 撤销重做 / 快照 / 适应视图 / 矢量导出全部继承。
20
+ */
21
+ export default class StatechartDesigner extends FlowDesigner {
22
+ private __nesting;
23
+ constructor(ice: any);
24
+ get nodes(): any[];
25
+ get edges(): any[];
26
+ /** 建状态(initial / final / state / composite),复合状态会自动把落在框内的状态收进容器 */
27
+ createState(props?: any): any;
28
+ /** 建一次转移;两端必须都是状态(否则抛错,与 FlowDesigner.createEdge 同一契约) */
29
+ createTransition(props?: any): any;
30
+ /**
31
+ * 几何自动嵌套:新状态的中心落在某个**复合状态**的框内就嵌进去(引擎容器能力)。
32
+ *
33
+ * 与 BPMN 的池/泳道同一套做法:`adoptChild`(**不能**用 removeChild —— 它会 destory 组件),
34
+ * 再把坐标换算成「以父容器左上角为原点」。
35
+ */
36
+ private __nestByGeometry;
37
+ /**
38
+ * 状态机语义校验:
39
+ * - 每个状态机要有**初始状态**(否则没有入口);
40
+ * - **终止状态不应有出边**(它表示流程结束);
41
+ * - **可达性**:从初始状态出发沿转移走不到的普通状态要提醒(画了但永远到不了);
42
+ * - 未连接的状态(既没有入边也没有出边)单独提示,和「不可达」区分开。
43
+ */
44
+ validateStatechart(): StatechartIssue[];
45
+ private __portPoint;
46
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEGroup, ICEPolyLine, ICERect, ICEText } from '../ice-render/index.mjs';
9
+ export declare type UmlClassKind = 'class' | 'interface' | 'enum';
10
+ /**
11
+ * @class UmlClass UML 类图的类框(三段式:类名 / 属性 / 方法)
12
+ *
13
+ * 与 ER 的 `Entity` 同一套做法:**复合组件** —— 类名、属性、方法、分隔线都是按 state
14
+ * 派生的内部子组件(`hasDerivedChildren() === true`),不写进文档、载入时重建。
15
+ *
16
+ * 与 Entity 的三点差异(这也是它值得单独做域包的原因):
17
+ * - 三段式:类名带(含构造型)+ 属性区 + 方法区,分隔线两条;
18
+ * - 成员是**自由文本**(`- id: string`、`+ pay(): void`),可见性/静态/泛型都由文本表达 ——
19
+ * 这是 UML 工具与文本格式(PlantUML/Mermaid)通行的做法,也让 AI 生成不必学一套结构化语法;
20
+ * - **高度随成员自动增长**,不允许成员画出框外。
21
+ */
22
+ export default class UmlClass extends ICEGroup {
23
+ /** 稳定类型标识(判型/序列化都用它,不要用 constructor.name:打包会被 mangle) */
24
+ static readonly typeId = "UmlClass";
25
+ protected stereotypeComponent: ICEText | null;
26
+ protected nameComponent: ICEText | null;
27
+ protected headerBackgroundComponent: ICERect | null;
28
+ protected memberComponents: ICEText[];
29
+ protected dividerComponents: ICEPolyLine[];
30
+ /** 内部子组件由 state 派生 → 不参与序列化 */
31
+ hasDerivedChildren(): boolean;
32
+ constructor(props?: any);
33
+ protected static arrangeParam(props: any): any;
34
+ /** 只需要重建内部排版的 state 键(拖动位置不该触发重建) */
35
+ private static readonly __layoutKeys;
36
+ setState(patch: any): void;
37
+ /** 应用层(属性面板 / DSL)改成员走这里,语义与 FlowNode.applyPatch 一致 */
38
+ applyPatch(patch?: any): void;
39
+ /**
40
+ * 按 state 重建三段式排版,并把**内容高度**写回自身(成员不会被画出框外)。
41
+ *
42
+ * 高度用 `this.state.height = h` 直接写:`setState()` 会再次触发重建,形成循环。
43
+ */
44
+ protected syncCompartments(): void;
45
+ private __clearDerivedChildren;
46
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import { ICEGroup, ICEPolyLine, ICERect, ICEText } from '../ice-render/index';
9
+ export declare type UmlClassKind = 'class' | 'interface' | 'enum';
10
+ /**
11
+ * @class UmlClass UML 类图的类框(三段式:类名 / 属性 / 方法)
12
+ *
13
+ * 与 ER 的 `Entity` 同一套做法:**复合组件** —— 类名、属性、方法、分隔线都是按 state
14
+ * 派生的内部子组件(`hasDerivedChildren() === true`),不写进文档、载入时重建。
15
+ *
16
+ * 与 Entity 的三点差异(这也是它值得单独做域包的原因):
17
+ * - 三段式:类名带(含构造型)+ 属性区 + 方法区,分隔线两条;
18
+ * - 成员是**自由文本**(`- id: string`、`+ pay(): void`),可见性/静态/泛型都由文本表达 ——
19
+ * 这是 UML 工具与文本格式(PlantUML/Mermaid)通行的做法,也让 AI 生成不必学一套结构化语法;
20
+ * - **高度随成员自动增长**,不允许成员画出框外。
21
+ */
22
+ export default class UmlClass extends ICEGroup {
23
+ /** 稳定类型标识(判型/序列化都用它,不要用 constructor.name:打包会被 mangle) */
24
+ static readonly typeId = "UmlClass";
25
+ protected stereotypeComponent: ICEText | null;
26
+ protected nameComponent: ICEText | null;
27
+ protected headerBackgroundComponent: ICERect | null;
28
+ protected memberComponents: ICEText[];
29
+ protected dividerComponents: ICEPolyLine[];
30
+ /** 内部子组件由 state 派生 → 不参与序列化 */
31
+ hasDerivedChildren(): boolean;
32
+ constructor(props?: any);
33
+ protected static arrangeParam(props: any): any;
34
+ /** 只需要重建内部排版的 state 键(拖动位置不该触发重建) */
35
+ private static readonly __layoutKeys;
36
+ setState(patch: any): void;
37
+ /** 应用层(属性面板 / DSL)改成员走这里,语义与 FlowNode.applyPatch 一致 */
38
+ applyPatch(patch?: any): void;
39
+ /**
40
+ * 按 state 重建三段式排版,并把**内容高度**写回自身(成员不会被画出框外)。
41
+ *
42
+ * 高度用 `this.state.height = h` 直接写:`setState()` 会再次触发重建,形成循环。
43
+ */
44
+ protected syncCompartments(): void;
45
+ private __clearDerivedChildren;
46
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Copyright (c) 2022 大漠穷秋.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import FlowDesigner from '../flow/FlowDesigner.mjs';
9
+ import type { UmlRelationKind } from './UmlRelation.mjs';
10
+ export declare type UmlIssue = {
11
+ level: 'error' | 'warning';
12
+ message: string;
13
+ id?: string;
14
+ };
15
+ /**
16
+ * @class UmlDesigner UML 类图设计器(域包 = 形状 + 应用层 + 校验 + 互操作 + 文档)
17
+ *
18
+ * 它是 `FlowDesigner` 的**薄扩展**,只做四件事,其余(选择、增删改、连线、撤销重做、
19
+ * 快照存取、适应视图、订阅)全部继承:
20
+ *
21
+ * 1. 建 UML 图元(`UmlClass` / `UmlRelation`)而不是流程图的 FlowNode/FlowEdge;
22
+ * 2. 节点/连线的**类型过滤**换成 UML 类型;
23
+ * 3. UML **语义校验**(重名类、悬空关系、继承环)。
24
+ *
25
+ * 之所以能这么薄:类框是复合组件(内部三段由 state 派生),关系是折线(标记进路径点集),
26
+ * 快照直接复用引擎序列化(typeId 注册表 + hasDerivedChildren)。
27
+ */
28
+ export default class UmlDesigner extends FlowDesigner {
29
+ constructor(ice: any);
30
+ /** 只认 UML 类框(继承来的 FlowNode 过滤换掉) */
31
+ get nodes(): any[];
32
+ /** 只认 UML 关系线 */
33
+ get edges(): any[];
34
+ /** 建一个类/接口/枚举(`createNode` 的 UML 语义版本) */
35
+ createClass(props?: any): any;
36
+ /** 建一条 UML 关系(继承 / 实现 / 关联 / 聚合 / 组合 / 依赖) */
37
+ createRelation(props?: any): any;
38
+ /** 改关系种类:记法(线型 + 端点标记 + 填充)随之一并更新 */
39
+ setRelationKind(id: string, relationKind: UmlRelationKind): any;
40
+ /** 关系种类清单(属性面板/DSL 共用同一份词汇表) */
41
+ get relationKinds(): string[];
42
+ /**
43
+ * UML 语义校验(结构之外的部分):
44
+ * - 类名重复(同一张图里两个类无法区分);
45
+ * - 关系两端必须都还在(删除类时引擎会级联删关系,这里是防御性的);
46
+ * - 继承/实现的**成环**(A 继承 B、B 又继承 A —— 类型系统不成立)。
47
+ */
48
+ validateUml(): UmlIssue[];
49
+ /** 关系记法的可读描述(属性面板/文档共用,避免三处各写一份文案) */
50
+ static describeRelationKind(kind: UmlRelationKind): string;
51
+ /** 端口点:与 FlowDesigner 的插槽语义一致(T/R/B/L/C),这里按 UML 常用左右出发 */
52
+ private __portPoint;
53
+ }