@g1cloud/bpmn-modeler-next 5.0.0-alpha.4 → 5.0.0-alpha.7

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.
@@ -1,6 +1,6 @@
1
1
  import { BpmnDocumentModelerLike } from '../core/modelerLike';
2
2
  import { SymbolicOp } from './symbolicOp';
3
- import { ResolveIssue } from './resolver';
3
+ import { ApplyBpmnOpsResult, ResolveIssue } from './resolver';
4
4
  import { GeometryFinding } from './geometryAudit';
5
5
  /** op 출처 — 감사·정책 분기용. `gui` = 호스트 채팅 패널, `rest` = 외부 브리지. */
6
6
  export type BpmnOpOrigin = 'agent' | 'gui' | 'rest';
@@ -41,6 +41,8 @@ export type ApplyBatchOutcome =
41
41
  version: number;
42
42
  xml: string;
43
43
  findings: GeometryFinding[];
44
+ /** 간선 교차 계측(B-14 ⓐ) — 문서 전체, 하강 전/후. finding 이 아니다. */
45
+ stats: ApplyBpmnOpsResult['stats'];
44
46
  } | {
45
47
  status: 'conflict';
46
48
  baseVersion: number;
@@ -16,6 +16,12 @@ export interface GeometryShape {
16
16
  container: boolean;
17
17
  /** 경계 이벤트처럼 **호스트에 붙는 것이 정상**인 도형 — 겹침 판정에서 제외된다. */
18
18
  attached: boolean;
19
+ /**
20
+ * 이 도형을 **의미론적으로** 담는 컨테이너 id(참여자 또는 확장 서브프로세스) — 없으면 루트.
21
+ * 좌표가 아니라 모델에서 온다(DI 는 프로세스 소속을 말하지 않는다). `shape-outside-container`
22
+ * 판정의 근거: 노드가 자기 풀 밖에 그려져 있으면 좌표만 보는 사람은 **남의 풀 노드로 읽는다.**
23
+ */
24
+ parent?: string;
19
25
  }
20
26
  export interface GeometryEdge {
21
27
  id: string;
@@ -47,9 +53,59 @@ export type GeometryFinding =
47
53
  kind: 'shape-overlap';
48
54
  shapes: [string, string];
49
55
  identical: boolean;
56
+ }
57
+ /**
58
+ * 도형이 자기 컨테이너(풀·확장 서브프로세스) 경계 밖으로 나가 있다. 원인은 컨테이너 크기가
59
+ * 내용물을 따라 늘지 않은 것(B-12 실측: 풀 높이가 band 수를 몰라 band 2 노드가 아래 풀 안에
60
+ * 놓였다). 작은 도형(이벤트)은 아무것과도 겹치지 않아 **관통·겹침 축은 침묵**하는데, 사람은
61
+ * 그 노드를 다른 풀의 것으로 읽는다 — 의미론이 조용히 뒤바뀌는 클래스라 따로 잡는다.
62
+ */
63
+ | {
64
+ kind: 'shape-outside-container';
65
+ shape: string;
66
+ container: string;
67
+ }
68
+ /**
69
+ * 두 간선의 축 정렬 구간이 **같은 선 위에 겹치는데 진행 방향이 반대**다 — 한 선처럼 보이는데
70
+ * 화살표가 양쪽 끝에 달려 어디서 어디로 가는지 읽을 수 없다(확정 6 네 번째 표본에서 사용자가
71
+ * 지목한 "문제가 되는 겹침" — 같은 방향으로 합류·팬아웃하는 겹침은 문제가 아니라 제외한다).
72
+ * 전형 = 되돌아가는 간선이 주 줄의 정방향 간선 위를 거꾸로 달리는 것, 같은 열을 반대로 오르내리는
73
+ * 메시지플로우 둘. `length` = 겹친 길이(px).
74
+ */
75
+ | {
76
+ kind: 'edge-overlap-opposite';
77
+ edges: [string, string];
78
+ axis: 'h' | 'v';
79
+ length: number;
50
80
  };
51
81
  /** 발견을 전후 비교(배치가 새로 만든 것 가려내기)할 수 있게 하는 안정 키. */
52
82
  export declare function geometryFindingKey(finding: GeometryFinding): string;
83
+ /**
84
+ * 두 간선의 **반대 방향** 공선 중첩 — 가장 긴 겹침의 (축, 길이). 없으면 `null`.
85
+ * 같은 방향 겹침(합류·팬아웃)은 세지 않는다.
86
+ */
87
+ export declare function oppositeOverlapOf(a: GeometryEdge, b: GeometryEdge): {
88
+ axis: 'h' | 'v';
89
+ length: number;
90
+ } | null;
91
+ /** 한 간선(후보 경로)이 다른 간선들과 만드는 반대 방향 중첩 수. */
92
+ export declare function oppositeOverlapCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
93
+ /**
94
+ * 이 간선이 관통하는 도형들(자기 끝점 제외). 판정과 **우회 보정**(routeRepair)이 같은
95
+ * 술어를 써야 "고쳤다는데 판정은 그대로"가 나지 않는다.
96
+ *
97
+ * `targets` 는 컨테이너를 제외한 도형 목록 — 호출자가 한 번 걸러 넘긴다(반복 호출 비용).
98
+ */
99
+ export declare function crossedShapesOf(edge: GeometryEdge, targets: readonly GeometryShape[]): GeometryShape[];
100
+ /**
101
+ * 한 간선(또는 그 후보 경로)이 다른 간선들과 교차하는 수. **끝점을 공유하는 간선은 제외**한다 —
102
+ * 같은 노드에서 나가는 팬아웃·같은 노드로 드는 합류는 꺾이는 자리가 겹쳐 보여도 교차가 아니다.
103
+ */
104
+ export declare function edgeCrossCount(edge: GeometryEdge, others: readonly GeometryEdge[]): number;
105
+ /** 장면 전체의 교차 쌍(id 오름차순 정렬, 결정론적). 길이가 곧 교차 수다. */
106
+ export declare function edgeCrossingPairsOf(scene: GeometryScene): Array<[string, string]>;
107
+ /** 컨테이너를 뺀 판정 대상 도형 — 관통·겹침 양쪽의 공통 모집단. */
108
+ export declare const auditTargetsOf: (scene: GeometryScene) => GeometryShape[];
53
109
  /**
54
110
  * 기하 판정 (순수). 결과는 **결정론적 순서**로 정렬해 반환한다 — 전후 diff·골든 비교·회귀
55
111
  * 고정이 전부 순서에 의존한다.
@@ -58,10 +114,6 @@ export declare function geometryFindingKey(finding: GeometryFinding): string;
58
114
  * 에서 무시할 수준이고, 색인은 실제로 큰 문서가 관찰될 때 넣는다(조기 최적화 회피).
59
115
  */
60
116
  export declare function auditGeometry(scene: GeometryScene): GeometryFinding[];
61
- /**
62
- * moddle `definitions` → 장면. 입력은 `describeProcess` 와 같은 트리라 캔버스·헤드리스 양쪽
63
- * 에서 같은 것을 준다(A-6 입력 계약 동형).
64
- */
65
117
  export declare function sceneFromDefinitions(definitions: ModdleElement): GeometryScene;
66
118
  /** 저장 진실 기준 전수 판정 — 그 문서에 있는 **전부**(선재 결함 포함). */
67
119
  export declare function auditBpmnGeometry(definitions: ModdleElement): GeometryFinding[];
@@ -8,6 +8,7 @@ export type { DocumentIndex, ElementCategory } from './documentIndex';
8
8
  export { buildRegistryIndex } from './documentIndex';
9
9
  export { validateOps } from './validate';
10
10
  export { lowerOps, resolverServicesOf, type ResolverServices } from './lower';
11
+ export { planCrossPoolRoute, planEdgeRepair, planMiddleSegmentShifts, planOppositeOverlapRepair, planSegmentDetours, repairIntroducedCrossings, repairIntroducedOppositeOverlaps, rerouteIntroducedCrossPoolEdges, } from './routeRepair';
11
12
  export interface ApplyBpmnOpsResult {
12
13
  ok: boolean;
13
14
  issues: ResolveIssue[];
@@ -20,5 +21,16 @@ export interface ApplyBpmnOpsResult {
20
21
  * 자기 배치 탓으로 읽고 무한 교정에 빠진다. 문서 전체 감사는 `auditBpmnGeometry`.
21
22
  */
22
23
  findings: GeometryFinding[];
24
+ /**
25
+ * 계측(B-14 ⓐ) — finding 이 아니다. 문서 **전체**의 간선 교차 수를 하강 전/후로 준다. 사람
26
+ * 마무리의 실체가 이 축이었다(확정 6 세 번째 표본: 교차 7 → 1)는 것이 드러난 뒤 도구가 그것을
27
+ * 볼 수 있게 한 채널. 배치가 교차를 얼마나 만들었는지 = `after - before`.
28
+ */
29
+ stats: {
30
+ edgeCrossings: {
31
+ before: number;
32
+ after: number;
33
+ };
34
+ };
23
35
  }
24
36
  export declare function applyBpmnOps(modeler: BpmnModelerLike, ops: readonly SymbolicOp[], lower?: typeof lowerOps): ApplyBpmnOpsResult;
@@ -0,0 +1,63 @@
1
+ import { GeometryEdge, GeometryPoint, GeometryScene, GeometryShape } from '../geometryAudit';
2
+ import { ResolverServices } from './lower';
3
+ /**
4
+ * 축 정렬 구간이 장애물을 **완전히 가로지를 때** 그것을 우회하는 4점을 만든다(순수).
5
+ *
6
+ * 반환은 `a`·`b` **사이에 끼워 넣을** 점들이다(양 끝점은 포함하지 않는다). 두 방향(위/아래
7
+ * 또는 좌/우)을 모두 돌려주고 어느 쪽이 나은지는 호출자가 판정기로 고른다.
8
+ *
9
+ * `null` = 이 구간은 다루지 않는다:
10
+ * - 사선 구간(축 정렬이 아님) — 우회 형상이 자명하지 않다
11
+ * - 장애물이 구간 끝에 걸쳐 있음 — 끝점 도킹과 얽혀 잘못 건드리면 연결이 떨어져 보인다
12
+ */
13
+ export declare function planSegmentDetours(a: GeometryPoint, b: GeometryPoint, rect: GeometryShape, margin?: number): [GeometryPoint[], GeometryPoint[]] | null;
14
+ /**
15
+ * 꺾임점이 장애물 **안**에 있는 형상 — 구간 우회로는 못 푼다(B-13 ②, 두 번째 표본 잔존 1건).
16
+ *
17
+ * bpmn-js 의 직각 경로는 대개 h-v-h(또는 v-h-v) 3구간이고, **중간 구간의 좌표**는 양 끝점의
18
+ * 중점이다. 그 중점이 어떤 도형의 폭 안에 떨어지면 세로 구간이 그 도형을 관통하고 꺾임점도
19
+ * 그 안에 있어 `planSegmentDetours` 가 거부한다(실측: 되돌아가는 간선의 중간 x 가 게이트웨이
20
+ * 폭 안). 해법은 우회가 아니라 **중간 구간을 장애물 옆으로 옮기는 것** — 점 수는 그대로 4 다.
21
+ * 두 후보(장애물 왼쪽/오른쪽 또는 위/아래)를 돌려주고 채택은 호출자가 판정기로 한다.
22
+ *
23
+ * `null` = 4점 직각 경로가 아니다.
24
+ */
25
+ export declare function planMiddleSegmentShifts(waypoints: readonly GeometryPoint[], rect: GeometryShape, margin?: number): [GeometryPoint[], GeometryPoint[]] | null;
26
+ /**
27
+ * 한 간선의 관통을 없애는 웨이포인트를 찾는다(순수). 못 찾으면 `null`.
28
+ *
29
+ * 장애물을 하나씩 처리하며 **매번 두 방향을 다 재보고 관통이 더 적은 쪽**을 고른다.
30
+ * 부모 컨테이너 바운즈를 알면 그 밖으로 나가는 우회를 후순위로 민다 — 풀 밖으로 튀어나간
31
+ * 선은 관통이 없어도 사람 눈에 결함이다(판정기가 못 보는 축이라 여기서 챙긴다).
32
+ */
33
+ export declare function planEdgeRepair(edge: GeometryEdge, targets: readonly GeometryShape[], container?: {
34
+ x: number;
35
+ y: number;
36
+ width: number;
37
+ height: number;
38
+ }): GeometryPoint[] | null;
39
+ /**
40
+ * 이 배치가 **새로 만든** 관통을 고친다(하강 직후, undo 에피소드 안에서 호출된다).
41
+ *
42
+ * `beforeKeys` = 하강 전 판정 키 집합. 거기 없던 관통만 대상이다(안전 성질 2).
43
+ * 완전히 해소되는 우회만 채택하고, 아니면 손대지 않는다(안전 성질 1) — 부분 개선을 받으면
44
+ * "고쳤는데 여전히 깨져 있다"가 되어 보고와 실물이 어긋난다.
45
+ */
46
+ export declare function repairIntroducedCrossings(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeKeys: ReadonlySet<string>): void;
47
+ /**
48
+ * 풀 횡단 메시지플로우의 6점 경로 계획(순수). `null` = 이 간선은 대상이 아니거나(중간 풀 없음 ·
49
+ * 끝점 해소 불가) 더 나은 열이 없다.
50
+ */
51
+ export declare function planCrossPoolRoute(edge: GeometryEdge, scene: GeometryScene): GeometryPoint[] | null;
52
+ /**
53
+ * 이 배치가 **새로 만든** 메시지플로우 중 풀을 횡단하는 것을 재경로한다(하강 직후, undo 에피소드
54
+ * 안). `beforeEdgeIds` = 하강 전 간선 id — 그 밖의 것만 대상(안전 성질 2: 선재 경로 불가침).
55
+ */
56
+ export declare function rerouteIntroducedCrossPoolEdges(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeEdgeIds: ReadonlySet<string>): void;
57
+ /** 한 간선의 반대 방향 중첩을 없애거나 줄이는 경로(순수). 못 찾으면 `null`. */
58
+ export declare function planOppositeOverlapRepair(edge: GeometryEdge, scene: GeometryScene): GeometryPoint[] | null;
59
+ /**
60
+ * 이 배치가 **새로 만든** 반대 방향 중첩을 고친다(하강 직후, undo 에피소드 안). 짝 중 새 간선만
61
+ * 손댄다(안전 성질 2) — 둘 다 새 것이면 되돌아가는 간선(A 후보가 있는 쪽)부터.
62
+ */
63
+ export declare function repairIntroducedOppositeOverlaps(services: Pick<ResolverServices, 'elementRegistry' | 'modeling'>, beforeKeys: ReadonlySet<string>, beforeEdgeIds: ReadonlySet<string>): void;