infracensus-collector 1.6.2 → 1.6.3
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/dist/index.js +72 -21
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15972,19 +15972,37 @@ ${tokenCss()}
|
|
|
15972
15972
|
writeRunSiteHint();
|
|
15973
15973
|
$("runTargets").value = (s.scanDefaults.targets || []).join(", ");
|
|
15974
15974
|
}
|
|
15975
|
-
|
|
15976
|
-
// A run that has just ENDED is the moment the history gained a row, and the
|
|
15977
|
-
// moment somebody wants to read it.
|
|
15975
|
+
// THE AUTHORITY ON WHAT IS RUNNING, held for the history to read.
|
|
15978
15976
|
//
|
|
15979
|
-
//
|
|
15980
|
-
//
|
|
15981
|
-
//
|
|
15982
|
-
//
|
|
15983
|
-
//
|
|
15984
|
-
//
|
|
15985
|
-
//
|
|
15986
|
-
|
|
15987
|
-
|
|
15977
|
+
// The detail used to decide "is this run live" from a boolean this paint
|
|
15978
|
+
// had set on a previous tick, and then say "the collector stopped before it
|
|
15979
|
+
// finished" on the strength of it \u2014 a strong claim about somebody's
|
|
15980
|
+
// machine, made from a stale client-side variable. The server knows: the
|
|
15981
|
+
// daemon and this console are one process, and the progress store IS the
|
|
15982
|
+
// running job. Matched by jobId below, so the claim is about the run being
|
|
15983
|
+
// looked at rather than about whatever was running most recently.
|
|
15984
|
+
liveProgress = s.scanProgress || null;
|
|
15985
|
+
renderLive(liveProgress);
|
|
15986
|
+
|
|
15987
|
+
const running = !!liveProgress;
|
|
15988
|
+
if ($("histWrap").open) {
|
|
15989
|
+
const now = Date.now();
|
|
15990
|
+
if (wasRunning && !running) {
|
|
15991
|
+
// The run just ended: the ledger gained its verdict, its device list and
|
|
15992
|
+
// its receipt all at once, and this is the moment somebody reads them.
|
|
15993
|
+
loadRuns();
|
|
15994
|
+
} else if (running) {
|
|
15995
|
+
// A LIVE run is repainted from the store above rather than re-read from
|
|
15996
|
+
// disk, because the two carry different things and only one of them
|
|
15997
|
+
// moves. The ledger records a phase when it COMPLETES \u2014 that is what
|
|
15998
|
+
// makes it a ledger and not a transcript \u2014 so bars built from it jump
|
|
15999
|
+
// from nothing to done and an operator watching a sweep sees a frozen
|
|
16000
|
+
// panel. The live store has every report. Repainting is free; the
|
|
16001
|
+
// re-read is not, so it happens on a slow beat to pick up the rest.
|
|
16002
|
+
if (now - lastRunsAt > 15000) loadRuns();
|
|
16003
|
+
else renderRuns(lastRuns);
|
|
16004
|
+
}
|
|
16005
|
+
}
|
|
15988
16006
|
wasRunning = running;
|
|
15989
16007
|
$("lastPollAt").textContent = fmt(s.daemon && s.daemon.lastPollAt);
|
|
15990
16008
|
$("lastPushAt").textContent = fmt(s.daemon && s.daemon.lastPushAt);
|
|
@@ -16638,6 +16656,20 @@ ${tokenCss()}
|
|
|
16638
16656
|
|
|
16639
16657
|
/** Was a scan running the last time we painted? Used to refresh history. */
|
|
16640
16658
|
let wasRunning = false;
|
|
16659
|
+
/** The running job as the SERVER reports it, or null. The liveness authority. */
|
|
16660
|
+
let liveProgress = null;
|
|
16661
|
+
/** The last fold read from the ledger, repainted between reads. */
|
|
16662
|
+
let lastRuns = [];
|
|
16663
|
+
/** When that read happened, so a live repaint does not re-read the file. */
|
|
16664
|
+
let lastRunsAt = 0;
|
|
16665
|
+
/**
|
|
16666
|
+
* Which runs the operator has expanded, by start time.
|
|
16667
|
+
*
|
|
16668
|
+
* A live run repaints every poll, and a repaint that rebuilt the list would
|
|
16669
|
+
* shut the panel somebody is reading three seconds after they opened it \u2014
|
|
16670
|
+
* which is precisely the panel this whole feature exists to keep open.
|
|
16671
|
+
*/
|
|
16672
|
+
const openRuns = new Set();
|
|
16641
16673
|
|
|
16642
16674
|
/**
|
|
16643
16675
|
* The last runs, folded from the ledger by the server.
|
|
@@ -16653,6 +16685,7 @@ ${tokenCss()}
|
|
|
16653
16685
|
const res = await fetch("/ui/api/runs", { cache: "no-store" });
|
|
16654
16686
|
if (res.status === 401) { showLogin(); return; }
|
|
16655
16687
|
const data = await res.json().catch(() => ({ runs: [] }));
|
|
16688
|
+
lastRunsAt = Date.now();
|
|
16656
16689
|
renderRuns(data.runs || []);
|
|
16657
16690
|
$("histNote").textContent = "";
|
|
16658
16691
|
} catch (e) {
|
|
@@ -16662,6 +16695,7 @@ ${tokenCss()}
|
|
|
16662
16695
|
}
|
|
16663
16696
|
|
|
16664
16697
|
function renderRuns(runs) {
|
|
16698
|
+
lastRuns = runs;
|
|
16665
16699
|
const host = $("histBody");
|
|
16666
16700
|
host.innerHTML = "";
|
|
16667
16701
|
if (!runs.length) {
|
|
@@ -16671,16 +16705,33 @@ ${tokenCss()}
|
|
|
16671
16705
|
}
|
|
16672
16706
|
host.className = "";
|
|
16673
16707
|
for (const run of runs) {
|
|
16708
|
+
// IS THIS RUN THE ONE RUNNING? Answered by the server's own record of
|
|
16709
|
+
// the job it is executing, not by a flag about whatever ran most
|
|
16710
|
+
// recently. A run with no job id is the one-shot CLI path, which cannot be
|
|
16711
|
+
// the daemon's live job and so is matched on nothing.
|
|
16712
|
+
const live = run.outcome === "running" && !!liveProgress
|
|
16713
|
+
&& (run.jobId ? liveProgress.jobId === run.jobId : false);
|
|
16714
|
+
const state = run.outcome === "running" && !live ? "stopped" : run.outcome;
|
|
16715
|
+
|
|
16716
|
+
// A LIVE run's stages come from the progress store, which reports every
|
|
16717
|
+
// tick; the ledger only records a phase once it has finished, so bars
|
|
16718
|
+
// folded from it cannot move while the work is happening.
|
|
16719
|
+
const phases = live && liveProgress.phases.length
|
|
16720
|
+
? liveProgress.phases.map((ph) => ({
|
|
16721
|
+
phase: ph.phase, done: ph.done, total: ph.total, note: ph.message,
|
|
16722
|
+
}))
|
|
16723
|
+
: (run.phases || []);
|
|
16724
|
+
|
|
16674
16725
|
const row = el("details", { class: "runrow" });
|
|
16726
|
+
// Reopened across repaints \u2014 see openRuns.
|
|
16727
|
+
if (openRuns.has(run.startedAt)) row.setAttribute("open", "open");
|
|
16728
|
+
row.addEventListener("toggle", () => {
|
|
16729
|
+
if (row.open) openRuns.add(run.startedAt);
|
|
16730
|
+
else openRuns.delete(run.startedAt);
|
|
16731
|
+
});
|
|
16675
16732
|
const sum = el("summary");
|
|
16676
16733
|
sum.appendChild(el("span", { class: "when", text: fmt(run.startedAt) }));
|
|
16677
16734
|
sum.appendChild(el("span", { text: run.mode }));
|
|
16678
|
-
// A run the LEDGER calls running is only reported as running if a scan is
|
|
16679
|
-
// actually in flight. The ledger cannot tell a live daemon from one killed
|
|
16680
|
-
// between two polls; the status poll can, and it is the half of the answer
|
|
16681
|
-
// this side of the page holds.
|
|
16682
|
-
const live = run.outcome === "running" && wasRunning;
|
|
16683
|
-
const state = run.outcome === "running" && !live ? "stopped" : run.outcome;
|
|
16684
16735
|
sum.appendChild(el("span", { class: "outcome-" + (live ? "running" : state), text:
|
|
16685
16736
|
state === "finished" ? "finished"
|
|
16686
16737
|
: state === "failed" ? "failed"
|
|
@@ -16710,7 +16761,7 @@ ${tokenCss()}
|
|
|
16710
16761
|
// The last stage the run reported is what it is DOING, which is the
|
|
16711
16762
|
// sentence somebody watching their own scan is looking for. A finished run
|
|
16712
16763
|
// has no use for it; a live one has nothing else.
|
|
16713
|
-
const latest =
|
|
16764
|
+
const latest = phases.length ? phases[phases.length - 1] : null;
|
|
16714
16765
|
block("Current stage", [
|
|
16715
16766
|
el("div", {
|
|
16716
16767
|
class: state === "failed" ? "bad" : state === "incomplete" || state === "stopped" ? "warntext" : "",
|
|
@@ -16729,9 +16780,9 @@ ${tokenCss()}
|
|
|
16729
16780
|
// \u2500\u2500 STAGES, AS BARS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
16730
16781
|
// The same bars the live panel draws, so a finished run and a running one
|
|
16731
16782
|
// look like the same thing at two moments.
|
|
16732
|
-
if (
|
|
16783
|
+
if (phases.length) {
|
|
16733
16784
|
const nodes = [];
|
|
16734
|
-
for (const ph of
|
|
16785
|
+
for (const ph of phases) {
|
|
16735
16786
|
for (const n of phaseBar(ph.phase, ph.done, ph.total, ph.note)) nodes.push(n);
|
|
16736
16787
|
}
|
|
16737
16788
|
block("Stages", nodes);
|