Files
brk/website_next/ask/tools/data.js
T
2026-07-28 21:35:02 +02:00

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) } : {}),
};
}