smart-unit 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ import { type Decimal } from 'decimal.js';
2
+ import { SmartUnitBase } from './SmartUnitBase';
3
+ import { type FormattedValue, type FractionDigits, type InputNumber, type SmartUnitOptions } from './utils';
4
+ export type DecimalOptions = Decimal.Config;
5
+ export type NumPrecision = InputNumber | string | bigint | Decimal;
6
+ export interface FormattedValuePrecision<U extends string> extends FormattedValue<U> {
7
+ decimal: Decimal;
8
+ }
9
+ export interface SmartUnitPrecisionOptions extends SmartUnitOptions {
10
+ /**
11
+ * Decimal.js configuration options
12
+ * - Creates an isolated Decimal class for this SmartUnit instance only
13
+ * - Used to customize precision and other parameters
14
+ */
15
+ decimalOptions?: DecimalOptions;
16
+ }
17
+ export declare class SmartUnitPrecision<U extends string = string> extends SmartUnitBase<U, true> {
18
+ private DecimalClass;
19
+ constructor(units: (U | number)[], option?: SmartUnitPrecisionOptions);
20
+ /**
21
+ * Gets the appropriate unit and adjusted value for the input number
22
+ *
23
+ * @param num - The input NumPrecision to determine the unit for
24
+ * @param fractionDigits - Decimal precision configuration
25
+ * @returns The FormattedValue object containing the number, unit, and decimal instance
26
+ */
27
+ getUnit(num: NumPrecision): FormattedValuePrecision<U>;
28
+ /**
29
+ * Formats a number as a string with unit and optional decimal place configuration
30
+ *
31
+ * @param num - The input number to format
32
+ * @param fractionDigits - Decimal precision configuration
33
+ * @returns The formatted string with number and unit
34
+ */
35
+ format(num: NumPrecision, fractionDigits?: FractionDigits): string;
36
+ /**
37
+ * Gets the chain of units for the input number
38
+ *
39
+ * @param num - The input number to determine the chain for
40
+ * @returns An array of FormattedValue objects representing the chain of units
41
+ */
42
+ getChainUnit(num: NumPrecision): FormattedValuePrecision<U>[];
43
+ /**
44
+ * Formats a number as a chain of units string
45
+ *
46
+ * @param num - The input number to format
47
+ * @returns The formatted chain string
48
+ */
49
+ formatChain(num: NumPrecision, separator?: string): string;
50
+ /**
51
+ * Converts a value from the specified unit to the base unit
52
+ *
53
+ * @param num - The number to convert
54
+ * @param unit - The original unit of the number
55
+ * @returns The converted value in base unit
56
+ */
57
+ toBase(num: NumPrecision, unit: U): Decimal;
58
+ /**
59
+ * Splits a string into its numeric part and unit
60
+ *
61
+ * @param str - Input string containing a number followed by a unit
62
+ * @returns An object containing the numeric value, unit, and Decimal instance
63
+ * @throws An error if no predefined unit is matched
64
+ */
65
+ splitUnit(str: string): FormattedValuePrecision<U>;
66
+ /**
67
+ * Parses a string with unit into a base unit numeric value
68
+ *
69
+ * @param str - Input string containing a number and unit
70
+ * @returns The value converted to base unit
71
+ */
72
+ parse(str: string): Decimal;
73
+ /**
74
+ * Converts a value from the original unit to the optimal unit with optional decimal precision
75
+ *
76
+ * @param num - The number to convert
77
+ * @param unit - The original unit
78
+ * @param fractionDigits - Optional decimal places for formatting output
79
+ * @returns The converted number as a formatted string
80
+ */
81
+ fromUnitFormat(num: NumPrecision, unit: U, fractionDigits?: FractionDigits): string;
82
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1,166 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var utils = require('./utils-DqEXot5a.js');
6
+
7
+ class SmartUnit extends utils.SmartUnitBase {
8
+ constructor(units, option = {}) {
9
+ super(units, option);
10
+ }
11
+ // 根据输入数值获取单位和调整后的值
12
+ /**
13
+ * Gets the appropriate unit and adjusted value for the input number
14
+ *
15
+ * @param num - The input number to determine the unit for
16
+ * @param fractionDigits - Decimal precision configuration
17
+ * @returns The FormattedValue object containing the number, unit, and formatted number string
18
+ */
19
+ getUnit(num, fractionDigits = this.fractionDigits) {
20
+ if (Number.isNaN(num))
21
+ throw new Error(utils.ERROR_NAN_INPUT);
22
+ const unitDigitsLen = this.unitDigits.length;
23
+ const isNegative = num < 0;
24
+ let absNum = isNegative ? -num : num;
25
+ let i = 0;
26
+ while (i < unitDigitsLen) {
27
+ const digit = this.unitDigits[i];
28
+ if (absNum < digit * this.threshold) {
29
+ break;
30
+ }
31
+ absNum /= digit;
32
+ i++;
33
+ }
34
+ const result = isNegative ? -absNum : absNum;
35
+ return {
36
+ num: result,
37
+ unit: this.unitNames[i],
38
+ numStr: this.formatNumber(result, fractionDigits),
39
+ };
40
+ }
41
+ // 将数字转换为字符串表示形式,并可选择配置小数位数
42
+ /**
43
+ * Formats a number as a string with unit and optional decimal place configuration
44
+ *
45
+ * @param num - The input number to format
46
+ * @param fractionDigits - Decimal precision configuration (defaults to instance setting)
47
+ * - If a number, defines fixed decimal places
48
+ * - If a string in "min-max" format, defines a range of decimal places
49
+ * - If omitted, uses the instance's default decimal configuration
50
+ * @returns The formatted string with number and unit (e.g. "1.50KB")
51
+ */
52
+ format(num, fractionDigits = this.fractionDigits) {
53
+ const { numStr, unit } = this.getUnit(num, fractionDigits);
54
+ return this._format(numStr, unit);
55
+ }
56
+ // 根据输入数值获取链式单位数组
57
+ /**
58
+ * Gets the chain of units for the input number
59
+ * @param num - The input number to determine the chain for
60
+ * @returns An array of FormattedValue objects representing the chain of units
61
+ */
62
+ getChainUnit(num) {
63
+ if (Number.isNaN(num))
64
+ throw new Error(utils.ERROR_NAN_INPUT);
65
+ const result = [];
66
+ if (num === 0) {
67
+ return [{ num: 0, unit: this.unitNames[0], numStr: '0' }];
68
+ }
69
+ const isNegative = num < 0;
70
+ let absNum = isNegative ? -num : num;
71
+ const accDigLen = this.accumulatedDigits.length;
72
+ for (let i = accDigLen - 1; i >= 0; i--) {
73
+ const accDigit = this.accumulatedDigits[i];
74
+ if (absNum < accDigit)
75
+ continue;
76
+ const res = Math.floor(absNum / accDigit);
77
+ const val = isNegative ? -res : res;
78
+ result.push({
79
+ num: val,
80
+ unit: this.unitNames[i + 1],
81
+ numStr: val.toString(),
82
+ });
83
+ absNum %= accDigit;
84
+ if (absNum === 0)
85
+ break;
86
+ }
87
+ if (absNum !== 0) {
88
+ const val = isNegative ? -absNum : absNum;
89
+ result.push({
90
+ num: val,
91
+ unit: this.unitNames[0],
92
+ numStr: this.formatNumber(val, this.fractionDigits),
93
+ });
94
+ }
95
+ return result;
96
+ }
97
+ // 将数字格式化为链式单位字符串
98
+ /**
99
+ * Formats a number as a chain of units string
100
+ * @param num - The input number to format
101
+ * @returns The formatted chain string
102
+ */
103
+ formatChain(num, separator = this.separator) {
104
+ const chain = this.getChainUnit(num);
105
+ return this._formatChain(chain, separator);
106
+ }
107
+ // 将给定数值从指定单位转换为基本单位
108
+ /**
109
+ * Converts a value from the specified unit to the base unit
110
+ *
111
+ * @param num - The number to convert
112
+ * @param unit - The original unit of the number
113
+ * @returns The converted value in base unit
114
+ */
115
+ toBase(num, unit) {
116
+ if (Number.isNaN(num))
117
+ throw new Error(utils.ERROR_NAN_INPUT);
118
+ const unitDigitsLen = this.unitDigits.length;
119
+ let nn = num;
120
+ for (let i = 0; i < unitDigitsLen; i++) {
121
+ const digit = this.unitDigits[i];
122
+ if (this.unitNames[i] === unit) {
123
+ return nn;
124
+ }
125
+ nn *= digit;
126
+ }
127
+ if (unit === this.unitNames.at(-1)) {
128
+ return nn;
129
+ }
130
+ throw new Error(`Undefined unit: "${unit}".`);
131
+ }
132
+ // 将带单位的值转换为基础单位的数值
133
+ /**
134
+ * Parses a string with unit into a base unit numeric value
135
+ *
136
+ * @param str - Input string containing a number and unit
137
+ * @returns The value converted to base unit
138
+ */
139
+ parse(str) {
140
+ const { num, unit } = this.splitUnit(str);
141
+ return this.toBase(num, unit);
142
+ }
143
+ // 将给定数值从原单位转换为最佳单位,并可指定小数精度
144
+ /**
145
+ * Converts a value from the original unit to the optimal unit with optional decimal precision
146
+ *
147
+ * @param num - The number to convert
148
+ * @param unit - The original unit
149
+ * @param fractionDigits - Optional decimal places for formatting output
150
+ * @returns The converted number as a formatted string
151
+ */
152
+ fromUnitFormat(num, unit, fractionDigits) {
153
+ const nnum = this.toBase(num, unit);
154
+ return this.format(nnum, fractionDigits);
155
+ }
156
+ }
157
+
158
+ /*!
159
+ * smart-unit
160
+ * Copyright (c) [2026] [flycran]
161
+ * MIT License. See LICENSE for details.
162
+ */
163
+
164
+ exports.ERROR_NAN_INPUT = utils.ERROR_NAN_INPUT;
165
+ exports.SmartUnit = SmartUnit;
166
+ exports.default = SmartUnit;
package/dist/index.d.ts CHANGED
@@ -3,108 +3,7 @@
3
3
  * Copyright (c) [2026] [flycran]
4
4
  * MIT License. See LICENSE for details.
5
5
  */
6
- import { type Decimal } from 'decimal.js';
7
- export type FractionDigits = number | `-${number}` | `${number}-` | `${number}-${number}` | undefined;
8
- export type DecimalOptions = Decimal.Config;
9
- export interface SmartUnitOptions<HP extends boolean = false> {
10
- /** Base digit for auto-generating unit conversions */
11
- baseDigit?: number;
12
- /**
13
- * Threshold for unit switching
14
- * The comparison value is multiplied by this threshold
15
- */
16
- threshold?: number;
17
- /**
18
- * Number of decimal places to preserve in the result
19
- * Can be a fixed number or a range like "min-max"
20
- */
21
- fractionDigits?: FractionDigits;
22
- /**
23
- * Enable high-precision calculation using decimal.js
24
- * - Uses decimal.js for high-precision floating-point calculations
25
- * - Supports calculations beyond JavaScript's safe integer limit
26
- * - Enables string, BigInt, and Decimal inputs for format and other methods
27
- */
28
- useDecimal?: HP;
29
- /**
30
- * Decimal.js configuration options
31
- * - Creates an isolated Decimal class for this SmartUnit instance only
32
- * - Used to customize precision and other parameters
33
- */
34
- decimalOptions?: DecimalOptions;
35
- }
36
- export interface NumUnit {
37
- /** The numeric value */
38
- num: number;
39
- /** The Decimal instance for high-precision mode */
40
- decimal?: Decimal;
41
- /** The unit string */
42
- unit: string;
43
- }
44
- export type Num<DS extends boolean = false> = DS extends true ? number | bigint | string | Decimal : number;
45
- export declare const ERROR_NAN_INPUT = "Accepting NaN as an argument may be unintentional and could lead to invalid results. If this is intentional, please set `SmartUnit.ignoreNaNInputs` to `true`.";
46
- export declare const ERROR_HIGH_PRECISION_NOT_ENABLED = "By default, only number input is supported. To enable high-precision calculations, explicitly set the decimalSafety parameter to true.";
47
- export declare class SmartUnit<HP extends boolean = false> {
48
- readonly units: (string | number)[];
49
- static ignoreNaNInputs: boolean;
50
- readonly threshold: number;
51
- readonly decimal?: FractionDigits;
52
- readonly unitsStr: string[];
53
- readonly highPrecision: HP;
54
- private DecimalClass;
55
- constructor(units: (string | number)[], option?: SmartUnitOptions<HP>);
56
- /**
57
- * Gets the appropriate unit and adjusted value for the input number
58
- *
59
- * @param num - The input number to determine the unit for
60
- * @returns An object containing the adjusted number and its corresponding unit
61
- */
62
- getUnit(num: Num<HP>): NumUnit;
63
- /**
64
- * Formats a number as a string with optional decimal place configuration
65
- *
66
- * @param num - The number to convert to string
67
- * @param decimal - Decimal precision configuration (defaults to instance setting)
68
- * - If a number, defines fixed decimal places
69
- * - If a string in "min-max" format, defines a range of decimal places
70
- * - If omitted, uses the instance's default decimal configuration
71
- * @returns The formatted string representation with unit
72
- */
73
- format(num: Num<HP>, decimal?: FractionDigits): string;
74
- /**
75
- * Converts a value from the specified unit to the base unit
76
- *
77
- * @param num - The number to convert
78
- * @param unit - The original unit of the number
79
- * @returns The converted value in base unit
80
- * - Returns Decimal if high-precision mode is enabled
81
- */
82
- toBase(num: Num<HP>, unit: string): HP extends true ? Decimal : number;
83
- /**
84
- * Splits a string into its numeric part and unit
85
- *
86
- * @param str - Input string containing a number followed by a unit
87
- * @returns An object containing the numeric value and unit
88
- * Only supports predefined units
89
- * Throws an error if no match is found
90
- */
91
- splitUnit(str: string): NumUnit;
92
- /**
93
- * Parses a string with unit into a base unit numeric value
94
- *
95
- * @param str - Input string containing a number and unit
96
- * @returns The value converted to base unit
97
- * - Returns Decimal if high-precision mode is enabled
98
- */
99
- parse(str: string): HP extends true ? Decimal : number;
100
- /**
101
- * Converts a value from the original unit to the optimal unit with optional decimal precision
102
- *
103
- * @param num - The number to convert
104
- * @param unit - The original unit
105
- * @param decimal - Optional decimal places for formatting output
106
- * @returns The converted number as a formatted string
107
- */
108
- fromUnitFormat(num: Num<HP>, unit: string, decimal?: FractionDigits): string;
109
- }
6
+ export * from './SmartUnit';
7
+ export * from './utils';
8
+ import { SmartUnit } from './SmartUnit';
110
9
  export default SmartUnit;
package/dist/index.mjs ADDED
@@ -0,0 +1,160 @@
1
+ import { S as SmartUnitBase, E as ERROR_NAN_INPUT } from './utils-C1byK7Uk.js';
2
+
3
+ class SmartUnit extends SmartUnitBase {
4
+ constructor(units, option = {}) {
5
+ super(units, option);
6
+ }
7
+ // 根据输入数值获取单位和调整后的值
8
+ /**
9
+ * Gets the appropriate unit and adjusted value for the input number
10
+ *
11
+ * @param num - The input number to determine the unit for
12
+ * @param fractionDigits - Decimal precision configuration
13
+ * @returns The FormattedValue object containing the number, unit, and formatted number string
14
+ */
15
+ getUnit(num, fractionDigits = this.fractionDigits) {
16
+ if (Number.isNaN(num))
17
+ throw new Error(ERROR_NAN_INPUT);
18
+ const unitDigitsLen = this.unitDigits.length;
19
+ const isNegative = num < 0;
20
+ let absNum = isNegative ? -num : num;
21
+ let i = 0;
22
+ while (i < unitDigitsLen) {
23
+ const digit = this.unitDigits[i];
24
+ if (absNum < digit * this.threshold) {
25
+ break;
26
+ }
27
+ absNum /= digit;
28
+ i++;
29
+ }
30
+ const result = isNegative ? -absNum : absNum;
31
+ return {
32
+ num: result,
33
+ unit: this.unitNames[i],
34
+ numStr: this.formatNumber(result, fractionDigits),
35
+ };
36
+ }
37
+ // 将数字转换为字符串表示形式,并可选择配置小数位数
38
+ /**
39
+ * Formats a number as a string with unit and optional decimal place configuration
40
+ *
41
+ * @param num - The input number to format
42
+ * @param fractionDigits - Decimal precision configuration (defaults to instance setting)
43
+ * - If a number, defines fixed decimal places
44
+ * - If a string in "min-max" format, defines a range of decimal places
45
+ * - If omitted, uses the instance's default decimal configuration
46
+ * @returns The formatted string with number and unit (e.g. "1.50KB")
47
+ */
48
+ format(num, fractionDigits = this.fractionDigits) {
49
+ const { numStr, unit } = this.getUnit(num, fractionDigits);
50
+ return this._format(numStr, unit);
51
+ }
52
+ // 根据输入数值获取链式单位数组
53
+ /**
54
+ * Gets the chain of units for the input number
55
+ * @param num - The input number to determine the chain for
56
+ * @returns An array of FormattedValue objects representing the chain of units
57
+ */
58
+ getChainUnit(num) {
59
+ if (Number.isNaN(num))
60
+ throw new Error(ERROR_NAN_INPUT);
61
+ const result = [];
62
+ if (num === 0) {
63
+ return [{ num: 0, unit: this.unitNames[0], numStr: '0' }];
64
+ }
65
+ const isNegative = num < 0;
66
+ let absNum = isNegative ? -num : num;
67
+ const accDigLen = this.accumulatedDigits.length;
68
+ for (let i = accDigLen - 1; i >= 0; i--) {
69
+ const accDigit = this.accumulatedDigits[i];
70
+ if (absNum < accDigit)
71
+ continue;
72
+ const res = Math.floor(absNum / accDigit);
73
+ const val = isNegative ? -res : res;
74
+ result.push({
75
+ num: val,
76
+ unit: this.unitNames[i + 1],
77
+ numStr: val.toString(),
78
+ });
79
+ absNum %= accDigit;
80
+ if (absNum === 0)
81
+ break;
82
+ }
83
+ if (absNum !== 0) {
84
+ const val = isNegative ? -absNum : absNum;
85
+ result.push({
86
+ num: val,
87
+ unit: this.unitNames[0],
88
+ numStr: this.formatNumber(val, this.fractionDigits),
89
+ });
90
+ }
91
+ return result;
92
+ }
93
+ // 将数字格式化为链式单位字符串
94
+ /**
95
+ * Formats a number as a chain of units string
96
+ * @param num - The input number to format
97
+ * @returns The formatted chain string
98
+ */
99
+ formatChain(num, separator = this.separator) {
100
+ const chain = this.getChainUnit(num);
101
+ return this._formatChain(chain, separator);
102
+ }
103
+ // 将给定数值从指定单位转换为基本单位
104
+ /**
105
+ * Converts a value from the specified unit to the base unit
106
+ *
107
+ * @param num - The number to convert
108
+ * @param unit - The original unit of the number
109
+ * @returns The converted value in base unit
110
+ */
111
+ toBase(num, unit) {
112
+ if (Number.isNaN(num))
113
+ throw new Error(ERROR_NAN_INPUT);
114
+ const unitDigitsLen = this.unitDigits.length;
115
+ let nn = num;
116
+ for (let i = 0; i < unitDigitsLen; i++) {
117
+ const digit = this.unitDigits[i];
118
+ if (this.unitNames[i] === unit) {
119
+ return nn;
120
+ }
121
+ nn *= digit;
122
+ }
123
+ if (unit === this.unitNames.at(-1)) {
124
+ return nn;
125
+ }
126
+ throw new Error(`Undefined unit: "${unit}".`);
127
+ }
128
+ // 将带单位的值转换为基础单位的数值
129
+ /**
130
+ * Parses a string with unit into a base unit numeric value
131
+ *
132
+ * @param str - Input string containing a number and unit
133
+ * @returns The value converted to base unit
134
+ */
135
+ parse(str) {
136
+ const { num, unit } = this.splitUnit(str);
137
+ return this.toBase(num, unit);
138
+ }
139
+ // 将给定数值从原单位转换为最佳单位,并可指定小数精度
140
+ /**
141
+ * Converts a value from the original unit to the optimal unit with optional decimal precision
142
+ *
143
+ * @param num - The number to convert
144
+ * @param unit - The original unit
145
+ * @param fractionDigits - Optional decimal places for formatting output
146
+ * @returns The converted number as a formatted string
147
+ */
148
+ fromUnitFormat(num, unit, fractionDigits) {
149
+ const nnum = this.toBase(num, unit);
150
+ return this.format(nnum, fractionDigits);
151
+ }
152
+ }
153
+
154
+ /*!
155
+ * smart-unit
156
+ * Copyright (c) [2026] [flycran]
157
+ * MIT License. See LICENSE for details.
158
+ */
159
+
160
+ export { ERROR_NAN_INPUT, SmartUnit, SmartUnit as default };