mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-19 14:24:47 -07:00
90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
import { createCube } from "./cube.js";
|
|
import { formatFeeRate } from "./render.js";
|
|
|
|
const NUM_BLOCKS = 8;
|
|
|
|
/**
|
|
* @typedef {{
|
|
* el: HTMLElement,
|
|
* topFace: HTMLDivElement,
|
|
* rightFace: HTMLDivElement,
|
|
* leftFace: HTMLDivElement,
|
|
* }} Cube
|
|
*/
|
|
|
|
/** @type {HTMLDivElement | null} */ let mempoolBlocksEl = null;
|
|
/** @type {Cube[]} */ const cubes = [];
|
|
|
|
/** @param {HTMLElement} parent the `.chain-scroll` element */
|
|
export function initMempool(parent) {
|
|
mempoolBlocksEl = document.createElement("div");
|
|
mempoolBlocksEl.classList.add("mempool-blocks");
|
|
mempoolBlocksEl.hidden = true;
|
|
parent.prepend(mempoolBlocksEl);
|
|
}
|
|
|
|
/** @param {MempoolBlock[]} blocks */
|
|
export function renderMempool(blocks) {
|
|
if (!mempoolBlocksEl) return;
|
|
mempoolBlocksEl.hidden = blocks.length === 0;
|
|
const want = Math.min(blocks.length, NUM_BLOCKS);
|
|
while (cubes.length > want) {
|
|
const last = cubes.pop();
|
|
if (last) last.el.remove();
|
|
}
|
|
while (cubes.length < want) {
|
|
const cube = createMempoolCube(cubes.length);
|
|
cubes.push(cube);
|
|
mempoolBlocksEl.append(cube.el);
|
|
}
|
|
for (let i = 0; i < want; i++) updateMempoolCube(cubes[i], blocks[i], i);
|
|
}
|
|
|
|
/** @param {number} position @returns {Cube} */
|
|
function createMempoolCube(position) {
|
|
const el = document.createElement("div");
|
|
el.classList.add("cube", "projected");
|
|
if (position === 0) el.classList.add("next");
|
|
const { topFace, rightFace, leftFace } = createCube(el, 0);
|
|
return { el, topFace, rightFace, leftFace };
|
|
}
|
|
|
|
/**
|
|
* @param {Cube} cube
|
|
* @param {MempoolBlock} block
|
|
* @param {number} position
|
|
*/
|
|
function updateMempoolCube(cube, block, position) {
|
|
const fill = Math.min(1, block.blockVSize / 1_000_000);
|
|
cube.el.style.setProperty("--fill", String(fill));
|
|
|
|
cube.topFace.textContent = "";
|
|
const label = document.createElement("p");
|
|
label.textContent = position === 0 ? "next" : `+${position}`;
|
|
cube.topFace.append(label);
|
|
|
|
cube.rightFace.textContent = "";
|
|
const txs = document.createElement("p");
|
|
txs.textContent = block.nTx.toLocaleString();
|
|
const txsUnit = document.createElement("p");
|
|
txsUnit.classList.add("dim");
|
|
txsUnit.textContent = block.nTx === 1 ? "tx" : "txs";
|
|
cube.rightFace.append(txs, txsUnit);
|
|
|
|
cube.leftFace.textContent = "";
|
|
const median = document.createElement("p");
|
|
const tilde = document.createElement("span");
|
|
tilde.classList.add("dim");
|
|
tilde.textContent = "~";
|
|
median.append(tilde, formatFeeRate(block.medianFee));
|
|
const range = document.createElement("p");
|
|
const dash = document.createElement("span");
|
|
dash.classList.add("dim");
|
|
dash.textContent = "-";
|
|
range.append(formatFeeRate(block.feeRange[0]), dash, formatFeeRate(block.feeRange[6]));
|
|
const unit = document.createElement("p");
|
|
unit.classList.add("dim");
|
|
unit.textContent = "sat/vB";
|
|
cube.leftFace.append(median, range, unit);
|
|
}
|