@@ -91,11 +91,161 @@ const LOG_10_1000 = Math.log(1000);
9191
9292// Cached configuration lookup for better performance
9393const STANDARD_CONFIGS = {
94- [ SI ] : { isDecimal : true , ceil : 1000 , actualStandard : JEDEC } ,
95- [ IEC ] : { isDecimal : false , ceil : 1024 , actualStandard : IEC } ,
96- [ JEDEC ] : { isDecimal : false , ceil : 1024 , actualStandard : JEDEC }
94+ [ SI ] : { isDecimal : true , ceil : 1000 , actualStandard : JEDEC } ,
95+ [ IEC ] : { isDecimal : false , ceil : 1024 , actualStandard : IEC } ,
96+ [ JEDEC ] : { isDecimal : false , ceil : 1024 , actualStandard : JEDEC }
9797} ;
9898
99+ /**
100+ * Optimized base configuration lookup
101+ * @param {string } standard - Standard type
102+ * @param {number } base - Base number
103+ * @returns {Object } Configuration object
104+ */
105+ function getBaseConfiguration ( standard , base ) {
106+ // Use cached lookup table for better performance
107+ if ( STANDARD_CONFIGS [ standard ] ) {
108+ return STANDARD_CONFIGS [ standard ] ;
109+ }
110+
111+ // Base override
112+ if ( base === 2 ) {
113+ return { isDecimal : false , ceil : 1024 , actualStandard : IEC } ;
114+ }
115+
116+ // Default
117+ return { isDecimal : true , ceil : 1000 , actualStandard : JEDEC } ;
118+ }
119+
120+ /**
121+ * Optimized zero value handling
122+ * @param {number } precision - Precision value
123+ * @param {string } actualStandard - Standard to use
124+ * @param {boolean } bits - Whether to use bits
125+ * @param {Object } symbols - Custom symbols
126+ * @param {boolean } full - Whether to use full form
127+ * @param {Array } fullforms - Custom full forms
128+ * @param {string } output - Output format
129+ * @param {string } spacer - Spacer character
130+ * @returns {string|Array|Object|number } Formatted result
131+ */
132+ function handleZeroValue ( precision , actualStandard , bits , symbols , full , fullforms , output , spacer ) {
133+ const result = [ ] ;
134+ result [ 0 ] = precision > 0 ? ( 0 ) . toPrecision ( precision ) : 0 ;
135+ const u = result [ 1 ] = STRINGS . symbol [ actualStandard ] [ bits ? BITS : BYTES ] [ 0 ] ;
136+
137+ if ( output === EXPONENT ) {
138+ return 0 ;
139+ }
140+
141+ // Apply symbol customization
142+ if ( symbols [ result [ 1 ] ] ) {
143+ result [ 1 ] = symbols [ result [ 1 ] ] ;
144+ }
145+
146+ // Apply full form
147+ if ( full ) {
148+ result [ 1 ] = fullforms [ 0 ] || STRINGS . fullform [ actualStandard ] [ 0 ] + ( bits ? BIT : BYTE ) ;
149+ }
150+
151+ // Return in requested format
152+ return output === ARRAY ? result : output === OBJECT ? {
153+ value : result [ 0 ] ,
154+ symbol : result [ 1 ] ,
155+ exponent : 0 ,
156+ unit : u
157+ } : result . join ( spacer ) ;
158+ }
159+
160+ /**
161+ * Optimized value calculation with bits handling
162+ * @param {number } num - Input number
163+ * @param {number } e - Exponent
164+ * @param {boolean } isDecimal - Whether to use decimal powers
165+ * @param {boolean } bits - Whether to calculate bits
166+ * @param {number } ceil - Ceiling value for auto-increment
167+ * @returns {Object } Object with val and e properties
168+ */
169+ function calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) {
170+ const d = isDecimal ? DECIMAL_POWERS [ e ] : BINARY_POWERS [ e ] ;
171+ let result = num / d ;
172+
173+ if ( bits ) {
174+ result *= 8 ;
175+ // Handle auto-increment for bits
176+ if ( result >= ceil && e < 8 ) {
177+ result /= ceil ;
178+ e ++ ;
179+ }
180+ }
181+
182+ return { result, e} ;
183+ }
184+
185+ /**
186+ * Optimized precision handling with scientific notation correction
187+ * @param {number } value - Current value
188+ * @param {number } precision - Precision to apply
189+ * @param {number } e - Current exponent
190+ * @param {number } num - Original number
191+ * @param {boolean } isDecimal - Whether using decimal base
192+ * @param {boolean } bits - Whether calculating bits
193+ * @param {number } ceil - Ceiling value
194+ * @param {Function } roundingFunc - Rounding function
195+ * @param {number } round - Round value
196+ * @returns {Object } Object with value and e properties
197+ */
198+ function applyPrecisionHandling ( value , precision , e , num , isDecimal , bits , ceil , roundingFunc , round ) {
199+ let result = value . toPrecision ( precision ) ;
200+
201+ // Handle scientific notation by recalculating with incremented exponent
202+ if ( result . includes ( E ) && e < 8 ) {
203+ e ++ ;
204+ const { result : valueResult } = calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) ;
205+ const p = round > 0 ? Math . pow ( 10 , round ) : 1 ;
206+ result = ( p === 1 ? roundingFunc ( valueResult ) : roundingFunc ( valueResult * p ) / p ) . toPrecision ( precision ) ;
207+ }
208+
209+ return { value : result , e} ;
210+ }
211+
212+ /**
213+ * Optimized number formatting with locale, separator, and padding
214+ * @param {number|string } value - Value to format
215+ * @param {string|boolean } locale - Locale setting
216+ * @param {Object } localeOptions - Locale options
217+ * @param {string } separator - Custom separator
218+ * @param {boolean } pad - Whether to pad
219+ * @param {number } round - Round value
220+ * @returns {string|number } Formatted value
221+ */
222+ function applyNumberFormatting ( value , locale , localeOptions , separator , pad , round ) {
223+ let result = value ;
224+
225+ // Apply locale formatting
226+ if ( locale === true ) {
227+ result = result . toLocaleString ( ) ;
228+ } else if ( locale . length > 0 ) {
229+ result = result . toLocaleString ( locale , localeOptions ) ;
230+ } else if ( separator . length > 0 ) {
231+ result = result . toString ( ) . replace ( PERIOD , separator ) ;
232+ }
233+
234+ // Apply padding
235+ if ( pad && round > 0 ) {
236+ const resultStr = result . toString ( ) ;
237+ const x = separator || ( ( resultStr . match ( / ( \D ) / g) || [ ] ) . pop ( ) || PERIOD ) ;
238+ const tmp = resultStr . split ( x ) ;
239+ const s = tmp [ 1 ] || EMPTY ;
240+ const l = s . length ;
241+ const n = round - l ;
242+
243+ result = `${ tmp [ 0 ] } ${ x } ${ s . padEnd ( l + n , ZERO ) } ` ;
244+ }
245+
246+ return result ;
247+ }
248+
99249/**
100250 * Converts a file size in bytes to a human-readable string with appropriate units
101251 * @param {number|string|bigint } arg - The file size in bytes to convert
@@ -148,8 +298,7 @@ function filesize (arg, {
148298 u = EMPTY ;
149299
150300 // Optimized base & standard configuration lookup
151- const config = getBaseConfiguration ( standard , base ) ;
152- const { isDecimal, ceil, actualStandard } = config ;
301+ const { isDecimal, ceil, actualStandard} = getBaseConfiguration ( standard , base ) ;
153302
154303 const full = fullform === true ,
155304 neg = num < 0 ,
@@ -194,9 +343,9 @@ function filesize (arg, {
194343 }
195344
196345 // Calculate value with optimized lookup and bits handling
197- const valueResult = calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) ;
198- val = valueResult . val ;
199- e = valueResult . e ;
346+ const { result : valueResult , e : valueExponent } = calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) ;
347+ val = valueResult ;
348+ e = valueExponent ;
200349
201350 // Optimize rounding calculation
202351 const p = e > 0 && round > 0 ? Math . pow ( 10 , round ) : 1 ;
@@ -252,156 +401,6 @@ function filesize (arg, {
252401 return spacer === SPACE ? `${ result [ 0 ] } ${ result [ 1 ] } ` : result . join ( spacer ) ;
253402}
254403
255- /**
256- * Optimized base configuration lookup
257- * @param {string } standard - Standard type
258- * @param {number } base - Base number
259- * @returns {Object } Configuration object
260- */
261- function getBaseConfiguration ( standard , base ) {
262- // Use cached lookup table for better performance
263- if ( STANDARD_CONFIGS [ standard ] ) {
264- return STANDARD_CONFIGS [ standard ] ;
265- }
266-
267- // Base override
268- if ( base === 2 ) {
269- return { isDecimal : false , ceil : 1024 , actualStandard : IEC } ;
270- }
271-
272- // Default
273- return { isDecimal : true , ceil : 1000 , actualStandard : JEDEC } ;
274- }
275-
276- /**
277- * Optimized zero value handling
278- * @param {number } precision - Precision value
279- * @param {string } actualStandard - Standard to use
280- * @param {boolean } bits - Whether to use bits
281- * @param {Object } symbols - Custom symbols
282- * @param {boolean } full - Whether to use full form
283- * @param {Array } fullforms - Custom full forms
284- * @param {string } output - Output format
285- * @param {string } spacer - Spacer character
286- * @returns {string|Array|Object|number } Formatted result
287- */
288- function handleZeroValue ( precision , actualStandard , bits , symbols , full , fullforms , output , spacer ) {
289- const result = [ ] ;
290- result [ 0 ] = precision > 0 ? ( 0 ) . toPrecision ( precision ) : 0 ;
291- const u = result [ 1 ] = STRINGS . symbol [ actualStandard ] [ bits ? BITS : BYTES ] [ 0 ] ;
292-
293- if ( output === EXPONENT ) {
294- return 0 ;
295- }
296-
297- // Apply symbol customization
298- if ( symbols [ result [ 1 ] ] ) {
299- result [ 1 ] = symbols [ result [ 1 ] ] ;
300- }
301-
302- // Apply full form
303- if ( full ) {
304- result [ 1 ] = fullforms [ 0 ] || STRINGS . fullform [ actualStandard ] [ 0 ] + ( bits ? BIT : BYTE ) ;
305- }
306-
307- // Return in requested format
308- return output === ARRAY ? result : output === OBJECT ? {
309- value : result [ 0 ] ,
310- symbol : result [ 1 ] ,
311- exponent : 0 ,
312- unit : u
313- } : result . join ( spacer ) ;
314- }
315-
316- /**
317- * Optimized value calculation with bits handling
318- * @param {number } num - Input number
319- * @param {number } e - Exponent
320- * @param {boolean } isDecimal - Whether to use decimal powers
321- * @param {boolean } bits - Whether to calculate bits
322- * @param {number } ceil - Ceiling value for auto-increment
323- * @returns {Object } Object with val and e properties
324- */
325- function calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) {
326- const d = isDecimal ? DECIMAL_POWERS [ e ] : BINARY_POWERS [ e ] ;
327- let val = num / d ;
328-
329- if ( bits ) {
330- val *= 8 ;
331- // Handle auto-increment for bits
332- if ( val >= ceil && e < 8 ) {
333- val /= ceil ;
334- e ++ ;
335- }
336- }
337-
338- return { val, e } ;
339- }
340-
341- /**
342- * Optimized precision handling with scientific notation correction
343- * @param {number } value - Current value
344- * @param {number } precision - Precision to apply
345- * @param {number } e - Current exponent
346- * @param {number } num - Original number
347- * @param {boolean } isDecimal - Whether using decimal base
348- * @param {boolean } bits - Whether calculating bits
349- * @param {number } ceil - Ceiling value
350- * @param {Function } roundingFunc - Rounding function
351- * @param {number } round - Round value
352- * @returns {Object } Object with value and e properties
353- */
354- function applyPrecisionHandling ( value , precision , e , num , isDecimal , bits , ceil , roundingFunc , round ) {
355- let result = value . toPrecision ( precision ) ;
356-
357- // Handle scientific notation by recalculating with incremented exponent
358- if ( result . includes ( E ) && e < 8 ) {
359- e ++ ;
360- const valueResult = calculateOptimizedValue ( num , e , isDecimal , bits , ceil ) ;
361- const p = round > 0 ? Math . pow ( 10 , round ) : 1 ;
362- result = ( p === 1 ? roundingFunc ( valueResult . val ) : roundingFunc ( valueResult . val * p ) / p ) . toPrecision ( precision ) ;
363- }
364-
365- return { value : result , e } ;
366- }
367-
368- /**
369- * Optimized number formatting with locale, separator, and padding
370- * @param {number|string } value - Value to format
371- * @param {string|boolean } locale - Locale setting
372- * @param {Object } localeOptions - Locale options
373- * @param {string } separator - Custom separator
374- * @param {boolean } pad - Whether to pad
375- * @param {number } round - Round value
376- * @returns {string|number } Formatted value
377- */
378- function applyNumberFormatting ( value , locale , localeOptions , separator , pad , round ) {
379- let result = value ;
380-
381- // Apply locale formatting
382- if ( locale === true ) {
383- result = result . toLocaleString ( ) ;
384- } else if ( locale . length > 0 ) {
385- result = result . toLocaleString ( locale , localeOptions ) ;
386- } else if ( separator . length > 0 ) {
387- result = result . toString ( ) . replace ( PERIOD , separator ) ;
388- }
389-
390- // Apply padding
391- if ( pad && round > 0 ) {
392- const resultStr = result . toString ( ) ;
393- const x = separator || ( ( resultStr . match ( / ( \D ) / g) || [ ] ) . pop ( ) || PERIOD ) ;
394- const tmp = resultStr . split ( x ) ;
395- const s = tmp [ 1 ] || EMPTY ;
396- const l = s . length ;
397- const n = round - l ;
398-
399- result = `${ tmp [ 0 ] } ${ x } ${ s . padEnd ( l + n , ZERO ) } ` ;
400- }
401-
402- return result ;
403- }
404-
405404/**
406405 * Creates a partially applied version of filesize with preset options
407406 * @param {Object } [options={}] - Default options to apply to the returned function
@@ -466,10 +465,5 @@ function partial ({
466465 } ) ;
467466}
468467
469- exports . applyNumberFormatting = applyNumberFormatting ;
470- exports . applyPrecisionHandling = applyPrecisionHandling ;
471- exports . calculateOptimizedValue = calculateOptimizedValue ;
472468exports . filesize = filesize ;
473- exports . getBaseConfiguration = getBaseConfiguration ;
474- exports . handleZeroValue = handleZeroValue ;
475469exports . partial = partial ;
0 commit comments