mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-25 09:48:10 -07:00
bitview: reorg part 5
This commit is contained in:
@@ -1,281 +0,0 @@
|
||||
import { serdeIndex } from "./serde";
|
||||
import { runWhenIdle } from "./timing";
|
||||
|
||||
/**
|
||||
* @param {Signals} signals
|
||||
* @param {Utilities} utils
|
||||
* @param {Env} env
|
||||
* @param {MetricToIndexes} metricToIndexes
|
||||
*/
|
||||
export function createVecsResources(signals, utils, env, metricToIndexes) {
|
||||
const owner = signals.getOwner();
|
||||
|
||||
const defaultFrom = -10_000;
|
||||
const defaultTo = undefined;
|
||||
|
||||
/**
|
||||
* Defaults
|
||||
* - from: -10_000
|
||||
* - to: undefined
|
||||
*
|
||||
* @param {Object} [args]
|
||||
* @param {number} [args.from]
|
||||
* @param {number} [args.to]
|
||||
*/
|
||||
function genFetchedKey(args) {
|
||||
return `${args?.from}-${args?.to}`;
|
||||
}
|
||||
|
||||
const defaultFetchedKey = genFetchedKey({ from: defaultFrom, to: defaultTo });
|
||||
|
||||
/**
|
||||
* @template {number | OHLCTuple} [T=number]
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
*/
|
||||
function createVecResource(index, metric) {
|
||||
if (env.localhost && !(metric in metricToIndexes)) {
|
||||
throw Error(`${metric} not recognized`);
|
||||
}
|
||||
|
||||
return signals.runWithOwner(owner, () => {
|
||||
/** @typedef {T extends number ? SingleValueData : CandlestickData} Value */
|
||||
|
||||
const fetchedRecord = signals.createSignal(
|
||||
/** @type {Map<string, {loading: boolean, at: Date | null, vec: Signal<T[] | null>}>} */ (
|
||||
new Map()
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
url: api.genUrl(index, metric, defaultFrom),
|
||||
fetched: fetchedRecord,
|
||||
/**
|
||||
* Defaults
|
||||
* - from: -10_000
|
||||
* - to: undefined
|
||||
*
|
||||
* @param {Object} [args]
|
||||
* @param {number} [args.from]
|
||||
* @param {number} [args.to]
|
||||
*/
|
||||
async fetch(args) {
|
||||
const from = args?.from ?? defaultFrom;
|
||||
const to = args?.to ?? defaultTo;
|
||||
const fetchedKey = genFetchedKey({ from, to });
|
||||
if (!fetchedRecord().has(fetchedKey)) {
|
||||
fetchedRecord.set((map) => {
|
||||
map.set(fetchedKey, {
|
||||
loading: false,
|
||||
at: null,
|
||||
vec: signals.createSignal(/** @type {T[] | null} */ (null), {
|
||||
equals: false,
|
||||
}),
|
||||
});
|
||||
return map;
|
||||
});
|
||||
}
|
||||
const fetched = fetchedRecord().get(fetchedKey);
|
||||
if (!fetched) throw Error("Unreachable");
|
||||
if (fetched.loading) return fetched.vec();
|
||||
if (fetched.at) {
|
||||
const diff = new Date().getTime() - fetched.at.getTime();
|
||||
const ONE_MINUTE_IN_MS = 60_000;
|
||||
if (diff < ONE_MINUTE_IN_MS) return fetched.vec();
|
||||
}
|
||||
fetched.loading = true;
|
||||
const res = /** @type {T[] | null} */ (
|
||||
await api.fetchVec(
|
||||
(values) => {
|
||||
if (values.length || !fetched.vec()) {
|
||||
fetched.vec.set(values);
|
||||
}
|
||||
},
|
||||
index,
|
||||
metric,
|
||||
from,
|
||||
to,
|
||||
)
|
||||
);
|
||||
fetched.at = new Date();
|
||||
fetched.loading = false;
|
||||
return res;
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/** @type {Map<string, NonNullable<ReturnType<typeof createVecResource>>>} */
|
||||
const map = new Map();
|
||||
|
||||
const vecs = {
|
||||
/**
|
||||
* @template {number | OHLCTuple} [T=number]
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
*/
|
||||
getOrCreate(index, metric) {
|
||||
const key = `${index},${metric}`;
|
||||
const found = map.get(key);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
|
||||
const vec = createVecResource(index, metric);
|
||||
if (!vec) throw Error("vec is undefined");
|
||||
map.set(key, /** @type {any} */ (vec));
|
||||
return vec;
|
||||
},
|
||||
genFetchedKey,
|
||||
defaultFetchedKey,
|
||||
};
|
||||
|
||||
return vecs;
|
||||
}
|
||||
/** @typedef {ReturnType<typeof createVecsResources>} VecsResources */
|
||||
/** @typedef {ReturnType<VecsResources["getOrCreate"]>} VecResource */
|
||||
|
||||
const CACHE_NAME = "api";
|
||||
const API_VECS_PREFIX = "/api/vecs";
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {(value: T) => void} callback
|
||||
* @param {string} path
|
||||
* @param {boolean} [mustBeArray]
|
||||
*/
|
||||
async function fetchApi(callback, path, mustBeArray) {
|
||||
const url = `${API_VECS_PREFIX}${path}`;
|
||||
|
||||
/** @type {T | null} */
|
||||
let cachedJson = null;
|
||||
|
||||
/** @type {Cache | undefined} */
|
||||
let cache;
|
||||
try {
|
||||
cache = await caches.open(CACHE_NAME);
|
||||
const cachedResponse = await cache.match(url);
|
||||
if (cachedResponse) {
|
||||
console.debug(`cache: ${url}`);
|
||||
const json = /** @type {T} */ await cachedResponse.json();
|
||||
cachedJson = json;
|
||||
callback(json);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (navigator.onLine) {
|
||||
// TODO: rerun after 10s instead of returning (due to some kind of error)
|
||||
|
||||
/** @type {Response | undefined} */
|
||||
let fetchedResponse;
|
||||
try {
|
||||
fetchedResponse = await fetch(url, {
|
||||
signal: AbortSignal.timeout(5000),
|
||||
});
|
||||
if (!fetchedResponse.ok) {
|
||||
throw Error;
|
||||
}
|
||||
} catch {
|
||||
return cachedJson;
|
||||
}
|
||||
|
||||
const clonedResponse = fetchedResponse.clone();
|
||||
|
||||
let fetchedJson = /** @type {T | null} */ (null);
|
||||
try {
|
||||
const f = await fetchedResponse.json();
|
||||
fetchedJson = /** @type {T} */ (
|
||||
mustBeArray && !Array.isArray(f) ? [f] : f
|
||||
);
|
||||
} catch (_) {
|
||||
return cachedJson;
|
||||
}
|
||||
|
||||
if (!fetchedJson) return cachedJson;
|
||||
|
||||
console.debug(`fetch: ${url}`);
|
||||
|
||||
if (Array.isArray(cachedJson) && Array.isArray(fetchedJson)) {
|
||||
const previousLength = cachedJson?.length || 0;
|
||||
const newLength = fetchedJson.length;
|
||||
|
||||
if (!newLength) {
|
||||
return cachedJson;
|
||||
}
|
||||
|
||||
if (previousLength && previousLength === newLength) {
|
||||
const previousLastValue = Object.values(cachedJson || []).at(-1);
|
||||
const newLastValue = Object.values(fetchedJson).at(-1);
|
||||
if (
|
||||
JSON.stringify(previousLastValue) === JSON.stringify(newLastValue)
|
||||
) {
|
||||
return cachedJson;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callback(fetchedJson);
|
||||
|
||||
runWhenIdle(async function () {
|
||||
try {
|
||||
await cache?.put(url, clonedResponse);
|
||||
} catch (_) {}
|
||||
});
|
||||
|
||||
return fetchedJson;
|
||||
} else {
|
||||
return cachedJson;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
* @param {number} [from]
|
||||
* @param {number} [to]
|
||||
*/
|
||||
function genPath(index, metric, from, to) {
|
||||
let path = `/${serdeIndex.serialize(index)}-to-${metric.replaceAll("_", "-")}?`;
|
||||
|
||||
if (from !== undefined) {
|
||||
path += `from=${from}`;
|
||||
}
|
||||
if (to !== undefined) {
|
||||
if (!path.endsWith("?")) {
|
||||
path += `&`;
|
||||
}
|
||||
path += `to=${to}`;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
/**
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
* @param {number} from
|
||||
*/
|
||||
genUrl(index, metric, from) {
|
||||
return `${API_VECS_PREFIX}${genPath(index, metric, from)}`;
|
||||
},
|
||||
/**
|
||||
* @template {number | OHLCTuple} [T=number]
|
||||
* @param {(v: T[]) => void} callback
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
* @param {number} [from]
|
||||
* @param {number} [to]
|
||||
*/
|
||||
fetchVec(callback, index, metric, from, to) {
|
||||
return fetchApi(callback, genPath(index, metric, from, to), true);
|
||||
},
|
||||
/**
|
||||
* @template {number | OHLCTuple} [T=number]
|
||||
* @param {(v: T) => void} callback
|
||||
* @param {Index} index
|
||||
* @param {Metric} metric
|
||||
*/
|
||||
fetchLast(callback, index, metric) {
|
||||
return fetchApi(callback, genPath(index, metric, -1));
|
||||
},
|
||||
};
|
||||
+7
-14
@@ -1,4 +1,4 @@
|
||||
/** @import { IChartApi, ISeriesApi as _ISeriesApi, SeriesDefinition, SingleValueData as _SingleValueData, CandlestickData as _CandlestickData, BaselineData as _BaselineData, HistogramData as _HistogramData, SeriesType, IPaneApi, LineSeriesPartialOptions as _LineSeriesPartialOptions, HistogramSeriesPartialOptions as _HistogramSeriesPartialOptions, BaselineSeriesPartialOptions as _BaselineSeriesPartialOptions, CandlestickSeriesPartialOptions as _CandlestickSeriesPartialOptions, WhitespaceData, DeepPartial, ChartOptions, Time, LineData as _LineData } from '../packages/lightweight-charts/5.0.8/dist/typings' */
|
||||
/** @import { IChartApi, ISeriesApi as _ISeriesApi, SeriesDefinition, SingleValueData as _SingleValueData, CandlestickData as _CandlestickData, BaselineData as _BaselineData, HistogramData as _HistogramData, SeriesType, IPaneApi, LineSeriesPartialOptions as _LineSeriesPartialOptions, HistogramSeriesPartialOptions as _HistogramSeriesPartialOptions, BaselineSeriesPartialOptions as _BaselineSeriesPartialOptions, CandlestickSeriesPartialOptions as _CandlestickSeriesPartialOptions, WhitespaceData, DeepPartial, ChartOptions, Time, LineData as _LineData } from '../../packages/lightweight-charts/5.0.8/dist/typings' */
|
||||
|
||||
import {
|
||||
createChart,
|
||||
@@ -7,20 +7,18 @@ import {
|
||||
LineSeries,
|
||||
BaselineSeries,
|
||||
// } from "../packages/lightweight-charts/5.0.8/dist/lightweight-charts.standalone.development.mjs";
|
||||
} from "../packages/lightweight-charts/5.0.8/dist/lightweight-charts.standalone.production.mjs";
|
||||
} from "../../packages/lightweight-charts/5.0.8/dist/lightweight-charts.standalone.production.mjs";
|
||||
|
||||
import {
|
||||
createHorizontalChoiceField,
|
||||
createLabeledInput,
|
||||
createSpanName,
|
||||
} from "./dom";
|
||||
import { createOklchToRGBA } from "./colors";
|
||||
import { throttle } from "./timing";
|
||||
import { serdeBool } from "./serde";
|
||||
} from "../dom";
|
||||
import { createOklchToRGBA } from "./oklch";
|
||||
import { throttle } from "../timing";
|
||||
import { serdeBool } from "../serde";
|
||||
|
||||
/**
|
||||
* @typedef {[number, number, number, number]} OHLCTuple
|
||||
*
|
||||
* @typedef {Object} Valued
|
||||
* @property {number} value
|
||||
*
|
||||
@@ -1003,7 +1001,7 @@ function numberToShortUSFormat(value, digits) {
|
||||
return numberToUSFormat(value, Math.min(1, digits || 10));
|
||||
} else if (absoluteValue < 1_000_000) {
|
||||
return numberToUSFormat(value, 0);
|
||||
} else if (absoluteValue >= 900_000_000_000_000_000_000_000) {
|
||||
} else if (absoluteValue >= 1_000_000_000_000_000_000_000) {
|
||||
return "Inf.";
|
||||
}
|
||||
|
||||
@@ -1015,11 +1013,6 @@ function numberToShortUSFormat(value, digits) {
|
||||
|
||||
const modulused = log % 3;
|
||||
|
||||
// return `${numberToUSFormat(
|
||||
// value / (1_000_000 * 1_000 ** letterIndex),
|
||||
// 3,
|
||||
// )}${letter}`;
|
||||
|
||||
if (modulused === 0) {
|
||||
return `${numberToUSFormat(
|
||||
value / (1_000_000 * 1_000 ** letterIndex),
|
||||
@@ -0,0 +1,100 @@
|
||||
export function createOklchToRGBA() {
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {readonly [number, number, number, number, number, number, number, number, number]} A
|
||||
* @param {readonly [number, number, number]} B
|
||||
* @returns
|
||||
*/
|
||||
function multiplyMatrices(A, B) {
|
||||
return /** @type {const} */ ([
|
||||
A[0] * B[0] + A[1] * B[1] + A[2] * B[2],
|
||||
A[3] * B[0] + A[4] * B[1] + A[5] * B[2],
|
||||
A[6] * B[0] + A[7] * B[1] + A[8] * B[2],
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} param0
|
||||
*/
|
||||
function oklch2oklab([l, c, h]) {
|
||||
return /** @type {const} */ ([
|
||||
l,
|
||||
isNaN(h) ? 0 : c * Math.cos((h * Math.PI) / 180),
|
||||
isNaN(h) ? 0 : c * Math.sin((h * Math.PI) / 180),
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} rgb
|
||||
*/
|
||||
function srgbLinear2rgb(rgb) {
|
||||
return rgb.map((c) =>
|
||||
Math.abs(c) > 0.0031308
|
||||
? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055)
|
||||
: 12.92 * c,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} lab
|
||||
*/
|
||||
function oklab2xyz(lab) {
|
||||
const LMSg = multiplyMatrices(
|
||||
/** @type {const} */ ([
|
||||
1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586,
|
||||
-0.0638541728258133, 1, -0.0894841775298119, -1.2914855480194092,
|
||||
]),
|
||||
lab,
|
||||
);
|
||||
const LMS = /** @type {[number, number, number]} */ (
|
||||
LMSg.map((val) => val ** 3)
|
||||
);
|
||||
return multiplyMatrices(
|
||||
/** @type {const} */ ([
|
||||
1.2268798758459243, -0.5578149944602171, 0.2813910456659647,
|
||||
-0.0405757452148008, 1.112286803280317, -0.0717110580655164,
|
||||
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816,
|
||||
]),
|
||||
LMS,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} xyz
|
||||
*/
|
||||
function xyz2rgbLinear(xyz) {
|
||||
return multiplyMatrices(
|
||||
[
|
||||
3.2409699419045226, -1.537383177570094, -0.4986107602930034,
|
||||
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
|
||||
0.05563007969699366, -0.20397695888897652, 1.0569715142428786,
|
||||
],
|
||||
xyz,
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {string} oklch */
|
||||
return function (oklch) {
|
||||
oklch = oklch.replace("oklch(", "");
|
||||
oklch = oklch.replace(")", "");
|
||||
let splitOklch = oklch.split(" / ");
|
||||
let alpha = 1;
|
||||
if (splitOklch.length === 2) {
|
||||
alpha = Number(splitOklch.pop()?.replace("%", "")) / 100;
|
||||
}
|
||||
splitOklch = oklch.split(" ");
|
||||
const lch = splitOklch.map((v, i) => {
|
||||
if (!i && v.includes("%")) {
|
||||
return Number(v.replace("%", "")) / 100;
|
||||
} else {
|
||||
return Number(v);
|
||||
}
|
||||
});
|
||||
const rgb = srgbLinear2rgb(
|
||||
xyz2rgbLinear(
|
||||
oklab2xyz(oklch2oklab(/** @type {[number, number, number]} */ (lch))),
|
||||
),
|
||||
).map((v) => {
|
||||
return Math.max(Math.min(Math.round(v * 255), 255), 0);
|
||||
});
|
||||
return [...rgb, alpha];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -114,104 +114,3 @@ export function createColors(dark) {
|
||||
* @typedef {Colors["orange"]} Color
|
||||
* @typedef {keyof Colors} ColorName
|
||||
*/
|
||||
|
||||
export function createOklchToRGBA() {
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @param {readonly [number, number, number, number, number, number, number, number, number]} A
|
||||
* @param {readonly [number, number, number]} B
|
||||
* @returns
|
||||
*/
|
||||
function multiplyMatrices(A, B) {
|
||||
return /** @type {const} */ ([
|
||||
A[0] * B[0] + A[1] * B[1] + A[2] * B[2],
|
||||
A[3] * B[0] + A[4] * B[1] + A[5] * B[2],
|
||||
A[6] * B[0] + A[7] * B[1] + A[8] * B[2],
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} param0
|
||||
*/
|
||||
function oklch2oklab([l, c, h]) {
|
||||
return /** @type {const} */ ([
|
||||
l,
|
||||
isNaN(h) ? 0 : c * Math.cos((h * Math.PI) / 180),
|
||||
isNaN(h) ? 0 : c * Math.sin((h * Math.PI) / 180),
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} rgb
|
||||
*/
|
||||
function srgbLinear2rgb(rgb) {
|
||||
return rgb.map((c) =>
|
||||
Math.abs(c) > 0.0031308
|
||||
? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055)
|
||||
: 12.92 * c,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} lab
|
||||
*/
|
||||
function oklab2xyz(lab) {
|
||||
const LMSg = multiplyMatrices(
|
||||
/** @type {const} */ ([
|
||||
1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586,
|
||||
-0.0638541728258133, 1, -0.0894841775298119, -1.2914855480194092,
|
||||
]),
|
||||
lab,
|
||||
);
|
||||
const LMS = /** @type {[number, number, number]} */ (
|
||||
LMSg.map((val) => val ** 3)
|
||||
);
|
||||
return multiplyMatrices(
|
||||
/** @type {const} */ ([
|
||||
1.2268798758459243, -0.5578149944602171, 0.2813910456659647,
|
||||
-0.0405757452148008, 1.112286803280317, -0.0717110580655164,
|
||||
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816,
|
||||
]),
|
||||
LMS,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {readonly [number, number, number]} xyz
|
||||
*/
|
||||
function xyz2rgbLinear(xyz) {
|
||||
return multiplyMatrices(
|
||||
[
|
||||
3.2409699419045226, -1.537383177570094, -0.4986107602930034,
|
||||
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
|
||||
0.05563007969699366, -0.20397695888897652, 1.0569715142428786,
|
||||
],
|
||||
xyz,
|
||||
);
|
||||
}
|
||||
|
||||
/** @param {string} oklch */
|
||||
return function (oklch) {
|
||||
oklch = oklch.replace("oklch(", "");
|
||||
oklch = oklch.replace(")", "");
|
||||
let splitOklch = oklch.split(" / ");
|
||||
let alpha = 1;
|
||||
if (splitOklch.length === 2) {
|
||||
alpha = Number(splitOklch.pop()?.replace("%", "")) / 100;
|
||||
}
|
||||
splitOklch = oklch.split(" ");
|
||||
const lch = splitOklch.map((v, i) => {
|
||||
if (!i && v.includes("%")) {
|
||||
return Number(v.replace("%", "")) / 100;
|
||||
} else {
|
||||
return Number(v);
|
||||
}
|
||||
});
|
||||
const rgb = srgbLinear2rgb(
|
||||
xyz2rgbLinear(
|
||||
oklab2xyz(oklch2oklab(/** @type {[number, number, number]} */ (lch))),
|
||||
),
|
||||
).map((v) => {
|
||||
return Math.max(Math.min(Math.round(v * 255), 255), 0);
|
||||
});
|
||||
return [...rgb, alpha];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -101,9 +101,9 @@ export const serdeBool = {
|
||||
* @param {string} v
|
||||
*/
|
||||
deserialize(v) {
|
||||
if (v === "true") {
|
||||
if (v === "true" || v === "1") {
|
||||
return true;
|
||||
} else if (v === "false") {
|
||||
} else if (v === "false" || v === "0") {
|
||||
return false;
|
||||
} else {
|
||||
throw "deser bool err";
|
||||
@@ -111,70 +111,6 @@ export const serdeBool = {
|
||||
},
|
||||
};
|
||||
|
||||
export const serdeIndex = {
|
||||
/**
|
||||
* @param {Index} v
|
||||
*/
|
||||
serialize(v) {
|
||||
switch (v) {
|
||||
case /** @satisfies {DateIndex} */ (0):
|
||||
return "dateindex";
|
||||
case /** @satisfies {DecadeIndex} */ (1):
|
||||
return "decadeindex";
|
||||
case /** @satisfies {DifficultyEpoch} */ (2):
|
||||
return "difficultyepoch";
|
||||
case /** @satisfies {EmptyOutputIndex} */ (3):
|
||||
return "emptyoutputindex";
|
||||
case /** @satisfies {HalvingEpoch} */ (4):
|
||||
return "halvingepoch";
|
||||
case /** @satisfies {Height} */ (5):
|
||||
return "height";
|
||||
case /** @satisfies {InputIndex} */ (6):
|
||||
return "inputindex";
|
||||
case /** @satisfies {MonthIndex} */ (7):
|
||||
return "monthindex";
|
||||
case /** @satisfies {OpReturnIndex} */ (8):
|
||||
return "opreturnindex";
|
||||
case /** @satisfies {OutputIndex} */ (9):
|
||||
return "outputindex";
|
||||
case /** @satisfies {P2AAddressIndex} */ (10):
|
||||
return "p2aaddressindex";
|
||||
case /** @satisfies {P2MSOutputIndex} */ (11):
|
||||
return "p2msoutputindex";
|
||||
case /** @satisfies {P2PK33AddressIndex} */ (12):
|
||||
return "p2pk33addressindex";
|
||||
case /** @satisfies {P2PK65AddressIndex} */ (13):
|
||||
return "p2pk65addressindex";
|
||||
case /** @satisfies {P2PKHAddressIndex} */ (14):
|
||||
return "p2pkhaddressindex";
|
||||
case /** @satisfies {P2SHAddressIndex} */ (15):
|
||||
return "p2shaddressindex";
|
||||
case /** @satisfies {P2TRAddressIndex} */ (16):
|
||||
return "p2traddressindex";
|
||||
case /** @satisfies {P2WPKHAddressIndex} */ (17):
|
||||
return "p2wpkhaddressindex";
|
||||
case /** @satisfies {P2WSHAddressIndex} */ (18):
|
||||
return "p2wshaddressindex";
|
||||
case /** @satisfies {QuarterIndex} */ (19):
|
||||
return "quarterindex";
|
||||
case /** @satisfies {SemesterIndex} */ (20):
|
||||
return "semesterindex";
|
||||
case /** @satisfies {TxIndex} */ (21):
|
||||
return "txindex";
|
||||
case /** @satisfies {UnknownOutputIndex} */ (22):
|
||||
return "unknownoutputindex";
|
||||
case /** @satisfies {WeekIndex} */ (23):
|
||||
return "weekindex";
|
||||
case /** @satisfies {YearIndex} */ (24):
|
||||
return "yearindex";
|
||||
case /** @satisfies {LoadedAddressIndex} */ (25):
|
||||
return "loadedaddressindex";
|
||||
case /** @satisfies {EmptyAddressIndex} */ (26):
|
||||
return "emptyaddressindex";
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export const serdeChartableIndex = {
|
||||
/**
|
||||
* @param {number} v
|
||||
|
||||
@@ -36,15 +36,3 @@ export function throttle(callback, wait = 1000) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VoidFunction} callback
|
||||
* @param {number} [timeout = 1]
|
||||
*/
|
||||
export function runWhenIdle(callback, timeout = 1) {
|
||||
if ("requestIdleCallback" in window) {
|
||||
requestIdleCallback(callback);
|
||||
} else {
|
||||
setTimeout(callback, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user