@cardenelabs/cdl 0.79.0 → 0.81.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/CHANGELOG.md CHANGED
@@ -5,6 +5,62 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.81.0] - 2026-09-27
9
+
10
+ ### Fixed
11
+
12
+ - **速さの判定が機械の混み具合で動かなくなった** (#897 / #898)
13
+
14
+ 軸 `validate-performance-budget` は検査に掛かった時間を壁時計 (`Date.now()`) で測っていた。
15
+ 壁時計は待たされた分も足すため、値が図の性質ではなく機械の混み具合で動く。
16
+
17
+ | 測り方 | 累計の幅 (使う側の図 599 枚を 3 周) |
18
+ |---|---|
19
+ | その検査だけを回す (5 回) | 335..1739ms |
20
+ | 検査を一式回す (5 回) | 806..2468ms |
21
+
22
+ 同じ入力で 7.4 倍ぶれていた。 境の 5000ms に対して最悪 49% なので超えてはいないが、図の
23
+ 枚数は 0.41.1 で軸を作った時の 444 枚から 599 枚に増えており、余裕は枚数の増加だけで減る。
24
+
25
+ CPU 時間で測る形にした。 待っている間は増えないため、同時に他の検査が走っても値が動かない。
26
+ `Date.now()` の 1ms 刻みでは 1 枚あたりがほとんど 0ms に丸まるが、CPU 時間はマイクロ秒で
27
+ 返るため超過時の「重い順」 の内訳も読める。 読む上乗せは 1 回 0.0008ms。
28
+
29
+ ### Added
30
+
31
+ - **掃き出しの返り値が速さの測り方を持つようになった** (#897 / #898)
32
+
33
+ `visualValidateAll` の返り値に `perfClock` (`"cpu"` または `"wall"`) が入る。
34
+ CPU 時間が読めない環境では壁時計に落ちるため、**どちらで測ったかを返り値と超過の文面の
35
+ 2 箇所に出す**。 測り方が変わったのに同じ顔で報告すると、読み手が 2 つの値を同じものとして
36
+ 並べる。
37
+
38
+ 返り値にも出すのは、超過していない周では文面が出ないため。 呼ぶ側が「CPU 時間で測れて
39
+ いるか」 を超過の有無と切り離して確かめられる。
40
+
41
+ ## [0.80.0] - 2026-09-27
42
+
43
+ ### Fixed
44
+
45
+ - **押せる箱を指すと押せる形のカーソルが出るようになった** (#869 / #896)
46
+
47
+ `relations: hover` を書いた図の箱は押せる形になるが、指しても `pointer` の cursor が
48
+ 出なかった。 読み上げには `role="button"` で「押せる」 と伝わる一方、見た目には出ない =
49
+ 読み手は触れて光るだけの箱だと読む。
50
+
51
+ 原因は同じ要素に `style` を 2 回渡していたこと。 React は後の値で前を丸ごと置き換える
52
+ ため、押せる箱に渡した `cursor: pointer` が後ろの `transition` に消されていた。
53
+
54
+ | 項目 | 直す前 | 直した後 |
55
+ |---|---|---|
56
+ | 押せる箱の `style` | `transition` だけ | `transition` と `cursor: pointer` |
57
+ | 押せない箱の `style` | `transition` だけ | 変えない |
58
+
59
+ `style` を 1 箇所でまとめて作り、要素へ 1 回だけ渡す形にした。 条件つきで広げる側には
60
+ 置かない = そこに残すと、後ろに `style` を 1 つ足しただけでまた黙って消える。
61
+
62
+ 押せない箱の cursor は親から継承したままにする (編集画面では掴む形になる)。
63
+
8
64
  ## [0.79.0] - 2026-09-27
9
65
 
10
66
  ### Fixed
@@ -3256,7 +3312,9 @@ Initial OSS release.
3256
3312
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
3257
3313
  行き止まりになる。
3258
3314
 
3259
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.79.0...HEAD
3315
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.81.0...HEAD
3316
+ [0.81.0]: https://github.com/cardene777/cdl/compare/v0.80.0...v0.81.0
3317
+ [0.80.0]: https://github.com/cardene777/cdl/compare/v0.79.0...v0.80.0
3260
3318
  [0.79.0]: https://github.com/cardene777/cdl/compare/v0.78.0...v0.79.0
3261
3319
  [0.78.0]: https://github.com/cardene777/cdl/compare/v0.77.0...v0.78.0
3262
3320
  [0.77.0]: https://github.com/cardene777/cdl/compare/v0.76.0...v0.77.0
package/dist/index.cjs CHANGED
@@ -18411,11 +18411,12 @@ function runAxes(laid, diag, violations, counts, push, profile, skippedAxes, \u5
18411
18411
  }
18412
18412
  function visualValidateAll(diagrams, opts) {
18413
18413
  \u5668\u3092\u78BA\u304B\u3081\u308B(opts?.container);
18414
+ const \u6642\u8A08 = perfClock();
18414
18415
  const durations = [];
18415
18416
  const reports = diagrams.map((d) => {
18416
- const start = Date.now();
18417
+ const \u6B62\u3081\u308B = \u6642\u8A08.\u6E2C\u308B();
18417
18418
  const r = visualValidate(d, opts);
18418
- durations.push(Date.now() - start);
18419
+ durations.push(\u6B62\u3081\u308B());
18419
18420
  return r;
18420
18421
  });
18421
18422
  const fail = reports.filter((r) => !r.ok).length;
@@ -18425,7 +18426,7 @@ function visualValidateAll(diagrams, opts) {
18425
18426
  totalCounts[axis] += r.counts[axis];
18426
18427
  }
18427
18428
  }
18428
- const metaViolations = validateMetaAxes(totalCounts, diagrams, durations, reports);
18429
+ const metaViolations = validateMetaAxes(totalCounts, diagrams, durations, reports, \u6642\u8A08.kind);
18429
18430
  return {
18430
18431
  total: reports.length,
18431
18432
  pass: reports.length - fail,
@@ -18434,12 +18435,35 @@ function visualValidateAll(diagrams, opts) {
18434
18435
  totalCounts,
18435
18436
  profile: opts?.profile ?? "production",
18436
18437
  skippedAxes: [...SKIPPED_AXES[opts?.profile ?? "production"]],
18437
- metaViolations
18438
+ metaViolations,
18439
+ perfClock: \u6642\u8A08.kind
18438
18440
  };
18439
18441
  }
18440
18442
  var PERF_BUDGET_TOTAL_MS = 5e3;
18443
+ function perfClock() {
18444
+ const cpu = globalThis.process?.cpuUsage;
18445
+ if (typeof cpu === "function") {
18446
+ return {
18447
+ kind: "cpu",
18448
+ \u6E2C\u308B: () => {
18449
+ const \u59CB\u3081 = cpu();
18450
+ return () => {
18451
+ const \u5DEE = cpu(\u59CB\u3081);
18452
+ return (\u5DEE.user + \u5DEE.system) / 1e3;
18453
+ };
18454
+ }
18455
+ };
18456
+ }
18457
+ return {
18458
+ kind: "wall",
18459
+ \u6E2C\u308B: () => {
18460
+ const \u59CB\u3081 = Date.now();
18461
+ return () => Date.now() - \u59CB\u3081;
18462
+ }
18463
+ };
18464
+ }
18441
18465
  var PERF_SLOWEST_SAMPLE = 5;
18442
- function perfBudgetViolations(durations, diagrams = []) {
18466
+ function perfBudgetViolations(durations, diagrams = [], clock) {
18443
18467
  const total = durations.reduce((s, d) => s + d, 0);
18444
18468
  if (total <= PERF_BUDGET_TOTAL_MS) return [];
18445
18469
  const \u91CD\u3044\u9806 = durations.map((ms, i) => ({ id: diagrams[i]?.id ?? "?", ms })).sort((a, b) => b.ms - a.ms);
@@ -18450,12 +18474,13 @@ function perfBudgetViolations(durations, diagrams = []) {
18450
18474
  {
18451
18475
  axis: "validate-performance-budget",
18452
18476
  diagramId: "__meta__",
18453
- detail: `visualValidateAll \u5168 ${durations.length} \u56F3\u306E\u7D2F\u8A08 ${total}ms > ${PERF_BUDGET_TOTAL_MS}ms budget (\u91CD\u3044\u9806 ${\u5185\u8A33})`,
18477
+ detail: `visualValidateAll \u5168 ${durations.length} \u56F3\u306E\u7D2F\u8A08 ${total}ms > ${PERF_BUDGET_TOTAL_MS}ms budget (\u91CD\u3044\u9806 ${\u5185\u8A33})` + // 測り方が変わったのに同じ顔で報告すると、読み手が 2 つの値を同じものとして並べる
18478
+ (clock === void 0 ? "" : `\u3001 \u6E2C\u308A\u65B9 ${clock === "cpu" ? "CPU \u6642\u9593" : "\u58C1\u6642\u8A08 (CPU \u6642\u9593\u304C\u8AAD\u3081\u306A\u3044)"}`),
18454
18479
  severity: "warn"
18455
18480
  }
18456
18481
  ];
18457
18482
  }
18458
- function validateMetaAxes(totalCounts, diagrams = [], durations = [], reports = []) {
18483
+ function validateMetaAxes(totalCounts, diagrams = [], durations = [], reports = [], clock) {
18459
18484
  const out = [];
18460
18485
  const totalErrors = reports.reduce(
18461
18486
  (sum, r) => sum + r.violations.filter((v) => v.severity === "error").length,
@@ -18470,7 +18495,7 @@ function validateMetaAxes(totalCounts, diagrams = [], durations = [], reports =
18470
18495
  severity: "warn"
18471
18496
  });
18472
18497
  }
18473
- out.push(...perfBudgetViolations(durations, diagrams));
18498
+ out.push(...perfBudgetViolations(durations, diagrams, clock));
18474
18499
  const DEAD_ALLOWLIST = [
18475
18500
  // catalog で自然発火なしを許容する security / migration / performance / meta / dev-quality axis 群。
18476
18501
  // 実 diagram に該当データ (XSS / migration list / oversized / broken doc) が混入するのが稀なため。
@@ -32108,6 +32133,10 @@ function CdlNodeView({
32108
32133
  const offsetX = node.renderOffsetX !== void 0 ? resolveNumericAttr(node.renderOffsetX, stateValues, 0) : 0;
32109
32134
  const offsetY = node.renderOffsetY !== void 0 ? resolveNumericAttr(node.renderOffsetY, stateValues, 0) : 0;
32110
32135
  const hasOffset = offsetX !== 0 || offsetY !== 0;
32136
+ const \u7BB1\u306Estyle = {
32137
+ transition: "opacity 120ms ease-out, transform 200ms ease-out",
32138
+ ...\u95A2\u4FC2\u306E\u53D7\u3051\u53E3 === void 0 ? {} : { cursor: "pointer" }
32139
+ };
32111
32140
  return /* @__PURE__ */ jsxRuntime.jsxs(
32112
32141
  "g",
32113
32142
  {
@@ -32129,7 +32158,6 @@ function CdlNodeView({
32129
32158
  role: "button",
32130
32159
  tabIndex: 0,
32131
32160
  "aria-pressed": \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u7126\u70B9 === node.id,
32132
- style: { cursor: "pointer" },
32133
32161
  onPointerEnter: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
32134
32162
  onPointerLeave: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u96E2\u308C\u305F(),
32135
32163
  onFocus: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
@@ -32144,7 +32172,7 @@ function CdlNodeView({
32144
32172
  transform: hasOffset ? `translate(${offsetX}, ${offsetY})` : void 0,
32145
32173
  opacity: boundOpacity,
32146
32174
  "data-cdl-tone": node.tone,
32147
- style: { transition: "opacity 120ms ease-out, transform 200ms ease-out" },
32175
+ style: \u7BB1\u306Estyle,
32148
32176
  children: [
32149
32177
  /* @__PURE__ */ jsxRuntime.jsx(
32150
32178
  "rect",