@cardenelabs/dragon 0.30.0 → 0.32.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 (55) hide show
  1. package/README.md +314 -12
  2. package/dist/index.cjs +6966 -1438
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +2150 -118
  5. package/dist/index.d.ts +2150 -118
  6. package/dist/index.js +6950 -1440
  7. package/dist/index.js.map +1 -1
  8. package/package.json +12 -13
  9. package/src/compile/actor-ids.ts +6 -15
  10. package/src/compile/actor-option-notice.ts +379 -0
  11. package/src/compile/actors.ts +32 -3
  12. package/src/compile/c4.ts +0 -3
  13. package/src/compile/chain.ts +43 -4
  14. package/src/compile/chart-fields.ts +16 -1
  15. package/src/compile/direction.ts +50 -11
  16. package/src/compile/edge-option-notice.ts +112 -0
  17. package/src/compile/flowchart.ts +344 -0
  18. package/src/compile/funnel.ts +14 -2
  19. package/src/compile/gantt.ts +141 -36
  20. package/src/compile/generic.ts +473 -61
  21. package/src/compile/journey.ts +14 -5
  22. package/src/compile/kinds.ts +5 -13
  23. package/src/compile/lanes.ts +95 -13
  24. package/src/compile/metro.ts +271 -0
  25. package/src/compile/mind.ts +55 -5
  26. package/src/compile/notice.ts +51 -4
  27. package/src/compile/order.ts +62 -0
  28. package/src/compile/parts.ts +107 -33
  29. package/src/compile/placement-apply.ts +27 -11
  30. package/src/compile/quadrant.ts +171 -16
  31. package/src/compile/record.ts +75 -0
  32. package/src/compile/row-marks.ts +128 -0
  33. package/src/compile/sequence.ts +105 -26
  34. package/src/compile/slug.ts +9 -1
  35. package/src/compile/stages.ts +247 -0
  36. package/src/compile/subtitle.ts +15 -2
  37. package/src/compile/swimlane-marks.ts +87 -0
  38. package/src/compile/swimlane.ts +13 -14
  39. package/src/compile/timeline.ts +213 -0
  40. package/src/compile/topology.ts +3 -9
  41. package/src/compile/tree.ts +13 -4
  42. package/src/compile/value-chart.ts +179 -25
  43. package/src/compile.ts +1550 -370
  44. package/src/focus.ts +2 -2
  45. package/src/index.ts +34 -2
  46. package/src/json-parser.ts +1407 -48
  47. package/src/keywords.ts +251 -17
  48. package/src/notation-lint.ts +41 -64
  49. package/src/schemas/diagram.json +643 -20
  50. package/src/types.ts +336 -35
  51. package/src/v05/parser.ts +2451 -271
  52. package/src/compile/class.ts +0 -100
  53. package/src/compile/er.ts +0 -44
  54. package/src/compile/solidity.ts +0 -39
  55. package/src/compile/state.ts +0 -71
