@tienne/gestalt 0.91.0 → 0.92.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 (37) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/plugin/skills/architecture/SKILL.md +15 -1
  3. package/dist/schemas/architecture-ir.schema.json +20 -0
  4. package/dist/src/architecture/html-client.d.ts +3 -0
  5. package/dist/src/architecture/html-client.d.ts.map +1 -1
  6. package/dist/src/architecture/html-client.js +192 -11
  7. package/dist/src/architecture/html-client.js.map +1 -1
  8. package/dist/src/architecture/html-renderer.d.ts.map +1 -1
  9. package/dist/src/architecture/html-renderer.js +219 -8
  10. package/dist/src/architecture/html-renderer.js.map +1 -1
  11. package/dist/src/architecture/html-theme.d.ts +2 -0
  12. package/dist/src/architecture/html-theme.d.ts.map +1 -1
  13. package/dist/src/architecture/html-theme.js +60 -0
  14. package/dist/src/architecture/html-theme.js.map +1 -1
  15. package/dist/src/architecture/ir-schema.d.ts +66 -26
  16. package/dist/src/architecture/ir-schema.d.ts.map +1 -1
  17. package/dist/src/architecture/ir-schema.js +9 -0
  18. package/dist/src/architecture/ir-schema.js.map +1 -1
  19. package/dist/src/architecture/merge.d.ts.map +1 -1
  20. package/dist/src/architecture/merge.js +9 -0
  21. package/dist/src/architecture/merge.js.map +1 -1
  22. package/dist/src/architecture/sequence-views.d.ts +155 -0
  23. package/dist/src/architecture/sequence-views.d.ts.map +1 -0
  24. package/dist/src/architecture/sequence-views.js +407 -0
  25. package/dist/src/architecture/sequence-views.js.map +1 -0
  26. package/dist/src/architecture/types.d.ts +13 -0
  27. package/dist/src/architecture/types.d.ts.map +1 -1
  28. package/dist/src/architecture/validator.d.ts +2 -1
  29. package/dist/src/architecture/validator.d.ts.map +1 -1
  30. package/dist/src/architecture/validator.js +84 -0
  31. package/dist/src/architecture/validator.js.map +1 -1
  32. package/package.json +1 -1
  33. package/plugin/.codex-plugin/plugin.json +1 -1
  34. package/plugin/.mcp.json +1 -1
  35. package/plugin/mcp.json +1 -1
  36. package/plugin/skills/architecture/SKILL.md +15 -1
  37. package/schemas/architecture-ir.schema.json +20 -0
