@takagaki/cortex-decisions-viewer 0.12.3 → 0.12.4

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 (2) hide show
  1. package/dist/render.js +246 -14
  2. package/package.json +1 -1
package/dist/render.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UNSETTLED_LIMITS = exports.REFLECT_OPS = exports.REFLECTING_LIMITS = void 0;
3
+ exports.UNSETTLED_LIMITS = exports.REFLECT_OPS = exports.LIVE_CONFIRM_LIMITS = exports.REFLECTING_LIMITS = void 0;
4
4
  exports.renderSite = renderSite;
5
5
  exports.livePending = livePending;
6
6
  exports.nextCheckDelay = nextCheckDelay;
@@ -375,6 +375,18 @@ const REFLECT_POLL_MS = 60 * 1000;
375
375
  * export しないローカルの const に置くこと。
376
376
  */
377
377
  exports.REFLECTING_LIMITS = { ttlMs: REFLECT_TTL_MS, pollMs: REFLECT_POLL_MS };
378
+ /**
379
+ * ライブ確認(op=state)の見切り(#256・設計v2 の1)。
380
+ *
381
+ * 通常応答は1〜2秒・Lambda のコールドスタートを含めても10秒で足りる。
382
+ * **10秒「確認中」が出続けるのは、嘘を断言するより許容できる。**
383
+ *
384
+ * 🔴 **これは「取り直しの予約」ではない。** 60秒の取り直し(REFLECT_POLL_MS /
385
+ * UNSETTLED_POLL_MS)を数えているテストは、この見切りを数から除くこと。
386
+ */
387
+ const LIVE_CONFIRM_TIMEOUT_MS = 10000;
388
+ /** 見切りを**テストから固定するための入れ物**(REFLECTING_LIMITS と同じ形) */
389
+ exports.LIVE_CONFIRM_LIMITS = { timeoutMs: LIVE_CONFIRM_TIMEOUT_MS };
378
390
  /**
379
391
  * 記録してよい操作の対応表。**既定は「記録しない」(null)。**
380
392
  *
@@ -2364,6 +2376,11 @@ a.ds-name:hover { text-decoration: underline; }
2364
2376
  /* 宣言はあるが実体が繋がっていない。未使用(グレー)とも接続済み(青)とも違うことを見せる */
