UNPKG

@ledgerhq/live-common

Version:
89 lines 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.reverseRangeIndex = exports.projectRangeIndex = exports.inferDynamicRange = exports.toRangeRaw = exports.fromRangeRaw = void 0; // Utility to deal with ranges const bignumber_js_1 = require("bignumber.js"); function fromRangeRaw(r) { return { initial: new bignumber_js_1.BigNumber(r.initial), min: new bignumber_js_1.BigNumber(r.min), max: new bignumber_js_1.BigNumber(r.max), step: new bignumber_js_1.BigNumber(r.step), steps: r.steps, }; } exports.fromRangeRaw = fromRangeRaw; function toRangeRaw(r) { return { initial: r.initial.toString(), min: r.min.toString(), max: r.max.toString(), step: r.step.toString(), steps: r.steps, }; } exports.toRangeRaw = toRangeRaw; const defaultOpts = { minMult: 0.3, maxMult: 2, targetSteps: 20, }; // infer a range from ONE estimated fees value. // e.g. we just have a "gasPrice" and we want a slider to move a gas value around it. // to test this: // for (let i = 0.1; i < 10; i += 0.1) console.log(i, inferDynamicRange(i)); function inferDynamicRange(amount, opts = {}) { const { minMult, maxMult, targetSteps, minValue, maxValue } = { ...defaultOpts, ...opts, }; const targetMin = minValue || amount.times(minMult); const targetMax = maxValue || amount.times(maxMult); const step = findBestRangeStep(targetMin, targetMax, targetSteps); if (Number.isNaN(step) || step.lte(0)) { throw new Error("inferDynamicRange: invalid parameters"); } const initial = stepping(amount, step, bignumber_js_1.BigNumber.ROUND_CEIL); const min = stepping(targetMin, step, bignumber_js_1.BigNumber.ROUND_CEIL); const max = stepping(targetMax, step, bignumber_js_1.BigNumber.ROUND_CEIL); const steps = max.minus(min).div(step).plus(1).toNumber(); return { initial, min, max, step, steps, }; } exports.inferDynamicRange = inferDynamicRange; function projectRangeIndex(range, index) { return range.min.plus(range.step.times(index)); } exports.projectRangeIndex = projectRangeIndex; function reverseRangeIndex(range, n) { const x = n.minus(range.min).div(range.max.minus(range.min)); const i = x.times(range.steps).integerValue(bignumber_js_1.BigNumber.ROUND_FLOOR).toNumber(); return Math.max(0, Math.min(i, range.steps - 1)); } exports.reverseRangeIndex = reverseRangeIndex; function stepping(n, step, roundingMode) { return n.div(step).integerValue(roundingMode).times(step); } const log10 = Math.log(10); // return step to use for a [min,max] with a planned number of steps (will approx). function findBestRangeStep(min, max, steps) { const nonRoundedStep = (max.toNumber() - min.toNumber()) / steps; const mag = Math.log(nonRoundedStep) / log10; const magInt = Math.floor(mag); const remain = mag - magInt; let step = new bignumber_js_1.BigNumber(10).pow(magInt); // heuristics if (remain < 0.3) { step = step.div(5); } else if (remain < 0.7) { step = step.div(2); } return step; } //# sourceMappingURL=range.js.map