@tienne/gestalt 0.87.0 → 0.89.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.
- package/CLAUDE.md +12 -4
- package/README.ko.md +2 -1
- package/README.md +3 -1
- package/dist/bin/gestalt-hook.d.ts +5 -0
- package/dist/bin/gestalt-hook.d.ts.map +1 -0
- package/dist/bin/gestalt-hook.js +51 -0
- package/dist/bin/gestalt-hook.js.map +1 -0
- package/dist/package.json +5 -3
- package/dist/plugin/skills/_shared/proactive-routing.md +1 -0
- package/dist/plugin/skills/architecture/SKILL.md +913 -0
- package/dist/plugin/skills/blast-radius/SKILL.md +11 -1
- package/dist/plugin/skills/diff-radius/SKILL.md +11 -0
- package/dist/schemas/architecture-ir.schema.json +596 -0
- package/dist/schemas/gestalt.schema.json +19 -0
- package/dist/src/architecture/canvas-geometry.d.ts +40 -0
- package/dist/src/architecture/canvas-geometry.d.ts.map +1 -0
- package/dist/src/architecture/canvas-geometry.js +212 -0
- package/dist/src/architecture/canvas-geometry.js.map +1 -0
- package/dist/src/architecture/codeowners.d.ts +16 -0
- package/dist/src/architecture/codeowners.d.ts.map +1 -0
- package/dist/src/architecture/codeowners.js +58 -0
- package/dist/src/architecture/codeowners.js.map +1 -0
- package/dist/src/architecture/compare-layout.d.ts +27 -0
- package/dist/src/architecture/compare-layout.d.ts.map +1 -0
- package/dist/src/architecture/compare-layout.js +72 -0
- package/dist/src/architecture/compare-layout.js.map +1 -0
- package/dist/src/architecture/dataflow-layout.d.ts +29 -0
- package/dist/src/architecture/dataflow-layout.d.ts.map +1 -0
- package/dist/src/architecture/dataflow-layout.js +229 -0
- package/dist/src/architecture/dataflow-layout.js.map +1 -0
- package/dist/src/architecture/doc-fresh.d.ts +31 -0
- package/dist/src/architecture/doc-fresh.d.ts.map +1 -0
- package/dist/src/architecture/doc-fresh.js +84 -0
- package/dist/src/architecture/doc-fresh.js.map +1 -0
- package/dist/src/architecture/doc-link.d.ts +84 -0
- package/dist/src/architecture/doc-link.d.ts.map +1 -0
- package/dist/src/architecture/doc-link.js +396 -0
- package/dist/src/architecture/doc-link.js.map +1 -0
- package/dist/src/architecture/doc-routes.d.ts +39 -0
- package/dist/src/architecture/doc-routes.d.ts.map +1 -0
- package/dist/src/architecture/doc-routes.js +123 -0
- package/dist/src/architecture/doc-routes.js.map +1 -0
- package/dist/src/architecture/doc-scan.d.ts +107 -0
- package/dist/src/architecture/doc-scan.d.ts.map +1 -0
- package/dist/src/architecture/doc-scan.js +617 -0
- package/dist/src/architecture/doc-scan.js.map +1 -0
- package/dist/src/architecture/doc-stale.d.ts +32 -0
- package/dist/src/architecture/doc-stale.d.ts.map +1 -0
- package/dist/src/architecture/doc-stale.js +60 -0
- package/dist/src/architecture/doc-stale.js.map +1 -0
- package/dist/src/architecture/drilldown.d.ts +51 -0
- package/dist/src/architecture/drilldown.d.ts.map +1 -0
- package/dist/src/architecture/drilldown.js +1160 -0
- package/dist/src/architecture/drilldown.js.map +1 -0
- package/dist/src/architecture/endpoint-match.d.ts +43 -0
- package/dist/src/architecture/endpoint-match.d.ts.map +1 -0
- package/dist/src/architecture/endpoint-match.js +133 -0
- package/dist/src/architecture/endpoint-match.js.map +1 -0
- package/dist/src/architecture/flow-layout.d.ts +79 -0
- package/dist/src/architecture/flow-layout.d.ts.map +1 -0
- package/dist/src/architecture/flow-layout.js +519 -0
- package/dist/src/architecture/flow-layout.js.map +1 -0
- package/dist/src/architecture/focus.d.ts +14 -0
- package/dist/src/architecture/focus.d.ts.map +1 -0
- package/dist/src/architecture/focus.js +107 -0
- package/dist/src/architecture/focus.js.map +1 -0
- package/dist/src/architecture/global-context.d.ts +23 -0
- package/dist/src/architecture/global-context.d.ts.map +1 -0
- package/dist/src/architecture/global-context.js +67 -0
- package/dist/src/architecture/global-context.js.map +1 -0
- package/dist/src/architecture/html-client.d.ts +35 -0
- package/dist/src/architecture/html-client.d.ts.map +1 -0
- package/dist/src/architecture/html-client.js +1852 -0
- package/dist/src/architecture/html-client.js.map +1 -0
- package/dist/src/architecture/html-renderer.d.ts +22 -0
- package/dist/src/architecture/html-renderer.d.ts.map +1 -0
- package/dist/src/architecture/html-renderer.js +1290 -0
- package/dist/src/architecture/html-renderer.js.map +1 -0
- package/dist/src/architecture/html-theme.d.ts +25 -0
- package/dist/src/architecture/html-theme.d.ts.map +1 -0
- package/dist/src/architecture/html-theme.js +681 -0
- package/dist/src/architecture/html-theme.js.map +1 -0
- package/dist/src/architecture/index.d.ts +9 -0
- package/dist/src/architecture/index.d.ts.map +1 -0
- package/dist/src/architecture/index.js +9 -0
- package/dist/src/architecture/index.js.map +1 -0
- package/dist/src/architecture/ir-schema.d.ts +1832 -0
- package/dist/src/architecture/ir-schema.d.ts.map +1 -0
- package/dist/src/architecture/ir-schema.js +343 -0
- package/dist/src/architecture/ir-schema.js.map +1 -0
- package/dist/src/architecture/kind-text.d.ts +21 -0
- package/dist/src/architecture/kind-text.d.ts.map +1 -0
- package/dist/src/architecture/kind-text.js +42 -0
- package/dist/src/architecture/kind-text.js.map +1 -0
- package/dist/src/architecture/layout.d.ts +227 -0
- package/dist/src/architecture/layout.d.ts.map +1 -0
- package/dist/src/architecture/layout.js +627 -0
- package/dist/src/architecture/layout.js.map +1 -0
- package/dist/src/architecture/mcp-tool-match.d.ts +49 -0
- package/dist/src/architecture/mcp-tool-match.d.ts.map +1 -0
- package/dist/src/architecture/mcp-tool-match.js +53 -0
- package/dist/src/architecture/mcp-tool-match.js.map +1 -0
- package/dist/src/architecture/merge.d.ts +54 -0
- package/dist/src/architecture/merge.d.ts.map +1 -0
- package/dist/src/architecture/merge.js +681 -0
- package/dist/src/architecture/merge.js.map +1 -0
- package/dist/src/architecture/micro-app.d.ts +20 -0
- package/dist/src/architecture/micro-app.d.ts.map +1 -0
- package/dist/src/architecture/micro-app.js +41 -0
- package/dist/src/architecture/micro-app.js.map +1 -0
- package/dist/src/architecture/name-ref-match.d.ts +43 -0
- package/dist/src/architecture/name-ref-match.d.ts.map +1 -0
- package/dist/src/architecture/name-ref-match.js +127 -0
- package/dist/src/architecture/name-ref-match.js.map +1 -0
- package/dist/src/architecture/packs/data.d.ts +109 -0
- package/dist/src/architecture/packs/data.d.ts.map +1 -0
- package/dist/src/architecture/packs/data.js +64 -0
- package/dist/src/architecture/packs/data.js.map +1 -0
- package/dist/src/architecture/packs/generic.d.ts +47 -0
- package/dist/src/architecture/packs/generic.d.ts.map +1 -0
- package/dist/src/architecture/packs/generic.js +35 -0
- package/dist/src/architecture/packs/generic.js.map +1 -0
- package/dist/src/architecture/packs/harness.d.ts +96 -0
- package/dist/src/architecture/packs/harness.d.ts.map +1 -0
- package/dist/src/architecture/packs/harness.js +66 -0
- package/dist/src/architecture/packs/harness.js.map +1 -0
- package/dist/src/architecture/packs/index.d.ts +840 -0
- package/dist/src/architecture/packs/index.d.ts.map +1 -0
- package/dist/src/architecture/packs/index.js +87 -0
- package/dist/src/architecture/packs/index.js.map +1 -0
- package/dist/src/architecture/packs/infra.d.ts +91 -0
- package/dist/src/architecture/packs/infra.d.ts.map +1 -0
- package/dist/src/architecture/packs/infra.js +57 -0
- package/dist/src/architecture/packs/infra.js.map +1 -0
- package/dist/src/architecture/packs/knowledge.d.ts +72 -0
- package/dist/src/architecture/packs/knowledge.d.ts.map +1 -0
- package/dist/src/architecture/packs/knowledge.js +58 -0
- package/dist/src/architecture/packs/knowledge.js.map +1 -0
- package/dist/src/architecture/packs/process.d.ts +87 -0
- package/dist/src/architecture/packs/process.d.ts.map +1 -0
- package/dist/src/architecture/packs/process.js +52 -0
- package/dist/src/architecture/packs/process.js.map +1 -0
- package/dist/src/architecture/packs/render-classes.d.ts +11 -0
- package/dist/src/architecture/packs/render-classes.d.ts.map +1 -0
- package/dist/src/architecture/packs/render-classes.js +92 -0
- package/dist/src/architecture/packs/render-classes.js.map +1 -0
- package/dist/src/architecture/packs/types.d.ts +66 -0
- package/dist/src/architecture/packs/types.d.ts.map +1 -0
- package/dist/src/architecture/packs/types.js +18 -0
- package/dist/src/architecture/packs/types.js.map +1 -0
- package/dist/src/architecture/packs/web-product.d.ts +348 -0
- package/dist/src/architecture/packs/web-product.d.ts.map +1 -0
- package/dist/src/architecture/packs/web-product.js +226 -0
- package/dist/src/architecture/packs/web-product.js.map +1 -0
- package/dist/src/architecture/sequence-layout.d.ts +50 -0
- package/dist/src/architecture/sequence-layout.d.ts.map +1 -0
- package/dist/src/architecture/sequence-layout.js +140 -0
- package/dist/src/architecture/sequence-layout.js.map +1 -0
- package/dist/src/architecture/service-facts.d.ts +30 -0
- package/dist/src/architecture/service-facts.d.ts.map +1 -0
- package/dist/src/architecture/service-facts.js +88 -0
- package/dist/src/architecture/service-facts.js.map +1 -0
- package/dist/src/architecture/store.d.ts +50 -0
- package/dist/src/architecture/store.d.ts.map +1 -0
- package/dist/src/architecture/store.js +320 -0
- package/dist/src/architecture/store.js.map +1 -0
- package/dist/src/architecture/types.d.ts +400 -0
- package/dist/src/architecture/types.d.ts.map +1 -0
- package/dist/src/architecture/types.js +75 -0
- package/dist/src/architecture/types.js.map +1 -0
- package/dist/src/architecture/validator.d.ts +65 -0
- package/dist/src/architecture/validator.d.ts.map +1 -0
- package/dist/src/architecture/validator.js +1249 -0
- package/dist/src/architecture/validator.js.map +1 -0
- package/dist/src/code-graph/cochange.d.ts +40 -0
- package/dist/src/code-graph/cochange.d.ts.map +1 -1
- package/dist/src/code-graph/cochange.js +88 -3
- package/dist/src/code-graph/cochange.js.map +1 -1
- package/dist/src/code-graph/engine.d.ts +35 -1
- package/dist/src/code-graph/engine.d.ts.map +1 -1
- package/dist/src/code-graph/engine.js +300 -55
- package/dist/src/code-graph/engine.js.map +1 -1
- package/dist/src/code-graph/freshness.d.ts +39 -0
- package/dist/src/code-graph/freshness.d.ts.map +1 -0
- package/dist/src/code-graph/freshness.js +93 -0
- package/dist/src/code-graph/freshness.js.map +1 -0
- package/dist/src/code-graph/hooks/background.d.ts +18 -0
- package/dist/src/code-graph/hooks/background.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/background.js +55 -0
- package/dist/src/code-graph/hooks/background.js.map +1 -0
- package/dist/src/code-graph/hooks/pointers.d.ts +66 -0
- package/dist/src/code-graph/hooks/pointers.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/pointers.js +292 -0
- package/dist/src/code-graph/hooks/pointers.js.map +1 -0
- package/dist/src/code-graph/hooks/rank.d.ts +36 -0
- package/dist/src/code-graph/hooks/rank.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/rank.js +212 -0
- package/dist/src/code-graph/hooks/rank.js.map +1 -0
- package/dist/src/code-graph/hooks/run.d.ts +37 -0
- package/dist/src/code-graph/hooks/run.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/run.js +324 -0
- package/dist/src/code-graph/hooks/run.js.map +1 -0
- package/dist/src/code-graph/hooks/settings.d.ts +11 -0
- package/dist/src/code-graph/hooks/settings.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/settings.js +25 -0
- package/dist/src/code-graph/hooks/settings.js.map +1 -0
- package/dist/src/code-graph/hooks/state.d.ts +20 -0
- package/dist/src/code-graph/hooks/state.d.ts.map +1 -0
- package/dist/src/code-graph/hooks/state.js +73 -0
- package/dist/src/code-graph/hooks/state.js.map +1 -0
- package/dist/src/code-graph/index.d.ts +6 -2
- package/dist/src/code-graph/index.d.ts.map +1 -1
- package/dist/src/code-graph/index.js +3 -1
- package/dist/src/code-graph/index.js.map +1 -1
- package/dist/src/code-graph/ko-text.d.ts +39 -0
- package/dist/src/code-graph/ko-text.d.ts.map +1 -0
- package/dist/src/code-graph/ko-text.js +223 -0
- package/dist/src/code-graph/ko-text.js.map +1 -0
- package/dist/src/code-graph/lock.d.ts +30 -0
- package/dist/src/code-graph/lock.d.ts.map +1 -0
- package/dist/src/code-graph/lock.js +140 -0
- package/dist/src/code-graph/lock.js.map +1 -0
- package/dist/src/code-graph/plugins/typescript-skeleton.d.ts +7 -0
- package/dist/src/code-graph/plugins/typescript-skeleton.d.ts.map +1 -0
- package/dist/src/code-graph/plugins/typescript-skeleton.js +157 -0
- package/dist/src/code-graph/plugins/typescript-skeleton.js.map +1 -0
- package/dist/src/code-graph/plugins/typescript.d.ts.map +1 -1
- package/dist/src/code-graph/plugins/typescript.js +58 -0
- package/dist/src/code-graph/plugins/typescript.js.map +1 -1
- package/dist/src/code-graph/storage.d.ts +85 -0
- package/dist/src/code-graph/storage.d.ts.map +1 -1
- package/dist/src/code-graph/storage.js +318 -3
- package/dist/src/code-graph/storage.js.map +1 -1
- package/dist/src/code-graph/types.d.ts +66 -0
- package/dist/src/code-graph/types.d.ts.map +1 -1
- package/dist/src/core/config.d.ts +33 -0
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +14 -0
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/errors.d.ts +4 -0
- package/dist/src/core/errors.d.ts.map +1 -1
- package/dist/src/core/errors.js +8 -0
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/hooks-env.d.ts +9 -0
- package/dist/src/core/hooks-env.d.ts.map +1 -0
- package/dist/src/core/hooks-env.js +16 -0
- package/dist/src/core/hooks-env.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +326 -3
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +170 -2
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +28 -4
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/architecture-passthrough.d.ts +9 -0
- package/dist/src/mcp/tools/architecture-passthrough.d.ts.map +1 -0
- package/dist/src/mcp/tools/architecture-passthrough.js +587 -0
- package/dist/src/mcp/tools/architecture-passthrough.js.map +1 -0
- package/dist/src/mcp/tools/code-graph-passthrough.d.ts +6 -1
- package/dist/src/mcp/tools/code-graph-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/code-graph-passthrough.js +95 -6
- package/dist/src/mcp/tools/code-graph-passthrough.js.map +1 -1
- package/dist/src/utils/claude-projects.d.ts +19 -0
- package/dist/src/utils/claude-projects.d.ts.map +1 -0
- package/dist/src/utils/claude-projects.js +157 -0
- package/dist/src/utils/claude-projects.js.map +1 -0
- package/dist/src/utils/read-only-tools.d.ts +19 -0
- package/dist/src/utils/read-only-tools.d.ts.map +1 -0
- package/dist/src/utils/read-only-tools.js +132 -0
- package/dist/src/utils/read-only-tools.js.map +1 -0
- package/package.json +5 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/mcp.json +1 -1
- package/plugin/skills/_shared/proactive-routing.md +1 -0
- package/plugin/skills/architecture/SKILL.md +913 -0
- package/plugin/skills/blast-radius/SKILL.md +11 -1
- package/plugin/skills/diff-radius/SKILL.md +11 -0
- package/schemas/architecture-ir.schema.json +596 -0
- package/schemas/gestalt.schema.json +19 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/** 캔버스 좌표 = 레이아웃 좌표 + 이 여백. 위쪽은 레인 제목이 앉는 자리다 */
|
|
2
|
+
export const CANVAS_PAD_X = 32;
|
|
3
|
+
export const CANVAS_PAD_TOP = 60;
|
|
4
|
+
export const CANVAS_PAD_BOTTOM = 40;
|
|
5
|
+
/** 레인 띠의 위아래 여백 */
|
|
6
|
+
export const LANE_INSET_Y = 12;
|
|
7
|
+
/** 제품 띠 구분선. 선은 캔버스 양끝에서 BAND_LINE_X만큼 들이고 띠 머리에서 BAND_LINE_Y 아래에 긋는다. 띠 이름은 그 선에 걸쳐 단다 */
|
|
8
|
+
export const BAND_LINE_X = 8;
|
|
9
|
+
export const BAND_LINE_Y = 10;
|
|
10
|
+
export const BAND_TITLE_X = 16;
|
|
11
|
+
export const BAND_TITLE_HALF = 10;
|
|
12
|
+
const PORT_INSET = 14;
|
|
13
|
+
const PORT_STEP = 9;
|
|
14
|
+
// elk 경로에서 레이어 하나를 가로지르는 수평 구간만 경유점으로 쓴다. 레이어 사이 틈에서 꺾이는 짧은 구간은 버린다
|
|
15
|
+
const MIN_VIA_LENGTH = 40;
|
|
16
|
+
const VIA_CLEARANCE = 24;
|
|
17
|
+
const VIA_MARGIN = 8;
|
|
18
|
+
const LOOP_REACH = 36;
|
|
19
|
+
const LOOP_DROP = 28;
|
|
20
|
+
const STACK_BOW_MAX = 30;
|
|
21
|
+
function r2(v) {
|
|
22
|
+
return Math.round(v * 100) / 100;
|
|
23
|
+
}
|
|
24
|
+
function cmp(a, b) {
|
|
25
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
26
|
+
}
|
|
27
|
+
function toBox(n) {
|
|
28
|
+
const left = n.x + CANVAS_PAD_X;
|
|
29
|
+
const top = n.y + CANVAS_PAD_TOP;
|
|
30
|
+
return { left, right: left + n.width, top, bottom: top + n.height, cy: top + n.height / 2 };
|
|
31
|
+
}
|
|
32
|
+
/** 한 카드에 붙는 선이 여럿이면 세로로 나눠 앉힌다. 맞은편 카드가 위에 있을수록 위쪽 자리다 */
|
|
33
|
+
function assignPorts(edges, boxes, side) {
|
|
34
|
+
const groups = new Map();
|
|
35
|
+
for (const e of edges) {
|
|
36
|
+
const key = side === 'out' ? e.from : e.to;
|
|
37
|
+
const list = groups.get(key);
|
|
38
|
+
if (list)
|
|
39
|
+
list.push(e);
|
|
40
|
+
else
|
|
41
|
+
groups.set(key, [e]);
|
|
42
|
+
}
|
|
43
|
+
const ports = new Map();
|
|
44
|
+
for (const [nodeId, list] of groups) {
|
|
45
|
+
const box = boxes.get(nodeId);
|
|
46
|
+
const other = (e) => boxes.get(side === 'out' ? e.to : e.from);
|
|
47
|
+
list.sort((a, b) => other(a).cy - other(b).cy || other(a).left - other(b).left || cmp(a.id, b.id));
|
|
48
|
+
const n = list.length;
|
|
49
|
+
const usable = box.bottom - box.top - PORT_INSET * 2;
|
|
50
|
+
const step = n > 1 ? Math.min(PORT_STEP, usable / (n - 1)) : 0;
|
|
51
|
+
list.forEach((e, i) => ports.set(e.id, r2(box.cy + (i - (n - 1) / 2) * step)));
|
|
52
|
+
}
|
|
53
|
+
return ports;
|
|
54
|
+
}
|
|
55
|
+
function curve(p, q) {
|
|
56
|
+
const dx = Math.max(16, (q.x - p.x) / 2);
|
|
57
|
+
return `C${r2(p.x + dx)} ${r2(p.y)} ${r2(q.x - dx)} ${r2(q.y)} ${r2(q.x)} ${r2(q.y)}`;
|
|
58
|
+
}
|
|
59
|
+
function bezierMid(p, q) {
|
|
60
|
+
// 수평 접선 3차 베지어의 t=0.5 지점은 두 끝점의 한가운데다
|
|
61
|
+
return { x: r2((p.x + q.x) / 2), y: r2((p.y + q.y) / 2) };
|
|
62
|
+
}
|
|
63
|
+
/** 카드가 서는 x 구간을 합친 목록. 레이어 열 하나가 구간 하나다 */
|
|
64
|
+
function columnsOf(boxes) {
|
|
65
|
+
const spans = [...boxes]
|
|
66
|
+
.map((b) => ({ left: b.left, right: b.right }))
|
|
67
|
+
.sort((a, b) => a.left - b.left);
|
|
68
|
+
const out = [];
|
|
69
|
+
for (const s of spans) {
|
|
70
|
+
const last = out[out.length - 1];
|
|
71
|
+
if (last && s.left <= last.right)
|
|
72
|
+
last.right = Math.max(last.right, s.right);
|
|
73
|
+
else
|
|
74
|
+
out.push({ ...s });
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* elk가 더미 노드 자리로 낸 수평 구간을 경유점으로 뽑는다. 사이 레인의 카드를 피해 가는 길이다.
|
|
80
|
+
* 구간은 지나는 카드 열 폭으로 줄인다. elk는 레이어 사이 틈 아무 데서나 꺾는데, 그대로 두면 곡선이 좁은 틈에서 급하게 꺾인다
|
|
81
|
+
*/
|
|
82
|
+
function viasOf(points, columns, minX, maxX) {
|
|
83
|
+
const vias = [];
|
|
84
|
+
for (let i = 0; i + 1 < points.length; i++) {
|
|
85
|
+
const a = points[i];
|
|
86
|
+
const b = points[i + 1];
|
|
87
|
+
if (Math.abs(a.y - b.y) > 0.5)
|
|
88
|
+
continue;
|
|
89
|
+
const lo = Math.max(Math.min(a.x, b.x) + CANVAS_PAD_X, minX);
|
|
90
|
+
const hi = Math.min(Math.max(a.x, b.x) + CANVAS_PAD_X, maxX);
|
|
91
|
+
const crossed = columns.filter((c) => c.right > lo && c.left < hi);
|
|
92
|
+
if (crossed.length === 0)
|
|
93
|
+
continue;
|
|
94
|
+
const x1 = Math.max(lo, crossed[0].left - VIA_MARGIN);
|
|
95
|
+
const x2 = Math.min(hi, crossed[crossed.length - 1].right + VIA_MARGIN);
|
|
96
|
+
if (x2 - x1 < MIN_VIA_LENGTH)
|
|
97
|
+
continue;
|
|
98
|
+
vias.push({ x1, x2, y: a.y + CANVAS_PAD_TOP });
|
|
99
|
+
}
|
|
100
|
+
vias.sort((a, b) => a.x1 - b.x1);
|
|
101
|
+
const out = [];
|
|
102
|
+
for (const v of vias) {
|
|
103
|
+
const prev = out[out.length - 1];
|
|
104
|
+
if (prev && v.x1 < prev.x2)
|
|
105
|
+
continue;
|
|
106
|
+
out.push(v);
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
function tipPath(x, y, len, half) {
|
|
111
|
+
return `M${r2(x)} ${r2(y)}L${r2(x - len)} ${r2(y - half)}L${r2(x - len)} ${r2(y + half)}Z`;
|
|
112
|
+
}
|
|
113
|
+
function tipPathLeft(x, y, len, half) {
|
|
114
|
+
return `M${r2(x)} ${r2(y)}L${r2(x + len)} ${r2(y - half)}L${r2(x + len)} ${r2(y + half)}Z`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 출발 카드 오른쪽 가운데에서 도착 카드 왼쪽 가운데로 가는 곡선을 낸다.
|
|
118
|
+
* 레인을 건너뛰는 선은 elk가 비워 둔 자리를 경유하고 왼쪽으로 돌아가는 선은 두 카드 아래로 감아 돈다.
|
|
119
|
+
* 입력만 보고 계산하므로 같은 입력이면 같은 경로가 나온다.
|
|
120
|
+
*/
|
|
121
|
+
export function routeCanvas(layout, inputs) {
|
|
122
|
+
const boxes = new Map(layout.nodes.map((n) => [n.id, toBox(n)]));
|
|
123
|
+
const elkPoints = new Map(layout.edges.map((e) => [e.id, e.points]));
|
|
124
|
+
const moved = new Set(layout.movedNodeIds ?? []);
|
|
125
|
+
const edges = [...inputs]
|
|
126
|
+
.filter((e) => e.from !== e.to && boxes.has(e.from) && boxes.has(e.to))
|
|
127
|
+
.sort((a, b) => cmp(a.id, b.id));
|
|
128
|
+
const columns = columnsOf(boxes.values());
|
|
129
|
+
const stacked = (e) => {
|
|
130
|
+
const a = boxes.get(e.from);
|
|
131
|
+
const b = boxes.get(e.to);
|
|
132
|
+
return b.left < a.right && b.right > a.left;
|
|
133
|
+
};
|
|
134
|
+
const outPorts = assignPorts(edges.filter((e) => !stacked(e)), boxes, 'out');
|
|
135
|
+
const inPorts = assignPorts(edges, boxes, 'in');
|
|
136
|
+
let maxY = layout.height + CANVAS_PAD_TOP + CANVAS_PAD_BOTTOM;
|
|
137
|
+
const routed = new Map();
|
|
138
|
+
for (const e of edges) {
|
|
139
|
+
const src = boxes.get(e.from);
|
|
140
|
+
const dst = boxes.get(e.to);
|
|
141
|
+
const half = r2(3.5 + e.width * 0.45);
|
|
142
|
+
const len = r2(7 + e.width * 0.5);
|
|
143
|
+
const start = { x: src.right, y: outPorts.get(e.id) };
|
|
144
|
+
const tipX = dst.left;
|
|
145
|
+
const end = { x: tipX - len + 1, y: inPorts.get(e.id) };
|
|
146
|
+
const reverse = dst.left < src.right + 8;
|
|
147
|
+
let d;
|
|
148
|
+
let mid;
|
|
149
|
+
if (e.backward && dst.right + 8 <= src.left) {
|
|
150
|
+
const from = { x: src.left, y: outPorts.get(e.id) };
|
|
151
|
+
const tipAt = dst.right;
|
|
152
|
+
const to = { x: tipAt + len - 1, y: inPorts.get(e.id) };
|
|
153
|
+
const dx = Math.max(16, (from.x - to.x) / 2);
|
|
154
|
+
d =
|
|
155
|
+
`M${r2(from.x)} ${r2(from.y)}` +
|
|
156
|
+
`C${r2(from.x - dx)} ${r2(from.y)} ${r2(to.x + dx)} ${r2(to.y)} ${r2(to.x)} ${r2(to.y)}`;
|
|
157
|
+
mid = bezierMid(from, to);
|
|
158
|
+
routed.set(e.id, {
|
|
159
|
+
id: e.id,
|
|
160
|
+
d,
|
|
161
|
+
tip: tipPathLeft(tipAt, to.y, len, half),
|
|
162
|
+
mid,
|
|
163
|
+
reverse: true,
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (stacked(e)) {
|
|
168
|
+
// 같은 열 카드끼리는 왼쪽 바깥으로 활처럼 휘어 잇는다. 오른쪽은 다음 레인으로 가는 선 자리다
|
|
169
|
+
const from = { x: src.left, y: src.cy };
|
|
170
|
+
const bow = Math.min(STACK_BOW_MAX, 18 + Math.abs(end.y - from.y) * 0.2);
|
|
171
|
+
const outX = Math.min(from.x, end.x) - bow;
|
|
172
|
+
d =
|
|
173
|
+
`M${r2(from.x)} ${r2(from.y)}` +
|
|
174
|
+
`C${r2(outX)} ${r2(from.y)} ${r2(outX)} ${r2(end.y)} ${r2(end.x)} ${r2(end.y)}`;
|
|
175
|
+
mid = { x: r2(outX + bow * 0.25), y: r2((from.y + end.y) / 2) };
|
|
176
|
+
}
|
|
177
|
+
else if (reverse) {
|
|
178
|
+
const drop = Math.max(src.bottom, dst.bottom) + LOOP_DROP;
|
|
179
|
+
maxY = Math.max(maxY, drop + CANVAS_PAD_BOTTOM);
|
|
180
|
+
const back = end.x - LOOP_REACH;
|
|
181
|
+
d =
|
|
182
|
+
`M${r2(start.x)} ${r2(start.y)}` +
|
|
183
|
+
`C${r2(start.x + LOOP_REACH)} ${r2(start.y)} ${r2(start.x + LOOP_REACH)} ${r2(drop)} ${r2(start.x)} ${r2(drop)}` +
|
|
184
|
+
`L${r2(end.x)} ${r2(drop)}` +
|
|
185
|
+
`C${r2(back)} ${r2(drop)} ${r2(back)} ${r2(end.y)} ${r2(end.x)} ${r2(end.y)}`;
|
|
186
|
+
mid = { x: r2((start.x + end.x) / 2), y: r2(drop) };
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const stale = moved.has(e.from) || moved.has(e.to);
|
|
190
|
+
const vias = viasOf(stale ? [] : (elkPoints.get(e.id) ?? []), columns, start.x + VIA_CLEARANCE, end.x - VIA_CLEARANCE);
|
|
191
|
+
const parts = [`M${r2(start.x)} ${r2(start.y)}`];
|
|
192
|
+
let at = start;
|
|
193
|
+
for (const v of vias) {
|
|
194
|
+
parts.push(curve(at, { x: v.x1, y: v.y }), `L${r2(v.x2)} ${r2(v.y)}`);
|
|
195
|
+
at = { x: v.x2, y: v.y };
|
|
196
|
+
}
|
|
197
|
+
parts.push(curve(at, end));
|
|
198
|
+
d = parts.join('');
|
|
199
|
+
const middle = vias[Math.floor(vias.length / 2)];
|
|
200
|
+
mid = middle
|
|
201
|
+
? { x: r2((middle.x1 + middle.x2) / 2), y: r2(middle.y) }
|
|
202
|
+
: bezierMid(start, end);
|
|
203
|
+
}
|
|
204
|
+
routed.set(e.id, { id: e.id, d, tip: tipPath(tipX, end.y, len, half), mid, reverse });
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
width: r2(layout.width + CANVAS_PAD_X * 2),
|
|
208
|
+
height: r2(maxY),
|
|
209
|
+
edges: routed,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=canvas-geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-geometry.js","sourceRoot":"","sources":["../../../src/architecture/canvas-geometry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CodeownersRule {
|
|
2
|
+
pattern: string;
|
|
3
|
+
owners: string[];
|
|
4
|
+
/** `*` 하나뿐인 규칙. 레포 전체에 기본 담당을 거는 줄이라 실제 담당과 따로 센다 */
|
|
5
|
+
catchAll: boolean;
|
|
6
|
+
re: RegExp;
|
|
7
|
+
}
|
|
8
|
+
export interface OwnerMatch {
|
|
9
|
+
owners: string[];
|
|
10
|
+
catchAll: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** GitHub CODEOWNERS 문법. 뒤에 나온 규칙이 이기고 담당이 빈 규칙은 담당을 지운다 */
|
|
13
|
+
export declare function parseCodeowners(text: string): CodeownersRule[];
|
|
14
|
+
export declare function ownersOf(rules: readonly CodeownersRule[], path: string): OwnerMatch | undefined;
|
|
15
|
+
export declare function readCodeowners(root: string): CodeownersRule[];
|
|
16
|
+
//# sourceMappingURL=codeowners.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeowners.d.ts","sourceRoot":"","sources":["../../../src/architecture/codeowners.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAS9D;AAwBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAQ/F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAM7D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const LOCATIONS = ['.github/CODEOWNERS', 'CODEOWNERS', 'docs/CODEOWNERS'];
|
|
4
|
+
/** GitHub CODEOWNERS 문법. 뒤에 나온 규칙이 이기고 담당이 빈 규칙은 담당을 지운다 */
|
|
5
|
+
export function parseCodeowners(text) {
|
|
6
|
+
const rules = [];
|
|
7
|
+
for (const raw of text.split('\n')) {
|
|
8
|
+
const line = raw.replace(/(^|\s)#.*$/, '').trim();
|
|
9
|
+
if (line === '')
|
|
10
|
+
continue;
|
|
11
|
+
const [pattern, ...owners] = line.split(/\s+/);
|
|
12
|
+
rules.push({ pattern: pattern, owners, catchAll: pattern === '*', re: patternRe(pattern) });
|
|
13
|
+
}
|
|
14
|
+
return rules;
|
|
15
|
+
}
|
|
16
|
+
function patternRe(pattern) {
|
|
17
|
+
const anchored = pattern.startsWith('/') || pattern.replace(/\/$/, '').includes('/');
|
|
18
|
+
const dir = pattern.endsWith('/');
|
|
19
|
+
const glob = pattern.replace(/^\//, '').replace(/\/$/, '');
|
|
20
|
+
let body = '';
|
|
21
|
+
for (let i = 0; i < glob.length; i++) {
|
|
22
|
+
const c = glob[i];
|
|
23
|
+
if (c === '*' && glob[i + 1] === '*') {
|
|
24
|
+
// `a/**`는 그 아래 전부, `a/**/b`는 중간 폴더 몇 단이든
|
|
25
|
+
const end = i + 2 === glob.length;
|
|
26
|
+
body += end ? '.*' : '(?:.*/)?';
|
|
27
|
+
i += glob[i + 2] === '/' ? 2 : 1;
|
|
28
|
+
}
|
|
29
|
+
else if (c === '*')
|
|
30
|
+
body += '[^/]*';
|
|
31
|
+
else if (c === '?')
|
|
32
|
+
body += '[^/]';
|
|
33
|
+
else
|
|
34
|
+
body += c.replace(/[.+^${}()|[\]\\]/, '\\$&');
|
|
35
|
+
}
|
|
36
|
+
const head = anchored ? '^' : '^(?:.*/)?';
|
|
37
|
+
// 폴더 규칙은 그 아래 전부, 파일 규칙도 같은 이름 폴더면 그 아래까지 덮는다. `docs/*`는 바로 아래만 덮는다
|
|
38
|
+
const tail = dir ? '/' : /(^|[^*])\*$/.test(pattern) && anchored ? '$' : '(?:/|$)';
|
|
39
|
+
return new RegExp(`${head}${body}${tail}`);
|
|
40
|
+
}
|
|
41
|
+
export function ownersOf(rules, path) {
|
|
42
|
+
const p = path.replace(/^\.?\//, '');
|
|
43
|
+
for (let i = rules.length - 1; i >= 0; i--) {
|
|
44
|
+
const r = rules[i];
|
|
45
|
+
if (r.re.test(p))
|
|
46
|
+
return r.owners.length > 0 ? { owners: r.owners, catchAll: r.catchAll } : undefined;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
export function readCodeowners(root) {
|
|
51
|
+
for (const loc of LOCATIONS) {
|
|
52
|
+
const file = join(root, loc);
|
|
53
|
+
if (existsSync(file))
|
|
54
|
+
return parseCodeowners(readFileSync(file, 'utf-8'));
|
|
55
|
+
}
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=codeowners.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeowners.js","sourceRoot":"","sources":["../../../src/architecture/codeowners.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ArchitectureNode, type ArchitectureProjection } from './types.js';
|
|
2
|
+
export type CompareColumnKey = 'left' | 'both' | 'right';
|
|
3
|
+
export interface CompareColumn {
|
|
4
|
+
key: CompareColumnKey;
|
|
5
|
+
title: string;
|
|
6
|
+
count: number;
|
|
7
|
+
x: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}
|
|
11
|
+
export interface CompareCard {
|
|
12
|
+
id: string;
|
|
13
|
+
column: CompareColumnKey;
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
export interface CompareLayout {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
columns: CompareColumn[];
|
|
23
|
+
cards: CompareCard[];
|
|
24
|
+
}
|
|
25
|
+
/** 그려지는 노드만 받아 세 열에 나눠 세운다. 열 안 순서는 묶음에 적은 순서다 */
|
|
26
|
+
export declare function computeCompareLayout(projection: ArchitectureProjection, drawable: ReadonlySet<string>, nodeById: ReadonlyMap<string, ArchitectureNode>): CompareLayout;
|
|
27
|
+
//# sourceMappingURL=compare-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-layout.d.ts","sourceRoot":"","sources":["../../../src/architecture/compare-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC5B,MAAM,YAAY,CAAC;AAYpB,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,gBAAgB,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,gBAAgB,CAAC;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAMD,kDAAkD;AAClD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,sBAAsB,EAClC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,EAC7B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,aAAa,CA2Df"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { measureNode, textUnits } from './layout.js';
|
|
2
|
+
import { chipTextOverride, displayKindOf, } from './types.js';
|
|
3
|
+
// compare는 세 열로 선다. 왼쪽 묶음에만, 둘 다, 오른쪽 묶음에만. 가운데가 겹치는 것이라 눈이 먼저 간다
|
|
4
|
+
const HEAD = 56;
|
|
5
|
+
const ROW_GAP = 20;
|
|
6
|
+
const COL_GAP = 56;
|
|
7
|
+
const COL_MIN = 180;
|
|
8
|
+
const COL_PAD = 20;
|
|
9
|
+
const HEAD_CHAR = 8;
|
|
10
|
+
const EMPTY_ROW = 40;
|
|
11
|
+
const TAIL = 24;
|
|
12
|
+
function round2(v) {
|
|
13
|
+
return Math.round(v * 100) / 100;
|
|
14
|
+
}
|
|
15
|
+
/** 그려지는 노드만 받아 세 열에 나눠 세운다. 열 안 순서는 묶음에 적은 순서다 */
|
|
16
|
+
export function computeCompareLayout(projection, drawable, nodeById) {
|
|
17
|
+
const [left, right] = projection.sides;
|
|
18
|
+
const keep = (ids) => [
|
|
19
|
+
...new Set(ids.filter((id) => drawable.has(id) && nodeById.has(id))),
|
|
20
|
+
];
|
|
21
|
+
const leftIds = keep(left.nodes);
|
|
22
|
+
const rightIds = keep(right.nodes);
|
|
23
|
+
const inRight = new Set(rightIds);
|
|
24
|
+
const inLeft = new Set(leftIds);
|
|
25
|
+
const groups = [
|
|
26
|
+
{ key: 'left', title: `${left.label}에만`, ids: leftIds.filter((id) => !inRight.has(id)) },
|
|
27
|
+
{ key: 'both', title: '둘 다', ids: leftIds.filter((id) => inRight.has(id)) },
|
|
28
|
+
{ key: 'right', title: `${right.label}에만`, ids: rightIds.filter((id) => !inLeft.has(id)) },
|
|
29
|
+
];
|
|
30
|
+
const sizeOf = (id) => {
|
|
31
|
+
const n = nodeById.get(id);
|
|
32
|
+
const chip = chipTextOverride(n);
|
|
33
|
+
return measureNode(n.label, n.displayName, n.displayNameInferred, displayKindOf(n), {
|
|
34
|
+
...(chip !== undefined ? { chip } : {}),
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const columns = [];
|
|
38
|
+
const cards = [];
|
|
39
|
+
let x = 0;
|
|
40
|
+
let tallest = 0;
|
|
41
|
+
for (const g of groups) {
|
|
42
|
+
const sizes = g.ids.map(sizeOf);
|
|
43
|
+
const width = Math.max(COL_MIN, (textUnits(g.title) + 4) * HEAD_CHAR, ...sizes.map((s) => s.width + COL_PAD * 2));
|
|
44
|
+
let y = HEAD;
|
|
45
|
+
g.ids.forEach((id, i) => {
|
|
46
|
+
const s = sizes[i];
|
|
47
|
+
cards.push({
|
|
48
|
+
id,
|
|
49
|
+
column: g.key,
|
|
50
|
+
x: round2(x + (width - s.width) / 2),
|
|
51
|
+
y,
|
|
52
|
+
width: s.width,
|
|
53
|
+
height: s.height,
|
|
54
|
+
});
|
|
55
|
+
y += s.height + ROW_GAP;
|
|
56
|
+
});
|
|
57
|
+
const height = g.ids.length > 0 ? y - ROW_GAP + COL_PAD : HEAD + EMPTY_ROW;
|
|
58
|
+
tallest = Math.max(tallest, height);
|
|
59
|
+
columns.push({ key: g.key, title: g.title, count: g.ids.length, x: round2(x), width, height });
|
|
60
|
+
x += width + COL_GAP;
|
|
61
|
+
}
|
|
62
|
+
// 열 배경은 가장 긴 열에 맞춰 같은 높이로 그린다. 짧은 열이 비어 보이는 게 곧 차이다
|
|
63
|
+
for (const c of columns)
|
|
64
|
+
c.height = round2(tallest);
|
|
65
|
+
return {
|
|
66
|
+
width: round2(x - COL_GAP),
|
|
67
|
+
height: round2(tallest + TAIL),
|
|
68
|
+
columns,
|
|
69
|
+
cards,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=compare-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-layout.js","sourceRoot":"","sources":["../../../src/architecture/compare-layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ArchitectureNode, type ArchitectureProjection } from './types.js';
|
|
2
|
+
export interface DataflowCard {
|
|
3
|
+
id: string;
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export interface DataflowEdge {
|
|
10
|
+
id: string;
|
|
11
|
+
/** SVG path d */
|
|
12
|
+
d: string;
|
|
13
|
+
/** 화살촉 세 점. 끝점, 왼쪽 날개, 오른쪽 날개 */
|
|
14
|
+
tip: [string, string, string];
|
|
15
|
+
labelX: number;
|
|
16
|
+
labelY: number;
|
|
17
|
+
}
|
|
18
|
+
export interface DataflowLayout {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
cards: DataflowCard[];
|
|
22
|
+
edges: DataflowEdge[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 그릴 메시지만 받아 좌표를 정한다. 같은 입력이면 같은 좌표가 나온다.
|
|
26
|
+
* 열은 되돌아가는 선을 뺀 뒤 가장 긴 경로로 정한다. 같은 열 안 순서는 participants, 없으면 처음 나온 순서다
|
|
27
|
+
*/
|
|
28
|
+
export declare function computeDataflowLayout(projection: ArchitectureProjection, drawn: ReadonlySet<string>, nodeById: ReadonlyMap<string, ArchitectureNode>): DataflowLayout;
|
|
29
|
+
//# sourceMappingURL=dataflow-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow-layout.d.ts","sourceRoot":"","sources":["../../../src/architecture/dataflow-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC5B,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,iCAAiC;IACjC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AA0CD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,sBAAsB,EAClC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC9C,cAAc,CA+KhB"}
|