Files
brk/websites/bitview/scripts/core/serde.js
2025-10-01 23:17:48 +02:00

532 lines
12 KiB
JavaScript

const localhost = window.location.hostname === "localhost";
export const serdeString = {
/**
* @param {string} v
*/
serialize(v) {
return v;
},
/**
* @param {string} v
*/
deserialize(v) {
return v;
},
};
export const serdeMetrics = {
/**
* @param {Metric[]} v
*/
serialize(v) {
return v.join(",");
},
/**
* @param {string} v
*/
deserialize(v) {
return /** @type {Metric[]} */ (v.split(","));
},
};
export const serdeNumber = {
/**
* @param {number} v
*/
serialize(v) {
return String(v);
},
/**
* @param {string} v
*/
deserialize(v) {
return Number(v);
},
};
export const serdeOptNumber = {
/**
* @param {number | null} v
*/
serialize(v) {
return v !== null ? String(v) : "";
},
/**
* @param {string} v
*/
deserialize(v) {
return v ? Number(v) : null;
},
};
export const serdeDate = {
/**
* @param {Date} date
*/
serialize(date) {
return date.toString();
},
/**
* @param {string} v
*/
deserialize(v) {
return new Date(v);
},
};
export const serdeOptDate = {
/**
* @param {Date | null} date
*/
serialize(date) {
return date !== null ? date.toString() : "";
},
/**
* @param {string} v
*/
deserialize(v) {
return new Date(v);
},
};
export const serdeBool = {
/**
* @param {boolean} v
*/
serialize(v) {
return String(v);
},
/**
* @param {string} v
*/
deserialize(v) {
if (v === "true" || v === "1") {
return true;
} else if (v === "false" || v === "0") {
return false;
} else {
throw "deser bool err";
}
},
};
export const serdeChartableIndex = {
/**
* @param {IndexName} v
* @returns {ChartableIndexName | null}
*/
serialize(v) {
switch (v) {
case "dateindex":
return "date";
case "decadeindex":
return "decade";
case "difficultyepoch":
return "epoch";
case "height":
return "timestamp";
case "monthindex":
return "month";
case "quarterindex":
return "quarter";
case "semesterindex":
return "semester";
case "weekindex":
return "week";
case "yearindex":
return "year";
default:
return null;
}
},
/**
* @param {ChartableIndexName} v
* @returns {IndexName}
*/
deserialize(v) {
switch (v) {
case "timestamp":
return "height";
case "date":
return "dateindex";
case "week":
return "weekindex";
case "epoch":
return "difficultyepoch";
case "month":
return "monthindex";
case "quarter":
return "quarterindex";
case "semester":
return "semesterindex";
case "year":
return "yearindex";
case "decade":
return "decadeindex";
default:
throw Error("todo");
}
},
};
/**
* @typedef {"" |
* "%all" |
* "%cmcap" |
* "%cp+l" |
* "%mcap" |
* "%pnl" |
* "%rcap" |
* "%self" |
* "/sec" |
* "address data" |
* "block" |
* "blocks" |
* "bool" |
* "btc" |
* "bytes" |
* "cents" |
* "coinblocks" |
* "coindays" |
* "constant" |
* "count" |
* "date" |
* "days" |
* "difficulty" |
* "epoch" |
* "gigabytes" |
* "h/s" |
* "hash" |
* "height" |
* "id" |
* "index" |
* "len" |
* "locktime" |
* "percentage" |
* "position" |
* "ratio" |
* "sat/vb" |
* "satblocks" |
* "satdays" |
* "sats" |
* "sats/(ph/s)/day" |
* "sats/(th/s)/day" |
* "sd" |
* "secs" |
* "timestamp" |
* "tx" |
* "type" |
* "usd" |
* "usd/(ph/s)/day" |
* "usd/(th/s)/day" |
* "vb" |
* "version" |
* "wu" |
* "years" |
* "" } Unit
*/
export const serdeUnit = {
/**
* @param {string} v
*/
deserialize(v) {
/** @type {Unit | undefined} */
let unit;
/**
* @param {Unit} u
*/
function setUnit(u) {
if (unit)
throw Error(
`Can't assign "${u}" to unit, "${unit}" is already assigned to "${v}"`,
);
unit = u;
}
if (
(!unit || localhost) &&
(v.includes("in_sats") ||
(v.endsWith("supply") &&
!(v.endsWith("circulating_supply") || v.endsWith("_own_supply"))) ||
v === "sent" ||
v === "annualized_volume" ||
v.endsWith("supply_half") ||
v.endsWith("supply_in_profit") ||
v.endsWith("supply_in_loss") ||
v.endsWith("stack") ||
(v.endsWith("value") && !v.includes("realized")) ||
((v.includes("coinbase") ||
v.includes("fee") ||
v.includes("subsidy") ||
v.includes("rewards")) &&
!(
v.startsWith("is_") ||
v.includes("_btc") ||
v.includes("_usd") ||
v.includes("fee_rate") ||
v.endsWith("dominance")
)))
) {
setUnit("sats");
}
if (
(!unit || localhost) &&
!v.endsWith("velocity") &&
((v.includes("_btc") &&
!(v.includes("0k_btc") || v.includes("1k_btc"))) ||
v.endsWith("_btc"))
) {
setUnit("btc");
}
if ((!unit || localhost) && v === "chain") {
setUnit("block");
}
if ((!unit || localhost) && v.startsWith("blocks_before")) {
setUnit("blocks");
}
if (
(!unit || localhost) &&
(v === "emptyaddressdata" || v === "loadedaddressdata")
) {
setUnit("address data");
}
if (
(!unit || localhost) &&
(v === "price_high" ||
v === "price_ohlc" ||
v === "price_low" ||
v === "price_close" ||
v === "price_open" ||
v === "price_ath" ||
v === "market_cap" ||
v.startsWith("price_true_range") ||
(v.includes("_usd") && !v.endsWith("velocity")) ||
v.includes("cointime_value") ||
v.endsWith("_ago") ||
v.endsWith("price_paid") ||
v.endsWith("_price") ||
(v.startsWith("price") && (v.endsWith("min") || v.endsWith("max"))) ||
(v.endsWith("_cap") && !v.includes("rel_to")) ||
v.endsWith("value_created") ||
v.endsWith("value_destroyed") ||
((v.includes("realized") || v.includes("true_market_mean")) &&
!v.includes("ratio") &&
!v.includes("rel_to")) ||
((v.endsWith("sma") || v.includes("sma_x") || v.endsWith("ema")) &&
!v.includes("ratio") &&
!v.includes("sopr") &&
!v.includes("hash_rate")) ||
v === "ath")
) {
setUnit("usd");
}
if ((!unit || localhost) && v.endsWith("cents")) {
setUnit("cents");
}
if (
((!unit || localhost) &&
(v.endsWith("ratio") ||
(v.includes("ratio") &&
(v.endsWith("sma") || v.endsWith("ema") || v.endsWith("zscore"))) ||
v.includes("sopr") ||
v.endsWith("_5sd") ||
v.endsWith("1sd") ||
v.endsWith("2sd") ||
v.endsWith("3sd") ||
v.endsWith("pct1") ||
v.endsWith("pct2") ||
v.endsWith("pct5") ||
v.endsWith("pct95") ||
v.endsWith("pct98") ||
v.endsWith("pct99"))) ||
v.includes("liveliness") ||
v.includes("vaultedness") ||
v == "puell_multiple" ||
v.endsWith("velocity")
) {
setUnit("ratio");
}
if (
(!unit || localhost) &&
(v === "price_drawdown" ||
v === "difficulty_adjustment" ||
v.endsWith("inflation_rate") ||
v.endsWith("_oscillator") ||
v.endsWith("_dominance") ||
v.endsWith("_returns") ||
v.endsWith("_rebound") ||
v.endsWith("_volatility") ||
v.endsWith("_cagr"))
) {
setUnit("percentage");
}
if (
(!unit || localhost) &&
(v.endsWith("count") ||
v.includes("_count_") ||
v.startsWith("block_count") ||
v.includes("blocks_mined") ||
(v.includes("tx_v") && !v.includes("vsize")))
) {
setUnit("count");
}
if (
(!unit || localhost) &&
(v.startsWith("hash_rate") || v.endsWith("as_hash"))
) {
setUnit("h/s");
}
if ((!unit || localhost) && v === "pool") {
setUnit("id");
}
if ((!unit || localhost) && v.includes("fee_rate")) {
setUnit("sat/vb");
}
if ((!unit || localhost) && v.startsWith("is_")) {
setUnit("bool");
}
if ((!unit || localhost) && v.endsWith("type")) {
setUnit("type");
}
if (
(!unit || localhost) &&
(v === "interval" || v.startsWith("block_interval"))
) {
setUnit("secs");
}
if ((!unit || localhost) && v.endsWith("_per_sec")) {
setUnit("/sec");
}
if ((!unit || localhost) && v.endsWith("locktime")) {
setUnit("locktime");
}
if ((!unit || localhost) && v.endsWith("version")) {
setUnit("version");
}
if (
(!unit || localhost) &&
(v === "txid" ||
(v.endsWith("bytes") && !v.endsWith("vbytes")) ||
v.endsWith("base_size") ||
v.endsWith("total_size") ||
v.includes("block_size"))
) {
setUnit("bytes");
}
if ((!unit || localhost) && v.endsWith("_sd")) {
setUnit("sd");
}
if ((!unit || localhost) && (v.includes("vsize") || v.includes("vbytes"))) {
setUnit("vb");
}
if ((!unit || localhost) && v.includes("weight")) {
setUnit("wu");
}
if ((!unit || localhost) && v.endsWith("index")) {
setUnit("index");
}
if ((!unit || localhost) && (v === "date" || v === "date_fixed")) {
setUnit("date");
}
if (
(!unit || localhost) &&
(v === "timestamp" || v === "timestamp_fixed")
) {
setUnit("timestamp");
}
if ((!unit || localhost) && v.includes("coinblocks")) {
setUnit("coinblocks");
}
if ((!unit || localhost) && v.includes("coindays")) {
setUnit("coindays");
}
if ((!unit || localhost) && v.includes("satblocks")) {
setUnit("satblocks");
}
if ((!unit || localhost) && v.includes("satdays")) {
setUnit("satdays");
}
if ((!unit || localhost) && v.endsWith("height")) {
setUnit("height");
}
if ((!unit || localhost) && v.endsWith("rel_to_market_cap")) {
setUnit("%mcap");
}
if ((!unit || localhost) && v.endsWith("rel_to_own_market_cap")) {
setUnit("%cmcap");
}
if ((!unit || localhost) && v.endsWith("rel_to_own_total_unrealized_pnl")) {
setUnit("%cp+l");
}
if ((!unit || localhost) && v.endsWith("rel_to_realized_cap")) {
setUnit("%rcap");
}
if ((!unit || localhost) && v.endsWith("rel_to_circulating_supply")) {
setUnit("%all");
}
if (
(!unit || localhost) &&
(v.includes("rel_to_realized_profit") ||
v.includes("rel_to_realized_loss"))
) {
setUnit("%pnl");
}
if ((!unit || localhost) && v.endsWith("rel_to_own_supply")) {
setUnit("%self");
}
if ((!unit || localhost) && v.endsWith("epoch")) {
setUnit("epoch");
}
if ((!unit || localhost) && v === "difficulty") {
setUnit("difficulty");
}
if ((!unit || localhost) && v === "blockhash") {
setUnit("hash");
}
if ((!unit || localhost) && v.startsWith("hash_price_phs")) {
setUnit("usd/(ph/s)/day");
}
if ((!unit || localhost) && v.startsWith("hash_price_ths")) {
setUnit("usd/(th/s)/day");
}
if ((!unit || localhost) && v.startsWith("hash_value_phs")) {
setUnit("sats/(ph/s)/day");
}
if ((!unit || localhost) && v.startsWith("hash_value_ths")) {
setUnit("sats/(th/s)/day");
}
if (
(!unit || localhost) &&
(v.includes("days_between") ||
v.includes("days_since") ||
v.startsWith("days_before"))
) {
setUnit("days");
}
if ((!unit || localhost) && v.includes("years_between")) {
setUnit("years");
}
if ((!unit || localhost) && v == "len") {
setUnit("len");
}
if ((!unit || localhost) && v == "position") {
setUnit("position");
}
if ((!unit || localhost) && v.startsWith("constant")) {
setUnit("constant");
}
if (!unit) {
console.log();
throw Error(`Unit not set for "${v}"`);
}
return /** @type {Unit} */ (unit);
},
};