@@ -0,0 +1,155 @@
1
+ import type { ArchitectureProjection, ProjectionMessage, SequenceBlockKind } from './types.js';
2
+ /** 렌더러가 쓰는 구간 하나. messageIds는 그린 메시지만 담고 participants는 순서도 머리 순서를 따른다 */
3
+ export interface SequencePhase {
4
+ id: string;
5
+ label: string;
6
+ /** IR에 phases가 없어 렌더할 때 자른 구간이면 true */
7
+ auto: boolean;
8
+ messageIds: string[];
9
+ participants: string[];
10
+ }
11
+ type PhaseMessage = Pick<ProjectionMessage, 'id' | 'from' | 'to' | 'reply' | 'block'>;
12
+ /**
13
+ * 맨 위 참여자가 지금 구간에서 아직 안 만난 대상을 부르는 자리에서 새 구간을 연다.
14
+ * 자기 호출, 응답, 이미 만난 대상 호출은 지금 구간에 붙는다. 묶음 한가운데에서는 자르지 않는다.
15
+ * 구간 이름은 그 구간을 연 메시지가 부른 대상의 이름이다
16
+ */
17
+ export declare function autoSequencePhases(messages: readonly PhaseMessage[], root: string | undefined, nameOf: (id: string) => string): {
18
+ label: string;
19
+ messageIds: string[];
20
+ }[];
21
+ /**
22
+ * IR의 phases를 그린 메시지에 맞춰 푼다. 근거가 없어 안 그린 메시지는 빼고 빈 구간은 버린다.
23
+ * phases가 없거나 그린 메시지를 다 덮지 못하면 자동으로 자른다. order는 순서도 머리 순서이고 맨 앞이 자동 분할의 기준이다
24
+ */
25
+ export declare function resolveSequencePhases(projection: Pick<ArchitectureProjection, 'messages' | 'phases'>, drawn: ReadonlySet<string>, order: readonly string[], nameOf: (id: string) => string): SequencePhase[];
26
+ /**
27
+ * 맨 위 참여자에서 몇 번 건너 불리는지. 가장 짧은 경로로 세고 응답과 자기 호출은 세지 않는다.
28
+ * 맨 위에서 못 닿는 참여자는 0이다
29
+ */
30
+ export declare function sequenceCallDepths(messages: readonly PhaseMessage[], root: string | undefined): Map<string, number>;
31
+ export interface WalkBox {
32
+ id: string;
33
+ x: number;
34
+ y: number;
35
+ width: number;
36
+ height: number;
37
+ }
38
+ export interface WalkStep {
39
+ messageId: string;
40
+ /** 번호. 그린 메시지만 1부터 센다 */
41
+ n: number;
42
+ phaseId: string;
43
+ from: string;
44
+ to: string;
45
+ d: string;
46
+ self: boolean;
47
+ }
48
+ export interface WalkLayout {
49
+ width: number;
50
+ height: number;
51
+ /** 구간 이름 자리. 새 참여자를 들이지 않는 구간은 띠가 없다 */
52
+ bands: {
53
+ phaseId: string;
54
+ label: string;
55
+ x: number;
56
+ y: number;
57
+ }[];
58
+ nodes: WalkBox[];
59
+ /** 메시지가 가리킨 지도 엣지. 같은 엣지는 한 번만 긋는다 */
60
+ edges: {
61
+ id: string;
62
+ d: string;
63
+ }[];
64
+ steps: WalkStep[];
65
+ }
66
+ /**
67
+ * 따라가기 지도 좌표. 열은 호출 깊이이고 띠는 그 참여자가 처음 나온 구간이다.
68
+ * 열 폭은 그 열에서 가장 넓은 카드 폭을 따른다. 좌표는 (0, 0)에서 시작한다.
69
+ * 단계 번호는 numberOf로 순서도 번호를 그대로 받는다. 단계 목록과 같은 번호여야 목록을 눌러 그 단계로 간다
70
+ * 양끝이 지도에 없는 메시지는 단계에서 빠지는데, 그러면 번호가 끊겨 클라이언트가 그 뒤 단계로 못 간다.
71
+ * 렌더러는 그린 메시지에서 참여자를 뽑아 넘기므로 빠지는 메시지가 없다
72
+ */
73
+ export declare function computeWalkLayout(phases: readonly SequencePhase[], messages: readonly Pick<ProjectionMessage, 'id' | 'from' | 'to' | 'edge'>[], depths: ReadonlyMap<string, number>, sizeOf: (id: string) => {
74
+ width: number;
75
+ height: number;
76
+ }, edgeById: ReadonlyMap<string, {
77
+ from: string;
78
+ to: string;
79
+ }>, numberOf: (messageId: string) => number): WalkLayout;
80
+ /** 두 카드를 잇는 선. 자기 호출은 오른쪽 위 고리, 같은 열은 오른쪽으로 불룩한 곡선, 나머지는 마주 보는 변을 잇는다 */
81
+ export declare function walkPath(a: WalkBox, b: WalkBox): string;
82
+ /** 단계별 카드 머리의 둘째 줄 */
83
+ export declare function phaseMetaText(phase: Pick<SequencePhase, 'messageIds' | 'participants'>): string;
84
+ export interface PhaseCardMessage {
85
+ id: string;
86
+ n: number;
87
+ y: number;
88
+ x1: number;
89
+ x2: number;
90
+ self: boolean;
91
+ /** 번호를 뺀 라벨이 쓸 수 있는 글자 폭. textUnits 단위다 */
92
+ labelUnits: number;
93
+ }
94
+ export interface PhaseCardBlock {
95
+ id: string;
96
+ kind: SequenceBlockKind;
97
+ label: string;
98
+ x: number;
99
+ y: number;
100
+ width: number;
101
+ height: number;
102
+ branches: {
103
+ y: number;
104
+ label: string;
105
+ }[];
106
+ }
107
+ export interface PhaseCardLayout {
108
+ phaseId: string;
109
+ /** 1부터 센 구간 번호 */
110
+ index: number;
111
+ x: number;
112
+ y: number;
113
+ width: number;
114
+ height: number;
115
+ /** 카드 안 작은 순서도. 좌표는 그 svg 기준이다 */
116
+ svg: {
117
+ x: number;
118
+ y: number;
119
+ width: number;
120
+ height: number;
121
+ heads: {
122
+ id: string;
123
+ x: number;
124
+ y: number;
125
+ width: number;
126
+ height: number;
127
+ cx: number;
128
+ }[];
129
+ lifeline: {
130
+ y1: number;
131
+ y2: number;
132
+ };
133
+ messages: PhaseCardMessage[];
134
+ blocks: PhaseCardBlock[];
135
+ };
136
+ }
137
+ export interface PhaseBoardLayout {
138
+ width: number;
139
+ height: number;
140
+ cards: PhaseCardLayout[];
141
+ /** 카드 사이 화살표의 가운데 자리 */
142
+ arrows: {
143
+ x: number;
144
+ y: number;
145
+ }[];
146
+ }
147
+ /**
148
+ * 단계별 카드 보드. 카드를 왼쪽에서 오른쪽으로 놓고 rowMax를 넘으면 다음 줄로 내린다.
149
+ * 가장 넓은 카드가 rowMax보다 넓으면 그 폭이 줄 폭이다. 줄을 넘긴 카드 앞에도 화살표를 둔다
150
+ */
151
+ export declare function computePhaseBoard(phases: readonly SequencePhase[], projection: Pick<ArchitectureProjection, 'messages' | 'blocks'>, numberOf: (id: string) => number, rowMax?: number): PhaseBoardLayout;
152
+ /** 글자 폭이 units를 넘으면 잘라 말줄임표를 붙인다. 폭은 textUnits로 잰다 */
153
+ export declare function clipText(text: string, units: number): string;
154
+ export {};
155
+ //# sourceMappingURL=sequence-views.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence-views.d.ts","sourceRoot":"","sources":["../../../src/architecture/sequence-views.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,407 @@
1
+ import { textUnits } from './layout.js';
2
+ /**
3
+ * 맨 위 참여자가 지금 구간에서 아직 안 만난 대상을 부르는 자리에서 새 구간을 연다.
4
+ * 자기 호출, 응답, 이미 만난 대상 호출은 지금 구간에 붙는다. 묶음 한가운데에서는 자르지 않는다.
5
+ * 구간 이름은 그 구간을 연 메시지가 부른 대상의 이름이다
6
+ */
7
+ export function autoSequencePhases(messages, root, nameOf) {
8
+ const out = [];
9
+ messages.forEach((m, i) => {
10
+ const cur = out[out.length - 1];
11
+ const prev = i > 0 ? messages[i - 1] : undefined;
12
+ const opens = !cur ||
13
+ (m.from === root &&
14
+ m.to !== root &&
15
+ !m.reply &&
16
+ !cur.seen.has(m.to) &&
17
+ !(m.block !== undefined && m.block === prev?.block));
18
+ if (opens)
19
+ out.push({ label: nameOf(m.to), messageIds: [], seen: new Set() });
20
+ const ph = out[out.length - 1];
21
+ ph.messageIds.push(m.id);
22
+ ph.seen.add(m.from);
23
+ ph.seen.add(m.to);
24
+ });
25
+ return out.map(({ label, messageIds }) => ({ label, messageIds }));
26
+ }
27
+ /**
28
+ * IR의 phases를 그린 메시지에 맞춰 푼다. 근거가 없어 안 그린 메시지는 빼고 빈 구간은 버린다.
29
+ * phases가 없거나 그린 메시지를 다 덮지 못하면 자동으로 자른다. order는 순서도 머리 순서이고 맨 앞이 자동 분할의 기준이다
30
+ */
31
+ export function resolveSequencePhases(projection, drawn, order, nameOf) {
32
+ const messages = projection.messages.filter((m) => drawn.has(m.id));
33
+ const byId = new Map(messages.map((m) => [m.id, m]));
34
+ const participantsOf = (ids) => {
35
+ const used = new Set(ids.flatMap((id) => [byId.get(id).from, byId.get(id).to]));
36
+ return order.filter((id) => used.has(id));
37
+ };
38
+ if (projection.phases !== undefined) {
39
+ const index = new Map(projection.messages.map((m, i) => [m.id, i]));
40
+ const phases = [];
41
+ for (const ph of projection.phases) {
42
+ const from = index.get(ph.from);
43
+ const to = index.get(ph.to);
44
+ if (from === undefined || to === undefined)
45
+ continue;
46
+ const ids = projection.messages
47
+ .slice(from, to + 1)
48
+ .map((m) => m.id)
49
+ .filter((id) => byId.has(id));
50
+ if (ids.length === 0)
51
+ continue;
52
+ phases.push({
53
+ id: ph.id,
54
+ label: ph.label,
55
+ auto: false,
56
+ messageIds: ids,
57
+ participants: participantsOf(ids),
58
+ });
59
+ }
60
+ const covered = phases.flatMap((ph) => ph.messageIds);
61
+ if (covered.length === messages.length && covered.every((id, i) => id === messages[i].id)) {
62
+ return phases;
63
+ }
64
+ }
65
+ return autoSequencePhases(messages, order[0], nameOf).map((ph, i) => ({
66
+ id: `auto-${i + 1}`,
67
+ label: ph.label,
68
+ auto: true,
69
+ messageIds: ph.messageIds,
70
+ participants: participantsOf(ph.messageIds),
71
+ }));
72
+ }
73
+ /**
74
+ * 맨 위 참여자에서 몇 번 건너 불리는지. 가장 짧은 경로로 세고 응답과 자기 호출은 세지 않는다.
75
+ * 맨 위에서 못 닿는 참여자는 0이다
76
+ */
77
+ export function sequenceCallDepths(messages, root) {
78
+ const out = new Map();
79
+ const next = new Map();
80
+ for (const m of messages) {
81
+ for (const id of [m.from, m.to])
82
+ if (!next.has(id))
83
+ next.set(id, []);
84
+ if (m.reply || m.from === m.to)
85
+ continue;
86
+ next.get(m.from).push(m.to);
87
+ }
88
+ if (root !== undefined && next.has(root)) {
89
+ out.set(root, 0);
90
+ const queue = [root];
91
+ for (let i = 0; i < queue.length; i++) {
92
+ const at = queue[i];
93
+ for (const to of next.get(at)) {
94
+ if (out.has(to))
95
+ continue;
96
+ out.set(to, out.get(at) + 1);
97
+ queue.push(to);
98
+ }
99
+ }
100
+ }
101
+ for (const id of next.keys())
102
+ if (!out.has(id))
103
+ out.set(id, 0);
104
+ return out;
105
+ }
106
+ const WALK_TOP = 22;
107
+ const WALK_PAD = 24;
108
+ const WALK_COL_GAP = 48;
109
+ const WALK_ROW_GAP = 16;
110
+ const WALK_BAND_GAP = 34;
111
+ const WALK_BAND_LABEL = 8;
112
+ const WALK_LOOP = 44;
113
+ /**
114
+ * 따라가기 지도 좌표. 열은 호출 깊이이고 띠는 그 참여자가 처음 나온 구간이다.
115
+ * 열 폭은 그 열에서 가장 넓은 카드 폭을 따른다. 좌표는 (0, 0)에서 시작한다.
116
+ * 단계 번호는 numberOf로 순서도 번호를 그대로 받는다. 단계 목록과 같은 번호여야 목록을 눌러 그 단계로 간다
117
+ * 양끝이 지도에 없는 메시지는 단계에서 빠지는데, 그러면 번호가 끊겨 클라이언트가 그 뒤 단계로 못 간다.
118
+ * 렌더러는 그린 메시지에서 참여자를 뽑아 넘기므로 빠지는 메시지가 없다
119
+ */
120
+ export function computeWalkLayout(phases, messages, depths, sizeOf, edgeById, numberOf) {
121
+ const placed = new Map();
122
+ const bandCols = [];
123
+ const bandPhase = [];
124
+ for (const ph of phases) {
125
+ const cols = new Map();
126
+ for (const id of ph.participants) {
127
+ if (placed.has(id))
128
+ continue;
129
+ const col = depths.get(id) ?? 0;
130
+ if (!cols.has(col))
131
+ cols.set(col, []);
132
+ const list = cols.get(col);
133
+ placed.set(id, { col, band: bandCols.length, row: list.length });
134
+ list.push(id);
135
+ }
136
+ if (cols.size === 0)
137
+ continue;
138
+ bandCols.push(cols);
139
+ bandPhase.push(ph);
140
+ }
141
+ const usedCols = [...new Set([...placed.values()].map((p) => p.col))].sort((a, b) => a - b);
142
+ const colWidth = new Map(usedCols.map((c) => [c, 0]));
143
+ for (const [id, p] of placed) {
144
+ colWidth.set(p.col, Math.max(colWidth.get(p.col), sizeOf(id).width));
145
+ }
146
+ const colX = new Map();
147
+ let x = WALK_PAD;
148
+ for (const c of usedCols) {
149
+ colX.set(c, x);
150
+ x += colWidth.get(c) + WALK_COL_GAP;
151
+ }
152
+ const boxes = new Map();
153
+ const bands = [];
154
+ let y = WALK_TOP;
155
+ bandCols.forEach((cols, band) => {
156
+ let h = 0;
157
+ for (const [col, list] of [...cols.entries()].sort((a, b) => a[0] - b[0])) {
158
+ let at = y;
159
+ for (const id of list) {
160
+ const s = sizeOf(id);
161
+ boxes.set(id, {
162
+ id,
163
+ x: round2(colX.get(col)),
164
+ y: round2(at),
165
+ width: s.width,
166
+ height: s.height,
167
+ });
168
+ at += s.height + WALK_ROW_GAP;
169
+ }
170
+ h = Math.max(h, at - WALK_ROW_GAP - y);
171
+ }
172
+ const ph = bandPhase[band];
173
+ bands.push({ phaseId: ph.id, label: ph.label, x: WALK_PAD, y: round2(y - WALK_BAND_LABEL) });
174
+ y += h + WALK_BAND_GAP;
175
+ });
176
+ const pathOf = (a, b) => walkPath(boxes.get(a), boxes.get(b));
177
+ const edges = [];
178
+ const seenEdges = new Set();
179
+ for (const m of messages) {
180
+ if (m.edge === undefined || seenEdges.has(m.edge))
181
+ continue;
182
+ const e = edgeById.get(m.edge);
183
+ if (!e || !boxes.has(e.from) || !boxes.has(e.to))
184
+ continue;
185
+ seenEdges.add(m.edge);
186
+ edges.push({ id: m.edge, d: pathOf(e.from, e.to) });
187
+ }
188
+ const phaseOf = new Map(phases.flatMap((ph) => ph.messageIds.map((id) => [id, ph.id])));
189
+ const steps = messages
190
+ .filter((m) => boxes.has(m.from) && boxes.has(m.to))
191
+ .map((m) => ({
192
+ messageId: m.id,
193
+ n: numberOf(m.id),
194
+ phaseId: phaseOf.get(m.id) ?? '',
195
+ from: m.from,
196
+ to: m.to,
197
+ d: pathOf(m.from, m.to),
198
+ self: m.from === m.to,
199
+ }));
200
+ const right = Math.max(WALK_PAD, ...[...boxes.values()].map((b) => b.x + b.width));
201
+ return {
202
+ width: round2(right + WALK_LOOP),
203
+ height: round2(bandCols.length > 0 ? y - WALK_BAND_GAP + WALK_PAD : WALK_TOP + WALK_PAD),
204
+ bands,
205
+ nodes: [...boxes.values()],
206
+ edges,
207
+ steps,
208
+ };
209
+ }
210
+ /** 두 카드를 잇는 선. 자기 호출은 오른쪽 위 고리, 같은 열은 오른쪽으로 불룩한 곡선, 나머지는 마주 보는 변을 잇는다 */
211
+ export function walkPath(a, b) {
212
+ const p = (x, y) => `${round2(x)} ${round2(y)}`;
213
+ if (a.id === b.id) {
214
+ const r = a.x + a.width;
215
+ const mid = a.y + a.height / 2;
216
+ return `M${p(r - 30, a.y)}C${p(r - 30, a.y - 34)} ${p(r + 40, mid)} ${p(r, mid)}`;
217
+ }
218
+ const y1 = a.y + a.height / 2;
219
+ const y2 = b.y + b.height / 2;
220
+ if (a.x === b.x) {
221
+ const ra = a.x + a.width;
222
+ const rb = b.x + b.width;
223
+ return `M${p(ra, y1)}C${p(ra + 40, y1)} ${p(rb + 40, y2)} ${p(rb, y2)}`;
224
+ }
225
+ const forward = a.x < b.x;
226
+ const x1 = forward ? a.x + a.width : a.x;
227
+ const x2 = forward ? b.x : b.x + b.width;
228
+ const mx = (x1 + x2) / 2;
229
+ return `M${p(x1, y1)}C${p(mx, y1)} ${p(mx, y2)} ${p(x2, y2)}`;
230
+ }
231
+ /** 단계별 카드 머리의 둘째 줄 */
232
+ export function phaseMetaText(phase) {
233
+ return `메시지 ${phase.messageIds.length}개, 참여자 ${phase.participants.length}명`;
234
+ }
235
+ const MINI_COL = 136;
236
+ const MINI_HEAD = 40;
237
+ const MINI_FIRST = 14;
238
+ const MINI_ROW = 26;
239
+ const MINI_BLOCK_HEAD = 18;
240
+ const MINI_BRANCH = 14;
241
+ const MINI_BLOCK_TAIL = 6;
242
+ const MINI_BOTTOM = 10;
243
+ const MINI_SELF_LABEL = 120;
244
+ const MINI_LABEL_UNIT = 6;
245
+ const CARD_PAD_X = 14;
246
+ const CARD_HEAD = 58;
247
+ const CARD_PAD_BOTTOM = 12;
248
+ const CARD_TITLE_UNIT = 8;
249
+ const CARD_META_UNIT = 6.5;
250
+ const CARD_TITLE_MAX = 360;
251
+ const BOARD_ARROW = 36;
252
+ const BOARD_ROW_GAP = 28;
253
+ /** 카드 한 장 안의 작은 순서도. 그 구간에 나오는 참여자만 열로 세운다 */
254
+ function miniSequence(phase, messageById, blockById, numberOf) {
255
+ const col = new Map(phase.participants.map((id, i) => [id, i]));
256
+ const cx = (id) => col.get(id) * MINI_COL + MINI_COL / 2;
257
+ const messages = phase.messageIds.map((id) => messageById.get(id));
258
+ let width = phase.participants.length * MINI_COL;
259
+ for (const m of messages) {
260
+ if (m.from === m.to)
261
+ width = Math.max(width, cx(m.from) + 24 + MINI_SELF_LABEL);
262
+ }
263
+ const out = [];
264
+ const blocks = [];
265
+ let y = MINI_HEAD + MINI_FIRST;
266
+ let open;
267
+ let openBranch;
268
+ const close = () => {
269
+ if (!open)
270
+ return;
271
+ y += MINI_BLOCK_TAIL;
272
+ open.height = round2(y - open.y);
273
+ blocks.push(open);
274
+ open = undefined;
275
+ y += 4;
276
+ };
277
+ for (const m of messages) {
278
+ if (open && open.id !== m.block)
279
+ close();
280
+ const b = m.block !== undefined ? blockById.get(m.block) : undefined;
281
+ if (!open && b) {
282
+ open = { id: b.id, kind: b.kind, label: b.label, x: 4, y, width: 0, height: 0, branches: [] };
283
+ openBranch = m.branch;
284
+ y += MINI_BLOCK_HEAD;
285
+ }
286
+ else if (open && m.branch !== openBranch) {
287
+ y += MINI_BRANCH / 2;
288
+ open.branches.push({ y: round2(y), label: m.branch ?? '' });
289
+ y += MINI_BRANCH / 2;
290
+ openBranch = m.branch;
291
+ }
292
+ y += MINI_ROW / 2;
293
+ const self = m.from === m.to;
294
+ const x1 = cx(m.from);
295
+ const x2 = cx(m.to);
296
+ const n = numberOf(m.id);
297
+ const room = self ? MINI_SELF_LABEL : Math.abs(x2 - x1) - 12;
298
+ out.push({
299
+ id: m.id,
300
+ n,
301
+ y: round2(y),
302
+ x1,
303
+ x2,
304
+ self,
305
+ labelUnits: Math.max(0, Math.floor(room / MINI_LABEL_UNIT) - textUnits(`${n}. `)),
306
+ });
307
+ y += MINI_ROW / 2;
308
+ }
309
+ close();
310
+ const height = round2(y + MINI_BOTTOM);
311
+ return {
312
+ x: CARD_PAD_X,
313
+ y: CARD_HEAD,
314
+ width: round2(width),
315
+ height,
316
+ heads: phase.participants.map((id, i) => ({
317
+ id,
318
+ x: i * MINI_COL + 6,
319
+ y: 4,
320
+ width: MINI_COL - 12,
321
+ height: MINI_HEAD - 8,
322
+ cx: cx(id),
323
+ })),
324
+ lifeline: { y1: MINI_HEAD, y2: height },
325
+ messages: out,
326
+ blocks: blocks.map((b) => ({ ...b, width: round2(width - 8) })),
327
+ };
328
+ }
329
+ /**
330
+ * 단계별 카드 보드. 카드를 왼쪽에서 오른쪽으로 놓고 rowMax를 넘으면 다음 줄로 내린다.
331
+ * 가장 넓은 카드가 rowMax보다 넓으면 그 폭이 줄 폭이다. 줄을 넘긴 카드 앞에도 화살표를 둔다
332
+ */
333
+ export function computePhaseBoard(phases, projection, numberOf, rowMax = 1280) {
334
+ const messageById = new Map(projection.messages.map((m) => [m.id, m]));
335
+ const blockById = new Map((projection.blocks ?? []).map((b) => [b.id, b]));
336
+ const sized = phases.map((ph, i) => {
337
+ const svg = miniSequence(ph, messageById, blockById, numberOf);
338
+ const title = Math.min(CARD_TITLE_MAX, textUnits(`${i + 1}. ${ph.label}`) * CARD_TITLE_UNIT);
339
+ const meta = textUnits(phaseMetaText(ph)) * CARD_META_UNIT;
340
+ return {
341
+ ph,
342
+ svg,
343
+ width: round2(CARD_PAD_X * 2 + Math.max(svg.width, title, meta)),
344
+ height: round2(CARD_HEAD + svg.height + CARD_PAD_BOTTOM),
345
+ };
346
+ });
347
+ const limit = Math.max(rowMax, ...sized.map((s) => s.width));
348
+ const rows = [];
349
+ let used = 0;
350
+ for (const s of sized) {
351
+ const row = rows[rows.length - 1];
352
+ if (row && used + BOARD_ARROW + s.width <= limit) {
353
+ row.push(s);
354
+ used += BOARD_ARROW + s.width;
355
+ }
356
+ else {
357
+ rows.push([s]);
358
+ used = (rows.length > 1 ? BOARD_ARROW : 0) + s.width;
359
+ }
360
+ }
361
+ const cards = [];
362
+ const arrows = [];
363
+ let y = 0;
364
+ let right = 0;
365
+ rows.forEach((row, r) => {
366
+ const h = Math.max(...row.map((s) => s.height));
367
+ let x = 0;
368
+ row.forEach((s, i) => {
369
+ if (r > 0 || i > 0) {
370
+ arrows.push({ x: round2(x + BOARD_ARROW / 2), y: round2(y + h / 2) });
371
+ x += BOARD_ARROW;
372
+ }
373
+ cards.push({
374
+ phaseId: s.ph.id,
375
+ index: cards.length + 1,
376
+ x: round2(x),
377
+ y: round2(y),
378
+ width: s.width,
379
+ height: s.height,
380
+ svg: s.svg,
381
+ });
382
+ x += s.width;
383
+ });
384
+ right = Math.max(right, x);
385
+ y += h + (r < rows.length - 1 ? BOARD_ROW_GAP : 0);
386
+ });
387
+ return { width: round2(right), height: round2(y), cards, arrows };
388
+ }
389
+ /** 글자 폭이 units를 넘으면 잘라 말줄임표를 붙인다. 폭은 textUnits로 잰다 */
390
+ export function clipText(text, units) {
391
+ if (textUnits(text) <= units)
392
+ return text;
393
+ let out = '';
394
+ let used = 0;
395
+ for (const ch of text) {
396
+ const w = textUnits(ch);
397
+ if (used + w > units - 1)
398
+ break;
399
+ out += ch;
400
+ used += w;
401
+ }
402
+ return `${out}…`;
403
+ }
404
+ function round2(v) {
405
+ return Math.round(v * 100) / 100;
406
+ }
407
+ //# sourceMappingURL=sequence-views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence-views.js","sourceRoot":"","sources":["../../../src/architecture/sequence-views.ts"],"names":[],"mappings":"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"}
@@ -361,6 +361,19 @@ export interface ArchitectureProjection {
361
361
  blocks?: ProjectionBlock[];
362
362
  /** compare가 견주는 두 묶음. 전과 후, 제품 둘처럼 왼쪽과 오른쪽에 선다 */
363
363
  sides?: ProjectionSide[];
364
+ /** sequence를 나누는 구간. 비우면 렌더할 때 맨 위 참여자가 새 대상을 부르는 자리에서 자른다 */
365
+ phases?: ProjectionPhase[];
366
+ }
367
+ /**
368
+ * sequence를 나누는 구간 하나. from과 to는 이 그림의 메시지 id이고 둘 다 구간에 든다.
369
+ * 배열 순서가 메시지 순서와 같고 구간끼리 겹치거나 비는 메시지가 없어야 한다
370
+ */
371
+ export interface ProjectionPhase {
372
+ id: string;
373
+ /** 사람이 읽는 단계 이름 */
374
+ label: string;
375
+ from: string;
376
+ to: string;
364
377
  }
365
378
  /** compare 묶음 하나. nodes는 지도의 노드 id다. 두 묶음에 다 있는 노드는 가운데 열에 선다 */
366
379
  export interface ProjectionSide {