mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-08-05 15:13:06 -07:00
89 lines
2.8 KiB
JavaScript
89 lines
2.8 KiB
JavaScript
import { brk } from "../../utils/client.js";
|
|
import { unitFromType } from "./metrics/unit.js";
|
|
|
|
const RANGE_POINTS = 120;
|
|
|
|
/** @param {string} unit */
|
|
function displayedUnit(unit) {
|
|
if (unit === "usd") return "$";
|
|
if (unit === "percent") return "%";
|
|
if (unit === "btc") return " BTC";
|
|
if (unit === "addresses") return " addresses";
|
|
if (unit === "utxos") return " UTXOs";
|
|
if (unit === "blocks") return " blocks";
|
|
return "";
|
|
}
|
|
|
|
/** @param {number} value @param {string | undefined} unit */
|
|
export function formatValue(value, unit) {
|
|
const number = new Intl.NumberFormat("en-US", { maximumFractionDigits: 8 }).format(value);
|
|
const affix = displayedUnit(unit ?? "");
|
|
return affix === "$" ? `$${number}` : `${number}${affix}`;
|
|
}
|
|
|
|
/** @param {{ name: string, indexes: string[], type: string, suggestedUnit?: string }} metric @param {Record<string, unknown>} action */
|
|
export async function readMetric(metric, action) {
|
|
const rawIndex = typeof action.index === "string" ? action.index : "";
|
|
const at = action.at;
|
|
const dateLike = typeof at === "string" && !/^-?\d+$/.test(at);
|
|
const index = metric.indexes.includes(rawIndex)
|
|
? rawIndex
|
|
: dateLike && metric.indexes.includes("day1")
|
|
? "day1"
|
|
: metric.indexes.includes("height")
|
|
? "height"
|
|
: metric.indexes[0];
|
|
if (!index) throw new Error(`No supported index for ${metric.name}`);
|
|
if (
|
|
typeof action.mode !== "string" ||
|
|
!["latest", "at", "range"].includes(action.mode)
|
|
) {
|
|
throw new Error(`A valid position is required for ${metric.name}`);
|
|
}
|
|
const mode = action.mode;
|
|
let response;
|
|
|
|
if (mode === "at") {
|
|
if (at === undefined) throw new Error("A block height or date is required");
|
|
response = await brk.getSeries(
|
|
metric.name,
|
|
/** @type {any} */ (index),
|
|
/** @type {any} */ (at),
|
|
undefined,
|
|
1,
|
|
);
|
|
} else if (mode === "range") {
|
|
const points = Math.min(Number(action.points) || RANGE_POINTS, RANGE_POINTS);
|
|
response = await brk.getSeries(
|
|
metric.name,
|
|
/** @type {any} */ (index),
|
|
/** @type {any} */ (action.start ?? -points),
|
|
/** @type {any} */ (action.end),
|
|
points,
|
|
);
|
|
} else {
|
|
response = await brk.getSeries(
|
|
metric.name,
|
|
/** @type {any} */ (index),
|
|
-1,
|
|
undefined,
|
|
1,
|
|
);
|
|
}
|
|
|
|
if (!response || typeof response !== "object" || !Array.isArray(response.data)) {
|
|
throw new Error(`No data returned for ${metric.name}`);
|
|
}
|
|
return {
|
|
name: metric.name,
|
|
label: metric.name.replaceAll("_", " "),
|
|
unit: metric.suggestedUnit ?? unitFromType(metric.type),
|
|
index: response.index,
|
|
start: response.start,
|
|
end: response.end,
|
|
stamp: response.stamp,
|
|
values: response.data,
|
|
...(mode === "at" ? { requested: String(at) } : {}),
|
|
};
|
|
}
|