UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

236 lines (210 loc) 8.72 kB
'use strict'; /** * Executes a Rule of Three calculation. * * @param {number} val1 - The first reference value (numerator in direct proportion, denominator in inverse). * @param {number} val2 - The second reference value (denominator in direct proportion, numerator in inverse). * @param {number} val3 - The third value (numerator in direct proportion, denominator in inverse). * @param {boolean} [inverse] - Whether the calculation should use inverse proportion (true for inverse, false for direct). * @returns {number} The result of the Rule of Three operation. * * Rule of Three Formula (Direct Proportion): * val1 / val2 = val3 / result * * For Inverse Proportion: * val1 / val3 = val2 / result * * Visual Representation: * * For Direct Proportion: * val1 val2 * ----- = ------ * val3 result * * For Inverse Proportion: * val1 val2 * ----- = ------ * val3 result * * @example * // Direct proportion: * ruleOfThree.execute(2, 6, 3, false); // → 9 * * @example * // Inverse proportion: * ruleOfThree.execute(2, 6, 3, true); // → 4 */ function ruleOfThree(val1, val2, val3, inverse = false) { return inverse ? Number(val1 * val2) / val3 : Number(val3 * val2) / val1; } /** * Calculates the actual value that corresponds to a percentage of a base number. * Unlike `getPercentage`, which tells how much something represents in percent, * this function tells how much a given percentage *is worth* in value. * * @param {number} price - The base number to apply the percentage to. * @param {number} percentage - The percentage to calculate from the base. * @returns {number} The resulting value of the percentage. * * @example * getSimplePerc(200, 15); // 30 */ function getSimplePerc(price, percentage) { return price * (percentage / 100); } /** * Calculates how much percent a partial value represents of the total value. * * @param {number} part - The partial value to compare. * @param {number} total - The total or maximum value. * @returns {number} The percentage that 'part' represents of 'total'. * * @example * getPercentage(5, 100); // 5 */ function getPercentage(part, total) { if (total === 0) return 0; return (part / total) * 100; } /** * Calculates the age based on the given date. * * @param {number|string|Date} timeData - The birth date (can be a timestamp, ISO string, or Date object). * @param {Date|null} [now=null] - The Date object representing the current date. Defaults to the current date and time if not provided. * @returns {number|null} The age in years, or null if `timeData` is not provided or invalid. */ function getAge(timeData = 0, now = null) { if (typeof timeData !== 'undefined' && timeData !== null && timeData !== 0) { const birthDate = new Date(timeData); if (Number.isNaN(birthDate.getTime())) return null; const currentDate = now instanceof Date ? now : new Date(); let age = currentDate.getFullYear() - birthDate.getFullYear(); const currentMonth = currentDate.getMonth(); const birthMonth = birthDate.getMonth(); const currentDay = currentDate.getDate(); const birthDay = birthDate.getDate(); // Adjust if birthday hasn't occurred yet this year if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) age--; return Math.abs(age); } return null; } /** * @typedef {Object} FormattedByteResult * @property {string|null} unit - The resulting unit (e.g., 'MB', 'GB') or null if input is invalid. * @property {number|null} value - The numerical value in the chosen unit, or null if input is invalid. */ /** * Converts a byte value into a human-readable format with unit and value separated. * * @param {number} bytes - The number of bytes to format. Must be a non-negative number. * @param {number|null} [decimals=null] - The number of decimal places to include in the result. Defaults to null. If negative, it will be treated as 0. If null, no rounding is applied. * @param {string|null} [maxUnit=null] - Optional unit limit. If provided, restricts conversion to this unit at most (e.g., 'MB' prevents conversion to 'GB' or higher). Must be one of: 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'. * @returns {FormattedByteResult} An object with the converted value and its corresponding unit. Returns nulls if input is invalid. * * @example * formatBytes(123456789); * // → { unit: 'MB', value: 117.74 } * * @example * formatBytes(1073741824, 2, 'MB'); * // → { unit: 'MB', value: 1024 } */ function formatBytes(bytes, decimals = null, maxUnit = null) { if (typeof bytes !== 'number' || bytes < 0) return { unit: null, value: null }; if (bytes === 0) return { unit: 'Bytes', value: 0 }; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const maxIndex = maxUnit && sizes.includes(maxUnit) ? sizes.indexOf(maxUnit) : sizes.length - 1; const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), maxIndex); let value = bytes / Math.pow(k, i); if (decimals !== null) { const dm = decimals < 0 ? 0 : decimals; value = parseFloat(value.toFixed(dm)); } const unit = sizes[i]; return { unit, value }; } /** * Generates a Fibonacci-like sequence as an array of vectors. * * @param {Object} [settings={}] * @param {number[]} [settings.baseValues=[0, 1]] - An array of two starting numbers (e.g. [0, 1] or [1, 1]). * @param {number} [settings.length=10] - Total number of items to generate in the sequence. * @param {(a: number, b: number, index: number) => number} [settings.combiner=((a, b) => a + b)] - A custom function to combine previous two numbers. * @returns {number[]} The resulting Fibonacci sequence. * * FibonacciVectors2D * @example * generateFibonacciSequence({ * baseValues: [[0, 1], [1, 1]], * length: 10, * combiner: ([x1, y1], [x2, y2]) => [x1 + x2, y1 + y2] * }); * * @beta */ function genFibonacciSeq({ baseValues = [0, 1], length = 10, combiner = (a, b) => a + b, } = {}) { if (!Array.isArray(baseValues) || baseValues.length !== 2) throw new Error('baseValues must be an array of exactly two numbers'); const sequence = [...baseValues.slice(0, 2)]; for (let i = 2; i < length; i++) { const next = combiner(sequence[i - 2], sequence[i - 1], i); sequence.push(next); } return sequence; } /** * Calculates the unit price of a coin or token based on the market capitalization and circulating supply. * * This function is typically used in financial contexts to determine the price * of an asset by dividing its total market capitalization by its circulating supply. * * @param {number} originalMarketCap - The total market capitalization (e.g., in USD). * @param {number} circulatingSupply - The number of coins/tokens currently in circulation. * @returns {number} The calculated price per unit of the asset. */ function calculateMarketcap(originalMarketCap, circulatingSupply) { if (Number.isNaN(originalMarketCap) || !Number.isFinite(originalMarketCap)) throw new TypeError('Original market cap must be a number.'); if (Number.isNaN(circulatingSupply) || !Number.isFinite(circulatingSupply)) throw new TypeError('Circulating supply must be a number.'); if (circulatingSupply <= 0) throw new Error('Circulating supply must be greater than zero.'); return originalMarketCap / circulatingSupply; } /** * Calculates the new price of a coin when the market cap changes. * @param {number} originalMarketCap - The original market cap. * @param {number} circulatingSupply - The circulating supply. * @param {number} newMarketCap - The new market cap. * @returns {{ * originalPrice: number, * newPrice: number, * priceChangePercent: number * }} */ function compareMarketcap(originalMarketCap, circulatingSupply, newMarketCap) { if (Number.isNaN(newMarketCap) || !Number.isFinite(newMarketCap)) throw new TypeError('New market cap must be a number.'); const originalPrice = calculateMarketcap(originalMarketCap, circulatingSupply); const newPrice = typeof newMarketCap === 'number' ? newMarketCap / circulatingSupply : NaN; const priceChangePercent = typeof newMarketCap === 'number' ? ((newPrice - originalPrice) / originalPrice) * 100 : NaN; return { originalPrice, newPrice, priceChangePercent, }; } exports.calculateMarketcap = calculateMarketcap; exports.compareMarketcap = compareMarketcap; exports.formatBytes = formatBytes; exports.genFibonacciSeq = genFibonacciSeq; exports.getAge = getAge; exports.getPercentage = getPercentage; exports.getSimplePerc = getSimplePerc; exports.ruleOfThree = ruleOfThree;