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.

190 lines (166 loc) 6.65 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; } exports.formatBytes = formatBytes; exports.genFibonacciSeq = genFibonacciSeq; exports.getAge = getAge; exports.getPercentage = getPercentage; exports.getSimplePerc = getSimplePerc; exports.ruleOfThree = ruleOfThree;