2365
2377
  .cm-node.cm-idle rect { fill: var(--surface); stroke: #cbd5e1; stroke-dasharray: 4 3; }
2366
2378
  .cm-node.cm-idle .cm-sync { fill: #b45309; }
2379
+ /* ライブ確認の応答を待っている間(#256)。**状態を何も言っていない見た目にする。**
2380
+ 破線(未使用・未接続)にも青(接続OK)にもしない——どちらも状態の断言になる。
2381
+ 語彙は一覧側の「登録状況を確認中です」(ds-gate-muted)と同じ灰色に揃える */
2382
+ .cm-node.cm-pending rect { fill: var(--surface); stroke: var(--border); }
2383
+ .cm-node.cm-pending .cm-sync { fill: #6b7280; }
2367
2384
  .cm-label { font-size: 13.5px; font-weight: 600; fill: var(--text); }
2368
2385
  .cm-node.cm-warn .cm-label { fill: #92400e; }
2369
2386
  .cm-node.cm-off .cm-label { fill: #9ca3af; }
@@ -2391,6 +2408,9 @@ a.ds-name:hover { text-decoration: underline; }
2391
2408
  .cm-link.cm-warn { stroke: #d97706; }
2392
2409
  .cm-link.cm-off { stroke: #d1d5db; opacity: .6; }
2393
2410
  .cm-link.cm-idle { stroke: #cbd5e1; opacity: .7; }
2411
+ /* 確認中の線(#256)。**薄い中立**——流れ(animation)を付けない。
2412
+ 動いている線は「いまデータが通っている」と読めるので、確認中に出すと断言になる */
2413
+ .cm-link.cm-pending { stroke: #cbd5e1; opacity: .4; }
2394
2414
  /* 線は6本とも焼いて、出す/出さないをここで切り替える(0.12.0・renderConnectionMap の項)。
2395
2415
  SVG 要素に HTML の hidden 属性は効かないので、クラスで消す */
2396
2416
  .cm-link.is-hidden { display: none; }
@@ -2802,6 +2822,9 @@ ${capabilityState.toString()}
2802
2822
  var REFLECT_TTL_MS = ${JSON.stringify(REFLECT_TTL_MS)};
2803
2823
  var REFLECT_POLL_MS = ${JSON.stringify(REFLECT_POLL_MS)};
2804
2824
  var REFLECT_OPS = ${JSON.stringify(exports.REFLECT_OPS)};
2825
+ // ライブ確認の見切り(#256)。**ここも書き写さない**——テストが固定している値と
2826
+ // 画面が使う値が割れると、「10秒で戻る」検査が通ったまま実機では戻らなくなる
2827
+ var LIVE_CONFIRM_TIMEOUT_MS = ${JSON.stringify(LIVE_CONFIRM_TIMEOUT_MS)};
2805
2828
  ${livePending.toString()}
2806
2829
  ${nextCheckDelay.toString()}
2807
2830
  ${settledPending.toString()}
@@ -5713,7 +5736,11 @@ ${deriveCapTile.toString()}
5713
5736
  * ——ここで引き直すと、タイルの色(st)を決めた材料と2回引くことになり、
5714
5737
  * 片方だけずれる余地ができる。null なら規則5=従来表示へフォールバック
5715
5738
  */
5716
- function tileSub(cap, st, derived, adapter, ins, srcs, derive) {
5739
+ /**
5740
+ * @param confirming 初回のライブ確認を待っている(#256)。**状態の断言だけを
5741
+ * 「確認中」に差し替える**——件数・最終同期は焼いた事実なので下でそのまま積む
5742
+ */
5743
+ function tileSub(cap, st, derived, adapter, ins, srcs, derive, confirming) {
5717
5744
  var internal = ins.filter(function (s) { return s.kind === cap; })[0];
5718
5745
  var live = srcs.filter(function (s) { return externalCapability(s.type) === cap; });
5719
5746
  var parts = [];
@@ -5724,7 +5751,13 @@ ${deriveCapTile.toString()}
5724
5751
  //
5725
5752
  // 🔴 **ここが正本からの導出(下)より先。** 意図的に OFF にした能力に
5726
5753
  // 「登録済み(接続は未確認です)」と出さないため(deriveCapTile の項)
5727
- if (derived && derived !== "on") {
5754
+ if (confirming) {
5755
+ // 🔴 **確認中は状態を言わない(#256)。** 下の分岐はどれも焼いた値からの断言で、
5756
+ // ライブが届くと訂正される=瞬きの出どころ。**語は既存の中間状態と揃える**
5757
+ //(DS_GATE_PENDING「登録状況を確認中です」)——新しい言い方を増やすと、
5758
+ // 同じ画面で「確認中」を意味する語が2つ並ぶ
5759
+ parts.push(DS_GATE_PENDING.text);
5760
+ } else if (derived && derived !== "on") {
5728
5761
  parts.push((CAP_STATE_MARK[st] || "") + (CAP_STATE_TEXT[derived] || "状態が判定できません"));
5729
5762
  } else if (derive) {
5730
5763
  // 🔴 **正本(登録・実測)からの導出(0.12.0・#231 / #235 / #227)。**
@@ -5882,9 +5915,22 @@ ${deriveCapTile.toString()}
5882
5915
  // 足した直後は「登録済み(まだ取り込みがありません)」と、**何が起きたかを言える**。
5883
5916
  // ここを逆にすると、まとめ表が追いつく翌朝まで「確認中です」が居座る
5884
5917
  var pend = capPending(cap) && !derive;
5918
+ // 🔴 **初回のライブ確認が答えるまで、状態を断言しない(#256・設計v2 の5)。**
5919
+ // この2行目は焼いた capabilities 由来の状態を先に言っていたので、図と同じ瞬き
5920
+ // (旧状態を見せて1〜2秒後に訂正)をタイルでも起こしていた。**兄弟機能の同型の
5921
+ // 穴は同便で掃く**——図だけ直すと、同じ画面の下半分で同じ嘘が続く。
5922
+ //
5923
+ // **差し替えるのは状態の語だけ。** 件数・名前・最終同期は焼いた**事実**なので
5924
+ // そのまま残す(ライブで訂正されるのは事実ではなく状態の解釈)。対象は導出が
5925
+ // 答える能力だけ(derived が null / "on")=図と同じ規則5の線引き。
5926
+ var confirming = liveConfirming() && (derived === null || derived === "on");
5885
5927
  var subEl = el("div", {
5886
- class: "ds-tile-sub " + (pend ? DS_GATE_PENDING.cls : "ds-gate-" + st),
5887
- text: pend ? DS_GATE_PENDING.text : tileSub(cap, st, derived, adapter, internals, sources, derive),
5928
+ class: "ds-tile-sub " + (confirming || pend ? DS_GATE_PENDING.cls : "ds-gate-" + st),
5929
+ // **反映待ち(pend)の形は変えない。** あちらは「足した行がまとめ表に載るまで」の
5930
+ // 折衷で、件数を添えると足した分を数えたようにも読める。確認中は焼いた件数を残す
5931
+ text: pend
5932
+ ? DS_GATE_PENDING.text
5933
+ : tileSub(cap, st, derived, adapter, internals, sources, derive, confirming),
5888
5934
  });
5889
5935
  // **反映が届いたら、届いたスナップショットから引き直す。** 下地へ戻すと
5890
5936
  // 「⏳ 反映中」→「⦿ 未接続」になる——データが正しくなったあとに嘘をつく。
@@ -5902,9 +5948,14 @@ ${deriveCapTile.toString()}
5902
5948
  var deriveNow = dNow && dNow !== "on" ? null : capDerivation(cap);
5903
5949
  if (deriveNow) stNow = deriveNow.state;
5904
5950
  var pendNow = capPending(cap) && !deriveNow;
5905
- n.className = "ds-tile-sub " + (pendNow ? DS_GATE_PENDING.cls : "ds-gate-" + stNow);
5951
+ // 確認中かどうかも引き直す(#256)。**タイルを作るときと同じ式**——ここで
5952
+ // 断言に戻すと、反映待ちの取り直しが走った回だけ焼いた状態が顔を出す
5953
+ var confirmingNow = liveConfirming() && (dNow === null || dNow === "on");
5954
+ n.className = "ds-tile-sub " + (confirmingNow || pendNow ? DS_GATE_PENDING.cls : "ds-gate-" + stNow);
5906
5955
  return {
5907
- text: pendNow ? DS_GATE_PENDING.text : tileSub(cap, stNow, dNow, adapter, insNow, srcsNow, deriveNow),
5956
+ text: pendNow
5957
+ ? DS_GATE_PENDING.text
5958
+ : tileSub(cap, stNow, dNow, adapter, insNow, srcsNow, deriveNow, confirmingNow),
5908
5959
  hidden: false,
5909
5960
  };
5910
5961
  });
@@ -8447,6 +8498,57 @@ ${deriveCapTile.toString()}
8447
8498
  * **操作タブに入り直したときだけ**もう一度取りに行く(ポーリングはしない)。
8448
8499
  */
8449
8500
  var liveFleetRequested = false;
8501
+
8502
+ /* ---------------------------------------------------------------------------
8503
+ * 「確認中 → 確定」の2段表示(#256)
8504
+ * ---------------------------------------------------------------------------
8505
+ * 図とタイルの初期表示は**夜間ビルド時点の状態を断言**していた。ページを開くと
8506
+ * ライブ確認(op=state)が走り、届いた瞬間に正本からの導出で当て直すので、
8507
+ * 焼いた状態とライブが食い違う案件では**「先に旧状態を見せて、あとで訂正する」
8508
+ * 瞬き**になる(リロード直後に線が一瞬つながって見え、1〜2秒後に消える)。
8509
+ *
8510
+ * **旧状態の先行断言をやめる。** 取得が始まる瞬間に「確認中」へ倒し、応答が届いて
8511
+ * から確定する。図の形(ノード・線のジオメトリ)は焼いたものをそのまま使う
8512
+ * ——捨てるとオフライン時のフォールバックと曲線の正本を失う。
8513
+ * ------------------------------------------------------------------------- */
8514
+
8515
+ /**
8516
+ * ライブ確認が実際に飛ぶ構成か。**loadLiveFleet の発火条件そのもの。**
8517
+ *
8518
+ * 🔴 **「確認中」を出すかどうかも、この1本で決める(設計v2 の2)。** 条件を書き写すと、
8519
+ * intake が無い案件・fetch を持たない環境では**取得が始まらないのに確認中が出たまま
8520
+ * 固まる**——直そうとした瞬きより悪い(永久に何も言わない画面になる)。
8521
+ */
8522
+ function liveConfirmPossible() {
8523
+ return !!SITE.intake && typeof fetch === "function";
8524
+ }
8525
+ /**
8526
+ * 最初のライブ確認が答えたか(成功・失敗・見切りのどれでも立つ)。
8527
+ *
8528
+ * **能力ごとに持たない。** 応答の到着は1回で、届いたあとに能力ごとの語を決めるのは
8529
+ * 導出(capDerivation)の仕事。ここを能力ごとに割ると判定が2箇所になる。
8530
+ */
8531
+ var liveAnswered = false;
8532
+ /**
8533
+ * 図を「確認中」にしたか。**ページ生存中の最初の取得の1回だけ(設計v3)。**
8534
+ *
8535
+ * loadLiveFleet は初回以外にも何度も呼ばれる(能力モーダルを開くたびの noteOpenCap・
8536
+ * 反映待ちの60秒ポーリング・保存直後の freshWanted 再取得)。呼び出しごとに確認中へ
8537
+ * 戻すと、**確定済みのノードが無関係な操作のたびに確認中→再確定を繰り返す**
8538
+ * ——直す前より体感が悪い再発になる。2回目以降は confirming 段を経ず、
8539
+ * applyStateToConnMap の冪等な当て直しに直接委ねる。
8540
+ */
8541
+ var connMapConfirmingShown = false;
8542
+ /** いま「確認中」を出す局面か(図の初回切り替えとタイルの両方が見る) */
8543
+ function liveConfirming() {
8544
+ return liveConfirmPossible() && !liveAnswered;
8545
+ }
8546
+ /**
8547
+ * 図の3行目に出す確認中の語。一覧側は DS_GATE_PENDING(「登録状況を確認中です」)で、
8548
+ * 図は幅が 148px しかないので短くする。**語彙は同じ「確認中」に揃える。**
8549
+ */
8550
+ var CONN_CONFIRMING_TEXT = "確認中…";
8551
+
8450
8552
  /**
8451
8553
  * op=state に送る能力。**常に全能力**(0.12.0・#231 の正本化)。
8452
8554
  *
@@ -8529,17 +8631,33 @@ ${deriveCapTile.toString()}
8529
8631
  if (fresh) freshWanted = true;
8530
8632
  if (liveFleetRequested) return;
8531
8633
  var intake = SITE.intake;
8532
- if (!intake) return;
8533
- // **fetch の有無を確かめてから呼ぶ。** テスト環境(JSDOM)は window.fetch を持たない。
8534
- // 素で呼ぶと描画中の ReferenceError になり、「画面が例外を出さずに描き切る」検査を割る。
8535
- if (typeof fetch !== "function") return;
8634
+ // **intake が無い/fetch が無い(JSDOM)なら取りに行かない。** 素で fetch を呼ぶと
8635
+ // 描画中の ReferenceError になり、「画面が例外を出さずに描き切る」検査を割る。
8636
+ // 判定は liveConfirmPossible に一本化してある——「確認中」を出す条件と同じでないと、
8637
+ // 取得が始まらない案件に確認中が出たまま残る(#256)
8638
+ if (!liveConfirmPossible()) return;
8536
8639
  liveFleetRequested = true;
8537
8640
  var useFresh = freshWanted;
8538
8641
  freshWanted = false;
8642
+ // 🔴 **図を確認中に倒すのは、fetch を発火する直前の1回だけ(#256・設計v3)。**
8643
+ // ここより後(応答の中)でやると意味が無く、ここより前(関数の入口)でやると
8644
+ // 取りに行かない経路でも確認中になる
8645
+ if (!connMapConfirmingShown) {
8646
+ connMapConfirmingShown = true;
8647
+ showConfirmingConnMap();
8648
+ }
8649
+ // **10秒で見切る(設計v2 の1)。** 応答が返らないまま待ち続けると、確認中が永久に
8650
+ // 残る=「何も言わない画面」になる。見切ったら失敗と同じ扱い(焼いた表示へ復元)。
8651
+ // AbortController が無い環境では見切らない(素の fetch は中断できない)
8652
+ var ctrl = typeof AbortController === "function" ? new AbortController() : null;
8653
+ var giveUp = ctrl ? setTimeout(function () { ctrl.abort(); }, LIVE_CONFIRM_TIMEOUT_MS) : null;
8654
+ /** 見切りのタイマを外す。**応答が来たら必ず呼ぶ**(残すと次の取得を巻き込んで中断する) */
8655
+ var clearGiveUp = function () { if (giveUp != null) { clearTimeout(giveUp); giveUp = null; } };
8539
8656
  var pfx = intake.url + (intake.url.indexOf("?") === -1 ? "?" : "&");
8540
8657
  fetch(pfx + "op=state&t=" + encodeURIComponent(intake.token), {
8541
8658
  method: "POST",
8542
8659
  headers: { "content-type": "application/json" },
8660
+ signal: ctrl ? ctrl.signal : undefined,
8543
8661
  // **常に全能力を要求する(ALL_STATE_CAPS の項)。** 知らない値は Lambda 側が黙って
8544
8662
  // 捨てる(断らない)ので、画面と Lambda の版が食い違っても接続状況の表示は消えない
8545
8663
  // **保存直後だけ据え置きを迂回させる。** これが無いと、サーバが保存前の答えを返し、
@@ -8548,8 +8666,15 @@ ${deriveCapTile.toString()}
8548
8666
  })
8549
8667
  // **非2xxも失敗として扱う。** ビューアとLambdaの版は独立に進むので、
8550
8668
  // op=state 未対応のLambdaは 400 を返す。通信エラーだけを見ていると空表示になる。
8551
- .then(function (res) { if (!res.ok) throw new Error("http " + res.status); return res.json(); })
8669
+ .then(function (res) {
8670
+ clearGiveUp();
8671
+ if (!res.ok) throw new Error("http " + res.status);
8672
+ return res.json();
8673
+ })
8552
8674
  .then(function (j) {
8675
+ // 🔴 **タイルの「確認中」を解くのは、下地を作り直す前(#256)。** 後に置くと、
8676
+ // 応答が届いた回のタイルだけ確認中のまま残る(次の再描画まで訂正が出ない)
8677
+ liveAnswered = true;
8553
8678
  // **fleet より先に読む。** fleet-status.json をまだ持たない案件(立ち上げ直後)は
8554
8679
  // 下で throw するが、リアルタイム同期の可否は索引由来なので独立に決まる
8555
8680
  LIVE_REALTIME = (j && j.realtime) || null;
@@ -8588,11 +8713,19 @@ ${deriveCapTile.toString()}
8588
8713
  if (freshWanted) loadLiveFleet();
8589
8714
  })
8590
8715
  .catch(function () {
8716
+ clearGiveUp();
8591
8717
  // 静的ビルドの値で描き続ける。ただし「古いかもしれない」ことは画面に出す
8592
8718
  LIVE_FLEET = null;
8593
8719
  LIVE_FLEET_FAILED = true;
8594
8720
  liveFleetRequested = false;
8721
+ liveAnswered = true;
8595
8722
  MERGED = null;
8723
+ // 🔴 **確認中に倒した図を焼いた表示へ戻す(#256・設計v2 の3)。** ライブが
8724
+ // 取れなかったときのフォールバックはここに残る——戻さないと「確認中…」の
8725
+ // ままの図が残り、オフラインでは**何も分からない画面**になる。
8726
+ // 「この図は◯◯時点です」の注記は既存のまま(ライブが取れていないときは
8727
+ // 図も一覧も同じ焼いた時点なので、注記なしが正直・設計v2 の4)
8728
+ restoreConfirmingConnMap();
8596
8729
  refreshDataSources();
8597
8730
  repaintReflect(document);
8598
8731
  repaintOpenLists();
@@ -9141,6 +9274,10 @@ ${deriveCapTile.toString()}
9141
9274
  *
9142
9275
  * **導出が答えない能力(規則5・設定が on 以外)は触らない。** 焼いた図がそのまま
9143
9276
  * 残る=従来表示へのフォールバック。タイル側と同じ規律。
9277
+ *
9278
+ * 🔴 **触らない能力は「焼いた表示に戻す」(#256・設計v2 の3)。** 確認中に倒した
9279
+ * あとで素通りすると、規則5の「焼いた図のまま」が**「確認中のまま固まる」に化ける**
9280
+ * ——応答は届いているのに、その能力だけ永久に何も言わない図になる。
9144
9281
  */
9145
9282
  function applyStateToConnMap() {
9146
9283
  var wrap = app.querySelector(".conn-map");
@@ -9148,9 +9285,9 @@ ${deriveCapTile.toString()}
9148
9285
  for (var cap in TILE_CAPS) {
9149
9286
  if (!Object.prototype.hasOwnProperty.call(TILE_CAPS, cap)) continue;
9150
9287
  // 設定そのものが OFF / 異常 / 未設置なら、その語(焼いた図)が正しい
9151
- if (capConfigState(cap)) continue;
9288
+ if (capConfigState(cap)) { restoreBakedConnMap(cap); continue; }
9152
9289
  var d = capDerivation(cap);
9153
- if (!d) continue; // 規則5: 材料が無い → 焼いた図のまま
9290
+ if (!d) { restoreBakedConnMap(cap); continue; } // 規則5: 材料が無い → 焼いた図のまま
9154
9291
  var node = wrap.querySelector('[data-target="ds-' + cap + '"]');
9155
9292
  if (!node) continue;
9156
9293
  node.setAttribute("class", "cm-node cm-" + d.state);
@@ -9169,7 +9306,102 @@ ${deriveCapTile.toString()}
9169
9306
  link.setAttribute("class", "cm-link cm-" + d.state
9170
9307
  + (d.state === "ok" || d.state === "warn" ? "" : " is-hidden"));
9171
9308
  }
9309
+ // 確定したので退避は要らない(設計v3)。**残すと、あとの取得が失敗したときに
9310
+ // 確定済みの表示へ焼いた値が上書きされる**——訂正した嘘が戻ってくる
9311
+ forgetBakedConnMap(node, link);
9312
+ }
9313
+ }
9314
+
9315
+ /**
9316
+ * 図の状態表現を「確認中」に倒す(#256)。**形は触らない。**
9317
+ *
9318
+ * 呼ぶのは loadLiveFleet が最初に fetch を発火する直前の1回だけ
9319
+ *(connMapConfirmingShown の項)。**「確認中にしてから取得を始める」順序にする**
9320
+ * ことで、取得が始まらない経路(intake の無い案件・fetch の無い環境)では
9321
+ * 確認中が絶対に出ない構造にしている(設計v2 の2)。
9322
+ *
9323
+ * 🔴 **上書きする直前に、焼いた表示を DOM のデータ属性へ退避する(設計v2 の3)。**
9324
+ * 退避を JS の変数に持つと、再描画・デバッグのときに DOM と食い違う。属性なら
9325
+ * **DOM が正本**のまま——「いま確認中の能力はどれか」も属性の有無で読める。
9326
+ *
9327
+ * **対象は applyStateToConnMap が当て直す能力だけ**(capConfigState が答えない=
9328
+ * derived が null / "on")。OFF・異常・未設置の語は設定そのものの話で、ライブが
9329
+ * 届いても変わらない——確認中にしたら、応答が来ても戻す相手がいなくなる。
9330
+ *
9331
+ * ⚠ **⚠️バッジ(cm-badge)は触らない。** あれは applyStateToConnMap も当て直して
9332
+ * いない(ビルド時に warn のノードにだけ焼かれ、以後そのまま)。確認中の間だけ
9333
+ * 隠すと、応答で warn が確定したときに**失敗が図から消えたまま**になる
9334
+ * ——「cm-warn を隠さない」の逆をこちらの都合で作る。バッジごと2段化するなら、
9335
+ * 6ノードに常時バッジを焼いて表示を切り替える形(線と同じ)にする別便が要る。
9336
+ */
9337
+ function showConfirmingConnMap() {
9338
+ var wrap = app.querySelector(".conn-map");
9339
+ if (!wrap) return;
9340
+ for (var cap in TILE_CAPS) {
9341
+ if (!Object.prototype.hasOwnProperty.call(TILE_CAPS, cap)) continue;
9342
+ if (capConfigState(cap)) continue;
9343
+ var node = wrap.querySelector('[data-target="ds-' + cap + '"]');
9344
+ if (!node) continue;
9345
+ node.setAttribute("data-cm-baked-class", node.getAttribute("class") || "");
9346
+ node.setAttribute("class", "cm-node cm-pending");
9347
+ var sync = node.querySelector(".cm-sync");
9348
+ if (sync) {
9349
+ // **data-ts は残して textContent だけ差し替える(設計v2 の3)。** 外すと
9350
+ // 復元したときに時刻の整形(renderConnMap の [data-ts])が二度と効かない
9351
+ sync.setAttribute("data-cm-baked-text", sync.textContent);
9352
+ sync.textContent = CONN_CONFIRMING_TEXT;
9353
+ }
9354
+ var link = wrap.querySelector('.cm-link[data-cm-cap="' + cap + '"]');
9355
+ if (link) {
9356
+ // **薄い中立の線を出す(is-hidden を外す)。** 線が消えていると「未接続」を
9357
+ // 断言したことになる。確認中は接続OK/未接続のどちらも言わない
9358
+ link.setAttribute("data-cm-baked-class", link.getAttribute("class") || "");
9359
+ link.setAttribute("class", "cm-link cm-pending");
9360
+ }
9361
+ }
9362
+ }
9363
+
9364
+ /**
9365
+ * 確認中に倒した能力を、焼いた表示へ戻す(#256・設計v2 の3)。
9366
+ *
9367
+ * 呼ぶのは2箇所——**ライブが取れなかったとき**(失敗・非2xx・見切り。全能力ぶん)と、
9368
+ * **応答は届いたが導出が答えなかった能力**(applyStateToConnMap の continue)。
9369
+ *
9370
+ * 退避属性が無ければ何もしない。**「確認中でない能力を戻す」経路を作らない**
9371
+ * ——確定済みのノードに焼いた値を書けば、それは訂正の取り消しになる。
9372
+ */
9373
+ function restoreBakedConnMap(cap) {
9374
+ var wrap = app.querySelector(".conn-map");
9375
+ if (!wrap) return;
9376
+ var node = wrap.querySelector('[data-target="ds-' + cap + '"]');
9377
+ if (!node || !node.hasAttribute("data-cm-baked-class")) return;
9378
+ node.setAttribute("class", node.getAttribute("data-cm-baked-class"));
9379
+ var sync = node.querySelector(".cm-sync");
9380
+ if (sync && sync.hasAttribute("data-cm-baked-text")) {
9381
+ sync.textContent = sync.getAttribute("data-cm-baked-text");
9382
+ }
9383
+ var link = wrap.querySelector('.cm-link[data-cm-cap="' + cap + '"]');
9384
+ if (link && link.hasAttribute("data-cm-baked-class")) {
9385
+ link.setAttribute("class", link.getAttribute("data-cm-baked-class"));
9386
+ }
9387
+ forgetBakedConnMap(node, link);
9388
+ }
9389
+
9390
+ /** 確認中に倒した全能力を焼いた表示へ戻す(ライブが1件も取れなかったとき) */
9391
+ function restoreConfirmingConnMap() {
9392
+ for (var cap in TILE_CAPS) {
9393
+ if (Object.prototype.hasOwnProperty.call(TILE_CAPS, cap)) restoreBakedConnMap(cap);
9394
+ }
9395
+ }
9396
+
9397
+ /** 退避を捨てる(確定した/戻し終えた)。属性の有無が「確認中か」の正本 */
9398
+ function forgetBakedConnMap(node, link) {
9399
+ if (node) {
9400
+ node.removeAttribute("data-cm-baked-class");
9401
+ var sync = node.querySelector(".cm-sync");
9402
+ if (sync) sync.removeAttribute("data-cm-baked-text");
9172
9403
  }
9404
+ if (link) link.removeAttribute("data-cm-baked-class");
9173
9405
  }
9174
9406
 
9175
9407
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takagaki/cortex-decisions-viewer",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "description": "Cortexの意思決定記録(Decisions/*.md)を静的サイトにビルドして閲覧する。各レコードに「Edit on GitHub」リンクを付与する。",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,