mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-23 00:48:11 -07:00
69 lines
1.7 KiB
JavaScript
69 lines
1.7 KiB
JavaScript
/**
|
|
* @typedef {Object} ResponseStep
|
|
* @property {string} label
|
|
* @property {number} [elapsedMs]
|
|
*/
|
|
|
|
/** @param {number} elapsedMs */
|
|
export function formatDuration(elapsedMs) {
|
|
if (elapsedMs < 100) return "<0.1s";
|
|
if (elapsedMs < 60_000) return `${(elapsedMs / 1_000).toFixed(1)}s`;
|
|
|
|
const minutes = Math.floor(elapsedMs / 60_000);
|
|
const seconds = Math.floor((elapsedMs % 60_000) / 1_000);
|
|
return `${minutes}m ${seconds}s`;
|
|
}
|
|
|
|
/** @param {string} label */
|
|
function normalizeLabel(label) {
|
|
return label
|
|
.replace(/\s*·.*$/, "")
|
|
.replace(/(?:\.\.\.|…)$/, "")
|
|
.trim();
|
|
}
|
|
|
|
/** @param {(steps: ResponseStep[]) => void} onUpdate */
|
|
export function createResponseTimer(onUpdate) {
|
|
const startedAt = performance.now();
|
|
/** @type {{ label: string, startedAt: number } | undefined} */
|
|
let active;
|
|
/** @type {{ label: string, elapsedMs: number }[]} */
|
|
const completed = [];
|
|
|
|
function publish() {
|
|
onUpdate(active
|
|
? [...completed, { label: active.label }]
|
|
: [...completed]);
|
|
}
|
|
|
|
function completeActive() {
|
|
if (!active) return;
|
|
|
|
completed.push({
|
|
label: active.label,
|
|
elapsedMs: Math.round(performance.now() - active.startedAt),
|
|
});
|
|
active = undefined;
|
|
}
|
|
|
|
return {
|
|
/** @param {string} nextLabel */
|
|
set(nextLabel) {
|
|
const label = normalizeLabel(nextLabel);
|
|
if (label === active?.label) return;
|
|
|
|
completeActive();
|
|
if (label) active = { label, startedAt: performance.now() };
|
|
publish();
|
|
},
|
|
finish() {
|
|
completeActive();
|
|
publish();
|
|
return {
|
|
elapsedMs: Math.round(performance.now() - startedAt),
|
|
steps: [...completed],
|
|
};
|
|
},
|
|
};
|
|
}
|