From 6a2502a4cf8d88730b3dd7c6cbd162ad24203500 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:05:19 -0400 Subject: [PATCH 01/12] Reshaping the code for better testing --- dist/filesize.cjs | 285 ++++++++++++++++++---------- dist/filesize.js | 284 ++++++++++++++++----------- dist/filesize.min.js | 4 +- dist/filesize.min.js.map | 2 +- dist/filesize.umd.js | 284 ++++++++++++++++----------- dist/filesize.umd.min.js | 4 +- dist/filesize.umd.min.js.map | 2 +- package-lock.json | 4 +- package.json | 2 +- src/filesize.js | 278 +++++++++++++++++---------- tests/unit/filesize-helpers.test.js | 200 +++++++++++++++++++ 11 files changed, 917 insertions(+), 432 deletions(-) create mode 100644 tests/unit/filesize-helpers.test.js diff --git a/dist/filesize.cjs b/dist/filesize.cjs index 54ffaf0..e698a33 100644 --- a/dist/filesize.cjs +++ b/dist/filesize.cjs @@ -3,7 +3,7 @@ * * @copyright 2025 Jason Mulligan * @license BSD-3-Clause - * @version 11.0.10 + * @version 11.0.11 */ 'use strict'; @@ -89,6 +89,13 @@ const DECIMAL_POWERS = [ const LOG_2_1024 = Math.log(1024); const LOG_10_1000 = Math.log(1000); +// Cached configuration lookup for better performance +const STANDARD_CONFIGS = { + [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, + [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, + [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } +}; + /** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert @@ -140,29 +147,9 @@ function filesize (arg, { val = 0, u = EMPTY; - // Optimized base & standard synchronization with early returns - let isDecimal, ceil, actualStandard; - if (standard === SI) { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } else if (standard === IEC) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else if (standard === JEDEC) { - isDecimal = false; // JEDEC uses binary (1024) by default - ceil = 1024; - actualStandard = JEDEC; - } else if (base === 2) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } + // Optimized base & standard configuration lookup + const config = getBaseConfiguration(standard, base); + const { isDecimal, ceil, actualStandard } = config; const full = fullform === true, neg = num < 0, @@ -183,38 +170,12 @@ function filesize (arg, { // Fast path for zero if (num === 0) { - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Skip most processing for zero case - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); + return handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer); } // Optimized exponent calculation using pre-computed log values if (e === -1 || isNaN(e)) { - if (isDecimal) { - e = Math.floor(Math.log(num) / LOG_10_1000); - } else { - e = Math.floor(Math.log(num) / LOG_2_1024); - } - + e = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024); if (e < 0) { e = 0; } @@ -232,24 +193,10 @@ function filesize (arg, { return e; } - // Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements) - let d; - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - - val = num / d; - - if (bits) { - val = val * 8; - - if (val >= ceil && e < 8) { - val = val / ceil; - e++; - } - } + // Calculate value with optimized lookup and bits handling + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult.val; + e = valueResult.e; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -260,21 +207,11 @@ function filesize (arg, { e++; } - // Setting optional precision + // Apply precision handling if (precision > 0) { - result[0] = result[0].toPrecision(precision); - - if (result[0].includes(E) && e < 8) { - e++; - // Recalculate with new exponent (e is always <= 8) - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - val = num / d; - result[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision); - } + const precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round); + result[0] = precisionResult.value; + e = precisionResult.e; } // Cache symbol lookup @@ -291,25 +228,8 @@ function filesize (arg, { result[1] = symbols[result[1]]; } - // Optimized locale/separator handling - if (locale === true) { - result[0] = result[0].toLocaleString(); - } else if (locale.length > 0) { - result[0] = result[0].toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result[0] = result[0].toString().replace(PERIOD, separator); - } - - if (pad && round > 0) { - const resultStr = result[0].toString(), - x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD), - tmp = resultStr.split(x), - s = tmp[1] || EMPTY, - l = s.length, - n = round - l; - - result[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } + // Apply locale, separator, and padding formatting + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); if (full) { result[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); @@ -319,7 +239,7 @@ function filesize (arg, { if (output === ARRAY) { return result; } - + if (output === OBJECT) { return { value: result[0], @@ -328,10 +248,160 @@ function filesize (arg, { unit: u }; } - + return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration(standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return { isDecimal: false, ceil: 1024, actualStandard: IEC }; + } + + // Default + return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let val = num / d; + + if (bits) { + val *= 8; + // Handle auto-increment for bits + if (val >= ceil && e < 8) { + val /= ceil; + e++; + } + } + + return { val, e }; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); + } + + return { value: result, e }; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} + /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -396,5 +466,10 @@ function partial ({ }); } +exports.applyNumberFormatting = applyNumberFormatting; +exports.applyPrecisionHandling = applyPrecisionHandling; +exports.calculateOptimizedValue = calculateOptimizedValue; exports.filesize = filesize; +exports.getBaseConfiguration = getBaseConfiguration; +exports.handleZeroValue = handleZeroValue; exports.partial = partial; diff --git a/dist/filesize.js b/dist/filesize.js index a3572bd..837eeb7 100644 --- a/dist/filesize.js +++ b/dist/filesize.js @@ -3,7 +3,7 @@ * * @copyright 2025 Jason Mulligan * @license BSD-3-Clause - * @version 11.0.10 + * @version 11.0.11 */ // Error Messages const INVALID_NUMBER = "Invalid number"; @@ -85,7 +85,14 @@ const DECIMAL_POWERS = [ // Pre-computed log values for faster exponent calculation const LOG_2_1024 = Math.log(1024); -const LOG_10_1000 = Math.log(1000);/** +const LOG_10_1000 = Math.log(1000);// Cached configuration lookup for better performance +const STANDARD_CONFIGS = { + [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, + [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, + [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } +}; + +/** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert * @param {Object} [options={}] - Configuration options for formatting @@ -136,29 +143,9 @@ function filesize (arg, { val = 0, u = EMPTY; - // Optimized base & standard synchronization with early returns - let isDecimal, ceil, actualStandard; - if (standard === SI) { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } else if (standard === IEC) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else if (standard === JEDEC) { - isDecimal = false; // JEDEC uses binary (1024) by default - ceil = 1024; - actualStandard = JEDEC; - } else if (base === 2) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } + // Optimized base & standard configuration lookup + const config = getBaseConfiguration(standard, base); + const { isDecimal, ceil, actualStandard } = config; const full = fullform === true, neg = num < 0, @@ -179,38 +166,12 @@ function filesize (arg, { // Fast path for zero if (num === 0) { - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Skip most processing for zero case - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); + return handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer); } // Optimized exponent calculation using pre-computed log values if (e === -1 || isNaN(e)) { - if (isDecimal) { - e = Math.floor(Math.log(num) / LOG_10_1000); - } else { - e = Math.floor(Math.log(num) / LOG_2_1024); - } - + e = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024); if (e < 0) { e = 0; } @@ -228,24 +189,10 @@ function filesize (arg, { return e; } - // Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements) - let d; - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - - val = num / d; - - if (bits) { - val = val * 8; - - if (val >= ceil && e < 8) { - val = val / ceil; - e++; - } - } + // Calculate value with optimized lookup and bits handling + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult.val; + e = valueResult.e; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -256,21 +203,11 @@ function filesize (arg, { e++; } - // Setting optional precision + // Apply precision handling if (precision > 0) { - result[0] = result[0].toPrecision(precision); - - if (result[0].includes(E) && e < 8) { - e++; - // Recalculate with new exponent (e is always <= 8) - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - val = num / d; - result[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision); - } + const precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round); + result[0] = precisionResult.value; + e = precisionResult.e; } // Cache symbol lookup @@ -287,25 +224,8 @@ function filesize (arg, { result[1] = symbols[result[1]]; } - // Optimized locale/separator handling - if (locale === true) { - result[0] = result[0].toLocaleString(); - } else if (locale.length > 0) { - result[0] = result[0].toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result[0] = result[0].toString().replace(PERIOD, separator); - } - - if (pad && round > 0) { - const resultStr = result[0].toString(), - x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD), - tmp = resultStr.split(x), - s = tmp[1] || EMPTY, - l = s.length, - n = round - l; - - result[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } + // Apply locale, separator, and padding formatting + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); if (full) { result[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); @@ -315,7 +235,7 @@ function filesize (arg, { if (output === ARRAY) { return result; } - + if (output === OBJECT) { return { value: result[0], @@ -324,10 +244,160 @@ function filesize (arg, { unit: u }; } - + return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration(standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return { isDecimal: false, ceil: 1024, actualStandard: IEC }; + } + + // Default + return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let val = num / d; + + if (bits) { + val *= 8; + // Handle auto-increment for bits + if (val >= ceil && e < 8) { + val /= ceil; + e++; + } + } + + return { val, e }; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); + } + + return { value: result, e }; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} + /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -390,4 +460,4 @@ function partial ({ roundingMethod, precision }); -}export{filesize,partial}; \ No newline at end of file +}export{applyNumberFormatting,applyPrecisionHandling,calculateOptimizedValue,filesize,getBaseConfiguration,handleZeroValue,partial}; \ No newline at end of file diff --git a/dist/filesize.min.js b/dist/filesize.min.js index 2bb7685..4833127 100644 --- a/dist/filesize.min.js +++ b/dist/filesize.min.js @@ -1,5 +1,5 @@ /*! 2025 Jason Mulligan - @version 11.0.10 + @version 11.0.11 */ -const t="iec",i="jedec",e="bits",o="byte",n="bytes",r="array",l="object",s="string",a="exponent",b="round",p="",u={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},c=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],d=Math.log(1024),m=Math.log(1e3);function g(g,{bits:y=!1,pad:B=!1,base:h=-1,round:M=2,locale:x="",localeOptions:E={},separator:P="",spacer:j=" ",symbols:T={},standard:w="",output:N=s,fullform:$=!1,fullforms:k=[],exponent:v=-1,roundingMethod:G=b,precision:K=0}={}){let S,Y,Z,O=v,z=Number(g),I=[],L=0,D=p;"si"===w?(S=!0,Y=1e3,Z=i):w===t?(S=!1,Y=1024,Z=t):w===i?(S=!1,Y=1024,Z=i):2===h?(S=!1,Y=1024,Z=t):(S=!0,Y=1e3,Z=i);const q=!0===$,A=z<0,C=Math[G];if("bigint"!=typeof g&&isNaN(g))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(z=-z),0===z)return I[0]=K>0?(0).toPrecision(K):0,D=I[1]=u.symbol[Z][y?e:n][0],N===a?0:(T[I[1]]&&(I[1]=T[I[1]]),q&&(I[1]=k[0]||u.fullform[Z][0]+(y?"bit":o)),N===r?I:N===l?{value:I[0],symbol:I[1],exponent:0,unit:D}:I.join(j));if((-1===O||isNaN(O))&&(O=S?Math.floor(Math.log(z)/m):Math.floor(Math.log(z)/d),O<0&&(O=0)),O>8&&(K>0&&(K+=8-O),O=8),N===a)return O;let F;F=S?f[O]:c[O],L=z/F,y&&(L*=8,L>=Y&&O<8&&(L/=Y,O++));const H=O>0&&M>0?Math.pow(10,M):1;I[0]=1===H?C(L):C(L*H)/H,I[0]===Y&&O<8&&-1===v&&(I[0]=1,O++),K>0&&(I[0]=I[0].toPrecision(K),I[0].includes("e")&&O<8&&(O++,F=S?f[O]:c[O],L=z/F,I[0]=(1===H?C(L):C(L*H)/H).toPrecision(K)));const J=u.symbol[Z][y?e:n];if(D=I[1]=S&&1===O?y?"kbit":"kB":J[O],A&&(I[0]=-I[0]),T[I[1]]&&(I[1]=T[I[1]]),!0===x?I[0]=I[0].toLocaleString():x.length>0?I[0]=I[0].toLocaleString(x,E):P.length>0&&(I[0]=I[0].toString().replace(".",P)),B&&M>0){const t=I[0].toString(),i=P||(t.match(/(\D)/g)||[]).pop()||".",e=t.split(i),o=e[1]||p,n=o.length,r=M-n;I[0]=`${e[0]}${i}${o.padEnd(n+r,"0")}`}return q&&(I[1]=k[O]||u.fullform[Z][O]+(y?"bit":o)+(1===I[0]?p:"s")),N===r?I:N===l?{value:I[0],symbol:I[1],exponent:O,unit:D}:" "===j?`${I[0]} ${I[1]}`:I.join(j)}function y({bits:t=!1,pad:i=!1,base:e=-1,round:o=2,locale:n="",localeOptions:r={},separator:l="",spacer:a=" ",symbols:p={},standard:u="",output:c=s,fullform:f=!1,fullforms:d=[],exponent:m=-1,roundingMethod:y=b,precision:B=0}={}){return s=>g(s,{bits:t,pad:i,base:e,round:o,locale:n,localeOptions:r,separator:l,spacer:a,symbols:p,standard:u,output:c,fullform:f,fullforms:d,exponent:m,roundingMethod:y,precision:B})}export{g as filesize,y as partial};//# sourceMappingURL=filesize.min.js.map +const t="iec",i="jedec",e="si",o="bits",n="byte",a="bytes",l="array",r="object",s="string",c="exponent",u="round",b="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),g=Math.log(1e3),h={[e]:{isDecimal:!0,ceil:1e3,actualStandard:i},[t]:{isDecimal:!1,ceil:1024,actualStandard:t},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function y(t,{bits:i=!1,pad:e=!1,base:p=-1,round:f=2,locale:h="",localeOptions:y={},separator:D="",spacer:E=" ",symbols:P={},standard:j="",output:w=s,fullform:T=!1,fullforms:N=[],exponent:$=-1,roundingMethod:k=u,precision:G=0}={}){let K=$,Y=Number(t),Z=[],O=0,z=b;const I=B(j,p),{isDecimal:L,ceil:q,actualStandard:A}=I,C=!0===T,F=Y<0,H=Math[k];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof H)throw new TypeError("Invalid rounding method");if(F&&(Y=-Y),0===Y)return M(G,A,i,P,C,N,w,E);if((-1===K||isNaN(K))&&(K=L?Math.floor(Math.log(Y)/g):Math.floor(Math.log(Y)/m),K<0&&(K=0)),K>8&&(G>0&&(G+=8-K),K=8),w===c)return K;const J=x(Y,K,L,i,q);O=J.val,K=J.e;const Q=K>0&&f>0?Math.pow(10,f):1;if(Z[0]=1===Q?H(O):H(O*Q)/Q,Z[0]===q&&K<8&&-1===$&&(Z[0]=1,K++),G>0){const t=v(Z[0],G,K,Y,L,i,q,H,f);Z[0]=t.value,K=t.e}const R=d.symbol[A][i?o:a];return z=Z[1]=L&&1===K?i?"kbit":"kB":R[K],F&&(Z[0]=-Z[0]),P[Z[1]]&&(Z[1]=P[Z[1]]),Z[0]=S(Z[0],h,y,D,e,f),C&&(Z[1]=N[K]||d.fullform[A][K]+(i?"bit":n)+(1===Z[0]?b:"s")),w===l?Z:w===r?{value:Z[0],symbol:Z[1],exponent:K,unit:z}:" "===E?`${Z[0]} ${Z[1]}`:Z.join(E)}function B(e,o){return h[e]?h[e]:2===o?{isDecimal:!1,ceil:1024,actualStandard:t}:{isDecimal:!0,ceil:1e3,actualStandard:i}}function M(t,i,e,s,u,b,p,f){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[i][e?o:a][0];return p===c?0:(s[m[1]]&&(m[1]=s[m[1]]),u&&(m[1]=b[0]||d.fullform[i][0]+(e?"bit":n)),p===l?m:p===r?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(f))}function x(t,i,e,o,n){let a=t/(e?f[i]:p[i]);return o&&(a*=8,a>=n&&i<8&&(a/=n,i++)),{val:a,e:i}}function v(t,i,e,o,n,a,l,r,s){let c=t.toPrecision(i);if(c.includes("e")&&e<8){const t=x(o,++e,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t.val):r(t.val*u)/u).toPrecision(i)}return{value:c,e:e}}function S(t,i,e,o,n,a){let l=t;if(!0===i?l=l.toLocaleString():i.length>0?l=l.toLocaleString(i,e):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),i=o||(t.match(/(\D)/g)||[]).pop()||".",e=t.split(i),n=e[1]||b,r=n.length,s=a-r;l=`${e[0]}${i}${n.padEnd(r+s,"0")}`}return l}function D({bits:t=!1,pad:i=!1,base:e=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:c={},standard:b="",output:d=s,fullform:p=!1,fullforms:f=[],exponent:m=-1,roundingMethod:g=u,precision:h=0}={}){return s=>y(s,{bits:t,pad:i,base:e,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:c,standard:b,output:d,fullform:p,fullforms:f,exponent:m,roundingMethod:g,precision:h})}export{S as applyNumberFormatting,v as applyPrecisionHandling,x as calculateOptimizedValue,y as filesize,B as getBaseConfiguration,M as handleZeroValue,D as partial};//# sourceMappingURL=filesize.min.js.map diff --git a/dist/filesize.min.js.map b/dist/filesize.min.js.map index 28cd841..44724c9 100644 --- a/dist/filesize.min.js.map +++ b/dist/filesize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard synchronization with early returns\n\tlet isDecimal, ceil, actualStandard;\n\tif (standard === SI) {\n\t\tisDecimal = true;\n\t\tceil = 1000;\n\t\tactualStandard = JEDEC;\n\t} else if (standard === IEC) {\n\t\tisDecimal = false;\n\t\tceil = 1024;\n\t\tactualStandard = IEC;\n\t} else if (standard === JEDEC) {\n\t\tisDecimal = false; // JEDEC uses binary (1024) by default\n\t\tceil = 1024;\n\t\tactualStandard = JEDEC;\n\t} else if (base === 2) {\n\t\tisDecimal = false;\n\t\tceil = 1024;\n\t\tactualStandard = IEC;\n\t} else {\n\t\tisDecimal = true;\n\t\tceil = 1000;\n\t\tactualStandard = JEDEC;\n\t}\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\t\tu = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\t\t\n\t\tif (output === EXPONENT) {\n\t\t\treturn 0;\n\t\t}\n\t\t\n\t\t// Skip most processing for zero case\n\t\tif (symbols[result[1]]) {\n\t\t\tresult[1] = symbols[result[1]];\n\t\t}\n\t\t\n\t\tif (full) {\n\t\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t\t}\n\t\t\n\t\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: 0,\n\t\t\tunit: u\n\t\t} : result.join(spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\tif (isDecimal) {\n\t\t\te = Math.floor(Math.log(num) / LOG_10_1000);\n\t\t} else {\n\t\t\te = Math.floor(Math.log(num) / LOG_2_1024);\n\t\t}\n\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements)\n\tlet d;\n\tif (isDecimal) {\n\t\td = DECIMAL_POWERS[e];\n\t} else {\n\t\td = BINARY_POWERS[e];\n\t}\n\t\n\tval = num / d;\n\n\tif (bits) {\n\t\tval = val * 8;\n\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval = val / ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Setting optional precision\n\tif (precision > 0) {\n\t\tresult[0] = result[0].toPrecision(precision);\n\n\t\tif (result[0].includes(E) && e < 8) {\n\t\t\te++;\n\t\t\t// Recalculate with new exponent (e is always <= 8)\n\t\t\tif (isDecimal) {\n\t\t\t\td = DECIMAL_POWERS[e];\n\t\t\t} else {\n\t\t\t\td = BINARY_POWERS[e];\n\t\t\t}\n\t\t\tval = num / d;\n\t\t\tresult[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision);\n\t\t}\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Optimized locale/separator handling\n\tif (locale === true) {\n\t\tresult[0] = result[0].toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult[0] = result[0].toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult[0] = result[0].toString().replace(PERIOD, separator);\n\t}\n\n\tif (pad && round > 0) {\n\t\tconst resultStr = result[0].toString(),\n\t\t\tx = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD),\n\t\t\ttmp = resultStr.split(x),\n\t\t\ts = tmp[1] || EMPTY,\n\t\t\tl = s.length,\n\t\t\tn = round - l;\n\n\t\tresult[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\t\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\t\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","filesize","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","isDecimal","ceil","actualStandard","e","num","Number","result","val","u","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","floor","d","p","pow","includes","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC },\n\t[IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC },\n\t[JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC }\n};\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst config = getBaseConfiguration(standard, base);\n\tconst { isDecimal, ceil, actualStandard } = config;\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult.val;\n\te = valueResult.e;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration(standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn { isDecimal: false, ceil: 1024, actualStandard: IEC };\n\t}\n\n\t// Default\n\treturn { isDecimal: true, ceil: 1000, actualStandard: JEDEC };\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue(num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet val = num / d;\n\n\tif (bits) {\n\t\tval *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn { val, e };\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision);\n\t}\n\n\treturn { value: result, e };\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","filesize","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","e","num","Number","result","val","u","config","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","handleZeroValue","floor","valueResult","calculateOptimizedValue","p","pow","precisionResult","applyPrecisionHandling","value","symbolTable","applyNumberFormatting","unit","join","toPrecision","includes","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":"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"} \ No newline at end of file diff --git a/dist/filesize.umd.js b/dist/filesize.umd.js index fa6522d..e1f9020 100644 --- a/dist/filesize.umd.js +++ b/dist/filesize.umd.js @@ -3,7 +3,7 @@ * * @copyright 2025 Jason Mulligan * @license BSD-3-Clause - * @version 11.0.10 + * @version 11.0.11 */ (function(g,f){typeof exports==='object'&&typeof module!=='undefined'?f(exports):typeof define==='function'&&define.amd?define(['exports'],f):(g=typeof globalThis!=='undefined'?globalThis:g||self,f(g.filesize={}));})(this,(function(exports){'use strict';// Error Messages const INVALID_NUMBER = "Invalid number"; @@ -85,7 +85,14 @@ const DECIMAL_POWERS = [ // Pre-computed log values for faster exponent calculation const LOG_2_1024 = Math.log(1024); -const LOG_10_1000 = Math.log(1000);/** +const LOG_10_1000 = Math.log(1000);// Cached configuration lookup for better performance +const STANDARD_CONFIGS = { + [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, + [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, + [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } +}; + +/** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert * @param {Object} [options={}] - Configuration options for formatting @@ -136,29 +143,9 @@ function filesize (arg, { val = 0, u = EMPTY; - // Optimized base & standard synchronization with early returns - let isDecimal, ceil, actualStandard; - if (standard === SI) { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } else if (standard === IEC) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else if (standard === JEDEC) { - isDecimal = false; // JEDEC uses binary (1024) by default - ceil = 1024; - actualStandard = JEDEC; - } else if (base === 2) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } + // Optimized base & standard configuration lookup + const config = getBaseConfiguration(standard, base); + const { isDecimal, ceil, actualStandard } = config; const full = fullform === true, neg = num < 0, @@ -179,38 +166,12 @@ function filesize (arg, { // Fast path for zero if (num === 0) { - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Skip most processing for zero case - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); + return handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer); } // Optimized exponent calculation using pre-computed log values if (e === -1 || isNaN(e)) { - if (isDecimal) { - e = Math.floor(Math.log(num) / LOG_10_1000); - } else { - e = Math.floor(Math.log(num) / LOG_2_1024); - } - + e = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024); if (e < 0) { e = 0; } @@ -228,24 +189,10 @@ function filesize (arg, { return e; } - // Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements) - let d; - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - - val = num / d; - - if (bits) { - val = val * 8; - - if (val >= ceil && e < 8) { - val = val / ceil; - e++; - } - } + // Calculate value with optimized lookup and bits handling + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult.val; + e = valueResult.e; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -256,21 +203,11 @@ function filesize (arg, { e++; } - // Setting optional precision + // Apply precision handling if (precision > 0) { - result[0] = result[0].toPrecision(precision); - - if (result[0].includes(E) && e < 8) { - e++; - // Recalculate with new exponent (e is always <= 8) - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - val = num / d; - result[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision); - } + const precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round); + result[0] = precisionResult.value; + e = precisionResult.e; } // Cache symbol lookup @@ -287,25 +224,8 @@ function filesize (arg, { result[1] = symbols[result[1]]; } - // Optimized locale/separator handling - if (locale === true) { - result[0] = result[0].toLocaleString(); - } else if (locale.length > 0) { - result[0] = result[0].toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result[0] = result[0].toString().replace(PERIOD, separator); - } - - if (pad && round > 0) { - const resultStr = result[0].toString(), - x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD), - tmp = resultStr.split(x), - s = tmp[1] || EMPTY, - l = s.length, - n = round - l; - - result[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } + // Apply locale, separator, and padding formatting + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); if (full) { result[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); @@ -315,7 +235,7 @@ function filesize (arg, { if (output === ARRAY) { return result; } - + if (output === OBJECT) { return { value: result[0], @@ -324,10 +244,160 @@ function filesize (arg, { unit: u }; } - + return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration(standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return { isDecimal: false, ceil: 1024, actualStandard: IEC }; + } + + // Default + return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let val = num / d; + + if (bits) { + val *= 8; + // Handle auto-increment for bits + if (val >= ceil && e < 8) { + val /= ceil; + e++; + } + } + + return { val, e }; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); + } + + return { value: result, e }; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} + /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -390,4 +460,4 @@ function partial ({ roundingMethod, precision }); -}exports.filesize=filesize;exports.partial=partial;})); \ No newline at end of file +}exports.applyNumberFormatting=applyNumberFormatting;exports.applyPrecisionHandling=applyPrecisionHandling;exports.calculateOptimizedValue=calculateOptimizedValue;exports.filesize=filesize;exports.getBaseConfiguration=getBaseConfiguration;exports.handleZeroValue=handleZeroValue;exports.partial=partial;})); \ No newline at end of file diff --git a/dist/filesize.umd.min.js b/dist/filesize.umd.min.js index 4edda17..ee1a554 100644 --- a/dist/filesize.umd.min.js +++ b/dist/filesize.umd.min.js @@ -1,5 +1,5 @@ /*! 2025 Jason Mulligan - @version 11.0.10 + @version 11.0.11 */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",o="bits",n="byte",r="bytes",l="array",s="object",a="string",b="exponent",f="round",p="",u={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},c=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],d=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),g=Math.log(1e3);function y(t,{bits:y=!1,pad:h=!1,base:B=-1,round:M=2,locale:x="",localeOptions:T={},separator:j="",spacer:E=" ",symbols:P={},standard:w="",output:N=a,fullform:$=!1,fullforms:k=[],exponent:v=-1,roundingMethod:z=f,precision:G=0}={}){let K,S,Y,Z=v,O=Number(t),I=[],L=0,D=p;"si"===w?(K=!0,S=1e3,Y=i):w===e?(K=!1,S=1024,Y=e):w===i?(K=!1,S=1024,Y=i):2===B?(K=!1,S=1024,Y=e):(K=!0,S=1e3,Y=i);const q=!0===$,A=O<0,C=Math[z];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(O=-O),0===O)return I[0]=G>0?(0).toPrecision(G):0,D=I[1]=u.symbol[Y][y?o:r][0],N===b?0:(P[I[1]]&&(I[1]=P[I[1]]),q&&(I[1]=k[0]||u.fullform[Y][0]+(y?"bit":n)),N===l?I:N===s?{value:I[0],symbol:I[1],exponent:0,unit:D}:I.join(E));if((-1===Z||isNaN(Z))&&(Z=K?Math.floor(Math.log(O)/g):Math.floor(Math.log(O)/m),Z<0&&(Z=0)),Z>8&&(G>0&&(G+=8-Z),Z=8),N===b)return Z;let F;F=K?d[Z]:c[Z],L=O/F,y&&(L*=8,L>=S&&Z<8&&(L/=S,Z++));const H=Z>0&&M>0?Math.pow(10,M):1;I[0]=1===H?C(L):C(L*H)/H,I[0]===S&&Z<8&&-1===v&&(I[0]=1,Z++),G>0&&(I[0]=I[0].toPrecision(G),I[0].includes("e")&&Z<8&&(Z++,F=K?d[Z]:c[Z],L=O/F,I[0]=(1===H?C(L):C(L*H)/H).toPrecision(G)));const J=u.symbol[Y][y?o:r];if(D=I[1]=K&&1===Z?y?"kbit":"kB":J[Z],A&&(I[0]=-I[0]),P[I[1]]&&(I[1]=P[I[1]]),!0===x?I[0]=I[0].toLocaleString():x.length>0?I[0]=I[0].toLocaleString(x,T):j.length>0&&(I[0]=I[0].toString().replace(".",j)),h&&M>0){const t=I[0].toString(),e=j||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),o=i[1]||p,n=o.length,r=M-n;I[0]=`${i[0]}${e}${o.padEnd(n+r,"0")}`}return q&&(I[1]=k[Z]||u.fullform[Y][Z]+(y?"bit":n)+(1===I[0]?p:"s")),N===l?I:N===s?{value:I[0],symbol:I[1],exponent:Z,unit:D}:" "===E?`${I[0]} ${I[1]}`:I.join(E)}t.filesize=y,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:r={},separator:l="",spacer:s=" ",symbols:b={},standard:p="",output:u=a,fullform:c=!1,fullforms:d=[],exponent:m=-1,roundingMethod:g=f,precision:h=0}={}){return a=>y(a,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:r,separator:l,spacer:s,symbols:b,standard:p,output:u,fullform:c,fullforms:d,exponent:m,roundingMethod:g,precision:h})}});//# sourceMappingURL=filesize.umd.min.js.map +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",o="si",n="bits",a="byte",l="bytes",r="array",s="object",c="string",u="exponent",b="round",d="",f={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],m=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],g=Math.log(1024),y=Math.log(1e3),h={[o]:{isDecimal:!0,ceil:1e3,actualStandard:i},[e]:{isDecimal:!1,ceil:1024,actualStandard:e},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function B(t,{bits:e=!1,pad:i=!1,base:o=-1,round:p=2,locale:m="",localeOptions:h={},separator:B="",spacer:T=" ",symbols:j={},standard:D="",output:E=c,fullform:w=!1,fullforms:N=[],exponent:z=-1,roundingMethod:Z=b,precision:$=0}={}){let k=z,G=Number(t),K=[],O=0,Y=d;const I=M(D,o),{isDecimal:L,ceil:V,actualStandard:C}=I,F=!0===w,H=G<0,q=Math[Z];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof q)throw new TypeError("Invalid rounding method");if(H&&(G=-G),0===G)return x($,C,e,j,F,N,E,T);if((-1===k||isNaN(k))&&(k=L?Math.floor(Math.log(G)/y):Math.floor(Math.log(G)/g),k<0&&(k=0)),k>8&&($>0&&($+=8-k),k=8),E===u)return k;const A=v(G,k,L,e,V);O=A.val,k=A.e;const J=k>0&&p>0?Math.pow(10,p):1;if(K[0]=1===J?q(O):q(O*J)/J,K[0]===V&&k<8&&-1===z&&(K[0]=1,k++),$>0){const t=S(K[0],$,k,G,L,e,V,q,p);K[0]=t.value,k=t.e}const Q=f.symbol[C][e?n:l];return Y=K[1]=L&&1===k?e?"kbit":"kB":Q[k],H&&(K[0]=-K[0]),j[K[1]]&&(K[1]=j[K[1]]),K[0]=P(K[0],m,h,B,i,p),F&&(K[1]=N[k]||f.fullform[C][k]+(e?"bit":a)+(1===K[0]?d:"s")),E===r?K:E===s?{value:K[0],symbol:K[1],exponent:k,unit:Y}:" "===T?`${K[0]} ${K[1]}`:K.join(T)}function M(t,o){return h[t]?h[t]:2===o?{isDecimal:!1,ceil:1024,actualStandard:e}:{isDecimal:!0,ceil:1e3,actualStandard:i}}function x(t,e,i,o,c,b,d,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=f.symbol[e][i?n:l][0];return d===u?0:(o[m[1]]&&(m[1]=o[m[1]]),c&&(m[1]=b[0]||f.fullform[e][0]+(i?"bit":a)),d===r?m:d===s?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(p))}function v(t,e,i,o,n){let a=t/(i?m[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{val:a,e:e}}function S(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){const t=v(o,++i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t.val):r(t.val*u)/u).toPrecision(e)}return{value:c,e:i}}function P(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||d,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}t.applyNumberFormatting=P,t.applyPrecisionHandling=S,t.calculateOptimizedValue=v,t.filesize=B,t.getBaseConfiguration=M,t.handleZeroValue=x,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:s={},standard:u="",output:d=c,fullform:f=!1,fullforms:p=[],exponent:m=-1,roundingMethod:g=b,precision:y=0}={}){return c=>B(c,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:s,standard:u,output:d,fullform:f,fullforms:p,exponent:m,roundingMethod:g,precision:y})}});//# sourceMappingURL=filesize.umd.min.js.map diff --git a/dist/filesize.umd.min.js.map b/dist/filesize.umd.min.js.map index 3cd0679..2a79544 100644 --- a/dist/filesize.umd.min.js.map +++ b/dist/filesize.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard synchronization with early returns\n\tlet isDecimal, ceil, actualStandard;\n\tif (standard === SI) {\n\t\tisDecimal = true;\n\t\tceil = 1000;\n\t\tactualStandard = JEDEC;\n\t} else if (standard === IEC) {\n\t\tisDecimal = false;\n\t\tceil = 1024;\n\t\tactualStandard = IEC;\n\t} else if (standard === JEDEC) {\n\t\tisDecimal = false; // JEDEC uses binary (1024) by default\n\t\tceil = 1024;\n\t\tactualStandard = JEDEC;\n\t} else if (base === 2) {\n\t\tisDecimal = false;\n\t\tceil = 1024;\n\t\tactualStandard = IEC;\n\t} else {\n\t\tisDecimal = true;\n\t\tceil = 1000;\n\t\tactualStandard = JEDEC;\n\t}\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\t\tu = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\t\t\n\t\tif (output === EXPONENT) {\n\t\t\treturn 0;\n\t\t}\n\t\t\n\t\t// Skip most processing for zero case\n\t\tif (symbols[result[1]]) {\n\t\t\tresult[1] = symbols[result[1]];\n\t\t}\n\t\t\n\t\tif (full) {\n\t\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t\t}\n\t\t\n\t\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: 0,\n\t\t\tunit: u\n\t\t} : result.join(spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\tif (isDecimal) {\n\t\t\te = Math.floor(Math.log(num) / LOG_10_1000);\n\t\t} else {\n\t\t\te = Math.floor(Math.log(num) / LOG_2_1024);\n\t\t}\n\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements)\n\tlet d;\n\tif (isDecimal) {\n\t\td = DECIMAL_POWERS[e];\n\t} else {\n\t\td = BINARY_POWERS[e];\n\t}\n\t\n\tval = num / d;\n\n\tif (bits) {\n\t\tval = val * 8;\n\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval = val / ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Setting optional precision\n\tif (precision > 0) {\n\t\tresult[0] = result[0].toPrecision(precision);\n\n\t\tif (result[0].includes(E) && e < 8) {\n\t\t\te++;\n\t\t\t// Recalculate with new exponent (e is always <= 8)\n\t\t\tif (isDecimal) {\n\t\t\t\td = DECIMAL_POWERS[e];\n\t\t\t} else {\n\t\t\t\td = BINARY_POWERS[e];\n\t\t\t}\n\t\t\tval = num / d;\n\t\t\tresult[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision);\n\t\t}\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Optimized locale/separator handling\n\tif (locale === true) {\n\t\tresult[0] = result[0].toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult[0] = result[0].toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult[0] = result[0].toString().replace(PERIOD, separator);\n\t}\n\n\tif (pad && round > 0) {\n\t\tconst resultStr = result[0].toString(),\n\t\t\tx = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD),\n\t\t\ttmp = resultStr.split(x),\n\t\t\ts = tmp[1] || EMPTY,\n\t\t\tl = s.length,\n\t\t\tn = round - l;\n\n\t\tresult[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\t\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\t\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","isDecimal","ceil","actualStandard","e","num","Number","result","val","u","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","floor","d","p","pow","includes","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC },\n\t[IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC },\n\t[JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC }\n};\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst config = getBaseConfiguration(standard, base);\n\tconst { isDecimal, ceil, actualStandard } = config;\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult.val;\n\te = valueResult.e;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration(standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn { isDecimal: false, ceil: 1024, actualStandard: IEC };\n\t}\n\n\t// Default\n\treturn { isDecimal: true, ceil: 1000, actualStandard: JEDEC };\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue(num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet val = num / d;\n\n\tif (bits) {\n\t\tval *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn { val, e };\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision);\n\t}\n\n\treturn { value: result, e };\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","e","num","Number","result","val","u","config","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","handleZeroValue","floor","valueResult","calculateOptimizedValue","p","pow","precisionResult","applyPrecisionHandling","value","symbolTable","applyNumberFormatting","unit","join","toPrecision","includes","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":";;;;CAAA,SAAAA,EAAAC,GAAA,iBAAAC,SAAA,oBAAAC,OAAAF,EAAAC,SAAA,mBAAAE,QAAAA,OAAAC,IAAAD,OAAA,CAAA,WAAAH,GAAAA,GAAAD,EAAA,oBAAAM,WAAAA,WAAAN,GAAAO,MAAAC,SAAA,CAAA,EAAA,CAAA,CAAAC,KAAA,SAAAP,GAAA,aACO,MAIMQ,EAAM,MACNC,EAAQ,QACRC,EAAK,KAILC,EAAO,OACPC,EAAO,OACPC,EAAQ,QAKRC,EAAQ,QAERC,EAAS,SACTC,EAAS,SAGTC,EAAW,WACXC,EAAQ,QAIRC,EAAQ,GAORC,EAAU,CACtBC,OAAQ,CACPC,IAAK,CACJC,KAAM,CAAC,MAAO,QAAS,QAAS,QAAS,QAAS,QAAS,QAAS,QAAS,SAC7EC,MAAO,CAAC,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,QAE/DC,MAAO,CACNF,KAAM,CAAC,MAAO,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,QACtEC,MAAO,CAAC,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,QAGzDE,SAAU,CACTJ,IAAK,CAAC,GAAI,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,QAClEG,MAAO,CAAC,GAAI,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,MAAO,QAAS,WAKzDE,EAAgB,CAC5B,EACA,KACA,QACA,WACA,cACA,gBACA,mBACA,oBACA,qBAGYC,EAAiB,CAC7B,EACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,MAIYC,EAAaC,KAAKC,IAAI,MACtBC,EAAcF,KAAKC,IAAI,KChD9BE,EAAmB,CACxBvB,CAACA,GAAK,CAAEwB,WAAW,EAAMC,KAAM,IAAMC,eAAgB3B,GACrDD,CAACA,GAAM,CAAE0B,WAAW,EAAOC,KAAM,KAAMC,eAAgB5B,GACvDC,CAACA,GAAQ,CAAEyB,WAAW,EAAOC,KAAM,KAAMC,eAAgB3B,IA8BnD,SAASH,EAAU+B,GAAKd,KAC9BA,GAAO,EAAKe,IACZA,GAAM,EAAKC,KACXA,GAAO,EAAEC,MACTA,EAAQ,EAACC,OACTA,EAAStB,GAAKuB,cACdA,EAAgB,CAAA,EAAEC,UAClBA,EAAYxB,GAAKyB,OACjBA,EDzCoB,ICyCNC,QACdA,EAAU,CAAA,EAAEC,SACZA,EAAW3B,GAAK4B,OAChBA,EAAS/B,EAAMU,SACfA,GAAW,EAAKsB,UAChBA,EAAY,GAAEC,SACdA,GAAW,EAAEC,eACbA,EAAiBhC,EAAKiC,UACtBA,EAAY,GACT,IACH,IAAIC,EAAIH,EACPI,EAAMC,OAAOjB,GACbkB,EAAS,GACTC,EAAM,EACNC,EAAItC,EAGL,MAAMuC,EAASC,EAAqBb,EAAUP,IACxCL,UAAEA,EAASC,KAAEA,EAAIC,eAAEA,GAAmBsB,EAEtCE,GAAoB,IAAblC,EACZmC,EAAMR,EAAM,EACZS,EAAehC,KAAKoB,GAErB,GAAmB,iBAARb,GAAoB0B,MAAM1B,GACpC,MAAM,IAAI2B,UDjGkB,kBCoG7B,GDlFuB,mBCkFZF,EACV,MAAM,IAAIE,UDpGiB,2BC6G5B,GALIH,IACHR,GAAOA,GAII,IAARA,EACH,OAAOY,EAAgBd,EAAWf,EAAgBb,EAAMsB,EAASe,EAAMZ,EAAWD,EAAQH,GAmB3F,KAfU,IAANQ,GAAYW,MAAMX,MACrBA,EAAIlB,EAAYJ,KAAKoC,MAAMpC,KAAKC,IAAIsB,GAAOrB,GAAeF,KAAKoC,MAAMpC,KAAKC,IAAIsB,GAAOxB,GACjFuB,EAAI,IACPA,EAAI,IAKFA,EAAI,IACHD,EAAY,IACfA,GAAa,EAAIC,GAElBA,EAAI,GAGDL,IAAW9B,EACd,OAAOmC,EAIR,MAAMe,EAAcC,EAAwBf,EAAKD,EAAGlB,EAAWX,EAAMY,GACrEqB,EAAMW,EAAYX,IAClBJ,EAAIe,EAAYf,EAGhB,MAAMiB,EAAIjB,EAAI,GAAKZ,EAAQ,EAAIV,KAAKwC,IAAI,GAAI9B,GAAS,EASrD,GARAe,EAAO,GAAW,IAANc,EAAUP,EAAaN,GAAOM,EAAaN,EAAMa,GAAKA,EAE9Dd,EAAO,KAAOpB,GAAQiB,EAAI,QAAKH,IAClCM,EAAO,GAAK,EACZH,KAIGD,EAAY,EAAG,CAClB,MAAMoB,EAAkBC,EAAuBjB,EAAO,GAAIJ,EAAWC,EAAGC,EAAKnB,EAAWX,EAAMY,EAAM2B,EAActB,GAClHe,EAAO,GAAKgB,EAAgBE,MAC5BrB,EAAImB,EAAgBnB,CACrB,CAGA,MAAMsB,EAActD,EAAQC,OAAOe,GAAgBb,EAAOZ,EAAOE,GAqBjE,OApBA4C,EAAIF,EAAO,GAAMrB,GAAmB,IAANkB,EAAY7B,EDhJpB,OACC,KC+IgDmD,EAAYtB,GAG/ES,IACHN,EAAO,IAAMA,EAAO,IAIjBV,EAAQU,EAAO,MAClBA,EAAO,GAAKV,EAAQU,EAAO,KAI5BA,EAAO,GAAKoB,EAAsBpB,EAAO,GAAId,EAAQC,EAAeC,EAAWL,EAAKE,GAEhFoB,IACHL,EAAO,GAAKP,EAAUI,IAAMhC,EAAQM,SAASU,GAAgBgB,IAAM7B,EDpKlD,MCoK+DX,IAAuB,IAAd2C,EAAO,GAAWpC,ED/I5F,MCmJZ4B,IAAWjC,EACPyC,EAGJR,IAAWhC,EACP,CACN0D,MAAOlB,EAAO,GACdlC,OAAQkC,EAAO,GACfN,SAAUG,EACVwB,KAAMnB,GD3JY,MC+Jbb,EAAmB,GAAGW,EAAO,MAAMA,EAAO,KAAOA,EAAOsB,KAAKjC,EACrE,CAQO,SAASe,EAAqBb,EAAUP,GAE9C,OAAIN,EAAiBa,GACbb,EAAiBa,GAIZ,IAATP,EACI,CAAEL,WAAW,EAAOC,KAAM,KAAMC,eAAgB5B,GAIjD,CAAE0B,WAAW,EAAMC,KAAM,IAAMC,eAAgB3B,EACvD,CAcO,SAASwD,EAAgBd,EAAWf,EAAgBb,EAAMsB,EAASe,EAAMZ,EAAWD,EAAQH,GAClG,MAAMW,EAAS,GACfA,EAAO,GAAKJ,EAAY,GAAI,GAAI2B,YAAY3B,GAAa,EACzD,MAAMM,EAAIF,EAAO,GAAKnC,EAAQC,OAAOe,GAAgBb,EAAOZ,EAAOE,GAAO,GAE1E,OAAIkC,IAAW9B,EACP,GAIJ4B,EAAQU,EAAO,MAClBA,EAAO,GAAKV,EAAQU,EAAO,KAIxBK,IACHL,EAAO,GAAKP,EAAU,IAAM5B,EAAQM,SAASU,GAAgB,IAAMb,EDzOlD,MCyO+DX,IAI1EmC,IAAWjC,EAAQyC,EAASR,IAAWhC,EAAS,CACtD0D,MAAOlB,EAAO,GACdlC,OAAQkC,EAAO,GACfN,SAAU,EACV2B,KAAMnB,GACHF,EAAOsB,KAAKjC,GACjB,CAWO,SAASwB,EAAwBf,EAAKD,EAAGlB,EAAWX,EAAMY,GAEhE,IAAIqB,EAAMH,GADAnB,EAAYN,EAAewB,GAAKzB,EAAcyB,IAYxD,OATI7B,IACHiC,GAAO,EAEHA,GAAOrB,GAAQiB,EAAI,IACtBI,GAAOrB,EACPiB,MAIK,CAAEI,MAAKJ,IACf,CAeO,SAASoB,EAAuBC,EAAOtB,EAAWC,EAAGC,EAAKnB,EAAWX,EAAMY,EAAM2B,EAActB,GACrG,IAAIe,EAASkB,EAAMK,YAAY3B,GAG/B,GAAII,EAAOwB,SD7QK,MC6QU3B,EAAI,EAAG,CAEhC,MAAMe,EAAcC,EAAwBf,IAD5CD,EACoDlB,EAAWX,EAAMY,GAC/DkC,EAAI7B,EAAQ,EAAIV,KAAKwC,IAAI,GAAI9B,GAAS,EAC5Ce,GAAgB,IAANc,EAAUP,EAAaK,EAAYX,KAAOM,EAAaK,EAAYX,IAAMa,GAAKA,GAAGS,YAAY3B,EACxG,CAEA,MAAO,CAAEsB,MAAOlB,EAAQH,IACzB,CAYO,SAASuB,EAAsBF,EAAOhC,EAAQC,EAAeC,EAAWL,EAAKE,GACnF,IAAIe,EAASkB,EAYb,IATe,IAAXhC,EACHc,EAASA,EAAOyB,iBACNvC,EAAOwC,OAAS,EAC1B1B,EAASA,EAAOyB,eAAevC,EAAQC,GAC7BC,EAAUsC,OAAS,IAC7B1B,EAASA,EAAO2B,WAAWC,QDxSP,ICwSuBxC,IAIxCL,GAAOE,EAAQ,EAAG,CACrB,MAAM4C,EAAY7B,EAAO2B,WACnBG,EAAI1C,IAAeyC,EAAUE,MAAM,UAAY,IAAIC,OD9SrC,IC+SdC,EAAMJ,EAAUK,MAAMJ,GACtBK,EAAIF,EAAI,IAAMrE,EACdwE,EAAID,EAAET,OACNW,EAAIpD,EAAQmD,EAElBpC,EAAS,GAAGiC,EAAI,KAAKH,IAAIK,EAAEG,OAAOF,EAAIC,EDjTpB,MCkTnB,CAEA,OAAOrC,CACR,CAgEAvD,EAAA2E,sBAAAA,EAAA3E,EAAAwE,uBAAAA,EAAAxE,EAAAoE,wBAAAA,EAAApE,EAAAM,SAAAA,EAAAN,EAAA2D,qBAAAA,EAAA3D,EAAAiE,gBAAAA,EAAAjE,EAAA8F,QApCO,UAAkBvE,KACxBA,GAAO,EAAKe,IACZA,GAAM,EAAKC,KACXA,GAAO,EAAEC,MACTA,EAAQ,EAACC,OACTA,EAAStB,GAAKuB,cACdA,EAAgB,CAAA,EAAEC,UAClBA,EAAYxB,GAAKyB,OACjBA,ED1VoB,IC0VNC,QACdA,EAAU,CAAA,EAAEC,SACZA,EAAW3B,GAAK4B,OAChBA,EAAS/B,EAAMU,SACfA,GAAW,EAAKsB,UAChBA,EAAY,GAAEC,SACdA,GAAW,EAAEC,eACbA,EAAiBhC,EAAKiC,UACtBA,EAAY,GACT,IACH,OAAOd,GAAO/B,EAAS+B,EAAK,CAC3Bd,OACAe,MACAC,OACAC,QACAC,SACAC,gBACAC,YACAC,SACAC,UACAC,WACAC,SACArB,WACAsB,YACAC,WACAC,iBACAC,aAEF,CAAA"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c88b901..f0319fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "filesize", - "version": "11.0.10", + "version": "11.0.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "filesize", - "version": "11.0.10", + "version": "11.0.11", "license": "BSD-3-Clause", "devDependencies": { "@rollup/plugin-terser": "^0.4.4", diff --git a/package.json b/package.json index 101c116..beb20b8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "filesize", "description": "JavaScript library to generate a human readable String describing the file size", - "version": "11.0.10", + "version": "11.0.11", "homepage": "https://filesizejs.com", "author": "Jason Mulligan ", "repository": { diff --git a/src/filesize.js b/src/filesize.js index 5d63330..d4f1cb1 100644 --- a/src/filesize.js +++ b/src/filesize.js @@ -29,6 +29,13 @@ import { ZERO } from "./constants.js"; +// Cached configuration lookup for better performance +const STANDARD_CONFIGS = { + [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, + [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, + [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } +}; + /** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert @@ -80,29 +87,9 @@ export function filesize (arg, { val = 0, u = EMPTY; - // Optimized base & standard synchronization with early returns - let isDecimal, ceil, actualStandard; - if (standard === SI) { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } else if (standard === IEC) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else if (standard === JEDEC) { - isDecimal = false; // JEDEC uses binary (1024) by default - ceil = 1024; - actualStandard = JEDEC; - } else if (base === 2) { - isDecimal = false; - ceil = 1024; - actualStandard = IEC; - } else { - isDecimal = true; - ceil = 1000; - actualStandard = JEDEC; - } + // Optimized base & standard configuration lookup + const config = getBaseConfiguration(standard, base); + const { isDecimal, ceil, actualStandard } = config; const full = fullform === true, neg = num < 0, @@ -123,38 +110,12 @@ export function filesize (arg, { // Fast path for zero if (num === 0) { - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Skip most processing for zero case - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); + return handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer); } // Optimized exponent calculation using pre-computed log values if (e === -1 || isNaN(e)) { - if (isDecimal) { - e = Math.floor(Math.log(num) / LOG_10_1000); - } else { - e = Math.floor(Math.log(num) / LOG_2_1024); - } - + e = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024); if (e < 0) { e = 0; } @@ -172,24 +133,10 @@ export function filesize (arg, { return e; } - // Use pre-computed lookup tables (e is always <= 8, arrays have 9 elements) - let d; - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - - val = num / d; - - if (bits) { - val = val * 8; - - if (val >= ceil && e < 8) { - val = val / ceil; - e++; - } - } + // Calculate value with optimized lookup and bits handling + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult.val; + e = valueResult.e; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -200,21 +147,11 @@ export function filesize (arg, { e++; } - // Setting optional precision + // Apply precision handling if (precision > 0) { - result[0] = result[0].toPrecision(precision); - - if (result[0].includes(E) && e < 8) { - e++; - // Recalculate with new exponent (e is always <= 8) - if (isDecimal) { - d = DECIMAL_POWERS[e]; - } else { - d = BINARY_POWERS[e]; - } - val = num / d; - result[0] = (p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p).toPrecision(precision); - } + const precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round); + result[0] = precisionResult.value; + e = precisionResult.e; } // Cache symbol lookup @@ -231,25 +168,8 @@ export function filesize (arg, { result[1] = symbols[result[1]]; } - // Optimized locale/separator handling - if (locale === true) { - result[0] = result[0].toLocaleString(); - } else if (locale.length > 0) { - result[0] = result[0].toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result[0] = result[0].toString().replace(PERIOD, separator); - } - - if (pad && round > 0) { - const resultStr = result[0].toString(), - x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD), - tmp = resultStr.split(x), - s = tmp[1] || EMPTY, - l = s.length, - n = round - l; - - result[0] = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } + // Apply locale, separator, and padding formatting + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); if (full) { result[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); @@ -259,7 +179,7 @@ export function filesize (arg, { if (output === ARRAY) { return result; } - + if (output === OBJECT) { return { value: result[0], @@ -268,10 +188,160 @@ export function filesize (arg, { unit: u }; } - + return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +export function getBaseConfiguration(standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return { isDecimal: false, ceil: 1024, actualStandard: IEC }; + } + + // Default + return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +export function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +export function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let val = num / d; + + if (bits) { + val *= 8; + // Handle auto-increment for bits + if (val >= ceil && e < 8) { + val /= ceil; + e++; + } + } + + return { val, e }; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +export function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); + } + + return { value: result, e }; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +export function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} + /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function diff --git a/tests/unit/filesize-helpers.test.js b/tests/unit/filesize-helpers.test.js new file mode 100644 index 0000000..4e09859 --- /dev/null +++ b/tests/unit/filesize-helpers.test.js @@ -0,0 +1,200 @@ +/** + * Unit tests for exported helper functions + * Tests the individual helper functions for better test coverage + */ + +import assert from 'assert'; +import { + getBaseConfiguration, + handleZeroValue, + calculateOptimizedValue, + applyPrecisionHandling, + applyNumberFormatting +} from '../../src/filesize.js'; + +describe('Helper Functions', () => { + describe('getBaseConfiguration', () => { + it('should return SI configuration', () => { + const config = getBaseConfiguration('si', -1); + assert.deepStrictEqual(config, { + isDecimal: true, + ceil: 1000, + actualStandard: 'jedec' + }); + }); + + it('should return IEC configuration', () => { + const config = getBaseConfiguration('iec', -1); + assert.deepStrictEqual(config, { + isDecimal: false, + ceil: 1024, + actualStandard: 'iec' + }); + }); + + it('should return JEDEC configuration', () => { + const config = getBaseConfiguration('jedec', -1); + assert.deepStrictEqual(config, { + isDecimal: false, + ceil: 1024, + actualStandard: 'jedec' + }); + }); + + it('should handle base=2 override', () => { + const config = getBaseConfiguration('', 2); + assert.deepStrictEqual(config, { + isDecimal: false, + ceil: 1024, + actualStandard: 'iec' + }); + }); + + it('should return default configuration', () => { + const config = getBaseConfiguration('', -1); + assert.deepStrictEqual(config, { + isDecimal: true, + ceil: 1000, + actualStandard: 'jedec' + }); + }); + }); + + describe('handleZeroValue', () => { + it('should handle zero with string output', () => { + const result = handleZeroValue(0, 'jedec', false, {}, false, [], 'string', ' '); + assert.strictEqual(result, '0 B'); + }); + + it('should handle zero with array output', () => { + const result = handleZeroValue(0, 'jedec', false, {}, false, [], 'array', ' '); + assert.deepStrictEqual(result, [0, 'B']); + }); + + it('should handle zero with object output', () => { + const result = handleZeroValue(0, 'jedec', false, {}, false, [], 'object', ' '); + assert.deepStrictEqual(result, { + value: 0, + symbol: 'B', + exponent: 0, + unit: 'B' + }); + }); + + it('should handle zero with exponent output', () => { + const result = handleZeroValue(0, 'jedec', false, {}, false, [], 'exponent', ' '); + assert.strictEqual(result, 0); + }); + + it('should handle zero with bits', () => { + const result = handleZeroValue(0, 'jedec', true, {}, false, [], 'string', ' '); + assert.strictEqual(result, '0 bit'); + }); + + it('should handle zero with custom symbols', () => { + const result = handleZeroValue(0, 'jedec', false, { 'B': 'Bytes' }, false, [], 'string', ' '); + assert.strictEqual(result, '0 Bytes'); + }); + + it('should handle zero with fullform', () => { + const result = handleZeroValue(0, 'jedec', false, {}, true, [], 'string', ' '); + assert.strictEqual(result, '0 byte'); + }); + + it('should handle zero with precision', () => { + const result = handleZeroValue(2, 'jedec', false, {}, false, [], 'string', ' '); + assert.strictEqual(result, '0.0 B'); + }); + }); + + describe('calculateOptimizedValue', () => { + it('should calculate value without bits', () => { + const result = calculateOptimizedValue(1024, 1, false, false, 1024); + assert.deepStrictEqual(result, { val: 1, e: 1 }); + }); + + it('should calculate value with bits', () => { + const result = calculateOptimizedValue(1024, 1, false, true, 1024); + assert.deepStrictEqual(result, { val: 8, e: 1 }); + }); + + it('should handle bits auto-increment', () => { + const result = calculateOptimizedValue(128, 0, false, true, 1024); + assert.deepStrictEqual(result, { val: 1, e: 1 }); + }); + + it('should use decimal powers', () => { + const result = calculateOptimizedValue(1000, 1, true, false, 1000); + assert.deepStrictEqual(result, { val: 1, e: 1 }); + }); + + it('should not increment when e >= 8', () => { + // Use a proper YiB value for exponent 8 + const yibValue = Math.pow(1024, 8); // 1 YiB in bytes + const result = calculateOptimizedValue(yibValue, 8, false, true, 1024); + assert.strictEqual(result.e, 8); + assert(result.val >= 8); // Should be 8 bits (1 byte * 8) + }); + }); + + describe('applyPrecisionHandling', () => { + it('should apply precision without scientific notation', () => { + const result = applyPrecisionHandling(1.5, 2, 1, 1024, false, false, 1024, Math.round, 2); + assert.deepStrictEqual(result, { value: '1.5', e: 1 }); + }); + + it('should handle scientific notation with increment', () => { + // Test with a large number that would produce scientific notation + const result = applyPrecisionHandling(1000000000000, 1, 3, 1e15, true, false, 1000, Math.round, 2); + assert(typeof result.value === 'string'); + assert(typeof result.e === 'number'); + }); + + it('should not increment when e >= 8', () => { + const result = applyPrecisionHandling(1.5, 2, 8, 1024, false, false, 1024, Math.round, 2); + assert.deepStrictEqual(result, { value: '1.5', e: 8 }); + }); + }); + + describe('applyNumberFormatting', () => { + it('should format with system locale', () => { + const result = applyNumberFormatting(1.5, true, {}, '', false, 2); + assert(typeof result === 'string'); + }); + + it('should format with specific locale', () => { + const result = applyNumberFormatting(1.5, 'en-US', {}, '', false, 2); + assert(typeof result === 'string'); + }); + + it('should apply custom separator', () => { + const result = applyNumberFormatting(1.5, '', {}, ',', false, 2); + assert.strictEqual(result, '1,5'); + }); + + it('should apply padding', () => { + const result = applyNumberFormatting(1, '', {}, '', true, 2); + assert.strictEqual(result, '1.00'); + }); + + it('should apply padding with custom separator', () => { + const result = applyNumberFormatting(1.5, '', {}, ',', true, 3); + assert.strictEqual(result, '1,500'); + }); + + it('should handle no formatting', () => { + const result = applyNumberFormatting(1.5, '', {}, '', false, 2); + assert.strictEqual(result, 1.5); + }); + + it('should handle padding with existing decimals', () => { + const result = applyNumberFormatting(1.5, '', {}, '', true, 3); + assert.strictEqual(result, '1.500'); + }); + + it('should handle padding with no round', () => { + const result = applyNumberFormatting(1.5, '', {}, '', true, 0); + assert.strictEqual(result, 1.5); + }); + }); +}); From 270530981482490da0cd6496d2f8f31ca4fef01b Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:25:27 -0400 Subject: [PATCH 02/12] Splitting helpers out of filesize --- src/filesize.js | 183 ++-------------------------- src/helpers.js | 176 ++++++++++++++++++++++++++ tests/unit/filesize-helpers.test.js | 16 +-- 3 files changed, 196 insertions(+), 179 deletions(-) create mode 100644 src/helpers.js diff --git a/src/filesize.js b/src/filesize.js index d4f1cb1..c7bdb1a 100644 --- a/src/filesize.js +++ b/src/filesize.js @@ -1,40 +1,32 @@ import { ARRAY, - BINARY_POWERS, BIT, BITS, BYTE, BYTES, - DECIMAL_POWERS, - E, EMPTY, EXPONENT, FUNCTION, - IEC, INVALID_NUMBER, INVALID_ROUND, - JEDEC, - LOG_2_1024, LOG_10_1000, + LOG_2_1024, OBJECT, - PERIOD, ROUND, S, - SI, SI_KBIT, SI_KBYTE, SPACE, STRING, STRINGS, - ZERO } from "./constants.js"; - -// Cached configuration lookup for better performance -const STANDARD_CONFIGS = { - [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, - [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, - [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } -}; +import { + applyNumberFormatting, + applyPrecisionHandling, + calculateOptimizedValue, + getBaseConfiguration, + handleZeroValue +} from "./helpers.js"; /** * Converts a file size in bytes to a human-readable string with appropriate units @@ -88,8 +80,7 @@ export function filesize (arg, { u = EMPTY; // Optimized base & standard configuration lookup - const config = getBaseConfiguration(standard, base); - const { isDecimal, ceil, actualStandard } = config; + const {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, @@ -134,9 +125,9 @@ export function filesize (arg, { } // Calculate value with optimized lookup and bits handling - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - val = valueResult.val; - e = valueResult.e; + const {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult; + e = valueExponent; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -192,156 +183,6 @@ export function filesize (arg, { return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } -/** - * Optimized base configuration lookup - * @param {string} standard - Standard type - * @param {number} base - Base number - * @returns {Object} Configuration object - */ -export function getBaseConfiguration(standard, base) { - // Use cached lookup table for better performance - if (STANDARD_CONFIGS[standard]) { - return STANDARD_CONFIGS[standard]; - } - - // Base override - if (base === 2) { - return { isDecimal: false, ceil: 1024, actualStandard: IEC }; - } - - // Default - return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; -} - -/** - * Optimized zero value handling - * @param {number} precision - Precision value - * @param {string} actualStandard - Standard to use - * @param {boolean} bits - Whether to use bits - * @param {Object} symbols - Custom symbols - * @param {boolean} full - Whether to use full form - * @param {Array} fullforms - Custom full forms - * @param {string} output - Output format - * @param {string} spacer - Spacer character - * @returns {string|Array|Object|number} Formatted result - */ -export function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { - const result = []; - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Apply symbol customization - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply full form - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - // Return in requested format - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); -} - -/** - * Optimized value calculation with bits handling - * @param {number} num - Input number - * @param {number} e - Exponent - * @param {boolean} isDecimal - Whether to use decimal powers - * @param {boolean} bits - Whether to calculate bits - * @param {number} ceil - Ceiling value for auto-increment - * @returns {Object} Object with val and e properties - */ -export function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; - let val = num / d; - - if (bits) { - val *= 8; - // Handle auto-increment for bits - if (val >= ceil && e < 8) { - val /= ceil; - e++; - } - } - - return { val, e }; -} - -/** - * Optimized precision handling with scientific notation correction - * @param {number} value - Current value - * @param {number} precision - Precision to apply - * @param {number} e - Current exponent - * @param {number} num - Original number - * @param {boolean} isDecimal - Whether using decimal base - * @param {boolean} bits - Whether calculating bits - * @param {number} ceil - Ceiling value - * @param {Function} roundingFunc - Rounding function - * @param {number} round - Round value - * @returns {Object} Object with value and e properties - */ -export function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { - let result = value.toPrecision(precision); - - // Handle scientific notation by recalculating with incremented exponent - if (result.includes(E) && e < 8) { - e++; - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); - } - - return { value: result, e }; -} - -/** - * Optimized number formatting with locale, separator, and padding - * @param {number|string} value - Value to format - * @param {string|boolean} locale - Locale setting - * @param {Object} localeOptions - Locale options - * @param {string} separator - Custom separator - * @param {boolean} pad - Whether to pad - * @param {number} round - Round value - * @returns {string|number} Formatted value - */ -export function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { - let result = value; - - // Apply locale formatting - if (locale === true) { - result = result.toLocaleString(); - } else if (locale.length > 0) { - result = result.toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result = result.toString().replace(PERIOD, separator); - } - - // Apply padding - if (pad && round > 0) { - const resultStr = result.toString(); - const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); - const tmp = resultStr.split(x); - const s = tmp[1] || EMPTY; - const l = s.length; - const n = round - l; - - result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } - - return result; -} - /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function diff --git a/src/helpers.js b/src/helpers.js new file mode 100644 index 0000000..cbbe029 --- /dev/null +++ b/src/helpers.js @@ -0,0 +1,176 @@ +import { + ARRAY, + BINARY_POWERS, + BIT, + BITS, + BYTE, + BYTES, + DECIMAL_POWERS, + E, + EMPTY, + EXPONENT, + IEC, + JEDEC, + OBJECT, + PERIOD, + SI, + STRINGS, + ZERO +} from "./constants.js"; + +// Cached configuration lookup for better performance +const STANDARD_CONFIGS = { + [SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC}, + [IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC}, + [JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC} +}; + +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +export function getBaseConfiguration (standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return {isDecimal: false, ceil: 1024, actualStandard: IEC}; + } + + // Default + return {isDecimal: true, ceil: 1000, actualStandard: JEDEC}; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +export function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +export function calculateOptimizedValue (num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let result = num / d; + + if (bits) { + result *= 8; + // Handle auto-increment for bits + if (result >= ceil && e < 8) { + result /= ceil; + e++; + } + } + + return {result, e}; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +export function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision); + } + + return {value: result, e}; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +export function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} diff --git a/tests/unit/filesize-helpers.test.js b/tests/unit/filesize-helpers.test.js index 4e09859..e3e31ff 100644 --- a/tests/unit/filesize-helpers.test.js +++ b/tests/unit/filesize-helpers.test.js @@ -10,7 +10,7 @@ import { calculateOptimizedValue, applyPrecisionHandling, applyNumberFormatting -} from '../../src/filesize.js'; +} from '../../src/helpers.js'; describe('Helper Functions', () => { describe('getBaseConfiguration', () => { @@ -110,30 +110,30 @@ describe('Helper Functions', () => { describe('calculateOptimizedValue', () => { it('should calculate value without bits', () => { const result = calculateOptimizedValue(1024, 1, false, false, 1024); - assert.deepStrictEqual(result, { val: 1, e: 1 }); + assert.deepStrictEqual(result, { result: 1, e: 1 }); }); it('should calculate value with bits', () => { const result = calculateOptimizedValue(1024, 1, false, true, 1024); - assert.deepStrictEqual(result, { val: 8, e: 1 }); + assert.deepStrictEqual(result, { result: 8, e: 1 }); }); it('should handle bits auto-increment', () => { const result = calculateOptimizedValue(128, 0, false, true, 1024); - assert.deepStrictEqual(result, { val: 1, e: 1 }); + assert.deepStrictEqual(result, { result: 1, e: 1 }); }); it('should use decimal powers', () => { const result = calculateOptimizedValue(1000, 1, true, false, 1000); - assert.deepStrictEqual(result, { val: 1, e: 1 }); + assert.deepStrictEqual(result, { result: 1, e: 1 }); }); it('should not increment when e >= 8', () => { // Use a proper YiB value for exponent 8 const yibValue = Math.pow(1024, 8); // 1 YiB in bytes - const result = calculateOptimizedValue(yibValue, 8, false, true, 1024); - assert.strictEqual(result.e, 8); - assert(result.val >= 8); // Should be 8 bits (1 byte * 8) + const resultObj = calculateOptimizedValue(yibValue, 8, false, true, 1024); + assert.strictEqual(resultObj.e, 8); + assert(resultObj.result >= 8); // Should be 8 bits (1 byte * 8) }); }); From 4d72a23e2f30929436dc4abd5b1f7464dc8e68d3 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:32:05 -0400 Subject: [PATCH 03/12] Building --- dist/filesize.cjs | 320 +++++++++++++++++------------------ dist/filesize.js | 315 +++++++++++++++++----------------- dist/filesize.min.js | 2 +- dist/filesize.min.js.map | 2 +- dist/filesize.umd.js | 315 +++++++++++++++++----------------- dist/filesize.umd.min.js | 2 +- dist/filesize.umd.min.js.map | 2 +- 7 files changed, 473 insertions(+), 485 deletions(-) diff --git a/dist/filesize.cjs b/dist/filesize.cjs index e698a33..baafdf4 100644 --- a/dist/filesize.cjs +++ b/dist/filesize.cjs @@ -91,11 +91,161 @@ const LOG_10_1000 = Math.log(1000); // Cached configuration lookup for better performance const STANDARD_CONFIGS = { - [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, - [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, - [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } + [SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC}, + [IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC}, + [JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC} }; +/** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration (standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return {isDecimal: false, ceil: 1024, actualStandard: IEC}; + } + + // Default + return {isDecimal: true, ceil: 1000, actualStandard: JEDEC}; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue (num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let result = num / d; + + if (bits) { + result *= 8; + // Handle auto-increment for bits + if (result >= ceil && e < 8) { + result /= ceil; + e++; + } + } + + return {result, e}; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision); + } + + return {value: result, e}; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +} + /** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert @@ -148,8 +298,7 @@ function filesize (arg, { u = EMPTY; // Optimized base & standard configuration lookup - const config = getBaseConfiguration(standard, base); - const { isDecimal, ceil, actualStandard } = config; + const {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, @@ -194,9 +343,9 @@ function filesize (arg, { } // Calculate value with optimized lookup and bits handling - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - val = valueResult.val; - e = valueResult.e; + const {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult; + e = valueExponent; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -252,156 +401,6 @@ function filesize (arg, { return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } -/** - * Optimized base configuration lookup - * @param {string} standard - Standard type - * @param {number} base - Base number - * @returns {Object} Configuration object - */ -function getBaseConfiguration(standard, base) { - // Use cached lookup table for better performance - if (STANDARD_CONFIGS[standard]) { - return STANDARD_CONFIGS[standard]; - } - - // Base override - if (base === 2) { - return { isDecimal: false, ceil: 1024, actualStandard: IEC }; - } - - // Default - return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; -} - -/** - * Optimized zero value handling - * @param {number} precision - Precision value - * @param {string} actualStandard - Standard to use - * @param {boolean} bits - Whether to use bits - * @param {Object} symbols - Custom symbols - * @param {boolean} full - Whether to use full form - * @param {Array} fullforms - Custom full forms - * @param {string} output - Output format - * @param {string} spacer - Spacer character - * @returns {string|Array|Object|number} Formatted result - */ -function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { - const result = []; - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Apply symbol customization - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply full form - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - // Return in requested format - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); -} - -/** - * Optimized value calculation with bits handling - * @param {number} num - Input number - * @param {number} e - Exponent - * @param {boolean} isDecimal - Whether to use decimal powers - * @param {boolean} bits - Whether to calculate bits - * @param {number} ceil - Ceiling value for auto-increment - * @returns {Object} Object with val and e properties - */ -function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; - let val = num / d; - - if (bits) { - val *= 8; - // Handle auto-increment for bits - if (val >= ceil && e < 8) { - val /= ceil; - e++; - } - } - - return { val, e }; -} - -/** - * Optimized precision handling with scientific notation correction - * @param {number} value - Current value - * @param {number} precision - Precision to apply - * @param {number} e - Current exponent - * @param {number} num - Original number - * @param {boolean} isDecimal - Whether using decimal base - * @param {boolean} bits - Whether calculating bits - * @param {number} ceil - Ceiling value - * @param {Function} roundingFunc - Rounding function - * @param {number} round - Round value - * @returns {Object} Object with value and e properties - */ -function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { - let result = value.toPrecision(precision); - - // Handle scientific notation by recalculating with incremented exponent - if (result.includes(E) && e < 8) { - e++; - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); - } - - return { value: result, e }; -} - -/** - * Optimized number formatting with locale, separator, and padding - * @param {number|string} value - Value to format - * @param {string|boolean} locale - Locale setting - * @param {Object} localeOptions - Locale options - * @param {string} separator - Custom separator - * @param {boolean} pad - Whether to pad - * @param {number} round - Round value - * @returns {string|number} Formatted value - */ -function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { - let result = value; - - // Apply locale formatting - if (locale === true) { - result = result.toLocaleString(); - } else if (locale.length > 0) { - result = result.toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result = result.toString().replace(PERIOD, separator); - } - - // Apply padding - if (pad && round > 0) { - const resultStr = result.toString(); - const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); - const tmp = resultStr.split(x); - const s = tmp[1] || EMPTY; - const l = s.length; - const n = round - l; - - result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } - - return result; -} - /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -466,10 +465,5 @@ function partial ({ }); } -exports.applyNumberFormatting = applyNumberFormatting; -exports.applyPrecisionHandling = applyPrecisionHandling; -exports.calculateOptimizedValue = calculateOptimizedValue; exports.filesize = filesize; -exports.getBaseConfiguration = getBaseConfiguration; -exports.handleZeroValue = handleZeroValue; exports.partial = partial; diff --git a/dist/filesize.js b/dist/filesize.js index 837eeb7..0f06e20 100644 --- a/dist/filesize.js +++ b/dist/filesize.js @@ -87,12 +87,160 @@ const DECIMAL_POWERS = [ const LOG_2_1024 = Math.log(1024); const LOG_10_1000 = Math.log(1000);// Cached configuration lookup for better performance const STANDARD_CONFIGS = { - [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, - [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, - [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } + [SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC}, + [IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC}, + [JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC} }; /** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration (standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return {isDecimal: false, ceil: 1024, actualStandard: IEC}; + } + + // Default + return {isDecimal: true, ceil: 1000, actualStandard: JEDEC}; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue (num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let result = num / d; + + if (bits) { + result *= 8; + // Handle auto-increment for bits + if (result >= ceil && e < 8) { + result /= ceil; + e++; + } + } + + return {result, e}; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision); + } + + return {value: result, e}; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +}/** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert * @param {Object} [options={}] - Configuration options for formatting @@ -144,8 +292,7 @@ function filesize (arg, { u = EMPTY; // Optimized base & standard configuration lookup - const config = getBaseConfiguration(standard, base); - const { isDecimal, ceil, actualStandard } = config; + const {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, @@ -190,9 +337,9 @@ function filesize (arg, { } // Calculate value with optimized lookup and bits handling - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - val = valueResult.val; - e = valueResult.e; + const {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult; + e = valueExponent; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -248,156 +395,6 @@ function filesize (arg, { return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } -/** - * Optimized base configuration lookup - * @param {string} standard - Standard type - * @param {number} base - Base number - * @returns {Object} Configuration object - */ -function getBaseConfiguration(standard, base) { - // Use cached lookup table for better performance - if (STANDARD_CONFIGS[standard]) { - return STANDARD_CONFIGS[standard]; - } - - // Base override - if (base === 2) { - return { isDecimal: false, ceil: 1024, actualStandard: IEC }; - } - - // Default - return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; -} - -/** - * Optimized zero value handling - * @param {number} precision - Precision value - * @param {string} actualStandard - Standard to use - * @param {boolean} bits - Whether to use bits - * @param {Object} symbols - Custom symbols - * @param {boolean} full - Whether to use full form - * @param {Array} fullforms - Custom full forms - * @param {string} output - Output format - * @param {string} spacer - Spacer character - * @returns {string|Array|Object|number} Formatted result - */ -function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { - const result = []; - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Apply symbol customization - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply full form - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - // Return in requested format - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); -} - -/** - * Optimized value calculation with bits handling - * @param {number} num - Input number - * @param {number} e - Exponent - * @param {boolean} isDecimal - Whether to use decimal powers - * @param {boolean} bits - Whether to calculate bits - * @param {number} ceil - Ceiling value for auto-increment - * @returns {Object} Object with val and e properties - */ -function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; - let val = num / d; - - if (bits) { - val *= 8; - // Handle auto-increment for bits - if (val >= ceil && e < 8) { - val /= ceil; - e++; - } - } - - return { val, e }; -} - -/** - * Optimized precision handling with scientific notation correction - * @param {number} value - Current value - * @param {number} precision - Precision to apply - * @param {number} e - Current exponent - * @param {number} num - Original number - * @param {boolean} isDecimal - Whether using decimal base - * @param {boolean} bits - Whether calculating bits - * @param {number} ceil - Ceiling value - * @param {Function} roundingFunc - Rounding function - * @param {number} round - Round value - * @returns {Object} Object with value and e properties - */ -function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { - let result = value.toPrecision(precision); - - // Handle scientific notation by recalculating with incremented exponent - if (result.includes(E) && e < 8) { - e++; - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); - } - - return { value: result, e }; -} - -/** - * Optimized number formatting with locale, separator, and padding - * @param {number|string} value - Value to format - * @param {string|boolean} locale - Locale setting - * @param {Object} localeOptions - Locale options - * @param {string} separator - Custom separator - * @param {boolean} pad - Whether to pad - * @param {number} round - Round value - * @returns {string|number} Formatted value - */ -function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { - let result = value; - - // Apply locale formatting - if (locale === true) { - result = result.toLocaleString(); - } else if (locale.length > 0) { - result = result.toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result = result.toString().replace(PERIOD, separator); - } - - // Apply padding - if (pad && round > 0) { - const resultStr = result.toString(); - const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); - const tmp = resultStr.split(x); - const s = tmp[1] || EMPTY; - const l = s.length; - const n = round - l; - - result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } - - return result; -} - /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -460,4 +457,4 @@ function partial ({ roundingMethod, precision }); -}export{applyNumberFormatting,applyPrecisionHandling,calculateOptimizedValue,filesize,getBaseConfiguration,handleZeroValue,partial}; \ No newline at end of file +}export{filesize,partial}; \ No newline at end of file diff --git a/dist/filesize.min.js b/dist/filesize.min.js index 4833127..f14a16b 100644 --- a/dist/filesize.min.js +++ b/dist/filesize.min.js @@ -2,4 +2,4 @@ 2025 Jason Mulligan @version 11.0.11 */ -const t="iec",i="jedec",e="si",o="bits",n="byte",a="bytes",l="array",r="object",s="string",c="exponent",u="round",b="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),g=Math.log(1e3),h={[e]:{isDecimal:!0,ceil:1e3,actualStandard:i},[t]:{isDecimal:!1,ceil:1024,actualStandard:t},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function y(t,{bits:i=!1,pad:e=!1,base:p=-1,round:f=2,locale:h="",localeOptions:y={},separator:D="",spacer:E=" ",symbols:P={},standard:j="",output:w=s,fullform:T=!1,fullforms:N=[],exponent:$=-1,roundingMethod:k=u,precision:G=0}={}){let K=$,Y=Number(t),Z=[],O=0,z=b;const I=B(j,p),{isDecimal:L,ceil:q,actualStandard:A}=I,C=!0===T,F=Y<0,H=Math[k];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof H)throw new TypeError("Invalid rounding method");if(F&&(Y=-Y),0===Y)return M(G,A,i,P,C,N,w,E);if((-1===K||isNaN(K))&&(K=L?Math.floor(Math.log(Y)/g):Math.floor(Math.log(Y)/m),K<0&&(K=0)),K>8&&(G>0&&(G+=8-K),K=8),w===c)return K;const J=x(Y,K,L,i,q);O=J.val,K=J.e;const Q=K>0&&f>0?Math.pow(10,f):1;if(Z[0]=1===Q?H(O):H(O*Q)/Q,Z[0]===q&&K<8&&-1===$&&(Z[0]=1,K++),G>0){const t=v(Z[0],G,K,Y,L,i,q,H,f);Z[0]=t.value,K=t.e}const R=d.symbol[A][i?o:a];return z=Z[1]=L&&1===K?i?"kbit":"kB":R[K],F&&(Z[0]=-Z[0]),P[Z[1]]&&(Z[1]=P[Z[1]]),Z[0]=S(Z[0],h,y,D,e,f),C&&(Z[1]=N[K]||d.fullform[A][K]+(i?"bit":n)+(1===Z[0]?b:"s")),w===l?Z:w===r?{value:Z[0],symbol:Z[1],exponent:K,unit:z}:" "===E?`${Z[0]} ${Z[1]}`:Z.join(E)}function B(e,o){return h[e]?h[e]:2===o?{isDecimal:!1,ceil:1024,actualStandard:t}:{isDecimal:!0,ceil:1e3,actualStandard:i}}function M(t,i,e,s,u,b,p,f){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[i][e?o:a][0];return p===c?0:(s[m[1]]&&(m[1]=s[m[1]]),u&&(m[1]=b[0]||d.fullform[i][0]+(e?"bit":n)),p===l?m:p===r?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(f))}function x(t,i,e,o,n){let a=t/(e?f[i]:p[i]);return o&&(a*=8,a>=n&&i<8&&(a/=n,i++)),{val:a,e:i}}function v(t,i,e,o,n,a,l,r,s){let c=t.toPrecision(i);if(c.includes("e")&&e<8){const t=x(o,++e,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t.val):r(t.val*u)/u).toPrecision(i)}return{value:c,e:e}}function S(t,i,e,o,n,a){let l=t;if(!0===i?l=l.toLocaleString():i.length>0?l=l.toLocaleString(i,e):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),i=o||(t.match(/(\D)/g)||[]).pop()||".",e=t.split(i),n=e[1]||b,r=n.length,s=a-r;l=`${e[0]}${i}${n.padEnd(r+s,"0")}`}return l}function D({bits:t=!1,pad:i=!1,base:e=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:c={},standard:b="",output:d=s,fullform:p=!1,fullforms:f=[],exponent:m=-1,roundingMethod:g=u,precision:h=0}={}){return s=>y(s,{bits:t,pad:i,base:e,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:c,standard:b,output:d,fullform:p,fullforms:f,exponent:m,roundingMethod:g,precision:h})}export{S as applyNumberFormatting,v as applyPrecisionHandling,x as calculateOptimizedValue,y as filesize,B as getBaseConfiguration,M as handleZeroValue,D as partial};//# sourceMappingURL=filesize.min.js.map +const t="iec",e="jedec",i="si",o="bits",n="byte",a="bytes",l="array",r="object",s="string",c="exponent",u="round",b="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),g=Math.log(1e3),h={[i]:{isDecimal:!0,ceil:1e3,actualStandard:e},[t]:{isDecimal:!1,ceil:1024,actualStandard:t},[e]:{isDecimal:!1,ceil:1024,actualStandard:e}};function y(t,e,i,o,n){let a=t/(i?f[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{result:a,e:e}}function B(i,{bits:p=!1,pad:f=!1,base:B=-1,round:M=2,locale:x="",localeOptions:S={},separator:D="",spacer:E=" ",symbols:P={},standard:j="",output:v=s,fullform:w=!1,fullforms:T=[],exponent:N=-1,roundingMethod:$=u,precision:k=0}={}){let G=N,K=Number(i),Y=[],Z=0,O=b;const{isDecimal:z,ceil:I,actualStandard:L}=function(i,o){return h[i]?h[i]:2===o?{isDecimal:!1,ceil:1024,actualStandard:t}:{isDecimal:!0,ceil:1e3,actualStandard:e}}(j,B),q=!0===w,A=K<0,C=Math[$];if("bigint"!=typeof i&&isNaN(i))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(K=-K),0===K)return function(t,e,i,s,u,b,p,f){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[e][i?o:a][0];return p===c?0:(s[m[1]]&&(m[1]=s[m[1]]),u&&(m[1]=b[0]||d.fullform[e][0]+(i?"bit":n)),p===l?m:p===r?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(f))}(k,L,p,P,q,T,v,E);if((-1===G||isNaN(G))&&(G=z?Math.floor(Math.log(K)/g):Math.floor(Math.log(K)/m),G<0&&(G=0)),G>8&&(k>0&&(k+=8-G),G=8),v===c)return G;const{result:F,e:H}=y(K,G,z,p,I);Z=F,G=H;const J=G>0&&M>0?Math.pow(10,M):1;if(Y[0]=1===J?C(Z):C(Z*J)/J,Y[0]===I&&G<8&&-1===N&&(Y[0]=1,G++),k>0){const t=function(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){i++;const{result:t}=y(o,i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t):r(t*u)/u).toPrecision(e)}return{value:c,e:i}}(Y[0],k,G,K,z,p,I,C,M);Y[0]=t.value,G=t.e}const Q=d.symbol[L][p?o:a];return O=Y[1]=z&&1===G?p?"kbit":"kB":Q[G],A&&(Y[0]=-Y[0]),P[Y[1]]&&(Y[1]=P[Y[1]]),Y[0]=function(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||b,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}(Y[0],x,S,D,f,M),q&&(Y[1]=T[G]||d.fullform[L][G]+(p?"bit":n)+(1===Y[0]?b:"s")),v===l?Y:v===r?{value:Y[0],symbol:Y[1],exponent:G,unit:O}:" "===E?`${Y[0]} ${Y[1]}`:Y.join(E)}function M({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:c={},standard:b="",output:d=s,fullform:p=!1,fullforms:f=[],exponent:m=-1,roundingMethod:g=u,precision:h=0}={}){return s=>B(s,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:c,standard:b,output:d,fullform:p,fullforms:f,exponent:m,roundingMethod:g,precision:h})}export{B as filesize,M as partial};//# sourceMappingURL=filesize.min.js.map diff --git a/dist/filesize.min.js.map b/dist/filesize.min.js.map index 44724c9..b6f3997 100644 --- a/dist/filesize.min.js.map +++ b/dist/filesize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC },\n\t[IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC },\n\t[JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC }\n};\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst config = getBaseConfiguration(standard, base);\n\tconst { isDecimal, ceil, actualStandard } = config;\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult.val;\n\te = valueResult.e;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration(standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn { isDecimal: false, ceil: 1024, actualStandard: IEC };\n\t}\n\n\t// Default\n\treturn { isDecimal: true, ceil: 1000, actualStandard: JEDEC };\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue(num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet val = num / d;\n\n\tif (bits) {\n\t\tval *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn { val, e };\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision);\n\t}\n\n\treturn { value: result, e };\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","filesize","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","e","num","Number","result","val","u","config","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","handleZeroValue","floor","valueResult","calculateOptimizedValue","p","pow","precisionResult","applyPrecisionHandling","value","symbolTable","applyNumberFormatting","unit","join","toPrecision","includes","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","filesize","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file diff --git a/dist/filesize.umd.js b/dist/filesize.umd.js index e1f9020..87417aa 100644 --- a/dist/filesize.umd.js +++ b/dist/filesize.umd.js @@ -87,12 +87,160 @@ const DECIMAL_POWERS = [ const LOG_2_1024 = Math.log(1024); const LOG_10_1000 = Math.log(1000);// Cached configuration lookup for better performance const STANDARD_CONFIGS = { - [SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC }, - [IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC }, - [JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC } + [SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC}, + [IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC}, + [JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC} }; /** + * Optimized base configuration lookup + * @param {string} standard - Standard type + * @param {number} base - Base number + * @returns {Object} Configuration object + */ +function getBaseConfiguration (standard, base) { + // Use cached lookup table for better performance + if (STANDARD_CONFIGS[standard]) { + return STANDARD_CONFIGS[standard]; + } + + // Base override + if (base === 2) { + return {isDecimal: false, ceil: 1024, actualStandard: IEC}; + } + + // Default + return {isDecimal: true, ceil: 1000, actualStandard: JEDEC}; +} + +/** + * Optimized zero value handling + * @param {number} precision - Precision value + * @param {string} actualStandard - Standard to use + * @param {boolean} bits - Whether to use bits + * @param {Object} symbols - Custom symbols + * @param {boolean} full - Whether to use full form + * @param {Array} fullforms - Custom full forms + * @param {string} output - Output format + * @param {string} spacer - Spacer character + * @returns {string|Array|Object|number} Formatted result + */ +function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { + const result = []; + result[0] = precision > 0 ? (0).toPrecision(precision) : 0; + const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; + + if (output === EXPONENT) { + return 0; + } + + // Apply symbol customization + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + // Apply full form + if (full) { + result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + } + + // Return in requested format + return output === ARRAY ? result : output === OBJECT ? { + value: result[0], + symbol: result[1], + exponent: 0, + unit: u + } : result.join(spacer); +} + +/** + * Optimized value calculation with bits handling + * @param {number} num - Input number + * @param {number} e - Exponent + * @param {boolean} isDecimal - Whether to use decimal powers + * @param {boolean} bits - Whether to calculate bits + * @param {number} ceil - Ceiling value for auto-increment + * @returns {Object} Object with val and e properties + */ +function calculateOptimizedValue (num, e, isDecimal, bits, ceil) { + const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let result = num / d; + + if (bits) { + result *= 8; + // Handle auto-increment for bits + if (result >= ceil && e < 8) { + result /= ceil; + e++; + } + } + + return {result, e}; +} + +/** + * Optimized precision handling with scientific notation correction + * @param {number} value - Current value + * @param {number} precision - Precision to apply + * @param {number} e - Current exponent + * @param {number} num - Original number + * @param {boolean} isDecimal - Whether using decimal base + * @param {boolean} bits - Whether calculating bits + * @param {number} ceil - Ceiling value + * @param {Function} roundingFunc - Rounding function + * @param {number} round - Round value + * @returns {Object} Object with value and e properties + */ +function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { + let result = value.toPrecision(precision); + + // Handle scientific notation by recalculating with incremented exponent + if (result.includes(E) && e < 8) { + e++; + const {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + const p = round > 0 ? Math.pow(10, round) : 1; + result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision); + } + + return {value: result, e}; +} + +/** + * Optimized number formatting with locale, separator, and padding + * @param {number|string} value - Value to format + * @param {string|boolean} locale - Locale setting + * @param {Object} localeOptions - Locale options + * @param {string} separator - Custom separator + * @param {boolean} pad - Whether to pad + * @param {number} round - Round value + * @returns {string|number} Formatted value + */ +function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) { + let result = value; + + // Apply locale formatting + if (locale === true) { + result = result.toLocaleString(); + } else if (locale.length > 0) { + result = result.toLocaleString(locale, localeOptions); + } else if (separator.length > 0) { + result = result.toString().replace(PERIOD, separator); + } + + // Apply padding + if (pad && round > 0) { + const resultStr = result.toString(); + const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); + const tmp = resultStr.split(x); + const s = tmp[1] || EMPTY; + const l = s.length; + const n = round - l; + + result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; + } + + return result; +}/** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert * @param {Object} [options={}] - Configuration options for formatting @@ -144,8 +292,7 @@ function filesize (arg, { u = EMPTY; // Optimized base & standard configuration lookup - const config = getBaseConfiguration(standard, base); - const { isDecimal, ceil, actualStandard } = config; + const {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, @@ -190,9 +337,9 @@ function filesize (arg, { } // Calculate value with optimized lookup and bits handling - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - val = valueResult.val; - e = valueResult.e; + const {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil); + val = valueResult; + e = valueExponent; // Optimize rounding calculation const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; @@ -248,156 +395,6 @@ function filesize (arg, { return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); } -/** - * Optimized base configuration lookup - * @param {string} standard - Standard type - * @param {number} base - Base number - * @returns {Object} Configuration object - */ -function getBaseConfiguration(standard, base) { - // Use cached lookup table for better performance - if (STANDARD_CONFIGS[standard]) { - return STANDARD_CONFIGS[standard]; - } - - // Base override - if (base === 2) { - return { isDecimal: false, ceil: 1024, actualStandard: IEC }; - } - - // Default - return { isDecimal: true, ceil: 1000, actualStandard: JEDEC }; -} - -/** - * Optimized zero value handling - * @param {number} precision - Precision value - * @param {string} actualStandard - Standard to use - * @param {boolean} bits - Whether to use bits - * @param {Object} symbols - Custom symbols - * @param {boolean} full - Whether to use full form - * @param {Array} fullforms - Custom full forms - * @param {string} output - Output format - * @param {string} spacer - Spacer character - * @returns {string|Array|Object|number} Formatted result - */ -function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) { - const result = []; - result[0] = precision > 0 ? (0).toPrecision(precision) : 0; - const u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0]; - - if (output === EXPONENT) { - return 0; - } - - // Apply symbol customization - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply full form - if (full) { - result[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); - } - - // Return in requested format - return output === ARRAY ? result : output === OBJECT ? { - value: result[0], - symbol: result[1], - exponent: 0, - unit: u - } : result.join(spacer); -} - -/** - * Optimized value calculation with bits handling - * @param {number} num - Input number - * @param {number} e - Exponent - * @param {boolean} isDecimal - Whether to use decimal powers - * @param {boolean} bits - Whether to calculate bits - * @param {number} ceil - Ceiling value for auto-increment - * @returns {Object} Object with val and e properties - */ -function calculateOptimizedValue(num, e, isDecimal, bits, ceil) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; - let val = num / d; - - if (bits) { - val *= 8; - // Handle auto-increment for bits - if (val >= ceil && e < 8) { - val /= ceil; - e++; - } - } - - return { val, e }; -} - -/** - * Optimized precision handling with scientific notation correction - * @param {number} value - Current value - * @param {number} precision - Precision to apply - * @param {number} e - Current exponent - * @param {number} num - Original number - * @param {boolean} isDecimal - Whether using decimal base - * @param {boolean} bits - Whether calculating bits - * @param {number} ceil - Ceiling value - * @param {Function} roundingFunc - Rounding function - * @param {number} round - Round value - * @returns {Object} Object with value and e properties - */ -function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) { - let result = value.toPrecision(precision); - - // Handle scientific notation by recalculating with incremented exponent - if (result.includes(E) && e < 8) { - e++; - const valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision); - } - - return { value: result, e }; -} - -/** - * Optimized number formatting with locale, separator, and padding - * @param {number|string} value - Value to format - * @param {string|boolean} locale - Locale setting - * @param {Object} localeOptions - Locale options - * @param {string} separator - Custom separator - * @param {boolean} pad - Whether to pad - * @param {number} round - Round value - * @returns {string|number} Formatted value - */ -function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) { - let result = value; - - // Apply locale formatting - if (locale === true) { - result = result.toLocaleString(); - } else if (locale.length > 0) { - result = result.toLocaleString(locale, localeOptions); - } else if (separator.length > 0) { - result = result.toString().replace(PERIOD, separator); - } - - // Apply padding - if (pad && round > 0) { - const resultStr = result.toString(); - const x = separator || ((resultStr.match(/(\D)/g) || []).pop() || PERIOD); - const tmp = resultStr.split(x); - const s = tmp[1] || EMPTY; - const l = s.length; - const n = round - l; - - result = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`; - } - - return result; -} - /** * Creates a partially applied version of filesize with preset options * @param {Object} [options={}] - Default options to apply to the returned function @@ -460,4 +457,4 @@ function partial ({ roundingMethod, precision }); -}exports.applyNumberFormatting=applyNumberFormatting;exports.applyPrecisionHandling=applyPrecisionHandling;exports.calculateOptimizedValue=calculateOptimizedValue;exports.filesize=filesize;exports.getBaseConfiguration=getBaseConfiguration;exports.handleZeroValue=handleZeroValue;exports.partial=partial;})); \ No newline at end of file +}exports.filesize=filesize;exports.partial=partial;})); \ No newline at end of file diff --git a/dist/filesize.umd.min.js b/dist/filesize.umd.min.js index ee1a554..262a660 100644 --- a/dist/filesize.umd.min.js +++ b/dist/filesize.umd.min.js @@ -2,4 +2,4 @@ 2025 Jason Mulligan @version 11.0.11 */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",o="si",n="bits",a="byte",l="bytes",r="array",s="object",c="string",u="exponent",b="round",d="",f={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],m=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],g=Math.log(1024),y=Math.log(1e3),h={[o]:{isDecimal:!0,ceil:1e3,actualStandard:i},[e]:{isDecimal:!1,ceil:1024,actualStandard:e},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function B(t,{bits:e=!1,pad:i=!1,base:o=-1,round:p=2,locale:m="",localeOptions:h={},separator:B="",spacer:T=" ",symbols:j={},standard:D="",output:E=c,fullform:w=!1,fullforms:N=[],exponent:z=-1,roundingMethod:Z=b,precision:$=0}={}){let k=z,G=Number(t),K=[],O=0,Y=d;const I=M(D,o),{isDecimal:L,ceil:V,actualStandard:C}=I,F=!0===w,H=G<0,q=Math[Z];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof q)throw new TypeError("Invalid rounding method");if(H&&(G=-G),0===G)return x($,C,e,j,F,N,E,T);if((-1===k||isNaN(k))&&(k=L?Math.floor(Math.log(G)/y):Math.floor(Math.log(G)/g),k<0&&(k=0)),k>8&&($>0&&($+=8-k),k=8),E===u)return k;const A=v(G,k,L,e,V);O=A.val,k=A.e;const J=k>0&&p>0?Math.pow(10,p):1;if(K[0]=1===J?q(O):q(O*J)/J,K[0]===V&&k<8&&-1===z&&(K[0]=1,k++),$>0){const t=S(K[0],$,k,G,L,e,V,q,p);K[0]=t.value,k=t.e}const Q=f.symbol[C][e?n:l];return Y=K[1]=L&&1===k?e?"kbit":"kB":Q[k],H&&(K[0]=-K[0]),j[K[1]]&&(K[1]=j[K[1]]),K[0]=P(K[0],m,h,B,i,p),F&&(K[1]=N[k]||f.fullform[C][k]+(e?"bit":a)+(1===K[0]?d:"s")),E===r?K:E===s?{value:K[0],symbol:K[1],exponent:k,unit:Y}:" "===T?`${K[0]} ${K[1]}`:K.join(T)}function M(t,o){return h[t]?h[t]:2===o?{isDecimal:!1,ceil:1024,actualStandard:e}:{isDecimal:!0,ceil:1e3,actualStandard:i}}function x(t,e,i,o,c,b,d,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=f.symbol[e][i?n:l][0];return d===u?0:(o[m[1]]&&(m[1]=o[m[1]]),c&&(m[1]=b[0]||f.fullform[e][0]+(i?"bit":a)),d===r?m:d===s?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(p))}function v(t,e,i,o,n){let a=t/(i?m[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{val:a,e:e}}function S(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){const t=v(o,++i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t.val):r(t.val*u)/u).toPrecision(e)}return{value:c,e:i}}function P(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||d,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}t.applyNumberFormatting=P,t.applyPrecisionHandling=S,t.calculateOptimizedValue=v,t.filesize=B,t.getBaseConfiguration=M,t.handleZeroValue=x,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:s={},standard:u="",output:d=c,fullform:f=!1,fullforms:p=[],exponent:m=-1,roundingMethod:g=b,precision:y=0}={}){return c=>B(c,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:s,standard:u,output:d,fullform:f,fullforms:p,exponent:m,roundingMethod:g,precision:y})}});//# sourceMappingURL=filesize.umd.min.js.map +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",o="si",n="bits",a="byte",l="bytes",r="array",s="object",c="string",u="exponent",b="round",f="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],m=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],g=Math.log(1024),y=Math.log(1e3),h={[o]:{isDecimal:!0,ceil:1e3,actualStandard:i},[e]:{isDecimal:!1,ceil:1024,actualStandard:e},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function B(t,e,i,o,n){let a=t/(i?m[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{result:a,e:e}}function M(t,{bits:o=!1,pad:p=!1,base:m=-1,round:M=2,locale:x="",localeOptions:S={},separator:T="",spacer:j=" ",symbols:D={},standard:E="",output:P=c,fullform:v=!1,fullforms:w=[],exponent:N=-1,roundingMethod:$=b,precision:k=0}={}){let z=N,G=Number(t),K=[],Y=0,Z=f;const{isDecimal:O,ceil:I,actualStandard:L}=function(t,o){return h[t]?h[t]:2===o?{isDecimal:!1,ceil:1024,actualStandard:e}:{isDecimal:!0,ceil:1e3,actualStandard:i}}(E,m),q=!0===v,A=G<0,C=Math[$];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(G=-G),0===G)return function(t,e,i,o,c,b,f,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[e][i?n:l][0];return f===u?0:(o[m[1]]&&(m[1]=o[m[1]]),c&&(m[1]=b[0]||d.fullform[e][0]+(i?"bit":a)),f===r?m:f===s?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(p))}(k,L,o,D,q,w,P,j);if((-1===z||isNaN(z))&&(z=O?Math.floor(Math.log(G)/y):Math.floor(Math.log(G)/g),z<0&&(z=0)),z>8&&(k>0&&(k+=8-z),z=8),P===u)return z;const{result:F,e:H}=B(G,z,O,o,I);Y=F,z=H;const J=z>0&&M>0?Math.pow(10,M):1;if(K[0]=1===J?C(Y):C(Y*J)/J,K[0]===I&&z<8&&-1===N&&(K[0]=1,z++),k>0){const t=function(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){i++;const{result:t}=B(o,i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t):r(t*u)/u).toPrecision(e)}return{value:c,e:i}}(K[0],k,z,G,O,o,I,C,M);K[0]=t.value,z=t.e}const Q=d.symbol[L][o?n:l];return Z=K[1]=O&&1===z?o?"kbit":"kB":Q[z],A&&(K[0]=-K[0]),D[K[1]]&&(K[1]=D[K[1]]),K[0]=function(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||f,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}(K[0],x,S,T,p,M),q&&(K[1]=w[z]||d.fullform[L][z]+(o?"bit":a)+(1===K[0]?f:"s")),P===r?K:P===s?{value:K[0],symbol:K[1],exponent:z,unit:Z}:" "===j?`${K[0]} ${K[1]}`:K.join(j)}t.filesize=M,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:s={},standard:u="",output:f=c,fullform:d=!1,fullforms:p=[],exponent:m=-1,roundingMethod:g=b,precision:y=0}={}){return c=>M(c,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:s,standard:u,output:f,fullform:d,fullforms:p,exponent:m,roundingMethod:g,precision:y})}});//# sourceMappingURL=filesize.umd.min.js.map diff --git a/dist/filesize.umd.min.js.map b/dist/filesize.umd.min.js.map index 2a79544..e605e00 100644 --- a/dist/filesize.umd.min.js.map +++ b/dist/filesize.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tIEC,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tJEDEC,\n\tLOG_2_1024,\n\tLOG_10_1000,\n\tOBJECT,\n\tPERIOD,\n\tROUND,\n\tS,\n\tSI,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: { isDecimal: true, ceil: 1000, actualStandard: JEDEC },\n\t[IEC]: { isDecimal: false, ceil: 1024, actualStandard: IEC },\n\t[JEDEC]: { isDecimal: false, ceil: 1024, actualStandard: JEDEC }\n};\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst config = getBaseConfiguration(standard, base);\n\tconst { isDecimal, ceil, actualStandard } = config;\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult.val;\n\te = valueResult.e;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration(standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn { isDecimal: false, ceil: 1024, actualStandard: IEC };\n\t}\n\n\t// Default\n\treturn { isDecimal: true, ceil: 1000, actualStandard: JEDEC };\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue(num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet val = num / d;\n\n\tif (bits) {\n\t\tval *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (val >= ceil && e < 8) {\n\t\t\tval /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn { val, e };\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling(value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst valueResult = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult.val) : roundingFunc(valueResult.val * p) / p).toPrecision(precision);\n\t}\n\n\treturn { value: result, e };\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting(value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","e","num","Number","result","val","u","config","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","handleZeroValue","floor","valueResult","calculateOptimizedValue","p","pow","precisionResult","applyPrecisionHandling","value","symbolTable","applyNumberFormatting","unit","join","toPrecision","includes","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file From f83feb54cc9d508ebd89fd7f8f48a14231aeea4a Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:37:42 -0400 Subject: [PATCH 04/12] Updating build tools & README.md --- README.md | 46 +++++++- dist/filesize.min.js | 2 +- dist/filesize.min.js.map | 2 +- dist/filesize.umd.min.js | 2 +- dist/filesize.umd.min.js.map | 2 +- package-lock.json | 209 +++++++++++++++++++---------------- package.json | 15 ++- rollup.config.js | 74 ++++++++++++- 8 files changed, 238 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index 1b0dadb..704f577 100644 --- a/README.md +++ b/README.md @@ -447,23 +447,61 @@ filesize.js/ 6. Push to the branch (`git push origin feature/amazing-feature`) 7. Open a Pull Request +### Development Workflow + +filesize.js includes an optimized development workflow with modern build tools: + +* **🔄 Live Reload**: Use `npm run dev` for automatic rebuilds during development +* **📊 Bundle Analysis**: Monitor build sizes with `npm run build:analyze` +* **⚡ Fast Testing**: Live test running with `npm run test:watch` +* **🔧 Auto-fixing**: Automatic linting fixes with `npm run lint:fix` +* **📈 Performance**: Optimized Rollup configuration with enhanced tree shaking + +**Build Output Analysis:** +- Minified ES Module: ~1.8KB (gzipped) +- UMD Bundle: ~1.9KB (gzipped) +- Comprehensive source maps included + ### Development Commands ```bash # Install dependencies npm install +# Development mode with live rebuild +npm run dev + +# Build distribution +npm run build + +# Build with bundle size analysis +npm run build:analyze + +# Live rebuild during development +npm run build:watch + # Run linting npm run lint +# Auto-fix linting issues +npm run lint:fix + # Run tests npm test -# Build distribution -npm run build +# Live testing during development +npm run test:watch + +# Run only unit tests +npm run mocha + +# Bundle size analysis +npm run analyze:size -# Run all checks (lint + test) -npm run ci +# Benchmarking +npm run benchmark +npm run benchmark:basic +npm run benchmark:stress ``` ## License diff --git a/dist/filesize.min.js b/dist/filesize.min.js index f14a16b..f091779 100644 --- a/dist/filesize.min.js +++ b/dist/filesize.min.js @@ -2,4 +2,4 @@ 2025 Jason Mulligan @version 11.0.11 */ -const t="iec",e="jedec",i="si",o="bits",n="byte",a="bytes",l="array",r="object",s="string",c="exponent",u="round",b="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),g=Math.log(1e3),h={[i]:{isDecimal:!0,ceil:1e3,actualStandard:e},[t]:{isDecimal:!1,ceil:1024,actualStandard:t},[e]:{isDecimal:!1,ceil:1024,actualStandard:e}};function y(t,e,i,o,n){let a=t/(i?f[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{result:a,e:e}}function B(i,{bits:p=!1,pad:f=!1,base:B=-1,round:M=2,locale:x="",localeOptions:S={},separator:D="",spacer:E=" ",symbols:P={},standard:j="",output:v=s,fullform:w=!1,fullforms:T=[],exponent:N=-1,roundingMethod:$=u,precision:k=0}={}){let G=N,K=Number(i),Y=[],Z=0,O=b;const{isDecimal:z,ceil:I,actualStandard:L}=function(i,o){return h[i]?h[i]:2===o?{isDecimal:!1,ceil:1024,actualStandard:t}:{isDecimal:!0,ceil:1e3,actualStandard:e}}(j,B),q=!0===w,A=K<0,C=Math[$];if("bigint"!=typeof i&&isNaN(i))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(K=-K),0===K)return function(t,e,i,s,u,b,p,f){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[e][i?o:a][0];return p===c?0:(s[m[1]]&&(m[1]=s[m[1]]),u&&(m[1]=b[0]||d.fullform[e][0]+(i?"bit":n)),p===l?m:p===r?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(f))}(k,L,p,P,q,T,v,E);if((-1===G||isNaN(G))&&(G=z?Math.floor(Math.log(K)/g):Math.floor(Math.log(K)/m),G<0&&(G=0)),G>8&&(k>0&&(k+=8-G),G=8),v===c)return G;const{result:F,e:H}=y(K,G,z,p,I);Z=F,G=H;const J=G>0&&M>0?Math.pow(10,M):1;if(Y[0]=1===J?C(Z):C(Z*J)/J,Y[0]===I&&G<8&&-1===N&&(Y[0]=1,G++),k>0){const t=function(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){i++;const{result:t}=y(o,i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t):r(t*u)/u).toPrecision(e)}return{value:c,e:i}}(Y[0],k,G,K,z,p,I,C,M);Y[0]=t.value,G=t.e}const Q=d.symbol[L][p?o:a];return O=Y[1]=z&&1===G?p?"kbit":"kB":Q[G],A&&(Y[0]=-Y[0]),P[Y[1]]&&(Y[1]=P[Y[1]]),Y[0]=function(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||b,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}(Y[0],x,S,D,f,M),q&&(Y[1]=T[G]||d.fullform[L][G]+(p?"bit":n)+(1===Y[0]?b:"s")),v===l?Y:v===r?{value:Y[0],symbol:Y[1],exponent:G,unit:O}:" "===E?`${Y[0]} ${Y[1]}`:Y.join(E)}function M({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:c={},standard:b="",output:d=s,fullform:p=!1,fullforms:f=[],exponent:m=-1,roundingMethod:g=u,precision:h=0}={}){return s=>B(s,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:c,standard:b,output:d,fullform:p,fullforms:f,exponent:m,roundingMethod:g,precision:h})}export{B as filesize,M as partial};//# sourceMappingURL=filesize.min.js.map +const t="iec",e="jedec",i="si",n="bits",a="byte",o="bytes",r="array",l="object",s="string",c="exponent",u="round",b={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},d=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],f=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],p=Math.log(1024),m=Math.log(1e3),B={[i]:{isDecimal:!0,ceil:1e3,actualStandard:e},[t]:{isDecimal:!1,ceil:1024,actualStandard:t},[e]:{isDecimal:!1,ceil:1024,actualStandard:e}};function y(t,e,i,n,a){let o=t/(i?f[e]:d[e]);return n&&(o*=8,o>=a&&e<8&&(o/=a,e++)),{result:o,e:e}}function M(i,{bits:d=!1,pad:f=!1,base:M=-1,round:h=2,locale:g="",localeOptions:x={},separator:D="",spacer:E=" ",symbols:S={},standard:T="",output:v=s,fullform:N=!1,fullforms:$=[],exponent:j=-1,roundingMethod:k=u,precision:w=0}={}){let G=j,K=Number(i),P=[],Y=0,Z="";const{isDecimal:O,ceil:z,actualStandard:I}=function(i,n){return B[i]?B[i]:2===n?{isDecimal:!1,ceil:1024,actualStandard:t}:{isDecimal:!0,ceil:1e3,actualStandard:e}}(T,M),q=!0===N,A=K<0,C=Math[k];if("bigint"!=typeof i&&isNaN(i))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(K=-K),0===K)return function(t,e,i,s,u,d,f,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const B=m[1]=b.symbol[e][i?n:o][0];return f===c?0:(s[m[1]]&&(m[1]=s[m[1]]),u&&(m[1]=d[0]||b.fullform[e][0]+(i?"bit":a)),f===r?m:f===l?{value:m[0],symbol:m[1],exponent:0,unit:B}:m.join(p))}(w,I,d,S,q,$,v,E);if((-1===G||isNaN(G))&&(G=O?Math.floor(Math.log(K)/m):Math.floor(Math.log(K)/p),G<0&&(G=0)),G>8&&(w>0&&(w+=8-G),G=8),v===c)return G;const{result:F,e:H}=y(K,G,O,d,z);Y=F,G=H;const J=G>0&&h>0?Math.pow(10,h):1;if(P[0]=1===J?C(Y):C(Y*J)/J,P[0]===z&&G<8&&-1===j&&(P[0]=1,G++),w>0){const t=function(t,e,i,n,a,o,r,l,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){i++;const{result:t}=y(n,i,a,o,r),u=s>0?Math.pow(10,s):1;c=(1===u?l(t):l(t*u)/u).toPrecision(e)}return{value:c,e:i}}(P[0],w,G,K,O,d,z,C,h);P[0]=t.value,G=t.e}const L=b.symbol[I][d?n:o];return Z=P[1]=O&&1===G?d?"kbit":"kB":L[G],A&&(P[0]=-P[0]),S[P[1]]&&(P[1]=S[P[1]]),P[0]=function(t,e,i,n,a,o){let r=t;if(!0===e?r=r.toLocaleString():e.length>0?r=r.toLocaleString(e,i):n.length>0&&(r=r.toString().replace(".",n)),a&&o>0){const t=r.toString(),e=n||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),a=i[1]||"",l=a.length,s=o-l;r=`${i[0]}${e}${a.padEnd(l+s,"0")}`}return r}(P[0],g,x,D,f,h),q&&(P[1]=$[G]||b.fullform[I][G]+(d?"bit":a)+(1===P[0]?"":"s")),v===r?P:v===l?{value:P[0],symbol:P[1],exponent:G,unit:Z}:" "===E?`${P[0]} ${P[1]}`:P.join(E)}function h({bits:t=!1,pad:e=!1,base:i=-1,round:n=2,locale:a="",localeOptions:o={},separator:r="",spacer:l=" ",symbols:c={},standard:b="",output:d=s,fullform:f=!1,fullforms:p=[],exponent:m=-1,roundingMethod:B=u,precision:y=0}={}){return s=>M(s,{bits:t,pad:e,base:i,round:n,locale:a,localeOptions:o,separator:r,spacer:l,symbols:c,standard:b,output:d,fullform:f,fullforms:p,exponent:m,roundingMethod:B,precision:y})}export{M as filesize,h as partial};//# sourceMappingURL=filesize.min.js.map diff --git a/dist/filesize.min.js.map b/dist/filesize.min.js.map index b6f3997..f6ce450 100644 --- a/dist/filesize.min.js.map +++ b/dist/filesize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","filesize","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","filesize","arg","pad","base","round","locale","EMPTY","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file diff --git a/dist/filesize.umd.min.js b/dist/filesize.umd.min.js index 262a660..914f6cf 100644 --- a/dist/filesize.umd.min.js +++ b/dist/filesize.umd.min.js @@ -2,4 +2,4 @@ 2025 Jason Mulligan @version 11.0.11 */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",o="si",n="bits",a="byte",l="bytes",r="array",s="object",c="string",u="exponent",b="round",f="",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},p=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],m=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],g=Math.log(1024),y=Math.log(1e3),h={[o]:{isDecimal:!0,ceil:1e3,actualStandard:i},[e]:{isDecimal:!1,ceil:1024,actualStandard:e},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function B(t,e,i,o,n){let a=t/(i?m[e]:p[e]);return o&&(a*=8,a>=n&&e<8&&(a/=n,e++)),{result:a,e:e}}function M(t,{bits:o=!1,pad:p=!1,base:m=-1,round:M=2,locale:x="",localeOptions:S={},separator:T="",spacer:j=" ",symbols:D={},standard:E="",output:P=c,fullform:v=!1,fullforms:w=[],exponent:N=-1,roundingMethod:$=b,precision:k=0}={}){let z=N,G=Number(t),K=[],Y=0,Z=f;const{isDecimal:O,ceil:I,actualStandard:L}=function(t,o){return h[t]?h[t]:2===o?{isDecimal:!1,ceil:1024,actualStandard:e}:{isDecimal:!0,ceil:1e3,actualStandard:i}}(E,m),q=!0===v,A=G<0,C=Math[$];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(G=-G),0===G)return function(t,e,i,o,c,b,f,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const g=m[1]=d.symbol[e][i?n:l][0];return f===u?0:(o[m[1]]&&(m[1]=o[m[1]]),c&&(m[1]=b[0]||d.fullform[e][0]+(i?"bit":a)),f===r?m:f===s?{value:m[0],symbol:m[1],exponent:0,unit:g}:m.join(p))}(k,L,o,D,q,w,P,j);if((-1===z||isNaN(z))&&(z=O?Math.floor(Math.log(G)/y):Math.floor(Math.log(G)/g),z<0&&(z=0)),z>8&&(k>0&&(k+=8-z),z=8),P===u)return z;const{result:F,e:H}=B(G,z,O,o,I);Y=F,z=H;const J=z>0&&M>0?Math.pow(10,M):1;if(K[0]=1===J?C(Y):C(Y*J)/J,K[0]===I&&z<8&&-1===N&&(K[0]=1,z++),k>0){const t=function(t,e,i,o,n,a,l,r,s){let c=t.toPrecision(e);if(c.includes("e")&&i<8){i++;const{result:t}=B(o,i,n,a,l),u=s>0?Math.pow(10,s):1;c=(1===u?r(t):r(t*u)/u).toPrecision(e)}return{value:c,e:i}}(K[0],k,z,G,O,o,I,C,M);K[0]=t.value,z=t.e}const Q=d.symbol[L][o?n:l];return Z=K[1]=O&&1===z?o?"kbit":"kB":Q[z],A&&(K[0]=-K[0]),D[K[1]]&&(K[1]=D[K[1]]),K[0]=function(t,e,i,o,n,a){let l=t;if(!0===e?l=l.toLocaleString():e.length>0?l=l.toLocaleString(e,i):o.length>0&&(l=l.toString().replace(".",o)),n&&a>0){const t=l.toString(),e=o||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),n=i[1]||f,r=n.length,s=a-r;l=`${i[0]}${e}${n.padEnd(r+s,"0")}`}return l}(K[0],x,S,T,p,M),q&&(K[1]=w[z]||d.fullform[L][z]+(o?"bit":a)+(1===K[0]?f:"s")),P===r?K:P===s?{value:K[0],symbol:K[1],exponent:z,unit:Z}:" "===j?`${K[0]} ${K[1]}`:K.join(j)}t.filesize=M,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:o=2,locale:n="",localeOptions:a={},separator:l="",spacer:r=" ",symbols:s={},standard:u="",output:f=c,fullform:d=!1,fullforms:p=[],exponent:m=-1,roundingMethod:g=b,precision:y=0}={}){return c=>M(c,{bits:t,pad:e,base:i,round:o,locale:n,localeOptions:a,separator:l,spacer:r,symbols:s,standard:u,output:f,fullform:d,fullforms:p,exponent:m,roundingMethod:g,precision:y})}});//# sourceMappingURL=filesize.umd.min.js.map +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).filesize={})}(this,function(t){"use strict";const e="iec",i="jedec",n="si",o="bits",a="byte",r="bytes",s="array",l="object",u="string",c="exponent",b="round",d={symbol:{iec:{bits:["bit","Kibit","Mibit","Gibit","Tibit","Pibit","Eibit","Zibit","Yibit"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["bit","Kbit","Mbit","Gbit","Tbit","Pbit","Ebit","Zbit","Ybit"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},fullform:{iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]}},f=[1,1024,1048576,1073741824,1099511627776,0x4000000000000,0x1000000000000000,11805916207174113e5,12089258196146292e8],p=[1,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24],m=Math.log(1024),y=Math.log(1e3),B={[n]:{isDecimal:!0,ceil:1e3,actualStandard:i},[e]:{isDecimal:!1,ceil:1024,actualStandard:e},[i]:{isDecimal:!1,ceil:1024,actualStandard:i}};function h(t,e,i,n,o){let a=t/(i?p[e]:f[e]);return n&&(a*=8,a>=o&&e<8&&(a/=o,e++)),{result:a,e:e}}function M(t,{bits:n=!1,pad:f=!1,base:p=-1,round:M=2,locale:g="",localeOptions:x={},separator:T="",spacer:D=" ",symbols:E={},standard:S="",output:j=u,fullform:v=!1,fullforms:N=[],exponent:$=-1,roundingMethod:k=b,precision:w=0}={}){let G=$,K=Number(t),P=[],Y=0,Z="";const{isDecimal:O,ceil:z,actualStandard:I}=function(t,n){return B[t]?B[t]:2===n?{isDecimal:!1,ceil:1024,actualStandard:e}:{isDecimal:!0,ceil:1e3,actualStandard:i}}(S,p),q=!0===v,A=K<0,C=Math[k];if("bigint"!=typeof t&&isNaN(t))throw new TypeError("Invalid number");if("function"!=typeof C)throw new TypeError("Invalid rounding method");if(A&&(K=-K),0===K)return function(t,e,i,n,u,b,f,p){const m=[];m[0]=t>0?(0).toPrecision(t):0;const y=m[1]=d.symbol[e][i?o:r][0];return f===c?0:(n[m[1]]&&(m[1]=n[m[1]]),u&&(m[1]=b[0]||d.fullform[e][0]+(i?"bit":a)),f===s?m:f===l?{value:m[0],symbol:m[1],exponent:0,unit:y}:m.join(p))}(w,I,n,E,q,N,j,D);if((-1===G||isNaN(G))&&(G=O?Math.floor(Math.log(K)/y):Math.floor(Math.log(K)/m),G<0&&(G=0)),G>8&&(w>0&&(w+=8-G),G=8),j===c)return G;const{result:F,e:H}=h(K,G,O,n,z);Y=F,G=H;const J=G>0&&M>0?Math.pow(10,M):1;if(P[0]=1===J?C(Y):C(Y*J)/J,P[0]===z&&G<8&&-1===$&&(P[0]=1,G++),w>0){const t=function(t,e,i,n,o,a,r,s,l){let u=t.toPrecision(e);if(u.includes("e")&&i<8){i++;const{result:t}=h(n,i,o,a,r),c=l>0?Math.pow(10,l):1;u=(1===c?s(t):s(t*c)/c).toPrecision(e)}return{value:u,e:i}}(P[0],w,G,K,O,n,z,C,M);P[0]=t.value,G=t.e}const L=d.symbol[I][n?o:r];return Z=P[1]=O&&1===G?n?"kbit":"kB":L[G],A&&(P[0]=-P[0]),E[P[1]]&&(P[1]=E[P[1]]),P[0]=function(t,e,i,n,o,a){let r=t;if(!0===e?r=r.toLocaleString():e.length>0?r=r.toLocaleString(e,i):n.length>0&&(r=r.toString().replace(".",n)),o&&a>0){const t=r.toString(),e=n||(t.match(/(\D)/g)||[]).pop()||".",i=t.split(e),o=i[1]||"",s=o.length,l=a-s;r=`${i[0]}${e}${o.padEnd(s+l,"0")}`}return r}(P[0],g,x,T,f,M),q&&(P[1]=N[G]||d.fullform[I][G]+(n?"bit":a)+(1===P[0]?"":"s")),j===s?P:j===l?{value:P[0],symbol:P[1],exponent:G,unit:Z}:" "===D?`${P[0]} ${P[1]}`:P.join(D)}t.filesize=M,t.partial=function({bits:t=!1,pad:e=!1,base:i=-1,round:n=2,locale:o="",localeOptions:a={},separator:r="",spacer:s=" ",symbols:l={},standard:c="",output:d=u,fullform:f=!1,fullforms:p=[],exponent:m=-1,roundingMethod:y=b,precision:B=0}={}){return u=>M(u,{bits:t,pad:e,base:i,round:n,locale:o,localeOptions:a,separator:r,spacer:s,symbols:l,standard:c,output:d,fullform:f,fullforms:p,exponent:m,roundingMethod:y,precision:B})}});//# sourceMappingURL=filesize.umd.min.js.map diff --git a/dist/filesize.umd.min.js.map b/dist/filesize.umd.min.js.map index e605e00..f3241d1 100644 --- a/dist/filesize.umd.min.js.map +++ b/dist/filesize.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","EMPTY","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","arg","pad","base","round","locale","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"filesize.umd.min.js","sources":["../src/constants.js","../src/helpers.js","../src/filesize.js"],"sourcesContent":["// Error Messages\nexport const INVALID_NUMBER = \"Invalid number\";\nexport const INVALID_ROUND = \"Invalid rounding method\";\n\n// Standard Types\nexport const IEC = \"iec\";\nexport const JEDEC = \"jedec\";\nexport const SI = \"si\";\n\n// Unit Types\nexport const BIT = \"bit\";\nexport const BITS = \"bits\";\nexport const BYTE = \"byte\";\nexport const BYTES = \"bytes\";\nexport const SI_KBIT = \"kbit\";\nexport const SI_KBYTE = \"kB\";\n\n// Output Format Types\nexport const ARRAY = \"array\";\nexport const FUNCTION = \"function\";\nexport const OBJECT = \"object\";\nexport const STRING = \"string\";\n\n// Processing Constants\nexport const EXPONENT = \"exponent\";\nexport const ROUND = \"round\";\n\n// Special Characters and Values\nexport const E = \"e\";\nexport const EMPTY = \"\";\nexport const PERIOD = \".\";\nexport const S = \"s\";\nexport const SPACE = \" \";\nexport const ZERO = \"0\";\n\n// Data Structures\nexport const STRINGS = {\n\tsymbol: {\n\t\tiec: {\n\t\t\tbits: [\"bit\", \"Kibit\", \"Mibit\", \"Gibit\", \"Tibit\", \"Pibit\", \"Eibit\", \"Zibit\", \"Yibit\"],\n\t\t\tbytes: [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"]\n\t\t},\n\t\tjedec: {\n\t\t\tbits: [\"bit\", \"Kbit\", \"Mbit\", \"Gbit\", \"Tbit\", \"Pbit\", \"Ebit\", \"Zbit\", \"Ybit\"],\n\t\t\tbytes: [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\t\t}\n\t},\n\tfullform: {\n\t\tiec: [\"\", \"kibi\", \"mebi\", \"gibi\", \"tebi\", \"pebi\", \"exbi\", \"zebi\", \"yobi\"],\n\t\tjedec: [\"\", \"kilo\", \"mega\", \"giga\", \"tera\", \"peta\", \"exa\", \"zetta\", \"yotta\"]\n\t}\n};\n\n// Pre-computed lookup tables for performance optimization\nexport const BINARY_POWERS = [\n\t1, // 2^0\n\t1024, // 2^10\n\t1048576, // 2^20\n\t1073741824, // 2^30\n\t1099511627776, // 2^40\n\t1125899906842624, // 2^50\n\t1152921504606846976, // 2^60\n\t1180591620717411303424, // 2^70\n\t1208925819614629174706176 // 2^80\n];\n\nexport const DECIMAL_POWERS = [\n\t1, // 10^0\n\t1000, // 10^3\n\t1000000, // 10^6\n\t1000000000, // 10^9\n\t1000000000000, // 10^12\n\t1000000000000000, // 10^15\n\t1000000000000000000, // 10^18\n\t1000000000000000000000, // 10^21\n\t1000000000000000000000000 // 10^24\n];\n\n// Pre-computed log values for faster exponent calculation\nexport const LOG_2_1024 = Math.log(1024);\nexport const LOG_10_1000 = Math.log(1000);\n","import {\n\tARRAY,\n\tBINARY_POWERS,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tDECIMAL_POWERS,\n\tE,\n\tEMPTY,\n\tEXPONENT,\n\tIEC,\n\tJEDEC,\n\tOBJECT,\n\tPERIOD,\n\tSI,\n\tSTRINGS,\n\tZERO\n} from \"./constants.js\";\n\n// Cached configuration lookup for better performance\nconst STANDARD_CONFIGS = {\n\t[SI]: {isDecimal: true, ceil: 1000, actualStandard: JEDEC},\n\t[IEC]: {isDecimal: false, ceil: 1024, actualStandard: IEC},\n\t[JEDEC]: {isDecimal: false, ceil: 1024, actualStandard: JEDEC}\n};\n\n/**\n * Optimized base configuration lookup\n * @param {string} standard - Standard type\n * @param {number} base - Base number\n * @returns {Object} Configuration object\n */\nexport function getBaseConfiguration (standard, base) {\n\t// Use cached lookup table for better performance\n\tif (STANDARD_CONFIGS[standard]) {\n\t\treturn STANDARD_CONFIGS[standard];\n\t}\n\n\t// Base override\n\tif (base === 2) {\n\t\treturn {isDecimal: false, ceil: 1024, actualStandard: IEC};\n\t}\n\n\t// Default\n\treturn {isDecimal: true, ceil: 1000, actualStandard: JEDEC};\n}\n\n/**\n * Optimized zero value handling\n * @param {number} precision - Precision value\n * @param {string} actualStandard - Standard to use\n * @param {boolean} bits - Whether to use bits\n * @param {Object} symbols - Custom symbols\n * @param {boolean} full - Whether to use full form\n * @param {Array} fullforms - Custom full forms\n * @param {string} output - Output format\n * @param {string} spacer - Spacer character\n * @returns {string|Array|Object|number} Formatted result\n */\nexport function handleZeroValue (precision, actualStandard, bits, symbols, full, fullforms, output, spacer) {\n\tconst result = [];\n\tresult[0] = precision > 0 ? (0).toPrecision(precision) : 0;\n\tconst u = result[1] = STRINGS.symbol[actualStandard][bits ? BITS : BYTES][0];\n\n\tif (output === EXPONENT) {\n\t\treturn 0;\n\t}\n\n\t// Apply symbol customization\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply full form\n\tif (full) {\n\t\tresult[1] = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE);\n\t}\n\n\t// Return in requested format\n\treturn output === ARRAY ? result : output === OBJECT ? {\n\t\tvalue: result[0],\n\t\tsymbol: result[1],\n\t\texponent: 0,\n\t\tunit: u\n\t} : result.join(spacer);\n}\n\n/**\n * Optimized value calculation with bits handling\n * @param {number} num - Input number\n * @param {number} e - Exponent\n * @param {boolean} isDecimal - Whether to use decimal powers\n * @param {boolean} bits - Whether to calculate bits\n * @param {number} ceil - Ceiling value for auto-increment\n * @returns {Object} Object with val and e properties\n */\nexport function calculateOptimizedValue (num, e, isDecimal, bits, ceil) {\n\tconst d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e];\n\tlet result = num / d;\n\n\tif (bits) {\n\t\tresult *= 8;\n\t\t// Handle auto-increment for bits\n\t\tif (result >= ceil && e < 8) {\n\t\t\tresult /= ceil;\n\t\t\te++;\n\t\t}\n\t}\n\n\treturn {result, e};\n}\n\n/**\n * Optimized precision handling with scientific notation correction\n * @param {number} value - Current value\n * @param {number} precision - Precision to apply\n * @param {number} e - Current exponent\n * @param {number} num - Original number\n * @param {boolean} isDecimal - Whether using decimal base\n * @param {boolean} bits - Whether calculating bits\n * @param {number} ceil - Ceiling value\n * @param {Function} roundingFunc - Rounding function\n * @param {number} round - Round value\n * @returns {Object} Object with value and e properties\n */\nexport function applyPrecisionHandling (value, precision, e, num, isDecimal, bits, ceil, roundingFunc, round) {\n\tlet result = value.toPrecision(precision);\n\n\t// Handle scientific notation by recalculating with incremented exponent\n\tif (result.includes(E) && e < 8) {\n\t\te++;\n\t\tconst {result: valueResult} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\t\tconst p = round > 0 ? Math.pow(10, round) : 1;\n\t\tresult = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision(precision);\n\t}\n\n\treturn {value: result, e};\n}\n\n/**\n * Optimized number formatting with locale, separator, and padding\n * @param {number|string} value - Value to format\n * @param {string|boolean} locale - Locale setting\n * @param {Object} localeOptions - Locale options\n * @param {string} separator - Custom separator\n * @param {boolean} pad - Whether to pad\n * @param {number} round - Round value\n * @returns {string|number} Formatted value\n */\nexport function applyNumberFormatting (value, locale, localeOptions, separator, pad, round) {\n\tlet result = value;\n\n\t// Apply locale formatting\n\tif (locale === true) {\n\t\tresult = result.toLocaleString();\n\t} else if (locale.length > 0) {\n\t\tresult = result.toLocaleString(locale, localeOptions);\n\t} else if (separator.length > 0) {\n\t\tresult = result.toString().replace(PERIOD, separator);\n\t}\n\n\t// Apply padding\n\tif (pad && round > 0) {\n\t\tconst resultStr = result.toString();\n\t\tconst x = separator || ((resultStr.match(/(\\D)/g) || []).pop() || PERIOD);\n\t\tconst tmp = resultStr.split(x);\n\t\tconst s = tmp[1] || EMPTY;\n\t\tconst l = s.length;\n\t\tconst n = round - l;\n\n\t\tresult = `${tmp[0]}${x}${s.padEnd(l + n, ZERO)}`;\n\t}\n\n\treturn result;\n}\n","import {\n\tARRAY,\n\tBIT,\n\tBITS,\n\tBYTE,\n\tBYTES,\n\tEMPTY,\n\tEXPONENT,\n\tFUNCTION,\n\tINVALID_NUMBER,\n\tINVALID_ROUND,\n\tLOG_10_1000,\n\tLOG_2_1024,\n\tOBJECT,\n\tROUND,\n\tS,\n\tSI_KBIT,\n\tSI_KBYTE,\n\tSPACE,\n\tSTRING,\n\tSTRINGS,\n} from \"./constants.js\";\nimport {\n\tapplyNumberFormatting,\n\tapplyPrecisionHandling,\n\tcalculateOptimizedValue,\n\tgetBaseConfiguration,\n\thandleZeroValue\n} from \"./helpers.js\";\n\n/**\n * Converts a file size in bytes to a human-readable string with appropriate units\n * @param {number|string|bigint} arg - The file size in bytes to convert\n * @param {Object} [options={}] - Configuration options for formatting\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {string|Array|Object|number} Formatted file size based on output option\n * @throws {TypeError} When arg is not a valid number or roundingMethod is invalid\n * @example\n * filesize(1024) // \"1 KB\"\n * filesize(1024, {bits: true}) // \"8 Kb\"\n * filesize(1024, {output: \"object\"}) // {value: 1, symbol: \"KB\", exponent: 1, unit: \"KB\"}\n */\nexport function filesize (arg, {\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\tlet e = exponent,\n\t\tnum = Number(arg),\n\t\tresult = [],\n\t\tval = 0,\n\t\tu = EMPTY;\n\n\t// Optimized base & standard configuration lookup\n\tconst {isDecimal, ceil, actualStandard} = getBaseConfiguration(standard, base);\n\n\tconst full = fullform === true,\n\t\tneg = num < 0,\n\t\troundingFunc = Math[roundingMethod];\n\n\tif (typeof arg !== \"bigint\" && isNaN(arg)) {\n\t\tthrow new TypeError(INVALID_NUMBER);\n\t}\n\n\tif (typeof roundingFunc !== FUNCTION) {\n\t\tthrow new TypeError(INVALID_ROUND);\n\t}\n\n\t// Flipping a negative number to determine the size\n\tif (neg) {\n\t\tnum = -num;\n\t}\n\n\t// Fast path for zero\n\tif (num === 0) {\n\t\treturn handleZeroValue(precision, actualStandard, bits, symbols, full, fullforms, output, spacer);\n\t}\n\n\t// Optimized exponent calculation using pre-computed log values\n\tif (e === -1 || isNaN(e)) {\n\t\te = isDecimal ? Math.floor(Math.log(num) / LOG_10_1000) : Math.floor(Math.log(num) / LOG_2_1024);\n\t\tif (e < 0) {\n\t\t\te = 0;\n\t\t}\n\t}\n\n\t// Exceeding supported length, time to reduce & multiply\n\tif (e > 8) {\n\t\tif (precision > 0) {\n\t\t\tprecision += 8 - e;\n\t\t}\n\t\te = 8;\n\t}\n\n\tif (output === EXPONENT) {\n\t\treturn e;\n\t}\n\n\t// Calculate value with optimized lookup and bits handling\n\tconst {result: valueResult, e: valueExponent} = calculateOptimizedValue(num, e, isDecimal, bits, ceil);\n\tval = valueResult;\n\te = valueExponent;\n\n\t// Optimize rounding calculation\n\tconst p = e > 0 && round > 0 ? Math.pow(10, round) : 1;\n\tresult[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p;\n\n\tif (result[0] === ceil && e < 8 && exponent === -1) {\n\t\tresult[0] = 1;\n\t\te++;\n\t}\n\n\t// Apply precision handling\n\tif (precision > 0) {\n\t\tconst precisionResult = applyPrecisionHandling(result[0], precision, e, num, isDecimal, bits, ceil, roundingFunc, round);\n\t\tresult[0] = precisionResult.value;\n\t\te = precisionResult.e;\n\t}\n\n\t// Cache symbol lookup\n\tconst symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES];\n\tu = result[1] = (isDecimal && e === 1) ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e];\n\n\t// Decorating a 'diff'\n\tif (neg) {\n\t\tresult[0] = -result[0];\n\t}\n\n\t// Applying custom symbol\n\tif (symbols[result[1]]) {\n\t\tresult[1] = symbols[result[1]];\n\t}\n\n\t// Apply locale, separator, and padding formatting\n\tresult[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round);\n\n\tif (full) {\n\t\tresult[1] = fullforms[e] || STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S);\n\t}\n\n\t// Optimized return logic\n\tif (output === ARRAY) {\n\t\treturn result;\n\t}\n\n\tif (output === OBJECT) {\n\t\treturn {\n\t\t\tvalue: result[0],\n\t\t\tsymbol: result[1],\n\t\t\texponent: e,\n\t\t\tunit: u\n\t\t};\n\t}\n\n\treturn spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer);\n}\n\n/**\n * Creates a partially applied version of filesize with preset options\n * @param {Object} [options={}] - Default options to apply to the returned function\n * @param {boolean} [options.bits=false] - If true, calculates bits instead of bytes\n * @param {boolean} [options.pad=false] - If true, pads decimal places to match round parameter\n * @param {number} [options.base=-1] - Number base (2 for binary, 10 for decimal, -1 for auto)\n * @param {number} [options.round=2] - Number of decimal places to round to\n * @param {string|boolean} [options.locale=\"\"] - Locale for number formatting, true for system locale\n * @param {Object} [options.localeOptions={}] - Additional options for locale formatting\n * @param {string} [options.separator=\"\"] - Custom decimal separator\n * @param {string} [options.spacer=\" \"] - String to separate value and unit\n * @param {Object} [options.symbols={}] - Custom unit symbols\n * @param {string} [options.standard=\"\"] - Unit standard to use (SI, IEC, JEDEC)\n * @param {string} [options.output=\"string\"] - Output format: \"string\", \"array\", \"object\", or \"exponent\"\n * @param {boolean} [options.fullform=false] - If true, uses full unit names instead of abbreviations\n * @param {Array} [options.fullforms=[]] - Custom full unit names\n * @param {number} [options.exponent=-1] - Force specific exponent (-1 for auto)\n * @param {string} [options.roundingMethod=\"round\"] - Math rounding method to use\n * @param {number} [options.precision=0] - Number of significant digits (0 for auto)\n * @returns {Function} A function that takes a file size and returns formatted output\n * @example\n * const formatBytes = partial({round: 1, standard: \"IEC\"});\n * formatBytes(1024) // \"1.0 KiB\"\n * formatBytes(2048) // \"2.0 KiB\"\n */\n// Partial application for functional programming\nexport function partial ({\n\tbits = false,\n\tpad = false,\n\tbase = -1,\n\tround = 2,\n\tlocale = EMPTY,\n\tlocaleOptions = {},\n\tseparator = EMPTY,\n\tspacer = SPACE,\n\tsymbols = {},\n\tstandard = EMPTY,\n\toutput = STRING,\n\tfullform = false,\n\tfullforms = [],\n\texponent = -1,\n\troundingMethod = ROUND,\n\tprecision = 0\n} = {}) {\n\treturn arg => filesize(arg, {\n\t\tbits,\n\t\tpad,\n\t\tbase,\n\t\tround,\n\t\tlocale,\n\t\tlocaleOptions,\n\t\tseparator,\n\t\tspacer,\n\t\tsymbols,\n\t\tstandard,\n\t\toutput,\n\t\tfullform,\n\t\tfullforms,\n\t\texponent,\n\t\troundingMethod,\n\t\tprecision\n\t});\n}\n"],"names":["g","f","exports","module","define","amd","globalThis","self","filesize","this","IEC","JEDEC","SI","BITS","BYTE","BYTES","ARRAY","OBJECT","STRING","EXPONENT","ROUND","STRINGS","symbol","iec","bits","bytes","jedec","fullform","BINARY_POWERS","DECIMAL_POWERS","LOG_2_1024","Math","log","LOG_10_1000","STANDARD_CONFIGS","isDecimal","ceil","actualStandard","calculateOptimizedValue","num","e","result","arg","pad","base","round","locale","EMPTY","localeOptions","separator","spacer","symbols","standard","output","fullforms","exponent","roundingMethod","precision","Number","val","u","getBaseConfiguration","full","neg","roundingFunc","isNaN","TypeError","toPrecision","value","unit","join","handleZeroValue","floor","valueResult","valueExponent","p","pow","precisionResult","includes","applyPrecisionHandling","symbolTable","toLocaleString","length","toString","replace","resultStr","x","match","pop","tmp","split","s","l","n","padEnd","applyNumberFormatting","partial"],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f0319fd..8a08787 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,13 @@ "@rollup/plugin-terser": "^0.4.4", "auto-changelog": "^2.5.0", "c8": "^10.1.3", - "eslint": "^9.30.1", + "eslint": "^9.36.0", "husky": "^9.1.7", "mocha": "^11.7.1", - "rollup": "^4.44.2" + "rollup": "^4.52.0" }, "engines": { - "node": ">= 10.4.0" + "node": ">= 16.0.0" } }, "node_modules/@bcoe/v8-coverage": { @@ -136,9 +136,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", - "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", + "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", "dev": true, "license": "MIT", "engines": { @@ -351,9 +351,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.2.tgz", - "integrity": "sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.0.tgz", + "integrity": "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==", "cpu": [ "arm" ], @@ -365,9 +365,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.2.tgz", - "integrity": "sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.0.tgz", + "integrity": "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==", "cpu": [ "arm64" ], @@ -379,9 +379,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.2.tgz", - "integrity": "sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.0.tgz", + "integrity": "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==", "cpu": [ "arm64" ], @@ -393,9 +393,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.2.tgz", - "integrity": "sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.0.tgz", + "integrity": "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==", "cpu": [ "x64" ], @@ -407,9 +407,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.2.tgz", - "integrity": "sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.0.tgz", + "integrity": "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==", "cpu": [ "arm64" ], @@ -421,9 +421,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.2.tgz", - "integrity": "sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.0.tgz", + "integrity": "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==", "cpu": [ "x64" ], @@ -435,9 +435,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.2.tgz", - "integrity": "sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.0.tgz", + "integrity": "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==", "cpu": [ "arm" ], @@ -449,9 +449,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.2.tgz", - "integrity": "sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.0.tgz", + "integrity": "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==", "cpu": [ "arm" ], @@ -463,9 +463,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.2.tgz", - "integrity": "sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.0.tgz", + "integrity": "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==", "cpu": [ "arm64" ], @@ -477,9 +477,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.2.tgz", - "integrity": "sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.0.tgz", + "integrity": "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==", "cpu": [ "arm64" ], @@ -491,9 +491,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.50.2.tgz", - "integrity": "sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.0.tgz", + "integrity": "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==", "cpu": [ "loong64" ], @@ -505,9 +505,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.2.tgz", - "integrity": "sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.0.tgz", + "integrity": "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==", "cpu": [ "ppc64" ], @@ -519,9 +519,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.2.tgz", - "integrity": "sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.0.tgz", + "integrity": "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==", "cpu": [ "riscv64" ], @@ -533,9 +533,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.2.tgz", - "integrity": "sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.0.tgz", + "integrity": "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==", "cpu": [ "riscv64" ], @@ -547,9 +547,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.2.tgz", - "integrity": "sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.0.tgz", + "integrity": "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==", "cpu": [ "s390x" ], @@ -561,9 +561,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.2.tgz", - "integrity": "sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.0.tgz", + "integrity": "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==", "cpu": [ "x64" ], @@ -575,9 +575,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.2.tgz", - "integrity": "sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.0.tgz", + "integrity": "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==", "cpu": [ "x64" ], @@ -589,9 +589,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.2.tgz", - "integrity": "sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.0.tgz", + "integrity": "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==", "cpu": [ "arm64" ], @@ -603,9 +603,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.2.tgz", - "integrity": "sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.0.tgz", + "integrity": "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==", "cpu": [ "arm64" ], @@ -617,9 +617,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.2.tgz", - "integrity": "sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.0.tgz", + "integrity": "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==", "cpu": [ "ia32" ], @@ -630,10 +630,24 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.0.tgz", + "integrity": "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.2.tgz", - "integrity": "sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.0.tgz", + "integrity": "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==", "cpu": [ "x64" ], @@ -1107,9 +1121,9 @@ } }, "node_modules/eslint": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", - "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", + "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1119,7 +1133,7 @@ "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.35.0", + "@eslint/js": "9.36.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2180,9 +2194,9 @@ } }, "node_modules/rollup": { - "version": "4.50.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.2.tgz", - "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==", + "version": "4.52.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz", + "integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==", "dev": true, "license": "MIT", "dependencies": { @@ -2196,27 +2210,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.50.2", - "@rollup/rollup-android-arm64": "4.50.2", - "@rollup/rollup-darwin-arm64": "4.50.2", - "@rollup/rollup-darwin-x64": "4.50.2", - "@rollup/rollup-freebsd-arm64": "4.50.2", - "@rollup/rollup-freebsd-x64": "4.50.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.50.2", - "@rollup/rollup-linux-arm-musleabihf": "4.50.2", - "@rollup/rollup-linux-arm64-gnu": "4.50.2", - "@rollup/rollup-linux-arm64-musl": "4.50.2", - "@rollup/rollup-linux-loong64-gnu": "4.50.2", - "@rollup/rollup-linux-ppc64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-gnu": "4.50.2", - "@rollup/rollup-linux-riscv64-musl": "4.50.2", - "@rollup/rollup-linux-s390x-gnu": "4.50.2", - "@rollup/rollup-linux-x64-gnu": "4.50.2", - "@rollup/rollup-linux-x64-musl": "4.50.2", - "@rollup/rollup-openharmony-arm64": "4.50.2", - "@rollup/rollup-win32-arm64-msvc": "4.50.2", - "@rollup/rollup-win32-ia32-msvc": "4.50.2", - "@rollup/rollup-win32-x64-msvc": "4.50.2", + "@rollup/rollup-android-arm-eabi": "4.52.0", + "@rollup/rollup-android-arm64": "4.52.0", + "@rollup/rollup-darwin-arm64": "4.52.0", + "@rollup/rollup-darwin-x64": "4.52.0", + "@rollup/rollup-freebsd-arm64": "4.52.0", + "@rollup/rollup-freebsd-x64": "4.52.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", + "@rollup/rollup-linux-arm-musleabihf": "4.52.0", + "@rollup/rollup-linux-arm64-gnu": "4.52.0", + "@rollup/rollup-linux-arm64-musl": "4.52.0", + "@rollup/rollup-linux-loong64-gnu": "4.52.0", + "@rollup/rollup-linux-ppc64-gnu": "4.52.0", + "@rollup/rollup-linux-riscv64-gnu": "4.52.0", + "@rollup/rollup-linux-riscv64-musl": "4.52.0", + "@rollup/rollup-linux-s390x-gnu": "4.52.0", + "@rollup/rollup-linux-x64-gnu": "4.52.0", + "@rollup/rollup-linux-x64-musl": "4.52.0", + "@rollup/rollup-openharmony-arm64": "4.52.0", + "@rollup/rollup-win32-arm64-msvc": "4.52.0", + "@rollup/rollup-win32-ia32-msvc": "4.52.0", + "@rollup/rollup-win32-x64-gnu": "4.52.0", + "@rollup/rollup-win32-x64-msvc": "4.52.0", "fsevents": "~2.3.2" } }, diff --git a/package.json b/package.json index beb20b8..01269ce 100644 --- a/package.json +++ b/package.json @@ -29,17 +29,24 @@ "sourceType": "module", "types": "types/filesize.d.ts", "engines": { - "node": ">= 10.4.0" + "node": ">= 16.0.0" }, "scripts": { "build": "npm run rollup", + "build:watch": "rollup --config --watch", + "build:analyze": "npm run rollup && npm run analyze:size", + "analyze:size": "echo 'Bundle size analysis:' && du -h dist/* && echo 'Gzipped sizes:' && gzip -c dist/filesize.min.js | wc -c | awk '{print $1\" bytes (gzipped)\"}' && gzip -c dist/filesize.umd.min.js | wc -c | awk '{print $1\" bytes (umd gzipped)\"}'", "changelog": "auto-changelog -p", "lint": "eslint *.js src/*.js tests/**/*.js", - "fix": "eslint --fix *.js src/*.js tests/**/*.js", + "lint:fix": "eslint --fix *.js src/*.js tests/**/*.js", + "fix": "npm run lint:fix", "mocha": "c8 mocha tests/**/*.js", "rollup": "rollup --config", "test": "npm run lint && npm run mocha", + "test:watch": "npm run mocha -- --watch", + "prepack": "npm run build", "prepare": "husky", + "dev": "npm run build:watch", "benchmark": "node benchmarks/index.js", "benchmark:basic": "node benchmarks/basic-performance.js", "benchmark:options": "node benchmarks/options-benchmark.js", @@ -51,10 +58,10 @@ "@rollup/plugin-terser": "^0.4.4", "auto-changelog": "^2.5.0", "c8": "^10.1.3", - "eslint": "^9.30.1", + "eslint": "^9.36.0", "husky": "^9.1.7", "mocha": "^11.7.1", - "rollup": "^4.44.2" + "rollup": "^4.52.0" }, "keywords": [ "file", diff --git a/rollup.config.js b/rollup.config.js index e38fe0d..4466f56 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,8 +1,10 @@ import terser from "@rollup/plugin-terser"; import { createRequire } from "node:module"; + const require = createRequire(import.meta.url); const pkg = require("./package.json"); const year = new Date().getFullYear(); + const bannerLong = `/** * ${pkg.name} * @@ -10,20 +12,82 @@ const bannerLong = `/** * @license ${pkg.license} * @version ${pkg.version} */`; + const bannerShort = `/*! ${year} ${pkg.author} @version ${pkg.version} */`; -const defaultOutBase = {compact: true, banner: bannerLong, name: pkg.name}; -const cjOutBase = {...defaultOutBase, compact: false, format: "cjs", exports: "named"}; -const esmOutBase = {...defaultOutBase, format: "esm"}; -const umdOutBase = {...defaultOutBase, format: "umd"}; -const minOutBase = {banner: bannerShort, name: pkg.name, plugins: [terser()], sourcemap: true}; + +// Optimized terser configuration for better compression +const terserOptions = { + compress: { + passes: 2, + drop_console: false, + drop_debugger: true, + pure_funcs: ['console.log'], + unsafe_arrows: true, + unsafe_methods: true + }, + mangle: { + properties: { + regex: /^_/ + } + }, + format: { + comments: "some" + } +}; + +const defaultOutBase = { + compact: true, + banner: bannerLong, + name: pkg.name, + generatedCode: { + constBindings: true, + arrowFunctions: true, + objectShorthand: true + } +}; + +const cjOutBase = { + ...defaultOutBase, + compact: false, + format: "cjs", + exports: "named", + interop: "compat" +}; + +const esmOutBase = { + ...defaultOutBase, + format: "esm" +}; + +const umdOutBase = { + ...defaultOutBase, + format: "umd" +}; + +const minOutBase = { + banner: bannerShort, + name: pkg.name, + plugins: [terser(terserOptions)], + sourcemap: true, + generatedCode: { + constBindings: true, + arrowFunctions: true, + objectShorthand: true + } +}; export default [ { input: "./src/filesize.js", + treeshake: { + moduleSideEffects: false, + propertyReadSideEffects: false, + unknownGlobalSideEffects: false + }, output: [ { ...cjOutBase, From d344092cfe82473366d8b4a391f517c11e265352 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:40:07 -0400 Subject: [PATCH 05/12] Reverting an erroneous change --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a08787..21f21c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "rollup": "^4.52.0" }, "engines": { - "node": ">= 16.0.0" + "node": ">= 10.4.0" } }, "node_modules/@bcoe/v8-coverage": { diff --git a/package.json b/package.json index 01269ce..6eb0af7 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "sourceType": "module", "types": "types/filesize.d.ts", "engines": { - "node": ">= 16.0.0" + "node": ">= 10.4.0" }, "scripts": { "build": "npm run rollup", From af3b8bea2268ec6ff87a063daa70194cab6c20d6 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:43:11 -0400 Subject: [PATCH 06/12] Fixing the engine.value for stable BigInt --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21f21c2..eb4f820 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "rollup": "^4.52.0" }, "engines": { - "node": ">= 10.4.0" + "node": ">= 10.8.0" } }, "node_modules/@bcoe/v8-coverage": { diff --git a/package.json b/package.json index 6eb0af7..b5cf20d 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "sourceType": "module", "types": "types/filesize.d.ts", "engines": { - "node": ">= 10.4.0" + "node": ">= 10.8.0" }, "scripts": { "build": "npm run rollup", From e14aa06f20fd245723e90a58fc0d04b813c70744 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:50:09 -0400 Subject: [PATCH 07/12] Updating documentation --- docs/TECHNICAL_DOCUMENTATION.md | 130 ++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 73 insertions(+), 59 deletions(-) diff --git a/docs/TECHNICAL_DOCUMENTATION.md b/docs/TECHNICAL_DOCUMENTATION.md index 7ec927e..6c9edbe 100644 --- a/docs/TECHNICAL_DOCUMENTATION.md +++ b/docs/TECHNICAL_DOCUMENTATION.md @@ -283,78 +283,85 @@ flowchart TD Start([Input: bytes, options]) --> Validate{Valid Input?} Validate -->|No| Error[Throw TypeError] - Validate -->|Yes| Normalize[Normalize Base & Standard] + Validate -->|Yes| ValidateRounding{Valid Rounding Method?} - Normalize --> CalcExp[Calculate Exponent] - CalcExp --> CheckExp{Exponent > 8?} - CheckExp -->|Yes| LimitExp[Limit to 8, Adjust Precision] - CheckExp -->|No| CheckZero{Input = 0?} - LimitExp --> CheckZero + ValidateRounding -->|No| Error + ValidateRounding -->|Yes| Normalize[Normalize Base & Standard] + + Normalize --> HandleNegative{Input < 0?} + HandleNegative -->|Yes| FlipSign[Store negative flag, use absolute value] + HandleNegative -->|No| CheckZero{Input = 0?} + FlipSign --> CheckZero - CheckZero -->|Yes| ZeroCase[Set result = 0, unit = base unit] - CheckZero -->|No| Convert[Convert Value & Calculate Unit] + CheckZero -->|Yes| ZeroCase[Use handleZeroValue helper] + CheckZero -->|No| CalcExp[Calculate Exponent using logarithms] - Convert --> CheckBits{Bits Mode?} - CheckBits -->|Yes| MultiplyBy8[Multiply by 8] - CheckBits -->|No| Round[Apply Rounding] - MultiplyBy8 --> Round + CalcExp --> CheckExp{Exponent > 8?} + CheckExp -->|Yes| LimitExp[Limit to 8, Adjust Precision] + CheckExp -->|No| CheckExpOutput{Output = 'exponent'?} + LimitExp --> CheckExpOutput - Round --> CheckOverflow{Value >= ceil?} - CheckOverflow -->|Yes| Increment[Increment Exponent] - CheckOverflow -->|No| Format[Apply Formatting] - Increment --> Format + CheckExpOutput -->|Yes| ReturnExp[Return exponent value] + CheckExpOutput -->|No| CalcValue[Calculate value using optimized lookup
Includes bits conversion if needed] - ZeroCase --> Format + CalcValue --> Round[Apply Rounding with power of 10] + Round --> CheckOverflow{Value >= ceil & e < 8?} + CheckOverflow -->|Yes| Increment[Set value=1, increment exponent] + CheckOverflow -->|No| CheckPrecision{Precision > 0?} + Increment --> CheckPrecision - Format --> Locale{Locale Set?} - Locale -->|Yes| LocaleFormat[Apply Locale Formatting] - Locale -->|No| Separator{Custom Separator?} - LocaleFormat --> Padding - Separator -->|Yes| CustomSep[Apply Custom Separator] - Separator -->|No| Padding{Padding Enabled?} - CustomSep --> Padding + CheckPrecision -->|Yes| ApplyPrecision[Apply precision handling
Handle scientific notation] + CheckPrecision -->|No| GetSymbol[Lookup symbol from table] + ApplyPrecision --> GetSymbol - Padding -->|Yes| PadDecimal[Pad Decimal Places] - Padding -->|No| FullForm{Full Form?} - PadDecimal --> FullForm + GetSymbol --> RestoreSign{Was negative?} + RestoreSign -->|Yes| ApplyNegative[Apply negative sign to value] + RestoreSign -->|No| CheckCustomSymbols{Custom symbols?} + ApplyNegative --> CheckCustomSymbols - FullForm -->|Yes| ExpandUnit[Use Full Unit Names] - FullForm -->|No| CustomSymbols{Custom Symbols?} - ExpandUnit --> CustomSymbols + CheckCustomSymbols -->|Yes| ApplySymbols[Apply custom symbols] + CheckCustomSymbols -->|No| FormatNumber[Apply number formatting
locale, separator, padding] + ApplySymbols --> FormatNumber - CustomSymbols -->|Yes| ApplySymbols[Apply Custom Symbols] - CustomSymbols -->|No| Output[Generate Output] - ApplySymbols --> Output + FormatNumber --> CheckFullForm{Full form enabled?} + CheckFullForm -->|Yes| ExpandUnit[Use full unit names] + CheckFullForm -->|No| GenerateOutput[Generate output based on format] + ExpandUnit --> GenerateOutput - Output --> Return([Return: Formatted Result]) + ZeroCase --> GenerateOutput + ReturnExp --> Return([Return: Formatted Result]) + GenerateOutput --> Return style Start fill:#166534,stroke:#15803d,stroke-width:2px,color:#ffffff style Error fill:#dc2626,stroke:#b91c1c,stroke-width:2px,color:#ffffff style Return fill:#1e40af,stroke:#1e3a8a,stroke-width:2px,color:#ffffff + style CalcValue fill:#7c2d12,stroke:#92400e,stroke-width:2px,color:#ffffff + style ApplyPrecision fill:#d97706,stroke:#b45309,stroke-width:2px,color:#ffffff ``` ### Standard Selection Logic ```mermaid flowchart TD - Input[Input: standard, base] --> CheckStandard{Standard = SI?} + Input[Input: standard, base] --> CheckCached{Standard in
cached configs?} - CheckStandard -->|Yes| SetDecimal[base = 10
standard = JEDEC] - CheckStandard -->|No| CheckIEC{Standard = IEC or JEDEC?} + CheckCached -->|Yes: SI| ReturnSI[isDecimal: true
ceil: 1000
actualStandard: JEDEC] + CheckCached -->|Yes: IEC| ReturnIEC[isDecimal: false
ceil: 1024
actualStandard: IEC] + CheckCached -->|Yes: JEDEC| ReturnJEDEC[isDecimal: false
ceil: 1024
actualStandard: JEDEC] + CheckCached -->|No| CheckBase{Base = 2?} - CheckIEC -->|Yes| SetBinary[base = 2] - CheckIEC -->|No| CheckBase{Base = 2?} + CheckBase -->|Yes| ReturnBase2[isDecimal: false
ceil: 1024
actualStandard: IEC] + CheckBase -->|No| ReturnDefault[isDecimal: true
ceil: 1000
actualStandard: JEDEC] - CheckBase -->|Yes| SetIEC[standard = IEC] - CheckBase -->|No| SetDefault[base = 10
standard = JEDEC] - - SetDecimal --> Result[Final: base, standard] - SetBinary --> Result - SetIEC --> Result - SetDefault --> Result + ReturnSI --> Result[Final Configuration] + ReturnIEC --> Result + ReturnJEDEC --> Result + ReturnBase2 --> Result + ReturnDefault --> Result style Input fill:#166534,stroke:#15803d,stroke-width:2px,color:#ffffff style Result fill:#1e40af,stroke:#1e3a8a,stroke-width:2px,color:#ffffff + style CheckCached fill:#7c2d12,stroke:#92400e,stroke-width:2px,color:#ffffff ``` ## API Reference @@ -755,23 +762,30 @@ export function SystemMetrics() { ```mermaid graph TB subgraph "Locale Processing" - A["Input Locale"] --> B{"Locale Type"} - B -->|"true"| C["System Locale"] - B -->|"string"| D["Specific Locale"] - B -->|"empty"| E["No Localization"] + A["Input: value, locale, localeOptions, separator, pad, round"] --> B{"Locale === true?"} + B -->|"Yes"| C["toLocaleString()"] + B -->|"No"| D{"Locale.length > 0?"} + + D -->|"Yes"| E["toLocaleString(locale, localeOptions)"] + D -->|"No"| F{"Separator.length > 0?"} + + F -->|"Yes"| G["toString().replace('.', separator)"] + F -->|"No"| H["Keep original value"] - C --> F["navigator.language"] - D --> G["Custom Locale"] - F --> H["toLocaleString()"] - G --> H + C --> I["Check Padding"] + E --> I + G --> I + H --> I - H --> I["Formatted Number"] - E --> J["toString()"] - J --> K["Apply Custom Separator"] + I --> J{"Pad enabled & round > 0?"} + J -->|"Yes"| K["Calculate decimal separator
Pad decimal places with zeros"] + J -->|"No"| L["Return formatted value"] + + K --> L end style A fill:#166534,stroke:#15803d,stroke-width:2px,color:#ffffff - style I fill:#1e40af,stroke:#1e3a8a,stroke-width:2px,color:#ffffff + style L fill:#1e40af,stroke:#1e3a8a,stroke-width:2px,color:#ffffff style K fill:#d97706,stroke:#b45309,stroke-width:2px,color:#ffffff ``` diff --git a/package.json b/package.json index b5cf20d..980c0b7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "module": "dist/filesize.js", "main": "dist/filesize.cjs", "exports": { - "types": "./types/filesize.d.ts", + "types": "./types", "import": "./dist/filesize.js", "require": "./dist/filesize.cjs" }, From b77d0c9c03fd0cf70a2366721d4318074b7fd6fc Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 08:54:46 -0400 Subject: [PATCH 08/12] Updating documentation --- docs/TECHNICAL_DOCUMENTATION.md | 89 +++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/docs/TECHNICAL_DOCUMENTATION.md b/docs/TECHNICAL_DOCUMENTATION.md index 6c9edbe..3bd280c 100644 --- a/docs/TECHNICAL_DOCUMENTATION.md +++ b/docs/TECHNICAL_DOCUMENTATION.md @@ -106,14 +106,18 @@ The filesize.js library implements several mathematical algorithms to convert ra The basic conversion from bytes to higher-order units follows the general formula: ```math -\text{value} = \frac{\text{bytes}}{\text{base}^{\text{exponent}}} +\text{value} = \frac{\text{bytes}}{\text{divisor}[\text{exponent}]} ``` Where: - $\text{bytes}$ is the input byte value -- $\text{base}$ is either 2 (binary) or 10 (decimal) depending on the standard +- $\text{divisor}[\text{exponent}]$ is a pre-computed lookup table value - $\text{exponent}$ determines the unit scale (0=bytes, 1=KB/KiB, 2=MB/MiB, etc.) +**Implementation Note**: For performance optimization, the library uses pre-computed lookup tables (`BINARY_POWERS` and `DECIMAL_POWERS`) instead of calculating powers at runtime: +- Binary: `[1, 1024, 1048576, 1073741824, ...]` (powers of 1024) +- Decimal: `[1, 1000, 1000000, 1000000000, ...]` (powers of 1000) + ### Exponent Calculation The appropriate exponent for automatic unit selection is calculated using logarithms: @@ -137,32 +141,47 @@ Where: ### Binary vs Decimal Standards #### Binary Standard (IEC) -Uses powers of 2 with base 1024: +Uses pre-computed powers of 1024: ```math -\text{value} = \frac{\text{bytes}}{2^{10 \cdot e}} = \frac{\text{bytes}}{1024^e} +\text{value} = \frac{\text{bytes}}{\text{BINARY\_POWERS}[e]} ``` +Where `BINARY_POWERS[e] = 1024^e` for efficiency. + Units: B, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB -#### Decimal Standard (SI) -Uses powers of 10 with base 1000: +#### Decimal Standard (SI/JEDEC) +Uses pre-computed powers of 1000: ```math -\text{value} = \frac{\text{bytes}}{10^{3 \cdot e}} = \frac{\text{bytes}}{1000^e} +\text{value} = \frac{\text{bytes}}{\text{DECIMAL\_POWERS}[e]} ``` +Where `DECIMAL_POWERS[e] = 1000^e` for efficiency. + Units: B, KB, MB, GB, TB, PB, EB, ZB, YB (uses JEDEC-style symbols) ### Bits Conversion -When converting to bits instead of bytes, the formula becomes: +When converting to bits instead of bytes, the implementation follows this sequence: +1. First calculate the base value: $\text{value} = \frac{\text{bytes}}{\text{divisor}[e]}$ +2. Then multiply by 8: $\text{value}_{\text{bits}} = \text{value} \times 8$ +3. Check for overflow and auto-increment if needed + +**Bits-Specific Overflow Handling**: ```math -\text{value}_{\text{bits}} = \frac{8 \cdot \text{bytes}}{\text{base}^e} +\text{if } \text{value}_{\text{bits}} \geq \text{ceil} \text{ and } e < 8 \text{ then:} +``` +```math +\begin{cases} +\text{value}_{\text{bits}} = \frac{\text{value}_{\text{bits}}}{\text{ceil}} \\ +e = e + 1 +\end{cases} ``` -This multiplication by 8 reflects the conversion from bytes to bits (1 byte = 8 bits). +This ensures proper unit progression for bit values (e.g., 8192 Kbit becomes 8 Mbit). ### Precision and Rounding @@ -182,14 +201,23 @@ When precision is specified ($p > 0$), the value is adjusted to show $p$ signifi \text{precise\_value} = \text{toPrecision}(\text{rounded\_value}, p) ``` -The precision parameter takes precedence over round when both are specified. If scientific notation results (contains 'E'), the exponent is incremented and the calculation is repeated to avoid exponential notation in output. +**Scientific Notation Avoidance**: If the precision formatting results in scientific notation (contains 'E') and $e < 8$, the algorithm: +1. Increments the exponent: $e = e + 1$ +2. Recalculates the value using the new exponent +3. Re-applies rounding and precision formatting +4. This ensures output remains in standard decimal notation + +The precision parameter takes precedence over round when both are specified. ### Overflow Handling -When a calculated value equals or exceeds the base threshold, the algorithm increments the exponent: +The library implements two distinct overflow handling mechanisms: + +#### 1. Main Flow Overflow (After Rounding) +When the rounded value exactly equals the ceiling value: ```math -\text{if } \text{value} \geq \text{base} \text{ and } e < 8 \text{ then:} +\text{if } \text{value} = \text{ceil} \text{ and } e < 8 \text{ and } \text{exponent} = -1 \text{ then:} ``` ```math \begin{cases} @@ -198,7 +226,22 @@ e = e + 1 \end{cases} ``` -This ensures proper unit progression (e.g., 1024 KB becomes 1 MB). +**Note**: This only applies when exponent is auto-calculated (`exponent = -1`), not when manually specified. + +#### 2. Bits-Specific Overflow (During Value Calculation) +For bits conversion, overflow is checked immediately after multiplication: + +```math +\text{if } \text{value}_{\text{bits}} \geq \text{ceil} \text{ and } e < 8 \text{ then:} +``` +```math +\begin{cases} +\text{value}_{\text{bits}} = \frac{\text{value}_{\text{bits}}}{\text{ceil}} \\ +e = e + 1 +\end{cases} +``` + +Both mechanisms ensure proper unit progression (e.g., 1024 KB becomes 1 MB). ### Exponent Boundary Conditions @@ -245,19 +288,21 @@ The algorithmic complexity of the conversion process is: ### Implementation Examples #### Default Conversion (1536 bytes) -Given: bytes = 1536, default settings (base = 10, JEDEC standard) +Given: bytes = 1536, default settings (decimal, JEDEC standard) -1. Calculate exponent: $e = \lfloor \log_{1000}(1536) \rfloor = \lfloor 1.062 \rfloor = 1$ -2. Calculate value: $\text{value} = \frac{1536}{1000^1} = 1.536$ -3. Apply rounding (2 decimal places): $1.536 \rightarrow 1.54$ -4. Result: "1.54 kB" +1. Calculate exponent: $e = \lfloor \frac{\ln(1536)}{\ln(1000)} \rfloor = \lfloor 1.062 \rfloor = 1$ +2. Lookup divisor: $\text{DECIMAL\_POWERS}[1] = 1000$ +3. Calculate value: $\text{value} = \frac{1536}{1000} = 1.536$ +4. Apply rounding (2 decimal places): $1.536 \rightarrow 1.54$ +5. Result: "1.54 KB" #### Binary Conversion (1536 bytes) Given: bytes = 1536, base = 2 (IEC standard) -1. Calculate exponent: $e = \lfloor \log_{1024}(1536) \rfloor = \lfloor 1.084 \rfloor = 1$ -2. Calculate value: $\text{value} = \frac{1536}{1024^1} = 1.5$ -3. Result: "1.5 KiB" +1. Calculate exponent: $e = \lfloor \frac{\ln(1536)}{\ln(1024)} \rfloor = \lfloor 1.084 \rfloor = 1$ +2. Lookup divisor: $\text{BINARY\_POWERS}[1] = 1024$ +3. Calculate value: $\text{value} = \frac{1536}{1024} = 1.5$ +4. Result: "1.5 KiB" #### Bits Conversion with Default Base (1024 bytes) Given: bytes = 1024, bits = true, default settings (base = 10) From ecf6b0c061b7829a54c7b3971ee182be3d00dc6e Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 09:00:12 -0400 Subject: [PATCH 09/12] Updating README.md benchmarks --- README.md | 80 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 704f577..8006fe5 100644 --- a/README.md +++ b/README.md @@ -125,62 +125,70 @@ filesize.js is optimized for high performance with comprehensive benchmarks cove | Scenario | Operations/sec | Notes | |----------|----------------|-------| -| **Basic conversion** | ~10-12M ops/sec | Fastest operations (small numbers) | -| **Large numbers** | ~10-11M ops/sec | Consistent performance | -| **With options** | ~4-9M ops/sec | Depends on option complexity | -| **Locale formatting** | ~85K ops/sec | Most expensive operation | -| **Partial functions** | ~6-8M ops/sec | ~10-20% overhead, amortized | +| **Basic conversion** | ~16-27M ops/sec | Fastest operations (large numbers) | +| **Small numbers** | ~18-20M ops/sec | Consistent performance | +| **With options** | ~5-13M ops/sec | Depends on option complexity | +| **Locale formatting** | ~91K ops/sec | Most expensive operation | +| **Stress testing** | ~2-10M ops/sec | Handles edge cases gracefully | ### 📊 Detailed Benchmark Results -#### Basic Performance (5-run average, excluding outliers) -- **filesize(0)**: 10.1M ops/sec -- **filesize(512)**: 12.3M ops/sec -- **filesize(1024)**: 10.2M ops/sec -- **filesize(1MB)**: 11.3M ops/sec -- **filesize(1GB)**: 11.1M ops/sec -- **With bits=true**: 9.3M ops/sec -- **With standard="iec"**: 9.6M ops/sec -- **With fullform=true**: 4.4M ops/sec -- **Object output**: 5.1M ops/sec +#### Basic Performance (5-run average) +- **filesize(0)**: 18.6M ops/sec +- **filesize(512)**: 20.3M ops/sec +- **filesize(1024)**: 18.7M ops/sec +- **filesize(1MB)**: 23.5M ops/sec +- **filesize(1GB)**: 23.6M ops/sec +- **filesize(1TB)**: 26.9M ops/sec +- **With bits=true**: 16.8M ops/sec +- **With standard="iec"**: 16.6M ops/sec +- **With round=4**: 13.4M ops/sec #### Options Performance Impact -- **Default options**: 6.4M ops/sec (baseline) -- **bits=true**: 1.66x slower -- **pad=true**: 2.74x slower -- **locale="en-US"**: 75x slower (significant overhead) -- **standard="iec"**: 1.12x slower -- **output="object"**: 0.96x faster -- **Complex combinations**: 1.6-2.1x slower +- **bits=true**: 12.5M ops/sec +- **pad=true**: 5.6M ops/sec +- **locale="en-US"**: 91K ops/sec (significant overhead) +- **standard="iec"**: 8.8M ops/sec +- **standard="jedec"**: 9.0M ops/sec +- **output="array"**: 10.2M ops/sec +- **output="object"**: 9.2M ops/sec +- **fullform=true**: 7.8M ops/sec +- **precision=3**: 6.3M ops/sec +- **separator=","**: 7.2M ops/sec #### Stress Test Results -- **Edge cases**: 2.0M ops/sec (90% success rate) -- **Very large numbers**: 3.7M ops/sec (100% success) -- **BigInt values**: 2.8M ops/sec (100% success) -- **Memory pressure**: 48K ops/sec (100% success) -- **Performance consistency**: 84.7% (10 runs average) +- **Edge cases**: 2.3M ops/sec (90% success rate) +- **Very large numbers**: 4.6M ops/sec (100% success) +- **Very small numbers**: 10.4M ops/sec (100% success) +- **Negative numbers**: 5.4M ops/sec (100% success) +- **Random options**: 2.3M ops/sec (100% success) +- **BigInt values**: 3.7M ops/sec (100% success) +- **Memory pressure**: 49K ops/sec (100% success) +- **Error conditions**: 715K ops/sec (~40% success rate) #### Partial Function Performance -- **Direct calls**: 8.0M ops/sec (baseline) -- **Simple partial**: 6.7M ops/sec (1.20x slower) -- **Complex partial**: 5.6M ops/sec (1.42x slower) -- **Partial with locale**: 84K ops/sec (95x slower) +Partial functions maintain excellent performance with minimal overhead: +- **Acceptable overhead**: 1.1-1.4x slower for most configurations +- **Locale partials**: Significant overhead (~180x slower) due to locale formatting +- **Creation cost**: Amortized across multiple uses ### 💡 Performance Insights -**Excellent Performance (>1M ops/sec)** +**Excellent Performance (>10M ops/sec)** - Basic conversions with minimal options +- Large number processing (1TB+ values) - Standard output formats (string, array, object) - IEC and JEDEC standards -**Good Performance (100K-1M ops/sec)** +**Good Performance (1-10M ops/sec)** - Complex option combinations - Precision and rounding operations - Fullform output +- Stress test scenarios **Use Sparingly (<100K ops/sec)** -- Locale formatting (significant overhead) -- Complex locale configurations +- Locale formatting (significant overhead ~91K ops/sec) +- Memory pressure conditions ### 🎯 Optimization Tips @@ -215,7 +223,7 @@ The latest version includes significant performance improvements: **Overall performance improvement: 30-70% faster** across common use cases while maintaining full backward compatibility. -*Benchmarks run on macOS ARM64, Node.js v23.10.0, 12 CPU cores, 24GB RAM* +*Benchmarks run on macOS ARM64, Node.js v24.8.0, 12 CPU cores, 24GB RAM (5-run averages)* ## API Reference From 7102c481762a91e2f4d26b3d03edda671c41bc73 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 09:09:33 -0400 Subject: [PATCH 10/12] Updating documentation --- docs/TECHNICAL_DOCUMENTATION.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/TECHNICAL_DOCUMENTATION.md b/docs/TECHNICAL_DOCUMENTATION.md index 3bd280c..963856a 100644 --- a/docs/TECHNICAL_DOCUMENTATION.md +++ b/docs/TECHNICAL_DOCUMENTATION.md @@ -291,32 +291,32 @@ The algorithmic complexity of the conversion process is: Given: bytes = 1536, default settings (decimal, JEDEC standard) 1. Calculate exponent: $e = \lfloor \frac{\ln(1536)}{\ln(1000)} \rfloor = \lfloor 1.062 \rfloor = 1$ -2. Lookup divisor: $\text{DECIMAL\_POWERS}[1] = 1000$ -3. Calculate value: $\text{value} = \frac{1536}{1000} = 1.536$ -4. Apply rounding (2 decimal places): $1.536 \rightarrow 1.54$ +2. Lookup divisor: DECIMAL_POWERS[1] = 1000 +3. Calculate value: $value = \frac{1536}{1000} = 1.536$ +4. Apply rounding (2 decimal places): $1.536 \to 1.54$ 5. Result: "1.54 KB" #### Binary Conversion (1536 bytes) Given: bytes = 1536, base = 2 (IEC standard) 1. Calculate exponent: $e = \lfloor \frac{\ln(1536)}{\ln(1024)} \rfloor = \lfloor 1.084 \rfloor = 1$ -2. Lookup divisor: $\text{BINARY\_POWERS}[1] = 1024$ -3. Calculate value: $\text{value} = \frac{1536}{1024} = 1.5$ +2. Lookup divisor: BINARY_POWERS[1] = 1024 +3. Calculate value: $value = \frac{1536}{1024} = 1.5$ 4. Result: "1.5 KiB" #### Bits Conversion with Default Base (1024 bytes) Given: bytes = 1024, bits = true, default settings (base = 10) -1. Calculate exponent: $e = \lfloor \log_{1000}(1024) \rfloor = \lfloor 1.003 \rfloor = 1$ -2. Calculate value: $\text{value} = \frac{1024 \cdot 8}{1000^1} = 8.192$ -3. Apply rounding (2 decimal places): $8.192 \rightarrow 8.19$ +1. Calculate exponent: $e = \lfloor \frac{\ln(1024)}{\ln(1000)} \rfloor = \lfloor 1.003 \rfloor = 1$ +2. Calculate value: $value = \frac{1024 \times 8}{1000} = 8.192$ +3. Apply rounding (2 decimal places): $8.192 \to 8.19$ 4. Result: "8.19 kbit" #### Bits Conversion with Binary Base (1024 bytes) Given: bytes = 1024, bits = true, base = 2 -1. Calculate exponent: $e = \lfloor \log_{1024}(1024) \rfloor = 1$ -2. Calculate value: $\text{value} = \frac{1024 \cdot 8}{1024^1} = 8$ +1. Calculate exponent: $e = \lfloor \frac{\ln(1024)}{\ln(1024)} \rfloor = 1$ +2. Calculate value: $value = \frac{1024 \times 8}{1024} = 8$ 3. Result: "8 Kibit" ## Data Flow From 49893eb94dbe958bc2d26af6473c43e2dbd654d3 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 09:12:54 -0400 Subject: [PATCH 11/12] Updating types files --- types/constants.d.ts | 32 ++++++++++- types/helpers.d.ts | 123 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 types/helpers.d.ts diff --git a/types/constants.d.ts b/types/constants.d.ts index 4da91d1..4b9e9c4 100644 --- a/types/constants.d.ts +++ b/types/constants.d.ts @@ -26,6 +26,7 @@ export const EXPONENT: "exponent"; export const ROUND: "round"; // Special Characters and Values +export const E: "e"; export const EMPTY: ""; export const PERIOD: "."; export const S: "s"; @@ -48,4 +49,33 @@ export const STRINGS: { iec: ["", "kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"]; jedec: ["", "kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta"]; }; -}; \ No newline at end of file +}; + +// Pre-computed lookup tables for performance optimization +export const BINARY_POWERS: readonly [ + 1, // 2^0 + 1024, // 2^10 + 1048576, // 2^20 + 1073741824, // 2^30 + 1099511627776, // 2^40 + 1125899906842624, // 2^50 + 1152921504606846976, // 2^60 + 1180591620717411303424, // 2^70 + 1208925819614629174706176 // 2^80 +]; + +export const DECIMAL_POWERS: readonly [ + 1, // 10^0 + 1000, // 10^3 + 1000000, // 10^6 + 1000000000, // 10^9 + 1000000000000, // 10^12 + 1000000000000000, // 10^15 + 1000000000000000000, // 10^18 + 1000000000000000000000, // 10^21 + 1000000000000000000000000 // 10^24 +]; + +// Pre-computed log values for faster exponent calculation +export const LOG_2_1024: number; +export const LOG_10_1000: number; \ No newline at end of file diff --git a/types/helpers.d.ts b/types/helpers.d.ts new file mode 100644 index 0000000..3c10088 --- /dev/null +++ b/types/helpers.d.ts @@ -0,0 +1,123 @@ +/** + * Configuration object returned by getBaseConfiguration + */ +export interface BaseConfiguration { + /** Whether to use decimal (base 10) calculations */ + isDecimal: boolean; + /** Ceiling value for auto-increment calculations */ + ceil: number; + /** The actual standard to use for formatting */ + actualStandard: string; +} + +/** + * Value calculation result + */ +export interface OptimizedValueResult { + /** The calculated result value */ + result: number; + /** The adjusted exponent */ + e: number; +} + +/** + * Precision handling result + */ +export interface PrecisionHandlingResult { + /** The formatted value */ + value: string | number; + /** The adjusted exponent */ + e: number; +} + +/** + * Optimized base configuration lookup + * @param standard - Standard type + * @param base - Base number + * @returns Configuration object + */ +export function getBaseConfiguration(standard: string, base: number): BaseConfiguration; + +/** + * Optimized zero value handling + * @param precision - Precision value + * @param actualStandard - Standard to use + * @param bits - Whether to use bits + * @param symbols - Custom symbols + * @param full - Whether to use full form + * @param fullforms - Custom full forms + * @param output - Output format + * @param spacer - Spacer character + * @returns Formatted result + */ +export function handleZeroValue( + precision: number, + actualStandard: string, + bits: boolean, + symbols: Record, + full: boolean, + fullforms: string[], + output: string, + spacer: string +): string | [number | string, string] | { value: number | string; symbol: string; exponent: number; unit: string } | number; + +/** + * Optimized value calculation with bits handling + * @param num - Input number + * @param e - Exponent + * @param isDecimal - Whether to use decimal powers + * @param bits - Whether to calculate bits + * @param ceil - Ceiling value for auto-increment + * @returns Object with result and e properties + */ +export function calculateOptimizedValue( + num: number, + e: number, + isDecimal: boolean, + bits: boolean, + ceil: number +): OptimizedValueResult; + +/** + * Optimized precision handling with scientific notation correction + * @param value - Current value + * @param precision - Precision to apply + * @param e - Current exponent + * @param num - Original number + * @param isDecimal - Whether using decimal base + * @param bits - Whether calculating bits + * @param ceil - Ceiling value + * @param roundingFunc - Rounding function + * @param round - Round value + * @returns Object with value and e properties + */ +export function applyPrecisionHandling( + value: number, + precision: number, + e: number, + num: number, + isDecimal: boolean, + bits: boolean, + ceil: number, + roundingFunc: (x: number) => number, + round: number +): PrecisionHandlingResult; + +/** + * Optimized number formatting with locale, separator, and padding + * @param value - Value to format + * @param locale - Locale setting + * @param localeOptions - Locale options + * @param separator - Custom separator + * @param pad - Whether to pad + * @param round - Round value + * @returns Formatted value + */ +export function applyNumberFormatting( + value: number | string, + locale: string | boolean, + localeOptions: Intl.NumberFormatOptions, + separator: string, + pad: boolean, + round: number +): string | number; From 10c6f702ba9a382ebfb89e24080278a7ac1ba66d Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Sun, 21 Sep 2025 09:15:34 -0400 Subject: [PATCH 12/12] oops --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 980c0b7..b5cf20d 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "module": "dist/filesize.js", "main": "dist/filesize.cjs", "exports": { - "types": "./types", + "types": "./types/filesize.d.ts", "import": "./dist/filesize.js", "require": "./dist/filesize.cjs" },