@@ -1,100 +0,0 @@
1
- import { diagram, classDiagram } from "@cardenelabs/cdl";
2
- import type { CdlDiagram } from "@cardenelabs/cdl";
3
- import type { DslDocument } from "../types";
4
-
5
- import { 箱の題 } from "./node-title";
6
-
7
- import { slugify } from "./slug";
8
-
9
- /**
10
- * クラス図の組み立て。
11
- *
12
- * 各クラスを 1 つの箱 (`storage`) にする。 描画側は題 (クラス名) と区切り線と行
13
- * (項目 / 手続き) を UML のクラス箱として描く。
14
- *
15
- * **クラスごとに縦列を 1 本作り、横に並べる** (#1263)。 組立て API 側がそう並べており、
16
- * 1 本にまとめると同じ内容でも横並びが縦並びになる (実測 = 見本は 3 縦列 450 幅)。
17
- * 縦列に見出しは付けない = クラスの名前は箱が既に描いており、縦列は並べるための入れ物
18
- * (`er` / `state` と同じ扱い、#1241)。
19
- *
20
- * 箱の種類は `storage` に強制する。 行と小見出しは `applyV05Extensions` が後から載せる。
21
- *
22
- * 矢印は継承や保有を表す (`extends` / `aggregates` 等を書き手が説明に書く)。
23
- */
24
- export function compileClass(doc: DslDocument): CdlDiagram {
25
- /*
26
- * **組み立て器 (`classDiagram`) に渡す** (#1466)。
27
- *
28
- * 以前は箱と矢印を直に組んでいたため、行頭の印・端の塗り・印が付く側・段の配置が
29
- * 1 つも出なかった = 画面の図と記法の図が別物になっていた。 組み立て器へ渡せば、
30
- * 意匠の決まり (`CLASS_RELATION_LOOK`) を 1 箇所から引ける。
31
- */
32
- const b = classDiagram({ id: slugify(doc.title), topic: doc.title });
33
- // 登場人物が 0 人なら枠も作らない。 先に作ると中身の無い枠が 1 つ残る (#1096)
34
- if (doc.actors.length === 0)
35
- return diagram(slugify(doc.title), { topic: doc.title, type: "class" }).build();
36
-
37
- /*
38
- * 縦列は `lane:` の順、段は `stack:` で決まる (#1466)。
39
- *
40
- * 書かない図は宣言した順に横 1 列 = 従来どおり。 1 つでも書けば格子に置く =
41
- * **箱の 1 つの辺には関係を 1 本まで** を守るには段が要る。
42
- */
43
- const 列番号 = new Map<string, number>();
44
- for (const a of doc.actors) {
45
- if (a.lane === undefined) continue;
46
- if (!列番号.has(a.lane)) 列番号.set(a.lane, 列番号.size);
47
- }
48
-
49
- for (const a of doc.actors) {
50
- /*
51
- * 行を持ち物と振る舞いに割る (#1466)。 **1 行ずつ括弧の有無で見る**。
52
- *
53
- * 区切りの行 (`───`) の位置では割らない = 振る舞いしか持たない箱は区切りを書けず、
54
- * 全部が持ち物に落ちる (実測 = `Auditable` の `audit()` が四角の印で出た)。
55
- * 区切りの行そのものは、組み立て器が群の間を空の行で作るので捨てる。
56
- */
57
- const rows = (a.rows ?? []).filter((r) => !/^[─-]+$/.test(r.trim()));
58
- const 振る舞い = (r: string): boolean => r.includes("(");
59
- const attributes = rows.filter((r) => !振る舞い(r));
60
- const methods = rows.filter(振る舞い);
61
- b.class({
62
- id: slugify(a.name),
63
- title: 箱の題(a),
64
- ...(attributes.length > 0 ? { attributes: [...attributes] } : {}),
65
- ...(methods.length > 0 ? { methods: [...methods] } : {}),
66
- ...(a.eyebrow ? { stereotype: a.eyebrow } : {}),
67
- ...(a.lane !== undefined ? { col: 列番号.get(a.lane) ?? 0 } : {}),
68
- ...(a.stack !== undefined ? { row: a.stack } : {}),
69
- });
70
- }
71
-
72
- for (const s2 of doc.flow) {
73
- b.relation({
74
- from: slugify(s2.from),
75
- to: slugify(s2.to),
76
- // 種類を書かない矢印は「使う」 扱い = 端が開いた矢になり、線と印の組が最も素直
77
- type: s2.relation ?? "uses",
78
- ...(s2.label ? { label: s2.label } : {}),
79
- ...(s2.sub ? { cardinality: s2.sub } : {}),
80
- // 出どころ側の多重度 (#1771)。 engine が出どころの端に添える (cdl#825)
81
- ...(s2.tailSub ? { tailCardinality: s2.tailSub } : {}),
82
- ...(s2.tone ? { tone: s2.tone } : {}),
83
- ...(s2.style ? { style: s2.style } : {}),
84
- ...(s2.head ? { head: s2.head } : {}),
85
- ...(s2.headFill ? { headFill: s2.headFill } : {}),
86
- ...(s2.tailHead ? { tailHead: s2.tailHead } : {}),
87
- });
88
- }
89
-
90
- const built = b.build();
91
- /*
92
- * 記法が段を書いた図では、組み立て器が作る 1 つの段を捨てる (#1466)。
93
- *
94
- * 段の注入 (`injectPhasesFallback`) は「段が 1 つも無い」 図にだけ効く。 組み立て器へ
95
- * 渡すようにしたことで自動の段が 1 つ付き、書いた段が届かなくなった (実測 = 6 段書いた
96
- * 図が 1 段で出た)。
97
- */
98
- const 書いた段がある = (doc.animate?.phases.length ?? 0) > 0;
99
- return 書いた段がある ? { ...built, phases: [] } : built;
100
- }
package/src/compile/er.ts DELETED
@@ -1,44 +0,0 @@
1
- import { er } from "@cardenelabs/cdl";
2
- import { 箱の題 } from "./node-title";
3
- import type { CdlDiagram } from "@cardenelabs/cdl";
4
- import type { DslDocument } from "../types";
5
-
6
- import { ERの関係の指定を作る } from "./er-relation";
7
- import { compileGenericWithAnimate } from "./generic";
8
-
9
- import { slugify } from "./slug";
10
-
11
- export function compileEr(doc: DslDocument): CdlDiagram {
12
- // v0.4 ... animation あり時 builder 直接経路 (entity を box として配置)
13
- if (doc.animate && doc.animate.phases.length > 0) {
14
- // 460 は preset 側の旧既定に合わせた値だった。 preset が箱 400 + 余白 25 × 2 = 450 を
15
- // 宣言するようになった (cardene777/cdl#359) ので、 同じ図が animate の有無で 10 world
16
- // ずれないようここも 450 にする。
17
- return compileGenericWithAnimate(doc, { kind: "er", laneWidth: 450 });
18
- }
19
- // er preset ... actors を entity に、 流れ を relation に
20
- const erBuilder = er({
21
- id: slugify(doc.title),
22
- topic: doc.title,
23
- });
24
- for (const a of doc.actors) {
25
- // entity rows は DSL では宣言できないので、 actor 名のみ entity 化
26
- // v0.3 で「列定義」 ブロックを追加検討
27
- erBuilder.entity({
28
- id: slugify(a.name) || a.name,
29
- title: 箱の題(a),
30
- rows: [], // v0.2 では rows なし
31
- });
32
- }
33
- for (const s of doc.flow) {
34
- // 多重度と名前と端は、段を持つ図と同じ 1 か所で決める (#2105)。
35
- // 語を書かない関係に `1:N` を補わない = 書いていない語を字と端に出さない
36
- erBuilder.relation({
37
- from: slugify(s.from),
38
- to: slugify(s.to),
39
- ...ERの関係の指定を作る(s),
40
- ...(s.tone ? { tone: s.tone } : {}),
41
- });
42
- }
43
- return erBuilder.build();
44
- }
@@ -1,39 +0,0 @@
1
- import type { CdlDiagram } from "@cardenelabs/cdl";
2
- import type { DslDocument } from "../types";
3
- import { compileSequence } from "./sequence";
4
- /**
5
- * Solidity 専用 preset。
6
- *
7
- * 設計:
8
- * - actors を kind=contract / eoa / multisig 等で配置 (EOA は左、 contract は中央、 storage は右など layered layout)
9
- * - flow は function call の sequence (msg.sender → contract.fn() → internal call → emit event)
10
- * - storage 更新は state + rows binding で自動 (kind: storage の actor に rows: ["bal[A]: {balA}", ...])
11
- * - event は kind: event の actor を右端に並べ、 emit edge で発火を表現
12
- * - revert は tone: error の edge で表現
13
- *
14
- * sequence preset を base に使い、 Solidity 文脈に最適化した default を載せる:
15
- * - default tone: accent (call) / success (emit) / error (revert)
16
- * - default style: solid (call) / dotted-flow (state-change)
17
- */
18
- export function compileSolidity(doc: DslDocument): CdlDiagram {
19
- // sequence preset と同等構造で組み立てる、 lane 順は eoa / contract / storage / event の優先順で sort
20
- const kindOrder: Record<string, number> = {
21
- eoa: 0,
22
- actor: 0,
23
- multisig: 0,
24
- signer: 0,
25
- wallet: 0,
26
- contract: 1,
27
- proxy: 1,
28
- library: 1,
29
- interface: 1,
30
- storage: 2,
31
- event: 3,
32
- };
33
- const sorted = [...doc.actors].sort(
34
- (a, b) => (kindOrder[a.kind] ?? 5) - (kindOrder[b.kind] ?? 5),
35
- );
36
- // sorted を doc.actors に上書きしてから sequence preset 経由で compile
37
- const sortedDoc: DslDocument = { ...doc, actors: sorted };
38
- return compileSequence(sortedDoc);
39
- }
@@ -1,71 +0,0 @@
1
- import { stateMachine } from "@cardenelabs/cdl";
2
- import type { NodeKind } from "@cardenelabs/cdl";
3
- import { 箱の題 } from "./node-title";
4
- import type { CdlDiagram } from "@cardenelabs/cdl";
5
- import type { DslDocument } from "../types";
6
-
7
- import { compileGenericWithAnimate } from "./generic";
8
- import { 描ける種別 } from "./kinds";
9
-
10
- import { slugify } from "./slug";
11
- import { 始まりと終わりの決め方 } from "./actors";
12
- export function compileState(doc: DslDocument): CdlDiagram {
13
- // v0.4 ... animation あり時 builder 直接経路 (各 state を lane で配置、 transition を edge)
14
- //
15
- // **種類を書いた形は動きの有無に関わらず generic 経路へ** (#1450、 #1263 と同じ理由)。
16
- // 動く図だけで効かせると、同じ記法でも静止図では指定が黙って消える
17
- // (実測 = `kind: mark-start` を書いた箱が `card` になり知らせも出ない)
18
- if ((doc.animate && doc.animate.phases.length > 0) || 既定と違う種類を書いた(doc)) {
19
- return compileGenericWithAnimate(doc, { kind: "state", laneWidth: 360 });
20
- }
21
- // stateMachine preset ... actors を state に、 流れ を transition に
22
- const fsm = stateMachine({
23
- id: slugify(doc.title),
24
- topic: doc.title,
25
- });
26
- const 決め方 = 始まりと終わりの決め方(doc);
27
- for (let i = 0; i < doc.actors.length; i++) {
28
- const a = doc.actors[i]!;
29
- // 書いた `initial:` / `final:` が勝つ。 1 つも書いていなければ順序で決める
30
- const initial = 決め方.始まり(a, i);
31
- const final = 決め方.終わり(a, i);
32
- fsm.state({
33
- id: slugify(a.name) || `s${i}`,
34
- title: 箱の題(a),
35
- ...(initial ? { initial: true } : {}),
36
- ...(final ? { final: true } : {}),
37
- });
38
- }
39
- for (const s of doc.flow) {
40
- fsm.transition({
41
- from: slugify(s.from),
42
- to: slugify(s.to),
43
- trigger: s.label,
44
- ...(s.sub ? { guard: s.sub } : {}),
45
- ...(s.tone ? { tone: s.tone } : {}),
46
- });
47
- }
48
- return fsm.build();
49
- }
50
-
51
- /** 状態の図で `stateMachine` preset が全ての箱に使う種類 */
52
- export const 状態の図の既定の種類: NodeKind = "card";
53
-
54
- /**
55
- * 状態の図で、既定と違う種類を書いた登場人物がいるか (#1450)。
56
- *
57
- * `stateMachine` preset は全ての状態を `card` で描くため、書いた `kind:` が黙って消える。
58
- * 始点終点の印 (`mark-start` / `mark-end`) を書けるようにするには、書いた形を効かせる必要がある。
59
- *
60
- * **「書いたか」 だけでは広すぎる**。 記法だけの種類 (`kind: state` 等) は `card` に読み替わり、
61
- * preset の出す形と同じになる = 書いても何も変わらないので経路を切り替える理由が無い。
62
- * 切り替えると既存の図の id と枠の作りが変わる (実測で golden 8 件が落ちた)。
63
- *
64
- * 読み替えた後の種類が既定と違う時だけ切り替える。 こうすると「書いたのに効かない」 は消え、
65
- * 「書いたが結果が同じ」 は従来の経路に留まる。
66
- */
67
- export function 既定と違う種類を書いた(doc: DslDocument): boolean {
68
- return doc.actors.some(
69
- (a) => a.kindWritten === true && 描ける種別(a.kind) !== 状態の図の既定の種類,
70
- );
71
- }